MemoryManagementWindows.cs 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. using System;
  2. using System.Runtime.InteropServices;
  3. namespace Ryujinx.Memory
  4. {
  5. static class MemoryManagementWindows
  6. {
  7. [Flags]
  8. private enum AllocationType : uint
  9. {
  10. Commit = 0x1000,
  11. Reserve = 0x2000,
  12. Decommit = 0x4000,
  13. Release = 0x8000,
  14. Reset = 0x80000,
  15. Physical = 0x400000,
  16. TopDown = 0x100000,
  17. WriteWatch = 0x200000,
  18. LargePages = 0x20000000
  19. }
  20. [Flags]
  21. private enum MemoryProtection : uint
  22. {
  23. NoAccess = 0x01,
  24. ReadOnly = 0x02,
  25. ReadWrite = 0x04,
  26. WriteCopy = 0x08,
  27. Execute = 0x10,
  28. ExecuteRead = 0x20,
  29. ExecuteReadWrite = 0x40,
  30. ExecuteWriteCopy = 0x80,
  31. GuardModifierflag = 0x100,
  32. NoCacheModifierflag = 0x200,
  33. WriteCombineModifierflag = 0x400
  34. }
  35. [DllImport("kernel32.dll")]
  36. private static extern IntPtr VirtualAlloc(
  37. IntPtr lpAddress,
  38. IntPtr dwSize,
  39. AllocationType flAllocationType,
  40. MemoryProtection flProtect);
  41. [DllImport("kernel32.dll")]
  42. private static extern bool VirtualProtect(
  43. IntPtr lpAddress,
  44. IntPtr dwSize,
  45. MemoryProtection flNewProtect,
  46. out MemoryProtection lpflOldProtect);
  47. [DllImport("kernel32.dll")]
  48. private static extern bool VirtualFree(IntPtr lpAddress, IntPtr dwSize, AllocationType dwFreeType);
  49. public static IntPtr Allocate(IntPtr size)
  50. {
  51. return AllocateInternal(size, AllocationType.Reserve | AllocationType.Commit);
  52. }
  53. public static IntPtr Reserve(IntPtr size)
  54. {
  55. return AllocateInternal(size, AllocationType.Reserve);
  56. }
  57. private static IntPtr AllocateInternal(IntPtr size, AllocationType flags = 0)
  58. {
  59. IntPtr ptr = VirtualAlloc(IntPtr.Zero, size, flags, MemoryProtection.ReadWrite);
  60. if (ptr == IntPtr.Zero)
  61. {
  62. throw new OutOfMemoryException();
  63. }
  64. return ptr;
  65. }
  66. public static bool Commit(IntPtr location, IntPtr size)
  67. {
  68. return VirtualAlloc(location, size, AllocationType.Commit, MemoryProtection.ReadWrite) != IntPtr.Zero;
  69. }
  70. public static bool Reprotect(IntPtr address, IntPtr size, MemoryPermission permission)
  71. {
  72. return VirtualProtect(address, size, GetProtection(permission), out _);
  73. }
  74. private static MemoryProtection GetProtection(MemoryPermission permission)
  75. {
  76. return permission switch
  77. {
  78. MemoryPermission.None => MemoryProtection.NoAccess,
  79. MemoryPermission.Read => MemoryProtection.ReadOnly,
  80. MemoryPermission.ReadAndWrite => MemoryProtection.ReadWrite,
  81. MemoryPermission.ReadAndExecute => MemoryProtection.ExecuteRead,
  82. MemoryPermission.ReadWriteExecute => MemoryProtection.ExecuteReadWrite,
  83. MemoryPermission.Execute => MemoryProtection.Execute,
  84. _ => throw new MemoryProtectionException(permission)
  85. };
  86. }
  87. public static bool Free(IntPtr address)
  88. {
  89. return VirtualFree(address, IntPtr.Zero, AllocationType.Release);
  90. }
  91. }
  92. }