aasa2
驱动中牛
驱动中牛
  • 注册日期2004-04-01
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分525分
  • 威望339点
  • 贡献值0点
  • 好评度106点
  • 原创分0分
  • 专家分0分
阅读:1122回复:5

竟然有这样的现象

楼主#
更多 发布于:2005-02-21 21:12
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]
技术交流:aasa2@21cn.com QQ群:10863699
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2005-02-21 22:20
不是说了在完成例程里不要碰IRP.因为下层PDO已经调用IOCOMPLTERREQUEST了,可能IRP已经被释放了.....
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-02-22 09:19
不是说了在完成例程里不要碰IRP.因为下层PDO已经调用IOCOMPLTERREQUEST了,可能IRP已经被释放了.....


在完成例程里当然可以碰irp,因为完成例程就是ioCompleteRequest在内部调用的,只有在所有的完成例程全部调完以后,irp才会被释放
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
地板#
发布于: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]
zhangshengyu
驱动老牛
驱动老牛
  • 注册日期2003-10-03
  • 最后登录2016-07-26
  • 粉丝0
  • 关注0
  • 积分792分
  • 威望696点
  • 贡献值41点
  • 好评度499点
  • 原创分0分
  • 专家分0分
  • 社区居民
地下室#
发布于:2005-02-22 09:26
需要
IoCopyCurrentIrpStackLocationToNext( Irp );
---内核开发合作或提供基础技术服务QQ:22863668 ---
bmyyyud
驱动老牛
驱动老牛
  • 注册日期2002-02-22
  • 最后登录2010-01-21
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望130点
  • 贡献值0点
  • 好评度106点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2005-02-22 10:02
问题不在完成例程,而在别处,如有些地方,你调用类似IoSkipCurrentIrpStackLocation的函数,使IrpStack堆栈层数不够,这样便出现你的那种情况。
滚滚长江东逝水 浪花淘尽英雄 是非成败转头空 青山依旧在 几度夕阳红 白发渔樵江渚上 惯看秋月春风 一壶浊酒喜相逢 古今多少事 尽付笑谈中
游客

返回顶部