代码之家  ›  专栏  ›  技术社区  ›  Wizard

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

  •  1
  • Wizard  · 技术社区  · 6 年前

    我想将匿名管道句柄传递给子进程。 This 答案似乎解释它很好的C++,但是我想在C.做这件事

    例如:

        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]);
    
    1 回复  |  直到 4 年前
        1
  •  1
  •   RbMm    6 年前

    是的,这没问题 HANDLE 按价值。实际上,目前你的代码可以正常工作。但是你要记住 手柄 是64位系统上的64位大小-因此不适合 int 是32位大小( 现在用户模式句柄值实际上适合32位 ). 所以我需要说 %I64x _atoi64 _wcstoi64 解码。

    例如,在父级中:

    WCHAR child_cmd[32];
    swprintf(child_cmd, L"<%I64x>", (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;
        }
    }
    

    作为单独注释-使用 CreatePipe 不是最好的选择-这个api设计非常糟糕,比如一个句柄只用于写,另一个句柄只用于读,不能选择异步I/O,不能使一个句柄继承而另一个不继承(在这种情况下根据需要)-更好地使用 CreateNamedPipeW CreateFileW 用于创建管道对。或 this 如果你想在管道上没有名字(从win7工作)