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.

492 lines
12 KiB

  1. /*++
  2. Copyright (C) 1997-2001 Microsoft Corporation
  3. Module Name:
  4. Abstract:
  5. History:
  6. --*/
  7. //***************************************************************************
  8. //
  9. // REFRESH.CPP
  10. //
  11. // Contains a single sample global refresher
  12. //
  13. //***************************************************************************
  14. #include "precomp.h"
  15. #include <stdio.h>
  16. #include <wbemidl.h>
  17. #include <wbemint.h>
  18. #include "refresh.h"
  19. //***************************************************************************
  20. //
  21. // Local globals (!)
  22. //
  23. //***************************************************************************
  24. static DWORD g_dwNumObjects = 0;
  25. static IWbemRefresher *g_pRefresher = 0;
  26. static IWbemClassObject *g_aObjects[MAX_OBJECTS];
  27. static LONG g_aObjIDs[MAX_OBJECTS];
  28. static IWbemConfigureRefresher *g_pCfgRef = 0;
  29. //***************************************************************************
  30. //
  31. // CreateRefresher
  32. //
  33. //***************************************************************************
  34. BOOL CreateRefresher()
  35. {
  36. if (g_pCfgRef != 0)
  37. {
  38. printf("Refresher already created\n");
  39. return FALSE;
  40. }
  41. // Create an empty refresher.
  42. // ===========================
  43. DWORD dwRes = CoCreateInstance(CLSID_WbemRefresher, 0, CLSCTX_SERVER,
  44. IID_IWbemRefresher, (LPVOID *) &g_pRefresher);
  45. if (dwRes != S_OK)
  46. {
  47. printf("Failed to create a new refresher.\n");
  48. return FALSE;
  49. }
  50. // Create the refresher manager.
  51. // =============================
  52. dwRes = g_pRefresher->QueryInterface(IID_IWbemConfigureRefresher,
  53. (LPVOID *) &g_pCfgRef);
  54. if (dwRes)
  55. {
  56. g_pRefresher->Release();
  57. g_pRefresher = 0;
  58. printf("Failed to create the refresher manager\n");
  59. return FALSE;
  60. }
  61. return TRUE;
  62. }
  63. //***************************************************************************
  64. //
  65. // Refresh
  66. //
  67. // Called to refresh all the objects in the refresher.
  68. //
  69. //***************************************************************************
  70. // ok
  71. BOOL Refresh()
  72. {
  73. if (g_pRefresher == 0)
  74. {
  75. printf("No active refresher!\n");
  76. return FALSE;
  77. }
  78. HRESULT hRes = g_pRefresher->Refresh(0);
  79. if (hRes)
  80. return FALSE;
  81. return TRUE;
  82. }
  83. //***************************************************************************
  84. //
  85. // DestroyRefresher
  86. //
  87. //***************************************************************************
  88. // ok
  89. BOOL DestroyRefresher()
  90. {
  91. if (g_pRefresher == 0)
  92. {
  93. printf("No active refresher!\n");
  94. return FALSE;
  95. }
  96. g_pRefresher->Release();
  97. g_pRefresher = 0;
  98. g_pCfgRef->Release();
  99. g_pCfgRef = 0;
  100. for (DWORD i = 0; i < g_dwNumObjects; i++)
  101. {
  102. g_aObjIDs[i] = 0;
  103. g_aObjects[i]->Release();
  104. g_aObjects[i] = 0;
  105. }
  106. g_dwNumObjects = 0;
  107. return TRUE;
  108. }
  109. //***************************************************************************
  110. //
  111. // AddObject
  112. //
  113. // Adds an object to the refresher and returns its ID. The ID is
  114. // refresher specific (if more than one refresher is used, the
  115. // IDs can overlap).
  116. //
  117. // Parameters:
  118. // pSvc IWbemServices pointing to the correct namespace
  119. // pszPath The path to the object
  120. //
  121. // Return value:
  122. // TRUE on success, FALSE on fail.
  123. //
  124. //***************************************************************************
  125. // ok
  126. BOOL AddObject(
  127. IN IWbemServices *pSvc,
  128. IN LPWSTR pszPath
  129. )
  130. {
  131. LONG lObjId;
  132. if (g_pRefresher == 0)
  133. {
  134. printf("No active refresher!\n");
  135. return FALSE;
  136. }
  137. // Make sure there is room.
  138. // ========================
  139. if (g_dwNumObjects == MAX_OBJECTS)
  140. {
  141. printf("No more room in object array\n");
  142. return FALSE;
  143. }
  144. // Add the object to the refresher.
  145. // =================================
  146. IWbemClassObject *pRefreshableCopy = 0;
  147. HRESULT hRes = g_pCfgRef->AddObjectByPath(
  148. pSvc,
  149. pszPath,
  150. 0,
  151. 0,
  152. &pRefreshableCopy,
  153. &lObjId
  154. );
  155. // See if we succeeded.
  156. // ====================
  157. if (hRes)
  158. {
  159. printf("Failed to add object %S to refresher. WBEM error code = 0x%X\n",
  160. pszPath,
  161. hRes
  162. );
  163. return FALSE;
  164. }
  165. // Record the object and its id.
  166. // =============================
  167. g_aObjects[g_dwNumObjects] = pRefreshableCopy;
  168. g_aObjIDs[g_dwNumObjects] = lObjId;
  169. g_dwNumObjects++; // Keeps track of how many objects we have
  170. return TRUE;
  171. }
  172. //***************************************************************************
  173. //
  174. // RemoveObject
  175. //
  176. // Removes an object from the refresher.
  177. //
  178. //***************************************************************************
  179. // ok
  180. BOOL RemoveObject(IN LONG lObjId)
  181. {
  182. if (g_pRefresher == 0)
  183. {
  184. printf("No active refresher!\n");
  185. return FALSE;
  186. }
  187. // Remove the obejct from our local bookkeeping.
  188. // =============================================
  189. for (DWORD i = 0; i < g_dwNumObjects; i++)
  190. {
  191. if (g_aObjIDs[i] == lObjId)
  192. {
  193. g_aObjIDs[i] = 0; // Remove the ID
  194. g_aObjects[i]->Release(); // Release the object
  195. g_aObjects[i] = 0; // Zero it for purity
  196. // Remove this element from the two arrays.
  197. // ========================================
  198. for (DWORD i2 = i; i2 < g_dwNumObjects - 1; i2++)
  199. {
  200. g_aObjIDs[i2] = g_aObjIDs[i2 + 1];
  201. g_aObjects[i2] = g_aObjects[i2 + 1];
  202. }
  203. g_dwNumObjects--;
  204. }
  205. }
  206. // Officially remove the object from the WBEM refresher.
  207. // =====================================================
  208. HRESULT hRes = g_pCfgRef->Remove(
  209. lObjId,
  210. 0
  211. );
  212. if (hRes)
  213. {
  214. return FALSE;
  215. }
  216. return TRUE;
  217. }
  218. //***************************************************************************
  219. //
  220. // ShowObjectList
  221. //
  222. // Shows all the objects in the refresher.
  223. //
  224. //***************************************************************************
  225. BOOL ShowObjectList()
  226. {
  227. if (g_pRefresher == 0)
  228. {
  229. printf("No active refresher!\n");
  230. return FALSE;
  231. }
  232. BSTR PropName = SysAllocString(L"__RELPATH");
  233. for (DWORD i = 0; i < g_dwNumObjects; i++)
  234. {
  235. VARIANT v;
  236. VariantInit(&v);
  237. g_aObjects[i]->Get(PropName, 0, &v, 0, 0);
  238. printf("Object ID = %u Path = %S\n", g_aObjIDs[i], V_BSTR(&v));
  239. VariantClear(&v);
  240. }
  241. SysFreeString(PropName);
  242. printf("---Total of %u object(s)\n", g_dwNumObjects);
  243. return TRUE;
  244. }
  245. //***************************************************************************
  246. //
  247. // DumpObjectById
  248. //
  249. // Dumps the object's contents.
  250. //
  251. //***************************************************************************
  252. BOOL DumpObjectById(LONG lObjId)
  253. {
  254. for (DWORD i = 0; i < g_dwNumObjects; i++)
  255. {
  256. if (g_aObjIDs[i] == lObjId)
  257. {
  258. DumpObject(g_aObjects[i]);
  259. return TRUE;
  260. }
  261. }
  262. return FALSE;
  263. }
  264. //***************************************************************************
  265. //
  266. // DumpObject
  267. //
  268. // Dumps out the contents of the object.
  269. //
  270. //***************************************************************************
  271. BOOL DumpObject(IWbemClassObject *pObj)
  272. {
  273. DWORD i;
  274. BSTR PropNames[64] = {0};
  275. DWORD dwNumPropNames = 0;
  276. VARIANT v;
  277. VariantInit(&v);
  278. printf("----Object Dump----\n");
  279. // Print out the object path to identify it.
  280. // =========================================
  281. BSTR PropName = SysAllocString(L"__RELPATH");
  282. pObj->Get(PropName, 0, &v, 0, 0);
  283. printf("Path = %S\n", V_BSTR(&v));
  284. VariantClear(&v);
  285. SysFreeString(PropName);
  286. // Enumerate through the 'real' properties, ignoring
  287. // standard WBEM system properties.
  288. // =================================================
  289. pObj->BeginEnumeration(WBEM_FLAG_NONSYSTEM_ONLY);
  290. BSTR bstrName = 0;
  291. LONG vt = 0;
  292. while (WBEM_NO_ERROR == pObj->Next(0, &bstrName, &v, &vt, 0))
  293. {
  294. printf("Property = %S\t", bstrName);
  295. PropNames[dwNumPropNames++] = bstrName; // Save the name for later use
  296. switch (vt)
  297. {
  298. case VT_I4:
  299. printf("\tType = VT_I4\tValue = %d\n", V_I4(&v));
  300. break;
  301. case VT_UI4:
  302. printf("\tType = VT_UI4\tValue = %u\n", V_I4(&v));
  303. break;
  304. case VT_BSTR:
  305. printf("\tType = VT_BSTR\tValue = %S\n", V_BSTR(&v));
  306. break;
  307. // Note that VARIANTs can't hold 64-bit integers,
  308. // so we have to use BSTRs for this.
  309. // ==============================================
  310. case VT_I8:
  311. printf("\tType = VT_I8\tValue = %S\n", V_BSTR(&v));
  312. break;
  313. case VT_UI8:
  314. printf("\tType = VT_UI8\tValue = %S\n", V_BSTR(&v));
  315. break;
  316. default:
  317. printf("\tType = complex\n");
  318. }
  319. }
  320. pObj->EndEnumeration();
  321. // Next, we can get the property values if we know the names
  322. // ahead of time through a more efficient access mechanism.
  323. // Since we saved all the property names, we can use these
  324. // to get handles to the properties of interest. In this
  325. // case, we get handles for all the properties. In real life,
  326. // you would just use this for properties of interest to
  327. // the end user.
  328. // ==========================================================
  329. IWbemObjectAccess *pAccess = 0;
  330. pObj->QueryInterface(IID_IWbemObjectAccess, (LPVOID *) &pAccess);
  331. LONG Handles[64] = {0};
  332. LONG Types[64] = {0};
  333. for (i = 0; i < dwNumPropNames; i++)
  334. {
  335. // Get handles for each of the properties. We actually
  336. // only have to do this once and could reuse the handles
  337. // in the future between refreshes for all instances of
  338. // this class.
  339. // =====================================================
  340. pAccess->GetPropertyHandle(PropNames[i], &Types[i], &Handles[i]);
  341. }
  342. // We can now pull in the values by the handles.
  343. // Note that these handles can be 'saved' for use
  344. // with other instances or a newly refreshed generation
  345. // of the same instance.
  346. // =====================================================
  347. DWORD dwValue;
  348. unsigned __int64 qwValue;
  349. for (i = 0; i < dwNumPropNames; i++)
  350. {
  351. switch (Types[i])
  352. {
  353. case VT_I4:
  354. case VT_UI4:
  355. pAccess->ReadDWORD(Handles[i], &dwValue);
  356. printf("Property %S has value %u\n", PropNames[i], dwValue);
  357. break;
  358. case VT_I8:
  359. case VT_UI8:
  360. pAccess->ReadQWORD(Handles[i], &qwValue);
  361. printf("Property %S has value %lu\n", PropNames[i], qwValue);
  362. break;
  363. // Other types
  364. // ===========
  365. default:
  366. printf("Property %S is Non integral type.\n", PropNames[i]);
  367. // We could have used pAccess->ReadPropertyValue for this.
  368. }
  369. }
  370. // Done with the dump. Cleanup time.
  371. // ==================================
  372. pAccess->Release(); // Done with this interface
  373. for (i = 0; i < dwNumPropNames; i++)
  374. SysFreeString(PropNames[i]); // Free prop names
  375. // Go home.
  376. // ========
  377. return TRUE;
  378. }