using System; using System.Runtime.InteropServices; namespace ScreenConnect; public class NativeMemoryMinder : CriticalFinalizerDisposableObject { private bool zeroMemoryOnAllocate; public int Size { get; private set; } public IntPtr Address { get; private set; } public unsafe byte* ByteAddress => (byte*)(void*)Address; public unsafe int* IntAddress => (int*)(void*)Address; public NativeMemoryMinder(bool zeroMemoryOnAllocate = false, int initialSize = 0) { this.zeroMemoryOnAllocate = zeroMemoryOnAllocate; if (initialSize != 0) { EnsureSizePossiblyRelocating(initialSize); } } public unsafe void EnsureSizePossiblyRelocating(int minSize) { if (Size < minSize) { Address = ((Address == IntPtr.Zero) ? Marshal.AllocHGlobal(minSize) : Marshal.ReAllocHGlobal(Address, (IntPtr)minSize)); if (zeroMemoryOnAllocate) { Extensions.ZeroMemory(ByteAddress + Size, minSize - Size); } Size = minSize; } } protected override void Dispose(bool disposing) { Marshal.FreeHGlobal(Address); } }