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之一。
[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 进行其他调用,以提交保留范围内的单个页面。 这样一个进程就可以保留其虚拟地址空间的范围,而无需消耗物理存储,直到需要它。
进程的虚拟地址空间中的每个页面都处于下表中所述的三种状态之一。
州 | 意义 |
---|---|
自由 | 该页面未提交或保留,并且无法访问该过程。 NtAllocateVirtualMemory 可以保留或同时保留和提交免费页面。 |
保留 | 其他分配函数不能使用地址范围,但进程无法访问该页面,并且没有与之关联的物理存储。 NtAllocateVirtualMemory 可以提交保留页,但它不能再次保留它。 NtFreeVirtualMemory 可以释放保留页,使其成为免费页面。 |
承诺 | 为页面分配物理存储,访问由保护代码控制。 系统仅在首次尝试读取或写入该页时,才会将每个提交的页面初始化并加载到物理内存中。 进程终止时,系统会释放已提交的页面的存储。 NtAllocateVirtualMemory 可以提交已提交的页面。 这意味着你可以提交一系列页面,无论它们是否已提交,并且函数不会失败。 NtFreeVirtualMemory 可以取消提交页面、释放页面的存储,也可以同时取消提交和释放提交的页面。 |
通过调用 NtAllocateVirtualMemory 分配的内存必须通过调用 NtFreeVirtualMemory来释放。
有关内存管理的详细信息,请参阅适用于 Windows 驱动程序 内存管理。
注意 如果对 NtAllocateVirtualMemory 函数的调用在用户模式下发生,则应使用名称“NtAllocateVirtualMemory”而不是“ZwAllocateVirtualMemory”。
对于内核模式驱动程序的调用,NtXxx 和 ZwXxx 版本的 Windows 本机系统服务例程的行为方式可能以不同的方式处理和解释输入参数。 有关 NtXxx 与 ZwXxx 例程之间的关系的详细信息,请参阅 使用 Nt 和 Zw 版本的本机系统服务例程。
要求
要求 | 价值 |
---|---|
最低支持的客户端 | Windows 2000 |
目标平台 | 普遍 |
标头 | ntifs.h (include Ntifs.h) |
库 | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | PASSIVE_LEVEL |
DDI 符合性规则 | HwStorPortProhibitedDDIs、PowerIrpDDis、SpNoWait、StorPortStartIo |