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.

490 lines
11 KiB

  1. // Consumer.cpp: implementation of the CConsumer class.
  2. //
  3. // Copyright (c)1999-20000 Microsoft Corporation, All Rights Reserved
  4. //////////////////////////////////////////////////////////////////////
  5. #define HM_AGENT_INTERVAL 1000
  6. #include <atlbase.h>
  7. #include "hmagent.h"
  8. #include "system.h"
  9. #include "Consumer.h"
  10. #include <process.h>
  11. #include "global.h"
  12. extern CSystem* g_pSystem;
  13. extern HANDLE g_hConfigLock;
  14. extern HANDLE g_hThrdDie;
  15. extern HANDLE g_hThrdDead;
  16. //////////////////////////////////////////////////////////////////////
  17. // Construction/Destruction
  18. //////////////////////////////////////////////////////////////////////
  19. CConsumer::CConsumer()
  20. {
  21. // one and only instance of Consumer.
  22. MY_OUTPUT(L"ENTER CConsumer::CConsumer()", 1);
  23. m_cRef = 1;
  24. m_uThrdId = 0;
  25. m_hUpdateThrdFn = NULL;
  26. // Set the polling interval. Default to 1 sec. if the value is invalid
  27. m_lAgentInterval = HM_AGENT_INTERVAL;
  28. // If this ever fails, the agent will not be able to do any work
  29. if( (m_hUpdateThrdFn =
  30. (HANDLE)_beginthreadex(NULL, 0, Update, this, 0, &m_uThrdId)) ==0)
  31. {
  32. OutputDebugString(L"_beginthreadex FAILED! HM agent inactive\n");
  33. }
  34. MY_ASSERT(m_hUpdateThrdFn);
  35. }
  36. CConsumer::~CConsumer()
  37. {
  38. MY_OUTPUT(L"CConsumer::~CConsumer", 1);
  39. if(!SetEvent(g_hThrdDie))
  40. {
  41. DWORD dwErr = GetLastError();
  42. MY_OUTPUT(L"SetEvent for CConsumer failed with error ",dwErr);
  43. }
  44. // *** At this point, WBEM already terminated our thread.
  45. }
  46. // Static thread fuction to update data point.
  47. unsigned int __stdcall CConsumer::Update(void *pv)
  48. {
  49. CConsumer* pThis = (CConsumer*)pv;
  50. BOOL bRet = FALSE;
  51. while(1)
  52. {
  53. if (WAIT_OBJECT_0 == WaitForSingleObject(g_hThrdDie, pThis->m_lAgentInterval))
  54. {
  55. MY_OUTPUT(L"CConsumer::Update()-Told to die!", 1);
  56. SetEvent(g_hThrdDead);
  57. break;
  58. }
  59. if (WaitForSingleObject(g_hConfigLock, HM_ASYNC_TIMEOUT) != WAIT_OBJECT_0)
  60. {
  61. continue;
  62. }
  63. if (!g_pSystem)
  64. {
  65. ReleaseMutex(g_hConfigLock);
  66. continue;
  67. }
  68. bRet = g_pSystem->OnAgentInterval();
  69. ReleaseMutex(g_hConfigLock);
  70. }
  71. _endthreadex(0);
  72. return 0;
  73. }
  74. //////////////////////////////////////////////////////////////////////
  75. // IUnknown Implementation
  76. //////////////////////////////////////////////////////////////////////
  77. STDMETHODIMP CConsumer::QueryInterface(REFIID riid, LPVOID* ppv)
  78. {
  79. *ppv = NULL;
  80. if (riid == IID_IUnknown || riid == IID_IWbemUnboundObjectSink)
  81. {
  82. *ppv = this;
  83. AddRef();
  84. return S_OK;
  85. }
  86. return E_NOINTERFACE;
  87. }
  88. STDMETHODIMP_(ULONG) CConsumer::AddRef(void)
  89. {
  90. return InterlockedIncrement((long*)&m_cRef);
  91. }
  92. STDMETHODIMP_(ULONG) CConsumer::Release(void)
  93. {
  94. return InterlockedDecrement((long*)&m_cRef);
  95. }
  96. //////////////////////////////////////////////////////////////////////
  97. // IWbemUnboundObjectSink Implementation
  98. //////////////////////////////////////////////////////////////////////
  99. /////////////////////////////////////////////////////////////////////////////
  100. // IndicateToConsumer: Consumes following HealthMon events :
  101. // Timer Event, Threshold modification event(HMDataPoint),
  102. // and Category update event(HMStaticCatStatus).
  103. STDMETHODIMP CConsumer::IndicateToConsumer(IWbemClassObject* pLogicalConsumer,
  104. LONG lNumObjects, IWbemClassObject** ppObjects)
  105. {
  106. MY_OUTPUT(L"ENTER CConsumer::IndicateToConsumer()", 1);
  107. HRESULT hRes = S_OK;
  108. // WBEM may deliver multiple events
  109. for (long i = 0; i < lNumObjects; i++)
  110. {
  111. hRes = ProcessEvent(ppObjects[i]);
  112. if (FAILED(hRes))
  113. {
  114. MY_OUTPUT2(L"CConsumer::IndicateToConsumer() Failed tp process event: 0x%08x\n",hRes,4);
  115. }
  116. } // end for loop
  117. if (hRes == WBEM_E_NOT_FOUND) // ok, otherwise CIMOM will reque this event
  118. {
  119. hRes = S_OK;
  120. }
  121. MY_OUTPUT(L"EXIT CConsumer::IndicateToConsumer()", 1);
  122. return hRes;
  123. }
  124. //////////////////////////////////////////////////////////////////////
  125. // CConsumer Implementation
  126. //////////////////////////////////////////////////////////////////////
  127. /////////////////////////////////////////////////////////////////////////////
  128. // ProcessEvent: Processes CIMOM events
  129. //
  130. HRESULT CConsumer::ProcessEvent(IWbemClassObject* pClass)
  131. {
  132. VARIANT vDispatch;
  133. MY_OUTPUT(L"CConsumer::ProcessEvent()", 1);
  134. //
  135. // Decide if it is a Timer, Creation, Modification, Deletion or some type of event.
  136. //
  137. VariantInit(&vDispatch);
  138. HRESULT hRes = pClass->Get(L"TargetInstance", 0L, &vDispatch, 0, 0);
  139. switch (hRes)
  140. {
  141. case WBEM_E_NOT_FOUND:
  142. {
  143. // Timer Event
  144. hRes = S_OK;
  145. VariantClear(&vDispatch);
  146. break;
  147. }
  148. case WBEM_S_NO_ERROR:
  149. {
  150. IWbemClassObject* pTargetInstance = NULL;
  151. hRes = GetWbemClassObject(&pTargetInstance, &vDispatch);
  152. MY_HRESASSERT(hRes);
  153. if (SUCCEEDED(hRes))
  154. {
  155. hRes = ProcessModEvent(pClass, pTargetInstance);
  156. }
  157. if (pTargetInstance)
  158. {
  159. pTargetInstance->Release();
  160. }
  161. VariantClear(&vDispatch);
  162. break;
  163. }
  164. default:
  165. {
  166. MY_HRESASSERT(hRes);
  167. MY_OUTPUT2(L"CConsumer::ProcessEvent()-Unexpected Error: 0x%08x\n",hRes,4);
  168. break;
  169. }
  170. } // end switch
  171. return hRes;
  172. }
  173. /////////////////////////////////////////////////////////////////////////////
  174. // ProcessModEvent: Processes the inst. modification events
  175. //
  176. HRESULT CConsumer::ProcessModEvent(IWbemClassObject* pClass, IWbemClassObject* pInst)
  177. {
  178. TCHAR szParent[HM_MAX_PATH];
  179. TCHAR szChild[HM_MAX_PATH];
  180. CComVariant vInstClassName;
  181. CComVariant vOperationClassName;
  182. CComVariant vParent;
  183. CComVariant vChild;
  184. HRESULT hRes = S_OK;
  185. TCHAR *pszInstName = NULL;
  186. TCHAR *pszOperationName = NULL;
  187. BOOL bMod = FALSE;
  188. DWORD dwErr = 0;
  189. MY_OUTPUT(L"CConsumer::ProcessModEvent()", 1);
  190. // So we don't step on our toes.
  191. dwErr = WaitForSingleObject(g_hConfigLock, HM_ASYNC_TIMEOUT);
  192. if(dwErr != WAIT_OBJECT_0)
  193. {
  194. if(dwErr = WAIT_TIMEOUT)
  195. {
  196. TRACE_MUTEX(L"TIMEOUT MUTEX");
  197. return WBEM_S_TIMEDOUT;
  198. }
  199. else
  200. {
  201. MY_OUTPUT(L"WaitForSingleObject on Mutex failed",4);
  202. return WBEM_E_FAILED;
  203. }
  204. }
  205. if (!g_pSystem)
  206. {
  207. ReleaseMutex(g_hConfigLock);
  208. return hRes;
  209. }
  210. hRes = pInst->Get(L"__CLASS", 0L, &vInstClassName, 0L, 0L);
  211. if (FAILED(hRes))
  212. {
  213. MY_HRESASSERT(hRes);
  214. MY_OUTPUT(L"CConsumer::ValidateModEvent()-Unexpected Error!", 4);
  215. ReleaseMutex(g_hConfigLock);
  216. return hRes;
  217. }
  218. hRes = pClass->Get(L"__CLASS", 0L, &vOperationClassName, 0L, 0L);
  219. if (FAILED(hRes))
  220. {
  221. MY_HRESASSERT(hRes);
  222. MY_OUTPUT(L"CConsumer::ValidateModEvent()-Unexpected Error!", 4);
  223. ReleaseMutex(g_hConfigLock);
  224. return hRes;
  225. }
  226. pszInstName = V_BSTR(&vInstClassName);
  227. pszOperationName = V_BSTR(&vOperationClassName);
  228. MY_ASSERT(wcslen(pszInstName) > HM_PREFIX_LEN);
  229. if(wcscmp(pszOperationName, HM_MOD_CLASS_NAME)==0)
  230. {
  231. bMod = TRUE;
  232. }
  233. else
  234. {
  235. bMod = FALSE;
  236. }
  237. try
  238. {
  239. if (!wcscmp(L"SystemConfiguration", pszInstName+HM_PREFIX_LEN))
  240. {
  241. if (bMod)
  242. {
  243. hRes = g_pSystem->ModSystem(pInst);
  244. }
  245. else
  246. {
  247. //XXXSend out a CRITICAL MESSAGE, Tell them they need to re-install the agent
  248. MY_ASSERT(FALSE);
  249. hRes = S_FALSE;
  250. }
  251. }
  252. else if (!wcscmp(L"DataGroupConfiguration", pszInstName+HM_PREFIX_LEN))
  253. {
  254. if (bMod)
  255. {
  256. hRes = g_pSystem->ModDataGroup(pInst);
  257. }
  258. else
  259. {
  260. MY_ASSERT(FALSE);
  261. hRes = S_FALSE;
  262. }
  263. }
  264. else if (!wcscmp(L"PolledGetObjectDataCollectorConfiguration", pszInstName+HM_PREFIX_LEN))
  265. {
  266. if (bMod)
  267. {
  268. hRes = g_pSystem->ModDataCollector(pInst);
  269. }
  270. else
  271. {
  272. MY_ASSERT(FALSE);
  273. hRes = S_FALSE;
  274. }
  275. }
  276. else if (!wcscmp(L"PolledMethodDataCollectorConfiguration", pszInstName+HM_PREFIX_LEN))
  277. {
  278. if (bMod)
  279. {
  280. hRes = g_pSystem->ModDataCollector(pInst);
  281. }
  282. else
  283. {
  284. MY_ASSERT(FALSE);
  285. hRes = S_FALSE;
  286. }
  287. }
  288. else if (!wcscmp(L"PolledQueryDataCollectorConfiguration", pszInstName+HM_PREFIX_LEN))
  289. {
  290. if (bMod)
  291. {
  292. hRes = g_pSystem->ModDataCollector(pInst);
  293. }
  294. else
  295. {
  296. MY_ASSERT(FALSE);
  297. hRes = S_FALSE;
  298. }
  299. }
  300. else if (!wcscmp(L"EventQueryDataCollectorConfiguration", pszInstName+HM_PREFIX_LEN))
  301. {
  302. if (bMod)
  303. {
  304. hRes = g_pSystem->ModDataCollector(pInst);
  305. }
  306. else
  307. {
  308. MY_ASSERT(FALSE);
  309. hRes = S_FALSE;
  310. }
  311. }
  312. else if (!wcscmp(L"ThresholdConfiguration", pszInstName+HM_PREFIX_LEN))
  313. {
  314. if (bMod)
  315. {
  316. hRes = g_pSystem->ModThreshold(pInst);
  317. }
  318. else
  319. {
  320. MY_ASSERT(FALSE);
  321. hRes = S_FALSE;
  322. }
  323. }
  324. else if (!wcscmp(L"ActionConfiguration", pszInstName+HM_PREFIX_LEN))
  325. {
  326. if (bMod)
  327. {
  328. hRes = g_pSystem->ModAction(pInst);
  329. }
  330. else if (!wcscmp(L"__InstanceCreationEvent", pszOperationName))
  331. {
  332. hRes = g_pSystem->CreateAction(pInst);
  333. }
  334. else
  335. {
  336. MY_ASSERT(FALSE);
  337. hRes = S_FALSE;
  338. }
  339. }
  340. else if (!wcscmp(L"ConfigurationActionAssociation", pszInstName+HM_PREFIX_LEN))
  341. {
  342. if (bMod)
  343. {
  344. g_pSystem->ModActionAssociation(pInst);
  345. }
  346. else if (!wcscmp(L"__InstanceCreationEvent", pszOperationName))
  347. {
  348. g_pSystem->CreateActionAssociation(pInst);
  349. }
  350. else if (!wcscmp(L"__InstanceDeletionEvent", pszOperationName))
  351. {
  352. //XXX g_pSystem->DeleteActionAssociation(pInst);
  353. }
  354. else
  355. {
  356. MY_ASSERT(FALSE);
  357. hRes = S_FALSE;
  358. }
  359. }
  360. else if (!wcscmp(L"ConfigurationAssociation", pszInstName+HM_PREFIX_LEN))
  361. {
  362. if (!wcscmp(L"__InstanceCreationEvent", pszOperationName))
  363. {
  364. hRes = pInst->Get(L"ParentPath", 0L, &vParent, 0L, 0L);
  365. if (FAILED(hRes))
  366. {
  367. MY_HRESASSERT(hRes);
  368. }
  369. else
  370. {
  371. hRes = pInst->Get(L"ChildPath", 0L, &vChild, 0L, 0L);
  372. if (FAILED(hRes))
  373. {
  374. MY_HRESASSERT(hRes);
  375. }
  376. else
  377. {
  378. wcscpy(szParent, V_BSTR(&vParent));
  379. wcscpy(szChild, V_BSTR(&vChild));
  380. if (wcsstr(szParent, L"MicrosoftHM_SystemConfiguration") &&
  381. wcsstr(szChild, L"MicrosoftHM_DataGroupConfiguration"))
  382. {
  383. hRes = g_pSystem->CreateSystemDataGroupAssociation(pInst);
  384. }
  385. else if (wcsstr(szParent, L"MicrosoftHM_DataGroupConfiguration") &&
  386. wcsstr(szChild, L"MicrosoftHM_DataGroupConfiguration"))
  387. {
  388. hRes = g_pSystem->CreateDataGroupDataGroupAssociation(pInst);
  389. }
  390. else if (wcsstr(szParent, L"MicrosoftHM_DataGroupConfiguration") &&
  391. (wcsstr(szChild, L"MicrosoftHM_DataCollectorConfiguration") ||
  392. wcsstr(szChild, L"MicrosoftHM_PolledGetObjectDataCollectorConfiguration") ||
  393. wcsstr(szChild, L"MicrosoftHM_PolledMethodDataCollectorConfiguration") ||
  394. wcsstr(szChild, L"MicrosoftHM_PolledQueryDataCollectorConfiguration") ||
  395. wcsstr(szChild, L"MicrosoftHM_EventQueryDataCollectorConfiguration")
  396. ))
  397. {
  398. hRes = g_pSystem->CreateDataGroupDataCollectorAssociation(pInst);
  399. }
  400. else if ((wcsstr(szParent, L"MicrosoftHM_DataCollectorConfiguration") ||
  401. wcsstr(szParent, L"MicrosoftHM_PolledGetObjectDataCollectorConfiguration") ||
  402. wcsstr(szParent, L"MicrosoftHM_PolledMethodDataCollectorConfiguration") ||
  403. wcsstr(szParent, L"MicrosoftHM_PolledQueryDataCollectorConfiguration") ||
  404. wcsstr(szParent, L"MicrosoftHM_EventQueryDataCollectorConfiguration")
  405. ) &&
  406. wcsstr(szChild, L"MicrosoftHM_ThresholdConfiguration"))
  407. {
  408. hRes = g_pSystem->CreateDataCollectorThresholdAssociation(pInst);
  409. }
  410. }
  411. }
  412. }
  413. else
  414. {
  415. MY_ASSERT(FALSE);
  416. hRes = S_FALSE;
  417. }
  418. }
  419. else
  420. {
  421. MY_ASSERT(FALSE);
  422. hRes = S_FALSE;
  423. }
  424. }
  425. catch (...)
  426. {
  427. MY_ASSERT(FALSE);
  428. hRes = S_FALSE;
  429. }
  430. ReleaseMutex(g_hConfigLock);
  431. MY_OUTPUT(L"EXIT CConsumer::ProcessModEvent()", 1);
  432. return hRes;
  433. }