Hi all,
I have a question: is there a solution to get the environment variables of a win32 proces? I have the process list throught the EnumProcesses windows call, now I woluld like scan inside the enumeration to get the environment variables of each process. Is it possible?
bye Federico
googler
January 19th, 2006, 08:56 AM
Unofficially, the environment will always be at virtual address 0x10000 of the process, so you can use ReadProcessMemory() to get it.
Officially, you need to first get the a pointer to the process PEB. See this (http://www.codeguru.com/forum/showthread.php?t=371338) thread on how to get it. In the PEB, at offset 16 is a pointer called "ProcessParameters". This pointer leads to a struct called _RTL_USER_PROCESS_PARAMETERS. Its address will always be 0x20000. Inside this struct, at offset 72 is a pointer called "Environment" which points to the process environment. Again, this pointer will always be 0x10000. These offsets are for NT kernel version 5.1 (Windows XP), and are subject to change from version to version if these struct change.
The reason these addresses always come out 0x10000 and 0x20000 has to do with the order in which CreateProcess() allocates memory for the new process. 0x10000 is the lowest usable address. So any process created with CreateProcess() should have these addresses. This excludes some native subsystem processes, but you may not care about those (and they may not be accessible anyway due to security reasons.)
fede_home
January 19th, 2006, 09:04 AM
Hi googler,
thank you for your reply! Is it really so hard to get an environment variable in windows? I'm trying to use your advice. Thank again.
Federico
googler
January 19th, 2006, 09:13 AM
It's very easy to get environment variables for your own process. You have API GetEnvironmentStrings() and GetEnvironmentVariable(). But the environment variables of another process is a different story. The only place they exist is in the user-mode address space of the other process. There are no pre-canned system API that I know of to get them, so the only way I see is to read them from the other process's memory directly with ReadProcessMemory().
Maybe it's enough for you to get the default environment variables from the registry. They're in
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment
for the system environment
and
HKEY_CURRENT_USER\Environment
for the current user.
fede_home
January 19th, 2006, 09:30 AM
I know GetEnvironmentStrings() and GetEnvironmentVariable(), but my story is a bit complex: I have a program which can start some others process, when a new proces is started I need to set a particolar variable. So if my main process crashes I can restart it but I need to retake each variables, to rewrite a list of my process. I think I have to use the environment variable, do you think there is a better and easier way?
bye Federico
googler
January 19th, 2006, 09:38 AM
When you spawn a new process with CreateProcess() you can set an initial environment for it with the lpEnvironment parameter.
I didn't understand from your description why your main process needs to read the environment of the spawned process if it crashes and restarts.
fede_home
January 19th, 2006, 09:57 AM
My main process is a remote front-end to start and stop particolar process. Like all process my main process can crach, at this point I can restart the main process to reopen the remote front-end but I must to know which process are started by the old main instance proces to menage them.
Federico
googler
January 19th, 2006, 10:22 AM
I guess your problem is that you want to be able to identify with process is "yours". Instead of using EnumProcesses, you can use the combination
CreateToolHelp32Snapshot/Process32First/Process32Next
These enumerators return a struct called PROCESSENTRY32 that has szExeFile in it, which is the name of the exe file for the process. From this you can indentify if this is your process.
Another way to get the name of the exe for a process is with GetModuleFileNameEx(). This will actually return a full path name if that helps. [use a NULL hModule.]
fede_home
January 19th, 2006, 10:34 AM
"I guess your problem is that you want to be able to identify with process is "yours"." -> yes and no, I would be able to identify each process started by the main process, even if the main process crashes and I restart a new instance of it. The new instance has to check each process in running and it has to be able to identify, in some way, if a process is started by the old (and crased) instance on main process.
Thanks again for you help
Federico
MrViggy
January 19th, 2006, 11:31 AM
Why not just maintain a file on disk that contains the list of processes that you started.
Viggy
fede_home
January 25th, 2006, 02:48 PM
ok, this is my code but it doesn't work:
#include <windows.h>
typedef LONG NTSTATUS;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
I try to get the command line first (then I can take also the environment variables). Why doesn't it work? Beginning from the peb's address is wronk... I don't know.
Federico
googler
January 25th, 2006, 03:28 PM
Here you go...
#include <tchar.h>
#include <windows.h>
typedef LONG NTSTATUS;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
Hi googler,
thank you, your code is perfect!!!! You are great, now I have to study it. You helped me in a hard position.....
Thanks again
Federico
googler
January 26th, 2006, 04:12 AM
Hey, it's your code. Your only bug was an extra ampersand in the third ReadProcessMemory. Other than that I just cleaned up some of the types to make it more accurate.
By the way, if you want to copy the environment and you can't find a length field for it in RTL_USER_PROCESS_PARAMETERS, you can do something else instead - call VirtualQueryEx() to get the size of the committed area starting at env, and then copy that much. This will be a multiple of page size, so it's actually bigger than the environment, but the environment ends in a double-L'\0', so you can find that.
zzmgd6
March 20th, 2008, 09:13 AM
I have successfully accomplished the above code. But I am still confused on how to get the "environment variables" of the process.
My issue is; I way to query the environment variables of a current running process and use a specific setting to launch another application. This is not a child process or sub process, has no relation to original process.
FYI, the original process is attaching to one of our databases, the database that it is connected to is an environemnt variable setting. I want to query that variable setting and connect to the same database that the user is currently connected to.
Any further help on this would be greatly appreciated. I have been working this off and on for about two weeks.
Regards.
codeguru.com
Copyright Internet.com Inc., All Rights Reserved.