출처 : http://www.jiniya.net/wp/archives/4511
Power state | ACPI state | Description |
---|---|---|
Working | S0 | The system is fully usable. Devices that are not in use can save power by entering a lower power state. |
Sleep | S1 S2 S3 | The system appears to be off. Power consumption is reduced to one of several levels, depending on how the system is to be used. The lower the level of power consumption, the more time it takes the system to return to the working state. |
Hibernation | S4 | The system appears to be off. Power consumption is reduced to the lowest level. The system saves the contents of memory to a hibernation file, preserving the state of the operating system, applications, and open documents. |
Soft Off | S5 | The system appears to be off. Some components remain powered so the computer can wake from input from the keyboard, LAN, or a USB device. The working context can be restored if it is stored on nonvolatile media. |
Mechanical Off | G3 | The system is completely off and consumes no power. The system returns to the working state only after a full reboot. |
동작 상태(S0), 수면 상태(S1, S2, S3), 하이버네이션 상태(S4), 소프트 오프 상태(S5), 그리고 완전 오프 상태(G3)
하이버네이션을 시키는 방법
1 |
SetSystemPowerState(FALSE, FALSE); |
전원을 꺼버릴 권한이요. 그렇다면 당연히 해당 권한을 획득
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
static BOOL WINAPI _EnableShutDownPriv() { BOOL ret = FALSE; HANDLE process = GetCurrentProcess(); HANDLE token; if(!OpenProcessToken(process , TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY , &token)) return FALSE; LUID luid; LookupPrivilegeValue(NULL, "SeShutdownPrivilege", &luid); TOKEN_PRIVILEGES priv; priv.PrivilegeCount = 1; priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; priv.Privileges[0].Luid = luid; ret = AdjustTokenPrivileges(token, FALSE, &priv, 0, NULL, NULL); CloseHandle(token); return TRUE; } |
깨우기
웨이터블 타이머(waitable timer)가 정식 명친인데요, 이 녀석은 하이버네이션 상태가 되더라도 동작
1 2 3 4 5 6 7 8 9 10 11 12 13 |
HANDLE timer = CreateWaitableTimer(NULL, TRUE, "MyWaitableTimer"); if(timer == NULL) return FALSE; __int64 nanoSecs; LARGE_INTEGER due; nanoSecs = -secs * 1000 * 1000 * 10; due.LowPart = (DWORD) (nanoSecs & 0xFFFFFFFF); due.HighPart = (LONG) (nanoSecs >> 32); if(!SetWaitableTimer(timer, &due, 0, 0, 0, TRUE)) return FALSE; |
대기 타이머에서 깨어나더라도 운영체제는 시스템을 바로 깨우지 않습니다. 우리가 전원이 필요하다고 운영체제에 알려줄 때 윈도우는 친절히도 시스템에 전원을 넣고 이전 상태로 복구
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
DWORD CALLBACK ShutDownProc(LPVOID p) { PHANDLE timer = (PHANDLE) p; WaitForSingleObject(*timer, INFINITE); CloseHandle(*timer); SetThreadExecutionState(ES_DISPLAY_REQUIRED); return 0; } PWRMGMT_API BOOL WINAPI HibernateAndReboot(int secs) { if(!_EnableShutDownPriv()) return FALSE; HANDLE timer = CreateWaitableTimer(NULL, TRUE, "MyWaitableTimer"); if(timer == NULL) return FALSE; __int64 nanoSecs; LARGE_INTEGER due; nanoSecs = -secs * 1000 * 1000 * 10; due.LowPart = (DWORD) (nanoSecs & 0xFFFFFFFF); due.HighPart = (LONG) (nanoSecs >> 32); if(!SetWaitableTimer(timer, &due, 0, 0, 0, TRUE)) return FALSE; if(GetLastError() == ERROR_NOT_SUPPORTED) return FALSE; HANDLE thread = CreateThread(NULL, 0, ShutDownProc, &timer, 0, NULL); if(!thread) { CloseHandle(timer); return FALSE; } CloseHandle(thread); SetSystemPowerState(FALSE, FALSE); return TRUE; } |