Scheduled window hibernating

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.

    ¡¡

    B.The problem

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.)

¡¡

C.The idea of program
¡¡

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.

¡¡

¡¡

    D.The major functions

    ¡¡

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

    ¡¡