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.

533 lines
13 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1997 - 1999
  3. Module Name:
  4. cenumsub.cxx
  5. Abstract:
  6. This file contains the implementation of the IEnumEventObject
  7. interface. This is used in implementing SENS publisher-side filtering.
  8. Author:
  9. Gopal Parupudi <GopalP>
  10. [Notes:]
  11. optional-notes
  12. Revision History:
  13. GopalP 1/26/1998 Start.
  14. --*/
  15. #include <precomp.hxx>
  16. //
  17. // Globals
  18. //
  19. LONG g_cEnumSubObj; // Count of active components
  20. LONG g_cEnumSubLock; // Count of Server locks
  21. //
  22. // Constructors and Destructors
  23. //
  24. CImpIEnumSub::CImpIEnumSub(
  25. void
  26. ) : m_cRef(1L), // Add a reference.
  27. m_FiredEvent(EVENT_INVALID),
  28. m_ulConnectionMadeType(0x0),
  29. m_ulConnectionMadeTypeNoQOC(0x0),
  30. m_ulConnectionLostType(0x0),
  31. m_bstrDestination(NULL),
  32. m_bstrDestinationNoQOC(NULL),
  33. m_ulDestinationType(0x0),
  34. m_ulDestinationTypeNoQOC(0x0)
  35. {
  36. InterlockedIncrement(&g_cEnumSubObj);
  37. }
  38. CImpIEnumSub::~CImpIEnumSub(
  39. void
  40. )
  41. {
  42. if (m_bstrDestination != NULL)
  43. {
  44. ::SysFreeString(m_bstrDestination);
  45. }
  46. if (m_bstrDestinationNoQOC != NULL)
  47. {
  48. ::SysFreeString(m_bstrDestinationNoQOC);
  49. }
  50. InterlockedDecrement(&g_cEnumSubObj);
  51. }
  52. //
  53. // Standard QueryInterface
  54. //
  55. STDMETHODIMP
  56. CImpIEnumSub::QueryInterface(
  57. REFIID riid,
  58. LPVOID *ppv
  59. )
  60. {
  61. HRESULT hr;
  62. DebugTraceGuid("CImpIEnumSub:QueryInterface()", riid);
  63. hr = S_OK;
  64. *ppv = NULL;
  65. // IUnknown
  66. if (IsEqualIID(riid, IID_IUnknown))
  67. {
  68. *ppv = (LPUNKNOWN) this;
  69. }
  70. else
  71. // IEnumEventObject
  72. if (IsEqualIID(riid, IID_IEnumEventObject))
  73. {
  74. *ppv = (IEnumEventObject *) this;
  75. }
  76. else
  77. {
  78. hr = E_NOINTERFACE;
  79. }
  80. if (NULL != *ppv)
  81. {
  82. ((LPUNKNOWN)*ppv)->AddRef();
  83. }
  84. return hr;
  85. }
  86. //
  87. // Standard AddRef and Release
  88. //
  89. STDMETHODIMP_(ULONG)
  90. CImpIEnumSub::AddRef(
  91. void
  92. )
  93. {
  94. return InterlockedIncrement(&m_cRef);
  95. }
  96. STDMETHODIMP_(ULONG)
  97. CImpIEnumSub::Release(
  98. void
  99. )
  100. {
  101. LONG cRefT;
  102. SensPrint(SENS_INFO, (SENS_STRING("\t| CImpIEnumSub::Release(m_cRef = %d) called.\n"), m_cRef));
  103. cRefT = InterlockedDecrement((PLONG) &m_cRef);
  104. if (0 == m_cRef)
  105. {
  106. delete this;
  107. }
  108. return cRefT;
  109. }
  110. //
  111. // IDispatch member function implementations. These are dummy implementations
  112. // as EventSystem never calls them.
  113. //
  114. STDMETHODIMP
  115. CImpIEnumSub::GetTypeInfoCount(
  116. UINT *pCountITypeInfo
  117. )
  118. {
  119. return E_NOTIMPL;
  120. }
  121. STDMETHODIMP
  122. CImpIEnumSub::GetTypeInfo(
  123. UINT iTypeInfo,
  124. LCID lcid,
  125. ITypeInfo **ppITypeInfo
  126. )
  127. {
  128. return E_NOTIMPL;
  129. }
  130. STDMETHODIMP
  131. CImpIEnumSub::GetIDsOfNames(
  132. REFIID riid,
  133. LPOLESTR *arrNames,
  134. UINT cNames,
  135. LCID lcid,
  136. DISPID *arrDispIDs)
  137. {
  138. return E_NOTIMPL;
  139. }
  140. STDMETHODIMP
  141. CImpIEnumSub::Invoke(
  142. DISPID dispID,
  143. REFIID riid,
  144. LCID lcid,
  145. WORD wFlags,
  146. DISPPARAMS *pDispParams,
  147. VARIANT *pvarResult,
  148. EXCEPINFO *pExecpInfo,
  149. UINT *puArgErr
  150. )
  151. {
  152. return E_NOTIMPL;
  153. }
  154. //
  155. // IEnumEventObject Implementation.
  156. //
  157. STDMETHODIMP
  158. CImpIEnumSub::Clone(
  159. LPUNKNOWN *ppIUnknown
  160. )
  161. {
  162. return E_NOTIMPL;
  163. }
  164. STDMETHODIMP
  165. CImpIEnumSub::Count(
  166. ULONG *pcAvailableElem
  167. )
  168. {
  169. HRESULT hr;
  170. USHORT i;
  171. ULONG cRequestCount;
  172. ULONG cReturnCount;
  173. BSTR bstrPropertyValue;
  174. BSTR bstrPropertyDestination;
  175. BSTR bstrPropertyType;
  176. ULONG cPubCacheSubs;
  177. IEventSubscription *pIEventSubscription;
  178. hr = S_OK;
  179. bstrPropertyValue = NULL;
  180. bstrPropertyDestination = NULL;
  181. bstrPropertyType = NULL;
  182. pIEventSubscription = NULL;
  183. *pcAvailableElem = 0;
  184. //
  185. // First, count ALL of subscriptions from PubCache.
  186. //
  187. hr = m_pIEnumSubs->Count(&cPubCacheSubs);
  188. if (FAILED(hr))
  189. {
  190. goto Cleanup;
  191. }
  192. *pcAvailableElem = cPubCacheSubs;
  193. Cleanup:
  194. //
  195. // Cleanup
  196. //
  197. return hr;
  198. }
  199. STDMETHODIMP
  200. CImpIEnumSub::Next(
  201. ULONG cRequestElem,
  202. LPUNKNOWN *ppIEventSubscription,
  203. ULONG *pcReturnElem
  204. )
  205. {
  206. HRESULT hr;
  207. ULONG cPubCacheSubs;
  208. ULONG cCount;
  209. ULONG ulCompareType;
  210. WCHAR szCompareType[10]; // To fit a stringized DWORD
  211. BOOL bPropertyPresent;
  212. BSTR bstrCompareDest;
  213. BSTR bstrPropertyDestination;
  214. BSTR bstrPropertyType;
  215. BSTR bstrPropertyValue;
  216. VARIANT variantPropertyValue;
  217. IEventSubscription *pIEventSubscription;
  218. hr = S_OK;
  219. *pcReturnElem = 0;
  220. cCount = 1;
  221. ulCompareType = 0x0;
  222. bstrCompareDest = NULL;
  223. bstrPropertyDestination = NULL;
  224. bstrPropertyType = NULL;
  225. bstrPropertyValue = NULL;
  226. pIEventSubscription = NULL;
  227. switch (m_FiredEvent)
  228. {
  229. case EVENT_CONNECTION_MADE:
  230. bstrPropertyType = ::SysAllocString(PROPERTY_CONNECTION_MADE_TYPE);
  231. if (bstrPropertyType == NULL)
  232. {
  233. hr = E_OUTOFMEMORY;
  234. goto Cleanup;
  235. }
  236. ulCompareType = m_ulConnectionMadeType;
  237. break;
  238. case EVENT_CONNECTION_MADE_NOQOC:
  239. bstrPropertyType = ::SysAllocString(PROPERTY_CONNECTION_MADE_NOQOC_TYPE);
  240. if (bstrPropertyType == NULL)
  241. {
  242. hr = E_OUTOFMEMORY;
  243. goto Cleanup;
  244. }
  245. ulCompareType = m_ulConnectionMadeTypeNoQOC;
  246. break;
  247. case EVENT_CONNECTION_LOST:
  248. bstrPropertyType = ::SysAllocString(PROPERTY_CONNECTION_LOST_TYPE);
  249. if (bstrPropertyType == NULL)
  250. {
  251. hr = E_OUTOFMEMORY;
  252. goto Cleanup;
  253. }
  254. ulCompareType = m_ulConnectionLostType;
  255. break;
  256. case EVENT_DESTINATION_REACHABLE:
  257. bstrPropertyDestination = ::SysAllocString(PROPERTY_DESTINATION);
  258. bstrPropertyType = ::SysAllocString(PROPERTY_DESTINATION_TYPE);
  259. if ( (bstrPropertyDestination == NULL)
  260. || (bstrPropertyType == NULL))
  261. {
  262. hr = E_OUTOFMEMORY;
  263. goto Cleanup;
  264. }
  265. bstrCompareDest = m_bstrDestination;
  266. ulCompareType = m_ulDestinationTypeNoQOC;
  267. break;
  268. case EVENT_DESTINATION_REACHABLE_NOQOC:
  269. bstrPropertyDestination = ::SysAllocString(PROPERTY_DESTINATION_NOQOC);
  270. bstrPropertyType = ::SysAllocString(PROPERTY_DESTINATION_NOQOC_TYPE);
  271. if ( (bstrPropertyDestination == NULL)
  272. || (bstrPropertyType == NULL))
  273. {
  274. hr = E_OUTOFMEMORY;
  275. goto Cleanup;
  276. }
  277. bstrCompareDest = m_bstrDestinationNoQOC;
  278. ulCompareType = m_ulDestinationTypeNoQOC;
  279. break;
  280. case EVENT_INVALID:
  281. default:
  282. hr = E_UNEXPECTED;
  283. goto Cleanup;
  284. } // switch
  285. for (;;)
  286. {
  287. bPropertyPresent = TRUE;
  288. hr = m_pIEnumSubs->Next(
  289. cCount,
  290. (LPUNKNOWN *)&pIEventSubscription,
  291. &cCount
  292. );
  293. if (hr != S_OK)
  294. {
  295. // Return S_FALSE to cause EventSystem loop to stop
  296. hr = S_FALSE;
  297. goto Cleanup;
  298. }
  299. switch (m_FiredEvent)
  300. {
  301. case EVENT_CONNECTION_MADE:
  302. case EVENT_CONNECTION_MADE_NOQOC:
  303. case EVENT_CONNECTION_LOST:
  304. VariantInit(&variantPropertyValue);
  305. hr = pIEventSubscription->GetPublisherProperty(
  306. bstrPropertyType,
  307. &variantPropertyValue
  308. );
  309. if (hr != S_OK)
  310. {
  311. // We consider this a successful match.
  312. SensPrint(SENS_INFO, (SENS_STRING("\t| Subscription::GetPublisherProperty() returned 0x%x\n"), hr));
  313. bPropertyPresent = FALSE;
  314. }
  315. else
  316. {
  317. ASSERT(variantPropertyValue.vt == VT_UI4);
  318. SensPrintW(SENS_INFO, (SENS_BSTR("\t| Property %s has value 0x%x\n"), bstrPropertyType, variantPropertyValue.ulVal));
  319. }
  320. //
  321. // Compare ulType here and pass back if they match
  322. //
  323. if ( (bPropertyPresent == TRUE)
  324. && (variantPropertyValue.ulVal != ulCompareType))
  325. {
  326. SensPrintW(SENS_INFO, (SENS_BSTR("\t| Subscription::PropertyValue was 0x%x!\n"), ulCompareType));
  327. break; // skip to next subscription
  328. }
  329. goto FoundMatchingSubscription;
  330. break;
  331. case EVENT_DESTINATION_REACHABLE:
  332. case EVENT_DESTINATION_REACHABLE_NOQOC:
  333. //
  334. // Compare Destination Name here and pass back if they match
  335. //
  336. VariantInit(&variantPropertyValue);
  337. hr = pIEventSubscription->GetPublisherProperty(
  338. bstrPropertyDestination,
  339. &variantPropertyValue
  340. );
  341. if (hr != S_OK)
  342. {
  343. // We consider this a successful match.
  344. SensPrint(SENS_INFO, (SENS_STRING("\t| Subscription::GetPublisherProperty() returned 0x%x\n"), hr));
  345. bPropertyPresent = FALSE;
  346. }
  347. else
  348. {
  349. ASSERT(variantPropertyValue.vt == VT_BSTR);
  350. bstrPropertyValue = variantPropertyValue.bstrVal;
  351. SensPrintW(SENS_INFO, (SENS_BSTR("\t| Property %s has value %s\n"), bstrPropertyDestination, bstrPropertyValue));
  352. }
  353. if ( (bPropertyPresent == TRUE)
  354. && (wcscmp(bstrPropertyValue, bstrCompareDest) != 0))
  355. {
  356. SensPrintW(SENS_INFO, (SENS_BSTR("\t| Subscription::PropertyValue was %s!\n"), bstrCompareDest));
  357. break; // skip to next subscription
  358. }
  359. //
  360. // Compare ulType here and pass back if they match
  361. //
  362. FreeVariant(&variantPropertyValue);
  363. VariantInit(&variantPropertyValue);
  364. bPropertyPresent = TRUE;
  365. hr = pIEventSubscription->GetPublisherProperty(
  366. bstrPropertyType,
  367. &variantPropertyValue
  368. );
  369. if (hr != S_OK)
  370. {
  371. // We consider this a successful match.
  372. SensPrint(SENS_INFO, (SENS_STRING("\t| Subscription::GetPublisherProperty() returned 0x%x\n"), hr));
  373. bPropertyPresent = FALSE;
  374. }
  375. else
  376. {
  377. ASSERT(variantPropertyValue.vt == VT_UI4);
  378. SensPrint(SENS_INFO, (SENS_STRING("\t| Property %s has value 0x%x\n"), bstrPropertyType, variantPropertyValue.ulVal));
  379. }
  380. if ( (bPropertyPresent == TRUE)
  381. && (variantPropertyValue.ulVal == ulCompareType))
  382. {
  383. SensPrintW(SENS_INFO, (SENS_BSTR("\t| Subscription::PropertyValue was %s!\n"), szCompareType));
  384. break; // skip to next subscription
  385. }
  386. goto FoundMatchingSubscription;
  387. break;
  388. case EVENT_INVALID:
  389. default:
  390. hr = E_UNEXPECTED;
  391. goto Cleanup;
  392. } // end of switch
  393. ContinueToNextSubscription:
  394. FreeVariant(&variantPropertyValue);
  395. pIEventSubscription->Release();
  396. } // for loop
  397. // Didn't find a matching subscription.
  398. goto Cleanup;
  399. FoundMatchingSubscription:
  400. FreeVariant(&variantPropertyValue);
  401. *ppIEventSubscription = pIEventSubscription;
  402. *pcReturnElem = 1;
  403. hr = S_OK;
  404. Cleanup:
  405. //
  406. // Cleanup
  407. //
  408. if (bstrPropertyDestination)
  409. {
  410. SysFreeString(bstrPropertyDestination);
  411. }
  412. if (bstrPropertyType)
  413. {
  414. SysFreeString(bstrPropertyType);
  415. }
  416. return hr;
  417. }
  418. STDMETHODIMP
  419. CImpIEnumSub::Reset(
  420. )
  421. {
  422. return (m_pIEnumSubs->Reset());
  423. }
  424. STDMETHODIMP
  425. CImpIEnumSub::Skip(
  426. ULONG cSkipElements
  427. )
  428. {
  429. return E_NOTIMPL;
  430. }