From 9fbc0a17502aa06fab0ce28cff05f4b7c33f3a39 Mon Sep 17 00:00:00 2001 From: dahall Date: Wed, 9 Sep 2020 17:41:42 -0600 Subject: [PATCH] Added SafeDRT_DATA to DRT --- PInvoke/Drt/Drt.cs | 96 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 91 insertions(+), 5 deletions(-) diff --git a/PInvoke/Drt/Drt.cs b/PInvoke/Drt/Drt.cs index 965d2dea..2c0d9163 100644 --- a/PInvoke/Drt/Drt.cs +++ b/PInvoke/Drt/Drt.cs @@ -1,6 +1,8 @@ using System; +using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; +using Vanara.Extensions; using Vanara.InteropServices; using static Vanara.PInvoke.Crypt32; using static Vanara.PInvoke.Ws2_32; @@ -1728,7 +1730,7 @@ namespace Vanara.PInvoke [StructLayout(LayoutKind.Sequential)] public struct DRT_BOOTSTRAP_RESOLVE_CONTEXT : IHandle { - private IntPtr handle; + private readonly IntPtr handle; /// Initializes a new instance of the struct. /// An object that represents the pre-existing handle to use. @@ -2146,7 +2148,7 @@ namespace Vanara.PInvoke [StructLayout(LayoutKind.Sequential)] public struct HDRT : IHandle { - private IntPtr handle; + private readonly IntPtr handle; /// Initializes a new instance of the struct. /// An object that represents the pre-existing handle to use. @@ -2194,7 +2196,7 @@ namespace Vanara.PInvoke [StructLayout(LayoutKind.Sequential)] public struct HDRT_REGISTRATION_CONTEXT : IHandle { - private IntPtr handle; + private readonly IntPtr handle; /// Initializes a new instance of the struct. /// An object that represents the pre-existing handle to use. @@ -2242,7 +2244,7 @@ namespace Vanara.PInvoke [StructLayout(LayoutKind.Sequential)] public struct HDRT_SEARCH_CONTEXT : IHandle { - private IntPtr handle; + private readonly IntPtr handle; /// Initializes a new instance of the struct. /// An object that represents the pre-existing handle to use. @@ -2290,7 +2292,7 @@ namespace Vanara.PInvoke [StructLayout(LayoutKind.Sequential)] public struct HDRT_TRANSPORT : IHandle { - private IntPtr handle; + private readonly IntPtr handle; /// Initializes a new instance of the struct. /// An object that represents the pre-existing handle to use. @@ -2333,5 +2335,89 @@ namespace Vanara.PInvoke /// public IntPtr DangerousGetHandle() => handle; } + + /// + /// The DRT_DATA structure contains an arbitrary array of bytes. The structure definition includes aliases appropriate to the various + /// functions that use it. + /// + [PInvokeData("wincrypt.h")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public class SafeDRT_DATA : IDisposable + { + /// A DWORD variable that contains the count, in bytes, of data. + private uint cb; + + /// A pointer to the data buffer. + private IntPtr pb; + + /// Initializes a new instance of the class. + /// The size, in bytes, to allocate. + public SafeDRT_DATA(int size) + { + cb = (uint)size; + if (size > 0) + pb = MemMethods.AllocMem(size); + } + + /// Initializes a new instance of the class. + /// The bytes to copy into the blob. + public SafeDRT_DATA(byte[] bytes) : this(bytes?.Length ?? 0) => Marshal.Copy(bytes, 0, pb, bytes.Length); + + /// Initializes a new instance of the class with a string. + /// The string value. + /// The character set to use. + public SafeDRT_DATA(string value, CharSet charSet = CharSet.Ansi) : this(StringHelper.GetBytes(value, true, charSet)) + { + } + + private SafeDRT_DATA(IntPtr handle, int size) + { + pb = handle; + cb = (uint)size; + } + + /// Represents an empty instance of a blob. + public static readonly SafeDRT_DATA Empty = new SafeDRT_DATA(IntPtr.Zero, 0); + + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + public void Dispose() + { + MemMethods.FreeMem(pb); + pb = IntPtr.Zero; + cb = 0; + } + + /// Allocates from unmanaged memory sufficient memory to hold an object of type T. + /// Native type + /// The value. + /// object to an native (unmanaged) memory block the size of T. + public static SafeDRT_DATA CreateFromStructure(in T value = default) => new SafeDRT_DATA(InteropExtensions.MarshalToPtr(value, MemMethods.AllocMem, out var s), s); + + /// + /// 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. + /// + /// Type of the trailing array of structures + /// Collection of structure objects + /// Number of bytes preceding the trailing array of structures + /// object to an native (unmanaged) structure with a trail array of structures + public static SafeDRT_DATA CreateFromList(IEnumerable values, int prefixBytes = 0) => + new SafeDRT_DATA(InteropExtensions.MarshalToPtr(values, MemMethods.AllocMem, out var s, prefixBytes), s); + + /// Allocates from unmanaged memory sufficient memory to hold an array of strings. + /// The list of strings. + /// The packing type for the strings. + /// The character set to use for the strings. + /// Number of bytes preceding the trailing strings. + /// + /// object to an native (unmanaged) array of strings stored using the model and the character set defined by . + /// + public static SafeDRT_DATA CreateFromStringList(IEnumerable values, StringListPackMethod packing = StringListPackMethod.Concatenated, CharSet charSet = CharSet.Auto, int prefixBytes = 0) => + new SafeDRT_DATA(InteropExtensions.MarshalToPtr(values, packing, MemMethods.AllocMem, out var s, charSet, prefixBytes), s); + + private static IMemoryMethods MemMethods => HGlobalMemoryMethods.Instance; + } } } \ No newline at end of file