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描述的缓冲区的适当子范围。 如果 长度 为零,则要映射的子范围从 VirtualAddress 开始,并包括 SourceMdl描述的剩余范围。

返回值

没有

言论

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

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

另请参阅

IoFreeMdl

mmAllocatePagesForMdl

mmAllocatePagesForMdlEx

mmBuildMdlForNonPagedPool

mmGetSystemAddressForMdlSafe

mmPrepareMdlForReuse

mmProbeAndLockPages