/****************************************************************************** Copyright (c) 1999 Microsoft Corporation Module Name: WMIParser_Cluster.cpp Abstract: This file contains the implementation of the WMIParser::Cluster class, which is used to cluster together instances based on Class or Key. Revision History: Davide Massarenti (Dmassare) 07/25/99 created ******************************************************************************/ #include "stdafx.h" HRESULT WMIParser::Cluster::Add( /*[in]*/ Instance* wmipiInst ) { __HCP_FUNC_ENTRY( "WMIParser::Cluster::Add" ); HRESULT hr; m_map[wmipiInst] = wmipiInst; hr = S_OK; __HCP_FUNC_EXIT(hr); } HRESULT WMIParser::Cluster::Find( /*[in] */ Instance* wmipiInst , /*[out]*/ Instance*& wmipiRes , /*[out]*/ bool& fFound ) { __HCP_FUNC_ENTRY( "WMIParser::Cluster::Find" ); HRESULT hr; ClusterByKeyIter itCluster; itCluster = m_map.find( wmipiInst ); if(itCluster != m_map.end()) { wmipiRes = (*itCluster).second; fFound = true; } else { wmipiRes = NULL; fFound = false; } hr = S_OK; __HCP_FUNC_EXIT(hr); } HRESULT WMIParser::Cluster::Enum( /*[out]*/ ClusterByKeyIter& itBegin , /*[out]*/ ClusterByKeyIter& itEnd ) { __HCP_FUNC_ENTRY( "WMIParser::Cluster::Enum" ); HRESULT hr; itBegin = m_map.begin(); itEnd = m_map.end (); hr = S_OK; __HCP_FUNC_EXIT(hr); } ///////////////////////////////////////////////////////////////////////////// HRESULT WMIParser::DistributeOnCluster( /*[in]*/ ClusterByClassMap& cluster , /*[in]*/ Snapshot& wmips ) { __HCP_FUNC_ENTRY( "WMIParser::DistributeOnCluster" ); HRESULT hr; Snapshot::InstIterConst itBegin; Snapshot::InstIterConst itEnd; Instance* pwmipiInst; // // Create clusters based on CLASSPATH/CLASSNAME. // __MPC_EXIT_IF_METHOD_FAILS(hr, wmips.get_Instances( itBegin, itEnd )); while(itBegin != itEnd) { // // First of all, find the cluster by Path/Class. // Cluster& subcluster = cluster[ pwmipiInst = const_cast(&*itBegin) ]; // // Then, add the instance in the cluster by Key. // __MPC_EXIT_IF_METHOD_FAILS(hr, subcluster.Add( pwmipiInst )); itBegin++; } hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); } ///////////////////////////////////////////////////////////////////////////// #define TAG_CIM L"CIM" #define VALUE_REMOVED L"Delete" #define VALUE_MODIFIED L"Update" #define VALUE_ADDED L"New" HRESULT WMIParser::CompareSnapshots( /*[in] */ BSTR bstrFilenameT0 , /*[in] */ BSTR bstrFilenameT1 , /*[in] */ BSTR bstrFilenameDiff , /*[out,retval]*/ VARIANT_BOOL *pVal ) { __HCP_FUNC_ENTRY( "WMIParser::CompareMachineInfo" ); HRESULT hr; WMIParser::ClusterByClassMap clusterOld; WMIParser::ClusterByClassMap clusterNew; WMIParser::ClusterByClassIter itClusterOld; WMIParser::ClusterByClassIter itClusterNew; WMIParser::Snapshot wmipsOld; WMIParser::Snapshot wmipsNew; WMIParser::Snapshot wmipsDiff; WMIParser::Snapshot::InstIterConst itBegin; WMIParser::Snapshot::InstIterConst itEnd; WMIParser::ClusterByKeyIter itSubBegin; WMIParser::ClusterByKeyIter itSubEnd; WMIParser::Instance* pwmipiInst; WMIParser::Instance* pwmipiInst2; WMIParser::Property_Scalar* pwmippChange; bool fDifferent = false; bool fFound; __MPC_PARAMCHECK_BEGIN(hr) __MPC_PARAMCHECK_POINTER_AND_SET(pVal,VARIANT_FALSE); __MPC_PARAMCHECK_END(); // // Load old and new snapshots and prepare the delta one. // __MPC_EXIT_IF_METHOD_FAILS(hr, wmipsOld.Load( SAFEBSTR( bstrFilenameT0 ), TAG_CIM )); __MPC_EXIT_IF_METHOD_FAILS(hr, wmipsNew.Load( SAFEBSTR( bstrFilenameT1 ), TAG_CIM )); __MPC_EXIT_IF_METHOD_FAILS(hr, wmipsDiff.New( )); // // Create clusters based on CLASSPATH/CLASSNAME. // __MPC_EXIT_IF_METHOD_FAILS(hr, WMIParser::DistributeOnCluster( clusterOld, wmipsOld )); __MPC_EXIT_IF_METHOD_FAILS(hr, WMIParser::DistributeOnCluster( clusterNew, wmipsNew )); // // Compute delta of Old vs New. // { for(itClusterOld = clusterOld.begin(); itClusterOld != clusterOld.end(); itClusterOld++) { pwmipiInst = (*itClusterOld).first; // Get the key of the cluster. itClusterNew = clusterNew.find( pwmipiInst ); if(itClusterNew == clusterNew.end()) { // // The cluster doesn't exist in the new snapshot, so it's a deleted cluster ... // // // Copy all the instances in the diff files, marking them as "Removed". // WMIParser::Cluster& subclusterOld = (*itClusterOld).second; __MPC_EXIT_IF_METHOD_FAILS(hr, subclusterOld.Enum( itSubBegin, itSubEnd )); while(itSubBegin != itSubEnd) { __MPC_EXIT_IF_METHOD_FAILS(hr, wmipsDiff.clone_Instance( (*itSubBegin).first, pwmipiInst )); // // Update the "Change" property. // __MPC_EXIT_IF_METHOD_FAILS(hr, pwmipiInst->get_Change( pwmippChange )); __MPC_EXIT_IF_METHOD_FAILS(hr, pwmippChange->put_Data( VALUE_REMOVED, fFound )); fDifferent = true; itSubBegin++; } } else { WMIParser::Cluster& subclusterOld = (*itClusterOld).second; WMIParser::Cluster& subclusterNew = (*itClusterNew).second; __MPC_EXIT_IF_METHOD_FAILS(hr, subclusterOld.Enum( itSubBegin, itSubEnd )); while(itSubBegin != itSubEnd) { pwmipiInst = (*itSubBegin).first; __MPC_EXIT_IF_METHOD_FAILS(hr, subclusterNew.Find( pwmipiInst, pwmipiInst2, fFound )); if(fFound == false) { // // Found a deleted instance ... // // // Copy it in the diff files, marking it as "Removed". // __MPC_EXIT_IF_METHOD_FAILS(hr, wmipsDiff.clone_Instance( (*itSubBegin).first, pwmipiInst )); // // Update the "Change" property. // __MPC_EXIT_IF_METHOD_FAILS(hr, pwmipiInst->get_Change( pwmippChange )); __MPC_EXIT_IF_METHOD_FAILS(hr, pwmippChange->put_Data( VALUE_REMOVED, fFound )); fDifferent = true; } else { if(*pwmipiInst == *pwmipiInst2) { // // They are the same... // } else { // // Found a changed instance ... // // // Copy it in the diff files, marking it as "Modified". // __MPC_EXIT_IF_METHOD_FAILS(hr, wmipsDiff.clone_Instance( (*itSubBegin).first, pwmipiInst )); // // Update the "Change" property. // __MPC_EXIT_IF_METHOD_FAILS(hr, pwmipiInst->get_Change( pwmippChange )); __MPC_EXIT_IF_METHOD_FAILS(hr, pwmippChange->put_Data( VALUE_MODIFIED, fFound )); fDifferent = true; } } itSubBegin++; } } } } // // Compute delta of New vs Old. // { for(itClusterNew = clusterNew.begin(); itClusterNew != clusterNew.end(); itClusterNew++) { pwmipiInst = (*itClusterNew).first; // Get the key of the cluster. itClusterOld = clusterOld.find( pwmipiInst ); if(itClusterOld == clusterOld.end()) { // // The cluster doesn't exist in the old snapshot, so it's an added cluster ... // // // Copy all the instances in the diff files, marking them as "Added". // WMIParser::Cluster& subclusterNew = (*itClusterNew).second; __MPC_EXIT_IF_METHOD_FAILS(hr, subclusterNew.Enum( itSubBegin, itSubEnd )); while(itSubBegin != itSubEnd) { __MPC_EXIT_IF_METHOD_FAILS(hr, wmipsDiff.clone_Instance( (*itSubBegin).first, pwmipiInst )); // // Update the "Change" property. // __MPC_EXIT_IF_METHOD_FAILS(hr, pwmipiInst->get_Change( pwmippChange )); __MPC_EXIT_IF_METHOD_FAILS(hr, pwmippChange->put_Data( VALUE_ADDED, fFound )); fDifferent = true; itSubBegin++; } } else { WMIParser::Cluster& subclusterNew = (*itClusterNew).second; WMIParser::Cluster& subclusterOld = (*itClusterOld).second; __MPC_EXIT_IF_METHOD_FAILS(hr, subclusterNew.Enum( itSubBegin, itSubEnd )); while(itSubBegin != itSubEnd) { pwmipiInst = (*itSubBegin).first; __MPC_EXIT_IF_METHOD_FAILS(hr, subclusterOld.Find( pwmipiInst, pwmipiInst2, fFound )); if(fFound == false) { // // Found an added instance ... // // // Copy it in the diff files, marking it as "Added". // __MPC_EXIT_IF_METHOD_FAILS(hr, wmipsDiff.clone_Instance( (*itSubBegin).first, pwmipiInst )); // // Update the "Change" property. // __MPC_EXIT_IF_METHOD_FAILS(hr, pwmipiInst->get_Change( pwmippChange )); __MPC_EXIT_IF_METHOD_FAILS(hr, pwmippChange->put_Data( VALUE_ADDED, fFound )); fDifferent = true; } else { // // Already checked for changes in two instances... // } itSubBegin++; } } } } // // Only save the delta if actually there are differences. // if(fDifferent) { // // Save the delta. // __MPC_EXIT_IF_METHOD_FAILS(hr, wmipsDiff.Save( SAFEBSTR( bstrFilenameDiff ) )); *pVal = VARIANT_TRUE; } else { *pVal = VARIANT_FALSE; } hr = S_OK; __HCP_FUNC_CLEANUP; __HCP_FUNC_EXIT(hr); }