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

/*++
Copyright (C) 1996-2001 Microsoft Corporation
Module Name:
FILTSINK.CPP
Abstract:
History:
--*/
#include "filtsink.h"
CFilteringSink::~CFilteringSink()
{
m_pFrontFilter->Release();
}
void* CFilteringSink::GetInterface(REFIID riid)
{
if(riid == IID_IHmmEventSink)
{
return (IHmmEventSink*)&m_XEventSink;
}
else return NULL;
}
STDMETHODIMP CFilteringSink::XEventSink::Indicate(
IN long lNumObjects,
IN IHmmClassObject **apObjects)
{
for(long l = 0; l < lNumObjects; l++)
{
IHmmClassObject* pObject = apObjects[l];
IHmmPropertySource* pSource;
pObject->QueryInterface(IID_IHmmPropertySource, (void**)&pSource);
HRESULT hres = m_pObject->CheckAndSend(pSource, TRUE, NULL, NULL);
pSource->Release();
if(FAILED(hres)) return hres;
}
return HMM_S_NO_ERROR;
}
STDMETHODIMP CFilteringSink::XEventSink::IndicateRaw(
IN long lNumObjects,
IN IHmmPropertySource **apObjects)
{
for(long l = 0; l < lNumObjects; l++)
{
HRESULT hres = m_pObject->CheckAndSend(apObjects[l], TRUE, NULL, NULL);
if(FAILED(hres)) return hres;
}
return HMM_S_NO_ERROR;
}
STDMETHODIMP CFilteringSink::XEventSink::IndicateWithHint(
IN long lNumObjects,
IN IHmmClassObject *pObject,
IN IUnknown *pHint)
{
// for now, ignore the hint
return Indicate(1, &pObject);
}
STDMETHODIMP CFilteringSink::XEventSink::CheckObject(
IN IHmmPropertySource *pSource,
OUT IHmmPropertyList **ppList,
OUT IUnknown **ppHint)
{
return m_pObject->CheckAndSend(pSource, FALSE, ppList, ppHint);
}
STDMETHODIMP CFilteringSink::XEventSink::GetRequirements(
IN IHmmFilter **ppRequirements)
{
return E_NOTIMPL;
}
STDMETHODIMP CFilteringSink::XEventSink::SetRequirementChangeSink(
IN IHmmRequirementChangeSink *pNewSink,
OUT IHmmRequirementChangeSink **ppOldSink)
{
if(ppOldSink)
{
*ppOldSink = m_pObject->m_pChangeSink;
}
else
{
if(m_pObject->m_pChangeSink) m_pObject->m_pChangeSink->Release();
}
m_pObject->m_pChangeSink = pNewSink;
if(pNewSink) pNewSink->AddRef();
return HMM_S_NO_ERROR;
}
STDMETHODIMP CFilteringSink::XEventSink::GetOptimizedSink(
IN IHmmFilter *pGuaranteedCondition,
IN long lFlags,
OUT IHmmEventSink **ppOptimizedSink)
{
if(pGuaranteedCondition == NULL || ppOptimizedSink == NULL)
{
return HMM_E_INVALID_PARAMETER;
}
// For now: return ourselves
*ppOptimizedSink = (IHmmEventSink*)this;
AddRef();
return HMM_S_NO_ERROR;
}
STDMETHODIMP CFilteringSink::XEventSink::GetUsefulSubsink(
long lIndex,
long lFlags,
IHmmEventSink **ppSubsink)
{
// For now --- no useful subsinks
*ppSubsink = NULL;
return HMM_S_NO_MORE_DATA;
}
long CFilteringSink::AddSmartMember(IHmmEventSink* pSmartSink)
{
CMember* pMember = new CMember(pSmartSink);
m_apMembers.Add(pMember);
NotifyChanged(NULL, pSmartSink);
return m_apMembers.GetSize();
}
long CFilteringSink::AddDumbMember(IHmmRawObjectSink* pDumbSink)
{
CMember* pMember = new CMember(pDumbSink);
m_apMembers.Add(pMember);
return m_apMembers.GetSize();
}
BOOL CFilteringSink::RemoveMember(long lIndex)
{
CMember* pMember = m_apMembers[lIndex];
if(pMember->m_bSmart)
NotifyChanged(pMember->m_pSmartSink, NULL);
m_apMembers.RemoveAt(lIndex);
return TRUE;
}
void CFilteringSink::SetFrontFilter(IHmmFilter* pFilter)
{
NotifyChanged(m_pFrontFilter, pFilter);
if(pFilter) pFilter->AddRef();
if(m_pFrontFilter) m_pFrontFilter->Release();
m_pFrontFilter = pFilter;
}
HRESULT CFilteringSink::CheckAndSend(IHmmPropertySource* pSource, BOOL bSend,
IHmmPropertyList** ppList, IUnknown** ppHint)
{
if(ppList) *ppList = NULL;
if(ppHint) *ppHint = NULL;
HRESULT hres;
BOOL bFound = FALSE;
// Check the front filter first
// ============================
if(m_pFrontFilter)
{
hres = m_pFrontFilter->CheckObject(pSource, ppList, NULL);
if(hres != HMM_S_NO_ERROR) return hres;
}
// Check individual members
// ========================
for(int i = 0; i < m_apMembers.GetSize(); i++)
{
CAnySink* pMember = m_apMembers[i];
if(bSend)
{
// Just send it
hres = pMember->Send(pSource, *ppList)
if(FAILED(hres)) return hres;
}
else
{
IHmmFilter* pFilter = pMember->GetFilter();
if(pFilter != NULL)
{
if(pFilter->CheckObject(pSource, NULL, NULL) == HMM_S_NO_ERROR)
{
bFound = TRUE;
}
pFilter->Release();
}
else
{
bFound = TRUE;
}
}
}
if(bFound || bSend)
return HMM_S_NO_ERROR;
else
return HMM_S_FALSE;
}