我正在尝试将互斥锁句柄传递给子进程槽命令行或其他任何方式。
我该怎么做? 我如何从孩子那里获得互斥锁?
这就是我创建子进程的方式:
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
)
编辑:
我需要将互斥锁用于多个子进程,可以吗?
所以这就是我现在正在做的事情:
HANDLE ghMutex;
int mutex;
char mutexstring[7];
mutex=(int)ghMutex;
itoa(mutexValue,mutexString,10);
我将传递mutexString trough命令行,然后在子进程中将其转换回来:
mutexValue=atoi(argv[2]);
Mutex=(HANDLE)mutexValue;
我的问题,是否可以进行(HANDLE)投射?
答案 0 :(得分:5)
两个选项:
您可以使用命名对象。进程A使用名称创建Mutex,然后生成进程B.进程B然后调用具有相同名称的OpenMutex或CreateMutex,它将获得相同互斥锁的句柄。
缺点是名称选择。如果您发生名称冲突,则可能会产生不可预测的结果。攻击者可以创建具有相同名称的互斥锁并创建拒绝服务情况。解决此问题的一种方法是随机生成名称。例如,进程A可以为名称生成GUID,然后将命令行上的GUID(作为字符串)传递给进程B.
您可以使用inheritance。子进程可以从父进程继承许多类型的句柄,包括互斥句柄。在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;
}
答案 1 :(得分:1)
在创建子进程之前创建互斥锁并使其可继承(在CreateMutex的lpMutexAttributes参数中将bInheritHandle设置为TRUE)。这样您就可以在命令行中传递句柄。
或者使用DuplicateHandle并通过其他机制传递句柄(例如,使用管道作为子进程的STDIN)。