// // Function: WSPCloseSocket // // Description: // The LSP captures the WSPCloseSocket call to know when it can free the // socket context structure created for every socket. // int WSPAPI WSPCloseSocket( SOCKET s, LPINT lpErrno ) { SOCKET_CONTEXT *sockContext = NULL; int rc = SOCKET_ERROR; // Find the socket context and remove it from the provider's list of sockets sockContext = FindSocketContext( s, TRUE ); if ( NULL == sockContext ) { *lpErrno = WSAENOTSOCK; goto cleanup; } ASSERT( sockContext->Provider->NextProcTable.lpWSPCloseSocket ); // Pass the socket down to close it rc = sockContext->Provider->NextProcTable.lpWSPCloseSocket( s, lpErrno ); // Just free the structure as its alreayd removed from the provider's list LspFree( sockContext ); cleanup: return rc; }
// // Function: WSPGetPeerName // // Description: // Since the LSP is proxying the remote address, this function needs to be // intercepted in order to return the address that the application thinks its // connected to. // int WSPAPI WSPGetPeerName( SOCKET s, struct sockaddr FAR * name, LPINT namelen, LPINT lpErrno ) { SOCKET_CONTEXT *sockContext = NULL; int rc = SOCKET_ERROR; // // Find our provider socket corresponding to this one // sockContext = FindSocketContext( s ); if ( NULL == sockContext ) { *lpErrno = WSAENOTSOCK; goto cleanup; } // If the connection has been proxied, return the address the application // originally tried to connect to. if ( TRUE == sockContext->Proxied ) { __try { // Verify buffer is large enough for underlying address structure if ( *namelen < sockContext->AddressLength ) { *namelen = sockContext->AddressLength; *lpErrno = WSAEFAULT; goto cleanup; } memcpy( name, &sockContext->OriginalAddress, *namelen ); *namelen = sockContext->AddressLength; } __except( EXCEPTION_EXECUTE_HANDLER ) { *lpErrno = WSAEFAULT; goto cleanup; } return NO_ERROR; }
// // Function: WSPConnect // // Description: // This routine establishes a connection on a socket. For the LSP it first // determines if the destination is to be proxied to a different address. // Once the "correct" destination is determined, the connect call is passed // to the lower provider. // int WSPAPI WSPConnect( SOCKET s, const struct sockaddr FAR * name, int namelen, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS, LPINT lpErrno ) { SOCKET_CONTEXT *sockContext = NULL; SOCKADDR *proxyAddr = NULL; int proxyLen = 0, rc = SOCKET_ERROR; // Find the socket context sockContext = FindSocketContext( s ); if ( NULL == sockContext ) { *lpErrno = WSAENOTSOCK; goto cleanup; } ASSERT( sockContext->Provider->NextProcTable.lpWSPConnect ); FindDestinationAddress( sockContext, name, namelen, &proxyAddr, &proxyLen ); rc = sockContext->Provider->NextProcTable.lpWSPConnect( s, proxyAddr, proxyLen, lpCallerData, lpCalleeData, lpSQOS, lpGQOS, lpErrno ); cleanup: return rc; }
// // Function: ExtConnectEx // // Description: // This is our provider's ConnectEx function. When an app calls WSAIoctl // to request the function pointer to ConnectEx, we intercept the call // and return a pointer to our extension function instead. This ConnectEx // implementation needs to perform the same proxying check that WSPConnect // does. // BOOL PASCAL FAR ExtConnectEx( IN SOCKET s, IN const struct sockaddr FAR *name, IN int namelen, IN PVOID lpSendBuffer OPTIONAL, IN DWORD dwSendDataLength, OUT LPDWORD lpdwBytesSent, IN LPOVERLAPPED lpOverlapped ) { SOCKET_CONTEXT *sockContext = NULL; SOCKADDR *proxyAddr = NULL; int Errno = NO_ERROR, proxyLen = 0, rc = FALSE; sockContext = FindSocketContext( s ); if ( NULL == sockContext ) { dbgprint("ExtConnectEx: FindSocketContext failed!"); Errno = WSAENOTSOCK; goto cleanup; } // Make sure we already have the extension function if ( NULL == sockContext->Provider->NextProcTableExt.lpfnConnectEx ) { GUID guidConnectEx = WSAID_CONNECTEX; rc = LoadExtensionFunction( (FARPROC **)&sockContext->Provider->NextProcTableExt.lpfnConnectEx, guidConnectEx, sockContext->Provider->NextProcTable.lpWSPIoctl, s ); if ( FALSE == rc ) { dbgprint("Next proc table ConnectEx == NULL!"); Errno = WSAEFAULT; goto cleanup; } } // See if the connect needs to be proxied FindDestinationAddress( sockContext, name, namelen, &proxyAddr, &proxyLen ); rc = sockContext->Provider->NextProcTableExt.lpfnConnectEx( s, proxyAddr, proxyLen, lpSendBuffer, dwSendDataLength, lpdwBytesSent, lpOverlapped ); cleanup: return rc; }
// int WSPAPI WSPGetSockOpt( SOCKET s, int level, int optname, __out_bcount(*optlen) char FAR * optval, __inout LPINT optlen, LPINT lpErrno ) { SOCKET_CONTEXT *sockContext = NULL; int rc = NO_ERROR; // Retrieve the socket context sockContext = FindSocketContext( s ); if ( NULL == sockContext ) { *lpErrno = WSAENOTSOCK; rc = SOCKET_ERROR; goto cleanup; } ASSERT( sockContext->Provider->NextProcTable.lpWSPGetSockOpt ); if ( ( SOL_SOCKET == level ) && ( ( SO_PROTOCOL_INFOA == optname ) || ( SO_PROTOCOL_INFOW == optname ) ) ) {