阅读:1517回复:6
50分请教 filter中的irp mdl问题
我在做一个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 这是什么原因呢? |
|
最新喜欢:aasa2
|
沙发#
发布于:2004-11-02 16:46
莫非三个irp共用一个mdl。但数据分别在mdl中的不同offset中?那么这个offset怎么取得呢?
还有,一个mdl所能承载的数据量,有限的吗? 是不是64KB? |
|
|
板凳#
发布于: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 |
|
|
地板#
发布于:2004-11-02 21:17
证实了的确是三个irp共用一个mdl的。
因为mdl->bytecount为 64KB。正好是三个irp的transize的总和。 但怎样知道每个irp在mdl中的偏移呢?( 实际监控时,三个irp执行时,其irp->mdladdress->byteoffset均为零. 而参数 pio_stack_location->parameters.scsi.srb中又再没有其它参数, 有谁做过这方面的开发呢? |
|
|
地下室#
发布于:2004-11-02 23:56
还有什么问题吗?
|
|
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)) |
|
|
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???? |
|
|