Source code of Windows XP (NT5)
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.

426 lines
11 KiB

  1. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // BVTREFRESH.CPP
  4. //
  5. //
  6. // Copyright (c)2000 Microsoft Corporation, All Rights Reserved
  7. //
  8. ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  9. #include <bvt.h>
  10. #include "BVTRefresh.h"
  11. ///////////////////////////////////////////////////////////////////
  12. //
  13. // Counter data
  14. //
  15. // These structures are used as a matter of convienience and
  16. // clarity. A real client should enumerate the properties
  17. // of an object in order to determine the number and names
  18. // of the counter properties.
  19. //
  20. ///////////////////////////////////////////////////////////////////
  21. // The number of counter properties for Win32_BasicHiPerf
  22. enum
  23. {
  24. Ctr1,
  25. Ctr2,
  26. Ctr3,
  27. Ctr4,
  28. Ctr5,
  29. NumCtrs
  30. };
  31. // The names and handles (set by SetHandles()) for a Win32_BasicHiPerf object
  32. struct CCounterData
  33. {
  34. WCHAR m_wcsName[256];
  35. long m_lHandle;
  36. } g_aCounters[] =
  37. {
  38. L"Counter1", 0,
  39. L"Counter2", 0,
  40. L"Counter3", 0,
  41. L"Counter4", 0,
  42. L"Counter5", 0,
  43. };
  44. ///////////////////////////////////////////////////////////////////
  45. //
  46. // CRefresher
  47. //
  48. ///////////////////////////////////////////////////////////////////
  49. CRefresher::CRefresher() : m_pNameSpace(NULL), m_pRefresher(NULL), m_pConfig(NULL)
  50. {
  51. }
  52. CRefresher::~CRefresher()
  53. {
  54. SAFE_RELEASE_PTR(m_pNameSpace);
  55. SAFE_RELEASE_PTR(m_pRefresher);
  56. SAFE_RELEASE_PTR(m_pConfig);
  57. }
  58. ///////////////////////////////////////////////////////////////////
  59. //
  60. // Helper methods
  61. //
  62. ///////////////////////////////////////////////////////////////////
  63. ///////////////////////////////////////////////////////////////////
  64. //
  65. // SetHandles will initialize the IWbemObjectAccess handle values
  66. // in the counter array.
  67. //
  68. // Returns a status code. Use the SUCCEEDED() and FAILED() macros
  69. // to interpret results.
  70. //
  71. ///////////////////////////////////////////////////////////////////
  72. HRESULT CRefresher::SetHandles(WCHAR * wcsClass)
  73. {
  74. HRESULT hr = WBEM_NO_ERROR;
  75. IWbemClassObject* pObj = NULL;
  76. long lIndex;
  77. // Get an IWbemObjectAccess interface to one of the sample objects
  78. // ===============================================================
  79. hr = m_pNameSpace->GetObject( CBSTR(wcsClass), 0, NULL, &pObj, NULL );
  80. if ( SUCCEEDED( hr ) )
  81. {
  82. // Get the alternate interface
  83. // ===========================
  84. IWbemObjectAccess* pAccess = NULL;
  85. hr = pObj->QueryInterface( IID_IWbemObjectAccess, ( LPVOID* )&pAccess );
  86. if( SUCCEEDED(hr))
  87. {
  88. // Set the access handles for all of the counter properties
  89. // ========================================================
  90. for ( lIndex = Ctr1; lIndex < NumCtrs; lIndex++ )
  91. {
  92. long lHandle;
  93. hr = pAccess->GetPropertyHandle( g_aCounters[lIndex].m_wcsName, NULL, &lHandle );
  94. if( SUCCEEDED(hr))
  95. {
  96. g_aCounters[lIndex].m_lHandle = lHandle;
  97. }
  98. }
  99. }
  100. SAFE_RELEASE_PTR(pAccess);
  101. }
  102. SAFE_RELEASE_PTR(pObj);
  103. return hr;
  104. }
  105. ///////////////////////////////////////////////////////////////////
  106. //
  107. // Class method API
  108. //
  109. ///////////////////////////////////////////////////////////////////
  110. ///////////////////////////////////////////////////////////////////
  111. //
  112. // Initialize will create the refresher and configuration manager
  113. // and set the IWbemObjectAccess handles which are used to access
  114. // property values of the instances.
  115. //
  116. // Returns a status code. Use the SUCCEEDED() and FAILED() macros
  117. // to interpret results.
  118. //
  119. ///////////////////////////////////////////////////////////////////
  120. HRESULT CRefresher::Initialize(IWbemServices* pNameSpace, WCHAR * wcsClass)
  121. {
  122. HRESULT hr = WBEM_NO_ERROR;
  123. // Copy the namespace pointer
  124. // ==========================
  125. if ( NULL == pNameSpace )
  126. {
  127. return WBEM_E_INVALID_PARAMETER;
  128. }
  129. m_pNameSpace = pNameSpace;
  130. m_pNameSpace->AddRef();
  131. // Create the refresher and refresher manager
  132. // ==========================================
  133. hr = CoCreateInstance( CLSID_WbemRefresher, NULL, CLSCTX_INPROC_SERVER, IID_IWbemRefresher, (void**) &m_pRefresher );
  134. if ( SUCCEEDED(hr))
  135. {
  136. hr = m_pRefresher->QueryInterface( IID_IWbemConfigureRefresher, (void**) &m_pConfig );
  137. if( SUCCEEDED(hr))
  138. {
  139. // Set the access handles
  140. // ======================
  141. hr = SetHandles(wcsClass);
  142. }
  143. }
  144. return hr;
  145. }
  146. ///////////////////////////////////////////////////////////////////
  147. //
  148. // AddObject will add a set of objects to the refresher. The
  149. // method will update m_aInstances with the instance data.
  150. //
  151. // Returns a status code. Use the SUCCEEDED() and FAILED() macros
  152. // to interpret results.
  153. //
  154. ///////////////////////////////////////////////////////////////////
  155. HRESULT CRefresher::AddObjects(WCHAR * wcsClass)
  156. {
  157. HRESULT hr = WBEM_NO_ERROR;
  158. long lIndex = 0;
  159. WCHAR wcsObjName[256];
  160. // Loop through all instances of the class and add them to the refresher
  161. // =============================================================================
  162. for ( lIndex = 0; lIndex < clNumInstances; lIndex++ )
  163. {
  164. IWbemClassObject* pObj = NULL;
  165. IWbemObjectAccess* pAccess = NULL;
  166. long lID;
  167. // Set the object path (e.g. Win32_BasicHiPerf=1)
  168. // ==============================================
  169. swprintf( wcsObjName, L"%s=%i", wcsClass, lIndex );
  170. // Add the object
  171. // ==============
  172. hr = m_pConfig->AddObjectByPath( m_pNameSpace, wcsObjName, 0, NULL, &pObj, &lID );
  173. if ( SUCCEEDED( hr ) )
  174. {
  175. // Save the IWbemObjectAccess interface
  176. // ====================================
  177. hr = pObj->QueryInterface( IID_IWbemObjectAccess, (void**) &pAccess );
  178. SAFE_RELEASE_PTR(pObj);
  179. m_Instances[lIndex].Set(pAccess, lID);
  180. // Set does it's own AddRef()
  181. // ==========================
  182. SAFE_RELEASE_PTR(pAccess);
  183. }
  184. }
  185. return hr;
  186. }
  187. ///////////////////////////////////////////////////////////////////
  188. //
  189. // RemoveObjects calls Remove() on the refresher's configuration
  190. // manager to remove all of the objects from the refresher.
  191. //
  192. // Returns a status code. Use the SUCCEEDED() and FAILED() macros
  193. // to interpret results.
  194. //
  195. ///////////////////////////////////////////////////////////////////
  196. HRESULT CRefresher::RemoveObjects()
  197. {
  198. HRESULT hr = WBEM_NO_ERROR;
  199. long lInstance = 0;
  200. // Remove the instances
  201. // ====================
  202. for ( lInstance = 0; lInstance < clNumInstances; lInstance++ )
  203. {
  204. m_pConfig->Remove( m_Instances[lInstance].GetID(), 0L );
  205. m_Instances[lInstance].Reset();
  206. }
  207. return hr;
  208. }
  209. ///////////////////////////////////////////////////////////////////
  210. //
  211. // ShowInstanceData will output all of the counter data for all
  212. // of the instances within the refresher.
  213. //
  214. // Returns a status code. Use the SUCCEEDED() and FAILED() macros
  215. // to interpret results.
  216. //
  217. ///////////////////////////////////////////////////////////////////
  218. HRESULT CRefresher::EnumerateObjectData()
  219. {
  220. HRESULT hr = WBEM_NO_ERROR;
  221. long lInstance;
  222. long lCounter;
  223. // Cycle through all of the instances and print all the counter data
  224. // =================================================================
  225. // Instance loop
  226. // =============
  227. for (lInstance = 0; lInstance < clNumInstances; lInstance++)
  228. {
  229. // Counter loop
  230. // ============
  231. for (lCounter = Ctr1; lCounter < NumCtrs; lCounter++)
  232. {
  233. DWORD dwVal;
  234. IWbemObjectAccess* pAccess = m_Instances[lInstance].GetMember();
  235. // Read the counter property value using the high performance IWbemObjectAccess->ReadDWORD().
  236. // NOTE: Remember to never to this while a refresh is in process!
  237. // ==========================================================================================
  238. hr = pAccess->ReadDWORD( g_aCounters[lCounter].m_lHandle, &dwVal);
  239. if (FAILED(hr))
  240. {
  241. break;
  242. }
  243. SAFE_RELEASE_PTR(pAccess);
  244. }
  245. }
  246. return hr;
  247. }
  248. ///////////////////////////////////////////////////////////////////
  249. //
  250. // AddEnum will add an enumerator to the refresher. The
  251. // function will return a status code. The enumerator class member
  252. // will updated.
  253. //
  254. // Returns a status code. Use the SUCCEEDED() and FAILED() macros
  255. // to interpret results.
  256. //
  257. ///////////////////////////////////////////////////////////////////
  258. HRESULT CRefresher::AddEnum(WCHAR * wcsClass)
  259. {
  260. HRESULT hr = WBEM_NO_ERROR;
  261. IWbemHiPerfEnum* pEnum = NULL;
  262. long lID;
  263. // Add an enumerator to the refresher
  264. // ==================================
  265. hr = m_pConfig->AddEnum( m_pNameSpace,wcsClass, 0, NULL, &pEnum, &lID );
  266. m_Enum.Set(pEnum, lID);
  267. // Set does it's own AddRef
  268. // ========================
  269. SAFE_RELEASE_PTR(pEnum);
  270. return hr;
  271. }
  272. ///////////////////////////////////////////////////////////////////
  273. //
  274. // RemoveEnum calls Remove() on the refresher's configuration
  275. // manager to remove the enumerator from the refresher.
  276. //
  277. // Returns a status code. Use the SUCCEEDED() and FAILED() macros
  278. // to interpret results.
  279. //
  280. ///////////////////////////////////////////////////////////////////
  281. HRESULT CRefresher::RemoveEnum()
  282. {
  283. HRESULT hr = WBEM_NO_ERROR;
  284. // Remove the enumerator
  285. // =====================
  286. hr = m_pConfig->Remove( m_Enum.GetID(), 0L );
  287. m_Enum.Reset();
  288. return hr;
  289. }
  290. ///////////////////////////////////////////////////////////////////
  291. //
  292. // ShowEnumeratorData will output the number of instances within
  293. // an enumerator. Property values from the instances may obtained
  294. // using the standard WMI methods.
  295. //
  296. // Returns a status code. Use the SUCCEEDED() and FAILED() macros
  297. // to interpret results.
  298. //
  299. ///////////////////////////////////////////////////////////////////
  300. HRESULT CRefresher::EnumerateEnumeratorData()
  301. {
  302. HRESULT hr = WBEM_NO_ERROR;
  303. DWORD dwNumReturned = clNumInstances;
  304. DWORD dwNumObjects = 0;
  305. IWbemObjectAccess** apEnumAccess = NULL;
  306. IWbemHiPerfEnum* pEnum = m_Enum.GetMember();
  307. // Fetch the instances from the enumerator
  308. // =======================================
  309. // Try to get the instances from the enumerator
  310. // ============================================
  311. hr = pEnum->GetObjects( 0L, dwNumObjects, apEnumAccess, &dwNumReturned );
  312. // Is the buffer too small?
  313. // ========================
  314. if ( WBEM_E_BUFFER_TOO_SMALL == hr )
  315. {
  316. // Increase the buffer size
  317. // ========================
  318. delete [] apEnumAccess;
  319. apEnumAccess = new IWbemObjectAccess*[dwNumReturned];
  320. dwNumObjects = dwNumReturned;
  321. memset( apEnumAccess, 0, sizeof( apEnumAccess ));
  322. if ( NULL != apEnumAccess )
  323. {
  324. hr = pEnum->GetObjects( 0L, dwNumObjects, apEnumAccess, &dwNumReturned );
  325. }
  326. else
  327. {
  328. hr = WBEM_E_OUT_OF_MEMORY;
  329. }
  330. }
  331. // Release the objects from the enumerator's object array
  332. // ======================================================
  333. for ( DWORD nCtr = 0; nCtr < dwNumReturned; nCtr++ )
  334. {
  335. if (NULL != apEnumAccess[nCtr])
  336. {
  337. apEnumAccess[nCtr]->Release();
  338. apEnumAccess[nCtr] = NULL;
  339. }
  340. }
  341. if ( NULL != apEnumAccess )
  342. delete [] apEnumAccess;
  343. pEnum->Release();
  344. return hr;
  345. }
  346. HRESULT CRefresher::Refresh()
  347. ///////////////////////////////////////////////////////////////////
  348. //
  349. // Refresh simply calls the IWbemRefresher->Refresh() method to
  350. // update all members of the refresher.
  351. //
  352. // Returns a status code. Use the SUCCEEDED() and FAILED() macros
  353. // to interpret results.
  354. //
  355. ///////////////////////////////////////////////////////////////////
  356. {
  357. return m_pRefresher->Refresh( 0L );
  358. }