请问下用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插入队列后并返回
}