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 必须足够大,才能描述 VirtualAddressLength 指定的子区域中的页面。

[in] VirtualAddress

指向 要由 TargetMdl 描述的子范围基虚拟地址的指针。

[in] Length

指定要由 TargetMdl 映射的长度(以字节为单位)。 此值与 VirtualAddress 结合使用,必须指定一个缓冲区,该缓冲区是 SourceMdl 描述的缓冲区的适当子范围。 如果 Length 为零,则要映射的子范围从 VirtualAddress 开始,并包括 SourceMdl 描述的剩余范围。

返回值

备注

此例程生成一个目标 MDL,用于描述源 MDL 描述的缓冲区的子范围。 此子范围由 VirtualAddressLength 参数指定。 SourceMdlTargetMdl 参数指向源 MDL 和目标 MDL。

驱动程序可以使用 IoBuildPartialMdl 将大型传输请求拆分为较小的传输请求。 在驱动程序调用 IoBuildPartialMdl 之前,必须锁定源 MDL 描述的物理页。 通常,源 MDL 描述用户地址空间中的缓冲区,驱动程序调用 MmProbeAndLockPages 例程来锁定此缓冲区中的页面。 但是,驱动程序可以通过调用 MmBuildMdlForNonPagedPoolMmAllocatePagesForMdlEx 或 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)

另请参阅

IoFreeMdl

MmAllocatePagesForMdl

MmAllocatePagesForMdlEx

MmBuildMdlForNonPagedPool

MmGetSystemAddressForMdlSafe

MmPrepareMdlForReuse

MmProbeAndLockPages