阅读:1561回复:13
IoCancelIrpk可否在完成历程中调用?斑竹,shentu大哥进来看看啊
我做了一个usb转虚拟串口的驱动,现在准备提供异步读写方式,因为同步的话,会导致应用在readfile的时候占用cpu时间太多。
现在应用中使用readfile()来进行读取,由于他没有指定readfile中要读的数据的长度(总是指定为1024),所以在我的驱动中要构造 很多的irp发送下去,然后返回应用status_pending.有的就完成不了,因为设备中没有数据, 现在我想要取消这些irp,应该在那里取消呢?如果在完成历程中,那末我调用Iocancelirp的时候,就又会进入完成历程。 大家给我一个解决方案吧。 |
|
沙发#
发布于:2004-12-01 21:58
在完成例程里面调用IoCancelIrp没有关系的,放心调用就可以了。
|
|
板凳#
发布于:2004-12-02 12:12
我是在自己分配的irp的完成历程里取消自己分配的多余的irp。
我尝试了一下,在cancel的时候,有pagefault,错误是0000000A,driver_irql_not_less_or_equal, 再问一个问题阿,是不是一定要完成历程返回了才能说irp被彻底完成了?比如说完成历程返回了status_more_process_required,才能说明此irp被完成呢? 谢谢阿。 |
|
地板#
发布于:2004-12-02 16:58
我猜想,也许你需要调用的是IoFreeIrp
|
|
地下室#
发布于:2004-12-02 17:11
我是在自己分配的irp的完成历程里取消自己分配的多余的irp。 driver_irql_not_less_or_equal的提示的参数是什么? |
|
|
5楼#
发布于:2004-12-02 19:44
0000000a(00000386,2,0,23Ad45f9 ),感觉取消逻辑太复杂了,allenzh帮我讲一下好吗?
主irp和辅助irp的取消到底是如何进行的呢? 应该在辅助irp的完成历程中取消主irp吗? 主irp是自己主动取消(调用iocancelirp)还是由下层取消? 取消历程是系统调用的,是不是只有在调用iocancelirp的时候取消历程才能被调用呢? 提前谢谢。 |
|
6楼#
发布于:2004-12-02 19:51
IofreeIrp()好像不行把,如果只是把irp free掉了,可是并没有完成他们阿,那样的话,是不是这些irp会一直在等待?下层驱动可能在满足条件的时候完成他们的话,就会出现操作空内存了,不知道是不是这样?
下层驱动都会开辟自己的内存区来保存上层传下来的irp堆栈吗?? 感谢您。:)。 |
|
7楼#
发布于:2004-12-02 22:41
我是在自己分配的irp的完成历程里取消自己分配的多余的irp。 在完成例程里面你就可以把这个当前的IRP给free(通过调用IoFreeIrp())。 |
|
8楼#
发布于:2004-12-03 09:10
我对楼主的方法是这样理解的:
应用层通过readfile来读取usb设备中的数据,但是因为数据对齐和长度的关系,需要多个(自己分配的)irp才能完成(为什么???),现在楼主因为某种原因要取消这些自己分配的irp(又是为什么????) 我的解决办法是不要取消irp,在处理主irp时,直接返回pending, 然后在与之相关的所有辅irp都完成后(即最后一个辅助irp都完成后),再IoCompleteRequest主irp,并IoFreeIrp所有的辅irp,当然每个辅irp完成后都要将读取到的数据复制到主irp的缓冲区中。 说白了,楼主就是要将一个读的irp分成多个读的irp。 不知道我的理解是否有误???? :D |
|
9楼#
发布于:2004-12-03 10:00
说说我的看法,IoCancelIrp好象通常都是系统调用的吧,用户线程结束irp没有完成时,系统调用IoCancelIrp,然后调用程序中提供的取消例程,或者用户显示调用win32 CancelIo引起你的取消例程被调用。
所以我感觉没有必要自己调用IocancelIrp吧。为什么不在一定条件下应用程序调用CancelIo这样驱动程序写好取消例程就行了 |
|
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可以吗? |
|
11楼#
发布于:2004-12-03 17:30
对那些还在排队的 IRPs 直接用 STATUS_CANCELLED 完成就可以了。只有对那个正在 Pending 的 IRP 要用 IoCancelIrp()。
|
|
12楼#
发布于:2004-12-05 13:55
Shentu说得对,我前一段时间也遇到相似的情况。我在DISPATHC LEVEL层读USB数据,只有数据读到,该IRP才返回,没有读到,此IRP一直在等待。因此,在卸载时,总有一个IRP才等待。因此,我只有在REMOVE例程中取消才解决问题。
BTW,我用什么工具才能检查驱动是否还有问题。象应用层程序有检查内存泄漏的工具,好象BOUNDCHECKER,但没用过,不知有大侠是否用它? |
|
|
13楼#
发布于:2004-12-06 12:04
0000000a(00000386,2,0,23Ad45f9 ),感觉取消逻辑太复杂了,allenzh帮我讲一下好吗? 说明你在对地址23Ad45f9读访问失败,你当前IRQL是2,而系统需要小于2的,你可能是将地址23Ad45f9释放了导致的。 |
|
|