106 lines
3.4 KiB
C#
106 lines
3.4 KiB
C#
|
using System;
|
|||
|
using System.Runtime.InteropServices;
|
|||
|
|
|||
|
namespace Ryujinx.Memory
|
|||
|
{
|
|||
|
static class MemoryManagementWindows
|
|||
|
{
|
|||
|
[Flags]
|
|||
|
private enum AllocationType : uint
|
|||
|
{
|
|||
|
Commit = 0x1000,
|
|||
|
Reserve = 0x2000,
|
|||
|
Decommit = 0x4000,
|
|||
|
Release = 0x8000,
|
|||
|
Reset = 0x80000,
|
|||
|
Physical = 0x400000,
|
|||
|
TopDown = 0x100000,
|
|||
|
WriteWatch = 0x200000,
|
|||
|
LargePages = 0x20000000
|
|||
|
}
|
|||
|
|
|||
|
[Flags]
|
|||
|
private enum MemoryProtection : uint
|
|||
|
{
|
|||
|
NoAccess = 0x01,
|
|||
|
ReadOnly = 0x02,
|
|||
|
ReadWrite = 0x04,
|
|||
|
WriteCopy = 0x08,
|
|||
|
Execute = 0x10,
|
|||
|
ExecuteRead = 0x20,
|
|||
|
ExecuteReadWrite = 0x40,
|
|||
|
ExecuteWriteCopy = 0x80,
|
|||
|
GuardModifierflag = 0x100,
|
|||
|
NoCacheModifierflag = 0x200,
|
|||
|
WriteCombineModifierflag = 0x400
|
|||
|
}
|
|||
|
|
|||
|
[DllImport("kernel32.dll")]
|
|||
|
private static extern IntPtr VirtualAlloc(
|
|||
|
IntPtr lpAddress,
|
|||
|
IntPtr dwSize,
|
|||
|
AllocationType flAllocationType,
|
|||
|
MemoryProtection flProtect);
|
|||
|
|
|||
|
[DllImport("kernel32.dll")]
|
|||
|
private static extern bool VirtualProtect(
|
|||
|
IntPtr lpAddress,
|
|||
|
IntPtr dwSize,
|
|||
|
MemoryProtection flNewProtect,
|
|||
|
out MemoryProtection lpflOldProtect);
|
|||
|
|
|||
|
[DllImport("kernel32.dll")]
|
|||
|
private static extern bool VirtualFree(IntPtr lpAddress, IntPtr dwSize, AllocationType dwFreeType);
|
|||
|
|
|||
|
public static IntPtr Allocate(IntPtr size)
|
|||
|
{
|
|||
|
return AllocateInternal(size, AllocationType.Reserve | AllocationType.Commit);
|
|||
|
}
|
|||
|
|
|||
|
public static IntPtr Reserve(IntPtr size)
|
|||
|
{
|
|||
|
return AllocateInternal(size, AllocationType.Reserve);
|
|||
|
}
|
|||
|
|
|||
|
private static IntPtr AllocateInternal(IntPtr size, AllocationType flags = 0)
|
|||
|
{
|
|||
|
IntPtr ptr = VirtualAlloc(IntPtr.Zero, size, flags, MemoryProtection.ReadWrite);
|
|||
|
|
|||
|
if (ptr == IntPtr.Zero)
|
|||
|
{
|
|||
|
throw new OutOfMemoryException();
|
|||
|
}
|
|||
|
|
|||
|
return ptr;
|
|||
|
}
|
|||
|
|
|||
|
public static bool Commit(IntPtr location, IntPtr size)
|
|||
|
{
|
|||
|
return VirtualAlloc(location, size, AllocationType.Commit, MemoryProtection.ReadWrite) != IntPtr.Zero;
|
|||
|
}
|
|||
|
|
|||
|
public static bool Reprotect(IntPtr address, IntPtr size, MemoryPermission permission)
|
|||
|
{
|
|||
|
return VirtualProtect(address, size, GetProtection(permission), out _);
|
|||
|
}
|
|||
|
|
|||
|
private static MemoryProtection GetProtection(MemoryPermission permission)
|
|||
|
{
|
|||
|
return permission switch
|
|||
|
{
|
|||
|
MemoryPermission.None => MemoryProtection.NoAccess,
|
|||
|
MemoryPermission.Read => MemoryProtection.ReadOnly,
|
|||
|
MemoryPermission.ReadAndWrite => MemoryProtection.ReadWrite,
|
|||
|
MemoryPermission.ReadAndExecute => MemoryProtection.ExecuteRead,
|
|||
|
MemoryPermission.ReadWriteExecute => MemoryProtection.ExecuteReadWrite,
|
|||
|
MemoryPermission.Execute => MemoryProtection.Execute,
|
|||
|
_ => throw new MemoryProtectionException(permission)
|
|||
|
};
|
|||
|
}
|
|||
|
|
|||
|
public static bool Free(IntPtr address)
|
|||
|
{
|
|||
|
return VirtualFree(address, IntPtr.Zero, AllocationType.Release);
|
|||
|
}
|
|||
|
}
|
|||
|
}
|