Changing Environment Variables Program Examples
Each process has an environment block associated with it. The environment block consists of a null-terminated block of null-terminated strings (meaning there are two null bytes at the end of the block), where each string is in the form:
name=value
All strings in the environment block must be sorted alphabetically by name. The sort is case-insensitive, Unicode order, without regard to locale. Because the equal sign is a separator, it must not be used in the name of an environment variable.
Environment Variables: Example 1
By default, a child process inherits a copy of the environment block of the parent process. The following example demonstrates how to create a new environment block to pass to a child process using CreateProcess(). This example uses the code in example three as the child process, EnvironVar3.exe. In this case you should try the third example first.
Create a new empty Win32 console application project. Give a suitable project name and change the project location if needed.
Then, add the source file and give it a suitable name.
Next, add the following source code.
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>
#define BUFSIZE 4096
int wmain(int argc, WCHAR **argv)
{
LPTSTR lpszCurrentVariable;
// Child process to be executed
WCHAR szAppName[]=L\\\\?\\C:\\amad\\EnvironVar3\\Debug\\EnvironVar3.exe;
// WCHAR szAppName[]=L\\\\?\\C:\\WINDOWS\\system32\\sol.exe;
STARTUPINFO si = {0};
PROCESS_INFORMATION pi = {0};
BOOL fSuccess;
DWORD Ret = 100;
LPTSTR lpszVariable;
LPWCH lpvEnv;
// Get the current process and thread IDs
wprintf(LParent process ID (wmain()) is %u\n, GetCurrentProcessId());
wprintf(LParent thread ID (wmain()) is %u\n, GetCurrentThreadId());
// Get a pointer to the environment block
lpvEnv = GetEnvironmentStrings();
// If the returned pointer is NULL, exit
if (lpvEnv == NULL)
{
wprintf(LGetEnvironmentStrings failed, error %d\n, GetLastError());
return 1;
}
else
wprintf(LGetEnvironmentStrings() is OK!\n);
// Copy environment strings into an environment block
lpszCurrentVariable = lpvEnv;
// Frees a block of environment strings
if(FreeEnvironmentStrings(lpvEnv) != 0)
wprintf(L\nFreeEnvironmentStrings() - a block of environment strings was freed!\n);
else
wprintf(L\nFreeEnvironmentStrings() failed, error %u\n, GetLastError());
if (FAILED(StringCchCopy(lpszCurrentVariable, BUFSIZE, LMyNewEnvSetting=awek gedik)))
{
wprintf(LStringCchCopy() - String copy failed\n);
return 1;
}
else
wprintf(LStringCchCopy() - env var was copied successfully!\n);
lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;
if (FAILED(StringCchCopy(lpszCurrentVariable, BUFSIZE, LMyNewVersion=2.34)))
{
wprintf(LStringCchCopy() - String copy failed\n);
return 1;
}
else
wprintf(LStringCchCopy() - Another env var was copied successfully!\n);
// Terminate the block with a NULL byte
// Variable strings are separated by NULL byte, and the block is
// terminated by a NULL byte
lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;
*lpszCurrentVariable = (WCHAR)0;
// Create the child process, specifying a new environment block
SecureZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
fSuccess = CreateProcess(szAppName, NULL, NULL, NULL, TRUE, NULL,
(LPVOID)lpszCurrentVariable, // new environment block
NULL, &si, &pi);
// Validate
if(!fSuccess)
{
wprintf(LCreateProcess() failed, error %d\n, GetLastError());
return 1;
}
else
{
wprintf(L\nCreateProcess() - Child process was created successfully!\n);
wprintf(LChild process ID is %u\n, pi.dwProcessId);
wprintf(LChild thread ID is %u\n, pi.dwThreadId);
// Verify the current process environment variable
wprintf(L\n);
system(set);
wprintf(L\n);
}
// Get the current env var
lpszVariable = GetEnvironmentStrings();
// If the returned pointer is NULL, exit
if (lpszVariable == NULL)
{
wprintf(LGetEnvironmentStrings() failed, error %d\n, GetLastError());
return 1;
}
else
wprintf(LGetEnvironmentStrings() is OK!\n);
// Try to print it
while(*lpszVariable)
{
wprintf(L%s\n, lpszVariable);
lpszVariable += lstrlen(lpszVariable) + 1;
}
// Frees a block of environment strings
if(FreeEnvironmentStrings(lpszVariable) != 0)
wprintf(L\nFreeEnvironmentStrings() - a block of environment strings was freed!\n);
else
wprintf(L\nFreeEnvironmentStrings() failed, error %u\n, GetLastError());
// Wait for the object to signal
Ret = WaitForSingleObject(pi.hProcess, INFINITE);
wprintf(L\nThe WaitForSingleObject return value is 0X%.8X\n, Ret);
// Close process and thread handles.
if(CloseHandle(pi.hProcess) != 0)
wprintf(Lpi.hProcess handle was closed successfully!\n);
else
wprintf(LFailed to close pi.hProcess handle, error %u\n, GetLastError());
if(CloseHandle(pi.hThread) != 0)
wprintf(Lpi.hThread handle was closed successfully!\n);
else
wprintf(LFailed to close pi.hThread handle, error %u\n, GetLastError());
return 0;
}
The following Application error displayed, however the output is consistent. The bug already solved for execve() or the wexecve() functions if the envp parameter contains an empty string.