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

4057 lines
100 KiB
C++

// validation.cpp
// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved
#include "precomp.h"
#include "schemavalwiz.h"
#include "schemavalwizctl.h"
#include "validation.h"
#include <commdlg.h>
CString g_csaClassQual[QUAL_ARRAY_SIZE];
CString g_csaAssocQual[QUAL_ARRAY_SIZE];
CString g_csaIndicQual[QUAL_ARRAY_SIZE];
CString g_csaPropQual[QUAL_ARRAY_SIZE];
CString g_csaArrayQual[QUAL_ARRAY_SIZE];
CString g_csaRefQual[QUAL_ARRAY_SIZE];
CString g_csaMethodQual[QUAL_ARRAY_SIZE];
CString g_csaParamQual[QUAL_ARRAY_SIZE];
CString g_csaAnyQual[QUAL_ARRAY_SIZE];
CString g_csaCIMQual[QUAL_ARRAY_SIZE * 2];
int g_iClassQual;
int g_iAssocQual;
int g_iIndicQual;
int g_iPropQual;
int g_iArrayQual;
int g_iRefQual;
int g_iMethodQual;
int g_iParamQual;
int g_iAnyQual;
int g_iCIMQual;
CString g_csaNoise[100];
int g_iNoise;
CReportLog g_ReportLog;
CLocalNamespace::CLocalNamespace(CString *csName, IWbemServices *pNamespace, IWbemServices *pParentNamespace)
{
m_pThisNamespace = pNamespace;
m_pParentNamespace = pParentNamespace;
m_csName = *csName;
m_csPath = m_csName;
}
CLocalNamespace::~CLocalNamespace()
{
}
CString CLocalNamespace::GetName() { return m_csName; }
CString CLocalNamespace::GetPath() { return m_csPath; }
IWbemServices * CLocalNamespace::GetThisNamespace() { return m_pThisNamespace; }
IWbemServices * CLocalNamespace::GetParentNamespace() { return m_pParentNamespace; }
HRESULT CLocalNamespace::Local_ValidLocale()
{
HRESULT hr = WBEM_S_NO_ERROR;
int i = 0;
CString csLocale = m_csName;
while(m_csName[i] != L'_') i++;
csLocale = m_csName.Right(m_csName.GetLength() - i);
//check to see if the locale is valid
if(!((0 == csLocale.CompareNoCase(_T("0x0000"))) || (0 == csLocale.CompareNoCase(_T("0x0406"))) ||
(0 == csLocale.CompareNoCase(_T("0x0413"))) || (0 == csLocale.CompareNoCase(_T("0x0813"))) ||
(0 == csLocale.CompareNoCase(_T("0x0409"))) || (0 == csLocale.CompareNoCase(_T("0x0809"))) ||
(0 == csLocale.CompareNoCase(_T("0x0c09"))) || (0 == csLocale.CompareNoCase(_T("0x1009"))) ||
(0 == csLocale.CompareNoCase(_T("0x1409"))) || (0 == csLocale.CompareNoCase(_T("0x1809"))) ||
(0 == csLocale.CompareNoCase(_T("0x040b"))) || (0 == csLocale.CompareNoCase(_T("0x040c"))) ||
(0 == csLocale.CompareNoCase(_T("0x080c"))) || (0 == csLocale.CompareNoCase(_T("0x0c0c"))) ||
(0 == csLocale.CompareNoCase(_T("0x100c"))) || (0 == csLocale.CompareNoCase(_T("0x0407"))) ||
(0 == csLocale.CompareNoCase(_T("0x0807"))) || (0 == csLocale.CompareNoCase(_T("0x0c07"))) ||
(0 == csLocale.CompareNoCase(_T("0x040f"))) || (0 == csLocale.CompareNoCase(_T("0x0410"))) ||
(0 == csLocale.CompareNoCase(_T("0x0810"))) || (0 == csLocale.CompareNoCase(_T("0x0414"))) ||
(0 == csLocale.CompareNoCase(_T("0x0814"))) || (0 == csLocale.CompareNoCase(_T("0x0416"))) ||
(0 == csLocale.CompareNoCase(_T("0x0816"))) || (0 == csLocale.CompareNoCase(_T("0x041D"))) ||
(0 == csLocale.CompareNoCase(_T("0x040a"))) || (0 == csLocale.CompareNoCase(_T("0x080a"))) ||
(0 == csLocale.CompareNoCase(_T("0x0c0a"))) || (0 == csLocale.CompareNoCase(_T("0x0415"))) ||
(0 == csLocale.CompareNoCase(_T("0x0405"))) || (0 == csLocale.CompareNoCase(_T("0x041b"))) ||
(0 == csLocale.CompareNoCase(_T("0x040e"))) || (0 == csLocale.CompareNoCase(_T("0x0419"))) ||
(0 == csLocale.CompareNoCase(_T("0x0408"))) || (0 == csLocale.CompareNoCase(_T("0x0400"))) ||
(0 == csLocale.CompareNoCase(_T("0x041f")))))
g_ReportLog.LogEntry(EC_INVALID_LOCALE_NAMESPACE, &m_csPath);
//Check to make sure the Locale is valid
return hr;
}
HRESULT CLocalNamespace::Local_ValidLocalizedClass(CClass *pClass)
{
HRESULT hr = WBEM_S_NO_ERROR;
IWbemClassObject *pErrorObject = NULL;
CString csName = pClass->GetName();
BSTR bstrName = csName.AllocSysString();
IWbemClassObject *pObj = NULL;
if(FAILED(hr = m_pParentNamespace->GetObject(bstrName, 0, NULL, &pObj, NULL))){
CString csUserMsg = _T("Cannot get ") + pClass->GetName();
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
return hr;
}
SysFreeString(bstrName);
IWbemClassObject *pLocalObj = pClass->GetClassObject();
LONG lType, lTypeLocal;
LONG lFlavor, lFlavorLocal;
VARIANT v, vLocal;
VariantInit(&v);
VariantInit(&vLocal);
pLocalObj->BeginEnumeration(WBEM_FLAG_LOCAL_ONLY);
while((hr = pLocalObj->Next(0, &bstrName, &vLocal, &lTypeLocal, &lFlavorLocal)) == WBEM_S_NO_ERROR){
if(FAILED(hr = pObj->Get(bstrName, 0, &v, &lType, &lFlavor)))
g_ReportLog.LogEntry(EC_INVALID_LOCALIZED_CLASS, &pClass->GetPath());
if(lType != lTypeLocal)
g_ReportLog.LogEntry(EC_INVALID_LOCALIZED_PROPERTY, &pClass->GetPath());
else if(lFlavor != lFlavorLocal)
g_ReportLog.LogEntry(EC_INVALID_LOCALIZED_PROPERTY, &pClass->GetPath());
SysFreeString(bstrName);
VariantClear(&v);
VariantClear(&vLocal);
}
pLocalObj->EndEnumeration();
//check the methods
IWbemClassObject *pInLocal = NULL;
IWbemClassObject *pOutLocal = NULL;
pLocalObj->BeginMethodEnumeration(0);
while((hr = pLocalObj->NextMethod(0, &bstrName, &pInLocal, &pOutLocal)) == WBEM_S_NO_ERROR){
CString csMethodPath = pClass->GetPath() + _T(".") + bstrName;
IWbemClassObject *pIn = NULL;
IWbemClassObject *pOut = NULL;
if(FAILED(hr = pObj->GetMethod(bstrName, 0, &pIn, &pOut)))
g_ReportLog.LogEntry(EC_INVALID_LOCALIZED_CLASS, &pClass->GetPath());
if(pInLocal && FAILED(pInLocal->CompareTo((WBEM_FLAG_IGNORE_CASE | WBEM_FLAG_IGNORE_QUALIFIERS | WBEM_FLAG_IGNORE_DEFAULT_VALUES | WBEM_FLAG_IGNORE_OBJECT_SOURCE ), pIn)))
g_ReportLog.LogEntry(EC_INVALID_LOCALIZED_METHOD, &csMethodPath);
else if(pOutLocal && FAILED(pOutLocal->CompareTo((WBEM_FLAG_IGNORE_CASE | WBEM_FLAG_IGNORE_QUALIFIERS | WBEM_FLAG_IGNORE_DEFAULT_VALUES | WBEM_FLAG_IGNORE_OBJECT_SOURCE ), pOut)))
g_ReportLog.LogEntry(EC_INVALID_LOCALIZED_METHOD, &csMethodPath);
//do some deeper comparisons
else if(pInLocal){
pInLocal->BeginEnumeration(WBEM_FLAG_LOCAL_ONLY);
while((hr = pInLocal->Next(0, &bstrName, &vLocal, &lTypeLocal, &lFlavorLocal)) == WBEM_S_NO_ERROR){
if(FAILED(hr = pIn->Get(bstrName, 0, &v, &lType, &lFlavor)))
g_ReportLog.LogEntry(EC_INVALID_LOCALIZED_METHOD, &csMethodPath);
if(lType != lTypeLocal)
g_ReportLog.LogEntry(EC_INVALID_LOCALIZED_METHOD, &csMethodPath);
else if(lFlavor != lFlavorLocal)
g_ReportLog.LogEntry(EC_INVALID_LOCALIZED_METHOD, &csMethodPath);
SysFreeString(bstrName);
VariantClear(&v);
VariantClear(&vLocal);
}
pInLocal->EndEnumeration();
if(pInLocal){
pOutLocal->BeginEnumeration(WBEM_FLAG_LOCAL_ONLY);
while((hr = pOutLocal->Next(0, &bstrName, &vLocal, &lTypeLocal, &lFlavorLocal)) == WBEM_S_NO_ERROR){
if(FAILED(hr = pOut->Get(bstrName, 0, &v, &lType, &lFlavor)))
g_ReportLog.LogEntry(EC_INVALID_LOCALIZED_METHOD, &csMethodPath);
if(lType != lTypeLocal)
g_ReportLog.LogEntry(EC_INVALID_LOCALIZED_METHOD, &csMethodPath);
else if(lFlavor != lFlavorLocal)
g_ReportLog.LogEntry(EC_INVALID_LOCALIZED_METHOD, &csMethodPath);
SysFreeString(bstrName);
VariantClear(&v);
VariantClear(&vLocal);
}
pOutLocal->EndEnumeration();
}
}
SysFreeString(bstrName);
if(pInLocal) pInLocal->Release();
if(pOutLocal) pOutLocal->Release();
pInLocal = NULL;
pOutLocal = NULL;
if(pIn) pIn->Release();
if(pOut) pOut->Release();
}
pLocalObj->EndMethodEnumeration();
pObj->Release();
ReleaseErrorObject(pErrorObject);
return hr;
}
/*
HRESULT CLocalNamespace::Local_ValidAmendedLocalClass()
{
HRESULT hr = WBEM_S_NO_ERROR;
return hr;
}
HRESULT CLocalNamespace::Local_ValidAbstractLocalClass()
{
HRESULT hr = WBEM_S_NO_ERROR;
return hr;
}
*/
/////////////////////////////////////////////
// CClass
CClass::CClass(CString *csName, IWbemClassObject *pClass, IWbemServices *pNamespace)
{
m_pClass = pClass;
m_csName = *csName;
m_pNamespace = pNamespace;
m_pQualSet = NULL;
IWbemClassObject *pErrorObject = NULL;
HRESULT hr = WBEM_S_NO_ERROR;
if(FAILED(hr = m_pClass->GetQualifierSet(&m_pQualSet))){
CString csUserMsg = _T("Cannot get ") + *csName + _T(" qualifier set");
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
}
CString csPATH = _T("__PATH");
m_csPath = GetBSTRProperty(m_pClass, &csPATH);
ReleaseErrorObject(pErrorObject);
}
CClass::~CClass()
{
}
void CClass::CleanUp()
{
if(m_pClass) m_pClass->Release();
if(m_pQualSet) m_pQualSet->Release();
m_csName.Empty();
m_csPath.Empty();
}
CString CClass::GetName() { return m_csName; }
CString CClass::GetPath() { return m_csPath; }
IWbemClassObject * CClass::GetClassObject() { return m_pClass; }
IWbemQualifierSet * CClass::GetQualifierSet() { return m_pQualSet; }
HRESULT CClass::ValidClassName()
{
HRESULT hr = WBEM_S_NO_ERROR;
// Check class name for a numeric first character
if(m_csName[0] == '1' || m_csName[0] == '2' || m_csName[0] == '3' || m_csName[0] == '4' ||
m_csName[0] == '5' || m_csName[0] == '6' || m_csName[0] == '7' || m_csName[0] == '8' ||
m_csName[0] == '9' || m_csName[0] == '0'){
g_ReportLog.LogEntry(EC_INVALID_CLASS_NAME, &m_csPath);
}
// Check class name for multiple underscores
int iLen = m_csName.GetLength();
int iUnderscore = -1;
for(int i = 1; i < iLen; i++){
if(m_csName[i] == '_'){
//if we already have an underscore, and it was the preceding character...
if(iUnderscore > -1){
if((iUnderscore + 1) == i){
g_ReportLog.LogEntry(EC_INVALID_CLASS_NAME, &m_csPath);
break;
}else if((iUnderscore + 1) < i)
break;
}
iUnderscore = i;
}
}
if(iUnderscore == -1) g_ReportLog.LogEntry(EC_INVALID_CLASS_NAME, &m_csPath);
return hr;
}
HRESULT CClass::VerifyClassType()
{
HRESULT hr = WBEM_S_NO_ERROR;
bool bAbstract, bDynamic, bStatic, bProvider;
bAbstract = bDynamic = bStatic = bProvider = false;
VARIANT v;
VariantInit(&v);
// Check for abstract, dynamic and static qualifiers
BSTR bstrAbstract = SysAllocString(L"Abstract");
if(SUCCEEDED(m_pQualSet->Get(bstrAbstract, 0, &v, NULL))){
bAbstract = true;
// Check class derivation for proper abstract usage.
}
SysFreeString(bstrAbstract);
VariantClear(&v);
BSTR bstrDynamic = SysAllocString(L"Dynamic");
if(SUCCEEDED(m_pQualSet->Get(bstrDynamic, 0, &v, NULL))) bDynamic = true;
SysFreeString(bstrDynamic);
VariantClear(&v);
BSTR bstrStatic = SysAllocString(L"Static");
if(SUCCEEDED(m_pQualSet->Get(bstrStatic, 0, &v, NULL))) bStatic = true;
SysFreeString(bstrStatic);
VariantClear(&v);
// Perform Provider check
BSTR bstrProvider = SysAllocString(L"Provider");
if(SUCCEEDED(m_pQualSet->Get(bstrProvider, 0, &v, NULL))) bProvider = true;
SysFreeString(bstrProvider);
VariantClear(&v);
// Check class is abstract, static or dynamic
if(!bAbstract && !bDynamic && !bStatic){
g_ReportLog.LogEntry(EC_INVALID_CLASS_TYPE, &m_csPath);
}else if((bAbstract && (bDynamic || bStatic)) || (bDynamic && bStatic)){
g_ReportLog.LogEntry(EC_INVALID_CLASS_TYPE, &m_csPath);
}
// Check class with provider is dynamic and visa vis
if((bProvider && !bDynamic) || (!bProvider && bDynamic)){
g_ReportLog.LogEntry(EC_INVALID_CLASS_TYPE, &m_csPath);
}
return hr;
}
bool CClass::IsAssociation()
{
bool bRetVal = false;
// Check for association qualifier
BSTR bstrAssociation = SysAllocString(L"Association");
if(SUCCEEDED(m_pQualSet->Get(bstrAssociation, 0, NULL, NULL))) bRetVal = true;
//check the inheritence
if(!bRetVal){
HRESULT hr = WBEM_S_NO_ERROR;
VARIANT vDer, v;
IWbemClassObject *pErrorObject = NULL;
VariantInit(&vDer);
VariantInit(&v);
// Check override validity
//get derivation
BSTR bstrDerivation = SysAllocString(L"__DERIVATION");
if(FAILED(hr = m_pClass->Get(bstrDerivation, 0, &vDer, NULL, NULL))){
CString csUserMsg = _T("Cannot get ") + m_csName + _T(" derivation");
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
}else{
BSTR HUGEP *pbstr;
long ix[2] = {0,0};
long lLower, lUpper;
int iDim = SafeArrayGetDim(vDer.parray);
HRESULT hr = SafeArrayGetLBound(vDer.parray, 1, &lLower);
hr = SafeArrayGetUBound(vDer.parray, 1, &lUpper);
hr = SafeArrayAccessData(vDer.parray, (void HUGEP* FAR*)&pbstr);
IWbemClassObject *pObj;
IWbemQualifierSet *pQualSet;
LONG lFlavor;
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++){
pObj = NULL;
pQualSet = NULL;
//get the super-object
hr = m_pNamespace->GetObject(pbstr[ix[0]], 0, NULL, &pObj, NULL);
hr = pObj->GetQualifierSet(&pQualSet);
//check if it's an association
if(SUCCEEDED(hr = pQualSet->Get(bstrAssociation, 0, NULL, &lFlavor))){
if(lFlavor == WBEM_FLAVOR_FLAG_PROPAGATE_TO_DERIVED_CLASS)
bRetVal = true;
}
pQualSet->Release();
pObj->Release();
if(bRetVal) break;
}
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++)SysFreeString(pbstr[ix[0]]);
}
SysFreeString(bstrDerivation);
VariantClear(&vDer);
VariantClear(&v);
ReleaseErrorObject(pErrorObject);
}
SysFreeString(bstrAssociation);
return bRetVal;
}
bool CClass::IsAbstract()
{
bool bRetVal = false;
// Check for abstract qualifier
BSTR bstrAbstract = SysAllocString(L"Abstract");
if(SUCCEEDED(m_pQualSet->Get(bstrAbstract, 0, NULL, NULL))) bRetVal = true;
SysFreeString(bstrAbstract);
return bRetVal;
}
HRESULT CClass::VerifyCompleteAssociation()
{
int iREFs = 0;
m_pClass->BeginEnumeration(WBEM_FLAG_REFS_ONLY | WBEM_FLAG_NONSYSTEM_ONLY);
HRESULT hr = WBEM_S_NO_ERROR;
while((hr = m_pClass->Next(0, NULL, NULL, NULL, NULL)) == WBEM_S_NO_ERROR) iREFs++;
//If we have less thean two REFs file an error
if(iREFs < 2) g_ReportLog.LogEntry(EC_INCOMPLETE_ASSOCIATION, &m_csPath);
return hr;
}
HRESULT CClass::ValidAssociationInheritence()
{
HRESULT hr = WBEM_S_NO_ERROR;
IWbemClassObject *pErrorObject = NULL;
IWbemClassObject *pSuperclass = NULL;
if(!IsAssociation()){
BSTR bstrSuperclass = SysAllocString(GetSuperClassName(m_pClass));
if(FAILED(hr = m_pNamespace->GetObject(bstrSuperclass, 0, NULL, &pSuperclass, NULL))){
CString csUserMsg = _T("Cannot get ") + m_csName + _T(" superclass");
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
SysFreeString(bstrSuperclass);
ReleaseErrorObject(pErrorObject);
}
IWbemQualifierSet *pQualSet = NULL;
if(FAILED(hr = pSuperclass->GetQualifierSet(&pQualSet))){
CString csSuperclass = bstrSuperclass;
CString csUserMsg = _T("Cannot get ") + csSuperclass + _T(" qualifier set");
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
SysFreeString(bstrSuperclass);
ReleaseErrorObject(pErrorObject);
}
BSTR bstrAssociation = SysAllocString(L"Association");
if(SUCCEEDED(pQualSet->Get(bstrAssociation, 0, NULL, NULL)))
g_ReportLog.LogEntry(EC_INVALID_ASSOCIATION_INHERITANCE, &m_csPath);
pQualSet->Release();
pSuperclass->Release();
SysFreeString(bstrAssociation);
SysFreeString(bstrSuperclass);
}
return hr;
}
HRESULT CClass::VerifyNoREF()
{
HRESULT hr = WBEM_S_NO_ERROR;
int iREFs = 0;
m_pClass->BeginEnumeration(WBEM_FLAG_REFS_ONLY | WBEM_FLAG_LOCAL_ONLY);
while((hr = m_pClass->Next(0, NULL, NULL, NULL, NULL)) == WBEM_S_NO_ERROR) iREFs++;
//If we have REFs file an error
if(iREFs > 0) g_ReportLog.LogEntry(EC_REF_ON_NONASSOCIATION_CLASS, &m_csPath);
return hr;
}
HRESULT CClass::W2K_ValidDerivation()
{
HRESULT hr = WBEM_S_NO_ERROR;
CString csSuperClass = GetSuperClassName(m_pClass);
CString csSuperSchema = csSuperClass;
CString csSchema = csSuperClass;
int i = 0;
bool bHaveSchema = false;
int iSize = csSuperSchema.GetLength();
//check for system classes
if((iSize > 0) && (csSuperSchema[0] != L'_')){
for(i = 0; i < iSize; i++){
if(csSuperSchema[i] == L'_'){
bHaveSchema = true;
break;
}
}
if(bHaveSchema){
csSuperSchema = csSuperSchema.Left(i);
if(csSuperSchema.CompareNoCase(_T("CIM")) == 0){
//check for proper CIM derivation
if(!(csSuperClass.CompareNoCase(_T("CIM_Product")) == 0) &&
!(csSuperClass.CompareNoCase(_T("CIM_PhysicalElement")) == 0) &&
!(csSuperClass.CompareNoCase(_T("CIM_FRU")) == 0) &&
!(csSuperClass.CompareNoCase(_T("CIM_Setting")) == 0) &&
!(csSuperClass.CompareNoCase(_T("CIM_Configuration")) == 0) &&
!(csSuperClass.CompareNoCase(_T("CIM_SupportAccess")) == 0) &&
!(csSuperClass.CompareNoCase(_T("CIM_Realizes")) == 0) &&
!(csSuperClass.CompareNoCase(_T("CIM_ElementSetting")) == 0) &&
!(csSuperClass.CompareNoCase(_T("CIM_ProductParentChild")) == 0) &&
!(csSuperClass.CompareNoCase(_T("CIM_ProductSupport")) == 0) &&
!(csSuperClass.CompareNoCase(_T("CIM_ProductPhysicalElements")) == 0) &&
!(csSuperClass.CompareNoCase(_T("CIM_FRUIncludesProduct")) == 0) &&
!(csSuperClass.CompareNoCase(_T("CIM_ProductSoftwareFeatures")) == 0) &&
!(csSuperClass.CompareNoCase(_T("CIM_ProductFRU")) == 0) &&
!(csSuperClass.CompareNoCase(_T("CIM_FRUPhysicalElements")) == 0)){
//fix for 56607 - allow Win32 classes to derive from
//CIM_LogicalElement
bHaveSchema = false;
for(i = 0; i < iSize; i++){
if(csSchema[i] == L'_'){
bHaveSchema = true;
break;
}
}
if(bHaveSchema){
csSchema = csSchema.Left(i);
if(csSchema.CompareNoCase(_T("Win32")) == 0){
if(!(csSuperClass.CompareNoCase(_T("CIM_LogicalElement")) == 0))
g_ReportLog.LogEntry(EC_INVALID_CLASS_DERIVATION, &m_csPath);
}
}
}
}else if(csSchema.CompareNoCase(_T("Win32")) == 0){
//this derivation is fine... do nothing
}else{
//this derivation is also fine... do nothing
}
}
}
return hr;
}
HRESULT CClass::W2K_ValidPhysicalElementDerivation()
{
HRESULT hr = WBEM_S_NO_ERROR;
IWbemClassObject *pErrorObject = NULL;
CString csClassSchema = GetClassSchema();
int i, iSize;
bool bHaveSchema = false;
iSize = csClassSchema.GetLength();
if(csClassSchema.GetLength() > 0){
//we have special rules for win32 classes... they
// can do things that others can't (like derive however
//they want from LogicalDevice)
if(csClassSchema.CompareNoCase(_T("Win32")) == 0)
return hr;
}
CString csSuperClass = GetSuperClassName(m_pClass);
if(csSuperClass.GetLength() < 1)
return hr;
//check the classes derivation
//get derivation
BSTR bstrDerivation = SysAllocString(L"__DERIVATION");
VARIANT vDer;
VariantInit(&vDer);
if(FAILED(hr = m_pClass->Get(bstrDerivation, 0, &vDer, NULL, NULL))){
CString csUserMsg = _T("Cannot get ") + m_csName + _T(" derivation");
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
SysFreeString(bstrDerivation);
ReleaseErrorObject(pErrorObject);
}else{
SysFreeString(bstrDerivation);
BSTR HUGEP *pbstr;
long ix[2] = {0,0};
long lLower, lUpper;
bool bFound = false;
int iDim = SafeArrayGetDim(vDer.parray);
HRESULT hr = SafeArrayGetLBound(vDer.parray, 1, &lLower);
hr = SafeArrayGetUBound(vDer.parray, 1, &lUpper);
hr = SafeArrayAccessData(vDer.parray, (void HUGEP* FAR*)&pbstr);
CString csDer;
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++){
csDer = pbstr[ix[0]];
if(csDer.CompareNoCase(_T("CIM_PhysicalElement")) == 0){
bFound = true;
break;
}
}
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++)
SysFreeString(pbstr[ix[0]]);
VariantClear(&vDer);
if(bFound){
//get the subclasses of the superclass
CString csQuery = _T("select * from meta_class where __SUPERCLASS=\"") + csSuperClass + _T("\"");
BSTR bstrQuery = csQuery.AllocSysString();
BSTR bstrWQL = SysAllocString(L"WQL");
IEnumWbemClassObject *pEnum = NULL;
if(FAILED(hr = m_pNamespace->ExecQuery(bstrWQL, bstrQuery, 0, NULL, &pEnum))){
CString csUserMsg = _T("Cannot get ") + csSuperClass;
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
SysFreeString(bstrWQL);
SysFreeString(bstrQuery);
return hr;
}
SysFreeString(bstrWQL);
SysFreeString(bstrQuery);
IWbemClassObject *pObj = NULL;
ULONG uReturned;
CString csSchema;
//check for classes derived from the superclass
// if there are cim or win32 classes log error
while((hr = pEnum->Next(INFINITE, 1, &pObj, &uReturned)) == WBEM_S_NO_ERROR){
csSchema = GetClassName(pObj);
i = 0;
bHaveSchema = false;
iSize = csSchema.GetLength();
//check for system classes
if((iSize > 0) && (csSchema[0] != L'_')){
for(i = 0; i < iSize; i++){
if(csSchema[i] == L'_'){
bHaveSchema = true;
break;
}
}
if(bHaveSchema){
csSchema = csSchema.Left(i);
if(csSchema.CompareNoCase(_T("CIM")) == 0){
g_ReportLog.LogEntry(EC_INVALID_PHYSICALELEMENT_DERIVATION, &m_csPath);
break;
}else if(csSchema.CompareNoCase(_T("Win32")) == 0){
g_ReportLog.LogEntry(EC_INVALID_PHYSICALELEMENT_DERIVATION, &m_csPath);
break;
}else{
//this derivation is fine... do nothing
}
}
}
pObj->Release();
pObj = NULL;
}
pEnum->Release();
}
}
ReleaseErrorObject(pErrorObject);
return hr;
}
HRESULT CClass::W2K_ValidSettingUsage(CStringArray *pStringArray)
{
HRESULT hr = WBEM_S_NO_ERROR;
if(IsAbstract())
return hr;
IWbemClassObject *pErrorObject = NULL;
//check the classes derivation
//get derivation
BSTR bstrDerivation = SysAllocString(L"__DERIVATION");
VARIANT vDer;
VariantInit(&vDer);
if(FAILED(hr = m_pClass->Get(bstrDerivation, 0, &vDer, NULL, NULL))){
CString csUserMsg = _T("Cannot get ") + m_csName + _T(" derivation");
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
SysFreeString(bstrDerivation);
ReleaseErrorObject(pErrorObject);
}else{
SysFreeString(bstrDerivation);
BSTR HUGEP *pbstr;
long ix[2] = {0,0};
long lLower, lUpper;
bool bFound = false;
int iDim = SafeArrayGetDim(vDer.parray);
HRESULT hr = SafeArrayGetLBound(vDer.parray, 1, &lLower);
hr = SafeArrayGetUBound(vDer.parray, 1, &lUpper);
hr = SafeArrayAccessData(vDer.parray, (void HUGEP* FAR*)&pbstr);
CString csDer;
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++){
csDer = pbstr[ix[0]];
if(csDer.CompareNoCase(_T("CIM_Setting")) == 0){
bFound = true;
break;
}
}
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++)
SysFreeString(pbstr[ix[0]]);
VariantClear(&vDer);
if(bFound){
bFound = false;
CString csQuery = _T("references of {") + m_csName +
_T("} where resultclass=CIM_ElementSetting schemaonly");
BSTR bstrQuery = csQuery.AllocSysString();
BSTR bstrWQL = SysAllocString(L"WQL");
IEnumWbemClassObject *pEnum = NULL;
if(FAILED(hr = m_pNamespace->ExecQuery(bstrWQL, bstrQuery, 0, NULL, &pEnum))){
CString csUserMsg = _T("Cannot execute references query for ") + m_csName;
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
SysFreeString(bstrWQL);
SysFreeString(bstrQuery);
return hr;
}
SysFreeString(bstrWQL);
SysFreeString(bstrQuery);
IWbemClassObject *pObj = NULL;
ULONG uReturned;
CString csObj;
int iClasses, i;
CString csClass;
//check for classes derived from the superclass
// if there are cim or win32 classes log error
while((hr = pEnum->Next(INFINITE, 1, &pObj, &uReturned)) == WBEM_S_NO_ERROR){
csObj = GetClassName(pObj);
iClasses = pStringArray->GetSize();
if(csObj.CompareNoCase(_T("CIM_ElementSetting")) != 0){
for(i = 0; i < iClasses; i++){
csClass = pStringArray->GetAt(i);
if(csObj.CompareNoCase(csClass) == 0){
bFound = true;
break;
}
}
}
pObj->Release();
pObj = NULL;
}
if(!bFound){
//we found nothing, so rather than just issue an error
//we should walk up the inheritence tree and see if we
// can find something that htis class might fall under.
if(!FindParentAssociation(_T("CIM_ElementSetting"), pStringArray)){
g_ReportLog.LogEntry(EC_INVALID_SETTING_USAGE, &m_csPath);
}
}
pEnum->Release();
}
}
SysFreeString(bstrDerivation);
VariantClear(&vDer);
ReleaseErrorObject(pErrorObject);
return hr;
}
HRESULT CClass::W2K_ValidStatisticsUsage(CStringArray *pStringArray)
{
HRESULT hr = WBEM_S_NO_ERROR;
IWbemClassObject *pErrorObject = NULL;
if(IsAbstract())
return hr;
//check the classes derivation
//get derivation
BSTR bstrDerivation = SysAllocString(L"__DERIVATION");
VARIANT vDer;
VariantInit(&vDer);
if(FAILED(hr = m_pClass->Get(bstrDerivation, 0, &vDer, NULL, NULL))){
CString csUserMsg = _T("Cannot get ") + m_csName + _T(" derivation");
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
SysFreeString(bstrDerivation);
ReleaseErrorObject(pErrorObject);
}else{
SysFreeString(bstrDerivation);
BSTR HUGEP *pbstr;
long ix[2] = {0,0};
long lLower, lUpper;
bool bFound = false;
int iDim = SafeArrayGetDim(vDer.parray);
HRESULT hr = SafeArrayGetLBound(vDer.parray, 1, &lLower);
hr = SafeArrayGetUBound(vDer.parray, 1, &lUpper);
hr = SafeArrayAccessData(vDer.parray, (void HUGEP* FAR*)&pbstr);
CString csDer;
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++){
csDer = pbstr[ix[0]];
if(csDer.CompareNoCase(_T("CIM_StatisticalInformation")) == 0){
bFound = true;
break;
}
}
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++)
SysFreeString(pbstr[ix[0]]);
VariantClear(&vDer);
if(bFound){
bFound = false;
CString csQuery = _T("references of {") + m_csName +
_T("} where resultclass=CIM_Statistics schemaonly");
BSTR bstrQuery = csQuery.AllocSysString();
BSTR bstrWQL = SysAllocString(L"WQL");
IEnumWbemClassObject *pEnum = NULL;
if(FAILED(hr = m_pNamespace->ExecQuery(bstrWQL, bstrQuery, 0, NULL, &pEnum))){
CString csUserMsg = _T("Cannot execute references query for ") + m_csName;
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
SysFreeString(bstrWQL);
SysFreeString(bstrQuery);
return hr;
}
SysFreeString(bstrWQL);
SysFreeString(bstrQuery);
IWbemClassObject *pObj = NULL;
ULONG uReturned;
CString csObj;
int iClasses, i;
CString csClass;
//check for classes derived from the superclass
// if there are cim or win32 classes log error
while((hr = pEnum->Next(INFINITE, 1, &pObj, &uReturned)) == WBEM_S_NO_ERROR){
CString csObj = GetClassName(pObj);
iClasses = pStringArray->GetSize();
if(csObj.CompareNoCase(_T("CIM_Statistics")) != 0){
for(i = 0; i < iClasses; i++){
csClass = pStringArray->GetAt(i);
if(csObj.CompareNoCase(csClass) == 0){
bFound = true;
break;
}
}
}
pObj->Release();
pObj = NULL;
}
if(!bFound) g_ReportLog.LogEntry(EC_INVALID_STATISTICS_USAGE, &m_csPath);
pEnum->Release();
}
}
SysFreeString(bstrDerivation);
VariantClear(&vDer);
ReleaseErrorObject(pErrorObject);
return hr;
}
HRESULT CClass::W2K_ValidLogicalDeviceDerivation()
{
HRESULT hr = WBEM_S_NO_ERROR;
IWbemClassObject *pErrorObject = NULL;
CString csClassSchema = GetClassSchema();
int i, iSize;
bool bHaveSchema = false;
if(csClassSchema.GetLength() > 0){
//we have special rules for win32 classes... they
// can do things that others can't (like derive however
//they want from LogicalDevice)
if(csClassSchema.CompareNoCase(_T("Win32")) == 0)
return hr;
}
CString csSuperClass = GetSuperClassName(m_pClass);
if(csSuperClass.CompareNoCase(_T("CIM_LogicalDevice")) == 0){
g_ReportLog.LogEntry(EC_INVALID_LOGICALDEVICE_DERIVATION, &m_csPath);
return WBEM_S_NO_ERROR;
}
if(csSuperClass.GetLength() < 1)
return hr;
//check the classes derivation
//get derivation
BSTR bstrDerivation = SysAllocString(L"__DERIVATION");
VARIANT vDer;
VariantInit(&vDer);
if(FAILED(hr = m_pClass->Get(bstrDerivation, 0, &vDer, NULL, NULL))){
CString csUserMsg = _T("Cannot get ") + m_csName + _T(" derivation");
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
SysFreeString(bstrDerivation);
ReleaseErrorObject(pErrorObject);
}else{
SysFreeString(bstrDerivation);
BSTR HUGEP *pbstr;
long ix[2] = {0,0};
long lLower, lUpper;
bool bFound = false;
int iDim = SafeArrayGetDim(vDer.parray);
HRESULT hr = SafeArrayGetLBound(vDer.parray, 1, &lLower);
hr = SafeArrayGetUBound(vDer.parray, 1, &lUpper);
hr = SafeArrayAccessData(vDer.parray, (void HUGEP* FAR*)&pbstr);
CString csDer;
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++){
csDer = pbstr[ix[0]];
if(csDer.CompareNoCase(_T("CIM_LogicalDevice")) == 0){
bFound = true;
break;
}
}
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++)
SysFreeString(pbstr[ix[0]]);
VariantClear(&vDer);
if(bFound){
//get the subclasses of the superclass
CString csQuery = _T("select * from meta_class where __SUPERCLASS=\"") + csSuperClass + _T("\"");
BSTR bstrQuery = csQuery.AllocSysString();
BSTR bstrWQL = SysAllocString(L"WQL");
IEnumWbemClassObject *pEnum = NULL;
if(FAILED(hr = m_pNamespace->ExecQuery(bstrWQL, bstrQuery, 0, NULL, &pEnum))){
CString csUserMsg = _T("Cannot get ") + csSuperClass;
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
SysFreeString(bstrWQL);
SysFreeString(bstrQuery);
return hr;
}
SysFreeString(bstrWQL);
SysFreeString(bstrQuery);
IWbemClassObject *pObj = NULL;
ULONG uReturned;
CString csSchema;
//check for classes derived from the superclass
// if there are cim or win32 classes log error
while((hr = pEnum->Next(INFINITE, 1, &pObj, &uReturned)) == WBEM_S_NO_ERROR){
csSchema = GetClassName(pObj);
i = 0;
bHaveSchema = false;
iSize = csSchema.GetLength();
//check for system classes
if((iSize > 0) && (csSchema.Mid(0, 1) != L'_')){
for(i = 0; i < iSize; i++){
if(csSchema.Mid(i, 1) == L'_'){
bHaveSchema = true;
break;
}
}
if(bHaveSchema){
csSchema = csSchema.Left(i);
if(csSchema.CompareNoCase(_T("CIM")) == 0){
g_ReportLog.LogEntry(EC_INVALID_LOGICALDEVICE_DERIVATION, &m_csPath);
break;
}else if(csSchema.CompareNoCase(_T("Win32")) == 0){
g_ReportLog.LogEntry(EC_INVALID_LOGICALDEVICE_DERIVATION, &m_csPath);
break;
}else{
//this derivation is fine... do nothing
}
}
}
pObj->Release();
pObj = NULL;
}
pEnum->Release();
}
}
ReleaseErrorObject(pErrorObject);
return hr;
}
HRESULT CClass::W2K_ValidSettingDeviceUsage(CStringArray *pStringArray)
{
HRESULT hr = WBEM_S_NO_ERROR;
if(IsAbstract())
return hr;
IWbemClassObject *pErrorObject = NULL;
//check the classes derivation
//get derivation
BSTR bstrDerivation = SysAllocString(L"__DERIVATION");
VARIANT vDer;
VariantInit(&vDer);
if(FAILED(hr = m_pClass->Get(bstrDerivation, 0, &vDer, NULL, NULL))){
CString csUserMsg = _T("Cannot get ") + m_csName + _T(" derivation");
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
SysFreeString(bstrDerivation);
ReleaseErrorObject(pErrorObject);
}else{
SysFreeString(bstrDerivation);
BSTR HUGEP *pbstr;
long ix[2] = {0,0};
long lLower, lUpper;
bool bFound = false;
int iDim = SafeArrayGetDim(vDer.parray);
HRESULT hr = SafeArrayGetLBound(vDer.parray, 1, &lLower);
hr = SafeArrayGetUBound(vDer.parray, 1, &lUpper);
hr = SafeArrayAccessData(vDer.parray, (void HUGEP* FAR*)&pbstr);
CString csDer;
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++){
csDer = pbstr[ix[0]];
if(csDer.CompareNoCase(_T("CIM_Setting")) == 0){
bFound = true;
break;
}
}
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++)
SysFreeString(pbstr[ix[0]]);
VariantClear(&vDer);
if(bFound){
bFound = false;
CString csQuery = _T("references of {") + m_csName +
_T("} where resultclass=CIM_ElementSetting schemaonly");
BSTR bstrQuery = csQuery.AllocSysString();
BSTR bstrWQL = SysAllocString(L"WQL");
IEnumWbemClassObject *pEnum = NULL;
if(FAILED(hr = m_pNamespace->ExecQuery(bstrWQL, bstrQuery, 0, NULL, &pEnum))){
CString csUserMsg = _T("Cannot execute references query for ") + m_csName;
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
SysFreeString(bstrWQL);
SysFreeString(bstrQuery);
return hr;
}
SysFreeString(bstrWQL);
SysFreeString(bstrQuery);
IWbemClassObject *pObj = NULL;
ULONG uReturned;
CString csObj;
int iClasses, i;
CString csClass;
//check for classes derived from the superclass
// if there are cim or win32 classes log error
while((hr = pEnum->Next(INFINITE, 1, &pObj, &uReturned)) == WBEM_S_NO_ERROR){
csObj = GetClassName(pObj);
iClasses = pStringArray->GetSize();
if(csObj.CompareNoCase(_T("CIM_ElementSetting")) != 0){
for(i = 0; i < iClasses; i++){
csClass = pStringArray->GetAt(i);
if(csObj.CompareNoCase(csClass) == 0){
bFound = true;
break;
}
}
if(bFound) break;
}
pObj->Release();
pObj = NULL;
}
if(!bFound){
//we found nothing, so rather than just issue an error
//we should walk up the inheritence tree and see if we
// can find something that htis class might fall under.
if(!FindParentAssociation(_T("CIM_ElementSetting"), pStringArray)){
g_ReportLog.LogEntry(EC_INVALID_SETTING_DEVICE_USAGE, &m_csPath);
}
}
pEnum->Release();
}
}
SysFreeString(bstrDerivation);
VariantClear(&vDer);
ReleaseErrorObject(pErrorObject);
return hr;
}
bool CClass::FindParentAssociation(CString csAssociation, CStringArray *pStringArray)
{
bool bRetVal = false;
HRESULT hr = WBEM_S_NO_ERROR;
IWbemClassObject *pErrorObject = NULL;
//check the classes derivation
//get derivation
BSTR bstrDerivation = SysAllocString(L"__DERIVATION");
VARIANT vDer;
VariantInit(&vDer);
if(FAILED(hr = m_pClass->Get(bstrDerivation, 0, &vDer, NULL, NULL))){
CString csUserMsg = _T("Cannot get ") + m_csName + _T(" derivation");
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
SysFreeString(bstrDerivation);
ReleaseErrorObject(pErrorObject);
}else{
SysFreeString(bstrDerivation);
BSTR HUGEP *pbstr;
long ix[2] = {0,0};
long lLower, lUpper;
bool bFound = false;
int iDim = SafeArrayGetDim(vDer.parray);
HRESULT hr = SafeArrayGetLBound(vDer.parray, 1, &lLower);
hr = SafeArrayGetUBound(vDer.parray, 1, &lUpper);
hr = SafeArrayAccessData(vDer.parray, (void HUGEP* FAR*)&pbstr);
CString csDer;
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++){
bFound = false;
csDer = pbstr[ix[0]];
CString csQuery = _T("references of {") + csDer +
_T("} where resultclass=") + csAssociation + (" schemaonly");
BSTR bstrQuery = csQuery.AllocSysString();
BSTR bstrWQL = SysAllocString(L"WQL");
IEnumWbemClassObject *pEnum = NULL;
if(FAILED(hr = m_pNamespace->ExecQuery(bstrWQL, bstrQuery, 0, NULL, &pEnum))){
CString csUserMsg = _T("Cannot execute references query for ") + m_csName;
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
SysFreeString(bstrWQL);
SysFreeString(bstrQuery);
return (hr != 0);
}
SysFreeString(bstrWQL);
SysFreeString(bstrQuery);
IWbemClassObject *pObj = NULL;
ULONG uReturned;
CString csObj;
int iClasses, i;
CString csClass;
//check for classes derived from the superclass
// if there are cim or win32 classes log error
while((hr = pEnum->Next(INFINITE, 1, &pObj, &uReturned)) == WBEM_S_NO_ERROR){
csObj = GetClassName(pObj);
iClasses = pStringArray->GetSize();
if(csObj.CompareNoCase(_T("CIM_ElementSetting")) != 0){
for(i = 0; i < iClasses; i++){
csClass = pStringArray->GetAt(i);
if(csObj.CompareNoCase(csClass) == 0){
bFound = true;
bRetVal = true;
break;
}
}
if(bFound) break;
}
pObj->Release();
pObj = NULL;
}
if(bFound) break;
pEnum->Release();
}
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++)
SysFreeString(pbstr[ix[0]]);
VariantClear(&vDer);
}
SysFreeString(bstrDerivation);
ReleaseErrorObject(pErrorObject);
return bRetVal;
}
HRESULT CClass::W2K_ValidComputerSystemDerivation()
{
HRESULT hr = WBEM_S_NO_ERROR;
//get the subclasses of the superclass
CString csSuperClass = GetSuperClassName(m_pClass);
CString csClass = GetClassName(m_pClass);
if(((csSuperClass.CompareNoCase(_T("CIM_UnitaryComputerSystem")) == 0) ||
(csSuperClass.CompareNoCase(_T("CIM_ComputerSystem")) == 0)) &&
(csClass.CompareNoCase(_T("Win32_ComputerSystem")) != 0))
g_ReportLog.LogEntry(EC_INVALID_COMPUTERSYSTEM_DERIVATION, &m_csPath);
return hr;
}
HRESULT CClass::Local_ValidLocale()
{
HRESULT hr = WBEM_S_NO_ERROR;
VARIANT v;
LONG lType;
BSTR bstrLocale = SysAllocString(L"Locale");
VariantInit(&v);
if(FAILED(hr = m_pQualSet->Get(bstrLocale, 0, &v, &lType)))
g_ReportLog.LogEntry(EC_INAPPROPRIATE_LOCALE_QUALIFIER, &m_csPath);
else{
CString csLocale = bstrLocale;
CQualifier *pQual = new CQualifier(&csLocale, &v, lType, &m_csPath);
//check to see if the locale is valid
ValidLocale(pQual);
pQual->CleanUp();
delete pQual;
VariantClear(&v);
}
SysFreeString(bstrLocale);
return hr;
}
HRESULT CClass::Local_ValidAmendedLocalClass()
{
HRESULT hr = WBEM_S_NO_ERROR;
BSTR bstrAmendment = SysAllocString(L"Amendment");
if(FAILED(hr = m_pQualSet->Get(bstrAmendment, 0, NULL, NULL)))
g_ReportLog.LogEntry(EC_UNAMENDED_LOCALIZED_CLASS, &m_csPath);
SysFreeString(bstrAmendment);
return hr;
}
HRESULT CClass::Local_ValidAbstractLocalClass()
{
HRESULT hr = WBEM_S_NO_ERROR;
BSTR bstrAbstract = SysAllocString(L"Abstract");
if(FAILED(hr = m_pQualSet->Get(bstrAbstract, 0, NULL, NULL))){
// If there is no abstract qualifier check for an
//amendment qualifier which implies abstract
BSTR bstrAmendment = SysAllocString(L"Amendment");
if(FAILED(hr = m_pQualSet->Get(bstrAmendment, 0, NULL, NULL)))
g_ReportLog.LogEntry(EC_NONABSTRACT_LOCALIZED_CLASS, &m_csPath);
SysFreeString(bstrAmendment);
}
SysFreeString(bstrAbstract);
return hr;
}
CString CClass::GetClassSchema()
{
int i = 0;
CString csSchema = m_csName;
bool bHaveSchema = false;
int iSize = csSchema.GetLength();
//check for system classes
if((iSize > 0) && (csSchema[0] != L'_')){
for(i = 0; i < iSize; i++){
if(csSchema[i] == L'_'){
bHaveSchema = true;
break;
}
}
if(bHaveSchema){
csSchema = csSchema.Left(i);
return csSchema;
}
}
return _T("");
}
/////////////////////////////////////////////
// CREF
CREF::CREF(CString *csName, VARIANT *pVar, LONG lType, LONG lFlavor, CClass *pParent)
{
m_csName = *csName;
VariantInit(&m_vValue);
if(pVar)m_vValue = *pVar;
m_lType = lType;
m_lFlavor = lFlavor;
m_pParent = pParent;
m_pQualSet = NULL;
m_csPath = m_pParent->m_csPath + _T(".") + m_csName;
IWbemClassObject *pErrorObject = NULL;
HRESULT hr = WBEM_S_NO_ERROR;
BSTR bstrName = m_csName.AllocSysString();
if(FAILED(hr = m_pParent->m_pClass->GetPropertyQualifierSet(bstrName, &m_pQualSet))){
CString csUserMsg = _T("Cannot get ") + m_csPath + _T(" qualifier set");
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
}
SysFreeString(bstrName);
ReleaseErrorObject(pErrorObject);
}
CREF::~CREF()
{
}
void CREF::CleanUp()
{
if(m_pQualSet) m_pQualSet->Release();
m_csName.Empty();
VariantClear(&m_vValue);
}
CString CREF::GetName() { return m_csName; }
CString CREF::GetPath() { return m_csPath; }
VARIANT CREF::GetValue() { return m_vValue; }
HRESULT CREF::ValidReferenceTarget()
{
HRESULT hr = WBEM_S_NO_ERROR;
VARIANT v;
VariantInit(&v);
BSTR bstrCIMTYPE = SysAllocString(L"CIMTYPE");
if(SUCCEEDED(hr = m_pQualSet->Get(bstrCIMTYPE, 0, &v, NULL))){
CString csREF = V_BSTR(&v);
csREF = csREF.Right(csREF.GetLength() - 4);
VariantClear(&v);
BSTR bstrClass = csREF.AllocSysString();
hr = m_pParent->m_pNamespace->GetObject(bstrClass, 0, NULL, NULL, NULL);
SysFreeString(bstrClass);
if(hr == WBEM_E_NOT_FOUND)
g_ReportLog.LogEntry(EC_INVALID_REF_TARGET, &m_csPath);
}
SysFreeString(bstrCIMTYPE);
return hr;
}
HRESULT CREF::VerifyRead()
{
HRESULT hr = WBEM_S_NO_ERROR;
BSTR bstrRead = SysAllocString(L"Read");
if((hr = m_pQualSet->Get(bstrRead, 0, NULL, NULL)) == WBEM_E_NOT_FOUND)
g_ReportLog.LogEntry(EC_PROPERTY_NOT_LABELED_READ, &m_csPath);
SysFreeString(bstrRead);
return hr;
}
HRESULT CREF::ValidREFOverrides()
{
HRESULT hr = WBEM_S_NO_ERROR;
VARIANT v, vSuperProp;
LONG lType;
BSTR bstrOverride = SysAllocString(L"Override");
IWbemClassObject *pErrorObject = NULL;
bool bRetVal = false;
VariantInit(&v);
if(SUCCEEDED(hr = m_pQualSet->Get(bstrOverride, 0, &v, NULL))){
BSTR bstrSuperClass = SysAllocString(L"__SUPERCLASS");
BSTR bstrProperty = V_BSTR(&v);
hr = m_pParent->m_pClass->Get(bstrSuperClass, 0, &v, &lType, NULL);
if(V_VT(&v) == VT_BSTR){
IWbemClassObject *pSuperClass = NULL;
VariantInit(&vSuperProp);
hr = m_pParent->m_pNamespace->GetObject(V_BSTR(&v), 0, NULL, &pSuperClass, NULL);
hr = pSuperClass->Get(bstrProperty, 0, &vSuperProp, &lType, NULL);
// if(lType != m_lType) g_ReportLog.LogEntry(EC_INVALID_REF_OVERRIDES, &m_csPath);
VariantClear(&v);
BSTR bstrCIMTYPE = SysAllocString(L"CIMTYPE");
if(FAILED(hr = m_pQualSet->Get(bstrCIMTYPE, 0, &v, NULL))){
CString csUserMsg = _T("Cannot get ") + m_csPath + _T(" qualifier set");
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
SysFreeString(bstrSuperClass);
SysFreeString(bstrProperty);
VariantClear(&v);
SysFreeString(bstrOverride);
pSuperClass->Release();
return hr;
}
CString csREF = V_BSTR(&v);
//cut the "ref:" part of string
csREF = csREF.Right(csREF.GetLength() - 4);
IWbemQualifierSet *pQualSet = NULL;
if(FAILED(hr = pSuperClass->GetPropertyQualifierSet(bstrProperty, &pQualSet))){
// CString csSuperclass = bstrProperty;
// CString csUserMsg = _T("Cannot get ") + csSuperclass + _T(" qualifier set");
// ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
SysFreeString(bstrSuperClass);
SysFreeString(bstrProperty);
VariantClear(&v);
SysFreeString(bstrOverride);
pSuperClass->Release();
return hr;
}
VariantClear(&v);
if(FAILED(hr = pQualSet->Get(bstrCIMTYPE, 0, &v, NULL))){
CString csUserMsg = _T("Cannot get ") + m_csPath + _T(" qualifier set");
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
SysFreeString(bstrSuperClass);
SysFreeString(bstrProperty);
VariantClear(&v);
SysFreeString(bstrOverride);
pSuperClass->Release();
pQualSet->Release();
return hr;
}
CString csSuperREF = V_BSTR(&v);
//cut the "ref:" part of string
csSuperREF = csSuperREF.Right(csSuperREF.GetLength() - 4);
BSTR bstrClass = SysAllocString(csREF);
IWbemClassObject *pClass = NULL;
if(SUCCEEDED(hr = m_pParent->m_pNamespace->GetObject(bstrClass, 0, NULL, &pClass, NULL))){
//get derivation
BSTR bstrDerivation = SysAllocString(L"__DERIVATION");
VARIANT vDer;
VariantInit(&vDer);
if(FAILED(hr = pClass->Get(bstrDerivation, 0, &vDer, NULL, NULL))){
CString csUserMsg = _T("Cannot get ") + csREF + _T(" derivation");
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
}else{
BSTR HUGEP *pbstr;
long ix[2] = {0,0};
long lLower, lUpper;
int iDim = SafeArrayGetDim(vDer.parray);
HRESULT hr = SafeArrayGetLBound(vDer.parray, 1, &lLower);
hr = SafeArrayGetUBound(vDer.parray, 1, &lUpper);
hr = SafeArrayAccessData(vDer.parray, (void HUGEP* FAR*)&pbstr);
CString csDerClass;
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++){
csDerClass = pbstr[ix[0]];
if(csSuperREF.CompareNoCase(csDerClass) == 0){
bRetVal = true;
break;
}
}
if(!bRetVal) g_ReportLog.LogEntry(EC_INVALID_REF_OVERRIDES, &m_csPath);
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++) SysFreeString(pbstr[ix[0]]);
}
SysFreeString(bstrDerivation);
pClass->Release();
}
SysFreeString(bstrClass);
VariantClear(&vSuperProp);
pSuperClass->Release();
SysFreeString(bstrCIMTYPE);
}
SysFreeString(bstrSuperClass);
SysFreeString(bstrProperty);
VariantClear(&v);
}
SysFreeString(bstrOverride);
ReleaseErrorObject(pErrorObject);
return hr;
}
HRESULT CREF::ValidMaxLen()
{
HRESULT hr = WBEM_S_NO_ERROR;
VARIANT v;
VariantInit(&v);
BSTR bstrKey = SysAllocString(L"Key");
if(SUCCEEDED(hr = m_pQualSet->Get(bstrKey, 0, &v, NULL))){
//if this is a string type property that is a key...
if((m_lType == CIM_STRING) && (V_BOOL(&v) == VARIANT_TRUE)){
BSTR bstrMaxLen = SysAllocString(L"MaxLen");
//if there is no MaxLen qualifier then it's an error
if((hr = m_pQualSet->Get(bstrMaxLen, 0, NULL, NULL)) == WBEM_E_NOT_FOUND)
g_ReportLog.LogEntry(EC_INVALID_PROPERTY_MAXLEN, &m_csPath);
SysFreeString(bstrMaxLen);
}
VariantClear(&v);
}else if(hr == WBEM_E_NOT_FOUND){
//if the key qualifier wasn't found it's not an error
hr = S_OK;
}
SysFreeString(bstrKey);
return hr;
}
/////////////////////////////////////////////
// CProperty
CProperty::CProperty(CString *csName, VARIANT *pVar, LONG lType, LONG lFlavor, CClass *pParent)
{
m_csName = *csName;
VariantInit(&m_vValue);
if(pVar)m_vValue = *pVar;
m_lType = lType;
m_lFlavor = lFlavor;
m_pParent = pParent;
m_csPath = m_pParent->m_csPath + _T(".") + m_csName;
IWbemClassObject *pErrorObject = NULL;
HRESULT hr = WBEM_S_NO_ERROR;
BSTR bstrName = m_csName.AllocSysString();
if(FAILED(hr = m_pParent->m_pClass->GetPropertyQualifierSet(bstrName, &m_pQualSet))){
CString csUserMsg = _T("Cannot get ") + m_csPath + _T(" qualifier set");
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
}
SysFreeString(bstrName);
ReleaseErrorObject(pErrorObject);
}
CProperty::~CProperty()
{
}
void CProperty::CleanUp()
{
if(m_pQualSet) m_pQualSet->Release();
m_csName.Empty();
VariantClear(&m_vValue);
}
CString CProperty::GetName() { return m_csName; }
CString CProperty::GetPath() { return m_csPath; }
VARIANT CProperty::GetValue() { return m_vValue; }
HRESULT CProperty::ValidPropOverrides()
{
HRESULT hr = WBEM_S_NO_ERROR;
VARIANT v;
LONG lType;
BSTR bstrOverride = SysAllocString(L"Override");
IWbemClassObject *pErrorObject = NULL;
VariantInit(&v);
if(SUCCEEDED(hr = m_pQualSet->Get(bstrOverride, 0, &v, NULL))){
BSTR bstrSuperClass = SysAllocString(L"__SUPERCLASS");
BSTR bstrProperty = V_BSTR(&v);
hr = m_pParent->m_pClass->Get(bstrSuperClass, 0, &v, &lType, NULL);
if(V_VT(&v) == VT_BSTR){
IWbemClassObject *pSuperClass = NULL;
hr = m_pParent->m_pNamespace->GetObject(V_BSTR(&v), 0, NULL, &pSuperClass, NULL);
hr = pSuperClass->Get(bstrProperty, 0, NULL, &lType, NULL);
pSuperClass->Release();
if(lType != m_lType) g_ReportLog.LogEntry(EC_INVALID_PROPERTY_OVERRIDE, &m_csPath);
}
SysFreeString(bstrSuperClass);
SysFreeString(bstrProperty);
VariantClear(&v);
}
SysFreeString(bstrOverride);
ReleaseErrorObject(pErrorObject);
return hr;
}
HRESULT CProperty::ValidMaxLen()
{
HRESULT hr = WBEM_S_NO_ERROR;
VARIANT v;
VariantInit(&v);
BSTR bstrKey = SysAllocString(L"Key");
if(SUCCEEDED(hr = m_pQualSet->Get(bstrKey, 0, &v, NULL))){
//if this is a string type property that is a key...
if((m_lType == CIM_STRING) && (V_BOOL(&v) == VARIANT_TRUE)){
BSTR bstrMaxLen = SysAllocString(L"MaxLen");
//if there is no MaxLen qualifier then it's an error
if((hr = m_pQualSet->Get(bstrMaxLen, 0, NULL, NULL)) == WBEM_E_NOT_FOUND)
g_ReportLog.LogEntry(EC_INVALID_PROPERTY_MAXLEN, &m_csPath);
SysFreeString(bstrMaxLen);
}
VariantClear(&v);
}else if(hr == WBEM_E_NOT_FOUND){
//if the key qualifier wasn't found it's not an error
hr = S_OK;
}
SysFreeString(bstrKey);
return hr;
}
HRESULT CProperty::VerifyRead()
{
HRESULT hr = WBEM_S_NO_ERROR;
BSTR bstrRead = SysAllocString(L"Read");
if((hr = m_pQualSet->Get(bstrRead, 0, NULL, NULL)) == WBEM_E_NOT_FOUND)
g_ReportLog.LogEntry(EC_PROPERTY_NOT_LABELED_READ, &m_csPath);
SysFreeString(bstrRead);
return hr;
}
HRESULT CProperty::ValueValueMapCheck()
{
HRESULT hr = WBEM_S_NO_ERROR;
VARIANT vMap, vVal;
int iValueCnt = 0;
int iValueMapCnt = 0;
bool bError = false;
VariantInit(&vVal);
VariantInit(&vMap);
BSTR bstrValue = SysAllocString(L"Values");
if(SUCCEEDED(hr = m_pQualSet->Get(bstrValue, 0, &vVal, NULL))){
if(!(V_VT(&vVal) & VT_ARRAY)){
g_ReportLog.LogEntry(EC_INVALID_PROPERTY_VALUE_QUALIFIER, &m_csPath);
bError = true;
}else{
//count number of items
iValueCnt = vVal.parray->rgsabound[0].cElements;
}
}
SysFreeString(bstrValue);
BSTR bstrValueMap = SysAllocString(L"ValueMap");
if(SUCCEEDED(hr = m_pQualSet->Get(bstrValueMap, 0, &vMap, NULL))){
if(!(V_VT(&vMap) & VT_ARRAY)){
g_ReportLog.LogEntry(EC_INVALID_PROPERTY_VALUEMAP_QUALIFIER, &m_csPath);
bError = true;
}else{
//count number of items
iValueMapCnt = vMap.parray->rgsabound[0].cElements;
//check if we start with 0... if so do some more exploring
long ix[2];
ix[1] = 0;
ix[0] = 0;
VARIANT v;
VariantInit(&v);
hr = SafeArrayGetElement(vMap.parray, ix, &v);
if(V_BSTR(&v) == L"0"){
WCHAR wcBuf[10];
bool bSequential = true;
for(int j = 1; j < iValueMapCnt; j ++){
ix[0] = j;
hr = SafeArrayGetElement(vMap.parray, ix, &v);
if(V_BSTR(&v) != _ltow(j, wcBuf, 10)){
bSequential = false;
break;
}
}
if(bSequential){
//we have sequential values starting at 0.... should not have
//ValueMap for this
g_ReportLog.LogEntry(EC_INVALID_PROPERTY_VALUEMAP_QUALIFIER, &m_csPath);
bError = true;
}
}
//check type against string
if(!(V_VT(&vMap) & VT_BSTR)){
g_ReportLog.LogEntry(EC_INVALID_PROPERTY_VALUEMAP_QUALIFIER, &m_csPath);
bError = true;
}
}
}else if(hr == WBEM_E_NOT_FOUND){
//we have value but no value map... required if the
// valuemap starts at 0 and goes up incrementally
iValueMapCnt = iValueCnt;
}
SysFreeString(bstrValueMap);
VariantClear(&vVal);
VariantClear(&vMap);
//compare item counts for value & valuemap
if(((iValueMapCnt != 0) && (iValueCnt != 0)) && (iValueMapCnt != iValueCnt) && !bError)
g_ReportLog.LogEntry(EC_INCONSITANT_VALUE_VALUEMAP_QUALIFIERS, &m_csPath);
return hr;
}
HRESULT CProperty::BitMapCheck()
{
HRESULT hr = WBEM_S_NO_ERROR;
VARIANT vMap, vVal;
int iValueCnt = 0;
int iValueMapCnt = 0;
bool bError = false;
VariantInit(&vVal);
VariantInit(&vMap);
BSTR bstrBitValue = SysAllocString(L"BitValues");
if(SUCCEEDED(hr = m_pQualSet->Get(bstrBitValue, 0, &vVal, NULL))){
if((V_VT(&vVal) & VT_ARRAY)){
//count number of items
iValueCnt = vVal.parray->rgsabound[0].cElements;
}
}
SysFreeString(bstrBitValue);
BSTR bstrBitMap = SysAllocString(L"BitMap");
if(SUCCEEDED(hr = m_pQualSet->Get(bstrBitMap, 0, &vMap, NULL))){
if(!(V_VT(&vMap) & VT_ARRAY)){
g_ReportLog.LogEntry(EC_INVALID_PROPERTY_BITMAP_QUALIFIER, &m_csPath);
bError = true;
}else{
//count number of items
iValueMapCnt = vMap.parray->rgsabound[0].cElements;
//check if we start with 0... if so do some more exploring
long ix[2];
ix[1] = 0;
ix[0] = 0;
VARIANT v;
VariantInit(&v);
hr = SafeArrayGetElement(vMap.parray, ix, &v);
if(V_BSTR(&v) == L"0"){
WCHAR wcBuf[10];
bool bSequential = true;
for(int j = 1; j < iValueMapCnt; j ++){
ix[0] = j;
hr = SafeArrayGetElement(vMap.parray, ix, &v);
if(V_BSTR(&v) != _ltow(j, wcBuf, 10)){
bSequential = false;
break;
}
}
if(bSequential){
//we have sequential values starting at 0.... should not have
//BitMap for this
g_ReportLog.LogEntry(EC_INVALID_PROPERTY_BITMAP_QUALIFIER, &m_csPath);
bError = true;
}
}
//check type against string
if(!(V_VT(&vMap) & VT_BSTR)){
g_ReportLog.LogEntry(EC_INVALID_PROPERTY_BITMAP_QUALIFIER, &m_csPath);
bError = true;
}
}
}else if(hr == WBEM_E_NOT_FOUND){
//we have value but no value map... required if the
// valuemap starts at 0 and goes up incrementally
iValueMapCnt = iValueCnt;
}
SysFreeString(bstrBitMap);
VariantClear(&vVal);
VariantClear(&vMap);
//compare item counts for value & valuemap
if(((iValueMapCnt != 0) && (iValueCnt != 0)) && (iValueMapCnt != iValueCnt) && !bError)
g_ReportLog.LogEntry(EC_INCONSITANT_BITVALUE_BITMAP_QUALIFIERS, &m_csPath);
return hr;
}
VARTYPE CProperty::GetVariantType()
{
VARTYPE vt = VT_NULL;
switch(m_lType) {
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;
}
return vt;
}
/*
HRESULT CProperty::Local_ValidProperty()
{
HRESULT hr = WBEM_S_NO_ERROR;
return hr;
}
*/
/////////////////////////////////////////////
// CMethod
CMethod::CMethod(CString *csName, IWbemClassObject *pIn, IWbemClassObject *pOut, CClass *pParent)
{
m_csName = *csName;
m_pInParams = pIn;
m_pOutParams = pOut;
m_pParent = pParent;
m_pQualSet = NULL;
m_csPath = m_pParent->m_csPath + _T(".") + m_csName;
BSTR bstrName = m_csName.AllocSysString();
HRESULT hr = WBEM_S_NO_ERROR;
IWbemClassObject *pErrorObject = NULL;
if(FAILED(hr = m_pParent->m_pClass->GetMethodQualifierSet(bstrName, &m_pQualSet))){
CString csUserMsg = _T("Cannot get ") + m_csPath + _T(" qualifier set");
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
}
SysFreeString(bstrName);
ReleaseErrorObject(pErrorObject);
}
CMethod::~CMethod()
{
}
void CMethod::CleanUp()
{
if(m_pQualSet) m_pQualSet->Release();
m_csName.Empty();
if(m_pInParams) m_pInParams->Release();
if(m_pOutParams) m_pOutParams->Release();
}
CString CMethod::GetName() { return m_csName; }
CString CMethod::GetPath() { return m_csPath; }
HRESULT CMethod::ValidMethodOverrides()
{
HRESULT hr = WBEM_S_NO_ERROR;
VARIANT v;
IWbemClassObject *pErrorObject = NULL;
VariantInit(&v);
BSTR bstrOverrides = SysAllocString(L"Overrides");
if(SUCCEEDED(hr = m_pQualSet->Get(bstrOverrides, 0, &v, NULL))){
BSTR bstrProperty = V_BSTR(&v);
BSTR bstrOrigin = NULL;
hr = m_pParent->m_pClass->GetMethodOrigin(bstrProperty, &bstrOrigin);
IWbemClassObject *pOriginClass = NULL;
IWbemClassObject *pIn = NULL;
IWbemClassObject *pOut = NULL;
// LONG lType;
hr = m_pParent->m_pNamespace->GetObject(bstrOrigin, 0, NULL, &pOriginClass, NULL);
hr = pOriginClass->GetMethod(bstrProperty, 0, &pIn, &pOut);
if((hr = m_pInParams->CompareTo(WBEM_FLAG_IGNORE_QUALIFIERS, pIn)) != WBEM_S_SAME)
g_ReportLog.LogEntry(EC_INVALID_METHOD_OVERRIDE, &m_csPath);
if((hr = m_pOutParams->CompareTo(WBEM_FLAG_IGNORE_QUALIFIERS, pOut)) != WBEM_S_SAME)
g_ReportLog.LogEntry(EC_INVALID_METHOD_OVERRIDE, &m_csPath);
pOriginClass->Release();
SysFreeString(bstrOrigin);
SysFreeString(bstrProperty);
}
VariantClear(&v);
ReleaseErrorObject(pErrorObject);
return hr;
}
/*
HRESULT CMethod::Local_ValidMethod()
{
HRESULT hr = WBEM_S_NO_ERROR;
return hr;
}
*/
/////////////////////////////////////////////
// CQualifier
CQualifier::CQualifier(CString *pcsName, VARIANT *pVar, LONG lType, CString *pcsParentPath)
{
m_csName = *pcsName;
VariantInit(&m_vValue);
if(pVar) m_vValue = *pVar;
m_lType = lType;
m_csPathNoQual = *pcsParentPath;
m_csPath = m_csPathNoQual + _T("[") + m_csName + _T("]");
}
CQualifier::~CQualifier()
{
}
void CQualifier::CleanUp()
{
// m_csPathNoQual.Empty();
// m_csName.Empty();
// m_csPath.Empty();
// VariantClear(&m_vValue);
}
CString CQualifier::GetName() { return m_csName; }
CString CQualifier::GetPath() { return m_csPath; }
CString CQualifier::GetPathNoQual() { return m_csPathNoQual; }
VARIANT CQualifier::GetValue() { return m_vValue; }
HRESULT CQualifier::ValidScope(SCOPE Scope)
{
HRESULT hr = WBEM_S_NO_ERROR;
switch(Scope){
case SCOPE_CLASS:
if(!IsClassQual(m_csName)){
if(IsCIMQual(m_csName)) g_ReportLog.LogEntry(EC_INVALID_QUALIFIER_SCOPE, &m_csPath);
else g_ReportLog.LogEntry(EC_NON_CIM_WMI_QUALIFIER, &m_csPath);
}
break;
case SCOPE_ASSOCIATION:
if((!IsAssocQual(m_csName)) && (!IsClassQual(m_csName))){
if(IsCIMQual(m_csName)) g_ReportLog.LogEntry(EC_INVALID_QUALIFIER_SCOPE, &m_csPath);
else g_ReportLog.LogEntry(EC_NON_CIM_WMI_QUALIFIER, &m_csPath);
}
break;
case SCOPE_INDICATION:
if(!IsIndicQual(m_csName)){
if(IsCIMQual(m_csName)) g_ReportLog.LogEntry(EC_INVALID_QUALIFIER_SCOPE, &m_csPath);
else g_ReportLog.LogEntry(EC_NON_CIM_WMI_QUALIFIER, &m_csPath);
}
break;
case SCOPE_PROPERTY:
if((!IsPropQual(m_csName)) && (!(V_VT(&m_vValue) & VT_ARRAY) || !IsArrayQual(m_csName))){
if(IsCIMQual(m_csName)) g_ReportLog.LogEntry(EC_INVALID_QUALIFIER_SCOPE, &m_csPath);
else g_ReportLog.LogEntry(EC_NON_CIM_WMI_QUALIFIER, &m_csPath);
}
break;
case SCOPE_METHOD:
if(!IsMethQual(m_csName)){
if(IsCIMQual(m_csName)) g_ReportLog.LogEntry(EC_INVALID_QUALIFIER_SCOPE, &m_csPath);
else g_ReportLog.LogEntry(EC_NON_CIM_WMI_QUALIFIER, &m_csPath);
}
break;
case SCOPE_METHOD_PARAM:
if(!IsParamQual(m_csName)){
if(IsCIMQual(m_csName)) g_ReportLog.LogEntry(EC_INVALID_QUALIFIER_SCOPE, &m_csPath);
else g_ReportLog.LogEntry(EC_NON_CIM_WMI_QUALIFIER, &m_csPath);
}
break;
case SCOPE_REF:
if((!IsRefQual(m_csName)) && (!IsPropQual(m_csName))){
if(IsCIMQual(m_csName)) g_ReportLog.LogEntry(EC_INVALID_QUALIFIER_SCOPE, &m_csPath);
else g_ReportLog.LogEntry(EC_NON_CIM_WMI_QUALIFIER, &m_csPath);
}
break;
case SCOPE_ARRAY:
if(!IsArrayQual(m_csName)){
if(IsCIMQual(m_csName)) g_ReportLog.LogEntry(EC_INVALID_QUALIFIER_SCOPE, &m_csPath);
else g_ReportLog.LogEntry(EC_NON_CIM_WMI_QUALIFIER, &m_csPath);
}
break;
}
return hr;
}
/////////////////////////////////////////////
// CReportLog
CReportLog::CReportLog()
{
m_pHead = new LogItem();
m_pHead->pNext = NULL;
m_pHead->csSource = _T("");
m_pHead->Code = EC_NO_ERROR;
m_pInsertPoint = m_pHead;
m_iEntryCount = 0;
}
CReportLog::~CReportLog()
{
}
HRESULT CReportLog::LogEntry(ERRORCODE eError, CString *pcsSource)
{
m_pInsertPoint->pNext = new LogItem();
m_pInsertPoint = m_pInsertPoint->pNext;
m_pInsertPoint->pNext = NULL;
m_pInsertPoint->csSource = *pcsSource;
m_pInsertPoint->Code = eError;
m_iEntryCount++;
return S_OK;
}
bool CReportLog::DeleteAll()
{
try{
LogItem *pThis = m_pHead->pNext;
m_pHead->pNext = NULL;
LogItem *pNext;
while(pThis){
pNext = pThis->pNext;
delete pThis;
pThis = pNext;
}
m_pInsertPoint = m_pHead;
m_iEntryCount = 0;
}catch(...){
return false;
}
return true;
}
HRESULT CReportLog::DisplayReport(CListCtrl *pList)
{
LogItem *pPos = m_pHead->pNext;
for(int i = 0; i < m_iEntryCount; i++){
if(pPos){
pList->InsertItem(i, GetErrorType(pPos->Code));
pList->SetItem(i, 1, LVIF_TEXT, GetErrorString(pPos->Code), NULL, NULL, NULL, NULL);
pList->SetItem(i, 2, LVIF_TEXT, pPos->csSource, NULL, NULL, NULL, NULL);
pList->SetItem(i, 3, LVIF_TEXT, GetErrorDescription(pPos->Code), NULL, NULL, NULL, NULL);
pList->SetItemData(i, i);
//set the items position in the list for sorting purposes
pPos = pPos->pNext;
}
}
return S_OK;
}
LogItem * CReportLog::GetItem(__int64 iPos)
{
if(iPos > m_iEntryCount) return NULL;
LogItem *pPos = m_pHead->pNext;
for(__int64 i = 0; i < iPos; i++)
pPos = pPos->pNext;
return pPos;
}
HRESULT CReportLog::ReportToFile(int iSubGraphs, int iRootObjects, CString *pcsSchema)
{
HRESULT hr = WBEM_S_NO_ERROR;
FILE *pOutputFile;
static WCHAR BASED_CODE szFilter[] = L"Log Files (*.log)|*.log|Text Files (*.txt)|*.txt|All Files (*.*)|*.*||";
CFileDialog *pDlg;
if(pcsSchema){
CString csSchema = *pcsSchema;
pDlg = new CFileDialog(FALSE, _T("log"), csSchema,
OFN_LONGNAMES | OFN_OVERWRITEPROMPT, szFilter, NULL);
}else{
pDlg = new CFileDialog(FALSE, _T("log"), NULL,
OFN_LONGNAMES | OFN_OVERWRITEPROMPT, szFilter, NULL);
}
int iRes = pDlg->DoModal();
if(iRes == IDOK){
//handle success
CString csFile = pDlg->GetPathName();
pOutputFile = _tfopen(csFile, _T("w"));
if(pOutputFile == NULL){
CString csUserMsg = _T("Cannot open file ") + csFile;
ErrorMsg(&csUserMsg, hr, NULL, TRUE, &csUserMsg, __FILE__, __LINE__);
return WBEM_E_FAILED;
}
LogItem *pPos = m_pHead->pNext;
_ftprintf(pOutputFile, _T("Type\tMessage\tSource\tDescription\n"));
_ftprintf(pOutputFile, _T("----\t-------\t------\t-----------\n\n"));
for(int i = 0; i < m_iEntryCount; i++){
if(pPos){
_ftprintf(pOutputFile, _T("%s\t%s\t%s\t%s\n"), GetErrorType(pPos->Code),
GetErrorString(pPos->Code), pPos->csSource, GetErrorDescription(pPos->Code));
pPos = pPos->pNext;
}
}
_ftprintf(pOutputFile, _T("\n"));
_ftprintf(pOutputFile, _T("SubGraphs\t%d\n"), iSubGraphs);
_ftprintf(pOutputFile, _T("Root Objects\t%d\n"), iRootObjects);
fclose(pOutputFile);
}else{
//handle the error
DWORD dwError = CommDlgExtendedError();
switch(dwError){
// case CDERR_DIALOGFAILURE:
// case CDERR_FINDRESFAILURE:
// case CDERR_INITIALIZATION:
// case CDERR_LOADRESFAILURE:
// case CDERR_LOADSTRFAILURE:
// case CDERR_LOCKRESFAILURE:
// case CDERR_MEMALLOCFAILURE:
// case CDERR_MEMLOCKFAILURE:
// case CDERR_NOHINSTANCE:
// case CDERR_NOHOOK:
// case CDERR_NOTEMPLATE:
// case CDERR_REGISTERMSGFAIL:
// case CDERR_STRUCTSIZE:
// CString csUserMsg = _T("An error occurred\n\nUnable to save to file");
// ErrorMsg(&csUserMsg, hr, NULL, TRUE, &csUserMsg, __FILE__, __LINE__);
// break;
case 0:
//no error, do nothing
break;
default:
CString csUserMsg = _T("An error occurred\n\nUnable to save to file");
ErrorMsg(&csUserMsg, hr, NULL, TRUE, &csUserMsg, __FILE__, __LINE__);
break;
break;
}
}
delete pDlg;
return hr;
}
CString CReportLog::GetErrorType(ERRORCODE eError)
{
CString csType;
if(eError < 0) csType = _T("Warning");
else csType = _T("Error");
return csType;
}
CString CReportLog::GetErrorString(ERRORCODE eError)
{
CString csError;
switch(eError){
//class errors
case EC_INVALID_CLASS_NAME:
csError = _T("Invalid Class Name");
break;
case EC_INADAQUATE_DESCRIPTION:
csError = _T("Inadequate Description");
break;
case EC_INVALID_CLASS_TYPE:
csError = _T("Invalid Class Type");
break;
case EC_INVALID_CLASS_UUID:
csError = _T("Invalid Class UUID");
break;
case EC_INVALID_CLASS_LOCALE:
csError = _T("Invalid Class Locale");
break;
case EC_INVALID_MAPPINGSTRINGS:
csError = _T("Invalid MappingStrings");
break;
//assoc/ref errors
case EC_INVALID_REF_TARGET:
csError = _T("Invalid REF Target");
break;
case EC_REF_NOT_LABELED_READ:
csError = _T("REF Not Labeled Read");
break;
case EC_INCOMPLETE_ASSOCIATION:
csError = _T("Incomplete Association");
break;
case EC_REF_ON_NONASSOCIATION_CLASS:
csError = _T("REF on Non-Association Class");
break;
case EC_INVALID_REF_OVERRIDES:
csError = _T("Invalid REF Override");
break;
case EC_INVALID_ASSOCIATION_INHERITANCE:
csError = _T("Invalid Association Inheritance");
break;
//proeprty errors
case EC_INVALID_PROPERTY_OVERRIDE:
csError = _T("Invalid Property Override");
break;
case EC_INVALID_PROPERTY_MAXLEN:
csError = _T("Invalid Property MaxLen Qualifier");
break;
case EC_PROPERTY_NOT_LABELED_READ:
csError = _T("Property Not Labeled Read");
break;
case EC_INVALID_PROPERTY_VALUE_QUALIFIER:
csError = _T("Invalid Property Value Qualifier");
break;
case EC_INVALID_PROPERTY_VALUEMAP_QUALIFIER:
csError = _T("Invalid Property ValueMap Qualifier");
break;
case EC_INCONSITANT_VALUE_VALUEMAP_QUALIFIERS:
csError = _T("Inconsistant Values/ValueMap Qualifiers");
break;
case EC_INVALID_PROPERTY_BITMAP_QUALIFIER:
csError = _T("Invalid Property BitMap Qualifier");
break;
case EC_INCONSITANT_BITVALUE_BITMAP_QUALIFIERS:
csError = _T("Inconsistant BitValues/BitMap Qualifiers");
break;
//method errors
case EC_INVALID_METHOD_OVERRIDE:
csError = _T("Invalid Method Override");
break;
//qualifier errors
case EC_INVALID_QUALIFIER_SCOPE:
csError = _T("Invalid Qualifier Scope");
break;
case EC_NON_CIM_WMI_QUALIFIER:
csError = _T("Found Non-CIM/WMI Qualifier");
break;
//overall checks
case EC_REDUNDANT_ASSOCIATION:
csError = _T("Redundant Association");
break;
//w2k errors
case EC_INVALID_CLASS_DERIVATION:
csError = _T("Invalid Class Derivation");
break;
case EC_INVALID_PHYSICALELEMENT_DERIVATION:
csError = _T("Invalid Physicalelement Derivation");
break;
case EC_INVALID_SETTING_USAGE:
csError = _T("Invalid Setting Usage");
break;
case EC_INVALID_STATISTICS_USAGE:
csError = _T("Invalid Statistics Usage");
break;
case EC_INVALID_LOGICALDEVICE_DERIVATION:
csError = _T("Invalid LogicalDevice Derivation");
break;
case EC_INVALID_SETTING_DEVICE_USAGE:
csError = _T("Invalid Setting-Device Usage");
break;
case EC_INVALID_COMPUTERSYSTEM_DERIVATION:
csError = _T("Invalid ComputerSystem Derivation");
break;
//localization errors
case EC_INCONSITANT_LOCALIZED_SCHEMA:
csError = _T("Inconsistant Localized Schema");
break;
case EC_INVALID_LOCALIZED_CLASS:
csError = _T("Invalid Localized Class");
break;
case EC_UNAMENDED_LOCALIZED_CLASS:
csError = _T("Unamended Localized Class");
break;
case EC_NONABSTRACT_LOCALIZED_CLASS:
csError = _T("Non-Abstract Localized Class");
break;
case EC_INVALID_LOCALIZED_PROPERTY:
csError = _T("Invalid Localized Property");
break;
case EC_INVALID_LOCALIZED_METHOD:
csError = _T("Invalid Localized Method");
break;
case EC_INAPPROPRIATE_LOCALE_QUALIFIER:
csError = _T("Inappropriate Locale Qualifier");
break;
case EC_INVALID_LOCALE_NAMESPACE:
csError = _T("Invalid Localized Namespace Name");
break;
default:
csError = _T("Unknown Error");
break;
}
return csError;
}
CString CReportLog::GetErrorDescription(ERRORCODE eError)
{
CString csError;
switch(eError){
//class errors
case EC_INVALID_CLASS_NAME:
csError = _T("The name of this class does not meet the CIM/WMI requirements for a valid class name.");
break;
case EC_INADAQUATE_DESCRIPTION:
csError = _T("The description provided may not provide a sufficient level of information about the object in question. This description should be evaluated.");
break;
case EC_INVALID_CLASS_TYPE:
csError = _T("A class must be either dynamic, abstract or static. Dynamic classes must have a provider.");
break;
case EC_INVALID_CLASS_UUID:
csError = _T("The UUID qualifier is either missing or is not in a valid format.");
break;
case EC_INVALID_CLASS_LOCALE:
csError = _T("The locale qualifier is either missing or is not a valid locale.");
break;
case EC_INVALID_MAPPINGSTRINGS:
csError = _T("The MappingString qualifier is either missing or is not in a valid format.");
break;
//assoc/ref errors
case EC_INVALID_REF_TARGET:
csError = _T("Reference overrides must maintain the type of the reference.");
break;
case EC_REF_NOT_LABELED_READ:
csError = _T("The reference property is not labeled as read.");
break;
case EC_INCOMPLETE_ASSOCIATION:
csError = _T("An association must contain at least two references.");
break;
case EC_REF_ON_NONASSOCIATION_CLASS:
csError = _T("A reference was found on a non-association class. Only associations may contain references.");
break;
case EC_INVALID_REF_OVERRIDES:
csError = _T("The override informaiton for this reference does not represent a valid object");
break;
case EC_INVALID_ASSOCIATION_INHERITANCE:
csError = _T("An association may be derived from a non-association class, but any class that derives from an association must be an association itself.");
break;
//proeprty errors
case EC_INVALID_PROPERTY_OVERRIDE:
csError = _T("Property overrides must maintain the type of the property.");
break;
case EC_INVALID_PROPERTY_MAXLEN:
csError = _T("Properties that are both strings and keys must have a valid MaxLen qualifier");
break;
case EC_PROPERTY_NOT_LABELED_READ:
csError = _T("The property is not labeled as read.");
break;
case EC_INVALID_PROPERTY_VALUE_QUALIFIER:
csError = _T("The Values qualifier is either not present, of a different type than the property or is not an array.");
break;
case EC_INVALID_PROPERTY_VALUEMAP_QUALIFIER:
csError = _T("The ValueMap qualifier is not an array or is not required.");
break;
case EC_INCONSITANT_VALUE_VALUEMAP_QUALIFIERS:
csError = _T("The Values and ValueMap qualifiers are not of the same length.");
break;
case EC_INVALID_PROPERTY_BITMAP_QUALIFIER:
csError = _T("The BitMap qualifier is not an array or is not required.");
break;
case EC_INCONSITANT_BITVALUE_BITMAP_QUALIFIERS:
csError = _T("The BitValues and BitMap qualifiers are not of the same length.");
break;
//method errors
case EC_INVALID_METHOD_OVERRIDE:
csError = _T("Method overrides must maintain the methods signature.");
break;
//qualifier errors
case EC_INVALID_QUALIFIER_SCOPE:
csError = _T("This qualifier is being used in an inappropriate place.");
break;
case EC_NON_CIM_WMI_QUALIFIER:
csError = _T("This qualifier is neither of CIM or WMI origin.");
break;
//overall checks
case EC_REDUNDANT_ASSOCIATION:
csError = _T("These associations share the same signature.");
break;
//w2k errors
case EC_INVALID_CLASS_DERIVATION:
csError = _T("See the Windows2000 logo requirements document for a description of valid class derivations.");
break;
case EC_INVALID_PHYSICALELEMENT_DERIVATION:
csError = _T("See the Windows2000 logo requirements document for a description of valid Physical Element derivations.");
break;
case EC_INVALID_SETTING_USAGE:
csError = _T("The setting information in this object is not being used appropriately. See the Windows2000 logo requirements document for details.");
break;
case EC_INVALID_STATISTICS_USAGE:
csError = _T("The statistics information in this object is not being used appropriately. See the Windows2000 logo requirements document for details.");
break;
case EC_INVALID_LOGICALDEVICE_DERIVATION:
csError = _T("See the Windows2000 logo requirements document for a description of valid Logical Device derivations.");
break;
case EC_INVALID_SETTING_DEVICE_USAGE:
csError = _T("The device-setting information in this object is not being used appropriately. See the Windows2000 logo requirements document for details.");
break;
case EC_INVALID_COMPUTERSYSTEM_DERIVATION:
csError = _T("See the Windows2000 logo requirements document for a description of valid Computer System derivations.");
break;
//localization errors
case EC_INCONSITANT_LOCALIZED_SCHEMA:
csError = _T("The schema found in this localized namespace does not match the schema in the parent namespace.");
break;
case EC_INVALID_LOCALIZED_CLASS:
csError = _T("This localized class does not match the definition in the parent namespace.");
break;
case EC_UNAMENDED_LOCALIZED_CLASS:
csError = _T("This localized class must contain the amendment qualifier.");
break;
case EC_NONABSTRACT_LOCALIZED_CLASS:
csError = _T("This localized class is not abstract.");
break;
case EC_INVALID_LOCALIZED_PROPERTY:
csError = _T("This localized property does not match the definition in the parent namespace.");
break;
case EC_INVALID_LOCALIZED_METHOD:
csError = _T("This localized method does not match the definition in the parent namespace.");
break;
case EC_INAPPROPRIATE_LOCALE_QUALIFIER:
csError = _T("The locale given for this object is inconsitent with the namespace in which it was found.");
break;
case EC_INVALID_LOCALE_NAMESPACE:
csError = _T("THe name given to this localized namespace does not represent a valid locale.");
break;
default:
csError = _T("Unknown Error");
break;
}
return csError;
}
/////////////////////////////////////////////
// Other Functions
HRESULT RedundantAssociationCheck(IWbemServices *pNamespace, CStringArray *pcsAssociations)
{
HRESULT hr = WBEM_S_NO_ERROR;
CStringArray csaReported1;
CStringArray csaReported2;
IWbemClassObject *pErrorObject = NULL;
IWbemClassObject *pObj = NULL;
IWbemClassObject *pComparisonObj = NULL;
IWbemQualifierSet *pQualSet = NULL;
CString csName;
BSTR bstrName = NULL;
BSTR bstrCIMTYPE;
VARIANT vCIMTYPE;
CString cstrName;
CString cstrType;
CString csComparisonClass;
CString csComparisonType;
CString csComparisonName;
VariantInit(&vCIMTYPE);
csaReported1.RemoveAll();
csaReported2.RemoveAll();
int iCount = pcsAssociations->GetSize();
for(int i = 0; i < iCount; i++){
csName = pcsAssociations->GetAt(i);
bstrName = csName.AllocSysString();
if(FAILED(hr = pNamespace->GetObject(bstrName, 0, NULL, &pObj, NULL))){
CString csUserMsg = _T("Cannot get ") + csName;
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
SysFreeString(bstrName);
return hr;
}
SysFreeString(bstrName);
CStringArray csaREFs;
csaREFs.RemoveAll();
CStringArray csaREFTypes;
csaREFTypes.RemoveAll();
int x = 0;
hr = pObj->BeginEnumeration(WBEM_FLAG_REFS_ONLY | WBEM_FLAG_NONSYSTEM_ONLY);
if(hr != WBEM_E_NOT_FOUND){
while((hr = pObj->Next(0, &bstrName, NULL, NULL, NULL)) == WBEM_S_NO_ERROR){
hr = pObj->GetPropertyQualifierSet(bstrName, &pQualSet);
bstrCIMTYPE = SysAllocString(L"CIMTYPE");
if(FAILED(hr = pQualSet->Get(bstrCIMTYPE, 0, &vCIMTYPE, NULL))){
CString csUserMsg = _T("Cannot get ") + csName;
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
SysFreeString(bstrName);
SysFreeString(bstrCIMTYPE);
return hr;
}
SysFreeString(bstrCIMTYPE);
cstrName = bstrName;
csaREFs.InsertAt(x, cstrName);
cstrType = V_BSTR(&vCIMTYPE);
csaREFTypes.InsertAt(x, cstrType);
VariantClear(&vCIMTYPE);
SysFreeString(bstrName);
pQualSet->Release();
pQualSet = NULL;
x++;
}
pObj->EndEnumeration();
//walk the whole list and compare the endpoints
for(int j = 0; j < (iCount - 1); j++){
if(j != i){
//if two are the same note as redundant
csComparisonClass = pcsAssociations->GetAt(j);
bstrName = csComparisonClass.AllocSysString();
if(FAILED(hr = pNamespace->GetObject(bstrName, 0, NULL, &pComparisonObj, NULL))){
CString csUserMsg = _T("Cannot get ") + csName;
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
SysFreeString(bstrName);
return hr;
}
SysFreeString(bstrName);
int iDuplicateREFs = 0;
int iREFCount = csaREFs.GetSize();
pComparisonObj->BeginEnumeration(WBEM_FLAG_REFS_ONLY | WBEM_FLAG_NONSYSTEM_ONLY);
while((hr = pComparisonObj->Next(0, &bstrName, NULL, NULL, NULL)) == WBEM_S_NO_ERROR){
csComparisonName = bstrName;
hr = pComparisonObj->GetPropertyQualifierSet(bstrName, &pQualSet);
if(hr != WBEM_E_NOT_FOUND){
BSTR bstrCIMTYPE = SysAllocString(L"CIMTYPE");
VARIANT vCIMTYPE;
VariantInit(&vCIMTYPE);
if(FAILED(hr = pQualSet->Get(bstrCIMTYPE, 0, &vCIMTYPE, NULL))){
CString csUserMsg = _T("Cannot get ") + csName;
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
SysFreeString(bstrCIMTYPE);
SysFreeString(bstrName);
return hr;
}
SysFreeString(bstrCIMTYPE);
csComparisonType = V_BSTR(&vCIMTYPE);
VariantClear(&vCIMTYPE);
for(int t = 0; t < iREFCount; t++){
if((csComparisonName.CompareNoCase(csaREFs.GetAt(t)) == 0) &&
(csComparisonType.CompareNoCase(csaREFTypes.GetAt(t)) == 0))
iDuplicateREFs++;
}
pQualSet->Release();
pQualSet = NULL;
}
SysFreeString(bstrName);
}
pComparisonObj->EndEnumeration();
if((iDuplicateREFs == iREFCount)){
bool bReported = false;
//check to see if we have already reported this
int iTrack = csaReported1.GetSize();
for(int i = 0; i < iTrack; i++){
if((csName.CompareNoCase(csaReported1[i]) == 0) &&
(csComparisonClass.CompareNoCase(csaReported2[i]) == 0)){
bReported = true;
break;
}
}
iTrack = csaReported2.GetSize();
for(i = 0; i < iTrack; i++){
if((csName.CompareNoCase(csaReported2[i]) == 0) &&
(csComparisonClass.CompareNoCase(csaReported1[i]) == 0)){
bReported = true;
break;
}
}
if(!bReported){
csaReported1.InsertAt(iTrack, csName);
csaReported2.InsertAt(iTrack, csComparisonClass);
CString csCombo = csName + _T(" : ") + csComparisonClass;
g_ReportLog.LogEntry(EC_REDUNDANT_ASSOCIATION, &csCombo);
}
}
pComparisonObj->Release();
pComparisonObj = NULL;
}
}
}
}
ReleaseErrorObject(pErrorObject);
return hr;
}
/*
CString GetRootObject(IWbemServices *pNamespace, CString csClassName)
{
HRESULT hr = WBEM_S_NO_ERROR;
IWbemClassObject *pErrorObject = NULL;
IWbemClassObject *pObj = NULL;
CString csLastClass;
BSTR bstrName;
while(csClassName.GetLength() > 0){
bstrName = csClassName.AllocSysString();
if(FAILED(hr = pNamespace->GetObject(bstrName, 0, NULL, &pObj, NULL))){
CString csUserMsg = _T("Cannot get ") + csClassName;
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
return _T("");
}
SysFreeString(bstrName);
csLastClass = csClassName;
csClassName = GetSuperClassName(pObj);
pObj->Release();
pObj = NULL;
}
csClassName = csLastClass;
return csClassName;
}
*/
CString GetRootObject(IWbemServices *pNamespace, CString csClassName)
{
HRESULT hr = WBEM_S_NO_ERROR;
IWbemClassObject *pErrorObject = NULL;
IWbemClassObject *pObj = NULL;
BSTR bstrName = csClassName.AllocSysString();
if(FAILED(hr = pNamespace->GetObject(bstrName, 0, NULL, &pObj, NULL))){
CString csUserMsg = _T("Cannot get ") + csClassName;
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
SysFreeString(bstrName);
ReleaseErrorObject(pErrorObject);
return _T("");
}
SysFreeString(bstrName);
CString csDYNASTY = _T("__DYNASTY");
CString csOut = GetBSTRProperty(pObj, &csDYNASTY);
pObj->Release();
ReleaseErrorObject(pErrorObject);
return csOut;
}
bool Local_CompareClassDerivation(CClass *pClass, CLocalNamespace *pLocalNamespace)
{
bool bRetVal = true;
IWbemClassObject *pErrorObject = NULL;
//get pClass (localized) and it's non localized equivelent
IWbemClassObject *pLocalObj = pClass->GetClassObject();
IWbemClassObject *pBaseObj = NULL;
IWbemServices *pBaseNamespace = pLocalNamespace->GetParentNamespace();
BSTR bstrName = pClass->GetName().AllocSysString();
HRESULT hr = pBaseNamespace->GetObject(bstrName, 0, NULL, &pBaseObj, NULL);
SysFreeString(bstrName);
if(FAILED(hr)){
CString csUserMsg = _T("Cannot get ") + pClass->GetName() + _T(" base object");
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
}
//get derivation
BSTR bstrDerivation = SysAllocString(L"__Derivation");
VARIANT vLocalDer, vBaseDer;
VariantInit(&vLocalDer);
VariantInit(&vBaseDer);
if(FAILED(pLocalObj->Get(bstrDerivation, 0, &vLocalDer, NULL, NULL))){
CString csUserMsg = _T("Cannot get ") + pClass->GetName() + _T(" derivation");
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
}else{
if(FAILED(pBaseObj->Get(bstrDerivation, 0, &vBaseDer, NULL, NULL))){
CString csUserMsg = _T("Cannot get ") + pClass->GetName() + _T(" base class derivation");
ErrorMsg(&csUserMsg, hr, pErrorObject, TRUE, &csUserMsg, __FILE__, __LINE__ - 32);
ReleaseErrorObject(pErrorObject);
}else{
BSTR HUGEP *plocalbstr;
BSTR HUGEP *pbasebstr;
long ix[2] = {0,0};
long lLower, lUpper, lBaseLower, lBaseUpper;
int iDim = SafeArrayGetDim(vLocalDer.parray);
hr = SafeArrayGetLBound(vLocalDer.parray, 1, &lLower);
hr = SafeArrayGetUBound(vLocalDer.parray, 1, &lUpper);
hr = SafeArrayGetLBound(vBaseDer.parray, 1, &lBaseLower);
if(lLower != lBaseLower) bRetVal = true;
hr = SafeArrayGetUBound(vBaseDer.parray, 1, &lBaseUpper);
if(lUpper != lBaseUpper) bRetVal = true;
hr = SafeArrayAccessData(vLocalDer.parray, (void HUGEP* FAR*)&plocalbstr);
hr = SafeArrayAccessData(vBaseDer.parray, (void HUGEP* FAR*)&pbasebstr);
if(bRetVal){
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++){
//check if it's an association
if(_wcsicmp(pbasebstr[ix[0]], plocalbstr[ix[0]]) != 0){
bRetVal = false;
}
if(!bRetVal) break;
}
}
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++){
SysFreeString(pbasebstr[ix[0]]);
SysFreeString(plocalbstr[ix[0]]);
}
}
}
VariantClear(&vLocalDer);
VariantClear(&vBaseDer);
pBaseObj->Release();
SysFreeString(bstrDerivation);
ReleaseErrorObject(pErrorObject);
//compare... set to false if they differ
return bRetVal;
}
HRESULT VerifyAllClassesPresent(CLocalNamespace *pLocalNamespace)
{
HRESULT hr = WBEM_S_NO_ERROR;
return hr;
}
HRESULT ValidUUID(CQualifier *pQual)
{
HRESULT hr = WBEM_S_NO_ERROR;
VARIANT v;
bool bRetVal = true;
VariantInit(&v);
v = pQual->GetValue();
if(V_VT(&v) == VT_BSTR){
// Check that it is a valid UUID format
CString csUUID = V_BSTR(&v);
if(csUUID[0] == _T('{')){
csUUID = csUUID.Left(csUUID.GetLength() - 1);
csUUID = csUUID.Right(csUUID.GetLength() - 1);
}
if(csUUID.GetLength() != 36) bRetVal = false;
if(csUUID.GetAt(8) != _T('-')) bRetVal = false;
if(csUUID.GetAt(13) != _T('-')) bRetVal = false;
if(csUUID.GetAt(18) != _T('-')) bRetVal = false;
if(csUUID.GetAt(23) != _T('-')) bRetVal = false;
}
VariantClear(&v);
if(!bRetVal){
CString csPath = pQual->GetPathNoQual();
g_ReportLog.LogEntry(EC_INVALID_CLASS_UUID, &csPath);
}
return hr;
}
HRESULT ValidLocale(CQualifier *pQual)
{
HRESULT hr = WBEM_S_NO_ERROR;
VARIANT v;
bool bRetVal = false;
VariantInit(&v);
v = pQual->GetValue();
if(V_VT(&v) == VT_I4){
// Check that it is a valid locale
if(((V_I4(&v) == 0x0000) || (V_I4(&v) == 0x0406) || (V_I4(&v) == 0x0413) ||
(V_I4(&v) == 0x0813) || (V_I4(&v) == 0x0409) || (V_I4(&v) == 0x0809) ||
(V_I4(&v) == 0x0c09) || (V_I4(&v) == 0x1009) || (V_I4(&v) == 0x1409) ||
(V_I4(&v) == 0x1809) || (V_I4(&v) == 0x040b) || (V_I4(&v) == 0x040c) ||
(V_I4(&v) == 0x080c) || (V_I4(&v) == 0x0c0c) || (V_I4(&v) == 0x100c) ||
(V_I4(&v) == 0x0407) || (V_I4(&v) == 0x0807) || (V_I4(&v) == 0x0c07) ||
(V_I4(&v) == 0x040f) || (V_I4(&v) == 0x0410) || (V_I4(&v) == 0x0810) ||
(V_I4(&v) == 0x0414) || (V_I4(&v) == 0x0814) || (V_I4(&v) == 0x0416) ||
(V_I4(&v) == 0x0816) || (V_I4(&v) == 0x041D) || (V_I4(&v) == 0x040a) ||
(V_I4(&v) == 0x080a) || (V_I4(&v) == 0x0c0a) || (V_I4(&v) == 0x0415) ||
(V_I4(&v) == 0x0405) || (V_I4(&v) == 0x041b) || (V_I4(&v) == 0x040e) ||
(V_I4(&v) == 0x0419) || (V_I4(&v) == 0x0408) || (V_I4(&v) == 0x0400) ||
(V_I4(&v) == 0x041f)))
bRetVal = true;
}
VariantClear(&v);
if(!bRetVal){
CString csPath = pQual->GetPathNoQual();
g_ReportLog.LogEntry(EC_INVALID_CLASS_LOCALE, &csPath);
}
return hr;
}
HRESULT ValidMappingStrings(CQualifier *pQual)
{
HRESULT hr = WBEM_S_NO_ERROR;
VARIANT v;
bool bRetVal = true;
VariantInit(&v);
v = pQual->GetValue();
if(V_VT(&v) == (VT_ARRAY|VT_BSTR)){
// Check for a valid string format
BSTR HUGEP *pbstr;
long ix[2] = {0,0};
long lLower, lUpper;
int iDim = SafeArrayGetDim(v.parray);
HRESULT hr = SafeArrayGetLBound(v.parray, 1, &lLower);
hr = SafeArrayGetUBound(v.parray, 1, &lUpper);
hr = SafeArrayAccessData(v.parray, (void HUGEP* FAR*)&pbstr);
CString csMap;
CString csTmp;
int iPos;
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++){
csMap = pbstr[ix[0]];
csTmp = csMap.Left(3);
if(csTmp.CompareNoCase(_T("MIF")) == 0){
csTmp = csMap.Mid(3, 1);
if(csTmp.CompareNoCase(_T(".")) == 0){
csMap = csMap.Right(csMap.GetLength() - 3);
iPos = csMap.Find(_T("|"));
csMap = csMap.Right(csMap.GetLength() - iPos + 1);
csMap.Find(_T("|"));
if(csMap.Find(_T("|")) <= 0) bRetVal = false;
}else bRetVal = false;
}else if(csTmp.CompareNoCase(_T("RFC")) == 0){
csMap = csMap.Right(csMap.GetLength() - 3);
iPos = csMap.Find(_T("|"));
if(iPos <= 0) bRetVal = false;
}
}
for(ix[0] = lLower; ix[0] <= lUpper; ix[0]++) SysFreeString(pbstr[ix[0]]);
}else bRetVal = false;
VariantClear(&v);
if(!bRetVal){
CString csPath = pQual->GetPathNoQual();
g_ReportLog.LogEntry(EC_INVALID_MAPPINGSTRINGS, &csPath);
}
return hr;
}
HRESULT ValidPropertyDescription(CQualifier *pQual, CString *pcsObject, CString *pcsProperty)
{
HRESULT hr = WBEM_S_NO_ERROR;
// TODO:
// this needs to check if the name of the property appears within the first
// 6 words of the description
VARIANT v;
bool bRetVal = true;
VariantInit(&v);
v = pQual->GetValue();
if(V_VT(&v) & VT_BSTR){
CString csSearch = V_BSTR(&v);
int iPos = 0;
for(int i = 0; i < 6; i++){
iPos = csSearch.Find(_T(" "), iPos);
}
csSearch = csSearch.Left(iPos + 1);
if(csSearch.Find(*pcsProperty, 0) == -1)
bRetVal = false;
}
if(!bRetVal){
CString csPath = pQual->GetPathNoQual();
g_ReportLog.LogEntry(EC_INADAQUATE_DESCRIPTION, &csPath);
}else{
//do the standard check
hr = ValidDescription(pQual, pcsObject);
}
return hr;
}
HRESULT ValidDescription(CQualifier *pQual, CString *pcsObject)
{
HRESULT hr = WBEM_S_NO_ERROR;
VARIANT v;
bool bRetVal = false;
VariantInit(&v);
v = pQual->GetValue();
if(V_VT(&v) & VT_BSTR){
// Should disallow descriptions that just recapitulate the name for
// example given the name
// Win32_LogicalDiskDrive
// An unacceptable description would be:
// "This class represents logical disk drives"
long lNoise;
CString csDesc;
for(int i = 0; i < QUAL_ARRAY_SIZE; i++)
g_csaNoise[i] = _T("");
g_iNoise = 0;
AddNoise("a");
AddNoise("and");
AddNoise("the");
AddNoise("class");
AddNoise("property");
AddNoise("this");
AddNoise("which");
AddNoise("is");
AddNoise("for");
AddNoise("may");
AddNoise("be");
AddNoise("component");
AddNoise("manage");
AddNoise("such");
AddNoise("as");
AddNoise("all");
AddNoise("abstract");
AddNoise("define");
AddNoise("object");
AddNoise("string");
AddNoise("number");
AddNoise("integer");
AddNoise("reference");
AddNoise("association");
AddNoise("or");
AddNoise("represent");
AddNoise(",");
AddNoise(".");
AddNoise(" ");
AddNoise("(");
AddNoise(")");
AddNoise("\\");
AddNoise("/");
AddNoise("<");
AddNoise(">");
csDesc = V_BSTR(&v);
for(long l = 1; l < csDesc.GetLength(); l++){
lNoise = FindNoise(csDesc.Mid(l));
if(lNoise > 0) csDesc = csDesc.Left(l - 1) + csDesc.Mid(l + lNoise);
}
if(CountLetters(csDesc, *pcsObject) < 50) bRetVal = false;
else bRetVal = true;
}
VariantClear(&v);
if(!bRetVal){
CString csPath = pQual->GetPathNoQual();
g_ReportLog.LogEntry(EC_INADAQUATE_DESCRIPTION, &csPath);
}
return hr;
}
void InitQualifierArrays()
{
g_iClassQual = g_iAssocQual = g_iIndicQual = g_iPropQual = g_iRefQual =
g_iMethodQual = g_iParamQual = g_iAnyQual = g_iCIMQual = 0;
//CIM Defined
AddClassQual(_T("ABSTRACT"));
AddAssocQual(_T("ABSTRACT"));
AddIndicQual(_T("ABSTRACT"));
AddClassQual(_T("AGGREGATION"));
AddPropQual(_T("ALIAS"));
AddRefQual(_T("ALIAS"));
AddMethodQual(_T("ALIAS"));
AddArrayQual(_T("ARRAYTYPE"));
//fix for #56607
AddRefQual(_T("ARRAYTYPE"));
AddPropQual(_T("ARRAYTYPE"));
AddParamQual(_T("ARRAYTYPE"));
AddClassQual(_T("ASSOCIATION"));
AddAssocQual(_T("DELETE"));
AddRefQual(_T("DELETE"));
AddAnyQual(_T("DESCRIPTION"));
AddClassQual(_T("EXPENSIVE"));
AddAssocQual(_T("EXPENSIVE"));
AddRefQual(_T("EXPENSIVE"));
AddPropQual(_T("EXPENSIVE"));
AddMethodQual(_T("EXPENSIVE"));
AddAssocQual(_T("IFDELETED"));
AddRefQual(_T("IFDELETED"));
AddParamQual(_T("IN"));
AddClassQual(_T("INVISIBLE"));
AddAssocQual(_T("INVISIBLE"));
AddPropQual(_T("INVISIBLE"));
AddRefQual(_T("INVISIBLE"));
AddMethodQual(_T("INVISIBLE"));
AddClassQual(_T("INDICATION"));
AddPropQual(_T("KEY"));
AddRefQual(_T("KEY"));
AddClassQual(_T("LARGE"));
AddPropQual(_T("LARGE"));
AddClassQual(_T("MAPPINGSTRINGS"));
AddPropQual(_T("MAPPINGSTRINGS"));
AddAssocQual(_T("MAPPINGSTRINGS"));
AddIndicQual(_T("MAPPINGSTRINGS"));
AddRefQual(_T("MAPPINGSTRINGS"));
AddRefQual(_T("MAX"));
AddPropQual(_T("MAXLEN"));
AddRefQual(_T("MIN"));
AddPropQual(_T("MODELCORRESPONDENCE"));
AddRefQual(_T("NONLOCAL"));
AddParamQual(_T("OUT"));
AddPropQual(_T("OVERRIDE"));
AddRefQual(_T("OVERRIDE"));
AddMethodQual(_T("OVERRIDE"));
AddPropQual(_T("PROPAGATED"));
AddPropQual(_T("READ"));
AddPropQual(_T("REQUIRED"));
AddClassQual(_T("REVISION"));
AddAssocQual(_T("REVISION"));
AddIndicQual(_T("REVISION"));
AddPropQual(_T("SCHEMA"));
AddMethodQual(_T("SCHEMA"));
AddClassQual(_T("SOURCE"));
AddAssocQual(_T("SOURCE"));
AddIndicQual(_T("SOURCE"));
AddPropQual(_T("SYNTAX"));
AddRefQual(_T("SYNTAX"));
AddPropQual(_T("SYNTAXTYPE"));
AddRefQual(_T("SYNTAXTYPE"));
AddClassQual(_T("TRIGGERTYPE"));
AddAssocQual(_T("TRIGGERTYPE"));
AddIndicQual(_T("TRIGGERTYPE"));
AddPropQual(_T("TRIGGERTYPE"));
AddRefQual(_T("TRIGGERTYPE"));
AddMethodQual(_T("TRIGGERTYPE"));
AddPropQual(_T("UNITS"));
AddPropQual(_T("VALUEMAP"));
AddPropQual(_T("VALUES"));
AddClassQual(_T("VERSION"));
AddAssocQual(_T("VERSION"));
AddIndicQual(_T("VERSION"));
AddRefQual(_T("WEAK"));
AddPropQual(_T("WRITE"));
//WMI defined qualifiers
AddClassQual(_T("AMENDMENT"));
AddAssocQual(_T("AMENDMENT"));
AddPropQual(_T("BITMAP"));
AddPropQual(_T("BITVALUES"));
AddPropQual(_T("CIM_KEY"));
AddPropQual(_T("CIMTYPE"));
AddMethodQual(_T("CIMTYPE"));
AddParamQual(_T("CIMTYPE"));
AddClassQual(_T("DEPRECATE"));
AddRefQual(_T("DEPRECATE"));
AddPropQual(_T("DEPRECATE"));
AddPropQual(_T("DEPRECATED"));
AddClassQual(_T("DISPLAY"));
AddPropQual(_T("DISPLAY"));
AddClassQual(_T("DYNAMIC"));
AddPropQual(_T("DYNAMIC"));
AddRefQual(_T("DYNAMIC"));
AddClassQual(_T("DYNPROPS"));
AddParamQual(_T("ID"));
AddMethodQual(_T("IMPLEMENTED"));
AddClassQual(_T("LOCALE"));
AddParamQual(_T("OPTIONAL"));
AddPropQual(_T("PRIVILEGES"));
AddMethodQual(_T("PRIVILEGES"));
AddClassQual(_T("PROVIDER"));
AddPropQual(_T("PROVIDER"));
AddRefQual(_T("PROVIDER"));
AddClassQual(_T("SINGLETON"));
AddClassQual(_T("STATIC"));
AddMethodQual(_T("STATIC"));
AddClassQual(_T("UUID"));
AddPropQual(_T("WRITEPRIVILEGES"));
}
void ClearQualifierArrays()
{
int i;
for(i = 0; i < QUAL_ARRAY_SIZE; i++){
g_csaClassQual[i] = _T("");
g_csaAssocQual[i] = _T("");
g_csaIndicQual[i] = _T("");
g_csaPropQual[i] = _T("");
g_csaArrayQual[i] = _T("");
g_csaRefQual[i] = _T("");
g_csaMethodQual[i] = _T("");
g_csaParamQual[i] = _T("");
g_csaAnyQual[i] = _T("");
g_csaCIMQual[i] = _T("");
}
g_iClassQual = g_iAssocQual = g_iIndicQual = g_iPropQual = g_iRefQual =
g_iMethodQual = g_iParamQual = g_iAnyQual = g_iCIMQual = 0;
}
bool IsClassQual(CString csQual)
{
int i;
for(i = 0; i < g_iClassQual; i++)
if(g_csaClassQual[i].CompareNoCase(csQual) == 0) return true;
for(i = 0; i < g_iAnyQual; i++)
if(g_csaAnyQual[i].CompareNoCase(csQual) == 0) return true;
return false;
}
bool IsAssocQual(CString csQual)
{
int i;
for(i = 0; i < g_iAssocQual; i++)
if(g_csaAssocQual[i].CompareNoCase(csQual) == 0) return true;
for(i = 0; i < g_iAnyQual; i++)
if(g_csaAnyQual[i].CompareNoCase(csQual) == 0) return true;
return false;
}
bool IsIndicQual(CString csQual)
{
int i;
for(i = 0; i < g_iIndicQual; i++)
if(g_csaIndicQual[i].CompareNoCase(csQual) == 0) return true;
for(i = 0; i < g_iAnyQual; i++)
if(g_csaAnyQual[i].CompareNoCase(csQual) == 0) return true;
return false;
}
bool IsPropQual(CString csQual)
{
int i;
for(i = 0; i < g_iPropQual; i++)
if(g_csaPropQual[i].CompareNoCase(csQual) == 0) return true;
for(i = 0; i < g_iAnyQual; i++)
if(g_csaAnyQual[i].CompareNoCase(csQual) == 0) return true;
return false;
}
bool IsRefQual(CString csQual)
{
int i;
for(i = 0; i < g_iRefQual; i++)
if(g_csaRefQual[i].CompareNoCase(csQual) == 0) return true;
for(i = 0; i < g_iAnyQual; i++)
if(g_csaAnyQual[i].CompareNoCase(csQual) == 0) return true;
return false;
}
bool IsParamQual(CString csQual)
{
int i;
for(i = 0; i < g_iParamQual; i++)
if(g_csaParamQual[i].CompareNoCase(csQual) == 0) return true;
for(i = 0; i < g_iAnyQual; i++)
if(g_csaAnyQual[i].CompareNoCase(csQual) == 0) return true;
return false;
}
bool IsMethQual(CString csQual)
{
int i;
for(i = 0; i < g_iMethodQual; i++)
if(g_csaMethodQual[i].CompareNoCase(csQual) == 0) return true;
for(i = 0; i < g_iAnyQual; i++)
if(g_csaAnyQual[i].CompareNoCase(csQual) == 0) return true;
return false;
}
bool IsArrayQual(CString csQual)
{
int i;
for(i = 0; i < g_iArrayQual; i++)
if(g_csaArrayQual[i].CompareNoCase(csQual) == 0) return true;
for(i = 0; i < g_iAnyQual; i++)
if(g_csaAnyQual[i].CompareNoCase(csQual) == 0) return true;
return false;
}
bool IsCIMQual(CString csQual)
{
for(int i = 0; i < g_iCIMQual; i++)
if(g_csaCIMQual[i].CompareNoCase(csQual) == 0) return true;
return false;
}
void AddClassQual(CString csStr)
{
g_csaClassQual[g_iClassQual] = csStr;
g_iClassQual++;
g_csaCIMQual[g_iCIMQual] = csStr;
g_iCIMQual++;
}
void AddAssocQual(CString csStr)
{
g_csaAssocQual[g_iAssocQual] = csStr;
g_iAssocQual++;
g_csaCIMQual[g_iCIMQual] = csStr;
g_iCIMQual++;
}
void AddIndicQual(CString csStr)
{
g_csaIndicQual[g_iIndicQual] = csStr;
g_iIndicQual++;
g_csaCIMQual[g_iCIMQual] = csStr;
g_iCIMQual++;
}
void AddPropQual(CString csStr)
{
g_csaPropQual[g_iPropQual] = csStr;
g_iPropQual++;
g_csaCIMQual[g_iCIMQual] = csStr;
g_iCIMQual++;
}
void AddArrayQual(CString csStr)
{
g_csaArrayQual[g_iArrayQual] = csStr;
g_iArrayQual++;
g_csaCIMQual[g_iCIMQual] = csStr;
g_iCIMQual++;
}
void AddRefQual(CString csStr)
{
g_csaRefQual[g_iRefQual] = csStr;
g_iRefQual++;
g_csaCIMQual[g_iCIMQual] = csStr;
g_iCIMQual++;
}
void AddMethodQual(CString csStr)
{
g_csaMethodQual[g_iMethodQual] = csStr;
g_iMethodQual++;
g_csaCIMQual[g_iCIMQual] = csStr;
g_iCIMQual++;
}
void AddParamQual(CString csStr)
{
g_csaParamQual[g_iParamQual] = csStr;
g_iParamQual++;
g_csaCIMQual[g_iCIMQual] = csStr;
g_iCIMQual++;
}
void AddAnyQual(CString csStr)
{
AddArrayQual(csStr);
AddAssocQual(csStr);
AddClassQual(csStr);
AddIndicQual(csStr);
AddMethodQual(csStr);
AddParamQual(csStr);
AddPropQual(csStr);
AddRefQual(csStr);
/*
g_csaAnyQual[g_iAnyQual] = csStr;
g_iAnyQual++;
g_csaCIMQual[g_iCIMQual] = csStr;
g_iCIMQual++;
*/
}
void AddNoise(CString csStr)
{
g_csaNoise[g_iNoise] = csStr;
g_iNoise++;
}
int FindNoise(CString csStr)
{
for(int i = 0; i < g_iNoise; i++){
if(g_csaNoise[i] == csStr.Left(g_csaNoise[i].GetLength()))
// should probably check for 's' and other obviouse suffixes
return g_csaNoise[i].GetLength();
}
return 0;
}
int CountLetters(CString csStr, CString csLetters)
{
int il = 0;
int ix = 0;
ix = csStr.Find(csLetters);
while(ix >= 0){
il += csLetters.GetLength();
ix = csStr.Find(csLetters);
}
return csStr.GetLength() - il;
}