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

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • CentreCorp is a fully integrated and diversified property management and real estate service company, specializing in the "shopping center" segment, and is one of the premier retail service providers in North America. Company executives travel a great deal, carrying a number of traveling laptops with critical current business data, and no easy way to back up to the network outside the office. Read this case study to learn how CentreCorp implemented a suite of business continuity services that included …

Most Popular Programming Stories

More for Developers

RSS Feeds