几天来我一直在努力解决这个问题,我一定已经阅读了互联网上的每一页,即使是远程相关的,但我仍然找不到答案。帮助!
这是场景:在 Windows 7 中,我有一个在管理员用户帐户(不是服务)下运行的进程。它创建了一个名为 mutex 的全局名称,稍后将用于在常规用户帐户下运行的子进程中。无论我做什么,或者我在互斥体上放置什么 ACL,子进程在尝试获取句柄时都会不断返回 Access Denied。
我已经将我的代码提取到一个测试应用程序中,只是为了试验进程和互斥体部分,我发现了一些令人惊讶的事情:如果我在没有首先创建互斥体的情况下从用户应用程序调用 OpenMutex,我预计会出现 Not Found 错误,但我仍然获得拒绝访问。但是,如果我从资源管理器启动用户应用程序(shift-right-click,Run as different user...),我会得到预期的行为。我还注意到,当从管理应用程序启动时,用户应用程序有一个普通的块状窗口边框,而不是正常的 Windows 主题。
所以我的猜测是我启动用户应用程序的方式有问题,但我看不出我错过了什么。
以下是相关部分:
bool CUserTest::LogInUser()
{
if ((m_hUserToken == NULL) && !LogonUser(TEST_USER_NAME, L".", TEST_USER_PASS, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, &m_hUserToken))
{
CloseHandle(m_hUserToken);
m_hUserToken = NULL;
}
return (m_hUserToken != NULL);
}
bool CUserTest::LaunchTestApp()
{
PROCESS_INFORMATION ProcInfo;
STARTUPINFO si;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(si);
si.lpDesktop = L"winsta0\\default";
wchar_t wszCmdLine[MAX_PATH + 1] = { 0 };
wcscpy(wszCmdLine, L"UserTestClient.exe");
bool bSuccess = false;
LPVOID pEnv;
PROFILEINFO sProfileInfo;
ZeroMemory(&sProfileInfo, sizeof(PROFILEINFO));
sProfileInfo.dwSize = sizeof(PROFILEINFO);
sProfileInfo.lpUserName = TEST_USER_NAME;
if (LoadUserProfile(m_hUserToken, &sProfileInfo))
{
if (ImpersonateLoggedOnUser(m_hUserToken))
{
if (CreateEnvironmentBlock(&pEnv, m_hUserToken, FALSE))
{
bSuccess = CreateProcessAsUser(
m_hUserToken,
NULL,
wszCmdLine,
NULL, // ProcessAttributes
NULL, // ThreadAttributes
FALSE, // InheritHandles
CREATE_UNICODE_ENVIRONMENT, // CreationFlags
pEnv, // Environment
NULL, // CurrentDirectory
&si,
&ProcInfo); // ProcessInformation
DestroyEnvironmentBlock(pEnv);
}
RevertToSelf();
}
UnloadUserProfile(m_hUserToken, sProfileInfo.hProfile);
}
if (bSuccess)
{
CloseHandle(ProcInfo.hThread);
CloseHandle(ProcInfo.hProcess);
}
return bSuccess;
}