How to pass a handle to a child process

I am trying to pass a mutex handle to the command line of a child process or in any other way.

How can i do this? How can I use a mutex from a child?

This is how I create 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 environment block NULL, // Use parent starting directory &si[j], // Pointer to STARTUPINFO structure &pi[j] ) // Pointer to PROCESS_INFORMATION structure ) 

EDIT:

I need to use mutexes for more than one child process, ok?

So here is what I am doing right now:

 HANDLE ghMutex; int mutex; char mutexstring[7]; mutex=(int)ghMutex; itoa(mutexValue,mutexString,10); 

I will pass the mutexString command line and then convert it back to a child process:

 mutexValue=atoi(argv[2]); Mutex=(HANDLE)mutexValue; 

My question is, is casting (HANDLE) good?

+4
source share
3 answers

Two options:

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

    Shortcomings in the choice of name. If you have a name clash, you might 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 create a random name. For example, Process A can generate a GUID for a name, and then pass that GUID (as a string) to the command line for process B.

  • You can use inheritance . Processes of child processes can inherit many types of descriptors from the parent process, including mutex descriptors. Set the bInheritHandles parameters in the CreateProcess command (which is already in your example) and pass the descriptor value (as a string) to the command line of the child process. Then the child process can convert the command line to a value and just start using it. The value in both processes is the same.

This method does not have the same drawbacks as the method of a named object.

Working example of inheritance (error checking completed):

 #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; } 
+5
source

Create a mutex before creating the child process and make it inheritable (set bInheritHandle to TRUE in the lpMutexAttributes parameter for CreateMutex). This way you can pass the handle to the command line.

Or use a DuplicateHandle and pass the handle through some other mechanism (for example, use a pipe like STDIN for the child process).

+1
source

You must perform IPC (interport communication) for this purpose. There are many IPC methods on Windows, for example:

  • Clipboard
  • COM
  • Rpc
  • Data copy
  • ...

See this article in MSD N for more details.

-1
source

All Articles