如何将句柄传递给子进程 [英] How to pass handle to child process

查看:81
本文介绍了如何将句柄传递给子进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to pass a mutex handle, to a child process trough command line, or any other way.

我该怎么做?我如何从孩子那里访问互斥锁?

How can I do that? How do I acess the mutex from the child?

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

This is how I'm creating the child process:

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
            )                     

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

I need to use the mutex for more than one child process, is it ok?

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

So here is what I'm doing right now:

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

mutex=(int)ghMutex;
itoa(mutexValue,mutexString,10);

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

I'll pass the mutexString trough command line, and then convert it back at child process:

mutexValue=atoi(argv[2]);

Mutex=(HANDLE)mutexValue;

我的问题,可以进行(HANDLE)铸造吗??

My question, is it okay to do the (HANDLE) casting??

推荐答案

两个选项:

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

  1. You can use named objects. Process A creates the Mutex with a name and then spawns Process B. Process B then calls OpenMutex or CreateMutex with the same name, and it will get a handle to the same mutex.

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

Drawbacks are in name selection. If you have a name collision, you can get unpredictable results. An attacker could create a mutex with the same name and create a denial of service situation. One way to deal with this is to generate the name randomly. For example, Process A could generate a GUID for the name, and then pass that GUID (as a string) on the command line to Process B.

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

You can use inheritance. Child processes can inherit many types of handles from the parent process, including mutex handles. Set the bInheritHandles parameters in the CreateProcess command (which your sample is already doing), and pass the value of the handle (as a string) on the command line to the child process. The child process can then convert the command line string back to a value and simply start using it. The value is the same in both processes.

这种技术没有命名对象技术的缺点.

This technique doesn't have the same drawbacks as the named object technique.

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

A working example of inheritance (error checking elided):

#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;
}

这篇关于如何将句柄传递给子进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆