unit Shutdownwindows;


interface
uses shellapi,messages,dialogs,Sysutils,windows,registry;

//const
//Already defined in delphi 4
//WM_QUERYENDSESSION = ;
//WM_ENDSESSION = ;
//ENDSESSION_LOGOFF = 000000;

var
sec_attrib : TSecurityAttributes;

type TPIDLIST = array[0..1000] of DWORD;
TEnumprocess = function (pidList : PInteger; cb : Integer; var cbNeeded : Integer) : BOOL ;stdcall;




function SetPrivilege(
  sPrivilegeName : string;
  bEnabled : boolean )
    : boolean;

function WinExit( iFlags : integer ) : boolean;


implementation


function Getwindowsversion() : integer;
var
vr : TOSVERSIONINFO;
getversion : integer;

begin
getversion:=0;
vr.dwOSVersionInfoSize:= sizeof(vr);
fillchar(vr.szCSDVersion,125,20);
GetVersionExA(vr);
case vr.dwPlatformId  of
1 : if vr.dwMinorVersion=0 then getversion:=1 else if vr.dwMinorVersion=10 then getversion:=2;
2 : begin
if vr.dwMajorVersion=3 Then getversion:=3;
if vr.dwMajorVersion=4 then getversion:=4;
if vr.dwMajorVersion>=5 then getversion:=5;
end;
end;
result:=getversion
end;


function SetPrivilege(
  sPrivilegeName : string;
  bEnabled : boolean )
    : boolean;
var
  TPPrev,
  TP         : TTokenPrivileges;
  Token      : THandle;
  dwRetLen   : DWord;
begin
  Result := False;

  OpenProcessToken(
    GetCurrentProcess,
    TOKEN_ADJUST_PRIVILEGES
    or TOKEN_QUERY,
    Token );

  TP.PrivilegeCount := 1;
  if( LookupPrivilegeValue(
        Nil,
        PChar( sPrivilegeName ),
        TP.Privileges[ 0 ].LUID ) )then
  begin
    if( bEnabled )then
    begin
      TP.Privileges[ 0 ].Attributes  :=
        SE_PRIVILEGE_ENABLED;
    end else
    begin
      TP.Privileges[ 0 ].Attributes  :=
        0;
    end;

    dwRetLen := 0;
    Result := AdjustTokenPrivileges(
                Token,
                False,
                TP,
                SizeOf( TPPrev ),
                TPPrev,
                dwRetLen );
  end;

  CloseHandle( Token );
end;

//
// iFlags:
//
//  one of the following must be
//  specified
//
//   EWX_LOGOFF
//   EWX_REBOOT
//   EWX_SHUTDOWN
//
//  following attributes may be
//  combined with above flags
//
//   EWX_POWEROFF
//   EWX_FORCE    : terminate processes
//
function WinExit( iFlags : integer ) : boolean;

begin


if (iFlags=(EWX_LOGOFF or EWX_FORCE)) and (Getwindowsversion<3) then iflags:=EWX_REBOOT or EWX_FORCE;

// This sections shutsdown apps before logging off, but fails with some apps, locking the application.
//if ((iFlags=(EWX_SHUTDOWN or EWX_FORCE)) or (iFlags=(EWX_SHUTDOWN or EWX_FORCE or EWX_POWEROFF))) and (Getwindowsversion<3) then begin
//ExitWindows(0,0);
//end;

  ExitWindowsEx(iFlags,0);
  Result := True;
    if( SetPrivilege( 'SeShutdownPrivilege', True ) )then
  begin
    if( not ExitWindowsEx( iFlags, 0 ) )then
    begin
      Result := False;
    end;
    SetPrivilege( 'SeShutdownPrivilege', False )
  end else
  begin
    Result := False;
  end;
if (iFlags=(EWX_SHUTDOWN or EWX_POWEROFF or EWX_FORCE)) or (iFlags=(EWX_SHUTDOWN or EWX_FORCE)) then halt;
end;




end.