Ошибка при вызове LsaOpenPolicy в Delphi 2010: Поиск и устранение причин
В данной статье мы рассмотрим проблему, с которой столкнулся разработчик при работе с функцией LsaOpenPolicy в среде Delphi 2010. Проблема заключается в том, что при вызове этой функции происходит исключение, и код, полученный из новогоsgroup, не работает.
Контекст проблемы:
Разработчик использовал функцию AddLogonAsAService, которая предназначена для добавления прав на вход в систему в качестве сервиса для указанного аккаунта. В коде используется функция LsaOpenPolicy для получения доступа к политике безопасности. Однако, при выполнении кода в среде Delphi 2010, возникает исключение в момент вызова LsaOpenPolicy.
Анализ кода:
В коде присутствуют некоторые ошибки, которые могут вызывать исключение:
Неправильная инициализация Server и Privilege (как отметил Remko).
При выделении памяти для ReferencedDomain выделяется 16 байтов, что недостаточно для строки в кодировке Unicode, используемой в Delphi 2010 и выше.
После использования LsaOpenPolicy не закрывается дескриптор политики, что может привести к утечке ресурсов.
Подтвержденный ответ:
Для решения проблемы необходимо внести следующие изменения:
Исправить инициализацию Server и Privilege.
Выделить память для ReferencedDomain с учётом размера символа в кодировке Unicode (SizeOf(Char)).
Добавить вызов LsaClose для закрытия дескриптора политики после его использования.
Также стоит обратить внимание на использование библиотек. Рекомендуется использовать Jedi Apilib, так как он содержит обновленные и правильно определенные функции и структуры.
Пример кода с исправлениями:
uses
JwaWinType, JwaNtSecApi;
function AddLogonAsAService(ID: pchar): boolean;
var
FResult: NTSTATUS;
FObjectAttributes: TLSAObjectAttributes;
FPolicyHandle: LSA_HANDLE;
Server, Privilege: TLSAUnicodeString;
FSID: PSID;
cbSid: DWORD;
ReferencedDomain: LPTSTR;
cchReferencedDomain: DWORD;
peUse: SID_NAME_USE;
PrivilegeString: String;
begin
Result := false;
try
ZeroMemory(@FObjectAttributes, SizeOf(TLSAObjectAttributes));
Server.Buffer := nil;
Server.Length := 0;
Server.MaximumLength := 256 * SizeOf(WideChar);
PrivilegeString := 'SeServiceLogonRight'; // или другой привилегии
Privilege.Buffer := PChar(PrivilegeString);
Privilege.Length := Length(PrivilegeString) * SizeOf(WideChar);
Privilege.MaximumLength := Privilege.Length + SizeOf(WideChar);
FResult := LsaOpenPolicy(
@Server, // на этой машине, так как буфер - NIL
@FObjectAttributes,
POLICY_ALL_ACCESS,
FPolicyHandle);
if FResult = STATUS_SUCCESS then
begin
// ...
// код для работы с политикой
// ...
end
else
begin
// Обработка ошибки
end;
LsaClose(FPolicyHandle); // Закрытие дескриптора политики
except
Result := false;
end;
end;
Альтернативный ответ:
В коде, предоставленном пользователем "andrew" в newsgroup, были обнаружены дополнительные ошибки, которые могли вызвать исключение. После внесения изменений, предложенных в альтернативном ответе, включая использование Jedi Apilib и корректную инициализацию буферов, код должен работать.
Заключение:
При работе с функциями безопасности Windows важно внимательно относиться к деталям, таким как корректное управление памятью и закрытие ресурсов. Использование проверенных библиотек, таких как Jedi Apilib, может помочь избежать многих распространенных ошибок.
Описание контекста: В статье рассматривается проблема, связанная с ошибкой при вызове функции `LsaOpenPolicy` в среде разработки Delphi 2010, включая анализ кода и предложения по устранению возникших исключений.
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.