Пытаюсь определить DriveEntry драйвера и слетаю в синяк. ObReferenceObjectByName () вызываю для L"\\Driver\\drvname" В чем можетбыть баг ?
Покажи как вызываешь? Вот это должно работать: Код (Text): status = ObReferenceObjectByName ( pusObjectPath, OBJ_CASE_INSENSITIVE, NULL, GENERIC_READ, *IoDriverObjectType, KernelMode, NULL, &pObject );
мой код (обрати внимание на IoDriverObjectType DDK разрешает NULL,а с IoDriverObjectType я не смог собрать - компилятор говорит, что не знает его) Код (Text): ULONG GetDriverAddress (PCHAR driverName, PARAM_ADDRESS param){ UNICODE_STRING stringW = {0}; ANSI_STRING stringA = {0}; PDRIVER_OBJECT driverObject = NULL; ULONG result = 0; BYTE name [MAX_PATH] = {0}; strcpy (name, "\\Driver\\"); strcpy (name, driverName); RtlInitAnsiString (&stringA, name); RtlAnsiStringToUnicodeString (&stringW, &stringA, TRUE); __try { if (!NT_SUCCESS (ObReferenceObjectByName (&stringW, OBJ_CASE_INSENSITIVE, NULL, FILE_READ_ACCESS, [b]NULL[/b], KernelMode, NULL, (PVOID *) &driverObject))){ #ifdef DBG DbgPrint (("DRVMON: Failed get reference object by name (GetDriverEntry)\n")); #endif return 0; } switch (param){ case DRIVER_ENTRY : result = (ULONG) driverObject->DriverStartIo; break; case ADD_DEVICE : result = (ULONG) driverObject->DriverExtension->AddDevice; break; } ObDereferenceObject ( (PVOID)driverObject ); } __finally { RtlFreeUnicodeString (&stringW); } return result; }
NULL в качестве ObjectType никак не можно. Должен быть указатель на тип объекта. Линкер ругается потому что ддк определяет указатели на всего три объекта тип: extern POBJECT_TYPE *IoFileObjectType; extern POBJECT_TYPE *ExEventObjectType; extern POBJECT_TYPE *ExSemaphoreObjectType; экспортируется же намного больше. Достаточно просто знать имена переменных, в который лежат соотв. указатели и определить их. Этот код должен собраться без проблем и работать. Код (Text): #include <ntddk.h> NTSTATUS DriverEntry(PDRIVER_OBJECT, PUNICODE_STRING); #pragma alloc_text( INIT, DriverEntry ) #undef ObReferenceObjectByName __declspec(dllimport) NTSTATUS ObReferenceObjectByName( IN PUNICODE_STRING ObjectName, IN ULONG Attributes, IN PACCESS_STATE PassedAccessState OPTIONAL, IN ACCESS_MASK DesiredAccess OPTIONAL, IN POBJECT_TYPE ObjectType, IN KPROCESSOR_MODE AccessMode, IN OUT PVOID ParseContext OPTIONAL, OUT PVOID *Object ); extern POBJECT_TYPE *IoDriverObjectType; #ifndef DECLARE_CONST_UNICODE_STRING #define DECLARE_CONST_UNICODE_STRING(_variablename, _string) \ const WCHAR _variablename ## _buffer[] = _string; \ const UNICODE_STRING _variablename = { sizeof(_string) - sizeof(WCHAR), sizeof(_string), (PWSTR) _variablename ## _buffer }; #endif DECLARE_CONST_UNICODE_STRING( g_usDriverPath, L"\\Driver\\Beep" ); NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { NTSTATUS status; PDRIVER_OBJECT pDriverObject; status = ObReferenceObjectByName ( (PUNICODE_STRING) &g_usDriverPath, OBJ_CASE_INSENSITIVE, NULL, GENERIC_READ, *IoDriverObjectType, KernelMode, NULL, &pDriverObject); if ( NT_SUCCESS( status ) ) { DbgPrint( "%wZ at %p\n", &g_usDriverPath, pDriverObject->DriverStart ); ObDereferenceObject( pDriverObject ); } return STATUS_DEVICE_CONFIGURATION_ERROR; }
Four-F обяъясни пожалуйста, что это означает Код (Text): [b]#undef[/b] ObReferenceObjectByName __declspec(dllimport) и почему __declspec(dllimport) а также что это есть такое Код (Text): #ifndef DECLARE_CONST_UNICODE_STRING #define DECLARE_CONST_UNICODE_STRING(_variablename, _string) \ const WCHAR _variablename ## _buffer[] = _string; \ const UNICODE_STRING _variablename = { sizeof(_string) - sizeof(WCHAR), sizeof(_string), (PWSTR) _variablename ## _buffer }; #endif
Почему же? можно. Это означает что тип объекта нам не важен. ObjectType нужен только, если объект нам передан из юзермодного кода для проверки типа объекта.
Строго говоря #undef ObReferenceObjectByName не нужен. Я выдрал определение из одного проекта и зацепил эту строку. У меня в проекте я просто хочу быть уверен, что компилятор будет использовать именно это определение. Что такое __declspec(dllimport) см. в MSDN. Закоментарь его, скомпили и посмотри в дизасме разницу. Без __declspec(dllimport) функция будет вызываться через доп. трамплин. Можно и без __declspec(dllimport). Это макрос Определен в ntdef.h начиная с ХР. Позволяет вместо такого убогого кода определить сразу всё что нужно. Код (Text): UNICODE_STRING us; RtlInitUnicodeString( &us, L"bla-bla" ); Единственно - если юникод сторок будет очень много, то может быть выгоднее использовать RtlInitUnicodeString. Ты, возможно, путаешь с ObReferenceObjectByHandle. Там ObjectType опционален. Функции, работающие с именами другая история. Хотя, чёрт его знает. Доберусь до отладчика - посмотрю.