【问题标题】:OpenMutex fails in process opened with CreateProcessAsUserOpenMutex 在使用 CreateProcessAsUser 打开的进程中失败
【发布时间】:2015-12-09 16:25:04
【问题描述】:

这几天我一直在思考这个问题,我一定已经阅读了互联网上的每一页,即使是远程相关的,但我仍然找不到答案。救命!

场景如下:在 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;
}

【问题讨论】:

  • 问题不太可能与您创建流程的方式有关。您需要显示打开互斥锁的代码。 (如果你先重启机器,你是否仍然得到“访问被拒绝”而不是“未找到”?)

标签: windows visual-c++ mutex createprocessasuser


【解决方案1】:

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

【讨论】:

  • 这……很奇怪。互斥锁是一个内核对象,因此您运行的桌面没有任何影响。 (对于非全局对象,远程桌面会话确实如此,但这不会产生拒绝访问错误。)也许问题不在于子进程无法打开互斥锁,而是它无法在全部?
猜你喜欢
  • 2014-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多