Здравствуйте! Пытаюсь написать драйвер, который просто пересылал бы код управления (IOCTL) нижележащему драйверу. Вроде делаю по шаблону, который взял с этого же могучего сайта (не помню в какой теме это было), но почему-то все зарывается на вызове API IoCallDriver. Вот код: Код (Text): *Includes* .data ;===Variables=== TargetDevName dw '\','D','e','v','i','c','e','\','U','S','B','F','D','O','-','0',0h dbg_err db "Error!",0dh,0h format db '%S',0h ctrl_code dd 0 ;===END=== .code DriverEntry proc pDriverObject:DRIVER_OBJECT, pusRegistryPath:UNICODE_STRING Call OpenFile mov eax,STATUS_DEVICE_CONFIGURATION_ERROR Ret DriverEntry endp ;==============================PROCEDURES==================== OpenFile proc local unstruc:UNICODE_STRING local p_iosb:IO_STATUS_BLOCK local p_devobj:DEVICE_OBJECT local p_irpstr:_IRP local p_event:KEVENT local p_fo:FILE_OBJECT local irpvar:DWORD invoke RtlInitUnicodeString,addr unstruc,offset TargetDevName Invoke DbgPrint,offset format,unstruc.Buffer;юникод-строка нормальная Invoke IoGetDeviceObjectPointer,addr unstruc,SYNCHRONIZE+FILE_ALL_ACCESS,addr p_fo,addr p_devobj mov dword ptr [dbg_err+1],eax Invoke DbgPrint,offset dbg_err;в eax STATUS_SUCCESS invoke KeInitializeEvent,addr p_event,NotificationEvent,0 mov ctrl_code,00220444h invoke IoBuildDeviceIoControlRequest,ctrl_code,addr p_devobj,0,0,0,0,0,addr p_event,addr p_iosb mov irpvar,eax mov dword ptr [dbg_err+1],eax invoke DbgPrint,offset dbg_err;в eax указатель на IRP пакет invoke IoCallDriver,addr p_devobj,irpvar; вот здесь система падает. BSOD 0x0000007E (0xC0000005,0x001200A0,0xF7A269CC,0xF7A266C8) mov dword ptr [dbg_err+1],eax Invoke DbgPrint,offset dbg_err cmp eax,STATUS_PENDING je Wait jmp Next Wait: invoke KeWaitForSingleObject,addr p_event,Executive,KernelMode,0,0 Next: mov eax,0 mov eax,p_iosb.Status mov dword ptr [dbg_err+1],eax Invoke DbgPrint,offset dbg_err endproc: invoke ObDereferenceObject,addr p_fo ret OpenFile endp end DriverEntry Никак я самостоятельно не могу понять в чем же причина... Очень большая просьба подсказать где я намудрил. Честно признаюсь это моя первая попытка написать драйвер, до этого были только простенькие юзерские приложения, так что не судите строго. Я ассемблер-то начал изучать всего полгода назад...
Код (Text): NTSTATUS IoCallDriver( IN PDEVICE_OBJECT DeviceObject, IN OUT PIRP Irp ); PIRP надо передавать, так Код (Text): invoke IoCallDriver,addr p_devobj,addr irpvar
Нет, так тоже не получается. На том же месте вылетает в STOP ошибку: NO_MORE_IRP_STACK_LOCATIONS 0x00000035 (0xF7A22AB8,0x000000.....). У меня в irpvar уже указатель на заполненный irp-пакет полученный после вызова IoBuildDeviceIoControlRequest, так зачем же на него еще и addr делать?
Чет ты перемудрил Код (Text): pIrp PIRP NULL ... invoke IoBuildDeviceIoControlRequest, mov pIrp,eax .if eax == NULL mov status ,STATUS_INSUFFICIENT_RESOURCES jmp exit .endif invoke IoCallDriver,devobj, pIrp Нормально все работает...
*Со вздохом* Да вроде действительно должно работать, на msdn'е есть такой же пример только на СИ и вместо USB там подключаются к PCI. Наблюдение: У меня перед вызовом IoGetDeviceObjectPointer структура DEVICE_OBJECT имеет какие-то непонятные данные. Интересно это так и должно быть? Я думал все неинициализированные структуры заполняются нулями. Ладно, попробую составить IRP вручную.
Ни фига ничего не выходит. Но по-крайней мере я понял что проблема, скорее всего, в неправильно составленном IRP. У меня уже такая каша в голове со всеми этими IRP и прочим, я уже и не знаю что пробовать. Вот пример с msdn'а: http://support.microsoft.com/kb/256161 Делал по аналогии. Может все-таки кто-нибудь подскажет, где я ошибся? Буду просто сверхпризнателен
Все, разобрался. Проблема была в том, что IoGetDeviceObjectPointer некорректно заполнял структуру DEVICE_OBJECT. Сделал через ZwOpenFile-ObReferenceObjectByHandle-IoGetRelatedObject и все заработало. У меня остался последний вопрос: Как мне послать физическому устройству (например USB-хабу) IOCTL_INTERNAL запрос? Получается надо послать запрос драйверу шины (usbd), а вот как это реализовать?