ZwAllocateVirtualMemory 函数 (ntifs.h)

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

语法

NTSYSAPI NTSTATUS ZwAllocateVirtualMemory(
  [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

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

[in] ZeroBits

节视图基址中必须为零的高序地址位数。 此值必须小于 21,并且仅在操作系统确定分配区域的位置时使用,就像 BaseAddressNULL时一样。

[in, out] RegionSize

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

[in] AllocationType

包含指定要执行的分配类型的标志的位掩码。 下表描述了这些标志。

意义
MEM_COMMIT 要提交页面的指定区域。 必须设置MEM_COMMIT、MEM_RESET或MEM_RESERVE之一。
MEM_PHYSICAL 分配物理内存。 此标志仅用于地址窗口扩展(AWE)内存。 如果设置了MEM_PHYSICAL,则还必须设置MEM_RESERVE,不能设置其他标志,并且 保护 必须设置为PAGE_READWRITE。
MEM_RESERVE 要保留页面的指定区域。 必须设置MEM_COMMIT、MEM_RESET或MEM_RESERVE之一。
MEM_RESET 重置指定区域的状态,以便如果页面位于分页文件中,则会丢弃这些页面并引入零页。 如果页面位于内存中并进行了修改,则会将其标记为未修改,以便不会将其写出到分页文件中。 内容 为零。 不使用 Protect 参数,但必须将其设置为有效值。 必须设置MEM_COMMIT、MEM_RESET或MEM_RESERVE之一;如果设置了MEM_RESET,则无法设置其他标志。
MEM_TOP_DOWN 应根据 ZeroBits,在最高虚拟地址上创建指定的区域。

[in] Protect

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

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

返回值

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

言论

ZwAllocateVirtualMemory 可以执行以下操作:

  • 提交上一次调用 ZwAllocateVirtualMemory保留的页面区域。

  • 保留免费页面的区域。

  • 保留并提交一个免费页面区域。

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

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

意义
自由 该页面未提交或保留,并且无法访问该过程。 ZwAllocateVirtualMemory 可以保留或同时保留和提交免费页面。
保留 其他分配函数不能使用地址范围,但进程无法访问该页面,并且没有与之关联的物理存储。 ZwAllocateVirtualMemory 可以提交保留页,但它不能再次保留它。 ZwFreeVirtualMemory 可以释放保留页,使其成为免费页面。
承诺 为页面分配物理存储,访问由保护代码控制。 系统仅在首次尝试读取或写入该页时,才会将每个提交的页面初始化并加载到物理内存中。 进程终止时,系统会释放已提交的页面的存储。 ZwAllocateVirtualMemory 可以提交已提交的页面。 这意味着你可以提交一系列页面,无论它们是否已提交,并且函数不会失败。 ZwFreeVirtualMemory 可以取消提交页面、释放页面的存储,也可以同时取消提交和释放提交的页面。

通过调用 ZwAllocateVirtualMemory 分配的内存必须通过调用 ZwFreeVirtualMemory来释放。

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

注意

如果在用户模式下调用 ZwAllocateVirtualMemory 函数,则应使用名称“NtAllocateVirtualMemory”而不是“ZwAllocateVirtualMemory”。

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

要求

要求 价值
最低支持的客户端 Windows 2000
目标平台 普遍
标头 ntifs.h (include Ntifs.h)
NtosKrnl.lib
DLL NtosKrnl.exe
IRQL PASSIVE_LEVEL
DDI 符合性规则 HwStorPortProhibitedDDIs(storport)PowerIrpDDis(wdm)SpNoWait(storport)StorPortStartIo(storport)

另请参阅

使用本机系统服务例程的 Nt 和 Zw 版本

ZwFreeVirtualMemory