The Windows Processes and Threads 21

 

 

 

 

 

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.

 

Changing Environment Variables Program Examples: Creating new Win32 C++ console application project in Visual C++ .NET

 

Then, add the source file and give it a suitable name.

 

Changing Environment Variables Program Examples: Adding new C++ source file for C++ source code to the existing C++ project

 

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(L"Parent process ID (wmain()) is %u\n", GetCurrentProcessId());

    wprintf(L"Parent 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(L"GetEnvironmentStrings failed, error %d\n", GetLastError());

        return 1;

    }

      else

            wprintf(L"GetEnvironmentStrings() 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, L"MyNewEnvSetting=awek gedik")))

    {

        wprintf(L"StringCchCopy() - String copy failed\n");

        return 1;

    }

      else

            wprintf(L"StringCchCopy() - env var was  copied successfully!\n");

 

    lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;

    if (FAILED(StringCchCopy(lpszCurrentVariable, BUFSIZE, L"MyNewVersion=2.34")))

    {

        wprintf(L"StringCchCopy() - String copy failed\n");

        return 1;

    }

      else

            wprintf(L"StringCchCopy() - 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(L"CreateProcess() failed, error %d\n", GetLastError());

        return 1;

    }

      else

      {

            wprintf(L"\nCreateProcess() - Child process was created successfully!\n");

            wprintf(L"Child process ID is %u\n", pi.dwProcessId);

            wprintf(L"Child 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(L"GetEnvironmentStrings() failed, error %d\n", GetLastError());

        return 1;

    }

      else

            wprintf(L"GetEnvironmentStrings() 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(L"pi.hProcess handle was closed successfully!\n");

      else

            wprintf(L"Failed to close pi.hProcess handle, error %u\n", GetLastError());

   

      if(CloseHandle(pi.hThread) != 0)

            wprintf(L"pi.hThread handle was closed successfully!\n");

      else

            wprintf(L"Failed to close pi.hThread handle, error %u\n", GetLastError());

 

    return 0;

}

 

The following Application error displayed, however the output is consistent. The bug already found for execve() or the wexecve() functions if the envp parameter contains an empty string.

 

Changing Environment Variables Program Examples: A sample console program output in action with error message 1

 

Changing Environment Variables Program Examples: A sample console program output in action with error message 2

 

 

 

< Processes & Threads 20 | Win32 Process & Thread Programming | Win32 Programming | Processes & Threads 22 >