using System; using System.Runtime.ConstrainedExecution; using System.Runtime.InteropServices; namespace Trinet.Core.IO.Ntfs { /// /// A for a global memory allocation. /// internal sealed class SafeHGlobalHandle : SafeHandle { #region Private Data private readonly int _size; #endregion #region Constructor /// /// Initializes a new instance of the class. /// /// /// The initial handle value. /// /// /// The size of this memory block, in bytes. /// [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] private SafeHGlobalHandle(IntPtr toManage, int size) : base(IntPtr.Zero, true) { _size = size; base.SetHandle(toManage); } /// /// Initializes a new instance of the class. /// private SafeHGlobalHandle() : base(IntPtr.Zero, true) { } #endregion #region Properties /// /// Gets a value indicating whether the handle value is invalid. /// /// /// if the handle value is invalid; /// otherwise, . /// public override bool IsInvalid { get { return IntPtr.Zero == base.handle; } } /// /// Returns the size of this memory block. /// /// /// The size of this memory block, in bytes. /// public int Size { get { return _size; } } #endregion #region Methods /// /// Allocates memory from the unmanaged memory of the process using GlobalAlloc. /// /// /// The number of bytes in memory required. /// /// /// A representing the memory. /// /// /// There is insufficient memory to satisfy the request. /// public static SafeHGlobalHandle Allocate(int bytes) { return new SafeHGlobalHandle(Marshal.AllocHGlobal(bytes), bytes); } /// /// Returns an invalid handle. /// /// /// An invalid . /// public static SafeHGlobalHandle Invalid() { return new SafeHGlobalHandle(); } /// /// Executes the code required to free the handle. /// /// /// if the handle is released successfully; /// otherwise, in the event of a catastrophic failure, . /// In this case, it generates a releaseHandleFailed MDA Managed Debugging Assistant. /// protected override bool ReleaseHandle() { Marshal.FreeHGlobal(base.handle); return true; } #endregion } }