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

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

[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 启用写入组合,即将缓存中的写入合并到硬件支持main内存。 此标志主要用于帧缓冲区内存,以便在写入设备之前,尽可能合并对同一缓存行的写入。 这可以大大减少跨总线写入到 (,例如) 视频内存。 如果硬件不支持写入组合,则会忽略标志。 此标志是页面保护修饰符,仅当与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 Native System Services 例程的 NtXxxZwXxx 版本在处理和解释输入参数的方式上的行为可能有所不同。 有关例程的 NtXxxZwXxx 版本之间的关系的详细信息,请参阅 使用本机系统服务例程的 Nt 和 Zw 版本

要求

   
最低受支持的客户端 Windows 2000
目标平台 通用
标头 ntifs.h (包括 Ntifs.h)
Library NtosKrnl.lib
DLL NtosKrnl.exe
IRQL PASSIVE_LEVEL
DDI 符合性规则 HwStorPortProhibitedDDI、PowerIrpDDis、SpNoWait、StorPortStartIo

另请参阅

NtFreeVirtualMemory