unit XReboot;

{
  TXWinReboot 2.0
  ===============
  A component for computer restart, reboot, shutdown, suspend and hibernate.

  Freeware.

  Copyright © 1998 Roman Stedronsky, Roman.Stedronsky@seznam.cz.

  All rights reserved. You may use this software in an application
  without fee or royalty, provided this copyright notice remains intact.

  properties:

    property Operation: TRebootOperation;		type of reboot operation
	roLogOff        	Shuts down all processes, then it logs the user off.
	roReboot		Shuts down the system and then restarts the system.
	roShutDown		Shuts down the system, flushs file buffers, stops processes.
	roSuspend		Suspends using RAM-alive technique.
	roHibernate		Suspends using hibernate technique.
    property PowerOff: boolean;				Shuts down the system and turns off the power (only with roShutDown).
    property ForceTerminateProcesses: boolean;		Forces processes to terminate.

  methods:

    function Execute: boolean;				reboot
}

interface

uses
  Windows, Classes;

type
  TRebootOperation = (roLogOff, roReboot, roShutDown, roSuspend, roHibernate);

type
  TXWinReboot = class(TComponent)
  protected
    FOperation: TRebootOperation;
    FPowerOff: boolean;
    FForceTerminateProcesses: boolean;
    function SetShutdownPrivilege(Enable: boolean): boolean;
  public
    constructor Create(AOwner: TComponent); override;
    function Execute: boolean;
  published
    property Operation: TRebootOperation read FOperation write FOperation default roReboot;
    property PowerOff: boolean read FPowerOff write FPowerOff default false;
    property ForceTerminateProcesses: boolean read FForceTerminateProcesses write FForceTerminateProcesses default false;
  end;

procedure Register;

implementation

const
  cRebootFlags: array[TRebootOperation] of integer = (EWX_LOGOFF, EWX_REBOOT, EWX_SHUTDOWN, 0, 0);
  cPowerOff = EWX_POWEROFF;
  cForceTerminateProcesses = EWX_FORCE;
  cPrivilegeName = 'SeShutdownPrivilege';

constructor TXWinReboot.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  Operation := roReboot;
  PowerOff := false;
  ForceTerminateProcesses := false;
end;

function TXWinReboot.SetShutdownPrivilege(Enable: boolean): boolean;
var
  PrevPrivileges: TTokenPrivileges;
  Privileges: TTokenPrivileges;
  Token: THandle;
  dwRetLen: DWord;
begin
  Result := False;
  OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, Token);
  Privileges.PrivilegeCount := 1;
  if LookupPrivilegeValue(nil, PChar(cPrivilegeName), Privileges.Privileges[0].LUID) then
  begin
    if Enable then
      Privileges.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
    else
      Privileges.Privileges[0].Attributes := 0;
    dwRetLen := 0;
    Result := AdjustTokenPrivileges(Token, False, Privileges, SizeOf(PrevPrivileges), PrevPrivileges, dwRetLen);
  end;
  CloseHandle(Token);
end;

function TXWinReboot.Execute: boolean;
var
  Flags: integer;
begin
  SetShutdownPrivilege(true);
  if Operation in [roLogOff..roShutDown] then
  begin
    Flags := cRebootFlags[FOperation];
    if FPowerOff then Flags := Flags or cPowerOff;
    if FForceTerminateProcesses then Flags := Flags or cForceTerminateProcesses;
    Result := ExitWindowsEx(Flags, 0);
  end
  else
    Result := SetSystemPowerState(Operation = roSuspend, FForceTerminateProcesses);
  SetShutdownPrivilege(false);
end;

procedure Register;
begin
  RegisterComponents('Extra', [TXWinReboot]);
end;

end.

