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.

212 lines
5.3 KiB

  1. /*++
  2. Copyright (C) 1996-2001 Microsoft Corporation
  3. Module Name:
  4. FILTSINK.CPP
  5. Abstract:
  6. History:
  7. --*/
  8. #include "filtsink.h"
  9. CFilteringSink::~CFilteringSink()
  10. {
  11. m_pFrontFilter->Release();
  12. }
  13. void* CFilteringSink::GetInterface(REFIID riid)
  14. {
  15. if(riid == IID_IHmmEventSink)
  16. {
  17. return (IHmmEventSink*)&m_XEventSink;
  18. }
  19. else return NULL;
  20. }
  21. STDMETHODIMP CFilteringSink::XEventSink::Indicate(
  22. IN long lNumObjects,
  23. IN IHmmClassObject **apObjects)
  24. {
  25. for(long l = 0; l < lNumObjects; l++)
  26. {
  27. IHmmClassObject* pObject = apObjects[l];
  28. IHmmPropertySource* pSource;
  29. pObject->QueryInterface(IID_IHmmPropertySource, (void**)&pSource);
  30. HRESULT hres = m_pObject->CheckAndSend(pSource, TRUE, NULL, NULL);
  31. pSource->Release();
  32. if(FAILED(hres)) return hres;
  33. }
  34. return HMM_S_NO_ERROR;
  35. }
  36. STDMETHODIMP CFilteringSink::XEventSink::IndicateRaw(
  37. IN long lNumObjects,
  38. IN IHmmPropertySource **apObjects)
  39. {
  40. for(long l = 0; l < lNumObjects; l++)
  41. {
  42. HRESULT hres = m_pObject->CheckAndSend(apObjects[l], TRUE, NULL, NULL);
  43. if(FAILED(hres)) return hres;
  44. }
  45. return HMM_S_NO_ERROR;
  46. }
  47. STDMETHODIMP CFilteringSink::XEventSink::IndicateWithHint(
  48. IN long lNumObjects,
  49. IN IHmmClassObject *pObject,
  50. IN IUnknown *pHint)
  51. {
  52. // for now, ignore the hint
  53. return Indicate(1, &pObject);
  54. }
  55. STDMETHODIMP CFilteringSink::XEventSink::CheckObject(
  56. IN IHmmPropertySource *pSource,
  57. OUT IHmmPropertyList **ppList,
  58. OUT IUnknown **ppHint)
  59. {
  60. return m_pObject->CheckAndSend(pSource, FALSE, ppList, ppHint);
  61. }
  62. STDMETHODIMP CFilteringSink::XEventSink::GetRequirements(
  63. IN IHmmFilter **ppRequirements)
  64. {
  65. return E_NOTIMPL;
  66. }
  67. STDMETHODIMP CFilteringSink::XEventSink::SetRequirementChangeSink(
  68. IN IHmmRequirementChangeSink *pNewSink,
  69. OUT IHmmRequirementChangeSink **ppOldSink)
  70. {
  71. if(ppOldSink)
  72. {
  73. *ppOldSink = m_pObject->m_pChangeSink;
  74. }
  75. else
  76. {
  77. if(m_pObject->m_pChangeSink) m_pObject->m_pChangeSink->Release();
  78. }
  79. m_pObject->m_pChangeSink = pNewSink;
  80. if(pNewSink) pNewSink->AddRef();
  81. return HMM_S_NO_ERROR;
  82. }
  83. STDMETHODIMP CFilteringSink::XEventSink::GetOptimizedSink(
  84. IN IHmmFilter *pGuaranteedCondition,
  85. IN long lFlags,
  86. OUT IHmmEventSink **ppOptimizedSink)
  87. {
  88. if(pGuaranteedCondition == NULL || ppOptimizedSink == NULL)
  89. {
  90. return HMM_E_INVALID_PARAMETER;
  91. }
  92. // For now: return ourselves
  93. *ppOptimizedSink = (IHmmEventSink*)this;
  94. AddRef();
  95. return HMM_S_NO_ERROR;
  96. }
  97. STDMETHODIMP CFilteringSink::XEventSink::GetUsefulSubsink(
  98. long lIndex,
  99. long lFlags,
  100. IHmmEventSink **ppSubsink)
  101. {
  102. // For now --- no useful subsinks
  103. *ppSubsink = NULL;
  104. return HMM_S_NO_MORE_DATA;
  105. }
  106. long CFilteringSink::AddSmartMember(IHmmEventSink* pSmartSink)
  107. {
  108. CMember* pMember = new CMember(pSmartSink);
  109. m_apMembers.Add(pMember);
  110. NotifyChanged(NULL, pSmartSink);
  111. return m_apMembers.GetSize();
  112. }
  113. long CFilteringSink::AddDumbMember(IHmmRawObjectSink* pDumbSink)
  114. {
  115. CMember* pMember = new CMember(pDumbSink);
  116. m_apMembers.Add(pMember);
  117. return m_apMembers.GetSize();
  118. }
  119. BOOL CFilteringSink::RemoveMember(long lIndex)
  120. {
  121. CMember* pMember = m_apMembers[lIndex];
  122. if(pMember->m_bSmart)
  123. NotifyChanged(pMember->m_pSmartSink, NULL);
  124. m_apMembers.RemoveAt(lIndex);
  125. return TRUE;
  126. }
  127. void CFilteringSink::SetFrontFilter(IHmmFilter* pFilter)
  128. {
  129. NotifyChanged(m_pFrontFilter, pFilter);
  130. if(pFilter) pFilter->AddRef();
  131. if(m_pFrontFilter) m_pFrontFilter->Release();
  132. m_pFrontFilter = pFilter;
  133. }
  134. HRESULT CFilteringSink::CheckAndSend(IHmmPropertySource* pSource, BOOL bSend,
  135. IHmmPropertyList** ppList, IUnknown** ppHint)
  136. {
  137. if(ppList) *ppList = NULL;
  138. if(ppHint) *ppHint = NULL;
  139. HRESULT hres;
  140. BOOL bFound = FALSE;
  141. // Check the front filter first
  142. // ============================
  143. if(m_pFrontFilter)
  144. {
  145. hres = m_pFrontFilter->CheckObject(pSource, ppList, NULL);
  146. if(hres != HMM_S_NO_ERROR) return hres;
  147. }
  148. // Check individual members
  149. // ========================
  150. for(int i = 0; i < m_apMembers.GetSize(); i++)
  151. {
  152. CAnySink* pMember = m_apMembers[i];
  153. if(bSend)
  154. {
  155. // Just send it
  156. hres = pMember->Send(pSource, *ppList)
  157. if(FAILED(hres)) return hres;
  158. }
  159. else
  160. {
  161. IHmmFilter* pFilter = pMember->GetFilter();
  162. if(pFilter != NULL)
  163. {
  164. if(pFilter->CheckObject(pSource, NULL, NULL) == HMM_S_NO_ERROR)
  165. {
  166. bFound = TRUE;
  167. }
  168. pFilter->Release();
  169. }
  170. else
  171. {
  172. bFound = TRUE;
  173. }
  174. }
  175. }
  176. if(bFound || bSend)
  177. return HMM_S_NO_ERROR;
  178. else
  179. return HMM_S_FALSE;
  180. }