Reputation: 568
I used DuplicateHandle for sharing a kernel object to the child process, I need to transfer handle of this object to that process, how to do this?
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);
}
Upvotes: 2
Views: 2505
Reputation: 598384
If you call DuplicateHandle()
in the parent process, you must specify the child process as the target process, accept the newly duplicated handle, and then use an IPC mechanism of your choosing to send the duplicated handle to the child process, eg:
int main() {
STARTUPINFO cif;
ZeroMemory(&cif, sizeof(cif));
cif.cb = sizeof(cif);
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
if (!CreateProcess("sp.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL,
&cif, &pi))
{
cout << "Test3: CreateProcess failed";
}
else
{
HANDLE hSemaphore = CreateSemaphore(NULL, 0, 1, NULL);
if (!hSemaphore)
{
cout << "Test3: CreateSemaphore failed";
}
else
{
HANDLE hDupSemaphore = NULL;
if (!DuplicateHandle(GetCurrentProcess(), hSemaphore, pi.hProcess, &hDupSemaphore, DUPLICATE_SAME_ACCESS, FALSE, 0))
{
cout << "Test3: DuplicateHandle failed";
}
else
{
// send hDupSemaphore to child process via IPC ...
if (WaitForSingleObject(hSemaphore, INFINITE) == WAIT_OBJECT_0)
{
cout << "Test3: access granted";
ReleaseSemaphore(hSemaphore, 1, NULL);
}
else
cout << "Test3: WaitForSingleObject failed";
CloseHandle(hDupSemaphore);
}
CloseHandle(hSemaphore);
}
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
return 0;
}
Otherwise, have the child process be the one to call DuplicateHandle()
instead. You can pass the parent's process ID and desired handle value to the child process via the command-line or other IPC mechanism, and then have the child process open the process ID with OpenProcess()
and call DuplicateHandle()
when it is ready to duplicate the source handle.
Otherwise, you can create the desired handle as inheritable (or use SetHandleInformation()
to mark it as inheritable after it is created), and then call CreateProcess()
with the bInheritHandles
parameter set to TRUE. Note that this will inherit ALL inheritable handles, unless you programmatically specify which handles the child process can inherit using STARTUPINFOEX
instead of STARTUPINFO
(Vista and later only).
On the other hand, you are trying to share a Semaphore, which can have a name assigned to it, so you should just create the semaphore with a name assigned and then pass that name to the child process so it can create/open its own semaphore handle using the same name. This is documented behavior, and is the preferred way to share kernel objects across process boundaries:
If the function succeeds, the return value is a handle to the semaphore object. If the named semaphore object existed before the function call, the function returns a handle to the existing object and
GetLastError
returnsERROR_ALREADY_EXISTS
.
Upvotes: 5