Edit

Share via


WSAEnumProtocolsA function (winsock2.h)

The WSAEnumProtocols function retrieves information about available transport protocols.

Syntax

int WSAAPI WSAEnumProtocolsA(
  [in]      LPINT               lpiProtocols,
  [out]     LPWSAPROTOCOL_INFOA lpProtocolBuffer,
  [in, out] LPDWORD             lpdwBufferLength
);

Parameters

[in] lpiProtocols

A NULL-terminated array of iProtocol values. This parameter is optional; if lpiProtocols is NULL, information on all available protocols is returned. Otherwise, information is retrieved only for those protocols listed in the array.

[out] lpProtocolBuffer

A pointer to a buffer that is filled with WSAPROTOCOL_INFO structures.

[in, out] lpdwBufferLength

On input, number of bytes in the lpProtocolBuffer buffer passed to WSAEnumProtocols. On output, the minimum buffer size that can be passed to WSAEnumProtocols to retrieve all the requested information. This routine has no ability to enumerate over multiple calls; the passed-in buffer must be large enough to hold all entries in order for the routine to succeed. This reduces the complexity of the API and should not pose a problem because the number of protocols loaded on a computer is typically small.

Return value

If no error occurs, WSAEnumProtocols returns the number of protocols to be reported. Otherwise, a value of SOCKET_ERROR is returned and a specific error code can be retrieved by calling WSAGetLastError.

Error code Meaning
WSANOTINITIALISED
A successful WSAStartup call must occur before using this function.
WSAENETDOWN
The network subsystem has failed.
WSAEINPROGRESS
A blocking Windows Sockets 1.1 call is in progress.
WSAEINVAL
Indicates that one of the specified parameters was invalid.
WSAENOBUFS
The buffer length was too small to receive all the relevant WSAPROTOCOL_INFO structures and associated information. Pass in a buffer at least as large as the value returned in lpdwBufferLength.
WSAEFAULT
One or more of the lpiProtocols, lpProtocolBuffer, or lpdwBufferLength parameters are not a valid part of the user address space.

Remarks

The WSAEnumProtocols function is used to discover information about the collection of transport protocols installed on the local computer. Layered protocols are only usable by applications when installed in protocol chains. Information on layered protocols is not returned except for any dummy layered service providers (LSPs) installed with a chain length of zero in the lpProtocolBuffer.

Note  Layered Service Providers are deprecated. Starting with Windows 8 and Windows Server 2012, use Windows Filtering Platform.
 
The lpiProtocols parameter can be used as a filter to constrain the amount of information provided. Often, lpiProtocols will be specified as a NULL pointer that will cause the function to return information on all available transport protocols and protocol chains.

The WSAEnumProtocols function differs from the WSCEnumProtocols and WSCEnumProtocols32 functions in that the WSAEnumProtocols function doesn't return WSAPROTOCOL_INFO structures for all installed protocols. The WSAEnumProtocols function excludes protocols that the service provider has set with the PFL_HIDDEN flag in the dwProviderFlags member of the WSAPROTOCOL_INFO structure to indicate to the Ws2_32.dll that this protocol should not be returned in the result buffer generated by WSAEnumProtocols function. In addition, the WSAEnumProtocols function does not return data for WSAPROTOCOL_INFO structures that have a chain length of one or greater (an LSP provider). The WSAEnumProtocols only returns information on base protocols and protocol chains that lack the PFL_HIDDEN flag and don't have a protocol chain length of zero.

A WSAPROTOCOL_INFO structure is provided in the buffer pointed to by lpProtocolBuffer for each requested protocol. If the specified buffer is not large enough (as indicated by the input value of lpdwBufferLength ), the value pointed to by lpdwBufferLength will be updated to indicate the required buffer size. The application should then obtain a large enough buffer and call WSAEnumProtocols again.

The order in which the WSAPROTOCOL_INFO structures appear in the buffer coincides with the order in which the protocol entries were registered by the service provider using the WS2_32.DLL, or with any subsequent reordering that occurred through the Windows Sockets application or DLL supplied for establishing default TCP/IP providers.

Windows Phone 8: The WSAEnumProtocolsW function is supported for Windows Phone Store apps on Windows Phone 8 and later.

Windows 8.1 and Windows Server 2012 R2: The WSAEnumProtocolsW function is supported for Windows Store apps on Windows 8.1, Windows Server 2012 R2, and later.

Examples

The following example demonstrates the use of the WSAEnumProtocols function to retrieve an array of WSAPROTOCOL_INFO structures for available transport protocols.

#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;
}


Note

The winsock2.h header defines WSAEnumProtocols as an alias that automatically selects the ANSI or Unicode version of this function based on the definition of the UNICODE preprocessor constant. Mixing usage of the encoding-neutral alias with code that is not encoding-neutral can lead to mismatches that result in compilation or runtime errors. For more information, see Conventions for Function Prototypes.

Requirements

Requirement Value
Minimum supported client Windows 8.1, Windows Vista [desktop apps | UWP apps]
Minimum supported server Windows Server 2003 [desktop apps | UWP apps]
Target Platform Windows
Header winsock2.h
Library Ws2_32.lib
DLL Ws2_32.dll

See also

WSAPROTOCOL_INFO

WSCEnumProtocols

WSCEnumProtocols32

Winsock Functions

Winsock Reference