2025-04-27 07:49:33 -04:00

1498 lines
32 KiB
C++

// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
#include "precomp.h"
#include "utils.h"
#include "resource.h"
#include "gctype.h"
#include "wbemidl.h"
#include "gc.h"
#include "hmmverr.h"
//********************************************************
// StripWhiteSpace
//
// Strip all leading and trailing white space out of a string value.
//
// Parameters:
// [out] CString& sValue
// The value is returned here.
//
// [in] LPCTSTR pszValue
// The string to strip the whitespace from.
//
// Returns:
// Nothing.
//
//********************************************************
void StripWhiteSpace(CString& sValue, LPCTSTR pszValue)
{
sValue = _T("");
// Skip leading spaces
while (*pszValue) {
if (isspace(*pszValue)) {
++pszValue;
}
else {
break;
}
}
// Search for the end of the string.
LPCTSTR pszEnd = pszValue;
while (*pszEnd) {
++pszEnd;
}
// Seach backwards for the first non-space character
--pszEnd;
while(pszEnd > pszValue) {
if (isspace(*pszEnd)) {
--pszEnd;
}
else {
break;
}
}
// Copy everything from the first non-space to the last non-space characters.
while (pszValue <= pszEnd) {
sValue += *pszValue++;
}
}
// One day we will add cell value validation here.
LPCTSTR EatWhite(LPCTSTR psz)
{
TCHAR ch;
ch = *psz;
while (isspace(ch)) {
ch = *++psz;
}
return psz;
}
__int64 atoi64(LPCTSTR pszValue)
{
#ifdef _UNICODE
char szValue[256];
wcstombs(szValue, pszValue, sizeof(szValue));
return _atoi64(szValue);
#else
return _atoi64(pszValue);
#endif
}
//*************************************************************
// AToUint32
//
// Convert an ASCII string to a uint32 value while doing overflow
// detection.
//
// Parameters:
// [in/out] LPCTSTR& pszValue
// Pointer to the numeric string to be converted. On return
// it will point just past the last digit eaten by this method.
//
// [out] ULONG& uiValue
// The converted value is returned here.
//
// Returns:
// SCODE
// S_OK if a value is returned without error. E_FAIL if no digits
// were converted or there was an overflow error.
//
//*****************************************************************
SCODE AToUint32(LPCTSTR& pszValue, ULONG& uiValue)
{
uiValue = 0;
int nDigits = 0;
int iDigit;
ULONG uiValueInitial;
while (iDigit = *pszValue) {
if (!::isdigit(iDigit)) {
break;
}
iDigit -= '0';
// Factor in the next digit after saving the initial value.
uiValueInitial = uiValue;
uiValue = uiValue * 10 + iDigit;
// Check for overflow by doing the inverse of what we did to factor in
// the next digit to see if we can get back to what we started with.
int iInverseDigit = uiValue % 10;
ULONG uiInverseValue = (uiValue - iInverseDigit) / 10;
if ((iInverseDigit != iDigit) || (uiInverseValue != uiValueInitial)) {
// An overflow occurred, so report the failure.
uiValue = uiValueInitial;
return E_FAIL;
}
++nDigits;
++pszValue;
}
if (nDigits == 0) {
return E_FAIL;
}
return S_OK;
}
//*************************************************************
// AToUint64
//
// Convert an ASCII string to a uint32 value while doing overflow
// detection.
//
// Parameters:
// [in/out] LPCTSTR& pszValue
// Pointer to the numeric string to be converted. On return
// it will point just past the last digit eaten by this method.
//
// [out] unsigned __int64& uiValue
// The converted value is returned here.
//
// Returns:
// SCODE
// S_OK if a value is returned without error. E_FAIL if no digits
// were converted or there was an overflow error.
//
//*****************************************************************
SCODE AToUint64(LPCTSTR& pszValue, unsigned __int64& uiValue)
{
uiValue = 0;
int nDigits = 0;
int iDigit;
unsigned __int64 uiValueInitial;
while (iDigit = *pszValue) {
if (!::isdigit(iDigit)) {
break;
}
iDigit -= '0';
// Factor in the next digit after saving the initial value.
uiValueInitial = uiValue;
uiValue = uiValue * 10 + iDigit;
// Check for overflow by doing the inverse of what we did to factor in
// the next digit to see if we can get back to what we started with.
int iInverseDigit = (int) (uiValue % 10);
unsigned __int64 uiInverseValue = (uiValue - iInverseDigit) / 10;
if ((iInverseDigit != iDigit) || (uiInverseValue != uiValueInitial)) {
// An overflow occurred, so report the failure.
uiValue = uiValueInitial;
return E_FAIL;
}
++nDigits;
++pszValue;
}
if (nDigits == 0) {
return E_FAIL;
}
return S_OK;
}
//*************************************************************
// AToSint64
//
// Convert an ASCII string to a sint64 value while doing overflow
// detection.
//
// Parameters:
// [in/out] LPCTSTR& pszValue
// Pointer to the numeric string to be converted. On return
// it will point just past the last digit eaten by this method.
//
// [out] __int64& uiValue
// The converted value is returned here.
//
// Returns:
// SCODE
// S_OK if a value is returned without error. E_FAIL if no digits
// were converted or there was an overflow error.
//
//*****************************************************************
SCODE AToSint64(LPCTSTR& pszValue, __int64& iValue)
{
pszValue = EatWhite(pszValue);
// Handle the sign.
BOOL bIsNegative = FALSE;
if (*pszValue == _T('+')) {
++pszValue;
}
else if (*pszValue == _T('-')) {
bIsNegative = TRUE;
++pszValue;
}
iValue = 0;
int nDigits = 0;
int iDigit;
__int64 iValueInitial;
while (iDigit = *pszValue) {
if (!::isdigit(iDigit)) {
break;
}
iDigit -= '0';
// Factor in the next digit after saving the initial value.
iValueInitial = iValue;
iValue = iValue * 10 + iDigit;
// Check for overflow by doing the inverse of what we did to factor in
// the next digit to see if we can get back to what we started with.
int iInverseDigit = (int) (iValue % 10);
__int64 iInverseValue = (iValue - iInverseDigit) / 10;
if ((iInverseDigit != iDigit) || (iInverseValue != iValueInitial)) {
// An overflow occurred, so report the failure.
iValue = iValueInitial;
return E_FAIL;
}
++nDigits;
++pszValue;
}
if (nDigits == 0) {
return E_FAIL;
}
if (bIsNegative) {
iValue = -iValue;
}
return S_OK;
}
//*****************************************************************
// CXStringArray::Load
//
// Given an array of resource ids, load the corresponding strings
// into this CStringArray.
//
// Parameters:
// UINT* puiResID
// Pointer to the array of string resource ids
//
// int nStrings
// The number of entries in the resource id array.
//
// Returns:
// Nothing.
//
//****************************************************************
void CXStringArray::Load(UINT* puiResID, int nStrings)
{
// If this string array was already loaded, do nothing.
if (GetSize() > 0) {
return;
}
CString sValue;
while (--nStrings >= 0) {
sValue.LoadString(*puiResID++);
Add(sValue);
}
}
//********************************************************************
// ToBSTR
//
// Convert a COleVariant to a BSTR
//
// Parameters:
// COleVariant& var
// The variant to convert.
//
// Returns:
// BSTR
// The place where the converted value is returned.
//
// Note that the BSTR returned is owned by the COleVariant.
//*******************************************************************
BSTR ToBSTR(COleVariant& var)
{
switch(var.vt) {
case VT_BSTR:
break;
case VT_NULL:
var = L"";
break;
default:
try
{
var.ChangeType(VT_BSTR);
}
catch(CException* )
{
var = L"";
}
break;
}
return var.bstrVal;
}
//***********************************************************************
// GenerateWindowID
//
// A series of unique window IDs are generated by sucessive calls to this
// method.
//
// Parameters:
// None.
//
// Returns:
// A unique window ID used when creating a new window.
//
//**********************************************************************
UINT GenerateWindowID()
{
static UINT nID = 4000;
return nID++;
}
//*************************************************************
// MakeSafeArray
//
// Make a safe array of the specified size and element type.
//
// Parameters:
// SAFEARRAY FAR ** ppsaCreated
// A pointer to the place to return the safe array.
//
// VARTYPE vt
// The type of the elements.
//
// int nElements
// The number of elements.
//
// Returns:
// SCODE
// S_OK if successful, otherwise a failure code.
//
//*************************************************************
SCODE MakeSafeArray(SAFEARRAY FAR ** ppsaCreated, VARTYPE vt, int nElements)
{
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = nElements;
*ppsaCreated = SafeArrayCreate(vt,1, rgsabound);
return (*ppsaCreated == NULL) ? 0x80000001 : S_OK;
}
//******************************************************************
// GetViewerFont
//
// Get the "global" font used by the HMOM object viewer. This method
// will probably be replaced when I can figure out a way to get the
// ambient font.
//
// Parameters:
// CFont& font
// A reference to the font to return.
//
// LONG lfHeight
// The desired font height.
//
// LONG lfWeight
// The weight of the font (FW_BOLD, FW_NORMAL, etc.)
//
// Returns:
// Nothing.
//
//*******************************************************************
void GetViewerFont(CFont& font, LONG lfHeight, LONG lfWeight)
{
CFont fontTmp;
fontTmp.CreateStockObject(SYSTEM_FONT);
LOGFONT logFont;
fontTmp.GetObject(sizeof(LOGFONT), &logFont);
logFont.lfWidth = 0;
logFont.lfHeight = lfHeight;
logFont.lfWeight = lfWeight;
logFont.lfQuality = DEFAULT_QUALITY;
logFont.lfPitchAndFamily = DEFAULT_PITCH | FF_SWISS;
lstrcpy(logFont.lfFaceName, _T("MS Shell Dlg"));
VERIFY(font.CreateFontIndirect(&logFont));
}
//***********************************************************************
// VariantToCString
//
// Convert a variant to a CString
//
// Parameters:
// CString& sResult
// The result is returned here.
//
// VARIANT& varSrc
// The source variant.
//
// Returns:
// Nothing.
//
//**********************************************************************
void VariantToCString(CString& sResult, const VARIANT& varSrc)
{
if (varSrc.vt == VT_BSTR) {
sResult = varSrc.bstrVal;
}
else {
COleVariant var(varSrc);
ToBSTR(var);
sResult = var.bstrVal;
}
}
//**********************************************************************
// IsPrefix
//
// Check to see if one string is the prefix of another.
//
// Parameters:
// [in] LPCTSTR pszPrefix
// The prefix to check for.
//
// [in] LPCTSTR pszValue
// The string to examine.
//
// Returns:
// TRUE if the pszPrefix is a prefix of sValue.
//
//**********************************************************************
BOOL IsPrefix(LPCTSTR pszPrefix, LPCTSTR pszValue)
{
while (*pszPrefix != 0) {
if (*pszPrefix != *pszValue) {
return FALSE;
}
++pszPrefix;
++pszValue;
}
return TRUE;
}
//**********************************************************************
// ClassFromCimtype
//
// Get the classname from a reference or object cimtype.
//
// Parameters:
// [in] LPCTSTR pszPrefix
// The prefix to check for.
//
// [in] CString& sValue
// The string to examine.
//
// Returns:
// TRUE if the pszPrefix is a prefix of sValue.
//
//**********************************************************************
SCODE ClassFromCimtype(LPCTSTR pszCimtype, CString& sClass)
{
int nchPrefix;
CString sPrefix;
// Check for an object type.
sPrefix.LoadString(IDS_OBJECT_PREFIX);
if (::IsPrefix(sPrefix, pszCimtype)) {
nchPrefix = sPrefix.GetLength();
sClass = pszCimtype;
sClass = sClass.Right(sClass.GetLength() - nchPrefix);
return S_OK;
}
// Check for a reference type.
sPrefix.LoadString(IDS_REF_PREFIX);
if (::IsPrefix(sPrefix, pszCimtype)) {
nchPrefix = sPrefix.GetLength();
sClass = pszCimtype;
sClass = sClass.Right(sClass.GetLength() - nchPrefix);
return S_OK;
}
return E_FAIL;
}
BOOL HasObjectPrefix(LPCTSTR psz)
{
CString sObjectPrefix;
sObjectPrefix.LoadString(IDS_OBJECT_PREFIX);
BOOL bIsPrefix = IsPrefix(sObjectPrefix, psz);
return bIsPrefix;
}
CBSTR& CBSTR::operator=(LPCTSTR psz)
{
if (m_bstr) {
::SysFreeString(m_bstr);
}
CString s(psz);
m_bstr = s.AllocSysString();
return *this;
}
CBSTR& CBSTR::operator=(CString& s)
{
if (m_bstr) {
::SysFreeString(m_bstr);
}
m_bstr = s.AllocSysString();
return *this;
}
CBSTR& CBSTR::operator=(BSTR bstr)
{
if (m_bstr) {
::SysFreeString(m_bstr);
}
CString s;
s = bstr;
m_bstr = s.AllocSysString();
return *this;
}
int CompareNoCase(BSTR bstr1, BSTR bstr2)
{
if (bstr1 == bstr2) {
return 0;
}
if (bstr1 == NULL) {
return -1;
}
else if (bstr2 == NULL) {
return 1;
}
ASSERT(bstr1 != NULL);
ASSERT(bstr2 != NULL);
while (TRUE) {
WCHAR wch1;
WCHAR wch2;
wch1 = towupper(*bstr1);
wch2 = towupper(*bstr2);
if (wch1 < wch2) {
return -1;
}
else if (wch1 > wch2) {
return 1;
}
else if (wch1 == 0) {
return 0;
}
++bstr1;
++bstr2;
}
}
BOOL IsEqualNoCase(BSTR bstr1, BSTR bstr2)
{
if (bstr1 == bstr2) {
return TRUE;
}
if (bstr1==NULL || bstr2==NULL) {
return FALSE;
}
while (TRUE) {
WCHAR wch1;
WCHAR wch2;
wch1 = towupper(*bstr1);
wch2 = towupper(*bstr2);
if (wch1 != wch2) {
break;
}
if (wch1 == 0) {
return TRUE;
}
++bstr1;
++bstr2;
}
return FALSE;
}
//*******************************************************
// VtFromCimtype
//
// Map a cimtype to a the variant type that CIMOM uses to
// represent the value.
//
// Parameters:
// [in] CIMTYPE cimtype
// The CIMTYPE
//
//
// Returns:
// VARTYPE
// The variant type that CIMOM uses to represent the given
// CIMTYPE.
//
//******************************************************
VARTYPE VtFromCimtype(CIMTYPE cimtype)
{
BOOL bIsArray = cimtype & CIM_FLAG_ARRAY;
cimtype = cimtype & CIM_TYPEMASK;
VARTYPE vt = VT_NULL;
switch(cimtype) {
case CIM_EMPTY:
vt = VT_NULL;
break;
case CIM_SINT8:
case CIM_CHAR16:
case CIM_SINT16:
vt = VT_I2;
break;
case CIM_UINT8:
vt = VT_UI1;
break;
case CIM_UINT16:
case CIM_UINT32:
case CIM_SINT32:
vt = VT_I4;
break;
case CIM_SINT64:
case CIM_UINT64:
case CIM_STRING:
case CIM_DATETIME:
case CIM_REFERENCE:
vt = VT_BSTR;
break;
case CIM_REAL32:
vt = VT_R4;
break;
case CIM_REAL64:
vt = VT_R8;
break;
case CIM_BOOLEAN:
vt = VT_BOOL;
break;
case CIM_OBJECT:
vt = VT_UNKNOWN;
break;
}
if (bIsArray) {
vt |= VT_ARRAY;
}
return vt;
}
TMapStringToLong amapCimType[] = {
{IDS_CIMTYPE_UINT8, CIM_UINT8 },
{IDS_CIMTYPE_SINT8, CIM_SINT8}, // I2
{IDS_CIMTYPE_UINT16, CIM_UINT16}, // VT_I4 Unsigned 16-bit integer
{IDS_CIMTYPE_CHAR16, CIM_CHAR16},
{IDS_CIMTYPE_SINT16, CIM_SINT16}, // VT_I2 Signed 16-bit integer
{IDS_CIMTYPE_UINT32, CIM_UINT32}, // VT_I4 Unsigned 32-bit integer
{IDS_CIMTYPE_SINT32, CIM_SINT32}, // VT_I4 Signed 32-bit integer
{IDS_CIMTYPE_UINT64, CIM_UINT64}, // VT_BSTR Unsigned 64-bit integer
{IDS_CIMTYPE_SINT64, CIM_SINT64}, // VT_BSTR Signed 64-bit integer
{IDS_CIMTYPE_STRING, CIM_STRING}, // VT_BSTR UCS-2 string
{IDS_CIMTYPE_BOOL, CIM_BOOLEAN}, // VT_BOOL Boolean
{IDS_CIMTYPE_REAL32, CIM_REAL32}, // VT_R4 IEEE 4-byte floating-point
{IDS_CIMTYPE_REAL64, CIM_REAL64}, // VT_R8 IEEE 8-byte floating-point
{IDS_CIMTYPE_DATETIME, CIM_DATETIME}, // VT_BSTR A string containing a date-time
{IDS_CIMTYPE_REF, CIM_REFERENCE}, // VT_BSTR Weakly-typed reference
{IDS_CIMTYPE_OBJECT, CIM_OBJECT}, // VT_UNKOWN Weakly-typed embedded instance
{IDS_CIMTYPE_UINT8_ARRAY, CIM_FLAG_ARRAY | CIM_UINT8 },
{IDS_CIMTYPE_SINT8_ARRAY, CIM_FLAG_ARRAY | CIM_SINT8 }, // I2
{IDS_CIMTYPE_UINT16_ARRAY, CIM_FLAG_ARRAY | CIM_UINT16 }, // VT_I4 Unsigned 16-bit integer
{IDS_CIMTYPE_CHAR16_ARRAY, CIM_FLAG_ARRAY | CIM_CHAR16}, // VT_I2
{IDS_CIMTYPE_SINT16_ARRAY, CIM_FLAG_ARRAY | CIM_SINT16}, // VT_I2 Signed 16-bit integer
{IDS_CIMTYPE_UINT32_ARRAY, CIM_FLAG_ARRAY | CIM_UINT32}, // VT_I4 Unsigned 32-bit integer
{IDS_CIMTYPE_SINT32_ARRAY, CIM_FLAG_ARRAY | CIM_SINT32}, // VT_I4 Signed 32-bit integer
{IDS_CIMTYPE_UINT64_ARRAY, CIM_FLAG_ARRAY | CIM_UINT64}, // VT_BSTR Unsigned 64-bit integer
{IDS_CIMTYPE_SINT64_ARRAY, CIM_FLAG_ARRAY | CIM_SINT64}, // VT_BSTR Signed 64-bit integer
{IDS_CIMTYPE_STRING_ARRAY, CIM_FLAG_ARRAY | CIM_STRING}, // VT_BSTR UCS-2 string
{IDS_CIMTYPE_BOOL_ARRAY, CIM_FLAG_ARRAY | CIM_BOOLEAN}, // VT_BOOL Boolean
{IDS_CIMTYPE_REAL32_ARRAY, CIM_FLAG_ARRAY | CIM_REAL32}, // VT_R4 IEEE 4-byte floating-point
{IDS_CIMTYPE_REAL64_ARRAY, CIM_FLAG_ARRAY | CIM_REAL64}, // VT_R8 IEEE 8-byte floating-point
{IDS_CIMTYPE_DATETIME_ARRAY, CIM_FLAG_ARRAY | CIM_DATETIME}, // VT_BSTR A string containing a date-time
{IDS_CIMTYPE_REF_ARRAY, CIM_FLAG_ARRAY | CIM_REFERENCE}, // VT_BSTR Weakly-typed reference
{IDS_CIMTYPE_OBJECT_ARRAY, CIM_FLAG_ARRAY | CIM_OBJECT} // VT_UNKNOWN Weakly-typed embedded instance
};
CMapStringToLong mapCimType;
//*************************************************************
// MapStringTocimtype
//
// Map a string to one of the cimom CIMTYPE values.
//
// Parameters:
// [in] LPCTSTR pszCimtype
// A string containing a cimtype.
//
// [out] CIMTYPE& cimtype
// The cimom CIMTYPE value is returned here.
//
// Returns:
// Nothing.
//
//*************************************************************
SCODE MapStringToCimtype(LPCTSTR pszCimtype, CIMTYPE& cimtype)
{
cimtype = CIM_EMPTY;
if (IsPrefix(_T("object:"), pszCimtype)) {
cimtype = CIM_OBJECT;
return S_OK;
}
else if (IsPrefix(_T("ref:"), pszCimtype)) {
cimtype = CIM_REFERENCE;
return S_OK;
}
static BOOL bDidInitMap = FALSE;
if (!bDidInitMap) {
mapCimType.Load(amapCimType, sizeof(amapCimType) / sizeof(TMapStringToLong));
}
long lNewType;
BOOL bFoundType = mapCimType.Lookup(pszCimtype, lNewType);
if (bFoundType) {
cimtype = (CIMTYPE) lNewType;
}
else {
cimtype = CIM_EMPTY;
}
return cimtype;
}
//*************************************************************
// CGcType::MapCimtypeToString
//
// Map a CIMTYPE value to its closest string equivallent. This
// function is called for properties, such as system properties, that
// do not have a cimtype qualifier and yet we still need to display
// a string value in the "type" cells.
//
// Parameters:
// [out] CString& sCimtype
// The string value of cimtype is returned here.
//
// [in] CIMTYPE cimtype
// The cimom CIMTYPE value.
//
// Returns:
// SCODE
// S_OK if a known cimtype is specified, E_FAIL if
// an unexpected cimtype is encountered.
//
//*************************************************************
SCODE MapCimtypeToString(CString& sCimtype, CIMTYPE cimtype)
{
SCODE sc = S_OK;
BOOL bIsArray = cimtype & CIM_FLAG_ARRAY;
cimtype &= ~CIM_FLAG_ARRAY;
switch(cimtype) {
case CIM_EMPTY:
sCimtype.LoadString(IDS_CIMTYPE_EMPTY);
break;
case CIM_SINT8:
sCimtype.LoadString(IDS_CIMTYPE_SINT8);
break;
case CIM_UINT8:
sCimtype.LoadString(IDS_CIMTYPE_UINT8);
break;
case CIM_CHAR16:
sCimtype.LoadString(IDS_CIMTYPE_CHAR16);
break;
case CIM_SINT16:
sCimtype.LoadString(IDS_CIMTYPE_SINT16);
break;
case CIM_UINT16:
sCimtype.LoadString(IDS_CIMTYPE_UINT16);
break;
case CIM_SINT32:
sCimtype.LoadString(IDS_CIMTYPE_SINT32);
break;
case CIM_UINT32:
sCimtype.LoadString(IDS_CIMTYPE_UINT32);
break;
case CIM_SINT64:
sCimtype.LoadString(IDS_CIMTYPE_SINT64);
break;
case CIM_UINT64:
sCimtype.LoadString(IDS_CIMTYPE_UINT64);
break;
case CIM_REAL32:
sCimtype.LoadString(IDS_CIMTYPE_REAL32);
break;
case CIM_REAL64:
sCimtype.LoadString(IDS_CIMTYPE_REAL64);
break;
case CIM_BOOLEAN:
sCimtype.LoadString(IDS_CIMTYPE_BOOL);
break;
case CIM_STRING:
sCimtype.LoadString(IDS_CIMTYPE_STRING);
break;
case CIM_DATETIME:
sCimtype.LoadString(IDS_CIMTYPE_DATETIME);
break;
case CIM_REFERENCE:
sCimtype.LoadString(IDS_CIMTYPE_REF);
break;
case CIM_OBJECT:
sCimtype.LoadString(IDS_CIMTYPE_OBJECT);
break;
default:
sCimtype.LoadString(IDS_CIMTYPE_UNEXPECTED);
sc = E_FAIL;
break;
}
return sc;
}
//*************************************************************
// CMapStringToLong::Load
//
// Given an array of TMapStringToLong entries, load the contents
// of this map so that the strings in the input array can be
// mapped to the corresponding values.
//
// Parameters:
// TMapStringToLong* pMap
// Pointer to an array of entries containing the resource ID of
// a string and the corresponding value to map the string to.
//
// int nEntries
// The number of entries in the array.
//
// Returns:
// Nothing.
//
//**************************************************************
void CMapStringToLong::Load(TMapStringToLong* pMap, int nEntries)
{
if (m_map.GetCount() > 0) {
return;
}
CString sKey;
while (--nEntries >= 0) {
sKey.LoadString(pMap->ids);
m_map.SetAt(sKey, (void*) pMap->lValue);
++pMap;
}
}
//**************************************************************
// CMapStringToLong::Lookup
//
// Lookup the given key string and return the corresponding value.
//
// Parameters:
// LPCTSTR key
// The key value string to lookup
//
// LONG& lValue
// The place to return the value corresponding to the
// key if the key was found.
//
// Returns:
// TRUE = The key was found and a value was returned via lValue.
// FALSE = The key was not found and no value was returned.
//
//**************************************************************
BOOL CMapStringToLong::Lookup( LPCTSTR key, LONG& lValue ) const
{
void* pVoid;
BOOL bFoundKey = m_map.Lookup(key, pVoid);
if (bFoundKey) {
// NOTE: EVEN UNDER Win64, WE REALLY ONLY ARE LOOKING
// AT THE LOWER 32 BITS OF THE POINTER. WE WERE ONLY
// USING A PTR TO STORE OUR LONG VALUE. THEREFORE, IT
// IS OK FOR US TO TRUNCATE IT
lValue = (DWORD)(DWORD_PTR)pVoid;
}
return bFoundKey;
}
//**********************************************************
// MapGcTypeToDisplayType
//
// Map a gridcell type to a string that is suitable for displaying
// in a cimtype grid cell.
//
// Parameters:
// [out] CString& sDisplayType
// Pointer to the type string that appears in the cimtype dropdown
// combo box.
//
// [in] const CGcType& type
// The grid cell type.
//
// Returns:
// Nothing.
//
//***********************************************************
void MapGcTypeToDisplayType(CString& sDisplayType, const CGcType& type)
{
CIMTYPE cimtype = (CIMTYPE) type;
CString sCimtype;
sCimtype = type.CimtypeString();
sDisplayType.Empty();
if (cimtype & CIM_FLAG_ARRAY) {
sDisplayType = "array of ";
}
sDisplayType = sDisplayType + sCimtype;
}
//**********************************************************
// MapDisplayTypeToGcType
//
// Map a display type string that appears in the cimtype drop-down
// combo into the corresponding CGcType.
//
// Parameters:
// [out] CGcType& type
// The grid cell type.
//
// [in] LPCTSTR pszDisplayType
// Pointer to the type string that appears in the cimtype dropdown
// combo box.
//
// Returns:
// Nothing.
//
//***********************************************************
void MapDisplayTypeToGcType(CGcType& type, LPCTSTR pszDisplayType)
{
type.SetCellType(CELLTYPE_CIMTYPE);
// Look for stongly typed objects and references. If one is found,
// set the cimtype and sCimtype strings.
int iKeyword;
int cch;
CString sDisplayType;
CString sCimtype;
if (::IsPrefix(_T("object:"), pszDisplayType)) {
// A strongly typed object
type.SetCimtype(CIM_OBJECT, pszDisplayType);
}
else if (::IsPrefix(_T("array of object:"), pszDisplayType)) {
sDisplayType = pszDisplayType;
// A strongly typed object array
iKeyword = sDisplayType.Find(_T("object:"));
cch = sDisplayType.GetLength();
sCimtype = sDisplayType.Right(cch - iKeyword);
type.SetCimtype(CIM_OBJECT | CIM_FLAG_ARRAY, sCimtype);
}
else if (::IsPrefix(_T("ref:"), pszDisplayType)){
type.SetCimtype(CIM_REFERENCE, pszDisplayType);
}
else if (::IsPrefix(_T("array of ref:"), pszDisplayType)) {
sDisplayType = pszDisplayType;
iKeyword = sDisplayType.Find(_T("ref:"));
cch = sDisplayType.GetLength();
sCimtype = sDisplayType.Right(cch - iKeyword);
type.SetCimtype(CIM_REFERENCE | CIM_FLAG_ARRAY, sCimtype);
}
else {
// Handle all of the other type strings.
CIMTYPE cimtype;
SCODE sc;
sc = ::MapStringToCimtype(pszDisplayType, cimtype);
if (SUCCEEDED(sc)) {
type.SetCimtype(cimtype);
}
else {
ASSERT(FALSE);
type.SetCimtype(CIM_STRING);
}
}
}
//**********************************************
// IsEmptyString
//
// Check to see if a BSTR is all white space.
//
// Parameters:
// [in] LPCTSTR psz
// The string to examine.
//
// Returns:
// BOOL
// TRUE if the string is empty, FALSE otherwise.
//
//*********************************************
BOOL IsEmptyString(LPCTSTR psz)
{
ASSERT(psz != NULL);
while (isspace(*psz)) {
++psz;
}
return (*psz == 0);
}
static BOOL IsHexDigit(int ch)
{
if (isdigit(ch)) {
return TRUE;
}
if (ch>='a' && ch<='f') {
return TRUE;
}
if (ch>='A' && ch<='A') {
return TRUE;
}
return FALSE;
}
static BOOL IsValidHexNumber(LPCTSTR pszValue)
{
pszValue = EatWhite(pszValue);
if ((pszValue[0] == '0') && (pszValue[1]=='x' || pszValue[1]=='X')) {
pszValue += 2;
while (IsHexDigit(*pszValue)) {
++pszValue;
}
pszValue = EatWhite(pszValue);
if (*pszValue == 0) {
return TRUE;
}
}
return FALSE;
}
static BOOL IsValidUnsignedNumber(LPCTSTR pszValue)
{
pszValue = EatWhite(pszValue);
if (*pszValue == '-') {
return FALSE;
}
if (*pszValue=='+') {
++pszValue;
}
pszValue = EatWhite(pszValue);
if (!isdigit(*pszValue)) {
return FALSE;
}
++pszValue;
while (isdigit(*pszValue)) {
++pszValue;
}
pszValue = EatWhite(pszValue);
if (*pszValue == 0) {
return TRUE;
}
else {
return FALSE;
}
}
static BOOL IsValidSignedNumber(LPCTSTR pszValue)
{
pszValue = EatWhite(pszValue);
if (*pszValue == 0) {
return FALSE;
}
if (*pszValue=='+' || *pszValue=='-') {
++pszValue;
}
pszValue = EatWhite(pszValue);
if (!isdigit(*pszValue)) {
return FALSE;
}
++pszValue;
while (isdigit(*pszValue)) {
++pszValue;
}
pszValue = EatWhite(pszValue);
if (*pszValue == 0) {
return TRUE;
}
else {
return FALSE;
}
}
#define MAX_UINT8 0x0ff
#define MIN_UINT8 0
#define MAX_SINT8 0x07f
#define MIN_SINT8 (~MAX_SINT8 & -1)
#define MAX_UINT16 0x0ffff
#define MIN_UINT16 0
#define MAX_SINT16 0x07fff
#define MIN_SINT16 (~MAX_SINT16 & -1)
#define MAX_UINT32 0x0ffffffff
#define MIN_UINT32 0
#define MAX_SINT32 0x07fffffff
#define MIN_SINT32 (~MAX_SINT32 & -1)
static BOOL IsValidCIM_SINT8(LPCTSTR pszValue)
{
if (!IsValidSignedNumber(pszValue)) {
return FALSE;
}
pszValue = EatWhite(pszValue);
int iValue;
int nFields = _stscanf(pszValue, _T("%d"), &iValue);
if (nFields != 1) {
return FALSE;
}
if ((iValue > MAX_SINT8) || (iValue < MIN_SINT8)) {
return FALSE;
}
return TRUE;
}
static BOOL IsValidCIM_UINT8(LPCTSTR pszValue)
{
if (!IsValidUnsignedNumber(pszValue)) {
return FALSE;
}
pszValue = EatWhite(pszValue);
unsigned int iValue;
int nFields = _stscanf(pszValue, _T("%ud"), &iValue);
if (nFields != 1) {
return FALSE;
}
if (iValue<MIN_UINT8 || iValue > MAX_UINT8) {
return FALSE;
}
return TRUE;
}
static BOOL IsValidCIM_SINT16(LPCTSTR pszValue)
{
if (!IsValidSignedNumber(pszValue)) {
return FALSE;
}
pszValue = EatWhite(pszValue);
int iValue;
int nFields = _stscanf(pszValue, _T("%d"), &iValue);
if (nFields != 1) {
return FALSE;
}
if ((iValue > MAX_SINT16) || (iValue < MIN_SINT16)) {
return FALSE;
}
return TRUE;
}
static BOOL IsValidCIM_UINT16(LPCTSTR pszValue)
{
if (!IsValidUnsignedNumber(pszValue)) {
return FALSE;
}
pszValue = EatWhite(pszValue);
unsigned int iValue;
int nFields = _stscanf(pszValue, _T("%ud"), &iValue);
if (nFields != 1) {
return FALSE;
}
if (iValue<MIN_UINT16 || iValue > MAX_UINT16) {
return FALSE;
}
return TRUE;
}
static BOOL IsValidCIM_SINT32(LPCTSTR pszValue)
{
if (!IsValidSignedNumber(pszValue)) {
return FALSE;
}
pszValue = EatWhite(pszValue);
int iValue;
int nFields = _stscanf(pszValue, _T("%d"), &iValue);
if (nFields != 1) {
return FALSE;
}
if ((iValue > MAX_SINT32) || (iValue < MIN_SINT32)) {
return FALSE;
}
return TRUE;
}
static BOOL IsValidCIM_UINT32(LPCTSTR pszValue)
{
if (!IsValidUnsignedNumber(pszValue)) {
return FALSE;
}
pszValue = EatWhite(pszValue);
unsigned long ulValue;
SCODE sc = AToUint32(pszValue, ulValue);
if (FAILED(sc)) {
return FALSE;
}
return TRUE;
}
static BOOL IsValidCIM_SINT64(LPCTSTR pszValue)
{
if (!IsValidSignedNumber(pszValue)) {
return FALSE;
}
__int64 iValue;
SCODE sc = AToSint64(pszValue, iValue);
if (FAILED(sc)) {
return FALSE;
}
return TRUE;
}
static BOOL IsValidCIM_UINT64(LPCTSTR pszValue)
{
if (!IsValidUnsignedNumber(pszValue)) {
return FALSE;
}
return TRUE;
}
static BOOL IsValidCIM_REAL32(LPCTSTR pszValue)
{
pszValue = EatWhite(pszValue);
float fltValue;
int nFields = _stscanf(pszValue, _T("%f"), &fltValue);
if (nFields != 1) {
return FALSE;
}
return TRUE;
}
static BOOL IsValidCIM_Real64(LPCTSTR pszValue)
{
pszValue = EatWhite(pszValue);
float fltValue;
int nFields = _stscanf(pszValue, _T("%f"), &fltValue);
if (nFields != 1) {
return FALSE;
}
return TRUE;
}
static BOOL IsValidCIM_Boolean(LPCTSTR pszValue)
{
// !!!CR: Validation needs to be implemented.
return TRUE;
}
static BOOL IsValidCIM_Datetime(LPCTSTR pszValue)
{
// !!!CR: Validation needs to be implemented.
return TRUE;
}
static BOOL IsValidCIM_CHAR16(LPCTSTR pszValue)
{
return IsValidCIM_SINT16(pszValue);
}
BOOL IsValidValue(CIMTYPE cimtype, LPCTSTR pszValue, BOOL bDisplayErrorMessage)
{
BOOL bIsValid = TRUE;
switch(cimtype) {
case CIM_SINT8:
bIsValid = IsValidCIM_SINT8(pszValue);
break;
case CIM_UINT8:
bIsValid = IsValidCIM_UINT8(pszValue);
break;
case CIM_SINT16:
bIsValid = IsValidCIM_SINT16(pszValue);
break;
case CIM_UINT16:
bIsValid = IsValidCIM_UINT16(pszValue);
break;
case CIM_SINT32:
bIsValid = IsValidCIM_SINT32(pszValue);
break;
case CIM_UINT32:
bIsValid = IsValidCIM_UINT32(pszValue);
break;
case CIM_SINT64:
bIsValid = IsValidCIM_SINT64(pszValue);
break;
case CIM_UINT64:
bIsValid = IsValidCIM_UINT64(pszValue);
break;
case CIM_REAL32:
bIsValid = IsValidCIM_REAL32(pszValue);
break;
case CIM_REAL64:
bIsValid = IsValidCIM_Real64(pszValue);
break;
case CIM_BOOLEAN:
bIsValid = IsValidCIM_Boolean(pszValue);
break;
case CIM_STRING:
bIsValid = TRUE;
break;
case CIM_DATETIME:
bIsValid = IsValidCIM_Datetime(pszValue);
break;
case CIM_REFERENCE:
bIsValid = TRUE;
break;
case CIM_CHAR16:
bIsValid = IsValidCIM_CHAR16(pszValue);
break;
default:
break;
}
if (!bIsValid && bDisplayErrorMessage) {
TCHAR szBuffer[1024];
CString sMessage;
CString sCimtype;
sMessage.LoadString(IDS_ERR_INVALID_VALUE);
MapCimtypeToString(sCimtype, cimtype);
_stprintf(szBuffer, sMessage, (LPCTSTR) sCimtype);
HmmvErrorMsg(szBuffer, S_OK, FALSE, NULL, _T(__FILE__), __LINE__);
}
return bIsValid;
}