如何判断一个虚拟内存页面是否被locking?

说,如果在某个时候我的进程中的虚拟内存的范围被locking,

//Memory was reserved & committed as such void* pMem = ::VirtualAlloc(NULL, 4096, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); //... //And then ::VirtualLock(pMem, 4096); 

因此,在我的进程中有一个虚拟内存中的页面的任意地址,我可以告诉它是否被locked

通过使用win32 api这是不可能的。 但是如果使用带有未记录 MEMORY_INFORMATION_CLASS值的MEMORY_INFORMATION_CLASS – 这是可能的。 对于数据结构定义 – 参见ntmmapi.h

我们需要使用MemoryWorkingSetExInformationMEMORY_WORKING_SET_EX_BLOCK并使用ULONG_PTR Locked : 1; 会员

演示测试:

 NTSTATUS IsPageLocked(PVOID BaseAddress, BOOLEAN& Locked) { MEMORY_WORKING_SET_EX_INFORMATION mwsei = { BaseAddress }; NTSTATUS status = ZwQueryVirtualMemory(NtCurrentProcess(), 0, MemoryWorkingSetExInformation, &mwsei, sizeof(mwsei), 0); if (0 <= status) { if (mwsei.VirtualAttributes.Valid) { Locked = mwsei.VirtualAttributes.Locked; } else { status = STATUS_INVALID_ADDRESS; } } return status; } NTSTATUS IsPageLockedEx(PVOID BaseAddress, BOOLEAN& Locked) { NTSTATUS status = IsPageLocked(BaseAddress, Locked); if (0 > status) { DbgPrint("IsPageLocked - error %x\n", status); } else { DbgPrint("IsPageLocked = %x\n", Locked); } return status; } void CheckVA() { if (PVOID pv = VirtualAlloc(NULL, PAGE_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE)) { BOOLEAN Locked; NTSTATUS status = IsPageLockedEx(pv, Locked); if (status == STATUS_INVALID_ADDRESS) { // at this point physical memory for pv not yet committed. reference memory for commit physical page if (*(PBYTE)pv) __nop(); status = IsPageLockedEx(pv, Locked); } if (VirtualLock(pv, PAGE_SIZE)) { IsPageLockedEx(pv, Locked); if (VirtualUnlock(pv, PAGE_SIZE)) { IsPageLockedEx(pv, Locked); } else { __debugbreak(); } } VirtualFree(pv, 0, MEM_RELEASE); } } 

DbgPrint输出

 IsPageLocked - error c0000141 IsPageLocked = 0 IsPageLocked = 1 IsPageLocked = 0