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;
}
 
			
				 back.gif (341 bytes)       up.gif (335 bytes)         next.gif (337 bytes)