Это уже обсуждалось в теме "Помогите составить IRP\n", но немного в другом контексте: там IRP обрабатывался как IRP_MJ_DEVICE_CONTROL, а не IRP_MJ_INTERNAL_DEVICE_CONTROL , как в моем случае. В общем, я написал функцию, которая посылает IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO стандартному драйверу LPT порта, в которой я находил объект устройства по имени, потом составлял IRP с помощью IoBuildDeviceIoControlRequest... Вроде все работает, я нахожу базовый адрес. Но работает криво: если я ТРИЖДЫ запущу и остановлю свой драйвер(при этом каждый раз драйвер из DriverEntry посылает IRP стандартному драйверу LPT), то в четвертый раз функция IoGetDeviceObjectPointer выполнится неудачно, и соответсвенно мой драйвер не сможет запуститься. Еще, что интересно, если попытаться в дивайсменеджере удалить LPT порт, то появится синий экран. Еще он может появится если включить Winamp Вот функция: Код (Text): NTSTATUS GetParPortBaseAddr( ULONG PortNum, PUCHAR *pPortBase ) { NTSTATUS status = STATUS_SUCCESS; UNICODE_STRING uPP; STRING aPP; CHAR PP0[] = "\\Device\\ParallelPort0"; CHAR PP1[] = "\\Device\\ParallelPort1"; CHAR PP2[] = "\\Device\\ParallelPort2"; PFILE_OBJECT pParPortXFileObj = NULL; PDEVICE_OBJECT pParPortXDevObj = NULL; PIRP pIrp = NULL; KEVENT WaitEvent; PARALLEL_PORT_INFORMATION ParPortInfo; IO_STATUS_BLOCK IOStatus; switch( PortNum ) { case 0: RtlInitAnsiString(&aPP, PP0); break; case 1: RtlInitAnsiString(&aPP, PP1); break; case 2: RtlInitAnsiString(&aPP, PP2); break; default: return -1; } RtlAnsiStringToUnicodeString(&uPP,&aPP,TRUE); status = IoGetDeviceObjectPointer( &uPP, FILE_ALL_ACCESS, &pParPortXFileObj, &pParPortXDevObj ); RtlFreeUnicodeString(&uPP); if(status!=STATUS_SUCCESS) { DbgPrint("Cann't obtain PPort DevObj\n"); return status; } KeInitializeEvent(&WaitEvent,NotificationEvent,FALSE); pIrp = IoBuildDeviceIoControlRequest( IOCTL_INTERNAL_GET_PARALLEL_PORT_INFO, pParPortXDevObj, &ParPortInfo, sizeof(PARALLEL_PORT_INFORMATION), &ParPortInfo, sizeof(PARALLEL_PORT_INFORMATION), TRUE, &WaitEvent, &IOStatus); if(pIrp == NULL) { DbgPrint("Allocation of IRP failed\n"); ObDereferenceObject( pParPortXDevObj ); return -1; } status = IoCallDriver(pParPortXDevObj, pIrp); if(status==STATUS_PENDING) { KeWaitForSingleObject( &WaitEvent, Executive, KernelMode, FALSE, NULL ); } status = IOStatus.Status; if(status!=STATUS_SUCCESS) { DbgPrint("pIrpCreationStatus: Not Successful\n"); ObDereferenceObject( pParPortXDevObj ); return status; } DbgPrint("ParPortBase = %X\n",(ULONG)ParPortInfo.Controller); DbgPrint("ParPortSpan = %i\n",(ULONG)ParPortInfo.SpanOfController); ((PUCHAR*)pPortBase)[0] = ParPortInfo.Controller; ObDereferenceObject( pParPortXDevObj ); return status; } Кто знает в чем тут дело?
Да, с форматированием вроде бы как разобрались Теперь бы с самой темой разобраться - ваще было бы круто... Беспощадный даос Я бы и сам мог поправить...
Что-то смотрю на ObDereferenceObject и вспомнилось: IoGetDeviceObjectPointer This routine also returns a pointer to the corresponding file object. When unloading, a driver can dereference the file object as a means of indirectly dereferencing the device object. To do so, the driver calls ObDereferenceObject from its Unload routine, passing the file object pointer returned by IoGetDeviceObjectPointer. Failure to dereference the device object in a driver's Unload routine prevents the next-lower driver from being unloaded. However, drivers that close the file object before the unload process must take out an extra reference on the device object before dereferencing the file object. Otherwise, dereferencing the file object can lead to a premature deletion of the device object.
cresta!!! Спасибо! Я только что заменил везде в вызовах ObDereferenceObject pParPortXDevObj на pParPortXFileObj и теперь могу запускать/останавливать драйвер сколько угодно раз! Ща попробую удалить стандартный драйвер...
при получении другим драйвером IRP_MJ_INTERNAL_DEVICE_CONTROL как узнать кем был послан irp данного типа?