阅读:2219回复:6
关于Walter Oney的书的疑问
小弟最近看Walter Oney的书,有以下疑问:
1。参考书第5章第2部分 IoStartPacket和IoStartNextPacket都有可能导致StartIo的调用,书中说“StartIo例程在DISPATCH_LEVEL级上获得控制,这意味着该函数不能生成任何页故障。另外,设备对象的CurrentIrp域和Irp参数都指向I/O管理器送来的IRP。” (1)我想知道设备对象的CurrentIrp域的设置,到底是我们用代码显性的在StartIo中实现,还是系统在IoStartPacket和IoStartNextPacket中背着我们偷偷设置好了? (2)如果Irp队列中的Irp被取空了,那么CurrentIrp域是不是应该被设置成NULL?如果要设置,那么是我们用代码显性设置(我不知道具体在那个函数里面做这个事情合适)还是IoStartPacket看到队列空了,它自己偷偷帮我们设置好了? 2。参考书第5章第5部分 作者在StartIo函数里面有如下判断: if (Irp != fdo->CurrentIrp || Irp->Cancel) 我觉得比较疑惑,StartIo是不是只由IoStartPacket和IoStartNextPacket来调用的? (1)如果是的话,他有必要检查Irp是不是就是fdo->CurrentIrp吗?因为我觉得IoStartPacket和IoStartNextPacket都是在设备空闲的时候才调用StartIo的,这个时候设备对象的CurrentIrp肯定就是传到StartIo里面的Irp了。就没有比较的必要了。 (2)如果不是的话,那么系统还有可能在什么时候调用StartIo? 呵呵。。。我是新手,当然问题很多,而且很蠢,大家帮忙看看吧。谢谢!当然,分数肯定不会少了大家的。不管您是否回答的很对,重在您的参与! [编辑 - 5/8/02 作者: JackyWu] |
|
最新喜欢:![]()
|
沙发#
发布于:2002-05-08 09:48
是“偷偷”设置好的吧。
|
|
板凳#
发布于:2002-05-08 12:05
关于第一个问题,无疑是偷偷的,看这句话:
当你调用IoStartPacket时,你指定了保存在IRP中的取消例程的地址。当你调用IoStartNextPacket(在你的DPC例程中)时,你为一个布尔参数指定了TRUE值,指定这个值表示你要使用标准取消机制。在IoStartPacket或IoStartNextPacket调用你的StartIo例程之前,它把设备对象中的CurrentIrp域设置为指向你要发送的IRP。如果队列中没有请求,则IoStartNextPacket把CurrentIrp域设置为NULL。 至于第二个问题: StartIo应该是只由IoStartPacket和IoStartNextPacket来调用的 至于为什么要判断,或许是为了确保安全吧 谁还有更好的解释,说来一听 |
|
|
地板#
发布于:2002-05-08 12:36
果然是高手,是我看书不仔细,呵呵。。。对于第一个问题的答复,看来是没有什么疑问了。先给分在说。第2个问题大家还有什么看法,人多力量大。请踊跃发言。
|
|
|
地下室#
发布于:2002-05-09 14:52
一:
如书上说的: 在内部,调用你的代码的系统例程象下面代码(注意:这不是真正的Windows 2000源代码): VOID IoStartPacket(PDEVICE_OBJECT device, PIRP Irp, PULONG key, PDRIVER_CANCEL cancel) { KIRQL oldirql; IoAcquireCancelSpinLock(&oldirql); IoSetCancelRoutine(Irp, cancel); device->CurrentIrp = Irp; IoReleaseCancelSpinLock(oldirql); device->DriverObject->DriverStartIo(device, Irp); } VOID IoStartNextPacket(PDEVICE_OBJECT device, BOOLEAN cancancel) { KIRQL oldirql; if (cancancel) IoAcquireCancelSpinLock(&oldirql); PKDEVICE_QUEUE_ENTRY p = KeRemoveDeviceQueue(&device->DeviceQueue)); PIRP Irp = CONTAINING_RECORD(p, IRP, Tail.Overlay.DeviceQueueEntry); device->CurrentIrp = Irp; if (cancancel) IoReleaseCancelSpinLock(oldirql); device->DriverObject->DriverStartIo(device, Irp); } 二: 看到你这样提出我想起昨天我有个朋友说他在startio里的irp地址不知为何变了,可见这个检验是有必要的.谢谢你在这里提出这个问题,我代他感谢你. |
|
5楼#
发布于:2002-05-09 15:16
谢啥,呵呵。。。我也搞不清楚为什么要变化。可能是我对驱动的流程不是很了解吧,请高手指点。谢谢!
[编辑 - 5/9/02 作者: JackyWu] |
|
|
6楼#
发布于:2007-11-29 13:34
![]() |
|