Programming/Win32 API2008. 12. 3. 10:07

제가 중점적으로 설명하려는 API는 다음과 같습니다.

ExitWindowsEx

InitiateSystemShutdown

NtShutdownSystem

 

먼저, ExitWindowsEx() 에 관하여 알아봅시다.

이 함수는 성공시 TRUE, 실패시 FALSE를 반환합니다.

WINUSERAPI

BOOL

WINAPI

ExitWindowsEx(

    DWORD dwFlags,

    DWORD dwReserved);

 

dwFlags에는 일반적으로 다음과 같은 상수들이 들어갑니다.

EWX_LOGOFF : 시스템을 로그오프시킨다.
EWX_SHUTDOWN : 시스템을 종료시킨다. (전원이 꺼지지 않는경우도 있다)
EWX_REBOOT : 시스템을 재시작시킨다.
EWX_FORCE : 이 옵션이 들어가면 실행중인 프로그램을 강제종료한다
EWX_POWEROFF : 이 옵션이 들어가면 전원을 완전히 끈다.
그리고, 이 상수들은 조합해서 쓸 수도 있습니다.

예를 들면, "실행중 프로그램을 강제종료시키고 시스템을 종료하고 싶다" 면,

dwFlags에는 EWX_SHUTDOWN | EWX_FORCE가 들어가면 되는 것입니다.

 

dwReserved에는 0xFFFFFFFF가 들어가는 것 같습니다.

헤더 파일에도 정의된 것이 있긴 있는것 같습니다.

#define ExitWindows(dwReserved, Code) ExitWindowsEx(EWX_LOGOFF, 0xFFFFFFFF)

자 이번에는 InitiateSystemShutdown()에 대해 알아보겠습니다.

이 함수는 호출시 프로세스 winlogon.exe에 시스템 종료 Message가 담긴 창을 띄워서

시스템 종료까지의 남은 시간을 표시해 줍니다. 남은 시간이 0:00:00이 되면, 시스템은 종료됩니다.

성공시 TRUE, 실패시 FALSE를 반환합니다.

여기서부터 나오는 함수는, Windows 9x는 지원하지 않습니다!!!!

WINADVAPI
BOOL
WINAPI
InitiateSystemShutdownA(
    IN LPSTR lpMachineName,
    IN LPSTR lpMessage,
    IN DWORD dwTimeout,
    IN BOOL bForceAppsClosed,
    IN BOOL bRebootAfterShutdown);

lpMachineName : 종료할 컴퓨터의 이름으로 보여집니다. 일반적으로 NULL

lpMessage : 시스템 종료시 띄울 Message

dwTimeout : 시스템 종료까지의 시간(초)

bForceAppsClosed : 시스템 종료시 프로그램을 강제종료할 것인가의 여부.

bRebootAfterShutdown : 시스템 종료 후에 재부팅 할것인지의 여부

또한, 이 함수로 시작된 시스템 종료는, 시스템 종료까지의 시간이 만기되기 전에 취소할 수 있는데,

이 역할을 하는 함수가 AbortSystemShutdown()입니다.

WINADVAPI

BOOL

WINAPI

AbortSystemShutdownA(

    IN LPSTR lpMachineName);

lpMachineName : 위의 설명과 같다.

 

이제는 좀 특별한 API인 NtShutdownSystem() 에 대해 알아보겠습니다.

이 함수는 다른 함수와는 좀 달리, 설정 저장 없이, 바로 시스템을 종료시킵니다.

성공시 STATUS_SUCCESS를 반환합니다.

STATUS_SUCCESS는 다음으로 정의됩니다:

#define STATUS_SUCCESS            (NTSTATUS)0

NTSYSAPI

NTSTATUS

NTAPI

NtShutdownSystem(

    IN SHUTDOWN_ACTION ShutdownAction);

ShutdownAction : 종료방법(말하자면 옵션).

SHUTDOWN_ACTION은 enum으로 되어있습니다.

typedef enum _SHUTDOWN_ACTION {
    ShutdownNoReboot,
    ShutdownReboot,
    ShutdownPowerOff
} SHUTDOWN_ACTION, *PSHUTDOWN_ACTION;
ShutdownNoReboot : 시스템을 종료하나, 재시작하지 않는다. (전원은 꺼지지 않는 것 같다.)

ShutdownReboot : 시스템을 재시작한다.

ShutdownPowerOff : 시스템 종료 후 전원을 끈다. 만일 하드웨어가 이 기능을 지원하지 않으면,  ShutdownReboot를 수행한다.

 

하지만, Windows NT/2K/XP/... 등에서 이를 사용하기 위해서는 Shutdown 권한이 있어야 합니다.

따라서, 권한을 얻어야 하는데, 그 일을 하는 함수가 바로, NTDLL.DLL의 RtlAdjustPrivilege()입니다.

OpenProcessToken()->LookupPrivilegeValue()->AdjustTokenPrivileges() 를 하는 방법도 있지만,

여기에서는 글이 약간 길어지므로 이 글에서는 다루지 않도록 하겠습니다.

NTSYSAPI

NTSTATUS

NTAPI

RtlAdjustPrivilege(

    ULONG Privilege,
    BOOL bEnable,
    BOOL bIsCurrentThread,
    PULONG PreviousPrivilege);
Privilege : LookupPrivilegeValue()로 얻어온 권한의 값(좀 설명이 애매하군요). Index.

bEnable : 권한을 설정할것인지의 여부. 일반적으로 TRUE.

bIsCurrentThread : 현재 쓰레드에 대하여인지의 여부. (테스트 결과, FALSE를 선택하면 프로세스 전체에 대해서인것 같다.)

일반적으로 FALSE.

PreviousPrivilege : 이전의 권한이 이 인자로 넘어온다.

예를 들어서, Debug 권한을 얻고 싶으면

ULONG PreviousPrivilege;

RtlAdjustPrivilege(20, TRUE, FALSE, &PreviousPrivilege)

를 해주면 될겁니다.

 

이상으로, 시스템 종료에 관한 몇몇 API와 그 쓰임에 대해 알아보았습니다.

Posted by skensita