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 描述的缓冲区的子范围。 此子范围由 VirtualAddress 和 Length 参数指定。 SourceMdl 和 TargetMdl 参数指向源 MDL 和目标 MDL。
驱动程序可以使用 IoBuildPartialMdl 将大型传输请求拆分为较小的传输请求。 在驱动程序调用 IoBuildPartialMdl 之前,必须锁定源 MDL 描述的物理页。 通常,源 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) |