typedef struct _PROCESS_INFORMATION { HANDLE hProcess; HANDLE hThread; DWORD dwProcessId; DWORD dwThreadId; } PROCESS_INFORMATION;
When a process is started, information can be specified for its startup state. This is given in a structure
typedef struct _STARTUPINFO { DWORD cb; LPTSTR lpReserved; LPTSTR lpDesktop; LPTSTR lpTitle; DWORD dwX; DWORD dwY; DWORD dwXSize; DWORD dwYSize; DWORD dwXCountChars; DWORD dwYCountChars; DWORD dwFillAttribute; DWORD dwFlags; WORD wShowWindow; WORD cbReserved2; LPBYTE lpReserved2; HANDLE hStdOutput; HANDLE hStdError; } STARTUPINFO, *LPSTARTUPINFO;
The system call
GetStartupInfo(LPSTARTUPINFO si)returns this information to the current process. Note the windows information contained in this. The
dwflags
member can be set to
BOOL CreateProcess( LPCTSTR lpApplicationName, // pointer to name of executable module LPTSTR lpCommandLine, // pointer to command line string LPSECURITY_ATTRIBUTES lpProcessAttributes, // pointer to process security a ttributes LPSECURITY_ATTRIBUTES lpThreadAttributes, // pointer to thread security at tributes BOOL bInheritHandles, // handle inheritance flag DWORD dwCreationFlags, // creation flags LPVOID lpEnvironment, // pointer to new environment block LPCTSTR lpCurrentDirectory, // pointer to current directory name LPSTARTUPINFO lpStartupInfo, // pointer to STARTUPINFO LPPROCESS_INFORMATION lpProcessInformation // pointer to PROCESS_INFORMATIO N );
For example,
#include <iostream.h> #include <windows.h> void main(void) { STARTUPINFO startupInfo; PROCESS_INFORMATION procInfo; BOOL success; GetStartupInfo(&startupInfo); success = CreateProcess(NULL, "notepad", NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startupInfo, &procInfo); if (! success) { cerr << "Couldn't create process: " << GetLastError() << endl; } }
DWORD WaitForSingleObject( HANDLE hHandle, // handle of object to wait for DWORD dwMilliseconds // time-out interval in milliseconds );can be used to wait for termination of a process, where the handle to wait on can be found from the
procInfo.hProcess
field
returned to the parent.
It is possible to set up shared resources, but it is a bit cumbersome.
To share an open file, the file must be opened with the
FILE_SHARE_READ
flag set.
In CreateProcess()
the bInheritHandles
flag must
be set to TRUE
. The actual handle to be shared must be
communicated between parent and child. One way of doing this is to
convert the handle to a string, pass the string as a command line parameter
to the child, and in the child convert it back to a handle.
The following example of this is from Marshall Brain Win32 System Services
//*************************************************************** // From the book "Win32 System Services: The Heart of Windows 95 // and Windows NT" // by Marshall Brain // Published by Prentice Hall // // Copyright 1995, by Prentice Hall. // // This code demonstrates the parent side of handle inheritance. //*************************************************************** // parent.cpp #include <windows.h> #include <iostream.h> #include <stdlib.h> HANDLE sample; void main(void) { STARTUPINFO startUpInfo; PROCESS_INFORMATION procInfo; BOOL success; char s[100]; SECURITY_ATTRIBUTES sa; // Set up security attributes to allow // inheritance of the file handle sa.nLength = sizeof(SECURITY_ATTRIBUTES); sa.lpSecurityDescriptor = 0; sa.bInheritHandle=TRUE; // Create a file handle sample = CreateFile("parent.cpp", GENERIC_READ, FILE_SHARE_READ, &sa, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (sample==INVALID_HANDLE_VALUE) cout << "In CreateFile" << GetLastError() << endl; // Init a startup structure GetStartupInfo(&startUpInfo); // convert the sample handle to a string _itoa((DWORD)sample, s, 10); // Create the child process, specifying // inherited handles. Pass the value of the // handle as a command line parameter success=CreateProcess("child.exe", s, 0, 0, TRUE, CREATE_NEW_CONSOLE, 0, 0, &startUpInfo, &procInfo); if (!success) cout << "Error creating process: " << GetLastError() << endl; // wait for the child to return (this // is not a requirement since the child // is its own independent process) WaitForSingleObject(procInfo.hProcess, INFINITE); }with the child as
//*************************************************************** // From the book "Win32 System Services: The Heart of Windows 95 // and Windows NT" // by Marshall Brain // Published by Prentice Hall // // Copyright 1995, by Prentice Hall. // // This code demonstrates the child side of handle inheritance. //*************************************************************** // child.cpp #include <windows.h> #include <iostream.h> #include <stdlib.h> HANDLE sample; void main(int argc, char *argv[]) { char str[200]; DWORD numRead; BOOL success; // Get the handle value off of the command line sample = (HANDLE) atoi(argv[0]); // Now use it like a normal file handle to // read the file success = ReadFile(sample, str, 100, &numRead, 0); if (!success) cout << "In ReadFile: " << GetLastError() << endl; // Output the string read from the file str[numRead] = '\0'; cout << str << endl; Sleep(2000); }