This entry was posted on Monday, March 16th, 2009 at 10:35 am and is filed under Tech Stuff. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.
Windows can be programmatically shutdown using the ExitWindowsEx() Win32 function. However it turns out that the trick to getting it to work is to first grant shutdown priviliges to the calling process via some rather ugly security functions – this type of faffing around can never me remembered so I will post some sample code here in the hopes that it might help me (in the future) or maybe someone else:
bool ShutdownPC(const bool reboot) { HANDLE hToken = NULL; if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { cerr << "OpenProcessToken() " << GetLastError(); return false; } TOKEN_PRIVILEGES tkp; if (!LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid)) { cerr << "LookupPrivilegeValue() " << GetLastError(); return false; } tkp.PrivilegeCount = 1; tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; if(!AdjustTokenPrivileges(hToken, false, &tkp, 0, NULL, NULL)) { cerr << "AdjustTokenPrivileges() " << GetLastError(); return false; } // And shutdown... with force! bool ret = ExitWindowsEx((reboot ? EWX_REBOOT : EWX_SHUTDOWN) | EWX_FORCE | EWX_FORCEIFHUNG, SHTDN_REASON_MAJOR_APPLICATION | SHTDN_REASON_MINOR_MAINTENANCE) == TRUE; if (!ret) { cerr << "ExitWindowsEx() " << GetLastError(); } return ret; }
