using System;
using System.Runtime.InteropServices;
using Vanara.Extensions;
using Vanara.InteropServices;
namespace Vanara.PInvoke;
/// Items from the WebSocket.dll.
public static partial class WebSocket
{
///
public const int WEB_SOCKET_MAX_CLOSE_REASON_LENGTH = 123;
private const string Lib_Websocket = "websocket.dll";
/// The WEB_SOCKET_ACTION enumeration specifies actions to be taken by WebSocket applications.
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/ne-websocket-web_socket_action typedef enum _WEB_SOCKET_ACTION {
// WEB_SOCKET_NO_ACTION = 0, WEB_SOCKET_SEND_TO_NETWORK_ACTION = 1, WEB_SOCKET_INDICATE_SEND_COMPLETE_ACTION = 2,
// WEB_SOCKET_RECEIVE_FROM_NETWORK_ACTION = 3, WEB_SOCKET_INDICATE_RECEIVE_COMPLETE_ACTION = 4 } WEB_SOCKET_ACTION, *PWEB_SOCKET_ACTION;
[PInvokeData("websocket.h", MSDNShortId = "NE:websocket._WEB_SOCKET_ACTION")]
public enum WEB_SOCKET_ACTION
{
///
/// Value:
/// 0
/// There are no actions to process.
///
WEB_SOCKET_NO_ACTION = 0,
///
/// Value:
/// 1
/// Indicates the application should send the buffers to a network.
///
WEB_SOCKET_SEND_TO_NETWORK_ACTION,
///
/// Value:
/// 2
///
/// Indicates the operation queued by WebSocketSend is complete. The application context returned by WebSocketCompleteAction for this
/// send operation is no longer needed, therefore it should be freed.
///
///
WEB_SOCKET_INDICATE_SEND_COMPLETE_ACTION,
///
/// Value:
/// 3
/// Indicates the application should fill the buffers with data from a network.
///
WEB_SOCKET_RECEIVE_FROM_NETWORK_ACTION,
///
/// Value:
/// 4
///
/// Indicates the operation queued by WebSocketReceive is complete. The application context returned by WebSocketCompleteAction for
/// this receive operation is no longer needed, therefore it should be freed.
///
///
WEB_SOCKET_INDICATE_RECEIVE_COMPLETE_ACTION,
}
/// The WEB_SOCKET_ACTION_QUEUE enumeration specifies the action types returned by WebSocketGetAction.
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/ne-websocket-web_socket_action_queue typedef enum
// _WEB_SOCKET_ACTION_QUEUE { WEB_SOCKET_SEND_ACTION_QUEUE = 0x1, WEB_SOCKET_RECEIVE_ACTION_QUEUE = 0x2, WEB_SOCKET_ALL_ACTION_QUEUE } WEB_SOCKET_ACTION_QUEUE;
[PInvokeData("websocket.h", MSDNShortId = "NE:websocket._WEB_SOCKET_ACTION_QUEUE")]
[Flags]
public enum WEB_SOCKET_ACTION_QUEUE
{
///
/// Value:
/// 0x1
/// WebSocketGetAction
/// will return only send-related actions.
///
WEB_SOCKET_SEND_ACTION_QUEUE = 0x1,
///
/// Value:
/// 0x2
/// WebSocketGetAction
/// will return receive-related actions as well as internal send actions (reply to a ping frame).
///
WEB_SOCKET_RECEIVE_ACTION_QUEUE = 0x2,
///
/// WebSocketGetAction
/// will return all actions.
///
WEB_SOCKET_ALL_ACTION_QUEUE = 0x3,
}
/// The WEB_SOCKET_BUFFER_TYPE enumeration specifies the bit values used to construct the WebSocket frame header.
///
///
/// Please note that the FRAGMENT and MESSAGE buffer types may not correspond to how the message appears (or is framed) on the wire. For
/// example, when a single unfragmented 1000-byte message is received, WebSocket.dll may return multiple FRAGMENT buffer types followed
/// by a single MESSAGE buffer type (with the sizes adding up to 1000).
///
///
/// Extension WebSocket frame headers (allowing reserved bits to be set by extensions) may be constructed by setting the high bit (MSB)
/// and low bit (LSB) to 0. The remaining 9 lowest bits can then be used to form the custom frame header in place of the
/// WEB_SOCKET_BUFFER_TYPE enumeration values.
///
///
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/ne-websocket-web_socket_buffer_type typedef enum _WEB_SOCKET_BUFFER_TYPE
// { WEB_SOCKET_UTF8_MESSAGE_BUFFER_TYPE = 0x80000000, WEB_SOCKET_UTF8_FRAGMENT_BUFFER_TYPE = 0x80000001,
// WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE = 0x80000002, WEB_SOCKET_BINARY_FRAGMENT_BUFFER_TYPE = 0x80000003, WEB_SOCKET_CLOSE_BUFFER_TYPE
// = 0x80000004, WEB_SOCKET_PING_PONG_BUFFER_TYPE = 0x80000005, WEB_SOCKET_UNSOLICITED_PONG_BUFFER_TYPE = 0x80000006 } WEB_SOCKET_BUFFER_TYPE;
[PInvokeData("websocket.h", MSDNShortId = "NE:websocket._WEB_SOCKET_BUFFER_TYPE")]
public enum WEB_SOCKET_BUFFER_TYPE : uint
{
///
/// Value:
/// 0x80000000
/// Indicates the buffer contains the last, and possibly only, part of a UTF8 message.
///
WEB_SOCKET_UTF8_MESSAGE_BUFFER_TYPE = 0x80000000,
///
/// Value:
/// 0x80000001
/// Indicates the buffer contains part of a UTF8 message.
///
WEB_SOCKET_UTF8_FRAGMENT_BUFFER_TYPE,
///
/// Value:
/// 0x80000002
/// Indicates the buffer contains the last, and possibly only, part of a binary message.
///
WEB_SOCKET_BINARY_MESSAGE_BUFFER_TYPE,
///
/// Value:
/// 0x80000003
/// Indicates the buffer contains part of a binary message.
///
WEB_SOCKET_BINARY_FRAGMENT_BUFFER_TYPE,
///
/// Value:
/// 0x80000004
/// Indicates the buffer contains a close message.
///
WEB_SOCKET_CLOSE_BUFFER_TYPE,
///
/// Value:
/// 0x80000005
///
/// Indicates the buffer contains a ping or pong message. When sending, this value means 'ping', when processing received data, this
/// value means 'pong'.
///
///
WEB_SOCKET_PING_PONG_BUFFER_TYPE,
///
/// Value:
/// 0x80000006
/// Indicates the buffer contains an unsolicited pong message.
///
WEB_SOCKET_UNSOLICITED_PONG_BUFFER_TYPE,
}
/// The WEB_SOCKET_CLOSE_STATUS enumeration specifies the WebSocket close status as defined by WSPROTO.
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/ne-websocket-web_socket_close_status typedef enum
// _WEB_SOCKET_CLOSE_STATUS { WEB_SOCKET_SUCCESS_CLOSE_STATUS = 1000, WEB_SOCKET_ENDPOINT_UNAVAILABLE_CLOSE_STATUS = 1001,
// WEB_SOCKET_PROTOCOL_ERROR_CLOSE_STATUS = 1002, WEB_SOCKET_INVALID_DATA_TYPE_CLOSE_STATUS = 1003, WEB_SOCKET_EMPTY_CLOSE_STATUS = 1005,
// WEB_SOCKET_ABORTED_CLOSE_STATUS = 1006, WEB_SOCKET_INVALID_PAYLOAD_CLOSE_STATUS = 1007, WEB_SOCKET_POLICY_VIOLATION_CLOSE_STATUS =
// 1008, WEB_SOCKET_MESSAGE_TOO_BIG_CLOSE_STATUS = 1009, WEB_SOCKET_UNSUPPORTED_EXTENSIONS_CLOSE_STATUS = 1010,
// WEB_SOCKET_SERVER_ERROR_CLOSE_STATUS = 1011, WEB_SOCKET_SECURE_HANDSHAKE_ERROR_CLOSE_STATUS = 1015 } WEB_SOCKET_CLOSE_STATUS;
[PInvokeData("websocket.h", MSDNShortId = "NE:websocket._WEB_SOCKET_CLOSE_STATUS")]
public enum WEB_SOCKET_CLOSE_STATUS : ushort
{
///
/// Value:
/// 1000
/// Close completed successfully.
///
WEB_SOCKET_SUCCESS_CLOSE_STATUS = 1000,
///
/// Value:
/// 1001
/// The endpoint is going away and thus closing the connection.
///
WEB_SOCKET_ENDPOINT_UNAVAILABLE_CLOSE_STATUS,
///
/// Value:
/// 1002
/// Peer detected protocol error and it is closing the connection.
///
WEB_SOCKET_PROTOCOL_ERROR_CLOSE_STATUS,
///
/// Value:
/// 1003
/// The endpoint cannot receive this type of data.
///
WEB_SOCKET_INVALID_DATA_TYPE_CLOSE_STATUS,
///
/// Value:
/// 1005
/// No close status
/// code was provided.
///
WEB_SOCKET_EMPTY_CLOSE_STATUS = 1005,
///
/// Value:
/// 1006
/// The
/// connection was closed without sending or
/// receiving a close frame.
///
WEB_SOCKET_ABORTED_CLOSE_STATUS,
///
/// Value:
/// 1007
/// Data within a message is not consistent with the type of the message.
///
WEB_SOCKET_INVALID_PAYLOAD_CLOSE_STATUS,
///
/// Value:
/// 1008
/// The message violates an endpoint's policy.
///
WEB_SOCKET_POLICY_VIOLATION_CLOSE_STATUS,
///
/// Value:
/// 1009
/// The message sent was too large to process.
///
WEB_SOCKET_MESSAGE_TOO_BIG_CLOSE_STATUS,
///
/// Value:
/// 1010
///
/// A client endpoint expected the server to negotiate one or more extensions, but the server didn't return them in the response
/// message of the WebSocket handshake.
///
///
WEB_SOCKET_UNSUPPORTED_EXTENSIONS_CLOSE_STATUS,
///
/// Value:
/// 1011
/// An unexpected condition prevented the server from
/// fulfilling the request.
///
WEB_SOCKET_SERVER_ERROR_CLOSE_STATUS,
///
/// Value:
/// 1015
/// The
/// TLS handshake could not be completed.
///
WEB_SOCKET_SECURE_HANDSHAKE_ERROR_CLOSE_STATUS = 1015,
}
/// The WEB_SOCKET_PROPERTY_TYPE enumeration specifies a WebSocket property type.
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/ne-websocket-web_socket_property_type typedef enum
// _WEB_SOCKET_PROPERTY_TYPE { WEB_SOCKET_RECEIVE_BUFFER_SIZE_PROPERTY_TYPE = 0, WEB_SOCKET_SEND_BUFFER_SIZE_PROPERTY_TYPE = 1,
// WEB_SOCKET_DISABLE_MASKING_PROPERTY_TYPE = 2, WEB_SOCKET_ALLOCATED_BUFFER_PROPERTY_TYPE = 3,
// WEB_SOCKET_DISABLE_UTF8_VERIFICATION_PROPERTY_TYPE = 4, WEB_SOCKET_KEEPALIVE_INTERVAL_PROPERTY_TYPE = 5,
// WEB_SOCKET_SUPPORTED_VERSIONS_PROPERTY_TYPE = 6 } WEB_SOCKET_PROPERTY_TYPE;
[PInvokeData("websocket.h", MSDNShortId = "NE:websocket._WEB_SOCKET_PROPERTY_TYPE")]
public enum WEB_SOCKET_PROPERTY_TYPE
{
///
/// Value:
/// 0
/// Property type:
/// ULONG
/// The WebSocket property is the internal receive buffer size. The buffer cannot be smaller than 256 bytes.
/// The default is 4096.
/// Used with WebSocketCreateClientHandle and WebSocketCreateServerHandle.
///
[CorrespondingType(typeof(uint))]
WEB_SOCKET_RECEIVE_BUFFER_SIZE_PROPERTY_TYPE,
///
/// Value:
/// 1
/// Property type:
/// ULONG
/// The WebSocket property is the internal send buffer size. The buffer cannot be smaller than 256 bytes.
/// The default is 4096 on a handle created with WebSocketCreateClientHandle, and 16 on a handle created with WebSocketCreateServerHandle.
/// Used with WebSocketCreateClientHandle and WebSocketCreateServerHandle.
///
[CorrespondingType(typeof(uint))]
WEB_SOCKET_SEND_BUFFER_SIZE_PROPERTY_TYPE,
///
/// Value:
/// 2
/// Property type:
/// BOOL
///
/// The WebSocket property is the disabling of the mask bit in client frames. On the client, this property sets the mask key to 0. On
/// the server, this property allows the server to accept client frames with the mask bit set to 0. This property may have serious
/// security implications.
///
/// By default, this property is not used and masking is enabled.
/// Used with WebSocketCreateClientHandle and WebSocketCreateServerHandle.
///
[CorrespondingType(typeof(BOOL))]
WEB_SOCKET_DISABLE_MASKING_PROPERTY_TYPE,
///
/// Value:
/// 3
/// Property type:
/// PVOID
///
/// The WebSocket property is the buffer that is used as an internal buffer. If the passed buffer is not used, the WebSocket library
/// will take care of buffer management.
///
///
/// The passed buffer must be aligned to an 8-byte boundary and be greater in size than the receive buffer size + send buffer size +
/// 256 bytes.
///
/// Used with WebSocketCreateClientHandle and WebSocketCreateServerHandle.
///
[CorrespondingType(typeof(byte[]))]
WEB_SOCKET_ALLOCATED_BUFFER_PROPERTY_TYPE,
///
/// Value:
/// 4
/// Property type:
/// BOOL
/// The WebSocket property disables UTF-8 verification.
/// Used with WebSocketCreateClientHandle and WebSocketCreateServerHandle.
///
[CorrespondingType(typeof(BOOL))]
WEB_SOCKET_DISABLE_UTF8_VERIFICATION_PROPERTY_TYPE,
///
/// Value:
/// 5
/// Property type:
/// ULONG
///
/// The WebSocket property is the interval, in milliseconds, to send a keep-alive packet over the connection. The default interval is
/// 30000 (30 seconds). The minimum interval is 15000 (15 seconds).
///
/// The default value for the keep-alive interval is read from
/// HKLM:\SOFTWARE\Microsoft\WebSocket\KeepaliveInterval. If a value is not set, the default value of 30000 will be used. It
/// is not possible to have a lower keepalive interval than 15000 milliseconds. If a lower value is set, 15000 milliseconds will be used.
/// Used with WebSocketGetGlobalProperty.
///
[CorrespondingType(typeof(uint))]
WEB_SOCKET_KEEPALIVE_INTERVAL_PROPERTY_TYPE,
///
/// Value:
/// 6
/// Property type:
/// ULONG array
/// The WebSocket property is the versions of the WebSocket protocol that are supported.
/// Used with WebSocketGetGlobalProperty.
///
[CorrespondingType(typeof(uint[]))]
WEB_SOCKET_SUPPORTED_VERSIONS_PROPERTY_TYPE,
}
///
/// The WebSocketAbortHandle function aborts a WebSocket session handle created by WebSocketCreateClientHandle or WebSocketCreateServerHandle.
///
///
/// Type: WEB_SOCKET_HANDLE
/// WebSocket session handle returned by a previous call to WebSocketCreateClientHandle or WebSocketCreateServerHandle.
///
///
/// If the function succeeds, it returns S_OK.
/// If the function fails, it returns a system error code defined in WinError.h.
///
///
/// WebSocketAbortHandle aborts a WEB_SOCKET_HANDLE session handle and any calls to WebSocketSend or WebSocketReceive will return
/// error when called with an aborted handle. WebSocketAbortHandle is a no-op if the WebSocket handshake has not been completed
/// and the session handle has not been initialized. Any send/receive operations that were queued using WebSocketSend or
/// WebSocketReceive will be ready to process using WebSocketGetAction, but attempts to queue additional operations using the
/// aborted handle will result in error.
///
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/nf-websocket-websocketaborthandle void WebSocketAbortHandle( [in]
// WEB_SOCKET_HANDLE hWebSocket );
[PInvokeData("websocket.h", MSDNShortId = "NF:websocket.WebSocketAbortHandle")]
[DllImport(Lib_Websocket, SetLastError = false, ExactSpelling = true)]
public static extern void WebSocketAbortHandle([In] WEB_SOCKET_HANDLE hWebSocket);
/// The WebSocketBeginClientHandshake function begins the client-side handshake.
///
/// Type: WEB_SOCKET_HANDLE
/// WebSocket session handle returned by a previous call to WebSocketCreateClientHandle.
///
///
/// Type: PCSTR*
///
/// 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.
///
///
///
/// Type: ULONG
/// Number of sub-protocols in pszSubprotocols.
///
///
/// Type: PCSTR*
///
/// 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.
///
///
///
/// Type: ULONG
/// Number of extensions in pszExtensions.
///
///
/// Type: const PWEB_SOCKET_HTTP_HEADER
///
/// 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 Host HTTP header as defined in RFC 2616.
///
///
///
/// Type: ULONG
/// Number of request headers in pInitialHeaders.
///
///
/// Type: PWEB_SOCKET_HTTP_HEADER
///
/// On successful output, pointer to 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 pInitialHeaders, the header must be replaced.
///
///
///
/// Type: ULONG*
/// On successful output, number of response headers in pAdditionalHeaders.
///
///
/// Type: HRESULT
/// If the function succeeds, it returns S_OK.
/// If the function fails, it returns a system error code defined in WinError.h.
///
///
/// To complete the client-side handshake, applications must call WebSocketEndClientHandshake. Once the client-server handshake is
/// complete, the application may use the session functions.
///
// 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")]
[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,
[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);
/// The WebSocketBeginServerHandshake function begins the server-side handshake.
///
/// Type: WEB_SOCKET_HANDLE
/// WebSocket session handle returned by a previous call to WebSocketCreateServerHandle.
///
///
/// Type: PCSTR
/// A pointer to a sub-protocol value chosen by the application. Must contain one subprotocol.
///
///
/// Type: PCSTR*
/// A pointer to a list of extensions chosen by the application. Must contain one extension per entry.
///
///
/// Type: ULONG
/// Number of extensions in pszExtensionSelected.
///
///
/// Type: const PWEB_SOCKET_HTTP_HEADER
/// Pointer to an array of WEB_SOCKET_HTTP_HEADER structures that contain the request headers received by the application.
///
///
/// Type: ULONG
/// Number of request headers in pRequestHeaders.
///
///
/// Type: PWEB_SOCKET_HTTP_HEADER*
///
/// 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.
///
///
///
/// Type: ULONG*
/// On successful output, number of response headers in pResponseHeaders.
///
///
/// Type: HRESULT
/// If the function succeeds, it returns S_OK.
/// If the function fails, it returns one of the following or a system error code defined in WinError.h.
///
///
/// Return code
/// Description
///
/// -
/// E_INVALID_PROTOCOL_FORMAT
/// Protocol data had an invalid format.
///
///
///
///
/// 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.
///
// 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")]
[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, MarshalAs(UnmanagedType.LPArray)] WEB_SOCKET_HTTP_HEADER[] pRequestHeaders, uint ulRequestHeaderCount,
[MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 7)] out WEB_SOCKET_HTTP_HEADER[] pResponseHeaders, out uint pulResponseHeaderCount);
/// The WebSocketCompleteAction function completes an action started by WebSocketGetAction.
///
/// Type: WEB_SOCKET_HANDLE
/// WebSocket session handle returned by a previous call to WebSocketCreateClientHandle or WebSocketCreateServerHandle.
///
///
/// Type: PVOID
/// Pointer to an action context handle that was returned by a previous call to WebSocketGetAction.
///
///
/// Type: ULONG
///
/// Number of bytes transferred for the WEB_SOCKET_SEND_TO_NETWORK_ACTION or WEB_SOCKET_RECEIVE_FROM_NETWORK_ACTION actions. This
/// value must be 0 for all other actions.
///
///
///
/// If the function succeeds, it returns S_OK.
/// If the function fails, it returns a system error code defined in WinError.h.
///
///
///
/// Each call to WebSocketGetAction must be paired with a call to WebSocketCompleteAction. For the following network actions, I/O
/// errors can occur:
///
///
/// -
///
/// WEB_SOCKET_SEND_TO_NETWORK_ACTION: if ulBytesTransferred is different than the sum all buffer lengths returned from
/// WebSocketGetAction the current send action is canceled and the next call to
/// WebSocketGetAction will return WEB_SOCKET_INDICATE_SEND_COMPLETE_ACTION even if not
/// all buffers passed to WebSocketSend were processed.
///
///
/// -
///
/// WEB_SOCKET_RECEIVE_FROM_NETWORK_ACTION: if ulBytesTransferred is 0, the current receive action is canceled and the next call
/// to WebSocketGetAction will return WEB_SOCKET_INDICATE_RECEIVE_COMPLETE_ACTION even if
/// not all buffers passed to WebSocketReceive were processed.
///
///
///
///
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/nf-websocket-websocketcompleteaction void WebSocketCompleteAction( [in]
// WEB_SOCKET_HANDLE hWebSocket, [in] PVOID pvActionContext, [in] ULONG ulBytesTransferred );
[PInvokeData("websocket.h", MSDNShortId = "NF:websocket.WebSocketCompleteAction")]
[DllImport(Lib_Websocket, SetLastError = false, ExactSpelling = true)]
public static extern void WebSocketCompleteAction([In] WEB_SOCKET_HANDLE hWebSocket, [In] IntPtr pvActionContext,
uint ulBytesTransferred);
/// The WebSocketCreateClientHandle function creates a client-side WebSocket session handle.
///
/// Type: const PWEB_SOCKET_PROPERTY
/// Pointer to an array of WEB_SOCKET_PROPERTY structures that contain WebSocket session-related properties.
///
///
/// Type: ULONG
/// Number of properties in pProperties.
///
///
/// Type: WEB_SOCKET_HANDLE*
/// On successful output, pointer to a newly allocated client-side WebSocket session handle.
///
///
/// Type: HRESULT
/// If the function succeeds, it returns S_OK.
/// If the function fails, it returns a system error code defined in WinError.h.
///
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/nf-websocket-websocketcreateclienthandle HRESULT
// WebSocketCreateClientHandle( [in] const PWEB_SOCKET_PROPERTY pProperties, [in] ULONG ulPropertyCount, [out] WEB_SOCKET_HANDLE
// *phWebSocket );
[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);
/// The WebSocketCreateServerHandle function creates a server-side WebSocket session handle.
///
/// Type: const PWEB_SOCKET_PROPERTY
/// Pointer to an array of WEB_SOCKET_PROPERTY structures that contain WebSocket session-related properties.
///
///
/// Type: ULONG
/// Number of properties in pProperties.
///
///
/// Type: WEB_SOCKET_HANDLE*
/// On successful output, pointer to a newly allocated server-side WebSocket session handle.
///
///
/// Type: HRESULT
/// If the function succeeds, it returns S_OK.
/// If the function fails, it returns a system error code defined in WinError.h.
///
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/nf-websocket-websocketcreateserverhandle HRESULT
// WebSocketCreateServerHandle( [in] const PWEB_SOCKET_PROPERTY pProperties, [in] ULONG ulPropertyCount, [out] WEB_SOCKET_HANDLE
// *phWebSocket );
[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);
///
/// The WebSocketDeleteHandle function deletes a WebSocket session handle created by WebSocketCreateClientHandle or WebSocketCreateServerHandle.
///
///
/// Type: WEB_SOCKET_HANDLE
/// WebSocket session handle returned by a previous call to WebSocketCreateClientHandle or WebSocketCreateServerHandle.
///
///
/// If the function succeeds, it returns S_OK.
/// If the function fails, it returns a system error code defined in WinError.h.
///
///
/// Any use of a deleted WEB_SOCKET_HANDLE session handle may result in an access violation.
///
/// Before an application deletes a session handle, it must ensure that all operations have been processed. Applications may use
/// WebSocketAbortHandle to abort any queued operations before calling WebSocketDeleteHandle.
///
///
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/nf-websocket-websocketdeletehandle void WebSocketDeleteHandle( [in]
// WEB_SOCKET_HANDLE hWebSocket );
[PInvokeData("websocket.h", MSDNShortId = "NF:websocket.WebSocketDeleteHandle")]
[DllImport(Lib_Websocket, SetLastError = false, ExactSpelling = true)]
public static extern void WebSocketDeleteHandle([In] WEB_SOCKET_HANDLE hWebSocket);
/// The WebSocketEndClientHandshake function completes the client-side handshake.
///
/// Type: WEB_SOCKET_HANDLE
/// WebSocket session handle returned by a previous call to WebSocketCreateClientHandle.
///
///
/// Type: const PWEB_SOCKET_HTTP_HEADER
/// Pointer to an array of WEB_SOCKET_HTTP_HEADER structures that contain the response headers received by the application.
///
///
/// Type: ULONG
/// Number of response headers in pResponseHeaders.
///
///
/// Type: ULONG*
///
/// On input, pointer to an array allocated by the application. On successful output, pointer to an array of numbers that represent the
/// extensions chosen by the server during the client-server handshake. These number are the zero-based indices into the extensions array
/// passed to pszExtensions in WebSocketBeginClientHandshake.
///
///
///
/// Type: ULONG*
///
/// On input, number of extensions allocated in pulSelectedExtensions. This must be at least equal to the number passed to
/// ulExtensionCount in WebSocketEndClientHandshake. On successful output, number of extensions returned in pulSelectedExtensions.
///
///
///
/// Type: ULONG*
///
/// On successful output, pointer to a number that represents the sub-protocol chosen by the server during the client-server handshake.
/// This number is the zero-based index into the sub-protocols array passed to pszSubprotocols in WebSocketBeginClientHandshake.
///
///
///
/// Type: HRESULT
/// If the function succeeds, it returns S_OK.
/// If the function fails, it returns one of the following or a system error code defined in WinError.h.
///
///
/// Return code
/// Description
///
/// -
/// E_INVALID_PROTOCOL_FORMAT
/// Protocol data had an invalid format.
///
/// -
/// E_UNSUPPORTED_SUBPROTOCOL
/// Server does not accept any of the sub-protocols specified by the application.
///
/// -
/// E_UNSUPPORTED_EXTENSION
/// Server does not accept extensions specified by the application.
///
///
///
///
/// This function must be called to complete the client-side handshake after a previous call to WebSocketBeginClientHandshake. Once the
/// client-server handshake is complete, the application may use the session functions.
///
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/nf-websocket-websocketendclienthandshake HRESULT
// WebSocketEndClientHandshake( [in] WEB_SOCKET_HANDLE hWebSocket, [in] const PWEB_SOCKET_HTTP_HEADER pResponseHeaders, [in] ULONG
// ulReponseHeaderCount, [in, out, optional] ULONG *pulSelectedExtensions, [in, out, optional] ULONG *pulSelectedExtensionCount, [in,
// out, optional] ULONG *pulSelectedSubprotocol );
[PInvokeData("websocket.h", MSDNShortId = "NF:websocket.WebSocketEndClientHandshake")]
[DllImport(Lib_Websocket, SetLastError = false, ExactSpelling = true)]
public static extern HRESULT WebSocketEndClientHandshake([In] WEB_SOCKET_HANDLE hWebSocket,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] WEB_SOCKET_HTTP_HEADER[] pResponseHeaders,
uint ulReponseHeaderCount, [In, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] pulSelectedExtensions,
ref uint pulSelectedExtensionCount, out uint pulSelectedSubprotocol);
/// The WebSocketEndClientHandshake function completes the client-side handshake.
///
/// Type: WEB_SOCKET_HANDLE
/// WebSocket session handle returned by a previous call to WebSocketCreateClientHandle.
///
///
/// Type: const PWEB_SOCKET_HTTP_HEADER
/// Pointer to an array of WEB_SOCKET_HTTP_HEADER structures that contain the response headers received by the application.
///
///
/// Type: ULONG
/// Number of response headers in pResponseHeaders.
///
///
/// Type: ULONG*
///
/// On input, pointer to an array allocated by the application. On successful output, pointer to an array of numbers that represent the
/// extensions chosen by the server during the client-server handshake. These number are the zero-based indices into the extensions array
/// passed to pszExtensions in WebSocketBeginClientHandshake.
///
///
///
/// Type: ULONG*
///
/// On input, number of extensions allocated in pulSelectedExtensions. This must be at least equal to the number passed to
/// ulExtensionCount in WebSocketEndClientHandshake. On successful output, number of extensions returned in pulSelectedExtensions.
///
///
///
/// Type: ULONG*
///
/// On successful output, pointer to a number that represents the sub-protocol chosen by the server during the client-server handshake.
/// This number is the zero-based index into the sub-protocols array passed to pszSubprotocols in WebSocketBeginClientHandshake.
///
///
///
/// Type: HRESULT
/// If the function succeeds, it returns S_OK.
/// If the function fails, it returns one of the following or a system error code defined in WinError.h.
///
///
/// Return code
/// Description
///
/// -
/// E_INVALID_PROTOCOL_FORMAT
/// Protocol data had an invalid format.
///
/// -
/// E_UNSUPPORTED_SUBPROTOCOL
/// Server does not accept any of the sub-protocols specified by the application.
///
/// -
/// E_UNSUPPORTED_EXTENSION
/// Server does not accept extensions specified by the application.
///
///
///
///
/// This function must be called to complete the client-side handshake after a previous call to WebSocketBeginClientHandshake. Once the
/// client-server handshake is complete, the application may use the session functions.
///
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/nf-websocket-websocketendclienthandshake HRESULT
// WebSocketEndClientHandshake( [in] WEB_SOCKET_HANDLE hWebSocket, [in] const PWEB_SOCKET_HTTP_HEADER pResponseHeaders, [in] ULONG
// ulReponseHeaderCount, [in, out, optional] ULONG *pulSelectedExtensions, [in, out, optional] ULONG *pulSelectedExtensionCount, [in,
// out, optional] ULONG *pulSelectedSubprotocol );
[PInvokeData("websocket.h", MSDNShortId = "NF:websocket.WebSocketEndClientHandshake")]
[DllImport(Lib_Websocket, SetLastError = false, ExactSpelling = true)]
public static extern HRESULT WebSocketEndClientHandshake([In] WEB_SOCKET_HANDLE hWebSocket,
[In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] WEB_SOCKET_HTTP_HEADER[] pResponseHeaders,
uint ulReponseHeaderCount, [In, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] uint[] pulSelectedExtensions,
[In, Optional] IntPtr pulSelectedExtensionCount, [In, Optional] IntPtr pulSelectedSubprotocol);
/// The WebSocketEndServerHandshake function completes the server-side handshake.
///
/// Type: WEB_SOCKET_HANDLE
/// WebSocket session handle returned by a previous call to WebSocketCreateServerHandle.
///
///
/// Type: HRESULT
/// If the function succeeds, it returns S_OK.
/// If the function fails, it returns a system error code defined in WinError.h.
///
///
/// This function may be called to complete the server-side handshake after a previous call to WebSocketBeginServerHandshake; however,
/// calling this function is optional and applications may use the session functions without first calling this function. This function
/// frees all internal handshake related structures and allocates data session buffers. All operations handled by this function will be
/// performed internally even if the function is not called.
///
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/nf-websocket-websocketendserverhandshake HRESULT
// WebSocketEndServerHandshake( [in] WEB_SOCKET_HANDLE hWebSocket );
[PInvokeData("websocket.h", MSDNShortId = "NF:websocket.WebSocketEndServerHandshake")]
[DllImport(Lib_Websocket, SetLastError = false, ExactSpelling = true)]
public static extern HRESULT WebSocketEndServerHandshake([In] WEB_SOCKET_HANDLE hWebSocket);
/// The WebSocketGetAction function returns an action from a call to WebSocketSend, WebSocketReceive or WebSocketCompleteAction.
///
/// Type: WEB_SOCKET_HANDLE
/// WebSocket session handle returned by a previous call to WebSocketCreateClientHandle or WebSocketCreateServerHandle.
///
///
/// Type: WEB_SOCKET_ACTION_QUEUE
/// Enumeration that specifies whether to query the send queue, the receive queue, or both.
///
///
/// Type: WEB_SOCKET_BUFFER*
/// Pointer to an array of WEB_SOCKET_BUFFER structures that contain WebSocket buffer data.
///
/// Note Do not allocate or deallocate memory for WEB_SOCKET_BUFFER structures, because they will be overwritten by
/// WebSocketGetAction. The memory for buffers returned by WebSocketGetAction are managed by the library.
///
///
///
/// Type: ULONG*
///
/// On input, pointer to a value that specifies the number of elements in pDataBuffers. On successful output, number of elements
/// that were actually returned in pDataBuffers.
///
///
///
/// Type: WEB_SOCKET_ACTION*
///
/// On successful output, pointer to a WEB_SOCKET_ACTION enumeration that specifies the action returned from the query to the queue
/// defines in eActionQueue.
///
///
///
/// Type: WEB_SOCKET_BUFFER_TYPE*
///
/// On successful output, pointer to a WEB_SOCKET_BUFFER_TYPE enumeration that specifies the type of Web Socket buffer data returned in pDataBuffers.
///
///
///
/// Type: PVOID*
///
/// On successful output, pointer to an application context handle. The context returned here was initially passed to WebSocketSend or
/// WebSocketReceive. pvApplicationContext is not set if pAction is WEB_SOCKET_NO_ACTION or
/// WEB_SOCKET_SEND_TO_NETWORK_ACTION when sending a pong in response to receiving a ping.
///
///
///
/// Type: PVOID*
/// On successful output, pointer to an action context handle. This handle is passed into a subsequent call WebSocketCompleteAction.
///
///
/// Type: HRESULT
/// If the function succeeds, it returns S_OK.
/// If the function fails, it returns one of the following or a system error code defined in WinError.h.
///
///
/// Return code
/// Description
///
/// -
/// E_INVALID_PROTOCOL_FORMAT
/// Protocol data had invalid format. This is only returned for receive operations.
///
/// -
/// E_INVALID_PROTOCOL_OPERATION
/// Protocol performed invalid operations. This is only returned for receive operations.
///
///
///
///
/// Each call to WebSocketGetAction must be paired with a call to WebSocketCompleteAction.
///
/// If the ulBytesTransferred parameter of WebSocketCompleteAction is different than the sum of all buffer lengths for the
/// WEB_SOCKET_SEND_TO_NETWORK_ACTION action or is zero for the WEB_SOCKET_RECEIVE_FROM_NETWORK_ACTION action, the WebSocket
/// application will not send or receive all of the data requested.
///
/// WebSocketGetAction will return in pAction:
///
/// -
/// WEB_SOCKET_INDICATE_SEND_COMPLETE_ACTION once an operation queued by WebSocketSend is completed.
///
/// -
/// WEB_SOCKET_INDICATE_RECEIVE_COMPLETE_ACTION once an operation queued by WebSocketReceive is completed.
///
///
///
/// There may be only one outstanding send and receive operation at a time, so the next action will be returned once the previous one has
/// been completed using WebSocketCompleteAction.
///
///
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/nf-websocket-websocketgetaction HRESULT WebSocketGetAction( [in]
// WEB_SOCKET_HANDLE hWebSocket, [in] WEB_SOCKET_ACTION_QUEUE eActionQueue, [in, out] WEB_SOCKET_BUFFER *pDataBuffers, [in, out] ULONG
// *pulDataBufferCount, [out] WEB_SOCKET_ACTION *pAction, [out] WEB_SOCKET_BUFFER_TYPE *pBufferType, [out, optional] PVOID
// *pvApplicationContext, [out] PVOID *pvActionContext );
[PInvokeData("websocket.h", MSDNShortId = "NF:websocket.WebSocketGetAction")]
[DllImport(Lib_Websocket, SetLastError = false, ExactSpelling = true)]
public static extern HRESULT WebSocketGetAction([In] WEB_SOCKET_HANDLE hWebSocket, [In] WEB_SOCKET_ACTION_QUEUE eActionQueue,
[In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] WEB_SOCKET_BUFFER[] pDataBuffers,
ref uint pulDataBufferCount, out WEB_SOCKET_ACTION pAction, out WEB_SOCKET_BUFFER_TYPE pBufferType,
out IntPtr pvApplicationContext, out IntPtr pvActionContext);
/// The WebSocketGetGlobalProperty function gets a single WebSocket property.
///
/// Type: WEB_SOCKET_PROPERTY
/// A WebSocket property.
///
///
/// Type: PVOID
/// A pointer to the property value. The pointer must have an alignment compatible with the type of the property.
///
///
/// Type: ULONG*
/// The size, in bytes, of the property pointed to by pvValue.
///
///
/// Type: HRESULT
/// If the function succeeds, it returns S_OK.
/// If the function fails, it returns a system error code defined in WinError.h.
///
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/nf-websocket-websocketgetglobalproperty HRESULT
// WebSocketGetGlobalProperty( [in] WEB_SOCKET_PROPERTY_TYPE eType, [in, out] PVOID pvValue, [in, out] ULONG *ulSize );
[PInvokeData("websocket.h", MSDNShortId = "NF:websocket.WebSocketGetGlobalProperty")]
[DllImport(Lib_Websocket, SetLastError = false, ExactSpelling = true)]
public static extern HRESULT WebSocketGetGlobalProperty([In] WEB_SOCKET_PROPERTY_TYPE eType, [In, Out] IntPtr pvValue,
ref uint ulSize);
/// The WebSocketGetGlobalProperty function gets a single WebSocket property.
///
/// Type: WEB_SOCKET_PROPERTY
/// A WebSocket property.
///
///
/// The property value.
///
///
/// Type: HRESULT
/// If the function succeeds, it returns S_OK.
/// If the function fails, it returns a system error code defined in WinError.h.
///
[PInvokeData("websocket.h", MSDNShortId = "NF:websocket.WebSocketGetGlobalProperty")]
public static HRESULT WebSocketGetGlobalProperty([In] WEB_SOCKET_PROPERTY_TYPE eType, out T pvValue)
{
if (typeof(T).IsArray)
{
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();
uint sz = mem.Size;
HRESULT ret = WebSocketGetGlobalProperty(eType, mem, ref sz);
pvValue = ret.Succeeded ? mem.ToStructure() : default;
return ret;
}
}
/// The WebSocketReceive function adds a receive operation to the protocol component operation queue.
///
/// Type: WEB_SOCKET_HANDLE
/// WebSocket session handle returned by a previous call to WebSocketCreateClientHandle or WebSocketCreateServerHandle.
///
///
/// Type: WEB_SOCKET_BUFFER*
///
/// A pointer to an array of WEB_SOCKET_BUFFER structures that WebSocket data will be written to when it is returned by
/// WebSocketGetAction. If NULL, WebSocketGetAction will return an internal buffer that enables zero-copy scenarios.
///
///
/// Note Once WEB_SOCKET_INDICATE_RECEIVE_COMPLETE is returned by WebSocketGetAction for this action, the memory pointer to by
/// pBuffer can be reclaimed.
///
///
///
/// Type: PVOID
/// A pointer to an application context handle that will be returned by a subsequent call to WebSocketGetAction.
///
///
/// Type: HRESULT
/// If the function succeeds, it returns S_OK.
/// If the function fails, it returns one of the following or a system error code defined in WinError.h.
///
///
/// Return code
/// Description
///
/// -
/// E_INVALID_PROTOCOL_OPERATION
/// Protocol performed an invalid operation.
///
///
///
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/nf-websocket-websocketreceive HRESULT WebSocketReceive( [in]
// WEB_SOCKET_HANDLE hWebSocket, [in, optional] WEB_SOCKET_BUFFER *pBuffer, [in, optional] PVOID pvContext );
[PInvokeData("websocket.h", MSDNShortId = "NF:websocket.WebSocketReceive")]
[DllImport(Lib_Websocket, SetLastError = false, ExactSpelling = true)]
public static extern HRESULT WebSocketReceive([In] WEB_SOCKET_HANDLE hWebSocket,
[In, Optional, MarshalAs(UnmanagedType.LPArray)] WEB_SOCKET_BUFFER[] pBuffer, [In, Optional] IntPtr pvContext);
/// The WebSocketSend function adds a send operation to the protocol component operation queue.
///
/// Type: WEB_SOCKET_HANDLE
/// WebSocket session handle returned by a previous call to WebSocketCreateClientHandle or WebSocketCreateServerHandle.
///
///
/// Type: WEB_SOCKET_BUFFER_TYPE
/// The type of WebSocket buffer data to send in pBuffer.
///
///
/// Type: WEB_SOCKET_BUFFER*
///
/// A pointer to an array of WEB_SOCKET_BUFFER structures that contains WebSocket buffer data to send. If BufferType is
/// WEB_SOCKET_PING_PONG_BUFFER_TYPE or WEB_SOCKET_UNSOLICITED_PONG_BUFFER_TYPE, pBuffer must be NULL.
///
///
/// Note Once WEB_SOCKET_INDICATE_SEND_COMPLETE is returned by WebSocketGetAction for this action, the memory pointer to by
/// pBuffer can be reclaimed.
///
///
///
/// Type: PVOID
/// A pointer to an application context handle that will be returned by a subsequent call to WebSocketGetAction.
///
///
/// Type: HRESULT
/// If the function succeeds, it returns S_OK.
/// If the function fails, it returns one of the following or a system error code defined in WinError.h.
///
///
/// Return code
/// Description
///
/// -
/// E_INVALID_PROTOCOL_OPERATION
/// Protocol performed an invalid operation.
///
///
///
/// After an application sends a WEB_SOCKET_CLOSE_BUFFER_TYPE WebSocket buffer successfully, it can only send control frames.
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/nf-websocket-websocketsend HRESULT WebSocketSend( [in] WEB_SOCKET_HANDLE
// hWebSocket, [in] WEB_SOCKET_BUFFER_TYPE BufferType, [in, optional] WEB_SOCKET_BUFFER *pBuffer, [in, optional] PVOID Context );
[PInvokeData("websocket.h", MSDNShortId = "NF:websocket.WebSocketSend")]
[DllImport(Lib_Websocket, SetLastError = false, ExactSpelling = true)]
public static extern HRESULT WebSocketSend([In] WEB_SOCKET_HANDLE hWebSocket, [In] WEB_SOCKET_BUFFER_TYPE BufferType,
[In, Optional, MarshalAs(UnmanagedType.LPArray)] WEB_SOCKET_BUFFER[] pBuffer, [In, Optional] IntPtr Context);
/// The WEB_SOCKET_BUFFER structure contains data for a specific WebSocket action.
///
/// Application must use the Data struct for all buffer types except WEB_SOCKET_CLOSE_BUFFER_TYPE. The CloseStatus
/// struct is used for WEB_SOCKET_CLOSE_BUFFER_TYPE.
///
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/ns-websocket-web_socket_buffer typedef union _WEB_SOCKET_BUFFER { struct
// { PBYTE pbBuffer; ULONG ulBufferLength; } Data; struct { PBYTE pbReason; ULONG ulReasonLength; USHORT usStatus; } CloseStatus; }
// WEB_SOCKET_BUFFER, *PWEB_SOCKET_BUFFER;
[PInvokeData("websocket.h", MSDNShortId = "NS:websocket._WEB_SOCKET_BUFFER")]
[StructLayout(LayoutKind.Explicit)]
public struct WEB_SOCKET_BUFFER
{
///
[FieldOffset(0)]
public DATA Data;
///
[FieldOffset(0)]
public CLOSESTATUS CloseStatus;
///
public struct DATA
{
/// Type: PBYTE Pointer to the WebSocket buffer data.
public IntPtr pbBuffer;
/// Type: ULONG Length, in bytes, of the buffer pointed to by pbBuffer.
public uint ulBufferLength;
}
///
public struct CLOSESTATUS
{
///
/// Type: PBYTE A point to a UTF-8 string that represents the reason the connection is closed. If ulReasonLength is 0, this must
/// be NULL.
///
public IntPtr pbReason;
///
/// Type: ULONG Length, in bytes, of the buffer pointed to by pbReason. It cannot exceed WEB_SOCKET_MAX_CLOSE_REASON_LENGTH (123 bytes).
///
public uint ulReasonLength;
/// WEB_SOCKET_CLOSE_STATUS enumeration that specifies the WebSocket status.
public WEB_SOCKET_CLOSE_STATUS usStatus;
}
/// Initializes a new instance of the struct.
/// The WebSocket buffer data.
public WEB_SOCKET_BUFFER(SafeAllocatedMemoryHandle mem)
{
CloseStatus = default;
Data.pbBuffer = mem;
Data.ulBufferLength = mem.Size;
}
/// Initializes a new instance of the struct.
/// A UTF-8 string that represents the reason the connection is closed.
/// The WebSocket status.
public WEB_SOCKET_BUFFER(SafeAllocatedMemoryHandle reason, WEB_SOCKET_CLOSE_STATUS closeStatus)
{
Data = default;
CloseStatus.pbReason = reason ?? IntPtr.Zero;
CloseStatus.ulReasonLength = reason?.Size ?? 0;
CloseStatus.usStatus = closeStatus;
}
}
/// Provides a handle to a WebSocket.
[StructLayout(LayoutKind.Sequential)]
public struct WEB_SOCKET_HANDLE : IHandle
{
private readonly IntPtr handle;
/// Initializes a new instance of the struct.
/// An object that represents the pre-existing handle to use.
public WEB_SOCKET_HANDLE(IntPtr preexistingHandle) => handle = preexistingHandle;
/// Returns an invalid handle by instantiating a object with .
public static WEB_SOCKET_HANDLE NULL => new(IntPtr.Zero);
/// Gets a value indicating whether this instance is a null handle.
public bool IsNull => handle == IntPtr.Zero;
/// Implements the operator !.
/// The handle.
/// The result of the operator.
public static bool operator !(WEB_SOCKET_HANDLE h1) => h1.IsNull;
/// Performs an explicit conversion from to .
/// The handle.
/// The result of the conversion.
public static explicit operator IntPtr(WEB_SOCKET_HANDLE h) => h.handle;
/// Performs an implicit conversion from to .
/// The pointer to a handle.
/// The result of the conversion.
public static implicit operator WEB_SOCKET_HANDLE(IntPtr h) => new(h);
/// Implements the operator !=.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator !=(WEB_SOCKET_HANDLE h1, WEB_SOCKET_HANDLE h2) => !(h1 == h2);
/// Implements the operator ==.
/// The first handle.
/// The second handle.
/// The result of the operator.
public static bool operator ==(WEB_SOCKET_HANDLE h1, WEB_SOCKET_HANDLE h2) => h1.Equals(h2);
///
public override bool Equals(object obj) => obj is WEB_SOCKET_HANDLE h && handle == h.handle;
///
public override int GetHashCode() => handle.GetHashCode();
///
public IntPtr DangerousGetHandle() => handle;
}
/// The WEB_SOCKET_HTTP_HEADER structure contains an HTTP header.
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/ns-websocket-web_socket_http_header typedef struct
// _WEB_SOCKET_HTTP_HEADER { PCHAR pcName; ULONG ulNameLength; PCHAR pcValue; ULONG ulValueLength; } WEB_SOCKET_HTTP_HEADER, *PWEB_SOCKET_HTTP_HEADER;
[PInvokeData("websocket.h", MSDNShortId = "NS:websocket._WEB_SOCKET_HTTP_HEADER")]
[StructLayout(LayoutKind.Sequential)]
public struct WEB_SOCKET_HTTP_HEADER
{
///
/// Type: PCHAR
/// A pointer to the HTTP header name. The name must not contain a colon character.
///
[MarshalAs(UnmanagedType.LPStr)]
public string pcName;
///
/// Type: ULONG
/// Length, in characters, of the HTTP header pointed to by pcName.
///
public uint ulNameLength;
///
/// Type: PCHAR
/// A pointer to the HTTP header value.
///
[MarshalAs(UnmanagedType.LPStr)]
public string pcValue;
///
/// Type: ULONG
/// Length, in characters, of the HTTP value pointed to by pcValue.
///
public uint ulValueLength;
/// Initializes a new instance of the struct.
/// The HTTP header name.
/// The header value.
public WEB_SOCKET_HTTP_HEADER(string name, string value)
{
pcName = name;
ulNameLength = (uint)name.Length;
pcValue = value;
ulValueLength = (uint)value.Length;
}
}
/// The WEB_SOCKET_PROPERTY structure contains a single WebSocket property.
// https://learn.microsoft.com/en-us/windows/win32/api/websocket/ns-websocket-web_socket_property typedef struct _WEB_SOCKET_PROPERTY {
// WEB_SOCKET_PROPERTY_TYPE Type; PVOID pvValue; ULONG ulValueSize; } WEB_SOCKET_PROPERTY, *PWEB_SOCKET_PROPERTY;
[PInvokeData("websocket.h", MSDNShortId = "NS:websocket._WEB_SOCKET_PROPERTY")]
[StructLayout(LayoutKind.Sequential)]
public struct WEB_SOCKET_PROPERTY
{
///
/// Type: WEB_SOCKET_PROPERTY_TYPE
/// The WebSocket property type.
///
public WEB_SOCKET_PROPERTY_TYPE Type;
///
/// Type: PVOID
/// A pointer to the value to set. The pointer must have an alignment compatible with the type of the property.
///
public IntPtr pvValue;
///
/// Type: ULONG
/// The size, in bytes, of the property pointed to by pvValue.
///
public uint ulValueSize;
/// Initializes a new instance of the struct.
/// The WebSocket property type.
/// The value to set.
public WEB_SOCKET_PROPERTY(WEB_SOCKET_PROPERTY_TYPE type, SafeAllocatedMemoryHandle value)
{
Type = type;
pvValue = value;
ulValueSize = value.Size;
}
}
/// Provides a for that is disposed using .
public class SafeWEB_SOCKET_HANDLE : SafeHANDLE
{
/// Initializes a new instance of the class and assigns an existing handle.
/// An object that represents the pre-existing handle to use.
/// to reliably release the handle during the finalization phase; otherwise, (not recommended).
public SafeWEB_SOCKET_HANDLE(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { }
/// Initializes a new instance of the class.
private SafeWEB_SOCKET_HANDLE() : base() { }
/// Performs an implicit conversion from to .
/// The safe handle instance.
/// The result of the conversion.
public static implicit operator WEB_SOCKET_HANDLE(SafeWEB_SOCKET_HANDLE h) => h.handle;
///
protected override bool InternalReleaseHandle() { WebSocketDeleteHandle(handle); return true; }
}
}