如何将重复的句柄传递给子进程?

And*_*ash 2 c++ winapi

我使用 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)

Rem*_*eau 5

如果在父进程中调用DuplicateHandle(),则必须将子进程指定为目标进程,接受新复制的句柄,然后使用您选择的 IPC 机制将复制的句柄发送给子进程,例如:

\n\n
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}\n
Run Code Online (Sandbox Code Playgroud)\n\n

否则,让子进程成为调用的进程DuplicateHandle()。您可以通过命令行或其他 IPC 机制将父进程的进程 ID 和所需的句柄值传递给子进程,然后让子进程打开进程 ID,并在准备复制源句柄时OpenProcess()调用DuplicateHandle()

\n\n

否则,您可以将所需句柄创建为可继承(或SetHandleInformation()在创建后将其标记为可继承),然后将CreateProcess()参数bInheritHandles设置为 TRUE 进行调用。请注意,这将继承所有可继承的句柄,除非您以编程方式指定子进程可以继承哪些句柄STARTUPINFOEX而不是使用STARTUPINFOVista 和更高版本)。

\n\n

另一方面,您试图共享一个信号量,它可以分配一个名称,因此您应该创建一个分配了名称的信号量,然后将该名称传递给子进程,以便它可以创建/打开自己的信号量使用相同名称的信号量句柄。这是记录的行为,并且是跨进程边界共享内核对象的首选方式:

\n\n
\n

如果函数成功,返回值是信号量对象的句柄。如果命名信号量对象在函数调用之前存在,则该函数返回现有对象的句柄并\xc2\xa0 GetLastError\xc2\xa0返回ERROR_ALREADY_EXISTS

\n
\n