void main() { int nProtocols; int nError; DWORD dwSize = 0; LPWSAPROTOCOL_INFOW pProtoInfo = NULL; // 首次调用,pProtoInfo传入NULL,取得需要的缓冲区长度 if(WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError) == SOCKET_ERROR) { if(nError != WSAENOBUFS) { return ; } } // 申请足够缓冲区内存。 pProtoInfo = (LPWSAPROTOCOL_INFOW)::GlobalAlloc(GPTR, dwSize); if (pProtoInfo == NULL) { return ; } //再次调用WSCEnumProtocols函数 nProtocols = ::WSCEnumProtocols(NULL, pProtoInfo, &dwSize, &nError); wchar_t szWPath[MAX_PATH] = {0}; int iLen = MAX_PATH; //使控制台支持中文编码//////////////////////////////////////////////////////////////////// setlocale(LC_ALL, "chs"); wprintf(L"%-10s%-25s%s\n\n", L"提供者ID", L"协议类型", L"DLL路径"); wchar_t *szWType[3] = {L"分层协议", L"基础协议", L"协议链"}; int iIndex = 0; for(int i=0; i<nProtocols; i++) { //打印传输服务提供者ID wprintf(L"%-13d", pProtoInfo[i].dwCatalogEntryId); //打印传输服务提供者协议类型 iIndex = (pProtoInfo[i].ProtocolChain.ChainLen>1?2:pProtoInfo[i].ProtocolChain.ChainLen); wprintf(L"%-15s", szWType[iIndex]); //打印传输服务提供者所对应DLL的路径 WSCGetProviderPath(&pProtoInfo[i].ProviderId, szWPath, &iLen, NULL); wprintf(L"%-15s\n", szWPath); } wprintf(L"共计 %d 个传输服务提供者\n", nProtocols); //释放内存 GlobalFree(pProtoInfo); //恢复控制台编码////////////////////////////////////////////////////////////////////////// setlocale(LC_ALL, NULL); }
// // Function: LoadProviderPath // // Description: // This function retrieves the provider's DLL path, expands any environment // variables, loads the DLL, and retrieves it's WSPStartup function. // BOOL LoadProviderPath( PROVIDER *loadProvider, int *lpErrno ) { int rc; *lpErrno = 0; // Retrieve the provider path of the lower layer loadProvider->ProviderPathLen = MAX_PATH - 1; rc = WSCGetProviderPath( &loadProvider->NextProvider.ProviderId, loadProvider->ProviderPathW, &loadProvider->ProviderPathLen, lpErrno ); if ( SOCKET_ERROR == rc ) { dbgprint("LoadProviderPath: WSCGetProviderPath failed: %d", *lpErrno ); goto cleanup; } rc = ExpandEnvironmentStringsW( loadProvider->ProviderPathW, loadProvider->LibraryPathW, MAX_PATH - 1 ); if ( ( 0 != rc ) && ( MAX_PATH-1 >= rc ) ) { loadProvider->Module = LoadLibraryW( loadProvider->LibraryPathW ); if ( NULL == loadProvider->Module ) { dbgprint("LoadProviderPath: LoadLibraryW failed: %d", GetLastError() ); goto cleanup; } } else if ( 0 == rc ) { char ProviderPathA[ MAX_PATH ], LibraryPathA[ MAX_PATH ]; // No UNICODE so we must be on Win9x rc = WideCharToMultiByte( CP_ACP, 0, loadProvider->ProviderPathW, loadProvider->ProviderPathLen, ProviderPathA, loadProvider->ProviderPathLen, NULL, NULL ); if ( 0 == rc ) { dbgprint("LoadProviderPath: WideCharToMultiByte failed: %d", GetLastError() ); goto cleanup; } rc = ExpandEnvironmentStringsA( ProviderPathA, LibraryPathA, MAX_PATH - 1 ); if ( ( 0 == rc ) || ( MAX_PATH - 1 < rc ) ) { dbgprint("LoadProviderPath: ExpandEnvironmentStringsA failed: %d", GetLastError() ); goto cleanup; } loadProvider->Module = LoadLibraryA( LibraryPathA ); if ( NULL == loadProvider->Module ) { dbgprint("LoadProviderPath: LoadLibraryA failed: %d", GetLastError() ); goto cleanup; } } // Retrieve the next provider's WSPSTartup function loadProvider->fnWSPStartup = (LPWSPSTARTUP) GetProcAddress( loadProvider->Module, "WSPStartup" ); if ( NULL == loadProvider->fnWSPStartup ) { dbgprint("LoadProviderPath: GetProcAddress failed: %d", GetLastError() ); goto cleanup; } return TRUE; cleanup: if ( *lpErrno == 0 ) *lpErrno = GetLastError(); return FALSE; }
// // Function: InstallIfsLspProtocolChains // // Description: // This routine installs the layered protocol chains for an IFS based LSP. It // assumes the LSP dummy entry is already installed. This function first enumerates // the catalog to find the ID of the dummy entry. It then builds the protocol // entries for the IFS layered protocols. Note that an IFS entry must be installed // such that no non-IFS providers are layered beneath it. This means if the user // chooses to install the IFS LSP over a provider which includes non-IFS layers, it // must insert itself into the chain such that it is below all non-IFS providers. // This means that existing entries need to be modified in order to reflect this // ordering. Also in the event that the IFS LSP is inserted into an existing chain // this installer still builds a series of standalone entries (i.e. entries that // would have existed of the LSPs layered over the IFS LSP were installed after // the IFS LSP was). // int InstallIfsLspProtocolChains( WINSOCK_CATALOG eCatalog, GUID *Guid, WCHAR *lpszLspName, WCHAR *lpszLspFullPathAndFile, DWORD *pdwCatalogIdArray, DWORD dwCatalogIdArrayCount ) { WSAPROTOCOL_INFOW *pProvider = NULL, *pProviderNew = NULL, *pLayeredEntries = NULL, *pEntry = NULL, TempEntry = {0}; DWORD *pProviderOrder = NULL, dwDummyLspId; WCHAR wszLspDll[ MAX_PATH ]; BOOL bLayeredOverNonIfs = FALSE, bContainsNonIfs = FALSE; HRESULT hr; int ProviderPathLen = MAX_PATH-1, iProviderCount, iProviderCountNew, LayerIdx, retval = SOCKET_ERROR, err, idx, rc, i, j, k; // Enumerate the catalog pProvider = EnumerateProviders( eCatalog, &iProviderCount ); if ( NULL == pProvider ) { fprintf( stderr, "InstallIfsLspProtocolChains: Unable to enumerate catalog\n" ); goto cleanup; } // Find the dummy, hidden entry of our new LSP dwDummyLspId = GetCatalogIdForProviderGuid( Guid, pProvider, iProviderCount ); ASSERT( dwDummyLspId != 0 ); // Allocate space for the protocol chains of the new LSP pLayeredEntries = (WSAPROTOCOL_INFOW *) LspAlloc( sizeof(WSAPROTOCOL_INFOW) * dwCatalogIdArrayCount, &err ); if ( NULL == pLayeredEntries ) { fprintf( stderr, "InstallIfsLspProtocolChains: LspAlloc failed: %d\n", err ); goto cleanup; } LayerIdx = 0; // Build the layered protocol entries as well as a list of those providers which // require modification. Whenever an LSP is installed, a number of protocol entries // are installed where the first entry in the chain array is the LSP's dummy entry. // Addtionally, if we're installing an IFS LSP over an provider whose protocol chain // includes non-IFS LSPs, the IFS LSP must be placed in the chain such that no // non-IFS LSPs are positioned after it in the chain. // Loop through each ID we're layering over for(i=0; i < (int)dwCatalogIdArrayCount ;i++) { for(j=0; j < iProviderCount ;j++) { printf("Matching selected ID %d to catalog %d\n", pdwCatalogIdArray[ i ], pProvider[ j ].dwCatalogEntryId ); if ( pdwCatalogIdArray[ i ] == pProvider[ j ].dwCatalogEntryId ) { // Verify the entry has room enough to be layered over if ( pProvider[ j ].ProtocolChain.ChainLen >= ( MAX_PROTOCOL_CHAIN - 1 ) ) { fprintf( stderr, "InstallIfsLspProtocolChain: Too many LSPs installed!\n"); goto cleanup; } // Save off the entry which we're layering over memcpy( &pLayeredEntries[ LayerIdx ], &pProvider[ j ], sizeof( pLayeredEntries[ 0 ] ) ); memcpy( &TempEntry, &pProvider[ j ], sizeof( TempEntry ) ); // Fill in the new LSP entry's name hr = StringCchPrintfW( pLayeredEntries[ LayerIdx ].szProtocol, WSAPROTOCOL_LEN, L"%s over [%s]", lpszLspName, pProvider[ j ].szProtocol ); if ( FAILED( hr ) ) { fprintf( stderr, "InstallIfsLspProtocolChains: StringCchPrintfW failed: 0x%x\n", hr ); goto cleanup; } // Check whether the selected entry contains non IFS LSPs in its chain if ( pProvider[ j ].ProtocolChain.ChainLen >= 2 ) { for(k=pProvider[ j ].ProtocolChain.ChainLen-2 ; k >= 0 ;k--) { bContainsNonIfs = IsNonIfsProvider( pProvider, iProviderCount, pProvider[ j ].ProtocolChain.ChainEntries[ k ] ); if ( TRUE == bContainsNonIfs ) { // Need to modify the pProvider entry to reference the // added LSP entry within its chain // In the 'modified' array make a space at location after 'k' InsertIdIntoProtocolChain( &pProvider[ j ], k+1, UPDATE_LSP_ENTRY ); // Save the index to the layer which corresponds to this entry pProvider[ j ].dwProviderReserved = LayerIdx + 1; // Need to fix the 'pLayeredEntry' as well BuildSubsetLspChain( &pLayeredEntries[ LayerIdx ], k+1, dwDummyLspId ); pLayeredEntries[ LayerIdx ].dwServiceFlags1 |= XP1_IFS_HANDLES; bLayeredOverNonIfs = TRUE; // Need to insert the IFS provider in all LSPs that are layered // above the location where the IFS provider was just inserted InsertIfsLspIntoAllChains( &TempEntry, pProvider, iProviderCount, LayerIdx + 1, k ); break; } } } // Need to setup the protocol chain in the pLayeredEntry if we haven't // already done so above if ( TRUE != bContainsNonIfs ) { InsertIdIntoProtocolChain( &pLayeredEntries[ LayerIdx ], 0, dwDummyLspId ); // The second entry is always the ID of the current pProvider[i] // In case of multiple LSPs then if we didn't do this the [1] index // would contain the ID of that LSP's dummy entry and not the entry // itself. pLayeredEntries[ LayerIdx ].ProtocolChain.ChainEntries[ 1 ] = TempEntry.dwCatalogEntryId; pLayeredEntries[ LayerIdx ].dwServiceFlags1 |= XP1_IFS_HANDLES; } LayerIdx++; } } } ASSERT( LayerIdx == (int)dwCatalogIdArrayCount ); // Create a unique GUID for each provider to install and install it for(i=0;i < (int)dwCatalogIdArrayCount ;i++) { if ( RPC_S_OK != UuidCreate( &pLayeredEntries[ i ].ProviderId ) ) { fprintf(stderr, "InstallIfsLspProtocolChains: UuidCreate failed: %d\n", GetLastError()); goto cleanup; } rc = InstallProvider( eCatalog, &pLayeredEntries[ i ].ProviderId, lpszLspFullPathAndFile, &pLayeredEntries[ i ], 1 ); if ( NO_ERROR != rc ) { fprintf(stderr, "InstallIfsLspProtocolChains: Unable to install the dummy LSP entry!\n"); goto cleanup; } } if ( TRUE == bLayeredOverNonIfs ) { // Enumerate the catalog again so we can find the catalog IDs pProviderNew = EnumerateProviders( eCatalog, &iProviderCountNew ); if ( NULL == pProvider ) { fprintf( stderr, "InstallIfsLspProtocolChains: Unable to enumerate catalog\n" ); goto cleanup; } for(i=0; i < (int)dwCatalogIdArrayCount ;i++) { pLayeredEntries[ i ].dwCatalogEntryId = GetCatalogIdForProviderGuid( &pLayeredEntries[ i ].ProviderId, pProviderNew, iProviderCountNew ); ASSERT( pLayeredEntries[ i ].dwCatalogEntryId != 0 ); } // Update the protocol chains of the modified entries to point to the just // installed providers for(i=0; i < iProviderCount ;i++) { if ( pProvider[ i ].dwProviderReserved == 0 ) continue; for(j=0; j < pProvider[ i ].ProtocolChain.ChainLen ;j++) { if ( UPDATE_LSP_ENTRY == pProvider[ i ].ProtocolChain.ChainEntries[ j ] ) { pProvider[ i ].ProtocolChain.ChainEntries[ j ] = pLayeredEntries[ pProvider[ i ].dwProviderReserved - 1 ].dwCatalogEntryId; pProvider[ i ].dwProviderReserved = 0; } } // Get the DLL path ProviderPathLen = MAX_PATH-1; rc = WSCGetProviderPath( &pProvider[ i ].ProviderId, wszLspDll, &ProviderPathLen, &err ); if ( SOCKET_ERROR == rc ) { fprintf( stderr, "InstallIfsLspProtocolChains: WSCGetProviderPath failed: %d\n", err ); goto cleanup; } // Update the providers which were modified rc = UpdateProvider( eCatalog, &pProvider[ i ].ProviderId, wszLspDll, &pProvider[ i ], 1, &err ); if ( SOCKET_ERROR == rc ) { fprintf( stderr, "InstallIfsLspProtocolChains: UpdateProvider failed: %d\n", err ); goto cleanup; } printf("Updated entry ID: %d: %S (chain len = %d)\n", pProvider[ i ].dwCatalogEntryId, pProvider[ i ].szProtocol, pProvider[ i ].ProtocolChain.ChainLen ); } FreeProviders( pProvider ); pProvider = NULL; FreeProviders( pProviderNew ); pProviderNew = NULL; /* { WSADATA wsd; WSACleanup(); WSAStartup( MAKEWORD(2,2), &wsd ); } */ pProvider = EnumerateProviders( eCatalog, &iProviderCount ); if ( NULL == pProvider ) { fprintf( stderr, "InstallIfsLspProtocolChains: Unable to enumerate catalog\n" ); goto cleanup; } // Allocate an array of DWORDs to contain the new catalog ordering pProviderOrder = (DWORD *)LspAlloc( iProviderCount * sizeof(DWORD), &err ); if ( NULL == pProviderOrder ) { fprintf( stderr, "InstallIfsLspProtocolChains: Unable to enumerate catalog\n" ); goto cleanup; } // First add the entries we layered over first idx = 0; for(i=0; i < (int)dwCatalogIdArrayCount ;i++) { pEntry = FindProviderById( pdwCatalogIdArray[ i ], pProvider, iProviderCount ); if ( NULL == pEntry ) { fprintf(stderr, "InstallIfsLspProtocolChain: Unable to find entry to reorder catalog!\n"); goto cleanup; } pEntry->dwProviderReserved = 1; pProviderOrder[ idx++ ] = pEntry->dwCatalogEntryId; } // Now go through the protocol chain of the entries we layered over and put those // LSP entries next in the new order for(i=0; i < (int)dwCatalogIdArrayCount ;i++) { pEntry = FindProviderById( pdwCatalogIdArray[ i ], pProvider, iProviderCount ); if ( NULL == pEntry ) { fprintf(stderr, "InstallIfsLspProtocolChain: Unable to find entry to reorder catalog!\n"); goto cleanup; } printf("Looping through: %d: %S (chain len = %d)\n", pEntry->dwCatalogEntryId, pEntry->szProtocol, pEntry->ProtocolChain.ChainLen ); for(j=1; j < pEntry->ProtocolChain.ChainLen-1 ;j++) { dwDummyLspId = FindDummyIdFromProtocolChainId( pEntry->ProtocolChain.ChainEntries[ j ], pProvider, iProviderCount ); printf(" Finding dummy ID for chain entry: %d is %d\n", pEntry->ProtocolChain.ChainEntries[ j ], dwDummyLspId ); for(k=0; k < iProviderCount ;k++) { if ( ( pProvider[ k ].ProtocolChain.ChainLen >= 2 ) && ( pProvider[ k ].ProtocolChain.ChainEntries[ 0 ] == dwDummyLspId ) && ( pProvider[ k ].dwProviderReserved == 0 ) ) { pProviderOrder[ idx++ ] = pProvider[ k ].dwCatalogEntryId; pProvider[ k ].dwProviderReserved = 1; printf(" Adding: %d\n", pProvider[ k ].dwCatalogEntryId ); } } } } // Now any catalog entry that wasn't already copied, copy it for(i=0; i < iProviderCount ;i++) { if ( pProvider[ i ].dwProviderReserved == 0 ) pProviderOrder[ idx++ ] = pProvider[ i ].dwCatalogEntryId; } ASSERT( idx == iProviderCount ); // Write the new catalog order rc = WriteProviderOrder( eCatalog, pProviderOrder, iProviderCount, &err ); if ( NO_ERROR != rc ) { fprintf( stderr, "InstallIfsLspProtocolChains: WriteProviderOrder failed: %d\n", err ); goto cleanup; } } else { // // Reorder the winsock catalog so the layered chain entries appear first. // Since we didn't have to modify any existing entries, all we need to do is // move the added entries to the head of the catalog // rc = ReorderCatalog( eCatalog, dwDummyLspId ); if ( NO_ERROR != rc ) { fprintf(stderr, "InstallIfsLspProtocolChains: Unable to reorder Winsock catalog!\n"); goto cleanup; } } retval = NO_ERROR; cleanup: if ( NULL != pProvider ) { FreeProviders( pProvider ); pProvider = NULL; } if ( NULL != pProviderNew ) { FreeProviders( pProviderNew ); pProviderNew = NULL; } if ( NULL != pProviderOrder ) { LspFree( pProviderOrder ); pProviderOrder = NULL; } return retval; }
NS_IMETHODIMP LSPAnnotationGatherer::Run() { PR_SetCurrentThreadName("LSP Annotator"); mThread = NS_GetCurrentThread(); DWORD size = 0; int err; // Get the size of the buffer we need if (SOCKET_ERROR != WSCEnumProtocols(nullptr, nullptr, &size, &err) || err != WSAENOBUFS) { // Er, what? NS_NOTREACHED("WSCEnumProtocols suceeded when it should have failed ..."); return NS_ERROR_FAILURE; } auto byteArray = MakeUnique<char[]>(size); WSAPROTOCOL_INFOW* providers = reinterpret_cast<WSAPROTOCOL_INFOW*>(byteArray.get()); int n = WSCEnumProtocols(nullptr, providers, &size, &err); if (n == SOCKET_ERROR) { // Lame. We provided the right size buffer; we'll just give up now. NS_WARNING("Could not get LSP list"); return NS_ERROR_FAILURE; } nsCString str; for (int i = 0; i < n; i++) { AppendUTF16toUTF8(nsDependentString(providers[i].szProtocol), str); str.AppendLiteral(" : "); str.AppendInt(providers[i].iVersion); str.AppendLiteral(" : "); str.AppendInt(providers[i].iAddressFamily); str.AppendLiteral(" : "); str.AppendInt(providers[i].iSocketType); str.AppendLiteral(" : "); str.AppendInt(providers[i].iProtocol); str.AppendLiteral(" : "); str.AppendPrintf("0x%x", providers[i].dwServiceFlags1); str.AppendLiteral(" : "); str.AppendPrintf("0x%x", providers[i].dwProviderFlags); str.AppendLiteral(" : "); wchar_t path[MAX_PATH]; int pathLen = MAX_PATH; if (!WSCGetProviderPath(&providers[i].ProviderId, path, &pathLen, &err)) { AppendUTF16toUTF8(nsDependentString(path), str); } str.AppendLiteral(" : "); // If WSCGetProviderInfo is available, we should call it to obtain the // category flags for this provider. When present, these flags inform // Windows as to which order to chain the providers. nsModuleHandle ws2_32(LoadLibraryW(L"ws2_32.dll")); if (ws2_32) { decltype(WSCGetProviderInfo)* pWSCGetProviderInfo = reinterpret_cast<decltype(WSCGetProviderInfo)*>( GetProcAddress(ws2_32, "WSCGetProviderInfo")); if (pWSCGetProviderInfo) { DWORD categoryInfo; size_t categoryInfoSize = sizeof(categoryInfo); if (!pWSCGetProviderInfo(&providers[i].ProviderId, ProviderInfoLspCategories, (PBYTE)&categoryInfo, &categoryInfoSize, 0, &err)) { str.AppendPrintf("0x%x", categoryInfo); } } } str.AppendLiteral(" : "); if (providers[i].ProtocolChain.ChainLen <= BASE_PROTOCOL) { // If we're dealing with a catalog entry that identifies an individual // base or layer provider, log its provider GUID. RPC_CSTR provIdStr = nullptr; if (UuidToStringA(&providers[i].ProviderId, &provIdStr) == RPC_S_OK) { str.Append(reinterpret_cast<char*>(provIdStr)); RpcStringFreeA(&provIdStr); } } if (i + 1 != n) { str.AppendLiteral(" \n "); } } mString = str; NS_DispatchToMainThread(NewRunnableMethod(this, &LSPAnnotationGatherer::Annotate)); return NS_OK; }
// // Function: PrintProtocolInfo // // Description: // Decode a WSAPROTOCOL_INFO entry and print the member fields // in a readable format. There's no secret voodoo here, just // interpret all the fields of the structure. // void PrintProtocolInfo( WSAPROTOCOL_INFOW *wsapi ) { WCHAR szGuidString[MAX_PATH], wszProviderPath[MAX_PATH]; INT dwProviderPathLen=MAX_PATH-1; int rc, error, i; rc = WSCGetProviderPath( &wsapi->ProviderId, wszProviderPath, &dwProviderPathLen, &error ); if ( 0 != rc ) { fprintf(stderr, "WSCGetProviderPath failed: %d\n", error); lstrcpyW(wszProviderPath, L"(error)"); } // // Display address family and protocol information // printf("\nProtocol: %S\n", wsapi->szProtocol); printf("\n Path: %S\n", wszProviderPath); printf(" Address Family: "); switch ( wsapi->iAddressFamily ) { case AF_INET: case AF_INET6: printf("%s\n", (wsapi->iAddressFamily == AF_INET ? "AF_INET" : "AF_INET6")); printf(" Protocol: "); switch (wsapi->iProtocol) { case IPPROTO_IP: printf("IPROTO_IP\n"); break; case IPPROTO_ICMP: printf("IPROTO_ICMP\n"); break; case IPPROTO_IGMP: printf("IPROTO_IGMP\n"); break; case IPPROTO_GGP: printf("IPROTO_GGP\n"); break; case IPPROTO_TCP: printf("IPROTO_TCP\n"); break; case IPPROTO_PUP: printf("IPROTO_PUP\n"); break; case IPPROTO_UDP: printf("IPROTO_UDP\n"); break; case IPPROTO_IDP: printf("IPROTO_IDP\n"); break; case IPPROTO_ND: printf("IPROTO_ND\n"); break; case IPPROTO_RM: printf("IPPROTO_RM\n"); break; case IPPROTO_RAW: printf("IPROTO_RAW\n"); break; } break; case AF_UNSPEC: printf("AF_UNSPEC\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_UNIX: printf("AF_UNIX\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_IMPLINK: printf("AF_IMPLINK\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_PUP: printf("AF_PUP\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_CHAOS: printf("AF_CHAOS\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_NS: printf("AF_NS or AF_IPX\n"); printf(" Protocol: "); switch ( wsapi->iProtocol ) { case NSPROTO_IPX: printf("NSPROTO_IPX\n"); break; case NSPROTO_SPX: printf("NSPROTO_SPX\n"); break; case NSPROTO_SPXII: printf("NSPROTO_SPXII\n"); break; } break; case AF_ISO: printf("AF_ISO or AF_OSI\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_ECMA: printf("AF_ECMA\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_DATAKIT: printf("AF_DATAKIT\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_CCITT: printf("AF_CCITT\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_SNA: printf("AF_SNA\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_DECnet: printf("AF_DECnet\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_DLI: printf("AF_DLI\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_LAT: printf("AF_LAT\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_HYLINK: printf("AF_HYLINK\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_APPLETALK: printf("AF_APPLETALK\n"); printf(" Protocol: "); switch ( wsapi->iProtocol ) { case DDPPROTO_RTMP: printf("DDPPROTO_RTMP\n"); break; case DDPPROTO_NBP: printf("DDPPROTO_NBP\n"); break; case DDPPROTO_ATP: printf("DDPROTO_ATP\n"); break; case DDPPROTO_AEP: printf("DDPPROTO_AEP\n"); break; case DDPPROTO_RTMPRQ: printf("DDPPROTO_RTMPRQ\n"); break; case DDPPROTO_ZIP: printf("DDPPROTO_ZIP\n"); break; case DDPPROTO_ADSP: printf("DDPPROTO_ADSP\n"); break; case ATPROTO_ADSP: printf("ATPROTO_ADSP\n"); break; case ATPROTO_ATP: printf("ATPROTO_ATP\n"); break; case ATPROTO_ASP: printf("ATPROTO_ASP\n"); break; case ATPROTO_PAP: printf("ATPROTO_PAP\n"); break; } break; case AF_NETBIOS: printf("AF_NETBIOS\n"); printf(" Protocol: "); printf("NetBIOS LANA %d\n", ((wsapi->iProtocol == 0x80000000) ? 0: abs(wsapi->iProtocol))); break; case AF_VOICEVIEW: printf("AF_VOICEVIEW\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_FIREFOX: printf("AF_FIREFOX\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_UNKNOWN1: printf("AF_UNKNOWN1\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_BAN: printf("AF_BAN\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_ATM: printf("AF_ATM\n"); printf(" Protocol: "); switch ( wsapi->iProtocol ) { case ATMPROTO_AALUSER: printf("ATMPROTO_AALUSER\n"); break; case ATMPROTO_AAL1: printf("ATMPROTO_AAL1\n"); break; case ATMPROTO_AAL2: printf("ATMPROTO_AAL2\n"); break; case ATMPROTO_AAL34: printf("ATMPROTO_AAL34\n"); break; case ATMPROTO_AAL5: printf("ATMPROTO_AAL5\n"); break; } break; case AF_CLUSTER: printf("AF_CLUSTER\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_12844: printf("AF_12844\n"); printf(" Protocol: UNKNOWN: %d", wsapi->iProtocol); break; case AF_IRDA: printf("AF_IRDA\n"); printf(" Protocol: "); switch (wsapi->iProtocol) { case IRDA_PROTO_SOCK_STREAM: printf("IRDA_PROTO_SOCK_STREAM\n"); break; } break; default: printf("Unknown: %d\n", wsapi->iAddressFamily); } // // Display socket type information // printf(" Socket Type: "); switch (wsapi->iSocketType) { case SOCK_STREAM: printf("SOCK_STREAM\n"); break; case SOCK_DGRAM: printf("SOCK_DGRAM\n"); break; case SOCK_RAW: printf("SOCK_RAW\n"); break; case SOCK_RDM: printf("SOCK_RDM\n"); break; case SOCK_SEQPACKET: printf("SOCK_SEQPACKET\n"); break; } // // Display the various provider flags for this entry // printf(" Connectionless: "); if (wsapi->dwServiceFlags1 & XP1_CONNECTIONLESS) printf("YES\n"); else printf("NO\n"); printf(" Guaranteed Delivery: "); if (wsapi->dwServiceFlags1 & XP1_GUARANTEED_DELIVERY) printf("YES\n"); else printf("NO\n"); printf(" Guaranteed Order: "); if (wsapi->dwServiceFlags1 & XP1_GUARANTEED_ORDER) printf("YES\n"); else printf("NO\n"); printf(" Message Oriented: "); if (wsapi->dwServiceFlags1 & XP1_MESSAGE_ORIENTED) printf("YES\n"); else printf("NO\n"); printf(" Pseudo Stream: "); if (wsapi->dwServiceFlags1 & XP1_PSEUDO_STREAM) printf("YES\n"); else printf("NO\n"); printf(" Graceful Close: "); if (wsapi->dwServiceFlags1 & XP1_GRACEFUL_CLOSE) printf("YES\n"); else printf("NO\n"); printf(" Expedited Data: "); if (wsapi->dwServiceFlags1 & XP1_EXPEDITED_DATA) printf("YES\n"); else printf("NO\n"); printf(" Connect Data: "); if (wsapi->dwServiceFlags1 & XP1_CONNECT_DATA) printf("YES\n"); else printf("NO\n"); printf(" Disconnect Data: "); if (wsapi->dwServiceFlags1 & XP1_DISCONNECT_DATA) printf("YES\n"); else printf("NO\n"); printf(" Supports Broadcast: "); if (wsapi->dwServiceFlags1 & XP1_SUPPORT_BROADCAST) printf("YES\n"); else printf("NO\n"); printf(" Supports Multipoint: "); if (wsapi->dwServiceFlags1 & XP1_SUPPORT_MULTIPOINT) printf("YES\n"); else printf("NO\n"); printf(" Multipoint Control Plane: "); if (wsapi->dwServiceFlags1 & XP1_MULTIPOINT_CONTROL_PLANE) printf("ROOTED\n"); else printf("NON-ROOTED\n"); printf(" Multipoint Data Plane: "); if (wsapi->dwServiceFlags1 & XP1_MULTIPOINT_DATA_PLANE) printf("ROOTED\n"); else printf("NON-ROOTED\n"); printf(" QoS Supported: "); if (wsapi->dwServiceFlags1 & XP1_QOS_SUPPORTED) printf("YES\n"); else printf("NO\n"); printf(" Unidirectional Sends: "); if (wsapi->dwServiceFlags1 & XP1_UNI_SEND) printf("YES\n"); else printf("NO\n"); printf(" Unidirection Receives: "); if (wsapi->dwServiceFlags1 & XP1_UNI_RECV) printf("YES\n"); else printf("NO\n"); printf(" IFS Handles: "); if (wsapi->dwServiceFlags1 & XP1_IFS_HANDLES) printf("YES\n"); else printf("NO\n"); printf(" Partial Messages: "); if (wsapi->dwServiceFlags1 & XP1_PARTIAL_MESSAGE) printf("YES\n"); else printf("NO\n"); printf(" Provider Flags: "); if (wsapi->dwProviderFlags & PFL_MULTIPLE_PROTO_ENTRIES) { printf("PFL_MULTIPLE_PROTO_ENTRIES "); } if (wsapi->dwProviderFlags & PFL_RECOMMENDED_PROTO_ENTRY) { printf("PFL_RECOMMENDED_PROT_ENTRY "); } if (wsapi->dwProviderFlags & PFL_HIDDEN) { printf("PFL_HIDDEN "); } if (wsapi->dwProviderFlags & PFL_MATCHES_PROTOCOL_ZERO) { printf("PFL_MATCHES_PROTOCOL_ZERO "); } if (wsapi->dwProviderFlags == 0) { printf("NONE"); } printf("\n"); // // Display provider ID and catalog ID as well as LSP chain information // StringFromGUID2( wsapi->ProviderId, szGuidString, MAX_PATH-1 ); printf(" Provider Id: %S\n", szGuidString); printf(" Catalog Entry Id: %ld\n", wsapi->dwCatalogEntryId); printf(" Number of Chain Entries: %d {", wsapi->ProtocolChain.ChainLen); for(i=0; i < wsapi->ProtocolChain.ChainLen ;i++) printf("%ld ", wsapi->ProtocolChain.ChainEntries[i]); printf("}\n"); // // Display the remaining information // printf(" Version: %d\n", wsapi->iVersion); printf("Max Socket Address Length: %d\n", wsapi->iMaxSockAddr); printf("Min Socket Address Length: %d\n", wsapi->iMinSockAddr); printf(" Protocol Max Offset: %d\n", wsapi->iProtocolMaxOffset); printf(" Network Byte Order: "); if (wsapi->iNetworkByteOrder == 0) printf("BIG-ENDIAN\n"); else printf("LITLE-ENDIAN\n"); printf(" Security Scheme: "); if (wsapi->iSecurityScheme == SECURITY_PROTOCOL_NONE) printf("NONE\n"); else printf("%d\n", wsapi->iSecurityScheme); printf(" Message Size: "); if (wsapi->dwMessageSize == 0) printf("N/A (Stream Oriented)\n"); else if (wsapi->dwMessageSize == 1) printf("Depended on underlying MTU\n"); else if (wsapi->dwMessageSize == 0xFFFFFFFF) printf("No limit\n"); else printf("%ld\n", wsapi->dwMessageSize); printf(" Provider Reserved: %d\n", wsapi->dwProviderReserved); }
JNIEXPORT jint JNICALL Java_com_act365_net_SocketWrenchSession__1deinstallProvider( JNIEnv* env , jclass , jint protocol ) { int nDeinstalled = 0 ; #ifdef WIN32 int i = -1 ; // Find the installed service providers for the given protocol. int protocolList[1]; protocolList[0] = (int) protocol ; if( ( nProtocols = WSAEnumProtocolsW( protocolList , protocolBuffer , & protocolBufferSize ) ) == SOCKET_ERROR ){ jclass exceptionClass = env -> FindClass("java/net/SocketException"); SocketUtils::throwError( env , exceptionClass , "WSAEnumProtocols()" ); env -> DeleteLocalRef( exceptionClass ); return nDeinstalled ; } // Find the path of the DLL in which the services are implemented. // (It's assumed that they're all implemented in a single MS DLL). int errorCode = 0 , dllPathLength = maxDllPathLength ; if( nProtocols > 0 ){ WSCGetProviderPath( & protocolBuffer[0].ProviderId , dllPath , & dllPathLength , & errorCode ); } if( errorCode > 0 ){ jclass exceptionClass = env -> FindClass("java/net/SocketException"); SocketUtils::throwError( env , exceptionClass , "WSCGetProviderPath()" ); env -> DeleteLocalRef( exceptionClass ); return nDeinstalled ; } // Deinstall. while( ++ i < nProtocols && ! errorCode ){ nDeinstalled += WSCDeinstallProvider( & protocolBuffer[i].ProviderId , & errorCode ); } if( errorCode > 0 ){ jclass exceptionClass = env -> FindClass("java/net/SocketException"); SocketUtils::throwError( env , exceptionClass , "WSCDeinstallProvider()" ); env -> DeleteLocalRef( exceptionClass ); } #endif return nDeinstalled ; }
// // Function: BuildLspMap // // Description: // This routine builds a map of all LSPs installed according to what order // they are in the catalog. That is, the information returned will be ordered // in the way the LSPs need to be installed. For example if LSP1 is installed // over the base TCP and UDP providers and LSP2 is installed over LSP1, then // this routine will return two LSP_ENTRY structures with LSP1 first followed // by LSP2. The algorithm for determining the order is to first sort by where // a base provider ID occurs in an LSP chain with lower numbered ones first. // For example, LSP1 layered directly over TCP will have a base ID (TCP) in // chain position 1 while LSP (layered over LSP1) will have the base ID in // chain index 2. This is the ChainOrder field (and it is the minimum value // for all layered providers). After this first sort, it is possible to have // several LSPs with the same ChainOrder value. Within these groupings the // entries are sorted by the maximum LSP chain length. Each LSP has a number // of layered providers each with its own chain (and the chains could be // different lengths). The MaxChainLength value is the longest chain length // of all providers belonging to a given LSP. Each grouping of LspOrder is then // sorted by MaxChainLengthin ascending order. // LSP_ENTRY * BuildLspMap( WSAPROTOCOL_INFOW *pProviders, int iProviderCount, int *pLspCount ) { LSP_ENTRY *pLsps = NULL, lsptmp; DWORD *pBaseList = NULL; int iLspCount = 0, iSortLspCount = 0, iOrphanCount = 0, iBaseCount = 0, iProviderPathLen, ErrorCode, LspOrder, start, end, idx, rc, i, j, k; // Retrieve how many orphaned chain entries are present iOrphanCount = CountOrphanedChainEntries( pProviders, iProviderCount ); // Retrieve the LSP count iSortLspCount = iLspCount = GetProviderCount( pProviders, iProviderCount, LAYERED_PROTOCOL ); if ( ( 0 == iOrphanCount ) && ( 0 == iLspCount ) ) { fprintf( stderr, "BuildLspMap: No LSP installed on the system!\n"); goto cleanup; } // If orphaned entries are present, create another LSP_ENTRY and put all orphaned // entries there. if ( iOrphanCount > 0 ) iLspCount++; // Allocate space for our structure which represents the LSPs installed pLsps = (LSP_ENTRY *) LspAlloc( sizeof( LSP_ENTRY ) * iLspCount, &ErrorCode ); if ( NULL == pLsps ) { fprintf( stderr, "BuildLspMap: LspAlloc failed: %d\n", ErrorCode ); goto cleanup; } // If orphaned entries are present, allocate space to hold them if ( iOrphanCount > 0 ) { pLsps[ iLspCount-1 ].LayeredEntries = (WSAPROTOCOL_INFOW *)LspAlloc( sizeof(WSAPROTOCOL_INFOW) * iOrphanCount, &ErrorCode ); if ( NULL == pLsps[ iLspCount-1 ].LayeredEntries ) { fprintf( stderr, "BuildLspMap: LspAlloc failed: %d\n", ErrorCode ); goto cleanup; } pLsps[ iLspCount-1 ].OrphanedEntries = TRUE; pLsps[ iLspCount-1 ].Count = iOrphanCount; // // Find the orphaned entries and save them off // idx = 0; for(i=0; i < iProviderCount ;i++) { // Only investigate protocol chain entries (i.e. chainlen > 1) if ( pProviders[ i ].ProtocolChain.ChainLen > 1 ) { // Walk the catalog and look for the dummy entry (i.e. the ID in // chain entry 0) for(j=0; j < iProviderCount ;j++) { if ( i == j ) continue; if ( pProviders[ i ].ProtocolChain.ChainEntries[ 0 ] == pProviders[ j ].dwCatalogEntryId ) { break; } } if ( j >= iProviderCount ) { // If j is past iProviderCount, no match was found so this is // an orphaned entry...save it off memcpy( &pLsps[ iLspCount-1 ].LayeredEntries[ idx ], &pProviders[ i ], sizeof( WSAPROTOCOL_INFOW ) ); rc = AddGuidToLspEntry( &pLsps[ iLspCount-1 ], &pProviders[ i ].ProviderId, &ErrorCode ); if ( SOCKET_ERROR == rc ) { fprintf( stderr, "BuildLspMap: AddGuidToLspEntry failed: %d\n", ErrorCode ); goto cleanup; } idx++; } } } } // // Build a list of the valid LSPs installed on the system // idx = 0; for(i=0; i < iProviderCount ;i++) { if ( LAYERED_PROTOCOL == pProviders[ i ].ProtocolChain.ChainLen ) { // Copy the dummy entry memcpy( &pLsps[ idx ].DummyEntry, &pProviders[ i ], sizeof( WSAPROTOCOL_INFOW ) ); // Get the DLL path iProviderPathLen = MAX_PATH-1; rc = WSCGetProviderPath( &pLsps[ idx ].DummyEntry.ProviderId, pLsps[ idx ].wszLspDll, &iProviderPathLen, &ErrorCode ); if ( SOCKET_ERROR == rc ) { fprintf( stderr, "BuildLspMap: WSCGetProviderPath failed: %d\n", ErrorCode ); goto cleanup; } // // Now go find all the layered entries associated with the dummy provider // // First get the count for(j=0; j < iProviderCount ;j++) { // // Compare only the first entry against the dummy ID. Otherwise, // we may pick up more than the provider's owned by this LSP // (it may pick up other providers layered over this LSP. // if ( ( pProviders[ j ].ProtocolChain.ChainLen > 1 ) && ( pProviders[ j ].ProtocolChain.ChainEntries[ 0 ] == pLsps[ idx ].DummyEntry.dwCatalogEntryId ) ) // if ( IsIdInChain( &pProviders[ j ], pLsps[ idx ].DummyEntry.dwCatalogEntryId ) ) { pLsps[idx].Count++; } } // Allocate space pLsps[ idx ].LayeredEntries = (WSAPROTOCOL_INFOW *) LspAlloc( sizeof( WSAPROTOCOL_INFOW ) * pLsps[ idx ].Count, &ErrorCode ); if ( NULL == pLsps[ idx ].LayeredEntries ) { fprintf( stderr, "BuildLspMap: LspAlloc failed: %d\n", ErrorCode ); goto cleanup; } pLsps[ idx ].LayerChanged = (int *) LspAlloc( sizeof( int ) * pLsps[ idx ].Count, &ErrorCode ); if ( NULL == pLsps[ idx ].LayerChanged ) { fprintf( stderr, "BuildLspMap: LspAlloc failed: %d\n", ErrorCode ); goto cleanup; } // Now go find the entries pLsps[idx].Count = 0; for(j=0; j < iProviderCount ;j++) { if ( ( pProviders[ j ].ProtocolChain.ChainLen > 1 ) && ( pProviders[ j ].ProtocolChain.ChainEntries[ 0 ] == pLsps[ idx ].DummyEntry.dwCatalogEntryId ) ) { memcpy( &pLsps[ idx ].LayeredEntries[pLsps[ idx ].Count], &pProviders[ j ], sizeof( WSAPROTOCOL_INFOW ) ); pLsps[idx].MaxChainLength = MAX( pLsps[ idx ].MaxChainLength, pLsps[ idx ].LayeredEntries[ pLsps[idx].Count ].ProtocolChain.ChainLen ); // Mark this entry as visited pProviders[ j ].dwProviderReserved = 1; // Keep track of how many GUIDs are used to install the layered entries rc = AddGuidToLspEntry( &pLsps[ idx ], &pProviders[ j ].ProviderId, &ErrorCode ); if ( SOCKET_ERROR == rc ) { fprintf( stderr, "BuildLspMap: AddGuidToLspEntry failed: %d\n", ErrorCode ); goto cleanup; } pLsps[ idx ].Count++; } } pLsps[ idx ].LspOrder = MAX_PROTOCOL_CHAIN; idx++; // Increment index into the map } } // // We now have an array of "LSPs" -- now order them // // First get a list of base provider IDs iBaseCount = GetProviderCount( pProviders, iProviderCount, BASE_PROTOCOL ); if ( 0 == iBaseCount ) { fprintf( stderr, "BuildLspMap: GetProviderCount(BASE_PROTOCOL) returned zero!\n" ); goto cleanup; } // Allocate space for the array of base provider ID's pBaseList = (DWORD *) LspAlloc( sizeof( DWORD ) * iBaseCount, &ErrorCode ); if ( NULL == pBaseList ) { fprintf( stderr, "BuildLspMap: HeapAlloc failed: %d\n", ErrorCode ); goto cleanup; } // // Copy the base provider ID's to our array -- this array contains the catalog // IDs of only base providers which will be used next to determine the order // in which LSPs were installed. // idx = 0; for(i=0; i < iProviderCount ;i++) { if ( BASE_PROTOCOL == pProviders[ i ].ProtocolChain.ChainLen ) { pBaseList[ idx++ ] = pProviders[ i ].dwCatalogEntryId; } } // // For each layered protocol entry of an LSP find the lowest index in the protocol // chain where a base provider resides. A protocol chain should always terminate // in a base provider. // for(LspOrder = 1; LspOrder < MAX_PROTOCOL_CHAIN ;LspOrder++) { for(i=0; i < iSortLspCount ;i++) { for(j=0; j < pLsps[ i ].Count ;j++) { for(k=0; k < iBaseCount ;k++) { if ( pLsps[ i ].LayeredEntries[ j ].ProtocolChain.ChainEntries[ LspOrder ] == pBaseList[ k ] ) { pLsps[ i ].LspOrder = MIN( pLsps[ i ].LspOrder, LspOrder ); break; } } } } } // // Sort the entries according to the LspOrder field // for(i=0; i < iSortLspCount ;i++) { for(j=i; j < iSortLspCount ;j++) { if ( pLsps[ i ].LspOrder > pLsps[ j ].LspOrder ) { // Exchange positions memcpy( &lsptmp, &pLsps[ i ], sizeof( LSP_ENTRY ) ); memcpy( &pLsps[ i ], &pLsps[ j ], sizeof( LSP_ENTRY ) ); memcpy( &pLsps[ j ], &lsptmp, sizeof( LSP_ENTRY ) ); } } } // // Now need to sort by MaxChainLength withing the LspOrder groupings // for(LspOrder=1; LspOrder < MAX_PROTOCOL_CHAIN ;LspOrder++) { // Find the start and end positions within the array for the given // LspOrder value start = -1; end = -1; for(i=0; i < iSortLspCount ;i++) { if ( pLsps[ i ].LspOrder == LspOrder ) { start = i; break; } } // // Find the end position which is the LSP Map entry whose LspOrder // value doesn't match the current one. This will give us the range // of LSP entries whose LspOrder value is identical -- we need to // sort the LSPs of the same LspOrder according to the MaxChainLength // if ( -1 != start ) { for(j=start; j < iSortLspCount ;j++) { if ( pLsps[ j ].LspOrder != LspOrder ) { end = j - 1; break; } } } // // If the following is true then all entries have the same order // value. We still need to sort by MaxChainLength so set the end // to the last LSP // if ( ( -1 != start ) && ( -1 == end ) ) { end = iSortLspCount - 1; } if ( ( -1 != start ) && ( -1 != end ) ) { for(i=start; i < end ;i++) { for(j=i; j < end ;j++) { if ( pLsps[ i ].MaxChainLength > pLsps[ j ].MaxChainLength ) { memcpy( &lsptmp, &pLsps[ i ], sizeof( LSP_ENTRY ) ); memcpy( &pLsps[ i ], &pLsps[ j ], sizeof( LSP_ENTRY ) ); memcpy( &pLsps[ j ], &lsptmp, sizeof( LSP_ENTRY ) ); } } } } } // Add the LSP dependency info to the map rc = LspDependencyCheck( pLsps, iSortLspCount ); if ( SOCKET_ERROR == rc ) { FreeLspMap( pLsps, iLspCount ); pLsps = NULL; iLspCount = 0; goto cleanup; } cleanup: if ( NULL != pLspCount ) *pLspCount = iLspCount; if ( NULL != pBaseList ) LspFree( pBaseList ); return pLsps; }