Creating the Windows child process with new environment variables

 

 

Compiler: Visual C++ Express Edition 2005

Compiled on Platform: Windows XP Pro SP2

Target platform: none, just for learning and fun

Header file: Standard and Windows

Additional library: Windows Platform SDK

Additional project setting: Set project to be compiled as C

Project -> your_project_name Properties -> Configuration Properties -> C/C++ -> Advanced -> Compiled As: Compiled as C Code (/TC)

Other info: non-CLR or unmanaged. Need to add netapi32.lib (netapi32.dll) to the project. Click the Project menu->Select the your_project_name Properties... sub menu->Expand the Configuration Properties folder on the left pane->Expand the Linker subfolder->Select the Input subfolder->Select the Additional Dependencies field on the right pane->Click the ... at the end of the field->Type in 'netapi32.lib' in the empty pane->Click the OK button->Click the OK button second time to close the project Properties dialog.

To do: Creating child process with new environment variables

To show: More on the Windows thread and process usage - creating and changing the environment variable for child process

 

 

 

 

// For WinXp

#define _WIN32_WINNT 0x0501

#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:\\windows\\system32\\cmd.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"MyNewOwnEnvSetting=ver 2.0")))

{

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

return 1;

}

else

wprintf(L"StringCchCopy() - env variable #1 was copied successfully!\n");

 

lpszCurrentVariable += lstrlen(lpszCurrentVariable) + 1;

if (FAILED(StringCchCopy(lpszCurrentVariable, BUFSIZE, L"MyNewOwnVar=MyPath")))

{

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

return 1;

}

else

wprintf(L"StringCchCopy() - Another env variable #2 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 variable

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;

}

 

Output example:

 

Parent process ID (wmain()) is 4156

Parent thread ID (wmain()) is 6124

GetEnvironmentStrings() is OK!

FreeEnvironmentStrings() - a block of environment strings was freed!

StringCchCopy() - env variable #1 was copied successfully!

StringCchCopy() - Another env variable #2 was copied successfully!

CreateProcess() - Child process was created successfully!

Child process ID is 540

Child thread ID is 4268

Microsoft Windows XP [Version 5.1.2600]

(C) Copyright 1985-2001 Microsoft Corp.

c:\amad\winprocessthread\winprocessthread>COMSPEC=C:\WINDOWS\system32\cmd.exe

MyNewOwnEnvSetting=ver 2.0

MyNewOwnVar=MyPath

PATHEXT=.COM;.EXE;.BAT;.CMD;.VBS;.JS;.WS

PROMPT=$P$G

GetEnvironmentStrings() is OK!

MyNewOwnEnvSetting=ver 2.0

MyNewOwnVar=MyPath

FreeEnvironmentStrings() - a block of environment strings was freed!

c:\amad\winprocessthread\winprocessthread>exit

The WaitForSingleObject return value is 0X00000000

pi.hProcess handle was closed successfully!

pi.hThread handle was closed successfully!

Press any key to continue . . .

 

 

C and C++ Programming Resources | C & C++ Code Example Index