Сбой OpenMutex в процессе, открытом с помощью CreateProcessAsUser

Я уже несколько дней бьюсь об этом, и, должно быть, я прочитал каждую страницу в Интернете, даже отдаленно связанную, но я все еще не могу найти ответ. Помогите!

Вот сценарий: в Windows 7 у меня есть процесс, работающий под учетной записью администратора (не службы). Он создает глобальное имя mutex, которое позже используется в дочернем процессе, работающем под учетной записью обычного пользователя. Независимо от того, что я делаю или какие ACL-списки я ставлю на мьютекс, дочерний процесс продолжает возвращать Access Denied при попытке получить дескриптор.

Я переместил свой код в тестовое приложение, просто чтобы поэкспериментировать с частями процесса и мьютекса, и обнаружил кое-что удивительное: если я вызываю OpenMutex из пользовательского приложения без предварительного создания мьютекса, я ожидаю ошибку Not Found, но я все еще получить доступ запрещен. Однако, если я вместо этого запускаю пользовательское приложение из Проводника (щелчок правой кнопкой мыши, Запуск от имени другого пользователя...), я получаю ожидаемое поведение. Я также заметил, что пользовательское приложение имеет простую блочную границу окна, а не обычную тему 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;
}

1 ответ

Я никогда не мог заставить вызов CreateProcessAsUser работать правильно, но я наконец заставил его работать, используя CreateProcessWithLogonW вместо этого. Хитрость заключалась в том, чтобы установить si.lpDesktop в NULL, а не в "winsta0\default", вопреки всему, что я читал до этого момента.

Другие вопросы по тегам