首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 嵌入开发 > 驱动开发 >

请教下用StartIO例程处理IRP串行列队基础有关问题,有点不太明白

2013-03-26 
请问下用StartIO例程处理IRP串行列队基础问题,有点不太明白?如何StartIO例程正在处理某个IRP过程中,这时又

请问下用StartIO例程处理IRP串行列队基础问题,有点不太明白?
     如何StartIO例程正在处理某个IRP过程中,这时又新来一个IRP进入StartIO例程
这时StartIO正忙,按教程思路应该新来的这个IPR,应该斩不处理先插入IRP列队中,
但是新来的这个IRP在经过上一步的IoStartPacket里已经设置device->CurrentIrp=Irp,
所以执行不到if (Irp!=DeviceObject->CurrentIrp||Irp->Cancel)//如果设备忙,则将IRP插入队列后并返回
这段代码中,但是按教程的说法应该是先插入到列队中去的?这不是矛盾吗?


//StartIO例程, IRP串行处理
VOID HelloDDKStartIO(IN PDEVICE_OBJECT  DeviceObject,IN PIRP  Irp ) 
{
KIRQL oldirql;//定义一个中断请求级 变量

//获取cancel自旋锁
IoAcquireCancelSpinLock(&oldirql);//获取cancel自旋锁,并保存cancel自旋锁以前的 IRQL中断请求级
if (Irp!=DeviceObject->CurrentIrp||Irp->Cancel)//如果设备忙,则将IRP插入队列后并返回
{
//如果当前有正在处理的IRP,则简单的入队列,并直接返回
//入队列的工作由系统完成,在StartIO中不用负责
IoReleaseCancelSpinLock(oldirql);//释放自旋锁
KdPrint(("Leave HelloDDKStartIO\n"));
return;//将IRP插入队列后并返回
}else
{
//由于正在处理该IRP,所以不允许调用取消例程
//因此将此IRP的取消例程设置为NULL
IoSetCancelRoutine(Irp,NULL);//将此IRP关联的 IRP取消例程 取消关联
IoReleaseCancelSpinLock(oldirql);//释放自旋锁
}

  
//处理IRP请求过程....


IoStartNextPacket(DeviceObject,TRUE);//在队列中再读取一个IRP,并进行StartIo
    
//在IoStartNextPacket内部还会设置:device->CurrentIrp=Irp
    //                       还会再次调用:HelloDDKStartIO(device , Irp)                          

}


  我画了一个图, 就是画不明白
不知那里理解错了?刚学驱动,请大侠解答下

QQ:271072330 
[解决办法]
是什么教程?代码贴的不够全。

可以试着这么去理解:
有两种情况会来调用HelloDDKStartIO这个函数。
1. 系统的IO Manager收到上层应用发下来的新Irp请求。这种情况下HelloDDKStartIO的Irp参数不是队列中的Irp,就会有(Irp!=DeviceObject->CurrentIrp)就会进入:


if (Irp!=DeviceObject->CurrentIrp
[解决办法]
Irp->Cancel)//如果设备忙,则将IRP插入队列后并返回
{
//如果当前有正在处理的IRP,则简单的入队列,并直接返回
//入队列的工作由系统完成,在StartIO中不用负责
IoReleaseCancelSpinLock(oldirql);//释放自旋锁
KdPrint(("Leave HelloDDKStartIO\n"));
return;//将IRP插入队列后并返回
}

2. 完成当前的IRP之后,HelloDDKStartIO函数再次自己调用HelloDDKStartIO。这时候的Irp参数是从Irp队列里面取出来并且设置了Irp==DeviceObject->CurrentIrp。函数就会直接处理该Irp,不用进入队列了。



热点排行