//----------------------------------------------------------------------------- // Copyright (c) Microsoft Corporation. All rights reserved. //----------------------------------------------------------------------------- namespace Microsoft.InfoCards { using System; using System.Runtime.InteropServices; using Microsoft.InfoCards.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.ConstrainedExecution; using System.Security; using IDT = Microsoft.InfoCards.Diagnostics.InfoCardTrace; // // Summary: // Provides a wrapper over HGlobal alloc'd memory guaranteeing that the // contents will be released in the presence of rude app domain and thread aborts. // internal class HGlobalSafeHandle : SafeHandle { public static HGlobalSafeHandle Construct() { return new HGlobalSafeHandle(); } public static HGlobalSafeHandle Construct(string managedString) { IDT.DebugAssert(!String.IsNullOrEmpty(managedString), "null string"); int bytes = (managedString.Length + 1) * 2; return new HGlobalSafeHandle(Marshal.StringToHGlobalUni(managedString), bytes); } public static HGlobalSafeHandle Construct(int bytes) { IDT.DebugAssert(bytes > 0, "attempt to allocate a handle with <= 0 bytes"); return new HGlobalSafeHandle(Marshal.AllocHGlobal(bytes), bytes); } [SuppressUnmanagedCodeSecurity] [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] [DllImport("Kernel32.dll", EntryPoint = "RtlZeroMemory", SetLastError = false)] public static extern void ZeroMemory(IntPtr dest, Int32 size); // // The number of bytes allocated. // private int m_bytes; [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] private HGlobalSafeHandle(IntPtr toManage, int length) : base(IntPtr.Zero, true) { m_bytes = length; SetHandle(toManage); } private HGlobalSafeHandle() : base(IntPtr.Zero, true) { } public override bool IsInvalid { get { return (IntPtr.Zero == base.handle); } } // // Summary: // Zero the string contents and release the handle // protected override bool ReleaseHandle() { IDT.DebugAssert(!IsInvalid, "handle is invalid in release handle"); IDT.DebugAssert(0 != m_bytes, "invalid size"); ZeroMemory(base.handle, m_bytes); Marshal.FreeHGlobal(base.handle); return true; } } }