Função WSAEnumProtocolsA (winsock2.h)

A função WSAEnumProtocols recupera informações sobre protocolos de transporte disponíveis.

Sintaxe

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

Parâmetros

[in] lpiProtocols

Uma matriz terminada em NULL de valores iProtocol. Esse parâmetro é opcional; se lpiProtocols for NULL, as informações sobre todos os protocolos disponíveis serão retornadas. Caso contrário, as informações serão recuperadas apenas para os protocolos listados na matriz.

[out] lpProtocolBuffer

Um ponteiro para um buffer que é preenchido com estruturas WSAPROTOCOL_INFO .

[in, out] lpdwBufferLength

Na entrada, o número de bytes no buffer lpProtocolBuffer passado para WSAEnumProtocols. Na saída, o tamanho mínimo do buffer que pode ser passado para WSAEnumProtocols para recuperar todas as informações solicitadas. Essa rotina não tem capacidade de enumerar em várias chamadas; o buffer passado deve ser grande o suficiente para manter todas as entradas para que a rotina tenha êxito. Isso reduz a complexidade da API e não deve representar um problema porque o número de protocolos carregados em um computador normalmente é pequeno.

Retornar valor

Se nenhum erro ocorrer, WSAEnumProtocols retornará o número de protocolos a serem relatados. Caso contrário, um valor de SOCKET_ERROR será retornado e um código de erro específico poderá ser recuperado chamando WSAGetLastError.

Código do erro Significado
WSANOTINITIALISED
Uma chamada WSAStartup bem-sucedida deve ocorrer antes de usar essa função.
WSAENETDOWN
O subsistema de rede falhou.
WSAEINPROGRESS
Uma chamada de bloqueio do Windows Sockets 1.1 está em andamento.
WSAEINVAL
Indica que um dos parâmetros especificados era inválido.
WSAENOBUFS
O comprimento do buffer era muito pequeno para receber todas as estruturas de WSAPROTOCOL_INFO relevantes e informações associadas. Passe um buffer pelo menos tão grande quanto o valor retornado em lpdwBufferLength.
WSAEFAULT
Um ou mais dos parâmetros lpiProtocols, lpProtocolBuffer ou lpdwBufferLength não são uma parte válida do espaço de endereço do usuário.

Comentários

A função WSAEnumProtocols é usada para descobrir informações sobre a coleção de protocolos de transporte instalados no computador local. Protocolos em camadas só podem ser usados por aplicativos quando instalados em cadeias de protocolo. As informações sobre protocolos em camadas não são retornadas, exceto para quaisquer LSPs (provedores de serviços em camadas) fictícios instalados com um comprimento de cadeia zero no lpProtocolBuffer.

Nota Os Provedores de Serviços em Camadas foram preteridos. Começando com Windows 8 e Windows Server 2012, use a Plataforma de Filtragem do Windows.
 
O parâmetro lpiProtocols pode ser usado como um filtro para restringir a quantidade de informações fornecidas. Muitas vezes, lpiProtocols será especificado como um ponteiro NULL que fará com que a função retorne informações sobre todos os protocolos de transporte e cadeias de protocolo disponíveis.

A função WSAEnumProtocols difere das funções WSCEnumProtocols e WSCEnumProtocols32 , pois a função WSAEnumProtocols não retorna estruturas WSAPROTOCOL_INFO para todos os protocolos instalados. A função WSAEnumProtocols exclui protocolos que o provedor de serviços definiu com o sinalizador PFL_HIDDEN no membro dwProviderFlags da estrutura WSAPROTOCOL_INFO para indicar ao Ws2_32.dll que esse protocolo não deve ser retornado no buffer de resultados gerado pela função WSAEnumProtocols . Além disso, a função WSAEnumProtocols não retorna dados para estruturas WSAPROTOCOL_INFO que têm um comprimento de cadeia de um ou mais (um provedor LSP). O WSAEnumProtocols retorna apenas informações sobre protocolos base e cadeias de protocolo que não têm o sinalizador PFL_HIDDEN e não têm um comprimento de cadeia de protocolo zero.

Uma estrutura WSAPROTOCOL_INFO é fornecida no buffer apontado por lpProtocolBuffer para cada protocolo solicitado. Se o buffer especificado não for grande o suficiente (conforme indicado pelo valor de entrada de lpdwBufferLength ), o valor apontado por lpdwBufferLength será atualizado para indicar o tamanho do buffer necessário. Em seguida, o aplicativo deve obter um buffer grande o suficiente e chamar WSAEnumProtocols novamente.

A ordem na qual as estruturas de WSAPROTOCOL_INFO aparecem no buffer coincide com a ordem em que as entradas de protocolo foram registradas pelo provedor de serviços usando o WS2_32.DLL ou com qualquer reordenação subsequente que ocorreu por meio do aplicativo Windows Sockets ou da DLL fornecida para estabelecer provedores de TCP/IP padrão.

Windows Phone 8: a função WSAEnumProtocolsW tem suporte para aplicativos Windows Phone Store no Windows Phone 8 e posterior.

Windows 8.1 e Windows Server 2012 R2: a função WSAEnumProtocolsW tem suporte para aplicativos da Windows Store em Windows 8.1, Windows Server 2012 R2 e posterior.

Exemplos

O exemplo a seguir demonstra o uso da função WSAEnumProtocols para recuperar uma matriz de estruturas de WSAPROTOCOL_INFO para protocolos de transporte disponíveis.

#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;
}


Observação

O cabeçalho winsock2.h define WSAEnumProtocols como um alias que seleciona automaticamente a versão ANSI ou Unicode dessa função com base na definição da constante de pré-processador UNICODE. Misturar o uso do alias neutro de codificação com código que não seja neutro em codificação pode levar a incompatibilidades que resultam em erros de compilação ou de runtime. Para obter mais informações, consulte Convenções para protótipos de função.

Requisitos

Requisito Valor
Cliente mínimo com suporte Windows 8.1, Windows Vista [aplicativos da área de trabalho | Aplicativos UWP]
Servidor mínimo com suporte Windows Server 2003 [aplicativos da área de trabalho | Aplicativos UWP]
Plataforma de Destino Windows
Cabeçalho winsock2.h
Biblioteca Ws2_32.lib
DLL Ws2_32.dll

Confira também

WSAPROTOCOL_INFO

WSCEnumProtocols

WSCEnumProtocols32

Funções Winsock

Referência de Winsock