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

  1. /******************************************************************************
  2. Copyright (c) 1999 Microsoft Corporation
  3. Module Name:
  4. WMIParser_Cluster.cpp
  5. Abstract:
  6. This file contains the implementation of the WMIParser::Cluster class,
  7. which is used to cluster together instances based on Class or Key.
  8. Revision History:
  9. Davide Massarenti (Dmassare) 07/25/99
  10. created
  11. ******************************************************************************/
  12. #include "stdafx.h"
  13. HRESULT WMIParser::Cluster::Add( /*[in]*/ Instance* wmipiInst )
  14. {
  15. __HCP_FUNC_ENTRY( "WMIParser::Cluster::Add" );
  16. HRESULT hr;
  17. m_map[wmipiInst] = wmipiInst;
  18. hr = S_OK;
  19. __HCP_FUNC_EXIT(hr);
  20. }
  21. HRESULT WMIParser::Cluster::Find( /*[in] */ Instance* wmipiInst ,
  22. /*[out]*/ Instance*& wmipiRes ,
  23. /*[out]*/ bool& fFound )
  24. {
  25. __HCP_FUNC_ENTRY( "WMIParser::Cluster::Find" );
  26. HRESULT hr;
  27. ClusterByKeyIter itCluster;
  28. itCluster = m_map.find( wmipiInst );
  29. if(itCluster != m_map.end())
  30. {
  31. wmipiRes = (*itCluster).second;
  32. fFound = true;
  33. }
  34. else
  35. {
  36. wmipiRes = NULL;
  37. fFound = false;
  38. }
  39. hr = S_OK;
  40. __HCP_FUNC_EXIT(hr);
  41. }
  42. HRESULT WMIParser::Cluster::Enum( /*[out]*/ ClusterByKeyIter& itBegin ,
  43. /*[out]*/ ClusterByKeyIter& itEnd )
  44. {
  45. __HCP_FUNC_ENTRY( "WMIParser::Cluster::Enum" );
  46. HRESULT hr;
  47. itBegin = m_map.begin();
  48. itEnd = m_map.end ();
  49. hr = S_OK;
  50. __HCP_FUNC_EXIT(hr);
  51. }
  52. /////////////////////////////////////////////////////////////////////////////
  53. HRESULT WMIParser::DistributeOnCluster( /*[in]*/ ClusterByClassMap& cluster ,
  54. /*[in]*/ Snapshot& wmips )
  55. {
  56. __HCP_FUNC_ENTRY( "WMIParser::DistributeOnCluster" );
  57. HRESULT hr;
  58. Snapshot::InstIterConst itBegin;
  59. Snapshot::InstIterConst itEnd;
  60. Instance* pwmipiInst;
  61. //
  62. // Create clusters based on CLASSPATH/CLASSNAME.
  63. //
  64. __MPC_EXIT_IF_METHOD_FAILS(hr, wmips.get_Instances( itBegin, itEnd ));
  65. while(itBegin != itEnd)
  66. {
  67. //
  68. // First of all, find the cluster by Path/Class.
  69. //
  70. Cluster& subcluster = cluster[ pwmipiInst = const_cast<Instance*>(&*itBegin) ];
  71. //
  72. // Then, add the instance in the cluster by Key.
  73. //
  74. __MPC_EXIT_IF_METHOD_FAILS(hr, subcluster.Add( pwmipiInst ));
  75. itBegin++;
  76. }
  77. hr = S_OK;
  78. __HCP_FUNC_CLEANUP;
  79. __HCP_FUNC_EXIT(hr);
  80. }
  81. /////////////////////////////////////////////////////////////////////////////
  82. #define TAG_CIM L"CIM"
  83. #define VALUE_REMOVED L"Delete"
  84. #define VALUE_MODIFIED L"Update"
  85. #define VALUE_ADDED L"New"
  86. HRESULT WMIParser::CompareSnapshots( /*[in] */ BSTR bstrFilenameT0 ,
  87. /*[in] */ BSTR bstrFilenameT1 ,
  88. /*[in] */ BSTR bstrFilenameDiff ,
  89. /*[out,retval]*/ VARIANT_BOOL *pVal )
  90. {
  91. __HCP_FUNC_ENTRY( "WMIParser::CompareMachineInfo" );
  92. HRESULT hr;
  93. WMIParser::ClusterByClassMap clusterOld;
  94. WMIParser::ClusterByClassMap clusterNew;
  95. WMIParser::ClusterByClassIter itClusterOld;
  96. WMIParser::ClusterByClassIter itClusterNew;
  97. WMIParser::Snapshot wmipsOld;
  98. WMIParser::Snapshot wmipsNew;
  99. WMIParser::Snapshot wmipsDiff;
  100. WMIParser::Snapshot::InstIterConst itBegin;
  101. WMIParser::Snapshot::InstIterConst itEnd;
  102. WMIParser::ClusterByKeyIter itSubBegin;
  103. WMIParser::ClusterByKeyIter itSubEnd;
  104. WMIParser::Instance* pwmipiInst;
  105. WMIParser::Instance* pwmipiInst2;
  106. WMIParser::Property_Scalar* pwmippChange;
  107. bool fDifferent = false;
  108. bool fFound;
  109. __MPC_PARAMCHECK_BEGIN(hr)
  110. __MPC_PARAMCHECK_POINTER_AND_SET(pVal,VARIANT_FALSE);
  111. __MPC_PARAMCHECK_END();
  112. //
  113. // Load old and new snapshots and prepare the delta one.
  114. //
  115. __MPC_EXIT_IF_METHOD_FAILS(hr, wmipsOld.Load( SAFEBSTR( bstrFilenameT0 ), TAG_CIM ));
  116. __MPC_EXIT_IF_METHOD_FAILS(hr, wmipsNew.Load( SAFEBSTR( bstrFilenameT1 ), TAG_CIM ));
  117. __MPC_EXIT_IF_METHOD_FAILS(hr, wmipsDiff.New( ));
  118. //
  119. // Create clusters based on CLASSPATH/CLASSNAME.
  120. //
  121. __MPC_EXIT_IF_METHOD_FAILS(hr, WMIParser::DistributeOnCluster( clusterOld, wmipsOld ));
  122. __MPC_EXIT_IF_METHOD_FAILS(hr, WMIParser::DistributeOnCluster( clusterNew, wmipsNew ));
  123. //
  124. // Compute delta of Old vs New.
  125. //
  126. {
  127. for(itClusterOld = clusterOld.begin(); itClusterOld != clusterOld.end(); itClusterOld++)
  128. {
  129. pwmipiInst = (*itClusterOld).first; // Get the key of the cluster.
  130. itClusterNew = clusterNew.find( pwmipiInst );
  131. if(itClusterNew == clusterNew.end())
  132. {
  133. //
  134. // The cluster doesn't exist in the new snapshot, so it's a deleted cluster ...
  135. //
  136. //
  137. // Copy all the instances in the diff files, marking them as "Removed".
  138. //
  139. WMIParser::Cluster& subclusterOld = (*itClusterOld).second;
  140. __MPC_EXIT_IF_METHOD_FAILS(hr, subclusterOld.Enum( itSubBegin, itSubEnd ));
  141. while(itSubBegin != itSubEnd)
  142. {
  143. __MPC_EXIT_IF_METHOD_FAILS(hr, wmipsDiff.clone_Instance( (*itSubBegin).first, pwmipiInst ));
  144. //
  145. // Update the "Change" property.
  146. //
  147. __MPC_EXIT_IF_METHOD_FAILS(hr, pwmipiInst->get_Change( pwmippChange ));
  148. __MPC_EXIT_IF_METHOD_FAILS(hr, pwmippChange->put_Data( VALUE_REMOVED, fFound ));
  149. fDifferent = true;
  150. itSubBegin++;
  151. }
  152. }
  153. else
  154. {
  155. WMIParser::Cluster& subclusterOld = (*itClusterOld).second;
  156. WMIParser::Cluster& subclusterNew = (*itClusterNew).second;
  157. __MPC_EXIT_IF_METHOD_FAILS(hr, subclusterOld.Enum( itSubBegin, itSubEnd ));
  158. while(itSubBegin != itSubEnd)
  159. {
  160. pwmipiInst = (*itSubBegin).first;
  161. __MPC_EXIT_IF_METHOD_FAILS(hr, subclusterNew.Find( pwmipiInst, pwmipiInst2, fFound ));
  162. if(fFound == false)
  163. {
  164. //
  165. // Found a deleted instance ...
  166. //
  167. //
  168. // Copy it in the diff files, marking it as "Removed".
  169. //
  170. __MPC_EXIT_IF_METHOD_FAILS(hr, wmipsDiff.clone_Instance( (*itSubBegin).first, pwmipiInst ));
  171. //
  172. // Update the "Change" property.
  173. //
  174. __MPC_EXIT_IF_METHOD_FAILS(hr, pwmipiInst->get_Change( pwmippChange ));
  175. __MPC_EXIT_IF_METHOD_FAILS(hr, pwmippChange->put_Data( VALUE_REMOVED, fFound ));
  176. fDifferent = true;
  177. }
  178. else
  179. {
  180. if(*pwmipiInst == *pwmipiInst2)
  181. {
  182. //
  183. // They are the same...
  184. //
  185. }
  186. else
  187. {
  188. //
  189. // Found a changed instance ...
  190. //
  191. //
  192. // Copy it in the diff files, marking it as "Modified".
  193. //
  194. __MPC_EXIT_IF_METHOD_FAILS(hr, wmipsDiff.clone_Instance( (*itSubBegin).first, pwmipiInst ));
  195. //
  196. // Update the "Change" property.
  197. //
  198. __MPC_EXIT_IF_METHOD_FAILS(hr, pwmipiInst->get_Change( pwmippChange ));
  199. __MPC_EXIT_IF_METHOD_FAILS(hr, pwmippChange->put_Data( VALUE_MODIFIED, fFound ));
  200. fDifferent = true;
  201. }
  202. }
  203. itSubBegin++;
  204. }
  205. }
  206. }
  207. }
  208. //
  209. // Compute delta of New vs Old.
  210. //
  211. {
  212. for(itClusterNew = clusterNew.begin(); itClusterNew != clusterNew.end(); itClusterNew++)
  213. {
  214. pwmipiInst = (*itClusterNew).first; // Get the key of the cluster.
  215. itClusterOld = clusterOld.find( pwmipiInst );
  216. if(itClusterOld == clusterOld.end())
  217. {
  218. //
  219. // The cluster doesn't exist in the old snapshot, so it's an added cluster ...
  220. //
  221. //
  222. // Copy all the instances in the diff files, marking them as "Added".
  223. //
  224. WMIParser::Cluster& subclusterNew = (*itClusterNew).second;
  225. __MPC_EXIT_IF_METHOD_FAILS(hr, subclusterNew.Enum( itSubBegin, itSubEnd ));
  226. while(itSubBegin != itSubEnd)
  227. {
  228. __MPC_EXIT_IF_METHOD_FAILS(hr, wmipsDiff.clone_Instance( (*itSubBegin).first, pwmipiInst ));
  229. //
  230. // Update the "Change" property.
  231. //
  232. __MPC_EXIT_IF_METHOD_FAILS(hr, pwmipiInst->get_Change( pwmippChange ));
  233. __MPC_EXIT_IF_METHOD_FAILS(hr, pwmippChange->put_Data( VALUE_ADDED, fFound ));
  234. fDifferent = true;
  235. itSubBegin++;
  236. }
  237. }
  238. else
  239. {
  240. WMIParser::Cluster& subclusterNew = (*itClusterNew).second;
  241. WMIParser::Cluster& subclusterOld = (*itClusterOld).second;
  242. __MPC_EXIT_IF_METHOD_FAILS(hr, subclusterNew.Enum( itSubBegin, itSubEnd ));
  243. while(itSubBegin != itSubEnd)
  244. {
  245. pwmipiInst = (*itSubBegin).first;
  246. __MPC_EXIT_IF_METHOD_FAILS(hr, subclusterOld.Find( pwmipiInst, pwmipiInst2, fFound ));
  247. if(fFound == false)
  248. {
  249. //
  250. // Found an added instance ...
  251. //
  252. //
  253. // Copy it in the diff files, marking it as "Added".
  254. //
  255. __MPC_EXIT_IF_METHOD_FAILS(hr, wmipsDiff.clone_Instance( (*itSubBegin).first, pwmipiInst ));
  256. //
  257. // Update the "Change" property.
  258. //
  259. __MPC_EXIT_IF_METHOD_FAILS(hr, pwmipiInst->get_Change( pwmippChange ));
  260. __MPC_EXIT_IF_METHOD_FAILS(hr, pwmippChange->put_Data( VALUE_ADDED, fFound ));
  261. fDifferent = true;
  262. }
  263. else
  264. {
  265. //
  266. // Already checked for changes in two instances...
  267. //
  268. }
  269. itSubBegin++;
  270. }
  271. }
  272. }
  273. }
  274. //
  275. // Only save the delta if actually there are differences.
  276. //
  277. if(fDifferent)
  278. {
  279. //
  280. // Save the delta.
  281. //
  282. __MPC_EXIT_IF_METHOD_FAILS(hr, wmipsDiff.Save( SAFEBSTR( bstrFilenameDiff ) ));
  283. *pVal = VARIANT_TRUE;
  284. }
  285. else
  286. {
  287. *pVal = VARIANT_FALSE;
  288. }
  289. hr = S_OK;
  290. __HCP_FUNC_CLEANUP;
  291. __HCP_FUNC_EXIT(hr);
  292. }