Reputation: 12992
I have two programs, Parent
and Kid
I want Kid to get the Handle of Parent after Parent creates Kid using CreateProcess
. The easiest way to transmit this handle seems to be by putting the Handle in the commandline arguments of CreateProcess
, but there is no way I can see to get the Parent's Handle inside Parent. GetCurrentProcess
returns a weird non-value, and DuplicateHandle
doesn't work without having the Kid's Handle (Impossible, since I need to create the Kid to get a Handle to it, but CreateProcess
is also the only chance to send the Parent's Handle to the Kid).
Is there any way I can give Kid
it's Parent's
Handle easily?
Upvotes: 1
Views: 1502
Reputation: 5155
Try getting the parent PID from its own process handle:
DWORD pid = GetProcessId(Parent);
Then in the child, given the pid, get the handle back:
OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
The PID can easily be passed around since its a number.
See the following for more details:
Upvotes: 1
Reputation: 33706
first of all we need get process id of parent process in Kid. this can be done by call NtQueryInformationProcess
with ProcessBasicInformation
. and inside PROCESS_BASIC_INFORMATION
(this structure declared in ntddk.h ) exist InheritedFromUniqueProcessId
member. strictly say this is can be not parent process id in case you use PROC_THREAD_ATTRIBUTE_PARENT_PROCESS
when create Kid, but if you not use this attribute when call CreateProcess
- the InheritedFromUniqueProcessId
- this will be your parent process id.
than we need understand, that parent can terminated and after this new process start with the same id. so after we open process with InheritedFromUniqueProcessId
we need check that this is really parent, but not new process, created after parent exit and reusing this id. this can be done by query process start time - obviously if this not parent process it started already after parent exit (before this id can not be reused), and parent exit after he start kid. so InheritedFromUniqueProcessId
can be not parent only in case it create time >= kid create time. we can query process create time by ProcessTimes
with NtQueryInformationProcess
. so final code can be:
NTSTATUS OpenParent(PHANDLE phProcess, ULONG DesiredAccess)
{
HANDLE hProcess;
KERNEL_USER_TIMES kut, _kut;
PROCESS_BASIC_INFORMATION pbi;
NTSTATUS status;
if (0 <= (status = NtQueryInformationProcess(
NtCurrentProcess(), ProcessBasicInformation,
&pbi, sizeof(pbi), 0)) &&
0 <= (status = NtQueryInformationProcess(
NtCurrentProcess(), ProcessTimes,
&kut, sizeof(kut), 0)))
{
static OBJECT_ATTRIBUTES zoa = { sizeof(zoa) };
CLIENT_ID cid = { (HANDLE)pbi.InheritedFromUniqueProcessId };
if (0 <= (status = NtOpenProcess(&hProcess, DesiredAccess|
PROCESS_QUERY_LIMITED_INFORMATION, &zoa, &cid)))
{
if (0 > (status = NtQueryInformationProcess(
hProcess, ProcessTimes, &_kut, sizeof(_kut), 0)) ||
kut.CreateTime.QuadPart <= _kut.CreateTime.QuadPart)
{
NtClose(hProcess);
return STATUS_PROCESS_IS_TERMINATING;
}
*phProcess = hProcess;
}
}
return status;
}
Upvotes: 0
Reputation: 595392
The easiest way to transmit this handle seems to be by putting the Handle in the commandline arguments of
CreateProcess
That is one way to do it, but it is not the only way.
Another simple way is to have Parent
send its process ID from GetCurrentProcessId()
to Kid
, and then Kid
can use OpenProcess()
to get a handle to Parent
.
there is no way I can see to get the Parent's Handle inside Parent.
GetCurrentProcess()
, which returns a pseudo-handle representing the calling process. All APIs that accept a process handle will accept this pseudo-handle when used in the context of the calling process.
But, for purposes of passing the calling process's handle to another process, Parent
would have to use DuplicateHandle()
to convert the pseudo-handle into a real handle (set Parent
as both source and target process). This is documented behavior.
GetCurrentProcess
returns a weird non-value, andDuplicateHandle
doesn't work without having the Kid's Handle
After Parent
has duplicated the pseudo-handle from GetProcessHandle()
into a real handle, it can then pass that duplicate to Kid
on the command line. Just make sure the duplicate is inheritable, and then use bInheritHandles=TRUE
in the CreateProcess()
call, or pass a STARTUPINFOEX
to CreateProcess()
containing a PROC_THREAD_ATTRIBUTE_HANDLE_LIST
(see Programmatically controlling which handles are inherited by new processes in Win32).
Impossible, since I need to create the Kid to get a Handle to it
If you don't want to use inheritable handles, then Parent
can alternatively create Kid
without passing any handle on the command line, then duplicate the GetCurrentProcess()
pseudo-handle with Kid
as the target process, then use an IPC mechanism of your choosing to send the duplicate to Kid
after it is already running.
but
CreateProcess
is also the only chance to send the Parent's Handle to the Kid
No, it is not the only way. IPC is another way.
Upvotes: 3