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

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read