diff --git a/PInvoke/Ws2_32/WinSock2.WSA.cs b/PInvoke/Ws2_32/WinSock2.WSA.cs index 8e3f26c8..078b843f 100644 --- a/PInvoke/Ws2_32/WinSock2.WSA.cs +++ b/PInvoke/Ws2_32/WinSock2.WSA.cs @@ -1,6 +1,7 @@ #pragma warning disable IDE1006 // Naming Styles using System; +using System.Data; using System.Runtime.InteropServices; using System.Text; using Vanara.Extensions; @@ -779,7 +780,7 @@ namespace Vanara.PInvoke // lpdwAddressStringLength ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error WSAAddressToString([In] SOCKADDR lpsaAddress, uint dwAddressLength, in WSAPROTOCOL_INFO lpProtocolInfo, StringBuilder lpszAddressString, ref uint lpdwAddressStringLength); /// /// @@ -885,7 +886,7 @@ namespace Vanara.PInvoke // lpdwAddressStringLength ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error 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. @@ -2172,7 +2173,7 @@ namespace Vanara.PInvoke // u_int wMsg, long lEvent ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error 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. @@ -2232,7 +2233,7 @@ namespace Vanara.PInvoke // hAsyncTaskHandle ); [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winsock.h", MSDNShortId = "0e53eccf-ef85-43ec-a02c-12896471a7a9")] - public static extern int WSACancelAsyncRequest(HANDLE hAsyncTaskHandle); + public static extern Win32Error WSACancelAsyncRequest(HANDLE hAsyncTaskHandle); /// The WSACleanup function terminates use of the Winsock 2 DLL (Ws2_32.dll). /// @@ -2310,7 +2311,7 @@ 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)] [PInvokeData("winsock.h", MSDNShortId = "72b7cc3e-be34-41e7-acbf-61742149ec8b")] - public static extern int WSACleanup(); + public static extern Win32Error WSACleanup(); /// The WSACloseEvent function closes an open event object handle. /// Object handle identifying the open event. @@ -2623,7 +2624,7 @@ namespace Vanara.PInvoke // sockaddr *name, int namelen, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error WSAConnect(SOCKET s, [In] SOCKADDR name, int namelen, [In, Optional] IntPtr lpCallerData, [Out, Optional] IntPtr lpCalleeData, [Optional] IntPtr lpSQOS, [Optional] IntPtr lpGQOS); /// @@ -3163,7 +3164,7 @@ namespace Vanara.PInvoke // SOCKET s, DWORD dwProcessId, LPWSAPROTOCOL_INFOA lpProtocolInfo ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error WSADuplicateSocket(SOCKET s, uint dwProcessId, out WSAPROTOCOL_INFO lpProtocolInfo); /// The WSAEnumNameSpaceProviders function retrieves information on available namespace providers. /// @@ -3935,7 +3936,7 @@ namespace Vanara.PInvoke // WSAEVENT hEventObject, long lNetworkEvents ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error 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. @@ -4246,7 +4247,7 @@ namespace Vanara.PInvoke // lpServiceClassInfo ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error 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 @@ -4311,7 +4312,7 @@ namespace Vanara.PInvoke // WSAGetServiceClassNameByClassIdA( LPGUID lpServiceClassId, LPSTR lpszServiceClassName, LPDWORD lpdwBufferLength ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error 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. @@ -4373,7 +4374,7 @@ namespace Vanara.PInvoke // hostlong, OUT u_long *lpnetlong ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error 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. @@ -4434,7 +4435,7 @@ namespace Vanara.PInvoke // hostshort, OUT u_short *lpnetshort ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error 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 @@ -4501,7 +4502,7 @@ namespace Vanara.PInvoke // WSAInstallServiceClassA( LPWSASERVICECLASSINFOA lpServiceClassInfo ); [DllImport(Lib.Ws2_32, SetLastError = true, CharSet = CharSet.Auto)] [PInvokeData("winsock2.h", MSDNShortId = "06760319-aeeb-4ad7-b77a-01efea7ed904")] - public static extern int WSAInstallServiceClass(in WSASERVICECLASSINFO lpServiceClassInfo); + public static extern Win32Error WSAInstallServiceClass(in WSASERVICECLASSINFO lpServiceClassInfo); /// The WSAIoctl function controls the mode of a socket. /// A descriptor identifying a socket. @@ -4740,7 +4741,7 @@ namespace Vanara.PInvoke // LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error 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 WSAJoinLeaf function joins a leaf node into a multipoint session, exchanges connect data, and specifies needed @@ -5255,7 +5256,7 @@ namespace Vanara.PInvoke // LPWSAQUERYSETA lpqsRestrictions, DWORD dwControlFlags, LPHANDLE lphLookup ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error WSALookupServiceBegin(in WSAQUERYSET lpqsRestrictions, LUP dwControlFlags, out HANDLE lphLookup); /// /// @@ -5304,7 +5305,7 @@ namespace Vanara.PInvoke // HANDLE hLookup ); [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "f9d2ac54-a818-464d-918e-80ebb5b1b106")] - public static extern int WSALookupServiceEnd(HANDLE hLookup); + public static extern Win32Error WSALookupServiceEnd(HANDLE hLookup); /// /// @@ -5590,7 +5591,7 @@ namespace Vanara.PInvoke // HANDLE hLookup, DWORD dwControlFlags, LPDWORD lpdwBufferLength, LPWSAQUERYSETA lpqsResults ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error 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. @@ -5722,7 +5723,7 @@ namespace Vanara.PInvoke // LPWSACOMPLETION lpCompletion ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error 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. @@ -5784,7 +5785,7 @@ namespace Vanara.PInvoke // u_long *lphostlong ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error 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. @@ -5845,7 +5846,7 @@ namespace Vanara.PInvoke // u_short *lphostshort ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error WSANtohs(SOCKET s, ushort netshort, out ushort lphostshort); /// The WSAPoll function determines status of one or more sockets. /// @@ -6039,7 +6040,7 @@ namespace Vanara.PInvoke // fds, INT timeout ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error WSAPoll([In, Out, MarshalAs(UnmanagedType.LPArray)] WSAPOLLFD[] fdArray, uint fds, int timeout); /// The WSAProviderConfigChange function notifies the application when the provider configuration is changed. /// @@ -6123,7 +6124,7 @@ namespace Vanara.PInvoke // lpCompletionRoutine ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error 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. @@ -6516,7 +6517,7 @@ namespace Vanara.PInvoke // LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error 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); /// @@ -6611,7 +6612,7 @@ namespace Vanara.PInvoke // LPWSABUF lpInboundDisconnectData ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error WSARecvDisconnect(SOCKET s, [In, Out, Optional] IntPtr lpInboundDisconnectData); /// The WSARecvFrom function receives a datagram and stores the source address. /// A descriptor identifying a socket. @@ -6911,7 +6912,7 @@ namespace Vanara.PInvoke // lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error 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. @@ -6958,7 +6959,7 @@ namespace Vanara.PInvoke // LPGUID lpServiceClassId ); [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "7d72f727-cca9-4a07-beb4-d64f23c1f0c1")] - public static extern int WSARemoveServiceClass(in Guid lpServiceClassId); + public static extern Win32Error 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. @@ -7302,7 +7303,7 @@ namespace Vanara.PInvoke // lpCompletionRoutine ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error 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); /// @@ -7386,7 +7387,7 @@ namespace Vanara.PInvoke // LPWSABUF lpOutboundDisconnectData ); [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "c05fc719-e35a-4194-ac01-a294b19ccce9")] - public static extern int WSASendDisconnect(SOCKET s, in WSABUF lpOutboundDisconnectData); + public static extern Win32Error WSASendDisconnect(SOCKET s, in WSABUF lpOutboundDisconnectData); /// /// The WSASendDisconnect function initiates termination of the connection for the socket and sends disconnect data. @@ -7469,7 +7470,7 @@ namespace Vanara.PInvoke // LPWSABUF lpOutboundDisconnectData ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error 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. @@ -7776,7 +7777,7 @@ namespace Vanara.PInvoke // lpCompletionRoutine ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error 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. @@ -8082,7 +8083,7 @@ namespace Vanara.PInvoke // lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error 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); @@ -8439,7 +8440,7 @@ namespace Vanara.PInvoke // lpqsRegInfo, WSAESETSERVICEOP essoperation, DWORD dwControlFlags ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error WSASetService(in WSAQUERYSET lpqsRegInfo, WSAESETSERVICEOP essoperation, ServiceInstallFlags dwControlFlags); /// The WSASocket function creates a socket that is bound to a specific transport-service provider. /// @@ -8998,6 +8999,563 @@ namespace Vanara.PInvoke [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); + /// The WSASocket function creates a socket that is bound to a specific transport-service provider. + /// + /// The address family specification. Possible values for the address family are defined in the Winsock2.h header file. + /// + /// On the Windows SDK released for Windows Vista and later, the organization of header files has changed and the possible values + /// for the address family are defined in the Ws2def.h header file. Note that the Ws2def.h header file is automatically included in + /// Winsock2.h, and should never be used directly. + /// + /// + /// The values currently supported are AF_INET or AF_INET6, which are the Internet address family formats for IPv4 and IPv6. Other + /// options for address family (AF_NETBIOS for use with NetBIOS, for example) are supported if a Windows Sockets service provider + /// for the address family is installed. Note that the values for the AF_ address family and PF_ protocol family constants are + /// identical (for example, AF_INET and PF_INET), so either constant can be used. + /// + /// The table below lists common values for address family although many other values are possible. + /// + /// + /// Af + /// Meaning + /// + /// + /// AF_UNSPEC 0 + /// The address family is unspecified. + /// + /// + /// AF_INET 2 + /// The Internet Protocol version 4 (IPv4) address family. + /// + /// + /// AF_IPX 6 + /// + /// The IPX/SPX address family. This address family is only supported if the NWLink IPX/SPX NetBIOS Compatible Transport protocol is + /// installed. This address family is not supported on Windows Vista and later. + /// + /// + /// + /// AF_APPLETALK 16 + /// + /// The AppleTalk address family. This address family is only supported if the AppleTalk protocol is installed. This address family + /// is not supported on Windows Vista and later. + /// + /// + /// + /// AF_NETBIOS 17 + /// + /// The NetBIOS address family. This address family is only supported if the Windows Sockets provider for NetBIOS is installed. The + /// Windows Sockets provider for NetBIOS is supported on 32-bit versions of Windows. This provider is installed by default on 32-bit + /// versions of Windows. The Windows Sockets provider for NetBIOS is not supported on 64-bit versions of windows including Windows + /// 7, Windows Server 2008, Windows Vista, Windows Server 2003, or Windows XP. The Windows Sockets provider for NetBIOS only + /// supports sockets where the type parameter is set to SOCK_DGRAM. The Windows Sockets provider for NetBIOS is not directly related + /// to the NetBIOS programming interface. The NetBIOS programming interface is not supported on Windows Vista, Windows Server 2008, + /// and later. + /// + /// + /// + /// AF_INET6 23 + /// The Internet Protocol version 6 (IPv6) address family. + /// + /// + /// AF_IRDA 26 + /// + /// The Infrared Data Association (IrDA) address family. This address family is only supported if the computer has an infrared port + /// and driver installed. + /// + /// + /// + /// AF_BTH 32 + /// + /// The Bluetooth address family. This address family is supported on Windows XP with SP2 or later if the computer has a Bluetooth + /// adapter and driver installed. + /// + /// + /// + /// + /// + /// The type specification for the new socket. + /// Possible values for the socket type are defined in the Winsock2.h header file. + /// The following table lists the possible values for the type parameter supported for Windows Sockets 2: + /// + /// + /// Type + /// Meaning + /// + /// + /// SOCK_STREAM 1 + /// + /// A socket type that provides sequenced, reliable, two-way, connection-based byte streams with an OOB data transmission mechanism. + /// This socket type uses the Transmission Control Protocol (TCP) for the Internet address family (AF_INET or AF_INET6). + /// + /// + /// + /// SOCK_DGRAM 2 + /// + /// A socket type that supports datagrams, which are connectionless, unreliable buffers of a fixed (typically small) maximum length. + /// This socket type uses the User Datagram Protocol (UDP) for the Internet address family (AF_INET or AF_INET6). + /// + /// + /// + /// SOCK_RAW 3 + /// + /// A socket type that provides a raw socket that allows an application to manipulate the next upper-layer protocol header. To + /// manipulate the IPv4 header, the IP_HDRINCL socket option must be set on the socket. To manipulate the IPv6 header, the + /// IPV6_HDRINCL socket option must be set on the socket. + /// + /// + /// + /// SOCK_RDM 4 + /// + /// A socket type that provides a reliable message datagram. An example of this type is the Pragmatic General Multicast (PGM) + /// multicast protocol implementation in Windows, often referred to as reliable multicast programming. This type value is only + /// supported if the Reliable Multicast Protocol is installed. + /// + /// + /// + /// SOCK_SEQPACKET 5 + /// A socket type that provides a pseudo-stream packet based on datagrams. + /// + /// + /// + /// In Windows Sockets 2, new socket types were introduced. An application can dynamically discover the attributes of each available + /// transport protocol through the WSAEnumProtocols function. So an application can determine the possible socket type and protocol + /// options for an address family and use this information when specifying this parameter. Socket type definitions in the Winsock2.h + /// and Ws2def.h header files will be periodically updated as new socket types, address families, and protocols are defined. + /// + /// In Windows Sockets 1.1, the only possible socket types are SOCK_DGRAM and SOCK_STREAM. + /// + /// + /// + /// The protocol to be used. The possible options for the protocol parameter are specific to the address family and socket type + /// specified. Possible values for the protocol are defined are defined in the Winsock2.h and Wsrm.h header files. + /// + /// + /// On the Windows SDK released for Windows Vista and later,, the organization of header files has changed and this parameter can be + /// one of the values from the IPPROTO enumeration type defined in the Ws2def.h header file. Note that the Ws2def.h header + /// file is automatically included in Winsock2.h, and should never be used directly. + /// + /// + /// If a value of 0 is specified, the caller does not wish to specify a protocol and the service provider will choose the protocol + /// to use. + /// + /// + /// When the af parameter is AF_INET or AF_INET6 and the type is SOCK_RAW, the value specified for the protocol is set in the + /// protocol field of the IPv6 or IPv4 packet header. + /// + /// The table below lists common values for the protocol although many other values are possible. + /// + /// + /// protocol + /// Meaning + /// + /// + /// IPPROTO_ICMP 1 + /// + /// The Internet Control Message Protocol (ICMP). This is a possible value when the af parameter is AF_UNSPEC, AF_INET, or AF_INET6 + /// and the type parameter is SOCK_RAW or unspecified. This protocol value is supported on Windows XP and later. + /// + /// + /// + /// IPPROTO_IGMP 2 + /// + /// The Internet Group Management Protocol (IGMP). This is a possible value when the af parameter is AF_UNSPEC, AF_INET, or AF_INET6 + /// and the type parameter is SOCK_RAW or unspecified. This protocol value is supported on Windows XP and later. + /// + /// + /// + /// BTHPROTO_RFCOMM 3 + /// + /// The Bluetooth Radio Frequency Communications (Bluetooth RFCOMM) protocol. This is a possible value when the af parameter is + /// AF_BTH and the type parameter is SOCK_STREAM. This protocol value is supported on Windows XP with SP2 or later. + /// + /// + /// + /// IPPROTO_TCP 6 + /// + /// The Transmission Control Protocol (TCP). This is a possible value when the af parameter is AF_INET or AF_INET6 and the type + /// parameter is SOCK_STREAM. + /// + /// + /// + /// IPPROTO_UDP 17 + /// + /// The User Datagram Protocol (UDP). This is a possible value when the af parameter is AF_INET or AF_INET6 and the type parameter + /// is SOCK_DGRAM. + /// + /// + /// + /// IPPROTO_ICMPV6 58 + /// + /// The Internet Control Message Protocol Version 6 (ICMPv6). This is a possible value when the af parameter is AF_UNSPEC, AF_INET, + /// or AF_INET6 and the type parameter is SOCK_RAW or unspecified. This protocol value is supported on Windows XP and later. + /// + /// + /// + /// IPPROTO_RM 113 + /// + /// The PGM protocol for reliable multicast. This is a possible value when the af parameter is AF_INET and the type parameter is + /// SOCK_RDM. On the Windows SDK released for Windows Vista and later, this protocol is also called IPPROTO_PGM. This protocol value + /// is only supported if the Reliable Multicast Protocol is installed. + /// + /// + /// + /// + /// + /// A pointer to a WSAPROTOCOL_INFO structure that defines the characteristics of the socket to be created. If this parameter is not + /// NULL, the socket will be bound to the provider associated with the indicated WSAPROTOCOL_INFO structure. + /// + /// + /// An existing socket group ID or an appropriate action to take when creating a new socket and a new socket group. + /// + /// If g is an existing socket group ID, join the new socket to this socket group, provided all the requirements set by this group + /// are met. + /// + /// If g is not an existing socket group ID, then the following values are possible. + /// + /// + /// g + /// Meaning + /// + /// + /// 0 + /// No group operation is performed. + /// + /// + /// SG_UNCONSTRAINED_GROUP 0x01 + /// + /// Create an unconstrained socket group and have the new socket be the first member. For an unconstrained group, Winsock does not + /// constrain all sockets in the socket group to have been created with the same value for the type and protocol parameters. + /// + /// + /// + /// SG_CONSTRAINED_GROUP 0x02 + /// + /// Create a constrained socket group and have the new socket be the first member. For a contrained socket group, Winsock constrains + /// all sockets in the socket group to have been created with the same value for the type and protocol parameters. A constrained + /// socket group may consist only of connection-oriented sockets, and requires that connections on all grouped sockets be to the + /// same address on the same host. + /// + /// + /// + /// + /// Note The SG_UNCONSTRAINED_GROUP and SG_CONSTRAINED_GROUP constants are not currently defined in a public header file. + /// + /// + /// + /// A set of flags used to specify additional socket attributes. + /// A combination of these flags may be set, although some combinations are not allowed. + /// + /// + /// Value + /// Meaning + /// + /// + /// WSA_FLAG_OVERLAPPED 0x01 + /// + /// 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_MULTIPOINT_C_ROOT 0x02 + /// + /// 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_LEAF 0x04 + /// + /// 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_D_ROOT 0x08 + /// + /// 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_LEAF 0x10 + /// + /// 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_ACCESS_SYSTEM_SECURITY 0x40 + /// + /// 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_NO_HANDLE_INHERIT 0x80 + /// + /// 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 + /// + /// + /// + /// + /// Important For multipoint sockets, only one of WSA_FLAG_MULTIPOINT_C_ROOT or WSA_FLAG_MULTIPOINT_C_LEAF + /// flags can be specified, and only one of WSA_FLAG_MULTIPOINT_D_ROOT or WSA_FLAG_MULTIPOINT_D_LEAF flags can be + /// specified. Refer to Multipoint and Multicast Semantics for additional information. + /// + /// + /// + /// + /// If no error occurs, WSASocket returns a descriptor referencing the new socket. Otherwise, a value of INVALID_SOCKET is + /// returned, and a specific error code can be retrieved by calling WSAGetLastError. + /// + /// Note This error code description is Microsoft-specific. + /// + /// + /// Error code + /// Meaning + /// + /// + /// WSANOTINITIALISED + /// A successful WSAStartup call must occur before using this function. + /// + /// + /// WSAENETDOWN + /// The network subsystem has failed. + /// + /// + /// WSAEAFNOSUPPORT + /// The specified address family is not supported. + /// + /// + /// WSAEFAULT + /// The lpProtocolInfo parameter is not in a valid part of the process address space. + /// + /// + /// WSAEINPROGRESS + /// A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function. + /// + /// + /// WSAEINVAL + /// This value is true for any of the following conditions. + /// + /// + /// WSAEINVALIDPROVIDER + /// The service provider returned a version other than 2.2. + /// + /// + /// WSAEINVALIDPROCTABLE + /// The service provider returned an invalid or incomplete procedure table to the WSPStartup. + /// + /// + /// WSAEMFILE + /// No more socket descriptors are available. + /// + /// + /// WSAENOBUFS + /// No buffer space is available. The socket cannot be created. + /// + /// + /// WSAEPROTONOSUPPORT + /// The specified protocol is not supported. + /// + /// + /// WSAEPROTOTYPE + /// The specified protocol is the wrong type for this socket. + /// + /// + /// WSAEPROVIDERFAILEDINIT + /// + /// The service provider failed to initialize. This error is returned if a layered service provider (LSP) or namespace provider was + /// improperly installed or the provider fails to operate correctly. + /// + /// + /// + /// WSAESOCKTNOSUPPORT + /// The specified socket type is not supported in this address family. + /// + /// + /// + /// + /// + /// The WSASocket function causes a socket descriptor and any related resources to be allocated and associated with a + /// transport-service provider. Most sockets should be created with the WSA_FLAG_OVERLAPPED attribute set in the dwFlags + /// parameter. A socket created with this attribute supports the use of overlapped I/O operations which provide higher performance. + /// By default, a socket created with the WSASocket function will not have this overlapped attribute set. In contrast, the + /// socket function creates a socket that supports overlapped I/O operations as the default behavior. + /// + /// + /// If the lpProtocolInfo parameter is NULL, Winsock will utilize the first available transport-service provider that + /// supports the requested combination of address family, socket type and protocol specified in the af, type, and protocol parameters. + /// + /// + /// If the lpProtocolInfo parameter is not NULL, the socket will be bound to the provider associated with the indicated + /// WSAPROTOCOL_INFO structure. In this instance, the application can supply the manifest constant FROM_PROTOCOL_INFO as the + /// value for any of af, type, or protocol parameters. This indicates that the corresponding values from the indicated + /// WSAPROTOCOL_INFO structure ( iAddressFamily, iSocketType, iProtocol) are to be assumed. In any case, + /// the values specified for af, type, and protocol are passed unmodified to the transport-service provider. + /// + /// + /// When selecting a protocol and its supporting service provider based on af, type, and protocol, this procedure will only choose a + /// base protocol or a protocol chain, not a protocol layer by itself. Unchained protocol layers are not considered to have partial + /// matches on type or af, either. That is, they do not lead to an error code of WSAEAFNOSUPPORT or WSAEPROTONOSUPPORT, if no + /// suitable protocol is found. + /// + /// + /// Note The manifest constant AF_UNSPEC continues to be defined in the header file but its use is strongly + /// discouraged, as this can cause ambiguity in interpreting the value of the protocol parameter. + /// + /// + /// Applications are encouraged to use AF_INET6 for the af parameter and create a dual-mode socket that can be used with both + /// IPv4 and IPv6. + /// + /// + /// If a socket is created using the WSASocket function, then the dwFlags parameter must have the WSA_FLAG_OVERLAPPED + /// attribute set for the SO_RCVTIMEO or SO_SNDTIMEO socket options to function properly. Otherwise the timeout never + /// takes effect on the socket. + /// + /// + /// Connection-oriented sockets such as SOCK_STREAM provide full-duplex connections, and must be in a connected state before + /// any data can be sent or received on them. A connection to a specified socket is established with a connect or WSAConnect + /// function call. Once connected, data can be transferred using send/WSASend and recv/WSARecv calls. When a session has been + /// completed, the closesocket function should be called to release the resources associated with the socket. For + /// connection-oriented sockets, the shutdown function should be called to stop data transfer on the socket before calling the + /// closesocket function. + /// + /// + /// The communications protocols used to implement a reliable, connection-oriented socket ensure that data is not lost or + /// duplicated. If data for which the peer protocol has buffer space cannot be successfully transmitted within a reasonable length + /// of time, the connection is considered broken and subsequent calls will fail with the error code set to WSAETIMEDOUT. + /// + /// + /// Connectionless, message-oriented sockets allow sending and receiving of datagrams to and from arbitrary peers using + /// sendto/WSASendTo and recvfrom/WSARecvFrom. If such a socket is connected to a specific peer, datagrams can be sent to that peer + /// using send/WSASend and can be received from (only) this peer using recv/WSARecv. + /// + /// + /// Support for sockets with type SOCK_RAW is not required, but service providers are encouraged to support raw sockets + /// whenever possible. + /// + /// + /// The WSASocket function can be used to create a socket to be used by a service so that if another socket tries to bind to + /// the same port used by the service, and audit record is generared. To enable this option, an application would need to do the following: + /// + /// + /// + /// + /// Call the AdjustTokenPrivileges function to enable the SE_SECURITY_NAME privilege in the access token for the process. + /// This privilege is required to set the ACCESS_SYSTEM_SECURITY access rights on the security descriptor for an object. + /// + /// + /// + /// + /// Call the WSASocket function to create a socket with dwFlag with the WSA_FLAG_ACCESS_SYSTEM_SECURITY option set. + /// The WSASocket function will fail if the AdjustTokenPrivileges function is not called first to enable the + /// SE_SECURITY_NAME privilege needed for this operation. + /// + /// + /// + /// + /// Call the SetSecurityInfo function to set a security descriptor with a System Access Control List (SACL) on the socket. The + /// socket handle returned by the WSASocket function is passed in the handle parameter. If the function succeeds, this will + /// set the the ACCESS_SYSTEM_SECURITY access right on the security descriptor for the socket. + /// + /// + /// + /// + /// Call the bindfunction to bind the socket to a specific port. If the bind function succeeds, then an audit entry is + /// generated if another socket tries to bind to the same port. + /// + /// + /// + /// + /// Call the AdjustTokenPrivileges function to remove the SE_SECURITY_NAME privilege in the access token for the process, + /// since this is no longer needed. + /// + /// + /// + /// + /// For more information on ACCESS_SYSTEM_SECURITY, see SACL Access Right and Audit Generation in the Authorization documentation. + /// + /// Socket Groups + /// + /// WinSock 2 introduced the notion of a socket group as a means for an application, or cooperating set of applications, to indicate + /// to an underlying service provider that a particular set of sockets are related and that the group thus formed has certain + /// attributes. Group attributes include relative priorities of the individual sockets within the group and a group quality of + /// service specification. + /// + /// + /// Applications that need to exchange multimedia streams over the network are an example where being able to establish a specific + /// relationship among a set of sockets could be beneficial. It is up to the transport on how to treat socket groups. + /// + /// + /// The WSASocket and WSAAccept functions can be used to explicitly create and join a socket group when creating a new + /// socket. The socket group ID for a socket can be retrieved by using the getsockopt function with level parameter set to + /// SOL_SOCKET and the optname parameter set to SO_GROUP_ID. A socket group and its associated socket group ID remain valid + /// until the last socket belonging to this socket group is closed. Socket group IDs are unique across all processes for a given + /// service provider. A socket group of zero indicates that the socket is not member of a socket group. + /// + /// + /// The relative group priority of a socket group can be accessed by using the getsockopt function with the level parameter set to + /// SOL_SOCKET and the optname parameter set to SO_GROUP_PRIORITY. The relative group priority of a socket group can be set + /// by using setsockopt with the level parameter set to SOL_SOCKET and the optname parameter set to SO_GROUP_PRIORITY. + /// + /// + /// The Winsock provider included with Windows allows the creation of socket groups and it enforces the SG_CONSTRAINED_GROUP. All + /// sockets in a constrained socket group must be created with the same value for the type and protocol parameters. A constrained + /// socket group may consist only of connection-oriented sockets, and requires that connections on all grouped sockets be to the + /// same address on the same host. This is the only restriction applied to a socket group by the Winsock provider included with + /// Windows. The socket group priority is not currently used by the Winsock provider or the TCP/IP stack included with Windows. + /// + /// Example Code + /// The following example demonstrates the use of the WSASocket function. + /// + /// Windows Phone 8: The WSASocketW function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// + /// Windows 8.1 and Windows Server 2012 R2: The WSASocketW function is supported for Windows Store apps on + /// Windows 8.1, Windows Server 2012 R2, and later. + /// + /// + // 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)] + [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); + /// The WSAStartup function initiates use of the Winsock DLL by a process. /// TBD /// A pointer to the WSADATA data structure that is to receive details of the Windows Sockets implementation. @@ -9255,7 +9813,7 @@ namespace Vanara.PInvoke // LPWSADATA lpWSAData ); [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winsock.h", MSDNShortId = "08299592-867c-491d-9769-d16602133659")] - public static extern int WSAStartup(ushort wVersionRequired, out WSADATA lpWSAData); + public static extern Win32Error WSAStartup(ushort wVersionRequired, out WSADATA lpWSAData); /// /// The WSAStringToAddress function converts a network address in its standard text presentation form into its numeric binary @@ -9336,7 +9894,7 @@ namespace Vanara.PInvoke // AddressString, INT AddressFamily, LPWSAPROTOCOL_INFOA lpProtocolInfo, LPSOCKADDR lpAddress, LPINT lpAddressLength ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error 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 @@ -9417,7 +9975,7 @@ namespace Vanara.PInvoke // AddressString, INT AddressFamily, LPWSAPROTOCOL_INFOA lpProtocolInfo, LPSOCKADDR lpAddress, LPINT lpAddressLength ); [DllImport(Lib.Ws2_32, SetLastError = true, 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 Win32Error WSAStringToAddress([MarshalAs(UnmanagedType.LPTStr)] string AddressString, ADDRESS_FAMILY AddressFamily, [In, Optional] IntPtr lpProtocolInfo, [Out] SOCKADDR lpAddress, ref int lpAddressLength); /// /// The WSAWaitForMultipleEvents function returns when one or all of the specified event objects are in the signaled state, @@ -9578,7 +10136,7 @@ namespace Vanara.PInvoke // WSAWaitForMultipleEvents( DWORD cEvents, const WSAEVENT *lphEvents, BOOL fWaitAll, DWORD dwTimeout, BOOL fAlertable ); [DllImport(Lib.Ws2_32, SetLastError = true, ExactSpelling = true)] [PInvokeData("winsock2.h", MSDNShortId = "7a978ade-6323-455b-b655-f372f4bcadc8")] - public static extern uint WSAWaitForMultipleEvents(uint cEvents, [In, MarshalAs(UnmanagedType.LPArray)] WSAEVENT[] lphEvents, [MarshalAs(UnmanagedType.Bool)] bool fWaitAll, uint dwTimeout, [MarshalAs(UnmanagedType.Bool)] bool fAlertable); + 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 @@ -10251,5 +10809,62 @@ namespace Vanara.PInvoke /// 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/ws2def.cs b/PInvoke/Ws2_32/ws2def.cs index f2fa65ee..f4de079d 100644 --- a/PInvoke/Ws2_32/ws2def.cs +++ b/PInvoke/Ws2_32/ws2def.cs @@ -1,4 +1,5 @@ using System; +using System.Net; using System.Runtime.InteropServices; using Vanara.Extensions; using Vanara.InteropServices; @@ -1317,6 +1318,54 @@ namespace Vanara.PInvoke /// A padding of an additional 112 bytes that brings the total size of the SOCKADDR_STORAGE structure to 128 bytes. [MarshalAs(UnmanagedType.ByValArray, SizeConst = 112)] public byte[] __ss_pad2; + + /// Performs an explicit conversion from to . + /// The address. + /// The resulting instance from the conversion. + public static explicit operator SOCKADDR_STORAGE(in SOCKADDR_IN6 addr) + { + using var mem = SafeHGlobalHandle.CreateFromStructure(addr); + mem.Size = Marshal.SizeOf(typeof(SOCKADDR_STORAGE)); + return mem.ToStructure(); + } + /// Performs an explicit conversion from to . + /// The address. + /// The resulting instance from the conversion. + public static explicit operator SOCKADDR_STORAGE(in SOCKADDR_IN addr) + { + using var mem = SafeHGlobalHandle.CreateFromStructure(addr); + mem.Size = Marshal.SizeOf(typeof(SOCKADDR_STORAGE)); + return mem.ToStructure(); + } + + /// Performs an explicit conversion from to . + /// The address. + /// The resulting instance from the conversion. + public static explicit operator SOCKADDR_STORAGE(SOCKADDR addr) + { + using var mem = new SafeHGlobalHandle(addr.GetAddressBytes()); + mem.Size = Marshal.SizeOf(typeof(SOCKADDR_STORAGE)); + return mem.ToStructure(); + } + + /// Performs an explicit conversion from to . + /// The address. + /// The resulting instance from the conversion. + public static explicit operator SOCKADDR_STORAGE(IPAddress addr) + { + using var mem = new SafeHGlobalHandle(addr.GetAddressBytes()); + mem.Size = Marshal.SizeOf(typeof(SOCKADDR_STORAGE)); + return mem.ToStructure(); + } + + /// + /// Performs an explicit conversion from to . + /// + /// The addr. + /// + /// The resulting instance from the conversion. + /// + public static explicit operator SOCKADDR(SOCKADDR_STORAGE addr) => SOCKADDR.CreateFromStructure(addr); } } } \ No newline at end of file diff --git a/PInvoke/Ws2_32/ws2tcpip.cs b/PInvoke/Ws2_32/ws2tcpip.cs index 21ad6cb3..311ba37b 100644 --- a/PInvoke/Ws2_32/ws2tcpip.cs +++ b/PInvoke/Ws2_32/ws2tcpip.cs @@ -1419,7 +1419,7 @@ namespace Vanara.PInvoke // https://docs.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-getipv4sourcefilter int getipv4sourcefilter( SOCKET // Socket, IN_ADDR Interface, IN_ADDR Group, MULTICAST_MODE_TYPE *FilterMode, ULONG *SourceCount, IN_ADDR *SourceList ); [PInvokeData("ws2tcpip.h", MSDNShortId = "17D35D24-C419-4787-AB93-E6B1B6B13807")] - public static int getipv4sourcefilter(SOCKET Socket, IN_ADDR Interface, IN_ADDR Group, out MULTICAST_MODE_TYPE FilterMode, ref int SourceCount, IN_ADDR[] SourceList) + public static Win32Error getipv4sourcefilter(SOCKET Socket, IN_ADDR Interface, IN_ADDR Group, out MULTICAST_MODE_TYPE FilterMode, ref int SourceCount, IN_ADDR[] SourceList) { FilterMode = MULTICAST_MODE_TYPE.MCAST_INCLUDE; @@ -1709,7 +1709,7 @@ namespace Vanara.PInvoke // Interface, const SOCKADDR *Group, int GroupLength, MULTICAST_MODE_TYPE *FilterMode, ULONG *SourceCount, SOCKADDR_STORAGE // *SourceList ); [PInvokeData("ws2tcpip.h", MSDNShortId = "2CA84000-F114-439D-BEDE-9990044C7785")] - public static int getsourcefilter(SOCKET Socket, uint Interface, [In] SOCKADDR Group, int GroupLength, out MULTICAST_MODE_TYPE FilterMode, ref int SourceCount, SOCKADDR_STORAGE[] SourceList) + public static Win32Error getsourcefilter(SOCKET Socket, uint Interface, [In] SOCKADDR Group, int GroupLength, out MULTICAST_MODE_TYPE FilterMode, ref int SourceCount, SOCKADDR_STORAGE[] SourceList) { FilterMode = MULTICAST_MODE_TYPE.MCAST_INCLUDE; @@ -3281,7 +3281,7 @@ namespace Vanara.PInvoke // https://docs.microsoft.com/en-us/windows/win32/api/ws2tcpip/nf-ws2tcpip-setipv4sourcefilter int setipv4sourcefilter( SOCKET // Socket, IN_ADDR Interface, IN_ADDR Group, MULTICAST_MODE_TYPE FilterMode, ULONG SourceCount, const IN_ADDR *SourceList ); [PInvokeData("ws2tcpip.h", MSDNShortId = "C296D050-9195-42B5-8EBE-C6004F2DA855")] - public static int setipv4sourcefilter(SOCKET Socket, IN_ADDR Interface, IN_ADDR Group, MULTICAST_MODE_TYPE FilterMode, uint SourceCount, IN_ADDR[] SourceList) + public static Win32Error setipv4sourcefilter(SOCKET Socket, IN_ADDR Interface, IN_ADDR Group, MULTICAST_MODE_TYPE FilterMode, uint SourceCount, IN_ADDR[] SourceList) { if (SourceCount > SourceList.Length) { @@ -3345,7 +3345,7 @@ namespace Vanara.PInvoke // Interface, const SOCKADDR *Group, int GroupLength, MULTICAST_MODE_TYPE FilterMode, ULONG SourceCount, const SOCKADDR_STORAGE // *SourceList ); [PInvokeData("ws2tcpip.h", MSDNShortId = "320455F3-FDFB-46C6-9F26-3C60064A2CB0")] - public static int setsourcefilter(SOCKET Socket, uint Interface, [In] SOCKADDR Group, int GroupLength, MULTICAST_MODE_TYPE FilterMode, uint SourceCount, SOCKADDR_STORAGE[] SourceList) + public static Win32Error setsourcefilter(SOCKET Socket, uint Interface, [In] SOCKADDR Group, int GroupLength, MULTICAST_MODE_TYPE FilterMode, uint SourceCount, SOCKADDR_STORAGE[] SourceList) { if (SourceCount > SourceList.Length || GroupLength > Group.Size) { diff --git a/UnitTests/PInvoke/Ws2_32/Ws2_32.csproj b/UnitTests/PInvoke/Ws2_32/Ws2_32.csproj index b7ebfb7a..ce692b72 100644 --- a/UnitTests/PInvoke/Ws2_32/Ws2_32.csproj +++ b/UnitTests/PInvoke/Ws2_32/Ws2_32.csproj @@ -46,6 +46,10 @@ {241f73ee-9298-45c9-b869-a045dff94c03} Vanara.Core + + {842d436f-598c-47d7-b5aa-12399f8ccfe9} + Vanara.PInvoke.Kernel32 + {a5e519e9-feba-4fe3-93a5-b8269bef72f4} Vanara.PInvoke.Shared