Vanara/PInvoke/Ws2_32/WinSock2.WSA.cs

12129 lines
672 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

using System;
using System.Data;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Text;
using Vanara.Extensions;
using Vanara.InteropServices;
namespace Vanara.PInvoke
{
/// <summary>Functions, structures and constants from ws2_32.h.</summary>
public static partial class Ws2_32
{
/// <summary>The <c>__WSAFDIsSet</c> function specifies whether a socket is included in a set of socket descriptors.</summary>
/// <param name="arg1">TBD</param>
/// <param name="arg2">
/// Pointer to an fd_set structure containing the set of socket descriptors. The <c>__WSAFDIsSet</c> function determines whether the
/// socket specified in the fd parameter is a member of that set.
/// </param>
/// <returns>None</returns>
/// <remarks>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-__wsafdisset int __WSAFDIsSet( SOCKET , fd_set * );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock.h", MSDNShortId = "ca420136-0b3b-45a1-85ce-83ab6ba1a70a")]
public static extern WSRESULT __WSAFDIsSet(SOCKET arg1, in fd_set arg2);
/// <summary>
/// The <c>WSAAccept</c> function conditionally accepts a connection based on the return value of a condition function, provides
/// quality of service flow specifications, and allows the transfer of connection data.
/// </summary>
/// <param name="s">A descriptor that identifies a socket that is listening for connections after a call to the listen function.</param>
/// <param name="addr">
/// An optional pointer to an sockaddr structure that receives the address of the connecting entity, as known to the communications
/// layer. The exact format of the addr parameter is determined by the address family established when the socket was created.
/// </param>
/// <param name="addrlen">
/// An optional pointer to an integer that contains the length of the sockaddr structure pointed to by the addr parameter, in bytes.
/// </param>
/// <param name="lpfnCondition">
/// The address of an optional, application-specified condition function that will make an accept/reject decision based on the
/// caller information passed in as parameters, and optionally create or join a socket group by assigning an appropriate value to
/// the result parameter g of this function. If this parameter is <c>NULL</c>, then no condition function is called.
/// </param>
/// <param name="dwCallbackData">
/// Callback data passed back to the application-specified condition function as the value of the dwCallbackData parameter passed to
/// the condition function. This parameter is only applicable if the lpfnCondition parameter is not <c>NULL</c>. This parameter is
/// not interpreted by Windows Sockets.
/// </param>
/// <returns>
/// <para>
/// If no error occurs, <c>WSAAccept</c> returns a value of type SOCKET that is a descriptor for the accepted socket. Otherwise, a
/// value of INVALID_SOCKET is returned, and a specific error code can be retrieved by calling WSAGetLastError.
/// </para>
/// <para>
/// The integer referred to by addrlen initially contains the amount of space pointed to by addr. On return it will contain the
/// actual length in bytes of the address returned.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAEACCES</term>
/// <term>
/// An attempt was made to access a socket in a way forbidden by its access permissions. This error is returned if the connection
/// request that was offered has timed out or been withdrawn.
/// </term>
/// </item>
/// <item>
/// <term>WSAECONNREFUSED</term>
/// <term>
/// No connection could be made because the target machine actively refused it. This error is returned if the connection request was
/// forcefully rejected as indicated in the return value of the condition function (CF_REJECT).
/// </term>
/// </item>
/// <item>
/// <term>WSAECONNRESET</term>
/// <term>
/// An existing connection was forcibly closed by the remote host. This error is returned of an incoming connection was indicated,
/// but was subsequently terminated by the remote peer prior to accepting the call.
/// </term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The system detected an invalid pointer address in attempting to use a pointer argument in a call. This error is returned of the
/// addrlen parameter is too small or the addr or lpfnCondition is not part of the user address space.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINTR</term>
/// <term>
/// A blocking operation was interrupted by a call to WSACancelBlockingCall. This error is returned if a blocking Windows Sockets
/// 1.1 call was canceled through WSACancelBlockingCall.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking operation is currently executing. This error is returned if a blocking Windows Sockets 1.1 call is in progress.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>
/// An invalid argument was supplied. This error is returned if listen was not invoked prior to WSAAccept, the return value of the
/// condition function is not a valid one, or any case where the specified socket is in an invalid state.
/// </term>
/// </item>
/// <item>
/// <term>WSAEMFILE</term>
/// <term>
/// Too many open sockets. This error is returned if the queue is nonempty upon entry to WSAAccept and there are no socket
/// descriptors available.
/// </term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>A socket operation encountered a dead network. This error is returned if the network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>
/// 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 returned if no buffer space is available.
/// </term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>
/// An operation was attempted on something that is not a socket. This error is returned if the socket descriptor passed in the s
/// parameter is not a socket.
/// </term>
/// </item>
/// <item>
/// <term>WSAEOPNOTSUPP</term>
/// <term>
/// The protocol family has not been configured into the system or no implementation for it exists. This error is returned if the
/// referenced socket is not a type that supports connection-oriented service.
/// </term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>
/// A non-blocking socket operation could not be completed immediately. This error is returned if the socket is marked as
/// nonblocking and no connections are present to be accepted.
/// </term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>
/// Either the application has not called WSAStartup, or WSAStartup failed. This error is returned of a successful call to the
/// WSAStartup function dit not occur before using this function.
/// </term>
/// </item>
/// <item>
/// <term>WSATRY_AGAIN</term>
/// <term>
/// This is usually a temporary error during hostname resolution and means that the local server did not receive a response from an
/// authoritative server. This error is returned if the acceptance of the connection request was deferred as indicated in the return
/// value of the condition function (CF_DEFER).
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAAccept</c> function extracts the first connection on the queue of pending connections on socket s, and checks it
/// against the condition function, provided the condition function is specified (that is, not <c>NULL</c>). If the condition
/// function returns CF_ACCEPT, <c>WSAAccept</c> creates a new socket. The newly created socket has the same properties as socket s
/// including asynchronous events registered with WSAAsyncSelect or with WSAEventSelect. If the condition function returns
/// CF_REJECT, <c>WSAAccept</c> rejects the connection request. The condition function runs in the same thread as this function
/// does, and should return as soon as possible. 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 <c>WSAAccept</c> again and
/// return either CF_ACCEPT or CF_REJECT as a return value from the condition function.
/// </para>
/// <para>
/// A socket in default mode (blocking) will block until a connection is present when an application calls <c>WSAAccept</c> and no
/// connections are pending on the queue.
/// </para>
/// <para>
/// A socket in nonblocking mode (blocking) fails with the error WSAEWOULDBLOCK when an application calls <c>WSAAccept</c> and no
/// connections are pending on the queue. After <c>WSAAccept</c> succeeds and returns a new socket handle, the accepted socket
/// cannot be used to accept any more connections. The original socket remains open and listens for new connection requests.
/// </para>
/// <para>
/// The addr parameter is a result parameter that is filled in with the address of the connecting entity, as known to the
/// communications layer. The exact format of the addr parameter is determined by the address family in which the communication is
/// occurring. The addrlen is a value-result parameter; it should initially contain the amount of space pointed to by addr. On
/// return, it will contain the actual length (in bytes) of the address returned. This call is used with connection-oriented socket
/// types such as SOCK_STREAM. If addr and/or addrlen are equal to <c>NULL</c>, then no information about the remote address of the
/// accepted socket is returned. Otherwise, these two parameters will be filled in if the connection is successfully accepted.
/// </para>
/// <para>A prototype of the condition function is defined in the Winsock2.h header file as the <c>LPCONDITIONPROC</c> as follows:</para>
/// <para>
/// The <c>ConditionFunc</c> is a placeholder for the application-specified callback function. The actual condition function must
/// reside in a DLL or application module. It is exported in the module definition file.
/// </para>
/// <para>
/// The lpCallerId parameter points to 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. The lpCallerData is 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 <c>NULL</c>. 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
/// <c>sockaddr</c> structure is interpreted according to its address family (typically by casting the <c>sockaddr</c> to some type
/// specific to the address family).
/// </para>
/// <para>
/// The lpSQOS parameter 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 <c>NULL</c> value indicates that there is no caller-supplied quality of service
/// and that no negotiation is possible. A non- <c>NULL</c> 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.
/// </para>
/// <para>
/// The lpGQOS parameter is reserved, and should be <c>NULL</c>. (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 <c>NULL</c> value for lpGQOS indicates no caller-specified group quality of service. Quality of
/// service information can be returned if negotiation is to occur.
/// </para>
/// <para>
/// The lpCalleeId is a parameter that contains the local address of the connected entity. The buf portion of the WSABUF pointed to
/// by lpCalleeId points to a sockaddr structure. The <c>sockaddr</c> structure is interpreted according to its address family
/// (typically by casting the <c>sockaddr</c> to some type specific to the address family such as struct <c>sockaddr_in</c>).
/// </para>
/// <para>
/// The lpCalleeData is a result parameter used by the condition function to supply user data back to the connecting entity. The
/// lpCalleeData-&gt;len initially contains the length of the buffer allocated by the service provider and pointed to by
/// lpCalleeData-&gt;buf. A value of zero means passing user data back to the caller is not supported. The condition function should
/// copy up to lpCalleeData-&gt;len bytes of data into lpCalleeData-&gt;buf, and then update lpCalleeData-&gt;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-&gt;len to zero. The format of all address and user data is specific to the address family to which the socket belongs.
/// </para>
/// <para>The g parameter is assigned within the condition function to indicate any of the following actions:</para>
/// <list type="bullet">
/// <item>
/// <term>
/// If g is an existing socket group identifier, add s to this group, provided all the requirements set by this group are met.
/// </term>
/// </item>
/// <item>
/// <term>If g = SG_UNCONSTRAINED_GROUP, create an unconstrained socket group and have s as the first member.</term>
/// </item>
/// <item>
/// <term>If g = SG_CONSTRAINED_GROUP, create a constrained socket group and have s as the first member.</term>
/// </item>
/// <item>
/// <term>If g = zero, no group operation is performed.</term>
/// </item>
/// </list>
/// <para>
/// 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 <c>SO_GROUP_ID</c>. 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.
/// </para>
/// <para>
/// The dwCallbackData parameter value passed to the condition function is the value passed as the dwCallbackData parameter in the
/// original <c>WSAAccept</c> call. This value is interpreted only by the Windows Socket version 2 client. This allows a client to
/// pass some context information from the <c>WSAAccept</c> 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.
/// </para>
/// <para>
/// <c>Note</c> To protect use of the <c>WSAAccept</c> function from SYN attacks, applications must perform full TCP handshakes
/// (SYN-SYNACK-ACK) before reporting the connection request. Protecting against SYN attacks in this manner results in the
/// SO_CONDITIONAL_ACCEPT socket option becoming inoperative; the conditional function is still called, and the <c>WSAAccept</c>
/// function operates properly, but server applications that rely on clients being unable to perform the handshake will not operate properly.
/// </para>
/// <para>
/// <c>Note</c> When issuing a blocking Winsock call such as <c>WSAAccept</c>, 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.
/// </para>
/// <para>Example Code</para>
/// <para>The following example demonstrates the use of the <c>WSAAccept</c> function.</para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winsock2/nf-winsock2-wsaaccept SOCKET WSAAPI WSAAccept( SOCKET s, sockaddr
// *addr, LPINT addrlen, LPCONDITIONPROC lpfnCondition, DWORD_PTR dwCallbackData );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "f385f63f-49b2-4eb7-8717-ad4cca1a2252")]
public static extern SOCKET WSAAccept(SOCKET s, SOCKADDR addr, ref int addrlen, [In, Out, Optional] ConditionFunc lpfnCondition, [In, Out, Optional] IntPtr dwCallbackData);
/// <summary>
/// <para>
/// The <c>WSAAddressToString</c> function converts all components of a sockaddr structure into a human-readable string
/// representation of the address.
/// </para>
/// <para>
/// This is intended to be used mainly for display purposes. If the caller requires that the translation to be performed by a
/// particular provider, it should supply the corresponding WSAPROTOCOL_INFO structure in the lpProtocolInfo parameter.
/// </para>
/// </summary>
/// <param name="lpsaAddress">A pointer to the sockaddr structure to translate into a string.</param>
/// <param name="dwAddressLength">
/// The length, in bytes, of the address in the sockaddr structure pointed to by the lpsaAddress parameter. The dwAddressLength
/// parameter may vary in size with different protocols.
/// </param>
/// <param name="lpProtocolInfo">
/// A pointer to the WSAPROTOCOL_INFO structure for a particular provider. If this is parameter is <c>NULL</c>, the call is routed
/// to the provider of the first protocol supporting the address family indicated in the lpsaAddress parameter.
/// </param>
/// <param name="lpszAddressString">A pointer to the buffer that receives the human-readable address string.</param>
/// <param name="lpdwAddressStringLength">
/// On input, this parameter specifies the length of the buffer pointed to by the lpszAddressString parameter. The length is
/// represented in bytes for ANSI strings, and in WCHARs for Unicode strings. On output, this parameter returns the length of the
/// string including the <c>NULL</c> terminator actually copied into the buffer pointed to by the lpszAddressString parameter. If
/// the specified buffer is not large enough, the function fails with a specific error of WSAEFAULT and this parameter is updated
/// with the required size.
/// </param>
/// <returns>
/// <para>
/// If no error occurs, <c>WSAAddressToString</c> returns a value of zero. Otherwise, the value SOCKET_ERROR is returned, and a
/// specific error number can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The specified lpcsAddress, lpProtocolInfo, and lpszAddressString parameters point to memory that is not all in the address space
/// of the process, or the buffer pointed to by the lpszAddressString parameter is too small. Pass in a larger buffer.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>
/// An invalid parameter was passed. This error is returned if the lpsaAddress, dwAddressLength, or lpdwAddressStringLength
/// parameter are NULL. This error is also returned if the specified address is not a valid socket address, or no transport provider
/// supports the indicated address family.
/// </term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>No buffer space is available.</term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>
/// The Winsock 2 DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAAddressToString</c> function provides a protocol-independent address-to-string translation. The
/// <c>WSAAddressToString</c> function takes a socket address structure pointed to by the lpsaAddress parameter and returns a
/// pointer to <c>NULL</c>-terminated string that represents the socket address in the lpszAddressString parameter. While the
/// inet_ntoa function works only with IPv4 addresses, the <c>WSAAddressToString</c> function works with any socket address
/// supported by a Winsock provider on the local computer including IPv6 addresses.
/// </para>
/// <para>
/// If the lpsaAddress parameter points to an IPv4 socket address (the address family is <c>AF_INET</c>), then the address string
/// returned in the buffer pointed to by the lpszAddressString parameter is in dotted-decimal notation as in "192.168.16.0", an
/// example of an IPv4 address in dotted-decimal notation.
/// </para>
/// <para>
/// If the lpsaAddress parameter points to an IPv6 socket address (the address family is <c>AF_INET6</c>), then the address string
/// returned in the buffer pointed to by the lpszAddressString parameter is in Internet standard format. The basic string
/// representation consists of 8 hexadecimal numbers separated by colons. A string of consecutive zero numbers is replaced with a
/// double-colon. There can only be one double-colon in the string representation of the IPv6 address.
/// </para>
/// <para>
/// If the length of the buffer pointed to by the lpszAddressString parameter is not large enough to receive the string
/// representation of the socket address, <c>WSAAddressToString</c> returns WSAEFAULT.
/// </para>
/// <para>
/// Support for IPv6 addresses using the <c>WSAAddressToString</c> function was added on Windows XP with Service Pack 1 (SP1)and
/// later. IPv6 must also be installed on the local computer for the <c>WSAAddressToString</c> function to support IPv6 addresses.
/// </para>
/// <para>
/// <c>Windows Phone 8:</c> The <c>WSAAddressToStringW</c> function is supported for Windows Phone Store apps on Windows Phone 8 and later.
/// </para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: The <c>WSAAddressToStringW</c> function is supported for Windows Store
/// apps on Windows 8.1, Windows Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winsock2/nf-winsock2-wsaaddresstostringa INT WSAAPI WSAAddressToStringA(
// LPSOCKADDR lpsaAddress, DWORD dwAddressLength, LPWSAPROTOCOL_INFOA lpProtocolInfo, LPSTR lpszAddressString, LPDWORD
// lpdwAddressStringLength );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winsock2.h", MSDNShortId = "d72e55e6-79a9-4386-9e1a-24a322f13426")]
public static extern WSRESULT WSAAddressToString([In] SOCKADDR lpsaAddress, uint dwAddressLength, in WSAPROTOCOL_INFO lpProtocolInfo, StringBuilder lpszAddressString, ref uint lpdwAddressStringLength);
/// <summary>
/// <para>
/// The <c>WSAAddressToString</c> function converts all components of a sockaddr structure into a human-readable string
/// representation of the address.
/// </para>
/// <para>
/// This is intended to be used mainly for display purposes. If the caller requires that the translation to be performed by a
/// particular provider, it should supply the corresponding WSAPROTOCOL_INFO structure in the lpProtocolInfo parameter.
/// </para>
/// </summary>
/// <param name="lpsaAddress">A pointer to the sockaddr structure to translate into a string.</param>
/// <param name="lpProtocolInfo">
/// A pointer to the WSAPROTOCOL_INFO structure for a particular provider. If this is parameter is <c>NULL</c>, the call is routed
/// to the provider of the first protocol supporting the address family indicated in the lpsaAddress parameter.
/// </param>
/// <returns>The human-readable address string.</returns>
/// <remarks>
/// <para>
/// The <c>WSAAddressToString</c> function provides a protocol-independent address-to-string translation. The
/// <c>WSAAddressToString</c> function takes a socket address structure pointed to by the lpsaAddress parameter and returns a
/// pointer to <c>NULL</c>-terminated string that represents the socket address in the lpszAddressString parameter. While the
/// inet_ntoa function works only with IPv4 addresses, the <c>WSAAddressToString</c> function works with any socket address
/// supported by a Winsock provider on the local computer including IPv6 addresses.
/// </para>
/// <para>
/// If the lpsaAddress parameter points to an IPv4 socket address (the address family is <c>AF_INET</c>), then the address string
/// returned in the buffer pointed to by the lpszAddressString parameter is in dotted-decimal notation as in "192.168.16.0", an
/// example of an IPv4 address in dotted-decimal notation.
/// </para>
/// <para>
/// If the lpsaAddress parameter points to an IPv6 socket address (the address family is <c>AF_INET6</c>), then the address string
/// returned in the buffer pointed to by the lpszAddressString parameter is in Internet standard format. The basic string
/// representation consists of 8 hexadecimal numbers separated by colons. A string of consecutive zero numbers is replaced with a
/// double-colon. There can only be one double-colon in the string representation of the IPv6 address.
/// </para>
/// <para>
/// Support for IPv6 addresses using the <c>WSAAddressToString</c> function was added on Windows XP with Service Pack 1 (SP1)and
/// later. IPv6 must also be installed on the local computer for the <c>WSAAddressToString</c> function to support IPv6 addresses.
/// </para>
/// <para>
/// <c>Windows Phone 8:</c> The <c>WSAAddressToStringW</c> function is supported for Windows Phone Store apps on Windows Phone 8 and later.
/// </para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: The <c>WSAAddressToStringW</c> function is supported for Windows Store
/// apps on Windows 8.1, Windows Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winsock2/nf-winsock2-wsaaddresstostringa INT WSAAPI WSAAddressToStringA(
// LPSOCKADDR lpsaAddress, DWORD dwAddressLength, LPWSAPROTOCOL_INFOA lpProtocolInfo, LPSTR lpszAddressString, LPDWORD
// lpdwAddressStringLength );
[PInvokeData("winsock2.h", MSDNShortId = "d72e55e6-79a9-4386-9e1a-24a322f13426")]
public static string WSAAddressToString([In] SOCKADDR lpsaAddress, [In, Optional] WSAPROTOCOL_INFO? lpProtocolInfo)
{
using var pc = lpProtocolInfo.HasValue ? new SafeCoTaskMemStruct<WSAPROTOCOL_INFO>(lpProtocolInfo.Value) : SafeCoTaskMemStruct<WSAPROTOCOL_INFO>.Null;
var sz = 1024U;
var err = WSAAddressToString(lpsaAddress, (uint)lpsaAddress.Size, pc, null, ref sz);
if (err == WSRESULT.WSAEFAULT && sz > 0)
{
StringBuilder sb = new((int)sz);
err = WSAAddressToString(lpsaAddress, (uint)lpsaAddress.Size, pc, sb, ref sz);
if (err == 0) return sb.ToString();
}
throw err.GetException();
}
/// <summary>
/// <para>
/// The <c>WSAAddressToString</c> function converts all components of a sockaddr structure into a human-readable string
/// representation of the address.
/// </para>
/// <para>
/// This is intended to be used mainly for display purposes. If the caller requires that the translation to be performed by a
/// particular provider, it should supply the corresponding WSAPROTOCOL_INFO structure in the lpProtocolInfo parameter.
/// </para>
/// </summary>
/// <param name="lpsaAddress">A pointer to the sockaddr structure to translate into a string.</param>
/// <param name="dwAddressLength">
/// The length, in bytes, of the address in the sockaddr structure pointed to by the lpsaAddress parameter. The dwAddressLength
/// parameter may vary in size with different protocols.
/// </param>
/// <param name="lpProtocolInfo">
/// A pointer to the WSAPROTOCOL_INFO structure for a particular provider. If this is parameter is <c>NULL</c>, the call is routed
/// to the provider of the first protocol supporting the address family indicated in the lpsaAddress parameter.
/// </param>
/// <param name="lpszAddressString">A pointer to the buffer that receives the human-readable address string.</param>
/// <param name="lpdwAddressStringLength">
/// On input, this parameter specifies the length of the buffer pointed to by the lpszAddressString parameter. The length is
/// represented in bytes for ANSI strings, and in WCHARs for Unicode strings. On output, this parameter returns the length of the
/// string including the <c>NULL</c> terminator actually copied into the buffer pointed to by the lpszAddressString parameter. If
/// the specified buffer is not large enough, the function fails with a specific error of WSAEFAULT and this parameter is updated
/// with the required size.
/// </param>
/// <returns>
/// <para>
/// If no error occurs, <c>WSAAddressToString</c> returns a value of zero. Otherwise, the value SOCKET_ERROR is returned, and a
/// specific error number can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The specified lpcsAddress, lpProtocolInfo, and lpszAddressString parameters point to memory that is not all in the address space
/// of the process, or the buffer pointed to by the lpszAddressString parameter is too small. Pass in a larger buffer.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>
/// An invalid parameter was passed. This error is returned if the lpsaAddress, dwAddressLength, or lpdwAddressStringLength
/// parameter are NULL. This error is also returned if the specified address is not a valid socket address, or no transport provider
/// supports the indicated address family.
/// </term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>No buffer space is available.</term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>
/// The Winsock 2 DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAAddressToString</c> function provides a protocol-independent address-to-string translation. The
/// <c>WSAAddressToString</c> function takes a socket address structure pointed to by the lpsaAddress parameter and returns a
/// pointer to <c>NULL</c>-terminated string that represents the socket address in the lpszAddressString parameter. While the
/// inet_ntoa function works only with IPv4 addresses, the <c>WSAAddressToString</c> function works with any socket address
/// supported by a Winsock provider on the local computer including IPv6 addresses.
/// </para>
/// <para>
/// If the lpsaAddress parameter points to an IPv4 socket address (the address family is <c>AF_INET</c>), then the address string
/// returned in the buffer pointed to by the lpszAddressString parameter is in dotted-decimal notation as in "192.168.16.0", an
/// example of an IPv4 address in dotted-decimal notation.
/// </para>
/// <para>
/// If the lpsaAddress parameter points to an IPv6 socket address (the address family is <c>AF_INET6</c>), then the address string
/// returned in the buffer pointed to by the lpszAddressString parameter is in Internet standard format. The basic string
/// representation consists of 8 hexadecimal numbers separated by colons. A string of consecutive zero numbers is replaced with a
/// double-colon. There can only be one double-colon in the string representation of the IPv6 address.
/// </para>
/// <para>
/// If the length of the buffer pointed to by the lpszAddressString parameter is not large enough to receive the string
/// representation of the socket address, <c>WSAAddressToString</c> returns WSAEFAULT.
/// </para>
/// <para>
/// Support for IPv6 addresses using the <c>WSAAddressToString</c> function was added on Windows XP with Service Pack 1 (SP1)and
/// later. IPv6 must also be installed on the local computer for the <c>WSAAddressToString</c> function to support IPv6 addresses.
/// </para>
/// <para>
/// <c>Windows Phone 8:</c> The <c>WSAAddressToStringW</c> function is supported for Windows Phone Store apps on Windows Phone 8 and later.
/// </para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: The <c>WSAAddressToStringW</c> function is supported for Windows Store
/// apps on Windows 8.1, Windows Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winsock2/nf-winsock2-wsaaddresstostringa INT WSAAPI WSAAddressToStringA(
// LPSOCKADDR lpsaAddress, DWORD dwAddressLength, LPWSAPROTOCOL_INFOA lpProtocolInfo, LPSTR lpszAddressString, LPDWORD
// lpdwAddressStringLength );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winsock2.h", MSDNShortId = "d72e55e6-79a9-4386-9e1a-24a322f13426")]
public static extern WSRESULT WSAAddressToString([In] SOCKADDR lpsaAddress, uint dwAddressLength, [Optional] IntPtr lpProtocolInfo, StringBuilder lpszAddressString, ref uint lpdwAddressStringLength);
/// <summary>
/// <para>The <c>WSAAsyncGetHostByAddr</c> function asynchronously retrieves host information that corresponds to an address.</para>
/// <para>
/// <c>Note</c> The <c>WSAAsyncGetHostByAddr</c> function is not designed to provide parallel resolution of several addresses.
/// Therefore, applications that issue several requests should not expect them to be executed concurrently. Alternatively,
/// applications can start another thread and use the getnameinfo function to resolve addresses in an IP-version agnostic manner.
/// Developers creating Windows Sockets 2 applications are urged to use the <c>getnameinfo</c> function to enable smooth transition
/// to IPv6 compatibility.
/// </para>
/// </summary>
/// <param name="hWnd">[in] The handle of the window which should receive a message when the asynchronous request completes.</param>
/// <param name="wMsg">[in] The message to be received when the asynchronous request completes.</param>
/// <param name="addr">[in] A pointer to the network address for the host. Host addresses are stored in network byte order.</param>
/// <param name="len">[in] The length of the address.</param>
/// <param name="type">[in] The type of the address.</param>
/// <param name="buf">
/// [out] A pointer to the data area to receive the hostent data. Note that this must be larger than the size of a hostent
/// structure. This is because the data area supplied is used by Windows Sockets to contain not only a hostent structure but any and
/// all of the data which is referenced by members of the hostent structure. It is recommended that you supply a buffer of
/// MAXGETHOSTSTRUCT bytes.
/// </param>
/// <param name="buflen">[in] The size of data area buf above.</param>
/// <returns>
/// <para>
/// The return value specifies whether or not the asynchronous operation was successfully initiated. It does not imply success or
/// failure of the operation itself.
/// </para>
/// <para>
/// If no error occurs, <c>WSAAsyncGetHostByAddr</c> returns a nonzero value of type HANDLE that is the asynchronous task handle
/// (not to be confused with a Windows HTASK) for the request. This value can be used in two ways. It can be used to cancel the
/// operation using WSACancelAsyncRequest, or it can be used to match up asynchronous operations and completion messages by
/// examining the wParam message parameter.
/// </para>
/// <para>
/// If the asynchronous operation could not be initiated, <c>WSAAsyncGetHostByAddr</c> returns a zero value, and a specific error
/// number can be retrieved by calling WSAGetLastError.
/// </para>
/// <para>
/// The following error codes can be set when an application window receives a message. As described above, they can be extracted
/// from the lParam in the reply message using the <c>WSAGETASYNCERROR</c> macro.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>Insufficient buffer space is available.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The addr or buf parameter is not in a valid part of the process address space.</term>
/// </item>
/// <item>
/// <term>WSAHOST_NOT_FOUND</term>
/// <term>Authoritative answer host not found.</term>
/// </item>
/// <item>
/// <term>WSATRY_AGAIN</term>
/// <term>Nonauthoritative host not found, or SERVERFAIL.</term>
/// </item>
/// <item>
/// <term>WSANO_RECOVERY</term>
/// <term>Nonrecoverable errors: FORMERR, REFUSED, NOTIMP.</term>
/// </item>
/// <item>
/// <term>WSANO_DATA</term>
/// <term>Valid name, no data record of requested type.</term>
/// </item>
/// </list>
/// <para>
/// The following errors can occur at the time of the function call, and indicate that the asynchronous operation could not be initiated.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error Code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>
/// The asynchronous operation cannot be scheduled at this time due to resource or other constraints within the Windows Sockets implementation.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAAsyncGetHostByAddr</c> function is an asynchronous version of gethostbyaddr. It is used to retrieve the host name and
/// address information that corresponds to a network address. Windows Sockets initiates the operation and returns to the caller
/// immediately, passing back an opaque, asynchronous task handle that the application can use to identify the operation. When the
/// operation is completed, the results (if any) are copied into the buffer provided by the caller and a message is sent to the
/// application's window.
/// </para>
/// <para>
/// When the asynchronous operation has completed, the application window indicated by the hWnd parameter receives message in the
/// wMsg parameter. The wParam parameter contains the asynchronous task handle as returned by the original function call. The high
/// 16 bits of lParam contain any error code. The error code can be any error as defined in Winsock2.h. An error code of zero
/// indicates successful completion of the asynchronous operation.
/// </para>
/// <para>
/// On successful completion, the buffer specified to the original function call contains a hostent structure. To access the members
/// of this structure, the original buffer address is cast to a <c>hostent</c> structure pointer and accessed as appropriate.
/// </para>
/// <para>
/// If the error code is WSAENOBUFS, the size of the buffer specified by buflen in the original call was too small to contain all
/// the resulting information. In this case, the low 16 bits of lParam contain the size of buffer required to supply all the
/// requisite information. If the application decides that the partial data is inadequate, it can reissue the
/// <c>WSAAsyncGetHostByAddr</c> function call with a buffer large enough to receive all the desired information (that is, no
/// smaller than the low 16 bits of lParam).
/// </para>
/// <para>
/// The buffer specified to this function is used by Windows Sockets to construct a structure together with the contents of data
/// areas referenced by members of the same hostent structure. To avoid the WSAENOBUFS error, the application should provide a
/// buffer of at least MAXGETHOSTSTRUCT bytes (as defined in Winsock2.h).
/// </para>
/// <para>
/// The error code and buffer length should be extracted from the lParam using the macros <c>WSAGETASYNCERROR</c> and
/// <c>WSAGETASYNCBUFLEN</c>, defined in Winsock2.h as:
/// </para>
/// <para>The use of these macros will maximize the portability of the source code for the application.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsaasyncgethostbyaddr HANDLE WSAAsyncGetHostByAddr( HWND
// hWnd, u_int wMsg, const char *addr, int len, int type, char *buf, int buflen );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock.h", MSDNShortId = "814cbb2e-8dd2-44b0-b8be-cfc5491bdc49")]
public static extern HANDLE WSAAsyncGetHostByAddr(HWND hWnd, uint wMsg, [In] IntPtr addr, int len, int type, [Out] IntPtr buf, int buflen);
/// <summary>
/// <para>The <c>WSAAsyncGetHostByName</c> function asynchronously retrieves host information that corresponds to a host name.</para>
/// <para>
/// <c>Note</c> The <c>WSAAsyncGetHostByName</c> function is not designed to provide parallel resolution of several names.
/// Therefore, applications that issue several requests should not expect them to be executed concurrently. Alternatively,
/// applications can start another thread and use the getaddrinfo function to resolve names in an IP-version agnostic manner.
/// Developers creating Windows Sockets 2 applications are urged to use the <c>getaddrinfo</c> function to enable smooth transition
/// to IPv6 compatibility.
/// </para>
/// </summary>
/// <param name="hWnd">[in] The handle of the window which should receive a message when the asynchronous request completes.</param>
/// <param name="wMsg">[in] The message to be received when the asynchronous request completes.</param>
/// <param name="name">[in] A pointer to the null terminated name of the host.</param>
/// <param name="buf">
/// [out] A pointer to the data area to receive the hostent data. Note that this must be larger than the size of a hostent
/// structure. This is because the data area supplied is used by Windows Sockets to contain not only a hostent structure but any and
/// all of the data which is referenced by members of the hostent structure. It is recommended that you supply a buffer of
/// MAXGETHOSTSTRUCT bytes.
/// </param>
/// <param name="buflen">[in] The size of data area buf above.</param>
/// <returns>
/// The return value specifies whether or not the asynchronous operation was successfully initiated. Note that it does not imply
/// success or failure of the operation itself.
/// <para>
/// If the operation was successfully initiated, WSAAsyncGetHostByName returns a nonzero value of type HANDLE which is the
/// asynchronous task handle(not to be confused with a Windows HTASK) for the request.This value can be used in two ways. It can be
/// used to cancel the operation using WSACancelAsyncRequest. It can also be used to match up asynchronous operations and completion
/// messages, by examining the wParam message argument.
/// </para>
/// <para>
/// If the asynchronous operation could not be initiated, WSAAsyncGetHostByName returns a zero value, and a specific error number
/// can be retrieved by calling WSAGetLastError.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAAsyncGetHostByName</c> function is an asynchronous version of gethostbyname, and is used to retrieve host name and
/// address information corresponding to a host name. Windows Sockets initiates the operation and returns to the caller immediately,
/// passing back an opaque asynchronous task handle that which the application can use to identify the operation. When the operation
/// is completed, the results (if any) are copied into the buffer provided by the caller and a message is sent to the application's window.
/// </para>
/// <para>
/// When the asynchronous operation has completed, the application window indicated by the hWnd parameter receives message in the
/// wMsg parameter. The wParam parameter contains the asynchronous task handle as returned by the original function call. The high
/// 16 bits of lParam contain any error code. The error code can be any error as defined in Winsock2.h. An error code of zero
/// indicates successful completion of the asynchronous operation.
/// </para>
/// <para>
/// On successful completion, the buffer specified to the original function call contains a hostent structure. To access the
/// elements of this structure, the original buffer address should be cast to a <c>hostent</c> structure pointer and accessed as appropriate.
/// </para>
/// <para>
/// If the error code is WSAENOBUFS, the size of the buffer specified by buflen in the original call was too small to contain all
/// the resulting information. In this case, the low 16 bits of lParam contain the size of buffer required to supply all the
/// requisite information. If the application decides that the partial data is inadequate, it can reissue the
/// <c>WSAAsyncGetHostByName</c> function call with a buffer large enough to receive all the desired information (that is, no
/// smaller than the low 16 bits of lParam).
/// </para>
/// <para>
/// The buffer specified to this function is used by Windows Sockets to construct a hostent structure together with the contents of
/// data areas referenced by members of the same <c>hostent</c> structure. To avoid the WSAENOBUFS error, the application should
/// provide a buffer of at least MAXGETHOSTSTRUCT bytes (as defined in Winsock2.h).
/// </para>
/// <para>
/// The error code and buffer length should be extracted from the lParam using the macros <c>WSAGETASYNCERROR</c> and
/// <c>WSAGETASYNCBUFLEN</c>, defined in Winsock2.h as:
/// </para>
/// <para>The use of these macros will maximize the portability of the source code for the application.</para>
/// <para><c>WSAAsyncGetHostByName</c> is guaranteed to resolve the string returned by a successful call to gethostname.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/wsipv6ok/nf-wsipv6ok-wsaasyncgethostbyname HANDLE WSAAsyncGetHostByName( _In_
// HWND hWnd, _In_ u_int wMsg, _In_z_ const char FAR * name, _Out_writes_bytes_(buflen) char FAR * buf, _In_ int buflen );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Ansi)]
[PInvokeData("wsipv6ok.h", MSDNShortId = "1a2b9c76-6e84-4ac2-b5c1-a2268edd0c49")]
public static extern HANDLE WSAAsyncGetHostByName(HWND hWnd, uint wMsg, [In] string name, [Out] IntPtr buf, int buflen);
/// <summary>
/// The <c>WSAAsyncGetProtoByName</c> function asynchronously retrieves protocol information that corresponds to a protocol name.
/// </summary>
/// <param name="hWnd">Handle of the window that will receive a message when the asynchronous request completes.</param>
/// <param name="wMsg">Message to be received when the asynchronous request completes.</param>
/// <param name="name">Pointer to the null-terminated protocol name to be resolved.</param>
/// <param name="buf">
/// Pointer to the data area to receive the protoent data. The data area must be larger than the size of a <c>protoent</c> structure
/// because the data area is used by Windows Sockets to contain a <c>protoent</c> structure and all of the data that is referenced
/// by members of the <c>protoent</c> structure. A buffer of MAXGETHOSTSTRUCT bytes is recommended.
/// </param>
/// <param name="buflen">Size of data area for the buf parameter, in bytes.</param>
/// <returns>
/// <para>
/// The return value specifies whether or not the asynchronous operation was successfully initiated. It does not imply success or
/// failure of the operation itself.
/// </para>
/// <para>
/// If no error occurs, <c>WSAAsyncGetProtoByName</c> returns a nonzero value of type HANDLE that is the asynchronous task handle
/// for the request (not to be confused with a Windows HTASK). This value can be used in two ways. It can be used to cancel the
/// operation using WSACancelAsyncRequest, or it can be used to match up asynchronous operations and completion messages, by
/// examining the wParam message parameter.
/// </para>
/// <para>
/// If the asynchronous operation could not be initiated, <c>WSAAsyncGetProtoByName</c> returns a zero value, and a specific error
/// number can be retrieved by calling WSAGetLastError.
/// </para>
/// <para>
/// The following error codes can be set when an application window receives a message. As described above, they can be extracted
/// from the lParam in the reply message using the <c>WSAGETASYNCERROR</c> macro.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>Insufficient buffer space is available.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The name or buf parameter is not in a valid part of the process address space.</term>
/// </item>
/// <item>
/// <term>WSAHOST_NOT_FOUND</term>
/// <term>Authoritative answer protocol not found.</term>
/// </item>
/// <item>
/// <term>WSATRY_AGAIN</term>
/// <term>A nonauthoritative protocol not found, or server failure.</term>
/// </item>
/// <item>
/// <term>WSANO_RECOVERY</term>
/// <term>Nonrecoverable errors, the protocols database is not accessible.</term>
/// </item>
/// <item>
/// <term>WSANO_DATA</term>
/// <term>Valid name, no data record of requested type.</term>
/// </item>
/// </list>
/// <para>
/// The following errors can occur at the time of the function call, and indicate that the asynchronous operation could not be initiated.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>
/// The asynchronous operation cannot be scheduled at this time due to resource or other constraints within the Windows Sockets implementation.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAAsyncGetProtoByName</c> function is an asynchronous version of getprotobyname. It is used to retrieve the protocol
/// name and number from the Windows Sockets database corresponding to a given protocol name. Windows Sockets initiates the
/// operation and returns to the caller immediately, passing back an opaque, asynchronous task handle that the application can use
/// to identify the operation. When the operation is completed, the results (if any) are copied into the buffer provided by the
/// caller and a message is sent to the application's window.
/// </para>
/// <para>
/// When the asynchronous operation has completed, the application window indicated by the hWnd parameter receives message in the
/// wMsg parameter. The wParam parameter contains the asynchronous task handle as returned by the original function call. The high
/// 16 bits of lParam contain any error code. The error code can be any error as defined in Winsock2.h. An error code of zero
/// indicates successful completion of the asynchronous operation.
/// </para>
/// <para>
/// On successful completion, the buffer specified to the original function call contains a protoent structure. To access the
/// members of this structure, the original buffer address should be cast to a <c>protoent</c> structure pointer and accessed as appropriate.
/// </para>
/// <para>
/// If the error code is WSAENOBUFS, the size of the buffer specified by buflen in the original call was too small to contain all
/// the resulting information. In this case, the low 16 bits of lParam contain the size of buffer required to supply all the
/// requisite information. If the application decides that the partial data is inadequate, it can reissue the
/// <c>WSAAsyncGetProtoByName</c> function call with a buffer large enough to receive all the desired information (that is, no
/// smaller than the low 16 bits of lParam).
/// </para>
/// <para>
/// The buffer specified to this function is used by Windows Sockets to construct a protoent structure together with the contents of
/// data areas referenced by members of the same <c>protoent</c> structure. To avoid the WSAENOBUFS error noted above, the
/// application should provide a buffer of at least MAXGETHOSTSTRUCT bytes (as defined in Winsock2.h).
/// </para>
/// <para>
/// The error code and buffer length should be extracted from the lParam using the macros <c>WSAGETASYNCERROR</c> and
/// <c>WSAGETASYNCBUFLEN</c>, defined in Winsock2.h as:
/// </para>
/// <para>The use of these macros will maximize the portability of the source code for the application.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsaasyncgetprotobyname HANDLE WSAAsyncGetProtoByName( HWND
// hWnd, u_int wMsg, const char *name, char *buf, int buflen );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Ansi)]
[PInvokeData("winsock.h", MSDNShortId = "747c40fd-5dc1-4533-896e-bc1c4368d7bd")]
public static extern HANDLE WSAAsyncGetProtoByName(HWND hWnd, uint wMsg, [In] string name, [Out] IntPtr buf, int buflen);
/// <summary>
/// The <c>WSAAsyncGetProtoByNumber</c> function asynchronously retrieves protocol information that corresponds to a protocol number.
/// </summary>
/// <param name="hWnd">Handle of the window that will receive a message when the asynchronous request completes.</param>
/// <param name="wMsg">Message to be received when the asynchronous request completes.</param>
/// <param name="number">Protocol number to be resolved, in host byte order.</param>
/// <param name="buf">
/// Pointer to the data area to receive the protoent data. The data area must be larger than the size of a <c>protoent</c> structure
/// because the data area is used by Windows Sockets to contain a <c>protoent</c> structure and all of the data that is referenced
/// by members of the <c>protoent</c> structure. A buffer of MAXGETHOSTSTRUCT bytes is recommended.
/// </param>
/// <param name="buflen">Size of data area for the buf parameter, in bytes.</param>
/// <returns>
/// <para>
/// The return value specifies whether or not the asynchronous operation was successfully initiated. It does not imply success or
/// failure of the operation itself.
/// </para>
/// <para>
/// If no error occurs, <c>WSAAsyncGetProtoByNumber</c> returns a nonzero value of type <c>HANDLE</c> that is the asynchronous task
/// handle for the request (not to be confused with a Windows HTASK). This value can be used in two ways. It can be used to cancel
/// the operation using WSACancelAsyncRequest, or it can be used to match up asynchronous operations and completion messages, by
/// examining the wParam message parameter.
/// </para>
/// <para>
/// If the asynchronous operation could not be initiated, <c>WSAAsyncGetProtoByNumber</c> returns a zero value, and a specific error
/// number can be retrieved by calling WSAGetLastError.
/// </para>
/// <para>
/// The following error codes can be set when an application window receives a message. As described above, they can be extracted
/// from the lParam in the reply message using the <c>WSAGETASYNCERROR</c> macro.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>Insufficient buffer space is available.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The buf parameter is not in a valid part of the process address space.</term>
/// </item>
/// <item>
/// <term>WSAHOST_NOT_FOUND</term>
/// <term>Authoritative answer protocol not found.</term>
/// </item>
/// <item>
/// <term>WSATRY_AGAIN</term>
/// <term>Nonauthoritative protocol not found, or server failure.</term>
/// </item>
/// <item>
/// <term>WSANO_RECOVERY</term>
/// <term>Nonrecoverable errors, the protocols database is not accessible.</term>
/// </item>
/// <item>
/// <term>WSANO_DATA</term>
/// <term>Valid name, no data record of requested type.</term>
/// </item>
/// </list>
/// <para>
/// The following errors can occur at the time of the function call, and indicate that the asynchronous operation could not be initiated.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>
/// The asynchronous operation cannot be scheduled at this time due to resource or other constraints within the Windows Sockets implementation.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAAsyncGetProtoByNumber</c> function is an asynchronous version of getprotobynumber, and is used to retrieve the
/// protocol name and number corresponding to a protocol number. Windows Sockets initiates the operation and returns to the caller
/// immediately, passing back an opaque, asynchronous task handle that the application can use to identify the operation. When the
/// operation is completed, the results (if any) are copied into the buffer provided by the caller and a message is sent to the
/// application's window.
/// </para>
/// <para>
/// When the asynchronous operation has completed, the application window indicated by the hWnd parameter receives message in the
/// wMsg parameter. The wParam parameter contains the asynchronous task handle as returned by the original function call. The high
/// 16 bits of lParam contain any error code. The error code can be any error as defined in Winsock2.h. An error code of zero
/// indicates successful completion of the asynchronous operation.
/// </para>
/// <para>
/// On successful completion, the buffer specified to the original function call contains a protoent structure. To access the
/// members of this structure, the original buffer address is cast to a <c>protoent</c> structure pointer and accessed as appropriate.
/// </para>
/// <para>
/// If the error code is WSAENOBUFS, the size of the buffer specified by buflen in the original call was too small to contain all
/// the resulting information. In this case, the low 16 bits of lParam contain the size of buffer required to supply all the
/// requisite information. If the application decides that the partial data is inadequate, it can reissue the
/// <c>WSAAsyncGetProtoByNumber</c> function call with a buffer large enough to receive all the desired information (that is, no
/// smaller than the low 16 bits of lParam).
/// </para>
/// <para>
/// The buffer specified to this function is used by Windows Sockets to construct a protoent structure together with the contents of
/// data areas referenced by members of the same <c>protoent</c> structure. To avoid the WSAENOBUFS error noted above, the
/// application should provide a buffer of at least MAXGETHOSTSTRUCT bytes (as defined in Winsock2.h).
/// </para>
/// <para>
/// The error code and buffer length should be extracted from the lParam using the macros <c>WSAGETASYNCERROR</c> and
/// <c>WSAGETASYNCBUFLEN</c>, defined in Winsock2.h as:
/// </para>
/// <para>The use of these macros will maximize the portability of the source code for the application.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsaasyncgetprotobynumber HANDLE WSAAsyncGetProtoByNumber(
// HWND hWnd, u_int wMsg, int number, char *buf, int buflen );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock.h", MSDNShortId = "10f28345-c178-47c0-9d0f-87f6743131d9")]
public static extern HANDLE WSAAsyncGetProtoByNumber(HWND hWnd, uint wMsg, int number, [Out] IntPtr buf, int buflen);
/// <summary>
/// The <c>WSAAsyncGetServByName</c> function asynchronously retrieves service information that corresponds to a service name and port.
/// </summary>
/// <param name="hWnd">Handle of the window that should receive a message when the asynchronous request completes.</param>
/// <param name="wMsg">Message to be received when the asynchronous request completes.</param>
/// <param name="name">Pointer to a <c>null</c>-terminated service name.</param>
/// <param name="proto">
/// Pointer to a protocol name. This can be <c>NULL</c>, in which case <c>WSAAsyncGetServByName</c> will search for the first
/// service entry for which s_name or one of the s_aliases matches the given name. Otherwise, <c>WSAAsyncGetServByName</c> matches
/// both name and proto.
/// </param>
/// <param name="buf">
/// Pointer to the data area to receive the servent data. The data area must be larger than the size of a <c>servent</c> structure
/// because the data area is used by Windows Sockets to contain a <c>servent</c> structure and all of the data that is referenced by
/// members of the <c>servent</c> structure. A buffer of MAXGETHOSTSTRUCT bytes is recommended.
/// </param>
/// <param name="buflen">Size of data area for the buf parameter, in bytes.</param>
/// <returns>
/// <para>
/// The return value specifies whether or not the asynchronous operation was successfully initiated. It does not imply success or
/// failure of the operation itself.
/// </para>
/// <para>
/// If no error occurs, <c>WSAAsyncGetServByName</c> returns a nonzero value of type <c>HANDLE</c> that is the asynchronous task
/// handle for the request (not to be confused with a Windows HTASK). This value can be used in two ways. It can be used to cancel
/// the operation using WSACancelAsyncRequest, or it can be used to match up asynchronous operations and completion messages, by
/// examining the wParam message parameter.
/// </para>
/// <para>
/// If the asynchronous operation could not be initiated, <c>WSAAsyncServByName</c> returns a zero value, and a specific error
/// number can be retrieved by calling WSAGetLastError.
/// </para>
/// <para>
/// The following error codes can be set when an application window receives a message. As described above, they can be extracted
/// from the lParam in the reply message using the <c>WSAGETASYNCERROR</c> macro.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>Insufficient buffer space is available.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The buf parameter is not in a valid part of the process address space.</term>
/// </item>
/// <item>
/// <term>WSAHOST_NOT_FOUND</term>
/// <term>Authoritative answer host not found.</term>
/// </item>
/// <item>
/// <term>WSATRY_AGAIN</term>
/// <term>Nonauthoritative service not found, or server failure.</term>
/// </item>
/// <item>
/// <term>WSANO_RECOVERY</term>
/// <term>Nonrecoverable errors, the services database is not accessible.</term>
/// </item>
/// <item>
/// <term>WSANO_DATA</term>
/// <term>Valid name, no data record of requested type.</term>
/// </item>
/// </list>
/// <para>
/// The following errors can occur at the time of the function call, and indicate that the asynchronous operation could not be initiated.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>
/// The asynchronous operation cannot be scheduled at this time due to resource or other constraints within the Windows Sockets implementation.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAAsyncGetServByName</c> function is an asynchronous version of getservbyname and is used to retrieve service
/// information corresponding to a service name. Windows Sockets initiates the operation and returns to the caller immediately,
/// passing back an opaque, asynchronous task handle that the application can use to identify the operation. When the operation is
/// completed, the results (if any) are copied into the buffer provided by the caller and a message is sent to the application's window.
/// </para>
/// <para>
/// When the asynchronous operation has completed, the application window indicated by the hWnd parameter receives message in the
/// wMsg parameter. The wParam parameter contains the asynchronous task handle as returned by the original function call. The high
/// 16 bits of lParam contain any error code. The error code can be any error as defined in Winsock2.h. An error code of zero
/// indicates successful completion of the asynchronous operation.
/// </para>
/// <para>
/// On successful completion, the buffer specified to the original function call contains a servent structure. To access the members
/// of this structure, the original buffer address should be cast to a <c>servent</c> structure pointer and accessed as appropriate.
/// </para>
/// <para>
/// If the error code is WSAENOBUFS, the size of the buffer specified by buflen in the original call was too small to contain all
/// the resulting information. In this case, the low 16 bits of lParam contain the size of buffer required to supply all the
/// requisite information. If the application decides that the partial data is inadequate, it can reissue the
/// <c>WSAAsyncGetServByName</c> function call with a buffer large enough to receive all the desired information (that is, no
/// smaller than the low 16 bits of lParam).
/// </para>
/// <para>
/// The buffer specified to this function is used by Windows Sockets to construct a servent structure together with the contents of
/// data areas referenced by members of the same <c>servent</c> structure. To avoid the WSAENOBUFS error, the application should
/// provide a buffer of at least MAXGETHOSTSTRUCT bytes (as defined in Winsock2.h).
/// </para>
/// <para>
/// The error code and buffer length should be extracted from the lParam using the macros <c>WSAGETASYNCERROR</c> and
/// <c>WSAGETASYNCBUFLEN</c>, defined in Winsock2.h as:
/// </para>
/// <para>The use of these macros will maximize the portability of the source code for the application.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsaasyncgetservbyname HANDLE WSAAsyncGetServByName( HWND
// hWnd, u_int wMsg, const char *name, const char *proto, char *buf, int buflen );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true, CharSet = CharSet.Ansi)]
[PInvokeData("winsock.h", MSDNShortId = "d3524197-cd7a-4863-8fbb-a05e6f5d38e0")]
public static extern HANDLE WSAAsyncGetServByName(HWND hWnd, uint wMsg, [In] string name, [In, Optional] string proto, [Out] IntPtr buf, int buflen);
/// <summary>
/// The <c>WSAAsyncGetServByPort</c> function asynchronously retrieves service information that corresponds to a port and protocol.
/// </summary>
/// <param name="hWnd">Handle of the window that should receive a message when the asynchronous request completes.</param>
/// <param name="wMsg">Message to be received when the asynchronous request completes.</param>
/// <param name="port">Port for the service, in network byte order.</param>
/// <param name="proto">
/// Pointer to a protocol name. This can be <c>NULL</c>, in which case <c>WSAAsyncGetServByPort</c> will search for the first
/// service entry for which s_port match the given port. Otherwise, <c>WSAAsyncGetServByPort</c> matches both port and proto.
/// </param>
/// <param name="buf">
/// Pointer to the data area to receive the servent data. The data area must be larger than the size of a <c>servent</c> structure
/// because the data area is used by Windows Sockets to contain a <c>servent</c> structure and all of the data that is referenced by
/// members of the <c>servent</c> structure. A buffer of MAXGETHOSTSTRUCT bytes is recommended.
/// </param>
/// <param name="buflen">Size of data area for the buf parameter, in bytes.</param>
/// <returns>
/// <para>
/// The return value specifies whether or not the asynchronous operation was successfully initiated. It does not imply success or
/// failure of the operation itself.
/// </para>
/// <para>
/// If no error occurs, <c>WSAAsyncGetServByPort</c> returns a nonzero value of type <c>HANDLE</c> that is the asynchronous task
/// handle for the request (not to be confused with a Windows HTASK). This value can be used in two ways. It can be used to cancel
/// the operation using WSACancelAsyncRequest, or it can be used to match up asynchronous operations and completion messages, by
/// examining the wParam message parameter.
/// </para>
/// <para>
/// If the asynchronous operation could not be initiated, <c>WSAAsyncGetServByPort</c> returns a zero value, and a specific error
/// number can be retrieved by calling WSAGetLastError.
/// </para>
/// <para>
/// The following error codes can be set when an application window receives a message. As described above, they can be extracted
/// from the lParam in the reply message using the <c>WSAGETASYNCERROR</c> macro.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>Insufficient buffer space is available.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The proto or buf parameter is not in a valid part of the process address space.</term>
/// </item>
/// <item>
/// <term>WSAHOST_NOT_FOUND</term>
/// <term>Authoritative answer port not found.</term>
/// </item>
/// <item>
/// <term>WSATRY_AGAIN</term>
/// <term>Nonauthoritative port not found, or server failure.</term>
/// </item>
/// <item>
/// <term>WSANO_RECOVERY</term>
/// <term>Nonrecoverable errors, the services database is not accessible.</term>
/// </item>
/// <item>
/// <term>WSANO_DATA</term>
/// <term>Valid name, no data record of requested type.</term>
/// </item>
/// </list>
/// <para>
/// The following errors can occur at the time of the function call, and indicate that the asynchronous operation could not be initiated.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>
/// The asynchronous operation cannot be scheduled at this time due to resource or other constraints within the Windows Sockets implementation.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAAsyncGetServByPort</c> function is an asynchronous version of getservbyport, and is used to retrieve service
/// information corresponding to a port number. Windows Sockets initiates the operation and returns to the caller immediately,
/// passing back an opaque, asynchronous task handle that the application can use to identify the operation. When the operation is
/// completed, the results (if any) are copied into the buffer provided by the caller and a message is sent to the application's window.
/// </para>
/// <para>
/// When the asynchronous operation has completed, the application window indicated by the hWnd parameter receives message in the
/// wMsg parameter. The wParam parameter contains the asynchronous task handle as returned by the original function call. The high
/// 16 bits of lParam contain any error code. The error code can be any error as defined in Winsock2.h. An error code of zero
/// indicates successful completion of the asynchronous operation.
/// </para>
/// <para>
/// On successful completion, the buffer specified to the original function call contains a servent structure. To access the members
/// of this structure, the original buffer address should be cast to a <c>servent</c> structure pointer and accessed as appropriate.
/// </para>
/// <para>
/// If the error code is WSAENOBUFS, the size of the buffer specified by buflen in the original call was too small to contain all
/// the resulting information. In this case, the low 16 bits of lParam contain the size of buffer required to supply all the
/// requisite information. If the application decides that the partial data is inadequate, it can reissue the
/// <c>WSAAsyncGetServByPort</c> function call with a buffer large enough to receive all the desired information (that is, no
/// smaller than the low 16 bits of lParam).
/// </para>
/// <para>
/// The buffer specified to this function is used by Windows Sockets to construct a servent structure together with the contents of
/// data areas referenced by members of the same <c>servent</c> structure. To avoid the WSAENOBUFS error, the application should
/// provide a buffer of at least MAXGETHOSTSTRUCT bytes (as defined in Winsock2.h).
/// </para>
/// <para>
/// The error code and buffer length should be extracted from the lParam using the macros <c>WSAGETASYNCERROR</c> and
/// <c>WSAGETASYNCBUFLEN</c>, defined in Winsock2.h as:
/// </para>
/// <para>The use of these macros will maximize the portability of the source code for the application.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaasyncgetservbyport HANDLE WSAAPI
// WSAAsyncGetServByPort( HWND hWnd, u_int wMsg, int port, const char *proto, char *buf, int buflen );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "0d0bd09c-ea97-46fb-b7b0-6e3e0a41dbc1")]
public static extern HANDLE WSAAsyncGetServByPort(HWND hWnd, uint wMsg, int port, [In, Optional] string proto, [Out] IntPtr buf, int buflen);
/// <summary>
/// <para>
/// [The <c>WSAAsyncSelect</c> function is available for use in the operating systems specified in the Requirements section. It may
/// be altered or unavailable in subsequent versions. Rather than use Select-style I/O, use Overlapped I/O and Event Objects with WinSock2.]
/// </para>
/// <para>The <c>WSAAsyncSelect</c> function requests Windows message-based notification of network events for a socket.</para>
/// </summary>
/// <param name="s">A descriptor that identifies the socket for which event notification is required.</param>
/// <param name="hWnd">A handle that identifies the window that will receive a message when a network event occurs.</param>
/// <param name="wMsg">A message to be received when a network event occurs.</param>
/// <param name="lEvent">A bitmask that specifies a combination of network events in which the application is interested.</param>
/// <returns>
/// <para>
/// If the <c>WSAAsyncSelect</c> function succeeds, the return value is zero, provided that the application's declaration of
/// interest in the network event set was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error number can
/// be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem failed.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>
/// One of the specified parameters was invalid, such as the window handle not referring to an existing window, or the specified
/// socket is in an invalid state.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// </list>
/// <para>
/// Additional error codes can be set when an application window receives a message. This error code is extracted from the lParam in
/// the reply message using the <c>WSAGETSELECTERROR</c> macro. Possible error codes for each network event are listed in the
/// following table.
/// </para>
/// <para>Event: FD_CONNECT</para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAEAFNOSUPPORT</term>
/// <term>Addresses in the specified family cannot be used with this socket.</term>
/// </item>
/// <item>
/// <term>WSAECONNREFUSED</term>
/// <term>The attempt to connect was rejected.</term>
/// </item>
/// <item>
/// <term>WSAENETUNREACH</term>
/// <term>The network cannot be reached from this host at this time.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The namelen parameter is invalid.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>The socket is already bound to an address.</term>
/// </item>
/// <item>
/// <term>WSAEISCONN</term>
/// <term>The socket is already connected.</term>
/// </item>
/// <item>
/// <term>WSAEMFILE</term>
/// <term>No more file descriptors are available.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>No buffer space is available. The socket cannot be connected.</term>
/// </item>
/// <item>
/// <term>WSAENOTCONN</term>
/// <term>The socket is not connected.</term>
/// </item>
/// <item>
/// <term>WSAETIMEDOUT</term>
/// <term>Attempt to connect timed out without establishing a connection.</term>
/// </item>
/// </list>
/// <para>Event: FD_CLOSE</para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem failed.</term>
/// </item>
/// <item>
/// <term>WSAECONNRESET</term>
/// <term>The connection was reset by the remote side.</term>
/// </item>
/// <item>
/// <term>WSAECONNABORTED</term>
/// <term>The connection was terminated due to a time-out or other failure.</term>
/// </item>
/// </list>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem failed.</term>
/// </item>
/// </list>
/// <para>Event: FD_ROUTING_INTERFACE_CHANGE</para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAENETUNREACH</term>
/// <term>The specified destination is no longer reachable.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem failed.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAAsyncSelect</c> function is used to request that WS2_32.DLL should send a message to the window hWnd when it detects
/// any network event specified by the lEvent parameter. The message that should be sent is specified by the wMsg parameter. The
/// socket for which notification is required is identified by the s parameter.
/// </para>
/// <para>
/// The <c>WSAAsyncSelect</c> function automatically sets socket s to nonblocking mode, regardless of the value of lEvent. To set
/// socket s back to blocking mode, it is first necessary to clear the event record associated with socket s via a call to
/// <c>WSAAsyncSelect</c> with lEvent set to zero. You can then call ioctlsocket or WSAIoctl to set the socket back to blocking
/// mode. For more information about how to set the nonblocking socket back to blocking mode, see the <c>ioctlsocket</c> and
/// <c>WSAIoctl</c> functions.
/// </para>
/// <para>The lEvent parameter is constructed by using the bitwise OR operator with any value listed in the following table.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>FD_READ</term>
/// <term>Set to receive notification of readiness for reading.</term>
/// </item>
/// <item>
/// <term>FD_WRITE</term>
/// <term>Wants to receive notification of readiness for writing.</term>
/// </item>
/// <item>
/// <term>FD_OOB</term>
/// <term>Wants to receive notification of the arrival of OOB data.</term>
/// </item>
/// <item>
/// <term>FD_ACCEPT</term>
/// <term>Wants to receive notification of incoming connections.</term>
/// </item>
/// <item>
/// <term>FD_CONNECT</term>
/// <term>Wants to receive notification of completed connection or multipoint join operation.</term>
/// </item>
/// <item>
/// <term>FD_CLOSE</term>
/// <term>Wants to receive notification of socket closure.</term>
/// </item>
/// <item>
/// <term>FD_QOS</term>
/// <term>Wants to receive notification of socket Quality of Service (QoS) changes.</term>
/// </item>
/// <item>
/// <term>FD_GROUP_QOS</term>
/// <term>
/// Wants to receive notification of socket group Quality of Service (QoS) changes (reserved for future use with socket groups). Reserved.
/// </term>
/// </item>
/// <item>
/// <term>FD_ROUTING_INTERFACE_CHANGE</term>
/// <term>Wants to receive notification of routing interface changes for the specified destination(s).</term>
/// </item>
/// <item>
/// <term>FD_ADDRESS_LIST_CHANGE</term>
/// <term>Wants to receive notification of local address list changes for the socket protocol family.</term>
/// </item>
/// </list>
/// <para>
/// Issuing a <c>WSAAsyncSelect</c> for a socket cancels any previous <c>WSAAsyncSelect</c> or WSAEventSelect for the same socket.
/// For example, to receive notification for both reading and writing, the application must call <c>WSAAsyncSelect</c> with both
/// <c>FD_READ</c> and <c>FD_WRITE</c>, as follows:
/// </para>
/// <para>
/// It is not possible to specify different messages for different events. The following code will not work; the second call will
/// cancel the effects of the first, and only <c>FD_WRITE</c> events will be reported with message wMsg2:
/// </para>
/// <para>
/// To cancel all notification indicating that Windows Sockets should send no further messages related to network events on the
/// socket, lEvent is set to zero.
/// </para>
/// <para>
/// Although <c>WSAAsyncSelect</c> immediately disables event message posting for the socket in this instance, it is possible that
/// messages could be waiting in the application message queue. Therefore, the application must be prepared to receive network event
/// messages even after cancellation. Closing a socket with closesocket also cancels <c>WSAAsyncSelect</c> message sending, but the
/// same caveat about messages in the queue still applies.
/// </para>
/// <para>
/// The socket created by the accept function has the same properties as the listening socket used to accept it. Consequently,
/// <c>WSAAsyncSelect</c> events set for the listening socket also apply to the accepted socket. For example, if a listening socket
/// has <c>WSAAsyncSelect</c> events <c>FD_ACCEPT</c>, <c>FD_READ</c>, and <c>FD_WRITE</c>, then any socket accepted on that
/// listening socket will also have <c>FD_ACCEPT</c>, <c>FD_READ</c>, and <c>FD_WRITE</c> events with the same wMsg value used for
/// messages. If a different wMsg or events are desired, the application should call <c>WSAAsyncSelect</c>, passing the accepted
/// socket and the desired new data.
/// </para>
/// <para>
/// When one of the nominated network events occurs on the specified socket s, the application window hWnd receives message wMsg.
/// The wParam parameter identifies the socket on which a network event has occurred. The low word of lParam specifies the network
/// event that has occurred. The high word of lParam contains any error code. The error code be any error as defined in Winsock2.h.
/// </para>
/// <para>
/// <c>Note</c> Upon receipt of an event notification message, the WSAGetLastError function cannot be used to check the error value
/// because the error value returned can differ from the value in the high word of lParam.
/// </para>
/// <para>
/// The error and event codes can be extracted from the lParam using the macros <c>WSAGETSELECTERROR</c> and
/// <c>WSAGETSELECTEVENT</c>, defined in Winsock2.h as:
/// </para>
/// <para>The use of these macros will maximize the portability of the source code for the application.</para>
/// <para>The possible network event codes that can be returned are listed in the following table.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>FD_READ</term>
/// <term>Socket s ready for reading.</term>
/// </item>
/// <item>
/// <term>FD_WRITE</term>
/// <term>Socket s ready for writing.</term>
/// </item>
/// <item>
/// <term>FD_OOB</term>
/// <term>OOB data ready for reading on socket s</term>
/// </item>
/// <item>
/// <term>FD_ACCEPT</term>
/// <term>Socket s ready for accepting a new incoming connection.</term>
/// </item>
/// <item>
/// <term>FD_CONNECT</term>
/// <term>Connection or multipoint join operation initiated on socket s completed.</term>
/// </item>
/// <item>
/// <term>FD_CLOSE</term>
/// <term>Connection identified by socket s has been closed.</term>
/// </item>
/// <item>
/// <term>FD_QOS</term>
/// <term>Quality of Service associated with socket s has changed.</term>
/// </item>
/// <item>
/// <term>FD_GROUP_QOS</term>
/// <term>
/// Reserved. Quality of Service associated with the socket group to which s belongs has changed (reserved for future use with
/// socket groups).
/// </term>
/// </item>
/// <item>
/// <term>FD_ROUTING_INTERFACE_CHANGE</term>
/// <term>Local interface that should be used to send to the specified destination has changed.</term>
/// </item>
/// <item>
/// <term>FD_ADDRESS_LIST_CHANGE</term>
/// <term>The list of addresses of the socket protocol family to which the application client can bind has changed.</term>
/// </item>
/// </list>
/// <para>
/// Although <c>WSAAsyncSelect</c> can be called with interest in multiple events, the application window will receive a single
/// message for each network event.
/// </para>
/// <para>
/// As in the case of the select function, <c>WSAAsyncSelect</c> will frequently be used to determine when a data transfer operation
/// (send or recv) can be issued with the expectation of immediate success. Nevertheless, a robust application must be prepared for
/// the possibility that it can receive a message and issue a Windows Sockets 2 call that returns WSAEWOULDBLOCK immediately. For
/// example, the following sequence of events is possible:
/// </para>
/// <list type="number">
/// <item>
/// <term>Data arrives on socket s; Windows Sockets 2 posts <c>WSAAsyncSelect</c> message</term>
/// </item>
/// <item>
/// <term>Application processes some other message</term>
/// </item>
/// <item>
/// <term>While processing, application issues an and notices that there is data ready to be read</term>
/// </item>
/// <item>
/// <term>Application issues a to read the data</term>
/// </item>
/// <item>
/// <term>
/// Application loops to process next message, eventually reaching the <c>WSAAsyncSelect</c> message indicating that data is ready
/// to read
/// </term>
/// </item>
/// <item>
/// <term>Application issues , which fails with the error WSAEWOULDBLOCK.</term>
/// </item>
/// </list>
/// <para>Other sequences are also possible.</para>
/// <para>
/// The WS2_32.DLL will not continually flood an application with messages for a particular network event. Having successfully
/// posted notification of a particular event to an application window, no further message(s) for that network event will be posted
/// to the application window until the application makes the function call that implicitly reenables notification of that network event.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Event</term>
/// <term>Reenabling function</term>
/// </listheader>
/// <item>
/// <term>FD_READ</term>
/// <term>recv, recvfrom, WSARecv, or WSARecvFrom.</term>
/// </item>
/// <item>
/// <term>FD_WRITE</term>
/// <term>send, sendto, WSASend, or WSASendTo.</term>
/// </item>
/// <item>
/// <term>FD_OOB</term>
/// <term>recv, recvfrom, WSARecv, or WSARecvFrom.</term>
/// </item>
/// <item>
/// <term>FD_ACCEPT</term>
/// <term>accept or WSAAccept unless the error code is WSATRY_AGAIN indicating that the condition function returned CF_DEFER.</term>
/// </item>
/// <item>
/// <term>FD_CONNECT</term>
/// <term>None.</term>
/// </item>
/// <item>
/// <term>FD_CLOSE</term>
/// <term>None.</term>
/// </item>
/// <item>
/// <term>FD_QOS</term>
/// <term>WSAIoctl with command SIO_GET_QOS.</term>
/// </item>
/// <item>
/// <term>FD_GROUP_QOS</term>
/// <term>Reserved. WSAIoctl with command SIO_GET_GROUP_QOS (reserved for future use with socket groups).</term>
/// </item>
/// <item>
/// <term>FD_ROUTING_INTERFACE_CHANGE</term>
/// <term>WSAIoctl with command SIO_ROUTING_INTERFACE_CHANGE.</term>
/// </item>
/// <item>
/// <term>FD_ADDRESS_LIST_CHANGE</term>
/// <term>WSAIoctl with command SIO_ADDRESS_LIST_CHANGE.</term>
/// </item>
/// </list>
/// <para>Any call to the reenabling routine, even one that fails, results in reenabling of message posting for the relevant event.</para>
/// <para>
/// For <c>FD_READ</c>, <c>FD_OOB</c>, and <c>FD_ACCEPT</c> events, message posting is level-triggered. This means that if the
/// reenabling routine is called and the relevant condition is still met after the call, a <c>WSAAsyncSelect</c> message is posted
/// to the application. This allows an application to be event-driven and not be concerned with the amount of data that arrives at
/// any one time. Consider the following sequence:
/// </para>
/// <list type="number">
/// <item>
/// <term>
/// Network transport stack receives 100 bytes of data on socket s and causes Windows Sockets 2 to post an <c>FD_READ</c> message.
/// </term>
/// </item>
/// <item>
/// <term>The application issues recv( s, buffptr, 50, 0) to read 50 bytes.</term>
/// </item>
/// <item>
/// <term>Another <c>FD_READ</c> message is posted because there is still data to be read.</term>
/// </item>
/// </list>
/// <para>
/// With these semantics, an application need not read all available data in response to an <c>FD_READ</c> message—a single recv in
/// response to each <c>FD_READ</c> message is appropriate. If an application issues multiple <c>recv</c> calls in response to a
/// single <c>FD_READ</c>, it can receive multiple <c>FD_READ</c> messages. Such an application can require disabling <c>FD_READ</c>
/// messages before starting the <c>recv</c> calls by calling <c>WSAAsyncSelect</c> with the <c>FD_READ</c> event not set.
/// </para>
/// <para>
/// The <c>FD_QOS</c> and <c>FD_GROUP_QOS</c> events are considered edge triggered. A message will be posted exactly once when a
/// quality of service change occurs. Further messages will not be forthcoming until either the provider detects a further change in
/// quality of service or the application renegotiates the quality of service for the socket.
/// </para>
/// <para>
/// The <c>FD_ROUTING_INTERFACE_CHANGE</c> message is posted when the local interface that should be used to reach the destination
/// specified in WSAIoctl with SIO_ROUTING_INTERFACE_CHANGE changes after such IOCTL has been issued.
/// </para>
/// <para>
/// The <c>FD_ADDRESS_LIST_CHANGE</c> message is posted when the list of addresses to which the application can bind changes after
/// WSAIoctl with SIO_ADDRESS_LIST_CHANGE has been issued.
/// </para>
/// <para>
/// If any event has occurred when the application calls <c>WSAAsyncSelect</c> or when the reenabling function is called, then a
/// message is posted as appropriate. For example, consider the following sequence:
/// </para>
/// <list type="number">
/// <item>
/// <term>An application calls listen.</term>
/// </item>
/// <item>
/// <term>A connect request is received, but not yet accepted.</term>
/// </item>
/// <item>
/// <term>
/// The application calls <c>WSAAsyncSelect</c> specifying that it requires receiving <c>FD_ACCEPT</c> messages for the socket. Due
/// to the persistence of events, Windows Sockets 2 posts an <c>FD_ACCEPT</c> message immediately.
/// </term>
/// </item>
/// </list>
/// <para>
/// The <c>FD_WRITE</c> event is handled slightly differently. An <c>FD_WRITE</c> message is posted when a socket is first connected
/// with connect or WSAConnect (after FD_CONNECT, if also registered) or accepted with accept or WSAAccept, and then after a send
/// operation fails with WSAEWOULDBLOCK and buffer space becomes available. Therefore, an application can assume that sends are
/// possible starting from the first <c>FD_WRITE</c> message and lasting until a send returns WSAEWOULDBLOCK. After such a failure
/// the application will be notified that sends are again possible with an <c>FD_WRITE</c> message.
/// </para>
/// <para>
/// The <c>FD_OOB</c> event is used only when a socket is configured to receive OOB data separately. If the socket is configured to
/// receive OOB data inline, the OOB (expedited) data is treated as normal data and the application should register an interest in,
/// and will receive, <c>FD_READ</c> events, not <c>FD_OOB</c> events. An application can set or inspect the way in which OOB data
/// is to be handled by using setsockopt or getsockopt for the SO_OOBINLINE option.
/// </para>
/// <para>
/// The error code in an <c>FD_CLOSE</c> message indicates whether the socket close was graceful or abortive. If the error code is
/// zero, then the close was graceful; if the error code is WSAECONNRESET, then the socket's virtual circuit was reset. This only
/// applies to connection-oriented sockets such as SOCK_STREAM.
/// </para>
/// <para>
/// The <c>FD_CLOSE</c> message is posted when a close indication is received for the virtual circuit corresponding to the socket.
/// In TCP terms, this means that the <c>FD_CLOSE</c> is posted when the connection goes into the TIME WAIT or CLOSE WAIT states.
/// This results from the remote end performing a shutdown on the send side or a closesocket. <c>FD_CLOSE</c> should only be posted
/// after all data is read from a socket, but an application should check for remaining data upon receipt of <c>FD_CLOSE</c> to
/// avoid any possibility of losing data.
/// </para>
/// <para>
/// Be aware that the application will only receive an <c>FD_CLOSE</c> message to indicate closure of a virtual circuit, and only
/// when all the received data has been read if this is a graceful close. It will not receive an <c>FD_READ</c> message to indicate
/// this condition.
/// </para>
/// <para>
/// The <c>FD_QOS</c> or <c>FD_GROUP_QOS</c> message is posted when any parameter in the flow specification associated with socket s
/// or the socket group that s belongs to has changed, respectively. Applications should use WSAIoctl with command SIO_GET_QOS or
/// SIO_GET_GROUP_QOS to get the current quality of service for socket s or for the socket group s belongs to, respectively.
/// </para>
/// <para>
/// The <c>FD_ROUTING_INTERFACE_CHANGE</c> and <c>FD_ADDRESS_LIST_CHANGE</c> events are considered edge triggered as well. A message
/// will be posted exactly once when a change occurs after the application has requested the notification by issuing WSAIoctl with
/// SIO_ROUTING_INTERFACE_CHANGE or SIO_ADDRESS_LIST_CHANGE correspondingly. Further messages will not be forthcoming until the
/// application reissues the IOCTL and another change is detected because the IOCTL has been issued.
/// </para>
/// <para>Here is a summary of events and conditions for each asynchronous notification message.</para>
/// <list type="bullet">
/// <item>
/// <term><c>FD_READ</c>:</term>
/// </item>
/// <item>
/// <term><c>FD_WRITE</c>:</term>
/// </item>
/// <item>
/// <term><c>FD_OOB</c>: Only valid when setsockopt SO_OOBINLINE is disabled (default).</term>
/// </item>
/// <item>
/// <term><c>FD_ACCEPT</c>:</term>
/// </item>
/// <item>
/// <term><c>FD_CONNECT</c>:</term>
/// </item>
/// <item>
/// <term><c>FD_CLOSE</c>: Only valid on connection-oriented sockets (for example, SOCK_STREAM)</term>
/// </item>
/// <item>
/// <term><c>FD_QOS</c>:</term>
/// </item>
/// <item>
/// <term><c>FD_GROUP_QOS</c>: Reserved.</term>
/// </item>
/// <item>
/// <term><c>FD_ROUTING_INTERFACE_CHANGE</c>:</term>
/// </item>
/// <item>
/// <term><c>FD_ADDRESS_LIST_CHANGE</c>:</term>
/// </item>
/// </list>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsaasyncselect int WSAAsyncSelect( SOCKET s, HWND hWnd,
// u_int wMsg, long lEvent );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock.h", MSDNShortId = "a4d3f599-358c-4a94-91eb-7e1c80244250")]
public static extern WSRESULT WSAAsyncSelect(SOCKET s, HWND hWnd, uint wMsg, int lEvent);
/// <summary>The <c>WSACancelAsyncRequest</c> function cancels an incomplete asynchronous operation.</summary>
/// <param name="hAsyncTaskHandle">Handle that specifies the asynchronous operation to be canceled.</param>
/// <returns>
/// <para>
/// The value returned by <c>WSACancelAsyncRequest</c> is zero if the operation was successfully canceled. Otherwise, the value
/// SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>Indicates that the specified asynchronous task handle was invalid.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEALREADY</term>
/// <term>The asynchronous routine being canceled has already completed.</term>
/// </item>
/// </list>
/// <para>
/// <c>Note</c> It is unclear whether the application can usefully distinguish between WSAEINVAL and WSAEALREADY, since in both
/// cases the error indicates that there is no asynchronous operation in progress with the indicated handle. (Trivial exception:
/// zero is always an invalid asynchronous task handle.) The Windows Sockets specification does not prescribe how a conformant
/// Windows Sockets provider should distinguish between the two cases. For maximum portability, a Windows Sockets application should
/// treat the two errors as equivalent.
/// </para>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSACancelAsyncRequest</c> function is used to cancel an asynchronous operation that was initiated by one of the
/// <c>WSAAsyncGetXByY</c> functions such as WSAAsyncGetHostByName. The operation to be canceled is identified by the
/// hAsyncTaskHandle parameter, which should be set to the asynchronous task handle as returned by the initiating
/// <c>WSAAsyncGetXByY</c> function.
/// </para>
/// <para>
/// An attempt to cancel an existing asynchronous <c>WSAAsyncGetXByY</c> operation can fail with an error code of WSAEALREADY for
/// two reasons. First, the original operation has already completed and the application has dealt with the resultant message.
/// Second, the original operation has already completed but the resultant message is still waiting in the application window queue.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsacancelasyncrequest int WSACancelAsyncRequest( HANDLE
// hAsyncTaskHandle );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock.h", MSDNShortId = "0e53eccf-ef85-43ec-a02c-12896471a7a9")]
public static extern WSRESULT WSACancelAsyncRequest(HANDLE hAsyncTaskHandle);
/// <summary>The <c>WSACleanup</c> function terminates use of the Winsock 2 DLL (Ws2_32.dll).</summary>
/// <returns>
/// <para>
/// The return value is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error
/// number can be retrieved by calling WSAGetLastError.
/// </para>
/// <para>In a multithreaded environment, <c>WSACleanup</c> terminates Windows Sockets operations for all threads.</para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// An application or DLL is required to perform a successful WSAStartup call before it can use Windows Sockets services. When it
/// has completed the use of Windows Sockets, the application or DLL must call <c>WSACleanup</c> to deregister itself from a Windows
/// Sockets implementation and allow the implementation to free any resources allocated on behalf of the application or DLL.
/// </para>
/// <para>
/// When <c>WSACleanup</c> is called, any pending blocking or asynchronous Windows Sockets calls issued by any thread in this
/// process are canceled without posting any notification messages or without signaling any event objects. Any pending overlapped
/// send or receive operations (WSASend, WSASendTo, WSARecv, or WSARecvFrom with an overlapped socket, for example) issued by any
/// thread in this process are also canceled without setting the event object or invoking the completion routine, if one was
/// specified. In this case, the pending overlapped operations fail with the error status <c>WSA_OPERATION_ABORTED</c>.
/// </para>
/// <para>
/// Sockets that were open when <c>WSACleanup</c> was called are reset and automatically deallocated as if closesocket were called.
/// Sockets that have been closed with <c>closesocket</c> but that still have pending data to be sent can be affected when
/// <c>WSACleanup</c> is called. In this case, the pending data can be lost if the WS2_32.DLL is unloaded from memory as the
/// application exits. To ensure that all pending data is sent, an application should use shutdown to close the connection, then
/// wait until the close completes before calling <c>closesocket</c> and <c>WSACleanup</c>. All resources and internal state, such
/// as queued unposted or posted messages, must be deallocated so as to be available to the next user.
/// </para>
/// <para>
/// There must be a call to <c>WSACleanup</c> for each successful call to WSAStartup. Only the final <c>WSACleanup</c> function call
/// performs the actual cleanup. The preceding calls simply decrement an internal reference count in the WS2_32.DLL.
/// </para>
/// <para>
/// <c>Note</c><c>WSACleanup</c> does not unregister names (peer names, for example) that may have been registered with a Windows
/// Sockets namespace provider such as Peer Name Resolution Protocol (PNRP) namespace provider.
/// </para>
/// <para>
/// In Windows Sockets 1.1, attempting to call <c>WSACleanup</c> from within a blocking hook and then failing to check the return
/// code was a common programming error. If a Winsock 1.1 application needs to quit while a blocking call is outstanding, the
/// application has to first cancel the blocking call with WSACancelBlockingCall then issue the <c>WSACleanup</c> call once control
/// has been returned to the application. In Windows Sockets 2, this issue does not exist and the <c>WSACancelBlockingCall</c>
/// function has been removed.
/// </para>
/// <para>
/// The <c>WSACleanup</c> function typically leads to protocol-specific helper DLLs being unloaded. As a result, the
/// <c>WSACleanup</c> function should not be called from the DllMain function in a application DLL. This can potentially cause
/// deadlocks. For more information, please see the DLL Main Function.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winsock/nf-winsock-wsacleanup int WSACleanup( );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock.h", MSDNShortId = "72b7cc3e-be34-41e7-acbf-61742149ec8b")]
public static extern WSRESULT WSACleanup();
/// <summary>The <c>WSACloseEvent</c> function closes an open event object handle.</summary>
/// <param name="hEvent">Object handle identifying the open event.</param>
/// <returns>
/// <para>If the function succeeds, the return value is <c>TRUE</c>.</para>
/// <para>If the function fails, the return value is <c>FALSE</c>. To get extended error information, call WSAGetLastError.</para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSA_INVALID_HANDLE</term>
/// <term>The hEvent is not a valid event object handle.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSACloseEvent</c> function closes the handle to an event object and frees resources associated with the event object.
/// This function is used to close a handle created by the WSACreateEventfunction. Once the handle to the event object is closed,
/// further references to this handle will fail with the error WSA_INVALID_HANDLE.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsacloseevent BOOL WSAAPI WSACloseEvent( WSAEVENT hEvent );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "40cefe46-10a3-4b6a-8c89-3e16237fc685")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WSACloseEvent(WSAEVENT hEvent);
/// <summary>
/// The <c>WSAConnect</c> function establishes a connection to another socket application, exchanges connect data, and specifies
/// required quality of service based on the specified FLOWSPEC structure.
/// </summary>
/// <param name="s">A descriptor identifying an unconnected socket.</param>
/// <param name="name">
/// A pointer to a sockaddr structure that specifies the address to which to connect. For IPv4, the <c>sockaddr</c> contains
/// <c>AF_INET</c> for the address family, the destination IPv4 address, and the destination port. For IPv6, the <c>sockaddr</c>
/// structure contains <c>AF_INET6</c> for the address family, the destination IPv6 address, the destination port, and may contain
/// additional flow and scope-id information.
/// </param>
/// <param name="namelen">The length, in bytes, of the sockaddr structure pointed to by the name parameter.</param>
/// <param name="lpCallerData">
/// A pointer to the user data that is to be transferred to the other socket during connection establishment. See Remarks.
/// </param>
/// <param name="lpCalleeData">
/// A pointer to the user data that is to be transferred back from the other socket during connection establishment. See Remarks.
/// </param>
/// <param name="lpSQOS">A pointer to the FLOWSPEC structures for socket s, one for each direction.</param>
/// <param name="lpGQOS">
/// Reserved for future use with socket groups. A pointer to the FLOWSPEC structures for the socket group (if applicable). This
/// parameter should be <c>NULL</c>.
/// </param>
/// <returns>
/// <para>
/// If no error occurs, <c>WSAConnect</c> returns zero. Otherwise, it returns SOCKET_ERROR, and a specific error code can be
/// retrieved by calling WSAGetLastError. On a blocking socket, the return value indicates success or failure of the connection attempt.
/// </para>
/// <para>
/// With a nonblocking socket, the connection attempt cannot be completed immediately. In this case, <c>WSAConnect</c> will return
/// SOCKET_ERROR, and WSAGetLastError will return WSAEWOULDBLOCK; the application could therefore:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Use select to determine the completion of the connection request by checking if the socket is writeable.</term>
/// </item>
/// <item>
/// <term>
/// If your application is using WSAAsyncSelect to indicate interest in connection events, then your application will receive an
/// FD_CONNECT notification when the connect operation is complete(successful or not).
/// </term>
/// </item>
/// <item>
/// <term>
/// If your application is using WSAEventSelect to indicate interest in connection events, then the associated event object will be
/// signaled when the connect operation is complete (successful or not).
/// </term>
/// </item>
/// </list>
/// <para>
/// For a nonblocking socket, until the connection attempt completes all subsequent calls to <c>WSAConnect</c> on the same socket
/// will fail with the error code WSAEALREADY.
/// </para>
/// <para>
/// If the return error code indicates the connection attempt failed (that is, WSAECONNREFUSED, WSAENETUNREACH, WSAETIMEDOUT) the
/// application can call <c>WSAConnect</c> again for the same socket.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEADDRINUSE</term>
/// <term>
/// 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 the execution of bind, but could be delayed until this function if the bind function operates on a
/// partially wildcard address (involving ADDR_ANY) and if a specific address needs to be "committed" at the time of this function.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINTR</term>
/// <term>The (blocking) Windows Socket 1.1 call was canceled through WSACancelBlockingCall.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEALREADY</term>
/// <term>A nonblocking connect or WSAConnect call is in progress on the specified socket.</term>
/// </item>
/// <item>
/// <term>WSAEADDRNOTAVAIL</term>
/// <term>The remote address is not a valid address (such as ADDR_ANY).</term>
/// </item>
/// <item>
/// <term>WSAEAFNOSUPPORT</term>
/// <term>Addresses in the specified family cannot be used with this socket.</term>
/// </item>
/// <item>
/// <term>WSAECONNREFUSED</term>
/// <term>The attempt to connect was rejected.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The name or the namelen parameter is not a valid part of the user address space, the namelen parameter is too small, the buffer
/// length for lpCalleeData, lpSQOS, and lpGQOS are too small, or the buffer length for lpCallerData is too large.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>
/// The parameter s is a listening socket, or the destination address specified is not consistent with that of the constrained group
/// to which the socket belongs, or the lpGQOS parameter is not NULL.
/// </term>
/// </item>
/// <item>
/// <term>WSAEISCONN</term>
/// <term>The socket is already connected (connection-oriented sockets only).</term>
/// </item>
/// <item>
/// <term>WSAENETUNREACH</term>
/// <term>The network cannot be reached from this host at this time.</term>
/// </item>
/// <item>
/// <term>WSAEHOSTUNREACH</term>
/// <term>A socket operation was attempted to an unreachable host.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>No buffer space is available. The socket cannot be connected.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEOPNOTSUPP</term>
/// <term>The FLOWSPEC structures specified in lpSQOS and lpGQOS cannot be satisfied.</term>
/// </item>
/// <item>
/// <term>WSAEPROTONOSUPPORT</term>
/// <term>The lpCallerData parameter is not supported by the service provider.</term>
/// </item>
/// <item>
/// <term>WSAETIMEDOUT</term>
/// <term>Attempt to connect timed out without establishing a connection.</term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>The socket is marked as nonblocking and the connection cannot be completed immediately.</term>
/// </item>
/// <item>
/// <term>WSAEACCES</term>
/// <term>Attempt to connect datagram socket to broadcast address failed because setsockopt SO_BROADCAST is not enabled.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAConnect</c> function is used to create a connection to the specified destination, and to perform a number of other
/// ancillary operations that occur at connect time. If the socket, s, is unbound, unique values are assigned to the local
/// association by the system, and the socket is marked as bound.
/// </para>
/// <para>
/// For applications targeted to Windows Vista and later, consider using the WSAConnectByList or WSAConnectByName function which
/// greatly simplify client application design.
/// </para>
/// <para>
/// For connection-oriented sockets (for example, type SOCK_STREAM), an active connection is initiated to the foreign host using
/// name (an address in the namespace of the socket; for a detailed description, please see bind). When this call completes
/// successfully, the socket is ready to send/receive data. If the address parameter of the name structure is all zeroes,
/// <c>WSAConnect</c> will return the error WSAEADDRNOTAVAIL. Any attempt to reconnect an active connection will fail with the error
/// code WSAEISCONN.
/// </para>
/// <para>
/// <c>Note</c> 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.
/// </para>
/// <para>
/// For connection-oriented, nonblocking sockets, it is often not possible to complete the connection immediately. In such cases,
/// this function returns the error WSAEWOULDBLOCK. However, the operation proceeds. When the success or failure outcome becomes
/// known, it may be reported in one of several ways depending on how the client registers for notification. If the client uses
/// select, success is reported in the writefds set and failure is reported in the exceptfds set. If the client uses WSAAsyncSelect
/// or WSAEventSelect, the notification is announced with FD_CONNECT and the error code associated with the FD_CONNECT indicates
/// either success or a specific reason for failure.
/// </para>
/// <para>
/// For a connectionless socket (for example, type SOCK_DGRAM), the operation performed by <c>WSAConnect</c> is merely to establish
/// a default destination address so that the socket can be used on subsequent connection-oriented send and receive operations
/// (send, WSASend, recv, and WSARecv). Any datagrams received from an address other than the destination address specified will be
/// discarded. If the entire name structure is all zeros (not just the address parameter of the name structure), then the socket
/// will be disconnected. Then, the default remote address will be indeterminate, so <c>send</c>, <c>WSASend</c>, <c>recv</c>, and
/// <c>WSARecv</c> calls will return the error code WSAENOTCONN. However, sendto, WSASendTo, recvfrom, and WSARecvFrom can still be
/// used. The default destination can be changed by simply calling <c>WSAConnect</c> again, even if the socket is already connected.
/// Any datagrams queued for receipt are discarded if name is different from the previous <c>WSAConnect</c>.
/// </para>
/// <para>
/// For connectionless sockets, name can indicate any valid address, including a broadcast address. However, to connect to a
/// broadcast address, a socket must have setsockopt SO_BROADCAST enabled. Otherwise, <c>WSAConnect</c> will fail with the error
/// code WSAEACCES.
/// </para>
/// <para>
/// On connectionless sockets, exchange of user-to-user data is not possible and the corresponding parameters will be silently ignored.
/// </para>
/// <para>
/// The application is responsible for allocating any memory space pointed to directly or indirectly by any of the parameters it specifies.
/// </para>
/// <para>
/// The lpCallerData parameter contains a pointer to any user data that is to be sent along with the connection request (called
/// connect data). This is additional data, not in the normal network data stream, that is sent with network requests to establish a
/// connection. This option is used by legacy protocols such as DECNet, OSI TP4, and others.
/// </para>
/// <para>
/// If lpCallerData is <c>NULL</c>, no user data will be passed to the peer. The lpCalleeData is a result parameter that will
/// contain any user data passed back from the other socket as part of the connection establishment in a WSABUF structure. The
/// <c>len</c> member of the <c>WSABUF</c> structure pointed to by the lpCalleeData parameter initially contains the length of the
/// buffer allocated by the application for the <c>buf</c> member of the <c>WSABUF</c> structure. The <c>len</c> member of the
/// <c>WSABUF</c> structure pointed to by the lpCalleeData parameter will be set to zero if no user data has been passed back. The
/// lpCalleeData information will be valid when the connection operation is complete. For blocking sockets, the connection operation
/// completes when the <c>WSAConnect</c> function returns. For nonblocking sockets, completion will be after the FD_CONNECT
/// notification has occurred. If lpCalleeData is <c>NULL</c>, no user data will be passed back. The exact format of the user data
/// is specific to the address family to which the socket belongs.
/// </para>
/// <para>
/// At connect time, an application can use the lpSQOS and lpGQOS parameter to override any previous quality of service
/// specification made for the socket through WSAIoctl with either the SIO_SET_QOS or SIO_SET_GROUP_QOS opcode.
/// </para>
/// <para>
/// The lpSQOS parameter specifies the FLOWSPEC structures for socket s, one for each direction, followed by any additional
/// provider-specific parameters. If either the associated transport provider in general or the specific type of socket in
/// particular cannot honor the quality of service request, an error will be returned as indicated in the following. The sending or
/// receiving flow specification values will be ignored, respectively, for any unidirectional sockets. If no provider-specific
/// parameters are specified, the <c>buf</c> and <c>len</c> members of the WSABUF structure pointed to by the lpCalleeData parameter
/// should be set to <c>NULL</c> and zero, respectively. A <c>NULL</c> value for lpSQOS parameter indicates no application-supplied
/// quality of service.
/// </para>
/// <para>
/// Reserved for future use with socket groups lpGQOS specifies the FLOWSPEC structures for the socket group (if applicable), one
/// for each direction, followed by any additional provider-specific parameters. If no provider-specific parameters are specified,
/// the <c>buf</c> and <c>len</c> members of the WSABUF structure pointed to by the lpCalleeData parameter should be set to
/// <c>NULL</c> and zero, respectively. A <c>NULL</c> value for lpGQOS indicates no application-supplied group quality of service.
/// This parameter will be ignored if s is not the creator of the socket group.
/// </para>
/// <para>
/// When connected sockets become closed for whatever reason, they should be discarded and recreated. It is safest to assume that
/// when things go awry for any reason on a connected socket, the application must discard and recreate the needed sockets in order
/// to return to a stable point.
/// </para>
/// <para>
/// <c>Note</c> When issuing a blocking Winsock call such as <c>WSAConnect</c>, 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.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaconnect int WSAAPI WSAConnect( SOCKET s, const
// sockaddr *name, int namelen, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "3b32cc6e-3df7-4104-a0d4-317fd445c7b2")]
public static extern WSRESULT WSAConnect(SOCKET s, [In] SOCKADDR name, int namelen, [In, Optional] IntPtr lpCallerData,
[Out, Optional] IntPtr lpCalleeData, [Optional] IntPtr lpSQOS, [Optional] IntPtr lpGQOS);
/// <summary>
/// <para>
/// The <c>WSAConnectByList</c> function establishes a connection to one out of a collection of possible endpoints represented by a
/// set of destination addresses (host names and ports). This function takes all the destination addresses passed to it and all of
/// the local computer's source addresses, and tries connecting using all possible address combinations before giving up.
/// </para>
/// <para>This function supports both IPv4 and IPv6 addresses.</para>
/// </summary>
/// <param name="s">
/// A descriptor that identifies an unbound and unconnected socket. Note that unlike other Winsock calls to establish a connection
/// (for example, WSAConnect), the <c>WSAConnectByList</c> function requires an unbound socket.
/// </param>
/// <param name="SocketAddress">
/// A pointer to a SOCKET_ADDRESS_LIST structure that represents the possible destination address and port pairs to connect to a
/// peer. It is the application's responsibility to fill in the port number in the each SOCKET_ADDRESS structure in the <c>SOCKET_ADDRESS_LIST</c>.
/// </param>
/// <param name="LocalAddressLength">
/// On input, a pointer to the size, in bytes, of the LocalAddress buffer provided by the caller. On output, a pointer to the size,
/// in bytes, of the <c>SOCKADDR</c> for the local address stored in the LocalAddress buffer filled in by the system upon successful
/// completion of the call.
/// </param>
/// <param name="LocalAddress">
/// A pointer to the <c>SOCKADDR</c> structure that receives the local address of the connection. The size of the parameter is
/// exactly the size returned in LocalAddressLength. This is the same information that would be returned by the getsockname
/// function. This parameter can be <c>NULL</c>, in which case, the LocalAddressLength parameter is ignored.
/// </param>
/// <param name="RemoteAddressLength">
/// On input, a pointer to the size, in bytes, of the RemoteAddress buffer provided by the caller. On output, a pointer to the size,
/// in bytes, of the <c>SOCKADDR</c> for the remote address stored in RemoteAddress buffer filled-in by the system upon successful
/// completion of the call.
/// </param>
/// <param name="RemoteAddress">
/// A pointer to the <c>SOCKADDR</c> structure that receives the remote address of the connection. This is the same information that
/// would be returned by the <c>getpeername</c> function. This parameter can be <c>NULL</c>, in which case, the RemoteAddressLength
/// is ignored.
/// </param>
/// <param name="timeout">
/// The time, in milliseconds, to wait for a response from the remote application before aborting the call. This parameter can be
/// <c>NULL</c> in which case <c>WSAConnectByList</c> will complete after either the connection is successfully established or after
/// a connection was attempted and failed on all possible local-remote address pairs.
/// </param>
/// <param name="Reserved">Reserved for future implementation. This parameter must be set to <c>NULL</c>.</param>
/// <returns>
/// <para>
/// If a connection is established, <c>WSAConnectByList</c> returns <c>TRUE</c> and LocalAddress and RemoteAddress parameters are
/// filled in if these buffers were supplied by the caller.
/// </para>
/// <para>If the call fails, <c>FALSE</c> is returned. WSAGetLastError can then be called to get extended error information.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>WSAEHOSTUNREACH</term>
/// <term>The host passed as the nodename parameter was unreachable.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>An invalid parameter was passed to the function. The Reserved parameter must be NULL.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>Sufficient memory could not be allocated.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>An invalid socket was passed to the function. The s parameter must not be INVALID_SOCKET or NULL.</term>
/// </item>
/// <item>
/// <term>WSAETIMEDOUT</term>
/// <term>A response from the remote application was not received before the timeout parameter was exceeded.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// <c>WSAConnectByList</c> is similar to the WSAConnectByName function. Instead of taking a single host name and service name
/// (port), <c>WSAConnectByList</c> takes a list of addresses (host addresses and ports) and connects to one of the addresses. The
/// <c>WSAConnectByList</c> function is designed to support peer-to-peer collaboration scenarios where an application needs to
/// connect to any available node out of a list of potential nodes. <c>WSAConnectByList</c> is compatible with both IPv6 and IPv4 versions.
/// </para>
/// <para>
/// The set of possible destinations, represented by a list of addresses, is provided by the caller. <c>WSAConnectByList</c> does
/// more than simply attempt to connect to one of possibly many destination addresses. Specifically, the function takes all remote
/// addresses passed in by the caller, all local addresses, and then attempts a connection first using address pairs with the
/// highest chance of success. As such, <c>WSAConnectByList</c> not only ensures that connection will be established if a connection
/// is at all possible, but also minimizes the time to establish the connection.
/// </para>
/// <para>
/// The caller can specify the LocalAddress and RemoteAddress buffers and lengths to determine the local and remote addresses for
/// which the connection was successfully established.
/// </para>
/// <para>
/// The timeout parameter allows the caller to limit the time spent by the function in establishing a connection. Internally,
/// <c>WSAConnectByList</c> performs multiple operations (connection attempts). In between each operation, the timeout parameter is
/// checked to see if the timeout has been exceeded and, if so, the call is aborted. Note that an individual operation (connect)
/// will not be interrupted once the timeout is exceeded, so the <c>WSAConnectByList</c> call can take longer to time out than the
/// value specified in the timeout parameter.
/// </para>
/// <para>
/// <c>WSAConnectByList</c> has limitations: It works only for connection-oriented sockets, such as those of type SOCK_STREAM. The
/// function does not support overlapped I/O or non-blocking behavior. <c>WSAConnectByList</c> will block even if the socket is in
/// non-blocking mode. <c>WSAConnectByList</c> will try connecting (one-by-one) to the various addresses provided by the caller.
/// Potentially, each of these connection attempts may fail with a different error code. Since only a single error code can be
/// returned, the value returned is the error code from the last connection attempt.
/// </para>
/// <para>
/// To enable both IPv6 and IPv4 addresses to be passed in the single address list accepted by the function, the following steps
/// must be performed prior to calling the function:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// The setsockopt function must be called on a socket created for the AF_INET6 address family to disable the <c>IPV6_V6ONLY</c>
/// socket option before calling <c>WSAConnectByList</c>. This is accomplished by calling the <c>setsockopt</c> function on the
/// socket with the level parameter set to <c>IPPROTO_IPV6</c> (see IPPROTO_IPV6 Socket Options), the optname parameter set to
/// <c>IPV6_V6ONLY</c>, and the optvalue parameter value set to zero .
/// </term>
/// </item>
/// <item>
/// <term>
/// Any IPv4 addresses must be represented in the IPv4-mapped IPv6 address format which enables an IPv6 only application to
/// communicate with an IPv4 node. The IPv4-mapped IPv6 address format allows the IPv4 address of an IPv4 node to be represented as
/// an IPv6 address. The IPv4 address is encoded into the low-order 32 bits of the IPv6 address, and the high-order 96 bits hold the
/// fixed prefix 0:0:0:0:0:FFFF. The IPv4-mapped IPv6 address format is specified in RFC 4291. For more information, see
/// www.ietf.org/rfc/rfc4291.txt. The IN6ADDR_SETV4MAPPED macro in Mstcpip.h can be used to convert an IPv4 address to the required
/// IPv4-mapped IPv6 address format.
/// </term>
/// </item>
/// </list>
/// <para>
/// The arrays of pointers passed in the SocketAddressList parameter point to an array of SOCKET_ADDRESS structures, which are a
/// generic data type. The RemoteAddress and the LocalAddress parameters also point to <c>SOCKADDR</c> structures. When
/// <c>WSAConnectByList</c> is called, it is expected that a socket address type specific to the network protocol or address family
/// being used will actually be passed in these parameters. So for IPv4 addresses, a pointer to a <c>sockaddr_in</c> structure would
/// be cast to a pointer to <c>SOCKADDR</c> when passed as a parameter. For IPv6 addresses, a pointer to a <c>sockaddr_in6</c>
/// structure would be cast to a pointer to <c>SOCKADDR</c> when passed as a parameter. The SocketAddressList parameter can contain
/// pointers to a mixture of IPv4 and IPv6 addresses. So some <c>SOCKET_ADDRESS</c> pointers can be to <c>sockaddr_in</c> structures
/// and others can be to <c>sockaddr_in6</c> structures. If it is expected that IPv6 addresses can be used, then the RemoteAddress
/// and LocalAddress parameters should point to <c>sockaddr_in6</c> structures and be cast to <c>SOCKADDR</c> structures. The
/// RemoteAddressLength and the LocalAddressLength parameters must represent the length of these larger structures.
/// </para>
/// <para>
/// When the WSAConnectByList function returns <c>TRUE</c>, 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.
/// </para>
/// <para>For example:</para>
/// <para>
/// <c>Note</c> When issuing a blocking Winsock call such as WSAConnectByList with the timeout parameter set to <c>NULL</c>, 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.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// <para>Examples</para>
/// <para>Establish a connection using <c>WSAConnectByList</c>.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaconnectbylist BOOL WSAConnectByList( SOCKET s,
// PSOCKET_ADDRESS_LIST SocketAddress, LPDWORD LocalAddressLength, LPSOCKADDR LocalAddress, LPDWORD RemoteAddressLength, LPSOCKADDR
// RemoteAddress, const timeval *timeout, LPWSAOVERLAPPED Reserved );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "7323d814-e96e-44b9-8ade-a9317e4fbf17")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WSAConnectByList(SOCKET s, in SOCKET_ADDRESS_LIST SocketAddress, ref uint LocalAddressLength, [Out] SOCKADDR LocalAddress,
ref uint RemoteAddressLength, [Out] SOCKADDR RemoteAddress, [In, Optional] IntPtr timeout, IntPtr Reserved = default);
/// <summary>
/// <para>
/// The <c>WSAConnectByName</c> function establishes a connection to a specified host and port. This function is provided to allow a
/// quick connection to a network endpoint given a host name and port.
/// </para>
/// <para>This function supports both IPv4 and IPv6 addresses.</para>
/// </summary>
/// <param name="s">
/// <para>A descriptor that identifies an unconnected socket.</para>
/// <para>
/// <c>Note</c> On Windows 7, Windows Server 2008 R2, and earlier, the <c>WSAConnectByName</c> function requires an unbound and
/// unconnected socket. This differs from other Winsock calls to establish a connection (for example, WSAConnect).
/// </para>
/// </param>
/// <param name="nodename">
/// A <c>NULL</c>-terminated string that contains the name of the host or the IP address of the host on which to connect for IPv4 or IPv6.
/// </param>
/// <param name="servicename">
/// <para>
/// A <c>NULL</c>-terminated string that contains the service name or destination port of the host on which to connect for IPv4 or IPv6.
/// </para>
/// <para>
/// A service name is a string alias for a port number. For example, “http” is an alias for port 80 defined by the Internet
/// Engineering Task Force (IETF) as the default port used by web servers for the HTTP protocol. Possible values for the servicename
/// parameter when a port number is not specified are listed in the following file:
/// </para>
/// <para>%WINDIR%\system32\drivers\etc\services</para>
/// </param>
/// <param name="LocalAddressLength">
/// On input, a pointer to the size, in bytes, of the LocalAddress buffer provided by the caller. On output, a pointer to the size,
/// in bytes, of the <c>SOCKADDR</c> for the local address stored in the LocalAddress buffer filled in by the system upon successful
/// completion of the call.
/// </param>
/// <param name="LocalAddress">
/// A pointer to the <c>SOCKADDR</c> structure that receives the local address of the connection. The size of the parameter is
/// exactly the size returned in LocalAddressLength. This is the same information that would be returned by the getsockname
/// function. This parameter can be <c>NULL</c>, in which case, the LocalAddressLength parameter is ignored.
/// </param>
/// <param name="RemoteAddressLength">
/// On input, a pointer to the size, in bytes, of the RemoteAddress buffer provided by the caller. On output, a pointer to the size,
/// in bytes, of the <c>SOCKADDR</c> for the remote address stored in RemoteAddress buffer filled-in by the system upon successful
/// completion of the call.
/// </param>
/// <param name="RemoteAddress">
/// A pointer to the <c>SOCKADDR</c> structure that receives the remote address of the connection. This is the same information that
/// would be returned by the <c>getpeername</c> function. This parameter can be <c>NULL</c>, in which case, the RemoteAddressLength
/// is ignored.
/// </param>
/// <param name="timeout">The time, in milliseconds, to wait for a response from the remote application before aborting the call.</param>
/// <param name="Reserved">Reserved for future implementation. This parameter must be set to <c>NULL</c>.</param>
/// <returns>
/// <para>
/// If a connection is established, <c>WSAConnectByName</c> returns <c>TRUE</c> and LocalAddress and RemoteAddress parameters are
/// filled in if these buffers were supplied by the caller.
/// </para>
/// <para>If the call fails, <c>FALSE</c> is returned. WSAGetLastError can then be called to get extended error information.</para>
/// <list type="table">
/// <listheader>
/// <term>Return code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>WSAEHOSTUNREACH</term>
/// <term>The host passed as the nodename parameter was unreachable.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>
/// An invalid parameter was passed to the function. The nodename or the servicename parameter must not be NULL. The Reserved
/// parameter must be NULL.
/// </term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>Sufficient memory could not be allocated.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>An invalid socket was passed to the function. The s parameter must not be INVALID_SOCKET or NULL.</term>
/// </item>
/// <item>
/// <term>WSAETIMEDOUT</term>
/// <term>A response from the remote application was not received before the timeout parameter was exceeded.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// <c>WSAConnectByName</c> is provided to enable quick and transparent connections to remote hosts on specific ports. It is
/// compatible with both IPv6 and IPv4 versions.
/// </para>
/// <para>To enable both IPv6 and IPv4 communications, use the following method:</para>
/// <list type="bullet">
/// <item>
/// <term>
/// The setsockopt function must be called on a socket created for the AF_INET6 address family to disable the <c>IPV6_V6ONLY</c>
/// socket option before calling <c>WSAConnectByName</c>. This is accomplished by calling the <c>setsockopt</c> function on the
/// socket with the level parameter set to <c>IPPROTO_IPV6</c> (see IPPROTO_IPV6 Socket Options), the optname parameter set to
/// <c>IPV6_V6ONLY</c>, and the optvalue parameter value set to zero .
/// </term>
/// </item>
/// </list>
/// <para>
/// <c>WSAConnectByName</c> has limitations: It works only for connection-oriented sockets, such as those of type SOCK_STREAM. The
/// function does not support overlapped I/O or non-blocking behavior. <c>WSAConnectByName</c> will block even if the socket is in
/// non-blocking mode.
/// </para>
/// <para>
/// <c>WSAConnectByName</c> does not support user-provided data during the establishment of a connection. This call does not support
/// FLOWSPEC structures, either. In cases where these features are required, WSAConnect must be used instead.
/// </para>
/// <para>
/// In versions before Windows 10, if an application needs to bind to a specific local address or port, then <c>WSAConnectByName</c>
/// cannot be used since the socket parameter to <c>WSAConnectByName</c> must be an unbound socket.
/// </para>
/// <para>This restriction was removed Windows 10.</para>
/// <para>
/// The RemoteAddress and the LocalAddress parameters point to a <c>SOCKADDR</c> structure, which is a generic data type. When
/// <c>WSAConnectByName</c> is called, it is expected that a socket address type specific to the network protocol or address family
/// being used will actually be passed in these parameters. So for IPv4 addresses, a pointer to a <c>sockaddr_in</c> structure would
/// be cast to a pointer to <c>SOCKADDR</c> as the RemoteAddress and LocalAddressparameters. For IPv6 addresses, a pointer to a
/// <c>sockaddr_in6</c> structure would be cast to a pointer to <c>SOCKADDR</c> as the RemoteAddress and LocalAddressparameters.
/// </para>
/// <para>
/// When the <c>WSAConnectByName</c> function returns <c>TRUE</c>, 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.
/// </para>
/// <para>For example:</para>
/// <para>
/// <c>Note</c> When issuing a blocking Winsock call such as <c>WSAConnectByName</c> with the timeout parameter set to <c>NULL</c>,
/// 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.
/// </para>
/// <para>
/// <c>Windows Phone 8:</c> The <c>WSAConnectByNameW</c> function is supported for Windows Phone Store apps on Windows Phone 8 and later.
/// </para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: The <c>WSAConnectByNameW</c> function is supported for Windows Store apps
/// on Windows 8.1, Windows Server 2012 R2, and later.
/// </para>
/// <para>Examples</para>
/// <para>Establish a connection using <c>WSAConnectByName</c>.</para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaconnectbynamea BOOL WSAConnectByNameA( SOCKET s,
// LPCSTR nodename, LPCSTR servicename, LPDWORD LocalAddressLength, LPSOCKADDR LocalAddress, LPDWORD RemoteAddressLength, LPSOCKADDR
// RemoteAddress, const timeval *timeout, LPWSAOVERLAPPED Reserved );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winsock2.h", MSDNShortId = "6d87699f-03bd-4579-9907-ae3c29b7332b")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WSAConnectByName(SOCKET s, [MarshalAs(UnmanagedType.LPTStr)] string nodename, [MarshalAs(UnmanagedType.LPTStr)] string servicename, ref uint LocalAddressLength,
[Out] SOCKADDR LocalAddress, ref uint RemoteAddressLength, [Out] SOCKADDR RemoteAddress, [In, Optional] IntPtr timeout, IntPtr Reserved = default);
/// <summary>The <c>WSACreateEvent</c> function creates a new event object.</summary>
/// <returns>
/// <para>
/// If no error occurs, <c>WSACreateEvent</c> returns the handle of the event object. Otherwise, the return value is
/// WSA_INVALID_EVENT. To get extended error information, call WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSA_NOT_ENOUGH_MEMORY</term>
/// <term>Not enough free memory available to create the event object.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSACreateEvent</c> function creates a manual-reset event object with an initial state of nonsignaled. The handle of the
/// event object returned cannot be inherited by child processes. The event object is unnamed.
/// </para>
/// <para>
/// The WSASetEvent function can be called to set the state of the event object to signaled. The WSAResetEvent function can be
/// called to set the state of the event object to nonsignaled. When an event object is no longer needed, the WSACloseEvent function
/// should be called to free the resources associated with the event object.
/// </para>
/// <para>
/// Windows Sockets 2 event objects are system objects in Windows environments. Therefore, if a Windows application wants to use an
/// auto-reset event rather than a manual-reset event, the application can call the CreateEvent function directly. The scope of an
/// event object is limited to the process in which it is created.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsacreateevent WSAEVENT WSAAPI WSACreateEvent();
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "cff3bc31-f34c-4bb2-9004-5ec31d0a704a")]
public static extern SafeWSAEVENT WSACreateEvent();
/// <summary>
/// The <c>WSADuplicateSocket</c> function returns a WSAPROTOCOL_INFO structure that can be used to create a new socket descriptor
/// for a shared socket. The <c>WSADuplicateSocket</c> function cannot be used on a QOS-enabled socket.
/// </summary>
/// <param name="s">Descriptor identifying the local socket.</param>
/// <param name="dwProcessId">Process identifier of the target process in which the duplicated socket will be used.</param>
/// <param name="lpProtocolInfo">
/// Pointer to a buffer, allocated by the client, that is large enough to contain a WSAPROTOCOL_INFO structure. The service provider
/// copies the protocol information structure contents to this buffer.
/// </param>
/// <returns>
/// <para>
/// If no error occurs, <c>WSADuplicateSocket</c> returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error
/// code can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>Indicates that one of the specified parameters was invalid.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEMFILE</term>
/// <term>No more socket descriptors are available.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>No buffer space is available. The socket cannot be created.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The lpProtocolInfo parameter is not a valid part of the user address space.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSADuplicateSocket</c> function is used to enable socket sharing between processes. A source process calls
/// <c>WSADuplicateSocket</c> to obtain a special WSAPROTOCOL_INFO structure. It uses some interprocess communications (IPC)
/// mechanism to pass the contents of this structure to a target process, which in turn uses it in a call to WSASocket to obtain a
/// descriptor for the duplicated socket. The special <c>WSAPROTOCOL_INFO</c> structure can only be used once by the target process.
/// </para>
/// <para>
/// Sockets can be shared among threads in a given process without using the <c>WSADuplicateSocket</c> function because a socket
/// descriptor is valid in all threads of a process.
/// </para>
/// <para>One possible scenario for establishing and handing off a shared socket is illustrated in the following table.</para>
/// <list type="table">
/// <listheader>
/// <term>Source process</term>
/// <term>IPC</term>
/// <term>Destination process</term>
/// </listheader>
/// <item>
/// <term>1) WSASocket, WSAConnect</term>
/// <term/>
/// <term/>
/// </item>
/// <item>
/// <term>2) Request target process identifier</term>
/// <term>==&gt;</term>
/// <term/>
/// </item>
/// <item>
/// <term/>
/// <term/>
/// <term>3) Receive process identifier request and respond</term>
/// </item>
/// <item>
/// <term>4) Receive process identifier</term>
/// <term>&lt;==</term>
/// <term/>
/// </item>
/// <item>
/// <term>5) Call WSADuplicateSocket to get a special WSAPROTOCOL_INFO structure</term>
/// <term/>
/// <term/>
/// </item>
/// <item>
/// <term>6) Send WSAPROTOCOL_INFO structure to target</term>
/// <term/>
/// <term/>
/// </item>
/// <item>
/// <term/>
/// <term>==&gt;</term>
/// <term>7) Receive WSAPROTOCOL_INFO structure</term>
/// </item>
/// <item>
/// <term/>
/// <term/>
/// <term>8) Call WSASocket to create shared socket descriptor.</term>
/// </item>
/// <item>
/// <term/>
/// <term/>
/// <term>9) Use shared socket for data exchange</term>
/// </item>
/// <item>
/// <term>10) closesocket</term>
/// <term>&lt;==</term>
/// <term/>
/// </item>
/// </list>
/// <para>
/// The descriptors that reference a shared socket can be used independently for I/O. However, the Windows Sockets interface does
/// not implement any type of access control, so it is up to the processes involved to coordinate their operations on a shared
/// socket. Shared sockets are typically used to having one process that is responsible for creating sockets and establishing
/// connections, and other processes that are responsible for information exchange.
/// </para>
/// <para>
/// All of the state information associated with a socket is held in common across all the descriptors because the socket
/// descriptors are duplicated and not the actual socket. For example, a setsockopt operation performed using one descriptor is
/// subsequently visible using a getsockopt from any or all descriptors. Both the source process and the destination process should
/// pass the same flags to their respective WSASocket function calls. If the source process uses the socket function to create the
/// socket, the destination process must pass the <c>WSA_FLAG_OVERLAPPED</c> flag to its <c>WSASocket</c> function call. A process
/// can call closesocket on a duplicated socket and the descriptor will become deallocated. The underlying socket, however, will
/// remain open until <c>closesocket</c> is called by the last remaining descriptor.
/// </para>
/// <para>
/// Notification on shared sockets is subject to the usual constraints of WSAAsyncSelect and WSAEventSelect. Issuing either of these
/// calls using any of the shared descriptors cancels any previous event registration for the socket, regardless of which descriptor
/// was used to make that registration. Thus, a shared socket cannot deliver FD_READ events to process A and FD_WRITE events to
/// process B. For situations when such tight coordination is required, developers would be advised to use threads instead of
/// separate processes.
/// </para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: The <c>WSADuplicateSocketW</c> function is supported for Windows Store
/// apps on Windows 8.1, Windows Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaduplicatesocketa int WSAAPI WSADuplicateSocketA(
// SOCKET s, DWORD dwProcessId, LPWSAPROTOCOL_INFOA lpProtocolInfo );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winsock2.h", MSDNShortId = "d4028461-bfa6-4074-9460-5d1371790d41")]
public static extern WSRESULT WSADuplicateSocket(SOCKET s, uint dwProcessId, out WSAPROTOCOL_INFO lpProtocolInfo);
/// <summary>The <c>WSAEnumNameSpaceProviders</c> function retrieves information on available namespace providers.</summary>
/// <param name="lpdwBufferLength">
/// On input, the number of bytes contained in the buffer pointed to by lpnspBuffer. On output (if the function fails, and the error
/// is WSAEFAULT), the minimum number of bytes to pass for the lpnspBuffer to retrieve all the requested information. The buffer
/// passed to <c>WSAEnumNameSpaceProviders</c> must be sufficient to hold all of the namespace information.
/// </param>
/// <param name="lpnspBuffer">
/// A buffer that is filled with WSANAMESPACE_INFO structures. The returned structures are located consecutively at the head of the
/// buffer. Variable sized information referenced by pointers in the structures point to locations within the buffer located between
/// the end of the fixed sized structures and the end of the buffer. The number of structures filled in is the return value of <c>WSAEnumNameSpaceProviders</c>.
/// </param>
/// <returns>
/// <para>
/// The <c>WSAEnumNameSpaceProviders</c> function returns the number of WSANAMESPACE_INFO structures copied into lpnspBuffer.
/// Otherwise, the value SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The lpnspBuffer parameter was a NULL pointer or the buffer length, lpdwBufferLength, was too small to receive all the relevant
/// WSANAMESPACE_INFO structures and associated information. When this error is returned, the buffer length required is returned in
/// the lpdwBufferLength parameter.
/// </term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>
/// The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
/// </term>
/// </item>
/// <item>
/// <term>WSA_NOT_ENOUGH_MEMORY</term>
/// <term>There was insufficient memory to perform the operation.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAEnumNameSpaceProviders</c> function returns information on available namespace providers in the buffer pointed to by
/// the lpnspBuffer parameter. The returned buffer contains an array of WSANAMESPACE_INFO structures located consecutively at the
/// head of the buffer. Variable sized information referenced by pointers in the <c>WSANAMESPACE_INFO</c> structures point to
/// locations within the buffer located between the end of the fixed <c>WSANAMESPACE_INFO</c> structures and the end of the buffer.
/// The number of <c>WSANAMESPACE_INFO</c> structures filled in is returned by the <c>WSAEnumNameSpaceProviders</c> function.
/// </para>
/// <para>
/// Each WSANAMESPACE_INFO structure entry contains the provider-specific information on the namespace entry passed to the
/// WSCInstallNameSpace and WSCInstallNameSpace32 functions when the namespace provider was installed.
/// </para>
/// <para>
/// The WSAEnumNameSpaceProvidersEx function is an enhanced version of the <c>WSAEnumNameSpaceProviders</c> function. The
/// WSCEnumNameSpaceProvidersEx32 function is an enhanced version of the <c>WSAEnumNameSpaceProviders</c> function that returns
/// information on available 32-bit namespace providers for use on 64-bit platforms.
/// </para>
/// <para>Example Code</para>
/// <para>
/// The following example demonstrates the use of the <c>WSAEnumNameSpaceProviders</c> function to retrieve information on available
/// namespace providers.
/// </para>
/// <para>
/// <c>Windows Phone 8:</c> The <c>WSAEnumNameSpaceProvidersW</c> function is supported for Windows Phone Store apps on Windows
/// Phone 8 and later.
/// </para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: The <c>WSAEnumNameSpaceProvidersW</c> function is supported for Windows
/// Store apps on Windows 8.1, Windows Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaenumnamespaceprovidersw INT WSAAPI
// WSAEnumNameSpaceProvidersW( LPDWORD lpdwBufferLength, LPWSANAMESPACE_INFOW lpnspBuffer );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Unicode)]
[PInvokeData("winsock2.h", MSDNShortId = "f5b6cd42-c5cb-43b6-bb96-fd260217e252")]
public static extern int WSAEnumNameSpaceProviders(ref uint lpdwBufferLength, [Out] IntPtr lpnspBuffer);
/// <summary>The <c>WSAEnumNameSpaceProvidersEx</c> function retrieves information on available namespace providers.</summary>
/// <param name="lpdwBufferLength">
/// On input, the number of bytes contained in the buffer pointed to by lpnspBuffer. On output (if the function fails, and the error
/// is WSAEFAULT), the minimum number of bytes to allocate for the lpnspBuffer buffer to allow it to retrieve all the requested
/// information. The buffer passed to <c>WSAEnumNameSpaceProvidersEx</c> must be sufficient to hold all of the namespace information.
/// </param>
/// <param name="lpnspBuffer">
/// A buffer that is filled with WSANAMESPACE_INFOEX structures. The returned structures are located consecutively at the head of
/// the buffer. Variable sized information referenced by pointers in the structures point to locations within the buffer located
/// between the end of the fixed sized structures and the end of the buffer. The number of structures filled in is the return value
/// of <c>WSAEnumNameSpaceProvidersEx</c>.
/// </param>
/// <returns>
/// <para>
/// The <c>WSAEnumNameSpaceProvidersEx</c> function returns the number of WSANAMESPACE_INFOEX structures copied into lpnspBuffer.
/// Otherwise, the value SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The lpnspBuffer parameter was a NULL pointer or the buffer length, lpdwBufferLength, was too small to receive all the relevant
/// WSANAMESPACE_INFOEX structures and associated information. When this error is returned, the buffer length required is returned
/// in the lpdwBufferLength parameter.
/// </term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>
/// The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
/// </term>
/// </item>
/// <item>
/// <term>WSA_NOT_ENOUGH_MEMORY</term>
/// <term>There was insufficient memory to perform the operation.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAEnumNameSpaceProvidersEx</c> function is an enhanced version of the WSAEnumNameSpaceProviders function. The
/// provider-specific data blob associated with the namespace entry passed in the lpProviderInfo parameter to the
/// WSCInstallNameSpaceEx function can be queried using <c>WSAEnumNameSpaceProvidersEx</c> function.
/// </para>
/// <para>
/// Currently, the only namespace provider included with Windows that sets information in the <c>ProviderSpecific</c> member of the
/// WSANAMESPACE_INFOEX structure is the NS_EMAIL provider. The format of the <c>ProviderSpecific</c> member for an NS_EMAIL
/// namespace provider is a NAPI_PROVIDER_INSTALLATION_BLOB structure.
/// </para>
/// <para>
/// When UNICODE or _UNICODE is defined, <c>WSAEnumNameSpaceProvidersEx</c> is defined to <c>WSAEnumNameSpaceProvidersExW</c>, the
/// Unicode version of this function. The lpnspBuffer parameter is defined to the LPSAWSANAMESPACE_INFOEXW data type and
/// <c>WSANAMESPACE_INFOEXW</c> structures are returned on success.
/// </para>
/// <para>
/// When UNICODE or _UNICODE is not defined, <c>WSAEnumNameSpaceProvidersEx</c> is defined to <c>WSAEnumNameSpaceProvidersExA</c>,
/// the ANSI version of this function. The lpnspBuffer parameter is defined to the LPSAWSANAMESPACE_INFOEXA data type and
/// <c>WSANAMESPACE_INFOEXA</c> structures are returned on success.
/// </para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: The <c>WSAEnumNameSpaceProvidersExW</c> function is supported for Windows
/// Store apps on Windows 8.1, Windows Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaenumnamespaceprovidersexa INT WSAAPI
// WSAEnumNameSpaceProvidersExA( LPDWORD lpdwBufferLength, LPWSANAMESPACE_INFOEXA lpnspBuffer );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Unicode)]
[PInvokeData("winsock2.h", MSDNShortId = "34bc96aa-63f7-4ab8-9376-6f4b979225ca")]
public static extern int WSAEnumNameSpaceProvidersEx(ref uint lpdwBufferLength, [Out] IntPtr lpnspBuffer);
/// <summary>
/// The <c>WSAEnumNetworkEvents</c> function discovers occurrences of network events for the indicated socket, clear internal
/// network event records, and reset event objects (optional).
/// </summary>
/// <param name="s">A descriptor identifying the socket.</param>
/// <param name="hEventObject">An optional handle identifying an associated event object to be reset.</param>
/// <param name="lpNetworkEvents">
/// A pointer to a WSANETWORKEVENTS structure that is filled with a record of network events that occurred and any associated error codes.
/// </param>
/// <returns>
/// <para>
/// The return value is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error
/// number can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>One of the specified parameters was invalid.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The lpNetworkEvents parameter is not a valid part of the user address space.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAEnumNetworkEvents</c> function is used to discover which network events have occurred for the indicated socket since
/// the last invocation of this function. It is intended for use in conjunction with WSAEventSelect, which associates an event
/// object with one or more network events. The recording of network events commences when <c>WSAEventSelect</c> is called with a
/// nonzero lNetworkEvents parameter and remains in effect until another call is made to <c>WSAEventSelect</c> with the
/// lNetworkEvents parameter set to zero, or until a call is made to WSAAsyncSelect.
/// </para>
/// <para>
/// <c>WSAEnumNetworkEvents</c> only reports network activity and errors nominated through WSAEventSelect. See the descriptions of
/// select and WSAAsyncSelect to find out how those functions report network activity and errors.
/// </para>
/// <para>
/// The socket's internal record of network events is copied to the structure referenced by lpNetworkEvents, after which the
/// internal network events record is cleared. If the hEventObject parameter is not <c>NULL</c>, the indicated event object is also
/// reset. The Windows Sockets provider guarantees that the operations of copying the network event record, clearing it and
/// resetting any associated event object are atomic, such that the next occurrence of a nominated network event will cause the
/// event object to become set. In the case of this function returning SOCKET_ERROR, the associated event object is not reset and
/// the record of network events is not cleared.
/// </para>
/// <para>
/// The <c>lNetworkEvents</c> member of the WSANETWORKEVENTS structure indicates which of the FD_XXX network events have occurred.
/// The <c>iErrorCode</c> array is used to contain any associated error codes with the array index corresponding to the position of
/// event bits in <c>lNetworkEvents</c>. Identifiers such as FD_READ_BIT and FD_WRITE_BIT can be used to index the <c>iErrorCode</c>
/// array. Note that only those elements of the <c>iErrorCode</c> array are set that correspond to the bits set in lNetworkEvents
/// parameter. Other parameters are not modified (this is important for backward compatibility with the applications that are not
/// aware of new FD_ROUTING_INTERFACE_CHANGE and FD_ADDRESS_LIST_CHANGE events).
/// </para>
/// <para>The following error codes can be returned along with the corresponding network event.</para>
/// <para><c>Event: FD_CONNECT</c></para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAEAFNOSUPPORT</term>
/// <term>Addresses in the specified family cannot be used with this socket.</term>
/// </item>
/// <item>
/// <term>WSAECONNREFUSED</term>
/// <term>The attempt to connect was forcefully rejected.</term>
/// </item>
/// <item>
/// <term>WSAENETUNREACH</term>
/// <term>The network cannot be reached from this host at this time.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>No buffer space is available. The socket cannot be connected.</term>
/// </item>
/// <item>
/// <term>WSAETIMEDOUT</term>
/// <term>An attempt to connect timed out without establishing a connection</term>
/// </item>
/// </list>
/// <para><c>Event: FD_CLOSE</c></para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAECONNRESET</term>
/// <term>The connection was reset by the remote side.</term>
/// </item>
/// <item>
/// <term>WSAECONNABORTED</term>
/// <term>The connection was terminated due to a time-out or other failure.</term>
/// </item>
/// </list>
/// <para><c>Event: FD_ACCEPT</c></para>
/// <para><c>Event: FD_ADDRESS_LIST_CHANGE</c></para>
/// <para><c>Event: FD_GROUP_QOS</c></para>
/// <para><c>Event: FD_QOS</c></para>
/// <para><c>Event: FD_OOB</c></para>
/// <para><c>Event: FD_READ</c></para>
/// <para><c>Event: FD_WRITE</c></para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// </list>
/// <para><c>Event: FD_ROUTING_INTERFACE_CHANGE</c></para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAENETUNREACH</term>
/// <term>The specified destination is no longer reachable.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// </list>
/// <para>Example Code</para>
/// <para>The following example demonstrates the use of the WSAEnumNetworkEvents function.</para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaenumnetworkevents int WSAAPI WSAEnumNetworkEvents(
// SOCKET s, WSAEVENT hEventObject, LPWSANETWORKEVENTS lpNetworkEvents );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "2e6abccd-c82c-4a6b-8720-259986ac9984")]
public static extern WSRESULT WSAEnumNetworkEvents(SOCKET s, [Optional] WSAEVENT hEventObject, out WSANETWORKEVENTS lpNetworkEvents);
/// <summary>The <c>WSAEnumProtocols</c> function retrieves information about available transport protocols.</summary>
/// <param name="lpiProtocols">
/// A <c>NULLl</c>-terminated array of iProtocol values. This parameter is optional; if lpiProtocols is <c>NULL</c>, information on
/// all available protocols is returned. Otherwise, information is retrieved only for those protocols listed in the array.
/// </param>
/// <param name="lpProtocolBuffer">A pointer to a buffer that is filled with WSAPROTOCOL_INFO structures.</param>
/// <param name="lpdwBufferLength">
/// On input, number of bytes in the lpProtocolBuffer buffer passed to <c>WSAEnumProtocols</c>. On output, the minimum buffer size
/// that can be passed to <c>WSAEnumProtocols</c> to retrieve all the requested information. This routine has no ability to
/// enumerate over multiple calls; the passed-in buffer must be large enough to hold all entries in order for the routine to
/// succeed. This reduces the complexity of the API and should not pose a problem because the number of protocols loaded on a
/// computer is typically small.
/// </param>
/// <returns>
/// <para>
/// If no error occurs, <c>WSAEnumProtocols</c> returns the number of protocols to be reported. Otherwise, a value of SOCKET_ERROR
/// is returned and a specific error code can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>Indicates that one of the specified parameters was invalid.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>
/// The buffer length was too small to receive all the relevant WSAPROTOCOL_INFO structures and associated information. Pass in a
/// buffer at least as large as the value returned in lpdwBufferLength.
/// </term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// One or more of the lpiProtocols, lpProtocolBuffer, or lpdwBufferLength parameters are not a valid part of the user address space.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAEnumProtocols</c> function is used to discover information about the collection of transport protocols installed on
/// the local computer. Layered protocols are only usable by applications when installed in protocol chains. Information on layered
/// protocols is not returned except for any dummy layered service providers (LSPs) installed with a chain length of zero in the lpProtocolBuffer.
/// </para>
/// <para>
/// <c>Note</c> Layered Service Providers are deprecated. Starting with Windows 8 and Windows Server 2012, use Windows Filtering Platform.
/// </para>
/// <para>
/// The lpiProtocols parameter can be used as a filter to constrain the amount of information provided. Often, lpiProtocols will be
/// specified as a <c>NULL</c> pointer that will cause the function to return information on all available transport protocols and
/// protocol chains.
/// </para>
/// <para>
/// The <c>WSAEnumProtocols</c> function differs from the WSCEnumProtocols and WSCEnumProtocols32 functions in that the
/// <c>WSAEnumProtocols</c> function doesn't return WSAPROTOCOL_INFO structures for all installed protocols. The
/// <c>WSAEnumProtocols</c> function excludes protocols that the service provider has set with the <c>PFL_HIDDEN</c> flag in the
/// <c>dwProviderFlags</c> member of the WSAPROTOCOL_INFO structure to indicate to the Ws2_32.dll that this protocol should not be
/// returned in the result buffer generated by <c>WSAEnumProtocols</c> function. In addition, the <c>WSAEnumProtocols</c> function
/// does not return data for WSAPROTOCOL_INFO structures that have a chain length of one or greater (an LSP provider). The
/// <c>WSAEnumProtocols</c> only returns information on base protocols and protocol chains that lack the <c>PFL_HIDDEN</c> flag and
/// don't have a protocol chain length of zero.
/// </para>
/// <para>
/// A WSAPROTOCOL_INFO structure is provided in the buffer pointed to by lpProtocolBuffer for each requested protocol. If the
/// specified buffer is not large enough (as indicated by the input value of lpdwBufferLength ), the value pointed to by
/// lpdwBufferLength will be updated to indicate the required buffer size. The application should then obtain a large enough buffer
/// and call <c>WSAEnumProtocols</c> again.
/// </para>
/// <para>
/// The order in which the WSAPROTOCOL_INFO structures appear in the buffer coincides with the order in which the protocol entries
/// were registered by the service provider using the WS2_32.DLL, or with any subsequent reordering that occurred through the
/// Windows Sockets application or DLL supplied for establishing default TCP/IP providers.
/// </para>
/// <para>
/// <c>Windows Phone 8:</c> The <c>WSAEnumProtocolsW</c> function is supported for Windows Phone Store apps on Windows Phone 8 and later.
/// </para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: The <c>WSAEnumProtocolsW</c> function is supported for Windows Store apps
/// on Windows 8.1, Windows Server 2012 R2, and later.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following example demonstrates the use of the <c>WSAEnumProtocols</c> function to retrieve an array of WSAPROTOCOL_INFO
/// structures for available transport protocols.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaenumprotocolsa int WSAAPI WSAEnumProtocolsA( LPINT
// lpiProtocols, LPWSAPROTOCOL_INFOA lpProtocolBuffer, LPDWORD lpdwBufferLength );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winsock2.h", MSDNShortId = "928b6937-41a3-4268-a3bc-14c9e04870e4")]
public static extern int WSAEnumProtocols([Optional, MarshalAs(UnmanagedType.LPArray)] int[] lpiProtocols, [Out] IntPtr lpProtocolBuffer, ref uint lpdwBufferLength);
/// <summary>
/// The <c>WSAEventSelect</c> function specifies an event object to be associated with the specified set of FD_XXX network events.
/// </summary>
/// <param name="s">A descriptor identifying the socket.</param>
/// <param name="hEventObject">
/// A handle identifying the event object to be associated with the specified set of FD_XXX network events.
/// </param>
/// <param name="lNetworkEvents">
/// A bitmask that specifies the combination of FD_XXX network events in which the application has interest.
/// </param>
/// <returns>
/// <para>
/// The return value is zero if the application's specification of the network events and the associated event object was
/// successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error number can be retrieved by calling WSAGetLastError.
/// </para>
/// <para>
/// As in the case of the select and WSAAsyncSelect functions, <c>WSAEventSelect</c> will frequently be used to determine when a
/// data transfer operation (send or recv) can be issued with the expectation of immediate success. Nevertheless, a robust
/// application must be prepared for the possibility that the event object is set and it issues a Windows Sockets call that returns
/// WSAEWOULDBLOCK immediately. For example, the following sequence of operations is possible:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Data arrives on socket s; Windows Sockets sets the <c>WSAEventSelect</c> event object.</term>
/// </item>
/// <item>
/// <term>The application does some other processing.</term>
/// </item>
/// <item>
/// <term>While processing, the application issues an ioctlsocket(s, FIONREAD...) and notices that there is data ready to be read.</term>
/// </item>
/// <item>
/// <term>The application issues a recv(s,...) to read the data.</term>
/// </item>
/// <item>
/// <term>
/// The application eventually waits on the event object specified in <c>WSAEventSelect</c>, which returns immediately indicating
/// that data is ready to read.
/// </term>
/// </item>
/// <item>
/// <term>The application issues recv(s,...), which fails with the error WSAEWOULDBLOCK.</term>
/// </item>
/// </list>
/// <para>
/// Having successfully recorded the occurrence of the network event (by setting the corresponding bit in the internal network event
/// record) and signaled the associated event object, no further actions are taken for that network event until the application
/// makes the function call that implicitly reenables the setting of that network event and signaling of the associated event object.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Network event</term>
/// <term>Re-enabling function</term>
/// </listheader>
/// <item>
/// <term>FD_READ</term>
/// <term>The recv, recvfrom, WSARecv, WSARecvEx, or WSARecvFrom function.</term>
/// </item>
/// <item>
/// <term>FD_WRITE</term>
/// <term>The send, sendto, WSASend, or WSASendTo function.</term>
/// </item>
/// <item>
/// <term>FD_OOB</term>
/// <term>The recv, recvfrom, WSARecv, WSARecvEx, or WSARecvFrom function.</term>
/// </item>
/// <item>
/// <term>FD_ACCEPT</term>
/// <term>
/// The accept, AcceptEx, or WSAAccept function unless the error code returned is WSATRY_AGAIN indicating that the condition
/// function returned CF_DEFER.
/// </term>
/// </item>
/// <item>
/// <term>FD_CONNECT</term>
/// <term>None.</term>
/// </item>
/// <item>
/// <term>FD_CLOSE</term>
/// <term>None.</term>
/// </item>
/// <item>
/// <term>FD_QOS</term>
/// <term>The WSAIoctl function with command SIO_GET_QOS.</term>
/// </item>
/// <item>
/// <term>FD_GROUP_QOS</term>
/// <term>Reserved.</term>
/// </item>
/// <item>
/// <term>FD_ROUTING_ INTERFACE_CHANGE</term>
/// <term>The WSAIoctl function with command SIO_ROUTING_INTERFACE_CHANGE.</term>
/// </item>
/// <item>
/// <term>FD_ADDRESS_ LIST_CHANGE</term>
/// <term>The WSAIoctl function with command SIO_ADDRESS_LIST_CHANGE.</term>
/// </item>
/// </list>
/// <para>
/// Any call to the reenabling routine, even one that fails, results in reenabling of recording and signaling for the relevant
/// network event and event object.
/// </para>
/// <para>
/// For FD_READ, FD_OOB, and FD_ACCEPT network events, network event recording and event object signaling are level-triggered. This
/// means that if the reenabling routine is called and the relevant network condition is still valid after the call, the network
/// event is recorded and the associated event object is set. This allows an application to be event-driven and not be concerned
/// with the amount of data that arrives at any one time. Consider the following sequence:
/// </para>
/// <list type="number">
/// <item>
/// <term>
/// The transport provider receives 100 bytes of data on socket s and causes WS2_32.DLL to record the FD_READ network event and set
/// the associated event object.
/// </term>
/// </item>
/// <item>
/// <term>The application issues recv(s, buffptr, 50, 0) to read 50 bytes.</term>
/// </item>
/// <item>
/// <term>
/// The transport provider causes WS2_32.DLL to record the FD_READ network event and sets the associated event object again since
/// there is still data to be read.
/// </term>
/// </item>
/// </list>
/// <para>
/// With these semantics, an application need not read all available data in response to an FD_READ network event—a single recv in
/// response to each FD_READ network event is appropriate.
/// </para>
/// <para>
/// The FD_QOS event is considered edge triggered. A message will be posted exactly once when a quality of service change occurs.
/// Further messages will not be forthcoming until either the provider detects a further change in quality of service or the
/// application renegotiates the quality of service for the socket.
/// </para>
/// <para>
/// The FD_ROUTING_INTERFACE_CHANGE and FD_ADDRESS_LIST_CHANGE events are considered edge triggered as well. A message will be
/// posted exactly once when a change occurs after the application has requested the notification by issuing WSAIoctl with
/// <c>SIO_ROUTING_INTERFACE_CHANGE</c> or <c>SIO_ADDRESS_LIST_CHANGE</c> correspondingly. Other messages will not be forthcoming
/// until the application reissues the IOCTL and another change is detected since the IOCTL has been issued.
/// </para>
/// <para>
/// If a network event has already happened when the application calls <c>WSAEventSelect</c> or when the reenabling function is
/// called, then a network event is recorded and the associated event object is set as appropriate. For example, consider the
/// following sequence:
/// </para>
/// <list type="number">
/// <item>
/// <term>An application calls listen.</term>
/// </item>
/// <item>
/// <term>A connect request is received but not yet accepted.</term>
/// </item>
/// <item>
/// <term>
/// The application calls <c>WSAEventSelect</c> specifying that it is interested in the FD_ACCEPT network event for the socket. Due
/// to the persistence of network events, Windows Sockets records the FD_ACCEPT network event and sets the associated event object immediately.
/// </term>
/// </item>
/// </list>
/// <para>
/// The FD_WRITE network event is handled slightly differently. An FD_WRITE network event is recorded when a socket is first
/// connected with a call to the connect, ConnectEx, WSAConnect, WSAConnectByList, or WSAConnectByName function or when a socket is
/// accepted with accept, AcceptEx, or WSAAccept function and then after a send fails with WSAEWOULDBLOCK and buffer space becomes
/// available. Therefore, an application can assume that sends are possible starting from the first FD_WRITE network event setting
/// and lasting until a send returns WSAEWOULDBLOCK. After such a failure the application will find out that sends are again
/// possible when an FD_WRITE network event is recorded and the associated event object is set.
/// </para>
/// <para>
/// The FD_OOB network event is used only when a socket is configured to receive OOB data separately. If the socket is configured to
/// receive OOB data inline, the OOB (expedited) data is treated as normal data and the application should register an interest in,
/// and will get FD_READ network event, not FD_OOB network event. An application can set or inspect the way in which OOB data is to
/// be handled by using setsockopt or getsockopt for the SO_OOBINLINE option.
/// </para>
/// <para>
/// The error code in an FD_CLOSE network event indicates whether the socket close was graceful or abortive. If the error code is
/// zero, then the close was graceful; if the error code is WSAECONNRESET, then the socket's virtual circuit was reset. This only
/// applies to connection-oriented sockets such as SOCK_STREAM.
/// </para>
/// <para>
/// The FD_CLOSE network event is recorded when a close indication is received for the virtual circuit corresponding to the socket.
/// In TCP terms, this means that the FD_CLOSE is recorded when the connection goes into the TIME WAIT or CLOSE WAIT states. This
/// results from the remote end performing a shutdown on the send side or a closesocket. FD_CLOSE being posted after all data is
/// read from a socket. An application should check for remaining data upon receipt of FD_CLOSE to avoid any possibility of losing
/// data. For more information, see the section on Graceful Shutdown, Linger Options, and Socket Closure and the <c>shutdown</c> function.
/// </para>
/// <para>
/// Note that Windows Sockets will record only an FD_CLOSE network event to indicate closure of a virtual circuit. It will not
/// record an FD_READ network event to indicate this condition.
/// </para>
/// <para>
/// The FD_QOS or FD_GROUP_QOS network event is recorded when any parameter in the flow specification associated with socket s.
/// Applications should use WSAIoctl with command <c>SIO_GET_QOS</c> to get the current quality of service for socket s.
/// </para>
/// <para>
/// The FD_ROUTING_INTERFACE_CHANGE network event is recorded when the local interface that should be used to reach the destination
/// specified in WSAIoctl with <c>SIO_ROUTING_INTERFACE_CHANGE</c> changes after such IOCTL has been issued.
/// </para>
/// <para>
/// The FD_ADDRESS_LIST_CHANGE network event is recorded when the list of addresses of protocol family for the socket to which the
/// application can bind changes after WSAIoctl with <c>SIO_ADDRESS_LIST_CHANGE</c> has been issued.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>One of the specified parameters was invalid, or the specified socket is in an invalid state.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAEventSelect</c> function is used to specify an event object, hEventObject, to be associated with the selected FD_XXX
/// network events, lNetworkEvents. The socket for which an event object is specified is identified by the s parameter. The event
/// object is set when any of the nominated network events occur.
/// </para>
/// <para>
/// The <c>WSAEventSelect</c> function operates very similarly to WSAAsyncSelect, the difference being the actions taken when a
/// nominated network event occurs. The <c>WSAAsyncSelect</c> function causes an application-specified Windows message to be posted.
/// The <c>WSAEventSelect</c> sets the associated event object and records the occurrence of this event in an internal network event
/// record. An application can use WSAWaitForMultipleEvents to wait or poll on the event object, and use WSAEnumNetworkEvents to
/// retrieve the contents of the internal network event record and thus determine which of the nominated network events have occurred.
/// </para>
/// <para>
/// The proper way to reset the state of an event object used with the <c>WSAEventSelect</c> function is to pass the handle of the
/// event object to the WSAEnumNetworkEvents function in the hEventObject parameter. This will reset the event object and adjust the
/// status of active FD events on the socket in an atomic fashion.
/// </para>
/// <para>
/// <c>WSAEventSelect</c> is the only function that causes network activity and errors to be recorded and retrievable through
/// WSAEnumNetworkEvents. See the descriptions of select and WSAAsyncSelect to find out how those functions report network activity
/// and errors.
/// </para>
/// <para>
/// The <c>WSAEventSelect</c> function automatically sets socket s to nonblocking mode, regardless of the value of lNetworkEvents.
/// To set socket s back to blocking mode, it is first necessary to clear the event record associated with socket s via a call to
/// <c>WSAEventSelect</c> with lNetworkEvents set to zero and the hEventObject parameter set to <c>NULL</c>. You can then call
/// ioctlsocket or WSAIoctl to set the socket back to blocking mode.
/// </para>
/// <para>
/// The lNetworkEvents parameter is constructed by using the bitwise OR operator with any of the values specified in the following list.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>FD_READ</term>
/// <term>Wants to receive notification of readiness for reading.</term>
/// </item>
/// <item>
/// <term>FD_WRITE</term>
/// <term>Wants to receive notification of readiness for writing.</term>
/// </item>
/// <item>
/// <term>FD_OOB</term>
/// <term>Wants to receive notification of the arrival of OOB data.</term>
/// </item>
/// <item>
/// <term>FD_ACCEPT</term>
/// <term>Wants to receive notification of incoming connections.</term>
/// </item>
/// <item>
/// <term>FD_CONNECT</term>
/// <term>Wants to receive notification of completed connection or multipoint join operation.</term>
/// </item>
/// <item>
/// <term>FD_CLOSE</term>
/// <term>Wants to receive notification of socket closure.</term>
/// </item>
/// <item>
/// <term>FD_QOS</term>
/// <term>Wants to receive notification of socket (QoS changes.</term>
/// </item>
/// <item>
/// <term>FD_GROUP_QOS</term>
/// <term>Reserved for future use with socket groups. Want to receive notification of socket group QoS changes.</term>
/// </item>
/// <item>
/// <term>FD_ROUTING_ INTERFACE_CHANGE</term>
/// <term>Wants to receive notification of routing interface changes for the specified destination.</term>
/// </item>
/// <item>
/// <term>FD_ADDRESS_ LIST_CHANGE</term>
/// <term>Wants to receive notification of local address list changes for the address family of the socket.</term>
/// </item>
/// </list>
/// <para>
/// Issuing a <c>WSAEventSelect</c> for a socket cancels any previous WSAAsyncSelect or <c>WSAEventSelect</c> for the same socket
/// and clears the internal network event record. For example, to associate an event object with both reading and writing network
/// events, the application must call <c>WSAEventSelect</c> with both FD_READ and FD_WRITE, as follows:
/// </para>
/// <para>
/// It is not possible to specify different event objects for different network events. The following code will not work; the second
/// call will cancel the effects of the first, and only the FD_WRITE network event will be associated with hEventObject2:
/// </para>
/// <para>
/// To cancel the association and selection of network events on a socket, lNetworkEvents should be set to zero, in which case the
/// hEventObject parameter will be ignored.
/// </para>
/// <para>
/// Closing a socket with closesocket also cancels the association and selection of network events specified in
/// <c>WSAEventSelect</c> for the socket. The application, however, still must call WSACloseEvent to explicitly close the event
/// object and free any resources.
/// </para>
/// <para>
/// The socket created when the accept function is called has the same properties as the listening socket used to accept it. Any
/// <c>WSAEventSelect</c> association and network events selection set for the listening socket apply to the accepted socket. For
/// example, if a listening socket has <c>WSAEventSelect</c> association of hEventObject with FD_ACCEPT, FD_READ, and FD_WRITE, then
/// any socket accepted on that listening socket will also have FD_ACCEPT, FD_READ, and FD_WRITE network events associated with the
/// same hEventObject. If a different hEventObject or network events are desired, the application should call <c>WSAEventSelect</c>,
/// passing the accepted socket and the desired new information.
/// </para>
/// <para>Example Code</para>
/// <para>The following example demonstrates the use of the <c>WSAEventSelect</c> function.</para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaeventselect int WSAAPI WSAEventSelect( SOCKET s,
// WSAEVENT hEventObject, long lNetworkEvents );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "f98a71e4-47fb-47a4-b37e-e4cc801a8f98")]
public static extern WSRESULT WSAEventSelect(SOCKET s, WSAEVENT hEventObject, FD lNetworkEvents);
/// <summary>The <c>WSAGetLastError</c> function returns the error status for the last Windows Sockets operation that failed.</summary>
/// <returns>The return value indicates the error code for this thread's last Windows Sockets operation that failed.</returns>
/// <remarks>
/// <para>
/// The <c>WSAGetLastError</c> function returns the last error that occurred for the calling thread. When a particular Windows
/// Sockets function indicates an error has occurred, this function should be called immediately to retrieve the extended error code
/// for the failing function call. This extended error code can be different from the error code obtained from getsockopt when
/// called with an optname parameter of <c>SO_ERROR</c>, which is socket-specific since <c>WSAGetLastError</c> is for all
/// thread-specific sockets.
/// </para>
/// <para>
/// If a function call's return value indicates that error or other relevant data was returned in the error code,
/// <c>WSAGetLastError</c> should be called immediately. This is necessary because some functions may reset the last extended error
/// code to 0 if they succeed, overwriting the extended error code returned by a previously failed function. To specifically reset
/// the extended error code, use the WSASetLastError function call with the iError parameter set to zero. A getsockopt function when
/// called with an optname parameter of <c>SO_ERROR</c> also resets the extended error code to zero.
/// </para>
/// <para>
/// The <c>WSAGetLastError</c> function should not be used to check for an extended error value on receipt of an asynchronous
/// message. In this case, the extended error value is passed in the lParam parameter of the message, and this can differ from the
/// value returned by <c>WSAGetLastError</c>.
/// </para>
/// <para>
/// <c>Note</c> An application can call the <c>WSAGetLastError</c> function to determine the extended error code for other Windows
/// sockets functions as is normally done in Windows Sockets even if the WSAStartup function fails or the <c>WSAStartup</c> function
/// was not called to properly initialize Windows Sockets before calling a Windows Sockets function. The <c>WSAGetLastError</c>
/// function is one of the only functions in the Winsock 2.2 DLL that can be called in the case of a <c>WSAStartup</c> failure.
/// </para>
/// <para>
/// The Windows Sockets extended error codes returned by this function and the text description of the error are listed under
/// Windows Sockets Error Codes. These error codes and a short text description associated with an error code are defined in the
/// Winerror.h header file. The FormatMessage function can be used to obtain the message string for the returned error.
/// </para>
/// <para>
/// For information on how to handle error codes when porting socket applications to Winsock, see Error Codes - errno, h_errno and WSAGetLastError.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winsock/nf-winsock-wsagetlasterror int WSAGetLastError( );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock.h", MSDNShortId = "39e41b66-44ed-46dc-bfc2-65228b669992")]
public static extern WSRESULT WSAGetLastError();
/// <summary>The <c>WSAGetOverlappedResult</c> function retrieves the results of an overlapped operation on the specified socket.</summary>
/// <param name="s">
/// <para>A descriptor identifying the socket.</para>
/// <para>
/// This is the same socket that was specified when the overlapped operation was started by a call to any of the Winsock functions
/// that supports overlappped operations. These functions include AcceptEx, ConnectEx, DisconnectEx, TransmitFile, TransmitPackets,
/// WSARecv, WSARecvFrom, WSARecvMsg, WSASend, WSASendMsg, WSASendTo, and WSAIoctl.
/// </para>
/// </param>
/// <param name="lpOverlapped">
/// A pointer to a WSAOVERLAPPED structure that was specified when the overlapped operation was started. This parameter must not be
/// a <c>NULL</c> pointer.
/// </param>
/// <param name="lpcbTransfer">
/// A pointer to a 32-bit variable that receives the number of bytes that were actually transferred by a send or receive operation,
/// or by the WSAIoctl function. This parameter must not be a <c>NULL</c> pointer.
/// </param>
/// <param name="fWait">
/// A flag that specifies whether the function should wait for the pending overlapped operation to complete. If <c>TRUE</c>, the
/// function does not return until the operation has been completed. If <c>FALSE</c> and the operation is still pending, the
/// function returns <c>FALSE</c> and the WSAGetLastError function returns WSA_IO_INCOMPLETE. The fWait parameter may be set to
/// <c>TRUE</c> only if the overlapped operation selected the event-based completion notification.
/// </param>
/// <param name="lpdwFlags">
/// A pointer to a 32-bit variable that will receive one or more flags that supplement the completion status. If the overlapped
/// operation was initiated through WSARecv or WSARecvFrom, this parameter will contain the results value for lpFlags parameter.
/// This parameter must not be a <c>NULL</c> pointer.
/// </param>
/// <returns>
/// <para>
/// If <c>WSAGetOverlappedResult</c> succeeds, the return value is <c>TRUE</c>. This means that the overlapped operation has
/// completed successfully and that the value pointed to by lpcbTransfer has been updated.
/// </para>
/// <para>
/// If <c>WSAGetOverlappedResult</c> returns <c>FALSE</c>, this means that either the overlapped operation has not completed, the
/// overlapped operation completed but with errors, or the overlapped operation's completion status could not be determined due to
/// errors in one or more parameters to <c>WSAGetOverlappedResult</c>. On failure, the value pointed to by lpcbTransfer will not be
/// updated. Use WSAGetLastError to determine the cause of the failure (either by the <c>WSAGetOverlappedResult</c> function or by
/// the associated overlapped operation).
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSA_INVALID_HANDLE</term>
/// <term>The hEvent parameter of the WSAOVERLAPPED structure does not contain a valid event object handle.</term>
/// </item>
/// <item>
/// <term>WSA_INVALID_PARAMETER</term>
/// <term>One of the parameters is unacceptable.</term>
/// </item>
/// <item>
/// <term>WSA_IO_INCOMPLETE</term>
/// <term>The fWait parameter is FALSE and the I/O operation has not yet completed.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// One or more of the lpOverlapped, lpcbTransfer, or lpdwFlags parameters are not in a valid part of the user address space. This
/// error is returned if the lpOverlapped, lpcbTransfer, or lpdwFlags parameter was a NULL pointer on Windows Server 2003 and earlier.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAGetOverlappedResult</c> function reports the results of the overlapped operation specified in the lpOverlapped
/// parameter for the socket specified in the s parameter. The <c>WSAGetOverlappedResult</c> function is passed the socket
/// descriptor and the WSAOVERLAPPED structure that was specified when the overlapped function was called. A pending operation is
/// indicated when the function that started the operation returns <c>FALSE</c> and the WSAGetLastError function returns
/// WSA_IO_PENDING. When an I/O operation such as WSARecv is pending, the function that started the operation resets the hEvent
/// member of the <c>WSAOVERLAPPED</c> structure to the nonsignaled state. Then, when the pending operation has completed, the
/// system sets the event object to the signaled state.
/// </para>
/// <para>
/// If the fWait parameter is <c>TRUE</c>, <c>WSAGetOverlappedResult</c> determines whether the pending operation has been completed
/// by waiting for the event object to be in the signaled state. A client may set the fWait parameter to <c>TRUE</c>, but only if it
/// selected event-based completion notification when the I/O operation was requested. If another form of notification was selected,
/// the usage of the hEvent parameter of the WSAOVERLAPPED structure is different, and setting fWait to <c>TRUE</c> causes
/// unpredictable results.
/// </para>
/// <para>
/// If the <c>WSAGetOverlappedResult</c> function is called with the lpOverlapped, lpcbTransfer, or lpdwFlags parameter set to a
/// <c>NULL</c> pointer on Windows Vista, this will result in an access violation. If the <c>WSAGetOverlappedResult</c> function is
/// called with the lpOverlapped, lpcbTransfer, or lpdwFlags parameter set to a <c>NULL</c> pointer on Windows Server 2003 and
/// earlier, this will result in the WSAEFAULT error code being returned.
/// </para>
/// <para>
/// <c>Note</c> All I/O is canceled when a thread exits. For overlapped sockets, pending asynchronous operations can fail if the
/// thread is closed before the operations complete. See ExitThread for more information.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsagetoverlappedresult BOOL WSAAPI
// WSAGetOverlappedResult( SOCKET s, LPWSAOVERLAPPED lpOverlapped, LPDWORD lpcbTransfer, BOOL fWait, LPDWORD lpdwFlags );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "3c43ccfd-0fe7-4ecc-9517-e0a1c448f7e4")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WSAGetOverlappedResult(SOCKET s, in WSAOVERLAPPED lpOverlapped, out uint lpcbTransfer, [MarshalAs(UnmanagedType.Bool)] bool fWait, out uint lpdwFlags);
/// <summary>
/// The <c>WSAGetQOSByName</c> function initializes a QOS structure based on a named template, or it supplies a buffer to retrieve
/// an enumeration of the available template names.
/// </summary>
/// <param name="s">A descriptor identifying a socket.</param>
/// <param name="lpQOSName">A pointer to a specific quality of service template.</param>
/// <param name="lpQOS">A pointer to the QOS structure to be filled.</param>
/// <returns>
/// <para>
/// If <c>WSAGetQOSByName</c> succeeds, the return value is <c>TRUE</c>. If the function fails, the return value is <c>FALSE</c>. To
/// get extended error information, call WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The lpQOSName or lpQOS parameter are not a valid part of the user address space, or the buffer length for lpQOS is too small.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAGetQOSByName</c> function is used by applications to initialize a QOS structure to a set of known values appropriate
/// for a particular service class or media type. These values are stored in a template that is referenced by a well-known name. The
/// client may retrieve these values by setting the buf parameter of the WSABUF structure indicated by lpQOSName, which points to a
/// string of nonzero length specifying a template name. In this case, the usage of lpQOSName is IN only, and results are returned
/// through lpQOS.
/// </para>
/// <para>
/// Alternatively, the client may use this function to retrieve an enumeration of available template names. The client may do this
/// by setting the buf parameter of the WSABUF indicated by lpQOSName to a zero-length null-terminated string. In this case the
/// buffer indicated by buf is overwritten with a sequence of as many available, null-terminated template names up to the number of
/// bytes available in buf as indicated by the len parameter of the <c>WSABUF</c> indicated by lpQOSName. The list of names itself
/// is terminated by a zero-length name. When the <c>WSAGetQOSByName</c> function is used to retrieve template names, the lpQOS
/// parameter is ignored.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsagetqosbyname BOOL WSAAPI WSAGetQOSByName( SOCKET s,
// LPWSABUF lpQOSName, LPQOS lpQOS );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "9b586856-5441-414b-8b91-298c952c351b")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WSAGetQOSByName(SOCKET s, in WSABUF lpQOSName, out QOS lpQOS);
/// <summary>
/// The <c>WSAGetServiceClassInfo</c> function retrieves the class information (schema) pertaining to a specified service class from
/// a specified namespace provider.
/// </summary>
/// <param name="lpProviderId">A pointer to a GUID that identifies a specific namespace provider.</param>
/// <param name="lpServiceClassId">A pointer to a GUID identifying the service class.</param>
/// <param name="lpdwBufSize">
/// <para>On input, the number of bytes contained in the buffer pointed to by the lpServiceClassInfo parameter.</para>
/// <para>
/// On output, if the function fails and the error is WSAEFAULT, this parameter specifies the minimum size, in bytes, of the buffer
/// pointed to lpServiceClassInfo needed to retrieve the record.
/// </para>
/// </param>
/// <param name="lpServiceClassInfo">
/// A pointer to a WSASERVICECLASSINFO structure that contains the service class information from the indicated namespace provider
/// for the specified service class.
/// </param>
/// <returns>
/// <para>
/// The return value is zero if the <c>WSAGetServiceClassInfo</c> was successful. Otherwise, the value SOCKET_ERROR is returned, and
/// a specific error number can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSA_NOT_ENOUGH_MEMORY</term>
/// <term>There was insufficient memory to perform the operation.</term>
/// </item>
/// <item>
/// <term>WSAEACCES</term>
/// <term>The calling routine does not have sufficient privileges to access the information.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The buffer pointed to by the lpServiceClassInfo parameter is too small to contain a WSASERVICECLASSINFOW. The application needs
/// to pass in a larger buffer.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>
/// The specified service class identifier or namespace provider identifier is not valid. This error is returned if the
/// lpProviderId, lpServiceClassId, lpdwBufSize, or lpServiceClassInfo parameters are NULL.
/// </term>
/// </item>
/// <item>
/// <term>WSAEOPNOTSUPP</term>
/// <term>
/// The operation is not supported for the type of object referenced. This error is returned by some namespace providers that do not
/// support getting service class information.
/// </term>
/// </item>
/// <item>
/// <term>WSANO_DATA</term>
/// <term>The requested name is valid, but no data of the requested type was found.</term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>
/// The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
/// </term>
/// </item>
/// <item>
/// <term>WSATYPE_NOT_FOUND</term>
/// <term>The specified class was not found.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// The <c>WSAGetServiceClassInfo</c> function retrieves service class information from a namespace provider. The service class
/// information retrieved from a particular namespace provider might not be the complete set of class information that was specified
/// when the service class was installed. Individual namespace providers are only required to retain service class information that
/// is applicable to the namespaces that they support. See the section Service Class Data Structures for more information.
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsagetserviceclassinfow INT WSAAPI
// WSAGetServiceClassInfoW( LPGUID lpProviderId, LPGUID lpServiceClassId, LPDWORD lpdwBufSize, LPWSASERVICECLASSINFOW
// lpServiceClassInfo );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winsock2.h", MSDNShortId = "e177bb7d-c7d3-43a4-a809-ab8212feea2e")]
public static extern WSRESULT WSAGetServiceClassInfo(in Guid lpProviderId, in Guid lpServiceClassId, ref uint lpdwBufSize, IntPtr lpServiceClassInfo);
/// <summary>
/// The <c>WSAGetServiceClassNameByClassId</c> function retrieves the name of the service associated with the specified type. This
/// name is the generic service name, like FTP or SNA, and not the name of a specific instance of that service.
/// </summary>
/// <param name="lpServiceClassId">A pointer to the GUID for the service class.</param>
/// <param name="lpszServiceClassName">A pointer to the service name.</param>
/// <param name="lpdwBufferLength">
/// On input, the length of the buffer returned by lpszServiceClassName, in characters. On output, the length of the service name
/// copied into lpszServiceClassName, in characters.
/// </param>
/// <returns>
/// <para>
/// The <c>WSAGetServiceClassNameByClassId</c> function returns a value of zero if successful. Otherwise, the value SOCKET_ERROR is
/// returned, and a specific error number can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSA_INVALID_PARAMETER</term>
/// <term>The lpServiceClassId parameter specified is invalid.</term>
/// </item>
/// <item>
/// <term>WSA_NOT_ENOUGH_MEMORY</term>
/// <term>There was insufficient memory to perform the operation.</term>
/// </item>
/// <item>
/// <term>WSAEACCES</term>
/// <term>The calling routine does not have sufficient privileges to access the information.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The specified buffer pointed to by lpszServiceClassName is too small. Pass in a larger buffer.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>No buffer space available.</term>
/// </item>
/// <item>
/// <term>WSAEOPNOTSUPP</term>
/// <term>
/// The operation is not supported for the type of object referenced. This error is returned by some namespace providers that do not
/// support getting service class information.
/// </term>
/// </item>
/// <item>
/// <term>WSANO_DATA</term>
/// <term>The lpServiceClassId is valid, but no data of the requested type was found.</term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>
/// The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
/// </term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsagetserviceclassnamebyclassida INT WSAAPI
// WSAGetServiceClassNameByClassIdA( LPGUID lpServiceClassId, LPSTR lpszServiceClassName, LPDWORD lpdwBufferLength );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winsock2.h", MSDNShortId = "0a61751e-10e5-4f91-a0b2-8c1baf477653")]
public static extern WSRESULT WSAGetServiceClassNameByClassId(in Guid lpServiceClassId, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpszServiceClassName, ref uint lpdwBufferLength);
/// <summary>The <c>WSAHtonl</c> function converts a <c>u_long</c> from host byte order to network byte order.</summary>
/// <param name="s">A descriptor identifying a socket.</param>
/// <param name="hostlong">A 32-bit number in host byte order.</param>
/// <param name="lpnetlong">A pointer to a 32-bit number to receive the number in network byte order.</param>
/// <returns>
/// <para>
/// If no error occurs, <c>WSAHtonl</c> returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can
/// be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The lpnetlong parameter is NULL or the address pointed to is not completely contained in a valid part of the user address space.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAHtonl</c> function takes a 32-bit number in host byte order and returns a 32-bit number in network byte order in the
/// 32-bit number pointed to by the lpnetlong parameter. The socket passed in the s parameter is used to determine the network byte
/// order required based on the Winsock catalog protocol entry associated with the socket. This feature supports Winsock providers
/// that use different network byte orders.
/// </para>
/// <para>
/// If the socket is for the AF_INET or AF_INET6 address family, the <c>WSAHtonl</c> function can be used to convert an IPv4 address
/// in host byte order to the IPv4 address in network byte order. This function does not do any checking to determine if the
/// hostlong parameter is a valid IPv4 address.
/// </para>
/// <para>
/// The <c>WSAHtonl</c> function requires that the Winsock DLL has previously been loaded with a successful call to the WSAStartup
/// function. For use with the AF_INET or AF_INET6 family, the htonlfunction does not require that the Winsock DLL be loaded.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsahtonl int WSAAPI WSAHtonl( IN SOCKET s, IN u_long
// hostlong, OUT u_long *lpnetlong );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "33512f49-d576-4439-ad8d-5c87387d6214")]
public static extern WSRESULT WSAHtonl([In] SOCKET s, [In] uint hostlong, out uint lpnetlong);
/// <summary>The <c>WSAHtons</c> function converts a <c>u_short</c> from host byte order to network byte order.</summary>
/// <param name="s">A descriptor identifying a socket.</param>
/// <param name="hostshort">A 16-bit number in host byte order.</param>
/// <param name="lpnetshort">A pointer to a 16-bit buffer to receive the number in network byte order.</param>
/// <returns>
/// <para>
/// If no error occurs, <c>WSAHtons</c> returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can
/// be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The lpnetshort parameter is NULL or the address pointed to is not completely contained in a valid part of the user address space.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAHtons</c> function takes a 16-bit number in host byte order and returns a 16-bit number in network byte order in the
/// 16-bit number pointed to by the lpnetshort parameter. The socket passed in the s parameter is used to determine the network byte
/// order required based on the Winsock catalog protocol entry associated with the socket. This feature supports Winsock providers
/// that use different network byte orders.
/// </para>
/// <para>
/// If the socket is for the AF_INET or AF_INET6 address family, the <c>WSAHtons</c> function can be used to convert an IP port
/// number in host byte order to the IP port number in network byte order.
/// </para>
/// <para>
/// The <c>WSAHtons</c> function requires that the Winsock DLL has previously been loaded with a successful call to the WSAStartup
/// function. For use with the AF_INET OR AF_INET6 address family, the htonsfunction does not require that the Winsock DLL be loaded.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsahtons int WSAAPI WSAHtons( IN SOCKET s, IN u_short
// hostshort, OUT u_short *lpnetshort );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "95fb103b-f7dd-4fa4-bf68-ed8e87cdd96b")]
public static extern WSRESULT WSAHtons([In] SOCKET s, [In] ushort hostshort, out ushort lpnetshort);
/// <summary>
/// The <c>WSAInstallServiceClass</c> function registers a service class schema within a namespace. This schema includes the class
/// name, class identifier, and any namespace-specific information that is common to all instances of the service, such as the SAP
/// identifier or object identifier.
/// </summary>
/// <param name="lpServiceClassInfo">
/// <para>Service class to namespace specifictype mapping information. Multiple mappings can be handled at one time.</para>
/// <para>See the section Service Class Data Structures for a description of pertinent data structures.</para>
/// </param>
/// <returns>
/// <para>
/// The return value is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error
/// number can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSA_INVALID_PARAMETER</term>
/// <term>The namespace provider cannot supply the requested class information.</term>
/// </item>
/// <item>
/// <term>WSA_NOT_ENOUGH_MEMORY</term>
/// <term>There was insufficient memory to perform the operation.</term>
/// </item>
/// <item>
/// <term>WSAEACCES</term>
/// <term>The calling function does not have sufficient privileges to install the service.</term>
/// </item>
/// <item>
/// <term>WSAEALREADY</term>
/// <term>
/// Service class information has already been registered for this service class identifier. To modify service class information,
/// first use WSARemoveServiceClass, and then reinstall with updated class information data.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>
/// The service class information was not valid or improperly structured. This error is returned if the lpServiceClassInfo parameter
/// is NULL.
/// </term>
/// </item>
/// <item>
/// <term>WSAEOPNOTSUPP</term>
/// <term>The operation is not supported. This error is returned if the namespace provider does not implement this function.</term>
/// </item>
/// <item>
/// <term>WSANO_DATA</term>
/// <term>The requested name is valid, but no data of the requested type was found.</term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>
/// The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
/// </term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsainstallserviceclassa INT WSAAPI
// WSAInstallServiceClassA( LPWSASERVICECLASSINFOA lpServiceClassInfo );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winsock2.h", MSDNShortId = "06760319-aeeb-4ad7-b77a-01efea7ed904")]
public static extern WSRESULT WSAInstallServiceClass(in WSASERVICECLASSINFO lpServiceClassInfo);
/// <summary>The <c>WSAIoctl</c> function controls the mode of a socket.</summary>
/// <param name="s">A descriptor identifying a socket.</param>
/// <param name="dwIoControlCode">The control code of operation to perform.</param>
/// <param name="lpvInBuffer">A pointer to the input buffer.</param>
/// <param name="cbInBuffer">The size, in bytes, of the input buffer.</param>
/// <param name="lpvOutBuffer">A pointer to the output buffer.</param>
/// <param name="cbOutBuffer">The size, in bytes, of the output buffer.</param>
/// <param name="lpcbBytesReturned">A pointer to actual number of bytes of output.</param>
/// <param name="lpOverlapped">A pointer to a WSAOVERLAPPED structure (ignored for non-overlapped sockets).</param>
/// <param name="lpCompletionRoutine">
/// <c>Note</c> A pointer to the completion routine called when the operation has been completed (ignored for non-overlapped
/// sockets). See Remarks.
/// </param>
/// <returns>
/// <para>
/// Upon successful completion, the <c>WSAIoctl</c> returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific
/// error code can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSA_IO_PENDING</term>
/// <term>An overlapped operation was successfully initiated and completion will be indicated at a later time.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The lpvInBuffer, lpvOutBuffer, lpcbBytesReturned, lpOverlapped, or lpCompletionRoutine parameter is not totally contained in a
/// valid part of the user address space, or the cbInBuffer or cbOutBuffer parameter is too small.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>
/// The dwIoControlCode parameter is not a valid command, or a specified input parameter is not acceptable, or the command is not
/// applicable to the type of socket specified.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>The function is invoked when a callback is in progress.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor s is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEOPNOTSUPP</term>
/// <term>
/// The specified IOCTL command cannot be realized. (For example, the FLOWSPEC structures specified in SIO_SET_QOS or
/// SIO_SET_GROUP_QOS cannot be satisfied.)
/// </term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>The socket is marked as non-blocking and the requested operation would block.</term>
/// </item>
/// <item>
/// <term>WSAENOPROTOOPT</term>
/// <term>
/// The socket option is not supported on the specified protocol. For example, an attempt to use the SIO_GET_BROADCAST_ADDRESS IOCTL
/// was made on an IPv6 socket or an attempt to use the TCP SIO_KEEPALIVE_VALS IOCTL was made on a datagram socket.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAIoctl</c> function is used to set or retrieve operating parameters associated with the socket, the transport protocol,
/// or the communications subsystem.
/// </para>
/// <para>
/// If both lpOverlapped and lpCompletionRoutine are <c>NULL</c>, the socket in this function will be treated as a non-overlapped
/// socket. For a non-overlapped socket, lpOverlapped and lpCompletionRoutine parameters are ignored, which causes the function to
/// behave like the standard ioctlsocket function except that the function can block if socket s is in blocking mode. If socket s is
/// in non-blocking mode, this function can return WSAEWOULDBLOCK when the specified operation cannot be finished immediately. In
/// this case, the application may change the socket to blocking mode and reissue the request or wait for the corresponding network
/// event (such as FD_ROUTING_INTERFACE_CHANGE or FD_ADDRESS_LIST_CHANGE in the case of <c>SIO_ROUTING_INTERFACE_CHANGE</c> or
/// <c>SIO_ADDRESS_LIST_CHANGE</c>) using a Windows message (using WSAAsyncSelect)-based or event (using WSAEventSelect)-based
/// notification mechanism.
/// </para>
/// <para>
/// For overlapped sockets, operations that cannot be completed immediately will be initiated, and completion will be indicated at a
/// later time. The <c>DWORD</c> value pointed to by the lpcbBytesReturned parameter that is returned may be ignored. The final
/// completion status and bytes returned can be retrieved when the appropriate completion method is signaled when the operation has completed.
/// </para>
/// <para>
/// Any IOCTL may block indefinitely, depending on the service provider's implementation. If the application cannot tolerate
/// blocking in a <c>WSAIoctl</c> call, overlapped I/O would be advised for IOCTLs that are especially likely to block including:
/// </para>
/// <para><c>SIO_ADDRESS_LIST_CHANGE</c></para>
/// <para><c>SIO_FINDROUTE</c></para>
/// <para><c>SIO_FLUSH</c></para>
/// <para><c>SIO_GET_QOS</c></para>
/// <para><c>SIO_GET_GROUP_QOS</c></para>
/// <para><c>SIO_ROUTING_INTERFACE_CHANGE</c></para>
/// <para><c>SIO_SET_QOS</c></para>
/// <para><c>SIO_SET_GROUP_QOS</c></para>
/// <para>
/// Some protocol-specific IOCTLs may also be especially likely to block. Check the relevant protocol-specific annex for any
/// available information.
/// </para>
/// <para>The prototype for the completion routine pointed to by the lpCompletionRoutine parameter is as follows:</para>
/// <para>
/// The CompletionRoutine is a placeholder for an application-supplied function name. The dwError parameter specifies the completion
/// status for the overlapped operation as indicated by lpOverlapped parameter. The cbTransferred parameter specifies the number of
/// bytes received. The dwFlags parameter is not used for this IOCTL. The completion routine does not return a value.
/// </para>
/// <para>
/// It is possible to adopt an encoding scheme that preserves the currently defined ioctlsocket opcodes while providing a convenient
/// way to partition the opcode identifier space in as much as the dwIoControlCode parameter is now a 32-bit entity. The
/// dwIoControlCode parameter is built to allow for protocol and vendor independence when adding new control codes while retaining
/// backward compatibility with the Windows Sockets 1.1 and Unix control codes. The dwIoControlCode parameter has the following form.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>I</term>
/// <term>O</term>
/// <term>V</term>
/// <term>T</term>
/// <term>Vendor/address family</term>
/// <term>Code</term>
/// </listheader>
/// <item>
/// <term>3</term>
/// <term>3</term>
/// <term>2</term>
/// <term>2 2</term>
/// <term>2 2 2 2 2 2 2 1 1 1 1</term>
/// <term>1 1 1 1 1 1</term>
/// </item>
/// <item>
/// <term>1</term>
/// <term>0</term>
/// <term>9</term>
/// <term>8 7</term>
/// <term>6 5 4 3 2 1 0 9 8 7 6</term>
/// <term>5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0</term>
/// </item>
/// </list>
/// <para>
/// <c>Note</c> The bits in dwIoControlCode parameter displayed in the table must be read vertically from top to bottom by column.
/// So the left-most bit is bit 31, the next bit is bit 30, and the right-most bit is bit 0.
/// </para>
/// <para>I is set if the input buffer is valid for the code, as with <c>IOC_IN</c>.</para>
/// <para>
/// O is set if the output buffer is valid for the code, as with <c>IOC_OUT</c>. Control codes using both input and output buffers
/// set both I and O.
/// </para>
/// <para>V is set if there are no parameters for the code, as with <c>IOC_VOID</c>.</para>
/// <para>T is a 2-bit quantity that defines the type of the IOCTL. The following values are defined:</para>
/// <para>0 The IOCTL is a standard Unix IOCTL code, as with <c>FIONREAD</c> and <c>FIONBIO</c>.</para>
/// <para>1 The IOCTL is a generic Windows Sockets 2 IOCTL code. New IOCTL codes defined for Windows Sockets 2 will have T == 1.</para>
/// <para>2 The IOCTL applies only to a specific address family.</para>
/// <para>
/// 3 The IOCTL applies only to a specific vendor's provider, as with <c>IOC_VENDOR</c>. This type allows companies to be assigned a
/// vendor number that appears in the <c>Vendor/Address family</c> parameter. Then, the vendor can define new IOCTLs specific to
/// that vendor without having to register the IOCTL with a clearinghouse, thereby providing vendor flexibility and privacy.
/// </para>
/// <para>
/// <c>Vendor/Address family</c> An 11-bit quantity that defines the vendor who owns the code (if T == 3) or that contains the
/// address family to which the code applies (if T == 2). If this is a Unix IOCTL code (T == 0) then this parameter has the same
/// value as the code on Unix. If this is a generic Windows Sockets 2 IOCTL (T == 1) then this parameter can be used as an extension
/// of the code parameter to provide additional code values.
/// </para>
/// <para><c>Code</c> The 16-bit quantity that contains the specific IOCTL code for the operation.</para>
/// <para>The following Unix IOCTL codes (commands) are supported.</para>
/// <para>The following Windows Sockets 2 commands are supported.</para>
/// <para>
/// If an overlapped operation completes immediately, <c>WSAIoctl</c> returns a value of zero and the lpcbBytesReturned parameter is
/// updated with the number of bytes in the output buffer. If the overlapped operation is successfully initiated and will complete
/// later, this function returns SOCKET_ERROR and indicates error code WSA_IO_PENDING. In this case, lpcbBytesReturned is not
/// updated. When the overlapped operation completes the amount of data in the output buffer is indicated either through the
/// cbTransferred parameter in the completion routine (if specified), or through the lpcbTransfer parameter in WSAGetOverlappedResult.
/// </para>
/// <para>
/// When called with an overlapped socket, the lpOverlapped parameter must be valid for the duration of the overlapped operation.
/// The lpOverlapped parameter contains the address of a WSAOVERLAPPED structure.
/// </para>
/// <para>
/// If the lpCompletionRoutine parameter is <c>NULL</c>, 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.
/// </para>
/// <para>
/// <c>Note</c> 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.
/// </para>
/// <para>
/// If lpCompletionRoutine is not <c>NULL</c>, 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- <c>NULL</c> lpCompletionRoutine and later calls
/// WSAGetOverlappedResult for the same overlapped I/O request may not set the fWait parameter for that invocation of
/// <c>WSAGetOverlappedResult</c> to <c>TRUE</c>. In this case, the usage of the hEvent parameter is undefined, and attempting to
/// wait on the hEvent parameter would produce unpredictable results.
/// </para>
/// <para>The prototype of the completion routine is as follows:</para>
/// <para>
/// This <c>CompletionRoutine</c> is a placeholder for an application-defined or library-defined function. The completion routine is
/// invoked only if the thread is in an alertable state. To put a thread into an alertable state, use the WSAWaitForMultipleEvents,
/// WaitForSingleObjectEx, or WaitForMultipleObjectsEx function with the fAlertable or bAlertable parameter set to <c>TRUE</c>.
/// </para>
/// <para>
/// The dwError parameter of <c>CompletionRoutine</c> specifies the completion status for the overlapped operation as indicated by
/// lpOverlapped. The cbTransferred parameter specifies the number of bytes returned. Currently, no flag values are defined and
/// dwFlags will be zero. The <c>CompletionRoutine</c> function does not return a value.
/// </para>
/// <para>
/// Returning from this function allows invocation of another pending completion routine for this socket. The completion routines
/// can be called in any order, not necessarily in the same order the overlapped operations are completed.
/// </para>
/// <para>Compatibility</para>
/// <para>
/// The IOCTL codes with T == 0 are a subset of the IOCTL codes used in Berkeley sockets. In particular, there is no command that is
/// equivalent to <c>FIOASYNC</c>.
/// </para>
/// <para>
/// <c>Note</c> Some IOCTL codes require additional header files. For example, use of the <c>SIO_RCVALL</c> IOCTL requires the
/// Mstcpip.h header file.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winsock2/nf-winsock2-wsaioctl int WSAAPI WSAIoctl( SOCKET s, DWORD
// dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned,
// LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "038aeca6-d7b7-4f74-ac69-4536c2e5118b")]
public static extern WSRESULT WSAIoctl(SOCKET s, uint dwIoControlCode, [In] IntPtr lpvInBuffer, uint cbInBuffer, [Out] IntPtr lpvOutBuffer,
uint cbOutBuffer, out uint lpcbBytesReturned, [Optional] IntPtr lpOverlapped,
[Optional, MarshalAs(UnmanagedType.FunctionPtr)] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
/// <summary>The <c>WSAIoctl</c> function controls the mode of a socket.</summary>
/// <param name="s">A descriptor identifying a socket.</param>
/// <param name="dwIoControlCode">The control code of operation to perform.</param>
/// <param name="lpvInBuffer">A pointer to the input buffer.</param>
/// <param name="cbInBuffer">The size, in bytes, of the input buffer.</param>
/// <param name="lpvOutBuffer">A pointer to the output buffer.</param>
/// <param name="cbOutBuffer">The size, in bytes, of the output buffer.</param>
/// <param name="lpcbBytesReturned">A pointer to actual number of bytes of output.</param>
/// <param name="lpOverlapped">A pointer to a WSAOVERLAPPED structure (ignored for non-overlapped sockets).</param>
/// <param name="lpCompletionRoutine">
/// <c>Note</c> A pointer to the completion routine called when the operation has been completed (ignored for non-overlapped
/// sockets). See Remarks.
/// </param>
/// <returns>
/// <para>
/// Upon successful completion, the <c>WSAIoctl</c> returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific
/// error code can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSA_IO_PENDING</term>
/// <term>An overlapped operation was successfully initiated and completion will be indicated at a later time.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The lpvInBuffer, lpvOutBuffer, lpcbBytesReturned, lpOverlapped, or lpCompletionRoutine parameter is not totally contained in a
/// valid part of the user address space, or the cbInBuffer or cbOutBuffer parameter is too small.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>
/// The dwIoControlCode parameter is not a valid command, or a specified input parameter is not acceptable, or the command is not
/// applicable to the type of socket specified.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>The function is invoked when a callback is in progress.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor s is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEOPNOTSUPP</term>
/// <term>
/// The specified IOCTL command cannot be realized. (For example, the FLOWSPEC structures specified in SIO_SET_QOS or
/// SIO_SET_GROUP_QOS cannot be satisfied.)
/// </term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>The socket is marked as non-blocking and the requested operation would block.</term>
/// </item>
/// <item>
/// <term>WSAENOPROTOOPT</term>
/// <term>
/// The socket option is not supported on the specified protocol. For example, an attempt to use the SIO_GET_BROADCAST_ADDRESS IOCTL
/// was made on an IPv6 socket or an attempt to use the TCP SIO_KEEPALIVE_VALS IOCTL was made on a datagram socket.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAIoctl</c> function is used to set or retrieve operating parameters associated with the socket, the transport protocol,
/// or the communications subsystem.
/// </para>
/// <para>
/// If both lpOverlapped and lpCompletionRoutine are <c>NULL</c>, the socket in this function will be treated as a non-overlapped
/// socket. For a non-overlapped socket, lpOverlapped and lpCompletionRoutine parameters are ignored, which causes the function to
/// behave like the standard ioctlsocket function except that the function can block if socket s is in blocking mode. If socket s is
/// in non-blocking mode, this function can return WSAEWOULDBLOCK when the specified operation cannot be finished immediately. In
/// this case, the application may change the socket to blocking mode and reissue the request or wait for the corresponding network
/// event (such as FD_ROUTING_INTERFACE_CHANGE or FD_ADDRESS_LIST_CHANGE in the case of <c>SIO_ROUTING_INTERFACE_CHANGE</c> or
/// <c>SIO_ADDRESS_LIST_CHANGE</c>) using a Windows message (using WSAAsyncSelect)-based or event (using WSAEventSelect)-based
/// notification mechanism.
/// </para>
/// <para>
/// For overlapped sockets, operations that cannot be completed immediately will be initiated, and completion will be indicated at a
/// later time. The <c>DWORD</c> value pointed to by the lpcbBytesReturned parameter that is returned may be ignored. The final
/// completion status and bytes returned can be retrieved when the appropriate completion method is signaled when the operation has completed.
/// </para>
/// <para>
/// Any IOCTL may block indefinitely, depending on the service provider's implementation. If the application cannot tolerate
/// blocking in a <c>WSAIoctl</c> call, overlapped I/O would be advised for IOCTLs that are especially likely to block including:
/// </para>
/// <para><c>SIO_ADDRESS_LIST_CHANGE</c></para>
/// <para><c>SIO_FINDROUTE</c></para>
/// <para><c>SIO_FLUSH</c></para>
/// <para><c>SIO_GET_QOS</c></para>
/// <para><c>SIO_GET_GROUP_QOS</c></para>
/// <para><c>SIO_ROUTING_INTERFACE_CHANGE</c></para>
/// <para><c>SIO_SET_QOS</c></para>
/// <para><c>SIO_SET_GROUP_QOS</c></para>
/// <para>
/// Some protocol-specific IOCTLs may also be especially likely to block. Check the relevant protocol-specific annex for any
/// available information.
/// </para>
/// <para>The prototype for the completion routine pointed to by the lpCompletionRoutine parameter is as follows:</para>
/// <para>
/// The CompletionRoutine is a placeholder for an application-supplied function name. The dwError parameter specifies the completion
/// status for the overlapped operation as indicated by lpOverlapped parameter. The cbTransferred parameter specifies the number of
/// bytes received. The dwFlags parameter is not used for this IOCTL. The completion routine does not return a value.
/// </para>
/// <para>
/// It is possible to adopt an encoding scheme that preserves the currently defined ioctlsocket opcodes while providing a convenient
/// way to partition the opcode identifier space in as much as the dwIoControlCode parameter is now a 32-bit entity. The
/// dwIoControlCode parameter is built to allow for protocol and vendor independence when adding new control codes while retaining
/// backward compatibility with the Windows Sockets 1.1 and Unix control codes. The dwIoControlCode parameter has the following form.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>I</term>
/// <term>O</term>
/// <term>V</term>
/// <term>T</term>
/// <term>Vendor/address family</term>
/// <term>Code</term>
/// </listheader>
/// <item>
/// <term>3</term>
/// <term>3</term>
/// <term>2</term>
/// <term>2 2</term>
/// <term>2 2 2 2 2 2 2 1 1 1 1</term>
/// <term>1 1 1 1 1 1</term>
/// </item>
/// <item>
/// <term>1</term>
/// <term>0</term>
/// <term>9</term>
/// <term>8 7</term>
/// <term>6 5 4 3 2 1 0 9 8 7 6</term>
/// <term>5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0</term>
/// </item>
/// </list>
/// <para>
/// <c>Note</c> The bits in dwIoControlCode parameter displayed in the table must be read vertically from top to bottom by column.
/// So the left-most bit is bit 31, the next bit is bit 30, and the right-most bit is bit 0.
/// </para>
/// <para>I is set if the input buffer is valid for the code, as with <c>IOC_IN</c>.</para>
/// <para>
/// O is set if the output buffer is valid for the code, as with <c>IOC_OUT</c>. Control codes using both input and output buffers
/// set both I and O.
/// </para>
/// <para>V is set if there are no parameters for the code, as with <c>IOC_VOID</c>.</para>
/// <para>T is a 2-bit quantity that defines the type of the IOCTL. The following values are defined:</para>
/// <para>0 The IOCTL is a standard Unix IOCTL code, as with <c>FIONREAD</c> and <c>FIONBIO</c>.</para>
/// <para>1 The IOCTL is a generic Windows Sockets 2 IOCTL code. New IOCTL codes defined for Windows Sockets 2 will have T == 1.</para>
/// <para>2 The IOCTL applies only to a specific address family.</para>
/// <para>
/// 3 The IOCTL applies only to a specific vendor's provider, as with <c>IOC_VENDOR</c>. This type allows companies to be assigned a
/// vendor number that appears in the <c>Vendor/Address family</c> parameter. Then, the vendor can define new IOCTLs specific to
/// that vendor without having to register the IOCTL with a clearinghouse, thereby providing vendor flexibility and privacy.
/// </para>
/// <para>
/// <c>Vendor/Address family</c> An 11-bit quantity that defines the vendor who owns the code (if T == 3) or that contains the
/// address family to which the code applies (if T == 2). If this is a Unix IOCTL code (T == 0) then this parameter has the same
/// value as the code on Unix. If this is a generic Windows Sockets 2 IOCTL (T == 1) then this parameter can be used as an extension
/// of the code parameter to provide additional code values.
/// </para>
/// <para><c>Code</c> The 16-bit quantity that contains the specific IOCTL code for the operation.</para>
/// <para>The following Unix IOCTL codes (commands) are supported.</para>
/// <para>The following Windows Sockets 2 commands are supported.</para>
/// <para>
/// If an overlapped operation completes immediately, <c>WSAIoctl</c> returns a value of zero and the lpcbBytesReturned parameter is
/// updated with the number of bytes in the output buffer. If the overlapped operation is successfully initiated and will complete
/// later, this function returns SOCKET_ERROR and indicates error code WSA_IO_PENDING. In this case, lpcbBytesReturned is not
/// updated. When the overlapped operation completes the amount of data in the output buffer is indicated either through the
/// cbTransferred parameter in the completion routine (if specified), or through the lpcbTransfer parameter in WSAGetOverlappedResult.
/// </para>
/// <para>
/// When called with an overlapped socket, the lpOverlapped parameter must be valid for the duration of the overlapped operation.
/// The lpOverlapped parameter contains the address of a WSAOVERLAPPED structure.
/// </para>
/// <para>
/// If the lpCompletionRoutine parameter is <c>NULL</c>, 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.
/// </para>
/// <para>
/// <c>Note</c> 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.
/// </para>
/// <para>
/// If lpCompletionRoutine is not <c>NULL</c>, 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- <c>NULL</c> lpCompletionRoutine and later calls
/// WSAGetOverlappedResult for the same overlapped I/O request may not set the fWait parameter for that invocation of
/// <c>WSAGetOverlappedResult</c> to <c>TRUE</c>. In this case, the usage of the hEvent parameter is undefined, and attempting to
/// wait on the hEvent parameter would produce unpredictable results.
/// </para>
/// <para>The prototype of the completion routine is as follows:</para>
/// <para>
/// This <c>CompletionRoutine</c> is a placeholder for an application-defined or library-defined function. The completion routine is
/// invoked only if the thread is in an alertable state. To put a thread into an alertable state, use the WSAWaitForMultipleEvents,
/// WaitForSingleObjectEx, or WaitForMultipleObjectsEx function with the fAlertable or bAlertable parameter set to <c>TRUE</c>.
/// </para>
/// <para>
/// The dwError parameter of <c>CompletionRoutine</c> specifies the completion status for the overlapped operation as indicated by
/// lpOverlapped. The cbTransferred parameter specifies the number of bytes returned. Currently, no flag values are defined and
/// dwFlags will be zero. The <c>CompletionRoutine</c> function does not return a value.
/// </para>
/// <para>
/// Returning from this function allows invocation of another pending completion routine for this socket. The completion routines
/// can be called in any order, not necessarily in the same order the overlapped operations are completed.
/// </para>
/// <para>Compatibility</para>
/// <para>
/// The IOCTL codes with T == 0 are a subset of the IOCTL codes used in Berkeley sockets. In particular, there is no command that is
/// equivalent to <c>FIOASYNC</c>.
/// </para>
/// <para>
/// <c>Note</c> Some IOCTL codes require additional header files. For example, use of the <c>SIO_RCVALL</c> IOCTL requires the
/// Mstcpip.h header file.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winsock2/nf-winsock2-wsaioctl int WSAAPI WSAIoctl( SOCKET s, DWORD
// dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned,
// LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "038aeca6-d7b7-4f74-ac69-4536c2e5118b")]
public static extern WSRESULT WSAIoctl(SOCKET s, uint dwIoControlCode, [In] IntPtr lpvInBuffer, uint cbInBuffer, [Out] IntPtr lpvOutBuffer,
uint cbOutBuffer, out uint lpcbBytesReturned, ref WSAOVERLAPPED lpOverlapped,
[Optional, MarshalAs(UnmanagedType.FunctionPtr)] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
/// <summary>The <c>WSAIoctl</c> function controls the mode of a socket.</summary>
/// <param name="s">A descriptor identifying a socket.</param>
/// <param name="dwIoControlCode">The control code of operation to perform.</param>
/// <param name="inVal">The input value.</param>
/// <param name="outVal">The output value.</param>
/// <returns>
/// <para>
/// Upon successful completion, the <c>WSAIoctl</c> returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific
/// error code can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The lpvInBuffer, lpvOutBuffer, lpcbBytesReturned, lpOverlapped, or lpCompletionRoutine parameter is not totally contained in a
/// valid part of the user address space, or the cbInBuffer or cbOutBuffer parameter is too small.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>
/// The dwIoControlCode parameter is not a valid command, or a specified input parameter is not acceptable, or the command is not
/// applicable to the type of socket specified.
/// </term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor s is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEOPNOTSUPP</term>
/// <term>
/// The specified IOCTL command cannot be realized. (For example, the FLOWSPEC structures specified in SIO_SET_QOS or
/// SIO_SET_GROUP_QOS cannot be satisfied.)
/// </term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>The socket is marked as non-blocking and the requested operation would block.</term>
/// </item>
/// <item>
/// <term>WSAENOPROTOOPT</term>
/// <term>
/// The socket option is not supported on the specified protocol. For example, an attempt to use the SIO_GET_BROADCAST_ADDRESS IOCTL
/// was made on an IPv6 socket or an attempt to use the TCP SIO_KEEPALIVE_VALS IOCTL was made on a datagram socket.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAIoctl</c> function is used to set or retrieve operating parameters associated with the socket, the transport protocol,
/// or the communications subsystem.
/// </para>
/// <para>
/// If both lpOverlapped and lpCompletionRoutine are <c>NULL</c>, the socket in this function will be treated as a non-overlapped
/// socket. For a non-overlapped socket, lpOverlapped and lpCompletionRoutine parameters are ignored, which causes the function to
/// behave like the standard ioctlsocket function except that the function can block if socket s is in blocking mode. If socket s is
/// in non-blocking mode, this function can return WSAEWOULDBLOCK when the specified operation cannot be finished immediately. In
/// this case, the application may change the socket to blocking mode and reissue the request or wait for the corresponding network
/// event (such as FD_ROUTING_INTERFACE_CHANGE or FD_ADDRESS_LIST_CHANGE in the case of <c>SIO_ROUTING_INTERFACE_CHANGE</c> or
/// <c>SIO_ADDRESS_LIST_CHANGE</c>) using a Windows message (using WSAAsyncSelect)-based or event (using WSAEventSelect)-based
/// notification mechanism.
/// </para>
/// <para>
/// Any IOCTL may block indefinitely, depending on the service provider's implementation. If the application cannot tolerate
/// blocking in a <c>WSAIoctl</c> call, overlapped I/O would be advised for IOCTLs that are especially likely to block including:
/// </para>
/// <para><c>SIO_ADDRESS_LIST_CHANGE</c></para>
/// <para><c>SIO_FINDROUTE</c></para>
/// <para><c>SIO_FLUSH</c></para>
/// <para><c>SIO_GET_QOS</c></para>
/// <para><c>SIO_GET_GROUP_QOS</c></para>
/// <para><c>SIO_ROUTING_INTERFACE_CHANGE</c></para>
/// <para><c>SIO_SET_QOS</c></para>
/// <para><c>SIO_SET_GROUP_QOS</c></para>
/// <para>
/// Some protocol-specific IOCTLs may also be especially likely to block. Check the relevant protocol-specific annex for any
/// available information.
/// </para>
/// <para>
/// It is possible to adopt an encoding scheme that preserves the currently defined ioctlsocket opcodes while providing a convenient
/// way to partition the opcode identifier space in as much as the dwIoControlCode parameter is now a 32-bit entity. The
/// dwIoControlCode parameter is built to allow for protocol and vendor independence when adding new control codes while retaining
/// backward compatibility with the Windows Sockets 1.1 and Unix control codes. The dwIoControlCode parameter has the following form.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>I</term>
/// <term>O</term>
/// <term>V</term>
/// <term>T</term>
/// <term>Vendor/address family</term>
/// <term>Code</term>
/// </listheader>
/// <item>
/// <term>3</term>
/// <term>3</term>
/// <term>2</term>
/// <term>2 2</term>
/// <term>2 2 2 2 2 2 2 1 1 1 1</term>
/// <term>1 1 1 1 1 1</term>
/// </item>
/// <item>
/// <term>1</term>
/// <term>0</term>
/// <term>9</term>
/// <term>8 7</term>
/// <term>6 5 4 3 2 1 0 9 8 7 6</term>
/// <term>5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0</term>
/// </item>
/// </list>
/// <para>
/// <c>Note</c> The bits in dwIoControlCode parameter displayed in the table must be read vertically from top to bottom by column.
/// So the left-most bit is bit 31, the next bit is bit 30, and the right-most bit is bit 0.
/// </para>
/// <para>I is set if the input buffer is valid for the code, as with <c>IOC_IN</c>.</para>
/// <para>
/// O is set if the output buffer is valid for the code, as with <c>IOC_OUT</c>. Control codes using both input and output buffers
/// set both I and O.
/// </para>
/// <para>V is set if there are no parameters for the code, as with <c>IOC_VOID</c>.</para>
/// <para>T is a 2-bit quantity that defines the type of the IOCTL. The following values are defined:</para>
/// <para>0 The IOCTL is a standard Unix IOCTL code, as with <c>FIONREAD</c> and <c>FIONBIO</c>.</para>
/// <para>1 The IOCTL is a generic Windows Sockets 2 IOCTL code. New IOCTL codes defined for Windows Sockets 2 will have T == 1.</para>
/// <para>2 The IOCTL applies only to a specific address family.</para>
/// <para>
/// 3 The IOCTL applies only to a specific vendor's provider, as with <c>IOC_VENDOR</c>. This type allows companies to be assigned a
/// vendor number that appears in the <c>Vendor/Address family</c> parameter. Then, the vendor can define new IOCTLs specific to
/// that vendor without having to register the IOCTL with a clearinghouse, thereby providing vendor flexibility and privacy.
/// </para>
/// <para>
/// <c>Vendor/Address family</c> An 11-bit quantity that defines the vendor who owns the code (if T == 3) or that contains the
/// address family to which the code applies (if T == 2). If this is a Unix IOCTL code (T == 0) then this parameter has the same
/// value as the code on Unix. If this is a generic Windows Sockets 2 IOCTL (T == 1) then this parameter can be used as an extension
/// of the code parameter to provide additional code values.
/// </para>
/// <para><c>Code</c> The 16-bit quantity that contains the specific IOCTL code for the operation.</para>
/// <para>The following Unix IOCTL codes (commands) are supported.</para>
/// <para>The following Windows Sockets 2 commands are supported.</para>
/// <para>
/// <c>Note</c> 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.
/// </para>
/// <para>Compatibility</para>
/// <para>
/// The IOCTL codes with T == 0 are a subset of the IOCTL codes used in Berkeley sockets. In particular, there is no command that is
/// equivalent to <c>FIOASYNC</c>.
/// </para>
/// <para>
/// <c>Note</c> Some IOCTL codes require additional header files. For example, use of the <c>SIO_RCVALL</c> IOCTL requires the
/// Mstcpip.h header file.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winsock2/nf-winsock2-wsaioctl int WSAAPI WSAIoctl( SOCKET s, DWORD
// dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned,
// LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
[PInvokeData("winsock2.h", MSDNShortId = "038aeca6-d7b7-4f74-ac69-4536c2e5118b")]
public static WSRESULT WSAIoctl<TIn, TOut>(SOCKET s, uint dwIoControlCode, TIn inVal, out TOut outVal) where TIn : struct where TOut : struct
{
using SafeHGlobalHandle ptrIn = SafeHGlobalHandle.CreateFromStructure(inVal), ptrOut = SafeHGlobalHandle.CreateFromStructure<TOut>();
var ret = WSAIoctl(s, dwIoControlCode, ptrIn, ptrIn.Size, ptrOut, ptrOut.Size, out var bRet);
if (ret.Failed)
{
outVal = default;
return WSAGetLastError();
}
outVal = ptrOut.ToStructure<TOut>();
return 0;
}
/// <summary>
/// The <c>WSAJoinLeaf</c> function joins a leaf node into a multipoint session, exchanges connect data, and specifies needed
/// quality of service based on the specified FLOWSPEC structures.
/// </summary>
/// <param name="s">Descriptor identifying a multipoint socket.</param>
/// <param name="name">Name of the peer to which the socket is to be joined.</param>
/// <param name="namelen">Length of name, in bytes.</param>
/// <param name="lpCallerData">Pointer to the user data that is to be transferred to the peer during multipoint session establishment.</param>
/// <param name="lpCalleeData">
/// Pointer to the user data that is to be transferred back from the peer during multipoint session establishment.
/// </param>
/// <param name="lpSQOS">Pointer to the FLOWSPEC structures for socket s, one for each direction.</param>
/// <param name="lpGQOS">
/// Reserved for future use with socket groups. A pointer to the FLOWSPEC structures for the socket group (if applicable).
/// </param>
/// <param name="dwFlags">
/// Flags to indicate that the socket is acting as a sender (JL_SENDER_ONLY), receiver (JL_RECEIVER_ONLY), or both (JL_BOTH).
/// </param>
/// <returns>
/// <para>
/// If no error occurs, <c>WSAJoinLeaf</c> returns a value of type SOCKET that is a descriptor for the newly created multipoint
/// socket. Otherwise, a value of INVALID_SOCKET is returned, and a specific error code can be retrieved by calling WSAGetLastError.
/// </para>
/// <para>On a blocking socket, the return value indicates success or failure of the join operation.</para>
/// <para>
/// With a nonblocking socket, successful initiation of a join operation is indicated by a return of a valid socket descriptor.
/// Subsequently, an FD_CONNECT indication will be given on the original socket s when the join operation completes, either
/// successfully or otherwise. The application must use either WSAAsyncSelect or WSAEventSelect with interest registered for the
/// FD_CONNECT event in order to determine when the join operation has completed and checks the associated error code to determine
/// the success or failure of the operation. The select function cannot be used to determine when the join operation completes.
/// </para>
/// <para>
/// Also, until the multipoint session join attempt completes all subsequent calls to <c>WSAJoinLeaf</c> on the same socket will
/// fail with the error code WSAEALREADY. After the <c>WSAJoinLeaf</c> operation completes successfully, a subsequent attempt will
/// usually fail with the error code WSAEISCONN. An exception to the WSAEISCONN rule occurs for a c_root socket that allows
/// root-initiated joins. In such a case, another join may be initiated after a prior <c>WSAJoinLeaf</c> operation completes.
/// </para>
/// <para>
/// If the return error code indicates the multipoint session join attempt failed (that is, WSAECONNREFUSED, WSAENETUNREACH,
/// WSAETIMEDOUT) the application can call <c>WSAJoinLeaf</c> again for the same socket.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAEADDRINUSE</term>
/// <term>
/// The socket's local address is already in use and the socket was not marked to allow address reuse with SO_REUSEADDR. This error
/// usually occurs at the time of bind, but could be delayed until this function if the bind was to a partially wildcard address
/// (involving ADDR_ANY) and if a specific address needs to be committed at the time of this function.
/// </term>
/// </item>
/// <item>
/// <term>WSAEADDRNOTAVAIL</term>
/// <term>The remote address is not a valid address (such as ADDR_ANY).</term>
/// </item>
/// <item>
/// <term>WSAEAFNOSUPPORT</term>
/// <term>Addresses in the specified family cannot be used with this socket.</term>
/// </item>
/// <item>
/// <term>WSAEALREADY</term>
/// <term>A nonblocking WSAJoinLeaf call is in progress on the specified socket.</term>
/// </item>
/// <item>
/// <term>WSAECONNREFUSED</term>
/// <term>The attempt to join was forcefully rejected.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The name or the namelen parameter is not a valid part of the user address space, the namelen parameter is too small, the buffer
/// length for lpCalleeData, lpSQOS, and lpGQOS are too small, or the buffer length for lpCallerData is too large.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>
/// A WSAJoinLeaf function call was performed on a UDP socket that was opened without setting its WSA_FLAG_MULTIPOINT_C_LEAF or
/// WSA_FLAG_MULTIPOINT_D_LEAF multipoint flag.
/// </term>
/// </item>
/// <item>
/// <term>WSAEISCONN</term>
/// <term>The socket is already a member of the multipoint session.</term>
/// </item>
/// <item>
/// <term>WSAEINTR</term>
/// <term>A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENETUNREACH</term>
/// <term>The network cannot be reached from this host at this time.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>No buffer space is available. The socket cannot be joined.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEOPNOTSUPP</term>
/// <term>The FLOWSPEC structures specified in lpSQOS and lpGQOS cannot be satisfied.</term>
/// </item>
/// <item>
/// <term>WSAEPROTONOSUPPORT</term>
/// <term>The lpCallerData augment is not supported by the service provider.</term>
/// </item>
/// <item>
/// <term>WSAETIMEDOUT</term>
/// <term>The attempt to join timed out without establishing a multipoint session.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAJoinLeaf</c> function is used to join a leaf node to a multipoint session, and to perform a number of other ancillary
/// operations that occur at session join time as well. If the socket s is unbound, unique values are assigned to the local
/// association by the system, and the socket is marked as bound.
/// </para>
/// <para>
/// The <c>WSAJoinLeaf</c> function has the same parameters and semantics as WSAConnect except that it returns a socket descriptor
/// (as in WSAAccept), and it has an additional dwFlags parameter. Only multipoint sockets created using WSASocket with appropriate
/// multipoint flags set can be used for input parameter s in this function. The returned socket descriptor will not be usable until
/// after the join operation completes. For example, if the socket is in nonblocking mode after a corresponding FD_CONNECT
/// indication has been received from WSAAsyncSelect or WSAEventSelect on the original socket s, except that closesocket may be
/// invoked on this new socket descriptor to cancel a pending join operation. A root application in a multipoint session may call
/// <c>WSAJoinLeaf</c> one or more times in order to add a number of leaf nodes, however at most one multipoint connection request
/// may be outstanding at a time. Refer to Multipoint and Multicast Semantics for additional information.
/// </para>
/// <para>
/// For nonblocking sockets it is often not possible to complete the connection immediately. In such a case, this function returns
/// an as-yet unusable socket descriptor and the operation proceeds. There is no error code such as WSAEWOULDBLOCK in this case,
/// since the function has effectively returned a successful start indication. When the final outcome success or failure becomes
/// known, it may be reported through WSAAsyncSelect or WSAEventSelect depending on how the client registers for notification on the
/// original socket s. In either case, the notification is announced with FD_CONNECT and the error code associated with the
/// FD_CONNECT indicates either success or a specific reason for failure. The select function cannot be used to detect completion
/// notification for <c>WSAJoinLeaf</c>.
/// </para>
/// <para>
/// The socket descriptor returned by <c>WSAJoinLeaf</c> is different depending on whether the input socket descriptor, s, is a
/// c_root or a c_leaf. When used with a c_root socket, the name parameter designates a particular leaf node to be added and the
/// returned socket descriptor is a c_leaf socket corresponding to the newly added leaf node. The newly created socket has the same
/// properties as s, including asynchronous events registered with WSAAsyncSelect or with WSAEventSelect. It is not intended to be
/// used for exchange of multipoint data, but rather is used to receive network event indications (for example, FD_CLOSE) for the
/// connection that exists to the particular c_leaf. Some multipoint implementations can also allow this socket to be used for side
/// chats between the root and an individual leaf node. An FD_CLOSE indication will be received for this socket if the corresponding
/// leaf node calls closesocket to drop out of the multipoint session. Symmetrically, invoking <c>closesocket</c> on the c_leaf
/// socket returned from <c>WSAJoinLeaf</c> will cause the socket in the corresponding leaf node to get an FD_CLOSE notification.
/// </para>
/// <para>
/// When <c>WSAJoinLeaf</c> is invoked with a c_leaf socket, the name parameter contains the address of the root application (for a
/// rooted control scheme) or an existing multipoint session (nonrooted control scheme), and the returned socket descriptor is the
/// same as the input socket descriptor. In other words, a new socket descriptor is not allocated. In a rooted control scheme, the
/// root application would put its c_root socket in listening mode by calling listen. The standard FD_ACCEPT notification will be
/// delivered when the leaf node requests to join itself to the multipoint session. The root application uses the usual accept or
/// WSAAccept functions to admit the new leaf node. The value returned from either <c>accept</c> or <c>WSAAccept</c> is also a
/// c_leaf socket descriptor just like those returned from <c>WSAJoinLeaf</c>. To accommodate multipoint schemes that allow both
/// root-initiated and leaf-initiated joins, it is acceptable for a c_root socket that is already in listening mode to be used as an
/// input to <c>WSAJoinLeaf</c>.
/// </para>
/// <para>
/// The application is responsible for allocating any memory space pointed to directly or indirectly by any of the parameters it specifies.
/// </para>
/// <para>
/// The lpCallerData is a value parameter that contains any user data that is to be sent along with the multipoint session join
/// request. If lpCallerData is <c>NULL</c>, no user data will be passed to the peer. The lpCalleeData is a result parameter that
/// will contain any user data passed back from the peer as part of the multipoint session establishment. The <c>len</c> member of
/// the WSABUF structure pointed to by the lpCalleeData parameter initially contains the length of the buffer allocated by the
/// application and pointed to by the <c>buf</c> member of the <c>WSABUF</c> structure. The <c>len</c> member of the <c>WSABUF</c>
/// structure pointed to by the lpCalleeData parameter will be set to zero if no user data has been passed back. The lpCalleeData
/// information will be valid when the multipoint join operation is complete.
/// </para>
/// <para>
/// For blocking sockets, this will be when the <c>WSAJoinLeaf</c> function returns. For nonblocking sockets, this will be after the
/// join operation has completed. For example, this could occur after FD_CONNECT notification on the original socket s). If
/// lpCalleeData is <c>NULL</c>, no user data will be passed back. The exact format of the user data is specific to the address
/// family to which the socket belongs.
/// </para>
/// <para>
/// At multipoint session establishment time, an application can use the lpSQOS and/or lpGQOS parameters to override any previous
/// quality of service specification made for the socket through WSAIoctl with the SIO_SET_QOS or SIO_SET_GROUP_QOS opcodes.
/// </para>
/// <para>
/// The lpSQOS parameter specifies the FLOWSPEC structures for socket s, one for each direction, followed by any additional
/// provider-specific parameters. If either the associated transport provider in general or the specific type of socket in
/// particular cannot honor the quality of service request, an error will be returned as indicated in the following. The respective
/// sending or receiving flow specification values will be ignored for any unidirectional sockets. If no provider-specific
/// parameters are specified, the <c>buf</c> and <c>len</c> members of the WSABUF structure pointed to by the lpCalleeData parameter
/// should be set to <c>NULL</c> and zero, respectively. A <c>NULL</c> value for lpSQOS indicates no application-supplied quality of service.
/// </para>
/// <para>
/// Reserved for future socket groups. The lpGQOS parameter specifies the FLOWSPEC structures for the socket group (if applicable),
/// one for each direction, followed by any additional provider-specific parameters. If no provider-specific parameters are
/// specified, the the <c>buf</c> and <c>len</c> members of the WSABUF structure pointed to by the lpCalleeData parameter should be
/// set to should be set to <c>NULL</c> and zero, respectively. A <c>NULL</c> value for lpGQOS indicates no application-supplied
/// group quality of service. This parameter will be ignored if s is not the creator of the socket group.
/// </para>
/// <para>
/// When connected sockets break (that is, become closed for whatever reason), they should be discarded and recreated. It is safest
/// to assume that when things go awry for any reason on a connected socket, the application must discard and recreate the needed
/// sockets in order to return to a stable point.
/// </para>
/// <para>
/// <c>Note</c> When issuing a blocking Winsock call such as <c>WSAJoinLeaf</c>, 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.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsajoinleaf SOCKET WSAAPI WSAJoinLeaf( SOCKET s, const
// sockaddr *name, int namelen, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS, DWORD dwFlags );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "ef9efa03-feed-4f0d-b874-c646cce745c9")]
public static extern SOCKET WSAJoinLeaf(SOCKET s, [In] SOCKADDR name, int namelen, [In, Optional] IntPtr lpCallerData, [Out, Optional] IntPtr lpCalleeData, [In, Optional] IntPtr lpSQOS, [In, Optional] IntPtr lpGQOS, JL dwFlags);
/// <summary>
/// The <c>WSALookupServiceBegin</c> function initiates a client query that is constrained by the information contained within a
/// WSAQUERYSET structure. <c>WSALookupServiceBegin</c> only returns a handle, which should be used by subsequent calls to
/// WSALookupServiceNext to get the actual results.
/// </summary>
/// <param name="lpqsRestrictions">A pointer to the search criteria. See the Remarks for details.</param>
/// <param name="dwControlFlags">
/// <para>A set of flags that controls the depth of the search.</para>
/// <para>
/// Supported values for the dwControlFlags parameter are defined in the Winsock2.h header file and can be a combination of the
/// following options.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Flag</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>LUP_DEEP 0x0001</term>
/// <term>Queries deep as opposed to just the first level.</term>
/// </item>
/// <item>
/// <term>LUP_CONTAINERS 0x0002</term>
/// <term>Returns containers only.</term>
/// </item>
/// <item>
/// <term>LUP_NOCONTAINERS 0x0004</term>
/// <term>Do not return containers.</term>
/// </item>
/// <item>
/// <term>LUP_NEAREST 0x0008</term>
/// <term>If possible, returns results in the order of distance. The measure of distance is provider specific.</term>
/// </item>
/// <item>
/// <term>LUP_RETURN_NAME 0x0010</term>
/// <term>Retrieves the name as lpszServiceInstanceName.</term>
/// </item>
/// <item>
/// <term>LUP_RETURN_TYPE 0x0020</term>
/// <term>Retrieves the type as lpServiceClassId.</term>
/// </item>
/// <item>
/// <term>LUP_RETURN_VERSION 0x0040</term>
/// <term>Retrieves the version as lpVersion.</term>
/// </item>
/// <item>
/// <term>LUP_RETURN_COMMENT 0x0080</term>
/// <term>Retrieves the comment as lpszComment.</term>
/// </item>
/// <item>
/// <term>LUP_RETURN_ADDR 0x0100</term>
/// <term>Retrieves the addresses as lpcsaBuffer.</term>
/// </item>
/// <item>
/// <term>LUP_RETURN_BLOB 0x0200</term>
/// <term>Retrieves the private data as lpBlob.</term>
/// </item>
/// <item>
/// <term>LUP_RETURN_ALIASES 0x0400</term>
/// <term>
/// Any available alias information is to be returned in successive calls to WSALookupServiceNext, and each alias returned will have
/// the RESULT_IS_ALIAS flag set.
/// </term>
/// </item>
/// <item>
/// <term>LUP_RETURN_QUERY_STRING 0x0800</term>
/// <term>Retrieves the query string used for the request.</term>
/// </item>
/// <item>
/// <term>LUP_RETURN_ALL 0x0FF0</term>
/// <term>A set of flags that retrieves all of the LUP_RETURN_* values.</term>
/// </item>
/// <item>
/// <term>LUP_FLUSHPREVIOUS 0x1000</term>
/// <term>
/// Used as a value for the dwControlFlags parameter in WSALookupServiceNext. Setting this flag instructs the provider to discard
/// the last result set, which was too large for the specified buffer, and move on to the next result set.
/// </term>
/// </item>
/// <item>
/// <term>LUP_FLUSHCACHE 0x2000</term>
/// <term>If the provider has been caching information, ignores the cache, and queries the namespace itself.</term>
/// </item>
/// <item>
/// <term>LUP_RES_SERVICE 0x8000</term>
/// <term>
/// This indicates whether prime response is in the remote or local part of CSADDR_INFO structure. The other part needs to be usable
/// in either case.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="lphLookup">A handle to be used when calling WSALookupServiceNext in order to start retrieving the results set.</param>
/// <returns>
/// <para>
/// The return value is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error
/// number can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSA_NOT_ENOUGH_MEMORY</term>
/// <term>There was insufficient memory to perform the operation.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>One or more parameters were missing or invalid for this provider.</term>
/// </item>
/// <item>
/// <term>WSANO_DATA</term>
/// <term>The name was found in the database but no data matching the given restrictions was located.</term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>
/// The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
/// </term>
/// </item>
/// <item>
/// <term>WSASERVICE_NOT_FOUND</term>
/// <term>
/// No such service is known. The service cannot be found in the specified name space. This error is returned for a bluetooth
/// service discovery request if no remote bluetooth devices were found.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The lpqsRestrictions parameter points to a buffer containing a WSAQUERYSET structure. At a minimum, the <c>dwSize</c> member of
/// the <c>WSAQUERYSET</c> must be set to the length of the buffer before calling the <c>WSALookupServiceBegin</c> function.
/// Applications can restrict the query by specifying other members in the <c>WSAQUERYSET</c>.
/// </para>
/// <para>
/// In most instances, applications interested in only a particular transport protocol should constrain their query by address
/// family and protocol using the <c>dwNumberOfProtocols</c> and <c>lpafpProtocols</c> members of the WSAQUERYSET rather than by
/// specifiying the namespace in the <c>dwNameSpace</c> member.
/// </para>
/// <para>
/// Information on supported network transport protocols can be retreived using the EnumProtocols, WSAEnumProtocols,
/// WSCEnumProtocols, or WSCEnumProtocols32 function.
/// </para>
/// <para>
/// It is also possible to constrain the query to a single namespace. For example, a query that only wants results from DNS (not
/// results from the local hosts file and other naming services) would set the <c>dwNameSpace</c> member to NS_DNS. For example, a
/// bluetooth device discovery would set the the <c>dwNameSpace</c> member to NS_BTH.
/// </para>
/// <para>
/// Applications can also restrict the query to a specific namespace provider by specifying a pointer to the GUID for the provider
/// in the <c>lpNSProviderId</c> member.
/// </para>
/// <para>
/// Information on namespace providers on the local computer can be retrieved using the WSAEnumNameSpaceProviders,
/// WSAEnumNameSpaceProvidersEx, WSCEnumNameSpaceProviders32, or WSCEnumNameSpaceProvidersEx32 function.
/// </para>
/// <para>
/// If LUP_CONTAINERS is specified in a call, other restriction values should be avoided. If any are specified, it is up to the name
/// service provider to decide if it can support this restriction over the containers. If it cannot, it should return an error.
/// </para>
/// <para>
/// Some name service providers can have other means of finding containers. For example, containers might all be of some well-known
/// type, or of a set of well-known types, and therefore a query restriction can be created for finding them. No matter what other
/// means the name service provider has for locating containers, LUP_CONTAINERS and LUP_NOCONTAINERS take precedence. Hence, if a
/// query restriction is given that includes containers, specifying LUP_NOCONTAINERS will prevent the container items from being
/// returned. Similarly, no matter the query restriction, if LUP_CONTAINERS is given, only containers should be returned. If a
/// namespace does not support containers, and LUP_CONTAINERS is specified, it should simply return WSANO_DATA.
/// </para>
/// <para>The preferred method of obtaining the containers within another container, is the call:</para>
/// <para>
/// This call is followed by the requisite number of WSALookupServiceNext calls. This will return all containers contained
/// immediately within the starting context; that is, it is not a deep query. With this, one can map the address space structure by
/// walking the hierarchy, perhaps enumerating the content of selected containers. Subsequent uses of <c>WSALookupServiceBegin</c>
/// use the containers returned from a previous call.
/// </para>
/// <para>
/// As mentioned above, a WSAQUERYSET structure is used as an input parameter to <c>WSALookupBegin</c> in order to qualify the
/// query. The following table indicates how the <c>WSAQUERYSET</c> is used to construct a query. When a parameter is marked as
/// (Optional) a <c>NULL</c> pointer can be specified, indicating that the parameter will not be used as a search criteria. See
/// section Query-Related Data Structures for additional information.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>WSAQUERYSET member</term>
/// <term>Query interpretation</term>
/// </listheader>
/// <item>
/// <term>dwSize</term>
/// <term>Must be set to sizeof(WSAQUERYSET). This is a versioning mechanism.</term>
/// </item>
/// <item>
/// <term>dwOutputFlags</term>
/// <term>Ignored for queries.</term>
/// </item>
/// <item>
/// <term>lpszServiceInstanceName</term>
/// <term>
/// (Optional) Referenced string contains service name. The semantics for wildcarding within the string are not defined, but can be
/// supported by certain namespace providers.
/// </term>
/// </item>
/// <item>
/// <term>lpServiceClassId</term>
/// <term>(Required) The GUID corresponding to the service class.</term>
/// </item>
/// <item>
/// <term>lpVersion</term>
/// <term>
/// (Optional) References desired version number and provides version comparison semantics (that is, version must match exactly, or
/// version must be not less than the value specified).
/// </term>
/// </item>
/// <item>
/// <term>lpszComment</term>
/// <term>Ignored for queries.</term>
/// </item>
/// <item>
/// <term>dwNameSpace See the Important note that follows.</term>
/// <term>Identifier of a single namespace in which to constrain the search, or NS_ALL to include all namespaces.</term>
/// </item>
/// <item>
/// <term>lpNSProviderId</term>
/// <term>(Optional) References the GUID of a specific namespace provider, and limits the query to this provider only.</term>
/// </item>
/// <item>
/// <term>lpszContext</term>
/// <term>(Optional) Specifies the starting point of the query in a hierarchical namespace.</term>
/// </item>
/// <item>
/// <term>dwNumberOfProtocols</term>
/// <term>Size of the protocol constraint array, can be zero.</term>
/// </item>
/// <item>
/// <term>lpafpProtocols</term>
/// <term>(Optional) References an array of AFPROTOCOLS structure. Only services that utilize these protocols will be returned.</term>
/// </item>
/// <item>
/// <term>lpszQueryString</term>
/// <term>
/// (Optional) Some namespaces (such as whois++) support enriched SQL-like queries that are contained in a simple text string. This
/// parameter is used to specify that string.
/// </term>
/// </item>
/// <item>
/// <term>dwNumberOfCsAddrs</term>
/// <term>Ignored for queries.</term>
/// </item>
/// <item>
/// <term>lpcsaBuffer</term>
/// <term>Ignored for queries.</term>
/// </item>
/// <item>
/// <term>lpBlob</term>
/// <term>(Optional) This is a pointer to a provider-specific entity.</term>
/// </item>
/// </list>
/// <para>
/// <c>Important</c> In most instances, applications interested in only a particular transport protocol should constrain their query
/// by address family and protocol rather than by namespace. This would allow an application that needs to locate a TCP/IP service,
/// for example, to have its query processed by all available namespaces such as the local hosts file, DNS, and NIS.
/// </para>
/// <para>
/// <c>Windows Phone 8:</c> The <c>WSALookupServiceBeginW</c> function is supported for Windows Phone Store apps on Windows Phone 8
/// and later.
/// </para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: The <c>WSALookupServiceBeginW</c> function is supported for Windows Store
/// apps on Windows 8.1, Windows Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsalookupservicebegina INT WSAAPI WSALookupServiceBeginA(
// LPWSAQUERYSETA lpqsRestrictions, DWORD dwControlFlags, LPHANDLE lphLookup );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winsock2.h", MSDNShortId = "448309ef-b9dd-4960-8016-d26691df59ec")]
public static extern WSRESULT WSALookupServiceBegin(in WSAQUERYSET lpqsRestrictions, LUP dwControlFlags, out HANDLE lphLookup);
/// <summary>
/// <para>
/// The <c>WSALookupServiceEnd</c> function is called to free the handle after previous calls to WSALookupServiceBegin and WSALookupServiceNext.
/// </para>
/// <para>
/// If you call <c>WSALookupServiceEnd</c> from another thread while an existing WSALookupServiceNext is blocked, the end call will
/// have the same effect as a cancel and will cause the <c>WSALookupServiceNext</c> call to return immediately.
/// </para>
/// </summary>
/// <param name="hLookup">Handle previously obtained by calling WSALookupServiceBegin.</param>
/// <returns>
/// <para>
/// The return value is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error
/// number can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSA_INVALID_HANDLE</term>
/// <term>The handle is not valid.</term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>
/// The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
/// </term>
/// </item>
/// <item>
/// <term>WSA_NOT_ENOUGH_MEMORY</term>
/// <term>There was insufficient memory to perform the operation.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsalookupserviceend INT WSAAPI WSALookupServiceEnd(
// HANDLE hLookup );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "f9d2ac54-a818-464d-918e-80ebb5b1b106")]
public static extern WSRESULT WSALookupServiceEnd(HANDLE hLookup);
/// <summary>
/// <para>
/// The <c>WSALookupServiceNext</c> function is called after obtaining a handle from a previous call to WSALookupServiceBegin in
/// order to retrieve the requested service information.
/// </para>
/// <para>
/// The provider will pass back a WSAQUERYSET structure in the lpqsResults buffer. The client should continue to call this function
/// until it returns WSA_E_NO_MORE, indicating that all of <c>WSAQUERYSET</c> has been returned.
/// </para>
/// </summary>
/// <param name="hLookup">A handle returned from the previous call to WSALookupServiceBegin.</param>
/// <param name="dwControlFlags">
/// <para>
/// A set of flags that controls the operation. The values passed in the dwControlFlags parameter to the
/// WSALookupServiceBeginfunction determine the possible criteria. Any values passed in the dwControlFlags parameter to the
/// <c>WSALookupServiceNext</c> function further restrict the criteria for the service lookup.
/// </para>
/// <para>
/// Currently, LUP_FLUSHPREVIOUS is defined as a means to cope with a result set that is too large. If an application does not (or
/// cannot) supply a large enough buffer, setting LUP_FLUSHPREVIOUS instructs the provider to discard the last result set—which was
/// too large—and move on to the next set for this call.
/// </para>
/// <para>
/// Supported values for the dwControlFlags parameter are defined in the Winsock2.h header file and can be a combination of the
/// following options.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Flag</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>LUP_DEEP 0x0001</term>
/// <term>Queries deep as opposed to just the first level.</term>
/// </item>
/// <item>
/// <term>LUP_CONTAINERS 0x0002</term>
/// <term>Returns containers only.</term>
/// </item>
/// <item>
/// <term>LUP_NOCONTAINERS 0x0004</term>
/// <term>Do not return containers.</term>
/// </item>
/// <item>
/// <term>LUP_NEAREST 0x0008</term>
/// <term>If possible, returns results in the order of distance. The measure of distance is provider specific.</term>
/// </item>
/// <item>
/// <term>LUP_RETURN_NAME 0x0010</term>
/// <term>Retrieves the name as lpszServiceInstanceName.</term>
/// </item>
/// <item>
/// <term>LUP_RETURN_TYPE 0x0020</term>
/// <term>Retrieves the type as lpServiceClassId.</term>
/// </item>
/// <item>
/// <term>LUP_RETURN_VERSION 0x0040</term>
/// <term>Retrieves the version as lpVersion.</term>
/// </item>
/// <item>
/// <term>LUP_RETURN_COMMENT 0x0080</term>
/// <term>Retrieves the comment as lpszComment.</term>
/// </item>
/// <item>
/// <term>LUP_RETURN_ADDR 0x0100</term>
/// <term>Retrieves the addresses as lpcsaBuffer.</term>
/// </item>
/// <item>
/// <term>LUP_RETURN_BLOB 0x0200</term>
/// <term>Retrieves the private data as lpBlob.</term>
/// </item>
/// <item>
/// <term>LUP_RETURN_ALIASES 0x0400</term>
/// <term>
/// Any available alias information is to be returned in successive calls to WSALookupServiceNext, and each alias returned will have
/// the RESULT_IS_ALIAS flag set.
/// </term>
/// </item>
/// <item>
/// <term>LUP_RETURN_QUERY_STRING 0x0800</term>
/// <term>Retrieves the query string used for the request.</term>
/// </item>
/// <item>
/// <term>LUP_RETURN_ALL 0x0FF0</term>
/// <term>A set of flags that retrieves all of the LUP_RETURN_* values.</term>
/// </item>
/// <item>
/// <term>LUP_FLUSHPREVIOUS 0x1000</term>
/// <term>
/// Used as a value for the dwControlFlags parameter in WSALookupServiceNext. Setting this flag instructs the provider to discard
/// the last result set, which was too large for the specified buffer, and move on to the next result set.
/// </term>
/// </item>
/// <item>
/// <term>LUP_FLUSHCACHE 0x2000</term>
/// <term>If the provider has been caching information, ignores the cache, and queries the namespace itself.</term>
/// </item>
/// <item>
/// <term>LUP_RES_SERVICE 0x8000</term>
/// <term>
/// This indicates whether prime response is in the remote or local part of CSADDR_INFO structure. The other part needs to be usable
/// in either case.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="lpdwBufferLength">
/// On input, the number of bytes contained in the buffer pointed to by lpqsResults. On output, if the function fails and the error
/// is WSAEFAULT, then it contains the minimum number of bytes to pass for the lpqsResults to retrieve the record.
/// </param>
/// <param name="lpqsResults">A pointer to a block of memory, which will contain one result set in a WSAQUERYSET structure on return.</param>
/// <returns>
/// <para>
/// The return value is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error
/// number can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSA_E_CANCELLED</term>
/// <term>
/// A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled. The data in the
/// lpqsResults buffer is undefined. In Windows Sockets version 2, conflicting error codes are defined for WSAECANCELLED (10103) and
/// WSA_E_CANCELLED (10111). The error code WSAECANCELLED will be removed in a future version and only WSA_E_CANCELLED will remain.
/// For Windows Sockets version 2, however, applications should check for both WSAECANCELLED and WSA_E_CANCELLED for the widest
/// possible compatibility with namespace providers that use either one.
/// </term>
/// </item>
/// <item>
/// <term>WSA_E_NO_MORE</term>
/// <term>
/// There is no more data available. In Windows Sockets version 2, conflicting error codes are defined for WSAENOMORE (10102) and
/// WSA_E_NO_MORE (10110). The error code WSAENOMORE will be removed in a future version and only WSA_E_NO_MORE will remain. For
/// Windows Sockets version 2, however, applications should check for both WSAENOMORE and WSA_E_NO_MORE for the widest possible
/// compatibility with name-space providers that use either one.
/// </term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The lpqsResults buffer was too small to contain a WSAQUERYSET set.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>One or more required parameters were invalid or missing.</term>
/// </item>
/// <item>
/// <term>WSA_INVALID_HANDLE</term>
/// <term>The specified Lookup handle is invalid.</term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>
/// The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
/// </term>
/// </item>
/// <item>
/// <term>WSANO_DATA</term>
/// <term>The name was found in the database, but no data matching the given restrictions was located.</term>
/// </item>
/// <item>
/// <term>WSA_NOT_ENOUGH_MEMORY</term>
/// <term>There was insufficient memory to perform the operation.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The dwControlFlags parameter specified in this function and the ones specified at the time of WSALookupServiceBegin are treated
/// as restrictions for the purpose of combination. The restrictions are combined between the ones at <c>WSALookupServiceBegin</c>
/// time and the ones at <c>WSALookupServiceNext</c> time. Therefore the flags at <c>WSALookupServiceNext</c> can never increase the
/// amount of data returned beyond what was requested at <c>WSALookupServiceBegin</c>, although it is not an error to specify more
/// or fewer flags. The flags specified at a given <c>WSALookupServiceNext</c> apply only to that call.
/// </para>
/// <para>
/// The dwControlFlags LUP_FLUSHPREVIOUS and LUP_RES_SERVICE are exceptions to the combined restrictions rule (because they are
/// behavior flags instead of restriction flags). If either of these flags are used in <c>WSALookupServiceNext</c> they have their
/// defined effect regardless of the setting of the same flags at WSALookupServiceBegin.
/// </para>
/// <para>
/// For example, if LUP_RETURN_VERSION is specified at WSALookupServiceBegin the service provider retrieves records including the
/// version. If LUP_RETURN_VERSION is NOT specified at <c>WSALookupServiceNext</c>, the returned information does not include the
/// version, even though it was available. No error is generated.
/// </para>
/// <para>
/// Also for example, if LUP_RETURN_BLOB is NOT specified at WSALookupServiceBegin but is specified at <c>WSALookupServiceNext</c>,
/// the returned information does not include the private data. No error is generated.
/// </para>
/// <para>
/// If the <c>WSALookupServiceNext</c> function fails with an error of WSAEFAULT, this indicates that the buffer pointed to by the
/// lpqsResults parameter was too small to contain the query results. A new buffer for a WSAQUERYSET should be provided with a size
/// specified by the value pointed to by the lpdwBufferLength parameter. This new buffer for the <c>WSAQUERYSET</c> needs to have
/// some of the members of the <c>WSAQUERYSET</c> specified before calling the <c>WSALookupServiceNext</c> function again. At a
/// minimum, the <c>dwSize</c> member of the <c>WSAQUERYSET</c> must be set to the new size of the buffer.
/// </para>
/// <para>Query Results</para>
/// <para>The following table describes how the query results are represented in the WSAQUERYSET structure.</para>
/// <list type="table">
/// <listheader>
/// <term>WSAQUERYSET member</term>
/// <term>Result interpretation</term>
/// </listheader>
/// <item>
/// <term>dwSize</term>
/// <term>Will be set to sizeof( WSAQUERYSET). This is used as a versioning mechanism.</term>
/// </item>
/// <item>
/// <term>dwOutputFlags</term>
/// <term>RESULT_IS_ALIAS flag indicates this is an alias result.</term>
/// </item>
/// <item>
/// <term>lpszServiceInstanceName</term>
/// <term>Referenced string contains service name.</term>
/// </item>
/// <item>
/// <term>lpServiceClassId</term>
/// <term>The GUID corresponding to the service class.</term>
/// </item>
/// <item>
/// <term>lpVersion</term>
/// <term>References version number of the particular service instance.</term>
/// </item>
/// <item>
/// <term>lpszComment</term>
/// <term>Optional comment string specified by service instance.</term>
/// </item>
/// <item>
/// <term>dwNameSpace</term>
/// <term>Namespace in which the service instance was found.</term>
/// </item>
/// <item>
/// <term>lpNSProviderId</term>
/// <term>Identifies the specific namespace provider that supplied this query result.</term>
/// </item>
/// <item>
/// <term>lpszContext</term>
/// <term>Specifies the context point in a hierarchical namespace at which the service is located.</term>
/// </item>
/// <item>
/// <term>dwNumberOfProtocols</term>
/// <term>Undefined for results.</term>
/// </item>
/// <item>
/// <term>lpafpProtocols</term>
/// <term>Undefined for results, all needed protocol information is in the CSADDR_INFO structures.</term>
/// </item>
/// <item>
/// <term>lpszQueryString</term>
/// <term>
/// When dwControlFlags includes LUP_RETURN_QUERY_STRING, this parameter returns the unparsed remainder of the
/// lpszServiceInstanceName specified in the original query. For example, in a namespace that identifies services by hierarchical
/// names that specify a host name and a file path within that host, the address returned might be the host address and the unparsed
/// remainder might be the file path. If the lpszServiceInstanceName is fully parsed and LUP_RETURN_QUERY_STRING is used, this
/// parameter is NULL or points to a zero-length string.
/// </term>
/// </item>
/// <item>
/// <term>dwNumberOfCsAddrs</term>
/// <term>Indicates the number of elements in the array of CSADDR_INFO structures.</term>
/// </item>
/// <item>
/// <term>lpcsaBuffer</term>
/// <term>A pointer to an array of CSADDR_INFO structures, with one complete transport address contained within each element.</term>
/// </item>
/// <item>
/// <term>lpBlob</term>
/// <term>(Optional) This is a pointer to a provider-specific entity.</term>
/// </item>
/// </list>
/// <para>
/// <c>Windows Phone 8:</c> The <c>WSALookupServiceNextW</c> function is supported for Windows Phone Store apps on Windows Phone 8
/// and later.
/// </para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: The <c>WSALookupServiceNextW</c> function is supported for Windows Store
/// apps on Windows 8.1, Windows Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsalookupservicenexta INT WSAAPI WSALookupServiceNextA(
// HANDLE hLookup, DWORD dwControlFlags, LPDWORD lpdwBufferLength, LPWSAQUERYSETA lpqsResults );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winsock2.h", MSDNShortId = "ab4f1830-b38d-4224-a6a9-6d4512245ad6")]
public static extern WSRESULT WSALookupServiceNext(HANDLE hLookup, LUP dwControlFlags, ref uint lpdwBufferLength, [Out] IntPtr lpqsResults);
/// <summary>The Windows Sockets <c>WSANSPIoctl</c> function enables developers to make I/O control calls to a registered namespace.</summary>
/// <param name="hLookup">The lookup handle returned from a previous call to the WSALookupServiceBegin function.</param>
/// <param name="dwControlCode">
/// <para>The control code of the operation to perform.</para>
/// <para>The values that may be used for the dwControlCode parameter are determined by the namespace provider.</para>
/// <para>
/// The following value is supported by several Microsoft namespace providers including the Network Location Awareness (NS_NLA)
/// namespace provider. This IOCTL is defined in the Winsock2.h header file.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>SIO_NSP_NOTIFY_CHANGE</term>
/// <term>
/// This operation checks if the results returned with previous calls using the hLookup parameter are still valid. These previous
/// calls include the initial call to the WSALookupServiceBegin function to retrieve the hLookup parameter. These previous calls may
/// also include calls to the WSALookupServiceNext function using the hLookup parameter.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="lpvInBuffer">A pointer to the input buffer.</param>
/// <param name="cbInBuffer">The size, in bytes, of the input buffer.</param>
/// <param name="lpvOutBuffer">A pointer to the output buffer.</param>
/// <param name="cbOutBuffer">The size, in bytes, of the output buffer.</param>
/// <param name="lpcbBytesReturned">A pointer to the number of bytes returned.</param>
/// <param name="lpCompletion">
/// A pointer to a WSACOMPLETION structure, used for asynchronous processing. Set lpCompletion to <c>NULL</c> to force blocking
/// (synchronous) execution.
/// </param>
/// <returns>
/// <para>
/// Success returns NO_ERROR. Failure returns SOCKET_ERROR, and a specific error code can be retrieved by calling the
/// WSAGetLastError function. The following table describes the error codes.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>WSA_INVALID_HANDLE</term>
/// <term>The hLookup parameter was not a valid query handle returned by WSALookupServiceBegin.</term>
/// </item>
/// <item>
/// <term>WSA_IO_PENDING</term>
/// <term>An overlapped operation was successfully initiated and completion will be indicated at a later time.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, or lpCompletion argument is not totally contained in a valid part of the
/// user address space. Alternatively, the cbInBuffer or cbOutBuffer argument is too small, and the argument is modified to reflect
/// the required allocation size.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>
/// A supplied parameter is not acceptable, or the operation inappropriately returns results from multiple namespaces when it does
/// not make sense for the specified operation.
/// </term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEOPNOTSUPP</term>
/// <term>
/// The operation is not supported. This error is returned if the namespace provider does not implement this function. This error
/// can also be returned if the specified dwControlCode is an unrecognized command.
/// </term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>
/// The socket is not using overlapped I/O (asynchronous processing), yet the lpCompletion parameter is non-NULL. This error is used
/// as a special notification for the SIO_NSP_NOTIFY_CHANGE IOCTL when the lpCompletion parameter is NULL (a poll) to indicate that
/// a query set remains valid.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSANSPIoctl</c> function is used to set or retrieve operating parameters associated with a query handle to a namespace
/// provider. The hLookup parameter is a handle to the namespace provider query previously returned by the WSALookupServiceBegin
/// function (not a socket handle).
/// </para>
/// <para>
/// Any IOCTL sent to a namespace provider may block indefinitely, depending upon the implementation of the namespace. If an
/// application cannot tolerate blocking in a <c>WSANSPIoctl</c> function call, overlapped I/O should be used and the lpCompletion
/// parameter should point to a WSACOMPLETION structure. To make a <c>WSANSPIoctl</c> function call nonblocking and return
/// immediately, set the <c>Type</c> member of the <c>WSACOMPLETION</c> structure to <c>NSP_NOTIFY_IMMEDIATELY</c>.
/// </para>
/// <para>
/// If lpCompletion is <c>NULL</c>, the <c>WSANSPIoctl</c> function executes as a blocking call. The namespace provider should
/// return immediately and should not block. But each namespace is responsible for enforcing this behavior.
/// </para>
/// <para>The following IOCTL code is supported by several Microsoft name space provider:</para>
/// <para>
/// Immediate poll operations are usually much less expensive since they do not require a notification object. In most cases, this
/// is implemented as a simple Boolean variable check. Asynchronous notification, however, may necessitate the creation of dedicated
/// worker threads and/or inter-process communication channels, depending on the implementation of the namespace provider service,
/// and will incur processing overhead related to the notification object involved with signaling the change event.
/// </para>
/// <para>
/// To cancel an asynchronous notification request, end the original query with a WSALookupServiceEnd function call on the affected
/// query handle. Canceling the asynchronous notification for LUP_NOTIFY_HWND will not post any message, however, an overlapped
/// operation will be completed and notification will be delivered with the error WSA_OPERATION_ABORTED.
/// </para>
/// <para>
/// <c>Note</c> 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.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsanspioctl INT WSAAPI WSANSPIoctl( HANDLE hLookup, DWORD
// dwControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned,
// LPWSACOMPLETION lpCompletion );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "6ecaedf0-0038-46d3-9916-c9cb069c5e92")]
public static extern WSRESULT WSANSPIoctl(HANDLE hLookup, uint dwControlCode, [In, Optional] IntPtr lpvInBuffer, uint cbInBuffer,
[Out, Optional] IntPtr lpvOutBuffer, uint cbOutBuffer, out uint lpcbBytesReturned, [In, Optional] IntPtr lpCompletion);
/// <summary>The Windows Sockets <c>WSANSPIoctl</c> function enables developers to make I/O control calls to a registered namespace.</summary>
/// <param name="hLookup">The lookup handle returned from a previous call to the WSALookupServiceBegin function.</param>
/// <param name="dwControlCode">
/// <para>The control code of the operation to perform.</para>
/// <para>The values that may be used for the dwControlCode parameter are determined by the namespace provider.</para>
/// <para>
/// The following value is supported by several Microsoft namespace providers including the Network Location Awareness (NS_NLA)
/// namespace provider. This IOCTL is defined in the Winsock2.h header file.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>SIO_NSP_NOTIFY_CHANGE</term>
/// <term>
/// This operation checks if the results returned with previous calls using the hLookup parameter are still valid. These previous
/// calls include the initial call to the WSALookupServiceBegin function to retrieve the hLookup parameter. These previous calls may
/// also include calls to the WSALookupServiceNext function using the hLookup parameter.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="lpvInBuffer">A pointer to the input buffer.</param>
/// <param name="cbInBuffer">The size, in bytes, of the input buffer.</param>
/// <param name="lpvOutBuffer">A pointer to the output buffer.</param>
/// <param name="cbOutBuffer">The size, in bytes, of the output buffer.</param>
/// <param name="lpcbBytesReturned">A pointer to the number of bytes returned.</param>
/// <param name="lpCompletion">
/// A pointer to a WSACOMPLETION structure, used for asynchronous processing. Set lpCompletion to <c>NULL</c> to force blocking
/// (synchronous) execution.
/// </param>
/// <returns>
/// <para>
/// Success returns NO_ERROR. Failure returns SOCKET_ERROR, and a specific error code can be retrieved by calling the
/// WSAGetLastError function. The following table describes the error codes.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>WSA_INVALID_HANDLE</term>
/// <term>The hLookup parameter was not a valid query handle returned by WSALookupServiceBegin.</term>
/// </item>
/// <item>
/// <term>WSA_IO_PENDING</term>
/// <term>An overlapped operation was successfully initiated and completion will be indicated at a later time.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The lpvInBuffer, cbInBuffer, lpvOutBuffer, cbOutBuffer, or lpCompletion argument is not totally contained in a valid part of the
/// user address space. Alternatively, the cbInBuffer or cbOutBuffer argument is too small, and the argument is modified to reflect
/// the required allocation size.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>
/// A supplied parameter is not acceptable, or the operation inappropriately returns results from multiple namespaces when it does
/// not make sense for the specified operation.
/// </term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEOPNOTSUPP</term>
/// <term>
/// The operation is not supported. This error is returned if the namespace provider does not implement this function. This error
/// can also be returned if the specified dwControlCode is an unrecognized command.
/// </term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>
/// The socket is not using overlapped I/O (asynchronous processing), yet the lpCompletion parameter is non-NULL. This error is used
/// as a special notification for the SIO_NSP_NOTIFY_CHANGE IOCTL when the lpCompletion parameter is NULL (a poll) to indicate that
/// a query set remains valid.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSANSPIoctl</c> function is used to set or retrieve operating parameters associated with a query handle to a namespace
/// provider. The hLookup parameter is a handle to the namespace provider query previously returned by the WSALookupServiceBegin
/// function (not a socket handle).
/// </para>
/// <para>
/// Any IOCTL sent to a namespace provider may block indefinitely, depending upon the implementation of the namespace. If an
/// application cannot tolerate blocking in a <c>WSANSPIoctl</c> function call, overlapped I/O should be used and the lpCompletion
/// parameter should point to a WSACOMPLETION structure. To make a <c>WSANSPIoctl</c> function call nonblocking and return
/// immediately, set the <c>Type</c> member of the <c>WSACOMPLETION</c> structure to <c>NSP_NOTIFY_IMMEDIATELY</c>.
/// </para>
/// <para>
/// If lpCompletion is <c>NULL</c>, the <c>WSANSPIoctl</c> function executes as a blocking call. The namespace provider should
/// return immediately and should not block. But each namespace is responsible for enforcing this behavior.
/// </para>
/// <para>The following IOCTL code is supported by several Microsoft name space provider:</para>
/// <para>
/// Immediate poll operations are usually much less expensive since they do not require a notification object. In most cases, this
/// is implemented as a simple Boolean variable check. Asynchronous notification, however, may necessitate the creation of dedicated
/// worker threads and/or inter-process communication channels, depending on the implementation of the namespace provider service,
/// and will incur processing overhead related to the notification object involved with signaling the change event.
/// </para>
/// <para>
/// To cancel an asynchronous notification request, end the original query with a WSALookupServiceEnd function call on the affected
/// query handle. Canceling the asynchronous notification for LUP_NOTIFY_HWND will not post any message, however, an overlapped
/// operation will be completed and notification will be delivered with the error WSA_OPERATION_ABORTED.
/// </para>
/// <para>
/// <c>Note</c> 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.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsanspioctl INT WSAAPI WSANSPIoctl( HANDLE hLookup, DWORD
// dwControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned,
// LPWSACOMPLETION lpCompletion );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "6ecaedf0-0038-46d3-9916-c9cb069c5e92")]
public static extern WSRESULT WSANSPIoctl(HANDLE hLookup, uint dwControlCode, [In, Optional] IntPtr lpvInBuffer, uint cbInBuffer,
[Out, Optional] IntPtr lpvOutBuffer, uint cbOutBuffer, out uint lpcbBytesReturned, in WSACOMPLETION lpCompletion);
/// <summary>The <c>WSANtohl</c> function converts a <c>u_long</c> from network byte order to host byte order.</summary>
/// <param name="s">A descriptor identifying a socket.</param>
/// <param name="netlong">A 32-bit number in network byte order.</param>
/// <param name="lphostlong">A pointer to a 32-bit number to receive the number in host byte order.</param>
/// <returns>
/// <para>
/// If no error occurs, <c>WSANtohl</c> returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can
/// be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The lphostlong parameter is NULL or the address pointed to is not completely contained in a valid part of the user address space.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSANtohl</c> function takes a 32-bit number in network byte order and returns a 32-bit number in host byte order in the
/// 32-bit number pointed to by the lphostlong parameter. The socket passed in the s parameter is used to determine the network byte
/// order required based on the Winsock catalog protocol entry associated with the socket. This feature supports Winsock providers
/// that use different network byte orders.
/// </para>
/// <para>
/// If the socket is for the AF_INET or AF_INET6 address family, the <c>WSANtohl</c> function can be used to convert an IPv4 address
/// in network byte order to the IPv4 address in host byte order. This function does not do any checking to determine if the netlong
/// parameter is a valid IPv4 address.
/// </para>
/// <para>
/// The <c>WSANtohl</c> function requires that the Winsock DLL has previously been loaded with a successful call to the WSAStartup
/// function. For use with the AF_INET or AF_INET6 family, the ntohl function does not require that the Winsock DLL be loaded.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsantohl int WSAAPI WSANtohl( SOCKET s, u_long netlong,
// u_long *lphostlong );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "7e3b42eb-3b93-459f-828a-c19e277882c7")]
public static extern WSRESULT WSANtohl(SOCKET s, uint netlong, out uint lphostlong);
/// <summary>The <c>WSANtohs</c> function converts a <c>u_short</c> from network byte order to host byte order.</summary>
/// <param name="s">A descriptor identifying a socket.</param>
/// <param name="netshort">A 16-bit number in network byte order.</param>
/// <param name="lphostshort">A pointer to a 16-bit number to receive the number in host byte order.</param>
/// <returns>
/// <para>
/// If no error occurs, <c>WSANtohs</c> returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error code can
/// be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The lphostshort parameter is NULL or the address pointed to is not completely contained in a valid part of the user address space.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSANtohs</c> function takes a 16-bit number in network byte order and returns a 16-bit number in host byte order in the
/// 16-bit number pointed to by the lphostshort parameter. The socket passed in the s parameter is used to determine the network
/// byte order required based on the Winsock catalog protocol entry associated with the socket. This feature supports Winsock
/// providers that use different network byte orders.
/// </para>
/// <para>
/// If the socket is for the AF_INET or AF_INET6 address family, the <c>WSANtohs</c> function can be used to convert an IP port
/// number in network byte order to the IP port number in host byte order.
/// </para>
/// <para>
/// The <c>WSANtohs</c> function requires that the Winsock DLL has previously been loaded with a successful call to the WSAStartup
/// function. For use with the AF_INET OR AF_INET6 address family, the ntohsfunction does not require that the Winsock DLL be loaded.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsantohs int WSAAPI WSANtohs( SOCKET s, u_short netshort,
// u_short *lphostshort );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "0a4bc3a9-9919-4dcb-8a37-af37e0243c8f")]
public static extern WSRESULT WSANtohs(SOCKET s, ushort netshort, out ushort lphostshort);
/// <summary>The <c>WSAPoll</c> function determines status of one or more sockets.</summary>
/// <param name="fdArray">
/// An array of one or more <c>POLLFD</c> structures specifying the set of sockets for which status is requested. The array must
/// contain at least one structure with a valid socket. Upon return, this parameter receives the updated sockets with the
/// <c>revents</c> status flags member set on each one that matches the status query criteria.
/// </param>
/// <param name="fds">
/// The number of <c>WSAPOLLFD</c> structures in fdarray. This is not necessarily the number of sockets for which status is requested.
/// </param>
/// <param name="timeout">
/// <para>A value that specifies the wait behavior, based on the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>Greater than zero</term>
/// <term>The time, in milliseconds, to wait.</term>
/// </item>
/// <item>
/// <term>Zero</term>
/// <term>Return immediately.</term>
/// </item>
/// <item>
/// <term>Less than zero</term>
/// <term>Wait indefinitely.</term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>Returns one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>Zero</term>
/// <term>No sockets were in the queried state before the timer expired.</term>
/// </item>
/// <item>
/// <term>Greater than zero</term>
/// <term>The number of elements in fdarray for which an revents member of the POLLFD structure is nonzero.</term>
/// </item>
/// <item>
/// <term>SOCKET_ERROR</term>
/// <term>An error occurred. Call the WSAGetLastError function to retrieve the extended error code.</term>
/// </item>
/// </list>
/// <list type="table">
/// <listheader>
/// <term>Extended Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>An exception occurred while reading user input parameters.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>
/// An invalid parameter was passed. This error is returned if the
/// [WSAPOLLFD](/windows/win32/api/winsock2/ns-winsock2-wsapollfd)a&gt; structures pointed to by the fdarray parameter when
/// requesting socket status. This error is also returned if none of the sockets specified in the fd member of any of the WSAPOLLFD
/// structures pointed to by the fdarray parameter were valid.
/// </term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>The function was unable to allocate sufficient memory.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>The <c>WSAPoll</c> function is defined on Windows Vista and later.</para>
/// <para>
/// The WSAPOLLFD structures. An application sets the appropriate flags in the <c>events</c> member of the <c>WSAPOLLFD</c>
/// structure to specify the type of status requested for each corresponding socket. The <c>WSAPoll</c> function returns the status
/// of a socket in the <c>revents</c> member of the <c>WSAPOLLFD</c> structure.
/// </para>
/// <para>
/// For each socket, a caller can request information on read or write status. Error conditions are always returned, so information
/// on them need not be requested.
/// </para>
/// <para>
/// The WSAPOLLFD structure pointed to by the fdarray parameter. All sockets that do not meet these criteria and have no error
/// condition will have the corresponding <c>revents</c> member set to 0.
/// </para>
/// <para>
/// A combination of the following flags can be set in the WSAPOLLFD structure for a given socket when requesting status for that socket:
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Flag</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>POLLPRI</term>
/// <term>Priority data may be read without blocking. This flag is not supported by the Microsoft Winsock provider.</term>
/// </item>
/// <item>
/// <term>POLLRDBAND</term>
/// <term>Priority band (out-of-band) data may be read without blocking.</term>
/// </item>
/// <item>
/// <term>POLLRDNORM</term>
/// <term>Normal data may be read without blocking.</term>
/// </item>
/// <item>
/// <term>POLLWRNORM</term>
/// <term>Normal data may be written without blocking.</term>
/// </item>
/// </list>
/// <para>
/// The <c>POLLIN</c> flag is defined as the combination of the <c>POLLRDNORM</c> and <c>POLLRDBAND</c> flag values. The
/// <c>POLLOUT</c> flag is defined as the same as the <c>POLLWRNORM</c> flag value.
/// </para>
/// <para>
/// The WSAPOLLFD structure must only contain a combination of the above flags that are supported by the Winsock provider. Any other
/// values are considered errors and <c>WSAPoll</c> will return <c>SOCKET_ERROR</c>. A subsequent call to the WSAGetLastError
/// function will retrieve the extended error code of WSAEINVAL. If the <c>POLLPRI</c> flag is set on a socket for the Microsoft
/// Winsock provider, the <c>WSAPoll</c> function will fail.
/// </para>
/// <para>When the WSAPOLLFD structures pointed to by the fdarray parameter to indicate socket status:</para>
/// <list type="table">
/// <listheader>
/// <term>Flag</term>
/// <term>Description</term>
/// </listheader>
/// <item>
/// <term>POLLERR</term>
/// <term>An error has occurred.</term>
/// </item>
/// <item>
/// <term>POLLHUP</term>
/// <term>A stream-oriented connection was either disconnected or aborted.</term>
/// </item>
/// <item>
/// <term>POLLNVAL</term>
/// <term>An invalid socket was used.</term>
/// </item>
/// <item>
/// <term>POLLPRI</term>
/// <term>Priority data may be read without blocking. This flag is not returned by the Microsoft Winsock provider.</term>
/// </item>
/// <item>
/// <term>POLLRDBAND</term>
/// <term>Priority band (out-of-band) data may be read without blocking.</term>
/// </item>
/// <item>
/// <term>POLLRDNORM</term>
/// <term>Normal data may be read without blocking.</term>
/// </item>
/// <item>
/// <term>POLLWRNORM</term>
/// <term>Normal data may be written without blocking.</term>
/// </item>
/// </list>
/// <para>With regard to TCP and UDP sockets:</para>
/// <list type="bullet"/>
/// <para>
/// The number of elements (not sockets) in fdarray is indicated by nfds. Members of fdarray which have their <c>fd</c> member set
/// to a negative value are ignored and their <c>revents</c> will be set to <c>POLLNVAL</c> upon return. This behavior is useful to
/// an application which maintains a fixed fdarray allocation and will not compact the array to remove unused entries or to
/// reallocate memory. It is not necessary to clear <c>revents</c> for any element prior to calling <c>WSAPoll</c>.
/// </para>
/// <para>
/// The timeout argument specifies how long the function is to wait before returning. A positive value contains the number of
/// milliseconds to wait before returning. A zero value forces <c>WSAPoll</c> to return immediately, and a negative value indicates
/// that <c>WSAPoll</c> should wait indefinitely.
/// </para>
/// <para>
/// <c>Note</c> When issuing a blocking Winsock call such as <c>WSAPoll</c> with the timeout parameter set to a negative number,
/// 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.
/// </para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsapoll int WSAAPI WSAPoll( LPWSAPOLLFD fdArray, ULONG
// fds, INT timeout );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "3f6f872c-5cee-49f3-bf22-2e8a5d147987")]
public static extern int WSAPoll([In, Out, MarshalAs(UnmanagedType.LPArray)] WSAPOLLFD[] fdArray, uint fds, int timeout);
/// <summary>The <c>WSAProviderConfigChange</c> function notifies the application when the provider configuration is changed.</summary>
/// <param name="lpNotificationHandle">
/// Pointer to notification handle. If the notification handle is set to <c>NULL</c> (the handle value not the pointer itself), this
/// function returns a notification handle in the location pointed to by lpNotificationHandle.
/// </param>
/// <param name="lpOverlapped">Pointer to a WSAOVERLAPPED structure.</param>
/// <param name="lpCompletionRoutine">Pointer to the completion routine called when the provider change notification is received.</param>
/// <returns>
/// <para>
/// If no error occurs the <c>WSAProviderConfigChange</c> returns 0. Otherwise, a value of SOCKET_ERROR is returned and a specific
/// error code may be retrieved by calling WSAGetLastError. The error code WSA_IO_PENDING indicates that the overlapped operation
/// has been successfully initiated and that completion (and thus change event) will be indicated at a later time.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSA_NOT_ENOUGH_MEMORY</term>
/// <term>Not enough free memory available to complete the operation.</term>
/// </item>
/// <item>
/// <term>WSA_INVALID_HANDLE</term>
/// <term>Value pointed by lpNotificationHandle parameter is not a valid notification handle.</term>
/// </item>
/// <item>
/// <term>WSAEOPNOTSUPP</term>
/// <term>Current operating system environment does not support provider installation or removal without restart.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAProviderConfigChange</c> function notifies the application of provider (both transport and namespace) installation or
/// removal in Windows operating environments that support such configuration change without requiring a restart. When called for
/// the first time (lpNotificationHandle parameter points to <c>NULL</c> handle), this function completes immediately and returns
/// notification handle in the location pointed by lpNotificationHandle that can be used in subsequent calls to receive
/// notifications of provider installation and removal. The second and any subsequent calls only complete when provider information
/// changes since the time the call was made It is expected (but not required) that the application uses overlapped I/O on second
/// and subsequent calls to <c>WSAProviderConfigChange</c>, in which case the call will return immediately and application will be
/// notified of provider configuration changes using the completion mechanism chosen through specified overlapped completion parameters.
/// </para>
/// <para>
/// Notification handle returned by <c>WSAProviderConfigChange</c> is like any regular operating system handle that should be closed
/// (when no longer needed) using Windows CloseHandle call.
/// </para>
/// <para>
/// The following sequence of actions can be used to guarantee that application always has current protocol configuration information:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>Call <c>WSAProviderConfigChange</c></term>
/// </item>
/// <item>
/// <term>Call WSAEnumProtocols and/or WSAEnumNameSpaceProviders</term>
/// </item>
/// <item>
/// <term>
/// Whenever <c>WSAProviderConfigChange</c> notifies application of provider configuration change (through blocking or overlapped
/// I/O), the whole sequence of actions should be repeated.
/// </term>
/// </item>
/// </list>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaproviderconfigchange INT WSAAPI
// WSAProviderConfigChange( LPHANDLE lpNotificationHandle, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE
// lpCompletionRoutine );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "abaf367a-8f99-478c-a58c-d57e9f9cd8a1")]
public static extern WSRESULT WSAProviderConfigChange(ref HANDLE lpNotificationHandle, [In, Out, Optional] IntPtr lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
/// <summary>The <c>WSARecv</c> function receives data from a connected socket or a bound connectionless socket.</summary>
/// <param name="s">A descriptor identifying a connected socket.</param>
/// <param name="lpBuffers">
/// A pointer to an array of WSABUF structures. Each <c>WSABUF</c> structure contains a pointer to a buffer and the length, in
/// bytes, of the buffer.
/// </param>
/// <param name="dwBufferCount">The number of WSABUF structures in the lpBuffers array.</param>
/// <param name="lpNumberOfBytesRecvd">
/// <para>A pointer to the number, in bytes, of data received by this call if the receive operation completes immediately.</para>
/// <para>
/// Use <c>NULL</c> for this parameter if the lpOverlapped parameter is not <c>NULL</c> to avoid potentially erroneous results. This
/// parameter can be <c>NULL</c> only if the lpOverlapped parameter is not <c>NULL</c>.
/// </para>
/// </param>
/// <param name="lpFlags">
/// A pointer to flags used to modify the behavior of the <c>WSARecv</c> function call. For more information, see the Remarks section.
/// </param>
/// <param name="lpOverlapped">A pointer to a WSAOVERLAPPED structure (ignored for nonoverlapped sockets).</param>
/// <param name="lpCompletionRoutine">
/// A pointer to the completion routine called when the receive operation has been completed (ignored for nonoverlapped sockets).
/// </param>
/// <returns>
/// <para>
/// If no error occurs and the receive operation has completed immediately, <c>WSARecv</c> 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 <c>SOCKET_ERROR</c> 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 overlapped operation was not successfully initiated and no completion
/// indication will occur.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAECONNABORTED</term>
/// <term>The virtual circuit was terminated due to a time-out or other failure.</term>
/// </item>
/// <item>
/// <term>WSAECONNRESET</term>
/// <term>
/// For a stream socket, the virtual circuit was reset by the remote side. The application should close the socket as it is no
/// longer usable. For a UDP datagram socket, this error would indicate that a previous send operation resulted in an ICMP "Port
/// Unreachable" message.
/// </term>
/// </item>
/// <item>
/// <term>WSAEDISCON</term>
/// <term>Socket s is message oriented and the virtual circuit was gracefully closed by the remote side.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The lpBuffers parameter is not completely contained in a valid part of the user address space.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEINTR</term>
/// <term>The (blocking) call was canceled by the WSACancelBlockingCall function.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>The socket has not been bound (for example, with bind).</term>
/// </item>
/// <item>
/// <term>WSAEMSGSIZE</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENETRESET</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>WSAENOTCONN</term>
/// <term>The socket is not connected.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEOPNOTSUPP</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>WSAESHUTDOWN</term>
/// <term>
/// The socket has been shut down; it is not possible to call WSARecv on a socket after shutdown has been invoked with how set to
/// SD_RECEIVE or SD_BOTH.
/// </term>
/// </item>
/// <item>
/// <term>WSAETIMEDOUT</term>
/// <term>The connection has been dropped because of a network failure or because the peer system failed to respond.</term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>
/// Windows NT: Overlapped sockets: there are too many outstanding overlapped I/O requests. Nonoverlapped sockets: The socket is
/// marked as nonblocking and the receive operation cannot be completed immediately.
/// </term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSA_IO_PENDING</term>
/// <term>An overlapped operation was successfully initiated and completion will be indicated at a later time.</term>
/// </item>
/// <item>
/// <term>WSA_OPERATION_ABORTED</term>
/// <term>The overlapped operation has been canceled due to the closure of the socket.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSARecv</c> function provides some additional features compared with the standard recv function in three important areas:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>It can be used in conjunction with overlapped sockets to perform overlapped recv operations.</term>
/// </item>
/// <item>
/// <term>It allows multiple receive buffers to be specified making it applicable to the scatter/gather type of I/O.</term>
/// </item>
/// <item>
/// <term>
/// The lpFlags parameter is used both on input and returned on output, allowing applications to sense the output state of the
/// <c>MSG_PARTIAL</c> flag bit. However, the <c>MSG_PARTIAL</c> flag bit is not supported by all protocols.
/// </term>
/// </item>
/// </list>
/// <para>
/// The <c>WSARecv</c> function is used on connected sockets or bound connectionless sockets specified by the s parameter and is
/// used to read incoming data. The socket's local address must be known. For server applications, this is usually done explicitly
/// through bind or implicitly through accept or WSAAccept. Explicit binding is discouraged for client applications. For client
/// applications the socket can become bound implicitly to a local address through connect, WSAConnect, sendto, WSASendTo, or WSAJoinLeaf.
/// </para>
/// <para>
/// For connected, connectionless sockets, this function restricts the addresses from which received messages are accepted. The
/// function only returns messages from the remote address specified in the connection. Messages from other addresses are (silently) discarded.
/// </para>
/// <para>
/// For overlapped sockets, <c>WSARecv</c> 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 WSAGetOverlappedResult.
/// </para>
/// <para>
/// <c>Note</c> 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.
/// </para>
/// <para>
/// If both lpOverlapped and lpCompletionRoutine are <c>NULL</c>, the socket in this function will be treated as a nonoverlapped socket.
/// </para>
/// <para>
/// For nonoverlapped 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.
/// </para>
/// <para><c>Note</c> The socket options <c>SO_RCVTIMEO</c> and <c>SO_SNDTIMEO</c> apply only to blocking sockets.</para>
/// <para>
/// Whether or not a protocol is acting as byte stream is determined by the setting of XP1_MESSAGE_ORIENTED and XP1_PSEUDO_STREAM in
/// its WSAPROTOCOL_INFO structure and the setting of the MSG_PARTIAL flag passed in to this function (for protocols that support
/// it). The following table lists relevant combinations, (an asterisk (*) indicates that the setting of this bit does not matter in
/// this case).
/// </para>
/// <list type="table">
/// <listheader>
/// <term>XP1_MESSAGE_ORIENTED</term>
/// <term>XP1_PSEUDO_STREAM</term>
/// <term>MSG_PARTIAL</term>
/// <term>Acts as</term>
/// </listheader>
/// <item>
/// <term>not set</term>
/// <term>*</term>
/// <term>*</term>
/// <term>Byte stream</term>
/// </item>
/// <item>
/// <term>*</term>
/// <term>Set</term>
/// <term>*</term>
/// <term>Byte stream</term>
/// </item>
/// <item>
/// <term>set</term>
/// <term>Not set</term>
/// <term>set</term>
/// <term>Byte stream</term>
/// </item>
/// <item>
/// <term>set</term>
/// <term>Not set</term>
/// <term>not set</term>
/// <term>Message oriented</term>
/// </item>
/// </list>
/// <para>
/// The buffers are filled in the order in which they appear in the array pointed to by lpBuffers, and the buffers are packed so
/// that no holes are created.
/// </para>
/// <para>
/// If this function is completed in an overlapped manner, it is the Winsock service provider's responsibility to capture the WSABUF
/// structures before returning from this call. This enables applications to build stack-based <c>WSABUF</c> arrays pointed to by
/// the lpBuffers parameter.
/// </para>
/// <para>
/// For byte stream-style sockets (for example, type <c>SOCK_STREAM</c>), incoming data is placed into the buffers until the buffers
/// are filled, the connection is closed, or the internally buffered data is exhausted. Regardless of whether or not the incoming
/// data fills all the buffers, the completion indication occurs for overlapped sockets.
/// </para>
/// <para>
/// For message-oriented sockets (for example, type <c>SOCK_DGRAM</c>), 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. If the <c>MSG_PARTIAL</c> feature is supported by the
/// underlying service provider, the <c>MSG_PARTIAL</c> flag is set in lpFlags and subsequent receive operations will retrieve the
/// rest of the message. If <c>MSG_PARTIAL</c> is not supported but the protocol is reliable, <c>WSARecv</c> generates the error
/// WSAEMSGSIZE and a subsequent receive operation with a larger buffer can be used to retrieve the entire message. Otherwise, (that
/// is, the protocol is unreliable and does not support <c>MSG_PARTIAL</c>), the excess data is lost, and <c>WSARecv</c> generates
/// the error WSAEMSGSIZE.
/// </para>
/// <para>
/// For connection-oriented sockets, <c>WSARecv</c> can indicate the graceful termination of the virtual circuit in one of two ways
/// that depend on whether the socket is byte stream or message oriented. For byte streams, zero bytes having been read (as
/// indicated by a zero return value to indicate success, and lpNumberOfBytesRecvd value of zero) indicates graceful closure and
/// that no more bytes will ever be read. For message-oriented sockets, where a zero byte message is often allowable, a failure with
/// an error code of WSAEDISCON is used to indicate graceful closure. In any case a return error code of WSAECONNRESET indicates an
/// abortive close has occurred.
/// </para>
/// <para>
/// The lpFlags parameter can be used to influence the behavior of the function invocation beyond the options specified for the
/// associated socket. That is, the semantics of this function are determined by the socket options and the lpFlags parameter. The
/// latter is constructed by using the bitwise OR operator with any of the values listed in the following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>MSG_PEEK</term>
/// <term>
/// Peeks 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 nonoverlapped sockets.
/// </term>
/// </item>
/// <item>
/// <term>MSG_OOB</term>
/// <term>Processes OOB data.</term>
/// </item>
/// <item>
/// <term>MSG_PARTIAL</term>
/// <term>
/// This flag is for message-oriented sockets only. On output, this flag indicates that the data specified is a portion of the
/// message transmitted by the sender. Remaining portions of the message will be specified in subsequent receive operations. A
/// subsequent receive operation with the MSG_PARTIAL flag cleared indicates end of sender's message. As an input parameter, this
/// flag indicates that the receive operation should complete even if only part of a message has been received by the transport provider.
/// </term>
/// </item>
/// <item>
/// <term>MSG_PUSH_IMMEDIATE</term>
/// <term>
/// This flag is for stream-oriented sockets only. This flag allows an application that uses stream sockets to tell the transport
/// provider not to delay completion of partially filled pending receive requests. This is a hint to the transport provider that the
/// application is willing to receive any incoming data as soon as possible without necessarily waiting for the remainder of the
/// data that might still be in transit. What constitutes a partially filled pending receive request is a transport-specific matter.
/// In the case of TCP, this refers to the case of incoming TCP segments being placed into the receive request data buffer where
/// none of the TCP segments indicated a PUSH bit value of 1. In this case, TCP may hold the partially filled receive request a
/// little longer to allow the remainder of the data to arrive with a TCP segment that has the PUSH bit set to 1. This flag tells
/// TCP not to hold the receive request but to complete it immediately. Using this flag for large block transfers is not recommended
/// since processing partial blocks is often not optimal. This flag is useful only for cases where receiving and processing the
/// partial data immediately helps decrease processing latency. This flag is a hint rather than an actual guarantee. This flag is
/// supported on Windows 8.1, Windows Server 2012 R2, and later.
/// </term>
/// </item>
/// <item>
/// <term>MSG_WAITALL</term>
/// <term>
/// The receive request will complete only when one of the following events occurs: Be aware that if the underlying transport
/// provider does not support MSG_WAITALL, or if the socket is in a non-blocking mode, then this call will fail with WSAEOPNOTSUPP.
/// Also, if MSG_WAITALL is specified along with MSG_OOB, MSG_PEEK, or MSG_PARTIAL, then this call will fail with WSAEOPNOTSUPP.
/// This flag is not supported on datagram sockets or message-oriented sockets.
/// </term>
/// </item>
/// </list>
/// <para>
/// For message-oriented sockets, the <c>MSG_PARTIAL</c> bit is set in the lpFlags parameter if a partial message is received. If a
/// complete message is received, <c>MSG_PARTIAL</c> is cleared in lpFlags. In the case of delayed completion, the value pointed to
/// by lpFlags is not updated. When completion has been indicated, the application should call WSAGetOverlappedResult and examine
/// the flags indicated by the lpdwFlags parameter.
/// </para>
/// <para>
/// <c>Note</c> When issuing a blocking Winsock call such as <c>WSARecv</c> 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.
/// </para>
/// <para>Overlapped Socket I/O</para>
/// <para>
/// If an overlapped operation completes immediately, <c>WSARecv</c> 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, <c>WSARecv</c> returns <c>SOCKET_ERROR</c> and indicates
/// error code WSA_IO_PENDING. In this case, lpNumberOfBytesRecvd and lpFlags are 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 <c>WSAGetOverlappedResult</c>.
/// </para>
/// <para>
/// The <c>WSARecv</c> function using overlapped I/O can be called from within the completion routine of a previous <c>WSARecv</c>,
/// WSARecvFrom, WSASend 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.
/// </para>
/// <para>
/// 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.
/// </para>
/// <para>
/// If the lpCompletionRoutine parameter is <c>NULL</c>, 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.
/// </para>
/// <para>
/// If lpCompletionRoutine is not <c>NULL</c>, 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- <c>NULL</c> lpCompletionRoutine and later calls
/// WSAGetOverlappedResult for the same overlapped I/O request may not set the fWait parameter for that invocation of
/// <c>WSAGetOverlappedResult</c> to <c>TRUE</c>. In this case the usage of the hEvent parameter is undefined, and attempting to
/// wait on the hEvent parameter would produce unpredictable results.
/// </para>
/// <para>
/// 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 <c>TRUE</c> is invoked.
/// </para>
/// <para>The prototype of the completion routine is as follows:</para>
/// <para>
/// CompletionRoutine is a placeholder for an application-defined or library-defined function name. The dwError specifies the
/// completion status for the overlapped operation as indicated by lpOverlapped. The cbTransferred parameter specifies the number of
/// bytes received. The dwFlags parameter contains information that would have appeared in lpFlags if the receive operation had
/// completed immediately. This function does not return a value.
/// </para>
/// <para>
/// 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 <c>WSA_IO_COMPLETION</c>. 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.
/// </para>
/// <para>
/// If you are using I/O completion ports, be aware that the order of calls made to <c>WSARecv</c> is also the order in which the
/// buffers are populated. <c>WSARecv</c> should not be called on the same socket simultaneously from different threads, because it
/// can result in an unpredictable buffer order.
/// </para>
/// <para>Example Code</para>
/// <para>The following example shows how to use the <c>WSARecv</c> function in overlapped I/O mode.</para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsarecv int WSAAPI WSARecv( SOCKET s, LPWSABUF lpBuffers,
// DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped,
// LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "bfe66e11-e9a7-4321-ad55-3141113e9a03")]
public static extern WSRESULT WSARecv(SOCKET s, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] WSABUF[] lpBuffers,
uint dwBufferCount, out uint lpNumberOfBytesRecvd, ref MsgFlags lpFlags, [In, Out, Optional] IntPtr lpOverlapped,
[In, Optional, MarshalAs(UnmanagedType.FunctionPtr)] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
/// <summary>The <c>WSARecv</c> function receives data from a connected socket or a bound connectionless socket.</summary>
/// <param name="s">A descriptor identifying a connected socket.</param>
/// <param name="lpBuffers">
/// A pointer to an array of WSABUF structures. Each <c>WSABUF</c> structure contains a pointer to a buffer and the length, in
/// bytes, of the buffer.
/// </param>
/// <param name="dwBufferCount">The number of WSABUF structures in the lpBuffers array.</param>
/// <param name="lpNumberOfBytesRecvd">
/// <para>A pointer to the number, in bytes, of data received by this call if the receive operation completes immediately.</para>
/// <para>
/// Use <c>NULL</c> for this parameter if the lpOverlapped parameter is not <c>NULL</c> to avoid potentially erroneous results. This
/// parameter can be <c>NULL</c> only if the lpOverlapped parameter is not <c>NULL</c>.
/// </para>
/// </param>
/// <param name="lpFlags">
/// A pointer to flags used to modify the behavior of the <c>WSARecv</c> function call. For more information, see the Remarks section.
/// </param>
/// <param name="lpOverlapped">A pointer to a WSAOVERLAPPED structure (ignored for nonoverlapped sockets).</param>
/// <param name="lpCompletionRoutine">
/// A pointer to the completion routine called when the receive operation has been completed (ignored for nonoverlapped sockets).
/// </param>
/// <returns>
/// <para>
/// If no error occurs and the receive operation has completed immediately, <c>WSARecv</c> 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 <c>SOCKET_ERROR</c> 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 overlapped operation was not successfully initiated and no completion
/// indication will occur.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAECONNABORTED</term>
/// <term>The virtual circuit was terminated due to a time-out or other failure.</term>
/// </item>
/// <item>
/// <term>WSAECONNRESET</term>
/// <term>
/// For a stream socket, the virtual circuit was reset by the remote side. The application should close the socket as it is no
/// longer usable. For a UDP datagram socket, this error would indicate that a previous send operation resulted in an ICMP "Port
/// Unreachable" message.
/// </term>
/// </item>
/// <item>
/// <term>WSAEDISCON</term>
/// <term>Socket s is message oriented and the virtual circuit was gracefully closed by the remote side.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The lpBuffers parameter is not completely contained in a valid part of the user address space.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEINTR</term>
/// <term>The (blocking) call was canceled by the WSACancelBlockingCall function.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>The socket has not been bound (for example, with bind).</term>
/// </item>
/// <item>
/// <term>WSAEMSGSIZE</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENETRESET</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>WSAENOTCONN</term>
/// <term>The socket is not connected.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEOPNOTSUPP</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>WSAESHUTDOWN</term>
/// <term>
/// The socket has been shut down; it is not possible to call WSARecv on a socket after shutdown has been invoked with how set to
/// SD_RECEIVE or SD_BOTH.
/// </term>
/// </item>
/// <item>
/// <term>WSAETIMEDOUT</term>
/// <term>The connection has been dropped because of a network failure or because the peer system failed to respond.</term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>
/// Windows NT: Overlapped sockets: there are too many outstanding overlapped I/O requests. Nonoverlapped sockets: The socket is
/// marked as nonblocking and the receive operation cannot be completed immediately.
/// </term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSA_IO_PENDING</term>
/// <term>An overlapped operation was successfully initiated and completion will be indicated at a later time.</term>
/// </item>
/// <item>
/// <term>WSA_OPERATION_ABORTED</term>
/// <term>The overlapped operation has been canceled due to the closure of the socket.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSARecv</c> function provides some additional features compared with the standard recv function in three important areas:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>It can be used in conjunction with overlapped sockets to perform overlapped recv operations.</term>
/// </item>
/// <item>
/// <term>It allows multiple receive buffers to be specified making it applicable to the scatter/gather type of I/O.</term>
/// </item>
/// <item>
/// <term>
/// The lpFlags parameter is used both on input and returned on output, allowing applications to sense the output state of the
/// <c>MSG_PARTIAL</c> flag bit. However, the <c>MSG_PARTIAL</c> flag bit is not supported by all protocols.
/// </term>
/// </item>
/// </list>
/// <para>
/// The <c>WSARecv</c> function is used on connected sockets or bound connectionless sockets specified by the s parameter and is
/// used to read incoming data. The socket's local address must be known. For server applications, this is usually done explicitly
/// through bind or implicitly through accept or WSAAccept. Explicit binding is discouraged for client applications. For client
/// applications the socket can become bound implicitly to a local address through connect, WSAConnect, sendto, WSASendTo, or WSAJoinLeaf.
/// </para>
/// <para>
/// For connected, connectionless sockets, this function restricts the addresses from which received messages are accepted. The
/// function only returns messages from the remote address specified in the connection. Messages from other addresses are (silently) discarded.
/// </para>
/// <para>
/// For overlapped sockets, <c>WSARecv</c> 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 WSAGetOverlappedResult.
/// </para>
/// <para>
/// <c>Note</c> 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.
/// </para>
/// <para>
/// If both lpOverlapped and lpCompletionRoutine are <c>NULL</c>, the socket in this function will be treated as a nonoverlapped socket.
/// </para>
/// <para>
/// For nonoverlapped 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.
/// </para>
/// <para><c>Note</c> The socket options <c>SO_RCVTIMEO</c> and <c>SO_SNDTIMEO</c> apply only to blocking sockets.</para>
/// <para>
/// Whether or not a protocol is acting as byte stream is determined by the setting of XP1_MESSAGE_ORIENTED and XP1_PSEUDO_STREAM in
/// its WSAPROTOCOL_INFO structure and the setting of the MSG_PARTIAL flag passed in to this function (for protocols that support
/// it). The following table lists relevant combinations, (an asterisk (*) indicates that the setting of this bit does not matter in
/// this case).
/// </para>
/// <list type="table">
/// <listheader>
/// <term>XP1_MESSAGE_ORIENTED</term>
/// <term>XP1_PSEUDO_STREAM</term>
/// <term>MSG_PARTIAL</term>
/// <term>Acts as</term>
/// </listheader>
/// <item>
/// <term>not set</term>
/// <term>*</term>
/// <term>*</term>
/// <term>Byte stream</term>
/// </item>
/// <item>
/// <term>*</term>
/// <term>Set</term>
/// <term>*</term>
/// <term>Byte stream</term>
/// </item>
/// <item>
/// <term>set</term>
/// <term>Not set</term>
/// <term>set</term>
/// <term>Byte stream</term>
/// </item>
/// <item>
/// <term>set</term>
/// <term>Not set</term>
/// <term>not set</term>
/// <term>Message oriented</term>
/// </item>
/// </list>
/// <para>
/// The buffers are filled in the order in which they appear in the array pointed to by lpBuffers, and the buffers are packed so
/// that no holes are created.
/// </para>
/// <para>
/// If this function is completed in an overlapped manner, it is the Winsock service provider's responsibility to capture the WSABUF
/// structures before returning from this call. This enables applications to build stack-based <c>WSABUF</c> arrays pointed to by
/// the lpBuffers parameter.
/// </para>
/// <para>
/// For byte stream-style sockets (for example, type <c>SOCK_STREAM</c>), incoming data is placed into the buffers until the buffers
/// are filled, the connection is closed, or the internally buffered data is exhausted. Regardless of whether or not the incoming
/// data fills all the buffers, the completion indication occurs for overlapped sockets.
/// </para>
/// <para>
/// For message-oriented sockets (for example, type <c>SOCK_DGRAM</c>), 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. If the <c>MSG_PARTIAL</c> feature is supported by the
/// underlying service provider, the <c>MSG_PARTIAL</c> flag is set in lpFlags and subsequent receive operations will retrieve the
/// rest of the message. If <c>MSG_PARTIAL</c> is not supported but the protocol is reliable, <c>WSARecv</c> generates the error
/// WSAEMSGSIZE and a subsequent receive operation with a larger buffer can be used to retrieve the entire message. Otherwise, (that
/// is, the protocol is unreliable and does not support <c>MSG_PARTIAL</c>), the excess data is lost, and <c>WSARecv</c> generates
/// the error WSAEMSGSIZE.
/// </para>
/// <para>
/// For connection-oriented sockets, <c>WSARecv</c> can indicate the graceful termination of the virtual circuit in one of two ways
/// that depend on whether the socket is byte stream or message oriented. For byte streams, zero bytes having been read (as
/// indicated by a zero return value to indicate success, and lpNumberOfBytesRecvd value of zero) indicates graceful closure and
/// that no more bytes will ever be read. For message-oriented sockets, where a zero byte message is often allowable, a failure with
/// an error code of WSAEDISCON is used to indicate graceful closure. In any case a return error code of WSAECONNRESET indicates an
/// abortive close has occurred.
/// </para>
/// <para>
/// The lpFlags parameter can be used to influence the behavior of the function invocation beyond the options specified for the
/// associated socket. That is, the semantics of this function are determined by the socket options and the lpFlags parameter. The
/// latter is constructed by using the bitwise OR operator with any of the values listed in the following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>MSG_PEEK</term>
/// <term>
/// Peeks 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 nonoverlapped sockets.
/// </term>
/// </item>
/// <item>
/// <term>MSG_OOB</term>
/// <term>Processes OOB data.</term>
/// </item>
/// <item>
/// <term>MSG_PARTIAL</term>
/// <term>
/// This flag is for message-oriented sockets only. On output, this flag indicates that the data specified is a portion of the
/// message transmitted by the sender. Remaining portions of the message will be specified in subsequent receive operations. A
/// subsequent receive operation with the MSG_PARTIAL flag cleared indicates end of sender's message. As an input parameter, this
/// flag indicates that the receive operation should complete even if only part of a message has been received by the transport provider.
/// </term>
/// </item>
/// <item>
/// <term>MSG_PUSH_IMMEDIATE</term>
/// <term>
/// This flag is for stream-oriented sockets only. This flag allows an application that uses stream sockets to tell the transport
/// provider not to delay completion of partially filled pending receive requests. This is a hint to the transport provider that the
/// application is willing to receive any incoming data as soon as possible without necessarily waiting for the remainder of the
/// data that might still be in transit. What constitutes a partially filled pending receive request is a transport-specific matter.
/// In the case of TCP, this refers to the case of incoming TCP segments being placed into the receive request data buffer where
/// none of the TCP segments indicated a PUSH bit value of 1. In this case, TCP may hold the partially filled receive request a
/// little longer to allow the remainder of the data to arrive with a TCP segment that has the PUSH bit set to 1. This flag tells
/// TCP not to hold the receive request but to complete it immediately. Using this flag for large block transfers is not recommended
/// since processing partial blocks is often not optimal. This flag is useful only for cases where receiving and processing the
/// partial data immediately helps decrease processing latency. This flag is a hint rather than an actual guarantee. This flag is
/// supported on Windows 8.1, Windows Server 2012 R2, and later.
/// </term>
/// </item>
/// <item>
/// <term>MSG_WAITALL</term>
/// <term>
/// The receive request will complete only when one of the following events occurs: Be aware that if the underlying transport
/// provider does not support MSG_WAITALL, or if the socket is in a non-blocking mode, then this call will fail with WSAEOPNOTSUPP.
/// Also, if MSG_WAITALL is specified along with MSG_OOB, MSG_PEEK, or MSG_PARTIAL, then this call will fail with WSAEOPNOTSUPP.
/// This flag is not supported on datagram sockets or message-oriented sockets.
/// </term>
/// </item>
/// </list>
/// <para>
/// For message-oriented sockets, the <c>MSG_PARTIAL</c> bit is set in the lpFlags parameter if a partial message is received. If a
/// complete message is received, <c>MSG_PARTIAL</c> is cleared in lpFlags. In the case of delayed completion, the value pointed to
/// by lpFlags is not updated. When completion has been indicated, the application should call WSAGetOverlappedResult and examine
/// the flags indicated by the lpdwFlags parameter.
/// </para>
/// <para>
/// <c>Note</c> When issuing a blocking Winsock call such as <c>WSARecv</c> 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.
/// </para>
/// <para>Overlapped Socket I/O</para>
/// <para>
/// If an overlapped operation completes immediately, <c>WSARecv</c> 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, <c>WSARecv</c> returns <c>SOCKET_ERROR</c> and indicates
/// error code WSA_IO_PENDING. In this case, lpNumberOfBytesRecvd and lpFlags are 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 <c>WSAGetOverlappedResult</c>.
/// </para>
/// <para>
/// The <c>WSARecv</c> function using overlapped I/O can be called from within the completion routine of a previous <c>WSARecv</c>,
/// WSARecvFrom, WSASend 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.
/// </para>
/// <para>
/// 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.
/// </para>
/// <para>
/// If the lpCompletionRoutine parameter is <c>NULL</c>, 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.
/// </para>
/// <para>
/// If lpCompletionRoutine is not <c>NULL</c>, 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- <c>NULL</c> lpCompletionRoutine and later calls
/// WSAGetOverlappedResult for the same overlapped I/O request may not set the fWait parameter for that invocation of
/// <c>WSAGetOverlappedResult</c> to <c>TRUE</c>. In this case the usage of the hEvent parameter is undefined, and attempting to
/// wait on the hEvent parameter would produce unpredictable results.
/// </para>
/// <para>
/// 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 <c>TRUE</c> is invoked.
/// </para>
/// <para>The prototype of the completion routine is as follows:</para>
/// <para>
/// CompletionRoutine is a placeholder for an application-defined or library-defined function name. The dwError specifies the
/// completion status for the overlapped operation as indicated by lpOverlapped. The cbTransferred parameter specifies the number of
/// bytes received. The dwFlags parameter contains information that would have appeared in lpFlags if the receive operation had
/// completed immediately. This function does not return a value.
/// </para>
/// <para>
/// 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 <c>WSA_IO_COMPLETION</c>. 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.
/// </para>
/// <para>
/// If you are using I/O completion ports, be aware that the order of calls made to <c>WSARecv</c> is also the order in which the
/// buffers are populated. <c>WSARecv</c> should not be called on the same socket simultaneously from different threads, because it
/// can result in an unpredictable buffer order.
/// </para>
/// <para>Example Code</para>
/// <para>The following example shows how to use the <c>WSARecv</c> function in overlapped I/O mode.</para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsarecv int WSAAPI WSARecv( SOCKET s, LPWSABUF lpBuffers,
// DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, LPWSAOVERLAPPED lpOverlapped,
// LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "bfe66e11-e9a7-4321-ad55-3141113e9a03")]
public static extern WSRESULT WSARecv(SOCKET s, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] WSABUF[] lpBuffers,
uint dwBufferCount, out uint lpNumberOfBytesRecvd, ref MsgFlags lpFlags, ref WSAOVERLAPPED lpOverlapped,
[In, Optional, MarshalAs(UnmanagedType.FunctionPtr)] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
/// <summary>
/// The <c>WSARecvDisconnect</c> function terminates reception on a socket, and retrieves the disconnect data if the socket is
/// connection oriented.
/// </summary>
/// <param name="s">A descriptor identifying a socket.</param>
/// <param name="lpInboundDisconnectData">A pointer to the incoming disconnect data.</param>
/// <returns>
/// <para>
/// If no error occurs, <c>WSARecvDisconnect</c> returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error
/// code can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The buffer referenced by the parameter lpInboundDisconnectData is too small.</term>
/// </item>
/// <item>
/// <term>WSAENOPROTOOPT</term>
/// <term>
/// The disconnect data is not supported by the indicated protocol family. Note that implementations of TCP/IP that do not support
/// disconnect data are not required to return the WSAENOPROTOOPT error code. See the remarks section for information about the
/// Microsoft implementation of TCP/IP.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAENOTCONN</term>
/// <term>The socket is not connected (connection-oriented sockets only).</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSARecvDisconnect</c> function is used on connection-oriented sockets to disable reception and retrieve any incoming
/// disconnect data from the remote party. This is equivalent to a shutdown (SD_RECEIVE), except that <c>WSARecvDisconnect</c> also
/// allows receipt of disconnect data (in protocols that support it).
/// </para>
/// <para>
/// After this function has been successfully issued, subsequent receives on the socket will be disallowed. Calling
/// <c>WSARecvDisconnect</c> has no effect on the lower protocol layers. For TCP sockets, if there is still data queued on the
/// socket waiting to be received, or data arrives subsequently, the connection is reset, since the data cannot be delivered to the
/// user. For UDP, incoming datagrams are accepted and queued. In no case will an ICMP error packet be generated.
/// </para>
/// <para>
/// <c>Note</c> The native implementation of TCP/IP on Windows does not support disconnect data. Disconnect data is only supported
/// with Windows Sockets providers that have the XP1_DISCONNECT_DATA flag in their WSAPROTOCOL_INFO structure. Use the
/// WSAEnumProtocols function to obtain <c>WSAPROTOCOL_INFO</c> structures for all installed providers.
/// </para>
/// <para>
/// To successfully receive incoming disconnect data, an application must use other mechanisms to determine that the circuit has
/// been closed. For example, an application needs to receive an FD_CLOSE notification, to receive a zero return value, or to
/// receive a WSAEDISCON or WSAECONNRESET error code from recv/WSARecv.
/// </para>
/// <para>
/// The <c>WSARecvDisconnect</c> function does not close the socket, and resources attached to the socket will not be freed until
/// closesocket is invoked.
/// </para>
/// <para>The <c>WSARecvDisconnect</c> function does not block regardless of the SO_LINGER setting on the socket.</para>
/// <para>
/// An application should not rely on being able to reuse a socket after it has been disconnected using <c>WSARecvDisconnect</c>. In
/// particular, a Windows Sockets provider is not required to support the use of connect or WSAConnect on such a socket.
/// </para>
/// <para>
/// <c>Note</c> When issuing a blocking Winsock call such as <c>WSARecvDisconnect</c>, 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.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsarecvdisconnect int WSAAPI WSARecvDisconnect( SOCKET s,
// LPWSABUF lpInboundDisconnectData );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "33e0fb8e-3ece-427f-b3ef-43a0f5cf0cc8")]
public static extern WSRESULT WSARecvDisconnect(SOCKET s, [In, Out, Optional] IntPtr lpInboundDisconnectData);
/// <summary>The <c>WSARecvFrom</c> function receives a datagram and stores the source address.</summary>
/// <param name="s">A descriptor identifying a socket.</param>
/// <param name="lpBuffers">
/// A pointer to an array of WSABUF structures. Each <c>WSABUF</c> structure contains a pointer to a buffer and the length of the buffer.
/// </param>
/// <param name="dwBufferCount">The number of WSABUF structures in the lpBuffers array.</param>
/// <param name="lpNumberOfBytesRecvd">
/// <para>A pointer to the number of bytes received by this call if the <c>WSARecvFrom</c> operation completes immediately.</para>
/// <para>
/// Use <c>NULL</c> for this parameter if the lpOverlapped parameter is not <c>NULL</c> to avoid potentially erroneous results. This
/// parameter can be <c>NULL</c> only if the lpOverlapped parameter is not <c>NULL</c>.
/// </para>
/// </param>
/// <param name="lpFlags">A pointer to flags used to modify the behavior of the <c>WSARecvFrom</c> function call. See remarks below.</param>
/// <param name="lpFrom">
/// An optional pointer to a buffer that will hold the source address upon the completion of the overlapped operation.
/// </param>
/// <param name="lpFromlen">A pointer to the size, in bytes, of the "from" buffer required only if lpFrom is specified.</param>
/// <param name="lpOverlapped">A pointer to a WSAOVERLAPPED structure (ignored for nonoverlapped sockets).</param>
/// <param name="lpCompletionRoutine">
/// A pointer to the completion routine called when the <c>WSARecvFrom</c> operation has been completed (ignored for nonoverlapped sockets).
/// </param>
/// <returns>
/// <para>
/// If no error occurs and the receive operation has completed immediately, <c>WSARecvFrom</c> 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 <c>SOCKET_ERROR</c> is returned, and a specific error code can be retrieved by calling WSAGetLastError. The error code
/// <c>WSA_IO_PENDING</c> 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.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAECONNRESET</term>
/// <term>
/// 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. For a UPD datagram socket, this error would indicate that a previous send operation resulted in an ICMP
/// "Port Unreachable" message.
/// </term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEINTR</term>
/// <term>A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>The socket has not been bound (with bind, for example).</term>
/// </item>
/// <item>
/// <term>WSAEMSGSIZE</term>
/// <term>
/// The message was too large for the specified buffer and (for unreliable protocols only) any trailing portion of the message that
/// did not fit into the buffer has been discarded.
/// </term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENETRESET</term>
/// <term>For a datagram socket, this error indicates that the time to live has expired.</term>
/// </item>
/// <item>
/// <term>WSAENOTCONN</term>
/// <term>The socket is not connected (connection-oriented sockets only).</term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>
/// Windows NT: Overlapped sockets: There are too many outstanding overlapped I/O requests. Nonoverlapped sockets: The socket is
/// marked as nonblocking and the receive operation cannot be completed immediately.
/// </term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSA_IO_PENDING</term>
/// <term>An overlapped operation was successfully initiated and completion will be indicated later.</term>
/// </item>
/// <item>
/// <term>WSA_OPERATION_ABORTED</term>
/// <term>The overlapped operation has been canceled due to the closure of the socket.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSARecvFrom</c> function provides functionality over and above the standard recvfrom function in three important areas:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>It can be used in conjunction with overlapped sockets to perform overlapped receive operations.</term>
/// </item>
/// <item>
/// <term>It allows multiple receive buffers to be specified making it applicable to the scatter/gather type of I/O.</term>
/// </item>
/// <item>
/// <term>
/// The lpFlags parameter is both an input and an output parameter, allowing applications to sense the output state of the
/// <c>MSG_PARTIAL</c> flag bit. Be aware that the <c>MSG_PARTIAL</c> flag bit is not supported by all protocols.
/// </term>
/// </item>
/// </list>
/// <para>
/// The <c>WSARecvFrom</c> function is used primarily on a connectionless socket specified by s. The socket's local address must be
/// known. For server applications, this is usually done explicitly through bind. Explicit binding is discouraged for client
/// applications. For client applications using this function the socket can become bound implicitly to a local address through
/// sendto, WSASendTo, or WSAJoinLeaf.
/// </para>
/// <para>
/// For overlapped sockets, this function is used to post one or more buffers into which incoming data will be placed as it becomes
/// available on a (possibly connected) socket, 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 WSAGetOverlappedResult. Also, the values indicated by lpFrom and lpFromlen
/// are not updated until completion is itself indicated. Applications must not use or disturb these values until they have been
/// updated, therefore the application must not use automatic (that is, stack-based) variables for these parameters.
/// </para>
/// <para>
/// <c>Note</c> 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.
/// </para>
/// <para>
/// If both lpOverlapped and lpCompletionRoutine are <c>NULL</c>, the socket in this function will be treated as a nonoverlapped socket.
/// </para>
/// <para>
/// For nonoverlapped sockets, the blocking semantics are identical to that of the standard WSARecv 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 user buffers. For 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.
/// </para>
/// <para>
/// The buffers are filled in the order in which they appear in the array indicated by lpBuffers, and the buffers are packed so that
/// no holes are created.
/// </para>
/// <para>
/// If this function is completed in an overlapped manner, it is the Winsock service provider's responsibility to capture the WSABUF
/// structures before returning from this call. This enables applications to build stack-based <c>WSABUF</c> arrays pointed to by
/// the lpBuffers parameter.
/// </para>
/// <para>
/// For connectionless socket types, the address from which the data originated is copied to the buffer indicated by lpFrom. The
/// value pointed to by lpFromlen is initialized to the size of this buffer, and is modified on completion to indicate the actual
/// size of the address stored there. As stated previously for overlapped sockets, the lpFrom and lpFromlen parameters are not
/// updated until after the overlapped I/O has completed. The memory pointed to by these parameters must, therefore, remain
/// available to the service provider and cannot be allocated on the application stack frame. The lpFrom and lpFromlen parameters
/// are ignored for connection-oriented sockets.
/// </para>
/// <para>For byte streamstyle sockets (for example, type SOCK_STREAM), incoming data is placed into the buffers until:</para>
/// <list type="bullet">
/// <item>
/// <term>The buffers are filled.</term>
/// </item>
/// <item>
/// <term>The connection is closed.</term>
/// </item>
/// <item>
/// <term>The internally buffered data is exhausted.</term>
/// </item>
/// </list>
/// <para>
/// Regardless of whether or not the incoming data fills all the buffers, the completion indication occurs for overlapped sockets.
/// For message-oriented sockets, 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. If the <c>MSG_PARTIAL</c> feature is supported by the underlying service provider, the
/// <c>MSG_PARTIAL</c> flag is set in lpFlags and subsequent receive operation(s) will retrieve the rest of the message. If
/// <c>MSG_PARTIAL</c> is not supported, but the protocol is reliable, <c>WSARecvFrom</c> generates the error WSAEMSGSIZE and a
/// subsequent receive operation with a larger buffer can be used to retrieve the entire message. Otherwise, (that is, the protocol
/// is unreliable and does not support <c>MSG_PARTIAL</c>), the excess data is lost, and <c>WSARecvFrom</c> generates the error WSAEMSGSIZE.
/// </para>
/// <para>
/// The lpFlags parameter can be used to influence the behavior of the function invocation beyond the options specified for the
/// associated socket. That is, the semantics of this function are determined by the socket options and the lpFlags parameter. The
/// latter is constructed by using the bitwise OR operator with any of any of the values listed in the following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>MSG_PEEK</term>
/// <term>
/// Previews the incoming data. The data is copied into the buffer, but is not removed from the input queue. This flag is valid only
/// for nonoverlapped sockets.
/// </term>
/// </item>
/// <item>
/// <term>MSG_OOB</term>
/// <term>Processes OOB data.</term>
/// </item>
/// <item>
/// <term>MSG_PARTIAL</term>
/// <term>
/// This flag is for message-oriented sockets only. On output, this flag indicates that the data is a portion of the message
/// transmitted by the sender. Remaining portions of the message will be transmitted in subsequent receive operations. A subsequent
/// receive operation with MSG_PARTIAL flag cleared indicates the end of the sender's message. As an input parameter, this flag
/// indicates that the receive operation should complete even if only part of a message has been received by the service provider.
/// </term>
/// </item>
/// </list>
/// <para>
/// For message-oriented sockets, the <c>MSG_PARTIAL</c> bit is set in the lpFlags parameter if a partial message is received. If a
/// complete message is received, <c>MSG_PARTIAL</c> is cleared in lpFlags. In the case of delayed completion, the value pointed to
/// by lpFlags is not updated. When completion has been indicated the application should call WSAGetOverlappedResult and examine the
/// flags pointed to by the lpdwFlags parameter.
/// </para>
/// <para>
/// <c>Note</c> When issuing a blocking Winsock call such as <c>WSARecvFrom</c> 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.
/// </para>
/// <para>Overlapped Socket I/O</para>
/// <para>
/// If an overlapped operation completes immediately, <c>WSARecvFrom</c> returns a value of zero and the lpNumberOfBytesRecvd
/// parameter is updated with the number of bytes received and the flag bits pointed by the lpFlags parameter are also updated. If
/// the overlapped operation is successfully initiated and will complete later, <c>WSARecvFrom</c> returns <c>SOCKET_ERROR</c> and
/// indicates error code <c>WSA_IO_PENDING</c>. In this case, lpNumberOfBytesRecvd and lpFlags 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 either through
/// the dwFlags parameter of the completion routine, or by examining the lpdwFlags parameter of <c>WSAGetOverlappedResult</c>.
/// </para>
/// <para>
/// The <c>WSARecvFrom</c> function can be called from within the completion routine of a previous WSARecv, <c>WSARecvFrom</c>,
/// WSASend, 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.
/// </para>
/// <para>
/// 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.
/// </para>
/// <para>
/// If the lpCompletionRoutine parameter is <c>NULL</c>, 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.
/// </para>
/// <para>
/// If lpCompletionRoutine is not <c>NULL</c>, 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- <c>NULL</c> lpCompletionRoutine and later calls
/// WSAGetOverlappedResult for the same overlapped I/O request may not set the fWait parameter for that invocation of
/// <c>WSAGetOverlappedResult</c> to <c>TRUE</c>. In this case the usage of the hEvent parameter is undefined, and attempting to
/// wait on the hEvent parameter would produce unpredictable results.
/// </para>
/// <para>
/// 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 <c>TRUE</c> is invoked.
/// </para>
/// <para>
/// The transport providers allow an application to invoke send and receive operations from within the context of the socket I/O
/// completion routine, and guarantee that, 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.
/// </para>
/// <para>The prototype of the completion routine is as follows.</para>
/// <para>
/// The <c>CompletionRoutine</c> is a placeholder for an application-defined or library-defined function name. The dwError specifies
/// the completion status for the overlapped operation as indicated by lpOverlapped. The cbTransferred specifies the number of bytes
/// received. The dwFlags parameter contains information that would have appeared in lpFlags if the receive operation had completed
/// immediately. This function does not return a value.
/// </para>
/// <para>
/// 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 they are specified.
/// </para>
/// <para>Example Code</para>
/// <para>The following example demonstrates the use of the <c>WSARecvFrom</c> function.</para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsarecvfrom int WSAAPI WSARecvFrom( SOCKET s, LPWSABUF
// lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, sockaddr *lpFrom, LPINT lpFromlen, LPWSAOVERLAPPED
// lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "8617dbb8-0e4e-4cd3-9597-5d20de6778f6")]
public static extern WSRESULT WSARecvFrom(SOCKET s, [In, Out, Optional, MarshalAs(UnmanagedType.LPArray)] WSABUF[] lpBuffers, uint dwBufferCount, out uint lpNumberOfBytesRecvd, ref MsgFlags lpFlags,
[Out] SOCKADDR lpFrom, ref int lpFromlen, [In, Out, Optional] IntPtr lpOverlapped, [In, Optional, MarshalAs(UnmanagedType.FunctionPtr)] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
/// <summary>The <c>WSARecvFrom</c> function receives a datagram and stores the source address.</summary>
/// <param name="s">A descriptor identifying a socket.</param>
/// <param name="lpBuffers">
/// A pointer to an array of WSABUF structures. Each <c>WSABUF</c> structure contains a pointer to a buffer and the length of the buffer.
/// </param>
/// <param name="dwBufferCount">The number of WSABUF structures in the lpBuffers array.</param>
/// <param name="lpNumberOfBytesRecvd">
/// <para>A pointer to the number of bytes received by this call if the <c>WSARecvFrom</c> operation completes immediately.</para>
/// <para>
/// Use <c>NULL</c> for this parameter if the lpOverlapped parameter is not <c>NULL</c> to avoid potentially erroneous results. This
/// parameter can be <c>NULL</c> only if the lpOverlapped parameter is not <c>NULL</c>.
/// </para>
/// </param>
/// <param name="lpFlags">A pointer to flags used to modify the behavior of the <c>WSARecvFrom</c> function call. See remarks below.</param>
/// <param name="lpFrom">
/// An optional pointer to a buffer that will hold the source address upon the completion of the overlapped operation.
/// </param>
/// <param name="lpFromlen">A pointer to the size, in bytes, of the "from" buffer required only if lpFrom is specified.</param>
/// <param name="lpOverlapped">A pointer to a WSAOVERLAPPED structure (ignored for nonoverlapped sockets).</param>
/// <param name="lpCompletionRoutine">
/// A pointer to the completion routine called when the <c>WSARecvFrom</c> operation has been completed (ignored for nonoverlapped sockets).
/// </param>
/// <returns>
/// <para>
/// If no error occurs and the receive operation has completed immediately, <c>WSARecvFrom</c> 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 <c>SOCKET_ERROR</c> is returned, and a specific error code can be retrieved by calling WSAGetLastError. The error code
/// <c>WSA_IO_PENDING</c> 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.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAECONNRESET</term>
/// <term>
/// 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. For a UPD datagram socket, this error would indicate that a previous send operation resulted in an ICMP
/// "Port Unreachable" message.
/// </term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEINTR</term>
/// <term>A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>The socket has not been bound (with bind, for example).</term>
/// </item>
/// <item>
/// <term>WSAEMSGSIZE</term>
/// <term>
/// The message was too large for the specified buffer and (for unreliable protocols only) any trailing portion of the message that
/// did not fit into the buffer has been discarded.
/// </term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENETRESET</term>
/// <term>For a datagram socket, this error indicates that the time to live has expired.</term>
/// </item>
/// <item>
/// <term>WSAENOTCONN</term>
/// <term>The socket is not connected (connection-oriented sockets only).</term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>
/// Windows NT: Overlapped sockets: There are too many outstanding overlapped I/O requests. Nonoverlapped sockets: The socket is
/// marked as nonblocking and the receive operation cannot be completed immediately.
/// </term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSA_IO_PENDING</term>
/// <term>An overlapped operation was successfully initiated and completion will be indicated later.</term>
/// </item>
/// <item>
/// <term>WSA_OPERATION_ABORTED</term>
/// <term>The overlapped operation has been canceled due to the closure of the socket.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSARecvFrom</c> function provides functionality over and above the standard recvfrom function in three important areas:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>It can be used in conjunction with overlapped sockets to perform overlapped receive operations.</term>
/// </item>
/// <item>
/// <term>It allows multiple receive buffers to be specified making it applicable to the scatter/gather type of I/O.</term>
/// </item>
/// <item>
/// <term>
/// The lpFlags parameter is both an input and an output parameter, allowing applications to sense the output state of the
/// <c>MSG_PARTIAL</c> flag bit. Be aware that the <c>MSG_PARTIAL</c> flag bit is not supported by all protocols.
/// </term>
/// </item>
/// </list>
/// <para>
/// The <c>WSARecvFrom</c> function is used primarily on a connectionless socket specified by s. The socket's local address must be
/// known. For server applications, this is usually done explicitly through bind. Explicit binding is discouraged for client
/// applications. For client applications using this function the socket can become bound implicitly to a local address through
/// sendto, WSASendTo, or WSAJoinLeaf.
/// </para>
/// <para>
/// For overlapped sockets, this function is used to post one or more buffers into which incoming data will be placed as it becomes
/// available on a (possibly connected) socket, 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 WSAGetOverlappedResult. Also, the values indicated by lpFrom and lpFromlen
/// are not updated until completion is itself indicated. Applications must not use or disturb these values until they have been
/// updated, therefore the application must not use automatic (that is, stack-based) variables for these parameters.
/// </para>
/// <para>
/// <c>Note</c> 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.
/// </para>
/// <para>
/// If both lpOverlapped and lpCompletionRoutine are <c>NULL</c>, the socket in this function will be treated as a nonoverlapped socket.
/// </para>
/// <para>
/// For nonoverlapped sockets, the blocking semantics are identical to that of the standard WSARecv 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 user buffers. For 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.
/// </para>
/// <para>
/// The buffers are filled in the order in which they appear in the array indicated by lpBuffers, and the buffers are packed so that
/// no holes are created.
/// </para>
/// <para>
/// If this function is completed in an overlapped manner, it is the Winsock service provider's responsibility to capture the WSABUF
/// structures before returning from this call. This enables applications to build stack-based <c>WSABUF</c> arrays pointed to by
/// the lpBuffers parameter.
/// </para>
/// <para>
/// For connectionless socket types, the address from which the data originated is copied to the buffer indicated by lpFrom. The
/// value pointed to by lpFromlen is initialized to the size of this buffer, and is modified on completion to indicate the actual
/// size of the address stored there. As stated previously for overlapped sockets, the lpFrom and lpFromlen parameters are not
/// updated until after the overlapped I/O has completed. The memory pointed to by these parameters must, therefore, remain
/// available to the service provider and cannot be allocated on the application stack frame. The lpFrom and lpFromlen parameters
/// are ignored for connection-oriented sockets.
/// </para>
/// <para>For byte streamstyle sockets (for example, type SOCK_STREAM), incoming data is placed into the buffers until:</para>
/// <list type="bullet">
/// <item>
/// <term>The buffers are filled.</term>
/// </item>
/// <item>
/// <term>The connection is closed.</term>
/// </item>
/// <item>
/// <term>The internally buffered data is exhausted.</term>
/// </item>
/// </list>
/// <para>
/// Regardless of whether or not the incoming data fills all the buffers, the completion indication occurs for overlapped sockets.
/// For message-oriented sockets, 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. If the <c>MSG_PARTIAL</c> feature is supported by the underlying service provider, the
/// <c>MSG_PARTIAL</c> flag is set in lpFlags and subsequent receive operation(s) will retrieve the rest of the message. If
/// <c>MSG_PARTIAL</c> is not supported, but the protocol is reliable, <c>WSARecvFrom</c> generates the error WSAEMSGSIZE and a
/// subsequent receive operation with a larger buffer can be used to retrieve the entire message. Otherwise, (that is, the protocol
/// is unreliable and does not support <c>MSG_PARTIAL</c>), the excess data is lost, and <c>WSARecvFrom</c> generates the error WSAEMSGSIZE.
/// </para>
/// <para>
/// The lpFlags parameter can be used to influence the behavior of the function invocation beyond the options specified for the
/// associated socket. That is, the semantics of this function are determined by the socket options and the lpFlags parameter. The
/// latter is constructed by using the bitwise OR operator with any of any of the values listed in the following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>MSG_PEEK</term>
/// <term>
/// Previews the incoming data. The data is copied into the buffer, but is not removed from the input queue. This flag is valid only
/// for nonoverlapped sockets.
/// </term>
/// </item>
/// <item>
/// <term>MSG_OOB</term>
/// <term>Processes OOB data.</term>
/// </item>
/// <item>
/// <term>MSG_PARTIAL</term>
/// <term>
/// This flag is for message-oriented sockets only. On output, this flag indicates that the data is a portion of the message
/// transmitted by the sender. Remaining portions of the message will be transmitted in subsequent receive operations. A subsequent
/// receive operation with MSG_PARTIAL flag cleared indicates the end of the sender's message. As an input parameter, this flag
/// indicates that the receive operation should complete even if only part of a message has been received by the service provider.
/// </term>
/// </item>
/// </list>
/// <para>
/// For message-oriented sockets, the <c>MSG_PARTIAL</c> bit is set in the lpFlags parameter if a partial message is received. If a
/// complete message is received, <c>MSG_PARTIAL</c> is cleared in lpFlags. In the case of delayed completion, the value pointed to
/// by lpFlags is not updated. When completion has been indicated the application should call WSAGetOverlappedResult and examine the
/// flags pointed to by the lpdwFlags parameter.
/// </para>
/// <para>
/// <c>Note</c> When issuing a blocking Winsock call such as <c>WSARecvFrom</c> 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.
/// </para>
/// <para>Overlapped Socket I/O</para>
/// <para>
/// If an overlapped operation completes immediately, <c>WSARecvFrom</c> returns a value of zero and the lpNumberOfBytesRecvd
/// parameter is updated with the number of bytes received and the flag bits pointed by the lpFlags parameter are also updated. If
/// the overlapped operation is successfully initiated and will complete later, <c>WSARecvFrom</c> returns <c>SOCKET_ERROR</c> and
/// indicates error code <c>WSA_IO_PENDING</c>. In this case, lpNumberOfBytesRecvd and lpFlags 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 either through
/// the dwFlags parameter of the completion routine, or by examining the lpdwFlags parameter of <c>WSAGetOverlappedResult</c>.
/// </para>
/// <para>
/// The <c>WSARecvFrom</c> function can be called from within the completion routine of a previous WSARecv, <c>WSARecvFrom</c>,
/// WSASend, 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.
/// </para>
/// <para>
/// 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.
/// </para>
/// <para>
/// If the lpCompletionRoutine parameter is <c>NULL</c>, 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.
/// </para>
/// <para>
/// If lpCompletionRoutine is not <c>NULL</c>, 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- <c>NULL</c> lpCompletionRoutine and later calls
/// WSAGetOverlappedResult for the same overlapped I/O request may not set the fWait parameter for that invocation of
/// <c>WSAGetOverlappedResult</c> to <c>TRUE</c>. In this case the usage of the hEvent parameter is undefined, and attempting to
/// wait on the hEvent parameter would produce unpredictable results.
/// </para>
/// <para>
/// 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 <c>TRUE</c> is invoked.
/// </para>
/// <para>
/// The transport providers allow an application to invoke send and receive operations from within the context of the socket I/O
/// completion routine, and guarantee that, 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.
/// </para>
/// <para>The prototype of the completion routine is as follows.</para>
/// <para>
/// The <c>CompletionRoutine</c> is a placeholder for an application-defined or library-defined function name. The dwError specifies
/// the completion status for the overlapped operation as indicated by lpOverlapped. The cbTransferred specifies the number of bytes
/// received. The dwFlags parameter contains information that would have appeared in lpFlags if the receive operation had completed
/// immediately. This function does not return a value.
/// </para>
/// <para>
/// 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 they are specified.
/// </para>
/// <para>Example Code</para>
/// <para>The following example demonstrates the use of the <c>WSARecvFrom</c> function.</para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsarecvfrom int WSAAPI WSARecvFrom( SOCKET s, LPWSABUF
// lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, sockaddr *lpFrom, LPINT lpFromlen, LPWSAOVERLAPPED
// lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "8617dbb8-0e4e-4cd3-9597-5d20de6778f6")]
public static extern WSRESULT WSARecvFrom(SOCKET s, [In, Out, Optional, MarshalAs(UnmanagedType.LPArray)] WSABUF[] lpBuffers, uint dwBufferCount, out uint lpNumberOfBytesRecvd, ref MsgFlags lpFlags,
[Out] SOCKADDR lpFrom, ref int lpFromlen, ref WSAOVERLAPPED lpOverlapped, [In, Optional, MarshalAs(UnmanagedType.FunctionPtr)] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
/// <summary>The <c>WSARemoveServiceClass</c> function permanently removes the service class schema from the registry.</summary>
/// <param name="lpServiceClassId">Pointer to the GUID for the service class you want to remove.</param>
/// <returns>
/// <para>
/// The return value is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is returned, and a specific error
/// number can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSATYPE_NOT_FOUND</term>
/// <term>The specified class was not found.</term>
/// </item>
/// <item>
/// <term>WSAEACCES</term>
/// <term>The calling routine does not have sufficient privileges to remove the Service.</term>
/// </item>
/// <item>
/// <term>WSAETOOMANYREFS</term>
/// <term>There are service instances that still reference the class. Removal of this class is not possible at this time.</term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>
/// The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>The specified GUID was not valid.</term>
/// </item>
/// <item>
/// <term>WSA_NOT_ENOUGH_MEMORY</term>
/// <term>There was insufficient memory to perform the operation.</term>
/// </item>
/// </list>
/// </returns>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaremoveserviceclass INT WSAAPI WSARemoveServiceClass(
// LPGUID lpServiceClassId );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "7d72f727-cca9-4a07-beb4-d64f23c1f0c1")]
public static extern WSRESULT WSARemoveServiceClass(in Guid lpServiceClassId);
/// <summary>The <c>WSAResetEvent</c> function resets the state of the specified event object to nonsignaled.</summary>
/// <param name="hEvent">A handle that identifies an open event object handle.</param>
/// <returns>
/// <para>
/// If the <c>WSAResetEvent</c> function succeeds, the return value is <c>TRUE</c>. If the function fails, the return value is
/// <c>FALSE</c>. To get extended error information, call WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSA_INVALID_HANDLE</term>
/// <term>The hEvent parameter is not a valid event object handle.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>The <c>WSAResetEvent</c> function is used to set the state of the event object to nonsignaled.</para>
/// <para>
/// The proper way to reset the state of an event object used with the WSAEventSelect function is to pass the handle of the event
/// object to the WSAEnumNetworkEvents function in the hEventObject parameter. This will reset the event object and adjust the
/// status of active FD events on the socket in an atomic fashion.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaresetevent BOOL WSAAPI WSAResetEvent( WSAEVENT hEvent );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "99a8b0f3-977f-44cd-a224-0819d7513c90")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WSAResetEvent(WSAEVENT hEvent);
/// <summary>The <c>WSASend</c> function sends data on a connected socket.</summary>
/// <param name="s">A descriptor that identifies a connected socket.</param>
/// <param name="lpBuffers">
/// A pointer to an array of WSABUF structures. Each <c>WSABUF</c> structure contains a pointer to a buffer and the length, in
/// bytes, of the buffer. For a Winsock application, once the <c>WSASend</c> function is called, the system owns these buffers and
/// the application may not access them. This array must remain valid for the duration of the send operation.
/// </param>
/// <param name="dwBufferCount">The number of WSABUF structures in the lpBuffers array.</param>
/// <param name="lpNumberOfBytesSent">
/// <para>A pointer to the number, in bytes, sent by this call if the I/O operation completes immediately.</para>
/// <para>
/// Use <c>NULL</c> for this parameter if the lpOverlapped parameter is not <c>NULL</c> to avoid potentially erroneous results. This
/// parameter can be <c>NULL</c> only if the lpOverlapped parameter is not <c>NULL</c>.
/// </para>
/// </param>
/// <param name="dwFlags">
/// The flags used to modify the behavior of the <c>WSASend</c> function call. For more information, see Using dwFlags in the
/// Remarks section.
/// </param>
/// <param name="lpOverlapped">A pointer to a WSAOVERLAPPED structure. This parameter is ignored for nonoverlapped sockets.</param>
/// <param name="lpCompletionRoutine">
/// A pointer to the completion routine called when the send operation has been completed. This parameter is ignored for
/// nonoverlapped sockets.
/// </param>
/// <returns>
/// <para>
/// If no error occurs and the send operation has completed immediately, <c>WSASend</c> 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
/// <c>SOCKET_ERROR</c> 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 overlapped operation was not successfully initiated and no completion
/// indication will occur.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAECONNABORTED</term>
/// <term>The virtual circuit was terminated due to a time-out or other failure.</term>
/// </item>
/// <item>
/// <term>WSAECONNRESET</term>
/// <term>
/// For a stream socket, the virtual circuit was reset by the remote side. The application should close the socket as it is no
/// longer usable. For a UDP datagram socket, this error would indicate that a previous send operation resulted in an ICMP "Port
/// Unreachable" message.
/// </term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The lpBuffers, lpNumberOfBytesSent, lpOverlapped, lpCompletionRoutine parameter is not totally contained in a valid part of the
/// user address space.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINTR</term>
/// <term>A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>The socket has not been bound with bind or the socket is not created with the overlapped flag.</term>
/// </item>
/// <item>
/// <term>WSAEMSGSIZE</term>
/// <term>The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENETRESET</term>
/// <term>
/// For a stream socket, the connection has been broken due to keep-alive activity detecting a failure while the operation was in
/// progress. For a datagram socket, this error indicates that the time to live has expired.
/// </term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>The Windows Sockets provider reports a buffer deadlock.</term>
/// </item>
/// <item>
/// <term>WSAENOTCONN</term>
/// <term>The socket is not connected.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEOPNOTSUPP</term>
/// <term>
/// 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, MSG_PARTIAL is not supported, or the socket is unidirectional and supports
/// only receive operations.
/// </term>
/// </item>
/// <item>
/// <term>WSAESHUTDOWN</term>
/// <term>
/// The socket has been shut down; it is not possible to WSASend on a socket after shutdown has been invoked with how set to SD_SEND
/// or SD_BOTH.
/// </term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>
/// Windows NT: Overlapped sockets: There are too many outstanding overlapped I/O requests. Nonoverlapped sockets: The socket is
/// marked as nonblocking and the send operation cannot be completed immediately.
/// </term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSA_IO_PENDING</term>
/// <term>An overlapped operation was successfully initiated and completion will be indicated at a later time.</term>
/// </item>
/// <item>
/// <term>WSA_OPERATION_ABORTED</term>
/// <term>
/// 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. For more information, see
/// the Remarks section.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>The <c>WSASend</c> function provides functionality over and above the standard send function in two important areas:</para>
/// <list type="bullet">
/// <item>
/// <term>It can be used in conjunction with overlapped sockets to perform overlapped send operations.</term>
/// </item>
/// <item>
/// <term>It allows multiple send buffers to be specified making it applicable to the scatter/gather type of I/O.</term>
/// </item>
/// </list>
/// <para>
/// The <c>WSASend</c> function is used to write outgoing data from one or more buffers on a connection-oriented socket specified by
/// s. It can also be used, however, on connectionless sockets that have a stipulated default peer address established through the
/// connect or WSAConnect function.
/// </para>
/// <para>
/// A socket created by the socket function will have the overlapped attribute as the default. A socket created by the WSASocket
/// function with the dwFlags parameter passed to <c>WSASocket</c> with the <c>WSA_FLAG_OVERLAPPED</c> bit set will have the
/// overlapped attribute. For sockets with the overlapped attribute, <c>WSASend</c> uses overlapped I/O unless both the lpOverlapped
/// and lpCompletionRoutine parameters are <c>NULL</c>. In that case, the socket is treated as a non-overlapped socket. A completion
/// indication will occur, invoking the completion of a routine or setting of an event object, when the buffer(s) have been consumed
/// by the transport. If the operation does not complete immediately, the final completion status is retrieved through the
/// completion routine or WSAGetOverlappedResult.
/// </para>
/// <para>
/// If both lpOverlapped and lpCompletionRoutine are <c>NULL</c>, the socket in this function will be treated as a non-overlapped socket.
/// </para>
/// <para>
/// For non-overlapped sockets, the last two parameters (lpOverlapped, lpCompletionRoutine) are ignored and <c>WSASend</c> adopts
/// the same blocking semantics as send. Data is copied from the buffer(s) into the transport's buffer. If the socket is
/// non-blocking and stream-oriented, and there is not sufficient space in the transport's buffer, <c>WSASend</c> will return with
/// only part of the application's buffers having been consumed. Given the same buffer situation and a blocking socket,
/// <c>WSASend</c> will block until all of the application buffer contents have been consumed.
/// </para>
/// <para><c>Note</c> The socket options <c>SO_RCVTIMEO</c> and <c>SO_SNDTIMEO</c> apply only to blocking sockets.</para>
/// <para>
/// If this function is completed in an overlapped manner, it is the Winsock service provider's responsibility to capture the WSABUF
/// structures before returning from this call. This enables applications to build stack-based <c>WSABUF</c> arrays pointed to by
/// the lpBuffers parameter.
/// </para>
/// <para>
/// For message-oriented sockets, do not exceed the maximum message size of the underlying provider, which can be obtained by
/// getting the value of socket option <c>SO_MAX_MSG_SIZE</c>. If the data is too long to pass atomically through the underlying
/// protocol the error WSAEMSGSIZE is returned, and no data is transmitted.
/// </para>
/// <para><c>Windows Me/98/95:</c> The <c>WSASend</c> function does not support more than 16 buffers.</para>
/// <para><c>Note</c> The successful completion of a <c>WSASend</c> does not indicate that the data was successfully delivered.</para>
/// <para>Using dwFlags</para>
/// <para>
/// The dwFlags parameter can be used to influence the behavior of the function invocation beyond the options specified for the
/// associated socket. That is, the semantics of this function are determined by the socket options and the dwFlags parameter. The
/// latter is constructed by using the bitwise OR operator with any of any of the values listed in the following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>MSG_DONTROUTE</term>
/// <term>
/// Specifies that the data should not be subject to routing. A Windows Sockets service provider can choose to ignore this flag.
/// </term>
/// </item>
/// <item>
/// <term>MSG_OOB</term>
/// <term>Send OOB data on a stream-style socket such as SOCK_STREAM only.</term>
/// </item>
/// <item>
/// <term>MSG_PARTIAL</term>
/// <term>
/// Specifies that lpBuffers only contains a partial message. Be aware that the error code WSAEOPNOTSUPP will be returned by
/// transports that do not support partial message transmissions.
/// </term>
/// </item>
/// </list>
/// <para>
/// <c>Note</c> When issuing a blocking Winsock call such as <c>WSASend</c> 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.
/// </para>
/// <para>Overlapped Socket I/O</para>
/// <para>
/// If an overlapped operation completes immediately, <c>WSASend</c> returns a value of zero and the lpNumberOfBytesSent parameter
/// is updated with the number of bytes sent. If the overlapped operation is successfully initiated and will complete later,
/// <c>WSASend</c> returns SOCKET_ERROR and indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesSent 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.
/// </para>
/// <para>
/// <c>Note</c> 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.
/// </para>
/// <para>
/// The <c>WSASend</c> function using overlapped I/O can be called from within the completion routine of a previous WSARecv,
/// WSARecvFrom, <c>WSASend</c>, or WSASendTo function. This enables time-sensitive data transmissions to occur entirely within a
/// preemptive context.
/// </para>
/// <para>
/// 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.
/// </para>
/// <para>
/// If the lpCompletionRoutine parameter is <c>NULL</c>, 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.
/// </para>
/// <para>
/// If lpCompletionRoutine is not <c>NULL</c>, 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- <c>NULL</c> lpCompletionRoutine and later calls
/// WSAGetOverlappedResult for the same overlapped I/O request may not set the fWait parameter for that invocation of
/// <c>WSAGetOverlappedResult</c> to <c>TRUE</c>. In this case the usage of the hEvent parameter is undefined, and attempting to
/// wait on the hEvent parameter would produce unpredictable results.
/// </para>
/// <para>
/// 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 <c>TRUE</c> is invoked.
/// </para>
/// <para>
/// The transport providers allow an application to invoke send and receive operations from within the context of the socket I/O
/// completion routine, and guarantee that, 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.
/// </para>
/// <para>The following C++ code example is a prototype of the completion routine.</para>
/// <para>
/// The CompletionRoutine function 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 lpOverlapped. cbTransferred specifies the
/// number of bytes sent. Currently there are no flag values defined and dwFlags will be zero. This function does not return a value.
/// </para>
/// <para>
/// Returning from this function allows invocation of another pending completion routine for this socket. All waiting completion
/// routines are called before the alertable thread's wait is satisfied with a return code of <c>WSA_IO_COMPLETION</c>. 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 sent in the same order they are specified.
/// </para>
/// <para>
/// The order of calls made to <c>WSASend</c> is also the order in which the buffers are transmitted to the transport layer.
/// <c>WSASend</c> should not be called on the same stream-oriented socket concurrently from different threads, because some Winsock
/// providers may split a large send request into multiple transmissions, and this may lead to unintended data interleaving from
/// multiple concurrent send requests on the same stream-oriented socket.
/// </para>
/// <para>Example Code</para>
/// <para>The following code example shows how to use the <c>WSASend</c> function in overlapped I/O mode.</para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasend int WSAAPI WSASend( SOCKET s, LPWSABUF lpBuffers,
// DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE
// lpCompletionRoutine );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "764339e6-a1ac-455d-8ebd-ad0fa50dc3b0")]
public static extern WSRESULT WSASend(SOCKET s, [In, MarshalAs(UnmanagedType.LPArray)] WSABUF[] lpBuffers, uint dwBufferCount, out uint lpNumberOfBytesSent,
MsgFlags dwFlags, [In, Out, Optional] IntPtr lpOverlapped, [In, Optional, MarshalAs(UnmanagedType.FunctionPtr)] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
/// <summary>The <c>WSASend</c> function sends data on a connected socket.</summary>
/// <param name="s">A descriptor that identifies a connected socket.</param>
/// <param name="lpBuffers">
/// A pointer to an array of WSABUF structures. Each <c>WSABUF</c> structure contains a pointer to a buffer and the length, in
/// bytes, of the buffer. For a Winsock application, once the <c>WSASend</c> function is called, the system owns these buffers and
/// the application may not access them. This array must remain valid for the duration of the send operation.
/// </param>
/// <param name="dwBufferCount">The number of WSABUF structures in the lpBuffers array.</param>
/// <param name="lpNumberOfBytesSent">
/// <para>A pointer to the number, in bytes, sent by this call if the I/O operation completes immediately.</para>
/// <para>
/// Use <c>NULL</c> for this parameter if the lpOverlapped parameter is not <c>NULL</c> to avoid potentially erroneous results. This
/// parameter can be <c>NULL</c> only if the lpOverlapped parameter is not <c>NULL</c>.
/// </para>
/// </param>
/// <param name="dwFlags">
/// The flags used to modify the behavior of the <c>WSASend</c> function call. For more information, see Using dwFlags in the
/// Remarks section.
/// </param>
/// <param name="lpOverlapped">A pointer to a WSAOVERLAPPED structure. This parameter is ignored for nonoverlapped sockets.</param>
/// <param name="lpCompletionRoutine">
/// A pointer to the completion routine called when the send operation has been completed. This parameter is ignored for
/// nonoverlapped sockets.
/// </param>
/// <returns>
/// <para>
/// If no error occurs and the send operation has completed immediately, <c>WSASend</c> 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
/// <c>SOCKET_ERROR</c> 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 overlapped operation was not successfully initiated and no completion
/// indication will occur.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAECONNABORTED</term>
/// <term>The virtual circuit was terminated due to a time-out or other failure.</term>
/// </item>
/// <item>
/// <term>WSAECONNRESET</term>
/// <term>
/// For a stream socket, the virtual circuit was reset by the remote side. The application should close the socket as it is no
/// longer usable. For a UDP datagram socket, this error would indicate that a previous send operation resulted in an ICMP "Port
/// Unreachable" message.
/// </term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The lpBuffers, lpNumberOfBytesSent, lpOverlapped, lpCompletionRoutine parameter is not totally contained in a valid part of the
/// user address space.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINTR</term>
/// <term>A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>The socket has not been bound with bind or the socket is not created with the overlapped flag.</term>
/// </item>
/// <item>
/// <term>WSAEMSGSIZE</term>
/// <term>The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENETRESET</term>
/// <term>
/// For a stream socket, the connection has been broken due to keep-alive activity detecting a failure while the operation was in
/// progress. For a datagram socket, this error indicates that the time to live has expired.
/// </term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>The Windows Sockets provider reports a buffer deadlock.</term>
/// </item>
/// <item>
/// <term>WSAENOTCONN</term>
/// <term>The socket is not connected.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEOPNOTSUPP</term>
/// <term>
/// 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, MSG_PARTIAL is not supported, or the socket is unidirectional and supports
/// only receive operations.
/// </term>
/// </item>
/// <item>
/// <term>WSAESHUTDOWN</term>
/// <term>
/// The socket has been shut down; it is not possible to WSASend on a socket after shutdown has been invoked with how set to SD_SEND
/// or SD_BOTH.
/// </term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>
/// Windows NT: Overlapped sockets: There are too many outstanding overlapped I/O requests. Nonoverlapped sockets: The socket is
/// marked as nonblocking and the send operation cannot be completed immediately.
/// </term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSA_IO_PENDING</term>
/// <term>An overlapped operation was successfully initiated and completion will be indicated at a later time.</term>
/// </item>
/// <item>
/// <term>WSA_OPERATION_ABORTED</term>
/// <term>
/// 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. For more information, see
/// the Remarks section.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>The <c>WSASend</c> function provides functionality over and above the standard send function in two important areas:</para>
/// <list type="bullet">
/// <item>
/// <term>It can be used in conjunction with overlapped sockets to perform overlapped send operations.</term>
/// </item>
/// <item>
/// <term>It allows multiple send buffers to be specified making it applicable to the scatter/gather type of I/O.</term>
/// </item>
/// </list>
/// <para>
/// The <c>WSASend</c> function is used to write outgoing data from one or more buffers on a connection-oriented socket specified by
/// s. It can also be used, however, on connectionless sockets that have a stipulated default peer address established through the
/// connect or WSAConnect function.
/// </para>
/// <para>
/// A socket created by the socket function will have the overlapped attribute as the default. A socket created by the WSASocket
/// function with the dwFlags parameter passed to <c>WSASocket</c> with the <c>WSA_FLAG_OVERLAPPED</c> bit set will have the
/// overlapped attribute. For sockets with the overlapped attribute, <c>WSASend</c> uses overlapped I/O unless both the lpOverlapped
/// and lpCompletionRoutine parameters are <c>NULL</c>. In that case, the socket is treated as a non-overlapped socket. A completion
/// indication will occur, invoking the completion of a routine or setting of an event object, when the buffer(s) have been consumed
/// by the transport. If the operation does not complete immediately, the final completion status is retrieved through the
/// completion routine or WSAGetOverlappedResult.
/// </para>
/// <para>
/// If both lpOverlapped and lpCompletionRoutine are <c>NULL</c>, the socket in this function will be treated as a non-overlapped socket.
/// </para>
/// <para>
/// For non-overlapped sockets, the last two parameters (lpOverlapped, lpCompletionRoutine) are ignored and <c>WSASend</c> adopts
/// the same blocking semantics as send. Data is copied from the buffer(s) into the transport's buffer. If the socket is
/// non-blocking and stream-oriented, and there is not sufficient space in the transport's buffer, <c>WSASend</c> will return with
/// only part of the application's buffers having been consumed. Given the same buffer situation and a blocking socket,
/// <c>WSASend</c> will block until all of the application buffer contents have been consumed.
/// </para>
/// <para><c>Note</c> The socket options <c>SO_RCVTIMEO</c> and <c>SO_SNDTIMEO</c> apply only to blocking sockets.</para>
/// <para>
/// If this function is completed in an overlapped manner, it is the Winsock service provider's responsibility to capture the WSABUF
/// structures before returning from this call. This enables applications to build stack-based <c>WSABUF</c> arrays pointed to by
/// the lpBuffers parameter.
/// </para>
/// <para>
/// For message-oriented sockets, do not exceed the maximum message size of the underlying provider, which can be obtained by
/// getting the value of socket option <c>SO_MAX_MSG_SIZE</c>. If the data is too long to pass atomically through the underlying
/// protocol the error WSAEMSGSIZE is returned, and no data is transmitted.
/// </para>
/// <para><c>Windows Me/98/95:</c> The <c>WSASend</c> function does not support more than 16 buffers.</para>
/// <para><c>Note</c> The successful completion of a <c>WSASend</c> does not indicate that the data was successfully delivered.</para>
/// <para>Using dwFlags</para>
/// <para>
/// The dwFlags parameter can be used to influence the behavior of the function invocation beyond the options specified for the
/// associated socket. That is, the semantics of this function are determined by the socket options and the dwFlags parameter. The
/// latter is constructed by using the bitwise OR operator with any of any of the values listed in the following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>MSG_DONTROUTE</term>
/// <term>
/// Specifies that the data should not be subject to routing. A Windows Sockets service provider can choose to ignore this flag.
/// </term>
/// </item>
/// <item>
/// <term>MSG_OOB</term>
/// <term>Send OOB data on a stream-style socket such as SOCK_STREAM only.</term>
/// </item>
/// <item>
/// <term>MSG_PARTIAL</term>
/// <term>
/// Specifies that lpBuffers only contains a partial message. Be aware that the error code WSAEOPNOTSUPP will be returned by
/// transports that do not support partial message transmissions.
/// </term>
/// </item>
/// </list>
/// <para>
/// <c>Note</c> When issuing a blocking Winsock call such as <c>WSASend</c> 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.
/// </para>
/// <para>Overlapped Socket I/O</para>
/// <para>
/// If an overlapped operation completes immediately, <c>WSASend</c> returns a value of zero and the lpNumberOfBytesSent parameter
/// is updated with the number of bytes sent. If the overlapped operation is successfully initiated and will complete later,
/// <c>WSASend</c> returns SOCKET_ERROR and indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesSent 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.
/// </para>
/// <para>
/// <c>Note</c> 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.
/// </para>
/// <para>
/// The <c>WSASend</c> function using overlapped I/O can be called from within the completion routine of a previous WSARecv,
/// WSARecvFrom, <c>WSASend</c>, or WSASendTo function. This enables time-sensitive data transmissions to occur entirely within a
/// preemptive context.
/// </para>
/// <para>
/// 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.
/// </para>
/// <para>
/// If the lpCompletionRoutine parameter is <c>NULL</c>, 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.
/// </para>
/// <para>
/// If lpCompletionRoutine is not <c>NULL</c>, 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- <c>NULL</c> lpCompletionRoutine and later calls
/// WSAGetOverlappedResult for the same overlapped I/O request may not set the fWait parameter for that invocation of
/// <c>WSAGetOverlappedResult</c> to <c>TRUE</c>. In this case the usage of the hEvent parameter is undefined, and attempting to
/// wait on the hEvent parameter would produce unpredictable results.
/// </para>
/// <para>
/// 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 <c>TRUE</c> is invoked.
/// </para>
/// <para>
/// The transport providers allow an application to invoke send and receive operations from within the context of the socket I/O
/// completion routine, and guarantee that, 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.
/// </para>
/// <para>The following C++ code example is a prototype of the completion routine.</para>
/// <para>
/// The CompletionRoutine function 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 lpOverlapped. cbTransferred specifies the
/// number of bytes sent. Currently there are no flag values defined and dwFlags will be zero. This function does not return a value.
/// </para>
/// <para>
/// Returning from this function allows invocation of another pending completion routine for this socket. All waiting completion
/// routines are called before the alertable thread's wait is satisfied with a return code of <c>WSA_IO_COMPLETION</c>. 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 sent in the same order they are specified.
/// </para>
/// <para>
/// The order of calls made to <c>WSASend</c> is also the order in which the buffers are transmitted to the transport layer.
/// <c>WSASend</c> should not be called on the same stream-oriented socket concurrently from different threads, because some Winsock
/// providers may split a large send request into multiple transmissions, and this may lead to unintended data interleaving from
/// multiple concurrent send requests on the same stream-oriented socket.
/// </para>
/// <para>Example Code</para>
/// <para>The following code example shows how to use the <c>WSASend</c> function in overlapped I/O mode.</para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasend int WSAAPI WSASend( SOCKET s, LPWSABUF lpBuffers,
// DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE
// lpCompletionRoutine );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "764339e6-a1ac-455d-8ebd-ad0fa50dc3b0")]
public static extern WSRESULT WSASend(SOCKET s, [In, MarshalAs(UnmanagedType.LPArray)] WSABUF[] lpBuffers, uint dwBufferCount, out uint lpNumberOfBytesSent,
MsgFlags dwFlags, ref WSAOVERLAPPED lpOverlapped, [In, Optional, MarshalAs(UnmanagedType.FunctionPtr)] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
/// <summary>
/// The <c>WSASendDisconnect</c> function initiates termination of the connection for the socket and sends disconnect data.
/// </summary>
/// <param name="s">Descriptor identifying a socket.</param>
/// <param name="lpOutboundDisconnectData">A pointer to the outgoing disconnect data.</param>
/// <returns>
/// <para>
/// If no error occurs, <c>WSASendDisconnect</c> returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error
/// code can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENOPROTOOPT</term>
/// <term>The parameter lpOutboundDisconnectData is not NULL, and the disconnect data is not supported by the service provider.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAENOTCONN</term>
/// <term>The socket is not connected (connection-oriented sockets only).</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The lpOutboundDisconnectData parameter is not completely contained in a valid part of the user address space.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSASendDisconnect</c> function is used on connection-oriented sockets to disable transmission and to initiate termination
/// of the connection along with the transmission of disconnect data, if any. This is equivalent to a shutdown (SD_SEND), except
/// that <c>WSASendDisconnect</c> also allows sending disconnect data (in protocols that support it).
/// </para>
/// <para>After this function has been successfully issued, subsequent sends are disallowed.</para>
/// <para>
/// The lpOutboundDisconnectData parameter, if not <c>NULL</c>, points to a buffer containing the outgoing disconnect data to be
/// sent to the remote party for retrieval by using WSARecvDisconnect.
/// </para>
/// <para>
/// <c>Note</c> The native implementation of TCP/IP on Windows does not support disconnect data. Disconnect data is only supported
/// with Windows Sockets providers that have the XP1_DISCONNECT_DATA flag in their WSAPROTOCOL_INFO structure. Use the
/// WSAEnumProtocols function to obtain <c>WSAPROTOCOL_INFO</c> structures for all installed providers.
/// </para>
/// <para>
/// The <c>WSASendDisconnect</c> function does not close the socket, and resources attached to the socket will not be freed until
/// closesocket is invoked.
/// </para>
/// <para>The <c>WSASendDisconnect</c> function does not block regardless of the SO_LINGER setting on the socket.</para>
/// <para>
/// An application should not rely on being able to reuse a socket after calling <c>WSASendDisconnect</c>. In particular, a Windows
/// Sockets provider is not required to support the use of connect/WSAConnect on such a socket.
/// </para>
/// <para>
/// <c>Note</c> When issuing a blocking Winsock call such as <c>WSASendDisconnect</c>, 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.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasenddisconnect int WSAAPI WSASendDisconnect( SOCKET s,
// LPWSABUF lpOutboundDisconnectData );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "c05fc719-e35a-4194-ac01-a294b19ccce9")]
public static extern WSRESULT WSASendDisconnect(SOCKET s, in WSABUF lpOutboundDisconnectData);
/// <summary>
/// The <c>WSASendDisconnect</c> function initiates termination of the connection for the socket and sends disconnect data.
/// </summary>
/// <param name="s">Descriptor identifying a socket.</param>
/// <param name="lpOutboundDisconnectData">A pointer to the outgoing disconnect data.</param>
/// <returns>
/// <para>
/// If no error occurs, <c>WSASendDisconnect</c> returns zero. Otherwise, a value of SOCKET_ERROR is returned, and a specific error
/// code can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENOPROTOOPT</term>
/// <term>The parameter lpOutboundDisconnectData is not NULL, and the disconnect data is not supported by the service provider.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAENOTCONN</term>
/// <term>The socket is not connected (connection-oriented sockets only).</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The lpOutboundDisconnectData parameter is not completely contained in a valid part of the user address space.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSASendDisconnect</c> function is used on connection-oriented sockets to disable transmission and to initiate termination
/// of the connection along with the transmission of disconnect data, if any. This is equivalent to a shutdown (SD_SEND), except
/// that <c>WSASendDisconnect</c> also allows sending disconnect data (in protocols that support it).
/// </para>
/// <para>After this function has been successfully issued, subsequent sends are disallowed.</para>
/// <para>
/// The lpOutboundDisconnectData parameter, if not <c>NULL</c>, points to a buffer containing the outgoing disconnect data to be
/// sent to the remote party for retrieval by using WSARecvDisconnect.
/// </para>
/// <para>
/// <c>Note</c> The native implementation of TCP/IP on Windows does not support disconnect data. Disconnect data is only supported
/// with Windows Sockets providers that have the XP1_DISCONNECT_DATA flag in their WSAPROTOCOL_INFO structure. Use the
/// WSAEnumProtocols function to obtain <c>WSAPROTOCOL_INFO</c> structures for all installed providers.
/// </para>
/// <para>
/// The <c>WSASendDisconnect</c> function does not close the socket, and resources attached to the socket will not be freed until
/// closesocket is invoked.
/// </para>
/// <para>The <c>WSASendDisconnect</c> function does not block regardless of the SO_LINGER setting on the socket.</para>
/// <para>
/// An application should not rely on being able to reuse a socket after calling <c>WSASendDisconnect</c>. In particular, a Windows
/// Sockets provider is not required to support the use of connect/WSAConnect on such a socket.
/// </para>
/// <para>
/// <c>Note</c> When issuing a blocking Winsock call such as <c>WSASendDisconnect</c>, 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.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasenddisconnect int WSAAPI WSASendDisconnect( SOCKET s,
// LPWSABUF lpOutboundDisconnectData );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "c05fc719-e35a-4194-ac01-a294b19ccce9")]
public static extern WSRESULT WSASendDisconnect(SOCKET s, [In, Optional] IntPtr lpOutboundDisconnectData);
/// <summary>The <c>WSASendMsg</c> function sends data and optional control information from connected and unconnected sockets.</summary>
/// <param name="Handle">A descriptor identifying the socket.</param>
/// <param name="lpMsg">A WSAMSG structure storing the Posix.1g <c>msghdr</c> structure.</param>
/// <param name="dwFlags">
/// The flags used to modify the behavior of the <c>WSASendMsg</c> function call. For more information, see Using dwFlags in the
/// Remarks section.
/// </param>
/// <param name="lpNumberOfBytesSent">
/// <para>A pointer to the number, in bytes, sent by this call if the I/O operation completes immediately.</para>
/// <para>
/// Use <c>NULL</c> for this parameter if the lpOverlapped parameter is not <c>NULL</c> to avoid potentially erroneous results. This
/// parameter can be <c>NULL</c> only if the lpOverlapped parameter is not <c>NULL</c>.
/// </para>
/// </param>
/// <param name="lpOverlapped">A pointer to a WSAOVERLAPPED structure. Ignored for non-overlapped sockets.</param>
/// <param name="lpCompletionRoutine">
/// A pointer to the completion routine called when the send operation completes. Ignored for non-overlapped sockets.
/// </param>
/// <returns>
/// <para>
/// Returns zero when successful and immediate completion occurs. When zero is returned, the specified completion routine is called
/// when the calling thread is in the alertable state.
/// </para>
/// <para>
/// A return value of <c>SOCKET_ERROR</c>, and subsequent call to WSAGetLastError that returns WSA_IO_PENDING, indicates the
/// overlapped operation has successfully initiated; completion is then indicated through other means, such as through events or
/// completion ports.
/// </para>
/// <para>
/// Upon failure, returns <c>SOCKET_ERROR</c> and a subsequent call to WSAGetLastError returns a value other than
/// <c>WSA_IO_PENDING</c>. The following table lists error codes.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAEACCES</term>
/// <term>The requested address is a broadcast address, but the appropriate flag was not set.</term>
/// </item>
/// <item>
/// <term>WSAECONNRESET</term>
/// <term>
/// For a UDP datagram socket, this error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message.
/// </term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The lpMsg, lpNumberOfBytesSent, lpOverlapped, or lpCompletionRoutine parameter is not totally contained in a valid part of the
/// user address space. This error is also returned if a name member of the WSAMSGstructure pointed to by the lpMsg parameter was a
/// NULL pointer and the namelen member of the WSAMSGstructure was not set to zero. This error is also returned if a Control.buf
/// member of the WSAMSGstructure pointed to by the lpMsg parameter was a NULL pointer and the Control.len member of the
/// WSAMSGstructure was not set to zero.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEINTR</term>
/// <term>A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>The socket has not been bound with bind, or the socket was not created with the overlapped flag.</term>
/// </item>
/// <item>
/// <term>WSAEMSGSIZE</term>
/// <term>The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENETRESET</term>
/// <term>For a datagram socket, this error indicates that the time to live has expired.</term>
/// </item>
/// <item>
/// <term>WSAENETUNREACH</term>
/// <term>The network is unreachable.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>The Windows Sockets provider reports a buffer deadlock.</term>
/// </item>
/// <item>
/// <term>WSAENOTCONN</term>
/// <term>The socket is not connected.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEOPNOTSUPP</term>
/// <term>
/// The socket operation is not supported. This error is returned if the dwFlags member of the WSAMSGstructure pointed to by the
/// lpMsg parameter includes any control flags invalid for WSASendMsg.
/// </term>
/// </item>
/// <item>
/// <term>WSAESHUTDOWN</term>
/// <term>
/// The socket has been shut down; it is not possible to call the WSASendMsg function on a socket after shutdown has been invoked
/// with how set to SD_SEND or SD_BOTH.
/// </term>
/// </item>
/// <item>
/// <term>WSAETIMEDOUT</term>
/// <term>
/// The socket timed out. This error is returned if the socket had a wait timeout specified using the SO_SNDTIMEO socket option and
/// the timeout was exceeded.
/// </term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>
/// Overlapped sockets: There are too many outstanding overlapped I/O requests. Nonoverlapped sockets: The socket is marked as
/// nonblocking and the send operation cannot be completed immediately.
/// </term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSA_IO_PENDING</term>
/// <term>An overlapped operation was successfully initiated and completion will be indicated at a later time.</term>
/// </item>
/// <item>
/// <term>WSA_OPERATION_ABORTED</term>
/// <term>
/// The overlapped operation has been canceled due to the closure of the socket or due to the execution of the SIO_FLUSH command in WSAIoctl.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSASendMsg</c> function can be used in place of the WSASend and WSASendTo functions. The <c>WSASendMsg</c> 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
/// <c>SOCK_DGRAM</c> or <c>SOCK_RAW</c>.
/// </para>
/// <para>
/// The dwFlags parameter can only contain a combination of the following control flags: <c>MSG_DONTROUTE</c>, <c>MSG_PARTIAL</c>,
/// and <c>MSG_OOB</c>. The <c>dwFlags</c> member of the WSAMSGstructure pointed to by the lpMsg parameter is ignored on input and
/// not used on output.
/// </para>
/// <para>
/// <c>Note</c> The function pointer for the <c>WSASendMsg</c> function must be obtained at run time by making a call to the
/// WSAIoctl function with the <c>SIO_GET_EXTENSION_FUNCTION_POINTER</c> opcode specified. The input buffer passed to the
/// <c>WSAIoctl</c> function must contain <c>WSAID_WSASENDMSG</c>, a globally unique identifier (GUID) whose value identifies the
/// <c>WSASendMsg</c> extension function. On success, the output returned by the <c>WSAIoctl</c> function contains a pointer to the
/// <c>WSASendMsg</c> function. The <c>WSAID_WSASENDMSG</c> GUID is defined in the Mswsock.h header file.
/// </para>
/// <para>
/// Overlapped sockets are created with a WSASocket function call that has the <c>WSA_FLAG_OVERLAPPED</c> flag set. For overlapped
/// sockets, sending information uses overlapped I/O unless both lpOverlapped and lpCompletionRoutine are <c>NULL</c>; when
/// lpOverlapped and lpCompletionRoutine are <c>NULL</c>, the socket is treated as a nonoverlapped socket. 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.
/// </para>
/// <para>
/// For nonoverlapped sockets, the lpOverlapped and lpCompletionRoutine parameters are ignored and <c>WSASendMsg</c> adopts the same
/// blocking semantics as the send function: data is copied from the buffer or buffers into the transport's buffer. If the socket is
/// nonblocking and stream oriented, and there is insufficient space in the transport's buffer, <c>WSASendMsg</c> returns with only
/// part of the application's buffers having been consumed. In contrast, this buffer situation on a blocking socket results in
/// <c>WSASendMsg</c> blocking until all of the application's buffer contents have been consumed.
/// </para>
/// <para>
/// 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 <c>WSABUF</c> arrays pointed to
/// by the <c>lpBuffers</c> member of the WSAMSGstructure pointed to by the lpMsg parameter.
/// </para>
/// <para>
/// For message-oriented sockets, care must be taken not to exceed the maximum message size of the underlying provider, which can be
/// obtained by getting the value of socket option <c>SO_MAX_MSG_SIZE</c>. If the data is too long to pass atomically through the
/// underlying protocol, the error <c>WSAEMSGSIZE</c> is returned and no data is transmitted.
/// </para>
/// <para>
/// On an IPv4 socket of type <c>SOCK_DGRAM</c> or <c>SOCK_RAW</c>, an application can specific the local IP source address to use
/// for sending with the <c>WSASendMsg</c> function. One of the control data objects passed in the WSAMSG structure to the
/// <c>WSASendMsg</c> function may contain an in_pktinfo structure used to specify the local IPv4 source address to use for sending.
/// </para>
/// <para>
/// On an IPv6 socket of type <c>SOCK_DGRAM</c> or <c>SOCK_RAW</c>, an application can specific the local IP source address to use
/// for sending with the <c>WSASendMsg</c> function. One of the control data objects passed in the WSAMSG structure to the
/// <c>WSASendMsg</c> function may contain an in6_pktinfo structure used to specify the local IPv6 source address to use for sending.
/// </para>
/// <para>
/// For a dual-stack socket when sending datagrams with the <c>WSASendMsg</c> function and an application wants to specify a
/// specific local IP source address to be used, the method to handle this depends on the destination IP address. When sending to an
/// IPv4 destination address or an IPv4-mapped IPv6 destination address, one of the control data objects passed in the WSAMSG
/// structure pointed to by the lpMsg parameter should contain an in_pktinfo structure containing the local IPv4 source address to
/// use for sending. When sending to an IPv6 destination address that is not a an IPv4-mapped IPv6 address, one of the control data
/// objects passed in the <c>WSAMSG</c> structure pointed to by the lpMsg parameter should contain an in6_pktinfo structure
/// containing the local IPv6 source address to use for sending.
/// </para>
/// <para><c>Note</c> The <c>SO_SNDTIMEO</c> socket option applies only to blocking sockets.</para>
/// <para><c>Note</c> The successful completion of a <c>WSASendMsg</c> does not indicate that the data was successfully delivered.</para>
/// <para>
/// <c>Note</c> When issuing a blocking Winsock call such as <c>WSASendMsg</c> 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.
/// </para>
/// <para>dwFlags</para>
/// <para>
/// The dwFlags input parameter can be used to influence the behavior of the function invocation beyond the options specified for
/// the associated socket. That is, the semantics of this function are determined by the socket options and the dwFlags parameter.
/// The latter is constructed by using the bitwise OR operator with any of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>MSG_DONTROUTE</term>
/// <term>
/// Specifies that the data should not be subject to routing. A Windows Sockets service provider can choose to ignore this flag.
/// </term>
/// </item>
/// <item>
/// <term>MSG_PARTIAL</term>
/// <term>
/// Specifies that lpMsg-&gt;lpBuffers contains only a partial message. Note that the error code WSAEOPNOTSUPP will be returned by
/// transports that do not support partial message transmissions.
/// </term>
/// </item>
/// </list>
/// <para>The possible values for dwFlags parameter are defined in the Winsock2.h header file.</para>
/// <para>On output, the <c>dwFlags</c> member of the WSAMSGstructure pointed to by the lpMsg parameter is not used.</para>
/// <para>Overlapped Socket I/O</para>
/// <para>
/// If an overlapped operation completes immediately, <c>WSASendMsg</c> returns a value of zero and the lpNumberOfBytesSent
/// parameter is updated with the number of bytes sent. If the overlapped operation is successfully initiated and will complete
/// later, <c>WSASendMsg</c> returns SOCKET_ERROR and indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesSent 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.
/// </para>
/// <para>
/// <c>Note</c> 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.
/// </para>
/// <para>
/// The <c>WSASendMsg</c> function using overlapped I/O can be called from within the completion routine of a previous , WSARecv,
/// WSARecvFrom, WSARecvMsg, WSASend, <c>WSASendMsg</c>, or WSASendTo function. This permits time-sensitive data transmissions to
/// occur entirely within a preemptive context.
/// </para>
/// <para>
/// 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.
/// </para>
/// <para>
/// If the lpCompletionRoutine parameter is <c>NULL</c>, 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.
/// </para>
/// <para>
/// If lpCompletionRoutine is not <c>NULL</c>, 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- <c>NULL</c> lpCompletionRoutine and later calls
/// WSAGetOverlappedResult for the same overlapped I/O request may not set the fWait parameter for that invocation of
/// <c>WSAGetOverlappedResult</c> to <c>TRUE</c>. In this case, the usage of the hEvent parameter is undefined, and attempting to
/// wait on the hEvent parameter would produce unpredictable results.
/// </para>
/// <para>
/// 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, for example, with WSAWaitForMultipleEvents called with the
/// fAlertable parameter set to <c>TRUE</c>.
/// </para>
/// <para>
/// The transport providers allow an application to invoke send and receive operations from within the context of the socket I/O
/// completion routine, and guarantee that, 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.
/// </para>
/// <para>The prototype of the completion routine is as follows.</para>
/// <para>
/// The <c>CompletionRoutine</c> function 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 indicates the number of bytes sent. Currently there are no flag values defined and the dwFlags parameter
/// will be zero. The <c>CompletionRoutine</c> function does not return a value.
/// </para>
/// <para>
/// Returning from this function allows invocation of another pending completion routine for the socket. 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 sent in the same order they are specified.
/// </para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasendmsg int WSAAPI WSASendMsg( SOCKET Handle, LPWSAMSG
// lpMsg, DWORD dwFlags, LPDWORD lpNumberOfBytesSent, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE
// lpCompletionRoutine );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "3b2ba645-6a70-4ba2-b4a2-5bde0c7f8d08")]
public static extern WSRESULT WSASendMsg(SOCKET Handle, in WSAMSG lpMsg, MsgFlags dwFlags, out uint lpNumberOfBytesSent, [In, Out, Optional] IntPtr lpOverlapped,
[In, Optional, MarshalAs(UnmanagedType.FunctionPtr)] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
/// <summary>The <c>WSASendMsg</c> function sends data and optional control information from connected and unconnected sockets.</summary>
/// <param name="Handle">A descriptor identifying the socket.</param>
/// <param name="lpMsg">A WSAMSG structure storing the Posix.1g <c>msghdr</c> structure.</param>
/// <param name="dwFlags">
/// The flags used to modify the behavior of the <c>WSASendMsg</c> function call. For more information, see Using dwFlags in the
/// Remarks section.
/// </param>
/// <param name="lpNumberOfBytesSent">
/// <para>A pointer to the number, in bytes, sent by this call if the I/O operation completes immediately.</para>
/// <para>
/// Use <c>NULL</c> for this parameter if the lpOverlapped parameter is not <c>NULL</c> to avoid potentially erroneous results. This
/// parameter can be <c>NULL</c> only if the lpOverlapped parameter is not <c>NULL</c>.
/// </para>
/// </param>
/// <param name="lpOverlapped">A pointer to a WSAOVERLAPPED structure. Ignored for non-overlapped sockets.</param>
/// <param name="lpCompletionRoutine">
/// A pointer to the completion routine called when the send operation completes. Ignored for non-overlapped sockets.
/// </param>
/// <returns>
/// <para>
/// Returns zero when successful and immediate completion occurs. When zero is returned, the specified completion routine is called
/// when the calling thread is in the alertable state.
/// </para>
/// <para>
/// A return value of <c>SOCKET_ERROR</c>, and subsequent call to WSAGetLastError that returns WSA_IO_PENDING, indicates the
/// overlapped operation has successfully initiated; completion is then indicated through other means, such as through events or
/// completion ports.
/// </para>
/// <para>
/// Upon failure, returns <c>SOCKET_ERROR</c> and a subsequent call to WSAGetLastError returns a value other than
/// <c>WSA_IO_PENDING</c>. The following table lists error codes.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAEACCES</term>
/// <term>The requested address is a broadcast address, but the appropriate flag was not set.</term>
/// </item>
/// <item>
/// <term>WSAECONNRESET</term>
/// <term>
/// For a UDP datagram socket, this error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message.
/// </term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The lpMsg, lpNumberOfBytesSent, lpOverlapped, or lpCompletionRoutine parameter is not totally contained in a valid part of the
/// user address space. This error is also returned if a name member of the WSAMSGstructure pointed to by the lpMsg parameter was a
/// NULL pointer and the namelen member of the WSAMSGstructure was not set to zero. This error is also returned if a Control.buf
/// member of the WSAMSGstructure pointed to by the lpMsg parameter was a NULL pointer and the Control.len member of the
/// WSAMSGstructure was not set to zero.
/// </term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEINTR</term>
/// <term>A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>The socket has not been bound with bind, or the socket was not created with the overlapped flag.</term>
/// </item>
/// <item>
/// <term>WSAEMSGSIZE</term>
/// <term>The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENETRESET</term>
/// <term>For a datagram socket, this error indicates that the time to live has expired.</term>
/// </item>
/// <item>
/// <term>WSAENETUNREACH</term>
/// <term>The network is unreachable.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>The Windows Sockets provider reports a buffer deadlock.</term>
/// </item>
/// <item>
/// <term>WSAENOTCONN</term>
/// <term>The socket is not connected.</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAEOPNOTSUPP</term>
/// <term>
/// The socket operation is not supported. This error is returned if the dwFlags member of the WSAMSGstructure pointed to by the
/// lpMsg parameter includes any control flags invalid for WSASendMsg.
/// </term>
/// </item>
/// <item>
/// <term>WSAESHUTDOWN</term>
/// <term>
/// The socket has been shut down; it is not possible to call the WSASendMsg function on a socket after shutdown has been invoked
/// with how set to SD_SEND or SD_BOTH.
/// </term>
/// </item>
/// <item>
/// <term>WSAETIMEDOUT</term>
/// <term>
/// The socket timed out. This error is returned if the socket had a wait timeout specified using the SO_SNDTIMEO socket option and
/// the timeout was exceeded.
/// </term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>
/// Overlapped sockets: There are too many outstanding overlapped I/O requests. Nonoverlapped sockets: The socket is marked as
/// nonblocking and the send operation cannot be completed immediately.
/// </term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSA_IO_PENDING</term>
/// <term>An overlapped operation was successfully initiated and completion will be indicated at a later time.</term>
/// </item>
/// <item>
/// <term>WSA_OPERATION_ABORTED</term>
/// <term>
/// The overlapped operation has been canceled due to the closure of the socket or due to the execution of the SIO_FLUSH command in WSAIoctl.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSASendMsg</c> function can be used in place of the WSASend and WSASendTo functions. The <c>WSASendMsg</c> 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
/// <c>SOCK_DGRAM</c> or <c>SOCK_RAW</c>.
/// </para>
/// <para>
/// The dwFlags parameter can only contain a combination of the following control flags: <c>MSG_DONTROUTE</c>, <c>MSG_PARTIAL</c>,
/// and <c>MSG_OOB</c>. The <c>dwFlags</c> member of the WSAMSGstructure pointed to by the lpMsg parameter is ignored on input and
/// not used on output.
/// </para>
/// <para>
/// <c>Note</c> The function pointer for the <c>WSASendMsg</c> function must be obtained at run time by making a call to the
/// WSAIoctl function with the <c>SIO_GET_EXTENSION_FUNCTION_POINTER</c> opcode specified. The input buffer passed to the
/// <c>WSAIoctl</c> function must contain <c>WSAID_WSASENDMSG</c>, a globally unique identifier (GUID) whose value identifies the
/// <c>WSASendMsg</c> extension function. On success, the output returned by the <c>WSAIoctl</c> function contains a pointer to the
/// <c>WSASendMsg</c> function. The <c>WSAID_WSASENDMSG</c> GUID is defined in the Mswsock.h header file.
/// </para>
/// <para>
/// Overlapped sockets are created with a WSASocket function call that has the <c>WSA_FLAG_OVERLAPPED</c> flag set. For overlapped
/// sockets, sending information uses overlapped I/O unless both lpOverlapped and lpCompletionRoutine are <c>NULL</c>; when
/// lpOverlapped and lpCompletionRoutine are <c>NULL</c>, the socket is treated as a nonoverlapped socket. 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.
/// </para>
/// <para>
/// For nonoverlapped sockets, the lpOverlapped and lpCompletionRoutine parameters are ignored and <c>WSASendMsg</c> adopts the same
/// blocking semantics as the send function: data is copied from the buffer or buffers into the transport's buffer. If the socket is
/// nonblocking and stream oriented, and there is insufficient space in the transport's buffer, <c>WSASendMsg</c> returns with only
/// part of the application's buffers having been consumed. In contrast, this buffer situation on a blocking socket results in
/// <c>WSASendMsg</c> blocking until all of the application's buffer contents have been consumed.
/// </para>
/// <para>
/// 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 <c>WSABUF</c> arrays pointed to
/// by the <c>lpBuffers</c> member of the WSAMSGstructure pointed to by the lpMsg parameter.
/// </para>
/// <para>
/// For message-oriented sockets, care must be taken not to exceed the maximum message size of the underlying provider, which can be
/// obtained by getting the value of socket option <c>SO_MAX_MSG_SIZE</c>. If the data is too long to pass atomically through the
/// underlying protocol, the error <c>WSAEMSGSIZE</c> is returned and no data is transmitted.
/// </para>
/// <para>
/// On an IPv4 socket of type <c>SOCK_DGRAM</c> or <c>SOCK_RAW</c>, an application can specific the local IP source address to use
/// for sending with the <c>WSASendMsg</c> function. One of the control data objects passed in the WSAMSG structure to the
/// <c>WSASendMsg</c> function may contain an in_pktinfo structure used to specify the local IPv4 source address to use for sending.
/// </para>
/// <para>
/// On an IPv6 socket of type <c>SOCK_DGRAM</c> or <c>SOCK_RAW</c>, an application can specific the local IP source address to use
/// for sending with the <c>WSASendMsg</c> function. One of the control data objects passed in the WSAMSG structure to the
/// <c>WSASendMsg</c> function may contain an in6_pktinfo structure used to specify the local IPv6 source address to use for sending.
/// </para>
/// <para>
/// For a dual-stack socket when sending datagrams with the <c>WSASendMsg</c> function and an application wants to specify a
/// specific local IP source address to be used, the method to handle this depends on the destination IP address. When sending to an
/// IPv4 destination address or an IPv4-mapped IPv6 destination address, one of the control data objects passed in the WSAMSG
/// structure pointed to by the lpMsg parameter should contain an in_pktinfo structure containing the local IPv4 source address to
/// use for sending. When sending to an IPv6 destination address that is not a an IPv4-mapped IPv6 address, one of the control data
/// objects passed in the <c>WSAMSG</c> structure pointed to by the lpMsg parameter should contain an in6_pktinfo structure
/// containing the local IPv6 source address to use for sending.
/// </para>
/// <para><c>Note</c> The <c>SO_SNDTIMEO</c> socket option applies only to blocking sockets.</para>
/// <para><c>Note</c> The successful completion of a <c>WSASendMsg</c> does not indicate that the data was successfully delivered.</para>
/// <para>
/// <c>Note</c> When issuing a blocking Winsock call such as <c>WSASendMsg</c> 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.
/// </para>
/// <para>dwFlags</para>
/// <para>
/// The dwFlags input parameter can be used to influence the behavior of the function invocation beyond the options specified for
/// the associated socket. That is, the semantics of this function are determined by the socket options and the dwFlags parameter.
/// The latter is constructed by using the bitwise OR operator with any of the following values.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>MSG_DONTROUTE</term>
/// <term>
/// Specifies that the data should not be subject to routing. A Windows Sockets service provider can choose to ignore this flag.
/// </term>
/// </item>
/// <item>
/// <term>MSG_PARTIAL</term>
/// <term>
/// Specifies that lpMsg-&gt;lpBuffers contains only a partial message. Note that the error code WSAEOPNOTSUPP will be returned by
/// transports that do not support partial message transmissions.
/// </term>
/// </item>
/// </list>
/// <para>The possible values for dwFlags parameter are defined in the Winsock2.h header file.</para>
/// <para>On output, the <c>dwFlags</c> member of the WSAMSGstructure pointed to by the lpMsg parameter is not used.</para>
/// <para>Overlapped Socket I/O</para>
/// <para>
/// If an overlapped operation completes immediately, <c>WSASendMsg</c> returns a value of zero and the lpNumberOfBytesSent
/// parameter is updated with the number of bytes sent. If the overlapped operation is successfully initiated and will complete
/// later, <c>WSASendMsg</c> returns SOCKET_ERROR and indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesSent 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.
/// </para>
/// <para>
/// <c>Note</c> 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.
/// </para>
/// <para>
/// The <c>WSASendMsg</c> function using overlapped I/O can be called from within the completion routine of a previous , WSARecv,
/// WSARecvFrom, WSARecvMsg, WSASend, <c>WSASendMsg</c>, or WSASendTo function. This permits time-sensitive data transmissions to
/// occur entirely within a preemptive context.
/// </para>
/// <para>
/// 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.
/// </para>
/// <para>
/// If the lpCompletionRoutine parameter is <c>NULL</c>, 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.
/// </para>
/// <para>
/// If lpCompletionRoutine is not <c>NULL</c>, 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- <c>NULL</c> lpCompletionRoutine and later calls
/// WSAGetOverlappedResult for the same overlapped I/O request may not set the fWait parameter for that invocation of
/// <c>WSAGetOverlappedResult</c> to <c>TRUE</c>. In this case, the usage of the hEvent parameter is undefined, and attempting to
/// wait on the hEvent parameter would produce unpredictable results.
/// </para>
/// <para>
/// 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, for example, with WSAWaitForMultipleEvents called with the
/// fAlertable parameter set to <c>TRUE</c>.
/// </para>
/// <para>
/// The transport providers allow an application to invoke send and receive operations from within the context of the socket I/O
/// completion routine, and guarantee that, 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.
/// </para>
/// <para>The prototype of the completion routine is as follows.</para>
/// <para>
/// The <c>CompletionRoutine</c> function 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 indicates the number of bytes sent. Currently there are no flag values defined and the dwFlags parameter
/// will be zero. The <c>CompletionRoutine</c> function does not return a value.
/// </para>
/// <para>
/// Returning from this function allows invocation of another pending completion routine for the socket. 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 sent in the same order they are specified.
/// </para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasendmsg int WSAAPI WSASendMsg( SOCKET Handle, LPWSAMSG
// lpMsg, DWORD dwFlags, LPDWORD lpNumberOfBytesSent, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE
// lpCompletionRoutine );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "3b2ba645-6a70-4ba2-b4a2-5bde0c7f8d08")]
public static extern WSRESULT WSASendMsg(SOCKET Handle, in WSAMSG lpMsg, MsgFlags dwFlags, out uint lpNumberOfBytesSent, ref WSAOVERLAPPED lpOverlapped,
[In, Optional, MarshalAs(UnmanagedType.FunctionPtr)] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
/// <summary>The <c>WSASendTo</c> function sends data to a specific destination, using overlapped I/O where applicable.</summary>
/// <param name="s">A descriptor identifying a (possibly connected) socket.</param>
/// <param name="lpBuffers">
/// A pointer to an array of WSABUF structures. Each <c>WSABUF</c> structure contains a pointer to a buffer and the length of the
/// buffer, in bytes. For a Winsock application, once the <c>WSASendTo</c> function is called, the system owns these buffers and the
/// application may not access them. This array must remain valid for the duration of the send operation.
/// </param>
/// <param name="dwBufferCount">The number of WSABUF structures in the lpBuffers array.</param>
/// <param name="lpNumberOfBytesSent">
/// <para>A pointer to the number of bytes sent by this call if the I/O operation completes immediately.</para>
/// <para>
/// Use <c>NULL</c> for this parameter if the lpOverlapped parameter is not <c>NULL</c> to avoid potentially erroneous results. This
/// parameter can be <c>NULL</c> only if the lpOverlapped parameter is not <c>NULL</c>.
/// </para>
/// </param>
/// <param name="dwFlags">The flags used to modify the behavior of the <c>WSASendTo</c> function call.</param>
/// <param name="lpTo">An optional pointer to the address of the target socket in the SOCKADDR structure.</param>
/// <param name="iTolen">The size, in bytes, of the address in the lpTo parameter.</param>
/// <param name="lpOverlapped">A pointer to a WSAOVERLAPPED structure (ignored for nonoverlapped sockets).</param>
/// <param name="lpCompletionRoutine">
/// A pointer to the completion routine called when the send operation has been completed (ignored for nonoverlapped sockets).
/// </param>
/// <returns>
/// <para>
/// If no error occurs and the send operation has completed immediately, <c>WSASendTo</c> 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
/// <c>SOCKET_ERROR</c> 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 overlapped operation was not successfully initiated and no completion
/// indication will occur.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAEACCES</term>
/// <term>The requested address is a broadcast address, but the appropriate flag was not set.</term>
/// </item>
/// <item>
/// <term>WSAEADDRNOTAVAIL</term>
/// <term>The remote address is not a valid address (such as ADDR_ANY).</term>
/// </item>
/// <item>
/// <term>WSAEAFNOSUPPORT</term>
/// <term>Addresses in the specified family cannot be used with this socket.</term>
/// </item>
/// <item>
/// <term>WSAECONNRESET</term>
/// <term>
/// For a UDP datagram socket, this error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message.
/// </term>
/// </item>
/// <item>
/// <term>WSAEDESTADDRREQ</term>
/// <term>A destination address is required.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The lpBuffers, lpTo, lpOverlapped, lpNumberOfBytesSent, or lpCompletionRoutine parameters are not part of the user address
/// space, or the lpTo parameter is too small.
/// </term>
/// </item>
/// <item>
/// <term>WSAEHOSTUNREACH</term>
/// <term>A socket operation was attempted to an unreachable host.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEINTR</term>
/// <term>A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>The socket has not been bound with bind, or the socket is not created with the overlapped flag.</term>
/// </item>
/// <item>
/// <term>WSAEMSGSIZE</term>
/// <term>The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENETRESET</term>
/// <term>For a datagram socket, this error indicates that the time to live has expired.</term>
/// </item>
/// <item>
/// <term>WSAENETUNREACH</term>
/// <term>The network cannot be reached from this host at this time.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>The Windows Sockets provider reports a buffer deadlock.</term>
/// </item>
/// <item>
/// <term>WSAENOTCONN</term>
/// <term>The socket is not connected (connection-oriented sockets only).</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAESHUTDOWN</term>
/// <term>
/// The socket has been shut down; it is not possible to WSASendTo on a socket after shutdown has been invoked with how set to
/// SD_SEND or SD_BOTH.
/// </term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>
/// Windows NT: Overlapped sockets: there are too many outstanding overlapped I/O requests. Nonoverlapped sockets: The socket is
/// marked as nonblocking and the send operation cannot be completed immediately.
/// </term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSA_IO_PENDING</term>
/// <term>An overlapped operation was successfully initiated and completion will be indicated at a later time.</term>
/// </item>
/// <item>
/// <term>WSA_OPERATION_ABORTED</term>
/// <term>
/// The overlapped operation has been canceled due to the closure of the socket, or the execution of the SIO_FLUSH command in WSAIoctl.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>The <c>WSASendTo</c> function provides enhanced features over the standard sendto function in two important areas:</para>
/// <list type="bullet">
/// <item>
/// <term>It can be used in conjunction with overlapped sockets to perform overlapped send operations.</term>
/// </item>
/// <item>
/// <term>It allows multiple send buffers to be specified making it applicable to the scatter/gather type of I/O.</term>
/// </item>
/// </list>
/// <para>
/// The <c>WSASendTo</c> function is normally used on a connectionless socket specified by s to send a datagram contained in one or
/// more buffers to a specific peer socket identified by the lpTo parameter. Even if the connectionless socket has been previously
/// connected using the connect function to a specific address, lpTo overrides the destination address for that particular datagram
/// only. On a connection-oriented socket, the lpTo and iToLen parameters are ignored; in this case, the <c>WSASendTo</c> is
/// equivalent to WSASend.
/// </para>
/// <para>
/// For overlapped sockets (created using WSASocket with flag <c>WSA_FLAG_OVERLAPPED</c>) sending data uses overlapped I/O, unless
/// both lpOverlapped and lpCompletionRoutine are <c>NULL</c> in which case the socket is treated as a nonoverlapped socket. A
/// completion indication will occur (invoking the completion routine or setting of an event object) when the buffer(s) have been
/// consumed by the transport. If the operation does not complete immediately, the final completion status is retrieved through the
/// completion routine or WSAGetOverlappedResult.
/// </para>
/// <para>
/// <c>Note</c> 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.
/// </para>
/// <para>
/// If both lpOverlapped and lpCompletionRoutine are <c>NULL</c>, the socket in this function will be treated as a nonoverlapped socket.
/// </para>
/// <para>
/// For nonoverlapped sockets, the last two parameters (lpOverlapped, lpCompletionRoutine) are ignored and <c>WSASendTo</c> adopts
/// the same blocking semantics as send. Data is copied from the buffer(s) into the transport buffer. If the socket is nonblocking
/// and stream oriented, and there is not sufficient space in the transport's buffer, <c>WSASendTo</c> returns with only part of the
/// application's buffers having been consumed. Given the same buffer situation and a blocking socket, <c>WSASendTo</c> will block
/// until all of the application's buffer contents have been consumed.
/// </para>
/// <para>
/// If this function is completed in an overlapped manner, it is the Winsock service provider's responsibility to capture the WSABUF
/// structures before returning from this call. This enables applications to build stack-based <c>WSABUF</c> arrays pointed to by
/// the lpBuffers parameter.
/// </para>
/// <para>
/// For message-oriented sockets, care must be taken not to exceed the maximum message size of the underlying transport, which can
/// be obtained by getting the value of socket option <c>SO_MAX_MSG_SIZE</c>. If the data is too long to pass atomically through the
/// underlying protocol the error WSAEMSGSIZE is returned, and no data is transmitted.
/// </para>
/// <para>
/// If the socket is unbound, unique values are assigned to the local association by the system, and the socket is then marked as bound.
/// </para>
/// <para>
/// If the socket is connected, the getsockname function can be used to determine the local IP address and port associated with the socket.
/// </para>
/// <para>
/// If the socket is not connected, the getsockname function can be used to determine the local port number associated with the
/// socket but the IP address returned is set to the wildcard address for the given protocol (for example, INADDR_ANY or "0.0.0.0"
/// for IPv4 and IN6ADDR_ANY_INIT or "::" for IPv6).
/// </para>
/// <para>The successful completion of a <c>WSASendTo</c> does not indicate that the data was successfully delivered.</para>
/// <para>
/// The dwFlags parameter can be used to influence the behavior of the function invocation beyond the options specified for the
/// associated socket. That is, the semantics of this function are determined by the socket options and the dwFlags parameter. The
/// latter is constructed by using the bitwise OR operator with any of any of the values listed in the following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>MSG_DONTROUTE</term>
/// <term>
/// Specifies that the data should not be subject to routing. A Windows Socket service provider may choose to ignore this flag.
/// </term>
/// </item>
/// <item>
/// <term>MSG_OOB</term>
/// <term>Send OOB data (stream-style socket such as SOCK_STREAM only).</term>
/// </item>
/// <item>
/// <term>MSG_PARTIAL</term>
/// <term>
/// Specifies that lpBuffers only contains a partial message. Be aware that the error code WSAEOPNOTSUPP will be returned by
/// transports that do not support partial message transmissions.
/// </term>
/// </item>
/// </list>
/// <para>
/// <c>Note</c> When issuing a blocking Winsock call such as <c>WSASendTo</c> with the lpOverlapped parameter set to <c>NULL</c>,
/// 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.
/// </para>
/// <para>Overlapped Socket I/O</para>
/// <para>
/// If an overlapped operation completes immediately, <c>WSASendTo</c> returns a value of zero and the lpNumberOfBytesSent parameter
/// is updated with the number of bytes sent. If the overlapped operation is successfully initiated and will complete later,
/// <c>WSASendTo</c> returns <c>SOCKET_ERROR</c> and indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesSent 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.
/// </para>
/// <para>
/// <c>Note</c> 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.
/// </para>
/// <para>
/// The <c>WSASendTo</c> function using overlapped I/O can be called from within the completion routine of a previous WSARecv,
/// WSARecvFrom, WSASend, or <c>WSASendTo</c> function. This permits time-sensitive data transmissions to occur entirely within a
/// preemptive context.
/// </para>
/// <para>
/// 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.
/// </para>
/// <para>
/// If the lpCompletionRoutine parameter is <c>NULL</c>, 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.
/// </para>
/// <para>
/// If lpCompletionRoutine is not <c>NULL</c>, 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- <c>NULL</c> lpCompletionRoutine and later calls
/// WSAGetOverlappedResult for the same overlapped I/O request may not set the fWait parameter for that invocation of
/// <c>WSAGetOverlappedResult</c> to <c>TRUE</c>. In this case the usage of the hEvent parameter is undefined, and attempting to
/// wait on the hEvent parameter would produce unpredictable results.
/// </para>
/// <para>
/// 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 <c>TRUE</c> is invoked.
/// </para>
/// <para>
/// Transport providers allow an application to invoke send and receive operations from within the context of the socket I/O
/// completion routine, and guarantee that, 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.
/// </para>
/// <para>The prototype of the completion routine is as follows.</para>
/// <para>
/// The CompletionRoutine function 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 lpOverlapped. The cbTransferred parameter
/// specifies the number of bytes sent. Currently there are no flag values defined and dwFlags will be zero. This function does not
/// return a value.
/// </para>
/// <para>
/// Returning from this function allows invocation of another pending completion routine for this socket. 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 in which the overlapped operations are completed.
/// However, the posted buffers are guaranteed to be sent in the same order they are specified.
/// </para>
/// <para>Example Code</para>
/// <para>The following example demonstrates the use of the <c>WSASendTo</c> function using an event object.</para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasendto int WSAAPI WSASendTo( SOCKET s, LPWSABUF
// lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, const sockaddr *lpTo, int iTolen, LPWSAOVERLAPPED
// lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "e3a11522-871c-4d6b-a2e6-ca91ffc2b698")]
public static extern WSRESULT WSASendTo(SOCKET s, [In, MarshalAs(UnmanagedType.LPArray)] WSABUF[] lpBuffers, uint dwBufferCount, out uint lpNumberOfBytesSent,
MsgFlags dwFlags, [In, Optional] SOCKADDR lpTo, int iTolen, [In, Out, Optional] IntPtr lpOverlapped,
[In, Optional, MarshalAs(UnmanagedType.FunctionPtr)] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
/// <summary>The <c>WSASendTo</c> function sends data to a specific destination, using overlapped I/O where applicable.</summary>
/// <param name="s">A descriptor identifying a (possibly connected) socket.</param>
/// <param name="lpBuffers">
/// A pointer to an array of WSABUF structures. Each <c>WSABUF</c> structure contains a pointer to a buffer and the length of the
/// buffer, in bytes. For a Winsock application, once the <c>WSASendTo</c> function is called, the system owns these buffers and the
/// application may not access them. This array must remain valid for the duration of the send operation.
/// </param>
/// <param name="dwBufferCount">The number of WSABUF structures in the lpBuffers array.</param>
/// <param name="lpNumberOfBytesSent">
/// <para>A pointer to the number of bytes sent by this call if the I/O operation completes immediately.</para>
/// <para>
/// Use <c>NULL</c> for this parameter if the lpOverlapped parameter is not <c>NULL</c> to avoid potentially erroneous results. This
/// parameter can be <c>NULL</c> only if the lpOverlapped parameter is not <c>NULL</c>.
/// </para>
/// </param>
/// <param name="dwFlags">The flags used to modify the behavior of the <c>WSASendTo</c> function call.</param>
/// <param name="lpTo">An optional pointer to the address of the target socket in the SOCKADDR structure.</param>
/// <param name="iTolen">The size, in bytes, of the address in the lpTo parameter.</param>
/// <param name="lpOverlapped">A pointer to a WSAOVERLAPPED structure (ignored for nonoverlapped sockets).</param>
/// <param name="lpCompletionRoutine">
/// A pointer to the completion routine called when the send operation has been completed (ignored for nonoverlapped sockets).
/// </param>
/// <returns>
/// <para>
/// If no error occurs and the send operation has completed immediately, <c>WSASendTo</c> 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
/// <c>SOCKET_ERROR</c> 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 overlapped operation was not successfully initiated and no completion
/// indication will occur.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAEACCES</term>
/// <term>The requested address is a broadcast address, but the appropriate flag was not set.</term>
/// </item>
/// <item>
/// <term>WSAEADDRNOTAVAIL</term>
/// <term>The remote address is not a valid address (such as ADDR_ANY).</term>
/// </item>
/// <item>
/// <term>WSAEAFNOSUPPORT</term>
/// <term>Addresses in the specified family cannot be used with this socket.</term>
/// </item>
/// <item>
/// <term>WSAECONNRESET</term>
/// <term>
/// For a UDP datagram socket, this error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message.
/// </term>
/// </item>
/// <item>
/// <term>WSAEDESTADDRREQ</term>
/// <term>A destination address is required.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>
/// The lpBuffers, lpTo, lpOverlapped, lpNumberOfBytesSent, or lpCompletionRoutine parameters are not part of the user address
/// space, or the lpTo parameter is too small.
/// </term>
/// </item>
/// <item>
/// <term>WSAEHOSTUNREACH</term>
/// <term>A socket operation was attempted to an unreachable host.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEINTR</term>
/// <term>A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>The socket has not been bound with bind, or the socket is not created with the overlapped flag.</term>
/// </item>
/// <item>
/// <term>WSAEMSGSIZE</term>
/// <term>The socket is message oriented, and the message is larger than the maximum supported by the underlying transport.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAENETRESET</term>
/// <term>For a datagram socket, this error indicates that the time to live has expired.</term>
/// </item>
/// <item>
/// <term>WSAENETUNREACH</term>
/// <term>The network cannot be reached from this host at this time.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>The Windows Sockets provider reports a buffer deadlock.</term>
/// </item>
/// <item>
/// <term>WSAENOTCONN</term>
/// <term>The socket is not connected (connection-oriented sockets only).</term>
/// </item>
/// <item>
/// <term>WSAENOTSOCK</term>
/// <term>The descriptor is not a socket.</term>
/// </item>
/// <item>
/// <term>WSAESHUTDOWN</term>
/// <term>
/// The socket has been shut down; it is not possible to WSASendTo on a socket after shutdown has been invoked with how set to
/// SD_SEND or SD_BOTH.
/// </term>
/// </item>
/// <item>
/// <term>WSAEWOULDBLOCK</term>
/// <term>
/// Windows NT: Overlapped sockets: there are too many outstanding overlapped I/O requests. Nonoverlapped sockets: The socket is
/// marked as nonblocking and the send operation cannot be completed immediately.
/// </term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSA_IO_PENDING</term>
/// <term>An overlapped operation was successfully initiated and completion will be indicated at a later time.</term>
/// </item>
/// <item>
/// <term>WSA_OPERATION_ABORTED</term>
/// <term>
/// The overlapped operation has been canceled due to the closure of the socket, or the execution of the SIO_FLUSH command in WSAIoctl.
/// </term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>The <c>WSASendTo</c> function provides enhanced features over the standard sendto function in two important areas:</para>
/// <list type="bullet">
/// <item>
/// <term>It can be used in conjunction with overlapped sockets to perform overlapped send operations.</term>
/// </item>
/// <item>
/// <term>It allows multiple send buffers to be specified making it applicable to the scatter/gather type of I/O.</term>
/// </item>
/// </list>
/// <para>
/// The <c>WSASendTo</c> function is normally used on a connectionless socket specified by s to send a datagram contained in one or
/// more buffers to a specific peer socket identified by the lpTo parameter. Even if the connectionless socket has been previously
/// connected using the connect function to a specific address, lpTo overrides the destination address for that particular datagram
/// only. On a connection-oriented socket, the lpTo and iToLen parameters are ignored; in this case, the <c>WSASendTo</c> is
/// equivalent to WSASend.
/// </para>
/// <para>
/// For overlapped sockets (created using WSASocket with flag <c>WSA_FLAG_OVERLAPPED</c>) sending data uses overlapped I/O, unless
/// both lpOverlapped and lpCompletionRoutine are <c>NULL</c> in which case the socket is treated as a nonoverlapped socket. A
/// completion indication will occur (invoking the completion routine or setting of an event object) when the buffer(s) have been
/// consumed by the transport. If the operation does not complete immediately, the final completion status is retrieved through the
/// completion routine or WSAGetOverlappedResult.
/// </para>
/// <para>
/// <c>Note</c> 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.
/// </para>
/// <para>
/// If both lpOverlapped and lpCompletionRoutine are <c>NULL</c>, the socket in this function will be treated as a nonoverlapped socket.
/// </para>
/// <para>
/// For nonoverlapped sockets, the last two parameters (lpOverlapped, lpCompletionRoutine) are ignored and <c>WSASendTo</c> adopts
/// the same blocking semantics as send. Data is copied from the buffer(s) into the transport buffer. If the socket is nonblocking
/// and stream oriented, and there is not sufficient space in the transport's buffer, <c>WSASendTo</c> returns with only part of the
/// application's buffers having been consumed. Given the same buffer situation and a blocking socket, <c>WSASendTo</c> will block
/// until all of the application's buffer contents have been consumed.
/// </para>
/// <para>
/// If this function is completed in an overlapped manner, it is the Winsock service provider's responsibility to capture the WSABUF
/// structures before returning from this call. This enables applications to build stack-based <c>WSABUF</c> arrays pointed to by
/// the lpBuffers parameter.
/// </para>
/// <para>
/// For message-oriented sockets, care must be taken not to exceed the maximum message size of the underlying transport, which can
/// be obtained by getting the value of socket option <c>SO_MAX_MSG_SIZE</c>. If the data is too long to pass atomically through the
/// underlying protocol the error WSAEMSGSIZE is returned, and no data is transmitted.
/// </para>
/// <para>
/// If the socket is unbound, unique values are assigned to the local association by the system, and the socket is then marked as bound.
/// </para>
/// <para>
/// If the socket is connected, the getsockname function can be used to determine the local IP address and port associated with the socket.
/// </para>
/// <para>
/// If the socket is not connected, the getsockname function can be used to determine the local port number associated with the
/// socket but the IP address returned is set to the wildcard address for the given protocol (for example, INADDR_ANY or "0.0.0.0"
/// for IPv4 and IN6ADDR_ANY_INIT or "::" for IPv6).
/// </para>
/// <para>The successful completion of a <c>WSASendTo</c> does not indicate that the data was successfully delivered.</para>
/// <para>
/// The dwFlags parameter can be used to influence the behavior of the function invocation beyond the options specified for the
/// associated socket. That is, the semantics of this function are determined by the socket options and the dwFlags parameter. The
/// latter is constructed by using the bitwise OR operator with any of any of the values listed in the following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>MSG_DONTROUTE</term>
/// <term>
/// Specifies that the data should not be subject to routing. A Windows Socket service provider may choose to ignore this flag.
/// </term>
/// </item>
/// <item>
/// <term>MSG_OOB</term>
/// <term>Send OOB data (stream-style socket such as SOCK_STREAM only).</term>
/// </item>
/// <item>
/// <term>MSG_PARTIAL</term>
/// <term>
/// Specifies that lpBuffers only contains a partial message. Be aware that the error code WSAEOPNOTSUPP will be returned by
/// transports that do not support partial message transmissions.
/// </term>
/// </item>
/// </list>
/// <para>
/// <c>Note</c> When issuing a blocking Winsock call such as <c>WSASendTo</c> with the lpOverlapped parameter set to <c>NULL</c>,
/// 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.
/// </para>
/// <para>Overlapped Socket I/O</para>
/// <para>
/// If an overlapped operation completes immediately, <c>WSASendTo</c> returns a value of zero and the lpNumberOfBytesSent parameter
/// is updated with the number of bytes sent. If the overlapped operation is successfully initiated and will complete later,
/// <c>WSASendTo</c> returns <c>SOCKET_ERROR</c> and indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesSent 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.
/// </para>
/// <para>
/// <c>Note</c> 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.
/// </para>
/// <para>
/// The <c>WSASendTo</c> function using overlapped I/O can be called from within the completion routine of a previous WSARecv,
/// WSARecvFrom, WSASend, or <c>WSASendTo</c> function. This permits time-sensitive data transmissions to occur entirely within a
/// preemptive context.
/// </para>
/// <para>
/// 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.
/// </para>
/// <para>
/// If the lpCompletionRoutine parameter is <c>NULL</c>, 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.
/// </para>
/// <para>
/// If lpCompletionRoutine is not <c>NULL</c>, 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- <c>NULL</c> lpCompletionRoutine and later calls
/// WSAGetOverlappedResult for the same overlapped I/O request may not set the fWait parameter for that invocation of
/// <c>WSAGetOverlappedResult</c> to <c>TRUE</c>. In this case the usage of the hEvent parameter is undefined, and attempting to
/// wait on the hEvent parameter would produce unpredictable results.
/// </para>
/// <para>
/// 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 <c>TRUE</c> is invoked.
/// </para>
/// <para>
/// Transport providers allow an application to invoke send and receive operations from within the context of the socket I/O
/// completion routine, and guarantee that, 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.
/// </para>
/// <para>The prototype of the completion routine is as follows.</para>
/// <para>
/// The CompletionRoutine function 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 lpOverlapped. The cbTransferred parameter
/// specifies the number of bytes sent. Currently there are no flag values defined and dwFlags will be zero. This function does not
/// return a value.
/// </para>
/// <para>
/// Returning from this function allows invocation of another pending completion routine for this socket. 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 in which the overlapped operations are completed.
/// However, the posted buffers are guaranteed to be sent in the same order they are specified.
/// </para>
/// <para>Example Code</para>
/// <para>The following example demonstrates the use of the <c>WSASendTo</c> function using an event object.</para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasendto int WSAAPI WSASendTo( SOCKET s, LPWSABUF
// lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, const sockaddr *lpTo, int iTolen, LPWSAOVERLAPPED
// lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "e3a11522-871c-4d6b-a2e6-ca91ffc2b698")]
public static extern WSRESULT WSASendTo(SOCKET s, [In, MarshalAs(UnmanagedType.LPArray)] WSABUF[] lpBuffers, uint dwBufferCount, out uint lpNumberOfBytesSent,
MsgFlags dwFlags, [In, Optional] SOCKADDR lpTo, int iTolen, ref WSAOVERLAPPED lpOverlapped,
[In, Optional, MarshalAs(UnmanagedType.FunctionPtr)] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine);
/// <summary>The <c>WSASetEvent</c> function sets the state of the specified event object to signaled.</summary>
/// <param name="hEvent">Handle that identifies an open event object.</param>
/// <returns>
/// <para>If the function succeeds, the return value is <c>TRUE</c>.</para>
/// <para>If the function fails, the return value is <c>FALSE</c>. To get extended error information, call WSAGetLastError.</para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSA_INVALID_HANDLE</term>
/// <term>The hEvent parameter is not a valid event object handle.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>The <c>WSASetEvent</c> function sets the state of the event object to be signaled.</para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasetevent BOOL WSAAPI WSASetEvent( WSAEVENT hEvent );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "8a3f41fe-77da-4e4e-975d-00eec7c11446")]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool WSASetEvent(WSAEVENT hEvent);
/// <summary>The <c>WSASetLastError</c> function sets the error code that can be retrieved through the WSAGetLastError function.</summary>
/// <param name="iError">Integer that specifies the error code to be returned by a subsequent WSAGetLastError call.</param>
/// <returns>
/// <para>This function generates no return values.</para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSASetLastError</c> function allows an application to set the error code to be returned by a subsequent WSAGetLastError
/// call for the current thread. Note that any subsequent Windows Sockets routine called by the application will override the error
/// code as set by this routine.
/// </para>
/// <para>
/// The error code set by <c>WSASetLastError</c> is different from the error code reset by calling the function getsockopt with SO_ERROR.
/// </para>
/// <para>The Windows Sockets error codes used by this function are listed under Windows Sockets Error Codes.</para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsasetlasterror void WSASetLastError( int iError );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock.h", MSDNShortId = "596155ee-3dcc-4ae3-97ab-0653e019cbee")]
public static extern void WSASetLastError(WSRESULT iError);
/// <summary>The <c>WSASetService</c> function registers or removes from the registry a service instance within one or more namespaces.</summary>
/// <param name="lpqsRegInfo">A pointer to the service information for registration or deregistration.</param>
/// <param name="essoperation">
/// <para>
/// A value that determines that operation requested. This parameter can be one of the values from the WSAESETSERVICEOP enumeration
/// type defined in the Winsock2.h header file.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>RNRSERVICE_REGISTER</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>RNRSERVICE_DEREGISTER</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>RNRSERVICE_DELETE</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="dwControlFlags">
/// <para>
/// Service install flags value that further controls the operation performed of the <c>WSASetService</c> function. The possible
/// values for this parameter are defined in the Winsock2.h header file.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Flag</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>SERVICE_MULTIPLE</term>
/// <term>
/// Controls scope of operation. When this flag is not set, service addresses are managed as a group. A register or removal from the
/// registry invalidates all existing addresses before adding the given address set. When set, the action is only performed on the
/// given address set. A register does not invalidate existing addresses and a removal from the registry only invalidates the given
/// set of addresses.
/// </term>
/// </item>
/// </list>
/// </param>
/// <returns>
/// <para>
/// The return value for <c>WSASetService</c> is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is
/// returned, and a specific error number can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAEACCES</term>
/// <term>The calling routine does not have sufficient privileges to install the Service.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>One or more required parameters were invalid or missing.</term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>
/// The Ws2_32.dll has not been initialized. The application must first call WSAStartup before calling any Windows Sockets functions.
/// </term>
/// </item>
/// <item>
/// <term>WSA_NOT_ENOUGH_MEMORY</term>
/// <term>There was insufficient memory to perform the operation.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSASetService</c> function can be used to affect a specific namespace provider, all providers associated with a specific
/// namespace, or all providers across all namespaces.
/// </para>
/// <para>
/// The available values for essOperation and dwControlFlags combine to control operation of the <c>WSASetService</c> function as
/// shown in the following table.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Operation</term>
/// <term>Flags</term>
/// <term>Service already exists</term>
/// <term>Service does not exist</term>
/// </listheader>
/// <item>
/// <term>RNRSERVICE_REGISTER</term>
/// <term>None</term>
/// <term>Overwrites the object. Uses only addresses specified. The object is REGISTERED.</term>
/// <term>Creates a new object. Uses only addresses specified. Object is REGISTERED.</term>
/// </item>
/// <item>
/// <term>RNRSERVICE_REGISTER</term>
/// <term>SERVICE_MULTIPLE</term>
/// <term>Updates the object. Adds new addresses to the existing set. The object is REGISTERED.</term>
/// <term>Creates a new object. Uses all addresses specified. Object is REGISTERED.</term>
/// </item>
/// <item>
/// <term>RNRSERVICE_DEREGISTER</term>
/// <term>None</term>
/// <term>Removes all addresses, but does not remove the object from the namespace. The object is removed from the registry.</term>
/// <term>WSASERVICE_NOT_FOUND</term>
/// </item>
/// <item>
/// <term>RNRSERVICE_DEREGISTER</term>
/// <term>SERVICE_MULTIPLE</term>
/// <term>
/// Updates the object. Removes only addresses that are specified. Only marks the object as DEREGISTERED if no addresses are
/// present. Does not remove the object from the namespace.
/// </term>
/// <term>WSASERVICE_NOT_FOUND</term>
/// </item>
/// <item>
/// <term>RNRSERVICE_DELETE</term>
/// <term>None</term>
/// <term>Removes the object from the namespace.</term>
/// <term>WSASERVICE_NOT_FOUND</term>
/// </item>
/// <item>
/// <term>RNRSERVICE_DELETE</term>
/// <term>SERVICE_MULTIPLE</term>
/// <term>Removes only addresses that are specified. Only removes object from the namespace if no addresses remain.</term>
/// <term>WSASERVICE_NOT_FOUND</term>
/// </item>
/// </list>
/// <para>
/// Publishing services to directories, such as Active Directory Services, is restricted based on access control lists (ACLs). For
/// more information, see Security Issues for Service Publication.
/// </para>
/// <para>
/// When the dwControlFlags parameter is set to <c>SERVICE_MULTIPLE</c>, an application can manage its addresses independently. This
/// is useful when the application wants to manage its protocols individually or when the service resides on more than one computer.
/// For instance, when a service uses more than one protocol, it may find that one listening socket aborts but the other sockets
/// remain operational. In this case, the service could remove the aborted address from the registry without affecting the other addresses.
/// </para>
/// <para>
/// When the dwControlFlags parameter is set to <c>SERVICE_MULTIPLE</c>, an application must not let stale addresses remain in the
/// object. This can happen if the application aborts without issuing a DEREGISTER request. When a service registers, it should
/// store its addresses. On its next invocation, the service should explicitly remove these old stale addresses from the registry
/// before registering new addresses.
/// </para>
/// <para>
/// <c>Note</c> If ANSI character strings are used, there is a chance that the WSAQUERYSET data in lpqsRegInfo may not contain any
/// results after this function returns. This is because the ANSI version of this method, <c>WSASetServiceA</c>, converts the ANSI
/// data in <c>WSAQUERYSET</c> to Unicode internally, but does not convert the results back to ANSI. This primarily impacts
/// transports that return a "service record handle" used to uniquely identify a record. To work around this issue, applications
/// should use Unicode string data in <c>WSAQUERYSET</c> when calling this function.
/// </para>
/// <para>Service Properties</para>
/// <para>
/// The following table describes how service property data is represented in a WSAQUERYSET structure. Fields labeled as (Optional)
/// can contain a null pointer.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>WSAQUERYSET member</term>
/// <term>Service property description</term>
/// </listheader>
/// <item>
/// <term>dwSize</term>
/// <term>Must be set to sizeof (WSAQUERYSET). This is a versioning mechanism.</term>
/// </item>
/// <item>
/// <term>dwOutputFlags</term>
/// <term>Not applicable and ignored.</term>
/// </item>
/// <item>
/// <term>lpszServiceInstanceName</term>
/// <term>Referenced string contains the service instance name.</term>
/// </item>
/// <item>
/// <term>lpServiceClassId</term>
/// <term>The GUID corresponding to this service class.</term>
/// </item>
/// <item>
/// <term>lpVersion</term>
/// <term>(Optional) Supplies service instance version number.</term>
/// </item>
/// <item>
/// <term>lpszComment</term>
/// <term>(Optional) An optional comment string.</term>
/// </item>
/// <item>
/// <term>dwNameSpace</term>
/// <term>See table that follows.</term>
/// </item>
/// <item>
/// <term>lpNSProviderId</term>
/// <term>See table that follows.</term>
/// </item>
/// <item>
/// <term>lpszContext</term>
/// <term>(Optional) Specifies the starting point of the query in a hierarchical namespace.</term>
/// </item>
/// <item>
/// <term>dwNumberOfProtocols</term>
/// <term>Ignored.</term>
/// </item>
/// <item>
/// <term>lpafpProtocols</term>
/// <term>Ignored.</term>
/// </item>
/// <item>
/// <term>lpszQueryString</term>
/// <term>Ignored.</term>
/// </item>
/// <item>
/// <term>dwNumberOfCsAddrs</term>
/// <term>The number of elements in the array of CSADDR_INFO structures referenced by lpcsaBuffer.</term>
/// </item>
/// <item>
/// <term>lpcsaBuffer</term>
/// <term>A pointer to an array of CSADDR_INFO structures that contain the address(es) that the service is listening on.</term>
/// </item>
/// <item>
/// <term>lpBlob</term>
/// <term>(Optional) This is a pointer to a provider-specific entity.</term>
/// </item>
/// </list>
/// <para>
/// As illustrated in the following, the combination of the <c>dwNameSpace</c> and <c>lpNSProviderId</c> members determine that
/// namespace providers are affected by this function.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>dwNameSpace</term>
/// <term>lpNSProviderId</term>
/// <term>Scope of impact</term>
/// </listheader>
/// <item>
/// <term>Ignored</term>
/// <term>Non-null</term>
/// <term>The specified name-space provider.</term>
/// </item>
/// <item>
/// <term>A valid name- space identifier</term>
/// <term>Null</term>
/// <term>All name-space providers that support the indicated namespace.</term>
/// </item>
/// <item>
/// <term>NS_ALL</term>
/// <term>Null</term>
/// <term>All name-space providers.</term>
/// </item>
/// </list>
/// <para>
/// <c>Windows Phone 8:</c> The <c>WSASetServiceW</c> function is supported for Windows Phone Store apps on Windows Phone 8 and later.
/// </para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: The <c>WSASetServiceW</c> function is supported for Windows Store apps on
/// Windows 8.1, Windows Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasetservicea INT WSAAPI WSASetServiceA( LPWSAQUERYSETA
// lpqsRegInfo, WSAESETSERVICEOP essoperation, DWORD dwControlFlags );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winsock2.h", MSDNShortId = "21a8ff26-4c9e-4846-a75a-1a27c746edab")]
public static extern WSRESULT WSASetService(in WSAQUERYSET lpqsRegInfo, WSAESETSERVICEOP essoperation, ServiceInstallFlags dwControlFlags);
/// <summary>The <c>WSASocket</c> function creates a socket that is bound to a specific transport-service provider.</summary>
/// <param name="af">
/// <para>The address family specification. Possible values for the address family are defined in the Winsock2.h header file.</para>
/// <para>
/// 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.
/// </para>
/// <para>
/// 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, <c>AF_INET</c> and <c>PF_INET</c>), so either constant can be used.
/// </para>
/// <para>The table below lists common values for address family although many other values are possible.</para>
/// <list type="table">
/// <listheader>
/// <term>Af</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>AF_UNSPEC 0</term>
/// <term>The address family is unspecified.</term>
/// </item>
/// <item>
/// <term>AF_INET 2</term>
/// <term>The Internet Protocol version 4 (IPv4) address family.</term>
/// </item>
/// <item>
/// <term>AF_IPX 6</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>AF_APPLETALK 16</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>AF_NETBIOS 17</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>AF_INET6 23</term>
/// <term>The Internet Protocol version 6 (IPv6) address family.</term>
/// </item>
/// <item>
/// <term>AF_IRDA 26</term>
/// <term>
/// The Infrared Data Association (IrDA) address family. This address family is only supported if the computer has an infrared port
/// and driver installed.
/// </term>
/// </item>
/// <item>
/// <term>AF_BTH 32</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="type">
/// <para>The type specification for the new socket.</para>
/// <para>Possible values for the socket type are defined in the Winsock2.h header file.</para>
/// <para>The following table lists the possible values for the type parameter supported for Windows Sockets 2:</para>
/// <list type="table">
/// <listheader>
/// <term>Type</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>SOCK_STREAM 1</term>
/// <term>
/// 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).
/// </term>
/// </item>
/// <item>
/// <term>SOCK_DGRAM 2</term>
/// <term>
/// 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).
/// </term>
/// </item>
/// <item>
/// <term>SOCK_RAW 3</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>SOCK_RDM 4</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>SOCK_SEQPACKET 5</term>
/// <term>A socket type that provides a pseudo-stream packet based on datagrams.</term>
/// </item>
/// </list>
/// <para>
/// 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.
/// </para>
/// <para>In Windows Sockets 1.1, the only possible socket types are <c>SOCK_DGRAM</c> and <c>SOCK_STREAM</c>.</para>
/// </param>
/// <param name="protocol">
/// <para>
/// The protocol to be used. The possible options for the protocol parameter are specific to the address family and socket type
/// specified. Possible values for the protocol are defined are defined in the Winsock2.h and Wsrm.h header files.
/// </para>
/// <para>
/// 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 <c>IPPROTO</c> 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.
/// </para>
/// <para>
/// If a value of 0 is specified, the caller does not wish to specify a protocol and the service provider will choose the protocol
/// to use.
/// </para>
/// <para>
/// When the af parameter is AF_INET or AF_INET6 and the type is <c>SOCK_RAW</c>, the value specified for the protocol is set in the
/// protocol field of the IPv6 or IPv4 packet header.
/// </para>
/// <para>The table below lists common values for the protocol although many other values are possible.</para>
/// <list type="table">
/// <listheader>
/// <term>protocol</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>IPPROTO_ICMP 1</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>IPPROTO_IGMP 2</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>BTHPROTO_RFCOMM 3</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>IPPROTO_TCP 6</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>IPPROTO_UDP 17</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>IPPROTO_ICMPV6 58</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>IPPROTO_RM 113</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="lpProtocolInfo">
/// A pointer to a WSAPROTOCOL_INFO structure that defines the characteristics of the socket to be created. If this parameter is not
/// <c>NULL</c>, the socket will be bound to the provider associated with the indicated <c>WSAPROTOCOL_INFO</c> structure.
/// </param>
/// <param name="g">
/// <para>An existing socket group ID or an appropriate action to take when creating a new socket and a new socket group.</para>
/// <para>
/// If g is an existing socket group ID, join the new socket to this socket group, provided all the requirements set by this group
/// are met.
/// </para>
/// <para>If g is not an existing socket group ID, then the following values are possible.</para>
/// <list type="table">
/// <listheader>
/// <term>g</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>0</term>
/// <term>No group operation is performed.</term>
/// </item>
/// <item>
/// <term>SG_UNCONSTRAINED_GROUP 0x01</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>SG_CONSTRAINED_GROUP 0x02</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// </list>
/// <para>
/// <c>Note</c> The SG_UNCONSTRAINED_GROUP and SG_CONSTRAINED_GROUP constants are not currently defined in a public header file.
/// </para>
/// </param>
/// <param name="dwFlags">
/// <para>A set of flags used to specify additional socket attributes.</para>
/// <para>A combination of these flags may be set, although some combinations are not allowed.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSA_FLAG_OVERLAPPED 0x01</term>
/// <term>
/// Create a socket that supports overlapped I/O operations. Most sockets should be created with this flag set. Overlapped sockets
/// can utilize WSASend, WSASendTo, WSARecv, WSARecvFrom, and WSAIoctl for overlapped I/O operations, which allow multiple
/// operations to be initiated and in progress simultaneously. All functions that allow overlapped operation (WSASend, WSARecv,
/// WSASendTo, WSARecvFrom, WSAIoctl) also support nonoverlapped usage on an overlapped socket if the values for parameters related
/// to overlapped operations are NULL.
/// </term>
/// </item>
/// <item>
/// <term>WSA_FLAG_MULTIPOINT_C_ROOT 0x02</term>
/// <term>
/// Create a socket that will be a c_root in a multipoint session. This attribute is only allowed if the WSAPROTOCOL_INFO structure
/// for the transport provider that creates the socket supports a multipoint or multicast mechanism and the control plane for a
/// multipoint session is rooted. This would be indicated by the dwServiceFlags1 member of the WSAPROTOCOL_INFO structure with the
/// XP1_SUPPORT_MULTIPOINT and XP1_MULTIPOINT_CONTROL_PLANE flags set. When the lpProtocolInfo parameter is not NULL, the
/// WSAPROTOCOL_INFO structure for the transport provider is pointed to by the lpProtocolInfo parameter. When the lpProtocolInfo
/// parameter is NULL, the WSAPROTOCOL_INFO structure is based on the transport provider selected by the values specified for the
/// af, type, and protocol parameters. Refer to Multipoint and Multicast Semantics for additional information on a multipoint session.
/// </term>
/// </item>
/// <item>
/// <term>WSA_FLAG_MULTIPOINT_C_LEAF 0x04</term>
/// <term>
/// Create a socket that will be a c_leaf in a multipoint session. This attribute is only allowed if the WSAPROTOCOL_INFO structure
/// for the transport provider that creates the socket supports a multipoint or multicast mechanism and the control plane for a
/// multipoint session is non-rooted. This would be indicated by the dwServiceFlags1 member of the WSAPROTOCOL_INFO structure with
/// the XP1_SUPPORT_MULTIPOINT flag set and the XP1_MULTIPOINT_CONTROL_PLANE flag not set. When the lpProtocolInfo parameter is not
/// NULL, the WSAPROTOCOL_INFO structure for the transport provider is pointed to by the lpProtocolInfo parameter. When the
/// lpProtocolInfo parameter is NULL, the WSAPROTOCOL_INFO structure is based on the transport provider selected by the values
/// specified for the af, type, and protocol parameters. Refer to Multipoint and Multicast Semantics for additional information on a
/// multipoint session.
/// </term>
/// </item>
/// <item>
/// <term>WSA_FLAG_MULTIPOINT_D_ROOT 0x08</term>
/// <term>
/// Create a socket that will be a d_root in a multipoint session. This attribute is only allowed if the WSAPROTOCOL_INFO structure
/// for the transport provider that creates the socket supports a multipoint or multicast mechanism and the data plane for a
/// multipoint session is rooted. This would be indicated by the dwServiceFlags1 member of the WSAPROTOCOL_INFO structure with the
/// XP1_SUPPORT_MULTIPOINT and XP1_MULTIPOINT_DATA_PLANE flags set. When the lpProtocolInfo parameter is not NULL, the
/// WSAPROTOCOL_INFO structure for the transport provider is pointed to by the lpProtocolInfo parameter. When the lpProtocolInfo
/// parameter is NULL, the WSAPROTOCOL_INFO structure is based on the transport provider selected by the values specified for the
/// af, type, and protocol parameters. Refer to Multipoint and Multicast Semantics for additional information on a multipoint session.
/// </term>
/// </item>
/// <item>
/// <term>WSA_FLAG_MULTIPOINT_D_LEAF 0x10</term>
/// <term>
/// Create a socket that will be a d_leaf in a multipoint session. This attribute is only allowed if the WSAPROTOCOL_INFO structure
/// for the transport provider that creates the socket supports a multipoint or multicast mechanism and the data plane for a
/// multipoint session is non-rooted. This would be indicated by the dwServiceFlags1 member of the WSAPROTOCOL_INFO structure with
/// the XP1_SUPPORT_MULTIPOINT flag set and the XP1_MULTIPOINT_DATA_PLANE flag not set. When the lpProtocolInfo parameter is not
/// NULL, the WSAPROTOCOL_INFO structure for the transport provider is pointed to by the lpProtocolInfo parameter. When the
/// lpProtocolInfo parameter is NULL, the WSAPROTOCOL_INFO structure is based on the transport provider selected by the values
/// specified for the af, type, and protocol parameters. Refer to Multipoint and Multicast Semantics for additional information on a
/// multipoint session.
/// </term>
/// </item>
/// <item>
/// <term>WSA_FLAG_ACCESS_SYSTEM_SECURITY 0x40</term>
/// <term>
/// Create a socket that allows the the ability to set a security descriptor on the socket that contains a security access control
/// list (SACL) as opposed to just a discretionary access control list (DACL). SACLs are used for generating audits and alarms when
/// an access check occurs on the object. For a socket, an access check occurs to determine whether the socket should be allowed to
/// bind to a specific address specified to the bind function. The ACCESS_SYSTEM_SECURITY access right controls the ability to get
/// or set the SACL in an object's security descriptor. The system grants this access right only if the SE_SECURITY_NAME privilege
/// is enabled in the access token of the requesting thread.
/// </term>
/// </item>
/// <item>
/// <term>WSA_FLAG_NO_HANDLE_INHERIT 0x80</term>
/// <term>
/// Create a socket that is non-inheritable. A socket handle created by the WSASocket or the socket function is inheritable by
/// default. When this flag is set, the socket handle is non-inheritable. The GetHandleInformation function can be used to determine
/// if a socket handle was created with the WSA_FLAG_NO_HANDLE_INHERIT flag set. The GetHandleInformation function will return that
/// the HANDLE_FLAG_INHERIT value is set. This flag is supported on Windows 7 with SP1, Windows Server 2008 R2 with SP1, and later
/// </term>
/// </item>
/// </list>
/// <para>
/// <c>Important</c> For multipoint sockets, only one of <c>WSA_FLAG_MULTIPOINT_C_ROOT</c> or <c>WSA_FLAG_MULTIPOINT_C_LEAF</c>
/// flags can be specified, and only one of <c>WSA_FLAG_MULTIPOINT_D_ROOT</c> or <c>WSA_FLAG_MULTIPOINT_D_LEAF</c> flags can be
/// specified. Refer to Multipoint and Multicast Semantics for additional information.
/// </para>
/// </param>
/// <returns>
/// <para>
/// If no error occurs, <c>WSASocket</c> returns a descriptor referencing the new socket. Otherwise, a value of INVALID_SOCKET is
/// returned, and a specific error code can be retrieved by calling WSAGetLastError.
/// </para>
/// <para><c>Note</c> This error code description is Microsoft-specific.</para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEAFNOSUPPORT</term>
/// <term>The specified address family is not supported.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The lpProtocolInfo parameter is not in a valid part of the process address space.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>This value is true for any of the following conditions.</term>
/// </item>
/// <item>
/// <term>WSAEINVALIDPROVIDER</term>
/// <term>The service provider returned a version other than 2.2.</term>
/// </item>
/// <item>
/// <term>WSAEINVALIDPROCTABLE</term>
/// <term>The service provider returned an invalid or incomplete procedure table to the WSPStartup.</term>
/// </item>
/// <item>
/// <term>WSAEMFILE</term>
/// <term>No more socket descriptors are available.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>No buffer space is available. The socket cannot be created.</term>
/// </item>
/// <item>
/// <term>WSAEPROTONOSUPPORT</term>
/// <term>The specified protocol is not supported.</term>
/// </item>
/// <item>
/// <term>WSAEPROTOTYPE</term>
/// <term>The specified protocol is the wrong type for this socket.</term>
/// </item>
/// <item>
/// <term>WSAEPROVIDERFAILEDINIT</term>
/// <term>
/// The service provider failed to initialize. This error is returned if a layered service provider (LSP) or namespace provider was
/// improperly installed or the provider fails to operate correctly.
/// </term>
/// </item>
/// <item>
/// <term>WSAESOCKTNOSUPPORT</term>
/// <term>The specified socket type is not supported in this address family.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSASocket</c> function causes a socket descriptor and any related resources to be allocated and associated with a
/// transport-service provider. Most sockets should be created with the <c>WSA_FLAG_OVERLAPPED</c> attribute set in the dwFlags
/// parameter. A socket created with this attribute supports the use of overlapped I/O operations which provide higher performance.
/// By default, a socket created with the <c>WSASocket</c> function will not have this overlapped attribute set. In contrast, the
/// socket function creates a socket that supports overlapped I/O operations as the default behavior.
/// </para>
/// <para>
/// If the lpProtocolInfo parameter is <c>NULL</c>, Winsock will utilize the first available transport-service provider that
/// supports the requested combination of address family, socket type and protocol specified in the af, type, and protocol parameters.
/// </para>
/// <para>
/// If the lpProtocolInfo parameter is not <c>NULL</c>, the socket will be bound to the provider associated with the indicated
/// WSAPROTOCOL_INFO structure. In this instance, the application can supply the manifest constant <c>FROM_PROTOCOL_INFO</c> as the
/// value for any of af, type, or protocol parameters. This indicates that the corresponding values from the indicated
/// <c>WSAPROTOCOL_INFO</c> structure ( <c>iAddressFamily</c>, <c>iSocketType</c>, <c>iProtocol</c>) are to be assumed. In any case,
/// the values specified for af, type, and protocol are passed unmodified to the transport-service provider.
/// </para>
/// <para>
/// When selecting a protocol and its supporting service provider based on af, type, and protocol, this procedure will only choose a
/// base protocol or a protocol chain, not a protocol layer by itself. Unchained protocol layers are not considered to have partial
/// matches on type or af, either. That is, they do not lead to an error code of WSAEAFNOSUPPORT or WSAEPROTONOSUPPORT, if no
/// suitable protocol is found.
/// </para>
/// <para>
/// <c>Note</c> The manifest constant <c>AF_UNSPEC</c> continues to be defined in the header file but its use is strongly
/// discouraged, as this can cause ambiguity in interpreting the value of the protocol parameter.
/// </para>
/// <para>
/// Applications are encouraged to use <c>AF_INET6</c> for the af parameter and create a dual-mode socket that can be used with both
/// IPv4 and IPv6.
/// </para>
/// <para>
/// If a socket is created using the <c>WSASocket</c> function, then the dwFlags parameter must have the <c>WSA_FLAG_OVERLAPPED</c>
/// attribute set for the <c>SO_RCVTIMEO</c> or <c>SO_SNDTIMEO</c> socket options to function properly. Otherwise the timeout never
/// takes effect on the socket.
/// </para>
/// <para>
/// Connection-oriented sockets such as <c>SOCK_STREAM</c> provide full-duplex connections, and must be in a connected state before
/// any data can be sent or received on them. A connection to a specified socket is established with a connect or WSAConnect
/// function call. Once connected, data can be transferred using send/WSASend and recv/WSARecv calls. When a session has been
/// completed, the closesocket function should be called to release the resources associated with the socket. For
/// connection-oriented sockets, the shutdown function should be called to stop data transfer on the socket before calling the
/// <c>closesocket</c> function.
/// </para>
/// <para>
/// The communications protocols used to implement a reliable, connection-oriented socket ensure that data is not lost or
/// duplicated. If data for which the peer protocol has buffer space cannot be successfully transmitted within a reasonable length
/// of time, the connection is considered broken and subsequent calls will fail with the error code set to WSAETIMEDOUT.
/// </para>
/// <para>
/// Connectionless, message-oriented sockets allow sending and receiving of datagrams to and from arbitrary peers using
/// sendto/WSASendTo and recvfrom/WSARecvFrom. If such a socket is connected to a specific peer, datagrams can be sent to that peer
/// using send/WSASend and can be received from (only) this peer using recv/WSARecv.
/// </para>
/// <para>
/// Support for sockets with type <c>SOCK_RAW</c> is not required, but service providers are encouraged to support raw sockets
/// whenever possible.
/// </para>
/// <para>
/// The <c>WSASocket</c> function can be used to create a socket to be used by a service so that if another socket tries to bind to
/// the same port used by the service, and audit record is generared. To enable this option, an application would need to do the following:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// Call the AdjustTokenPrivileges function to enable the <c>SE_SECURITY_NAME</c> privilege in the access token for the process.
/// This privilege is required to set the <c>ACCESS_SYSTEM_SECURITY</c> access rights on the security descriptor for an object.
/// </term>
/// </item>
/// <item>
/// <term>
/// Call the <c>WSASocket</c> function to create a socket with dwFlag with the <c>WSA_FLAG_ACCESS_SYSTEM_SECURITY</c> option set.
/// The <c>WSASocket</c> function will fail if the AdjustTokenPrivileges function is not called first to enable the
/// <c>SE_SECURITY_NAME</c> privilege needed for this operation.
/// </term>
/// </item>
/// <item>
/// <term>
/// Call the SetSecurityInfo function to set a security descriptor with a System Access Control List (SACL) on the socket. The
/// socket handle returned by the <c>WSASocket</c> function is passed in the handle parameter. If the function succeeds, this will
/// set the the <c>ACCESS_SYSTEM_SECURITY</c> access right on the security descriptor for the socket.
/// </term>
/// </item>
/// <item>
/// <term>
/// Call the bindfunction to bind the socket to a specific port. If the <c>bind</c> function succeeds, then an audit entry is
/// generated if another socket tries to bind to the same port.
/// </term>
/// </item>
/// <item>
/// <term>
/// Call the AdjustTokenPrivileges function to remove the <c>SE_SECURITY_NAME</c> privilege in the access token for the process,
/// since this is no longer needed.
/// </term>
/// </item>
/// </list>
/// <para>
/// For more information on <c>ACCESS_SYSTEM_SECURITY</c>, see SACL Access Right and Audit Generation in the Authorization documentation.
/// </para>
/// <para>Socket Groups</para>
/// <para>
/// WinSock 2 introduced the notion of a socket group as a means for an application, or cooperating set of applications, to indicate
/// to an underlying service provider that a particular set of sockets are related and that the group thus formed has certain
/// attributes. Group attributes include relative priorities of the individual sockets within the group and a group quality of
/// service specification.
/// </para>
/// <para>
/// Applications that need to exchange multimedia streams over the network are an example where being able to establish a specific
/// relationship among a set of sockets could be beneficial. It is up to the transport on how to treat socket groups.
/// </para>
/// <para>
/// The <c>WSASocket</c> and WSAAccept functions can be used to explicitly create and join a socket group when creating a new
/// socket. The socket group ID for a socket can be retrieved by using the getsockopt function with level parameter set to
/// SOL_SOCKET and the optname parameter set to <c>SO_GROUP_ID</c>. 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 of zero indicates that the socket is not member of a socket group.
/// </para>
/// <para>
/// The relative group priority of a socket group can be accessed by using the getsockopt function with the level parameter set to
/// SOL_SOCKET and the optname parameter set to <c>SO_GROUP_PRIORITY</c>. The relative group priority of a socket group can be set
/// by using setsockopt with the level parameter set to SOL_SOCKET and the optname parameter set to <c>SO_GROUP_PRIORITY</c>.
/// </para>
/// <para>
/// The Winsock provider included with Windows allows the creation of socket groups and it enforces the SG_CONSTRAINED_GROUP. All
/// sockets in a constrained socket group must be 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. This is the only restriction applied to a socket group by the Winsock provider included with
/// Windows. The socket group priority is not currently used by the Winsock provider or the TCP/IP stack included with Windows.
/// </para>
/// <para>Example Code</para>
/// <para>The following example demonstrates the use of the <c>WSASocket</c> function.</para>
/// <para>
/// <c>Windows Phone 8:</c> The <c>WSASocketW</c> function is supported for Windows Phone Store apps on Windows Phone 8 and later.
/// </para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: The <c>WSASocketW</c> function is supported for Windows Store apps on
/// Windows 8.1, Windows Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasocketa SOCKET WSAAPI WSASocketA( int af, int type,
// int protocol, LPWSAPROTOCOL_INFOA lpProtocolInfo, GROUP g, DWORD dwFlags );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winsock2.h", MSDNShortId = "dcf2e543-de54-43d9-9e45-4cb935da3548")]
public static extern SOCKET WSASocket(ADDRESS_FAMILY af, SOCK type, IPPROTO protocol, in WSAPROTOCOL_INFO lpProtocolInfo, GROUP g, WSA_FLAG dwFlags);
/// <summary>The <c>WSASocket</c> function creates a socket that is bound to a specific transport-service provider.</summary>
/// <param name="af">
/// <para>The address family specification. Possible values for the address family are defined in the Winsock2.h header file.</para>
/// <para>
/// 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.
/// </para>
/// <para>
/// 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, <c>AF_INET</c> and <c>PF_INET</c>), so either constant can be used.
/// </para>
/// <para>The table below lists common values for address family although many other values are possible.</para>
/// <list type="table">
/// <listheader>
/// <term>Af</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>AF_UNSPEC 0</term>
/// <term>The address family is unspecified.</term>
/// </item>
/// <item>
/// <term>AF_INET 2</term>
/// <term>The Internet Protocol version 4 (IPv4) address family.</term>
/// </item>
/// <item>
/// <term>AF_IPX 6</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>AF_APPLETALK 16</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>AF_NETBIOS 17</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>AF_INET6 23</term>
/// <term>The Internet Protocol version 6 (IPv6) address family.</term>
/// </item>
/// <item>
/// <term>AF_IRDA 26</term>
/// <term>
/// The Infrared Data Association (IrDA) address family. This address family is only supported if the computer has an infrared port
/// and driver installed.
/// </term>
/// </item>
/// <item>
/// <term>AF_BTH 32</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="type">
/// <para>The type specification for the new socket.</para>
/// <para>Possible values for the socket type are defined in the Winsock2.h header file.</para>
/// <para>The following table lists the possible values for the type parameter supported for Windows Sockets 2:</para>
/// <list type="table">
/// <listheader>
/// <term>Type</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>SOCK_STREAM 1</term>
/// <term>
/// 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).
/// </term>
/// </item>
/// <item>
/// <term>SOCK_DGRAM 2</term>
/// <term>
/// 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).
/// </term>
/// </item>
/// <item>
/// <term>SOCK_RAW 3</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>SOCK_RDM 4</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>SOCK_SEQPACKET 5</term>
/// <term>A socket type that provides a pseudo-stream packet based on datagrams.</term>
/// </item>
/// </list>
/// <para>
/// 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.
/// </para>
/// <para>In Windows Sockets 1.1, the only possible socket types are <c>SOCK_DGRAM</c> and <c>SOCK_STREAM</c>.</para>
/// </param>
/// <param name="protocol">
/// <para>
/// The protocol to be used. The possible options for the protocol parameter are specific to the address family and socket type
/// specified. Possible values for the protocol are defined are defined in the Winsock2.h and Wsrm.h header files.
/// </para>
/// <para>
/// 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 <c>IPPROTO</c> 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.
/// </para>
/// <para>
/// If a value of 0 is specified, the caller does not wish to specify a protocol and the service provider will choose the protocol
/// to use.
/// </para>
/// <para>
/// When the af parameter is AF_INET or AF_INET6 and the type is <c>SOCK_RAW</c>, the value specified for the protocol is set in the
/// protocol field of the IPv6 or IPv4 packet header.
/// </para>
/// <para>The table below lists common values for the protocol although many other values are possible.</para>
/// <list type="table">
/// <listheader>
/// <term>protocol</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>IPPROTO_ICMP 1</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>IPPROTO_IGMP 2</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>BTHPROTO_RFCOMM 3</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>IPPROTO_TCP 6</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>IPPROTO_UDP 17</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>IPPROTO_ICMPV6 58</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>IPPROTO_RM 113</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// </list>
/// </param>
/// <param name="lpProtocolInfo">
/// A pointer to a WSAPROTOCOL_INFO structure that defines the characteristics of the socket to be created. If this parameter is not
/// <c>NULL</c>, the socket will be bound to the provider associated with the indicated <c>WSAPROTOCOL_INFO</c> structure.
/// </param>
/// <param name="g">
/// <para>An existing socket group ID or an appropriate action to take when creating a new socket and a new socket group.</para>
/// <para>
/// If g is an existing socket group ID, join the new socket to this socket group, provided all the requirements set by this group
/// are met.
/// </para>
/// <para>If g is not an existing socket group ID, then the following values are possible.</para>
/// <list type="table">
/// <listheader>
/// <term>g</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>0</term>
/// <term>No group operation is performed.</term>
/// </item>
/// <item>
/// <term>SG_UNCONSTRAINED_GROUP 0x01</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// <item>
/// <term>SG_CONSTRAINED_GROUP 0x02</term>
/// <term>
/// 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.
/// </term>
/// </item>
/// </list>
/// <para>
/// <c>Note</c> The SG_UNCONSTRAINED_GROUP and SG_CONSTRAINED_GROUP constants are not currently defined in a public header file.
/// </para>
/// </param>
/// <param name="dwFlags">
/// <para>A set of flags used to specify additional socket attributes.</para>
/// <para>A combination of these flags may be set, although some combinations are not allowed.</para>
/// <list type="table">
/// <listheader>
/// <term>Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSA_FLAG_OVERLAPPED 0x01</term>
/// <term>
/// Create a socket that supports overlapped I/O operations. Most sockets should be created with this flag set. Overlapped sockets
/// can utilize WSASend, WSASendTo, WSARecv, WSARecvFrom, and WSAIoctl for overlapped I/O operations, which allow multiple
/// operations to be initiated and in progress simultaneously. All functions that allow overlapped operation (WSASend, WSARecv,
/// WSASendTo, WSARecvFrom, WSAIoctl) also support nonoverlapped usage on an overlapped socket if the values for parameters related
/// to overlapped operations are NULL.
/// </term>
/// </item>
/// <item>
/// <term>WSA_FLAG_MULTIPOINT_C_ROOT 0x02</term>
/// <term>
/// Create a socket that will be a c_root in a multipoint session. This attribute is only allowed if the WSAPROTOCOL_INFO structure
/// for the transport provider that creates the socket supports a multipoint or multicast mechanism and the control plane for a
/// multipoint session is rooted. This would be indicated by the dwServiceFlags1 member of the WSAPROTOCOL_INFO structure with the
/// XP1_SUPPORT_MULTIPOINT and XP1_MULTIPOINT_CONTROL_PLANE flags set. When the lpProtocolInfo parameter is not NULL, the
/// WSAPROTOCOL_INFO structure for the transport provider is pointed to by the lpProtocolInfo parameter. When the lpProtocolInfo
/// parameter is NULL, the WSAPROTOCOL_INFO structure is based on the transport provider selected by the values specified for the
/// af, type, and protocol parameters. Refer to Multipoint and Multicast Semantics for additional information on a multipoint session.
/// </term>
/// </item>
/// <item>
/// <term>WSA_FLAG_MULTIPOINT_C_LEAF 0x04</term>
/// <term>
/// Create a socket that will be a c_leaf in a multipoint session. This attribute is only allowed if the WSAPROTOCOL_INFO structure
/// for the transport provider that creates the socket supports a multipoint or multicast mechanism and the control plane for a
/// multipoint session is non-rooted. This would be indicated by the dwServiceFlags1 member of the WSAPROTOCOL_INFO structure with
/// the XP1_SUPPORT_MULTIPOINT flag set and the XP1_MULTIPOINT_CONTROL_PLANE flag not set. When the lpProtocolInfo parameter is not
/// NULL, the WSAPROTOCOL_INFO structure for the transport provider is pointed to by the lpProtocolInfo parameter. When the
/// lpProtocolInfo parameter is NULL, the WSAPROTOCOL_INFO structure is based on the transport provider selected by the values
/// specified for the af, type, and protocol parameters. Refer to Multipoint and Multicast Semantics for additional information on a
/// multipoint session.
/// </term>
/// </item>
/// <item>
/// <term>WSA_FLAG_MULTIPOINT_D_ROOT 0x08</term>
/// <term>
/// Create a socket that will be a d_root in a multipoint session. This attribute is only allowed if the WSAPROTOCOL_INFO structure
/// for the transport provider that creates the socket supports a multipoint or multicast mechanism and the data plane for a
/// multipoint session is rooted. This would be indicated by the dwServiceFlags1 member of the WSAPROTOCOL_INFO structure with the
/// XP1_SUPPORT_MULTIPOINT and XP1_MULTIPOINT_DATA_PLANE flags set. When the lpProtocolInfo parameter is not NULL, the
/// WSAPROTOCOL_INFO structure for the transport provider is pointed to by the lpProtocolInfo parameter. When the lpProtocolInfo
/// parameter is NULL, the WSAPROTOCOL_INFO structure is based on the transport provider selected by the values specified for the
/// af, type, and protocol parameters. Refer to Multipoint and Multicast Semantics for additional information on a multipoint session.
/// </term>
/// </item>
/// <item>
/// <term>WSA_FLAG_MULTIPOINT_D_LEAF 0x10</term>
/// <term>
/// Create a socket that will be a d_leaf in a multipoint session. This attribute is only allowed if the WSAPROTOCOL_INFO structure
/// for the transport provider that creates the socket supports a multipoint or multicast mechanism and the data plane for a
/// multipoint session is non-rooted. This would be indicated by the dwServiceFlags1 member of the WSAPROTOCOL_INFO structure with
/// the XP1_SUPPORT_MULTIPOINT flag set and the XP1_MULTIPOINT_DATA_PLANE flag not set. When the lpProtocolInfo parameter is not
/// NULL, the WSAPROTOCOL_INFO structure for the transport provider is pointed to by the lpProtocolInfo parameter. When the
/// lpProtocolInfo parameter is NULL, the WSAPROTOCOL_INFO structure is based on the transport provider selected by the values
/// specified for the af, type, and protocol parameters. Refer to Multipoint and Multicast Semantics for additional information on a
/// multipoint session.
/// </term>
/// </item>
/// <item>
/// <term>WSA_FLAG_ACCESS_SYSTEM_SECURITY 0x40</term>
/// <term>
/// Create a socket that allows the the ability to set a security descriptor on the socket that contains a security access control
/// list (SACL) as opposed to just a discretionary access control list (DACL). SACLs are used for generating audits and alarms when
/// an access check occurs on the object. For a socket, an access check occurs to determine whether the socket should be allowed to
/// bind to a specific address specified to the bind function. The ACCESS_SYSTEM_SECURITY access right controls the ability to get
/// or set the SACL in an object's security descriptor. The system grants this access right only if the SE_SECURITY_NAME privilege
/// is enabled in the access token of the requesting thread.
/// </term>
/// </item>
/// <item>
/// <term>WSA_FLAG_NO_HANDLE_INHERIT 0x80</term>
/// <term>
/// Create a socket that is non-inheritable. A socket handle created by the WSASocket or the socket function is inheritable by
/// default. When this flag is set, the socket handle is non-inheritable. The GetHandleInformation function can be used to determine
/// if a socket handle was created with the WSA_FLAG_NO_HANDLE_INHERIT flag set. The GetHandleInformation function will return that
/// the HANDLE_FLAG_INHERIT value is set. This flag is supported on Windows 7 with SP1, Windows Server 2008 R2 with SP1, and later
/// </term>
/// </item>
/// </list>
/// <para>
/// <c>Important</c> For multipoint sockets, only one of <c>WSA_FLAG_MULTIPOINT_C_ROOT</c> or <c>WSA_FLAG_MULTIPOINT_C_LEAF</c>
/// flags can be specified, and only one of <c>WSA_FLAG_MULTIPOINT_D_ROOT</c> or <c>WSA_FLAG_MULTIPOINT_D_LEAF</c> flags can be
/// specified. Refer to Multipoint and Multicast Semantics for additional information.
/// </para>
/// </param>
/// <returns>
/// <para>
/// If no error occurs, <c>WSASocket</c> returns a descriptor referencing the new socket. Otherwise, a value of INVALID_SOCKET is
/// returned, and a specific error code can be retrieved by calling WSAGetLastError.
/// </para>
/// <para><c>Note</c> This error code description is Microsoft-specific.</para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEAFNOSUPPORT</term>
/// <term>The specified address family is not supported.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The lpProtocolInfo parameter is not in a valid part of the process address space.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>This value is true for any of the following conditions.</term>
/// </item>
/// <item>
/// <term>WSAEINVALIDPROVIDER</term>
/// <term>The service provider returned a version other than 2.2.</term>
/// </item>
/// <item>
/// <term>WSAEINVALIDPROCTABLE</term>
/// <term>The service provider returned an invalid or incomplete procedure table to the WSPStartup.</term>
/// </item>
/// <item>
/// <term>WSAEMFILE</term>
/// <term>No more socket descriptors are available.</term>
/// </item>
/// <item>
/// <term>WSAENOBUFS</term>
/// <term>No buffer space is available. The socket cannot be created.</term>
/// </item>
/// <item>
/// <term>WSAEPROTONOSUPPORT</term>
/// <term>The specified protocol is not supported.</term>
/// </item>
/// <item>
/// <term>WSAEPROTOTYPE</term>
/// <term>The specified protocol is the wrong type for this socket.</term>
/// </item>
/// <item>
/// <term>WSAEPROVIDERFAILEDINIT</term>
/// <term>
/// The service provider failed to initialize. This error is returned if a layered service provider (LSP) or namespace provider was
/// improperly installed or the provider fails to operate correctly.
/// </term>
/// </item>
/// <item>
/// <term>WSAESOCKTNOSUPPORT</term>
/// <term>The specified socket type is not supported in this address family.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSASocket</c> function causes a socket descriptor and any related resources to be allocated and associated with a
/// transport-service provider. Most sockets should be created with the <c>WSA_FLAG_OVERLAPPED</c> attribute set in the dwFlags
/// parameter. A socket created with this attribute supports the use of overlapped I/O operations which provide higher performance.
/// By default, a socket created with the <c>WSASocket</c> function will not have this overlapped attribute set. In contrast, the
/// socket function creates a socket that supports overlapped I/O operations as the default behavior.
/// </para>
/// <para>
/// If the lpProtocolInfo parameter is <c>NULL</c>, Winsock will utilize the first available transport-service provider that
/// supports the requested combination of address family, socket type and protocol specified in the af, type, and protocol parameters.
/// </para>
/// <para>
/// If the lpProtocolInfo parameter is not <c>NULL</c>, the socket will be bound to the provider associated with the indicated
/// WSAPROTOCOL_INFO structure. In this instance, the application can supply the manifest constant <c>FROM_PROTOCOL_INFO</c> as the
/// value for any of af, type, or protocol parameters. This indicates that the corresponding values from the indicated
/// <c>WSAPROTOCOL_INFO</c> structure ( <c>iAddressFamily</c>, <c>iSocketType</c>, <c>iProtocol</c>) are to be assumed. In any case,
/// the values specified for af, type, and protocol are passed unmodified to the transport-service provider.
/// </para>
/// <para>
/// When selecting a protocol and its supporting service provider based on af, type, and protocol, this procedure will only choose a
/// base protocol or a protocol chain, not a protocol layer by itself. Unchained protocol layers are not considered to have partial
/// matches on type or af, either. That is, they do not lead to an error code of WSAEAFNOSUPPORT or WSAEPROTONOSUPPORT, if no
/// suitable protocol is found.
/// </para>
/// <para>
/// <c>Note</c> The manifest constant <c>AF_UNSPEC</c> continues to be defined in the header file but its use is strongly
/// discouraged, as this can cause ambiguity in interpreting the value of the protocol parameter.
/// </para>
/// <para>
/// Applications are encouraged to use <c>AF_INET6</c> for the af parameter and create a dual-mode socket that can be used with both
/// IPv4 and IPv6.
/// </para>
/// <para>
/// If a socket is created using the <c>WSASocket</c> function, then the dwFlags parameter must have the <c>WSA_FLAG_OVERLAPPED</c>
/// attribute set for the <c>SO_RCVTIMEO</c> or <c>SO_SNDTIMEO</c> socket options to function properly. Otherwise the timeout never
/// takes effect on the socket.
/// </para>
/// <para>
/// Connection-oriented sockets such as <c>SOCK_STREAM</c> provide full-duplex connections, and must be in a connected state before
/// any data can be sent or received on them. A connection to a specified socket is established with a connect or WSAConnect
/// function call. Once connected, data can be transferred using send/WSASend and recv/WSARecv calls. When a session has been
/// completed, the closesocket function should be called to release the resources associated with the socket. For
/// connection-oriented sockets, the shutdown function should be called to stop data transfer on the socket before calling the
/// <c>closesocket</c> function.
/// </para>
/// <para>
/// The communications protocols used to implement a reliable, connection-oriented socket ensure that data is not lost or
/// duplicated. If data for which the peer protocol has buffer space cannot be successfully transmitted within a reasonable length
/// of time, the connection is considered broken and subsequent calls will fail with the error code set to WSAETIMEDOUT.
/// </para>
/// <para>
/// Connectionless, message-oriented sockets allow sending and receiving of datagrams to and from arbitrary peers using
/// sendto/WSASendTo and recvfrom/WSARecvFrom. If such a socket is connected to a specific peer, datagrams can be sent to that peer
/// using send/WSASend and can be received from (only) this peer using recv/WSARecv.
/// </para>
/// <para>
/// Support for sockets with type <c>SOCK_RAW</c> is not required, but service providers are encouraged to support raw sockets
/// whenever possible.
/// </para>
/// <para>
/// The <c>WSASocket</c> function can be used to create a socket to be used by a service so that if another socket tries to bind to
/// the same port used by the service, and audit record is generared. To enable this option, an application would need to do the following:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>
/// Call the AdjustTokenPrivileges function to enable the <c>SE_SECURITY_NAME</c> privilege in the access token for the process.
/// This privilege is required to set the <c>ACCESS_SYSTEM_SECURITY</c> access rights on the security descriptor for an object.
/// </term>
/// </item>
/// <item>
/// <term>
/// Call the <c>WSASocket</c> function to create a socket with dwFlag with the <c>WSA_FLAG_ACCESS_SYSTEM_SECURITY</c> option set.
/// The <c>WSASocket</c> function will fail if the AdjustTokenPrivileges function is not called first to enable the
/// <c>SE_SECURITY_NAME</c> privilege needed for this operation.
/// </term>
/// </item>
/// <item>
/// <term>
/// Call the SetSecurityInfo function to set a security descriptor with a System Access Control List (SACL) on the socket. The
/// socket handle returned by the <c>WSASocket</c> function is passed in the handle parameter. If the function succeeds, this will
/// set the the <c>ACCESS_SYSTEM_SECURITY</c> access right on the security descriptor for the socket.
/// </term>
/// </item>
/// <item>
/// <term>
/// Call the bindfunction to bind the socket to a specific port. If the <c>bind</c> function succeeds, then an audit entry is
/// generated if another socket tries to bind to the same port.
/// </term>
/// </item>
/// <item>
/// <term>
/// Call the AdjustTokenPrivileges function to remove the <c>SE_SECURITY_NAME</c> privilege in the access token for the process,
/// since this is no longer needed.
/// </term>
/// </item>
/// </list>
/// <para>
/// For more information on <c>ACCESS_SYSTEM_SECURITY</c>, see SACL Access Right and Audit Generation in the Authorization documentation.
/// </para>
/// <para>Socket Groups</para>
/// <para>
/// WinSock 2 introduced the notion of a socket group as a means for an application, or cooperating set of applications, to indicate
/// to an underlying service provider that a particular set of sockets are related and that the group thus formed has certain
/// attributes. Group attributes include relative priorities of the individual sockets within the group and a group quality of
/// service specification.
/// </para>
/// <para>
/// Applications that need to exchange multimedia streams over the network are an example where being able to establish a specific
/// relationship among a set of sockets could be beneficial. It is up to the transport on how to treat socket groups.
/// </para>
/// <para>
/// The <c>WSASocket</c> and WSAAccept functions can be used to explicitly create and join a socket group when creating a new
/// socket. The socket group ID for a socket can be retrieved by using the getsockopt function with level parameter set to
/// SOL_SOCKET and the optname parameter set to <c>SO_GROUP_ID</c>. 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 of zero indicates that the socket is not member of a socket group.
/// </para>
/// <para>
/// The relative group priority of a socket group can be accessed by using the getsockopt function with the level parameter set to
/// SOL_SOCKET and the optname parameter set to <c>SO_GROUP_PRIORITY</c>. The relative group priority of a socket group can be set
/// by using setsockopt with the level parameter set to SOL_SOCKET and the optname parameter set to <c>SO_GROUP_PRIORITY</c>.
/// </para>
/// <para>
/// The Winsock provider included with Windows allows the creation of socket groups and it enforces the SG_CONSTRAINED_GROUP. All
/// sockets in a constrained socket group must be 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. This is the only restriction applied to a socket group by the Winsock provider included with
/// Windows. The socket group priority is not currently used by the Winsock provider or the TCP/IP stack included with Windows.
/// </para>
/// <para>Example Code</para>
/// <para>The following example demonstrates the use of the <c>WSASocket</c> function.</para>
/// <para>
/// <c>Windows Phone 8:</c> The <c>WSASocketW</c> function is supported for Windows Phone Store apps on Windows Phone 8 and later.
/// </para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: The <c>WSASocketW</c> function is supported for Windows Store apps on
/// Windows 8.1, Windows Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasocketa SOCKET WSAAPI WSASocketA( int af, int type,
// int protocol, LPWSAPROTOCOL_INFOA lpProtocolInfo, GROUP g, DWORD dwFlags );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winsock2.h", MSDNShortId = "dcf2e543-de54-43d9-9e45-4cb935da3548")]
public static extern SOCKET WSASocket(ADDRESS_FAMILY af, SOCK type, IPPROTO protocol, [Optional] IntPtr lpProtocolInfo, GROUP g, WSA_FLAG dwFlags);
/// <summary>The <c>WSAStartup</c> function initiates use of the Winsock DLL by a process.</summary>
/// <param name="wVersionRequired">TBD</param>
/// <param name="lpWSAData">A pointer to the WSADATA data structure that is to receive details of the Windows Sockets implementation.</param>
/// <returns>
/// <para>If successful, the <c>WSAStartup</c> function returns zero. Otherwise, it returns one of the error codes listed below.</para>
/// <para>
/// The <c>WSAStartup</c> function directly returns the extended error code in the return value for this function. A call to the
/// WSAGetLastError function is not needed and should not be used.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSASYSNOTREADY</term>
/// <term>The underlying network subsystem is not ready for network communication.</term>
/// </item>
/// <item>
/// <term>WSAVERNOTSUPPORTED</term>
/// <term>The version of Windows Sockets support requested is not provided by this particular Windows Sockets implementation.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 operation is in progress.</term>
/// </item>
/// <item>
/// <term>WSAEPROCLIM</term>
/// <term>A limit on the number of tasks supported by the Windows Sockets implementation has been reached.</term>
/// </item>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The lpWSAData parameter is not a valid pointer.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAStartup</c> function must be the first Windows Sockets function called by an application or DLL. It allows an
/// application or DLL to specify the version of Windows Sockets required and retrieve details of the specific Windows Sockets
/// implementation. The application or DLL can only issue further Windows Sockets functions after successfully calling <c>WSAStartup</c>.
/// </para>
/// <para>
/// In order to support various Windows Sockets implementations and applications that can have functional differences from the
/// latest version of Windows Sockets specification, a negotiation takes place in <c>WSAStartup</c>. The caller of <c>WSAStartup</c>
/// passes in the wVersionRequested parameter the highest version of the Windows Sockets specification that the application
/// supports. The Winsock DLL indicates the highest version of the Windows Sockets specification that it can support in its
/// response. The Winsock DLL also replies with version of the Windows Sockets specification that it expects the caller to use.
/// </para>
/// <para>
/// When an application or DLL calls the <c>WSAStartup</c> function, the Winsock DLL examines the version of the Windows Sockets
/// specification requested by the application passed in the wVersionRequested parameter. If the version requested by the
/// application is equal to or higher than the lowest version supported by the Winsock DLL, the call succeeds and the Winsock DLL
/// returns detailed information in the WSADATA structure pointed to by the lpWSAData parameter. The <c>wHighVersion</c> member of
/// the <c>WSADATA</c> structure indicates the highest version of the Windows Sockets specification that the Winsock DLL supports.
/// The <c>wVersion</c> member of the <c>WSADATA</c> structure indicates the version of the Windows Sockets specification that the
/// Winsock DLL expects the caller to use.
/// </para>
/// <para>
/// If the <c>wVersion</c> member of the WSADATA structure is unacceptable to the caller, the application or DLL should call
/// WSACleanup to release the Winsock DLL resources and fail to initialize the Winsock application. In order to support this
/// application or DLL, it will be necessary to search for an updated version of the Winsock DLL to install on the platform.
/// </para>
/// <para>
/// The current version of the Windows Sockets specification is version 2.2. The current Winsock DLL, Ws2_32.dll, supports
/// applications that request any of the following versions of Windows Sockets specification:
/// </para>
/// <list type="bullet">
/// <item>
/// <term>1.0</term>
/// </item>
/// <item>
/// <term>1.1</term>
/// </item>
/// <item>
/// <term>2.0</term>
/// </item>
/// <item>
/// <term>2.1</term>
/// </item>
/// <item>
/// <term>2.2</term>
/// </item>
/// </list>
/// <para>
/// To get full access to the new syntax of a higher version of the Windows Sockets specification, the application must negotiate
/// for this higher version. In this case, the wVersionRequested parameter should be set to request version 2.2. The application
/// must also fully conform to that higher version of the Windows Socket specification, such as compiling against the appropriate
/// header file, linking with a new library, or other special cases. The Winsock2.h header file for Winsock 2 support is included
/// with the Microsoft Windows Software Development Kit (SDK).
/// </para>
/// <para>
/// Windows Sockets version 2.2 is supported on Windows Server 2008, Windows Vista, Windows Server 2003, Windows XP, Windows 2000,
/// Windows NT 4.0 with Service Pack 4 (SP4) and later, Windows Me, Windows 98, and Windows 95 OSR2. Windows Sockets version 2.2 is
/// also supported on Windows 95 with the Windows Socket 2 Update. Applications on these platforms should normally request Winsock
/// 2.2 by setting the wVersionRequested parameter accordingly.
/// </para>
/// <para>
/// On Windows 95 and versions of Windows NT 3.51 and earlier, Windows Sockets version 1.1 is the highest version of the Windows
/// Sockets specification supported.
/// </para>
/// <para>
/// It is legal and possible for an application or DLL written to use a lower version of the Windows Sockets specification that is
/// supported by the Winsock DLL to successfully negotiate this lower version using the <c>WSAStartup</c> function. For example, an
/// application can request version 1.1 in the wVersionRequested parameter passed to the <c>WSAStartup</c> function on a platform
/// with the Winsock 2.2 DLL. In this case, the application should only rely on features that fit within the version requested. New
/// Ioctl codes, new behavior of existing functions, and new functions should not be used. The version negotiation provided by the
/// <c>WSAStartup</c> was primarily used to allow older Winsock 1.1 applications developed for Windows 95 and Windows NT 3.51 and
/// earlier to run with the same behavior on later versions of Windows. The Winsock.h header file for Winsock 1.1 support is
/// included with the Windows SDK.
/// </para>
/// <para>
/// This negotiation in the <c>WSAStartup</c> function allows both the application or DLL that uses Windows Sockets and the Winsock
/// DLL to support a range of Windows Sockets versions. An application or DLL can use the Winsock DLL if there is any overlap in the
/// version ranges. Detailed information on the Windows Sockets implementation is provided in the WSADATA structure returned by the
/// <c>WSAStartup</c> function.
/// </para>
/// <para>The following table shows how <c>WSAStartup</c> works with different applications and Winsock DLL versions.</para>
/// <list type="table">
/// <listheader>
/// <term>Caller version support</term>
/// <term>Winsock DLL version support</term>
/// <term>wVersion requested</term>
/// <term>wVersion returned</term>
/// <term>wHighVersion returned</term>
/// <term>End result</term>
/// </listheader>
/// <item>
/// <term>1.1</term>
/// <term>1.1</term>
/// <term>1.1</term>
/// <term>1.1</term>
/// <term>1.1</term>
/// <term>use 1.1</term>
/// </item>
/// <item>
/// <term>1.0 1.1</term>
/// <term>1.0</term>
/// <term>1.1</term>
/// <term>1.0</term>
/// <term>1.0</term>
/// <term>use 1.0</term>
/// </item>
/// <item>
/// <term>1.0</term>
/// <term>1.0 1.1</term>
/// <term>1.0</term>
/// <term>1.0</term>
/// <term>1.1</term>
/// <term>use 1.0</term>
/// </item>
/// <item>
/// <term>1.1</term>
/// <term>1.0 1.1</term>
/// <term>1.1</term>
/// <term>1.1</term>
/// <term>1.1</term>
/// <term>use 1.1</term>
/// </item>
/// <item>
/// <term>1.1</term>
/// <term>1.0</term>
/// <term>1.1</term>
/// <term>1.0</term>
/// <term>1.0</term>
/// <term>Application fails</term>
/// </item>
/// <item>
/// <term>1.0</term>
/// <term>1.1</term>
/// <term>1.0</term>
/// <term>—</term>
/// <term>—</term>
/// <term>WSAVERNOTSUPPORTED</term>
/// </item>
/// <item>
/// <term>1.0 1.1</term>
/// <term>1.0 1.1</term>
/// <term>1.1</term>
/// <term>1.1</term>
/// <term>1.1</term>
/// <term>use 1.1</term>
/// </item>
/// <item>
/// <term>1.1 2.0</term>
/// <term>1.0 1.1</term>
/// <term>2.0</term>
/// <term>1.1</term>
/// <term>1.1</term>
/// <term>use 1.1</term>
/// </item>
/// <item>
/// <term>2.0</term>
/// <term>1.0 1.1 2.0</term>
/// <term>2.0</term>
/// <term>2.0</term>
/// <term>2.0</term>
/// <term>use 2.0</term>
/// </item>
/// <item>
/// <term>2.0 2.2</term>
/// <term>1.0 1.1 2.0</term>
/// <term>2.2</term>
/// <term>2.0</term>
/// <term>2.0</term>
/// <term>use 2.0</term>
/// </item>
/// <item>
/// <term>2.2</term>
/// <term>1.0 1.1 2.0 2.1 2.2</term>
/// <term>2.2</term>
/// <term>2.2</term>
/// <term>2.2</term>
/// <term>use 2.2</term>
/// </item>
/// </list>
/// <para>
/// Once an application or DLL has made a successful <c>WSAStartup</c> call, it can proceed to make other Windows Sockets calls as
/// needed. When it has finished using the services of the Winsock DLL, the application must call WSACleanup to allow the Winsock
/// DLL to free internal Winsock resources used by the application.
/// </para>
/// <para>
/// An application can call <c>WSAStartup</c> more than once if it needs to obtain the WSADATA structure information more than once.
/// On each such call, the application can specify any version number supported by the Winsock DLL.
/// </para>
/// <para>
/// The <c>WSAStartup</c> function typically leads to protocol-specific helper DLLs being loaded. As a result, the <c>WSAStartup</c>
/// function should not be called from the DllMain function in a application DLL. This can potentially cause deadlocks. For more
/// information, please see the DLL Main Function.
/// </para>
/// <para>
/// An application must call the WSACleanup function for every successful time the <c>WSAStartup</c> function is called. This means,
/// for example, that if an application calls <c>WSAStartup</c> three times, it must call <c>WSACleanup</c> three times. The first
/// two calls to <c>WSACleanup</c> do nothing except decrement an internal counter; the final <c>WSACleanup</c> call for the task
/// does all necessary resource deallocation for the task.
/// </para>
/// <para>
/// <c>Note</c> An application can call the WSAGetLastError function to determine the extended error code for other Windows sockets
/// functions as is normally done in Windows Sockets even if the <c>WSAStartup</c> function fails or the <c>WSAStartup</c> function
/// was not called to properly initialize Windows Sockets before calling a Windows Sockets function. The <c>WSAGetLastError</c>
/// function is one of the only functions in the Winsock 2.2 DLL that can be called in the case of a <c>WSAStartup</c> failure.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// <para>Examples</para>
/// <para>
/// The following code fragment demonstrates how an application that supports only version 2.2 of Windows Sockets makes a
/// <c>WSAStartup</c> call:
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/desktop/api/winsock/nf-winsock-wsastartup int WSAStartup( WORD wVersionRequired,
// LPWSADATA lpWSAData );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock.h", MSDNShortId = "08299592-867c-491d-9769-d16602133659")]
public static extern Win32Error WSAStartup(ushort wVersionRequired, out WSADATA lpWSAData);
/// <summary>
/// The <c>WSAStringToAddress</c> function converts a network address in its standard text presentation form into its numeric binary
/// form in a sockaddr structure, suitable for passing to Windows Sockets routines that take such a structure.
/// </summary>
/// <param name="AddressString">
/// A pointer to the zero-terminated string that contains the network address in standard text form to convert.
/// </param>
/// <param name="AddressFamily">The address family of the network address pointed to by the AddressString parameter.</param>
/// <param name="lpProtocolInfo">
/// The WSAPROTOCOL_INFO structure associated with the provider to be used. If this is <c>NULL</c>, the call is routed to the
/// provider of the first protocol supporting the indicated AddressFamily.
/// </param>
/// <param name="lpAddress">
/// A pointer to a buffer that is filled with a sockaddr structure for the address string if the function succeeds.
/// </param>
/// <param name="lpAddressLength">
/// A pointer to the length, in bytes, of the buffer pointed to by the lpAddress parameter. If the function call is successful, this
/// parameter returns a pointer to the size of the sockaddr structure returned in the lpAddress parameter. If the specified buffer
/// is not large enough, the function fails with a specific error of WSAEFAULT and this parameter is updated with the required size
/// in bytes.
/// </param>
/// <returns>
/// <para>
/// The return value for <c>WSAStringToAddress</c> is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is
/// returned, and a specific error number can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The buffer pointed to by the lpAddress parameter is too small. Pass in a larger buffer.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>The functions was unable to translate the string into a sockaddr. See the following Remarks section for more information.</term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>
/// The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Socket functions.
/// </term>
/// </item>
/// <item>
/// <term>WSA_NOT_ENOUGH_MEMORY</term>
/// <term>There was insufficient memory to perform the operation.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAStringToAddress</c> function converts a network address in standard text form into its numeric binary form in a
/// sockaddr structure.
/// </para>
/// <para>
/// Any missing components of the address will be defaulted to a reasonable value, if possible. For example, a missing port number
/// will default to zero. If the caller wants the translation to be done by a particular provider, it should supply the
/// corresponding WSAPROTOCOL_INFO structure in the lpProtocolInfo parameter.
/// </para>
/// <para>
/// The <c>WSAStringToAddress</c> function fails (and returns WSAEINVAL) if the <c>sin_family</c> member of the SOCKADDR_IN
/// structure, which is passed in the lpAddress parameter in the form of a <c>sockaddr</c> structure, is not set to AF_INET or AF_INET6.
/// </para>
/// <para>
/// Support for IPv6 addresses using the <c>WSAStringToAddress</c> function was added on Windows XP with Service Pack 1 (SP1)and
/// later. IPv6 must also be installed on the local computer for the <c>WSAStringToAddress</c> function to support IPv6 addresses.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsastringtoaddressa INT WSAAPI WSAStringToAddressA( LPSTR
// AddressString, INT AddressFamily, LPWSAPROTOCOL_INFOA lpProtocolInfo, LPSOCKADDR lpAddress, LPINT lpAddressLength );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winsock2.h", MSDNShortId = "7b9946c3-c8b3-45ae-9bde-03faaf604bba")]
public static extern WSRESULT WSAStringToAddress([MarshalAs(UnmanagedType.LPTStr)] string AddressString, ADDRESS_FAMILY AddressFamily, in WSAPROTOCOL_INFO lpProtocolInfo, [Out] SOCKADDR lpAddress, ref int lpAddressLength);
/// <summary>
/// The <c>WSAStringToAddress</c> function converts a network address in its standard text presentation form into its numeric binary
/// form in a sockaddr structure, suitable for passing to Windows Sockets routines that take such a structure.
/// </summary>
/// <param name="AddressString">
/// A pointer to the zero-terminated string that contains the network address in standard text form to convert.
/// </param>
/// <param name="AddressFamily">The address family of the network address pointed to by the AddressString parameter.</param>
/// <param name="lpProtocolInfo">
/// The WSAPROTOCOL_INFO structure associated with the provider to be used. If this is <c>NULL</c>, the call is routed to the
/// provider of the first protocol supporting the indicated AddressFamily.
/// </param>
/// <param name="lpAddress">
/// A pointer to a buffer that is filled with a sockaddr structure for the address string if the function succeeds.
/// </param>
/// <param name="lpAddressLength">
/// A pointer to the length, in bytes, of the buffer pointed to by the lpAddress parameter. If the function call is successful, this
/// parameter returns a pointer to the size of the sockaddr structure returned in the lpAddress parameter. If the specified buffer
/// is not large enough, the function fails with a specific error of WSAEFAULT and this parameter is updated with the required size
/// in bytes.
/// </param>
/// <returns>
/// <para>
/// The return value for <c>WSAStringToAddress</c> is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is
/// returned, and a specific error number can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The buffer pointed to by the lpAddress parameter is too small. Pass in a larger buffer.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>The functions was unable to translate the string into a sockaddr. See the following Remarks section for more information.</term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>
/// The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Socket functions.
/// </term>
/// </item>
/// <item>
/// <term>WSA_NOT_ENOUGH_MEMORY</term>
/// <term>There was insufficient memory to perform the operation.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAStringToAddress</c> function converts a network address in standard text form into its numeric binary form in a
/// sockaddr structure.
/// </para>
/// <para>
/// Any missing components of the address will be defaulted to a reasonable value, if possible. For example, a missing port number
/// will default to zero. If the caller wants the translation to be done by a particular provider, it should supply the
/// corresponding WSAPROTOCOL_INFO structure in the lpProtocolInfo parameter.
/// </para>
/// <para>
/// The <c>WSAStringToAddress</c> function fails (and returns WSAEINVAL) if the <c>sin_family</c> member of the SOCKADDR_IN
/// structure, which is passed in the lpAddress parameter in the form of a <c>sockaddr</c> structure, is not set to AF_INET or AF_INET6.
/// </para>
/// <para>
/// Support for IPv6 addresses using the <c>WSAStringToAddress</c> function was added on Windows XP with Service Pack 1 (SP1)and
/// later. IPv6 must also be installed on the local computer for the <c>WSAStringToAddress</c> function to support IPv6 addresses.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsastringtoaddressa INT WSAAPI WSAStringToAddressA( LPSTR
// AddressString, INT AddressFamily, LPWSAPROTOCOL_INFOA lpProtocolInfo, LPSOCKADDR lpAddress, LPINT lpAddressLength );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winsock2.h", MSDNShortId = "7b9946c3-c8b3-45ae-9bde-03faaf604bba")]
public static extern WSRESULT WSAStringToAddress([MarshalAs(UnmanagedType.LPTStr)] string AddressString, ADDRESS_FAMILY AddressFamily, [In, Optional] IntPtr lpProtocolInfo, [Out] SOCKADDR lpAddress, ref int lpAddressLength);
/// <summary>
/// The <c>WSAStringToAddress</c> function converts a network address in its standard text presentation form into its numeric binary
/// form in a sockaddr structure, suitable for passing to Windows Sockets routines that take such a structure.
/// </summary>
/// <param name="AddressString">
/// A pointer to the zero-terminated string that contains the network address in standard text form to convert.
/// </param>
/// <param name="AddressFamily">The address family of the network address pointed to by the AddressString parameter.</param>
/// <param name="lpProtocolInfo">
/// The WSAPROTOCOL_INFO structure associated with the provider to be used. If this is <c>NULL</c>, the call is routed to the
/// provider of the first protocol supporting the indicated AddressFamily.
/// </param>
/// <param name="lpAddress">
/// A pointer to a buffer that is filled with a sockaddr structure for the address string if the function succeeds.
/// </param>
/// <param name="lpAddressLength">
/// A pointer to the length, in bytes, of the buffer pointed to by the lpAddress parameter. If the function call is successful, this
/// parameter returns a pointer to the size of the sockaddr structure returned in the lpAddress parameter. If the specified buffer
/// is not large enough, the function fails with a specific error of WSAEFAULT and this parameter is updated with the required size
/// in bytes.
/// </param>
/// <returns>
/// <para>
/// The return value for <c>WSAStringToAddress</c> is zero if the operation was successful. Otherwise, the value SOCKET_ERROR is
/// returned, and a specific error number can be retrieved by calling WSAGetLastError.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSAEFAULT</term>
/// <term>The buffer pointed to by the lpAddress parameter is too small. Pass in a larger buffer.</term>
/// </item>
/// <item>
/// <term>WSAEINVAL</term>
/// <term>The functions was unable to translate the string into a sockaddr. See the following Remarks section for more information.</term>
/// </item>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>
/// The WS2_32.DLL has not been initialized. The application must first call WSAStartup before calling any Windows Socket functions.
/// </term>
/// </item>
/// <item>
/// <term>WSA_NOT_ENOUGH_MEMORY</term>
/// <term>There was insufficient memory to perform the operation.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAStringToAddress</c> function converts a network address in standard text form into its numeric binary form in a
/// sockaddr structure.
/// </para>
/// <para>
/// Any missing components of the address will be defaulted to a reasonable value, if possible. For example, a missing port number
/// will default to zero. If the caller wants the translation to be done by a particular provider, it should supply the
/// corresponding WSAPROTOCOL_INFO structure in the lpProtocolInfo parameter.
/// </para>
/// <para>
/// The <c>WSAStringToAddress</c> function fails (and returns WSAEINVAL) if the <c>sin_family</c> member of the SOCKADDR_IN
/// structure, which is passed in the lpAddress parameter in the form of a <c>sockaddr</c> structure, is not set to AF_INET or AF_INET6.
/// </para>
/// <para>
/// Support for IPv6 addresses using the <c>WSAStringToAddress</c> function was added on Windows XP with Service Pack 1 (SP1)and
/// later. IPv6 must also be installed on the local computer for the <c>WSAStringToAddress</c> function to support IPv6 addresses.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsastringtoaddressa INT WSAAPI WSAStringToAddressA( LPSTR
// AddressString, INT AddressFamily, LPWSAPROTOCOL_INFOA lpProtocolInfo, LPSOCKADDR lpAddress, LPINT lpAddressLength );
[DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)]
[PInvokeData("winsock2.h", MSDNShortId = "7b9946c3-c8b3-45ae-9bde-03faaf604bba")]
public static extern WSRESULT WSAStringToAddress([MarshalAs(UnmanagedType.LPTStr)] string AddressString, ADDRESS_FAMILY AddressFamily, [In, Optional] IntPtr lpProtocolInfo, [Out] IntPtr lpAddress, ref int lpAddressLength);
/// <summary>
/// The <c>WSAStringToAddress</c> function converts a network address in its standard text presentation form into its numeric binary
/// form in a sockaddr structure, suitable for passing to Windows Sockets routines that take such a structure.
/// </summary>
/// <param name="AddressString">
/// A pointer to the zero-terminated string that contains the network address in standard text form to convert.
/// </param>
/// <param name="AddressFamily">The address family of the network address pointed to by the AddressString parameter.</param>
/// <param name="lpProtocolInfo">
/// The WSAPROTOCOL_INFO structure associated with the provider to be used. If this is <c>NULL</c>, the call is routed to the
/// provider of the first protocol supporting the indicated AddressFamily.
/// </param>
/// <returns>A sockaddr structure for the address string if the function succeeds.</returns>
/// <remarks>
/// <para>
/// The <c>WSAStringToAddress</c> function converts a network address in standard text form into its numeric binary form in a
/// sockaddr structure.
/// </para>
/// <para>
/// Any missing components of the address will be defaulted to a reasonable value, if possible. For example, a missing port number
/// will default to zero. If the caller wants the translation to be done by a particular provider, it should supply the corresponding
/// WSAPROTOCOL_INFO structure in the lpProtocolInfo parameter.
/// </para>
/// <para>
/// The <c>WSAStringToAddress</c> function fails (and returns WSAEINVAL) if the <c>sin_family</c> member of the SOCKADDR_IN
/// structure, which is passed in the lpAddress parameter in the form of a <c>sockaddr</c> structure, is not set to AF_INET or AF_INET6.
/// </para>
/// <para>
/// Support for IPv6 addresses using the <c>WSAStringToAddress</c> function was added on Windows XP with Service Pack 1 (SP1)and
/// later. IPv6 must also be installed on the local computer for the <c>WSAStringToAddress</c> function to support IPv6 addresses.
/// </para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsastringtoaddressa INT WSAAPI WSAStringToAddressA( LPSTR
// AddressString, INT AddressFamily, LPWSAPROTOCOL_INFOA lpProtocolInfo, LPSOCKADDR lpAddress, LPINT lpAddressLength );
[PInvokeData("winsock2.h", MSDNShortId = "7b9946c3-c8b3-45ae-9bde-03faaf604bba")]
public static SOCKADDR_INET WSAStringToAddress(string AddressString, ADDRESS_FAMILY AddressFamily, [In, Optional] WSAPROTOCOL_INFO? lpProtocolInfo)
{
using var pc = lpProtocolInfo.HasValue ? new SafeCoTaskMemStruct<WSAPROTOCOL_INFO>(lpProtocolInfo.Value) : SafeCoTaskMemStruct<WSAPROTOCOL_INFO>.Null;
using var addr = new SafeCoTaskMemStruct<SOCKADDR_INET>();
int sz = addr.Size;
WSAStringToAddress(AddressString, AddressFamily, pc, addr, ref sz).ThrowIfFailed();
return addr.Value;
}
/// <summary>
/// The <c>WSAWaitForMultipleEvents</c> function returns when one or all of the specified event objects are in the signaled state,
/// when the time-out interval expires, or when an I/O completion routine has executed.
/// </summary>
/// <param name="cEvents">
/// The number of event object handles in the array pointed to by lphEvents. The maximum number of event object handles is
/// <c>WSA_MAXIMUM_WAIT_EVENTS</c>. One or more events must be specified.
/// </param>
/// <param name="lphEvents">
/// <para>
/// A pointer to an array of event object handles. The array can contain handles of objects of different types. It may not contain
/// multiple copies of the same handle if the fWaitAll parameter is set to <c>TRUE</c>. If one of these handles is closed while the
/// wait is still pending, the behavior of <c>WSAWaitForMultipleEvents</c> is undefined.
/// </para>
/// <para>The handles must have the <c>SYNCHRONIZE</c> access right. For more information, see Standard Access Rights.</para>
/// </param>
/// <param name="fWaitAll">
/// A value that specifies the wait type. If <c>TRUE</c>, the function returns when the state of all objects in the lphEvents array
/// is signaled. If <c>FALSE</c>, the function returns when any of the event objects is signaled. In the latter case, the return
/// value minus <c>WSA_WAIT_EVENT_0</c> indicates the index of the event object whose state caused the function to return. If more
/// than one event object became signaled during the call, this is the array index to the signaled event object with the smallest
/// index value of all the signaled event objects.
/// </param>
/// <param name="dwTimeout">
/// The time-out interval, in milliseconds. <c>WSAWaitForMultipleEvents</c> returns if the time-out interval expires, even if
/// conditions specified by the fWaitAll parameter are not satisfied. If the dwTimeout parameter is zero,
/// <c>WSAWaitForMultipleEvents</c> tests the state of the specified event objects and returns immediately. If dwTimeout is
/// <c>WSA_INFINITE</c>, <c>WSAWaitForMultipleEvents</c> waits forever; that is, the time-out interval never expires.
/// </param>
/// <param name="fAlertable">
/// A value that specifies whether the thread is placed in an alertable wait state so the system can execute I/O completion
/// routines. If <c>TRUE</c>, the thread is placed in an alertable wait state and <c>WSAWaitForMultipleEvents</c> can return when
/// the system executes an I/O completion routine. In this case, <c>WSA_WAIT_IO_COMPLETION</c> is returned and the event that was
/// being waited on is not signaled yet. The application must call the <c>WSAWaitForMultipleEvents</c> function again. If
/// <c>FALSE</c>, the thread is not placed in an alertable wait state and I/O completion routines are not executed.
/// </param>
/// <returns>
/// <para>If the <c>WSAWaitForMultipleEvents</c> function succeeds, the return value upon success is one of the following values.</para>
/// <list type="table">
/// <listheader>
/// <term>Return Value</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSA_WAIT_EVENT_0 to (WSA_WAIT_EVENT_0 + cEvents - 1)</term>
/// <term>
/// If the fWaitAll parameter is TRUE, the return value indicates that all specified event objects is signaled. If the fWaitAll
/// parameter is FALSE, the return value minus WSA_WAIT_EVENT_0 indicates the lphEvents array index of the signaled event object
/// that satisfied the wait. If more than one event object became signaled during the call, the return value indicates the lphEvents
/// array index of the signaled event object with the smallest index value of all the signaled event objects.
/// </term>
/// </item>
/// <item>
/// <term>WSA_WAIT_IO_COMPLETION</term>
/// <term>
/// The wait was ended by one or more I/O completion routines that were executed. The event that was being waited on is not signaled
/// yet. The application must call the WSAWaitForMultipleEvents function again. This return value can only be returned if the
/// fAlertable parameter is TRUE.
/// </term>
/// </item>
/// <item>
/// <term>WSA_WAIT_TIMEOUT</term>
/// <term>
/// The time-out interval elapsed and the conditions specified by the fWaitAll parameter were not satisfied. No I/O completion
/// routines were executed.
/// </term>
/// </item>
/// </list>
/// <para>
/// If the <c>WSAWaitForMultipleEvents</c> function fails, the return value is <c>WSA_WAIT_FAILED</c>. The following table lists
/// values that can be used with WSAGetLastError to get extended error information.
/// </para>
/// <list type="table">
/// <listheader>
/// <term>Error code</term>
/// <term>Meaning</term>
/// </listheader>
/// <item>
/// <term>WSANOTINITIALISED</term>
/// <term>A successful WSAStartup call must occur before using this function.</term>
/// </item>
/// <item>
/// <term>WSAENETDOWN</term>
/// <term>The network subsystem has failed.</term>
/// </item>
/// <item>
/// <term>WSAEINPROGRESS</term>
/// <term>A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.</term>
/// </item>
/// <item>
/// <term>WSA_NOT_ENOUGH_MEMORY</term>
/// <term>Not enough free memory was available to complete the operation.</term>
/// </item>
/// <item>
/// <term>WSA_INVALID_HANDLE</term>
/// <term>One or more of the values in the lphEvents array is not a valid event object handle.</term>
/// </item>
/// <item>
/// <term>WSA_INVALID_PARAMETER</term>
/// <term>The cEvents parameter does not contain a valid handle count.</term>
/// </item>
/// </list>
/// </returns>
/// <remarks>
/// <para>
/// The <c>WSAWaitForMultipleEvents</c> function determines whether the wait criteria have been met. If the criteria have not been
/// met, the calling thread enters the wait state. It uses no processor time while waiting for the criteria to be met.
/// </para>
/// <para>
/// The <c>WSAWaitForMultipleEvents</c> function returns when any one or all of the specified objects are in the signaled state, or
/// when the time-out interval elapses.
/// </para>
/// <para>
/// When the bWaitAll parameter is <c>TRUE</c>, the wait operation is completed only when the states of all objects have been set to
/// signaled. The function does not modify the states of the specified objects until the states of all objects have been set to signaled.
/// </para>
/// <para>
/// When bWaitAll parameter is <c>FALSE</c>, <c>WSAWaitForMultipleEvents</c> checks the handles in the lphEvents array in order
/// starting with index 0, until one of the objects is signaled. If multiple objects become signaled, the function returns the index
/// of the first handle in the lphEvents array whose object was signaled.
/// </para>
/// <para>
/// This function is also used to perform an alertable wait by setting the fAlertable parameter to <c>TRUE</c>. This enables the
/// function to return when the system executes an I/O completion routine by the calling thread.
/// </para>
/// <para>
/// A thread must be in an alertable wait state in order for the system to execute I/O completion routines (asynchronous procedure
/// calls or APCs). So if an application calls <c>WSAWaitForMultipleEvents</c> when there are pending asynchronous operations that
/// have I/O completion routines and the fAlertable parameter is <c>FALSE</c>, then those I/O completion routines will not be
/// executed even if those I/O operations are completed.
/// </para>
/// <para>
/// If the fAlertable parameter is <c>TRUE</c> and one of the pending operations completes, the APC is executed and
/// <c>WSAWaitForMultipleEvents</c> will return <c>WSA_IO_COMPLETION</c>. The pending event is not signaled yet. The application
/// must call the <c>WSAWaitForMultipleEvents</c> function again.
/// </para>
/// <para>
/// Applications that require an alertable wait state without waiting for any event objects to be signaled should use the Windows
/// SleepEx function.
/// </para>
/// <para>The current implementation of <c>WSAWaitForMultipleEvents</c> calls the WaitForMultipleObjectsEx function.</para>
/// <para>
/// <c>Note</c> Use caution when calling the <c>WSAWaitForMultipleEvents</c> with code that directly or indirectly creates windows.
/// If a thread creates any windows, it must process messages. Message broadcasts are sent to all windows in the system. A thread
/// that uses <c>WSAWaitForMultipleEvents</c> with no time-out limit (the dwTimeout parameter set to <c>WSA_INFINITE</c>) may cause
/// the system to become deadlocked.
/// </para>
/// <para>Example Code</para>
/// <para>The following code example shows how to use the <c>WSAWaitForMultipleEvents</c> function.</para>
/// <para><c>Windows Phone 8:</c> This function is supported for Windows Phone Store apps on Windows Phone 8 and later.</para>
/// <para>
/// <c>Windows 8.1</c> and <c>Windows Server 2012 R2</c>: This function is supported for Windows Store apps on Windows 8.1, Windows
/// Server 2012 R2, and later.
/// </para>
/// </remarks>
// https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsawaitformultipleevents DWORD WSAAPI
// WSAWaitForMultipleEvents( DWORD cEvents, const WSAEVENT *lphEvents, BOOL fWaitAll, DWORD dwTimeout, BOOL fAlertable );
[DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)]
[PInvokeData("winsock2.h", MSDNShortId = "7a978ade-6323-455b-b655-f372f4bcadc8")]
public static extern Kernel32.WAIT_STATUS WSAWaitForMultipleEvents(uint cEvents, [In, MarshalAs(UnmanagedType.LPArray)] WSAEVENT[] lphEvents, [MarshalAs(UnmanagedType.Bool)] bool fWaitAll, uint dwTimeout, [MarshalAs(UnmanagedType.Bool)] bool fAlertable);
}
}