ログオフ, シャットダウン,再起動を行う

(2004.12.02)
#pragma once
 
#include "Module.h"
 
 
//////////////////////////////////////////////////////////////////////////////
// CExitWindowsHelper
 
class CExitWindowsHelper
{
protected:
    CExitWindowsHelper();                            // 実装しない
    virtual ~CExitWindowsHelper();
 
public:
    static HRESULT Logoff(UINT uFlags = 0)
    {
        return CExitWindowsHelper::ExitWindowsEx(uFlags | EWX_LOGOFF);
    }
    static HRESULT Poweroff(UINT uFlags = 0)
    {
        return CExitWindowsHelper::ExitWindowsEx(uFlags | EWX_POWEROFF);
    }
    static HRESULT Reboot(UINT uFlags = 0)
    {
        return CExitWindowsHelper::ExitWindowsEx(uFlags | EWX_REBOOT);
    }
    static HRESULT Shutdown(UINT uFlags = 0)
    {
        return CExitWindowsHelper::ExitWindowsEx(uFlags | EWX_SHUTDOWN);
    }
 
public:
    static HRESULT ExitWindowsEx(UINT uFlags)
    {
        HRESULT hr = S_OK;
 
        OSVERSIONINFO version;
        memset(&version, 0, sizeof(version));
        version.dwOSVersionInfoSize = sizeof(version);
        ::GetVersionEx(&version);
        if(version.dwPlatformId == VER_PLATFORM_WIN32_NT)
        {
            hr = CExitWindowsHelper::AdjustTokenForExitWindowsEx();
            if (FAILED(hr))
            {
                return hr;
            }
        }
        else
        {
            // 何もしない。。
        }
 
        BOOL br = ::ExitWindowsEx(uFlags, 0);
        if (!br)
        {
            DWORD dwError = ::GetLastError();
            return HRESULT_FROM_WIN32(dwError);
        }
 
        return S_OK;
    }
 
protected:
    static HRESULT AdjustTokenForExitWindowsEx()
    {
        BOOL br = TRUE;
 
        HANDLE hProcess = ::GetCurrentProcess();
 
        HANDLE hToken = 0;
        br = Probe_OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);
        if (!br)
        {
            DWORD dwError = ::GetLastError();
            return HRESULT_FROM_WIN32(dwError);
        }
 
        LUID luid = {0};
        br = Probe_LookupPrivilegeValue(0, SE_SHUTDOWN_NAME, &luid);
        if (!br)
        {
            DWORD dwError = ::GetLastError();
            return HRESULT_FROM_WIN32(dwError);
        }
 
        TOKEN_PRIVILEGES NewState = {0};
        NewState.PrivilegeCount = 1;
        NewState.Privileges[0].Luid = luid;
        NewState.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
 
        TOKEN_PRIVILEGES PreviousState = {0};
        DWORD ReturnLength = 0;
 
        br = Probe_AdjustTokenPrivileges(hToken, FALSE, &NewState, sizeof(NewState), &PreviousState, &ReturnLength);
        if (!br)
        {
            DWORD dwError = ::GetLastError();
            return HRESULT_FROM_WIN32(dwError);
        }
 
        return S_OK;
    }
 
protected:
    typedef BOOL WINAPI OpenProcessTokenProcType(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
    static BOOL Probe_OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
    {
        CModule module(_T("advapi32.dll"));
 
        OpenProcessTokenProcType* func = (OpenProcessTokenProcType*)module.GetProcAddress(_T("OpenProcessToken"));
        if (func == NULL)
        {
            return 0;
        }
 
        return func(ProcessHandle, DesiredAccess, TokenHandle);
    }
    typedef BOOL WINAPI LookupPrivilegeValueProcType(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid);
    static BOOL Probe_LookupPrivilegeValue(LPCTSTR lpSystemName, LPCTSTR lpName, PLUID lpLuid)
    {
        CModule module(_T("advapi32.dll"));
 
        LookupPrivilegeValueProcType* func = (LookupPrivilegeValueProcType*)module.GetProcAddress(_T("LookupPrivilegeValueA"));
        if (func == NULL)
        {
            return 0;
        }
 
        return func(lpSystemName, lpName, lpLuid);
    }
    typedef BOOL WINAPI AdjustTokenPrivilegesProcType(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength);
    static BOOL Probe_AdjustTokenPrivileges(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength)
    {
        CModule module(_T("advapi32.dll"));
 
        AdjustTokenPrivilegesProcType* func = (AdjustTokenPrivilegesProcType*)module.GetProcAddress(_T("AdjustTokenPrivileges"));
        if (func == NULL)
        {
            return 0;
        }
 
        return func(TokenHandle, DisableAllPrivileges, NewState, BufferLength, PreviousState, ReturnLength);
    }
};
一覧に戻る
© 2003 WAC.com All Right Reserved.