Program Development using Unix Win32 Process API

Contents

Process information
Process creation
Waiting
Inheriting information
Processes in Win32 are largely independant from their parents, and are more like tasks.

Process information

Current process information is returned to the parent when a child is created. This is
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

Process creation

To create a new process, use
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;
    }
}

Waiting

The function
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.

Inheriting information

The new process does not inherit information from the parent. Open files are not inherited, for example, unlike Unix.

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);
}
Home Program Development using Unix Home
Jan Newmarch (http://jan.newmarch.name)
jan@newmarch.name
Last modified: Wed Nov 19 18:49:08 EST 1997
Copyright ©Jan Newmarch