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 描述源 MDL 描述的缓冲区子范围。 此子范围由 VirtualAddressLength 参数指定。 SourceMdlTargetMdl 参数指向源 MDL 和目标 MDL。

驱动程序可以使用 IoBuildPartialMdl 将大型传输请求拆分为较小的传输请求。 源 MDL 描述的物理页面必须在驱动程序调用 IoBuildPartialMdl 之前锁定。 通常,源 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