Reputation: 50883
Before we can use the ExitWindowsEx
function for shutting down the computer, we must add the SE_SHUTDOWN_NAME
privilege to the process like this:
HANDLE hToken = NULL;
LUID luid;
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken);
LookupPrivilegeValue(L"", SE_SHUTDOWN_NAME, &luid);
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
bRet = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, 0);
ExitWindowsEx(EWX_REBOOT, 0);
This works perfectly fine.
I know that this is by design, but I don't understand what's the motivation of Microsoft for deciding that a privilege must be enabled before the ExitWindowsEx
function can be used. It's obviously not designed to prevent a process from rebooting the computer, because all it needs to do for rebooting is adding the SE_SHUTDOWN_NAME to the process and call ExitWindowsEx
.
The Windows developpment term could have put the code above directly into the ExitWindowsEx
function.
Upvotes: 3
Views: 2378
Reputation: 6608
You don't need to add it (you can't add a privilege to your current token), you need to enable it.
Most privileges are disabled by default, probably to avoid an accidental use (just like the read-only attribute on files). There's no need to run around with the privilege enabled at all times, and having the ExitWindowsEx
function enable it by itself would break consistency with other privilege-dependent functions.
Upvotes: 12