OS Independent Windows System Shut Down Class

Environment: VC5/6, WIN 9X/NT4/2000/XP.

Introduction

This class is a light wrapper around the Windows system shut down stuff. By using this class you can shut down, restart, or log off either forcefully or normally without worrying about what type of OS it is. It is also possible to set up the current process so that it will shut down only after closing all processes.

The Old Way

The basic steps to shut down a machine via the Windows API are:

  1. Find out which operating system is currently running by using the OSVERSIONINFO structure and calling:
    GetVersionEx(&m_osvi)
  2. If it is an NT system, you have to call the following:
    BOOL OpenProcessToken(
         HANDLE  ProcessHandle,
         DWORD   DesiredAccess,
         PHANDLE TokenHandle),
         BOOL    LookupPrivilegeValue(
         LPCTSTR lpSystemName,
         LPCTSTR lpName,
         PLUID   lpLuid ),
    
    BOOL AdjustTokenPrivileges(
         HANDLE TokenHandle,
         BOOL DisableAllPrivileges,
         PTOKEN_PRIVILEGES NewState,
         DWORD BufferLength,
         PTOKEN_PRIVILEGES PreviousState,
         PDWORD ReturnLength
         )
  3. If all the functions succeed, call ExitWindowsEx for NT and 9X. To log off in 9X, you have to call the ExitWindows function.

The basic steps to set up your process to shut down only after closing all process via the Windows API are:

  1. Find out which operating system is currently running by using the OSVERSIONINFO structure and calling:
    GetVersionEx(&m_osvi).
  2. If it's an NT system, call:
    BOOL SetProcessShutdownParameters(
         DWORD dwLevel,
         DWORD dwFlags
         )

Changing the parameter values and calling all this Win32 API is really tough. All functions around this have been bundled in a wrapper class to make it easier to use and user friendly for the programmer.

A Better Solution

The CExitWindows class will provide you with the necessary methods to shut down/restart/log off the system in an easier manner.

The simpler way to use this class is to create an object of type CExitWindows either as a member variable or local variable:

CExitWindows m_ExitWindows    // Member variable of some class

Then, you can call the individual member function that has its own default meaning. The various methods and their details are given below.

Construction

CExitWindows();

The constructor will identify which operating system is currently being used. See the following sections for details.

Operations

public:

  static BOOL SetItAsLastShutDownProcess();
         //It is used to set the Application to reserve last
         //shutdown position.

         BOOL LogOff();
         //It will log off the user after prompting a save

         BOOL Restart();
         //It will restart the machine after prompting a save

         BOOL ShutDown();
         //It will shut down the machine after prompting a save

         OSVERSIONINFO GetOsVersionInfo()const;
         //It will give const OSVERSIONINFO structure. You can
         //check the OS version and other related information.

         UINT GetOsVersion();
         //It will give a 32-bit unsigned integer with OS family
         //information.
         //If NT, function will return WINNT. If 9X family,
         //values will be WIN9X.

         BOOL ExitWindowsExt(UINT nFlag,DWORD dwType);
         //This function is useful if you want to change any
         //parameter values.
         //It will check and assign other operations.

         BOOL ForceShutDown();
         //It will shut down forcefully without allowing a save.

         BOOL ForceLogOff();
         //It will log off current user forcefully without
         //allowing a save.

         BOOL ForceReStart();
         //It will restart forcefully without allowing a save.

         CExitWindows();

  virtual ~CExitWindows();
protected:

         BOOL AdjustProcessTokenPrivilege();
         //Adjusting the privilege of the process to shut down
         //the machine.

To Shut Down the Machine

Create an object of type CExitWindows, either as a member variable or local variable:

CExitWindows m_ExitWindows;

If you want to set it up so that the current process must shut down only after all others have closed, you can do it without declaring any object. See the code below.

CExitWindows::SetItAsLastShutDownProcess()

Call the method written below if you want to shut down forcefully.

m_ExitWindows.ForceShutDown()

It is not possible to shut down, restart, or log off an NT system if the working user doesn't have the privilege to do the operation. If the operation failed in an NT system, the function will return any of the three values OPENING_PROCESS_TOKEN_FAILED, ADJUST_PRIVILEGE_FAILED, or ADJUST_TOCKEN_FAILED.

For normal shutdown, use following function:

m_ExitWindows.ShutDown();

It is the same for all operations. Refer to the demo application provided as a sample.

System BUG: Forcefully loging off an operation in the 9X OS will not terminate the calling process.

Downloads

Download demo project - 96 Kb
Download source - 109 Kb


Comments

  • Good Work

    Posted by Legacy on 02/22/2004 12:00am

    Originally posted by: Shine Kumar

    Hai
    This is a very good one.

    Reply
  • How about logoff under Win9x?

    Posted by Legacy on 08/21/2003 12:00am

    Originally posted by: Wally

    Hello!

    Well, everything seems to be OK, but...
    Under Win9x, when You try to logoff there is still
    Desktop of previously logged user.
    You should first kill explorer.exe process (like I do in
    my own implementation such class written about 3years ago).
    And other case: only one (default) profile under Win9x.
    Logoff shouldn't be posssible.

    Try to update sourcecode.

    Regards, Wally

    Reply
  • good work

    Posted by Legacy on 08/20/2003 12:00am

    Originally posted by: fenil and biju


    lots useful

    fenil and biju

    Reply
  • Good work from PALA

    Posted by Legacy on 08/18/2003 12:00am

    Originally posted by: Aiswarya Nair

    Good work from PALA.KTS softwares ..We will Inform this to MANi sir

    Reply
  • It's

    Posted by Legacy on 08/16/2003 12:00am

    Originally posted by: Nido John

    It's great. Very useful. 
    

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • On-demand Event Event Date: September 10, 2014 Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild." This loop of continuous delivery and continuous feedback is how the best mobile …

  • Stories about devastating cyberattacks are plaguing the news. Why? The DNS protocol is easy to exploit. See your network the way hackers do—as an easy target. Learn how you can effectively secure your DNS infrastructure today.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds