// validation.cpp // Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved #include "precomp.h" #include "schemavalwiz.h" #include "schemavalwizctl.h" #include "validation.h" #include 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; }