Retail products


Traffic interception SDK

Control every TCP/IP network connection

  • Route connections via proxy
  • Redirect connections and modify the data
  • Block connections and applications
SSL interception SDK

View SSL in plaintext and modify it

  • View the SSL stream decrypted in plaintext
  • Redirect SSL connection and modify decrypted data
  • Browser shows "SSL lock" without warnings

Documentation


spi.cpp File Reference

#include "lspdef.h"
#include <strsafe.h>
#include <stdio.h>
#include <stdlib.h>

Include dependency graph for spi.cpp:

Go to the source code of this file.


Defines

#define DEFAULT_PRINT_BUFFER   512

Functions

int FindUrl (__in_ecount(buflen) char *buf, int buflen, __out char **start)
BOOL WINAPI DllMain (IN HINSTANCE hinstDll, IN DWORD dwReason, LPVOID lpvReserved)
int WSPAPI WSPCleanup (LPINT lpErrno)
int WSPAPI WSPCloseSocket (SOCKET s, LPINT lpErrno)
int WSPAPI WSPConnect (SOCKET s, const struct sockaddr FAR *name, int namelen, LPWSABUF lpCallerData, LPWSABUF lpCalleeData, LPQOS lpSQOS, LPQOS lpGQOS, LPINT lpErrno)
int WSPAPI WSPGetPeerName (SOCKET s, struct sockaddr FAR *name, LPINT namelen, LPINT lpErrno)
int WSPAPI WSPGetSockOpt (SOCKET s, int level, int optname, __out_bcount(*optlen) char FAR *optval, __inout LPINT optlen, LPINT lpErrno)
int WSPAPI WSPIoctl (SOCKET s, DWORD dwIoControlCode, LPVOID lpvInBuffer, DWORD cbInBuffer, LPVOID lpvOutBuffer, DWORD cbOutBuffer, LPDWORD lpcbBytesReturned, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
int WSPAPI WSPSend (SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine, LPWSATHREADID lpThreadId, LPINT lpErrno)
SOCKET WSPAPI WSPSocket (int af, int type, int protocol, LPWSAPROTOCOL_INFOW lpProtocolInfo, GROUP g, DWORD dwFlags, LPINT lpErrno)
SOCKET WSPAPI WSPAccept (SOCKET s, struct sockaddr FAR *addr, LPINT addrlen, LPCONDITIONPROC lpfnCondition, DWORD_PTR dwCallbackData, LPINT lpErrno)
int WSPAPI WSPStartup (WORD wVersion, LPWSPDATA lpWSPData, LPWSAPROTOCOL_INFOW lpProtocolInfo, WSPUPCALLTABLE UpCallTable, LPWSPPROC_TABLE lpProcTable)
void FindDestinationAddress (SOCKET_CONTEXT *context, const SOCKADDR *destAddr, int destLen, SOCKADDR **proxyAddr, int *proxyLen)
void FreeLspProviders (PROVIDER *lspProvider, int lspProviderCount, int *lpErrno)

Variables

CRITICAL_SECTION gCriticalSection
WSPUPCALLTABLE gMainUpCallTable
LPPROVIDER gLayerInfo = NULL
int gLayerCount = 0

Define Documentation

#define DEFAULT_PRINT_BUFFER   512

Definition at line 37 of file spi.cpp.


Function Documentation

BOOL WINAPI DllMain ( IN HINSTANCE  hinstDll,
IN DWORD  dwReason,
LPVOID  lpvReserved 
)

Definition at line 81 of file spi.cpp.

00086 {
00087     UNREFERENCED_PARAMETER( hinstDll );
00088     UNREFERENCED_PARAMETER( lpvReserved );
00089 
00090     switch (dwReason)
00091     {
00092 
00093         case DLL_PROCESS_ATTACH:
00094             //
00095             // Initialize some critical section objects 
00096             //
00097             __try
00098             {
00099                 InitializeCriticalSection( &gCriticalSection );
00100                 InitializeCriticalSection( &gDebugCritSec );
00101             }
00102             __except( EXCEPTION_EXECUTE_HANDLER )
00103             {
00104                 goto cleanup;
00105             }
00106             break;
00107 
00108         case DLL_THREAD_ATTACH:
00109             break;
00110 
00111         case DLL_THREAD_DETACH:
00112             break;
00113 
00114         case DLL_PROCESS_DETACH:
00115             gDetached = TRUE;
00116 
00117             EnterCriticalSection( &gCriticalSection );
00118             if ( NULL != gLayerInfo )
00119             {
00120                 int Error;
00121 
00122                 // Free LSP structures if still present as well as call WSPCleanup
00123                 //    for all providers this LSP loaded
00124                 FreeLspProviders( gLayerInfo, gLayerCount, &Error );
00125                 gLayerInfo = NULL;
00126                 gLayerCount = 0;
00127             }
00128             LeaveCriticalSection( &gCriticalSection );
00129 
00130             DeleteCriticalSection( &gCriticalSection );
00131             DeleteCriticalSection( &gDebugCritSec );
00132 
00133             break;
00134     }
00135 
00136     return TRUE;
00137 
00138 cleanup:
00139 
00140     return FALSE;
00141 }

void FindDestinationAddress ( SOCKET_CONTEXT context,
const SOCKADDR *  destAddr,
int  destLen,
SOCKADDR **  proxyAddr,
int *  proxyLen 
)

Definition at line 1049 of file spi.cpp.

01056 {
01057     UNREFERENCED_PARAMETER( context );
01058     UNREFERENCED_PARAMETER( destLen );
01059     UNREFERENCED_PARAMETER( proxyAddr );
01060     UNREFERENCED_PARAMETER( proxyLen );
01061 
01062     context->AddressLength = destLen;
01063 
01064     // Save destination address
01065     memcpy( &context->OriginalAddress, destAddr, context->AddressLength );
01066 
01067     *proxyAddr = (SOCKADDR *) &context->OriginalAddress;
01068     *proxyLen  = context->AddressLength;
01069 
01070     if ( destAddr->sa_family == AF_INET )
01071     {
01072         // Redirect one destination to another
01073         if ( ( (SOCKADDR_IN *)destAddr )->sin_addr.s_addr == inet_addr("157.56.236.201") )
01074         {
01075             memcpy( &context->ProxiedAddress, destAddr, context->AddressLength );
01076             ( (SOCKADDR_IN *)&context->ProxiedAddress )->sin_addr.s_addr = inet_addr(
01077                     "157.56.237.9"
01078                     );
01079 
01080             *proxyAddr = (SOCKADDR *) &context->ProxiedAddress;
01081 
01082             context->Proxied = TRUE;
01083         }
01084     }
01085     else if ( destAddr->sa_family == AF_INET6 )
01086     {
01087         // Perform redirection here
01088     }
01089 }

int FindUrl ( __in_ecount(buflen) char *  buf,
int  buflen,
__out char **  start 
)

Definition at line 1144 of file spi.cpp.

01149 {
01150     char   *subptr = NULL, *substart = NULL;
01151     int     subidx,
01152             idx;
01153 
01154     *start = NULL;
01155 
01156     // Perform a substring search starting at the beginning of 'buf'
01157     idx = 0;
01158     while ( idx < buflen )
01159     {
01160         substart = buf;
01161         subidx   = idx;
01162         subptr   = "GET";
01163 
01164         // Once a character is matched proceed to check for a complete match 
01165         //    while ensuring we don't go past the end of the buffer (since it may not
01166         //    be NULL terminated -- at least not the portion we're currently looking
01167         //    at)
01168         while ( ( subidx < buflen ) && ( *subptr != '\0' ) && ( *subptr == *substart ) )
01169         {
01170             subptr++;
01171             substart++;
01172             subidx++;
01173         }
01174 
01175         // If 'subptr' is pointing to NULL then a match to "GET" was found
01176         if ( *subptr == '\0' )
01177         {
01178             // A GET request was found so skip over the subsequent space
01179             idx = subidx + 1;
01180             
01181             // Validate we're still within the buffer
01182             if ( idx >= buflen )
01183             {
01184                 // Went past the buffer so return no match
01185                 return 0;
01186             }
01187 
01188             *start = substart + 1;  // Advance the character pointer past the space
01189 
01190             substart++;
01191             subidx = idx;
01192 
01193             // Advance the search pointer until we hit the end space
01194             while ( ( subidx < buflen ) && ( *substart != ' ' ) )
01195             {
01196                 substart++;
01197                 subidx++;
01198             }
01199 
01200             // If we're sitting on the trailing space, we found a URL so return
01201             //    how many bytes are in the URL
01202             if ( *substart == ' ' )
01203             {
01204                 return subidx - idx;
01205             }
01206             else
01207             {
01208                 // Error occured so just return since we're not where we expected
01209                 return 0;
01210             }
01211         }
01212 
01213         // Advance the main pointers and index and start the search with the next
01214         //    string location
01215         buf++;
01216         idx++;
01217     }
01218 
01219     return 0;
01220 }

void FreeLspProviders ( PROVIDER lspProvider,
int  lspProviderCount,
int *  lpErrno 
)

Definition at line 1098 of file spi.cpp.

01103 {
01104     int     i;
01105 
01106     if ( NULL == lspProvider )
01107         return;
01108 
01109     // Need to iterate through the LSP providers and call WSPCleanup accordingly
01110     for(i=0; i < lspProviderCount ;i++)
01111     {
01112         while( 0 != lspProvider[ i ].StartupCount )
01113         {
01114             lspProvider[ i ].StartupCount--;
01115 
01116             lspProvider[ i ].NextProcTable.lpWSPCleanup( lpErrno );
01117         }
01118 
01119         if ( NULL != lspProvider[ i ].Module )
01120         {
01121             FreeLibrary( lspProvider[ i ].Module );
01122             lspProvider[ i ].Module = NULL;
01123         }
01124     }
01125 
01126     for(i=0; i < lspProviderCount ;i++)
01127     {
01128         FreeSocketContextList( &lspProvider[ i ] );
01129         
01130         DeleteCriticalSection( &lspProvider[ i ].ProviderCritSec );
01131     }
01132 
01133     LspFree( lspProvider );
01134 }

SOCKET WSPAPI WSPAccept ( SOCKET  s,
struct sockaddr FAR *  addr,
LPINT  addrlen,
LPCONDITIONPROC  lpfnCondition,
DWORD_PTR  dwCallbackData,
LPINT  lpErrno 
)

Definition at line 798 of file spi.cpp.

00806 {
00807     SOCKET_CONTEXT     *sockContext = NULL,
00808                        *acceptContext = NULL;
00809     SOCKET              acceptProviderSocket = INVALID_SOCKET,
00810                         sret;
00811     int                 rc;
00812 
00813     sockContext = FindSocketContext( s );
00814     if ( NULL == sockContext )
00815     {
00816         *lpErrno = WSAENOTSOCK;
00817         goto cleanup;
00818     }
00819 
00820     ASSERT( sockContext->Provider->NextProcTable.lpWSPAccept );
00821 
00822     //
00823     // Create the socket from the lower layer
00824     //
00825     acceptProviderSocket = sockContext->Provider->NextProcTable.lpWSPAccept(
00826             s, 
00827             addr, 
00828             addrlen, 
00829             lpfnCondition,
00830             dwCallbackData,
00831             lpErrno
00832             );
00833     if ( INVALID_SOCKET == acceptProviderSocket )
00834     {
00835         dbgprint("WSPAccept: NextProcTable.WSPAccept failed: %d", *lpErrno);
00836         goto cleanup;
00837     }
00838 
00839     //
00840     // Create the context information to be associated with this socket
00841     //
00842     acceptContext = CreateSocketContext(
00843             sockContext->Provider,
00844             acceptProviderSocket,
00845             lpErrno
00846             );
00847     if ( NULL == sockContext )
00848     {
00849         dbgprint( "WSPAccept: CreateSocketContext failed: %d", *lpErrno );
00850         goto cleanup;
00851     }
00852 
00853     //
00854     // Associate ownership of this handle with our LSP
00855     //
00856     sret = gMainUpCallTable.lpWPUModifyIFSHandle(
00857             sockContext->Provider->LayerProvider.dwCatalogEntryId,
00858             acceptProviderSocket,
00859             lpErrno
00860             );
00861     if ( INVALID_SOCKET == sret )
00862     {
00863         dbgprint( "WSPAccept: WPUModifyIFSHandle failed: %d", *lpErrno );
00864         goto cleanup;
00865     }
00866 
00867     ASSERT( sret == acceptProviderSocket );
00868 
00869     return acceptProviderSocket;
00870 
00871 cleanup:
00872 
00873     // If an error occured close the socket if it was already created
00874     if ( ( NULL != sockContext ) && ( NULL != acceptContext ) &&
00875          ( INVALID_SOCKET != acceptProviderSocket ) )
00876     {
00877         rc = sockContext->Provider->NextProcTable.lpWSPCloseSocket(
00878                 acceptProviderSocket,
00879                 lpErrno
00880                 );
00881         if ( SOCKET_ERROR == rc )
00882         {
00883             dbgprint( "WSPAccept: WSPCloseSocket failed: %d", *lpErrno );
00884         }
00885 
00886     }
00887     if ( ( NULL != sockContext ) && ( NULL != acceptContext ) )
00888         FreeSocketContext( sockContext->Provider, acceptContext );
00889 
00890     return INVALID_SOCKET;
00891 }

int WSPAPI WSPCleanup ( LPINT  lpErrno  ) 

Definition at line 151 of file spi.cpp.

00154 {
00155     int        rc = SOCKET_ERROR;
00156 
00157     if ( gDetached )
00158     {
00159         rc = NO_ERROR;
00160         goto cleanup;
00161     }
00162 
00163     //
00164     // Grab the DLL global critical section
00165     //
00166     EnterCriticalSection( &gCriticalSection );
00167 
00168     // Verify WSPStartup has been called
00169     if ( 0 == gStartupCount )
00170     {
00171         *lpErrno = WSANOTINITIALISED;
00172         goto cleanup;
00173     }
00174 
00175     // Decrement the global entry count
00176     gStartupCount--;
00177 
00178     if ( 0 == gStartupCount )
00179     {
00180         // Free LSP structures if still present as well as call WSPCleanup
00181         //    for all providers this LSP loaded
00182         FreeLspProviders( gLayerInfo, gLayerCount, lpErrno );
00183         gLayerInfo = NULL;
00184         gLayerCount = 0;
00185     }
00186     
00187     rc = NO_ERROR;
00188 
00189 cleanup:
00190 
00191     LeaveCriticalSection( &gCriticalSection );
00192 
00193     return rc;
00194 }

int WSPAPI WSPCloseSocket ( SOCKET  s,
LPINT  lpErrno 
)

Definition at line 204 of file spi.cpp.

00208 {
00209     SOCKET_CONTEXT *sockContext = NULL;
00210     int             rc = SOCKET_ERROR;
00211 
00212     // Find the socket context and remove it from the provider's list of sockets
00213     sockContext = FindSocketContext( s, TRUE );
00214     if ( NULL == sockContext )
00215     {
00216         *lpErrno = WSAENOTSOCK;
00217         goto cleanup;
00218     }
00219 
00220     ASSERT( sockContext->Provider->NextProcTable.lpWSPCloseSocket );
00221 
00222     // Pass the socket down to close it
00223     rc = sockContext->Provider->NextProcTable.lpWSPCloseSocket(
00224             s,
00225             lpErrno
00226             );
00227 
00228     // Just free the structure as its alreayd removed from the provider's list
00229     LspFree( sockContext );
00230 
00231 cleanup:
00232 
00233     return rc;
00234 }

int WSPAPI WSPConnect ( SOCKET  s,
const struct sockaddr FAR *  name,
int  namelen,
LPWSABUF  lpCallerData,
LPWSABUF  lpCalleeData,
LPQOS  lpSQOS,
LPQOS  lpGQOS,
LPINT  lpErrno 
)

Definition at line 246 of file spi.cpp.

00256 {
00257     SOCKET_CONTEXT *sockContext = NULL;
00258     SOCKADDR       *proxyAddr = NULL;
00259     int             proxyLen = 0,
00260                     rc = SOCKET_ERROR;
00261 
00262     // Find the socket context
00263     sockContext = FindSocketContext( s );
00264     if ( NULL == sockContext )
00265     {
00266         *lpErrno = WSAENOTSOCK;
00267         goto cleanup;
00268     }
00269 
00270     ASSERT( sockContext->Provider->NextProcTable.lpWSPConnect );
00271 
00272     FindDestinationAddress( sockContext, name, namelen, &proxyAddr, &proxyLen );
00273 
00274     rc = sockContext->Provider->NextProcTable.lpWSPConnect(
00275             s,
00276             proxyAddr, 
00277             proxyLen, 
00278             lpCallerData, 
00279             lpCalleeData,
00280             lpSQOS, 
00281             lpGQOS, 
00282             lpErrno
00283             );
00284 
00285 cleanup:
00286 
00287     return rc;
00288 }

int WSPAPI WSPGetPeerName ( SOCKET  s,
struct sockaddr FAR *  name,
LPINT  namelen,
LPINT  lpErrno 
)

Definition at line 299 of file spi.cpp.

00305 {
00306     SOCKET_CONTEXT *sockContext = NULL;
00307     int             rc = SOCKET_ERROR;
00308 
00309     //
00310     // Find our provider socket corresponding to this one
00311     //
00312     sockContext = FindSocketContext( s );
00313     if ( NULL == sockContext )
00314     {
00315         *lpErrno = WSAENOTSOCK;
00316         goto cleanup;
00317     }
00318 
00319     // If the connection has been proxied, return the address the application
00320     //    originally tried to connect to.
00321     if ( TRUE == sockContext->Proxied )
00322     {
00323         __try
00324         {
00325             // Verify buffer is large enough for underlying address structure
00326             if ( *namelen < sockContext->AddressLength )
00327             {
00328                 *namelen = sockContext->AddressLength;
00329                 *lpErrno = WSAEFAULT;
00330                 goto cleanup;
00331             }
00332 
00333             memcpy( name, &sockContext->OriginalAddress, *namelen );
00334             *namelen = sockContext->AddressLength;
00335         } 
00336         __except( EXCEPTION_EXECUTE_HANDLER )
00337         {
00338             *lpErrno = WSAEFAULT;
00339             goto cleanup;
00340         }
00341 
00342         return NO_ERROR;
00343     }
00344 
00345     ASSERT( sockContext->Provider->NextProcTable.lpWSPGetPeerName );
00346 
00347     rc = sockContext->Provider->NextProcTable.lpWSPGetPeerName(
00348             s,
00349             name,
00350             namelen, 
00351             lpErrno
00352             );
00353 
00354 cleanup:
00355 
00356     return rc;
00357 }

int WSPAPI WSPGetSockOpt ( SOCKET  s,
int  level,
int  optname,
__out_bcount *optlen char FAR *  optval,
__inout LPINT  optlen,
LPINT  lpErrno 
)

Definition at line 366 of file spi.cpp.

00374 {
00375     SOCKET_CONTEXT *sockContext = NULL;
00376     int             rc = NO_ERROR;
00377 
00378     // Retrieve the socket context
00379     sockContext = FindSocketContext( s );
00380     if ( NULL == sockContext )
00381     {
00382         *lpErrno = WSAENOTSOCK;
00383         rc = SOCKET_ERROR;
00384         goto cleanup;
00385     }
00386 
00387     ASSERT( sockContext->Provider->NextProcTable.lpWSPGetSockOpt );
00388 
00389     if ( ( SOL_SOCKET == level ) && (
00390             ( SO_PROTOCOL_INFOA == optname ) ||
00391             ( SO_PROTOCOL_INFOW == optname )
00392          )
00393        )
00394     {
00395         __try
00396         {
00397             switch ( optname )
00398             {
00399                 case SO_PROTOCOL_INFOA:
00400                     if (  *optlen <= sizeof( WSAPROTOCOL_INFOA ) )
00401                     {
00402                         *optlen = sizeof( WSAPROTOCOL_INFOA );
00403                         *lpErrno = WSAEFAULT;
00404                         rc = SOCKET_ERROR;
00405                         goto cleanup;
00406                     }
00407 
00408                     *optlen = sizeof( WSAPROTOCOL_INFOA );
00409                     memcpy( optval, &sockContext->Provider->LayerProvider,
00410                             sizeof( WSAPROTOCOL_INFOA ) );
00411 
00412                     break;
00413 
00414                 case SO_PROTOCOL_INFOW:
00415                     if ( *optlen <= sizeof( WSAPROTOCOL_INFOW ) )
00416                     {
00417                         *optlen = sizeof( WSAPROTOCOL_INFOW );
00418                         *lpErrno = WSAEFAULT;
00419                         rc = SOCKET_ERROR;
00420                         goto cleanup;
00421                     }
00422 
00423                     *optlen = sizeof( WSAPROTOCOL_INFOW );
00424                     memcpy( optval, &sockContext->Provider->LayerProvider,
00425                             sizeof( WSAPROTOCOL_INFOW ) );
00426 
00427                     break;
00428 
00429             }
00430         }
00431         __except( EXCEPTION_EXECUTE_HANDLER )
00432         {
00433             *lpErrno = WSAEFAULT;
00434             rc = SOCKET_ERROR;
00435             goto cleanup;
00436         }
00437 
00438         if ( SO_PROTOCOL_INFOA == optname )
00439         {
00440             WideCharToMultiByte( 
00441                     CP_ACP, 
00442                     0,
00443                     sockContext->Provider->LayerProvider.szProtocol,
00444                     -1,
00445                     ( (WSAPROTOCOL_INFOA *)optval )->szProtocol,
00446                     WSAPROTOCOL_LEN+1,
00447                     NULL,
00448                     NULL
00449                     );
00450         }
00451     }
00452     else
00453     {
00454         rc = sockContext->Provider->NextProcTable.lpWSPGetSockOpt(
00455                 s,
00456                 level,
00457                 optname,
00458                 optval,
00459                 optlen,
00460                 lpErrno
00461                 );
00462     }
00463 
00464 cleanup:
00465 
00466     return rc;
00467 }

int WSPAPI WSPIoctl ( SOCKET  s,
DWORD  dwIoControlCode,
LPVOID  lpvInBuffer,
DWORD  cbInBuffer,
LPVOID  lpvOutBuffer,
DWORD  cbOutBuffer,
LPDWORD  lpcbBytesReturned,
LPWSAOVERLAPPED  lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine,
LPWSATHREADID  lpThreadId,
LPINT  lpErrno 
)

Definition at line 478 of file spi.cpp.

00491 {
00492     SOCKET_CONTEXT *sockContext = NULL;
00493     GUID            ConnectExGuid = WSAID_CONNECTEX;
00494     int             rc = NO_ERROR;
00495 
00496     // If loading an extension function, check for ConnectEx
00497     if ( SIO_GET_EXTENSION_FUNCTION_POINTER == dwIoControlCode )
00498     {
00499         if ( 0 == memcmp( lpvInBuffer, &ConnectExGuid, sizeof( GUID ) ) )
00500         {
00501             // Return a pointer to our intermediate extension function
00502             __try 
00503             {
00504                 if ( cbOutBuffer < sizeof( LPFN_CONNECTEX ) )
00505                 {
00506                     *lpcbBytesReturned = sizeof( LPFN_CONNECTEX );
00507                     *lpErrno = WSAEFAULT;
00508                     rc = SOCKET_ERROR;
00509                     goto cleanup;
00510                 }
00511                 *lpcbBytesReturned = sizeof( LPFN_CONNECTEX );
00512                 *((DWORD_PTR *)lpvOutBuffer) = (DWORD_PTR) ExtConnectEx;
00513             }
00514             __except( EXCEPTION_EXECUTE_HANDLER )
00515             {
00516                 *lpErrno = WSAEFAULT;
00517                 rc = SOCKET_ERROR;
00518             }
00519             return rc;
00520         }
00521     }
00522 
00523     // Retrieve the socket context
00524     sockContext = FindSocketContext( s );
00525     if ( NULL == sockContext )
00526     {
00527         *lpErrno = WSAENOTSOCK;
00528         rc = SOCKET_ERROR;
00529         goto cleanup;
00530     }
00531 
00532     ASSERT( sockContext->Provider->NextProcTable.lpWSPIoctl );
00533 
00534     // Pass the call to the lower layer
00535     rc = sockContext->Provider->NextProcTable.lpWSPIoctl(
00536             s,
00537             dwIoControlCode, 
00538             lpvInBuffer,
00539             cbInBuffer, 
00540             lpvOutBuffer, 
00541             cbOutBuffer, 
00542             lpcbBytesReturned, 
00543             lpOverlapped, 
00544             lpCompletionRoutine, 
00545             lpThreadId, 
00546             lpErrno
00547             );
00548 
00549 cleanup:
00550 
00551     return rc;
00552 }

int WSPAPI WSPSend ( SOCKET  s,
LPWSABUF  lpBuffers,
DWORD  dwBufferCount,
LPDWORD  lpNumberOfBytesSent,
DWORD  dwFlags,
LPWSAOVERLAPPED  lpOverlapped,
LPWSAOVERLAPPED_COMPLETION_ROUTINE  lpCompletionRoutine,
LPWSATHREADID  lpThreadId,
LPINT  lpErrno 
)

Definition at line 570 of file spi.cpp.

00581 {
00582     SOCKET_CONTEXT *sockContext = NULL;
00583     DWORD           i;
00584     char           *start = NULL,
00585                     urlstr[ DEFAULT_PRINT_BUFFER ];
00586     int             rc = SOCKET_ERROR,
00587                     len;
00588 
00589     //
00590     // Find our provider socket corresponding to this one
00591     //
00592     sockContext = FindSocketContext( s );
00593     if ( NULL == sockContext )
00594     {
00595         *lpErrno = WSAENOTSOCK;
00596         goto cleanup;
00597     }
00598 
00599     // Parse the send buffer and look for HTTP GET requests
00600     __try
00601     {
00602         for(i=0; i < dwBufferCount ;i++)
00603         {
00604             len = FindUrl( lpBuffers[ i ].buf, lpBuffers[ i ].len, &start );
00605             if ( ( len > 0 ) && ( len+1 < DEFAULT_PRINT_BUFFER ) )
00606             {
00607                 if ( FAILED (StringCchCopyN( urlstr, DEFAULT_PRINT_BUFFER, start, len+1 ) ) )
00608                 {
00609                     *lpErrno = WSAEFAULT;
00610                     goto cleanup;
00611                 }
00612 
00613                 if ( len >= DEFAULT_PRINT_BUFFER )
00614                     urlstr[ DEFAULT_PRINT_BUFFER-1 ] = '\0';
00615                 else
00616                     urlstr[len] = '\0';
00617 
00618                 // URL can be logged but this just displays it to the debugger
00619                 dbgprint("Found URL: '%s'", urlstr );
00620             }
00621         }
00622     }
00623     __except( EXCEPTION_EXECUTE_HANDLER )
00624     {
00625         dbgprint("WSPSend: ***access violation ***");
00626         *lpErrno = WSAEFAULT;
00627         goto cleanup;
00628     }
00629 
00630     ASSERT( sockContext->Provider->NextProcTable.lpWSPSend );
00631 
00632     // Just pass the request along to the lower provider. NOTE: If we choose to
00633     //    modify the data things get a bit trickier if we substitute our own send
00634     //    buffer since we would need to be in the data notification path in order
00635     //    to know when we are able to free that memory (i.e. the lower layer has
00636     //    processed it and is done). In this case a non-IFS LSP is more appropriate
00637     //    since it intercepts all IO completion notifications.
00638 
00639     rc = sockContext->Provider->NextProcTable.lpWSPSend(
00640             s,
00641             lpBuffers,
00642             dwBufferCount, 
00643             lpNumberOfBytesSent,
00644             dwFlags,
00645             lpOverlapped,
00646             lpCompletionRoutine,
00647             lpThreadId,
00648             lpErrno
00649             );
00650 cleanup:
00651 
00652     return rc;
00653 }

SOCKET WSPAPI WSPSocket ( int  af,
int  type,
int  protocol,
LPWSAPROTOCOL_INFOW  lpProtocolInfo,
GROUP  g,
DWORD  dwFlags,
LPINT  lpErrno 
)

Definition at line 665 of file spi.cpp.

00674 {
00675     WSAPROTOCOL_INFOW   InfoCopy = {0};
00676     SOCKET_CONTEXT     *sockContext = NULL;
00677     PROVIDER           *lowerProvider = NULL;
00678     SOCKET              nextProviderSocket = INVALID_SOCKET,
00679                         sret = INVALID_SOCKET;
00680     int                 rc;
00681 
00682     // Find the LSP entry which matches the given provider info
00683     lowerProvider = FindMatchingLspEntryForProtocolInfo(
00684             lpProtocolInfo,
00685             gLayerInfo,
00686             gLayerCount
00687             );
00688     if ( NULL == lowerProvider )
00689     {
00690         dbgprint("WSPSocket: FindMatchingLspEntryForProtocolInfo failed!" );
00691         goto cleanup;
00692     }
00693 
00694     if ( 0 == lowerProvider->StartupCount ) 
00695     {
00696         rc = InitializeProvider( lowerProvider, MAKEWORD(2,2), lpProtocolInfo, 
00697                gMainUpCallTable, lpErrno );
00698         if ( SOCKET_ERROR == rc )
00699         {
00700             dbgprint("WSPSocket: InitializeProvider failed: %d", *lpErrno);
00701             goto cleanup;
00702         }
00703     }
00704 
00705     // If the next layer is a base, substitute the provider structure with the
00706     //    base provider's
00707     if ( BASE_PROTOCOL == lowerProvider->NextProvider.ProtocolChain.ChainLen )
00708     {
00709         memcpy( &InfoCopy, &lowerProvider->NextProvider, sizeof( InfoCopy ) );
00710         InfoCopy.dwProviderReserved = lpProtocolInfo->dwProviderReserved;
00711         lpProtocolInfo = &InfoCopy;
00712     }
00713 
00714     ASSERT( lowerProvider->NextProcTable.lpWSPSocket );
00715 
00716     //
00717     // Create the socket from the lower layer
00718     //
00719     nextProviderSocket = lowerProvider->NextProcTable.lpWSPSocket(
00720             af, 
00721             type, 
00722             protocol, 
00723             lpProtocolInfo,
00724             g, 
00725             dwFlags,
00726             lpErrno
00727             );
00728     if ( INVALID_SOCKET == nextProviderSocket )
00729     {
00730         dbgprint("WSPSocket: NextProcTable.WSPSocket failed: %d", *lpErrno);
00731         goto cleanup;
00732     }
00733 
00734     //
00735     // Create the context information to be associated with this socket
00736     //
00737     sockContext = CreateSocketContext(
00738             lowerProvider,
00739             nextProviderSocket,
00740             lpErrno
00741             );
00742     if ( NULL == sockContext )
00743     {
00744         dbgprint( "WSPSocket: CreateSocketContext failed: %d", *lpErrno );
00745         goto cleanup;
00746     }
00747 
00748     //
00749     // Associate ownership of this handle with our LSP
00750     //
00751     sret = gMainUpCallTable.lpWPUModifyIFSHandle(
00752             lowerProvider->LayerProvider.dwCatalogEntryId,
00753             nextProviderSocket,
00754             lpErrno
00755             );
00756     if ( INVALID_SOCKET == sret )
00757     {
00758         dbgprint( "WSPSocket: WPUModifyIFSHandle failed: %d", *lpErrno );
00759         goto cleanup;
00760     }
00761 
00762     ASSERT( sret == nextProviderSocket );
00763 
00764     return nextProviderSocket;
00765 
00766 cleanup:
00767 
00768     // If an error occured close the socket if it was already created
00769     if ( ( NULL != sockContext ) && ( NULL != lowerProvider ) &&
00770          ( INVALID_SOCKET != nextProviderSocket ) )
00771     {
00772         rc = lowerProvider->NextProcTable.lpWSPCloseSocket(
00773                 nextProviderSocket,
00774                 lpErrno
00775                 );
00776         if ( SOCKET_ERROR == rc )
00777         {
00778             dbgprint( "WSPSocket: WSPCloseSocket failed: %d", *lpErrno );
00779         }
00780 
00781     }
00782     if ( ( NULL != sockContext ) && ( NULL != lowerProvider ) )
00783         FreeSocketContext( lowerProvider, sockContext );
00784 
00785     return INVALID_SOCKET;
00786 }

int WSPAPI WSPStartup ( WORD  wVersion,
LPWSPDATA  lpWSPData,
LPWSAPROTOCOL_INFOW  lpProtocolInfo,
WSPUPCALLTABLE  UpCallTable,
LPWSPPROC_TABLE  lpProcTable 
)

Definition at line 932 of file spi.cpp.

00939 {
00940     PROVIDER           *loadProvider = NULL;
00941     int                 Error = WSAEPROVIDERFAILEDINIT,
00942                         rc;
00943 
00944     EnterCriticalSection( &gCriticalSection );
00945 
00946     // The first time the startup is called, create our heap and allocate some
00947     //    data structures for tracking the LSP providers
00948     if ( 0 == gStartupCount )
00949     {
00950         // Create the heap for all LSP allocations
00951         rc = LspCreateHeap( &Error );
00952         if ( SOCKET_ERROR == rc )
00953         {
00954             dbgprint("WSPStartup: LspCreateHeap failed: %d", Error );
00955             goto cleanup;
00956         }
00957 
00958         // Find this LSP's entries in the Winsock catalog and build a map of them
00959         rc = FindLspEntries( &gLayerInfo, &gLayerCount, &Error );
00960         if ( FALSE == rc )
00961         {
00962             dbgprint("WSPStartup: FindLspEntries failed: %d", Error );
00963             goto cleanup;
00964         }
00965 
00966         // Save off upcall table - this should be the same across all WSPStartup calls
00967         memcpy( &gMainUpCallTable, &UpCallTable, sizeof( gMainUpCallTable ) );
00968 
00969     }
00970 
00971     // Find the matching LSP provider for the requested protocol info passed in.
00972     //    This can either be an LSP layered over use or an entry belonging to this
00973     //    LSP. Note that the LSP startup gets called for each LSP layered protocol
00974     //    entry with a unique GUID. Because of this each layered protocol entry for
00975     //    the IFS LSP should be installed with its own unique GUID.
00976     loadProvider = FindMatchingLspEntryForProtocolInfo(
00977             lpProtocolInfo,
00978             gLayerInfo,
00979             gLayerCount,
00980             TRUE
00981             );
00982     if ( NULL == loadProvider )
00983     {
00984         dbgprint("WSPStartup: FindMatchingLspEntryForProtocolInfo failed!");
00985         ASSERT( 0 );
00986         goto cleanup;
00987     }
00988 
00989     // If this is the first time to "load" this particular provider, initialize
00990     //    the lower layer, etc.
00991     if ( 0 == loadProvider->StartupCount )
00992     {
00993 
00994         rc = InitializeProvider( loadProvider, wVersion, lpProtocolInfo, 
00995                 UpCallTable, &Error );
00996         if ( SOCKET_ERROR == rc )
00997         {
00998             dbgprint("WSPStartup: InitializeProvider failed: %d", Error );
00999             goto cleanup;
01000         }
01001 
01002     }
01003 
01004     gStartupCount++;
01005 
01006     // Build the proc table to return to the caller
01007     memcpy( lpProcTable, &loadProvider->NextProcTable, sizeof( *lpProcTable ) );
01008 
01009     // Override only those functions the LSP wants to intercept
01010     lpProcTable->lpWSPAccept        = WSPAccept;
01011     lpProcTable->lpWSPCleanup       = WSPCleanup;
01012     lpProcTable->lpWSPCloseSocket   = WSPCloseSocket;
01013     lpProcTable->lpWSPConnect       = WSPConnect;
01014     lpProcTable->lpWSPGetPeerName   = WSPGetPeerName;
01015     lpProcTable->lpWSPGetSockOpt    = WSPGetSockOpt;
01016     lpProcTable->lpWSPIoctl         = WSPIoctl;
01017     lpProcTable->lpWSPSend          = WSPSend;
01018     lpProcTable->lpWSPSocket        = WSPSocket;
01019 
01020     memcpy( lpWSPData, &loadProvider->WinsockVersion, sizeof( *lpWSPData ) );
01021 
01022     Error = NO_ERROR;
01023 
01024 cleanup:
01025 
01026     LeaveCriticalSection( &gCriticalSection );
01027 
01028     return Error;
01029 }


Variable Documentation

CRITICAL_SECTION gCriticalSection

Definition at line 45 of file spi.cpp.

int gLayerCount = 0

Definition at line 48 of file spi.cpp.

Definition at line 47 of file spi.cpp.

WSPUPCALLTABLE gMainUpCallTable

Definition at line 46 of file spi.cpp.