C 将匿名管道句柄传递给子进程

C 将匿名管道句柄传递给子进程,c,windows,C,Windows,我希望将匿名管道句柄传递给子进程。答案似乎解释它很好的C++,但是我想这样做在C. < /P> 我是否将句柄转换为整数?还是将句柄的内存地址传递给子进程,然后创建另一个指向该句柄的句柄 例如: 家长: BOOL bCreatePipe, bReadFile; HANDLE hRead = NULL; HANDLE hWrite = NULL; SECURITY_ATTRIBUTES lpPipeAttributes; lpPipeAttributes.nL

我希望将匿名管道句柄传递给子进程。答案似乎解释它很好的C++,但是我想这样做在C. < /P> 我是否将句柄转换为整数?还是将句柄的内存地址传递给子进程,然后创建另一个指向该句柄的句柄

例如:

家长:

    BOOL bCreatePipe, bReadFile;
    HANDLE hRead = NULL;
    HANDLE hWrite = NULL;
    SECURITY_ATTRIBUTES lpPipeAttributes;
    lpPipeAttributes.nLength = sizeof(lpPipeAttributes);
    lpPipeAttributes.lpSecurityDescriptor = NULL;
    lpPipeAttributes.bInheritHandle = TRUE;

    // Create pipe file descriptors for parent and child
    bCreatePipe = CreatePipe(&hRead, &hWrite, &lpPipeAttributes, (DWORD)BUFFER_SIZE);
    if (bCreatePipe == FALSE) {
        printf("[-]Error creating IPC pipe : %d", GetLastError());
        exit(-1);
    }

    // Create command line arguments for child process
    snprintf(child_cmd, CMD_LINE_SIZE, "%d", &hWrite);

    // Create child process to handle request
    if ( !CreateProcess(
         "C:\\Users\\Child.exe",        // No module name (use command line)
         child_cmd,      // Command line
         NULL,           // Process handle not inheritable
         NULL,           // Thread handle not inheritable
         TRUE,           // Set handle inheritance to TRUE (for pipe)
         0,              // No creation flags
         NULL,           // Use parent's environment block
         NULL,           // Use parent's starting directory
         &si,            // Pointer to STARTUPINFO structure
         &pi)            // Pointer to PROCESS_INFORMATION structure
         )
    {
        printf("[-]CreateProcess failed : %d\n", GetLastError());
        exit(-1);
    }
儿童:

// Set variables to arguments passed by parent 
HANDLE hWrite = atoi(argv[0]);

是的,这是通过值传递
HANDLE
ok。实际上,目前您的代码可以正常工作。但是需要记住的是,
HANDLE
在64位系统上是64位大小的-因此不适合32位大小的
int
(现在用户模式句柄值实际上适合32位)。因此,需要使用say
%I64x
格式对句柄值进行编码,并使用
\u atoi64
\u wcstoi64
进行解码

例如,在父项中:

WCHAR child_cmd[32];
swprintf(child_cmd, L"<%I64x>", (ULONG64)(ULONG_PTR)hWrite);
WCHAR child_cmd[32];
swprintf(child_cmd,L“”(ULONG64)(ULONG_PTR)hWrite);
儿童:

HANDLE hWrite = 0;
if (PWSTR sz = wcschr(GetCommandLineW(), '<'))
{
    hWrite = (HANDLE)(ULONG_PTR)_wcstoi64(sz + 1, &sz, 16);
    if (*sz != '>')
    {
        hWrite = 0;
    }
}
handlehwrite=0;
如果(PWSTR sz=wcschr(GetCommandLineW(),“”)
{
hWrite=0;
}
}

另请注意-使用
CreatePipe
不是最佳选择-此api设计非常糟糕,例如一个句柄仅用于写入,另一个句柄仅用于读取,无法选择异步I/O,无法使一个句柄继承另一个句柄(在这种情况下需要)-最好使用
CreateNamedPipeW
+
CreateFileW
来创建管道对。或者,如果您不想在管道上使用名称,则使用这种方式(从win7开始工作)<肖恩>:使用Windows可能会更容易。@:这似乎是使用Windows,其中命名管道比UNIX类型系统复杂得多。您链接到的答案非常少,就是C++特定的,只是<代码> CUT<代码>(用<代码> PRINTF < /代码>替换)并忽略全局API调用开始时的
::
。包含的文件可能是
stdio.h
windows.h
句柄是一个
无符号int
。向子进程传递地址通常是毫无意义的,因为它有不同的地址空间。@cdarke-
句柄
is不是
无符号整数
(始终为32位)-它是
无效*
因此
UINT\u PTR
如果需要(64位系统中为64位)@RbMm:对不起,那就改了。