How to get a list of installed on the machine LSP?

If you believe MSDN , then they are registered in HKEY_LOCAL_MACHINE \ COMM \ WS2 \ LSP but I do not have the COMM key. I thought that it simply does not show regedit, but I can not open it through RegOpenKeyEx - returns:

error 87 (invalid parameter)

Although for any key everything works fine (I changed only the path to the key). Products like AVZ show these LSPs very well .. or do they take them from somewhere else?

  • On the desktop or on CE, which is described by reference? - karmadro4
  • Desktop, I just did not find a similar article for it, so I gave a link to CE - Seinar


1 answer 1

Using the WSCEnumProtocols function. Code based on an example from the Windows SDK :

#include <stdlib.h> #include <locale.h> #include <stdio.h> #include <tchar.h> #include <winsock2.h> #include <Windows.h> #include <ws2spi.h> //https://github.com/pauldotknopf/WindowsSDK7-Samples/blob/e8fe83b043727e71f5179da11fc6228475e7973c/netds/winsock/lsp/install/instlsp.cpp #pragma comment(lib,"Ws2_32.lib") typedef enum { LspCatalogBoth = 0, LspCatalog32Only, LspCatalog64Only } WINSOCK_CATALOG; //*** private LSP heap **** HANDLE gLspHeap = NULL; int LspCreateHeap( int *lpErrno ) { gLspHeap = HeapCreate( 0, 128000, 0 ); if ( NULL == gLspHeap ) { *lpErrno = WSAEPROVIDERFAILEDINIT; return SOCKET_ERROR; } return NO_ERROR; } void * LspAlloc( SIZE_T size, int *lpErrno ) { void *mem = NULL; mem = HeapAlloc( gLspHeap, HEAP_ZERO_MEMORY, size ); if ( NULL == mem ) { *lpErrno = WSAENOBUFS; } return mem; } void LspFree( LPVOID buf ) { HeapFree( gLspHeap, 0, buf ); } //********************************************** LPWSAPROTOCOL_INFOW EnumerateProviders( WINSOCK_CATALOG Catalog, LPINT TotalProtocols ) { LPWSAPROTOCOL_INFOW ProtocolInfo = NULL; DWORD ProtocolInfoSize = 0; INT ErrorCode = NO_ERROR, rc; if ( NULL == TotalProtocols ) goto cleanup; *TotalProtocols = 0; #ifdef _WIN64 // Find out how many entries we need to enumerate if ( LspCatalog64Only == Catalog ) { // Find the size of the buffer rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode ); if ( SOCKET_ERROR == rc ) { if ( WSAENOBUFS != ErrorCode ) goto cleanup; ErrorCode = NO_ERROR; } // Allocate the buffer ProtocolInfo = (LPWSAPROTOCOL_INFOW) LspAlloc( ProtocolInfoSize, &ErrorCode ); if (ProtocolInfo == NULL) goto cleanup; // Enumerate the catalog for real rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode ); if ( SOCKET_ERROR == rc ) goto cleanup; // Update the count *TotalProtocols = rc; } else if ( LspCatalog32Only == Catalog ) { HMODULE hModule; LPWSCENUMPROTOCOLS fnWscEnumProtocols32 = NULL; // Load ws2_32.dll hModule = LoadLibrary( TEXT( "ws2_32.dll" ) ); if ( NULL == hModule ) goto cleanup; // Find the 32-bit catalog enumerator fnWscEnumProtocols32 = (LPWSCENUMPROTOCOLS) GetProcAddress( hModule, "WSCEnumProtocols32" ); if ( NULL == fnWscEnumProtocols32 ) goto cleanup; // Find the required buffer size rc = fnWscEnumProtocols32(NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode); if ( SOCKET_ERROR == rc ) { if ( WSAENOBUFS != ErrorCode ) goto cleanup; ErrorCode = NO_ERROR; } // Allocate the buffer ProtocolInfo = (LPWSAPROTOCOL_INFOW) LspAlloc( ProtocolInfoSize, &ErrorCode ); if ( NULL == ProtocolInfo ) goto cleanup; // Enumrate the catalog for real this time rc = fnWscEnumProtocols32( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode ); if ( SOCKET_ERROR == rc ) goto cleanup; // Update the count *TotalProtocols = rc; FreeLibrary( hModule ); } #else if ( LspCatalog32Only == Catalog ) { // Find the size of the buffer rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode ); if ( SOCKET_ERROR == rc ) { if ( WSAENOBUFS != ErrorCode ) goto cleanup; ErrorCode = NO_ERROR; } // Allocate the buffer ProtocolInfo = (LPWSAPROTOCOL_INFOW) LspAlloc( ProtocolInfoSize, &ErrorCode ); if ( NULL == ProtocolInfo ) goto cleanup; // Enumerate the catalog for real rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode ); if ( SOCKET_ERROR == rc ) goto cleanup; // Update the count *TotalProtocols = rc; } else if ( LspCatalog64Only == Catalog ) { puts( "Unable to enumerate 64-bit Winsock catalog from 32-bit process!"); } #endif else { // Find the size of the buffer rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode ); if ( SOCKET_ERROR == rc ) { if ( WSAENOBUFS != ErrorCode ) goto cleanup; ErrorCode = NO_ERROR; } // Allocate the buffer ProtocolInfo = (LPWSAPROTOCOL_INFOW) LspAlloc( ProtocolInfoSize, &ErrorCode ); if ( NULL == ProtocolInfo ) goto cleanup; // Enumerate the catalog for real rc = WSCEnumProtocols( NULL, ProtocolInfo, &ProtocolInfoSize, &ErrorCode ); if ( SOCKET_ERROR == rc ) goto cleanup; // Update the count *TotalProtocols = rc; } cleanup: if ( ( NO_ERROR != ErrorCode ) && ( NULL != ProtocolInfo ) ) { LspFree( ProtocolInfo ); ProtocolInfo = NULL; } return ProtocolInfo; } 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 protocol information // printf("*** %S ***\n", wsapi->szProtocol); printf("Path: %S\n", wszProviderPath); // // 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); if(wsapi->ProtocolChain.ChainLen == LAYERED_PROTOCOL)printf("LSP: Yes\n"); else printf("LSP: No\n"); 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"); printf("Version: %d\n\n", wsapi->iVersion); } void FreeProviders( LPWSAPROTOCOL_INFOW ProtocolInfo ) { LspFree( ProtocolInfo ); } void PrintProviders( WINSOCK_CATALOG Catalog) { WSAPROTOCOL_INFOW *pProtocolInfo = NULL; INT iProtocolCount = 0, i; // Enumerate catalog and print it pProtocolInfo = EnumerateProviders( Catalog, &iProtocolCount ); if ( NULL == pProtocolInfo ) { fprintf( stderr, "PrintProviders: Unable to enumerate catalog!\n" ); goto cleanup; } for(i=0; i < iProtocolCount ;i++) { PrintProtocolInfo( &pProtocolInfo[ i ] ); } cleanup: if ( NULL != pProtocolInfo ) FreeProviders( pProtocolInfo ); return; } int main(void) { #ifdef _WIN64 WINSOCK_CATALOG eCatalog = /*LspCatalog64Only*/LspCatalogBoth; #else WINSOCK_CATALOG eCatalog = LspCatalog32Only; #endif WSADATA wsd; int rc; setlocale(LC_ALL,"Russian"); // Load Winsock rc = WSAStartup( MAKEWORD(2,2), &wsd ); if ( 0 != rc ) { fprintf( stderr, "Unable to load Winsock: %d\n", rc ); return -1; } // Initialize data structures LspCreateHeap( &rc ); // Print the 32-bit catalog if ( ( LspCatalogBoth == eCatalog ) || ( LspCatalog32Only == eCatalog ) ) { printf( "\n32-bit providers:\n\n" ); PrintProviders( LspCatalog32Only); printf( "=======================\n" ); } // Print the 64-bit catalog if ( ( LspCatalogBoth == eCatalog ) || ( LspCatalog64Only == eCatalog ) ) { printf( "\n64-bit providers:\n\n" ); PrintProviders( LspCatalog64Only); printf( "=======================\n" ); } system("PAUSE"); return 0; }