#include <winsock2.h>
#include <stdio.h>

int main(int argc, char **argv)
{
	WSADATA WSAData;
	int i, nRet;
	WSAPROTOCOL_INFO *lpProtocolBuf = NULL;
	DWORD dwBufLen = 0;
	SOCKET SocDescriptor;
	DWORD dwErr;
	BOOL bProtocolFound;

	if (WSAStartup(MAKEWORD(2,2), &WSAData) != 0)
		printf("WSAStartup() failed with error code %ld\n", WSAGetLastError());
	else
	{
		printf("WSAStartup() seems OK!\n");

		// First, have WSAEnumProtocols() tell you how big a buffer you need
		nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen);
		
		printf("The buffer size is %d bytes...\n", dwBufLen);

		// If failed, returns SOCKET_ERROR
		if (nRet != SOCKET_ERROR)
			printf("WSAEnumProtocols() does not return SOCKET_ERROR!\n");
		// WSAENOBUFS - The buffer length was too small
		else if ((dwErr = WSAGetLastError()) != WSAENOBUFS)
			// WSAEnumProtocols() failed for some reason not relating to buffer size
			printf("WSAEnumProtocols() does not return WSAENOBUFS,\n"
			"    however failed with error code %ld\n", WSAGetLastError());
		else
		{
			// WSAEnumProtocols() failed for the "expected" reason. Therefore,
			// you need to allocate a buffer of the appropriate size.
			printf("Allocating the buffer of the appropriate size...\n");
			lpProtocolBuf = (WSAPROTOCOL_INFO *)malloc(dwBufLen);
			printf("Recheck, the buffer size is %d bytes...\n", 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 (nRet == SOCKET_ERROR)
					printf("WSAEnumProtocols() failed with error code %d\n", WSAGetLastError());
				else
				{
					printf("WSAEnumProtocols() looks pretty fine!\n");
					// Loop through protocols, looking for the first service
					// provider that meets the matching criteria.
					// Originally FALSE, if found change to TRUE

					printf("Matching the specified service provider...\n");
					printf("	IPPROTO_TCP and XP1_QOS_SUPPORTED...\n");
					bProtocolFound = FALSE;
					for (i=0; i<nRet; i++)
					{
						if ((lpProtocolBuf[i].iProtocol == IPPROTO_TCP) &&
							((XP1_QOS_SUPPORTED & lpProtocolBuf[i].dwServiceFlags1) == XP1_QOS_SUPPORTED))
						{
							bProtocolFound = TRUE;
							// first service provider matched, exit the loop
							break;
						}
					}
					printf("The specified service provider found/matched! buffer index, i is %d...\n", i);
					
					// Once you have chosen a service provider, the following sample code
					//demonstrates how to actually create a socket using a supplied WSAPROTOCOL_INFO structure
					//from the service provider you have chosen
					
					SocDescriptor = WSASocket(
						FROM_PROTOCOL_INFO, // manifest constant
						FROM_PROTOCOL_INFO, // manifest constant
						FROM_PROTOCOL_INFO, // manifest constant
						&lpProtocolBuf[i], // from WSAPROTOCOL_INFO
						0, // reserved
						WSA_FLAG_OVERLAPPED);
					
					printf("Reconfirm the buffer index, i is %d\n", i);
					if (SocDescriptor == INVALID_SOCKET)
					{
						printf("WSASocket() failed with error code %d\n", WSAGetLastError());
						WSACleanup();
					}
					else
						printf("WSASocket() looks fine, continue on next tasks!\n");
				}
			}
		}
	}
	// If not needed anymore, deallocate memory to the system's heap
	free(lpProtocolBuf);
	// WSA cleanup
	if(WSACleanup() != 0)
		printf("WSACleanup() failed!...\n");
	else
		printf("WSACleanup() is OK...\n");
	return 0;
}
