www.pudn.com > ComputerInfo_demo.zip > SoketUtility.cpp


#include "stdafx.h" 
#include "socketutility.h" 
#include  
 
CSocketUtility::CSocketUtility(void) 
: m_nRefCount(0) 
{ 
} 
 
CSocketUtility::~CSocketUtility(void) 
{ 
} 
 
/****************************************************************************** 
 *	Function: 
 * 
 *	Parameters: 
 * 
 *	Returns: 
 * 
 *	Description: 
 * 
 *****************************************************************************/ 
bool CSocketUtility::Startup (void) 
{ 
	WORD wVersionRequested; 
	WSADATA wsaData; 
	int err; 
 
	wVersionRequested = MAKEWORD (2, 2); 
 
	err = WSAStartup (wVersionRequested, &wsaData); 
	if ( err != 0 ) 
	{ 
		/* Tell the user that we could not find a usable */ 
		/* WinSock DLL.                                  */ 
		return false; 
	} 
 
	/* Confirm that the WinSock DLL supports 2.2.*/ 
	/* Note that if the DLL supports versions greater    */ 
	/* than 2.2 in addition to 2.2, it will still return */ 
	/* 2.2 in wVersion since that is the version we      */ 
	/* requested.                                        */ 
 
	if (LOBYTE(wsaData.wVersion) != 2 || 
		HIBYTE(wsaData.wVersion) != 2 ) 
	{ 
		/* Tell the user that we could not find a usable */ 
		/* WinSock DLL.                                  */ 
		WSACleanup (); 
		return false;  
	} 
 
	char chDataBuf[WSADESCRIPTION_LEN+1]; 
 
	wsprintf (chDataBuf, _T ("%d.%d"), LOBYTE(wsaData.wVersion), HIBYTE(wsaData.wVersion)); 
	m_strWSVersion = chDataBuf; 
 
	wsprintf (chDataBuf, _T ("%d.%d"), LOBYTE(wsaData.wHighVersion), HIBYTE(wsaData.wHighVersion)); 
	m_strWSHiVersion = chDataBuf; 
 
	// Keep track of the number of initializations of Scket DLL. 
	m_nRefCount++; 
	return true; 
} 
 
/****************************************************************************** 
 *	Function: 
 * 
 *	Parameters: 
 * 
 *	Returns: 
 * 
 *	Description: 
 * 
 *****************************************************************************/ 
bool CSocketUtility::ShutDown (void) 
{ 
	int nErrCode = 0; 
	if (m_nRefCount > 0) 
	{ 
		if (WSACleanup () == 0) 
		{ 
			m_nRefCount--; 
		} 
		else 
		{ 
			nErrCode = WSAGetLastError (); 
		} 
	} 
	return (0 == nErrCode); 
} 
 
/****************************************************************************** 
 *	Function: 
 * 
 *	Parameters: 
 * 
 *	Returns: 
 * 
 *	Description: 
 * 
 *****************************************************************************/ 
bool CSocketUtility::GetIPAddress(const string& strHost, string& strAddress) 
{ 
	LPHOSTENT lpHost; 
	ULONG lAddr = INADDR_ANY; 
	string strHostCopy = strHost; 
 
	// If host name string is empty, we will use the standard host name 
	// for local machine. 
	if (strHost.length () == 0) 
	{ 
		DWORD dwLength = MAX_PATH; 
		TCHAR szName[MAX_PATH]; 
		::gethostname (szName, MAX_PATH); 
		strHostCopy = szName; 
	} 
 
	lpHost = ::gethostbyname (strHostCopy.c_str ()); 
	if (NULL != lpHost) 
	{ 
		struct sockaddr_in scAddr; 
		for(int i=0; lpHost->h_addr_list[i] != NULL ;i++) 
         { 
            memcpy(&(scAddr.sin_addr), lpHost->h_addr_list[i], 
                   lpHost->h_length); 
			strAddress = inet_ntoa(scAddr.sin_addr); 
         } 
	} 
	else 
	{ 
		strAddress = ""; 
		return false; 
	} 
	return true; 
} 
 
/****************************************************************************** 
 *	Function: 
 * 
 *	Parameters: 
 * 
 *	Returns: 
 * 
 *	Description: 
 * 
 *****************************************************************************/ 
bool CSocketUtility::GetWinSockVersion(string& strWSVersion, string& strWSHiVersion) 
{ 
	if (this->m_nRefCount <= 0) 
	{ 
		return false; 
	} 
 
	strWSVersion = m_strWSVersion; 
	strWSHiVersion = m_strWSHiVersion; 
	return bool(); 
} 
 
/****************************************************************************** 
 *	Function: 
 * 
 *	Parameters: 
 * 
 *	Returns: 
 * 
 *	Description: 
 * 
 *****************************************************************************/ 
bool CSocketUtility::GetIPInterfaces(void) 
{ 
	// Before we proceed, make sure that socket dll has been initialized. 
	if (this->m_nRefCount <= 0) 
	{ 
		return false; 
	} 
 
	int wsError = 0; 
	DWORD dwBytesReturned; 
	INTERFACE_INFO localAddr[10];  // Assume there will be no more than 10 IP interfaces 
	SOCKET s; 
 
	// Create UDP socket. 
	s = WSASocket (AF_INET, SOCK_DGRAM, IPPROTO_UDP, NULL, 0, 0); 
//	s = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP); 
	if (INVALID_SOCKET == s) 
	{ 
		return false; 
	} 
 
	// The WSAIoctl function is used to set or retrieve operating parameters 
	// associated with the socket, the transport protocol, or the communications 
	// subsystem. 
	// Enumerate all IP interfaces 
	wsError = WSAIoctl (s, 
						SIO_GET_INTERFACE_LIST, 
						NULL, 
						0, 
						&localAddr, 
						sizeof (localAddr), 
						&dwBytesReturned, 
						NULL, 
						NULL); 
	if (SOCKET_ERROR == wsError) 
	{ 
		closesocket (s); 
		return false; 
	} 
 
	// Make sure that socket has been closed. 
	closesocket(s); 
 
	char *pAddrString; 
	SOCKADDR_IN *pAddrInet; 
	ULONG SetFlags; 
	int numLocalAddr = dwBytesReturned/sizeof (dwBytesReturned); 
	for (int i = 0; i < numLocalAddr; i++) 
	{ 
		pAddrInet = (SOCKADDR_IN*)&localAddr[i].iiAddress; 
		pAddrString = inet_ntoa(pAddrInet->sin_addr); 
 
		pAddrInet = (SOCKADDR_IN*)&localAddr[i].iiNetmask; 
		pAddrString = inet_ntoa(pAddrInet->sin_addr); 
 
		pAddrInet = (SOCKADDR_IN*)&localAddr[i].iiBroadcastAddress; 
		pAddrString = inet_ntoa(pAddrInet->sin_addr); 
 
		SetFlags = localAddr[i].iiFlags; 
	} 
 
	return bool(); 
} 
 
/****************************************************************************** 
 *	Function: 
 * 
 *	Parameters: 
 * 
 *	Returns: 
 * 
 *	Description: 
 * 
 *****************************************************************************/ 
bool CSocketUtility::IsInitialized(void) 
{ 
	return (m_nRefCount > 0); 
} 
 
/****************************************************************************** 
 *	Function: 
 * 
 *	Parameters: 
 * 
 *	Returns: 
 * 
 *	Description: 
 * 
 *****************************************************************************/ 
bool CSocketUtility::EnumProtocols(long &lNumProtocols, PROTOCOL_ATTRIB **pAttributes) 
{ 
	// Make sure that Socket DLL has been initialized. 
	if (!this->IsInitialized ()) 
	{ 
		return false; 
	} 
 
	int nRet = 0; 
	DWORD dwBufLen = 0; 
	DWORD dwError = 0; 
	WSAPROTOCOL_INFO *lpProtocolBuf = NULL; 
	// First we will see how much data will be needed for information 
	// structure. 
	nRet = WSAEnumProtocols (NULL, lpProtocolBuf, &dwBufLen); 
	if (SOCKET_ERROR != nRet) 
	{ 
		// There should have been an error reported cause of insufficient 
		// buffer length provided. There is some other error in the 
		// call. So return wil error now. 
		return false; 
	} 
 
	// Get the error reported by call. 
	dwError = WSAGetLastError (); 
 
	// If insufficient buffer length, then assign the required buffer. 
	if (WSAENOBUFS == dwError) 
	{ 
		lpProtocolBuf = (WSAPROTOCOL_INFO *)(::malloc (dwBufLen)); 
		if (NULL == lpProtocolBuf) 
		{ 
			return false; 
		} 
 
		nRet = WSAEnumProtocols(NULL, lpProtocolBuf, &dwBufLen); 
		if (SOCKET_ERROR == nRet) 
		{ 
			::free(lpProtocolBuf); 
			return false; 
		} 
 
//		*pAttributes = new PROTOCOL_ATTRIB[nRet]; 
		*pAttributes = (PROTOCOL_ATTRIB*)::malloc (nRet * sizeof (PROTOCOL_ATTRIB)); 
		if (NULL == *pAttributes) 
		{ 
			::free(lpProtocolBuf); 
			return false; 
		} 
		// Loop thru each protocol. 
		for (int i = 0; i < nRet; i++) 
		{ 
			unsigned char *pszGUID = NULL; 
			(*pAttributes[i]).Name = lpProtocolBuf[i].szProtocol; 
			(*pAttributes[i]).Version = lpProtocolBuf[i].iVersion; 
			(*pAttributes[i]).CatalogEntryId = lpProtocolBuf[i].dwCatalogEntryId; 
			::UuidToString (&lpProtocolBuf[i].ProviderId, &pszGUID); 
			(*pAttributes[i]).ProviderID = (char *)pszGUID; 
			::RpcStringFree (&pszGUID); 
			(*pAttributes[i]).ByteOrder = lpProtocolBuf[i].iNetworkByteOrder; 
			(*pAttributes[i]).MinSockAddress = lpProtocolBuf[i].iMinSockAddr; 
			(*pAttributes[i]).MaxSockAddress = lpProtocolBuf[i].iMaxSockAddr; 
			(*pAttributes[i]).AddressFamily = lpProtocolBuf[i].iAddressFamily; 
			(*pAttributes[i]).SecurityScheme = lpProtocolBuf[i].iSecurityScheme; 
		} 
 
		lNumProtocols = nRet; 
	} 
	::free(lpProtocolBuf); 
	return true; 
}