Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

380 lines
12 KiB

/******************************************************************************
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<Instance*>(&*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);
}