3.3.4 Environment Variables

Every process has an environment block that contains a set of environment variables and their values. The command processor (cmd.exe) allows you to use the “set” command to display its environment block or to create new environment variables (as in, “set name=value”). Programs started by the command processor will inherit its environment variables.

By default, a child process inherits the environment variables of its parent process. However, you can specify a different environment for the child by creating a new environment block and passing a pointer to it as a parameter to the CreateProcess function. The environment block consists of a null terminated block of null terminated strings (that is, two null bytes at the end), where each string is in the form: “name=value”. Because the '=' character is used as a separator, it must not be used in the name of an environment variable. The following code fragment creates a new environment block to pass to a child process:

/*

* Child's environment has variables "foo" and "stop",

* whose values are "bar" and "go", respectively. The

* empty string provides null terminator for block.

*/

char *newenv[3] = {"foo=bar", "stop=go", ""};

bResult = CreateProcess(NULL, "child", NULL, NULL, TRUE, 0,

(LPVOID) newenv[0], // new environment

NULL, &startupinfo, &procinfo);

If you want the child process to inherit most of the parent's environment with only a few changes, it is easier to save the current values, make changes for the child to inherit, and then restore the saved values. For example:

char *oldvalue, buf[BUFSIZE];

BOOL bResult;

/*

* Save the current value of "varname" if it is set. If not

* set, oldvalue is NULL which causes "varname" to be deleted

* in call to SetEnvironmentVariable after process creation

*/

oldvalue = (GetEnvironmentVariable("varname", buf, BUFSIZE)) ?

buf : NULL;

/* set value for child to inherit, and create child process */

if (! SetEnvironmentVariable("varname", "newvalue")) errorfunc();

bResult = CreateProcess(NULL, "child", NULL, NULL, TRUE, 0,

NULL, // inherit parent's environment

NULL, &startupinfo, &procinfo);

/* restore the parent's environment */

if (! SetEnvironmentVariable("varname", oldvalue)) errorfunc();

The GetEnvironmentStrings function returns a pointer to the environment block of the calling process. This should be treated as a read only block, and not modified directly. Instead, you should use the SetEnvironmentVariable function if you need to change an environment variable. The following code fragment from a console application prints the contents of the process' environment block:

char *cur;

LPVOID env = GetEnvironmentStrings();

for (cur = (char *) env; *cur; cur++) {

while (*cur) {

putchar(*cur);

cur++;

}

putchar('\n');

}

Any process can use the GetEnvironmentVariable function with a specified variable to determine whether it is defined in its environment, and if so, what its value is. A process can set the value of a specified variable or delete it from its environment using the SetEnvironmentVariable function. A process using SetEnvironmentVariable will not affect the environment of its parent process, but the effects could be inherited by its child processes.