C++ 如何使每个进程都能访问同步互斥体?
我需要使用全局互斥来同步多个进程对共享文件的访问。我创建互斥体如下:C++ 如何使每个进程都能访问同步互斥体?,c++,windows,winapi,synchronization,mutex,C++,Windows,Winapi,Synchronization,Mutex,我需要使用全局互斥来同步多个进程对共享文件的访问。我创建互斥体如下: HANDLE hMutex = ::CreateMutex(NULL, FALSE, L"Global\\MySpecialName"); 然后将其用于: //Entering critical section VERIFY(::WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0); 然后: //Leave critical section VERIFY(::Rel
HANDLE hMutex = ::CreateMutex(NULL, FALSE, L"Global\\MySpecialName");
然后将其用于:
//Entering critical section
VERIFY(::WaitForSingleObject(hMutex, INFINITE) == WAIT_OBJECT_0);
然后:
//Leave critical section
VERIFY(::ReleaseMutex(hMutex));
问题产生于这样一个事实,即共享此互斥体的进程是本地系统服务和几个使用登录用户凭据运行的用户模式进程。因此,如果互斥首先由服务创建,那么当用户模式进程尝试打开它时,CreateMutex
失败,错误代码为error\u ACCESS\u DENIED
在创建互斥体之前,我正在阅读为互斥体指定一个安全描述符的内容,但我似乎不知道如何通过
一切来访问互斥体,我真的不需要任何复杂性吗?以下是我使用的,基于:
请参阅创建一个安全描述符的示例,该描述符授予每个人读取权限。@JonathanPotter:我想我遇到过类似的情况。您可以看到,问题是这一行One ACE允许对每个人进行读取访问
——在我的情况下,我需要对每个人进行完全访问,因为我也在同步互斥锁。另外KEY\u ALL\u access
在我的情况下不适用。我需要什么来代替互斥--FILE\u ALL\u ACCESS
或GENERIC\u ALL
?如果你问我,对于本地系统服务拥有和使用的东西,对每个人进行完全访问是一个非常不明智的想法。当然,除非安全根本不重要。任何人的读访问都有点问题,因为任何人都可以通过等待互斥锁来阻止服务。最终,攻击者迟早会获得互斥锁。所以他从来没有发布过,现在呢?这项服务永远被封锁。但是如果有写权限,某人可以关闭手柄。如果您的进程没有为此做好准备,它可能会异常中止。@Damon:好的,那么您将如何实现对共享资源的进程间同步?谢谢。你能解释一下D:(A;;GA;;;WD)(A;;GA;;;AN)S:(ML;;NW;;;ME)
翻译成什么吗?这篇文章中都提到了。“D:(A;;GA;;;WD)(A;;GA;;;AN)S:(ML;;NW;;;ME)->中等完整性”。是的,我看到了。我试图理解所有这些疯狂的符号是什么意思“D:(A;;GA;;WD)(A;;GA;;AN)S:(ML;;NW;;;ME”?你可以读一下。对不起。我尝试了你的方法,但如果我让我的用户模式进程在安全性_强制_低_RID
下运行,它就不起作用了。我仍然从CreateMutex
中得到错误_访问
HANDLE hMutex = NULL;
DWORD dwError;
// Create a global mutex
pSecDesc = MakeAllowAllSecurityDescriptor();
if(pSecDesc)
{
SECURITY_ATTRIBUTES SecAttr;
SecAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
SecAttr.lpSecurityDescriptor = pSecDesc;
SecAttr.bInheritHandle = FALSE;
hMutex = CreateMutex(&SecAttr, TRUE, MUTEX_NAME);
dwError = GetLastError();
LocalFree(pSecDesc);
}
//
// From http://blogs.msdn.com/b/winsdk/archive/2009/11/10/access-denied-on-a-mutex.aspx
//
PSECURITY_DESCRIPTOR MakeAllowAllSecurityDescriptor(void)
{
WCHAR *pszStringSecurityDescriptor;
if(GetWindowsVersion(NULL) >= 6)
pszStringSecurityDescriptor = L"D:(A;;GA;;;WD)(A;;GA;;;AN)S:(ML;;NW;;;ME)";
else
pszStringSecurityDescriptor = L"D:(A;;GA;;;WD)(A;;GA;;;AN)";
PSECURITY_DESCRIPTOR pSecDesc;
if(!ConvertStringSecurityDescriptorToSecurityDescriptor(pszStringSecurityDescriptor, SDDL_REVISION_1, &pSecDesc, NULL))
return NULL;
return pSecDesc;
}