mirror of https://github.com/dahall/Vanara.git
BREAKING CHANGE: Due to performance, changed IMemoryMethods and ISimpleMemoryMethods to contain method signatures instead of properties of method delegates. Then changed all derived memory classes to new interface definition. I believe most of this only affects internal classes so hopefully not a huge effect on your code.
parent
abc888d60b
commit
e701d99c1b
|
@ -12,28 +12,60 @@ namespace Vanara.InteropServices
|
|||
/// <seealso cref="IMemoryMethods"/>
|
||||
public sealed class CoTaskMemoryMethods : IMemoryMethods
|
||||
{
|
||||
/// <summary>Gets the allocation method.</summary>
|
||||
public Func<int, IntPtr> AllocMem => Marshal.AllocCoTaskMem;
|
||||
/// <summary>Gets the reallocation method.</summary>
|
||||
public Func<IntPtr, int, IntPtr> ReAllocMem => Marshal.ReAllocCoTaskMem;
|
||||
/// <summary>Gets the free method.</summary>
|
||||
public Action<IntPtr> FreeMem => Marshal.FreeCoTaskMem;
|
||||
/// <summary>Gets the Unicode string allocation method.</summary>
|
||||
public Func<string, IntPtr> AllocStringUni => Marshal.StringToCoTaskMemUni;
|
||||
/// <summary>Gets the Ansi string allocation method.</summary>
|
||||
public Func<string, IntPtr> AllocStringAnsi => Marshal.StringToCoTaskMemAnsi;
|
||||
/// <summary>Gets the Unicode <see cref="SecureString"/> allocation method.</summary>
|
||||
public Func<SecureString, IntPtr> AllocSecureStringUni => Marshal.SecureStringToCoTaskMemUnicode;
|
||||
/// <summary>Gets the Ansi <see cref="SecureString"/> allocation method.</summary>
|
||||
public Func<SecureString, IntPtr> AllocSecureStringAnsi => Marshal.SecureStringToCoTaskMemAnsi;
|
||||
/// <summary>Gets the Unicode <see cref="SecureString"/> free method.</summary>
|
||||
public Action<IntPtr> FreeSecureStringUni => Marshal.ZeroFreeCoTaskMemUnicode;
|
||||
/// <summary>Gets the Ansi <see cref="SecureString"/> free method.</summary>
|
||||
public Action<IntPtr> FreeSecureStringAnsi => Marshal.ZeroFreeCoTaskMemAnsi;
|
||||
|
||||
|
||||
/// <summary>Static instance to methods.</summary>
|
||||
public static IMemoryMethods Instance { get; } = new CoTaskMemoryMethods();
|
||||
|
||||
/// <summary>Gets a handle to a memory allocation of the specified size.</summary>
|
||||
/// <param name="size">The size, in bytes, of memory to allocate.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public IntPtr AllocMem(int size) => Marshal.AllocCoTaskMem(size);
|
||||
|
||||
/// <summary>Gets the Ansi <see cref="SecureString"/> allocation method.</summary>
|
||||
/// <param name="secureString">The secure string.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public IntPtr AllocSecureStringAnsi(SecureString secureString) => Marshal.SecureStringToCoTaskMemAnsi(secureString);
|
||||
|
||||
/// <summary>Gets the Unicode <see cref="SecureString"/> allocation method.</summary>
|
||||
/// <param name="secureString">The secure string.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public IntPtr AllocSecureStringUni(SecureString secureString) => Marshal.SecureStringToCoTaskMemUnicode(secureString);
|
||||
|
||||
/// <summary>Gets the Ansi string allocation method.</summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public IntPtr AllocStringAnsi(string value) => Marshal.StringToCoTaskMemAnsi(value);
|
||||
|
||||
/// <summary>Gets the Unicode string allocation method.</summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public IntPtr AllocStringUni(string value) => Marshal.StringToCoTaskMemUni(value);
|
||||
|
||||
/// <summary>Frees the memory associated with a handle.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
public void FreeMem(IntPtr hMem) => Marshal.FreeCoTaskMem(hMem);
|
||||
|
||||
/// <summary>Gets the Ansi <see cref="SecureString"/> free method.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
public void FreeSecureStringAnsi(IntPtr hMem) => Marshal.ZeroFreeCoTaskMemAnsi(hMem);
|
||||
|
||||
/// <summary>Gets the Unicode <see cref="SecureString"/> free method.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
public void FreeSecureStringUni(IntPtr hMem) => Marshal.ZeroFreeCoTaskMemUnicode(hMem);
|
||||
|
||||
/// <summary>Locks the memory of a specified handle and gets a pointer to it.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
/// <returns>A pointer to the locked memory.</returns>
|
||||
public IntPtr LockMem(IntPtr hMem) => hMem;
|
||||
|
||||
/// <summary>Gets the reallocation method.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
/// <param name="size">The size, in bytes, of memory to allocate.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public IntPtr ReAllocMem(IntPtr hMem, int size) => Marshal.ReAllocCoTaskMem(hMem, size);
|
||||
|
||||
/// <summary>Unlocks the memory of a specified handle.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
public void UnlockMem(IntPtr hMem) { }
|
||||
}
|
||||
|
||||
/// <summary>A <see cref="SafeHandle"/> for memory allocated via COM.</summary>
|
||||
|
@ -51,12 +83,18 @@ namespace Vanara.InteropServices
|
|||
/// <exception cref="System.ArgumentOutOfRangeException">size - The value of this argument must be non-negative</exception>
|
||||
public SafeCoTaskMemHandle(SizeT size) : base(size) { }
|
||||
|
||||
/// <summary>Allocates from unmanaged memory to represent an array of pointers and marshals the unmanaged pointers (IntPtr) to the native array equivalent.</summary>
|
||||
/// <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="bytes">Array of unmanaged pointers</param>
|
||||
/// <returns>SafeCoTaskMemHandle object to an native (unmanaged) array of pointers</returns>
|
||||
public SafeCoTaskMemHandle(byte[] bytes) : base(bytes) { }
|
||||
|
||||
/// <summary>Allocates from unmanaged memory to represent an array of pointers and marshals the unmanaged pointers (IntPtr) to the native array equivalent.</summary>
|
||||
/// <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>SafeCoTaskMemHandle object to an native (unmanaged) array of pointers</returns>
|
||||
public SafeCoTaskMemHandle(IntPtr[] values) : base(values) { }
|
||||
|
@ -73,25 +111,17 @@ namespace Vanara.InteropServices
|
|||
/// <summary>Represents a NULL memory pointer.</summary>
|
||||
public static SafeCoTaskMemHandle Null => new SafeCoTaskMemHandle(IntPtr.Zero, 0, false);
|
||||
|
||||
/// <summary>Converts an <see cref="IntPtr"/> to a <see cref="SafeCoTaskMemHandle"/> where it owns the reference.</summary>
|
||||
/// <param name="ptr">The <see cref="IntPtr"/>.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator SafeCoTaskMemHandle(IntPtr ptr) => new SafeCoTaskMemHandle(ptr, 0, true);
|
||||
|
||||
/// <summary>Allocates from unmanaged memory sufficient memory to hold an object of type T.</summary>
|
||||
/// <typeparam name="T">Native type</typeparam>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns><see cref="SafeCoTaskMemHandle"/> object to an native (unmanaged) memory block the size of T.</returns>
|
||||
public static SafeCoTaskMemHandle CreateFromStructure<T>(in T value = default) => new SafeCoTaskMemHandle(InteropExtensions.MarshalToPtr(value, mm.AllocMem, out int s), s);
|
||||
|
||||
/// <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 precedes the trailing array into the unmanaged memory. ONLY structures with attribute StructLayout of
|
||||
/// LayoutKind.Sequential are supported.
|
||||
/// 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 precedes the trailing 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="values">Collection of structure objects</param>
|
||||
/// <param name="count">Number of items in <paramref name="values"/>. Setting this value to -1 will cause the method to get the count by iterating through <paramref name="values"/>.</param>
|
||||
/// <param name="count">
|
||||
/// Number of items in <paramref name="values"/>. Setting this value to -1 will cause the method to get the count by iterating
|
||||
/// through <paramref name="values"/>.
|
||||
/// </param>
|
||||
/// <param name="prefixBytes">Number of bytes preceding the trailing array of structures</param>
|
||||
/// <returns><see cref="SafeCoTaskMemHandle"/> object to an native (unmanaged) structure with a trail array of structures</returns>
|
||||
public static SafeCoTaskMemHandle CreateFromList<T>(IEnumerable<T> values, int count = -1, int prefixBytes = 0) => new SafeCoTaskMemHandle(InteropExtensions.MarshalToPtr(values, mm.AllocMem, out int s, prefixBytes), s);
|
||||
|
@ -101,7 +131,21 @@ namespace Vanara.InteropServices
|
|||
/// <param name="packing">The packing type for the strings.</param>
|
||||
/// <param name="charSet">The character set to use for the strings.</param>
|
||||
/// <param name="prefixBytes">Number of bytes preceding the trailing strings.</param>
|
||||
/// <returns><see cref="SafeCoTaskMemHandle"/> object to an native (unmanaged) array of strings stored using the <paramref name="packing"/> model and the character set defined by <paramref name="charSet"/>.</returns>
|
||||
/// <returns>
|
||||
/// <see cref="SafeCoTaskMemHandle"/> object to an native (unmanaged) array of strings stored using the <paramref name="packing"/>
|
||||
/// model and the character set defined by <paramref name="charSet"/>.
|
||||
/// </returns>
|
||||
public static SafeCoTaskMemHandle CreateFromStringList(IEnumerable<string> values, StringListPackMethod packing = StringListPackMethod.Concatenated, CharSet charSet = CharSet.Auto, int prefixBytes = 0) => new SafeCoTaskMemHandle(InteropExtensions.MarshalToPtr(values, packing, mm.AllocMem, out int s, charSet, prefixBytes), s);
|
||||
|
||||
/// <summary>Allocates from unmanaged memory sufficient memory to hold an object of type T.</summary>
|
||||
/// <typeparam name="T">Native type</typeparam>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns><see cref="SafeCoTaskMemHandle"/> object to an native (unmanaged) memory block the size of T.</returns>
|
||||
public static SafeCoTaskMemHandle CreateFromStructure<T>(in T value = default) => new SafeCoTaskMemHandle(InteropExtensions.MarshalToPtr(value, mm.AllocMem, out int s), s);
|
||||
|
||||
/// <summary>Converts an <see cref="IntPtr"/> to a <see cref="SafeCoTaskMemHandle"/> where it owns the reference.</summary>
|
||||
/// <param name="ptr">The <see cref="IntPtr"/>.</param>
|
||||
/// <returns>The result of the conversion.</returns>
|
||||
public static implicit operator SafeCoTaskMemHandle(IntPtr ptr) => new SafeCoTaskMemHandle(ptr, 0, true);
|
||||
}
|
||||
}
|
|
@ -12,27 +12,60 @@ namespace Vanara.InteropServices
|
|||
/// <seealso cref="IMemoryMethods"/>
|
||||
public sealed class HGlobalMemoryMethods : IMemoryMethods
|
||||
{
|
||||
/// <summary>Gets the allocation method.</summary>
|
||||
public Func<int, IntPtr> AllocMem => Marshal.AllocHGlobal;
|
||||
/// <summary>Gets the reallocation method.</summary>
|
||||
public Func<IntPtr, int, IntPtr> ReAllocMem => (p, i) => Marshal.ReAllocHGlobal(p, (IntPtr)i);
|
||||
/// <summary>Gets the free method.</summary>
|
||||
public Action<IntPtr> FreeMem => Marshal.FreeHGlobal;
|
||||
/// <summary>Gets the Unicode string allocation method.</summary>
|
||||
public Func<string, IntPtr> AllocStringUni => Marshal.StringToHGlobalUni;
|
||||
/// <summary>Gets the Ansi string allocation method.</summary>
|
||||
public Func<string, IntPtr> AllocStringAnsi => Marshal.StringToHGlobalAnsi;
|
||||
/// <summary>Gets the Unicode <see cref="SecureString"/> allocation method.</summary>
|
||||
public Func<SecureString, IntPtr> AllocSecureStringUni => Marshal.SecureStringToGlobalAllocUnicode;
|
||||
/// <summary>Gets the Ansi <see cref="SecureString"/> allocation method.</summary>
|
||||
public Func<SecureString, IntPtr> AllocSecureStringAnsi => Marshal.SecureStringToGlobalAllocAnsi;
|
||||
/// <summary>Gets the Unicode <see cref="SecureString"/> free method.</summary>
|
||||
public Action<IntPtr> FreeSecureStringUni => Marshal.ZeroFreeGlobalAllocUnicode;
|
||||
/// <summary>Gets the Ansi <see cref="SecureString"/> free method.</summary>
|
||||
public Action<IntPtr> FreeSecureStringAnsi => Marshal.ZeroFreeGlobalAllocAnsi;
|
||||
|
||||
/// <summary>Static instance to methods.</summary>
|
||||
public static IMemoryMethods Instance { get; } = new HGlobalMemoryMethods();
|
||||
|
||||
/// <summary>Gets a handle to a memory allocation of the specified size.</summary>
|
||||
/// <param name="size">The size, in bytes, of memory to allocate.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public IntPtr AllocMem(int size) => Marshal.AllocHGlobal(size);
|
||||
|
||||
/// <summary>Gets the Ansi <see cref="SecureString"/> allocation method.</summary>
|
||||
/// <param name="secureString">The secure string.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public IntPtr AllocSecureStringAnsi(SecureString secureString) => Marshal.SecureStringToGlobalAllocAnsi(secureString);
|
||||
|
||||
/// <summary>Gets the Unicode <see cref="SecureString"/> allocation method.</summary>
|
||||
/// <param name="secureString">The secure string.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public IntPtr AllocSecureStringUni(SecureString secureString) => Marshal.SecureStringToGlobalAllocUnicode(secureString);
|
||||
|
||||
/// <summary>Gets the Ansi string allocation method.</summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public IntPtr AllocStringAnsi(string value) => Marshal.StringToHGlobalAnsi(value);
|
||||
|
||||
/// <summary>Gets the Unicode string allocation method.</summary>
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public IntPtr AllocStringUni(string value) => Marshal.StringToHGlobalUni(value);
|
||||
|
||||
/// <summary>Frees the memory associated with a handle.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
public void FreeMem(IntPtr hMem) => Marshal.FreeHGlobal(hMem);
|
||||
|
||||
/// <summary>Gets the Ansi <see cref="SecureString"/> free method.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
public void FreeSecureStringAnsi(IntPtr hMem) => Marshal.ZeroFreeGlobalAllocAnsi(hMem);
|
||||
|
||||
/// <summary>Gets the Unicode <see cref="SecureString"/> free method.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
public void FreeSecureStringUni(IntPtr hMem) => Marshal.ZeroFreeGlobalAllocUnicode(hMem);
|
||||
|
||||
/// <summary>Locks the memory of a specified handle and gets a pointer to it.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
/// <returns>A pointer to the locked memory.</returns>
|
||||
public IntPtr LockMem(IntPtr hMem) => hMem;
|
||||
|
||||
/// <summary>Gets the reallocation method.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
/// <param name="size">The size, in bytes, of memory to allocate.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public IntPtr ReAllocMem(IntPtr hMem, int size) => Marshal.ReAllocHGlobal(hMem, (IntPtr)size);
|
||||
|
||||
/// <summary>Unlocks the memory of a specified handle.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
public void UnlockMem(IntPtr hMem) { }
|
||||
}
|
||||
|
||||
/// <summary>A <see cref="SafeHandle"/> for memory allocated via LocalAlloc.</summary>
|
||||
|
|
|
@ -28,25 +28,38 @@ namespace Vanara.InteropServices
|
|||
public interface IMemoryMethods : ISimpleMemoryMethods
|
||||
{
|
||||
/// <summary>Gets the Ansi <see cref="SecureString"/> allocation method.</summary>
|
||||
Func<SecureString, IntPtr> AllocSecureStringAnsi { get; }
|
||||
/// <param name="secureString">The secure string.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
IntPtr AllocSecureStringAnsi(SecureString secureString);
|
||||
|
||||
/// <summary>Gets the Unicode <see cref="SecureString"/> allocation method.</summary>
|
||||
Func<SecureString, IntPtr> AllocSecureStringUni { get; }
|
||||
/// <param name="secureString">The secure string.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
IntPtr AllocSecureStringUni(SecureString secureString);
|
||||
|
||||
/// <summary>Gets the Ansi string allocation method.</summary>
|
||||
Func<string, IntPtr> AllocStringAnsi { get; }
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
IntPtr AllocStringAnsi(string value);
|
||||
|
||||
/// <summary>Gets the Unicode string allocation method.</summary>
|
||||
Func<string, IntPtr> AllocStringUni { get; }
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
IntPtr AllocStringUni(string value);
|
||||
|
||||
/// <summary>Gets the Ansi <see cref="SecureString"/> free method.</summary>
|
||||
Action<IntPtr> FreeSecureStringAnsi { get; }
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
void FreeSecureStringAnsi(IntPtr hMem);
|
||||
|
||||
/// <summary>Gets the Unicode <see cref="SecureString"/> free method.</summary>
|
||||
Action<IntPtr> FreeSecureStringUni { get; }
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
void FreeSecureStringUni(IntPtr hMem);
|
||||
|
||||
/// <summary>Gets the reallocation method.</summary>
|
||||
Func<IntPtr, int, IntPtr> ReAllocMem { get; }
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
/// <param name="size">The size, in bytes, of memory to allocate.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
IntPtr ReAllocMem(IntPtr hMem, int size);
|
||||
}
|
||||
|
||||
/// <summary>Interface for classes that support safe memory pointers.</summary>
|
||||
|
@ -135,48 +148,91 @@ namespace Vanara.InteropServices
|
|||
/// <summary>Interface to capture unmanaged simple (alloc/free) memory methods.</summary>
|
||||
public interface ISimpleMemoryMethods
|
||||
{
|
||||
/// <summary>Gets the allocation method.</summary>
|
||||
Func<int, IntPtr> AllocMem { get; }
|
||||
/// <summary>Gets a handle to a memory allocation of the specified size.</summary>
|
||||
/// <param name="size">The size, in bytes, of memory to allocate.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
IntPtr AllocMem(int size);
|
||||
|
||||
/// <summary>Gets the free method.</summary>
|
||||
Action<IntPtr> FreeMem { get; }
|
||||
/// <summary>Frees the memory associated with a handle.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
void FreeMem(IntPtr hMem);
|
||||
|
||||
/// <summary>Locks the memory of a specified handle and gets a pointer to it.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
/// <returns>A pointer to the locked memory.</returns>
|
||||
IntPtr LockMem(IntPtr hMem);
|
||||
|
||||
/// <summary>Unlocks the memory of a specified handle.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
void UnlockMem(IntPtr hMem);
|
||||
}
|
||||
|
||||
/// <summary>Implementation of <see cref="IMemoryMethods"/> using just the methods from <see cref="ISimpleMemoryMethods"/>.</summary>
|
||||
/// <typeparam name="TSimple">The type of the simple.</typeparam>
|
||||
/// <seealso cref="Vanara.InteropServices.IMemoryMethods"/>
|
||||
public class MemoryMethodsFromSimple<TSimple> : IMemoryMethods where TSimple : ISimpleMemoryMethods, new()
|
||||
public abstract class MemoryMethodsBase : IMemoryMethods
|
||||
{
|
||||
/// <summary>A static instance of TSimple.</summary>
|
||||
public static TSimple SimpleInstance = new TSimple();
|
||||
/// <summary>
|
||||
/// Gets a handle to a memory allocation of the specified size.
|
||||
/// </summary>
|
||||
/// <param name="size">The size, in bytes, of memory to allocate.</param>
|
||||
/// <returns>
|
||||
/// A memory handle.
|
||||
/// </returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public abstract IntPtr AllocMem(int size);
|
||||
|
||||
/// <summary>Gets the Ansi <see cref="SecureString"/> allocation method.</summary>
|
||||
public Func<SecureString, IntPtr> AllocSecureStringAnsi => s => StringHelper.AllocSecureString(s, CharSet.Ansi, AllocMem);
|
||||
/// <param name="secureString">The secure string.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public virtual IntPtr AllocSecureStringAnsi(SecureString secureString) => StringHelper.AllocSecureString(secureString, CharSet.Ansi, AllocMem);
|
||||
|
||||
/// <summary>Gets the Unicode <see cref="SecureString"/> allocation method.</summary>
|
||||
public Func<SecureString, IntPtr> AllocSecureStringUni => s => StringHelper.AllocSecureString(s, CharSet.Unicode, AllocMem);
|
||||
/// <param name="secureString">The secure string.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public virtual IntPtr AllocSecureStringUni(SecureString secureString) => StringHelper.AllocSecureString(secureString, CharSet.Unicode, AllocMem);
|
||||
|
||||
/// <summary>Gets the Ansi string allocation method.</summary>
|
||||
public Func<string, IntPtr> AllocStringAnsi => s => StringHelper.AllocString(s, CharSet.Ansi, AllocMem);
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public virtual IntPtr AllocStringAnsi(string value) => StringHelper.AllocString(value, CharSet.Ansi, AllocMem);
|
||||
|
||||
/// <summary>Gets the Unicode string allocation method.</summary>
|
||||
public Func<string, IntPtr> AllocStringUni => s => StringHelper.AllocString(s, CharSet.Unicode, AllocMem);
|
||||
/// <param name="value">The value.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public virtual IntPtr AllocStringUni(string value) => StringHelper.AllocString(value, CharSet.Unicode, AllocMem);
|
||||
|
||||
/// <summary>Frees the memory associated with a handle.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
public abstract void FreeMem(IntPtr hMem);
|
||||
|
||||
/// <summary>Gets the Ansi <see cref="SecureString"/> free method.</summary>
|
||||
public Action<IntPtr> FreeSecureStringAnsi => FreeMem;
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
public virtual void FreeSecureStringAnsi(IntPtr hMem) => FreeMem(hMem);
|
||||
|
||||
/// <summary>Gets the Unicode <see cref="SecureString"/> free method.</summary>
|
||||
public Action<IntPtr> FreeSecureStringUni => FreeMem;
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
public virtual void FreeSecureStringUni(IntPtr hMem) => FreeMem(hMem);
|
||||
|
||||
/// <summary>Locks the memory of a specified handle and gets a pointer to it.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
/// <returns>A pointer to the locked memory.</returns>
|
||||
public virtual IntPtr LockMem(IntPtr hMem) => hMem;
|
||||
|
||||
/// <summary>Gets the reallocation method.</summary>
|
||||
/// <exception cref="System.NotImplementedException"></exception>
|
||||
public Func<IntPtr, int, IntPtr> ReAllocMem => throw new NotImplementedException();
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
/// <param name="size">The size, in bytes, of memory to allocate.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public virtual IntPtr ReAllocMem(IntPtr hMem, int size)
|
||||
{
|
||||
var hNew = AllocMem(size);
|
||||
hMem.CopyTo(hNew, size);
|
||||
FreeMem(hMem);
|
||||
return hNew;
|
||||
}
|
||||
|
||||
/// <summary>Gets the allocation method.</summary>
|
||||
public Func<int, IntPtr> AllocMem => SimpleInstance.AllocMem;
|
||||
|
||||
/// <summary>Gets the free method.</summary>
|
||||
public Action<IntPtr> FreeMem => SimpleInstance.FreeMem;
|
||||
/// <summary>Unlocks the memory of a specified handle.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
public virtual void UnlockMem(IntPtr hMem) { }
|
||||
}
|
||||
|
||||
/// <summary>Abstract base class for all SafeHandle derivatives that encapsulate handling unmanaged memory.</summary>
|
||||
|
|
|
@ -5845,41 +5845,27 @@ namespace Vanara.PInvoke
|
|||
|
||||
/// <summary>Standard crypto memory allocation methods.</summary>
|
||||
/// <seealso cref="Vanara.InteropServices.IMemoryMethods"/>
|
||||
public class CryptMemMethods : IMemoryMethods
|
||||
public class CryptMemMethods : MemoryMethodsBase
|
||||
{
|
||||
/// <summary>Gets a static instance of this class.</summary>
|
||||
public static readonly CryptMemMethods Instance = new CryptMemMethods();
|
||||
|
||||
/// <summary>Gets the allocation method.</summary>
|
||||
public Func<int, IntPtr> AllocMem => i => CryptMemAlloc((uint)i);
|
||||
|
||||
/// <summary>Gets the Ansi <see cref="T:System.Security.SecureString"/> allocation method.</summary>
|
||||
/// <summary>Gets a handle to a memory allocation of the specified size.</summary>
|
||||
/// <param name="size">The size, in bytes, of memory to allocate.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public Func<SecureString, IntPtr> AllocSecureStringAnsi => throw new NotImplementedException();
|
||||
public override IntPtr AllocMem(int size) => Win32Error.ThrowLastErrorIfNull(CryptMemAlloc((uint)size));
|
||||
|
||||
/// <summary>Gets the Unicode <see cref="T:System.Security.SecureString"/> allocation method.</summary>
|
||||
/// <summary>Frees the memory associated with a handle.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public Func<SecureString, IntPtr> AllocSecureStringUni => throw new NotImplementedException();
|
||||
|
||||
/// <summary>Gets the Ansi string allocation method.</summary>
|
||||
public Func<string, IntPtr> AllocStringAnsi => s => StringHelper.AllocString(s, CharSet.Ansi, AllocMem);
|
||||
|
||||
/// <summary>Gets the Unicode string allocation method.</summary>
|
||||
public Func<string, IntPtr> AllocStringUni => s => StringHelper.AllocString(s, CharSet.Unicode, AllocMem);
|
||||
|
||||
/// <summary>Gets the free method.</summary>
|
||||
public Action<IntPtr> FreeMem => CryptMemFree;
|
||||
|
||||
/// <summary>Gets the Ansi <see cref="T:System.Security.SecureString"/> free method.</summary>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public Action<IntPtr> FreeSecureStringAnsi => throw new NotImplementedException();
|
||||
|
||||
/// <summary>Gets the Unicode <see cref="T:System.Security.SecureString"/> free method.</summary>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public Action<IntPtr> FreeSecureStringUni => throw new NotImplementedException();
|
||||
public override void FreeMem(IntPtr hMem) => CryptMemFree(hMem);
|
||||
|
||||
/// <summary>Gets the reallocation method.</summary>
|
||||
public Func<IntPtr, int, IntPtr> ReAllocMem => (p, i) => CryptMemRealloc(p, (uint)i);
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
/// <param name="size">The size, in bytes, of memory to allocate.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public override IntPtr ReAllocMem(IntPtr hMem, int size) => Win32Error.ThrowLastErrorIfNull(CryptMemRealloc(hMem, (uint)size));
|
||||
}
|
||||
|
||||
/// <summary>Safe handle for crypto memory.</summary>
|
||||
|
|
|
@ -1445,8 +1445,24 @@ namespace Vanara.PInvoke
|
|||
internal class DnsProxyStringMem : ISimpleMemoryMethods
|
||||
{
|
||||
private bool self = false;
|
||||
public Func<int, IntPtr> AllocMem => s => { self = true; return Marshal.AllocCoTaskMem(s); };
|
||||
public Action<IntPtr> FreeMem => p => { if (self) Marshal.FreeCoTaskMem(p); else DnsFreeProxyName(p); };
|
||||
|
||||
/// <summary>Gets a handle to a memory allocation of the specified size.</summary>
|
||||
/// <param name="size">The size, in bytes, of memory to allocate.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public IntPtr AllocMem(int size) { self = true; return Marshal.AllocCoTaskMem(size); }
|
||||
|
||||
/// <summary>Frees the memory associated with a handle.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
public void FreeMem(IntPtr hMem) { if (self) Marshal.FreeCoTaskMem(hMem); else DnsFreeProxyName(hMem); }
|
||||
|
||||
/// <summary>Locks the memory of a specified handle and gets a pointer to it.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
/// <returns>A pointer to the locked memory.</returns>
|
||||
public IntPtr LockMem(IntPtr hMem) => hMem;
|
||||
|
||||
/// <summary>Unlocks the memory of a specified handle.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
public void UnlockMem(IntPtr hMem) { }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1380,40 +1380,28 @@ namespace Vanara.PInvoke
|
|||
|
||||
/// <summary>Unmanaged memory methods for a heap.</summary>
|
||||
/// <seealso cref="IMemoryMethods"/>
|
||||
public sealed class HeapMemoryMethods : IMemoryMethods
|
||||
public sealed class HeapMemoryMethods : MemoryMethodsBase
|
||||
{
|
||||
/// <summary>Gets a static instance of this class.</summary>
|
||||
/// <value>The instance.</value>
|
||||
public static IMemoryMethods Instance { get; } = new HeapMemoryMethods();
|
||||
|
||||
/// <summary>Gets the allocation method.</summary>
|
||||
public Func<int, IntPtr> AllocMem => i => { var o = HeapAllocInternal(HeapHandle, 0, i); return o != IntPtr.Zero ? o : throw Win32Error.GetLastError().GetException(); };
|
||||
internal HHEAP HeapHandle { get; set; } = GetProcessHeap();
|
||||
|
||||
/// <summary>Gets the Ansi <see cref="SecureString"/> allocation method.</summary>
|
||||
public Func<SecureString, IntPtr> AllocSecureStringAnsi => s => StringHelper.AllocSecureString(s, CharSet.Ansi, AllocMem);
|
||||
/// <summary>Gets a handle to a memory allocation of the specified size.</summary>
|
||||
/// <param name="size">The size, in bytes, of memory to allocate.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public override IntPtr AllocMem(int size) => Win32Error.ThrowLastErrorIfNull((IntPtr)HeapAllocInternal(HeapHandle, 0, size));
|
||||
|
||||
/// <summary>Gets the Unicode <see cref="SecureString"/> allocation method.</summary>
|
||||
public Func<SecureString, IntPtr> AllocSecureStringUni => s => StringHelper.AllocSecureString(s, CharSet.Unicode, AllocMem);
|
||||
|
||||
/// <summary>Gets the Ansi string allocation method.</summary>
|
||||
public Func<string, IntPtr> AllocStringAnsi => s => StringHelper.AllocString(s, CharSet.Ansi, AllocMem);
|
||||
|
||||
/// <summary>Gets the Unicode string allocation method.</summary>
|
||||
public Func<string, IntPtr> AllocStringUni => s => StringHelper.AllocString(s, CharSet.Unicode, AllocMem);
|
||||
|
||||
/// <summary>Gets the free method.</summary>
|
||||
public Action<IntPtr> FreeMem => p => HeapFree(HeapHandle, 0, p);
|
||||
|
||||
/// <summary>Gets the Ansi <see cref="SecureString"/> free method.</summary>
|
||||
public Action<IntPtr> FreeSecureStringAnsi => p => StringHelper.FreeSecureString(p, GetSize(p), FreeMem);
|
||||
|
||||
/// <summary>Gets the Unicode <see cref="SecureString"/> free method.</summary>
|
||||
public Action<IntPtr> FreeSecureStringUni => p => StringHelper.FreeSecureString(p, GetSize(p), FreeMem);
|
||||
/// <summary>Frees the memory associated with a handle.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
public override void FreeMem(IntPtr hMem) => HeapFree(HeapHandle, 0, hMem);
|
||||
|
||||
/// <summary>Gets the reallocation method.</summary>
|
||||
public Func<IntPtr, int, IntPtr> ReAllocMem => (p, i) => { var o = HeapReAllocInternal(HeapHandle, 0, p, i); return o != IntPtr.Zero ? o : throw Win32Error.GetLastError().GetException(); };
|
||||
|
||||
internal HHEAP HeapHandle { get; set; } = GetProcessHeap();
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
/// <param name="size">The size, in bytes, of memory to allocate.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public override IntPtr ReAllocMem(IntPtr hMem, int size) => Win32Error.ThrowLastErrorIfNull((IntPtr)HeapReAllocInternal(HeapHandle, 0, hMem, size));
|
||||
|
||||
private int GetSize(IntPtr ptr) => (int)HeapSize(HeapHandle, 0, ptr).Value;
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security;
|
||||
using Vanara.Extensions;
|
||||
using Vanara.PInvoke;
|
||||
using static Vanara.PInvoke.Kernel32;
|
||||
|
@ -11,37 +10,25 @@ namespace Vanara.InteropServices
|
|||
{
|
||||
/// <summary>Unmanaged memory methods for local heap.</summary>
|
||||
/// <seealso cref="IMemoryMethods"/>
|
||||
public sealed class LocalMemoryMethods : IMemoryMethods
|
||||
public sealed class LocalMemoryMethods : MemoryMethodsBase
|
||||
{
|
||||
/// <summary>Gets the allocation method.</summary>
|
||||
public Func<int, IntPtr> AllocMem => i => { var o = LocalAlloc(LMEM.LPTR, i); return !o.IsNull ? (IntPtr)o : throw Win32Error.GetLastError().GetException(); };
|
||||
|
||||
/// <summary>Gets the Ansi <see cref="SecureString"/> allocation method.</summary>
|
||||
public Func<SecureString, IntPtr> AllocSecureStringAnsi => s => StringHelper.AllocSecureString(s, CharSet.Ansi, AllocMem);
|
||||
|
||||
/// <summary>Gets the Unicode <see cref="SecureString"/> allocation method.</summary>
|
||||
public Func<SecureString, IntPtr> AllocSecureStringUni => s => StringHelper.AllocSecureString(s, CharSet.Unicode, AllocMem);
|
||||
|
||||
/// <summary>Gets the Ansi string allocation method.</summary>
|
||||
public Func<string, IntPtr> AllocStringAnsi => s => StringHelper.AllocString(s, CharSet.Ansi, AllocMem);
|
||||
|
||||
/// <summary>Gets the Unicode string allocation method.</summary>
|
||||
public Func<string, IntPtr> AllocStringUni => s => StringHelper.AllocString(s, CharSet.Unicode, AllocMem);
|
||||
|
||||
/// <summary>Gets the free method.</summary>
|
||||
public Action<IntPtr> FreeMem => p => LocalFree(p);
|
||||
|
||||
/// <summary>Gets the Ansi <see cref="SecureString"/> free method.</summary>
|
||||
public Action<IntPtr> FreeSecureStringAnsi => p => StringHelper.FreeSecureString(p, LocalSize(p), FreeMem);
|
||||
|
||||
/// <summary>Gets the Unicode <see cref="SecureString"/> free method.</summary>
|
||||
public Action<IntPtr> FreeSecureStringUni => p => StringHelper.FreeSecureString(p, LocalSize(p), FreeMem);
|
||||
|
||||
/// <summary>Gets the reallocation method.</summary>
|
||||
public Func<IntPtr, int, IntPtr> ReAllocMem => (p, i) => { var o = LocalReAlloc(p, i, LMEM.LMEM_MOVEABLE); return !o.IsNull ? (IntPtr)o : throw Win32Error.GetLastError().GetException(); };
|
||||
|
||||
/// <summary>Gets a static instance of these methods.</summary>
|
||||
public static readonly IMemoryMethods Instance = new LocalMemoryMethods();
|
||||
|
||||
/// <summary>Gets a handle to a memory allocation of the specified size.</summary>
|
||||
/// <param name="size">The size, in bytes, of memory to allocate.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public override IntPtr AllocMem(int size) => Win32Error.ThrowLastErrorIfNull((IntPtr)LocalAlloc(LMEM.LPTR, size));
|
||||
|
||||
/// <summary>Frees the memory associated with a handle.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
public override void FreeMem(IntPtr hMem) => LocalFree(hMem);
|
||||
|
||||
/// <summary>Gets the reallocation method.</summary>
|
||||
/// <param name="hMem">A memory handle.</param>
|
||||
/// <param name="size">The size, in bytes, of memory to allocate.</param>
|
||||
/// <returns>A memory handle.</returns>
|
||||
public override IntPtr ReAllocMem(IntPtr hMem, int size) => Win32Error.ThrowLastErrorIfNull((IntPtr)LocalReAlloc(hMem, size, LMEM.LMEM_FIXED | LMEM.LMEM_ZEROINIT));
|
||||
}
|
||||
|
||||
/// <summary>A <see cref="SafeHandle"/> for memory allocated via LocalAlloc.</summary>
|
||||
|
|
|
@ -100,6 +100,21 @@ namespace Vanara.PInvoke
|
|||
[System.Diagnostics.DebuggerStepThrough]
|
||||
public static void ThrowLastError(string message = null) => GetLastError().ThrowIfFailed(message);
|
||||
|
||||
/// <summary>Throws the last error if the function returns <see langword="false"/>.</summary>
|
||||
/// <param name="value">The value to check.</param>
|
||||
/// <param name="message">The message.</param>
|
||||
public static bool ThrowLastErrorIfFalse(bool value, string message = null) => CheckPredicateOrThrow(value, v => !v, message);
|
||||
|
||||
/// <summary>Throws the last error if the value is an invalid handle.</summary>
|
||||
/// <param name="value">The SafeHandle to check.</param>
|
||||
/// <param name="message">The message.</param>
|
||||
public static SafeHandle ThrowLastErrorIfInvalid(SafeHandle value, string message = null) => CheckPredicateOrThrow(value, v => v.IsInvalid, message);
|
||||
|
||||
/// <summary>Throws the last error if the value is a NULL pointer (IntPtr.Zero).</summary>
|
||||
/// <param name="value">The pointer to check.</param>
|
||||
/// <param name="message">The message.</param>
|
||||
public static IntPtr ThrowLastErrorIfNull(IntPtr value, string message = null) => CheckPredicateOrThrow(value, v => v == IntPtr.Zero, message);
|
||||
|
||||
/// <summary>Throws if the last error failed, unless the error is the specified value.</summary>
|
||||
/// <param name="exception">The failure code to ignore.</param>
|
||||
/// <param name="message">The message to associate with the exception.</param>
|
||||
|
@ -226,6 +241,13 @@ namespace Vanara.PInvoke
|
|||
|
||||
ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)value).ToUInt64(provider);
|
||||
|
||||
private static T CheckPredicateOrThrow<T>(T value, Func<T, bool> failure, string message)
|
||||
{
|
||||
if (failure(value))
|
||||
GetLastError().ThrowIfFailed(message);
|
||||
return value;
|
||||
}
|
||||
|
||||
private static uint? ValueFromObj(object obj)
|
||||
{
|
||||
if (obj == null) return null;
|
||||
|
|
Loading…
Reference in New Issue