Compartilhar via


Função WSAEnumProtocolsW (winsock2.h)

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

Sintaxe

int WSAAPI WSAEnumProtocolsW(
  [in]      LPINT               lpiProtocols,
  [out]     LPWSAPROTOCOL_INFOW lpProtocolBuffer,
  [in, out] LPDWORD             lpdwBufferLength
);

Parâmetros

[in] lpiProtocols

Uma matriz NULLterminada 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 de 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 seja bem-sucedida. 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.

Valor de retorno

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

Código de 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âmetroslpiProtocols , lpProtocolBufferou lpdwBufferLength não são uma parte válida do espaço de endereço do usuário.

Observações

A função WSAEnumProtocols é usada para descobrir informações sobre a coleção de protocolos de transporte instalados no computador local. Os 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 de zero no lpProtocolBuffer.

Observação provedores de serviços em camadas são preteridos. Começando com o Windows 8 e o Windows Server 2012, use da 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ão especificados 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 os 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 por 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 igual ou superior (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 de 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 na qual 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 Do Windows Sockets ou da DLL fornecido para estabelecer provedores TCP/IP padrão.

Windows Phone 8: a função de WSAEnumProtocolsW tem suporte para aplicativos da 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 no 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;
}


Nota

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 do pré-processador UNICODE. A combinação do uso do alias neutro de codificação com código que não é neutro em codificação pode levar a incompatibilidades que resultam em erros de compilação ou de runtime. Para obter mais informações, consulte Conventions for Function Prototypes.

Requisitos

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

Consulte também

WSAPROTOCOL_INFO

WSCEnumProtocols

WSCEnumProtocols32

do Winsock Functions

referência Winsock