acidfish
驱动小牛
驱动小牛
  • 注册日期2002-05-20
  • 最后登录2009-11-11
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望3点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
阅读:1845回复:9

关于取消例程和完成例程的一点认识,大牛们请斧正

楼主#
更多 发布于:2004-04-24 12:13
最近开发的时候得到了一点认识,不知道正确与否,请大牛们判断一下:
当我一个功能驱动程序收到一个上层发下来的Irp的时候,如果IoSetCancelRoutine和IoSetCompletionRoutine都进行了设置,win32 app采用异步调用,当win32 app调用CancelIo对发送的Irp进行取消处理的时候,CancelRoutine和CompletionRoutine会有不同情况的调用,具体情况是:

IoSetCancelRoutine...;
IoSetCompletionRoutine..;
...
IoMarkIrpPending...;
IoCallDriver...;//将该Irp发送到下层驱动
return STATUS_PENDING;

此处若调用IoCallDriver,则当win32app call CancelIo的时候,OS会调用Completion Routine而不会调用Cancel Routine;
若没有调用IoCallDriver的话(即没有将该Irp发送到下层驱动),则OS会调用Cancel Routine,而不会调用Completion Routine

最新喜欢:

hbnhbnhbnhbnhbn...
wenzihe
驱动牛犊
驱动牛犊
  • 注册日期2003-12-02
  • 最后登录2005-10-08
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-04-25 00:16
终于找到相关话题了
CancelIo能结束进入死循环的Io吗?
如何操作?
谢谢
顶住 一个业余大菜鸟
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
板凳#
发布于:2004-04-26 09:53
VOID
  IoSetCompletionRoutine(
    IN PIRP  Irp,
    IN PIO_COMPLETION_ROUTINE  CompletionRoutine,
    IN PVOID  Context,
    IN BOOLEAN    InvokeOnSuccess,
    IN BOOLEAN  InvokeOnError,
    IN BOOLEAN  InvokeOnCancel
    );
所以可以在任何Success,
    Error,
    Cancel的时候调用完成例程
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
punk
驱动小牛
驱动小牛
  • 注册日期2001-04-07
  • 最后登录2018-06-01
  • 粉丝0
  • 关注0
  • 积分621分
  • 威望164点
  • 贡献值0点
  • 好评度60点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-07-09 16:21
既然还有lower device就不应该设置cancel route
不停学习
acidfish
驱动小牛
驱动小牛
  • 注册日期2002-05-20
  • 最后登录2009-11-11
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望3点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-07-09 16:43
哦。谢谢老兄提醒。
还真没考虑这种情况。
现在回想起来,老兄说得还真是,碰到的一些SetCancelroutine的例子都是不往下发送Irp的情况。
Shentu
驱动小牛
驱动小牛
  • 注册日期2004-04-05
  • 最后登录2011-01-24
  • 粉丝0
  • 关注0
  • 积分234分
  • 威望24点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-07-12 18:33
自己程序里创建的新的 IRPs 是可以设置取消例程的,而且一般都是要设置的,否则怎么取消呢?
对了,acidfish大哥,还要谢谢你给我的usb-to-serial的宝贵意见!现在基本上没有什么问题了。谢谢你!!
punk
驱动小牛
驱动小牛
  • 注册日期2001-04-07
  • 最后登录2018-06-01
  • 粉丝0
  • 关注0
  • 积分621分
  • 威望164点
  • 贡献值0点
  • 好评度60点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-07-13 14:50
自己程序里创建的新的 IRPs 是可以设置取消例程的,而且一般都是要设置的,否则怎么取消呢?
对了,acidfish大哥,还要谢谢你给我的usb-to-serial的宝贵意见!现在基本上没有什么问题了。谢谢你!!

要是上层取消了irp,那lower device岂不是要非法访问了?
创建irp的程序可以设置完成例程啊?
调用IoCancelIrp通知下层device取消啊。
不停学习
acidfish
驱动小牛
驱动小牛
  • 注册日期2002-05-20
  • 最后登录2009-11-11
  • 粉丝0
  • 关注0
  • 积分21分
  • 威望3点
  • 贡献值0点
  • 好评度2点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-07-13 14:56
[quote]自己程序里创建的新的 IRPs 是可以设置取消例程的,而且一般都是要设置的,否则怎么取消呢?
对了,acidfish大哥,还要谢谢你给我的usb-to-serial的宝贵意见!现在基本上没有什么问题了。谢谢你!!

要是上层取消了irp,那lower device岂不是要非法访问了?
创建irp的程序可以设置完成例程啊?
调用IoCancelIrp通知下层device取消啊。 [/quote]

如果Irp是本层驱动发起的,那么调用IoCancelIrp通知下层取消irp的话,系统不会再调用本层设置的cancel routine,而是调用这个irp的complete routine。
这一点我是专门做过测试的。
punk
驱动小牛
驱动小牛
  • 注册日期2001-04-07
  • 最后登录2018-06-01
  • 粉丝0
  • 关注0
  • 积分621分
  • 威望164点
  • 贡献值0点
  • 好评度60点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-07-13 15:05
[quote][quote]自己程序里创建的新的 IRPs 是可以设置取消例程的,而且一般都是要设置的,否则怎么取消呢?
对了,acidfish大哥,还要谢谢你给我的usb-to-serial的宝贵意见!现在基本上没有什么问题了。谢谢你!!

要是上层取消了irp,那lower device岂不是要非法访问了?
创建irp的程序可以设置完成例程啊?
调用IoCancelIrp通知下层device取消啊。 [/quote]

如果Irp是本层驱动发起的,那么调用IoCancelIrp通知下层取消irp的话,系统不会再调用本层设置的cancel routine,而是调用这个irp的complete routine。
这一点我是专门做过测试的。 [/quote]
完成历程每个irpstack有一个,cancel route只有irp才有,总共有一个,下层设置了它,上层当然相应不了,再说,下层要是不设置它,说明它不可被cancel,既然不可被cancel,调用iocancelirp很可能出现非法访问错误。比如上层在它设置的cancel历程里调用了iocomplete,下层可能还在对它进行操作呢!
不停学习
Shentu
驱动小牛
驱动小牛
  • 注册日期2004-04-05
  • 最后登录2011-01-24
  • 粉丝0
  • 关注0
  • 积分234分
  • 威望24点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-07-13 17:30
下层驱动在处理来自上层的IRP的时候,一般都要看一下IRP的Cancel位是否被设置,以及CancelRoutine是否已被调用,然后才决定怎么动作。一般这样就可以防止访问空的问题。
调用IoCancelIrp()可以取消由本层驱动管理的IRPs,而且对这样的IRP设置Cancel例程的话,下层的驱动是可以用新的来覆盖这个Cancel例程,但是也无所谓的,不会有坏的影响。

[编辑 -  7/13/04 by  Shentu]
游客

返回顶部