我的目标是在本地服务的登录用户会话中运行我的用户GUI进程。我粗略地做了以下几点:
//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);
这很有效,用户流程也很好,但是integrity level存在一个问题。当此代码在安装服务后立即运行时(当用户会话已经长时间登录时),它创建的用户进程具有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
完整性级别运行。
知道我在这里做错了什么吗?