/************************************************************
Module name: Inherit.c
Notices: Copyright (c) 2000 Jeffrey Richter
************************************************************/
#include <Windows.h>
int WINAPI WinMain (HINSTANCE hinstExe, HINSTANCE,
PSTR pszCmdLine, int nCmdShow) {
// Подготовка STARTUPINFO стркутуры для порождения процессов.
STARTUPINFO si = { sizeof(si) };
SECURITY_ATTRIBUTES saProcess, saThread;
PROCESS_INFORMATION piProcessB, piProcessC;
TCHAR szPath[MAX_PATH];
// Подготовка к порождению процесса B из процесса A.
// Дескриптор идентифицирует новый процесс
// объект должен быть наследуемым.
saProcess.nLength = sizeof(saProcess);
saProcess.lpSecurityDescriptor = NULL;
saProcess.bInheritHandle = TRUE;
// Дескриптор идентифицирует новый поток
// объект должен быть не наследуемым.
saThread.nLength = sizeof(saThread);
saThread.lpSecurityDescriptor = NULL;
saThread.bInheritHandle = FALSE;
// Порождение процесса B.
lstrcpy(szPath, TEXT("ProcessB"));
CreateProcess(NULL, szPath, &saProcess, &saThread,
FALSE, 0, NULL, NULL, &si, &piProcessB);
// Стркутура piProcessB содержит два дескриптора
// относящихся к процессу A:
// hProcess, который идентифицирует наследуемый объект процесса B
// и hThread, который идентифицирует объект ядра – главный поток
// процесса B и не является наследуемым.
|
|
// Подготовка к порождению процесса C из процесса A.
// Так NULL передается для параметров psaProcess и psaThread
//, дескрипторы к объектам процесс и
// главный поток процесса С – по умолчанию ненаследуемые
// Если процесс A породит другой новый процесс, этот новый процесс
// не наследует дескрипторы к объектам процесса и потка процесса С.
// Так TRUE передается в качестве параметра bInheritHandles,
// Процесс C будет наследовать десриптор идентифицирующий процесс
// B но не будет наследовать дескриптор его главного потока.
lstrcpy(szPath, TEXT("ProcessC"));
CreateProcess(NULL, szPath, NULL, NULL,
TRUE, 0, NULL, NULL, &si, &piProcessC);
return(0);
}
Создавая процесс В, система формирует объекты ядра «процесс» и «поток», а за тем — в структуре, на которую указывает параметр ppiProcInfo, — возвращает их описатели процессу А, и с этого момента тот может манипулировать только что созданными объектами «процесс» и «поток».
Теперь предположим, что процесс А собирается вторично вызвать функцию CreateProcess, чтобы породить процесс С. Сначала ему нужно определить, стоит ли предоставлять процессу С доступ к своим объектам ядра. Для этого используется параметр blnberitHandles, если он приравнен TRUE, система передаст процессу С все наследуемые описатели в этом случае наследуется и описатель объекта ядра "процесс" процесса В. А вот описатель объекта "первичный поток" процесса В не наследуется ни при каком значении bInberitHandles. Кроме того, если процесс А вызывает CreateProcess, передавая через параметр blnberitHandles значение FALSE, процесс С не наследует никаких описателей, используемых в данный момент процессом А.