기본카테고리

[C++]ExitWindowsEx() 를 이용한 시스템 종료

DevAdd 2011. 1. 7. 10:17




// OS에 따라 적절하게 시스템을 강제 종료한다.
BOOL SystemShutDown()
{
CString strOSName=_T("");

HANDLE hToken;
TOKEN_PRIVILEGES tkp;
CString l_sErrorCode;
OSVERSIONINFO verInfo;
//0: default 1: 3.1 // 2: 98 //3: 95 //4: NT
verInfo.dwOSVersionInfoSize = sizeof(verInfo);
GetVersionEx(&verInfo) ;
switch(verInfo.dwPlatformId)
{
/*case VER_PLATFORM_WIN32s:
strOSName = "Microsoft Windows 3.1";
MessageBox(strOSName);
break; */
case VER_PLATFORM_WIN32_WINDOWS:
ExitWindowsEx(/*EWX_FORCE | */EWX_SHUTDOWN, 0); break;

case VER_PLATFORM_WIN32_NT:
default:
// NT계열에서 시스템 권한 얻어오기
if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
MessageBox(NULL, STR_FAIL_GET_SYSTEM_RIGHT, GetMessageBoxTitle(), MB_ICONINFORMATION);
return FALSE;
}
LookupPrivilegeValue( NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges( hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
if (GetLastError() != ERROR_SUCCESS)
{
MessageBox(NULL, STR_FAIL_GET_SYSTEM_RIGHT, GetMessageBoxTitle(), MB_ICONINFORMATION);
return FALSE;
}
ExitWindowsEx(/*EWX_FORCE | */EWX_POWEROFF, 1);
break;
}
return TRUE;
}

 

 

 

/////////////////////////////////////////////////////////////////////////////////////

// 함수 설명

 

ExitWindowsEx(EWX_SHUTDOWN|EWX_POWEROFF|EWX_FORCE,0);

이런식으로 호출 하면...된다.

 

하지만


WINDOWS NT/2000에서는 시스템쪽의 권한이 강화 되어 있어서 그냥

ExitWindowsEx(EWX_SHUTDOWN|EWX_POWEROFF|EWX_FORCE,0);

이 함수를 호출 하면 Return FALSE 되고 넘어가 버린다.

WINDOWS NT/2000에서 시스템을 종료하려면 시스템으로 부터 권한을 얻어와야 한다.

HANDLE hToken;
TOKEN_PRIVILEGES stTokenPrivilege;

if( OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken) )
{
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &stTokenPrivilege.Privileges[0].Luid);

stTokenPrivilege.PrivilegeCount = 1;
stTokenPrivilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

if( AdjustTokenPrivileges(hToken, FALSE, &stTokenPrivilege, 0, (PTOKEN_PRIVILEGES)NULL, 0) )
ExitWindowsEx(EWX_SHUTDOWN|EWX_POWEROFF|EWX_FORCE,0);
}

이런식으로 권한을 먼저 획득 한뒤 종료 함수를 호출해 주면 된다.

참고로 종료 말고도 여러 Flag가 존재한다.

EWX_LOGOFF : 로그 오프.

EWX_REBOOT : Windows 머신의 재기동.

EWX_SHUTDOWN: Windows 머신의 전원을 끈다.

EWX_FORCE : 전프로세스를 강력한 강제 종료 걸친다.

EWX_FORCEIFHUNG : Windows2000전용이며, 위와 같은 기능을한다