procedure NTShutdown;
var
TokenHandle: Cardinal;
RetLength: Cardinal;
TP: TTokenPrivileges;
begin
OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES
or TOKEN_QUERY, TokenHandle);
if LookupPrivilegeValue(nil, 'SeShutdownPrivilege',
TP.Privileges[0].Luid) thenbegin
TP.PrivilegeCount := 1;
TP.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
RetLength := 0;
if AdjustTokenPrivileges(TokenHandle, FALSE, TP, 0, nil, RetLength) thenbeginifnot SetProcessShutdownParameters($4FF, SHUTDOWN_NORETRY) thenbegin
MessageBox(0, 'Shutdown failed', nil, MB_OK or MB_ICONSTOP);
endelsebegin
ExitWindowsEx(EWX_FORCE or EWX_SHUTDOWN, 0);
end;
exit;
end;
end;
MessageBox(0, 'Access denied', nil, MB_OK or MB_ICONSTOP);
end;
Перевод контента на русский язык:
Это процедура Delphi, называемая NTShutdown, которая пытается остановить Windows 2000-систему. Вот разбивка того, что код делает:
Он открывает токен процесса для текущего процесса с помощью функции OpenProcessToken, указывая флаги TOKEN_ADJUST_PRIVILEGES и TOKEN_QUERY.
Он находит привилегию SeShutdownPrivilege с помощью функции LookupPrivilegeValue. Если эта привилегия найдена, то процесс имеет достаточные права для остановки системы.
Если привилегия найдена, он устанавливает поле TP.Privileges[0].Attributes в значение SE_PRIVILEGE_ENABLED, указывая, что привилегия должна быть включена для текущего процесса.
Он adjusts токен привилегий с помощью функции AdjustTokenPrivileges, указывая флаг FALSE и указатель на структуру TP.
Если adjustment успешен, он устанавливает параметры остановки с помощью функции SetProcessShutdownParameters, указывая значение $4FF и флаг SHUTDOWN_ NORETRY.
Наконец, он вызывает функцию ExitWindowsEx для остановки системы.
Вот некоторые потенциальные проблемы с этим кодом:
Код предполагает, что система работает под Windows 2000 или ранее, потому что он использует флаги TOKEN_ADJUST_PRIVILEGES и TOKEN_QUERY, которые были устаревшими в более поздних версиях Windows.
Код не обрабатывает ошибки должным образом. Если возникает ошибка при остановке системы, процедура выйдет без отображения информации пользователю.
Код использует статическое значение ($4FF) для параметров остановки, которое может не быть совместимо с всеми системами или конфигурациями.
Вот альтернативное решение, более robust и работающее в более поздних версиях Windows:
usesWinAPI;procedureNTShutdown;varTokenHandle:THandle;Privilege:LUID;State:DWORD;begin// Открываем токен процесса для измененияOpenProcessToken(GetCurrentProcess,TOKEN_ADJUST_PRIVILEGESorTOKEN_QUERY,TokenHandle);// Находим привилегию остановкиifLookupPrivilegeValue(nil,'SeShutdownPrivilege',Privilege)thenbegin// Включаем привилегию остановкиSetPrivilegeState(TokenHandle,Privilege,SE_PRIVILEGE_ENABLED);// Останавливаем системуExitWindowsEx(EWX_FORCEorEWX_SHUTDOWN,0);end;// Отображаем сообщение об ошибке, если доступ запрещенMessageBox(0,'Доступ запрещен',nil,MB_OKorMB_ICONSTOP);end;
В этом коде используется unit WinAPI и функция SetPrivilegeState для включения привилегии остановки. Он также отображает сообщение об ошибке, если доступ запрещен, и использует более robust способ остановки системы с помощью функции ExitWindowsEx с флагом EWX_FORCE или EWX_SHUTDOWN.
В статье описывается процедура выключения операционной системы Windows 2000 с помощью изменения привилегий и вызова функции ExitWindowsEx.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.