Originally Posted By: Roger
That said: the go-to-sleep-and-wake-up-again functionality should work fine on XP


Not tested (or even compiled):

Code:
#define SUSPEND_SLEEP TRUE
#define SUSPEND_HIBERNATE FALSE

const LONGLONG FILETIME_UNITS_PER_MICROSECOND = 10;
const LONGLONG FILETIME_UNITS_PER_MILLISECOND = FILETIME_UNITS_PER_MICROSECOND * 1000;
const LONGLONG FILETIME_UNITS_PER_SECOND = FILETIME_UNITS_PER_MILLISECOND * 1000;

int _tmain(int argc, _TCHAR* argv[])
{
	BOOL fSuspend = SUSPEND_SLEEP;
	BOOL fForce = FALSE;
	DWORD delaySeconds = 90;

	HANDLE hToken;
	::OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);

	LUID privilegeId;
	LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &privilegeId);

	TOKEN_PRIVILEGES privs;
	privs.PrivilegeCount = 1;
	privs.Privileges[0].Luid = privilegeId;
	privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

	::AdjustTokenPrivileges(hToken, FALSE, &privs, sizeof(TOKEN_PRIVILEGES), NULL, 0);
	HANDLE hTimer = ::CreateWaitableTimer(NULL, FALSE, NULL);

	SYSTEMTIME systemTime;
	GetSystemTime(&systemTime);

	FILETIME fileTime;
	SystemTimeToFileTime(&systemTime, &fileTime);

	LARGE_INTEGER wakeTime;
	wakeTime.LowPart = fileTime.dwLowDateTime;
	wakeTime.HighPart = fileTime.dwHighDateTime;

	wakeTime.QuadPart += delaySeconds * FILETIME_UNITS_PER_SECOND;

	::SetWaitableTimer(hTimer, &wakeTime, 0, NULL, NULL, TRUE);
	::SetSystemPowerState(fSuspend, fForce);

	return 0;
}

_________________________
-- roger