Функция WSAEnumProtocolsA (winsock2.h)
Функция WSAEnumProtocols извлекает сведения о доступных транспортных протоколах.
Синтаксис
int WSAAPI WSAEnumProtocolsA(
[in] LPINT lpiProtocols,
[out] LPWSAPROTOCOL_INFOA lpProtocolBuffer,
[in, out] LPDWORD lpdwBufferLength
);
Параметры
[in] lpiProtocols
Массив значений iProtocol, заканчивающийся значением NULL. Этот параметр является необязательным; Если lpiProtocols имеет значение NULL, возвращаются сведения обо всех доступных протоколах. В противном случае сведения извлекаются только для протоколов, перечисленных в массиве.
[out] lpProtocolBuffer
Указатель на буфер, заполненный WSAPROTOCOL_INFO структурами.
[in, out] lpdwBufferLength
Во входных данных — количество байтов в буфере lpProtocolBuffer , передаваемого в WSAEnumProtocols. В выходных данных — минимальный размер буфера, который можно передать в WSAEnumProtocols для получения всех запрошенных сведений. Эта подпрограмма не может выполнять перечисление нескольких вызовов; Переданный буфер должен быть достаточно большим, чтобы вместить все записи, чтобы подпрограмма была успешной. Это снижает сложность API и не должно создавать проблем, так как количество протоколов, загруженных на компьютер, как правило, невелико.
Возвращаемое значение
Если ошибка не возникает, WSAEnumProtocols возвращает количество протоколов, которые необходимо сообщить. В противном случае возвращается значение SOCKET_ERROR, и можно получить определенный код ошибки, вызвав WSAGetLastError.
Код ошибки | Значение |
---|---|
Перед использованием этой функции должен произойти успешный вызов WSAStartup . | |
Произошел сбой сетевой подсистемы. | |
Выполняется блокирующий вызов Windows Sockets 1.1. | |
Указывает, что один из указанных параметров был недопустимым. | |
Длина буфера была слишком мала для получения всех соответствующих WSAPROTOCOL_INFO структур и связанных с ними сведений. Передайте буфер размером по крайней мере значение, возвращаемое в lpdwBufferLength. | |
Один или несколько параметров lpiProtocols, lpProtocolBuffer или lpdwBufferLength не являются допустимой частью адресного пространства пользователя. |
Комментарии
Функция WSAEnumProtocols используется для обнаружения сведений о коллекции транспортных протоколов, установленных на локальном компьютере. Многоуровневые протоколы могут использоваться приложениями только при установке в цепочках протоколов. Сведения о многоуровневых протоколах не возвращаются, за исключением фиктивных поставщиков многоуровневых служб (LSP), установленных с нулевой длиной цепочки в lpProtocolBuffer.
Функция WSAEnumProtocols отличается от функций WSCEnumProtocols и WSCEnumProtocols32 тем, что функция WSAEnumProtocols не возвращает WSAPROTOCOL_INFO структуры для всех установленных протоколов. Функция WSAEnumProtocols исключает протоколы, установленные поставщиком услуг с флагом PFL_HIDDEN в элементе dwProviderFlags структуры WSAPROTOCOL_INFO , чтобы указать Ws2_32.dll, что этот протокол не должен возвращаться в буфере результатов, созданном функцией WSAEnumProtocols . Кроме того, функция WSAEnumProtocols не возвращает данные для WSAPROTOCOL_INFO структур, длина цепочки которых равна одной или больше (поставщик LSP). WSAEnumProtocols возвращает только сведения о базовых протоколах и цепочках протоколов, в которых отсутствует флаг PFL_HIDDEN и длина цепочки протоколов не равна нулю.
Структура WSAPROTOCOL_INFO предоставляется в буфере, на который указывает lpProtocolBuffer для каждого запрошенного протокола. Если указанный буфер недостаточно велик (как указано входным значением lpdwBufferLength ), значение, на которое указывает lpdwBufferLength , будет обновлено для указания требуемого размера буфера. Затем приложение должно получить достаточно большой буфер и снова вызвать WSAEnumProtocols .
Порядок, в котором структуры WSAPROTOCOL_INFO отображаются в буфере, совпадает с порядком, в котором записи протокола были зарегистрированы поставщиком услуг с помощью WS2_32.DLL, или с любым последующим изменением порядка, которое произошло с помощью приложения Windows Sockets или библиотеки DLL, предоставленной для установки поставщиков TCP/IP по умолчанию.
Windows Phone 8. Функция WSAEnumProtocolsW поддерживается для приложений Магазина Windows Phone на Windows Phone 8 и более поздних версий.
Windows 8.1 и Windows Server 2012 R2. Функция WSAEnumProtocolsW поддерживается для приложений Магазина Windows на Windows 8.1, Windows Server 2012 R2 и более поздних версиях.
Примеры
В следующем примере показано использование функции WSAEnumProtocols для получения массива WSAPROTOCOL_INFO структур для доступных транспортных протоколов.
#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;
}
Примечание
Заголовок winsock2.h определяет WSAEnumProtocols в качестве псевдонима, который автоматически выбирает версию ANSI или Юникод этой функции на основе определения константы препроцессора ЮНИКОД. Использование псевдонима, не зависящий от кодирования, с кодом, который не является нейтральным для кодировки, может привести к несоответствиям, которые приводят к ошибкам компиляции или времени выполнения. Дополнительные сведения см. в разделе Соглашения для прототипов функций.
Требования
Требование | Значение |
---|---|
Минимальная версия клиента | Windows 8.1, Windows Vista [классические приложения | Приложения UWP] |
Минимальная версия сервера | Windows Server 2003 [классические приложения | Приложения UWP] |
Целевая платформа | Windows |
Header | winsock2.h |
Библиотека | Ws2_32.lib |
DLL | Ws2_32.dll |