Переделал WindowsShutdown из KOL.pas
function EnablePrivilege(const Machine, PrivilegesName: KOLString;
var PreviousState: TTokenPrivileges): THandle;
var
Ftkp: TTokenPrivileges;
dwRetLen :DWORD;
begin
if not OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
or TOKEN_QUERY, Result) then
begin
Result := 0;
Exit;
end;
if not LookupPrivilegeValue(PKOLChar(Machine), PKOLChar(PrivilegesName),
Ftkp.Privileges[0].Luid) then
begin
CloseHandle(Result);
Result := 0;
Exit;
end;
Ftkp.PrivilegeCount := 1;
Ftkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
if (not AdjustTokenPrivileges(Result, FALSE, Ftkp, sizeof(Ftkp),
PreviousState, dwRetLen)) or (GetLastError() = ERROR_NOT_ALL_ASSIGNED) then
begin
CloseHandle(Result);
Result := 0;
Exit;
end;
end;
procedure RestorePrivilege(hToken: THandle; Previous: TTokenPrivileges);
var
dummy: Cardinal;
begin
AdjustTokenPrivileges(hToken, FALSE, Previous, sizeOf(Previous), nil, dummy);
CloseHandle(hToken);
end;
function WindowsShutdown(const Machine: KOLString; Force, Reboot: Boolean): Boolean;
var
hToken: THandle;
tkp_prev: TTokenPrivileges;
Flags: Integer;
PrName: KOLString;
begin
Result := False;
if Integer( GetVersion ) < 0 then
begin
if Machine <> '' then Exit;
Flags := EWX_SHUTDOWN;
if Reboot then
Flags := Flags or EWX_REBOOT;
if Force then
Flags := Flags or EWX_FORCE;
Result := ExitWindowsEx( Flags, 0 );
Exit;
end;
if Machine = '' then
PrName := 'SeShutdownPrivilege'
else
PrName := 'SeRemoteShutdownPrivilege';
hToken := EnablePrivilege(Machine, PrName, tkp_prev);
if hToken = 0 then Exit;
Result := InitiateSystemShutdown(PKOLChar(Machine), nil, 0, Force, Reboot);
if not Result then RestorePrivilege(hToken, tkp_prev);
end;
В оригинале не закрывается hToken, не критично но все же :) Плюс лишний tkp_prev:=tkp; и зачем получать сразу обе привилегии 'SeShutdownPrivilege' и 'SeRemoteShutdownPrivilege'? Плюс код включения привелегий может еще кому-то пригодиться. Например вот:
function Suspend(Hibernate, Force: Boolean): Boolean;
var
hToken: THandle;
tkp_prev: TTokenPrivileges;
begin
Result := False;
if Integer( GetVersion ) < 0 then Exit;
hToken := EnablePrivilege('', 'SeShutdownPrivilege', tkp_prev);
if hToken = 0 then Exit;
Result := SetSystemPowerState(not Hibernate, Force);
RestorePrivilege(hToken, tkp_prev);
end;
Если ошибок нет, предлагаю заменить и добавить.