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 必须描述锁定的物理页面。 锁定的 MDL 可由 MmProbeAndLockPagesMmAllocatePagesForMdlEx 例程生成。 对于到用户空间的映射,可以使用 由 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 映射的物理页面。

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

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

  • 如果无法映射指定的页面,则例程将引发异常。 指定 UserMode 的 调用方必须将对 MmMapLockedPagesSpecifyCache 的调用包装在 try/except 块中。 有关详细信息,请参阅 处理异常

  • 例程返回在运行驱动程序的进程上下文中有效的用户地址。 例如,如果 64 位驱动程序在 32 位应用程序的上下文中运行,则缓冲区将映射到应用程序 32 位地址范围内的地址。

  • 当 AccessMode 为 UserMode 时,始终创建非可执行映射。 因此,在这种情况下,不需要将 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 运行。

要求

要求
目标平台 通用
标头 wdm.h(包括 Wdm.h、Ntddk.h、Ntifs.h)
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL 请参见“备注”部分。
DDI 符合性规则 HwStorPortProhibitedDDI (storport)

另请参阅

MmAllocatePagesForMdl

MmAllocatePagesForMdlEx

MmBuildMdlForNonPagedPool

MmGetSystemAddressForMdlSafe

MmProbeAndLockPages

MmUnmapLockedPages