阅读:1134回复:5
竟然有这样的现象
IoSetCompletionRoutine( Irp, SfQueryInformationCompletion, NULL, TRUE, FALSE, FALSE );
完成历程: DBGSTATIC NTSTATUS SfQueryInformationCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation( Irp ); PDEVICE_EXTENSION deviceExtension = DeviceObject->DeviceExtension; ....... } 一般情况很正常,无意中蓝屏,说page Fault。 我察看一下变量,提示Irp,DeviceObject都是0,我第一次见到。 谁能解释一下? [编辑 - 2/21/05 by aasa2] |
|
|
沙发#
发布于:2005-02-21 22:20
不是说了在完成例程里不要碰IRP.因为下层PDO已经调用IOCOMPLTERREQUEST了,可能IRP已经被释放了.....
|
|
|
板凳#
发布于:2005-02-22 09:19
不是说了在完成例程里不要碰IRP.因为下层PDO已经调用IOCOMPLTERREQUEST了,可能IRP已经被释放了..... 在完成例程里当然可以碰irp,因为完成例程就是ioCompleteRequest在内部调用的,只有在所有的完成例程全部调完以后,irp才会被释放 |
|
地板#
发布于:2005-02-22 09:22
关于楼主的问题,windows驱动编程模型中是这么说的:
完成例程使用的设备对象指针参数就是I/O堆栈单元中DeviceObject域中的指针。通常IoCallDriver设置该值。有时,在创建IRP时还同时创建一个额外的堆栈单元,以便能向完成例程传递参数而不用创建一个额外的上下文结构。如果此时创建者不去设置这个额外的DeviceObject域,那么完成例程得到的设备对象指针将为NULL。 何时调用IoMarkIrpPending 上文中陈述的规则“如果Irp->PendingReturned为TRUE,那么任何不返回STATUS_MORE_PROCESSING_REQUIRED的完成例程都应该调用IoMarkIrpPending”,这几乎完全是对的,但仍有例外。如果驱动程序分配了IRP,安装了完成例程,然后在未改变堆栈指针的情况下调用IoCallDriver,那么完成例程就不应该包含这两行代码,因为没有堆栈单元与你的驱动程序关联。(这种情况与完成例程的设备对象参数为NULL的情形类似。驱动程序通常做的是分配一个带有额外堆栈单元的IRP,在第一个单元中设置DeviceObject指针,在调用IoSetCompletionRoutine和IoCallDriver前用IoSetNextIrpStackLocation函数跳过那个额外堆栈单元。如果你这样做,那么在完成例程中调用IoMarkIrpPending将不会出现问题,并且完成例程也能得到了一个有效的设备对象) [编辑 - 2/22/05 by tooflat] |
|
驱动老牛
|
地下室#
发布于:2005-02-22 09:26
需要
IoCopyCurrentIrpStackLocationToNext( Irp ); |
|
5楼#
发布于:2005-02-22 10:02
问题不在完成例程,而在别处,如有些地方,你调用类似IoSkipCurrentIrpStackLocation的函数,使IrpStack堆栈层数不够,这样便出现你的那种情况。
|
|
|