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.

758 lines
19 KiB

  1. /*++
  2. Copyright (C) Microsoft Corporation, 1997 - 1999
  3. Module Name:
  4. cpubfilt.cxx
  5. Abstract:
  6. This file contains the implementation of the PublisherFilter
  7. for the ISensNetwork interface exposed by SENS.
  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_cFilterObj; // Count of active components
  20. LONG g_cFilterLock; // Count of Server locks
  21. //
  22. // Constructors and Destructors
  23. //
  24. CImpISensNetworkFilter::CImpISensNetworkFilter(
  25. void
  26. ) : m_cRef(1L), // Add a reference.
  27. m_pConnectionMade_Enum(NULL),
  28. m_pConnectionMadeNoQOC_Enum(NULL),
  29. m_pConnectionLost_Enum(NULL),
  30. m_pDestinationReachable_Enum(NULL),
  31. m_pDestinationReachableNoQOC_Enum(NULL),
  32. m_pConnectionMade_FiringControl(NULL),
  33. m_pConnectionMadeNoQOC_FiringControl(NULL),
  34. m_pConnectionLost_FiringControl(NULL),
  35. m_pDestinationReachable_FiringControl(NULL),
  36. m_pDestinationReachableNoQOC_FiringControl(NULL)
  37. {
  38. InterlockedIncrement(&g_cFilterObj);
  39. }
  40. CImpISensNetworkFilter::~CImpISensNetworkFilter(
  41. void
  42. )
  43. {
  44. InterlockedDecrement(&g_cFilterObj);
  45. //
  46. // Release all references that we added to IEnumEventObject pointers,
  47. // if any.
  48. //
  49. if (m_pConnectionMade_Enum)
  50. {
  51. m_pConnectionMade_Enum->Release();
  52. }
  53. if (m_pConnectionMadeNoQOC_Enum)
  54. {
  55. m_pConnectionMadeNoQOC_Enum->Release();
  56. }
  57. if (m_pConnectionLost_Enum)
  58. {
  59. m_pConnectionLost_Enum->Release();
  60. }
  61. if (m_pDestinationReachable_Enum)
  62. {
  63. m_pDestinationReachable_Enum->Release();
  64. }
  65. if (m_pDestinationReachableNoQOC_Enum)
  66. {
  67. m_pDestinationReachableNoQOC_Enum->Release();
  68. }
  69. //
  70. // Release all references that we added to IFiringControl pointers,
  71. // if any (and there shouldn't be any).
  72. //
  73. if (m_pConnectionMade_FiringControl)
  74. {
  75. m_pConnectionMade_FiringControl->Release();
  76. }
  77. if (m_pConnectionMadeNoQOC_FiringControl)
  78. {
  79. m_pConnectionMadeNoQOC_FiringControl->Release();
  80. }
  81. if (m_pConnectionLost_FiringControl)
  82. {
  83. m_pConnectionLost_FiringControl->Release();
  84. }
  85. if (m_pDestinationReachable_FiringControl)
  86. {
  87. m_pDestinationReachable_FiringControl->Release();
  88. }
  89. if (m_pDestinationReachableNoQOC_FiringControl)
  90. {
  91. m_pDestinationReachableNoQOC_FiringControl->Release();
  92. }
  93. }
  94. //
  95. // Standard QueryInterface
  96. //
  97. STDMETHODIMP
  98. CImpISensNetworkFilter::QueryInterface(
  99. REFIID riid,
  100. LPVOID *ppv
  101. )
  102. {
  103. HRESULT hr;
  104. DebugTraceGuid("CImpISensNetworkFilter:QueryInterface()", riid);
  105. hr = S_OK;
  106. *ppv = NULL;
  107. // IUnknown
  108. if (IsEqualIID(riid, IID_IUnknown))
  109. {
  110. *ppv = (ISensNetwork *) this;
  111. }
  112. else
  113. // ISensNetwork
  114. if (IsEqualIID(riid, IID_ISensNetwork))
  115. {
  116. *ppv = (ISensNetwork *) this;
  117. }
  118. else
  119. // IPublisherFilter
  120. if (IsEqualIID(riid, IID_IPublisherFilter))
  121. {
  122. *ppv = (IPublisherFilter *) this;
  123. }
  124. else
  125. {
  126. hr = E_NOINTERFACE;
  127. }
  128. if (NULL != *ppv)
  129. {
  130. ((LPUNKNOWN)*ppv)->AddRef();
  131. }
  132. return hr;
  133. }
  134. //
  135. // IDispatch member function implementations. These are dummy implementations
  136. // as EventSystem never calls them.
  137. //
  138. STDMETHODIMP
  139. CImpISensNetworkFilter::GetTypeInfoCount(
  140. UINT *pCountITypeInfo
  141. )
  142. {
  143. return E_NOTIMPL;
  144. }
  145. STDMETHODIMP
  146. CImpISensNetworkFilter::GetTypeInfo(
  147. UINT iTypeInfo,
  148. LCID lcid,
  149. ITypeInfo **ppITypeInfo
  150. )
  151. {
  152. return E_NOTIMPL;
  153. }
  154. STDMETHODIMP
  155. CImpISensNetworkFilter::GetIDsOfNames(
  156. REFIID riid,
  157. LPOLESTR *arrNames,
  158. UINT cNames,
  159. LCID lcid,
  160. DISPID *arrDispIDs)
  161. {
  162. return E_NOTIMPL;
  163. }
  164. STDMETHODIMP
  165. CImpISensNetworkFilter::Invoke(
  166. DISPID dispID,
  167. REFIID riid,
  168. LCID lcid,
  169. WORD wFlags,
  170. DISPPARAMS *pDispParams,
  171. VARIANT *pvarResult,
  172. EXCEPINFO *pExecpInfo,
  173. UINT *puArgErr
  174. )
  175. {
  176. return E_NOTIMPL;
  177. }
  178. //
  179. // Standard AddRef and Release
  180. //
  181. STDMETHODIMP_(ULONG)
  182. CImpISensNetworkFilter::AddRef(
  183. void
  184. )
  185. {
  186. return InterlockedIncrement(&m_cRef);
  187. }
  188. STDMETHODIMP_(ULONG)
  189. CImpISensNetworkFilter::Release(
  190. void
  191. )
  192. {
  193. LONG cRefT;
  194. SensPrint(SENS_INFO, (SENS_STRING("\t| CImpISensNetworkFilter::Release(m_cRef = %d) called.\n"), m_cRef));
  195. cRefT = InterlockedDecrement((PLONG) &m_cRef);
  196. if (0 == m_cRef)
  197. {
  198. delete this;
  199. }
  200. return cRefT;
  201. }
  202. //
  203. // ISensNetwork Implementation.
  204. //
  205. STDMETHODIMP
  206. CImpISensNetworkFilter::ConnectionMade(
  207. BSTR bstrConnection,
  208. ULONG ulType,
  209. LPSENS_QOCINFO lpQOCInfo
  210. )
  211. {
  212. SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
  213. SensPrint(SENS_INFO, (SENS_STRING("CImpISensNetworkFilter::ConnectionMade() called\n\n")));
  214. SensPrintW(SENS_INFO, (SENS_BSTR(" bstrConnection - %s\n"), bstrConnection));
  215. SensPrint(SENS_INFO, (SENS_STRING(" ulType - 0x%x\n"), ulType));
  216. SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
  217. HRESULT hr = S_OK;
  218. ConnectionFilter filter(PROPERTY_CONNECTION_MADE_TYPE, ulType, hr);
  219. if (SUCCEEDED(hr))
  220. {
  221. hr = FilterAndFire(
  222. filter,
  223. m_pConnectionMade_Enum,
  224. m_pConnectionMade_FiringControl
  225. );
  226. }
  227. // We're done with this IFiringControl object.
  228. m_pConnectionMade_FiringControl->Release();
  229. m_pConnectionMade_FiringControl = NULL;
  230. return hr;
  231. }
  232. STDMETHODIMP
  233. CImpISensNetworkFilter::ConnectionMadeNoQOCInfo(
  234. BSTR bstrConnection,
  235. ULONG ulType
  236. )
  237. {
  238. SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
  239. SensPrint(SENS_INFO, (SENS_STRING("CImpISensNetworkFilter::ConnectionMadeNoQOCInfo() called\n\n")));
  240. SensPrintW(SENS_INFO, (SENS_BSTR(" bstrConnection - %s\n"), bstrConnection));
  241. SensPrint(SENS_INFO, (SENS_STRING(" ulType - 0x%x\n"), ulType));
  242. SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
  243. HRESULT hr = S_OK;
  244. ConnectionFilter filter(PROPERTY_CONNECTION_MADE_NOQOC_TYPE, ulType, hr);
  245. if (SUCCEEDED(hr))
  246. {
  247. hr = FilterAndFire(
  248. filter,
  249. m_pConnectionMadeNoQOC_Enum,
  250. m_pConnectionMadeNoQOC_FiringControl
  251. );
  252. }
  253. // We're done with this IFiringControl object.
  254. m_pConnectionMadeNoQOC_FiringControl->Release();
  255. m_pConnectionMadeNoQOC_FiringControl = NULL;
  256. return hr;
  257. }
  258. STDMETHODIMP
  259. CImpISensNetworkFilter::ConnectionLost(
  260. BSTR bstrConnection,
  261. ULONG ulType
  262. )
  263. {
  264. SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
  265. SensPrint(SENS_INFO, (SENS_STRING("CImpISensNetworkFilter::ConnectionLost() called\n\n")));
  266. SensPrintW(SENS_INFO, (SENS_BSTR(" bstrConnection - %s\n"), bstrConnection));
  267. SensPrint(SENS_INFO, (SENS_STRING(" ulType - 0x%x\n"), ulType));
  268. SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
  269. HRESULT hr = S_OK;
  270. ConnectionFilter filter(PROPERTY_CONNECTION_LOST_TYPE, ulType, hr);
  271. if (SUCCEEDED(hr))
  272. {
  273. hr = FilterAndFire(
  274. filter,
  275. m_pConnectionLost_Enum,
  276. m_pConnectionLost_FiringControl
  277. );
  278. }
  279. // We're done with this IFiringControl object.
  280. m_pConnectionLost_FiringControl->Release();
  281. m_pConnectionLost_FiringControl = NULL;
  282. return hr;
  283. }
  284. STDMETHODIMP
  285. CImpISensNetworkFilter::DestinationReachable(
  286. BSTR bstrDestination,
  287. BSTR bstrConnection,
  288. ULONG ulType,
  289. LPSENS_QOCINFO lpQOCInfo
  290. )
  291. {
  292. SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
  293. SensPrint(SENS_INFO, (SENS_STRING("CImpISensNetworkFilter::DestinationReachable() called\n\n")));
  294. SensPrintW(SENS_INFO, (SENS_BSTR(" bstrDestination - %s\n"), bstrDestination));
  295. SensPrintW(SENS_INFO, (SENS_BSTR(" bstrConnection - %s\n"), bstrConnection));
  296. SensPrint(SENS_INFO, (SENS_STRING(" ulType - 0x%x\n"), ulType));
  297. SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
  298. HRESULT hr = S_OK;
  299. ReachabilityFilter filter(PROPERTY_DESTINATION, PROPERTY_DESTINATION_TYPE, bstrDestination, ulType, hr);
  300. if (SUCCEEDED(hr))
  301. {
  302. hr = FilterAndFire(
  303. filter,
  304. m_pDestinationReachable_Enum,
  305. m_pDestinationReachable_FiringControl
  306. );
  307. }
  308. // We're done with this IFiringControl object.
  309. m_pDestinationReachable_FiringControl->Release();
  310. m_pDestinationReachable_FiringControl = NULL;
  311. return hr;
  312. }
  313. STDMETHODIMP
  314. CImpISensNetworkFilter::DestinationReachableNoQOCInfo(
  315. BSTR bstrDestination,
  316. BSTR bstrConnection,
  317. ULONG ulType
  318. )
  319. {
  320. SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
  321. SensPrint(SENS_INFO, (SENS_STRING("CImpISensNetworkFilter::DestinationReachableNoQOCInfo() called\n\n")));
  322. SensPrintW(SENS_INFO, (SENS_BSTR(" bstrDestination - %s\n"), bstrDestination));
  323. SensPrintW(SENS_INFO, (SENS_BSTR(" bstrConnection - %s\n"), bstrConnection));
  324. SensPrint(SENS_INFO, (SENS_STRING(" ulType - 0x%x\n"), ulType));
  325. SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
  326. HRESULT hr = S_OK;
  327. ReachabilityFilter filter(PROPERTY_DESTINATION_NOQOC, PROPERTY_DESTINATION_NOQOC_TYPE, bstrDestination, ulType, hr);
  328. if (SUCCEEDED(hr))
  329. {
  330. hr = FilterAndFire(
  331. filter,
  332. m_pDestinationReachableNoQOC_Enum,
  333. m_pDestinationReachableNoQOC_FiringControl
  334. );
  335. }
  336. // We're done with this IFiringControl object.
  337. m_pDestinationReachableNoQOC_FiringControl->Release();
  338. m_pDestinationReachableNoQOC_FiringControl = NULL;
  339. return hr;
  340. }
  341. //
  342. // IPublisherFilter Implementation.
  343. //
  344. STDMETHODIMP
  345. CImpISensNetworkFilter::Initialize(
  346. BSTR bstrMethodName,
  347. IDispatch* dispUserDefined
  348. )
  349. {
  350. HRESULT hr = E_INVALIDARG;
  351. IEnumEventObject** ppEnum = NULL;
  352. if (wcscmp(bstrMethodName, CONNECTION_MADE_METHOD) == 0)
  353. {
  354. ppEnum = &m_pConnectionMade_Enum;
  355. }
  356. else
  357. if (wcscmp(bstrMethodName, CONNECTION_MADE_NOQOC_METHOD) == 0)
  358. {
  359. ppEnum = &m_pConnectionMadeNoQOC_Enum;
  360. }
  361. else
  362. if (wcscmp(bstrMethodName, CONNECTION_LOST_METHOD) == 0)
  363. {
  364. ppEnum = &m_pConnectionLost_Enum;
  365. }
  366. else
  367. if (wcscmp(bstrMethodName, DESTINATION_REACHABLE_METHOD) == 0)
  368. {
  369. ppEnum = &m_pDestinationReachable_Enum;
  370. }
  371. else
  372. if (wcscmp(bstrMethodName, DESTINATION_REACHABLE_NOQOC_METHOD) == 0)
  373. {
  374. ppEnum = &m_pDestinationReachableNoQOC_Enum;
  375. }
  376. if (ppEnum != NULL)
  377. {
  378. IEventControl* control = NULL;
  379. hr = dispUserDefined->QueryInterface(IID_IEventControl, (void**)&control);
  380. if (FAILED(hr))
  381. {
  382. return hr;
  383. }
  384. IEventObjectCollection* collection = NULL;
  385. hr = control->GetSubscriptions(bstrMethodName, NULL, NULL, &collection);
  386. if (SUCCEEDED(hr))
  387. {
  388. hr = collection->get_NewEnum(ppEnum);
  389. // Don't need the collection any more... just keep the enum
  390. collection->Release();
  391. }
  392. control->Release();
  393. }
  394. return hr;
  395. }
  396. STDMETHODIMP
  397. CImpISensNetworkFilter::PrepareToFire(
  398. BSTR bstrMethodName,
  399. IFiringControl* pIFiringControl
  400. )
  401. {
  402. HRESULT hr = E_INVALIDARG;
  403. IFiringControl** ppFiringControl = NULL;
  404. if (wcscmp(bstrMethodName, CONNECTION_MADE_METHOD) == 0)
  405. {
  406. ppFiringControl = &m_pConnectionMade_FiringControl;
  407. }
  408. else
  409. if (wcscmp(bstrMethodName, CONNECTION_MADE_NOQOC_METHOD) == 0)
  410. {
  411. ppFiringControl = &m_pConnectionMadeNoQOC_FiringControl;
  412. }
  413. else
  414. if (wcscmp(bstrMethodName, CONNECTION_LOST_METHOD) == 0)
  415. {
  416. ppFiringControl = &m_pConnectionLost_FiringControl;
  417. }
  418. else
  419. if (wcscmp(bstrMethodName, DESTINATION_REACHABLE_METHOD) == 0)
  420. {
  421. ppFiringControl = &m_pDestinationReachable_FiringControl;
  422. }
  423. else
  424. if (wcscmp(bstrMethodName, DESTINATION_REACHABLE_NOQOC_METHOD) == 0)
  425. {
  426. ppFiringControl = &m_pDestinationReachableNoQOC_FiringControl;
  427. }
  428. if (ppFiringControl != NULL)
  429. {
  430. *ppFiringControl = pIFiringControl;
  431. pIFiringControl->AddRef();
  432. hr = S_OK;
  433. }
  434. return hr;
  435. }
  436. //
  437. // Filter helper implementations.
  438. //
  439. //
  440. // ConnectionFilter implementation.
  441. //
  442. ConnectionFilter::ConnectionFilter(
  443. const wchar_t* connectionTypeProperty,
  444. ULONG connectionType,
  445. HRESULT& hr
  446. ) : m_connectionTypeProperty(SysAllocString(connectionTypeProperty)),
  447. m_connectionType(connectionType)
  448. {
  449. if (m_connectionTypeProperty == NULL)
  450. {
  451. hr = E_OUTOFMEMORY;
  452. }
  453. else
  454. {
  455. hr = S_OK;
  456. }
  457. }
  458. ConnectionFilter::~ConnectionFilter(
  459. void
  460. )
  461. {
  462. SysFreeString(m_connectionTypeProperty);
  463. }
  464. HRESULT
  465. ConnectionFilter::CheckMatch(
  466. IEventSubscription* pSubscription
  467. ) const
  468. {
  469. VARIANT value;
  470. VariantInit(&value);
  471. HRESULT hr = pSubscription->GetPublisherProperty(m_connectionTypeProperty, &value);
  472. if (hr == S_FALSE)
  473. {
  474. // If the property isn't present, consider it a successful match.
  475. hr = S_OK;
  476. }
  477. else
  478. if (hr == S_OK)
  479. {
  480. // If the property is there, it must match the incoming parameter value.
  481. ASSERT(value.vt == VT_UI4);
  482. SensPrintW(SENS_INFO, (SENS_BSTR("\t| Property %s has value 0x%x\n"), m_connectionTypeProperty, value.ulVal));
  483. hr = (m_connectionType == value.ulVal) ? S_OK : S_FALSE;
  484. }
  485. VariantClear(&value);
  486. return hr;
  487. }
  488. //
  489. // ReachabilityFilter implementation
  490. //
  491. ReachabilityFilter::ReachabilityFilter(
  492. const wchar_t* destinationProperty,
  493. const wchar_t* destinationTypeProperty,
  494. BSTR destination,
  495. ULONG destinationType,
  496. HRESULT& hr
  497. ) : m_destinationProperty(SysAllocString(destinationProperty)),
  498. m_destinationTypeProperty(SysAllocString(destinationTypeProperty)),
  499. m_destination(destination),
  500. m_destinationType(destinationType)
  501. {
  502. if (m_destinationProperty == NULL || m_destinationTypeProperty == NULL)
  503. {
  504. hr = E_OUTOFMEMORY;
  505. }
  506. else
  507. {
  508. hr = S_OK;
  509. }
  510. }
  511. ReachabilityFilter::~ReachabilityFilter(
  512. void
  513. )
  514. {
  515. SysFreeString(m_destinationProperty);
  516. SysFreeString(m_destinationTypeProperty);
  517. }
  518. HRESULT
  519. ReachabilityFilter::CheckMatch(
  520. IEventSubscription* pSubscription
  521. ) const
  522. {
  523. HRESULT hr;
  524. // Check the destination property
  525. VARIANT value;
  526. VariantInit(&value);
  527. hr = pSubscription->GetPublisherProperty(m_destinationProperty, &value);
  528. if (hr == S_FALSE)
  529. {
  530. // If the property isn't present, consider it a successful match.
  531. hr = S_OK;
  532. SensPrintW(SENS_INFO, (SENS_BSTR("\t\t\t| Subscription (0x%x) has no %s Dest Property\n"), pSubscription, m_destinationProperty));
  533. }
  534. else
  535. if (hr == S_OK)
  536. {
  537. // If the property is there, it must match the incoming parameter value.
  538. ASSERT(value.vt == VT_BSTR);
  539. SensPrintW(SENS_INFO, (SENS_BSTR("\t\t\t| Property %s has value %s\n"), m_destinationProperty, value.bstrVal));
  540. hr = (wcscmp(m_destination, value.bstrVal) == 0) ? S_OK : S_FALSE;
  541. }
  542. VariantClear(&value);
  543. if (hr == S_OK)
  544. {
  545. // If we have a match so far, check the destination type property
  546. VARIANT value;
  547. VariantInit(&value);
  548. hr = pSubscription->GetPublisherProperty(m_destinationTypeProperty, &value);
  549. if (hr == S_FALSE)
  550. {
  551. // If the property isn't present, consider it a successful match.
  552. hr = S_OK;
  553. SensPrintW(SENS_INFO, (SENS_BSTR("\t\t\t| Subscription (0x%x) has no %s Type Property\n"), pSubscription, m_destinationTypeProperty));
  554. }
  555. else
  556. if (hr == S_OK)
  557. {
  558. // If the property is there, it must match the incoming parameter value.
  559. ASSERT(value.vt == VT_UI4);
  560. SensPrintW(SENS_INFO, (SENS_BSTR("\t\t\t| Property %s has value 0x%x\n"), m_destinationTypeProperty, value.ulVal));
  561. hr = (m_destinationType == value.ulVal) ? S_OK : S_FALSE;
  562. }
  563. VariantClear(&value);
  564. }
  565. return hr;
  566. }
  567. //
  568. // Generic filter and fire method.
  569. //
  570. HRESULT
  571. FilterAndFire(
  572. const Filter& filter,
  573. IEnumEventObject* enumerator,
  574. IFiringControl* firingControl
  575. )
  576. {
  577. HRESULT hr;
  578. IEventSubscription* pSubscription = NULL;
  579. int i = 0;
  580. //
  581. // Reset the enum back to the start
  582. //
  583. hr = enumerator->Reset();
  584. //
  585. // Loop through all the candidate subscriptions and fire the ones
  586. // that match the filter criteria.
  587. //
  588. for (;;)
  589. {
  590. ULONG cCount = 1;
  591. hr = enumerator->Next(cCount, (IUnknown**)&pSubscription, &cCount);
  592. if (hr != S_OK || cCount != 1)
  593. {
  594. break;
  595. }
  596. SensPrintA(SENS_INFO, ("\t\t\t| ****** Count for 0x%x is %d\n", enumerator, ++i));
  597. hr = filter.CheckMatch(pSubscription);
  598. if (hr == S_OK)
  599. {
  600. SensPrintA(SENS_INFO, ("\t\t\t| FilterAndFire(0x%x): CheckMatch() succeeded\n", enumerator));
  601. firingControl->FireSubscription(pSubscription);
  602. }
  603. pSubscription->Release();
  604. pSubscription = NULL;
  605. }
  606. //
  607. // Cleanup, including any left-over stuff in case of premature exit from the loop.
  608. //
  609. if (pSubscription != NULL)
  610. {
  611. pSubscription->Release();
  612. }
  613. return S_OK;
  614. }