From 7d9101e9770c9a6d4165cbfd41e994bdb98ed64f Mon Sep 17 00:00:00 2001 From: David Hall Date: Wed, 26 Oct 2022 23:03:47 -0600 Subject: [PATCH] Added Microsoft-specific winsock constructs to Ws2_32 --- PInvoke/Ws2_32/MSWSock.cs | 4319 ++++++++++++++++++++++++++++++---- PInvoke/Ws2_32/WinSock2.cs | 5266 +++++++++++++++++++++--------------------- PInvoke/Ws2_32/mstcpip.cs | 2098 ++++++++--------- PInvoke/Ws2_32/mswsockdef.cs | 144 ++ PInvoke/Ws2_32/ws2def.cs | 4326 +++++++++++++++++----------------- PInvoke/Ws2_32/ws2ipdef.cs | 1519 ++++++------ 6 files changed, 10690 insertions(+), 6982 deletions(-) create mode 100644 PInvoke/Ws2_32/mswsockdef.cs diff --git a/PInvoke/Ws2_32/MSWSock.cs b/PInvoke/Ws2_32/MSWSock.cs index 55be5c61..190b75aa 100644 --- a/PInvoke/Ws2_32/MSWSock.cs +++ b/PInvoke/Ws2_32/MSWSock.cs @@ -1,412 +1,3943 @@ using System; using System.Runtime.InteropServices; +using System.Text; +using System.Threading; using Vanara.InteropServices; -namespace Vanara.PInvoke +namespace Vanara.PInvoke; + +public static partial class Ws2_32 { - public static partial class Ws2_32 +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + public const int SO_CONNDATA = 0x7000; + public const int SO_CONNDATALEN = 0x7004; + /// + /// Returns the number of seconds a socket has been connected. This socket option is valid for connection oriented protocols only. + /// + [CorrespondingType(typeof(uint))] + public const int SO_CONNECT_TIME = 0x700C; + public const int SO_CONNOPT = 0x7001; + public const int SO_CONNOPTLEN = 0x7005; + public const int SO_DISCDATA = 0x7002; + public const int SO_DISCDATALEN = 0x7006; + public const int SO_DISCOPT = 0x7003; + public const int SO_DISCOPTLEN = 0x7007; + public const int SO_MAXDG = 0x7009; + public const int SO_MAXPATHDG = 0x700A; + public const int SO_OPENTYPE = 0x7008; + public const int SO_SYNCHRONOUS_ALERT = 0x10; + public const int SO_SYNCHRONOUS_NONALERT = 0x20; + public const int SO_UPDATE_ACCEPT_CONTEXT = 0x700B; + public const int SO_UPDATE_CONNECT_CONTEXT = 0x7010; + public const int TCP_BSDURGENT = 0x7000; + public static readonly uint SIO_BASE_HANDLE = _WSAIOR(IOC_WS2, 34); + public static readonly uint SIO_BSP_HANDLE = _WSAIOR(IOC_WS2, 27); + public static readonly uint SIO_BSP_HANDLE_POLL = _WSAIOR(IOC_WS2, 29); + public static readonly uint SIO_BSP_HANDLE_SELECT = _WSAIOR(IOC_WS2, 28); + public static readonly uint SIO_EXT_POLL = _WSAIORW(IOC_WS2, 31); + public static readonly uint SIO_EXT_SELECT = _WSAIORW(IOC_WS2, 30); + public static readonly uint SIO_EXT_SENDMSG = _WSAIORW(IOC_WS2, 32); + public static readonly uint SIO_SOCKET_CLOSE_NOTIFY = _WSAIOW(IOC_VENDOR, 13); + public static readonly uint SIO_UDP_CONNRESET = _WSAIOW(IOC_VENDOR, 12); + public static readonly uint SIO_UDP_NETRESET = _WSAIOW(IOC_VENDOR, 15); +#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member + + /// GUID value used by SIO_GET_EXTENSION_FUNCTION_POINTER to get the LPFN_WSARECVMSG (WSARecvMsg) extension function. + public static readonly Guid WSAID_WSARECVMSG = new(0xf689d7c8,0x6f1f,0x436b,0x8a,0x53,0xe5,0x4f,0xe3,0x51,0xc3,0x22); + + /// GUID value used by SIO_GET_EXTENSION_FUNCTION_POINTER to get the LPFN_WSASENDMSG (WSASendMsg) extension function. + public static readonly Guid WSAID_WSASENDMSG = new(0xa441e712,0x754f,0x43ca,0x84,0xa7,0x0d,0xee,0x44,0xcf,0x60,0x6d); + + /// GUID value used by SIO_GET_EXTENSION_FUNCTION_POINTER to get the LPFN_WSACONNECTEX extension function. + public static readonly Guid WSAID_CONNECTEX = new(0x25a207b9,0xddf3,0x4660,0x8e,0xe9,0x76,0xe5,0x8c,0x74,0x06,0x3e); + + /// GUID value used by SIO_GET_EXTENSION_FUNCTION_POINTER to get the LPFN_WSADISCONNECTEX extension function. + public static readonly Guid WSAID_DISCONNECTEX = new( 0x7fda2e11,0x8630,0x436f,0xa0, 0x31, 0xf5, 0x36, 0xa6, 0xee, 0xc1, 0x57); + + /// GUID value used by SIO_GET_EXTENSION_FUNCTION_POINTER to get the LPFN_WSAPOLL extension function. + public static readonly Guid WSAID_WSAPOLL = new(0x18C76F85,0xDC66,0x4964,0x97,0x2E,0x23,0xC2,0x72,0x38,0x31,0x2B); + + /// GUID value used by SIO_GET_EXTENSION_FUNCTION_POINTER to get the LPFN_WSAMULTIPLE_RIO extension function. + public static readonly Guid WSAID_MULTIPLE_RIO = new(0x8509e081,0x96dd,0x4005,0xb1,0x65,0x9e,0x2e,0xe8,0xc7,0x9e,0x3f); + + /// GUID value used by SIO_GET_EXTENSION_FUNCTION_POINTER to get the LPFN_WSATRANSMITPACKETS extension function. + public static readonly Guid WSAID_TRANSMITPACKETS = new( 0xd9689da0,0x1f90,0x11d3,0x99,0x71,0x00,0xc0,0x4f,0x68,0xc8,0x76); + + /// GUID value used by SIO_GET_EXTENSION_FUNCTION_POINTER to get the LPFN_WSATRANSMITFILE extension function. + public static readonly Guid WSAID_TRANSMITFILE = new( 0xb5367df0,0xcbac,0x11cf,0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92); + + /// GUID value used by SIO_GET_EXTENSION_FUNCTION_POINTER to get the LPFN_WSAACCEPTEX (AcceptEx) extension function. + public static readonly Guid WSAID_ACCEPTEX = new( 0xb5367df1,0xcbac,0x11cf,0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92); + + /// GUID value used by SIO_GET_EXTENSION_FUNCTION_POINTER to get the LPFN_WSAGETACCEPTEXSOCKADDRS extension function. + public static readonly Guid WSAID_GETACCEPTEXSOCKADDRS = new(0xb5367df2,0xcbac,0x11cf,0x95,0xca,0x00,0x80,0x5f,0x48,0xa1,0x92); + + /// + public static readonly Guid NLA_NAMESPACE_GUID = new( 0x6642243a,0x3ba8,0x4aa6,0xba,0xa5,0x2e,0xb,0xd7,0x1f,0xdd,0x83); + + /// + public static readonly Guid NLA_SERVICE_CLASS_GUID = new(0x37e515,0xb5c9,0x4a43,0xba,0xda,0x8b,0x48,0xa8,0x7a,0xd2,0x39); + + private const string Lib_Mswsock = "mswsock.dll"; + + /// + /// The ConnectEx function establishes a connection to a specified socket, and optionally sends data once the connection is + /// established. The ConnectEx function is only supported on connection-oriented sockets. + /// + /// A descriptor that identifies an unconnected, previously bound socket. See Remarks for more information. + /// + /// A pointer to a sockaddr structure that specifies the address to which to connect. For IPv4, the sockaddr contains + /// AF_INET for the address family, the destination IPv4 address, and the destination port. For IPv6, the sockaddr + /// structure contains AF_INET6 for the address family, the destination IPv6 address, the destination port, and may contain + /// additional IPv6 flow and scope-id information. + /// + /// The length, in bytes, of the sockaddr structure pointed to by the name parameter. + /// + /// A pointer to the buffer to be transferred after a connection is established. This parameter is optional. If the TCP_FASTOPEN option + /// is enabled on s before ConnectEx is called, then some of this data may be sent during connection establishment. + /// + /// + /// The length, in bytes, of data pointed to by the lpSendBuffer parameter. This parameter is ignored when the lpSendBuffer + /// parameter is NULL. + /// + /// + /// On successful return, this parameter points to a DWORD value that indicates the number of bytes that were sent after the + /// connection was established. The bytes sent are from the buffer pointed to by the lpSendBuffer parameter. This parameter is + /// ignored when the lpSendBuffer parameter is NULL. + /// + /// + /// An OVERLAPPED structure used to process the request. The lpOverlapped parameter must be specified, and cannot be NULL. + /// + /// + /// + /// On success, the ConnectEx function returns TRUE. On failure, the function returns FALSE. Use the WSAGetLastError + /// function to get extended error information. If a call to the WSAGetLastError function returns ERROR_IO_PENDING, the + /// operation initiated successfully and is in progress. Under such circumstances, the call may still fail when the overlapped operation completes. + /// + /// + /// If the error code returned is WSAECONNREFUSED, WSAENETUNREACH, or WSAETIMEDOUT, the application can call ConnectEx, + /// WSAConnect, or connect again on the same socket. + /// + /// + /// + /// Error code + /// Description + /// + /// + /// WSANOTINITIALISED + /// A successful WSAStartup function call must occur before using ConnectEx. + /// + /// + /// WSAENETDOWN + /// The network subsystem has failed. + /// + /// + /// WSAEADDRINUSE + /// + /// The local address of the socket is already in use, and the socket was not marked to allow address reuse with SO_REUSEADDR. This error + /// usually occurs during a bind operation, but the error could be delayed until a ConnectEx function call, if the bind function + /// was called with a wildcard address ( INADDR_ANY or in6addr_any) specified for the local IP address. A specific IP + /// address needs to be implicitly bound by the ConnectEx function. + /// + /// + /// + /// WSAEALREADY + /// A nonblocking connect, WSAConnect, or ConnectEx function call is in progress on the specified socket. + /// + /// + /// WSAEADDRNOTAVAIL + /// + /// The remote address is not a valid address, such as ADDR_ANY (the ConnectEx function is only supported for connection-oriented sockets). + /// + /// + /// + /// WSAEAFNOSUPPORT + /// Addresses in the specified family cannot be used with this socket. + /// + /// + /// WSAECONNREFUSED + /// The attempt to connect was rejected. + /// + /// + /// WSAEFAULT + /// + /// The name, lpSendBuffer, or lpOverlapped parameter is not a valid part of the user address space, or + /// namelen is too small. + /// + /// + /// + /// WSAEINVAL + /// The parameter s is an unbound or a listening socket. + /// + /// + /// WSAEISCONN + /// The socket is already connected. + /// + /// + /// WSAENETUNREACH + /// The network cannot be reached from this host at this time. + /// + /// + /// WSAEHOSTUNREACH + /// A socket operation was attempted to an unreachable host. + /// + /// + /// WSAENOBUFS + /// No buffer space is available; the socket cannot be connected. + /// + /// + /// WSAENOTSOCK + /// The descriptor is not a socket. + /// + /// + /// WSAETIMEDOUT + /// The attempt to connect timed out without establishing a connection. + /// + /// + /// + /// + /// + /// The ConnectEx function combines several socket functions into a single API/kernel transition. The following operations are + /// performed when a call to the ConnectEx function completes successfully: + /// + /// + /// + /// A new connection is established. + /// + /// + /// An optional block of data is sent after the connection is established. + /// + /// + /// + /// For applications targeted to Windows Vista and later, consider using the WSAConnectByList or WSAConnectByName function which greatly + /// simplify client application design. + /// + /// + /// The ConnectEx function can only be used with connection-oriented sockets. The socket passed in the s parameter must be + /// created with a socket type of SOCK_STREAM, SOCK_RDM, or SOCK_SEQPACKET. + /// + /// + /// The lpSendBuffer parameter points to a buffer of data to send after the connection is established. The dwSendDataLength + /// parameter specifies the length in bytes of this data to send. An application can request to send a large buffer of data using the + /// ConnectEx in the same way that the send and WSASend functions can be used. But developers are strongly advised against sending + /// a huge buffer in a single call using ConnectEx, because this operation uses a large amount of system memory resources until + /// the whole buffer has been sent. + /// + /// + /// If the ConnectEx function is successful, a connection was established and all of the data pointed to by the + /// lpSendBuffer parameter was sent to the address specified in the sockaddr structure pointed to by the name parameter. + /// + /// + /// Note The function pointer for the ConnectEx function must be obtained at run time by making a call to the WSAIoctl + /// function with the SIO_GET_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the WSAIoctl function + /// must contain WSAID_CONNECTEX, a globally unique identifier (GUID) whose value identifies the ConnectEx extension + /// function. On success, the output returned by the WSAIoctl function contains a pointer to the ConnectEx function. The + /// WSAID_CONNECTEX GUID is defined in the Mswsock.h header file. + /// + /// + /// The ConnectEx function uses overlapped I/O. As a result, the ConnectEx function enables an application to service a + /// large number of clients with relatively few threads. In contrast, the WSAConnect function, which does not use overlapped I/O, usually + /// requires a separate thread to service each connection request when simultaneous requests are received. + /// + /// + /// Connection-oriented sockets are often unable to complete their connection immediately, and therefore the operation is initiated and + /// the function immediately returns with the ERROR_IO_PENDING or WSA_IO_PENDING error. When the connect operation completes and success + /// or failure is achieved, status is reported using the completion notification mechanism indicated in lpOverlapped. As with all + /// overlapped function calls, you can use events or completion ports as the completion notification mechanism. The + /// lpNumberOfBytesTransferred parameter of the GetQueuedCompletionStatus or GetOverlappedResult or WSAGetOverlappedResult + /// function indicates the number of bytes sent in the request. + /// + /// When the ConnectEx function successfully completes, socket handle s can be passed to only the following functions: + /// + /// + /// ReadFile + /// + /// + /// WriteFile + /// + /// + /// send or WSASend + /// + /// + /// recv or WSARecv + /// + /// + /// TransmitFile + /// + /// + /// closesocket + /// + /// + /// + /// If the TransmitFile function is called on a previously connected socket with both TF_DISCONNECT and TF_REUSE_SOCKET flags, the + /// specified socket is returned to a state in which it is not connected, but still bound. In such cases, the handle of the socket can be + /// passed to the ConnectEx function in its s parameter, but the socket cannot be reused in an AcceptEx function call. + /// Similarly, the accepted socket reused using the TransmitFile function cannot be used in a call to ConnectEx. Note that + /// in the case of a reused socket, ConnectEx is subject to the behavior of the underlying transport. For example, a TCP socket + /// may be subject to the TCP TIME_WAIT state, causing the ConnectEx call to be delayed. + /// + /// + /// When the ConnectEx function returns TRUE, the socket s is in the default state for a connected socket. The + /// socket s does not enable previously set properties or options until SO_UPDATE_CONNECT_CONTEXT is set on the socket. Use the + /// setsockopt function to set the SO_UPDATE_CONNECT_CONTEXT option. + /// + /// For example: + /// + /// The getsockopt function can be used with the SO_CONNECT_TIME socket option to check whether a connection has been established + /// while ConnectEx is in progress. If a connection has been established, the value returned in the optval parameter passed + /// to the getsockopt function is the number of seconds the socket has been connected. If the socket is not connected, the + /// returned optval parameter contains 0xFFFFFFFF. Checking a connection in this manner is necessary to determine whether + /// connections have been established for a period of time without sending any data; in such cases, it is recommended that such + /// connections be terminated. + /// + /// For example: + /// + /// Note If a socket is opened, a setsockopt call is made, and then a sendto call is made, Windows Sockets performs an implicit + /// bind function call. + /// + /// + /// If the address parameter of the sockaddr structure pointed to in the name parameter is all zeros, ConnectEx returns the + /// error WSAEADDRNOTAVAIL. Any attempt to reconnect an active connection will fail with the error code WSAEISCONN. + /// + /// + /// When a connected socket becomes closed for any reason, it is recommended that the socket be discarded and a new socket created. The + /// reasoning for this is that it is safest to assume that when things go awry on a connected socket for any reason, the application must + /// discard the socket and create the needed socket again in order to return to a stable point. + /// + /// + /// If the DisconnectEx function is called with the TF_REUSE_SOCKET flag, the specified socket is returned to a state in which it + /// is not connected, but still bound. In such cases, the handle of the socket can be passed to the ConnectEx function in its + /// s parameter. + /// + /// + /// The interval of time that must elapse before TCP can release a closed connection and reuse its resources is known as the TIME_WAIT + /// state or the 2MSL state. During this time, the connection can be reopened at much less cost to the client and server than + /// establishing a new connection. + /// + /// + /// The TIME_WAIT behavior is specified in RFC 793, which requires that TCP maintains a closed connection for an interval at least equal + /// to twice the maximum segment lifetime (MSL) of the network. When a connection is released, its socket pair and internal resources + /// used for the socket can be used to support another connection. + /// + /// + /// Windows TCP reverts to a TIME_WAIT state subsequent to the closing of a connection. While in the TIME_WAIT state, a socket pair + /// cannot be reused. The TIME_WAIT period is configurable by modifying the following DWORD registry setting that represents the + /// TIME_WAIT period in seconds. + /// + /// HKEY_LOCAL_MACHINE\ System\ CurrentControlSet\ Services\ TCPIP\ Parameters\ TcpTimedWaitDelay + /// + /// By default, the MSL is defined to be 120 seconds. The TcpTimedWaitDelay registry setting defaults to a value 240 seconds, which + /// represents 2 times the maximum segment lifetime of 120 seconds or 4 minutes. However, you can use this entry to customize the interval. + /// + /// + /// Reducing the value of this entry allows TCP to release closed connections faster, providing more resources for new connections. + /// However, if the value is too low, TCP might release connection resources before the connection is complete, requiring the server to + /// use additional resources to re-establish the connection. + /// + /// This registry setting can be set from 0 to 300 seconds. + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_connectex LPFN_CONNECTEX LpfnConnectex; BOOL + // LpfnConnectex( [in] SOCKET s, [in] const sockaddr *name, [in] int namelen, [in, optional] PVOID lpSendBuffer, [in] DWORD + // dwSendDataLength, [out] LPDWORD lpdwBytesSent, [in] LPOVERLAPPED lpOverlapped ) {...} + [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_CONNECTEX")] + [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = false)] + [return: MarshalAs(UnmanagedType.Bool)] + public delegate bool LPFN_CONNECTEX([In] SOCKET s, [In] SOCKADDR name, int namelen, [In, Optional] IntPtr lpSendBuffer, + uint dwSendDataLength, out uint lpdwBytesSent, in NativeOverlapped lpOverlapped); + + /// + /// The DisconnectEx function closes a connection on a socket, and allows the socket handle to be reused. + /// + /// Note + /// This function is a Microsoft-specific extension to the Windows Sockets specification. + /// + /// + /// A handle to a connected, connection-oriented socket. + /// + /// A pointer to an OVERLAPPED structure. If the socket handle has been opened as overlapped, specifying this parameter results in + /// an overlapped (asynchronous) I/O operation. + /// + /// + /// + /// A set of flags that customizes processing of the function call. When this parameter is set to zero, no flags are set. The dwFlags + /// parameter can have the following value. + /// + /// + /// + /// Flag + /// Meaning + /// + /// + /// TF_REUSE_SOCKET + /// + /// Prepares the socket handle to be reused. When the DisconnectEx request completes, the socket handle can be passed to the [ + /// AcceptEx](./nf-mswsock-acceptex.md) or [ ConnectEx](./nc-mswsock-lpfn_connectex.md) function. + /// + /// + /// + /// + /// Reserved. Must be zero. If nonzero, WSAEINVAL is returned. + /// + /// + /// On success, the DisconnectEx function returns TRUE. On failure, the function returns FALSE. Use the + /// WSAGetLastError function to get extended error information. If a call to the WSAGetLastError function returns + /// ERROR_IO_PENDING, the operation initiated successfully and is in progress. Under such circumstances, the call may still fail + /// when the operation completes. + /// + /// + /// + /// Error code + /// Description + /// + /// + /// WSAEFAULT + /// + /// The system detected an invalid pointer address in attempting to use a pointer argument. This error is returned if an invalid pointer + /// value was passed in the lpOverlapped parameter. + /// + /// + /// + /// WSAEINVAL + /// + /// The invalid parameter was passed. This error is returned if the dwFlags parameter was specified with a zero value other than TF_REUSE_SOCKET. + /// + /// + /// + /// WSAENOTCONN + /// + /// The socket is not connected. This error is returned if the socket s parameter was not in a connected state. This error can + /// also be returned if the socket was in the transmit closing state from a previous request and the dwFlags parameter was not set + /// to TF_REUSE_SOCKET to request a reuse of the socket. + /// + /// + /// + /// + /// + /// + /// The DisconnectEx function does not support datagram sockets. Therefore, the socket specified by hSocket must be + /// connection-oriented, such as a SOCK_STREAM, SOCK_SEQPACKET, or SOCK_RDM socket. + /// + /// + /// Note + /// + /// The function pointer for the DisconnectEx function must be obtained at run time by making a call to the WSAIoctl + /// function with the SIO_GET_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the WSAIoctl function + /// must contain WSAID_DISCONNECTEX, a globally unique identifier (GUID) whose value identifies the DisconnectEx extension + /// function. On success, the output returned by the WSAIoctl function contains a pointer to the DisconnectEx function. The + /// WSAID_DISCONNECTEX GUID is defined in the Mswsock.h header file. + /// + /// + /// + /// When lpOverlapped is not NULL, overlapped I/O might not finish before DisconnectEx returns, resulting in the + /// DisconnectEx function returning FALSE and a call to the WSAGetLastError function returning + /// ERROR_IO_PENDING. This design enables the caller to continue processing while the disconnect operation completes. Upon + /// completion of the request, Windows sets either the event specified by the hEvent member of the OVERLAPPED structure, or + /// the socket specified by hSocket, to the signaled state. + /// + /// + /// Note + /// + /// All I/O initiated by a given thread is canceled when that thread exits. For overlapped sockets, pending asynchronous operations can + /// fail if the thread is closed before the operations complete. See ExitThread for more information. + /// + /// + /// + /// The TIME_WAIT state determines the time that must elapse before TCP can release a closed connection and reuse its resources. This + /// interval between closure and release is known as the TIME_WAIT state or 2MSL state. During this time, the connection can be reopened + /// at much less cost to the client and server than establishing a new connection. The TIME_WAIT behavior is specified in RFC 793 which + /// requires that TCP maintains a closed connection for an interval at least equal to twice the maximum segment lifetime (MSL) of the + /// network. When a connection is released, its socket pair and internal resources used for the socket can be used to support another connection. + /// + /// + /// Windows TCP reverts to a TIME_WAIT state subsequent to the closing of a connection. While in the TIME_WAIT state, a socket pair + /// cannot be re-used. The TIME_WAIT period is configurable by modifying the following DWORD registry setting that represents the + /// TIME_WAIT period in seconds. + /// + /// HKEY_LOCAL_MACHINE\ System\ CurrentControlSet\ Services\ TCPIP\ Parameters\ TcpTimedWaitDelay + /// + /// By default, the MSL is defined to be 120 seconds. The TcpTimedWaitDelay registry setting defaults to a value 240 seconds, which + /// represents 2 times the maximum segment lifetime of 120 seconds or 4 minutes. However, you can use this entry to customize the + /// interval. Reducing the value of this entry allows TCP to release closed connections faster, providing more resources for new + /// connections. However, if the value is too low, TCP might release connection resources before the connection is complete, requiring + /// the server to use additional resources to re-establish the connection. This registry setting can be set from 0 to 300 seconds. + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_disconnectex LPFN_DISCONNECTEX LpfnDisconnectex; BOOL + // LpfnDisconnectex( SOCKET s, LPOVERLAPPED lpOverlapped, DWORD dwFlags, DWORD dwReserved ) {...} + [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_DISCONNECTEX")] + [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = false)] + [return: MarshalAs(UnmanagedType.Bool)] + public delegate bool LPFN_DISCONNECTEX(SOCKET s, in NativeOverlapped lpOverlapped, TF dwFlags, uint dwReserved = 0); + + /// + /// The RIOCloseCompletionQueue function closes an existing completion queue used for I/O completion notification by send and + /// receive requests with the Winsock registered I/O extensions. + /// + /// A descriptor identifying an existing completion queue. + /// None + /// + /// + /// The RIOCloseCompletionQueue function closes an existing completion queue used for I/O completion. The RIO_CQ passed in + /// the CQ parameter is locked for writing by the kernel. The completion queue is marked as invalid, so that new completions cannot be + /// added. Any new completions to be added are silently dropped. The application is expected to tracking any pending send or receive operations. + /// + /// + /// If an invalid completion queue is passed in the CQ parameter ( RIO_INVALID_CQ, for example), this is ignored by the + /// RIOCloseCompletionQueue function. + /// + /// + /// Note + /// + /// The function pointer to the RIOCloseCompletionQueue function must be obtained at run time by making a call to the + /// WSAIoctl function with the SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the + /// WSAIoctl function must contain WSAID_MULTIPLE_RIO, a globally unique identifier (GUID) whose value identifies the + /// Winsock registered I/O extension functions. On success, the output returned by the WSAIoctl function contains a pointer to the + /// RIO_EXTENSION_FUNCTION_TABLE structure that contains pointers to the Winsock registered I/O extension functions. The + /// SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER IOCTL is defined in the Ws2def.h header file. The WSAID_MULTIPLE_RIO GUID + /// is defined in the Mswsock.h header file. + /// + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_rioclosecompletionqueue LPFN_RIOCLOSECOMPLETIONQUEUE + // LpfnRioclosecompletionqueue; void LpfnRioclosecompletionqueue( RIO_CQ CQ ) {...} + [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_RIOCLOSECOMPLETIONQUEUE")] + [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = false)] + public delegate void LPFN_RIOCLOSECOMPLETIONQUEUE(RIO_CQ CQ); + + /// + /// The RIOCreateCompletionQueue function creates an I/O completion queue of a specific size for use with the Winsock registered + /// I/O extensions. + /// + /// The size, in number of entries, of the completion queue to create. + /// + /// + /// The type of notification completion to use based on the Type member of the RIO_NOTIFICATION_COMPLETION structure (I/O + /// completion or event notification). + /// + /// + /// If the Type member is set to RIO_EVENT_COMPLETION, then the Event member of the + /// RIO_NOTIFICATION_COMPLETION structure must be set. + /// + /// + /// If the Type member is set to RIO_IOCP_COMPLETION, then the Iocp member of the RIO_NOTIFICATION_COMPLETION + /// structure must be set and the Iocp.Overlapped member of the RIO_NOTIFICATION_COMPLETION structure must not be NULL. + /// + /// + /// If the NotificationCompletion parameter is NULL, this specifies no notification completion is used and that polling must be used to + /// determine completion. + /// + /// + /// + /// + /// If no error occurs, the RIOCreateCompletionQueue function returns a descriptor referencing a new completion queue. Otherwise, + /// a value of RIO_INVALID_CQ is returned, and a specific error code can be retrieved by calling the WSAGetLastError function. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// WSAEFAULT + /// The system detected an invalid pointer address in attempting to use a pointer argument in a call. + /// + /// + /// WSAEINVAL + /// + /// An invalid parameter was passed to the function. This error is returned if the QueueSize parameter is less than 1 or greater + /// than RIO_MAX_CQ_SIZE defined in the Mswsockdef.h header file. + /// + /// + /// + /// WSAENOBUFS + /// + /// Sufficient memory could not be allocated. This error is returned if there was insufficient memory to allocate the completion queue + /// requested based on the QueueSize parameter. + /// + /// + /// + /// + /// + /// + /// The RIOCreateCompletionQueue function creates an I/O completion queue of a specific size. The size of the completion queue + /// restricts the set of registered I/O sockets that can be associated with the completion queue. For more information, see the + /// RIOCreateRequestQueue function. + /// + /// + /// When creating a RIO_CQ, the RIO_NOTIFICATION_COMPLETION structure pointed to by the NotificationCompletion parameter + /// determines how the application will receive completion queue notifications. If a RIO_NOTIFICATION_COMPLETION structure is + /// provided when creating the completion queue, the application may call the RIONotify function to request a completion queue + /// notification. Normally this notification occurs when the completion queue is not empty. This may happen immediately or when the next + /// completion entry is inserted into the completion queue. However, send and receive requests may be flagged as + /// RIO_MSG_DONT_NOTIFY. Completion queue notification and will never be triggered as a result of such requests. If the completion + /// queue contains only entries with the RIO_MSG_DONT_NOTIFY flag set, the completion queue notification will not be triggered. + /// Also, when a new entry enters the completion queue, the completion queue notification is only triggered if the + /// RIO_MSG_DONT_NOTIFY flag was not set on the associated request. Any completed requests can still be retrieved by polling using + /// the RIODequeueCompletion function. Once a completion queue notification is issued, the application must call the + /// RIONotify function in order to receive another completion queue notification. When a completion queue notification occurs, the + /// application typically calls the RIODequeueCompletion function to dequeue the completed send or receive requests. + /// + /// Two options are available for completion queue notification. + /// + /// + /// Event handles. + /// + /// + /// I/O completion ports + /// + /// + /// + /// If the Type member of the RIO_NOTIFICATION_COMPLETION structure is set to RIO_EVENT_COMPLETION, an event handle + /// is used to signal completion queue notifications. An event handle is provided as the EventNotify.EventHandle member in the + /// RIO_NOTIFICATION_COMPLETION structure passed to the RIOCreateCompletionQueue function. The Event.EventHandle + /// member should contain the handle for an event created by the WSACreateEvent or CreateEvent function. To receive the + /// RIONotify completion, the application should wait on the specified event handle using WSAWaitForMultipleEvents or a + /// similar wait routine. The completion of the RIONotify function for this RIO_CQ will signal the event. The + /// Event.NotifyReset member in the RIO_NOTIFICATION_COMPLETION structure passed to the RIOCreateCompletionQueue + /// function indicates whether or not the event should be reset as part of a call to the RIONotify function. If the application + /// plans to reset and reuse the event, the application can reduce overhead by setting the Event.NotifyReset member to a non-zero + /// value. This causes the event to be automatically reset by the RIONotify function when the notification occurs. This mitigates + /// the need to call the WSAResetEvent function to reset the event between calls to the RIONotify function. + /// + /// + /// If the Type member of the RIO_NOTIFICATION_COMPLETION structure is set to RIO_IOCP_COMPLETION, an I/O completion + /// port is used to signal completion queue notifications. An I/O completion port handle is provided as the Iocp.IocpHandle member + /// in the RIO_NOTIFICATION_COMPLETION structure passed to the RIOCreateCompletionQueue function. The completion of the + /// RIONotify function for this RIO_CQ will queue an entry to the I/O completion port which can be retrieved using the + /// GetQueuedCompletionStatus or GetQueuedCompletionStatusEx function. A queued entry will have the returned + /// lpCompletionKey parameter value set to the value specified in Iocp.CompletionKey member of the + /// RIO_NOTIFICATION_COMPLETION structure and the Iocp.Overlapped member in the RIO_NOTIFICATION_COMPLETION + /// structure will be a non-NULL value. + /// + /// + /// In terms of its usage, completion queue notification is designed to wake up a waiting application thread so that the thread can + /// examine the completion queue. Waking and scheduling a thread comes at a cost, so if this happens too frequently it will have a + /// negative impact on the application performance. The RIO_MSG_DONT_NOTIFY flag is provided so that the application can control + /// the frequency of these events and limit their over impact on performance. + /// + /// + /// Note + /// + /// For purposes of efficiency, access to the completion queues ( RIO_CQ structs) and request queues ( RIO_RQ structs) are + /// not protected by synchronization primitives. If you need to access a completion or request queue from multiple threads, access should + /// be coordinated by a critical section, slim reader write lock or similar mechanism. This locking is not needed for access by a single + /// thread. Different threads can access separate requests/completion queues without locks. The need for synchronization occurs only when + /// multiple threads try to access the same queue. Synchronization is also required if multiple threads issue sends and receives on the + /// same socket because the send and receive operations use the socket’s request queue. + /// + /// + /// + /// Note + /// + /// The function pointer to the RIOCreateCompletionQueue function must be obtained at run time by making a call to the + /// WSAIoctl function with the SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the + /// WSAIoctl function must contain WSAID_MULTIPLE_RIO, a globally unique identifier (GUID) whose value identifies the + /// Winsock registered I/O extension functions. On success, the output returned by the WSAIoctl function contains a pointer to the + /// RIO_EXTENSION_FUNCTION_TABLE structure that contains pointers to the Winsock registered I/O extension functions. The + /// SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER IOCTL is defined in the Ws2def.h header file. The WSAID_MULTIPLE_RIO GUID + /// is defined in the Mswsock.h header file. + /// + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_riocreatecompletionqueue LPFN_RIOCREATECOMPLETIONQUEUE + // LpfnRiocreatecompletionqueue; RIO_CQ LpfnRiocreatecompletionqueue( DWORD QueueSize, PRIO_NOTIFICATION_COMPLETION + // NotificationCompletion ) {...} + [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_RIOCREATECOMPLETIONQUEUE")] + [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = false)] + public delegate RIO_CQ LPFN_RIOCREATECOMPLETIONQUEUE(uint QueueSize, IntPtr NotificationCompletion); + + /// + /// The RIOCreateRequestQueue function creates a registered I/O socket descriptor using a specified socket and I/O completion + /// queues for use with the Winsock registered I/O extensions. + /// + /// A descriptor that identifies the socket. + /// + /// The maximum number of outstanding receives allowed on the socket. + /// This parameter is usually a small number for most applications. + /// + /// + /// The maximum number of receive data buffers on the socket. + /// + /// Note + /// For Windows 8 and Windows Server 2012 , this parameter must be 1. + /// + /// + /// The maximum number of outstanding sends allowed on the socket. + /// + /// The maximum number of send data buffers on the socket. + /// + /// Note + /// For Windows 8 and Windows Server 2012 , this parameter must be 1. + /// + /// + /// A descriptor that identifies the I/O completion queue to use for receive request completions. + /// + /// A descriptor that identifies the I/O completion queue to use for send request completions. + /// This parameter may have the same value as the ReceiveCQ parameter. + /// + /// The socket context to associate with this request queue. + /// + /// + /// If no error occurs, the RIOCreateRequestQueue function returns a descriptor referencing a new request queue. Otherwise, a + /// value of RIO_INVALID_RQ is returned, and a specific error code can be retrieved by calling the WSAGetLastError function. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// WSAEINVAL + /// + /// An invalid parameter was passed to the function. This error is returned if the ReceiveCQ or SendCQ parameters contained + /// RIO_INVALID_CQ. This error is returned if both the MaxOutstandingReceive and MaxOutstandingSend parameters are + /// zero. This error is also returned if the socket passed in the Socket parameter is in the process of initializing or closing. + /// + /// + /// + /// WSAENOBUFS + /// + /// Sufficient memory could not be allocated. This error is returned if there was insufficient memory to allocate the request queue based + /// on the parameters. This error is also returned if the network session limit was exceeded. + /// + /// + /// + /// WSAENOTSOCK + /// The descriptor is not a socket. This error is returned if the Socket parameter is not a valid socket. + /// + /// + /// WSAEOPNOTSUPP + /// + /// The attempted operation is not supported for the type of object referenced. This error is returned for a socket in the Socket + /// parameter for an unsupported socket type ( SOCK_RAW, for example) + /// + /// + /// + /// + /// + /// + /// The RIOCreateRequestQueue function creates a registered I/O socket descriptor using a specified socket and I/O completion + /// queues. An application must call RIOCreateRequestQueue to obtain a RIO_RQ for a Winsock socket before the application + /// can use the RIOSend, RIOSendEx, RIOReceive, or RIOReceiveEx functions. In order to obtain a + /// RIO_RQ, the Winsock socket must be associated with completion queues for send and receive, although the same completion queue + /// can be used for both. + /// + /// + /// Due to the finite size of completion queues, a socket may only be associated with a completion queue for send and receive operations + /// if it guarantees not to exceed the capacity for total queued completions. Therefore, socket specific limits are established by the + /// call to the RIOCreateRequestQueue function. These limits are used both during the RIOCreateRequestQueue call to verify + /// sufficient space in the completion queues to accommodate the socket requests and during request initiation time to make sure that the + /// request does not cause the socket to exceed its limits. + /// + /// + /// The send and receive queues can be associated with multiple sockets. The sizes of the send and receive queues must be greater than or + /// equal to the send and receive sizes of all attached sockets. As request queues are closed by closing the sockets using the the + /// closesocket function, those slots will be freed up for use by other sockets. + /// + /// + /// Note + /// + /// For purposes of efficiency, access to the completion queues ( RIO_CQ structs) and request queues ( RIO_RQ structs) are + /// not protected by synchronization primitives. If you need to access a completion or request queue from multiple threads, access should + /// be coordinated by a critical section, slim reader write lock or similar mechanism. This locking is not needed for access by a single + /// thread. Different threads can access separate requests/completion queues without locks. The need for synchronization occurs only when + /// multiple threads try to access the same queue. Synchronization is also required if multiple threads issue sends and receives on the + /// same socket because the send and receive operations use the socket’s request queue. + /// + /// + /// + /// When an application is finished using the RIO_RQ, the application should call the closesocket function to close the + /// socket and free the associated resources. + /// + /// + /// Note + /// + /// The function pointer to the RIOCreateRequestQueue function must be obtained at run time by making a call to the + /// WSAIoctl function with the SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the + /// WSAIoctl function must contain WSAID_MULTIPLE_RIO, a globally unique identifier (GUID) whose value identifies the + /// Winsock registered I/O extension functions. On success, the output returned by the WSAIoctl function contains a pointer to the + /// RIO_EXTENSION_FUNCTION_TABLE structure that contains pointers to the Winsock registered I/O extension functions. The + /// SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER IOCTL is defined in the Ws2def.h header file. The WSAID_MULTIPLE_RIO GUID + /// is defined in the Mswsock.h header file. + /// + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_riocreaterequestqueue LPFN_RIOCREATEREQUESTQUEUE + // LpfnRiocreaterequestqueue; RIO_RQ LpfnRiocreaterequestqueue( SOCKET Socket, ULONG MaxOutstandingReceive, ULONG MaxReceiveDataBuffers, + // ULONG MaxOutstandingSend, ULONG MaxSendDataBuffers, RIO_CQ ReceiveCQ, RIO_CQ SendCQ, PVOID SocketContext ) {...} + [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_RIOCREATEREQUESTQUEUE")] + [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = false)] + public delegate RIO_RQ LPFN_RIOCREATEREQUESTQUEUE(SOCKET Socket, uint MaxOutstandingReceive, uint MaxReceiveDataBuffers, + uint MaxOutstandingSend, uint MaxSendDataBuffers, RIO_CQ ReceiveCQ, RIO_CQ SendCQ, IntPtr SocketContext); + + /// + /// The RIODequeueCompletion function removes entries from an I/O completion queue for use with the Winsock registered I/O extensions. + /// + /// A descriptor that identifies an I/O completion queue. + /// An array of RIORESULT structures to receive the description of the completions dequeued. + /// The maximum number of entries in the Array to write. + /// + /// If no error occurs, the RIODequeueCompletion function returns the number of completion entries removed from the specified + /// completion queue. Otherwise, a value of RIO_CORRUPT_CQ is returned to indicate that the state of the RIO_CQ passed in + /// the CQ parameter has become corrupt due to memory corruption or misuse of the RIO functions. + /// + /// + /// + /// The RIODequeueCompletion function removes entries from an I/O completion queue for send and receive requests with the Winsock + /// registered I/O extensions. + /// + /// + /// The RIODequeueCompletion function is the mechanism by which an application can find out about completed send and receive + /// requests. An application normally calls the RIODequeueCompletion function after receiving notification based on the method + /// registered with the RIONotify function when the completion queue is not empty. The notification behavior for an I/O completion + /// queue is set when the RIO_CQ is created. The RIO_NOTIFICATION_COMPLETION structure that determines the notification + /// behavior is passed to the RIOCreateCompletionQueue function when a RIO_CQ is created. + /// + /// + /// When the RIODequeueCompletion function completes, the Array parameter contains an array of pointers to RIORESULT + /// structures for the completed send and receive requests that were dequeued. The members of the returned RIORESULT structures + /// provide information on the completion status of the completed request and the number of bytes that were transferred. Each returned + /// RIORESULT structure also includes a socket context and an application context that can be used to identify the specific + /// completed request. + /// + /// + /// If the I/O completion queue passed in the CQ parameter is not valid or damaged, the RIODequeueCompletion function returns a + /// count of RIO_CORRUPT_CQ. + /// + /// + /// The RIODequeueCompletion function returns a value of zero is returned if there are no completed send or receive requests to be dequeued. + /// + /// + /// Only after a request’s completion has been dequeued does the system release the association to its buffer and buffer registration, + /// along with its quota charge. + /// + /// + /// Note + /// + /// For purposes of efficiency, access to the completion queues ( RIO_CQ structs) and request queues ( RIO_RQ structs) are + /// not protected by synchronization primitives. If you need to access a completion or request queue from multiple threads, access should + /// be coordinated by a critical section, slim reader write lock or similar mechanism. This locking is not needed for access by a single + /// thread. Different threads can access separate requests/completion queues without locks. The need for synchronization occurs only when + /// multiple threads try to access the same queue. Synchronization is also required if multiple threads issue sends and receives on the + /// same socket because the send and receive operations use the socket’s request queue. + /// + /// + /// + /// Note + /// + /// The function pointer to the RIODequeueCompletion function must be obtained at run time by making a call to the WSAIoctl + /// function with the SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the WSAIoctl + /// function must contain WSAID_MULTIPLE_RIO, a globally unique identifier (GUID) whose value identifies the Winsock registered + /// I/O extension functions. On success, the output returned by the WSAIoctl function contains a pointer to the + /// RIO_EXTENSION_FUNCTION_TABLE structure that contains pointers to the Winsock registered I/O extension functions. The + /// SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER IOCTL is defined in the Ws2def.h header file. The WSAID_MULTIPLE_RIO GUID + /// is defined in the Mswsock.h header file. + /// + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_riodequeuecompletion LPFN_RIODEQUEUECOMPLETION + // LpfnRiodequeuecompletion; ULONG LpfnRiodequeuecompletion( RIO_CQ CQ, PRIORESULT Array, ULONG ArraySize ) {...} + [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_RIODEQUEUECOMPLETION")] + [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = false)] + public delegate uint LPFN_RIODEQUEUECOMPLETION(RIO_CQ CQ, [MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] RIORESULT[] Array, uint ArraySize); + + /// The RIODeregisterBuffer function deregisters a registered buffer used with the Winsock registered I/O extensions. + /// A descriptor identifying a registered buffer. + /// None + /// + /// + /// The RIODeregisterBuffer function deregisters a registered buffer. When a buffer is deregistered, the application is indicating + /// that it is done with the buffer identifier passed in the BufferId parameter. Any subsequent calls to other functions that try to use + /// this buffer identifier will fail. + /// + /// + /// If a buffer that is still in use is deregistered, the results are undefined. This is considered a serious error. In the + /// RIORESULT structure returned by the RIODequeueCompletion function, the status will be unchanged from the normal status. + /// An application developer can detect this error condition using the Application Verifier tool. + /// + /// If an invalid buffer identifier is passed in the BufferId parameter, this is ignored by the RIODeregisterBuffer function. + /// + /// Note + /// + /// The function pointer to the RIODeregisterBuffer function must be obtained at run time by making a call to the WSAIoctl + /// function with the SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the WSAIoctl + /// function must contain WSAID_MULTIPLE_RIO, a globally unique identifier (GUID) whose value identifies the Winsock registered + /// I/O extension functions. On success, the output returned by the WSAIoctl function contains a pointer to the + /// RIO_EXTENSION_FUNCTION_TABLE structure that contains pointers to the Winsock registered I/O extension functions. The + /// SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER IOCTL is defined in the Ws2def.h header file. The WSAID_MULTIPLE_RIO GUID + /// is defined in the Mswsock.h header file. + /// + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_rioderegisterbuffer LPFN_RIODEREGISTERBUFFER + // LpfnRioderegisterbuffer; void LpfnRioderegisterbuffer( RIO_BUFFERID BufferId ) {...} + [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_RIODEREGISTERBUFFER")] + [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = false)] + public delegate void LPFN_RIODEREGISTERBUFFER(RIO_BUFFERID BufferId); + + /// + /// The RIONotify function registers the method to use for notification behavior with an I/O completion queue for use with the + /// Winsock registered I/O extensions. + /// + /// A descriptor that identifies an I/O completion queue. + /// + /// + /// If no error occurs, the RIONotify function returns ERROR_SUCCESS. Otherwise, the function failed and a specific error + /// code is returned. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// WSAEINVAL + /// + /// An invalid parameter was passed to the function. This error is returned if invalid completion queue is passed in the CQ + /// parameter ( RIO_INVALID_CQ, for example). This error can also be returned when an internal error occurs. + /// + /// + /// + /// WSAEALREADY + /// + /// An operation was attempted on a non-blocking socket that already had an operation in progress. This error is returned if a previous + /// RIONotify request has not yet completed. + /// + /// + /// + /// + /// + /// + /// The RIONotify function registers the method to be used for notification behavior for sending or receiving network data with + /// the Winsock registered I/O extensions. + /// + /// + /// The RIONotify function is the mechanism by which an application finds out that requests are completed and are awaiting a call + /// to the RIODequeueCompletion function. The RIONotify function sets the method to be used for notification behavior when + /// an I/O completion queue is not empty and contains the completion of a result. + /// + /// + /// The notification behavior for a completion queue is set when the RIO_CQ is created. The RIO_NOTIFICATION_COMPLETION + /// structure is passed to the RIOCreateCompletionQueue function when a RIO_CQ is created. + /// + /// + /// For a completion queue that uses an event, the Type member of the RIO_NOTIFICATION_COMPLETION structure is set to + /// RIO_EVENT_COMPLETION. The Event.EventHandle member should contain the handle for an event created by the + /// WSACreateEvent or CreateEvent function. To receive the RIONotify completion, the application should wait on the + /// specified event handle using WSAWaitForMultipleEvents or a similar wait routine. If the application plans to reset and reuse + /// the event, the application can reduce overhead by setting the Event.NotifyReset member to a non-zero value. This causes the + /// event to be automatically reset by the RIONotify function when the notification occurs. This mitigates the need to call the + /// WSAResetEvent function to reset the event between calls to the RIONotify function. + /// + /// + /// When the RIONotify function is called used event completion and the specified completion queue is already not empty, the event + /// is set either synchronously or asynchronously. In both cases, additional entries do not need to enter the completion queue before the + /// event is set. Until the completion queue contains the completion of a request that did not have the RIO_MSG_DONT_NOTIFY flag + /// set, the completion queue is considered empty for the purposes of the RIONotify function and the event is not set. Any + /// completed requests can still be retrieved using the RIODequeueCompletion function. When the event is set, the application + /// typically calls the RIODequeueCompletion function to dequeue the completed send and receive requests. + /// + /// + /// For a completion queue that uses an I/O completion port, the Type member of the RIO_NOTIFICATION_COMPLETION structure + /// is set to RIO_IOCP_COMPLETION. The Iocp.IocpHandle member should contain the handle for an I/O completion port created + /// by the CreateIoCompletionPort function. To receive the RIONotify completion, the application should call the + /// GetQueuedCompletionStatus or GetQueuedCompletionStatusEx function. The application should provide a dedicated + /// OVERLAPPED object for the completion queue, and it may also use the Iocp.CompletionKey member to distinguish + /// RIONotify requests on the completion queue from other I/O completions including RIONotify completions for other + /// completion queues. + /// + /// + /// An application using thread pools can use thread pool wait objects to get RIONotify completions via its thread pool. In that + /// case, the call to the SetThreadpoolWait function should immediately follow the call to RIONotify. If the + /// SetThreadpoolWait function is called before RIONotify and the application relies on RIONotify to clear the event + /// object, this may result in spurious executions of the wait object callback. + /// + /// + /// Note + /// + /// The function pointer to the RIONotify function must be obtained at run time by making a call to the WSAIoctl function + /// with the SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the WSAIoctl function + /// must contain WSAID_MULTIPLE_RIO, a globally unique identifier (GUID) whose value identifies the Winsock registered I/O + /// extension functions. On success, the output returned by the WSAIoctl function contains a pointer to the + /// RIO_EXTENSION_FUNCTION_TABLE structure that contains pointers to the Winsock registered I/O extension functions. The + /// SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER IOCTL is defined in the Ws2def.h header file. The WSAID_MULTIPLE_RIO GUID + /// is defined in the Mswsock.h header file. + /// + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_rionotify LPFN_RIONOTIFY LpfnRionotify; INT LpfnRionotify( + // RIO_CQ CQ ) {...} + [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_RIONOTIFY")] + [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = false)] + public delegate WSRESULT LPFN_RIONOTIFY(RIO_CQ CQ); + + /// + /// The RIOReceive function receives network data on a connected registered I/O TCP socket or a bound registered I/O UDP socket + /// for use with the Winsock registered I/O extensions. + /// + /// A descriptor that identifies a connected registered I/O TCP socket or a bound registered I/O UDP socket. + /// + /// A description of the portion of the registered buffer in which to receive data. + /// + /// This parameter may be NULL for a bound registered I/O UDP socket if the application does not need to receive the data payload in the + /// UDP datagram. + /// + /// + /// + /// A data buffer count parameter that indicates if data is to be received in the buffer pointed to by the pData parameter. + /// This parameter should be set to zero if the pData is NULL. Otherwise, this parameter should be set to 1. + /// + /// + /// A set of flags that modify the behavior of the RIOReceive function. + /// The Flags parameter can contain a combination of the following options defined in the Mswsockdef.h header file: + /// + /// + /// The request context to associate with this receive operation. + /// + /// + /// If no error occurs, the RIOReceive function returns TRUE. In this case, the receive operation is successfully initiated + /// and the completion will have already been queued or the operation has been successfully initiated and the completion will be queued + /// at a later time. + /// + /// + /// A value of FALSE indicates the function failed, the operation was not successfully initiated and no completion indication will + /// be queued. A specific error code can be retrieved by calling the WSAGetLastError function. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// WSAEFAULT + /// + /// The system detected an invalid pointer address in attempting to use a pointer argument in a call. This error is returned if a buffer + /// identifier is deregistered or a buffer is freed for any of the RIO_BUF structures passed in parameters before the operation is + /// queued or invoked. + /// + /// + /// + /// WSAEINVAL + /// + /// An invalid parameter was passed to the function. This error is returned if the SocketQueue parameter is not valid, the + /// Flags parameter contains a value not valid for a receive operation, or the integrity of the completion queue has been + /// compromised. This error can also be returned for other issues with parameters. + /// + /// + /// + /// WSAENOBUFS + /// + /// Sufficient memory could not be allocated. This error is returned if the I/O completion queue associated with the SocketQueue + /// parameter is full or the I/O completion queue was created with zero receive entries. + /// + /// + /// + /// WSA_OPERATION_ABORTED + /// + /// The operation has been canceled while the receive operation was pending. This error is returned if the socket is closed locally or + /// remotely, or the SIO_FLUSH command in WSAIoctl is executed on this socket. + /// + /// + /// + /// + /// + /// + /// An application can use the RIOReceive function to receive network data into any buffer completely contained within a single + /// registered buffer. The Offset and Length members of the RIO_BUF structure pointed to by the pData parameter + /// determine where the network data is received in the buffer. + /// + /// + /// Once the RIOReceive function is called, the buffer passed in the pData parameter including the RIO_BUFFERID in the + /// BufferId member of RIO_BUF structure must remain valid for the duration of the receive operation. + /// + /// + /// In order to avoid race conditions, a buffer associated with a receive request should not be read or written before the request + /// completes. This includes using the buffer as the source for a send request or the destination for another receive request. Portions + /// of a registered buffer not associated with any receive request are not included in this restriction. + /// + /// + /// The Flags parameter can be used to influence the behavior of the RIOReceive function invocation beyond the options specified + /// for the associated socket. The behavior of this function is determined by a combination of any socket options set on the socket + /// associated with the SocketQueue parameter and the values specified in the Flags parameter. + /// + /// + /// Note + /// + /// The function pointer to the RIOReceive function must be obtained at run time by making a call to the WSAIoctl function + /// with the SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the WSAIoctl function + /// must contain WSAID_MULTIPLE_RIO, a globally unique identifier (GUID) whose value identifies the Winsock registered I/O + /// extension functions. On success, the output returned by the WSAIoctl function contains a pointer to the + /// RIO_EXTENSION_FUNCTION_TABLE structure that contains pointers to the Winsock registered I/O extension functions. The + /// SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER IOCTL is defined in the Ws2def.h header file. The WSAID_MULTIPLE_RIO GUID + /// is defined in the Mswsock.h header file. + /// + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_rioreceive LPFN_RIORECEIVE LpfnRioreceive; BOOL + // LpfnRioreceive( RIO_RQ SocketQueue, PRIO_BUF pData, ULONG DataBufferCount, DWORD Flags, PVOID RequestContext ) {...} + [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_RIORECEIVE")] + [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = false)] + [return: MarshalAs(UnmanagedType.Bool)] + public delegate bool LPFN_RIORECEIVE(RIO_RQ SocketQueue, [In, Optional] IntPtr pData, uint DataBufferCount, RIO_MSG Flags, + IntPtr RequestContext); + + /// + /// The RIOReceiveEx function receives network data on a connected registered I/O TCP socket or a bound registered I/O UDP socket + /// with additional options for use with the Winsock registered I/O extensions. + /// + /// A descriptor that identifies a connected registered I/O UDP socket or a bound registered I/O UDP socket. + /// + /// A description of the portion of the registered buffer in which to receive data. + /// + /// This parameter may be NULL for a bound registered I/O UDP socket if the application does not need to receive a data payload in the + /// UDP datagram. + /// + /// + /// + /// A data buffer count parameter that indicates if data is to be received in the buffer pointed to by the pData parameter. + /// This parameter should be set to zero if the pData is NULL. Otherwise, this parameter should be set to 1. + /// + /// + /// A buffer segment that on completion will hold the local address on which the network data was received. + /// + /// This parameter may be NULL if the application does not want to receive the local address. If this parameter is not + /// NULL, then the buffer segment must be at least the size of a SOCKADDR_INET structure. + /// + /// + /// + /// A buffer segment that on completion will hold the remote address from which the network data was received. + /// + /// This parameter may be NULL if the application does not want to receive the remote address. If this parameter is not + /// NULL, then the buffer segment must be at least the size of a SOCKADDR_INET structure. + /// + /// + /// + /// A buffer slice that on completion will hold additional control information about the receive operation. + /// This parameter may be NULL if the application does not want to receive the additional control information. + /// + /// + /// + /// A set of flags that modify the behavior of the RIOReceiveEx function. + /// The Flags parameter can contain a combination of the following options defined in the Mswsockdef.h header file: + /// + /// + /// The request context to associate with this receive operation. + /// + /// + /// If no error occurs, the RIOReceiveEx function returns TRUE. In this case, the receive operation is successfully + /// initiated and the completion will have already been queued or the operation has been successfully initiated and the completion will + /// be queued at a later time. + /// + /// + /// A value of FALSE indicates the function failed, the operation was not successfully initiated and no completion indication will + /// be queued. A specific error code can be retrieved by calling the WSAGetLastError function. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// WSAEFAULT + /// + /// The system detected an invalid pointer address in attempting to use a pointer argument in a call. This error is returned if a buffer + /// identifier is deregistered or a buffer is freed for any of the RIO_BUF structures passed in parameters before the operation is + /// queued or invoked. + /// + /// + /// + /// WSAEINVAL + /// + /// An invalid parameter was passed to the function. This error is returned if the SocketQueue parameter is not valid, the + /// dwFlags parameter contains a value not valid for a receive operation, or the integrity of the completion queue has been + /// compromised. This error can also be returned for other issues with parameters. + /// + /// + /// + /// WSAENOBUFS + /// + /// Sufficient memory could not be allocated. This error is returned if the I/O completion queue associated with the SocketQueue + /// parameter is full or the I/O completion queue was created with zero receive entries. + /// + /// + /// + /// WSA_OPERATION_ABORTED + /// + /// The operation has been canceled while the receive operation was pending. This error is returned if the socket is closed locally or + /// remotely, or the the SIO_FLUSH command in WSAIoctl is executed. + /// + /// + /// + /// + /// + /// + /// An application can use the RIOReceiveEx function to receive network data into any buffer completely contained within a single + /// registered buffer. The Offset and Length members of the RIO_BUF structure pointed to by the pData parameter + /// determine where the network data is received in the buffer. + /// + /// + /// Once the RIOReceiveEx function is called, the buffer passed in the pData parameter including the RIO_BUFFERID in the + /// BufferId member of RIO_BUF structure must remain valid for the duration of the receive operation. + /// + /// + /// In order to avoid race conditions, a buffer associated with a receive request should not be read or written before the request + /// completes. This includes using the buffer as the source for a send request or the destination for another receive request. Portions + /// of a registered buffer not associated with any receive request are not included in this restriction. + /// + /// + /// The pLocalAddress parameter can be used to retrieve the local address where the data was received. The pRemoteAddress parameter can + /// be used to retrieve the remote address from which the data was received. The local and remote addresses are returned as + /// SOCKADDR_INET structures. As a result, the Length member of the RIO_BUF pointed to by pLocalAddress or + /// pRemoteAddress parameters should be equal or greater than the size of a SOCKADDR_INET structure. + /// + /// + /// The following table summarizes the various uses of control data available for use with the control information in the pControlContext member. + /// + /// + /// + /// Protocol + /// cmsg_level + /// cmsg_type + /// Description + /// + /// + /// IPv4 + /// IPPROTO_IP + /// IP_ORIGINAL_ARRIVAL_IF + /// + /// Receives the original IPv4 arrival interface where the packet was received for datagram sockets. This control data is used by + /// firewalls when a Teredo, 6to4, or ISATAP tunnel is used for IPv4 NAT traversal. The cmsg_data[] member is a ULONG that contains the + /// IF_INDEX defined in the ifdef.h header file. For more information, see the IPPROTO_IP Socket Options for the + /// IP_ORIGINAL_ARRIVAL_IF socket option. + /// + /// + /// + /// IPv4 + /// IPPROTO_IP + /// IP_PKTINFO + /// Specifies/receives packet information. For more information, see the IPPROTO_IP Socket Options for the IP_PKTINFO socket option. + /// + /// + /// IPv6 + /// IPPROTO_IPV6 + /// IPV6_DSTOPTS + /// Specifies/receives destination options. + /// + /// + /// IPv6 + /// IPPROTO_IPV6 + /// IPV6_HOPLIMIT + /// + /// Specifies/receives hop limit. For more information, see the IPPROTO_IPV6 Socket Options for the IPV6_HOPLIMIT socket option. + /// + /// + /// + /// IPv6 + /// IPPROTO_IPV6 + /// IPV6_HOPOPTS + /// Specifies/receives hop-by-hop options. + /// + /// + /// IPv6 + /// IPPROTO_IPV6 + /// IPV6_NEXTHOP + /// Specifies next-hop address. + /// + /// + /// IPv6 + /// IPPROTO_IPV6 + /// IPV6_PKTINFO + /// + /// Specifies/receives packet information. For more information, see the IPPROTO_IPV6 Socket Options for the IPV6_PKTINFO socket option. + /// + /// + /// + /// IPv6 + /// IPPROTO_IPV6 + /// IPV6_RTHDR + /// Specifies/receives routing header. + /// + /// + /// + /// Control data is made up of one or more control data objects, each beginning with a WSACMSGHDR structure, defined as the following: + /// + /// The members of the WSACMSGHDR structure are as follows: + /// + /// + /// Term + /// Description + /// + /// + /// cmsg_len + /// + /// The number of bytes of data starting from the beginning of the WSACMSGHDR to the end of data (excluding padding bytes that may + /// follow data). + /// + /// + /// + /// cmsg_level + /// The protocol that originated the control information. + /// + /// + /// cmsg_type + /// The protocol-specific type of control information. + /// + /// + /// + /// The Flags parameter can be used to influence the behavior of the RIOReceiveEx function invocation beyond the options specified + /// for the associated socket. The behavior of this function is determined by a combination of any socket options set on the socket + /// associated with the SocketQueue parameter and the values specified in the Flags parameter. + /// + /// + /// Note + /// + /// The function pointer to the RIOReceiveEx function must be obtained at run time by making a call to the WSAIoctl + /// function with the SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the WSAIoctl + /// function must contain WSAID_MULTIPLE_RIO, a globally unique identifier (GUID) whose value identifies the Winsock registered + /// I/O extension functions. On success, the output returned by the WSAIoctl function contains a pointer to the + /// RIO_EXTENSION_FUNCTION_TABLE structure that contains pointers to the Winsock registered I/O extension functions. The + /// SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER IOCTL is defined in the Ws2def.h header file. The WSAID_MULTIPLE_RIO GUID + /// is defined in the Mswsock.h header file. + /// + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_rioreceiveex LPFN_RIORECEIVEEX LpfnRioreceiveex; int + // LpfnRioreceiveex( RIO_RQ SocketQueue, PRIO_BUF pData, ULONG DataBufferCount, PRIO_BUF pLocalAddress, PRIO_BUF pRemoteAddress, PRIO_BUF + // pControlContext, PRIO_BUF pFlags, DWORD Flags, PVOID RequestContext ) {...} + [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_RIORECEIVEEX")] + [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = false)] + public delegate int LPFN_RIORECEIVEEX(RIO_RQ SocketQueue, PRIO_BUF pData, uint DataBufferCount, [In, Optional] PRIO_BUF pLocalAddress, + [In, Optional] PRIO_BUF pRemoteAddress, [In, Optional] PRIO_BUF pControlContext, PRIO_BUF pFlags, RIO_MSG Flags, IntPtr RequestContext); + + /// + /// The RIORegisterBuffer function registers a RIO_BUFFERID, a registered buffer descriptor, with a specified buffer for + /// use with the Winsock registered I/O extensions. + /// + /// A pointer to the beginning of the memory buffer to register. + /// The length, in bytes, in the buffer to register. + /// + /// + /// If no error occurs, the RIORegisterBuffer function returns a registered buffer descriptor. Otherwise, a value of + /// RIO_INVALID_BUFFERID is returned, and a specific error code can be retrieved by calling the WSAGetLastError function. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// WSAEFAULT + /// + /// The system detected an invalid pointer address in attempting to use a pointer argument in a call. This error is returned if an + /// invalid buffer pointer is passed in DataBuffer parameter. + /// + /// + /// + /// WSAEINVAL + /// An invalid parameter was passed to the function. This error is returned if the DataLength parameter is zero. + /// + /// + /// + /// + /// + /// The RIORegisterBuffer function creates a registered buffer identifier for a specified buffer. When a buffer is registered, the + /// virtual memory pages containing the buffer will be locked into physical memory. + /// + /// + /// If several small, non-contiguous buffers are registered, the physical memory footprint for the buffers may effectively be as large as + /// an entire memory page per registration. In these cases it may be beneficial to allocate multiple request buffers together. + /// + /// + /// There is also a small amount of overhead in physical memory used for the buffer registration itself. So if there are many allocations + /// aggregated into single larger allocation, the physical memory footprint may be reduced further by aggregating the buffer + /// registrations as well. In this case the application may need to take extra care to ensure that the buffers are eventually + /// deregistered, but not while any send or receive requests are outstanding. + /// + /// + /// A portion of a registered buffer is passed to the RIOSend, RIOSendEx, RIOReceive, and RIOReceiveEx + /// functions in the pData parameter for sending or receiving data. + /// + /// When the buffer identifier is no longer needed, call the RIODeregisterBuffer function to deregister the buffer identifier. + /// + /// Note + /// + /// The function pointer to the RIORegisterBuffer function must be obtained at run time by making a call to the WSAIoctl + /// function with the SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the WSAIoctl + /// function must contain WSAID_MULTIPLE_RIO, a globally unique identifier (GUID) whose value identifies the Winsock registered + /// I/O extension functions. On success, the output returned by the WSAIoctl function contains a pointer to the + /// RIO_EXTENSION_FUNCTION_TABLE structure that contains pointers to the Winsock registered I/O extension functions. The + /// SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER IOCTL is defined in the Ws2def.h header file. The WSAID_MULTIPLE_RIO GUID + /// is defined in the Mswsock.h header file. + /// + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_rioregisterbuffer LPFN_RIOREGISTERBUFFER + // LpfnRioregisterbuffer; RIO_BUFFERID LpfnRioregisterbuffer( PCHAR DataBuffer, DWORD DataLength ) {...} + [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_RIOREGISTERBUFFER")] + [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = false, CharSet = CharSet.Ansi)] + public delegate RIO_BUFFERID LPFN_RIOREGISTERBUFFER([MarshalAs(UnmanagedType.LPStr)] StringBuilder DataBuffer, uint DataLength); + + /// + /// The RIOResizeCompletionQueue function resizes an I/O completion queue to be either larger or smaller for use with the Winsock + /// registered I/O extensions. + /// + /// A descriptor that identifies an existing I/O completion queue to resize. + /// + /// + /// + /// If no error occurs, the RIOResizeCompletionQueue function returns TRUE. Otherwise, a value of FALSE is returned, + /// and a specific error code can be retrieved by calling the WSAGetLastError function. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// WSAEFAULT + /// + /// The system detected an invalid pointer address in attempting to use a pointer argument in a call. This error is returned if the + /// completion queue specified in the CQ parameter contains an invalid pointer. + /// + /// + /// + /// WSAEINVAL + /// + /// An invalid parameter was passed to the function. This error is returned if the CQ parameter is not valid (RIO_INVALID_CQ, for + /// example). This error is also returned if the size of the queue specified in the QueueSize parameter is greater than RIO_CQ_MAX_SIZE. + /// + /// + /// + /// WSAENOBUFS + /// + /// Sufficient memory could not be allocated. This error is returned if memory could not be allocated for the queue specified in the + /// QueueSize parameter. + /// + /// + /// + /// WSAETOOMANYREFS + /// + /// There are too many operations that still reference the I/O completion queue. Resizing of this I/O completion queue to be smaller is + /// not possible at this time. + /// + /// + /// + /// + /// The RIOResizeCompletionQueue function resizes an I/O completion queue to be either larger or smaller. If the I/O completion + /// queue already contains completions, those completions will be copied over to the new completion queue. + /// + /// + /// I/O completion queues have a required minimum size that is dependent on the number of request queues associated with the completion + /// queue and the number of sends and receives on the request queues. If an application calls the RIOResizeCompletionQueue + /// function and tries to set the queue too small for the number of existing completions in the I/O completion queue, the call will fail + /// and the queue will not be resized. + /// + /// + /// Note + /// + /// The function pointer to the RIOResizeCompletionQueue function must be obtained at run time by making a call to the + /// WSAIoctl function with the SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the + /// WSAIoctl function must contain WSAID_MULTIPLE_RIO, a globally unique identifier (GUID) whose value identifies the + /// Winsock registered I/O extension functions. On success, the output returned by the WSAIoctl function contains a pointer to the + /// RIO_EXTENSION_FUNCTION_TABLE structure that contains pointers to the Winsock registered I/O extension functions. The + /// SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER IOCTL is defined in the Ws2def.h header file. The WSAID_MULTIPLE_RIO GUID + /// is defined in the Mswsock.h header file. + /// + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_rioresizecompletionqueue LPFN_RIORESIZECOMPLETIONQUEUE + // LpfnRioresizecompletionqueue; BOOL LpfnRioresizecompletionqueue( RIO_CQ CQ, DWORD QueueSize ) {...} + [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_RIORESIZECOMPLETIONQUEUE")] + [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = false)] + [return: MarshalAs(UnmanagedType.Bool)] + public delegate bool LPFN_RIORESIZECOMPLETIONQUEUE(RIO_CQ CQ, uint QueueSize); + + /// + /// The RIOResizeRequestQueue function resizes a request queue to be either larger or smaller for use with the Winsock registered + /// I/O extensions. + /// + /// A descriptor that identifies an existing registered I/O socket descriptor (request queue) to resize. + /// + /// The maximum number of outstanding sends allowed on the socket. This value can be larger or smaller than the original number. + /// This parameter is usually a small number for most applications. + /// + /// + /// The maximum number of outstanding receives allowed on the socket. This value can be larger or smaller than the original number. + /// + /// + /// + /// If no error occurs, the RIOResizeRequestQueue function returns TRUE. Otherwise, a value of FALSE is returned, + /// and a specific error code can be retrieved by calling the WSAGetLastError function. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// WSAEINVAL + /// + /// An invalid parameter was passed to the function. This error is returned if the RQ parameter is not valid (RIO_INVALID_RQ, for + /// example). This error is also returned if both the MaxOutstandingReceive and MaxOutstandingSend parameters are zero. + /// + /// + /// + /// WSAENOBUFS + /// Sufficient memory could not be allocated. This error is returned if memory could not be allocated for the resized request queue. + /// + /// + /// WSAETOOMANYREFS + /// + /// There are too many operations that still reference the request queue. Resizing of this request queue to be smaller is not possible at + /// this time. + /// + /// + /// + /// + /// + /// + /// The RIOResizeRequestQueue function resizes a request queue to be either larger or smaller. If the request queue already + /// contains entries, those entries will be copied over to the new request queue. + /// + /// + /// A request queue has a required minimum size that is dependent on the current number of entries (number of sends and receives on the + /// request queue). If an application calls the RIOResizeRequestQueue function and tries to set the queue too small for the number + /// of existing entries, the call will fail and the queue will not be resized. + /// + /// + /// Note + /// + /// The function pointer to the RIOResizeRequestQueue function must be obtained at run time by making a call to the + /// WSAIoctl function with the SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the + /// WSAIoctl function must contain WSAID_MULTIPLE_RIO, a globally unique identifier (GUID) whose value identifies the + /// Winsock registered I/O extension functions. On success, the output returned by the WSAIoctl function contains a pointer to the + /// RIO_EXTENSION_FUNCTION_TABLE structure that contains pointers to the Winsock registered I/O extension functions. The + /// SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER IOCTL is defined in the Ws2def.h header file. The WSAID_MULTIPLE_RIO GUID + /// is defined in the Mswsock.h header file. + /// + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_rioresizerequestqueue LPFN_RIORESIZEREQUESTQUEUE + // LpfnRioresizerequestqueue; BOOL LpfnRioresizerequestqueue( RIO_RQ RQ, DWORD MaxOutstandingReceive, DWORD MaxOutstandingSend ) {...} + [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_RIORESIZEREQUESTQUEUE")] + [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = false)] + [return: MarshalAs(UnmanagedType.Bool)] + public delegate bool LPFN_RIORESIZEREQUESTQUEUE(RIO_RQ RQ, uint MaxOutstandingReceive, uint MaxOutstandingSend); + + /// + /// The RIOSend function sends network data on a connected registered I/O TCP socket or a bound registered I/O UDP socket for use + /// with the Winsock registered I/O extensions. + /// + /// A descriptor that identifies a connected registered I/O TCP socket or a bound registered I/O UDP socket. + /// + /// A description of the portion of the registered buffer from which to send data. + /// + /// This parameter may be NULL for a bound registered I/O UDP socket if the application does not need to send a data payload in the UDP datagram. + /// + /// + /// + /// A data buffer count parameter that indicates if data is to be sent in the buffer pointed to by the pData parameter. + /// This parameter should be set to zero if the pData is NULL. Otherwise, this parameter should be set to 1. + /// + /// + /// A set of flags that modify the behavior of the RIOSend function. + /// The Flags parameter can contain a combination of the following options defined in the Mswsockdef.h header file: + /// + /// + /// The request context to associate with this send operation. + /// + /// + /// If no error occurs, the RIOSend function returns TRUE. In this case, the send operation is successfully initiated and + /// the completion will have already been queued or the operation has been successfully initiated and the completion will be queued at a + /// later time. + /// + /// + /// A value of FALSE indicates the function failed, the operation was not successfully initiated and no completion indication will + /// be queued. A specific error code can be retrieved by calling the WSAGetLastError function. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// WSAEFAULT + /// + /// The system detected an invalid pointer address in attempting to use a pointer argument in a call. This error is returned if a buffer + /// identifier is deregistered or a buffer is freed for any of the RIO_BUF structures passed in parameters before the operation is + /// queued or invoked. + /// + /// + /// + /// WSAEINVAL + /// + /// An invalid parameter was passed to the function. This error is returned if the SocketQueue parameter is not valid, the + /// Flags parameter contains a value not valid for a send operation, or the integrity of the completion queue has been + /// compromised. This error can also be returned for other issues with parameters. + /// + /// + /// + /// WSAENOBUFS + /// + /// Sufficient memory could not be allocated. This error is returned if the I/O completion queue associated with the SocketQueue + /// parameter is full or the I/O completion queue was created with zero send entries. + /// + /// + /// + /// WSA_IO_PENDING + /// The operation has been successfully initiated and the completion will be queued at a later time. + /// + /// + /// + /// + /// + /// An application can use the RIOSend function to send network data from any buffer completely contained within a single + /// registered buffer. The Offset and Length members of the RIO_BUF structure pointed to by the pData parameter + /// determine the network data to be sent from the buffer. + /// + /// + /// The buffer associated with a send operation must not be used concurrently with another send or receive operation. The buffer, and + /// buffer registration, must remain valid for the duration of a send operation. This means that you should not pass the same PRIO_BUF to + /// a RIOSend(Ex) request when one is already pending. Only after an in-flight RIOSend(Ex) request is complete should you re-use the same + /// PRIO_BUF (either with the same offset or with a different offset and length). Furthermore, when send data references a registered + /// buffer (either a portion or the entire buffer), the entire registered buffer must not be used until the send has completed. This + /// includes using a portion of the registered buffer for a receive operation or another send operation. + /// + /// + /// The Flags parameter can be used to influence the behavior of the RIOSend function beyond the options specified for the + /// associated socket. The behavior of this function is determined by a combination of any socket options set on the socket associated + /// with the SocketQueue parameter and the values specified in the Flags parameter. + /// + /// + /// Note + /// + /// The function pointer to the RIOSend function must be obtained at run time by making a call to the WSAIoctl function + /// with the SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the WSAIoctl function + /// must contain WSAID_MULTIPLE_RIO, a globally unique identifier (GUID) whose value identifies the Winsock registered I/O + /// extension functions. On success, the output returned by the WSAIoctl function contains a pointer to the + /// RIO_EXTENSION_FUNCTION_TABLE structure that contains pointers to the Winsock registered I/O extension functions. The + /// SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER IOCTL is defined in the Ws2def.h header file. The WSAID_MULTIPLE_RIO GUID + /// is defined in the Mswsock.h header file. + /// + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_riosend LPFN_RIOSEND LpfnRiosend; BOOL LpfnRiosend( RIO_RQ + // SocketQueue, PRIO_BUF pData, ULONG DataBufferCount, DWORD Flags, PVOID RequestContext ) {...} + [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_RIOSEND")] + [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = false)] + [return: MarshalAs(UnmanagedType.Bool)] + public delegate bool LPFN_RIOSEND(RIO_RQ SocketQueue, [In, Optional] PRIO_BUF pData, uint DataBufferCount, RIO_MSG Flags, + IntPtr RequestContext); + + /// + /// The RIOSendEx function sends network data on a connected registered I/O TCP socket or a bound registered I/O UDP socket with + /// additional options for use with the Winsock registered I/O extensions. + /// + /// A descriptor that identifies a connected registered I/O TCP socket or a bound registered I/O UDP socket. + /// + /// + /// A buffer segment from a registered buffer from which to send data. The RIO_BUF structure pointed to by this parameter can + /// represent a portion of a registered buffer or a complete registered buffer. + /// + /// + /// This parameter may be NULL for a bound registered I/O UDP socket if the application does not need to send a data payload in the UDP datagram. + /// + /// + /// + /// A data buffer count parameter that indicates if data is to be sent in the buffer pointed to by the pData parameter. + /// This parameter should be set to zero if the pData is NULL. Otherwise, this parameter should be set to 1. + /// + /// This parameter is reserved and must be NULL. + /// + /// A buffer segment from a registered buffer that on input holds the remote address to which the network data is to be sent. + /// This parameter may be NULL if the socket is connected. + /// + /// + /// A buffer slice that on completion will hold additional control information about the send operation. + /// This parameter may be NULL if the application does not want to receive the additional control information. + /// + /// + /// A buffer slice that on completion will hold additional information about the set of flags for the send operation. + /// This parameter may be NULL if the application does not want to receive the additional flags information. + /// + /// + /// A set of flags that modify the behavior of the RIOSendEx function. + /// The Flags parameter can contain a combination of the following options defined in the Mswsockdef.h header file: + /// + /// + /// The request context to associate with this send operation. + /// + /// + /// If no error occurs, the RIOSendEx function returns TRUE. In this case, the send operation is successfully initiated and + /// the completion will have already been queued or the operation has been successfully initiated and the completion will be queued at a + /// later time. + /// + /// + /// A value of FALSE indicates the function failed, the operation was not successfully initiated and no completion indication will + /// be queued. A specific error code can be retrieved by calling the WSAGetLastError function. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// WSAEFAULT + /// + /// The system detected an invalid pointer address in attempting to use a pointer argument in a call. This error is returned if a buffer + /// identifier is deregistered or a buffer is freed for any of the RIO_BUF structures passed in parameters before the operation is + /// queued or invoked. + /// + /// + /// + /// WSAEINVAL + /// + /// An invalid parameter was passed to the function. This error is returned if the SocketQueue parameter is not valid, the + /// Flags parameter contains a value not valid for a send operation, or the integrity of the completion queue has been + /// compromised. This error can also be returned for other issues with parameters. + /// + /// + /// + /// WSAENOBUFS + /// + /// Sufficient memory could not be allocated. This error is returned if the I/O completion queue associated with the SocketQueue + /// parameter is full or the I/O completion queue was created with zero send entries. + /// + /// + /// + /// WSA_IO_PENDING + /// The operation has been successfully initiated and the completion will be queued at a later time. + /// + /// + /// + /// + /// + /// An application can use the RIOSendEx function to send network data from any buffer completely contained within a single + /// registered buffer. The Offset and Length members of the RIO_BUF structure pointed to by the pData parameter + /// determine the network data to be sent from the buffer. + /// + /// + /// The buffer associated with a send operation must not be used concurrently with another send or receive operation. The buffer, and + /// buffer registration, must remain valid for the duration of a send operation. This means that you should not pass the same PRIO_BUF to + /// a RIOSend(Ex) request when one is already pending. Only after an in-flight RIOSend(Ex) request is complete should you re-use the same + /// PRIO_BUF (either with the same offset or with a different offset and length). Furthermore, when send data references a registered + /// buffer (either a portion or the entire buffer), the entire registered buffer must not be used until the send has completed. This + /// includes using a portion of the registered buffer for a receive operation or another send operation. + /// + /// + /// The pLocalAddress parameter can be used to retrieve the local address from which the data was sent. The pRemoteAddress parameter can + /// be used to retrieve the remote address to which the data was sent. The local and remote addresses are returned as + /// SOCKADDR_INET structures. As a result, the Length member of the RIO_BUF pointed to by pLocalAddress or + /// pRemoteAddress parameters should be equal or greater than the size of a SOCKADDR_INET structure. + /// + /// + /// The following table summarizes the various uses of control data available for use with the control information in the pControlContext member. + /// + /// + /// + /// Protocol + /// cmsg_level + /// cmsg_type + /// Description + /// + /// + /// IPv4 + /// IPPROTO_IP + /// IP_PKTINFO + /// Specifies/receives packet information. For more information, see the IPPROTO_IP Socket Options for the IP_PKTINFO socket option. + /// + /// + /// IPv6 + /// IPPROTO_IPV6 + /// IPV6_DSTOPTS + /// Specifies/receives destination options. + /// + /// + /// IPv6 + /// IPPROTO_IPV6 + /// IPV6_HOPLIMIT + /// + /// Specifies/receives hop limit. For more information, see the IPPROTO_IPV6 Socket Options for the IPV6_HOPLIMIT socket option. + /// + /// + /// + /// IPv6 + /// IPPROTO_IPV6 + /// IPV6_HOPOPTS + /// Specifies/receives hop-by-hop options. + /// + /// + /// IPv6 + /// IPPROTO_IPV6 + /// IPV6_NEXTHOP + /// Specifies next-hop address. + /// + /// + /// IPv6 + /// IPPROTO_IPV6 + /// IPV6_PKTINFO + /// + /// Specifies/receives packet information. For more information, see the IPPROTO_IPV6 Socket Options for the IPV6_PKTINFO socket option. + /// + /// + /// + /// IPv6 + /// IPPROTO_IPV6 + /// IPV6_RTHDR + /// Specifies/receives routing header. + /// + /// + /// + /// Control data is made up of one or more control data objects, each beginning with a WSACMSGHDR structure, defined as the following: + /// + /// The members of the WSACMSGHDR structure are as follows: + /// + /// + /// Term + /// Description + /// + /// + /// cmsg_len + /// + /// The number of bytes of data starting from the beginning of the WSACMSGHDR to the end of data (excluding padding bytes that may + /// follow data). + /// + /// + /// + /// cmsg_level + /// The protocol that originated the control information. + /// + /// + /// cmsg_type + /// The protocol-specific type of control information. + /// + /// + /// + /// The Flags parameter can be used to influence the behavior of the RIOSendEx function beyond the options specified for the + /// associated socket. The behavior of this function is determined by a combination of any socket options set on the socket associated + /// with the SocketQueue parameter and the values specified in the Flags parameter. + /// + /// + /// Note + /// + /// The function pointer to the RIOSendEx function must be obtained at run time by making a call to the WSAIoctl function + /// with the SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the WSAIoctl function + /// must contain WSAID_MULTIPLE_RIO, a globally unique identifier (GUID) whose value identifies the Winsock registered I/O + /// extension functions. On success, the output returned by the WSAIoctl function contains a pointer to the + /// RIO_EXTENSION_FUNCTION_TABLE structure that contains pointers to the Winsock registered I/O extension functions. The + /// SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER IOCTL is defined in the Ws2def.h header file. The WSAID_MULTIPLE_RIO GUID + /// is defined in the Mswsock.h header file. + /// + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_riosendex LPFN_RIOSENDEX LpfnRiosendex; BOOL + // LpfnRiosendex( RIO_RQ SocketQueue, PRIO_BUF pData, ULONG DataBufferCount, PRIO_BUF pLocalAddress, PRIO_BUF pRemoteAddress, PRIO_BUF + // pControlContext, PRIO_BUF pFlags, DWORD Flags, PVOID RequestContext ) {...} + [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_RIOSENDEX")] + [UnmanagedFunctionPointer(CallingConvention.Winapi, SetLastError = false)] + [return: MarshalAs(UnmanagedType.Bool)] + public delegate bool LPFN_RIOSENDEX(RIO_RQ SocketQueue, [In, Optional] PRIO_BUF pData, uint DataBufferCount, [In, Optional] PRIO_BUF pLocalAddress, + [In, Optional] PRIO_BUF pRemoteAddress, [In, Optional] PRIO_BUF pControlContext, [In, Optional] PRIO_BUF pFlags, uint Flags, IntPtr RequestContext); + + /// + /// The TransmitPackets function transmits in-memory data or file data over a connected socket. The TransmitPackets + /// function uses the operating system cache manager to retrieve file data, locking memory for the minimum time required to transmit and + /// resulting in efficient, high-performance transmission. + /// + /// + /// A handle to the connected socket to be used in the transmission. Although the socket does not need to be a connection-oriented + /// circuit, the default destination/peer should have been established using the connect, WSAConnect, accept, WSAAccept, AcceptEx, or + /// WSAJoinLeaf function. + /// + /// An array of type TRANSMIT_PACKETS_ELEMENT, describing the data to be transmitted. + /// The number of elements in lpPacketArray. + /// + /// + /// The size, in bytes, of the data block used in the send operation. Set nSendSize to zero to let the sockets layer select a + /// default send size. + /// + /// + /// Setting nSendSize to 0xFFFFFFF enables the caller to control the size and content of each send request, achieved by using the + /// TP_ELEMENT_EOP flag in the TRANSMIT_PACKETS_ELEMENT array pointed to in the lpPacketArray parameter. This capability is useful + /// for message protocols that place limitations on the size of individual send requests. + /// + /// + /// + /// A pointer to an OVERLAPPED structure. If the socket handle specified in the hSocket parameter has been opened as overlapped, + /// use this parameter to achieve asynchronous (overlapped) I/O operation. Socket handles are opened as overlapped by default. + /// + /// + /// + /// A set of flags used to customize processing of the TransmitPackets function. The following table outlines the use of the + /// dwFlags parameter. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// TF_DISCONNECT + /// + /// Starts a transport-level disconnect after all the file data has been queued for transmission. Applies only to connection-oriented + /// sockets. Specifying this flag for sockets that do not support disconnect semantics (such as datagram sockets) results in an error. + /// + /// + /// + /// TF_REUSE_SOCKET + /// + /// Prepares the socket handle to be reused. When the TransmitPackets function completes, the socket handle can be passed to the + /// AcceptEx function. Valid only when a connection-oriented socket and TF_DISCONNECT are specified. + /// + /// + /// + /// TF_USE_DEFAULT_WORKER + /// + /// Directs Winsock to use the system's default thread to process long TransmitPackets requests. Long TransmitPackets + /// requests are defined as requests that require more than a single read from the file or a cache; the long request definition therefore + /// depends on the size of the file and the specified length of the send packet. The system default thread can be adjusted using the + /// following registry parameter as a REG_DWORD: HKEY_LOCAL_MACHINE\ CurrentControlSet\ Services\ AFD\ + /// Parameters\ TransmitWorker + /// + /// + /// + /// TF_USE_SYSTEM_THREAD + /// + /// Directs Winsock to use system threads to process long TransmitPackets requests. Long TransmitPackets requests are + /// defined as requests that require more than a single read from the file or a cache; the long request definition therefore depends on + /// the size of the file and the specified length of the send packet. + /// + /// + /// + /// TF_USE_KERNEL_APC + /// + /// Directs Winsock to use kernel Asynchronous Procedure Calls (APCs) instead of worker threads to process long TransmitPackets + /// requests. Long TransmitPackets requests are defined as requests that require more than a single read from the file or a cache; + /// the long request definition therefore depends on the size of the file and the specified length of the send packet. See Remarks for + /// more information. + /// + /// + /// + /// + /// + /// + /// If the TransmitPackets function succeeds, the return value is TRUE. Otherwise, the return value is FALSE. To get + /// extended error information, call WSAGetLastError. An error code of WSA_IO_PENDING or ERROR_IO_PENDING indicates that the overlapped + /// operation has been successfully initiated and that completion will be indicated at a later time. Any other error code indicates that + /// the overlapped operation was not successfully initiated and no completion indication will occur. Applications should handle either + /// ERROR_IO_PENDING or WSA_IO_PENDING in this case. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// WSAECONNABORTED + /// + /// An established connection was aborted by the software in your host machine. This error is returned if the virtual circuit was + /// terminated due to a time-out or other failure. + /// + /// + /// + /// WSAECONNRESET + /// + /// An existing connection was forcibly closed by the remote host. This error is returned for a stream socket when the virtual circuit + /// was reset by the remote side. The application should close the socket as it is no longer usable. + /// + /// + /// + /// WSAEFAULT + /// + /// The system detected an invalid pointer address in attempting to use a pointer argument in a call. This error is returned if the + /// lpPacketArray or the lpOverlapped parameter is not totally contained in a valid part of the user address space. + /// + /// + /// + /// WSAEINVAL + /// + /// An invalid argument was supplied. This error is returned if the dwFlags parameter has the TF_REUSE_SOCKET flag set, but + /// the TF_DISCONNECT flag was not set. This error is also returned if the offset specified in the OVERLAPPED structure pointed to + /// by the lpOverlapped is not within the file. This error is also returned if the total number of bytes to be transmitted is a + /// value greater than 2,147,483,646, the maximum value for a 32-bit integer minus 1. + /// + /// + /// + /// WSAENETDOWN + /// A socket operation encountered a dead network.This error is returned if the network subsystem has failed. + /// + /// + /// WSAENETRESET + /// + /// The connection has been broken due to keep-alive activity detecting a failure while the operation was in progress. This error is + /// returned for a stream socket where the connection was broken due to keep-alive activity detecting a failure. + /// + /// + /// + /// WSAENOBUFS + /// + /// An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full. This + /// error is also returned if the Windows Sockets provider reports a buffer deadlock. + /// + /// + /// + /// WSAENOTCONN + /// + /// A request to send or receive data was disallowed because the socket is not connected. This error is returned for a stream socket. + /// + /// + /// + /// WSAENOTSOCK + /// + /// An operation was attempted on something that is not a socket. This error is returned if the hSocket parameter is not a socket. + /// + /// + /// + /// WSAESHUTDOWN + /// + /// A request to send or receive data was disallowed because the socket had already been shut down in that direction with a previous + /// shutdown call. This error is returned if a stream socket has been shut down for sending. It is not possible to call TransmitFile on a + /// stream socket after the shutdown function has been called on the socket with the how parameter set to SD_SEND or SD_BOTH. + /// + /// + /// + /// WSANOTINITIALISED + /// + /// Either the application has not called the WSAStartup function, or WSAStartup failed. A successful WSAStartup call must + /// occur before using the TransmitFile function. + /// + /// + /// + /// WSA_IO_PENDING + /// + /// An overlapped I/O operation is in progress. This value is returned if an overlapped I/O operation was successfully initiated and + /// indicates that completion will be indicated at a later time. + /// + /// + /// + /// WSA_OPERATION_ABORTED + /// + /// The I/O operation has been aborted because of either a thread exit or an application request. This error is returned if the + /// overlapped operation has been canceled due to the closure of the socket, the execution of the "SIO_FLUSH" command in WSAIoctl, or the + /// thread that initiated the overlapped request exited before the operation completed. + /// + /// + /// + /// + /// + /// The TransmitPackets function is optimized according to the operating system on which it is used: + /// + /// + /// On Windows server editions, the TransmitPackets function is optimized for high performance. + /// + /// + /// + /// On Windows client editions, the TransmitPackets function is optimized for minimum memory and resource utilization. + /// + /// + /// + /// + /// The maximum number of bytes that can be transmitted using a single call to the TransmitPackets function is 2,147,483,646, the + /// maximum value for a 32-bit integer minus 1. If an application needs to transmit data larger than 2,147,483,646 bytes, then multiple + /// calls to the TransmitPackets function can be used with each call transferring no more than 2,147,483,646 bytes. + /// + /// The function pointer for the TransmitPackets function must be obtained at run time by making a call to the + /// WSAIoctl function with the SIO_GET_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the WSAIoctl + /// function must contain WSAID_TRANSMITPACKETS, a globally unique identifier (GUID) whose value identifies the + /// TransmitPackets extension function. On success, the output returned by the WSAIoctl function contains a pointer to the + /// TransmitPackets function. The WSAID_TRANSMITPACKETS GUID is defined in the Mswsock.h header file. + /// Expect better performance results when using the TransmitPackets function on Windows Server 2003. + /// + /// When lpOverlapped is not NULL, overlapped I/O might not finish before the TransmitPackets function returns. When + /// this occurs, the TransmitPackets function returns fails, and a call to the WSAGetLastError function returns ERROR_IO_PENDING, + /// allowing the caller to continue processing while the transmission completes. + /// + /// All I/O initiated by a given thread is canceled when that thread exits. For overlapped sockets, pending + /// asynchronous operations can fail if the thread is closed before the operations complete. See ExitThread for more information. + /// + /// When the TransmitPackets function returns TRUE or returns FALSE and WSAGetLastError returns ERROR_IO_PENDING, + /// Windows sets the event specified by the hEvent member of the OVERLAPPED structure or the socket specified by hSocket to + /// the signaled state, and upon completion, delivers notification to any completion port associated with the socket. Use + /// GetOverlappedResult, or WSAGetOverlappedResult, or GetQueuedCompletionStatus to retrieve final status and number of bytes transmitted. + /// + /// TransmitPackets and Asynchronous Procedure Calls (APCs) + /// + /// Use of the TF_USE_KERNEL_APC flag can deliver significant performance benefits. If the thread initiating the TransmitPackets + /// function call is being used for heavy computations, it is possible, though unlikely, that APCs could be prevented from launching. + /// + /// There is a difference between kernel and user-mode APCs: + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_transmitpackets LPFN_TRANSMITPACKETS LpfnTransmitpackets; + // BOOL LpfnTransmitpackets( SOCKET hSocket, LPTRANSMIT_PACKETS_ELEMENT lpPacketArray, DWORD nElementCount, DWORD nSendSize, LPOVERLAPPED + // lpOverlapped, DWORD dwFlags ) {...} + [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_TRANSMITPACKETS")] + [UnmanagedFunctionPointer(CallingConvention.Winapi)] + [return: MarshalAs(UnmanagedType.Bool)] + public delegate bool LPFN_TRANSMITPACKETS(SOCKET hSocket, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] TRANSMIT_PACKETS_ELEMENT[] lpPacketArray, + uint nElementCount, uint nSendSize, [In] IntPtr lpOverlapped, TF dwFlags); + + /// + /// + /// LPFN_WSARECVMSG is a function pointer type. You implement a matching WSARecvMsg callback function in your app. The + /// system uses your callback function to transmit to you in-memory data, or file data, over a connected socket. + /// + /// + /// Your WSARecvMsg callback function receives ancillary data/control information with a message, from connected and unconnected sockets. + /// + /// + /// Note + /// This function is a Microsoft-specific extension to the Windows Sockets specification. + /// + /// + /// + /// Type: _In_ SOCKET + /// A descriptor that identifies the socket. + /// + /// + /// Type: _Inout_ LPWSAMSG + /// A pointer to a WSAMSG structure based on the Posix.1g specification for the msghdr structure. + /// + /// + /// Type: _Out_opt_ LPDWORD + /// A pointer to a DWORD containing number of bytes received by this call if the WSARecvMsg operation completes immediately. + /// + /// To avoid potentially erroneous results, pass NULL for this parameter if the lpOverlapped parameter is not NULL . This + /// parameter can be NULL only if the lpOverlapped parameter is not NULL. + /// + /// + /// + /// Type: _Inout_opt_ LPWSAOVERLAPPED + /// A pointer to a WSAOVERLAPPED structure. Ignored for non-overlapped structures. + /// + /// + /// Type: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE + /// A pointer to the completion routine called when the receive operation completes. Ignored for non-overlapped structures. + /// + /// + /// + /// If no error occurs and the receive operation has completed immediately, WSARecvMsg returns zero. In this case, the completion + /// routine will have already been scheduled to be called once the calling thread is in the alertable state. Otherwise, a value of + /// SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError. The error code + /// WSA_IO_PENDING indicates that the overlapped operation has been successfully initiated and that completion will be indicated + /// at a later time. + /// + /// + /// Any other error code indicates that the operation was not successfully initiated and no completion indication will occur if an + /// overlapped operation was requested. + /// + /// + /// + /// Error code + /// Meaning + /// + /// + /// WSAECONNRESET + /// + /// For a UDP datagram socket, this error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message. + /// + /// + /// + /// WSAEFAULT + /// + /// The lpBuffers, lpFlags, lpFrom, lpNumberOfBytesRecvd, lpFromlen, lpOverlapped, or + /// lpCompletionRoutine parameter is not totally contained in a valid part of the user address space: the lpFrom buffer was + /// too small to accommodate the peer address. This error is also returned if a name member of the WSAMSG structure pointed + /// to by the lpMsg parameter was a NULL pointer and the namelen member of the WSAMSG structure was not set + /// to zero. This error is also returned if a Control.buf member of the WSAMSG structure pointed to by the lpMsg + /// parameter was a NULL pointer and the Control.len member of the WSAMSG structure was not set to zero. + /// + /// + /// + /// WSAEINPROGRESS + /// A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function. + /// + /// + /// WSAEINTR + /// A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall. + /// + /// + /// WSAEINVAL + /// The socket has not been bound (with bind, for example). + /// + /// + /// WSAEMSGSIZE + /// + /// The message was too large to fit into the specified buffer and (for unreliable protocols only) any trailing portion of the message + /// that did not fit into the buffer has been discarded. + /// + /// + /// + /// WSAENETDOWN + /// The network subsystem has failed. + /// + /// + /// WSAENETRESET + /// For a datagram socket, this error indicates that the time to live has expired. + /// + /// + /// WSAENOTCONN + /// The socket is not connected (connection-oriented sockets only). + /// + /// + /// WSAETIMEDOUT + /// + /// The socket timed out. This error is returned if the socket had a wait timeout specified using the SO_RCVTIMEO socket option + /// and the timeout was exceeded. + /// + /// + /// + /// WSAEOPNOTSUPP + /// + /// The socket operation is not supported. This error is returned if the dwFlags member of the WSAMSG structure pointed to + /// by the lpMsg parameter includes the MSG_PEEK control flag on a non-datagram socket. + /// + /// + /// + /// WSAEWOULDBLOCK + /// + /// Windows NT: Overlapped sockets: There are too many outstanding overlapped I/O requests. Non-overlapped sockets: The socket is + /// marked as nonblocking and the receive operation cannot be completed immediately. + /// + /// + /// + /// WSANOTINITIALISED + /// A successful WSAStartup call must occur before using this function. + /// + /// + /// WSA_IO_PENDING + /// An overlapped operation was successfully initiated and completion will be indicated at a later time. + /// + /// + /// WSA_OPERATION_ABORTED + /// The overlapped operation has been canceled due to the closure of the socket. + /// + /// + /// + /// + /// + /// The WSARecvMsg function can be used in place of the WSARecv and WSARecvFrom functions to receive data and + /// optional control information from connected and unconnected sockets. The WSARecvMsg function can only be used with datagrams + /// and raw sockets. The socket descriptor in the s parameter must be opened with the socket type set to SOCK_DGRAM or SOCK_RAW. + /// + /// + /// Note The function pointer for the WSARecvMsg function must be obtained at run time by making a call to the + /// WSAIoctl function with the SIO_GET_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the + /// WSAIoctl function must contain WSAID_WSARECVMSG, a globally unique identifier (GUID) whose value identifies the + /// WSARecvMsg extension function. On success, the output returned by the WSAIoctl function contains a pointer to the + /// WSARecvMsg function. The WSAID_WSARECVMSG GUID is defined in the Mswsock.h header file. + /// + /// + /// The dwFlags member of the WSAMSG structure pointed to by the lpMsg parameter may only contain the MSG_PEEK + /// control flag on input. + /// + /// + /// Overlapped sockets are created with a WSASocket function call that has the WSA_FLAG_OVERLAPPED flag set. For overlapped + /// sockets, receiving information uses overlapped I/O unless both the lpOverlapped and lpCompletionRoutine parameters are NULL. + /// The socket is treated as a non-overlapped socket when both the lpOverlapped and lpCompletionRoutine parameters are NULL. + /// + /// + /// A completion indication occurs with overlapped sockets. Once the buffer or buffers have been consumed by the transport, a completion + /// routine is triggered or an event object is set. If the operation does not complete immediately, the final completion status is + /// retrieved through the completion routine or by calling the WSAGetOverlappedResult function. + /// + /// + /// For overlapped sockets, WSARecvMsg is used to post one or more buffers into which incoming data will be placed as it becomes + /// available, after which the application-specified completion indication (invocation of the completion routine or setting of an event + /// object) occurs. If the operation does not complete immediately, the final completion status is retrieved through the completion + /// routine or the WSAGetOverlappedResult function. + /// + /// + /// For non-overlapped sockets, the blocking semantics are identical to that of the standard recv function and the lpOverlapped + /// and lpCompletionRoutine parameters are ignored. Any data that has already been received and buffered by the transport will be copied + /// into the specified user buffers. In the case of a blocking socket with no data currently having been received and buffered by the + /// transport, the call will block until data is received. Windows Sockets 2 does not define any standard blocking time-out mechanism for + /// this function. For protocols acting as byte-stream protocols the stack tries to return as much data as possible subject to the + /// available buffer space and amount of received data available. However, receipt of a single byte is sufficient to unblock the caller. + /// There is no guarantee that more than a single byte will be returned. For protocols acting as message-oriented, a full message is + /// required to unblock the caller. + /// + /// Note The SO_RCVTIMEO socket option applies only to blocking sockets. + /// + /// The buffers are filled in the order in which they appear in the array pointed to by the lpBuffers member of the WSAMSG + /// structure pointed to by the lpMsg parameter, and the buffers are packed so that no holes are created. + /// + /// + /// If this function is completed in an overlapped manner, it is the Winsock service provider's responsibility to capture this + /// WSABUF structure before returning from this call. This enables applications to build stack-based WSABUF arrays pointed + /// to by the lpBuffers member of the WSAMSG structure pointed to by the lpMsg parameter. + /// + /// + /// For message-oriented sockets (a socket type of SOCK_DGRAM or SOCK_RAW), an incoming message is placed into the buffers + /// up to the total size of the buffers, and the completion indication occurs for overlapped sockets. If the message is larger than the + /// buffers, the buffers are filled with the first part of the message and the excess data is lost, and WSARecvMsg generates the + /// error WSAEMSGSIZE. + /// + /// + /// When the IP_PKTINFO socket option is enabled on an IPv4 socket of type SOCK_DGRAM or SOCK_RAW, the WSARecvMsg + /// function returns packet information in the WSAMSG structure pointed to by the lpMsg parameter. One of the control data objects + /// in the returned WSAMSG structure will contain an in_pktinfo structure used to store received packet address information. + /// + /// + /// For datagrams received over IPv4, the Control member of the WSAMSG structure received will contain a WSABUF + /// structure that contains a WSACMSGHDR structure. The cmsg_level member of this WSACMSGHDR structure would contain + /// IPPROTO_IP, the cmsg_type member of this structure would contain IP_PKTINFO, and the cmsg_data member + /// would contain an in_pktinfo structure used to store received IPv4 packet address information. The IPv4 address in the + /// in_pktinfo structure is the IPv4 address from which the packet was received. + /// + /// + /// When the IPV6_PKTINFO socket option is enabled on an IPv6 socket of type SOCK_DGRAM or SOCK_RAW, the WSARecvMsg + /// function returns packet information in the WSAMSG structure pointed to by the lpMsg parameter. One of the control data objects + /// in the returned WSAMSG structure will contain an in6_pktinfo structure used to store received packet address information. + /// + /// + /// For datagrams received over IPv6, the Control member of the WSAMSG structure received will contain a WSABUF + /// structure that contains a WSACMSGHDR structure. The cmsg_level member of this WSACMSGHDR structure would contain + /// IPPROTO_IPV6, the cmsg_type member of this structure would contain IPV6_PKTINFO, and the cmsg_data member + /// would contain an in6_pktinfo structure used to store received IPv6 packet address information. The IPv6 address in the + /// in6_pktinfo structure is the IPv6 address from which the packet was received. + /// + /// + /// For a dual-stack datagram socket, if an application requires the WSARecvMsg function to return packet information in a + /// WSAMSG structure for datagrams received over IPv4, then IP_PKTINFO socket option must be set to true on the socket. If only + /// the IPV6_PKTINFO option is set to true on the socket, packet information will be provided for datagrams received over IPv6 but may + /// not be provided for datagrams received over IPv4. + /// + /// Note that the Ws2ipdef.h header file is automatically included in Ws2tcpip.h, and should never be used directly. + /// + /// Note All I/O initiated by a given thread is canceled when that thread exits. For overlapped sockets, pending asynchronous + /// operations can fail if the thread is closed before the operations complete. For more information, see ExitThread. + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// dwFlags + /// + /// On input, the dwFlags member of the WSAMSG structure pointed to by the lpMsg parameter can be used to influence the + /// behavior of the function invocation beyond the socket options specified for the associated socket. That is, the semantics of this + /// function are determined by the socket options and the dwFlags member of the WSAMSG structure. The only possible input + /// value for the dwFlags member of the WSAMSG structure pointed to by the lpMsg parameter is MSG_PEEK. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// MSG_PEEK + /// + /// Peek at the incoming data. The data is copied into the buffer, but is not removed from the input queue. This flag is valid only for + /// non-overlapped sockets. + /// + /// + /// + /// The possible values for dwFlags member on input are defined in the Winsock2.h header file. + /// + /// On output, the dwFlags member of the WSAMSG structure pointed to by the lpMsg parameter may return a combination of any + /// of the following values. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// MSG_BCAST + /// The datagram was received as a link-layer broadcast or with a destination IP address that is a broadcast address. + /// + /// + /// MSG_CTRUNC + /// The control (ancillary) data was truncated. More control data was present than the process allocated room for. + /// + /// + /// MSG_MCAST + /// The datagram was received with a destination IP address that is a multicast address. + /// + /// + /// MSG_TRUNC + /// The datagram was truncated. More data was present than the process allocated room for. + /// + /// + /// + /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files has + /// changed and the possible values for the dwFlags member on output are defined in the Ws2def.h header file which is + /// automatically included by the Winsock2.h header file. + /// + /// + /// On versions of the Platform Software Development Kit (SDK) for Windows Server 2003 and earlier, the possible values for the + /// dwFlags member on output are defined in the Mswsock.h header file. + /// + /// + /// Note When issuing a blocking Winsock call such as WSARecvMsg with the lpOverlapped parameter set to NULL, Winsock may + /// need to wait for a network event before the call can complete. Winsock performs an alertable wait in this situation, which can be + /// interrupted by an asynchronous procedure call (APC) scheduled on the same thread. Issuing another blocking Winsock call inside an APC + /// that interrupted an ongoing blocking Winsock call on the same thread will lead to undefined behavior, and must never be attempted by + /// Winsock clients. + /// + /// Overlapped Socket I/O + /// + /// If an overlapped operation completes immediately, WSARecvMsg returns a value of zero and the lpNumberOfBytesRecvd parameter is + /// updated with the number of bytes received and the flag bits indicated by the lpFlags parameter are also updated. If the overlapped + /// operation is successfully initiated and will complete later, WSARecvMsg returns SOCKET_ERROR and indicates error code + /// WSA_IO_PENDING. In this case, lpNumberOfBytesRecvd is not updated. When the overlapped operation completes, the amount of data + /// transferred is indicated either through the cbTransferred parameter in the completion routine (if specified), or through the + /// lpcbTransfer parameter in WSAGetOverlappedResult. Flag values are obtained by examining the lpdwFlags parameter of WSAGetOverlappedResult. + /// + /// + /// The WSARecvMsg function using overlapped I/O can be called from within the completion routine of a previous WSARecv, + /// WSARecvFrom, WSARecvMsg, WSASend, WSASendMsg, or WSASendTo function. For a given socket, I/O + /// completion routines will not be nested. This permits time-sensitive data transmissions to occur entirely within a preemptive context. + /// + /// + /// The lpOverlapped parameter must be valid for the duration of the overlapped operation. If multiple I/O operations are simultaneously + /// outstanding, each must reference a separate WSAOVERLAPPED structure. + /// + /// + /// If the lpCompletionRoutine parameter is NULL, the hEvent parameter of lpOverlapped is signaled when the overlapped operation + /// completes if it contains a valid event object handle. An application can use WSAWaitForMultipleEvents or + /// WSAGetOverlappedResult to wait or poll on the event object. + /// + /// + /// If lpCompletionRoutine is not NULL, the hEvent parameter is ignored and can be used by the application to pass context + /// information to the completion routine. A caller that passes a non- NULL lpCompletionRoutine and later calls + /// WSAGetOverlappedResult for the same overlapped I/O request may not set the fWait parameter for that invocation of + /// WSAGetOverlappedResult to TRUE. In this case the usage of the hEvent parameter is undefined, and attempting to wait on + /// the hEvent parameter would produce unpredictable results. + /// + /// + /// The completion routine follows the same rules as stipulated for Windows file I/O completion routines. The completion routine will not + /// be invoked until the thread is in an alertable wait state such as can occur when the function WSAWaitForMultipleEvents with + /// the fAlertable parameter set to TRUE is invoked. + /// + /// The prototype of the completion routine is as follows: + /// + /// void CALLBACK CompletionRoutine( IN DWORD dwError, IN DWORD cbTransferred, IN LPWSAOVERLAPPED lpOverlapped, IN DWORD dwFlags ); + /// + /// + /// The CompletionRoutine is a placeholder for an application-defined or library-defined function name. The dwError parameter + /// specifies the completion status for the overlapped operation as indicated by the lpOverlapped parameter. The cbTransferred parameter + /// specifies the number of bytes received. The dwFlags parameter contains information that is also returned in dwFlags member of + /// the WSAMSG structure pointed to by the lpMsg parameter if the receive operation had completed immediately. The + /// CompletionRoutine function does not return a value. + /// + /// + /// Returning from this function allows invocation of another pending completion routine for this socket. When using + /// WSAWaitForMultipleEvents, all waiting completion routines are called before the alertable thread's wait is satisfied with a + /// return code of WSA_IO_COMPLETION. The completion routines can be called in any order, not necessarily in the same order the + /// overlapped operations are completed. However, the posted buffers are guaranteed to be filled in the same order in which they are specified. + /// + /// + /// If you are using I/O completion ports, be aware that the order of calls made to WSARecvMsg is also the order in which the + /// buffers are populated. The WSARecvMsg function should not be called on the same socket simultaneously from different threads, + /// because it can result in an unpredictable buffer order. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_wsarecvmsg LPFN_WSARECVMSG LpfnWsarecvmsg; INT + // LpfnWsarecvmsg( SOCKET s, LPWSAMSG lpMsg, LPDWORD lpdwNumberOfBytesRecvd, LPWSAOVERLAPPED lpOverlapped, + // LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ) {...} + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_WSARECVMSG")] + public delegate int LPFN_WSARECVMSG(SOCKET s, ref WSAMSG lpMsg, out uint lpdwNumberOfBytesRecvd, ref WSAOVERLAPPED lpOverlapped, [In, Optional] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); + + /// + /// The RIO_NOTIFICATION_COMPLETION_TYPE enumeration specifies the type of completion queue notifications to use with the + /// RIONotify function when sending or receiving data using the Winsock registered I/O extensions. + /// + /// + /// + /// The RIO_NOTIFICATION_COMPLETION_TYPE enumeration is used with the Winsock registered I/O extensions to specify the type of I/O + /// completion to use with a RIO_CQ. An enumeration value is set in the RIO_NOTIFICATION_COMPLETION structure passed to the + /// RIOCreateCompletionQueue function when the RIO_CQ is created. + /// + /// + /// When creating a RIO_CQ, the RIO_NOTIFICATION_COMPLETION structure determines how the application will receive completion queue + /// notifications. If the RIO_NOTIFICATION_COMPLETION structure is provided when creating the completion queue, the application + /// may call the RIONotify function to request a completion queue notification. Normally this notification occurs when the completion + /// queue is not empty. This may happen immediately or when the next completion entry is inserted into the completion queue. Once a + /// completion queue notification is issued, the application must call RIONotify in order to receive another completion queue notification. + /// + /// Two options are available for completion queue notification. + /// + /// + /// Event handles. + /// + /// + /// I/O completion ports + /// + /// + /// + /// If the Type member of the RIO_NOTIFICATION_COMPLETION structure is set to RIO_EVENT_COMPLETION, an event handle is used + /// to signal completion queue notifications. An event handle is provided as the EventNotify.EventHandle member in the + /// RIO_NOTIFICATION_COMPLETION structure passed to the RIOCreateCompletionQueue function. + /// + /// + /// If the Type member of the RIO_NOTIFICATION_COMPLETION structure is set to RIO_IOCP_COMPLETION, an I/O completion port + /// is used to signal completion queue notifications. An I/O completion port handle is provided as the Iocp.IocpHandle member in + /// the RIO_NOTIFICATION_COMPLETION structure passed to the RIOCreateCompletionQueue function. The completion of the RIONotify + /// function for this RIO_CQ will queue an entry to the I/O completion port which can be retrieved using the GetQueuedCompletionStatus or + /// GetQueuedCompletionStatusEx function. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/ne-mswsock-rio_notification_completion_type typedef enum + // _RIO_NOTIFICATION_COMPLETION_TYPE { RIO_EVENT_COMPLETION = 1, RIO_IOCP_COMPLETION = 2 } RIO_NOTIFICATION_COMPLETION_TYPE, *PRIO_NOTIFICATION_COMPLETION_TYPE; + [PInvokeData("mswsock.h", MSDNShortId = "NE:mswsock._RIO_NOTIFICATION_COMPLETION_TYPE")] + public enum RIO_NOTIFICATION_COMPLETION_TYPE { - /// GUID value used by SIO_GET_EXTENSION_FUNCTION_POINTER to get the LPFN_WSARECVMSG (WSARecvMsg) extension function. - public static readonly Guid WSAID_WSARECVMSG = new("{0xf689d7c8,0x6f1f,0x436b,{0x8a,0x53,0xe5,0x4f,0xe3,0x51,0xc3,0x22}}"); + /// + /// Value: 1 + /// An event handle is used to signal completion queue notifications. + /// + /// An event handle is provided as the EventNotify.EventHandle member in the RIO_NOTIFICATION_COMPLETION structure passed to the + /// RIOCreateCompletionQueue function when the RIO_CQ is created. The completion of the RIONotify function for this RIO_CQ will + /// signal the event. The Event.NotifyReset member in the RIO_NOTIFICATION_COMPLETION structure passed to the + /// RIOCreateCompletionQueue function when the RIO_CQ is created indicates whether or not the event should be reset as part of a call + /// to the RIONotify function. + /// + /// + RIO_EVENT_COMPLETION = 1, + + /// + /// Value: 2 + /// An I/O completion port handle is used to signal completion queue notifications. + /// + /// An I/O completion port handle is provided as the Iocp.IocpHandle member in the RIO_NOTIFICATION_COMPLETION structure passed to + /// the RIOCreateCompletionQueue function when the RIO_CQ is created. The completion of the RIONotify function for this RIO_CQ will + /// queue an entry to the I/O completion port which can be retrieved using the GetQueuedCompletionStatus or + /// GetQueuedCompletionStatusEx function. The queued entry will have the returned lpCompletionKey parameter value set to the value + /// specified in the Iocp.CompletionKey member of the RIO_NOTIFICATION_COMPLETION and the returned lpOverlapped parameter value set + /// to the value specified in the Iocp.Overlapped member in RIO_NOTIFICATION_COMPLETION structure. The Iocp.Overlapped member in the + /// RIO_NOTIFICATION_COMPLETION will be a non-NULL value. + /// + /// + RIO_IOCP_COMPLETION, + } + + /// A set of flags used to customize processing of the TransmitPackets function. + [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_TRANSMITPACKETS")] + [Flags] + public enum TF : uint + { + /// + /// Starts a transport-level disconnect after all the file data has been queued for transmission. Applies only to connection-oriented + /// sockets. Specifying this flag for sockets that do not support disconnect semantics (such as datagram sockets) results in an error. + /// + TF_DISCONNECT = 0x01, + + /// + /// Prepares the socket handle to be reused. When the TransmitPackets function completes, the socket handle can be passed to the AcceptEx + /// function. Valid only when a connection-oriented socket and TF_DISCONNECT are specified. + /// + /// The socket level packet transmit is subject to the behavior of the underlying transport. For example, a TCP socket + /// may be subject to the TCP TIME_WAIT state, causing the TransmitPackets call to be delayed. + /// + /// + TF_REUSE_SOCKET = 0x02, /// /// - /// LPFN_WSARECVMSG is a function pointer type. You implement a matching WSARecvMsg callback function in your app. The - /// system uses your callback function to transmit to you in-memory data, or file data, over a connected socket. + /// Complete the TransmitFile request immediately, without pending. If this flag is specified and TransmitFile succeeds, then the + /// data has been accepted by the system but not necessarily acknowledged by the remote end. Do not use this setting with the + /// TF_DISCONNECT and TF_REUSE_SOCKET flags. /// + /// If the file being sent is not in the file system cache, the request pends. + /// + TF_WRITE_BEHIND = 0x04, + + /// + /// Directs Winsock to use the system's default thread to process long TransmitPackets requests. Long TransmitPackets requests are + /// defined as requests that require more than a single read from the file or a cache; the long request definition therefore depends on + /// the size of the file and the specified length of the send packet. + /// The system default thread can be adjusted using the following registry parameter as a REG_DWORD:HKEY_LOCAL_MACHINE\CurrentControlSet\Services\AFD\Parameters\TransmitWorker + /// + TF_USE_DEFAULT_WORKER = 0x00, + + /// + /// Directs Winsock to use system threads to process long TransmitPackets requests. Long TransmitPackets requests are defined as requests + /// that require more than a single read from the file or a cache; the long request definition therefore depends on the size of the file + /// and the specified length of the send packet. + /// + TF_USE_SYSTEM_THREAD = 0x10, + + /// + /// Directs Winsock to use kernel Asynchronous Procedure Calls (APCs) instead of worker threads to process long TransmitPackets requests. + /// Long TransmitPackets requests are defined as requests that require more than a single read from the file or a cache; the long request + /// definition therefore depends on the size of the file and the specified length of the send packet. See Remarks for more information. + /// + TF_USE_KERNEL_APC = 0x20, + } + + /// Flags used to describe the contents of the packet array element, and to customize TransmitPackets function processing. + [PInvokeData("mswsock.h", MSDNShortId = "NS:mswsock._TRANSMIT_PACKETS_ELEMENT")] + [Flags] + public enum TP_ELEMENT : uint + { + /// Specifies that data resides in memory. Mutually exclusive with TP_ELEMENT_FILE. + TP_ELEMENT_MEMORY = 1, + + /// Specifies that data resides in a file. Default setting for dwElFlags. Mutually exclusive with TP_ELEMENT_MEMORY. + TP_ELEMENT_FILE = 2, + + /// + /// Specifies that this element should not be combined with the next element in a single send request from the sockets layer to the + /// transport. This flag is used for granular control of the content of each message on a datagram or message-oriented socket. + /// + TP_ELEMENT_EOP = 4, + } + + /// + /// The AcceptEx function accepts a new connection, returns the local and remote address, and receives the first block of data + /// sent by the client application. + /// + /// + /// A descriptor identifying a socket that has already been called with the listen function. A server application waits for attempts to + /// connect on this socket. + /// + /// + /// A descriptor identifying a socket on which to accept an incoming connection. This socket must not be bound or connected. + /// + /// + /// A pointer to a buffer that receives the first block of data sent on a new connection, the local address of the server, and the remote + /// address of the client. The receive data is written to the first part of the buffer starting at offset zero, while the addresses are + /// written to the latter part of the buffer. This parameter must be specified. + /// + /// + /// The number of bytes in lpOutputBuffer that will be used for actual receive data at the beginning of the buffer. This size + /// should not include the size of the local address of the server, nor the remote address of the client; they are appended to the output + /// buffer. If dwReceiveDataLength is zero, accepting the connection will not result in a receive operation. Instead, + /// AcceptEx completes as soon as a connection arrives, without waiting for any data. + /// + /// + /// The number of bytes reserved for the local address information. This value must be at least 16 bytes more than the maximum address + /// length for the transport protocol in use. + /// + /// + /// The number of bytes reserved for the remote address information. This value must be at least 16 bytes more than the maximum address + /// length for the transport protocol in use. Cannot be zero. + /// + /// + /// A pointer to a DWORD that receives the count of bytes received. This parameter is set only if the operation completes + /// synchronously. If it returns ERROR_IO_PENDING and is completed later, then this DWORD is never set and you must obtain the + /// number of bytes read from the completion notification mechanism. + /// + /// + /// An OVERLAPPED structure that is used to process the request. This parameter must be specified; it cannot be NULL. + /// + /// + /// If no error occurs, the AcceptEx function completed successfully and a value of TRUE is returned. + /// + /// If the function fails, AcceptEx returns FALSE. The WSAGetLastError function can then be called to return extended error + /// information. If WSAGetLastError returns ERROR_IO_PENDING, then the operation was successfully initiated and is still in + /// progress. If the error is WSAECONNRESET, an incoming connection was indicated, but was subsequently terminated by the remote peer + /// prior to accepting the call. + /// + /// + /// + /// + /// The AcceptEx function combines several socket functions into a single API/kernel transition. The AcceptEx function, + /// when successful, performs three tasks: + /// + /// + /// + /// A new connection is accepted. + /// + /// + /// Both the local and remote addresses for the connection are returned. + /// + /// + /// The first block of data sent by the remote is received. + /// + /// + /// + /// Note The function pointer for the AcceptEx function must be obtained at run time by making a call to the WSAIoctl + /// function with the SIO_GET_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the WSAIoctl function + /// must contain WSAID_ACCEPTEX, a globally unique identifier (GUID) whose value identifies the AcceptEx extension + /// function. On success, the output returned by the WSAIoctl function contains a pointer to the AcceptEx function. The + /// WSAID_ACCEPTEX GUID is defined in the Mswsock.h header file. + /// + /// A program can make a connection to a socket more quickly using AcceptEx instead of the accept function. + /// A single output buffer receives the data, the local socket address (the server), and the remote socket address (the client). + /// + /// Using a single buffer improves performance. When using AcceptEx, the GetAcceptExSockaddrs function must be called to parse the + /// buffer into its three distinct parts (data, local socket address, and remote socket address). On Windows XP and later, once the + /// AcceptEx function completes and the SO_UPDATE_ACCEPT_CONTEXT option is set on the accepted socket, the local address + /// associated with the accepted socket can also be retrieved using the getsockname function. Likewise, the remote address associated + /// with the accepted socket can be retrieved using the getpeername function. + /// + /// + /// The buffer size for the local and remote address must be 16 bytes more than the size of the sockaddr structure for the transport + /// protocol in use because the addresses are written in an internal format. For example, the size of a sockaddr_in (the address + /// structure for TCP/IP) is 16 bytes. Therefore, a buffer size of at least 32 bytes must be specified for the local and remote addresses. + /// + /// + /// The AcceptEx function uses overlapped I/O, unlike the accept function. If your application uses AcceptEx, it can + /// service a large number of clients with a relatively small number of threads. As with all overlapped Windows functions, either Windows + /// events or completion ports can be used as a completion notification mechanism. + /// + /// + /// Another key difference between the AcceptEx function and the accept function is that AcceptEx requires the caller to + /// already have two sockets: + /// + /// + /// + /// One that specifies the socket on which to listen. + /// + /// + /// One that specifies the socket on which to accept the connection. + /// + /// + /// The sAcceptSocket parameter must be an open socket that is neither bound nor connected. + /// + /// The lpNumberOfBytesTransferred parameter of the GetQueuedCompletionStatus function or the GetOverlappedResult function + /// indicates the number of bytes received in the request. + /// + /// When this operation is successfully completed, sAcceptSocket can be passed, but to the following functions only: + /// + /// + /// Note If the TransmitFile function is called with both the TF_DISCONNECT and TF_REUSE_SOCKET flags, the specified socket has + /// been returned to a state in which it is neither bound nor connected. The socket handle can then be passed to the AcceptEx + /// function in the sAcceptSocket parameter, but the socket cannot be passed to the ConnectEx function. + /// + /// + /// When the AcceptEx function returns, the socket sAcceptSocket is in the default state for a connected socket. The socket + /// sAcceptSocket does not inherit the properties of the socket associated with sListenSocket parameter until + /// SO_UPDATE_ACCEPT_CONTEXT is set on the socket. Use the setsockopt function to set the SO_UPDATE_ACCEPT_CONTEXT option, specifying + /// sAcceptSocket as the socket handle and sListenSocket as the option value. + /// + /// For example: + /// + /// If a receive buffer is provided, the overlapped operation will not complete until a connection is accepted and data is read. Use the + /// getsockopt function with the SO_CONNECT_TIME option to check whether a connection has been accepted. If it has been accepted, you can + /// determine how long the connection has been established. The return value is the number of seconds that the socket has been connected. + /// If the socket is not connected, the getsockopt returns 0xFFFFFFFF. Applications that check whether the overlapped operation + /// has completed, in combination with the SO_CONNECT_TIME option, can determine that a connection has been accepted but no data has been + /// received. Scrutinizing a connection in this manner enables an application to determine whether connections that have been established + /// for a while have received no data. It is recommended such connections be terminated by closing the accepted socket, which forces the + /// AcceptEx function call to complete with an error. + /// + /// For example: + /// + /// Note All I/O initiated by a given thread is canceled when that thread exits. For overlapped sockets, pending asynchronous + /// operations can fail if the thread is closed before the operations complete. See ExitThread for more information. + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// Example Code + /// The following example uses the AcceptEx function using overlapped I/O and completion ports. + /// Notes for QoS + /// + /// The TransmitFile function allows the setting of two flags, TF_DISCONNECT or TF_REUSE_SOCKET, that return the socket to a + /// "disconnected, reusable" state after the file has been transmitted. These flags should not be used on a socket where quality of + /// service has been requested, since the service provider may immediately delete any quality of service associated with the socket + /// before the file transfer has completed. The best approach for a QoS-enabled socket is to simply call the closesocket function when + /// the file transfer has completed, rather than relying on these flags. + /// + /// Notes for ATM + /// + /// There are important issues associated with connection setup when using Asynchronous Transfer Mode (ATM) with Windows Sockets 2. + /// Please see the Remarks section in the accept function documentation for important ATM connection setup information. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-acceptex BOOL AcceptEx( [in] SOCKET sListenSocket, [in] SOCKET + // sAcceptSocket, [in] PVOID lpOutputBuffer, [in] DWORD dwReceiveDataLength, [in] DWORD dwLocalAddressLength, [in] DWORD + // dwRemoteAddressLength, [out] LPDWORD lpdwBytesReceived, [in] LPOVERLAPPED lpOverlapped ); + [PInvokeData("mswsock.h", MSDNShortId = "NF:mswsock.AcceptEx")] + [DllImport(Lib_Mswsock, SetLastError = true, ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool AcceptEx([In] SOCKET sListenSocket, [In] SOCKET sAcceptSocket, [In] IntPtr lpOutputBuffer, + uint dwReceiveDataLength, uint dwLocalAddressLength, uint dwRemoteAddressLength, out uint lpdwBytesReceived, + in NativeOverlapped lpOverlapped); + + /// + /// The GetAcceptExSockaddrs function parses the data obtained from a call to the AcceptEx function and passes the local and + /// remote addresses to a sockaddr structure. + /// + /// + /// A pointer to a buffer that receives the first block of data sent on a connection resulting from an AcceptEx call. Must be the same + /// lpOutputBuffer parameter that was passed to the AcceptEx function. + /// + /// + /// The number of bytes in the buffer used for receiving the first data. This value must be equal to the dwReceiveDataLength + /// parameter that was passed to the AcceptEx function. + /// + /// + /// The number of bytes reserved for the local address information. This value must be equal to the dwLocalAddressLength parameter + /// that was passed to the AcceptEx function. + /// + /// + /// The number of bytes reserved for the remote address information. This value must be equal to the dwRemoteAddressLength + /// parameter that was passed to the AcceptEx function. + /// + /// + /// A pointer to the sockaddr structure that receives the local address of the connection (the same information that would be returned by + /// the getsockname function). This parameter must be specified. + /// + /// The size, in bytes, of the local address. This parameter must be specified. + /// + /// A pointer to the sockaddr structure that receives the remote address of the connection (the same information that would be returned + /// by the getpeername function). This parameter must be specified. + /// + /// The size, in bytes, of the local address. This parameter must be specified. + /// None + /// + /// + /// The GetAcceptExSockaddrs function is used exclusively with the AcceptEx function to parse the first data that the socket + /// receives into local and remote addresses. The AcceptEx function returns local and remote address information in an internal + /// format. Application developers need to use the GetAcceptExSockaddrs function if there is a need for the sockaddr structures + /// containing the local or remote addresses. + /// + /// + /// Note The function pointer for the GetAcceptExSockaddrs function must be obtained at run time by making a call to the + /// WSAIoctl function with the SIO_GET_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the WSAIoctl + /// function must contain WSAID_GETACCEPTEXSOCKADDRS, a globally unique identifier (GUID) whose value identifies the + /// GetAcceptExSockaddrs extension function. On success, the output returned by the WSAIoctl function contains a pointer to + /// the GetAcceptExSockaddrs function. The WSAID_GETACCEPTEXSOCKADDRS GUID is defined in the Mswsock.h header file. + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-getacceptexsockaddrs void GetAcceptExSockaddrs( [in] PVOID + // lpOutputBuffer, [in] DWORD dwReceiveDataLength, [in] DWORD dwLocalAddressLength, [in] DWORD dwRemoteAddressLength, [out] sockaddr + // **LocalSockaddr, [out] LPINT LocalSockaddrLength, [out] sockaddr **RemoteSockaddr, [out] LPINT RemoteSockaddrLength ); + [PInvokeData("mswsock.h", MSDNShortId = "NF:mswsock.GetAcceptExSockaddrs")] + [DllImport(Lib_Mswsock, SetLastError = false, ExactSpelling = true)] + public static extern void GetAcceptExSockaddrs([In] IntPtr lpOutputBuffer, uint dwReceiveDataLength, uint dwLocalAddressLength, + uint dwRemoteAddressLength, out IntPtr LocalSockaddr, out int LocalSockaddrLength, out IntPtr RemoteSockaddr, + out int RemoteSockaddrLength); + + /// + /// The TransmitFile function transmits file data over a connected socket handle. This function uses the operating system's cache + /// manager to retrieve the file data, and provides high-performance file data transfer over sockets. + /// + /// + /// A handle to a connected socket. The TransmitFile function will transmit the file data over this socket. The socket specified + /// by the hSocket parameter must be a connection-oriented socket of type SOCK_STREAM, SOCK_SEQPACKET, or SOCK_RDM. + /// + /// + /// + /// A handle to the open file that the TransmitFile function transmits. Since the operating system reads the file data + /// sequentially, you can improve caching performance by opening the handle with FILE_FLAG_SEQUENTIAL_SCAN. + /// + /// + /// The hFile parameter is optional. If the hFile parameter is NULL, only data in the header and/or the tail buffer + /// is transmitted. Any additional action, such as socket disconnect or reuse, is performed as specified by the dwFlags parameter. + /// + /// + /// + /// + /// The number of bytes in the file to transmit. The TransmitFile function completes when it has sent the specified number of + /// bytes, or when an error occurs, whichever occurs first. + /// + /// Set this parameter to zero in order to transmit the entire file. + /// + /// + /// + /// The size, in bytes, of each block of data sent in each send operation. This parameter is used by Windows' sockets layer to determine + /// the block size for send operations. To select the default send size, set this parameter to zero. + /// + /// The nNumberOfBytesPerSend parameter is useful for protocols that have limitations on the size of individual send requests. + /// + /// + /// + /// A pointer to an OVERLAPPED structure. If the socket handle has been opened as overlapped, specify this parameter in order to achieve + /// an overlapped (asynchronous) I/O operation. By default, socket handles are opened as overlapped. + /// + /// + /// You can use the lpOverlapped parameter to specify a 64-bit offset within the file at which to start the file data transfer by + /// setting the Offset and OffsetHigh member of the OVERLAPPED structure. If lpOverlapped is a NULL pointer, + /// the transmission of data always starts at the current byte offset in the file. + /// + /// + /// When the lpOverlapped is not NULL, the overlapped I/O might not finish before TransmitFile returns. In that + /// case, the TransmitFile function returns FALSE, and WSAGetLastError returns ERROR_IO_PENDING or WSA_IO_PENDING. This + /// enables the caller to continue processing while the file transmission operation completes. Windows will set the event specified by + /// the hEvent member of the OVERLAPPED structure, or the socket specified by hSocket, to the signaled state upon + /// completion of the data transmission request. + /// + /// + /// + /// A pointer to a TRANSMIT_FILE_BUFFERS data structure that contains pointers to data to send before and after the file data is sent. + /// This parameter should be set to a NULL pointer if you want to transmit only the file data. + /// + /// + /// + /// A set of flags used to modify the behavior of the TransmitFile function call. The dwFlags parameter can contain a + /// combination of the following options defined in the Mswsock.h header file: + /// + /// + /// + /// Flag + /// Meaning + /// + /// + /// TF_DISCONNECT + /// Start a transport-level disconnect after all the file data has been queued for transmission. + /// + /// + /// TF_REUSE_SOCKET + /// + /// Prepare the socket handle to be reused. This flag is valid only if TF_DISCONNECT is also specified. When the + /// TransmitFile request completes, the socket handle can be passed to the function call previously used to establish the + /// connection, such as AcceptEx or ConnectEx. Such reuse is mutually exclusive; for example, if the AcceptEx function was called + /// for the socket, reuse is allowed only for subsequent calls to the AcceptEx function, and not allowed for a subsequent call to ConnectEx. + /// + /// + /// + /// TF_USE_DEFAULT_WORKER + /// + /// Directs the Windows Sockets service provider to use the system's default thread to process long TransmitFile requests. The + /// system default thread can be adjusted using the following registry parameter as a REG_DWORD: HKEY_LOCAL_MACHINE\ + /// CurrentControlSet\ Services\ AFD\ Parameters\ TransmitWorker + /// + /// + /// + /// TF_USE_SYSTEM_THREAD + /// Directs the Windows Sockets service provider to use system threads to process long TransmitFile requests. + /// + /// + /// TF_USE_KERNEL_APC + /// + /// Directs the driver to use kernel asynchronous procedure calls (APCs) instead of worker threads to process long TransmitFile + /// requests. Long TransmitFile requests are defined as requests that require more than a single read from the file or a cache; + /// the request therefore depends on the size of the file and the specified length of the send packet. Use of TF_USE_KERNEL_APC can + /// deliver significant performance benefits. It is possible (though unlikely), however, that the thread in which context + /// TransmitFile is initiated is being used for heavy computations; this situation may prevent APCs from launching. Note that the + /// Winsock kernel mode driver uses normal kernel APCs, which launch whenever a thread is in a wait state, which differs from user-mode + /// APCs, which launch whenever a thread is in an alertable wait state initiated in user mode). + /// + /// + /// + /// TF_WRITE_BEHIND + /// + /// Complete the TransmitFile request immediately, without pending. If this flag is specified and TransmitFile succeeds, + /// then the data has been accepted by the system but not necessarily acknowledged by the remote end. Do not use this setting with the + /// TF_DISCONNECT and TF_REUSE_SOCKET flags. + /// + /// + /// + /// + /// + /// + /// If the TransmitFile function succeeds, the return value is TRUE. Otherwise, the return value is FALSE. To get + /// extended error information, call WSAGetLastError. An error code of WSA_IO_PENDING or ERROR_IO_PENDING indicates that the overlapped + /// operation has been successfully initiated and that completion will be indicated at a later time. Any other error code indicates that + /// the overlapped operation was not successfully initiated and no completion indication will occur. Applications should handle either + /// ERROR_IO_PENDING or WSA_IO_PENDING in this case. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// WSAECONNABORTED + /// + /// An established connection was aborted by the software in your host machine. This error is returned if the virtual circuit was + /// terminated due to a time-out or other failure. + /// + /// + /// + /// WSAECONNRESET + /// + /// An existing connection was forcibly closed by the remote host. This error is returned for a stream socket when the virtual circuit + /// was reset by the remote side. The application should close the socket as it is no longer usable. + /// + /// + /// + /// WSAEFAULT + /// + /// The system detected an invalid pointer address in attempting to use a pointer argument in a call. This error is returned if the + /// lpTransmitBuffers or lpOverlapped parameter is not totally contained in a valid part of the user address space. + /// + /// + /// + /// WSAEINVAL + /// + /// An invalid argument was supplied. This error is returned if the hSocket parameter specified a socket of type SOCK_DGRAM + /// or SOCK_RAW. This error is returned if the dwFlags parameter has the TF_REUSE_SOCKET flag set, but the + /// TF_DISCONNECT flag was not set. This error is also returned if the offset specified in the OVERLAPPED structure pointed to by + /// the lpOverlapped is not within the file. This error is also returned if the nNumberOfBytesToWrite parameter is set to a + /// value greater than 2,147,483,646, the maximum value for a 32-bit integer minus 1. + /// + /// + /// + /// WSAENETDOWN + /// A socket operation encountered a dead network.This error is returned if the network subsystem has failed. + /// + /// + /// WSAENETRESET + /// The connection has been broken due to keep-alive activity detecting a failure while the operation was in progress. + /// + /// + /// WSAENOBUFS + /// + /// An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full. This + /// error is also returned if the Windows Sockets provider reports a buffer deadlock. + /// + /// + /// + /// WSAENOTCONN + /// A request to send or receive data was disallowed because the socket is not connected. + /// + /// + /// WSAENOTSOCK + /// + /// An operation was attempted on something that is not a socket. This error is returned if the hSocket parameter is not a socket. + /// + /// + /// + /// WSAESHUTDOWN + /// + /// A request to send or receive data was disallowed because the socket had already been shut down in that direction with a previous + /// shutdown call. This error is returned if the socket has been shut down for sending. It is not possible to call TransmitFile on a + /// socket after the shutdown function has been called on the socket with the how parameter set to SD_SEND or SD_BOTH. + /// + /// + /// + /// WSANOTINITIALISED + /// + /// Either the application has not called the WSAStartup function, or WSAStartup failed. A successful WSAStartup call must + /// occur before using the TransmitFile function. + /// + /// + /// + /// WSA_IO_PENDING + /// + /// An overlapped I/O operation is in progress. This value is returned if an overlapped I/O operation was successfully initiated and + /// indicates that completion will be indicated at a later time. + /// + /// + /// + /// WSA_OPERATION_ABORTED + /// + /// The I/O operation has been aborted because of either a thread exit or an application request. This error is returned if the + /// overlapped operation has been canceled due to the closure of the socket, the execution of the "SIO_FLUSH" command in WSAIoctl, or the + /// thread that initiated the overlapped request exited before the operation completed. + /// + /// + /// + /// + /// + /// + /// The TransmitFile function uses the operating system's cache manager to retrieve the file data, and provide high-performance + /// file data transfer over sockets. + /// + /// + /// The TransmitFile function only supports connection-oriented sockets of type SOCK_STREAM, SOCK_SEQPACKET, and + /// SOCK_RDM. Sockets of type SOCK_DGRAM and SOCK_RAW are not supported. The TransmitPackets function can be used + /// with sockets of type SOCK_DGRAM. + /// + /// + /// The maximum number of bytes that can be transmitted using a single call to the TransmitFile function is 2,147,483,646, the + /// maximum value for a 32-bit integer minus 1. The maximum number of bytes to send in a single call includes any data sent before or + /// after the file data pointed to by the lpTransmitBuffers parameter plus the value specified in the nNumberOfBytesToWrite + /// parameter for the length of file data to send. If an application needs to transmit a file larger than 2,147,483,646 bytes, then + /// multiple calls to the TransmitFile function can be used with each call transferring no more than 2,147,483,646 bytes. Setting + /// the nNumberOfBytesToWrite parameter to zero for a file larger than 2,147,483,646 bytes will also fail since in this case the + /// TransmitFile function will use the size of the file as the value for the number of bytes to transmit. + /// + /// + /// Note The function pointer for the TransmitFile function must be obtained at run time by making a call to the WSAIoctl + /// function with the SIO_GET_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the WSAIoctl function + /// must contain WSAID_TRANSMITFILE, a globally unique identifier (GUID) whose value identifies the TransmitFile extension + /// function. On success, the output returned by the WSAIoctl function contains a pointer to the TransmitFile function. The + /// WSAID_TRANSMITFILE GUID is defined in the Mswsock.h header file. + /// + /// + /// NoteTransmitFile is not functional on transports that perform their own buffering. Transports with the + /// TDI_SERVICE_INTERNAL_BUFFERING flag set, such as ADSP, perform their own buffering. Because TransmitFile achieves its + /// performance gains by sending data directly from the file cache. Transports that run out of buffer space on a particular connection + /// are not handled by TransmitFile, and as a result of running out of buffer space on the connection, TransmitFile returns STATUS_DEVICE_NOT_READY. + /// + /// + /// The TransmitFile function was primarily added to Winsock for use by high-performance server applications (web and ftp servers, + /// for example). + /// + /// + /// Workstation and client versions of Windows optimize the TransmitFile function for minimum memory and resource utilization by + /// limiting the number of concurrent TransmitFile operations allowed on the system to a maximum of two. On Windows Vista, Windows + /// XP, Windows 2000 Professional, and Windows NT Workstation 3.51 and later only two outstanding TransmitFile requests are + /// handled simultaneously; the third request will wait until one of the previous requests is completed. + /// + /// + /// Server versions of Windows optimize the TransmitFile function for high performance. On server versions, there are no default + /// limits placed on the number of concurrent TransmitFile operations allowed on the system. Expect better performance results + /// when using TransmitFile on server versions of Windows. On server versions of Windows, it is possible to set a limit on the + /// maximum number of concurrent TransmitFile operations by creating a registry entry and setting a value for the following REG_DWORD: + /// + /// HKEY_LOCAL_MACHINE\ CurrentControlSet\ Services\ AFD\ Parameters\ MaxActiveTransmitFileCount + /// + /// If the TransmitFile function is called with TCP socket (protocol of IPPROTO_TCP) with both the TF_DISCONNECT and + /// TF_REUSE_SOCKET flags specified, the call will not complete until the two following conditions are met. + /// + /// + /// + /// All pending receive data sent by remote side (received prior to a FIN from the remote side) on the TCP socket has been read. + /// + /// + /// The remote side has closed the connection (completed the graceful TCP connection closure). + /// + /// + /// + /// If the TransmitFile function is called with the lpOverlapped parameter set to NULL, the operation is executed as + /// synchronous I/O. The function will not complete until the file has been sent. + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// Notes for QoS + /// + /// The TransmitFile function allows the setting of two flags, TF_DISCONNECT or TF_REUSE_SOCKET, that return the socket to a + /// "disconnected, reusable" state after the file has been transmitted. These flags should not be used on a socket where quality of + /// service has been requested, since the service provider may immediately delete any quality of service associated with the socket + /// before the file transfer has completed. The best approach for a QoS-enabled socket is to simply call the closesocket function when + /// the file transfer has completed, rather than relying on these flags. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-transmitfile BOOL TransmitFile( SOCKET hSocket, HANDLE hFile, + // DWORD nNumberOfBytesToWrite, DWORD nNumberOfBytesPerSend, LPOVERLAPPED lpOverlapped, LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers, DWORD + // dwReserved ); + [PInvokeData("mswsock.h", MSDNShortId = "NF:mswsock.TransmitFile")] + [DllImport(Lib_Mswsock, SetLastError = true, ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool TransmitFile(SOCKET hSocket, HFILE hFile, uint nNumberOfBytesToWrite, + uint nNumberOfBytesPerSend, in NativeOverlapped lpOverlapped, in TRANSMIT_FILE_BUFFERS lpTransmitBuffers, + uint dwReserved = 0); + + /// + /// The TransmitFile function transmits file data over a connected socket handle. This function uses the operating system's cache + /// manager to retrieve the file data, and provides high-performance file data transfer over sockets. + /// + /// + /// A handle to a connected socket. The TransmitFile function will transmit the file data over this socket. The socket specified + /// by the hSocket parameter must be a connection-oriented socket of type SOCK_STREAM, SOCK_SEQPACKET, or SOCK_RDM. + /// + /// + /// + /// A handle to the open file that the TransmitFile function transmits. Since the operating system reads the file data + /// sequentially, you can improve caching performance by opening the handle with FILE_FLAG_SEQUENTIAL_SCAN. + /// + /// + /// The hFile parameter is optional. If the hFile parameter is NULL, only data in the header and/or the tail buffer + /// is transmitted. Any additional action, such as socket disconnect or reuse, is performed as specified by the dwFlags parameter. + /// + /// + /// + /// + /// The number of bytes in the file to transmit. The TransmitFile function completes when it has sent the specified number of + /// bytes, or when an error occurs, whichever occurs first. + /// + /// Set this parameter to zero in order to transmit the entire file. + /// + /// + /// + /// The size, in bytes, of each block of data sent in each send operation. This parameter is used by Windows' sockets layer to determine + /// the block size for send operations. To select the default send size, set this parameter to zero. + /// + /// The nNumberOfBytesPerSend parameter is useful for protocols that have limitations on the size of individual send requests. + /// + /// + /// + /// A pointer to an OVERLAPPED structure. If the socket handle has been opened as overlapped, specify this parameter in order to achieve + /// an overlapped (asynchronous) I/O operation. By default, socket handles are opened as overlapped. + /// + /// + /// You can use the lpOverlapped parameter to specify a 64-bit offset within the file at which to start the file data transfer by + /// setting the Offset and OffsetHigh member of the OVERLAPPED structure. If lpOverlapped is a NULL pointer, + /// the transmission of data always starts at the current byte offset in the file. + /// + /// + /// When the lpOverlapped is not NULL, the overlapped I/O might not finish before TransmitFile returns. In that + /// case, the TransmitFile function returns FALSE, and WSAGetLastError returns ERROR_IO_PENDING or WSA_IO_PENDING. This + /// enables the caller to continue processing while the file transmission operation completes. Windows will set the event specified by + /// the hEvent member of the OVERLAPPED structure, or the socket specified by hSocket, to the signaled state upon + /// completion of the data transmission request. + /// + /// + /// + /// A pointer to a TRANSMIT_FILE_BUFFERS data structure that contains pointers to data to send before and after the file data is sent. + /// This parameter should be set to a NULL pointer if you want to transmit only the file data. + /// + /// + /// + /// A set of flags used to modify the behavior of the TransmitFile function call. The dwFlags parameter can contain a + /// combination of the following options defined in the Mswsock.h header file: + /// + /// + /// + /// Flag + /// Meaning + /// + /// + /// TF_DISCONNECT + /// Start a transport-level disconnect after all the file data has been queued for transmission. + /// + /// + /// TF_REUSE_SOCKET + /// + /// Prepare the socket handle to be reused. This flag is valid only if TF_DISCONNECT is also specified. When the + /// TransmitFile request completes, the socket handle can be passed to the function call previously used to establish the + /// connection, such as AcceptEx or ConnectEx. Such reuse is mutually exclusive; for example, if the AcceptEx function was called + /// for the socket, reuse is allowed only for subsequent calls to the AcceptEx function, and not allowed for a subsequent call to ConnectEx. + /// + /// + /// + /// TF_USE_DEFAULT_WORKER + /// + /// Directs the Windows Sockets service provider to use the system's default thread to process long TransmitFile requests. The + /// system default thread can be adjusted using the following registry parameter as a REG_DWORD: HKEY_LOCAL_MACHINE\ + /// CurrentControlSet\ Services\ AFD\ Parameters\ TransmitWorker + /// + /// + /// + /// TF_USE_SYSTEM_THREAD + /// Directs the Windows Sockets service provider to use system threads to process long TransmitFile requests. + /// + /// + /// TF_USE_KERNEL_APC + /// + /// Directs the driver to use kernel asynchronous procedure calls (APCs) instead of worker threads to process long TransmitFile + /// requests. Long TransmitFile requests are defined as requests that require more than a single read from the file or a cache; + /// the request therefore depends on the size of the file and the specified length of the send packet. Use of TF_USE_KERNEL_APC can + /// deliver significant performance benefits. It is possible (though unlikely), however, that the thread in which context + /// TransmitFile is initiated is being used for heavy computations; this situation may prevent APCs from launching. Note that the + /// Winsock kernel mode driver uses normal kernel APCs, which launch whenever a thread is in a wait state, which differs from user-mode + /// APCs, which launch whenever a thread is in an alertable wait state initiated in user mode). + /// + /// + /// + /// TF_WRITE_BEHIND + /// + /// Complete the TransmitFile request immediately, without pending. If this flag is specified and TransmitFile succeeds, + /// then the data has been accepted by the system but not necessarily acknowledged by the remote end. Do not use this setting with the + /// TF_DISCONNECT and TF_REUSE_SOCKET flags. + /// + /// + /// + /// + /// + /// + /// If the TransmitFile function succeeds, the return value is TRUE. Otherwise, the return value is FALSE. To get + /// extended error information, call WSAGetLastError. An error code of WSA_IO_PENDING or ERROR_IO_PENDING indicates that the overlapped + /// operation has been successfully initiated and that completion will be indicated at a later time. Any other error code indicates that + /// the overlapped operation was not successfully initiated and no completion indication will occur. Applications should handle either + /// ERROR_IO_PENDING or WSA_IO_PENDING in this case. + /// + /// + /// + /// Return code + /// Description + /// + /// + /// WSAECONNABORTED + /// + /// An established connection was aborted by the software in your host machine. This error is returned if the virtual circuit was + /// terminated due to a time-out or other failure. + /// + /// + /// + /// WSAECONNRESET + /// + /// An existing connection was forcibly closed by the remote host. This error is returned for a stream socket when the virtual circuit + /// was reset by the remote side. The application should close the socket as it is no longer usable. + /// + /// + /// + /// WSAEFAULT + /// + /// The system detected an invalid pointer address in attempting to use a pointer argument in a call. This error is returned if the + /// lpTransmitBuffers or lpOverlapped parameter is not totally contained in a valid part of the user address space. + /// + /// + /// + /// WSAEINVAL + /// + /// An invalid argument was supplied. This error is returned if the hSocket parameter specified a socket of type SOCK_DGRAM + /// or SOCK_RAW. This error is returned if the dwFlags parameter has the TF_REUSE_SOCKET flag set, but the + /// TF_DISCONNECT flag was not set. This error is also returned if the offset specified in the OVERLAPPED structure pointed to by + /// the lpOverlapped is not within the file. This error is also returned if the nNumberOfBytesToWrite parameter is set to a + /// value greater than 2,147,483,646, the maximum value for a 32-bit integer minus 1. + /// + /// + /// + /// WSAENETDOWN + /// A socket operation encountered a dead network.This error is returned if the network subsystem has failed. + /// + /// + /// WSAENETRESET + /// The connection has been broken due to keep-alive activity detecting a failure while the operation was in progress. + /// + /// + /// WSAENOBUFS + /// + /// An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full. This + /// error is also returned if the Windows Sockets provider reports a buffer deadlock. + /// + /// + /// + /// WSAENOTCONN + /// A request to send or receive data was disallowed because the socket is not connected. + /// + /// + /// WSAENOTSOCK + /// + /// An operation was attempted on something that is not a socket. This error is returned if the hSocket parameter is not a socket. + /// + /// + /// + /// WSAESHUTDOWN + /// + /// A request to send or receive data was disallowed because the socket had already been shut down in that direction with a previous + /// shutdown call. This error is returned if the socket has been shut down for sending. It is not possible to call TransmitFile on a + /// socket after the shutdown function has been called on the socket with the how parameter set to SD_SEND or SD_BOTH. + /// + /// + /// + /// WSANOTINITIALISED + /// + /// Either the application has not called the WSAStartup function, or WSAStartup failed. A successful WSAStartup call must + /// occur before using the TransmitFile function. + /// + /// + /// + /// WSA_IO_PENDING + /// + /// An overlapped I/O operation is in progress. This value is returned if an overlapped I/O operation was successfully initiated and + /// indicates that completion will be indicated at a later time. + /// + /// + /// + /// WSA_OPERATION_ABORTED + /// + /// The I/O operation has been aborted because of either a thread exit or an application request. This error is returned if the + /// overlapped operation has been canceled due to the closure of the socket, the execution of the "SIO_FLUSH" command in WSAIoctl, or the + /// thread that initiated the overlapped request exited before the operation completed. + /// + /// + /// + /// + /// + /// + /// The TransmitFile function uses the operating system's cache manager to retrieve the file data, and provide high-performance + /// file data transfer over sockets. + /// + /// + /// The TransmitFile function only supports connection-oriented sockets of type SOCK_STREAM, SOCK_SEQPACKET, and + /// SOCK_RDM. Sockets of type SOCK_DGRAM and SOCK_RAW are not supported. The TransmitPackets function can be used + /// with sockets of type SOCK_DGRAM. + /// + /// + /// The maximum number of bytes that can be transmitted using a single call to the TransmitFile function is 2,147,483,646, the + /// maximum value for a 32-bit integer minus 1. The maximum number of bytes to send in a single call includes any data sent before or + /// after the file data pointed to by the lpTransmitBuffers parameter plus the value specified in the nNumberOfBytesToWrite + /// parameter for the length of file data to send. If an application needs to transmit a file larger than 2,147,483,646 bytes, then + /// multiple calls to the TransmitFile function can be used with each call transferring no more than 2,147,483,646 bytes. Setting + /// the nNumberOfBytesToWrite parameter to zero for a file larger than 2,147,483,646 bytes will also fail since in this case the + /// TransmitFile function will use the size of the file as the value for the number of bytes to transmit. + /// + /// + /// Note The function pointer for the TransmitFile function must be obtained at run time by making a call to the WSAIoctl + /// function with the SIO_GET_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the WSAIoctl function + /// must contain WSAID_TRANSMITFILE, a globally unique identifier (GUID) whose value identifies the TransmitFile extension + /// function. On success, the output returned by the WSAIoctl function contains a pointer to the TransmitFile function. The + /// WSAID_TRANSMITFILE GUID is defined in the Mswsock.h header file. + /// + /// + /// NoteTransmitFile is not functional on transports that perform their own buffering. Transports with the + /// TDI_SERVICE_INTERNAL_BUFFERING flag set, such as ADSP, perform their own buffering. Because TransmitFile achieves its + /// performance gains by sending data directly from the file cache. Transports that run out of buffer space on a particular connection + /// are not handled by TransmitFile, and as a result of running out of buffer space on the connection, TransmitFile returns STATUS_DEVICE_NOT_READY. + /// + /// + /// The TransmitFile function was primarily added to Winsock for use by high-performance server applications (web and ftp servers, + /// for example). + /// + /// + /// Workstation and client versions of Windows optimize the TransmitFile function for minimum memory and resource utilization by + /// limiting the number of concurrent TransmitFile operations allowed on the system to a maximum of two. On Windows Vista, Windows + /// XP, Windows 2000 Professional, and Windows NT Workstation 3.51 and later only two outstanding TransmitFile requests are + /// handled simultaneously; the third request will wait until one of the previous requests is completed. + /// + /// + /// Server versions of Windows optimize the TransmitFile function for high performance. On server versions, there are no default + /// limits placed on the number of concurrent TransmitFile operations allowed on the system. Expect better performance results + /// when using TransmitFile on server versions of Windows. On server versions of Windows, it is possible to set a limit on the + /// maximum number of concurrent TransmitFile operations by creating a registry entry and setting a value for the following REG_DWORD: + /// + /// HKEY_LOCAL_MACHINE\ CurrentControlSet\ Services\ AFD\ Parameters\ MaxActiveTransmitFileCount + /// + /// If the TransmitFile function is called with TCP socket (protocol of IPPROTO_TCP) with both the TF_DISCONNECT and + /// TF_REUSE_SOCKET flags specified, the call will not complete until the two following conditions are met. + /// + /// + /// + /// All pending receive data sent by remote side (received prior to a FIN from the remote side) on the TCP socket has been read. + /// + /// + /// The remote side has closed the connection (completed the graceful TCP connection closure). + /// + /// + /// + /// If the TransmitFile function is called with the lpOverlapped parameter set to NULL, the operation is executed as + /// synchronous I/O. The function will not complete until the file has been sent. + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// Notes for QoS + /// + /// The TransmitFile function allows the setting of two flags, TF_DISCONNECT or TF_REUSE_SOCKET, that return the socket to a + /// "disconnected, reusable" state after the file has been transmitted. These flags should not be used on a socket where quality of + /// service has been requested, since the service provider may immediately delete any quality of service associated with the socket + /// before the file transfer has completed. The best approach for a QoS-enabled socket is to simply call the closesocket function when + /// the file transfer has completed, rather than relying on these flags. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-transmitfile BOOL TransmitFile( SOCKET hSocket, HANDLE hFile, + // DWORD nNumberOfBytesToWrite, DWORD nNumberOfBytesPerSend, LPOVERLAPPED lpOverlapped, LPTRANSMIT_FILE_BUFFERS lpTransmitBuffers, DWORD + // dwReserved ); + [PInvokeData("mswsock.h", MSDNShortId = "NF:mswsock.TransmitFile")] + [DllImport(Lib_Mswsock, SetLastError = true, ExactSpelling = true)] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool TransmitFile(SOCKET hSocket, HFILE hFile, uint nNumberOfBytesToWrite, + uint nNumberOfBytesPerSend, [In, Optional] IntPtr lpOverlapped, [In, Optional] IntPtr lpTransmitBuffers, + uint dwReserved = 0); + + /// + /// + /// The WSARecvEx function receives data from a connected socket or a bound connectionless socket. The WSARecvEx function + /// is similar to the recv function, except that the flags parameter is used only to return information. When a partial message is + /// received while using datagram protocol, the MSG_PARTIAL bit is set in the flags parameter on return from the function. + /// + /// Note The WSARecvEx function is a Microsoft-specific extension to the Windows Sockets specification. + /// + /// A descriptor that identifies a connected socket. + /// A pointer to the buffer to receive the incoming data. + /// The length, in bytes, of the buffer pointed to by the buf parameter. + /// An indicator specifying whether the message is fully or partially received for datagram sockets. + /// + /// + /// If no error occurs, WSARecvEx returns the number of bytes received. If the connection has been closed, it returns zero. + /// Additionally, if a partial message was received, the MSG_PARTIAL bit is set in the flags parameter. If a complete message was + /// received, MSG_PARTIAL is not set in flags + /// + /// Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError. + /// + /// Important For a stream oriented-transport protocol, MSG_PARTIAL is never set on return from WSARecvEx. This function + /// behaves identically to the recv function for stream-transport protocols. + /// + /// + /// + /// Error code + /// Meaning + /// + /// + /// WSAECONNABORTED + /// + /// The virtual circuit was terminated due to a time-out or other failure. The application should close the socket as it is no longer usable. + /// + /// + /// + /// WSAECONNRESET + /// + /// The virtual circuit was reset by the remote side executing a hard or abortive close. The application should close the socket as it is + /// no longer usable. On a UPD-datagram socket this error would indicate that a previous send operation resulted in an ICMP "Port + /// Unreachable" message. + /// + /// + /// + /// WSAEFAULT + /// The buf parameter is not completely contained in a valid part of the user address space. + /// + /// + /// WSAEINPROGRESS + /// A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function. + /// + /// + /// WSAEINTR + /// The (blocking) call was canceled by the WSACancelBlockingCall call. + /// + /// + /// WSAEINVAL + /// + /// The socket has not been bound with bind, or an unknown flag was specified, or MSG_OOB was specified for a socket with SO_OOBINLINE + /// enabled or (for byte stream sockets only) len was zero or negative. + /// + /// + /// + /// WSAENETDOWN + /// The network subsystem has failed. + /// + /// + /// WSAENETRESET + /// + /// For a connection-oriented socket, this error indicates that the connection has been broken due to keep-alive activity that + /// detected a failure while the operation was in progress. For a datagram socket, this error indicates that the time to live has expired. + /// + /// + /// + /// WSAENOTCONN + /// The socket is not connected. + /// + /// + /// WSAENOTSOCK + /// The descriptor is not a socket. + /// + /// + /// WSAEOPNOTSUPP + /// + /// MSG_OOB was specified, but the socket is not stream-style such as type SOCK_STREAM, OOB data is not supported in the communication + /// domain associated with this socket, or the socket is unidirectional and supports only send operations. + /// + /// + /// + /// WSAESHUTDOWN + /// + /// The socket has been shut down; it is not possible to use WSARecvEx on a socket after shutdown has been invoked with how set to + /// SD_RECEIVE or SD_BOTH. + /// + /// + /// + /// WSAETIMEDOUT + /// The connection has been dropped because of a network failure or because the peer system failed to respond. + /// + /// + /// WSAEWOULDBLOCK + /// The socket is marked as nonblocking and the receive operation would block. + /// + /// + /// WSANOTINITIALISED + /// A successful WSAStartup call must occur before using this function. + /// + /// + /// + /// + /// + /// The WSARecvEx function that is part of the Microsoft implementation of Windows Sockets 2 is similar to the more common recv + /// function except that the flags parameter is used for a single specific purpose. The flags parameter is used to indicate + /// whether a partial or complete message is received when a message-oriented protocol is being used. + /// + /// + /// The value pointed to by the flags parameter is ignored on input. So no flags can be passed to the WSARecvEx function to + /// modify its behavior. The value pointed to by the flags parameter is set on output. This differs from the recv and WSARecv + /// functions where the value pointed to by the flags parameter on input can modify the behavior of the function. + /// + /// The WSARecvEx and recv functions behave identically for stream-oriented protocols. + /// The flags parameter accommodates two common situations in which a partial message will be received: + /// + /// + /// When the application's data buffer size is smaller than the message size and the message coincidentally arrives in two pieces. + /// + /// + /// When the message is rather large and must arrive in several pieces. + /// + /// + /// + /// The MSG_PARTIAL bit is set in the value pointed to by the flags parameter on return from WSARecvEx when a partial + /// message was received. If a complete message was received, MSG_PARTIAL is not set in the value pointed to by the flags parameter. + /// + /// + /// The recv function is different from the WSARecvEx and WSARecv functions in that the recv function always receives a + /// single message for each call for message-oriented transport protocols. The recv function also does not have a means to + /// indicate to the application that the data received is only a partial message. An application must build its own protocol for checking + /// whether a message is partial or complete by checking for the error code WSAEMSGSIZE after each call to recv. When the + /// application buffer is smaller than the data being sent, as much of the message as will fit is copied into the user's buffer and + /// recv returns with the error code WSAEMSGSIZE. A subsequent call to recv will get the next part of the message. + /// + /// + /// Applications written for message-oriented transport protocols should be coded for this possibility if message sizing is not + /// guaranteed by the application's data transfer protocol. An application can use recv and manage the protocol itself. Alternatively, an + /// application can use WSARecvEx and check that the MSG_PARTIAL bit is set in the flags parameter. + /// + /// + /// The WSARecvEx function provides the developer with a more effective way of checking whether a message received is partial or + /// complete when a very large message arrives incrementally. For example, if an application sends a one-megabyte message, the transport + /// protocol must break up the message in order to send it over the physical network. It is theoretically possible for the transport + /// protocol on the receiving side to buffer all the data in the message, but this would be quite expensive in terms of resources. + /// Instead, WSARecvEx can be used, minimizing overhead and eliminating the need for an application-based protocol. + /// + /// + /// Note All I/O initiated by a given thread is canceled when that thread exits. For overlapped sockets, pending asynchronous + /// operations can fail if the thread is closed before the operations complete. See the ExitThread function for more information. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/nf-mswsock-wsarecvex int WSARecvEx( [in] SOCKET s, [out] char *buf, [in] + // int len, [in, out] int *flags ); + [PInvokeData("mswsock.h", MSDNShortId = "NF:mswsock.WSARecvEx")] + [DllImport(Lib_Mswsock, SetLastError = true, ExactSpelling = true)] + public static extern int WSARecvEx([In] SOCKET s, [Out] IntPtr buf, int len, ref int flags); + + /// + /// The RIO_EXTENSION_FUNCTION_TABLE structure contains information on the functions that implement the Winsock registered I/O extensions. + /// + /// + /// + /// The RIO_EXTENSION_FUNCTION_TABLE structure contains information on the functions that implement the Winsock registered I/O extensions. + /// + /// + /// The function pointers for the Winsock registered I/O extension functions must be obtained at run time by making a call to the + /// WSAIoctl function with the SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the + /// WSAIoctl function must contain WSAID_MULTIPLE_RIO, a globally unique identifier (GUID) whose value identifies the + /// Winsock registered I/O extension functions. On success, the output returned by the WSAIoctl function contains a pointer to the + /// RIO_EXTENSION_FUNCTION_TABLE structure that contains pointers to the Winsock registered I/O extension functions. The + /// SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER IOCTL is defined in the Ws2def.h header file.The WSAID_MULTIPLE_RIO + /// GUID is defined in the Mswsock.h header file. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/ns-mswsock-rio_extension_function_table typedef struct + // _RIO_EXTENSION_FUNCTION_TABLE { DWORD cbSize; LPFN_RIORECEIVE RIOReceive; LPFN_RIORECEIVEEX RIOReceiveEx; LPFN_RIOSEND RIOSend; + // LPFN_RIOSENDEX RIOSendEx; LPFN_RIOCLOSECOMPLETIONQUEUE RIOCloseCompletionQueue; LPFN_RIOCREATECOMPLETIONQUEUE + // RIOCreateCompletionQueue; LPFN_RIOCREATEREQUESTQUEUE RIOCreateRequestQueue; LPFN_RIODEQUEUECOMPLETION RIODequeueCompletion; + // LPFN_RIODEREGISTERBUFFER RIODeregisterBuffer; LPFN_RIONOTIFY RIONotify; LPFN_RIOREGISTERBUFFER RIORegisterBuffer; + // LPFN_RIORESIZECOMPLETIONQUEUE RIOResizeCompletionQueue; LPFN_RIORESIZEREQUESTQUEUE RIOResizeRequestQueue; } + // RIO_EXTENSION_FUNCTION_TABLE, *PRIO_EXTENSION_FUNCTION_TABLE; + [PInvokeData("mswsock.h", MSDNShortId = "NS:mswsock._RIO_EXTENSION_FUNCTION_TABLE")] + [StructLayout(LayoutKind.Sequential)] + public struct RIO_EXTENSION_FUNCTION_TABLE + { + /// The size, in bytes, of the structure. + public uint cbSize; + + /// A pointer to the RIOReceive function. + public LPFN_RIORECEIVE RIOReceive; + + /// A pointer to the RIOReceiveEx function. + public LPFN_RIORECEIVEEX RIOReceiveEx; + + /// A pointer to the RIOSend function. + public LPFN_RIOSEND RIOSend; + + /// A pointer to the RIOSendEx function. + public LPFN_RIOSENDEX RIOSendEx; + + /// A pointer to the RIOCloseCompletionQueue function. + public LPFN_RIOCLOSECOMPLETIONQUEUE RIOCloseCompletionQueue; + + /// A pointer to the RIOCreateCompletionQueue function. + public LPFN_RIOCREATECOMPLETIONQUEUE RIOCreateCompletionQueue; + + /// A pointer to the RIOCreateRequestQueue function. + public LPFN_RIOCREATEREQUESTQUEUE RIOCreateRequestQueue; + + /// A pointer to the RIODequeueCompletion function. + public LPFN_RIODEQUEUECOMPLETION RIODequeueCompletion; + + /// A pointer to the RIODeregisterBuffer function. + public LPFN_RIODEREGISTERBUFFER RIODeregisterBuffer; + + /// A pointer to the RIONotify function. + public LPFN_RIONOTIFY RIONotify; + + /// A pointer to the RIORegisterBuffer function. + public LPFN_RIOREGISTERBUFFER RIORegisterBuffer; + + /// A pointer to the RIOResizeCompletionQueue function. + public LPFN_RIORESIZECOMPLETIONQUEUE RIOResizeCompletionQueue; + + /// A pointer to the RIOResizeRequestQueue function. + public LPFN_RIORESIZEREQUESTQUEUE RIOResizeRequestQueue; + } + + /// + /// The RIO_NOTIFICATION_COMPLETION structure specifies the method for I/O completion to be used with a RIONotify function for + /// sending or receiving network data with the Winsock registered I/O extensions. + /// + /// + /// + /// The RIO_NOTIFICATION_COMPLETION structure is used to specify the behavior of the RIONotify function used with the Winsock + /// registered I/O extensions. + /// + /// + /// The RIO_NOTIFICATION_COMPLETION structure is passed to the RIOCreateCompletionQueue function when a RIO_CQ is created. If an + /// application does not call the RIONotify function for a completion queue, the completion queue can be created without a + /// RIO_NOTIFICATION_COMPLETION object. + /// + /// + /// For completion queues using an event, the Type member of the RIO_NOTIFICATION_COMPLETION structure is set to + /// RIO_EVENT_COMPLETION. The Event.EventHandle member of the RIO_NOTIFICATION_COMPLETION structure should contain + /// the handle for an event created by the WSACreateEvent or CreateEvent function. To receive the RIONotify completion, the application + /// should wait on the specified event handle using WSAWaitForMultipleEvents or a similar wait routine. If the application plans to reset + /// and reuse the event, the application can reduce overhead by setting the Event.NotifyReset member of the + /// RIO_NOTIFICATION_COMPLETION structure to a non-zero value. This causes the event to be reset by the RIONotify function + /// when notification occurs. This mitigates the need to call the WSAResetEvent function to reset the event between calls to the + /// RIONotify function. + /// + /// + /// For completion queues using an I/O completion port, the Type member of the RIO_NOTIFICATION_COMPLETION structure is set + /// to RIO_IOCP_COMPLETION. The Iocp.IocpHandle member of the RIO_NOTIFICATION_COMPLETION structure should contain + /// the handle for an I/O completion port created by the CreateIoCompletionPort function. To receive the RIONotify completion, the + /// application should call the GetQueuedCompletionStatus or GetQueuedCompletionStatusEx function. The application should provide a + /// dedicated OVERLAPPED object for the completion queue, and it may also use the Iocp.CompletionKey member to distinguish + /// RIONotify requests on the completion queue from other I/O completions including RIONotify completions for other + /// completion queues. + /// + /// + /// An application using thread pools can use thread pool wait objects to get RIONotify completions via its thread pool. In that case, + /// the call to the SetThreadpoolWait function should immediately follow the call to RIONotify. If the SetThreadpoolWait + /// function is called before RIONotify and the application relies on RIONotify to clear the event object, this may result + /// in spurious executions of the wait object callback. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/ns-mswsock-rio_notification_completion typedef struct + // _RIO_NOTIFICATION_COMPLETION { RIO_NOTIFICATION_COMPLETION_TYPE Type; union { struct { HANDLE EventHandle; BOOL NotifyReset; } Event; + // struct { HANDLE IocpHandle; PVOID CompletionKey; PVOID Overlapped; } Iocp; }; } RIO_NOTIFICATION_COMPLETION, *PRIO_NOTIFICATION_COMPLETION; + [PInvokeData("mswsock.h", MSDNShortId = "NS:mswsock._RIO_NOTIFICATION_COMPLETION")] + [StructLayout(LayoutKind.Sequential)] + public struct RIO_NOTIFICATION_COMPLETION + { + /// The type of completion to use with the RIONotify function when sending or receiving data. + public RIO_NOTIFICATION_COMPLETION_TYPE Type; + + /// + public UNION union; + + /// + [StructLayout(LayoutKind.Explicit)] + public struct UNION + { + /// + [FieldOffset(0)] + public EVENT Event; + + /// + [FieldOffset(0)] + public IOCP Iocp; + + /// + [StructLayout(LayoutKind.Sequential)] + public struct EVENT + { + /// + /// The handle for the event to set following a completed RIONotify request. + /// This value is valid when the Type member is set to RIO_EVENT_COMPLETION. + /// + public HANDLE EventHandle; + + /// + /// + /// The boolean value that causes the associated event to be reset when the RIONotify function is called. A non-zero value + /// cause the associated event to be reset. + /// + /// This value is valid when the Type member is set to RIO_EVENT_COMPLETION. + /// + public BOOL NotifyReset; + } + + /// + [StructLayout(LayoutKind.Sequential)] + public struct IOCP + { + /// + /// The handle for the I/O completion port to use for queuing a RIONotify request completion. + /// This value is valid when the Type member is set to RIO_IOCP_COMPLETION. + /// + public HANDLE IocpHandle; + + /// + /// + /// The value to use for lpCompletionKey parameter returned by the GetQueuedCompletionStatus or + /// GetQueuedCompletionStatusEx function when queuing a RIONotify request. + /// + /// This value is valid when the Type member is set to RIO_IOCP_COMPLETION. + /// + public IntPtr CompletionKey; + + /// + /// + /// A pointer to the OVERLAPPED structure to use when queuing a RIONotify request completion. This member must point to a + /// valid OVERLAPPED structure. + /// + /// This value is valid when the Type member is set to RIO_IOCP_COMPLETION. + /// + public IntPtr Overlapped; + } + } + } + + /// + /// The TRANSMIT_FILE_BUFFERS structure specifies data to be transmitted before and after file data during a TransmitFile function + /// file transfer operation. + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/ns-mswsock-transmit_file_buffers typedef struct _TRANSMIT_FILE_BUFFERS { + // LPVOID Head; DWORD HeadLength; LPVOID Tail; DWORD TailLength; } TRANSMIT_FILE_BUFFERS, *PTRANSMIT_FILE_BUFFERS, *LPTRANSMIT_FILE_BUFFERS; + [PInvokeData("mswsock.h", MSDNShortId = "NS:mswsock._TRANSMIT_FILE_BUFFERS")] + [StructLayout(LayoutKind.Sequential)] + public struct TRANSMIT_FILE_BUFFERS + { + /// Pointer to a buffer that contains data to be transmitted before the file data is transmitted. + public IntPtr Head; + + /// Size of the buffer pointed to by Head, in bytes, to be transmitted. + public uint HeadLength; + + /// Pointer to a buffer that contains data to be transmitted after the file data is transmitted. + public IntPtr Tail; + + /// Size of the buffer pointed to Tail, in bytes, to be transmitted. + public uint TailLength; + } + + /// + /// The TRANSMIT_PACKETS_ELEMENT structure specifies a single data element to be transmitted by the TransmitPackets function. + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsock/ns-mswsock-transmit_packets_element typedef struct + // _TRANSMIT_PACKETS_ELEMENT { ULONG dwElFlags; ULONG cLength; union { struct { LARGE_INTEGER nFileOffset; HANDLE hFile; }; PVOID + // pBuffer; }; } TRANSMIT_PACKETS_ELEMENT, *PTRANSMIT_PACKETS_ELEMENT, *LPTRANSMIT_PACKETS_ELEMENT; + [PInvokeData("mswsock.h", MSDNShortId = "NS:mswsock._TRANSMIT_PACKETS_ELEMENT")] + [StructLayout(LayoutKind.Sequential)] + public struct TRANSMIT_PACKETS_ELEMENT + { + /// + /// Type: ULONG /// - /// Your WSARecvMsg callback function receives ancillary data/control information with a message, from connected and - /// unconnected sockets. + /// Flags used to describe the contents of the packet array element, and to customize TransmitPackets function processing. The + /// following table lists valid flags: /// + /// + /// + /// Flag + /// Meaning + /// + /// + /// TP_ELEMENT_FILE + /// Specifies that data resides in a file. Default setting for dwElFlags. Mutually exclusive with TP_ELEMENT_MEMORY. + /// + /// + /// TP_ELEMENT_MEMORY + /// Specifies that data resides in memory. Mutually exclusive with TP_ELEMENT_FILE. + /// + /// + /// TP_ELEMENT_EOP + /// + /// Specifies that this element should not be combined with the next element in a single send request from the sockets layer to the + /// transport. This flag is used for granular control of the content of each message on a datagram or message-oriented socket. + /// + /// + /// + /// + public TP_ELEMENT dwElFlags; + + /// + /// Type: ULONG + /// The number of bytes to transmit. If zero, the entire file is transmitted. + /// + public uint cLength; + + /// + /// Type: LARGE_INTEGER /// - /// Note - /// This function is a Microsoft-specific extension to the Windows Sockets specification. + /// The file offset, in bytes, at which to begin the transfer. Valid only if TP_ELEMENT_FILE is specified in dwEIFlags. When + /// set to –1, transmission begins at the current byte offset. /// /// - /// - /// Type: _In_ SOCKET - /// A descriptor that identifies the socket. - /// - /// - /// Type: _Inout_ LPWSAMSG - /// A pointer to a WSAMSG structure based on the Posix.1g specification for the msghdr structure. - /// - /// - /// Type: _Out_opt_ LPDWORD - /// - /// A pointer to a DWORD containing number of bytes received by this call if the WSARecvMsg operation completes immediately. - /// - /// - /// To avoid potentially erroneous results, pass NULL for this parameter if the lpOverlapped parameter is not NULL . - /// This parameter can be NULL only if the lpOverlapped parameter is not NULL. - /// - /// - /// - /// Type: _Inout_opt_ LPWSAOVERLAPPED - /// A pointer to a WSAOVERLAPPED structure. Ignored for non-overlapped structures. - /// - /// - /// Type: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE - /// A pointer to the completion routine called when the receive operation completes. Ignored for non-overlapped structures. - /// - /// - /// - /// If no error occurs and the receive operation has completed immediately, WSARecvMsg returns zero. In this case, the - /// completion routine will have already been scheduled to be called once the calling thread is in the alertable state. Otherwise, a - /// value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError. The error code - /// WSA_IO_PENDING indicates that the overlapped operation has been successfully initiated and that completion will be - /// indicated at a later time. - /// - /// - /// Any other error code indicates that the operation was not successfully initiated and no completion indication will occur if an - /// overlapped operation was requested. - /// - /// - /// - /// Error code - /// Meaning - /// - /// - /// WSAECONNRESET - /// - /// For a UDP datagram socket, this error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message. - /// - /// - /// - /// WSAEFAULT - /// - /// The lpBuffers, lpFlags, lpFrom, lpNumberOfBytesRecvd, lpFromlen, lpOverlapped, or - /// lpCompletionRoutine parameter is not totally contained in a valid part of the user address space: the lpFrom buffer - /// was too small to accommodate the peer address. This error is also returned if a name member of the WSAMSG structure - /// pointed to by the lpMsg parameter was a NULL pointer and the namelen member of the WSAMSG structure - /// was not set to zero. This error is also returned if a Control.buf member of the WSAMSG structure pointed to by the - /// lpMsg parameter was a NULL pointer and the Control.len member of the WSAMSG structure was not set to zero. - /// - /// - /// - /// WSAEINPROGRESS - /// A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function. - /// - /// - /// WSAEINTR - /// A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall. - /// - /// - /// WSAEINVAL - /// The socket has not been bound (with bind, for example). - /// - /// - /// WSAEMSGSIZE - /// - /// The message was too large to fit into the specified buffer and (for unreliable protocols only) any trailing portion of the - /// message that did not fit into the buffer has been discarded. - /// - /// - /// - /// WSAENETDOWN - /// The network subsystem has failed. - /// - /// - /// WSAENETRESET - /// For a datagram socket, this error indicates that the time to live has expired. - /// - /// - /// WSAENOTCONN - /// The socket is not connected (connection-oriented sockets only). - /// - /// - /// WSAETIMEDOUT - /// - /// The socket timed out. This error is returned if the socket had a wait timeout specified using the SO_RCVTIMEO socket - /// option and the timeout was exceeded. - /// - /// - /// - /// WSAEOPNOTSUPP - /// - /// The socket operation is not supported. This error is returned if the dwFlags member of the WSAMSG structure pointed - /// to by the lpMsg parameter includes the MSG_PEEK control flag on a non-datagram socket. - /// - /// - /// - /// WSAEWOULDBLOCK - /// - /// Windows NT: Overlapped sockets: There are too many outstanding overlapped I/O requests. Non-overlapped sockets: The socket - /// is marked as nonblocking and the receive operation cannot be completed immediately. - /// - /// - /// - /// WSANOTINITIALISED - /// A successful WSAStartup call must occur before using this function. - /// - /// - /// WSA_IO_PENDING - /// An overlapped operation was successfully initiated and completion will be indicated at a later time. - /// - /// - /// WSA_OPERATION_ABORTED - /// The overlapped operation has been canceled due to the closure of the socket. - /// - /// - /// - /// - /// - /// The WSARecvMsg function can be used in place of the WSARecv and WSARecvFrom functions to receive data and - /// optional control information from connected and unconnected sockets. The WSARecvMsg function can only be used with - /// datagrams and raw sockets. The socket descriptor in the s parameter must be opened with the socket type set to SOCK_DGRAM - /// or SOCK_RAW. - /// - /// - /// Note The function pointer for the WSARecvMsg function must be obtained at run time by making a call to the - /// WSAIoctl function with the SIO_GET_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the - /// WSAIoctl function must contain WSAID_WSARECVMSG, a globally unique identifier (GUID) whose value identifies the - /// WSARecvMsg extension function. On success, the output returned by the WSAIoctl function contains a pointer to the - /// WSARecvMsg function. The WSAID_WSARECVMSG GUID is defined in the Mswsock.h header file. - /// - /// - /// The dwFlags member of the WSAMSG structure pointed to by the lpMsg parameter may only contain the MSG_PEEK - /// control flag on input. - /// - /// - /// Overlapped sockets are created with a WSASocket function call that has the WSA_FLAG_OVERLAPPED flag set. For - /// overlapped sockets, receiving information uses overlapped I/O unless both the lpOverlapped and lpCompletionRoutine parameters are - /// NULL. The socket is treated as a non-overlapped socket when both the lpOverlapped and lpCompletionRoutine parameters are NULL. - /// - /// - /// A completion indication occurs with overlapped sockets. Once the buffer or buffers have been consumed by the transport, a - /// completion routine is triggered or an event object is set. If the operation does not complete immediately, the final completion - /// status is retrieved through the completion routine or by calling the WSAGetOverlappedResult function. - /// - /// - /// For overlapped sockets, WSARecvMsg is used to post one or more buffers into which incoming data will be placed as it - /// becomes available, after which the application-specified completion indication (invocation of the completion routine or setting - /// of an event object) occurs. If the operation does not complete immediately, the final completion status is retrieved through the - /// completion routine or the WSAGetOverlappedResult function. - /// - /// - /// For non-overlapped sockets, the blocking semantics are identical to that of the standard recv function and the - /// lpOverlapped and lpCompletionRoutine parameters are ignored. Any data that has already been received and buffered by the - /// transport will be copied into the specified user buffers. In the case of a blocking socket with no data currently having been - /// received and buffered by the transport, the call will block until data is received. Windows Sockets 2 does not define any - /// standard blocking time-out mechanism for this function. For protocols acting as byte-stream protocols the stack tries to return - /// as much data as possible subject to the available buffer space and amount of received data available. However, receipt of a - /// single byte is sufficient to unblock the caller. There is no guarantee that more than a single byte will be returned. For - /// protocols acting as message-oriented, a full message is required to unblock the caller. - /// - /// Note The SO_RCVTIMEO socket option applies only to blocking sockets. - /// - /// The buffers are filled in the order in which they appear in the array pointed to by the lpBuffers member of the - /// WSAMSG structure pointed to by the lpMsg parameter, and the buffers are packed so that no holes are created. - /// - /// - /// If this function is completed in an overlapped manner, it is the Winsock service provider's responsibility to capture this - /// WSABUF structure before returning from this call. This enables applications to build stack-based WSABUF arrays - /// pointed to by the lpBuffers member of the WSAMSG structure pointed to by the lpMsg parameter. - /// - /// - /// For message-oriented sockets (a socket type of SOCK_DGRAM or SOCK_RAW), an incoming message is placed into the - /// buffers up to the total size of the buffers, and the completion indication occurs for overlapped sockets. If the message is - /// larger than the buffers, the buffers are filled with the first part of the message and the excess data is lost, and - /// WSARecvMsg generates the error WSAEMSGSIZE. - /// - /// - /// When the IP_PKTINFO socket option is enabled on an IPv4 socket of type SOCK_DGRAM or SOCK_RAW, the - /// WSARecvMsg function returns packet information in the WSAMSG structure pointed to by the lpMsg parameter. One of - /// the control data objects in the returned WSAMSG structure will contain an in_pktinfo structure used to store - /// received packet address information. - /// - /// - /// For datagrams received over IPv4, the Control member of the WSAMSG structure received will contain a WSABUF - /// structure that contains a WSACMSGHDR structure. The cmsg_level member of this WSACMSGHDR structure would - /// contain IPPROTO_IP, the cmsg_type member of this structure would contain IP_PKTINFO, and the - /// cmsg_data member would contain an in_pktinfo structure used to store received IPv4 packet address information. The - /// IPv4 address in the in_pktinfo structure is the IPv4 address from which the packet was received. - /// - /// - /// When the IPV6_PKTINFO socket option is enabled on an IPv6 socket of type SOCK_DGRAM or SOCK_RAW, the - /// WSARecvMsg function returns packet information in the WSAMSG structure pointed to by the lpMsg parameter. One of - /// the control data objects in the returned WSAMSG structure will contain an in6_pktinfo structure used to store - /// received packet address information. - /// - /// - /// For datagrams received over IPv6, the Control member of the WSAMSG structure received will contain a WSABUF - /// structure that contains a WSACMSGHDR structure. The cmsg_level member of this WSACMSGHDR structure would - /// contain IPPROTO_IPV6, the cmsg_type member of this structure would contain IPV6_PKTINFO, and the - /// cmsg_data member would contain an in6_pktinfo structure used to store received IPv6 packet address information. The - /// IPv6 address in the in6_pktinfo structure is the IPv6 address from which the packet was received. - /// - /// - /// For a dual-stack datagram socket, if an application requires the WSARecvMsg function to return packet information in a - /// WSAMSG structure for datagrams received over IPv4, then IP_PKTINFO socket option must be set to true on the socket. If - /// only the IPV6_PKTINFO option is set to true on the socket, packet information will be provided for datagrams received over IPv6 - /// but may not be provided for datagrams received over IPv4. - /// - /// Note that the Ws2ipdef.h header file is automatically included in Ws2tcpip.h, and should never be used directly. - /// - /// Note All I/O initiated by a given thread is canceled when that thread exits. For overlapped sockets, pending asynchronous - /// operations can fail if the thread is closed before the operations complete. For more information, see ExitThread. - /// - /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. - /// - /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows - /// Server 2012 R2, and later. - /// - /// dwFlags - /// - /// On input, the dwFlags member of the WSAMSG structure pointed to by the lpMsg parameter can be used to influence the - /// behavior of the function invocation beyond the socket options specified for the associated socket. That is, the semantics of this - /// function are determined by the socket options and the dwFlags member of the WSAMSG structure. The only possible - /// input value for the dwFlags member of the WSAMSG structure pointed to by the lpMsg parameter is MSG_PEEK. - /// - /// - /// - /// Value - /// Meaning - /// - /// - /// MSG_PEEK - /// - /// Peek at the incoming data. The data is copied into the buffer, but is not removed from the input queue. This flag is valid only - /// for non-overlapped sockets. - /// - /// - /// - /// The possible values for dwFlags member on input are defined in the Winsock2.h header file. - /// - /// On output, the dwFlags member of the WSAMSG structure pointed to by the lpMsg parameter may return a combination of - /// any of the following values. - /// - /// - /// - /// Value - /// Meaning - /// - /// - /// MSG_BCAST - /// The datagram was received as a link-layer broadcast or with a destination IP address that is a broadcast address. - /// - /// - /// MSG_CTRUNC - /// The control (ancillary) data was truncated. More control data was present than the process allocated room for. - /// - /// - /// MSG_MCAST - /// The datagram was received with a destination IP address that is a multicast address. - /// - /// - /// MSG_TRUNC - /// The datagram was truncated. More data was present than the process allocated room for. - /// - /// - /// - /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files - /// has changed and the possible values for the dwFlags member on output are defined in the Ws2def.h header file which is - /// automatically included by the Winsock2.h header file. - /// - /// - /// On versions of the Platform Software Development Kit (SDK) for Windows Server 2003 and earlier, the possible values for the - /// dwFlags member on output are defined in the Mswsock.h header file. - /// - /// - /// Note When issuing a blocking Winsock call such as WSARecvMsg with the lpOverlapped parameter set to NULL, Winsock - /// may need to wait for a network event before the call can complete. Winsock performs an alertable wait in this situation, which - /// can be interrupted by an asynchronous procedure call (APC) scheduled on the same thread. Issuing another blocking Winsock call - /// inside an APC that interrupted an ongoing blocking Winsock call on the same thread will lead to undefined behavior, and must - /// never be attempted by Winsock clients. - /// - /// Overlapped Socket I/O - /// - /// If an overlapped operation completes immediately, WSARecvMsg returns a value of zero and the lpNumberOfBytesRecvd - /// parameter is updated with the number of bytes received and the flag bits indicated by the lpFlags parameter are also updated. If - /// the overlapped operation is successfully initiated and will complete later, WSARecvMsg returns SOCKET_ERROR and - /// indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesRecvd is not updated. When the overlapped operation completes, - /// the amount of data transferred is indicated either through the cbTransferred parameter in the completion routine (if specified), - /// or through the lpcbTransfer parameter in WSAGetOverlappedResult. Flag values are obtained by examining the lpdwFlags - /// parameter of WSAGetOverlappedResult. - /// - /// - /// The WSARecvMsg function using overlapped I/O can be called from within the completion routine of a previous - /// WSARecv, WSARecvFrom, WSARecvMsg, WSASend, WSASendMsg, or WSASendTo function. For a - /// given socket, I/O completion routines will not be nested. This permits time-sensitive data transmissions to occur entirely within - /// a preemptive context. - /// - /// - /// The lpOverlapped parameter must be valid for the duration of the overlapped operation. If multiple I/O operations are - /// simultaneously outstanding, each must reference a separate WSAOVERLAPPED structure. - /// - /// - /// If the lpCompletionRoutine parameter is NULL, the hEvent parameter of lpOverlapped is signaled when the overlapped - /// operation completes if it contains a valid event object handle. An application can use WSAWaitForMultipleEvents or - /// WSAGetOverlappedResult to wait or poll on the event object. - /// - /// - /// If lpCompletionRoutine is not NULL, the hEvent parameter is ignored and can be used by the application to pass context - /// information to the completion routine. A caller that passes a non- NULL lpCompletionRoutine and later calls - /// WSAGetOverlappedResult for the same overlapped I/O request may not set the fWait parameter for that invocation of - /// WSAGetOverlappedResult to TRUE. In this case the usage of the hEvent parameter is undefined, and attempting to wait - /// on the hEvent parameter would produce unpredictable results. - /// - /// - /// The completion routine follows the same rules as stipulated for Windows file I/O completion routines. The completion routine will - /// not be invoked until the thread is in an alertable wait state such as can occur when the function WSAWaitForMultipleEvents - /// with the fAlertable parameter set to TRUE is invoked. - /// - /// The prototype of the completion routine is as follows: - /// - /// void CALLBACK CompletionRoutine( IN DWORD dwError, IN DWORD cbTransferred, IN LPWSAOVERLAPPED lpOverlapped, IN DWORD dwFlags ); - /// - /// - /// The CompletionRoutine is a placeholder for an application-defined or library-defined function name. The dwError parameter - /// specifies the completion status for the overlapped operation as indicated by the lpOverlapped parameter. The cbTransferred - /// parameter specifies the number of bytes received. The dwFlags parameter contains information that is also returned in - /// dwFlags member of the WSAMSG structure pointed to by the lpMsg parameter if the receive operation had completed - /// immediately. The CompletionRoutine function does not return a value. - /// - /// - /// Returning from this function allows invocation of another pending completion routine for this socket. When using - /// WSAWaitForMultipleEvents, all waiting completion routines are called before the alertable thread's wait is satisfied with - /// a return code of WSA_IO_COMPLETION. The completion routines can be called in any order, not necessarily in the same order - /// the overlapped operations are completed. However, the posted buffers are guaranteed to be filled in the same order in which they - /// are specified. - /// - /// - /// If you are using I/O completion ports, be aware that the order of calls made to WSARecvMsg is also the order in which the - /// buffers are populated. The WSARecvMsg function should not be called on the same socket simultaneously from different - /// threads, because it can result in an unpredictable buffer order. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_wsarecvmsg - // LPFN_WSARECVMSG LpfnWsarecvmsg; INT LpfnWsarecvmsg( SOCKET s, LPWSAMSG lpMsg, LPDWORD lpdwNumberOfBytesRecvd, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ) {...} - [UnmanagedFunctionPointer(CallingConvention.StdCall)] - [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_WSARECVMSG")] - public delegate int LPFN_WSARECVMSG(SOCKET s, ref WSAMSG lpMsg, out uint lpdwNumberOfBytesRecvd, ref WSAOVERLAPPED lpOverlapped, [In, Optional] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); + public long nFileOffset; - /* - AcceptEx function - GetAcceptExSockaddrs function - LPFN_CONNECTEX callback function - LPFN_DISCONNECTEX callback function - LPFN_RIOCLOSECOMPLETIONQUEUE callback function - LPFN_RIOCREATECOMPLETIONQUEUE callback function - LPFN_RIOCREATEREQUESTQUEUE callback function - LPFN_RIODEQUEUECOMPLETION callback function - LPFN_RIODEREGISTERBUFFER callback function - LPFN_RIONOTIFY callback function - LPFN_RIORECEIVE callback function - LPFN_RIORECEIVEEX callback function - LPFN_RIOREGISTERBUFFER callback function - LPFN_RIORESIZECOMPLETIONQUEUE callback function - LPFN_RIORESIZEREQUESTQUEUE callback function - LPFN_RIOSEND callback function - LPFN_RIOSENDEX callback function - LPFN_TRANSMITPACKETS callback function - RIO_EXTENSION_FUNCTION_TABLE structure - RIO_NOTIFICATION_COMPLETION structure - RIO_NOTIFICATION_COMPLETION_TYPE enumeration - TRANSMIT_FILE_BUFFERS structure - TRANSMIT_PACKETS_ELEMENT structure - TransmitFile function - WSARecvEx function - */ + /// + /// Type: HANDLE + /// + /// A handle to an open file to be transmitted. Valid only if TP_ELEMENT_FILE is specified in dwEIFlags. Windows reads the + /// file sequentially; caching performance is improved by opening this handle with FILE_FLAG_SEQUENTIAL_SCAN. + /// + /// + public HFILE hFile; + + /// + /// Type: PVOID + /// A pointer to the data in memory to be sent. Valid only if TP_ELEMENT_MEMORY is specified in dwEIFlags. + /// + public IntPtr pBuffer; } } \ No newline at end of file diff --git a/PInvoke/Ws2_32/WinSock2.cs b/PInvoke/Ws2_32/WinSock2.cs index bcb199a7..efed7156 100644 --- a/PInvoke/Ws2_32/WinSock2.cs +++ b/PInvoke/Ws2_32/WinSock2.cs @@ -6,2711 +6,2671 @@ using System.Runtime.InteropServices; using Vanara.Extensions; using Vanara.InteropServices; -namespace Vanara.PInvoke +namespace Vanara.PInvoke; + +/// Functions, structures and constants from ws2_32.h. +public static partial class Ws2_32 { - /// Functions, structures and constants from ws2_32.h. - public static partial class Ws2_32 + /// + public static readonly uint SIO_NSP_NOTIFY_CHANGE = _WSAIOW(IOC_WS2, 25); + + /// + /// An opaque data structure object from the service provider associated with socket s. This object stores the current configuration + /// information of the service provider. The exact format of this data structure is service provider specific. + /// + public const int PVD_CONFIG = 0x3001; + + /// The socket is listening. + [CorrespondingType(typeof(BOOL))] + public const int SO_ACCEPTCONN = 0x0002; + + /// The socket is configured for the transmission and receipt of broadcast messages. + [CorrespondingType(typeof(BOOL))] + public const int SO_BROADCAST = 0x0020; + + /// Returns the local address, local port, remote address, remote port, socket type, and protocol used by a socket. + [CorrespondingType(typeof(CSADDR_INFO))] + public const int SO_BSP_STATE = 0x1009; + + /// Returns current socket state, either from a previous call to setsockopt or the system default. + [CorrespondingType(typeof(BOOL))] + public const int SO_CONDITIONAL_ACCEPT = 0x3002; + + /// Debugging is enabled. + [CorrespondingType(typeof(BOOL))] + public const int SO_DEBUG = 0x0001; + + /// If TRUE, the SO_LINGER option is disabled. + [CorrespondingType(typeof(BOOL))] + public const int SO_DONTLINGER = (int)~SO_LINGER; + + /// + /// Routing is disabled. Setting this succeeds but is ignored on AF_INET sockets; fails on AF_INET6 sockets with WSAENOPROTOOPT. + /// This option is not supported on ATM sockets. + /// + [CorrespondingType(typeof(BOOL))] + public const int SO_DONTROUTE = 0x0010; + + /// Retrieves error status and clear. + [CorrespondingType(typeof(int))] + public const int SO_ERROR = 0x1007; + + /// + /// Prevents any other socket from binding to the same address and port. This option must be set before calling the bind function. + /// + [CorrespondingType(typeof(BOOL))] + public const int SO_EXCLUSIVEADDRUSE = (int)~SO_REUSEADDR; + + /// Reserved. + [CorrespondingType(typeof(GROUP))] + public const int SO_GROUP_ID = 0x2001; + + /// Reserved. + [CorrespondingType(typeof(int))] + public const int SO_GROUP_PRIORITY = 0x2002; + + /// Keep-alives are being sent. Not supported on ATM sockets. + [CorrespondingType(typeof(BOOL))] + public const int SO_KEEPALIVE = 0x0008; + + /// Returns the current linger options. + [CorrespondingType(typeof(LINGER))] + public const int SO_LINGER = 0x0080; + + /// + /// The maximum size of a message for message-oriented socket types (for example, SOCK_DGRAM). Has no meaning for stream oriented sockets. + /// + [CorrespondingType(typeof(uint))] + public const int SO_MAX_MSG_SIZE = 0x2003; + + /// + /// OOB data is being received in the normal data stream. (See section Windows Sockets 1.1 Blocking Routines and EINPROGRESS for a + /// discussion of this topic.) + /// + [CorrespondingType(typeof(BOOL))] + public const int SO_OOBINLINE = 0x0100; + + /// A description of the protocol information for the protocol that is bound to this socket. + [CorrespondingType(typeof(WSAPROTOCOL_INFO))] + public const int SO_PROTOCOL_INFO = SO_PROTOCOL_INFOW; + + /// A description of the protocol information for the protocol that is bound to this socket. + [CorrespondingType(typeof(WSAPROTOCOL_INFO))] + public const int SO_PROTOCOL_INFOA = 0x2004; + + /// A description of the protocol information for the protocol that is bound to this socket. + [CorrespondingType(typeof(WSAPROTOCOL_INFO))] + public const int SO_PROTOCOL_INFOW = 0x2005; + + /// + /// The total per-socket buffer space reserved for receives. This is unrelated to SO_MAX_MSG_SIZE and does not necessarily + /// correspond to the size of the TCP receive window. + /// + [CorrespondingType(typeof(int))] + public const int SO_RCVBUF = 0x1002; + + /// Receives low watermark. + [CorrespondingType(typeof(int))] + public const int SO_RCVLOWAT = 0x1004; + + /// Receives time-out. + [CorrespondingType(typeof(int))] + public const int SO_RCVTIMEO = 0x1006; + + /// The socket can be bound to an address which is already in use. Not applicable for ATM sockets. + [CorrespondingType(typeof(BOOL))] + public const int SO_REUSEADDR = 0x0004; + + /// + /// The total per-socket buffer space reserved for sends. This is unrelated to SO_MAX_MSG_SIZE and does not necessarily correspond + /// to the size of a TCP send window. + /// + [CorrespondingType(typeof(int))] + public const int SO_SNDBUF = 0x1001; + + /// Sends low watermark. + [CorrespondingType(typeof(int))] + public const int SO_SNDLOWAT = 0x1003; + + /// Sends time-out. + [CorrespondingType(typeof(int))] + public const int SO_SNDTIMEO = 0x1005; + + /// The type of the socket (for example, SOCK_STREAM). + [CorrespondingType(typeof(int))] + public const int SO_TYPE = 0x1008; + + /// + public const int SO_USELOOPBACK = 0x0040; + + /// A value that indicates a function failure. + public const int SOCKET_ERROR = -1; + + /// The socket option level. + public const int SOL_SOCKET = 0xffff; + + /// Maximum queue length specifiable by listen. + public const int SOMAXCONN = 0x7fffffff; + + /// Disables the Nagle algorithm for send coalescing. + [CorrespondingType(typeof(BOOL))] + public const int TCP_NODELAY = 0x0001; + + /// The application-specified callback function for . + /// + /// A WSABUF structure that contains the address of the connecting entity, where its len parameter is the length of the buffer in + /// bytes, and its buf parameter is a pointer to the buffer.. + /// + /// + /// A value parameter that contains any user data. The information in these parameters is sent along with the connection request. If + /// no caller identification or caller data is available, the corresponding parameters will be NULL. Many network protocols do not + /// support connect-time caller data. Most conventional network protocols can be expected to support caller identifier information + /// at connection-request time. The buf portion of the WSABUF pointed to by lpCallerId points to a sockaddr. The sockaddr structure + /// is interpreted according to its address family (typically by casting the sockaddr to some type specific to the address family). + /// + /// + /// References the FLOWSPEC structures for socket s specified by the caller, one for each direction, followed by any additional + /// provider-specific parameters. The sending or receiving flow specification values will be ignored as appropriate for any + /// unidirectional sockets. A NULL value indicates that there is no caller-supplied quality of service and that no negotiation is + /// possible. A non-NULL lpSQOS pointer indicates that a quality of service negotiation is to occur or that the provider is prepared + /// to accept the quality of service request without negotiation. + /// + /// + /// Reserved, and should be NULL. (reserved for future use with socket groups) references the FLOWSPEC structure for the socket + /// group the caller is to create, one for each direction, followed by any additional provider-specific parameters. A NULL value for + /// lpGQOS indicates no caller-specified group quality of service. Quality of service information can be returned if negotiation is + /// to occur. + /// + /// + /// Contains the local address of the connected entity. The buf portion of the WSABUF pointed to by lpCalleeId points to a sockaddr + /// structure. The sockaddr structure is interpreted according to its address family (typically by casting the sockaddr to some type + /// specific to the address family such as struct sockaddr_in). + /// + /// + /// A result parameter used by the condition function to supply user data back to the connecting entity. The lpCalleeData->len + /// initially contains the length of the buffer allocated by the service provider and pointed to by lpCalleeData->buf. A value of + /// zero means passing user data back to the caller is not supported. The condition function should copy up to lpCalleeData->len + /// bytes of data into lpCalleeData->buf, and then update lpCalleeData->len to indicate the actual number of bytes + /// transferred. If no user data is to be passed back to the caller, the condition function should set lpCalleeData->len to zero. + /// The format of all address and user data is specific to the address family to which the socket belongs. + /// + /// + /// Assigned within the condition function to indicate any of the following actions: + /// + /// + /// If g is an existing socket group identifier, add s to this group, provided all the requirements set by this group are met. + /// + /// If g = SG_UNCONSTRAINED_GROUP, create an unconstrained socket group and have s as the first member. + /// If g = SG_CONSTRAINED_GROUP, create a constrained socket group and have s as the first member. + /// If g = zero, no group operation is performed. + /// + /// + /// For unconstrained groups, any set of sockets can be grouped together as long as they are supported by a single service provider. + /// A constrained socket group can consist only of connection-oriented sockets, and requires that connections on all grouped sockets + /// be to the same address on the same host.For newly created socket groups, the new group identifier can be retrieved by using + /// getsockopt function with level parameter set to SOL_SOCKET and the optname parameter set to SO_GROUP_ID.A socket group and its + /// associated socket group ID remain valid until the last socket belonging to this socket group is closed.Socket group IDs are + /// unique across all processes for a given service provider. A socket group and its associated identifier remain valid until the + /// last socket belonging to this socket group is closed.Socket group identifiers are unique across all processes for a given + /// service provider. For more information on socket groups, see the Remarks for the WSASocket functions. + /// + /// + /// + /// Value passed to the condition function is the value passed as the dwCallbackData parameter in the original WSAAccept call. This + /// value is interpreted only by the Windows Socket version 2 client. This allows a client to pass some context information from the + /// WSAAccept call site through to the condition function. This also provides the condition function with any additional information + /// required to determine whether to accept the connection or not. A typical usage is to pass a (suitably cast) pointer to a data + /// structure containing references to application-defined objects with which this socket is associated. + /// + /// + [PInvokeData("winsock2.h", MSDNShortId = "f385f63f-49b2-4eb7-8717-ad4cca1a2252")] + [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)] + public delegate CF ConditionFunc(in WSABUF lpCallerId, in WSABUF lpCallerData, IntPtr lpSQOS, IntPtr lpGQOS, in WSABUF lpCalleeId, in WSABUF lpCalleeData, out GROUP g, IntPtr dwCallbackData); + + /// The address family specification. + [PInvokeData("winsock2.h")] + public enum ADDRESS_FAMILY : ushort + { + /// Unspecified address family. + AF_UNSPEC = 0, + + /// Unix local to host address. + AF_UNIX = 1, + + /// Address for IP version 4. + AF_INET = 2, + + /// ARPANET IMP address. + AF_IMPLINK = 3, + + /// Address for PUP protocols. + AF_PUP = 4, + + /// Address for MIT CHAOS protocols. + AF_CHAOS = 5, + + /// Address for Xerox NS protocols. + AF_NS = 6, + + /// IPX or SPX address. + AF_IPX = AF_NS, + + /// Address for ISO protocols. + AF_ISO = 7, + + /// Address for OSI protocols. + AF_OSI = AF_ISO, + + /// European Computer Manufacturers Association (ECMA) address. + AF_ECMA = 8, + + /// Address for Datakit protocols. + AF_DATAKIT = 9, + + /// Addresses for CCITT protocols, such as X.25. + AF_CCITT = 10, + + /// IBM SNA address. + AF_SNA = 11, + + /// DECnet address. + AF_DECnet = 12, + + /// Direct data-link interface address. + AF_DLI = 13, + + /// LAT address. + AF_LAT = 14, + + /// NSC Hyperchannel address. + AF_HYLINK = 15, + + /// AppleTalk address. + AF_APPLETALK = 16, + + /// NetBios address. + AF_NETBIOS = 17, + + /// VoiceView address. + AF_VOICEVIEW = 18, + + /// FireFox address. + AF_FIREFOX = 19, + + /// Undocumented. + AF_UNKNOWN1 = 20, + + /// Banyan address. + AF_BAN = 21, + + /// Native ATM services address. + AF_ATM = 22, + + /// Address for IP version 6. + AF_INET6 = 23, + + /// Address for Microsoft cluster products. + AF_CLUSTER = 24, + + /// IEEE 1284.4 workgroup address. + AF_12844 = 25, + + /// IrDA address. + AF_IRDA = 26, + + /// Address for Network Designers OSI gateway-enabled protocols. + AF_NETDES = 28, + + /// Undocumented. + AF_TCNPROCESS = 29, + + /// Undocumented. + AF_TCNMESSAGE = 30, + + /// Undocumented. + AF_ICLFXBM = 31, + + /// Bluetooth RFCOMM/L2CAP protocols. + AF_BTH = 32, + + /// Link layer interface. + AF_LINK = 33, + + /// Windows Hyper-V. + AF_HYPERV = 34, + } + + /// Possible return values to WSAAccept from the LPCONDITIONPROC. + [PInvokeData("winsock2.h", MSDNShortId = "f385f63f-49b2-4eb7-8717-ad4cca1a2252")] + public enum CF { /// - /// An opaque data structure object from the service provider associated with socket s. This object stores the current configuration - /// information of the service provider. The exact format of this data structure is service provider specific. + /// WSAAccept creates a new socket. The newly created socket has the same properties as socket s including asynchronous events + /// registered with WSAAsyncSelect or with WSAEventSelect. /// - public const int PVD_CONFIG = 0x3001; - - /// The socket is listening. - [CorrespondingType(typeof(BOOL))] - public const int SO_ACCEPTCONN = 0x0002; - - /// The socket is configured for the transmission and receipt of broadcast messages. - [CorrespondingType(typeof(BOOL))] - public const int SO_BROADCAST = 0x0020; - - /// Returns the local address, local port, remote address, remote port, socket type, and protocol used by a socket. - [CorrespondingType(typeof(CSADDR_INFO))] - public const int SO_BSP_STATE = 0x1009; - - /// Returns current socket state, either from a previous call to setsockopt or the system default. - [CorrespondingType(typeof(BOOL))] - public const int SO_CONDITIONAL_ACCEPT = 0x3002; - - /// - public const int SO_CONNDATA = 0x7000; - - /// - public const int SO_CONNDATALEN = 0x7004; + CF_ACCEPT = 0x0000, /// - /// Returns the number of seconds a socket has been connected. This socket option is valid for connection oriented protocols only. + /// WSAAccept rejects the connection request. The condition function runs in the same thread as this function does, and should + /// return as soon as possible. /// - [CorrespondingType(typeof(uint))] - public const int SO_CONNECT_TIME = 0x700C; - - /// - public const int SO_CONNOPT = 0x7001; - - /// - public const int SO_CONNOPTLEN = 0x7005; - - /// Debugging is enabled. - [CorrespondingType(typeof(BOOL))] - public const int SO_DEBUG = 0x0001; - - /// - public const int SO_DISCDATA = 0x7002; - - /// - public const int SO_DISCDATALEN = 0x7006; - - /// - public const int SO_DISCOPT = 0x7003; - - /// - public const int SO_DISCOPTLEN = 0x7007; - - /// If TRUE, the SO_LINGER option is disabled. - [CorrespondingType(typeof(BOOL))] - public const int SO_DONTLINGER = (int)~SO_LINGER; + CF_REJECT = 0x0001, /// - /// Routing is disabled. Setting this succeeds but is ignored on AF_INET sockets; fails on AF_INET6 sockets with WSAENOPROTOOPT. - /// This option is not supported on ATM sockets. + /// If the decision cannot be made immediately, the condition function should return CF_DEFER to indicate that no decision has + /// been made, and no action about this connection request should be taken by the service provider. When the application is + /// ready to take action on the connection request, it will invoke WSAAccept again and return either CF_ACCEPT or CF_REJECT as a + /// return value from the condition function. /// - [CorrespondingType(typeof(BOOL))] - public const int SO_DONTROUTE = 0x0010; + CF_DEFER = 0x0002 + } - /// Retrieves error status and clear. - [CorrespondingType(typeof(int))] - public const int SO_ERROR = 0x1007; + /// Socket group flags. + [PInvokeData("winsock2.h")] + [Flags] + public enum GROUP : uint + { + /// + /// Create an unconstrained socket group and have the new socket be the first member. For an unconstrained group, Winsock does + /// not constrain all sockets in the socket group to have been created with the same value for the type and protocol parameters. + /// + SG_UNCONSTRAINED_GROUP = 0x01, /// - /// Prevents any other socket from binding to the same address and port. This option must be set before calling the bind function. + /// Create a constrained socket group and have the new socket be the first member. For a contrained socket group, Winsock + /// constrains all sockets in the socket group to have been created with the same value for the type and protocol parameters. A + /// constrained socket group may consist only of connection-oriented sockets, and requires that connections on all grouped + /// sockets be to the same address on the same host. /// - [CorrespondingType(typeof(BOOL))] - public const int SO_EXCLUSIVEADDRUSE = (int)~SO_REUSEADDR; - - /// Reserved. - [CorrespondingType(typeof(GROUP))] - public const int SO_GROUP_ID = 0x2001; - - /// Reserved. - [CorrespondingType(typeof(int))] - public const int SO_GROUP_PRIORITY = 0x2002; - - /// Keep-alives are being sent. Not supported on ATM sockets. - [CorrespondingType(typeof(BOOL))] - public const int SO_KEEPALIVE = 0x0008; - - /// Returns the current linger options. - [CorrespondingType(typeof(LINGER))] - public const int SO_LINGER = 0x0080; - - /// - /// The maximum size of a message for message-oriented socket types (for example, SOCK_DGRAM). Has no meaning for stream oriented sockets. - /// - [CorrespondingType(typeof(uint))] - public const int SO_MAX_MSG_SIZE = 0x2003; - - /// - public const int SO_MAXDG = 0x7009; - - /// - public const int SO_MAXPATHDG = 0x700A; - - /// - /// OOB data is being received in the normal data stream. (See section Windows Sockets 1.1 Blocking Routines and EINPROGRESS for a - /// discussion of this topic.) - /// - [CorrespondingType(typeof(BOOL))] - public const int SO_OOBINLINE = 0x0100; - - /// A description of the protocol information for the protocol that is bound to this socket. - [CorrespondingType(typeof(WSAPROTOCOL_INFO))] - public const int SO_PROTOCOL_INFO = SO_PROTOCOL_INFOW; - - /// A description of the protocol information for the protocol that is bound to this socket. - [CorrespondingType(typeof(WSAPROTOCOL_INFO))] - public const int SO_PROTOCOL_INFOA = 0x2004; - - /// A description of the protocol information for the protocol that is bound to this socket. - [CorrespondingType(typeof(WSAPROTOCOL_INFO))] - public const int SO_PROTOCOL_INFOW = 0x2005; - - /// - /// The total per-socket buffer space reserved for receives. This is unrelated to SO_MAX_MSG_SIZE and does not necessarily - /// correspond to the size of the TCP receive window. - /// - [CorrespondingType(typeof(int))] - public const int SO_RCVBUF = 0x1002; - - /// Receives low watermark. - [CorrespondingType(typeof(int))] - public const int SO_RCVLOWAT = 0x1004; - - /// Receives time-out. - [CorrespondingType(typeof(int))] - public const int SO_RCVTIMEO = 0x1006; - - /// The socket can be bound to an address which is already in use. Not applicable for ATM sockets. - [CorrespondingType(typeof(BOOL))] - public const int SO_REUSEADDR = 0x0004; - - /// - /// The total per-socket buffer space reserved for sends. This is unrelated to SO_MAX_MSG_SIZE and does not necessarily correspond - /// to the size of a TCP send window. - /// - [CorrespondingType(typeof(int))] - public const int SO_SNDBUF = 0x1001; - - /// Sends low watermark. - [CorrespondingType(typeof(int))] - public const int SO_SNDLOWAT = 0x1003; - - /// Sends time-out. - [CorrespondingType(typeof(int))] - public const int SO_SNDTIMEO = 0x1005; - - /// The type of the socket (for example, SOCK_STREAM). - [CorrespondingType(typeof(int))] - public const int SO_TYPE = 0x1008; - - /// - public const int SO_UPDATE_ACCEPT_CONTEXT = 0x700B; - - /// - public const int SO_USELOOPBACK = 0x0040; - - /// A value that indicates a function failure. - public const int SOCKET_ERROR = -1; - - /// The socket option level. - public const int SOL_SOCKET = 0xffff; - - /// Maximum queue length specifiable by listen. - public const int SOMAXCONN = 0x7fffffff; - - /// - public const int TCP_BSDURGENT = 0x7000; - - /// Disables the Nagle algorithm for send coalescing. - [CorrespondingType(typeof(BOOL))] - public const int TCP_NODELAY = 0x0001; - - /// The application-specified callback function for . - /// - /// A WSABUF structure that contains the address of the connecting entity, where its len parameter is the length of the buffer in - /// bytes, and its buf parameter is a pointer to the buffer.. - /// - /// - /// A value parameter that contains any user data. The information in these parameters is sent along with the connection request. If - /// no caller identification or caller data is available, the corresponding parameters will be NULL. Many network protocols do not - /// support connect-time caller data. Most conventional network protocols can be expected to support caller identifier information - /// at connection-request time. The buf portion of the WSABUF pointed to by lpCallerId points to a sockaddr. The sockaddr structure - /// is interpreted according to its address family (typically by casting the sockaddr to some type specific to the address family). - /// - /// - /// References the FLOWSPEC structures for socket s specified by the caller, one for each direction, followed by any additional - /// provider-specific parameters. The sending or receiving flow specification values will be ignored as appropriate for any - /// unidirectional sockets. A NULL value indicates that there is no caller-supplied quality of service and that no negotiation is - /// possible. A non-NULL lpSQOS pointer indicates that a quality of service negotiation is to occur or that the provider is prepared - /// to accept the quality of service request without negotiation. - /// - /// - /// Reserved, and should be NULL. (reserved for future use with socket groups) references the FLOWSPEC structure for the socket - /// group the caller is to create, one for each direction, followed by any additional provider-specific parameters. A NULL value for - /// lpGQOS indicates no caller-specified group quality of service. Quality of service information can be returned if negotiation is - /// to occur. - /// - /// - /// Contains the local address of the connected entity. The buf portion of the WSABUF pointed to by lpCalleeId points to a sockaddr - /// structure. The sockaddr structure is interpreted according to its address family (typically by casting the sockaddr to some type - /// specific to the address family such as struct sockaddr_in). - /// - /// - /// A result parameter used by the condition function to supply user data back to the connecting entity. The lpCalleeData->len - /// initially contains the length of the buffer allocated by the service provider and pointed to by lpCalleeData->buf. A value of - /// zero means passing user data back to the caller is not supported. The condition function should copy up to lpCalleeData->len - /// bytes of data into lpCalleeData->buf, and then update lpCalleeData->len to indicate the actual number of bytes - /// transferred. If no user data is to be passed back to the caller, the condition function should set lpCalleeData->len to zero. - /// The format of all address and user data is specific to the address family to which the socket belongs. - /// - /// - /// Assigned within the condition function to indicate any of the following actions: - /// - /// - /// If g is an existing socket group identifier, add s to this group, provided all the requirements set by this group are met. - /// - /// If g = SG_UNCONSTRAINED_GROUP, create an unconstrained socket group and have s as the first member. - /// If g = SG_CONSTRAINED_GROUP, create a constrained socket group and have s as the first member. - /// If g = zero, no group operation is performed. - /// - /// - /// For unconstrained groups, any set of sockets can be grouped together as long as they are supported by a single service provider. - /// A constrained socket group can consist only of connection-oriented sockets, and requires that connections on all grouped sockets - /// be to the same address on the same host.For newly created socket groups, the new group identifier can be retrieved by using - /// getsockopt function with level parameter set to SOL_SOCKET and the optname parameter set to SO_GROUP_ID.A socket group and its - /// associated socket group ID remain valid until the last socket belonging to this socket group is closed.Socket group IDs are - /// unique across all processes for a given service provider. A socket group and its associated identifier remain valid until the - /// last socket belonging to this socket group is closed.Socket group identifiers are unique across all processes for a given - /// service provider. For more information on socket groups, see the Remarks for the WSASocket functions. - /// - /// - /// - /// Value passed to the condition function is the value passed as the dwCallbackData parameter in the original WSAAccept call. This - /// value is interpreted only by the Windows Socket version 2 client. This allows a client to pass some context information from the - /// WSAAccept call site through to the condition function. This also provides the condition function with any additional information - /// required to determine whether to accept the connection or not. A typical usage is to pass a (suitably cast) pointer to a data - /// structure containing references to application-defined objects with which this socket is associated. - /// - /// - [PInvokeData("winsock2.h", MSDNShortId = "f385f63f-49b2-4eb7-8717-ad4cca1a2252")] - [UnmanagedFunctionPointer(CallingConvention.Winapi, CharSet = CharSet.Unicode)] - public delegate CF ConditionFunc(in WSABUF lpCallerId, in WSABUF lpCallerData, IntPtr lpSQOS, IntPtr lpGQOS, in WSABUF lpCalleeId, in WSABUF lpCalleeData, out GROUP g, IntPtr dwCallbackData); - - /// The address family specification. - [PInvokeData("winsock2.h")] - public enum ADDRESS_FAMILY : ushort - { - /// Unspecified address family. - AF_UNSPEC = 0, - - /// Unix local to host address. - AF_UNIX = 1, - - /// Address for IP version 4. - AF_INET = 2, - - /// ARPANET IMP address. - AF_IMPLINK = 3, - - /// Address for PUP protocols. - AF_PUP = 4, - - /// Address for MIT CHAOS protocols. - AF_CHAOS = 5, - - /// Address for Xerox NS protocols. - AF_NS = 6, - - /// IPX or SPX address. - AF_IPX = AF_NS, - - /// Address for ISO protocols. - AF_ISO = 7, - - /// Address for OSI protocols. - AF_OSI = AF_ISO, - - /// European Computer Manufacturers Association (ECMA) address. - AF_ECMA = 8, - - /// Address for Datakit protocols. - AF_DATAKIT = 9, - - /// Addresses for CCITT protocols, such as X.25. - AF_CCITT = 10, - - /// IBM SNA address. - AF_SNA = 11, - - /// DECnet address. - AF_DECnet = 12, - - /// Direct data-link interface address. - AF_DLI = 13, - - /// LAT address. - AF_LAT = 14, - - /// NSC Hyperchannel address. - AF_HYLINK = 15, - - /// AppleTalk address. - AF_APPLETALK = 16, - - /// NetBios address. - AF_NETBIOS = 17, - - /// VoiceView address. - AF_VOICEVIEW = 18, - - /// FireFox address. - AF_FIREFOX = 19, - - /// Undocumented. - AF_UNKNOWN1 = 20, - - /// Banyan address. - AF_BAN = 21, - - /// Native ATM services address. - AF_ATM = 22, - - /// Address for IP version 6. - AF_INET6 = 23, - - /// Address for Microsoft cluster products. - AF_CLUSTER = 24, - - /// IEEE 1284.4 workgroup address. - AF_12844 = 25, - - /// IrDA address. - AF_IRDA = 26, - - /// Address for Network Designers OSI gateway-enabled protocols. - AF_NETDES = 28, - - /// Undocumented. - AF_TCNPROCESS = 29, - - /// Undocumented. - AF_TCNMESSAGE = 30, - - /// Undocumented. - AF_ICLFXBM = 31, - - /// Bluetooth RFCOMM/L2CAP protocols. - AF_BTH = 32, - - /// Link layer interface. - AF_LINK = 33, - - /// Windows Hyper-V. - AF_HYPERV = 34, - } - - /// Possible return values to WSAAccept from the LPCONDITIONPROC. - [PInvokeData("winsock2.h", MSDNShortId = "f385f63f-49b2-4eb7-8717-ad4cca1a2252")] - public enum CF - { - /// - /// WSAAccept creates a new socket. The newly created socket has the same properties as socket s including asynchronous events - /// registered with WSAAsyncSelect or with WSAEventSelect. - /// - CF_ACCEPT = 0x0000, - - /// - /// WSAAccept rejects the connection request. The condition function runs in the same thread as this function does, and should - /// return as soon as possible. - /// - CF_REJECT = 0x0001, - - /// - /// If the decision cannot be made immediately, the condition function should return CF_DEFER to indicate that no decision has - /// been made, and no action about this connection request should be taken by the service provider. When the application is - /// ready to take action on the connection request, it will invoke WSAAccept again and return either CF_ACCEPT or CF_REJECT as a - /// return value from the condition function. - /// - CF_DEFER = 0x0002 - } - - /// Socket group flags. - [PInvokeData("winsock2.h")] - [Flags] - public enum GROUP : uint - { - /// - /// Create an unconstrained socket group and have the new socket be the first member. For an unconstrained group, Winsock does - /// not constrain all sockets in the socket group to have been created with the same value for the type and protocol parameters. - /// - SG_UNCONSTRAINED_GROUP = 0x01, - - /// - /// Create a constrained socket group and have the new socket be the first member. For a contrained socket group, Winsock - /// constrains all sockets in the socket group to have been created with the same value for the type and protocol parameters. A - /// constrained socket group may consist only of connection-oriented sockets, and requires that connections on all grouped - /// sockets be to the same address on the same host. - /// - SG_CONSTRAINED_GROUP = 0x02 - } - - /// Indicate either big-endian or little-endian with the values 0 and 1 respectively. - [PInvokeData("winsock2.h", MSDNShortId = "be5f3e81-1442-43c7-9e4e-9eb2b2a05132")] - public enum NetworkByteOrder - { - /// The bigendian - BIGENDIAN = 0x0000, - - /// The littleendian - LITTLEENDIAN = 0x0001 - } - - /// Namespace identifier. - [PInvokeData("winsock2.h", MSDNShortId = "cc4ccb2d-ea5a-48bd-a3ae-f70432ab2c39")] - public enum NS - { - /// All installed and active namespaces. - NS_ALL = 0, - - /// - NS_SAP = 1, - - /// - NS_NDS = 2, - - /// - NS_PEER_BROWSE = 3, - - /// - NS_SLP = 5, - - /// - NS_DHCP = 6, - - /// - NS_TCPIP_LOCAL = 10, - - /// - NS_TCPIP_HOSTS = 11, - - /// The domain name system (DNS) namespace. - NS_DNS = 12, - - /// The NetBIOS over TCP/IP (NETBT) namespace. - NS_NETBT = 13, - - /// The Windows Internet Naming Service (NS_WINS) namespace. - NS_WINS = 14, - - /// - /// The network location awareness (NLA) namespace. - /// This namespace identifier is supported on Windows XP and later. - /// - NS_NLA = 15, - - /// - /// The Bluetooth namespace. - /// This namespace identifier is supported on Windows Vista and later. - /// - NS_BTH = 16, - - /// - NS_LOCALNAME = 19, - - /// - NS_NBP = 20, - - /// - NS_MS = 30, - - /// - NS_STDA = 31, - - /// The Windows NT Directory Services (NS_NTDS) namespace. - NS_NTDS = 32, - - /// - /// The email namespace. - /// This namespace identifier is supported on Windows Vista and later. - /// - NS_EMAIL = 37, - - /// - /// The peer-to-peer namespace for a specific peer name. - /// This namespace identifier is supported on Windows Vista and later. - /// - NS_PNRPNAME = 38, - - /// - /// The peer-to-peer namespace for a collection of peer names. - /// This namespace identifier is supported on Windows Vista and later. - /// - NS_PNRPCLOUD = 39, - - /// - NS_X500 = 40, - - /// - NS_NIS = 41, - - /// - NS_NISPLUS = 42, - - /// - NS_WRQ = 50, - - /// - NS_NETDES = 60 - } - - /// A set of flags that provides information on how this protocol is represented in the Winsock catalog. - [PInvokeData("winsock2.h", MSDNShortId = "be5f3e81-1442-43c7-9e4e-9eb2b2a05132")] - [Flags] - public enum PFL : uint - { - /// - /// Indicates that this is one of two or more entries for a single protocol (from a given provider) which is capable of - /// implementing multiple behaviors. An example of this is SPX which, on the receiving side, can behave either as a - /// message-oriented or a stream-oriented protocol. - /// - PFL_MULTIPLE_PROTO_ENTRIES = 0x00000001, - - /// - /// Indicates that this is the recommended or most frequently used entry for a protocol that is capable of implementing multiple behaviors. - /// - PFL_RECOMMENDED_PROTO_ENTRY = 0x00000002, - - /// - /// Set by a provider to indicate to the Ws2_32.dll that this protocol should not be returned in the result buffer generated by - /// WSAEnumProtocols. Obviously, a Windows Sockets 2 application should never see an entry with this bit set. - /// - PFL_HIDDEN = 0x00000004, - - /// Indicates that a value of zero in the protocol parameter of socket or WSASocket matches this protocol entry. - PFL_MATCHES_PROTOCOL_ZERO = 0x00000008, - - /// - /// Set by a provider to indicate support for network direct access. - /// This value is supported on Windows 7 and Windows Server 2008 R2. - /// - PFL_NETWORKDIRECT_PROVIDER = 0x00000010, - } - - /// The type specification for the new socket. - [PInvokeData("winsock2.h", MSDNShortId = "6bf6e6c4-6268-479c-86a6-52e90cf317db")] - public enum SOCK - { - /// - /// A socket type that provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission - /// mechanism. This socket type uses the Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6). - /// - SOCK_STREAM = 1, - - /// - /// A socket type that supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum - /// length. This socket type uses the User Datagram Protocol (UDP) for the Internet address family (AF_INET or AF_INET6). - /// - SOCK_DGRAM = 2, - - /// - /// A socket type that provides a raw socket that allows an application to manipulate the next upper-layer protocol header. To - /// manipulate the IPv4 header, the IP_HDRINCL socket option must be set on the socket. To manipulate the IPv6 header, the - /// IPV6_HDRINCL socket option must be set on the socket. - /// - SOCK_RAW = 3, - - /// - /// A socket type that provides a reliable message datagram. An example of this type is the Pragmatic General Multicast (PGM) - /// multicast protocol implementation in Windows, often referred to as reliable multicast programming. - /// This type value is only supported if the Reliable Multicast Protocol is installed. - /// - SOCK_RDM = 4, - - /// A socket type that provides a pseudo-stream packet based on datagrams. - SOCK_SEQPACKET = 5, - } - - /// a bitmask of the notification events for the socket. - [PInvokeData("winsock2.h", MSDNShortId = "NS:winsock2.SOCK_NOTIFY_REGISTRATION")] - [Flags] - public enum SOCK_NOTIFY_EVENT : ushort - { - /// Input is available from the socket without blocking. - SOCK_NOTIFY_EVENT_IN = SOCK_NOTIFY_REGISTER_EVENT.SOCK_NOTIFY_REGISTER_EVENT_IN, - - /// Output can be provided to the socket without blocking. - SOCK_NOTIFY_EVENT_OUT = SOCK_NOTIFY_REGISTER_EVENT.SOCK_NOTIFY_REGISTER_EVENT_OUT, - - /// The socket connection has terminated. - SOCK_NOTIFY_EVENT_HANGUP = SOCK_NOTIFY_REGISTER_EVENT.SOCK_NOTIFY_REGISTER_EVENT_HANGUP, - - /// The socket is in an error state. - SOCK_NOTIFY_EVENT_ERR = 0x40, - - /// The notification has been deregistered. - SOCK_NOTIFY_EVENT_REMOVE = 0x80, - - /// All events. - SOCK_NOTIFY_EVENTS_ALL = SOCK_NOTIFY_REGISTER_EVENT.SOCK_NOTIFY_REGISTER_EVENTS_ALL | SOCK_NOTIFY_EVENT_ERR | SOCK_NOTIFY_EVENT_REMOVE, - } - - /// Indicates the operation to perform on a registration. At most one operation may be performed at a time. - [PInvokeData("winsock2.h", MSDNShortId = "NS:winsock2.SOCK_NOTIFY_REGISTRATION")] - [Flags] - public enum SOCK_NOTIFY_OP : byte - { - /// - /// No registration operations should take place. Use this if your application calls ProcessSocketNotifications and is only - /// interested in receiving notifications. - /// - SOCK_NOTIFY_OP_NONE = 0x00, - - /// - /// Enables the registration. Notifications must not be re-enabled until the SOCK_NOTIFY_EVENT_DISABLE notification is received. - /// - SOCK_NOTIFY_OP_ENABLE = 0x01, - - /// - /// Disables the registration, but doesn't destroy the underlying data structures. Note that this doesn't remove the - /// registration, it merely suppresses queuing of new notifications. Notifications that have already been queued might still be - /// delivered until the SOCK_NOTIFY_EVENT_DISABLE event is received. - /// - SOCK_NOTIFY_OP_DISABLE = 0x02, - - /// - /// Removes a previously-registered notification. Both enabled and disabled notifications may be removed. The - /// SOCK_NOTIFY_EVENT_REMOVE notification is issued, with the guarantee that no more notifications will be issued afterwards for - /// that completion key unless it is re-registered. - /// - SOCK_NOTIFY_OP_REMOVE = 0x04, - } - - /// A set of flags indicating the notifications being requested. - [PInvokeData("winsock2.h", MSDNShortId = "NS:winsock2.SOCK_NOTIFY_REGISTRATION")] - [Flags] - public enum SOCK_NOTIFY_REGISTER_EVENT : ushort - { - /// Notifications should not be issued. - SOCK_NOTIFY_REGISTER_EVENT_NONE = 0x00, - - /// A notification should be issued when data can be read without blocking. - SOCK_NOTIFY_REGISTER_EVENT_IN = 0x01, - - /// A notification should be issued when data can be written without blocking. - SOCK_NOTIFY_REGISTER_EVENT_OUT = 0x02, - - /// A notification should be issued when a stream-oriented connection was either disconnected or aborted. - SOCK_NOTIFY_REGISTER_EVENT_HANGUP = 0x04, - - /// All flags. - SOCK_NOTIFY_REGISTER_EVENTS_ALL = SOCK_NOTIFY_REGISTER_EVENT_IN | SOCK_NOTIFY_REGISTER_EVENT_OUT | SOCK_NOTIFY_REGISTER_EVENT_HANGUP - } - - /// A set of flags indicating the trigger behavior. - [PInvokeData("winsock2.h", MSDNShortId = "NS:winsock2.SOCK_NOTIFY_REGISTRATION")] - [Flags] - public enum SOCK_NOTIFY_TRIGGER : byte - { - /// The registration will be disabled (not removed) upon delivery of the next notification. - SOCK_NOTIFY_TRIGGER_ONESHOT = 0x01, - - /// The registration will remain active until it is explicitly disabled or removed. - SOCK_NOTIFY_TRIGGER_PERSISTENT = 0x02, - - /// - /// The registration is for level-triggered notifications. Not compatible with edge-triggered. One of edge- or level-triggered - /// must be supplied. - /// - SOCK_NOTIFY_TRIGGER_LEVEL = 0x04, - - /// - /// The registration is for edge-triggered notifications. Not compatible with level-triggered. One of edge- or level-triggered - /// must be supplied. - /// - SOCK_NOTIFY_TRIGGER_EDGE = 0x08, - - /// All triggers. - SOCK_NOTIFY_TRIGGER_ALL = SOCK_NOTIFY_TRIGGER_ONESHOT | SOCK_NOTIFY_TRIGGER_PERSISTENT | SOCK_NOTIFY_TRIGGER_LEVEL | SOCK_NOTIFY_TRIGGER_EDGE, - } - - /// - /// The Windows Sockets WSAECOMPARATOR enumeration type is used for version-comparison semantics in Windows Sockets 2. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/ne-winsock2-wsaecomparator typedef enum _WSAEcomparator { COMP_EQUAL, - // COMP_NOTLESS } WSAECOMPARATOR, *PWSAECOMPARATOR, *LPWSAECOMPARATOR; - [PInvokeData("winsock2.h", MSDNShortId = "a1de171e-42d7-4d57-b241-1db9989dbd8e")] - public enum WSAECOMPARATOR - { - /// Used for determining whether version values are equal. - COMP_EQUAL, - - /// Used for determining whether a version value is no less than a specified value. - COMP_NOTLESS, - } - - /// A value that determines that operation requested. - [PInvokeData("winsock2.h")] - public enum WSAESETSERVICEOP - { - /// - /// Register the service. For SAP, this means sending out a periodic broadcast. This is an NOP for the DNS namespace. For - /// persistent data stores, this means updating the address information. - /// - RNRSERVICE_REGISTER = 0, - - /// - /// Remove the service from the registry. For SAP, this means stop sending out the periodic broadcast. This is an NOP for the - /// DNS namespace. For persistent data stores this means deleting address information. - /// - RNRSERVICE_DEREGISTER, - - /// - /// Delete the service from dynamic name and persistent spaces. For services represented by multiple CSADDR_INFO structures - /// (using the SERVICE_MULTIPLE flag), only the specified address will be deleted, and this must match exactly the corresponding - /// CSADDR_INFO structure that was specified when the service was registered. - /// - RNRSERVICE_DELETE - } - - /// A bitmask that describes the services provided by the protocol. - [PInvokeData("winsock2.h", MSDNShortId = "be5f3e81-1442-43c7-9e4e-9eb2b2a05132")] - [Flags] - public enum XP1 - { - /// Provides connectionless (datagram) service. If not set, the protocol supports connection-oriented data transfer. - XP1_CONNECTIONLESS = 0x00000001, - - /// Guarantees that all data sent will reach the intended destination. - XP1_GUARANTEED_DELIVERY = 0x00000002, - - /// - /// Guarantees that data only arrives in the order in which it was sent and that it is not duplicated. This characteristic does - /// not necessarily mean that the data is always delivered, but that any data that is delivered is delivered in the order in - /// which it was sent. - /// - XP1_GUARANTEED_ORDER = 0x00000004, - - /// Honors message boundaries—as opposed to a stream-oriented protocol where there is no concept of message boundaries. - XP1_MESSAGE_ORIENTED = 0x00000008, - - /// - /// A message-oriented protocol, but message boundaries are ignored for all receipts. This is convenient when an application - /// does not desire message framing to be done by the protocol. - /// - XP1_PSEUDO_STREAM = 0x00000010, - - /// Supports two-phase (graceful) close. If not set, only abortive closes are performed. - XP1_GRACEFUL_CLOSE = 0x00000020, - - /// Supports expedited (urgent) data. - XP1_EXPEDITED_DATA = 0x00000040, - - /// Supports connect data. - XP1_CONNECT_DATA = 0x00000080, - - /// Supports disconnect data. - XP1_DISCONNECT_DATA = 0x00000100, - - /// Supports a broadcast mechanism. - XP1_SUPPORT_BROADCAST = 0x00000200, - - /// Supports a multipoint or multicast mechanism. Control and data plane attributes are indicated below. - XP1_SUPPORT_MULTIPOINT = 0x00000400, - - /// Indicates whether the control plane is rooted (value = 1) or nonrooted (value = 0). - XP1_MULTIPOINT_CONTROL_PLANE = 0x00000800, - - /// Indicates whether the data plane is rooted (value = 1) or nonrooted (value = 0). - XP1_MULTIPOINT_DATA_PLANE = 0x00001000, - - /// Supports quality of service requests. - XP1_QOS_SUPPORTED = 0x00002000, - - /// Bit is reserved. - XP1_INTERRUPT = 0x00004000, - - /// Protocol is unidirectional in the send direction. - XP1_UNI_SEND = 0x00008000, - - /// Protocol is unidirectional in the recv direction. - XP1_UNI_RECV = 0x00010000, - - /// Socket descriptors returned by the provider are operating system Installable File System (IFS) handles. - XP1_IFS_HANDLES = 0x00020000, - - /// The MSG_PARTIAL flag is supported in WSASend and WSASendTo. - XP1_PARTIAL_MESSAGE = 0x00040000, - - /// - /// The protocol provides support for SAN. - /// This value is supported on Windows 7 and Windows Server 2008 R2. - /// - XP1_SAN_SUPPORT_SDP = 0x00080000, - } - - /// - /// - /// Associates a set of sockets with a completion port, and retrieves any notifications that are already pending on that port. Once - /// associated, the completion port receives the socket state notifications that were specified. Only Microsoft Winsock provider - /// sockets are supported. - /// - /// - /// To reduce system call overhead, you can register for notifications and retrieve them in a single call to - /// ProcessSocketNotifications. Alternatively, you can retrieve them explicitly by calling the usual I/O completion port - /// functions, such as GetQueuedCompletionStatus. Notifications retrieved using ProcessSocketNotifications are the same as - /// those retrieved using GetQueuedCompletionStatusEx, which might include notification packets other than socket state changes. - /// - /// - /// The notification event flags are the integer value of the dwNumberOfBytesTransferred fields of the returned OVERLAPPED_ENTRY - /// structures. This is similar to using JOBOBJECT_ASSOCIATE_COMPLETION_PORT, which also uses the dwNumberOfBytesTransferred field - /// to send integer messages. Call the SocketNotificationRetrieveEvents function to obtain them. - /// - /// - /// A socket handle can be registered to only one IOCP at a time. Re-registering a previously-registered socket handle overwrites - /// the existing registration. Before you close a handle used for registration, you should explicitly remove registration, and wait - /// for the SOCK_NOTIFY_EVENT_REMOVE notification (see Remarks in this topic). - /// - /// For more info, and code examples, see Winsock socket state notifications. - /// - /// - /// Type: _In_ HANDLE - /// - /// A handle to an I/O completion port created using the CreateIoCompletionPort function. The port will be used in the - /// CompletionPort parameter of the PostQueuedCompletionStatus function when messages are sent on behalf of the socket. - /// - /// - /// - /// Type: _In_ UINT32 - /// The number of registrations supplied by registrationInfos. - /// - /// - /// Type: _Inout_updates_opt_(registrationCount) SOCK_NOTIFY_REGISTRATION* - /// - /// A pointer to an array of SOCK_NOTIFY_REGISTRATION structures that define the notification registration parameters. These include - /// the socket of interest, the notification events of interest, and the operation flags. On success, you must inspect the elements - /// for whether the registration was processed successfully. This argument must be NULL if registrationCount is 0. - /// - /// - /// - /// Type: _In_ UINT32 - /// - /// The time in milliseconds that you're willing to wait for a completion packet to appear at the completion port. If a completion - /// packet doesn't appear within the specified time, then the function times out and returns ERROR_TIMEOUT. - /// - /// - /// If timeoutMs is INFINITE (0xFFFFFFFF), then the function will never time out. If timeoutMs is 0, and there is no I/O - /// operation to dequeue, then the function will time out immediately. - /// - /// The value of timeoutMs must be 0 if completionCount is 0. - /// - /// - /// Type: _In_ ULONG - /// - /// The maximum number of OVERLAPPED_ENTRY structures to remove. If 0 is specified, then only registration operations will be processed. - /// - /// - /// - /// Type: _Out_writes_to_opt_(completionCount, *receivedEntryCount) OVERLAPPED_ENTRY* - /// - /// On input, points to a pre-allocated array of OVERLAPPED_ENTRY structures. The array mustn't overlap with the registrationInfos - /// array. The value of completionPortEntries must be NULL if completionCount is 0. - /// - /// - /// On output, receives an array of OVERLAPPED_ENTRY structures that hold the entries. The number of array elements is provided by - /// ReceivedEntryCount. The dwNumberOfBytesTransferred fields of the structures are integer masks of received events. The - /// lpOverlapped fields are reserved and must not be used as pointers. - /// - /// - /// - /// Type: _Out_opt_ UINT32* - /// A pointer to a variable that receives the number of entries removed. Must be NULL if completionCount is 0. - /// - /// - /// - /// If successful, returns ERROR_SUCCESS. If the function succeeded and you supplied a non-0 completionCount, but no - /// completion packets appeared within the specified time, returns WAIT_TIMEOUT. Otherwise, returns an appropriate - /// WSAE* error code. - /// - /// - /// If ERROR_SUCCESS or WAIT_TIMEOUT is returned, then you must inspect the individual registration infos' - /// registration results. Otherwise, the entire operation failed, and no changes occurred. - /// - /// - /// See SocketNotificationRetrieveEvents for the events that are possible when a notification is received. - // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-processsocketnotifications DWORD WSAAPI - // ProcessSocketNotifications( HANDLE completionPort, UINT32 registrationCount, SOCK_NOTIFY_REGISTRATION *registrationInfos, UINT32 - // timeoutMs, ULONG completionCount, OVERLAPPED_ENTRY *completionPortEntries, UINT32 *receivedEntryCount ); - [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] - [PInvokeData("winsock2.h", MSDNShortId = "NF:winsock2.ProcessSocketNotifications")] - public static extern uint ProcessSocketNotifications(HFILE completionPort, uint registrationCount, - [In, Out, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] SOCK_NOTIFY_REGISTRATION[] registrationInfos, - uint timeoutMs, uint completionCount, - [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] Kernel32.OVERLAPPED_ENTRY[] completionPortEntries, out uint receivedEntryCount); - - /// - /// - /// Associates a set of sockets with a completion port, and retrieves any notifications that are already pending on that port. Once - /// associated, the completion port receives the socket state notifications that were specified. Only Microsoft Winsock provider - /// sockets are supported. - /// - /// - /// To reduce system call overhead, you can register for notifications and retrieve them in a single call to - /// ProcessSocketNotifications. Alternatively, you can retrieve them explicitly by calling the usual I/O completion port - /// functions, such as GetQueuedCompletionStatus. Notifications retrieved using ProcessSocketNotifications are the same as - /// those retrieved using GetQueuedCompletionStatusEx, which might include notification packets other than socket state changes. - /// - /// - /// The notification event flags are the integer value of the dwNumberOfBytesTransferred fields of the returned OVERLAPPED_ENTRY - /// structures. This is similar to using JOBOBJECT_ASSOCIATE_COMPLETION_PORT, which also uses the dwNumberOfBytesTransferred field - /// to send integer messages. Call the SocketNotificationRetrieveEvents function to obtain them. - /// - /// - /// A socket handle can be registered to only one IOCP at a time. Re-registering a previously-registered socket handle overwrites - /// the existing registration. Before you close a handle used for registration, you should explicitly remove registration, and wait - /// for the SOCK_NOTIFY_EVENT_REMOVE notification (see Remarks in this topic). - /// - /// For more info, and code examples, see Winsock socket state notifications. - /// - /// - /// Type: _In_ HANDLE - /// - /// A handle to an I/O completion port created using the CreateIoCompletionPort function. The port will be used in the - /// CompletionPort parameter of the PostQueuedCompletionStatus function when messages are sent on behalf of the socket. - /// - /// - /// - /// Type: _In_ UINT32 - /// The number of registrations supplied by registrationInfos. - /// - /// - /// Type: _Inout_updates_opt_(registrationCount) SOCK_NOTIFY_REGISTRATION* - /// - /// A pointer to an array of SOCK_NOTIFY_REGISTRATION structures that define the notification registration parameters. These include - /// the socket of interest, the notification events of interest, and the operation flags. On success, you must inspect the elements - /// for whether the registration was processed successfully. This argument must be NULL if registrationCount is 0. - /// - /// - /// - /// Type: _In_ UINT32 - /// - /// The time in milliseconds that you're willing to wait for a completion packet to appear at the completion port. If a completion - /// packet doesn't appear within the specified time, then the function times out and returns ERROR_TIMEOUT. - /// - /// - /// If timeoutMs is INFINITE (0xFFFFFFFF), then the function will never time out. If timeoutMs is 0, and there is no I/O - /// operation to dequeue, then the function will time out immediately. - /// - /// The value of timeoutMs must be 0 if completionCount is 0. - /// - /// - /// Type: _In_ ULONG - /// - /// The maximum number of OVERLAPPED_ENTRY structures to remove. If 0 is specified, then only registration operations will be processed. - /// - /// - /// - /// Type: _Out_writes_to_opt_(completionCount, *receivedEntryCount) OVERLAPPED_ENTRY* - /// - /// On input, points to a pre-allocated array of OVERLAPPED_ENTRY structures. The array mustn't overlap with the registrationInfos - /// array. The value of completionPortEntries must be NULL if completionCount is 0. - /// - /// - /// On output, receives an array of OVERLAPPED_ENTRY structures that hold the entries. The number of array elements is provided by - /// ReceivedEntryCount. The dwNumberOfBytesTransferred fields of the structures are integer masks of received events. The - /// lpOverlapped fields are reserved and must not be used as pointers. - /// - /// - /// - /// Type: _Out_opt_ UINT32* - /// A pointer to a variable that receives the number of entries removed. Must be NULL if completionCount is 0. - /// - /// - /// - /// If successful, returns ERROR_SUCCESS. If the function succeeded and you supplied a non-0 completionCount, but no - /// completion packets appeared within the specified time, returns WAIT_TIMEOUT. Otherwise, returns an appropriate - /// WSAE* error code. - /// - /// - /// If ERROR_SUCCESS or WAIT_TIMEOUT is returned, then you must inspect the individual registration infos' - /// registration results. Otherwise, the entire operation failed, and no changes occurred. - /// - /// - /// See SocketNotificationRetrieveEvents for the events that are possible when a notification is received. - // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-processsocketnotifications DWORD WSAAPI - // ProcessSocketNotifications( HANDLE completionPort, UINT32 registrationCount, SOCK_NOTIFY_REGISTRATION *registrationInfos, UINT32 - // timeoutMs, ULONG completionCount, OVERLAPPED_ENTRY *completionPortEntries, UINT32 *receivedEntryCount ); - [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] - [PInvokeData("winsock2.h", MSDNShortId = "NF:winsock2.ProcessSocketNotifications")] - public static extern Win32Error ProcessSocketNotifications(HFILE completionPort, uint registrationCount, - [In, Out, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] SOCK_NOTIFY_REGISTRATION[] registrationInfos, - uint timeoutMs, [Optional] uint completionCount, [In, Optional] IntPtr completionPortEntries, [In, Optional] IntPtr receivedEntryCount); + SG_CONSTRAINED_GROUP = 0x02 + } + + /// Indicate either big-endian or little-endian with the values 0 and 1 respectively. + [PInvokeData("winsock2.h", MSDNShortId = "be5f3e81-1442-43c7-9e4e-9eb2b2a05132")] + public enum NetworkByteOrder + { + /// The bigendian + BIGENDIAN = 0x0000, + + /// The littleendian + LITTLEENDIAN = 0x0001 + } + + /// Namespace identifier. + [PInvokeData("winsock2.h", MSDNShortId = "cc4ccb2d-ea5a-48bd-a3ae-f70432ab2c39")] + public enum NS + { + /// All installed and active namespaces. + NS_ALL = 0, /// - /// - /// - public static int SOMAXCONN_HINT(int b) => -b; + NS_SAP = 1, + + /// + NS_NDS = 2, + + /// + NS_PEER_BROWSE = 3, + + /// + NS_SLP = 5, + + /// + NS_DHCP = 6, + + /// + NS_TCPIP_LOCAL = 10, + + /// + NS_TCPIP_HOSTS = 11, + + /// The domain name system (DNS) namespace. + NS_DNS = 12, + + /// The NetBIOS over TCP/IP (NETBT) namespace. + NS_NETBT = 13, + + /// The Windows Internet Naming Service (NS_WINS) namespace. + NS_WINS = 14, /// - /// The CSADDR_INFO structure contains Windows Sockets address information for a socket, network service, or namespace provider. + /// The network location awareness (NLA) namespace. + /// This namespace identifier is supported on Windows XP and later. /// - /// - /// The GetAddressByName function obtains Windows Sockets address information using CSADDR_INFO structures. - /// - /// The getsockopt function called with the SO_BSP_STATE socket option retrieves a CSADDR_INFO structure for the specified socket. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/nspapi/ns-nspapi-csaddr_info typedef struct _CSADDR_INFO { SOCKET_ADDRESS - // LocalAddr; SOCKET_ADDRESS RemoteAddr; INT iSocketType; INT iProtocol; } CSADDR_INFO, *PCSADDR_INFO, *LPCSADDR_INFO; - [PInvokeData("nspapi.h", MSDNShortId = "9cad3586-e315-4f6f-9045-7c95502bb768")] - [StructLayout(LayoutKind.Sequential)] - public struct CSADDR_INFO - { - /// - /// Type: SOCKET_ADDRESS - /// The Windows Sockets local address. - /// In a client application, pass this address to the bind function to obtain access to a network service. - /// - /// In a network service, pass this address to the bind function so that the service is bound to the appropriate local address. - /// - /// - public SOCKET_ADDRESS LocalAddr; - - /// - /// Type: SOCKET_ADDRESS - /// Windows Sockets remote address. - /// There are several uses for this remote address: - /// - /// - /// - /// You can use this remote address to connect to the service through the connect function. This is useful if an application - /// performs send/receive operations that involve connection-oriented protocols. - /// - /// - /// - /// - /// You can use this remote address with the sendto function when you are communicating over a connectionless (datagram) - /// protocol. If you are using a connectionless protocol, such as UDP, sendto is typically the way you pass data to the - /// remote system. - /// - /// - /// - /// - public SOCKET_ADDRESS RemoteAddr; - - /// - /// Type: INT - /// The type of Windows socket. Possible values for the socket type are defined in the Winsock2.h header file. - /// The following table lists the possible values supported for Windows Sockets 2: - /// - /// - /// Value - /// Meaning - /// - /// - /// SOCK_STREAM - /// - /// A stream socket. This is a protocol that sends data as a stream of bytes, with no message boundaries. This socket type - /// provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. This socket - /// type uses the Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6). - /// - /// - /// - /// SOCK_DGRAM - /// - /// A datagram socket. This socket type supports datagrams, which are connectionless, unreliable buffers of a fixed (typically - /// small) maximum length. This socket type uses the User Datagram Protocol (UDP) for the Internet address family (AF_INET or - /// AF_INET6). Services use recvfrom function to obtain datagrams. The listen and accept functions do not work with datagrams. - /// - /// - /// - /// SOCK_RDM - /// - /// A reliable message datagram socket. This socket type preserves message boundaries in data. An example of this type is the - /// Pragmatic General Multicast (PGM) multicast protocol implementation in Windows, often referred to as reliable multicast programming. - /// - /// - /// - /// SOCK_SEQPACKET - /// A sequenced packet stream socket. This socket type provides a pseudo-stream packet based on datagrams. - /// - /// - /// - public SOCK iSocketType; - - /// - /// Type: INT - /// - /// The protocol used. The possible options for the protocol parameter are specific to the address family and socket type - /// specified. Possible values are defined in the Winsock2.h and Wsrm.h header files. - /// - /// - /// On the Windows SDK released for Windows Vista and later, the organization of header files has changed and this parameter can - /// be one of the values from the IPPROTO enumeration type defined in the Ws2def.h header file. Note that the Ws2def.h - /// header file is automatically included in Winsock2.h, and should never be used directly. - /// - /// The table below lists common values for the protocol although many other values are possible. - /// - /// - /// protocol - /// Meaning - /// - /// - /// IPPROTO_TCP 6 - /// - /// The Transmission Control Protocol (TCP). This is a possible value when the address family is AF_INET or AF_INET6 and the - /// iSocketType member is SOCK_STREAM. - /// - /// - /// - /// IPPROTO_UDP 17 - /// - /// The User Datagram Protocol (UDP). This is a possible value when the address family is AF_INET or AF_INET6 and the - /// iSocketType member is SOCK_DGRAM. - /// - /// - /// - /// IPPROTO_RM 113 - /// - /// The PGM protocol for reliable multicast. This is a possible value when the address family is AF_INET and the iSocketType - /// member is SOCK_RDM. On the Windows SDK released for Windows Vista and later, this value is also called IPPROTO_PGM. - /// - /// - /// - /// - public IPPROTO iProtocol; - } - - /// The IN_ADDR structure represents an IPv4 address. - [PInvokeData("winsock2.h")] - [StructLayout(LayoutKind.Sequential)] - public struct IN_ADDR : IEquatable - { - /// An IPv4 address formatted as a u_long. - public uint S_addr; - - /// Initializes a new instance of the struct. - /// An IPv4 address. - public IN_ADDR(uint v4addr) => S_addr = v4addr; - - /// Initializes a new instance of the struct. - /// An IPv4 address - /// Byte array must have 4 items. - v4addr - public IN_ADDR(byte[] v4addr) - { - if (v4addr == null || v4addr.Length < 4) - throw new ArgumentException("Byte array must have 4 items.", nameof(v4addr)); - S_addr = BitConverter.ToUInt32(v4addr, 0); - } - - /// Initializes a new instance of the struct. - /// The first byte. - /// The second byte. - /// The third byte. - /// The fourth byte. - public IN_ADDR(byte b1, byte b2, byte b3, byte b4) => S_addr = b1 | (uint)b2 << 8 | (uint)b3 << 16 | (uint)b4 << 24; - - /// Gets the address represented as four bytes. - /// An IPv4 address formatted as four u_chars. - public byte[] S_un_b => BitConverter.GetBytes(S_addr); - - /// - public static readonly IN_ADDR INADDR_ANY = new(0U); - - /// - public static readonly IN_ADDR INADDR_LOOPBACK = new(0x7f000001); - - /// - public static readonly IN_ADDR INADDR_BROADCAST = new(0xffffffff); - - /// - public static readonly IN_ADDR INADDR_NONE = new(0xffffffff); - - /// Implements the operator ==. - /// The left. - /// The right. - /// The result of the operator. - public static bool operator ==(IN_ADDR left, IN_ADDR right) => left.Equals(right); - - /// Implements the operator !=. - /// The left. - /// The right. - /// The result of the operator. - public static bool operator !=(IN_ADDR left, IN_ADDR right) => !left.Equals(right); - - /// Performs an implicit conversion from to . - /// An IN_ADDR value. - /// The result of the conversion. - public static implicit operator uint(IN_ADDR a) => a.S_addr; - - /// Performs an implicit conversion from to . - /// An IN_ADDR value. - /// The result of the conversion. - public static implicit operator long(IN_ADDR a) => a.S_addr; - - /// Performs an implicit conversion from to . - /// An IN_ADDR value. - /// The result of the conversion. - public static implicit operator byte[](IN_ADDR a) => BitConverter.GetBytes(a.S_addr); - - /// Performs an implicit conversion from to . - /// A UInt32 value. - /// The result of the conversion. - public static implicit operator IN_ADDR(uint a) => new(a); - - /// Performs an implicit conversion from to . - /// An Int64 value. - /// The result of the conversion. - public static implicit operator IN_ADDR(long a) => new((uint)a); - - /// Performs an explicit conversion from to . - /// The ipv4. - /// The resulting instance from the conversion. - public static explicit operator IN6_ADDR(IN_ADDR ipv4) => new(ipv4); - - /// Determines equality between this instance and . - /// The other value to compare. - /// if is equal to this instance. - public bool Equals(IN_ADDR other) => S_addr == other.S_addr; - - /// Determines whether the specified , is equal to this instance. - /// The to compare with this instance. - /// if the specified is equal to this instance; otherwise, . - public override bool Equals(object obj) => obj is IN_ADDR i ? Equals(i) : base.Equals(obj); - - /// Returns a hash code for this instance. - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - public override int GetHashCode() => S_addr.GetHashCode(); - - /// Returns a that represents this instance. - /// A that represents this instance. - public override string ToString() - { - var b = S_un_b; - return $"{b[0]}.{b[1]}.{b[2]}.{b[3]}"; - } - } - - /// The IN6_ADDR structure represents an IPv6 address. - [PInvokeData("winsock2.h")] - [StructLayout(LayoutKind.Sequential, Size = IN6_ADDR_SIZE)] - public struct IN6_ADDR : IEquatable - { - private const int IN6_ADDR_SIZE = 16; - - private ulong lower; - private ulong upper; - - /// The IPv6 standard loopback address (IN6ADDR_LOOPBACK_INIT). - public static readonly IN6_ADDR Loopback = new(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }); - - /// The IPv6 standard unspecified address (IN6ADDR_ANY_INIT). - public static readonly IN6_ADDR Unspecified = new(); - - /// Initializes a new instance of the struct. - /// The IPv6 address as an array of bytes. - public IN6_ADDR(byte[] v6addr) - { - lower = upper = 0; - bytes = v6addr; - } - - /// Initializes a new instance of the struct from an . - /// The ipv4 address. - public IN6_ADDR(IN_ADDR ipv4) - { - lower = 0; - upper = Macros.MAKELONG64(0xffff0000, ipv4.S_addr); - } - - /// Gets or sets the byte array representing the IPv6 address. - /// The bytes. - /// Byte array must have 16 items. - value - public byte[] bytes - { - get - { - unsafe - { - var v6addr = new byte[IN6_ADDR_SIZE]; - fixed (byte* usp = &v6addr[0]) - { - var ulp2 = (ulong*)usp; - ulp2[0] = lower; - ulp2[1] = upper; - } - return v6addr; - } - } - set - { - unsafe - { - if (value == null) value = new byte[IN6_ADDR_SIZE]; - if (value.Length != IN6_ADDR_SIZE) - throw new ArgumentException("Byte array must have 16 items.", nameof(value)); - fixed (byte* bp = &value[0]) - { - var ulp = (ulong*)bp; - lower = ulp[0]; - upper = ulp[1]; - } - } - } - } - - /// Gets a value indicating whether this instance is an anycast address. - /// if this instance is an anycast address; otherwise, . - public bool IsAnycast => IsSubnetRerservedAnycast || IsSubnetRouterAnycast; - - /// Gets a value indicating whether this instance uses EUI-64 interface identifiers. - /// if this instance uses EUI-64 interface identifiers; otherwise, . - public bool IsEUI64 => (bytes[0] & 0xe0) != 0 && !IsMulticast; - - /// Gets a value indicating whether this instance is a global address. - /// if this instance is a global address; otherwise, . - public bool IsGlobal - { - get - { - var High = bytes[0] & 0xf0u; - return High != 0 && High != 0xf0; - } - } - - /// Gets a value indicating whether this instance is a link local address. - /// if this instance is a link local address; otherwise, . - public bool IsLinkLocal - { - get - { - var b = bytes; - return b[0] == 0xfe && (b[1] & 0xc0) == 0x80; - } - } - - /// Gets a value indicating whether this instance is a LOOPBACK address. - /// if this instance is a LOOPBACK address; otherwise, . - public bool IsLoopback => Equals(Loopback); - - /// Gets a value indicating whether this instance is a MULTICAST address. - /// if this instance is a MULTICAST address; otherwise, . - public bool IsMulticast => bytes[0] == 0xff; - - /// Gets a value indicating whether this instance is a site local address. - /// if this instance is a site local address; otherwise, . - public bool IsSiteLocal - { - get - { - var b = bytes; - return b[0] == 0xfe && (b[1] & 0xc0) == 0xc0; - } - } - - /// Gets a value indicating whether the subnet router anycast address. - /// if the subnet router anycast address; otherwise, . - public bool IsSubnetRouterAnycast => IsEUI64 && upper == 0; - - /// Gets a value indicating whether the subnet reserved anycast address. - /// if the subnet reserved anycast address; otherwise, . - public bool IsSubnetRerservedAnycast - { - get - { - var w = words; - return IsEUI64 && w[4] == 0xfffd && w[5] == 0xffff && w[6] == 0xffff && (w[7] & 0x80ff) == 0x80ff; - } - } - - /// Gets a value indicating whether this instance is an UNSPECIFIED address. - /// if this instance is an UNSPECIFIED address; otherwise, . - public bool IsUnspecified => Equals(Unspecified); - - /// Gets a value indicating whether this instance is an IPv4 compatible address. - /// if this instance is an IPv4 compatible address; otherwise, . - public bool IsV4Compatible - { - get - { - var w = words; - var b = bytes; - return lower == 0 && w[4] == 0 && w[5] == 0 && w[6] == 0 && b[14] == 0 && (b[15] == 0 || b[15] == 1); - } - } - - /// Gets a value indicating whether this instance is an IPv4 mapped address. - /// if this instance is an IPv4 mapped address; otherwise, . - public bool IsV4Mapped - { - get - { - var w = words; - return lower == 0 && w[4] == 0 && w[5] == 0xffff; - } - } - - /// Gets a value indicating whether this instance is an IPv4 translated address. - /// if this instance is an IPv4 translated address; otherwise, . - public bool IsV4Translated - { - get - { - var w = words; - return lower == 0 && w[4] == 0xffff && w[5] == 0; - } - } - - /// Gets or sets the array of WORD (ushort) values representing the IPv6 address. - /// The array of WORD values. - /// UInt16 array must have 8 items. - value - public ushort[] words - { - get - { - unsafe - { - var v6addr = new ushort[IN6_ADDR_SIZE / 2]; - fixed (ushort* usp = &v6addr[0]) - { - var ulp2 = (ulong*)usp; - ulp2[0] = lower; - ulp2[1] = upper; - } - return v6addr; - } - } - set - { - unsafe - { - if (value == null) value = new ushort[IN6_ADDR_SIZE / 2]; - if (value.Length != IN6_ADDR_SIZE / 2) - throw new ArgumentException("UInt16 array must have 8 items.", nameof(value)); - fixed (ushort* bp = &value[0]) - { - var ulp = (ulong*)bp; - lower = ulp[0]; - upper = ulp[1]; - } - } - } - } - - /// Implements the operator ==. - /// The left. - /// The right. - /// The result of the operator. - public static bool operator ==(IN6_ADDR left, IN6_ADDR right) => left.Equals(right); - - /// Implements the operator !=. - /// The left. - /// The right. - /// The result of the operator. - public static bool operator !=(IN6_ADDR left, IN6_ADDR right) => !left.Equals(right); - - /// Performs an implicit conversion from [] to . - /// The byte array. - /// The resulting instance from the conversion. - public static implicit operator IN6_ADDR(byte[] a) => new(a); - - /// Performs an implicit conversion from to []. - /// The instance. - /// The resulting [] instance from the conversion. - public static implicit operator byte[](IN6_ADDR a) => a.bytes; - - /// Determines whether the specified , is equal to this instance. - /// The to compare with this instance. - /// if the specified is equal to this instance; otherwise, . - public override bool Equals(object obj) => obj is IN6_ADDR i ? Equals(i) : base.Equals(obj); - - /// Returns a hash code for this instance. - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - public override int GetHashCode() => (lower, upper).GetHashCode(); - - /// Converts to string. - /// A that represents this instance. - public override string ToString() - { - const string numberFormat = "{0:x4}:{1:x4}:{2:x4}:{3:x4}:{4:x4}:{5:x4}:{6}.{7}.{8}.{9}"; - var m_Numbers = words; - return string.Format(System.Globalization.CultureInfo.InvariantCulture, numberFormat, - m_Numbers[0], m_Numbers[1], m_Numbers[2], m_Numbers[3], m_Numbers[4], m_Numbers[5], - (m_Numbers[6] >> 8) & 0xFF, m_Numbers[6] & 0xFF, (m_Numbers[7] >> 8) & 0xFF, m_Numbers[7] & 0xFF); - } - - /// Determines whether the specified value is equal to this instance. - /// The value to compare with this instance. - /// if the specified value is equal to this instance; otherwise, . - public bool Equals(IN6_ADDR other) => lower == other.lower && upper == other.upper; - } + NS_NLA = 15, /// - /// The linger structure maintains information about a specific socket that specifies how that socket should behave when data - /// is queued to be sent and the closesocket function is called on the socket. + /// The Bluetooth namespace. + /// This namespace identifier is supported on Windows Vista and later. /// - /// + NS_BTH = 16, + + /// + NS_LOCALNAME = 19, + + /// + NS_NBP = 20, + + /// + NS_MS = 30, + + /// + NS_STDA = 31, + + /// The Windows NT Directory Services (NS_NTDS) namespace. + NS_NTDS = 32, + + /// + /// The email namespace. + /// This namespace identifier is supported on Windows Vista and later. + /// + NS_EMAIL = 37, + + /// + /// The peer-to-peer namespace for a specific peer name. + /// This namespace identifier is supported on Windows Vista and later. + /// + NS_PNRPNAME = 38, + + /// + /// The peer-to-peer namespace for a collection of peer names. + /// This namespace identifier is supported on Windows Vista and later. + /// + NS_PNRPCLOUD = 39, + + /// + NS_X500 = 40, + + /// + NS_NIS = 41, + + /// + NS_NISPLUS = 42, + + /// + NS_WRQ = 50, + + /// + NS_NETDES = 60 + } + + /// A set of flags that provides information on how this protocol is represented in the Winsock catalog. + [PInvokeData("winsock2.h", MSDNShortId = "be5f3e81-1442-43c7-9e4e-9eb2b2a05132")] + [Flags] + public enum PFL : uint + { + /// + /// Indicates that this is one of two or more entries for a single protocol (from a given provider) which is capable of + /// implementing multiple behaviors. An example of this is SPX which, on the receiving side, can behave either as a + /// message-oriented or a stream-oriented protocol. + /// + PFL_MULTIPLE_PROTO_ENTRIES = 0x00000001, + + /// + /// Indicates that this is the recommended or most frequently used entry for a protocol that is capable of implementing multiple behaviors. + /// + PFL_RECOMMENDED_PROTO_ENTRY = 0x00000002, + + /// + /// Set by a provider to indicate to the Ws2_32.dll that this protocol should not be returned in the result buffer generated by + /// WSAEnumProtocols. Obviously, a Windows Sockets 2 application should never see an entry with this bit set. + /// + PFL_HIDDEN = 0x00000004, + + /// Indicates that a value of zero in the protocol parameter of socket or WSASocket matches this protocol entry. + PFL_MATCHES_PROTOCOL_ZERO = 0x00000008, + + /// + /// Set by a provider to indicate support for network direct access. + /// This value is supported on Windows 7 and Windows Server 2008 R2. + /// + PFL_NETWORKDIRECT_PROVIDER = 0x00000010, + } + + /// The type specification for the new socket. + [PInvokeData("winsock2.h", MSDNShortId = "6bf6e6c4-6268-479c-86a6-52e90cf317db")] + public enum SOCK + { + /// + /// A socket type that provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission + /// mechanism. This socket type uses the Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6). + /// + SOCK_STREAM = 1, + + /// + /// A socket type that supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum + /// length. This socket type uses the User Datagram Protocol (UDP) for the Internet address family (AF_INET or AF_INET6). + /// + SOCK_DGRAM = 2, + + /// + /// A socket type that provides a raw socket that allows an application to manipulate the next upper-layer protocol header. To + /// manipulate the IPv4 header, the IP_HDRINCL socket option must be set on the socket. To manipulate the IPv6 header, the + /// IPV6_HDRINCL socket option must be set on the socket. + /// + SOCK_RAW = 3, + + /// + /// A socket type that provides a reliable message datagram. An example of this type is the Pragmatic General Multicast (PGM) + /// multicast protocol implementation in Windows, often referred to as reliable multicast programming. + /// This type value is only supported if the Reliable Multicast Protocol is installed. + /// + SOCK_RDM = 4, + + /// A socket type that provides a pseudo-stream packet based on datagrams. + SOCK_SEQPACKET = 5, + } + + /// a bitmask of the notification events for the socket. + [PInvokeData("winsock2.h", MSDNShortId = "NS:winsock2.SOCK_NOTIFY_REGISTRATION")] + [Flags] + public enum SOCK_NOTIFY_EVENT : ushort + { + /// Input is available from the socket without blocking. + SOCK_NOTIFY_EVENT_IN = SOCK_NOTIFY_REGISTER_EVENT.SOCK_NOTIFY_REGISTER_EVENT_IN, + + /// Output can be provided to the socket without blocking. + SOCK_NOTIFY_EVENT_OUT = SOCK_NOTIFY_REGISTER_EVENT.SOCK_NOTIFY_REGISTER_EVENT_OUT, + + /// The socket connection has terminated. + SOCK_NOTIFY_EVENT_HANGUP = SOCK_NOTIFY_REGISTER_EVENT.SOCK_NOTIFY_REGISTER_EVENT_HANGUP, + + /// The socket is in an error state. + SOCK_NOTIFY_EVENT_ERR = 0x40, + + /// The notification has been deregistered. + SOCK_NOTIFY_EVENT_REMOVE = 0x80, + + /// All events. + SOCK_NOTIFY_EVENTS_ALL = SOCK_NOTIFY_REGISTER_EVENT.SOCK_NOTIFY_REGISTER_EVENTS_ALL | SOCK_NOTIFY_EVENT_ERR | SOCK_NOTIFY_EVENT_REMOVE, + } + + /// Indicates the operation to perform on a registration. At most one operation may be performed at a time. + [PInvokeData("winsock2.h", MSDNShortId = "NS:winsock2.SOCK_NOTIFY_REGISTRATION")] + [Flags] + public enum SOCK_NOTIFY_OP : byte + { + /// + /// No registration operations should take place. Use this if your application calls ProcessSocketNotifications and is only + /// interested in receiving notifications. + /// + SOCK_NOTIFY_OP_NONE = 0x00, + + /// + /// Enables the registration. Notifications must not be re-enabled until the SOCK_NOTIFY_EVENT_DISABLE notification is received. + /// + SOCK_NOTIFY_OP_ENABLE = 0x01, + + /// + /// Disables the registration, but doesn't destroy the underlying data structures. Note that this doesn't remove the + /// registration, it merely suppresses queuing of new notifications. Notifications that have already been queued might still be + /// delivered until the SOCK_NOTIFY_EVENT_DISABLE event is received. + /// + SOCK_NOTIFY_OP_DISABLE = 0x02, + + /// + /// Removes a previously-registered notification. Both enabled and disabled notifications may be removed. The + /// SOCK_NOTIFY_EVENT_REMOVE notification is issued, with the guarantee that no more notifications will be issued afterwards for + /// that completion key unless it is re-registered. + /// + SOCK_NOTIFY_OP_REMOVE = 0x04, + } + + /// A set of flags indicating the notifications being requested. + [PInvokeData("winsock2.h", MSDNShortId = "NS:winsock2.SOCK_NOTIFY_REGISTRATION")] + [Flags] + public enum SOCK_NOTIFY_REGISTER_EVENT : ushort + { + /// Notifications should not be issued. + SOCK_NOTIFY_REGISTER_EVENT_NONE = 0x00, + + /// A notification should be issued when data can be read without blocking. + SOCK_NOTIFY_REGISTER_EVENT_IN = 0x01, + + /// A notification should be issued when data can be written without blocking. + SOCK_NOTIFY_REGISTER_EVENT_OUT = 0x02, + + /// A notification should be issued when a stream-oriented connection was either disconnected or aborted. + SOCK_NOTIFY_REGISTER_EVENT_HANGUP = 0x04, + + /// All flags. + SOCK_NOTIFY_REGISTER_EVENTS_ALL = SOCK_NOTIFY_REGISTER_EVENT_IN | SOCK_NOTIFY_REGISTER_EVENT_OUT | SOCK_NOTIFY_REGISTER_EVENT_HANGUP + } + + /// A set of flags indicating the trigger behavior. + [PInvokeData("winsock2.h", MSDNShortId = "NS:winsock2.SOCK_NOTIFY_REGISTRATION")] + [Flags] + public enum SOCK_NOTIFY_TRIGGER : byte + { + /// The registration will be disabled (not removed) upon delivery of the next notification. + SOCK_NOTIFY_TRIGGER_ONESHOT = 0x01, + + /// The registration will remain active until it is explicitly disabled or removed. + SOCK_NOTIFY_TRIGGER_PERSISTENT = 0x02, + + /// + /// The registration is for level-triggered notifications. Not compatible with edge-triggered. One of edge- or level-triggered + /// must be supplied. + /// + SOCK_NOTIFY_TRIGGER_LEVEL = 0x04, + + /// + /// The registration is for edge-triggered notifications. Not compatible with level-triggered. One of edge- or level-triggered + /// must be supplied. + /// + SOCK_NOTIFY_TRIGGER_EDGE = 0x08, + + /// All triggers. + SOCK_NOTIFY_TRIGGER_ALL = SOCK_NOTIFY_TRIGGER_ONESHOT | SOCK_NOTIFY_TRIGGER_PERSISTENT | SOCK_NOTIFY_TRIGGER_LEVEL | SOCK_NOTIFY_TRIGGER_EDGE, + } + + /// + /// The Windows Sockets WSAECOMPARATOR enumeration type is used for version-comparison semantics in Windows Sockets 2. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/ne-winsock2-wsaecomparator typedef enum _WSAEcomparator { COMP_EQUAL, + // COMP_NOTLESS } WSAECOMPARATOR, *PWSAECOMPARATOR, *LPWSAECOMPARATOR; + [PInvokeData("winsock2.h", MSDNShortId = "a1de171e-42d7-4d57-b241-1db9989dbd8e")] + public enum WSAECOMPARATOR + { + /// Used for determining whether version values are equal. + COMP_EQUAL, + + /// Used for determining whether a version value is no less than a specified value. + COMP_NOTLESS, + } + + /// A value that determines that operation requested. + [PInvokeData("winsock2.h")] + public enum WSAESETSERVICEOP + { + /// + /// Register the service. For SAP, this means sending out a periodic broadcast. This is an NOP for the DNS namespace. For + /// persistent data stores, this means updating the address information. + /// + RNRSERVICE_REGISTER = 0, + + /// + /// Remove the service from the registry. For SAP, this means stop sending out the periodic broadcast. This is an NOP for the + /// DNS namespace. For persistent data stores this means deleting address information. + /// + RNRSERVICE_DEREGISTER, + + /// + /// Delete the service from dynamic name and persistent spaces. For services represented by multiple CSADDR_INFO structures + /// (using the SERVICE_MULTIPLE flag), only the specified address will be deleted, and this must match exactly the corresponding + /// CSADDR_INFO structure that was specified when the service was registered. + /// + RNRSERVICE_DELETE + } + + /// A bitmask that describes the services provided by the protocol. + [PInvokeData("winsock2.h", MSDNShortId = "be5f3e81-1442-43c7-9e4e-9eb2b2a05132")] + [Flags] + public enum XP1 + { + /// Provides connectionless (datagram) service. If not set, the protocol supports connection-oriented data transfer. + XP1_CONNECTIONLESS = 0x00000001, + + /// Guarantees that all data sent will reach the intended destination. + XP1_GUARANTEED_DELIVERY = 0x00000002, + + /// + /// Guarantees that data only arrives in the order in which it was sent and that it is not duplicated. This characteristic does + /// not necessarily mean that the data is always delivered, but that any data that is delivered is delivered in the order in + /// which it was sent. + /// + XP1_GUARANTEED_ORDER = 0x00000004, + + /// Honors message boundaries—as opposed to a stream-oriented protocol where there is no concept of message boundaries. + XP1_MESSAGE_ORIENTED = 0x00000008, + + /// + /// A message-oriented protocol, but message boundaries are ignored for all receipts. This is convenient when an application + /// does not desire message framing to be done by the protocol. + /// + XP1_PSEUDO_STREAM = 0x00000010, + + /// Supports two-phase (graceful) close. If not set, only abortive closes are performed. + XP1_GRACEFUL_CLOSE = 0x00000020, + + /// Supports expedited (urgent) data. + XP1_EXPEDITED_DATA = 0x00000040, + + /// Supports connect data. + XP1_CONNECT_DATA = 0x00000080, + + /// Supports disconnect data. + XP1_DISCONNECT_DATA = 0x00000100, + + /// Supports a broadcast mechanism. + XP1_SUPPORT_BROADCAST = 0x00000200, + + /// Supports a multipoint or multicast mechanism. Control and data plane attributes are indicated below. + XP1_SUPPORT_MULTIPOINT = 0x00000400, + + /// Indicates whether the control plane is rooted (value = 1) or nonrooted (value = 0). + XP1_MULTIPOINT_CONTROL_PLANE = 0x00000800, + + /// Indicates whether the data plane is rooted (value = 1) or nonrooted (value = 0). + XP1_MULTIPOINT_DATA_PLANE = 0x00001000, + + /// Supports quality of service requests. + XP1_QOS_SUPPORTED = 0x00002000, + + /// Bit is reserved. + XP1_INTERRUPT = 0x00004000, + + /// Protocol is unidirectional in the send direction. + XP1_UNI_SEND = 0x00008000, + + /// Protocol is unidirectional in the recv direction. + XP1_UNI_RECV = 0x00010000, + + /// Socket descriptors returned by the provider are operating system Installable File System (IFS) handles. + XP1_IFS_HANDLES = 0x00020000, + + /// The MSG_PARTIAL flag is supported in WSASend and WSASendTo. + XP1_PARTIAL_MESSAGE = 0x00040000, + + /// + /// The protocol provides support for SAN. + /// This value is supported on Windows 7 and Windows Server 2008 R2. + /// + XP1_SAN_SUPPORT_SDP = 0x00080000, + } + + /// + /// + /// Associates a set of sockets with a completion port, and retrieves any notifications that are already pending on that port. Once + /// associated, the completion port receives the socket state notifications that were specified. Only Microsoft Winsock provider + /// sockets are supported. + /// + /// + /// To reduce system call overhead, you can register for notifications and retrieve them in a single call to + /// ProcessSocketNotifications. Alternatively, you can retrieve them explicitly by calling the usual I/O completion port + /// functions, such as GetQueuedCompletionStatus. Notifications retrieved using ProcessSocketNotifications are the same as + /// those retrieved using GetQueuedCompletionStatusEx, which might include notification packets other than socket state changes. + /// + /// + /// The notification event flags are the integer value of the dwNumberOfBytesTransferred fields of the returned OVERLAPPED_ENTRY + /// structures. This is similar to using JOBOBJECT_ASSOCIATE_COMPLETION_PORT, which also uses the dwNumberOfBytesTransferred field + /// to send integer messages. Call the SocketNotificationRetrieveEvents function to obtain them. + /// + /// + /// A socket handle can be registered to only one IOCP at a time. Re-registering a previously-registered socket handle overwrites + /// the existing registration. Before you close a handle used for registration, you should explicitly remove registration, and wait + /// for the SOCK_NOTIFY_EVENT_REMOVE notification (see Remarks in this topic). + /// + /// For more info, and code examples, see Winsock socket state notifications. + /// + /// + /// Type: _In_ HANDLE + /// + /// A handle to an I/O completion port created using the CreateIoCompletionPort function. The port will be used in the + /// CompletionPort parameter of the PostQueuedCompletionStatus function when messages are sent on behalf of the socket. + /// + /// + /// + /// Type: _In_ UINT32 + /// The number of registrations supplied by registrationInfos. + /// + /// + /// Type: _Inout_updates_opt_(registrationCount) SOCK_NOTIFY_REGISTRATION* + /// + /// A pointer to an array of SOCK_NOTIFY_REGISTRATION structures that define the notification registration parameters. These include + /// the socket of interest, the notification events of interest, and the operation flags. On success, you must inspect the elements + /// for whether the registration was processed successfully. This argument must be NULL if registrationCount is 0. + /// + /// + /// + /// Type: _In_ UINT32 + /// + /// The time in milliseconds that you're willing to wait for a completion packet to appear at the completion port. If a completion + /// packet doesn't appear within the specified time, then the function times out and returns ERROR_TIMEOUT. + /// + /// + /// If timeoutMs is INFINITE (0xFFFFFFFF), then the function will never time out. If timeoutMs is 0, and there is no I/O + /// operation to dequeue, then the function will time out immediately. + /// + /// The value of timeoutMs must be 0 if completionCount is 0. + /// + /// + /// Type: _In_ ULONG + /// + /// The maximum number of OVERLAPPED_ENTRY structures to remove. If 0 is specified, then only registration operations will be processed. + /// + /// + /// + /// Type: _Out_writes_to_opt_(completionCount, *receivedEntryCount) OVERLAPPED_ENTRY* + /// + /// On input, points to a pre-allocated array of OVERLAPPED_ENTRY structures. The array mustn't overlap with the registrationInfos + /// array. The value of completionPortEntries must be NULL if completionCount is 0. + /// + /// + /// On output, receives an array of OVERLAPPED_ENTRY structures that hold the entries. The number of array elements is provided by + /// ReceivedEntryCount. The dwNumberOfBytesTransferred fields of the structures are integer masks of received events. The + /// lpOverlapped fields are reserved and must not be used as pointers. + /// + /// + /// + /// Type: _Out_opt_ UINT32* + /// A pointer to a variable that receives the number of entries removed. Must be NULL if completionCount is 0. + /// + /// + /// + /// If successful, returns ERROR_SUCCESS. If the function succeeded and you supplied a non-0 completionCount, but no + /// completion packets appeared within the specified time, returns WAIT_TIMEOUT. Otherwise, returns an appropriate + /// WSAE* error code. + /// + /// + /// If ERROR_SUCCESS or WAIT_TIMEOUT is returned, then you must inspect the individual registration infos' + /// registration results. Otherwise, the entire operation failed, and no changes occurred. + /// + /// + /// See SocketNotificationRetrieveEvents for the events that are possible when a notification is received. + // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-processsocketnotifications DWORD WSAAPI + // ProcessSocketNotifications( HANDLE completionPort, UINT32 registrationCount, SOCK_NOTIFY_REGISTRATION *registrationInfos, UINT32 + // timeoutMs, ULONG completionCount, OVERLAPPED_ENTRY *completionPortEntries, UINT32 *receivedEntryCount ); + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winsock2.h", MSDNShortId = "NF:winsock2.ProcessSocketNotifications")] + public static extern uint ProcessSocketNotifications(HFILE completionPort, uint registrationCount, + [In, Out, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] SOCK_NOTIFY_REGISTRATION[] registrationInfos, + uint timeoutMs, uint completionCount, + [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] Kernel32.OVERLAPPED_ENTRY[] completionPortEntries, out uint receivedEntryCount); + + /// + /// + /// Associates a set of sockets with a completion port, and retrieves any notifications that are already pending on that port. Once + /// associated, the completion port receives the socket state notifications that were specified. Only Microsoft Winsock provider + /// sockets are supported. + /// + /// + /// To reduce system call overhead, you can register for notifications and retrieve them in a single call to + /// ProcessSocketNotifications. Alternatively, you can retrieve them explicitly by calling the usual I/O completion port + /// functions, such as GetQueuedCompletionStatus. Notifications retrieved using ProcessSocketNotifications are the same as + /// those retrieved using GetQueuedCompletionStatusEx, which might include notification packets other than socket state changes. + /// + /// + /// The notification event flags are the integer value of the dwNumberOfBytesTransferred fields of the returned OVERLAPPED_ENTRY + /// structures. This is similar to using JOBOBJECT_ASSOCIATE_COMPLETION_PORT, which also uses the dwNumberOfBytesTransferred field + /// to send integer messages. Call the SocketNotificationRetrieveEvents function to obtain them. + /// + /// + /// A socket handle can be registered to only one IOCP at a time. Re-registering a previously-registered socket handle overwrites + /// the existing registration. Before you close a handle used for registration, you should explicitly remove registration, and wait + /// for the SOCK_NOTIFY_EVENT_REMOVE notification (see Remarks in this topic). + /// + /// For more info, and code examples, see Winsock socket state notifications. + /// + /// + /// Type: _In_ HANDLE + /// + /// A handle to an I/O completion port created using the CreateIoCompletionPort function. The port will be used in the + /// CompletionPort parameter of the PostQueuedCompletionStatus function when messages are sent on behalf of the socket. + /// + /// + /// + /// Type: _In_ UINT32 + /// The number of registrations supplied by registrationInfos. + /// + /// + /// Type: _Inout_updates_opt_(registrationCount) SOCK_NOTIFY_REGISTRATION* + /// + /// A pointer to an array of SOCK_NOTIFY_REGISTRATION structures that define the notification registration parameters. These include + /// the socket of interest, the notification events of interest, and the operation flags. On success, you must inspect the elements + /// for whether the registration was processed successfully. This argument must be NULL if registrationCount is 0. + /// + /// + /// + /// Type: _In_ UINT32 + /// + /// The time in milliseconds that you're willing to wait for a completion packet to appear at the completion port. If a completion + /// packet doesn't appear within the specified time, then the function times out and returns ERROR_TIMEOUT. + /// + /// + /// If timeoutMs is INFINITE (0xFFFFFFFF), then the function will never time out. If timeoutMs is 0, and there is no I/O + /// operation to dequeue, then the function will time out immediately. + /// + /// The value of timeoutMs must be 0 if completionCount is 0. + /// + /// + /// Type: _In_ ULONG + /// + /// The maximum number of OVERLAPPED_ENTRY structures to remove. If 0 is specified, then only registration operations will be processed. + /// + /// + /// + /// Type: _Out_writes_to_opt_(completionCount, *receivedEntryCount) OVERLAPPED_ENTRY* + /// + /// On input, points to a pre-allocated array of OVERLAPPED_ENTRY structures. The array mustn't overlap with the registrationInfos + /// array. The value of completionPortEntries must be NULL if completionCount is 0. + /// + /// + /// On output, receives an array of OVERLAPPED_ENTRY structures that hold the entries. The number of array elements is provided by + /// ReceivedEntryCount. The dwNumberOfBytesTransferred fields of the structures are integer masks of received events. The + /// lpOverlapped fields are reserved and must not be used as pointers. + /// + /// + /// + /// Type: _Out_opt_ UINT32* + /// A pointer to a variable that receives the number of entries removed. Must be NULL if completionCount is 0. + /// + /// + /// + /// If successful, returns ERROR_SUCCESS. If the function succeeded and you supplied a non-0 completionCount, but no + /// completion packets appeared within the specified time, returns WAIT_TIMEOUT. Otherwise, returns an appropriate + /// WSAE* error code. + /// + /// + /// If ERROR_SUCCESS or WAIT_TIMEOUT is returned, then you must inspect the individual registration infos' + /// registration results. Otherwise, the entire operation failed, and no changes occurred. + /// + /// + /// See SocketNotificationRetrieveEvents for the events that are possible when a notification is received. + // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-processsocketnotifications DWORD WSAAPI + // ProcessSocketNotifications( HANDLE completionPort, UINT32 registrationCount, SOCK_NOTIFY_REGISTRATION *registrationInfos, UINT32 + // timeoutMs, ULONG completionCount, OVERLAPPED_ENTRY *completionPortEntries, UINT32 *receivedEntryCount ); + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] + [PInvokeData("winsock2.h", MSDNShortId = "NF:winsock2.ProcessSocketNotifications")] + public static extern Win32Error ProcessSocketNotifications(HFILE completionPort, uint registrationCount, + [In, Out, Optional, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] SOCK_NOTIFY_REGISTRATION[] registrationInfos, + uint timeoutMs, [Optional] uint completionCount, [In, Optional] IntPtr completionPortEntries, [In, Optional] IntPtr receivedEntryCount); + + /// + /// + /// + public static int SOMAXCONN_HINT(int b) => -b; + + /// + /// The CSADDR_INFO structure contains Windows Sockets address information for a socket, network service, or namespace provider. + /// + /// + /// The GetAddressByName function obtains Windows Sockets address information using CSADDR_INFO structures. + /// + /// The getsockopt function called with the SO_BSP_STATE socket option retrieves a CSADDR_INFO structure for the specified socket. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/nspapi/ns-nspapi-csaddr_info typedef struct _CSADDR_INFO { SOCKET_ADDRESS + // LocalAddr; SOCKET_ADDRESS RemoteAddr; INT iSocketType; INT iProtocol; } CSADDR_INFO, *PCSADDR_INFO, *LPCSADDR_INFO; + [PInvokeData("nspapi.h", MSDNShortId = "9cad3586-e315-4f6f-9045-7c95502bb768")] + [StructLayout(LayoutKind.Sequential)] + public struct CSADDR_INFO + { + /// + /// Type: SOCKET_ADDRESS + /// The Windows Sockets local address. + /// In a client application, pass this address to the bind function to obtain access to a network service. /// - /// The l_onoff member of the linger structure determines whether a socket should remain open for a specified amount - /// of time after a closesocket function call to enable queued data to be sent. Somewhat confusing is that this member can be - /// modified in two ways: + /// In a network service, pass this address to the bind function so that the service is bound to the appropriate local address. /// + /// + public SOCKET_ADDRESS LocalAddr; + + /// + /// Type: SOCKET_ADDRESS + /// Windows Sockets remote address. + /// There are several uses for this remote address: /// /// /// - /// Call the setsockopt function with the optname parameter set to SO_DONTLINGER. The optval parameter determines how the - /// l_onoff member is modified. + /// You can use this remote address to connect to the service through the connect function. This is useful if an application + /// performs send/receive operations that involve connection-oriented protocols. /// /// /// /// - /// Call the setsockopt function with the optname parameter set to SO_LINGER. The optval parameter specifies how both the - /// l_onoff and l_linger members are modified. + /// You can use this remote address with the sendto function when you are communicating over a connectionless (datagram) + /// protocol. If you are using a connectionless protocol, such as UDP, sendto is typically the way you pass data to the + /// remote system. /// /// /// - /// - /// The l_linger member of the linger structure determines the amount of time, in seconds, a socket should remain - /// open. This member is only applicable if the l_onoff member of the linger structure is nonzero. - /// - /// - /// To enable a socket to remain open, an application should set the l_onoff member to a nonzero value and set the - /// l_linger member to the desired time-out in seconds. To disable a socket from remaining open, an application only needs to - /// set the l_onoff member of the linger structure to zero. - /// - /// - /// If an application calls the setsockopt function with the optname parameter set to SO_DONTLINGER to set the l_onoff - /// member to a nonzero value, the value for the l_linger member is not specified. In this case, the time-out used is - /// implementation dependent. If a previous time-out has been established for a socket (by enabling SO_LINGER), this time-out value - /// should be reinstated by the service provider. - /// - /// Note that enabling a nonzero timeout on a nonblocking socket is not recommended. - /// - /// The getsockopt function can be called with the optname parameter set to SO_LINGER to retrieve the current value of the - /// linger structure associated with a socket. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winsock/ns-winsock-linger typedef struct linger { u_short l_onoff; u_short - // l_linger; } LINGER, *PLINGER, *LPLINGER; - [PInvokeData("winsock.h", MSDNShortId = "c1dbabcf-b5cd-4a9d-9bf9-b04c62117d74")] - [StructLayout(LayoutKind.Sequential)] - public struct LINGER - { - /// - /// Type: u_short - /// - /// Specifies whether a socket should remain open for a specified amount of time after a closesocket function call to enable - /// queued data to be sent. This member can have one of the following values. - /// - /// - /// - /// Value - /// Meaning - /// - /// - /// 0 - /// - /// The socket will not remain open. This is the value set if the setsockopt function is called with the optname parameter set - /// to SO_DONTLINGER and the optval parameter is zero. This value is also set if the setsockopt function is called with the - /// optname parameter set to SO_LINGER and the linger structure passed in the optval parameter has the l_onoff member set to 0. - /// - /// - /// - /// nonzero - /// - /// The socket will remain open for a specified amount of time. This value is set if the setsockopt function is called with the - /// optname parameter set to SO_DONTLINGER and the optval parameter is nonzero. This value is also set if the setsockopt - /// function is called with the optname parameter set to SO_LINGER and the linger structure passed in the optval parameter has - /// the l_onoff member set to a nonzero value. - /// - /// - /// - /// - public ushort l_onoff; - - /// - /// Type: u_short - /// - /// The linger time in seconds. This member specifies how long to remain open after a closesocket function call to enable queued - /// data to be sent. This member is only applicable if the l_onoff member of the linger structure is set to a - /// nonzero value. - /// - /// - /// This value is set if the setsockopt function is called with the optname parameter set to SO_LINGER. The optval - /// parameter passed to the setsockopt function must contain a linger structure that is copied to the internal - /// linger structure maintained for the socket. - /// - /// - public ushort l_linger; - } + /// + public SOCKET_ADDRESS RemoteAddr; /// - /// The QOS structure provides the means by which QOS-enabled applications can specify quality of service parameters for sent - /// and received traffic on a particular flow. - /// - /// - /// Most applications can fulfill their quality of service requirements without using the ProviderSpecific buffer. However, if the - /// application must provide information not available with standard Windows 2000 QOS parameters, the ProviderSpecific buffer allows - /// the application to provide additional parameters for RSVP and/or traffic control. - /// - // https://docs.microsoft.com/en-us/windows/desktop/api/winsock2/ns-winsock2-_qualityofservice typedef struct _QualityOfService { - // FLOWSPEC SendingFlowspec; FLOWSPEC ReceivingFlowspec; WSABUF ProviderSpecific; } QOS, *LPQOS; - [PInvokeData("winsock2.h", MSDNShortId = "859faa13-bd66-46ee-8452-6ff5d53d66c9")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] - public struct QOS - { - /// - /// Specifies QOS parameters for the sending direction of a particular flow. SendingFlowspec is sent in the form of a FLOWSPEC structure. - /// - public FLOWSPEC SendingFlowspec; - - /// - /// Specifies QOS parameters for the receiving direction of a particular flow. ReceivingFlowspec is sent in the form of a - /// FLOWSPEC structure. - /// - public FLOWSPEC ReceivingFlowspec; - - /// - /// Pointer to a structure of type WSABUF that can provide additional provider-specific quality of service parameters to the - /// RSVP SP for a given flow. - /// - public WSABUF ProviderSpecific; - } - - /// - /// Represents info supplied to the ProcessSocketNotifications function. - /// For more info, and code examples, see Winsock socket state notifications. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/ns-winsock2-sock_notify_registration typedef struct - // SOCK_NOTIFY_REGISTRATION { SOCKET socket; PVOID completionKey; UINT16 eventFilter; UINT8 operation; UINT8 triggerFlags; DWORD - // registrationResult; } SOCK_NOTIFY_REGISTRATION; - [PInvokeData("winsock2.h", MSDNShortId = "NS:winsock2.SOCK_NOTIFY_REGISTRATION")] - [StructLayout(LayoutKind.Sequential)] - public struct SOCK_NOTIFY_REGISTRATION - { - /// - /// Type: SOCKET - /// - /// A handle to a Winsock socket opened by any of the WSASocket, socket, WSAAccept, accept, or WSADuplicateSocket functions. - /// Only Microsoft Winsock provider sockets are supported. - /// - /// - public SOCKET socket; - - /// - /// Type: PVOID - /// - /// The value to use in the dwCompletionKey parameter of the PostQueuedCompletionStatus function when notifications are sent on - /// behalf of the socket. This parameter is used upon registration creation. To change the completion key, remove the - /// registration and re-register it. - /// - /// - public IntPtr completionKey; - - /// - /// Type: UINT16 - /// - /// A set of flags indicating the notifications being requested. This must be one or more of the following values (defined in - /// WinSock2.h - /// ). - /// - /// - /// SOCK_NOTIFY_REGISTER_EVENT_NONE. Notifications should not be issued. SOCK_NOTIFY_REGISTER_EVENT_IN. A - /// notification should be issued when data can be read without blocking. SOCK_NOTIFY_REGISTER_EVENT_OUT. A notification - /// should be issued when data can be written without blocking. SOCK_NOTIFY_REGISTER_EVENT_HANGUP. A notification should - /// be issued when a stream-oriented connection was either disconnected or aborted. SOCK_NOTIFY_REGISTER_EVENTS_ALL. Has - /// the value - /// (SOCK_NOTIFY_REGISTER_EVENT_IN | SOCK_NOTIFY_REGISTER_EVENT_OUT | SOCK_NOTIFY_REGISTER_EVENT_HANGUP) - /// . - /// - /// - public SOCK_NOTIFY_REGISTER_EVENT eventFilter; - - /// - /// Type: UINT8 - /// - /// Indicates the operation to perform on a registration. At most one operation may be performed at a time. These values are - /// defined in - /// WinSock2.h - /// . - /// - /// - /// SOCK_NOTIFY_OP_NONE. No registration operations should take place. Use this if your application calls - /// ProcessSocketNotifications and is only interested in receiving notifications. SOCK_NOTIFY_OP_ENABLE. Enables the - /// registration. Notifications must not be re-enabled until the SOCK_NOTIFY_EVENT_DISABLE notification is received. - /// SOCK_NOTIFY_OP_DISABLE. Disables the registration, but doesn't destroy the underlying data structures. Note that this - /// doesn't remove the registration, it merely suppresses queuing of new notifications. Notifications that have already been - /// queued might still be delivered until the SOCK_NOTIFY_EVENT_DISABLE event is received. SOCK_NOTIFY_OP_REMOVE. - /// Removes a previously-registered notification. Both enabled and disabled notifications may be removed. The - /// SOCK_NOTIFY_EVENT_REMOVE notification is issued, with the guarantee that no more notifications will be issued - /// afterwards for that completion key unless it is re-registered. - /// - /// - public SOCK_NOTIFY_OP operation; - - /// - /// Type: UINT8 - /// A set of flags indicating the trigger behavior (defined in - /// WinSock2.h - /// ). - /// - /// - /// SOCK_NOTIFY_TRIGGER_ONESHOT. The registration will be disabled (not removed) upon delivery of the next notification. - /// SOCK_NOTIFY_TRIGGER_PERSISTENT. The registration will remain active until it is explicitly disabled or removed. - /// SOCK_NOTIFY_TRIGGER_LEVEL. The registration is for level-triggered notifications. Not compatible with edge-triggered. - /// One of edge- or level-triggered must be supplied. SOCK_NOTIFY_TRIGGER_EDGE. The registration is for edge-triggered - /// notifications. Not compatible with level-triggered. One of edge- or level-triggered must be supplied. - /// - /// - /// Notifications are only supplied when the registration is enabled. Notifications are not queued up while the registration is - /// disabled. As notifications are queued up for a given socket, they are coalesced into a single notification. Therefore, - /// multiple events may be described by a single event mask for the socket. - /// - /// Given the registration is enabled, level-triggered notifications are supplied whenever the desired conditions hold. - /// - /// Given the registration is enabled, edge-triggered notifications are supplied whenever a condition changes from not holding - /// to holding. The condition must change while the registration is enabled for a notification to be queued. As such, after - /// registering, the socket's receive buffer must be completely drained to ensure a notification is received. - /// - /// - public SOCK_NOTIFY_TRIGGER triggerFlags; - - /// - /// Type: DWORD - /// - /// After a successful call to ProcessSocketNotifications, registrationResult contains a code indicating the success or failure - /// of the registration. A value of ERROR_SUCCESS indicates that registration was successful. - /// - /// - public Win32Error registrationResult; - } - - /// Provides a handle to a socket. - /// - [PInvokeData("winsock2.h")] - [StructLayout(LayoutKind.Sequential)] - public struct SOCKET : IHandle - { - /// The handle - private readonly IntPtr handle; - - /// Initializes a new instance of the struct. - /// An object that represents the pre-existing handle to use. - public SOCKET(IntPtr preexistingHandle) => handle = preexistingHandle; - - /// Represents an invalid socket which is different than a null socket. - /// The invalid socket. - public static SOCKET INVALID_SOCKET => new(new IntPtr(-1)); - - /// Returns an invalid handle by instantiating a object with . - /// Returns a value. - public static SOCKET NULL => new(IntPtr.Zero); - - /// Gets a value indicating whether this instance is a null handle. - /// if this instance is null; otherwise, . - public bool IsNull => handle == IntPtr.Zero; - - /// Performs an explicit conversion from to . - /// The handle. - /// The result of the conversion. - public static explicit operator IntPtr(SOCKET h) => h.handle; - - /// Performs an implicit conversion from to . - /// The pointer to a handle. - /// The result of the conversion. - public static implicit operator SOCKET(IntPtr h) => new(h); - - /// Implements the operator !=. - /// The first handle. - /// The second handle. - /// The result of the operator. - public static bool operator !=(SOCKET h1, SOCKET h2) => !(h1 == h2); - - /// Implements the operator ==. - /// The first handle. - /// The second handle. - /// The result of the operator. - public static bool operator ==(SOCKET h1, SOCKET h2) => h1.Equals(h2); - - /// Determines whether the specified , is equal to this instance. - /// The to compare with this instance. - /// - /// if the specified is equal to this instance; otherwise, . - /// - /// - public override bool Equals(object obj) => obj is SOCKET h && handle == h.handle; - - /// Returns a hash code for this instance. - /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. - /// - public override int GetHashCode() => handle.GetHashCode(); - - /// Returns the value of the handle field. - /// An IntPtr representing the value of the handle field. - /// - public IntPtr DangerousGetHandle() => handle; - - /// - public override string ToString() => handle.ToString(); - } - - /// - /// The timeval structure is used to specify a time interval. It is associated with the Berkeley Software Distribution (BSD) - /// Time.h header file. - /// - /// - /// - /// The timeval structure is used in Windows Sockets by the select function to specify the maximum time the function can take - /// to complete. The time interval is a combination of the values in tv_sec and tv_usec members. - /// - /// - /// Several functions are added on Windows Vista and later that use the timeval structure. These functions include - /// GetAddrInfoEx, SetAddrInfoEx, WSAConnectByList, and WSAConnectByName. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winsock/ns-winsock-timeval typedef struct timeval { long tv_sec; long tv_usec; - // } TIMEVAL, *PTIMEVAL, *LPTIMEVAL; - [PInvokeData("winsock.h", MSDNShortId = "3024c961-bb47-40ac-a49c-b12cd431e4e7")] - [StructLayout(LayoutKind.Sequential)] - public struct TIMEVAL - { - /// Time interval, in seconds. - public int tv_sec; - - /// - /// Time interval, in microseconds. This value is used in combination with the tv_sec member to represent time interval - /// values that are not a multiple of seconds. - /// - public int tv_usec; - - /// Performs an explicit conversion from to . - /// The time span. - /// The resulting instance from the conversion. - public static explicit operator TIMEVAL(TimeSpan timeSpan) - { - var tr = Math.Truncate(timeSpan.TotalSeconds); - return new TIMEVAL { tv_sec = (int)tr, tv_usec = (int)((timeSpan.Ticks - TimeSpan.TicksPerSecond * (long)tr) / TimeSpan.TicksPerMillisecond) }; - } - } - - /// The WSADATA structure contains information about the Windows Sockets implementation. - /// - /// - /// The WSAStartup function initiates the use of the Windows Sockets DLL by a process. The WSAStartup function returns a - /// pointer to the WSADATA structure in the lpWSADataparameter. - /// - /// The current version of the Windows Sockets specification returned in the wHighVersion member of the - /// - /// WSADATA structure is version 2.2 encoded with the major version number in the low-byte and the minor version number in - /// the high-byte. This version of the current Winsock DLL, Ws2_32.dll, supports applications that request any of the following - /// versions of the Windows Sockets specification: - /// - /// + /// Type: INT + /// The type of Windows socket. Possible values for the socket type are defined in the Winsock2.h header file. + /// The following table lists the possible values supported for Windows Sockets 2: + /// + /// + /// Value + /// Meaning + /// /// - /// 1.0 + /// SOCK_STREAM + /// + /// A stream socket. This is a protocol that sends data as a stream of bytes, with no message boundaries. This socket type + /// provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. This socket + /// type uses the Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6). + /// /// /// - /// 1.1 + /// SOCK_DGRAM + /// + /// A datagram socket. This socket type supports datagrams, which are connectionless, unreliable buffers of a fixed (typically + /// small) maximum length. This socket type uses the User Datagram Protocol (UDP) for the Internet address family (AF_INET or + /// AF_INET6). Services use recvfrom function to obtain datagrams. The listen and accept functions do not work with datagrams. + /// /// /// - /// 2.0 + /// SOCK_RDM + /// + /// A reliable message datagram socket. This socket type preserves message boundaries in data. An example of this type is the + /// Pragmatic General Multicast (PGM) multicast protocol implementation in Windows, often referred to as reliable multicast programming. + /// /// /// - /// 2.1 - /// - /// - /// 2.2 + /// SOCK_SEQPACKET + /// A sequenced packet stream socket. This socket type provides a pseudo-stream packet based on datagrams. /// /// - /// - /// Depending on the version requested by the application, one of the above version numbers is the value encoded as the major - /// version number in the low-byte and the minor version number in the high-byte that is returned in the wVersion member of - /// the WSADATA structure. - /// - /// - /// Note An application should ignore the iMaxsockets, iMaxUdpDg, and lpVendorInfo members in - /// WSADATA if the value in wVersion after a successful call to WSAStartup is at least 2. This is because the - /// architecture of Windows Sockets changed in version 2 to support multiple providers, and WSADATA no longer applies to a - /// single vendor's stack. Two new socket options are introduced to supply provider-specific information: SO_MAX_MSG_SIZE (replaces - /// the iMaxUdpDg member) and PVD_CONFIG (allows any other provider-specific configuration to occur). - /// - /// Examples - /// The following example demonstrates the use of the WSADATA structure. - /// - // https://docs.microsoft.com/en-us/windows/desktop/api/winsock/ns-winsock-wsadata typedef struct WSAData { WORD wVersion; WORD - // wHighVersion; unsigned short iMaxSockets; unsigned short iMaxUdpDg; char *lpVendorInfo; char szDescription[WSADESCRIPTION_LEN + - // 1]; char szSystemStatus[WSASYS_STATUS_LEN + 1]; } WSADATA; - [PInvokeData("winsock.h", MSDNShortId = "c3c4c0d6-c8b3-4991-bedb-f45816cc8160")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] - public struct WSADATA - { - private const int WSADESCRIPTION_LEN = 256; - private const int WSASYS_STATUS_LEN = 128; - - /// - /// Type: WORD - /// - /// The version of the Windows Sockets specification that the Ws2_32.dll expects the caller to use. The high-order byte - /// specifies the minor version number; the low-order byte specifies the major version number. - /// - /// - public ushort wVersion; - - /// - /// Type: WORD - /// - /// The highest version of the Windows Sockets specification that the Ws2_32.dll can support. The high-order byte specifies the - /// minor version number; the low-order byte specifies the major version number. - /// - /// - /// This is the same value as the wVersion member when the version requested in the wVersionRequested parameter passed to - /// the WSAStartup function is the highest version of the Windows Sockets specification that the Ws2_32.dll can support. - /// - /// - public ushort wHighVersion; - - /// - /// Type: unsigned short - /// - /// The maximum number of sockets that may be opened. This member should be ignored for Windows Sockets version 2 and later. - /// - /// - /// The iMaxSockets member is retained for compatibility with Windows Sockets specification 1.1, but should not be used - /// when developing new applications. No single value can be appropriate for all underlying service providers. The architecture - /// of Windows Sockets changed in version 2 to support multiple providers, and the WSADATA structure no longer applies to - /// a single vendor's stack. - /// - /// - public ushort iMaxSockets; - - /// - /// Type: unsigned short - /// The maximum datagram message size. This member is ignored for Windows Sockets version 2 and later. - /// - /// The iMaxUdpDg member is retained for compatibility with Windows Sockets specification 1.1, but should not be used - /// when developing new applications. The architecture of Windows Sockets changed in version 2 to support multiple providers, - /// and the WSADATA structure no longer applies to a single vendor's stack. For the actual maximum message size specific - /// to a particular Windows Sockets service provider and socket type, applications should use getsockopt to retrieve the value - /// of option SO_MAX_MSG_SIZE after a socket has been created. - /// - /// - public ushort iMaxUdpDg; - - /// - /// Type: char FAR* - /// A pointer to vendor-specific information. This member should be ignored for Windows Sockets version 2 and later. - /// - /// The lpVendorInfo member is retained for compatibility with Windows Sockets specification 1.1. The architecture of - /// Windows Sockets changed in version 2 to support multiple providers, and the WSADATA structure no longer applies to a - /// single vendor's stack. Applications needing to access vendor-specific configuration information should use getsockopt to - /// retrieve the value of option PVD_CONFIG for vendor-specific information. - /// - /// - public IntPtr lpVendorInfo; - - /// - /// Type: char[WSADESCRIPTION_LEN+1] - /// - /// A NULL-terminated ASCII string into which the Ws2_32.dll copies a description of the Windows Sockets implementation. - /// The text (up to 256 characters in length) can contain any characters except control and formatting characters. The most - /// likely use that an application would have for this member is to display it (possibly truncated) in a status message. - /// - /// - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = WSADESCRIPTION_LEN + 1)] - public string szDescription; - - /// - /// Type: char[WSASYS_STATUS_LEN+1] - /// - /// A NULL-terminated ASCII string into which the Ws2_32.dll copies relevant status or configuration information. The - /// Ws2_32.dll should use this parameter only if the information might be useful to the user or support staff. This member - /// should not be considered as an extension of the szDescription parameter. - /// - /// - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = WSASYS_STATUS_LEN + 1)] - public string szSystemStatus; - } + /// + public SOCK iSocketType; /// - /// The WSAPROTOCOL_INFO structure is used to store or retrieve complete information for a given protocol. + /// Type: INT + /// + /// The protocol used. The possible options for the protocol parameter are specific to the address family and socket type + /// specified. Possible values are defined in the Winsock2.h and Wsrm.h header files. + /// + /// + /// On the Windows SDK released for Windows Vista and later, the organization of header files has changed and this parameter can + /// be one of the values from the IPPROTO enumeration type defined in the Ws2def.h header file. Note that the Ws2def.h + /// header file is automatically included in Winsock2.h, and should never be used directly. + /// + /// The table below lists common values for the protocol although many other values are possible. + /// + /// + /// protocol + /// Meaning + /// + /// + /// IPPROTO_TCP 6 + /// + /// The Transmission Control Protocol (TCP). This is a possible value when the address family is AF_INET or AF_INET6 and the + /// iSocketType member is SOCK_STREAM. + /// + /// + /// + /// IPPROTO_UDP 17 + /// + /// The User Datagram Protocol (UDP). This is a possible value when the address family is AF_INET or AF_INET6 and the + /// iSocketType member is SOCK_DGRAM. + /// + /// + /// + /// IPPROTO_RM 113 + /// + /// The PGM protocol for reliable multicast. This is a possible value when the address family is AF_INET and the iSocketType + /// member is SOCK_RDM. On the Windows SDK released for Windows Vista and later, this value is also called IPPROTO_PGM. + /// + /// + /// /// - // https://docs.microsoft.com/en-us/windows/desktop/api/winsock2/ns-winsock2-_wsaprotocol_infoa typedef struct _WSAPROTOCOL_INFOA { - // DWORD dwServiceFlags1; DWORD dwServiceFlags2; DWORD dwServiceFlags3; DWORD dwServiceFlags4; DWORD dwProviderFlags; GUID - // ProviderId; DWORD dwCatalogEntryId; WSAPROTOCOLCHAIN ProtocolChain; int iVersion; int iAddressFamily; int iMaxSockAddr; int - // iMinSockAddr; int iSocketType; int iProtocol; int iProtocolMaxOffset; int iNetworkByteOrder; int iSecurityScheme; DWORD - // dwMessageSize; DWORD dwProviderReserved; CHAR szProtocol[WSAPROTOCOL_LEN + 1]; } WSAPROTOCOL_INFOA, *LPWSAPROTOCOL_INFOA; - [PInvokeData("winsock2.h", MSDNShortId = "758c5553-056f-4ea5-a851-30ef641ffb14")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] - public struct WSAPROTOCOL_INFO + public IPPROTO iProtocol; + } + + /// The IN_ADDR structure represents an IPv4 address. + [PInvokeData("winsock2.h")] + [StructLayout(LayoutKind.Sequential)] + public struct IN_ADDR : IEquatable + { + /// An IPv4 address formatted as a u_long. + public uint S_addr; + + /// Initializes a new instance of the struct. + /// An IPv4 address. + public IN_ADDR(uint v4addr) => S_addr = v4addr; + + /// Initializes a new instance of the struct. + /// An IPv4 address + /// Byte array must have 4 items. - v4addr + public IN_ADDR(byte[] v4addr) { - private const int WSAPROTOCOL_LEN = 255; - - /// - /// Type: DWORD - /// - /// A bitmask that describes the services provided by the protocol. The possible values for this member are defined in the - /// Winsock2.h header file. - /// - /// The following values are possible. - /// - /// - /// Value - /// Meaning - /// - /// - /// XP1_CONNECTIONLESS 0x00000001 - /// Provides connectionless (datagram) service. If not set, the protocol supports connection-oriented data transfer. - /// - /// - /// XP1_GUARANTEED_DELIVERY 0x00000002 - /// Guarantees that all data sent will reach the intended destination. - /// - /// - /// XP1_GUARANTEED_ORDER 0x00000004 - /// - /// Guarantees that data only arrives in the order in which it was sent and that it is not duplicated. This characteristic does - /// not necessarily mean that the data is always delivered, but that any data that is delivered is delivered in the order in - /// which it was sent. - /// - /// - /// - /// XP1_MESSAGE_ORIENTED 0x00000008 - /// Honors message boundaries—as opposed to a stream-oriented protocol where there is no concept of message boundaries. - /// - /// - /// XP1_PSEUDO_STREAM 0x00000010 - /// - /// A message-oriented protocol, but message boundaries are ignored for all receipts. This is convenient when an application - /// does not desire message framing to be done by the protocol. - /// - /// - /// - /// XP1_GRACEFUL_CLOSE 0x00000020 - /// Supports two-phase (graceful) close. If not set, only abortive closes are performed. - /// - /// - /// XP1_EXPEDITED_DATA 0x00000040 - /// Supports expedited (urgent) data. - /// - /// - /// XP1_CONNECT_DATA 0x00000080 - /// Supports connect data. - /// - /// - /// XP1_DISCONNECT_DATA 0x00000100 - /// Supports disconnect data. - /// - /// - /// XP1_SUPPORT_BROADCAST 0x00000200 - /// Supports a broadcast mechanism. - /// - /// - /// XP1_SUPPORT_MULTIPOINT 0x00000400 - /// Supports a multipoint or multicast mechanism. Control and data plane attributes are indicated below. - /// - /// - /// XP1_MULTIPOINT_CONTROL_PLANE 0x00000800 - /// Indicates whether the control plane is rooted (value = 1) or nonrooted (value = 0). - /// - /// - /// XP1_MULTIPOINT_DATA_PLANE 0x00001000 - /// Indicates whether the data plane is rooted (value = 1) or nonrooted (value = 0). - /// - /// - /// XP1_QOS_SUPPORTED 0x00002000 - /// Supports quality of service requests. - /// - /// - /// XP1_INTERRUPT - /// Bit is reserved. - /// - /// - /// XP1_UNI_SEND 0x00008000 - /// Protocol is unidirectional in the send direction. - /// - /// - /// XP1_UNI_RECV 0x00010000 - /// Protocol is unidirectional in the recv direction. - /// - /// - /// XP1_IFS_HANDLES 0x00020000 - /// Socket descriptors returned by the provider are operating system Installable File System (IFS) handles. - /// - /// - /// XP1_PARTIAL_MESSAGE 0x00040000 - /// The MSG_PARTIAL flag is supported in WSASend and WSASendTo. - /// - /// - /// XP1_SAN_SUPPORT_SDP 0x00080000 - /// The protocol provides support for SAN. This value is supported on Windows 7 and Windows Server 2008 R2. - /// - /// - /// - /// Note Only one of XP1_UNI_SEND or XP1_UNI_RECV values may be set. If a protocol can be unidirectional in either - /// direction, two WSAPROTOCOL_INFOW structures should be used. When neither bit is set, the protocol is considered to be bidirectional. - /// - /// - public XP1 dwServiceFlags1; - - /// - /// Type: DWORD - /// Reserved for additional protocol-attribute definitions. - /// - public uint dwServiceFlags2; - - /// - /// Type: DWORD - /// Reserved for additional protocol-attribute definitions. - /// - public uint dwServiceFlags3; - - /// - /// Type: DWORD - /// - /// A set of flags that provides information on how this protocol is represented in the Winsock catalog. The possible values for - /// this member are defined in the Winsock2.h header file. - /// - /// The following flag values are possible. - /// - /// - /// Value - /// Meaning - /// - /// - /// PFL_MULTIPLE_PROTO_ENTRIES 0x00000001 - /// - /// Indicates that this is one of two or more entries for a single protocol (from a given provider) which is capable of - /// implementing multiple behaviors. An example of this is SPX which, on the receiving side, can behave either as a - /// message-oriented or a stream-oriented protocol. - /// - /// - /// - /// PFL_RECOMMENDED_PROTO_ENTRY 0x00000002 - /// - /// Indicates that this is the recommended or most frequently used entry for a protocol that is capable of implementing multiple behaviors. - /// - /// - /// - /// PFL_HIDDEN 0x00000004 - /// - /// Set by a provider to indicate to the Ws2_32.dll that this protocol should not be returned in the result buffer generated by - /// WSAEnumProtocols. Obviously, a Windows Sockets 2 application should never see an entry with this bit set. - /// - /// - /// - /// PFL_MATCHES_PROTOCOL_ZERO 0x00000008 - /// Indicates that a value of zero in the protocol parameter of socket or WSASocket matches this protocol entry. - /// - /// - /// PFL_NETWORKDIRECT_PROVIDER 0x00000010 - /// - /// Set by a provider to indicate support for network direct access. This value is supported on Windows 7 and Windows Server - /// 2008 R2. - /// - /// - /// - /// - public uint dwServiceFlags4; - - /// - /// Type: DWORD - /// Reserved for additional protocol-attribute definitions. - /// - public uint dwProviderFlags; - - /// - /// Type: GUID - /// - /// A globally unique identifier (GUID) assigned to the provider by the service provider vendor. This value is useful for - /// instances where more than one service provider is able to implement a particular protocol. An application can use the - /// ProviderId member to distinguish between providers that might otherwise be indistinguishable. - /// - /// - public Guid ProviderId; - - /// - /// Type: DWORD - /// A unique identifier assigned by the WS2_32.DLL for each WSAPROTOCOL_INFO structure. - /// - public uint dwCatalogEntryId; - - /// - /// Type: WSAPROTOCOLCHAIN - /// - /// The WSAPROTOCOLCHAIN structure associated with the protocol. If the length of the chain is 0, this WSAPROTOCOL_INFO - /// entry represents a layered protocol which has Windows Sockets 2 SPI as both its top and bottom edges. If the length of the - /// chain equals 1, this entry represents a base protocol whose Catalog Entry identifier is in the dwCatalogEntryId - /// member of the WSAPROTOCOL_INFO structure. If the length of the chain is larger than 1, this entry represents a - /// protocol chain which consists of one or more layered protocols on top of a base protocol. The corresponding Catalog Entry - /// identifiers are in the ProtocolChain.ChainEntries array starting with the layered protocol at the top (the zero element in - /// the ProtocolChain.ChainEntries array) and ending with the base protocol. Refer to the Windows Sockets 2 Service Provider - /// Interface specification for more information on protocol chains. - /// - /// - public WSAPROTOCOLCHAIN ProtocolChain; - - /// - /// Type: int - /// The protocol version identifier. - /// - public int iVersion; - - /// - /// Type: int - /// - /// A value to pass as the address family parameter to the socket or WSASocket function in order to open a socket for this - /// protocol. This value also uniquely defines the structure of a protocol address for a sockaddr used by the protocol. - /// - /// - /// On the Windows SDK released for Windows Vista and later, the possible values for the address family are defined in the - /// Ws2def.h header file. Note that the Ws2def.h header file is automatically included in Winsock2.h, and should never be used directly. - /// - /// - /// On versions of the Platform SDK for Windows Server 2003 and older, the possible values for the address family are defined in - /// the Winsock2.h header file. - /// - /// - /// The values currently supported are AF_INET or AF_INET6, which are the Internet address family formats for IPv4 and IPv6. - /// Other options for address family (AF_NETBIOS for use with NetBIOS, for example) are supported if a Windows Sockets service - /// provider for the address family is installed. Note that the values for the AF_ address family and PF_ protocol family - /// constants are identical (for example, AF_INET and PF_INET), so either constant can be used. - /// - /// The table below lists common values for address family although many other values are possible. - /// - /// - /// iAddressFamily - /// Meaning - /// - /// - /// AF_INET 2 - /// The Internet Protocol version 4 (IPv4) address family. - /// - /// - /// AF_IPX 6 - /// - /// The IPX/SPX address family. This address family is only supported if the NWLink IPX/SPX NetBIOS Compatible Transport - /// protocol is installed. This address family is not supported on Windows Vista and later. - /// - /// - /// - /// AF_APPLETALK 16 - /// - /// The AppleTalk address family. This address family is only supported if the AppleTalk protocol is installed. This address - /// family is not supported on Windows Vista and later. - /// - /// - /// - /// AF_NETBIOS 17 - /// - /// The NetBIOS address family. This address family is only supported if the Windows Sockets provider for NetBIOS is installed. - /// The Windows Sockets provider for NetBIOS is supported on 32-bit versions of Windows. This provider is installed by default - /// on 32-bit versions of Windows. The Windows Sockets provider for NetBIOS is not supported on 64-bit versions of windows - /// including Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003, or Windows XP. The Windows Sockets provider - /// for NetBIOS only supports sockets where the type parameter is set to SOCK_DGRAM. The Windows Sockets provider for NetBIOS is - /// not directly related to the NetBIOS programming interface. The NetBIOS programming interface is not supported on Windows - /// Vista, Windows Server 2008, and later. - /// - /// - /// - /// AF_INET6 23 - /// The Internet Protocol version 6 (IPv6) address family. - /// - /// - /// AF_IRDA 26 - /// - /// The Infrared Data Association (IrDA) address family. This address family is only supported if the computer has an infrared - /// port and driver installed. - /// - /// - /// - /// AF_BTH 32 - /// - /// The Bluetooth address family. This address family is supported on Windows XP with SP2 or later if the computer has a - /// Bluetooth adapter and driver installed. - /// - /// - /// - /// - public int iAddressFamily; - - /// - /// Type: int - /// The maximum address length, in bytes. - /// - public int iMaxSockAddr; - - /// - /// Type: int - /// The minimum address length, in bytes. - /// - public int iMinSockAddr; - - /// - /// Type: int - /// - /// A value to pass as the socket type parameter to the socket or WSASocket function in order to open a socket for this - /// protocol. Possible values for the socket type are defined in the Winsock2.h header file. - /// - /// The following table lists the possible values for the iSocketType member supported for Windows Sockets 2: - /// - /// - /// iSocketType - /// Meaning - /// - /// - /// SOCK_STREAM 1 - /// - /// A socket type that provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission - /// mechanism. This socket type uses the Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6). - /// - /// - /// - /// SOCK_DGRAM 2 - /// - /// A socket type that supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum - /// length. This socket type uses the User Datagram Protocol (UDP) for the Internet address family (AF_INET or AF_INET6). - /// - /// - /// - /// SOCK_RAW 3 - /// - /// A socket type that provides a raw socket that allows an application to manipulate the next upper-layer protocol header. To - /// manipulate the IPv4 header, the IP_HDRINCL socket option must be set on the socket. To manipulate the IPv6 header, the - /// IPV6_HDRINCL socket option must be set on the socket. - /// - /// - /// - /// SOCK_RDM 4 - /// - /// A socket type that provides a reliable message datagram. An example of this type is the Pragmatic General Multicast (PGM) - /// multicast protocol implementation in Windows, often referred to as reliable multicast programming. This value is only - /// supported if the Reliable Multicast Protocol is installed. - /// - /// - /// - /// SOCK_SEQPACKET 5 - /// A socket type that provides a pseudo-stream packet based on datagrams. - /// - /// - /// - public SOCK iSocketType; - - /// - /// Type: int - /// - /// A value to pass as the protocol parameter to the socket or WSASocket function in order to open a socket for this protocol. - /// The possible options for the iProtocol member are specific to the address family and socket type specified. - /// - /// - /// On the Windows SDK released for Windows Vista and later, this member can be one of the values from the IPPROTO - /// enumeration type defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically included in - /// Winsock2.h, and should never be used directly. - /// - /// - /// On versions of the Platform SDK for Windows Server 2003 and earlier, the possible values for the iProtocol member are - /// defined in the Winsock2.h and Wsrm.h header files. - /// - /// The table below lists common values for the iProtocol although many other values are possible. - /// - /// - /// iProtocol - /// Meaning - /// - /// - /// IPPROTO_ICMP 1 - /// The Internet Control Message Protocol (ICMP). This value is supported on Windows XP and later. - /// - /// - /// IPPROTO_IGMP 2 - /// The Internet Group Management Protocol (IGMP). This value is supported on Windows XP and later. - /// - /// - /// BTHPROTO_RFCOMM 3 - /// - /// The Bluetooth Radio Frequency Communications (Bluetooth RFCOMM) protocol. This value is supported on Windows XP with SP2 or later. - /// - /// - /// - /// IPPROTO_TCP 6 - /// The Transmission Control Protocol (TCP). - /// - /// - /// IPPROTO_UDP 17 - /// The User Datagram Protocol (UDP). - /// - /// - /// IPPROTO_ICMPV6 58 - /// The Internet Control Message Protocol Version 6 (ICMPv6). This value is supported on Windows XP and later. - /// - /// - /// IPPROTO_RM 113 - /// - /// The PGM protocol for reliable multicast. On the Windows SDK released for Windows Vista and later, this protocol is also - /// called IPPROTO_PGM. This value is only supported if the Reliable Multicast Protocol is installed. - /// - /// - /// - /// - public IPPROTO iProtocol; - - /// - /// Type: int - /// - /// The maximum value that may be added to iProtocol when supplying a value for the protocol parameter to socket or - /// WSASocket function. Not all protocols allow a range of values. When this is the case iProtocolMaxOffset is zero. - /// - /// - public int iProtocolMaxOffset; - - /// - /// Type: int - /// - /// Currently these values are manifest constants (BIGENDIAN and LITTLEENDIAN) that indicate either big-endian or little-endian - /// with the values 0 and 1 respectively. - /// - /// - public int iNetworkByteOrder; - - /// - /// Type: int - /// - /// The type of security scheme employed (if any). A value of SECURITY_PROTOCOL_NONE (0) is used for protocols that do not - /// incorporate security provisions. - /// - /// - public int iSecurityScheme; - - /// - /// Type: DWORD - /// - /// The maximum message size, in bytes, supported by the protocol. This is the maximum size that can be sent from any of the - /// host's local interfaces. For protocols that do not support message framing, the actual maximum that can be sent to a given - /// address may be less. There is no standard provision to determine the maximum inbound message size. The following special - /// values are defined. - /// - /// - /// - /// Value - /// Meaning - /// - /// - /// 0 - /// The protocol is stream-oriented and hence the concept of message size is not relevant. - /// - /// - /// 0x1 - /// - /// The maximum outbound (send) message size is dependent on the underlying network MTU (maximum sized transmission unit) and - /// hence cannot be known until after a socket is bound. Applications should use getsockopt to retrieve the value of - /// SO_MAX_MSG_SIZE after the socket has been bound to a local address. - /// - /// - /// - /// 0xFFFFFFFF - /// The protocol is message-oriented, but there is no maximum limit to the size of messages that may be transmitted. - /// - /// - /// - public uint dwMessageSize; - - /// - /// Type: DWORD - /// Reserved for use by service providers. - /// - public uint dwProviderReserved; - - /// - /// Type: TCHAR[WSAPROTOCOL_LEN+1] - /// - /// An array of characters that contains a human-readable name identifying the protocol, for example "MSAFD Tcpip [UDP/IP]". The - /// maximum number of characters allowed is WSAPROTOCOL_LEN, which is defined to be 255. - /// - /// - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = WSAPROTOCOL_LEN + 1)] - public string szProtocol; + if (v4addr == null || v4addr.Length < 4) + throw new ArgumentException("Byte array must have 4 items.", nameof(v4addr)); + S_addr = BitConverter.ToUInt32(v4addr, 0); } - /// - /// The WSAPROTOCOLCHAIN structure contains a counted list of Catalog Entry identifiers that comprise a protocol chain. - /// - /// - /// - /// If the length of the chain is larger than 1, this structure represents a protocol chain which consists of one or more layered - /// protocols on top of a base protocol. The corresponding Catalog Entry IDs are in the ProtocolChain.ChainEntries array starting - /// with the layered protocol at the top (the zeroth element in the ProtocolChain.ChainEntries array) and ending with the base - /// protocol. Refer to Windows Sockets 2 Service Provider Interface for more information on protocol chains. - /// - /// - // https://docs.microsoft.com/en-us/windows/desktop/api/winsock2/ns-winsock2-wsaprotocolchain typedef struct _WSAPROTOCOLCHAIN { int - // ChainLen; DWORD ChainEntries[MAX_PROTOCOL_CHAIN]; } WSAPROTOCOLCHAIN, *LPWSAPROTOCOLCHAIN; - [PInvokeData("winsock2.h", MSDNShortId = "c0676f45-e3e3-45f2-9b34-d7318fddc282")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] - public struct WSAPROTOCOLCHAIN + /// Initializes a new instance of the struct. + /// The first byte. + /// The second byte. + /// The third byte. + /// The fourth byte. + public IN_ADDR(byte b1, byte b2, byte b3, byte b4) => S_addr = b1 | (uint)b2 << 8 | (uint)b3 << 16 | (uint)b4 << 24; + + /// Gets the address represented as four bytes. + /// An IPv4 address formatted as four u_chars. + public byte[] S_un_b => BitConverter.GetBytes(S_addr); + + /// + public static readonly IN_ADDR INADDR_ANY = new(0U); + + /// + public static readonly IN_ADDR INADDR_LOOPBACK = new(0x7f000001); + + /// + public static readonly IN_ADDR INADDR_BROADCAST = new(0xffffffff); + + /// + public static readonly IN_ADDR INADDR_NONE = new(0xffffffff); + + /// Implements the operator ==. + /// The left. + /// The right. + /// The result of the operator. + public static bool operator ==(IN_ADDR left, IN_ADDR right) => left.Equals(right); + + /// Implements the operator !=. + /// The left. + /// The right. + /// The result of the operator. + public static bool operator !=(IN_ADDR left, IN_ADDR right) => !left.Equals(right); + + /// Performs an implicit conversion from to . + /// An IN_ADDR value. + /// The result of the conversion. + public static implicit operator uint(IN_ADDR a) => a.S_addr; + + /// Performs an implicit conversion from to . + /// An IN_ADDR value. + /// The result of the conversion. + public static implicit operator long(IN_ADDR a) => a.S_addr; + + /// Performs an implicit conversion from to . + /// An IN_ADDR value. + /// The result of the conversion. + public static implicit operator byte[](IN_ADDR a) => BitConverter.GetBytes(a.S_addr); + + /// Performs an implicit conversion from to . + /// A UInt32 value. + /// The result of the conversion. + public static implicit operator IN_ADDR(uint a) => new(a); + + /// Performs an implicit conversion from to . + /// An Int64 value. + /// The result of the conversion. + public static implicit operator IN_ADDR(long a) => new((uint)a); + + /// Performs an explicit conversion from to . + /// The ipv4. + /// The resulting instance from the conversion. + public static explicit operator IN6_ADDR(IN_ADDR ipv4) => new(ipv4); + + /// Determines equality between this instance and . + /// The other value to compare. + /// if is equal to this instance. + public bool Equals(IN_ADDR other) => S_addr == other.S_addr; + + /// Determines whether the specified , is equal to this instance. + /// The to compare with this instance. + /// if the specified is equal to this instance; otherwise, . + public override bool Equals(object obj) => obj is IN_ADDR i ? Equals(i) : base.Equals(obj); + + /// Returns a hash code for this instance. + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + public override int GetHashCode() => S_addr.GetHashCode(); + + /// Returns a that represents this instance. + /// A that represents this instance. + public override string ToString() { - private const int MAX_PROTOCOL_CHAIN = 7; - - /// - /// Length of the chain, in bytes. The following settings apply: - /// Setting ChainLen to zero indicates a layered protocol - /// Setting ChainLen to one indicates a base protocol - /// Setting ChainLen to greater than one indicates a protocol chain - /// - public int ChainLen; - - /// - /// Array of protocol chain entries. - /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_PROTOCOL_CHAIN)] - public uint[] ChainEntries; - } - - /// Provides a for that is disposed using . - public class SafeSOCKET : 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 SafeSOCKET(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } - - /// Initializes a new instance of the class. - private SafeSOCKET() : base() { } - - /// Represents an invalid socket which is different than a null socket. - /// The invalid socket. - public static SafeSOCKET INVALID_SOCKET => new(new IntPtr(-1), false); - - /// Returns an invalid handle by instantiating a object with . - /// Returns a value. - public static SafeSOCKET NULL => new(IntPtr.Zero, false); - - /// Performs an implicit conversion from to . - /// The safe handle instance. - /// The result of the conversion. - public static implicit operator SOCKET(SafeSOCKET h) => h.handle; - - /// - protected override bool InternalReleaseHandle() => closesocket(this) == 0; - } - - /// - /// - /// The sockaddr structure varies depending on the protocol selected. Except for the sin*_family parameter, sockaddr contents are - /// expressed in network byte order. - /// - /// - /// Winsock functions using sockaddr are not strictly interpreted to be pointers to a sockaddr structure. The structure is - /// interpreted differently in the context of different address families. The only requirements are that the first u_short is - /// the address family and the total size of the memory buffer in bytes is namelen. - /// - /// - /// The structure also stores socket address information and the structure is sufficiently large to store - /// IPv4 or IPv6 address information. The use of the SOCKADDR_STORAGE structure promotes protocol-family and protocol-version - /// independence, and simplifies development. It is recommended that the SOCKADDR_STORAGE structure be used in place of the - /// sockaddr structure. The SOCKADDR_STORAGE structure is supported on Windows Server 2003 and later. - /// - /// The sockaddr structure and sockaddr_in structures below are used with IPv4. Other protocols use similar structures. - /// The sockaddr_in6 and sockaddr_in6_old structures below are used with IPv6. - /// - /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, SOCKADDR and - /// SOCKADDR_IN typedef tags are defined for sockaddr and sockaddr_in structures as follows: - /// - /// - /// On the Windows SDK released for Windows Vista and later, the organization of header files has changed and the sockaddr and - /// sockaddr_in structures are defined in the Ws2def.h header file, not the Winsock2.h header file. The Ws2def.h header file is - /// automatically included by the Winsock2.h header file. The sockaddr_in6 structure is defined in the Ws2ipdef.h header file, not - /// the Ws2tcpip.h header file. The Ws2ipdef.h header file is automatically included by the Ws2tcpip.h header file. The Ws2def.h and - /// Ws2ipdef.h header files should never be used directly. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/winsock/sockaddr-2 - [PInvokeData("winsock2.h", MSDNShortId = "d1392e1c-2b20-425a-8adf-38e665fb6275")] - public class SOCKADDR : SafeMemoryHandle - { - /// Initializes a new instance of the class. - /// The handle to the memory with the address. - /// if set to this class with dispose the memory. - /// The size of the memory pointed to by . - public SOCKADDR(IntPtr handle, bool ownsHandle = false, int size = 0) : base(handle, size, ownsHandle) { } - - /// Initializes a new instance of the class. - /// The IPv4 address value. - /// The port. - public SOCKADDR(uint addr, ushort port = 0) : this(BitConverter.GetBytes(addr), port) - { - } - - /// Initializes a new instance of the class. - /// The IPv4 or IPv6 address as a byte array. - /// The port. - /// The scope identifier for IPv6 addresses. - /// addr - public SOCKADDR(byte[] addr, ushort port = 0, uint scopeId = 0) : - base(addr.Length == 4 ? Marshal.SizeOf(typeof(SOCKADDR_IN)) : Marshal.SizeOf(typeof(SOCKADDR_IN6))) - { - if (addr.Length == 4) - { - var in4 = new SOCKADDR_IN(new IN_ADDR(addr), port); - Marshal.StructureToPtr(in4, handle, false); - } - else if (addr.Length == 16) - { - var in6 = new SOCKADDR_IN6(addr, scopeId, port); - Marshal.StructureToPtr(in6, handle, false); - } - else - throw new ArgumentOutOfRangeException(nameof(addr)); - } - - /// Initializes a new instance of the class. - /// The value to assign. - public SOCKADDR(SOCKADDR_IN addr) : base(Marshal.SizeOf(typeof(SOCKADDR_IN))) => Marshal.StructureToPtr(addr, handle, false); - - /// Initializes a new instance of the class. - /// The value to assign. - public SOCKADDR(SOCKADDR_IN6 addr) : base(Marshal.SizeOf(typeof(SOCKADDR_IN6))) => Marshal.StructureToPtr(addr, handle, false); - - /// Initializes a new instance of the class. - /// The ip address. - public SOCKADDR(IPAddress ipAddress) : this(ipAddress.GetAddressBytes()) { } - - /// Initializes a new instance of the class. - /// The socket address. - public SOCKADDR(IPEndPoint endPoint) : this(endPoint.Address.GetAddressBytes(), (ushort)endPoint.Port) { } - - internal SOCKADDR(SOCKET_ADDRESS addr) : base(addr.iSockaddrLength) => addr.lpSockaddr.CopyTo(handle, addr.iSockaddrLength); - - /// Gets an instance that represents an empty address. - public static SOCKADDR Empty => new(new byte[Marshal.SizeOf(typeof(IN6_ADDR))]); - - /// Gets the data behind this address as a byte array. - /// The address data. - public byte[] sa_data => GetBytes(2, 14); - - /// Gets the of this address. - /// The address family. - public ADDRESS_FAMILY sa_family => (ADDRESS_FAMILY)handle.ToStructure(); - - /// Allocates from unmanaged memory sufficient memory to hold an object of type T. - /// Native type - /// The value. - /// object to an native (unmanaged) memory block the size of T. - public static SOCKADDR CreateFromStructure(T value = default) => new(InteropExtensions.MarshalToPtr(value, mm.AllocMem, out int s), true, s); - - /// Performs an explicit conversion from to . - /// The address. - /// The resulting instance from the conversion. - /// - public static explicit operator SOCKADDR_IN(SOCKADDR addr) => addr.sa_family is ADDRESS_FAMILY.AF_INET or ADDRESS_FAMILY.AF_UNSPEC ? addr.handle.ToStructure() : throw new InvalidCastException(); - - /// Performs an explicit conversion from to . - /// The address. - /// The resulting instance from the conversion. - /// - public static explicit operator SOCKADDR_IN6(SOCKADDR addr) => addr.sa_family == ADDRESS_FAMILY.AF_INET6 ? addr.handle.ToStructure() : (SOCKADDR_IN6)(SOCKADDR_IN)addr; - - /// Performs an explicit conversion from to . - /// The address. - /// The resulting instance from the conversion. - /// - public static explicit operator SOCKADDR_INET(SOCKADDR addr) => addr.sa_family == ADDRESS_FAMILY.AF_INET6 ? addr.handle.ToStructure() : (SOCKADDR_INET)(SOCKADDR_IN)addr; - - /// Performs an implicit conversion from to . - /// The address. - /// The resulting instance from the conversion. - public static implicit operator IntPtr(SOCKADDR addr) => addr.DangerousGetHandle(); - - /// Performs an implicit conversion from to . - /// The address. - /// The resulting instance from the conversion. - public static implicit operator SOCKADDR(SOCKADDR_IN addr) => new(addr); - - /// Performs an implicit conversion from to . - /// The address. - /// The resulting instance from the conversion. - public static implicit operator SOCKADDR(SOCKADDR_IN6 addr) => new(addr); - - /// Performs an implicit conversion from to . - /// The address. - /// The resulting instance from the conversion. - public static implicit operator SOCKADDR(SOCKADDR_INET addr) => CreateFromStructure(addr); - - /// Provides a copy of as an array of bytes. - /// The array of bytes from this instance. - public byte[] GetAddressBytes() => GetBytes(0, Size); - - /// - public override string ToString() => sa_family == ADDRESS_FAMILY.AF_INET ? ((SOCKADDR_IN)this).ToString() : ((SOCKADDR_IN6)this).ToString(); + var b = S_un_b; + return $"{b[0]}.{b[1]}.{b[2]}.{b[3]}"; } } + + /// The IN6_ADDR structure represents an IPv6 address. + [PInvokeData("winsock2.h")] + [StructLayout(LayoutKind.Sequential, Size = IN6_ADDR_SIZE)] + public struct IN6_ADDR : IEquatable + { + private const int IN6_ADDR_SIZE = 16; + + private ulong lower; + private ulong upper; + + /// The IPv6 standard loopback address (IN6ADDR_LOOPBACK_INIT). + public static readonly IN6_ADDR Loopback = new(new byte[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }); + + /// The IPv6 standard unspecified address (IN6ADDR_ANY_INIT). + public static readonly IN6_ADDR Unspecified = new(); + + /// Initializes a new instance of the struct. + /// The IPv6 address as an array of bytes. + public IN6_ADDR(byte[] v6addr) + { + lower = upper = 0; + bytes = v6addr; + } + + /// Initializes a new instance of the struct from an . + /// The ipv4 address. + public IN6_ADDR(IN_ADDR ipv4) + { + lower = 0; + upper = Macros.MAKELONG64(0xffff0000, ipv4.S_addr); + } + + /// Gets or sets the byte array representing the IPv6 address. + /// The bytes. + /// Byte array must have 16 items. - value + public byte[] bytes + { + get + { + unsafe + { + var v6addr = new byte[IN6_ADDR_SIZE]; + fixed (byte* usp = &v6addr[0]) + { + var ulp2 = (ulong*)usp; + ulp2[0] = lower; + ulp2[1] = upper; + } + return v6addr; + } + } + set + { + unsafe + { + if (value == null) value = new byte[IN6_ADDR_SIZE]; + if (value.Length != IN6_ADDR_SIZE) + throw new ArgumentException("Byte array must have 16 items.", nameof(value)); + fixed (byte* bp = &value[0]) + { + var ulp = (ulong*)bp; + lower = ulp[0]; + upper = ulp[1]; + } + } + } + } + + /// Gets a value indicating whether this instance is an anycast address. + /// if this instance is an anycast address; otherwise, . + public bool IsAnycast => IsSubnetRerservedAnycast || IsSubnetRouterAnycast; + + /// Gets a value indicating whether this instance uses EUI-64 interface identifiers. + /// if this instance uses EUI-64 interface identifiers; otherwise, . + public bool IsEUI64 => (bytes[0] & 0xe0) != 0 && !IsMulticast; + + /// Gets a value indicating whether this instance is a global address. + /// if this instance is a global address; otherwise, . + public bool IsGlobal + { + get + { + var High = bytes[0] & 0xf0u; + return High != 0 && High != 0xf0; + } + } + + /// Gets a value indicating whether this instance is a link local address. + /// if this instance is a link local address; otherwise, . + public bool IsLinkLocal + { + get + { + var b = bytes; + return b[0] == 0xfe && (b[1] & 0xc0) == 0x80; + } + } + + /// Gets a value indicating whether this instance is a LOOPBACK address. + /// if this instance is a LOOPBACK address; otherwise, . + public bool IsLoopback => Equals(Loopback); + + /// Gets a value indicating whether this instance is a MULTICAST address. + /// if this instance is a MULTICAST address; otherwise, . + public bool IsMulticast => bytes[0] == 0xff; + + /// Gets a value indicating whether this instance is a site local address. + /// if this instance is a site local address; otherwise, . + public bool IsSiteLocal + { + get + { + var b = bytes; + return b[0] == 0xfe && (b[1] & 0xc0) == 0xc0; + } + } + + /// Gets a value indicating whether the subnet router anycast address. + /// if the subnet router anycast address; otherwise, . + public bool IsSubnetRouterAnycast => IsEUI64 && upper == 0; + + /// Gets a value indicating whether the subnet reserved anycast address. + /// if the subnet reserved anycast address; otherwise, . + public bool IsSubnetRerservedAnycast + { + get + { + var w = words; + return IsEUI64 && w[4] == 0xfffd && w[5] == 0xffff && w[6] == 0xffff && (w[7] & 0x80ff) == 0x80ff; + } + } + + /// Gets a value indicating whether this instance is an UNSPECIFIED address. + /// if this instance is an UNSPECIFIED address; otherwise, . + public bool IsUnspecified => Equals(Unspecified); + + /// Gets a value indicating whether this instance is an IPv4 compatible address. + /// if this instance is an IPv4 compatible address; otherwise, . + public bool IsV4Compatible + { + get + { + var w = words; + var b = bytes; + return lower == 0 && w[4] == 0 && w[5] == 0 && w[6] == 0 && b[14] == 0 && (b[15] == 0 || b[15] == 1); + } + } + + /// Gets a value indicating whether this instance is an IPv4 mapped address. + /// if this instance is an IPv4 mapped address; otherwise, . + public bool IsV4Mapped + { + get + { + var w = words; + return lower == 0 && w[4] == 0 && w[5] == 0xffff; + } + } + + /// Gets a value indicating whether this instance is an IPv4 translated address. + /// if this instance is an IPv4 translated address; otherwise, . + public bool IsV4Translated + { + get + { + var w = words; + return lower == 0 && w[4] == 0xffff && w[5] == 0; + } + } + + /// Gets or sets the array of WORD (ushort) values representing the IPv6 address. + /// The array of WORD values. + /// UInt16 array must have 8 items. - value + public ushort[] words + { + get + { + unsafe + { + var v6addr = new ushort[IN6_ADDR_SIZE / 2]; + fixed (ushort* usp = &v6addr[0]) + { + var ulp2 = (ulong*)usp; + ulp2[0] = lower; + ulp2[1] = upper; + } + return v6addr; + } + } + set + { + unsafe + { + if (value == null) value = new ushort[IN6_ADDR_SIZE / 2]; + if (value.Length != IN6_ADDR_SIZE / 2) + throw new ArgumentException("UInt16 array must have 8 items.", nameof(value)); + fixed (ushort* bp = &value[0]) + { + var ulp = (ulong*)bp; + lower = ulp[0]; + upper = ulp[1]; + } + } + } + } + + /// Implements the operator ==. + /// The left. + /// The right. + /// The result of the operator. + public static bool operator ==(IN6_ADDR left, IN6_ADDR right) => left.Equals(right); + + /// Implements the operator !=. + /// The left. + /// The right. + /// The result of the operator. + public static bool operator !=(IN6_ADDR left, IN6_ADDR right) => !left.Equals(right); + + /// Performs an implicit conversion from [] to . + /// The byte array. + /// The resulting instance from the conversion. + public static implicit operator IN6_ADDR(byte[] a) => new(a); + + /// Performs an implicit conversion from to []. + /// The instance. + /// The resulting [] instance from the conversion. + public static implicit operator byte[](IN6_ADDR a) => a.bytes; + + /// Determines whether the specified , is equal to this instance. + /// The to compare with this instance. + /// if the specified is equal to this instance; otherwise, . + public override bool Equals(object obj) => obj is IN6_ADDR i ? Equals(i) : base.Equals(obj); + + /// Returns a hash code for this instance. + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + public override int GetHashCode() => (lower, upper).GetHashCode(); + + /// Converts to string. + /// A that represents this instance. + public override string ToString() + { + const string numberFormat = "{0:x4}:{1:x4}:{2:x4}:{3:x4}:{4:x4}:{5:x4}:{6}.{7}.{8}.{9}"; + var m_Numbers = words; + return string.Format(System.Globalization.CultureInfo.InvariantCulture, numberFormat, + m_Numbers[0], m_Numbers[1], m_Numbers[2], m_Numbers[3], m_Numbers[4], m_Numbers[5], + (m_Numbers[6] >> 8) & 0xFF, m_Numbers[6] & 0xFF, (m_Numbers[7] >> 8) & 0xFF, m_Numbers[7] & 0xFF); + } + + /// Determines whether the specified value is equal to this instance. + /// The value to compare with this instance. + /// if the specified value is equal to this instance; otherwise, . + public bool Equals(IN6_ADDR other) => lower == other.lower && upper == other.upper; + } + + /// + /// The linger structure maintains information about a specific socket that specifies how that socket should behave when data + /// is queued to be sent and the closesocket function is called on the socket. + /// + /// + /// + /// The l_onoff member of the linger structure determines whether a socket should remain open for a specified amount + /// of time after a closesocket function call to enable queued data to be sent. Somewhat confusing is that this member can be + /// modified in two ways: + /// + /// + /// + /// + /// Call the setsockopt function with the optname parameter set to SO_DONTLINGER. The optval parameter determines how the + /// l_onoff member is modified. + /// + /// + /// + /// + /// Call the setsockopt function with the optname parameter set to SO_LINGER. The optval parameter specifies how both the + /// l_onoff and l_linger members are modified. + /// + /// + /// + /// + /// The l_linger member of the linger structure determines the amount of time, in seconds, a socket should remain + /// open. This member is only applicable if the l_onoff member of the linger structure is nonzero. + /// + /// + /// To enable a socket to remain open, an application should set the l_onoff member to a nonzero value and set the + /// l_linger member to the desired time-out in seconds. To disable a socket from remaining open, an application only needs to + /// set the l_onoff member of the linger structure to zero. + /// + /// + /// If an application calls the setsockopt function with the optname parameter set to SO_DONTLINGER to set the l_onoff + /// member to a nonzero value, the value for the l_linger member is not specified. In this case, the time-out used is + /// implementation dependent. If a previous time-out has been established for a socket (by enabling SO_LINGER), this time-out value + /// should be reinstated by the service provider. + /// + /// Note that enabling a nonzero timeout on a nonblocking socket is not recommended. + /// + /// The getsockopt function can be called with the optname parameter set to SO_LINGER to retrieve the current value of the + /// linger structure associated with a socket. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winsock/ns-winsock-linger typedef struct linger { u_short l_onoff; u_short + // l_linger; } LINGER, *PLINGER, *LPLINGER; + [PInvokeData("winsock.h", MSDNShortId = "c1dbabcf-b5cd-4a9d-9bf9-b04c62117d74")] + [StructLayout(LayoutKind.Sequential)] + public struct LINGER + { + /// + /// Type: u_short + /// + /// Specifies whether a socket should remain open for a specified amount of time after a closesocket function call to enable + /// queued data to be sent. This member can have one of the following values. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// 0 + /// + /// The socket will not remain open. This is the value set if the setsockopt function is called with the optname parameter set + /// to SO_DONTLINGER and the optval parameter is zero. This value is also set if the setsockopt function is called with the + /// optname parameter set to SO_LINGER and the linger structure passed in the optval parameter has the l_onoff member set to 0. + /// + /// + /// + /// nonzero + /// + /// The socket will remain open for a specified amount of time. This value is set if the setsockopt function is called with the + /// optname parameter set to SO_DONTLINGER and the optval parameter is nonzero. This value is also set if the setsockopt + /// function is called with the optname parameter set to SO_LINGER and the linger structure passed in the optval parameter has + /// the l_onoff member set to a nonzero value. + /// + /// + /// + /// + public ushort l_onoff; + + /// + /// Type: u_short + /// + /// The linger time in seconds. This member specifies how long to remain open after a closesocket function call to enable queued + /// data to be sent. This member is only applicable if the l_onoff member of the linger structure is set to a + /// nonzero value. + /// + /// + /// This value is set if the setsockopt function is called with the optname parameter set to SO_LINGER. The optval + /// parameter passed to the setsockopt function must contain a linger structure that is copied to the internal + /// linger structure maintained for the socket. + /// + /// + public ushort l_linger; + } + + /// + /// The QOS structure provides the means by which QOS-enabled applications can specify quality of service parameters for sent + /// and received traffic on a particular flow. + /// + /// + /// Most applications can fulfill their quality of service requirements without using the ProviderSpecific buffer. However, if the + /// application must provide information not available with standard Windows 2000 QOS parameters, the ProviderSpecific buffer allows + /// the application to provide additional parameters for RSVP and/or traffic control. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winsock2/ns-winsock2-_qualityofservice typedef struct _QualityOfService { + // FLOWSPEC SendingFlowspec; FLOWSPEC ReceivingFlowspec; WSABUF ProviderSpecific; } QOS, *LPQOS; + [PInvokeData("winsock2.h", MSDNShortId = "859faa13-bd66-46ee-8452-6ff5d53d66c9")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct QOS + { + /// + /// Specifies QOS parameters for the sending direction of a particular flow. SendingFlowspec is sent in the form of a FLOWSPEC structure. + /// + public FLOWSPEC SendingFlowspec; + + /// + /// Specifies QOS parameters for the receiving direction of a particular flow. ReceivingFlowspec is sent in the form of a + /// FLOWSPEC structure. + /// + public FLOWSPEC ReceivingFlowspec; + + /// + /// Pointer to a structure of type WSABUF that can provide additional provider-specific quality of service parameters to the + /// RSVP SP for a given flow. + /// + public WSABUF ProviderSpecific; + } + + /// + /// Represents info supplied to the ProcessSocketNotifications function. + /// For more info, and code examples, see Winsock socket state notifications. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/ns-winsock2-sock_notify_registration typedef struct + // SOCK_NOTIFY_REGISTRATION { SOCKET socket; PVOID completionKey; UINT16 eventFilter; UINT8 operation; UINT8 triggerFlags; DWORD + // registrationResult; } SOCK_NOTIFY_REGISTRATION; + [PInvokeData("winsock2.h", MSDNShortId = "NS:winsock2.SOCK_NOTIFY_REGISTRATION")] + [StructLayout(LayoutKind.Sequential)] + public struct SOCK_NOTIFY_REGISTRATION + { + /// + /// Type: SOCKET + /// + /// A handle to a Winsock socket opened by any of the WSASocket, socket, WSAAccept, accept, or WSADuplicateSocket functions. + /// Only Microsoft Winsock provider sockets are supported. + /// + /// + public SOCKET socket; + + /// + /// Type: PVOID + /// + /// The value to use in the dwCompletionKey parameter of the PostQueuedCompletionStatus function when notifications are sent on + /// behalf of the socket. This parameter is used upon registration creation. To change the completion key, remove the + /// registration and re-register it. + /// + /// + public IntPtr completionKey; + + /// + /// Type: UINT16 + /// + /// A set of flags indicating the notifications being requested. This must be one or more of the following values (defined in + /// WinSock2.h + /// ). + /// + /// + /// SOCK_NOTIFY_REGISTER_EVENT_NONE. Notifications should not be issued. SOCK_NOTIFY_REGISTER_EVENT_IN. A + /// notification should be issued when data can be read without blocking. SOCK_NOTIFY_REGISTER_EVENT_OUT. A notification + /// should be issued when data can be written without blocking. SOCK_NOTIFY_REGISTER_EVENT_HANGUP. A notification should + /// be issued when a stream-oriented connection was either disconnected or aborted. SOCK_NOTIFY_REGISTER_EVENTS_ALL. Has + /// the value + /// (SOCK_NOTIFY_REGISTER_EVENT_IN | SOCK_NOTIFY_REGISTER_EVENT_OUT | SOCK_NOTIFY_REGISTER_EVENT_HANGUP) + /// . + /// + /// + public SOCK_NOTIFY_REGISTER_EVENT eventFilter; + + /// + /// Type: UINT8 + /// + /// Indicates the operation to perform on a registration. At most one operation may be performed at a time. These values are + /// defined in + /// WinSock2.h + /// . + /// + /// + /// SOCK_NOTIFY_OP_NONE. No registration operations should take place. Use this if your application calls + /// ProcessSocketNotifications and is only interested in receiving notifications. SOCK_NOTIFY_OP_ENABLE. Enables the + /// registration. Notifications must not be re-enabled until the SOCK_NOTIFY_EVENT_DISABLE notification is received. + /// SOCK_NOTIFY_OP_DISABLE. Disables the registration, but doesn't destroy the underlying data structures. Note that this + /// doesn't remove the registration, it merely suppresses queuing of new notifications. Notifications that have already been + /// queued might still be delivered until the SOCK_NOTIFY_EVENT_DISABLE event is received. SOCK_NOTIFY_OP_REMOVE. + /// Removes a previously-registered notification. Both enabled and disabled notifications may be removed. The + /// SOCK_NOTIFY_EVENT_REMOVE notification is issued, with the guarantee that no more notifications will be issued + /// afterwards for that completion key unless it is re-registered. + /// + /// + public SOCK_NOTIFY_OP operation; + + /// + /// Type: UINT8 + /// A set of flags indicating the trigger behavior (defined in + /// WinSock2.h + /// ). + /// + /// + /// SOCK_NOTIFY_TRIGGER_ONESHOT. The registration will be disabled (not removed) upon delivery of the next notification. + /// SOCK_NOTIFY_TRIGGER_PERSISTENT. The registration will remain active until it is explicitly disabled or removed. + /// SOCK_NOTIFY_TRIGGER_LEVEL. The registration is for level-triggered notifications. Not compatible with edge-triggered. + /// One of edge- or level-triggered must be supplied. SOCK_NOTIFY_TRIGGER_EDGE. The registration is for edge-triggered + /// notifications. Not compatible with level-triggered. One of edge- or level-triggered must be supplied. + /// + /// + /// Notifications are only supplied when the registration is enabled. Notifications are not queued up while the registration is + /// disabled. As notifications are queued up for a given socket, they are coalesced into a single notification. Therefore, + /// multiple events may be described by a single event mask for the socket. + /// + /// Given the registration is enabled, level-triggered notifications are supplied whenever the desired conditions hold. + /// + /// Given the registration is enabled, edge-triggered notifications are supplied whenever a condition changes from not holding + /// to holding. The condition must change while the registration is enabled for a notification to be queued. As such, after + /// registering, the socket's receive buffer must be completely drained to ensure a notification is received. + /// + /// + public SOCK_NOTIFY_TRIGGER triggerFlags; + + /// + /// Type: DWORD + /// + /// After a successful call to ProcessSocketNotifications, registrationResult contains a code indicating the success or failure + /// of the registration. A value of ERROR_SUCCESS indicates that registration was successful. + /// + /// + public Win32Error registrationResult; + } + + /// Provides a handle to a socket. + /// + [PInvokeData("winsock2.h")] + [StructLayout(LayoutKind.Sequential)] + public struct SOCKET : IHandle + { + /// The handle + private readonly IntPtr handle; + + /// Initializes a new instance of the struct. + /// An object that represents the pre-existing handle to use. + public SOCKET(IntPtr preexistingHandle) => handle = preexistingHandle; + + /// Represents an invalid socket which is different than a null socket. + /// The invalid socket. + public static SOCKET INVALID_SOCKET => new(new IntPtr(-1)); + + /// Returns an invalid handle by instantiating a object with . + /// Returns a value. + public static SOCKET NULL => new(IntPtr.Zero); + + /// Gets a value indicating whether this instance is a null handle. + /// if this instance is null; otherwise, . + public bool IsNull => handle == IntPtr.Zero; + + /// Performs an explicit conversion from to . + /// The handle. + /// The result of the conversion. + public static explicit operator IntPtr(SOCKET h) => h.handle; + + /// Performs an implicit conversion from to . + /// The pointer to a handle. + /// The result of the conversion. + public static implicit operator SOCKET(IntPtr h) => new(h); + + /// Implements the operator !=. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator !=(SOCKET h1, SOCKET h2) => !(h1 == h2); + + /// Implements the operator ==. + /// The first handle. + /// The second handle. + /// The result of the operator. + public static bool operator ==(SOCKET h1, SOCKET h2) => h1.Equals(h2); + + /// Determines whether the specified , is equal to this instance. + /// The to compare with this instance. + /// + /// if the specified is equal to this instance; otherwise, . + /// + /// + public override bool Equals(object obj) => obj is SOCKET h && handle == h.handle; + + /// Returns a hash code for this instance. + /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. + /// + public override int GetHashCode() => handle.GetHashCode(); + + /// Returns the value of the handle field. + /// An IntPtr representing the value of the handle field. + /// + public IntPtr DangerousGetHandle() => handle; + + /// + public override string ToString() => handle.ToString(); + } + + /// + /// The timeval structure is used to specify a time interval. It is associated with the Berkeley Software Distribution (BSD) + /// Time.h header file. + /// + /// + /// + /// The timeval structure is used in Windows Sockets by the select function to specify the maximum time the function can take + /// to complete. The time interval is a combination of the values in tv_sec and tv_usec members. + /// + /// + /// Several functions are added on Windows Vista and later that use the timeval structure. These functions include + /// GetAddrInfoEx, SetAddrInfoEx, WSAConnectByList, and WSAConnectByName. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winsock/ns-winsock-timeval typedef struct timeval { long tv_sec; long tv_usec; + // } TIMEVAL, *PTIMEVAL, *LPTIMEVAL; + [PInvokeData("winsock.h", MSDNShortId = "3024c961-bb47-40ac-a49c-b12cd431e4e7")] + [StructLayout(LayoutKind.Sequential)] + public struct TIMEVAL + { + /// Time interval, in seconds. + public int tv_sec; + + /// + /// Time interval, in microseconds. This value is used in combination with the tv_sec member to represent time interval + /// values that are not a multiple of seconds. + /// + public int tv_usec; + + /// Performs an explicit conversion from to . + /// The time span. + /// The resulting instance from the conversion. + public static explicit operator TIMEVAL(TimeSpan timeSpan) + { + var tr = Math.Truncate(timeSpan.TotalSeconds); + return new TIMEVAL { tv_sec = (int)tr, tv_usec = (int)((timeSpan.Ticks - TimeSpan.TicksPerSecond * (long)tr) / TimeSpan.TicksPerMillisecond) }; + } + } + + /// The WSADATA structure contains information about the Windows Sockets implementation. + /// + /// + /// The WSAStartup function initiates the use of the Windows Sockets DLL by a process. The WSAStartup function returns a + /// pointer to the WSADATA structure in the lpWSADataparameter. + /// + /// The current version of the Windows Sockets specification returned in the wHighVersion member of the + /// + /// WSADATA structure is version 2.2 encoded with the major version number in the low-byte and the minor version number in + /// the high-byte. This version of the current Winsock DLL, Ws2_32.dll, supports applications that request any of the following + /// versions of the Windows Sockets specification: + /// + /// + /// + /// 1.0 + /// + /// + /// 1.1 + /// + /// + /// 2.0 + /// + /// + /// 2.1 + /// + /// + /// 2.2 + /// + /// + /// + /// Depending on the version requested by the application, one of the above version numbers is the value encoded as the major + /// version number in the low-byte and the minor version number in the high-byte that is returned in the wVersion member of + /// the WSADATA structure. + /// + /// + /// Note An application should ignore the iMaxsockets, iMaxUdpDg, and lpVendorInfo members in + /// WSADATA if the value in wVersion after a successful call to WSAStartup is at least 2. This is because the + /// architecture of Windows Sockets changed in version 2 to support multiple providers, and WSADATA no longer applies to a + /// single vendor's stack. Two new socket options are introduced to supply provider-specific information: SO_MAX_MSG_SIZE (replaces + /// the iMaxUdpDg member) and PVD_CONFIG (allows any other provider-specific configuration to occur). + /// + /// Examples + /// The following example demonstrates the use of the WSADATA structure. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winsock/ns-winsock-wsadata typedef struct WSAData { WORD wVersion; WORD + // wHighVersion; unsigned short iMaxSockets; unsigned short iMaxUdpDg; char *lpVendorInfo; char szDescription[WSADESCRIPTION_LEN + + // 1]; char szSystemStatus[WSASYS_STATUS_LEN + 1]; } WSADATA; + [PInvokeData("winsock.h", MSDNShortId = "c3c4c0d6-c8b3-4991-bedb-f45816cc8160")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)] + public struct WSADATA + { + private const int WSADESCRIPTION_LEN = 256; + private const int WSASYS_STATUS_LEN = 128; + + /// + /// Type: WORD + /// + /// The version of the Windows Sockets specification that the Ws2_32.dll expects the caller to use. The high-order byte + /// specifies the minor version number; the low-order byte specifies the major version number. + /// + /// + public ushort wVersion; + + /// + /// Type: WORD + /// + /// The highest version of the Windows Sockets specification that the Ws2_32.dll can support. The high-order byte specifies the + /// minor version number; the low-order byte specifies the major version number. + /// + /// + /// This is the same value as the wVersion member when the version requested in the wVersionRequested parameter passed to + /// the WSAStartup function is the highest version of the Windows Sockets specification that the Ws2_32.dll can support. + /// + /// + public ushort wHighVersion; + + /// + /// Type: unsigned short + /// + /// The maximum number of sockets that may be opened. This member should be ignored for Windows Sockets version 2 and later. + /// + /// + /// The iMaxSockets member is retained for compatibility with Windows Sockets specification 1.1, but should not be used + /// when developing new applications. No single value can be appropriate for all underlying service providers. The architecture + /// of Windows Sockets changed in version 2 to support multiple providers, and the WSADATA structure no longer applies to + /// a single vendor's stack. + /// + /// + public ushort iMaxSockets; + + /// + /// Type: unsigned short + /// The maximum datagram message size. This member is ignored for Windows Sockets version 2 and later. + /// + /// The iMaxUdpDg member is retained for compatibility with Windows Sockets specification 1.1, but should not be used + /// when developing new applications. The architecture of Windows Sockets changed in version 2 to support multiple providers, + /// and the WSADATA structure no longer applies to a single vendor's stack. For the actual maximum message size specific + /// to a particular Windows Sockets service provider and socket type, applications should use getsockopt to retrieve the value + /// of option SO_MAX_MSG_SIZE after a socket has been created. + /// + /// + public ushort iMaxUdpDg; + + /// + /// Type: char FAR* + /// A pointer to vendor-specific information. This member should be ignored for Windows Sockets version 2 and later. + /// + /// The lpVendorInfo member is retained for compatibility with Windows Sockets specification 1.1. The architecture of + /// Windows Sockets changed in version 2 to support multiple providers, and the WSADATA structure no longer applies to a + /// single vendor's stack. Applications needing to access vendor-specific configuration information should use getsockopt to + /// retrieve the value of option PVD_CONFIG for vendor-specific information. + /// + /// + public IntPtr lpVendorInfo; + + /// + /// Type: char[WSADESCRIPTION_LEN+1] + /// + /// A NULL-terminated ASCII string into which the Ws2_32.dll copies a description of the Windows Sockets implementation. + /// The text (up to 256 characters in length) can contain any characters except control and formatting characters. The most + /// likely use that an application would have for this member is to display it (possibly truncated) in a status message. + /// + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = WSADESCRIPTION_LEN + 1)] + public string szDescription; + + /// + /// Type: char[WSASYS_STATUS_LEN+1] + /// + /// A NULL-terminated ASCII string into which the Ws2_32.dll copies relevant status or configuration information. The + /// Ws2_32.dll should use this parameter only if the information might be useful to the user or support staff. This member + /// should not be considered as an extension of the szDescription parameter. + /// + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = WSASYS_STATUS_LEN + 1)] + public string szSystemStatus; + } + + /// + /// The WSAPROTOCOL_INFO structure is used to store or retrieve complete information for a given protocol. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winsock2/ns-winsock2-_wsaprotocol_infoa typedef struct _WSAPROTOCOL_INFOA { + // DWORD dwServiceFlags1; DWORD dwServiceFlags2; DWORD dwServiceFlags3; DWORD dwServiceFlags4; DWORD dwProviderFlags; GUID + // ProviderId; DWORD dwCatalogEntryId; WSAPROTOCOLCHAIN ProtocolChain; int iVersion; int iAddressFamily; int iMaxSockAddr; int + // iMinSockAddr; int iSocketType; int iProtocol; int iProtocolMaxOffset; int iNetworkByteOrder; int iSecurityScheme; DWORD + // dwMessageSize; DWORD dwProviderReserved; CHAR szProtocol[WSAPROTOCOL_LEN + 1]; } WSAPROTOCOL_INFOA, *LPWSAPROTOCOL_INFOA; + [PInvokeData("winsock2.h", MSDNShortId = "758c5553-056f-4ea5-a851-30ef641ffb14")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct WSAPROTOCOL_INFO + { + private const int WSAPROTOCOL_LEN = 255; + + /// + /// Type: DWORD + /// + /// A bitmask that describes the services provided by the protocol. The possible values for this member are defined in the + /// Winsock2.h header file. + /// + /// The following values are possible. + /// + /// + /// Value + /// Meaning + /// + /// + /// XP1_CONNECTIONLESS 0x00000001 + /// Provides connectionless (datagram) service. If not set, the protocol supports connection-oriented data transfer. + /// + /// + /// XP1_GUARANTEED_DELIVERY 0x00000002 + /// Guarantees that all data sent will reach the intended destination. + /// + /// + /// XP1_GUARANTEED_ORDER 0x00000004 + /// + /// Guarantees that data only arrives in the order in which it was sent and that it is not duplicated. This characteristic does + /// not necessarily mean that the data is always delivered, but that any data that is delivered is delivered in the order in + /// which it was sent. + /// + /// + /// + /// XP1_MESSAGE_ORIENTED 0x00000008 + /// Honors message boundaries—as opposed to a stream-oriented protocol where there is no concept of message boundaries. + /// + /// + /// XP1_PSEUDO_STREAM 0x00000010 + /// + /// A message-oriented protocol, but message boundaries are ignored for all receipts. This is convenient when an application + /// does not desire message framing to be done by the protocol. + /// + /// + /// + /// XP1_GRACEFUL_CLOSE 0x00000020 + /// Supports two-phase (graceful) close. If not set, only abortive closes are performed. + /// + /// + /// XP1_EXPEDITED_DATA 0x00000040 + /// Supports expedited (urgent) data. + /// + /// + /// XP1_CONNECT_DATA 0x00000080 + /// Supports connect data. + /// + /// + /// XP1_DISCONNECT_DATA 0x00000100 + /// Supports disconnect data. + /// + /// + /// XP1_SUPPORT_BROADCAST 0x00000200 + /// Supports a broadcast mechanism. + /// + /// + /// XP1_SUPPORT_MULTIPOINT 0x00000400 + /// Supports a multipoint or multicast mechanism. Control and data plane attributes are indicated below. + /// + /// + /// XP1_MULTIPOINT_CONTROL_PLANE 0x00000800 + /// Indicates whether the control plane is rooted (value = 1) or nonrooted (value = 0). + /// + /// + /// XP1_MULTIPOINT_DATA_PLANE 0x00001000 + /// Indicates whether the data plane is rooted (value = 1) or nonrooted (value = 0). + /// + /// + /// XP1_QOS_SUPPORTED 0x00002000 + /// Supports quality of service requests. + /// + /// + /// XP1_INTERRUPT + /// Bit is reserved. + /// + /// + /// XP1_UNI_SEND 0x00008000 + /// Protocol is unidirectional in the send direction. + /// + /// + /// XP1_UNI_RECV 0x00010000 + /// Protocol is unidirectional in the recv direction. + /// + /// + /// XP1_IFS_HANDLES 0x00020000 + /// Socket descriptors returned by the provider are operating system Installable File System (IFS) handles. + /// + /// + /// XP1_PARTIAL_MESSAGE 0x00040000 + /// The MSG_PARTIAL flag is supported in WSASend and WSASendTo. + /// + /// + /// XP1_SAN_SUPPORT_SDP 0x00080000 + /// The protocol provides support for SAN. This value is supported on Windows 7 and Windows Server 2008 R2. + /// + /// + /// + /// Note Only one of XP1_UNI_SEND or XP1_UNI_RECV values may be set. If a protocol can be unidirectional in either + /// direction, two WSAPROTOCOL_INFOW structures should be used. When neither bit is set, the protocol is considered to be bidirectional. + /// + /// + public XP1 dwServiceFlags1; + + /// + /// Type: DWORD + /// Reserved for additional protocol-attribute definitions. + /// + public uint dwServiceFlags2; + + /// + /// Type: DWORD + /// Reserved for additional protocol-attribute definitions. + /// + public uint dwServiceFlags3; + + /// + /// Type: DWORD + /// + /// A set of flags that provides information on how this protocol is represented in the Winsock catalog. The possible values for + /// this member are defined in the Winsock2.h header file. + /// + /// The following flag values are possible. + /// + /// + /// Value + /// Meaning + /// + /// + /// PFL_MULTIPLE_PROTO_ENTRIES 0x00000001 + /// + /// Indicates that this is one of two or more entries for a single protocol (from a given provider) which is capable of + /// implementing multiple behaviors. An example of this is SPX which, on the receiving side, can behave either as a + /// message-oriented or a stream-oriented protocol. + /// + /// + /// + /// PFL_RECOMMENDED_PROTO_ENTRY 0x00000002 + /// + /// Indicates that this is the recommended or most frequently used entry for a protocol that is capable of implementing multiple behaviors. + /// + /// + /// + /// PFL_HIDDEN 0x00000004 + /// + /// Set by a provider to indicate to the Ws2_32.dll that this protocol should not be returned in the result buffer generated by + /// WSAEnumProtocols. Obviously, a Windows Sockets 2 application should never see an entry with this bit set. + /// + /// + /// + /// PFL_MATCHES_PROTOCOL_ZERO 0x00000008 + /// Indicates that a value of zero in the protocol parameter of socket or WSASocket matches this protocol entry. + /// + /// + /// PFL_NETWORKDIRECT_PROVIDER 0x00000010 + /// + /// Set by a provider to indicate support for network direct access. This value is supported on Windows 7 and Windows Server + /// 2008 R2. + /// + /// + /// + /// + public uint dwServiceFlags4; + + /// + /// Type: DWORD + /// Reserved for additional protocol-attribute definitions. + /// + public uint dwProviderFlags; + + /// + /// Type: GUID + /// + /// A globally unique identifier (GUID) assigned to the provider by the service provider vendor. This value is useful for + /// instances where more than one service provider is able to implement a particular protocol. An application can use the + /// ProviderId member to distinguish between providers that might otherwise be indistinguishable. + /// + /// + public Guid ProviderId; + + /// + /// Type: DWORD + /// A unique identifier assigned by the WS2_32.DLL for each WSAPROTOCOL_INFO structure. + /// + public uint dwCatalogEntryId; + + /// + /// Type: WSAPROTOCOLCHAIN + /// + /// The WSAPROTOCOLCHAIN structure associated with the protocol. If the length of the chain is 0, this WSAPROTOCOL_INFO + /// entry represents a layered protocol which has Windows Sockets 2 SPI as both its top and bottom edges. If the length of the + /// chain equals 1, this entry represents a base protocol whose Catalog Entry identifier is in the dwCatalogEntryId + /// member of the WSAPROTOCOL_INFO structure. If the length of the chain is larger than 1, this entry represents a + /// protocol chain which consists of one or more layered protocols on top of a base protocol. The corresponding Catalog Entry + /// identifiers are in the ProtocolChain.ChainEntries array starting with the layered protocol at the top (the zero element in + /// the ProtocolChain.ChainEntries array) and ending with the base protocol. Refer to the Windows Sockets 2 Service Provider + /// Interface specification for more information on protocol chains. + /// + /// + public WSAPROTOCOLCHAIN ProtocolChain; + + /// + /// Type: int + /// The protocol version identifier. + /// + public int iVersion; + + /// + /// Type: int + /// + /// A value to pass as the address family parameter to the socket or WSASocket function in order to open a socket for this + /// protocol. This value also uniquely defines the structure of a protocol address for a sockaddr used by the protocol. + /// + /// + /// On the Windows SDK released for Windows Vista and later, the possible values for the address family are defined in the + /// Ws2def.h header file. Note that the Ws2def.h header file is automatically included in Winsock2.h, and should never be used directly. + /// + /// + /// On versions of the Platform SDK for Windows Server 2003 and older, the possible values for the address family are defined in + /// the Winsock2.h header file. + /// + /// + /// The values currently supported are AF_INET or AF_INET6, which are the Internet address family formats for IPv4 and IPv6. + /// Other options for address family (AF_NETBIOS for use with NetBIOS, for example) are supported if a Windows Sockets service + /// provider for the address family is installed. Note that the values for the AF_ address family and PF_ protocol family + /// constants are identical (for example, AF_INET and PF_INET), so either constant can be used. + /// + /// The table below lists common values for address family although many other values are possible. + /// + /// + /// iAddressFamily + /// Meaning + /// + /// + /// AF_INET 2 + /// The Internet Protocol version 4 (IPv4) address family. + /// + /// + /// AF_IPX 6 + /// + /// The IPX/SPX address family. This address family is only supported if the NWLink IPX/SPX NetBIOS Compatible Transport + /// protocol is installed. This address family is not supported on Windows Vista and later. + /// + /// + /// + /// AF_APPLETALK 16 + /// + /// The AppleTalk address family. This address family is only supported if the AppleTalk protocol is installed. This address + /// family is not supported on Windows Vista and later. + /// + /// + /// + /// AF_NETBIOS 17 + /// + /// The NetBIOS address family. This address family is only supported if the Windows Sockets provider for NetBIOS is installed. + /// The Windows Sockets provider for NetBIOS is supported on 32-bit versions of Windows. This provider is installed by default + /// on 32-bit versions of Windows. The Windows Sockets provider for NetBIOS is not supported on 64-bit versions of windows + /// including Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003, or Windows XP. The Windows Sockets provider + /// for NetBIOS only supports sockets where the type parameter is set to SOCK_DGRAM. The Windows Sockets provider for NetBIOS is + /// not directly related to the NetBIOS programming interface. The NetBIOS programming interface is not supported on Windows + /// Vista, Windows Server 2008, and later. + /// + /// + /// + /// AF_INET6 23 + /// The Internet Protocol version 6 (IPv6) address family. + /// + /// + /// AF_IRDA 26 + /// + /// The Infrared Data Association (IrDA) address family. This address family is only supported if the computer has an infrared + /// port and driver installed. + /// + /// + /// + /// AF_BTH 32 + /// + /// The Bluetooth address family. This address family is supported on Windows XP with SP2 or later if the computer has a + /// Bluetooth adapter and driver installed. + /// + /// + /// + /// + public int iAddressFamily; + + /// + /// Type: int + /// The maximum address length, in bytes. + /// + public int iMaxSockAddr; + + /// + /// Type: int + /// The minimum address length, in bytes. + /// + public int iMinSockAddr; + + /// + /// Type: int + /// + /// A value to pass as the socket type parameter to the socket or WSASocket function in order to open a socket for this + /// protocol. Possible values for the socket type are defined in the Winsock2.h header file. + /// + /// The following table lists the possible values for the iSocketType member supported for Windows Sockets 2: + /// + /// + /// iSocketType + /// Meaning + /// + /// + /// SOCK_STREAM 1 + /// + /// A socket type that provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission + /// mechanism. This socket type uses the Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6). + /// + /// + /// + /// SOCK_DGRAM 2 + /// + /// A socket type that supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum + /// length. This socket type uses the User Datagram Protocol (UDP) for the Internet address family (AF_INET or AF_INET6). + /// + /// + /// + /// SOCK_RAW 3 + /// + /// A socket type that provides a raw socket that allows an application to manipulate the next upper-layer protocol header. To + /// manipulate the IPv4 header, the IP_HDRINCL socket option must be set on the socket. To manipulate the IPv6 header, the + /// IPV6_HDRINCL socket option must be set on the socket. + /// + /// + /// + /// SOCK_RDM 4 + /// + /// A socket type that provides a reliable message datagram. An example of this type is the Pragmatic General Multicast (PGM) + /// multicast protocol implementation in Windows, often referred to as reliable multicast programming. This value is only + /// supported if the Reliable Multicast Protocol is installed. + /// + /// + /// + /// SOCK_SEQPACKET 5 + /// A socket type that provides a pseudo-stream packet based on datagrams. + /// + /// + /// + public SOCK iSocketType; + + /// + /// Type: int + /// + /// A value to pass as the protocol parameter to the socket or WSASocket function in order to open a socket for this protocol. + /// The possible options for the iProtocol member are specific to the address family and socket type specified. + /// + /// + /// On the Windows SDK released for Windows Vista and later, this member can be one of the values from the IPPROTO + /// enumeration type defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically included in + /// Winsock2.h, and should never be used directly. + /// + /// + /// On versions of the Platform SDK for Windows Server 2003 and earlier, the possible values for the iProtocol member are + /// defined in the Winsock2.h and Wsrm.h header files. + /// + /// The table below lists common values for the iProtocol although many other values are possible. + /// + /// + /// iProtocol + /// Meaning + /// + /// + /// IPPROTO_ICMP 1 + /// The Internet Control Message Protocol (ICMP). This value is supported on Windows XP and later. + /// + /// + /// IPPROTO_IGMP 2 + /// The Internet Group Management Protocol (IGMP). This value is supported on Windows XP and later. + /// + /// + /// BTHPROTO_RFCOMM 3 + /// + /// The Bluetooth Radio Frequency Communications (Bluetooth RFCOMM) protocol. This value is supported on Windows XP with SP2 or later. + /// + /// + /// + /// IPPROTO_TCP 6 + /// The Transmission Control Protocol (TCP). + /// + /// + /// IPPROTO_UDP 17 + /// The User Datagram Protocol (UDP). + /// + /// + /// IPPROTO_ICMPV6 58 + /// The Internet Control Message Protocol Version 6 (ICMPv6). This value is supported on Windows XP and later. + /// + /// + /// IPPROTO_RM 113 + /// + /// The PGM protocol for reliable multicast. On the Windows SDK released for Windows Vista and later, this protocol is also + /// called IPPROTO_PGM. This value is only supported if the Reliable Multicast Protocol is installed. + /// + /// + /// + /// + public IPPROTO iProtocol; + + /// + /// Type: int + /// + /// The maximum value that may be added to iProtocol when supplying a value for the protocol parameter to socket or + /// WSASocket function. Not all protocols allow a range of values. When this is the case iProtocolMaxOffset is zero. + /// + /// + public int iProtocolMaxOffset; + + /// + /// Type: int + /// + /// Currently these values are manifest constants (BIGENDIAN and LITTLEENDIAN) that indicate either big-endian or little-endian + /// with the values 0 and 1 respectively. + /// + /// + public int iNetworkByteOrder; + + /// + /// Type: int + /// + /// The type of security scheme employed (if any). A value of SECURITY_PROTOCOL_NONE (0) is used for protocols that do not + /// incorporate security provisions. + /// + /// + public int iSecurityScheme; + + /// + /// Type: DWORD + /// + /// The maximum message size, in bytes, supported by the protocol. This is the maximum size that can be sent from any of the + /// host's local interfaces. For protocols that do not support message framing, the actual maximum that can be sent to a given + /// address may be less. There is no standard provision to determine the maximum inbound message size. The following special + /// values are defined. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// 0 + /// The protocol is stream-oriented and hence the concept of message size is not relevant. + /// + /// + /// 0x1 + /// + /// The maximum outbound (send) message size is dependent on the underlying network MTU (maximum sized transmission unit) and + /// hence cannot be known until after a socket is bound. Applications should use getsockopt to retrieve the value of + /// SO_MAX_MSG_SIZE after the socket has been bound to a local address. + /// + /// + /// + /// 0xFFFFFFFF + /// The protocol is message-oriented, but there is no maximum limit to the size of messages that may be transmitted. + /// + /// + /// + public uint dwMessageSize; + + /// + /// Type: DWORD + /// Reserved for use by service providers. + /// + public uint dwProviderReserved; + + /// + /// Type: TCHAR[WSAPROTOCOL_LEN+1] + /// + /// An array of characters that contains a human-readable name identifying the protocol, for example "MSAFD Tcpip [UDP/IP]". The + /// maximum number of characters allowed is WSAPROTOCOL_LEN, which is defined to be 255. + /// + /// + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = WSAPROTOCOL_LEN + 1)] + public string szProtocol; + } + + /// + /// The WSAPROTOCOLCHAIN structure contains a counted list of Catalog Entry identifiers that comprise a protocol chain. + /// + /// + /// + /// If the length of the chain is larger than 1, this structure represents a protocol chain which consists of one or more layered + /// protocols on top of a base protocol. The corresponding Catalog Entry IDs are in the ProtocolChain.ChainEntries array starting + /// with the layered protocol at the top (the zeroth element in the ProtocolChain.ChainEntries array) and ending with the base + /// protocol. Refer to Windows Sockets 2 Service Provider Interface for more information on protocol chains. + /// + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/winsock2/ns-winsock2-wsaprotocolchain typedef struct _WSAPROTOCOLCHAIN { int + // ChainLen; DWORD ChainEntries[MAX_PROTOCOL_CHAIN]; } WSAPROTOCOLCHAIN, *LPWSAPROTOCOLCHAIN; + [PInvokeData("winsock2.h", MSDNShortId = "c0676f45-e3e3-45f2-9b34-d7318fddc282")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct WSAPROTOCOLCHAIN + { + private const int MAX_PROTOCOL_CHAIN = 7; + + /// + /// Length of the chain, in bytes. The following settings apply: + /// Setting ChainLen to zero indicates a layered protocol + /// Setting ChainLen to one indicates a base protocol + /// Setting ChainLen to greater than one indicates a protocol chain + /// + public int ChainLen; + + /// + /// Array of protocol chain entries. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_PROTOCOL_CHAIN)] + public uint[] ChainEntries; + } + + /// Provides a for that is disposed using . + public class SafeSOCKET : 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 SafeSOCKET(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } + + /// Initializes a new instance of the class. + private SafeSOCKET() : base() { } + + /// Represents an invalid socket which is different than a null socket. + /// The invalid socket. + public static SafeSOCKET INVALID_SOCKET => new(new IntPtr(-1), false); + + /// Returns an invalid handle by instantiating a object with . + /// Returns a value. + public static SafeSOCKET NULL => new(IntPtr.Zero, false); + + /// Performs an implicit conversion from to . + /// The safe handle instance. + /// The result of the conversion. + public static implicit operator SOCKET(SafeSOCKET h) => h.handle; + + /// + protected override bool InternalReleaseHandle() => closesocket(this) == 0; + } + + /// + /// + /// The sockaddr structure varies depending on the protocol selected. Except for the sin*_family parameter, sockaddr contents are + /// expressed in network byte order. + /// + /// + /// Winsock functions using sockaddr are not strictly interpreted to be pointers to a sockaddr structure. The structure is + /// interpreted differently in the context of different address families. The only requirements are that the first u_short is + /// the address family and the total size of the memory buffer in bytes is namelen. + /// + /// + /// The structure also stores socket address information and the structure is sufficiently large to store + /// IPv4 or IPv6 address information. The use of the SOCKADDR_STORAGE structure promotes protocol-family and protocol-version + /// independence, and simplifies development. It is recommended that the SOCKADDR_STORAGE structure be used in place of the + /// sockaddr structure. The SOCKADDR_STORAGE structure is supported on Windows Server 2003 and later. + /// + /// The sockaddr structure and sockaddr_in structures below are used with IPv4. Other protocols use similar structures. + /// The sockaddr_in6 and sockaddr_in6_old structures below are used with IPv6. + /// + /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, SOCKADDR and + /// SOCKADDR_IN typedef tags are defined for sockaddr and sockaddr_in structures as follows: + /// + /// + /// On the Windows SDK released for Windows Vista and later, the organization of header files has changed and the sockaddr and + /// sockaddr_in structures are defined in the Ws2def.h header file, not the Winsock2.h header file. The Ws2def.h header file is + /// automatically included by the Winsock2.h header file. The sockaddr_in6 structure is defined in the Ws2ipdef.h header file, not + /// the Ws2tcpip.h header file. The Ws2ipdef.h header file is automatically included by the Ws2tcpip.h header file. The Ws2def.h and + /// Ws2ipdef.h header files should never be used directly. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/winsock/sockaddr-2 + [PInvokeData("winsock2.h", MSDNShortId = "d1392e1c-2b20-425a-8adf-38e665fb6275")] + public class SOCKADDR : SafeMemoryHandle + { + /// Initializes a new instance of the class. + /// The handle to the memory with the address. + /// if set to this class with dispose the memory. + /// The size of the memory pointed to by . + public SOCKADDR(IntPtr handle, bool ownsHandle = false, int size = 0) : base(handle, size, ownsHandle) { } + + /// Initializes a new instance of the class. + /// The IPv4 address value. + /// The port. + public SOCKADDR(uint addr, ushort port = 0) : this(BitConverter.GetBytes(addr), port) + { + } + + /// Initializes a new instance of the class. + /// The IPv4 or IPv6 address as a byte array. + /// The port. + /// The scope identifier for IPv6 addresses. + /// addr + public SOCKADDR(byte[] addr, ushort port = 0, uint scopeId = 0) : + base(addr.Length == 4 ? Marshal.SizeOf(typeof(SOCKADDR_IN)) : Marshal.SizeOf(typeof(SOCKADDR_IN6))) + { + if (addr.Length == 4) + { + var in4 = new SOCKADDR_IN(new IN_ADDR(addr), port); + Marshal.StructureToPtr(in4, handle, false); + } + else if (addr.Length == 16) + { + var in6 = new SOCKADDR_IN6(addr, scopeId, port); + Marshal.StructureToPtr(in6, handle, false); + } + else + throw new ArgumentOutOfRangeException(nameof(addr)); + } + + /// Initializes a new instance of the class. + /// The value to assign. + public SOCKADDR(SOCKADDR_IN addr) : base(Marshal.SizeOf(typeof(SOCKADDR_IN))) => Marshal.StructureToPtr(addr, handle, false); + + /// Initializes a new instance of the class. + /// The value to assign. + public SOCKADDR(SOCKADDR_IN6 addr) : base(Marshal.SizeOf(typeof(SOCKADDR_IN6))) => Marshal.StructureToPtr(addr, handle, false); + + /// Initializes a new instance of the class. + /// The ip address. + public SOCKADDR(IPAddress ipAddress) : this(ipAddress.GetAddressBytes()) { } + + /// Initializes a new instance of the class. + /// The socket address. + public SOCKADDR(IPEndPoint endPoint) : this(endPoint.Address.GetAddressBytes(), (ushort)endPoint.Port) { } + + internal SOCKADDR(SOCKET_ADDRESS addr) : base(addr.iSockaddrLength) => addr.lpSockaddr.CopyTo(handle, addr.iSockaddrLength); + + /// Gets an instance that represents an empty address. + public static SOCKADDR Empty => new(new byte[Marshal.SizeOf(typeof(IN6_ADDR))]); + + /// Gets the data behind this address as a byte array. + /// The address data. + public byte[] sa_data => GetBytes(2, 14); + + /// Gets the of this address. + /// The address family. + public ADDRESS_FAMILY sa_family => (ADDRESS_FAMILY)handle.ToStructure(); + + /// Allocates from unmanaged memory sufficient memory to hold an object of type T. + /// Native type + /// The value. + /// object to an native (unmanaged) memory block the size of T. + public static SOCKADDR CreateFromStructure(T value = default) => new(InteropExtensions.MarshalToPtr(value, mm.AllocMem, out int s), true, s); + + /// Performs an explicit conversion from to . + /// The address. + /// The resulting instance from the conversion. + /// + public static explicit operator SOCKADDR_IN(SOCKADDR addr) => addr.sa_family is ADDRESS_FAMILY.AF_INET or ADDRESS_FAMILY.AF_UNSPEC ? addr.handle.ToStructure() : throw new InvalidCastException(); + + /// Performs an explicit conversion from to . + /// The address. + /// The resulting instance from the conversion. + /// + public static explicit operator SOCKADDR_IN6(SOCKADDR addr) => addr.sa_family == ADDRESS_FAMILY.AF_INET6 ? addr.handle.ToStructure() : (SOCKADDR_IN6)(SOCKADDR_IN)addr; + + /// Performs an explicit conversion from to . + /// The address. + /// The resulting instance from the conversion. + /// + public static explicit operator SOCKADDR_INET(SOCKADDR addr) => addr.sa_family == ADDRESS_FAMILY.AF_INET6 ? addr.handle.ToStructure() : (SOCKADDR_INET)(SOCKADDR_IN)addr; + + /// Performs an implicit conversion from to . + /// The address. + /// The resulting instance from the conversion. + public static implicit operator IntPtr(SOCKADDR addr) => addr.DangerousGetHandle(); + + /// Performs an implicit conversion from to . + /// The address. + /// The resulting instance from the conversion. + public static implicit operator SOCKADDR(SOCKADDR_IN addr) => new(addr); + + /// Performs an implicit conversion from to . + /// The address. + /// The resulting instance from the conversion. + public static implicit operator SOCKADDR(SOCKADDR_IN6 addr) => new(addr); + + /// Performs an implicit conversion from to . + /// The address. + /// The resulting instance from the conversion. + public static implicit operator SOCKADDR(SOCKADDR_INET addr) => CreateFromStructure(addr); + + /// Provides a copy of as an array of bytes. + /// The array of bytes from this instance. + public byte[] GetAddressBytes() => GetBytes(0, Size); + + /// + public override string ToString() => sa_family == ADDRESS_FAMILY.AF_INET ? ((SOCKADDR_IN)this).ToString() : ((SOCKADDR_IN6)this).ToString(); + } } \ No newline at end of file diff --git a/PInvoke/Ws2_32/mstcpip.cs b/PInvoke/Ws2_32/mstcpip.cs index 79882131..2da1ec19 100644 --- a/PInvoke/Ws2_32/mstcpip.cs +++ b/PInvoke/Ws2_32/mstcpip.cs @@ -3,1129 +3,1169 @@ using System; using System.Runtime.InteropServices; -namespace Vanara.PInvoke +namespace Vanara.PInvoke; + +/// Functions, structures and constants from ws2_32.h. +public static partial class Ws2_32 { - /// Functions, structures and constants from ws2_32.h. - public static partial class Ws2_32 +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + public static readonly uint SIO_ABSORB_RTRALERT = _WSAIOW(IOC_VENDOR, 5); + public static readonly uint SIO_ACQUIRE_PORT_RESERVATION = _WSAIOW(IOC_VENDOR, 100); + public static readonly uint SIO_APPLY_TRANSPORT_SETTING = _WSAIOW(IOC_VENDOR, 19); + public static readonly uint SIO_ASSOCIATE_PORT_RESERVATION = _WSAIOW(IOC_VENDOR, 102); + public static readonly uint SIO_CPU_AFFINITY = _WSAIOW(IOC_VENDOR, 21); + public static readonly uint SIO_DELETE_PEER_TARGET_NAME = _WSAIOW(IOC_VENDOR, 203); + public static readonly uint SIO_GET_TX_TIMESTAMP = _WSAIOW(IOC_VENDOR, 234); + public static readonly uint SIO_INDEX_ADD_MCAST = _WSAIOW(IOC_VENDOR, 10); + public static readonly uint SIO_INDEX_BIND = _WSAIOW(IOC_VENDOR, 8); + public static readonly uint SIO_INDEX_DEL_MCAST = _WSAIOW(IOC_VENDOR, 11); + public static readonly uint SIO_INDEX_MCASTIF = _WSAIOW(IOC_VENDOR, 9); + public static readonly uint SIO_KEEPALIVE_VALS = _WSAIOW(IOC_VENDOR, 4); + public static readonly uint SIO_LIMIT_BROADCASTS = _WSAIOW(IOC_VENDOR, 7); + public static readonly uint SIO_LOOPBACK_FAST_PATH = _WSAIOW(IOC_VENDOR, 16); + public static readonly uint SIO_PRIORITY_HINT = SIO_SET_PRIORITY_HINT; + public static readonly uint SIO_QUERY_RSS_SCALABILITY_INFO = _WSAIOR(IOC_VENDOR, 210); + public static readonly uint SIO_QUERY_SECURITY = _WSAIORW(IOC_VENDOR, 201); + public static readonly uint SIO_QUERY_TRANSPORT_SETTING = _WSAIOW(IOC_VENDOR, 20); + public static readonly uint SIO_QUERY_WFP_ALE_ENDPOINT_HANDLE = _WSAIOR(IOC_VENDOR, 205); + public static readonly uint SIO_QUERY_WFP_CONNECTION_REDIRECT_CONTEXT = _WSAIOW(IOC_VENDOR, 221); + public static readonly uint SIO_QUERY_WFP_CONNECTION_REDIRECT_RECORDS = _WSAIOW(IOC_VENDOR, 220); + public static readonly uint SIO_RCVALL = _WSAIOW(IOC_VENDOR, 1); + public static readonly uint SIO_RCVALL_IF = _WSAIOW(IOC_VENDOR, 14); + public static readonly uint SIO_RCVALL_IGMPMCAST = _WSAIOW(IOC_VENDOR, 3); + public static readonly uint SIO_RCVALL_MCAST = _WSAIOW(IOC_VENDOR, 2); + public static readonly uint SIO_RCVALL_MCAST_IF = _WSAIOW(IOC_VENDOR, 13); + public static readonly uint SIO_RELEASE_PORT_RESERVATION = _WSAIOW(IOC_VENDOR, 101); + public static readonly uint SIO_SET_PEER_TARGET_NAME = _WSAIOW(IOC_VENDOR, 202); + public static readonly uint SIO_SET_PRIORITY_HINT = _WSAIOW(IOC_VENDOR, 24); + public static readonly uint SIO_SET_SECURITY = _WSAIOW(IOC_VENDOR, 200); + public static readonly uint SIO_SET_WFP_CONNECTION_REDIRECT_RECORDS = _WSAIOW(IOC_VENDOR, 222); + public static readonly uint SIO_SOCKET_USAGE_NOTIFICATION = _WSAIOW(IOC_VENDOR, 204); + public static readonly uint SIO_TCP_INFO = _WSAIORW(IOC_VENDOR, 39); + public static readonly uint SIO_TCP_INITIAL_RTO = _WSAIOW(IOC_VENDOR, 17); + public static readonly uint SIO_TCP_SET_ACK_FREQUENCY = _WSAIOW(IOC_VENDOR, 23); + public static readonly uint SIO_TCP_SET_ICW = _WSAIOW(IOC_VENDOR, 22); + public static readonly uint SIO_TIMESTAMPING = _WSAIOW(IOC_VENDOR, 235); + public static readonly uint SIO_UCAST_IF = _WSAIOW(IOC_VENDOR, 6); +#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member + + /// + /// The CONTROL_CHANNEL_TRIGGER_STATUS enumeration specifies the status from a query for the REAL_TIME_NOTIFICATION_CAPABILITY + /// transport setting for a TCP socket that is used with ControlChannelTrigger to receive background network notifications in a + /// Windows Store app. + /// + /// + /// + /// The CONTROL_CHANNEL_TRIGGER_STATUS structure is supported on Windows 8, and Windows Server 2012, and later versions of the + /// operating system. + /// + /// + /// A CONTROL_CHANNEL_TRIGGER_STATUS enumeration value is returned as output from the SIO_QUERY_TRANSPORT_SETTING IOCTL to a query + /// the REAL_TIME_NOTIFICATION_CAPABILITY transport setting for a TCP socket that is used with ControlChannelTrigger to + /// receive background network notifications in a Windows Store app. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ne-mstcpip-control_channel_trigger_status typedef enum { + // CONTROL_CHANNEL_TRIGGER_STATUS_INVALID = 0, CONTROL_CHANNEL_TRIGGER_STATUS_SOFTWARE_SLOT_ALLOCATED = 1, + // CONTROL_CHANNEL_TRIGGER_STATUS_HARDWARE_SLOT_ALLOCATED = 2, CONTROL_CHANNEL_TRIGGER_STATUS_POLICY_ERROR = 3, + // CONTROL_CHANNEL_TRIGGER_STATUS_SYSTEM_ERROR = 4, CONTROL_CHANNEL_TRIGGER_STATUS_TRANSPORT_DISCONNECTED = 5, + // CONTROL_CHANNEL_TRIGGER_STATUS_SERVICE_UNAVAILABLE = 6 } CONTROL_CHANNEL_TRIGGER_STATUS, *PCONTROL_CHANNEL_TRIGGER_STATUS; + [PInvokeData("mstcpip.h", MSDNShortId = "NE:mstcpip.__unnamed_enum_0")] + public enum CONTROL_CHANNEL_TRIGGER_STATUS { /// - /// The CONTROL_CHANNEL_TRIGGER_STATUS enumeration specifies the status from a query for the REAL_TIME_NOTIFICATION_CAPABILITY - /// transport setting for a TCP socket that is used with ControlChannelTrigger to receive background network notifications in a - /// Windows Store app. + /// Value: + /// 0 + /// Status is invalid. /// - /// - /// - /// The CONTROL_CHANNEL_TRIGGER_STATUS structure is supported on Windows 8, and Windows Server 2012, and later versions of the - /// operating system. - /// - /// - /// A CONTROL_CHANNEL_TRIGGER_STATUS enumeration value is returned as output from the SIO_QUERY_TRANSPORT_SETTING IOCTL to a query - /// the REAL_TIME_NOTIFICATION_CAPABILITY transport setting for a TCP socket that is used with ControlChannelTrigger to - /// receive background network notifications in a Windows Store app. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ne-mstcpip-control_channel_trigger_status typedef enum { - // CONTROL_CHANNEL_TRIGGER_STATUS_INVALID = 0, CONTROL_CHANNEL_TRIGGER_STATUS_SOFTWARE_SLOT_ALLOCATED = 1, - // CONTROL_CHANNEL_TRIGGER_STATUS_HARDWARE_SLOT_ALLOCATED = 2, CONTROL_CHANNEL_TRIGGER_STATUS_POLICY_ERROR = 3, - // CONTROL_CHANNEL_TRIGGER_STATUS_SYSTEM_ERROR = 4, CONTROL_CHANNEL_TRIGGER_STATUS_TRANSPORT_DISCONNECTED = 5, - // CONTROL_CHANNEL_TRIGGER_STATUS_SERVICE_UNAVAILABLE = 6 } CONTROL_CHANNEL_TRIGGER_STATUS, *PCONTROL_CHANNEL_TRIGGER_STATUS; - [PInvokeData("mstcpip.h", MSDNShortId = "NE:mstcpip.__unnamed_enum_0")] - public enum CONTROL_CHANNEL_TRIGGER_STATUS - { - /// - /// Value: - /// 0 - /// Status is invalid. - /// - CONTROL_CHANNEL_TRIGGER_STATUS_INVALID, - - /// - /// Value: - /// 1 - /// A software slot was allocated for the - /// ControlChannelTrigger - /// . - /// - CONTROL_CHANNEL_TRIGGER_STATUS_SOFTWARE_SLOT_ALLOCATED, - - /// - /// Value: - /// 2 - /// A hardware slot was allocated for the - /// ControlChannelTrigger - /// . - /// - CONTROL_CHANNEL_TRIGGER_STATUS_HARDWARE_SLOT_ALLOCATED, - - /// - /// Value: - /// 3 - /// A status policy error. - /// - CONTROL_CHANNEL_TRIGGER_STATUS_POLICY_ERROR, - - /// - /// Value: - /// 4 - /// A status system error. - /// - CONTROL_CHANNEL_TRIGGER_STATUS_SYSTEM_ERROR, - - /// - /// Value: - /// 5 - /// The TCP transport is disconnected. - /// - CONTROL_CHANNEL_TRIGGER_STATUS_TRANSPORT_DISCONNECTED, - - /// - /// Value: - /// 6 - /// Service is unavailable. - /// - CONTROL_CHANNEL_TRIGGER_STATUS_SERVICE_UNAVAILABLE, - } - - /// The set of possible security flags for the connection defined in the Mstcpip.h header file. - [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._SOCKET_SECURITY_QUERY_INFO")] - [Flags] - public enum SOCKET_INFO_CONNECTION : uint - { - /// If present, traffic is being secured by a security protocol. If absent, the traffic is flowing in the clear. - SOCKET_INFO_CONNECTION_SECURED = 0x1, - - /// - /// If present, the connection traffic is being encrypted. The SOCKET_INFO_CONNECTION_SECURED flag is always set when this - /// flag is present. - /// - SOCKET_INFO_CONNECTION_ENCRYPTED = 0x2, - - /// - SOCKET_INFO_CONNECTION_IMPERSONATED = 0x4, - } + CONTROL_CHANNEL_TRIGGER_STATUS_INVALID, /// - /// The SOCKET_SECURITY_PROTOCOL enumeration indicates the type of security protocol to be used on a socket to secure network traffic. + /// Value: + /// 1 + /// A software slot was allocated for the + /// ControlChannelTrigger + /// . /// - /// - /// This enumeration is supported on Windows Vista and later. - /// - /// Currently, the only type of security protocol that is supported is IPsec. So specifying an enumeration value of - /// SOCKET_SECURITY_PROTOCOL_DEFAULT has the same effect as specifying SOCKET_SECURITY_PROTOCOL_IPSEC. - /// - /// - /// The SOCKET_SECURITY_PROTOCOL enumeration is used in the SOCKET_PEER_TARGET_NAME, SOCKET_SECURITY_QUERY_INFO, - /// SOCKET_SECURITY_QUERY_TEMPLATE, SOCKET_SECURITY_SETTINGS, and SOCKET_SECURITY_SETTINGS_IPSEC structures to indicate the type of - /// security protocol to be used on a socket in the SecurityProtocol member. These structures are used by the - /// WSAQuerySocketSecurity, WSASetSocketPeerTargetName, and WSASetSocketSecurity functions. - /// - /// - /// In addition to identifying the security protocol, this type is also used to decide how to interpret a pointer passed to some of - /// the secure socket functions. This is analogous to how the sa_family member of the sockaddr type is used to interpret a - /// pointer as either sockaddr_in or sockaddr_in6. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ne-mstcpip-socket_security_protocol typedef enum - // _SOCKET_SECURITY_PROTOCOL { SOCKET_SECURITY_PROTOCOL_DEFAULT, SOCKET_SECURITY_PROTOCOL_IPSEC, SOCKET_SECURITY_PROTOCOL_IPSEC2, - // SOCKET_SECURITY_PROTOCOL_INVALID } SOCKET_SECURITY_PROTOCOL; - [PInvokeData("mstcpip.h", MSDNShortId = "NE:mstcpip._SOCKET_SECURITY_PROTOCOL")] - public enum SOCKET_SECURITY_PROTOCOL - { - /// The default system security will be used. - SOCKET_SECURITY_PROTOCOL_DEFAULT, - - /// IPsec will be used. - SOCKET_SECURITY_PROTOCOL_IPSEC, - - /// - SOCKET_SECURITY_PROTOCOL_IPSEC2, - - /// - /// The maximum possible value for the - /// SOCKET_SECURITY_PROTOCOL - /// enumeration type. This is not a legal value. - /// - SOCKET_SECURITY_PROTOCOL_INVALID, - } - - /// A set of flags that allow applications to set specific security requirements on a socket. - [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._SOCKET_SECURITY_SETTINGS")] - [Flags] - public enum SOCKET_SETTINGS : uint - { - /// - /// Indicates that guaranteed encryption of traffic is required. This flag should be set if the default policy prefers methods of - /// protection that do not use encryption. If this flag is set and encryption is not possible for any reason, no packets will be - /// sent and a connection will not be established. - /// - SOCKET_SETTINGS_GUARANTEE_ENCRYPTION = 0x1, - - /// - /// Indicates that clear text connections are allowed. If this flag is set, some or all of the sent packets will be sent in clear - /// text, especially if security with the peer could not be negotiated. - /// - SOCKET_SETTINGS_ALLOW_INSECURE = 0x2, - } - - /// Flags for IPsec security settings. - [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._SOCKET_SECURITY_SETTINGS_IPSEC")] - [Flags] - public enum SOCKET_SETTINGS_IPSEC : uint - { - /// - /// When this flag is set, IPsec filter instantiation is omitted for the socket. This flag should be set when an application - /// knows that IPsec filters and policy already exist for its traffic. Applications running on a domain with IPsec policy in - /// place can also set this flag. - /// - SOCKET_SETTINGS_IPSEC_SKIP_FILTER_INSTANTIATION = 0x1, - - /// - SOCKET_SETTINGS_IPSEC_OPTIONAL_PEER_NAME_VERIFICATION = 0x2, - - /// - SOCKET_SETTINGS_IPSEC_ALLOW_FIRST_INBOUND_PKT_UNENCRYPTED = 0x4, - - /// - SOCKET_SETTINGS_IPSEC_PEER_NAME_IS_RAW_FORMAT = 0x8, - } - - /// The Windows Sockets SOCKET_USAGE_TYPE enumeration is used to specified the usage type for the socket. - // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ne-mstcpip-socket_usage_type typedef enum _SOCKET_USAGE_TYPE { - // SYSTEM_CRITICAL_SOCKET = 1 } SOCKET_USAGE_TYPE; - [PInvokeData("mstcpip.h", MSDNShortId = "NE:mstcpip._SOCKET_USAGE_TYPE")] - public enum SOCKET_USAGE_TYPE - { - /// - /// Value: - /// 1 - /// The usage type is critical to the system. - /// - SYSTEM_CRITICAL_SOCKET = 1, - } + CONTROL_CHANNEL_TRIGGER_STATUS_SOFTWARE_SLOT_ALLOCATED, /// - /// The Windows Sockets TCPSTATE enumeration indicates the possible states of a Transmission Control Protocol (TCP) connection. + /// Value: + /// 2 + /// A hardware slot was allocated for the + /// ControlChannelTrigger + /// . /// - /// - /// - /// A TCP connection progresses from one state to another in response to events. The events are the user calls OPEN, SEND, RECEIVE, - /// CLOSE, ABORT, and STATUS; the incoming segments, particularly those containing the SYN, ACK, RST and FIN flags; and timeouts. - /// - /// For more information about TCP connection states, see RFC 793. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ne-mstcpip-tcpstate typedef enum _TCPSTATE { TCPSTATE_CLOSED, - // TCPSTATE_LISTEN, TCPSTATE_SYN_SENT, TCPSTATE_SYN_RCVD, TCPSTATE_ESTABLISHED, TCPSTATE_FIN_WAIT_1, TCPSTATE_FIN_WAIT_2, - // TCPSTATE_CLOSE_WAIT, TCPSTATE_CLOSING, TCPSTATE_LAST_ACK, TCPSTATE_TIME_WAIT, TCPSTATE_MAX } TCPSTATE; - [PInvokeData("mstcpip.h", MSDNShortId = "NE:mstcpip._TCPSTATE")] - public enum TCPSTATE - { - /// - /// - /// The TCP connection has no connection state at all. This state represents the state when there is no Transmission Control - /// Block (TCB), and therefore, - /// - /// no connection. - /// - TCPSTATE_CLOSED, - - /// - /// The TCP connection is waiting for a connection request from any remote - /// TCP and port. - /// - TCPSTATE_LISTEN, - - /// - /// -The TCP connection is waiting for a matching connection request - /// after sending a connection request. - /// - TCPSTATE_SYN_SENT, - - /// - /// The TCP connection is waiting for an acknowledgment that confirms the connection - /// request after both receiving and sending a - /// connection request. - /// - TCPSTATE_SYN_RCVD, - - /// - /// The TCP connection is an open connection, so the data received can be - /// delivered to the user. This state is normal state for the data transfer phase - /// of the connection. - /// - TCPSTATE_ESTABLISHED, - - /// - /// The TCP connection is waiting for a request to end the connection - /// from the remote TCP, or an acknowledgment of the previously sent request to end the connection. - /// - TCPSTATE_FIN_WAIT_1, - - /// - /// The TCP connection is waiting for a request to end the connection - /// from the remote TCP. - /// - TCPSTATE_FIN_WAIT_2, - - /// - /// The TCP connection is waiting for a request to end the connection - /// from the local user. - /// - TCPSTATE_CLOSE_WAIT, - - /// The TCP connection is waiting for an acknowledgment of the request to end the connection from the remote TCP. - TCPSTATE_CLOSING, - - /// - /// The TCP connection is waiting for an acknowledgment of the request to end the connection that was previously sent to the - /// remote TCP, which includes an acknowledgment of its request to end the connection. - /// - TCPSTATE_LAST_ACK, - - /// - /// The TCP connection is waiting for enough time to pass to be sure - /// the remote TCP received the acknowledgment of its request to end the connection. - /// - TCPSTATE_TIME_WAIT, - - /// - /// The maximum value of the - /// TCPSTATE - /// enumeration. - /// - TCPSTATE_MAX, - } - - /// Enable/disable timestamp reception for rx/tx direction. - [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._TIMESTAMPING_CONFIG")] - [Flags] - public enum TIMESTAMPING_FLAG : uint - { - /// - TIMESTAMPING_FLAG_RX = 0x1, - - /// - TIMESTAMPING_FLAG_TX = 0x2, - } + CONTROL_CHANNEL_TRIGGER_STATUS_HARDWARE_SLOT_ALLOCATED, /// - /// The ASSOCIATE_NAMERES_CONTEXT_INPUT structure contains the transport setting ID and handle to a fully qualified domain name. + /// Value: + /// 3 + /// A status policy error. /// - /// - /// - /// Generally speaking, you can use ASSOCIATE_NAMERES_CONTEXT_INPUT to enforce policy based on Fully Qualified Domain Name - /// (FQDN), rather than just IP address. you can do so by retrieving a handle to a FQDN with a call to GetAddrInfoEx, using the - /// addinfoex4 structure. From there, you can use the handle in ASSOCIATE_NAMERES_CONTEXT_INPUT in a call to WSAIoctl, using - /// the SIO_APPLY_TRANSPORT_SETTING ioctl. - /// - /// Examples - /// - /// The following code describes making a call to GetAddrInfoEx with a addinfoex4 structure to retrieve the handle to a FQDN. the - /// sample then call WSAIoctl with the ASSOCIATE_NAMERES_CONTEXT_INPUT structure. - /// - /// - /// // // Connect to a server using its IPv4 addresses // VOID ConnectServer( PCWSTR server) { int iResult; PADDRINFOEX4 pResult = NULL; ADDRINFOEX3 hints = { 0 }; PADDRINFOEX4 pCur = NULL; WSADATA wsaData; SOCKET connectSocket = INVALID_SOCKET; ULONG bytesReturned = 0; ASSOCIATE_NAMERES_CONTEXT_INPUT input = { 0 }; SOCKADDR_IN clientService; wchar_t ipstringbuffer[46]; String string; DWORD dwRetval; // // Initialize Winsock // iResult = WSAStartup( MAKEWORD(2, 2), &wsaData); if (iResult != 0) { printf("WSAStartup failed: %d\n", iResult); goto Exit; } // // Create a SOCKET for connection // connectSocket = socket( AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP); if (connectSocket == INVALID_SOCKET) { printf("socket failed: %d\n", WSAGetLastError()); goto Exit; } // // Do name resolution // hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_EXTENDED | AI_FQDN | AI_CANONNAME | AI_RESOLUTION_HANDLE; hints.ai_version = ADDRINFOEX_VERSION_4; dwRetval = GetAddrInfoExW( server, NULL, NS_DNS, NULL, (const ADDRINFOEXW*)&hints, (PADDRINFOEXW*)&pResult, NULL, NULL, NULL, NULL); if (dwRetval != 0) { printf("GetAddrInfoEx failed with error: %d\n", dwRetval); goto Exit; } input.TransportSettingId.Guid = ASSOCIATE_NAMERES_CONTEXT; input.Handle = pResult->ai_resolutionhandle; // // Associate socket with the handle // if (WSAIoctl( connectSocket, SIO_APPLY_TRANSPORT_SETTING, (VOID *)&input, sizeof(input), NULL, 0, &bytesReturned, NULL, NULL) == SOCKET_ERROR) if (iResult != 0){ printf("WSAIoctl failed: %d\n", WSAGetLastError()); goto Exit; } // // Connect to server // pCur = pResult; while (pCur != NULL) { if (pCur->ai_addr->sa_family == AF_INET) { clientService = *(const sockaddr_in*)pCur->ai_addr; clientService.sin_port = htons(80); if (connect( connectSocket, (const SOCKADDR *)&clientService, sizeof(clientService)) == SOCKET_ERROR) { printf("connect failed: %d\n", WSAGetLastError()); goto Exit; } } pCur = pCur->ai_next; } Exit: if (connectSocket != INVALID_SOCKET) { closesocket(connectSocket); } if (pResult) { FreeAddrInfoExW((ADDRINFOEXW*)pResult); } WSACleanup(); return; } - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-associate_nameres_context_input typedef struct - // _ASSOCIATE_NAMERES_CONTEXT_INPUT { TRANSPORT_SETTING_ID TransportSettingId; UINT64 Handle; } ASSOCIATE_NAMERES_CONTEXT_INPUT, *PASSOCIATE_NAMERES_CONTEXT_INPUT; - [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._ASSOCIATE_NAMERES_CONTEXT_INPUT")] - [StructLayout(LayoutKind.Sequential)] - public struct ASSOCIATE_NAMERES_CONTEXT_INPUT - { - /// The transport setting ID. - public TRANSPORT_SETTING_ID TransportSettingId; - - /// Handle to a fully qualified domain name. - public ulong Handle; - } + CONTROL_CHANNEL_TRIGGER_STATUS_POLICY_ERROR, /// - /// The INET_PORT_RANGE structure provides input data used by the SIO_ACQUIRE_PORT_RESERVATION IOCTL to acquire a runtime - /// reservation for a block of TCP or UDP ports. + /// Value: + /// 4 + /// A status system error. /// - /// - /// The INET_PORT_RANGE structure is supported on Windows Vista and later. - /// - /// The INET_PORT_RANGE structure is the datatype passed in the input buffer to the SIO_ACQUIRE_PORT_RESERVATION IOCTL. This - /// IOCTL is used to acquire a runtime reservation for a block of TCP or UDP ports. - /// - /// The INET_PORT_RANGE structure is typedefed to the INET_PORT_RESERVATION structure. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-inet_port_range typedef struct _INET_PORT_RANGE { USHORT - // StartPort; USHORT NumberOfPorts; } INET_PORT_RANGE, *PINET_PORT_RANGE, INET_PORT_RESERVATION, *PINET_PORT_RESERVATION; - [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._INET_PORT_RANGE")] - [StructLayout(LayoutKind.Sequential)] - public struct INET_PORT_RANGE - { - /// - /// The starting TCP or UDP port number. If this parameter is set to zero, the system will choose a starting TCP or UDP port number. - /// - public ushort StartPort; - - /// The number of TCP or UDP port numbers to reserve. - public ushort NumberOfPorts; - } + CONTROL_CHANNEL_TRIGGER_STATUS_SYSTEM_ERROR, /// - /// The INET_PORT_RESERVATION_INSTANCE structure contains a port reservation and a token for a block of TCP or UDP ports. + /// Value: + /// 5 + /// The TCP transport is disconnected. /// - /// - /// The INET_PORT_RESERVATION_INSTANCE structure is supported on Windows Vista and later. - /// - /// The INET_PORT_RESERVATION_INSTANCE structure is returned by the SIO_ACQUIRE_PORT_RESERVATION IOCTL when acquiring a - /// runtime reservation for a block of TCP or UDP ports. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-inet_port_reservation_instance typedef struct { - // INET_PORT_RESERVATION Reservation; INET_PORT_RESERVATION_TOKEN Token; } INET_PORT_RESERVATION_INSTANCE, *PINET_PORT_RESERVATION_INSTANCE; - [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip.__unnamed_struct_2")] - [StructLayout(LayoutKind.Sequential)] - public struct INET_PORT_RESERVATION_INSTANCE - { - /// - /// A runtime port reservation for a block of TCP or UDP ports. - /// The INET_PORT_RESERVATION structure is typedefed to the INET_PORT_RANGE structure. - /// - public INET_PORT_RANGE Reservation; - - /// A port reservation token for a block of TCP or UDP ports. - public INET_PORT_RESERVATION_TOKEN Token; - } - - /// The INET_PORT_RESERVATION_TOKEN structure contains a port reservation token for a block of TCP or UDP ports. - /// - /// The INET_PORT_RESERVATION_TOKEN structure is supported on Windows Vista and later. - /// - /// The INET_PORT_RESERVATION_TOKEN structure is used by the SIO_ACQUIRE_PORT_RESERVATION , SIO_ASSOCIATE_PORT_RESERVATION, - /// and SIO_RELEASE_PORT_RESERVATION Ioctl for TCP or UDP port reservations. The INET_PORT_RESERVATION_TOKEN structure is also - /// equivalent to the ULONG64 Token parameter used by the CreatePersistentTcpPortReservation, CreatePersistentUdpPortReservation, - /// DeletePersistentTcpPortReservation, DeletePersistentUdpPortReservation, LookupPersistentTcpPortReservation, and - /// LookupPersistentUdpPortReservation functions in IP Helper. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-inet_port_reservation_token typedef struct { ULONG64 Token; - // } INET_PORT_RESERVATION_TOKEN, *PINET_PORT_RESERVATION_TOKEN; - [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip.__unnamed_struct_1")] - [StructLayout(LayoutKind.Sequential)] - public struct INET_PORT_RESERVATION_TOKEN - { - /// A port reservation token for a block of TCP or UDP ports. - public ulong Token; - } + CONTROL_CHANNEL_TRIGGER_STATUS_TRANSPORT_DISCONNECTED, /// - /// The REAL_TIME_NOTIFICATION_SETTING_INPUT structure provides input settings to apply for the - /// REAL_TIME_NOTIFICATION_CAPABILITY transport setting for a TCP socket that is used with ControlChannelTrigger to receive - /// background network notifications in a Windows Store app. + /// Value: + /// 6 + /// Service is unavailable. /// - /// - /// - /// The REAL_TIME_NOTIFICATION_SETTING_INPUT structure is supported on Windows 8, and Windows Server 2012, and later versions - /// of the operating system. - /// - /// - /// If the TRANSPORT_SETTING_ID in the lpvInBuffer parameter passed to the SIO_APPLY_TRANSPORT_SETTING IOCTL has the - /// Guid member set to REAL_TIME_NOTIFICATION_CAPABILITY, then this is a request to query the real time notification - /// settings for the TCP socket used with ControlChannelTrigger to receive background network notifications in a Windows Store app. - /// The lpvInBuffer parameter should point to a REAL_TIME_NOTIFICATION_SETTING_INPUT structure used as input to the - /// SIO_APPLY_TRANSPORT_SETTING IOCTL to apply the transport setting. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-real_time_notification_setting_input typedef struct - // _REAL_TIME_NOTIFICATION_SETTING_INPUT { TRANSPORT_SETTING_ID TransportSettingId; GUID BrokerEventGuid; } - // REAL_TIME_NOTIFICATION_SETTING_INPUT, *PREAL_TIME_NOTIFICATION_SETTING_INPUT; - [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._REAL_TIME_NOTIFICATION_SETTING_INPUT")] - [StructLayout(LayoutKind.Sequential)] - public struct REAL_TIME_NOTIFICATION_SETTING_INPUT - { - /// The transport setting ID. - public TRANSPORT_SETTING_ID TransportSettingId; + CONTROL_CHANNEL_TRIGGER_STATUS_SERVICE_UNAVAILABLE, + } - /// The realtime notification broker event GUID for this transport ID. - public Guid BrokerEventGuid; - } + /// The set of possible security flags for the connection defined in the Mstcpip.h header file. + [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._SOCKET_SECURITY_QUERY_INFO")] + [Flags] + public enum SOCKET_INFO_CONNECTION : uint + { + /// If present, traffic is being secured by a security protocol. If absent, the traffic is flowing in the clear. + SOCKET_INFO_CONNECTION_SECURED = 0x1, /// - /// The REAL_TIME_NOTIFICATION_SETTING_OUTPUT structure provides the output settings from a query for the - /// REAL_TIME_NOTIFICATION_CAPABILITY transport setting for a TCP socket that is used with ControlChannelTrigger to receive - /// background network notifications in a Windows Store app. + /// If present, the connection traffic is being encrypted. The SOCKET_INFO_CONNECTION_SECURED flag is always set when this + /// flag is present. /// - /// - /// - /// The REAL_TIME_NOTIFICATION_SETTING_OUTPUT structure is supported on Windows 8, and Windows Server 2012, and later versions of the - /// operating system. - /// - /// - /// If the TRANSPORT_SETTING_ID in the lpvInBuffer parameter passed to the SIO_QUERY_TRANSPORT_SETTING IOCTL has the - /// Guid member set to REAL_TIME_NOTIFICATION_CAPABILITY, then this is a request to query the real time notification - /// settings for the TCP socket used with ControlChannelTrigger to receive background network notifications in a Windows Store app. - /// If the WSAIoctl or LPWSPIoctl call is successful, this IOCTL returns a REAL_TIME_NOTIFICATION_SETTING_OUTPUT structure with the - /// current status. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-real_time_notification_setting_output typedef struct - // _REAL_TIME_NOTIFICATION_SETTING_OUTPUT { CONTROL_CHANNEL_TRIGGER_STATUS ChannelStatus; } REAL_TIME_NOTIFICATION_SETTING_OUTPUT, *PREAL_TIME_NOTIFICATION_SETTING_OUTPUT; - [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._REAL_TIME_NOTIFICATION_SETTING_OUTPUT")] - [StructLayout(LayoutKind.Sequential)] - public struct REAL_TIME_NOTIFICATION_SETTING_OUTPUT - { - /// The channel status for a socket that is used with the ControlChannelTrigger. - public CONTROL_CHANNEL_TRIGGER_STATUS ChannelStatus; - } + SOCKET_INFO_CONNECTION_ENCRYPTED = 0x2, + + /// + SOCKET_INFO_CONNECTION_IMPERSONATED = 0x4, + } + + /// + /// The SOCKET_SECURITY_PROTOCOL enumeration indicates the type of security protocol to be used on a socket to secure network traffic. + /// + /// + /// This enumeration is supported on Windows Vista and later. + /// + /// Currently, the only type of security protocol that is supported is IPsec. So specifying an enumeration value of + /// SOCKET_SECURITY_PROTOCOL_DEFAULT has the same effect as specifying SOCKET_SECURITY_PROTOCOL_IPSEC. + /// + /// + /// The SOCKET_SECURITY_PROTOCOL enumeration is used in the SOCKET_PEER_TARGET_NAME, SOCKET_SECURITY_QUERY_INFO, + /// SOCKET_SECURITY_QUERY_TEMPLATE, SOCKET_SECURITY_SETTINGS, and SOCKET_SECURITY_SETTINGS_IPSEC structures to indicate the type of + /// security protocol to be used on a socket in the SecurityProtocol member. These structures are used by the + /// WSAQuerySocketSecurity, WSASetSocketPeerTargetName, and WSASetSocketSecurity functions. + /// + /// + /// In addition to identifying the security protocol, this type is also used to decide how to interpret a pointer passed to some of + /// the secure socket functions. This is analogous to how the sa_family member of the sockaddr type is used to interpret a + /// pointer as either sockaddr_in or sockaddr_in6. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ne-mstcpip-socket_security_protocol typedef enum + // _SOCKET_SECURITY_PROTOCOL { SOCKET_SECURITY_PROTOCOL_DEFAULT, SOCKET_SECURITY_PROTOCOL_IPSEC, SOCKET_SECURITY_PROTOCOL_IPSEC2, + // SOCKET_SECURITY_PROTOCOL_INVALID } SOCKET_SECURITY_PROTOCOL; + [PInvokeData("mstcpip.h", MSDNShortId = "NE:mstcpip._SOCKET_SECURITY_PROTOCOL")] + public enum SOCKET_SECURITY_PROTOCOL + { + /// The default system security will be used. + SOCKET_SECURITY_PROTOCOL_DEFAULT, + + /// IPsec will be used. + SOCKET_SECURITY_PROTOCOL_IPSEC, + + /// + SOCKET_SECURITY_PROTOCOL_IPSEC2, /// - /// The SOCKET_PEER_TARGET_NAME structure contains the IP address and name for a peer target and the type of security protocol - /// to be used on a socket. + /// The maximum possible value for the + /// SOCKET_SECURITY_PROTOCOL + /// enumeration type. This is not a legal value. /// - /// - /// The SOCKET_PEER_TARGET_NAME structure is supported on Windows Vista and later. - /// - /// The SOCKET_PEER_TARGET_NAME structure is used by the WSASetSocketPeerTargetName function to specify the peer target name - /// that corresponds to a peer IP address. This target name is meant to be specified by client applications to securely identify the - /// peer that should be authenticated. - /// - /// - /// Currently, the only type of security protocol that is supported is IPsec. So specifying an enumeration value of - /// SOCKET_SECURITY_PROTOCOL_DEFAULT has the same effect as specifying SOCKET_SECURITY_PROTOCOL_IPSEC in the - /// SecurityProtocol member. - /// - /// - /// The implementation of IPsec on Windows Vista and Windows Server 2008 only supports computer-to-computer and user-to-computer - /// authentication. As a result, the peer target name specified in the AllStrings member of the SOCKET_PEER_TARGET_NAME - /// structure should refer to the peer computer principal. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-socket_peer_target_name typedef struct - // _SOCKET_PEER_TARGET_NAME { SOCKET_SECURITY_PROTOCOL SecurityProtocol; SOCKADDR_STORAGE PeerAddress; ULONG PeerTargetNameStringLen; - // wchar_t AllStrings[0]; } SOCKET_PEER_TARGET_NAME; - [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._SOCKET_PEER_TARGET_NAME")] - [StructLayout(LayoutKind.Sequential)] - public struct SOCKET_PEER_TARGET_NAME - { - /// A SOCKET_SECURITY_PROTOCOL value that identifies the type of protocol used to secure the traffic on the socket. - public SOCKET_SECURITY_PROTOCOL SecurityProtocol; + SOCKET_SECURITY_PROTOCOL_INVALID, + } - /// The IP address of the peer for the socket. - public SOCKADDR_STORAGE PeerAddress; - - /// The length, in bytes, of the peer target name in the AllStrings member. - public uint PeerTargetNameStringLen; - - /// The peer target name for the socket. - [MarshalAs(UnmanagedType.LPWStr, SizeConst = 0)] - public string AllStrings; - } + /// A set of flags that allow applications to set specific security requirements on a socket. + [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._SOCKET_SECURITY_SETTINGS")] + [Flags] + public enum SOCKET_SETTINGS : uint + { + /// + /// Indicates that guaranteed encryption of traffic is required. This flag should be set if the default policy prefers methods of + /// protection that do not use encryption. If this flag is set and encryption is not possible for any reason, no packets will be + /// sent and a connection will not be established. + /// + SOCKET_SETTINGS_GUARANTEE_ENCRYPTION = 0x1, /// - /// The SOCKET_SECURITY_QUERY_INFO structure contains security information returned by the WSAQuerySocketSecurity function. + /// Indicates that clear text connections are allowed. If this flag is set, some or all of the sent packets will be sent in clear + /// text, especially if security with the peer could not be negotiated. /// - /// - /// The SOCKET_SECURITY_QUERY_INFO structure is supported on Windows Vista and later. + SOCKET_SETTINGS_ALLOW_INSECURE = 0x2, + } + + /// Flags for IPsec security settings. + [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._SOCKET_SECURITY_SETTINGS_IPSEC")] + [Flags] + public enum SOCKET_SETTINGS_IPSEC : uint + { + /// + /// When this flag is set, IPsec filter instantiation is omitted for the socket. This flag should be set when an application + /// knows that IPsec filters and policy already exist for its traffic. Applications running on a domain with IPsec policy in + /// place can also set this flag. + /// + SOCKET_SETTINGS_IPSEC_SKIP_FILTER_INSTANTIATION = 0x1, + + /// + SOCKET_SETTINGS_IPSEC_OPTIONAL_PEER_NAME_VERIFICATION = 0x2, + + /// + SOCKET_SETTINGS_IPSEC_ALLOW_FIRST_INBOUND_PKT_UNENCRYPTED = 0x4, + + /// + SOCKET_SETTINGS_IPSEC_PEER_NAME_IS_RAW_FORMAT = 0x8, + } + + /// The Windows Sockets SOCKET_USAGE_TYPE enumeration is used to specified the usage type for the socket. + // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ne-mstcpip-socket_usage_type typedef enum _SOCKET_USAGE_TYPE { + // SYSTEM_CRITICAL_SOCKET = 1 } SOCKET_USAGE_TYPE; + [PInvokeData("mstcpip.h", MSDNShortId = "NE:mstcpip._SOCKET_USAGE_TYPE")] + public enum SOCKET_USAGE_TYPE + { + /// + /// Value: + /// 1 + /// The usage type is critical to the system. + /// + SYSTEM_CRITICAL_SOCKET = 1, + } + + /// + /// The Windows Sockets TCPSTATE enumeration indicates the possible states of a Transmission Control Protocol (TCP) connection. + /// + /// + /// + /// A TCP connection progresses from one state to another in response to events. The events are the user calls OPEN, SEND, RECEIVE, + /// CLOSE, ABORT, and STATUS; the incoming segments, particularly those containing the SYN, ACK, RST and FIN flags; and timeouts. + /// + /// For more information about TCP connection states, see RFC 793. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ne-mstcpip-tcpstate typedef enum _TCPSTATE { TCPSTATE_CLOSED, + // TCPSTATE_LISTEN, TCPSTATE_SYN_SENT, TCPSTATE_SYN_RCVD, TCPSTATE_ESTABLISHED, TCPSTATE_FIN_WAIT_1, TCPSTATE_FIN_WAIT_2, + // TCPSTATE_CLOSE_WAIT, TCPSTATE_CLOSING, TCPSTATE_LAST_ACK, TCPSTATE_TIME_WAIT, TCPSTATE_MAX } TCPSTATE; + [PInvokeData("mstcpip.h", MSDNShortId = "NE:mstcpip._TCPSTATE")] + public enum TCPSTATE + { + /// /// - /// The SOCKET_SECURITY_QUERY_INFO structure is used by the WSAQuerySocketSecurity function to return information about the - /// security applied to a connection on a socket. + /// The TCP connection has no connection state at all. This state represents the state when there is no Transmission Control + /// Block (TCB), and therefore, /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-socket_security_query_info typedef struct - // _SOCKET_SECURITY_QUERY_INFO { SOCKET_SECURITY_PROTOCOL SecurityProtocol; ULONG Flags; UINT64 PeerApplicationAccessTokenHandle; - // UINT64 PeerMachineAccessTokenHandle; } SOCKET_SECURITY_QUERY_INFO; - [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._SOCKET_SECURITY_QUERY_INFO")] - [StructLayout(LayoutKind.Sequential)] - public struct SOCKET_SECURITY_QUERY_INFO - { - /// A SOCKET_SECURITY_PROTOCOL value that identifies the protocol used to secure the traffic. - public SOCKET_SECURITY_PROTOCOL SecurityProtocol; - - /// - /// The set of possible security flags for the connection defined in the Mstcpip.h header file. - /// - /// - /// Value - /// Meaning - /// - /// - /// SOCKET_INFO_CONNECTION_SECURED 0x00000001 - /// If present, traffic is being secured by a security protocol. If absent, the traffic is flowing in the clear. - /// - /// - /// SOCKET_INFO_CONNECTION_ENCRYPTED 0x00000002 - /// - /// If present, the connection traffic is being encrypted. The SOCKET_INFO_CONNECTION_SECURED flag is always set when this - /// flag is present. - /// - /// - /// - /// - public SOCKET_INFO_CONNECTION Flags; - - /// - /// A handle to the access token that represents the account under which the peer application is running. After using the token - /// for access checks, the application should close the handle using the CloseHandle function. - /// - public ulong PeerApplicationAccessTokenHandle; - - /// - /// A handle to the access token for the peer computer's account during the course of the application. After using the token for - /// access checks, the application should close the handle using the CloseHandle function. - /// - public ulong PeerMachineAccessTokenHandle; - } + /// no connection. + /// + TCPSTATE_CLOSED, /// - /// The SOCKET_SECURITY_QUERY_TEMPLATE structure contains the security template used by the WSAQuerySocketSecurity function. + /// The TCP connection is waiting for a connection request from any remote + /// TCP and port. /// - /// - /// The SOCKET_SECURITY_QUERY_TEMPLATE structure is supported on Windows Vista and later. - /// - /// The SOCKET_SECURITY_QUERY_TEMPLATE structure is used by the WSAQuerySocketSecurity function to specify the type of query - /// information to return for a socket. The SOCKET_SECURITY_QUERY_TEMPLATE structure passed to the - /// WSAQuerySocketSecurity function may contain zeros for all members to request default security information. - /// - /// - /// If the SOCKET_SECURITY_QUERY_TEMPLATE structure is specified with the PeerTokenAccessMask member not specified (set - /// to zero), then the WSAQuerySocketSecurity function will not return the PeerApplicationAccessTokenHandle and - /// PeerMachineAccessTokenHandle members in the SOCKET_SECURITY_QUERY_INFO structure. - /// - /// - /// Currently, the only type of security protocol that is supported is IPsec. So specifying an enumeration value of - /// SOCKET_SECURITY_PROTOCOL_DEFAULT for the SecurityProtocol member has the same effect as specifying SOCKET_SECURITY_PROTOCOL_IPSEC. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-socket_security_query_template typedef struct - // _SOCKET_SECURITY_QUERY_TEMPLATE { SOCKET_SECURITY_PROTOCOL SecurityProtocol; SOCKADDR_STORAGE PeerAddress; ULONG - // PeerTokenAccessMask; } SOCKET_SECURITY_QUERY_TEMPLATE; - [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._SOCKET_SECURITY_QUERY_TEMPLATE")] - [StructLayout(LayoutKind.Sequential)] - public struct SOCKET_SECURITY_QUERY_TEMPLATE - { - /// A SOCKET_SECURITY_PROTOCOL value that identifies the protocol used to secure the traffic. - public SOCKET_SECURITY_PROTOCOL SecurityProtocol; - - /// - /// The IP address of the peer for which security information is being queried. For connection-oriented sockets (protocol of - /// IPPROTO_TCP), the connected socket uniquely identifies a peer. In this case, this parameter is ignored. - /// - public SOCKADDR_STORAGE PeerAddress; - - /// - /// The access mask used for opening the peer user application and computer token handles that are returned as part of the query information. - /// - public uint PeerTokenAccessMask; - } - - /// The SOCKET_SECURITY_SETTINGS structure specifies generic security requirements for a socket. - /// - /// The SOCKET_SECURITY_SETTINGS structure is supported on Windows Vista and later. - /// - /// The SOCKET_SECURITY_SETTINGS structure is used by the WSASetSocketSecurity function to enable and apply security on a socket. - /// - /// - /// Security settings not addressed in this structure are derived from the system default policy or the administratively configured - /// policy. It is recommended that most applications specify a value of SOCKET_SECURITY_PROTOCOL_DEFAULT for the - /// SOCKET_SECURITY_PROTOCOL enumeration in the SecurityProtocol member. This makes the application neutral to security - /// protocols and allows easier deployments among different systems. - /// - /// - /// Advanced applications can specify a security protocol and associated settings by casting them to the - /// SOCKET_SECURITY_SETTINGS type. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-socket_security_settings typedef struct - // _SOCKET_SECURITY_SETTINGS { SOCKET_SECURITY_PROTOCOL SecurityProtocol; ULONG SecurityFlags; } SOCKET_SECURITY_SETTINGS; - [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._SOCKET_SECURITY_SETTINGS")] - [StructLayout(LayoutKind.Sequential)] - public struct SOCKET_SECURITY_SETTINGS - { - /// A SOCKET_SECURITY_PROTOCOL value that identifies the type of security protocol to be used on the socket. - public SOCKET_SECURITY_PROTOCOL SecurityProtocol; - - /// - /// - /// A set of flags that allow applications to set specific security requirements on a socket. The possible values are defined in - /// the Mstcpip.h header file. - /// - /// - /// - /// Value - /// Meaning - /// - /// - /// SOCKET_SETTINGS_GUARANTEE_ENCRYPTION 0x00000001 - /// - /// Indicates that guaranteed encryption of traffic is required. This flag should be set if the default policy prefers methods of - /// protection that do not use encryption. If this flag is set and encryption is not possible for any reason, no packets will be - /// sent and a connection will not be established. - /// - /// - /// - /// SOCKET_SETTINGS_ALLOW_INSECURE 0x00000002 - /// - /// Indicates that clear text connections are allowed. If this flag is set, some or all of the sent packets will be sent in clear - /// text, especially if security with the peer could not be negotiated. - /// - /// - /// - /// - public SOCKET_SETTINGS SecurityFlags; - } + TCPSTATE_LISTEN, /// - /// The SOCKET_SECURITY_SETTINGS_IPSEC structure specifies various security requirements and settings that are specific to IPsec. + /// -The TCP connection is waiting for a matching connection request + /// after sending a connection request. /// - /// - /// The SOCKET_SECURITY_SETTINGS_IPSEC structure is supported on Windows Vista and later. + TCPSTATE_SYN_SENT, + + /// + /// The TCP connection is waiting for an acknowledgment that confirms the connection + /// request after both receiving and sending a + /// connection request. + /// + TCPSTATE_SYN_RCVD, + + /// + /// The TCP connection is an open connection, so the data received can be + /// delivered to the user. This state is normal state for the data transfer phase + /// of the connection. + /// + TCPSTATE_ESTABLISHED, + + /// + /// The TCP connection is waiting for a request to end the connection + /// from the remote TCP, or an acknowledgment of the previously sent request to end the connection. + /// + TCPSTATE_FIN_WAIT_1, + + /// + /// The TCP connection is waiting for a request to end the connection + /// from the remote TCP. + /// + TCPSTATE_FIN_WAIT_2, + + /// + /// The TCP connection is waiting for a request to end the connection + /// from the local user. + /// + TCPSTATE_CLOSE_WAIT, + + /// The TCP connection is waiting for an acknowledgment of the request to end the connection from the remote TCP. + TCPSTATE_CLOSING, + + /// + /// The TCP connection is waiting for an acknowledgment of the request to end the connection that was previously sent to the + /// remote TCP, which includes an acknowledgment of its request to end the connection. + /// + TCPSTATE_LAST_ACK, + + /// + /// The TCP connection is waiting for enough time to pass to be sure + /// the remote TCP received the acknowledgment of its request to end the connection. + /// + TCPSTATE_TIME_WAIT, + + /// + /// The maximum value of the + /// TCPSTATE + /// enumeration. + /// + TCPSTATE_MAX, + } + + /// Enable/disable timestamp reception for rx/tx direction. + [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._TIMESTAMPING_CONFIG")] + [Flags] + public enum TIMESTAMPING_FLAG : uint + { + /// + TIMESTAMPING_FLAG_RX = 0x1, + + /// + TIMESTAMPING_FLAG_TX = 0x2, + } + + /// + /// The ASSOCIATE_NAMERES_CONTEXT_INPUT structure contains the transport setting ID and handle to a fully qualified domain name. + /// + /// + /// + /// Generally speaking, you can use ASSOCIATE_NAMERES_CONTEXT_INPUT to enforce policy based on Fully Qualified Domain Name + /// (FQDN), rather than just IP address. you can do so by retrieving a handle to a FQDN with a call to GetAddrInfoEx, using the + /// addinfoex4 structure. From there, you can use the handle in ASSOCIATE_NAMERES_CONTEXT_INPUT in a call to WSAIoctl, using + /// the SIO_APPLY_TRANSPORT_SETTING ioctl. + /// + /// Examples + /// + /// The following code describes making a call to GetAddrInfoEx with a addinfoex4 structure to retrieve the handle to a FQDN. the + /// sample then call WSAIoctl with the ASSOCIATE_NAMERES_CONTEXT_INPUT structure. + /// + /// + /// // // Connect to a server using its IPv4 addresses // VOID ConnectServer( PCWSTR server) { int iResult; PADDRINFOEX4 pResult = NULL; ADDRINFOEX3 hints = { 0 }; PADDRINFOEX4 pCur = NULL; WSADATA wsaData; SOCKET connectSocket = INVALID_SOCKET; ULONG bytesReturned = 0; ASSOCIATE_NAMERES_CONTEXT_INPUT input = { 0 }; SOCKADDR_IN clientService; wchar_t ipstringbuffer[46]; String string; DWORD dwRetval; // // Initialize Winsock // iResult = WSAStartup( MAKEWORD(2, 2), &wsaData); if (iResult != 0) { printf("WSAStartup failed: %d\n", iResult); goto Exit; } // // Create a SOCKET for connection // connectSocket = socket( AF_UNSPEC, SOCK_STREAM, IPPROTO_TCP); if (connectSocket == INVALID_SOCKET) { printf("socket failed: %d\n", WSAGetLastError()); goto Exit; } // // Do name resolution // hints.ai_family = AF_INET; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_EXTENDED | AI_FQDN | AI_CANONNAME | AI_RESOLUTION_HANDLE; hints.ai_version = ADDRINFOEX_VERSION_4; dwRetval = GetAddrInfoExW( server, NULL, NS_DNS, NULL, (const ADDRINFOEXW*)&hints, (PADDRINFOEXW*)&pResult, NULL, NULL, NULL, NULL); if (dwRetval != 0) { printf("GetAddrInfoEx failed with error: %d\n", dwRetval); goto Exit; } input.TransportSettingId.Guid = ASSOCIATE_NAMERES_CONTEXT; input.Handle = pResult->ai_resolutionhandle; // // Associate socket with the handle // if (WSAIoctl( connectSocket, SIO_APPLY_TRANSPORT_SETTING, (VOID *)&input, sizeof(input), NULL, 0, &bytesReturned, NULL, NULL) == SOCKET_ERROR) if (iResult != 0){ printf("WSAIoctl failed: %d\n", WSAGetLastError()); goto Exit; } // // Connect to server // pCur = pResult; while (pCur != NULL) { if (pCur->ai_addr->sa_family == AF_INET) { clientService = *(const sockaddr_in*)pCur->ai_addr; clientService.sin_port = htons(80); if (connect( connectSocket, (const SOCKADDR *)&clientService, sizeof(clientService)) == SOCKET_ERROR) { printf("connect failed: %d\n", WSAGetLastError()); goto Exit; } } pCur = pCur->ai_next; } Exit: if (connectSocket != INVALID_SOCKET) { closesocket(connectSocket); } if (pResult) { FreeAddrInfoExW((ADDRINFOEXW*)pResult); } WSACleanup(); return; } + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-associate_nameres_context_input typedef struct + // _ASSOCIATE_NAMERES_CONTEXT_INPUT { TRANSPORT_SETTING_ID TransportSettingId; UINT64 Handle; } ASSOCIATE_NAMERES_CONTEXT_INPUT, *PASSOCIATE_NAMERES_CONTEXT_INPUT; + [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._ASSOCIATE_NAMERES_CONTEXT_INPUT")] + [StructLayout(LayoutKind.Sequential)] + public struct ASSOCIATE_NAMERES_CONTEXT_INPUT + { + /// The transport setting ID. + public TRANSPORT_SETTING_ID TransportSettingId; + + /// Handle to a fully qualified domain name. + public ulong Handle; + } + + /// + /// The INET_PORT_RANGE structure provides input data used by the SIO_ACQUIRE_PORT_RESERVATION IOCTL to acquire a runtime + /// reservation for a block of TCP or UDP ports. + /// + /// + /// The INET_PORT_RANGE structure is supported on Windows Vista and later. + /// + /// The INET_PORT_RANGE structure is the datatype passed in the input buffer to the SIO_ACQUIRE_PORT_RESERVATION IOCTL. This + /// IOCTL is used to acquire a runtime reservation for a block of TCP or UDP ports. + /// + /// The INET_PORT_RANGE structure is typedefed to the INET_PORT_RESERVATION structure. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-inet_port_range typedef struct _INET_PORT_RANGE { USHORT + // StartPort; USHORT NumberOfPorts; } INET_PORT_RANGE, *PINET_PORT_RANGE, INET_PORT_RESERVATION, *PINET_PORT_RESERVATION; + [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._INET_PORT_RANGE")] + [StructLayout(LayoutKind.Sequential)] + public struct INET_PORT_RANGE + { + /// + /// The starting TCP or UDP port number. If this parameter is set to zero, the system will choose a starting TCP or UDP port number. + /// + public ushort StartPort; + + /// The number of TCP or UDP port numbers to reserve. + public ushort NumberOfPorts; + } + + /// + /// The INET_PORT_RESERVATION_INSTANCE structure contains a port reservation and a token for a block of TCP or UDP ports. + /// + /// + /// The INET_PORT_RESERVATION_INSTANCE structure is supported on Windows Vista and later. + /// + /// The INET_PORT_RESERVATION_INSTANCE structure is returned by the SIO_ACQUIRE_PORT_RESERVATION IOCTL when acquiring a + /// runtime reservation for a block of TCP or UDP ports. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-inet_port_reservation_instance typedef struct { + // INET_PORT_RESERVATION Reservation; INET_PORT_RESERVATION_TOKEN Token; } INET_PORT_RESERVATION_INSTANCE, *PINET_PORT_RESERVATION_INSTANCE; + [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip.__unnamed_struct_2")] + [StructLayout(LayoutKind.Sequential)] + public struct INET_PORT_RESERVATION_INSTANCE + { + /// + /// A runtime port reservation for a block of TCP or UDP ports. + /// The INET_PORT_RESERVATION structure is typedefed to the INET_PORT_RANGE structure. + /// + public INET_PORT_RANGE Reservation; + + /// A port reservation token for a block of TCP or UDP ports. + public INET_PORT_RESERVATION_TOKEN Token; + } + + /// The INET_PORT_RESERVATION_TOKEN structure contains a port reservation token for a block of TCP or UDP ports. + /// + /// The INET_PORT_RESERVATION_TOKEN structure is supported on Windows Vista and later. + /// + /// The INET_PORT_RESERVATION_TOKEN structure is used by the SIO_ACQUIRE_PORT_RESERVATION , SIO_ASSOCIATE_PORT_RESERVATION, + /// and SIO_RELEASE_PORT_RESERVATION Ioctl for TCP or UDP port reservations. The INET_PORT_RESERVATION_TOKEN structure is also + /// equivalent to the ULONG64 Token parameter used by the CreatePersistentTcpPortReservation, CreatePersistentUdpPortReservation, + /// DeletePersistentTcpPortReservation, DeletePersistentUdpPortReservation, LookupPersistentTcpPortReservation, and + /// LookupPersistentUdpPortReservation functions in IP Helper. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-inet_port_reservation_token typedef struct { ULONG64 Token; + // } INET_PORT_RESERVATION_TOKEN, *PINET_PORT_RESERVATION_TOKEN; + [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip.__unnamed_struct_1")] + [StructLayout(LayoutKind.Sequential)] + public struct INET_PORT_RESERVATION_TOKEN + { + /// A port reservation token for a block of TCP or UDP ports. + public ulong Token; + } + + /// + /// The REAL_TIME_NOTIFICATION_SETTING_INPUT structure provides input settings to apply for the + /// REAL_TIME_NOTIFICATION_CAPABILITY transport setting for a TCP socket that is used with ControlChannelTrigger to receive + /// background network notifications in a Windows Store app. + /// + /// + /// + /// The REAL_TIME_NOTIFICATION_SETTING_INPUT structure is supported on Windows 8, and Windows Server 2012, and later versions + /// of the operating system. + /// + /// + /// If the TRANSPORT_SETTING_ID in the lpvInBuffer parameter passed to the SIO_APPLY_TRANSPORT_SETTING IOCTL has the + /// Guid member set to REAL_TIME_NOTIFICATION_CAPABILITY, then this is a request to query the real time notification + /// settings for the TCP socket used with ControlChannelTrigger to receive background network notifications in a Windows Store app. + /// The lpvInBuffer parameter should point to a REAL_TIME_NOTIFICATION_SETTING_INPUT structure used as input to the + /// SIO_APPLY_TRANSPORT_SETTING IOCTL to apply the transport setting. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-real_time_notification_setting_input typedef struct + // _REAL_TIME_NOTIFICATION_SETTING_INPUT { TRANSPORT_SETTING_ID TransportSettingId; GUID BrokerEventGuid; } + // REAL_TIME_NOTIFICATION_SETTING_INPUT, *PREAL_TIME_NOTIFICATION_SETTING_INPUT; + [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._REAL_TIME_NOTIFICATION_SETTING_INPUT")] + [StructLayout(LayoutKind.Sequential)] + public struct REAL_TIME_NOTIFICATION_SETTING_INPUT + { + /// The transport setting ID. + public TRANSPORT_SETTING_ID TransportSettingId; + + /// The realtime notification broker event GUID for this transport ID. + public Guid BrokerEventGuid; + } + + /// + /// The REAL_TIME_NOTIFICATION_SETTING_OUTPUT structure provides the output settings from a query for the + /// REAL_TIME_NOTIFICATION_CAPABILITY transport setting for a TCP socket that is used with ControlChannelTrigger to receive + /// background network notifications in a Windows Store app. + /// + /// + /// + /// The REAL_TIME_NOTIFICATION_SETTING_OUTPUT structure is supported on Windows 8, and Windows Server 2012, and later versions of the + /// operating system. + /// + /// + /// If the TRANSPORT_SETTING_ID in the lpvInBuffer parameter passed to the SIO_QUERY_TRANSPORT_SETTING IOCTL has the + /// Guid member set to REAL_TIME_NOTIFICATION_CAPABILITY, then this is a request to query the real time notification + /// settings for the TCP socket used with ControlChannelTrigger to receive background network notifications in a Windows Store app. + /// If the WSAIoctl or LPWSPIoctl call is successful, this IOCTL returns a REAL_TIME_NOTIFICATION_SETTING_OUTPUT structure with the + /// current status. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-real_time_notification_setting_output typedef struct + // _REAL_TIME_NOTIFICATION_SETTING_OUTPUT { CONTROL_CHANNEL_TRIGGER_STATUS ChannelStatus; } REAL_TIME_NOTIFICATION_SETTING_OUTPUT, *PREAL_TIME_NOTIFICATION_SETTING_OUTPUT; + [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._REAL_TIME_NOTIFICATION_SETTING_OUTPUT")] + [StructLayout(LayoutKind.Sequential)] + public struct REAL_TIME_NOTIFICATION_SETTING_OUTPUT + { + /// The channel status for a socket that is used with the ControlChannelTrigger. + public CONTROL_CHANNEL_TRIGGER_STATUS ChannelStatus; + } + + /// + /// The SOCKET_PEER_TARGET_NAME structure contains the IP address and name for a peer target and the type of security protocol + /// to be used on a socket. + /// + /// + /// The SOCKET_PEER_TARGET_NAME structure is supported on Windows Vista and later. + /// + /// The SOCKET_PEER_TARGET_NAME structure is used by the WSASetSocketPeerTargetName function to specify the peer target name + /// that corresponds to a peer IP address. This target name is meant to be specified by client applications to securely identify the + /// peer that should be authenticated. + /// + /// + /// Currently, the only type of security protocol that is supported is IPsec. So specifying an enumeration value of + /// SOCKET_SECURITY_PROTOCOL_DEFAULT has the same effect as specifying SOCKET_SECURITY_PROTOCOL_IPSEC in the + /// SecurityProtocol member. + /// + /// + /// The implementation of IPsec on Windows Vista and Windows Server 2008 only supports computer-to-computer and user-to-computer + /// authentication. As a result, the peer target name specified in the AllStrings member of the SOCKET_PEER_TARGET_NAME + /// structure should refer to the peer computer principal. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-socket_peer_target_name typedef struct + // _SOCKET_PEER_TARGET_NAME { SOCKET_SECURITY_PROTOCOL SecurityProtocol; SOCKADDR_STORAGE PeerAddress; ULONG PeerTargetNameStringLen; + // wchar_t AllStrings[0]; } SOCKET_PEER_TARGET_NAME; + [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._SOCKET_PEER_TARGET_NAME")] + [StructLayout(LayoutKind.Sequential)] + public struct SOCKET_PEER_TARGET_NAME + { + /// A SOCKET_SECURITY_PROTOCOL value that identifies the type of protocol used to secure the traffic on the socket. + public SOCKET_SECURITY_PROTOCOL SecurityProtocol; + + /// The IP address of the peer for the socket. + public SOCKADDR_STORAGE PeerAddress; + + /// The length, in bytes, of the peer target name in the AllStrings member. + public uint PeerTargetNameStringLen; + + /// The peer target name for the socket. + [MarshalAs(UnmanagedType.LPWStr, SizeConst = 0)] + public string AllStrings; + } + + /// + /// The SOCKET_SECURITY_QUERY_INFO structure contains security information returned by the WSAQuerySocketSecurity function. + /// + /// + /// The SOCKET_SECURITY_QUERY_INFO structure is supported on Windows Vista and later. + /// + /// The SOCKET_SECURITY_QUERY_INFO structure is used by the WSAQuerySocketSecurity function to return information about the + /// security applied to a connection on a socket. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-socket_security_query_info typedef struct + // _SOCKET_SECURITY_QUERY_INFO { SOCKET_SECURITY_PROTOCOL SecurityProtocol; ULONG Flags; UINT64 PeerApplicationAccessTokenHandle; + // UINT64 PeerMachineAccessTokenHandle; } SOCKET_SECURITY_QUERY_INFO; + [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._SOCKET_SECURITY_QUERY_INFO")] + [StructLayout(LayoutKind.Sequential)] + public struct SOCKET_SECURITY_QUERY_INFO + { + /// A SOCKET_SECURITY_PROTOCOL value that identifies the protocol used to secure the traffic. + public SOCKET_SECURITY_PROTOCOL SecurityProtocol; + + /// + /// The set of possible security flags for the connection defined in the Mstcpip.h header file. + /// + /// + /// Value + /// Meaning + /// + /// + /// SOCKET_INFO_CONNECTION_SECURED 0x00000001 + /// If present, traffic is being secured by a security protocol. If absent, the traffic is flowing in the clear. + /// + /// + /// SOCKET_INFO_CONNECTION_ENCRYPTED 0x00000002 + /// + /// If present, the connection traffic is being encrypted. The SOCKET_INFO_CONNECTION_SECURED flag is always set when this + /// flag is present. + /// + /// + /// + /// + public SOCKET_INFO_CONNECTION Flags; + + /// + /// A handle to the access token that represents the account under which the peer application is running. After using the token + /// for access checks, the application should close the handle using the CloseHandle function. + /// + public ulong PeerApplicationAccessTokenHandle; + + /// + /// A handle to the access token for the peer computer's account during the course of the application. After using the token for + /// access checks, the application should close the handle using the CloseHandle function. + /// + public ulong PeerMachineAccessTokenHandle; + } + + /// + /// The SOCKET_SECURITY_QUERY_TEMPLATE structure contains the security template used by the WSAQuerySocketSecurity function. + /// + /// + /// The SOCKET_SECURITY_QUERY_TEMPLATE structure is supported on Windows Vista and later. + /// + /// The SOCKET_SECURITY_QUERY_TEMPLATE structure is used by the WSAQuerySocketSecurity function to specify the type of query + /// information to return for a socket. The SOCKET_SECURITY_QUERY_TEMPLATE structure passed to the + /// WSAQuerySocketSecurity function may contain zeros for all members to request default security information. + /// + /// + /// If the SOCKET_SECURITY_QUERY_TEMPLATE structure is specified with the PeerTokenAccessMask member not specified (set + /// to zero), then the WSAQuerySocketSecurity function will not return the PeerApplicationAccessTokenHandle and + /// PeerMachineAccessTokenHandle members in the SOCKET_SECURITY_QUERY_INFO structure. + /// + /// + /// Currently, the only type of security protocol that is supported is IPsec. So specifying an enumeration value of + /// SOCKET_SECURITY_PROTOCOL_DEFAULT for the SecurityProtocol member has the same effect as specifying SOCKET_SECURITY_PROTOCOL_IPSEC. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-socket_security_query_template typedef struct + // _SOCKET_SECURITY_QUERY_TEMPLATE { SOCKET_SECURITY_PROTOCOL SecurityProtocol; SOCKADDR_STORAGE PeerAddress; ULONG + // PeerTokenAccessMask; } SOCKET_SECURITY_QUERY_TEMPLATE; + [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._SOCKET_SECURITY_QUERY_TEMPLATE")] + [StructLayout(LayoutKind.Sequential)] + public struct SOCKET_SECURITY_QUERY_TEMPLATE + { + /// A SOCKET_SECURITY_PROTOCOL value that identifies the protocol used to secure the traffic. + public SOCKET_SECURITY_PROTOCOL SecurityProtocol; + + /// + /// The IP address of the peer for which security information is being queried. For connection-oriented sockets (protocol of + /// IPPROTO_TCP), the connected socket uniquely identifies a peer. In this case, this parameter is ignored. + /// + public SOCKADDR_STORAGE PeerAddress; + + /// + /// The access mask used for opening the peer user application and computer token handles that are returned as part of the query information. + /// + public uint PeerTokenAccessMask; + } + + /// The SOCKET_SECURITY_SETTINGS structure specifies generic security requirements for a socket. + /// + /// The SOCKET_SECURITY_SETTINGS structure is supported on Windows Vista and later. + /// + /// The SOCKET_SECURITY_SETTINGS structure is used by the WSASetSocketSecurity function to enable and apply security on a socket. + /// + /// + /// Security settings not addressed in this structure are derived from the system default policy or the administratively configured + /// policy. It is recommended that most applications specify a value of SOCKET_SECURITY_PROTOCOL_DEFAULT for the + /// SOCKET_SECURITY_PROTOCOL enumeration in the SecurityProtocol member. This makes the application neutral to security + /// protocols and allows easier deployments among different systems. + /// + /// + /// Advanced applications can specify a security protocol and associated settings by casting them to the + /// SOCKET_SECURITY_SETTINGS type. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-socket_security_settings typedef struct + // _SOCKET_SECURITY_SETTINGS { SOCKET_SECURITY_PROTOCOL SecurityProtocol; ULONG SecurityFlags; } SOCKET_SECURITY_SETTINGS; + [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._SOCKET_SECURITY_SETTINGS")] + [StructLayout(LayoutKind.Sequential)] + public struct SOCKET_SECURITY_SETTINGS + { + /// A SOCKET_SECURITY_PROTOCOL value that identifies the type of security protocol to be used on the socket. + public SOCKET_SECURITY_PROTOCOL SecurityProtocol; + + /// /// - /// The SOCKET_SECURITY_SETTINGS_IPSEC structure is meant to be used by an advanced application that requires more flexibility - /// and wishes to customize IPSec policy for their traffic. The pointer to the SOCKET_SECURITY_SETTINGS_IPSEC structure needs - /// to cast to the SOCKET_SECURITY_SETTINGS structure type when calling the WSASetSocketSecurity function to enable and apply - /// security on a socket. + /// A set of flags that allow applications to set specific security requirements on a socket. The possible values are defined in + /// the Mstcpip.h header file. /// + /// + /// + /// Value + /// Meaning + /// + /// + /// SOCKET_SETTINGS_GUARANTEE_ENCRYPTION 0x00000001 + /// + /// Indicates that guaranteed encryption of traffic is required. This flag should be set if the default policy prefers methods of + /// protection that do not use encryption. If this flag is set and encryption is not possible for any reason, no packets will be + /// sent and a connection will not be established. + /// + /// + /// + /// SOCKET_SETTINGS_ALLOW_INSECURE 0x00000002 + /// + /// Indicates that clear text connections are allowed. If this flag is set, some or all of the sent packets will be sent in clear + /// text, especially if security with the peer could not be negotiated. + /// + /// + /// + /// + public SOCKET_SETTINGS SecurityFlags; + } + + /// + /// The SOCKET_SECURITY_SETTINGS_IPSEC structure specifies various security requirements and settings that are specific to IPsec. + /// + /// + /// The SOCKET_SECURITY_SETTINGS_IPSEC structure is supported on Windows Vista and later. + /// + /// The SOCKET_SECURITY_SETTINGS_IPSEC structure is meant to be used by an advanced application that requires more flexibility + /// and wishes to customize IPSec policy for their traffic. The pointer to the SOCKET_SECURITY_SETTINGS_IPSEC structure needs + /// to cast to the SOCKET_SECURITY_SETTINGS structure type when calling the WSASetSocketSecurity function to enable and apply + /// security on a socket. + /// + /// + /// The SecurityProtocol member of the SOCKET_SECURITY_SETTINGS_IPSEC structure must be set to + /// SOCKET_SECURITY_PROTOCOL_IPSEC, not SOCKET_SECURITY_PROTOCOL_DEFAULT. + /// + /// + /// To simplify Internet Protocol security (IPsec) deployment, Windows Vista and later support an enhanced version of the Internet + /// Key Exchange (IKE) protocol known as Authenticated Internet Protocol (AuthIP). AuthIP provides simplified IPsec policy + /// configuration and maintenance in many configurations and additional flexibility for IPsec peer authentication. + /// + /// + /// There is a possibility that some of the IPsec settings specified in the SOCKET_SECURITY_SETTINGS_IPSEC structure may end + /// up being different from the actual settings applied to the network traffic on a socket. For example, this could happen when an + /// application specifies custom main mode or quick mode policy, but a different policy with a higher priority (a domain policy, for + /// example) specifies conflicting settings for the same traffic. To be aware of such conflicts, an application can use the Windows + /// Filtering Platform API to query the policy being applied and subscribe for notifications. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-socket_security_settings_ipsec typedef struct + // _SOCKET_SECURITY_SETTINGS_IPSEC { SOCKET_SECURITY_PROTOCOL SecurityProtocol; ULONG SecurityFlags; ULONG IpsecFlags; GUID + // AuthipMMPolicyKey; GUID AuthipQMPolicyKey; GUID Reserved; UINT64 Reserved2; ULONG UserNameStringLen; ULONG DomainNameStringLen; + // ULONG PasswordStringLen; wchar_t AllStrings[0]; } SOCKET_SECURITY_SETTINGS_IPSEC; + [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._SOCKET_SECURITY_SETTINGS_IPSEC")] + [StructLayout(LayoutKind.Sequential)] + public struct SOCKET_SECURITY_SETTINGS_IPSEC + { + /// + /// Type: SOCKET_SECURITY_PROTOCOL /// - /// The SecurityProtocol member of the SOCKET_SECURITY_SETTINGS_IPSEC structure must be set to - /// SOCKET_SECURITY_PROTOCOL_IPSEC, not SOCKET_SECURITY_PROTOCOL_DEFAULT. + /// A SOCKET_SECURITY_PROTOCOL value that identifies the type of security protocol to be used on the socket. This member must be + /// set to SOCKET_SECURITY_PROTOCOL_IPSEC. /// + /// + public SOCKET_SECURITY_PROTOCOL SecurityProtocol; + + /// + /// Type: ULONG /// - /// To simplify Internet Protocol security (IPsec) deployment, Windows Vista and later support an enhanced version of the Internet - /// Key Exchange (IKE) protocol known as Authenticated Internet Protocol (AuthIP). AuthIP provides simplified IPsec policy - /// configuration and maintenance in many configurations and additional flexibility for IPsec peer authentication. + /// A set of flags that allow applications to set specific security requirements on a socket. The possible values are defined in + /// the Mstcpip.h header file. /// + /// + /// + /// Value + /// Meaning + /// + /// + /// SOCKET_SETTINGS_GUARANTEE_ENCRYPTION 0x00000001 + /// + /// Indicates that guaranteed encryption of traffic is required. This flag should be set if the default policy prefers methods of + /// protection that do not use encryption. If this flag is set and encryption is not possible for any reason, no packets will be + /// sent and a connection will not be established. + /// + /// + /// + /// SOCKET_SETTINGS_ALLOW_INSECURE 0x00000002 + /// + /// Indicates that clear text connections are allowed. If this flag is set, some or all of the sent packets will be sent in clear + /// text, especially if security with the peer could not be negotiated. + /// + /// + /// + /// + public SOCKET_SETTINGS SecurityFlags; + + /// + /// Type: ULONG + /// Flags for IPsec security settings. The possible values are defined in the Mstcpip.h header file. + /// + /// + /// Value + /// Meaning + /// + /// + /// SOCKET_SETTINGS_IPSEC_SKIP_FILTER_INSTANTIATION 0x00000001 + /// + /// When this flag is set, IPsec filter instantiation is omitted for the socket. This flag should be set when an application + /// knows that IPsec filters and policy already exist for its traffic. Applications running on a domain with IPsec policy in + /// place can also set this flag. + /// + /// + /// + /// + public SOCKET_SETTINGS_IPSEC IpsecFlags; + + /// + /// Type: GUID /// - /// There is a possibility that some of the IPsec settings specified in the SOCKET_SECURITY_SETTINGS_IPSEC structure may end - /// up being different from the actual settings applied to the network traffic on a socket. For example, this could happen when an - /// application specifies custom main mode or quick mode policy, but a different policy with a higher priority (a domain policy, for - /// example) specifies conflicting settings for the same traffic. To be aware of such conflicts, an application can use the Windows - /// Filtering Platform API to query the policy being applied and subscribe for notifications. + /// The GUID for the Windows Filtering Platform key of the AuthIP main mode provider context. If an application wishes to use a + /// custom main mode policy, it should first use the FwpmProviderContextAdd0 function to add the corresponding provider context + /// and specify the returned key in this member. This field is ignored for a GUID of zero. /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-socket_security_settings_ipsec typedef struct - // _SOCKET_SECURITY_SETTINGS_IPSEC { SOCKET_SECURITY_PROTOCOL SecurityProtocol; ULONG SecurityFlags; ULONG IpsecFlags; GUID - // AuthipMMPolicyKey; GUID AuthipQMPolicyKey; GUID Reserved; UINT64 Reserved2; ULONG UserNameStringLen; ULONG DomainNameStringLen; - // ULONG PasswordStringLen; wchar_t AllStrings[0]; } SOCKET_SECURITY_SETTINGS_IPSEC; - [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._SOCKET_SECURITY_SETTINGS_IPSEC")] - [StructLayout(LayoutKind.Sequential)] - public struct SOCKET_SECURITY_SETTINGS_IPSEC - { - /// - /// Type: SOCKET_SECURITY_PROTOCOL - /// - /// A SOCKET_SECURITY_PROTOCOL value that identifies the type of security protocol to be used on the socket. This member must be - /// set to SOCKET_SECURITY_PROTOCOL_IPSEC. - /// - /// - public SOCKET_SECURITY_PROTOCOL SecurityProtocol; + /// + public Guid AuthipMMPolicyKey; - /// - /// Type: ULONG - /// - /// A set of flags that allow applications to set specific security requirements on a socket. The possible values are defined in - /// the Mstcpip.h header file. - /// - /// - /// - /// Value - /// Meaning - /// - /// - /// SOCKET_SETTINGS_GUARANTEE_ENCRYPTION 0x00000001 - /// - /// Indicates that guaranteed encryption of traffic is required. This flag should be set if the default policy prefers methods of - /// protection that do not use encryption. If this flag is set and encryption is not possible for any reason, no packets will be - /// sent and a connection will not be established. - /// - /// - /// - /// SOCKET_SETTINGS_ALLOW_INSECURE 0x00000002 - /// - /// Indicates that clear text connections are allowed. If this flag is set, some or all of the sent packets will be sent in clear - /// text, especially if security with the peer could not be negotiated. - /// - /// - /// - /// - public SOCKET_SETTINGS SecurityFlags; + /// + /// Type: GUID + /// + /// The Windows Filtering Platform key of the AuthIp quick mode provider context. If an application wishes to use a custom quick + /// mode policy, it should first use the FwpmProviderContextAdd0 function to add the corresponding provider context and specify + /// the returned key in this field. This field is ignored for a GUID of zero. + /// + /// + public Guid AuthipQMPolicyKey; - /// - /// Type: ULONG - /// Flags for IPsec security settings. The possible values are defined in the Mstcpip.h header file. - /// - /// - /// Value - /// Meaning - /// - /// - /// SOCKET_SETTINGS_IPSEC_SKIP_FILTER_INSTANTIATION 0x00000001 - /// - /// When this flag is set, IPsec filter instantiation is omitted for the socket. This flag should be set when an application - /// knows that IPsec filters and policy already exist for its traffic. Applications running on a domain with IPsec policy in - /// place can also set this flag. - /// - /// - /// - /// - public SOCKET_SETTINGS_IPSEC IpsecFlags; + /// + /// Type: GUID + /// Reserved for future use. + /// + public Guid Reserved; - /// - /// Type: GUID - /// - /// The GUID for the Windows Filtering Platform key of the AuthIP main mode provider context. If an application wishes to use a - /// custom main mode policy, it should first use the FwpmProviderContextAdd0 function to add the corresponding provider context - /// and specify the returned key in this member. This field is ignored for a GUID of zero. - /// - /// - public Guid AuthipMMPolicyKey; + /// + /// Type: UINT64 + /// Reserved for future use. + /// + public ulong Reserved2; - /// - /// Type: GUID - /// - /// The Windows Filtering Platform key of the AuthIp quick mode provider context. If an application wishes to use a custom quick - /// mode policy, it should first use the FwpmProviderContextAdd0 function to add the corresponding provider context and specify - /// the returned key in this field. This field is ignored for a GUID of zero. - /// - /// - public Guid AuthipQMPolicyKey; + /// + /// Type: ULONG + /// The length, in bytes, of the user name in the AllStrings member. + /// + public uint UserNameStringLen; - /// - /// Type: GUID - /// Reserved for future use. - /// - public Guid Reserved; + /// + /// Type: ULONG + /// The length, in bytes, of the domain name in the AllStrings member. + /// + public uint DomainNameStringLen; - /// - /// Type: UINT64 - /// Reserved for future use. - /// - public ulong Reserved2; + /// + /// Type: ULONG + /// The length, in bytes, of the password in the AllStrings member. + /// + public uint PasswordStringLen; - /// - /// Type: ULONG - /// The length, in bytes, of the user name in the AllStrings member. - /// - public uint UserNameStringLen; + /// + /// Type: wchar_t[] + /// A string that contains the user name, the domain name, and the password concatenated in this order. + /// + [MarshalAs(UnmanagedType.LPWStr, SizeConst = 0)] + public string AllStrings; + } - /// - /// Type: ULONG - /// The length, in bytes, of the domain name in the AllStrings member. - /// - public uint DomainNameStringLen; + /// Contains the Transmission Control Protocol (TCP) statistics that were collected for a socket. + /// + /// To get an instance of this structure, call the WSAIoctl or LPWSPIoctl function with the SIO_TCP_INFO control code. Specify 0 for + /// the lpvInBuffer field to retrieve the v0 version of this structure. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-tcp_info_v0 typedef struct _TCP_INFO_v0 { TCPSTATE State; + // ULONG Mss; ULONG64 ConnectionTimeMs; BOOLEAN TimestampsEnabled; ULONG RttUs; ULONG MinRttUs; ULONG BytesInFlight; ULONG Cwnd; + // ULONG SndWnd; ULONG RcvWnd; ULONG RcvBuf; ULONG64 BytesOut; ULONG64 BytesIn; ULONG BytesReordered; ULONG BytesRetrans; ULONG + // FastRetrans; ULONG DupAcksIn; ULONG TimeoutEpisodes; UCHAR SynRetrans; } TCP_INFO_v0, *PTCP_INFO_v0; + [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._TCP_INFO_v0")] + [StructLayout(LayoutKind.Sequential)] + public struct TCP_INFO_v0 + { + /// A value from the TCPSTATE enumeration that indicates the state of the TCP connection. + public TCPSTATE State; - /// - /// Type: ULONG - /// The length, in bytes, of the password in the AllStrings member. - /// - public uint PasswordStringLen; + /// The current maximum segment size (MSS) for the connection, in bytes. + public uint Mss; - /// - /// Type: wchar_t[] - /// A string that contains the user name, the domain name, and the password concatenated in this order. - /// - [MarshalAs(UnmanagedType.LPWStr, SizeConst = 0)] - public string AllStrings; - } + /// The lifetime of the connection, in milliseconds. + public ulong ConnectionTimeMs; + /// TRUE if TCP time stamps are turned on for the connection; otherwise FALSE. + [MarshalAs(UnmanagedType.U1)] + public bool TimestampsEnabled; + + /// The current estimated round-trip time for the connection, in microseconds. + public uint RttUs; + + /// The minimum sampled round trip time, in microseconds. + public uint MinRttUs; + + /// The current number of sent bytes that are unacknowledged. + public uint BytesInFlight; + + /// The size of the current congestion window, in bytes. + public uint Cwnd; + + /// The size of the send window (SND.WND in RFC 793), in bytes. + public uint SndWnd; + + /// The size of the receive window (RCV.WND in RFC 793), in bytes. + public uint RcvWnd; + + /// + /// The size of the current receive buffer, in bytes. The size of the receive buffer changes dynamically when autotuning is + /// turned on for the receive window. + /// + public uint RcvBuf; + + /// The total number of bytes sent. + public ulong BytesOut; + + /// The total number of bytes received. + public ulong BytesIn; + + /// The total number of bytes reordered. + public uint BytesReordered; + + /// The total number of bytes retransmitted. + public uint BytesRetrans; + + /// The number of calls of the Fast Retransmit algorithm. + public uint FastRetrans; + + /// The total number of duplicate acknowledgments received. + public uint DupAcksIn; + + /// The total number of retransmission timeout episodes. Each episode can consist of multiple timeouts. + public uint TimeoutEpisodes; + + /// The total number of retransmitted synchronize control flags (SYNs). + public byte SynRetrans; + } + + /// + /// Contains the Transmission Control Protocol (TCP) statistics that were collected for a socket. Version 1.0 of this structure + /// provides additional fields. + /// + /// + /// To get an instance of this structure, call the WSAIoctl or LPWSPIoctl function with the SIO_TCP_INFO control code. Specify 1 for + /// the lpvInBuffer field to retrieve the v1 version of this structure. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-tcp_info_v1 typedef struct _TCP_INFO_v1 { TCPSTATE State; + // ULONG Mss; ULONG64 ConnectionTimeMs; BOOLEAN TimestampsEnabled; ULONG RttUs; ULONG MinRttUs; ULONG BytesInFlight; ULONG Cwnd; + // ULONG SndWnd; ULONG RcvWnd; ULONG RcvBuf; ULONG64 BytesOut; ULONG64 BytesIn; ULONG BytesReordered; ULONG BytesRetrans; ULONG + // FastRetrans; ULONG DupAcksIn; ULONG TimeoutEpisodes; UCHAR SynRetrans; ULONG SndLimTransRwin; ULONG SndLimTimeRwin; ULONG64 + // SndLimBytesRwin; ULONG SndLimTransCwnd; ULONG SndLimTimeCwnd; ULONG64 SndLimBytesCwnd; ULONG SndLimTransSnd; ULONG SndLimTimeSnd; + // ULONG64 SndLimBytesSnd; } TCP_INFO_v1, *PTCP_INFO_v1; + [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._TCP_INFO_v1")] + [StructLayout(LayoutKind.Sequential)] + public struct TCP_INFO_v1 + { /// Contains the Transmission Control Protocol (TCP) statistics that were collected for a socket. - /// - /// To get an instance of this structure, call the WSAIoctl or LPWSPIoctl function with the SIO_TCP_INFO control code. Specify 0 for - /// the lpvInBuffer field to retrieve the v0 version of this structure. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-tcp_info_v0 typedef struct _TCP_INFO_v0 { TCPSTATE State; - // ULONG Mss; ULONG64 ConnectionTimeMs; BOOLEAN TimestampsEnabled; ULONG RttUs; ULONG MinRttUs; ULONG BytesInFlight; ULONG Cwnd; - // ULONG SndWnd; ULONG RcvWnd; ULONG RcvBuf; ULONG64 BytesOut; ULONG64 BytesIn; ULONG BytesReordered; ULONG BytesRetrans; ULONG - // FastRetrans; ULONG DupAcksIn; ULONG TimeoutEpisodes; UCHAR SynRetrans; } TCP_INFO_v0, *PTCP_INFO_v0; - [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._TCP_INFO_v0")] - [StructLayout(LayoutKind.Sequential)] - public struct TCP_INFO_v0 - { - /// A value from the TCPSTATE enumeration that indicates the state of the TCP connection. - public TCPSTATE State; + public TCPSTATE State; - /// The current maximum segment size (MSS) for the connection, in bytes. - public uint Mss; + /// The current maximum segment size (MSS) for the connection, in bytes. + public uint Mss; - /// The lifetime of the connection, in milliseconds. - public ulong ConnectionTimeMs; + /// The lifetime of the connection, in milliseconds. + public ulong ConnectionTimeMs; - /// TRUE if TCP time stamps are turned on for the connection; otherwise FALSE. - [MarshalAs(UnmanagedType.U1)] - public bool TimestampsEnabled; + /// TRUE if TCP time stamps are turned on for the connection; otherwise FALSE. + [MarshalAs(UnmanagedType.U1)] + public bool TimestampsEnabled; - /// The current estimated round-trip time for the connection, in microseconds. - public uint RttUs; + /// The current estimated round-trip time for the connection, in microseconds. + public uint RttUs; - /// The minimum sampled round trip time, in microseconds. - public uint MinRttUs; + /// The minimum sampled round trip time, in microseconds. + public uint MinRttUs; - /// The current number of sent bytes that are unacknowledged. - public uint BytesInFlight; + /// The current number of sent bytes that are unacknowledged. + public uint BytesInFlight; - /// The size of the current congestion window, in bytes. - public uint Cwnd; + /// The size of the current congestion window, in bytes. + public uint Cwnd; - /// The size of the send window (SND.WND in RFC 793), in bytes. - public uint SndWnd; + /// The size of the send window (SND.WND in RFC 793), in bytes. + public uint SndWnd; - /// The size of the receive window (RCV.WND in RFC 793), in bytes. - public uint RcvWnd; - - /// - /// The size of the current receive buffer, in bytes. The size of the receive buffer changes dynamically when autotuning is - /// turned on for the receive window. - /// - public uint RcvBuf; - - /// The total number of bytes sent. - public ulong BytesOut; - - /// The total number of bytes received. - public ulong BytesIn; - - /// The total number of bytes reordered. - public uint BytesReordered; - - /// The total number of bytes retransmitted. - public uint BytesRetrans; - - /// The number of calls of the Fast Retransmit algorithm. - public uint FastRetrans; - - /// The total number of duplicate acknowledgments received. - public uint DupAcksIn; - - /// The total number of retransmission timeout episodes. Each episode can consist of multiple timeouts. - public uint TimeoutEpisodes; - - /// The total number of retransmitted synchronize control flags (SYNs). - public byte SynRetrans; - } + /// The size of the receive window (RCV.WND in RFC 793), in bytes. + public uint RcvWnd; /// - /// Contains the Transmission Control Protocol (TCP) statistics that were collected for a socket. Version 1.0 of this structure - /// provides additional fields. + /// The size of the current receive buffer, in bytes. The size of the receive buffer changes dynamically when autotuning is + /// turned on for the receive window. /// - /// - /// To get an instance of this structure, call the WSAIoctl or LPWSPIoctl function with the SIO_TCP_INFO control code. Specify 1 for - /// the lpvInBuffer field to retrieve the v1 version of this structure. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-tcp_info_v1 typedef struct _TCP_INFO_v1 { TCPSTATE State; - // ULONG Mss; ULONG64 ConnectionTimeMs; BOOLEAN TimestampsEnabled; ULONG RttUs; ULONG MinRttUs; ULONG BytesInFlight; ULONG Cwnd; - // ULONG SndWnd; ULONG RcvWnd; ULONG RcvBuf; ULONG64 BytesOut; ULONG64 BytesIn; ULONG BytesReordered; ULONG BytesRetrans; ULONG - // FastRetrans; ULONG DupAcksIn; ULONG TimeoutEpisodes; UCHAR SynRetrans; ULONG SndLimTransRwin; ULONG SndLimTimeRwin; ULONG64 - // SndLimBytesRwin; ULONG SndLimTransCwnd; ULONG SndLimTimeCwnd; ULONG64 SndLimBytesCwnd; ULONG SndLimTransSnd; ULONG SndLimTimeSnd; - // ULONG64 SndLimBytesSnd; } TCP_INFO_v1, *PTCP_INFO_v1; - [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._TCP_INFO_v1")] - [StructLayout(LayoutKind.Sequential)] - public struct TCP_INFO_v1 - { - /// Contains the Transmission Control Protocol (TCP) statistics that were collected for a socket. - public TCPSTATE State; + public uint RcvBuf; - /// The current maximum segment size (MSS) for the connection, in bytes. - public uint Mss; + /// The total number of bytes sent. + public ulong BytesOut; - /// The lifetime of the connection, in milliseconds. - public ulong ConnectionTimeMs; + /// The total number of bytes received. + public ulong BytesIn; - /// TRUE if TCP time stamps are turned on for the connection; otherwise FALSE. - [MarshalAs(UnmanagedType.U1)] - public bool TimestampsEnabled; + /// The total number of bytes reordered. + public uint BytesReordered; - /// The current estimated round-trip time for the connection, in microseconds. - public uint RttUs; + /// The total number of bytes retransmitted. + public uint BytesRetrans; - /// The minimum sampled round trip time, in microseconds. - public uint MinRttUs; + /// The number of calls of the Fast Retransmit algorithm. + public uint FastRetrans; - /// The current number of sent bytes that are unacknowledged. - public uint BytesInFlight; + /// The total number of duplicate acknowledgments received. + public uint DupAcksIn; - /// The size of the current congestion window, in bytes. - public uint Cwnd; + /// The total number of retransmission timeout episodes. Each episode can consist of multiple timeouts. + public uint TimeoutEpisodes; - /// The size of the send window (SND.WND in RFC 793), in bytes. - public uint SndWnd; - - /// The size of the receive window (RCV.WND in RFC 793), in bytes. - public uint RcvWnd; - - /// - /// The size of the current receive buffer, in bytes. The size of the receive buffer changes dynamically when autotuning is - /// turned on for the receive window. - /// - public uint RcvBuf; - - /// The total number of bytes sent. - public ulong BytesOut; - - /// The total number of bytes received. - public ulong BytesIn; - - /// The total number of bytes reordered. - public uint BytesReordered; - - /// The total number of bytes retransmitted. - public uint BytesRetrans; - - /// The number of calls of the Fast Retransmit algorithm. - public uint FastRetrans; - - /// The total number of duplicate acknowledgments received. - public uint DupAcksIn; - - /// The total number of retransmission timeout episodes. Each episode can consist of multiple timeouts. - public uint TimeoutEpisodes; - - /// The total number of retransmitted synchronize control flags (SYNs). - public byte SynRetrans; - - /// - /// The number of transitions into the "Receiver Limited" state from either the "Congestion Limited" or "Sender Limited" states. - /// - public uint SndLimTransRwin; - - /// - /// The cumulative time, in milliseconds, spent in the "Receiver Limited" state where TCP transmission stops because the sender - /// has filled the announced receiver window. - /// - public uint SndLimTimeRwin; - - /// The total number of bytes sent in the "Receiver Limited" state. - public ulong SndLimBytesRwin; - - /// - /// The number of transitions into the "Congestion Limited" state from either the "Receiver Limited" or "Sender Limited" states. - /// - public uint SndLimTransCwnd; - - /// - /// The cumulative time, in milliseconds, spent in the "Congestion Limited" state. When there is a retransmission timeout, it is - /// counted in this member and not the cumulative time for some other state. - /// - public uint SndLimTimeCwnd; - - /// The total number of bytes sent in the "Congestion Limited" state. - public ulong SndLimBytesCwnd; - - /// - /// The number of transitions into the "Sender Limited" state from either the "Receiver Limited" or "Congestion Limited" states. - /// - public uint SndLimTransSnd; - - /// The cumulative time, in milliseconds, spent in the "Sender Limited" state. - public uint SndLimTimeSnd; - - /// The total number of bytes sent in the "Sender Limited" state. - public ulong SndLimBytesSnd; - } + /// The total number of retransmitted synchronize control flags (SYNs). + public byte SynRetrans; /// - /// The TCP_INITIAL_RTO_PARAMETERS structure specifies data used by the SIO_TCP_INITIAL_RTO IOCTL to configure initial - /// re-transmission timeout (RTO) parameters to be used on the socket. + /// The number of transitions into the "Receiver Limited" state from either the "Congestion Limited" or "Sender Limited" states. /// - /// - /// - /// The TCP_INITIAL_RTO_PARAMETERS structure allows an application to configure the initial round trip time (RTT) used to compute the - /// retransmission timeout. The application can also configure the number of re-transmissions that will be attempted before the - /// connection attempt fails. - /// - /// - /// An application should supply the RTT of choice in milliseconds and the maximum number of retransmissions in this structure. The - /// Windows TCP/IP stack will honor these parameters for the subsequent connection attempt. The retransmission behavior for TCP is - /// documented in IETF RFC 793 and 2988. - /// - /// - /// An application may use the unspecified defines, TCP_INITIAL_RTO_UNSPECIFIED_RTT and - /// TCP_INITIAL_RTO_UNSPECIFIED_MAX_SYN_RETRANSMISSIONS when supplying values for one of these fields. This allows the system - /// to pick up administrator configured settings for the parameter left unspecified. - /// - /// - /// An application can choose system defaults for any of these fields and supply those values using the default defines, - /// TCP_INITIAL_RTO_DEFAULT_RTT and TCP_INITIAL_RTO_DEFAULT_MAX_SYN_RETRANSMISSIONS. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-tcp_initial_rto_parameters typedef struct - // _TCP_INITIAL_RTO_PARAMETERS { USHORT Rtt; UCHAR MaxSynRetransmissions; } TCP_INITIAL_RTO_PARAMETERS, *PTCP_INITIAL_RTO_PARAMETERS; - [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._TCP_INITIAL_RTO_PARAMETERS")] - [StructLayout(LayoutKind.Sequential)] - public struct TCP_INITIAL_RTO_PARAMETERS - { - /// Supplies the initial RTT in milliseconds. - public ushort Rtt; - - /// Supplies the number of retransmissions attempted before the connection setup fails. - public byte MaxSynRetransmissions; - } - - /// Argument structure for SIO_KEEPALIVE_VALS - [PInvokeData("mstcpip.h")] - [StructLayout(LayoutKind.Sequential)] - public struct tcp_keepalive - { - /// - /// Determines if TCP keep-alive is enabled or disabled. If the onoff member is set to a nonzero value, TCP keep-alive is enabled - /// and the other members in the structure are used. - /// - public BOOL onoff; - - /// Specifies the timeout, in milliseconds, with no activity until the first keep-alive packet is sent. - public uint keepalivetime; - - /// - /// Specifies the interval, in milliseconds, between when successive keep-alive packets are sent if no acknowledgement is received. - /// - public uint keepaliveinterval; - } + public uint SndLimTransRwin; /// - /// Describes the input structure used by the SIO_TIMESTAMPING configuration IOCTL to configure timestamp reception for a datagram socket. + /// The cumulative time, in milliseconds, spent in the "Receiver Limited" state where TCP transmission stops because the sender + /// has filled the announced receiver window. /// - // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-timestamping_config typedef struct _TIMESTAMPING_CONFIG { - // ULONG Flags; USHORT TxTimestampsBuffered; } TIMESTAMPING_CONFIG, *PTIMESTAMPING_CONFIG; - [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._TIMESTAMPING_CONFIG")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct TIMESTAMPING_CONFIG - { - /// - /// Type: ULONG - /// Enable/disable timestamp reception for rx/tx direction. - /// - /// Use the values TIMESTAMPING_FLAG_RX (0x1) and TIMESTAMPING_FLAG_TX (0x2) (both defined in mstcpip.h ). - /// Specify a value to enable timestamp reception for that direction; and omit a value to disable timestamp reception for that direction. - /// - /// - public TIMESTAMPING_FLAG Flags; + public uint SndLimTimeRwin; - /// - /// Type: USHORT - /// - /// Determines how many tx timestamps may be buffered. When the count of tx timestamps that have been buffered reaches a value - /// equal to TxTimestampsBuffered, and a new tx timestamp has been generated, the new timestamp will be discarded. - /// - /// - public ushort TxTimestampsBuffered; - } + /// The total number of bytes sent in the "Receiver Limited" state. + public ulong SndLimBytesRwin; /// - /// The TRANSPORT_SETTING_ID structure specifies the transport setting ID used by the SIO_APPLY_TRANSPORT_SETTING and - /// SIO_QUERY_TRANSPORT_SETTING IOCTLs to apply or query the transport setting for a socket. + /// The number of transitions into the "Congestion Limited" state from either the "Receiver Limited" or "Sender Limited" states. /// - /// + public uint SndLimTransCwnd; + + /// + /// The cumulative time, in milliseconds, spent in the "Congestion Limited" state. When there is a retransmission timeout, it is + /// counted in this member and not the cumulative time for some other state. + /// + public uint SndLimTimeCwnd; + + /// The total number of bytes sent in the "Congestion Limited" state. + public ulong SndLimBytesCwnd; + + /// + /// The number of transitions into the "Sender Limited" state from either the "Receiver Limited" or "Congestion Limited" states. + /// + public uint SndLimTransSnd; + + /// The cumulative time, in milliseconds, spent in the "Sender Limited" state. + public uint SndLimTimeSnd; + + /// The total number of bytes sent in the "Sender Limited" state. + public ulong SndLimBytesSnd; + } + + /// + /// The TCP_INITIAL_RTO_PARAMETERS structure specifies data used by the SIO_TCP_INITIAL_RTO IOCTL to configure initial + /// re-transmission timeout (RTO) parameters to be used on the socket. + /// + /// + /// + /// The TCP_INITIAL_RTO_PARAMETERS structure allows an application to configure the initial round trip time (RTT) used to compute the + /// retransmission timeout. The application can also configure the number of re-transmissions that will be attempted before the + /// connection attempt fails. + /// + /// + /// An application should supply the RTT of choice in milliseconds and the maximum number of retransmissions in this structure. The + /// Windows TCP/IP stack will honor these parameters for the subsequent connection attempt. The retransmission behavior for TCP is + /// documented in IETF RFC 793 and 2988. + /// + /// + /// An application may use the unspecified defines, TCP_INITIAL_RTO_UNSPECIFIED_RTT and + /// TCP_INITIAL_RTO_UNSPECIFIED_MAX_SYN_RETRANSMISSIONS when supplying values for one of these fields. This allows the system + /// to pick up administrator configured settings for the parameter left unspecified. + /// + /// + /// An application can choose system defaults for any of these fields and supply those values using the default defines, + /// TCP_INITIAL_RTO_DEFAULT_RTT and TCP_INITIAL_RTO_DEFAULT_MAX_SYN_RETRANSMISSIONS. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-tcp_initial_rto_parameters typedef struct + // _TCP_INITIAL_RTO_PARAMETERS { USHORT Rtt; UCHAR MaxSynRetransmissions; } TCP_INITIAL_RTO_PARAMETERS, *PTCP_INITIAL_RTO_PARAMETERS; + [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._TCP_INITIAL_RTO_PARAMETERS")] + [StructLayout(LayoutKind.Sequential)] + public struct TCP_INITIAL_RTO_PARAMETERS + { + /// Supplies the initial RTT in milliseconds. + public ushort Rtt; + + /// Supplies the number of retransmissions attempted before the connection setup fails. + public byte MaxSynRetransmissions; + } + + /// Argument structure for SIO_KEEPALIVE_VALS + [PInvokeData("mstcpip.h")] + [StructLayout(LayoutKind.Sequential)] + public struct tcp_keepalive + { + /// + /// Determines if TCP keep-alive is enabled or disabled. If the onoff member is set to a nonzero value, TCP keep-alive is enabled + /// and the other members in the structure are used. + /// + public BOOL onoff; + + /// Specifies the timeout, in milliseconds, with no activity until the first keep-alive packet is sent. + public uint keepalivetime; + + /// + /// Specifies the interval, in milliseconds, between when successive keep-alive packets are sent if no acknowledgement is received. + /// + public uint keepaliveinterval; + } + + /// + /// Describes the input structure used by the SIO_TIMESTAMPING configuration IOCTL to configure timestamp reception for a datagram socket. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mstcpip/ns-mstcpip-timestamping_config typedef struct _TIMESTAMPING_CONFIG { + // ULONG Flags; USHORT TxTimestampsBuffered; } TIMESTAMPING_CONFIG, *PTIMESTAMPING_CONFIG; + [PInvokeData("mstcpip.h", MSDNShortId = "NS:mstcpip._TIMESTAMPING_CONFIG")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct TIMESTAMPING_CONFIG + { + /// + /// Type: ULONG + /// Enable/disable timestamp reception for rx/tx direction. /// - /// The only transport setting defined for Windows 8 and Windows Server 2012 is for the REAL_TIME_NOTIFICATION_CAPABILITY - /// capability on a TCP socket. For Windows 10 and Windows Server 2016, there is another transport setting defined as ASSOCIATE_NAMERES_CONTEXT. + /// Use the values TIMESTAMPING_FLAG_RX (0x1) and TIMESTAMPING_FLAG_TX (0x2) (both defined in mstcpip.h ). + /// Specify a value to enable timestamp reception for that direction; and omit a value to disable timestamp reception for that direction. /// + /// + public TIMESTAMPING_FLAG Flags; + + /// + /// Type: USHORT /// - /// The TRANSPORT_SETTING_ID structure is passed as input to the SIO_APPLY_TRANSPORT_SETTING and SIO_QUERY_TRANSPORT_SETTING - /// IOCTLs. The Guid member determines what transport setting is applied or queried. + /// Determines how many tx timestamps may be buffered. When the count of tx timestamps that have been buffered reaches a value + /// equal to TxTimestampsBuffered, and a new tx timestamp has been generated, the new timestamp will be discarded. /// - /// The only transport setting currently defines is for the REAL_TIME_NOTIFICATION_CAPABILITY capability on a TCP socket. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/transportsettingcommon/ns-transportsettingcommon-transport_setting_id typedef - // struct TRANSPORT_SETTING_ID { GUID Guid; } TRANSPORT_SETTING_ID, *PTRANSPORT_SETTING_ID; - [PInvokeData("transportsettingcommon.h", MSDNShortId = "NS:transportsettingcommon.TRANSPORT_SETTING_ID")] - [StructLayout(LayoutKind.Sequential)] - public struct TRANSPORT_SETTING_ID - { - /// The transport setting ID. - public Guid Guid; - } + /// + public ushort TxTimestampsBuffered; + } + + /// + /// The TRANSPORT_SETTING_ID structure specifies the transport setting ID used by the SIO_APPLY_TRANSPORT_SETTING and + /// SIO_QUERY_TRANSPORT_SETTING IOCTLs to apply or query the transport setting for a socket. + /// + /// + /// + /// The only transport setting defined for Windows 8 and Windows Server 2012 is for the REAL_TIME_NOTIFICATION_CAPABILITY + /// capability on a TCP socket. For Windows 10 and Windows Server 2016, there is another transport setting defined as ASSOCIATE_NAMERES_CONTEXT. + /// + /// + /// The TRANSPORT_SETTING_ID structure is passed as input to the SIO_APPLY_TRANSPORT_SETTING and SIO_QUERY_TRANSPORT_SETTING + /// IOCTLs. The Guid member determines what transport setting is applied or queried. + /// + /// The only transport setting currently defines is for the REAL_TIME_NOTIFICATION_CAPABILITY capability on a TCP socket. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/transportsettingcommon/ns-transportsettingcommon-transport_setting_id typedef + // struct TRANSPORT_SETTING_ID { GUID Guid; } TRANSPORT_SETTING_ID, *PTRANSPORT_SETTING_ID; + [PInvokeData("transportsettingcommon.h", MSDNShortId = "NS:transportsettingcommon.TRANSPORT_SETTING_ID")] + [StructLayout(LayoutKind.Sequential)] + public struct TRANSPORT_SETTING_ID + { + /// The transport setting ID. + public Guid Guid; } } \ No newline at end of file diff --git a/PInvoke/Ws2_32/mswsockdef.cs b/PInvoke/Ws2_32/mswsockdef.cs new file mode 100644 index 00000000..f19e4b9a --- /dev/null +++ b/PInvoke/Ws2_32/mswsockdef.cs @@ -0,0 +1,144 @@ +global using PRIO_BUF = System.IntPtr; +global using RIO_BUFFERID = System.IntPtr; +global using RIO_CQ = System.IntPtr; +global using RIO_RQ = System.IntPtr; + +using System; +using System.Runtime.InteropServices; + +namespace Vanara.PInvoke; + +public static partial class Ws2_32 +{ +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + public const int RIO_MAX_CQ_SIZE = 0x8000000; + public static readonly RIO_CQ RIO_CORRUPT_CQ = (RIO_CQ)0xFFFFFFFF; + public static readonly RIO_BUFFERID RIO_INVALID_BUFFERID = (RIO_BUFFERID)0xFFFFFFFF; + public static readonly RIO_CQ RIO_INVALID_CQ = (RIO_CQ)0; + public static readonly RIO_RQ RIO_INVALID_RQ = (RIO_RQ)0; + public static readonly uint SIO_SET_COMPATIBILITY_MODE = _WSAIOW(IOC_VENDOR, 300); +#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member + + /// A set of flags that modify the behavior of the RIOSendEx function. + [PInvokeData("mswsockdef.h", MSDNShortId = "NC:mswsock.LPFN_RIORECEIVE")] + [Flags] + public enum RIO_MSG + { + /// + /// The request should not trigger the RIONotify function when request completion is inserted into its completion queue. + /// + RIO_MSG_DONT_NOTIFY = 0x00000001, + + /// + /// The request does not need to be executed immediately. This will insert the request into the request queue, but it may or may not + /// trigger the execution of the request. Sending data may be delayed until a send request is made on the RIO_RQ passed in the + /// SocketQueue parameter without the RIO_MSG_DEFER flag set. To trigger execution for all sends in a send queue, call + /// the RIOSend or RIOSendEx function without the RIO_MSG_DEFER flag set. Note The send request is + /// charged against the outstanding I/O capacity on the RIO_RQ passed in the SocketQueue parameter regardless of + /// whether RIO_MSG_DEFER is set. + /// + RIO_MSG_DEFER = 0x00000002, + + /// + /// Causes the recv call to only complete when the buffer slice supplied is full, an error occurs, or the connection is terminated. + /// + RIO_MSG_WAITALL = 0x00000004, + + /// + /// Previous requests added with RIO_MSG_DEFER flag will be committed. When the RIO_MSG_COMMIT_ONLY flag is set, no + /// other flags may be specified. When the RIO_MSG_COMMIT_ONLY flag is set, the pData, pLocalAddress, + /// pRemoteAddress, pControlContext, pFlags, and RequestContext parameters must be NULL and the + /// DataBufferCount parameter must be zero. This flag would normally be used occasionally after a number of requests were + /// issued with the RIO_MSG_DEFER flag set. This eliminates the need when using the RIO_MSG_DEFER flag to make the last + /// request without the RIO_MSG_DEFER flag, which causes the last request to complete much slower than other requests. Unlike + /// other calls to the RIOSendEx function, when the RIO_MSG_COMMIT_ONLY flag is set calls to the RIOSendEx + /// function do not need to be serialized. For a single RIO_RQ, the RIOSendEx function can be called with + /// RIO_MSG_COMMIT_ONLY on one thread while calling the RIOSendEx function on another thread. + /// + RIO_MSG_COMMIT_ONLY = 0x00000008, + } + + /// + /// The RIO_BUF structure specifies a portion of a registered buffer used for sending or receiving network data with the Winsock + /// registered I/O extensions. + /// + /// + /// + /// The Winsock registered I/O extensions often operate on portions of registered buffers sometimes called buffer slices. The + /// RIO_BUF structure is used by an application that needs to use a small amount of registered memory for sending or receiving + /// network data. The application can often increase performance by registering one large buffer and then using small chunks of the + /// buffer as needed. The RIO_BUF structure may describe any contiguous segment of memory contained in a single buffer registration. + /// + /// + /// A pointer to a RIO_BUF structure is passed as the pData parameter to the RIOSend, RIOSendEx, RIOReceive, and + /// RIOReceiveEx functions to send or receive network data. + /// + /// + /// An application cannot resize a registered buffer simply by using a buffer slice with values larger than the original buffer that was + /// registered using the RIORegisterBuffer function. + /// + /// + /// The RIO_BUF structure is defined in the Mswsockdef.h header file which is automatically included in the + /// Mswsock.h header file. The Mswsockdef.h header file should never be used directly. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsockdef/ns-mswsockdef-rio_buf typedef struct _RIO_BUF { RIO_BUFFERID BufferId; + // ULONG Offset; ULONG Length; } RIO_BUF, *PRIO_BUF; + [PInvokeData("mswsockdef.h", MSDNShortId = "NS:mswsockdef._RIO_BUF")] + [StructLayout(LayoutKind.Sequential)] + public struct RIO_BUF + { + /// The registered buffer descriptor for a Winsock registered I/O buffer used with send and receive requests. + public RIO_BUFFERID BufferId; + + /// + /// The offset, in bytes, into the buffer specified by the BufferId member. An Offset value of zero points to the + /// beginning of the buffer + /// + public uint Offset; + + /// A length, in bytes, of the buffer to use from the Offset member. + public uint Length; + } + + /// + /// The RIORESULT structure contains data used to indicate request completion results used with the Winsock registered I/O extensions. + /// + /// + /// + /// The RIORESULT structure defines the data format used to indicate request completion by the Winsock registered I/O extensions. + /// An application requests completion indications by allocating an array of RIORESULT structures and passing the array of + /// RIORESULT structures to the RIODequeueCompletion function along with the element count. The application need not perform any + /// initialization of the RIORESULT structure elements before calling the RIODequeueCompletion function. + /// + /// + /// The SocketContext member of the RIORESULT structure can be used by an application to identify the RIO_CQ object or the + /// associated application object on which the Winsock registered I/O request was issued. The RequestContext member of the + /// RIORESULT structure can similarly be used to identify the particular Winsock registered I/O request that was completed. + /// + /// + /// The RIORESULT structure is defined in the Mswsockdef.h header file which is automatically included in the + /// Mswsock.h header file. The Mswsockdef.h header file should never be used directly. + /// + /// + // https://learn.microsoft.com/en-us/windows/win32/api/mswsockdef/ns-mswsockdef-rioresult typedef struct _RIORESULT { LONG Status; ULONG + // BytesTransferred; ULONGLONG SocketContext; ULONGLONG RequestContext; } RIORESULT, *PRIORESULT; + [PInvokeData("mswsockdef.h", MSDNShortId = "NS:mswsockdef._RIORESULT")] + [StructLayout(LayoutKind.Sequential)] + public struct RIORESULT + { + /// The completion status of the Winsock registered I/O request. + public int Status; + + /// The number of bytes sent or received in the I/O request. + public uint BytesTransferred; + + /// An application-provided context specified in call to the RIOCreateRequestQueue function. + public ulong SocketContext; + + /// + /// An application-provided context specified with the registered I/O request to the RIOReceive, RIOReceiveEx, RIOSend, and RIOSendEx functions. + /// + public ulong RequestContext; + } +} \ No newline at end of file diff --git a/PInvoke/Ws2_32/ws2def.cs b/PInvoke/Ws2_32/ws2def.cs index 718992d5..84b121d1 100644 --- a/PInvoke/Ws2_32/ws2def.cs +++ b/PInvoke/Ws2_32/ws2def.cs @@ -6,2224 +6,2258 @@ using Vanara.Extensions; using Vanara.InteropServices; #pragma warning disable IDE1006 // Naming Styles -namespace Vanara.PInvoke +namespace Vanara.PInvoke; + +public static partial class Ws2_32 { - public static partial class Ws2_32 +#pragma warning disable CS1591 // Missing XML comment for publicly visible type or member + public const uint IOC_UNIX = 0x00000000; + public const uint IOC_WS2 = 0x08000000; + public const uint IOC_PROTOCOL = 0x10000000; + public const uint IOC_VENDOR = 0x18000000; + public const uint IOC_WSK = 0x0F000000; + public static uint _WSAIO(uint x, uint y) => IOC_VOID|x|y; + public static uint _WSAIOR(uint x, uint y) => IOC_OUT|x|y; + public static uint _WSAIOW(uint x, uint y) => IOC_IN|x|y; + public static uint _WSAIORW(uint x, uint y) => IOC_INOUT|x|y; + public static readonly uint SIO_ASSOCIATE_HANDLE = _WSAIOW(IOC_WS2,1); + public static readonly uint SIO_ENABLE_CIRCULAR_QUEUEING = _WSAIO(IOC_WS2,2); + public static readonly uint SIO_FIND_ROUTE = _WSAIOR(IOC_WS2,3); + public static readonly uint SIO_FLUSH = _WSAIO(IOC_WS2,4); + public static readonly uint SIO_GET_BROADCAST_ADDRESS = _WSAIOR(IOC_WS2,5); + public static readonly uint SIO_GET_EXTENSION_FUNCTION_POINTER = _WSAIORW(IOC_WS2,6); + public static readonly uint SIO_GET_QOS = _WSAIORW(IOC_WS2,7); + public static readonly uint SIO_GET_GROUP_QOS = _WSAIORW(IOC_WS2,8); + public static readonly uint SIO_MULTIPOINT_LOOPBACK = _WSAIOW(IOC_WS2,9); + public static readonly uint SIO_MULTICAST_SCOPE = _WSAIOW(IOC_WS2,10); + public static readonly uint SIO_SET_QOS = _WSAIOW(IOC_WS2,11); + public static readonly uint SIO_SET_GROUP_QOS = _WSAIOW(IOC_WS2,12); + public static readonly uint SIO_TRANSLATE_HANDLE = _WSAIORW(IOC_WS2,13); + public static readonly uint SIO_ROUTING_INTERFACE_QUERY = _WSAIORW(IOC_WS2,20); + public static readonly uint SIO_ROUTING_INTERFACE_CHANGE = _WSAIOW(IOC_WS2,21); + public static readonly uint SIO_ADDRESS_LIST_QUERY = _WSAIOR(IOC_WS2,22); + public static readonly uint SIO_ADDRESS_LIST_CHANGE = _WSAIO(IOC_WS2,23); + public static readonly uint SIO_QUERY_TARGET_PNP_HANDLE = _WSAIOR(IOC_WS2,24); + public static readonly uint SIO_QUERY_RSS_PROCESSOR_INFO = _WSAIOR(IOC_WS2,37); + public static readonly uint SIO_ADDRESS_LIST_SORT = _WSAIORW(IOC_WS2,25); + public static readonly uint SIO_RESERVED_1 = _WSAIOW(IOC_WS2,26); + public static readonly uint SIO_RESERVED_2 = _WSAIOW(IOC_WS2,33); + public static readonly uint SIO_GET_MULTIPLE_EXTENSION_FUNCTION_POINTER = _WSAIORW(IOC_WS2, 36); +#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member + + /// Flags that indicate options used in the GetAddrInfoW function. + [PInvokeData("ws2def.h", MSDNShortId = "a4896eac-68ae-4a08-8647-36be65fe4478")] + [Flags] + public enum ADDRINFO_FLAGS : uint { - /// Flags that indicate options used in the GetAddrInfoW function. - [PInvokeData("ws2def.h", MSDNShortId = "a4896eac-68ae-4a08-8647-36be65fe4478")] - [Flags] - public enum ADDRINFO_FLAGS : uint - { - /// The socket address will be used in a call to the bindfunction. - AI_PASSIVE = 0x01, + /// The socket address will be used in a call to the bindfunction. + AI_PASSIVE = 0x01, - /// The canonical name is returned in the first ai_canonname member. - AI_CANONNAME = 0x02, + /// The canonical name is returned in the first ai_canonname member. + AI_CANONNAME = 0x02, - /// The nodename parameter passed to the GetAddrInfoW function must be a numeric string. - AI_NUMERICHOST = 0x04, + /// The nodename parameter passed to the GetAddrInfoW function must be a numeric string. + AI_NUMERICHOST = 0x04, - /// Servicename must be a numeric port number. - AI_NUMERICSERV = 0x08, + /// Servicename must be a numeric port number. + AI_NUMERICSERV = 0x08, - /// - /// If this bit is set, a request is made for IPv6 addresses and IPv4 addresses with AI_V4MAPPED. - /// This option is supported on Windows Vista and later. - /// - AI_ALL = 0x0100, + /// + /// If this bit is set, a request is made for IPv6 addresses and IPv4 addresses with AI_V4MAPPED. + /// This option is supported on Windows Vista and later. + /// + AI_ALL = 0x0100, - /// - /// The GetAddrInfoW will resolve only if a global address is configured. The IPv6 and IPv4 loopback address is not considered a - /// valid global address. This option is only supported on Windows Vista and later. - /// - AI_ADDRCONFIG = 0x0400, + /// + /// The GetAddrInfoW will resolve only if a global address is configured. The IPv6 and IPv4 loopback address is not considered a + /// valid global address. This option is only supported on Windows Vista and later. + /// + AI_ADDRCONFIG = 0x0400, - /// - /// If the GetAddrInfoW request for an IPv6 addresses fails, a name service request is made for IPv4 addresses and these - /// addresses are converted to IPv4-mapped IPv6 address format. - /// This option is supported on Windows Vista and later. - /// - AI_V4MAPPED = 0x0800, + /// + /// If the GetAddrInfoW request for an IPv6 addresses fails, a name service request is made for IPv4 addresses and these + /// addresses are converted to IPv4-mapped IPv6 address format. + /// This option is supported on Windows Vista and later. + /// + AI_V4MAPPED = 0x0800, - /// - /// The address information can be from a non-authoritative namespace provider. - /// This option is only supported on Windows Vista and later for the NS_EMAIL namespace. - /// - AI_NON_AUTHORITATIVE = 0x04000, + /// + /// The address information can be from a non-authoritative namespace provider. + /// This option is only supported on Windows Vista and later for the NS_EMAIL namespace. + /// + AI_NON_AUTHORITATIVE = 0x04000, - /// - /// The address information is from a secure channel. - /// This option is only supported on Windows Vista and later for the NS_EMAIL namespace. - /// - AI_SECURE = 0x08000, + /// + /// The address information is from a secure channel. + /// This option is only supported on Windows Vista and later for the NS_EMAIL namespace. + /// + AI_SECURE = 0x08000, - /// - /// The address information is for a preferred name for a user. - /// This option is only supported on Windows Vista and later for the NS_EMAIL namespace. - /// - AI_RETURN_PREFERRED_NAMES = 0x010000, + /// + /// The address information is for a preferred name for a user. + /// This option is only supported on Windows Vista and later for the NS_EMAIL namespace. + /// + AI_RETURN_PREFERRED_NAMES = 0x010000, - /// - /// If a flat name (single label) is specified, GetAddrInfoW will return the fully qualified domain name that the name - /// eventually resolved to. The fully qualified domain name is returned in the ai_canonname member. - /// - /// This is different than AI_CANONNAME bit flag that returns the canonical name registered in DNS which may be different than - /// the fully qualified domain name that the flat name resolved to. - /// - /// - /// Only one of the AI_FQDN and AI_CANONNAME bits can be set. The GetAddrInfoW function will fail if both flags are present with EAI_BADFLAGS. - /// - /// This option is supported on Windows 7, Windows Server 2008 R2, and later. - /// - AI_FQDN = 0x00020000, + /// + /// If a flat name (single label) is specified, GetAddrInfoW will return the fully qualified domain name that the name + /// eventually resolved to. The fully qualified domain name is returned in the ai_canonname member. + /// + /// This is different than AI_CANONNAME bit flag that returns the canonical name registered in DNS which may be different than + /// the fully qualified domain name that the flat name resolved to. + /// + /// + /// Only one of the AI_FQDN and AI_CANONNAME bits can be set. The GetAddrInfoW function will fail if both flags are present with EAI_BADFLAGS. + /// + /// This option is supported on Windows 7, Windows Server 2008 R2, and later. + /// + AI_FQDN = 0x00020000, - /// - /// A hint to the namespace provider that the hostname being queried is being used in a file share scenario. The namespace - /// provider may ignore this hint. - /// This option is supported on Windows 7, Windows Server 2008 R2, and later. - /// - AI_FILESERVER = 0x00040000, + /// + /// A hint to the namespace provider that the hostname being queried is being used in a file share scenario. The namespace + /// provider may ignore this hint. + /// This option is supported on Windows 7, Windows Server 2008 R2, and later. + /// + AI_FILESERVER = 0x00040000, - /// - /// Disable the automatic International Domain Name encoding using Punycode in the name resolution functions called by the - /// GetAddrInfoW function. - /// This option is supported on Windows 8, Windows Server 2012, and later. - /// - AI_DISABLE_IDN_ENCODING = 0x00080000, + /// + /// Disable the automatic International Domain Name encoding using Punycode in the name resolution functions called by the + /// GetAddrInfoW function. + /// This option is supported on Windows 8, Windows Server 2012, and later. + /// + AI_DISABLE_IDN_ENCODING = 0x00080000, - /// Indicates this is extended ADDRINFOEX(2/..) struct - AI_EXTENDED = 0x80000000, + /// Indicates this is extended ADDRINFOEX(2/..) struct + AI_EXTENDED = 0x80000000, - /// Request resolution handle - AI_RESOLUTION_HANDLE = 0x40000000, - } + /// Request resolution handle + AI_RESOLUTION_HANDLE = 0x40000000, + } - /// Protocols. The IPv6 defines are specified in RFC 2292. - [PInvokeData("ws2def.h")] - public enum IPPROTO - { - /// - IPPROTO_IP = 0, + /// Protocols. The IPv6 defines are specified in RFC 2292. + [PInvokeData("ws2def.h")] + public enum IPPROTO + { + /// + IPPROTO_IP = 0, - /// - IPPROTO_HOPOPTS = 0, + /// + IPPROTO_HOPOPTS = 0, - /// - /// The Internet Control Message Protocol (ICMP). This is a possible value when the af parameter is AF_UNSPEC, AF_INET, or - /// AF_INET6 and the type parameter is SOCK_RAW or unspecified. - /// This protocol value is supported on Windows XP and later. - /// - IPPROTO_ICMP = 1, + /// + /// The Internet Control Message Protocol (ICMP). This is a possible value when the af parameter is AF_UNSPEC, AF_INET, or + /// AF_INET6 and the type parameter is SOCK_RAW or unspecified. + /// This protocol value is supported on Windows XP and later. + /// + IPPROTO_ICMP = 1, - /// - /// The Internet Group Management Protocol (IGMP). This is a possible value when the af parameter is AF_UNSPEC, AF_INET, or - /// AF_INET6 and the type parameter is SOCK_RAW or unspecified. - /// This protocol value is supported on Windows XP and later. - /// - IPPROTO_IGMP = 2, + /// + /// The Internet Group Management Protocol (IGMP). This is a possible value when the af parameter is AF_UNSPEC, AF_INET, or + /// AF_INET6 and the type parameter is SOCK_RAW or unspecified. + /// This protocol value is supported on Windows XP and later. + /// + IPPROTO_IGMP = 2, - /// - /// The Bluetooth Radio Frequency Communications (Bluetooth RFCOMM) protocol. This is a possible value when the af parameter is - /// AF_BTH and the type parameter is SOCK_STREAM. - /// This protocol value is supported on Windows XP with SP2 or later. - /// - IPPROTO_GGP = 3, + /// + /// The Bluetooth Radio Frequency Communications (Bluetooth RFCOMM) protocol. This is a possible value when the af parameter is + /// AF_BTH and the type parameter is SOCK_STREAM. + /// This protocol value is supported on Windows XP with SP2 or later. + /// + IPPROTO_GGP = 3, - /// - IPPROTO_IPV4 = 4, + /// + IPPROTO_IPV4 = 4, - /// - IPPROTO_ST = 5, + /// + IPPROTO_ST = 5, - /// - /// The Transmission Control Protocol (TCP). This is a possible value when the af parameter is AF_INET or AF_INET6 and the type - /// parameter is SOCK_STREAM. - /// - IPPROTO_TCP = 6, + /// + /// The Transmission Control Protocol (TCP). This is a possible value when the af parameter is AF_INET or AF_INET6 and the type + /// parameter is SOCK_STREAM. + /// + IPPROTO_TCP = 6, - /// - IPPROTO_CBT = 7, + /// + IPPROTO_CBT = 7, - /// - IPPROTO_EGP = 8, + /// + IPPROTO_EGP = 8, - /// - IPPROTO_IGP = 9, + /// + IPPROTO_IGP = 9, - /// - IPPROTO_PUP = 12, + /// + IPPROTO_PUP = 12, - /// - /// The User Datagram Protocol (UDP). This is a possible value when the af parameter is AF_INET or AF_INET6 and the type - /// parameter is SOCK_DGRAM. - /// - IPPROTO_UDP = 17, + /// + /// The User Datagram Protocol (UDP). This is a possible value when the af parameter is AF_INET or AF_INET6 and the type + /// parameter is SOCK_DGRAM. + /// + IPPROTO_UDP = 17, - /// - IPPROTO_IDP = 22, + /// + IPPROTO_IDP = 22, - /// - IPPROTO_RDP = 27, + /// + IPPROTO_RDP = 27, - /// - IPPROTO_IPV6 = 41, + /// + IPPROTO_IPV6 = 41, - /// - IPPROTO_ROUTING = 43, + /// + IPPROTO_ROUTING = 43, - /// - IPPROTO_FRAGMENT = 44, + /// + IPPROTO_FRAGMENT = 44, - /// - IPPROTO_ESP = 50, + /// + IPPROTO_ESP = 50, - /// - IPPROTO_AH = 51, + /// + IPPROTO_AH = 51, - /// - /// The Internet Control Message Protocol Version 6 (ICMPv6). This is a possible value when the af parameter is AF_UNSPEC, - /// AF_INET, or AF_INET6 and the type parameter is SOCK_RAW or unspecified. - /// This protocol value is supported on Windows XP and later. - /// - IPPROTO_ICMPV6 = 58, + /// + /// The Internet Control Message Protocol Version 6 (ICMPv6). This is a possible value when the af parameter is AF_UNSPEC, + /// AF_INET, or AF_INET6 and the type parameter is SOCK_RAW or unspecified. + /// This protocol value is supported on Windows XP and later. + /// + IPPROTO_ICMPV6 = 58, - /// - IPPROTO_NONE = 59, + /// + IPPROTO_NONE = 59, - /// - IPPROTO_DSTOPTS = 60, + /// + IPPROTO_DSTOPTS = 60, - /// - IPPROTO_ND = 77, + /// + IPPROTO_ND = 77, - /// - IPPROTO_ICLFXBM = 78, + /// + IPPROTO_ICLFXBM = 78, - /// - IPPROTO_PIM = 103, + /// + IPPROTO_PIM = 103, - /// - /// The PGM protocol for reliable multicast. This is a possible value when the af parameter is AF_INET and the type parameter is - /// SOCK_RDM. On the Windows SDK released for Windows Vista and later, this protocol is also called IPPROTO_PGM. - /// This protocol value is only supported if the Reliable Multicast Protocol is installed. - /// - IPPROTO_PGM = 113, + /// + /// The PGM protocol for reliable multicast. This is a possible value when the af parameter is AF_INET and the type parameter is + /// SOCK_RDM. On the Windows SDK released for Windows Vista and later, this protocol is also called IPPROTO_PGM. + /// This protocol value is only supported if the Reliable Multicast Protocol is installed. + /// + IPPROTO_PGM = 113, - /// - IPPROTO_L2TP = 115, + /// + IPPROTO_L2TP = 115, - /// - IPPROTO_SCTP = 132, + /// + IPPROTO_SCTP = 132, - /// - IPPROTO_RAW = 255, + /// + IPPROTO_RAW = 255, - /// - IPPROTO_MAX = 256, + /// + IPPROTO_MAX = 256, - /// - IPPROTO_RESERVED_RAW = 257, + /// + IPPROTO_RESERVED_RAW = 257, - /// - IPPROTO_RESERVED_IPSEC = 258, + /// + IPPROTO_RESERVED_IPSEC = 258, - /// - IPPROTO_RESERVED_IPSECOFFLOAD = 259, + /// + IPPROTO_RESERVED_IPSECOFFLOAD = 259, - /// - IPPROTO_RESERVED_WNV = 260, + /// + IPPROTO_RESERVED_WNV = 260, - /// - IPPROTO_RESERVED_MAX = 261 - } + /// + IPPROTO_RESERVED_MAX = 261 + } - /// Customize processing of the GetNameInfoW function. - [PInvokeData("ws2def.h", MSDNShortId = "5630a49a-c182-440c-ad54-6ff3ba4274c6")] - public enum NI - { - /// Results in local hosts having only their Relative Distinguished Name (RDN) returned in the pNodeBuffer parameter. - NI_NOFQDN = 0x01 /* Only return nodename portion for local hosts */, + /// Customize processing of the GetNameInfoW function. + [PInvokeData("ws2def.h", MSDNShortId = "5630a49a-c182-440c-ad54-6ff3ba4274c6")] + public enum NI + { + /// Results in local hosts having only their Relative Distinguished Name (RDN) returned in the pNodeBuffer parameter. + NI_NOFQDN = 0x01 /* Only return nodename portion for local hosts */, - /// - /// Returns the numeric form of the host name instead of its name. The numeric form of the host name is also returned if the - /// host name cannot be resolved by DNS. - /// - NI_NUMERICHOST = 0x02 /* Return numeric form of the host's address */, + /// + /// Returns the numeric form of the host name instead of its name. The numeric form of the host name is also returned if the + /// host name cannot be resolved by DNS. + /// + NI_NUMERICHOST = 0x02 /* Return numeric form of the host's address */, - /// A host name that cannot be resolved by the DNS results in an error. - NI_NAMEREQD = 0x04 /* Error if the host's name not in DNS */, + /// A host name that cannot be resolved by the DNS results in an error. + NI_NAMEREQD = 0x04 /* Error if the host's name not in DNS */, - /// - /// Returns the port number of the service instead of its name. Also, if a host name is not found for an IP address (127.0.0.2, - /// for example), the hostname is returned as the IP address. - /// - NI_NUMERICSERV = 0x08 /* Return numeric form of the service (port #) */, + /// + /// Returns the port number of the service instead of its name. Also, if a host name is not found for an IP address (127.0.0.2, + /// for example), the hostname is returned as the IP address. + /// + NI_NUMERICSERV = 0x08 /* Return numeric form of the service (port #) */, - /// - /// Indicates that the service is a datagram service. This flag is necessary for the few services that provide different port - /// numbers for UDP and TCP service. - /// - NI_DGRAM = 0x10 /* Service is a datagram service */, - } + /// + /// Indicates that the service is a datagram service. This flag is necessary for the few services that provide different port + /// numbers for UDP and TCP service. + /// + NI_DGRAM = 0x10 /* Service is a datagram service */, + } - /// The scope of the IPv6 transport address. - [PInvokeData("ws2def.h")] - public enum SCOPE_LEVEL - { - /// The transport address has interface-local scope. - ScopeLevelInterface = 1, + /// The scope of the IPv6 transport address. + [PInvokeData("ws2def.h")] + public enum SCOPE_LEVEL + { + /// The transport address has interface-local scope. + ScopeLevelInterface = 1, - /// The transport address has link-local scope. - ScopeLevelLink = 2, + /// The transport address has link-local scope. + ScopeLevelLink = 2, - /// The transport address has subnet-local scope. - ScopeLevelSubnet = 3, + /// The transport address has subnet-local scope. + ScopeLevelSubnet = 3, - /// The transport address has admin-local scope. - ScopeLevelAdmin = 4, + /// The transport address has admin-local scope. + ScopeLevelAdmin = 4, - /// The transport address has site-local scope. - ScopeLevelSite = 5, + /// The transport address has site-local scope. + ScopeLevelSite = 5, - /// The transport address has organization-local scope. - ScopeLevelOrganization = 8, + /// The transport address has organization-local scope. + ScopeLevelOrganization = 8, - /// The transport address has global scope. - ScopeLevelGlobal = 14, + /// The transport address has global scope. + ScopeLevelGlobal = 14, - /// The scope level count. - ScopeLevelCount = 16 - } + /// The scope level count. + ScopeLevelCount = 16 + } - /// Gets the size, in bytes, of a given a number of address. - /// The address count. - /// The size, in bytes, required to hold the structure. This does not include allocation for the addresses pointed to by each . - [PInvokeData("ws2def.h")] - public static SizeT SIZEOF_SOCKET_ADDRESS_LIST(SizeT AddressCount) => Marshal.OffsetOf(typeof(SOCKET_ADDRESS_LIST), "Address").ToInt32() + Marshal.SizeOf(typeof(SOCKET_ADDRESS)) * AddressCount; + /// Gets the size, in bytes, of a given a number of address. + /// The address count. + /// The size, in bytes, required to hold the structure. This does not include allocation for the addresses pointed to by each . + [PInvokeData("ws2def.h")] + public static SizeT SIZEOF_SOCKET_ADDRESS_LIST(SizeT AddressCount) => Marshal.OffsetOf(typeof(SOCKET_ADDRESS_LIST), "Address").ToInt32() + Marshal.SizeOf(typeof(SOCKET_ADDRESS)) * AddressCount; #if x64 - public static readonly SizeT MAX_NATURAL_ALIGNMENT = sizeof(ulong); + public static readonly SizeT MAX_NATURAL_ALIGNMENT = sizeof(ulong); #else - /// The maximum natural alignment - public static readonly SizeT MAX_NATURAL_ALIGNMENT = sizeof(uint); + /// The maximum natural alignment + public static readonly SizeT MAX_NATURAL_ALIGNMENT = sizeof(uint); #endif - [StructLayout(LayoutKind.Sequential)] - private struct AlignedStruct where T : struct + [StructLayout(LayoutKind.Sequential)] + private struct AlignedStruct where T : struct + { + private readonly byte b; + public readonly T type; + } + + /// Returns the alignment in bytes of the specified type as a value of type . + /// The type for which to get the alignment. + /// The alignment in bytes of the specified type. + public static SizeT TYPE_ALIGNMENT() where T : struct => Marshal.OffsetOf(typeof(AlignedStruct), "type").ToInt64(); + + /// Returns the alignment in bytes of padding as a value of type . + /// The padding length. + /// The alignment in bytes. + public static SizeT WSA_CMSGDATA_ALIGN(SizeT length) => (length + MAX_NATURAL_ALIGNMENT-1) & (~(MAX_NATURAL_ALIGNMENT-1)); + + /// Returns the alignment in bytes of WSACMSGHDR with padding as a value of type . + /// The padding length. + /// The alignment in bytes. + public static SizeT WSA_CMSGHDR_ALIGN(SizeT length) => + (length + TYPE_ALIGNMENT()-1) & (~(TYPE_ALIGNMENT()-1)); + + /// + /// Returns a pointer to the first byte of data (what is referred to as the cmsg_data member though it is not defined in the structure). + /// + /// The WSACMSGHDR instance. + /// The pointer. + public static unsafe byte* WSA_CMSG_DATA(WSACMSGHDR* cmsg) => (byte*)cmsg + WSA_CMSGDATA_ALIGN(Marshal.SizeOf(typeof(WSACMSGHDR))); + + /// + /// Returns the first ancillary data object, or a null if there is no ancillary data in the control buffer of the WSAMSG structure. + /// + /// The message. + /// The first ancillary data object, or a null. + public static unsafe WSACMSGHDR* WSA_CMSG_FIRSTHDR(in WSAMSG msg) => + (msg.Control.len >= Marshal.SizeOf(typeof(WSACMSGHDR))) ? (WSACMSGHDR*)msg.Control.buf : default; + + /// Returns the value to store in cmsg_len given the amount of data. + /// The length. + /// The data length. + public static SizeT WSA_CMSG_LEN(SizeT length) => WSA_CMSGDATA_ALIGN(Marshal.SizeOf(typeof(WSACMSGHDR))) + length; + + /// Returns the next ancillary data object, or a null if there are no more data objects. + /// The message. + /// The message header. + /// The next header. + public static unsafe WSACMSGHDR* WSA_CMSG_NXTHDR(in WSAMSG msg, WSACMSGHDR* cmsg) + { + if (cmsg is null) + return WSA_CMSG_FIRSTHDR(msg); + unsafe { - private readonly byte b; - public readonly T type; - } - - /// Returns the alignment in bytes of the specified type as a value of type . - /// The type for which to get the alignment. - /// The alignment in bytes of the specified type. - public static SizeT TYPE_ALIGNMENT() where T : struct => Marshal.OffsetOf(typeof(AlignedStruct), "type").ToInt64(); - - /// Returns the alignment in bytes of padding as a value of type . - /// The padding length. - /// The alignment in bytes. - public static SizeT WSA_CMSGDATA_ALIGN(SizeT length) => (length + MAX_NATURAL_ALIGNMENT-1) & (~(MAX_NATURAL_ALIGNMENT-1)); - - /// Returns the alignment in bytes of WSACMSGHDR with padding as a value of type . - /// The padding length. - /// The alignment in bytes. - public static SizeT WSA_CMSGHDR_ALIGN(SizeT length) => - (length + TYPE_ALIGNMENT()-1) & (~(TYPE_ALIGNMENT()-1)); - - /// - /// Returns a pointer to the first byte of data (what is referred to as the cmsg_data member though it is not defined in the structure). - /// - /// The WSACMSGHDR instance. - /// The pointer. - public static unsafe byte* WSA_CMSG_DATA(WSACMSGHDR* cmsg) => (byte*)cmsg + WSA_CMSGDATA_ALIGN(Marshal.SizeOf(typeof(WSACMSGHDR))); - - /// - /// Returns the first ancillary data object, or a null if there is no ancillary data in the control buffer of the WSAMSG structure. - /// - /// The message. - /// The first ancillary data object, or a null. - public static unsafe WSACMSGHDR* WSA_CMSG_FIRSTHDR(in WSAMSG msg) => - (msg.Control.len >= Marshal.SizeOf(typeof(WSACMSGHDR))) ? (WSACMSGHDR*)msg.Control.buf : default; - - /// Returns the value to store in cmsg_len given the amount of data. - /// The length. - /// The data length. - public static SizeT WSA_CMSG_LEN(SizeT length) => WSA_CMSGDATA_ALIGN(Marshal.SizeOf(typeof(WSACMSGHDR))) + length; - - /// Returns the next ancillary data object, or a null if there are no more data objects. - /// The message. - /// The message header. - /// The next header. - public static unsafe WSACMSGHDR* WSA_CMSG_NXTHDR(in WSAMSG msg, WSACMSGHDR* cmsg) - { - if (cmsg is null) - return WSA_CMSG_FIRSTHDR(msg); - unsafe - { - var len = (byte*)cmsg + WSA_CMSGHDR_ALIGN(cmsg->cmsg_len) + Marshal.SizeOf(typeof(WSACMSGHDR)); - return len > (byte*)msg.Control.buf + msg.Control.len ? null : (WSACMSGHDR*)((byte*)cmsg + WSA_CMSGHDR_ALIGN(cmsg->cmsg_len)); - } - } - - /// Returns total size of an ancillary data object given the amount of data. Used to allocate the correct amount of space. - /// The length. - /// Total size - public static SizeT WSA_CMSG_SPACE(SizeT length) => WSA_CMSGDATA_ALIGN(Marshal.SizeOf(typeof(WSACMSGHDR)) + WSA_CMSGHDR_ALIGN(length)); - - /// - /// The addrinfoex2 structure is used by the GetAddrInfoEx function to hold host address information when both a canonical name and - /// a fully qualified domain name have been requested. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-addrinfoex2w typedef struct addrinfoex2W { int ai_flags; int - // ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; PWSTR ai_canonname; struct sockaddr *ai_addr; void *ai_blob; - // size_t ai_bloblen; LPGUID ai_provider; struct addrinfoex2W *ai_next; int ai_version; PWSTR ai_fqdn; } ADDRINFOEX2W, - // *PADDRINFOEX2W, *LPADDRINFOEX2W; - [PInvokeData("ws2def.h", MSDNShortId = "9CB33347-A838-473D-B5CD-1149D6632CF2")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct ADDRINFOEX2W - { - /// - /// Flags that indicate options used in the GetAddrInfoEx function. - /// - /// Supported values for the ai_flags member are defined in the Winsock2.h include file and can be a combination of the - /// following options. - /// - /// - /// - /// Value - /// Meaning - /// - /// - /// AI_PASSIVE 0x01 - /// The socket address will be used in a call to the bindfunction. - /// - /// - /// AI_CANONNAME 0x02 - /// The canonical name is returned in the first ai_canonname member. - /// - /// - /// AI_NUMERICHOST 0x04 - /// The nodename parameter passed to the GetAddrInfoEx function must be a numeric string. - /// - /// - /// AI_ALL 0x0100 - /// - /// If this bit is set, a request is made for IPv6 addresses and IPv4 addresses with AI_V4MAPPED. This option is supported on - /// Windows Vista and later. - /// - /// - /// - /// AI_ADDRCONFIG 0x0400 - /// - /// The GetAddrInfoEx will resolve only if a global address is configured. The IPv6 and IPv4 loopback address is not considered - /// a valid global address. This option is supported on Windows Vista and later. - /// - /// - /// - /// AI_V4MAPPED 0x0800 - /// - /// If the GetAddrInfoEx request for an IPv6 addresses fails, a name service request is made for IPv4 addresses and these - /// addresses are converted to IPv4-mapped IPv6 address format. This option is supported on Windows Vista and later. - /// - /// - /// - /// AI_NON_AUTHORITATIVE 0x04000 - /// - /// The address information is from non-authoritative results. When this option is set in the pHints parameter of GetAddrInfoEx, - /// the NS_EMAIL namespace provider returns both authoritative and non-authoritative results. If this option is not set, then - /// only authoritative results are returned. This option is only supported on Windows Vista and later for the NS_EMAIL namespace. - /// - /// - /// - /// AI_SECURE 0x08000 - /// - /// The address information is from a secure channel. If the AI_SECURE bit is set, the NS_EMAIL namespace provider will return - /// results that were obtained with enhanced security to minimize possible spoofing. When this option is set in the pHints - /// parameter of GetAddrInfoEx, the NS_EMAIL namespace provider returns only results that were obtained with enhanced security - /// to minimize possible spoofing. This option is only supported on Windows Vista and later for the NS_EMAIL namespace. - /// - /// - /// - /// AI_RETURN_PREFERRED_NAMES 0x010000 - /// - /// The address information is for a preferred names for publication with a specific namespace. When this option is set in the - /// pHints parameter of GetAddrInfoEx, no name should be provided in the pName parameter and the NS_EMAIL namespace provider - /// will return preferred names for publication. This option is only supported on Windows Vista and later for the NS_EMAIL namespace. - /// - /// - /// - /// AI_FQDN 0x00020000 - /// - /// The fully qualified domain name is returned in the first ai_fqdn member. When this option is set in the pHints parameter of - /// GetAddrInfoEx and a flat name (single label) is specified in the pName parameter, the fully qualified domain name that the - /// name eventually resolved to will be returned. This option is supported on Windows 7, Windows Server 2008 R2, and later. - /// - /// - /// - /// AI_FILESERVER 0x00040000 - /// - /// A hint to the namespace provider that the hostname being queried is being used in a file share scenario. The namespace - /// provider may ignore this hint. This option is supported on Windows 7, Windows Server 2008 R2, and later. - /// - /// - /// - /// AI_DISABLE_IDN_ENCODING 0x00080000 - /// - /// Disable the automatic International Domain Name encoding using Punycode in the name resolution functions called by the - /// GetAddrInfoEx function. This option is supported on Windows 8, Windows Server 2012, and later. - /// - /// - /// - /// - public ADDRINFO_FLAGS ai_flags; - - private uint _ai_family; - - /// - /// Type: int - /// The address family. Possible values for the address family are defined in the Winsock2.h include file. - /// - /// On the Windows SDK released for Windows Vista and later,, the organization of header files has changed and the possible - /// values for the address family are defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically - /// included in Winsock2.h, and should never be used directly. - /// - /// - /// The values currently supported are AF_INET or AF_INET6, which are the Internet address family formats for IPv4 - /// and IPv6. Other options for address family ( AF_NETBIOS for use with NetBIOS, for example) are supported if a Windows - /// Sockets service provider for the address family is installed. Note that the values for the AF_ address family and PF_ - /// protocol family constants are identical (for example, AF_UNSPEC and PF_UNSPEC), so either constant can be used. - /// - /// The table below lists common values for the address family although many other values are possible. - /// - /// - /// Value - /// Meaning - /// - /// - /// AF_UNSPEC 0 - /// The address family is unspecified. - /// - /// - /// AF_INET 2 - /// The Internet Protocol version 4 (IPv4) address family. - /// - /// - /// AF_NETBIOS 17 - /// The NetBIOS address family. This address family is only supported if a Windows Sockets provider for NetBIOS is installed. - /// - /// - /// AF_INET6 23 - /// The Internet Protocol version 6 (IPv6) address family. - /// - /// - /// AF_IRDA 26 - /// - /// The Infrared Data Association (IrDA) address family. This address family is only supported if the computer has an infrared - /// port and driver installed. - /// - /// - /// - /// AF_BTH 32 - /// - /// The Bluetooth address family. This address family is only supported if a Bluetooth adapter is installed on Windows Server - /// 2003 or later. - /// - /// - /// - /// - public ADDRESS_FAMILY ai_family { get => (ADDRESS_FAMILY)_ai_family; set => _ai_family = (ushort)value; } - - /// - /// The socket type. Possible values for the socket type are defined in the Winsock2.h include file. - /// The following table lists the possible values for the socket type supported for Windows Sockets 2: - /// - /// - /// Value - /// Meaning - /// - /// - /// SOCK_STREAM 1 - /// - /// Provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. Uses the - /// Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6). If the ai_family member is - /// AF_IRDA, then SOCK_STREAM is the only supported socket type. - /// - /// - /// - /// SOCK_DGRAM 2 - /// - /// Supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. Uses the User - /// Datagram Protocol (UDP) for the Internet address family (AF_INET or AF_INET6). - /// - /// - /// - /// SOCK_RAW 3 - /// - /// Provides a raw socket that allows an application to manipulate the next upper-layer protocol header. To manipulate the IPv4 - /// header, the IP_HDRINCL socket option must be set on the socket. To manipulate the IPv6 header, the IPV6_HDRINCL socket - /// option must be set on the socket. - /// - /// - /// - /// SOCK_RDM 4 - /// - /// Provides a reliable message datagram. An example of this type is the Pragmatic General Multicast (PGM) multicast protocol - /// implementation in Windows, often referred to as reliable multicast programming. - /// - /// - /// - /// SOCK_SEQPACKET 5 - /// Provides a pseudo-stream packet based on datagrams. - /// - /// - /// - /// In Windows Sockets 2, new socket types were introduced. An application can dynamically discover the attributes of each - /// available transport protocol through the WSAEnumProtocols function. So an application can determine the possible socket type - /// and protocol options for an address family and use this information when specifying this parameter. Socket type definitions - /// in the Winsock2.h and Ws2def.h header files will be periodically updated as new socket types, address families, and - /// protocols are defined. - /// - /// In Windows Sockets 1.1, the only possible socket types are SOCK_DATAGRAM and SOCK_STREAM. - /// - public SOCK ai_socktype; - - /// - /// - /// The protocol type. The possible options are specific to the address family and socket type specified. Possible values for - /// the ai_protocol are defined in Winsock2.h and the Wsrm.h header files. - /// - /// - /// On the Windows SDK released for Windows Vista and later,, the organization of header files has changed and this member can - /// be one of the values from the IPPROTO enumeration type defined in the Ws2def.h header file. Note that the Ws2def.h - /// header file is automatically included in Winsock2.h, and should never be used directly. - /// - /// - /// If a value of 0 is specified for ai_protocol, the caller does not wish to specify a protocol and the service provider - /// will choose the ai_protocol to use. For protocols other than IPv4 and IPv6, set ai_protocol to zero. - /// - /// The following table lists common values for the ai_protocol member although many other values are possible. - /// - /// - /// Value - /// Meaning - /// - /// - /// IPPROTO_TCP 6 - /// - /// The Transmission Control Protocol (TCP). This is a possible value when the ai_family member is AF_INET or AF_INET6 and the - /// ai_socktype member is SOCK_STREAM. - /// - /// - /// - /// IPPROTO_UDP 17 - /// - /// The User Datagram Protocol (UDP). This is a possible value when the ai_family member is AF_INET or AF_INET6 and the type - /// parameter is SOCK_DGRAM. - /// - /// - /// - /// IPPROTO_RM 113 - /// - /// The PGM protocol for reliable multicast. This is a possible value when the ai_family member is AF_INET and the ai_socktype - /// member is SOCK_RDM. On the Windows SDK released for Windows Vista and later, this value is also called IPPROTO_PGM. - /// - /// - /// - /// If the ai_family member is AF_IRDA, then the ai_protocol must be 0. - /// - public IPPROTO ai_protocol; - - /// The length, in bytes, of the buffer pointed to by the ai_addr member. - public SizeT ai_addrlen; - - /// The canonical name for the host. - public StrPtrUni ai_canonname; - - /// - /// A pointer to a sockaddr structure. The ai_addr member in each returned addrinfoex2 structure points to a - /// filled-in socket address structure. The length, in bytes, of each returned addrinfoex2 structure is specified in the - /// ai_addrlen member. - /// - public IntPtr ai_addr; - - /// - /// A pointer to data that is used to return provider-specific namespace information that is associated with the name beyond a - /// list of addresses. The length, in bytes, of the buffer pointed to by ai_blob must be specified in the - /// ai_bloblen member. - /// - public IntPtr ai_blob; - - /// The length, in bytes, of the ai_blob member. - public SizeT ai_bloblen; - - /// A pointer to the GUID of a specific namespace provider. - public GuidPtr ai_provider; - - /// - /// A pointer to the next structure in a linked list. This parameter is set to NULL in the last addrinfoex2 - /// structure of a linked list. - /// - public IntPtr ai_next; - - /// The version number of this structure. The value currently used for this version of the structure is 2. - public int ai_version; - - /// The fully qualified domain name for the host. - public StrPtrUni ai_fqdn; - - /// - /// Type: struct sockaddr* - /// - /// A pointer to a sockaddr structure. The ai_addr member in each returned ADDRINFOW structure points to a filled-in - /// socket address structure. The length, in bytes, of each returned ADDRINFOW structure is specified in the - /// ai_addrlen member. - /// - /// - public SOCKADDR addr => new(ai_addr, false, ai_addrlen); - - /// - public override string ToString() => $"{ai_fqdn}::{ai_canonname}:{ai_flags},{ai_family},{ai_socktype},{ai_protocol},{addr}"; - } - - /// The addrinfoex structure is used by the GetAddrInfoEx function to hold host address information. - /// - /// - /// The addrinfoex structure is used by the GetAddrInfoEx function to hold host address information. The addrinfoex - /// structure is an enhanced version of the addrinfo and addrinfoW structures. The extra structure members are for blob data and the - /// GUID for the namespace provider. The blob data is used to return additional provider-specific namespace information associated - /// with a name. The format of data in the ai_blob member is specific to a particular namespace provider. Currently, blob - /// data is used by the NS_EMAIL namespace provider to supply additional information. - /// - /// - /// The addrinfoex structure is an enhanced version of the addrinfo and addrinfoW structure used with GetAddrInfoEx function. - /// The GetAddrInfoEx function allows specifying the namespace provider to resolve the query. For use with the IPv6 and IPv4 - /// protocol, name resolution can be by the Domain Name System (DNS), a local hosts file, an email provider (the NS_EMAIL - /// namespace), or by other naming mechanisms. - /// - /// - /// When UNICODE or _UNICODE is defined, addrinfoex is defined to addrinfoexW, the Unicode version of this structure. - /// The string parameters are defined to the PWSTR data type and the addrinfoexW structure is used. - /// - /// - /// When UNICODE or _UNICODE is not defined, addrinfoex is defined to addrinfoexA, the ANSI version of this structure. - /// The string parameters are of the PCSTR data type and the addrinfoexA structure is used. - /// - /// - /// Upon a successful call to GetAddrInfoEx, a linked list of addrinfoex structures is returned in the ppResult parameter - /// passed to the GetAddrInfoEx function. The list can be processed by following the pointer provided in the ai_next - /// member of each returned addrinfoex structure until a NULL pointer is encountered. In each returned - /// addrinfoex structure, the ai_family, ai_socktype, and ai_protocol members correspond to respective - /// arguments in a socket or WSASocket function call. Also, the ai_addr member in each returned addrinfoex structure - /// points to a filled-in socket address structure, the length of which is specified in its ai_addrlen member. - /// - /// Examples - /// The following example demonstrates the use of the addrinfoex structure. - /// - /// Note Ensure that the development environment targets the newest version of Ws2tcpip.h which includes structure and - /// function definitions for ADDRINFOEX and GetAddrInfoEx, respectively. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-addrinfoexa typedef struct addrinfoexA { int ai_flags; int - // ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; char *ai_canonname; struct sockaddr *ai_addr; void *ai_blob; - // size_t ai_bloblen; LPGUID ai_provider; struct addrinfoexA *ai_next; } ADDRINFOEXA, *PADDRINFOEXA, *LPADDRINFOEXA; - [PInvokeData("ws2def.h", MSDNShortId = "1077e03d-a1a4-45ab-a5d2-29a67e03f5df")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public unsafe struct ADDRINFOEXW - { - /// - /// Type: int - /// Flags that indicate options used in the GetAddrInfoEx function. - /// - /// Supported values for the ai_flags member are defined in the Winsock2.h include file and can be a combination of the - /// following options. - /// - /// - /// - /// Value - /// Meaning - /// - /// - /// AI_PASSIVE 0x01 - /// The socket address will be used in a call to the bindfunction. - /// - /// - /// AI_CANONNAME 0x02 - /// - /// The canonical name is returned in the first ai_canonname member. When both the AI_CANONNAME and AI_FQDN bits are set, an - /// addrinfoex2 structure is returned not the addrinfoex structure. - /// - /// - /// - /// AI_NUMERICHOST 0x04 - /// The nodename parameter passed to the GetAddrInfoEx function must be a numeric string. - /// - /// - /// AI_ALL 0x0100 - /// - /// If this bit is set, a request is made for IPv6 addresses and IPv4 addresses with AI_V4MAPPED. This option is supported on - /// Windows Vista and later. - /// - /// - /// - /// AI_ADDRCONFIG 0x0400 - /// - /// The GetAddrInfoEx will resolve only if a global address is configured. The IPv6 and IPv4 loopback address is not considered - /// a valid global address. This option is only supported on Windows Vista and later. - /// - /// - /// - /// AI_V4MAPPED 0x0800 - /// - /// If the GetAddrInfoEx request for an IPv6 addresses fails, a name service request is made for IPv4 addresses and these - /// addresses are converted to IPv4-mapped IPv6 address format. This option is supported on Windows Vista and later. - /// - /// - /// - /// AI_NON_AUTHORITATIVE 0x04000 - /// - /// The address information is from non-authoritative results. When this option is set in the pHints parameter of GetAddrInfoEx, - /// the NS_EMAIL namespace provider returns both authoritative and non-authoritative results. If this option is not set, then - /// only authoritative results are returned. In the ppResults parameter returned by GetAddrInfoEx, this flag is set in the - /// ai_flags member of the addrinfoex structure for non-authoritative results. This option is only supported on Windows Vista - /// and later for the NS_EMAIL namespace. - /// - /// - /// - /// AI_SECURE 0x08000 - /// - /// The address information is from a secure channel. If the AI_SECURE bit is set, the NS_EMAIL namespace provider will return - /// results that were obtained with enhanced security to minimize possible spoofing. When this option is set in the pHints - /// parameter of GetAddrInfoEx, the NS_EMAIL namespace provider returns only results that were obtained with enhanced security - /// to minimize possible spoofing. In the ppResults parameter returned by GetAddrInfoEx, this flag is set in the ai_flags member - /// of the addrinfoex structure for results returned with enhanced security to minimize possible spoofing. This option is only - /// supported on Windows Vista and later for the NS_EMAIL namespace. - /// - /// - /// - /// AI_RETURN_PREFERRED_NAMES 0x010000 - /// - /// The address information is for a preferred names for publication with a specific namespace. When this option is set in the - /// pHints parameter of GetAddrInfoEx, no name should be provided in the pName parameter and the NS_EMAIL namespace provider - /// will return preferred names for publication. In the ppResults parameter returned by GetAddrInfoEx, this flag is set in the - /// ai_flags member of the addrinfoex structure for results returned for preferred names for publication. This option is only - /// supported on Windows Vista and later for the NS_EMAIL namespace. - /// - /// - /// - /// AI_FQDN 0x00020000 - /// - /// The fully qualified domain name is returned in the first ai_canonicalname member. When this option is set in the pHints - /// parameter of GetAddrInfoEx and a flat name (single label) is specified in the pName parameter, the fully qualified domain - /// name that the name eventually resolved to will be returned. When both the AI_CANONNAME and AI_FQDN bits are set, an - /// addrinfoex2 structure is returned not the addrinfoex structure. This option is supported on Windows 7, Windows Server 2008 - /// R2, and later. - /// - /// - /// - /// AI_FILESERVER 0x00040000 - /// - /// A hint to the namespace provider that the hostname being queried is being used in a file share scenario. The namespace - /// provider may ignore this hint. This option is supported on Windows 7, Windows Server 2008 R2, and later. - /// - /// - /// - /// AI_DISABLE_IDN_ENCODING 0x00080000 - /// - /// Disable the automatic International Domain Name encoding using Punycode in the name resolution functions called by the - /// GetAddrInfoEx function. This option is supported on Windows 8, Windows Server 2012, and later. - /// - /// - /// - /// - public ADDRINFO_FLAGS ai_flags; - - private uint _ai_family; - - /// - /// Type: int - /// The address family. Possible values for the address family are defined in the Winsock2.h include file. - /// - /// On the Windows SDK released for Windows Vista and later,, the organization of header files has changed and the possible - /// values for the address family are defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically - /// included in Winsock2.h, and should never be used directly. - /// - /// - /// The values currently supported are AF_INET or AF_INET6, which are the Internet address family formats for IPv4 - /// and IPv6. Other options for address family ( AF_NETBIOS for use with NetBIOS, for example) are supported if a Windows - /// Sockets service provider for the address family is installed. Note that the values for the AF_ address family and PF_ - /// protocol family constants are identical (for example, AF_UNSPEC and PF_UNSPEC), so either constant can be used. - /// - /// The table below lists common values for the address family although many other values are possible. - /// - /// - /// Value - /// Meaning - /// - /// - /// AF_UNSPEC 0 - /// The address family is unspecified. - /// - /// - /// AF_INET 2 - /// The Internet Protocol version 4 (IPv4) address family. - /// - /// - /// AF_NETBIOS 17 - /// The NetBIOS address family. This address family is only supported if a Windows Sockets provider for NetBIOS is installed. - /// - /// - /// AF_INET6 23 - /// The Internet Protocol version 6 (IPv6) address family. - /// - /// - /// AF_IRDA 26 - /// - /// The Infrared Data Association (IrDA) address family. This address family is only supported if the computer has an infrared - /// port and driver installed. - /// - /// - /// - /// AF_BTH 32 - /// - /// The Bluetooth address family. This address family is only supported if a Bluetooth adapter is installed on Windows Server - /// 2003 or later. - /// - /// - /// - /// - public ADDRESS_FAMILY ai_family { get => (ADDRESS_FAMILY)_ai_family; set => _ai_family = (ushort)value; } - - /// - /// Type: int - /// The socket type. Possible values for the socket type are defined in the Winsock2.h include file. - /// The following table lists the possible values for the socket type supported for Windows Sockets 2: - /// - /// - /// Value - /// Meaning - /// - /// - /// SOCK_STREAM 1 - /// - /// Provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. Uses the - /// Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6). If the ai_family member is - /// AF_IRDA, then SOCK_STREAM is the only supported socket type. - /// - /// - /// - /// SOCK_DGRAM 2 - /// - /// Supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. Uses the User - /// Datagram Protocol (UDP) for the Internet address family (AF_INET or AF_INET6). - /// - /// - /// - /// SOCK_RAW 3 - /// - /// Provides a raw socket that allows an application to manipulate the next upper-layer protocol header. To manipulate the IPv4 - /// header, the IP_HDRINCL socket option must be set on the socket. To manipulate the IPv6 header, the IPV6_HDRINCL socket - /// option must be set on the socket. - /// - /// - /// - /// SOCK_RDM 4 - /// - /// Provides a reliable message datagram. An example of this type is the Pragmatic General Multicast (PGM) multicast protocol - /// implementation in Windows, often referred to as reliable multicast programming. - /// - /// - /// - /// SOCK_SEQPACKET 5 - /// Provides a pseudo-stream packet based on datagrams. - /// - /// - /// - /// In Windows Sockets 2, new socket types were introduced. An application can dynamically discover the attributes of each - /// available transport protocol through the WSAEnumProtocols function. So an application can determine the possible socket type - /// and protocol options for an address family and use this information when specifying this parameter. Socket type definitions - /// in the Winsock2.h and Ws2def.h header files will be periodically updated as new socket types, address families, and - /// protocols are defined. - /// - /// In Windows Sockets 1.1, the only possible socket types are SOCK_DATAGRAM and SOCK_STREAM. - /// - public SOCK ai_socktype; - - /// - /// Type: int - /// - /// The protocol type. The possible options are specific to the address family and socket type specified. Possible values for - /// the ai_protocol are defined in Winsock2.h and the Wsrm.h header files. - /// - /// - /// On the Windows SDK released for Windows Vista and later,, the organization of header files has changed and this member can - /// be one of the values from the IPPROTO enumeration type defined in the Ws2def.h header file. Note that the Ws2def.h - /// header file is automatically included in Winsock2.h, and should never be used directly. - /// - /// - /// If a value of 0 is specified for ai_protocol, the caller does not wish to specify a protocol and the service provider - /// will choose the ai_protocol to use. For protocols other than IPv4 and IPv6, set ai_protocol to zero. - /// - /// The following table lists common values for the ai_protocol member although many other values are possible. - /// - /// - /// Value - /// Meaning - /// - /// - /// IPPROTO_TCP 6 - /// - /// The Transmission Control Protocol (TCP). This is a possible value when the ai_family member is AF_INET or AF_INET6 and the - /// ai_socktype member is SOCK_STREAM. - /// - /// - /// - /// IPPROTO_UDP 17 - /// - /// The User Datagram Protocol (UDP). This is a possible value when the ai_family member is AF_INET or AF_INET6 and the type - /// parameter is SOCK_DGRAM. - /// - /// - /// - /// IPPROTO_RM 113 - /// - /// The PGM protocol for reliable multicast. This is a possible value when the ai_family member is AF_INET and the ai_socktype - /// member is SOCK_RDM. On the Windows SDK released for Windows Vista and later, this value is also called IPPROTO_PGM. - /// - /// - /// - /// If the ai_family member is AF_IRDA, then the ai_protocol must be 0. - /// - public IPPROTO ai_protocol; - - /// - /// Type: size_t - /// The length, in bytes, of the buffer pointed to by the ai_addr member. - /// - public SizeT ai_addrlen; - - /// - /// Type: PCTSTR - /// The canonical name for the host. - /// - public StrPtrUni ai_canonname; - - /// - /// Type: struct sockaddr* - /// - /// A pointer to a sockaddr structure. The ai_addr member in each returned addrinfoex structure points to a - /// filled-in socket address structure. The length, in bytes, of each returned addrinfoex structure is specified in the - /// ai_addrlen member. - /// - /// - public IntPtr ai_addr; - - /// - /// Type: void* - /// - /// A pointer to data that is used to return provider-specific namespace information that is associated with the name beyond a - /// list of addresses. The length, in bytes, of the buffer pointed to by ai_blob must be specified in the - /// ai_bloblen member. - /// - /// - public IntPtr ai_blob; - - /// - /// Type: size_t - /// The length, in bytes, of the ai_blob member. - /// - public SizeT ai_bloblen; - - /// - /// Type: LPGUID - /// A pointer to the GUID of a specific namespace provider. - /// - public Guid* ai_provider; - - /// - /// Type: struct addrinfoex* - /// - /// A pointer to the next structure in a linked list. This parameter is set to NULL in the last addrinfoex - /// structure of a linked list. - /// - /// - public IntPtr ai_next; - - /// - /// Type: struct sockaddr* - /// - /// A pointer to a sockaddr structure. The ai_addr member in each returned ADDRINFOW structure points to a filled-in - /// socket address structure. The length, in bytes, of each returned ADDRINFOW structure is specified in the - /// ai_addrlen member. - /// - /// - public SOCKADDR addr => new(ai_addr, false, ai_addrlen); - - /// - public override string ToString() => $"{ai_canonname}:{ai_flags},{ai_family},{ai_socktype},{ai_protocol},{addr}"; - } - - /// - /// The addrinfoex2 structure is used by the GetAddrInfoEx function to hold host address information when both a canonical - /// name and a fully qualified domain name have been requested. - /// - /// - /// The addrinfoex2 structure is supported on Windows 8 and Windows Server 2012 - /// - /// The addrinfoex2 structure is used by the GetAddrInfoEx function to hold host address information when both the - /// AI_FQDN and AI_CANONNAME bits are set in the ai_flags member of the optional addrinfoex structure provided - /// in the hints parameter to the GetAddrInfoEx function. The addrinfoex2 structure is an enhanced version of the - /// addrinfoex structure that can return both the canonical name and the fully qualified domain name for the host. The extra - /// structure members are for a version number of the structure and the fully qualified domain name for the host. - /// - /// - /// The addrinfoex2 structure used with GetAddrInfoEx function is an enhanced version of the addrinfo and addrinfoW - /// structures used with the getaddrinfo and GetAddrInfoW functions. The GetAddrInfoEx function allows specifying the - /// namespace provider to resolve the query. For use with the IPv6 and IPv4 protocol, name resolution can be by the Domain Name - /// System (DNS), a local hosts file, an email provider (the NS_EMAIL namespace), or by other naming mechanisms. - /// - /// - /// The blob data in tha ai_blob member is used to return additional provider-specific namespace information associated with - /// a name. The format of data in the ai_blob member is specific to a particular namespace provider. Currently, blob data is - /// used by the NS_EMAIL namespace provider to supply additional information. - /// - /// - /// When UNICODE or _UNICODE is defined, addrinfoex2 is defined to addrinfoex2W, the Unicode version of this - /// structure. The string parameters are defined to the PWSTR data type and the addrinfoex2W structure is used. - /// - /// - /// When UNICODE or _UNICODE is not defined, addrinfoex2 is defined to addrinfoex2A, the ANSI version of this - /// structure. The string parameters are of the char * data type and the addrinfoex2A structure is used. - /// - /// - /// Upon a successful call to GetAddrInfoEx, a linked list of addrinfoex2 structures is returned in the ppResult parameter - /// passed to the GetAddrInfoEx function. The list can be processed by following the pointer provided in the ai_next - /// member of each returned addrinfoex2 structure until a NULL pointer is encountered. In each returned - /// addrinfoex2 structure, the ai_family, ai_socktype, and ai_protocol members correspond to respective - /// arguments in a socket or WSASocket function call. Also, the ai_addr member in each returned addrinfoex2 structure - /// points to a filled-in socket address structure, the length of which is specified in its ai_addrlen member. - /// - /// - /// The addrinfo structure is used by the getaddrinfo function to hold host address information. - /// - /// The addrinfo structure is used by the ANSI getaddrinfo function to hold host address information. - /// The addrinfoW structure is the version of this structure used by the Unicode GetAddrInfoW function. - /// - /// Macros in the Ws2tcpip.h header file define a ADDRINFOT structure and a mixed-case function name of GetAddrInfo. - /// The GetAddrInfo function should be called with the nodename and servname parameters of a pointer of type TCHAR and - /// the hints and res parameters of a pointer of type ADDRINFOT. When UNICODE or _UNICODE is not defined, ADDRINFOT is - /// defined to the addrinfo structure and GetAddrInfo is defined to getaddrinfo, the ANSI version of this function. - /// When UNICODE or _UNICODE is defined, ADDRINFOT is defined to the addrinfoW structure and GetAddrInfo is defined to - /// GetAddrInfoW, the Unicode version of this function. - /// - /// - /// Upon a successful call to getaddrinfo, a linked list of addrinfo structures is returned in the res parameter passed to - /// the getaddrinfo function. The list can be processed by following the pointer provided in the ai_next member of - /// each returned addrinfo structure until a NULL pointer is encountered. In each returned addrinfo structure, - /// the ai_family, ai_socktype, and ai_protocol members correspond to respective arguments in a socket or - /// WSASocket function call. Also, the ai_addr member in each returned addrinfo structure points to a filled-in socket - /// address structure, the length of which is specified in its ai_addrlen member. - /// - /// Support for getaddrinfo and the addrinfo struct on older versions of Windows - /// - /// The getaddrinfo function that uses the addrinfo structure was added to the Ws2_32.dll on Windows XP and later. The - /// addrinfo structure is defined in the Ws2tcpip.h header file included with the Platform SDK released for Windows XP and - /// later and the Windows SDK released for Windows Vista and later. - /// - /// - /// To execute an application that uses the getaddrinfo function and the addrinfo structure on earlier versions of Windows - /// (Windows 2000), then you need to include the Ws2tcpip.h and Wspiapi.h files. When the Wspiapi.h include file is added, the - /// getaddrinfo function is defined to the WspiapiGetAddrInfo inline function in the Wspiapi.h file. At runtime, the - /// WspiapiGetAddrInfo function is implemented in such a way that if the Ws2_32.dll or the Wship6.dll (the file containing - /// getaddrinfo in the IPv6 Technology Preview for Windows 2000) does not include getaddrinfo, then a version of - /// getaddrinfo is implemented inline based on code in the Wspiapi.h header file. This inline code will be used on older - /// Windows platforms that do not natively support the getaddrinfo function. - /// - /// - /// The IPv6 protocol is supported on Windows 2000 when the IPv6 Technology Preview for Windows 2000 is installed. Otherwise - /// getaddrinfo support on versions of Windows earlier than Windows XP is limited to handling IPv4 name resolution. - /// - /// - /// The GetAddrInfoW function that uses the addrinfoW structure is the Unicode version of the getaddrinfo function and associated - /// addrinfo structure. The GetAddrInfoW function was added to the Ws2_32.dll in Windows XP with Service Pack 2 (SP2). - /// The GetAddrInfoW function and the addrinfoW structure cannot be used on versions of Windows earlier than Windows - /// XP with SP2. - /// - /// Examples - /// The following code example shows the use of the addrinfo structure. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-addrinfoa typedef struct addrinfo { int ai_flags; int - // ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; char *ai_canonname; struct sockaddr *ai_addr; struct addrinfo - // *ai_next; } ADDRINFOA, *PADDRINFOA; - [PInvokeData("ws2def.h", MSDNShortId = "4df914ab-59b0-4110-bc81-59e5f6722b8d")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] - public struct ADDRINFOW - { - /// - /// Type: int - /// Flags that indicate options used in the getaddrinfo function. - /// - /// Supported values for the ai_flags member are defined in the Ws2def.h header file on the Windows SDK for Windows 7 and - /// later. These values are defined in the Ws2tcpip.h header file on the Windows SDK for Windows Server 2008 and Windows Vista. - /// These values are defined in the Ws2tcpip.h header file on the Platform SDK for Windows Server 2003, and Windows XP. - /// Supported values for the ai_flags member can be a combination of the following options. - /// - /// - /// - /// Value - /// Meaning - /// - /// - /// AI_PASSIVE 0x01 - /// The socket address will be used in a call to the bindfunction. - /// - /// - /// AI_CANONNAME 0x02 - /// The canonical name is returned in the first ai_canonname member. - /// - /// - /// AI_NUMERICHOST 0x04 - /// The nodename parameter passed to the getaddrinfo function must be a numeric string. - /// - /// - /// AI_ALL 0x0100 - /// - /// If this bit is set, a request is made for IPv6 addresses and IPv4 addresses with AI_V4MAPPED. This option is supported on - /// Windows Vista and later. - /// - /// - /// - /// AI_ADDRCONFIG 0x0400 - /// - /// The getaddrinfo will resolve only if a global address is configured. The IPv6 and IPv4 loopback address is not considered a - /// valid global address. This option is supported on Windows Vista and later. - /// - /// - /// - /// AI_V4MAPPED 0x0800 - /// - /// If the getaddrinfo request for IPv6 addresses fails, a name service request is made for IPv4 addresses and these addresses - /// are converted to IPv4-mapped IPv6 address format. This option is supported on Windows Vista and later. - /// - /// - /// - /// AI_NON_AUTHORITATIVE 0x04000 - /// - /// The address information can be from a non-authoritative namespace provider. This option is only supported on Windows Vista - /// and later for the NS_EMAIL namespace. - /// - /// - /// - /// AI_SECURE 0x08000 - /// - /// The address information is from a secure channel. This option is only supported on Windows Vista and later for the NS_EMAIL namespace. - /// - /// - /// - /// AI_RETURN_PREFERRED_NAMES 0x010000 - /// - /// The address information is for a preferred name for a user. This option is only supported on Windows Vista and later for the - /// NS_EMAIL namespace. - /// - /// - /// - /// AI_FQDN 0x00020000 - /// - /// If a flat name (single label) is specified, getaddrinfo will return the fully qualified domain name that the name eventually - /// resolved to. The fully qualified domain name is returned in the ai_canonname member. This is different than AI_CANONNAME bit - /// flag that returns the canonical name registered in DNS which may be different than the fully qualified domain name that the - /// flat name resolved to. Only one of the AI_FQDN and AI_CANONNAME bits can be set. The getaddrinfo function will fail if both - /// flags are present with EAI_BADFLAGS. This option is supported on Windows 7, Windows Server 2008 R2, and later. - /// - /// - /// - /// AI_FILESERVER 0x00040000 - /// - /// A hint to the namespace provider that the hostname being queried is being used in a file share scenario. The namespace - /// provider may ignore this hint. This option is supported on Windows 7, Windows Server 2008 R2, and later. - /// - /// - /// - /// - public ADDRINFO_FLAGS ai_flags; - - private uint _ai_family; - - /// - /// Type: int - /// The address family. Possible values for the address family are defined in the Winsock2.h include file. - /// - /// On the Windows SDK released for Windows Vista and later,, the organization of header files has changed and the possible - /// values for the address family are defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically - /// included in Winsock2.h, and should never be used directly. - /// - /// - /// The values currently supported are AF_INET or AF_INET6, which are the Internet address family formats for IPv4 - /// and IPv6. Other options for address family ( AF_NETBIOS for use with NetBIOS, for example) are supported if a Windows - /// Sockets service provider for the address family is installed. Note that the values for the AF_ address family and PF_ - /// protocol family constants are identical (for example, AF_UNSPEC and PF_UNSPEC), so either constant can be used. - /// - /// The table below lists common values for the address family although many other values are possible. - /// - /// - /// Value - /// Meaning - /// - /// - /// AF_UNSPEC 0 - /// The address family is unspecified. - /// - /// - /// AF_INET 2 - /// The Internet Protocol version 4 (IPv4) address family. - /// - /// - /// AF_NETBIOS 17 - /// The NetBIOS address family. This address family is only supported if a Windows Sockets provider for NetBIOS is installed. - /// - /// - /// AF_INET6 23 - /// The Internet Protocol version 6 (IPv6) address family. - /// - /// - /// AF_IRDA 26 - /// - /// The Infrared Data Association (IrDA) address family. This address family is only supported if the computer has an infrared - /// port and driver installed. - /// - /// - /// - /// AF_BTH 32 - /// - /// The Bluetooth address family. This address family is only supported if a Bluetooth adapter is installed on Windows Server - /// 2003 or later. - /// - /// - /// - /// - public ADDRESS_FAMILY ai_family { get => (ADDRESS_FAMILY)_ai_family; set => _ai_family = (ushort)value; } - - /// - /// Type: int - /// The socket type. Possible values for the socket type are defined in the Winsock2.h header file. - /// The following table lists the possible values for the socket type supported for Windows Sockets 2: - /// - /// - /// Value - /// Meaning - /// - /// - /// SOCK_STREAM 1 - /// - /// Provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. Uses the - /// Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6). If the ai_family member is - /// AF_IRDA, then SOCK_STREAM is the only supported socket type. - /// - /// - /// - /// SOCK_DGRAM 2 - /// - /// Supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. Uses the User - /// Datagram Protocol (UDP) for the Internet address family (AF_INET or AF_INET6). - /// - /// - /// - /// SOCK_RAW 3 - /// - /// Provides a raw socket that allows an application to manipulate the next upper-layer protocol header. To manipulate the IPv4 - /// header, the IP_HDRINCL socket option must be set on the socket. To manipulate the IPv6 header, the IPV6_HDRINCL socket - /// option must be set on the socket. - /// - /// - /// - /// SOCK_RDM 4 - /// - /// Provides a reliable message datagram. An example of this type is the Pragmatic General Multicast (PGM) multicast protocol - /// implementation in Windows, often referred to as reliable multicast programming. - /// - /// - /// - /// SOCK_SEQPACKET 5 - /// Provides a pseudo-stream packet based on datagrams. - /// - /// - /// - /// In Windows Sockets 2, new socket types were introduced. An application can dynamically discover the attributes of each - /// available transport protocol through the WSAEnumProtocols function. So an application can determine the possible socket type - /// and protocol options for an address family and use this information when specifying this parameter. Socket type definitions - /// in the Winsock2.h and Ws2def.h header files will be periodically updated as new socket types, address families, and - /// protocols are defined. - /// - /// In Windows Sockets 1.1, the only possible socket types are SOCK_DATAGRAM and SOCK_STREAM. - /// - public SOCK ai_socktype; - - /// - /// Type: int - /// - /// The protocol type. The possible options are specific to the address family and socket type specified. Possible values for - /// the ai_protocol are defined in the Winsock2.h and Wsrm.h header files. - /// - /// - /// On the Windows SDK released for Windows Vista and later, the organization of header files has changed and this member can be - /// one of the values from the IPPROTO enumeration type defined in the Ws2def.h header file. Note that the Ws2def.h - /// header file is automatically included in Winsock2.h, and should never be used directly. - /// - /// - /// If a value of 0 is specified for ai_protocol, the caller does not wish to specify a protocol and the service provider - /// will choose the ai_protocol to use. For protocols other than IPv4 and IPv6, set ai_protocol to zero. - /// - /// The following table lists common values for the ai_protocol member although many other values are possible. - /// - /// - /// Value - /// Meaning - /// - /// - /// IPPROTO_TCP 6 - /// - /// The Transmission Control Protocol (TCP). This is a possible value when the ai_family member is AF_INET or AF_INET6 and the - /// ai_socktype member is SOCK_STREAM. - /// - /// - /// - /// IPPROTO_UDP 17 - /// - /// The User Datagram Protocol (UDP). This is a possible value when the ai_family member is AF_INET or AF_INET6 and the type - /// parameter is SOCK_DGRAM. - /// - /// - /// - /// IPPROTO_RM 113 - /// - /// The PGM protocol for reliable multicast. This is a possible value when the ai_family member is AF_INET and the ai_socktype - /// member is SOCK_RDM. On the Windows SDK released for Windows Vista and later, this value is also called IPPROTO_PGM. - /// - /// - /// - /// If the ai_family member is AF_IRDA, then the ai_protocol must be 0. - /// - public IPPROTO ai_protocol; - - /// - /// Type: size_t - /// The length, in bytes, of the buffer pointed to by the ai_addr member. - /// - public SizeT ai_addrlen; - - /// - /// Type: char* - /// The canonical name for the host. - /// - public StrPtrUni ai_canonname; - - /// - /// Type: struct sockaddr* - /// - /// A pointer to a sockaddr structure. The ai_addr member in each returned addrinfo structure points to a - /// filled-in socket address structure. The length, in bytes, of each returned addrinfo structure is specified in the - /// ai_addrlen member. - /// - /// - public IntPtr ai_addr; - - /// - /// Type: struct addrinfo* - /// - /// A pointer to the next structure in a linked list. This parameter is set to NULL in the last addrinfo structure - /// of a linked list. - /// - /// - public IntPtr ai_next; - - /// - /// Type: struct sockaddr* - /// - /// A pointer to a sockaddr structure. The ai_addr member in each returned ADDRINFOW structure points to a filled-in - /// socket address structure. The length, in bytes, of each returned ADDRINFOW structure is specified in the - /// ai_addrlen member. - /// - /// - public SOCKADDR addr => new(ai_addr, false, ai_addrlen); - - /// - public override string ToString() => $"{ai_canonname}:{ai_flags},{ai_family},{ai_socktype},{ai_protocol},{addr}"; - } - - /// The scope identifier for the IPv6 transport address. - [PInvokeData("ws2def.h")] - [StructLayout(LayoutKind.Sequential)] - public struct SCOPE_ID - { - /// A ULONG representation of the IPv6 scope identifier. - public uint Value; - - /// - /// - /// The zone index that identifies the zone to which the transport address pertains. Zones of the different scopes are - /// instantiated as follows: - /// - /// - /// Each interface on a node comprises a single zone of interface-local scope. - /// Each link, and the interfaces attached to that link, comprise a single zone of link-local scope. - /// There is a single zone of global scope that comprises all of the links and interfaces in the Internet. - /// The boundaries of zones of scope other than interface-local, link-local, and global are defined by network administrators. - /// - /// A value of zero specifies the default zone. - /// - /// The zone index. - public uint Zone - { - get => BitHelper.GetBits(Value, 0, 28); - set => BitHelper.SetBits(ref Value, 0, 28, value); - } - - /// - /// - /// The scope of the IPv6 transport address. This scope must be the same as the IPv6 scope value that is embedded in the IPv6 - /// transport address. This member can be one of the following: - /// - /// ScopeLevelInterface - /// The transport address has interface-local scope. - /// ScopeLevelLink - /// The transport address has link-local scope. - /// ScopeLevelSubnet - /// The transport address has subnet-local scope. - /// ScopeLevelAdmin - /// The transport address has admin-local scope. - /// ScopeLevelSite - /// The transport address has site-local scope. - /// ScopeLevelOrganization - /// The transport address has organization-local scope. - /// ScopeLevelGlobal - /// The transport address has global scope. - /// - /// The level. - public byte Level - { - get => (byte)BitHelper.GetBits(Value, 28, 4); - set => BitHelper.SetBits(ref Value, 28, 4, value); - } - } - - /// The SOCKADDR_IN structure specifies a transport address and port for the AF_INET address family. - /// - /// All of the data in the SOCKADDR_IN structure, except for the address family, must be specified in network-byte-order (big-endian). - /// - // https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-sockaddr_in typedef struct sockaddr_in { #if ... short - // sin_family; #else ADDRESS_FAMILY sin_family; #endif USHORT sin_port; IN_ADDR sin_addr; CHAR sin_zero[8]; } SOCKADDR_IN, *PSOCKADDR_IN; - [PInvokeData("ws2def.h", MSDNShortId = "96379562-403f-451c-ac7a-f0eec34bfe5e")] - [StructLayout(LayoutKind.Sequential, Pack = 2)] - public struct SOCKADDR_IN - { - /// The address family for the transport address. This member should always be set to AF_INET. - public ADDRESS_FAMILY sin_family; - - /// A transport protocol port number. - public ushort sin_port; - - /// An IN_ADDR structure that contains an IPv4 transport address. - public IN_ADDR sin_addr; - - /// Reserved for system use. A WSK application should set the contents of this array to zero. - public ulong sin_zero; - - /// Initializes a new instance of the struct. - /// An IN_ADDR structure that contains an IPv4 transport address. - /// A transport protocol port number. - public SOCKADDR_IN(IN_ADDR addr, ushort port = 0) - { - sin_family = ADDRESS_FAMILY.AF_INET; - sin_port = port; - sin_addr = addr; - sin_zero = 0; - } - - /// Performs an implicit conversion from to . - /// The addr. - /// The resulting instance from the conversion. - public static implicit operator SOCKADDR_IN(IN_ADDR addr) => new(addr); - - /// Performs an explicit conversion from to . - /// The ipv4 address. - /// The resulting instance from the conversion. - public static explicit operator SOCKADDR_IN6(SOCKADDR_IN ipv4) => new(ipv4); - - /// Converts to string. - /// A that represents this instance. - public override string ToString() => $"{sin_addr}:{sin_port}"; - } - - /// The SOCKADDR_STORAGE structure is a generic structure that specifies a transport address. - /// - /// A WSK application typically does not directly access any of the members of the SOCKADDR_STORAGE structure except for the - /// ss_family member. Instead, a pointer to a SOCKADDR_STORAGE structure is normally cast to a pointer to the specific - /// SOCKADDR structure type that corresponds to a particular address family. - /// - // https://docs.microsoft.com/ja-jp/windows/desktop/api/ws2def/ns-ws2def-sockaddr_storage_lh typedef struct sockaddr_storage { - // ADDRESS_FAMILY ss_family; CHAR __ss_pad1[_SS_PAD1SIZE]; __int64 __ss_align; CHAR __ss_pad2[_SS_PAD2SIZE]; } SOCKADDR_STORAGE_LH, - // *PSOCKADDR_STORAGE_LH, *LPSOCKADDR_STORAGE_LH; - [PInvokeData("ws2def.h", MSDNShortId = "27e56c1a-ce11-4cdb-9be8-25ed2f94fb37")] - [StructLayout(LayoutKind.Sequential, Pack = 8)] - public struct SOCKADDR_STORAGE - { - /// - /// The address family for the transport address. For more information about supported address families, see WSK Address Families. - /// - public ADDRESS_FAMILY ss_family; - - /// A padding of 6 bytes that puts the __ss_align member on an eight-byte boundary within the structure. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] - public byte[] __ss_pad1; - - /// A 64-bit value that forces the structure to be 8-byte aligned. - public long __ss_align; - - /// A padding of an additional 112 bytes that brings the total size of the SOCKADDR_STORAGE structure to 128 bytes. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 112)] - public byte[] __ss_pad2; - - /// Performs an explicit conversion from to . - /// The address. - /// The resulting instance from the conversion. - public static explicit operator SOCKADDR_STORAGE(in SOCKADDR_IN6 addr) - { - using var mem = SafeHGlobalHandle.CreateFromStructure(addr); - mem.Size = Marshal.SizeOf(typeof(SOCKADDR_STORAGE)); - return mem.ToStructure(); - } - - /// Performs an explicit conversion from to . - /// The address. - /// The resulting instance from the conversion. - public static explicit operator SOCKADDR_STORAGE(in SOCKADDR_IN addr) - { - using var mem = SafeHGlobalHandle.CreateFromStructure(addr); - mem.Size = Marshal.SizeOf(typeof(SOCKADDR_STORAGE)); - return mem.ToStructure(); - } - - /// Performs an explicit conversion from to . - /// The address. - /// The resulting instance from the conversion. - public static explicit operator SOCKADDR_STORAGE(SOCKADDR addr) - { - using var mem = new SafeHGlobalHandle(addr.GetAddressBytes()); - mem.Size = Marshal.SizeOf(typeof(SOCKADDR_STORAGE)); - return mem.ToStructure(); - } - - /// Performs an explicit conversion from to . - /// The address. - /// The resulting instance from the conversion. - public static explicit operator SOCKADDR_STORAGE(IPAddress addr) - { - using var mem = new SafeHGlobalHandle(addr.GetAddressBytes()); - mem.Size = Marshal.SizeOf(typeof(SOCKADDR_STORAGE)); - return mem.ToStructure(); - } - - /// Performs an explicit conversion from to . - /// The address. - /// The resulting instance from the conversion. - public static explicit operator SOCKADDR_STORAGE(SOCKADDR_INET addr) - { - using var mem = SafeHGlobalHandle.CreateFromStructure(addr); - mem.Size = Marshal.SizeOf(typeof(SOCKADDR_STORAGE)); - return mem.ToStructure(); - } - - /// Performs an explicit conversion from to . - /// The addr. - /// The resulting instance from the conversion. - public static explicit operator SOCKADDR(SOCKADDR_STORAGE addr) => SOCKADDR.CreateFromStructure(addr); - - /// Performs an explicit conversion from to . - /// The addr. - /// The resulting instance from the conversion. - public static explicit operator SOCKADDR_IN(SOCKADDR_STORAGE addr) => (SOCKADDR_IN)SOCKADDR.CreateFromStructure(addr); - - /// Performs an explicit conversion from to . - /// The addr. - /// The resulting instance from the conversion. - public static explicit operator SOCKADDR_IN6(SOCKADDR_STORAGE addr) => (SOCKADDR_IN6)SOCKADDR.CreateFromStructure(addr); - - /// Performs an explicit conversion from to . - /// The addr. - /// The resulting instance from the conversion. - public static explicit operator SOCKADDR_INET(SOCKADDR_STORAGE addr) => (SOCKADDR_INET)SOCKADDR.CreateFromStructure(addr); - } - - /// The SOCKET_ADDRESS structure stores protocol-specific address information. - /// - /// - /// The SOCKADDR structure pointed to by the lpSockaddr member varies depending on the protocol or address family selected. - /// For example, the sockaddr_in6 structure is used for an IPv6 socket address while the sockaddr_in4 structure is - /// used for an IPv4 socket address. The address family is the first member of all of the SOCKADDR structures. The address - /// family is used to determine which structure is used. - /// - /// - /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files - /// has changed and the SOCKET_ADDRESS structure is defined in the Ws2def.h header file. Note that the Ws2def.h header file - /// is automatically included in Winsock2.h, and should never be used directly. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-socket_address typedef struct _SOCKET_ADDRESS { LPSOCKADDR - // lpSockaddr; INT iSockaddrLength; } SOCKET_ADDRESS, *PSOCKET_ADDRESS, *LPSOCKET_ADDRESS; - [PInvokeData("ws2def.h", MSDNShortId = "37fbcb96-a859-4eca-8928-8051f95407b9")] - [StructLayout(LayoutKind.Sequential, -#if x64 - Size = 16)] -#else - Size = 8)] -#endif - public struct SOCKET_ADDRESS - { - /// A pointer to a socket address represented as a SOCKADDR structure. - public IntPtr lpSockaddr; - - /// The length, in bytes, of the socket address. - public int iSockaddrLength; - - /// Gets the from this instance. - /// The value pointed to by this instance. - public SOCKADDR_INET GetSOCKADDR() => lpSockaddr.ToStructure(iSockaddrLength); - - /// Performs an implicit conversion from to . - /// The address. - /// The result of the conversion. - public static implicit operator SOCKADDR(SOCKET_ADDRESS address) => new(address); - - /// Converts to string. - /// A that represents this instance. - public override string ToString() => GetSOCKADDR().ToString(); - } - - /// The SOCKET_ADDRESS_LIST structure defines a variable-sized list of transport addresses. - /// - /// - /// A WSK application passes a buffer to the WskControlSocket function when the WSK application queries the current list of local - /// transport addresses that match a socket's address family. If the call to the WskControlSocket function succeeds, the - /// buffer contains a SOCKET_ADDRESS_LIST structure followed by the SOCKADDR structures for each of the local transport addresses - /// that match the socket's address family. The WSK subsystem fills in the Address array and sets the iAddressCount - /// member to the number of entries in the array. The lpSockaddr pointers in each of the SOCKET_ADDRESS structures in the - /// array point to the specific SOCKADDR structure type that corresponds to the address family that the WSK application specified - /// when it created the socket. - /// - /// For more information about querying the current list of local transport addresses, see SIO_ADDRESS_LIST_QUERY. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-socket_address_list typedef struct _SOCKET_ADDRESS_LIST { INT - // iAddressCount; SOCKET_ADDRESS Address[1]; } SOCKET_ADDRESS_LIST, *PSOCKET_ADDRESS_LIST, *LPSOCKET_ADDRESS_LIST; - [PInvokeData("ws2def.h", MSDNShortId = "b005200b-b0c2-4f19-8765-cd26fbfc0cff")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(iAddressCount))] - [StructLayout(LayoutKind.Sequential)] - public struct SOCKET_ADDRESS_LIST - { - /// The number of transport addresses in the list. - public int iAddressCount; - - /// A variable-sized array of SOCKET_ADDRESS structures. The SOCKET_ADDRESS structure is defined as follows: - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public SOCKET_ADDRESS[] Address; - - /// Packs this instance into a single memory block so that it can be passed as a pointer to other API methods. - /// - /// A instance that contains this structure and all memeroy assigned to its elements. - /// - public SafeCoTaskMemStruct Pack() - { - var addrOffset = Marshal.OffsetOf(typeof(SOCKET_ADDRESS_LIST), "Address").ToInt32(); - var eosOffset = addrOffset + iAddressCount * Marshal.SizeOf(typeof(SOCKET_ADDRESS)); - var cbAddressList = eosOffset + Address.Sum(a => a.iSockaddrLength); - - var addressList = new SafeCoTaskMemStruct(cbAddressList); - ((IntPtr)addressList).Write(iAddressCount); - var newAddr = new SOCKET_ADDRESS[iAddressCount]; - var ptr = ((IntPtr)addressList).Offset(eosOffset); - for (int i = 0; i < iAddressCount; i++) - { - newAddr[i] = new SOCKET_ADDRESS { iSockaddrLength = Address[i].iSockaddrLength, lpSockaddr = ptr }; - Address[i].lpSockaddr.CopyTo(ptr, Address[i].iSockaddrLength); - ptr = ptr.Offset(Address[i].iSockaddrLength); - } - ((IntPtr)addressList).Write(newAddr, addrOffset); - return addressList; - } - } - - /// - /// The SOCKET_PROCESSOR_AFFINITY structure contains the association between a socket and an RSS processor core and NUMA node.. - /// - /// - /// - /// The SOCKET_PROCESSOR_AFFINITY structure is supported on Windows 8, and Windows Server 2012, and later versions of the - /// operating system. - /// - /// - /// The SIO_QUERY_RSS_PROCESSOR_INFO IOCTL is used to determine the association between a socket and an RSS processor core and NUMA - /// node. This IOCTL returns a SOCKET_PROCESSOR_AFFINITY structure that contains the processor number and the NUMA node ID. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-socket_processor_affinity typedef struct - // _SOCKET_PROCESSOR_AFFINITY { PROCESSOR_NUMBER Processor; USHORT NumaNodeId; USHORT Reserved; } SOCKET_PROCESSOR_AFFINITY, *PSOCKET_PROCESSOR_AFFINITY; - [PInvokeData("ws2def.h", MSDNShortId = "CB1E9F79-C6BD-40C2-8D0F-36B24B1BBBF4")] - [StructLayout(LayoutKind.Sequential)] - public struct SOCKET_PROCESSOR_AFFINITY - { - /// - /// A structure to represent a system wide processor number. This PROCESSOR_NUMBER structure contains a group number and - /// relative processor number within the group. - /// - public Kernel32.PROCESSOR_NUMBER Processor; - - /// The NUMA node ID. - public ushort NumaNodeId; - - /// A value reserved for future use. - public ushort Reserved; - } - - /// The WSABUF structure enables the creation or manipulation of a data buffer used by some Winsock functions. - // https://docs.microsoft.com/en-us/windows/desktop/api/ws2def/ns-ws2def-_wsabuf typedef struct _WSABUF { ULONG len; CHAR *buf; } - // WSABUF, *LPWSABUF; - [PInvokeData("ws2def.h", MSDNShortId = "a012c3ba-67fd-4fcf-84d1-85e9d495c29c")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] - public struct WSABUF - { - /// The length of the buffer, in bytes. - public uint len; - - /// A pointer to the buffer. - public IntPtr buf; - } - - /// The CMSGHDR structure defines the header for a control data object that is associated with a datagram. - /// - /// The control information data that is associated with a datagram is made up of one or more control data objects. Each object - /// begins with a CMSGHDR structure. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-wsacmsghdr typedef struct _WSACMSGHDR { SIZE_T cmsg_len; INT - // cmsg_level; INT cmsg_type; } WSACMSGHDR, *PWSACMSGHDR, *LPWSACMSGHDR; - [PInvokeData("ws2def.h", MSDNShortId = "NS:ws2def._WSACMSGHDR")] - [StructLayout(LayoutKind.Sequential)] - public struct WSACMSGHDR - { - /// - /// The number of bytes from the beginning of the CMSGHDR structure to the end of the control data. - /// Note The value of the cmsg_len member does not account for any padding that may follow the control data. - /// - public SizeT cmsg_len; - - /// The protocol that originated the control information. - public int cmsg_level; - - /// The protocol-specific type of control information. - public int cmsg_type; - } - - /// - /// The WSAMSG structure is used with the WSARecvMsg and WSASendMsg functions to store address and optional control - /// information about connected and unconnected sockets as well as an array of buffers used to store message data. - /// - /// - /// - /// In the Microsoft Windows Software Development Kit (SDK), the version of this structure for use on Windows Vistais defined with - /// the data type for the dwBufferCount and dwFlags members as a ULONG. When compiling an application if the - /// target platform is Windows Vista and later ( NTDDI_VERSION >= NTDDI_LONGHORN, _WIN32_WINNT >= 0x0600, or WINVER - /// >= 0x0600), the data type for the dwBufferCount and dwFlags members is a ULONG. - /// - /// - /// Windows Server 2003 and Windows XP: When compiling an application, the data type for the dwBufferCount and - /// dwFlags members is a DWORD. - /// - /// - /// On the Windows SDK released for Windows Vista and later, the WSAMSG structure is defined in the Ws2def.h header file. - /// Note that the Ws2def.h header file is automatically included in Winsock2.h, and should never be used directly - /// - /// - /// If the datagram or control data is truncated during the transmission, the function being used in association with the - /// WSAMSG structure returns SOCKET_ERROR and a call to the WSAGetLastError function returns WSAEMSGSIZE. It is up to the - /// application to determine what was truncated by checking for MSG_TRUNC and/or MSG_CTRUNC flags. - /// - /// Use of the Control Member - /// - /// The following table summarizes the various uses of control data available for use in the Control member for IPv4 and IPv6. - /// - /// - /// - /// Protocol - /// cmsg_level - /// cmsg_type - /// Description - /// - /// - /// IPv4 - /// IPPROTO_IP - /// IP_ORIGINAL_ARRIVAL_IF - /// - /// Receives the original IPv4 arrival interface where the packet was received for datagram sockets. This control data is used by - /// firewalls when a Teredo, 6to4, or ISATAP tunnel is used for IPv4 NAT traversal. The cmsg_data[] member in the WSAMSG structure - /// is a ULONG that contains the IF_INDEX defined in the Ifdef.h header file. For more information, see the IPPROTO_IP Socket - /// Options for the IP_ORIGINAL_ARRIVAL_IF socket option. Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: - /// The IP_ORIGINAL_ARRIVAL_IF cmsg_type is not supported. - /// - /// - /// - /// IPv4 - /// IPPROTO_IP - /// IP_PKTINFO - /// Specifies/receives packet information for an IPv4 socket. For more information, see the IP_PKTINFO socket option. - /// - /// - /// IPv6 - /// IPPROTO_IPV6 - /// IPV6_DSTOPTS - /// Specifies/receives destination options. - /// - /// - /// IPv6 - /// IPPROTO_IPV6 - /// IPV6_HOPLIMIT - /// Specifies/receives hop limit. For more information, see the IPPROTO_IPV6 Socket Options for the IPV6_HOPLIMIT socket option. - /// - /// - /// IPv6 - /// IPPROTO_IPV6 - /// IPV6_HOPOPTS - /// Specifies/receives hop-by-hop options. - /// - /// - /// IPv6 - /// IPPROTO_IPV6 - /// IPV6_NEXTHOP - /// Specifies next-hop address. - /// - /// - /// IPv6 - /// IPPROTO_IPV6 - /// IPV6_PKTINFO - /// Specifies/receives packet information for an IPv6 socket. For more information, see the IPV6_PKTINFO socket option. - /// - /// - /// IPv6 - /// IPPROTO_IPV6 - /// IPV6_RTHDR - /// Specifies/receives routing header. - /// - /// - /// - /// Control data is made up of one or more control data objects, each beginning with a WSACMSGHDR structure, defined as the following. - /// - /// - /// Note The transport, not the application, fills out the header information in the WSACMSGHDR structure. The - /// application simply sets the needed socket options and provides the adequate buffer size. - /// - /// The members of the WSACMSGHDR structure are as follows: - /// - /// - /// Term - /// Description - /// - /// - /// cmsg_len - /// - /// The number of bytes of data starting from the beginning of the WSACMSGHDR to the end of data (excluding padding bytes that may - /// follow data). - /// - /// - /// - /// cmsg_level - /// The protocol that originated the control information. - /// - /// - /// cmsg_type - /// The protocol-specific type of control information. - /// - /// - /// The following macros are used to navigate the data objects: - /// - /// Returns a pointer to the first control data object. Returns a NULL pointer if there is no control data in the - /// WSAMSG structure, such as when the Control member is a NULL pointer. - /// - /// - /// Returns a pointer to the next control data object, or NULL if there are no more data objects. If the pcmsg parameter is - /// NULL, a pointer to the first control data object is returned. - /// - /// - /// Returns a pointer to the first byte of data (referred to as the cmsg_data member, though it is not defined in the structure). - /// - /// - /// Returns the total size of a control data object, given the amount of data. Used to allocate the correct amount of buffer space. - /// Includes alignment padding. - /// - /// Returns the value in cmsg_len given the amount of data. Includes alignment padding. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-wsamsg typedef struct _WSAMSG { LPSOCKADDR name; INT namelen; - // LPWSABUF lpBuffers; #if ... ULONG dwBufferCount; #else DWORD dwBufferCount; #endif WSABUF Control; #if ... ULONG dwFlags; #else - // DWORD dwFlags; #endif } WSAMSG, *PWSAMSG, *LPWSAMSG; - [PInvokeData("ws2def.h", MSDNShortId = "105a6e2c-1edf-4ec0-a1c2-ac0bcafeda30")] - [StructLayout(LayoutKind.Sequential)] - public struct WSAMSG - { - /// - /// Type: LPSOCKADDR - /// - /// A pointer to a SOCKET_ADDRESS structure that stores information about the remote address. Used only with unconnected sockets. - /// - /// - public IntPtr name; - - /// - /// Type: INT - /// - /// The length, in bytes, of the SOCKET_ADDRESS structure pointed to in the pAddr member. Used only with unconnected sockets. - /// - /// - public int namelen; - - /// - /// Type: LPWSABUF - /// - /// An array of WSABUF structures used to receive the message data. The capability of the lpBuffers member to contain - /// multiple buffers enables the use of scatter/gather I/O. - /// - /// - public IntPtr lpBuffers; - - /// - /// Type: DWORD - /// The number of buffers pointed to in the lpBuffers member. - /// - public uint dwBufferCount; - - /// - /// Type: WSABUF - /// A structure of WSABUF type used to specify optional control data. See Remarks. - /// - public WSABUF Control; - - /// - /// Type: DWORD - /// - /// One or more control flags, specified as the logical OR of values. The possible values for dwFlags member on - /// input are defined in the Winsock2.h header file. The possible values for dwFlags member on output are defined in the - /// Ws2def.h header file which is automatically included by the Winsock2.h header file. - /// - /// - /// - /// Flags on input - /// Meaning - /// - /// - /// MSG_PEEK - /// - /// Peek at the incoming data. The data is copied into the buffer, but is not removed from the input queue. This flag is valid - /// only for non-overlapped sockets. - /// - /// - /// - /// - /// - /// Flag returned - /// Meaning - /// - /// - /// MSG_BCAST - /// The datagram was received as a link-layer broadcast or with a destination IP address that is a broadcast address. - /// - /// - /// MSG_MCAST - /// The datagram was received with a destination IP address that is a multicast address. - /// - /// - /// MSG_TRUNC - /// The datagram was truncated. More data was present than the process allocated room for. - /// - /// - /// MSG_CTRUNC - /// The control (ancillary) data was truncated. More control data was present than the process allocated room for. - /// - /// - /// - public MsgFlags dwFlags; - } - - /// - /// - /// Some of the socket IOCTL opcodes for Windows Sockets 2 are summarized in the following table. More detailed information is in - /// the Winsock reference on Winsock IOCTLs and the WSPIoctl function. There are other new protocol-specific IOCTL - /// opcodes that can be found in the protocol-specific annex. - /// - /// A complete list of Winsock IOCTLs are available in the Winsock reference. - /// - // https://docs.microsoft.com/en-us/windows/win32/winsock/summary-of-socket-ioctl-opcodes-2 - [PInvokeData("ws2def.h", MSDNShortId = "fb6447b4-28f5-4ab7-bbdc-5a57ed38a994")] - public static class WinSockIOControlCode - { - /// - /// Determine the amount of data that can be read atomically from socket s. The lpvOutBuffer parameter points at an unsigned long - /// in which WSAIoctl stores the result. - /// - /// If the socket passed in the s parameter is stream oriented(for example, type SOCK_STREAM), FIONREAD returns the total amount - /// of data that can be read in a single receive operation; this is normally the same as the total amount of data queued on the - /// socket(since a data stream is byte-oriented, this is not guaranteed). - /// - /// - /// If the socket passed in the s parameter is message oriented(for example, type SOCK_DGRAM), FIONREAD returns the reports the - /// total number of bytes available to read, not the size of the first datagram(message) queued on the socket. - /// - /// - public static readonly uint FIONREAD = _IOR('f', 127); /* get # bytes to read */ - - /// - /// Enable or disable non-blocking mode on socket s. The lpvInBuffer parameter points at an unsigned long (QoS), which is nonzero - /// if non-blocking mode is to be enabled and zero if it is to be disabled. When a socket is created, it operates in blocking - /// mode (that is, non-blocking mode is disabled). This is consistent with BSD sockets. - /// - /// The WSAAsyncSelect or WSAEventSelect routine automatically sets a socket to non-blocking mode.If WSAAsyncSelect or - /// WSAEventSelect has been issued on a socket, then any attempt to use WSAIoctl to set the socket back to blocking mode will - /// fail with WSAEINVAL. To set the socket back to blocking mode, an application must first disable WSAAsyncSelect by calling - /// WSAAsyncSelect with the lEvent parameter equal to zero, or disable WSAEventSelect by calling WSAEventSelect with the - /// lNetworkEvents parameter equal to zero. - /// - /// - public static readonly uint FIONBIO = _IOW('f', 126); /* set/clear non-blocking i/o */ - - /// Enable notification for when data is waiting to be received. - public static readonly uint FIOASYNC = _IOW('f', 125); /* set/clear async i/o */ - - /// Requests notification of changes in information reported through SIO_ADDRESS_LIST_QUERY - public static readonly uint SIO_ADDRESS_LIST_CHANGE = _WSAIO(IOC_WS2, 23); - - /// - /// Obtains a list of local transport addresses of the socket's protocol family to which the application can bind. The list of - /// addresses varies based on address family and some addresses are excluded from the list. - /// - [CorrespondingType(typeof(SOCKET_ADDRESS), CorrespondingAction.Get)] - public static readonly uint SIO_ADDRESS_LIST_QUERY = _WSAIOR(IOC_WS2, 22); - - /// - /// Allows application developers to sort a list of IPv6 and IPv4 destination addresses to determine the best available address - /// for making a connection. - /// - [CorrespondingType(typeof(SOCKET_ADDRESS_LIST), CorrespondingAction.GetSet)] - public static readonly uint SIO_ADDRESS_LIST_SORT = _WSAIORW(IOC_WS2, 25); - - /// Associates the socket with the specified handle of a companion interface. - public static readonly uint SIO_ASSOCIATE_HANDLE = _WSAIOW(IOC_WS2, 1); - - /// Enables circular queuing. - public static readonly uint SIO_ENABLE_CIRCULAR_QUEUEING = _WSAIO(IOC_WS2, 2); - - /// Requests the route to the specified address to be discovered. - [CorrespondingType(typeof(SOCKADDR), CorrespondingAction.Set)] - public static readonly uint SIO_FIND_ROUTE = _WSAIOR(IOC_WS2, 3); - - /// Discards current contents of the sending queue. - public static readonly uint SIO_FLUSH = _WSAIO(IOC_WS2, 4); - - /// Retrieves the protocol-specific broadcast address to be used in WSPSendTo. - [CorrespondingType(typeof(SOCKADDR), CorrespondingAction.Get)] - public static readonly uint SIO_GET_BROADCAST_ADDRESS = _WSAIOR(IOC_WS2, 5); - - /// Gets the function pointer for the WSASendMsg function obtained at run time. - public static readonly uint SIO_GET_EXTENSION_FUNCTION_POINTER = _WSAIORW(IOC_WS2, 6); - - /// Reserved. - [CorrespondingType(typeof(QOS), CorrespondingAction.Get)] - public static readonly uint SIO_GET_GROUP_QOS = _WSAIORW(IOC_WS2, 8); - - /// Retrieves current flow specifications for the socket. - [CorrespondingType(typeof(QOS), CorrespondingAction.Get)] - public static readonly uint SIO_GET_QOS = _WSAIORW(IOC_WS2, 7); - - /// Specifies the scope over which multicast transmissions will occur. - [CorrespondingType(typeof(int), CorrespondingAction.Set)] - public static readonly uint SIO_MULTICAST_SCOPE = _WSAIOW(IOC_WS2, 10); - - /// Controls whether data sent in a multipoint session will also be received by the same socket on the local host. - [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] - public static readonly uint SIO_MULTIPOINT_LOOPBACK = _WSAIOW(IOC_WS2, 9); - - /// Queries the association between a socket and an RSS processor core and NUMA node. - [CorrespondingType(typeof(SOCKET_PROCESSOR_AFFINITY), CorrespondingAction.Get)] - public static readonly uint SIO_QUERY_RSS_PROCESSOR_INFO = _WSAIOR(IOC_WS2, 37); - - /// Obtains socket descriptor of the next provider in the chain on which current socket depends in regards to PnP. - [CorrespondingType(typeof(SOCKET), CorrespondingAction.Get)] - public static readonly uint SIO_QUERY_TARGET_PNP_HANDLE = _WSAIOR(IOC_WS2, 24); - - /// - /// Requests notification of changes in information reported through SIO_ROUTING_INTERFACE_QUERY for the specified address. - /// - [CorrespondingType(typeof(SOCKADDR), CorrespondingAction.Set)] - public static readonly uint SIO_ROUTING_INTERFACE_CHANGE = _WSAIOW(IOC_WS2, 21); - - /// Obtains the address of the local interface that should be used to send to the specified address. - [CorrespondingType(typeof(SOCKADDR), CorrespondingAction.GetSet)] - public static readonly uint SIO_ROUTING_INTERFACE_QUERY = _WSAIORW(IOC_WS2, 20); - - /// Reserved. - [CorrespondingType(typeof(QOS), CorrespondingAction.Set)] - public static readonly uint SIO_SET_GROUP_QOS = _WSAIOW(IOC_WS2, 12); - - /// Establishes new flow specifications for the socket. - [CorrespondingType(typeof(QOS), CorrespondingAction.Set)] - public static readonly uint SIO_SET_QOS = _WSAIOW(IOC_WS2, 11); - - /// Obtains a corresponding handle for socket s that is valid in the context of a companion interface. - [CorrespondingType(typeof(int), CorrespondingAction.Set)] - public static readonly uint SIO_TRANSLATE_HANDLE = _WSAIORW(IOC_WS2, 13); - - /// set high watermark - public static readonly uint SIOCSHIWAT = _IOW('s', 0); /* set high watermark */ - - /// get high watermark - public static readonly uint SIOCGHIWAT = _IOR('s', 1); /* get high watermark */ - - /// set low watermark - public static readonly uint SIOCSLOWAT = _IOW('s', 2); /* set low watermark */ - - /// get low watermark - public static readonly uint SIOCGLOWAT = _IOR('s', 3); /* get low watermark */ - - /// - /// Determine whether or not all OOB data has been read. This applies only to a socket of stream-style (for example, type - /// SOCK_STREAM) that has been configured for inline reception of any OOB data (SO_OOBINLINE). If no OOB data is waiting to be - /// read, the operation returns TRUE. Otherwise, it returns FALSE, and the next receive operation performed on the socket will - /// retrieve some or all of the data preceding the mark; the application should use the SIOCATMARK operation to determine whether - /// any remains. If there is any normal data preceding the urgent (out of band) data, it will be received in order. (Note that - /// recv operations will never mix OOB and normal data in the same call.) lpvOutBuffer points at a BOOL in which WSAIoctl stores - /// the result. - /// - public static readonly uint SIOCATMARK = _IOR('s', 7); /* at oob mark? */ - - private const uint IOCPARM_MASK = 0x7f; /* parameters must be < 128 bytes */ - private const uint IOC_VOID = 0x20000000; /* no parameters */ - private const uint IOC_OUT = 0x40000000; /* copy out parameters */ - private const uint IOC_IN = 0x80000000; /* copy in parameters */ - private const uint IOC_INOUT = IOC_IN|IOC_OUT; - private const uint IOC_PROTOCOL = 0x10000000; - private const uint IOC_UNIX = 0x00000000; - private const uint IOC_VENDOR = 0x18000000; - private const uint IOC_WS2 = 0x08000000; - private const uint IOC_WSK = IOC_WS2 | 0x07000000; - - private static uint _IO(uint x, uint y) => (IOC_VOID|((x)<<8)|(y)); - - private static uint _IOR(uint x, uint y) => (IOC_OUT|((sizeof(uint)&IOCPARM_MASK)<<16)|((x)<<8)|(y)); - - private static uint _IOW(uint x, uint y) => (IOC_IN|((sizeof(uint)&IOCPARM_MASK)<<16)|((x)<<8)|(y)); - - private static uint _WSAIO(uint x, uint y) => IOC_VOID | (x) | (y); - - private static uint _WSAIOR(uint x, uint y) => IOC_OUT | (x) | (y); - - private static uint _WSAIORW(uint x, uint y) => IOC_INOUT | (x) | (y); - - private static uint _WSAIOW(uint x, uint y) => IOC_IN | (x) | (y); + var len = (byte*)cmsg + WSA_CMSGHDR_ALIGN(cmsg->cmsg_len) + Marshal.SizeOf(typeof(WSACMSGHDR)); + return len > (byte*)msg.Control.buf + msg.Control.len ? null : (WSACMSGHDR*)((byte*)cmsg + WSA_CMSGHDR_ALIGN(cmsg->cmsg_len)); } } + + /// Returns total size of an ancillary data object given the amount of data. Used to allocate the correct amount of space. + /// The length. + /// Total size + public static SizeT WSA_CMSG_SPACE(SizeT length) => WSA_CMSGDATA_ALIGN(Marshal.SizeOf(typeof(WSACMSGHDR)) + WSA_CMSGHDR_ALIGN(length)); + + /// + /// The addrinfoex2 structure is used by the GetAddrInfoEx function to hold host address information when both a canonical name and + /// a fully qualified domain name have been requested. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-addrinfoex2w typedef struct addrinfoex2W { int ai_flags; int + // ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; PWSTR ai_canonname; struct sockaddr *ai_addr; void *ai_blob; + // size_t ai_bloblen; LPGUID ai_provider; struct addrinfoex2W *ai_next; int ai_version; PWSTR ai_fqdn; } ADDRINFOEX2W, + // *PADDRINFOEX2W, *LPADDRINFOEX2W; + [PInvokeData("ws2def.h", MSDNShortId = "9CB33347-A838-473D-B5CD-1149D6632CF2")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct ADDRINFOEX2W + { + /// + /// Flags that indicate options used in the GetAddrInfoEx function. + /// + /// Supported values for the ai_flags member are defined in the Winsock2.h include file and can be a combination of the + /// following options. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// AI_PASSIVE 0x01 + /// The socket address will be used in a call to the bindfunction. + /// + /// + /// AI_CANONNAME 0x02 + /// The canonical name is returned in the first ai_canonname member. + /// + /// + /// AI_NUMERICHOST 0x04 + /// The nodename parameter passed to the GetAddrInfoEx function must be a numeric string. + /// + /// + /// AI_ALL 0x0100 + /// + /// If this bit is set, a request is made for IPv6 addresses and IPv4 addresses with AI_V4MAPPED. This option is supported on + /// Windows Vista and later. + /// + /// + /// + /// AI_ADDRCONFIG 0x0400 + /// + /// The GetAddrInfoEx will resolve only if a global address is configured. The IPv6 and IPv4 loopback address is not considered + /// a valid global address. This option is supported on Windows Vista and later. + /// + /// + /// + /// AI_V4MAPPED 0x0800 + /// + /// If the GetAddrInfoEx request for an IPv6 addresses fails, a name service request is made for IPv4 addresses and these + /// addresses are converted to IPv4-mapped IPv6 address format. This option is supported on Windows Vista and later. + /// + /// + /// + /// AI_NON_AUTHORITATIVE 0x04000 + /// + /// The address information is from non-authoritative results. When this option is set in the pHints parameter of GetAddrInfoEx, + /// the NS_EMAIL namespace provider returns both authoritative and non-authoritative results. If this option is not set, then + /// only authoritative results are returned. This option is only supported on Windows Vista and later for the NS_EMAIL namespace. + /// + /// + /// + /// AI_SECURE 0x08000 + /// + /// The address information is from a secure channel. If the AI_SECURE bit is set, the NS_EMAIL namespace provider will return + /// results that were obtained with enhanced security to minimize possible spoofing. When this option is set in the pHints + /// parameter of GetAddrInfoEx, the NS_EMAIL namespace provider returns only results that were obtained with enhanced security + /// to minimize possible spoofing. This option is only supported on Windows Vista and later for the NS_EMAIL namespace. + /// + /// + /// + /// AI_RETURN_PREFERRED_NAMES 0x010000 + /// + /// The address information is for a preferred names for publication with a specific namespace. When this option is set in the + /// pHints parameter of GetAddrInfoEx, no name should be provided in the pName parameter and the NS_EMAIL namespace provider + /// will return preferred names for publication. This option is only supported on Windows Vista and later for the NS_EMAIL namespace. + /// + /// + /// + /// AI_FQDN 0x00020000 + /// + /// The fully qualified domain name is returned in the first ai_fqdn member. When this option is set in the pHints parameter of + /// GetAddrInfoEx and a flat name (single label) is specified in the pName parameter, the fully qualified domain name that the + /// name eventually resolved to will be returned. This option is supported on Windows 7, Windows Server 2008 R2, and later. + /// + /// + /// + /// AI_FILESERVER 0x00040000 + /// + /// A hint to the namespace provider that the hostname being queried is being used in a file share scenario. The namespace + /// provider may ignore this hint. This option is supported on Windows 7, Windows Server 2008 R2, and later. + /// + /// + /// + /// AI_DISABLE_IDN_ENCODING 0x00080000 + /// + /// Disable the automatic International Domain Name encoding using Punycode in the name resolution functions called by the + /// GetAddrInfoEx function. This option is supported on Windows 8, Windows Server 2012, and later. + /// + /// + /// + /// + public ADDRINFO_FLAGS ai_flags; + + private uint _ai_family; + + /// + /// Type: int + /// The address family. Possible values for the address family are defined in the Winsock2.h include file. + /// + /// On the Windows SDK released for Windows Vista and later,, the organization of header files has changed and the possible + /// values for the address family are defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically + /// included in Winsock2.h, and should never be used directly. + /// + /// + /// The values currently supported are AF_INET or AF_INET6, which are the Internet address family formats for IPv4 + /// and IPv6. Other options for address family ( AF_NETBIOS for use with NetBIOS, for example) are supported if a Windows + /// Sockets service provider for the address family is installed. Note that the values for the AF_ address family and PF_ + /// protocol family constants are identical (for example, AF_UNSPEC and PF_UNSPEC), so either constant can be used. + /// + /// The table below lists common values for the address family although many other values are possible. + /// + /// + /// Value + /// Meaning + /// + /// + /// AF_UNSPEC 0 + /// The address family is unspecified. + /// + /// + /// AF_INET 2 + /// The Internet Protocol version 4 (IPv4) address family. + /// + /// + /// AF_NETBIOS 17 + /// The NetBIOS address family. This address family is only supported if a Windows Sockets provider for NetBIOS is installed. + /// + /// + /// AF_INET6 23 + /// The Internet Protocol version 6 (IPv6) address family. + /// + /// + /// AF_IRDA 26 + /// + /// The Infrared Data Association (IrDA) address family. This address family is only supported if the computer has an infrared + /// port and driver installed. + /// + /// + /// + /// AF_BTH 32 + /// + /// The Bluetooth address family. This address family is only supported if a Bluetooth adapter is installed on Windows Server + /// 2003 or later. + /// + /// + /// + /// + public ADDRESS_FAMILY ai_family { get => (ADDRESS_FAMILY)_ai_family; set => _ai_family = (ushort)value; } + + /// + /// The socket type. Possible values for the socket type are defined in the Winsock2.h include file. + /// The following table lists the possible values for the socket type supported for Windows Sockets 2: + /// + /// + /// Value + /// Meaning + /// + /// + /// SOCK_STREAM 1 + /// + /// Provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. Uses the + /// Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6). If the ai_family member is + /// AF_IRDA, then SOCK_STREAM is the only supported socket type. + /// + /// + /// + /// SOCK_DGRAM 2 + /// + /// Supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. Uses the User + /// Datagram Protocol (UDP) for the Internet address family (AF_INET or AF_INET6). + /// + /// + /// + /// SOCK_RAW 3 + /// + /// Provides a raw socket that allows an application to manipulate the next upper-layer protocol header. To manipulate the IPv4 + /// header, the IP_HDRINCL socket option must be set on the socket. To manipulate the IPv6 header, the IPV6_HDRINCL socket + /// option must be set on the socket. + /// + /// + /// + /// SOCK_RDM 4 + /// + /// Provides a reliable message datagram. An example of this type is the Pragmatic General Multicast (PGM) multicast protocol + /// implementation in Windows, often referred to as reliable multicast programming. + /// + /// + /// + /// SOCK_SEQPACKET 5 + /// Provides a pseudo-stream packet based on datagrams. + /// + /// + /// + /// In Windows Sockets 2, new socket types were introduced. An application can dynamically discover the attributes of each + /// available transport protocol through the WSAEnumProtocols function. So an application can determine the possible socket type + /// and protocol options for an address family and use this information when specifying this parameter. Socket type definitions + /// in the Winsock2.h and Ws2def.h header files will be periodically updated as new socket types, address families, and + /// protocols are defined. + /// + /// In Windows Sockets 1.1, the only possible socket types are SOCK_DATAGRAM and SOCK_STREAM. + /// + public SOCK ai_socktype; + + /// + /// + /// The protocol type. The possible options are specific to the address family and socket type specified. Possible values for + /// the ai_protocol are defined in Winsock2.h and the Wsrm.h header files. + /// + /// + /// On the Windows SDK released for Windows Vista and later,, the organization of header files has changed and this member can + /// be one of the values from the IPPROTO enumeration type defined in the Ws2def.h header file. Note that the Ws2def.h + /// header file is automatically included in Winsock2.h, and should never be used directly. + /// + /// + /// If a value of 0 is specified for ai_protocol, the caller does not wish to specify a protocol and the service provider + /// will choose the ai_protocol to use. For protocols other than IPv4 and IPv6, set ai_protocol to zero. + /// + /// The following table lists common values for the ai_protocol member although many other values are possible. + /// + /// + /// Value + /// Meaning + /// + /// + /// IPPROTO_TCP 6 + /// + /// The Transmission Control Protocol (TCP). This is a possible value when the ai_family member is AF_INET or AF_INET6 and the + /// ai_socktype member is SOCK_STREAM. + /// + /// + /// + /// IPPROTO_UDP 17 + /// + /// The User Datagram Protocol (UDP). This is a possible value when the ai_family member is AF_INET or AF_INET6 and the type + /// parameter is SOCK_DGRAM. + /// + /// + /// + /// IPPROTO_RM 113 + /// + /// The PGM protocol for reliable multicast. This is a possible value when the ai_family member is AF_INET and the ai_socktype + /// member is SOCK_RDM. On the Windows SDK released for Windows Vista and later, this value is also called IPPROTO_PGM. + /// + /// + /// + /// If the ai_family member is AF_IRDA, then the ai_protocol must be 0. + /// + public IPPROTO ai_protocol; + + /// The length, in bytes, of the buffer pointed to by the ai_addr member. + public SizeT ai_addrlen; + + /// The canonical name for the host. + public StrPtrUni ai_canonname; + + /// + /// A pointer to a sockaddr structure. The ai_addr member in each returned addrinfoex2 structure points to a + /// filled-in socket address structure. The length, in bytes, of each returned addrinfoex2 structure is specified in the + /// ai_addrlen member. + /// + public IntPtr ai_addr; + + /// + /// A pointer to data that is used to return provider-specific namespace information that is associated with the name beyond a + /// list of addresses. The length, in bytes, of the buffer pointed to by ai_blob must be specified in the + /// ai_bloblen member. + /// + public IntPtr ai_blob; + + /// The length, in bytes, of the ai_blob member. + public SizeT ai_bloblen; + + /// A pointer to the GUID of a specific namespace provider. + public GuidPtr ai_provider; + + /// + /// A pointer to the next structure in a linked list. This parameter is set to NULL in the last addrinfoex2 + /// structure of a linked list. + /// + public IntPtr ai_next; + + /// The version number of this structure. The value currently used for this version of the structure is 2. + public int ai_version; + + /// The fully qualified domain name for the host. + public StrPtrUni ai_fqdn; + + /// + /// Type: struct sockaddr* + /// + /// A pointer to a sockaddr structure. The ai_addr member in each returned ADDRINFOW structure points to a filled-in + /// socket address structure. The length, in bytes, of each returned ADDRINFOW structure is specified in the + /// ai_addrlen member. + /// + /// + public SOCKADDR addr => new(ai_addr, false, ai_addrlen); + + /// + public override string ToString() => $"{ai_fqdn}::{ai_canonname}:{ai_flags},{ai_family},{ai_socktype},{ai_protocol},{addr}"; + } + + /// The addrinfoex structure is used by the GetAddrInfoEx function to hold host address information. + /// + /// + /// The addrinfoex structure is used by the GetAddrInfoEx function to hold host address information. The addrinfoex + /// structure is an enhanced version of the addrinfo and addrinfoW structures. The extra structure members are for blob data and the + /// GUID for the namespace provider. The blob data is used to return additional provider-specific namespace information associated + /// with a name. The format of data in the ai_blob member is specific to a particular namespace provider. Currently, blob + /// data is used by the NS_EMAIL namespace provider to supply additional information. + /// + /// + /// The addrinfoex structure is an enhanced version of the addrinfo and addrinfoW structure used with GetAddrInfoEx function. + /// The GetAddrInfoEx function allows specifying the namespace provider to resolve the query. For use with the IPv6 and IPv4 + /// protocol, name resolution can be by the Domain Name System (DNS), a local hosts file, an email provider (the NS_EMAIL + /// namespace), or by other naming mechanisms. + /// + /// + /// When UNICODE or _UNICODE is defined, addrinfoex is defined to addrinfoexW, the Unicode version of this structure. + /// The string parameters are defined to the PWSTR data type and the addrinfoexW structure is used. + /// + /// + /// When UNICODE or _UNICODE is not defined, addrinfoex is defined to addrinfoexA, the ANSI version of this structure. + /// The string parameters are of the PCSTR data type and the addrinfoexA structure is used. + /// + /// + /// Upon a successful call to GetAddrInfoEx, a linked list of addrinfoex structures is returned in the ppResult parameter + /// passed to the GetAddrInfoEx function. The list can be processed by following the pointer provided in the ai_next + /// member of each returned addrinfoex structure until a NULL pointer is encountered. In each returned + /// addrinfoex structure, the ai_family, ai_socktype, and ai_protocol members correspond to respective + /// arguments in a socket or WSASocket function call. Also, the ai_addr member in each returned addrinfoex structure + /// points to a filled-in socket address structure, the length of which is specified in its ai_addrlen member. + /// + /// Examples + /// The following example demonstrates the use of the addrinfoex structure. + /// + /// Note Ensure that the development environment targets the newest version of Ws2tcpip.h which includes structure and + /// function definitions for ADDRINFOEX and GetAddrInfoEx, respectively. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-addrinfoexa typedef struct addrinfoexA { int ai_flags; int + // ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; char *ai_canonname; struct sockaddr *ai_addr; void *ai_blob; + // size_t ai_bloblen; LPGUID ai_provider; struct addrinfoexA *ai_next; } ADDRINFOEXA, *PADDRINFOEXA, *LPADDRINFOEXA; + [PInvokeData("ws2def.h", MSDNShortId = "1077e03d-a1a4-45ab-a5d2-29a67e03f5df")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public unsafe struct ADDRINFOEXW + { + /// + /// Type: int + /// Flags that indicate options used in the GetAddrInfoEx function. + /// + /// Supported values for the ai_flags member are defined in the Winsock2.h include file and can be a combination of the + /// following options. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// AI_PASSIVE 0x01 + /// The socket address will be used in a call to the bindfunction. + /// + /// + /// AI_CANONNAME 0x02 + /// + /// The canonical name is returned in the first ai_canonname member. When both the AI_CANONNAME and AI_FQDN bits are set, an + /// addrinfoex2 structure is returned not the addrinfoex structure. + /// + /// + /// + /// AI_NUMERICHOST 0x04 + /// The nodename parameter passed to the GetAddrInfoEx function must be a numeric string. + /// + /// + /// AI_ALL 0x0100 + /// + /// If this bit is set, a request is made for IPv6 addresses and IPv4 addresses with AI_V4MAPPED. This option is supported on + /// Windows Vista and later. + /// + /// + /// + /// AI_ADDRCONFIG 0x0400 + /// + /// The GetAddrInfoEx will resolve only if a global address is configured. The IPv6 and IPv4 loopback address is not considered + /// a valid global address. This option is only supported on Windows Vista and later. + /// + /// + /// + /// AI_V4MAPPED 0x0800 + /// + /// If the GetAddrInfoEx request for an IPv6 addresses fails, a name service request is made for IPv4 addresses and these + /// addresses are converted to IPv4-mapped IPv6 address format. This option is supported on Windows Vista and later. + /// + /// + /// + /// AI_NON_AUTHORITATIVE 0x04000 + /// + /// The address information is from non-authoritative results. When this option is set in the pHints parameter of GetAddrInfoEx, + /// the NS_EMAIL namespace provider returns both authoritative and non-authoritative results. If this option is not set, then + /// only authoritative results are returned. In the ppResults parameter returned by GetAddrInfoEx, this flag is set in the + /// ai_flags member of the addrinfoex structure for non-authoritative results. This option is only supported on Windows Vista + /// and later for the NS_EMAIL namespace. + /// + /// + /// + /// AI_SECURE 0x08000 + /// + /// The address information is from a secure channel. If the AI_SECURE bit is set, the NS_EMAIL namespace provider will return + /// results that were obtained with enhanced security to minimize possible spoofing. When this option is set in the pHints + /// parameter of GetAddrInfoEx, the NS_EMAIL namespace provider returns only results that were obtained with enhanced security + /// to minimize possible spoofing. In the ppResults parameter returned by GetAddrInfoEx, this flag is set in the ai_flags member + /// of the addrinfoex structure for results returned with enhanced security to minimize possible spoofing. This option is only + /// supported on Windows Vista and later for the NS_EMAIL namespace. + /// + /// + /// + /// AI_RETURN_PREFERRED_NAMES 0x010000 + /// + /// The address information is for a preferred names for publication with a specific namespace. When this option is set in the + /// pHints parameter of GetAddrInfoEx, no name should be provided in the pName parameter and the NS_EMAIL namespace provider + /// will return preferred names for publication. In the ppResults parameter returned by GetAddrInfoEx, this flag is set in the + /// ai_flags member of the addrinfoex structure for results returned for preferred names for publication. This option is only + /// supported on Windows Vista and later for the NS_EMAIL namespace. + /// + /// + /// + /// AI_FQDN 0x00020000 + /// + /// The fully qualified domain name is returned in the first ai_canonicalname member. When this option is set in the pHints + /// parameter of GetAddrInfoEx and a flat name (single label) is specified in the pName parameter, the fully qualified domain + /// name that the name eventually resolved to will be returned. When both the AI_CANONNAME and AI_FQDN bits are set, an + /// addrinfoex2 structure is returned not the addrinfoex structure. This option is supported on Windows 7, Windows Server 2008 + /// R2, and later. + /// + /// + /// + /// AI_FILESERVER 0x00040000 + /// + /// A hint to the namespace provider that the hostname being queried is being used in a file share scenario. The namespace + /// provider may ignore this hint. This option is supported on Windows 7, Windows Server 2008 R2, and later. + /// + /// + /// + /// AI_DISABLE_IDN_ENCODING 0x00080000 + /// + /// Disable the automatic International Domain Name encoding using Punycode in the name resolution functions called by the + /// GetAddrInfoEx function. This option is supported on Windows 8, Windows Server 2012, and later. + /// + /// + /// + /// + public ADDRINFO_FLAGS ai_flags; + + private uint _ai_family; + + /// + /// Type: int + /// The address family. Possible values for the address family are defined in the Winsock2.h include file. + /// + /// On the Windows SDK released for Windows Vista and later,, the organization of header files has changed and the possible + /// values for the address family are defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically + /// included in Winsock2.h, and should never be used directly. + /// + /// + /// The values currently supported are AF_INET or AF_INET6, which are the Internet address family formats for IPv4 + /// and IPv6. Other options for address family ( AF_NETBIOS for use with NetBIOS, for example) are supported if a Windows + /// Sockets service provider for the address family is installed. Note that the values for the AF_ address family and PF_ + /// protocol family constants are identical (for example, AF_UNSPEC and PF_UNSPEC), so either constant can be used. + /// + /// The table below lists common values for the address family although many other values are possible. + /// + /// + /// Value + /// Meaning + /// + /// + /// AF_UNSPEC 0 + /// The address family is unspecified. + /// + /// + /// AF_INET 2 + /// The Internet Protocol version 4 (IPv4) address family. + /// + /// + /// AF_NETBIOS 17 + /// The NetBIOS address family. This address family is only supported if a Windows Sockets provider for NetBIOS is installed. + /// + /// + /// AF_INET6 23 + /// The Internet Protocol version 6 (IPv6) address family. + /// + /// + /// AF_IRDA 26 + /// + /// The Infrared Data Association (IrDA) address family. This address family is only supported if the computer has an infrared + /// port and driver installed. + /// + /// + /// + /// AF_BTH 32 + /// + /// The Bluetooth address family. This address family is only supported if a Bluetooth adapter is installed on Windows Server + /// 2003 or later. + /// + /// + /// + /// + public ADDRESS_FAMILY ai_family { get => (ADDRESS_FAMILY)_ai_family; set => _ai_family = (ushort)value; } + + /// + /// Type: int + /// The socket type. Possible values for the socket type are defined in the Winsock2.h include file. + /// The following table lists the possible values for the socket type supported for Windows Sockets 2: + /// + /// + /// Value + /// Meaning + /// + /// + /// SOCK_STREAM 1 + /// + /// Provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. Uses the + /// Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6). If the ai_family member is + /// AF_IRDA, then SOCK_STREAM is the only supported socket type. + /// + /// + /// + /// SOCK_DGRAM 2 + /// + /// Supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. Uses the User + /// Datagram Protocol (UDP) for the Internet address family (AF_INET or AF_INET6). + /// + /// + /// + /// SOCK_RAW 3 + /// + /// Provides a raw socket that allows an application to manipulate the next upper-layer protocol header. To manipulate the IPv4 + /// header, the IP_HDRINCL socket option must be set on the socket. To manipulate the IPv6 header, the IPV6_HDRINCL socket + /// option must be set on the socket. + /// + /// + /// + /// SOCK_RDM 4 + /// + /// Provides a reliable message datagram. An example of this type is the Pragmatic General Multicast (PGM) multicast protocol + /// implementation in Windows, often referred to as reliable multicast programming. + /// + /// + /// + /// SOCK_SEQPACKET 5 + /// Provides a pseudo-stream packet based on datagrams. + /// + /// + /// + /// In Windows Sockets 2, new socket types were introduced. An application can dynamically discover the attributes of each + /// available transport protocol through the WSAEnumProtocols function. So an application can determine the possible socket type + /// and protocol options for an address family and use this information when specifying this parameter. Socket type definitions + /// in the Winsock2.h and Ws2def.h header files will be periodically updated as new socket types, address families, and + /// protocols are defined. + /// + /// In Windows Sockets 1.1, the only possible socket types are SOCK_DATAGRAM and SOCK_STREAM. + /// + public SOCK ai_socktype; + + /// + /// Type: int + /// + /// The protocol type. The possible options are specific to the address family and socket type specified. Possible values for + /// the ai_protocol are defined in Winsock2.h and the Wsrm.h header files. + /// + /// + /// On the Windows SDK released for Windows Vista and later,, the organization of header files has changed and this member can + /// be one of the values from the IPPROTO enumeration type defined in the Ws2def.h header file. Note that the Ws2def.h + /// header file is automatically included in Winsock2.h, and should never be used directly. + /// + /// + /// If a value of 0 is specified for ai_protocol, the caller does not wish to specify a protocol and the service provider + /// will choose the ai_protocol to use. For protocols other than IPv4 and IPv6, set ai_protocol to zero. + /// + /// The following table lists common values for the ai_protocol member although many other values are possible. + /// + /// + /// Value + /// Meaning + /// + /// + /// IPPROTO_TCP 6 + /// + /// The Transmission Control Protocol (TCP). This is a possible value when the ai_family member is AF_INET or AF_INET6 and the + /// ai_socktype member is SOCK_STREAM. + /// + /// + /// + /// IPPROTO_UDP 17 + /// + /// The User Datagram Protocol (UDP). This is a possible value when the ai_family member is AF_INET or AF_INET6 and the type + /// parameter is SOCK_DGRAM. + /// + /// + /// + /// IPPROTO_RM 113 + /// + /// The PGM protocol for reliable multicast. This is a possible value when the ai_family member is AF_INET and the ai_socktype + /// member is SOCK_RDM. On the Windows SDK released for Windows Vista and later, this value is also called IPPROTO_PGM. + /// + /// + /// + /// If the ai_family member is AF_IRDA, then the ai_protocol must be 0. + /// + public IPPROTO ai_protocol; + + /// + /// Type: size_t + /// The length, in bytes, of the buffer pointed to by the ai_addr member. + /// + public SizeT ai_addrlen; + + /// + /// Type: PCTSTR + /// The canonical name for the host. + /// + public StrPtrUni ai_canonname; + + /// + /// Type: struct sockaddr* + /// + /// A pointer to a sockaddr structure. The ai_addr member in each returned addrinfoex structure points to a + /// filled-in socket address structure. The length, in bytes, of each returned addrinfoex structure is specified in the + /// ai_addrlen member. + /// + /// + public IntPtr ai_addr; + + /// + /// Type: void* + /// + /// A pointer to data that is used to return provider-specific namespace information that is associated with the name beyond a + /// list of addresses. The length, in bytes, of the buffer pointed to by ai_blob must be specified in the + /// ai_bloblen member. + /// + /// + public IntPtr ai_blob; + + /// + /// Type: size_t + /// The length, in bytes, of the ai_blob member. + /// + public SizeT ai_bloblen; + + /// + /// Type: LPGUID + /// A pointer to the GUID of a specific namespace provider. + /// + public Guid* ai_provider; + + /// + /// Type: struct addrinfoex* + /// + /// A pointer to the next structure in a linked list. This parameter is set to NULL in the last addrinfoex + /// structure of a linked list. + /// + /// + public IntPtr ai_next; + + /// + /// Type: struct sockaddr* + /// + /// A pointer to a sockaddr structure. The ai_addr member in each returned ADDRINFOW structure points to a filled-in + /// socket address structure. The length, in bytes, of each returned ADDRINFOW structure is specified in the + /// ai_addrlen member. + /// + /// + public SOCKADDR addr => new(ai_addr, false, ai_addrlen); + + /// + public override string ToString() => $"{ai_canonname}:{ai_flags},{ai_family},{ai_socktype},{ai_protocol},{addr}"; + } + + /// + /// The addrinfoex2 structure is used by the GetAddrInfoEx function to hold host address information when both a canonical + /// name and a fully qualified domain name have been requested. + /// + /// + /// The addrinfoex2 structure is supported on Windows 8 and Windows Server 2012 + /// + /// The addrinfoex2 structure is used by the GetAddrInfoEx function to hold host address information when both the + /// AI_FQDN and AI_CANONNAME bits are set in the ai_flags member of the optional addrinfoex structure provided + /// in the hints parameter to the GetAddrInfoEx function. The addrinfoex2 structure is an enhanced version of the + /// addrinfoex structure that can return both the canonical name and the fully qualified domain name for the host. The extra + /// structure members are for a version number of the structure and the fully qualified domain name for the host. + /// + /// + /// The addrinfoex2 structure used with GetAddrInfoEx function is an enhanced version of the addrinfo and addrinfoW + /// structures used with the getaddrinfo and GetAddrInfoW functions. The GetAddrInfoEx function allows specifying the + /// namespace provider to resolve the query. For use with the IPv6 and IPv4 protocol, name resolution can be by the Domain Name + /// System (DNS), a local hosts file, an email provider (the NS_EMAIL namespace), or by other naming mechanisms. + /// + /// + /// The blob data in tha ai_blob member is used to return additional provider-specific namespace information associated with + /// a name. The format of data in the ai_blob member is specific to a particular namespace provider. Currently, blob data is + /// used by the NS_EMAIL namespace provider to supply additional information. + /// + /// + /// When UNICODE or _UNICODE is defined, addrinfoex2 is defined to addrinfoex2W, the Unicode version of this + /// structure. The string parameters are defined to the PWSTR data type and the addrinfoex2W structure is used. + /// + /// + /// When UNICODE or _UNICODE is not defined, addrinfoex2 is defined to addrinfoex2A, the ANSI version of this + /// structure. The string parameters are of the char * data type and the addrinfoex2A structure is used. + /// + /// + /// Upon a successful call to GetAddrInfoEx, a linked list of addrinfoex2 structures is returned in the ppResult parameter + /// passed to the GetAddrInfoEx function. The list can be processed by following the pointer provided in the ai_next + /// member of each returned addrinfoex2 structure until a NULL pointer is encountered. In each returned + /// addrinfoex2 structure, the ai_family, ai_socktype, and ai_protocol members correspond to respective + /// arguments in a socket or WSASocket function call. Also, the ai_addr member in each returned addrinfoex2 structure + /// points to a filled-in socket address structure, the length of which is specified in its ai_addrlen member. + /// + /// + /// The addrinfo structure is used by the getaddrinfo function to hold host address information. + /// + /// The addrinfo structure is used by the ANSI getaddrinfo function to hold host address information. + /// The addrinfoW structure is the version of this structure used by the Unicode GetAddrInfoW function. + /// + /// Macros in the Ws2tcpip.h header file define a ADDRINFOT structure and a mixed-case function name of GetAddrInfo. + /// The GetAddrInfo function should be called with the nodename and servname parameters of a pointer of type TCHAR and + /// the hints and res parameters of a pointer of type ADDRINFOT. When UNICODE or _UNICODE is not defined, ADDRINFOT is + /// defined to the addrinfo structure and GetAddrInfo is defined to getaddrinfo, the ANSI version of this function. + /// When UNICODE or _UNICODE is defined, ADDRINFOT is defined to the addrinfoW structure and GetAddrInfo is defined to + /// GetAddrInfoW, the Unicode version of this function. + /// + /// + /// Upon a successful call to getaddrinfo, a linked list of addrinfo structures is returned in the res parameter passed to + /// the getaddrinfo function. The list can be processed by following the pointer provided in the ai_next member of + /// each returned addrinfo structure until a NULL pointer is encountered. In each returned addrinfo structure, + /// the ai_family, ai_socktype, and ai_protocol members correspond to respective arguments in a socket or + /// WSASocket function call. Also, the ai_addr member in each returned addrinfo structure points to a filled-in socket + /// address structure, the length of which is specified in its ai_addrlen member. + /// + /// Support for getaddrinfo and the addrinfo struct on older versions of Windows + /// + /// The getaddrinfo function that uses the addrinfo structure was added to the Ws2_32.dll on Windows XP and later. The + /// addrinfo structure is defined in the Ws2tcpip.h header file included with the Platform SDK released for Windows XP and + /// later and the Windows SDK released for Windows Vista and later. + /// + /// + /// To execute an application that uses the getaddrinfo function and the addrinfo structure on earlier versions of Windows + /// (Windows 2000), then you need to include the Ws2tcpip.h and Wspiapi.h files. When the Wspiapi.h include file is added, the + /// getaddrinfo function is defined to the WspiapiGetAddrInfo inline function in the Wspiapi.h file. At runtime, the + /// WspiapiGetAddrInfo function is implemented in such a way that if the Ws2_32.dll or the Wship6.dll (the file containing + /// getaddrinfo in the IPv6 Technology Preview for Windows 2000) does not include getaddrinfo, then a version of + /// getaddrinfo is implemented inline based on code in the Wspiapi.h header file. This inline code will be used on older + /// Windows platforms that do not natively support the getaddrinfo function. + /// + /// + /// The IPv6 protocol is supported on Windows 2000 when the IPv6 Technology Preview for Windows 2000 is installed. Otherwise + /// getaddrinfo support on versions of Windows earlier than Windows XP is limited to handling IPv4 name resolution. + /// + /// + /// The GetAddrInfoW function that uses the addrinfoW structure is the Unicode version of the getaddrinfo function and associated + /// addrinfo structure. The GetAddrInfoW function was added to the Ws2_32.dll in Windows XP with Service Pack 2 (SP2). + /// The GetAddrInfoW function and the addrinfoW structure cannot be used on versions of Windows earlier than Windows + /// XP with SP2. + /// + /// Examples + /// The following code example shows the use of the addrinfo structure. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-addrinfoa typedef struct addrinfo { int ai_flags; int + // ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; char *ai_canonname; struct sockaddr *ai_addr; struct addrinfo + // *ai_next; } ADDRINFOA, *PADDRINFOA; + [PInvokeData("ws2def.h", MSDNShortId = "4df914ab-59b0-4110-bc81-59e5f6722b8d")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] + public struct ADDRINFOW + { + /// + /// Type: int + /// Flags that indicate options used in the getaddrinfo function. + /// + /// Supported values for the ai_flags member are defined in the Ws2def.h header file on the Windows SDK for Windows 7 and + /// later. These values are defined in the Ws2tcpip.h header file on the Windows SDK for Windows Server 2008 and Windows Vista. + /// These values are defined in the Ws2tcpip.h header file on the Platform SDK for Windows Server 2003, and Windows XP. + /// Supported values for the ai_flags member can be a combination of the following options. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// AI_PASSIVE 0x01 + /// The socket address will be used in a call to the bindfunction. + /// + /// + /// AI_CANONNAME 0x02 + /// The canonical name is returned in the first ai_canonname member. + /// + /// + /// AI_NUMERICHOST 0x04 + /// The nodename parameter passed to the getaddrinfo function must be a numeric string. + /// + /// + /// AI_ALL 0x0100 + /// + /// If this bit is set, a request is made for IPv6 addresses and IPv4 addresses with AI_V4MAPPED. This option is supported on + /// Windows Vista and later. + /// + /// + /// + /// AI_ADDRCONFIG 0x0400 + /// + /// The getaddrinfo will resolve only if a global address is configured. The IPv6 and IPv4 loopback address is not considered a + /// valid global address. This option is supported on Windows Vista and later. + /// + /// + /// + /// AI_V4MAPPED 0x0800 + /// + /// If the getaddrinfo request for IPv6 addresses fails, a name service request is made for IPv4 addresses and these addresses + /// are converted to IPv4-mapped IPv6 address format. This option is supported on Windows Vista and later. + /// + /// + /// + /// AI_NON_AUTHORITATIVE 0x04000 + /// + /// The address information can be from a non-authoritative namespace provider. This option is only supported on Windows Vista + /// and later for the NS_EMAIL namespace. + /// + /// + /// + /// AI_SECURE 0x08000 + /// + /// The address information is from a secure channel. This option is only supported on Windows Vista and later for the NS_EMAIL namespace. + /// + /// + /// + /// AI_RETURN_PREFERRED_NAMES 0x010000 + /// + /// The address information is for a preferred name for a user. This option is only supported on Windows Vista and later for the + /// NS_EMAIL namespace. + /// + /// + /// + /// AI_FQDN 0x00020000 + /// + /// If a flat name (single label) is specified, getaddrinfo will return the fully qualified domain name that the name eventually + /// resolved to. The fully qualified domain name is returned in the ai_canonname member. This is different than AI_CANONNAME bit + /// flag that returns the canonical name registered in DNS which may be different than the fully qualified domain name that the + /// flat name resolved to. Only one of the AI_FQDN and AI_CANONNAME bits can be set. The getaddrinfo function will fail if both + /// flags are present with EAI_BADFLAGS. This option is supported on Windows 7, Windows Server 2008 R2, and later. + /// + /// + /// + /// AI_FILESERVER 0x00040000 + /// + /// A hint to the namespace provider that the hostname being queried is being used in a file share scenario. The namespace + /// provider may ignore this hint. This option is supported on Windows 7, Windows Server 2008 R2, and later. + /// + /// + /// + /// + public ADDRINFO_FLAGS ai_flags; + + private uint _ai_family; + + /// + /// Type: int + /// The address family. Possible values for the address family are defined in the Winsock2.h include file. + /// + /// On the Windows SDK released for Windows Vista and later,, the organization of header files has changed and the possible + /// values for the address family are defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically + /// included in Winsock2.h, and should never be used directly. + /// + /// + /// The values currently supported are AF_INET or AF_INET6, which are the Internet address family formats for IPv4 + /// and IPv6. Other options for address family ( AF_NETBIOS for use with NetBIOS, for example) are supported if a Windows + /// Sockets service provider for the address family is installed. Note that the values for the AF_ address family and PF_ + /// protocol family constants are identical (for example, AF_UNSPEC and PF_UNSPEC), so either constant can be used. + /// + /// The table below lists common values for the address family although many other values are possible. + /// + /// + /// Value + /// Meaning + /// + /// + /// AF_UNSPEC 0 + /// The address family is unspecified. + /// + /// + /// AF_INET 2 + /// The Internet Protocol version 4 (IPv4) address family. + /// + /// + /// AF_NETBIOS 17 + /// The NetBIOS address family. This address family is only supported if a Windows Sockets provider for NetBIOS is installed. + /// + /// + /// AF_INET6 23 + /// The Internet Protocol version 6 (IPv6) address family. + /// + /// + /// AF_IRDA 26 + /// + /// The Infrared Data Association (IrDA) address family. This address family is only supported if the computer has an infrared + /// port and driver installed. + /// + /// + /// + /// AF_BTH 32 + /// + /// The Bluetooth address family. This address family is only supported if a Bluetooth adapter is installed on Windows Server + /// 2003 or later. + /// + /// + /// + /// + public ADDRESS_FAMILY ai_family { get => (ADDRESS_FAMILY)_ai_family; set => _ai_family = (ushort)value; } + + /// + /// Type: int + /// The socket type. Possible values for the socket type are defined in the Winsock2.h header file. + /// The following table lists the possible values for the socket type supported for Windows Sockets 2: + /// + /// + /// Value + /// Meaning + /// + /// + /// SOCK_STREAM 1 + /// + /// Provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. Uses the + /// Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6). If the ai_family member is + /// AF_IRDA, then SOCK_STREAM is the only supported socket type. + /// + /// + /// + /// SOCK_DGRAM 2 + /// + /// Supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. Uses the User + /// Datagram Protocol (UDP) for the Internet address family (AF_INET or AF_INET6). + /// + /// + /// + /// SOCK_RAW 3 + /// + /// Provides a raw socket that allows an application to manipulate the next upper-layer protocol header. To manipulate the IPv4 + /// header, the IP_HDRINCL socket option must be set on the socket. To manipulate the IPv6 header, the IPV6_HDRINCL socket + /// option must be set on the socket. + /// + /// + /// + /// SOCK_RDM 4 + /// + /// Provides a reliable message datagram. An example of this type is the Pragmatic General Multicast (PGM) multicast protocol + /// implementation in Windows, often referred to as reliable multicast programming. + /// + /// + /// + /// SOCK_SEQPACKET 5 + /// Provides a pseudo-stream packet based on datagrams. + /// + /// + /// + /// In Windows Sockets 2, new socket types were introduced. An application can dynamically discover the attributes of each + /// available transport protocol through the WSAEnumProtocols function. So an application can determine the possible socket type + /// and protocol options for an address family and use this information when specifying this parameter. Socket type definitions + /// in the Winsock2.h and Ws2def.h header files will be periodically updated as new socket types, address families, and + /// protocols are defined. + /// + /// In Windows Sockets 1.1, the only possible socket types are SOCK_DATAGRAM and SOCK_STREAM. + /// + public SOCK ai_socktype; + + /// + /// Type: int + /// + /// The protocol type. The possible options are specific to the address family and socket type specified. Possible values for + /// the ai_protocol are defined in the Winsock2.h and Wsrm.h header files. + /// + /// + /// On the Windows SDK released for Windows Vista and later, the organization of header files has changed and this member can be + /// one of the values from the IPPROTO enumeration type defined in the Ws2def.h header file. Note that the Ws2def.h + /// header file is automatically included in Winsock2.h, and should never be used directly. + /// + /// + /// If a value of 0 is specified for ai_protocol, the caller does not wish to specify a protocol and the service provider + /// will choose the ai_protocol to use. For protocols other than IPv4 and IPv6, set ai_protocol to zero. + /// + /// The following table lists common values for the ai_protocol member although many other values are possible. + /// + /// + /// Value + /// Meaning + /// + /// + /// IPPROTO_TCP 6 + /// + /// The Transmission Control Protocol (TCP). This is a possible value when the ai_family member is AF_INET or AF_INET6 and the + /// ai_socktype member is SOCK_STREAM. + /// + /// + /// + /// IPPROTO_UDP 17 + /// + /// The User Datagram Protocol (UDP). This is a possible value when the ai_family member is AF_INET or AF_INET6 and the type + /// parameter is SOCK_DGRAM. + /// + /// + /// + /// IPPROTO_RM 113 + /// + /// The PGM protocol for reliable multicast. This is a possible value when the ai_family member is AF_INET and the ai_socktype + /// member is SOCK_RDM. On the Windows SDK released for Windows Vista and later, this value is also called IPPROTO_PGM. + /// + /// + /// + /// If the ai_family member is AF_IRDA, then the ai_protocol must be 0. + /// + public IPPROTO ai_protocol; + + /// + /// Type: size_t + /// The length, in bytes, of the buffer pointed to by the ai_addr member. + /// + public SizeT ai_addrlen; + + /// + /// Type: char* + /// The canonical name for the host. + /// + public StrPtrUni ai_canonname; + + /// + /// Type: struct sockaddr* + /// + /// A pointer to a sockaddr structure. The ai_addr member in each returned addrinfo structure points to a + /// filled-in socket address structure. The length, in bytes, of each returned addrinfo structure is specified in the + /// ai_addrlen member. + /// + /// + public IntPtr ai_addr; + + /// + /// Type: struct addrinfo* + /// + /// A pointer to the next structure in a linked list. This parameter is set to NULL in the last addrinfo structure + /// of a linked list. + /// + /// + public IntPtr ai_next; + + /// + /// Type: struct sockaddr* + /// + /// A pointer to a sockaddr structure. The ai_addr member in each returned ADDRINFOW structure points to a filled-in + /// socket address structure. The length, in bytes, of each returned ADDRINFOW structure is specified in the + /// ai_addrlen member. + /// + /// + public SOCKADDR addr => new(ai_addr, false, ai_addrlen); + + /// + public override string ToString() => $"{ai_canonname}:{ai_flags},{ai_family},{ai_socktype},{ai_protocol},{addr}"; + } + + /// The scope identifier for the IPv6 transport address. + [PInvokeData("ws2def.h")] + [StructLayout(LayoutKind.Sequential)] + public struct SCOPE_ID + { + /// A ULONG representation of the IPv6 scope identifier. + public uint Value; + + /// + /// + /// The zone index that identifies the zone to which the transport address pertains. Zones of the different scopes are + /// instantiated as follows: + /// + /// + /// Each interface on a node comprises a single zone of interface-local scope. + /// Each link, and the interfaces attached to that link, comprise a single zone of link-local scope. + /// There is a single zone of global scope that comprises all of the links and interfaces in the Internet. + /// The boundaries of zones of scope other than interface-local, link-local, and global are defined by network administrators. + /// + /// A value of zero specifies the default zone. + /// + /// The zone index. + public uint Zone + { + get => BitHelper.GetBits(Value, 0, 28); + set => BitHelper.SetBits(ref Value, 0, 28, value); + } + + /// + /// + /// The scope of the IPv6 transport address. This scope must be the same as the IPv6 scope value that is embedded in the IPv6 + /// transport address. This member can be one of the following: + /// + /// ScopeLevelInterface + /// The transport address has interface-local scope. + /// ScopeLevelLink + /// The transport address has link-local scope. + /// ScopeLevelSubnet + /// The transport address has subnet-local scope. + /// ScopeLevelAdmin + /// The transport address has admin-local scope. + /// ScopeLevelSite + /// The transport address has site-local scope. + /// ScopeLevelOrganization + /// The transport address has organization-local scope. + /// ScopeLevelGlobal + /// The transport address has global scope. + /// + /// The level. + public byte Level + { + get => (byte)BitHelper.GetBits(Value, 28, 4); + set => BitHelper.SetBits(ref Value, 28, 4, value); + } + } + + /// The SOCKADDR_IN structure specifies a transport address and port for the AF_INET address family. + /// + /// All of the data in the SOCKADDR_IN structure, except for the address family, must be specified in network-byte-order (big-endian). + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-sockaddr_in typedef struct sockaddr_in { #if ... short + // sin_family; #else ADDRESS_FAMILY sin_family; #endif USHORT sin_port; IN_ADDR sin_addr; CHAR sin_zero[8]; } SOCKADDR_IN, *PSOCKADDR_IN; + [PInvokeData("ws2def.h", MSDNShortId = "96379562-403f-451c-ac7a-f0eec34bfe5e")] + [StructLayout(LayoutKind.Sequential, Pack = 2)] + public struct SOCKADDR_IN + { + /// The address family for the transport address. This member should always be set to AF_INET. + public ADDRESS_FAMILY sin_family; + + /// A transport protocol port number. + public ushort sin_port; + + /// An IN_ADDR structure that contains an IPv4 transport address. + public IN_ADDR sin_addr; + + /// Reserved for system use. A WSK application should set the contents of this array to zero. + public ulong sin_zero; + + /// Initializes a new instance of the struct. + /// An IN_ADDR structure that contains an IPv4 transport address. + /// A transport protocol port number. + public SOCKADDR_IN(IN_ADDR addr, ushort port = 0) + { + sin_family = ADDRESS_FAMILY.AF_INET; + sin_port = port; + sin_addr = addr; + sin_zero = 0; + } + + /// Performs an implicit conversion from to . + /// The addr. + /// The resulting instance from the conversion. + public static implicit operator SOCKADDR_IN(IN_ADDR addr) => new(addr); + + /// Performs an explicit conversion from to . + /// The ipv4 address. + /// The resulting instance from the conversion. + public static explicit operator SOCKADDR_IN6(SOCKADDR_IN ipv4) => new(ipv4); + + /// Converts to string. + /// A that represents this instance. + public override string ToString() => $"{sin_addr}:{sin_port}"; + } + + /// The SOCKADDR_STORAGE structure is a generic structure that specifies a transport address. + /// + /// A WSK application typically does not directly access any of the members of the SOCKADDR_STORAGE structure except for the + /// ss_family member. Instead, a pointer to a SOCKADDR_STORAGE structure is normally cast to a pointer to the specific + /// SOCKADDR structure type that corresponds to a particular address family. + /// + // https://docs.microsoft.com/ja-jp/windows/desktop/api/ws2def/ns-ws2def-sockaddr_storage_lh typedef struct sockaddr_storage { + // ADDRESS_FAMILY ss_family; CHAR __ss_pad1[_SS_PAD1SIZE]; __int64 __ss_align; CHAR __ss_pad2[_SS_PAD2SIZE]; } SOCKADDR_STORAGE_LH, + // *PSOCKADDR_STORAGE_LH, *LPSOCKADDR_STORAGE_LH; + [PInvokeData("ws2def.h", MSDNShortId = "27e56c1a-ce11-4cdb-9be8-25ed2f94fb37")] + [StructLayout(LayoutKind.Sequential, Pack = 8)] + public struct SOCKADDR_STORAGE + { + /// + /// The address family for the transport address. For more information about supported address families, see WSK Address Families. + /// + public ADDRESS_FAMILY ss_family; + + /// A padding of 6 bytes that puts the __ss_align member on an eight-byte boundary within the structure. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 6)] + public byte[] __ss_pad1; + + /// A 64-bit value that forces the structure to be 8-byte aligned. + public long __ss_align; + + /// A padding of an additional 112 bytes that brings the total size of the SOCKADDR_STORAGE structure to 128 bytes. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 112)] + public byte[] __ss_pad2; + + /// Performs an explicit conversion from to . + /// The address. + /// The resulting instance from the conversion. + public static explicit operator SOCKADDR_STORAGE(in SOCKADDR_IN6 addr) + { + using var mem = SafeHGlobalHandle.CreateFromStructure(addr); + mem.Size = Marshal.SizeOf(typeof(SOCKADDR_STORAGE)); + return mem.ToStructure(); + } + + /// Performs an explicit conversion from to . + /// The address. + /// The resulting instance from the conversion. + public static explicit operator SOCKADDR_STORAGE(in SOCKADDR_IN addr) + { + using var mem = SafeHGlobalHandle.CreateFromStructure(addr); + mem.Size = Marshal.SizeOf(typeof(SOCKADDR_STORAGE)); + return mem.ToStructure(); + } + + /// Performs an explicit conversion from to . + /// The address. + /// The resulting instance from the conversion. + public static explicit operator SOCKADDR_STORAGE(SOCKADDR addr) + { + using var mem = new SafeHGlobalHandle(addr.GetAddressBytes()); + mem.Size = Marshal.SizeOf(typeof(SOCKADDR_STORAGE)); + return mem.ToStructure(); + } + + /// Performs an explicit conversion from to . + /// The address. + /// The resulting instance from the conversion. + public static explicit operator SOCKADDR_STORAGE(IPAddress addr) + { + using var mem = new SafeHGlobalHandle(addr.GetAddressBytes()); + mem.Size = Marshal.SizeOf(typeof(SOCKADDR_STORAGE)); + return mem.ToStructure(); + } + + /// Performs an explicit conversion from to . + /// The address. + /// The resulting instance from the conversion. + public static explicit operator SOCKADDR_STORAGE(SOCKADDR_INET addr) + { + using var mem = SafeHGlobalHandle.CreateFromStructure(addr); + mem.Size = Marshal.SizeOf(typeof(SOCKADDR_STORAGE)); + return mem.ToStructure(); + } + + /// Performs an explicit conversion from to . + /// The addr. + /// The resulting instance from the conversion. + public static explicit operator SOCKADDR(SOCKADDR_STORAGE addr) => SOCKADDR.CreateFromStructure(addr); + + /// Performs an explicit conversion from to . + /// The addr. + /// The resulting instance from the conversion. + public static explicit operator SOCKADDR_IN(SOCKADDR_STORAGE addr) => (SOCKADDR_IN)SOCKADDR.CreateFromStructure(addr); + + /// Performs an explicit conversion from to . + /// The addr. + /// The resulting instance from the conversion. + public static explicit operator SOCKADDR_IN6(SOCKADDR_STORAGE addr) => (SOCKADDR_IN6)SOCKADDR.CreateFromStructure(addr); + + /// Performs an explicit conversion from to . + /// The addr. + /// The resulting instance from the conversion. + public static explicit operator SOCKADDR_INET(SOCKADDR_STORAGE addr) => (SOCKADDR_INET)SOCKADDR.CreateFromStructure(addr); + } + + /// The SOCKET_ADDRESS structure stores protocol-specific address information. + /// + /// + /// The SOCKADDR structure pointed to by the lpSockaddr member varies depending on the protocol or address family selected. + /// For example, the sockaddr_in6 structure is used for an IPv6 socket address while the sockaddr_in4 structure is + /// used for an IPv4 socket address. The address family is the first member of all of the SOCKADDR structures. The address + /// family is used to determine which structure is used. + /// + /// + /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files + /// has changed and the SOCKET_ADDRESS structure is defined in the Ws2def.h header file. Note that the Ws2def.h header file + /// is automatically included in Winsock2.h, and should never be used directly. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-socket_address typedef struct _SOCKET_ADDRESS { LPSOCKADDR + // lpSockaddr; INT iSockaddrLength; } SOCKET_ADDRESS, *PSOCKET_ADDRESS, *LPSOCKET_ADDRESS; + [PInvokeData("ws2def.h", MSDNShortId = "37fbcb96-a859-4eca-8928-8051f95407b9")] + [StructLayout(LayoutKind.Sequential, +#if x64 + Size = 16)] +#else + Size = 8)] +#endif + public struct SOCKET_ADDRESS + { + /// A pointer to a socket address represented as a SOCKADDR structure. + public IntPtr lpSockaddr; + + /// The length, in bytes, of the socket address. + public int iSockaddrLength; + + /// Gets the from this instance. + /// The value pointed to by this instance. + public SOCKADDR_INET GetSOCKADDR() => lpSockaddr.ToStructure(iSockaddrLength); + + /// Performs an implicit conversion from to . + /// The address. + /// The result of the conversion. + public static implicit operator SOCKADDR(SOCKET_ADDRESS address) => new(address); + + /// Converts to string. + /// A that represents this instance. + public override string ToString() => GetSOCKADDR().ToString(); + } + + /// The SOCKET_ADDRESS_LIST structure defines a variable-sized list of transport addresses. + /// + /// + /// A WSK application passes a buffer to the WskControlSocket function when the WSK application queries the current list of local + /// transport addresses that match a socket's address family. If the call to the WskControlSocket function succeeds, the + /// buffer contains a SOCKET_ADDRESS_LIST structure followed by the SOCKADDR structures for each of the local transport addresses + /// that match the socket's address family. The WSK subsystem fills in the Address array and sets the iAddressCount + /// member to the number of entries in the array. The lpSockaddr pointers in each of the SOCKET_ADDRESS structures in the + /// array point to the specific SOCKADDR structure type that corresponds to the address family that the WSK application specified + /// when it created the socket. + /// + /// For more information about querying the current list of local transport addresses, see SIO_ADDRESS_LIST_QUERY. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-socket_address_list typedef struct _SOCKET_ADDRESS_LIST { INT + // iAddressCount; SOCKET_ADDRESS Address[1]; } SOCKET_ADDRESS_LIST, *PSOCKET_ADDRESS_LIST, *LPSOCKET_ADDRESS_LIST; + [PInvokeData("ws2def.h", MSDNShortId = "b005200b-b0c2-4f19-8765-cd26fbfc0cff")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), nameof(iAddressCount))] + [StructLayout(LayoutKind.Sequential)] + public struct SOCKET_ADDRESS_LIST + { + /// The number of transport addresses in the list. + public int iAddressCount; + + /// A variable-sized array of SOCKET_ADDRESS structures. The SOCKET_ADDRESS structure is defined as follows: + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public SOCKET_ADDRESS[] Address; + + /// Packs this instance into a single memory block so that it can be passed as a pointer to other API methods. + /// + /// A instance that contains this structure and all memeroy assigned to its elements. + /// + public SafeCoTaskMemStruct Pack() + { + var addrOffset = Marshal.OffsetOf(typeof(SOCKET_ADDRESS_LIST), "Address").ToInt32(); + var eosOffset = addrOffset + iAddressCount * Marshal.SizeOf(typeof(SOCKET_ADDRESS)); + var cbAddressList = eosOffset + Address.Sum(a => a.iSockaddrLength); + + var addressList = new SafeCoTaskMemStruct(cbAddressList); + ((IntPtr)addressList).Write(iAddressCount); + var newAddr = new SOCKET_ADDRESS[iAddressCount]; + var ptr = ((IntPtr)addressList).Offset(eosOffset); + for (int i = 0; i < iAddressCount; i++) + { + newAddr[i] = new SOCKET_ADDRESS { iSockaddrLength = Address[i].iSockaddrLength, lpSockaddr = ptr }; + Address[i].lpSockaddr.CopyTo(ptr, Address[i].iSockaddrLength); + ptr = ptr.Offset(Address[i].iSockaddrLength); + } + ((IntPtr)addressList).Write(newAddr, addrOffset); + return addressList; + } + } + + /// + /// The SOCKET_PROCESSOR_AFFINITY structure contains the association between a socket and an RSS processor core and NUMA node.. + /// + /// + /// + /// The SOCKET_PROCESSOR_AFFINITY structure is supported on Windows 8, and Windows Server 2012, and later versions of the + /// operating system. + /// + /// + /// The SIO_QUERY_RSS_PROCESSOR_INFO IOCTL is used to determine the association between a socket and an RSS processor core and NUMA + /// node. This IOCTL returns a SOCKET_PROCESSOR_AFFINITY structure that contains the processor number and the NUMA node ID. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-socket_processor_affinity typedef struct + // _SOCKET_PROCESSOR_AFFINITY { PROCESSOR_NUMBER Processor; USHORT NumaNodeId; USHORT Reserved; } SOCKET_PROCESSOR_AFFINITY, *PSOCKET_PROCESSOR_AFFINITY; + [PInvokeData("ws2def.h", MSDNShortId = "CB1E9F79-C6BD-40C2-8D0F-36B24B1BBBF4")] + [StructLayout(LayoutKind.Sequential)] + public struct SOCKET_PROCESSOR_AFFINITY + { + /// + /// A structure to represent a system wide processor number. This PROCESSOR_NUMBER structure contains a group number and + /// relative processor number within the group. + /// + public Kernel32.PROCESSOR_NUMBER Processor; + + /// The NUMA node ID. + public ushort NumaNodeId; + + /// A value reserved for future use. + public ushort Reserved; + } + + /// The WSABUF structure enables the creation or manipulation of a data buffer used by some Winsock functions. + // https://docs.microsoft.com/en-us/windows/desktop/api/ws2def/ns-ws2def-_wsabuf typedef struct _WSABUF { ULONG len; CHAR *buf; } + // WSABUF, *LPWSABUF; + [PInvokeData("ws2def.h", MSDNShortId = "a012c3ba-67fd-4fcf-84d1-85e9d495c29c")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct WSABUF + { + /// The length of the buffer, in bytes. + public uint len; + + /// A pointer to the buffer. + public IntPtr buf; + } + + /// The CMSGHDR structure defines the header for a control data object that is associated with a datagram. + /// + /// The control information data that is associated with a datagram is made up of one or more control data objects. Each object + /// begins with a CMSGHDR structure. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-wsacmsghdr typedef struct _WSACMSGHDR { SIZE_T cmsg_len; INT + // cmsg_level; INT cmsg_type; } WSACMSGHDR, *PWSACMSGHDR, *LPWSACMSGHDR; + [PInvokeData("ws2def.h", MSDNShortId = "NS:ws2def._WSACMSGHDR")] + [StructLayout(LayoutKind.Sequential)] + public struct WSACMSGHDR + { + /// + /// The number of bytes from the beginning of the CMSGHDR structure to the end of the control data. + /// Note The value of the cmsg_len member does not account for any padding that may follow the control data. + /// + public SizeT cmsg_len; + + /// The protocol that originated the control information. + public int cmsg_level; + + /// The protocol-specific type of control information. + public int cmsg_type; + } + + /// + /// The WSAMSG structure is used with the WSARecvMsg and WSASendMsg functions to store address and optional control + /// information about connected and unconnected sockets as well as an array of buffers used to store message data. + /// + /// + /// + /// In the Microsoft Windows Software Development Kit (SDK), the version of this structure for use on Windows Vistais defined with + /// the data type for the dwBufferCount and dwFlags members as a ULONG. When compiling an application if the + /// target platform is Windows Vista and later ( NTDDI_VERSION >= NTDDI_LONGHORN, _WIN32_WINNT >= 0x0600, or WINVER + /// >= 0x0600), the data type for the dwBufferCount and dwFlags members is a ULONG. + /// + /// + /// Windows Server 2003 and Windows XP: When compiling an application, the data type for the dwBufferCount and + /// dwFlags members is a DWORD. + /// + /// + /// On the Windows SDK released for Windows Vista and later, the WSAMSG structure is defined in the Ws2def.h header file. + /// Note that the Ws2def.h header file is automatically included in Winsock2.h, and should never be used directly + /// + /// + /// If the datagram or control data is truncated during the transmission, the function being used in association with the + /// WSAMSG structure returns SOCKET_ERROR and a call to the WSAGetLastError function returns WSAEMSGSIZE. It is up to the + /// application to determine what was truncated by checking for MSG_TRUNC and/or MSG_CTRUNC flags. + /// + /// Use of the Control Member + /// + /// The following table summarizes the various uses of control data available for use in the Control member for IPv4 and IPv6. + /// + /// + /// + /// Protocol + /// cmsg_level + /// cmsg_type + /// Description + /// + /// + /// IPv4 + /// IPPROTO_IP + /// IP_ORIGINAL_ARRIVAL_IF + /// + /// Receives the original IPv4 arrival interface where the packet was received for datagram sockets. This control data is used by + /// firewalls when a Teredo, 6to4, or ISATAP tunnel is used for IPv4 NAT traversal. The cmsg_data[] member in the WSAMSG structure + /// is a ULONG that contains the IF_INDEX defined in the Ifdef.h header file. For more information, see the IPPROTO_IP Socket + /// Options for the IP_ORIGINAL_ARRIVAL_IF socket option. Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: + /// The IP_ORIGINAL_ARRIVAL_IF cmsg_type is not supported. + /// + /// + /// + /// IPv4 + /// IPPROTO_IP + /// IP_PKTINFO + /// Specifies/receives packet information for an IPv4 socket. For more information, see the IP_PKTINFO socket option. + /// + /// + /// IPv6 + /// IPPROTO_IPV6 + /// IPV6_DSTOPTS + /// Specifies/receives destination options. + /// + /// + /// IPv6 + /// IPPROTO_IPV6 + /// IPV6_HOPLIMIT + /// Specifies/receives hop limit. For more information, see the IPPROTO_IPV6 Socket Options for the IPV6_HOPLIMIT socket option. + /// + /// + /// IPv6 + /// IPPROTO_IPV6 + /// IPV6_HOPOPTS + /// Specifies/receives hop-by-hop options. + /// + /// + /// IPv6 + /// IPPROTO_IPV6 + /// IPV6_NEXTHOP + /// Specifies next-hop address. + /// + /// + /// IPv6 + /// IPPROTO_IPV6 + /// IPV6_PKTINFO + /// Specifies/receives packet information for an IPv6 socket. For more information, see the IPV6_PKTINFO socket option. + /// + /// + /// IPv6 + /// IPPROTO_IPV6 + /// IPV6_RTHDR + /// Specifies/receives routing header. + /// + /// + /// + /// Control data is made up of one or more control data objects, each beginning with a WSACMSGHDR structure, defined as the following. + /// + /// + /// Note The transport, not the application, fills out the header information in the WSACMSGHDR structure. The + /// application simply sets the needed socket options and provides the adequate buffer size. + /// + /// The members of the WSACMSGHDR structure are as follows: + /// + /// + /// Term + /// Description + /// + /// + /// cmsg_len + /// + /// The number of bytes of data starting from the beginning of the WSACMSGHDR to the end of data (excluding padding bytes that may + /// follow data). + /// + /// + /// + /// cmsg_level + /// The protocol that originated the control information. + /// + /// + /// cmsg_type + /// The protocol-specific type of control information. + /// + /// + /// The following macros are used to navigate the data objects: + /// + /// Returns a pointer to the first control data object. Returns a NULL pointer if there is no control data in the + /// WSAMSG structure, such as when the Control member is a NULL pointer. + /// + /// + /// Returns a pointer to the next control data object, or NULL if there are no more data objects. If the pcmsg parameter is + /// NULL, a pointer to the first control data object is returned. + /// + /// + /// Returns a pointer to the first byte of data (referred to as the cmsg_data member, though it is not defined in the structure). + /// + /// + /// Returns the total size of a control data object, given the amount of data. Used to allocate the correct amount of buffer space. + /// Includes alignment padding. + /// + /// Returns the value in cmsg_len given the amount of data. Includes alignment padding. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2def/ns-ws2def-wsamsg typedef struct _WSAMSG { LPSOCKADDR name; INT namelen; + // LPWSABUF lpBuffers; #if ... ULONG dwBufferCount; #else DWORD dwBufferCount; #endif WSABUF Control; #if ... ULONG dwFlags; #else + // DWORD dwFlags; #endif } WSAMSG, *PWSAMSG, *LPWSAMSG; + [PInvokeData("ws2def.h", MSDNShortId = "105a6e2c-1edf-4ec0-a1c2-ac0bcafeda30")] + [StructLayout(LayoutKind.Sequential)] + public struct WSAMSG + { + /// + /// Type: LPSOCKADDR + /// + /// A pointer to a SOCKET_ADDRESS structure that stores information about the remote address. Used only with unconnected sockets. + /// + /// + public IntPtr name; + + /// + /// Type: INT + /// + /// The length, in bytes, of the SOCKET_ADDRESS structure pointed to in the pAddr member. Used only with unconnected sockets. + /// + /// + public int namelen; + + /// + /// Type: LPWSABUF + /// + /// An array of WSABUF structures used to receive the message data. The capability of the lpBuffers member to contain + /// multiple buffers enables the use of scatter/gather I/O. + /// + /// + public IntPtr lpBuffers; + + /// + /// Type: DWORD + /// The number of buffers pointed to in the lpBuffers member. + /// + public uint dwBufferCount; + + /// + /// Type: WSABUF + /// A structure of WSABUF type used to specify optional control data. See Remarks. + /// + public WSABUF Control; + + /// + /// Type: DWORD + /// + /// One or more control flags, specified as the logical OR of values. The possible values for dwFlags member on + /// input are defined in the Winsock2.h header file. The possible values for dwFlags member on output are defined in the + /// Ws2def.h header file which is automatically included by the Winsock2.h header file. + /// + /// + /// + /// Flags on input + /// Meaning + /// + /// + /// MSG_PEEK + /// + /// Peek at the incoming data. The data is copied into the buffer, but is not removed from the input queue. This flag is valid + /// only for non-overlapped sockets. + /// + /// + /// + /// + /// + /// Flag returned + /// Meaning + /// + /// + /// MSG_BCAST + /// The datagram was received as a link-layer broadcast or with a destination IP address that is a broadcast address. + /// + /// + /// MSG_MCAST + /// The datagram was received with a destination IP address that is a multicast address. + /// + /// + /// MSG_TRUNC + /// The datagram was truncated. More data was present than the process allocated room for. + /// + /// + /// MSG_CTRUNC + /// The control (ancillary) data was truncated. More control data was present than the process allocated room for. + /// + /// + /// + public MsgFlags dwFlags; + } + + /// + /// + /// Some of the socket IOCTL opcodes for Windows Sockets 2 are summarized in the following table. More detailed information is in + /// the Winsock reference on Winsock IOCTLs and the WSPIoctl function. There are other new protocol-specific IOCTL + /// opcodes that can be found in the protocol-specific annex. + /// + /// A complete list of Winsock IOCTLs are available in the Winsock reference. + /// + // https://docs.microsoft.com/en-us/windows/win32/winsock/summary-of-socket-ioctl-opcodes-2 + [PInvokeData("ws2def.h", MSDNShortId = "fb6447b4-28f5-4ab7-bbdc-5a57ed38a994")] + public static class WinSockIOControlCode + { + /// + /// Determine the amount of data that can be read atomically from socket s. The lpvOutBuffer parameter points at an unsigned long + /// in which WSAIoctl stores the result. + /// + /// If the socket passed in the s parameter is stream oriented(for example, type SOCK_STREAM), FIONREAD returns the total amount + /// of data that can be read in a single receive operation; this is normally the same as the total amount of data queued on the + /// socket(since a data stream is byte-oriented, this is not guaranteed). + /// + /// + /// If the socket passed in the s parameter is message oriented(for example, type SOCK_DGRAM), FIONREAD returns the reports the + /// total number of bytes available to read, not the size of the first datagram(message) queued on the socket. + /// + /// + public static readonly uint FIONREAD = _IOR('f', 127); /* get # bytes to read */ + + /// + /// Enable or disable non-blocking mode on socket s. The lpvInBuffer parameter points at an unsigned long (QoS), which is nonzero + /// if non-blocking mode is to be enabled and zero if it is to be disabled. When a socket is created, it operates in blocking + /// mode (that is, non-blocking mode is disabled). This is consistent with BSD sockets. + /// + /// The WSAAsyncSelect or WSAEventSelect routine automatically sets a socket to non-blocking mode.If WSAAsyncSelect or + /// WSAEventSelect has been issued on a socket, then any attempt to use WSAIoctl to set the socket back to blocking mode will + /// fail with WSAEINVAL. To set the socket back to blocking mode, an application must first disable WSAAsyncSelect by calling + /// WSAAsyncSelect with the lEvent parameter equal to zero, or disable WSAEventSelect by calling WSAEventSelect with the + /// lNetworkEvents parameter equal to zero. + /// + /// + public static readonly uint FIONBIO = _IOW('f', 126); /* set/clear non-blocking i/o */ + + /// Enable notification for when data is waiting to be received. + public static readonly uint FIOASYNC = _IOW('f', 125); /* set/clear async i/o */ + + /// Requests notification of changes in information reported through SIO_ADDRESS_LIST_QUERY + public static readonly uint SIO_ADDRESS_LIST_CHANGE = _WSAIO(IOC_WS2, 23); + + /// + /// Obtains a list of local transport addresses of the socket's protocol family to which the application can bind. The list of + /// addresses varies based on address family and some addresses are excluded from the list. + /// + [CorrespondingType(typeof(SOCKET_ADDRESS), CorrespondingAction.Get)] + public static readonly uint SIO_ADDRESS_LIST_QUERY = _WSAIOR(IOC_WS2, 22); + + /// + /// Allows application developers to sort a list of IPv6 and IPv4 destination addresses to determine the best available address + /// for making a connection. + /// + [CorrespondingType(typeof(SOCKET_ADDRESS_LIST), CorrespondingAction.GetSet)] + public static readonly uint SIO_ADDRESS_LIST_SORT = _WSAIORW(IOC_WS2, 25); + + /// Associates the socket with the specified handle of a companion interface. + public static readonly uint SIO_ASSOCIATE_HANDLE = _WSAIOW(IOC_WS2, 1); + + /// Enables circular queuing. + public static readonly uint SIO_ENABLE_CIRCULAR_QUEUEING = _WSAIO(IOC_WS2, 2); + + /// Requests the route to the specified address to be discovered. + [CorrespondingType(typeof(SOCKADDR), CorrespondingAction.Set)] + public static readonly uint SIO_FIND_ROUTE = _WSAIOR(IOC_WS2, 3); + + /// Discards current contents of the sending queue. + public static readonly uint SIO_FLUSH = _WSAIO(IOC_WS2, 4); + + /// Retrieves the protocol-specific broadcast address to be used in WSPSendTo. + [CorrespondingType(typeof(SOCKADDR), CorrespondingAction.Get)] + public static readonly uint SIO_GET_BROADCAST_ADDRESS = _WSAIOR(IOC_WS2, 5); + + /// Gets the function pointer for the WSASendMsg function obtained at run time. + public static readonly uint SIO_GET_EXTENSION_FUNCTION_POINTER = _WSAIORW(IOC_WS2, 6); + + /// Reserved. + [CorrespondingType(typeof(QOS), CorrespondingAction.Get)] + public static readonly uint SIO_GET_GROUP_QOS = _WSAIORW(IOC_WS2, 8); + + /// Retrieves current flow specifications for the socket. + [CorrespondingType(typeof(QOS), CorrespondingAction.Get)] + public static readonly uint SIO_GET_QOS = _WSAIORW(IOC_WS2, 7); + + /// Specifies the scope over which multicast transmissions will occur. + [CorrespondingType(typeof(int), CorrespondingAction.Set)] + public static readonly uint SIO_MULTICAST_SCOPE = _WSAIOW(IOC_WS2, 10); + + /// Controls whether data sent in a multipoint session will also be received by the same socket on the local host. + [CorrespondingType(typeof(BOOL), CorrespondingAction.Set)] + public static readonly uint SIO_MULTIPOINT_LOOPBACK = _WSAIOW(IOC_WS2, 9); + + /// Queries the association between a socket and an RSS processor core and NUMA node. + [CorrespondingType(typeof(SOCKET_PROCESSOR_AFFINITY), CorrespondingAction.Get)] + public static readonly uint SIO_QUERY_RSS_PROCESSOR_INFO = _WSAIOR(IOC_WS2, 37); + + /// Obtains socket descriptor of the next provider in the chain on which current socket depends in regards to PnP. + [CorrespondingType(typeof(SOCKET), CorrespondingAction.Get)] + public static readonly uint SIO_QUERY_TARGET_PNP_HANDLE = _WSAIOR(IOC_WS2, 24); + + /// + /// Requests notification of changes in information reported through SIO_ROUTING_INTERFACE_QUERY for the specified address. + /// + [CorrespondingType(typeof(SOCKADDR), CorrespondingAction.Set)] + public static readonly uint SIO_ROUTING_INTERFACE_CHANGE = _WSAIOW(IOC_WS2, 21); + + /// Obtains the address of the local interface that should be used to send to the specified address. + [CorrespondingType(typeof(SOCKADDR), CorrespondingAction.GetSet)] + public static readonly uint SIO_ROUTING_INTERFACE_QUERY = _WSAIORW(IOC_WS2, 20); + + /// Reserved. + [CorrespondingType(typeof(QOS), CorrespondingAction.Set)] + public static readonly uint SIO_SET_GROUP_QOS = _WSAIOW(IOC_WS2, 12); + + /// Establishes new flow specifications for the socket. + [CorrespondingType(typeof(QOS), CorrespondingAction.Set)] + public static readonly uint SIO_SET_QOS = _WSAIOW(IOC_WS2, 11); + + /// Obtains a corresponding handle for socket s that is valid in the context of a companion interface. + [CorrespondingType(typeof(int), CorrespondingAction.Set)] + public static readonly uint SIO_TRANSLATE_HANDLE = _WSAIORW(IOC_WS2, 13); + + /// set high watermark + public static readonly uint SIOCSHIWAT = _IOW('s', 0); /* set high watermark */ + + /// get high watermark + public static readonly uint SIOCGHIWAT = _IOR('s', 1); /* get high watermark */ + + /// set low watermark + public static readonly uint SIOCSLOWAT = _IOW('s', 2); /* set low watermark */ + + /// get low watermark + public static readonly uint SIOCGLOWAT = _IOR('s', 3); /* get low watermark */ + + /// + /// Determine whether or not all OOB data has been read. This applies only to a socket of stream-style (for example, type + /// SOCK_STREAM) that has been configured for inline reception of any OOB data (SO_OOBINLINE). If no OOB data is waiting to be + /// read, the operation returns TRUE. Otherwise, it returns FALSE, and the next receive operation performed on the socket will + /// retrieve some or all of the data preceding the mark; the application should use the SIOCATMARK operation to determine whether + /// any remains. If there is any normal data preceding the urgent (out of band) data, it will be received in order. (Note that + /// recv operations will never mix OOB and normal data in the same call.) lpvOutBuffer points at a BOOL in which WSAIoctl stores + /// the result. + /// + public static readonly uint SIOCATMARK = _IOR('s', 7); /* at oob mark? */ + + private const uint IOCPARM_MASK = 0x7f; /* parameters must be < 128 bytes */ + private const uint IOC_VOID = 0x20000000; /* no parameters */ + private const uint IOC_OUT = 0x40000000; /* copy out parameters */ + private const uint IOC_IN = 0x80000000; /* copy in parameters */ + private const uint IOC_INOUT = IOC_IN|IOC_OUT; + private const uint IOC_PROTOCOL = 0x10000000; + private const uint IOC_UNIX = 0x00000000; + private const uint IOC_VENDOR = 0x18000000; + private const uint IOC_WS2 = 0x08000000; + private const uint IOC_WSK = IOC_WS2 | 0x07000000; + + private static uint _IO(uint x, uint y) => (IOC_VOID|((x)<<8)|(y)); + + private static uint _IOR(uint x, uint y) => (IOC_OUT|((sizeof(uint)&IOCPARM_MASK)<<16)|((x)<<8)|(y)); + + private static uint _IOW(uint x, uint y) => (IOC_IN|((sizeof(uint)&IOCPARM_MASK)<<16)|((x)<<8)|(y)); + + private static uint _WSAIO(uint x, uint y) => IOC_VOID | (x) | (y); + + private static uint _WSAIOR(uint x, uint y) => IOC_OUT | (x) | (y); + + private static uint _WSAIORW(uint x, uint y) => IOC_INOUT | (x) | (y); + + private static uint _WSAIOW(uint x, uint y) => IOC_IN | (x) | (y); + } } \ No newline at end of file diff --git a/PInvoke/Ws2_32/ws2ipdef.cs b/PInvoke/Ws2_32/ws2ipdef.cs index 4f703b47..ff8947ff 100644 --- a/PInvoke/Ws2_32/ws2ipdef.cs +++ b/PInvoke/Ws2_32/ws2ipdef.cs @@ -4,808 +4,807 @@ using Vanara.Extensions; using Vanara.InteropServices; #pragma warning disable IDE1006 // Naming Styles -namespace Vanara.PInvoke +namespace Vanara.PInvoke; + +public static partial class Ws2_32 { - public static partial class Ws2_32 + /// + public const int IN6ADDR_LINKLOCALPREFIX_LENGTH = 64; + + /// + public const int IN6ADDR_MULTICASTPREFIX_LENGTH = 8; + + /// + public const int IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_LENGTH = 104; + + /// + public const int IN6ADDR_V4MAPPEDPREFIX_LENGTH = 96; + + /// + public const int IN6ADDR_6TO4PREFIX_LENGTH = 16; + + /// + public const int IN6ADDR_TEREDOPREFIX_LENGTH = 32; + + /// + public const int INET_ADDRSTRLEN = 22; + + /// + public const int INET6_ADDRSTRLEN = 65; + + /// + public const uint IOC_IN = 0x80000000; + + /// + public const uint IOC_INOUT = IOC_IN | IOC_OUT; + + /// + public const uint IOC_OUT = 0x40000000; + + /// + public const uint IOC_VOID = 0x20000000; + + /// + public const uint IOCPARM_MASK = 0x7f; + + /// + /// It is used to return information about each interface on the local machine. Nothing is required on input, but on output, an array of INTERFACE_INFO structures is returned. + /// + public static readonly uint SIO_GET_INTERFACE_LIST = _IOR('t', 127, typeof(uint)); + + /// + /// This ioctl is the same as SIO_GET_INTERFACE_LIST except the structure returned contains embedded SOCKET_ADDRESS structure to describe each local interface, as opposed to SOCKADDR_GEN structure. This removes the dependency the size of the socket address structure. + /// + public static readonly uint SIO_GET_INTERFACE_LIST_EX = _IOR('t', 126, typeof(uint)); + + /// + /// This ioctl retrieves the multicast filter set on a given socket. The multicast state is set with the SIO_SET_MULTICAST_FILTER ioctl. This ioctl requires an IGMPv3-enabled network and is supported in only Windows XP. + /// + public static readonly uint SIO_GET_MULTICAST_FILTER = _IOW('t', 124 | IOC_IN, typeof(uint)); + + /// + /// This ioctl sets the multicast state. The input parameter is a struct ip_msfilter. + /// + public static readonly uint SIO_SET_MULTICAST_FILTER = _IOW('t', 125, typeof(uint)); + + /// + /// This ioctl retrieves the multicast filter set on a given socket. The multicast state is set with the SIO_SET_MULTICAST_FILTER ioctl. This ioctl requires an IGMPv3-enabled network and is supported in only Windows XP. + /// + public static readonly uint SIOCGIPMSFILTER = SIO_GET_MULTICAST_FILTER; + + /// + /// Enables an application to retrieve a list of the IPv4 or IPv6 source addresses that comprise the source filter along with the current mode on a given interface index and a multicast group for a socket. The source filter may either include or exclude the set of source address, depending on the filter mode (MCAST_INCLUDE or MCAST_EXCLUDE), which is defined in the GROUP_FILTER structure. + /// + public static readonly uint SIOCGMSFILTER = _IOW('t', 127 | IOC_IN, typeof(uint)); + + /// + /// This ioctl sets the multicast state. The input parameter is a struct ip_msfilter. + /// + public static readonly uint SIOCSIPMSFILTER = SIO_SET_MULTICAST_FILTER; + + /// + /// Enables an application to specify or modify a list of IPv4 or IPv6 source addresses on a given interface index and to specify or modify a multicast group for a socket. The source filter can include or exclude the set of source address, depending on the filter mode (MCAST_INCLUDE or MCAST_EXCLUDE), which is defined in the GROUP_FILTER structure of the BPXYIOCC macro. The application can join multiple source multicast groups on a single socket; it also can join the same group on multiple interfaces on the same socket. However, there is a maximum limit of 20 groups per single UDP socket and there is a maximum limit of 256 groups per single RAW socket. + /// + public static readonly uint SIOCSMSFILTER = _IOW('t', 126, typeof(uint)); + + /// The MULTICAST_MODE_TYPE enumeration specifies the filter mode for multicast group addresses. + /// + /// This enumeration is supported on Windows Vistaand later. + /// + /// The MULTICAST_MODE_TYPE enumeration is used in the gf_fmode member of the GROUP_SOURCE_REQ structure to determine + /// if a list of IP addresses should included or excluded. The values from this enumeration can also be used in the + /// imsf_fmode member of the ip_msfilter structure. + /// + /// + /// The MULTICAST_MODE_TYPE enumeration is defined in the Ws2ipdef.h header file which is automatically included in the + /// Ws2tcpip.h header file. The Ws2ipdef.h header files should never be used directly. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ne-ws2ipdef-multicast_mode_type typedef enum { MCAST_INCLUDE, + // MCAST_EXCLUDE } MULTICAST_MODE_TYPE; + [PInvokeData("ws2ipdef.h", MSDNShortId = "7ca9cb9b-618a-4e73-9e2a-18e55e5c00c0")] + public enum MULTICAST_MODE_TYPE { - /// - public const int IN6ADDR_LINKLOCALPREFIX_LENGTH = 64; + /// The filter contains a list of IP addresses to include. + MCAST_INCLUDE, - /// - public const int IN6ADDR_MULTICASTPREFIX_LENGTH = 8; + /// The filter contains a list of IP addresses to exclude. + MCAST_EXCLUDE, + } - /// - public const int IN6ADDR_SOLICITEDNODEMULTICASTPREFIX_LENGTH = 104; + /// + /// Used for an ioctl that reads data from the device driver. The driver will be allowed to return sizeof(data_type) bytes to the user. + /// + /// The type. + /// The value. + /// The type from which a size is extracted. + /// IOCtrl value. + public static uint _IOR(char x, uint y, Type t) => IOC_OUT | (((uint)Marshal.SizeOf(t) & IOCPARM_MASK) << 16) | ((uint)x) << 8 | (y); - /// - public const int IN6ADDR_V4MAPPEDPREFIX_LENGTH = 96; + /// Used for an ioctl that writes data to the device driver. + /// The type. + /// The value. + /// The type from which a size is extracted. + /// IOCtrl value. + public static uint _IOW(char x, uint y, Type t) => IOC_IN | (((uint)Marshal.SizeOf(t) & IOCPARM_MASK) << 16) | ((uint)x) << 8 | (y); - /// - public const int IN6ADDR_6TO4PREFIX_LENGTH = 16; + /// Gets the size, in bytes, of an GROUP_FILTER with a number of SOCKADDR_STORAGE items. + /// The number of SOCKADDR_STORAGE sources. + /// Size, in bytes. + [PInvokeData("ws2ipdef.h")] + public static int GROUP_FILTER_SIZE(int numsrc) => Marshal.SizeOf(typeof(GROUP_FILTER)) - Marshal.SizeOf(typeof(SOCKADDR_STORAGE)) + numsrc * Marshal.SizeOf(typeof(SOCKADDR_STORAGE)); - /// - public const int IN6ADDR_TEREDOPREFIX_LENGTH = 32; + /// Gets the size, in bytes, of an IP_MSFILTER with a number of IN_ADDR items. + /// The number of IN_ADDR sources. + /// Size, in bytes. + [PInvokeData("ws2ipdef.h")] + public static int IP_MSFILTER_SIZE(int NumSources) => Marshal.SizeOf(typeof(IP_MSFILTER)) - Marshal.SizeOf(typeof(IN_ADDR)) + NumSources * Marshal.SizeOf(typeof(IN_ADDR)); - /// - public const int INET_ADDRSTRLEN = 22; + /// The GROUP_FILTER structure provides multicast filtering parameters for multicast IPv6 or IPv4 addresses. + /// + /// + /// The GROUP_FILTER structure is used with either IPv6 or IPv4 multicast addresses. The GROUP_FILTER structure is + /// passed as an argument for the SIOCGMSFILTER and SIOCSMSFILTER IOCTLs. + /// + /// + /// The GROUP_FILTER structure and related structures used for multicast programming are based on IETF recommendations in + /// sections 5 and 8.2 of RFC 3768. For more information, see http://www.ietf.org/rfc/rfc3678.txt. + /// + /// + /// On Windows Vista and later, a set of socket options are available for multicast programming that support IPv6 and IPv4 + /// addresses. These socket options are IP agnostic and can be used on both IPv6 and IPv4. These IP agnostic options use the + /// GROUP_REQ and the GROUP_SOURCE_REQ structures and are the preferred socket options for multicast programming on Windows Vista + /// and later. + /// + /// The GetAdaptersAddresses function can be used to obtain interface index information required for the gf_interface member. + /// + /// The GROUP_FILTER structure and the Ioctls that use this structure are only valid on datagram and raw sockets (the socket + /// type must be SOCK_DGRAM or SOCK_RAW). + /// + /// + /// The GROUP_FILTER structure is defined in the Ws2ipdef.h header file which is automatically included in the Ws2tcpip.h + /// header file. The Ws2ipdef.h header files should never be used directly. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-group_filter typedef struct group_filter { ULONG + // gf_interface; SOCKADDR_STORAGE gf_group; MULTICAST_MODE_TYPE gf_fmode; ULONG gf_numsrc; SOCKADDR_STORAGE gf_slist[1]; } + // GROUP_FILTER, *PGROUP_FILTER; + [PInvokeData("ws2ipdef.h", MSDNShortId = "09aa1f67-c858-4bef-9a98-ce25ebcc1d4e")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), "gf_numsrc")] + [StructLayout(LayoutKind.Sequential)] + public struct GROUP_FILTER + { + /// The interface index of the local interface for the multicast group to filter. + public uint gf_interface; - /// - public const int INET6_ADDRSTRLEN = 65; - - /// - public const uint IOC_IN = 0x80000000; - - /// - public const uint IOC_INOUT = IOC_IN | IOC_OUT; - - /// - public const uint IOC_OUT = 0x40000000; - - /// - public const uint IOC_VOID = 0x20000000; - - /// - public const uint IOCPARM_MASK = 0x7f; + /// The multicast address group that should be filtered. This may be either an IPv6 or IPv4 multicast address. + public SOCKADDR_STORAGE gf_group; /// - /// It is used to return information about each interface on the local machine. Nothing is required on input, but on output, an array of INTERFACE_INFO structures is returned. - /// - public static readonly uint SIO_GET_INTERFACE_LIST = _IOR('t', 127, typeof(uint)); - - /// - /// This ioctl is the same as SIO_GET_INTERFACE_LIST except the structure returned contains embedded SOCKET_ADDRESS structure to describe each local interface, as opposed to SOCKADDR_GEN structure. This removes the dependency the size of the socket address structure. - /// - public static readonly uint SIO_GET_INTERFACE_LIST_EX = _IOR('t', 126, typeof(uint)); - - /// - /// This ioctl retrieves the multicast filter set on a given socket. The multicast state is set with the SIO_SET_MULTICAST_FILTER ioctl. This ioctl requires an IGMPv3-enabled network and is supported in only Windows XP. - /// - public static readonly uint SIO_GET_MULTICAST_FILTER = _IOW('t', 124 | IOC_IN, typeof(uint)); - - /// - /// This ioctl sets the multicast state. The input parameter is a struct ip_msfilter. - /// - public static readonly uint SIO_SET_MULTICAST_FILTER = _IOW('t', 125, typeof(uint)); - - /// - /// This ioctl retrieves the multicast filter set on a given socket. The multicast state is set with the SIO_SET_MULTICAST_FILTER ioctl. This ioctl requires an IGMPv3-enabled network and is supported in only Windows XP. - /// - public static readonly uint SIOCGIPMSFILTER = SIO_GET_MULTICAST_FILTER; - - /// - /// Enables an application to retrieve a list of the IPv4 or IPv6 source addresses that comprise the source filter along with the current mode on a given interface index and a multicast group for a socket. The source filter may either include or exclude the set of source address, depending on the filter mode (MCAST_INCLUDE or MCAST_EXCLUDE), which is defined in the GROUP_FILTER structure. - /// - public static readonly uint SIOCGMSFILTER = _IOW('t', 127 | IOC_IN, typeof(uint)); - - /// - /// This ioctl sets the multicast state. The input parameter is a struct ip_msfilter. - /// - public static readonly uint SIOCSIPMSFILTER = SIO_SET_MULTICAST_FILTER; - - /// - /// Enables an application to specify or modify a list of IPv4 or IPv6 source addresses on a given interface index and to specify or modify a multicast group for a socket. The source filter can include or exclude the set of source address, depending on the filter mode (MCAST_INCLUDE or MCAST_EXCLUDE), which is defined in the GROUP_FILTER structure of the BPXYIOCC macro. The application can join multiple source multicast groups on a single socket; it also can join the same group on multiple interfaces on the same socket. However, there is a maximum limit of 20 groups per single UDP socket and there is a maximum limit of 256 groups per single RAW socket. - /// - public static readonly uint SIOCSMSFILTER = _IOW('t', 126, typeof(uint)); - - /// The MULTICAST_MODE_TYPE enumeration specifies the filter mode for multicast group addresses. - /// - /// This enumeration is supported on Windows Vistaand later. + /// The multicast filter mode. /// - /// The MULTICAST_MODE_TYPE enumeration is used in the gf_fmode member of the GROUP_SOURCE_REQ structure to determine - /// if a list of IP addresses should included or excluded. The values from this enumeration can also be used in the - /// imsf_fmode member of the ip_msfilter structure. + /// This member can be one of the values from the MULTICAST_MODE_TYPE enumeration type defined in the Ws2ipdef.h header file. + /// This member determines if the list of IP addresses in the gf_numsrc member should be included or excluded. /// + /// + /// + /// Value + /// Meaning + /// + /// + /// MCAST_INCLUDE + /// The filter contains a list of IP addresses to include. + /// + /// + /// MCAST_EXCLUDE + /// The filter contains a list of IP addresses to exclude. + /// + /// + /// + public MULTICAST_MODE_TYPE gf_fmode; + + /// The number of multicast filter source address entries in the gf_slist member. + public uint gf_numsrc; + + /// + /// An array of SOCKADDR_STORAGE structures specifying the multicast source addresses to include or exclude. These IP addresses + /// may be either IPv6 or IPv4 addresses, but they must be the same address family (IPv6 or IPv4) as the address specified in + /// the gf_group member.. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public SOCKADDR_STORAGE[] gf_slist; + } + + /// + /// The in_pktinfo structure is used to store received packet address information, and is used by Windows to return + /// information about received packets and also allows specifying the local IPv4 address to use for sending packets. + /// + /// + /// + /// If the IP_PKTINFO socket option is set on a socket of type SOCK_DGRAM or SOCK_RAW, one of the control data objects + /// returned by the LPFN_WSARECVMSG (WSARecvMsg) function will contain an in_pktinfo structure used to store received packet + /// address information. + /// + /// + /// On an IPv4 socket of type SOCK_DGRAM or SOCK_RAW, an application can specific the local IP address to use for + /// sending with the WSASendMsg function. One of the control data objects passed in the WSAMSG structure to the WSASendMsg + /// function may contain an in_pktinfo structure used to specify the local IPv4 address to use for sending. + /// + /// + /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files + /// has changed and the in_pktinfo structure is defined in the Ws2ipdef.h header file which is automatically included + /// in the Ws2tcpip.h header file. The Ws2ipdef.h header files should never be used directly. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-in_pktinfo typedef struct in_pktinfo { IN_ADDR ipi_addr; + // ULONG ipi_ifindex; } IN_PKTINFO, *PIN_PKTINFO; + [PInvokeData("ws2ipdef.h", MSDNShortId = "NS:ws2ipdef.in_pktinfo")] + [StructLayout(LayoutKind.Sequential)] + public struct IN_PKTINFO + { + /// + /// The destination IPv4 address from the IP header of the received packet when used with the LPFN_WSARECVMSG (WSARecvMsg) + /// function. The local source IPv4 address to set in the IP header when used with the WSASendMsg function. + /// + public IN_ADDR ipi_addr; + + /// + /// The interface on which the packet was received when used with the LPFN_WSARECVMSG (WSARecvMsg) function. The interface on + /// which the packet should be sent when used with the WSASendMsg function. + /// + public uint ipi_ifindex; + } + + /// + /// The in6_pktinfo structure is used to store received IPv6 packet address information, and is used by Windows to return + /// information about received packets and also allows specifying the local IPv6 address to use for sending packets. + /// + /// + /// + /// If the IPV6_PKTINFO socket option is set on a socket of type SOCK_DGRAM or SOCK_RAW, one of the control data + /// objects returned by the LPFN_WSARECVMSG (WSARecvMsg) function will contain an in6_pktinfo structure used to store received + /// packet address information. + /// + /// + /// On an IPv6 socket of type SOCK_DGRAM or SOCK_RAW, an application can specific the local IP source address to use + /// for sending with the WSASendMsg function. One of the control data objects passed in the WSAMSG structure to the WSASendMsg + /// function may contain an in6_pktinfo structure used to specify the local IPv6 address to use for sending. + /// + /// + /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files + /// has changed and the in6_pktinfo structure is defined in the Ws2ipdef.h header file which is automatically included + /// in the Ws2tcpip.h header file. The Ws2ipdef.h header files should never be used directly. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-in6_pktinfo typedef struct in6_pktinfo { IN6_ADDR + // ipi6_addr; ULONG ipi6_ifindex; } IN6_PKTINFO, *PIN6_PKTINFO; + [PInvokeData("ws2ipdef.h", MSDNShortId = "NS:ws2ipdef.in6_pktinfo")] + [StructLayout(LayoutKind.Sequential)] + public struct IN6_PKTINFO + { + /// + /// The destination IPv6 address from the IP header of the received packet when used with the LPFN_WSARECVMSG (WSARecvMsg) + /// function. The local source IPv6 address to set in the IP header when used with the WSASendMsg function. + /// + public IN6_ADDR ipi6_addr; + + /// + /// The interface on which the packet was received when used with the LPFN_WSARECVMSG (WSARecvMsg) function. The interface on + /// which the packet should be sent when used with the WSASendMsg function. + /// + public uint ipi6_ifindex; + } + + /// The ip_mreq structure provides multicast group information for IPv4 addresses. + /// + /// + /// The ip_mreq structure is used with IPv4 addresses. The ip_mreq structure is used with the IP_ADD_MEMBERSHIP and + /// IP_DROP_MEMBERSHIP socket options. + /// + /// + /// The ip_mreq structure and related structures used for IPv4 multicast programming are based on IETF recommendations in + /// sections 4 and 8.1 of RFC 3768. For more information, see http://www.ietf.org/rfc/rfc3678.txt. + /// + /// + /// For more configurable multicast capabilities with IPv4, use the ip_mreq_source structure. See Multicast Programming for more information. + /// + /// + /// On Windows Vista and later, a set of socket options are available for multicast programming that support IPv6 and IPv4 addresses. + /// These socket options are IP agnostic and can be used on both IPv6 and IPv4. These IP agnostic options use the GROUP_REQ and the + /// GROUP_SOURCE_REQ structures and are the preferred socket options for multicast programming on Windows Vista and later. + /// + /// The ip_mreq structure is the IPv4 equivalent of the IPv6-based ipv6_mreq structure. + /// + /// The imr_interface member can be an interface index. Any IP address in the 0.x.x.x block (first octet of 0) except for the + /// IP address of 0.0.0.0 is treated as an interface index. An interface index is a 24-bit number. The 0.0.0.0/8 IPv4 address block + /// is not used (this range is reserved). The GetAdaptersAddresses function can be used to obtain interface index information to use + /// for the imr_interface member. + /// + /// + /// It is recommended that a local IPv4 address or interface index always be specified in the imr_interface member of the + /// ip_mreq structure, rather than use the default interface. This is particularly important on computers with multiple + /// network interfaces and multiple public IPv4 addresses. + /// + /// + /// The default interface used for IPv4 multicast is determined by the networking stack in Windows. An application can determine the + /// default interface used for IPv4 multicast using the GetIpForwardTable function to retrieve the IPv4 routing table. The network + /// interface with the lowest value for the routing metric for a destination IP address of 224.0.0.0 is the default interface for + /// IPv4 multicast. The routing table can also be displayed from the command prompt with the following command: + /// + /// route print + /// + /// The IP_MULTICAST_IF socket option can be used to set the default interface to send IPv4 multicast packets. This socket option + /// does not change the default interface used to receive IPv4 multicast packets. + /// + /// + /// A typical IPv4 multicast application would use the IP_ADD_MEMBERSHIP socket option with the ip_mreq structure to join a + /// multicast group and listen for multicast packets on a specific interface. The IP_MULTICAST_IF socket option would be used + /// to set the interface to send IPv4 multicast packets to the multicast group. The most common scenario would be a multicast + /// application that listens and sends on the same interface for a multicast group. Multiple sockets might be used by a multicast + /// application with one socket for listening and one or more sockets for sending. + /// + /// + /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files + /// has changed and the ip_mreq structure is defined in the Ws2ipdef.h header file which is automatically included in + /// the Ws2tcpip.h header file. The Ws2ipdef.h header files should never be used directly. + /// + /// + /// Note The IP_MREQ and PIP_MREQ derived structures are only defined on the Windows SDK released with Windows + /// Vista and later. The ip_mreq structure should be used on earlier versions of the Windows SDK. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-ip_mreq typedef struct ip_mreq { IN_ADDR imr_multiaddr; + // IN_ADDR imr_interface; } IP_MREQ, *PIP_MREQ; + [PInvokeData("ws2ipdef.h", MSDNShortId = "NS:ws2ipdef.ip_mreq")] + [StructLayout(LayoutKind.Sequential)] + public struct IP_MREQ + { + /// The address of the IPv4 multicast group. + public IN_ADDR imr_multiaddr; + + /// /// - /// The MULTICAST_MODE_TYPE enumeration is defined in the Ws2ipdef.h header file which is automatically included in the - /// Ws2tcpip.h header file. The Ws2ipdef.h header files should never be used directly. + /// The local IPv4 address of the interface or the interface index on which the multicast group should be joined or dropped. This + /// value is in network byte order. If this member specifies an IPv4 address of 0.0.0.0, the default IPv4 multicast interface is used. /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ne-ws2ipdef-multicast_mode_type typedef enum { MCAST_INCLUDE, - // MCAST_EXCLUDE } MULTICAST_MODE_TYPE; - [PInvokeData("ws2ipdef.h", MSDNShortId = "7ca9cb9b-618a-4e73-9e2a-18e55e5c00c0")] - public enum MULTICAST_MODE_TYPE + /// To use an interface index of 1 would be the same as an IP address of 0.0.0.1. + /// + public IN_ADDR imr_interface; + } + + /// The ip_msfilter structure provides multicast filtering parameters for IPv4 addresses. + /// + /// + /// The ip_msfilter structure is used with IPv4 addresses. The ip_msfilter structure is passed as an argument for the + /// SIO_GET_MULTICAST_FILTER and SIO_SET_MULTICAST_FILTER IOCTLs. + /// + /// + /// The ip_msfilter structure and related structures used for IPv4 multicast programming are based on IETF recommendations in + /// sections 4 and 8.1 of RFC 3768. For more information, see http://www.ietf.org/rfc/rfc3678.txt. + /// + /// + /// On Windows Vista and later, a set of socket options are available for multicast programming that support IPv6 and IPv4 + /// addresses. These socket options are IP agnostic and can be used on both IPv6 and IPv4. These IP agnostic options use the + /// GROUP_REQ and the GROUP_SOURCE_REQ structures and the SIOCSMSFILTER and SIOCGMSFILTER IOCTLs. These are the + /// preferred socket options and IOCTLs for multicast programming on Windows Vista and later. + /// + /// + /// The imsf_interface member can be an interface index. Any IPv4 address in the 0.x.x.x block (first octet of 0) except for + /// the IPv4 address of 0.0.0.0 is treated as an interface index. An interface index is a 24-bit number. The 0.0.0.0/8 IPv4 address + /// block is not used (this range is reserved). The GetAdaptersAddresses function can be used to obtain interface index information + /// to use for the imsf_interface member. + /// + /// + /// It is recommended that a local IPv4 address or interface index always be specified in the imsf_interface member of the + /// ip_msfilter structure, rather than use the default interface. This is particularly important on computers with multiple + /// network interfaces and multiple public IPv4 addresses. + /// + /// + /// The default interface used for IPv4 multicast is determined by the networking stack in Windows. An application can determine the + /// default interface used for IPv4 multicast using the GetIpForwardTable function to retrieve the IPv4 routing table. The network + /// interface with the lowest value for the routing metric for a destination IP address of 224.0.0.0 is the default interface for + /// IPv4 multicast. The routing table can also be displayed from the command prompt with the following command: + /// + /// route print + /// + /// The IP_MULTICAST_IF socket option can be used to set the default interface to send IPv4 multicast packets. This socket option + /// does not change the default interface used to receive IPv4 multicast packets. + /// + /// + /// A typical IPv4 multicast application would use the IP_ADD_MEMBERSHIP socket option with the ip_mreq structure or the + /// IP_ADD_SOURCE_MEMBERSHIP socket option with the ip_mreq_source structure to join a multicast group and listen for + /// multicast packets on a specific interface. The IP_MULTICAST_IF socket option would be used to set the interface to send + /// IPv4 multicast packets to the multicast group. The most common scenario would be a multicast application that listens and sends + /// on the same interface for a multicast group. Multiple sockets might be used by a multicast application with one socket for + /// listening and one or more sockets for sending. + /// + /// + /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files + /// has changed and the ip_msfilter structure is defined in the Ws2ipdef.h header file which is automatically included in the + /// Ws2tcpip.h header file. The Ws2ipdef.h header files should never be used directly. + /// + /// + /// Note The IP_MSFILTER and PIP_MSFILTER derived structures are only defined on the Windows SDK released with + /// Windows Vista and later. The ip_msfilter structure should be used on earlier versions of the Windows SDK. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-ip_msfilter typedef struct ip_msfilter { IN_ADDR + // imsf_multiaddr; IN_ADDR imsf_interface; MULTICAST_MODE_TYPE imsf_fmode; ULONG imsf_numsrc; IN_ADDR imsf_slist[1]; } IP_MSFILTER, *PIP_MSFILTER; + [PInvokeData("ws2ipdef.h", MSDNShortId = "8d9d515e-9369-4d71-9614-6cbeb5557a5d")] + [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), "imsf_numsrc")] + [StructLayout(LayoutKind.Sequential)] + public struct IP_MSFILTER + { + /// The IPv4 address of the multicast group. + public IN_ADDR imsf_multiaddr; + + /// + /// + /// The local IPv4 address of the interface or the interface index on which the multicast group should be filtered. This value + /// is in network byte order. If this member specifies an IPv4 address of 0.0.0.0, the default IPv4 multicast interface is used. + /// + /// To use an interface index of 1 would be the same as an IP address of 0.0.0.1. + /// + public IN_ADDR imsf_interface; + + /// + /// + /// The multicast filter mode to be used. This parameter can be either MCAST_INCLUDE (value of 0) to include particular + /// multicast sources, or MCAST_EXCLUDE (value of 1) to exclude traffic from specified sources. + /// + /// On Windows Server 2003 and Windows XP, these values are defined in the Ws2tcpip.h header file. + /// + /// On Windows Vistaand later, these values are defined as enumeration values in the MULTICAST_MODE_TYPE enumeration defined in + /// the Ws2ipdef.h header file. + /// + /// + public MULTICAST_MODE_TYPE imsf_fmode; + + /// The number of sources in the imsf_slist member. + public uint imsf_numsrc; + + /// An array of in_addr structures that specify the IPv4 multicast source addresses to include or exclude. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] + public IN_ADDR[] imsf_slist; + } + + /// The ipv6_mreq structure provides multicast group information for IPv6 addresses. + /// + /// + /// The ipv6_mreq structure is used with IPv6 addresses. The ipv6_mreq structure is used with the IPV6_ADD_MEMBERSHIP, + /// IPV6_DROP_MEMBERSHIP, IPV6_JOIN_GROUP, and IPV6_LEAVE_GROUP socket options. The IPV6_JOIN_GROUP and + /// IPV6_ADD_MEMBERSHIP socket options are defined to be the same. The IPV6_LEAVE_GROUP and IPV6_DROP_MEMBERSHIP + /// socket options are defined to be the same. + /// + /// + /// On Windows Vista and later, a set of socket options are available for multicast programming that support IPv6 and IPv4 addresses. + /// These socket options are IP agnostic and can be used on both IPv6 and IPv4. These IP agnostic options use the GROUP_REQ and the + /// GROUP_SOURCE_REQ structures and are the preferred socket options for multicast programming on Windows Vista and later. + /// + /// The ipv6_mreq structure is the IPv6 equivalent of the IPv4-based ip_mreq structure. + /// + /// The GetAdaptersAddresses function can be used to obtain interface index information required for the ipv6mr_interface member. + /// + /// + /// The ipv6_mreq structure and the IPPROTO_IPV6 level socket options that use this structure are only valid on + /// datagram and raw sockets (the socket type must be SOCK_DGRAM or SOCK_RAW). + /// + /// + /// It is recommended that a local IPv6 interface index always be specified in the ipv6mr_interface member of the + /// ipv6_mreq structure, rather than use the default interface. This is particularly important on computers with multiple + /// network interfaces and multiple public IPv6 addresses. + /// + /// + /// The default interface used for IPv6 multicast is determined by the networking stack in Windows. On Windows Vista and later, an + /// application can determine the default interface used for IPv6 multicast using the GetIpForwardTable2 function to retrieve the + /// IPv6 routing table. The network interface with the lowest value for the routing metric for a destination IPv6 multicast address + /// (the FF00::/8 IPv6 address block) is the default interface for IPv6 multicast. The routing table can also be displayed from the + /// command prompt with the following command: + /// + /// route print + /// + /// The IPV6_MULTICAST_IF socket option can be used to set the default interface to send IPv6 multicast packets. This socket option + /// does not change the default interface used to receive IPv6 multicast packets. + /// + /// + /// A typical IPv6 multicast application would use the IPV6_ADD_MEMBERSHIP or IPV6_JOIN_GROUP socket option with the + /// ipv6_mreq structure to join a multicast group and listen for multicast packets on a specific interface. The + /// IPV6_MULTICAST_IF socket option would be used to set the interface to send IPv6 multicast packets to the multicast group. + /// The most common scenario would be a multicast application that listens and sends on the same interface for a multicast group. + /// Multiple sockets might be used by a multicast application with one socket for listening and one or more sockets for sending. + /// + /// + /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files + /// has changed and the ipv6_mreq structure is defined in the Ws2ipdef.h header file which is automatically included in + /// the Ws2tcpip.h header file. The Ws2ipdef.h header files should never be used directly. + /// + /// + /// Note The PIP6_MREQ derived structure is only defined on the Windows SDK released with Windows Vista and later. The + /// GROUP_REQ and the GROUP_SOURCE_REQ structures and are the preferred socket options for multicast programming on Windows Vista and later. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-ipv6_mreq typedef struct ipv6_mreq { IN6_ADDR + // ipv6mr_multiaddr; ULONG ipv6mr_interface; } IPV6_MREQ, *PIPV6_MREQ; + [PInvokeData("ws2ipdef.h", MSDNShortId = "NS:ws2ipdef.ipv6_mreq")] + [StructLayout(LayoutKind.Sequential)] + public struct IPV6_MREQ + { + /// The address of the IPv6 multicast group. + public IN6_ADDR ipv6mr_multiaddr; + + /// + /// The interface index of the local interface on which the multicast group should be joined or dropped. If this member specifies + /// an interface index of 0, the default multicast interface is used. + /// + public uint ipv6mr_interface; + } + + /// The SOCKADDR_IN6 structure specifies a transport address and port for the AF_INET6 address family. + /// + /// + /// All of the data in the SOCKADDR_IN6 structure, except for the address family, must be specified in network-byte-order (big-endian). + /// + /// + /// The size of the SOCKADDR_IN6 structure is too large to fit in the memory space that is provided by a SOCKADDR structure. For a + /// structure that is guaranteed to be large enough to contain a transport address for all possible address families, see SOCKADDR_STORAGEa>. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-sockaddr_in6_lh typedef struct sockaddr_in6 { + // ADDRESS_FAMILY sin6_family; USHORT sin6_port; ULONG sin6_flowinfo; IN6_ADDR sin6_addr; union { ULONG sin6_scope_id; SCOPE_ID + // sin6_scope_struct; }; } SOCKADDR_IN6_LH, *PSOCKADDR_IN6_LH, *LPSOCKADDR_IN6_LH; + [PInvokeData("ws2ipdef.h", MSDNShortId = "ef2955d2-5dc1-420b-a9e0-32a584059d5a")] + [StructLayout(LayoutKind.Sequential, Pack = 2)] + public struct SOCKADDR_IN6 + { + /// The address family for the transport address. This member should always be set to AF_INET6. + public ADDRESS_FAMILY sin6_family; + + /// A transport protocol port number. + public ushort sin6_port; + + /// The IPv6 flow information. + public uint sin6_flowinfo; + + /// An IN6_ADDR structure that contains an IPv6 transport address. + public IN6_ADDR sin6_addr; + + /// A ULONG representation of the IPv6 scope identifier that is defined in the sin6_scope_struct member. + public uint sin6_scope_id; + + /// Initializes a new instance of the struct. + /// A byte array that contains an IPv6 transport address. + /// + /// A ULONG representation of the IPv6 scope identifier that is defined in the sin6_scope_struct member. + /// + /// A transport protocol port number. + public SOCKADDR_IN6(byte[] addr, uint scope_id, ushort port = 0) : this(new IN6_ADDR(addr), scope_id, port) { - /// The filter contains a list of IP addresses to include. - MCAST_INCLUDE, - - /// The filter contains a list of IP addresses to exclude. - MCAST_EXCLUDE, } - /// - /// Used for an ioctl that reads data from the device driver. The driver will be allowed to return sizeof(data_type) bytes to the user. - /// - /// The type. - /// The value. - /// The type from which a size is extracted. - /// IOCtrl value. - public static uint _IOR(char x, uint y, Type t) => IOC_OUT | (((uint)Marshal.SizeOf(t) & IOCPARM_MASK) << 16) | ((uint)x) << 8 | (y); - - /// Used for an ioctl that writes data to the device driver. - /// The type. - /// The value. - /// The type from which a size is extracted. - /// IOCtrl value. - public static uint _IOW(char x, uint y, Type t) => IOC_IN | (((uint)Marshal.SizeOf(t) & IOCPARM_MASK) << 16) | ((uint)x) << 8 | (y); - - /// Gets the size, in bytes, of an GROUP_FILTER with a number of SOCKADDR_STORAGE items. - /// The number of SOCKADDR_STORAGE sources. - /// Size, in bytes. - [PInvokeData("ws2ipdef.h")] - public static int GROUP_FILTER_SIZE(int numsrc) => Marshal.SizeOf(typeof(GROUP_FILTER)) - Marshal.SizeOf(typeof(SOCKADDR_STORAGE)) + numsrc * Marshal.SizeOf(typeof(SOCKADDR_STORAGE)); - - /// Gets the size, in bytes, of an IP_MSFILTER with a number of IN_ADDR items. - /// The number of IN_ADDR sources. - /// Size, in bytes. - [PInvokeData("ws2ipdef.h")] - public static int IP_MSFILTER_SIZE(int NumSources) => Marshal.SizeOf(typeof(IP_MSFILTER)) - Marshal.SizeOf(typeof(IN_ADDR)) + NumSources * Marshal.SizeOf(typeof(IN_ADDR)); - - /// The GROUP_FILTER structure provides multicast filtering parameters for multicast IPv6 or IPv4 addresses. - /// - /// - /// The GROUP_FILTER structure is used with either IPv6 or IPv4 multicast addresses. The GROUP_FILTER structure is - /// passed as an argument for the SIOCGMSFILTER and SIOCSMSFILTER IOCTLs. - /// - /// - /// The GROUP_FILTER structure and related structures used for multicast programming are based on IETF recommendations in - /// sections 5 and 8.2 of RFC 3768. For more information, see http://www.ietf.org/rfc/rfc3678.txt. - /// - /// - /// On Windows Vista and later, a set of socket options are available for multicast programming that support IPv6 and IPv4 - /// addresses. These socket options are IP agnostic and can be used on both IPv6 and IPv4. These IP agnostic options use the - /// GROUP_REQ and the GROUP_SOURCE_REQ structures and are the preferred socket options for multicast programming on Windows Vista - /// and later. - /// - /// The GetAdaptersAddresses function can be used to obtain interface index information required for the gf_interface member. - /// - /// The GROUP_FILTER structure and the Ioctls that use this structure are only valid on datagram and raw sockets (the socket - /// type must be SOCK_DGRAM or SOCK_RAW). - /// - /// - /// The GROUP_FILTER structure is defined in the Ws2ipdef.h header file which is automatically included in the Ws2tcpip.h - /// header file. The Ws2ipdef.h header files should never be used directly. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-group_filter typedef struct group_filter { ULONG - // gf_interface; SOCKADDR_STORAGE gf_group; MULTICAST_MODE_TYPE gf_fmode; ULONG gf_numsrc; SOCKADDR_STORAGE gf_slist[1]; } - // GROUP_FILTER, *PGROUP_FILTER; - [PInvokeData("ws2ipdef.h", MSDNShortId = "09aa1f67-c858-4bef-9a98-ce25ebcc1d4e")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), "gf_numsrc")] - [StructLayout(LayoutKind.Sequential)] - public struct GROUP_FILTER + /// Initializes a new instance of the struct. + /// An IN6_ADDR structure that contains an IPv6 transport address. + /// + /// A ULONG representation of the IPv6 scope identifier that is defined in the sin6_scope_struct member. + /// + /// A transport protocol port number. + public SOCKADDR_IN6(IN6_ADDR addr, uint scope_id, ushort port = 0) { - /// The interface index of the local interface for the multicast group to filter. - public uint gf_interface; - - /// The multicast address group that should be filtered. This may be either an IPv6 or IPv4 multicast address. - public SOCKADDR_STORAGE gf_group; - - /// - /// The multicast filter mode. - /// - /// This member can be one of the values from the MULTICAST_MODE_TYPE enumeration type defined in the Ws2ipdef.h header file. - /// This member determines if the list of IP addresses in the gf_numsrc member should be included or excluded. - /// - /// - /// - /// Value - /// Meaning - /// - /// - /// MCAST_INCLUDE - /// The filter contains a list of IP addresses to include. - /// - /// - /// MCAST_EXCLUDE - /// The filter contains a list of IP addresses to exclude. - /// - /// - /// - public MULTICAST_MODE_TYPE gf_fmode; - - /// The number of multicast filter source address entries in the gf_slist member. - public uint gf_numsrc; - - /// - /// An array of SOCKADDR_STORAGE structures specifying the multicast source addresses to include or exclude. These IP addresses - /// may be either IPv6 or IPv4 addresses, but they must be the same address family (IPv6 or IPv4) as the address specified in - /// the gf_group member.. - /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public SOCKADDR_STORAGE[] gf_slist; + sin6_family = ADDRESS_FAMILY.AF_INET6; + sin6_port = port; + sin6_flowinfo = 0; + sin6_addr = addr; + sin6_scope_id = scope_id; } + /// Initializes a new instance of the struct from a . + /// The IPv4 socket address. + public SOCKADDR_IN6(SOCKADDR_IN v4) : this(new IN6_ADDR(v4.sin_addr), 0, v4.sin_port) { } + + /// Performs an implicit conversion from to . + /// The address. + /// The resulting instance from the conversion. + public static implicit operator SOCKADDR_IN6(IN6_ADDR addr) => new(addr, 0); + + /// Represents an IPv6 anycast socket address. + public static readonly SOCKADDR_IN6 IN6ADDR_ANY = new() { sin6_family = ADDRESS_FAMILY.AF_INET6, sin6_addr = IN6_ADDR.Unspecified }; + + /// Represents an IPv6 LOOPBACK socket address. + public static readonly SOCKADDR_IN6 IN6ADDR_LOOPBACK = new() { sin6_family = ADDRESS_FAMILY.AF_INET6, sin6_addr = IN6_ADDR.Loopback }; + + /// + public override string ToString() => $"{sin6_addr}" + (sin6_scope_id == 0 ? "" : "%" + sin6_scope_id.ToString()) + $":{sin6_port}"; + } + + /// + /// The SOCKADDR_IN6_PAIR structure contains pointers to a pair of IP addresses that represent a source and destination + /// address pair. + /// + /// + /// The SOCKADDR_IN6_PAIR structure is defined on Windows Vista and later. + /// + /// Any IPv4 addresses in the SOCKADDR_IN6_PAIR structure must be represented in the IPv4-mapped IPv6 address format which + /// enables an IPv6 only application to communicate with an IPv4 node. For more information on the IPv4-mapped IPv6 address format, + /// see Dual-Stack Sockets. + /// + /// The SOCKADDR_IN6_PAIR structure is used by the CreateSortedAddressPairs function. + /// Note that the Ws2ipdef.h header file is automatically included in Ws2tcpip.h header file, and should never be used directly. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/ws2ipdef/ns-ws2ipdef-_sockaddr_in6_pair typedef struct _sockaddr_in6_pair { + // PSOCKADDR_IN6 SourceAddress; PSOCKADDR_IN6 DestinationAddress; } SOCKADDR_IN6_PAIR, *PSOCKADDR_IN6_PAIR; + [PInvokeData("ws2ipdef.h", MSDNShortId = "0265f8e0-8b35-4d9d-bf22-e98e9ff36a17")] + [StructLayout(LayoutKind.Sequential)] + public struct SOCKADDR_IN6_PAIR + { + /// The source address + private readonly IntPtr _SourceAddress; + + /// The destination address + private readonly IntPtr _DestinationAddress; + /// - /// The in_pktinfo structure is used to store received packet address information, and is used by Windows to return - /// information about received packets and also allows specifying the local IPv4 address to use for sending packets. + /// A pointer to an IP source address represented as a SOCKADDR_IN6 structure. The address family is in host byte order and the + /// IPv6 address, port, flow information, and zone ID are in network byte order. /// - /// - /// - /// If the IP_PKTINFO socket option is set on a socket of type SOCK_DGRAM or SOCK_RAW, one of the control data objects - /// returned by the LPFN_WSARECVMSG (WSARecvMsg) function will contain an in_pktinfo structure used to store received packet - /// address information. - /// - /// - /// On an IPv4 socket of type SOCK_DGRAM or SOCK_RAW, an application can specific the local IP address to use for - /// sending with the WSASendMsg function. One of the control data objects passed in the WSAMSG structure to the WSASendMsg - /// function may contain an in_pktinfo structure used to specify the local IPv4 address to use for sending. - /// - /// - /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files - /// has changed and the in_pktinfo structure is defined in the Ws2ipdef.h header file which is automatically included - /// in the Ws2tcpip.h header file. The Ws2ipdef.h header files should never be used directly. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-in_pktinfo typedef struct in_pktinfo { IN_ADDR ipi_addr; - // ULONG ipi_ifindex; } IN_PKTINFO, *PIN_PKTINFO; - [PInvokeData("ws2ipdef.h", MSDNShortId = "NS:ws2ipdef.in_pktinfo")] - [StructLayout(LayoutKind.Sequential)] - public struct IN_PKTINFO - { - /// - /// The destination IPv4 address from the IP header of the received packet when used with the LPFN_WSARECVMSG (WSARecvMsg) - /// function. The local source IPv4 address to set in the IP header when used with the WSASendMsg function. - /// - public IN_ADDR ipi_addr; - - /// - /// The interface on which the packet was received when used with the LPFN_WSARECVMSG (WSARecvMsg) function. The interface on - /// which the packet should be sent when used with the WSASendMsg function. - /// - public uint ipi_ifindex; - } + /// The source address. + public SOCKADDR_IN6 SourceAddress => _SourceAddress.ToStructure(); /// - /// The in6_pktinfo structure is used to store received IPv6 packet address information, and is used by Windows to return - /// information about received packets and also allows specifying the local IPv6 address to use for sending packets. + /// A pointer to an IP source address represented as a SOCKADDR_IN6 structure. The address family is in host byte order and the + /// IPv6 address, port, flow information, and zone ID are in network byte order. /// - /// - /// - /// If the IPV6_PKTINFO socket option is set on a socket of type SOCK_DGRAM or SOCK_RAW, one of the control data - /// objects returned by the LPFN_WSARECVMSG (WSARecvMsg) function will contain an in6_pktinfo structure used to store received - /// packet address information. - /// - /// - /// On an IPv6 socket of type SOCK_DGRAM or SOCK_RAW, an application can specific the local IP source address to use - /// for sending with the WSASendMsg function. One of the control data objects passed in the WSAMSG structure to the WSASendMsg - /// function may contain an in6_pktinfo structure used to specify the local IPv6 address to use for sending. - /// - /// - /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files - /// has changed and the in6_pktinfo structure is defined in the Ws2ipdef.h header file which is automatically included - /// in the Ws2tcpip.h header file. The Ws2ipdef.h header files should never be used directly. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-in6_pktinfo typedef struct in6_pktinfo { IN6_ADDR - // ipi6_addr; ULONG ipi6_ifindex; } IN6_PKTINFO, *PIN6_PKTINFO; - [PInvokeData("ws2ipdef.h", MSDNShortId = "NS:ws2ipdef.in6_pktinfo")] - [StructLayout(LayoutKind.Sequential)] - public struct IN6_PKTINFO - { - /// - /// The destination IPv6 address from the IP header of the received packet when used with the LPFN_WSARECVMSG (WSARecvMsg) - /// function. The local source IPv6 address to set in the IP header when used with the WSASendMsg function. - /// - public IN6_ADDR ipi6_addr; + /// The destination address. + public SOCKADDR_IN6 DestinationAddress => _DestinationAddress.ToStructure(); - /// - /// The interface on which the packet was received when used with the LPFN_WSARECVMSG (WSARecvMsg) function. The interface on - /// which the packet should be sent when used with the WSASendMsg function. - /// - public uint ipi6_ifindex; - } + /// Performs an implicit conversion from to . + /// The unmanaged value. + /// The resulting instance from the conversion. + public static implicit operator SOCKADDR_IN6_PAIR_NATIVE(SOCKADDR_IN6_PAIR unmgd) => + new() + { SourceAddress = unmgd.SourceAddress, DestinationAddress = unmgd.DestinationAddress }; - /// The ip_mreq structure provides multicast group information for IPv4 addresses. - /// - /// - /// The ip_mreq structure is used with IPv4 addresses. The ip_mreq structure is used with the IP_ADD_MEMBERSHIP and - /// IP_DROP_MEMBERSHIP socket options. - /// - /// - /// The ip_mreq structure and related structures used for IPv4 multicast programming are based on IETF recommendations in - /// sections 4 and 8.1 of RFC 3768. For more information, see http://www.ietf.org/rfc/rfc3678.txt. - /// - /// - /// For more configurable multicast capabilities with IPv4, use the ip_mreq_source structure. See Multicast Programming for more information. - /// - /// - /// On Windows Vista and later, a set of socket options are available for multicast programming that support IPv6 and IPv4 addresses. - /// These socket options are IP agnostic and can be used on both IPv6 and IPv4. These IP agnostic options use the GROUP_REQ and the - /// GROUP_SOURCE_REQ structures and are the preferred socket options for multicast programming on Windows Vista and later. - /// - /// The ip_mreq structure is the IPv4 equivalent of the IPv6-based ipv6_mreq structure. - /// - /// The imr_interface member can be an interface index. Any IP address in the 0.x.x.x block (first octet of 0) except for the - /// IP address of 0.0.0.0 is treated as an interface index. An interface index is a 24-bit number. The 0.0.0.0/8 IPv4 address block - /// is not used (this range is reserved). The GetAdaptersAddresses function can be used to obtain interface index information to use - /// for the imr_interface member. - /// - /// - /// It is recommended that a local IPv4 address or interface index always be specified in the imr_interface member of the - /// ip_mreq structure, rather than use the default interface. This is particularly important on computers with multiple - /// network interfaces and multiple public IPv4 addresses. - /// - /// - /// The default interface used for IPv4 multicast is determined by the networking stack in Windows. An application can determine the - /// default interface used for IPv4 multicast using the GetIpForwardTable function to retrieve the IPv4 routing table. The network - /// interface with the lowest value for the routing metric for a destination IP address of 224.0.0.0 is the default interface for - /// IPv4 multicast. The routing table can also be displayed from the command prompt with the following command: - /// - /// route print - /// - /// The IP_MULTICAST_IF socket option can be used to set the default interface to send IPv4 multicast packets. This socket option - /// does not change the default interface used to receive IPv4 multicast packets. - /// - /// - /// A typical IPv4 multicast application would use the IP_ADD_MEMBERSHIP socket option with the ip_mreq structure to join a - /// multicast group and listen for multicast packets on a specific interface. The IP_MULTICAST_IF socket option would be used - /// to set the interface to send IPv4 multicast packets to the multicast group. The most common scenario would be a multicast - /// application that listens and sends on the same interface for a multicast group. Multiple sockets might be used by a multicast - /// application with one socket for listening and one or more sockets for sending. - /// - /// - /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files - /// has changed and the ip_mreq structure is defined in the Ws2ipdef.h header file which is automatically included in - /// the Ws2tcpip.h header file. The Ws2ipdef.h header files should never be used directly. - /// - /// - /// Note The IP_MREQ and PIP_MREQ derived structures are only defined on the Windows SDK released with Windows - /// Vista and later. The ip_mreq structure should be used on earlier versions of the Windows SDK. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-ip_mreq typedef struct ip_mreq { IN_ADDR imr_multiaddr; - // IN_ADDR imr_interface; } IP_MREQ, *PIP_MREQ; - [PInvokeData("ws2ipdef.h", MSDNShortId = "NS:ws2ipdef.ip_mreq")] - [StructLayout(LayoutKind.Sequential)] - public struct IP_MREQ - { - /// The address of the IPv4 multicast group. - public IN_ADDR imr_multiaddr; + /// Converts to string. + /// A that represents this instance. + /// + public override string ToString() => $"{SourceAddress} : {DestinationAddress}"; + } - /// - /// - /// The local IPv4 address of the interface or the interface index on which the multicast group should be joined or dropped. This - /// value is in network byte order. If this member specifies an IPv4 address of 0.0.0.0, the default IPv4 multicast interface is used. - /// - /// To use an interface index of 1 would be the same as an IP address of 0.0.0.1. - /// - public IN_ADDR imr_interface; - } - - /// The ip_msfilter structure provides multicast filtering parameters for IPv4 addresses. - /// - /// - /// The ip_msfilter structure is used with IPv4 addresses. The ip_msfilter structure is passed as an argument for the - /// SIO_GET_MULTICAST_FILTER and SIO_SET_MULTICAST_FILTER IOCTLs. - /// - /// - /// The ip_msfilter structure and related structures used for IPv4 multicast programming are based on IETF recommendations in - /// sections 4 and 8.1 of RFC 3768. For more information, see http://www.ietf.org/rfc/rfc3678.txt. - /// - /// - /// On Windows Vista and later, a set of socket options are available for multicast programming that support IPv6 and IPv4 - /// addresses. These socket options are IP agnostic and can be used on both IPv6 and IPv4. These IP agnostic options use the - /// GROUP_REQ and the GROUP_SOURCE_REQ structures and the SIOCSMSFILTER and SIOCGMSFILTER IOCTLs. These are the - /// preferred socket options and IOCTLs for multicast programming on Windows Vista and later. - /// - /// - /// The imsf_interface member can be an interface index. Any IPv4 address in the 0.x.x.x block (first octet of 0) except for - /// the IPv4 address of 0.0.0.0 is treated as an interface index. An interface index is a 24-bit number. The 0.0.0.0/8 IPv4 address - /// block is not used (this range is reserved). The GetAdaptersAddresses function can be used to obtain interface index information - /// to use for the imsf_interface member. - /// - /// - /// It is recommended that a local IPv4 address or interface index always be specified in the imsf_interface member of the - /// ip_msfilter structure, rather than use the default interface. This is particularly important on computers with multiple - /// network interfaces and multiple public IPv4 addresses. - /// - /// - /// The default interface used for IPv4 multicast is determined by the networking stack in Windows. An application can determine the - /// default interface used for IPv4 multicast using the GetIpForwardTable function to retrieve the IPv4 routing table. The network - /// interface with the lowest value for the routing metric for a destination IP address of 224.0.0.0 is the default interface for - /// IPv4 multicast. The routing table can also be displayed from the command prompt with the following command: - /// - /// route print - /// - /// The IP_MULTICAST_IF socket option can be used to set the default interface to send IPv4 multicast packets. This socket option - /// does not change the default interface used to receive IPv4 multicast packets. - /// - /// - /// A typical IPv4 multicast application would use the IP_ADD_MEMBERSHIP socket option with the ip_mreq structure or the - /// IP_ADD_SOURCE_MEMBERSHIP socket option with the ip_mreq_source structure to join a multicast group and listen for - /// multicast packets on a specific interface. The IP_MULTICAST_IF socket option would be used to set the interface to send - /// IPv4 multicast packets to the multicast group. The most common scenario would be a multicast application that listens and sends - /// on the same interface for a multicast group. Multiple sockets might be used by a multicast application with one socket for - /// listening and one or more sockets for sending. - /// - /// - /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files - /// has changed and the ip_msfilter structure is defined in the Ws2ipdef.h header file which is automatically included in the - /// Ws2tcpip.h header file. The Ws2ipdef.h header files should never be used directly. - /// - /// - /// Note The IP_MSFILTER and PIP_MSFILTER derived structures are only defined on the Windows SDK released with - /// Windows Vista and later. The ip_msfilter structure should be used on earlier versions of the Windows SDK. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-ip_msfilter typedef struct ip_msfilter { IN_ADDR - // imsf_multiaddr; IN_ADDR imsf_interface; MULTICAST_MODE_TYPE imsf_fmode; ULONG imsf_numsrc; IN_ADDR imsf_slist[1]; } IP_MSFILTER, *PIP_MSFILTER; - [PInvokeData("ws2ipdef.h", MSDNShortId = "8d9d515e-9369-4d71-9614-6cbeb5557a5d")] - [VanaraMarshaler(typeof(SafeAnysizeStructMarshaler), "imsf_numsrc")] - [StructLayout(LayoutKind.Sequential)] - public struct IP_MSFILTER - { - /// The IPv4 address of the multicast group. - public IN_ADDR imsf_multiaddr; - - /// - /// - /// The local IPv4 address of the interface or the interface index on which the multicast group should be filtered. This value - /// is in network byte order. If this member specifies an IPv4 address of 0.0.0.0, the default IPv4 multicast interface is used. - /// - /// To use an interface index of 1 would be the same as an IP address of 0.0.0.1. - /// - public IN_ADDR imsf_interface; - - /// - /// - /// The multicast filter mode to be used. This parameter can be either MCAST_INCLUDE (value of 0) to include particular - /// multicast sources, or MCAST_EXCLUDE (value of 1) to exclude traffic from specified sources. - /// - /// On Windows Server 2003 and Windows XP, these values are defined in the Ws2tcpip.h header file. - /// - /// On Windows Vistaand later, these values are defined as enumeration values in the MULTICAST_MODE_TYPE enumeration defined in - /// the Ws2ipdef.h header file. - /// - /// - public MULTICAST_MODE_TYPE imsf_fmode; - - /// The number of sources in the imsf_slist member. - public uint imsf_numsrc; - - /// An array of in_addr structures that specify the IPv4 multicast source addresses to include or exclude. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] - public IN_ADDR[] imsf_slist; - } - - /// The ipv6_mreq structure provides multicast group information for IPv6 addresses. - /// - /// - /// The ipv6_mreq structure is used with IPv6 addresses. The ipv6_mreq structure is used with the IPV6_ADD_MEMBERSHIP, - /// IPV6_DROP_MEMBERSHIP, IPV6_JOIN_GROUP, and IPV6_LEAVE_GROUP socket options. The IPV6_JOIN_GROUP and - /// IPV6_ADD_MEMBERSHIP socket options are defined to be the same. The IPV6_LEAVE_GROUP and IPV6_DROP_MEMBERSHIP - /// socket options are defined to be the same. - /// - /// - /// On Windows Vista and later, a set of socket options are available for multicast programming that support IPv6 and IPv4 addresses. - /// These socket options are IP agnostic and can be used on both IPv6 and IPv4. These IP agnostic options use the GROUP_REQ and the - /// GROUP_SOURCE_REQ structures and are the preferred socket options for multicast programming on Windows Vista and later. - /// - /// The ipv6_mreq structure is the IPv6 equivalent of the IPv4-based ip_mreq structure. - /// - /// The GetAdaptersAddresses function can be used to obtain interface index information required for the ipv6mr_interface member. - /// - /// - /// The ipv6_mreq structure and the IPPROTO_IPV6 level socket options that use this structure are only valid on - /// datagram and raw sockets (the socket type must be SOCK_DGRAM or SOCK_RAW). - /// - /// - /// It is recommended that a local IPv6 interface index always be specified in the ipv6mr_interface member of the - /// ipv6_mreq structure, rather than use the default interface. This is particularly important on computers with multiple - /// network interfaces and multiple public IPv6 addresses. - /// - /// - /// The default interface used for IPv6 multicast is determined by the networking stack in Windows. On Windows Vista and later, an - /// application can determine the default interface used for IPv6 multicast using the GetIpForwardTable2 function to retrieve the - /// IPv6 routing table. The network interface with the lowest value for the routing metric for a destination IPv6 multicast address - /// (the FF00::/8 IPv6 address block) is the default interface for IPv6 multicast. The routing table can also be displayed from the - /// command prompt with the following command: - /// - /// route print - /// - /// The IPV6_MULTICAST_IF socket option can be used to set the default interface to send IPv6 multicast packets. This socket option - /// does not change the default interface used to receive IPv6 multicast packets. - /// - /// - /// A typical IPv6 multicast application would use the IPV6_ADD_MEMBERSHIP or IPV6_JOIN_GROUP socket option with the - /// ipv6_mreq structure to join a multicast group and listen for multicast packets on a specific interface. The - /// IPV6_MULTICAST_IF socket option would be used to set the interface to send IPv6 multicast packets to the multicast group. - /// The most common scenario would be a multicast application that listens and sends on the same interface for a multicast group. - /// Multiple sockets might be used by a multicast application with one socket for listening and one or more sockets for sending. - /// - /// - /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files - /// has changed and the ipv6_mreq structure is defined in the Ws2ipdef.h header file which is automatically included in - /// the Ws2tcpip.h header file. The Ws2ipdef.h header files should never be used directly. - /// - /// - /// Note The PIP6_MREQ derived structure is only defined on the Windows SDK released with Windows Vista and later. The - /// GROUP_REQ and the GROUP_SOURCE_REQ structures and are the preferred socket options for multicast programming on Windows Vista and later. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-ipv6_mreq typedef struct ipv6_mreq { IN6_ADDR - // ipv6mr_multiaddr; ULONG ipv6mr_interface; } IPV6_MREQ, *PIPV6_MREQ; - [PInvokeData("ws2ipdef.h", MSDNShortId = "NS:ws2ipdef.ipv6_mreq")] - [StructLayout(LayoutKind.Sequential)] - public struct IPV6_MREQ - { - /// The address of the IPv6 multicast group. - public IN6_ADDR ipv6mr_multiaddr; - - /// - /// The interface index of the local interface on which the multicast group should be joined or dropped. If this member specifies - /// an interface index of 0, the default multicast interface is used. - /// - public uint ipv6mr_interface; - } - - /// The SOCKADDR_IN6 structure specifies a transport address and port for the AF_INET6 address family. - /// - /// - /// All of the data in the SOCKADDR_IN6 structure, except for the address family, must be specified in network-byte-order (big-endian). - /// - /// - /// The size of the SOCKADDR_IN6 structure is too large to fit in the memory space that is provided by a SOCKADDR structure. For a - /// structure that is guaranteed to be large enough to contain a transport address for all possible address families, see SOCKADDR_STORAGEa>. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-sockaddr_in6_lh typedef struct sockaddr_in6 { - // ADDRESS_FAMILY sin6_family; USHORT sin6_port; ULONG sin6_flowinfo; IN6_ADDR sin6_addr; union { ULONG sin6_scope_id; SCOPE_ID - // sin6_scope_struct; }; } SOCKADDR_IN6_LH, *PSOCKADDR_IN6_LH, *LPSOCKADDR_IN6_LH; - [PInvokeData("ws2ipdef.h", MSDNShortId = "ef2955d2-5dc1-420b-a9e0-32a584059d5a")] - [StructLayout(LayoutKind.Sequential, Pack = 2)] - public struct SOCKADDR_IN6 - { - /// The address family for the transport address. This member should always be set to AF_INET6. - public ADDRESS_FAMILY sin6_family; - - /// A transport protocol port number. - public ushort sin6_port; - - /// The IPv6 flow information. - public uint sin6_flowinfo; - - /// An IN6_ADDR structure that contains an IPv6 transport address. - public IN6_ADDR sin6_addr; - - /// A ULONG representation of the IPv6 scope identifier that is defined in the sin6_scope_struct member. - public uint sin6_scope_id; - - /// Initializes a new instance of the struct. - /// A byte array that contains an IPv6 transport address. - /// - /// A ULONG representation of the IPv6 scope identifier that is defined in the sin6_scope_struct member. - /// - /// A transport protocol port number. - public SOCKADDR_IN6(byte[] addr, uint scope_id, ushort port = 0) : this(new IN6_ADDR(addr), scope_id, port) - { - } - - /// Initializes a new instance of the struct. - /// An IN6_ADDR structure that contains an IPv6 transport address. - /// - /// A ULONG representation of the IPv6 scope identifier that is defined in the sin6_scope_struct member. - /// - /// A transport protocol port number. - public SOCKADDR_IN6(IN6_ADDR addr, uint scope_id, ushort port = 0) - { - sin6_family = ADDRESS_FAMILY.AF_INET6; - sin6_port = port; - sin6_flowinfo = 0; - sin6_addr = addr; - sin6_scope_id = scope_id; - } - - /// Initializes a new instance of the struct from a . - /// The IPv4 socket address. - public SOCKADDR_IN6(SOCKADDR_IN v4) : this(new IN6_ADDR(v4.sin_addr), 0, v4.sin_port) { } - - /// Performs an implicit conversion from to . - /// The address. - /// The resulting instance from the conversion. - public static implicit operator SOCKADDR_IN6(IN6_ADDR addr) => new(addr, 0); - - /// Represents an IPv6 anycast socket address. - public static readonly SOCKADDR_IN6 IN6ADDR_ANY = new() { sin6_family = ADDRESS_FAMILY.AF_INET6, sin6_addr = IN6_ADDR.Unspecified }; - - /// Represents an IPv6 LOOPBACK socket address. - public static readonly SOCKADDR_IN6 IN6ADDR_LOOPBACK = new() { sin6_family = ADDRESS_FAMILY.AF_INET6, sin6_addr = IN6_ADDR.Loopback }; - - /// - public override string ToString() => $"{sin6_addr}" + (sin6_scope_id == 0 ? "" : "%" + sin6_scope_id.ToString()) + $":{sin6_port}"; - } + /// + /// The SOCKADDR_IN6_PAIR structure contains pointers to a pair of IP addresses that represent a source and destination + /// address pair. + /// + /// + /// The SOCKADDR_IN6_PAIR structure is defined on Windows Vista and later. + /// + /// Any IPv4 addresses in the SOCKADDR_IN6_PAIR structure must be represented in the IPv4-mapped IPv6 address format which + /// enables an IPv6 only application to communicate with an IPv4 node. For more information on the IPv4-mapped IPv6 address format, + /// see Dual-Stack Sockets. + /// + /// The SOCKADDR_IN6_PAIR structure is used by the CreateSortedAddressPairs function. + /// Note that the Ws2ipdef.h header file is automatically included in Ws2tcpip.h header file, and should never be used directly. + /// + // https://docs.microsoft.com/en-us/windows/desktop/api/ws2ipdef/ns-ws2ipdef-_sockaddr_in6_pair typedef struct _sockaddr_in6_pair { + // PSOCKADDR_IN6 SourceAddress; PSOCKADDR_IN6 DestinationAddress; } SOCKADDR_IN6_PAIR, *PSOCKADDR_IN6_PAIR; + [PInvokeData("ws2ipdef.h", MSDNShortId = "0265f8e0-8b35-4d9d-bf22-e98e9ff36a17")] + [StructLayout(LayoutKind.Sequential)] + public struct SOCKADDR_IN6_PAIR_NATIVE + { + /// + /// A pointer to an IP source address represented as a SOCKADDR_IN6 structure. The address family is in host byte order and the + /// IPv6 address, port, flow information, and zone ID are in network byte order. + /// + public SOCKADDR_IN6 SourceAddress; /// - /// The SOCKADDR_IN6_PAIR structure contains pointers to a pair of IP addresses that represent a source and destination - /// address pair. + /// A pointer to an IP source address represented as a SOCKADDR_IN6 structure. The address family is in host byte order and the + /// IPv6 address, port, flow information, and zone ID are in network byte order. /// - /// - /// The SOCKADDR_IN6_PAIR structure is defined on Windows Vista and later. + public SOCKADDR_IN6 DestinationAddress; + + /// Converts to string. + /// A that represents this instance. + /// + public override string ToString() => $"{SourceAddress} : {DestinationAddress}"; + } + + /// The SOCKADDR_INET union contains an IPv4, an IPv6 address, or an address family. + /// + /// The SOCKADDR_INET union is defined on Windows Vista and later. + /// + /// The SOCKADDR_INET union is a convenience structure for accessing an IPv4 address, an IPv6 address, or the IP address + /// family without having to cast the sockaddr structure. + /// + /// The SOCKADDR_INET union is the data type of the Prefix member in the IP_ADDRESS_PREFIX structure + /// Note that the Ws2ipdef.h header file is automatically included in Ws2tcpip.h header file, and should never be used directly. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-sockaddr_inet typedef union _SOCKADDR_INET { SOCKADDR_IN + // Ipv4; SOCKADDR_IN6 Ipv6; ADDRESS_FAMILY si_family; } SOCKADDR_INET, *PSOCKADDR_INET; + [PInvokeData("ws2ipdef.h", MSDNShortId = "7278dcb4-65c6-4aea-a474-cb7fae4d7672")] + [StructLayout(LayoutKind.Explicit)] + public struct SOCKADDR_INET : IEquatable, IEquatable, IEquatable + { + /// + /// An IPv4 address represented as a SOCKADDR_IN structure containing the address family and the IPv4 address. The address + /// family is in host byte order and the IPv4 address is in network byte order. /// - /// Any IPv4 addresses in the SOCKADDR_IN6_PAIR structure must be represented in the IPv4-mapped IPv6 address format which - /// enables an IPv6 only application to communicate with an IPv4 node. For more information on the IPv4-mapped IPv6 address format, - /// see Dual-Stack Sockets. + /// On the Windows SDK released for Windows Vista and later, the organization of header files has changed and the SOCKADDR_IN + /// structure is defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically included in + /// Winsock2.h, and should never be used directly. /// - /// The SOCKADDR_IN6_PAIR structure is used by the CreateSortedAddressPairs function. - /// Note that the Ws2ipdef.h header file is automatically included in Ws2tcpip.h header file, and should never be used directly. - /// - // https://docs.microsoft.com/en-us/windows/desktop/api/ws2ipdef/ns-ws2ipdef-_sockaddr_in6_pair typedef struct _sockaddr_in6_pair { - // PSOCKADDR_IN6 SourceAddress; PSOCKADDR_IN6 DestinationAddress; } SOCKADDR_IN6_PAIR, *PSOCKADDR_IN6_PAIR; - [PInvokeData("ws2ipdef.h", MSDNShortId = "0265f8e0-8b35-4d9d-bf22-e98e9ff36a17")] - [StructLayout(LayoutKind.Sequential)] - public struct SOCKADDR_IN6_PAIR - { - /// The source address - private readonly IntPtr _SourceAddress; - - /// The destination address - private readonly IntPtr _DestinationAddress; - - /// - /// A pointer to an IP source address represented as a SOCKADDR_IN6 structure. The address family is in host byte order and the - /// IPv6 address, port, flow information, and zone ID are in network byte order. - /// - /// The source address. - public SOCKADDR_IN6 SourceAddress => _SourceAddress.ToStructure(); - - /// - /// A pointer to an IP source address represented as a SOCKADDR_IN6 structure. The address family is in host byte order and the - /// IPv6 address, port, flow information, and zone ID are in network byte order. - /// - /// The destination address. - public SOCKADDR_IN6 DestinationAddress => _DestinationAddress.ToStructure(); - - /// Performs an implicit conversion from to . - /// The unmanaged value. - /// The resulting instance from the conversion. - public static implicit operator SOCKADDR_IN6_PAIR_NATIVE(SOCKADDR_IN6_PAIR unmgd) => - new() - { SourceAddress = unmgd.SourceAddress, DestinationAddress = unmgd.DestinationAddress }; - - /// Converts to string. - /// A that represents this instance. - /// - public override string ToString() => $"{SourceAddress} : {DestinationAddress}"; - } + /// + [FieldOffset(0)] + public SOCKADDR_IN Ipv4; /// - /// The SOCKADDR_IN6_PAIR structure contains pointers to a pair of IP addresses that represent a source and destination - /// address pair. - /// - /// - /// The SOCKADDR_IN6_PAIR structure is defined on Windows Vista and later. + /// An IPv6 address represented as a SOCKADDR_IN6 structure containing the address family and the IPv6 address. The address + /// family is in host byte order and the IPv6 address is in network byte order. /// - /// Any IPv4 addresses in the SOCKADDR_IN6_PAIR structure must be represented in the IPv4-mapped IPv6 address format which - /// enables an IPv6 only application to communicate with an IPv4 node. For more information on the IPv4-mapped IPv6 address format, - /// see Dual-Stack Sockets. + /// On the Windows SDK released for Windows Vista and later, the organization of header files has changed and the SOCKADDR_IN6 + /// structure is defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically included in + /// Winsock2.h, and should never be used directly. /// - /// The SOCKADDR_IN6_PAIR structure is used by the CreateSortedAddressPairs function. - /// Note that the Ws2ipdef.h header file is automatically included in Ws2tcpip.h header file, and should never be used directly. - /// - // https://docs.microsoft.com/en-us/windows/desktop/api/ws2ipdef/ns-ws2ipdef-_sockaddr_in6_pair typedef struct _sockaddr_in6_pair { - // PSOCKADDR_IN6 SourceAddress; PSOCKADDR_IN6 DestinationAddress; } SOCKADDR_IN6_PAIR, *PSOCKADDR_IN6_PAIR; - [PInvokeData("ws2ipdef.h", MSDNShortId = "0265f8e0-8b35-4d9d-bf22-e98e9ff36a17")] - [StructLayout(LayoutKind.Sequential)] - public struct SOCKADDR_IN6_PAIR_NATIVE + /// + [FieldOffset(0)] + public SOCKADDR_IN6 Ipv6; + + /// + /// The address family. + /// + /// Possible values for the address family are listed in the Ws2def.h header file. Note that the values for the AF_ address + /// family and PF_ protocol family constants are identical (for example, AF_INET and PF_INET), so either constant can be + /// used.The Ws2def.h header file is automatically included in Winsock2.h, and should never be used directly. + /// + /// + [FieldOffset(0)] + public ADDRESS_FAMILY si_family; + + /// Gets the size of the actual address (not necessarily the size of the structure). + public int Size => si_family == ADDRESS_FAMILY.AF_INET ? Marshal.SizeOf(typeof(SOCKADDR_IN)) : Marshal.SizeOf(typeof(SOCKADDR_IN6)); + + /// Specifies whether this instance is equal to the specified object. + /// The object to test for equality. + /// if is equal to this instance. + public bool Equals(SOCKADDR_INET other) => (si_family == ADDRESS_FAMILY.AF_INET && Ipv4.Equals(other.Ipv4)) || (si_family == ADDRESS_FAMILY.AF_INET6 && Ipv6.Equals(other.Ipv6)); + + /// Specifies whether this instance is equal to the specified object. + /// The object to test for equality. + /// if is equal to this instance. + public bool Equals(SOCKADDR_IN other) => si_family == ADDRESS_FAMILY.AF_INET && Ipv4.Equals(other); + + /// Specifies whether this instance is equal to the specified object. + /// The object to test for equality. + /// if is equal to this instance. + public bool Equals(SOCKADDR_IN6 other) => si_family == ADDRESS_FAMILY.AF_INET6 && Ipv6.Equals(other); + + /// Performs an implicit conversion from to . + /// The address. + /// The resulting instance from the conversion. + public static implicit operator SOCKADDR_INET(SOCKADDR_IN address) => new() { Ipv4 = address }; + + /// Performs an implicit conversion from to . + /// The address. + /// The resulting instance from the conversion. + public static implicit operator SOCKADDR_INET(SOCKADDR_IN6 address) => new() { Ipv6 = address }; + + /// Performs an explicit conversion from to . + /// The address. + /// The result of the conversion. + public static explicit operator SOCKADDR_INET(System.Net.IPEndPoint address) { - /// - /// A pointer to an IP source address represented as a SOCKADDR_IN6 structure. The address family is in host byte order and the - /// IPv6 address, port, flow information, and zone ID are in network byte order. - /// - public SOCKADDR_IN6 SourceAddress; - - /// - /// A pointer to an IP source address represented as a SOCKADDR_IN6 structure. The address family is in host byte order and the - /// IPv6 address, port, flow information, and zone ID are in network byte order. - /// - public SOCKADDR_IN6 DestinationAddress; - - /// Converts to string. - /// A that represents this instance. - /// - public override string ToString() => $"{SourceAddress} : {DestinationAddress}"; + if (address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) + return new() { Ipv4 = new SOCKADDR_IN(new(address.Address.GetAddressBytes()), (ushort)address.Port) }; + return new() { Ipv6 = new SOCKADDR_IN6(address.Address.GetAddressBytes(), (uint)address.Address.ScopeId, (ushort)address.Port) }; } - /// The SOCKADDR_INET union contains an IPv4, an IPv6 address, or an address family. - /// - /// The SOCKADDR_INET union is defined on Windows Vista and later. - /// - /// The SOCKADDR_INET union is a convenience structure for accessing an IPv4 address, an IPv6 address, or the IP address - /// family without having to cast the sockaddr structure. - /// - /// The SOCKADDR_INET union is the data type of the Prefix member in the IP_ADDRESS_PREFIX structure - /// Note that the Ws2ipdef.h header file is automatically included in Ws2tcpip.h header file, and should never be used directly. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/ws2ipdef/ns-ws2ipdef-sockaddr_inet typedef union _SOCKADDR_INET { SOCKADDR_IN - // Ipv4; SOCKADDR_IN6 Ipv6; ADDRESS_FAMILY si_family; } SOCKADDR_INET, *PSOCKADDR_INET; - [PInvokeData("ws2ipdef.h", MSDNShortId = "7278dcb4-65c6-4aea-a474-cb7fae4d7672")] - [StructLayout(LayoutKind.Explicit)] - public struct SOCKADDR_INET : IEquatable, IEquatable, IEquatable + /// Converts to string. + /// A that represents this instance. + public override string ToString() { - /// - /// An IPv4 address represented as a SOCKADDR_IN structure containing the address family and the IPv4 address. The address - /// family is in host byte order and the IPv4 address is in network byte order. - /// - /// On the Windows SDK released for Windows Vista and later, the organization of header files has changed and the SOCKADDR_IN - /// structure is defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically included in - /// Winsock2.h, and should never be used directly. - /// - /// - [FieldOffset(0)] - public SOCKADDR_IN Ipv4; - - /// - /// An IPv6 address represented as a SOCKADDR_IN6 structure containing the address family and the IPv6 address. The address - /// family is in host byte order and the IPv6 address is in network byte order. - /// - /// On the Windows SDK released for Windows Vista and later, the organization of header files has changed and the SOCKADDR_IN6 - /// structure is defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically included in - /// Winsock2.h, and should never be used directly. - /// - /// - [FieldOffset(0)] - public SOCKADDR_IN6 Ipv6; - - /// - /// The address family. - /// - /// Possible values for the address family are listed in the Ws2def.h header file. Note that the values for the AF_ address - /// family and PF_ protocol family constants are identical (for example, AF_INET and PF_INET), so either constant can be - /// used.The Ws2def.h header file is automatically included in Winsock2.h, and should never be used directly. - /// - /// - [FieldOffset(0)] - public ADDRESS_FAMILY si_family; - - /// Gets the size of the actual address (not necessarily the size of the structure). - public int Size => si_family == ADDRESS_FAMILY.AF_INET ? Marshal.SizeOf(typeof(SOCKADDR_IN)) : Marshal.SizeOf(typeof(SOCKADDR_IN6)); - - /// Specifies whether this instance is equal to the specified object. - /// The object to test for equality. - /// if is equal to this instance. - public bool Equals(SOCKADDR_INET other) => (si_family == ADDRESS_FAMILY.AF_INET && Ipv4.Equals(other.Ipv4)) || (si_family == ADDRESS_FAMILY.AF_INET6 && Ipv6.Equals(other.Ipv6)); - - /// Specifies whether this instance is equal to the specified object. - /// The object to test for equality. - /// if is equal to this instance. - public bool Equals(SOCKADDR_IN other) => si_family == ADDRESS_FAMILY.AF_INET && Ipv4.Equals(other); - - /// Specifies whether this instance is equal to the specified object. - /// The object to test for equality. - /// if is equal to this instance. - public bool Equals(SOCKADDR_IN6 other) => si_family == ADDRESS_FAMILY.AF_INET6 && Ipv6.Equals(other); - - /// Performs an implicit conversion from to . - /// The address. - /// The resulting instance from the conversion. - public static implicit operator SOCKADDR_INET(SOCKADDR_IN address) => new() { Ipv4 = address }; - - /// Performs an implicit conversion from to . - /// The address. - /// The resulting instance from the conversion. - public static implicit operator SOCKADDR_INET(SOCKADDR_IN6 address) => new() { Ipv6 = address }; - - /// Performs an explicit conversion from to . - /// The address. - /// The result of the conversion. - public static explicit operator SOCKADDR_INET(System.Net.IPEndPoint address) - { - if (address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) - return new() { Ipv4 = new SOCKADDR_IN(new(address.Address.GetAddressBytes()), (ushort)address.Port) }; - return new() { Ipv6 = new SOCKADDR_IN6(address.Address.GetAddressBytes(), (uint)address.Address.ScopeId, (ushort)address.Port) }; - } - - /// Converts to string. - /// A that represents this instance. - public override string ToString() - { - var sb = new System.Text.StringBuilder($"{si_family}"); - if (si_family == ADDRESS_FAMILY.AF_INET) - sb.Append(":").Append(Ipv4); - else if (si_family == ADDRESS_FAMILY.AF_INET6) - sb.Append(":").Append(Ipv6); - return sb.ToString(); - } + var sb = new System.Text.StringBuilder($"{si_family}"); + if (si_family == ADDRESS_FAMILY.AF_INET) + sb.Append(":").Append(Ipv4); + else if (si_family == ADDRESS_FAMILY.AF_INET6) + sb.Append(":").Append(Ipv6); + return sb.ToString(); } } } \ No newline at end of file