0

几天来我一直在努力解决这个问题,我一定已经阅读了互联网上的每一页,即使是远程相关的,但我仍然找不到答案。帮助!

这是场景:在 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;
}
4

1 回答 1

0

我永远无法让 CreateProcessAsUser 调用正常工作,但我最终使用 CreateProcessWithLogonW 让它工作。诀窍是将 si.lpDesktop 设置为 NULL 而不是“winsta0\default”,这与我到目前为止阅读的所有内容相反。

于 2015-12-16T12:26:54.807 回答