Compartilhar via


Função WSCEnumProtocols (ws2spi.h)

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

Sintaxe

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

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

[in, out] lpdwBufferLength

Na entrada, o tamanho do buffer lpProtocolBuffer passado para WSCEnumProtocols, em bytes. Na saída, o tamanho mínimo do buffer, em bytes, que pode ser passado para WSCEnumProtocols para recuperar todas as informações solicitadas.

[out] lpErrno

Um ponteiro para o código de erro.

Valor retornado

Se nenhum erro ocorrer, WSCEnumProtocols 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 estará disponível em lpErrno.

Código do erro Significado
WSAEFAULT
Um dos argumentos a mais não está em uma parte válida do espaço de endereço do usuário.
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.

Comentários

A função WSCEnumProtocols é usada para descobrir informações sobre a coleção de protocolos de transporte instalados no computador local. Essa função é diferente de sua contraparte de API (WSAEnumProtocols) na qual WSAPROTOCOL_INFOW estruturas para todos os protocolos instalados são retornadas. Isso inclui protocolos que o provedor de serviços definiu o sinalizador PFL_HIDDEN no membro dwProviderFlags da estrutura WSAPROTOCOL_INFOW 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, o WSCEnumProtocols também retorna dados para estruturas WSAPROTOCOL_INFOW que têm um comprimento de cadeia zero ( um provedor LSP fictício). 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.

**Observação** Os provedores de serviços em camadas foram preteridos. A partir do Windows 8 e do 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. Normalmente, um ponteiro nulo é fornecido para que a função retorne informações sobre todos os protocolos de transporte disponíveis.

Uma estrutura WSAPROTOCOL_INFOW é fornecida no buffer apontado por lpProtocolBuffer para cada protocolo solicitado. Se o buffer fornecido 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. O cliente SPI do Windows Sockets deve obter um buffer grande o suficiente e chamar essa função novamente. A função WSCEnumProtocols não pode enumerar em várias chamadas; o buffer passado deve ser grande o suficiente para manter todas as entradas esperadas para que a função tenha êxito. Isso reduz a complexidade da função e não deve representar um problema porque o número de protocolos carregados em um computador local normalmente é pequeno.

A ordem na qual as estruturas de WSAPROTOCOL_INFOW aparecem no buffer coincide com a ordem em que as entradas de protocolo foram registradas pelo provedor de serviços com o WS2_32.dll ou com qualquer reordenação subsequente que possa ter ocorrido por meio do miniaplicativo Windows Sockets fornecido para estabelecer provedores de transporte padrão.

Exemplos

O exemplo a seguir demonstra o uso da função WSCEnumProtocols para recuperar uma matriz de estruturas de WSAPROTOCOL_INFOW para protocolos instalados no computador 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 com suporte Windows 2000 Professional [somente aplicativos da área de trabalho]
Servidor mínimo com suporte Windows 2000 Server [somente aplicativos da área de trabalho]
Plataforma de Destino Windows
Cabeçalho ws2spi.h
Biblioteca Ws2_32.lib
DLL Ws2_32.dll

Confira também

Wsaenumprotocols

WSAPROTOCOL_INFOW

WSCEnumProtocols32