// Copyright (c) 1997-2001 Microsoft Corporation, All Rights Reserved #include "precomp.h" #include "SchemaInfo.h" // Returns TRUE if the attribute exists, it is of type BOOL, and is set to TRUE BOOL GetAttribBool(IWbemQualifierSet *pAttribSet, LPCWSTR szName) { if(!pAttribSet) return FALSE; BOOL bReturn = FALSE; VARIANTARG var; VariantInit(&var); BSTR bstrTemp = SysAllocString(szName); HRESULT hr = pAttribSet->Get(bstrTemp, 0, &var, NULL); ::SysFreeString(bstrTemp); if(SUCCEEDED(hr) && var.vt == VT_BOOL) bReturn = V_BOOL(&var); VariantClear(&var); return bReturn; } CString GetBSTRProperty(IWbemClassObject *pClass, LPCWSTR szProperty) { CString szOut; VARIANTARG var; VariantInit(&var); long lType; long lFlavor; BSTR bstrTemp = SysAllocString(szProperty); HRESULT hr = pClass->Get(bstrTemp, 0, &var, &lType, &lFlavor); ::SysFreeString(bstrTemp); if(SUCCEEDED(hr) && var.vt == VT_BSTR) szOut = var.bstrVal; VariantClear(&var); return szOut; } BOOL IsAbstract(IWbemQualifierSet *pAttribSet) { return GetAttribBool(pAttribSet, L"Abstract"); } BOOL IsAssoc(IWbemQualifierSet *pAttribSet) { return GetAttribBool(pAttribSet, L"Association"); } CString GetIWbemClass(IWbemClassObject *pClass) { return GetBSTRProperty(pClass,L"__Class"); } CString GetIWbemSuperClass(IWbemClassObject *pClass) { return GetBSTRProperty(pClass,L"__SuperClass"); } void CSchemaInfo::Init(const CPtrArray &rgpClasses) { CleanUp(); Update(rgpClasses); } void CSchemaInfo::Update(const CPtrArray &rgpClasses) { for(int i=0;im_rgszSubs.GetSize()) { for(int i=0;im_rgszSubs.GetSize();i++) DeleteFromMap(u.pClass->m_rgszSubs[i]); } delete u.pClass; m_mapNameToClass.RemoveKey(szClass); } CSchemaInfo::CClassInfo &CSchemaInfo::AddClass(IWbemClassObject *pClass) { IWbemQualifierSet *pAttribSet = NULL; if(FAILED(pClass->GetQualifierSet(&pAttribSet))) { ASSERT(FALSE); // Nothing we can do - IsAbstract and IsAssoc will handle it } CString szClass = GetIWbemClass(pClass); CString szSuper = GetIWbemSuperClass(pClass); CClassInfo &info = (*this)[szClass]; info.m_pObject = pClass; info.m_szClass = szClass; info.m_szSuper = szSuper; info.m_bAbstract = IsAbstract(pAttribSet); info.m_bAssoc = IsAssoc(pAttribSet); (*this)[szSuper].m_rgszSubs.Add(szClass); if(!info.m_bAbstract) { CString szClassT(szSuper); while(szClassT.GetLength()) { CClassInfo &infoT = (*this)[szClassT]; if(infoT.m_bSomeConcreteChild) break; infoT.m_bSomeConcreteChild = TRUE; szClassT = infoT.m_szSuper; } } if(pAttribSet) pAttribSet->Release(); return info; } // OLD STUFF FROM ClassNavCtl.cpp #if 0 CStringArray rgszRealClasses; CStringArray rgszRealAssocs; CStringArray rgszRealAssocsLeft; CStringArray rgszRealAssocsRight; POSITION pos = schema.GetStartPosition(); while(pos) { CString szClass; CSchemaInfo::CClassInfo &info = schema.GetNextAssoc(pos, szClass); if(info.m_szClass.GetLength() == 0) continue; if(!info.m_bAbstract) { if(info.m_bAssoc) { rgszRealAssocs.Add(szClass); CString szLeft, szRight; GetAssocLeftRight(info.m_pObject, szLeft, szRight); rgszRealAssocsLeft.Add(szLeft); rgszRealAssocsRight.Add(szRight); } else { rgszRealClasses.Add(szClass); CString szClassT(szClass); while(szClassT.GetLength()) { schema[szClassT].m_rgszRealSubs.Add(szClass); szClassT = schema[szClassT].m_szSuper; } } } } HTREEITEM hLRA = m_ctcTree.InsertItem(_T("Classes that can participate in Associations"), SCHEMA_ASSOC, SCHEMA_ASSOC); HTREEITEM hALR = m_ctcTree.InsertItem(_T("Associations classes"), SCHEMA_ASSOC, SCHEMA_ASSOC); HTREEITEM hLegend = m_ctcTree.InsertItem(_T("Legend"), SCHEMA_15, SCHEMA_15); m_ctcTree.InsertItem(_T("Abstract Class with only Abstract children"), SCHEMA_CLASS_ABSTRACT2, SCHEMA_CLASS_ABSTRACT2, hLegend); m_ctcTree.InsertItem(_T("Abstract Class with at leat one child not Abstract"), SCHEMA_CLASS_ABSTRACT1, SCHEMA_CLASS_ABSTRACT1, hLegend); m_ctcTree.InsertItem(_T("Class"), SCHEMA_CLASS, SCHEMA_CLASS, hLegend); m_ctcTree.InsertItem(_T("Abstract Association Class with only Abstract children"), SCHEMA_ASSOC_ABSTRACT2, SCHEMA_ASSOC_ABSTRACT2, hLegend); m_ctcTree.InsertItem(_T("Abstract Associaton Class with at leat one Non-Abstract child"), SCHEMA_ASSOC_ABSTRACT1, SCHEMA_ASSOC_ABSTRACT1, hLegend); m_ctcTree.InsertItem(_T("Associaton Class"), SCHEMA_ASSOC, SCHEMA_ASSOC, hLegend); HTREEITEM hLegend2 = m_ctcTree.InsertItem(_T("Specialized Icons"), SCHEMA_15, SCHEMA_15, hLegend); HTREEITEM hLegend3 = m_ctcTree.InsertItem(_T("Debug Info"), SCHEMA_15, SCHEMA_15, hLegend); m_ctcTree.InsertItem(_T("Association Class with one side the same or superclass of other"), SCHEMA_ASSOC_2, SCHEMA_ASSOC_2, hLegend2); m_ctcTree.InsertItem(_T("Association Class whoes relationship is more than 1 to 1"), SCHEMA_ASSOC_1, SCHEMA_ASSOC_1, hLegend2); m_ctcTree.InsertItem(_T("Endpoint Class with multiple possible Association paths"), SCHEMA_CLASS_1, SCHEMA_CLASS_1, hLegend2); DWORD dw4 = GetTickCount(); for(i=0;i %i)"), (LPCTSTR)szAssoc, nNonAbstractOnLeft, nNonAbstractOnRight); m_ctcTree.SetItemText(hAssoc, sz); m_ctcTree.SetItemImage(hAssoc, SCHEMA_ASSOC_1, SCHEMA_ASSOC_1); } if(schema.IsSuper(szLeft, szRight) || schema.IsSuper(szRight, szLeft)) m_ctcTree.SetItemImage(hAssoc, SCHEMA_ASSOC_2, SCHEMA_ASSOC_2); // m_ctcTree.SetItemImage(hAssoc, bMany?12:SCHEMA_ASSOC_2, bMany?12:SCHEMA_ASSOC_2); int j; for(j=0;jGetStartPosition(); while(pos2) { u.pMap->GetNextAssoc(pos2, szEndpoint, pTemp2); m_ctcTree.AddTreeObject2(hAssoc, schema[szEndpoint], FALSE); } delete u.pMap; } pos1 = mapEndpoints.GetStartPosition(); while(pos1) { mapEndpoints.GetNextAssoc(pos1, szEndpoint, u.pTemp); HTREEITEM hEndpoint = m_ctcTree.AddTreeObject2(hEndpoints, schema[szEndpoint], TRUE); if(u.pMap->GetCount() > 1) m_ctcTree.SetItemImage(hEndpoint, SCHEMA_CLASS_1, SCHEMA_CLASS_1); POSITION pos2 = u.pMap->GetStartPosition(); while(pos2) { u.pMap->GetNextAssoc(pos2, szAssoc, pTemp2); m_ctcTree.AddTreeObject2(hEndpoint, schema[szAssoc], FALSE); } delete u.pMap; } m_ctcTree.SortChildren(hAssocs); m_ctcTree.Expand(hAssocs, TVE_EXPAND); m_ctcTree.SortChildren(hEndpoints); m_ctcTree.Expand(hEndpoints, TVE_EXPAND); } DWORD dw6 = GetTickCount(); DWORD dwTotal1 = dw2-dw1;; DWORD dwTotal2 = dw3-dw2;; DWORD dwTotal3 = dw4-dw3;; DWORD dwTotal4 = dw5-dw4;; DWORD dwTotal5 = dw6-dw5;; DWORD dwTotal = dw6 - dw1; CString sz; sz.Format(_T("Total = %i.%03i (%i.%03i, %i.%03i, %i.%03i, %i.%03i, %i.%03i)"), dwTotal/1000, dwTotal%1000, dwTotal1/1000, dwTotal1%1000, dwTotal2/1000, dwTotal2%1000, dwTotal3/1000, dwTotal3%1000, dwTotal4/1000, dwTotal4%1000, dwTotal5/1000, dwTotal5%1000); m_ctcTree.InsertItem(sz, SCHEMA_15, SCHEMA_15, hLegend3); m_ctcTree.SortChildren(hALR); m_ctcTree.SortChildren(hLRA); #endif