Función WSCEnumProtocols (ws2spi.h)

La función WSCEnumProtocols recupera información sobre los protocolos de transporte disponibles.

Sintaxis

int WSCEnumProtocols(
  [in]      LPINT               lpiProtocols,
  [out]     LPWSAPROTOCOL_INFOW lpProtocolBuffer,
  [in, out] LPDWORD             lpdwBufferLength,
  [out]     LPINT               lpErrno
);

Parámetros

[in] lpiProtocols

Matriz terminada en NULL de valores iProtocol . Este parámetro es opcional; Si lpiProtocols es NULL, se devuelve información sobre todos los protocolos disponibles. De lo contrario, la información solo se recupera para los protocolos enumerados en la matriz.

[out] lpProtocolBuffer

Puntero a un búfer que se rellena con estructuras de WSAPROTOCOL_INFOW .

[in, out] lpdwBufferLength

En la entrada, el tamaño del búfer lpProtocolBuffer pasado a WSCEnumProtocols, en bytes. En la salida, el tamaño mínimo del búfer, en bytes, que se puede pasar a WSCEnumProtocols para recuperar toda la información solicitada.

[out] lpErrno

Puntero al código de error.

Valor devuelto

Si no se produce ningún error, WSCEnumProtocols devuelve el número de protocolos en los que se notificará. De lo contrario, se devuelve un valor de SOCKET_ERROR y hay disponible un código de error específico en lpErrno.

Código de error Significado
WSAEFAULT
Uno de los argumentos no está en una parte válida del espacio de direcciones del usuario.
WSAEINVAL
Indica que uno de los parámetros especificados no era válido.
WSAENOBUFS
La longitud del búfer era demasiado pequeña para recibir todas las estructuras de WSAProtocol_Info pertinentes y la información asociada. Pase un búfer al menos tan grande como el valor devuelto en lpdwBufferLength.

Observaciones

La función WSCEnumProtocols se usa para detectar información sobre la colección de protocolos de transporte instalados en el equipo local. Esta función difiere de su homólogo de API (WSAEnumProtocols) en que se devuelven las estructuras de WSAPROTOCOL_INFOW para todos los protocolos instalados. Esto incluye protocolos que el proveedor de servicios ha establecido la marca PFL_HIDDEN en el miembro dwProviderFlags de la estructura WSAPROTOCOL_INFOW para indicar al Ws2_32.dll que este protocolo no debe devolverse en el búfer de resultados generado por la función WSAEnumProtocols . Además, WSCEnumProtocols también devuelve datos para WSAPROTOCOL_INFOW estructuras que tienen una longitud de cadena de cero (un proveedor LSP ficticio). WSAEnumProtocols solo devuelve información sobre los protocolos base y las cadenas de protocolo que carecen de la marca PFL_HIDDEN y no tienen una longitud de cadena de protocolo de cero.

**Nota** Los proveedores de servicios en capas están en desuso. A partir de Windows 8 y Windows Server 2012, use la Plataforma de filtrado de Windows.
 
El parámetro lpiProtocols se puede usar como filtro para restringir la cantidad de información proporcionada. Normalmente, se proporciona un puntero NULO para que la función devuelva información sobre todos los protocolos de transporte disponibles.

Se proporciona una estructura WSAPROTOCOL_INFOW en el búfer al que apunta lpProtocolBuffer para cada protocolo solicitado. Si el búfer proporcionado no es lo suficientemente grande (como se indica en el valor de entrada de lpdwBufferLength), el valor al que apunta lpdwBufferLength se actualizará para indicar el tamaño de búfer necesario. El cliente SPI de Windows Sockets debe obtener un búfer suficientemente grande y llamar a esta función de nuevo. La función WSCEnumProtocols no puede enumerar en varias llamadas; El búfer pasado debe ser lo suficientemente grande como para contener todas las entradas esperadas para que la función se realice correctamente. Esto reduce la complejidad de la función y no debe suponer un problema porque el número de protocolos cargados en un equipo local suele ser pequeño.

El orden en que las estructuras de WSAPROTOCOL_INFOW aparecen en el búfer coincide con el orden en el que el proveedor de servicios registró las entradas del protocolo con el WS2_32.dll, o con cualquier reordenación posterior que pueda haberse producido a través del applet de Windows Sockets proporcionado para establecer proveedores de transporte predeterminados.

Ejemplos

En el ejemplo siguiente se muestra el uso de la función WSCEnumProtocols para recuperar una matriz de estructuras de WSAPROTOCOL_INFOW para los protocolos instalados en el equipo local.

#ifndef UNICODE
#define UNICODE 1
#endif

#include <winsock2.h>
#include <ws2tcpip.h>
#include <ws2spi.h>
#include <objbase.h>
#include <stdio.h>

// Link with ws2_32.lib and ole32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "ole32.lib")

#define MALLOC(x) HeapAlloc(GetProcessHeap(), 0, (x))
#define FREE(x) HeapFree(GetProcessHeap(), 0, (x))
// Note: could also use malloc() and free()

int wmain()
{

    //-----------------------------------------
    // Declare and initialize variables
    WSADATA wsaData;
    int iResult = 0;

    INT iNuminfo = 0;

    int i;

    // Allocate a 16K buffer to retrieve all the protocol providers
    DWORD dwBufferLen = 16384;
    LPWSAPROTOCOL_INFOW lpProtocolInfo = NULL;
    int iErrno = 0;

    // variables needed for converting provider GUID to a string
    int iRet = 0;
    WCHAR GuidString[40] = { 0 };

    // Initialize Winsock
    iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
    if (iResult != 0) {
        wprintf(L"WSAStartup failed: %d\n", iResult);
        return 1;
    }

    lpProtocolInfo = (LPWSAPROTOCOL_INFOW) MALLOC(dwBufferLen);
    if (lpProtocolInfo == NULL) {
        wprintf(L"Memory allocation for providers buffer failed\n");
        WSACleanup();
        return 1;
    }

    iNuminfo = WSCEnumProtocols(NULL, lpProtocolInfo, &dwBufferLen, &iErrno);
    if (iNuminfo == SOCKET_ERROR) {
        if (iErrno != WSAENOBUFS) {
            wprintf(L"WSCEnumProtocols failed with error: %d\n", iErrno);
            if (lpProtocolInfo) {
                FREE(lpProtocolInfo);
                lpProtocolInfo = NULL;
            }
            WSACleanup();
            return 1;
        } else {
            wprintf(L"WSCEnumProtocols failed with error: WSAENOBUFS (%d)\n",
                    iErrno);
            wprintf(L"  Increasing buffer size to %d\n\n", dwBufferLen);
            if (lpProtocolInfo) {
                FREE(lpProtocolInfo);
                lpProtocolInfo = NULL;
            }
            lpProtocolInfo = (LPWSAPROTOCOL_INFOW) MALLOC(dwBufferLen);
            if (lpProtocolInfo == NULL) {
                wprintf(L"Memory allocation increase for buffer failed\n");
                WSACleanup();
                return 1;
            }
            iNuminfo =
                WSCEnumProtocols(NULL, lpProtocolInfo, &dwBufferLen, &iErrno);
            if (iNuminfo == SOCKET_ERROR) {
                wprintf(L"WSCEnumProtocols failed with error: %d\n", iErrno);
                if (lpProtocolInfo) {
                    FREE(lpProtocolInfo);
                    lpProtocolInfo = NULL;
                }
                WSACleanup();
                return 1;
            }

        }
    }

    wprintf(L"WSCEnumProtocols succeeded with protocol count = %d\n\n",
            iNuminfo);
    for (i = 0; i < iNuminfo; i++) {
        wprintf(L"Winsock Catalog Provider Entry #%d\n", i);
        wprintf
            (L"----------------------------------------------------------\n");
        wprintf(L"Entry type:\t\t\t ");
        if (lpProtocolInfo[i].ProtocolChain.ChainLen == 1)
            wprintf(L"Base Service Provider\n");
        else
            wprintf(L"Layered Chain Entry\n");

        wprintf(L"Protocol:\t\t\t %ws\n", lpProtocolInfo[i].szProtocol);

        iRet =
            StringFromGUID2(lpProtocolInfo[i].ProviderId,
                            (LPOLESTR) & GuidString, 39);
        if (iRet == 0)
            wprintf(L"StringFromGUID2 failed\n");
        else
            wprintf(L"Provider ID:\t\t\t %ws\n", GuidString);

        wprintf(L"Catalog Entry ID:\t\t %u\n",
                lpProtocolInfo[i].dwCatalogEntryId);

        wprintf(L"Version:\t\t\t %d\n", lpProtocolInfo[i].iVersion);

        wprintf(L"Address Family:\t\t\t %d\n",
                lpProtocolInfo[i].iAddressFamily);
        wprintf(L"Max Socket Address Length:\t %d\n",
                lpProtocolInfo[i].iMaxSockAddr);
        wprintf(L"Min Socket Address Length:\t %d\n",
                lpProtocolInfo[i].iMinSockAddr);

        wprintf(L"Socket Type:\t\t\t %d\n", lpProtocolInfo[i].iSocketType);
        wprintf(L"Socket Protocol:\t\t %d\n", lpProtocolInfo[i].iProtocol);
        wprintf(L"Socket Protocol Max Offset:\t %d\n",
                lpProtocolInfo[i].iProtocolMaxOffset);

        wprintf(L"Network Byte Order:\t\t %d\n",
                lpProtocolInfo[i].iNetworkByteOrder);
        wprintf(L"Security Scheme:\t\t %d\n",
                lpProtocolInfo[i].iSecurityScheme);
        wprintf(L"Max Message Size:\t\t %u\n", lpProtocolInfo[i].dwMessageSize);

        wprintf(L"ServiceFlags1:\t\t\t 0x%x\n",
                lpProtocolInfo[i].dwServiceFlags1);
        wprintf(L"ServiceFlags2:\t\t\t 0x%x\n",
                lpProtocolInfo[i].dwServiceFlags2);
        wprintf(L"ServiceFlags3:\t\t\t 0x%x\n",
                lpProtocolInfo[i].dwServiceFlags3);
        wprintf(L"ServiceFlags4:\t\t\t 0x%x\n",
                lpProtocolInfo[i].dwServiceFlags4);
        wprintf(L"ProviderFlags:\t\t\t 0x%x\n",
                lpProtocolInfo[i].dwProviderFlags);

        wprintf(L"Protocol Chain length:\t\t %d\n",
                lpProtocolInfo[i].ProtocolChain.ChainLen);

        wprintf(L"\n");
    }

    if (lpProtocolInfo) {
        FREE(lpProtocolInfo);
        lpProtocolInfo = NULL;
    }
    WSACleanup();

    return 0;
}


Requisitos

   
Cliente mínimo compatible Windows 2000 Professional [solo aplicaciones de escritorio]
Servidor mínimo compatible Windows 2000 Server [solo aplicaciones de escritorio]
Plataforma de destino Windows
Encabezado ws2spi.h
Library Ws2_32.lib
Archivo DLL Ws2_32.dll

Consulte también

WSAEnumProtocols

WSAPROTOCOL_INFOW

WSCEnumProtocols32