I want my sleep key back! (or how to hibernate a machine from your app)

One of the first things I do when I get a new desktop machine or install a new build
of Windows is to map the Sleep button on my keyboard to hibernate instead of
suspend. Hibernate makes more sense for these machines because they will never
run on batteries and I want them to be truly off ;). This worked out great because
I have a bunch of first generation Microsft USB keyboards (they are off white with
a row of blue buttons across the top and a normal extended key layout). I got really,
really used to this. I would just hit the sleep key, the machine would
hibernate and I could walk away. No start menu, no mouse, just a simple key press.

Well, my keyboard at home broke and I bought a Microsoft Natural Ergonomic
Keyboard 4000 to replace it. Works great…but there is no Sleep key on the
keyboard! Ergh. So, instead I figured I would map one of the five
customizable keys (which meant I had to run IntelliType as well…<sigh>)
to an application which would hibernate the machine for me. I thought it would be
obvious, but it wasn’t.

In the end, the program is quite short, but figuring out
the magic user mode incantations was hard for a kernel curmudgeon like me.
Anyways, here is the app I wrote to get a machine to hibernate and return my ability to
put hibernate machine with a single keypress. All it does is adjust the
process’s token to enable SE_SHUTDOWN_NAME and then call SetSystemPowerState().
Simple as it is, I am proud of it ;).

    #ifndef WIN32_LEAN_AND_MEAN
#endif // WIN32_LEAN_AND_MEAN

#include <windows.h>
#include <stdio.h>

HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable or disable privilege
LUID luid;

if (!LookupPrivilegeValue(NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid)) { // receives LUID of privilege
printf("LookupPrivilegeValue error: %u\n", GetLastError() );
return FALSE;

tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege) {
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else {
tp.Privileges[0].Attributes = 0;

// Enable the privilege or disable all privileges.
if (!AdjustTokenPrivileges(hToken,
printf("AdjustTokenPrivileges error: %d / 0x%x\n",
GetLastError(), GetLastError() );
return FALSE;

if (GetLastError() == ERROR_NOT_ALL_ASSIGNED) {
printf("The token does not have the specified privilege.\n");
return FALSE;

return TRUE;

int __cdecl main()
HANDLE hToken;

if (!OpenProcessToken(GetCurrentProcess(),
&hToken)) {
printf("open failed %d / 0x%x\n", GetLastError(), GetLastError());
return FALSE;

if (SetPrivilege(hToken,
TRUE)) {
if (SetSystemPowerState(FALSE, TRUE) == FALSE) {
printf("failed %d / 0x%x\n", GetLastError(), GetLastError());
else {
printf("set failed %d / 0x%x\n", GetLastError(), GetLastError());

return 0;

Comments (11)

  1. JVert says:

    try "shutdown.exe /h" next time

    I guess you can put this down as ‘professional development’ though. 🙂

  2. I forgot to mention that I tried that already.  The /h option for shutdown.exe was added post XP SP2, which is the OS I really needed this for ;).

  3. No, it doesn’t solve that problem. in the thread, the calleer wants to disable a keyboard sleep button (see my response), here i am replacing a missing button


  4. barrkel says:

    For this, I use Cygwin’s hibernate program; any version of Windows that can hibernate, it’ll hibernate.

  5. well, that requires a toolchain that I don’t want to download ;).  besides, now i can do fun stuff like set a timer to hiber in 30 minutes and then create a waitable timer to wake the machine up later ;0.


  6. Moso says:

    How does it compare with a single line of code? Do I still need those privilege adjusting code if user were not admin?

    SetSuspendState(TRUE, FALSE, FALSE);

  7. Moso, good question on SetSuspendState().   I didn’t know about this function until you asked.  It does all of this work for your actually.  It will enable the SE_SHUTDOWN_NAME privilege for you before attempting the system power state transition.  Definitely makes for a simpler application :).


  8. I am a creature of habit. Once I get into a pattern, especially with keyboard keys (i.e. my sleep key

  9. jani667 says:

    Sorry for bringing this old thread up, but doronh, can you tell me how you create that waitable timer to wake the machine up later?