阅读:1448回复:10
关于分层驱动程序中IoCompleteIrp的问题。
假设有分层驱动程序从上到下一次是I、II、III.
现在假设驱动程序II从I上受到一个Irp,这个Irp可能II或者III都会处理,所以,II就自己保留了一份,同时CallNext传递给了III.这时II,III都是排队处理Irp队列. 现在问题是,如果在某个条件下,II需要IoCompleteRequest掉这个Irp了,这是时候,会不会影响到III上(III上排队处理到这个Irp时会不会出问题)??如何使III知道这个Irp已经被II处理了??? --------------------- 谢谢大侠 [编辑 - 7/8/04 by lwglucky] |
|
|
沙发#
发布于:2004-07-27 18:16
IoCompleteRequest只能由一个driver来调用,否则BSOD,会出来专门的一个Bug Check Code ;) ------------ 这个答案就是我想要的,但是我想明白的是这个irp下去后,上层驱动是否可以主动调用IocanelIrp触发completion routine的cancel呢?? 否则这个cancel routine在哪里/什么时候被触发呢?? |
|
|
板凳#
发布于:2004-07-27 00:39
irp实际上有2部分组成,一步凤是头,另一部分叫做IO_STACK_LOCATION ,对于每一层驱动,都将分配一个。
irp包有上层驱动调用calldriver传到下层驱动,一次创下,当某个驱动觉得它可以处理这个irp包时,他将调用IoCompleteRequest,这样,这个irp包就完成了,下层驱动根本不会知道曾经有这么一个irp包。 值得注意的是,在某一层调用IoCompleteRequest后,他的上层驱动如果注册了完成历程,那么,他将获得机会做再次的处理,当然,完成历程只能饭后某个状态,而不能再次调用IoCompleteRequest了,否则,就有问题了 |
|
|
地板#
发布于:2004-07-09 00:13
IoCompleteRequest只能由一个driver来调用,否则BSOD,会出来专门的一个Bug Check Code ;)
如果是用system的queue,不用管。如果是用自己的queue,传下去前设completion routine的cancel,在里面把它remove掉 |
|
|
地下室#
发布于:2004-07-08 15:08
楼主对IRP传递的模型好像理解得不太对喔。
建议看一下这个帖子。 Kernel Mode discussion and Soft Driver -〉IRP 乱杂谈 |
|
5楼#
发布于:2004-07-08 13:58
我是初学者,我讲讲我的理解:
从上到下1,2,3层,从1来了个IRP,2收到后,作自己的处理,做完后用IoSkipCurrentIrpStackLocation()拷贝IRP堆栈到下层的堆栈里面,然后用IoCallDriver()把IRP传到下层也就是3的那层 不知道我理解得对吗? |
|
6楼#
发布于:2004-07-08 13:01
但是这个问题经常碰到啊,比如说II、III层都在排队一个Irp,这个时候I将Irp取消了(比如说程序关闭了),这个时候留在II,III队列中的Irp该怎么办呢?? 这些由I/O Manager来处理,我们不用管它 :D 不过到底是怎样处理的,俺也不清楚。 arthurtu:给大家点解点解? :) |
|
7楼#
发布于:2004-07-08 12:24
1、自己保留了一份是指什么?把irp的内容copy出来?还是保存这个irp的地址?
2、如果用把irp给下层了,就失去了对这个irp的控制,除非再得到这个irp的控制权(比如,完成例程),否则不要去动它; |
|
8楼#
发布于:2004-07-08 11:27
不太明白你的意思,
如果II调用了IoComplete,III不知情而继续调用IoComplete,肯定会出错。此时,应该定义个事件或callback通知III吧。 |
|
9楼#
发布于:2004-07-08 10:58
但是这个问题经常碰到啊,比如说II、III层都在排队一个Irp,这个时候I将Irp取消了(比如说程序关闭了),这个时候留在II,III队列中的Irp该怎么办呢??
|
|
|
10楼#
发布于:2004-07-08 10:15
好像不可以哦。 IoComplete不能随便调的 :P
|
|