Функция WSCEnumProtocols (ws2spi.h)
Функция WSCEnumProtocols извлекает сведения о доступных транспортных протоколах.
Синтаксис
int WSCEnumProtocols(
[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
Указатель на код ошибки.
Возвращаемое значение
Если ошибка не возникает, WSCEnumProtocols возвращает количество протоколов, о которых нужно сообщить. В противном случае возвращается значение SOCKET_ERROR, а в lpErrno доступен определенный код ошибки.
Код ошибки | Значение |
---|---|
Один из нескольких аргументов не находится в допустимой части адресного пространства пользователя. | |
Указывает, что один из указанных параметров был недопустимым. | |
Длина буфера была слишком мала для получения всех соответствующих WSAProtocol_Info структур и связанных сведений. Передайте буфер размером не менее значения, возвращаемого в lpdwBufferLength. |
Комментарии
Функция WSCEnumProtocols используется для обнаружения сведений о коллекции транспортных протоколов, установленных на локальном компьютере. Эта функция отличается от своего аналога API (WSAEnumProtocols) тем, что возвращаются WSAPROTOCOL_INFOW структуры для всех установленных протоколов. К ним относятся протоколы, которые поставщик служб установил флаг PFL_HIDDEN в элементе dwProviderFlags структуры WSAPROTOCOL_INFOW , чтобы указать Ws2_32.dll, что этот протокол не должен возвращаться в буфере результатов, созданном функцией WSAEnumProtocols . Кроме того, WSCEnumProtocols также возвращает данные для WSAPROTOCOL_INFOW структур с нулевой длиной цепочки (фиктивный поставщик LSP). WSAEnumProtocols возвращает только сведения о базовых протоколах и цепочках протоколов, в которых отсутствует флаг PFL_HIDDEN и длина цепочки протоколов не равна нулю.
Структура WSAPROTOCOL_INFOW предоставляется в буфере, на который указывает lpProtocolBuffer для каждого запрошенного протокола. Если предоставленный буфер недостаточно велик (на что указывает входное значение lpdwBufferLength), значение, указываемое lpdwBufferLength , будет обновлено для указания требуемого размера буфера. Затем клиент WINDOWS Sockets SPI должен получить достаточно большой буфер и снова вызвать эту функцию. Функция WSCEnumProtocols не может выполнять перечисление нескольких вызовов; Передаваемый буфер должен быть достаточно большим, чтобы вместить все ожидаемые записи, чтобы функция была успешной. Это снижает сложность функции и не должно создавать проблем, так как количество протоколов, загруженных на локальный компьютер, обычно невелико.
Порядок, в котором структуры WSAPROTOCOL_INFOW отображаются в буфере, совпадает с порядком регистрации записей протокола поставщиком услуг с WS2_32.dll, или с любым последующим изменением порядка, которое могло произойти с помощью аплета Windows Sockets, предоставленного для создания поставщиков транспорта по умолчанию.
Примеры
В следующем примере показано использование функции WSCEnumProtocols для получения массива WSAPROTOCOL_INFOW структур для протоколов, установленных на локальном компьютере.
#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;
}
Требования
Минимальная версия клиента | Windows 2000 Professional [только классические приложения] |
Минимальная версия сервера | Windows 2000 Server [только классические приложения] |
Целевая платформа | Windows |
Header | ws2spi.h |
Библиотека | Ws2_32.lib |
DLL | Ws2_32.dll |