我使用 DuplicateHandle 向子进程共享一个内核对象,我需要将该对象的句柄传输给该进程,该怎么做?
int main() {
STARTUPINFO cif;
ZeroMemory(&cif, sizeof(STARTUPINFO));
PROCESS_INFORMATION pi;
CreateProcess("sp.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL,
&cif, &pi);
HANDLE Semaphore = CreateSemaphore(NULL, 0, 1, NULL);
DuplicateHandle(GetCurrentProcess(), Semaphore, pi.hProcess, NULL,
DUPLICATE_SAME_ACCESS, FALSE, 0);
WaitForSingleObject(Semaphore, INFINITE);
cout << "Test3: access granted";
CloseHandle(pi.hProcess);
CloseHandle(Semaphore);
}
Run Code Online (Sandbox Code Playgroud)
如果在父进程中调用DuplicateHandle(),则必须将子进程指定为目标进程,接受新复制的句柄,然后使用您选择的 IPC 机制将复制的句柄发送给子进程,例如:
int main() {\n STARTUPINFO cif;\n ZeroMemory(&cif, sizeof(cif));\n cif.cb = sizeof(cif);\n\n PROCESS_INFORMATION pi;\n ZeroMemory(&pi, sizeof(pi));\n\n if (!CreateProcess("sp.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, \n &cif, &pi))\n {\n cout << "Test3: CreateProcess failed";\n }\n else\n {\n HANDLE hSemaphore = CreateSemaphore(NULL, 0, 1, NULL);\n if (!hSemaphore)\n {\n cout << "Test3: CreateSemaphore failed";\n }\n else\n {\n HANDLE hDupSemaphore = NULL;\n\n if (!DuplicateHandle(GetCurrentProcess(), hSemaphore, pi.hProcess, &hDupSemaphore, DUPLICATE_SAME_ACCESS, FALSE, 0))\n {\n cout << "Test3: DuplicateHandle failed";\n }\n else\n {\n // send hDupSemaphore to child process via IPC ...\n\n if (WaitForSingleObject(hSemaphore, INFINITE) == WAIT_OBJECT_0)\n {\n cout << "Test3: access granted";\n ReleaseSemaphore(hSemaphore, 1, NULL);\n }\n else\n cout << "Test3: WaitForSingleObject failed";\n\n CloseHandle(hDupSemaphore);\n }\n\n CloseHandle(hSemaphore);\n }\n\n CloseHandle(pi.hThread);\n CloseHandle(pi.hProcess);\n }\n\n return 0;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n否则,让子进程成为调用的进程DuplicateHandle()。您可以通过命令行或其他 IPC 机制将父进程的进程 ID 和所需的句柄值传递给子进程,然后让子进程打开进程 ID,并在准备复制源句柄时OpenProcess()调用DuplicateHandle()。
否则,您可以将所需句柄创建为可继承(或SetHandleInformation()在创建后将其标记为可继承),然后将CreateProcess()参数bInheritHandles设置为 TRUE 进行调用。请注意,这将继承所有可继承的句柄,除非您以编程方式指定子进程可以继承哪些句柄STARTUPINFOEX而不是使用STARTUPINFOVista 和更高版本)。
另一方面,您试图共享一个信号量,它可以分配一个名称,因此您应该创建一个分配了名称的信号量,然后将该名称传递给子进程,以便它可以创建/打开自己的信号量使用相同名称的信号量句柄。这是记录的行为,并且是跨进程边界共享内核对象的首选方式:
\n\n\n\n如果函数成功,返回值是信号量对象的句柄。如果命名信号量对象在函数调用之前存在,则该函数返回现有对象的句柄并\xc2\xa0
\nGetLastError\xc2\xa0返回ERROR_ALREADY_EXISTS。