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