Сбой 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", вопреки всему, что я читал до этого момента.