Función WSAEnumProtocolsA (winsock2.h)

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

Sintaxis

int WSAAPI WSAEnumProtocolsA(
  [in]      LPINT               lpiProtocols,
  [out]     LPWSAPROTOCOL_INFOA lpProtocolBuffer,
  [in, out] LPDWORD             lpdwBufferLength
);

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_INFO .

[in, out] lpdwBufferLength

En la entrada, número de bytes en el búfer lpProtocolBuffer pasado a WSAEnumProtocols. En la salida, el tamaño mínimo del búfer que se puede pasar a WSAEnumProtocols para recuperar toda la información solicitada. Esta rutina no tiene capacidad para enumerar en varias llamadas; El búfer pasado debe ser lo suficientemente grande como para contener todas las entradas para que la rutina se realice correctamente. Esto reduce la complejidad de la API y no debe suponer un problema porque el número de protocolos cargados en un equipo suele ser pequeño.

Valor devuelto

Si no se produce ningún error, WSAEnumProtocols devuelve el número de protocolos que se van a notificar. De lo contrario, se devuelve un valor de SOCKET_ERROR y se puede recuperar un código de error específico llamando a WSAGetLastError.

Código de error Significado
WSANOTINITIALISED
Debe producirse una llamada de WSAStartup correcta antes de usar esta función.
WSAENETDOWN
Error en el subsistema de red.
WSAEINPROGRESS
Hay en curso una llamada de Bloqueo de Windows Sockets 1.1.
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 e información asociada. Pase un búfer al menos tan grande como el valor devuelto en lpdwBufferLength.
WSAEFAULT
Uno o varios de los parámetros lpiProtocols, lpProtocolBuffer o lpdwBufferLength no son una parte válida del espacio de direcciones del usuario.

Comentarios

La función WSAEnumProtocols se usa para detectar información sobre la colección de protocolos de transporte instalados en el equipo local. Las aplicaciones solo pueden usar protocolos en capas cuando se instalan en cadenas de protocolos. No se devuelve información sobre los protocolos en capas, excepto para los proveedores de servicios en capas ficticias (LSP) instalados con una longitud de cadena de cero en lpProtocolBuffer.

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. A menudo, lpiProtocols se especificará como un puntero NULL que hará que la función devuelva información sobre todos los protocolos de transporte y las cadenas de protocolo disponibles.

La función WSAEnumProtocols difiere de las funciones WSCEnumProtocols y WSCEnumProtocols32 en que la función WSAEnumProtocols no devuelve estructuras WSAPROTOCOL_INFO para todos los protocolos instalados. La función WSAEnumProtocols excluye los protocolos que el proveedor de servicios ha establecido con la marca PFL_HIDDEN en el miembro dwProviderFlags de la estructura WSAPROTOCOL_INFO 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, la función WSAEnumProtocols no devuelve datos para WSAPROTOCOL_INFO estructuras que tienen una longitud de cadena de uno o mayor (un proveedor LSP). 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.

Se proporciona una estructura WSAPROTOCOL_INFO en el búfer al que apunta lpProtocolBuffer para cada protocolo solicitado. Si el búfer especificado 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. A continuación, la aplicación debe obtener un búfer suficientemente grande y llamar a WSAEnumProtocols de nuevo.

El orden en que las estructuras de WSAPROTOCOL_INFO aparecen en el búfer coincide con el orden en el que el proveedor de servicios registró las entradas de protocolo mediante el WS2_32.DLL, o con cualquier reordenación posterior que se produjo a través de la aplicación o DLL de Windows Sockets proporcionada para establecer proveedores TCP/IP predeterminados.

Windows Phone 8: La función WSAEnumProtocolsW es compatible con las aplicaciones de Windows Phone Store en Windows Phone 8 y versiones posteriores.

Windows 8.1 y Windows Server 2012 R2: la función WSAEnumProtocolsW es compatible con las aplicaciones de la Tienda Windows en Windows 8.1, Windows Server 2012 R2 y versiones posteriores.

Ejemplos

En el ejemplo siguiente se muestra el uso de la función WSAEnumProtocols para recuperar una matriz de estructuras de WSAPROTOCOL_INFO para los protocolos de transporte disponibles.

#ifndef UNICODE
#define UNICODE 1
#endif

#include <winsock2.h>
#include <ws2tcpip.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 iError = 0;
    INT iNuminfo = 0;

    int i;

    // Allocate a 16K buffer to retrieve all the protocol providers
    DWORD dwBufferLen = 16384;

    LPWSAPROTOCOL_INFO lpProtocolInfo = NULL;

    // 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_INFO) MALLOC(dwBufferLen);
    if (lpProtocolInfo == NULL) {
        wprintf(L"Memory allocation for providers buffer failed\n");
        WSACleanup();
        return 1;
    }

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

        }
    }

    wprintf(L"WSAEnumProtocols 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;
}


Nota

El encabezado winsock2.h define WSAEnumProtocols como alias que selecciona automáticamente la versión ANSI o Unicode de esta función en función de la definición de la constante de preprocesador UNICODE. La combinación del uso del alias neutro de codificación con código que no es neutral de codificación puede provocar discrepancias que dan lugar a errores de compilación o en tiempo de ejecución. Para obtener más información, vea Convenciones para prototipos de función.

Requisitos

Requisito Value
Cliente mínimo compatible Windows 8.1, Windows Vista [aplicaciones de escritorio | Aplicaciones para UWP]
Servidor mínimo compatible Windows Server 2003 [aplicaciones de escritorio | aplicaciones para UWP]
Plataforma de destino Windows
Encabezado winsock2.h
Library Ws2_32.lib
Archivo DLL Ws2_32.dll

Consulte también

WSAPROTOCOL_INFO

WSCEnumProtocols

WSCEnumProtocols32

Funciones winsock

Referencia de Winsock