Всем привет.
Снова запуск приложения из сервиса. Нашел несколько вариантов, все варианты проблемные. Нормального описания того, что тут происходит я тоже найти не могу, поэтому ваще не врубаюсь что тут делается... какие-то жетоны... :)
Короче, под 32-х разрядными windows xp и сервером 2003 все нормально работает. Сервер 2012 64бит вываливается на WTSQueryUserToken : 1008 An attempt was made to reference a token that does not exist
Других операционок проверить у меня нет. Дайте списать рабочий код, плиз. :)
function LaunchApplication(FileName: string): Boolean;
var pi: PROCESS_INFORMATION;
si: STARTUPINFO;
dwSessionId, winlogonPid, DesiredAccess,erno: DWORD;
hUserToken, hUserTokenDup, hPToken, hProcess, hsnap: THandle;
dwCreationFlags: DWORD;
procEntry: TProcessEntry32;
winlogonSessId: DWORD;
tp, tpko: Windows.TTokenPrivileges;
Buffer: DWORD;
lpenv: pointer;
ok: boolean; text: string;
label ex;
begin
Result := False;
hUserToken := 0;
hUserTokenDup := 0;
hPToken := 0;
hProcess := 0;
dwSessionId := WTSGetActiveConsoleSessionId;
hSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap = INVALID_HANDLE_VALUE) then exit;
procEntry.dwSize := sizeof(TPROCESSENTRY32);
ok := Process32First(hSnap, procEntry);
if not ok then exit;
winlogonPid := 0;
repeat
winlogonSessId := 0;
ok := ProcessIdToSessionId(procEntry.th32ProcessID, @winlogonSessId);
if (ok and (winlogonSessId = dwSessionId))
then begin
winlogonPid := procEntry.th32ProcessID;
break;
end;
until (not Process32Next(hSnap, procEntry));
ok := WTSQueryUserToken(dwSessionId, @hUserToken);
if not ok
then begin
erno := GetLastError;
text := 'WTSQueryUserToken : ' + inttostr(erno) + ' ' + SysErrorMessage(erno);
AddStr2File(text,'test.txt');
goto ex;
end;
dwCreationFlags := NORMAL_PRIORITY_CLASS or CREATE_NEW_CONSOLE;
ZeroMemory(@si, sizeof(STARTUPINFO));
si.cb := sizeof(STARTUPINFO);
si.lpDesktop := PChar('Winsta0\Default');
ZeroMemory(@pi, sizeof(pi));
hProcess := OpenProcess(MAXIMUM_ALLOWED, FALSE, winlogonPid);
DesiredAccess := TOKEN_ALL_ACCESS or TOKEN_ADJUST_SESSIONID or TOKEN_READ or TOKEN_WRITE;
ok := OpenProcessToken(GetCurrentProcess, DesiredAccess, hPToken);
if not ok
then begin
erno := GetLastError;
text := 'OpenProcessToken : ' + inttostr(erno) + ' ' + SysErrorMessage(erno);
AddStr2File(text,'test.txt');
goto ex;
end;
ok := LookupPrivilegeValue(nil, SE_DEBUG_NAME, tp.Privileges[0].Luid);
if not ok
then begin
erno := GetLastError;
text := 'LookupPrivilegeValue : ' + inttostr(erno) + ' ' + SysErrorMessage(erno);
AddStr2File(text,'test.txt');
goto ex;
end;
tp.PrivilegeCount := 1;
tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
ok := DuplicateTokenEx(hPToken, MAXIMUM_ALLOWED , nil, SecurityIdentification, TokenPrimary, hUserTokenDup);
if not ok
then begin
erno := GetLastError;
text := 'DuplicateTokenEx : ' + inttostr(erno) + ' ' + SysErrorMessage(erno);
AddStr2File(text,'test.txt');
goto ex;
end;
ok := SetTokenInformation(hUserTokenDup, TTokenInformationClass(ord(TokenSessionId)),
@dwSessionId, sizeof(dwSessionId));
if not ok
then begin
erno := GetLastError;
text := 'SetTokenInformation : ' + inttostr(erno) + ' ' + SysErrorMessage(erno);
AddStr2File(text,'test.txt');
goto ex;
end;
ok := AdjustTokenPrivileges(hUserTokenDup, FALSE, tp, sizeof(tp), tpko, Buffer);
if not ok
then begin
erno := GetLastError;
text := 'AdjustTokenPrivileges : ' + inttostr(erno) + ' ' + SysErrorMessage(erno);
AddStr2File(text,'test.txt');
goto ex;
end;
lpEnv := nil;
ok := CreateEnvironmentBlock(lpEnv, hUserTokenDup, TRUE);
if ok
then dwCreationFlags := dwCreationFlags or CREATE_UNICODE_ENVIRONMENT or PROFILE_USER
else lpEnv := nil;
CreateProcessAsUser(hUserTokenDup, PChar(FileName), nil, nil, nil, FALSE, dwCreationFlags,lpEnv, nil, si, pi);
ex:
CloseHandle(hUserToken);
CloseHandle(hPToken);
CloseHandle(hProcess);
CloseHandle(hUserTokenDup);
end;