ID: Q192121
The information in this article applies to:
- Windows NT, version 4.0
- Windows 95
- Windows 98
The Winsock 2 API WSAEnumProtocols returns a list of supported WSAPROTOCOL_INFO structures. Each structure in the list represents a Winsock 2 service provider that is installed on the system. You need to understand the contents of this structure so that you can choose the proper Winsock 2 service provider (that is, the one that provides the capabilities your application needs). This articles provides sample code you need to enumerate all Winsock 2 service providers and print out the contents of the returned WSAPROTOCOL_INFO structure.
The sample code below demonstrates how to enumerate all Winsock 2 service providers and print out the contents of the returned WSAPROTOCOL_INFO structure.
#include <winsock2.h>
#include <rpc.h>
#include <stdio.h>
static void PrintBufEntry(WSAPROTOCOL_INFO *pProtocolBuf);
int main(int argc, char *argv[])
{
WSADATA WSAData;
int i, nRet;
DWORD dwErr;
WSAPROTOCOL_INFO *lpProtocolBuf = NULL;
DWORD dwBufLen = 0;
if (WSAStartup(MAKEWORD(2,2), &WSAData))
printf("WSAStartup %d", WSAGetLastError());
else
{
// First, have WSAEnumProtocols tell you how big a buffer you
// need.
nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen);
if (SOCKET_ERROR != nRet)
printf("WSAEnumProtocols: should not have succeeded\n");
else if (WSAENOBUFS != (dwErr = WSAGetLastError()))
// WSAEnumProtocols failed for some reason not relating
// to buffer size - also odd.
printf("WSAEnumProtocols(1): %d\n", WSAGetLastError());
else
{
// WSAEnumProtocols failed for the "expected" reason.
// Now you need to allocate a buffer that is the right size.
lpProtocolBuf = (WSAPROTOCOL_INFO *)malloc(dwBufLen);
if (lpProtocolBuf)
{
// Now you can call WSAEnumProtocols again with the
// expectation that it will succeed
// because you have allocated a big enough buffer.
nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen);
if (SOCKET_ERROR == nRet)
printf("WSAEnumProtocols(3): %d\n",
WSAGetLastError());
else
{
// Enumerate the protocols.
for (i=0; i<nRet; i++)
PrintBufEntry(&lpProtocolBuf[i]);
}
free(lpProtocolBuf);
}
}
}
WSACleanup();
return(0);
}
// Print out the contents of a WSAPROTOCOL_INFO structure in
// a readable format.
//
static void PrintBufEntry(
WSAPROTOCOL_INFO *pProtocolBuf
)
{
unsigned char *pszUuid;
int j;
printf("\nProtocol <%s>\n", pProtocolBuf->szProtocol);
// A guid is the same as a uuid.
UuidToString(&pProtocolBuf->ProviderId, &pszUuid);
printf(" ProviderId {%s}\n", pszUuid);
RpcStringFree(&pszUuid);
if (!pProtocolBuf->dwServiceFlags1)
printf(" dwServiceFlags1: 0\n");
else
printf(" dwServiceFlags1: 0x%08X\n",
pProtocolBuf->dwServiceFlags1);
// Check which bit flags are set.
if (pProtocolBuf->dwServiceFlags1 & XP1_CONNECTIONLESS)
printf(" XP1_CONNECTIONLESS\n");
if (pProtocolBuf->dwServiceFlags1 & XP1_GUARANTEED_DELIVERY)
printf(" XP1_GUARANTEED_DELIVERY\n");
if (pProtocolBuf->dwServiceFlags1 & XP1_GUARANTEED_ORDER)
printf(" XP1_GUARANTEED_ORDER\n");
if (pProtocolBuf->dwServiceFlags1 & XP1_MESSAGE_ORIENTED)
printf(" XP1_MESSAGE_ORIENTED\n");
if (pProtocolBuf->dwServiceFlags1 & XP1_PSEUDO_STREAM)
printf(" XP1_PSEUDO_STREAM\n");
if (pProtocolBuf->dwServiceFlags1 & XP1_GRACEFUL_CLOSE)
printf(" XP1_GRACEFUL_CLOSE\n");
if (pProtocolBuf->dwServiceFlags1 & XP1_EXPEDITED_DATA)
printf(" XP1_EXPEDITED_DATA\n");
if (pProtocolBuf->dwServiceFlags1 & XP1_CONNECT_DATA)
printf(" XP1_CONNECT_DATA\n");
if (pProtocolBuf->dwServiceFlags1 & XP1_DISCONNECT_DATA)
printf(" XP1_DISCONNECT_DATA\n");
if (pProtocolBuf->dwServiceFlags1 & XP1_SUPPORT_BROADCAST)
printf(" XP1_SUPPORT_BROADCAST\n");
if (pProtocolBuf->dwServiceFlags1 & XP1_SUPPORT_MULTIPOINT)
printf(" XP1_SUPPORT_MULTIPOINT\n");
if (pProtocolBuf->dwServiceFlags1 & XP1_MULTIPOINT_CONTROL_PLANE)
printf(" XP1_MULTIPOINT_CONTROL_PLANE\n");
if (pProtocolBuf->dwServiceFlags1 & XP1_MULTIPOINT_DATA_PLANE)
printf(" XP1_MULTIPOINT_DATA_PLANE\n");
if (pProtocolBuf->dwServiceFlags1 & XP1_QOS_SUPPORTED)
printf(" XP1_QOS_SUPPORTED\n");
if (pProtocolBuf->dwServiceFlags1 & XP1_INTERRUPT)
printf(" XP1_INTERRUPT\n");
if (pProtocolBuf->dwServiceFlags1 & XP1_UNI_SEND)
printf(" XP1_UNI_SEND\n");
if (pProtocolBuf->dwServiceFlags1 & XP1_UNI_RECV)
printf(" XP1_UNI_RECV\n");
if (pProtocolBuf->dwServiceFlags1 & XP1_IFS_HANDLES)
printf(" XP1_IFS_HANDLES\n");
if (pProtocolBuf->dwServiceFlags1 & XP1_PARTIAL_MESSAGE)
printf(" XP1_PARTIAL_MESSAGE\n");
printf(" dwServiceFlags2: reserved\n");
printf(" dwServiceFlags3: reserved\n");
printf(" dwServiceFlags4: reserved\n");
printf(" dwProviderFlags:\n");
if (pProtocolBuf->dwProviderFlags & PFL_MULTIPLE_PROTO_ENTRIES)
printf(" PFL_MULTIPLE_PROTO_ENTRIES\n");
if (pProtocolBuf->dwProviderFlags & PFL_RECOMMENDED_PROTO_ENTRY)
printf(" PFL_RECOMMENDED_PROTO_ENTRY\n");
if (pProtocolBuf->dwProviderFlags & PFL_HIDDEN)
printf(" PFL_HIDDEN\n");
if (pProtocolBuf->dwProviderFlags & PFL_MATCHES_PROTOCOL_ZERO)
printf(" PFL_MATCHES_PROTOCOL_ZERO\n");
printf(" dwCatalogEntryId = %u\n", pProtocolBuf->dwCatalogEntryId);
printf(" ProtocolChain.ChainLen = %d ",
pProtocolBuf->ProtocolChain.ChainLen);
if (1 == pProtocolBuf->ProtocolChain.ChainLen)
printf(" ==> this is a base service provider\n");
else if (pProtocolBuf->ProtocolChain.ChainLen > 1)
{
printf(" ==>
ProtocolChain layered to base protocol\n");
for (j=0; j<pProtocolBuf->ProtocolChain.ChainLen; j++)
printf(" Chain Catalog Entry Id = %u\n",
pProtocolBuf->ProtocolChain.ChainEntries[j]);
}
else if (0 == pProtocolBuf->ProtocolChain.ChainLen)
printf(" ==> this is a layered service provider\n");
else
printf(" Invalid\n");
printf(" iVersion = %d\n", pProtocolBuf->iVersion);
printf(" iAddressFamily = %d\n", pProtocolBuf->iAddressFamily);
printf(" iMaxSockAddr = %d\n", pProtocolBuf->iMaxSockAddr);
printf(" iMinSockAddr = %d\n", pProtocolBuf->iMinSockAddr);
// iProtocols returns a negative number for Microsoft NetBIOS
// service providers corresponding to the lana number * -1 (for
// example, -2 implies lana 2), except for lana 0 which is equal to
// 0x80000000 because protocol 0 is reserved for special use.
printf(" iProtocol = %d\n", pProtocolBuf->iProtocol);
printf(" iProtocolMaxOffset = %d\n",
pProtocolBuf->iProtocolMaxOffset);
printf(" iNetworkByteOrder = %s\n",
((pProtocolBuf->iNetworkByteOrder == LITTLEENDIAN) ?
"LITTLEENDIAN" : "BIGENDIAN"));
printf(" iSecurityScheme = %d\n", pProtocolBuf->iSecurityScheme);
printf(" dwMessageSize = %u\n", pProtocolBuf->dwMessageSize);
printf(" dwProviderReserved = reserved\n");
return;
}
When you compile this code, link with the libraries Ws2_32.lib and Rpcrt4.lib.
This program runs on Windows 98, Windows NT 4.0, and Windows 95 systems that have the Winsock 2 for Windows 95 Update installed.
Additional query words:
Keywords : kbcode kbnetwork kbNTOS400 kbSDKPlatform kbWinOS95 kbWinOS98 kbWinsock kbCodeSam kbGrpNet
Issue type : kbhowto
Last Reviewed: September 11, 1998