{
For some functions you need to get the right privileges
on a Windows NT machine.
(e.g: To shut down or restart windows with ExitWindowsEx or
to change the system time)
The following code provides a procedure to adjust the privileges.
The AdjustTokenPrivileges() function enables or disables privileges
in the specified access token.
}// NT Defined Privileges from winnt.h const
SE_CREATE_TOKEN_NAME = 'SeCreateTokenPrivilege';
SE_ASSIGNPRIMARYTOKEN_NAME = 'SeAssignPrimaryTokenPrivilege';
SE_LOCK_MEMORY_NAME = 'SeLockMemoryPrivilege';
SE_INCREASE_QUOTA_NAME = 'SeIncreaseQuotaPrivilege';
SE_UNSOLICITED_INPUT_NAME = 'SeUnsolicitedInputPrivilege';
SE_MACHINE_ACCOUNT_NAME = 'SeMachineAccountPrivilege';
SE_TCB_NAME = 'SeTcbPrivilege';
SE_SECURITY_NAME = 'SeSecurityPrivilege';
SE_TAKE_OWNERSHIP_NAME = 'SeTakeOwnershipPrivilege';
SE_LOAD_DRIVER_NAME = 'SeLoadDriverPrivilege';
SE_SYSTEM_PROFILE_NAME = 'SeSystemProfilePrivilege';
SE_SYSTEMTIME_NAME = 'SeSystemtimePrivilege';
SE_PROF_SINGLE_PROCESS_NAME = 'SeProfileSingleProcessPrivilege';
SE_INC_BASE_PRIORITY_NAME = 'SeIncreaseBasePriorityPrivilege';
SE_CREATE_PAGEFILE_NAME = 'SeCreatePagefilePrivilege';
SE_CREATE_PERMANENT_NAME = 'SeCreatePermanentPrivilege';
SE_BACKUP_NAME = 'SeBackupPrivilege';
SE_RESTORE_NAME = 'SeRestorePrivilege';
SE_SHUTDOWN_NAME = 'SeShutdownPrivilege';
SE_DEBUG_NAME = 'SeDebugPrivilege';
SE_AUDIT_NAME = 'SeAuditPrivilege';
SE_SYSTEM_ENVIRONMENT_NAME = 'SeSystemEnvironmentPrivilege';
SE_CHANGE_NOTIFY_NAME = 'SeChangeNotifyPrivilege';
SE_REMOTE_SHUTDOWN_NAME = 'SeRemoteShutdownPrivilege';
SE_UNDOCK_NAME = 'SeUndockPrivilege';
SE_SYNC_AGENT_NAME = 'SeSyncAgentPrivilege';
SE_ENABLE_DELEGATION_NAME = 'SeEnableDelegationPrivilege';
SE_MANAGE_VOLUME_NAME = 'SeManageVolumePrivilege';
// Enables or disables privileges debending on the bEnabled function NTSetPrivilege(sPrivilege: string; bEnabled: Boolean): Boolean;
var
hToken: THandle;
TokenPriv: TOKEN_PRIVILEGES;
PrevTokenPriv: TOKEN_PRIVILEGES;
ReturnLength: Cardinal;
begin
Result := True;
// Only for Windows NT/2000/XP and later. ifnot (Win32Platform = VER_PLATFORM_WIN32_NT) then Exit;
Result := False;
// obtain the processes token if OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken) thenbegintry// Get the locally unique identifier (LUID) . if LookupPrivilegeValue(nil, PChar(sPrivilege),
TokenPriv.Privileges[0].Luid) thenbegin
TokenPriv.PrivilegeCount := 1; // one privilege to set case bEnabled ofTrue: TokenPriv.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
False: TokenPriv.Privileges[0].Attributes := 0;
end;
ReturnLength := 0; // replaces a var parameter
PrevTokenPriv := TokenPriv;
// enable or disable the privilege
AdjustTokenPrivileges(hToken, False, TokenPriv, SizeOf(PrevTokenPriv),
PrevTokenPriv, ReturnLength);
end;
finally
CloseHandle(hToken);
end;
end;
// test the return value of AdjustTokenPrivileges.
Result := GetLastError = ERROR_SUCCESS;
ifnot Result thenraise Exception.Create(SysErrorMessage(GetLastError));
end;
Код-snippet на Delphi, который предоставляет процедуру для изменения привилегий на машинке Windows NT. Функция NTSetPrivilege включает или отключает привилегии в указанном токене доступа.
Код определяет набор констант для различных привилегий, определенных NT, таких как SE_CREATE_TOKEN_NAME, SE_ASSIGNPRIMARYTOKEN_NAME и т.д.
Функция NTSetPrivilege принимает два параметра: sPrivilege (имя привилегии для включения или отключения) и bEnabled (логическое значение, указывающее, нужно ли включить или отключить привилегию).
Вот шаги функции:
Она проверяет, является ли платформа Windows NT, XP или позднее.
Она получает токен процесса с помощью OpenProcessToken.
Она получает уникальный локальный идентификатор (LUID) для указанной привилегии с помощью LookupPrivilegeValue.
Она задает массив Privileges содержимым, состоящим из одного элемента с указанным LUID и атрибутами (включено или отключено).
Она вызывает функцию AdjustTokenPrivileges, чтобы включить или отключить привилегию.
Если функция неудачна, она выбрасывает исключение с ошибкой.
Функция возвращает логическое значение, указывающее, была ли привилегия успешно включена или отключена.
Некоторые потенциальные улучшения:
Рассмотрите использование более описательных имен переменных, таких как privilegeName вместо sPrivilege.
Вам может потребоваться добавление обработки ошибок для случаев, когда функции OpenProcessToken или LookupPrivilegeValue неудачны.
Если вы целяете на Windows Vista или позднее, рассмотрите использование константы SeSecurityPrivilege вместо SE_SECURITY_NAME, так как последняя является устаревшей.
В целом, этот код предоставляет полезную функцию для изменения привилегий на машинках Windows NT.
Установка привилегий на Windows NT позволяет выполнять функции с повышенными правами, такие как shutdown, restart и изменение системного времени.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.