Доброго времени суток. Сейчас передо мной стоит задача переделать инсталятор драйвера, чтобы тот мог выгружать предыдущую версию и загружать новую без перезагрузки. В драйвере предусмотрена "динамическая выгрузка". Драйвер регистрируется в системе соответствующим ключем реестра (создаются поля ImagePath, Type, Group, Start и тд), загружается функцией ZwLoadDriver. Загрузка проходит нормально, но с выгрузкой предыдущей версии - проблемы. Я пытаюсь выгрузить драйвер с помощью функции ZwUnloadDriver, отправляя в качестве параметра путь к тому же ключу реестра, по которому производилась регистрация. На это действо выскакивает ошибка с кодом 0xC0000034 (STATUS_OBJECT_NAME_NOT_FOUND), я попытался для эксперимента явно добавить поле ObjectName, в качестве значения которого указал ту же строку, что и в имени драйвера (имени ключа реестра). Но стала выскакивать другая ошибка - 0xC000003B (STATUS_OBJECT_PATH_SYNTAX_BAD), смысл которой я не могу понять. Помогите пожалуйста разобраться... Заранее спасибо! Если будет нужно, завтра выложу код загрузки и выгрузки драйвера... ЗЫ Извините канеш за глупый вопрос, наверняка решение лежит совсем рядом, но я его в упор не вижу. ЗЗЫ И ещё извините за терминологию, которой изложил проблему, просто раньше не доводилось иметь дело с драйверами)))
Покажи код. Обычно для выгрузки драйвера нужен примерно такой код Код (Text): UNICODE_STRING RegistryPath; NTSTATUS Status; RtlInitUnicodeString (&RegistryPath, L"\\Registry\\Machine\\CurrentControlSet\\Services\\ServiceName"); Status = ZwUnloadDriver (&RegistryPath); DbgPrint ("ZwUnloadDriver returned status %lx\n", Status);
Драйвер запускается по ключу: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\drvntk32 Код (Text): DisplayName (REG_SZ) = drvntk32 ErrorControl (REG_DWORD) = 0x00000000 Group (REG_SZ) = Streams Drivers ImagePath (REG_SZ) = \SystemRoot\drvntk32.sys Start (REG_DWORD) = 0x00000001 Type (REG_DWORD) = 0x00000001 Код выгружающий драйвер: Код (Text): bool StopDriver(const WCHAR* name) { LONG status = FALSE; HMODULE hNtdll = LoadLibrary(L"ntdll.dll"); PZWUD pZwUnloadDriver = (PZWUD)GetProcAddress(hNtdll, "ZwUnloadDriver"); if(pZwUnloadDriver == NULL) { printf("pZwUnloadDriver == NULL\n"); return false; } PRIUS pRtlInitUnicodeString = (PRIUS)GetProcAddress(hNtdll, "RtlInitUnicodeString"); if(pRtlInitUnicodeString == NULL) { printf("pRtlInitUnicodeString == NULL\n"); return false; } UNICODE_STRING uRegName; pRtlInitUnicodeString(&uRegName, name); status = pZwUnloadDriver(&uRegName); printf("ZwUnloadDriver = 0x%x\n", status); return status == STATUS_SUCCESS; } Запускается с параметром: name = L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\drvntk32"; Возникает ошибка: 0xC0000034; Если я явно добавляю в указанный ключ поле ObjectName (REG_SZ) = drvntk32, то при попытке выгрузки возникает ошибка: 0xC000003B. Вот как то так))
Мыслей особых у меня нет, но попробуй написать так: Код (Text): L"\\Registry\\Machine\\SYSTEM\\ControlSet00X\\Services\\drvntk32" где X это номер текущей конфигурации. Этот номер можно взять отсюда: Код (Text): HKEY_LOCAL_MACHINE\SYSTEM\Select, Current Не факт, что поможет, но мало ли.
конвенции вызова NtApi корректны? \SystemRoot\ - это папка винды, нужна именно она, или всё же \SystemRoot\system32 ?
да, адреса функций проверял, если ты об этом)))) да, драйвер лежит в папке винды, он бы не запустился при старте системы, если путь был бы неправильным... кажется, что просто не хватает некоторых полей в ключе реестра, но чего именно не хватает - мне не понятно...
нет... странно это все... мне кажется, что дело все таки в неправильном ключе реестра... жалко, придется видимо делать с перезагрузкой...
Случайно натолкнулся на такую же проблему. Решение - читать МСДН. Rel ваш код: МСДН (http://msdn.microsoft.com/en-us/library/ff567117(VS.85).aspx)
Это не может быть причиной, т.к. сервисы NtLoadDriver() и NtUnloadDriver() используют флаг OBJ_CASE_INSENSITIVE.
Rel, а стандартные консольные утилиты (net или sc) нормально этот драйвер выгружают? Попробуй: Код (Text): net stop drvntk32
Да, еще не увидел в коде разрешения привелегии загрузки/выгрузки драйверов SE_LOAD_DRIVER_NAME, хотя это дает совершенно другой статус ошибки.