Microsoft KB Archive/192121

{|
 * width="100%"|

HOWTO: Enumerate & Print Contents of WSAPROTOCOL_INFO Structure

 * }

Q192121

-

The information in this article applies to:


 * Microsoft Win32 Software Development Kit (SDK), used with:
 * Microsoft Windows 95
 * Microsoft Windows 98
 * the operating system: Microsoft Windows NT 4.0
 * the operating system: Microsoft Windows 2000

-

SUMMARY
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.

MORE INFORMATION
The sample code below demonstrates how to enumerate all Winsock 2 service providers and print out the contents of the returned WSAPROTOCOL_INFO structure.

Sample Code
  #include    #include    #include 

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\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; jProtocolChain.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 2000, Windows NT 4.0, Windows 98, and Windows 95 systems that have the Winsock 2 for Windows 95 Update installed.

Additional query words:

Keywords : _IK kbnetwork kbOSWinNT400 kbOSWin2000 kbSDKPlatform kbOSWin95 kbOSWin98 kbWinsock kbCodeSam kbGrpDSNet

Issue type : kbhowto

Technology : kbWin32SDKSearch kbAudDeveloper kbSDKSearch kbWin32sSearch