第一,分配进程虚拟空间:
VirtualAlloc (PVOID 开始地址,SIZE_T 大小,DWORD 类型,DWORD 保护属性)
“开始地址”可以是NULL,由系统分配进程空间;“类型”是MEM_RESERVE|MEM_PHYSICAL;“保护属性”只能是
PAGE_READWRITE。
MEM_PHYSICAL指的是区域将受物理存储器的支持。
第二,你要计算出分配的页面数目PageCount:
利用本文第二节的GetSystemInfo可以计算出来。
第三,分配物理内存页面:
AllocateUserPhysicalPages (HANDLE 进程句柄,SIZE_T 页数,ULONG_PTR 页面指针数组)
进程句柄可以用GetCurrentProcess()获得;页数是刚计算出来的页数PageCount;页面数组指针unsigned long* Array[PageCount]。
系统会将分配结果存进这个数组。
第四,将物理内存与虚拟空间进行映射:
MapUserPhysicalPages (PVOID 开始地址,SIZE_T 页数,ULONG_PTR 页面指针数组)
“开始地址”是第一步分配的空间;
这样的话,虚拟地址就可以使用了。
如果“页面指针数组”是NULL,则取消映射。
第五,释放物理页面
FreeUserPhysicalPages (HANDLE 进程句柄,SIZE_T 页数,ULONG_PTR 页面指针数组)
这个除了释放物理页面外,还会取消物理页面的映射。
第六,释放进程空间
VirtualFree (PVOID 开始地址,0,MEM_RELEASE)
C++程序:
首先,在登录用户有了Lock Pages in Memory权限以后,还需要调用Windows API激活这个权限。
BOOL VirtualMem::LoggedSetLockPagesPrivilege ( HANDLE hProcess,BOOL bEnable)
{
struct {
DWORD Count;//数组的个数
LUID_AND_ATTRIBUTES Privilege [1];} Info;
HANDLE Token;
//打开本进程的权限句柄
BOOL Result = OpenProcessToken ( hProcess,
TOKEN_ADJUST_PRIVILEGES,
& Token);
If (Result!= TRUE )
{
printf( "Cannot open process token.\n" );
return FALSE;
}
//我们只改变一个属性
Info.Count = 1;
//准备激活
if( bEnable )
Info.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
else
Info.Privilege[0].Attributes = 0;
//根据权限名字找到LGUID
Result = LookupPrivilegeValue ( NULL,
SE_LOCK_MEMORY_NAME,
&(Info.Privilege[0].Luid));
if( Result != TRUE )
{
printf( "Cannot get privilege for %s.\n", SE_LOCK_MEMORY_NAME );
return FALSE;
}
// 激活Lock Pages in Memory权限
Result = AdjustTokenPrivileges ( Token, FALSE,(PTOKEN_PRIVILEGES) &Info,0, NULL, NULL);
if( Result != TRUE )
{
printf ("Cannot adjust token privileges (%u)\n", GetLastError() );
return FALSE;
}
else
{
if( GetLastError() != ERROR_SUCCESS )
{
printf ("Cannot enable the SE_LOCK_MEMORY_NAME privilege; ");
Smile service,common progress!