00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #include "instlsp.h"
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 int
00031 InstallLsp(
00032 WINSOCK_CATALOG eCatalog,
00033 __in_z char *lpszLspName,
00034 __in_z char *lpszLspPathAndFile,
00035 DWORD dwCatalogIdArrayCount,
00036 DWORD *pdwCatalogIdArray,
00037 BOOL IfsProvider,
00038 BOOL InstallOverAll
00039 )
00040 {
00041 OSVERSIONINFOEX osv = {0};
00042 WSAPROTOCOL_INFOW *pProtocolInfo = NULL,
00043 *pDummyEntry = NULL,
00044 *pLayeredEntries = NULL;
00045 WCHAR wszLspName[ WSAPROTOCOL_LEN ],
00046 wszFullProviderPath[ MAX_PATH+1 ];
00047 GUID ProviderBaseGuid;
00048 INT rc = SOCKET_ERROR;
00049
00050
00051
00052
00053
00054
00055 if ( NULL == lpszLspName )
00056 {
00057 lpszLspName = DEFAULT_LSP_NAME;
00058 }
00059
00060
00061 rc = MultiByteToWideChar(
00062 CP_ACP,
00063 0,
00064 lpszLspName,
00065 (int) strlen( lpszLspName ) + 1,
00066 wszLspName,
00067 WSAPROTOCOL_LEN
00068 );
00069 if (rc == 0)
00070 {
00071 fprintf(stderr, "InstallLsp: MultiByteToWideChar failed to convert '%s'; Error = %d\n",
00072 lpszLspName, GetLastError());
00073 goto cleanup;
00074 }
00075
00076 rc = MultiByteToWideChar(
00077 CP_ACP,
00078 0,
00079 lpszLspPathAndFile,
00080 (int) strlen( lpszLspPathAndFile ) + 1,
00081 wszFullProviderPath,
00082 MAX_PATH
00083 );
00084 if ( 0 == rc )
00085 {
00086 fprintf( stderr, "InstallLsp: MultiByteToWidechar failed to convert '%s': Error = %d\n",
00087 lpszLspPathAndFile, GetLastError() );
00088 goto cleanup;
00089 }
00090
00091
00092 if ( 0 == dwCatalogIdArrayCount )
00093 {
00094 fprintf(stderr, "InstallLsp: Error! Must specify at least one provider to layer over!\n\n");
00095 goto cleanup;
00096 }
00097
00098 printf("LSP name is '%S'\n", wszLspName);
00099
00100
00101 RetrieveLspGuid( lpszLspPathAndFile, &ProviderBaseGuid );
00102
00103 osv.dwOSVersionInfoSize = sizeof(osv);
00104 GetVersionEx( (LPOSVERSIONINFO) &osv );
00105
00106 if ( osv.dwMajorVersion >= 6 )
00107 {
00108
00109
00110 rc = InstallProviderVista(
00111 eCatalog,
00112 wszLspName,
00113 wszFullProviderPath,
00114 &ProviderBaseGuid,
00115 dwCatalogIdArrayCount,
00116 pdwCatalogIdArray,
00117 IfsProvider,
00118 InstallOverAll
00119 );
00120 if ( SOCKET_ERROR == rc )
00121 {
00122 goto cleanup;
00123 }
00124
00125 }
00126 else
00127 {
00128
00129
00130
00131
00132
00133 pDummyEntry = CreateDummyEntry( eCatalog, pdwCatalogIdArray[ 0 ], wszLspName, IfsProvider );
00134 if (pDummyEntry == NULL)
00135 {
00136 fprintf(stderr, "InstallLsp: CreateDummyEntry failed!\n");
00137 goto cleanup;
00138 }
00139
00140
00141 rc = InstallProvider(
00142 eCatalog,
00143 &ProviderBaseGuid,
00144 wszFullProviderPath,
00145 pDummyEntry,
00146 1
00147 );
00148 if ( NO_ERROR != rc )
00149 {
00150 fprintf(stderr, "InstallLsp: Unable to install the dummy LSP entry!\n");
00151 goto cleanup;
00152 }
00153
00154
00155 LspFree( pDummyEntry );
00156 pDummyEntry = NULL;
00157
00158 if ( FALSE == IfsProvider )
00159 {
00160 rc = InstallNonIfsLspProtocolChains( eCatalog, &ProviderBaseGuid, wszLspName,
00161 wszFullProviderPath, pdwCatalogIdArray, dwCatalogIdArrayCount );
00162
00163 }
00164 else
00165 {
00166 rc = InstallIfsLspProtocolChains( eCatalog, &ProviderBaseGuid, wszLspName,
00167 wszFullProviderPath, pdwCatalogIdArray, dwCatalogIdArrayCount );
00168 }
00169
00170 if ( SOCKET_ERROR == rc )
00171 {
00172
00173 DeinstallProvider( eCatalog, &ProviderBaseGuid );
00174 }
00175
00176 }
00177
00178 cleanup:
00179
00180 if ( NULL != pProtocolInfo )
00181 FreeProviders( pProtocolInfo );
00182
00183 if ( NULL != pDummyEntry )
00184 LspFree( pDummyEntry );
00185
00186 if ( NULL != pLayeredEntries )
00187 LspFree( pLayeredEntries );
00188
00189 return rc;
00190 }
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 int
00201 InstallProvider(
00202 WINSOCK_CATALOG Catalog,
00203 GUID *Guid,
00204 WCHAR *lpwszLspPath,
00205 WSAPROTOCOL_INFOW *pProvider,
00206 INT iProviderCount
00207 )
00208 {
00209 WSAPROTOCOL_INFOW *pEnumProviders = NULL,
00210 *pEntry = NULL;
00211 INT iEnumProviderCount,
00212 ErrorCode,
00213 rc = SOCKET_ERROR;
00214
00215 #ifdef _WIN64
00216 if ( LspCatalog32Only == Catalog )
00217 {
00218
00219 fprintf( stderr, "InstallProvider: Error! It is not possible to install only "
00220 "in 32-bit catalog from 64-bit process!\n\n"
00221 );
00222 goto cleanup;
00223 }
00224 else if ( LspCatalog64Only == Catalog )
00225 {
00226
00227 rc = WSCInstallProvider(
00228 Guid,
00229 lpwszLspPath,
00230 pProvider,
00231 iProviderCount,
00232 &ErrorCode
00233 );
00234 }
00235 else
00236 {
00237
00238 rc = WSCInstallProvider64_32(
00239 Guid,
00240 lpwszLspPath,
00241 pProvider,
00242 iProviderCount,
00243 &ErrorCode
00244 );
00245 }
00246 #else
00247 if ( LspCatalog32Only == Catalog )
00248 {
00249
00250 rc = WSCInstallProvider(
00251 Guid,
00252 lpwszLspPath,
00253 pProvider,
00254 iProviderCount,
00255 &ErrorCode
00256 );
00257 }
00258 else
00259 {
00260
00261 fprintf( stderr, "InstallProvider: Error! It is not possible to install into "
00262 "the 64-bit catalog from a 32-bit process!\n\n"
00263 );
00264 goto cleanup;
00265 }
00266 #endif
00267 if ( SOCKET_ERROR == rc )
00268 {
00269 fprintf( stderr, "InstallProvider: WSCInstallProvider* failed: %d\n", ErrorCode );
00270 goto cleanup;
00271 }
00272
00273
00274 pEnumProviders = EnumerateProviders( Catalog, &iEnumProviderCount );
00275 if ( NULL == pEnumProviders )
00276 {
00277 fprintf( stderr, "InstallProvider: EnumerateProviders failed!\n" );
00278 goto cleanup;
00279 }
00280
00281
00282 pEntry = FindProviderByGuid( Guid, pEnumProviders, iEnumProviderCount );
00283 if ( pEntry )
00284 {
00285 printf( "Installed: [%4d] %S\n",
00286 pEntry->dwCatalogEntryId,
00287 pEntry->szProtocol
00288 );
00289 }
00290
00291 cleanup:
00292
00293 if ( NULL != pEnumProviders )
00294 FreeProviders( pEnumProviders );
00295
00296 return rc;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308 WSAPROTOCOL_INFOW *
00309 CreateDummyEntry(
00310 WINSOCK_CATALOG Catalog,
00311 INT CatalogId,
00312 WCHAR *lpwszLspName,
00313 BOOL IfsProvider
00314 )
00315 {
00316 WSAPROTOCOL_INFOW *pProtocolInfo = NULL,
00317 *pDummyEntry = NULL,
00318 *pEntry = NULL;
00319 INT iProtocolCount = 0;
00320 int err;
00321
00322
00323 pProtocolInfo = EnumerateProviders( Catalog, &iProtocolCount );
00324 if ( NULL == pProtocolInfo )
00325 {
00326 fprintf(stderr, "CreateDummyEntry: EnumerateProviders failed!\n");
00327 goto cleanup;
00328 }
00329
00330
00331 pEntry = FindProviderById( CatalogId, pProtocolInfo, iProtocolCount );
00332 if ( pEntry )
00333 {
00334
00335 pDummyEntry = (WSAPROTOCOL_INFOW *) LspAlloc(
00336 sizeof( WSAPROTOCOL_INFOW ),
00337 &err
00338 );
00339 if ( NULL == pDummyEntry )
00340 {
00341 fprintf( stderr, "CreateDummyEntry: LspAlloc failed: %d\n", err );
00342 goto cleanup;
00343 }
00344
00345
00346 memcpy( pDummyEntry, pEntry, sizeof( WSAPROTOCOL_INFOW ) );
00347 }
00348 else
00349 {
00350 fprintf(stderr, "CreateDummyEntry: Error! Unable to find provider with ID of %d\n\n",
00351 CatalogId
00352 );
00353 goto cleanup;
00354 }
00355
00356
00357 if ( FALSE == IfsProvider )
00358 pDummyEntry->dwServiceFlags1 &= (~XP1_IFS_HANDLES);
00359
00360
00361 pDummyEntry->iSocketType = 0;
00362 pDummyEntry->iProtocol = 0;
00363 pDummyEntry->dwProviderFlags |= PFL_HIDDEN;
00364 pDummyEntry->dwProviderFlags &= (~PFL_MATCHES_PROTOCOL_ZERO);
00365 pDummyEntry->ProtocolChain.ChainLen = LAYERED_PROTOCOL;
00366
00367
00368 wcsncpy( pDummyEntry->szProtocol, lpwszLspName, WSAPROTOCOL_LEN );
00369
00370 cleanup:
00371
00372 if ( NULL != pProtocolInfo )
00373 FreeProviders( pProtocolInfo );
00374
00375 return pDummyEntry;
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395 int
00396 InstallIfsLspProtocolChains(
00397 WINSOCK_CATALOG eCatalog,
00398 GUID *Guid,
00399 WCHAR *lpszLspName,
00400 WCHAR *lpszLspFullPathAndFile,
00401 DWORD *pdwCatalogIdArray,
00402 DWORD dwCatalogIdArrayCount
00403 )
00404 {
00405 WSAPROTOCOL_INFOW *pProvider = NULL,
00406 *pProviderNew = NULL,
00407 *pLayeredEntries = NULL,
00408 *pEntry = NULL,
00409 TempEntry = {0};
00410 DWORD *pProviderOrder = NULL,
00411 dwDummyLspId;
00412 WCHAR wszLspDll[ MAX_PATH ];
00413 BOOL bLayeredOverNonIfs = FALSE,
00414 bContainsNonIfs = FALSE;
00415 HRESULT hr;
00416 int ProviderPathLen = MAX_PATH-1,
00417 iProviderCount,
00418 iProviderCountNew,
00419 LayerIdx,
00420 retval = SOCKET_ERROR,
00421 err,
00422 idx,
00423 rc,
00424 i, j, k;
00425
00426
00427 pProvider = EnumerateProviders( eCatalog, &iProviderCount );
00428 if ( NULL == pProvider )
00429 {
00430 fprintf( stderr, "InstallIfsLspProtocolChains: Unable to enumerate catalog\n" );
00431 goto cleanup;
00432 }
00433
00434
00435 dwDummyLspId = GetCatalogIdForProviderGuid( Guid, pProvider, iProviderCount );
00436
00437 ASSERT( dwDummyLspId != 0 );
00438
00439
00440 pLayeredEntries = (WSAPROTOCOL_INFOW *) LspAlloc( sizeof(WSAPROTOCOL_INFOW) *
00441 dwCatalogIdArrayCount, &err );
00442 if ( NULL == pLayeredEntries )
00443 {
00444 fprintf( stderr, "InstallIfsLspProtocolChains: LspAlloc failed: %d\n", err );
00445 goto cleanup;
00446 }
00447
00448 LayerIdx = 0;
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458 for(i=0; i < (int)dwCatalogIdArrayCount ;i++)
00459 {
00460 for(j=0; j < iProviderCount ;j++)
00461 {
00462 printf("Matching selected ID %d to catalog %d\n",
00463 pdwCatalogIdArray[ i ], pProvider[ j ].dwCatalogEntryId );
00464
00465 if ( pdwCatalogIdArray[ i ] == pProvider[ j ].dwCatalogEntryId )
00466 {
00467
00468 if ( pProvider[ j ].ProtocolChain.ChainLen >= ( MAX_PROTOCOL_CHAIN - 1 ) )
00469 {
00470 fprintf( stderr, "InstallIfsLspProtocolChain: Too many LSPs installed!\n");
00471 goto cleanup;
00472 }
00473
00474
00475 memcpy( &pLayeredEntries[ LayerIdx ], &pProvider[ j ],
00476 sizeof( pLayeredEntries[ 0 ] ) );
00477
00478 memcpy( &TempEntry, &pProvider[ j ], sizeof( TempEntry ) );
00479
00480
00481 hr = StringCchPrintfW( pLayeredEntries[ LayerIdx ].szProtocol, WSAPROTOCOL_LEN,
00482 L"%s over [%s]",
00483 lpszLspName,
00484 pProvider[ j ].szProtocol
00485 );
00486 if ( FAILED( hr ) )
00487 {
00488 fprintf( stderr, "InstallIfsLspProtocolChains: StringCchPrintfW failed: 0x%x\n", hr );
00489 goto cleanup;
00490 }
00491
00492
00493 if ( pProvider[ j ].ProtocolChain.ChainLen >= 2 )
00494 {
00495 for(k=pProvider[ j ].ProtocolChain.ChainLen-2 ; k >= 0 ;k--)
00496 {
00497 bContainsNonIfs = IsNonIfsProvider( pProvider, iProviderCount,
00498 pProvider[ j ].ProtocolChain.ChainEntries[ k ] );
00499
00500 if ( TRUE == bContainsNonIfs )
00501 {
00502
00503
00504
00505
00506 InsertIdIntoProtocolChain( &pProvider[ j ], k+1, UPDATE_LSP_ENTRY );
00507
00508
00509 pProvider[ j ].dwProviderReserved = LayerIdx + 1;
00510
00511
00512 BuildSubsetLspChain( &pLayeredEntries[ LayerIdx ], k+1, dwDummyLspId );
00513
00514 pLayeredEntries[ LayerIdx ].dwServiceFlags1 |= XP1_IFS_HANDLES;
00515
00516 bLayeredOverNonIfs = TRUE;
00517
00518
00519
00520 InsertIfsLspIntoAllChains( &TempEntry, pProvider, iProviderCount,
00521 LayerIdx + 1, k );
00522
00523 break;
00524 }
00525 }
00526 }
00527
00528
00529
00530 if ( TRUE != bContainsNonIfs )
00531 {
00532 InsertIdIntoProtocolChain( &pLayeredEntries[ LayerIdx ], 0, dwDummyLspId );
00533
00534
00535
00536
00537
00538 pLayeredEntries[ LayerIdx ].ProtocolChain.ChainEntries[ 1 ] =
00539 TempEntry.dwCatalogEntryId;
00540
00541 pLayeredEntries[ LayerIdx ].dwServiceFlags1 |= XP1_IFS_HANDLES;
00542 }
00543
00544 LayerIdx++;
00545 }
00546 }
00547 }
00548
00549 ASSERT( LayerIdx == (int)dwCatalogIdArrayCount );
00550
00551
00552 for(i=0;i < (int)dwCatalogIdArrayCount ;i++)
00553 {
00554 if ( RPC_S_OK != UuidCreate( &pLayeredEntries[ i ].ProviderId ) )
00555 {
00556 fprintf(stderr, "InstallIfsLspProtocolChains: UuidCreate failed: %d\n", GetLastError());
00557 goto cleanup;
00558 }
00559
00560 rc = InstallProvider( eCatalog, &pLayeredEntries[ i ].ProviderId,
00561 lpszLspFullPathAndFile, &pLayeredEntries[ i ], 1 );
00562 if ( NO_ERROR != rc )
00563 {
00564 fprintf(stderr, "InstallIfsLspProtocolChains: Unable to install the dummy LSP entry!\n");
00565 goto cleanup;
00566 }
00567 }
00568
00569 if ( TRUE == bLayeredOverNonIfs )
00570 {
00571
00572
00573 pProviderNew = EnumerateProviders( eCatalog, &iProviderCountNew );
00574 if ( NULL == pProviderNew )
00575 {
00576 fprintf( stderr, "InstallIfsLspProtocolChains: Unable to enumerate catalog\n" );
00577 goto cleanup;
00578 }
00579
00580 for(i=0; i < (int)dwCatalogIdArrayCount ;i++)
00581 {
00582 pLayeredEntries[ i ].dwCatalogEntryId = GetCatalogIdForProviderGuid(
00583 &pLayeredEntries[ i ].ProviderId,
00584 pProviderNew,
00585 iProviderCountNew
00586 );
00587
00588 ASSERT( pLayeredEntries[ i ].dwCatalogEntryId != 0 );
00589 }
00590
00591
00592
00593 for(i=0; i < iProviderCount ;i++)
00594 {
00595 if ( pProvider[ i ].dwProviderReserved == 0 )
00596 continue;
00597
00598 for(j=0; j < pProvider[ i ].ProtocolChain.ChainLen ;j++)
00599 {
00600 if ( UPDATE_LSP_ENTRY == pProvider[ i ].ProtocolChain.ChainEntries[ j ] )
00601 {
00602 pProvider[ i ].ProtocolChain.ChainEntries[ j ] =
00603 pLayeredEntries[ pProvider[ i ].dwProviderReserved - 1 ].dwCatalogEntryId;
00604
00605 pProvider[ i ].dwProviderReserved = 0;
00606 }
00607 }
00608
00609
00610 ProviderPathLen = MAX_PATH-1;
00611 rc = WSCGetProviderPath(
00612 &pProvider[ i ].ProviderId,
00613 wszLspDll,
00614 &ProviderPathLen,
00615 &err
00616 );
00617 if ( SOCKET_ERROR == rc )
00618 {
00619 fprintf( stderr, "InstallIfsLspProtocolChains: WSCGetProviderPath failed: %d\n", err );
00620 goto cleanup;
00621 }
00622
00623
00624 rc = UpdateProvider( eCatalog, &pProvider[ i ].ProviderId,
00625 wszLspDll, &pProvider[ i ], 1, &err );
00626 if ( SOCKET_ERROR == rc )
00627 {
00628 fprintf( stderr, "InstallIfsLspProtocolChains: UpdateProvider failed: %d\n", err );
00629 goto cleanup;
00630 }
00631
00632 printf("Updated entry ID: %d: %S (chain len = %d)\n",
00633 pProvider[ i ].dwCatalogEntryId,
00634 pProvider[ i ].szProtocol,
00635 pProvider[ i ].ProtocolChain.ChainLen
00636 );
00637 }
00638
00639 FreeProviders( pProvider );
00640 pProvider = NULL;
00641
00642 FreeProviders( pProviderNew );
00643 pProviderNew = NULL;
00644
00645
00646
00647
00648
00649 {
00650 WSADATA wsd;
00651
00652 WSACleanup();
00653
00654 WSAStartup( MAKEWORD(2,2), &wsd );
00655 }
00656
00657
00658 pProvider = EnumerateProviders( eCatalog, &iProviderCount );
00659 if ( NULL == pProvider )
00660 {
00661 fprintf( stderr, "InstallIfsLspProtocolChains: Unable to enumerate catalog\n" );
00662 goto cleanup;
00663 }
00664
00665
00666 pProviderOrder = (DWORD *)LspAlloc( iProviderCount * sizeof(DWORD), &err );
00667 if ( NULL == pProviderOrder )
00668 {
00669 fprintf( stderr, "InstallIfsLspProtocolChains: Unable to enumerate catalog\n" );
00670 goto cleanup;
00671 }
00672
00673
00674 idx = 0;
00675 for(i=0; i < (int)dwCatalogIdArrayCount ;i++)
00676 {
00677 pEntry = FindProviderById( pdwCatalogIdArray[ i ], pProvider, iProviderCount );
00678 if ( NULL == pEntry )
00679 {
00680 fprintf(stderr, "InstallIfsLspProtocolChain: Unable to find entry to reorder catalog!\n");
00681 goto cleanup;
00682 }
00683
00684 pEntry->dwProviderReserved = 1;
00685
00686 pProviderOrder[ idx++ ] = pEntry->dwCatalogEntryId;
00687 }
00688
00689
00690
00691 for(i=0; i < (int)dwCatalogIdArrayCount ;i++)
00692 {
00693 pEntry = FindProviderById( pdwCatalogIdArray[ i ], pProvider, iProviderCount );
00694 if ( NULL == pEntry )
00695 {
00696 fprintf(stderr, "InstallIfsLspProtocolChain: Unable to find entry to reorder catalog!\n");
00697 goto cleanup;
00698 }
00699
00700 printf("Looping through: %d: %S (chain len = %d)\n",
00701 pEntry->dwCatalogEntryId,
00702 pEntry->szProtocol,
00703 pEntry->ProtocolChain.ChainLen );
00704
00705 for(j=1; j < pEntry->ProtocolChain.ChainLen-1 ;j++)
00706 {
00707 dwDummyLspId = FindDummyIdFromProtocolChainId(
00708 pEntry->ProtocolChain.ChainEntries[ j ],
00709 pProvider,
00710 iProviderCount
00711 );
00712
00713 printf(" Finding dummy ID for chain entry: %d is %d\n",
00714 pEntry->ProtocolChain.ChainEntries[ j ],
00715 dwDummyLspId
00716 );
00717
00718 for(k=0; k < iProviderCount ;k++)
00719 {
00720 if ( ( pProvider[ k ].ProtocolChain.ChainLen >= 2 ) &&
00721 ( pProvider[ k ].ProtocolChain.ChainEntries[ 0 ] == dwDummyLspId ) &&
00722 ( pProvider[ k ].dwProviderReserved == 0 )
00723 )
00724 {
00725 pProviderOrder[ idx++ ] = pProvider[ k ].dwCatalogEntryId;
00726 pProvider[ k ].dwProviderReserved = 1;
00727
00728 printf(" Adding: %d\n", pProvider[ k ].dwCatalogEntryId );
00729 }
00730 }
00731 }
00732 }
00733
00734
00735 for(i=0; i < iProviderCount ;i++)
00736 {
00737 if ( pProvider[ i ].dwProviderReserved == 0 )
00738 pProviderOrder[ idx++ ] = pProvider[ i ].dwCatalogEntryId;
00739 }
00740
00741 ASSERT( idx == iProviderCount );
00742
00743
00744 rc = WriteProviderOrder( eCatalog, pProviderOrder, iProviderCount, &err );
00745 if ( NO_ERROR != rc )
00746 {
00747 fprintf( stderr, "InstallIfsLspProtocolChains: WriteProviderOrder failed: %d\n",
00748 err );
00749 goto cleanup;
00750 }
00751 }
00752 else
00753 {
00754
00755
00756
00757
00758
00759 rc = ReorderCatalog( eCatalog, dwDummyLspId );
00760 if ( NO_ERROR != rc )
00761 {
00762 fprintf(stderr, "InstallIfsLspProtocolChains: Unable to reorder Winsock catalog!\n");
00763 goto cleanup;
00764 }
00765 }
00766
00767 retval = NO_ERROR;
00768
00769 cleanup:
00770
00771 if ( NULL != pProvider )
00772 {
00773 FreeProviders( pProvider );
00774 pProvider = NULL;
00775 }
00776
00777 if ( NULL != pProviderNew )
00778 {
00779 FreeProviders( pProviderNew );
00780 pProviderNew = NULL;
00781 }
00782
00783 if ( NULL != pProviderOrder )
00784 {
00785 LspFree( pProviderOrder );
00786 pProviderOrder = NULL;
00787 }
00788
00789 return retval;
00790 }
00791
00792
00793
00794
00795
00796
00797
00798
00799
00800
00801 int
00802 InstallNonIfsLspProtocolChains(
00803 WINSOCK_CATALOG eCatalog,
00804 GUID *Guid,
00805 WCHAR *lpszLspName,
00806 WCHAR *lpszLspFullPathAndFile,
00807 DWORD *pdwCatalogIdArray,
00808 DWORD dwCatalogIdArrayCount
00809 )
00810 {
00811 WSAPROTOCOL_INFOW *pProvider = NULL,
00812 *pLayeredEntries = NULL;
00813 DWORD dwDummyLspId = 0;
00814 INT iProviderCount = 0,
00815 retval = SOCKET_ERROR,
00816 idx,
00817 err,
00818 rc,
00819 i, j;
00820 HRESULT hr;
00821
00822
00823 pProvider = EnumerateProviders( eCatalog, &iProviderCount );
00824 if ( NULL == pProvider )
00825 {
00826 fprintf( stderr, "InstallNonIfsLspProtocolChain: Unable to enumerate catalog\n" );
00827 goto cleanup;
00828 }
00829
00830 pLayeredEntries = (WSAPROTOCOL_INFOW *) LspAlloc( sizeof(WSAPROTOCOL_INFOW) *
00831 dwCatalogIdArrayCount, &err );
00832 if ( NULL == pLayeredEntries )
00833 {
00834 fprintf( stderr, "InstallNonIfsLspProtocolChain: LspAlloc failed: %d\n", err );
00835 goto cleanup;
00836 }
00837
00838
00839 dwDummyLspId = GetCatalogIdForProviderGuid( Guid, pProvider, iProviderCount );
00840
00841 ASSERT( dwDummyLspId != 0 );
00842
00843
00844 idx = 0;
00845 for(i=0; i < iProviderCount ;i++)
00846 {
00847 for(j=0; j < (int) dwCatalogIdArrayCount ;j++)
00848 {
00849 if ( pProvider[ i ].dwCatalogEntryId == pdwCatalogIdArray[ j ] )
00850 {
00851 if ( pProvider[ i ].ProtocolChain.ChainLen >= ( MAX_PROTOCOL_CHAIN - 1 ) )
00852 {
00853 fprintf( stderr, "InstallNonIfsLspProtocolchain: Too many LSPs installed!\n");
00854 goto cleanup;
00855 }
00856
00857 memcpy( &pLayeredEntries[ idx ], &pProvider[ i ], sizeof( WSAPROTOCOL_INFOW ) );
00858
00859
00860 hr = StringCchPrintfW( pLayeredEntries[ idx ].szProtocol, WSAPROTOCOL_LEN,
00861 L"%s over [%s]",
00862 lpszLspName,
00863 pProvider[ i ].szProtocol
00864 );
00865 if ( FAILED( hr ) )
00866 {
00867 fprintf( stderr, "InstallNonIfsLspProtocolChain: StringCchPrintfW failed: 0x%x\n", hr );
00868 goto cleanup;
00869 }
00870
00871
00872
00873 InsertIdIntoProtocolChain( &pLayeredEntries[ idx ], 0, dwDummyLspId );
00874
00875
00876
00877
00878
00879 pLayeredEntries[ idx ].ProtocolChain.ChainEntries[ 1 ] =
00880 pProvider[ i ].dwCatalogEntryId;
00881
00882
00883 pLayeredEntries[ idx ].dwServiceFlags1 &= (~XP1_IFS_HANDLES);
00884
00885 idx++;
00886 }
00887 }
00888 }
00889
00890 for(i=0; i < (int)dwCatalogIdArrayCount ;i++)
00891 {
00892
00893 if ( UuidCreate( &pLayeredEntries[ i ].ProviderId ) != RPC_S_OK )
00894 {
00895 fprintf(stderr, "InstallNonIfsLspProtocolChains: UuidCreate failed: %d\n", GetLastError());
00896 goto cleanup;
00897 }
00898
00899
00900 rc = InstallProvider(
00901 eCatalog,
00902 &pLayeredEntries[ i ].ProviderId,
00903 lpszLspFullPathAndFile,
00904 &pLayeredEntries[ i ],
00905 1
00906 );
00907 if ( NO_ERROR != rc )
00908 {
00909 fprintf(stderr, "InstallNonIfsLspProtocolChains: Unable to install layered chain entries!\n");
00910 goto cleanup;
00911 }
00912 }
00913
00914
00915 rc = ReorderCatalog( eCatalog, dwDummyLspId );
00916 if ( NO_ERROR != rc )
00917 {
00918 fprintf(stderr, "InstallNonIfsLspProtocolChains: Unable to reorder Winsock catalog!\n");
00919 goto cleanup;
00920 }
00921
00922 retval = NO_ERROR;
00923
00924 cleanup:
00925
00926 if ( NULL != pProvider )
00927 FreeProviders( pProvider );
00928
00929 if ( NULL != pLayeredEntries )
00930 LspFree( pLayeredEntries );
00931
00932 return retval;
00933 }
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944
00945
00946 int
00947 InsertIfsLspIntoAllChains(
00948 WSAPROTOCOL_INFOW *OriginalEntry,
00949 WSAPROTOCOL_INFOW *Catalog,
00950 int CatalogCount,
00951 int IfsEntryIdx,
00952 int ChainIdx
00953 )
00954 {
00955 WSAPROTOCOL_INFOW TempEntry = {0};
00956 int Idx, i, j, k;
00957
00958 for(i=ChainIdx; i > 0 ;i--)
00959 {
00960 #ifdef DBG
00961 printf( "Looking for entry: %d\n", OriginalEntry->ProtocolChain.ChainEntries[ i ] );
00962 #endif
00963
00964 for(j=0; j < CatalogCount ;j++)
00965 {
00966 if ( Catalog[ j ].dwCatalogEntryId == OriginalEntry->ProtocolChain.ChainEntries[ i ] )
00967 {
00968 printf( "Found match: %ws\n", Catalog[ j ].szProtocol );
00969 Idx = j;
00970
00971 if ( Catalog[ j ].ProtocolChain.ChainLen == LAYERED_PROTOCOL )
00972 {
00973 Idx = -1;
00974
00975
00976
00977
00978 for(k=0; k < CatalogCount ;k++)
00979 {
00980 if ( ( OriginalEntry->iAddressFamily == Catalog[ k ].iAddressFamily ) &&
00981 ( OriginalEntry->iSocketType == Catalog[ k ].iSocketType ) &&
00982 ( OriginalEntry->iProtocol == Catalog[ k ].iProtocol ) &&
00983 ( (i+1) == Catalog[ k ].ProtocolChain.ChainLen )
00984 )
00985 {
00986 Idx = k;
00987 break;
00988 }
00989 }
00990 }
00991
00992 if ( Idx != -1 )
00993 {
00994
00995 memcpy( &TempEntry, &Catalog[ Idx ], sizeof( TempEntry ) );
00996
00997 if ( Catalog[ Idx ].ProtocolChain.ChainLen >= 2 )
00998 {
00999 for(k=Catalog[ Idx ].ProtocolChain.ChainLen-2 ; k >= 0 ;k--)
01000 {
01001 if ( TRUE == IsNonIfsProvider( Catalog, CatalogCount,
01002 Catalog[ Idx ].ProtocolChain.ChainEntries[ k ] ) )
01003 {
01004
01005 InsertIdIntoProtocolChain( &Catalog[ Idx ], k+1, UPDATE_LSP_ENTRY );
01006
01007
01008 Catalog[ Idx ].dwProviderReserved = IfsEntryIdx;
01009 }
01010 }
01011 }
01012 }
01013 else
01014 {
01015 printf( "????? Index not found ????\n" );
01016 }
01017
01018 break;
01019 }
01020 }
01021 }
01022
01023 return 0;
01024 }
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035 int
01036 ReorderCatalog(
01037 WINSOCK_CATALOG Catalog,
01038 DWORD dwLayeredId
01039 )
01040 {
01041 DWORD *pdwProtocolOrder = NULL;
01042 INT iProviderCount,
01043 ErrorCode,
01044 rc = SOCKET_ERROR;
01045
01046 #ifdef _WIN64
01047 if ( ( LspCatalog32Only == Catalog ) || ( LspCatalogBoth == Catalog ) )
01048 {
01049 printf("Reordering 32-bit Winsock catalog...\n");
01050 pdwProtocolOrder = ReorderACatalog(
01051 LspCatalog32Only,
01052 dwLayeredId,
01053 &iProviderCount
01054 );
01055 if ( NULL == pdwProtocolOrder )
01056 {
01057 fprintf( stderr, "ReorderCatalog: ReorderACatalog failed!\n" );
01058 goto cleanup;
01059 }
01060
01061 rc = WriteProviderOrder( LspCatalog32Only, pdwProtocolOrder, iProviderCount, &ErrorCode );
01062 if ( SOCKET_ERROR == rc )
01063 {
01064 fprintf( stderr, "ReorderCatalog: Reorder of 32-bit catalog failed: %d\n", rc );
01065 }
01066 }
01067 if ( ( LspCatalog64Only == Catalog ) || ( LspCatalogBoth == Catalog ) )
01068 {
01069 printf("Reordering 64-bit Winsock catalog...\n");
01070 pdwProtocolOrder = ReorderACatalog(
01071 LspCatalog64Only,
01072 dwLayeredId,
01073 &iProviderCount
01074 );
01075 if ( NULL == pdwProtocolOrder )
01076 {
01077 fprintf(stderr, "ReorderCatalog: ReorderACatalog failed!\n");
01078 goto cleanup;
01079 }
01080
01081 rc = WriteProviderOrder( LspCatalog64Only, pdwProtocolOrder, iProviderCount, &ErrorCode );
01082 if ( SOCKET_ERROR == rc )
01083 {
01084 fprintf(stderr, "ReorderCatalog: Reorder of 64-bit catalog failed: %d\n", rc);
01085 }
01086 }
01087 #else
01088 if ( ( LspCatalog32Only == Catalog ) || ( LspCatalogBoth == Catalog ) )
01089 {
01090 printf("Reordering 32-bit Winsock catalog...\n");
01091 pdwProtocolOrder = ReorderACatalog(
01092 LspCatalog32Only,
01093 dwLayeredId,
01094 &iProviderCount
01095 );
01096 if ( NULL == pdwProtocolOrder )
01097 {
01098 fprintf( stderr, "ReorderCatalog: ReorderACatalog failed!\n" );
01099 goto cleanup;
01100 }
01101
01102 rc = WriteProviderOrder( LspCatalog32Only, pdwProtocolOrder, iProviderCount, &ErrorCode );
01103 if ( SOCKET_ERROR == rc )
01104 {
01105 fprintf(stderr, "ReorderCatalog: Reorder of 32-bit catalog failed: %d\n", rc);
01106 }
01107 }
01108 #endif
01109
01110 cleanup:
01111
01112 if ( NULL != pdwProtocolOrder )
01113 LspFree( pdwProtocolOrder );
01114
01115 return rc;
01116 }
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127 DWORD *
01128 ReorderACatalog(
01129 WINSOCK_CATALOG Catalog,
01130 DWORD dwLayerId,
01131 INT *dwEntryCount
01132 )
01133 {
01134 WSAPROTOCOL_INFOW *pProvider = NULL;
01135 DWORD *pdwProtocolOrder = NULL;
01136 INT iProviderCount = 0,
01137 idx,
01138 err,
01139 i;
01140
01141
01142 if ( ( NULL == dwEntryCount ) || ( LspCatalogBoth == Catalog ) )
01143 return NULL;
01144
01145
01146 pProvider = EnumerateProviders( Catalog, &iProviderCount );
01147 if ( NULL == pProvider )
01148 {
01149 fprintf( stderr, "ReorderACatalog: Unable to enumerate Winsock catalog!\n" );
01150 goto cleanup;
01151 }
01152
01153
01154 pdwProtocolOrder = (DWORD *) LspAlloc(
01155 sizeof( DWORD ) * iProviderCount,
01156 &err
01157 );
01158 if ( NULL == pdwProtocolOrder )
01159 {
01160 fprintf(stderr, "ReorderACatalog: LspAlloc failed: %d\n", GetLastError());
01161 goto cleanup;
01162 }
01163
01164 idx = 0;
01165
01166
01167 for(i=0; i < iProviderCount ;i++)
01168 {
01169 if ( TRUE == IsIdInChain( &pProvider[ i ], dwLayerId ) )
01170 {
01171 pdwProtocolOrder[ idx++ ] = pProvider[ i ].dwCatalogEntryId;
01172 }
01173 }
01174
01175
01176 for(i=0; i < iProviderCount ;i++)
01177 {
01178 if ( FALSE == IsIdInChain( &pProvider[ i ], dwLayerId ) )
01179 {
01180 pdwProtocolOrder[ idx++ ] = pProvider[ i ].dwCatalogEntryId;
01181 }
01182 }
01183
01184 cleanup:
01185
01186 if (pProvider)
01187 FreeProviders(pProvider);
01188
01189
01190 *dwEntryCount = iProviderCount;
01191
01192
01193 return pdwProtocolOrder;
01194 }
01195
01196
01197
01198
01199
01200
01201
01202
01203
01204 int
01205 WriteProviderOrder(
01206 WINSOCK_CATALOG Catalog,
01207 DWORD *pdwCatalogOrder,
01208 DWORD dwNumberOfEntries,
01209 INT *lpErrno
01210 )
01211 {
01212 int rc = NO_ERROR;
01213
01214 #ifdef _WIN64
01215 if ( LspCatalog32Only == Catalog )
01216 {
01217 rc = WSCWriteProviderOrder32( pdwCatalogOrder, dwNumberOfEntries );
01218 }
01219 else if ( LspCatalog64Only == Catalog )
01220 {
01221 rc = WSCWriteProviderOrder( pdwCatalogOrder, dwNumberOfEntries );
01222 }
01223 #else
01224 if ( LspCatalog32Only == Catalog )
01225 {
01226 rc = WSCWriteProviderOrder(pdwCatalogOrder, dwNumberOfEntries );
01227 }
01228 else
01229 {
01230 fprintf( stderr, "WriteProviderOrder: Unable to manipulate 64-bit catalog from "
01231 "a 32-bit process\n" );
01232 }
01233 #endif
01234 if ( 0 != rc )
01235 {
01236 *lpErrno = rc;
01237 fprintf( stderr, "WriteProviderOrder: WSCWriteProviderOrder failed: %d\n", *lpErrno );
01238 rc = SOCKET_ERROR;
01239 }
01240
01241 return rc;
01242 }
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261 int
01262 InstallProviderVista(
01263 WINSOCK_CATALOG eCatalog,
01264 __in_z WCHAR *lpszLspName,
01265 __in_z WCHAR *lpszLspPathAndFile,
01266 LPGUID providerGuid,
01267 DWORD dwCatalogIdArrayCount,
01268 DWORD *pdwCatalogIdArray,
01269 BOOL IfsProvider,
01270 BOOL InstallOverAll
01271 )
01272 {
01273 LPWSCINSTALLPROVIDERANDCHAINS lpInstallProviderAndChains;
01274 WSAPROTOCOL_INFOW *protocolList = NULL;
01275 WSAPROTOCOL_INFOW *pEnumProviders = NULL;
01276 HMODULE hMod = NULL;
01277 DWORD dwEntryCount;
01278 char *lpInstallFunction = NULL;
01279 INT iEnumProviderCount;
01280 int rc, i, j, error;
01281
01282
01283 rc = SOCKET_ERROR;
01284
01285
01286
01287
01288
01289 hMod = LoadLibrary("ws2_32.dll");
01290 if ( NULL == hMod )
01291 {
01292 fprintf(stderr, "Unable to load ws2_32.dll!\n");
01293 goto cleanup;
01294 }
01295
01296 #ifdef _WIN64
01297 if ( ( eCatalog == LspCatalog32Only ) || ( eCatalog == LspCatalog64Only ) )
01298 {
01299 fprintf(stderr, "New install API always installs into both catalogs!\n");
01300 goto cleanup;
01301 }
01302 else
01303 {
01304 lpInstallFunction = "WSCInstallProviderAndChains64_32";
01305 }
01306 #else
01307 if ( ( eCatalog == LspCatalog64Only) || ( eCatalog == LspCatalogBoth ) )
01308 {
01309 fprintf(stderr, "Cannot install into 64-bit catalog from 32-bit process\n");
01310 goto cleanup;
01311 }
01312 else
01313 {
01314 lpInstallFunction = "WSCInstallProviderAndChains";
01315 }
01316 #endif
01317
01318
01319 lpInstallProviderAndChains = (LPWSCINSTALLPROVIDERANDCHAINS) GetProcAddress(
01320 hMod,
01321 lpInstallFunction
01322 );
01323 if ( NULL == lpInstallProviderAndChains )
01324 {
01325 fprintf( stderr, "InstallLsp: Unable to load WSCInstallProviderAndChains function!\n");
01326 rc = SOCKET_ERROR;
01327 goto cleanup;
01328 }
01329
01330 if ( InstallOverAll )
01331 {
01332
01333
01334
01335
01336 rc = lpInstallProviderAndChains(
01337 providerGuid,
01338 lpszLspPathAndFile,
01339 lpszLspName,
01340 ( IfsProvider ? XP1_IFS_HANDLES : 0 ),
01341 NULL,
01342 NULL,
01343 NULL,
01344 &error
01345 );
01346 if ( SOCKET_ERROR == rc )
01347 {
01348 fprintf(stderr, "InstallProviderVista: %s failed: %d\n",
01349 lpInstallFunction, error );
01350 goto cleanup;
01351 }
01352 }
01353 else
01354 {
01355
01356
01357
01358
01359
01360 protocolList = (WSAPROTOCOL_INFOW *) LspAlloc( sizeof(WSAPROTOCOL_INFOW) *
01361 dwCatalogIdArrayCount, &error);
01362 if ( NULL == protocolList )
01363 {
01364 fprintf(stderr, "InstallProviderVista: Out of memory!\n");
01365 rc = SOCKET_ERROR;
01366 goto cleanup;
01367 }
01368
01369 pEnumProviders = EnumerateProviders( eCatalog, &iEnumProviderCount );
01370 if ( NULL == pEnumProviders )
01371 {
01372 fprintf(stderr, "InstallProviderVista: Unable to enumerate catalog!\n");
01373 rc = SOCKET_ERROR;
01374 goto cleanup;
01375 }
01376
01377
01378 dwEntryCount = 0;
01379 for(i=0; i < (int)dwCatalogIdArrayCount ;i++)
01380 {
01381 for(j=0; j < iEnumProviderCount ;j++)
01382 {
01383 if ( pdwCatalogIdArray[i] == pEnumProviders[j].dwCatalogEntryId )
01384 {
01385 memcpy( &protocolList[dwEntryCount++], &pEnumProviders[j], sizeof(WSAPROTOCOL_INFOW) );
01386 }
01387 }
01388 }
01389
01390 rc = lpInstallProviderAndChains(
01391 providerGuid,
01392 lpszLspPathAndFile,
01393 lpszLspName,
01394 ( IfsProvider ? XP1_IFS_HANDLES : 0 ),
01395 protocolList,
01396 dwEntryCount,
01397 NULL,
01398 &error
01399 );
01400 if ( SOCKET_ERROR == rc )
01401 {
01402 fprintf(stderr, "InstallProviderVista: %s failed: %d\n",
01403 lpInstallFunction, error );
01404 goto cleanup;
01405 }
01406 }
01407
01408 rc = NO_ERROR;
01409
01410 cleanup:
01411
01412 if ( NULL != hMod )
01413 FreeLibrary( hMod );
01414
01415 if ( NULL != pEnumProviders )
01416 FreeProviders( pEnumProviders );
01417
01418 if ( NULL != protocolList )
01419 LspFree( protocolList );
01420
01421 return rc;
01422 }