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描述的缓冲区的适当子范围。 如果 长度 为零,则要映射的子范围从 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) |
库 | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | <=DISPATCH_LEVEL |
DDI 符合性规则 | MdlAfterReqCompletedIntIoctlA(kmdf),MdlAfterReqCompletedIoctlA(kmdf),MdlAfterReqCompletedReadA(kmdf),MdlAfterReqCompletedWriteA(kmdf) |