AMemoryWin32.cs 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. using System;
  2. using System.Runtime.InteropServices;
  3. namespace ChocolArm64.Memory
  4. {
  5. static class AMemoryWin32
  6. {
  7. private const int MEM_COMMIT = 0x00001000;
  8. private const int MEM_RESERVE = 0x00002000;
  9. private const int MEM_WRITE_WATCH = 0x00200000;
  10. private const int PAGE_READWRITE = 0x04;
  11. private const int MEM_RELEASE = 0x8000;
  12. private const int WRITE_WATCH_FLAG_RESET = 1;
  13. [DllImport("kernel32.dll")]
  14. private static extern IntPtr VirtualAlloc(IntPtr lpAddress, IntPtr dwSize, int flAllocationType, int flProtect);
  15. [DllImport("kernel32.dll")]
  16. private static extern bool VirtualFree(IntPtr lpAddress, IntPtr dwSize, int dwFreeType);
  17. [DllImport("kernel32.dll")]
  18. private unsafe static extern int GetWriteWatch(
  19. int dwFlags,
  20. IntPtr lpBaseAddress,
  21. IntPtr dwRegionSize,
  22. IntPtr[] lpAddresses,
  23. long* lpdwCount,
  24. long* lpdwGranularity);
  25. public static IntPtr Allocate(IntPtr Size)
  26. {
  27. const int Flags = MEM_COMMIT | MEM_RESERVE | MEM_WRITE_WATCH;
  28. IntPtr Address = VirtualAlloc(IntPtr.Zero, Size, Flags, PAGE_READWRITE);
  29. if (Address == IntPtr.Zero)
  30. {
  31. throw new InvalidOperationException();
  32. }
  33. return Address;
  34. }
  35. public static void Free(IntPtr Address)
  36. {
  37. VirtualFree(Address, IntPtr.Zero, MEM_RELEASE);
  38. }
  39. public unsafe static int GetPageSize(IntPtr Address, IntPtr Size)
  40. {
  41. IntPtr[] Addresses = new IntPtr[1];
  42. long Count = Addresses.Length;
  43. long Granularity;
  44. GetWriteWatch(
  45. 0,
  46. Address,
  47. Size,
  48. Addresses,
  49. &Count,
  50. &Granularity);
  51. return (int)Granularity;
  52. }
  53. public unsafe static void IsRegionModified(
  54. IntPtr Address,
  55. IntPtr Size,
  56. IntPtr[] Addresses,
  57. out int AddrCount)
  58. {
  59. long Count = Addresses.Length;
  60. long Granularity;
  61. GetWriteWatch(
  62. WRITE_WATCH_FLAG_RESET,
  63. Address,
  64. Size,
  65. Addresses,
  66. &Count,
  67. &Granularity);
  68. AddrCount = (int)Count;
  69. }
  70. }
  71. }