jame.z
驱动牛犊
驱动牛犊
  • 注册日期2001-08-07
  • 最后登录2004-05-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1978回复:15

IRP的处理问题

楼主#
更多 发布于:2002-05-07 15:40
书上有说:
    在完成例程中有两行模板语句
    if (Irp->PendingReturned)
        IoMarkIrpPending(Irp);
    ....
请问:
1)该IRP会完成吗?
2)我怎样才知道这个IRP什么时候完成? :o

最新喜欢:

flyfoxflyfox
Tom.Cat
禁止发言
禁止发言
  • 注册日期2001-10-10
  • 最后登录2019-07-29
  • 粉丝1
  • 关注0
  • 积分-53792分
  • 威望197411点
  • 贡献值0点
  • 好评度5点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2002-05-07 16:14
用户被禁言,该主题自动屏蔽!
KungFu
驱动大牛
驱动大牛
  • 注册日期2001-09-27
  • 最后登录2008-04-08
  • 粉丝0
  • 关注0
  • 积分221分
  • 威望24点
  • 贡献值0点
  • 好评度19点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2002-05-08 08:14
书上有说:
    在完成例程中有两行模板语句
    if (Irp->PendingReturned)
        IoMarkIrpPending(Irp);
    ....
请问:
1)该IRP会完成吗?
2)我怎样才知道这个IRP什么时候完成? :o

你可以给irp设置一个完成历程,当完成时候,该历程被调用
我不写驱动好多年
jame.z
驱动牛犊
驱动牛犊
  • 注册日期2001-08-07
  • 最后登录2004-05-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2002-05-08 08:22
我意思是:
    譬如,我为一个READ的IRP,在READ DISPATCH中设置了完成例程,在完成例程中按书上的做法
if (Irp->PendingReturned)
IoMarkIrpPending(Irp);
如果在完成例程中经过了这两句后,该IRP被挂起了,然而以后还有没有完成的机会?如果有我应该怎样做去捕捉它的完成?当它完成的时候还会调用我现在给它设置的完成例程吗?
一般来说我是不应该在完成例程中调用IoCompleteRequest来完成由系统来的IRP(即不是我的驱动自身创建的IRP)吧?
-----------------------------------------------------------
谢谢你们的回答,我的问题很多,希望高手能细心为小弟解答
.X.T.I.M.
驱动大牛
驱动大牛
  • 注册日期2001-09-22
  • 最后登录2021-08-25
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2002-05-08 09:32
我意思是:
    譬如,我为一个READ的IRP,在READ DISPATCH中设置了完成例程,在完成例程中按书上的做法
if (Irp->PendingReturned)
IoMarkIrpPending(Irp);
如果在完成例程中经过了这两句后,该IRP被挂起了,然而以后还有没有完成的机会?如果有我应该怎样做去捕捉它的完成?当它完成的时候还会调用我现在给它设置的完成例程吗?
一般来说我是不应该在完成例程中调用IoCompleteRequest来完成由系统来的IRP(即不是我的驱动自身创建的IRP)吧?
-----------------------------------------------------------
谢谢你们的回答,我的问题很多,希望高手能细心为小弟解答

IoCompleteRequest实际上没什么神秘的,就是告诉I/OM你的()里的那个IRP处理完了[不管是传入的,还是你生成的!当然前提是在这之前系统必须已经传入一个IRP,这个时候你的生成的IRP只是忽略了原来的重新生成一个而已!],也就是说当你呼叫IoCompleteRequest函数的时候()里面的IRP马上就会送上去!相反你可以保留若干个具有某些用途的IRP到你想送上去的时候送上去!明白我说什么没有?这个函数其实就是告诉I/O你完成了对()里面的IRP的处理,并告诉他可以送上去了!
<IMG src="http://www.microsoft.com/traincert/images/logos/mcp.gif" border=0> <IMG src="http://www.microsoft.com/traincert/images/logos/mcdba.gif" border=0><br> <IMG src="http://www.microsoft.com/traincert/images/logos/mcse.gif" border=0> <IMG src="http://www.microsoft.com/traincert/images/logos/mcsd.gif" border=0>
jame.z
驱动牛犊
驱动牛犊
  • 注册日期2001-08-07
  • 最后登录2004-05-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2002-05-08 10:04
两次完成IRP不出现问题?
.X.T.I.M.
驱动大牛
驱动大牛
  • 注册日期2001-09-22
  • 最后登录2021-08-25
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2002-05-08 11:36
两次完成IRP不出现问题?

这不是废话么?同一个IRP完成两次当然出问题啦~~两个就不会有问题啊!IRP队列!!明白没?有个IOINCREMENT函数知道吧??还有个DE的!PACKET里面有!里面有个COUNT,自己去看看~~我好久没看PACKET了!那个COUNT就是IRP的数量!当然你也不能凭空生成个IRP就拿来完成!
<IMG src="http://www.microsoft.com/traincert/images/logos/mcp.gif" border=0> <IMG src="http://www.microsoft.com/traincert/images/logos/mcdba.gif" border=0><br> <IMG src="http://www.microsoft.com/traincert/images/logos/mcse.gif" border=0> <IMG src="http://www.microsoft.com/traincert/images/logos/mcsd.gif" border=0>
jame.z
驱动牛犊
驱动牛犊
  • 注册日期2001-08-07
  • 最后登录2004-05-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
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进行任何多余的处理。但是如果我去调它后,上层应用程序会因死等待而挂起。
---------------------------------------------------------
小弟实在比较麻烦和天资愚顿,请大侠耐心教导,谢谢~~
wangqins
驱动小牛
驱动小牛
  • 注册日期2002-04-28
  • 最后登录2007-08-30
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2002-05-08 13:44
如果你需要马上完成,不用给IRP pending,直接IoCompleteIRP就可以。如果你需要下传可以使用IoStartPacket然后在StartIo例程中完成它。
jame.z
驱动牛犊
驱动牛犊
  • 注册日期2001-08-07
  • 最后登录2004-05-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2002-05-08 13:51
如果我不完成它有没有问题?
因为我现在的处理就是不理它,我怕以后会有问题。
-------------------------------------------------------

如果你需要马上完成,不用给IRP pending,直接IoCompleteIRP就可以。如果你需要下传可以使用IoStartPacket然后在StartIo例程中完成它

谢谢你的回答,你的回答很直接,谢谢。
matt
驱动中牛
驱动中牛
  • 注册日期2001-07-24
  • 最后登录2016-02-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2002-05-08 14:49
书上有说:
    在完成例程中有两行模板语句
    if (Irp->PendingReturned)
        IoMarkIrpPending(Irp);
    ....
请问:
1)该IRP会完成吗?
2)我怎样才知道这个IRP什么时候完成? :o


如果你的完成例程被调用了,这说明此IRP已被完成了(由最低层driver)。一般设置完成例程是因为你传递给了下层驱动,若你自己来处理此IRP,那完全用不着什么完成例程。
System Internals http://sys.xiloo.com
matt
驱动中牛
驱动中牛
  • 注册日期2001-07-24
  • 最后登录2016-02-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2002-05-08 14:50
书上有说:
    在完成例程中有两行模板语句
    if (Irp->PendingReturned)
        IoMarkIrpPending(Irp);
    ....
请问:
1)该IRP会完成吗?
2)我怎样才知道这个IRP什么时候完成? :o


如果你的完成例程被调用了,这说明此IRP已被完成了(由最低层driver)。一般设置完成例程是因为你传递给了下层驱动,若你自己来处理此IRP(你是最低层driver),那完全用不着什么完成例程。
System Internals http://sys.xiloo.com
jame.z
驱动牛犊
驱动牛犊
  • 注册日期2001-08-07
  • 最后登录2004-05-11
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
12楼#
发布于:2002-05-08 15:29
如果你的完成例程被调用了,这说明此IRP已被完成了(由最低层driver)。一般设置完成例程是因为你传递给了下层驱动,若你自己来处理此IRP(你是最低层driver),那完全用不着什么完成例程。

我不是说了我的是过滤驱动吗?我要向下传的,我读READ的IRP返回的确数据肯定需要设置完成例成程.
Tom_lyd
驱动大牛
驱动大牛
  • 注册日期2001-09-02
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2002-05-08 16:00
书上有说:
    在完成例程中有两行模板语句
    if (Irp->PendingReturned)
        IoMarkIrpPending(Irp);
    ....
请问:
1)该IRP会完成吗?
2)我怎样才知道这个IRP什么时候完成? :o


    首先:将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管理器。
Tom_lyd
.X.T.I.M.
驱动大牛
驱动大牛
  • 注册日期2001-09-22
  • 最后登录2021-08-25
  • 粉丝0
  • 关注0
  • 积分1分
  • 威望10点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2002-05-08 16:19
请大虾别生气,我先说说我的情况:
1)系统向一个COM口发读操作,我写的是一个过滤,把它attach到COM的设备栈上。
2)我在READ DISPATCH里设置了完成例程然后向下发
3)READ IRP完成了,正常地进入我的完成例程,但是它的PendingReturned标志被设置了(下层驱动调用过IoMarkIrpPending),然而我也学书上的那两句模板语句,
调用了IoMarkIrpPending,也就是说明IRP已经挂起了。
--------------------------------------------------------
1)如果我要知道该IRP什么时候完成,我怎么去做?
2)如果要自己调用IoCompleteRequest,我要应该在哪里处理?在完成例程外面调用IoCompleteRequest还是紧跟IoMarkIrpPending后调用?我根本就不需要对该Irp进行任何多余的处理。但是如果我去调它后,上层应用程序会因死等待而挂起。
---------------------------------------------------------
小弟实在比较麻烦和天资愚顿,请大侠耐心教导,谢谢~~


其实挂起一个IRP就是告诉系统,你现在在等待它的处理,这个IRP并没有完成!这个时候系统会为你保留资源是肯定的,因为在你没有iocomplete或cancel一个IRP的时候,系统是不会自做主张的!你可以在任何你认为你完成IRP操作的时候完成这个IRP或你想取消的时候取消它!MARKIRP的后面不是要设置个CANCLE的ROUTINE么?这个东西就是取消IRP用的[当然你也可以自己立即取消这个IRP,I/OM有提供函数的啊!这个函数名你一定知道啦!]。如果你不想操作这个传入的IRP的话马上完成他!不用想其他的!然后要取消的话马上就取消!下面就收不到了!只要记住你的驱动和真正的COM口驱动是串联的!明白了?
<IMG src="http://www.microsoft.com/traincert/images/logos/mcp.gif" border=0> <IMG src="http://www.microsoft.com/traincert/images/logos/mcdba.gif" border=0><br> <IMG src="http://www.microsoft.com/traincert/images/logos/mcse.gif" border=0> <IMG src="http://www.microsoft.com/traincert/images/logos/mcsd.gif" border=0>
sureman
驱动牛犊
驱动牛犊
  • 注册日期2001-08-22
  • 最后登录2018-05-29
  • 粉丝0
  • 关注0
  • 积分63分
  • 威望27点
  • 贡献值0点
  • 好评度4点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2002-05-17 16:39
哦,是这样的。
噢,谢谢各位,我的眼睛都看累了。
★人生没有失败,只有粉碎!★
游客

返回顶部