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
}
}