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 必须描述锁定的物理页面。 MmProbeAndLockPages 或 MmAllocatePagesForMdlEx 例程可以生成锁定的 MDL。 若要映射到用户空间,可以使用由 MmBuildMdlForNonPagedPool 例程生成的 MDL。
[in] AccessMode
指定要在其中映射 MDL:KernelMode 或 UserMode的访问模式。 几乎所有驱动程序都应使用 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 开始,指定的优先级值可以使用 MdlMappingNoWrite 或 MdlMappingNoExecute 标志来指定禁用写入或指令执行的内存。 有关 优先级可能值的详细信息,请参阅 mmGetSystemAddressForMdlSafe。
返回值
mmMapLockedPagesSpecifyCache 返回映射页的起始地址。 如果无法映射页并且 BugCheckOnFailureFALSE,则例程将返回 NULL。
言论
使用 MmUnmapLockedPages 取消映射由 MmMapLockedPagesSpecifyCache映射的物理页面。
如果 AccessModeKernelMode,并且如果 MmMapLockedPagesSpecifyCache 无法映射指定的页面, 例程返回 NULL(如果 BugCheckOnFailure = FALSE),或作系统发出 bug 检查(如果 BugCheckOnFailure = TRUE)。
如果 AccessModeUserMode,请注意以下详细信息:
如果无法映射指定的页面,则例程将引发异常。 指定 UserMode 的调用方必须在 try/except 块中包装对 MmMapLockedPagesSpecifyCache 的调用。 有关详细信息,请参阅 处理异常。
例程返回在运行驱动程序的进程上下文中有效的用户地址。 例如,如果 64 位驱动程序在 32 位应用程序的上下文中运行,则缓冲区将映射到应用程序的 32 位地址范围内的地址。
AccessModeUserMode时,始终创建非可执行映射。 因此,在此方案中不需要将 MdlMappingNoExecute 标志与 Priority 参数一起使用。 但是,在此方案中,MdlMappingNoWrite 标志仍可与 Priority 参数一起使用,以请求只读映射。
使用 MdlMappingNoWrite 标志和 Priority 参数的代码无法更改映射的非可执行保护以及使用用户模式运行的代码所指定的映射的任何写入保护。 例如,如果驱动程序将某些页面映射到用户进程并指定 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) |
库 | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | 请参阅“备注”部分。 |
DDI 符合性规则 | HwStorPortProhibitedDIS(storport) |