阅读:1978回复:15
IRP的处理问题
书上有说:
在完成例程中有两行模板语句 if (Irp->PendingReturned) IoMarkIrpPending(Irp); .... 请问: 1)该IRP会完成吗? 2)我怎样才知道这个IRP什么时候完成? :o |
|
最新喜欢:![]() |
沙发#
发布于:2002-05-07 16:14
用户被禁言,该主题自动屏蔽! |
|
板凳#
发布于:2002-05-08 08:14
书上有说: 你可以给irp设置一个完成历程,当完成时候,该历程被调用 |
|
|
地板#
发布于:2002-05-08 08:22
我意思是:
譬如,我为一个READ的IRP,在READ DISPATCH中设置了完成例程,在完成例程中按书上的做法 if (Irp->PendingReturned) IoMarkIrpPending(Irp); 如果在完成例程中经过了这两句后,该IRP被挂起了,然而以后还有没有完成的机会?如果有我应该怎样做去捕捉它的完成?当它完成的时候还会调用我现在给它设置的完成例程吗? 一般来说我是不应该在完成例程中调用IoCompleteRequest来完成由系统来的IRP(即不是我的驱动自身创建的IRP)吧? ----------------------------------------------------------- 谢谢你们的回答,我的问题很多,希望高手能细心为小弟解答 |
|
地下室#
发布于:2002-05-08 09:32
我意思是: IoCompleteRequest实际上没什么神秘的,就是告诉I/OM你的()里的那个IRP处理完了[不管是传入的,还是你生成的!当然前提是在这之前系统必须已经传入一个IRP,这个时候你的生成的IRP只是忽略了原来的重新生成一个而已!],也就是说当你呼叫IoCompleteRequest函数的时候()里面的IRP马上就会送上去!相反你可以保留若干个具有某些用途的IRP到你想送上去的时候送上去!明白我说什么没有?这个函数其实就是告诉I/O你完成了对()里面的IRP的处理,并告诉他可以送上去了! |
|
|
5楼#
发布于:2002-05-08 10:04
两次完成IRP不出现问题?
|
|
6楼#
发布于:2002-05-08 11:36
两次完成IRP不出现问题? 这不是废话么?同一个IRP完成两次当然出问题啦~~两个就不会有问题啊!IRP队列!!明白没?有个IOINCREMENT函数知道吧??还有个DE的!PACKET里面有!里面有个COUNT,自己去看看~~我好久没看PACKET了!那个COUNT就是IRP的数量!当然你也不能凭空生成个IRP就拿来完成! |
|
|
7楼#
发布于:2002-05-08 13:38
请大虾别生气,我先说说我的情况:
1)系统向一个COM口发读操作,我写的是一个过滤,把它attach到COM的设备栈上。 2)我在READ DISPATCH里设置了完成例程然后向下发 3)READ IRP完成了,正常地进入我的完成例程,但是它的PendingReturned标志被设置了(下层驱动调用过IoMarkIrpPending),然而我也学书上的那两句模板语句, 调用了IoMarkIrpPending,也就是说明IRP已经挂起了。 -------------------------------------------------------- 1)如果我要知道该IRP什么时候完成,我怎么去做? 2)如果要自己调用IoCompleteRequest,我要应该在哪里处理?在完成例程外面调用IoCompleteRequest还是紧跟IoMarkIrpPending后调用?我根本就不需要对该Irp进行任何多余的处理。但是如果我去调它后,上层应用程序会因死等待而挂起。 --------------------------------------------------------- 小弟实在比较麻烦和天资愚顿,请大侠耐心教导,谢谢~~ |
|
8楼#
发布于:2002-05-08 13:44
如果你需要马上完成,不用给IRP pending,直接IoCompleteIRP就可以。如果你需要下传可以使用IoStartPacket然后在StartIo例程中完成它。
|
|
9楼#
发布于:2002-05-08 13:51
如果我不完成它有没有问题?
因为我现在的处理就是不理它,我怕以后会有问题。 -------------------------------------------------------
谢谢你的回答,你的回答很直接,谢谢。 |
|
10楼#
发布于:2002-05-08 14:49
书上有说: 如果你的完成例程被调用了,这说明此IRP已被完成了(由最低层driver)。一般设置完成例程是因为你传递给了下层驱动,若你自己来处理此IRP,那完全用不着什么完成例程。 |
|
|
11楼#
发布于:2002-05-08 14:50
书上有说: 如果你的完成例程被调用了,这说明此IRP已被完成了(由最低层driver)。一般设置完成例程是因为你传递给了下层驱动,若你自己来处理此IRP(你是最低层driver),那完全用不着什么完成例程。 |
|
|
12楼#
发布于:2002-05-08 15:29
如果你的完成例程被调用了,这说明此IRP已被完成了(由最低层driver)。一般设置完成例程是因为你传递给了下层驱动,若你自己来处理此IRP(你是最低层driver),那完全用不着什么完成例程。 我不是说了我的是过滤驱动吗?我要向下传的,我读READ的IRP返回的确数据肯定需要设置完成例成程. |
|
13楼#
发布于:2002-05-08 16:00
书上有说: 首先:将IRP标记为挂起,为的是不让IO管理器不把这个IRP从内存中删除,如果调用IoCompleteRequest,则IO管理器会马上把IRP从内存中删除。 完成例程调用的时机是目标IRP被更低层的驱动程序处理完毕后调用的,这一点毫无疑问。但处理的结果却不一定是STATUS_SUCCESS。拿硬盘存储过程来说,可能一块数据需要传输好几次才能传输完,在这种情况下将IRP标记为挂起是很容易理解的。 在过滤驱动程序中,如果处理的IRP是自己创建的而不是拦截到的,则一般要将IRP标记为挂起,因为自己创建的IRP要自己来管理,IO管理器不负责删除它。如果不标记为挂起而调用IoCompleteRequest,则IO管理器会试图删除这个IRP,却又不能在自己的数据段中找到这个IRP而会导致页故障。 综上所述:将IRP标记为PENDING,存在于两种情况下,一种是批量传输时,要将大块数据分成小块数据传输,直到最后一块数据传输完成才完成此IRP,否则一定要将此IRP标记为挂起。 第二种情况是自己创建的IRP,一定要标记为挂起。原因是自己创建的IRP要自己负责删除,而不能依赖于IO管理器。 |
|
|
14楼#
发布于:2002-05-08 16:19
请大虾别生气,我先说说我的情况: 其实挂起一个IRP就是告诉系统,你现在在等待它的处理,这个IRP并没有完成!这个时候系统会为你保留资源是肯定的,因为在你没有iocomplete或cancel一个IRP的时候,系统是不会自做主张的!你可以在任何你认为你完成IRP操作的时候完成这个IRP或你想取消的时候取消它!MARKIRP的后面不是要设置个CANCLE的ROUTINE么?这个东西就是取消IRP用的[当然你也可以自己立即取消这个IRP,I/OM有提供函数的啊!这个函数名你一定知道啦!]。如果你不想操作这个传入的IRP的话马上完成他!不用想其他的!然后要取消的话马上就取消!下面就收不到了!只要记住你的驱动和真正的COM口驱动是串联的!明白了? |
|
|
15楼#
发布于:2002-05-17 16:39
哦,是这样的。
噢,谢谢各位,我的眼睛都看累了。 |
|
|