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.

2337 lines
56 KiB

  1. //***************************************************************************
  2. //
  3. // ACTION.CPP
  4. //
  5. // Module: HEALTHMON SERVER AGENT
  6. //
  7. // Purpose: To act as the coordinator of actions. WMI actually provides the
  8. // code and support to carry out the actions (like email). This class
  9. // does the scheduling, and throttling of them.
  10. //
  11. // Copyright (c)1999 Microsoft Corporation, All Rights Reserved
  12. //
  13. //***************************************************************************
  14. #include <stdio.h>
  15. #include <tchar.h>
  16. #include "system.h"
  17. #include "action.h"
  18. extern CSystem* g_pSystem;
  19. extern HMODULE g_hWbemComnModule;
  20. static BYTE LocalSystemSID[] = {1,1,0,0,0,0,0,5,18,0,0,0};
  21. //////////////////////////////////////////////////////////////////////
  22. //////////////////////////////////////////////////////////////////////
  23. // Construction/Destruction
  24. //////////////////////////////////////////////////////////////////////
  25. CAction::CAction()
  26. {
  27. MY_OUTPUT(L"ENTER ***** CAction::CAction...", 4);
  28. m_szGUID = NULL;
  29. m_szName = NULL;
  30. m_szDescription = NULL;
  31. m_szTypeGUID = NULL;
  32. m_pszStatusGUID = NULL;
  33. m_lCurrState = HM_GOOD;
  34. m_hmStatusType = HMSTATUS_ACTION;
  35. m_bValidLoad = FALSE;
  36. wcscpy(m_szDTTime, m_szDTCurrTime);
  37. wcscpy(m_szTime, m_szCurrTime);
  38. MY_OUTPUT(L"EXIT ***** CAction::CAction...", 4);
  39. }
  40. CAction::~CAction()
  41. {
  42. MY_OUTPUT(L"ENTER ***** CAction::~CAction...", 4);
  43. Cleanup(TRUE);
  44. if (m_szGUID)
  45. {
  46. delete [] m_szGUID;
  47. m_szGUID = NULL;
  48. }
  49. m_bValidLoad = FALSE;
  50. MY_OUTPUT(L"EXIT ***** CAction::~CAction...", 4);
  51. }
  52. //
  53. // Load a single Action
  54. //
  55. HRESULT CAction::LoadInstanceFromMOF(IWbemClassObject* pActionConfigInst, BOOL bModifyPass/*FALSE*/)
  56. {
  57. HRESULT hRetRes = S_OK;
  58. TCHAR szTemp[1024];
  59. GUID guid;
  60. LPTSTR pszStr;
  61. LPTSTR pszTemp;
  62. BOOL bRetValue = TRUE;
  63. QSTRUCT Q;
  64. BSTR Language = NULL;
  65. BSTR Query = NULL;
  66. HRESULT hRes;
  67. ULONG uReturned;
  68. IWbemClassObject *pAssocObj = NULL;
  69. IEnumWbemClassObject *pEnum = NULL;
  70. LPTSTR pszUpper = NULL;
  71. MY_OUTPUT(L"ENTER ***** CAction::LoadInstanceFromMOF...", 4);
  72. m_bValidLoad = TRUE;
  73. if (m_szGUID == NULL)
  74. {
  75. // Get the GUID property
  76. hRetRes = GetStrProperty(pActionConfigInst, L"GUID", &m_szGUID);
  77. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) return hRetRes;
  78. }
  79. if (bModifyPass==FALSE)
  80. {
  81. Cleanup(TRUE);
  82. hRetRes = CoCreateGuid(&guid);
  83. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  84. m_pszStatusGUID = new TCHAR[100];
  85. MY_ASSERT(m_pszStatusGUID); if (!m_pszStatusGUID) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  86. StringFromGUID2(guid, m_pszStatusGUID, 100);
  87. }
  88. else
  89. {
  90. Cleanup(FALSE);
  91. }
  92. // Get the Name. If it is NULL then we use the qualifier
  93. hRetRes = GetStrProperty(pActionConfigInst, L"Name", &m_szName);
  94. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  95. // Get the Description. If it is NULL then we use the qualifier
  96. hRetRes = GetStrProperty(pActionConfigInst, L"Description", &m_szDescription);
  97. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  98. hRetRes = GetBoolProperty(pActionConfigInst, L"Enabled", &m_bEnabled);
  99. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  100. hRetRes = GetUint8Property(pActionConfigInst, L"ActiveDays", &m_iActiveDays);
  101. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  102. // The time format looks as follows "********0600**.******+***"; hh is hours and mm is minutes
  103. // All else is ignored.
  104. hRetRes = GetStrProperty(pActionConfigInst, L"BeginTime", &pszTemp);
  105. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  106. pszStr = wcschr(pszTemp, '.');
  107. if (pszStr)
  108. {
  109. // Back up to look at the minute
  110. pszStr -= 2;
  111. *pszStr = '\0';
  112. pszStr -= 2;
  113. m_lBeginMinuteTime= _wtol(pszStr);
  114. // Back up to look at the hour
  115. *pszStr = '\0';
  116. pszStr -= 2;
  117. m_lBeginHourTime= _wtol(pszStr);
  118. }
  119. else
  120. {
  121. m_lBeginMinuteTime= -1;
  122. m_lBeginHourTime= -1;
  123. }
  124. delete [] pszTemp;
  125. hRetRes = GetStrProperty(pActionConfigInst, L"EndTime", &pszTemp);
  126. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  127. pszStr = wcschr(pszTemp, '.');
  128. if (pszStr)
  129. {
  130. // Back up to look at the minute
  131. pszStr -= 2;
  132. *pszStr = '\0';
  133. pszStr -= 2;
  134. m_lEndMinuteTime= _wtol(pszStr);
  135. // Back up to look at the hour
  136. *pszStr = '\0';
  137. pszStr -= 2;
  138. m_lEndHourTime= _wtol(pszStr);
  139. }
  140. else
  141. {
  142. m_lEndMinuteTime= -1;
  143. m_lEndHourTime= -1;
  144. }
  145. delete [] pszTemp;
  146. hRetRes = GetStrProperty(pActionConfigInst, L"TypeGUID", &m_szTypeGUID);
  147. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  148. //
  149. // Need to create a temporary consumer for each configuration object associated to
  150. // this Action. These are the real events that are happening to cause the actions
  151. // to fire.
  152. //
  153. if (!bModifyPass)
  154. {
  155. //
  156. // Loop through all Associations to this Action
  157. //
  158. Language = SysAllocString(L"WQL");
  159. MY_ASSERT(Language); if (!Language) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  160. wcscpy(szTemp, L"REFERENCES OF {MicrosoftHM_ActionConfiguration.GUID=\"");
  161. lstrcat(szTemp, m_szGUID);
  162. lstrcat(szTemp, L"\"} WHERE ResultClass=MicrosoftHM_ConfigurationActionAssociation");
  163. Query = SysAllocString(szTemp);
  164. MY_ASSERT(Query); if (!Query) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  165. // Initialize IEnumWbemClassObject pointer
  166. pEnum = NULL;
  167. // Issue query
  168. hRetRes = g_pIWbemServices->ExecQuery(Language, Query, WBEM_FLAG_FORWARD_ONLY, 0, &pEnum);
  169. SysFreeString(Query);
  170. Query = NULL;
  171. SysFreeString(Language);
  172. Language = NULL;
  173. if (hRetRes != 0)
  174. {
  175. MY_HRESASSERT(hRetRes);
  176. }
  177. else
  178. {
  179. // Retrieve objects in result set
  180. while (TRUE)
  181. {
  182. pAssocObj = NULL;
  183. uReturned = 0;
  184. hRes = pEnum->Next(0, 1, &pAssocObj, &uReturned);
  185. if (uReturned == 0)
  186. {
  187. break;
  188. }
  189. //
  190. // Next, setup the temporary consumer for the event(s) that the actions is
  191. // triggered by, so we can do throttling.
  192. //
  193. hRetRes = GetStrProperty(pAssocObj, L"ParentPath", &Q.szUserConfigPath);
  194. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  195. Q.pBase = g_pSystem->GetParentPointerFromPath(Q.szUserConfigPath);
  196. if (!Q.pBase || (Q.pBase && Q.pBase->m_hmStatusType==HMSTATUS_THRESHOLD))
  197. {
  198. if (Q.szUserConfigPath)
  199. delete [] Q.szUserConfigPath;
  200. pAssocObj->Release();
  201. pAssocObj = NULL;
  202. continue;
  203. }
  204. // hRetRes = GetUint32Property(pAssocObj, L"ThrottleTime", &Q.lThrottleTime);
  205. // MY_HRESASSERT(hRetRes);
  206. Q.lThrottleTime = 0;
  207. hRetRes = GetUint32Property(pAssocObj, L"ReminderTime", &Q.lReminderTime);
  208. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  209. hRetRes = GetStrProperty(pAssocObj, L"Query", &Q.szQuery);
  210. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  211. //
  212. // Look for "...State=0 OR State=9"
  213. //
  214. pszUpper = _wcsdup(Q.szQuery);
  215. MY_ASSERT(pszUpper); if (!pszUpper) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  216. _wcsupr(pszUpper);
  217. Q.ulTriggerStates = 0;
  218. pszStr = wcsstr(pszUpper, L"STATE");
  219. if (pszStr)
  220. {
  221. if (wcschr(pszStr, '0'))
  222. {
  223. Q.ulTriggerStates |= 1<<0;
  224. }
  225. if (wcschr(pszStr, '4'))
  226. {
  227. Q.ulTriggerStates |= 1<<4;
  228. }
  229. if (wcschr(pszStr, '5'))
  230. {
  231. Q.ulTriggerStates |= 1<<5;
  232. }
  233. if (wcschr(pszStr, '8'))
  234. {
  235. Q.ulTriggerStates |= 1<<8;
  236. }
  237. if (wcschr(pszStr, '9'))
  238. {
  239. Q.ulTriggerStates |= 1<<9;
  240. }
  241. }
  242. free(pszUpper);
  243. pszUpper = NULL;
  244. hRetRes = GetStrProperty(pAssocObj, L"__PATH", &Q.szConfigActionAssocPath);
  245. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  246. hRetRes = GetStrProperty(pAssocObj, L"ChildPath", &Q.szChildPath);
  247. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  248. if (m_bEnabled)
  249. {
  250. //
  251. // Setup the event query. We need to be able to identify each individual
  252. // use of this Action! Pass in this unique property.
  253. //
  254. Q.pTempSink = new CTempConsumer(Q.szConfigActionAssocPath);
  255. MY_ASSERT(Q.pTempSink); if (!Q.pTempSink) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  256. Q.hRes = 0;
  257. Language = SysAllocString(L"WQL");
  258. MY_ASSERT(Language); if (!Language) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  259. Query = SysAllocString(Q.szQuery);
  260. MY_ASSERT(Query); if (!Query) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  261. hRes = 1;
  262. if (g_pIWbemServices != NULL)
  263. {
  264. hRes = g_pIWbemServices->ExecNotificationQueryAsync(
  265. Language,
  266. Query,
  267. 0,
  268. NULL,
  269. Q.pTempSink);
  270. Q.hRes = hRes;
  271. }
  272. SysFreeString(Query);
  273. Query = NULL;
  274. SysFreeString(Language);
  275. Language = NULL;
  276. }
  277. else
  278. {
  279. Q.pTempSink = 0;
  280. Q.hRes = 0;
  281. }
  282. Q.startTick = 0;
  283. Q.reminderTimeTick = 0;
  284. Q.bThrottleOn = FALSE;
  285. MY_ASSERT(Q.pBase);
  286. m_qList.push_back(Q);
  287. // Release it.
  288. pAssocObj->Release();
  289. pAssocObj = NULL;
  290. }
  291. // All done
  292. pEnum->Release();
  293. pEnum = NULL;
  294. }
  295. }
  296. m_bValidLoad = TRUE;
  297. MY_OUTPUT(L"EXIT ***** CAction::LoadInstanceFromMOF...", 4);
  298. return S_OK;
  299. error:
  300. MY_ASSERT(FALSE);
  301. if (Query)
  302. SysFreeString(Query);
  303. if (Language)
  304. SysFreeString(Language);
  305. if (pszUpper)
  306. free(pszUpper);
  307. if (pAssocObj)
  308. pAssocObj->Release();
  309. if (pEnum)
  310. pEnum->Release();
  311. Cleanup(TRUE);
  312. m_bValidLoad = FALSE;
  313. return hRetRes;
  314. }
  315. //
  316. // In the case of Actions, they don't actually have an interval to them, but they
  317. // get called here for each action every second (the base agent interval).
  318. //
  319. BOOL CAction::OnAgentInterval(void)
  320. {
  321. HRESULT hRetRes = S_OK;
  322. HRESULT hRes;
  323. IWbemClassObject* pInstance = NULL;
  324. HRESULT hRes2;
  325. IWbemClassObject* pInstance2 = NULL;
  326. DWORD currTick;
  327. BOOL bTimeOK;
  328. int i, iSize;
  329. QSTRUCT *pQ;
  330. BSTR Language = NULL;
  331. BSTR Query = NULL;
  332. GUID guid;
  333. if (m_bValidLoad == FALSE)
  334. return FALSE;
  335. //
  336. // Make sure that we are in a valid time to run.
  337. //
  338. bTimeOK = checkTime();
  339. // Remember that the DISABLED state overrides SCHEDULEDOUT.
  340. if ((m_bEnabled==FALSE && m_lCurrState==HM_DISABLED) ||
  341. (bTimeOK==FALSE && m_lCurrState==HM_SCHEDULEDOUT && m_bEnabled))
  342. {
  343. return TRUE;
  344. }
  345. else if (m_bEnabled==FALSE && m_lCurrState!=HM_DISABLED ||
  346. bTimeOK==FALSE && m_lCurrState!=HM_SCHEDULEDOUT)
  347. {
  348. //
  349. // Going into Scheduled Outage OR DISABLED.
  350. // What if we are going from ScheduledOut to Disabled?
  351. // Or from Disabled to ScheduledOut?
  352. // Possible transitions:
  353. // GOOD -> Disabled
  354. // GOOD -> ScheduledOut
  355. // Disabled -> ScheduledOut
  356. // ScheduledOut -> Disabled
  357. //
  358. iSize = m_qList.size();
  359. for (i=0; i<iSize; i++)
  360. {
  361. MY_ASSERT(i<m_qList.size());
  362. pQ = &m_qList[i];
  363. if (pQ->pTempSink)
  364. {
  365. g_pIWbemServices->CancelAsyncCall((IWbemObjectSink*)pQ->pTempSink);
  366. pQ->pTempSink->Release();
  367. pQ->pTempSink = NULL;
  368. }
  369. pQ->hRes = 0;
  370. }
  371. if (m_bEnabled==FALSE)
  372. {
  373. m_lCurrState = HM_DISABLED;
  374. FireEvent(-1, NULL, HMRES_ACTION_DISABLE);
  375. }
  376. else
  377. {
  378. m_lCurrState = HM_SCHEDULEDOUT;
  379. FireEvent(-1, NULL, HMRES_ACTION_OUTAGE);
  380. }
  381. return TRUE;
  382. }
  383. else if (m_lCurrState==HM_DISABLED || m_lCurrState==HM_SCHEDULEDOUT)
  384. {
  385. //
  386. // Comming out of Scheduled Outage OR DISABLED.
  387. // Might be going from ScheduledOut/Disabled to Disabled,
  388. // or disabled to ScheduledOut.
  389. //
  390. m_lCurrState = HM_GOOD;
  391. FireEvent(-1, NULL, HMRES_ACTION_ENABLE);
  392. // Re-setup the event consumer
  393. iSize = m_qList.size();
  394. for (i=0; i<iSize; i++)
  395. {
  396. MY_ASSERT(i<m_qList.size());
  397. pQ = &m_qList[i];
  398. pQ->pTempSink = new CTempConsumer(pQ->szConfigActionAssocPath);
  399. MY_ASSERT(pQ->pTempSink); if (!pQ->pTempSink) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  400. pQ->hRes = 0;
  401. Language = SysAllocString(L"WQL");
  402. MY_ASSERT(Language); if (!Language) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  403. Query = SysAllocString(pQ->szQuery);
  404. MY_ASSERT(Query); if (!Query) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  405. hRes = 1;
  406. if (g_pIWbemServices != NULL)
  407. {
  408. hRes = g_pIWbemServices->ExecNotificationQueryAsync(
  409. Language,
  410. Query,
  411. 0,
  412. NULL,
  413. pQ->pTempSink);
  414. pQ->hRes = hRes;
  415. }
  416. SysFreeString(Query);
  417. Query = NULL;
  418. SysFreeString(Language);
  419. Language = NULL;
  420. if (hRes != 0)
  421. {
  422. MY_HRESASSERT(hRes);
  423. }
  424. else
  425. {
  426. pQ->startTick = 0;
  427. pQ->reminderTimeTick = 0;
  428. pQ->bThrottleOn = FALSE;
  429. }
  430. }
  431. }
  432. //
  433. // Determine if the throttle time needs to come into play.
  434. //
  435. currTick = GetTickCount();
  436. iSize = m_qList.size();
  437. for (i=0; i<iSize; i++)
  438. {
  439. MY_ASSERT(i<m_qList.size());
  440. pQ = &m_qList[i];
  441. if (0<pQ->lThrottleTime)
  442. {
  443. // May have not gone off yet
  444. if ((0<pQ->startTick))
  445. {
  446. // Check to see if alloted time has passed
  447. if ((pQ->lThrottleTime*1000) < (currTick-pQ->startTick))
  448. {
  449. pQ->bThrottleOn = FALSE;
  450. pQ->startTick = 0;
  451. }
  452. else
  453. {
  454. pQ->bThrottleOn = TRUE;
  455. }
  456. }
  457. }
  458. }
  459. // Try and prevent problems where we may have had a query fail to register
  460. iSize = m_qList.size();
  461. for (i=0; i<iSize; i++)
  462. {
  463. MY_ASSERT(i<m_qList.size());
  464. pQ = &m_qList[i];
  465. if (pQ->hRes!=0)
  466. {
  467. Language = SysAllocString(L"WQL");
  468. MY_ASSERT(Language); if (!Language) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  469. Query = SysAllocString(pQ->szQuery);
  470. MY_ASSERT(Query); if (!Query) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  471. hRes = 1;
  472. if (g_pIWbemServices != NULL && pQ->pTempSink && pQ->hRes!=0)
  473. {
  474. hRes = g_pIWbemServices->ExecNotificationQueryAsync(
  475. Language,
  476. Query,
  477. 0,
  478. NULL,
  479. pQ->pTempSink);
  480. MY_HRESASSERT(hRes);
  481. pQ->hRes = hRes;
  482. }
  483. SysFreeString(Query);
  484. Query = NULL;
  485. SysFreeString(Language);
  486. Language = NULL;
  487. if (hRes == 0)
  488. {
  489. pQ->startTick = 0;
  490. pQ->reminderTimeTick = 0;
  491. pQ->bThrottleOn = FALSE;
  492. }
  493. }
  494. }
  495. //
  496. // Determine if we need to fire off a reminder event.
  497. // We first need to be in the violated state.
  498. //
  499. iSize = m_qList.size();
  500. for (i=0; i<iSize; i++)
  501. {
  502. MY_ASSERT(i<m_qList.size());
  503. pQ = &m_qList[i];
  504. MY_ASSERT(pQ->pBase);
  505. if ((g_pActionEventSink || g_pActionTriggerEventSink) && pQ->pBase &&
  506. pQ->lReminderTime!=0 && pQ->reminderTimeTick==pQ->lReminderTime)
  507. {
  508. // Fire event to console, and another one to the event consumer
  509. wcscpy(m_szDTTime, m_szDTCurrTime);
  510. wcscpy(m_szTime, m_szCurrTime);
  511. m_lCurrState = HM_GOOD;
  512. if (m_pszStatusGUID)
  513. {
  514. delete [] m_pszStatusGUID;
  515. m_pszStatusGUID = NULL;
  516. }
  517. hRetRes = CoCreateGuid(&guid);
  518. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  519. m_pszStatusGUID = new TCHAR[100];
  520. MY_ASSERT(m_pszStatusGUID); if (!m_pszStatusGUID) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  521. StringFromGUID2(guid, m_pszStatusGUID, 100);
  522. hRes = GetHMActionStatus(&pInstance, NULL, L"MicrosoftHM_ActionStatusEvent", HMRES_ACTION_FIRED);
  523. hRes2 = GetHMActionStatus(&pInstance2, NULL, L"MicrosoftHM_ActionTriggerEvent", HMRES_ACTION_FIRED);
  524. if (SUCCEEDED(hRes) && SUCCEEDED(hRes2))
  525. {
  526. pQ->pBase->SendReminderActionIfStateIsSame(g_pActionEventSink, g_pActionTriggerEventSink, pInstance, pInstance2, pQ->ulTriggerStates);
  527. }
  528. else
  529. {
  530. MY_OUTPUT(L"failed to get instance!", 1);
  531. MY_HRESASSERT(hRes);
  532. MY_HRESASSERT(hRes2);
  533. }
  534. if (pInstance)
  535. {
  536. pInstance->Release();
  537. pInstance = NULL;
  538. }
  539. if (pInstance2)
  540. {
  541. pInstance2->Release();
  542. pInstance2 = NULL;
  543. }
  544. pQ->reminderTimeTick = 0;
  545. }
  546. if (pQ->lReminderTime!=0 && pQ->reminderTimeTick==pQ->lReminderTime)
  547. pQ->reminderTimeTick = 0;
  548. pQ->reminderTimeTick++;
  549. }
  550. return TRUE;
  551. error:
  552. MY_ASSERT(FALSE);
  553. if (Query)
  554. SysFreeString(Query);
  555. if (Language)
  556. SysFreeString(Language);
  557. m_bValidLoad = FALSE;
  558. Cleanup(TRUE);
  559. return FALSE;
  560. }
  561. //
  562. // Here we get an event, and since we act as the gatekeeper to pass on the final event
  563. // that the EventConsumer will get fired from, we decide if we need to throttle.
  564. // To send on the event, we embed the incomming event into ours.
  565. //
  566. BOOL CAction::HandleTempEvent(LPTSTR szConfigActionAssocPath, IWbemClassObject* pObj)
  567. {
  568. BOOL bRetValue = TRUE;
  569. IWbemClassObject* pInstance = NULL;
  570. HRESULT hRes;
  571. BOOL bFound;
  572. QSTRUCT *pQ;
  573. int i, iSize;
  574. MY_OUTPUT(L"ENTER ***** CAction::HandleTempEvent...", 2);
  575. if (m_bValidLoad == FALSE)
  576. return FALSE;
  577. m_lCurrState = HM_GOOD;
  578. //
  579. // See if it is one of these
  580. //
  581. bFound = FALSE;
  582. iSize = m_qList.size();
  583. for (i=0; i<iSize; i++)
  584. {
  585. MY_ASSERT(i<m_qList.size());
  586. pQ = &m_qList[i];
  587. if (!_wcsicmp(pQ->szConfigActionAssocPath, szConfigActionAssocPath))
  588. {
  589. bFound = TRUE;
  590. break;
  591. }
  592. }
  593. //
  594. // We capture the time that this happened, so that we can throttle in the
  595. // OnAgentInterval call we can disable the action from happening (until time again).
  596. //
  597. if (bFound==FALSE)
  598. {
  599. return FALSE;
  600. }
  601. if (pQ->startTick == 0)
  602. {
  603. pQ->startTick = GetTickCount();
  604. }
  605. MY_OUTPUT2(L"HandleTempEvent GUID=%s", m_szGUID, 4);
  606. MY_OUTPUT2(L"szConfigActionAssocPath=%s", szConfigActionAssocPath, 4);
  607. if (pQ->bThrottleOn == FALSE)
  608. {
  609. if (pQ->lReminderTime != 0)
  610. {
  611. pQ->reminderTimeTick = 0;
  612. }
  613. // Don't send if no-one is listening!
  614. if (g_pActionTriggerEventSink != NULL)
  615. {
  616. wcscpy(m_szDTTime, m_szDTCurrTime);
  617. wcscpy(m_szTime, m_szCurrTime);
  618. FireEvent(-1, NULL, HMRES_ACTION_FIRED);
  619. hRes = GetHMActionStatus(&pInstance, pObj, L"MicrosoftHM_ActionTriggerEvent", HMRES_ACTION_FIRED);
  620. if (SUCCEEDED(hRes))
  621. {
  622. if (g_pActionTriggerEventSink)
  623. {
  624. hRes = g_pActionTriggerEventSink->Indicate(1, &pInstance);
  625. //WBEM_E_SERVER_TOO_BUSY is Ok. Wbem will deliver.
  626. if (FAILED(hRes) && hRes != WBEM_E_SERVER_TOO_BUSY)
  627. {
  628. bRetValue = FALSE;
  629. MY_OUTPUT(L"Failed on Indicate!", 4);
  630. }
  631. }
  632. pInstance->Release();
  633. pInstance = NULL;
  634. }
  635. else
  636. {
  637. MY_OUTPUT(L"failed to get instance!", 1);
  638. MY_HRESASSERT(hRes);
  639. }
  640. }
  641. }
  642. MY_OUTPUT(L"EXIT ***** CAction::HandleTempEvent...", 2);
  643. return bRetValue;
  644. }
  645. //oooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo
  646. HRESULT CAction::FindAndModAction(BSTR szGUID, IWbemClassObject* pObj)
  647. {
  648. HRESULT hRetRes = S_OK;
  649. //
  650. // Is this us we are looking for?
  651. //
  652. if (!_wcsicmp(m_szGUID, szGUID))
  653. {
  654. hRetRes = LoadInstanceFromMOF(pObj, TRUE);
  655. return hRetRes;
  656. }
  657. return WBEM_S_DIFFERENT;
  658. }
  659. BOOL CAction::FindAndCreateActionAssociation(BSTR szGUID, IWbemClassObject* pObj)
  660. {
  661. HRESULT hRes;
  662. HRESULT hRetRes = S_OK;
  663. int i, iSize;
  664. QSTRUCT *pQ;
  665. QSTRUCT Q;
  666. BOOL bFound;
  667. BOOL bTimeOK;
  668. LPTSTR pszStr;
  669. BSTR Language = NULL;
  670. BSTR Query = NULL;
  671. LPTSTR pszConfigActionAssocPath = NULL;
  672. LPTSTR pszUpper = NULL;
  673. if (m_bValidLoad == FALSE)
  674. return FALSE;
  675. //
  676. // Is this the Action we are looking for?
  677. //
  678. if (!_wcsicmp(m_szGUID, szGUID))
  679. {
  680. hRetRes = GetStrProperty(pObj, L"__PATH", &pszConfigActionAssocPath);
  681. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  682. MY_OUTPUT2(L"Association to Action GUID=%s", szGUID, 4);
  683. MY_OUTPUT2(L"To PATH=%s", pszConfigActionAssocPath, 4);
  684. // Now check to see if this association already exists
  685. bFound = FALSE;
  686. iSize = m_qList.size();
  687. for (i=0; i<iSize; i++)
  688. {
  689. MY_ASSERT(i<m_qList.size());
  690. pQ = &m_qList[i];
  691. if (!_wcsicmp(pQ->szConfigActionAssocPath, pszConfigActionAssocPath))
  692. {
  693. bFound = TRUE;
  694. break;
  695. }
  696. }
  697. delete [] pszConfigActionAssocPath;
  698. pszConfigActionAssocPath = NULL;
  699. if (bFound == FALSE)
  700. {
  701. MY_OUTPUT(L"OK: Not found yet.", 4);
  702. Q.szUserConfigPath = NULL;
  703. Q.szQuery = NULL;
  704. Q.szConfigActionAssocPath = NULL;
  705. Q.szChildPath = NULL;
  706. //
  707. // Next, setup the temporary consumer for the event(s) that the actions is
  708. // triggered by, so we can do throttling.
  709. //
  710. hRetRes = GetStrProperty(pObj, L"ParentPath", &Q.szUserConfigPath);
  711. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  712. Q.pBase = g_pSystem->GetParentPointerFromPath(Q.szUserConfigPath);
  713. if (!Q.pBase || (Q.pBase && Q.pBase->m_hmStatusType==HMSTATUS_THRESHOLD))
  714. {
  715. if (Q.szUserConfigPath)
  716. {
  717. delete [] Q.szUserConfigPath;
  718. }
  719. }
  720. else
  721. {
  722. // hRetRes = GetUint32Property(pObj, L"ThrottleTime", &Q.lThrottleTime);
  723. // MY_HRESASSERT(hRetRes);
  724. Q.lThrottleTime = 0;
  725. hRetRes = GetUint32Property(pObj, L"ReminderTime", &Q.lReminderTime);
  726. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  727. hRetRes = GetStrProperty(pObj, L"Query", &Q.szQuery);
  728. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  729. //
  730. // Look for "...State=0 OR State=9"
  731. //
  732. pszUpper = _wcsdup(Q.szQuery);
  733. MY_ASSERT(pszUpper); if (!pszUpper) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  734. _wcsupr(pszUpper);
  735. Q.ulTriggerStates = 0;
  736. pszStr = wcsstr(pszUpper, L"STATE");
  737. if (pszStr)
  738. {
  739. if (wcschr(pszStr, '0'))
  740. {
  741. Q.ulTriggerStates |= 1<<0;
  742. }
  743. if (wcschr(pszStr, '4'))
  744. {
  745. Q.ulTriggerStates |= 1<<4;
  746. }
  747. if (wcschr(pszStr, '5'))
  748. {
  749. Q.ulTriggerStates |= 1<<5;
  750. }
  751. if (wcschr(pszStr, '8'))
  752. {
  753. Q.ulTriggerStates |= 1<<8;
  754. }
  755. if (wcschr(pszStr, '9'))
  756. {
  757. Q.ulTriggerStates |= 1<<9;
  758. }
  759. }
  760. free(pszUpper);
  761. pszUpper = NULL;
  762. hRetRes = GetStrProperty(pObj, L"__PATH", &Q.szConfigActionAssocPath);
  763. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  764. hRetRes = GetStrProperty(pObj, L"ChildPath", &Q.szChildPath);
  765. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  766. TCHAR msgbuf[1024];
  767. wsprintf(msgbuf, L"ACTIONASSOCIATION: AGUID=%s parentpath=%s childpath=%s", szGUID, Q.szUserConfigPath, Q.szChildPath);
  768. MY_OUTPUT(msgbuf, 4);
  769. //
  770. // Setup the event query. We need to be able to identify each individual
  771. // use of this Action! Pass in this unique property.
  772. //
  773. bTimeOK = checkTime();
  774. if (m_bEnabled==TRUE && bTimeOK==TRUE)
  775. {
  776. Q.pTempSink = new CTempConsumer(Q.szConfigActionAssocPath);
  777. MY_ASSERT(Q.pTempSink); if (!Q.pTempSink) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  778. Language = SysAllocString(L"WQL");
  779. MY_ASSERT(Language); if (!Language) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  780. Query = SysAllocString(Q.szQuery);
  781. MY_ASSERT(Query); if (!Query) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  782. hRes = 1;
  783. Q.hRes = 0;
  784. if (g_pIWbemServices != NULL)
  785. {
  786. hRes = g_pIWbemServices->ExecNotificationQueryAsync(
  787. Language,
  788. Query,
  789. 0,
  790. NULL,
  791. Q.pTempSink);
  792. Q.hRes = hRes;
  793. }
  794. SysFreeString(Query);
  795. Query = NULL;
  796. SysFreeString(Language);
  797. Language = NULL;
  798. Q.startTick = 0;
  799. Q.reminderTimeTick = 0;
  800. Q.bThrottleOn = FALSE;
  801. MY_ASSERT(Q.pBase);
  802. m_qList.push_back(Q);
  803. }
  804. else
  805. {
  806. Q.pTempSink = NULL;
  807. Q.startTick = 0;
  808. Q.reminderTimeTick = 0;
  809. Q.bThrottleOn = FALSE;
  810. MY_ASSERT(Q.pBase);
  811. m_qList.push_back(Q);
  812. }
  813. }
  814. return TRUE;
  815. }
  816. else
  817. {
  818. MY_OUTPUT(L"WHY?: Already There.", 4);
  819. return FALSE;
  820. }
  821. }
  822. else
  823. {
  824. return FALSE;
  825. }
  826. error:
  827. MY_ASSERT(FALSE);
  828. if (pszUpper)
  829. free(pszUpper);
  830. if (pszConfigActionAssocPath)
  831. delete [] pszConfigActionAssocPath;
  832. if (Q.szUserConfigPath)
  833. delete [] Q.szUserConfigPath;
  834. if (Q.szQuery)
  835. delete [] Q.szQuery;
  836. if (Q.szConfigActionAssocPath)
  837. delete [] Q.szConfigActionAssocPath;
  838. if (Q.szChildPath)
  839. delete [] Q.szChildPath;
  840. if (Query)
  841. SysFreeString(Query);
  842. if (Language)
  843. SysFreeString(Language);
  844. return TRUE;
  845. }
  846. BOOL CAction::FindAndModActionAssociation(BSTR szGUID, IWbemClassObject* pObj)
  847. {
  848. HRESULT hRes;
  849. HRESULT hRetRes;
  850. int i, iSize;
  851. QSTRUCT *pQ;
  852. LPTSTR pszTemp;
  853. BOOL bFound;
  854. BSTR Language = NULL;
  855. BSTR Query = NULL;
  856. BOOL bSameQuery = FALSE;
  857. BOOL bTimeOK;
  858. LPTSTR pszUpper = NULL;
  859. LPTSTR pszStr;
  860. if (m_bValidLoad == FALSE)
  861. return FALSE;
  862. //
  863. // Is this the Action we are looking for?
  864. //
  865. if (!_wcsicmp(m_szGUID, szGUID))
  866. {
  867. hRetRes = GetStrProperty(pObj, L"__PATH", &pszTemp);
  868. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  869. // Now check to see if this association already exists
  870. bFound = FALSE;
  871. iSize = m_qList.size();
  872. for (i=0; i<iSize; i++)
  873. {
  874. MY_ASSERT(i<m_qList.size());
  875. pQ = &m_qList[i];
  876. if (!_wcsicmp(pQ->szConfigActionAssocPath, pszTemp))
  877. {
  878. bFound = TRUE;
  879. break;
  880. }
  881. }
  882. delete [] pszTemp;
  883. pszTemp = NULL;
  884. if (bFound == TRUE)
  885. {
  886. MY_OUTPUT2(L"MODACTIONASSOCIATION: AGUID=%s", szGUID, 4);
  887. MY_OUTPUT2(L"parentpath=%s", pQ->szUserConfigPath, 4);
  888. MY_OUTPUT2(L"childpath=%s", pQ->szChildPath, 4);
  889. if (pQ->szQuery)
  890. {
  891. hRetRes = GetStrProperty(pObj, L"Query", &pszTemp);
  892. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  893. if (!wcscmp(pQ->szQuery, pszTemp))
  894. {
  895. bSameQuery = TRUE;
  896. pQ->reminderTimeTick = 0;
  897. }
  898. // Check to See if we have to register a new query.
  899. if (!bSameQuery)
  900. {
  901. delete [] pQ->szQuery;
  902. pQ->szQuery = NULL;
  903. hRetRes = GetStrProperty(pObj, L"Query", &pQ->szQuery);
  904. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  905. //
  906. // Look for "...State=0 OR State=9"
  907. //
  908. pszUpper = _wcsdup(pQ->szQuery);
  909. MY_ASSERT(pszUpper); if (!pszUpper) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  910. _wcsupr(pszUpper);
  911. pQ->ulTriggerStates = 0;
  912. pszStr = wcsstr(pszUpper, L"STATE");
  913. if (pszStr)
  914. {
  915. if (wcschr(pszStr, '0'))
  916. {
  917. pQ->ulTriggerStates |= 1<<0;
  918. }
  919. if (wcschr(pszStr, '4'))
  920. {
  921. pQ->ulTriggerStates |= 1<<4;
  922. }
  923. if (wcschr(pszStr, '5'))
  924. {
  925. pQ->ulTriggerStates |= 1<<5;
  926. }
  927. if (wcschr(pszStr, '8'))
  928. {
  929. pQ->ulTriggerStates |= 1<<8;
  930. }
  931. if (wcschr(pszStr, '9'))
  932. {
  933. pQ->ulTriggerStates |= 1<<9;
  934. }
  935. }
  936. free(pszUpper);
  937. pszUpper = NULL;
  938. }
  939. delete [] pszTemp;
  940. pszTemp = NULL;
  941. }
  942. if (pQ->szUserConfigPath)
  943. {
  944. delete [] pQ->szUserConfigPath;
  945. pQ->szUserConfigPath = NULL;
  946. }
  947. if (pQ->szChildPath)
  948. {
  949. delete [] pQ->szChildPath;
  950. pQ->szChildPath = NULL;
  951. }
  952. if (pQ->pTempSink && !bSameQuery)
  953. {
  954. g_pIWbemServices->CancelAsyncCall((IWbemObjectSink*)pQ->pTempSink);
  955. pQ->pTempSink->Release();
  956. pQ->pTempSink = NULL;
  957. }
  958. //
  959. // Next, setup the temporary consumer for the event(s) that the actions is
  960. // triggered by, so we can do throttling.
  961. //
  962. // hRetRes = GetUint32Property(pObj, L"ThrottleTime", &pQ->lThrottleTime);
  963. // MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  964. pQ->lThrottleTime = 0;
  965. hRetRes = GetUint32Property(pObj, L"ReminderTime", &pQ->lReminderTime);
  966. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  967. hRetRes = GetStrProperty(pObj, L"ParentPath", &pQ->szUserConfigPath);
  968. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  969. hRetRes = GetStrProperty(pObj, L"ChildPath", &pQ->szChildPath);
  970. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  971. //
  972. // Setup the event query. We need to be able to identify each individual
  973. // use of this Action! Pass in this unique property.
  974. //
  975. bTimeOK = checkTime();
  976. if (!bSameQuery && m_bEnabled==TRUE && bTimeOK==TRUE)
  977. {
  978. pQ->pTempSink = new CTempConsumer(pQ->szConfigActionAssocPath);
  979. MY_ASSERT(pQ->pTempSink); if (!pQ->pTempSink) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  980. Language = SysAllocString(L"WQL");
  981. MY_ASSERT(Language); if (!Language) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  982. Query = SysAllocString(pQ->szQuery);
  983. MY_ASSERT(Query); if (!Query) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  984. hRes = 1;
  985. pQ->hRes = 0;
  986. if (g_pIWbemServices != NULL)
  987. {
  988. hRes = g_pIWbemServices->ExecNotificationQueryAsync(
  989. Language,
  990. Query,
  991. 0,
  992. NULL,
  993. //XXXm_pContext,
  994. pQ->pTempSink);
  995. pQ->hRes = hRes;
  996. }
  997. SysFreeString(Query);
  998. Query = NULL;
  999. SysFreeString(Language);
  1000. Language = NULL;
  1001. if (hRes != 0)
  1002. {
  1003. MY_HRESASSERT(hRes);
  1004. }
  1005. else
  1006. {
  1007. pQ->startTick = 0;
  1008. pQ->reminderTimeTick = 0;
  1009. pQ->bThrottleOn = FALSE;
  1010. }
  1011. }
  1012. }
  1013. return TRUE;
  1014. }
  1015. else
  1016. {
  1017. return FALSE;
  1018. }
  1019. error:
  1020. MY_ASSERT(FALSE);
  1021. if (pszTemp)
  1022. free(pszTemp);
  1023. if (Query)
  1024. SysFreeString(Query);
  1025. if (Language)
  1026. SysFreeString(Language);
  1027. Cleanup(TRUE);
  1028. m_bValidLoad = FALSE;
  1029. return TRUE;
  1030. }
  1031. BOOL CAction::DeleteConfigActionAssoc(LPTSTR pszConfigGUID, LPTSTR pszActionGUID)
  1032. {
  1033. TCHAR *pszEventFilter = NULL;
  1034. BSTR instName = NULL;
  1035. BOOL bFound = FALSE;
  1036. TCHAR szGUID[1024];
  1037. LPTSTR pStr;
  1038. LPTSTR pStr2;
  1039. int i, iSize;
  1040. QSTRUCT *pQ;
  1041. QLIST::iterator iaQ;
  1042. IWbemClassObject* pInst = NULL;
  1043. HRESULT hRes;
  1044. HRESULT hRetRes = S_OK;
  1045. if (m_bValidLoad == FALSE)
  1046. return FALSE;
  1047. //
  1048. // First verify that we have the proper action identified.
  1049. //
  1050. if (_wcsicmp(m_szGUID, pszActionGUID))
  1051. {
  1052. return FALSE;
  1053. }
  1054. TCHAR msgbuf[1024];
  1055. wsprintf(msgbuf, L"DELETECONFIGACTIONASSOCIATION: CONFIGGUID=%s AGUID=%s", pszConfigGUID, pszActionGUID);
  1056. MY_OUTPUT(msgbuf, 4);
  1057. //
  1058. // Verify the Configuration instance associated to this Action
  1059. // We are not deleting the ActionConfig, or the __EventConsumer,
  1060. //__EventFilter, __FilterToConsumerBinding Just usage of it - ConfigActionAssoc
  1061. //
  1062. iSize = m_qList.size();
  1063. iaQ = m_qList.begin();
  1064. for (i=0; i<iSize; i++, iaQ++)
  1065. {
  1066. MY_ASSERT(i<m_qList.size());
  1067. pQ = &m_qList[i];
  1068. wcscpy(szGUID, pQ->szUserConfigPath);
  1069. pStr = wcschr(szGUID, '\"');
  1070. if (pStr)
  1071. {
  1072. pStr++;
  1073. pStr2 = wcschr(pStr, '\"');
  1074. if (pStr2)
  1075. {
  1076. *pStr2 = '\0';
  1077. }
  1078. }
  1079. else
  1080. {
  1081. pStr = wcschr(szGUID, '=');
  1082. if (pStr)
  1083. {
  1084. pStr++;
  1085. if (*pStr == '@')
  1086. {
  1087. pStr2 = pStr;
  1088. pStr2++;
  1089. *pStr2 = '\0';
  1090. }
  1091. }
  1092. }
  1093. if (pStr)
  1094. {
  1095. if (!_wcsicmp(pStr, pszConfigGUID))
  1096. {
  1097. hRetRes = GetWbemObjectInst(&g_pIWbemServices, pQ->szConfigActionAssocPath, NULL, &pInst);
  1098. if (!pInst)
  1099. {
  1100. MY_HRESASSERT(hRetRes);
  1101. return FALSE;
  1102. }
  1103. hRetRes = GetStrProperty(pInst, L"EventFilter", &pszEventFilter);
  1104. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  1105. pInst->Release();
  1106. pInst = NULL;
  1107. delete [] pszEventFilter;
  1108. pszEventFilter = NULL;
  1109. //
  1110. // Delete MicrosoftHM_ConfigurationActionAssociation.
  1111. //
  1112. instName = SysAllocString(pQ->szConfigActionAssocPath);
  1113. MY_ASSERT(instName); if (!instName) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  1114. if ((hRes = g_pIWbemServices->DeleteInstance(instName, 0L, NULL, NULL)) != S_OK)
  1115. {
  1116. MY_OUTPUT(L"ENTER ***** ConfigurationActionAssoc Delete failed...", 4);
  1117. }
  1118. SysFreeString(instName);
  1119. instName = NULL;
  1120. if (pQ->szQuery)
  1121. {
  1122. delete [] pQ->szQuery;
  1123. pQ->szQuery = NULL;
  1124. }
  1125. if (pQ->szConfigActionAssocPath)
  1126. {
  1127. delete [] pQ->szConfigActionAssocPath;
  1128. pQ->szConfigActionAssocPath = NULL;
  1129. }
  1130. if (pQ->szUserConfigPath)
  1131. {
  1132. delete [] pQ->szUserConfigPath;
  1133. pQ->szUserConfigPath = NULL;
  1134. }
  1135. if (pQ->szChildPath)
  1136. {
  1137. delete [] pQ->szChildPath;
  1138. pQ->szChildPath = NULL;
  1139. }
  1140. if (pQ->pTempSink)
  1141. {
  1142. g_pIWbemServices->CancelAsyncCall((IWbemObjectSink*)pQ->pTempSink);
  1143. pQ->pTempSink->Release();
  1144. pQ->pTempSink = NULL;
  1145. }
  1146. m_qList.erase(iaQ);
  1147. bFound = TRUE;
  1148. break;
  1149. }
  1150. }
  1151. }
  1152. if (bFound == TRUE)
  1153. {
  1154. }
  1155. return bFound;
  1156. error:
  1157. MY_ASSERT(FALSE);
  1158. if (pszEventFilter)
  1159. delete [] pszEventFilter;
  1160. if (instName)
  1161. SysFreeString(instName);
  1162. if (pInst)
  1163. pInst->Release();
  1164. return TRUE;
  1165. }
  1166. BOOL CAction::DeleteEFAndFTCB(void)
  1167. {
  1168. TCHAR szTemp[1024];
  1169. TCHAR *pszEventConsumer = NULL;
  1170. BSTR instName = NULL;
  1171. LPTSTR pStr;
  1172. LPTSTR pStr2;
  1173. IWbemClassObject* pInst = NULL;
  1174. HRESULT hRes;
  1175. HRESULT hRetRes = S_OK;
  1176. //
  1177. // Delete the __EventFilter
  1178. //
  1179. wcscpy(szTemp, L"__EventFilter.Name=\"");
  1180. lstrcat(szTemp, m_szGUID);
  1181. lstrcat(szTemp, L"\"");
  1182. instName = SysAllocString(szTemp);
  1183. MY_ASSERT(instName); if (!instName) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  1184. if ((hRes = g_pIWbemServices->DeleteInstance(instName, 0L, NULL, NULL)) != S_OK)
  1185. {
  1186. MY_OUTPUT(L"ENTER ***** __EventFilter Delete failed...", 4);
  1187. }
  1188. SysFreeString(instName);
  1189. instName = NULL;
  1190. //
  1191. // Delete the __FilterToConsumerBinding. Looks as follows -
  1192. //__FilterToConsumerBinding.
  1193. //Consumer="CommandLineEventConsumer.Name=\"{944E9251-6C58-11d3-90E9-006097919914}\"",
  1194. //Filter="__EventFilter.Name=\"{944E9251-6C58-11d3-90E9-006097919914}\""
  1195. //
  1196. wcscpy(szTemp, L"MicrosoftHM_ActionConfiguration.GUID=\"");
  1197. lstrcat(szTemp, m_szGUID);
  1198. lstrcat(szTemp, L"\"");
  1199. hRetRes = GetWbemObjectInst(&g_pIWbemServices, szTemp, NULL, &pInst);
  1200. if (!pInst)
  1201. {
  1202. return FALSE;
  1203. }
  1204. hRetRes = GetStrProperty(pInst, L"EventConsumer", &pszEventConsumer);
  1205. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  1206. pInst->Release();
  1207. pInst = NULL;
  1208. // We need to format the strings a bit, need extra backslashes in there
  1209. pStr = wcschr(pszEventConsumer, ':');
  1210. MY_ASSERT(pStr); if (!pStr) goto Badstring;
  1211. pStr++;
  1212. pStr2 = wcschr(pStr, '\"');
  1213. MY_ASSERT(pStr2); if (!pStr2) goto Badstring;
  1214. *pStr2 = '\0';
  1215. wcscpy(szTemp, L"__FilterToConsumerBinding.Consumer=\"");
  1216. lstrcat(szTemp, L"\\\\\\\\.\\\\root\\\\cimv2\\\\MicrosoftHealthMonitor:");
  1217. lstrcat(szTemp, pStr);
  1218. lstrcat(szTemp, L"\\\"");
  1219. pStr = pStr2;
  1220. pStr++;
  1221. pStr2 = wcschr(pStr, '\"');
  1222. MY_ASSERT(pStr2); if (!pStr2) goto Badstring;
  1223. *pStr2 = '\0';
  1224. lstrcat(szTemp, pStr);
  1225. lstrcat(szTemp, L"\\\"\",Filter=\"\\\\\\\\.\\\\root\\\\cimv2\\\\MicrosoftHealthMonitor:");
  1226. lstrcat(szTemp, L"__EventFilter.Name=\\\"");
  1227. lstrcat(szTemp, m_szGUID);
  1228. lstrcat(szTemp, L"\\\"\"");
  1229. instName = SysAllocString(szTemp);
  1230. MY_ASSERT(instName); if (!instName) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  1231. if ((hRes = g_pIWbemServices->DeleteInstance(instName, 0L, NULL, NULL)) != S_OK)
  1232. {
  1233. MY_OUTPUT(L"ENTER ***** __FilterToConsumerBinding Delete failed...", 4);
  1234. }
  1235. SysFreeString(instName);
  1236. instName = NULL;
  1237. goto Goodstring;
  1238. Badstring:
  1239. MY_OUTPUT(L"ENTER ***** Bad FilterToConsumer string", 4);
  1240. Goodstring:
  1241. delete [] pszEventConsumer;
  1242. pszEventConsumer = NULL;
  1243. return TRUE;
  1244. error:
  1245. MY_ASSERT(FALSE);
  1246. if (pszEventConsumer)
  1247. delete [] pszEventConsumer;
  1248. if (instName)
  1249. SysFreeString(instName);
  1250. if (pInst)
  1251. pInst->Release();
  1252. return FALSE;
  1253. }
  1254. //
  1255. // Delete the Action Configuration instance and everything that goes with it.
  1256. // Need to delete the ActionConfiguration, __EventConsumer, all ConfigActionAssoc's,
  1257. // __EventFilter's, __FilterToConsumerBinding's
  1258. //
  1259. BOOL CAction::DeleteAConfig(void)
  1260. {
  1261. HRESULT hRes;
  1262. QLIST qList;
  1263. QSTRUCT Q;
  1264. QSTRUCT *pQ;
  1265. int i, iSize;
  1266. TCHAR szTemp[1024];
  1267. TCHAR *pszEventConsumer = NULL;
  1268. BSTR instName = NULL;
  1269. LPTSTR pStr1;
  1270. LPTSTR pStr2;
  1271. LPTSTR pStr3;
  1272. LPTSTR pStr4;
  1273. BSTR Language = NULL;
  1274. BSTR Query = NULL;
  1275. IEnumWbemClassObject *pEnum;
  1276. IWbemClassObject *pAssocObj = NULL;
  1277. ULONG uReturned;
  1278. IWbemClassObject* pInst = NULL;
  1279. HRESULT hRetRes = S_OK;
  1280. MY_OUTPUT(L"ENTER ***** CAction::DeleteAConfig...", 1);
  1281. TCHAR msgbuf[1024];
  1282. wsprintf(msgbuf, L"DELETE: AGUID=%s", m_szGUID);
  1283. MY_OUTPUT(msgbuf, 4);
  1284. //
  1285. // Get rid of all associations to the action.
  1286. // Make use of other function, loop through all associations
  1287. //
  1288. Language = SysAllocString(L"WQL");
  1289. MY_ASSERT(Language); if (!Language) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  1290. wcscpy(szTemp, L"REFERENCES OF {MicrosoftHM_ActionConfiguration.GUID=\"");
  1291. lstrcat(szTemp, m_szGUID);
  1292. lstrcat(szTemp, L"\"} WHERE ResultClass=MicrosoftHM_ConfigurationActionAssociation");
  1293. Query = SysAllocString(szTemp);
  1294. MY_ASSERT(Query); if (!Query) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  1295. // Initialize IEnumWbemClassObject pointer
  1296. pEnum = 0;
  1297. // Issue query
  1298. hRes = g_pIWbemServices->ExecQuery(Language, Query, WBEM_FLAG_FORWARD_ONLY, 0, &pEnum);
  1299. SysFreeString(Query);
  1300. Query = NULL;
  1301. SysFreeString(Language);
  1302. Language = NULL;
  1303. if (hRes != 0)
  1304. {
  1305. MY_OUTPUT(L"ENTER ***** DeleteAConfig failed...", 4);
  1306. return FALSE;
  1307. }
  1308. // Retrieve objects in result set
  1309. while (TRUE)
  1310. {
  1311. pAssocObj = NULL;
  1312. uReturned = 0;
  1313. hRes = pEnum->Next(0, 1, &pAssocObj, &uReturned);
  1314. if (uReturned == 0)
  1315. {
  1316. break;
  1317. }
  1318. hRetRes = GetStrProperty(pAssocObj, L"ParentPath", &Q.szUserConfigPath);
  1319. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  1320. hRetRes = GetStrProperty(pAssocObj, L"ChildPath", &Q.szChildPath);
  1321. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  1322. qList.push_back(Q);
  1323. // Release it.
  1324. pAssocObj->Release();
  1325. pAssocObj = NULL;
  1326. }
  1327. // All done
  1328. pEnum->Release();
  1329. pEnum = NULL;
  1330. iSize = qList.size();
  1331. for (i=0; i<iSize; i++)
  1332. {
  1333. MY_ASSERT(i<qList.size());
  1334. pQ = &qList[i];
  1335. pStr1 = wcschr(pQ->szUserConfigPath, '\"');
  1336. if (pStr1)
  1337. {
  1338. pStr1++;
  1339. pStr2 = wcschr(pStr1, '\"');
  1340. if (pStr2)
  1341. {
  1342. *pStr2 = '\0';
  1343. }
  1344. }
  1345. pStr3 = wcschr(pQ->szChildPath, '\"');
  1346. if (pStr3)
  1347. {
  1348. pStr3++;
  1349. pStr4 = wcschr(pStr3, '\"');
  1350. if (pStr4)
  1351. {
  1352. *pStr4 = '\0';
  1353. }
  1354. }
  1355. DeleteConfigActionAssoc(pStr1, pStr3);
  1356. if (pQ->szUserConfigPath)
  1357. delete [] pQ->szUserConfigPath;
  1358. if (pQ->szChildPath)
  1359. delete [] pQ->szChildPath;
  1360. }
  1361. qList.clear();
  1362. //
  1363. // Finally we can get rid of the __EventFilter and __FilterToConsumerBinding.
  1364. //
  1365. DeleteEFAndFTCB();
  1366. //
  1367. // Finally we can get rid of the actual ActionConfiguration instance, and the __EventConsumer.
  1368. //
  1369. wcscpy(szTemp, L"MicrosoftHM_ActionConfiguration.GUID=\"");
  1370. lstrcat(szTemp, m_szGUID);
  1371. lstrcat(szTemp, L"\"");
  1372. hRetRes = GetWbemObjectInst(&g_pIWbemServices, szTemp, NULL, &pInst);
  1373. if (!pInst)
  1374. {
  1375. MY_HRESASSERT(hRetRes);
  1376. return FALSE;
  1377. }
  1378. hRetRes = GetStrProperty(pInst, L"EventConsumer", &pszEventConsumer);
  1379. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  1380. pInst->Release();
  1381. pInst = NULL;
  1382. instName = SysAllocString(szTemp);
  1383. MY_ASSERT(instName); if (!instName) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  1384. if ((hRes = g_pIWbemServices->DeleteInstance(instName, 0L, NULL, NULL)) != S_OK)
  1385. {
  1386. MY_OUTPUT(L"ENTER ***** ActionConfiguration Delete failed...", 4);
  1387. }
  1388. SysFreeString(instName);
  1389. instName = NULL;
  1390. instName = SysAllocString(pszEventConsumer);
  1391. MY_ASSERT(instName); if (!instName) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  1392. if ((hRes = g_pIWbemServices->DeleteInstance(instName, 0L, NULL, NULL)) != S_OK)
  1393. {
  1394. MY_OUTPUT(L"ENTER ***** EventConsumer Delete failed...", 4);
  1395. }
  1396. SysFreeString(instName);
  1397. instName = NULL;
  1398. delete [] pszEventConsumer;
  1399. pszEventConsumer = NULL;
  1400. MY_OUTPUT(L"EXIT ***** CAction::DeleteAConfig...", 1);
  1401. return TRUE;
  1402. error:
  1403. MY_ASSERT(FALSE);
  1404. if (pszEventConsumer)
  1405. delete [] pszEventConsumer;
  1406. if (instName)
  1407. SysFreeString(instName);
  1408. if (Query)
  1409. SysFreeString(Query);
  1410. if (Language)
  1411. SysFreeString(Language);
  1412. if (pAssocObj)
  1413. pAssocObj->Release();
  1414. if (pEnum)
  1415. pEnum->Release();
  1416. if (pInst)
  1417. pInst->Release();
  1418. return FALSE;
  1419. }
  1420. // This is only for event sending related to going into a scheduled outage time,
  1421. // or the disabling of the action.
  1422. BOOL CAction::FireEvent(long lErrorCode, LPTSTR pszErrorDescription, int iResString)
  1423. {
  1424. HRESULT hRetRes = S_OK;
  1425. GUID guid;
  1426. HRESULT hRes;
  1427. BOOL bRetValue = TRUE;
  1428. IWbemClassObject* pInstance = NULL;
  1429. LPVOID lpMsgBuf = NULL;
  1430. TCHAR szTemp[1024] = L"";
  1431. TCHAR buf[256] = L"";
  1432. MY_OUTPUT(L"ENTER ***** CAction::FireEvent...", 2);
  1433. // Don't send if no-one is listening!
  1434. if (g_pActionEventSink == NULL)
  1435. {
  1436. return bRetValue;
  1437. }
  1438. if (iResString != HMRES_ACTION_LOADFAIL)
  1439. {
  1440. if (m_pszStatusGUID)
  1441. {
  1442. delete [] m_pszStatusGUID;
  1443. m_pszStatusGUID = NULL;
  1444. }
  1445. hRetRes = CoCreateGuid(&guid);
  1446. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  1447. m_pszStatusGUID = new TCHAR[100];
  1448. MY_ASSERT(m_pszStatusGUID); if (!m_pszStatusGUID) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  1449. StringFromGUID2(guid, m_pszStatusGUID, 100);
  1450. wcscpy(m_szDTTime, m_szDTCurrTime);
  1451. wcscpy(m_szTime, m_szCurrTime);
  1452. }
  1453. hRes = GetHMActionStatus(&pInstance, NULL, L"MicrosoftHM_ActionStatusEvent", iResString);
  1454. if (SUCCEEDED(hRes))
  1455. {
  1456. // Add in the extra error info if available
  1457. if (lErrorCode != -1)
  1458. {
  1459. if (g_hResLib == NULL || !LoadString(g_hResLib, iResString, szTemp, 1024))
  1460. {
  1461. MY_ASSERT(FALSE);
  1462. wcscpy(szTemp, L"Could not locate resource string.");
  1463. }
  1464. wsprintf(buf, L" 0x%08x : ", lErrorCode);
  1465. wcsncat(szTemp, buf, 1023-wcslen(szTemp));
  1466. szTemp[1023] = '\0';
  1467. if (g_hWbemComnModule)
  1468. {
  1469. FormatMessage(FORMAT_MESSAGE_MAX_WIDTH_MASK|FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_HMODULE,
  1470. g_hWbemComnModule, lErrorCode, 0, (LPTSTR) &lpMsgBuf, 0, NULL);
  1471. if (lpMsgBuf)
  1472. {
  1473. wcsncat(szTemp, (LPCTSTR)lpMsgBuf, 1023-wcslen(szTemp));
  1474. szTemp[1023] = '\0';
  1475. LocalFree(lpMsgBuf);
  1476. wcsncat(szTemp, L". ", 1023-wcslen(szTemp));
  1477. szTemp[1023] = '\0';
  1478. }
  1479. }
  1480. if (pszErrorDescription)
  1481. {
  1482. wcsncat(szTemp, pszErrorDescription, 1023-wcslen(szTemp));
  1483. szTemp[1023] = '\0';
  1484. }
  1485. PutStrProperty(pInstance, L"Message", szTemp);
  1486. }
  1487. MY_OUTPUT2(L"EVENT: Action State Change=%d", m_lCurrState, 4);
  1488. if (g_pActionEventSink)
  1489. {
  1490. hRes = g_pActionEventSink->Indicate(1, &pInstance);
  1491. //WBEM_E_SERVER_TOO_BUSY is Ok. Wbem will deliver.
  1492. if (FAILED(hRes) && hRes != WBEM_E_SERVER_TOO_BUSY)
  1493. {
  1494. MY_HRESASSERT(hRes);
  1495. bRetValue = FALSE;
  1496. MY_OUTPUT(L"Failed on Indicate!", 4);
  1497. }
  1498. }
  1499. pInstance->Release();
  1500. pInstance = NULL;
  1501. }
  1502. else
  1503. {
  1504. MY_HRESASSERT(hRes);
  1505. MY_OUTPUT(L"failed to get instance!", 1);
  1506. }
  1507. MY_OUTPUT(L"EXIT ***** CAction::FireEvent...", 2);
  1508. return bRetValue;
  1509. error:
  1510. MY_ASSERT(FALSE);
  1511. if (pInstance)
  1512. pInstance->Release();
  1513. return FALSE;
  1514. }
  1515. HRESULT CAction::GetHMActionStatus(IWbemClassObject** ppInstance, IWbemClassObject* pObj, LPTSTR pszClass, int iResString)
  1516. {
  1517. BOOL bRetValue = TRUE;
  1518. IWbemClassObject* pClass = NULL;
  1519. TCHAR szTemp[1024];
  1520. BSTR bsString = NULL;
  1521. HRESULT hRes;
  1522. HRESULT hRetRes;
  1523. VARIANT v;
  1524. long lState;
  1525. DWORD dwNameLen = MAX_COMPUTERNAME_LENGTH + 2;
  1526. TCHAR szComputerName[MAX_COMPUTERNAME_LENGTH + 2];
  1527. VariantInit(&v);
  1528. MY_OUTPUT(L"ENTER ***** CAction::GetHMActionStatus...", 1);
  1529. bsString = SysAllocString(pszClass);
  1530. MY_ASSERT(bsString); if (!bsString) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  1531. hRes = g_pIWbemServices->GetObject(bsString, 0L, NULL, &pClass, NULL);
  1532. SysFreeString(bsString);
  1533. bsString = NULL;
  1534. if (FAILED(hRes))
  1535. {
  1536. MY_HRESASSERT(hRes);
  1537. return hRes;
  1538. }
  1539. hRes = pClass->SpawnInstance(0, ppInstance);
  1540. pClass->Release();
  1541. pClass = NULL;
  1542. if (FAILED(hRes))
  1543. {
  1544. MY_HRESASSERT(hRes);
  1545. return hRes;
  1546. }
  1547. if (iResString != HMRES_ACTION_LOADFAIL)
  1548. {
  1549. PutStrProperty(*ppInstance, L"GUID", m_szGUID);
  1550. PutStrProperty(*ppInstance, L"Name", m_szName);
  1551. if (GetComputerName(szComputerName, &dwNameLen))
  1552. {
  1553. PutStrProperty(*ppInstance, L"SystemName", szComputerName);
  1554. }
  1555. else
  1556. {
  1557. PutStrProperty(*ppInstance, L"SystemName", L"LocalMachine");
  1558. }
  1559. if (pObj)
  1560. {
  1561. hRetRes = GetUint32Property(pObj, L"State", &lState);
  1562. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  1563. PutUint32Property(*ppInstance, L"State", lState);
  1564. }
  1565. else
  1566. {
  1567. PutUint32Property(*ppInstance, L"State", m_lCurrState);
  1568. }
  1569. if (pObj)
  1570. {
  1571. VariantInit(&v);
  1572. V_VT(&v) = VT_UNKNOWN;
  1573. V_UNKNOWN(&v) = (IUnknown*)pObj;
  1574. (V_UNKNOWN(&v))->AddRef();
  1575. hRes = (*ppInstance)->Put(L"EmbeddedStatusEvent", 0L, &v, 0L);
  1576. VariantClear(&v);
  1577. MY_HRESASSERT(hRes);
  1578. }
  1579. PutStrProperty(*ppInstance, L"TimeGeneratedGMT", m_szDTCurrTime);
  1580. PutStrProperty(*ppInstance, L"LocalTimeFormatted", m_szCurrTime);
  1581. PutStrProperty(*ppInstance, L"StatusGUID", m_pszStatusGUID);
  1582. }
  1583. else
  1584. {
  1585. PutUint32Property(*ppInstance, L"State", HM_CRITICAL);
  1586. PutStrProperty(*ppInstance, L"Name", L"...");
  1587. }
  1588. if (g_hResLib == NULL || !LoadString(g_hResLib, iResString, szTemp, 1024))
  1589. {
  1590. MY_ASSERT(FALSE);
  1591. wcscpy(szTemp, L"Could not locate resource string.");
  1592. }
  1593. PutStrProperty(*ppInstance, L"Message", szTemp);
  1594. MY_OUTPUT(L"EXIT ***** CAction::GetHMActionStatus...", 1);
  1595. return hRes;
  1596. error:
  1597. MY_ASSERT(FALSE);
  1598. if (bsString)
  1599. SysFreeString(bsString);
  1600. if (pClass)
  1601. pClass->Release();
  1602. return hRetRes;
  1603. }
  1604. LPTSTR CAction::GetGUID(void)
  1605. {
  1606. return m_szGUID;
  1607. }
  1608. HRESULT CAction::SendHMActionStatusInstances(IWbemObjectSink* pSink)
  1609. {
  1610. HRESULT hRes = S_OK;
  1611. IWbemClassObject* pObj = NULL;
  1612. int iResString;
  1613. MY_OUTPUT(L"ENTER ***** CAction::SendHMActionStatusInstances...", 2);
  1614. if (m_bValidLoad == FALSE)
  1615. return WBEM_E_INVALID_OBJECT;
  1616. if (pSink == NULL)
  1617. {
  1618. MY_OUTPUT(L"Instances-Invalid Sink", 1);
  1619. return WBEM_E_INVALID_PARAMETER;
  1620. }
  1621. if (m_lCurrState==HM_SCHEDULEDOUT)
  1622. {
  1623. iResString = HMRES_ACTION_OUTAGE;
  1624. }
  1625. else if (m_lCurrState==HM_DISABLED)
  1626. {
  1627. iResString = HMRES_ACTION_DISABLE;
  1628. }
  1629. else if (m_lCurrState==HM_CRITICAL)
  1630. {
  1631. iResString = HMRES_ACTION_FAILED;
  1632. }
  1633. else
  1634. {
  1635. iResString = HMRES_ACTION_ENABLE;
  1636. }
  1637. // Provide Instance
  1638. hRes = GetHMActionStatus(&pObj, NULL, L"MicrosoftHM_ActionStatus", iResString);
  1639. if (SUCCEEDED(hRes))
  1640. {
  1641. hRes = pSink->Indicate(1, &pObj);
  1642. if (FAILED(hRes) && hRes!=WBEM_E_SERVER_TOO_BUSY && hRes!=WBEM_E_CALL_CANCELLED && hRes!=WBEM_E_TRANSPORT_FAILURE)
  1643. {
  1644. MY_HRESASSERT(hRes);
  1645. MY_OUTPUT(L"SendHMSystemStatusInstances-failed to send status!", 1);
  1646. }
  1647. pObj->Release();
  1648. pObj = NULL;
  1649. }
  1650. else
  1651. {
  1652. MY_HRESASSERT(hRes);
  1653. MY_OUTPUT(L":SendHMSystemStatusInstances-failed to get instance!", 1);
  1654. }
  1655. MY_OUTPUT(L"EXIT ***** CAction::SendHMSystemStatusInstances...", 2);
  1656. return hRes;
  1657. }
  1658. // For a single GetObject
  1659. HRESULT CAction::SendHMActionStatusInstance(IWbemObjectSink* pSink, LPTSTR pszGUID)
  1660. {
  1661. MY_OUTPUT(L"ENTER ***** CAction::SendHMActionStatusInstance...", 1);
  1662. //
  1663. // Is this the one we are looking for?
  1664. //
  1665. if (!_wcsicmp(m_szGUID, pszGUID))
  1666. {
  1667. if (m_bValidLoad == FALSE)
  1668. return WBEM_E_INVALID_OBJECT;
  1669. SendHMActionStatusInstances(pSink);
  1670. return S_OK;
  1671. }
  1672. MY_OUTPUT(L"EXIT ***** CAction::SendHMActionStatusInstance...", 1);
  1673. return WBEM_S_DIFFERENT;
  1674. }
  1675. BOOL CAction::checkTime(void)
  1676. {
  1677. BOOL bTimeOK;
  1678. SYSTEMTIME st; // system time
  1679. //
  1680. // Make sure that we are in a valid time to run.
  1681. // NULL (-1) means run all the time.
  1682. //
  1683. bTimeOK = FALSE;
  1684. if (m_bEnabled==TRUE)
  1685. {
  1686. GetLocalTime(&st);
  1687. bTimeOK = FALSE;
  1688. // Check the Day of the Week
  1689. if (!(m_iActiveDays&(1<<st.wDayOfWeek)))
  1690. {
  1691. }
  1692. else if (m_lBeginHourTime<0 || m_lEndHourTime<0)
  1693. {
  1694. bTimeOK = TRUE;
  1695. }
  1696. else if (m_lBeginHourTime==m_lEndHourTime && m_lBeginMinuteTime==m_lEndMinuteTime)
  1697. {
  1698. // Check the Hours of operation
  1699. // First see if we are doing an inclusive time tests, or an exclusive time test
  1700. // Case where the time is exactly equal, and that means run this once per day
  1701. if (st.wHour==m_lBeginHourTime && st.wMinute==m_lBeginMinuteTime)
  1702. {
  1703. if (st.wSecond <= HM_POLLING_INTERVAL)
  1704. {
  1705. bTimeOK = TRUE;
  1706. }
  1707. }
  1708. }
  1709. else if ((m_lBeginHourTime < m_lEndHourTime) ||
  1710. ((m_lBeginHourTime==m_lEndHourTime) && m_lBeginMinuteTime < m_lEndMinuteTime))
  1711. {
  1712. // Inclusive case
  1713. if ((m_lBeginHourTime < st.wHour) ||
  1714. ((m_lBeginHourTime == st.wHour) && m_lBeginMinuteTime <= st.wMinute))
  1715. {
  1716. if ((st.wHour < m_lEndHourTime) ||
  1717. ((st.wHour == m_lEndHourTime) && st.wMinute < m_lEndMinuteTime))
  1718. {
  1719. bTimeOK = TRUE;
  1720. }
  1721. }
  1722. }
  1723. else
  1724. {
  1725. // Exclusive case
  1726. if ((m_lEndHourTime > st.wHour) ||
  1727. ((m_lEndHourTime == st.wHour) && m_lEndMinuteTime > st.wMinute))
  1728. {
  1729. bTimeOK = TRUE;
  1730. }
  1731. else if ((st.wHour > m_lBeginHourTime) ||
  1732. ((st.wHour == m_lBeginHourTime) && st.wMinute >= m_lBeginMinuteTime))
  1733. {
  1734. bTimeOK = TRUE;
  1735. }
  1736. }
  1737. }
  1738. return bTimeOK;
  1739. }
  1740. CBase *CAction::FindImediateChildByName(LPTSTR pszName)
  1741. {
  1742. MY_ASSERT(FALSE);
  1743. return NULL;
  1744. }
  1745. BOOL CAction::GetNextChildName(LPTSTR pszChildName, LPTSTR pszOutName)
  1746. {
  1747. MY_ASSERT(FALSE);
  1748. return NULL;
  1749. }
  1750. CBase *CAction::FindPointerFromName(LPTSTR pszName)
  1751. {
  1752. MY_ASSERT(FALSE);
  1753. return NULL;
  1754. }
  1755. #ifdef SAVE
  1756. BOOL CAction::ModifyAssocForMove(CBase *pNewParentBase)
  1757. {
  1758. MY_ASSERT(FALSE);
  1759. return TRUE;
  1760. }
  1761. #endif
  1762. BOOL CAction::ReceiveNewChildForMove(CBase *pBase)
  1763. {
  1764. MY_ASSERT(FALSE);
  1765. return FALSE;
  1766. }
  1767. BOOL CAction::DeleteChildFromList(LPTSTR pszGUID)
  1768. {
  1769. MY_ASSERT(FALSE);
  1770. return FALSE;
  1771. }
  1772. BOOL CAction::SendReminderActionIfStateIsSame(IWbemObjectSink* pActionEventSink, IWbemObjectSink* pActionTriggerEventSink, IWbemClassObject* pActionInstance, IWbemClassObject* pActionTriggerInstance, unsigned long ulTriggerStates)
  1773. {
  1774. MY_ASSERT(FALSE);
  1775. return FALSE;
  1776. }
  1777. BOOL CAction::HandleTempErrorEvent(BSTR szGUID, long lErrorCode, LPTSTR pszErrorDescription)
  1778. {
  1779. if (m_bValidLoad == FALSE)
  1780. return FALSE;
  1781. //
  1782. // Is this us we are looking for?
  1783. //
  1784. if (!_wcsicmp(m_szGUID, szGUID))
  1785. {
  1786. m_lCurrState = HM_CRITICAL;
  1787. FireEvent(lErrorCode, pszErrorDescription, HMRES_ACTION_FAILED);
  1788. return TRUE;
  1789. }
  1790. return FALSE;
  1791. }
  1792. BOOL CAction::Cleanup(BOOL bClearAll)
  1793. {
  1794. int i, iSize;
  1795. QSTRUCT *pQ;
  1796. if (m_szName)
  1797. {
  1798. delete [] m_szName;
  1799. m_szName = NULL;
  1800. }
  1801. if (m_szDescription)
  1802. {
  1803. delete [] m_szDescription;
  1804. m_szDescription = NULL;
  1805. }
  1806. if (m_szTypeGUID)
  1807. {
  1808. delete [] m_szTypeGUID;
  1809. m_szTypeGUID = NULL;
  1810. }
  1811. if (bClearAll)
  1812. {
  1813. if (m_pszStatusGUID)
  1814. {
  1815. delete [] m_pszStatusGUID;
  1816. m_pszStatusGUID = NULL;
  1817. }
  1818. iSize = m_qList.size();
  1819. for (i=0; i<iSize; i++)
  1820. {
  1821. MY_ASSERT(i<m_qList.size());
  1822. pQ = &m_qList[i];
  1823. if (pQ->szQuery)
  1824. delete [] pQ->szQuery;
  1825. if (pQ->szConfigActionAssocPath)
  1826. delete [] pQ->szConfigActionAssocPath;
  1827. if (pQ->szUserConfigPath)
  1828. delete [] pQ->szUserConfigPath;
  1829. if (pQ->szChildPath)
  1830. delete [] pQ->szChildPath;
  1831. if (pQ->pTempSink)
  1832. {
  1833. g_pIWbemServices->CancelAsyncCall((IWbemObjectSink*)pQ->pTempSink);
  1834. pQ->pTempSink->Release();
  1835. pQ->pTempSink = NULL;
  1836. }
  1837. }
  1838. m_qList.clear();
  1839. }
  1840. return TRUE;
  1841. }
  1842. HRESULT CAction::RemapAction(void)
  1843. {
  1844. HRESULT hRetRes = S_OK;
  1845. QLIST qList;
  1846. TCHAR szTemp[1024];
  1847. LPTSTR pStr2;
  1848. TCHAR *pszEventConsumer = NULL;
  1849. LPTSTR pStr;
  1850. IWbemClassObject* pInst = NULL;
  1851. MY_OUTPUT(L"ENTER ***** CAction::RemapAction...", 1);
  1852. wcscpy(szTemp, L"MicrosoftHM_ActionConfiguration.GUID=\"");
  1853. lstrcat(szTemp, m_szGUID);
  1854. lstrcat(szTemp, L"\"");
  1855. hRetRes = GetWbemObjectInst(&g_pIWbemServices, szTemp, NULL, &pInst);
  1856. if (!pInst)
  1857. {
  1858. MY_HRESASSERT(hRetRes);
  1859. return FALSE;
  1860. }
  1861. hRetRes = GetStrProperty(pInst, L"EventConsumer", &pszEventConsumer);
  1862. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  1863. pInst->Release();
  1864. pInst = NULL;
  1865. //
  1866. // __EventConsumer.
  1867. //
  1868. hRetRes = GetWbemObjectInst(&g_pIWbemServices, pszEventConsumer, NULL, &pInst);
  1869. if (!pInst)
  1870. {
  1871. MY_HRESASSERT(hRetRes);
  1872. return FALSE;
  1873. }
  1874. hRetRes = RemapOneAction(pInst);
  1875. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  1876. pInst->Release();
  1877. pInst = NULL;
  1878. //
  1879. // __EventFilter.
  1880. //
  1881. wcscpy(szTemp, L"__EventFilter.Name=\"");
  1882. lstrcat(szTemp, m_szGUID);
  1883. lstrcat(szTemp, L"\"");
  1884. hRetRes = GetWbemObjectInst(&g_pIWbemServices, szTemp, NULL, &pInst);
  1885. if (!pInst)
  1886. {
  1887. MY_HRESASSERT(hRetRes);
  1888. return FALSE;
  1889. }
  1890. hRetRes = RemapOneAction(pInst);
  1891. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  1892. pInst->Release();
  1893. pInst = NULL;
  1894. //
  1895. // __FilterToConsumerBinding
  1896. //
  1897. // We need to format the strings a bit, need extra backslashes in there
  1898. pStr = wcschr(pszEventConsumer, ':');
  1899. MY_ASSERT(pStr); if (!pStr) goto Badstring;
  1900. pStr++;
  1901. pStr2 = wcschr(pStr, '\"');
  1902. MY_ASSERT(pStr2); if (!pStr2) goto Badstring;
  1903. *pStr2 = '\0';
  1904. wcscpy(szTemp, L"__FilterToConsumerBinding.Consumer=\"");
  1905. lstrcat(szTemp, L"\\\\\\\\.\\\\root\\\\cimv2\\\\MicrosoftHealthMonitor:");
  1906. lstrcat(szTemp, pStr);
  1907. lstrcat(szTemp, L"\\\"");
  1908. pStr = pStr2;
  1909. pStr++;
  1910. pStr2 = wcschr(pStr, '\"');
  1911. MY_ASSERT(pStr2); if (!pStr2) goto Badstring;
  1912. *pStr2 = '\0';
  1913. lstrcat(szTemp, pStr);
  1914. lstrcat(szTemp, L"\\\"\",Filter=\"\\\\\\\\.\\\\root\\\\cimv2\\\\MicrosoftHealthMonitor:");
  1915. lstrcat(szTemp, L"__EventFilter.Name=\\\"");
  1916. lstrcat(szTemp, m_szGUID);
  1917. lstrcat(szTemp, L"\\\"\"");
  1918. hRetRes = GetWbemObjectInst(&g_pIWbemServices, szTemp, NULL, &pInst);
  1919. if (!pInst)
  1920. {
  1921. MY_HRESASSERT(hRetRes);
  1922. return FALSE;
  1923. }
  1924. hRetRes = RemapOneAction(pInst);
  1925. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  1926. pInst->Release();
  1927. pInst = NULL;
  1928. goto Goodstring;
  1929. Badstring:
  1930. MY_OUTPUT(L"ENTER ***** Bad FilterToConsumer string", 4);
  1931. Goodstring:
  1932. delete [] pszEventConsumer;
  1933. pszEventConsumer = NULL;
  1934. MY_OUTPUT(L"EXIT ***** CAction::RemapAction...", 1);
  1935. return TRUE;
  1936. error:
  1937. MY_ASSERT(FALSE);
  1938. if (pszEventConsumer)
  1939. delete [] pszEventConsumer;
  1940. if (pInst)
  1941. pInst->Release();
  1942. return FALSE;
  1943. }
  1944. HRESULT CAction::RemapOneAction(IWbemClassObject* pObj)
  1945. {
  1946. HANDLE hToken = NULL;
  1947. HRESULT hRetRes = S_OK;
  1948. IWbemCallResult *pResult = 0;
  1949. SAFEARRAY* psa = NULL;
  1950. VARIANT var;
  1951. CIMTYPE vtType;
  1952. long lBound, uBound;
  1953. BOOL bObjIsLocalSystem;
  1954. BOOL bSuccess;
  1955. SID_IDENTIFIER_AUTHORITY ntauth = SECURITY_NT_AUTHORITY;
  1956. DWORD dwLengthNeeded;
  1957. void* psid = 0;
  1958. PTOKEN_USER pUserInfo = NULL;
  1959. VariantInit(&var);
  1960. // Need to verify that we're in fact running under the LocalSystem SID!
  1961. // otherwise we'd end up in an infinite loop! Need an assert to check that
  1962. // the current thread is running as LocalSystem.
  1963. bSuccess = OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &hToken);
  1964. MY_ASSERT(bSuccess); if (!bSuccess) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  1965. // Call GetTokenInformation to get the buffer size.
  1966. dwLengthNeeded = 0;
  1967. bSuccess = GetTokenInformation(hToken, TokenUser, NULL, dwLengthNeeded, &dwLengthNeeded);
  1968. // Allocate the buffer.
  1969. pUserInfo = (PTOKEN_USER) GlobalAlloc(GPTR, dwLengthNeeded);
  1970. MY_ASSERT(pUserInfo); if (!pUserInfo) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  1971. // Call GetTokenInformation again to get the group information.
  1972. bSuccess = GetTokenInformation(hToken, TokenUser, pUserInfo, dwLengthNeeded, &dwLengthNeeded);
  1973. MY_ASSERT(bSuccess); if (!bSuccess) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  1974. bSuccess = AllocateAndInitializeSid(&ntauth, 1, SECURITY_LOCAL_SYSTEM_RID, 0, 0, 0, 0, 0, 0, 0, &psid);
  1975. MY_ASSERT(bSuccess); if (!bSuccess) {hRetRes = WBEM_E_OUT_OF_MEMORY; goto error;}
  1976. // Verify that winmgmt is running under LocalSystem. If not we don't do anything.
  1977. if (EqualSid(pUserInfo->User.Sid, psid))
  1978. {
  1979. // get the CreatorSID of this instance
  1980. hRetRes = pObj->Get(L"CreatorSID", 0, &var, &vtType, NULL);
  1981. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  1982. if (vtType != (CIM_UINT8 | CIM_FLAG_ARRAY))
  1983. {
  1984. hRetRes = WBEM_E_FAILED;
  1985. goto error;
  1986. }
  1987. // make sure it's the right size
  1988. psa = var.parray;
  1989. if (::SafeArrayGetElemsize(psa) != 1)
  1990. {
  1991. hRetRes = WBEM_E_FAILED;
  1992. goto error;
  1993. }
  1994. hRetRes = ::SafeArrayGetLBound(psa, 1, &lBound);
  1995. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  1996. hRetRes = ::SafeArrayGetUBound(psa, 1, &uBound);
  1997. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  1998. if (lBound !=0)
  1999. {
  2000. hRetRes = WBEM_E_FAILED;
  2001. goto error;
  2002. }
  2003. // now see if this is LocalSystem by comparing to
  2004. // the hardcoded LocalSystem SID
  2005. bObjIsLocalSystem = false;
  2006. if (uBound == (sizeof LocalSystemSID)-1 )
  2007. {
  2008. LPVOID lpCreatorSID = NULL;
  2009. hRetRes = ::SafeArrayAccessData(psa, &lpCreatorSID);
  2010. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  2011. if (memcmp (lpCreatorSID, LocalSystemSID, sizeof LocalSystemSID) == 0)
  2012. {
  2013. bObjIsLocalSystem = true;
  2014. }
  2015. hRetRes = ::SafeArrayUnaccessData(psa);
  2016. MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  2017. }
  2018. // If it's not a LocalSystem SID, to replace it with a LocalSytem SID,
  2019. // we need to just store the instance in WMI-- WMI will automatically
  2020. // replace the SID that's there with our SID-- LocalSystem.
  2021. //
  2022. if (bObjIsLocalSystem == FALSE)
  2023. {
  2024. hRetRes = g_pIWbemServices->PutInstance(pObj, WBEM_FLAG_UPDATE_ONLY, NULL, &pResult);
  2025. // MY_HRESASSERT(hRetRes); if (hRetRes!=S_OK) goto error;
  2026. }
  2027. VariantClear(&var);
  2028. }
  2029. CloseHandle(hToken);
  2030. FreeSid(psid);
  2031. if (pUserInfo)
  2032. GlobalFree(pUserInfo);
  2033. return S_OK;
  2034. error:
  2035. MY_OUTPUT2(L"11 0x%08x\n",hRetRes,5);
  2036. MY_ASSERT(FALSE);
  2037. VariantClear(&var);
  2038. CloseHandle(hToken);
  2039. FreeSid(psid);
  2040. if (pUserInfo)
  2041. GlobalFree(pUserInfo);
  2042. return hRetRes;
  2043. }
  2044. HRESULT CAction::CheckForBadLoad(void)
  2045. {
  2046. HRESULT hRetRes = S_OK;
  2047. IWbemClassObject* pObj = NULL;
  2048. TCHAR szTemp[1024];
  2049. if (m_bValidLoad == FALSE)
  2050. {
  2051. wcscpy(szTemp, L"MicrosoftHM_ActionConfiguration.GUID=\"");
  2052. lstrcat(szTemp, m_szGUID);
  2053. lstrcat(szTemp, L"\"");
  2054. hRetRes = GetWbemObjectInst(&g_pIWbemServices, szTemp, NULL, &pObj);
  2055. if (!pObj)
  2056. {
  2057. MY_HRESASSERT(hRetRes);
  2058. return S_FALSE;
  2059. }
  2060. hRetRes = LoadInstanceFromMOF(pObj, FALSE);
  2061. // Here is where we can try and send out a generic SOS if the load failed each time!!!
  2062. if (hRetRes != S_OK)
  2063. {
  2064. FireEvent(-1, NULL, HMRES_ACTION_LOADFAIL);
  2065. }
  2066. MY_HRESASSERT(hRetRes);
  2067. pObj->Release();
  2068. pObj = NULL;
  2069. return hRetRes;
  2070. }
  2071. return S_OK;
  2072. }