Leaked source code of windows server 2003
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.

604 lines
16 KiB

  1. //#--------------------------------------------------------------
  2. //
  3. // File: saconsumer.cpp
  4. //
  5. // Synopsis: This file holds the implementation of the
  6. // CSAConsumer class
  7. //
  8. // History: 12/10/2000 serdarun Created
  9. //
  10. // Copyright (C) 1999-2000 Microsoft Corporation
  11. // All rights reserved.
  12. //
  13. //#--------------------------------------------------------------
  14. #include "stdafx.h"
  15. #include "ldm.h"
  16. #include "SAConsumer.h"
  17. const WCHAR ELEMENT_RETRIEVER [] = L"Elementmgr.ElementRetriever";
  18. const WCHAR RESOURCE_CONTAINER [] = L"LOCALUIAlertDefinitions";
  19. const WCHAR SA_ALERTS [] = L"SA_Alerts";
  20. //
  21. // name of WBEM class
  22. //
  23. const WCHAR PROPERTY_CLASS_NAME [] = L"__CLASS";
  24. const WCHAR PROPERTY_ALERT_ID [] = L"AlertID";
  25. const WCHAR PROPERTY_ALERT_SOURCE [] = L"AlertSource";
  26. const WCHAR PROPERTY_ALERT_LOG [] = L"AlertLog";
  27. const WCHAR PROPERTY_ALERT_COOKIE [] = L"Cookie";
  28. const WCHAR PROPERTY_ALERT_BITCODE [] = L"LocalUIMsgCode";
  29. // Alert Event Classes
  30. const WCHAR CLASS_WBEM_RAISE_ALERT [] = L"Microsoft_SA_RaiseAlert";
  31. const WCHAR CLASS_WBEM_CLEAR_ALERT [] = L"Microsoft_SA_ClearAlert";
  32. //
  33. // Standard IUnknown implementation
  34. //
  35. ULONG CSAConsumer::AddRef()
  36. {
  37. return InterlockedIncrement(&m_lRef);
  38. }
  39. //
  40. // Standard IUnknown implementation
  41. //
  42. ULONG CSAConsumer::Release()
  43. {
  44. if (InterlockedDecrement(&m_lRef) == 0)
  45. {
  46. delete this;
  47. return 0;
  48. }
  49. return m_lRef;
  50. }
  51. //
  52. // Standard IUnknown implementation
  53. //
  54. STDMETHODIMP CSAConsumer::QueryInterface(REFIID riid, LPVOID *ppv)
  55. {
  56. *ppv = NULL;
  57. SATraceFunction("CSAConsumer::QueryInterface");
  58. if (IID_IUnknown==riid)
  59. {
  60. *ppv = (void *)(IUnknown *) this;
  61. AddRef();
  62. return S_OK;
  63. }
  64. else
  65. {
  66. if (IID_IWbemObjectSink==riid)
  67. {
  68. *ppv = (void *)(IWbemObjectSink *) this;
  69. AddRef();
  70. return S_OK;
  71. }
  72. }
  73. return E_NOINTERFACE;
  74. }
  75. //++--------------------------------------------------------------
  76. //
  77. // Function: Indicate
  78. //
  79. // Synopsis: This is the IWbemObjectSink interface method
  80. // through which WBEM calls back to provide the
  81. // event objects
  82. //
  83. // Arguments:
  84. // [in] LONG - number of events
  85. // [in] IWbemClassObject** - array of events
  86. //
  87. // Returns: HRESULT - success/failure
  88. //
  89. // History: serdarun Created 12/10/2000
  90. //
  91. // Called By: WBEM
  92. //
  93. //----------------------------------------------------------------
  94. STDMETHODIMP CSAConsumer::Indicate (
  95. /*[in]*/ LONG lObjectCount,
  96. /*[in]*/ IWbemClassObject **ppObjArray
  97. )
  98. {
  99. HRESULT hr = WBEM_S_NO_ERROR;
  100. BOOL bNewLocalUIAlert = FALSE;
  101. _ASSERT (ppObjArray && (0 != lObjectCount));
  102. //
  103. // check if we have somthing to process
  104. //
  105. if ((!ppObjArray) || (0 == lObjectCount))
  106. {
  107. return (WBEM_E_INVALID_PARAMETER);
  108. }
  109. CComBSTR bstrClassName = CComBSTR(PROPERTY_CLASS_NAME);
  110. if (bstrClassName.m_str == NULL)
  111. {
  112. SATraceString ("CSAConsumer::Indicate failed on memory allocation");
  113. return E_OUTOFMEMORY;
  114. }
  115. try
  116. {
  117. SATraceString ("CSAConsumer::Indicate-WMI called with event objects");
  118. for (LONG lCount = 0; lCount < lObjectCount; lCount++)
  119. {
  120. //
  121. // get the event type
  122. //
  123. CComVariant vtName;
  124. hr = ppObjArray[lCount]->Get (
  125. bstrClassName,
  126. 0, //reserved
  127. &vtName,
  128. NULL, // type
  129. NULL // flavor
  130. );
  131. if (FAILED (hr))
  132. {
  133. SATracePrintf("CSAConsumer-Consumer unable to get event name:%x",hr);
  134. break;
  135. }
  136. if ( ( 0 == _wcsicmp (CLASS_WBEM_CLEAR_ALERT, V_BSTR (&vtName)) ) ||
  137. ( 0 == _wcsicmp (CLASS_WBEM_RAISE_ALERT, V_BSTR (&vtName)) ) )
  138. {
  139. bNewLocalUIAlert = TRUE;
  140. }
  141. }
  142. if (bNewLocalUIAlert)
  143. {
  144. //
  145. // Notify clients about this alert
  146. //
  147. ::PostMessage(m_hwndMainWindow,wm_SaAlertMessage,(WPARAM)0,(LPARAM)0);
  148. //
  149. // calculate the new message code and notify saldm
  150. //
  151. // don't need it anymore, no led support
  152. CalculateMsgCodeAndNotify();
  153. }
  154. }
  155. catch (...)
  156. {
  157. SATraceString("Exception occured in CSAConsumer::Indicate method");
  158. }
  159. //
  160. // we don't have enumeration, so just return
  161. //
  162. return WBEM_S_NO_ERROR;
  163. } // end of CSAConsumer::Indicate method
  164. //++--------------------------------------------------------------
  165. //
  166. // Function: SetStatus
  167. //
  168. // Synopsis: This is the IWbemObjectSink interface method
  169. // through which WBEM calls in to indicate end of
  170. // event sequence or provide other error codes
  171. //
  172. // Arguments:
  173. // [in] LONG - progress
  174. // [in] HRESULT - status information
  175. // [in] BSTR - string info
  176. // [in] IWbemClassObject* - status object
  177. //
  178. // Returns: HRESULT - success/failure
  179. //
  180. // History: serdarun Created 12/10/2000
  181. //
  182. // Called By: WBEM
  183. //
  184. //----------------------------------------------------------------
  185. STDMETHODIMP CSAConsumer::SetStatus (
  186. /*[in]*/ LONG lFlags,
  187. /*[in]*/ HRESULT hResult,
  188. /*[in]*/ BSTR strParam,
  189. /*[in]*/ IWbemClassObject *pObjParam
  190. )
  191. {
  192. SATracePrintf ("SAConsumer-IWbemObjectSink::SetStatus called:%x",hResult);
  193. return (WBEM_S_NO_ERROR);
  194. } // end of CSAConsumer::SetStatus method
  195. STDMETHODIMP CSAConsumer::SetServiceWindow(
  196. /*[in]*/ HWND hwndMainWindow
  197. )
  198. {
  199. m_hwndMainWindow = hwndMainWindow;
  200. return S_OK;
  201. }
  202. //++--------------------------------------------------------------
  203. //
  204. // Function: CalculateMsgCodeAndNotify
  205. //
  206. // Synopsis: calculate the new message code and notify saldm
  207. //
  208. // Arguments: none
  209. //
  210. // Returns: HRESULT - success/failure
  211. //
  212. // History: serdarun Created 01/16/2001
  213. //
  214. //----------------------------------------------------------------
  215. STDMETHODIMP CSAConsumer::CalculateMsgCodeAndNotify(void)
  216. {
  217. HRESULT hr;
  218. //
  219. // will contain the class id for element manager
  220. //
  221. CLSID clsid;
  222. //
  223. // element manager pointer
  224. //
  225. CComPtr<IWebElementRetriever> pWebElementRetriever = NULL;
  226. CComPtr<IDispatch> pDispatch = NULL;
  227. //
  228. // All of the sa alerts
  229. //
  230. CComPtr<IWebElementEnum> pAlertEnum = NULL;
  231. //
  232. // Localui alert definitions
  233. //
  234. CComPtr<IWebElementEnum> pAlertDefEnum = NULL;
  235. //
  236. // LocalUI message code
  237. //
  238. DWORD dwLocalUIMsgCode = 1;
  239. //
  240. // number of sa alerts
  241. //
  242. LONG lAlertCount = 0;
  243. //
  244. // enumaration of sa alerts
  245. //
  246. CComPtr<IEnumVARIANT> pEnumVariant = NULL;
  247. CComPtr<IUnknown> pUnknown = NULL;
  248. DWORD dwElementsLeft = 0;
  249. CComVariant varElement;
  250. CComBSTR bstrSaAlerts = CComBSTR(SA_ALERTS);
  251. CComBSTR bstrResourceContainer = CComBSTR(RESOURCE_CONTAINER);
  252. CComBSTR bstrAlertLog = CComBSTR(PROPERTY_ALERT_LOG);
  253. CComBSTR bstrAlertID = CComBSTR(PROPERTY_ALERT_ID);
  254. CComBSTR bstrAlertBitCode = CComBSTR(PROPERTY_ALERT_BITCODE);
  255. if ( (bstrSaAlerts.m_str == NULL) ||
  256. (bstrResourceContainer.m_str == NULL)||
  257. (bstrAlertLog.m_str == NULL)||
  258. (bstrAlertID.m_str == NULL)||
  259. (bstrAlertBitCode.m_str == NULL) )
  260. {
  261. SATraceString("CSAConsumer::CalculateMsgCodeAndNotify failed on memory allocation ");
  262. return E_OUTOFMEMORY;
  263. }
  264. //
  265. // get the CLSID for Element manager
  266. //
  267. hr = ::CLSIDFromProgID (ELEMENT_RETRIEVER,&clsid);
  268. if (FAILED (hr))
  269. {
  270. SATracePrintf ("CSAConsumer::CalculateMsgCodeAndNotify failed on CLSIDFromProgID:%x",hr);
  271. return hr;
  272. }
  273. //
  274. // create the Element Retriever now
  275. //
  276. hr = ::CoCreateInstance (
  277. clsid,
  278. NULL,
  279. CLSCTX_LOCAL_SERVER,
  280. IID_IWebElementRetriever,
  281. (PVOID*) &pWebElementRetriever
  282. );
  283. if (FAILED (hr))
  284. {
  285. SATracePrintf ("CSAConsumer::CalculateMsgCodeAndNotify failed on CoCreateInstance:%x",hr);
  286. return hr;
  287. }
  288. //
  289. // get all of the sa alerts
  290. //
  291. hr = pWebElementRetriever->GetElements (
  292. 1,
  293. bstrSaAlerts,
  294. &pDispatch
  295. );
  296. if (FAILED (hr))
  297. {
  298. SATracePrintf ("CSAConsumer::CalculateMsgCodeAndNotify failed on GetElements for sa alerts:%x",hr);
  299. return hr;
  300. }
  301. //
  302. // get the enum variant for sa alerts
  303. //
  304. hr = pDispatch->QueryInterface (
  305. IID_IWebElementEnum,
  306. (LPVOID*) (&pAlertEnum)
  307. );
  308. if (FAILED (hr))
  309. {
  310. SATracePrintf ("CSAConsumer::CalculateMsgCodeAndNotify failed on QueryInterface:%x",hr);
  311. return hr;
  312. }
  313. //
  314. // get number of alerts
  315. //
  316. hr = pAlertEnum->get_Count (&lAlertCount);
  317. if (FAILED (hr))
  318. {
  319. SATracePrintf ("CResCtrl::GetLocalUIResources failed on get_Count:%x",hr);
  320. return hr;
  321. }
  322. //
  323. // no alerts, just send message code zero to main window
  324. //
  325. if (0 == lAlertCount)
  326. {
  327. ::PostMessage(m_hwndMainWindow,wm_SaLEDMessage,WPARAM(dwLocalUIMsgCode),(LPARAM)0);
  328. return S_OK;
  329. }
  330. pDispatch = NULL;
  331. //
  332. // get localui alert definitions
  333. //
  334. hr = pWebElementRetriever->GetElements (
  335. 1,
  336. bstrResourceContainer,
  337. &pDispatch
  338. );
  339. if (FAILED (hr))
  340. {
  341. SATracePrintf ("CSAConsumer::CalculateMsgCodeAndNotify failed on GetElements for alert definitions:%x",hr);
  342. return hr;
  343. }
  344. //
  345. // get the enum variant
  346. //
  347. hr = pDispatch->QueryInterface (
  348. IID_IWebElementEnum,
  349. (LPVOID*) (&pAlertDefEnum)
  350. );
  351. if (FAILED (hr))
  352. {
  353. SATracePrintf ("CSAConsumer::CalculateMsgCodeAndNotify failed on QueryInterface:%x",hr);
  354. return hr;
  355. }
  356. //
  357. // enumerate sa alerts and find the localui ones
  358. //
  359. hr = pAlertEnum->get__NewEnum (&pUnknown);
  360. if (FAILED (hr))
  361. {
  362. SATracePrintf ("CSAConsumer::CalculateMsgCodeAndNotify failed on get__NewEnum:%x",hr);
  363. return hr;
  364. }
  365. //
  366. // get the enum variant
  367. //
  368. hr = pUnknown->QueryInterface (
  369. IID_IEnumVARIANT,
  370. (LPVOID*)(&pEnumVariant)
  371. );
  372. if (FAILED (hr))
  373. {
  374. SATracePrintf ("CSAConsumer::CalculateMsgCodeAndNotify failed on QueryInterface:%x",hr);
  375. return hr;
  376. }
  377. //
  378. // get elements out of the collection and initialize
  379. //
  380. hr = pEnumVariant->Next (1, &varElement, &dwElementsLeft);
  381. if (FAILED (hr))
  382. {
  383. SATracePrintf ("CSAConsumer::CalculateMsgCodeAndNotify failed on Next:%x",hr);
  384. return hr;
  385. }
  386. //
  387. // for each resource
  388. //
  389. while ((dwElementsLeft> 0) && (SUCCEEDED (hr)) )
  390. {
  391. //
  392. // get the IWebElement Interface from alert object
  393. //
  394. CComPtr <IWebElement> pElement;
  395. hr = varElement.pdispVal->QueryInterface (
  396. __uuidof (IWebElement),
  397. (LPVOID*)(&pElement)
  398. );
  399. if (FAILED (hr))
  400. {
  401. SATracePrintf ("CSAConsumer::CalculateMsgCodeAndNotify failed on QueryInterface:%x",hr);
  402. return hr;
  403. }
  404. wstring wsAlertKey;
  405. //
  406. // get the alert log
  407. //
  408. CComVariant vtAlertLog;
  409. hr = pElement->GetProperty (
  410. bstrAlertLog,
  411. &vtAlertLog
  412. );
  413. if (FAILED (hr))
  414. {
  415. SATracePrintf("CSAConsumer-CalculateMsgCodeAndNotify unable to get alert log:%x",hr);
  416. return hr;
  417. }
  418. SATracePrintf("CSAConsumer-CalculateMsgCodeAndNotify alert log:%ws",V_BSTR (&vtAlertLog));
  419. //
  420. // get the alert id
  421. //
  422. CComVariant vtAlertID;
  423. hr = pElement->GetProperty (
  424. bstrAlertID,
  425. &vtAlertID
  426. );
  427. if (FAILED (hr))
  428. {
  429. SATracePrintf("CSAConsumer-CalculateMsgCodeAndNotify unable to get alert id:%x",hr);
  430. return hr;
  431. }
  432. SATracePrintf("CSAConsumer-CalculateMsgCodeAndNotify alert id:%x",V_I4 (&vtAlertID));
  433. WCHAR szAlertID[16];
  434. //
  435. // convert alert id to a hex string
  436. //
  437. swprintf(szAlertID,L"%X",V_I4 (&vtAlertID));
  438. //
  439. // create key name by appending, container+alertlog+alertid
  440. //
  441. wsAlertKey.assign(RESOURCE_CONTAINER);
  442. wsAlertKey.append(V_BSTR (&vtAlertLog));
  443. wsAlertKey.append(szAlertID);
  444. CComVariant vtAlertKey = wsAlertKey.c_str();
  445. SATracePrintf("CSAConsumer-CalculateMsgCodeAndNotify alert element id:%ws",V_BSTR(&vtAlertKey));
  446. CComPtr<IDispatch> pDispElement = NULL;
  447. //
  448. // check if it is a localui alert
  449. //
  450. hr = pAlertDefEnum->Item(&vtAlertKey,&pDispElement);
  451. if ( (SUCCEEDED(hr)) && (pDispElement != NULL) )
  452. {
  453. //
  454. // get the IWebElement Interface from alert definition object
  455. //
  456. CComPtr <IWebElement> pAlertElement = NULL;
  457. hr = pDispElement->QueryInterface (
  458. __uuidof (IWebElement),
  459. (LPVOID*)(&pAlertElement)
  460. );
  461. if (FAILED (hr))
  462. {
  463. SATracePrintf ("CSAConsumer::CalculateMsgCodeAndNotify failed on QueryInterface for IWebElement:%x",hr);
  464. return hr;
  465. }
  466. //
  467. // get the alert message code
  468. //
  469. CComVariant vtAlertMsgCode;
  470. hr = pAlertElement->GetProperty (
  471. bstrAlertBitCode,
  472. &vtAlertMsgCode
  473. );
  474. if (FAILED (hr))
  475. {
  476. SATracePrintf("CSAConsumer-CalculateMsgCodeAndNotify unable to get alert message code:%x",hr);
  477. }
  478. else
  479. {
  480. SATracePrintf("CSAConsumer-CalculateMsgCodeAndNotify message code:%x",V_I4(&vtAlertMsgCode));
  481. dwLocalUIMsgCode |= V_I4(&vtAlertMsgCode);
  482. }
  483. }
  484. //
  485. // clear the perClient value from this variant
  486. //
  487. varElement.Clear ();
  488. //
  489. // get next client out of the collection
  490. //
  491. hr = pEnumVariant->Next (1, &varElement, &dwElementsLeft);
  492. if (FAILED (hr))
  493. {
  494. SATracePrintf ("CSAConsumer-CalculateMsgCodeAndNotify failed on Next:%x",hr);
  495. }
  496. }
  497. ::PostMessage(m_hwndMainWindow,wm_SaLEDMessage,WPARAM(dwLocalUIMsgCode),(LPARAM)0);
  498. return S_OK;
  499. } // end of CSAConsumer::CalculateMsgCodeAndNotify