Compare commits

...

5 Commits

Author SHA1 Message Date
David Hall 428e7b4e85 Added nullability to WinTrust 2023-10-23 09:38:29 -06:00
David Hall dfb673fe79 Added nullability to Wer 2023-10-23 08:02:50 -06:00
David Hall c91314e0a9 Added nullability to WebSocket, added some overloads, and created test 2023-10-23 07:49:31 -06:00
David Hall 661d4acdeb Added ability to IntPtr.Convert extension to handle all value type arrays. 2023-10-23 07:47:34 -06:00
David Hall b429b0e793 Added nullability to WcnApi 2023-10-22 15:12:23 -06:00
9 changed files with 430 additions and 72 deletions

View File

@ -42,9 +42,15 @@ public static class IntPtrConverter
}
if (sz == 0) throw new ArgumentException("Cannot convert a pointer with no Size.", nameof(sz));
// Handle byte array and string as special cases
if (destType.IsArray && destType.GetElementType() == typeof(byte))
return ptr.ToByteArray((int)sz);
// Handle array and string as special cases
if (destType.IsArray)
{
Type elemType = destType.GetElementType()!;
if (elemType == typeof(byte))
return ptr.ToByteArray((int)sz, 0, sz);
int elemSz = Marshal.SizeOf(elemType);
return ptr.ToArray(elemType, (int)sz / elemSz, 0, sz);
}
if (destType == typeof(string))
return StringHelper.GetString(ptr, charSet, sz);
return ptr.ToStructure(destType, sz, 0, out _);

View File

@ -158,7 +158,7 @@ public static partial class WcnApi
// https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/nf-wcndevice-iwcndevice-setpassword HRESULT SetPassword(
// WCN_PASSWORD_TYPE Type, DWORD dwPasswordLength, const BYTE [] pbPassword );
[PreserveSig]
HRESULT SetPassword(WCN_PASSWORD_TYPE Type, uint dwPasswordLength, [MarshalAs(UnmanagedType.LPStr)] string pbPassword);
HRESULT SetPassword(WCN_PASSWORD_TYPE Type, uint dwPasswordLength, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] pbPassword);
/// <summary>The <c>IWCNDevice::Connect</c> method initiates the session.</summary>
/// <param name="pNotify">
@ -198,7 +198,7 @@ public static partial class WcnApi
// https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/nf-wcndevice-iwcndevice-connect HRESULT Connect(
// IWCNConnectNotify *pNotify );
[PreserveSig]
HRESULT Connect([In, Optional] IWCNConnectNotify pNotify);
HRESULT Connect([In, Optional] IWCNConnectNotify? pNotify);
/// <summary>The <c>IWCNDevice::GetAttribute</c> method gets a cached attribute from the device.</summary>
/// <param name="AttributeType">
@ -235,7 +235,7 @@ public static partial class WcnApi
// https://docs.microsoft.com/en-us/windows/win32/api/wcndevice/nf-wcndevice-iwcndevice-getattribute HRESULT GetAttribute(
// WCN_ATTRIBUTE_TYPE AttributeType, DWORD dwMaxBufferSize, BYTE [] pbBuffer, DWORD *pdwBufferUsed );
[PreserveSig]
HRESULT GetAttribute(WCN_ATTRIBUTE_TYPE AttributeType, uint dwMaxBufferSize, [Out] IntPtr pbBuffer, out uint pdwBufferUsed);
HRESULT GetAttribute(WCN_ATTRIBUTE_TYPE AttributeType, [In, Optional] uint dwMaxBufferSize, [Out, Optional] IntPtr pbBuffer, out uint pdwBufferUsed);
/// <summary>The GetIntegerAttribute method gets a cached attribute from the device as an integer.</summary>
/// <param name="AttributeType">
@ -498,7 +498,7 @@ public static partial class WcnApi
public static T GetIntegerAttribute<T>(this IWCNDevice iDev, WCN_ATTRIBUTE_TYPE AttributeType) where T : struct, IConvertible
{
var hr = iDev.GetIntegerAttribute(AttributeType, out var u);
return hr.Succeeded ? (T)Convert.ChangeType(u, typeof(T)) : throw hr.GetException();
return hr.Succeeded ? (T)Convert.ChangeType(u, typeof(T)) : throw hr.GetException()!;
}
/// <summary>The <c>WCN_VENDOR_EXTENSION_SPEC</c> structure contains data that defines a vendor extension.</summary>

View File

@ -458,10 +458,146 @@ public static partial class WebSocket
// *pulAdditionalHeaderCount );
[PInvokeData("websocket.h", MSDNShortId = "NF:websocket.WebSocketBeginClientHandshake")]
[DllImport(Lib_Websocket, SetLastError = false, ExactSpelling = true)]
public static extern HRESULT WebSocketBeginClientHandshake([In] WEB_SOCKET_HANDLE hWebSocket, [In, Optional, MarshalAs(UnmanagedType.LPStr)] string? pszSubprotocols,
[Optional] uint ulSubprotocolCount, [In, Optional, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string? pszExtensions, [Optional] uint ulExtensionCount,
public static extern HRESULT WebSocketBeginClientHandshake([In] WEB_SOCKET_HANDLE hWebSocket, [In, Optional, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[]? pszSubprotocols,
[Optional] uint ulSubprotocolCount, [In, Optional, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[]? pszExtensions, [Optional] uint ulExtensionCount,
[In, Optional, MarshalAs(UnmanagedType.LPArray)] WEB_SOCKET_HTTP_HEADER[]? pInitialHeaders, [Optional] uint ulInitialHeaderCount,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 8)] out WEB_SOCKET_HTTP_HEADER[] pAdditionalHeaders, out uint pulAdditionalHeaderCount);
out IntPtr pAdditionalHeaders, out uint pulAdditionalHeaderCount);
/// <summary>The <c>WebSocketBeginClientHandshake</c> function begins the client-side handshake.</summary>
/// <param name="hWebSocket">
/// <para>Type: <c>WEB_SOCKET_HANDLE</c></para>
/// <para>WebSocket session handle returned by a previous call to WebSocketCreateClientHandle.</para>
/// </param>
/// <param name="pszSubprotocols">
/// <para>Type: <c>PCSTR*</c></para>
/// <para>
/// Pointer to an array of sub-protocols chosen by the application. Once the client-server handshake is complete, the application must
/// use the sub-protocol returned by WebSocketEndClientHandshake. Must contain one subprotocol per entry.
/// </para>
/// </param>
/// <param name="ulSubprotocolCount">
/// <para>Type: <c>ULONG</c></para>
/// <para>Number of sub-protocols in <c>pszSubprotocols</c>.</para>
/// </param>
/// <param name="pszExtensions">
/// <para>Type: <c>PCSTR*</c></para>
/// <para>
/// Pointer to an array of extensions chosen by the application. Once the client-server handshake is complete, the application must use
/// the extension returned by WebSocketEndClientHandshake. Must contain one extension per entry.
/// </para>
/// </param>
/// <param name="ulExtensionCount">
/// <para>Type: <c>ULONG</c></para>
/// <para>Number of extensions in <c>pszExtensions</c>.</para>
/// </param>
/// <param name="pInitialHeaders">
/// <para>Type: <c>const PWEB_SOCKET_HTTP_HEADER</c></para>
/// <para>
/// Pointer to an array of WEB_SOCKET_HTTP_HEADER structures that contain the request headers to be sent by the application. The array
/// must include the <c>Host HTTP</c> header as defined in RFC 2616.
/// </para>
/// </param>
/// <param name="ulInitialHeaderCount">
/// <para>Type: <c>ULONG</c></para>
/// <para>Number of request headers in <c>pInitialHeaders</c>.</para>
/// </param>
/// <param name="pAdditionalHeaders">
/// <para>Type: <c>PWEB_SOCKET_HTTP_HEADER</c></para>
/// <para>
/// On successful output, an array of WEB_SOCKET_HTTP_HEADER structures that contain the request headers to be sent by the
/// application. If any of these headers were specified in <c>pInitialHeaders</c>, the header must be replaced.
/// </para>
/// </param>
/// <returns>
/// <para>Type: <c>HRESULT</c></para>
/// <para>If the function succeeds, it returns <c>S_OK</c>.</para>
/// <para>If the function fails, it returns a system error code defined in WinError.h.</para>
/// </returns>
/// <remarks>
/// To complete the client-side handshake, applications must call WebSocketEndClientHandshake. Once the client-server handshake is
/// complete, the application may use the session functions.
/// </remarks>
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/nf-websocket-websocketbeginclienthandshake HRESULT
// WebSocketBeginClientHandshake( [in] WEB_SOCKET_HANDLE hWebSocket, [in, optional] PCSTR *pszSubprotocols, [in] ULONG
// ulSubprotocolCount, [in, optional] PCSTR *pszExtensions, [in] ULONG ulExtensionCount, [in, optional] const PWEB_SOCKET_HTTP_HEADER
// pInitialHeaders, [in] ULONG ulInitialHeaderCount, [out] PWEB_SOCKET_HTTP_HEADER *pAdditionalHeaders, [out] ULONG
// *pulAdditionalHeaderCount );
[PInvokeData("websocket.h", MSDNShortId = "NF:websocket.WebSocketBeginClientHandshake")]
public static HRESULT WebSocketBeginClientHandshake([In] WEB_SOCKET_HANDLE hWebSocket, [In, Optional, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[]? pszSubprotocols,
[Optional] uint ulSubprotocolCount, [In, Optional, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[]? pszExtensions, [Optional] uint ulExtensionCount,
[In, Optional, MarshalAs(UnmanagedType.LPArray)] WEB_SOCKET_HTTP_HEADER[]? pInitialHeaders, [Optional] uint ulInitialHeaderCount,
out WEB_SOCKET_HTTP_HEADER[]? pAdditionalHeaders)
{
var ret = WebSocketBeginClientHandshake(hWebSocket, pszSubprotocols, ulSubprotocolCount, pszExtensions, ulExtensionCount, pInitialHeaders, ulInitialHeaderCount, out var pHeaders, out var count);
pAdditionalHeaders = ret.Succeeded ? pHeaders.ToArray<WEB_SOCKET_HTTP_HEADER>((int)count) : null;
return ret;
}
/// <summary>The <c>WebSocketBeginServerHandshake</c> function begins the server-side handshake.</summary>
/// <param name="hWebSocket">
/// <para>Type: <c>WEB_SOCKET_HANDLE</c></para>
/// <para>WebSocket session handle returned by a previous call to WebSocketCreateServerHandle.</para>
/// </param>
/// <param name="pszSubprotocolSelected">
/// <para>Type: <c>PCSTR</c></para>
/// <para>A pointer to a sub-protocol value chosen by the application. Must contain one subprotocol.</para>
/// </param>
/// <param name="pszExtensionSelected">
/// <para>Type: <c>PCSTR*</c></para>
/// <para>A pointer to a list of extensions chosen by the application. Must contain one extension per entry.</para>
/// </param>
/// <param name="ulExtensionSelectedCount">
/// <para>Type: <c>ULONG</c></para>
/// <para>Number of extensions in <c>pszExtensionSelected</c>.</para>
/// </param>
/// <param name="pRequestHeaders">
/// <para>Type: <c>const PWEB_SOCKET_HTTP_HEADER</c></para>
/// <para>Pointer to an array of WEB_SOCKET_HTTP_HEADER structures that contain the request headers received by the application.</para>
/// </param>
/// <param name="ulRequestHeaderCount">
/// <para>Type: <c>ULONG</c></para>
/// <para>Number of request headers in <c>pRequestHeaders</c>.</para>
/// </param>
/// <param name="pResponseHeaders">
/// <para>Type: <c>PWEB_SOCKET_HTTP_HEADER*</c></para>
/// <para>
/// On successful output, a pointer to an array or WEB_SOCKET_HTTP_HEADER structures that contain the response headers to be sent by the application.
/// </para>
/// </param>
/// <returns>
/// <para>Type: <c>HRESULT</c></para>
/// <para>If the function succeeds, it returns <c>S_OK</c>.</para>
/// <para>If the function fails, it returns one of the following or a system error code defined in WinError.h.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term><c>E_INVALID_PROTOCOL_FORMAT</c></term>
/// <term>Protocol data had an invalid format.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// To complete the server-side handshake, applications must call WebSocketEndServerHandshake or any of the session functions. Once the
/// client-server handshake is complete, the application may use the session functions.
/// </remarks>
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/nf-websocket-websocketbeginserverhandshake HRESULT
// WebSocketBeginServerHandshake( [in] WEB_SOCKET_HANDLE hWebSocket, [in, optional] PCSTR pszSubprotocolSelected, [in, optional] PCSTR
// *pszExtensionSelected, [in] ULONG ulExtensionSelectedCount, [in] const PWEB_SOCKET_HTTP_HEADER pRequestHeaders, [in] ULONG
// ulRequestHeaderCount, [out] PWEB_SOCKET_HTTP_HEADER *pResponseHeaders, [out] ULONG *pulResponseHeaderCount );
[PInvokeData("websocket.h", MSDNShortId = "NF:websocket.WebSocketBeginServerHandshake")]
public static HRESULT WebSocketBeginServerHandshake([In] WEB_SOCKET_HANDLE hWebSocket,
[In, Optional, MarshalAs(UnmanagedType.LPStr)] string? pszSubprotocolSelected,
[In, Optional, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[]? pszExtensionSelected, [Optional] uint ulExtensionSelectedCount,
[In, MarshalAs(UnmanagedType.LPArray)] WEB_SOCKET_HTTP_HEADER[] pRequestHeaders, uint ulRequestHeaderCount,
out WEB_SOCKET_HTTP_HEADER[]? pResponseHeaders)
{
var ret = WebSocketBeginServerHandshake(hWebSocket, pszSubprotocolSelected, pszExtensionSelected, ulExtensionSelectedCount, pRequestHeaders, ulRequestHeaderCount, out var pHeaders, out var count);
pResponseHeaders = ret.Succeeded ? pHeaders.ToArray<WEB_SOCKET_HTTP_HEADER>((int)count) : null;
return ret;
}
/// <summary>The <c>WebSocketBeginServerHandshake</c> function begins the server-side handshake.</summary>
/// <param name="hWebSocket">
@ -525,9 +661,9 @@ public static partial class WebSocket
[DllImport(Lib_Websocket, SetLastError = false, ExactSpelling = true)]
public static extern HRESULT WebSocketBeginServerHandshake([In] WEB_SOCKET_HANDLE hWebSocket,
[In, Optional, MarshalAs(UnmanagedType.LPStr)] string? pszSubprotocolSelected,
[In, Optional, MarshalAs(UnmanagedType.LPStr)] string? pszExtensionSelected, [Optional] uint ulExtensionSelectedCount,
[In, Optional, MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPStr)] string[]? pszExtensionSelected, [Optional] uint ulExtensionSelectedCount,
[In, MarshalAs(UnmanagedType.LPArray)] WEB_SOCKET_HTTP_HEADER[] pRequestHeaders, uint ulRequestHeaderCount,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 7)] out WEB_SOCKET_HTTP_HEADER[] pResponseHeaders, out uint pulResponseHeaderCount);
out IntPtr pResponseHeaders, out uint pulResponseHeaderCount);
/// <summary>The <c>WebSocketCompleteAction</c> function completes an action started by WebSocketGetAction.</summary>
/// <param name="hWebSocket">
@ -556,19 +692,19 @@ public static partial class WebSocket
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// WEB_SOCKET_SEND_TO_NETWORK_ACTION: if <c>ulBytesTransferred</c> is different than the sum all buffer lengths returned from
/// WebSocketGetAction the current send action is canceled and the next call to
/// <c>WebSocketGetAction</c> will return <c>WEB_SOCKET_INDICATE_SEND_COMPLETE_ACTION</c> even if not
/// all buffers passed to WebSocketSend were processed.
/// </term>
/// <term>WEB_SOCKET_SEND_TO_NETWORK_ACTION:</term>
/// <description>
/// if <c>ulBytesTransferred</c> is different than the sum all buffer lengths returned from WebSocketGetAction the current send action is
/// canceled and the next call to <c>WebSocketGetAction</c> will return <c>WEB_SOCKET_INDICATE_SEND_COMPLETE_ACTION</c> even if not all
/// buffers passed to WebSocketSend were processed.
/// </description>
/// </item>
/// <item>
/// <term>
/// WEB_SOCKET_RECEIVE_FROM_NETWORK_ACTION: if <c>ulBytesTransferred</c> is 0, the current receive action is canceled and the next call
/// to WebSocketGetAction will return <c>WEB_SOCKET_INDICATE_RECEIVE_COMPLETE_ACTION</c> even if
/// not all buffers passed to WebSocketReceive were processed.
/// </term>
/// <term>WEB_SOCKET_RECEIVE_FROM_NETWORK_ACTION:</term>
/// <description>
/// if <c>ulBytesTransferred</c> is 0, the current receive action is canceled and the next call to WebSocketGetAction will return
/// <c>WEB_SOCKET_INDICATE_RECEIVE_COMPLETE_ACTION</c> even if not all buffers passed to WebSocketReceive were processed.
/// </description>
/// </item>
/// </list>
/// </remarks>
@ -603,8 +739,8 @@ public static partial class WebSocket
[PInvokeData("websocket.h", MSDNShortId = "NF:websocket.WebSocketCreateClientHandle")]
[DllImport(Lib_Websocket, SetLastError = false, ExactSpelling = true)]
public static extern HRESULT WebSocketCreateClientHandle(
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] WEB_SOCKET_PROPERTY[] pProperties,
uint ulPropertyCount, out SafeWEB_SOCKET_HANDLE phWebSocket);
[In, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] WEB_SOCKET_PROPERTY[]? pProperties,
[Optional] uint ulPropertyCount, out SafeWEB_SOCKET_HANDLE phWebSocket);
/// <summary>The <c>WebSocketCreateServerHandle</c> function creates a server-side WebSocket session handle.</summary>
/// <param name="pProperties">
@ -630,8 +766,8 @@ public static partial class WebSocket
[PInvokeData("websocket.h", MSDNShortId = "NF:websocket.WebSocketCreateServerHandle")]
[DllImport(Lib_Websocket, SetLastError = false, ExactSpelling = true)]
public static extern HRESULT WebSocketCreateServerHandle(
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] WEB_SOCKET_PROPERTY[] pProperties,
uint ulPropertyCount, out SafeWEB_SOCKET_HANDLE phWebSocket);
[In, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] WEB_SOCKET_PROPERTY[]? pProperties,
[In, Optional] uint ulPropertyCount, out SafeWEB_SOCKET_HANDLE phWebSocket);
/// <summary>
/// The <c>WebSocketDeleteHandle</c> function deletes a WebSocket session handle created by WebSocketCreateClientHandle or WebSocketCreateServerHandle.
@ -964,26 +1100,18 @@ public static partial class WebSocket
/// <para>If the function fails, it returns a system error code defined in WinError.h.</para>
/// </returns>
[PInvokeData("websocket.h", MSDNShortId = "NF:websocket.WebSocketGetGlobalProperty")]
public static HRESULT WebSocketGetGlobalProperty<T>([In] WEB_SOCKET_PROPERTY_TYPE eType, out T pvValue)
public static HRESULT WebSocketGetGlobalProperty<T>([In] WEB_SOCKET_PROPERTY_TYPE eType, out T? pvValue)
{
if (typeof(T).IsArray)
using SafeCoTaskMemHandle mem = typeof(T).IsArray ? new(1024) : SafeCoTaskMemHandle.CreateFromStructure<T>();
uint sz = mem.Size;
HRESULT ret = WebSocketGetGlobalProperty(eType, mem, ref sz);
if (ret.Failed && sz > mem.Size)
{
using SafeCoTaskMemHandle mem = new(1024);
uint sz = mem.Size;
HRESULT ret = WebSocketGetGlobalProperty(eType, mem, ref sz);
Type elemType = typeof(T).GetElementType();
int elemSz = Marshal.SizeOf(elemType);
pvValue = ret.Succeeded ? (T)(object)mem.DangerousGetHandle().ToArray(elemType, mem.Size / elemSz, 0, sz) : default;
return ret;
}
else
{
using SafeCoTaskMemHandle mem = SafeCoTaskMemHandle.CreateFromStructure<T>();
uint sz = mem.Size;
HRESULT ret = WebSocketGetGlobalProperty(eType, mem, ref sz);
pvValue = ret.Succeeded ? mem.ToStructure<T>() : default;
return ret;
mem.Size = sz;
ret = WebSocketGetGlobalProperty(eType, mem, ref sz);
}
pvValue = mem.ToType<T>();
return ret;
}
/// <summary>The <c>WebSocketReceive</c> function adds a receive operation to the protocol component operation queue.</summary>

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using System.Collections.Generic;
using static Vanara.PInvoke.DbgHelp;
using static Vanara.PInvoke.Kernel32;
@ -44,7 +45,7 @@ public static partial class Wer
WerConsentAlwaysPrompt = 4,
}
/// <summary>Flags used by <see cref="WerReportAddDump"/>.</summary>
/// <summary>Flags used by <see cref="WerReportAddDump(HREPORT, HPROCESS, HTHREAD, WER_DUMP_TYPE, in WER_EXCEPTION_INFORMATION, in WER_DUMP_CUSTOM_OPTIONS, WER_DUMP)"/>.</summary>
[PInvokeData("werapi.h", MSDNShortId = "b40dac44-f7c5-43f0-876d-6f97c26bf461")]
[Flags]
public enum WER_DUMP
@ -214,7 +215,7 @@ public static partial class Wer
// https://docs.microsoft.com/en-us/windows/win32/api/werapi/nf-werapi-werfreestring void WerFreeString( PCWSTR pwszStr );
[DllImport(Lib.Wer, SetLastError = false, ExactSpelling = true)]
[PInvokeData("werapi.h", MSDNShortId = "748AEFD4-3310-4BC1-A3DA-CFACBA31F2FC")]
public static extern void WerFreeString([MarshalAs(UnmanagedType.LPWStr)] string pwszStr);
public static extern void WerFreeString(StrPtrUni pwszStr);
/// <summary>Removes the specified application from the list of applications that are to be excluded from error reporting.</summary>
/// <param name="pwzExeName">
@ -327,7 +328,79 @@ public static partial class Wer
// PWER_DUMP_CUSTOM_OPTIONS pDumpCustomOptions, DWORD dwFlags );
[DllImport(Lib.Wer, SetLastError = false, ExactSpelling = true)]
[PInvokeData("werapi.h", MSDNShortId = "b40dac44-f7c5-43f0-876d-6f97c26bf461")]
public static extern HRESULT WerReportAddDump(HREPORT hReportHandle, HPROCESS hProcess, HTHREAD hThread, WER_DUMP_TYPE dumpType, in WER_EXCEPTION_INFORMATION pExceptionParam, in WER_DUMP_CUSTOM_OPTIONS pDumpCustomOptions, WER_DUMP dwFlags);
public static extern HRESULT WerReportAddDump(HREPORT hReportHandle, HPROCESS hProcess, [Optional] HTHREAD hThread,
WER_DUMP_TYPE dumpType, in WER_EXCEPTION_INFORMATION pExceptionParam, in WER_DUMP_CUSTOM_OPTIONS pDumpCustomOptions, WER_DUMP dwFlags);
/// <summary>Adds a dump of the specified type to the specified report.</summary>
/// <param name="hReportHandle">A handle to the report. This handle is returned by the WerReportCreate function.</param>
/// <param name="hProcess">
/// A handle to the process for which the report is being generated. This handle must have the STANDARD_RIGHTS_READ and
/// PROCESS_QUERY_INFORMATION access rights.
/// </param>
/// <param name="hThread">
/// A handle to the thread of hProcess for which the report is being generated. If dumpType is WerDumpTypeMicro, this parameter is
/// required. For other dump types, this parameter may be <c>NULL</c>.
/// </param>
/// <param name="dumpType">
/// <para>The type of minidump. This parameter can be one of the following values from the <c>WER_DUMP_TYPE</c> enumeration type.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WerDumpTypeHeapDump</term>
/// <term>
/// An extended minidump that contains additional data such as the process memory. This type is equivalent to creating a minidump
/// with the following options:
/// </term>
/// </item>
/// <item>
/// <term>WerDumpTypeMicroDump</term>
/// <term>
/// A limited minidump that contains only a stack trace. This type is equivalent to creating a minidump with the following options:
/// </term>
/// </item>
/// <item>
/// <term>WerDumpTypeMiniDump</term>
/// <term>A minidump. This type is equivalent to creating a minidump with the following options:</term>
/// </item>
/// </list>
/// </param>
/// <param name="pExceptionParam">A pointer to a WER_EXCEPTION_INFORMATION structure that specifies exception information.</param>
/// <param name="pDumpCustomOptions">
/// A pointer to a WER_DUMP_CUSTOM_OPTIONS structure that specifies custom minidump options. If this parameter is <c>NULL</c>, the
/// standard minidump information is collected.
/// </param>
/// <param name="dwFlags">
/// <para>This parameter can be 0 or the following value.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WER_DUMP_NOHEAP_ONQUEUE</term>
/// <term>If the report is being queued, do not include a heap dump. Using this flag saves disk space.</term>
/// </item>
/// </list>
/// </param>
/// <returns>This function returns <c>S_OK</c> on success or an error code on failure.</returns>
/// <remarks>
/// <para>Use this function only for generic reporting—it has no effect on operating system crash or no-response reporting.</para>
/// <para>
/// If the server asks for a mini dump and you specify <c>WerDumpTypeHeapDump</c> for the dumpType parameter, WER will not send the
/// heap dump to the Watson server. However, if the server asks for a heap dump and the dumpType is <c>WerDumpTypeMiniDump</c>, WER
/// will send the mini dump to the server. Thus, it is recommended that you set dumpType to <c>WerDumpTypeMiniDump</c>.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/werapi/nf-werapi-werreportadddump HRESULT WerReportAddDump( HREPORT
// hReportHandle, HANDLE hProcess, HANDLE hThread, WER_DUMP_TYPE dumpType, PWER_EXCEPTION_INFORMATION pExceptionParam,
// PWER_DUMP_CUSTOM_OPTIONS pDumpCustomOptions, DWORD dwFlags );
[DllImport(Lib.Wer, SetLastError = false, ExactSpelling = true)]
[PInvokeData("werapi.h", MSDNShortId = "b40dac44-f7c5-43f0-876d-6f97c26bf461")]
public static extern HRESULT WerReportAddDump(HREPORT hReportHandle, HPROCESS hProcess, [Optional] HTHREAD hThread,
WER_DUMP_TYPE dumpType, in WER_EXCEPTION_INFORMATION pExceptionParam, [In, Optional] IntPtr pDumpCustomOptions, WER_DUMP dwFlags);
/// <summary>Adds a file to the specified report.</summary>
/// <param name="hReportHandle">A handle to the report. This handle is returned by the WerReportCreate function.</param>
@ -528,7 +601,7 @@ public static partial class Wer
// hReportHandle, DWORD dwparamID, PCWSTR pwzName, PCWSTR pwzValue );
[DllImport(Lib.Wer, SetLastError = false, ExactSpelling = true)]
[PInvokeData("werapi.h", MSDNShortId = "accf423d-6f03-41e2-b5e9-4a0b630bc918")]
public static extern HRESULT WerReportSetParameter(HREPORT hReportHandle, WER_P dwparamID, [MarshalAs(UnmanagedType.LPWStr)] string pwzName, [MarshalAs(UnmanagedType.LPWStr)] string pwzValue);
public static extern HRESULT WerReportSetParameter(HREPORT hReportHandle, WER_P dwparamID, [MarshalAs(UnmanagedType.LPWStr)] string? pwzName, [MarshalAs(UnmanagedType.LPWStr)] string? pwzValue);
/// <summary>Sets the user interface options for the specified report.</summary>
/// <param name="hReportHandle">A handle to the report. This handle is returned by the WerReportCreate function.</param>
@ -816,7 +889,7 @@ public static partial class Wer
// HREPORTSTORE hReportStore, PCWSTR *ppszReportKey );
[DllImport(Lib.Wer, SetLastError = false, ExactSpelling = true)]
[PInvokeData("werapi.h", MSDNShortId = "E4732B60-BFBE-4916-83A6-5F031D267913")]
public static extern HRESULT WerStoreGetFirstReportKey(HREPORTSTORE hReportStore, [MarshalAs(UnmanagedType.LPWStr)] out string ppszReportKey);
public static extern HRESULT WerStoreGetFirstReportKey(HREPORTSTORE hReportStore, out StrPtrUni ppszReportKey);
/// <summary>Gets a reference to the next report in the error report store.</summary>
/// <param name="hReportStore">The error report store (previously retrieved with WerStoreOpen).</param>
@ -844,7 +917,7 @@ public static partial class Wer
// HREPORTSTORE hReportStore, PCWSTR *ppszReportKey );
[DllImport(Lib.Wer, SetLastError = false, ExactSpelling = true)]
[PInvokeData("werapi.h", MSDNShortId = "781D54A9-6F51-445E-89A8-A0C944081B81")]
public static extern HRESULT WerStoreGetNextReportKey(HREPORTSTORE hReportStore, [MarshalAs(UnmanagedType.LPWStr)] out string ppszReportKey);
public static extern HRESULT WerStoreGetNextReportKey(HREPORTSTORE hReportStore, out StrPtrUni ppszReportKey);
/// <summary>Opens the collection of stored error reports.</summary>
/// <param name="repStoreType">The type of report store to open. See Remarks for details.</param>
@ -955,7 +1028,7 @@ public static partial class Wer
public static bool operator ==(HREPORT h1, HREPORT h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object? obj) => obj is HREPORT h ? handle == h.handle : false;
public override bool Equals(object? obj) => obj is HREPORT h && handle == h.handle;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
@ -1003,7 +1076,7 @@ public static partial class Wer
public static bool operator ==(HREPORTSTORE h1, HREPORTSTORE h2) => h1.Equals(h2);
/// <inheritdoc/>
public override bool Equals(object? obj) => obj is HREPORTSTORE h ? handle == h.handle : false;
public override bool Equals(object? obj) => obj is HREPORTSTORE h && handle == h.handle;
/// <inheritdoc/>
public override int GetHashCode() => handle.GetHashCode();
@ -1120,7 +1193,7 @@ public static partial class Wer
/// <para>This member is valid only if <c>dwMask</c> contains WER_DUMP_MASK_PREFERRED_MODULE_LIST.</para>
/// </summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
public string wzPreferredModuleList;
public string? wzPreferredModuleList;
/// <summary>A default instance with the size field set.</summary>
public static readonly WER_DUMP_CUSTOM_OPTIONS Default = new() { dwSize = (uint)Marshal.SizeOf(typeof(WER_DUMP_CUSTOM_OPTIONS)) };
@ -1190,13 +1263,6 @@ public static partial class Wer
public HWND hwndParent;
/// <summary>A default instance with the size field set.</summary>
/* Unmerged change from project 'Vanara.PInvoke.Wer (netcoreapp3.1)'
Before:
public static readonly WER_REPORT_INFORMATION Default = new WER_REPORT_INFORMATION { dwSize = (uint)Marshal.SizeOf(typeof(WER_REPORT_INFORMATION)) };
After:
public static readonly WER_REPORT_INFORMATION Default = new() { dwSize = (uint)Marshal.SizeOf(typeof(WER_REPORT_INFORMATION)) };
*/
public static readonly WER_REPORT_INFORMATION Default = new() { dwSize = (uint)Marshal.SizeOf(typeof(WER_REPORT_INFORMATION)) };
}

View File

@ -1,3 +1,4 @@
using System.Collections.Generic;
using static Vanara.PInvoke.Crypt32;
namespace Vanara.PInvoke;
@ -312,7 +313,8 @@ public static partial class WinTrust
[DllImport(Lib.Wintrust, SetLastError = true, ExactSpelling = true)]
[PInvokeData("mscat.h", MSDNShortId = "B089217A-5C12-4C51-8E46-3A9243347B21")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptCATAdminAcquireContext2(out SafeHCATADMIN phCatAdmin, in Guid pgSubsystem, [MarshalAs(UnmanagedType.LPWStr), Optional] string? pwszHashAlgorithm, in CERT_STRONG_SIGN_PARA pStrongHashPolicy, uint dwFlags = 0);
public static extern bool CryptCATAdminAcquireContext2(out SafeHCATADMIN phCatAdmin, in Guid pgSubsystem,
[MarshalAs(UnmanagedType.LPWStr), Optional] string? pwszHashAlgorithm, in CERT_STRONG_SIGN_PARA pStrongHashPolicy, uint dwFlags = 0);
/// <summary>
/// <para>
@ -389,7 +391,8 @@ public static partial class WinTrust
[DllImport(Lib.Wintrust, SetLastError = true, ExactSpelling = true)]
[PInvokeData("mscat.h", MSDNShortId = "B089217A-5C12-4C51-8E46-3A9243347B21")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptCATAdminAcquireContext2(out SafeHCATADMIN phCatAdmin, [Optional] IntPtr pgSubsystem, [MarshalAs(UnmanagedType.LPWStr), Optional] string? pwszHashAlgorithm, [Optional] IntPtr pStrongHashPolicy, uint dwFlags = 0);
public static extern bool CryptCATAdminAcquireContext2(out SafeHCATADMIN phCatAdmin, [Optional] IntPtr pgSubsystem,
[MarshalAs(UnmanagedType.LPWStr), Optional] string? pwszHashAlgorithm, [Optional] IntPtr pStrongHashPolicy, uint dwFlags = 0);
/// <summary>
/// <para>
@ -430,7 +433,8 @@ public static partial class WinTrust
// https://docs.microsoft.com/en-us/windows/win32/api/mscat/nf-mscat-cryptcatadminaddcatalog HCATINFO CryptCATAdminAddCatalog(
// HCATADMIN hCatAdmin, PWSTR pwszCatalogFile, PWSTR pwszSelectBaseName, DWORD dwFlags );
[PInvokeData("mscat.h", MSDNShortId = "a227597c-a0af-4b86-bd29-03f478aef244")]
public static SafeHCATINFO CryptCATAdminAddCatalog(SafeHCATADMIN hCatAdmin, [MarshalAs(UnmanagedType.LPWStr)] string pwszCatalogFile, [MarshalAs(UnmanagedType.LPWStr), Optional] string? pwszSelectBaseName, uint dwFlags) =>
public static SafeHCATINFO CryptCATAdminAddCatalog(SafeHCATADMIN hCatAdmin, [MarshalAs(UnmanagedType.LPWStr)] string pwszCatalogFile,
[MarshalAs(UnmanagedType.LPWStr), Optional] string? pwszSelectBaseName, uint dwFlags) =>
new(InternalCryptCATAdminAddCatalog(hCatAdmin, pwszCatalogFile, pwszSelectBaseName, dwFlags), hCatAdmin, true);
/// <summary>
@ -466,7 +470,7 @@ public static partial class WinTrust
[DllImport(Lib.Wintrust, SetLastError = true, ExactSpelling = true)]
[PInvokeData("mscat.h", MSDNShortId = "4dc5688f-4b7a-4baf-9671-868cac7f1896")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptCATAdminCalcHashFromFileHandle(HFILE hFile, ref uint pcbHash, IntPtr pbHash, uint dwFlags = 0);
public static extern bool CryptCATAdminCalcHashFromFileHandle(HFILE hFile, ref uint pcbHash, [Optional] IntPtr pbHash, uint dwFlags = 0);
/// <summary>
/// <para>The <c>CryptCATAdminCalcHashFromFileHandle2</c> function calculates the hash for a file by using the specified algorithm.</para>
@ -526,7 +530,7 @@ public static partial class WinTrust
[DllImport(Lib.Wintrust, SetLastError = true, ExactSpelling = true)]
[PInvokeData("mscat.h", MSDNShortId = "CBFA60A8-5E5A-4FAD-8AD3-26539802CD53")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CryptCATAdminCalcHashFromFileHandle2(HCATADMIN hCatAdmin, HFILE hFile, ref uint pcbHash, IntPtr pbHash = default, uint dwFlags = 0);
public static extern bool CryptCATAdminCalcHashFromFileHandle2(HCATADMIN hCatAdmin, HFILE hFile, ref uint pcbHash, [Optional] IntPtr pbHash, uint dwFlags = 0);
/// <summary>
/// <para>
@ -597,9 +601,9 @@ public static partial class WinTrust
// https://docs.microsoft.com/en-us/windows/win32/api/mscat/nf-mscat-cryptcatadminenumcatalogfromhash HCATINFO
// CryptCATAdminEnumCatalogFromHash( HCATADMIN hCatAdmin, BYTE *pbHash, DWORD cbHash, DWORD dwFlags, HCATINFO *phPrevCatInfo );
[PInvokeData("mscat.h", MSDNShortId = "33ab2d01-94ab-4d23-a054-9da0731485d6")]
public static SafeHCATINFO CryptCATAdminEnumCatalogFromHash(SafeHCATADMIN hCatAdmin, IntPtr pbHash, uint cbHash, [Optional] uint dwFlags, SafeHCATINFO phPrevCatInfo = null)
public static SafeHCATINFO CryptCATAdminEnumCatalogFromHash(SafeHCATADMIN hCatAdmin, IntPtr pbHash, uint cbHash, [Optional] uint dwFlags, SafeHCATINFO? phPrevCatInfo = null)
{
HCATINFO hPrev = phPrevCatInfo ?? default;
HCATINFO hPrev = phPrevCatInfo is null ? default : (HCATINFO)phPrevCatInfo;
return new SafeHCATINFO(InternalCryptCATAdminEnumCatalogFromHash(hCatAdmin, pbHash, cbHash, dwFlags, ref hPrev), hCatAdmin, true);
}
@ -798,7 +802,35 @@ public static partial class WinTrust
// CryptCATCDFEnumCatAttributes( CRYPTCATCDF *pCDF, CRYPTCATATTRIBUTE *pPrevAttr, PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError );
[DllImport(Lib.Wintrust, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mscat.h", MSDNShortId = "01889cb9-7bf4-4591-9bb2-b263c4effe0c")]
public static extern IntPtr CryptCATCDFEnumCatAttributes(SafeCRYPTCATCDF pCDF, IntPtr pPrevAttr, PfnCdfParseErrorCallback pfnParseError);
public static extern IntPtr CryptCATCDFEnumCatAttributes(SafeCRYPTCATCDF pCDF, IntPtr pPrevAttr, PfnCdfParseErrorCallback? pfnParseError);
/// <summary>
/// <para>
/// [The <c>CryptCATCDFEnumCatAttributes</c> function is available for use in the operating systems specified in the Requirements
/// section. It may be altered or unavailable in subsequent versions.]
/// </para>
/// <para>
/// The <c>CryptCATCDFEnumCatAttributes</c> function enumerates catalog-level attributes within the <c>CatalogHeader</c> section of
/// a catalog definition file (CDF). <c>CryptCATCDFEnumCatAttributes</c> is called by MakeCat.
/// </para>
/// </summary>
/// <param name="pCDF">A pointer to a CRYPTCATCDF structure.</param>
/// <param name="pfnParseError">A pointer to a user-defined function to handle file parse errors.</param>
/// <returns>
/// A sequence of CRYPTCATATTRIBUTE structures.
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/mscat/nf-mscat-cryptcatcdfenumcatattributes CRYPTCATATTRIBUTE *
// CryptCATCDFEnumCatAttributes( CRYPTCATCDF *pCDF, CRYPTCATATTRIBUTE *pPrevAttr, PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError );
[PInvokeData("mscat.h", MSDNShortId = "01889cb9-7bf4-4591-9bb2-b263c4effe0c")]
public static IEnumerable<CRYPTCATATTRIBUTE> CryptCATCDFEnumCatAttributes(SafeCRYPTCATCDF pCDF, PfnCdfParseErrorCallback? pfnParseError) =>
EnumPrev<CRYPTCATATTRIBUTE>(p => CryptCATCDFEnumCatAttributes(pCDF, p, pfnParseError));
private static IEnumerable<T> EnumPrev<T>(Func<IntPtr, IntPtr> f) where T : struct
{
IntPtr pPrevAttr = IntPtr.Zero;
while ((pPrevAttr = f(pPrevAttr)) != IntPtr.Zero)
yield return pPrevAttr.ToStructure<T>();
}
/// <summary>
/// <para>
@ -882,7 +914,7 @@ public static partial class WinTrust
// pwszFilePath, PFN_CDF_PARSE_ERROR_CALLBACK pfnParseError );
[DllImport(Lib.Wintrust, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mscat.h", MSDNShortId = "d400d8bd-c0a0-41dc-9093-8e4fc758d82f")]
public static extern SafeCRYPTCATCDF CryptCATCDFOpen([MarshalAs(UnmanagedType.LPWStr)] string pwszFilePath, PfnCdfParseErrorCallback pfnParseError);
public static extern SafeCRYPTCATCDF CryptCATCDFOpen([MarshalAs(UnmanagedType.LPWStr)] string pwszFilePath, PfnCdfParseErrorCallback? pfnParseError);
/// <summary>
/// <para>
@ -929,6 +961,25 @@ public static partial class WinTrust
[PInvokeData("mscat.h", MSDNShortId = "064e87db-4330-4b8b-9865-ba8b9714f6e4")]
public static extern IntPtr CryptCATEnumerateAttr(HCATALOG hCatalog, in CRYPTCATMEMBER pCatMember, IntPtr pPrevAttr);
/// <summary>
/// <para>
/// [The <c>CryptCATEnumerateAttr</c> function is available for use in the operating systems specified in the Requirements section. It
/// may be altered or unavailable in subsequent versions.]
/// </para>
/// <para>
/// The <c>CryptCATEnumerateAttr</c> function enumerates the attributes associated with a member of a catalog. This function has no
/// associated import library. You must use the LoadLibrary and GetProcAddress functions to dynamically link to Wintrust.dll.
/// </para>
/// </summary>
/// <param name="hCatalog">Handle for the catalog that contains the member identified by pCatMember. This value cannot be <c>NULL</c>.</param>
/// <param name="pCatMember">A pointer to the CRYPTCATMEMBER structure that identifies which member of the catalog is being enumerated.</param>
/// <returns>The return value is a sequence of CRYPTCATATTRIBUTE structures that contains the attribute information.</returns>
// https://docs.microsoft.com/en-us/windows/win32/api/mscat/nf-mscat-cryptcatenumerateattr CRYPTCATATTRIBUTE *
// CryptCATEnumerateAttr( IN HANDLE hCatalog, IN CRYPTCATMEMBER *pCatMember, IN CRYPTCATATTRIBUTE *pPrevAttr );
[PInvokeData("mscat.h", MSDNShortId = "064e87db-4330-4b8b-9865-ba8b9714f6e4")]
public static IEnumerable<CRYPTCATATTRIBUTE> CryptCATEnumerateAttr(HCATALOG hCatalog, CRYPTCATMEMBER pCatMember) =>
EnumPrev<CRYPTCATATTRIBUTE>(p => CryptCATEnumerateAttr(hCatalog, pCatMember, p));
/// <summary>
/// <para>
/// [The <c>CryptCATEnumerateCatAttr</c> function is available for use in the operating systems specified in the Requirements
@ -956,6 +1007,24 @@ public static partial class WinTrust
[PInvokeData("mscat.h", MSDNShortId = "57b6ff5c-e47e-41ac-8ec8-01a47ea77acf")]
public static extern IntPtr CryptCATEnumerateCatAttr(HCATALOG hCatalog, IntPtr pPrevAttr);
/// <summary>
/// <para>
/// [The <c>CryptCATEnumerateCatAttr</c> function is available for use in the operating systems specified in the Requirements section. It
/// may be altered or unavailable in subsequent versions.]
/// </para>
/// <para>
/// The <c>CryptCATEnumerateCatAttr</c> function enumerates the attributes associated with a catalog. This function has no associated
/// import library. You must use the LoadLibrary and GetProcAddress functions to dynamically link to Wintrust.dll.
/// </para>
/// </summary>
/// <param name="hCatalog">Handle for the catalog whose attributes are being enumerated. This value cannot be <c>NULL</c>.</param>
/// <returns>The return value is a sequence of CRYPTCATATTRIBUTE structures that contains the attribute information.</returns>
// https://docs.microsoft.com/en-us/windows/win32/api/mscat/nf-mscat-cryptcatenumeratecatattr CRYPTCATATTRIBUTE *
// CryptCATEnumerateCatAttr( IN HANDLE hCatalog, IN CRYPTCATATTRIBUTE *pPrevAttr );
[PInvokeData("mscat.h", MSDNShortId = "57b6ff5c-e47e-41ac-8ec8-01a47ea77acf")]
public static IEnumerable<CRYPTCATATTRIBUTE> CryptCATEnumerateCatAttr(HCATALOG hCatalog) =>
EnumPrev<CRYPTCATATTRIBUTE>(p => CryptCATEnumerateCatAttr(hCatalog, p));
/// <summary>
/// <para>
/// [The <c>CryptCATEnumerateMember</c> function is available for use in the operating systems specified in the Requirements
@ -983,6 +1052,21 @@ public static partial class WinTrust
[PInvokeData("mscat.h", MSDNShortId = "6bbfef11-a150-4255-8620-27c1b1587b48")]
public static extern IntPtr CryptCATEnumerateMember(HCATALOG hCatalog, IntPtr pPrevMember);
/// <summary>
/// <para>
/// [The <c>CryptCATEnumerateMember</c> function is available for use in the operating systems specified in the Requirements section. It
/// may be altered or unavailable in subsequent versions.]
/// </para>
/// <para>The <c>CryptCATEnumerateMember</c> function enumerates the members of a catalog.</para>
/// </summary>
/// <param name="hCatalog">The handle of the catalog that contains the members to enumerate. This value cannot be <c>NULL</c>.</param>
/// <returns>This function returns a sequence of CRYPTCATMEMBER structures that represents the next member of the catalog.</returns>
// https://docs.microsoft.com/en-us/windows/win32/api/mscat/nf-mscat-cryptcatenumeratemember CRYPTCATMEMBER *
// CryptCATEnumerateMember( IN HANDLE hCatalog, IN CRYPTCATMEMBER *pPrevMember );
[PInvokeData("mscat.h", MSDNShortId = "6bbfef11-a150-4255-8620-27c1b1587b48")]
public static IEnumerable<CRYPTCATMEMBER> CryptCATEnumerateMember(HCATALOG hCatalog) =>
EnumPrev<CRYPTCATMEMBER>(p => CryptCATEnumerateMember(hCatalog, p));
/// <summary>
/// <para>
/// [The <c>CryptCATGetAttrInfo</c> function is available for use in the operating systems specified in the Requirements section. It
@ -1443,7 +1527,7 @@ public static partial class WinTrust
[DllImport(Lib.Wintrust, SetLastError = false, ExactSpelling = true)]
[PInvokeData("mscat.h", MSDNShortId = "eeba34d4-08aa-456a-8fdc-16795cbce36a")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool IsCatalogFile([In] HFILE hFile, [MarshalAs(UnmanagedType.LPWStr)] string pwszFileName);
public static extern bool IsCatalogFile([In, Optional] HFILE hFile, [MarshalAs(UnmanagedType.LPWStr), Optional] string? pwszFileName);
[DllImport(Lib.Wintrust, SetLastError = true, EntryPoint = "CryptCATAdminAddCatalog")]
private static extern IntPtr InternalCryptCATAdminAddCatalog(HCATADMIN hCatAdmin, [MarshalAs(UnmanagedType.LPWStr)] string pwszCatalogFile, [MarshalAs(UnmanagedType.LPWStr), Optional] string? pwszSelectBaseName, uint dwFlags);
@ -1923,7 +2007,7 @@ public static partial class WinTrust
hAdmin = hCatAdmin ?? throw new ArgumentNullException(nameof(hCatAdmin));
/// <summary>Initializes a new instance of the <see cref="SafeHCATINFO"/> class.</summary>
private SafeHCATINFO() : base() { }
private SafeHCATINFO() : base() => hAdmin = new(IntPtr.Zero, false);
/// <summary>Performs an implicit conversion from <see cref="SafeHCATINFO"/> to <see cref="HCATINFO"/>.</summary>
/// <param name="h">The safe handle instance.</param>

View File

@ -1,3 +1,4 @@
#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member
using static Vanara.PInvoke.Crypt32;
namespace Vanara.PInvoke;

View File

@ -0,0 +1,8 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<AssemblyName>UnitTest.PInvoke.WebSocket</AssemblyName>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\PInvoke\WebSocket\Vanara.PInvoke.WebSocket.csproj" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,44 @@
using NUnit.Framework;
using NUnit.Framework.Internal;
using System.Collections.Generic;
using static Vanara.PInvoke.WebSocket;
namespace Vanara.PInvoke.Tests;
[TestFixture]
public class WebSocketTests
{
[OneTimeSetUp]
public void _Setup()
{
}
[OneTimeTearDown]
public void _TearDown()
{
}
[Test]
public void WebSocketBeginServerHandshakeTest()
{
Assert.That(WebSocketCreateClientHandle(null, 0, out SafeWEB_SOCKET_HANDLE? ch), ResultIs.Successful);
Assert.That(ch, ResultIs.ValidHandle);
var hdrs = new[] { new WEB_SOCKET_HTTP_HEADER { pcName = "Connection", ulNameLength = 10, pcValue = "Upgrade", ulValueLength = 7 }, new WEB_SOCKET_HTTP_HEADER { pcName = "Upgrade", ulNameLength = 7, pcValue = "websocket", ulValueLength = 9 } };
Assert.That(WebSocketBeginClientHandshake(ch, null, 0, null, 0, hdrs, (uint)hdrs.Length, out var ah), ResultIs.Successful);
Assert.That(ah, Has.Length.GreaterThan(0));
ah!.WriteValues();
Assert.That(WebSocketCreateServerHandle(null, 0, out SafeWEB_SOCKET_HANDLE? sh), ResultIs.Successful);
Assert.That(sh, ResultIs.ValidHandle);
List<WEB_SOCKET_HTTP_HEADER> hdrl = new(ah!) { new() { pcName = "Host", ulNameLength = 4, pcValue = "localhost", ulValueLength = 9 } };
Assert.That(WebSocketBeginServerHandshake(sh, null, null, 0, hdrl.ToArray(), (uint)hdrl.Count, out WEB_SOCKET_HTTP_HEADER[]? rh), ResultIs.Successful);
Assert.That(rh, Has.Length.GreaterThan(0));
rh!.WriteValues();
Assert.That(WebSocketEndClientHandshake(ch, rh!, (uint)rh!.Length), ResultIs.Successful);
Assert.That(WebSocketEndServerHandshake(sh), ResultIs.Successful);
}
}

View File

@ -427,6 +427,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Vanara.PInvoke.UIAutomation
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Windows.Shell.Common", "UnitTests\Windows.Shell.Common\Windows.Shell.Common.csproj", "{2727B06D-1E73-4108-AFDE-39C1A6F99806}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebSocket", "UnitTests\PInvoke\WebSocket\WebSocket.csproj", "{AEA2913A-5E67-4C33-823F-CE06295DB35A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@ -3749,6 +3751,24 @@ Global
{2727B06D-1E73-4108-AFDE-39C1A6F99806}.Release|x64.Build.0 = Release|x64
{2727B06D-1E73-4108-AFDE-39C1A6F99806}.Release|x86.ActiveCfg = Release|x86
{2727B06D-1E73-4108-AFDE-39C1A6F99806}.Release|x86.Build.0 = Release|x86
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.Debug|x64.ActiveCfg = Debug|x64
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.Debug|x64.Build.0 = Debug|x64
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.Debug|x86.ActiveCfg = Debug|x86
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.Debug|x86.Build.0 = Debug|x86
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.DebugNoTests|Any CPU.ActiveCfg = DebugNoTests|Any CPU
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.DebugNoTests|Any CPU.Build.0 = DebugNoTests|Any CPU
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.DebugNoTests|x64.ActiveCfg = DebugNoTests|x64
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.DebugNoTests|x64.Build.0 = DebugNoTests|x64
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.DebugNoTests|x86.ActiveCfg = DebugNoTests|x86
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.DebugNoTests|x86.Build.0 = DebugNoTests|x86
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.Release|Any CPU.Build.0 = Release|Any CPU
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.Release|x64.ActiveCfg = Release|x64
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.Release|x64.Build.0 = Release|x64
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.Release|x86.ActiveCfg = Release|x86
{AEA2913A-5E67-4C33-823F-CE06295DB35A}.Release|x86.Build.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -3941,6 +3961,7 @@ Global
{BD978D87-063B-461F-9ECB-B67F962F54D6} = {385CAD2D-0A5E-4F80-927B-D5499D126B90}
{7729B4B9-4837-49D5-91CC-5BB66E23A376} = {212ABBD0-B724-4CFA-9D6D-E3891547FA90}
{2727B06D-1E73-4108-AFDE-39C1A6F99806} = {3EC6B40D-71D3-4E59-A0E0-544EC605FE11}
{AEA2913A-5E67-4C33-823F-CE06295DB35A} = {385CAD2D-0A5E-4F80-927B-D5499D126B90}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {543FAC75-2AF1-4EF1-9609-B242B63FEED4}