dwServiceFlags1: DWORD;
dwServiceFlags2: DWORD;
dwServicsFlags3: DWORD;
dwServiceFlags4: DWORD;
dwProviderFlags: DWORD;
ProviderId: GUID;
dwCatalogEntryId: DWORD;
ProtocolChain: TWSAProtocolChain;
iVersion: Integer;
iAddressFamily: Integer;
iMaxSockAddr: Integer;
iMinSockAddr: Integer;
iSocketType: Integer;
iProtocol: Integer;
iProtocolMaxOffset: Integer;
iNetworkByteOrder: Integer;
iSecurityScheme: Integer;
dwMessageSize: DWORD;
dwProviderReserved: DWORD;
szProtocol: array [0..WSAPROTOCOL_LEN] of Char;
end;
Расшифровка полей типа TWSAProtocolInfo
есть в MSDN, мы здесь не будем ее приводить.
Сама функция WSAEnumProtocols
, которая позволяет получить список всех протоколов, провайдеры которых установлены на компьютере, приведена в листинге 2.37.
WSAEnumProtocols
// ***** описание на C++ *****
int WSAEnumProtocols(LPINT lpiProtocols, LPWSAPROTOCOL_INFO lpProtocolBuffer, LPDWORD lpdwBufferLength);
// ***** Описание на Delphi *****
function WSAEnumProtocols(lpiProtocols: PInteger; lpProtocolBuffer: PWSAProtocolInfo; var BufferLength: DWORD): Integer;
В старых версиях MSDN в описании этой функции есть небольшая опечатка: тип параметра lpdwBufferLength
назван LLPDWORD
вместо LPDWORD
.
Библиотека WS2_32.dll придерживается тех же правил насчет ANSI- и Unicode-вариантов функций, что и другие системные библиотеки (см. разд. 1.1.12), поэтому в ней нет функции с именем WSAEnumProtocols
, а есть WSAEnumProtocolsA
и WSAEnumProtocolsW
. Эти функции работают с разными вариантами структуры WSAPROTOCOL_INFO
, которые различаются типом элементов в последнем массиве — CHAR
или WCHAR
.
Параметр lpiProtocols
указывает на первый элемент массива, содержащего список протоколов, информацию о которых нужно получить. Если этот указатель равен nil
, то возвращается информация обо всех доступных протоколах. Параметр lpProtocolBuffer
содержит указатель на начало массива структур типа TWSAProtocolInfo
. Программа должна заранее выделить память под этот массив. Параметр BufferLength
при вызове должен содержать размер буфера lpProtocolBuffer
в байтах (именно размер в байтах, а не количество элементов). После завершения функции сюда помешается минимальный размер буфера, необходимый для размещения информации обо всех запрошенных протоколах. Если это значение больше переданного, функция завершается с ошибкой.
Если параметр lpiProtocols
не равен нулю, он должен содержать указатель на массив, завершающийся нулем. Следовательно, если количество протоколов, запрашиваемых программой, равно
В системе может быть установлено несколько провайдеров для одного протокола. В этом случае информация о каждом провайдере будет помещена в отдельный элемент массива. Из-за этого число задействованных элементов в массиве lpProtocolBuffer
может превышать количество протоколов, определяемых параметром lpiProtocols
.
К сожалению, полную информацию о том, каким протоколам какие номера соответствуют, в документации найти не удалось. Можно только сказать, что для получения информации о протоколе TCP в массив lpiProtocols
необходимо поместить константу IPPROTO_TCP
, о протоколе UDP — константу IPPROTO_UDP
.