Virtu/Library/SafeAllocHandle.cs

148 lines
4.8 KiB
C#
Raw Normal View History

using System;
using System.ComponentModel;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles;
namespace Jellyfish.Library
{
[SecurityPermission(SecurityAction.InheritanceDemand, UnmanagedCode = true)]
[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
public abstract class SafeAllocHandle : SafeHandleZeroOrMinusOneIsInvalid
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected SafeAllocHandle(bool ownsHandle) :
base(ownsHandle)
{
}
}
[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
public sealed class SafeGlobalAllocHandle : SafeAllocHandle
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public SafeGlobalAllocHandle() :
base(true)
{
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public SafeGlobalAllocHandle(IntPtr existingHandle, bool ownsHandle) :
base(ownsHandle)
{
SetHandle(existingHandle);
}
public static SafeGlobalAllocHandle Allocate(int size)
{
return Allocate(0x0, size);
}
public static SafeGlobalAllocHandle Allocate(byte[] value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
SafeGlobalAllocHandle alloc = Allocate(value.Length);
Marshal.Copy(value, 0, alloc.DangerousGetHandle(), value.Length);
return alloc;
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
protected override bool ReleaseHandle()
{
return (NativeMethods.GlobalFree(handle) == IntPtr.Zero);
}
private static SafeGlobalAllocHandle Allocate(uint flags, int size)
{
SafeGlobalAllocHandle alloc = NativeMethods.GlobalAlloc(flags, (IntPtr)size);
if (alloc.IsInvalid)
{
throw new Win32Exception();
}
return alloc;
}
[SuppressUnmanagedCodeSecurity]
private static class NativeMethods
{
[DllImport("kernel32.dll", SetLastError = true)]
public static extern SafeGlobalAllocHandle GlobalAlloc(uint dwFlags, IntPtr sizetBytes);
[DllImport("kernel32.dll", SetLastError = true)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static extern IntPtr GlobalFree(IntPtr hMem);
}
}
[SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
public sealed class SafeLocalAllocHandle : SafeAllocHandle
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public SafeLocalAllocHandle() :
base(true)
{
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public SafeLocalAllocHandle(IntPtr existingHandle, bool ownsHandle) :
base(ownsHandle)
{
SetHandle(existingHandle);
}
public static SafeLocalAllocHandle Allocate(int size)
{
return Allocate(0x0, size);
}
public static SafeLocalAllocHandle Allocate(byte[] value)
{
if (value == null)
{
throw new ArgumentNullException("value");
}
SafeLocalAllocHandle alloc = Allocate(value.Length);
Marshal.Copy(value, 0, alloc.DangerousGetHandle(), value.Length);
return alloc;
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
protected override bool ReleaseHandle()
{
return (NativeMethods.LocalFree(handle) == IntPtr.Zero);
}
private static SafeLocalAllocHandle Allocate(uint flags, int size)
{
SafeLocalAllocHandle alloc = NativeMethods.LocalAlloc(flags, (IntPtr)size);
if (alloc.IsInvalid)
{
throw new Win32Exception();
}
return alloc;
}
[SuppressUnmanagedCodeSecurity]
private static class NativeMethods
{
[DllImport("kernel32.dll", SetLastError = true)]
public static extern SafeLocalAllocHandle LocalAlloc(uint dwFlags, IntPtr sizetBytes);
[DllImport("kernel32.dll", SetLastError = true)]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
public static extern IntPtr LocalFree(IntPtr hMem);
}
}
}