90 lines
2.7 KiB
C#
90 lines
2.7 KiB
C#
|
//-----------------------------------------------------------------------------
|
||
|
// 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;
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
}
|