using System; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Security; namespace Vanara.PInvoke; public static partial class Ws2_32 { /// A WinSock2 result. Some functions can interpret the result from a simple failure (SOCKET_ERROR) to the actual error. [StructLayout(LayoutKind.Sequential, Pack = 4)] [PInvokeData("winsock2.h")] public struct WSRESULT : IComparable, IComparable, IEquatable, IEquatable, IEquatable, IConvertible, IErrorProvider { internal readonly int _value; /// Initializes a new instance of the structure. /// The raw WSRESULT value. public WSRESULT(int rawValue) => _value = rawValue; /// Gets a value indicating whether this is a failure (Severity bit 31 equals 1). /// true if failed; otherwise, false. public bool Failed => _value != 0; /// Gets a value indicating whether this is a success (Severity bit 31 equals 0). /// true if succeeded; otherwise, false. public bool Succeeded => _value == 0; /// Performs an explicit conversion from to . /// The value. /// The resulting instance from the conversion. public static explicit operator HRESULT(WSRESULT value) => value.ToHRESULT(); /// Performs an explicit conversion from to . /// The value. /// The resulting instance from the conversion. public static explicit operator Win32Error(WSRESULT value) => unchecked((uint)(value._value == SOCKET_ERROR ? GetLastError()._value : value._value)); /// Performs an explicit conversion from to . /// The value. /// The result of the conversion. public static explicit operator int(WSRESULT value) => value._value; /// Performs an explicit conversion from to . /// The value. /// The result of the conversion. public static explicit operator SocketError(WSRESULT value) => (SocketError)value._value; /// Performs an implicit conversion from to . /// The value. /// The result of the conversion. public static implicit operator WSRESULT(int value) => new(value); /// Performs an implicit conversion from to . /// The value. /// The result of the conversion. public static implicit operator WSRESULT(SocketError value) => new((int)value); /// Implements the operator !. /// The value. /// The result of the operator. public static bool operator !(WSRESULT value) => value.Failed; /// Implements the operator !=. /// The first . /// The second . /// The result of the operator. public static bool operator !=(WSRESULT hrLeft, WSRESULT hrRight) => !(hrLeft == hrRight); /// Implements the operator !=. /// The first . /// The second . /// The result of the operator. public static bool operator !=(WSRESULT hrLeft, int hrRight) => !(hrLeft == hrRight); /// Implements the operator ==. /// The first . /// The second . /// The result of the operator. public static bool operator ==(WSRESULT hrLeft, WSRESULT hrRight) => hrLeft.Equals(hrRight); /// Implements the operator ==. /// The first . /// The second . /// The result of the operator. public static bool operator ==(WSRESULT hrLeft, int hrRight) => hrLeft.Equals(hrRight); /// /// If the supplied raw WSRESULT value represents a failure, throw the associated with the optionally /// supplied message. /// /// The 32-bit raw WSRESULT value. /// The optional message to assign to the . [SecurityCritical, System.Diagnostics.DebuggerStepThrough] public static void ThrowIfFailed(int value, string message = null) => new WSRESULT(value).ThrowIfFailed(message); /// Throws the last error. /// The message. [SecurityCritical, System.Diagnostics.DebuggerStepThrough] public static void ThrowLastError(string message = null) => GetLastError().ThrowIfFailed(message); /// Throws the last error if the predicate delegate returns . /// The type of the value to evaluate. /// The value to check. /// The delegate which returns on failure. /// The message. /// The passed in on success. [SecurityCritical, System.Diagnostics.DebuggerStepThrough] public static T ThrowLastErrorIf(T value, Func valueIsFailure, string message = null) { if (valueIsFailure(value)) GetLastError().ThrowIfFailed(message); return value; } /// Throws the last error if the function returns . /// The value to check. /// The message. [SecurityCritical, System.Diagnostics.DebuggerStepThrough] public static bool ThrowLastErrorIfFalse(bool value, string message = null) => ThrowLastErrorIf(value, v => !v, message); /// Throws the last error if the value is an invalid handle. /// The SafeHandle to check. /// The message. [SecurityCritical, System.Diagnostics.DebuggerStepThrough] public static T ThrowLastErrorIfInvalid(T value, string message = null) where T : SafeHandle => ThrowLastErrorIf(value, v => v.IsInvalid, message); /// Compares the current object with another object of the same type. /// An object to compare with this object. /// /// A value that indicates the relative order of the objects being compared. The return value has the following /// meanings: Value Meaning Less than zero This object is less than the parameter.Zero This object is equal /// to . Greater than zero This object is greater than . /// public int CompareTo(WSRESULT other) => _value.CompareTo(other._value); /// /// Compares the current instance with another object of the same type and returns an integer that indicates whether the current /// instance precedes, follows, or occurs in the same position in the sort order as the other object. /// /// An object to compare with this instance. /// /// A value that indicates the relative order of the objects being compared. The return value has these meanings: Value Meaning Less /// than zero This instance precedes in the sort order. Zero This instance occurs in the same position in the /// sort order as . Greater than zero This instance follows in the sort order. /// public int CompareTo(object obj) => obj switch { WSRESULT r => CompareTo(r), int i => i.CompareTo(_value), SocketError e => e.CompareTo((SocketError)_value), IErrorProvider e => ToHRESULT().CompareTo(e.ToHRESULT()), _ => _value.CompareTo(obj) }; /// Indicates whether the current object is equal to an . /// An object to compare with this object. /// true if the current object is equal to the parameter; otherwise, false. public bool Equals(int other) => other == _value; /// Determines whether the specified , is equal to this instance. /// The to compare with this instance. /// true if the specified is equal to this instance; otherwise, false. public override bool Equals(object obj) => obj switch { null => false, WSRESULT r => Equals(r), int i => Equals(i), SocketError e => Equals(e), IErrorProvider e => ToHRESULT().Equals(e.ToHRESULT()), IConvertible c => Equals(c.ToInt32(null)), _ => base.Equals(obj) }; /// Indicates whether the current object is equal to an . /// An object to compare with this object. /// true if the current object is equal to the parameter; otherwise, false. public bool Equals(SocketError other) => (int)other == _value; /// Indicates whether the current object is equal to another object of the same type. /// An object to compare with this object. /// true if the current object is equal to the parameter; otherwise, false. public bool Equals(WSRESULT other) => other._value == _value; /// Gets the .NET associated with the WSRESULT value and optionally adds the supplied message. /// The optional message to assign to the . /// The associated or null if this WSRESULT is not a failure. [SecurityCritical, SecuritySafeCritical] public Exception GetException(string message = null) => _value switch { 0 => null, SOCKET_ERROR => new SocketException((int)GetLastError()), _ => new SocketException(_value) }; /// Returns a hash code for this instance. /// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table. public override int GetHashCode() => _value; /// Gets the last error. /// The last error. [SecurityCritical, System.Diagnostics.DebuggerStepThrough] public static WSRESULT GetLastError() => WSAGetLastError(); /// /// If this represents a failure, throw the associated with the optionally supplied message. /// /// The optional message to assign to the . [SecurityCritical, SecuritySafeCritical, System.Diagnostics.DebuggerStepThrough] public void ThrowIfFailed(string message = null) { Exception exception = GetException(message); if (exception is not null) throw exception; } /// Converts this error to an . /// An equivalent . public HRESULT ToHRESULT() => HRESULT.HRESULT_FROM_WIN32((Win32Error)this); /// Returns a that represents this instance. /// A that represents this instance. public override string ToString() => StaticFieldValueHash.TryGetFieldName(_value, out var err) ? err : ToHRESULT().ToString(); TypeCode IConvertible.GetTypeCode() => _value.GetTypeCode(); bool IConvertible.ToBoolean(IFormatProvider provider) => Succeeded; byte IConvertible.ToByte(IFormatProvider provider) => ((IConvertible)_value).ToByte(provider); char IConvertible.ToChar(IFormatProvider provider) => throw new NotSupportedException(); DateTime IConvertible.ToDateTime(IFormatProvider provider) => throw new NotSupportedException(); decimal IConvertible.ToDecimal(IFormatProvider provider) => ((IConvertible)_value).ToDecimal(provider); double IConvertible.ToDouble(IFormatProvider provider) => ((IConvertible)_value).ToDouble(provider); short IConvertible.ToInt16(IFormatProvider provider) => ((IConvertible)_value).ToInt16(provider); int IConvertible.ToInt32(IFormatProvider provider) => _value; long IConvertible.ToInt64(IFormatProvider provider) => ((IConvertible)_value).ToInt64(provider); sbyte IConvertible.ToSByte(IFormatProvider provider) => ((IConvertible)_value).ToSByte(provider); float IConvertible.ToSingle(IFormatProvider provider) => ((IConvertible)_value).ToSingle(provider); string IConvertible.ToString(IFormatProvider provider) => ToString(); object IConvertible.ToType(Type conversionType, IFormatProvider provider) => ((IConvertible)_value).ToType(conversionType, provider); ushort IConvertible.ToUInt16(IFormatProvider provider) => ((IConvertible)unchecked((uint)_value)).ToUInt16(provider); uint IConvertible.ToUInt32(IFormatProvider provider) => unchecked((uint)_value); ulong IConvertible.ToUInt64(IFormatProvider provider) => ((IConvertible)unchecked((uint)_value)).ToUInt64(provider); /// /// Specified event object handle is invalid. /// An application attempts to use an event object, but the specified handle is not valid. /// public const int WSA_INVALID_HANDLE = 6; /// /// Insufficient memory available. /// /// An application used a Windows Sockets function that directly maps to a Windows function. The Windows function is indicating a /// lack of required memory resources. /// /// public const int WSA_NOT_ENOUGH_MEMORY = 8; /// /// One or more parameters are invalid. /// /// An application used a Windows Sockets function which directly maps to a Windows function. The Windows function is indicating a /// problem with one or more parameters. /// /// public const int WSA_INVALID_PARAMETER = 87; /// /// Overlapped operation aborted. /// An overlapped operation was canceled due to the closure of the socket, or the execution of the SIO_FLUSH command in WSAIoctl. /// public const int WSA_OPERATION_ABORTED = 995; /// /// Overlapped I/O event object not in signaled state. /// /// The application has tried to determine the status of an overlapped operation which is not yet completed. Applications that use /// WSAGetOverlappedResult (with the fWait flag set to FALSE) in a polling mode to determine when an overlapped operation has /// completed, get this error code until the operation is complete. /// /// public const int WSA_IO_INCOMPLETE = 996; /// /// Overlapped operations will complete later. /// /// The application has initiated an overlapped operation that cannot be completed immediately. A completion indication will be given /// later when the operation has been completed. /// /// public const int WSA_IO_PENDING = 997; /// A blocking operation was interrupted by a call to WSACancelBlockingCall. public const int WSAEINTR = 0x00002714; /// The file handle supplied is not valid. public const int WSAEBADF = 0x00002719; /// An attempt was made to access a socket in a way forbidden by its access permissions. public const int WSAEACCES = 0x0000271D; /// The system detected an invalid pointer address in attempting to use a pointer argument in a call. public const int WSAEFAULT = 0x0000271E; /// An invalid argument was supplied. public const int WSAEINVAL = 0x00002726; /// Too many open sockets. public const int WSAEMFILE = 0x00002728; /// A nonblocking socket operation could not be completed immediately. public const int WSAEWOULDBLOCK = 0x00002733; /// A blocking operation is currently executing. public const int WSAEINPROGRESS = 0x00002734; /// An operation was attempted on a nonblocking socket that already had an operation in progress. public const int WSAEALREADY = 0x00002735; /// An operation was attempted on something that is not a socket. public const int WSAENOTSOCK = 0x00002736; /// A required address was omitted from an operation on a socket. public const int WSAEDESTADDRREQ = 0x00002737; /// A message sent on a datagram socket was larger than the internal message buffer or some other network limit, or the buffer used to receive a datagram into was smaller than the datagram itself. public const int WSAEMSGSIZE = 0x00002738; /// A protocol was specified in the socket function call that does not support the semantics of the socket type requested. public const int WSAEPROTOTYPE = 0x00002739; /// An unknown, invalid, or unsupported option or level was specified in a getsockopt or setsockopt call. public const int WSAENOPROTOOPT = 0x0000273A; /// The requested protocol has not been configured into the system, or no implementation for it exists. public const int WSAEPROTONOSUPPORT = 0x0000273B; /// The support for the specified socket type does not exist in this address family. public const int WSAESOCKTNOSUPPORT = 0x0000273C; /// The attempted operation is not supported for the type of object referenced. public const int WSAEOPNOTSUPP = 0x0000273D; /// The protocol family has not been configured into the system or no implementation for it exists. public const int WSAEPFNOSUPPORT = 0x0000273E; /// An address incompatible with the requested protocol was used. public const int WSAEAFNOSUPPORT = 0x0000273F; /// Only one usage of each socket address (protocol/network address/port) is normally permitted. public const int WSAEADDRINUSE = 0x00002740; /// The requested address is not valid in its context. public const int WSAEADDRNOTAVAIL = 0x00002741; /// A socket operation encountered a dead network. public const int WSAENETDOWN = 0x00002742; /// A socket operation was attempted to an unreachable network. public const int WSAENETUNREACH = 0x00002743; /// The connection has been broken due to keep-alive activity detecting a failure while the operation was in progress. public const int WSAENETRESET = 0x00002744; /// An established connection was aborted by the software in your host machine. public const int WSAECONNABORTED = 0x00002745; /// An existing connection was forcibly closed by the remote host. public const int WSAECONNRESET = 0x00002746; /// An operation on a socket could not be performed because the system lacked sufficient buffer space or because a queue was full. public const int WSAENOBUFS = 0x00002747; /// A connect request was made on an already connected socket. public const int WSAEISCONN = 0x00002748; /// A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied. public const int WSAENOTCONN = 0x00002749; /// A request to send or receive data was disallowed because the socket had already been shut down in that direction with a previous shutdown call. public const int WSAESHUTDOWN = 0x0000274A; /// Too many references to a kernel object. public const int WSAETOOMANYREFS = 0x0000274B; /// A connection attempt failed because the connected party did not properly respond after a period of time, or the established connection failed because the connected host failed to respond. public const int WSAETIMEDOUT = 0x0000274C; /// No connection could be made because the target machine actively refused it. public const int WSAECONNREFUSED = 0x0000274D; /// Cannot translate name. public const int WSAELOOP = 0x0000274E; /// Name or name component was too long. public const int WSAENAMETOOLONG = 0x0000274F; /// A socket operation failed because the destination host was down. public const int WSAEHOSTDOWN = 0x00002750; /// A socket operation was attempted to an unreachable host. public const int WSAEHOSTUNREACH = 0x00002751; /// Cannot remove a directory that is not empty. public const int WSAENOTEMPTY = 0x00002752; /// A Windows Sockets implementation might have a limit on the number of applications that can use it simultaneously. public const int WSAEPROCLIM = 0x00002753; /// Ran out of quota. public const int WSAEUSERS = 0x00002754; /// Ran out of disk quota. public const int WSAEDQUOT = 0x00002755; /// File handle reference is no longer available. public const int WSAESTALE = 0x00002756; /// Item is not available locally. public const int WSAEREMOTE = 0x00002757; /// WSAStartup cannot function at this time because the underlying system it uses to provide network services is currently unavailable. public const int WSASYSNOTREADY = 0x0000276B; /// The Windows Sockets version requested is not supported. public const int WSAVERNOTSUPPORTED = 0x0000276C; /// Either the application has not called WSAStartup, or WSAStartup failed. public const int WSANOTINITIALISED = 0x0000276D; /// Returned by WSARecv or WSARecvFrom to indicate that the remote party has initiated a graceful shutdown sequence. public const int WSAEDISCON = 0x00002775; /// No more results can be returned by WSALookupServiceNext. public const int WSAENOMORE = 0x00002776; /// A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled. public const int WSAECANCELLED = 0x00002777; /// The procedure call table is invalid. public const int WSAEINVALIDPROCTABLE = 0x00002778; /// The requested service provider is invalid. public const int WSAEINVALIDPROVIDER = 0x00002779; /// The requested service provider could not be loaded or initialized. public const int WSAEPROVIDERFAILEDINIT = 0x0000277A; /// A system call that should never fail has failed. public const int WSASYSCALLFAILURE = 0x0000277B; /// No such service is known. The service cannot be found in the specified namespace. public const int WSASERVICE_NOT_FOUND = 0x0000277C; /// The specified class was not found. public const int WSATYPE_NOT_FOUND = 0x0000277D; /// No more results can be returned by WSALookupServiceNext. public const int WSA_E_NO_MORE = 0x0000277E; /// A call to WSALookupServiceEnd was made while this call was still processing. The call has been canceled. public const int WSA_E_CANCELLED = 0x0000277F; /// A database query failed because it was actively refused. public const int WSAEREFUSED = 0x00002780; /// No such host is known. public const int WSAHOST_NOT_FOUND = 0x00002AF9; /// This is usually a temporary error during host name resolution and means that the local server did not receive a response from an authoritative server. public const int WSATRY_AGAIN = 0x00002AFA; /// A nonrecoverable error occurred during a database lookup. public const int WSANO_RECOVERY = 0x00002AFB; /// The requested name is valid, but no data of the requested type was found. public const int WSANO_DATA = 0x00002AFC; /// At least one reserve has arrived. public const int WSA_QOS_RECEIVERS = 0x00002AFD; /// At least one path has arrived. public const int WSA_QOS_SENDERS = 0x00002AFE; /// There are no senders. public const int WSA_QOS_NO_SENDERS = 0x00002AFF; /// There are no receivers. public const int WSA_QOS_NO_RECEIVERS = 0x00002B00; /// Reserve has been confirmed. public const int WSA_QOS_REQUEST_CONFIRMED = 0x00002B01; /// Error due to lack of resources. public const int WSA_QOS_ADMISSION_FAILURE = 0x00002B02; /// Rejected for administrative reasons - bad credentials. public const int WSA_QOS_POLICY_FAILURE = 0x00002B03; /// Unknown or conflicting style. public const int WSA_QOS_BAD_STYLE = 0x00002B04; /// There is a problem with some part of the filterspec or provider-specific buffer in general. public const int WSA_QOS_BAD_OBJECT = 0x00002B05; /// There is a problem with some part of the flowspec. public const int WSA_QOS_TRAFFIC_CTRL_ERROR = 0x00002B06; /// General quality of serve (QOS) error. public const int WSA_QOS_GENERIC_ERROR = 0x00002B07; /// An invalid or unrecognized service type was found in the flowspec. public const int WSA_QOS_ESERVICETYPE = 0x00002B08; /// An invalid or inconsistent flowspec was found in the QOS structure. public const int WSA_QOS_EFLOWSPEC = 0x00002B09; /// Invalid QOS provider-specific buffer. public const int WSA_QOS_EPROVSPECBUF = 0x00002B0A; /// An invalid QOS filter style was used. public const int WSA_QOS_EFILTERSTYLE = 0x00002B0B; /// An invalid QOS filter type was used. public const int WSA_QOS_EFILTERTYPE = 0x00002B0C; /// An incorrect number of QOS FILTERSPECs were specified in the FLOWDESCRIPTOR. public const int WSA_QOS_EFILTERCOUNT = 0x00002B0D; /// An object with an invalid ObjectLength field was specified in the QOS provider-specific buffer. public const int WSA_QOS_EOBJLENGTH = 0x00002B0E; /// An incorrect number of flow descriptors was specified in the QOS structure. public const int WSA_QOS_EFLOWCOUNT = 0x00002B0F; /// An unrecognized object was found in the QOS provider-specific buffer. public const int WSA_QOS_EUNKOWNPSOBJ = 0x00002B10; /// An invalid policy object was found in the QOS provider-specific buffer. public const int WSA_QOS_EPOLICYOBJ = 0x00002B11; /// An invalid QOS flow descriptor was found in the flow descriptor list. public const int WSA_QOS_EFLOWDESC = 0x00002B12; /// An invalid or inconsistent flowspec was found in the QOS provider-specific buffer. public const int WSA_QOS_EPSFLOWSPEC = 0x00002B13; /// An invalid FILTERSPEC was found in the QOS provider-specific buffer. public const int WSA_QOS_EPSFILTERSPEC = 0x00002B14; /// An invalid shape discard mode object was found in the QOS provider-specific buffer. public const int WSA_QOS_ESDMODEOBJ = 0x00002B15; /// An invalid shaping rate object was found in the QOS provider-specific buffer. public const int WSA_QOS_ESHAPERATEOBJ = 0x00002B16; /// A reserved policy element was found in the QOS provider-specific buffer. public const int WSA_QOS_RESERVED_PETYPE = 0x00002B17; } }