以下代码有时会毫无问题地工作,有时会抛出“访问被拒绝”错误。行为不一致。
_hMutex = CreateMutex(NULL, FALSE, MutexName);
if (_hMutex == NULL)
{
throw MY_ERROR(GetLastError(), L"Error creating mutex handle");
}
我运行具有此代码的独立可执行文件,执行操作并退出。它不是多线程应用程序。每次运行时都会使用相同的用户凭据登录。
你能帮我解决这个问题吗?
谢谢, 下摆
答案 0 :(得分:2)
如果互斥锁是一个已命名的互斥锁,并且该对象在此函数调用之前存在,则返回值是现有对象的句柄, GetLastError 返回ERROR_ALREADY_EXISTS
,bInitialOwner被忽略,并且调用线程未被授予所有权。
但是,如果呼叫者具有有限的访问权限,则该功能将失败并显示ERROR_ACCESS_DENIED
,并且呼叫者应使用 OpenMutex 功能。
答案 1 :(得分:1)
这可能是因为已存在MutexName
的互斥锁。您正在使用默认安全描述符创建互斥锁,该安全描述符(取决于您使用此互斥锁的方式)可能不允许其他用途。
有关详情,请参阅MSDN。一个有用的片段:
如果互斥锁是一个命名的互斥锁,并且该对象在此之前存在 函数调用,[省略],如果 调用者具有有限的访问权限,该函数将失败
ERROR_ACCESS_DENIED
和调用者应该使用OpenMutex函数。
答案 2 :(得分:0)
我终于找到了。有一个服务与系统帐户一起运行,该帐户创建互斥锁和用户尝试访问它时运行的exe。这是由于许可。
答案 3 :(得分:0)
今天我遇到了类似的问题,但会话不同。
互斥体已命名并具有前缀 Global\
。
当一个应用程序创建命名的全局互斥锁时,不允许不同用户帐户的其他应用程序与同一个互斥锁同步。
CreateMutex 始终返回错误 ERROR_ACCESS_DENIED
。 OpenMutex 成功,但无法使用互斥锁进行同步。
解决方案是每个应用程序都必须使用 CreateMutexEx
访问全局互斥锁(仅请求 SYNCHRONIZE
)并且您必须指定 SecurityAttributes。默认的 SecurityAttributes 不允许在用户帐户之间共享。
工作代码如下:
HANDLE hMutex;
{
DWORD dwRes, dwDisposition;
PSID pEveryoneSID = NULL;
PACL pACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea[1];
SID_IDENTIFIER_AUTHORITY SIDAuthWorld =
SECURITY_WORLD_SID_AUTHORITY;
SECURITY_ATTRIBUTES sa;
LONG lRes;
// Create a well-known SID for the Everyone group.
if(!AllocateAndInitializeSid(&SIDAuthWorld, 1,
SECURITY_WORLD_RID,
0, 0, 0, 0, 0, 0, 0,
&pEveryoneSID))
{
_tprintf(_T("AllocateAndInitializeSid Error %u\n"), GetLastError());
goto Cleanup;
}
// Initialize an EXPLICIT_ACCESS structure for an ACE.
// The ACE will allow Everyone read access to the key.
ZeroMemory(&ea, 1 * sizeof(EXPLICIT_ACCESS));
ea[0].grfAccessPermissions = SYNCHRONIZE;
ea[0].grfAccessMode = SET_ACCESS;
ea[0].grfInheritance= NO_INHERITANCE;
ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
ea[0].Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
ea[0].Trustee.ptstrName = (LPTSTR) pEveryoneSID;
// Create a new ACL that contains the new ACEs.
dwRes = SetEntriesInAcl(1, ea, NULL, &pACL);
if (ERROR_SUCCESS != dwRes)
{
_tprintf(_T("SetEntriesInAcl Error %u\n"), GetLastError());
goto Cleanup;
}
// Initialize a security descriptor.
pSD = (PSECURITY_DESCRIPTOR) LocalAlloc(LPTR,
SECURITY_DESCRIPTOR_MIN_LENGTH);
if (NULL == pSD)
{
_tprintf(_T("LocalAlloc Error %u\n"), GetLastError());
goto Cleanup;
}
if (!InitializeSecurityDescriptor(pSD,
SECURITY_DESCRIPTOR_REVISION))
{
_tprintf(_T("InitializeSecurityDescriptor Error %u\n"),
GetLastError());
goto Cleanup;
}
// Add the ACL to the security descriptor.
if (!SetSecurityDescriptorDacl(pSD,
TRUE, // bDaclPresent flag
pACL,
FALSE)) // not a default DACL
{
_tprintf(_T("SetSecurityDescriptorDacl Error %u\n"),
GetLastError());
goto Cleanup;
}
// Initialize a security attributes structure.
sa.nLength = sizeof (SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = pSD;
sa.bInheritHandle = FALSE;
hMutex = CreateMutexExW(&sa, L"Global\\MyNamedMutex", 0, SYNCHRONIZE);
Cleanup:
if (pEveryoneSID)
FreeSid(pEveryoneSID);
if (pAdminSID)
FreeSid(pAdminSID);
if (pACL)
LocalFree(pACL);
if (pSD)
LocalFree(pSD);
}
// Do something with hMutex
WaitForSingleObject(hMutex, INFINITE);
CloseHandle(hMutex);
源链接: