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.

612 lines
18 KiB

  1. //*****************************************************************************
  2. //
  3. // Copyright (c) 1996-1999, Microsoft Corporation, All rights reserved
  4. //
  5. // EVENTREP.CPP
  6. //
  7. // This file implements basic classes for event representation.
  8. //
  9. // See eventrep.h for documentation.
  10. //
  11. // History:
  12. //
  13. // 11/27/96 a-levn Compiles.
  14. //
  15. //*****************************************************************************
  16. #include "precomp.h"
  17. #include <stdio.h>
  18. #include <ess.h>
  19. CTimeKeeper CEventRepresentation::mstatic_TimeKeeper;
  20. CEventRepresentation::CEventTypeData CEventRepresentation::staticTypes[] =
  21. {
  22. {e_EventTypeExtrinsic, L"__ExtrinsicEvent", NULL},
  23. {e_EventTypeNamespaceCreation, L"__NamespaceCreationEvent", NULL},
  24. {e_EventTypeNamespaceDeletion, L"__NamespaceDeletionEvent", NULL},
  25. {e_EventTypeNamespaceModification, L"__NamespaceModificationEvent", NULL},
  26. {e_EventTypeClassCreation, L"__ClassCreationEvent", NULL},
  27. {e_EventTypeClassDeletion, L"__ClassDeletionEvent", NULL},
  28. {e_EventTypeClassModification, L"__ClassModificationEvent", NULL},
  29. {e_EventTypeInstanceCreation, L"__InstanceCreationEvent", NULL},
  30. {e_EventTypeInstanceDeletion, L"__InstanceDeletionEvent", NULL},
  31. {e_EventTypeInstanceModification, L"__InstanceModificationEvent", NULL},
  32. {e_EventTypeTimer, L"__TimerEvent", NULL}
  33. };
  34. IWbemDecorator* CEventRepresentation::mstatic_pDecorator = NULL;
  35. //******************************************************************************
  36. // public
  37. //
  38. // See eventrep.h for documentation
  39. //
  40. //******************************************************************************
  41. int CEventRepresentation::NumEventTypes()
  42. {
  43. return sizeof(staticTypes) / sizeof CEventTypeData;
  44. }
  45. //******************************************************************************
  46. // public
  47. //
  48. // See eventrep.h for documentation
  49. //
  50. //******************************************************************************
  51. HRESULT CEventRepresentation::Initialize(IWbemServices* pNamespace,
  52. IWbemDecorator* pDecorator)
  53. {
  54. mstatic_pDecorator = pDecorator;
  55. pDecorator->AddRef();
  56. return WBEM_S_NO_ERROR;
  57. }
  58. HRESULT CEventRepresentation::Shutdown()
  59. {
  60. if(mstatic_pDecorator)
  61. {
  62. mstatic_pDecorator->Release();
  63. mstatic_pDecorator = NULL;
  64. }
  65. for(int i = 0; i < NumEventTypes(); i++)
  66. {
  67. if(staticTypes[i].pEventClass != NULL)
  68. {
  69. staticTypes[i].pEventClass->Release();
  70. staticTypes[i].pEventClass = NULL;
  71. }
  72. }
  73. return WBEM_S_NO_ERROR;
  74. }
  75. //******************************************************************************
  76. // public
  77. //
  78. // See eventrep.h for documentation
  79. //
  80. //******************************************************************************
  81. CEventRepresentation::~CEventRepresentation()
  82. {
  83. if(m_bAllocated)
  84. {
  85. // All fields have been allocated, and need to be deleted
  86. // ======================================================
  87. delete [] wsz1;
  88. delete [] wsz2;
  89. delete [] wsz3;
  90. for(int i = 0; i < nObjects; i++)
  91. {
  92. (apObjects[i])->Release();
  93. }
  94. delete [] apObjects;
  95. }
  96. if(m_pCachedObject)
  97. m_pCachedObject->Release();
  98. }
  99. //******************************************************************************
  100. // public
  101. //
  102. // See eventrep.h for documentation
  103. //
  104. //******************************************************************************
  105. DELETE_ME CEventRepresentation* CEventRepresentation::MakePermanentCopy()
  106. {
  107. // Allocate a new event structure and set flags to "allocated"
  108. // ===========================================================
  109. CEventRepresentation* pCopy = _new CEventRepresentation;
  110. if(pCopy == NULL)
  111. return NULL;
  112. pCopy->m_bAllocated = TRUE;
  113. pCopy->type = type;
  114. pCopy->dw1 = dw1;
  115. pCopy->dw2 = dw2;
  116. if(wsz1)
  117. {
  118. pCopy->wsz1 = _new WCHAR[wcslen(wsz1)+1];
  119. if(pCopy->wsz1 == NULL)
  120. {
  121. delete pCopy;
  122. return NULL;
  123. }
  124. StringCchCopyW( pCopy->wsz1, wcslen(wsz1)+1, wsz1 );
  125. }
  126. else pCopy->wsz1 = NULL;
  127. if(wsz2)
  128. {
  129. pCopy->wsz2 = _new WCHAR[wcslen(wsz2)+1];
  130. if(pCopy->wsz2 == NULL)
  131. {
  132. delete pCopy;
  133. return NULL;
  134. }
  135. StringCchCopyW( pCopy->wsz2, wcslen(wsz2)+1, wsz2 );
  136. }
  137. else pCopy->wsz2 = NULL;
  138. if(wsz3)
  139. {
  140. pCopy->wsz3 = _new WCHAR[wcslen(wsz3)+1];
  141. if(pCopy->wsz3 == NULL)
  142. {
  143. delete pCopy;
  144. return NULL;
  145. }
  146. StringCchCopyW(pCopy->wsz3, wcslen(wsz3)+1, wsz3 );
  147. }
  148. else pCopy->wsz3 = NULL;
  149. pCopy->nObjects = nObjects;
  150. pCopy->apObjects = _new IWbemClassObject*[nObjects];
  151. if(pCopy->apObjects == NULL)
  152. {
  153. delete pCopy;
  154. return NULL;
  155. }
  156. // Make fresh copies of all objects
  157. // ================================
  158. // TBD: more effecient solutions may be possible here!
  159. for(int i = 0; i < nObjects; i++)
  160. {
  161. HRESULT hres = apObjects[i]->Clone(pCopy->apObjects + i);
  162. if(FAILED(hres))
  163. {
  164. // Abort
  165. pCopy->nObjects = i; // successfully copied
  166. delete pCopy;
  167. return NULL;
  168. }
  169. }
  170. return pCopy;
  171. }
  172. //******************************************************************************
  173. // public
  174. //
  175. // See esssink.h for documentation
  176. //
  177. //******************************************************************************
  178. INTERNAL LPCWSTR CEventRepresentation::GetEventName(EEventType type)
  179. {
  180. for(int i = 0; i < NumEventTypes(); i++)
  181. {
  182. if(staticTypes[i].type == type) return staticTypes[i].wszEventName;
  183. }
  184. return NULL;
  185. }
  186. //******************************************************************************
  187. // public
  188. //
  189. // See esssink.h for documentation
  190. //
  191. //******************************************************************************
  192. INTERNAL IWbemClassObject* CEventRepresentation::GetEventClass(
  193. CEssNamespace* pNamespace, EEventType type)
  194. {
  195. for(int i = 0; i < NumEventTypes(); i++)
  196. {
  197. if(staticTypes[i].type == type)
  198. {
  199. if(staticTypes[i].pEventClass == NULL)
  200. {
  201. _IWmiObject* pClass = NULL;
  202. HRESULT hres = pNamespace->GetClass(staticTypes[i].wszEventName,
  203. &pClass);
  204. if(FAILED(hres))
  205. return NULL;
  206. staticTypes[i].pEventClass = pClass;
  207. }
  208. return staticTypes[i].pEventClass;
  209. }
  210. }
  211. return NULL;
  212. }
  213. INTERNAL IWbemClassObject* CEventRepresentation::GetEventClass(CEss* pEss,
  214. EEventType type)
  215. {
  216. CEssNamespace* pNamespace = NULL;
  217. HRESULT hres = pEss->GetNamespaceObject( L"root", FALSE, &pNamespace);
  218. if(FAILED(hres))
  219. return NULL;
  220. IWbemClassObject* pClass = GetEventClass(pNamespace, type);
  221. pNamespace->Release();
  222. return pClass;
  223. }
  224. //******************************************************************************
  225. // public
  226. //
  227. // See esssink.h for documentation
  228. //
  229. //******************************************************************************
  230. DWORD CEventRepresentation::GetTypeMaskFromName(READ_ONLY LPCWSTR wszEventName)
  231. {
  232. if(wszEventName[0] != '_')
  233. return 1 << e_EventTypeExtrinsic;
  234. for(int i = 0; i < NumEventTypes(); i++)
  235. {
  236. if(!wbem_wcsicmp(staticTypes[i].wszEventName, wszEventName))
  237. return (1 << staticTypes[i].type);
  238. }
  239. if(!wbem_wcsicmp(wszEventName, L"__Event"))
  240. {
  241. return 0xFFFFFFFF;
  242. }
  243. if(!wbem_wcsicmp(wszEventName, L"__NamespaceOperationEvent"))
  244. {
  245. return (1 << e_EventTypeNamespaceCreation) |
  246. (1 << e_EventTypeNamespaceDeletion) |
  247. (1 << e_EventTypeNamespaceModification);
  248. }
  249. if(!wbem_wcsicmp(wszEventName, L"__ClassOperationEvent"))
  250. {
  251. return (1 << e_EventTypeClassCreation) |
  252. (1 << e_EventTypeClassDeletion) |
  253. (1 << e_EventTypeClassModification);
  254. }
  255. if(!wbem_wcsicmp(wszEventName, L"__InstanceOperationEvent"))
  256. {
  257. return (1 << e_EventTypeInstanceCreation) |
  258. (1 << e_EventTypeInstanceDeletion) |
  259. (1 << e_EventTypeInstanceModification);
  260. }
  261. if(!wbem_wcsicmp(wszEventName, EVENT_DROP_CLASS) ||
  262. !wbem_wcsicmp(wszEventName, QUEUE_OVERFLOW_CLASS) ||
  263. !wbem_wcsicmp(wszEventName, CONSUMER_FAILURE_CLASS))
  264. {
  265. return (1 << e_EventTypeSystem);
  266. }
  267. return 1 << e_EventTypeExtrinsic;
  268. }
  269. //******************************************************************************
  270. // public
  271. //
  272. // See esssink.h for documentation
  273. //
  274. //******************************************************************************
  275. EEventType CEventRepresentation::GetTypeFromName(READ_ONLY LPCWSTR wszEventName)
  276. {
  277. for(int i = 0; i < NumEventTypes(); i++)
  278. {
  279. if(!wbem_wcsicmp(staticTypes[i].wszEventName, wszEventName))
  280. return staticTypes[i].type;
  281. }
  282. return e_EventTypeExtrinsic;
  283. }
  284. //******************************************************************************
  285. // public
  286. //
  287. // See esssink.h for documentation
  288. //
  289. //******************************************************************************
  290. HRESULT CEventRepresentation::MakeWbemObject(
  291. CEssNamespace* pNamespace,
  292. RELEASE_ME IWbemClassObject** ppEventObj)
  293. {
  294. HRESULT hres;
  295. // Check if we have a cached copy
  296. // ==============================
  297. if(m_pCachedObject != NULL)
  298. {
  299. *ppEventObj = m_pCachedObject;
  300. m_pCachedObject->AddRef();
  301. return S_OK;
  302. }
  303. if(type == e_EventTypeExtrinsic || type == e_EventTypeTimer ||
  304. type == e_EventTypeSystem)
  305. {
  306. *ppEventObj = apObjects[0];
  307. mstatic_TimeKeeper.DecorateObject((_IWmiObject*)apObjects[0]);
  308. (*ppEventObj)->AddRef();
  309. return S_OK;
  310. }
  311. // Create an instance
  312. // ==================
  313. IWbemClassObject* pClass = GetEventClass(pNamespace, (EEventType)type);
  314. if(pClass == NULL)
  315. {
  316. return WBEM_E_NOT_FOUND;
  317. }
  318. IWbemClassObject* pEventObj = NULL;
  319. if(FAILED(pClass->SpawnInstance(0, &pEventObj)))
  320. {
  321. return WBEM_E_FAILED;
  322. }
  323. CReleaseMe rm1(pEventObj);
  324. // Set event-dependent properties
  325. // ==============================
  326. VARIANT vFirst, vSecond;
  327. VariantInit(&vFirst);
  328. VariantInit(&vSecond);
  329. CClearMe cm1(&vFirst);
  330. CClearMe cm2(&vSecond);
  331. if(nObjects > 0)
  332. {
  333. V_VT(&vFirst) = VT_EMBEDDED_OBJECT;
  334. V_EMBEDDED_OBJECT(&vFirst) = apObjects[0];
  335. apObjects[0]->AddRef();
  336. }
  337. if(nObjects > 1)
  338. {
  339. V_VT(&vSecond) = VT_EMBEDDED_OBJECT;
  340. V_EMBEDDED_OBJECT(&vSecond) = apObjects[1];
  341. if(apObjects[1])
  342. {
  343. apObjects[1]->AddRef();
  344. }
  345. else
  346. V_VT(&vSecond) = VT_NULL; // no previous!
  347. }
  348. LPCWSTR wszFirstProp = NULL, wszSecondProp = NULL;
  349. hres = WBEM_E_CRITICAL_ERROR;
  350. switch(type)
  351. {
  352. case e_EventTypeInstanceCreation:
  353. hres = pEventObj->Put(TARGET_INSTANCE_PROPNAME, 0, &vFirst, 0);
  354. break;
  355. case e_EventTypeInstanceDeletion:
  356. hres = pEventObj->Put(TARGET_INSTANCE_PROPNAME, 0, &vFirst, 0);
  357. break;
  358. case e_EventTypeInstanceModification:
  359. hres = pEventObj->Put(TARGET_INSTANCE_PROPNAME, 0, &vFirst, 0);
  360. if(SUCCEEDED(hres))
  361. hres = pEventObj->Put(PREVIOUS_INSTANCE_PROPNAME, 0,
  362. &vSecond, 0);
  363. break;
  364. case e_EventTypeClassCreation:
  365. hres = pEventObj->Put(TARGET_CLASS_PROPNAME, 0, &vFirst, 0);
  366. break;
  367. case e_EventTypeClassDeletion:
  368. hres = pEventObj->Put(TARGET_CLASS_PROPNAME, 0, &vFirst, 0);
  369. break;
  370. case e_EventTypeClassModification:
  371. hres = pEventObj->Put(TARGET_CLASS_PROPNAME, 0, &vFirst, 0);
  372. if(SUCCEEDED(hres))
  373. hres = pEventObj->Put(PREVIOUS_CLASS_PROPNAME, 0, &vSecond,
  374. 0);
  375. break;
  376. case e_EventTypeNamespaceCreation:
  377. hres = pEventObj->Put(TARGET_NAMESPACE_PROPNAME, 0, &vFirst, 0);
  378. break;
  379. case e_EventTypeNamespaceDeletion:
  380. hres = pEventObj->Put(TARGET_NAMESPACE_PROPNAME, 0, &vFirst, 0);
  381. break;
  382. case e_EventTypeNamespaceModification:
  383. hres = pEventObj->Put(TARGET_NAMESPACE_PROPNAME, 0, &vFirst, 0);
  384. if(SUCCEEDED(hres))
  385. hres = pEventObj->Put(PREVIOUS_NAMESPACE_PROPNAME, 0,
  386. &vSecond, 0);
  387. break;
  388. }
  389. if(FAILED(hres))
  390. return hres;
  391. // Decorate it
  392. // ===========
  393. if(mstatic_pDecorator)
  394. {
  395. hres = mstatic_pDecorator->DecorateObject(pEventObj, wsz1);
  396. if(FAILED(hres))
  397. return hres;
  398. }
  399. mstatic_TimeKeeper.DecorateObject((_IWmiObject*)pEventObj);
  400. // Store it in our cache
  401. // =====================
  402. m_pCachedObject = pEventObj;
  403. m_pCachedObject->AddRef();
  404. *ppEventObj = pEventObj;
  405. (*ppEventObj)->AddRef();
  406. return S_OK;
  407. }
  408. HRESULT CEventRepresentation::CreateFromObject(IWbemClassObject* pEvent,
  409. LPWSTR wszNamespace)
  410. {
  411. HRESULT hres;
  412. // Get the class of the event
  413. // ==========================
  414. VARIANT vClass;
  415. VariantInit(&vClass);
  416. if (FAILED(hres = pEvent->Get(L"__CLASS", 0, &vClass, NULL, NULL)))
  417. return hres;
  418. type = GetTypeFromName(V_BSTR(&vClass));
  419. dw1 = 0;
  420. dw2 = 0;
  421. wsz1 = _new WCHAR[wcslen(wszNamespace)+1];
  422. if (!wsz1)
  423. return WBEM_E_OUT_OF_MEMORY;
  424. StringCchCopyW( wsz1, wcslen(wszNamespace)+1, wszNamespace );
  425. wsz2 = NULL;
  426. wsz3 = NULL;
  427. nObjects = 1;
  428. m_bAllocated = TRUE;
  429. IWbemClassObject** aEmbedded = new IWbemClassObject*[2];
  430. if (!aEmbedded)
  431. return WBEM_E_OUT_OF_MEMORY;
  432. apObjects = (IWbemClassObject**)aEmbedded;
  433. aEmbedded[0] = pEvent;
  434. pEvent->AddRef();
  435. VariantClear(&vClass);
  436. // If the event is an intrinsic one, get the class of the target object
  437. // ====================================================================
  438. VARIANT vEmbed;
  439. VariantInit(&vEmbed);
  440. #define SET_FIRST_OBJECT \
  441. { \
  442. pEvent->Release(); \
  443. aEmbedded[0] = (IWbemClassObject*)V_EMBEDDED_OBJECT(&vEmbed); \
  444. aEmbedded[0]->AddRef(); \
  445. aEmbedded[0]->Get(L"__CLASS", 0, &vClass, NULL, NULL); \
  446. wsz2 = _new WCHAR[wcslen(V_BSTR(&vClass))+1]; \
  447. StringCchCopyW( wsz2, wcslen(V_BSTR(&vClass))+1,V_BSTR(&vClass)); \
  448. VariantClear(&vEmbed); \
  449. VariantClear(&vClass); \
  450. }
  451. #define SET_SECOND_OBJECT \
  452. { \
  453. nObjects = 2; \
  454. aEmbedded[1] = (IWbemClassObject*)V_EMBEDDED_OBJECT(&vEmbed); \
  455. aEmbedded[1]->AddRef(); \
  456. VariantClear(&vEmbed); \
  457. }
  458. switch(type)
  459. {
  460. case e_EventTypeClassModification:
  461. hres = pEvent->Get(PREVIOUS_CLASS_PROPNAME, 0, &vEmbed, NULL, NULL);
  462. if(SUCCEEDED(hres))
  463. SET_SECOND_OBJECT;
  464. case e_EventTypeClassCreation:
  465. case e_EventTypeClassDeletion:
  466. hres = pEvent->Get(TARGET_CLASS_PROPNAME, 0, &vEmbed, NULL, NULL);
  467. if(SUCCEEDED(hres))
  468. SET_FIRST_OBJECT
  469. break;
  470. case e_EventTypeInstanceModification:
  471. hres = pEvent->Get(PREVIOUS_INSTANCE_PROPNAME, 0, &vEmbed,
  472. NULL, NULL);
  473. if(SUCCEEDED(hres))
  474. SET_SECOND_OBJECT;
  475. case e_EventTypeInstanceCreation:
  476. case e_EventTypeInstanceDeletion:
  477. hres = pEvent->Get(TARGET_INSTANCE_PROPNAME, 0, &vEmbed,
  478. NULL, NULL);
  479. if(SUCCEEDED(hres))
  480. SET_FIRST_OBJECT;
  481. break;
  482. case e_EventTypeNamespaceModification:
  483. hres = pEvent->Get(PREVIOUS_NAMESPACE_PROPNAME, 0, &vEmbed,
  484. NULL, NULL);
  485. if(SUCCEEDED(hres))
  486. SET_SECOND_OBJECT;
  487. case e_EventTypeNamespaceCreation:
  488. case e_EventTypeNamespaceDeletion:
  489. hres = pEvent->Get(TARGET_NAMESPACE_PROPNAME, 0, &vEmbed,
  490. NULL, NULL);
  491. if(SUCCEEDED(hres))
  492. SET_FIRST_OBJECT;
  493. break;
  494. }
  495. return WBEM_S_NO_ERROR;
  496. }
  497. STDMETHODIMP CEventRepresentation::InheritsFrom(WBEM_WSTR wszName)
  498. {
  499. if(type == e_EventTypeExtrinsic)
  500. return apObjects[0]->InheritsFrom(wszName);
  501. LPCWSTR wszEventName = GetEventName((EEventType)type);
  502. if(wszEventName == NULL)
  503. return WBEM_E_OUT_OF_MEMORY;
  504. if(!wbem_wcsicmp(wszName, wszEventName))
  505. return S_OK;
  506. if(!wbem_wcsicmp(wszName, L"__IndicationRelated"))
  507. return S_OK;
  508. if(!wbem_wcsicmp(wszName, L"__Event"))
  509. return S_OK;
  510. if(!wbem_wcsicmp(wszName, L"__NamespaceOperationEvent") &&
  511. wcsstr(wszEventName, L"Namespace"))
  512. return S_OK;
  513. if(!wbem_wcsicmp(wszName, L"__ClassOperationEvent") &&
  514. wcsstr(wszEventName, L"Class"))
  515. return S_OK;
  516. if(!wbem_wcsicmp(wszName, L"__InstanceOperationEvent") &&
  517. wcsstr(wszEventName, L"Instance"))
  518. return S_OK;
  519. return S_FALSE;
  520. }