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


lspcommon.h File Reference

#include <winsock2.h>
#include <ws2spi.h>

Include dependency graph for lspcommon.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.


Classes

struct  _EXT_WSPPROC_TABLE
struct  _PROVIDER

Defines

#define __in_z
#define WINSOCK_DLL   "\\ws2_32.dll"
#define ASSERT(exp)
#define dbgprint

Typedefs

typedef void(* LPFN_GETLSPGUID )(GUID *lpGuid)
typedef struct _EXT_WSPPROC_TABLE EXT_WSPPROC_TABLE
typedef struct _PROVIDER PROVIDER
typedef struct _PROVIDERLPPROVIDER

Enumerations

enum  WINSOCK_CATALOG { LspCatalogBoth = 0, LspCatalog32Only, LspCatalog64Only }

Functions

BOOL FindLspEntries (PROVIDER **lspProviders, int *lspProviderCount, int *lpErrno)
PROVIDERFindMatchingLspEntryForProtocolInfo (WSAPROTOCOL_INFOW *inInfo, PROVIDER *lspProviders, int lspCount, BOOL fromStartup=FALSE)
int InitializeProvider (PROVIDER *provider, WORD wVersion, WSAPROTOCOL_INFOW *lpProtocolInfo, WSPUPCALLTABLE UpCallTable, int *Error)
BOOL LoadProviderPath (PROVIDER *loadProvider, int *lpErrno)
int VerifyProcTable (LPWSPPROC_TABLE lpProcTable)
LPWSAPROTOCOL_INFOW EnumerateProviders (WINSOCK_CATALOG Catalog, LPINT TotalProtocols)
int EnumerateProvidersExisting (WINSOCK_CATALOG Catalog, WSAPROTOCOL_INFOW *ProtocolInfo, LPDWORD ProtocolInfoSize)
void FreeProviders (LPWSAPROTOCOL_INFOW ProtocolInfo)
void PrintProtocolInfo (WSAPROTOCOL_INFOW *ProtocolInfo)
void * LspAlloc (SIZE_T size, int *lpErrno)
void LspFree (LPVOID buf)
int LspCreateHeap (int *lpErrno)
void LspDestroyHeap ()

Variables

HANDLE gLspHeap
GUID gProviderGuid
CRITICAL_SECTION gDebugCritSec

Define Documentation

#define __in_z

Definition at line 25 of file lspcommon.h.

#define ASSERT ( exp   ) 

Definition at line 352 of file lspcommon.h.

#define dbgprint

Definition at line 353 of file lspcommon.h.

#define WINSOCK_DLL   "\\ws2_32.dll"

Definition at line 29 of file lspcommon.h.


Typedef Documentation

typedef void(* LPFN_GETLSPGUID)(GUID *lpGuid)

Definition at line 48 of file lspcommon.h.

typedef struct _PROVIDER * LPPROVIDER

typedef struct _PROVIDER PROVIDER


Enumeration Type Documentation

Enumerator:
LspCatalogBoth 
LspCatalog32Only 
LspCatalog64Only 

Definition at line 51 of file lspcommon.h.

00052 {
00053     LspCatalogBoth = 0,
00054     LspCatalog32Only,
00055     LspCatalog64Only
00056 } WINSOCK_CATALOG;


Function Documentation

LPWSAPROTOCOL_INFOW EnumerateProviders ( WINSOCK_CATALOG  Catalog,
LPINT  TotalProtocols 
)

Definition at line 87 of file provider.cpp.

00091 {
00092     LPWSAPROTOCOL_INFOW ProtocolInfo = NULL;
00093     DWORD               ProtocolInfoSize = 0;
00094     INT                 ErrorCode = NO_ERROR,
00095                         rc;
00096     
00097     if ( NULL == TotalProtocols )
00098         goto cleanup;
00099 
00100     *TotalProtocols = 0;
00101 
00102 #ifdef _WIN64
00103     // Find out how many entries we need to enumerate
00104     if ( LspCatalog64Only == Catalog )
00105     {
00106         // Find the size of the buffer
00107         rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode );
00108         if ( SOCKET_ERROR == rc )
00109         {
00110             if ( WSAENOBUFS != ErrorCode )
00111                 goto cleanup;
00112             ErrorCode = NO_ERROR;
00113         }
00114 
00115         // Allocate the buffer
00116         ProtocolInfo = (LPWSAPROTOCOL_INFOW) LspAlloc(
00117                 ProtocolInfoSize,
00118                &ErrorCode
00119                 );
00120         if (ProtocolInfo == NULL)
00121             goto cleanup;
00122 
00123         // Enumerate the catalog for real
00124         rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode );
00125         if ( SOCKET_ERROR == rc )
00126             goto cleanup;
00127 
00128         // Update the count
00129         *TotalProtocols = rc;
00130     }
00131     else if ( LspCatalog32Only == Catalog )
00132     {
00133         HMODULE            hModule;
00134         LPWSCENUMPROTOCOLS fnWscEnumProtocols32 = NULL;
00135 
00136         // Load ws2_32.dll
00137         hModule = LoadLibrary( TEXT( "ws2_32.dll" ) );
00138         if ( NULL == hModule )
00139             goto cleanup;
00140 
00141         // Find the 32-bit catalog enumerator
00142         fnWscEnumProtocols32 = (LPWSCENUMPROTOCOLS) GetProcAddress(
00143                 hModule, 
00144                 TEXT( "WSCEnumProtocols32" )
00145                 );
00146         if ( NULL == fnWscEnumProtocols32 )
00147             goto cleanup;
00148         
00149         // Find the required buffer size
00150         rc = fnWscEnumProtocols32(NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode);
00151         if ( SOCKET_ERROR == rc )
00152         {
00153             if ( WSAENOBUFS != ErrorCode )
00154                 goto cleanup;
00155             ErrorCode = NO_ERROR;
00156         }
00157 
00158         // Allocate the buffer
00159         ProtocolInfo = (LPWSAPROTOCOL_INFOW) LspAlloc(
00160                 ProtocolInfoSize,
00161                &ErrorCode
00162                 );
00163         if ( NULL == ProtocolInfo )
00164             goto cleanup;
00165 
00166         // Enumrate the catalog for real this time
00167         rc = fnWscEnumProtocols32( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode );
00168         if ( SOCKET_ERROR == rc )
00169             goto cleanup;
00170 
00171         // Update the count 
00172         *TotalProtocols = rc;
00173 
00174         FreeLibrary( hModule );
00175     }
00176 #else
00177     if ( LspCatalog32Only == Catalog )
00178     {
00179         // Find the size of the buffer
00180         rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode );
00181         if ( SOCKET_ERROR == rc )
00182         {
00183             if ( WSAENOBUFS != ErrorCode )
00184                 goto cleanup;
00185             ErrorCode = NO_ERROR;
00186         }
00187 
00188         // Allocate the buffer
00189         ProtocolInfo = (LPWSAPROTOCOL_INFOW) LspAlloc(
00190                 ProtocolInfoSize,
00191                &ErrorCode
00192                 );
00193         if ( NULL == ProtocolInfo )
00194             goto cleanup;
00195 
00196         // Enumerate the catalog for real
00197         rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode );
00198         if ( SOCKET_ERROR == rc )
00199             goto cleanup;
00200 
00201         // Update the count
00202         *TotalProtocols = rc;
00203     }
00204     else if ( LspCatalog64Only == Catalog )
00205     {
00206         dbgprint( "Unable to enumerate 64-bit Winsock catalog from 32-bit process!");
00207     }
00208 #endif
00209     else
00210     {
00211         // Find the size of the buffer
00212         rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode );
00213         if ( SOCKET_ERROR == rc )
00214         {
00215             if ( WSAENOBUFS != ErrorCode )
00216                 goto cleanup;
00217             ErrorCode = NO_ERROR;
00218         }
00219 
00220         // Allocate the buffer
00221         ProtocolInfo = (LPWSAPROTOCOL_INFOW) LspAlloc(
00222                 ProtocolInfoSize,
00223                &ErrorCode
00224                 );
00225         if ( NULL == ProtocolInfo )
00226             goto cleanup;
00227 
00228         // Enumerate the catalog for real
00229         rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode );
00230         if ( SOCKET_ERROR == rc )
00231             goto cleanup;
00232 
00233         // Update the count
00234         *TotalProtocols = rc;
00235     }
00236 
00237 cleanup:
00238 
00239     if ( ( NO_ERROR != ErrorCode ) && ( NULL != ProtocolInfo ) )
00240     {
00241         LspFree( ProtocolInfo );
00242         ProtocolInfo = NULL;
00243     }
00244 
00245     return ProtocolInfo;
00246 }

int EnumerateProvidersExisting ( WINSOCK_CATALOG  Catalog,
WSAPROTOCOL_INFOW *  ProtocolInfo,
LPDWORD  ProtocolInfoSize 
)

Definition at line 255 of file provider.cpp.

00260 {
00261     INT                 ErrorCode = NO_ERROR,
00262                         rc = NO_ERROR;
00263     
00264 #ifdef _WIN64
00265     if ( LspCatalog64Only == Catalog )
00266     {
00267         rc = WSCEnumProtocols( NULL, ProtocolInfo, ProtocolInfoSize, &ErrorCode );
00268     }
00269     else if ( LspCatalog32Only == Catalog )
00270     {
00271         rc = WSCEnumProtocols32( NULL, ProtocolInfo, ProtocolInfoSize, &ErrorCode );
00272     }
00273 #else
00274     if ( LspCatalog32Only == Catalog )
00275     {
00276         rc = WSCEnumProtocols( NULL, ProtocolInfo, ProtocolInfoSize, &ErrorCode );
00277     }
00278     else if ( LspCatalog64Only == Catalog )
00279     {
00280         dbgprint( "Unable to enumerate 64-bit Winsock catalog from 32-bit process!" );
00281     }
00282 #endif
00283     if ( SOCKET_ERROR == rc )
00284     {
00285         dbgprint( "EnumerateProvidersExisting: WSCEnumProviders failed: %d",
00286                 GetLastError() );
00287     }
00288 
00289     return rc;
00290 }

BOOL FindLspEntries ( PROVIDER **  lspProviders,
int *  lspProviderCount,
int *  lpErrno 
)

Definition at line 397 of file provider.cpp.

00402 {
00403     PROVIDER           *Providers = NULL;
00404     LPWSAPROTOCOL_INFOW ProtocolInfo = NULL;
00405     DWORD               DummyLspId = 0;
00406     int                 ProtocolCount = 0,
00407                         LayerCount = 0,
00408                         idx,
00409                         i, j;
00410 
00411     *lspProviderCount = 0;
00412     *lspProviders = NULL;
00413 
00414     // Enumerate the catalog
00415     ProtocolInfo = EnumerateProviders( LspCatalogBoth, &ProtocolCount );
00416     if ( NULL == ProtocolInfo )
00417     {
00418         dbgprint("FindLspEntries; EnumerateProviders failed!");
00419         goto cleanup;
00420     }
00421 
00422     // Find our dummy LSP entry ID
00423     DummyLspId = 0;
00424     for(i=0; i < ProtocolCount ;i++)
00425     {
00426         if ( 0 == memcmp( &ProtocolInfo[ i ].ProviderId, &gProviderGuid, sizeof( gProviderGuid ) ) )
00427         {
00428             DummyLspId = ProtocolInfo[ i ].dwCatalogEntryId;
00429             break;
00430         }
00431     }
00432 
00433     ASSERT( 0 != DummyLspId );
00434 
00435     // Count how many LSP layered entries are present
00436     LayerCount = 0;
00437     for(i=0; i < ProtocolCount ;i++)
00438     {
00439         if ( ( ProtocolInfo[ i ].ProtocolChain.ChainLen > 1 ) &&
00440              ( DummyLspId == ProtocolInfo[ i ].ProtocolChain.ChainEntries[ 0 ] )
00441            )
00442         {
00443             LayerCount++;
00444         }
00445     }
00446 
00447     ASSERT( 0 != LayerCount );
00448 
00449     // Allocate space for the layered providers
00450     Providers = (PROVIDER *) LspAlloc( sizeof(PROVIDER) * LayerCount, lpErrno );
00451     if ( NULL == Providers )
00452     {
00453         dbgprint("FindLspEntries: LspAlloc failed: %d", *lpErrno );
00454         goto cleanup;
00455     }
00456 
00457     idx = 0;
00458 
00459     // Save the LSP layered entries
00460     for(i=0; i < ProtocolCount ;i++)
00461     {
00462         // The layered protocol entries for this LSP will always reference the
00463         //    dummy entry ID as its first entry in the chain array. Also make
00464         //    sure to check only LSP entries (since a base provider's chain length
00465         //    is 1 but the chain array entries can be garbage)
00466         if ( ( ProtocolInfo[ i ].ProtocolChain.ChainLen > 1 ) &&
00467              ( DummyLspId == ProtocolInfo[ i ].ProtocolChain.ChainEntries[ 0 ] )
00468            )
00469         {
00470             // Copy the new entry to the head
00471             memcpy( &Providers[ idx ].LayerProvider, &ProtocolInfo[ i ], sizeof(WSAPROTOCOL_INFOW) );
00472             Providers[ idx ].LayerProvider.szProtocol[ WSAPROTOCOL_LEN ] = '\0';
00473 
00474             // Copy the provider underneath this entry
00475             for(j=0; j < ProtocolCount ;j++)
00476             {
00477                 // The next provider can either be a base, a dummy, or another layered
00478                 //    protocol chain. If a dummy or layer then both providers will have
00479                 //    the same DLL to load.
00480                 if ( ProtocolInfo[ i ].ProtocolChain.ChainEntries[ 1 ] ==
00481                      ProtocolInfo[ j ].dwCatalogEntryId )
00482                 {
00483                     memcpy( &Providers[ idx ].NextProvider, &ProtocolInfo[ j ],
00484                             sizeof( WSAPROTOCOL_INFOW ) );
00485                     Providers[ idx ].NextProvider.szProtocol[ WSAPROTOCOL_LEN ] = '\0';
00486                     break;
00487                 }
00488             }
00489 
00490             // Verify we copied the lower layer
00491             ASSERT( j < ProtocolCount );
00492 
00493             InitializeCriticalSection( &Providers[ idx ].ProviderCritSec );
00494             InitializeListHead( &Providers[ idx ].SocketList );
00495 
00496             Providers[ idx ].LspDummyId = DummyLspId;
00497 
00498             idx++;
00499         }
00500     }
00501 
00502     ASSERT( idx == LayerCount );
00503 
00504     if ( NULL != ProtocolInfo )
00505         FreeProviders( ProtocolInfo );
00506 
00507     *lspProviders = Providers;
00508     *lspProviderCount = LayerCount;
00509 
00510     return TRUE;
00511 
00512 cleanup:
00513 
00514     if ( NULL != ProtocolInfo )
00515         FreeProviders( ProtocolInfo );
00516 
00517     if ( NULL != Providers )
00518         LspFree( Providers );
00519 
00520     return FALSE;
00521 }

PROVIDER* FindMatchingLspEntryForProtocolInfo ( WSAPROTOCOL_INFOW *  inInfo,
PROVIDER lspProviders,
int  lspCount,
BOOL  fromStartup = FALSE 
)

Definition at line 534 of file provider.cpp.

00540 {
00541     WSAPROTOCOL_INFOW  *ProtocolInfo = NULL;
00542     DWORD               hiddenEntryId;
00543     int                 ProtocolCount,
00544                         i, j, k;
00545 
00546     // Two possibilites - this inInfo belongs to our LSP or its a layer over our LSP
00547 
00548     // First see if the inInfo is one of the LSPs entry
00549     for(i=0; i < lspCount ;i++)
00550     {
00551         if ( inInfo->dwCatalogEntryId == lspProviders[ i ].LayerProvider.dwCatalogEntryId )
00552         {
00553             return &lspProviders[ i ];
00554         }
00555     }
00556 
00557     ASSERT( inInfo->ProtocolChain.ChainLen > 1 );
00558 
00559     // Next check the inInfo's protocol chains for a reference to our LSP
00560     for(i=0; i < lspCount ;i++)
00561     {
00562         for(j=1; j < inInfo->ProtocolChain.ChainLen ;j++)
00563         {
00564             if ( inInfo->ProtocolChain.ChainEntries[ j ] == lspProviders[ i ].LspDummyId )
00565             {
00566                 // Bad news, the entry passed to us references our dummy entry so we
00567                 //    need to do some heuristic work to find the "correct" LSP entry
00568                 //    that corresponds to the input provider
00569                 goto next_match;
00570             }
00571             else if ( inInfo->ProtocolChain.ChainEntries[ j ] == lspProviders[ i ].LayerProvider.dwCatalogEntryId )
00572             {
00573                 return &lspProviders[ i ];
00574             }
00575         }
00576     }
00577 
00578 next_match:
00579 
00580     // If we didn't find an explicit match we'll have to guess - first try to
00581     //    match address family, socket type, protocol and provider flags
00582     for(i=0; i < lspCount ;i++)
00583     {
00584         if ( ( inInfo->iAddressFamily == lspProviders[ i ].LayerProvider.iAddressFamily ) &&
00585              ( inInfo->iSocketType == lspProviders[ i ].LayerProvider.iSocketType ) &&
00586              ( inInfo->iProtocol == lspProviders[ i ].LayerProvider.iProtocol ) &&
00587              ( ( ( inInfo->dwServiceFlags1 & ~XP1_IFS_HANDLES ) ==
00588                  ( lspProviders[ i ].LayerProvider.dwServiceFlags1 & ~XP1_IFS_HANDLES ) 
00589                )
00590              )
00591            )
00592         {
00593             return &lspProviders[ i ];
00594         }
00595     }
00596 
00597     // If this routine was called from WSPSocket and we can't find a match yet, we're
00598     //    in bad shape since the protocol info passed in matches no entries of this 
00599     //    LSPs ...
00600 
00601     ASSERT( fromStartup );
00602 
00603 #ifndef DBG
00604     UNREFERENCED_PARAMETER( fromStartup );
00605 #endif
00606 
00607     //
00608     // Still no match. See if the protocol info passed in belongs to another LSP.
00609     // Enumerate all its protocol entries and see if we reside in any of those
00610     // chains. This typically will happen when an LSP is layered over us and it
00611     // bulk loads all of the providers beneath its entries upon its first WSPStartup
00612     // call.
00613     //
00614     // For example consider the following catalog (where this LSP is LSP1):
00615     //
00616     //  _____________ _____________
00617     //  | LSP 2 TCP | | LSP 2 UDP |
00618     //  _____________              
00619     //  | LSP 1 TCP |
00620     //  _____________ _____________
00621     //  | BASE TCP  | | BASE UDP  |
00622     //
00623     // When LSP 2 is started, its WSPStartup is invoked with its UDP entry (since
00624     // the application created a UDP socket). Because LSP2 initializes all its layers
00625     // upon first WSPStartup it will load all the layers beneath it. So LSP2 will
00626     // load LSP1 and invoke its WSPStartup but will pass the UDP protocol info which
00627     // it was passed. At this point LSP1 won't know what to do since it was passed a
00628     // UDP entry and its not layered over any UDP entry. LSP1 cannot return any
00629     // entry if its an IFS LSP which implements only a subset of the Winsock
00630     // functions (i.e. LSP1 will return a mix of function pointers from BASE TCP
00631     // and its own LSP DLL). Because of this, LSP1 will try to "match" which
00632     // chain from LSP2 it actually resides in such that when LSP2 creates a TCP
00633     // socket later, it will have the correct function pointers.
00634     //
00635     // The heuristic is:
00636     // 1. Find all layered protocol entries belonging to the WSAPROTOCOL_INFOW passed.
00637     //    In the above example it would find LSP2 TCP and LSP2 UDP.
00638     // 2. Iterate through each provider found and walk the protocol chain in each 
00639     //    provider, looking for a reference to LSP1's entry.
00640     // 3. If found check LSP1 entry to see if it has already been loaded. If not
00641     //    then this is the match, if so then LSP2 could be layered over another TCP
00642     //    entry which is also layered over LSP1 so keep looking.
00643     //
00644 
00645     // Should never receive a base or dummy entry
00646     ASSERT( inInfo->ProtocolChain.ChainLen > 1 );
00647 
00648     ProtocolInfo = EnumerateProviders( LspCatalogBoth, &ProtocolCount );
00649     if ( NULL == ProtocolInfo )
00650     {
00651         dbgprint("FindMatchingLspEntryForProtocolInfo: EnumerateProviders failed!\n");
00652         goto cleanup;
00653     }
00654 
00655     hiddenEntryId = 0;
00656     for(i=0; i < ProtocolCount ;i++)
00657     {
00658         if ( inInfo->ProtocolChain.ChainEntries[ 0 ] == ProtocolInfo[ i ].dwCatalogEntryId )
00659         {
00660             hiddenEntryId = ProtocolInfo[ i ].dwCatalogEntryId;
00661             break;
00662         }
00663     }
00664 
00665     ASSERT( hiddenEntryId );
00666 
00667     for(i=0; i < ProtocolCount ;i++)
00668     {
00669         if ( ProtocolInfo[ i ].ProtocolChain.ChainEntries[ 0 ] == hiddenEntryId )
00670         {
00671             // This entry belongs to the LSP layered over us - walk its chains to
00672             //    see if it references our LSP
00673             for(j=1; j < ProtocolInfo[ i ].ProtocolChain.ChainLen ;j++)
00674             {
00675                 for(k=0; k < lspCount ;k++)
00676                 {
00677                     if ( ProtocolInfo[ i ].ProtocolChain.ChainEntries[ j ] ==
00678                          lspProviders[ k ].LayerProvider.ProtocolChain.ChainEntries[ 0 ]
00679                        )
00680                     {
00681                         // Bad news again, the protocol chain of the LSP above us
00682                         //   references our dummy LSP entry so we'll have to try
00683                         //   to match according to the protocol triplet and provider
00684                         //   flags
00685                         if ( ( ProtocolInfo[ i ].iAddressFamily == 
00686                                lspProviders[ k ].LayerProvider.iAddressFamily ) &&
00687                              ( ProtocolInfo[ i ].iSocketType ==
00688                                lspProviders[ k ].LayerProvider.iSocketType ) &&
00689                              ( ProtocolInfo[ i ].iProtocol ==
00690                                lspProviders[ k ].LayerProvider.iProtocol ) &&
00691                              ( ( ProtocolInfo[ i ].dwServiceFlags1 & ~XP1_IFS_HANDLES ) ==
00692                                ( lspProviders[ k ].LayerProvider.dwServiceFlags1 & ~XP1_IFS_HANDLES ) )
00693                            )
00694                         {
00695                             return &lspProviders[ i ];
00696                         }
00697                     }
00698 
00699                     if ( ( ProtocolInfo[ i ].ProtocolChain.ChainEntries[ j ] ==
00700                             lspProviders[ k ].LayerProvider.dwCatalogEntryId ) &&
00701                          ( lspProviders[ k ].StartupCount == 0 ) 
00702                        )
00703                     {
00704                         return &lspProviders[ i ];
00705                     }
00706                 }
00707             }
00708         }
00709     }
00710     
00711 cleanup:
00712 
00713     ASSERT( FALSE ); 
00714 
00715     return NULL;
00716 }

void FreeProviders ( LPWSAPROTOCOL_INFOW  ProtocolInfo  ) 

Definition at line 299 of file provider.cpp.

00302 {
00303     LspFree( ProtocolInfo );
00304 }

int InitializeProvider ( PROVIDER provider,
WORD  wVersion,
WSAPROTOCOL_INFOW *  lpProtocolInfo,
WSPUPCALLTABLE  UpCallTable,
int *  Error 
)

Definition at line 825 of file provider.cpp.

00832 {
00833     WSAPROTOCOL_INFOW  *ProviderInfo = NULL;
00834     int                 rc;
00835 
00836     rc = LoadProviderPath( provider, Error );
00837     if ( FALSE == rc )
00838     {
00839         dbgprint("WSPStartup: LoadProviderPath failed: %d", *Error );
00840         goto cleanup;
00841     }
00842 
00843     // Determine which protocol structure to pass to the lower layer -
00844     //    if the next layer is a base provider, pass the base provider's
00845     //    structure; otherwise, pass whatever was given to us
00846     if ( BASE_PROTOCOL == provider->NextProvider.ProtocolChain.ChainLen )
00847         ProviderInfo = &provider->NextProvider;
00848     else
00849         ProviderInfo = lpProtocolInfo;
00850 
00851     rc = provider->fnWSPStartup(
00852             wVersion,
00853             &provider->WinsockVersion,
00854             ProviderInfo,
00855             UpCallTable,
00856             &provider->NextProcTable
00857             );
00858     if ( 0 != rc )
00859     {
00860         dbgprint("%ws::WSPStartup failed: %d", provider->NextProvider.szProtocol,
00861                 rc );
00862         *Error = rc;
00863         goto cleanup;
00864     }
00865 
00866     // Make sure the proc table returned is valid
00867     rc = VerifyProcTable( &provider->NextProcTable );
00868     if ( SOCKET_ERROR == rc )
00869     {
00870         *Error = WSAEINVALIDPROCTABLE;
00871         goto cleanup;
00872     }
00873 
00874     ASSERT( NO_ERROR == rc );
00875 
00876     // Increment a startup count per-provider as well as an overall counter
00877     //    e.g. The sum of all the individual provider's startup should equal
00878     //         the global counter, that is, until the process starts calling
00879     //         WSPCleanup
00880     provider->StartupCount++;
00881 
00882 cleanup:
00883 
00884     return rc;
00885 }

BOOL LoadProviderPath ( PROVIDER loadProvider,
int *  lpErrno 
)

Definition at line 728 of file provider.cpp.

00732 {
00733     int     rc;
00734 
00735     *lpErrno = 0;
00736 
00737     // Retrieve the provider path of the lower layer
00738     loadProvider->ProviderPathLen = MAX_PATH - 1;
00739     rc = WSCGetProviderPath(
00740            &loadProvider->NextProvider.ProviderId,
00741             loadProvider->ProviderPathW,
00742            &loadProvider->ProviderPathLen,
00743             lpErrno
00744             );
00745     if ( SOCKET_ERROR == rc )
00746     {
00747         dbgprint("LoadProviderPath: WSCGetProviderPath failed: %d", *lpErrno );
00748         goto cleanup;
00749     }
00750 
00751     rc = ExpandEnvironmentStringsW(
00752             loadProvider->ProviderPathW,
00753             loadProvider->LibraryPathW,
00754             MAX_PATH - 1
00755             );
00756     if ( ( 0 != rc ) && ( MAX_PATH-1 >= rc ) )
00757     {
00758         loadProvider->Module = LoadLibraryW( loadProvider->LibraryPathW );
00759         if ( NULL == loadProvider->Module )
00760         {
00761             dbgprint("LoadProviderPath: LoadLibraryW failed: %d", GetLastError() );
00762             goto cleanup;
00763         }
00764     }
00765     else if ( 0 == rc )
00766     {
00767         char    ProviderPathA[ MAX_PATH ],
00768                 LibraryPathA[ MAX_PATH ];
00769 
00770         // No UNICODE so we must be on Win9x
00771         rc = WideCharToMultiByte( CP_ACP, 0,
00772                 loadProvider->ProviderPathW,
00773                 loadProvider->ProviderPathLen,
00774                 ProviderPathA,
00775                 MAX_PATH,
00776                 NULL,
00777                 NULL
00778                 );
00779         if ( 0 == rc )
00780         {
00781             dbgprint("LoadProviderPath: WideCharToMultiByte failed: %d", GetLastError() );
00782             goto cleanup;
00783         }
00784 
00785         rc = ExpandEnvironmentStringsA(
00786                 ProviderPathA,
00787                 LibraryPathA,
00788                 MAX_PATH - 1
00789                 );
00790         if ( ( 0 == rc ) || ( MAX_PATH - 1 < rc ) )
00791         {
00792             dbgprint("LoadProviderPath: ExpandEnvironmentStringsA failed: %d", GetLastError() );
00793             goto cleanup;
00794         }
00795 
00796         loadProvider->Module = LoadLibraryA( LibraryPathA );
00797         if ( NULL == loadProvider->Module )
00798         {
00799             dbgprint("LoadProviderPath: LoadLibraryA failed: %d", GetLastError() );
00800             goto cleanup;
00801         }
00802     }
00803 
00804     // Retrieve the next provider's WSPSTartup function
00805     loadProvider->fnWSPStartup = (LPWSPSTARTUP) GetProcAddress(
00806             loadProvider->Module,
00807             "WSPStartup"
00808             );
00809     if ( NULL == loadProvider->fnWSPStartup )
00810     {
00811         dbgprint("LoadProviderPath: GetProcAddress failed: %d", GetLastError() );
00812         goto cleanup;
00813     }
00814 
00815     return TRUE;
00816 
00817 cleanup:
00818 
00819     if ( *lpErrno == 0 )
00820         *lpErrno = GetLastError();
00821     return FALSE;
00822 }

void* LspAlloc ( SIZE_T  size,
int *  lpErrno 
)

Definition at line 314 of file provider.cpp.

00318 {
00319     void *mem = NULL;
00320     mem = HeapAlloc( 
00321             gLspHeap, 
00322             HEAP_ZERO_MEMORY, 
00323             size
00324             );
00325     if ( NULL == mem )
00326     {
00327         *lpErrno = WSAENOBUFS;
00328     }
00329 
00330     return mem;
00331 }

int LspCreateHeap ( int *  lpErrno  ) 

Definition at line 354 of file provider.cpp.

00357 {
00358     gLspHeap = HeapCreate( 0, 128000, 0 );
00359     if ( NULL == gLspHeap )
00360     {
00361         *lpErrno = WSAEPROVIDERFAILEDINIT;
00362         return SOCKET_ERROR;
00363     }
00364     return NO_ERROR;
00365 }

void LspDestroyHeap (  ) 

Definition at line 374 of file provider.cpp.

00376 {
00377     if ( NULL != gLspHeap )
00378     {
00379         HeapDestroy( gLspHeap );
00380         gLspHeap = NULL;
00381     }
00382 }

void LspFree ( LPVOID  buf  ) 

Definition at line 340 of file provider.cpp.

00343 {
00344     HeapFree( gLspHeap, 0, buf );
00345 }

void PrintProtocolInfo ( WSAPROTOCOL_INFOW *  ProtocolInfo  ) 

int VerifyProcTable ( LPWSPPROC_TABLE  lpProcTable  ) 

Definition at line 895 of file provider.cpp.

00898 {
00899    if ( lpProcTable->lpWSPAccept &&
00900         lpProcTable->lpWSPAddressToString &&
00901         lpProcTable->lpWSPAsyncSelect &&
00902         lpProcTable->lpWSPBind &&
00903         lpProcTable->lpWSPCancelBlockingCall &&
00904         lpProcTable->lpWSPCleanup &&
00905         lpProcTable->lpWSPCloseSocket &&
00906         lpProcTable->lpWSPConnect &&
00907         lpProcTable->lpWSPDuplicateSocket &&
00908         lpProcTable->lpWSPEnumNetworkEvents &&
00909         lpProcTable->lpWSPEventSelect &&
00910         lpProcTable->lpWSPGetOverlappedResult &&
00911         lpProcTable->lpWSPGetPeerName &&
00912         lpProcTable->lpWSPGetSockOpt &&
00913         lpProcTable->lpWSPGetSockName &&
00914         lpProcTable->lpWSPGetQOSByName &&
00915         lpProcTable->lpWSPIoctl &&
00916         lpProcTable->lpWSPJoinLeaf &&
00917         lpProcTable->lpWSPListen &&
00918         lpProcTable->lpWSPRecv &&
00919         lpProcTable->lpWSPRecvDisconnect &&
00920         lpProcTable->lpWSPRecvFrom &&
00921         lpProcTable->lpWSPSelect &&
00922         lpProcTable->lpWSPSend &&
00923         lpProcTable->lpWSPSendDisconnect &&
00924         lpProcTable->lpWSPSendTo &&
00925         lpProcTable->lpWSPSetSockOpt &&
00926         lpProcTable->lpWSPShutdown &&
00927         lpProcTable->lpWSPSocket &&
00928         lpProcTable->lpWSPStringToAddress )
00929     {
00930         return NO_ERROR;
00931     }
00932     return SOCKET_ERROR;
00933 }


Variable Documentation

CRITICAL_SECTION gDebugCritSec

Definition at line 39 of file provider.cpp.

HANDLE gLspHeap

Definition at line 42 of file provider.cpp.

Definition at line 37 of file lspguid.cpp.