#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);
}
};