Функция WSCEnumProtocols32 (ws2spi.h)

Функция WSCEnumProtocols32 извлекает сведения о доступных транспортных протоколах.

Примечание Этот вызов является строго 32-разрядной версией WSCEnumProtocols для использования на 64-разрядных платформах. Он предоставляется для предоставления 64-разрядным процессам доступа к 32-разрядным каталогам.

 

Синтаксис

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

Параметры

[in] lpiProtocols

Массив значений iProtocol , завершающийся null. Этот параметр является необязательным; Если lpiProtocols имеет значение NULL, возвращаются сведения обо всех доступных протоколах. В противном случае сведения извлекаются только для протоколов, перечисленных в массиве.

[out] lpProtocolBuffer

Буфер, заполненный WSAPROTOCOL_INFOW структурами.

[in, out] lpdwBufferLength

На входе размер буфера lpProtocolBuffer , переданного в WSCEnumProtocols, в байтах. В выходных данных — минимальный размер буфера в байтах, который можно передать в WSCEnumProtocols для получения всех запрошенных сведений.

[out] lpErrno

Указатель на код ошибки.

Возвращаемое значение

Если ошибка не возникает, функция WSCEnumProtocols32 возвращает количество протоколов, которые должны быть переданы. В противном случае возвращается значение SOCKET_ERROR, а в lpErrno доступен определенный код ошибки.

Код ошибки Значение
WSAEFAULT
Один из аргументов не находится в допустимой части адресного пространства пользователя.
WSAEINVAL
Указывает, что один из указанных параметров был недопустимым.
WSAENOBUFS
Длина буфера была слишком мала для получения всех соответствующих WSAProtocol_Info структур и связанных сведений. Передайте буфер размером по крайней мере значение, возвращаемое в lpdwBufferLength.

Комментарии

WSCEnumProtocols32 — это строго 32-разрядная версия WSCEnumProtocols. На 64-разрядном компьютере все вызовы не только 32-разрядные (например, все функции, которые не заканчиваются на "32"), работают в собственном 64-разрядном каталоге. Процессы, выполняемые на 64-разрядном компьютере, должны использовать определенные вызовы 32-разрядных функций для работы со строго 32-разрядным каталогом и сохранения совместимости. Определения и семантика конкретных 32-разрядных вызовов совпадают с собственными аналогами.

Эта функция используется для обнаружения сведений о коллекции транспортных протоколов, установленных на локальном компьютере. Эта функция отличается от своего аналога API (WSAEnumProtocols) тем, что возвращаются WSAPROTOCOL_INFOW структуры для всех установленных протоколов. Сюда входят протоколы, которые поставщик услуг установил флаг PFL_HIDDEN в элементе dwProviderFlags структуры WSAPROTOCOL_INFOW , чтобы указать Ws2_32.dll, что этот протокол не должен возвращаться в буфере результатов, созданном функцией WSAEnumProtocols . Кроме того, WSCEnumProtocols32 также возвращает данные для WSAPROTOCOL_INFOW структур с нулевой длиной цепочки (фиктивный поставщик LSP). WSAEnumProtocols возвращает только сведения о базовых протоколах и цепочках протоколов, в которых отсутствует флаг PFL_HIDDEN и длина цепочки протоколов не равна нулю.

**Примечание** Многоуровневые поставщики услуг являются устаревшими. Начиная с Windows 8 и Windows Server 2012, используйте платформу фильтрации Windows.
 
Параметр lpiProtocols можно использовать в качестве фильтра для ограничения объема предоставленной информации. Как правило, предоставляется указатель NULL, поэтому функция возвращает сведения обо всех доступных транспортных протоколах.

Структура WSAPROTOCOL_INFOW предоставляется в буфере, на который указывает lpProtocolBuffer для каждого запрошенного протокола. Если предоставленный буфер недостаточно велик (как указано входным значением lpdwBufferLength), значение, на которое указывает lpdwBufferLength , будет обновлено для указания требуемого размера буфера. Затем клиент SPI windows Sockets должен получить достаточно большой буфер и снова вызвать эту функцию. Функция WSCEnumProtocols32 не может выполнять перечисление нескольких вызовов; Переданный буфер должен быть достаточно большим, чтобы вместить все ожидаемые записи, чтобы функция была успешной. Это снижает сложность функции и не должно создавать проблем, так как количество протоколов, загруженных на компьютер, как правило, невелико.

Порядок, в котором структуры WSAPROTOCOL_INFOW отображаются в буфере, совпадает с порядком, в котором записи протокола были зарегистрированы поставщиком услуг с помощью WS2_32.dll, или с любым последующим изменением порядка, которое могло произойти через приложение Windows Sockets, предоставленное для установления поставщиков транспорта по умолчанию.

Примеры

В следующем примере показано использование функции WSCEnumProtocols32 для использования на 64-разрядных платформах для получения массива WSAPROTOCOL_INFOW структур для протоколов, установленных на локальном компьютере в 32-разрядном каталоге.

#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 = WSCEnumProtocols32(NULL, lpProtocolInfo, &dwBufferLen, &iErrno);
    if (iNuminfo == SOCKET_ERROR) {
        if (iErrno != WSAENOBUFS) {
            wprintf(L"WSCEnumProtocols32 failed with error: %d\n", iErrno);
            if (lpProtocolInfo) {
                FREE(lpProtocolInfo);
                lpProtocolInfo = NULL;
            }
            WSACleanup();
            return 1;
        } else {
            wprintf(L"WSCEnumProtocols32 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 =
                WSCEnumProtocols32(NULL, lpProtocolInfo, &dwBufferLen, &iErrno);
            if (iNuminfo == SOCKET_ERROR) {
                wprintf(L"WSCEnumProtocols32 failed with error: %d\n", iErrno);
                if (lpProtocolInfo) {
                    FREE(lpProtocolInfo);
                    lpProtocolInfo = NULL;
                }
                WSACleanup();
                return 1;
            }

        }
    }

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


Требования

   
Минимальная версия клиента Windows Vista, Windows XP Professional x64 Edition [только классические приложения]
Минимальная версия сервера Windows Server 2008, Windows Server 2003 x64 Edition [только классические приложения]
Целевая платформа Windows
Header ws2spi.h
Библиотека Ws2_32.lib
DLL Ws2_32.dll

См. также раздел

WSAEnumProtocols

WSAPROTOCOL_INFOW

WSCEnumProtocols