?
Solved

ExitWindowsEx(EWX_SHUTDOWN , EWX_FORCE);

Posted on 2001-06-17
7
Medium Priority
?
2,935 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:
Mohammed Nasman earned 400 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
Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

 
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:Mohammed Nasman
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

Free Tool: Port Scanner

Check which ports are open to the outside world. Helps make sure that your firewall rules are working as intended.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
In this tutorial I will show you how to use the Windows Speech API in Delphi. I will only cover basic functions such as text to speech and controlling the speed of the speech. SAPI Installation First you need to install the SAPI type library, th…
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…
Free Data Recovery software is an advanced solution from Kernel Tools to recover data and files such as documents, emails, database, media and pictures, etc. It supports recovery from physical & logical drive after a hard disk crash, accidental/inte…

589 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