如何使每个进程都具有访问权限的同步互斥锁?

时间:2013-12-14 05:36:08

标签: 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(::ReleaseMutex(hMutex));

问题产生于共享此互斥锁的进程是本地系统服务以及使用已登录用户的凭据运行的多个用户模式进程。因此,如果服务首次创建互斥锁,那么当用户模式进程尝试打开它时,CreateMutex将失败并显示错误代码ERROR_ACCESS_DENIED

我正在阅读在创建互斥锁之前为互斥锁指定安全描述符,但我似乎无法弄清楚如何通过everything访问它,我真的不需要任何复杂性吗?

1 个答案:

答案 0 :(得分:4)

以下是我使用的内容,基于this article

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