ldd
ldd
驱动牛犊
驱动牛犊
  • 注册日期2001-08-18
  • 最后登录2003-11-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1750回复:1

再问Huyg斑竹,为什么这两个地址有时不相同?

楼主#
更多 发布于:2001-08-27 13:06
我先用IoAllocateMemory成功地申请了一块非分页内存,VA指向这块内存
然后调用:pMdl=IoAllocateMdl(VA,BufferSize,FALSE,FALSE,NULL);
这样pMdl就描述了这块内存。
接下来我调用NdisQueryBuffer(pMdl,&PktBuffer,&uiBufSize);
用DbgPrint将VA和PktBuffer的值打印出来,结果发现这两个值有时相同,
而有时却相差非常大(内容也不一样!)。
请看我的DbgPrint的输出:
(不同)
00000001 0.00001676 HeaderBufferSize is 14 bytes
00000002 0.00003241 VA is 0x81747268
00000003 0.00004498 Pk is 0x8ac43268
(相同)
00001134 41.15231768 HeaderBufferSize is 14 bytes
00001135 41.15233444 VA is 0x8670a6c8
00001136 41.15234646 Pk is 0x8670a6c8

我看了NdisQueryBuffer的定义:
#define NdisQueryBuffer(_Buffer, _VirtualAddress, _Length) \
{ \
if (ARGUMENT_PRESENT(_VirtualAddress)) \
{ \
*(PVOID *)(_VirtualAddress) = MmGetSystemAddressForMdl(_Buffer); \
} \
*(_Length) = MmGetMdlByteCount(_Buffer); \
}
MmGetSystemAddressForMdl是:
#define MmGetSystemAddressForMdl(MDL)                                  \
     (((MDL)->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA |                    \
                        MDL_SOURCE_IS_NONPAGED_POOL)) ?                \
                             ((MDL)->MappedSystemVa) :                 \
                             (MmMapLockedPages((MDL),KernelMode)))
其中:
typedef struct _MDL {
    struct _MDL *Next;
    CSHORT Size;
    CSHORT MdlFlags;
    struct _EPROCESS *Process;
    PVOID MappedSystemVa;
    PVOID StartVa;
    ULONG ByteCount;
    ULONG ByteOffset;
} MDL, *PMDL;
#define MDL_MAPPED_TO_SYSTEM_VA     0x0001
#define MDL_SOURCE_IS_NONPAGED_POOL 0x0004
所以MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL = 0x0005

MSDN中说在Windows NT 4.0 SP3以后(我用的是Windows 2000),MmMapLockedPages
返回实际的虚拟地址(页边界地址+偏移量)。我又参看了一下Art Baker的书和Mason的书,
知道了第一次调用MmGetSystemAddressForMdl时,MmMapLockPages会将返回的这个虚拟
地址存放在MDL的MappedSystemVa域中,而第二次调用MmGetSystemAddressForMdl时,
就可以直接返回(MDL)->MappedSystemVa了,这可能是用(MDL)->MdlFlags来调节的吧?!
(比如说MdlFlags初始为0,被MmMapLockedPages函数修改为1)。
所以我感觉不管(MDL)->MdlFlags是多少,返回的总是实际的虚拟地址,而不是页边界地址。
所以我想不通为什么我的VA有时候却不等于NdisQueryBuffer返回的虚拟地址。

[ldd 编辑于 2001-08-27 13:09]
ldd
ldd
驱动牛犊
驱动牛犊
  • 注册日期2001-08-18
  • 最后登录2003-11-03
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2001-08-27 13:55
Huyg版主,真是惭愧,问了个这么傻的问题。

我又想了一下,一个物理地址是可以对应着多个虚拟地址的!
至于内容嘛,我得出两个不相同的结论是因为我少调用了一个函数,
我刚把这个函数及后面的异常处理加了进去,经过反复地测试后发现:

有些情况下,两个地址是相同的,而有些情况下,两个地址是
不同的,但不管这两个地址是否相同,他们的内容是相同的!!!
即两个不相同的虚拟地址对应着一个实际的物理地址。

没有经过思考,问了个这么傻的问题,faint!
游客

返回顶部