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.
758 lines
19 KiB
758 lines
19 KiB
/*++
|
|
|
|
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;
|
|
}
|