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.

801 lines
18 KiB

  1. //***************************************************************************
  2. //
  3. // PGDE.CPP
  4. //
  5. // Module: HEALTHMON SERVER AGENT
  6. //
  7. // Purpose: CPolledGetObjectDataCollector class to do WMI instance collection.
  8. //
  9. // Copyright (c)1999 Microsoft Corporation, All Rights Reserved
  10. //
  11. //***************************************************************************
  12. #include "pgde.h"
  13. #include "system.h"
  14. extern CSystem* g_pSystem;
  15. //////////////////////////////////////////////////////////////////////
  16. //////////////////////////////////////////////////////////////////////
  17. // Construction/Destruction
  18. //////////////////////////////////////////////////////////////////////
  19. CPolledGetObjectDataCollector::CPolledGetObjectDataCollector()
  20. {
  21. MY_OUTPUT(L"ENTER ***** CPolledGetObjectDataCollector...", 1);
  22. m_pRefresher = NULL;
  23. m_pConfigureRefresher = NULL;
  24. m_pEnum = NULL;
  25. m_pObjAccess = NULL;
  26. m_lId = 0;
  27. m_szObjectPath = NULL;
  28. m_deType = HM_PGDE;
  29. m_lNumInstancesCollected = 0;
  30. m_pEnumObjs = NULL;
  31. m_pCallResult = NULL;
  32. MY_OUTPUT(L"EXIT ***** CPolledGetObjectDataCollector...", 1);
  33. }
  34. CPolledGetObjectDataCollector::~CPolledGetObjectDataCollector()
  35. {
  36. MY_OUTPUT(L"ENTER ***** ~CPolledGetObjectDataCollector...", 1);
  37. if (m_szObjectPath)
  38. {
  39. delete [] m_szObjectPath;
  40. }
  41. if (m_pRefresher != NULL)
  42. {
  43. m_pRefresher->Release();
  44. m_pRefresher = NULL;
  45. }
  46. if (m_pConfigureRefresher != NULL)
  47. {
  48. m_pConfigureRefresher->Release();
  49. m_pConfigureRefresher = NULL;
  50. }
  51. if (m_pEnum != NULL)
  52. {
  53. m_pEnum->Release();
  54. m_pEnum = NULL;
  55. }
  56. if (m_pObjAccess != NULL)
  57. {
  58. m_pObjAccess->Release();
  59. m_pObjAccess = NULL;
  60. }
  61. EnumDone();
  62. MY_OUTPUT(L"EXIT ***** ~CPolledGetObjectDataCollector...", 1);
  63. }
  64. //
  65. // Load a single DataCollector, and everything under it.
  66. //
  67. HRESULT CPolledGetObjectDataCollector::LoadInstanceFromMOF(IWbemClassObject* pObj, CDataGroup *pParentDG, LPTSTR pszParentObjPath, BOOL bModifyPass/*FALSE*/)
  68. {
  69. HRESULT hRes;
  70. IWbemClassObject* pConfigObj = NULL;
  71. BOOL bRetValue = TRUE;
  72. HRESULT hRetRes = S_OK;
  73. int i, iSize;
  74. CThreshold* pThreshold;
  75. MY_OUTPUT(L"ENTER ***** CPolledGetObjectDataCollector::LoadInstanceFromMOF...", 4);
  76. iSize = m_thresholdList.size();
  77. for (i = 0; i < iSize ; i++)
  78. {
  79. MY_ASSERT(i<m_thresholdList.size());
  80. pThreshold = m_thresholdList[i];
  81. if (pThreshold->m_bValidLoad == FALSE)
  82. return WBEM_E_INVALID_OBJECT;
  83. // return S_OK;
  84. }
  85. if (m_szObjectPath)
  86. {
  87. delete [] m_szObjectPath;
  88. m_szObjectPath = NULL;
  89. }
  90. m_lNumInstancesCollected = 0;
  91. //
  92. // Call the base class to load the common properties. Then do the specific ones.
  93. //
  94. hRetRes = CDataCollector::LoadInstanceFromMOF(pObj, pParentDG, pszParentObjPath, bModifyPass);
  95. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) return hRetRes;
  96. // Get the GUID property
  97. hRetRes = GetStrProperty(pObj, L"ObjectPath", &m_szObjectPath);
  98. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  99. // Decide if the path sets us up for multiple instances
  100. if (wcschr(m_szObjectPath, L'='))
  101. {
  102. m_bMultiInstance = FALSE;
  103. }
  104. else
  105. {
  106. m_bMultiInstance = TRUE;
  107. }
  108. //
  109. // Check to see if the High Performance interfaces are supported
  110. // Otherwise we just revert to less efficient WMI interfaces
  111. //
  112. hRes = E_UNEXPECTED;
  113. if (SUCCEEDED(hRes))
  114. {
  115. }
  116. else
  117. {
  118. m_pRefresher = NULL;
  119. bRetValue = FALSE;
  120. }
  121. if (bModifyPass)
  122. {
  123. }
  124. MY_OUTPUT(L"EXIT ***** CPolledGetObjectDataCollector::LoadInstanceFromMOF...", 4);
  125. return S_OK;
  126. error:
  127. MY_ASSERT(FALSE);
  128. m_bValidLoad = FALSE;
  129. Cleanup(FALSE);
  130. return hRetRes;
  131. }
  132. //
  133. // Get the instance out of WMI, and store all the properties we care about.
  134. // Also calculate statistics for them.
  135. //
  136. BOOL CPolledGetObjectDataCollector::CollectInstance(void)
  137. {
  138. BSTR bstrName = NULL;
  139. TCHAR szTemp[1024];
  140. HRESULT hRes;
  141. IWbemClassObject *pObj = NULL;
  142. BOOL bRetValue = TRUE;
  143. PNSTRUCT *ppn;
  144. INSTSTRUCT inst;
  145. INSTSTRUCT *pinst;
  146. int i, j, iSize, jSize;
  147. SAFEARRAY *psaNames = NULL;
  148. BSTR PropName = NULL;
  149. CThreshold *pThreshold;
  150. IRSSTRUCT *pirs;
  151. ACTUALINSTSTRUCT *pActualInst;
  152. MY_OUTPUT(L"ENTER ***** CPolledGetObjectDataCollector::CollectInstance...", 1);
  153. m_lNumInstancesCollected = 0;
  154. if (m_pIWbemServices == NULL)
  155. {
  156. //XXX m_lCurrState = HM_CRITICAL;
  157. MY_ASSERT(FALSE);
  158. m_ulErrorCode = HMRES_BADWMI;
  159. GetLatestAgentError(HMRES_BADWMI, m_szErrorDescription);
  160. StoreStandardProperties();
  161. return FALSE;
  162. }
  163. //
  164. // First we can tell if this is going to be single instance, or multi-instance
  165. //
  166. //XXXCould split this out into four functions that call from here.
  167. if (m_bMultiInstance==TRUE)
  168. {
  169. //XXXNeed to change this to be asyncronous???
  170. //
  171. // MULTI-INSTANCE CASE
  172. //
  173. //
  174. // Check to see if the High Performance interfaces are supported
  175. //
  176. if (m_pRefresher!=NULL)
  177. {
  178. // Ask for the refresh
  179. #ifdef SAVE
  180. hRes = m_pRefresher->Refresh(0L);
  181. if (FAILED(hRes))
  182. {
  183. }
  184. #endif
  185. // Now get the instance
  186. }
  187. else
  188. {
  189. //
  190. // We get an instance at a time, so we can set all to not needed first,
  191. // then go through them, do StoreValues... and delete what is not needed.
  192. //
  193. //
  194. // Mark each instance, so we can tell if we still need them.
  195. //
  196. iSize = m_pnList.size();
  197. for (i = 0; i < iSize ; i++)
  198. {
  199. MY_ASSERT(i<m_pnList.size());
  200. ppn = &m_pnList[i];
  201. jSize = ppn->instList.size();
  202. for (j = 0; j < jSize ; j++)
  203. {
  204. MY_ASSERT(j<ppn->instList.size());
  205. pinst = &ppn->instList[j];
  206. pinst->bNeeded = FALSE;
  207. }
  208. }
  209. // Also for all thresholds under this DataCollector
  210. iSize = m_thresholdList.size();
  211. for (i = 0; i < iSize; i++)
  212. {
  213. MY_ASSERT(i<m_thresholdList.size());
  214. pThreshold = m_thresholdList[i];
  215. jSize = pThreshold->m_irsList.size();
  216. for (j = 0; j < jSize; j++)
  217. {
  218. MY_ASSERT(j<pThreshold->m_irsList.size());
  219. pirs = &pThreshold->m_irsList[j];
  220. pirs->bNeeded = FALSE;
  221. }
  222. }
  223. iSize = m_actualInstList.size();
  224. for (i=0; i < iSize; i++)
  225. {
  226. MY_ASSERT(i<m_actualInstList.size());
  227. pActualInst = &m_actualInstList[i];
  228. pActualInst->bNeeded = FALSE;
  229. }
  230. //
  231. // Enumerate through the instances
  232. //
  233. bstrName = SysAllocString(m_szObjectPath);
  234. m_pEnumObjs = NULL;
  235. hRes = m_pIWbemServices->CreateInstanceEnum(bstrName,
  236. WBEM_FLAG_SHALLOW|WBEM_FLAG_FORWARD_ONLY|WBEM_FLAG_RETURN_IMMEDIATELY, NULL,
  237. &m_pEnumObjs);
  238. if (hRes != S_OK)
  239. {
  240. m_ulErrorCode = hRes;
  241. GetLatestWMIError(HMRES_OBJECTNOTFOUND, hRes, m_szErrorDescription);
  242. StoreStandardProperties();
  243. bRetValue = FALSE;
  244. MY_HRESASSERT(hRes);
  245. MY_OUTPUT2(L"PGDE-Unexpected Error: 0x%08x",hRes,4);
  246. MY_OUTPUT2(L"m_szGUID was=%s",m_szGUID,4);
  247. MY_OUTPUT2(L"bstrName was=%s",bstrName,4);
  248. MY_OUTPUT2(L"CreateInstanceEnum(%s)",m_szObjectPath,4);
  249. }
  250. else
  251. {
  252. m_bKeepCollectingSemiSync = TRUE;
  253. bRetValue = CollectInstanceSemiSync();
  254. }
  255. SysFreeString(bstrName);
  256. }
  257. }
  258. else
  259. {
  260. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  261. //XXX
  262. //XXX
  263. //XXX
  264. //We should just always use the multi-instance code, and delete this code.
  265. //The multi-instance code will still work in the single instance case!!!!!
  266. //XXX
  267. //XXX
  268. //XXX
  269. //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  270. //
  271. // SINGLE INSTANCE CASE
  272. //
  273. //
  274. // Check to see if the High Performance interfaces are supported
  275. //
  276. if (m_pRefresher!=NULL)
  277. {
  278. // Ask for the refresh
  279. #ifdef SAVE
  280. hRes = m_pRefresher->Refresh(0L);
  281. if (FAILED(hRes))
  282. {
  283. }
  284. #endif
  285. // Now get the instances
  286. }
  287. else
  288. {
  289. //
  290. // Mark each instance, so we can tell if we still need them.
  291. //
  292. iSize = m_pnList.size();
  293. for (i = 0; i < iSize ; i++)
  294. {
  295. MY_ASSERT(i<m_pnList.size());
  296. ppn = &m_pnList[i];
  297. jSize = ppn->instList.size();
  298. for (j = 0; j < jSize ; j++)
  299. {
  300. MY_ASSERT(j<ppn->instList.size());
  301. pinst = &ppn->instList[j];
  302. pinst->bNeeded = FALSE;
  303. }
  304. }
  305. // Also for all thresholds under this DataCollector
  306. iSize = m_thresholdList.size();
  307. for (i = 0; i < iSize; i++)
  308. {
  309. MY_ASSERT(i<m_thresholdList.size());
  310. pThreshold = m_thresholdList[i];
  311. jSize = pThreshold->m_irsList.size();
  312. for (j = 0; j < jSize; j++)
  313. {
  314. MY_ASSERT(j<pThreshold->m_irsList.size());
  315. pirs = &pThreshold->m_irsList[j];
  316. pirs->bNeeded = FALSE;
  317. }
  318. }
  319. iSize = m_actualInstList.size();
  320. for (i=0; i < iSize; i++)
  321. {
  322. MY_ASSERT(i<m_actualInstList.size());
  323. pActualInst = &m_actualInstList[i];
  324. pActualInst->bNeeded = FALSE;
  325. }
  326. //
  327. // This is the single instance, NON-HighPerformance case
  328. //
  329. swprintf(szTemp, L"%s", m_szObjectPath);
  330. hRes = GetWbemObjectInstSemiSync(&m_pIWbemServices, szTemp, m_pContext, &m_pCallResult);
  331. if (hRes != S_OK || m_pCallResult == NULL)
  332. {
  333. m_ulErrorCode = hRes;
  334. GetLatestWMIError(HMRES_OBJECTNOTFOUND, hRes, m_szErrorDescription);
  335. StoreStandardProperties();
  336. bRetValue = FALSE;
  337. MY_HRESASSERT(hRes);
  338. MY_OUTPUT2(L"PGDE-Unexpected Error: 0x%08x",hRes,4);
  339. MY_OUTPUT2(L"m_szGUID was=%s",m_szGUID,4);
  340. MY_OUTPUT2(L"CreateWbemObjectInstSemiSync(%s)",m_szObjectPath,4);
  341. }
  342. else
  343. {
  344. m_bKeepCollectingSemiSync = TRUE;
  345. bRetValue = CollectInstanceSemiSync();
  346. }
  347. }
  348. }
  349. MY_OUTPUT(L"EXIT ***** CPolledGetObjectDataCollector::CollectInstance...", 1);
  350. return bRetValue;
  351. }
  352. BOOL CPolledGetObjectDataCollector::CollectInstanceSemiSync(void)
  353. {
  354. LPTSTR pszID = NULL;
  355. HRESULT hRes;
  356. IWbemClassObject *pObj;
  357. IWbemClassObject *apObj[10];
  358. INSTSTRUCT inst;
  359. long lStatus;
  360. ULONG uReturned = 0;
  361. MY_OUTPUT(L"ENTER ***** CPolledGetObjectDataCollector::CollectInstanceSemiSync...", 1);
  362. if (m_bMultiInstance==TRUE)
  363. {
  364. MY_ASSERT(m_pEnumObjs);
  365. // We never want to block here, so we set it for zero second timeout,
  366. // and have it return immediatly what it has available.
  367. hRes = m_pEnumObjs->Next(0, 10, apObj, &uReturned);
  368. if (hRes == WBEM_S_TIMEDOUT)
  369. {
  370. // Didn't get full list of instances yet.
  371. if (!ProcessObjects(uReturned, apObj))
  372. {
  373. EnumDone();
  374. return FALSE;
  375. }
  376. return FALSE;
  377. }
  378. else if (hRes == WBEM_S_FALSE)
  379. {
  380. //
  381. // Means that we are done. The number returned was less than asked for.
  382. // But we still process what we did recieve to finish it off.
  383. // Add in a fake instance for the number of instances returned.
  384. //
  385. if (!ProcessObjects(uReturned, apObj))
  386. {
  387. EnumDone();
  388. return FALSE;
  389. }
  390. else
  391. {
  392. m_ulErrorCode = 0;
  393. StoreStandardProperties();
  394. EnumDone();
  395. //XXXWhy was this here??? m_lCurrState = HM_GOOD;
  396. return TRUE;
  397. }
  398. }
  399. else if (hRes == WBEM_S_NO_ERROR)
  400. {
  401. // Means that we have an instance, The number returned was what was requested
  402. }
  403. else
  404. {
  405. MY_HRESASSERT(hRes);
  406. MY_OUTPUT2(L"PGDE-Unexpected Error MultiInstance Next(): 0x%08x",hRes,4);
  407. MY_OUTPUT2(L"m_szGUID was=%s",m_szGUID,4);
  408. MY_OUTPUT2(L"ObjectPath was=%s",m_szObjectPath,4);
  409. m_ulErrorCode = hRes;
  410. GetLatestWMIError(HMRES_ENUMFAIL, hRes, m_szErrorDescription);
  411. StoreStandardProperties();
  412. EnumDone();
  413. return FALSE;
  414. }
  415. if (apObj[0] == NULL)
  416. {
  417. //
  418. // NULL in this case can actually happen. An example is where the
  419. // threshold is to see if the SQL Server service is running. If it
  420. // is not even on the machine, then we would get an error looking
  421. // for its instance.
  422. //
  423. m_ulErrorCode = hRes;
  424. GetLatestWMIError(HMRES_OBJECTNOTFOUND, hRes, m_szErrorDescription);
  425. StoreStandardProperties();
  426. EnumDone();
  427. }
  428. else
  429. {
  430. MY_ASSERT(uReturned>=1);
  431. if (!ProcessObjects(uReturned, apObj))
  432. {
  433. EnumDone();
  434. return FALSE;
  435. }
  436. // else
  437. // {
  438. // m_ulErrorCode = 0;
  439. // }
  440. }
  441. }
  442. else
  443. {
  444. MY_ASSERT(m_pCallResult);
  445. lStatus = 0;
  446. //
  447. // Keep trying until we get WBEM_S_NO_ERROR. Then we know the GetObject call has completed.
  448. // hRes will contain the result of the origional GetObject call if needed.
  449. //
  450. hRes = m_pCallResult->GetCallStatus(0, &lStatus);
  451. if (hRes == WBEM_S_TIMEDOUT)
  452. {
  453. return FALSE;
  454. }
  455. else if (hRes == WBEM_S_NO_ERROR)
  456. {
  457. // Means that we are done.
  458. // HOWEVER, we don't know if we ever retrieved any instances!
  459. // This is different from the multi-instance case, because we do
  460. // ask for a single specific instance, and will know below if it is there!
  461. }
  462. else
  463. {
  464. MY_HRESASSERT(hRes);
  465. MY_OUTPUT2(L"PGDE-Unexpected Error SingleInstance GetCallStatus: 0x%08x",hRes,4);
  466. MY_OUTPUT2(L"m_szGUID was=%s",m_szGUID,4);
  467. MY_OUTPUT2(L"ObjectPath was=%s",m_szObjectPath,4);
  468. m_ulErrorCode = hRes;
  469. GetLatestWMIError(HMRES_OBJECTNOTFOUND, hRes, m_szErrorDescription);
  470. StoreStandardProperties();
  471. EnumDone();
  472. return FALSE;
  473. }
  474. //
  475. // This may mean that the call completed, and the object was not found (e.g. bad path).
  476. //
  477. if (lStatus != 0)
  478. {
  479. MY_HRESASSERT(lStatus);
  480. m_ulErrorCode = lStatus;
  481. GetLatestWMIError(HMRES_OBJECTNOTFOUND, lStatus, m_szErrorDescription);
  482. StoreStandardProperties();
  483. EnumDone();
  484. return FALSE;
  485. }
  486. //
  487. // Get the Object finaly.
  488. //
  489. hRes = m_pCallResult->GetResultObject(0, &pObj);
  490. if (pObj == NULL)
  491. {
  492. MY_ASSERT(FALSE);
  493. //
  494. // NULL in this case can actually happen. An example is where the
  495. // threshold is to see if the SQL Server service is running. If it
  496. // is not even on the machine, then we would get an error looking
  497. // for its instance.
  498. //
  499. m_lCurrState = HM_WARNING;
  500. m_ulErrorCode = 0;
  501. EnumDone();
  502. }
  503. else
  504. {
  505. //
  506. // Figure out the key property name to identify instances with.
  507. //
  508. hRes = GetInstanceID(pObj, &pszID);
  509. if (hRes != S_OK)
  510. {
  511. pObj->Release();
  512. m_ulErrorCode = hRes;
  513. GetLatestWMIError(HMRES_OBJECTNOTFOUND, hRes, m_szErrorDescription);
  514. StoreStandardProperties();
  515. EnumDone();
  516. return FALSE;
  517. }
  518. //
  519. // Mark instances need to keep around, and add new ones
  520. //
  521. hRes = CheckInstanceExistance(pObj, pszID);
  522. if (hRes != S_OK)
  523. {
  524. delete [] pszID;
  525. pObj->Release();
  526. m_ulErrorCode = hRes;
  527. GetLatestWMIError(HMRES_OBJECTNOTFOUND, hRes, m_szErrorDescription);
  528. StoreStandardProperties();
  529. EnumDone();
  530. return FALSE;
  531. }
  532. m_lNumInstancesCollected = 1;
  533. StoreValues(pObj, pszID);
  534. delete [] pszID;
  535. pObj->Release();
  536. pObj = NULL;
  537. //
  538. // We are done.
  539. // Add in a fake instance for the number of instances returned.
  540. //
  541. m_ulErrorCode = 0;
  542. StoreStandardProperties();
  543. m_lCurrState = HM_GOOD;
  544. EnumDone();
  545. }
  546. return TRUE;
  547. }
  548. MY_OUTPUT(L"EXIT ***** CPolledGetObjectDataCollector::CollectInstanceSemiSync...", 1);
  549. return FALSE;
  550. }
  551. BOOL CPolledGetObjectDataCollector::ProcessObjects(ULONG uReturned, IWbemClassObject **apObj)
  552. {
  553. HRESULT hRes;
  554. LPTSTR pszID;
  555. ULONG n;
  556. BOOL bRetValue = TRUE;
  557. for (n = 0; n < uReturned; n++)
  558. {
  559. if (g_pSystem->m_lNumInstancesAccepted <m_lNumInstancesCollected)
  560. {
  561. m_ulErrorCode = HMRES_TOOMANYINSTS;
  562. GetLatestAgentError(HMRES_TOOMANYINSTS, m_szErrorDescription);
  563. StoreStandardProperties();
  564. bRetValue = FALSE;
  565. break;
  566. }
  567. //Why does the above cause ASSERT on 1151 of Threshold.cpp???
  568. //
  569. // Figure out the key property name to identify instances with.
  570. //
  571. hRes = GetInstanceID(apObj[n], &pszID);
  572. if (hRes != S_OK)
  573. {
  574. m_ulErrorCode = hRes;
  575. GetLatestWMIError(HMRES_OBJECTNOTFOUND, hRes, m_szErrorDescription);
  576. StoreStandardProperties();
  577. bRetValue = FALSE;
  578. break;
  579. }
  580. //
  581. // Special case to throw out the "_Total" instance in the multi-instance case
  582. //
  583. if (!_wcsicmp(pszID, L"_total"))
  584. {
  585. delete [] pszID;
  586. continue;
  587. }
  588. //
  589. // Mark instances need to keep around, and add new ones
  590. //
  591. hRes = CheckInstanceExistance(apObj[n], pszID);
  592. if (hRes != S_OK)
  593. {
  594. delete [] pszID;
  595. m_ulErrorCode = hRes;
  596. GetLatestWMIError(HMRES_OBJECTNOTFOUND, hRes, m_szErrorDescription);
  597. StoreStandardProperties();
  598. bRetValue = FALSE;
  599. break;
  600. }
  601. //
  602. // Now store each property that we need to for this instance
  603. //
  604. m_lNumInstancesCollected++;
  605. StoreValues(apObj[n], pszID);
  606. delete [] pszID;
  607. }
  608. for (n = 0; n < uReturned; n++)
  609. {
  610. apObj[n]->Release();
  611. apObj[n] = NULL;
  612. }
  613. return bRetValue;
  614. }
  615. //XXXIs EnumDone needed in all cases, if so place it in the base class
  616. BOOL CPolledGetObjectDataCollector::EnumDone(void)
  617. {
  618. IRSSTRUCT *pirs;
  619. IWbemClassObject *pObj = NULL;
  620. BOOL bRetValue = TRUE;
  621. PNSTRUCT *ppn;
  622. INSTSTRUCT inst;
  623. INSTSTRUCT *pinst;
  624. int i, j, iSize, jSize;
  625. CThreshold *pThreshold;
  626. SAFEARRAY *psaNames = NULL;
  627. BSTR PropName = NULL;
  628. INSTLIST::iterator iaPINST;
  629. IRSLIST::iterator iaPIRS;
  630. ACTUALINSTLIST::iterator iaPAI;
  631. ACTUALINSTSTRUCT *pActualInst;
  632. CleanupSemiSync();
  633. //XXXAdd similar code to get rid of what is not needed in the m_instList
  634. //XXXOnce again take common code and place it in the base class!VVVVVVVVVVVVVVVVVVVVVVVVv
  635. //
  636. // Now loop through and get rid of instances that are no longer around
  637. //
  638. iSize = m_pnList.size();
  639. for (i = 0; i < iSize; i++)
  640. {
  641. MY_ASSERT(i<m_pnList.size());
  642. ppn = &m_pnList[i];
  643. iaPINST = ppn->instList.begin();
  644. jSize = ppn->instList.size();
  645. for (j = 0; j < jSize && iaPINST ; j++)
  646. {
  647. pinst = iaPINST;
  648. if (pinst->bNeeded == FALSE)
  649. {
  650. if (pinst->szInstanceID)
  651. delete [] pinst->szInstanceID;
  652. if (pinst->szCurrValue)
  653. delete [] pinst->szCurrValue;
  654. pinst->szCurrValue = NULL;
  655. iaPINST = ppn->instList.erase(iaPINST);
  656. }
  657. else
  658. {
  659. iaPINST++;
  660. }
  661. }
  662. }
  663. // Also for all thresholds under this DataCollector
  664. iSize = m_thresholdList.size();
  665. for (i = 0; i < iSize; i++)
  666. {
  667. MY_ASSERT(i<m_thresholdList.size());
  668. pThreshold = m_thresholdList[i];
  669. iaPIRS = pThreshold->m_irsList.begin();
  670. jSize = pThreshold->m_irsList.size();
  671. for (j = 0; j < jSize && iaPIRS ; j++)
  672. {
  673. pirs = iaPIRS;
  674. if (pirs->bNeeded == FALSE)
  675. {
  676. if (pirs->szInstanceID)
  677. delete [] pirs->szInstanceID;
  678. iaPIRS = pThreshold->m_irsList.erase(iaPIRS);
  679. }
  680. else
  681. {
  682. iaPIRS++;
  683. }
  684. }
  685. }
  686. iaPAI = m_actualInstList.begin();
  687. jSize = m_actualInstList.size();
  688. for (j = 0; j < jSize && iaPAI; j++)
  689. {
  690. pActualInst = iaPAI;
  691. if (pActualInst->bNeeded == FALSE)
  692. {
  693. if (pActualInst->szInstanceID)
  694. {
  695. delete [] pActualInst->szInstanceID;
  696. }
  697. if (pActualInst->pInst)
  698. {
  699. pActualInst->pInst->Release();
  700. pActualInst->pInst = NULL;
  701. }
  702. iaPAI = m_actualInstList.erase(iaPAI);
  703. }
  704. else
  705. {
  706. iaPAI++;
  707. }
  708. }
  709. //XXXOnce again take common code and place it in the base class!^^^^^^^^^^^^^^^^^^^^^^^^^
  710. return TRUE;
  711. }
  712. BOOL CPolledGetObjectDataCollector::CleanupSemiSync(void)
  713. {
  714. if (m_bMultiInstance==TRUE)
  715. {
  716. if (m_pEnumObjs)
  717. {
  718. m_pEnumObjs->Release();
  719. m_pEnumObjs = NULL;
  720. }
  721. }
  722. else
  723. {
  724. if (m_pCallResult)
  725. {
  726. m_pCallResult->Release();
  727. m_pCallResult = NULL;
  728. }
  729. }
  730. m_bKeepCollectingSemiSync = FALSE;
  731. m_lCollectionTimeOutCount = 0;
  732. return TRUE;
  733. }