function WTSQueryUserToken(SessionId: ULONG; var phToken: THandle): BOOL;
stdcall; external 'Wtsapi32.dll';
procedure CreateProcessByUser;
var SessionId: DWORD; UserToken: THandle; Hndl, Hnd: THandle; luid: Int64;
newPriv, oldPriv: TTokenPrivileges; odlPrivLen: Cardinal; si: TStartupInfo;
pi: TProcessInformation;
begin
SessionId := WtsGetActiveConsoleSessionID;
if SessionId = $FFFFFFFF then Exit;
var
processHandle := GetCurrentProcess;
if OpenProcessToken(processHandle, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY,
Hndl) then begin
LookupPrivilegevalue(nil, SE_TCB_NAME, luid);
newPriv.PrivilegeCount := 1;
newPriv.Privileges[0].luid := luid;
newPriv.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
if AdjustTokenPrivileges(Hndl, False, newPriv, Sizeof(oldPriv), oldPriv,
odlPrivLen) then begin
if WTSQueryUserToken(SessionId, UserToken) then begin
DuplicateTokenEx(UserToken, TOKEN_ASSIGN_PRIMARY or TOKEN_ALL_ACCESS,
nil, SecurityIdentification, TokenPrimary, Hnd);
try
ZeroMemory(@si, Sizeof(si));
si.cb := Sizeof(si);
si.lpDesktop := PChar('winsta0\Default');
si.dwFlags := STARTF_USESHOWWINDOW;
si.wShowWindow := SW_HIDE;
ZeroMemory(@pi, Sizeof(pi));
CreateProcessAsUser(Hnd, PChar('C:\Windows\system32\cmd.exe'), PChar( '/C ' + TDirectory.GetCurrentDirectory + '\emsms.exe'), nil,
nil, False, CREATE_NEW_CONSOLE, nil, nil, si, pi);
finally
CloseHandle(UserToken);
end;
end;
end;
end;
end;