Windows 内核对象句柄是可以在不同进程之间相互共用的,创建内核对象的函数一般都有一个SECURITY_ATTRIBUTES
类型的参数,此参数中bInheritHandle
为TRUE时表明该内核对象可继承。用 CreateProcess 创建进程时参数bInheritHandles
为TRUE则表示新创建的进程,继承父进程所有可继承的内核对象。此例实现内核文件句柄在父子进程之间的继承共用。
typedef struct _SECURITY_ATTRIBUTES {
DWORD nLength;
LPVOID lpSecurityDescriptor;
BOOL bInheritHandle;
} SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
如下【代码段1】 用 CreateFile 创建了一个可继承的内核对象 h,然后将此变量值保存在进程环境块中。用 CreateProcess 创建子进程时,设置第五个参数为 TRUE,表示子进程继承内核对象 h。
#include <stdio.h>
#include <Windows.h>
int main(int argc, char* argv[])
{
SECURITY_ATTRIBUTES sa;
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
HANDLE h = CreateFile(TEXT("D:\\a.txt"), GENERIC_ALL, FILE_SHARE_READ, &sa, OPEN_ALWAYS, NULL, NULL);
DWORD dwWriten;
WriteFile(h, "Hello ", 6, &dwWriten, NULL);
char szData[16] = { 0 };
_itoa_s((int)h, szData, 10);
SetEnvironmentVariableA("hFileObj", szData);
PROCESS_INFORMATION pi;
STARTUPINFO si = { sizeof(si) };
CreateProcess(TEXT("D:\\1.exe"), NULL, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
WaitForInputIdle(h, 10 * 1000);
system("pause");
CloseHandle(h);
system("pause");
return 0;
}
如下【代码段2】 利用 GetEnvironmentVariable 函数从进程环境块中取父进程传递过来的内核对象 h 的值(子进程默认继承父进程的进程环境块),然后就可以对该该对象进程操作。
#include <stdio.h>
#include <windows.h>
int main()
{
char szData[16] = { 0 };
GetEnvironmentVariableA("hFileObj", szData, _countof(szData));
MessageBoxA(0, szData, 0, 0);
HANDLE h = (HANDLE)atoi(szData);
DWORD dwWriten;
WriteFile(h, "World", 5, &dwWriten, NULL);
CloseHandle(h);
return 0;
}
将【代码段2】生成的 1.exe 放在 D:盘根路径下,然后运行【代码段1】生成的exe,查看 D:\a.txt 内容。