2015-12-09 10 views
0

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

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

Я перекинул свой код в тестовое приложение, чтобы поэкспериментировать с части процесса и мьютекса, и я нашел что-то удивительное: если я вызову OpenMutex из пользовательского приложения без предварительного создания мьютекса, я бы ожидал, Обнаружена ошибка, но я все равно получаю отказ в доступе. Однако, если я запускаю пользовательское приложение из Проводника (shift-right-click, Run as different user ...), я получаю ожидаемое поведение. Я также заметил, что пользовательское приложение имеет обычную блочную рамку окна, а не обычную тему Windows при запуске из приложения admin.

Так что я предполагаю, что что-то не так с тем, как я запускаю пользовательское приложение, но я просто не вижу, что мне не хватает.

Вот соответствующие части:

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; 
} 
+0

Проблема вряд ли будет связана с тем, как вы создаете процесс. Вам нужно показать код, который открывает мьютекс. (У вас все еще есть «доступ запрещен», а не «не найден», если вы сначала перезагрузите машину?) –

ответ

0

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

+0

Это ... очень странно. Мьютекс - это объект ядра, поэтому рабочий стол, на котором вы работаете, не влияет. (Сеанс удаленного рабочего стола делает для неглобальных объектов, но это не приведет к ошибке Access Denied.) Возможно, проблема заключалась не в том, что дочерний процесс не мог открыть мьютекс, но он не мог работать при все? –