NtAllocateVirtualMemory 函数 (ntifs.h)

NtAllocateVirtualMemory 例程保留、提交或同时保留指定进程的用户模式虚拟地址空间中的页面区域。

语法

__kernel_entry NTSYSCALLAPI NTSTATUS NtAllocateVirtualMemory(
  [in]      HANDLE    ProcessHandle,
  [in, out] PVOID     *BaseAddress,
  [in]      ULONG_PTR ZeroBits,
  [in, out] PSIZE_T   RegionSize,
  [in]      ULONG     AllocationType,
  [in]      ULONG     Protect
);

参数

[in] ProcessHandle

应执行映射的进程的句柄。 使用 NtCurrentProcess 宏(在 Ntddk.h 中定义)指定当前进程。

[in, out] BaseAddress

指向将接收已分配页区域基地址的变量的指针。 如果 BaseAddress 的初始值为非 NULL,则从指定的虚拟地址开始分配区域,向下舍入到下一个主机页大小地址边界。 如果 BaseAddress 的初始 值为 NULL,操作系统将确定区域分配位置。

[in] ZeroBits

在节视图的基地址中必须为零的高序地址位数。 仅在操作系统确定分配区域位置(如 BaseAddress* 为 NULL 时) 使用。 请注意,当 ZeroBits 大于 32 时,它将成为位掩码。

[in, out] RegionSize

指向变量的指针,该变量将接收已分配页区域的实际大小(以字节为单位)。 RegionSize 的初始值指定区域的大小(以字节为单位)并向上舍入到下一个主机页大小边界。 输入时 RegionSize 不能为零。

[in] AllocationType

一个位掩码,包含指定要针对指定页区域执行的分配类型的标志。 下表描述了最常见的标志。 有关可能的标志和说明的完整列表,请参阅 VirtualAlloc

备注

必须MEM_COMMIT、MEM_RESET或MEM_RESERVE之一。

标志 含义
MEM_COMMIT 要提交页的指定区域。
MEM_RESERVE 要保留的页的指定区域。
MEM_RESET 重置指定区域的状态,以便如果页面位于分页文件中,则将其丢弃,并包含零页。 如果页位于内存中并进行了修改,则它们将被标记为未修改,以便它们不会写入分页文件。 内容不 零。 使用 Protect 参数,但必须设置为有效值。 如果MEM_RESET,则不能设置其他标志。
其他 MEM_ XXX 标志 请参阅 VirtualAlloc

[in] Protect

一个位掩码,包含页保护标志,用于指定提交页面区域所需的保护。 下表描述了这些标志。

标志 含义
PAGE_NOACCESS 不允许访问已提交页面区域。 尝试读取、写入或执行已提交区域会导致访问冲突异常,称为常规保护 (GP) 错误。
PAGE_READONLY 允许对已提交页面区域进行只读和执行访问。 尝试写入已提交区域会导致访问冲突。
PAGE_READWRITE 允许读取、写入和执行对已提交页面区域的访问权限。 如果允许对基础节进行写入访问,则共享页面的单个副本。 否则,在写入时共享只读/复制页。
PAGE_EXECUTE 允许对已提交页面区域执行访问权限。 尝试读取或写入已提交区域会导致访问冲突。
PAGE_EXECUTE_READ 允许对已提交页面区域执行和读取访问权限。 尝试写入已提交区域会导致访问冲突。
PAGE_GUARD 该区域中的页面将成为保护页。 任何从保护页读取或写入保护页的尝试都会导致系统引发STATUS_GUARD_PAGE异常。 因此,保护页充当一次访问警报。 此标志是一个页面保护修饰符,仅在与页面保护标志之一使用时有效,PAGE_NOACCESS。 当访问尝试导致系统关闭保护页状态时,基础页面保护将接管。 如果在系统服务期间发生保护页异常,该服务通常会返回故障状态指示器。
PAGE_NOCACHE 页面区域应分配为不可缓存。 PAGE_NOCACHE节不允许使用 。
PAGE_WRITECOMBINE 启用写入组合,即将缓存中的写入合并到主内存,硬件支持写入。 此标志主要用于帧缓冲区内存,以便尽可能合并写入同一缓存行,然后再写入设备。 这可大大减少整个总线上写入数据 (例如) 内存。 如果硬件不支持写入组合,则忽略 标志。 此标志是一个页面保护修饰符,仅在与页面保护标志之一使用时有效,PAGE_NOACCESS。

返回值

NtAllocateVirtualMemory 返回STATUS_SUCCESS错误状态代码。 可能的错误状态代码包括:

  • STATUS_ACCESS_DENIED
  • STATUS_ALREADY_COMMITTED
  • STATUS_COMMITMENT_LIMIT
  • STATUS_CONFLICTING_ADDRESSES
  • STATUS_INSUFFICIENT_RESOURCES
  • STATUS_INVALID_HANDLE
  • STATUS_INVALID_PAGE_PROTECTION
  • STATUS_NO_MEMORY
  • STATUS_OBJECT_TYPE_MISMATCH
  • STATUS_PROCESS_IS_TERMINATING

注解

NtAllocateVirtualMemory 可以执行以下操作:

  • 提交上一次调用 NtAllocateVirtualMemory 保留的页区域
  • 保留一个免费页面区域。
  • 保留并提交一个免费页面区域。

内核模式驱动程序可以使用 NtAllocateVirtualMemory 在指定的进程中保留一系列应用程序可访问的虚拟地址,然后对 NtAllocateVirtualMemory 进行其他调用,以提交保留范围中的单个页面。 这使进程能够保留其虚拟地址空间的范围,而无需使用物理存储,直到需要为止。

进程的虚拟地址空间的每一页都位于下表所述的三种状态之一。

状态 含义
FREE 页面未提交或保留,进程无法访问该页。 NtAllocateVirtualMemory 可以保留或同时保留和提交免费页。
RESERVED 其他分配函数不能使用地址范围,但进程无法访问该页,并且没有与之关联的物理存储。 NtAllocateVirtualMemory 可以提交保留页,但它不能再次预留。 NtFreeVirtualMemory 可以释放保留页面,使其成为可用页面。
提交 将为页面分配物理存储,并通过保护代码控制访问权限。 系统仅在第一次尝试读取或写入到该页面时,初始化并将每个已提交的页面加载到物理内存中。 当进程终止时,系统将为提交的页释放存储空间。 NtAllocateVirtualMemory 可以提交已提交的页面。 这意味着你可以提交一定范围的页面,而不管它们是否已被提交,并且函数不会失败。 NtFreeVirtualMemory 可以解除提交的页面,释放页面的存储,也可以同时解除和发布已提交的页面。

调用 NtAllocateVirtualMemory 分配的内存必须通过调用 NtFreeVirtualMemory 释放。

有关内存管理的详细信息,请参阅Windows 驱动程序的内存管理

注意 如果对 NtAllocateVirtualMemory 函数的调用在用户模式下出现,则应使用名称 "NtAllocateVirtualMemory" 而不是 "ZwAllocateVirtualMemory"。

对于来自内核模式驱动程序的调用,Windows 本机系统服务例程的 Nt * xxx* 和 Zw * xxx* 版本的行为方式与它们处理和解释输入参数的方式不同。 有关例程的 nt * xxx* 和 Zw * xxx* 版本之间的关系的详细信息,请参阅 使用本机系统服务例程的 nt 和 Zw 版本

要求

   
最低受支持的客户端 从 Windows 2000 开始可用。
目标平台 通用
标头 ntifs (包含 Ntifs)
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL PASSIVE_LEVEL
DDI 符合性规则 HwStorPortProhibitedDDIs, PowerIrpDDis, SpNoWait, StorPortStartIo

请参阅

NtFreeVirtualMemory