我有两个程序,Parent
和Kid
我希望孩子在父母使用CreateProcess
创建孩子之后得到孩子的父母的帮助。传递此句柄的最简单方法似乎是将Handle放在CreateProcess
的命令行参数中,但是我看不到将Parent的Handle放入Parent的方法。 GetCurrentProcess
返回一个奇怪的非值,并且DuplicateHandle
在没有孩子的句柄的情况下不起作用(不可能,因为我需要创建孩子来获得它的句柄,但是CreateProcess
也是将“父母之手”发送给孩子的唯一机会。
有什么办法可以使Kid
容易处理吗?{p}?
答案 0 :(得分:2)
传递此句柄的最简单方法似乎是将句柄放在
CreateProcess
的命令行参数中
这是一种方法,但这不是 only 方法。
另一种简单的方法是让Parent
将其进程ID从GetCurrentProcessId()
发送到Kid
,然后Kid
可以使用OpenProcess()
来获取句柄Parent
。
我无法看到将“家长的句柄”放入“家长”内部。
GetCurrentProcess()
,它返回代表调用过程的伪句柄。在调用进程的上下文中使用时,所有接受进程句柄的API都将接受此伪句柄。
但是,为了将调用进程的句柄传递到另一个进程,Parent
必须使用DuplicateHandle()
将伪句柄转换为真实句柄(将Parent
设置为两个源和目标过程)。这是记录的行为。
GetCurrentProcess
返回一个奇怪的非值,并且DuplicateHandle
在没有儿童手柄的情况下不起作用
Parent
将伪句柄从GetProcessHandle()
复制到真实句柄之后,然后可以在命令行上将复制的副本传递给Kid
。只要确保副本是可继承的,然后在bInheritHandles=TRUE
调用中使用CreateProcess()
,或将STARTUPINFOEX
传递到包含CreateProcess()
的{{1}}(请参阅{{ 3}})。
不可能,因为我需要创建一个Kid来处理它
如果您不想使用可继承的句柄,那么PROC_THREAD_ATTRIBUTE_HANDLE_LIST
可以创建Parent
而不在命令行上传递任何句柄,然后将Kid
伪句柄复制为{ {1}}作为目标进程,然后使用您选择的IPC机制在副本已运行后将其发送到GetCurrentProcess()
。
但是
Kid
也是将父母的把柄传给孩子的唯一机会
不,这不是 only 方式。 IPC是另一种方式。
答案 1 :(得分:1)
尝试从其自己的进程句柄获取父PID:
DWORD pid = GetProcessId(Parent);
然后在给定pid的孩子中,取回手柄:
OpenProcess(PROCESS_ALL_ACCESS, TRUE, pid);
PID可以带数字,因此很容易传递。
有关更多详细信息,请参见以下内容:
答案 2 :(得分:0)
首先,我们需要获取Kid中父进程的进程ID。这可以通过与ProcessBasicInformation
一起调用NtQueryInformationProcess
来完成。在PROCESS_BASIC_INFORMATION
内部(在 ntddk.h 中声明的此结构)内部存在InheritedFromUniqueProcessId
成员。严格说来,如果您在创建Kid时使用PROC_THREAD_ATTRIBUTE_PARENT_PROCESS
,这可能不是父进程ID,但是如果您在调用CreateProcess
-InheritedFromUniqueProcessId
时不使用此属性,它将是您的父级进程ID。
我们需要理解的是,父级可以终止,并且在此新进程之后以相同的ID开始。因此,在使用InheritedFromUniqueProcessId
打开进程之后,我们需要检查它是否确实是父进程,而不是在父进程退出并重新使用此ID之后创建的新进程。这可以通过查询进程的开始时间来完成-显然,如果不是父进程,它是在父退出后(无法重用此ID之前)已经启动的,并且在他启动Kid之后退出了。因此InheritedFromUniqueProcessId
只能在创建时间> =孩子创建时间的情况下才能成为父项。我们可以使用ProcessTimes
通过NtQueryInformationProcess
查询流程创建时间。因此最终代码可以是:
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;
}