diff --git a/PInvoke/Ws2_32/MSWSock.cs b/PInvoke/Ws2_32/MSWSock.cs new file mode 100644 index 00000000..55be5c61 --- /dev/null +++ b/PInvoke/Ws2_32/MSWSock.cs @@ -0,0 +1,412 @@ +using System; +using System.Runtime.InteropServices; +using Vanara.InteropServices; + +namespace Vanara.PInvoke +{ + public static partial class Ws2_32 + { + /// GUID value used by SIO_GET_EXTENSION_FUNCTION_POINTER to get the LPFN_WSARECVMSG (WSARecvMsg) extension function. + public static readonly Guid WSAID_WSARECVMSG = new("{0xf689d7c8,0x6f1f,0x436b,{0x8a,0x53,0xe5,0x4f,0xe3,0x51,0xc3,0x22}}"); + + /// + /// + /// LPFN_WSARECVMSG is a function pointer type. You implement a matching WSARecvMsg callback function in your app. The + /// system uses your callback function to transmit to you in-memory data, or file data, over a connected socket. + /// + /// + /// Your WSARecvMsg callback function receives ancillary data/control information with a message, from connected and + /// unconnected sockets. + /// + /// + /// Note + /// This function is a Microsoft-specific extension to the Windows Sockets specification. + /// + /// + /// + /// Type: _In_ SOCKET + /// A descriptor that identifies the socket. + /// + /// + /// Type: _Inout_ LPWSAMSG + /// A pointer to a WSAMSG structure based on the Posix.1g specification for the msghdr structure. + /// + /// + /// Type: _Out_opt_ LPDWORD + /// + /// A pointer to a DWORD containing number of bytes received by this call if the WSARecvMsg operation completes immediately. + /// + /// + /// To avoid potentially erroneous results, pass NULL for this parameter if the lpOverlapped parameter is not NULL . + /// This parameter can be NULL only if the lpOverlapped parameter is not NULL. + /// + /// + /// + /// Type: _Inout_opt_ LPWSAOVERLAPPED + /// A pointer to a WSAOVERLAPPED structure. Ignored for non-overlapped structures. + /// + /// + /// Type: _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE + /// A pointer to the completion routine called when the receive operation completes. Ignored for non-overlapped structures. + /// + /// + /// + /// If no error occurs and the receive operation has completed immediately, WSARecvMsg returns zero. In this case, the + /// completion routine will have already been scheduled to be called once the calling thread is in the alertable state. Otherwise, a + /// value of SOCKET_ERROR is returned, and a specific error code can be retrieved by calling WSAGetLastError. The error code + /// WSA_IO_PENDING indicates that the overlapped operation has been successfully initiated and that completion will be + /// indicated at a later time. + /// + /// + /// Any other error code indicates that the operation was not successfully initiated and no completion indication will occur if an + /// overlapped operation was requested. + /// + /// + /// + /// Error code + /// Meaning + /// + /// + /// WSAECONNRESET + /// + /// For a UDP datagram socket, this error would indicate that a previous send operation resulted in an ICMP "Port Unreachable" message. + /// + /// + /// + /// WSAEFAULT + /// + /// The lpBuffers, lpFlags, lpFrom, lpNumberOfBytesRecvd, lpFromlen, lpOverlapped, or + /// lpCompletionRoutine parameter is not totally contained in a valid part of the user address space: the lpFrom buffer + /// was too small to accommodate the peer address. This error is also returned if a name member of the WSAMSG structure + /// pointed to by the lpMsg parameter was a NULL pointer and the namelen member of the WSAMSG structure + /// was not set to zero. This error is also returned if a Control.buf member of the WSAMSG structure pointed to by the + /// lpMsg parameter was a NULL pointer and the Control.len member of the WSAMSG structure was not set to zero. + /// + /// + /// + /// WSAEINPROGRESS + /// A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function. + /// + /// + /// WSAEINTR + /// A blocking Windows Socket 1.1 call was canceled through WSACancelBlockingCall. + /// + /// + /// WSAEINVAL + /// The socket has not been bound (with bind, for example). + /// + /// + /// WSAEMSGSIZE + /// + /// The message was too large to fit into the specified buffer and (for unreliable protocols only) any trailing portion of the + /// message that did not fit into the buffer has been discarded. + /// + /// + /// + /// WSAENETDOWN + /// The network subsystem has failed. + /// + /// + /// WSAENETRESET + /// For a datagram socket, this error indicates that the time to live has expired. + /// + /// + /// WSAENOTCONN + /// The socket is not connected (connection-oriented sockets only). + /// + /// + /// WSAETIMEDOUT + /// + /// The socket timed out. This error is returned if the socket had a wait timeout specified using the SO_RCVTIMEO socket + /// option and the timeout was exceeded. + /// + /// + /// + /// WSAEOPNOTSUPP + /// + /// The socket operation is not supported. This error is returned if the dwFlags member of the WSAMSG structure pointed + /// to by the lpMsg parameter includes the MSG_PEEK control flag on a non-datagram socket. + /// + /// + /// + /// WSAEWOULDBLOCK + /// + /// Windows NT: Overlapped sockets: There are too many outstanding overlapped I/O requests. Non-overlapped sockets: The socket + /// is marked as nonblocking and the receive operation cannot be completed immediately. + /// + /// + /// + /// WSANOTINITIALISED + /// A successful WSAStartup call must occur before using this function. + /// + /// + /// WSA_IO_PENDING + /// An overlapped operation was successfully initiated and completion will be indicated at a later time. + /// + /// + /// WSA_OPERATION_ABORTED + /// The overlapped operation has been canceled due to the closure of the socket. + /// + /// + /// + /// + /// + /// The WSARecvMsg function can be used in place of the WSARecv and WSARecvFrom functions to receive data and + /// optional control information from connected and unconnected sockets. The WSARecvMsg function can only be used with + /// datagrams and raw sockets. The socket descriptor in the s parameter must be opened with the socket type set to SOCK_DGRAM + /// or SOCK_RAW. + /// + /// + /// Note The function pointer for the WSARecvMsg function must be obtained at run time by making a call to the + /// WSAIoctl function with the SIO_GET_EXTENSION_FUNCTION_POINTER opcode specified. The input buffer passed to the + /// WSAIoctl function must contain WSAID_WSARECVMSG, a globally unique identifier (GUID) whose value identifies the + /// WSARecvMsg extension function. On success, the output returned by the WSAIoctl function contains a pointer to the + /// WSARecvMsg function. The WSAID_WSARECVMSG GUID is defined in the Mswsock.h header file. + /// + /// + /// The dwFlags member of the WSAMSG structure pointed to by the lpMsg parameter may only contain the MSG_PEEK + /// control flag on input. + /// + /// + /// Overlapped sockets are created with a WSASocket function call that has the WSA_FLAG_OVERLAPPED flag set. For + /// overlapped sockets, receiving information uses overlapped I/O unless both the lpOverlapped and lpCompletionRoutine parameters are + /// NULL. The socket is treated as a non-overlapped socket when both the lpOverlapped and lpCompletionRoutine parameters are NULL. + /// + /// + /// A completion indication occurs with overlapped sockets. Once the buffer or buffers have been consumed by the transport, a + /// completion routine is triggered or an event object is set. If the operation does not complete immediately, the final completion + /// status is retrieved through the completion routine or by calling the WSAGetOverlappedResult function. + /// + /// + /// For overlapped sockets, WSARecvMsg is used to post one or more buffers into which incoming data will be placed as it + /// becomes available, after which the application-specified completion indication (invocation of the completion routine or setting + /// of an event object) occurs. If the operation does not complete immediately, the final completion status is retrieved through the + /// completion routine or the WSAGetOverlappedResult function. + /// + /// + /// For non-overlapped sockets, the blocking semantics are identical to that of the standard recv function and the + /// lpOverlapped and lpCompletionRoutine parameters are ignored. Any data that has already been received and buffered by the + /// transport will be copied into the specified user buffers. In the case of a blocking socket with no data currently having been + /// received and buffered by the transport, the call will block until data is received. Windows Sockets 2 does not define any + /// standard blocking time-out mechanism for this function. For protocols acting as byte-stream protocols the stack tries to return + /// as much data as possible subject to the available buffer space and amount of received data available. However, receipt of a + /// single byte is sufficient to unblock the caller. There is no guarantee that more than a single byte will be returned. For + /// protocols acting as message-oriented, a full message is required to unblock the caller. + /// + /// Note The SO_RCVTIMEO socket option applies only to blocking sockets. + /// + /// The buffers are filled in the order in which they appear in the array pointed to by the lpBuffers member of the + /// WSAMSG structure pointed to by the lpMsg parameter, and the buffers are packed so that no holes are created. + /// + /// + /// If this function is completed in an overlapped manner, it is the Winsock service provider's responsibility to capture this + /// WSABUF structure before returning from this call. This enables applications to build stack-based WSABUF arrays + /// pointed to by the lpBuffers member of the WSAMSG structure pointed to by the lpMsg parameter. + /// + /// + /// For message-oriented sockets (a socket type of SOCK_DGRAM or SOCK_RAW), an incoming message is placed into the + /// buffers up to the total size of the buffers, and the completion indication occurs for overlapped sockets. If the message is + /// larger than the buffers, the buffers are filled with the first part of the message and the excess data is lost, and + /// WSARecvMsg generates the error WSAEMSGSIZE. + /// + /// + /// When the IP_PKTINFO socket option is enabled on an IPv4 socket of type SOCK_DGRAM or SOCK_RAW, the + /// WSARecvMsg function returns packet information in the WSAMSG structure pointed to by the lpMsg parameter. One of + /// the control data objects in the returned WSAMSG structure will contain an in_pktinfo structure used to store + /// received packet address information. + /// + /// + /// For datagrams received over IPv4, the Control member of the WSAMSG structure received will contain a WSABUF + /// structure that contains a WSACMSGHDR structure. The cmsg_level member of this WSACMSGHDR structure would + /// contain IPPROTO_IP, the cmsg_type member of this structure would contain IP_PKTINFO, and the + /// cmsg_data member would contain an in_pktinfo structure used to store received IPv4 packet address information. The + /// IPv4 address in the in_pktinfo structure is the IPv4 address from which the packet was received. + /// + /// + /// When the IPV6_PKTINFO socket option is enabled on an IPv6 socket of type SOCK_DGRAM or SOCK_RAW, the + /// WSARecvMsg function returns packet information in the WSAMSG structure pointed to by the lpMsg parameter. One of + /// the control data objects in the returned WSAMSG structure will contain an in6_pktinfo structure used to store + /// received packet address information. + /// + /// + /// For datagrams received over IPv6, the Control member of the WSAMSG structure received will contain a WSABUF + /// structure that contains a WSACMSGHDR structure. The cmsg_level member of this WSACMSGHDR structure would + /// contain IPPROTO_IPV6, the cmsg_type member of this structure would contain IPV6_PKTINFO, and the + /// cmsg_data member would contain an in6_pktinfo structure used to store received IPv6 packet address information. The + /// IPv6 address in the in6_pktinfo structure is the IPv6 address from which the packet was received. + /// + /// + /// For a dual-stack datagram socket, if an application requires the WSARecvMsg function to return packet information in a + /// WSAMSG structure for datagrams received over IPv4, then IP_PKTINFO socket option must be set to true on the socket. If + /// only the IPV6_PKTINFO option is set to true on the socket, packet information will be provided for datagrams received over IPv6 + /// but may not be provided for datagrams received over IPv4. + /// + /// Note that the Ws2ipdef.h header file is automatically included in Ws2tcpip.h, and should never be used directly. + /// + /// Note All I/O initiated by a given thread is canceled when that thread exits. For overlapped sockets, pending asynchronous + /// operations can fail if the thread is closed before the operations complete. For more information, see ExitThread. + /// + /// Windows Phone 8: This function is supported for Windows Phone Store apps on Windows Phone 8 and later. + /// + /// Windows 8.1 and Windows Server 2012 R2: This function is supported for Windows Store apps on Windows 8.1, Windows + /// Server 2012 R2, and later. + /// + /// dwFlags + /// + /// On input, the dwFlags member of the WSAMSG structure pointed to by the lpMsg parameter can be used to influence the + /// behavior of the function invocation beyond the socket options specified for the associated socket. That is, the semantics of this + /// function are determined by the socket options and the dwFlags member of the WSAMSG structure. The only possible + /// input value for the dwFlags member of the WSAMSG structure pointed to by the lpMsg parameter is MSG_PEEK. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// MSG_PEEK + /// + /// Peek at the incoming data. The data is copied into the buffer, but is not removed from the input queue. This flag is valid only + /// for non-overlapped sockets. + /// + /// + /// + /// The possible values for dwFlags member on input are defined in the Winsock2.h header file. + /// + /// On output, the dwFlags member of the WSAMSG structure pointed to by the lpMsg parameter may return a combination of + /// any of the following values. + /// + /// + /// + /// Value + /// Meaning + /// + /// + /// MSG_BCAST + /// The datagram was received as a link-layer broadcast or with a destination IP address that is a broadcast address. + /// + /// + /// MSG_CTRUNC + /// The control (ancillary) data was truncated. More control data was present than the process allocated room for. + /// + /// + /// MSG_MCAST + /// The datagram was received with a destination IP address that is a multicast address. + /// + /// + /// MSG_TRUNC + /// The datagram was truncated. More data was present than the process allocated room for. + /// + /// + /// + /// On the Microsoft Windows Software Development Kit (SDK) released for Windows Vista and later, the organization of header files + /// has changed and the possible values for the dwFlags member on output are defined in the Ws2def.h header file which is + /// automatically included by the Winsock2.h header file. + /// + /// + /// On versions of the Platform Software Development Kit (SDK) for Windows Server 2003 and earlier, the possible values for the + /// dwFlags member on output are defined in the Mswsock.h header file. + /// + /// + /// Note When issuing a blocking Winsock call such as WSARecvMsg with the lpOverlapped parameter set to NULL, Winsock + /// may need to wait for a network event before the call can complete. Winsock performs an alertable wait in this situation, which + /// can be interrupted by an asynchronous procedure call (APC) scheduled on the same thread. Issuing another blocking Winsock call + /// inside an APC that interrupted an ongoing blocking Winsock call on the same thread will lead to undefined behavior, and must + /// never be attempted by Winsock clients. + /// + /// Overlapped Socket I/O + /// + /// If an overlapped operation completes immediately, WSARecvMsg returns a value of zero and the lpNumberOfBytesRecvd + /// parameter is updated with the number of bytes received and the flag bits indicated by the lpFlags parameter are also updated. If + /// the overlapped operation is successfully initiated and will complete later, WSARecvMsg returns SOCKET_ERROR and + /// indicates error code WSA_IO_PENDING. In this case, lpNumberOfBytesRecvd is not updated. When the overlapped operation completes, + /// the amount of data transferred is indicated either through the cbTransferred parameter in the completion routine (if specified), + /// or through the lpcbTransfer parameter in WSAGetOverlappedResult. Flag values are obtained by examining the lpdwFlags + /// parameter of WSAGetOverlappedResult. + /// + /// + /// The WSARecvMsg function using overlapped I/O can be called from within the completion routine of a previous + /// WSARecv, WSARecvFrom, WSARecvMsg, WSASend, WSASendMsg, or WSASendTo function. For a + /// given socket, I/O completion routines will not be nested. This permits time-sensitive data transmissions to occur entirely within + /// a preemptive context. + /// + /// + /// The lpOverlapped parameter must be valid for the duration of the overlapped operation. If multiple I/O operations are + /// simultaneously outstanding, each must reference a separate WSAOVERLAPPED structure. + /// + /// + /// If the lpCompletionRoutine parameter is NULL, the hEvent parameter of lpOverlapped is signaled when the overlapped + /// operation completes if it contains a valid event object handle. An application can use WSAWaitForMultipleEvents or + /// WSAGetOverlappedResult to wait or poll on the event object. + /// + /// + /// If lpCompletionRoutine is not NULL, the hEvent parameter is ignored and can be used by the application to pass context + /// information to the completion routine. A caller that passes a non- NULL lpCompletionRoutine and later calls + /// WSAGetOverlappedResult for the same overlapped I/O request may not set the fWait parameter for that invocation of + /// WSAGetOverlappedResult to TRUE. In this case the usage of the hEvent parameter is undefined, and attempting to wait + /// on the hEvent parameter would produce unpredictable results. + /// + /// + /// The completion routine follows the same rules as stipulated for Windows file I/O completion routines. The completion routine will + /// not be invoked until the thread is in an alertable wait state such as can occur when the function WSAWaitForMultipleEvents + /// with the fAlertable parameter set to TRUE is invoked. + /// + /// The prototype of the completion routine is as follows: + /// + /// void CALLBACK CompletionRoutine( IN DWORD dwError, IN DWORD cbTransferred, IN LPWSAOVERLAPPED lpOverlapped, IN DWORD dwFlags ); + /// + /// + /// The CompletionRoutine is a placeholder for an application-defined or library-defined function name. The dwError parameter + /// specifies the completion status for the overlapped operation as indicated by the lpOverlapped parameter. The cbTransferred + /// parameter specifies the number of bytes received. The dwFlags parameter contains information that is also returned in + /// dwFlags member of the WSAMSG structure pointed to by the lpMsg parameter if the receive operation had completed + /// immediately. The CompletionRoutine function does not return a value. + /// + /// + /// Returning from this function allows invocation of another pending completion routine for this socket. When using + /// WSAWaitForMultipleEvents, all waiting completion routines are called before the alertable thread's wait is satisfied with + /// a return code of WSA_IO_COMPLETION. The completion routines can be called in any order, not necessarily in the same order + /// the overlapped operations are completed. However, the posted buffers are guaranteed to be filled in the same order in which they + /// are specified. + /// + /// + /// If you are using I/O completion ports, be aware that the order of calls made to WSARecvMsg is also the order in which the + /// buffers are populated. The WSARecvMsg function should not be called on the same socket simultaneously from different + /// threads, because it can result in an unpredictable buffer order. + /// + /// + // https://docs.microsoft.com/en-us/windows/win32/api/mswsock/nc-mswsock-lpfn_wsarecvmsg + // LPFN_WSARECVMSG LpfnWsarecvmsg; INT LpfnWsarecvmsg( SOCKET s, LPWSAMSG lpMsg, LPDWORD lpdwNumberOfBytesRecvd, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine ) {...} + [UnmanagedFunctionPointer(CallingConvention.StdCall)] + [PInvokeData("mswsock.h", MSDNShortId = "NC:mswsock.LPFN_WSARECVMSG")] + public delegate int LPFN_WSARECVMSG(SOCKET s, ref WSAMSG lpMsg, out uint lpdwNumberOfBytesRecvd, ref WSAOVERLAPPED lpOverlapped, [In, Optional] LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine); + + /* + AcceptEx function + GetAcceptExSockaddrs function + LPFN_CONNECTEX callback function + LPFN_DISCONNECTEX callback function + LPFN_RIOCLOSECOMPLETIONQUEUE callback function + LPFN_RIOCREATECOMPLETIONQUEUE callback function + LPFN_RIOCREATEREQUESTQUEUE callback function + LPFN_RIODEQUEUECOMPLETION callback function + LPFN_RIODEREGISTERBUFFER callback function + LPFN_RIONOTIFY callback function + LPFN_RIORECEIVE callback function + LPFN_RIORECEIVEEX callback function + LPFN_RIOREGISTERBUFFER callback function + LPFN_RIORESIZECOMPLETIONQUEUE callback function + LPFN_RIORESIZEREQUESTQUEUE callback function + LPFN_RIOSEND callback function + LPFN_RIOSENDEX callback function + LPFN_TRANSMITPACKETS callback function + RIO_EXTENSION_FUNCTION_TABLE structure + RIO_NOTIFICATION_COMPLETION structure + RIO_NOTIFICATION_COMPLETION_TYPE enumeration + TRANSMIT_FILE_BUFFERS structure + TRANSMIT_PACKETS_ELEMENT structure + TransmitFile function + WSARecvEx function + */ + } +} \ No newline at end of file