517 lines
16 KiB
Plaintext
517 lines
16 KiB
Plaintext
unit SeCrmHeMain;
|
||
|
||
interface
|
||
|
||
uses
|
||
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Classes,
|
||
Vcl.Graphics, Vcl.Controls, Vcl.SvcMgr, Vcl.Dialogs;
|
||
|
||
const
|
||
SERVICE_ACCEPT_SESSIONCHANGE = $00000020;
|
||
SERVICE_CONTROL_SESSIONCHANGE = $00000014;
|
||
|
||
WTS_SESSION_LOGON = 5;
|
||
WTS_SESSION_LOGOFF = 6;
|
||
WTS_SESSION_LOCK = 7;
|
||
WTS_SESSION_UNLOCK = 8;
|
||
|
||
SHTDN_REASON_MAJOR_SOFTWARE = $00030000;
|
||
SHTDN_REASON_MINOR_OTHER = $00000000;
|
||
|
||
type
|
||
TSvcCrmHe = class(TService)
|
||
procedure ServicePause(Sender: TService; var Paused: Boolean);
|
||
procedure ServiceStop(Sender: TService; var Stopped: Boolean);
|
||
procedure ServiceExecute(Sender: TService);
|
||
private
|
||
{ Private declarations }
|
||
public
|
||
function GetServiceController: TServiceController; override;
|
||
{ Public declarations }
|
||
end;
|
||
|
||
function CreateEnvironmentBlock(var lpEnvironment: Pointer;
|
||
hToken: THandle;
|
||
bInherit: BOOL): BOOL; stdcall; external 'userenv.dll';
|
||
|
||
var
|
||
SvcCrmHe: TSvcCrmHe;
|
||
|
||
implementation
|
||
|
||
uses
|
||
//{$IFDEF DEBUG}
|
||
// Tocsg.Trace,
|
||
//{$ENDIF}
|
||
Tocsg.Trace,Tocsg.Win32, GlobalDefine, Tocsg.Path, Tocsg.Process, Tocsg.Safe, Tocsg.WTS,
|
||
Tocsg.Kernel32, Tocsg.Shell, Tocsg.Service, Winapi.WinSvc, Tocsg.Registry;
|
||
|
||
{$R *.dfm}
|
||
|
||
function _ExecuteAppAsUser(dwFollowPID: DWORD; sPath, sParam: String; dwVisible: DWORD): TProcessInformation;
|
||
type
|
||
TOKEN_MANDATORY_LABEL = record
|
||
Label_: SID_AND_ATTRIBUTES;
|
||
end;
|
||
const
|
||
DEFWINSTATION = 'WinSta0';
|
||
|
||
DEFDESKTOP = 'Default';
|
||
WINLOGON = 'Winlogon';
|
||
SCREENSAVER = 'Screen-Saver';
|
||
|
||
WHITESPACE = ' '{SPACE}+chr(9){TAB}+chr(10){LF};
|
||
DOMUSERSEP = '\';
|
||
var
|
||
StartupInfo: TStartupInfo;
|
||
ProcessInfo: TProcessInformation;
|
||
dwCreateFlag: DWORD;
|
||
pEnvBlock: Pointer;
|
||
hProc, hToken, hNewToken: THandle;
|
||
TIL: TOKEN_MANDATORY_LABEL;
|
||
begin
|
||
ZeroMemory(@Result, SizeOf(Result));
|
||
ZeroMemory(@ProcessInfo, SizeOf(TProcessInformation));
|
||
ZeroMemory(@TIL, SizeOf(TIL));
|
||
|
||
hToken := 0;
|
||
hNewToken := 0;
|
||
|
||
if dwFollowPID = 0 then
|
||
begin
|
||
{$IFDEF DEBUG} TTgTrace.T('_ExecuteAppAsUser() .. FollowPID is null..'); {$ENDIF}
|
||
exit;
|
||
end;
|
||
|
||
// hProc := OpenProcess(PROCESS_ALL_ACCESS, false, dwFollowPID);
|
||
hProc := OpenProcess(MAXIMUM_ALLOWED, false, dwFollowPID);
|
||
if hProc = 0 then
|
||
begin
|
||
{$IFDEF DEBUG} TTgTrace.T('_ExecuteAppAsUser() .. OpenProcess() - Fail... Error=%d', [GetLastError]); {$ENDIF}
|
||
exit;
|
||
end;
|
||
|
||
try
|
||
// if OpenProcessToken(hProc, TOKEN_ASSIGN_PRIMARY or TOKEN_DUPLICATE, hToken) then
|
||
if OpenProcessToken(hProc, MAXIMUM_ALLOWED, hToken) then
|
||
begin
|
||
// if DuplicateTokenEx(hToken, TOKEN_ASSIGN_PRIMARY or TOKEN_ALL_ACCESS, nil,
|
||
if DuplicateTokenEx(hToken, MAXIMUM_ALLOWED, nil,
|
||
SecurityImpersonation, TokenPrimary, hNewToken) then
|
||
begin
|
||
ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
|
||
StartupInfo.cb := Sizeof(StartupInfo);
|
||
StartupInfo.lpDesktop := DEFWINSTATION + '\' + DEFDESKTOP;
|
||
// StartupInfo.dwFlags := STARTF_USESHOWWINDOW or STARTF_USEPOSITION; // SW_HIDE<44><45><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><>Ű<EFBFBD><C5B0><EFBFBD><EFBFBD> <20>̰<EFBFBD> Ȱ<><C8B0>ȭ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ѵ<EFBFBD> (<28>뼺 ã<><C3A3>) 15_0521 sunk
|
||
StartupInfo.wShowWindow := dwVisible;
|
||
|
||
dwCreateFlag := NORMAL_PRIORITY_CLASS or CREATE_NEW_CONSOLE;
|
||
|
||
pEnvBlock := nil;
|
||
CreateEnvironmentBlock(pEnvBlock, hNewToken, true);
|
||
if pEnvBlock <> nil then
|
||
dwCreateFlag := dwCreateFlag or CREATE_UNICODE_ENVIRONMENT;
|
||
|
||
if CreateProcessAsUserW(hNewToken,
|
||
nil,//PWideChar(ExtractFileName(sPath)),
|
||
PWideChar(Format('"%s" %s', [sPath, sParam])),
|
||
nil,
|
||
nil,
|
||
false,
|
||
dwCreateFlag,
|
||
pEnvBlock,
|
||
nil,//PWideChar(ExtractFilePath(sPath)),
|
||
StartupInfo,
|
||
ProcessInfo) then
|
||
begin
|
||
Result := ProcessInfo;
|
||
end else
|
||
{$IFDEF DEBUG} TTgTrace.T('_ExecuteAppAsUser() .. CreateProcessAsUserW() - Fail... Error=%d', [GetLastError]); {$ENDIF}
|
||
end;
|
||
end else
|
||
{$IFDEF DEBUG} TTgTrace.T('_ExecuteAppAsUser() .. OpenProcessToken() - Fail... Error=%d', [GetLastError]); {$ENDIF}
|
||
finally
|
||
if hToken <> 0 then
|
||
CLoseHandle(hToken);
|
||
if hNewToken <> 0 then
|
||
CloseHandle(hNewToken);
|
||
if hProc <> 0 then
|
||
CloseHandle(hProc);
|
||
end;
|
||
end;
|
||
|
||
|
||
procedure ForceRebootSystem;
|
||
var
|
||
hToken: THandle;
|
||
tkp: TTokenPrivileges;
|
||
ReturnLength: DWORD;
|
||
begin
|
||
// 1. <20><><EFBFBD><EFBFBD> <20><><EFBFBD>μ<EFBFBD><CEBC><EFBFBD><EFBFBD><EFBFBD> <20><>ū<EFBFBD><C5AB> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>غ<EFBFBD>
|
||
if OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
|
||
begin
|
||
// 2. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>(SeShutdownPrivilege)<29><> LUID ȹ<><C8B9>
|
||
LookupPrivilegeValue(nil, 'SeShutdownPrivilege', tkp.Privileges[0].Luid);
|
||
tkp.PrivilegeCount := 1;
|
||
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
|
||
|
||
// 3. <20><>ū<EFBFBD><C5AB> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
|
||
AdjustTokenPrivileges(hToken, False, tkp, 0, nil, ReturnLength);
|
||
CloseHandle(hToken);
|
||
end;
|
||
|
||
// 4. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> (EWX_FORCE <20>ɼ<EFBFBD><C9BC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD> <20><><EFBFBD>α<CEB1> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
|
||
ExitWindowsEx(EWX_REBOOT or EWX_FORCE, SHTDN_REASON_MAJOR_SOFTWARE or SHTDN_REASON_MINOR_OTHER);
|
||
end;
|
||
|
||
procedure ServiceController(CtrlCode: DWord); stdcall;
|
||
begin
|
||
SvcCrmHe.Controller(CtrlCode);
|
||
end;
|
||
|
||
function TSvcCrmHe.GetServiceController: TServiceController;
|
||
begin
|
||
Result := ServiceController;
|
||
end;
|
||
|
||
|
||
procedure TSvcCrmHe.ServiceExecute(Sender: TService);
|
||
var
|
||
sAPath,
|
||
sWPath,
|
||
sCurDir,
|
||
sRunParam,
|
||
sRunAsModule: String;
|
||
bExeBeforeSleep: Boolean;
|
||
dwExeTerm: DWORD;
|
||
// bFailExeTrust: Boolean;
|
||
nFailExeTrustCnt: Integer;
|
||
processInfo: TProcessInformation;
|
||
|
||
function ExecuteAgent(dwOwnerPid: DWORD): THandle;//Boolean;
|
||
var
|
||
t: Integer;
|
||
sTrustedInstExe: String;
|
||
begin
|
||
Result := 0;
|
||
|
||
if FileExists(sWPath) then
|
||
begin
|
||
dwExeTerm := GetTickCount;
|
||
if not DeleteFile(sWPath) then
|
||
begin
|
||
SetFileAttributes(PChar(sWPath), FILE_ATTRIBUTE_NORMAL);
|
||
DeleteFile(sWPath);
|
||
end;
|
||
exit;
|
||
end else
|
||
if dwExeTerm <> 0 then
|
||
begin
|
||
if (GetTickCount - dwExeTerm) < 10000 then
|
||
exit;
|
||
dwExeTerm := 0;
|
||
end;
|
||
|
||
if bExeBeforeSleep then
|
||
begin
|
||
bExeBeforeSleep := false;
|
||
Sleep(3000);
|
||
end;
|
||
|
||
sTrustedInstExe := sCurDir + DIR_CONF + EXE_TRUST;
|
||
// cmd â<><C3A2> <20><><EFBFBD>Դ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> HEC<45><43><EFBFBD><EFBFBD> <20><><EFBFBD>ſ<EFBFBD>û<EFBFBD><C3BB> 23_1208 13:56:30 kku
|
||
if (nFailExeTrustCnt < 3) and FileExists(sTrustedInstExe) then
|
||
begin
|
||
// -U:[ Option ] Create a process with specified user option.
|
||
// Available options:
|
||
// T TrustedInstaller
|
||
// S System
|
||
// C Current User
|
||
// E Current User (Elevated)
|
||
// P Current Process
|
||
// D Current Process (Drop right)
|
||
// PS: This is a mandatory parameter.
|
||
// -UseCurrentConsole - X <20>ƹ<EFBFBD><C6B9><EFBFBD><EFBFBD><EFBFBD> cmd<6D><64> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>Ѿ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD>Ͱ<EFBFBD> <20>ʹ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>.
|
||
|
||
Inc(nFailExeTrustCnt);
|
||
|
||
sRunParam := UpperCase(GetRegValueAsString(HKEY_LOCAL_MACHINE, 'SYSTEM\ControlSet001\Services\SvcCrmHe', 'EA'));
|
||
if sRunParam = 'ADMIN' then
|
||
sRunParam := Format('-U:E -P:E "%s"', [sAPath])
|
||
else if sRunParam = 'USER' then
|
||
sRunParam := Format('-U:C -P:E "%s"', [sAPath])
|
||
else
|
||
sRunParam := Format('-U:T -P:E "%s"', [sAPath]);
|
||
ExecutePath_hide(sTrustedInstExe, sRunParam);
|
||
// ExecutePath_hide(sTrustedInstExe, Format('-U:E -P:E "%s"', [sAPath]));
|
||
// t := 0;
|
||
// while t < 10 do
|
||
// begin
|
||
// if MutexExists(MUTEX_AGENT) then
|
||
// begin
|
||
// nFailExeTrustCnt := 0;
|
||
// Result := true;
|
||
// exit;
|
||
// end;
|
||
//
|
||
// Sleep(500);
|
||
// Inc(t);
|
||
// end;
|
||
|
||
// if _ExecuteAppAsUser(dwOwnerPid, sTrustedInstExe, Format('-U:T -P:E "%s"', [sAPath]), SW_HIDE).dwProcessId <> 0 then
|
||
// begin
|
||
// {$IFDEF DEBUG} TTgTrace.T('ServiceExecute() .. No Agent Mutext .. RunAsModule=%s .. Success!!', [sRunAsModule]); {$ENDIF}
|
||
// Sleep(2000);
|
||
// end else begin
|
||
// {$IFDEF DEBUG} TTgTrace.T('ServiceExecute() .. No Agent Mutext .. RunAsModule=%s .. Fail..... _ExecuteAppAsUser()', [sRunAsModule]); {$ENDIF}
|
||
// bFailExeTrust := true;
|
||
// end;
|
||
end else
|
||
begin
|
||
// if _ExecuteAppAsUser(dwOwnerPid, sAPath, Format('/wlid %d', [dwOwnerPid]), SW_HIDE).dwProcessId <> 0 then
|
||
|
||
// if ExecuteApp(sAPath, '', SW_SHOWNORMAL).dwProcessId <> 0 then // Ʈ<><C6AE><EFBFBD><EFBFBD> <20>ȳ<EFBFBD><C8B3><EFBFBD>
|
||
processInfo:= _ExecuteAppAsUser(dwOwnerPid, sAPath, '', SW_SHOWNORMAL);
|
||
if processInfo.dwProcessId <> 0 then
|
||
begin
|
||
// t := 0;
|
||
// while t < 10 do
|
||
// begin
|
||
// if MutexExists(MUTEX_AGENT) then
|
||
// begin
|
||
// nFailExeTrustCnt := 0;
|
||
// Result := true;
|
||
// exit;
|
||
// end;
|
||
//
|
||
// Sleep(500);
|
||
// Inc(t);
|
||
// end;
|
||
Result:= processInfo.hProcess;
|
||
CloseHandle(processInfo.hThread);
|
||
// if Result then
|
||
// begin
|
||
// {$IFDEF DEBUG} TTgTrace.T('ServiceExecute() .. No Agent Mutext .. RunAsModule=%s .. Success!!', [sRunAsModule]); {$ENDIF}
|
||
// Sleep(2000);
|
||
// end;
|
||
end else begin
|
||
{$IFDEF DEBUG} TTgTrace.T('ServiceExecute() .. No Agent Mutext .. RunAsModule=%s .. Fail..... _ExecuteAppAsUser()', [sRunAsModule]); {$ENDIF}
|
||
end;
|
||
end;
|
||
|
||
// t := 0;
|
||
// while t < 6 do
|
||
// begin
|
||
// if MutexExists(MUTEX_AGENT) then
|
||
// begin
|
||
// Result := true;
|
||
// exit;
|
||
// end;
|
||
//
|
||
// Sleep(500);
|
||
// Inc(t);
|
||
// end;
|
||
|
||
{$IFDEF DEBUG} TTgTrace.T('ServiceExecute() .. No Agent Mutex .. check timeover .. '); {$ENDIF}
|
||
end;
|
||
|
||
var
|
||
PIDList: TProcessIdList;
|
||
WTSInfo: TTgWTSSessionInfomation;
|
||
dwWinLogonSsId,
|
||
dwExecuteAsPid: DWORD;
|
||
sAccount: String;
|
||
i: Integer;
|
||
Mtx: TTgMutex;
|
||
processHandle: THandle;
|
||
WaitHandles: array[0..1] of THandle;
|
||
WaitResult: DWORD;
|
||
|
||
begin
|
||
// bFailExeTrust := false;
|
||
nFailExeTrustCnt := 0;
|
||
dwExeTerm := 0;
|
||
bExeBeforeSleep := false;
|
||
Mtx := nil;
|
||
if not MutexExists(MUTEX_SERVICE) then
|
||
begin
|
||
Mtx := TTgMutex.Create(MUTEX_SERVICE);
|
||
if Mtx.MutexState <> msCreateOk then
|
||
exit;
|
||
end;
|
||
|
||
{$IFDEF DEBUG} TTgTrace.T('ServiceExecute() .. Begin'); {$ENDIF}
|
||
|
||
Guard(WTSInfo, TTgWTSSessionInfomation.Create);
|
||
Guard(PIDList, TProcessIdList.Create);
|
||
sCurDir := GetRunExePathDir;
|
||
sAPath := sCurDir + EXE_HE;
|
||
if not FileExists(sAPath) then
|
||
begin
|
||
sCurDir := GetProgramFilesDir + DIR_HE;
|
||
sAPath := sCurDir + EXE_HE;
|
||
end;
|
||
{$IFDEF DEBUG} TTgTrace.T('APath="%s"', [sAPath]); {$ENDIF}
|
||
sWPath := ExtractFilePath(sAPath) + BYE_ENDSESSION;
|
||
|
||
try
|
||
while not Terminated do
|
||
begin
|
||
if MutexExists(MUTEX_KILL) then
|
||
begin
|
||
{$IFDEF DEBUG} TTgTrace.T('Found .. MUTEX_KILL!!'); {$ENDIF}
|
||
ServiceThread.Terminate;
|
||
exit;
|
||
end;
|
||
|
||
if FileExists(sAPath) then
|
||
begin
|
||
if not MutexExists(MUTEX_AGENT) then
|
||
begin
|
||
{$IFDEF DEBUG} TTgTrace.T('ServiceExecute() .. No Agent Mutext'); {$ENDIF}
|
||
|
||
// if LoadWinlogonPidInfo then
|
||
// continue;
|
||
|
||
// explorer.exe <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>α<CEB1> <20><><EFBFBD><EFBFBD><EFBFBD>ϸ<EFBFBD> Ʈ<><C6AE><EFBFBD>̰<EFBFBD> <20>Ȼ<EFBFBD><C8BB>ܼ<EFBFBD>
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD>Ȱ<EFBFBD> Ȯ<><C8AE><EFBFBD>ϰ<EFBFBD> <20>õ<EFBFBD><C3B5>Ѵ<EFBFBD> 22_0502 14:21:30 kku
|
||
if GetProcessPidByName('explorer.exe') <> 0 then
|
||
begin
|
||
dwExecuteAsPid := 0;
|
||
case GetProcessPidsByName('winlogon.exe', PIDList) of
|
||
0 : sRunAsModule := 'explorer.exe';
|
||
1 : sRunAsModule := 'winlogon.exe';
|
||
else
|
||
begin
|
||
sRunAsModule := 'winlogon.exe';
|
||
|
||
WTSInfo.UpdateSessionInfo;
|
||
for i := 0 to PIDList.Count - 1 do
|
||
if ProcessIdToSessionId(PIDList[i], dwWinLogonSsId) then
|
||
begin
|
||
sAccount := WTSInfo.GetUserNameBySsid(dwWinLogonSsId);
|
||
if (sAccount <> '') and
|
||
(UpperCase(sAccount) <> 'SYSTEM') and
|
||
(UpperCase(sAccount) <> 'CONSOLE') then
|
||
begin
|
||
dwExecuteAsPid := PIDList[i];
|
||
break;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
{$IFDEF DEBUG} TTgTrace.T('ServiceExecute() .. No Agent Mutext .. RunAsModule=%s', [sRunAsModule]); {$ENDIF}
|
||
|
||
// dwExecuteAsPid := GetProcessPidByName('TrustedInstaller.exe');
|
||
|
||
if dwExecuteAsPid = 0 then
|
||
dwExecuteAsPid := GetProcessPidByName(sRunAsModule);
|
||
|
||
{$IFDEF DEBUG} TTgTrace.T(Format('ServiceExecute() .. dwExecuteAsPid : %d',[DWORD(dwExecuteAsPid)])); {$ENDIF}
|
||
|
||
if dwExecuteAsPid <> 0 then
|
||
processHandle:= ExecuteAgent(dwExecuteAsPid);
|
||
end else
|
||
bExeBeforeSleep := true;
|
||
end
|
||
else
|
||
begin
|
||
var pid: DWORD;
|
||
pid:= GetProcessPidByName(sAPath);
|
||
if pid <> 0 then
|
||
begin
|
||
var hProc := OpenProcess(PROCESS_ALL_ACCESS, false, pid);
|
||
if hProc = 0 then
|
||
begin
|
||
{$IFDEF DEBUG} TTgTrace.T('ExecuteAgent() .. OpenProcess() - Fail... Error=%d, sAPath:%s', [GetLastError, sAPath]); {$ENDIF}
|
||
end
|
||
else
|
||
begin
|
||
{$IFDEF DEBUG} TTgTrace.T('ExecuteAgent() .. OpenProcess() - ok... '); {$ENDIF}
|
||
processHandle:= hProc;
|
||
end;
|
||
end;
|
||
end;
|
||
end;
|
||
|
||
{$IFDEF DEBUG} TTgTrace.T(Format('ServiceExecute() .. processHandle : %p',[Pointer(processHandle)])); {$ENDIF}
|
||
if processHandle <> 0 then
|
||
begin
|
||
WaitHandles[0] := ServiceThread.Handle;
|
||
WaitHandles[1] := processHandle;
|
||
|
||
WaitResult := WaitForMultipleObjects(2, @WaitHandles, False, INFINITE);
|
||
if WaitResult = WAIT_OBJECT_0 then
|
||
begin
|
||
|
||
|
||
//WaitForSingleObject(ServiceThread.Handle, 500);
|
||
// Sleep(500);
|
||
ServiceThread.ProcessRequests(false);
|
||
end
|
||
else if WaitResult = WAIT_OBJECT_0 + 1 then
|
||
begin
|
||
var ExitCode: DWORD;
|
||
if GetExitCodeProcess(processHandle, ExitCode) then
|
||
begin
|
||
if ExitCode = 0 then
|
||
begin
|
||
// [<5B><>Ȳ A] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ų<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><> <20>ֽ<EFBFBD><D6BD>ϴ<EFBFBD>.
|
||
|
||
end
|
||
else if ExitCode = 1 then
|
||
begin
|
||
// [<5B><>Ȳ B] <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>(1)<29>߰ų<DFB0> ũ<><C5A9><EFBFBD><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ڵ<EFBFBD>)<29><> <20><><EFBFBD><EFBFBD>
|
||
// <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ǵ<EFBFBD> <20>ý<EFBFBD><C3BD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>!
|
||
ForceRebootSystem;
|
||
end;
|
||
|
||
Sleep(3000);
|
||
|
||
{$IFDEF DEBUG} TTgTrace.T(Format('ServiceExecute() .. Terminate Process ExitCode : %x',[ExitCode])); {$ENDIF}
|
||
CloseHandle(ProcessInfo.hProcess);
|
||
processHandle := 0;
|
||
end;
|
||
end;
|
||
end
|
||
else
|
||
begin
|
||
WaitForSingleObject(ServiceThread.Handle, 500);
|
||
ServiceThread.ProcessRequests(false);
|
||
// bRunLoop := False;
|
||
end;
|
||
end;
|
||
finally
|
||
{$IFDEF DEBUG} TTgTrace.T('ServiceExecute() .. End'); {$ENDIF}
|
||
if Assigned(PIDList) then FreeAndNil(PIDList);
|
||
if Assigned(WTSInfo) then FreeAndNil(WTSInfo);
|
||
if Mtx <> nil then
|
||
FreeAndNil(Mtx);
|
||
|
||
if processHandle <> 0 then
|
||
CloseHandle(processHandle);
|
||
end;
|
||
end;
|
||
|
||
procedure TSvcCrmHe.ServicePause(Sender: TService; var Paused: Boolean);
|
||
begin
|
||
{$IFDEF DEBUG}
|
||
Paused := true;
|
||
{$ELSE}
|
||
Paused := MutexExists(MUTEX_KILL);
|
||
{$ENDIF}
|
||
end;
|
||
|
||
procedure TSvcCrmHe.ServiceStop(Sender: TService; var Stopped: Boolean);
|
||
begin
|
||
{$IFDEF DEBUG}
|
||
Stopped := true;
|
||
{$ELSE}
|
||
Stopped := MutexExists(MUTEX_KILL);
|
||
{$ENDIF}
|
||
end;
|
||
|
||
end.
|