mmMapLockedPagesSpecifyCache 函数 (wdm.h)

MmMapLockedPagesSpecifyCache 例程将 MDL 描述的物理页映射到虚拟地址,并使调用方能够指定用于创建映射的缓存属性。

语法

PVOID MmMapLockedPagesSpecifyCache(
  [in]           PMDL                                                                          MemoryDescriptorList,
  [in]           __drv_strictType(KPROCESSOR_MODE / enum _MODE,__drv_typeConst)KPROCESSOR_MODE AccessMode,
  [in]           __drv_strictTypeMatch(__drv_typeCond)MEMORY_CACHING_TYPE                      CacheType,
  [in, optional] PVOID                                                                         RequestedAddress,
  [in]           ULONG                                                                         BugCheckOnFailure,
  [in]           ULONG                                                                         Priority
);

参数

[in] MemoryDescriptorList

指向要映射的 MDL 的指针。 此 MDL 必须描述锁定的物理页面。 可通过 MmProbeAndLockPagesMmAllocatePagesForMdlEx 例程生成锁定的 MDL。 若要映射到用户空间,可以使用 MmBuildMdlForNonPagedPool 例程生成的 MDL。

[in] AccessMode

指定要在其中映射 MDL: KernelModeUserMode 的访问模式。 几乎所有驱动程序都应使用 KernelMode

[in] CacheType

指定一个 MEMORY_CACHING_TYPE 值,该值指示用于映射 MDL 的缓存属性。 有关更多信息,请参见下面的“备注”部分。

[in, optional] RequestedAddress

如果 AccessMode = UserMode,此参数指定要将 MDL 映射到的起始用户虚拟地址,或设置为 NULL 以允许系统选择起始地址。 系统可能会向下舍入请求的地址以满足地址边界要求,因此调用方必须检查返回值。

[in] BugCheckOnFailure

指定由于系统资源不足而无法映射 MDL 时 AccessMode = KernelMode 的例程的行为。 如果 为 TRUE,系统会发出 bug 检查。 如果 为 FALSE,则例程返回 NULL。 驱动程序必须将此参数设置为 FALSE

[in] Priority

一个 MM_PAGE_PRIORITY 值,该值指示当页表条目 (PTE) 稀缺时成功的重要性。 从 Windows 8 开始,指定的优先级值可以是具有 MdlMappingNoWriteMdlMappingNoExecute 标志的按位 ORed,以指定禁用写入或指令执行的内存。 有关 Priority 的可能值的详细信息,请参阅 MmGetSystemAddressForMdlSafe

返回值

MmMapLockedPagesSpecifyCache 返回映射页的起始地址。 如果无法映射页面并且 BugCheckOnFailureFALSE,则例程返回 NULL

注解

使用 MmUnmapLockedPages 取消映射 MmMapLockedPagesSpecifyCache 映射的物理页面。

如果 AccessMode 为 KernelMode,如果 MmMapLockedPagesSpecifyCache 无法映射指定页面,则例程返回 NULL (如果 BugCheckOnFailure = FALSE) ,或者操作系统在 BugCheckOnFailure = TRUE) 时发出 bug 检查 (。

如果 AccessModeUserMode,请注意以下详细信息:

  • 如果无法映射指定的页面,则例程将引发异常。 指定 UserMode 的调用方必须在 try/except 块中包装对 MmMapLockedPagesSpecifyCache 的调用。 有关详细信息,请参阅 处理异常
  • 该例程返回在运行驱动程序的进程上下文中有效的用户地址。 例如,如果 64 位驱动程序在 32 位应用程序的上下文中运行,则缓冲区将映射到应用程序 32 位地址范围内的地址。
  • AccessModeUserMode 时,始终创建非可执行映射。 因此,在这种情况下,将 MdlMappingNoExecute 标志与 Priority 参数结合使用是不必要的。 但是, MdlMappingNoWrite 标志仍可与此方案中的 Priority 参数一起使用,以请求只读映射。
  • 映射的非可执行保护以及使用具有 Priority 参数的 MdlMappingNoWrite 标志指定的映射的任何写入保护都不能由在用户模式下运行的代码更改。 例如,如果驱动程序将某些页面映射到用户进程并指定 MdlMappingNoWrite 标志,则系统会保证进程无法修改页面。
仅当 MDL 描述的页面没有与其关联的缓存类型时,该例程才使用 CacheType 参数。 不过,几乎在所有情况下,页面都已有关联的缓存类型,并且此缓存类型已由新的映射使用。 此规则的例外是 MmAllocatePagesForMdl 分配的页面,该页面没有与其关联的特定缓存类型。 对于此类页面, CacheType 参数确定映射的缓存类型。

驱动程序不得尝试为 MDL 创建多个系统地址空间映射。 此外,由于 由 MmBuildMdlForNonPagedPool 例程生成的 MDL 已映射到系统地址空间,因此驱动程序不得尝试通过使用 MmMapLockedPagesSpecifyCache 例程 (再次将此 MDL 映射到系统地址空间,尽管允许创建用户地址空间映射) 。 如果不知道锁定的 MDL 是否已具有系统地址空间映射,驱动程序可以使用 MmGetSystemAddressForMdlSafe 宏而不是 MmMapLockedPagesSpecifyCache。 如果 MDL 已映射到系统地址空间, 则 MmGetSystemAddressForMdlSafe 将返回现有的系统地址空间映射,而不是创建新的映射。

警告 将内核内存映射到用户地址空间的驱动程序必须避免向不受信任的进程公开潜在的敏感内核数据。 未初始化的缓冲区(如从池分配的缓冲区)必须在映射之前显式填充零。 此外,从池中分配的用户模式缓冲区的大小必须是虚拟内存页大小的倍数,以防止缓冲区中的任何部分用于其他分配。 最后,缓冲区在仍映射到用户地址空间时不得释放回池。
 
如果 AccessModeUserMode,则调用方必须在 IRQL <= APC_LEVEL运行。 如果 AccessModeKernelMode,则调用方必须在 IRQL <= DISPATCH_LEVEL运行。

要求

   
最低受支持的客户端 从 Windows 2000 开始可用。
目标平台 通用
标头 wdm.h(包括 Wdm.h、Ntddk.h、Ntifs.h)
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL 请参阅“备注”部分。
DDI 符合性规则 HwStorPortProhibitedDDI (storport)

另请参阅

MmAllocatePagesForMdl

MmAllocatePagesForMdlEx

MmBuildMdlForNonPagedPool

MmGetSystemAddressForMdlSafe

MmProbeAndLockPages

MmUnmapLockedPages