Sample Code
windows driver samples/ Windows Filtering Platform Sample/ C++/ lib/ HelperFunctions_WinSock.cpp/
//////////////////////////////////////////////////////////////////////////////////////////////////// // // Copyright (c) 2012 Microsoft Corporation. All Rights Reserved. // // Module Name: // HelperFunctions_WinSock.cpp // // Abstract: // This module contains functions for assisting in operations pertaining to Windows Sockets. // // Author: // Dusty Harper (DHarper) // // Revision History: // // [ Month ][Day] [Year] - [Revision]-[ Comments ] // May 01, 2010 - 1.0 - Creation // //////////////////////////////////////////////////////////////////////////////////////////////////// #include "HelperFunctions_Include.h" /// . /** @helper_function="HlprWinSockCleanup" Purpose: Terminates use of the Winsock DLL for the process's use. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS741549.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockCleanup() { UINT32 status = NO_ERROR; status = WSACleanup(); if(status != NO_ERROR) { status = WSAGetLastError(); HlprLogError(L"HlprWinSockCleanup : WSACleanup() [status: %#x]", status); } return status; } /** @helper_function="HlprWinSockInitialize" Purpose: Initializes use of the Winsock DLL for the process's use. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS742213.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockInitialize() { UINT32 status = NO_ERROR; UINT16 versionRequested = MAKEWORD(2, 2); WSADATA wsaData = {0}; status = WSAStartup(versionRequested, &wsaData); if(status != NO_ERROR) HlprLogError(L"HlprWinSockInitialize : WSAStartup() [status: %#x]", status); return status; } /** @helper_function="HlprWinSockDestroyWSAEvent" Purpose: Free a WSAEvent. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS741551.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockDestroyWSAEvent(_Inout_ WSAEVENT* pWSAEvent) { ASSERT(pWSAEvent); UINT32 status = NO_ERROR; if(!WSACloseEvent(*pWSAEvent)) { status = WSAGetLastError(); HlprLogError(L"HlprWinSockDestroyWSAEvent : WSACloseEvent() [status: %#x]", status); } else *pWSAEvent = WSA_INVALID_EVENT; return status; } /** @helper_function="HlprWinSockSetWSAEvent" Purpose: Set a WSAEvent to signaled. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS742208.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockSetWSAEvent(_In_ WSAEVENT wsaEvent) { UINT32 status = NO_ERROR; if(!WSASetEvent(wsaEvent)) { status = WSAGetLastError(); HlprLogError(L"HlprWinSockSetWSAEvent : WSASetEvent() [status: %#x]", status); } return status; } /** @helper_function="HlprWinSockCreateWSAEvent" Purpose: Create a WSAEvent. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS741561.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockCreateWSAEvent(_Inout_ WSAEVENT* pWSAEvent) { ASSERT(pWSAEvent); UINT32 status = NO_ERROR; *pWSAEvent = WSACreateEvent(); if(*pWSAEvent == WSA_INVALID_EVENT) { status = WSAGetLastError(); HlprLogError(L"HlprWinSockCreateWSAEvent : WSACreateEvent() [status: %#x]", status); } return status; } /** @helper_function="HlprWinSockDestroySocket" Purpose: Destroy a socket gracefully. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS740481.aspx <br> HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS737582.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockDestroySocket(_Inout_ SOCKET* pSocket) { ASSERT(pSocket); UINT32 status = NO_ERROR; if(*pSocket != INVALID_SOCKET) { status = shutdown(*pSocket, SD_BOTH); if(status != NO_ERROR) { status = WSAGetLastError(); HlprLogError(L"HlprWinSockDestroySocket : shutdown() [status: %#x]", status); HLPR_BAIL; } status = closesocket(*pSocket); if(status != NO_ERROR) { status = WSAGetLastError(); HlprLogError(L"HlprWinSockDestroySocket : shutdown() [status: %#x]", status); HLPR_BAIL; } *pSocket = INVALID_SOCKET; } HLPR_BAIL_LABEL: return status; } /** @helper_function="HlprWinSockCreateSocket" Purpose: Create a new socket. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS742212.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockCreateSocket(_In_ SOCKADDR_STORAGE* pSockAddrStorage, _In_ UINT8 protocol, _Inout_ SOCKET* pSocket) { ASSERT(pSockAddrStorage); ASSERT(pSocket); UINT32 status = NO_ERROR; UINT32 type = SOCK_RAW; if(protocol == IPPROTO_TCP) type = SOCK_STREAM; else if(protocol == IPPROTO_UDP) type = SOCK_DGRAM; *pSocket = WSASocket(pSockAddrStorage->ss_family, type, protocol, 0, 0, WSA_FLAG_OVERLAPPED); if(*pSocket == INVALID_SOCKET) { status = WSAGetLastError(); HlprLogError(L"HlprWinSockCreateSocket : WSASocket() [status:%#x]", status); } return status; } /** @helper_function="HlprWinSockSetAbortiveDisconnect" Purpose: Set the linger socket option to FALSE. <br> <br> Notes: This function needs to be called prior to HlprWinSockDestroySocket for stream sockets that get a WSAECONNRESET. <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS740476.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockSetAbortiveDisconnect(_In_ SOCKET abortedSocket) { ASSERT(abortedSocket != INVALID_SOCKET); UINT32 status = NO_ERROR; LINGER linger = {0}; linger.l_onoff = TRUE; linger.l_linger = 0; status = setsockopt(abortedSocket, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(LINGER)); if(status != NO_ERROR) { status = WSAGetLastError(); HlprLogError(L"HlprWinSockSetAbortiveDisconnect : setsockopt() [status: %#x]", status); } return status; } /** @helper_function="HlprWinSockSetSocketReceiveTimeout" Purpose: Specify a timeout for blocking receive calls. <br> <br> Notes: This function needs to be called prior to binding the socket. <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS740476.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockSetSocketReceiveTimeout(_In_ SOCKET receivingSocket, _In_ UINT32 timeout) /* 5000 */ { ASSERT(receivingSocket != INVALID_SOCKET); UINT32 status = NO_ERROR; status = setsockopt(receivingSocket, SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(UINT32)); if(status != NO_ERROR) { status = WSAGetLastError(); HlprLogError(L"HlprWinSockSetSocketReceiveTimeout : setsockopt() [status: %#x]", status); } return status; } /** @helper_function="HlprWinSockSetSocketSendTimeout" Purpose: Specify a timeout for blocking send calls. <br> <br> Notes: This function needs to be called prior to binding the socket. <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS740476.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockSetSocketSendTimeout(_In_ SOCKET sendingSocket, _In_ UINT32 timeout) /* 5000 */ { ASSERT(sendingSocket != INVALID_SOCKET); UINT32 status = NO_ERROR; status = setsockopt(sendingSocket, SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(UINT32)); if(status != NO_ERROR) { status = WSAGetLastError(); HlprLogError(L"HlprWinSockSetSocketSendTimeout : setsockopt() [status: %#x]", status); } return status; } /** @helper_function="HlprWinSockSetSocketNonBlocking" Purpose: Enable non-blocking mode on the socket. <br> <br> Notes: This function needs to be called prior to binding the socket. <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS741621.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockSetSocketNonBlocking(_In_ SOCKET unboundSocket) { ASSERT(unboundSocket != INVALID_SOCKET); UINT32 status = NO_ERROR; UINT32 isNonBlockingSocket = TRUE; UINT32 bytesReturned = 0; status = WSAIoctl(unboundSocket, FIONBIO, &isNonBlockingSocket, sizeof(UINT32), 0, 0, (LPDWORD)&bytesReturned, 0, 0); if(status != NO_ERROR) { status = WSAGetLastError(); HlprLogError(L"HlprWinSockSetSocketNonBlocking : WSAIoctl() [status: %#x]", status); } return status; } /** @helper_function="HlprWinSockAcquirePortReservationForSocket" Purpose: Request a runtime reservation for the provided ports. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/GG699720.aspx <br> HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS741621.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockAcquirePortReservationForSocket(_In_ SOCKET unboundSocket, _In_ INET_PORT_RANGE* pPortRange, _Inout_ UINT64* pReservationToken) { ASSERT(unboundSocket != INVALID_SOCKET); ASSERT(pPortRange); ASSERT(pReservationToken); UINT32 status = NO_ERROR; UINT32 bytesReturned = 0; INET_PORT_RESERVATION_INSTANCE reservation = {0}; status = WSAIoctl(unboundSocket, SIO_ACQUIRE_PORT_RESERVATION, pPortRange, sizeof(INET_PORT_RANGE), &reservation, sizeof(INET_PORT_RESERVATION_INSTANCE), (LPDWORD)&bytesReturned, 0, 0); if(status != NO_ERROR) { status = WSAGetLastError(); HlprLogError(L"HlprWinSockAssociatePortReservationWithSocket : WSAIoctl() [status: %#x]", status); } else *pReservationToken = reservation.Token.Token; return status; } /** @helper_function="HlprWinSockAssociatePortReservationWithSocket" Purpose: Associate the socket with the persistent port(s) that were reserved previously. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/GG699721.aspx <br> HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS741621.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockAssociatePortReservationWithSocket(_In_ SOCKET unboundSocket, _In_ UINT64 reservationToken) { ASSERT(unboundSocket != INVALID_SOCKET); UINT32 status = NO_ERROR; UINT32 bytesReturned = 0; status = WSAIoctl(unboundSocket, SIO_ASSOCIATE_PORT_RESERVATION, &reservationToken, sizeof(UINT64), 0, 0, (LPDWORD)&bytesReturned, 0, 0); if(status != NO_ERROR) { status = WSAGetLastError(); HlprLogError(L"HlprWinSockAssociatePortReservationWithSocket : WSAIoctl() [status: %#x]", status); } return status; } /** @private_function="HlprWinSockQueryPortReservation" Purpose: Find the token for the previously created port reservations. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/GG696072.aspx <br> HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/GG696063.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockQueryPortReservation(_In_ UINT8 ipProtocol, _In_ INET_PORT_RANGE* pPortRange, _Inout_ UINT64* pReservationToken) { ASSERT(ipProtocol != IPPROTO_TCP && ipProtocol != IPPROTO_UDP); ASSERT(pPortRange); ASSERT(pReservationToken); UINT32 status = NO_ERROR; if(ipProtocol == IPPROTO_TCP) status = LookupPersistentTcpPortReservation(htons(pPortRange->StartPort), pPortRange->NumberOfPorts, pReservationToken); else status = LookupPersistentUdpPortReservation(htons(pPortRange->StartPort), pPortRange->NumberOfPorts, pReservationToken); if(status != NO_ERROR) { if(status == ERROR_NOT_FOUND) HlprLogInfo(L"HlprWinSockQueryPortReservation : LookupPersistent%sPortReservation() [status: %#x]", ipProtocol == IPPROTO_TCP ? L"Tcp" : L"Udp", status); else HlprLogError(L"HlprWinSockQueryPortReservation : LookupPersistent%sPortReservation() [status: %#x]", ipProtocol == IPPROTO_TCP ? L"Tcp" : L"Udp", status); *pReservationToken = 0; } return status; } /** @private_function="HlprWinSockDestroyPortReservation" Purpose: Removes the reservation of specific ports for the Proxy service's use. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/GG696070.aspx <br> HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/GG696071.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockDestroyPortReservation(_In_ UINT8 ipProtocol, _In_ INET_PORT_RANGE* pPortRange, _Inout_opt_ UINT64* pReservationToken) /* 0 */ { ASSERT(ipProtocol != IPPROTO_TCP && ipProtocol != IPPROTO_UDP); ASSERT(pPortRange); UINT32 status = NO_ERROR; if(ipProtocol == IPPROTO_TCP) status = DeletePersistentTcpPortReservation(htons(pPortRange->StartPort), pPortRange->NumberOfPorts); else status = DeletePersistentUdpPortReservation(htons(pPortRange->StartPort), pPortRange->NumberOfPorts); if(status == NO_ERROR) { if(pReservationToken) *pReservationToken = 0; } else if(status == ERROR_NOT_FOUND) { status = NO_ERROR; if(pReservationToken) *pReservationToken = 0; } else HlprLogError(L"HlprWinSockDestroyPortReservation : DeletePersistent%sPortReservation() [status: %#x]", ipProtocol == IPPROTO_TCP ? L"Tcp" : L"Udp", status); return status; } /** @private_function="HlprWinSockCreatePortReservation" Purpose: Reserves specific ports for the Proxy service's use. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/GG696068.aspx <br> HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/GG696069.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockCreatePortReservation(_In_ UINT8 ipProtocol, _In_ INET_PORT_RANGE* pPortRange, _Inout_ UINT64* pReservationToken) { ASSERT(ipProtocol != IPPROTO_TCP && ipProtocol != IPPROTO_UDP); ASSERT(pPortRange); ASSERT(pReservationToken); UINT32 status = NO_ERROR; if(ipProtocol == IPPROTO_TCP) status = CreatePersistentTcpPortReservation(htons(pPortRange->StartPort), pPortRange->NumberOfPorts, pReservationToken); else status = CreatePersistentUdpPortReservation(htons(pPortRange->StartPort), pPortRange->NumberOfPorts, pReservationToken); if(status != NO_ERROR) { HlprLogError(L"HlprWinSockCreatePortReservation : CreatePersistent%sPortReservation() [status: %#x]", ipProtocol == IPPROTO_TCP ? L"Tcp" : L"Udp", status); *pReservationToken = 0; } return status; } #if(NTDDI_VERSION >= NTDDI_WIN8) /** @helper_function="HlprWinSockAssociateResourceRecordsWithProxiedConnection" Purpose: Retrieve the original RESOURCE_RECORDS from the original socket and associate them with the new (proxy) socket. <br> <br> Notes: This function needs to be called prior to binding the proxied socket. <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS741621.aspx <br> HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Hardware/HH802472.aspx <br> HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Hardware/HH802473.aspx <br> HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Hardware/HH802474.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockAssociateResourceRecordsWithProxiedConnection(_In_ SOCKET originalSocket, _Inout_ SOCKET proxySocket, _Inout_ SOCKADDR_STORAGE* pProxyPeerSockAddrStorage, _Inout_opt_ SOCKADDR_STORAGE* pOriginSockAddrStorage) /* 0 */ { ASSERT(originalSocket != INVALID_SOCKET); ASSERT(proxySocket != INVALID_SOCKET); ASSERT(pProxyPeerSockAddrStorage); UINT32 status = NO_ERROR; const SIZE_T REDIRECT_RECORDS_SIZE = 2048; const SIZE_T REDIRECT_CONTEXT_SIZE = sizeof(SOCKADDR_STORAGE) * 2; BYTE** ppRedirectRecords = 0; BYTE** ppRedirectContext = 0; SIZE_T redirectRecordsSize = 0; SIZE_T redirectContextSize = 0; SIZE_T redirectRecordsSet = 0; HLPR_NEW_ARRAY(ppRedirectRecords, BYTE*, REDIRECT_RECORDS_SIZE); HLPR_BAIL_ON_ALLOC_FAILURE(ppRedirectRecords, status); HLPR_NEW_ARRAY(ppRedirectContext, BYTE*, REDIRECT_CONTEXT_SIZE); HLPR_BAIL_ON_ALLOC_FAILURE(ppRedirectContext, status); /// Retrieve the REDIRECT_RECORDS from the client socket status = WSAIoctl(originalSocket, SIO_QUERY_WFP_CONNECTION_REDIRECT_RECORDS, 0, 0, (BYTE*)ppRedirectRecords, REDIRECT_RECORDS_SIZE, (LPDWORD)&redirectRecordsSize, 0, 0); if(status != NO_ERROR) { status = WSAGetLastError(); HlprLogError(L"HlprWinSockAssociateResourceRecordsWithProxiedConnection : WSAIoctl() [status: %#x]", status); HLPR_BAIL; } status = WSAIoctl(originalSocket, SIO_QUERY_WFP_CONNECTION_REDIRECT_CONTEXT, 0, 0, (BYTE*)ppRedirectContext, REDIRECT_CONTEXT_SIZE, (LPDWORD)&redirectContextSize, 0, 0); if(status != NO_ERROR) { status = WSAGetLastError(); if(status != FWP_E_NOT_FOUND) { HlprLogError(L"HlprWinSockAssociateResourceRecordsWithProxiedConnection : WSAIoctl() [status: %#x]", status); HLPR_BAIL; } } /// The context passed in WFPSamplerCalloutDriver.sys is the SOCKADDR_STORAGE info of the classified peer endpoint ... RtlCopyMemory(pProxyPeerSockAddrStorage, &(((SOCKADDR_STORAGE*)ppRedirectContext)[0]), sizeof(SOCKADDR_STORAGE)); /// ... and the SOCK_ADDR_STORAGE of the classified origin endpoint. if(pOriginSockAddrStorage) RtlCopyMemory(pOriginSockAddrStorage, &(((SOCKADDR_STORAGE*)ppRedirectContext)[1]), sizeof(SOCKADDR_STORAGE)); /// Attach the REDIRECT_RECORDS to the proxied socket status = WSAIoctl(proxySocket, SIO_SET_WFP_CONNECTION_REDIRECT_RECORDS, (BYTE*)ppRedirectRecords, (DWORD)redirectRecordsSize, 0, 0, (LPDWORD)&redirectRecordsSet, 0, 0); if(status != NO_ERROR) { status = WSAGetLastError(); HlprLogError(L"HlprWinSockAssociateResourceRecordsWithProxiedConnection : WSAIoctl() [status: %#x]", status); HLPR_BAIL; } ASSERT(redirectRecordsSize == redirectRecordsSet); HLPR_BAIL_LABEL: HLPR_DELETE_ARRAY(ppRedirectContext); HLPR_DELETE_ARRAY(ppRedirectRecords); return status; } #endif /// (NTDDI_VERSION >= NTDDI_WIN8) /** @helper_function="HlprWinSockBindToSocket" Purpose: Bind a socket to a protocol, port, and network address. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS737550.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockBindToSocket(_In_ SOCKET unboundSocket, _In_ SOCKADDR_STORAGE* pSockAddrStorage) { ASSERT(unboundSocket != INVALID_SOCKET); ASSERT(pSockAddrStorage); UINT32 status = NO_ERROR; status = bind(unboundSocket, (SOCKADDR*)pSockAddrStorage, sizeof(SOCKADDR_STORAGE)); if(status != NO_ERROR) { status = WSAGetLastError(); HlprLogError(L"HlprWinSockBindToSocket : bind() [status: %#x]", status); } return status; } /** @helper_function="HlprWinSockListenOnSocket" Purpose: Place the socket in a state in which it listens for incoming connections. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS739168.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockListenOnSocket(_In_ SOCKET boundSocket) { ASSERT(boundSocket != INVALID_SOCKET); UINT32 status = NO_ERROR; status = listen(boundSocket, SOMAXCONN); if(status != NO_ERROR) { status = WSAGetLastError(); HlprLogError(L"HlprWinSockListenOnSocket : listen() [status: %#x]", status); } return status; } /** @helper_function="HlprWinSockAcceptConnection" Purpose: Place the socket in a state in which it listens for incoming connections. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS741513.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockAcceptConnection(_In_ SOCKET listeningSocket, _Inout_ SOCKET* pConnectedSocket, _Inout_ SOCKADDR_STORAGE* pPeerSockAddrStorage) { ASSERT(listeningSocket != INVALID_SOCKET); ASSERT(pConnectedSocket); ASSERT(pPeerSockAddrStorage); UINT32 status = NO_ERROR; UINT32 addressLength = sizeof(SOCKADDR_STORAGE); *pConnectedSocket = WSAAccept(listeningSocket, (SOCKADDR*)pPeerSockAddrStorage, (LPINT)&addressLength, 0, 0); if(*pConnectedSocket == INVALID_SOCKET) { status = WSAGetLastError(); HlprLogError(L"HlprWinSockAcceptConnection : WSAAccept() [status: %#x]", status); } return status; } /** @helper_function="HlprWinSockConnectSocket" Purpose: Establish the TCP handshake with the remote peer. <br> <br> Notes: <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS741559.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockConnectSocket(_In_ SOCKET unconnectedSocket, _In_ SOCKADDR_STORAGE* pPeerSockAddrStorage) { ASSERT(unconnectedSocket != INVALID_SOCKET); ASSERT(pPeerSockAddrStorage); UINT32 status = NO_ERROR; status = WSAConnect(unconnectedSocket, (SOCKADDR*)pPeerSockAddrStorage, sizeof(SOCKADDR_STORAGE), 0, 0, 0, 0); if(status != NO_ERROR) { status = WSAGetLastError(); HlprLogError(L"HlprWinSockConnectSocket : WSAConnect() [status: %#x]", status); } return status; } /** @helper_function="HlprWinSockReceiveTCPData" Purpose: Receive TCP data from the peer. <br> <br> Notes: For use with TCP only. <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS741688.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockReceiveTCPData(_In_ SOCKET receivingSocket, _Inout_updates_(numDataBuffers) WSABUF* pDataBuffers, _Inout_ UINT32* pNumBytesReceived, _In_opt_ LPWSAOVERLAPPED pOverlapped, /* 0 */ _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE pCompletionFn, /* 0 */ _In_ UINT32 numDataBuffers, /* 1 */ _In_ UINT32 msgFlags) /* 0 */ { ASSERT(receivingSocket != INVALID_SOCKET); ASSERT(pDataBuffers); ASSERT(pDataBuffers->len); ASSERT(pDataBuffers->buf); ASSERT(pNumBytesReceived); ASSERT(numDataBuffers); ASSERT((pNumBytesReceived && pOverlapped == 0 && pCompletionFn == 0) || (pNumBytesReceived && pOverlapped && pCompletionFn)); UINT32 status = NO_ERROR; UINT32 flags = msgFlags; status = WSARecv(receivingSocket, pDataBuffers, numDataBuffers, (LPDWORD)pNumBytesReceived, (LPDWORD)&flags, pOverlapped, pCompletionFn); if(status != NO_ERROR) { status = WSAGetLastError(); if(status == WSA_IO_PENDING && pOverlapped && pCompletionFn) status = NO_ERROR; else if(status != WSAEDISCON) HlprLogError(L"HlprWinSockReceiveData : WSARecv() [status: %#x]", status); } return status; } /** @helper_function="HlprWinSockSendTCPData" Purpose: Transmit TCP data to the peer. <br> <br> Notes: For use with TCP only. <br> <br> MSDN_Ref: HTTP://MSDN.Microsoft.com/En-US/Library/Windows/Desktop/MS742203.aspx <br> */ _Success_(return == NO_ERROR) UINT32 HlprWinSockSendTCPData(_In_ SOCKET sendingSocket, _In_reads_(numDataBuffers) WSABUF* pDataBuffers, _Inout_opt_ UINT32* pNumBytesTransmitted, _In_opt_ LPWSAOVERLAPPED pOverlapped, /* 0 */ _In_opt_ LPWSAOVERLAPPED_COMPLETION_ROUTINE pCompletionFn, /* 0 */ _In_ UINT32 numDataBuffers) /* 1 */ { ASSERT(sendingSocket != INVALID_SOCKET); ASSERT(pDataBuffers); ASSERT(pDataBuffers->len); ASSERT(pDataBuffers->buf); ASSERT(numDataBuffers); ASSERT((pNumBytesTransmitted && pOverlapped == 0 && pCompletionFn == 0) || (pNumBytesTransmitted && pOverlapped && pCompletionFn)); UINT32 status = NO_ERROR; status = WSASend(sendingSocket, pDataBuffers, numDataBuffers, (LPDWORD)pNumBytesTransmitted, 0, pOverlapped, pCompletionFn); if(status != NO_ERROR) { status = WSAGetLastError(); if(status == WSA_IO_PENDING && pOverlapped && pCompletionFn) status = NO_ERROR; else HlprLogError(L"HlprWinSockSendTCPData : WSASend() [status: %#x]", status); } return status; }
Our Services
-
What our customers say about us?
Read our customer testimonials to find out why our clients keep returning for their projects.
View Testimonials