MemoryManagementWindows.cs 4.6 KB

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