00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 #ifndef _PSDK_BLD
00026 #include <nt.h>
00027 #include <ntrtl.h>
00028 #include <nturtl.h>
00029 #endif
00030 
00031 #include <ws2spi.h>
00032 #include <mswsock.h>
00033 #include <sporder.h>
00034 #include "lspcommon.h"
00035 
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 
00039 CRITICAL_SECTION    gDebugCritSec;
00040 
00041 
00042 HANDLE gLspHeap = NULL;
00043 
00044 
00045 
00046 
00047 
00048 
00049 
00050 
00051 #ifdef DBG
00052 void 
00053 dbgprint(
00054     char *format,
00055     ...
00056     )
00057 {
00058     static  DWORD pid=0;
00059     va_list vl;
00060     char    dbgbuf1[2048],
00061             dbgbuf2[2048];
00062 
00063     
00064     if ( 0 == pid )
00065     {
00066         pid = GetCurrentProcessId();
00067     }
00068 
00069     EnterCriticalSection(&gDebugCritSec);
00070     va_start(vl, format);
00071     wvsprintf(dbgbuf1, format, vl);
00072     wsprintf(dbgbuf2, "%lu: %s\r\n", pid, dbgbuf1);
00073     va_end(vl);
00074 
00075     OutputDebugString(dbgbuf2);
00076     LeaveCriticalSection(&gDebugCritSec);
00077 }
00078 #endif
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 LPWSAPROTOCOL_INFOW 
00087 EnumerateProviders(
00088     WINSOCK_CATALOG Catalog, 
00089     LPINT           TotalProtocols
00090     )
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     
00104     if ( LspCatalog64Only == Catalog )
00105     {
00106         
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         
00116         ProtocolInfo = (LPWSAPROTOCOL_INFOW) LspAlloc(
00117                 ProtocolInfoSize,
00118                &ErrorCode
00119                 );
00120         if (ProtocolInfo == NULL)
00121             goto cleanup;
00122 
00123         
00124         rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode );
00125         if ( SOCKET_ERROR == rc )
00126             goto cleanup;
00127 
00128         
00129         *TotalProtocols = rc;
00130     }
00131     else if ( LspCatalog32Only == Catalog )
00132     {
00133         HMODULE            hModule;
00134         LPWSCENUMPROTOCOLS fnWscEnumProtocols32 = NULL;
00135 
00136         
00137         hModule = LoadLibrary( TEXT( "ws2_32.dll" ) );
00138         if ( NULL == hModule )
00139             goto cleanup;
00140 
00141         
00142         fnWscEnumProtocols32 = (LPWSCENUMPROTOCOLS) GetProcAddress(
00143                 hModule, 
00144                 TEXT( "WSCEnumProtocols32" )
00145                 );
00146         if ( NULL == fnWscEnumProtocols32 )
00147             goto cleanup;
00148         
00149         
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         
00159         ProtocolInfo = (LPWSAPROTOCOL_INFOW) LspAlloc(
00160                 ProtocolInfoSize,
00161                &ErrorCode
00162                 );
00163         if ( NULL == ProtocolInfo )
00164             goto cleanup;
00165 
00166         
00167         rc = fnWscEnumProtocols32( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode );
00168         if ( SOCKET_ERROR == rc )
00169             goto cleanup;
00170 
00171         
00172         *TotalProtocols = rc;
00173 
00174         FreeLibrary( hModule );
00175     }
00176 #else
00177     if ( LspCatalog32Only == Catalog )
00178     {
00179         
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         
00189         ProtocolInfo = (LPWSAPROTOCOL_INFOW) LspAlloc(
00190                 ProtocolInfoSize,
00191                &ErrorCode
00192                 );
00193         if ( NULL == ProtocolInfo )
00194             goto cleanup;
00195 
00196         
00197         rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode );
00198         if ( SOCKET_ERROR == rc )
00199             goto cleanup;
00200 
00201         
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         
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         
00221         ProtocolInfo = (LPWSAPROTOCOL_INFOW) LspAlloc(
00222                 ProtocolInfoSize,
00223                &ErrorCode
00224                 );
00225         if ( NULL == ProtocolInfo )
00226             goto cleanup;
00227 
00228         
00229         rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode );
00230         if ( SOCKET_ERROR == rc )
00231             goto cleanup;
00232 
00233         
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 }
00247 
00248 
00249 
00250 
00251 
00252 
00253 
00254 int
00255 EnumerateProvidersExisting(
00256     WINSOCK_CATALOG     Catalog, 
00257     WSAPROTOCOL_INFOW  *ProtocolInfo,
00258     LPDWORD             ProtocolInfoSize
00259     )
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 }
00291 
00292 
00293 
00294 
00295 
00296 
00297 
00298 void 
00299 FreeProviders(
00300     LPWSAPROTOCOL_INFOW ProtocolInfo
00301     )
00302 {
00303     LspFree( ProtocolInfo );
00304 }
00305 
00306 
00307 
00308 
00309 
00310 
00311 
00312 
00313 void *
00314 LspAlloc(
00315     SIZE_T  size,
00316     int    *lpErrno
00317     )
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 }
00332 
00333 
00334 
00335 
00336 
00337 
00338 
00339 void
00340 LspFree(
00341     LPVOID  buf
00342     )
00343 {
00344     HeapFree( gLspHeap, 0, buf );
00345 }
00346 
00347 
00348 
00349 
00350 
00351 
00352 
00353 int
00354 LspCreateHeap(
00355     int *lpErrno
00356     )
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 }
00366 
00367 
00368 
00369 
00370 
00371 
00372 
00373 void
00374 LspDestroyHeap(
00375     )
00376 {
00377     if ( NULL != gLspHeap )
00378     {
00379         HeapDestroy( gLspHeap );
00380         gLspHeap = NULL;
00381     }
00382 }
00383 
00384 
00385 
00386 
00387 
00388 
00389 
00390 
00391 
00392 
00393 
00394 
00395 
00396 BOOL
00397 FindLspEntries(
00398         PROVIDER  **lspProviders,
00399         int        *lspProviderCount,
00400         int        *lpErrno
00401         )
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     
00415     ProtocolInfo = EnumerateProviders( LspCatalogBoth, &ProtocolCount );
00416     if ( NULL == ProtocolInfo )
00417     {
00418         dbgprint("FindLspEntries; EnumerateProviders failed!");
00419         goto cleanup;
00420     }
00421 
00422     
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     
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     
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     
00460     for(i=0; i < ProtocolCount ;i++)
00461     {
00462         
00463         
00464         
00465         
00466         if ( ( ProtocolInfo[ i ].ProtocolChain.ChainLen > 1 ) &&
00467              ( DummyLspId == ProtocolInfo[ i ].ProtocolChain.ChainEntries[ 0 ] )
00468            )
00469         {
00470             
00471             memcpy( &Providers[ idx ].LayerProvider, &ProtocolInfo[ i ], sizeof(WSAPROTOCOL_INFOW) );
00472             Providers[ idx ].LayerProvider.szProtocol[ WSAPROTOCOL_LEN ] = '\0';
00473 
00474             
00475             for(j=0; j < ProtocolCount ;j++)
00476             {
00477                 
00478                 
00479                 
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             
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 }
00522 
00523 #pragma warning(push)
00524 #pragma warning(disable: 4127)
00525 
00526 
00527 
00528 
00529 
00530 
00531 
00532 
00533 PROVIDER *
00534 FindMatchingLspEntryForProtocolInfo(
00535         WSAPROTOCOL_INFOW *inInfo,
00536         PROVIDER          *lspProviders,
00537         int                lspCount,
00538         BOOL               fromStartup
00539         )
00540 {
00541     WSAPROTOCOL_INFOW  *ProtocolInfo = NULL;
00542     DWORD               hiddenEntryId;
00543     int                 ProtocolCount,
00544                         i, j, k;
00545 
00546     
00547 
00548     
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     
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                 
00567                 
00568                 
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     
00581     
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     
00598     
00599     
00600 
00601     ASSERT( fromStartup );
00602 
00603 #ifndef DBG
00604     UNREFERENCED_PARAMETER( fromStartup );
00605 #endif
00606 
00607     
00608     
00609     
00610     
00611     
00612     
00613     
00614     
00615     
00616     
00617     
00618     
00619     
00620     
00621     
00622     
00623     
00624     
00625     
00626     
00627     
00628     
00629     
00630     
00631     
00632     
00633     
00634     
00635     
00636     
00637     
00638     
00639     
00640     
00641     
00642     
00643     
00644 
00645     
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             
00672             
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                         
00682                         
00683                         
00684                         
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 }
00717 
00718 #pragma warning(pop)
00719 
00720 
00721 
00722 
00723 
00724 
00725 
00726 
00727 BOOL
00728 LoadProviderPath(
00729     PROVIDER    *loadProvider,
00730     int         *lpErrno
00731     )
00732 {
00733     int     rc;
00734 
00735     *lpErrno = 0;
00736 
00737     
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         
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     
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 }
00823 
00824 int
00825 InitializeProvider(
00826         PROVIDER *provider,
00827         WORD wVersion,
00828         WSAPROTOCOL_INFOW *lpProtocolInfo,
00829         WSPUPCALLTABLE UpCallTable,
00830         int *Error
00831         )
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     
00844     
00845     
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     
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     
00877     
00878     
00879     
00880     provider->StartupCount++;
00881 
00882 cleanup:
00883 
00884     return rc;
00885 }
00886 
00887 
00888 
00889 
00890 
00891 
00892 
00893 
00894 int 
00895 VerifyProcTable(
00896     LPWSPPROC_TABLE lpProcTable
00897     )
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 }
00934