Ошибки при использовании NtEnumerateKey: почему KeyNameInformation не работает в Windows 7
В данной статье мы рассмотрим проблему, с которой сталкиваются разработчики при использовании функции NtEnumerateKey в контексте получения информации о ключах реестра в операционных системах семейства Windows, в частности, на примере Windows 7. Основное внимание будет уделено некорректной работе с параметром KeyInformation, что приводит к возврату ошибки NTSTATUS = 0xC000000D с сообщением "An invalid parameter was passed to a service or function.".
Проблема с KeyInformation в NtEnumerateKey
Функция NtEnumerateKey используется для перечисления информации о ключах реестра. Один из параметров этой функции — KeyInformation, который определяет тип запрашиваемой информации. В коде, представленном в вопросе, используется структура KEY_NAME_INFORMATION для получения имени ключа. Однако при выполнении этого кода на Windows 7 функция возвращает указанную выше ошибку.
type
KEY_NAME_INFORMATION = record
NameLength: ULONG;
Name: array[0..254] of WCHAR;
end;
PKEY_NAME_INFORMATION = ^KEY_NAME_INFORMATION;
var
iNtStatus: LONG;
hKeyResult: THandle;
KeyNameInfo: KEY_NAME_INFORMATION;
iResultLen: ULONG;
iNtStatus := NtOpenKey(@hKeyResult, (KEY_ENUMERATE_SUB_KEYS) and not
SYNCHRONIZE, @rObjAttrs);
if hKeyResult = 0 then Exit;
iNtStatus := NtEnumerateKey(hKeyResult,
0,
KeyNameInformation,
@KeyNameInfo,
SizeOf(KEY_NAME_INFORMATION),
@iResultLen);
Обновление: Странное поведение
Автор вопроса также упоминает, что если использовать KeyBasicInformation вместо KeyNameInformation, функция NtEnumerateKey возвращает STATUS_SUCCESS. Это поднимает вопрос о том, поддерживает ли NtEnumerateKey параметр KeyNameInformation.
type
KEY_BASIC_INFORMATION = record
LastWriteTime: LARGE_INTEGER;
TitleIndex: ULONG;
NameLength: ULONG;
Name: array[0..254] of WCHAR;
end;
PKEY_BASIC_INFORMATION = ^KEY_BASIC_INFORMATION;
var
KeyBasicInfo: KEY_BASIC_INFORMATION;
iNtStatus := NtEnumerateKey(hKeyResult,
0,
KeyBasicInformation,
@KeyBasicInfo,
SizeOf(KEY_BASIC_INFORMATION),
@iResultLen);
Подтвержденное решение
Изучение документации Zw(Nt для пользовательского режима)EnumerateKey показывает, что параметр KeyInformationClass должен быть установлен в значение, соответствующее одному из перечисленных типов информации: KeyBasicInformation, KeyFullInformation, KeyNodeInformation. Если указать значение, не входящее в этот список, функция вернет ошибку STATUS_INVALID_PARAMETER.
type
TKeyInformationClass = (KeyBasicInformation, KeyFullInformation, KeyNodeInformation);
var
// ...
KeyInformationClass: TKeyInformationClass;
begin
// ...
KeyInformationClass := KeyBasicInformation; // или другой допустимый тип
// ...
end;
Альтернативный ответ
Проблема может крыться в неправильной инициализации структуры KeyInformation. Важно убедиться, что структура полностью инициализирована перед передачей её в функцию NtEnumerateKey. Например, если используется KeyNameInformation, необходимо удостовериться, что поле NameLength корректно инициализировано, а массив Name достаточно велик для хранения результата.
Заключение
При работе с функцией NtEnumerateKey важно правильно определить тип запрашиваемой информации и убедиться, что структура для этой информации корректно инициализирована. В случае с Windows 7 и KeyNameInformation, возможно, потребуется дополнительная проверка версий API и совместимости с операционной системой, так как поддержка различных типов информации может отличаться.
Проблема заключается в ошибках, возникающих при использовании функции `NtEnumerateKey` для получения информации о ключах реестра в Windows 7, особенно при попытке использовать параметр `KeyNameInformation`, что приводит к возврату ошибки `STATUS_INVALID_
Комментарии и вопросы
Получайте свежие новости и обновления по Object Pascal, Delphi и Lazarus прямо в свой смартфон. Подпишитесь на наш Telegram-канал delphi_kansoftware и будьте в курсе последних тенденций в разработке под Linux, Windows, Android и iOS
Материалы статей собраны из открытых источников, владелец сайта не претендует на авторство. Там где авторство установить не удалось, материал подаётся без имени автора. В случае если Вы считаете, что Ваши права нарушены, пожалуйста, свяжитесь с владельцем сайта.