Solved

ExitWindowsEx(EWX_SHUTDOWN , EWX_FORCE);

Posted on 2001-06-17
7
2,538 Views
Last Modified: 2012-08-14
HI all

I have made a computer shutting program
but program not work in Win2000

this line:
ExitWindowsEx(EWX_SHUTDOWN , EWX_FORCE);

How i changed that?

Thanks
Janozzy
0
Comment
Question by:janozzy
  • 2
  • 2
  • 2
  • +1
7 Comments
 
LVL 22

Accepted Solution

by:
mnasman earned 100 total points
ID: 6199519
Hello

  In win2k you need to have privileges for shutdown the computer, try this example and you can shutdown the computer in any version of windows, it will detect ur win version and than shutdown the pc, I got it from delphi3000 site.


unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  StdCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.DFM}

function GetWinVersion: String;
var
   VersionInfo : TOSVersionInfo;
   OSName      : String;
begin
   // set the size of the record
   VersionInfo.dwOSVersionInfoSize := SizeOf( TOSVersionInfo );

   if Windows.GetVersionEx( VersionInfo ) then
      begin
         with VersionInfo do
         begin
            case dwPlatformId of
               VER_PLATFORM_WIN32s   : OSName := 'Win32s';
               VER_PLATFORM_WIN32_WINDOWS : OSName := 'Windows 95';
               VER_PLATFORM_WIN32_NT      : OSName := 'Windows NT';
            end; // case dwPlatformId
            Result := OSName + ' Version ' + IntToStr( dwMajorVersion ) + '.' + IntToStr( dwMinorVersion ) +
                      #13#10' (Build ' + IntToStr( dwBuildNumber ) + ': ' + szCSDVersion + ')';
         end; // with VersionInfo
      end // if GetVersionEx
   else
      Result := '';
end;

procedure ShutDown;
const
  SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';   // Borland forgot this declaration
var
  hToken       : THandle;
  tkp          : TTokenPrivileges;
  tkpo         : TTokenPrivileges;
  zero         : DWORD;
begin
  if Pos( 'Windows NT', GetWinVersion) = 1  then // we've got to do a whole buch of things
     begin
        zero := 0;
        if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
           begin
             MessageBox( 0, 'Exit Error', 'OpenProcessToken() Failed', MB_OK );
             Exit;
           end; // if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken)
        if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) then
           begin
             MessageBox( 0, 'Exit Error', 'OpenProcessToken() Failed', MB_OK );
             Exit;
           end; // if not OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken)


        // SE_SHUTDOWN_NAME
        if not LookupPrivilegeValue( nil, 'SeShutdownPrivilege' , tkp.Privileges[ 0 ].Luid ) then
           begin
              MessageBox( 0, 'Exit Error', 'LookupPrivilegeValue() Failed', MB_OK );
              Exit;
           end; // if not LookupPrivilegeValue( nil, 'SeShutdownPrivilege' , tkp.Privileges[0].Luid )
        tkp.PrivilegeCount := 1;
        tkp.Privileges[ 0 ].Attributes := SE_PRIVILEGE_ENABLED;

        AdjustTokenPrivileges( hToken, False, tkp, SizeOf( TTokenPrivileges ), tkpo, zero );
        if Boolean( GetLastError() ) then
           begin
              MessageBox( 0, 'Exit Error', 'AdjustTokenPrivileges() Failed', MB_OK );
              Exit;
           end // if Boolean( GetLastError() )
        else
           ExitWindowsEx( EWX_FORCE or EWX_SHUTDOWN, 0 );
      end // if OSVersion = 'Windows NT'
   else
      begin // just shut the machine down
        ExitWindowsEx( EWX_FORCE or EWX_SHUTDOWN, 0 );
      end; // else
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ShutDown;
end;

end.
0
 
LVL 17

Expert Comment

by:inthe
ID: 6199542
Hi,
you need the correct privileges to do it in nt/win2k
try using a procedure like this instead:

function srExitWindows(const aFlags: Word): Boolean;
var
  vi: TOSVersionInfo;
  hToken: THandle;
  tp: TTokenPrivileges;
  h: DWord;
begin
  vi.dwOsVersionInfoSize := SizeOf(vi);
  GetVersionEx(vi);
  if vi.dwPlatFormId = VER_PLATFORM_WIN32_NT then
  begin
    OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES,
hToken);
    LookUpPrivilegeValue(nil, 'SeShutDownPrivilege',
tp.Privileges[0].Luid);
    tp.PrivilegeCount := 1;
    tp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
    h := 0;
    AdjustTokenPrivileges(hToken, False, tp, 0,
PTokenPrivileges(nil)^, h);
    CloseHandle(hToken);
    Result := ExitWindowsEx(aFlags, 0);
  end
  else
    Result := ExitWindowsEx(aFlags, 0);
end;
0
 
LVL 17

Expert Comment

by:inthe
ID: 6199545
had the page open a bit long i think ;-)
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 20

Expert Comment

by:Madshi
ID: 6199631
Hi Janozzy,

two things:

(1) You're using ExitWindowsEx incorrectly. The second parameter is reserved and must be 0. You have to give in all flags into the first parameter like this:

ExitWindowsEx(EWX_SHUTDOWN or EWX_FORCE, 0);

(2) In NT based systems you need a special privilege to be enabled. I hate these privileges and that you always have to care about them. So I've written a little function, which I execute in all my projects, which simply enabled all available privileges. You can safely call this function in win9x, too. There is simply doesn't do anything:

procedure EnableAllPrivileges;
var c1, c2 : dword;
    ptp    : PTokenPrivileges;
    i1     : integer;
begin
  if OpenProcessToken(windows.GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, c1) then
    try
      c2 := 0;
      GetTokenInformation(c1, TokenPrivileges, nil, 0, c2);
      if c2 <> 0 then begin
        ptp := AllocMem(c2);
        if GetTokenInformation(c1, TokenPrivileges, ptp, c2, c2) then begin
          for i1 := 0 to integer(ptp^.PrivilegeCount) - 1 do
            ptp^.Privileges[i1].Attributes := ptp^.Privileges[i1].Attributes or SE_PRIVILEGE_ENABLED;
          AdjustTokenPrivileges(c1, false, ptp^, c2, PTokenPrivileges(nil)^, cardinal(pointer(nil)^));
        end;
        FreeMem(ptp);
      end;
    finally CloseHandle(c1) end;
end;

Regards, Madshi.
0
 

Author Comment

by:janozzy
ID: 6199656
MNASMAN : Your code don't work in 2000 and 98 give Msgsrv32 error.
Other answers not tested yet.

Thanks all

Janozzy
0
 
LVL 22

Expert Comment

by:mnasman
ID: 6199679
Janozzy, i have win2000 and i test it there, it shutdown my computer while i tested and i back and rewrite it again, lol
0
 

Author Comment

by:janozzy
ID: 6199813
hi all
i found working code :

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
     TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED
   else
     TP.Privileges[0].Attributes := 0;
   
   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
 result := true;
 if SetPrivilege ('SeShutdownPrivilege', true) then
 begin
   if (not ExitWindowsEx (iFlags, 0)) then
   begin
     // handle errors...
     result := False
   end;
   SetPrivilege ('SeShutdownPrivilege', False)
 end
 else
 begin
   // handle errors...
   result := False
 end
end;

Thanks all answers.
I give points to Mnasman for his hard work:)
0

Featured Post

Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

Join & Write a Comment

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Creating an auto free TStringList The TStringList is a basic and frequently used object in Delphi. On many occasions, you may want to create a temporary list, process some items in the list and be done with the list. In such cases, you have to…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
Get a first impression of how PRTG looks and learn how it works.   This video is a short introduction to PRTG, as an initial overview or as a quick start for new PRTG users.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now