xiaorain
驱动牛犊
驱动牛犊
  • 注册日期2003-04-21
  • 最后登录2005-11-05
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1561回复:13

IoCancelIrpk可否在完成历程中调用?斑竹,shentu大哥进来看看啊

楼主#
更多 发布于:2004-12-01 11:50
我做了一个usb转虚拟串口的驱动,现在准备提供异步读写方式,因为同步的话,会导致应用在readfile的时候占用cpu时间太多。
现在应用中使用readfile()来进行读取,由于他没有指定readfile中要读的数据的长度(总是指定为1024),所以在我的驱动中要构造
很多的irp发送下去,然后返回应用status_pending.有的就完成不了,因为设备中没有数据,
现在我想要取消这些irp,应该在那里取消呢?如果在完成历程中,那末我调用Iocancelirp的时候,就又会进入完成历程。
大家给我一个解决方案吧。
Shentu
驱动小牛
驱动小牛
  • 注册日期2004-04-05
  • 最后登录2011-01-24
  • 粉丝0
  • 关注0
  • 积分234分
  • 威望24点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-12-01 21:58
在完成例程里面调用IoCancelIrp没有关系的,放心调用就可以了。
xiaorain
驱动牛犊
驱动牛犊
  • 注册日期2003-04-21
  • 最后登录2005-11-05
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-12-02 12:12
我是在自己分配的irp的完成历程里取消自己分配的多余的irp。
我尝试了一下,在cancel的时候,有pagefault,错误是0000000A,driver_irql_not_less_or_equal,
再问一个问题阿,是不是一定要完成历程返回了才能说irp被彻底完成了?比如说完成历程返回了status_more_process_required,才能说明此irp被完成呢?
谢谢阿。
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-12-02 16:58
我猜想,也许你需要调用的是IoFreeIrp
AllenZh
驱动老牛
驱动老牛
  • 注册日期2001-08-19
  • 最后登录2015-11-27
  • 粉丝19
  • 关注10
  • 积分1316分
  • 威望2387点
  • 贡献值7点
  • 好评度321点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-12-02 17:11
我是在自己分配的irp的完成历程里取消自己分配的多余的irp。
我尝试了一下,在cancel的时候,有pagefault,错误是0000000A,driver_irql_not_less_or_equal,
再问一个问题阿,是不是一定要完成历程返回了才能说irp被彻底完成了?比如说完成历程返回了status_more_process_required,才能说明此irp被完成呢?
谢谢阿。

driver_irql_not_less_or_equal的提示的参数是什么?
1,承接Windows下驱动/应用开发 2,本人原创虚拟鼠标/键盘,触摸屏,虚拟显卡,Mirror驱动,XP无盘的SCSI虚拟磁盘驱动等 3,windows下有尝技术服务(包括BUG调试,员工培训等) 欢迎深圳和海外企业联系.msn:mfczmh@sina.com
xiaorain
驱动牛犊
驱动牛犊
  • 注册日期2003-04-21
  • 最后登录2005-11-05
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-12-02 19:44
0000000a(00000386,2,0,23Ad45f9 ),感觉取消逻辑太复杂了,allenzh帮我讲一下好吗?
主irp和辅助irp的取消到底是如何进行的呢?
应该在辅助irp的完成历程中取消主irp吗?
主irp是自己主动取消(调用iocancelirp)还是由下层取消?
取消历程是系统调用的,是不是只有在调用iocancelirp的时候取消历程才能被调用呢?
提前谢谢。
xiaorain
驱动牛犊
驱动牛犊
  • 注册日期2003-04-21
  • 最后登录2005-11-05
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-12-02 19:51
IofreeIrp()好像不行把,如果只是把irp free掉了,可是并没有完成他们阿,那样的话,是不是这些irp会一直在等待?下层驱动可能在满足条件的时候完成他们的话,就会出现操作空内存了,不知道是不是这样?
下层驱动都会开辟自己的内存区来保存上层传下来的irp堆栈吗??
感谢您。:)。

Shentu
驱动小牛
驱动小牛
  • 注册日期2004-04-05
  • 最后登录2011-01-24
  • 粉丝0
  • 关注0
  • 积分234分
  • 威望24点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-12-02 22:41
我是在自己分配的irp的完成历程里取消自己分配的多余的irp。
我尝试了一下,在cancel的时候,有pagefault,错误是0000000A,driver_irql_not_less_or_equal,
再问一个问题阿,是不是一定要完成历程返回了才能说irp被彻底完成了?比如说完成历程返回了status_more_process_required,才能说明此irp被完成呢?
谢谢阿。


在完成例程里面你就可以把这个当前的IRP给free(通过调用IoFreeIrp())。
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-12-03 09:10
我对楼主的方法是这样理解的:
应用层通过readfile来读取usb设备中的数据,但是因为数据对齐和长度的关系,需要多个(自己分配的)irp才能完成(为什么???),现在楼主因为某种原因要取消这些自己分配的irp(又是为什么????)

我的解决办法是不要取消irp,在处理主irp时,直接返回pending,
然后在与之相关的所有辅irp都完成后(即最后一个辅助irp都完成后),再IoCompleteRequest主irp,并IoFreeIrp所有的辅irp,当然每个辅irp完成后都要将读取到的数据复制到主irp的缓冲区中。


说白了,楼主就是要将一个读的irp分成多个读的irp。

不知道我的理解是否有误???? :D
sean198148
驱动牛犊
驱动牛犊
  • 注册日期2003-01-22
  • 最后登录2014-10-08
  • 粉丝0
  • 关注0
  • 积分44分
  • 威望26点
  • 贡献值0点
  • 好评度3点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-12-03 10:00
说说我的看法,IoCancelIrp好象通常都是系统调用的吧,用户线程结束irp没有完成时,系统调用IoCancelIrp,然后调用程序中提供的取消例程,或者用户显示调用win32 CancelIo引起你的取消例程被调用。
所以我感觉没有必要自己调用IocancelIrp吧。为什么不在一定条件下应用程序调用CancelIo这样驱动程序写好取消例程就行了
xiaorain
驱动牛犊
驱动牛犊
  • 注册日期2003-04-21
  • 最后登录2005-11-05
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
10楼#
发布于:2004-12-03 10:19
感谢大家。:)
tooflat你说的对,因为是usb设备,所以一个读irp下来,readfile()制定了长度,我要将这些长度分成64的长度,组成带urb的irp,然后发给下层驱动,但是因为readfile中的长度时胡乱制定的,比如说一直是1024,但是设备没有那末多的数据,于是我要在读完了设备中的数据以后将数据返回,可是返回的花,就要把我自己组成的那些irp给cancel掉,才能够结束读irp,然后数据就给了应用了。

shentu大哥,我在完成历程中是把当前d的irp free掉了(知道可以free了:)),现在的问题是我要把剩下的那些irp给cancel掉.只是简单的IOfreeirp来释放掉剩下的irp可以吗?

Shentu
驱动小牛
驱动小牛
  • 注册日期2004-04-05
  • 最后登录2011-01-24
  • 粉丝0
  • 关注0
  • 积分234分
  • 威望24点
  • 贡献值0点
  • 好评度20点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2004-12-03 17:30
 对那些还在排队的 IRPs 直接用  STATUS_CANCELLED 完成就可以了。只有对那个正在 Pending 的 IRP 要用 IoCancelIrp()。
lejianz
驱动中牛
驱动中牛
  • 注册日期2003-03-05
  • 最后登录2023-11-15
  • 粉丝0
  • 关注0
  • 积分8分
  • 威望145点
  • 贡献值0点
  • 好评度116点
  • 原创分0分
  • 专家分0分
  • 社区居民
12楼#
发布于:2004-12-05 13:55
Shentu说得对,我前一段时间也遇到相似的情况。我在DISPATHC LEVEL层读USB数据,只有数据读到,该IRP才返回,没有读到,此IRP一直在等待。因此,在卸载时,总有一个IRP才等待。因此,我只有在REMOVE例程中取消才解决问题。

BTW,我用什么工具才能检查驱动是否还有问题。象应用层程序有检查内存泄漏的工具,好象BOUNDCHECKER,但没用过,不知有大侠是否用它?
一起交流,共同提高!
AllenZh
驱动老牛
驱动老牛
  • 注册日期2001-08-19
  • 最后登录2015-11-27
  • 粉丝19
  • 关注10
  • 积分1316分
  • 威望2387点
  • 贡献值7点
  • 好评度321点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2004-12-06 12:04
0000000a(00000386,2,0,23Ad45f9 ),感觉取消逻辑太复杂了,allenzh帮我讲一下好吗?
主irp和辅助irp的取消到底是如何进行的呢?
应该在辅助irp的完成历程中取消主irp吗?
主irp是自己主动取消(调用iocancelirp)还是由下层取消?
取消历程是系统调用的,是不是只有在调用iocancelirp的时候取消历程才能被调用呢?
提前谢谢。
 

说明你在对地址23Ad45f9读访问失败,你当前IRQL是2,而系统需要小于2的,你可能是将地址23Ad45f9释放了导致的。
1,承接Windows下驱动/应用开发 2,本人原创虚拟鼠标/键盘,触摸屏,虚拟显卡,Mirror驱动,XP无盘的SCSI虚拟磁盘驱动等 3,windows下有尝技术服务(包括BUG调试,员工培训等) 欢迎深圳和海外企业联系.msn:mfczmh@sina.com
游客

返回顶部