专注收集记录技术开发学习笔记、技术难点、解决方案
网站信息搜索 >> 请输入关键词:
您当前的位置: 首页 > 驱动开发

取消当前 IRP 执行的过程是怎样的?解决办法

发布时间:2010-06-14 17:45:59 文章来源:www.iduyao.cn 采编人员:星星草
取消当前 IRP 执行的过程是怎样的?
#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.
友情提示:
信息收集于互联网,如果您发现错误或造成侵权,请及时通知本站更正或删除,具体联系方式见页面底部联系我们,谢谢。

其他相似内容:

热门推荐: