From 78cabaa31f7ef6cccd0f9e70eed26407f1cd4fe8 Mon Sep 17 00:00:00 2001 From: dahall Date: Sun, 10 Jul 2022 17:30:38 -0600 Subject: [PATCH] Separated WSA code into multiple files, changed return codes to SocketError (from .NET core libs) and added error handling functions. --- PInvoke/Ws2_32/WinSock2.WSA.Enum.cs | 391 ++++++++++++ PInvoke/Ws2_32/WinSock2.WSA.Error.cs | 33 + PInvoke/Ws2_32/WinSock2.WSA.Struct.cs | 487 +++++++++++++++ PInvoke/Ws2_32/WinSock2.WSA.cs | 1062 ++++----------------------------- 4 files changed, 1017 insertions(+), 956 deletions(-) create mode 100644 PInvoke/Ws2_32/WinSock2.WSA.Enum.cs create mode 100644 PInvoke/Ws2_32/WinSock2.WSA.Error.cs create mode 100644 PInvoke/Ws2_32/WinSock2.WSA.Struct.cs diff --git a/PInvoke/Ws2_32/WinSock2.WSA.Enum.cs b/PInvoke/Ws2_32/WinSock2.WSA.Enum.cs new file mode 100644 index 00000000..d29dfcd3 --- /dev/null +++ b/PInvoke/Ws2_32/WinSock2.WSA.Enum.cs @@ -0,0 +1,391 @@ +#pragma warning disable IDE1006 // Naming Styles + +using System; +using System.Data; +using System.Runtime.InteropServices; +using System.Text; +using Vanara.Extensions; +using Vanara.InteropServices; + +namespace Vanara.PInvoke +{ + /// Functions, structures and constants from ws2_32.h. + public static partial class Ws2_32 + { + /// The CompletionRoutine is a placeholder for an application-defined or library-defined function name. + /// Specifies the completion status for the overlapped operation as indicated by lpOverlapped. + /// Specifies the number of bytes received. + /// The overlapped operation. + /// Contains information that would have appeared in lpFlags if the receive operation had completed immediately. + // void (CALLBACK* LPWSAOVERLAPPED_COMPLETION_ROUTINE) ( IN DWORD dwError, IN DWORD cbTransferred, IN LPWSAOVERLAPPED lpOverlapped, + // IN DWORD dwFlags ); + [PInvokeData("winsock2.h", MSDNShortId = "abaf367a-8f99-478c-a58c-d57e9f9cd8a1")] + public delegate void LPWSAOVERLAPPED_COMPLETION_ROUTINE([In] uint dwError, [In] uint cbTransferred, [In] in WSAOVERLAPPED lpOverlapped, [In] uint dwFlags); + + /// Network events. + [PInvokeData("winsock2.h", MSDNShortId = "f98a71e4-47fb-47a4-b37e-e4cc801a8f98")] + public enum FD + { + /// Wants to receive notification of readiness for reading. + FD_READ = (1 << 0), + + /// Wants to receive notification of readiness for writing. + FD_WRITE = (1 << 1), + + /// Wants to receive notification of the arrival of OOB data. + FD_OOB = (1 << 2), + + /// Wants to receive notification of incoming connections. + FD_ACCEPT = (1 << 3), + + /// Wants to receive notification of completed connection or multipoint join operation. + FD_CONNECT = (1 << 4), + + /// Wants to receive notification of socket closure. + FD_CLOSE = (1 << 5), + + /// Wants to receive notification of socket (QoS changes. + FD_QOS = (1 << 6), + + /// Reserved for future use with socket groups. Want to receive notification of socket group QoS changes. + FD_GROUP_QOS = (1 << 7), + + /// Wants to receive notification of routing interface changes for the specified destination. + FD_ROUTING_INTERFACE_CHANGE = (1 << 8), + + /// Wants to receive notification of local address list changes for the address family of the socket. + FD_ADDRESS_LIST_CHANGE = (1 << 9), + + /// All events. + FD_ALL_EVENTS = ((1 << 10) - 1) + } + + /// Flags to indicate that the socket is acting as a sender (JL_SENDER_ONLY), receiver (JL_RECEIVER_ONLY), or both (JL_BOTH). + [PInvokeData("winsock2.h", MSDNShortId = "ef9efa03-feed-4f0d-b874-c646cce745c9")] + [Flags] + public enum JL + { + /// Acting as a sender. + JL_SENDER_ONLY = 0x01, + + /// Acting as a receiver. + JL_RECEIVER_ONLY = 0x02, + + /// Acting as both sender and receiver. + JL_BOTH = 0x04, + } + + /// Flags that control the depth of the search. + [PInvokeData("winsock2.h", MSDNShortId = "448309ef-b9dd-4960-8016-d26691df59ec")] + [Flags] + public enum LUP : uint + { + /// Queries deep as opposed to just the first level. + LUP_DEEP = 0x0001, + + /// Returns containers only. + LUP_CONTAINERS = 0x0002, + + /// Do not return containers. + LUP_NOCONTAINERS = 0x0004, + + /// If possible, returns results in the order of distance. The measure of distance is provider specific. + LUP_NEAREST = 0x0008, + + /// Retrieves the name as lpszServiceInstanceName. + LUP_RETURN_NAME = 0x0010, + + /// Retrieves the type as lpServiceClassId. + LUP_RETURN_TYPE = 0x0020, + + /// Retrieves the version as lpVersion. + LUP_RETURN_VERSION = 0x0040, + + /// Retrieves the comment as lpszComment. + LUP_RETURN_COMMENT = 0x0080, + + /// Retrieves the addresses as lpcsaBuffer. + LUP_RETURN_ADDR = 0x0100, + + /// Retrieves the private data as lpBlob. + LUP_RETURN_BLOB = 0x0200, + + /// + /// 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. + /// + LUP_RETURN_ALIASES = 0x0400, + + /// Retrieves the query string used for the request. + LUP_RETURN_QUERY_STRING = 0x0800, + + /// A set of flags that retrieves all of the LUP_RETURN_* values. + LUP_RETURN_ALL = 0x0FF0, + + /// If the provider has cached information, ignore the cache and query the namespace itself. + LUP_FLUSHCACHE = 0x1000, + + /// + /// Used as a value for the dwControlFlags parameter in NSPLookupServiceNext. Setting this flag instructs the provider to + /// discard the last result set, which was too large for the supplied buffer, and move on to the next result set. + /// + LUP_FLUSHPREVIOUS = 0x2000, + + /// Indicates that the namespace provider should included non-authoritative results for names. + LUP_NON_AUTHORITATIVE = 0x4000, + + /// + /// Indicates whether prime response is in the remote or local part of CSADDR_INFO structure. The other part must be usable in + /// either case. This option applies only to service instance requests. + /// + LUP_RES_SERVICE = 0x8000, + + /// Indicates that the namespace provider should use a secure query. This option only applies to name query requests. + LUP_SECURE = 0x8000, + + /// Indicates that the namespace provider should return only preferred names. + LUP_RETURN_PREFERRED_NAMES = 0x10000, + + /// Indicates that the namespace provider should return the address configuration. + LUP_ADDRCONFIG = 0x100000, + + /// + /// Indicates that the namespace provider should return the dual addresses. This option only applies to dual-mode sockets (IPv6 + /// and IPv4 mapped addresses). + /// + LUP_DUAL_ADDR = 0x200000, + + /// + LUP_DNS_ONLY = 0x20000, + + /// + LUP_FILESERVER = 0x00400000, + + /// + /// Indicates that the namespace provider should disable automatic International Domain Names encoding. This value is supported + /// on Windows 8 and Windows Server 2012 + /// + LUP_DISABLE_IDN_ENCODING = 0x00800000, + + /// + LUP_API_ANSI = 0x01000000, + + /// + LUP_RESOLUTION_HANDLE = 0x80000000, + } + + /// + /// 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. + /// + [PInvokeData("winsock2.h", MSDNShortId = "bfe66e11-e9a7-4321-ad55-3141113e9a03")] + [Flags] + public enum MsgFlags + { + /// Processes OOB data. + MSG_OOB = 0x1, + + /// + /// 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. + /// + MSG_PEEK = 0x2, + + /// + MSG_DONTROUTE = 0x4, + + /// + /// 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. + /// + MSG_WAITALL = 0x8, + + /// + /// 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. + /// + MSG_PUSH_IMMEDIATE = 0x20, + + /// + /// 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. + /// + MSG_PARTIAL = 0x8000, + + /// + MSG_INTERRUPT = 0x10, + + /// The datagram was truncated. More data was present than the process allocated room for. + MSG_TRUNC = 0x0100, + + /// The control (ancillary) data was truncated. More control data was present than the process allocated room for. + MSG_CTRUNC = 0x0200, + + /// The datagram was received as a link-layer broadcast or with a destination IP address that is a broadcast address. + MSG_BCAST = 0x0400, + + /// The datagram was received with a destination IP address that is a multicast address. + MSG_MCAST = 0x0800, + + /// + /// This flag specifies that queued errors should be received from the socket error queue. The error is passed in an ancillary + /// message with a type dependent on the protocol (for IPv4 IP_RECVERR). The user should supply a buffer of sufficient size.See + /// cmsg(3) and ip(7) for more information.The payload of the original packet that caused the error is passed as normal data via + /// msg_iovec. The original destination address of the datagram that caused the error is supplied via msg_name. + /// + MSG_ERRQUEUE = 0x1000, + } + + /// + /// A set of flags that indicate the type of status being requested or, upon return from the WSAPoll function call, the results of + /// the status query. + /// + [PInvokeData("winsock2.h", MSDNShortId = "88f122ce-e2ca-44ce-bd53-d73d0962e7ef")] + [Flags] + public enum PollFlags : short + { + /// Normal data may be read without blocking. + POLLRDNORM = 0x0100, + + /// Priority band (out-of-band) data may be read without blocking. + POLLRDBAND = 0x0200, + + /// POLLRDNORM | POLLRDBAND + POLLIN = (POLLRDNORM | POLLRDBAND), + + /// Priority data may be read without blocking. This flag is not returned by the Microsoft Winsock provider. + POLLPRI = 0x0400, + + /// Normal data may be written without blocking. + POLLWRNORM = 0x0010, + + /// Normal data may be written without blocking. + POLLOUT = (POLLWRNORM), + + /// + POLLWRBAND = 0x0020, + + /// An error has occurred. + POLLERR = 0x0001, + + /// A stream-oriented connection was either disconnected or aborted. + POLLHUP = 0x0002, + + /// An invalid socket was used. + POLLNVAL = 0x0004, + } + + /// Service install flags value that further controls the operation performed of the WSASetServicefunction. + [PInvokeData("winsock2.h", MSDNShortId = "21a8ff26-4c9e-4846-a75a-1a27c746edab")] + [Flags] + public enum ServiceInstallFlags + { + /// + /// 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. + /// + SERVICE_MULTIPLE = 0x00000001, + } + + /// A set of flags used to specify additional socket attributes. + [PInvokeData("winsock2.h", MSDNShortId = "dcf2e543-de54-43d9-9e45-4cb935da3548")] + [Flags] + public enum WSA_FLAG + { + /// + /// 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. + /// + WSA_FLAG_OVERLAPPED = 0x01, + + /// + /// 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. + /// + WSA_FLAG_MULTIPOINT_C_ROOT = 0x02, + + /// + /// 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. + /// + WSA_FLAG_MULTIPOINT_C_LEAF = 0x04, + + /// + /// 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. + /// + WSA_FLAG_MULTIPOINT_D_ROOT = 0x08, + + /// + /// 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. + /// + WSA_FLAG_MULTIPOINT_D_LEAF = 0x10, + + /// + /// 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. + /// + WSA_FLAG_ACCESS_SYSTEM_SECURITY = 0x40, + + /// + /// 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 + /// + WSA_FLAG_NO_HANDLE_INHERIT = 0x80, + + /// + WSA_FLAG_REGISTERED_IO = 0x100, + } + } +} \ No newline at end of file diff --git a/PInvoke/Ws2_32/WinSock2.WSA.Error.cs b/PInvoke/Ws2_32/WinSock2.WSA.Error.cs new file mode 100644 index 00000000..813ace3e --- /dev/null +++ b/PInvoke/Ws2_32/WinSock2.WSA.Error.cs @@ -0,0 +1,33 @@ +using System; +using System.Net.Sockets; +using System.Security; + +namespace Vanara.PInvoke +{ + public static partial class Ws2_32 + { + /// + /// Throws an appropriate exception if is a failure. If the value of equals (-1 or SOCKET_ERROR), then is called to retrive the actual error. + /// + /// The value to process. + public static void ThrowIfFailed(this SocketError err) { var ex = err.GetException(); if (ex is not null) throw ex; } + + /// Throws the last error if the function returns . + /// The value to check. + public static void ThrowLastErrorIfFalse(bool value) { if (!value) throw WSAGetLastError().GetException(); } + + /// + /// Gets the .NET associated with the value and optionally adds the supplied message. + /// + /// The value to process. + /// The associated or if this is not a failure. + [SecurityCritical, SecuritySafeCritical] + public static Exception GetException(this SocketError err) => err switch + { + 0 => null, + SocketError.SocketError => new SocketException((int)WSAGetLastError()), + _ => new SocketException((int)err) + }; + } +} \ No newline at end of file diff --git a/PInvoke/Ws2_32/WinSock2.WSA.Struct.cs b/PInvoke/Ws2_32/WinSock2.WSA.Struct.cs new file mode 100644 index 00000000..4051d953 --- /dev/null +++ b/PInvoke/Ws2_32/WinSock2.WSA.Struct.cs @@ -0,0 +1,487 @@ +#pragma warning disable IDE1006 // Naming Styles + +using System; +using System.Data; +using System.Runtime.InteropServices; +using Vanara.InteropServices; + +namespace Vanara.PInvoke +{ + /// Functions, structures and constants from ws2_32.h. + public static partial class Ws2_32 + { + /// + /// The fd_set structure is used by various Windows Sockets functions and service providers, such as the select function, to + /// place sockets into a "set" for various purposes, such as testing a given socket for readability using the readfds parameter of + /// the select function. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winsock/ns-winsock-fd_set typedef struct fd_set { u_int fd_count; SOCKET + // fd_array[FD_SETSIZE]; } fd_set, FD_SET, *PFD_SET, *LPFD_SET; + [PInvokeData("winsock.h", MSDNShortId = "2af5d69d-190e-4814-8d8b-438431808625")] + [StructLayout(LayoutKind.Sequential)] + public struct fd_set + { + /// The number of sockets in the set. + public uint fd_count; + + /// An array of sockets that are in the set. + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] + public SOCKET[] fd_array; + } + + /// The WSANETWORKEVENTS structure is used to store a socket's internal information about network events. + // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/ns-winsock2-wsanetworkevents typedef struct _WSANETWORKEVENTS { long + // lNetworkEvents; int iErrorCode[FD_MAX_EVENTS]; } WSANETWORKEVENTS, *LPWSANETWORKEVENTS; + [PInvokeData("winsock2.h", MSDNShortId = "72ae4aa8-4e15-4215-8dcb-45e394ac1313")] + [StructLayout(LayoutKind.Sequential)] + public struct WSANETWORKEVENTS + { + /// Indicates which of the FD_XXX network events have occurred. + public int lNetworkEvents; + + /// + /// Array that contains any associated error codes, with an array index that corresponds to the position of event bits in + /// lNetworkEvents. The identifiers FD_READ_BIT, FD_WRITE_BIT and others can be used to index the iErrorCode array. + /// + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] + public int[] iErrorCode; + } + + /// The WSANSCLASSINFO structure provides individual parameter information for a specific Windows Sockets namespace. + /// + /// The WSANSCLASSINFO structure is defined differently depending on whether ANSI or UNICODE is used. The above syntax block + /// applies to ANSI; for UNICODE, the datatype for lpszName is LPWSTR. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/ns-winsock2-wsansclassinfoa typedef struct _WSANSClassInfoA { LPSTR + // lpszName; DWORD dwNameSpace; DWORD dwValueType; DWORD dwValueSize; LPVOID lpValue; } WSANSCLASSINFOA, *PWSANSCLASSINFOA, *LPWSANSCLASSINFOA; + [PInvokeData("winsock2.h", MSDNShortId = "b4f811ad-7967-45bd-b563-a28bb1633596")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct WSANSCLASSINFO + { + /// String value associated with the parameter, such as SAPID, TCPPORT, and so forth. + [MarshalAs(UnmanagedType.LPStr)] + public string lpszName; + + /// GUID associated with the namespace. + public uint dwNameSpace; + + /// Value type for the parameter, such as REG_DWORD or REG_SZ, and so forth. + public uint dwValueType; + + /// Size of the parameter provided in lpValue, in bytes. + public uint dwValueSize; + + /// Pointer to the value of the parameter. + public IntPtr lpValue; + } + + /// The WSAPOLLFD structure stores socket information used by the WSAPoll function. + /// + /// The WSAPOLLFD structure is defined on Windows Vista and later. + /// + /// The WSAPOLLFD structure is used by the WSAPoll function to determine the status of one or more sockets. The set of + /// sockets for which status is requested is specified in fdarray parameter, which is an array of WSAPOLLFD structures. An + /// application sets the appropriate flags in the events member of the WSAPOLLFD structure to specify the type of + /// status requested for each corresponding socket. The WSAPoll function returns the status of a socket in the revents + /// member of the WSAPOLLFD structure. + /// + /// + /// If the fd member of the WSAPOLLFD structure is set to a negative value, the structure is ignored by the WSAPoll + /// function call, and the revents member is cleared upon return. This is useful to applications that maintain a fixed + /// allocation for the fdarray parameter of WSAPoll; such applications need not waste resources compacting elements of the + /// array for unused entries or reallocating memory. It is unnecessary to clear the revents member prior to calling the + /// WSAPoll function. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/ns-winsock2-wsapollfd typedef struct pollfd { SOCKET fd; SHORT + // events; SHORT revents; } WSAPOLLFD, *PWSAPOLLFD, *LPWSAPOLLFD; + [PInvokeData("winsock2.h", MSDNShortId = "88f122ce-e2ca-44ce-bd53-d73d0962e7ef")] + [StructLayout(LayoutKind.Sequential)] + public struct WSAPOLLFD + { + /// + /// Type: SOCKET + /// The identifier of the socket for which to find status. This parameter is ignored if set to a negative value. See Remarks. + /// + public SOCKET fd; + + /// + /// Type: short + /// A set of flags indicating the type of status being requested. This must be one or more of the following. + /// + /// + /// Flag + /// Meaning + /// + /// + /// POLLPRI + /// Priority data may be read without blocking. This flag is not supported by the Microsoft Winsock provider. + /// + /// + /// POLLRDBAND + /// Priority band (out-of-band) data can be read without blocking. + /// + /// + /// POLLRDNORM + /// Normal data can be read without blocking. + /// + /// + /// POLLWRNORM + /// Normal data can be written without blocking. + /// + /// + /// + /// The POLLIN flag is defined as the combination of the POLLRDNORM and POLLRDBAND flag values. The POLLOUT flag + /// is defined as the same as the POLLWRNORM flag value. + /// + /// + public PollFlags events; + + /// + /// Type: short + /// + /// A set of flags that indicate, upon return from the WSAPoll function call, the results of the status query. This can a + /// combination of the following flags. + /// + /// + /// + /// Flag + /// Description + /// + /// + /// POLLERR + /// An error has occurred. + /// + /// + /// POLLHUP + /// A stream-oriented connection was either disconnected or aborted. + /// + /// + /// POLLNVAL + /// An invalid socket was used. + /// + /// + /// POLLPRI + /// Priority data may be read without blocking. This flag is not returned by the Microsoft Winsock provider. + /// + /// + /// POLLRDBAND + /// Priority band (out-of-band) data may be read without blocking. + /// + /// + /// POLLRDNORM + /// Normal data may be read without blocking. + /// + /// + /// POLLWRNORM + /// Normal data may be written without blocking. + /// + /// + /// + /// The POLLIN flag is defined as the combination of the POLLRDNORM and POLLRDBAND flag values. The POLLOUT flag + /// is defined as the same as the POLLWRNORM flag value. + /// + /// + /// For sockets that do not satisfy the status query, and have no error, the revents member is set to zero upon return. + /// + /// + public PollFlags revents; + } + + /// + /// The WSAQUERYSET structure provides relevant information about a given service, including service class ID, service name, + /// applicable namespace identifier and protocol information, as well as a set of transport addresses at which the service listens. + /// + /// + /// + /// The WSAQUERYSET structure is used as part of the original namespace provider version 1 architecture available on Windows + /// 95 and later. A newer version 2 of the namespace architecture is available on Windows Vista and later. + /// + /// + /// 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. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/ns-winsock2-wsaquerysetw typedef struct _WSAQuerySetW { DWORD dwSize; + // LPWSTR lpszServiceInstanceName; LPGUID lpServiceClassId; LPWSAVERSION lpVersion; LPWSTR lpszComment; DWORD dwNameSpace; LPGUID + // lpNSProviderId; LPWSTR lpszContext; DWORD dwNumberOfProtocols; LPAFPROTOCOLS lpafpProtocols; LPWSTR lpszQueryString; DWORD + // dwNumberOfCsAddrs; LPCSADDR_INFO lpcsaBuffer; DWORD dwOutputFlags; LPBLOB lpBlob; } WSAQUERYSETW, *PWSAQUERYSETW, *LPWSAQUERYSETW; + [PInvokeData("winsock2.h", MSDNShortId = "6c81fbba-aaf4-49ca-ab79-b6fe5dfb0076")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct WSAQUERYSET + { + /// + /// Type: DWORD + /// + /// The size, in bytes, of the WSAQUERYSET structure. This member is used as a versioning mechanism since the size of the + /// WSAQUERYSET structure has changed on later versions of Windows. + /// + /// + public uint dwSize; + + /// + /// Type: LPTSTR + /// + /// A pointer to an optional NULL-terminated string that contains service name. The semantics for using wildcards within the + /// string are not defined, but can be supported by certain namespace providers. + /// + /// + [MarshalAs(UnmanagedType.LPTStr)] public string lpszServiceInstanceName; + + /// + /// Type: LPGUID + /// The GUID corresponding to the service class. This member is required to be set. + /// + public GuidPtr lpServiceClassId; + + /// + /// Type: LPWSAVERSION + /// + /// A pointer to an optional desired version number of the namespace provider. This member provides version comparison semantics + /// (that is, the version requested must match exactly, or version must be not less than the value supplied). + /// + /// + public IntPtr lpVersion; + + /// + /// Type: LPTSTR + /// This member is ignored for queries. + /// + [MarshalAs(UnmanagedType.LPTStr)] public string lpszComment; + + /// + /// Type: DWORD + /// + /// A namespace identifier that determines which namespace providers are queried. Passing a specific namespace identifier will + /// result in only namespace providers that support the specified namespace being queried. Specifying NS_ALL will result + /// in all installed and active namespace providers being queried. + /// + /// + /// Options for the dwNameSpace member are listed in the Winsock2.h include file. Several new namespace providers are + /// included with Windows Vista and later. Other namespace providers can be installed, so the following possible values are only + /// those commonly available. Many other values are possible. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// NS_ALL + /// All installed and active namespaces. + /// + /// + /// NS_BTH + /// The Bluetooth namespace. This namespace identifier is supported on Windows Vista and later. + /// + /// + /// NS_DNS + /// The domain name system (DNS) namespace. + /// + /// + /// NS_EMAIL + /// The email namespace. This namespace identifier is supported on Windows Vista and later. + /// + /// + /// NS_NLA + /// The network location awareness (NLA) namespace. This namespace identifier is supported on Windows XP and later. + /// + /// + /// NS_PNRPNAME + /// + /// The peer-to-peer name space for a specific peer name. This namespace identifier is supported on Windows Vista and later. + /// + /// + /// + /// NS_PNRPCLOUD + /// + /// The peer-to-peer name space for a collection of peer names. This namespace identifier is supported on Windows Vista and later. + /// + /// + /// + /// + public NS dwNameSpace; + + /// + /// Type: LPGUID + /// + /// A pointer to an optional GUID of a specific namespace provider to query in the case where multiple namespace providers are + /// registered under a single namespace such as NS_DNS. Passing the GUID for a specific namespace provider will result in + /// only the specified namespace provider being queried. The WSAEnumNameSpaceProviders and WSAEnumNameSpaceProvidersEx functions + /// can be called to retrieve the GUID for a namespace provider. + /// + /// + public GuidPtr lpNSProviderId; + + /// + /// Type: LPTSTR + /// A pointer to an optional starting point of the query in a hierarchical namespace. + /// + [MarshalAs(UnmanagedType.LPTStr)] public string lpszContext; + + /// + /// Type: DWORD + /// The size, in bytes, of the protocol constraint array. This member can be zero. + /// + public uint dwNumberOfProtocols; + + /// + /// Type: LPAFPROTOCOLS + /// A pointer to an optional array of AFPROTOCOLS structures. Only services that utilize these protocols will be returned. + /// + public IntPtr lpafpProtocols; + + /// + /// Type: LPTSTR + /// + /// A pointer to an optional NULL-terminated query string. 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. + /// + /// + [MarshalAs(UnmanagedType.LPTStr)] public string lpszQueryString; + + /// + /// Type: DWORD + /// This member is ignored for queries. + /// + public uint dwNumberOfCsAddrs; + + /// + /// Type: LPCSADDR_INFO + /// This member is ignored for queries. + /// + public IntPtr lpcsaBuffer; + + /// + /// Type: DWORD + /// This member is ignored for queries. + /// + public uint dwOutputFlags; + + /// + /// Type: LPBLOB + /// + /// An optional pointer to data that is used to query or set provider-specific namespace information. The format of this + /// information is specific to the namespace provider. + /// + /// + public IntPtr lpBlob; + + /// Initializes a new instance of the struct. + /// The name space. + public WSAQUERYSET(NS nameSpace) : this() + { + dwSize = (uint)Marshal.SizeOf(this); + dwNameSpace = nameSpace; + } + } + + /// + /// The WSASERVICECLASSINFO structure contains information about a specified service class. For each service class in Windows + /// Sockets 2, there is a single WSASERVICECLASSINFO structure. + /// + // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/ns-winsock2-wsaserviceclassinfow typedef struct _WSAServiceClassInfoW + // { LPGUID lpServiceClassId; LPWSTR lpszServiceClassName; DWORD dwCount; LPWSANSCLASSINFOW lpClassInfos; } WSASERVICECLASSINFOW, + // *PWSASERVICECLASSINFOW, *LPWSASERVICECLASSINFOW; + [PInvokeData("winsock2.h", MSDNShortId = "02422c24-34a6-4e34-a795-66b0b687ac44")] + [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] + public struct WSASERVICECLASSINFO + { + /// Unique Identifier (GUID) for the service class. + public GuidPtr lpServiceClassId; + + /// Well known name associated with the service class. + [MarshalAs(UnmanagedType.LPTStr)] + public string lpszServiceClassName; + + /// Number of entries in lpClassInfos. + public uint dwCount; + + /// Array of WSANSCLASSINFO structures that contains information about the service class. + public IntPtr lpClassInfos; + + /// Marshaled array of WSANSCLASSINFO structures that contains information about the service class. + public WSANSCLASSINFO[] ClassInfos => lpClassInfos.ToArray((int)dwCount); + } + + /// Provides a for that is disposed using . + public class SafeWSAEVENT : SafeHANDLE, ISyncHandle + { + /// Initializes a new instance of the class and assigns an existing handle. + /// An object that represents the pre-existing handle to use. + /// + /// to reliably release the handle during the finalization phase; otherwise, (not recommended). + /// + public SafeWSAEVENT(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } + + /// Initializes a new instance of the class. + private SafeWSAEVENT() : base() { } + + /// Performs an implicit conversion from to . + /// The safe handle instance. + /// The result of the conversion. + public static implicit operator WSAEVENT(SafeWSAEVENT h) => h.handle; + + /// + protected override bool InternalReleaseHandle() => WSACloseEvent(handle); + } + + /// + /// A disposable class to manage initialization of the WSA library. See remarks for use. + /// + /// + /// + /// using (var wsa = SafeWSA.Initialize()) + /// { + /// // Call WSA functions... + /// } + /// + /// Or, if you must have a certain version of the library, use the InitDemandVersion static method. + /// + /// using (var wsa = SafeWSA.InitDemandVersion(Macros.MAKEWORD(1, 1))) + /// { + /// // Call WSA functions. + /// // The above call with throw a VersionNotFoundException if that version is not supported. + /// } + /// + /// + /// + public class SafeWSA : IDisposable + { + private WSADATA data; + + private SafeWSA() { } + + /// Initiates use of the Winsock DLL by a process. + /// The requested version of the WinSock library. + /// An object that holds the WinSock library while in scope. Upon disposal, WSACleanup is called. + public static SafeWSA Initialize(ushort wVersionRequired = 0x0202) + { + var ret = new SafeWSA(); + WSAStartup(wVersionRequired, out ret.data).ThrowIfFailed(); + return ret; + } + + /// + /// Initiates use of the Winsock DLL by a process and throws an exception if isn't available. + /// + /// The required version of the WinSock library. + /// An object that holds the WinSock library while in scope. Upon disposal, WSACleanup is called. + /// + public static SafeWSA DemandVersion(ushort wVersionRequired) + { + var ret = Initialize(wVersionRequired); + if (ret.Data.wVersion != wVersionRequired) + throw new VersionNotFoundException(); + return ret; + } + + /// Gets the WSADATA value returned by WSAStartup. + /// The data. + public WSADATA Data { get => data; private set => data = value; } + + void IDisposable.Dispose() => WSACleanup(); + } + } +} \ No newline at end of file diff --git a/PInvoke/Ws2_32/WinSock2.WSA.cs b/PInvoke/Ws2_32/WinSock2.WSA.cs index 3ee8c545..1e9d1401 100644 --- a/PInvoke/Ws2_32/WinSock2.WSA.cs +++ b/PInvoke/Ws2_32/WinSock2.WSA.cs @@ -2,6 +2,7 @@ using System; using System.Data; +using System.Net.Sockets; using System.Runtime.InteropServices; using System.Text; using Vanara.Extensions; @@ -12,382 +13,6 @@ namespace Vanara.PInvoke /// Functions, structures and constants from ws2_32.h. public static partial class Ws2_32 { - /// The CompletionRoutine is a placeholder for an application-defined or library-defined function name. - /// Specifies the completion status for the overlapped operation as indicated by lpOverlapped. - /// Specifies the number of bytes received. - /// The overlapped operation. - /// Contains information that would have appeared in lpFlags if the receive operation had completed immediately. - // void (CALLBACK* LPWSAOVERLAPPED_COMPLETION_ROUTINE) ( IN DWORD dwError, IN DWORD cbTransferred, IN LPWSAOVERLAPPED lpOverlapped, - // IN DWORD dwFlags ); - [PInvokeData("winsock2.h", MSDNShortId = "abaf367a-8f99-478c-a58c-d57e9f9cd8a1")] - public delegate void LPWSAOVERLAPPED_COMPLETION_ROUTINE([In] uint dwError, [In] uint cbTransferred, [In] in WSAOVERLAPPED lpOverlapped, [In] uint dwFlags); - - /// Network events. - [PInvokeData("winsock2.h", MSDNShortId = "f98a71e4-47fb-47a4-b37e-e4cc801a8f98")] - public enum FD - { - /// Wants to receive notification of readiness for reading. - FD_READ = (1 << 0), - - /// Wants to receive notification of readiness for writing. - FD_WRITE = (1 << 1), - - /// Wants to receive notification of the arrival of OOB data. - FD_OOB = (1 << 2), - - /// Wants to receive notification of incoming connections. - FD_ACCEPT = (1 << 3), - - /// Wants to receive notification of completed connection or multipoint join operation. - FD_CONNECT = (1 << 4), - - /// Wants to receive notification of socket closure. - FD_CLOSE = (1 << 5), - - /// Wants to receive notification of socket (QoS changes. - FD_QOS = (1 << 6), - - /// Reserved for future use with socket groups. Want to receive notification of socket group QoS changes. - FD_GROUP_QOS = (1 << 7), - - /// Wants to receive notification of routing interface changes for the specified destination. - FD_ROUTING_INTERFACE_CHANGE = (1 << 8), - - /// Wants to receive notification of local address list changes for the address family of the socket. - FD_ADDRESS_LIST_CHANGE = (1 << 9), - - /// All events. - FD_ALL_EVENTS = ((1 << 10) - 1) - } - - /// Flags to indicate that the socket is acting as a sender (JL_SENDER_ONLY), receiver (JL_RECEIVER_ONLY), or both (JL_BOTH). - [PInvokeData("winsock2.h", MSDNShortId = "ef9efa03-feed-4f0d-b874-c646cce745c9")] - [Flags] - public enum JL - { - /// Acting as a sender. - JL_SENDER_ONLY = 0x01, - - /// Acting as a receiver. - JL_RECEIVER_ONLY = 0x02, - - /// Acting as both sender and receiver. - JL_BOTH = 0x04, - } - - /// Flags that control the depth of the search. - [PInvokeData("winsock2.h", MSDNShortId = "448309ef-b9dd-4960-8016-d26691df59ec")] - [Flags] - public enum LUP : uint - { - /// Queries deep as opposed to just the first level. - LUP_DEEP = 0x0001, - - /// Returns containers only. - LUP_CONTAINERS = 0x0002, - - /// Do not return containers. - LUP_NOCONTAINERS = 0x0004, - - /// If possible, returns results in the order of distance. The measure of distance is provider specific. - LUP_NEAREST = 0x0008, - - /// Retrieves the name as lpszServiceInstanceName. - LUP_RETURN_NAME = 0x0010, - - /// Retrieves the type as lpServiceClassId. - LUP_RETURN_TYPE = 0x0020, - - /// Retrieves the version as lpVersion. - LUP_RETURN_VERSION = 0x0040, - - /// Retrieves the comment as lpszComment. - LUP_RETURN_COMMENT = 0x0080, - - /// Retrieves the addresses as lpcsaBuffer. - LUP_RETURN_ADDR = 0x0100, - - /// Retrieves the private data as lpBlob. - LUP_RETURN_BLOB = 0x0200, - - /// - /// 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. - /// - LUP_RETURN_ALIASES = 0x0400, - - /// Retrieves the query string used for the request. - LUP_RETURN_QUERY_STRING = 0x0800, - - /// A set of flags that retrieves all of the LUP_RETURN_* values. - LUP_RETURN_ALL = 0x0FF0, - - /// If the provider has cached information, ignore the cache and query the namespace itself. - LUP_FLUSHCACHE = 0x1000, - - /// - /// Used as a value for the dwControlFlags parameter in NSPLookupServiceNext. Setting this flag instructs the provider to - /// discard the last result set, which was too large for the supplied buffer, and move on to the next result set. - /// - LUP_FLUSHPREVIOUS = 0x2000, - - /// Indicates that the namespace provider should included non-authoritative results for names. - LUP_NON_AUTHORITATIVE = 0x4000, - - /// - /// Indicates whether prime response is in the remote or local part of CSADDR_INFO structure. The other part must be usable in - /// either case. This option applies only to service instance requests. - /// - LUP_RES_SERVICE = 0x8000, - - /// Indicates that the namespace provider should use a secure query. This option only applies to name query requests. - LUP_SECURE = 0x8000, - - /// Indicates that the namespace provider should return only preferred names. - LUP_RETURN_PREFERRED_NAMES = 0x10000, - - /// Indicates that the namespace provider should return the address configuration. - LUP_ADDRCONFIG = 0x100000, - - /// - /// Indicates that the namespace provider should return the dual addresses. This option only applies to dual-mode sockets (IPv6 - /// and IPv4 mapped addresses). - /// - LUP_DUAL_ADDR = 0x200000, - - /// - LUP_DNS_ONLY = 0x20000, - - /// - LUP_FILESERVER = 0x00400000, - - /// - /// Indicates that the namespace provider should disable automatic International Domain Names encoding. This value is supported - /// on Windows 8 and Windows Server 2012 - /// - LUP_DISABLE_IDN_ENCODING = 0x00800000, - - /// - LUP_API_ANSI = 0x01000000, - - /// - LUP_RESOLUTION_HANDLE = 0x80000000, - } - - /// - /// 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. - /// - [PInvokeData("winsock2.h", MSDNShortId = "bfe66e11-e9a7-4321-ad55-3141113e9a03")] - [Flags] - public enum MsgFlags - { - /// Processes OOB data. - MSG_OOB = 0x1, - - /// - /// 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. - /// - MSG_PEEK = 0x2, - - /// - MSG_DONTROUTE = 0x4, - - /// - /// 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. - /// - MSG_WAITALL = 0x8, - - /// - /// 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. - /// - MSG_PUSH_IMMEDIATE = 0x20, - - /// - /// 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. - /// - MSG_PARTIAL = 0x8000, - - /// - MSG_INTERRUPT = 0x10, - - /// The datagram was truncated. More data was present than the process allocated room for. - MSG_TRUNC = 0x0100, - - /// The control (ancillary) data was truncated. More control data was present than the process allocated room for. - MSG_CTRUNC = 0x0200, - - /// The datagram was received as a link-layer broadcast or with a destination IP address that is a broadcast address. - MSG_BCAST = 0x0400, - - /// The datagram was received with a destination IP address that is a multicast address. - MSG_MCAST = 0x0800, - - /// - /// This flag specifies that queued errors should be received from the socket error queue. The error is passed in an ancillary - /// message with a type dependent on the protocol (for IPv4 IP_RECVERR). The user should supply a buffer of sufficient size.See - /// cmsg(3) and ip(7) for more information.The payload of the original packet that caused the error is passed as normal data via - /// msg_iovec. The original destination address of the datagram that caused the error is supplied via msg_name. - /// - MSG_ERRQUEUE = 0x1000, - } - - /// - /// A set of flags that indicate the type of status being requested or, upon return from the WSAPoll function call, the results of - /// the status query. - /// - [PInvokeData("winsock2.h", MSDNShortId = "88f122ce-e2ca-44ce-bd53-d73d0962e7ef")] - [Flags] - public enum PollFlags : short - { - /// Normal data may be read without blocking. - POLLRDNORM = 0x0100, - - /// Priority band (out-of-band) data may be read without blocking. - POLLRDBAND = 0x0200, - - /// POLLRDNORM | POLLRDBAND - POLLIN = (POLLRDNORM | POLLRDBAND), - - /// Priority data may be read without blocking. This flag is not returned by the Microsoft Winsock provider. - POLLPRI = 0x0400, - - /// Normal data may be written without blocking. - POLLWRNORM = 0x0010, - - /// Normal data may be written without blocking. - POLLOUT = (POLLWRNORM), - - /// - POLLWRBAND = 0x0020, - - /// An error has occurred. - POLLERR = 0x0001, - - /// A stream-oriented connection was either disconnected or aborted. - POLLHUP = 0x0002, - - /// An invalid socket was used. - POLLNVAL = 0x0004, - } - - /// Service install flags value that further controls the operation performed of the WSASetServicefunction. - [PInvokeData("winsock2.h", MSDNShortId = "21a8ff26-4c9e-4846-a75a-1a27c746edab")] - [Flags] - public enum ServiceInstallFlags - { - /// - /// 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. - /// - SERVICE_MULTIPLE = 0x00000001, - } - - /// A set of flags used to specify additional socket attributes. - [PInvokeData("winsock2.h", MSDNShortId = "dcf2e543-de54-43d9-9e45-4cb935da3548")] - [Flags] - public enum WSA_FLAG - { - /// - /// 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. - /// - WSA_FLAG_OVERLAPPED = 0x01, - - /// - /// 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. - /// - WSA_FLAG_MULTIPOINT_C_ROOT = 0x02, - - /// - /// 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. - /// - WSA_FLAG_MULTIPOINT_C_LEAF = 0x04, - - /// - /// 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. - /// - WSA_FLAG_MULTIPOINT_D_ROOT = 0x08, - - /// - /// 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. - /// - WSA_FLAG_MULTIPOINT_D_LEAF = 0x10, - - /// - /// 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. - /// - WSA_FLAG_ACCESS_SYSTEM_SECURITY = 0x40, - - /// - /// 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 - /// - WSA_FLAG_NO_HANDLE_INHERIT = 0x80, - - /// - WSA_FLAG_REGISTERED_IO = 0x100, - } - /// The __WSAFDIsSet function specifies whether a socket is included in a set of socket descriptors. /// TBD /// @@ -405,7 +30,7 @@ namespace Vanara.PInvoke // 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 int __WSAFDIsSet(SOCKET arg1, in fd_set arg2); + public static extern SocketError __WSAFDIsSet(SOCKET arg1, in fd_set arg2); /// /// The WSAAccept function conditionally accepts a connection based on the return value of a condition function, provides @@ -672,7 +297,7 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [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); @@ -778,9 +403,9 @@ namespace Vanara.PInvoke // 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 = true, CharSet = CharSet.Auto)] + [DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("winsock2.h", MSDNShortId = "d72e55e6-79a9-4386-9e1a-24a322f13426")] - public static extern int WSAAddressToString([In] SOCKADDR lpsaAddress, uint dwAddressLength, in WSAPROTOCOL_INFO lpProtocolInfo, StringBuilder lpszAddressString, ref uint lpdwAddressStringLength); + public static extern SocketError WSAAddressToString([In] SOCKADDR lpsaAddress, uint dwAddressLength, in WSAPROTOCOL_INFO lpProtocolInfo, StringBuilder lpszAddressString, ref uint lpdwAddressStringLength); /// /// @@ -870,19 +495,18 @@ namespace Vanara.PInvoke // LPSOCKADDR lpsaAddress, DWORD dwAddressLength, LPWSAPROTOCOL_INFOA lpProtocolInfo, LPSTR lpszAddressString, LPDWORD // lpdwAddressStringLength ); [PInvokeData("winsock2.h", MSDNShortId = "d72e55e6-79a9-4386-9e1a-24a322f13426")] - public static Win32Error WSAAddressToString([In] SOCKADDR lpsaAddress, [In, Optional] WSAPROTOCOL_INFO? lpProtocolInfo, out string lpszAddressString) + public static string WSAAddressToString([In] SOCKADDR lpsaAddress, [In, Optional] WSAPROTOCOL_INFO? lpProtocolInfo) { using var pc = lpProtocolInfo.HasValue ? new SafeCoTaskMemStruct(lpProtocolInfo.Value) : SafeCoTaskMemStruct.Null; var sz = 1024U; var err = WSAAddressToString(lpsaAddress, (uint)lpsaAddress.Size, pc, null, ref sz); - lpszAddressString = null; - if (err == Win32Error.WSAEFAULT && sz > 0) + if (err == SocketError.Fault && sz > 0) { StringBuilder sb = new((int)sz); err = WSAAddressToString(lpsaAddress, (uint)lpsaAddress.Size, pc, sb, ref sz); - if (err == 0) lpszAddressString = sb.ToString(); + if (err == 0) return sb.ToString(); } - return WSAGetLastError(); + err.ThrowIfFailed(); } /// @@ -987,9 +611,9 @@ namespace Vanara.PInvoke // 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 = true, CharSet = CharSet.Auto)] + [DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("winsock2.h", MSDNShortId = "d72e55e6-79a9-4386-9e1a-24a322f13426")] - public static extern int WSAAddressToString([In] SOCKADDR lpsaAddress, uint dwAddressLength, [Optional] IntPtr lpProtocolInfo, StringBuilder lpszAddressString, ref uint lpdwAddressStringLength); + public static extern SocketError WSAAddressToString([In] SOCKADDR lpsaAddress, uint dwAddressLength, [Optional] IntPtr lpProtocolInfo, StringBuilder lpszAddressString, ref uint lpdwAddressStringLength); /// /// The WSAAsyncGetHostByAddr function asynchronously retrieves host information that corresponds to an address. @@ -1132,7 +756,7 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [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); @@ -1343,7 +967,7 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true, CharSet = CharSet.Ansi)] + [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); @@ -1478,7 +1102,7 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [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); @@ -1617,7 +1241,7 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true, CharSet = CharSet.Ansi)] + [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); @@ -1755,7 +1379,7 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [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); @@ -2274,9 +1898,9 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock.h", MSDNShortId = "a4d3f599-358c-4a94-91eb-7e1c80244250")] - public static extern int WSAAsyncSelect(SOCKET s, HWND hWnd, uint wMsg, int lEvent); + public static extern SocketError WSAAsyncSelect(SOCKET s, HWND hWnd, uint wMsg, int lEvent); /// The WSACancelAsyncRequest function cancels an incomplete asynchronous operation. /// Handle that specifies the asynchronous operation to be canceled. @@ -2334,9 +1958,9 @@ namespace Vanara.PInvoke /// // https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsacancelasyncrequest int WSACancelAsyncRequest( HANDLE // hAsyncTaskHandle ); - [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock.h", MSDNShortId = "0e53eccf-ef85-43ec-a02c-12896471a7a9")] - public static extern int WSACancelAsyncRequest(HANDLE hAsyncTaskHandle); + public static extern SocketError WSACancelAsyncRequest(HANDLE hAsyncTaskHandle); /// The WSACleanup function terminates use of the Winsock 2 DLL (Ws2_32.dll). /// @@ -2412,9 +2036,9 @@ namespace Vanara.PInvoke /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winsock/nf-winsock-wsacleanup int WSACleanup( ); - [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock.h", MSDNShortId = "72b7cc3e-be34-41e7-acbf-61742149ec8b")] - public static extern int WSACleanup(); + public static extern SocketError WSACleanup(); /// The WSACloseEvent function closes an open event object handle. /// Object handle identifying the open event. @@ -2457,7 +2081,7 @@ namespace Vanara.PInvoke /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsacloseevent BOOL WSAAPI WSACloseEvent( WSAEVENT hEvent ); - [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)] + [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); @@ -2725,9 +2349,9 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "3b32cc6e-3df7-4104-a0d4-317fd445c7b2")] - public static extern int WSAConnect(SOCKET s, [In] SOCKADDR name, int namelen, [In, Optional] IntPtr lpCallerData, + public static extern SocketError WSAConnect(SOCKET s, [In] SOCKADDR name, int namelen, [In, Optional] IntPtr lpCallerData, [Out, Optional] IntPtr lpCalleeData, [Optional] IntPtr lpSQOS, [Optional] IntPtr lpGQOS); /// @@ -2897,7 +2521,7 @@ namespace Vanara.PInvoke // 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 = true, ExactSpelling = true)] + [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, @@ -3052,7 +2676,7 @@ namespace Vanara.PInvoke // 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 = true, CharSet = CharSet.Auto)] + [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, @@ -3109,7 +2733,7 @@ namespace Vanara.PInvoke /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsacreateevent WSAEVENT WSAAPI WSACreateEvent(); - [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "cff3bc31-f34c-4bb2-9004-5ec31d0a704a")] public static extern SafeWSAEVENT WSACreateEvent(); @@ -3265,9 +2889,9 @@ namespace Vanara.PInvoke /// // 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 = true, CharSet = CharSet.Auto)] + [DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("winsock2.h", MSDNShortId = "d4028461-bfa6-4074-9460-5d1371790d41")] - public static extern int WSADuplicateSocket(SOCKET s, uint dwProcessId, out WSAPROTOCOL_INFO lpProtocolInfo); + public static extern SocketError WSADuplicateSocket(SOCKET s, uint dwProcessId, out WSAPROTOCOL_INFO lpProtocolInfo); /// The WSAEnumNameSpaceProviders function retrieves information on available namespace providers. /// @@ -3343,9 +2967,9 @@ namespace Vanara.PInvoke /// // 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 = true, CharSet = CharSet.Unicode)] + [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); + public static extern SocketError WSAEnumNameSpaceProviders(ref uint lpdwBufferLength, [Out] IntPtr lpnspBuffer); /// The WSAEnumNameSpaceProvidersEx function retrieves information on available namespace providers. /// @@ -3417,9 +3041,9 @@ namespace Vanara.PInvoke /// // 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 = true, CharSet = CharSet.Unicode)] + [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); + public static extern SocketError WSAEnumNameSpaceProvidersEx(ref uint lpdwBufferLength, [Out] IntPtr lpnspBuffer); /// /// The WSAEnumNetworkEvents function discovers occurrences of network events for the indicated socket, clear internal @@ -3583,9 +3207,9 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "2e6abccd-c82c-4a6b-8720-259986ac9984")] - public static extern int WSAEnumNetworkEvents(SOCKET s, [Optional] WSAEVENT hEventObject, out WSANETWORKEVENTS lpNetworkEvents); + public static extern SocketError WSAEnumNetworkEvents(SOCKET s, [Optional] WSAEVENT hEventObject, out WSANETWORKEVENTS lpNetworkEvents); /// The WSAEnumProtocols function retrieves information about available transport protocols. /// @@ -3691,9 +3315,9 @@ namespace Vanara.PInvoke /// // 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 = true, CharSet = CharSet.Auto)] + [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); + public static extern SocketError WSAEnumProtocols([Optional, MarshalAs(UnmanagedType.LPArray)] int[] lpiProtocols, [Out] IntPtr lpProtocolBuffer, ref uint lpdwBufferLength); /// /// The WSAEventSelect function specifies an event object to be associated with the specified set of FD_XXX network events. @@ -4037,9 +3661,9 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "f98a71e4-47fb-47a4-b37e-e4cc801a8f98")] - public static extern int WSAEventSelect(SOCKET s, WSAEVENT hEventObject, FD lNetworkEvents); + public static extern SocketError WSAEventSelect(SOCKET s, WSAEVENT hEventObject, FD lNetworkEvents); /// The WSAGetLastError function returns the error status for the last Windows Sockets operation that failed. /// The return value indicates the error code for this thread's last Windows Sockets operation that failed. @@ -4084,9 +3708,9 @@ namespace Vanara.PInvoke /// /// // https://docs.microsoft.com/en-us/windows/desktop/api/winsock/nf-winsock-wsagetlasterror int WSAGetLastError( ); - [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock.h", MSDNShortId = "39e41b66-44ed-46dc-bfc2-65228b669992")] - public static extern Win32Error WSAGetLastError(); + public static extern SocketError WSAGetLastError(); /// The WSAGetOverlappedResult function retrieves the results of an overlapped operation on the specified socket. /// @@ -4201,7 +3825,7 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [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); @@ -4262,7 +3886,7 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [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); @@ -4348,9 +3972,9 @@ namespace Vanara.PInvoke // 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 = true, CharSet = CharSet.Auto)] + [DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("winsock2.h", MSDNShortId = "e177bb7d-c7d3-43a4-a809-ab8212feea2e")] - public static extern int WSAGetServiceClassInfo(in Guid lpProviderId, in Guid lpServiceClassId, ref uint lpdwBufSize, IntPtr lpServiceClassInfo); + public static extern SocketError WSAGetServiceClassInfo(in Guid lpProviderId, in Guid lpServiceClassId, ref uint lpdwBufSize, IntPtr lpServiceClassInfo); /// /// The WSAGetServiceClassNameByClassId function retrieves the name of the service associated with the specified type. This @@ -4413,9 +4037,9 @@ namespace Vanara.PInvoke /// // 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 = true, CharSet = CharSet.Auto)] + [DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("winsock2.h", MSDNShortId = "0a61751e-10e5-4f91-a0b2-8c1baf477653")] - public static extern int WSAGetServiceClassNameByClassId(in Guid lpServiceClassId, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpszServiceClassName, ref uint lpdwBufferLength); + public static extern SocketError WSAGetServiceClassNameByClassId(in Guid lpServiceClassId, [MarshalAs(UnmanagedType.LPTStr)] StringBuilder lpszServiceClassName, ref uint lpdwBufferLength); /// The WSAHtonl function converts a u_long from host byte order to network byte order. /// A descriptor identifying a socket. @@ -4475,9 +4099,9 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "33512f49-d576-4439-ad8d-5c87387d6214")] - public static extern int WSAHtonl([In] SOCKET s, [In] uint hostlong, out uint lpnetlong); + public static extern SocketError WSAHtonl([In] SOCKET s, [In] uint hostlong, out uint lpnetlong); /// The WSAHtons function converts a u_short from host byte order to network byte order. /// A descriptor identifying a socket. @@ -4536,9 +4160,9 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "95fb103b-f7dd-4fa4-bf68-ed8e87cdd96b")] - public static extern int WSAHtons([In] SOCKET s, [In] ushort hostshort, out ushort lpnetshort); + public static extern SocketError WSAHtons([In] SOCKET s, [In] ushort hostshort, out ushort lpnetshort); /// /// The WSAInstallServiceClass function registers a service class schema within a namespace. This schema includes the class @@ -4603,9 +4227,9 @@ namespace Vanara.PInvoke /// // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsainstallserviceclassa INT WSAAPI // WSAInstallServiceClassA( LPWSASERVICECLASSINFOA lpServiceClassInfo ); - [DllImport(Lib.Ws2_32, SetLastError = true, CharSet = CharSet.Auto)] + [DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("winsock2.h", MSDNShortId = "06760319-aeeb-4ad7-b77a-01efea7ed904")] - public static extern int WSAInstallServiceClass(in WSASERVICECLASSINFO lpServiceClassInfo); + public static extern SocketError WSAInstallServiceClass(in WSASERVICECLASSINFO lpServiceClassInfo); /// The WSAIoctl function controls the mode of a socket. /// A descriptor identifying a socket. @@ -4842,9 +4466,9 @@ namespace Vanara.PInvoke // 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 = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "038aeca6-d7b7-4f74-ac69-4536c2e5118b")] - public static extern int WSAIoctl(SOCKET s, uint dwIoControlCode, [In] IntPtr lpvInBuffer, uint cbInBuffer, [Out] IntPtr lpvOutBuffer, uint cbOutBuffer, out uint lpcbBytesReturned, [Optional] IntPtr lpOverlapped, [Optional] IntPtr lpCompletionRoutine); + public static extern SocketError WSAIoctl(SOCKET s, uint dwIoControlCode, [In] IntPtr lpvInBuffer, uint cbInBuffer, [Out] IntPtr lpvOutBuffer, uint cbOutBuffer, out uint lpcbBytesReturned, [Optional] IntPtr lpOverlapped, [Optional] IntPtr lpCompletionRoutine); /// The WSAIoctl function controls the mode of a socket. /// A descriptor identifying a socket. @@ -5263,7 +4887,7 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [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); @@ -5541,9 +5165,9 @@ namespace Vanara.PInvoke /// // 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 = true, CharSet = CharSet.Auto)] + [DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("winsock2.h", MSDNShortId = "448309ef-b9dd-4960-8016-d26691df59ec")] - public static extern int WSALookupServiceBegin(in WSAQUERYSET lpqsRestrictions, LUP dwControlFlags, out HANDLE lphLookup); + public static extern SocketError WSALookupServiceBegin(in WSAQUERYSET lpqsRestrictions, LUP dwControlFlags, out HANDLE lphLookup); /// /// @@ -5590,9 +5214,9 @@ namespace Vanara.PInvoke /// // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsalookupserviceend INT WSAAPI WSALookupServiceEnd( // HANDLE hLookup ); - [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "f9d2ac54-a818-464d-918e-80ebb5b1b106")] - public static extern int WSALookupServiceEnd(HANDLE hLookup); + public static extern SocketError WSALookupServiceEnd(HANDLE hLookup); /// /// @@ -5876,9 +5500,9 @@ namespace Vanara.PInvoke /// // 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 = true, CharSet = CharSet.Auto)] + [DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("winsock2.h", MSDNShortId = "ab4f1830-b38d-4224-a6a9-6d4512245ad6")] - public static extern int WSALookupServiceNext(HANDLE hLookup, LUP dwControlFlags, ref uint lpdwBufferLength, [Out] IntPtr lpqsResults); + public static extern SocketError WSALookupServiceNext(HANDLE hLookup, LUP dwControlFlags, ref uint lpdwBufferLength, [Out] IntPtr lpqsResults); /// The Windows Sockets WSANSPIoctl function enables developers to make I/O control calls to a registered namespace. /// The lookup handle returned from a previous call to the WSALookupServiceBegin function. @@ -6008,9 +5632,9 @@ namespace Vanara.PInvoke // 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 = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "6ecaedf0-0038-46d3-9916-c9cb069c5e92")] - public static extern int WSANSPIoctl(HANDLE hLookup, uint dwControlCode, [In, Optional] IntPtr lpvInBuffer, uint cbInBuffer, [Out, Optional] IntPtr lpvOutBuffer, uint cbOutBuffer, out uint lpcbBytesReturned, [In, Optional] IntPtr lpCompletion); + public static extern SocketError WSANSPIoctl(HANDLE hLookup, uint dwControlCode, [In, Optional] IntPtr lpvInBuffer, uint cbInBuffer, [Out, Optional] IntPtr lpvOutBuffer, uint cbOutBuffer, out uint lpcbBytesReturned, [In, Optional] IntPtr lpCompletion); /// The WSANtohl function converts a u_long from network byte order to host byte order. /// A descriptor identifying a socket. @@ -6070,9 +5694,9 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "7e3b42eb-3b93-459f-828a-c19e277882c7")] - public static extern int WSANtohl(SOCKET s, uint netlong, out uint lphostlong); + public static extern SocketError WSANtohl(SOCKET s, uint netlong, out uint lphostlong); /// The WSANtohs function converts a u_short from network byte order to host byte order. /// A descriptor identifying a socket. @@ -6131,9 +5755,9 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "0a4bc3a9-9919-4dcb-8a37-af37e0243c8f")] - public static extern int WSANtohs(SOCKET s, ushort netshort, out ushort lphostshort); + public static extern SocketError WSANtohs(SOCKET s, ushort netshort, out ushort lphostshort); /// The WSAPoll function determines status of one or more sockets. /// @@ -6325,9 +5949,9 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [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); + public static extern SocketError WSAPoll([In, Out, MarshalAs(UnmanagedType.LPArray)] WSAPOLLFD[] fdArray, uint fds, int timeout); /// The WSAProviderConfigChange function notifies the application when the provider configuration is changed. /// @@ -6409,9 +6033,9 @@ namespace Vanara.PInvoke // 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 = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "abaf367a-8f99-478c-a58c-d57e9f9cd8a1")] - public static extern int WSAProviderConfigChange(ref HANDLE lpNotificationHandle, [In, Out, Optional] IntPtr lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); + public static extern SocketError WSAProviderConfigChange(ref HANDLE lpNotificationHandle, [In, Out, Optional] IntPtr lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); /// The WSARecv function receives data from a connected socket or a bound connectionless socket. /// A descriptor identifying a connected socket. @@ -6802,9 +6426,9 @@ namespace Vanara.PInvoke // 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 = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "bfe66e11-e9a7-4321-ad55-3141113e9a03")] - public static extern int WSARecv(SOCKET s, [In] IntPtr lpBuffers, uint dwBufferCount, out uint lpNumberOfBytesRecvd, ref MsgFlags lpFlags, [In, Out, Optional] IntPtr lpOverlapped, + public static extern SocketError WSARecv(SOCKET s, [In] IntPtr lpBuffers, uint dwBufferCount, out uint lpNumberOfBytesRecvd, ref MsgFlags lpFlags, [In, Out, Optional] IntPtr lpOverlapped, [In, Optional, MarshalAs(UnmanagedType.FunctionPtr)] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); /// @@ -6897,9 +6521,9 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "33e0fb8e-3ece-427f-b3ef-43a0f5cf0cc8")] - public static extern int WSARecvDisconnect(SOCKET s, [In, Out, Optional] IntPtr lpInboundDisconnectData); + public static extern SocketError WSARecvDisconnect(SOCKET s, [In, Out, Optional] IntPtr lpInboundDisconnectData); /// The WSARecvFrom function receives a datagram and stores the source address. /// A descriptor identifying a socket. @@ -7197,9 +6821,9 @@ namespace Vanara.PInvoke // 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 = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "8617dbb8-0e4e-4cd3-9597-5d20de6778f6")] - public static extern int WSARecvFrom(SOCKET s, [In, Out, Optional, MarshalAs(UnmanagedType.LPArray)] WSABUF[] lpBuffers, uint dwBufferCount, out uint lpNumberOfBytesRecvd, ref MsgFlags lpFlags, + public static extern SocketError 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); /// The WSARemoveServiceClass function permanently removes the service class schema from the registry. @@ -7244,9 +6868,9 @@ namespace Vanara.PInvoke /// // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaremoveserviceclass INT WSAAPI WSARemoveServiceClass( // LPGUID lpServiceClassId ); - [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "7d72f727-cca9-4a07-beb4-d64f23c1f0c1")] - public static extern int WSARemoveServiceClass(in Guid lpServiceClassId); + public static extern SocketError WSARemoveServiceClass(in Guid lpServiceClassId); /// The WSAResetEvent function resets the state of the specified event object to nonsignaled. /// A handle that identifies an open event object handle. @@ -7292,7 +6916,7 @@ namespace Vanara.PInvoke /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsaresetevent BOOL WSAAPI WSAResetEvent( WSAEVENT hEvent ); - [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)] + [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); @@ -7588,9 +7212,9 @@ namespace Vanara.PInvoke // 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 = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "764339e6-a1ac-455d-8ebd-ad0fa50dc3b0")] - public static extern int WSASend(SOCKET s, [In, MarshalAs(UnmanagedType.LPArray)] WSABUF[] lpBuffers, uint dwBufferCount, out uint lpNumberOfBytesSent, + public static extern SocketError 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); /// @@ -7672,9 +7296,9 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "c05fc719-e35a-4194-ac01-a294b19ccce9")] - public static extern int WSASendDisconnect(SOCKET s, in WSABUF lpOutboundDisconnectData); + public static extern SocketError WSASendDisconnect(SOCKET s, in WSABUF lpOutboundDisconnectData); /// /// The WSASendDisconnect function initiates termination of the connection for the socket and sends disconnect data. @@ -7755,9 +7379,9 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "c05fc719-e35a-4194-ac01-a294b19ccce9")] - public static extern int WSASendDisconnect(SOCKET s, [In, Optional] IntPtr lpOutboundDisconnectData); + public static extern SocketError WSASendDisconnect(SOCKET s, [In, Optional] IntPtr lpOutboundDisconnectData); /// The WSASendMsg function sends data and optional control information from connected and unconnected sockets. /// A descriptor identifying the socket. @@ -8062,9 +7686,9 @@ namespace Vanara.PInvoke // 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 = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "3b2ba645-6a70-4ba2-b4a2-5bde0c7f8d08")] - public static extern int WSASendMsg(SOCKET Handle, in WSAMSG lpMsg, MsgFlags dwFlags, out uint lpNumberOfBytesSent, [In, Out, Optional] IntPtr lpOverlapped, + public static extern SocketError 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); /// The WSASendTo function sends data to a specific destination, using overlapped I/O where applicable. @@ -8368,9 +7992,9 @@ namespace Vanara.PInvoke // 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 = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "e3a11522-871c-4d6b-a2e6-ca91ffc2b698")] - public static extern int WSASendTo(SOCKET s, [In, MarshalAs(UnmanagedType.LPArray)] WSABUF[] lpBuffers, uint dwBufferCount, out uint lpNumberOfBytesSent, + public static extern SocketError 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); @@ -8411,7 +8035,7 @@ namespace Vanara.PInvoke /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/nf-winsock2-wsasetevent BOOL WSAAPI WSASetEvent( WSAEVENT hEvent ); - [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)] + [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); @@ -8448,7 +8072,7 @@ namespace Vanara.PInvoke /// /// // https://docs.microsoft.com/en-us/windows/win32/api/winsock/nf-winsock-wsasetlasterror void WSASetLastError( int iError ); - [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)] + [DllImport(Lib.Ws2_32, SetLastError = false, ExactSpelling = true)] [PInvokeData("winsock.h", MSDNShortId = "596155ee-3dcc-4ae3-97ab-0653e019cbee")] public static extern void WSASetLastError(int iError); @@ -8725,9 +8349,9 @@ namespace Vanara.PInvoke /// // 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 = true, CharSet = CharSet.Auto)] + [DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("winsock2.h", MSDNShortId = "21a8ff26-4c9e-4846-a75a-1a27c746edab")] - public static extern int WSASetService(in WSAQUERYSET lpqsRegInfo, WSAESETSERVICEOP essoperation, ServiceInstallFlags dwControlFlags); + public static extern SocketError WSASetService(in WSAQUERYSET lpqsRegInfo, WSAESETSERVICEOP essoperation, ServiceInstallFlags dwControlFlags); /// The WSASocket function creates a socket that is bound to a specific transport-service provider. /// @@ -9282,7 +8906,7 @@ namespace Vanara.PInvoke /// // 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 = true, CharSet = CharSet.Auto)] + [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); @@ -9839,7 +9463,7 @@ namespace Vanara.PInvoke /// // 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 = true, CharSet = CharSet.Auto)] + [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); @@ -10098,7 +9722,7 @@ namespace Vanara.PInvoke /// // https://docs.microsoft.com/en-us/windows/desktop/api/winsock/nf-winsock-wsastartup int WSAStartup( WORD wVersionRequired, // LPWSADATA lpWSAData ); - [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)] + [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); @@ -10179,9 +9803,9 @@ namespace Vanara.PInvoke /// // 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 = true, CharSet = CharSet.Auto)] + [DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("winsock2.h", MSDNShortId = "7b9946c3-c8b3-45ae-9bde-03faaf604bba")] - public static extern int WSAStringToAddress([MarshalAs(UnmanagedType.LPTStr)] string AddressString, ADDRESS_FAMILY AddressFamily, in WSAPROTOCOL_INFO lpProtocolInfo, [Out] SOCKADDR lpAddress, ref int lpAddressLength); + public static extern SocketError WSAStringToAddress([MarshalAs(UnmanagedType.LPTStr)] string AddressString, ADDRESS_FAMILY AddressFamily, in WSAPROTOCOL_INFO lpProtocolInfo, [Out] SOCKADDR lpAddress, ref int lpAddressLength); /// /// The WSAStringToAddress function converts a network address in its standard text presentation form into its numeric binary @@ -10260,9 +9884,9 @@ namespace Vanara.PInvoke /// // 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 = true, CharSet = CharSet.Auto)] + [DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("winsock2.h", MSDNShortId = "7b9946c3-c8b3-45ae-9bde-03faaf604bba")] - public static extern int WSAStringToAddress([MarshalAs(UnmanagedType.LPTStr)] string AddressString, ADDRESS_FAMILY AddressFamily, [In, Optional] IntPtr lpProtocolInfo, [Out] SOCKADDR lpAddress, ref int lpAddressLength); + public static extern SocketError WSAStringToAddress([MarshalAs(UnmanagedType.LPTStr)] string AddressString, ADDRESS_FAMILY AddressFamily, [In, Optional] IntPtr lpProtocolInfo, [Out] SOCKADDR lpAddress, ref int lpAddressLength); /// /// The WSAStringToAddress function converts a network address in its standard text presentation form into its numeric binary @@ -10341,9 +9965,9 @@ namespace Vanara.PInvoke /// // 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 = true, CharSet = CharSet.Auto)] + [DllImport(Lib.Ws2_32, SetLastError = false, CharSet = CharSet.Auto)] [PInvokeData("winsock2.h", MSDNShortId = "7b9946c3-c8b3-45ae-9bde-03faaf604bba")] - public static extern int WSAStringToAddress([MarshalAs(UnmanagedType.LPTStr)] string AddressString, ADDRESS_FAMILY AddressFamily, [In, Optional] IntPtr lpProtocolInfo, [Out] IntPtr lpAddress, ref int lpAddressLength); + public static extern SocketError WSAStringToAddress([MarshalAs(UnmanagedType.LPTStr)] string AddressString, ADDRESS_FAMILY AddressFamily, [In, Optional] IntPtr lpProtocolInfo, [Out] IntPtr lpAddress, ref int lpAddressLength); /// /// The WSAStringToAddress function converts a network address in its standard text presentation form into its numeric binary @@ -10584,482 +10208,8 @@ namespace Vanara.PInvoke /// // 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 = true, ExactSpelling = true)] + [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); - - /// - /// The fd_set structure is used by various Windows Sockets functions and service providers, such as the select function, to - /// place sockets into a "set" for various purposes, such as testing a given socket for readability using the readfds parameter of - /// the select function. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winsock/ns-winsock-fd_set typedef struct fd_set { u_int fd_count; SOCKET - // fd_array[FD_SETSIZE]; } fd_set, FD_SET, *PFD_SET, *LPFD_SET; - [PInvokeData("winsock.h", MSDNShortId = "2af5d69d-190e-4814-8d8b-438431808625")] - [StructLayout(LayoutKind.Sequential)] - public struct fd_set - { - /// The number of sockets in the set. - public uint fd_count; - - /// An array of sockets that are in the set. - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)] - public SOCKET[] fd_array; - } - - /// The WSANETWORKEVENTS structure is used to store a socket's internal information about network events. - // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/ns-winsock2-wsanetworkevents typedef struct _WSANETWORKEVENTS { long - // lNetworkEvents; int iErrorCode[FD_MAX_EVENTS]; } WSANETWORKEVENTS, *LPWSANETWORKEVENTS; - [PInvokeData("winsock2.h", MSDNShortId = "72ae4aa8-4e15-4215-8dcb-45e394ac1313")] - [StructLayout(LayoutKind.Sequential)] - public struct WSANETWORKEVENTS - { - /// Indicates which of the FD_XXX network events have occurred. - public int lNetworkEvents; - - /// - /// Array that contains any associated error codes, with an array index that corresponds to the position of event bits in - /// lNetworkEvents. The identifiers FD_READ_BIT, FD_WRITE_BIT and others can be used to index the iErrorCode array. - /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 10)] - public int[] iErrorCode; - } - - /// The WSANSCLASSINFO structure provides individual parameter information for a specific Windows Sockets namespace. - /// - /// The WSANSCLASSINFO structure is defined differently depending on whether ANSI or UNICODE is used. The above syntax block - /// applies to ANSI; for UNICODE, the datatype for lpszName is LPWSTR. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/ns-winsock2-wsansclassinfoa typedef struct _WSANSClassInfoA { LPSTR - // lpszName; DWORD dwNameSpace; DWORD dwValueType; DWORD dwValueSize; LPVOID lpValue; } WSANSCLASSINFOA, *PWSANSCLASSINFOA, *LPWSANSCLASSINFOA; - [PInvokeData("winsock2.h", MSDNShortId = "b4f811ad-7967-45bd-b563-a28bb1633596")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] - public struct WSANSCLASSINFO - { - /// String value associated with the parameter, such as SAPID, TCPPORT, and so forth. - [MarshalAs(UnmanagedType.LPStr)] - public string lpszName; - - /// GUID associated with the namespace. - public uint dwNameSpace; - - /// Value type for the parameter, such as REG_DWORD or REG_SZ, and so forth. - public uint dwValueType; - - /// Size of the parameter provided in lpValue, in bytes. - public uint dwValueSize; - - /// Pointer to the value of the parameter. - public IntPtr lpValue; - } - - /// The WSAPOLLFD structure stores socket information used by the WSAPoll function. - /// - /// The WSAPOLLFD structure is defined on Windows Vista and later. - /// - /// The WSAPOLLFD structure is used by the WSAPoll function to determine the status of one or more sockets. The set of - /// sockets for which status is requested is specified in fdarray parameter, which is an array of WSAPOLLFD structures. An - /// application sets the appropriate flags in the events member of the WSAPOLLFD structure to specify the type of - /// status requested for each corresponding socket. The WSAPoll function returns the status of a socket in the revents - /// member of the WSAPOLLFD structure. - /// - /// - /// If the fd member of the WSAPOLLFD structure is set to a negative value, the structure is ignored by the WSAPoll - /// function call, and the revents member is cleared upon return. This is useful to applications that maintain a fixed - /// allocation for the fdarray parameter of WSAPoll; such applications need not waste resources compacting elements of the - /// array for unused entries or reallocating memory. It is unnecessary to clear the revents member prior to calling the - /// WSAPoll function. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/ns-winsock2-wsapollfd typedef struct pollfd { SOCKET fd; SHORT - // events; SHORT revents; } WSAPOLLFD, *PWSAPOLLFD, *LPWSAPOLLFD; - [PInvokeData("winsock2.h", MSDNShortId = "88f122ce-e2ca-44ce-bd53-d73d0962e7ef")] - [StructLayout(LayoutKind.Sequential)] - public struct WSAPOLLFD - { - /// - /// Type: SOCKET - /// The identifier of the socket for which to find status. This parameter is ignored if set to a negative value. See Remarks. - /// - public SOCKET fd; - - /// - /// Type: short - /// A set of flags indicating the type of status being requested. This must be one or more of the following. - /// - /// - /// Flag - /// Meaning - /// - /// - /// POLLPRI - /// Priority data may be read without blocking. This flag is not supported by the Microsoft Winsock provider. - /// - /// - /// POLLRDBAND - /// Priority band (out-of-band) data can be read without blocking. - /// - /// - /// POLLRDNORM - /// Normal data can be read without blocking. - /// - /// - /// POLLWRNORM - /// Normal data can be written without blocking. - /// - /// - /// - /// The POLLIN flag is defined as the combination of the POLLRDNORM and POLLRDBAND flag values. The POLLOUT flag - /// is defined as the same as the POLLWRNORM flag value. - /// - /// - public PollFlags events; - - /// - /// Type: short - /// - /// A set of flags that indicate, upon return from the WSAPoll function call, the results of the status query. This can a - /// combination of the following flags. - /// - /// - /// - /// Flag - /// Description - /// - /// - /// POLLERR - /// An error has occurred. - /// - /// - /// POLLHUP - /// A stream-oriented connection was either disconnected or aborted. - /// - /// - /// POLLNVAL - /// An invalid socket was used. - /// - /// - /// POLLPRI - /// Priority data may be read without blocking. This flag is not returned by the Microsoft Winsock provider. - /// - /// - /// POLLRDBAND - /// Priority band (out-of-band) data may be read without blocking. - /// - /// - /// POLLRDNORM - /// Normal data may be read without blocking. - /// - /// - /// POLLWRNORM - /// Normal data may be written without blocking. - /// - /// - /// - /// The POLLIN flag is defined as the combination of the POLLRDNORM and POLLRDBAND flag values. The POLLOUT flag - /// is defined as the same as the POLLWRNORM flag value. - /// - /// - /// For sockets that do not satisfy the status query, and have no error, the revents member is set to zero upon return. - /// - /// - public PollFlags revents; - } - - /// - /// The WSAQUERYSET structure provides relevant information about a given service, including service class ID, service name, - /// applicable namespace identifier and protocol information, as well as a set of transport addresses at which the service listens. - /// - /// - /// - /// The WSAQUERYSET structure is used as part of the original namespace provider version 1 architecture available on Windows - /// 95 and later. A newer version 2 of the namespace architecture is available on Windows Vista and later. - /// - /// - /// 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. - /// - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/ns-winsock2-wsaquerysetw typedef struct _WSAQuerySetW { DWORD dwSize; - // LPWSTR lpszServiceInstanceName; LPGUID lpServiceClassId; LPWSAVERSION lpVersion; LPWSTR lpszComment; DWORD dwNameSpace; LPGUID - // lpNSProviderId; LPWSTR lpszContext; DWORD dwNumberOfProtocols; LPAFPROTOCOLS lpafpProtocols; LPWSTR lpszQueryString; DWORD - // dwNumberOfCsAddrs; LPCSADDR_INFO lpcsaBuffer; DWORD dwOutputFlags; LPBLOB lpBlob; } WSAQUERYSETW, *PWSAQUERYSETW, *LPWSAQUERYSETW; - [PInvokeData("winsock2.h", MSDNShortId = "6c81fbba-aaf4-49ca-ab79-b6fe5dfb0076")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] - public struct WSAQUERYSET - { - /// - /// Type: DWORD - /// - /// The size, in bytes, of the WSAQUERYSET structure. This member is used as a versioning mechanism since the size of the - /// WSAQUERYSET structure has changed on later versions of Windows. - /// - /// - public uint dwSize; - - /// - /// Type: LPTSTR - /// - /// A pointer to an optional NULL-terminated string that contains service name. The semantics for using wildcards within the - /// string are not defined, but can be supported by certain namespace providers. - /// - /// - [MarshalAs(UnmanagedType.LPTStr)] public string lpszServiceInstanceName; - - /// - /// Type: LPGUID - /// The GUID corresponding to the service class. This member is required to be set. - /// - public GuidPtr lpServiceClassId; - - /// - /// Type: LPWSAVERSION - /// - /// A pointer to an optional desired version number of the namespace provider. This member provides version comparison semantics - /// (that is, the version requested must match exactly, or version must be not less than the value supplied). - /// - /// - public IntPtr lpVersion; - - /// - /// Type: LPTSTR - /// This member is ignored for queries. - /// - [MarshalAs(UnmanagedType.LPTStr)] public string lpszComment; - - /// - /// Type: DWORD - /// - /// A namespace identifier that determines which namespace providers are queried. Passing a specific namespace identifier will - /// result in only namespace providers that support the specified namespace being queried. Specifying NS_ALL will result - /// in all installed and active namespace providers being queried. - /// - /// - /// Options for the dwNameSpace member are listed in the Winsock2.h include file. Several new namespace providers are - /// included with Windows Vista and later. Other namespace providers can be installed, so the following possible values are only - /// those commonly available. Many other values are possible. - /// - /// - /// - /// Value - /// Meaning - /// - /// - /// NS_ALL - /// All installed and active namespaces. - /// - /// - /// NS_BTH - /// The Bluetooth namespace. This namespace identifier is supported on Windows Vista and later. - /// - /// - /// NS_DNS - /// The domain name system (DNS) namespace. - /// - /// - /// NS_EMAIL - /// The email namespace. This namespace identifier is supported on Windows Vista and later. - /// - /// - /// NS_NLA - /// The network location awareness (NLA) namespace. This namespace identifier is supported on Windows XP and later. - /// - /// - /// NS_PNRPNAME - /// - /// The peer-to-peer name space for a specific peer name. This namespace identifier is supported on Windows Vista and later. - /// - /// - /// - /// NS_PNRPCLOUD - /// - /// The peer-to-peer name space for a collection of peer names. This namespace identifier is supported on Windows Vista and later. - /// - /// - /// - /// - public NS dwNameSpace; - - /// - /// Type: LPGUID - /// - /// A pointer to an optional GUID of a specific namespace provider to query in the case where multiple namespace providers are - /// registered under a single namespace such as NS_DNS. Passing the GUID for a specific namespace provider will result in - /// only the specified namespace provider being queried. The WSAEnumNameSpaceProviders and WSAEnumNameSpaceProvidersEx functions - /// can be called to retrieve the GUID for a namespace provider. - /// - /// - public GuidPtr lpNSProviderId; - - /// - /// Type: LPTSTR - /// A pointer to an optional starting point of the query in a hierarchical namespace. - /// - [MarshalAs(UnmanagedType.LPTStr)] public string lpszContext; - - /// - /// Type: DWORD - /// The size, in bytes, of the protocol constraint array. This member can be zero. - /// - public uint dwNumberOfProtocols; - - /// - /// Type: LPAFPROTOCOLS - /// A pointer to an optional array of AFPROTOCOLS structures. Only services that utilize these protocols will be returned. - /// - public IntPtr lpafpProtocols; - - /// - /// Type: LPTSTR - /// - /// A pointer to an optional NULL-terminated query string. 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. - /// - /// - [MarshalAs(UnmanagedType.LPTStr)] public string lpszQueryString; - - /// - /// Type: DWORD - /// This member is ignored for queries. - /// - public uint dwNumberOfCsAddrs; - - /// - /// Type: LPCSADDR_INFO - /// This member is ignored for queries. - /// - public IntPtr lpcsaBuffer; - - /// - /// Type: DWORD - /// This member is ignored for queries. - /// - public uint dwOutputFlags; - - /// - /// Type: LPBLOB - /// - /// An optional pointer to data that is used to query or set provider-specific namespace information. The format of this - /// information is specific to the namespace provider. - /// - /// - public IntPtr lpBlob; - - /// Initializes a new instance of the struct. - /// The name space. - public WSAQUERYSET(NS nameSpace) : this() - { - dwSize = (uint)Marshal.SizeOf(this); - dwNameSpace = nameSpace; - } - } - - /// - /// The WSASERVICECLASSINFO structure contains information about a specified service class. For each service class in Windows - /// Sockets 2, there is a single WSASERVICECLASSINFO structure. - /// - // https://docs.microsoft.com/en-us/windows/win32/api/winsock2/ns-winsock2-wsaserviceclassinfow typedef struct _WSAServiceClassInfoW - // { LPGUID lpServiceClassId; LPWSTR lpszServiceClassName; DWORD dwCount; LPWSANSCLASSINFOW lpClassInfos; } WSASERVICECLASSINFOW, - // *PWSASERVICECLASSINFOW, *LPWSASERVICECLASSINFOW; - [PInvokeData("winsock2.h", MSDNShortId = "02422c24-34a6-4e34-a795-66b0b687ac44")] - [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] - public struct WSASERVICECLASSINFO - { - /// Unique Identifier (GUID) for the service class. - public GuidPtr lpServiceClassId; - - /// Well known name associated with the service class. - [MarshalAs(UnmanagedType.LPTStr)] - public string lpszServiceClassName; - - /// Number of entries in lpClassInfos. - public uint dwCount; - - /// Array of WSANSCLASSINFO structures that contains information about the service class. - public IntPtr lpClassInfos; - - /// Marshaled array of WSANSCLASSINFO structures that contains information about the service class. - public WSANSCLASSINFO[] ClassInfos => lpClassInfos.ToArray((int)dwCount); - } - - /// Provides a for that is disposed using . - public class SafeWSAEVENT : SafeHANDLE, ISyncHandle - { - /// Initializes a new instance of the class and assigns an existing handle. - /// An object that represents the pre-existing handle to use. - /// - /// to reliably release the handle during the finalization phase; otherwise, (not recommended). - /// - public SafeWSAEVENT(IntPtr preexistingHandle, bool ownsHandle = true) : base(preexistingHandle, ownsHandle) { } - - /// Initializes a new instance of the class. - private SafeWSAEVENT() : base() { } - - /// Performs an implicit conversion from to . - /// The safe handle instance. - /// The result of the conversion. - public static implicit operator WSAEVENT(SafeWSAEVENT h) => h.handle; - - /// - protected override bool InternalReleaseHandle() => WSACloseEvent(handle); - } - - /// - /// A disposable class to manage initialization of the WSA library. See remarks for use. - /// - /// - /// - /// using (var wsa = SafeWSA.Initialize()) - /// { - /// // Call WSA functions... - /// } - /// - /// Or, if you must have a certain version of the library, use the InitDemandVersion static method. - /// - /// using (var wsa = SafeWSA.InitDemandVersion(Macros.MAKEWORD(1, 1))) - /// { - /// // Call WSA functions. - /// // The above call with throw a VersionNotFoundException if that version is not supported. - /// } - /// - /// - /// - public class SafeWSA : IDisposable - { - private WSADATA data; - - private SafeWSA() { } - - /// Initiates use of the Winsock DLL by a process. - /// The requested version of the WinSock library. - /// An object that holds the WinSock library while in scope. Upon disposal, WSACleanup is called. - public static SafeWSA Initialize(ushort wVersionRequired = 0x0202) - { - var ret = new SafeWSA(); - WSAStartup(wVersionRequired, out ret.data).ThrowIfFailed(); - return ret; - } - - /// - /// Initiates use of the Winsock DLL by a process and throws an exception if isn't available. - /// - /// The required version of the WinSock library. - /// An object that holds the WinSock library while in scope. Upon disposal, WSACleanup is called. - /// - public static SafeWSA DemandVersion(ushort wVersionRequired) - { - var ret = Initialize(wVersionRequired); - if (ret.Data.wVersion != wVersionRequired) - throw new VersionNotFoundException(); - return ret; - } - - /// Gets the WSADATA value returned by WSAStartup. - /// The data. - public WSADATA Data { get => data; private set => data = value; } - - void IDisposable.Dispose() => WSACleanup(); - } } } \ No newline at end of file