{Starter of Notify program}
procedure TAMNotifier1.StartApp(const App, Parameters, CurDir : TJwString);
var
pi : PROCESS_INFORMATION;
si : STARTUPINFO;
dwSessionId : DWORD;
winlogonPid : DWORD;
hUserToken : THANDLE;
hUserTokenDup : THANDLE;
hPToken : THANDLE;
hProcess : THANDLE;
hsnap : THANDLE;
dwCreationFlags : DWORD;
procEntry : TPROCESSENTRY32;
winlogonSessId : DWORD;
tp : TOKEN_PRIVILEGES;
lpenv : pointer;
err : boolean;
pCurDir : TJwPChar;
pCmdLine : TJwPChar;
begin
pCmdLine := TJwPChar('"'+App+'" ' + Parameters);
pCurDir := Nil;
if Length(CurDir) > 0 then
pCurDir := TJwPChar(CurDir);
dwSessionId := WTSGetActiveConsoleSessionId();
hSnap := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap = INVALID_HANDLE_VALUE) then
exit;
procEntry.dwSize := sizeof(TPROCESSENTRY32);
repeat
if (comparetext(procEntry.szExeFile, 'winlogon.exe') = 0) then
begin
winlogonSessId := 0;
if (ProcessIdToSessionId(procEntry.th32ProcessID, winlogonSessId)
and (winlogonSessId = dwSessionId)) then
begin
winlogonPid := procEntry.th32ProcessID;
break;
end;
end;
until (not Process32Next(hSnap, procEntry));
WTSQueryUserToken(dwSessionId, hUserToken);
dwCreationFlags := NORMAL_PRIORITY_CLASS or CREATE_NEW_CONSOLE;
ZeroMemory(@si, sizeof(STARTUPINFO));
si.cb := sizeof(STARTUPINFO);
si.lpDesktop := 'winsta0\Winlogon';
ZeroMemory(@pi, sizeof(pi));
hProcess := OpenProcess(MAXIMUM_ALLOWED,FALSE,winlogonPid);
if(not OpenProcessToken(hProcess,TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY
or TOKEN_DUPLICATE or TOKEN_ASSIGN_PRIMARY or TOKEN_ADJUST_SESSIONID
or TOKEN_READ or TOKEN_WRITE, hPToken)) then
Err := True;
if (not LookupPrivilegeValue(nil,SE_DEBUG_NAME,
tp.Privileges[0].Luid)) then
Err := True;
tp.PrivilegeCount := 1;
tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
DuplicateTokenEx(hPToken,MAXIMUM_ALLOWED,Nil,
SecurityIdentification,TokenPrimary,hUserTokenDup);
SetTokenInformation(hUserTokenDup,
TokenSessionId,pointer(dwSessionId),sizeof(DWORD));
if (not AdjustTokenPrivileges(hUserTokenDup,FALSE,@
tp,sizeof(TOKEN_PRIVILEGES),
nil,nil)) then
Err := True;
if (GetLastError() = ERROR_NOT_ALL_ASSIGNED) then
Err := True;
lpEnv := nil;
if(CreateEnvironmentBlock(lpEnv,hUserTokenDup,TRUE)) then
dwCreationFlags := dwCreationFlags or CREATE_UNICODE_ENVIRONMENT
else
lpEnv := nil;
CreateProcessAsUser(hUserTokenDup,TJwPChar(App), pCmdLine,
nil, nil, FALSE, dwCreationFlags, lpEnv, pCurDir, si, pi );
CloseHandle(hProcess);
CloseHandle(hUserToken);
CloseHandle(hUserTokenDup);
CloseHandle(hPToken);
end;