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);
}
Program Development using Unix Home