ioBuildPartialMdl 函数 (wdm.h)
IoBuildPartialMdl 例程生成新的内存描述符列表 (MDL) ,该列表表示现有 MDL 描述的缓冲区的一部分。
语法
void IoBuildPartialMdl(
[in] PMDL SourceMdl,
[in, out] PMDL TargetMdl,
[in] PVOID VirtualAddress,
[in] ULONG Length
);
参数
[in] SourceMdl
指向描述原始缓冲区的 MDL 的指针,其中要映射子范围。
[in, out] TargetMdl
指向调用方分配的 MDL 的指针。 此 MDL 必须足够大,才能描述 VirtualAddress 和 Length 指定的子区域中的页面。
[in] VirtualAddress
指向 TargetMdl 描述的子范围的基本虚拟地址的指针。
[in] Length
指定要由 TargetMdl 映射的长度(以字节为单位)。 此值与 VirtualAddress 结合使用,必须指定一个缓冲区,该缓冲区是 SourceMdl 描述的缓冲区的正确子范围。 如果 Length 为零,则要映射的子范围从 VirtualAddress 开始,并包含 SourceMdl 描述的剩余范围。
返回值
无
备注
此例程生成一个目标 MDL,该 MDL 描述源 MDL 描述的缓冲区子范围。 此子范围由 VirtualAddress 和 Length 参数指定。 SourceMdl 和 TargetMdl 参数指向源 MDL 和目标 MDL。
驱动程序可以使用 IoBuildPartialMdl 将大型传输请求拆分为较小的传输请求。 源 MDL 描述的物理页面必须在驱动程序调用 IoBuildPartialMdl 之前锁定。 通常,源 MDL 描述用户地址空间中的缓冲区,驱动程序调用 MmProbeAndLockPages 例程来锁定此缓冲区中的页。 但是,驱动程序可以通过调用 MmBuildMdlForNonPagedPool、 MmAllocatePagesForMdlEx 或 MmAllocatePagesForMdl 例程从非分页内存生成源 MDL 。
创建部分 MDL 时:
- 如果原始 MDL 已在系统空间中映射,则部分 MDL 共享该映射,并且无需再次映射它。
- 如果原始 MDL 未在系统空间中映射,则部分 MDL 也不映射。 如果需要系统模式地址,请对部分 MDL 调用 MmGetSystemAddressForMdlSafe 。
- 如果不知道上述哪一项适用,无论怎样,调用 MmGetSystemAddressForMdlSafe 是安全的。 如果从已映射到系统地址空间的源 MDL 生成部分 MDL, 则 MmGetSystemAddressForMdlSafe 使用现有的源映射。 否则, MmGetSystemAddressForMdlSafe 将创建新的映射。
若要防止泄露此新映射,驱动程序必须在重用部分 MDL 之前调用 MmPrepareMdlForReuse 。 此外,如果存在此类映射, IoFreeMdl 例程会释放部分 MDL 的系统地址空间映射。
有关 MDL 的详细信息,请参阅使用 MDL。
要求
最低受支持的客户端 | 从 Windows 2000 开始可用。 |
目标平台 | 通用 |
标头 | wdm.h(包括 Wdm.h、Ntddk.h、Ntifs.h) |
Library | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | <=DISPATCH_LEVEL |
DDI 符合性规则 | MdlAfterReqCompletedIntIoctlA (kmdf) 、 MdlAfterReqCompletedIoctlA (kmdf) 、 MdlAfterReqCompletedReadA (kmdf) 、 MdlAfterReqCompletedWriteA (kmdf) |