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;
}
Thank You.
Regards,
sushma
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
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
Igor Sharovar
I used WdfDeviceGetIoTarget(WdfDevice) to get the iotarget. I do not
think there is any problem here.
Regards,
Sushma