mirror of https://github.com/tongzx/nt5src
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
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;
|
|
}
|
|
|
|
|
|
|