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.

757 lines
22 KiB

  1. /*++
  2. Copyright (c) 1998-1999 Microsoft Corporation
  3. Module Name:
  4. mspterm.cpp
  5. Abstract:
  6. Implementations for the CBaseTerminal, CSingleFilterTerminal, and various
  7. work item / worker thread classes.
  8. --*/
  9. #include "precomp.h"
  10. #pragma hdrstop
  11. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  12. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  13. CBaseTerminal::CBaseTerminal()
  14. : m_TerminalDirection(TD_CAPTURE)
  15. , m_TerminalType(TT_STATIC)
  16. , m_TerminalState(TS_NOTINUSE)
  17. , m_TerminalClassID(CLSID_NULL)
  18. , m_pFTM(NULL)
  19. {
  20. LOG((MSP_TRACE, "CBaseTerminal::CBaseTerminal() called"));
  21. HRESULT hr = CoCreateFreeThreadedMarshaler(
  22. GetControllingUnknown(), &m_pFTM);
  23. if ( FAILED(hr) )
  24. {
  25. LOG((MSP_TRACE, "CBaseTerminal::CBaseTerminal() - create ftm failed"));
  26. }
  27. }
  28. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  29. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  30. CBaseTerminal::~CBaseTerminal()
  31. {
  32. if (NULL != m_pFTM)
  33. {
  34. m_pFTM->Release();
  35. }
  36. LOG((MSP_TRACE, "CBaseTerminal::~CBaseTerminal() finished"));
  37. }
  38. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  39. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  40. //
  41. // Dynamic terminals that support only one direction must override this to check
  42. // if the direction is valid (although the terminal manager is supposed to
  43. // ensure that the wrong direction is never passed). Dynamic terminal might want
  44. // to override this for other reasons too (create filters now, etc.).
  45. //
  46. // Static terminals normally just call this in their CreateTerminal().
  47. //
  48. HRESULT CBaseTerminal::Initialize(
  49. IN IID iidTerminalClass,
  50. IN DWORD dwMediaType,
  51. IN TERMINAL_DIRECTION Direction,
  52. IN MSP_HANDLE htAddress
  53. )
  54. {
  55. CLock lock(m_CritSec);
  56. LOG((MSP_TRACE, "CBaseTerminal::Initialize - enter"));
  57. //
  58. // Check if the media type is supported by this terminal.
  59. //
  60. if ( ! MediaTypeSupported( (long) dwMediaType) )
  61. {
  62. LOG((MSP_ERROR, "CBaseTerminal::Initialize - "
  63. "media type not supported - returning E_INVALIDARG"));
  64. return E_INVALIDARG;
  65. }
  66. //
  67. // Save this configurarion.
  68. //
  69. m_dwMediaType = dwMediaType;
  70. m_TerminalDirection = Direction;
  71. m_TerminalClassID = iidTerminalClass;
  72. m_htAddress = htAddress;
  73. LOG((MSP_TRACE, "CBaseTerminal::Initialize - exit S_OK"));
  74. return S_OK;
  75. }
  76. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  77. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  78. STDMETHODIMP CBaseTerminal::get_AddressHandle (
  79. OUT MSP_HANDLE * phtAddress
  80. )
  81. {
  82. CLock lock(m_CritSec);
  83. LOG((MSP_TRACE, "CBaseTerminal::get_AddressHandle - enter"));
  84. if ( MSPB_IsBadWritePtr( phtAddress, sizeof(MSP_HANDLE) ) )
  85. {
  86. LOG((MSP_ERROR, "CBaseTerminal::get_AddressHandle - returning E_POINTER"));
  87. return E_POINTER;
  88. }
  89. *phtAddress = m_htAddress;
  90. LOG((MSP_TRACE, "CBaseTerminal::get_AddressHandle - exit S_OK"));
  91. return S_OK;
  92. }
  93. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  94. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  95. STDMETHODIMP CBaseTerminal::get_Name(BSTR * pbsName)
  96. {
  97. CLock lock(m_CritSec);
  98. LOG((MSP_TRACE, "CBaseTerminal::get_Name - enter"));
  99. if ( MSPB_IsBadWritePtr( pbsName, sizeof(BSTR) ) )
  100. {
  101. LOG((MSP_ERROR, "CBaseTerminal::get_Name - "
  102. "bad BSTR passed in - returning E_POINTER"));
  103. return E_POINTER;
  104. }
  105. *pbsName = SysAllocString(m_szName);
  106. if ( *pbsName == NULL )
  107. {
  108. LOG((MSP_ERROR, "CBaseTerminal::get_Name - "
  109. "can't sysallocstring - returning E_OUTOFMEMORY"));
  110. return E_OUTOFMEMORY;
  111. }
  112. LOG((MSP_TRACE, "CBaseTerminal::get_Name - exit S_OK"));
  113. return S_OK;
  114. }
  115. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  116. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  117. STDMETHODIMP CBaseTerminal::get_State(TERMINAL_STATE * pVal)
  118. {
  119. CLock lock(m_CritSec);
  120. LOG((MSP_TRACE, "CBaseTerminal::get_State - enter"));
  121. if ( MSPB_IsBadWritePtr( pVal, sizeof(TERMINAL_STATE) ) )
  122. {
  123. LOG((MSP_ERROR, "CBaseTerminal::get_State - returning E_POINTER"));
  124. return E_POINTER;
  125. }
  126. *pVal = m_TerminalState;
  127. LOG((MSP_TRACE, "CBaseTerminal::get_State - exit S_OK"));
  128. return S_OK;
  129. }
  130. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  131. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  132. STDMETHODIMP CBaseTerminal::get_TerminalType(TERMINAL_TYPE * pVal)
  133. {
  134. CLock lock(m_CritSec);
  135. LOG((MSP_TRACE, "CBaseTerminal::get_TerminalType - enter"));
  136. if ( MSPB_IsBadWritePtr( pVal, sizeof(TERMINAL_TYPE) ) )
  137. {
  138. LOG((MSP_ERROR, "CBaseTerminal::get_TerminalType - returning E_POINTER"));
  139. return E_POINTER;
  140. }
  141. *pVal = m_TerminalType;
  142. LOG((MSP_TRACE, "CBaseTerminal::get_TerminalType - exit S_OK"));
  143. return S_OK;
  144. }
  145. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  146. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  147. STDMETHODIMP CBaseTerminal::get_TerminalClass(BSTR * pbsClassID)
  148. {
  149. CLock lock(m_CritSec);
  150. LOG((MSP_TRACE, "CBaseTerminal::get_TerminalClass - enter"));
  151. if ( MSPB_IsBadWritePtr( pbsClassID, sizeof(BSTR) ) )
  152. {
  153. LOG((MSP_ERROR, "CBaseTerminal::get_TerminalClass - returning E_POINTER"));
  154. return E_POINTER;
  155. }
  156. //
  157. // Convert the CLSID to an OLE string.
  158. //
  159. LPOLESTR lposClass = NULL;
  160. HRESULT hr = StringFromCLSID(m_TerminalClassID, &lposClass);
  161. if (FAILED(hr))
  162. {
  163. LOG((MSP_ERROR, "CBaseTerminal::get_TerminalClass (StringFromCLSID) - returning %8x", hr));
  164. return hr;
  165. }
  166. //
  167. // Put the string in a BSTR.
  168. //
  169. *pbsClassID = ::SysAllocString(lposClass);
  170. //
  171. // Free the OLE string.
  172. //
  173. ::CoTaskMemFree(lposClass);
  174. if (*pbsClassID == NULL)
  175. {
  176. LOG((MSP_ERROR, "CBaseTerminal::get_TerminalClass - returning E_OUTOFMEMORY"));
  177. return E_OUTOFMEMORY;
  178. }
  179. LOG((MSP_TRACE, "CBaseTerminal::get_TerminalClass - exit S_OK"));
  180. return S_OK;
  181. }
  182. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  183. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  184. STDMETHODIMP CBaseTerminal::get_Direction(
  185. OUT TERMINAL_DIRECTION *pDirection
  186. )
  187. {
  188. CLock lock(m_CritSec);
  189. LOG((MSP_TRACE, "CBaseTerminal::get_Direction - enter"));
  190. if ( MSPB_IsBadWritePtr( pDirection, sizeof(TERMINAL_DIRECTION) ) )
  191. {
  192. LOG((MSP_ERROR, "CBaseTerminal::get_Direction - returning E_POINTER"));
  193. return E_POINTER;
  194. }
  195. *pDirection = m_TerminalDirection;
  196. LOG((MSP_TRACE, "CBaseTerminal::get_Direction - exit S_OK"));
  197. return S_OK;
  198. }
  199. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  200. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  201. // enters each of the internal filters into the filter graph
  202. // connects the internal filters together (if applicable)
  203. // and returns all the filters to be used as connection points
  204. STDMETHODIMP CBaseTerminal::ConnectTerminal(
  205. IN IGraphBuilder * pGraph,
  206. IN DWORD dwTerminalDirection,
  207. IN OUT DWORD * pdwNumPins,
  208. OUT IPin ** ppPins
  209. )
  210. {
  211. LOG((MSP_TRACE, "CBaseTerminal::ConnectTerminal - enter"));
  212. //
  213. // Check parameters.
  214. //
  215. if ( IsBadReadPtr(pGraph, sizeof(IGraphBuilder) ) )
  216. {
  217. LOG((MSP_ERROR, "CBaseTerminal::ConnectTerminal - "
  218. "bad graph pointer; exit E_POINTER"));
  219. return E_POINTER;
  220. }
  221. if ( MSPB_IsBadWritePtr(pdwNumPins, sizeof(DWORD) ) )
  222. {
  223. LOG((MSP_ERROR, "CBaseTerminal::ConnectTerminal - "
  224. "bad numpins pointer; exit E_POINTER"));
  225. return E_POINTER;
  226. }
  227. //
  228. // Find out how many pins we expose. For most terminals this is
  229. // straightforward but we pass in the graph pointer in case they
  230. // need to do something funky to figure this out.
  231. //
  232. DWORD dwActualNumPins;
  233. HRESULT hr;
  234. hr = GetNumExposedPins(pGraph, &dwActualNumPins);
  235. if ( FAILED(hr) )
  236. {
  237. LOG((MSP_ERROR, "CBaseTerminal::ConnectTerminal - "
  238. "GetNumExposedPins failed - exit 0x%08x", hr));
  239. return hr;
  240. }
  241. //
  242. // If ppPins is NULL, just return the number of pins and don't try to
  243. // connect the terminal.
  244. //
  245. if ( ppPins == NULL )
  246. {
  247. LOG((MSP_TRACE, "CBaseTerminal::ConnectTerminal - "
  248. "returned number of exposed pins - exit S_OK"));
  249. *pdwNumPins = dwActualNumPins;
  250. return S_OK;
  251. }
  252. //
  253. // Otherwise, we have a pin return buffer. Check that the purported buffer
  254. // size is big enough and that the buffer is actually writable to the size
  255. // we need.
  256. //
  257. if ( *pdwNumPins < dwActualNumPins )
  258. {
  259. LOG((MSP_ERROR, "CBaseTerminal::ConnectTerminal - "
  260. "not enough space to place pins; exit TAPI_E_NOTENOUGHMEMORY"));
  261. *pdwNumPins = dwActualNumPins;
  262. return TAPI_E_NOTENOUGHMEMORY;
  263. }
  264. if ( MSPB_IsBadWritePtr(ppPins, dwActualNumPins * sizeof(IPin *) ) )
  265. {
  266. LOG((MSP_ERROR, "CBaseTerminal::ConnectTerminal - "
  267. "bad pins array pointer; exit E_POINTER"));
  268. return E_POINTER;
  269. }
  270. //
  271. // Check if we're already connected, and if so, change our state to
  272. // connected. Note that this makes sense for both core static terminals
  273. // and dynamic terminals. Also note that we need to protect this with
  274. // a critical section, but after this we can let go of the lock because
  275. // anyone who subsequently enters the critical section will bail at this
  276. // point.
  277. //
  278. {
  279. CLock lock(m_CritSec);
  280. //
  281. // check if already connected
  282. //
  283. if (TS_INUSE == m_TerminalState)
  284. {
  285. LOG((MSP_ERROR, "CBaseTerminal::ConnectTerminal - "
  286. "terminal already in use; exit TAPI_E_TERMINALINUSE"));
  287. return TAPI_E_TERMINALINUSE;
  288. }
  289. //
  290. // Save important state.
  291. //
  292. m_pGraph = pGraph;
  293. m_TerminalState = TS_INUSE;
  294. }
  295. // add filters to the filter graph
  296. hr = AddFiltersToGraph();
  297. if ( FAILED(hr) )
  298. {
  299. LOG((MSP_ERROR, "CBaseTerminal::ConnectTerminal - "
  300. "can't add filters to graph"));
  301. goto disconnect_terminal;
  302. }
  303. // Give the terminal a chance to do any preconnection
  304. hr = ConnectFilters();
  305. if ( FAILED(hr) )
  306. {
  307. LOG((MSP_ERROR, "CBaseTerminal::ConnectTerminal - "
  308. "can't do internal filter connection"));
  309. goto disconnect_terminal;
  310. }
  311. //
  312. // Get the pins that this filter exposes. No need to pass in
  313. // the filter graph because we already saved the graph pointer.
  314. //
  315. *pdwNumPins = dwActualNumPins;
  316. hr = GetExposedPins(ppPins);
  317. if ( FAILED(hr) )
  318. {
  319. LOG((MSP_ERROR, "CBaseTerminal::ConnectTerminal - "
  320. "can't get exposed pins"));
  321. goto disconnect_terminal;
  322. }
  323. LOG((MSP_TRACE, "CBaseTerminal::ConnectTerminal success"));
  324. return S_OK;
  325. disconnect_terminal:
  326. //
  327. // best effort attempt to disconnect - ignore error code
  328. //
  329. DisconnectTerminal(pGraph, 0);
  330. //
  331. // Release our reference to the graph and set ourselves to notinuse state.
  332. // DisconnectTerminal does this on success, but we need to make sure this
  333. // cleanup happens even if DisconnectTerminal failed.
  334. //
  335. m_pGraph = NULL; // this releases the CComPtr
  336. m_TerminalState = TS_NOTINUSE;
  337. LOG((MSP_TRACE, "CBaseTerminal::ConnectTerminal - exit 0x%08x", hr));
  338. return hr;
  339. }
  340. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  341. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  342. STDMETHODIMP
  343. CBaseTerminal::CompleteConnectTerminal(void)
  344. {
  345. LOG((MSP_TRACE, "CBaseTerminal::CompleteConnectTerminal - enter"));
  346. LOG((MSP_TRACE, "CBaseTerminal::CompleteConnectTerminal - exit S_OK"));
  347. return S_OK;
  348. }
  349. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  350. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  351. // disconnects the internal filters from each other (if applicable)
  352. // and removes them from the filter graph (thus breaking connections to
  353. // the stream).
  354. // Filter graph parameter is used for validation, to make sure the terminal
  355. // is disconnected from the same graph that it was originally connected to.
  356. STDMETHODIMP
  357. CBaseTerminal::DisconnectTerminal(
  358. IN IGraphBuilder * pGraph,
  359. IN DWORD dwReserved
  360. )
  361. {
  362. CLock lock(m_CritSec);
  363. LOG((MSP_TRACE, "CBaseTerminal::DisconnectTerminal called"));
  364. //
  365. // If not in use, then there is nothing to be done.
  366. //
  367. if ( TS_INUSE != m_TerminalState )
  368. {
  369. _ASSERTE(m_pGraph == NULL);
  370. LOG((MSP_TRACE, "CBaseTerminal::DisconnectTerminal success; not in use"));
  371. return S_OK;
  372. }
  373. //
  374. // Check that we are being disconnected from the correct graph.
  375. //
  376. if ( m_pGraph != pGraph )
  377. {
  378. LOG((MSP_TRACE, "CBaseTerminal::DisconnectTerminal - "
  379. "wrong graph; returning E_INVALIDARG"));
  380. return E_INVALIDARG;
  381. }
  382. //
  383. // Extra sanity check.
  384. //
  385. if ( m_pGraph == NULL )
  386. {
  387. LOG((MSP_TRACE, "CBaseTerminal::DisconnectTerminal - "
  388. "no graph; returning E_UNEXPECTED"));
  389. return E_UNEXPECTED;
  390. }
  391. HRESULT hr;
  392. //
  393. // Remove filters from the graph
  394. //
  395. hr = RemoveFiltersFromGraph();
  396. if ( FAILED(hr) )
  397. {
  398. LOG((MSP_ERROR, "CBaseTerminal::DisconnectTerminal - "
  399. "remove filters from graph failed; returning 0x%08x", hr));
  400. return hr;
  401. }
  402. //
  403. // Release our reference to the graph and set ourselves to notinuse state.
  404. //
  405. m_pGraph = NULL; // this releases the CComPtr
  406. m_TerminalState = TS_NOTINUSE;
  407. LOG((MSP_TRACE, "CBaseTerminal::DisconnectTerminal success"));
  408. return S_OK;
  409. }
  410. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  411. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  412. STDMETHODIMP CBaseTerminal::get_MediaType(long * plMediaType)
  413. {
  414. CLock lock(m_CritSec);
  415. LOG((MSP_TRACE, "CBaseTerminal::get_MediaType - enter"));
  416. if ( MSPB_IsBadWritePtr(plMediaType, sizeof(long) ) )
  417. {
  418. LOG((MSP_ERROR, "CBaseTerminal::get_MediaType - returning E_POINTER"));
  419. return E_POINTER;
  420. }
  421. *plMediaType = (long) m_dwMediaType;
  422. LOG((MSP_TRACE, "CBaseTerminal::get_MediaType - exit S_OK"));
  423. return S_OK;
  424. }
  425. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  426. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  427. BOOL CBaseTerminal::MediaTypeSupported(long lMediaType)
  428. {
  429. return IsValidSingleMediaType( (DWORD) lMediaType,
  430. GetSupportedMediaTypes() );
  431. }
  432. /////////////////////////////////////////////////////////////////////////////
  433. /////////////////////////////////////////////////////////////////////////////
  434. // //
  435. // CSingleFilterTerminal //
  436. // //
  437. // This is a base class for a terminal with a single filter and pin. The //
  438. // terminal could be any direction or media type, and it could be static //
  439. // or dynamic. //
  440. // //
  441. /////////////////////////////////////////////////////////////////////////////
  442. /////////////////////////////////////////////////////////////////////////////
  443. HRESULT CSingleFilterTerminal::GetNumExposedPins(
  444. IN IGraphBuilder * pGraph,
  445. OUT DWORD * pdwNumPins)
  446. {
  447. LOG((MSP_TRACE, "CSingleFilterTerminal::GetNumExposedPins - enter"));
  448. //
  449. // We ignote pGraph because we don't need to do anything special to find
  450. // out how many pins we have.
  451. //
  452. *pdwNumPins = 1;
  453. LOG((MSP_TRACE, "CSingleFilterTerminal::GetNumExposedPins - exit S_OK"));
  454. return S_OK;
  455. }
  456. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  457. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  458. HRESULT CSingleFilterTerminal::GetExposedPins(
  459. OUT IPin ** ppPins
  460. )
  461. {
  462. LOG((MSP_TRACE, "CSingleFilterTerminal::GetExposedPins - enter"));
  463. _ASSERTE( ! MSPB_IsBadWritePtr(ppPins, 1 * sizeof(IPin *) ) );
  464. //
  465. // Return our single pin.
  466. //
  467. *ppPins = m_pIPin;
  468. (*ppPins)->AddRef();
  469. LOG((MSP_TRACE, "CSingleFilterTerminal::GetExposedPins - exit S_OK"));
  470. return S_OK;
  471. }
  472. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  473. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  474. // stops the rightmost render filter in the terminal
  475. // (needed for dynamic filter graphs)
  476. STDMETHODIMP CSingleFilterTerminal::RunRenderFilter(void)
  477. {
  478. // check that we're really a render filter
  479. // tell our single filter to run
  480. return E_NOTIMPL;
  481. }
  482. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  483. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  484. // stops the rightmost render filter in the terminal
  485. // (needed for dynamic filter graphs)
  486. STDMETHODIMP CSingleFilterTerminal::StopRenderFilter(void)
  487. {
  488. // check that we're really a render filter
  489. // tell our single filter to stop
  490. return E_NOTIMPL;
  491. }
  492. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  493. //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  494. HRESULT
  495. CSingleFilterTerminal::RemoveFiltersFromGraph(void)
  496. {
  497. LOG((MSP_TRACE, "CSingleFilterTerminal::RemoveFiltersFromGraph - enter"));
  498. if (m_pGraph == NULL)
  499. {
  500. LOG((MSP_ERROR, "CSingleFilterTerminal::RemoveFiltersFromGraph - "
  501. "no graph; returning E_UNEXPECTED"));
  502. return E_UNEXPECTED;
  503. }
  504. if (m_pIFilter == NULL)
  505. {
  506. LOG((MSP_ERROR, "CSingleFilterTerminal::RemoveFiltersFromGraph - "
  507. "no filter; returning E_UNEXPECTED"));
  508. return E_UNEXPECTED;
  509. }
  510. //
  511. // Remove the filter from the graph. This also disconnects any connections
  512. // the filter may have.
  513. //
  514. HRESULT hr = m_pGraph->RemoveFilter(m_pIFilter);
  515. LOG((MSP_TRACE, "CSingleFilterTerminal::RemoveFiltersFromGraph - exit 0x%08x", hr));
  516. return hr;
  517. }
  518. HRESULT
  519. CSingleFilterStaticTerminal::CompareMoniker(
  520. IMoniker *pMoniker
  521. )
  522. {
  523. IMoniker *pReducedMoniker;
  524. IMoniker *pReducedNewMoniker;
  525. IBindCtx *pbc;
  526. HRESULT hr;
  527. hr = CreateBindCtx( 0, &pbc );
  528. if (FAILED(hr))
  529. {
  530. LOG((MSP_ERROR, "CSingleFilterStaticTerminal::CompareMoniker - "
  531. "unable to create bind context"));
  532. return hr;
  533. }
  534. hr = m_pMoniker->Reduce(pbc ,MKRREDUCE_ALL, NULL, &pReducedMoniker);
  535. if (FAILED(hr) || !pReducedMoniker)
  536. {
  537. LOG((MSP_ERROR, "CSingleFilterStaticTerminal::CompareMoniker - "
  538. "unable to reduce moniker"));
  539. pbc->Release(); // release the bind context
  540. return hr;
  541. }
  542. hr = pMoniker->Reduce(pbc ,MKRREDUCE_ALL, NULL, &pReducedNewMoniker);
  543. if (FAILED(hr) || !pReducedNewMoniker)
  544. {
  545. LOG((MSP_ERROR, "CSingleFilterStaticTerminal::CompareMoniker - "
  546. "unable to reduce moniker"));
  547. pbc->Release(); // release the bind context
  548. pReducedMoniker->Release(); // release the reduced moniker
  549. return hr;
  550. }
  551. pbc->Release(); // release the bind context
  552. if (pReducedMoniker->IsEqual(pReducedNewMoniker) == S_OK)
  553. {
  554. LOG((MSP_TRACE, "CSingleFilterStaticTerminal::CompareMoniker - "
  555. "exit - return S_OK"));
  556. pReducedMoniker->Release(); // release the reduced monikers
  557. pReducedNewMoniker->Release();
  558. return S_OK;
  559. }
  560. pReducedMoniker->Release(); // release the reduced monikers
  561. pReducedNewMoniker->Release();
  562. LOG((MSP_TRACE, "CSingleFilterStaticTerminal::CompareMoniker - "
  563. "exit - return S_FALSE"));
  564. return S_FALSE;
  565. }
  566. // eof