阅读:1326回复:3
对传统的做法的一点疑惑
请看下列代码:
NTSTATUS ForwardAndWait(PDEVICE_OBJECT fdo, PIRP Irp) { KEVENT event; KeInitializeEvent(&event,NotificationEvent,FALSE); IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp,(PIO_COMPLETION_ROUTINE)OnRequestComplete, (PVOID)&event, TRUE, TRUE, TRUE); PPCI9054_DEVICE_EXTENSION pdx=(PPCI9054_DEVICE_EXTENSION)fdo->DeviceExtension; IoCallDriver(pdx->NextStackDevice,Irp); KeWaitForSingleObject(&event,Executive,KernelMode,false,NULL); return Irp->IoStatus.Status; } NTSTATUS OnRequestComplete(PDEVICE_OBJECT fdo,PIRP Irp,PKEVENT pev) { KeSetEvent(pev,0,FALSE); return STATUS_MORE_PROCESSING_REQUIRED; } 大家一看就知道,这是向下传递IRP的一种做法。我想讨论一下在下层驱动程序不排队IRP的情况下,以上做法中利用KEVENT event进行同步是否有其必要性? 我认为:没有必要。 我假设调用ForwardAndWait的驱动程序为“A”,下面层的驱动程序为“B”。若在“B”中不对IRP进行排队,那么在“A”中调用IoCallDriver返回的肯定不是STATUS_PENDING了。即在IoCallDriver返回之前,“B”中肯定已经调用过IoCompleteRequest了。 以上代码里面利用KEVENT event进行同步,我估计是想防止当“B”中排队IRP的时候,“A”中的IoCallDriver在下层驱动程序“B”没有IoCompleteRequest的情况下返回了。这个时候就需要KeWaitForSingleObject来保证“A”在下层驱动没有完成此IRP前必须等待。 若我们已经知道下层驱动并不会排队IRP的情况下,我认为程序本身的流程已经保证了IoCallDriver返回的时候,下层驱动程序“B”肯定已经IoCompleteRequest了,所以就没有必要再KeWaitForSingleObject了。 以上是我的一点理解,请高手指点一下。谢谢! |
|
|
沙发#
发布于:2002-06-18 08:49
厉害厉害,想的很深入。
|
|
板凳#
发布于:2002-06-18 19:17
用户被禁言,该主题自动屏蔽! |
|
地板#
发布于:2002-06-19 08:47
如果有中断服务打断B的执行的话,我是这样理解的 ,不知道对不对:
中断服务例程的优先级比B高,那么中断服务例程返回时,还是继续操作B中剩下的语句。这并不会造成B返回时,IRP还没有IoCompleteRequest的情况。只有当B将IRP排队的时候,B返回,但是IRP还没有完成。 请各位指正。 |
|
|