SunMing.Cai
驱动牛犊
驱动牛犊
  • 注册日期2002-11-25
  • 最后登录2008-01-10
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
阅读:1517回复:6

50分请教 filter中的irp mdl问题

楼主#
更多 发布于:2004-11-02 16:21
我在做一个disk filter,位于disk.sys的下层。
目的是拦截disk.sys向磁盘写了的特定位置写了什么数据(需要提取数据),功能是类似软件实现的还原卡一样.
我现在将拦截得到的irp排队,然后在thread中逐个处理.但遇到一个问题.
我发现在拦截scsi_write时,经常都是连续三个irp使用同一个mdl。即后两个irp它的提供的buffer都是错误的(startlba正确),这是什么原因呢?
经常都是连续3个irp一共写入64KB数据,分别是
irp1 写入 28KB数据(startlba与mdl均正确)
irp2 写入 28KB数据(startlba正确,mdl与irp1的相同)
irp3 写入 8KB数据(startlba正确,mdl与irp1的相同)
于是后两个irp都在正确的位置写入了错误的数据.
我获取irp的方法是irp->mdl, 再将mdl转换为systemaddress
这是什么原因呢?

最新喜欢:

aasa2aasa2
梦想驱动人生 ------------------------ MSN:saleonnet@hotmail.com ICQ:175745619 OQ:14892627
SunMing.Cai
驱动牛犊
驱动牛犊
  • 注册日期2002-11-25
  • 最后登录2008-01-10
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-11-02 16:46
莫非三个irp共用一个mdl。但数据分别在mdl中的不同offset中?那么这个offset怎么取得呢?
还有,一个mdl所能承载的数据量,有限的吗? 是不是64KB?
梦想驱动人生 ------------------------ MSN:saleonnet@hotmail.com ICQ:175745619 OQ:14892627
SunMing.Cai
驱动牛犊
驱动牛犊
  • 注册日期2002-11-25
  • 最后登录2008-01-10
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2004-11-02 17:49
Buffer=(PUCHAR)MmGetSystemAddressForMdl(Mdl);
我原来用的方法,但加续三个irp得到相同的buffer,

//Buffer=(PUCHAR)MmGetSystemAddressForMdl(Mdl)+Mdl->byteOffset; //halt
//Buffer=(PUCHAR)(Mdl->MappedSystemVa)+Mdl->ByteOffset; //halt
//Buffer=(PUCHAR)((PUCHAR)((Mdl)->StartVa)+(Mdl)->ByteOffset); //halt
后来我尝试用这几个方法,但pc都会reboot
梦想驱动人生 ------------------------ MSN:saleonnet@hotmail.com ICQ:175745619 OQ:14892627
SunMing.Cai
驱动牛犊
驱动牛犊
  • 注册日期2002-11-25
  • 最后登录2008-01-10
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-11-02 21:17
证实了的确是三个irp共用一个mdl的。
因为mdl->bytecount为 64KB。正好是三个irp的transize的总和。

但怎样知道每个irp在mdl中的偏移呢?(
实际监控时,三个irp执行时,其irp->mdladdress->byteoffset均为零.

而参数 pio_stack_location->parameters.scsi.srb中又再没有其它参数, 有谁做过这方面的开发呢?
梦想驱动人生 ------------------------ MSN:saleonnet@hotmail.com ICQ:175745619 OQ:14892627
piggy
驱动牛犊
驱动牛犊
  • 注册日期2001-08-24
  • 最后登录2012-01-14
  • 粉丝0
  • 关注0
  • 积分4分
  • 威望27点
  • 贡献值0点
  • 好评度16点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2004-11-02 23:56
还有什么问题吗?
SunMing.Cai
驱动牛犊
驱动牛犊
  • 注册日期2002-11-25
  • 最后登录2008-01-10
  • 粉丝0
  • 关注0
  • 积分10分
  • 威望1点
  • 贡献值0点
  • 好评度1点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-11-03 00:06
谢谢piggy的帮助了.
总结一下,这是因为classpnp会将一个 irp 分割成多个irp向low driver发送。这时它不会多次分配mdl。

在lower driver中(我的是disk filter), 对于每个irp,可以执行如下语句:
if srb->databuffer==null offsetinmdl=0
else offsetinmdl=(ulong)((ulong)srb->databuffer-(ulong)mmgetmdlvirtualaddress(mdl))
梦想驱动人生 ------------------------ MSN:saleonnet@hotmail.com ICQ:175745619 OQ:14892627
AllenZh
驱动老牛
驱动老牛
  • 注册日期2001-08-19
  • 最后登录2015-11-27
  • 粉丝19
  • 关注10
  • 积分1316分
  • 威望2387点
  • 贡献值7点
  • 好评度321点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-11-03 09:57
在DDK中其实有:
#define MmGetMdlVirtualAddress(Mdl)                                     \
    ((PVOID) ((PCHAR) ((Mdl)->StartVa) + (Mdl)->ByteOffset))

而你说
//Buffer=(PUCHAR)((PUCHAR)((Mdl)->StartVa)+(Mdl)->ByteOffset); //halt
难道MmGetMdlVirtualAddress得到的是offset????
1,承接Windows下驱动/应用开发 2,本人原创虚拟鼠标/键盘,触摸屏,虚拟显卡,Mirror驱动,XP无盘的SCSI虚拟磁盘驱动等 3,windows下有尝技术服务(包括BUG调试,员工培训等) 欢迎深圳和海外企业联系.msn:mfczmh@sina.com
游客

返回顶部