|
//-----------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
//-----------------------------------------------------------------------------
namespace Microsoft.InfoCards
{
using System;
using System.Runtime.InteropServices;
using System.Runtime.CompilerServices;
using System.Runtime.ConstrainedExecution;
using System.Security;
using Microsoft.InfoCards.Diagnostics;
using IDT = Microsoft.InfoCards.Diagnostics.InfoCardTrace;
//
// Summary:
// Provides a wrapper over memory allocated by GlobalAlloc
// guaranteeing that it will be freed during rude thread / appdomain unloads.
// Remarks:
// There is a small ---- in the usage of this class, as it is used to wrap return parameters
// immediatley following the function return.
//
internal class GlobalAllocSafeHandle : SafeHandle
{
[SuppressUnmanagedCodeSecurity]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[DllImport("Kernel32.dll", EntryPoint = "RtlZeroMemory", SetLastError = false)]
public static extern void ZeroMemory(IntPtr dest, Int32 size);
[SuppressUnmanagedCodeSecurity]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall)]
public static extern IntPtr GlobalFree(IntPtr hMem);
//
// How many bytes we currently wrap. This can be zero, as our usage allows for a valid handle
// backed by 0 bytes of allocated memory - specificially TransformBlock and TransformFinalBlock
// can return this by design.
//
private int m_bytes;
private GlobalAllocSafeHandle() : base(IntPtr.Zero, true) { m_bytes = 0; }
public int Length
{
set { m_bytes = value; }
get { return m_bytes; }
}
public override bool IsInvalid
{
get
{
return (IntPtr.Zero == base.handle);
}
}
//
// Summary:
// Clear the data held and release the memory.
//
protected override bool ReleaseHandle()
{
if (m_bytes > 0)
{
ZeroMemory(base.handle, m_bytes);
GlobalFree(base.handle);
m_bytes = 0;
}
return true;
}
}
}
|