|
- // THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
- // ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
- // THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
- // PARTICULAR PURPOSE.
- //
- // Copyright (c) Microsoft Corporation. All rights reserved
-
- using System;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Diagnostics.CodeAnalysis;
- using System.Runtime.CompilerServices;
- using System.Runtime.ConstrainedExecution;
- using System.Runtime.InteropServices;
- using System.Security;
-
- using Microsoft.Win32.SafeHandles;
-
- namespace Security2
- {
- using HANDLE = System.IntPtr;
-
- internal sealed class SafeHGlobalHandle : IDisposable
- {
- #region Constructor and Destructor
- SafeHGlobalHandle()
- {
- pointer = IntPtr.Zero;
- }
-
- SafeHGlobalHandle(IntPtr handle)
- {
- pointer = handle;
- }
-
- ~SafeHGlobalHandle()
- {
- Dispose();
- }
- #endregion
-
- #region Public methods
- public static SafeHGlobalHandle InvalidHandle
- {
- get { return new SafeHGlobalHandle(IntPtr.Zero); }
- }
-
- /// <summary>
- /// Adds reference to other SafeHGlobalHandle objects, the pointer to
- /// which are refered to by this object. This is to ensure that such
- /// objects being referred to wouldn't be unreferenced until this object
- /// is active.
- ///
- /// For e.g. when this object is an array of pointers to other objects
- /// </summary>
- /// <param name="children">Collection of SafeHGlobalHandle objects
- /// referred to by this object.</param>
- public void AddSubReference(IEnumerable<SafeHGlobalHandle> children)
- {
- if (references == null)
- {
- references = new List<SafeHGlobalHandle>();
- }
-
- references.AddRange(children);
- }
-
- /// <summary>
- /// Allocates from unmanaged memory to represent an array of pointers
- /// and marshals the unmanaged pointers (IntPtr) to the native array
- /// equivalent.
- /// </summary>
- /// <param name="values">Array of unmanaged pointers</param>
- /// <returns>SafeHGlobalHandle object to an native (unmanaged) array of pointers</returns>
- public static SafeHGlobalHandle AllocHGlobal(IntPtr[] values)
- {
- SafeHGlobalHandle result = AllocHGlobal(IntPtr.Size * values.Length);
-
- Marshal.Copy(values, 0, result.pointer, values.Length);
-
- return result;
- }
-
- public static SafeHGlobalHandle AllocHGlobalStruct<T>(T obj) where T : struct
- {
- Debug.Assert(typeof(T).StructLayoutAttribute.Value == LayoutKind.Sequential);
-
- SafeHGlobalHandle result = AllocHGlobal(Marshal.SizeOf(typeof(T)));
-
- Marshal.StructureToPtr(obj, result.pointer, false);
-
- return result;
- }
-
- /// <summary>
- /// Allocates from unmanaged memory to represent an array of structures
- /// and marshals the structure elements to the native array of
- /// structures. ONLY structures with attribute StructLayout of
- /// LayoutKind.Sequential are supported.
- /// </summary>
- /// <typeparam name="T">Native structure type</typeparam>
- /// <param name="values">Collection of structure objects</param>
- /// <param name="count">Number of elements in the collection</param>
- /// <returns>SafeHGlobalHandle object to an native (unmanaged) array of structures</returns>
- public static SafeHGlobalHandle AllocHGlobal<T>(ICollection<T> values) where T : struct
- {
- Debug.Assert(typeof(T).StructLayoutAttribute.Value == LayoutKind.Sequential);
-
- return AllocHGlobal(0, values, values.Count);
- }
-
- /// <summary>
- /// Allocates from unmanaged memory to represent a structure with a
- /// variable length array at the end and marshal these structure
- /// elements. It is the callers responsibility to marshal what preceeds
- /// the trailinh array into the unmanaged memory. ONLY structures with
- /// attribute StructLayout of LayoutKind.Sequential are supported.
- /// </summary>
- /// <typeparam name="T">Type of the trailing array of structures</typeparam>
- /// <param name="prefixBytes">Number of bytes preceeding the trailing array of structures</param>
- /// <param name="values">Collection of structure objects</param>
- /// <param name="count"></param>
- /// <returns>SafeHGlobalHandle object to an native (unmanaged) structure
- /// with a trail array of structures</returns>
- public static SafeHGlobalHandle AllocHGlobal<T>(int prefixBytes, IEnumerable<T> values, int count) where T
- : struct
- {
- Debug.Assert(typeof(T).StructLayoutAttribute.Value == LayoutKind.Sequential);
-
- SafeHGlobalHandle result = AllocHGlobal(prefixBytes + Marshal.SizeOf(typeof(T)) * count);
-
- IntPtr ptr = new IntPtr(result.pointer.ToInt32() + prefixBytes);
- foreach (var value in values)
- {
- Marshal.StructureToPtr(value, ptr, false);
- ptr.Increment<T>();
- }
-
- return result;
- }
-
- /// <summary>
- /// Allocates from unmanaged memory to represent a unicode string (WSTR)
- /// and marshal this to a native PWSTR.
- /// </summary>
- /// <param name="s">String</param>
- /// <returns>SafeHGlobalHandle object to an native (unmanaged) unicode string</returns>
- public static SafeHGlobalHandle AllocHGlobal(string s)
- {
- return new SafeHGlobalHandle(Marshal.StringToHGlobalUni(s));
- }
-
- /// <summary>
- /// Operator to obtain the unmanaged pointer wrapped by the object. Note
- /// that the returned pointer is only valid for the lifetime of this
- /// object.
- /// </summary>
- /// <param name="safeHandle">SafeHGlobalHandle object</param>
- /// <returns>Unmanaged pointer wrapped by the object</returns>
- public IntPtr ToIntPtr()
- {
- return pointer;
- }
- #endregion
-
- #region IDisposable implmentation
- public void Dispose()
- {
- if (pointer != IntPtr.Zero)
- {
- Marshal.FreeHGlobal(pointer);
- pointer = IntPtr.Zero;
- }
-
- GC.SuppressFinalize(this);
- }
- #endregion
-
- #region Private implementation
- [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope",
- Justification = "Caller will dispose result")]
- static SafeHGlobalHandle AllocHGlobal(int cb)
- {
- if (cb < 0)
- {
- throw new ArgumentOutOfRangeException("cb", "The value of this argument must be non-negative");
- }
-
- SafeHGlobalHandle result = new SafeHGlobalHandle();
-
- //
- // CER
- //
- RuntimeHelpers.PrepareConstrainedRegions();
- try { }
- finally
- {
- result.pointer = Marshal.AllocHGlobal(cb);
- }
-
- return result;
- }
- #endregion
-
- #region Private members
- /// <summary>
- /// Maintainsreference to other SafeHGlobalHandle objects, the pointer
- /// to which are refered to by this object. This is to ensure that such
- /// objects being referred to wouldn't be unreferenced until this object
- /// is active.
- /// </summary>
- List<SafeHGlobalHandle> references;
-
- //
- // Using SafeHandle here doesn't buy much since the pointer is
- // eventually stashed into a native structure. Using a SafeHandle would
- // involve calling DangerousGetHandle in place of ToIntPtr which makes
- // code analysis report CA2001: Avoid calling problematic methods.
- //
- [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")]
- /// <summary>
- /// Unmanaged pointer wrapped by this object
- /// </summary>
- IntPtr pointer;
- #endregion
- }
-
- //
- // Adopted from: http://msdn.microsoft.com/en-us/magazine/cc163823.aspx
- //
- /// <summary>
- /// Safe wrapper for HANDLE to a token.
- /// </summary>
- internal class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
- {
- #region Constructors
- /// <summary>
- /// This safehandle instance "owns" the handle, hence base(true)
- /// is being called. When safehandle is no longer in use it will
- /// call this class's ReleaseHandle method which will release
- /// the resources
- /// </summary>
- private SafeTokenHandle() : base(true) { }
-
- // 0 is an Invalid Handle
- internal SafeTokenHandle(HANDLE handle)
- : base(true)
- {
- SetHandle(handle);
- }
- #endregion
-
- internal static SafeTokenHandle InvalidHandle
- {
- [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode", Justification = "Retain to illustrate semantics")]
- get { return new SafeTokenHandle(HANDLE.Zero); }
- }
-
- #region Private implementation
- /// <summary>
- /// Release the HANDLE held by this instance
- /// </summary>
- /// <returns>true if the release was successful. false otherwise.</returns>
- override protected bool ReleaseHandle()
- {
- return NativeMethods.CloseHandle(handle);
- }
- #endregion
-
- #region Nested class for P/Invokes
- static class NativeMethods
- {
- [DllImport(Win32.KERNEL32_DLL, SetLastError = true),
- SuppressUnmanagedCodeSecurity,
- ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool CloseHandle(HANDLE handle);
- }
- #endregion
- }
-
- /// <summary>
- /// Safe wrapper for AUTHZ_RESOURCE_MANAGER_HANDLE.
- /// </summary>
- internal class SafeAuthzRMHandle : SafeHandleZeroOrMinusOneIsInvalid
- {
- #region Constructors
- /// <summary>
- /// This safehandle instance "owns" the handle, hence base(true)
- /// is being called. When safehandle is no longer in use it will
- /// call this class's ReleaseHandle method which will release
- /// the resources
- /// </summary>
- SafeAuthzRMHandle() : base(true) { }
-
- [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode",
- Justification = "Retain to illustrate semantics and for reuse")]
- SafeAuthzRMHandle(HANDLE handle)
- : base(true)
- {
- SetHandle(handle);
- }
- #endregion
-
- public static SafeAuthzRMHandle InvalidHandle
- {
- [SuppressMessage("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode",
- Justification = "Retain to illustrate semantics")]
- get { return new SafeAuthzRMHandle(HANDLE.Zero); }
- }
-
- #region Private implementation
- /// <summary>
- /// Release the resource manager handle held by this instance
- /// </summary>
- /// <returns>true if the release was successful. false otherwise.</returns>
- override protected bool ReleaseHandle()
- {
- return NativeMethods.AuthzFreeResourceManager(handle);
- }
- #endregion
-
- #region Nested class for P/Invokes
- static class NativeMethods
- {
- [DllImport(Win32.AUTHZ_DLL, SetLastError = true),
- SuppressUnmanagedCodeSecurity,
- ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
- [return: MarshalAs(UnmanagedType.Bool)]
- public static extern bool AuthzFreeResourceManager(HANDLE handle);
- }
- #endregion
- }
- }
|