如何将句柄传递给子进程

Cai*_*aio 4 c winapi

我正在尝试将互斥锁句柄传递给子进程槽命令行或任何其他方式.

我怎样才能做到这一点?我如何从孩子那里获得互斥量?

这就是我创建子进程的方式:

HANDLE ghMutex;

     if( !CreateProcess( _T("C:\\Users\\Kumppler\\Documents\\Visual Studio 2010\\Projects\\teste3\\Debug\\teste3.exe"),   // No module name (use command line)
                aux2,                              // Command line
                NULL,                              // Process handle not inheritable
                NULL,                              // Thread handle not inheritable
                TRUE,                              // Set handle inheritance to TRUE
                STARTF_USESTDHANDLES,              // inherit the standard input, standard output, and standard error handles
                NULL,                              // Use parent's environment block
                NULL,                              // Use parent's starting directory 
                &si[j],                            // Pointer to STARTUPINFO structure
                &pi[j] )                           // Pointer to PROCESS_INFORMATION structure
            )                     
Run Code Online (Sandbox Code Playgroud)

编辑:

我需要将互斥锁用于多个子进程,可以吗?

所以这就是我现在正在做的事情:

HANDLE ghMutex;
int mutex;
char mutexstring[7];

mutex=(int)ghMutex;
itoa(mutexValue,mutexString,10);
Run Code Online (Sandbox Code Playgroud)

我将传递mutexString槽命令行,然后在子进程中将其转换回来:

mutexValue=atoi(argv[2]);

Mutex=(HANDLE)mutexValue;
Run Code Online (Sandbox Code Playgroud)

我的问题是,(HANDLE)铸造是否可以?

Adr*_*thy 5

两种选择:

  1. 您可以使用命名对象.进程A使用名称创建Mutex,然后生成进程B.进程B然后调用具有相同名称的OpenMutex或CreateMutex,它将获得相同互斥锁的句柄.

    缺点是名称选择.如果您发生名称冲突,则可能会产生不可预测的结果.攻击者可以创建具有相同名称的互斥锁并创建拒绝服务情况.解决此问题的一种方法是随机生成名称.例如,进程A可以为名称生成GUID,然后在命令行上将该GUID(作为字符串)传递给进程B.

  2. 您可以使用继承.子进程可以从父进程继承许多类型的句柄,包括互斥句柄.在CreateProcess命令(您的示例已在进行)中设置bInheritHandles参数,并将命令行上的句柄值(作为字符串)传递给子进程.然后,子进程可以将命令行字符串转换回值,然后开始使用它.两个过程中的值相同.

该技术与命名对象技术没有相同的缺点.

继承的一个工作示例(错误检查省略):

#include <cstddef>
#include <iostream>
#include <string>
#include <sstream>
#include <windows.h>

void DoParentWork() {
  std::wcout << L"Parent:  Creating an inheritable event..." << std::endl;
  SECURITY_ATTRIBUTES security = {
    sizeof(security), nullptr, /* bInheritHandle = */ TRUE
  };
  HANDLE hEvent = ::CreateEventW(&security, /* bManualReset = */ TRUE,
                                 /* bInitialState = */ FALSE, nullptr);

  std::wstringstream ssCommand;
  ssCommand << L"foo.exe " << reinterpret_cast<std::size_t>(hEvent);
  std::wstring strCmd = ssCommand.str();;

  std::wcout << L"Parent:  Starting child process..." << std::endl;
  STARTUPINFO start_info = {sizeof(start_info)};
  PROCESS_INFORMATION proc_info = {0};
  ::CreateProcessW(L"foo.exe", &strCmd[0], nullptr, nullptr,
                   /* bInheritHandles = */ TRUE, 0, nullptr, nullptr,
                   &start_info, &proc_info);
  ::CloseHandle(proc_info.hThread);
  ::CloseHandle(proc_info.hProcess);

  std::wcout << L"Parent:  Waiting for the child to signal the event."
             << std::endl;
  if (::WaitForSingleObject(hEvent, 10*1000) == WAIT_OBJECT_0) {
    std::wcout << L"Parent:  The event was signaled." << std::endl;
  } else {
    std::wcout << L"Parent:  Timed out waiting for the event."
               << std::endl;
  }
  ::CloseHandle(hEvent);
}

void DoChildWork(const char *pszEvent) {
  std::stringstream ss(pszEvent);
  UINT_PTR iEvent;
  ss >> iEvent;
  HANDLE hEvent = reinterpret_cast<HANDLE>(iEvent);
  std::cout << "Child:  Event handle "
            << reinterpret_cast<std::size_t>(hEvent) << std::endl;
  ::Sleep(2000);
  std::cout << "Child:  Signalling the event." << std::endl;
  ::SetEvent(hEvent);
}

int main(int cArgs, char *ppszArgs[]) {
  if (cArgs > 1) DoChildWork(ppszArgs[1]);
  else DoParentWork();
  return 0;
}
Run Code Online (Sandbox Code Playgroud)