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.

765 lines
20 KiB

  1. //***************************************************************************
  2. //
  3. // EQDE.CPP
  4. //
  5. // Module: HEALTHMON SERVER AGENT
  6. //
  7. // Purpose: CEventQueryDataCollector class to do WMI instance collection.
  8. //
  9. // Copyright (c)1999 Microsoft Corporation, All Rights Reserved
  10. //
  11. //***************************************************************************
  12. #include "eqde.h"
  13. #include "system.h"
  14. extern CSystem* g_pSystem;
  15. //////////////////////////////////////////////////////////////////////
  16. //////////////////////////////////////////////////////////////////////
  17. // Construction/Destruction
  18. //////////////////////////////////////////////////////////////////////
  19. CEventQueryDataCollector::CEventQueryDataCollector()
  20. {
  21. MY_OUTPUT(L"ENTER ***** CEventQueryDataCollector...", 4);
  22. m_pTempSink = NULL;
  23. m_deType = HM_EQDE;
  24. m_szQuery = NULL;
  25. m_lNumInstancesCollected = 0;
  26. m_hResLast = 0;
  27. MY_OUTPUT(L"EXIT ***** CEventQueryDataCollector...", 4);
  28. }
  29. CEventQueryDataCollector::~CEventQueryDataCollector()
  30. {
  31. MY_OUTPUT(L"ENTER ***** ~CEventQueryDataCollector...", 4);
  32. if (m_szQuery)
  33. delete [] m_szQuery;
  34. if (m_pTempSink)
  35. {
  36. m_pIWbemServices->CancelAsyncCall((IWbemObjectSink*)m_pTempSink);
  37. m_pTempSink->Release();
  38. m_pTempSink = NULL;
  39. }
  40. EnumDone();
  41. MY_OUTPUT(L"EXIT ***** ~CEventQueryDataCollector...", 4);
  42. }
  43. //
  44. // Load a single DataCollector, and everything under it.
  45. //
  46. HRESULT CEventQueryDataCollector::LoadInstanceFromMOF(IWbemClassObject* pObj, CDataGroup *pParentDG, LPTSTR pszParentObjPath, BOOL bModifyPass/*FALSE*/)
  47. {
  48. TCHAR szQuery[4096];
  49. BSTR Language = NULL;
  50. BSTR Query = NULL;
  51. BSTR bstrClassName = NULL;
  52. IEnumWbemClassObject *pEnumDataPoints = NULL;
  53. IWbemClassObject *pDataPoint = NULL;
  54. IWbemLocator *pLocator = NULL;
  55. BOOL bRetValue = TRUE;
  56. HRESULT hRetRes = S_OK;
  57. IWbemClassObject *pClass = NULL;
  58. IWbemQualifierSet *pQSet = NULL;
  59. BSTR PathToClass = NULL;
  60. VARIANT v;
  61. BSTR bstrError = NULL;
  62. BSTR bstrWarning = NULL;
  63. BSTR bstrInformation = NULL;
  64. BSTR bstrAuditSuccess = NULL;
  65. BSTR bstrAuditFailure = NULL;
  66. SAFEARRAY* psa = NULL;
  67. LCID lcID;
  68. VariantInit(&v);
  69. int i, iSize;
  70. CThreshold* pThreshold;
  71. MY_OUTPUT(L"ENTER ***** CEventQueryDataCollector::LoadInstanceFromMOF...", 4);
  72. iSize = m_thresholdList.size();
  73. for (i = 0; i < iSize ; i++)
  74. {
  75. MY_ASSERT(i<m_thresholdList.size());
  76. pThreshold = m_thresholdList[i];
  77. if (pThreshold->m_bValidLoad == FALSE)
  78. return WBEM_E_INVALID_OBJECT;
  79. // return S_OK;
  80. }
  81. if (m_szQuery)
  82. {
  83. delete [] m_szQuery;
  84. m_szQuery = NULL;
  85. }
  86. m_lNumInstancesCollected = 0;
  87. if (m_pTempSink)
  88. {
  89. m_pIWbemServices->CancelAsyncCall((IWbemObjectSink*)m_pTempSink);
  90. m_pTempSink->Release();
  91. m_pTempSink = NULL;
  92. }
  93. //
  94. // Call the base class to load the common properties. Then do the specific ones.
  95. //
  96. hRetRes = CDataCollector::LoadInstanceFromMOF(pObj, pParentDG, pszParentObjPath, bModifyPass);
  97. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) return hRetRes;
  98. // Get the GUID property
  99. hRetRes = GetStrProperty(pObj, L"Query", &m_szQuery);
  100. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  101. //OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
  102. //
  103. // On non-English machines we must alter the query that uses Win32_NtLogEvent class.
  104. // Whistler will have evnttype property that is a uint8 to use, instead of the Type property.
  105. //
  106. lcID = PRIMARYLANGID(GetSystemDefaultLCID());
  107. wcsncpy(szQuery, m_szQuery, 4095);
  108. szQuery[4095] = '\0';
  109. _wcsupr(szQuery);
  110. if (!(lcID != 0 && lcID == 0x00000009) &&
  111. wcsstr(szQuery, L"WIN32_NTLOGEVENT"))
  112. {
  113. // Get the class definition.
  114. PathToClass = SysAllocString(L"Win32_NTLogEvent");
  115. MY_ASSERT(PathToClass); if (!PathToClass) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  116. hRetRes = g_pIWbemServicesCIMV2->GetObject(PathToClass, WBEM_FLAG_USE_AMENDED_QUALIFIERS, 0, &pClass, 0);
  117. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  118. SysFreeString(PathToClass); PathToClass=NULL;
  119. hRetRes = pClass->GetPropertyQualifierSet(L"Type", &pQSet);
  120. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  121. pClass->Release(); pClass = NULL;
  122. hRetRes = pQSet->Get(L"Values", 0, &v, 0);
  123. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  124. psa = V_ARRAY(&v);
  125. BSTR *pBstr = 0;
  126. hRetRes = SafeArrayAccessData(psa, (void**) &pBstr);
  127. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  128. bstrError = pBstr[psa->rgsabound[0].lLbound];
  129. bstrWarning = pBstr[psa->rgsabound[0].lLbound + 1];
  130. bstrInformation = pBstr[psa->rgsabound[0].lLbound + 2];
  131. bstrAuditSuccess = pBstr[psa->rgsabound[0].lLbound + 3];
  132. bstrAuditFailure = pBstr[psa->rgsabound[0].lLbound + 4];
  133. hRetRes = ReplaceStr(&m_szQuery, L"ERROR", bstrError);
  134. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  135. hRetRes = ReplaceStr(&m_szQuery, L"WARNING", bstrWarning);
  136. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  137. hRetRes = ReplaceStr(&m_szQuery, L"INFORMATION", bstrInformation);
  138. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  139. hRetRes = ReplaceStr(&m_szQuery, L"AUDIT SUCCESS", bstrAuditSuccess);
  140. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  141. hRetRes = ReplaceStr(&m_szQuery, L"AUDIT FAILURE", bstrAuditFailure);
  142. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  143. SafeArrayUnaccessData(psa);
  144. psa = NULL;
  145. pQSet->Release(); pQSet = NULL;
  146. }
  147. //OOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO
  148. wcsncpy(szQuery, m_szQuery, 4095);
  149. szQuery[4095] = '\0';
  150. _wcsupr(szQuery);
  151. if (wcsstr(szQuery, L"INSTANCECREATIONEVENT") || wcsstr(szQuery, L"CLASSCREATIONEVENT"))
  152. {
  153. m_bInstCreationQuery = TRUE;
  154. }
  155. else
  156. {
  157. m_bInstCreationQuery = FALSE;
  158. }
  159. //
  160. // Setup the event query
  161. //
  162. if (m_bEnabled==TRUE && m_bParentEnabled==TRUE)
  163. {
  164. Language = SysAllocString(L"WQL");
  165. MY_ASSERT(Language); if (!Language) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  166. Query = SysAllocString(m_szQuery);
  167. MY_ASSERT(Query); if (!Query) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  168. hRetRes = 1;
  169. m_hResLast = 0;
  170. if (m_pIWbemServices != NULL)
  171. {
  172. m_pTempSink = new CTempConsumer(this);
  173. MY_ASSERT(m_pTempSink); if (!m_pTempSink) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  174. hRetRes = m_pIWbemServices->ExecNotificationQueryAsync(
  175. Language,
  176. Query,
  177. 0,
  178. m_pContext,
  179. m_pTempSink);
  180. m_hResLast = hRetRes;
  181. }
  182. SysFreeString(Language);
  183. Language = NULL;
  184. SysFreeString(Query);
  185. Query = NULL;
  186. TCHAR buf[256];
  187. wsprintf(buf, L"BAD ExecNotificationQueryAsync: 0x%08x", hRetRes);
  188. MY_OUTPUT(buf, 4);
  189. if (hRetRes != WBEM_S_NO_ERROR)
  190. {
  191. if (m_pTempSink)
  192. {
  193. m_pTempSink->Release();
  194. m_pTempSink = NULL;
  195. }
  196. }
  197. else
  198. {
  199. MY_OUTPUT(L"GOOD ExecNotificationQueryAsync", 4);
  200. }
  201. }
  202. m_startTick = GetTickCount();
  203. m_lTryDelayTime = 120;
  204. MY_OUTPUT(L"EXIT ***** CEventQueryDataCollector::LoadInstanceFromMOF...", 4);
  205. return S_OK;
  206. error:
  207. MY_ASSERT(FALSE);
  208. if (PathToClass)
  209. SysFreeString(PathToClass);
  210. if (pClass)
  211. pClass->Release();
  212. if (pQSet)
  213. pQSet->Release();
  214. if (psa)
  215. SafeArrayUnaccessData(psa);
  216. if (Language)
  217. SysFreeString(Language);
  218. if (Query)
  219. SysFreeString(Query);
  220. m_bValidLoad = FALSE;
  221. Cleanup(FALSE);
  222. return hRetRes;
  223. }
  224. //
  225. // Event based data collectors work in a bit different manner than the polled data collectors.
  226. // Specifically we collect all the instances as them come into the HandleTempEvent function,
  227. // and then at the collection interval we evaluate each one in turn, serialy, so we
  228. // end up with a state being what ever the last event was. We also only evaluate the Thresholds
  229. // that are across CollectionErrorCode, CollectionInstanceCount, CollectionErrorDescription.
  230. // We thus also only end up with potentially one single event after we evaluate all that came
  231. // in. That one can be used with action sending.
  232. // This also means that there is no such thing as multi-instance when it comes to Event
  233. // based data collectors.
  234. // We will keep that one last event around forever, as it represents the last thing we reveived,
  235. // get rid rid of it if the user does a RESET.
  236. // We get the events into a special holding vector, and transfer them over one at a time later,
  237. // at the interval when we do the evaluation.
  238. //
  239. BOOL CEventQueryDataCollector::CollectInstance(void)
  240. {
  241. HRESULT hRetRes = S_OK;
  242. BSTR Language = NULL;
  243. BSTR Query = NULL;
  244. DWORD currTick;
  245. MY_OUTPUT(L"ENTER ***** CEventQueryDataCollector::CollectInstance...", 1);
  246. //
  247. // Try and fix up queries that failed to register for some reason.
  248. //
  249. if (m_bEnabled==TRUE && m_bParentEnabled==TRUE && m_pIWbemServices!=NULL &&
  250. m_hResLast!=0 && m_lTryDelayTime != -1)
  251. {
  252. // Do some time checking, to make a minute go by before try again in this case!
  253. currTick = GetTickCount();
  254. if ((m_lTryDelayTime*1000) < (currTick-m_startTick))
  255. {
  256. m_lTryDelayTime = -1;
  257. Language = SysAllocString(L"WQL");
  258. MY_ASSERT(Language); if (!Language) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  259. Query = SysAllocString(m_szQuery);
  260. MY_ASSERT(Query); if (!Query) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  261. m_pTempSink = new CTempConsumer(this);
  262. MY_ASSERT(m_pTempSink); if (!m_pTempSink) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  263. hRetRes = m_pIWbemServices->ExecNotificationQueryAsync(
  264. Language,
  265. Query,
  266. 0,
  267. m_pContext,
  268. m_pTempSink);
  269. m_hResLast = hRetRes;
  270. SysFreeString(Language);
  271. Language = NULL;
  272. SysFreeString(Query);
  273. Query = NULL;
  274. TCHAR buf[256];
  275. wsprintf(buf, L"BAD ExecNotificationQueryAsync: 0x%08x", hRetRes);
  276. MY_OUTPUT(buf, 4);
  277. if (hRetRes != WBEM_S_NO_ERROR)
  278. {
  279. MY_HRESASSERT(hRetRes);
  280. if (m_pTempSink)
  281. {
  282. m_pTempSink->Release();
  283. m_pTempSink = NULL;
  284. }
  285. }
  286. else
  287. {
  288. MY_OUTPUT(L"GOOD ExecNotificationQueryAsync", 4);
  289. }
  290. }
  291. }
  292. if (m_pIWbemServices == NULL)
  293. {
  294. m_ulErrorCode = HMRES_BADWMI;
  295. GetLatestAgentError(HMRES_BADWMI, m_szErrorDescription);
  296. StoreStandardProperties();
  297. return FALSE;
  298. }
  299. if (m_pTempSink == NULL)
  300. {
  301. m_ulErrorCode = m_hResLast;
  302. // GetLatestAgentError(HMRES_OBJECTNOTFOUND, m_szErrorDescription);
  303. GetLatestWMIError(HMRES_OBJECTNOTFOUND, m_ulErrorCode, m_szErrorDescription);
  304. StoreStandardProperties();
  305. return FALSE;
  306. }
  307. EnumDone();
  308. MY_OUTPUT(L"EXIT ***** CEventQueryDataCollector::CollectInstance...", 1);
  309. return TRUE;
  310. error:
  311. MY_ASSERT(FALSE);
  312. if (Language)
  313. SysFreeString(Language);
  314. if (Query)
  315. SysFreeString(Query);
  316. m_bValidLoad = FALSE;
  317. Cleanup(FALSE);
  318. return hRetRes;
  319. }
  320. BOOL CEventQueryDataCollector::HandleTempEvent(IWbemClassObject* pObj)
  321. {
  322. TCHAR szTemp[4096];
  323. HRESULT hRes;
  324. SAFEARRAY *psaNames = NULL;
  325. BSTR PropName = NULL;
  326. VARIANT vDispatch;
  327. VARIANT v;
  328. IWbemClassObject* pTargetInstance = NULL;
  329. INSTSTRUCT inst;
  330. long lIntervalCountTemp;
  331. long lNumInstancesCollectedTemp;
  332. BOOL bEmbeddedEvent;
  333. HOLDINSTSTRUCT holdInst;
  334. VariantInit(&v);
  335. VariantInit(&vDispatch);
  336. MY_OUTPUT(L"ENTER ***** CEventQueryDataCollector::HandleTempEvent...", 4);
  337. if (m_bValidLoad == FALSE)
  338. return FALSE;
  339. // We can't open ourselves up to an unlimited number of instances flooding in.
  340. // Set the message error, and when we get to the collection interval it will be sent out
  341. if (g_pSystem->m_lNumInstancesAccepted < m_lNumInstancesCollected)
  342. {
  343. if (m_ulErrorCode != HMRES_TOOMANYINSTS)
  344. {
  345. lIntervalCountTemp = m_lIntervalCount;
  346. lNumInstancesCollectedTemp = m_lNumInstancesCollected;
  347. ResetState(FALSE, FALSE);
  348. m_lIntervalCount = lIntervalCountTemp;
  349. m_lNumInstancesCollected = lNumInstancesCollectedTemp;
  350. }
  351. else
  352. {
  353. EnumDone();
  354. }
  355. m_ulErrorCode = HMRES_TOOMANYINSTS;
  356. GetLatestAgentError(HMRES_TOOMANYINSTS, m_szErrorDescription);
  357. StoreStandardProperties();
  358. return TRUE;
  359. }
  360. //
  361. // Decide if this is an __InstanceXXXEvent. If it is grab the TargetInstance as the object
  362. // to use, else we have what we need in pObj as it is.
  363. //
  364. VariantInit(&v);
  365. hRes = pObj->Get(L"__CLASS", 0L, &v, 0L, 0L);
  366. if (FAILED(hRes))
  367. { // UNEXPECTED FAILURE!
  368. MY_OUTPUT2(L"CEQ Unexpected Error: 0x%08x\n",hRes,4);
  369. MY_OUTPUT2(L"m_szGUID was=%s",m_szGUID,4);
  370. MY_HRESASSERT(hRes);
  371. VariantClear(&v);
  372. return TRUE;
  373. }
  374. wcsncpy(szTemp, V_BSTR(&v), 4095);
  375. szTemp[4095] = '\0';
  376. _wcsupr(szTemp);
  377. if (wcsstr(szTemp, L"__INSTANCE") || wcsstr(szTemp, L"__CLASS"))
  378. {
  379. bEmbeddedEvent = TRUE;
  380. MY_OUTPUT(L"::HandleTempEvent -> Embedded event", 3);
  381. }
  382. else
  383. {
  384. bEmbeddedEvent = FALSE;
  385. m_bInstCreationQuery = TRUE;
  386. MY_OUTPUT(L"::HandleTempEvent -> NON Embedded event", 3);
  387. }
  388. VariantClear(&v);
  389. //
  390. //
  391. //
  392. if (bEmbeddedEvent == TRUE)
  393. {
  394. VariantInit(&vDispatch);
  395. if (wcsstr(szTemp, L"__INSTANCE"))
  396. hRes = pObj->Get(L"TargetInstance", 0L, &vDispatch, 0, 0);
  397. else if (wcsstr(szTemp, L"__CLASS"))
  398. hRes = pObj->Get(L"TargetClass", 0L, &vDispatch, 0, 0);
  399. else
  400. hRes = pObj->Get(L"TargetInstance", 0L, &vDispatch, 0, 0);
  401. hRes = GetWbemClassObject(&pTargetInstance, &vDispatch);
  402. }
  403. else
  404. {
  405. pTargetInstance = pObj;
  406. }
  407. if (SUCCEEDED(hRes))
  408. {
  409. m_lNumInstancesCollected++;
  410. holdInst.pEvent = NULL;
  411. hRes = pTargetInstance->Clone(&holdInst.pEvent);
  412. if (FAILED(hRes))
  413. {
  414. MY_ASSERT(FALSE);
  415. }
  416. else
  417. {
  418. m_holdList.push_back(holdInst);
  419. }
  420. if (bEmbeddedEvent == TRUE)
  421. {
  422. pTargetInstance->Release();
  423. }
  424. }
  425. else
  426. {
  427. MY_HRESASSERT(hRes);
  428. MY_OUTPUT2(L"CEQ Unexpected Error: 0x%08x\n",hRes,4);
  429. MY_OUTPUT2(L"m_szGUID was=%s",m_szGUID,4);
  430. }
  431. if (bEmbeddedEvent == TRUE)
  432. {
  433. VariantClear(&vDispatch);
  434. }
  435. m_ulErrorCode = 0;
  436. MY_OUTPUT(L"EXIT ***** CEventQueryDataCollector::HandleTempEvent...", 4);
  437. return TRUE;
  438. }
  439. BOOL CEventQueryDataCollector::CollectInstanceSemiSync(void)
  440. {
  441. MY_ASSERT(FALSE);
  442. return TRUE;
  443. }
  444. BOOL CEventQueryDataCollector::EnumDone(void)
  445. {
  446. IWbemClassObject *pObj = NULL;
  447. BOOL bRetValue = TRUE;
  448. PNSTRUCT *ppn;
  449. INSTSTRUCT inst;
  450. INSTSTRUCT *pinst;
  451. int i, j, iSize, jSize;
  452. CThreshold *pThreshold;
  453. SAFEARRAY *psaNames = NULL;
  454. BSTR PropName = NULL;
  455. ACTUALINSTSTRUCT *pActualInst;
  456. CleanupSemiSync();
  457. // If we got any new events in this collection interval, we can dump the old one.
  458. if (m_holdList.size())
  459. {
  460. //
  461. // Now loop through and get rid of instances that are no longer around
  462. //
  463. iSize = m_pnList.size();
  464. for (i = 0; i < iSize ; i++)
  465. {
  466. MY_ASSERT(i<m_pnList.size());
  467. ppn = &m_pnList[i];
  468. jSize = ppn->instList.size();
  469. for (j = 0; j < jSize ; j++)
  470. {
  471. MY_ASSERT(j<ppn->instList.size());
  472. pinst = &ppn->instList[j];
  473. if (pinst->szCurrValue)
  474. delete [] pinst->szCurrValue;
  475. if (pinst->szInstanceID)
  476. delete [] pinst->szInstanceID;
  477. pinst->valList.clear();
  478. }
  479. ppn->instList.clear();
  480. }
  481. // Also for all thresholds under this DataCollector
  482. iSize = m_thresholdList.size();
  483. for (i = 0; i < iSize ; i++)
  484. {
  485. MY_ASSERT(i<m_thresholdList.size());
  486. pThreshold = m_thresholdList[i];
  487. pThreshold->ClearInstList();
  488. }
  489. iSize = m_actualInstList.size();
  490. for (i=0; i < iSize; i++)
  491. {
  492. MY_ASSERT(i<m_actualInstList.size());
  493. pActualInst = &m_actualInstList[i];
  494. if (pActualInst->szInstanceID)
  495. delete [] pActualInst->szInstanceID;
  496. if (pActualInst->pInst)
  497. {
  498. pActualInst->pInst->Release();
  499. pActualInst->pInst = NULL;
  500. }
  501. }
  502. m_actualInstList.clear();
  503. //XXXOnce again take common code and place it in the base class!^^^^^^^^^^^^^^^^^^^^^^^^^
  504. }
  505. return TRUE;
  506. }
  507. BOOL CEventQueryDataCollector::CleanupSemiSync(void)
  508. {
  509. m_bKeepCollectingSemiSync = FALSE;
  510. m_lCollectionTimeOutCount = 0;
  511. return TRUE;
  512. }
  513. BOOL CEventQueryDataCollector::EvaluateThresholds(BOOL bIgnoreReset, BOOL bSkipStatndard, BOOL bSkipOthers, BOOL bDoThresholdSkipClean)
  514. {
  515. HRESULT hRes;
  516. LPTSTR pszID = NULL;
  517. TCHAR szID[32];
  518. TCHAR szID2[32];
  519. HOLDINSTSTRUCT *pHoldInst;
  520. int i, iSize;
  521. long lPrevState;
  522. long lNumberChanges = 0;
  523. // Need to keep track of the overall prev state of the DC so that DG can roll up changes
  524. lPrevState = m_lCurrState;
  525. //
  526. // Feed each temp event in one at a time from the special holding vector
  527. //
  528. iSize = m_holdList.size();
  529. if (iSize > 0)
  530. {
  531. wcscpy(m_szDTCollectTime, m_szDTCurrTime);
  532. wcscpy(m_szCollectTime, m_szCurrTime);
  533. }
  534. //XXXIs this risky???We do not need to do anything because we did not receive any events!!!
  535. // if (iSize==0)
  536. // return TRUE;
  537. for (i=0; i<iSize; i++)
  538. {
  539. m_lPrevState = m_lCurrState;
  540. m_lNumberChanges = 0;
  541. // m_ulErrorCode = 0;
  542. // m_szErrorDescription[0] = '\0';
  543. MY_ASSERT(i<m_holdList.size());
  544. pHoldInst = &m_holdList[i];
  545. MY_ASSERT(pHoldInst->pEvent);
  546. //
  547. // Figure out the key property name to identify instances with.
  548. //
  549. if (m_bInstCreationQuery == TRUE)
  550. {
  551. wsprintf(szID, L"(%5d)", i);
  552. }
  553. else
  554. {
  555. hRes = GetInstanceID(pHoldInst->pEvent, &pszID);
  556. if (hRes != S_OK)
  557. {
  558. m_ulErrorCode = hRes;
  559. GetLatestWMIError(HMRES_OBJECTNOTFOUND, hRes, m_szErrorDescription);
  560. StoreStandardProperties();
  561. EnumDone();
  562. return FALSE;
  563. }
  564. wsprintf(szID2, L"%s(%5d)", pszID, i);
  565. wcscpy(szID, szID2);
  566. delete [] pszID;
  567. }
  568. //
  569. // Mark instances need to keep around, and add new ones
  570. //
  571. hRes = CheckInstanceExistance(pHoldInst->pEvent, szID);
  572. if (hRes != S_OK)
  573. {
  574. m_ulErrorCode = hRes;
  575. GetLatestWMIError(HMRES_OBJECTNOTFOUND, hRes, m_szErrorDescription);
  576. StoreStandardProperties();
  577. EnumDone();
  578. return FALSE;
  579. }
  580. StoreValues(pHoldInst->pEvent, szID);
  581. CDataCollector::EvaluateThresholds(bIgnoreReset, TRUE, FALSE, TRUE);
  582. SendEvents();
  583. lNumberChanges += m_lNumberChanges;
  584. if (pHoldInst->pEvent)
  585. {
  586. pHoldInst->pEvent->Release();
  587. pHoldInst->pEvent = NULL;
  588. }
  589. // Keep clearing out the event info, unless it is the last one, which we
  590. // want to keep around, as it represents the final state.
  591. if (i < iSize-1)
  592. {
  593. EnumDone();
  594. }
  595. }
  596. m_holdList.clear();
  597. // Need to be able to independantly send out events for standard property violations
  598. m_lPrevState = lPrevState;
  599. m_lCurrState = lPrevState;
  600. m_lNumberChanges = 0;
  601. // m_ulErrorCode = 0;
  602. // m_szErrorDescription[0] = '\0';
  603. StoreStandardProperties();
  604. CDataCollector::EvaluateThresholds(bIgnoreReset, FALSE, TRUE, TRUE);
  605. SendEvents();
  606. lNumberChanges += m_lNumberChanges;
  607. FireStatisticsEvent();
  608. // Need to keep track of the overall prev state of the DC so that DG can roll up changes
  609. m_lPrevState = lPrevState;
  610. m_lNumberChanges = lNumberChanges;
  611. return TRUE;
  612. }
  613. BOOL CEventQueryDataCollector::SetParentEnabledFlag(BOOL bEnabled)
  614. {
  615. BSTR Language = NULL;
  616. BSTR Query = NULL;
  617. HRESULT hRetRes = S_OK;
  618. CDataCollector::SetParentEnabledFlag(bEnabled);
  619. m_lNumInstancesCollected = 0;
  620. if (m_pTempSink)
  621. {
  622. m_pIWbemServices->CancelAsyncCall((IWbemObjectSink*)m_pTempSink);
  623. m_pTempSink->Release();
  624. m_pTempSink = NULL;
  625. }
  626. //
  627. // Setup the event query
  628. //
  629. if (m_bEnabled==TRUE && m_bParentEnabled==TRUE)
  630. {
  631. Language = SysAllocString(L"WQL");
  632. MY_ASSERT(Language); if (!Language) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  633. Query = SysAllocString(m_szQuery);
  634. MY_ASSERT(Query); if (!Query) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  635. hRetRes = 1;
  636. m_hResLast = 0;
  637. if (m_pIWbemServices != NULL)
  638. {
  639. m_pTempSink = new CTempConsumer(this);
  640. MY_ASSERT(m_pTempSink); if (!m_pTempSink) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  641. hRetRes = m_pIWbemServices->ExecNotificationQueryAsync(
  642. Language,
  643. Query,
  644. 0,
  645. m_pContext,
  646. m_pTempSink);
  647. m_hResLast = hRetRes;
  648. }
  649. SysFreeString(Language);
  650. Language = NULL;
  651. SysFreeString(Query);
  652. Query = NULL;
  653. TCHAR buf[256];
  654. wsprintf(buf, L"BAD ExecNotificationQueryAsync: 0x%08x", hRetRes);
  655. MY_OUTPUT(buf, 4);
  656. if (hRetRes != WBEM_S_NO_ERROR)
  657. {
  658. if (m_pTempSink)
  659. {
  660. m_pTempSink->Release();
  661. m_pTempSink = NULL;
  662. }
  663. }
  664. else
  665. {
  666. MY_OUTPUT(L"GOOD ExecNotificationQueryAsync", 4);
  667. }
  668. }
  669. m_startTick = GetTickCount();
  670. m_lTryDelayTime = 120;
  671. return TRUE;
  672. error:
  673. MY_ASSERT(FALSE);
  674. if (Language)
  675. SysFreeString(Language);
  676. if (Query)
  677. SysFreeString(Query);
  678. m_bValidLoad = FALSE;
  679. Cleanup(FALSE);
  680. return hRetRes;
  681. }