#pragma code_seg("PAGE")
NTSTATUS MyWdmRead(PDEVICE_OBJECT DeviceObject,PIRP Irp)
{
KdPrint(("enter MyWdmRead"));
PMY_DEVICE_EXTENSION pDevExt =(PMY_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
IoMarkIrpPending(Irp);
IoSetCancelRoutine(Irp,OnCancelIrpRead);
KIRQL oldirql;
KeRaiseIrql(DISPATCH_LEVEL,&oldirql
if(! KeInsertDeviceQueue(&pDevExt->ReadIrpQueue,&Irp->Tail.Overlay.DeviceQueueEntry));
{
MyStartIoRead(DeviceObject,Irp);// 会将队列中所有的IRP都处理掉
}
KeLowerIrql(oldirql);
KdPrint(("leave MyWdmRead "));
return STATUS_PENDING;
}
[/code]
- C/C++ code
#pragma code_seg() VOID MyStartIoRead(IN PDEVICE_OBJECT DeviceObject,IN PIRP pStartIoIrp) { KdPrint(("Enter MyStartIoRead")); PMY_DEVICE_EXTENSION pDevExt=(PMY_DEVICE_EXTENSION)DeviceObject->DeviceExtension; PKDEVICE_QUEUE_ENTRY Device_Entry; PIRP pIrp=pStartIoIrp; do { NTSTATUS Status=STATUS_SUCCESS; PIO_STACK_LOCATION stack=IoGetCurrentIrpStackLocation(Irp); ULONG ulReadLength =stack->Parameters.Read.Length; Irp->IoStatus.Status=Status; Irp->IoStatus.Information=ulReadLength; memset(Irp->AssociatedIrp.SystemBuffer,0xAA,ulReadLength); IoCompleteRequest(Irp,IO_NO_INCREMENT); //完成这个IRP //以下代码用来得到下一次循环中要处理的IRP Device_Entry=KeRemoveDeviceQueue(&pDevExt->ReadIrpQueue);//从队列中移除一个IRP //得到IRP中的List_ENTRY if(Device_Entry==NULL) //如果队列已经为空 { break; //退出 do while 循换 } pIrp=CONTAINING_RECORD(Device_Entry,IRP,Tail.Overlay.DeviceQueueEntry); //通过LIST_ENTRY得到Irp 这个Irp是下次循环中要处理的 } while (1); KdPrint(("leave My startIoRead function")); }
想要给上面这个自定义 IRP队列、自定义StartIo例程 写 Cancel例程
还在startIo 队列中等待执行的的Irp 还可以理解 从等待队列中摘除即可
如果是正在startIo例程中执行的IRP 比如已经在上面的do 循环里执行了一半了
这时取消 该是什么样的?
比如如果在Cancel例程里 返回status_cancelled 用 IoCompleteRequest结束了这个IRP
那DO循环里的代码才执行了一半 继续执行下去会怎样
该怎么处理Cancek例程 要取消的IRP 是当前正执行IRP的情况?
------解决方案--------------------
1 If IRP currently being processed in StartIo or interrupt handler
then just quit without completing IRP. The IRP Cancel flag will
be detected in due course and the IRP completed (as cancelled) then.
2 If IRP still in StartIo queue then remove it and complete it as cancelled.