У вас есть разрешение, но оно отключено . Вот что говорит PowerShell.
Для выключения системы вы используете функцию Win32API, которая называется InitiateSystemShutdown
или ExitWindowsEx
:
ExitWindowsEx(EWX_POWEROFF, 0);
Примечание этих функций:
Чтобы завершить работу локального компьютера, вызывающий поток должен иметь привилегию SE_SHUTDOWN_NAME. По умолчанию пользователи могут включить привилегию SE_SHUTDOWN_NAME на компьютере, на котором они вошли, а администраторы могут включить привилегию SE_REMOTE_SHUTDOWN_NAME на удаленных компьютерах.
Как видите, Windows проверяет привилегии потоков (любой поток имеет токен с привилегиями). Если вы звоните ExitWindowsEx
без привилегии SE_SHUTDOWN_NAME, функция завершится с ошибкой:
Error code: 1314 A required privilege is not held by the client
Потоки, которые вы создаете по умолчанию, наследуют ваши привилегии; но программа может включить отключенную привилегию, которая была предоставлена с помощью AdjustTokenPrivileges
:
TOKEN_PRIVILEGES tp; tp.PrivilegeCount = 1; tp.Privileges[0].Luid = LookupPrivilegeValue(NULL, "SeShutdownPrivilege"); tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; HANDLE processToken = OpenProcessToken(GetCurrentProcess, TOKEN_ADJUST_PRIVILEGES); AdjustTokenPrivileges(processToken, false, tp, 0, NULL, NULL); CloseHandle(processToken);
Изменение привилегий в токене говорит:
AdjustTokenPrivileges
невозможно добавить или удалить привилегии из токена. Он может включать только существующие привилегии, которые в данный момент отключены, или отключать существующие привилегии, которые в данный момент включены
Итак, почему эта привилегия отключена по умолчанию? Чтобы убедиться, что ни одна программа не может закрыть Windows случайно. Приложения должны запрашивать это явно.
Есть древняя, но очень хорошая книга: https://www.amazon.com/Programming-Windows-Security-Keith-Brown/dp/0201604426/ обо всем этом.