Windows2003-3790/net/mmc/dhcp/utils.cpp
2020-09-30 16:53:55 +02:00

1227 lines
30 KiB
C++

/**********************************************************************/
/** Microsoft Windows NT **/
/** Copyright(c) Microsoft Corporation, 1991 - 1999 **/
/**********************************************************************/
/*
utils.cpp
Utility routines for the DHCP admin snapin
FILE HISTORY:
DavidHov 6/15/93 Created
*/
#include "stdafx.h"
//#include "svcguid.h"
#define NUM_OPTION_TYPES 3
#define NUM_OPTION_POSS NUM_OPTION_TYPES * NUM_OPTION_TYPES
int g_OptionPriorityMap[NUM_OPTION_POSS][NUM_OPTION_TYPES] =
{
{ICON_IDX_CLIENT_OPTION_LEAF, ICON_IDX_CLIENT_OPTION_LEAF, 0},
{ICON_IDX_CLIENT_OPTION_LEAF, ICON_IDX_SCOPE_OPTION_LEAF, -1},
{ICON_IDX_CLIENT_OPTION_LEAF, ICON_IDX_SERVER_OPTION_LEAF, -1},
{ICON_IDX_SCOPE_OPTION_LEAF, ICON_IDX_CLIENT_OPTION_LEAF, 1},
{ICON_IDX_SCOPE_OPTION_LEAF, ICON_IDX_SCOPE_OPTION_LEAF, 0},
{ICON_IDX_SCOPE_OPTION_LEAF, ICON_IDX_SERVER_OPTION_LEAF, -1},
{ICON_IDX_SERVER_OPTION_LEAF, ICON_IDX_CLIENT_OPTION_LEAF, 1},
{ICON_IDX_SERVER_OPTION_LEAF, ICON_IDX_SCOPE_OPTION_LEAF, 1},
{ICON_IDX_SERVER_OPTION_LEAF, ICON_IDX_SERVER_OPTION_LEAF, 0}
};
int
UtilGetOptionPriority(int nOpt1, int nOpt2)
{
int nRet = 0;
for (int i = 0; i < NUM_OPTION_POSS; i++)
{
if ( (nOpt1 == g_OptionPriorityMap[i][0]) &&
(nOpt2 == g_OptionPriorityMap[i][1]) )
{
nRet = g_OptionPriorityMap[i][2];
break;
}
}
return nRet;
}
int ServerBrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
{
int i;
switch (uMsg)
{
case BFFM_INITIALIZED:
SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData);
break;
}
return 0;
}
/*---------------------------------------------------------------------------
UtilGetFolderName()
Gets the folder name for backup/restore.
Author: EricDav
---------------------------------------------------------------------------*/
BOOL
UtilGetFolderName(CString & strInitialPath, CString& strHelpText, CString& strSelectedPath)
{
BOOL fOk = FALSE;
TCHAR szBuffer[MAX_PATH];
TCHAR szExpandedPath[MAX_PATH * 2];
HRESULT hr;
CString strStartingPath = strInitialPath;
if (strStartingPath.IsEmpty())
{
strStartingPath = _T("%SystemDrive%\\");
}
ExpandEnvironmentStrings(strStartingPath, szExpandedPath, sizeof(szExpandedPath) / sizeof(TCHAR));
LPITEMIDLIST pidlPrograms = NULL;
hr = SHGetSpecialFolderLocation(NULL, CSIDL_DRIVES, &pidlPrograms);
if ( FAILED( hr ) )
{
return fOk;
}
BROWSEINFO browseInfo;
browseInfo.hwndOwner = ::FindMMCMainWindow();
browseInfo.pidlRoot = pidlPrograms;
browseInfo.pszDisplayName = szBuffer;
browseInfo.lpszTitle = strHelpText;
browseInfo.ulFlags = BIF_NEWDIALOGSTYLE | BIF_RETURNONLYFSDIRS ;
browseInfo.lpfn = ServerBrowseCallbackProc;
browseInfo.lParam = (LPARAM) szExpandedPath;
LPITEMIDLIST pidlBrowse = SHBrowseForFolder(&browseInfo);
fOk = SHGetPathFromIDList(pidlBrowse, szBuffer);
CString strPath(szBuffer);
strSelectedPath = strPath;
LPMALLOC pMalloc = NULL;
if (pidlPrograms && SUCCEEDED(SHGetMalloc(&pMalloc)))
{
if (pMalloc)
pMalloc->Free(pidlPrograms);
}
return fOk;
}
/*---------------------------------------------------------------------------
UtilConvertLeaseTime
Converts the lease time from a dword to its day, hour and minute
values
Author: EricDav
---------------------------------------------------------------------------*/
void
UtilConvertLeaseTime
(
DWORD dwLeaseTime,
int * pnDays,
int * pnHours,
int * pnMinutes
)
{
*pnDays = dwLeaseTime / (60 * 60 * 24);
dwLeaseTime = (dwLeaseTime % (60 * 60 * 24));
*pnHours = dwLeaseTime / (60 * 60);
dwLeaseTime = (dwLeaseTime % (60 * 60));
*pnMinutes = dwLeaseTime / 60;
}
/*---------------------------------------------------------------------------
UtilConvertLeaseTime
Converts the lease time from its day, hour and minute values to
a dword
Author: EricDav
---------------------------------------------------------------------------*/
DWORD
UtilConvertLeaseTime
(
int nDays,
int nHours,
int nMinutes
)
{
return (DWORD) (nDays * 60 * 60 * 24) +
(nHours * 60 * 60) +
(nMinutes * 60);
}
/*---------------------------------------------------------------------------
UtilCvtStringToIpAddr
Description
Author: EricDav
---------------------------------------------------------------------------*/
ENUM_HOST_NAME_TYPE
UtilCategorizeName
(
LPCTSTR pszName
)
{
// assume a NetBios name
ENUM_HOST_NAME_TYPE enResult = HNM_TYPE_NB ;
const TCHAR chDash = '-';
const TCHAR chDot = '.' ;
const TCHAR chSlash = '\\' ;
CString strName( pszName ) ;
int cch = strName.GetLength() ;
// Does the name begin with two slashes??
if ( cch > 2
&& strName.GetAt(0) == chSlash
&& strName.GetAt(1) == chSlash )
{
enResult = HNM_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 = HNM_TYPE_DNS ;
}
else if ( cDots == 3 )
{
enResult = HNM_TYPE_IP ;
}
}
}
return enResult ;
}
/*---------------------------------------------------------------------------
UtilCvtStringToIpAddr
Description
Author: EricDav
---------------------------------------------------------------------------*/
DHCP_IP_ADDRESS
UtilCvtStringToIpAddr
(
const CHAR * pszString
)
{
//
// Convert the string to network byte order, then to host byte order.
//
return (DHCP_IP_ADDRESS) ::ntohl( ::inet_addr( pszString ) ) ;
}
/*---------------------------------------------------------------------------
UtilCvtWstrToIpAddr
Description
Author: EricDav
---------------------------------------------------------------------------*/
DHCP_IP_ADDRESS
UtilCvtWstrToIpAddr
(
const LPCWSTR pcwString
)
{
CHAR szString [ MAX_PATH ] = {0};
::WideCharToMultiByte(CP_OEMCP, 0, pcwString, -1, szString, sizeof(szString), NULL, NULL);
//
// Convert the string to network byte order, then to host byte order.
//
return (DHCP_IP_ADDRESS) ::ntohl( ::inet_addr( szString ) );
}
/*---------------------------------------------------------------------------
UtilCvtIpAddrToString
Description
Author: EricDav
---------------------------------------------------------------------------*/
void
UtilCvtIpAddrToString
(
DHCP_IP_ADDRESS dhipa,
CHAR * pszString,
UINT cBuffSize
)
{
struct in_addr ipaddr ;
//
// Convert the unsigned long to network byte order
//
ipaddr.s_addr = ::htonl( (u_long) dhipa ) ;
//
// Convert the IP address value to a string
//
CHAR * pszAddr = inet_ntoa( ipaddr ) ;
// Copy the string to the caller's buffer.
ASSERT(cBuffSize > ::strlen(pszAddr));
ASSERT(pszString);
if (pszAddr)
{
::strcpy( pszString, pszAddr ) ;
}
}
/*---------------------------------------------------------------------------
UtilCvtIpAddrToWstr
Description
Author: EricDav
---------------------------------------------------------------------------*/
BOOL
UtilCvtIpAddrToWstr
(
DHCP_IP_ADDRESS dhipa,
CString * pstrIpAddress
)
{
CHAR szString [ MAX_PATH ] ;
LPCTSTR pbuf;
::UtilCvtIpAddrToString( dhipa, szString, MAX_PATH );
INT cch = ::strlen( szString ) ;
LPTSTR pBuf = pstrIpAddress->GetBuffer(IP_ADDDRESS_LENGTH_MAX);
ZeroMemory(pBuf, IP_ADDDRESS_LENGTH_MAX);
::MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, szString, -1, pBuf, IP_ADDDRESS_LENGTH_MAX);
pstrIpAddress->ReleaseBuffer();
return TRUE;
}
/*---------------------------------------------------------------------------
UtilCvtIpAddrToWstr
Description
Author: EricDav
---------------------------------------------------------------------------*/
BOOL
UtilCvtIpAddrToWstr
(
DHCP_IP_ADDRESS dhipa,
WCHAR * pwcszString,
INT cBuffCount
)
{
CHAR szString [ MAX_PATH ] ;
if ( cBuffCount > sizeof szString - 1 )
{
cBuffCount = sizeof szString - 1 ;
}
::UtilCvtIpAddrToString( dhipa, szString, cBuffCount );
#ifdef FE_SB
INT cch;
cch = ::MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, szString, -1, pwcszString, cBuffCount);
pwcszString[cch] = L'\0';
#else
INT cch = ::strlen( szString ) ;
//::mbstowcs( pwcszString, szString, cch ) ;
::MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, szString, cch, pwcszString, cBuffCount);
pwcszString[cch] = 0 ;
#endif
return TRUE ;
}
/*---------------------------------------------------------------------------
UtilDupIpAddrToWstr
Description
Author: EricDav
---------------------------------------------------------------------------*/
WCHAR *
UtilDupIpAddrToWstr
(
DHCP_IP_ADDRESS dhipa
)
{
WCHAR wcszString [ MAX_PATH ] ;
if ( ! ::UtilCvtIpAddrToWstr( dhipa, wcszString, ( sizeof ( wcszString ) / sizeof( WCHAR ) ) ) )
{
return NULL ;
}
return ::UtilWcstrDup( wcszString ) ;
}
/*---------------------------------------------------------------------------
validateNetbiosName
Simplistic routine to check to see if the given name is viable
as a NetBIOS name.
Author: EricDav
---------------------------------------------------------------------------*/
static BOOL
validateNetbiosName
(
const CHAR * pchName
)
{
INT nChars = ::strlen( pchName ) ;
if ( nChars > MAX_COMPUTERNAME_LENGTH || nChars == 0 )
{
return FALSE ;
}
for ( ; *pchName ; pchName++ )
{
if ( *pchName == '.' )
{
break ;
}
}
return *pchName == 0 ;
}
/*---------------------------------------------------------------------------
UtilGetHostInfo
Description
Author: EricDav
---------------------------------------------------------------------------*/
DWORD
UtilGetHostInfo
(
DHCP_IP_ADDRESS dhipa,
DHC_HOST_INFO_STRUCT * pdhsrvi
)
{
ZeroMemory(pdhsrvi, sizeof(DHC_HOST_INFO_STRUCT));
pdhsrvi->_dhipa = dhipa ;
//
// Call the Winsock API to get host name and alias information.
//
u_long ulAddrInNetOrder = ::htonl( (u_long) dhipa ) ;
HOSTENT * pHostInfo = ::gethostbyaddr( (CHAR *) & ulAddrInNetOrder,
sizeof ulAddrInNetOrder,
PF_INET ) ;
if ( pHostInfo == NULL )
{
return ::WSAGetLastError();
}
CHAR * * ppchAlias = pHostInfo->h_aliases ;
//
// Check and copy the host name.
//
if ( sizeof (pdhsrvi->_chNetbiosName) <= ::strlen( pHostInfo->h_name ) )
{
return ERROR_INVALID_NAME ;
}
ZeroMemory(pdhsrvi->_chNetbiosName, sizeof(pdhsrvi->_chNetbiosName));
::MultiByteToWideChar(CP_ACP,
MB_PRECOMPOSED,
pHostInfo->h_name,
lstrlenA(pHostInfo->h_name),
pdhsrvi->_chNetbiosName,
sizeof(pdhsrvi->_chNetbiosName) / sizeof( pdhsrvi->_chNetbiosName[ 0 ]));
// remove any periods at the end
while (pdhsrvi->_chHostName[lstrlen(pdhsrvi->_chNetbiosName) - 1] == '.')
{
pdhsrvi->_chHostName[lstrlen(pdhsrvi->_chNetbiosName) - 1] = 0;
}
// gethostbyaddr is returning the hostname only in some cases.
// Make another call to get the fqdn
CString strTemp = pdhsrvi->_chNetbiosName;
if (strTemp.Find('.') == -1)
{
// this is not a FQDN
strTemp.Empty();
UtilGetHostAddressFQDN(pdhsrvi->_chNetbiosName, &strTemp, &dhipa);
}
// copy the data into the buffer
strTemp.MakeLower();
memset(pdhsrvi->_chHostName, 0, sizeof(pdhsrvi->_chHostName));
lstrcpy(pdhsrvi->_chHostName, strTemp);
//
// 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 NOERROR ;
}
/*---------------------------------------------------------------------------
addrFromHostent
Description
Author: EricDav
---------------------------------------------------------------------------*/
static DHCP_IP_ADDRESS
addrFromHostent
(
const HOSTENT * pHostent,
INT index = 0
)
{
return (DHCP_IP_ADDRESS) ::ntohl( *((u_long *) pHostent->h_addr_list[index]) ) ;
}
/*---------------------------------------------------------------------------
UtilGetHostAddress
Description
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
UtilGetHostAddressFQDN
(
LPCTSTR pszHostName,
CString * pstrFQDN,
DHCP_IP_ADDRESS * pdhipa
)
{
HRESULT hr = NOERROR;
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(DHCPSNAP_STRING_MAX * sizeof( WCHAR ));
ZeroMemory(pName, DHCPSNAP_STRING_MAX * sizeof( WCHAR ));
::MultiByteToWideChar(CP_ACP,
MB_PRECOMPOSED,
pHostent->h_name,
strlen(pHostent->h_name),
pName,
DHCPSNAP_STRING_MAX );
pstrFQDN->ReleaseBuffer();
}
else
{
hr = ::WSAGetLastError() ;
}
return hr;
}
/*---------------------------------------------------------------------------
UtilGetHostAddress
Description
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
UtilGetHostAddress
(
LPCTSTR pszHostName,
DHCP_IP_ADDRESS * pdhipa
)
{
HRESULT hr = NOERROR;
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 = ::WSAGetLastError() ;
}
return hr ;
}
/*---------------------------------------------------------------------------
UtilGetLocalHostAddress
Description
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
UtilGetLocalHostAddress
(
DHCP_IP_ADDRESS * pdhipa
)
{
CHAR chHostName [ DHCPSNAP_STRING_MAX ] ;
HRESULT hr = NOERROR;
if ( ::gethostname( chHostName, sizeof chHostName ) == 0 )
{
CString strTemp = chHostName;
hr = ::UtilGetHostAddress( strTemp, pdhipa ) ;
}
else
{
//err = ::WSAGetLastError() ;
hr = E_FAIL;
}
return hr;
}
/*---------------------------------------------------------------------------
UtilGetLocalHostName
Description
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
UtilGetLocalHostName
(
CString * pstrName
)
{
CHAR chHostName [ DHCPSNAP_STRING_MAX * 2 ] ;
HRESULT hr = NOERROR;
if ( ::gethostname( chHostName, sizeof (chHostName) ) == 0 )
{
LPTSTR pName = pstrName->GetBuffer(DHCPSNAP_STRING_MAX * sizeof( WCHAR ));
ZeroMemory(pName, DHCPSNAP_STRING_MAX * sizeof( WCHAR ));
::MultiByteToWideChar(CP_ACP,
MB_PRECOMPOSED,
chHostName,
strlen(chHostName),
pName,
DHCPSNAP_STRING_MAX );
pstrName->ReleaseBuffer();
}
else
{
//err = ::WSAGetLastError() ;
hr = E_FAIL;
}
return hr;
}
/*---------------------------------------------------------------------------
UtilGetNetbiosAddress
Description
Author: EricDav
---------------------------------------------------------------------------*/
HRESULT
UtilGetNetbiosAddress
(
LPCTSTR pszNetbiosName,
DHCP_IP_ADDRESS * pdhipa
)
{
//
// This code presupposes that the "hosts" file maps NetBIOS names
// and DNS names identically. THIS IS NOT A VALID SUPPOSITION, but is
// expedient for the on-campus work.
//
return UtilGetHostAddress( pszNetbiosName, pdhipa ) ;
}
/*---------------------------------------------------------------------------
UtilWcstrDup
"strdup" a WC string
Author: EricDav
---------------------------------------------------------------------------*/
WCHAR *
UtilWcstrDup
(
const WCHAR * pwcsz,
INT * pccwLength
)
{
WCHAR szwchEmpty [2] = { 0 } ;
if ( pwcsz == NULL )
{
pwcsz = szwchEmpty ;
}
INT ccw = ::wcslen( pwcsz );
WCHAR * pwcszNew = new WCHAR [ ccw + 1 ] ;
if ( pwcszNew == NULL )
{
return NULL ;
}
::wcscpy( pwcszNew, pwcsz ) ;
if ( pccwLength )
{
*pccwLength = ccw ;
}
return pwcszNew ;
}
/*---------------------------------------------------------------------------
UtilWcstrDup
Description
Author: EricDav
---------------------------------------------------------------------------*/
WCHAR *
UtilWcstrDup
(
const CHAR * psz,
INT * pccwLength
)
{
INT ccw = ::strlen( psz ) ;
WCHAR * pwcszNew = new WCHAR [ ccw + 1 ] ;
if ( pwcszNew == NULL )
{
return NULL ;
}
//::mbstowcs( pwcszNew, psz, ccw ) ;
#ifdef FE_SB
ccw = ::MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, psz, -1, pwcszNew, ccw+1);
if ( pccwLength )
{
*pccwLength = ccw ;
}
pwcszNew[ccw] = L'\0';
#else
::MultiByteToWideChar(CP_OEMCP, MB_PRECOMPOSED, psz, ccw, pwcszNew, ccw+1);
if ( pccwLength )
{
*pccwLength = ccw ;
}
pwcszNew[ccw] = 0 ;
#endif
return pwcszNew ;
}
/*---------------------------------------------------------------------------
UtilCstrDup
Description
Author: EricDav
---------------------------------------------------------------------------*/
CHAR *
UtilCstrDup
(
const WCHAR * pwcsz
)
{
INT ccw = ::wcslen( pwcsz ),
cch = (ccw + 1) * 2 ;
CHAR * psz = new CHAR [ cch ] ;
if ( psz == NULL )
{
return NULL ;
}
//::wcstombs( psz, pwcsz, cch ) ;
::WideCharToMultiByte( CP_OEMCP, WC_COMPOSITECHECK, pwcsz, -1, psz, cch, NULL, NULL ) ;
return psz ;
}
/*---------------------------------------------------------------------------
UtilCstrDup
Description
Author: EricDav
---------------------------------------------------------------------------*/
CHAR *
UtilCstrDup
(
const CHAR * psz
)
{
CHAR * pszNew = new CHAR [ ::strlen( psz ) + 1 ] ;
if ( pszNew == NULL )
{
return NULL ;
}
::strcpy( pszNew, psz ) ;
return pszNew ;
}
/*---------------------------------------------------------------------------
cvtWcStrToStr
Description
Author: EricDav
---------------------------------------------------------------------------*/
static HRESULT
cvtWcStrToStr
(
char * psz,
size_t cch,
const WCHAR * pwcsz,
size_t cwch
)
{
#ifdef FE_SB
int cchResult = ::WideCharToMultiByte( CP_ACP, 0,
pwcsz, -1,
psz, cch,
NULL, NULL ) ;
#else
int cchResult = ::WideCharToMultiByte( CP_ACP, 0,
pwcsz, cwch,
psz, cwch,
NULL, NULL ) ;
#endif
psz[ cchResult ] = 0 ;
//return cchResult ? 0 : ::GetLastError();
return cchResult ? NOERROR : E_FAIL;
}
wchar_t rgchHex[] = L"00112233445566778899aAbBcCdDeEfF";
/*---------------------------------------------------------------------------
UtilCvtHexString
Convert a string of hex digits to a byte array
Author: EricDav
---------------------------------------------------------------------------*/
BOOL
UtilCvtHexString
(
LPCTSTR pszNum,
CByteArray & cByte
)
{
int i = 0,
iDig,
iByte,
cDig ;
int iBase = 16 ;
BOOL bByteBoundary ;
//
// Skip leading blanks
//
for ( ; *pszNum == L' ' ; pszNum++ ) ;
//
// Skip a leading zero
//
if ( *pszNum == L'0' )
{
pszNum++ ;
}
//
// Look for hexadecimal marker
//
if ( *pszNum == L'x' || *pszNum == L'X' )
{
pszNum++ ;
}
bByteBoundary = ::wcslen( pszNum ) % 2 ;
for ( iByte = cDig = 0 ; *pszNum ; )
{
wchar_t * pszDig = ::wcschr( rgchHex, *pszNum++ ) ;
if ( pszDig == NULL )
{
break;
// return FALSE;
}
iDig = ((int) (pszDig - rgchHex)) / 2 ;
if ( iDig >= iBase )
{
break ;
// return FALSE;
}
iByte = (iByte * 16) + iDig ;
if ( bByteBoundary )
{
cByte.SetAtGrow( cDig++, (UCHAR) iByte ) ;
iByte = 0 ;
}
bByteBoundary = ! bByteBoundary ;
}
cByte.SetSize( cDig ) ;
//
// Return TRUE if we reached the end of the string.
//
return *pszNum == 0 ;
}
/*---------------------------------------------------------------------------
UtilCvtByteArrayToString
Description
Author: EricDav
---------------------------------------------------------------------------*/
BOOL
UtilCvtByteArrayToString
(
const CByteArray & abAddr,
CString & str
)
{
int i ;
DWORD err = 0 ;
// TRY
{
str.Empty() ;
//
// The hex conversion string has two characters per nibble,
// to allow for upper case.
//
for ( i = 0 ; i < abAddr.GetSize() ; i++ )
{
int i1 = ((abAddr.GetAt(i) & 0xF0) >> 4) * 2 ,
i2 = (abAddr.GetAt(i) & 0x0F) * 2 ;
str += rgchHex[ i1 ] ;
str += rgchHex[ i2 ] ;
}
}
// CATCH(CMemoryException, pMemException)
// if ( pMemException )
// {
// str.Empty() ;
// err = 1;
// }
return err == 0 ;
}
/*---------------------------------------------------------------------------
PchParseUnicodeString
Parse a unicode string by copying its content
into a CString object.
The parsing ends when the null-terminator ('\0')is
reached or the comma (',') is reached.
Return pointer to the character where parsing
ended('\0') or (',')
Author: EricDav
---------------------------------------------------------------------------*/
WCHAR *
PchParseUnicodeString
(
CONST WCHAR * szwString, // IN: String to parse
DWORD dwLength,
CString& rString // OUT: Content of the substring
)
{
ASSERT(szwString != NULL);
ASSERT(BOOT_FILE_STRING_DELIMITER_W == L','); // Just in case
WCHAR szwBufferT[1024]; // Temporary buffer
WCHAR * pchwDst = szwBufferT;
while (*szwString != L'\0')
{
if (*szwString == BOOT_FILE_STRING_DELIMITER_W)
break;
*pchwDst++ = *szwString++;
if ((DWORD) (pchwDst - szwBufferT) > dwLength)
{
// we've gone past the end of our buffer!! ouch
Panic0("PchParseUnicodeString: Gone past end of buffer");
break;
}
ASSERT((pchwDst - szwBufferT < sizeof(szwBufferT)) && "Buffer overflow");
} // while
*pchwDst = L'\0';
rString = szwBufferT; // Copy the string into the CString object
return const_cast<WCHAR *>(szwString);
} // PchParseUnicodeString()
/////////////////////////////////////////////////////////////////////////////
// FGetCtrlDWordValue()
//
// Return a 32-bit unsigned integer from an edit control
//
// This function is like GetDlgItemInt() except it accepts hexadecimal values,
// has range checking and/or overflow checking.
// If value is out of range, function will display a friendly message and will
// set the focus to control.
// Range: dwMin to dwMax inclusive
// - If both dwMin and dwMax are zero, no range checking is performed
// - Return TRUE if successful, otherwise FALSE
// - On error, pdwValue remains unchanged.
//
BOOL FGetCtrlDWordValue(HWND hwndEdit, DWORD * pdwValue, DWORD dwMin, DWORD dwMax)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
TCHAR szT[256];
DWORD Len, dwResult;
BOOL Success;
ASSERT(IsWindow(hwndEdit));
ASSERT(pdwValue);
ASSERT(dwMin <= dwMax);
::GetWindowText(hwndEdit, szT, (sizeof(szT)-1)/sizeof(TCHAR));
szT[ 255 ] = _T('\0');
Success = FCvtAsciiToInteger( szT, OUT &dwResult );
*pdwValue = dwResult;
if (( !Success ) || (dwResult < dwMin) || (dwResult > dwMax)) {
CString strBuffer;
strBuffer.LoadString( IDS_ERR_INVALID_INTEGER );
::wsprintf( szT, strBuffer, dwMin, dwMax, dwMin, dwMax );
ASSERT( wcslen( szT ) < sizeof( szT ));
::SetFocus( hwndEdit );
::AfxMessageBox( szT );
::SetFocus( hwndEdit );
return FALSE;
} // if
return TRUE;
} // FGetCtrlDWordValue
/////////////////////////////////////////////////////////////////////////////
//
// Convert a string to a binary integer
// - String is allowed to be decimal or hexadecimal
// - Minus sign is not allowed
// If successful, set *pdwValue to the integer and return TRUE.
// If not successful (overflow or illegal integer) return FALSE.
//
BOOL
FCvtAsciiToInteger(
IN const TCHAR * pszNum,
OUT DWORD * pdwValue
)
{
DWORD dwResult = 0;
DWORD Res = 0;
BOOL IsHex = FALSE;
LPWSTR Format;
const TCHAR *pBuf;
ASSERT(pszNum != NULL);
ASSERT(pdwValue != NULL);
pBuf = pszNum;
// Skip leading blanks and/or zeroes
while (( *pszNum == _T(' ')) ||
( *pszNum == _T('\t')) ||
( *pszNum == _T('0'))) {
pszNum++;
}
// If there is just '0' in the buffer, make sure we don't ignore it
// Check if we are using hexadecimal base
if (( *pszNum == _T('x')) || ( *pszNum == _T('X'))) {
IsHex = TRUE;
pszNum++;
}
else if (( pszNum != pBuf ) &&
( *(pszNum - 1) == _T('0'))) {
// back track the 0 we skipped
pszNum--;
}
// -ve numbers are not valid
if ( *pszNum == L'-' ) {
*pdwValue = 0;
return FALSE;
}
// if we are the end of the string, then return success
if ( *pszNum == L'\0' ) {
*pdwValue = 0;
return TRUE;
}
Format = ( IsHex ) ? L"%lx" : L"%lu";
Res = swscanf( pszNum, Format, &dwResult );
if ( Res == 0 ) {
*pdwValue = 0;
return FALSE;
}
ASSERT( Res == 1 );
*pdwValue = dwResult;
return TRUE;
} // FCvtAsciiToInteger
void UtilConvertStringToDwordDword(LPCTSTR pszString, DWORD_DWORD * pdwdw)
{
ULARGE_INTEGER value;
BOOL hex = FALSE;
value.QuadPart = 0;
// skip white spaces
while (( *pszString == L' ' ) ||
( *pszString == L'\t' )) {
pszString++;
}
hex = (( pszString[ 0 ] == L'0' ) &&
( pszString[ 1 ] == L'x' ))
? TRUE : FALSE;
if ( hex ) {
if ( 1 != _stscanf( pszString + 2, _T( "%I64x" ), &value.QuadPart )) {
value.QuadPart = 0;
}
}
else { // decimal
if ( 1 != _stscanf( pszString, _T( "%I64u" ), &value.QuadPart )) {
value.QuadPart = 0;
}
}
// Use 0 for all -ve numbers
if ( *pszString == L'-' ) {
value.QuadPart = 0;
}
pdwdw->DWord1 = value.HighPart;
pdwdw->DWord2 = value.LowPart;
} // UtilConvertStringToDwordDword()
void UtilConvertDwordDwordToString(DWORD_DWORD * pdwdw, CString * pstrString, BOOL bDecimal)
{
TCHAR szNum [ STRING_LENGTH_MAX ] ;
ULARGE_INTEGER Temp;
Temp.HighPart = pdwdw->DWord1;
Temp.LowPart = pdwdw->DWord2;
if (bDecimal)
{
::wsprintf( szNum, L"%I64u", Temp.QuadPart );
}
else
{
::wsprintf( szNum, L"0x%I64x", Temp.QuadPart );
}
*pstrString = szNum ;
}
// End of DHCPUTIL.CPP