SECURITY_ATTRIBUTES 句柄繼承

調用 CreateProcess 創建進程時,可以讓子進程繼承父進程句柄表中可以被繼承的內核對象。
一個內核對象能夠被繼承,必須在創建時通過 SECURITY_ATTRIBUTES 結構指定可繼承;另一個條件是 CreateProcess 第五個參數 bInheritHandles 必須設置爲 TRUE.
下面通過一個例子演示句柄繼承。

創建兩個控制檯程序扮演父進程和子進程,其中,內核對象使用事件來舉例,使用了命令行參數傳遞事件句柄。子進程啓動後,獲取命令行參數,得到事件句柄,這樣就完成了內核對象的繼承,本質上是把父進程句柄表中的事件複製到子進程的句柄表中。

父進程中,在 SetEvent 調用處設置斷點,以便觀察。

父進程

// ParentProcess.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <WINDOWS.H>

int main(int argc, char* argv[])
{
	char szBuffer[256] = {0};
	// 創建可繼承內核對象必須在 SECURITY_ATTRIBUTES 中指定可繼承
	SECURITY_ATTRIBUTES sa;
	sa.nLength = sizeof(sa);
	sa.lpSecurityDescriptor = NULL;
	sa.bInheritHandle = TRUE;
	// 創建可繼承的內核對象
	HANDLE hEvent = CreateEvent(&sa, TRUE, FALSE, NULL);	
	sprintf(szBuffer, "c:\\SubProcess.exe %x", hEvent);
	STARTUPINFO si = {0};
	PROCESS_INFORMATION pi;
	si.cb = sizeof(si);
	CreateProcess(NULL, szBuffer, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
	// 設置事件爲已通知
	SetEvent(hEvent);
	// 關閉句柄,內核對象不會銷燬,因爲子進程已經獲取了該句柄
	CloseHandle(hEvent);

	return 0;
}


子進程

// SubProcess.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <WINDOWS.H>
#include <TCHAR.H>

int main(int argc, char* argv[])
{
	char szBuffer[256] = {0};
	memcpy(szBuffer, argv[1], strlen(argv[1]));
	DWORD dwHandle = 0;
	sscanf(szBuffer, "%x", &dwHandle);
	printf("%s\n", argv[0]);
	printf("%x\n", dwHandle);
	HANDLE hEvent = (HANDLE)dwHandle;
	printf("開始等待事件通知...\n");
	WaitForSingleObject(hEvent, INFINITE);
	DWORD dwCode = GetLastError();
	printf("事件已通知.\n");
	getchar();
	return 0;
}


運行結果
在這裏插入圖片描述
子線程以創建,並在 WaitForSingleObject 處阻塞,當父進程繼續執行 SetEvent ,則事件對象設置爲已通知,子進程 WaitForSingleObject 執行完成。

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章