759 lines
18 KiB
C++
759 lines
18 KiB
C++
/*++
|
||
|
||
Copyright (C) Microsoft Corporation, 1997 - 1999
|
||
|
||
Module Name:
|
||
|
||
cpubfilt.cxx
|
||
|
||
Abstract:
|
||
|
||
This file contains the implementation of the PublisherFilter
|
||
for the ISensNetwork interface exposed by SENS.
|
||
|
||
Author:
|
||
|
||
Gopal Parupudi <GopalP>
|
||
|
||
[Notes:]
|
||
|
||
optional-notes
|
||
|
||
Revision History:
|
||
|
||
GopalP 1/26/1998 Start.
|
||
|
||
--*/
|
||
|
||
|
||
|
||
#include <precomp.hxx>
|
||
|
||
|
||
//
|
||
// Globals
|
||
//
|
||
LONG g_cFilterObj; // Count of active components
|
||
LONG g_cFilterLock; // Count of Server locks
|
||
|
||
|
||
|
||
|
||
|
||
//
|
||
// Constructors and Destructors
|
||
//
|
||
CImpISensNetworkFilter::CImpISensNetworkFilter(
|
||
void
|
||
) : m_cRef(1L), // Add a reference.
|
||
m_pConnectionMade_Enum(NULL),
|
||
m_pConnectionMadeNoQOC_Enum(NULL),
|
||
m_pConnectionLost_Enum(NULL),
|
||
m_pDestinationReachable_Enum(NULL),
|
||
m_pDestinationReachableNoQOC_Enum(NULL),
|
||
m_pConnectionMade_FiringControl(NULL),
|
||
m_pConnectionMadeNoQOC_FiringControl(NULL),
|
||
m_pConnectionLost_FiringControl(NULL),
|
||
m_pDestinationReachable_FiringControl(NULL),
|
||
m_pDestinationReachableNoQOC_FiringControl(NULL)
|
||
{
|
||
InterlockedIncrement(&g_cFilterObj);
|
||
}
|
||
|
||
CImpISensNetworkFilter::~CImpISensNetworkFilter(
|
||
void
|
||
)
|
||
{
|
||
InterlockedDecrement(&g_cFilterObj);
|
||
|
||
//
|
||
// Release all references that we added to IEnumEventObject pointers,
|
||
// if any.
|
||
//
|
||
if (m_pConnectionMade_Enum)
|
||
{
|
||
m_pConnectionMade_Enum->Release();
|
||
}
|
||
|
||
if (m_pConnectionMadeNoQOC_Enum)
|
||
{
|
||
m_pConnectionMadeNoQOC_Enum->Release();
|
||
}
|
||
|
||
if (m_pConnectionLost_Enum)
|
||
{
|
||
m_pConnectionLost_Enum->Release();
|
||
}
|
||
|
||
if (m_pDestinationReachable_Enum)
|
||
{
|
||
m_pDestinationReachable_Enum->Release();
|
||
}
|
||
|
||
if (m_pDestinationReachableNoQOC_Enum)
|
||
{
|
||
m_pDestinationReachableNoQOC_Enum->Release();
|
||
}
|
||
|
||
//
|
||
// Release all references that we added to IFiringControl pointers,
|
||
// if any (and there shouldn't be any).
|
||
//
|
||
if (m_pConnectionMade_FiringControl)
|
||
{
|
||
m_pConnectionMade_FiringControl->Release();
|
||
}
|
||
|
||
if (m_pConnectionMadeNoQOC_FiringControl)
|
||
{
|
||
m_pConnectionMadeNoQOC_FiringControl->Release();
|
||
}
|
||
|
||
if (m_pConnectionLost_FiringControl)
|
||
{
|
||
m_pConnectionLost_FiringControl->Release();
|
||
}
|
||
|
||
if (m_pDestinationReachable_FiringControl)
|
||
{
|
||
m_pDestinationReachable_FiringControl->Release();
|
||
}
|
||
|
||
if (m_pDestinationReachableNoQOC_FiringControl)
|
||
{
|
||
m_pDestinationReachableNoQOC_FiringControl->Release();
|
||
}
|
||
}
|
||
|
||
|
||
|
||
|
||
//
|
||
// Standard QueryInterface
|
||
//
|
||
STDMETHODIMP
|
||
CImpISensNetworkFilter::QueryInterface(
|
||
REFIID riid,
|
||
LPVOID *ppv
|
||
)
|
||
{
|
||
HRESULT hr;
|
||
|
||
DebugTraceGuid("CImpISensNetworkFilter:QueryInterface()", riid);
|
||
|
||
hr = S_OK;
|
||
*ppv = NULL;
|
||
|
||
// IUnknown
|
||
if (IsEqualIID(riid, IID_IUnknown))
|
||
{
|
||
*ppv = (ISensNetwork *) this;
|
||
}
|
||
else
|
||
// ISensNetwork
|
||
if (IsEqualIID(riid, IID_ISensNetwork))
|
||
{
|
||
*ppv = (ISensNetwork *) this;
|
||
}
|
||
else
|
||
// IPublisherFilter
|
||
if (IsEqualIID(riid, IID_IPublisherFilter))
|
||
{
|
||
*ppv = (IPublisherFilter *) this;
|
||
}
|
||
else
|
||
{
|
||
hr = E_NOINTERFACE;
|
||
}
|
||
|
||
if (NULL != *ppv)
|
||
{
|
||
((LPUNKNOWN)*ppv)->AddRef();
|
||
}
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
|
||
//
|
||
// IDispatch member function implementations. These are dummy implementations
|
||
// as EventSystem never calls them.
|
||
//
|
||
|
||
STDMETHODIMP
|
||
CImpISensNetworkFilter::GetTypeInfoCount(
|
||
UINT *pCountITypeInfo
|
||
)
|
||
{
|
||
return E_NOTIMPL;
|
||
|
||
}
|
||
|
||
STDMETHODIMP
|
||
CImpISensNetworkFilter::GetTypeInfo(
|
||
UINT iTypeInfo,
|
||
LCID lcid,
|
||
ITypeInfo **ppITypeInfo
|
||
)
|
||
{
|
||
return E_NOTIMPL;
|
||
}
|
||
|
||
STDMETHODIMP
|
||
CImpISensNetworkFilter::GetIDsOfNames(
|
||
REFIID riid,
|
||
LPOLESTR *arrNames,
|
||
UINT cNames,
|
||
LCID lcid,
|
||
DISPID *arrDispIDs)
|
||
{
|
||
return E_NOTIMPL;
|
||
}
|
||
|
||
STDMETHODIMP
|
||
CImpISensNetworkFilter::Invoke(
|
||
DISPID dispID,
|
||
REFIID riid,
|
||
LCID lcid,
|
||
WORD wFlags,
|
||
DISPPARAMS *pDispParams,
|
||
VARIANT *pvarResult,
|
||
EXCEPINFO *pExecpInfo,
|
||
UINT *puArgErr
|
||
)
|
||
{
|
||
return E_NOTIMPL;
|
||
}
|
||
|
||
|
||
|
||
|
||
//
|
||
// Standard AddRef and Release
|
||
//
|
||
STDMETHODIMP_(ULONG)
|
||
CImpISensNetworkFilter::AddRef(
|
||
void
|
||
)
|
||
{
|
||
return InterlockedIncrement(&m_cRef);
|
||
}
|
||
|
||
STDMETHODIMP_(ULONG)
|
||
CImpISensNetworkFilter::Release(
|
||
void
|
||
)
|
||
{
|
||
LONG cRefT;
|
||
|
||
SensPrint(SENS_INFO, (SENS_STRING("\t| CImpISensNetworkFilter::Release(m_cRef = %d) called.\n"), m_cRef));
|
||
|
||
cRefT = InterlockedDecrement((PLONG) &m_cRef);
|
||
|
||
if (0 == m_cRef)
|
||
{
|
||
delete this;
|
||
}
|
||
|
||
return cRefT;
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ISensNetwork Implementation.
|
||
//
|
||
|
||
STDMETHODIMP
|
||
CImpISensNetworkFilter::ConnectionMade(
|
||
BSTR bstrConnection,
|
||
ULONG ulType,
|
||
LPSENS_QOCINFO lpQOCInfo
|
||
)
|
||
{
|
||
SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
|
||
SensPrint(SENS_INFO, (SENS_STRING("CImpISensNetworkFilter::ConnectionMade() called\n\n")));
|
||
SensPrintW(SENS_INFO, (SENS_BSTR(" bstrConnection - %s\n"), bstrConnection));
|
||
SensPrint(SENS_INFO, (SENS_STRING(" ulType - 0x%x\n"), ulType));
|
||
SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
|
||
|
||
HRESULT hr = S_OK;
|
||
ConnectionFilter filter(PROPERTY_CONNECTION_MADE_TYPE, ulType, hr);
|
||
if (SUCCEEDED(hr))
|
||
{
|
||
hr = FilterAndFire(
|
||
filter,
|
||
m_pConnectionMade_Enum,
|
||
m_pConnectionMade_FiringControl
|
||
);
|
||
}
|
||
|
||
// We're done with this IFiringControl object.
|
||
m_pConnectionMade_FiringControl->Release();
|
||
m_pConnectionMade_FiringControl = NULL;
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
STDMETHODIMP
|
||
CImpISensNetworkFilter::ConnectionMadeNoQOCInfo(
|
||
BSTR bstrConnection,
|
||
ULONG ulType
|
||
)
|
||
{
|
||
SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
|
||
SensPrint(SENS_INFO, (SENS_STRING("CImpISensNetworkFilter::ConnectionMadeNoQOCInfo() called\n\n")));
|
||
SensPrintW(SENS_INFO, (SENS_BSTR(" bstrConnection - %s\n"), bstrConnection));
|
||
SensPrint(SENS_INFO, (SENS_STRING(" ulType - 0x%x\n"), ulType));
|
||
SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
|
||
|
||
HRESULT hr = S_OK;
|
||
ConnectionFilter filter(PROPERTY_CONNECTION_MADE_NOQOC_TYPE, ulType, hr);
|
||
if (SUCCEEDED(hr))
|
||
{
|
||
hr = FilterAndFire(
|
||
filter,
|
||
m_pConnectionMadeNoQOC_Enum,
|
||
m_pConnectionMadeNoQOC_FiringControl
|
||
);
|
||
}
|
||
|
||
// We're done with this IFiringControl object.
|
||
m_pConnectionMadeNoQOC_FiringControl->Release();
|
||
m_pConnectionMadeNoQOC_FiringControl = NULL;
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
STDMETHODIMP
|
||
CImpISensNetworkFilter::ConnectionLost(
|
||
BSTR bstrConnection,
|
||
ULONG ulType
|
||
)
|
||
{
|
||
SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
|
||
SensPrint(SENS_INFO, (SENS_STRING("CImpISensNetworkFilter::ConnectionLost() called\n\n")));
|
||
SensPrintW(SENS_INFO, (SENS_BSTR(" bstrConnection - %s\n"), bstrConnection));
|
||
SensPrint(SENS_INFO, (SENS_STRING(" ulType - 0x%x\n"), ulType));
|
||
SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
|
||
|
||
HRESULT hr = S_OK;
|
||
ConnectionFilter filter(PROPERTY_CONNECTION_LOST_TYPE, ulType, hr);
|
||
if (SUCCEEDED(hr))
|
||
{
|
||
hr = FilterAndFire(
|
||
filter,
|
||
m_pConnectionLost_Enum,
|
||
m_pConnectionLost_FiringControl
|
||
);
|
||
}
|
||
|
||
// We're done with this IFiringControl object.
|
||
m_pConnectionLost_FiringControl->Release();
|
||
m_pConnectionLost_FiringControl = NULL;
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
STDMETHODIMP
|
||
CImpISensNetworkFilter::DestinationReachable(
|
||
BSTR bstrDestination,
|
||
BSTR bstrConnection,
|
||
ULONG ulType,
|
||
LPSENS_QOCINFO lpQOCInfo
|
||
)
|
||
{
|
||
SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
|
||
SensPrint(SENS_INFO, (SENS_STRING("CImpISensNetworkFilter::DestinationReachable() called\n\n")));
|
||
SensPrintW(SENS_INFO, (SENS_BSTR(" bstrDestination - %s\n"), bstrDestination));
|
||
SensPrintW(SENS_INFO, (SENS_BSTR(" bstrConnection - %s\n"), bstrConnection));
|
||
SensPrint(SENS_INFO, (SENS_STRING(" ulType - 0x%x\n"), ulType));
|
||
SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
|
||
|
||
HRESULT hr = S_OK;
|
||
ReachabilityFilter filter(PROPERTY_DESTINATION, PROPERTY_DESTINATION_TYPE, bstrDestination, ulType, hr);
|
||
if (SUCCEEDED(hr))
|
||
{
|
||
hr = FilterAndFire(
|
||
filter,
|
||
m_pDestinationReachable_Enum,
|
||
m_pDestinationReachable_FiringControl
|
||
);
|
||
}
|
||
|
||
// We're done with this IFiringControl object.
|
||
m_pDestinationReachable_FiringControl->Release();
|
||
m_pDestinationReachable_FiringControl = NULL;
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
STDMETHODIMP
|
||
CImpISensNetworkFilter::DestinationReachableNoQOCInfo(
|
||
BSTR bstrDestination,
|
||
BSTR bstrConnection,
|
||
ULONG ulType
|
||
)
|
||
{
|
||
SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
|
||
SensPrint(SENS_INFO, (SENS_STRING("CImpISensNetworkFilter::DestinationReachableNoQOCInfo() called\n\n")));
|
||
SensPrintW(SENS_INFO, (SENS_BSTR(" bstrDestination - %s\n"), bstrDestination));
|
||
SensPrintW(SENS_INFO, (SENS_BSTR(" bstrConnection - %s\n"), bstrConnection));
|
||
SensPrint(SENS_INFO, (SENS_STRING(" ulType - 0x%x\n"), ulType));
|
||
SensPrint(SENS_INFO, (SENS_STRING("---------------------------------------------------------\n")));
|
||
|
||
|
||
HRESULT hr = S_OK;
|
||
ReachabilityFilter filter(PROPERTY_DESTINATION_NOQOC, PROPERTY_DESTINATION_NOQOC_TYPE, bstrDestination, ulType, hr);
|
||
if (SUCCEEDED(hr))
|
||
{
|
||
hr = FilterAndFire(
|
||
filter,
|
||
m_pDestinationReachableNoQOC_Enum,
|
||
m_pDestinationReachableNoQOC_FiringControl
|
||
);
|
||
}
|
||
|
||
// We're done with this IFiringControl object.
|
||
m_pDestinationReachableNoQOC_FiringControl->Release();
|
||
m_pDestinationReachableNoQOC_FiringControl = NULL;
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
|
||
//
|
||
// IPublisherFilter Implementation.
|
||
//
|
||
STDMETHODIMP
|
||
CImpISensNetworkFilter::Initialize(
|
||
BSTR bstrMethodName,
|
||
IDispatch* dispUserDefined
|
||
)
|
||
{
|
||
HRESULT hr = E_INVALIDARG;
|
||
|
||
IEnumEventObject** ppEnum = NULL;
|
||
if (wcscmp(bstrMethodName, CONNECTION_MADE_METHOD) == 0)
|
||
{
|
||
ppEnum = &m_pConnectionMade_Enum;
|
||
}
|
||
else
|
||
if (wcscmp(bstrMethodName, CONNECTION_MADE_NOQOC_METHOD) == 0)
|
||
{
|
||
ppEnum = &m_pConnectionMadeNoQOC_Enum;
|
||
}
|
||
else
|
||
if (wcscmp(bstrMethodName, CONNECTION_LOST_METHOD) == 0)
|
||
{
|
||
ppEnum = &m_pConnectionLost_Enum;
|
||
}
|
||
else
|
||
if (wcscmp(bstrMethodName, DESTINATION_REACHABLE_METHOD) == 0)
|
||
{
|
||
ppEnum = &m_pDestinationReachable_Enum;
|
||
}
|
||
else
|
||
if (wcscmp(bstrMethodName, DESTINATION_REACHABLE_NOQOC_METHOD) == 0)
|
||
{
|
||
ppEnum = &m_pDestinationReachableNoQOC_Enum;
|
||
}
|
||
|
||
if (ppEnum != NULL)
|
||
{
|
||
IEventControl* control = NULL;
|
||
hr = dispUserDefined->QueryInterface(IID_IEventControl, (void**)&control);
|
||
if (FAILED(hr))
|
||
{
|
||
return hr;
|
||
}
|
||
|
||
IEventObjectCollection* collection = NULL;
|
||
hr = control->GetSubscriptions(bstrMethodName, NULL, NULL, &collection);
|
||
if (SUCCEEDED(hr))
|
||
{
|
||
hr = collection->get_NewEnum(ppEnum);
|
||
|
||
// Don't need the collection any more... just keep the enum
|
||
collection->Release();
|
||
}
|
||
|
||
control->Release();
|
||
}
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
STDMETHODIMP
|
||
CImpISensNetworkFilter::PrepareToFire(
|
||
BSTR bstrMethodName,
|
||
IFiringControl* pIFiringControl
|
||
)
|
||
{
|
||
HRESULT hr = E_INVALIDARG;
|
||
|
||
IFiringControl** ppFiringControl = NULL;
|
||
if (wcscmp(bstrMethodName, CONNECTION_MADE_METHOD) == 0)
|
||
{
|
||
ppFiringControl = &m_pConnectionMade_FiringControl;
|
||
}
|
||
else
|
||
if (wcscmp(bstrMethodName, CONNECTION_MADE_NOQOC_METHOD) == 0)
|
||
{
|
||
ppFiringControl = &m_pConnectionMadeNoQOC_FiringControl;
|
||
}
|
||
else
|
||
if (wcscmp(bstrMethodName, CONNECTION_LOST_METHOD) == 0)
|
||
{
|
||
ppFiringControl = &m_pConnectionLost_FiringControl;
|
||
}
|
||
else
|
||
if (wcscmp(bstrMethodName, DESTINATION_REACHABLE_METHOD) == 0)
|
||
{
|
||
ppFiringControl = &m_pDestinationReachable_FiringControl;
|
||
}
|
||
else
|
||
if (wcscmp(bstrMethodName, DESTINATION_REACHABLE_NOQOC_METHOD) == 0)
|
||
{
|
||
ppFiringControl = &m_pDestinationReachableNoQOC_FiringControl;
|
||
}
|
||
|
||
if (ppFiringControl != NULL)
|
||
{
|
||
*ppFiringControl = pIFiringControl;
|
||
pIFiringControl->AddRef();
|
||
hr = S_OK;
|
||
}
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
|
||
//
|
||
// Filter helper implementations.
|
||
//
|
||
|
||
|
||
//
|
||
// ConnectionFilter implementation.
|
||
//
|
||
|
||
ConnectionFilter::ConnectionFilter(
|
||
const wchar_t* connectionTypeProperty,
|
||
ULONG connectionType,
|
||
HRESULT& hr
|
||
) : m_connectionTypeProperty(SysAllocString(connectionTypeProperty)),
|
||
m_connectionType(connectionType)
|
||
{
|
||
if (m_connectionTypeProperty == NULL)
|
||
{
|
||
hr = E_OUTOFMEMORY;
|
||
}
|
||
else
|
||
{
|
||
hr = S_OK;
|
||
}
|
||
}
|
||
|
||
|
||
ConnectionFilter::~ConnectionFilter(
|
||
void
|
||
)
|
||
{
|
||
SysFreeString(m_connectionTypeProperty);
|
||
}
|
||
|
||
|
||
HRESULT
|
||
ConnectionFilter::CheckMatch(
|
||
IEventSubscription* pSubscription
|
||
) const
|
||
{
|
||
VARIANT value;
|
||
VariantInit(&value);
|
||
HRESULT hr = pSubscription->GetPublisherProperty(m_connectionTypeProperty, &value);
|
||
|
||
if (hr == S_FALSE)
|
||
{
|
||
// If the property isn't present, consider it a successful match.
|
||
hr = S_OK;
|
||
}
|
||
else
|
||
if (hr == S_OK)
|
||
{
|
||
// If the property is there, it must match the incoming parameter value.
|
||
ASSERT(value.vt == VT_UI4);
|
||
SensPrintW(SENS_INFO, (SENS_BSTR("\t| Property %s has value 0x%x\n"), m_connectionTypeProperty, value.ulVal));
|
||
hr = (m_connectionType == value.ulVal) ? S_OK : S_FALSE;
|
||
}
|
||
|
||
VariantClear(&value);
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
//
|
||
// ReachabilityFilter implementation
|
||
//
|
||
|
||
ReachabilityFilter::ReachabilityFilter(
|
||
const wchar_t* destinationProperty,
|
||
const wchar_t* destinationTypeProperty,
|
||
BSTR destination,
|
||
ULONG destinationType,
|
||
HRESULT& hr
|
||
) : m_destinationProperty(SysAllocString(destinationProperty)),
|
||
m_destinationTypeProperty(SysAllocString(destinationTypeProperty)),
|
||
m_destination(destination),
|
||
m_destinationType(destinationType)
|
||
{
|
||
if (m_destinationProperty == NULL || m_destinationTypeProperty == NULL)
|
||
{
|
||
hr = E_OUTOFMEMORY;
|
||
}
|
||
else
|
||
{
|
||
hr = S_OK;
|
||
}
|
||
}
|
||
|
||
|
||
ReachabilityFilter::~ReachabilityFilter(
|
||
void
|
||
)
|
||
{
|
||
SysFreeString(m_destinationProperty);
|
||
SysFreeString(m_destinationTypeProperty);
|
||
}
|
||
|
||
|
||
HRESULT
|
||
ReachabilityFilter::CheckMatch(
|
||
IEventSubscription* pSubscription
|
||
) const
|
||
{
|
||
HRESULT hr;
|
||
|
||
// Check the destination property
|
||
VARIANT value;
|
||
VariantInit(&value);
|
||
hr = pSubscription->GetPublisherProperty(m_destinationProperty, &value);
|
||
|
||
if (hr == S_FALSE)
|
||
{
|
||
// If the property isn't present, consider it a successful match.
|
||
hr = S_OK;
|
||
SensPrintW(SENS_INFO, (SENS_BSTR("\t\t\t| Subscription (0x%x) has no %s Dest Property\n"), pSubscription, m_destinationProperty));
|
||
}
|
||
else
|
||
if (hr == S_OK)
|
||
{
|
||
// If the property is there, it must match the incoming parameter value.
|
||
ASSERT(value.vt == VT_BSTR);
|
||
SensPrintW(SENS_INFO, (SENS_BSTR("\t\t\t| Property %s has value %s\n"), m_destinationProperty, value.bstrVal));
|
||
hr = (wcscmp(m_destination, value.bstrVal) == 0) ? S_OK : S_FALSE;
|
||
}
|
||
|
||
VariantClear(&value);
|
||
|
||
if (hr == S_OK)
|
||
{
|
||
// If we have a match so far, check the destination type property
|
||
VARIANT value;
|
||
VariantInit(&value);
|
||
hr = pSubscription->GetPublisherProperty(m_destinationTypeProperty, &value);
|
||
|
||
if (hr == S_FALSE)
|
||
{
|
||
// If the property isn't present, consider it a successful match.
|
||
hr = S_OK;
|
||
SensPrintW(SENS_INFO, (SENS_BSTR("\t\t\t| Subscription (0x%x) has no %s Type Property\n"), pSubscription, m_destinationTypeProperty));
|
||
}
|
||
else
|
||
if (hr == S_OK)
|
||
{
|
||
// If the property is there, it must match the incoming parameter value.
|
||
ASSERT(value.vt == VT_UI4);
|
||
SensPrintW(SENS_INFO, (SENS_BSTR("\t\t\t| Property %s has value 0x%x\n"), m_destinationTypeProperty, value.ulVal));
|
||
hr = (m_destinationType == value.ulVal) ? S_OK : S_FALSE;
|
||
}
|
||
|
||
VariantClear(&value);
|
||
}
|
||
|
||
return hr;
|
||
}
|
||
|
||
|
||
|
||
|
||
//
|
||
// Generic filter and fire method.
|
||
//
|
||
HRESULT
|
||
FilterAndFire(
|
||
const Filter& filter,
|
||
IEnumEventObject* enumerator,
|
||
IFiringControl* firingControl
|
||
)
|
||
{
|
||
HRESULT hr;
|
||
IEventSubscription* pSubscription = NULL;
|
||
int i = 0;
|
||
|
||
//
|
||
// Reset the enum back to the start
|
||
//
|
||
hr = enumerator->Reset();
|
||
|
||
//
|
||
// Loop through all the candidate subscriptions and fire the ones
|
||
// that match the filter criteria.
|
||
//
|
||
for (;;)
|
||
{
|
||
ULONG cCount = 1;
|
||
|
||
hr = enumerator->Next(cCount, (IUnknown**)&pSubscription, &cCount);
|
||
if (hr != S_OK || cCount != 1)
|
||
{
|
||
break;
|
||
}
|
||
|
||
SensPrintA(SENS_INFO, ("\t\t\t| ****** Count for 0x%x is %d\n", enumerator, ++i));
|
||
|
||
hr = filter.CheckMatch(pSubscription);
|
||
if (hr == S_OK)
|
||
{
|
||
SensPrintA(SENS_INFO, ("\t\t\t| FilterAndFire(0x%x): CheckMatch() succeeded\n", enumerator));
|
||
firingControl->FireSubscription(pSubscription);
|
||
}
|
||
|
||
pSubscription->Release();
|
||
pSubscription = NULL;
|
||
}
|
||
|
||
//
|
||
// Cleanup, including any left-over stuff in case of premature exit from the loop.
|
||
//
|
||
if (pSubscription != NULL)
|
||
{
|
||
pSubscription->Release();
|
||
}
|
||
|
||
return S_OK;
|
||
}
|