MDL的本质就是记录一段虚拟地址所对应着的一系列的物理地址。
MDL数据结构的结尾是一组PFN,记录着物理地址,相关宏是MmGetMdlPfnArray。
初始化:一般用用IoAllocateMdl初始化,但是这个步骤并没有建立起虚拟地址和物理地址的联系。IoAllocateMdl会调用MmInitializeMdl用于初始化MDL,填充MDL的header。
校验MDL对应的虚拟地址可读写:MmProbeAndLockPages
建立与PFN的联系:MmBuildMdlForNonPagedPool,IoBuildPartialMdl,MmProbeAndLockPages
建立新的虚拟地址映射:MmMapLockedPages,MmMapLockedPagesSpecifyCache,MmGetSystemAddressForMdl,MmGetSystemAddressForMdlSafe
非分页:MDL_SOURCE_IS_NONPAGED_POOL
在驱动中使用MDL的四种可能:
1. 在驱动中如果使用METHOD_NEITHER方法,传进来的buffer就是user app的buffer。如果需要在任意进程上下文中使用这个buffer,需要创建MDL,并且判断MDL对应的内存是否可以操作,最后把它重新map到kernel mode memory。WRK中的ExLockUserBuffer是个很好的例子。其实METHOD_IN_DIRECT方式也是这个原理,只不过是OS帮你去做这些事情了。
2. 在A驱动中发起向B驱动的请求。最好的例子是磁盘类驱动ClassSendSrbSynchronous。首先创建IR