阅读:2211回复:15
在IoCompletionRoutine里需要调用IoCompleteIrp吗?
标准过滤驱动程序里,我想建立一个IoCompletionRoutine来改变返回的数据,
但是在写框架的时候, NTSTATUS completeirp(IN PDEVICE_OBJECT DeviceObject,IN PIRP irp,IN PVOID Context){ if(irp->PendingReturned){ IoMarkIrpPending(irp); //IoCompleteIrp(irp); return STATUS_PENDING; } //IoCompleteIrp(irp); return STATUS_SUCCESS; } 不知道这里的IoCompleteIrp是否需要,看了ddk很长时间也是云里雾里的,好像很多样例驱动里都没有,但是好像ddk又说如果下层不IoCompleteIrp,更上层的IoCompletionRoutine得不到调用??晕啊 还有一个问题是本来已经是IoCompletionRoutine了,为什么还会接受到PendingReturned的irp??一个irp被完成了,状态还是pending?那么什么时候就不pending了?那个时候IoCompletionRoutine还会得到调用吗? 谢谢大家,我真是菜鸟,ddk越看越晕,唉~~ |
|
最新喜欢:hunter...
|
沙发#
发布于:2005-07-18 12:32
实际上就是在IoCompleteIrp内部调用IoCompletionRoutine的,所以你在IoCompletionRoutine里就不要调用IoCompleteIrp了,不然乱套了
|
|
板凳#
发布于:2005-07-18 13:24
嗯,谢谢zhaock斑竹。
还有一个问题是本来已经是IoCompletionRoutine了,为什么还会接受到PendingReturned的irp??一个irp被完成了,状态还是pending?那么什么时候就不pending了?那个时候IoCompletionRoutine还会得到调用吗? 谢谢…… |
|
|
地板#
发布于:2005-07-18 18:04
终于想起密码了 ~
/quote* 还有一个问题是本来已经是IoCompletionRoutine了,为什么还会接受到PendingReturned的irp??// 不单单是 PendingReturned的irp 只要下层某驱动调用了IoCompleteIrp,就会在你设置的IoCompletionRoutine中收到 /quote* 一个irp被完成了,状态还是pending?那么什么时候就不pending了?那个时候IoCompletionRoutine还会得到调用吗?// pending 只意味着 告诉上面 可能需要一段时间才complete。。这样上面IOCALLDRIVER就不用傻等了 /quote* 那个时候IoCompletionRoutine还会得到调用吗?// 会, IoCompletionRoutine在IoCompleteIrp上下文中调用 与pend不pending无关。。 chenx-python |
|
地下室#
发布于:2005-07-18 22:37
chenx-python老兄,你就是救命稻草,呵呵~~
|
|
|
5楼#
发布于:2005-07-18 23:10
但是我觉得“告诉上面 可能需要一段时间才complete。。这样上面IOCALLDRIVER就不用傻等了”可以通过直接return status_pending 但是不调用IoCompleteIrp呀,因为irp并未完成,应该等中断发生,真正完成的时候再调用IoCompleteIrp
|
|
|
驱动老牛
|
6楼#
发布于:2005-07-19 09:35
完成历程应该是这样
NTSTATUS CompletionRoutine(PDEVICE_OBJECT device, PIRP Irp, PVOID context) { if (Irp->PendingReturned) IoMarkIrpPending(Irp); ... return STATUS_MORE_PROCESSING_REQUIRED; } 而且也不能调用IoCompleteIrp 因为这个必须再设置完成历程之后调用,否则完成历程是不会被调用的。 |
|
7楼#
发布于:2005-07-19 09:45
回答的不准确。这个问题说起来话长,试着解释一下。可以参看一下walter oney的windows driver model一书,有更为详细的解释
>>已经是IoCompletionRoutine了,为什么还会接受到PendingReturned的irp >>一个irp被完成了,状态还是pending?那么什么时候就不pending了? 先解释一下PendingReturned的含义,这个PendingReturned是IoCompleteRequest循环处理每个 stack的时候附的值,Irp->PendingReturned = stackPointer->Control & SL_PENDING_RETURNED; stackPointer->Control & SL_PENDING_RETURNED又是什么时候被附的值呢? 就是当你调用IoMarkIrpPending(Irp)的时候附的值。 if(irp->PendingReturned){ IoMarkIrpPending(irp); IoMarkIrpPending是个宏,如下 #define IoMarkIrpPending( Irp ) ( \ IoGetCurrentIrpStackLocation( (Irp) )->Control |= SL_PENDING_RETURNED ) 可见PendingReturned含义是曾经调用过IoMarkIrpPending,并不是现在仍是pending状态,现在已经是完成的irp了。 至于这 if(irp->PendingReturned) IoMarkIrpPending(irp); 两条语句的含义,最好看walter oney,实在非三言两语可以说明白 |
|
8楼#
发布于:2005-07-19 11:54
to baiyuanfan
倒了。。我说的就是通过直接return status_pending 不让上面傻等 跟IoCompleteIrp 无关 to zhao版,我只是简单说下pending。 并不是PendingReturned 。 你上面说的对 if(irp->PendingReturned) IoMarkIrpPending(irp); 存在的目的就是: 如果下层返回pending,让最高级栈IRP SL_PENDING_RETURNED = 1 . IoCompleteIrp会根据这个标志决定是否排个APC做些清理工作 对于6楼的 你return STATUS_MORE_PROCESSING_REQUIRED 后 这时候IRP所有权你自己的了 除非这个IRP是你自己建立的 否则 你应该在另个例层中继续调用IoCompleteIrp完成IRP |
|
9楼#
发布于:2005-07-19 13:05
对于楼主的情况,你可以在完成例程,停掉irp的complete处理
即 yourComplete(...) { // 创建一个event,通过PVOID Context传递 KeSetEvent(...); return STATUS_MORE_PROCESSING_REQUIRED; } 你在IoCallDriver前,创建event,调用IoCallDriver后,如果返回pending则等待event 修改数据完了,你再完成这个irp 常用的做法 |
|
10楼#
发布于:2005-07-19 13:44
下面是引用arthurtu于2005-07-19 13:05发表的: arthurtu老大说的在很多ddk自己带的过滤驱动里都是这样子实现的,但是小弟有个疑问,就是这样会阻塞掉自己的驱动的dispatch的返回,使异步的io失去意义了。为什么不直接在自己驱动的dispatch里立刻返回,在完成例程本身里修改数据呢? 谢谢各位! |
|
|
11楼#
发布于:2005-07-21 09:48
下面是引用baiyuanfan于2005-07-19 13:44发表的: just because sometimes u need synch process. and sometimes completion_routine runs at <= dispatch_level |
|
|
12楼#
发布于:2005-07-21 10:44
下面是引用rayyang2000于2005-07-21 09:48发表的: 好久不见rayyang2000版主了,你的网站打不开了。http://www.ybwork.com/ |
|
|
13楼#
发布于:2005-07-21 11:28
就是, completion_routine 可能在passive,也可能在dispatch
|
|
14楼#
发布于:2005-07-23 21:18
upup
|
|
|
15楼#
发布于:2005-07-23 21:22
那我就用普通的异步方式,直接在完成例程例修改数据也可以吧,让dispatch立刻返回
|
|
|