function RunProcessInSession(SessionID:dword; AExeName,AParamStr:string):boolean;
var
StartUpInfo: TStartUpInfo;
ProcessInfo: TProcessInformation;
hProcessToken,hNewToken:THandle;
cmd:WideString;
begin
{$IFDEF dm}_log('RunProcessInSession start '+AExeName+' '+AParamStr,false,1);{$ENDIF}
result:=false;
{$IFDEF dm}_log('call OpenProcessToken',false,0,5);{$ENDIF}
if WindowsError(func_OpenProcessToken(func_GetCurrentProcess,MAXIMUM_ALLOWED,hProcessToken)) then
begin
{$IFDEF dm}_log('Oops... fail to OpenProcessToken',false,-1);{$ENDIF}
exit;
end;
{$IFDEF dm}_log('call DuplicateTokenEx',false,0,5);{$ENDIF}
if WindowsError(func_DuplicateTokenEx(hProcessToken,TOKEN_ALL_ACCESS or TOKEN_READ or TOKEN_WRITE or TOKEN_EXECUTE,nil,SecurityDelegation,TokenPrimary,hNewToken)) then
begin
{$IFDEF dm}_log('Oops... fail to DuplicateTokenEx',false,-1);{$ENDIF}
func_CloseHandle(hProcessToken);
exit;
end;
{$IFDEF dm}_log('call SetTokenInformation',false,0,5);{$ENDIF}
if WindowsError(func_SetTokenInformation(hNewToken,TokenSessionId,@SessionID,sizeof(SessionID))) then
begin
{$IFDEF dm}_log('Oops... fail to SetTokenInformation',false,-1);{$ENDIF}
func_CloseHandle(hProcessToken);
func_CloseHandle(hNewToken);
exit;
end;
FillChar(ProcessInfo, SizeOf(TProcessInformation), 0);
FillChar(StartUpInfo, SizeOf(TStartUpInfo), 0);
with StartUpInfo do
begin
cb := SizeOf(TStartUpInfo);
dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK;
wShowWindow := SW_SHOWNORMAL;
lpDesktop := PChar('winsta0\default');
end;
cmd:=AExeName+' '+AParamStr;
{$IFDEF dm}_log('call CreateProcessAsUser',false,0,5);{$ENDIF}
result:=func_CreateProcessAsUserW(hNewToken,
nil,
PWideChar(cmd),
nil,
nil,
FALSE,
NORMAL_PRIORITY_CLASS or CREATE_UNICODE_ENVIRONMENT,
nil,
nil,
StartUpInfo,
ProcessInfo);
if not WindowsError(result) then
begin
result:=true;
func_CloseHandle(ProcessInfo.hThread);
func_CloseHandle(ProcessInfo.hProcess);
end
else
begin
{$IFDEF dm}_log('Oops... fail to CreateProcessAsUser',false,0,3);{$ENDIF}
end;
func_CloseHandle(hProcessToken);
func_CloseHandle(hNewToken);
{$IFDEF dm}_log('RunProcessInSession end',false,-1);{$ENDIF}
end;