Моя цель — запустить процесс пользовательского интерфейса в сеансе пользователя, вошедшего в систему из моей локальной службы. Я примерно делаю следующее:
//Pseudo-code, with error checks omitted
HANDLE hToken;
WTSQueryUserToken(dwUserSessionID, &hToken);
HANDLE hToken2;
DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, NULL, SecurityIdentification, TokenPrimary, &hToken2);
//Need to adjust UIAccess for the needs of the user process
DWORD dwUIAccess = 1;
SetTokenInformation(hToken2, TokenUIAccess, &dwUIAccess, sizeof(dwUIAccess));
ImpersonateLoggedOnUser(hToken2);
CreateProcessAsUser(hToken2, strUserExeFilePath, ...);
RevertToSelf();
CloseHandle(hToken2);
CloseHandle(hToken);
Это работает, и пользовательский процесс запускается просто отлично, но есть одна проблема с его уровень целостности. Когда этот код запускается сразу после установки службы (когда пользовательский сеанс долго входил в систему) создаваемый им пользовательский процесс имеет SECURITY_MANDATORY_MEDIUM_RID
это уровень, который я бы ожидал.
Но если приведенный выше код запускается сразу после входа интерактивного пользователя Windows на рабочую станцию, запускается пользовательский процесс, но он имеет SECURITY_MANDATORY_HIGH_RID
уровень целостности. (Я тестирую его на Windows 7.)
Поэтому я подумал добавить следующий код для настройки уровня целостности:
PSID pSidIL = NULL;
//INFO on SID: https://support.microsoft.com/en-us/kb/243330?wa=wsignin1.0
ConvertStringSidToSid(L"S-1-16-8192", &pSidIL);
TOKEN_MANDATORY_LABEL tml = {0};
tml.Label.Attributes = SE_GROUP_INTEGRITY;
tml.Label.Sid = pSidIL;
SetTokenInformation(hToken2, TokenIntegrityLevel, &tml, sizeof(TOKEN_MANDATORY_LABEL) + ::GetSidLengthRequired(1));
LocalFree(pSidIL);
но это не имело никакого значения, и пользовательский процесс все еще работал с high
уровень целостности после входа пользователя.
Есть идеи, что я здесь делаю не так?
Задача ещё не решена.