|
|
/**********************************************************************/ /** Microsoft Windows/NT **/ /** Copyright(c) Microsoft Corporation, 1999 - 1999 **/ /**********************************************************************/
/*
compinfo.cpp Computer info class plus helper functions
FILE HISTORY:
*/ #include <stdafx.h>
#include <winsock.h>
#include "compinfo.h"
#define STRING_MAX 256
//
//
//
BOOL CIpInfoArray::FIsInList(DWORD dwIp) { BOOL fFound = FALSE;
for (int i = 0; i < GetSize(); i++) { if (GetAt(i).dwIp == dwIp) { fFound = TRUE; break; } }
return fFound; }
//
//
//
CComputerInfo::CComputerInfo(LPCTSTR pszNameOrIp) { m_strNameOrIp = pszNameOrIp; m_nIndex = -1; }
CComputerInfo::~CComputerInfo() {
}
HRESULT CComputerInfo::GetIp(DWORD * pdwIp, int nIndex) { HRESULT hr = hrOK;
if (m_nIndex == -1) { hr = InitializeData(); }
if (SUCCEEDED(hr)) { if (pdwIp) *pdwIp = m_arrayIps[nIndex].dwIp; } else { if (pdwIp) *pdwIp = 0xFFFFFFFF; }
return hr; }
HRESULT CComputerInfo::GetIpStr(CString & strIp, int nIndex) { HRESULT hr = hrOK;
if (m_nIndex == -1) { hr = InitializeData(); }
if (SUCCEEDED(hr)) { struct in_addr ipaddr ;
//
// Convert the unsigned long to network byte order
//
ipaddr.s_addr = ::htonl( (u_long) m_arrayIps[nIndex].dwIp ) ; CHAR * pszAddr = inet_ntoa( ipaddr ) ;
::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pszAddr, -1, strIp.GetBuffer(IP_ADDDRESS_LENGTH_MAX), IP_ADDDRESS_LENGTH_MAX); strIp.ReleaseBuffer(); } else { strIp.Empty(); }
return hr; }
HRESULT CComputerInfo::GetHostName(CString & strHostName) { HRESULT hr = hrOK;
if (m_nIndex == -1) { hr = InitializeData(); }
if (SUCCEEDED(hr)) { strHostName = m_strHostname; } else { strHostName.Empty(); }
return hr; }
HRESULT CComputerInfo::GetFqdn(CString & strFqdn, int nIndex) { HRESULT hr = hrOK;
if (m_nIndex == -1) { hr = InitializeData(); }
if (SUCCEEDED(hr)) { strFqdn = m_arrayIps[nIndex].strFqdn; } else { strFqdn.Empty(); }
return hr; }
int CComputerInfo::GetCount() { return m_nIndex; }
//
// Call this function to reset the internal data so that on the next query
// we will rebuild our data.
//
void CComputerInfo::Reset() { // set this to -1 so that we will get the data again on the next call
m_nIndex = -1; m_arrayIps.RemoveAll(); m_strHostname.Empty(); }
HRESULT CComputerInfo::GetDomain(CString & strDomain) { // not supported right now
strDomain.Empty();
return E_NOTIMPL; }
HRESULT CComputerInfo::IsLocalMachine(BOOL * pfIsLocal) { HRESULT hr = hrOK;
if (m_nIndex == -1) { hr = InitializeData(); }
if (pfIsLocal) { if (SUCCEEDED(hr)) { CString strLocal; DWORD dwSize = STRING_MAX; BOOL fSuccess = GetComputerName(strLocal.GetBuffer(dwSize), &dwSize); strLocal.ReleaseBuffer();
if (fSuccess) { *pfIsLocal = (strLocal.CompareNoCase(m_strHostname) == 0) ? TRUE : FALSE; } } else { *pfIsLocal = FALSE; } }
return hr; }
COMPUTER_INFO_TYPE CComputerInfo::GetInputType() { // assume a NetBios name
COMPUTER_INFO_TYPE enResult = COMPUTER_INFO_TYPE_NB ; const TCHAR chDash = '-'; const TCHAR chDot = '.' ; const TCHAR chSlash = '\\' ; CString strName( m_strNameOrIp ) ;
int cch = strName.GetLength() ;
// Does the name begin with two slashes??
if ( cch > 2 && strName.GetAt(0) == chSlash && strName.GetAt(1) == chSlash ) { enResult = COMPUTER_INFO_TYPE_NB ; } else { //
// Scan the name looking for DNS name or IP address
//
int i = 0, cDots = 0, cAlpha = 0, cDash = 0; TCHAR ch ; BOOL bOk = TRUE ;
for ( ; i < cch ; i++ ) { switch ( ch = strName.GetAt( i ) ) { case chDot: if ( ++cDots > 3 ) { // we keep track of the number of dots,
// but we need to be able to handle fully
// qualified domain names (FQDN) so more than
// 3 dots is ok.
//bOk = FALSE ;
} break;
default: if ( _istalpha( ch ) ) { cAlpha++; } else if ( ch == chDash ) { cDash++; } else if ( !_istdigit(ch) ) { bOk = FALSE; }
break; } if ( ! bOk ) { break ; } } if ( bOk ) { if ( cAlpha ) { enResult = COMPUTER_INFO_TYPE_DNS ; } else if ( cDots == 3 ) { enResult = COMPUTER_INFO_TYPE_IP ; } } }
return enResult ; }
// internal functions
HRESULT CComputerInfo::InitializeData() { HRESULT hr = hrOK;
switch (GetInputType()) { case COMPUTER_INFO_TYPE_NB: case COMPUTER_INFO_TYPE_DNS: { DWORD dwIp;
GetHostAddress(m_strNameOrIp, &dwIp); GetHostInfo(dwIp); } break;
case COMPUTER_INFO_TYPE_IP: { // convert the string to ansi
CHAR szString [ STRING_MAX ] = {0}; ::WideCharToMultiByte(CP_ACP, 0, m_strNameOrIp, -1, szString, sizeof(szString), NULL, NULL);
// get the host info after converting the IP string to a DWORD
GetHostInfo(::ntohl( ::inet_addr( szString ) ) ); } break; }
return hr; }
HRESULT CComputerInfo::GetHostInfo ( DWORD dhipa ) { CString strFQDN; CString strHostname; CString strTemp; CIpInfo ipInfo;
//
// Call the Winsock API to get host name and alias information.
//
u_long ulAddrInNetOrder = ::htonl( (u_long) dhipa ) ;
HOSTENT * pHostEnt = ::gethostbyaddr( (CHAR *) & ulAddrInNetOrder, sizeof ulAddrInNetOrder, PF_INET ) ; if ( pHostEnt == NULL ) { return HRESULT_FROM_WIN32(::WSAGetLastError()); }
CHAR * * ppchAlias = pHostEnt->h_aliases ;
//
// Check and copy the host name.
//
::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pHostEnt->h_name, lstrlenA(pHostEnt->h_name), strTemp.GetBuffer(STRING_MAX * 2), STRING_MAX * 2);
strTemp.ReleaseBuffer();
// remove any periods at the end
while (strTemp[strTemp.GetLength() - 1] == '.') { strTemp = strTemp.Left(strTemp.GetLength() - 1); }
// gethostbyaddr is returning the hostname only in some cases.
// Make another call to get the fqdn
if (strTemp.Find('.') == -1) { // this is not a FQDN
GetHostAddressFQDN(strTemp, &strFQDN, &dhipa); } else { strFQDN = strTemp; }
// copy the data into the buffer
strFQDN.MakeLower(); int nDot = strFQDN.Find('.'); m_strHostname = strFQDN.Left(nDot); // add the primary entry to the array
ipInfo.dwIp = dhipa; ipInfo.strFqdn = strFQDN;
m_arrayIps.Add(ipInfo);
// now loop through the h_addr_list
int iCount = 0; while ( (LPDWORD)(pHostEnt->h_addr_list[iCount] ) ) { if (!m_arrayIps.FIsInList(addrFromHostent(pHostEnt, iCount))) { ipInfo.dwIp = addrFromHostent(pHostEnt, iCount); ipInfo.strFqdn.Empty();
m_arrayIps.Add(ipInfo); }
iCount++; }
m_nIndex = m_arrayIps.GetSize();
//
// Find the first acceptable NetBIOS name among the aliases;
// i.e., the first name without a period
//
/*
for ( ; *ppchAlias ; ppchAlias++ ) { if ( validateNetbiosName( *ppchAlias ) ) { break ; } }
//
// Empty the NetBIOS name in case we didn't get one.
//
pdhsrvi->_chNetbiosName[0] = 0 ; if ( *ppchAlias ) { //
// We found a usable name; copy it to output structure.
//
::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, *ppchAlias, lstrlenA(*ppchAlias), pdhsrvi->_chNetbiosName, sizeof(pdhsrvi->_chNetbiosName)); } */
return hrOK ; }
HRESULT CComputerInfo::GetHostAddressFQDN ( LPCTSTR pszHostName, CString * pstrFQDN, DWORD * pdhipa ) { HRESULT hr = hrOK; CHAR szString [ MAX_PATH ] = {0};
::WideCharToMultiByte(CP_ACP, 0, pszHostName, -1, szString, sizeof(szString), NULL, NULL);
HOSTENT * pHostent = ::gethostbyname( szString ) ;
if ( pHostent ) { *pdhipa = addrFromHostent( pHostent ) ;
LPTSTR pName = pstrFQDN->GetBuffer(STRING_MAX * 2); ZeroMemory(pName, STRING_MAX * 2);
::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pHostent->h_name, strlen(pHostent->h_name), pName, STRING_MAX * 2);
pstrFQDN->ReleaseBuffer();
} else { hr = HRESULT_FROM_WIN32(::WSAGetLastError()); }
return hr; }
DWORD CComputerInfo::addrFromHostent ( const HOSTENT * pHostent, INT index ) { return (DWORD) ::ntohl( *((u_long *) pHostent->h_addr_list[index]) ); }
HRESULT CComputerInfo::GetHostAddress ( LPCTSTR pszHostName, DWORD * pdhipa ) { HRESULT hr = hrOK; CHAR szString [ MAX_PATH ] = {0};
::WideCharToMultiByte(CP_ACP, 0, pszHostName, -1, szString, sizeof(szString), NULL, NULL);
HOSTENT * pHostent = ::gethostbyname( szString ) ;
if ( pHostent ) { *pdhipa = addrFromHostent( pHostent ) ; } else { hr = HRESULT_FROM_WIN32(::WSAGetLastError()); }
return hr ; }
HRESULT CComputerInfo::GetLocalHostAddress ( DWORD * pdhipa ) { HRESULT hr = hrOK; CHAR chHostName [ STRING_MAX * 2 ];
if ( ::gethostname( chHostName, sizeof(chHostName) ) == 0 ) { CString strTemp = chHostName; hr = GetHostAddress( strTemp, pdhipa ) ; } else { hr = HRESULT_FROM_WIN32(::WSAGetLastError()) ; }
return hr; }
HRESULT CComputerInfo::GetLocalHostName ( CString * pstrName ) { HRESULT hr = hrOK; CHAR chHostName [ STRING_MAX * 2 ] ;
if ( ::gethostname( chHostName, sizeof (chHostName) ) == 0 ) { LPTSTR pName = pstrName->GetBuffer(STRING_MAX * 2); ZeroMemory(pName, STRING_MAX * 2);
::MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, chHostName, strlen(chHostName), pName, STRING_MAX * 2);
pstrName->ReleaseBuffer(); } else { hr = HRESULT_FROM_WIN32(::WSAGetLastError()) ; }
return hr; }
|