- The Code is taken from WDM Sample.
- Here the problem is to Cancel IRP, In case the CBW command and Direction flage is oppsite in direction, Example Write10 Command opcode and Read Direction.
The dispatch routine called and the completion routine not get called. - But if all the parameter is correct then the Dispatch routine and completion routine both get called.
- IoCancelIrp() Crash the Driver and result is blue screen.
UsbBuildInterruptOrBulkTransferRequest(
urb,
sizeof(struct _URB_BULK_OR_INTERRUPT_TRANSFER),
ptrPipeInfor->PipeHandle,
NULL,
mdl,
ulStageLength,
ulUrbFlags,
NULL);
// set USB_RW_CONTEXT parameters.
rwContext->Urb = urb;
rwContext->Mdl = mdl;
rwContext->Numxfer = 0;
rwContext->Length = ulTotalLength - ulStageLength;
rwContext->VirtualAddress = ptrVirtualAddr + ulStageLength;
rwContext->DeviceExtension = stPtrDeviceExtension;
// use the original read/write irp as an internal device control irp
nextStack = IoGetNextIrpStackLocation(Irp);
nextStack->Parameters.Others.Argument1 = (PVOID) urb;
nextStack->MajorFunction = IRP_MJ_INTERNAL_DEVICE_CONTROL;
nextStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_INTERNAL_USB_SUBMIT_URB;
IoSetCompletionRoutine(Irp,
(PIO_COMPLETION_ROUTINE) USB_ReadWriteCompletion,
rwContext,
TRUE,
TRUE,
TRUE);
// since we return STATUS_PENDING call IoMarkIrpPending.
// Step Given by MSDN.
IoMarkIrpPending(Irp);
USB_IoIncrement(stPtrDeviceExtension);
/* Prepare the Timer, For limiting wait on IRP */
CancelDpcInterval.QuadPart = -5000000 * 50;
/* Set the IRP for Cancellation Routine */
stPtrDeviceExtension->RwIrp = Irp;
/* Qeueue Time Object */
bDPCQueued = KeSetTimer( &stPtrDeviceExtension->RwIrpTimer, CancelDpcInterval, &stPtrDeviceExtension->RwIrpDpc);
ntlStatus = IoCallDriver(stPtrDeviceExtension->TopOfStackDeviceObject, Irp);
}