Prev: Building a common driver binary for both XP, Vista and 7
Next: 32 bit process & 64 bit driver, 32/64 bit pointer?
From: Sushma on 11 Feb 2010 07:52 Hi All, When i intercept the MJ_INTERNAL_DEVICE_CONTROL IRP for my usb mass storage device in usbstor lower filter I get a BSOD when completing the original request. Basically when I get the request I encrypt the data buffer in filter before sending it to device. I create a new request and a URB for the request. But when I try complete the original request in completion routine I get BSOD (DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)). Here is the stack trace and source code. Can some one provide a hint where I'm going wrong. Regards, Sushma STACK_TEXT: f895c7ac 804f8df9 00000003 f895cb08 00000000 nt! RtlpBreakWithStatusInstruction f895c7f8 804f99e4 00000003 00000018 f83391cc nt!KiBugCheckDebugBreak +0x19 f895cbd8 805446e0 0000000a 00000018 00000002 nt!KeBugCheck2+0x574 f895cbd8 f83391cc 0000000a 00000018 00000002 nt!KiTrap0E+0x238 f895cc98 f8339325 82dd93d0 82af7390 f836ba8c wdf01000! FxRequestBase::CompleteSubmittedNoContext+0x18 f895ccb4 f831dc36 82b9d6fb 82af7390 00000000 wdf01000! FxRequestBase::CompleteSubmitted+0x104 f895ccd0 f831dcde 01dd93d0 82b916c8 f895ccfc wdf01000! FxIoTarget::RequestCompletionRoutine+0x12d f895cce0 804f080d 82adb2a0 82b9d640 82dd93d0 wdf01000! FxIoTarget::_RequestCompletionRoutine+0x35 f895ccfc 804f16b0 82adb2a0 82b9d640 82b916c8 nt!IopUnloadSafeCompletion +0x1d f895cd2c f8336d6b 82dd93d0 aa2102a0 00000000 nt!IopfCompleteRequest +0xa2 f895cd54 f8329757 00000000 00000000 00000000 wdf01000! FxRequest::CompleteInternal+0x379 f895cd70 aa20faea 00000000 82dd93d0 00000000 wdf01000! imp_WdfRequestComplete+0x108 WARNING: Stack unwind information not available. Following frames may be wrong. f895cd84 aa2102ea 7d226c28 00000000 825a71d8 lfilter+0xaea f895cd98 f8339217 7d2467b0 7d508c68 f895cdbc lfilter+0x12ea f895cde4 f8339325 82db9848 82af7390 f836ba8c wdf01000! FxRequestBase::CompleteSubmittedNoContext+0x63 f895ce00 f831dc36 82f71af7 82af7390 00000000 wdf01000! FxRequestBase::CompleteSubmitted+0x104 f895ce1c f831dcde 01db9848 828ae378 f895ce48 wdf01000! FxIoTarget::RequestCompletionRoutine+0x12d f895ce2c 804f080d 00000000 82f71a60 82db9848 wdf01000! FxIoTarget::_RequestCompletionRoutine+0x35 f895ce48 804f16b0 00000000 82f71a60 828ae378 nt!IopUnloadSafeCompletion +0x1d f895ce78 f7fb70d5 82f71a60 82617498 82e0e028 nt!IopfCompleteRequest +0xa2 f895cee0 f7fb7d47 82dbef00 00000000 82e0e7d8 USBPORT! USBPORT_CompleteTransfer+0x373 f895cf10 f7fb8944 026e6f44 82e0e0e0 82e0e0e0 USBPORT! USBPORT_DoneTransfer+0x137 f895cf48 f7fba13a 82e0e028 80546abc 82e0e230 USBPORT! USBPORT_FlushDoneTransferList+0x16c f895cf74 f7fc824b 82e0e028 80546abc 82e0e028 USBPORT!USBPORT_DpcWorker +0x224 f895cfb0 f7fc83c2 82e0e028 00000001 806e6427 USBPORT! USBPORT_IsrDpcWorker+0x38f f895cfcc 80545e6f 82e0e64c 6b755044 00000000 USBPORT!USBPORT_IsrDpc +0x166 f895cff4 805459db f85e433c 00000000 00000000 nt!KiRetireDpcList+0x61 f895cff8 f85e433c 00000000 00000000 00000000 nt!KiDispatchInterrupt +0x2b 805459db 00000000 00000009 0081850f bb830000 0xf85e433c VOID FilterEvtIoInternalDeviceControl( IN WDFQUEUE Queue, IN WDFREQUEST Request, IN size_t OutputBufferLength, IN size_t InputBufferLength, IN ULONG IoControlCode ) { NTSTATUS status = STATUS_SUCCESS; WDF_REQUEST_PARAMETERS_INIT(¶ms); WdfRequestGetParameters(Request, ¶ms); urb = (PURB) params.Parameters.Others.Arg1; device = WdfIoQueueGetDevice(Queue); filterExt = FilterGetData(device); switch (IoControlCode) { case IOCTL_INTERNAL_USB_SUBMIT_URB: switch(urb->UrbHeader.Function) { case URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER: if(CBW || CSW) { ret = WdfRequestSend(Request, Target, WDF_NO_SEND_OPTIONS); if (ret == FALSE) { status = WdfRequestGetStatus (Request); WdfRequestComplete(Request, status); } } if(DataBuffer) { WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = ioTarget; status = WdfRequestCreate( &attributes, ioTarget, &filterExt->NewRequest ); if (!NT_SUCCESS(status)) { goto Exit; } WDF_OBJECT_ATTRIBUTES_INIT(&attributes); attributes.ParentObject = Request; status = WdfMemoryCreate( &attributes, NonPagedPool, POOL_TAG, sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER), &urbMemory, (PVOID*) &pUrb ); if (!NT_SUCCESS(status)) { status = STATUS_INSUFFICIENT_RESOURCES; goto Exit; } filterExt->pUrb = pUrb; filterExt->RequestToComplete = Request; OldIrp = WdfRequestWdmGetIrp(Request); virtualAddress = (ULONG_PTR) MmGetSystemAddressForMdlSafe(OldIrp- >MdlAddress, NormalPagePriority); totalLength = pUrb- >UrbBulkOrInterruptTransfer.TransferBufferLength; status = FilterEncrypt(Request, filterExt->NewRequest, filterExt) if (!NT_SUCCESS(status)) { goto Exit; } filterExt->newMdl = IoAllocateMdl((PVOID) virtualAddress, totalLength, FALSE, FALSE, NULL); if (filterExt->newMdl == NULL) { status = STATUS_INSUFFICIENT_RESOURCES; goto Exit; } Irp = WdfRequestWdmGetIrp(filterExt->NewRequest); Irp->MdlAddress = filterExt->newMdl; MmBuildMdlForNonPagedPool(filterExt->newMdl); UsbBuildInterruptOrBulkTransferRequest( filterExt->pUrb, sizeof (struct _URB_BULK_OR_INTERRUPT_TRANSFER), pUrb->UrbBulkOrInterruptTransfer.PipeHandle, NULL, filterExt->newMdl, totalLength, pUrb->UrbBulkOrInterruptTransfer.TransferFlags, NULL ); NextStack = IoGetNextIrpStackLocation(WdfRequestWdmGetIrp(filterExt->NewRequest)); NextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL; NextStack->Parameters.Others.Argument1 = filterExt->pUrb; NextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB; // Setup completion proc WdfRequestSetCompletionRoutine(filterExt->NewRequest, FilterBulkOnlySendDataComplete, filterExt); if (WdfRequestSend(filterExt->NewRequest, WdfDeviceGetIoTarget(filterExt->WdfDevice), WDF_NO_SEND_OPTIONS) == FALSE) { status = WdfRequestGetStatus(filterExt->NewRequest); } } default: //do something } default: // do something } Exit: WdfRequestComplete(Request, CompletionParams->IoStatus.Status); } VOID FilterBulkOnlySendDataComplete( IN WDFREQUEST Request, IN WDFIOTARGET Target, PWDF_REQUEST_COMPLETION_PARAMS CompletionParams, IN WDFCONTEXT Context ) { PFILTER_EXTENSION filterExt; filterExt = (PFILTER_EXTENSION)Context; WdfRequestComplete(filterExt->RequestToComplete, CompletionParams- >IoStatus.Status); IoFreeMdl(filterExt->newMdl); WdfObjectDelete(filterExt->NewRequest); return; }
From: Sushma on 11 Feb 2010 21:56 I'm desperately looking out for a fix as I'm not able to proceed further. Can some one look into code or suggest an alternate way to achieve what I wanted to do. Thank You. Regards, sushma
From: Philip Ries [MSFT] on 12 Feb 2010 16:31 You might be completing an invalid request. Why don't you complete the request that is being completed to you, that is, the Request parameter of FilterBulkOnlySendDataComplete? Sushma wrote: > I'm desperately looking out for a fix as I'm not able to proceed > further. Can some one look into code or suggest an alternate way to > achieve what I wanted to do. > > Thank You. > > Regards, > sushma
From: Sushma on 14 Feb 2010 09:32 > You might be completing an invalid request. Why don't you complete the > request that is being completed to you, that is, the Request parameter > of FilterBulkOnlySendDataComplete? > I do not think I can do that as the request was created in the driver. The request parameter of FilterBulkOnlySendDataComplete is the one created in my driver. However, I tried to complete it but there was BSOD with same error. One strange thing I observed is that if I do not complete any request in my completion routine, there was no crash. When I tried move some data to device few requests were successful but after copying some data it just got stuck at completion routine and I get a reset port request. This may not be correct, I just took a chance. Is there any other way to complete the original request after the completion routine of newly created request is invoked? Thank You. Regards, Sushma
From: Sushma on 15 Feb 2010 08:19
When I had used WDM way (IoCompleteRequest instead of WdfRequestComplete) to complete the original request there was no BSOD. I think the request got corrupted by mixing WDM and WDF. The reason I had to use WDM was I need mdl pointer in the IRP. I had tried using WdfRequestRetrieveInputWdmMdl, but it failed with STATUS_INVALID_DEVICE_REQUEST. I'm not sure for the reason for failure. Thank You. Regards, Sushma |