[翻译整理] M4orz3r..
Blog...Http://Hi.baidu.com/M4orz3r
转载请注明... 水平有限,翻译错误之处请留言告知...
功能:在指定进程的虚拟地址空间中保留或开辟一段区域..除非MEM_RESET被使用,否则这个函数将会初始化那段内存为0.
函数原型:
LPVOID WINAPI VirtualAllocEx( __in HANDLE hProcess, //需要在其中分配空间的进程的句柄. __in_opt LPVOID lpAddress, //想要获取的地址区域.. __in SIZE_T dwSize, //要分配的内存大小. __in DWORD flAllocationType, //内存分配的类型 __in DWORD flProtect //内存页保护. );
参数:
hProcess:
需要在其中非配空间的进程的句柄..这个句柄必须拥有PROCESS_VM_OPERATION访问权限.获取更多信息请参考Process Security And Access Rights..
lpAddress.:
指向一个你想要获取分配的地址区域..如果你要保留一段内存区域..这个函数会轮询地址,到最近的分配粒度...如果你要提交的内存已经预留.那么这个地址会在最近的页边界..为了确定这个页的大小和在本机上的内存分配粒度,可以使用GetSystemInfo..如果这个参数为NULL,那么这个函数会自己决定如何分配..
dwSize:
要分配的内存区域的大小.以byte为单位..如果这个参数为NULL,该函数会轮询dwSize到下一个页的边界.如果不为NULL,这个函数会在任意的页中分配由lpAddress 大盘dwSize所指定的byte大小的地址.这意味着一个2字节的范围可能会跨越页边界而分配为两个页..
flAllocationType :
内存分配的类型,这个参数必须包含以下其中一种.
MEM_COMMIT
0x1000
分配指定的物理内存或在磁盘上的内存分页文件.这个函数会初始化它们为0.
要保留或提交页请调用VirtualAllocEx 并设置MEM_COMMIT | MEM_RESERVE..
如果你试图提交一个未保留的页.这个函数将会失败.返回错误代码为ERROR_INVALID_ADDRESS.
尝试提交一个已提交的页不会导致函数失败.这意味着你提交页时需要首先确定每一页的当前状态.
MEM_RESERVE
0x2000
在指定进程的虚拟地址空间中保留一段在物理内存或磁盘上的内存分页文件中的内存区域.
你可以通过VirtualAllocEx附带MEM_COMMIT提交保留页.要保留和提交页请调用VirtualAllocEx并附带MEM_COMMIT |MEM_RESERVE..
其他的内存分配功能有malloc,和LocalAlloc .在内存释放以前,不能使用预留的内存..
MEM_RESET
0x80000
这个数据表明,对lpAddress和dwSize所指定的内存已不再感兴趣.这个页将不能够再读出或写入数据..无论什么时候这个内存块被使用过将不能销毁....这个值也不能再被用于其它值.. 使用这个值不能保MEM_RESET的区域包含0..如果想要指定的区域包含0..销毁内存,并重新定义它..
当你使用MEM_RESET时,VirtualAllocEx函数将会忽略fProtect的值...但无论如何,你扔必须设置fProtect的值.
如果你使用MEM_RESET并且这个区域的内存是由一个文件映射的..VirtualAllocEx返回一个错误..如果有它是一个分页文件,那么只能允许共享查看...
此参数还可以指定为以下值:
MEM_LARGE_PAGES
0x20000000
使用large page support分配内存.这个尺寸和对齐方式必须是这个最大页的最低倍数.要获取这个值,请使用GetLargePageMinimum函数..
MEM_PHYSICAL
0x400000
分配一段具有读写权限的物理内存..这个值是独一无二的..使用Address Windowing Extensions内存..
这个值必须为MEM_RESERVE不能为其他值...
MEM_TOP_DOWN
0x100000
在最高地址分配内存..
flprotect:
在分配的内存页区域中进行内存保护....如果这个页being committed 你可以指定memory protection constants中的任意一个..
保护属性指定,保护的页不能跟指定分配的页冲突..
返回值:
如果函数成功,返回值为分配页区域的基地址...如果失败返回NULL。获取更多错误信息请调用GetLastError...
附注:
每一个页都有一个关联的页状态.VirtualAllocEx函数可以执行以下操作.
提交一个保留页区域..
保留一个空闲页区域.
同时保留和提交一个空闲页.
VirtualAllocEx不能保留一个已保留的页.它可以提交一个早已提交的页.这意味着你可以提交的页面范围,不管它是否有一个早已提交的页,这个函数也不会失败..
你可以使用VirtualAllocEx来预留一个页块..并且可以创建一个额外的调用VirtualAllocEx来从预留的块中提交一个单独的页..这回使得进程保留一段区域.它并不会消耗虚拟地址空间的物理内存.直到它被需要..
如果lpAddress参数不为NULL.这个函数使用lpAddress 和dwSize 参数来计算所需分配的区域. 全部区域的页状态必须兼容指定的flAllocationType参数.否则函数失败,并且没有内存被分配.这个兼容性要求并不能阻止早已提交的页.见上面列表.
要执行动态生成的代码,要使用VirtualAllocEx来分配内存,并且VirtualAllocEx必须被授予PAGE_EXECUTE权限..
该VirtualAllocEx函数可用于保留在一个特定进程的虚拟地址空间的地址窗口扩展(AWE)的内存区域..这种内存区域,可以被映射到虚拟内存不足的应用程序中去..MEM_PHYSICAL MEM_RESERVE必须被设定. MEM_COMMIT必须不能设置.页保护必须设置为PAGE_READWRITE.
VirtualFreeEx函数可以撤销一个已提交的页.发布的页.或同时解除和释放一个提交的页.同样也可以释放一个保留的页.使他成为一个空闲的页.