mirror of
https://github.com/mirror/processhacker
synced 2026-06-08 16:03:24 +00:00
710682a5ab
git-svn-id: svn://svn.code.sf.net/p/processhacker/code@1526 21ef857c-d57f-4fe0-8362-d861dc6d29cd
84 lines
2.6 KiB
C#
84 lines
2.6 KiB
C#
using System;
|
|
using ProcessHacker.Common.Objects;
|
|
using ProcessHacker.Native.Api;
|
|
using ProcessHacker.Native.Objects;
|
|
|
|
namespace ProcessHacker.Native.Memory
|
|
{
|
|
public sealed class PhysicalPages : BaseObject
|
|
{
|
|
private ProcessHandle _processHandle;
|
|
private int _count;
|
|
private IntPtr[] _pfnArray;
|
|
|
|
public PhysicalPages(ProcessHandle processHandle, int count, bool pages)
|
|
{
|
|
if (pages)
|
|
_count = count;
|
|
else
|
|
_count = (count - 1) / Windows.PageSize + 1;
|
|
|
|
IntPtr pageCount = new IntPtr(_count);
|
|
|
|
_pfnArray = new IntPtr[_count];
|
|
|
|
if (!Win32.AllocateUserPhysicalPages(processHandle, ref pageCount, _pfnArray))
|
|
Win32.ThrowLastError();
|
|
|
|
if (pageCount.ToInt32() != _count)
|
|
throw new Exception("Could not allocate all pages.");
|
|
|
|
_processHandle = processHandle;
|
|
_processHandle.Reference();
|
|
}
|
|
|
|
protected override void DisposeObject(bool disposing)
|
|
{
|
|
IntPtr freedPages = new IntPtr(_count);
|
|
|
|
_processHandle.Dereference();
|
|
|
|
if (!Win32.FreeUserPhysicalPages(_processHandle, ref freedPages, _pfnArray))
|
|
Win32.ThrowLastError();
|
|
|
|
if (freedPages.ToInt32() != _count)
|
|
throw new Exception("Could not free all pages.");
|
|
}
|
|
|
|
public PhysicalPagesMapping Map(IntPtr address, MemoryProtection protection)
|
|
{
|
|
return new PhysicalPagesMapping(this, address, protection);
|
|
}
|
|
|
|
internal void Map(IntPtr address, MemoryProtection protection, bool unmap)
|
|
{
|
|
if (!unmap)
|
|
{
|
|
IntPtr allocAddress = Win32.VirtualAllocEx(
|
|
ProcessHandle.GetCurrent(),
|
|
address,
|
|
_count * Windows.PageSize,
|
|
MemoryState.Reserve | MemoryState.Physical,
|
|
protection
|
|
);
|
|
|
|
if (!Win32.MapUserPhysicalPages(
|
|
allocAddress,
|
|
new IntPtr(_count),
|
|
_pfnArray
|
|
))
|
|
Win32.ThrowLastError();
|
|
}
|
|
else
|
|
{
|
|
if (!Win32.MapUserPhysicalPages(
|
|
address,
|
|
new IntPtr(_count),
|
|
_pfnArray
|
|
))
|
|
Win32.ThrowLastError();
|
|
}
|
|
}
|
|
}
|
|
}
|