Scheduled Windows Hibernating
A. First Edition
This is almost a trivial practice of win32 api. However, I spent a whole night, literally, to implement it.
I listen mp3 player and want to shut down my PC at a setup moment. What's more, I want my PC to hibernate instead of shutting down. Simple? A sort of, but the "privilege" in windows is a bit tricky and the timer is not so easy to use. (Actually there is a "windows" timer which doesn't work properly.)
The only thing I must remember is that the "PHANDLE" or HANDLE* cannot be passed as parameter to "OpenProcessToken". Instead you have to pass &HANDLE. This is really strange thing and drives me crazy for whole night.
E.Further improvement
F.File listing
1. winshut.cpp
file name: winshut.cpp
#include <iostream> #include <windows.h> #include <mmsystem.h> #include <process.h> //#include <PowrProf.h> // using namespace std; #pragma comment (lib, "winmm.lib") typedef BOOL (*SetSuspendState_Type)( BOOL Hibernate, BOOL ForceCritical, BOOL DisableWakeEvent ); void hibernate() { HANDLE handle=NULL; HMODULE hmodule; TOKEN_PRIVILEGES tp; //DWORD length; LUID luid; SetSuspendState_Type proc; if (!LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &luid)) { printf("lookup fails\n"); exit(23); } if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &handle)==0) { printf("open process token fails and error code is %d\n", GetLastError()); exit(2); } tp.PrivilegeCount=1; tp.Privileges[0].Luid=luid; tp.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED; if (AdjustTokenPrivileges(handle, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), NULL, NULL)==0) { printf("adjust token privileges fails error=%d \n", GetLastError()); exit(5); } /* if (ExitWindowsEx(EWX_POWEROFF, 0)==0) { printf("failed and error code is %d\n", GetLastError()); } */ if ((hmodule=LoadLibrary("powrprof.dll"))==NULL) { printf("load library fails\n"); exit(12); } proc=(SetSuspendState_Type)GetProcAddress(hmodule, "SetSuspendState"); proc(TRUE, FALSE, TRUE); } void CALLBACK timerProc(UINT uTimerID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2) { printf("prepare to hibernating...\n"); //hibernate(); } LPTIMECALLBACK pTimerProc=timerProc; int main(int argc, char** argv) { UINT delay; char* myArgs[2]; STARTUPINFO startInfo; PROCESS_INFORMATION pi; int hour, minute, second; if (argc==1) { hour=0; minute=0; second=3; } if (argc>2) { sscanf(argv[1], "%d:%d:%d", &hour, &minute, &second); } if (argc==3) { myArgs[0]=argv[2]; myArgs[1]=NULL; //////////////////////////// memset(&startInfo, 0, sizeof(STARTUPINFO)); memset(&pi, 0, sizeof(STARTUPINFO)); startInfo.cb=sizeof(STARTUPINFO); if (CreateProcess(argv[2], NULL, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &startInfo, &pi)==0) { printf("create process fails and error=%d\n", GetLastError()); exit(9); } } delay=(hour*3600+minute*60+second)*1000; if (!timeSetEvent(delay, 0, pTimerProc, 45, TIME_ONESHOT)) { printf("failed \n"); } else { printf("successful\n"); } Sleep(delay+5000); return 0; }