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; } } }