1052 lines
24 KiB
C++
1052 lines
24 KiB
C++
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
seolib.cpp
|
|
|
|
Abstract:
|
|
|
|
This module contains the implementations for various
|
|
utility classes and functions of the Server Extension
|
|
Object system.
|
|
|
|
Author:
|
|
|
|
Don Dumitru (dondu@microsoft.com)
|
|
|
|
Revision History:
|
|
|
|
dondu 05/20/97 Created.
|
|
|
|
--*/
|
|
|
|
|
|
#include <stdio.h>
|
|
#include <windows.h>
|
|
#include <mailmsg.h>
|
|
#include <dbgtrace.h>
|
|
#include <cpool.h>
|
|
#include <filehc.h>
|
|
#define _ATL_NO_DEBUG_CRT
|
|
#define _ATL_STATIC_REGISTRY 1
|
|
#define _ASSERTE _ASSERT
|
|
#define _WINDLL
|
|
#include "atlbase.h"
|
|
extern CComModule _Module;
|
|
#include "atlcom.h"
|
|
#undef _WINDLL
|
|
#include "seo.h"
|
|
#include "seolib.h"
|
|
|
|
|
|
CEventBaseDispatcher::CEventBaseDispatcher() {
|
|
|
|
// nothing
|
|
}
|
|
|
|
|
|
CEventBaseDispatcher::~CEventBaseDispatcher() {
|
|
|
|
// nothing
|
|
}
|
|
|
|
|
|
CEventBaseDispatcher::CBinding::CBinding() {
|
|
|
|
m_bIsValid = FALSE;
|
|
}
|
|
|
|
|
|
CEventBaseDispatcher::CBinding::~CBinding() {
|
|
|
|
// nothing
|
|
}
|
|
|
|
|
|
HRESULT CEventBaseDispatcher::CBinding::Init(IEventBinding *piBinding) {
|
|
HRESULT hrRes;
|
|
CComPtr<IEventPropertyBag> pProps;
|
|
CComVariant varValue;
|
|
|
|
if (!piBinding) {
|
|
return (E_POINTER);
|
|
}
|
|
varValue.vt = VT_BOOL;
|
|
hrRes = piBinding->get_Enabled(&varValue.boolVal);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
return (hrRes);
|
|
}
|
|
m_bIsValid = varValue.boolVal ? TRUE: FALSE;
|
|
varValue.Clear();
|
|
m_dwPriority = (DWORD) PRIO_DEFAULT;
|
|
m_bExclusive = FALSE;
|
|
m_piBinding = piBinding;
|
|
hrRes = piBinding->get_SourceProperties(&pProps);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
return (hrRes);
|
|
}
|
|
hrRes = pProps->Item(&CComVariant(L"Priority"),&varValue);
|
|
if (SUCCEEDED(hrRes) && (hrRes != S_FALSE)) {
|
|
hrRes = varValue.ChangeType(VT_I4);
|
|
if (SUCCEEDED(hrRes)) {
|
|
if (varValue.lVal < PRIO_MIN) {
|
|
varValue.lVal = PRIO_MIN;
|
|
} else if (varValue.lVal > PRIO_MAX) {
|
|
varValue.lVal = PRIO_MAX;
|
|
}
|
|
m_dwPriority = (DWORD) varValue.lVal;
|
|
} else {
|
|
hrRes = varValue.ChangeType(VT_BSTR);
|
|
if (SUCCEEDED(hrRes)) {
|
|
static struct {
|
|
LPCWSTR pszString;
|
|
DWORD dwValue;
|
|
} sConvert[] = {{PRIO_HIGHEST_STR,PRIO_HIGHEST},
|
|
{PRIO_HIGH_STR,PRIO_HIGH},
|
|
{PRIO_MEDIUM_STR,PRIO_MEDIUM},
|
|
{PRIO_LOW_STR,PRIO_LOW},
|
|
{PRIO_LOWEST_STR,PRIO_LOWEST},
|
|
{PRIO_DEFAULT_STR,PRIO_DEFAULT},
|
|
{NULL,0}};
|
|
for (DWORD dwIdx=0;sConvert[dwIdx].pszString;dwIdx++) {
|
|
if (_wcsicmp(varValue.bstrVal,sConvert[dwIdx].pszString) == 0) {
|
|
m_dwPriority = sConvert[dwIdx].dwValue;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
varValue.Clear();
|
|
hrRes = pProps->Item(&CComVariant(L"Exclusive"),&varValue);
|
|
if (SUCCEEDED(hrRes) && (hrRes != S_FALSE)) {
|
|
hrRes = varValue.ChangeType(VT_BOOL);
|
|
if (SUCCEEDED(hrRes)) {
|
|
m_bExclusive = (varValue.boolVal ? TRUE : FALSE);
|
|
}
|
|
}
|
|
hrRes = InitRuleEngine();
|
|
// ignore result
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
int CEventBaseDispatcher::CBinding::Compare(const CBinding& b) const {
|
|
|
|
#if 0
|
|
if (!m_bIsValid || !b.m_bIsValid) {
|
|
if (m_bIsValid == b.m_bIsValid) {
|
|
return (0);
|
|
}
|
|
if (!b.m_bIsValid) {
|
|
return (-1);
|
|
}
|
|
return (1);
|
|
}
|
|
#endif
|
|
if (m_dwPriority == b.m_dwPriority) {
|
|
return (0);
|
|
}
|
|
if (m_dwPriority < b.m_dwPriority) {
|
|
return (-1);
|
|
}
|
|
return (1);
|
|
}
|
|
|
|
|
|
HRESULT CEventBaseDispatcher::CBinding::InitRuleEngine(IEventBinding *piBinding, REFIID iidDesired, IUnknown **ppUnkRuleEngine) {
|
|
HRESULT hrRes;
|
|
CComPtr<IEventPropertyBag> pProperties;
|
|
CComVariant varValue;
|
|
CStringGUID objGuid;
|
|
|
|
if (ppUnkRuleEngine) {
|
|
*ppUnkRuleEngine = NULL;
|
|
}
|
|
if (!piBinding || !ppUnkRuleEngine) {
|
|
return (E_POINTER);
|
|
}
|
|
hrRes = piBinding->get_SourceProperties(&pProperties);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
return (hrRes);
|
|
}
|
|
hrRes = pProperties->Item(&CComVariant(L"RuleEngine"),&varValue);
|
|
if (!SUCCEEDED(hrRes) || (hrRes == S_FALSE)) {
|
|
return (hrRes);
|
|
}
|
|
hrRes = SEOCreateObject(&varValue,piBinding,pProperties,iidDesired,ppUnkRuleEngine);
|
|
return (SUCCEEDED(hrRes)?S_OK:S_FALSE);
|
|
}
|
|
|
|
|
|
HRESULT CEventBaseDispatcher::CBinding::InitRuleEngine() {
|
|
|
|
// default is to not to try to load a rule engine
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
int CEventBaseDispatcher::CBindingList::Compare(CBinding* p1, CBinding* p2) {
|
|
|
|
return (p1->Compare(*p2));
|
|
};
|
|
|
|
|
|
HRESULT CEventBaseDispatcher::CParams::CheckRule(CBinding& b) {
|
|
|
|
// default behavior is to not pay attention to any "rules"
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
HRESULT CEventBaseDispatcher::CParams::CallObject(IEventManager *piManager, CBinding& bBinding) {
|
|
HRESULT hrRes;
|
|
CComPtr<IUnknown> pUnkSink;
|
|
|
|
if (!piManager) {
|
|
return (E_POINTER);
|
|
}
|
|
hrRes = piManager->CreateSink(bBinding.m_piBinding,NULL,&pUnkSink);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
return (hrRes);
|
|
}
|
|
return (CallObject(bBinding,pUnkSink));
|
|
}
|
|
|
|
|
|
HRESULT CEventBaseDispatcher::CParams::CallObject(CBinding& bBinding, IUnknown *pUnkSink) {
|
|
HRESULT hrRes;
|
|
CComQIPtr<IEventSinkNotify,&IID_IEventSinkNotify> pSink;
|
|
CComQIPtr<IDispatch,&IID_IEventSinkNotifyDisp> pSinkDisp;
|
|
DISPPARAMS dpNoArgs = {NULL,NULL,0,0};
|
|
|
|
// Default behavior is to call IEventSinkNotify::OnEvent, or to call
|
|
// IEventSinkNotifyDisp::Invoke passing DISPID_VALUE (which maps to OnEvent).
|
|
//
|
|
// This means that the base dispatcher is able to invoke simple COM objects. If you
|
|
// provide your own CallObject() routine, your routine call delegate this this base
|
|
// implementation if you want to "inherit" this functionality.
|
|
if (!pUnkSink) {
|
|
return (E_POINTER);
|
|
}
|
|
pSink = pUnkSink;
|
|
if (!pSink) {
|
|
pSinkDisp = pUnkSink;
|
|
}
|
|
if (!pSink && !pSinkDisp) {
|
|
return (E_NOINTERFACE);
|
|
}
|
|
if (pSink) {
|
|
hrRes = pSink->OnEvent();
|
|
return (S_OK);
|
|
}
|
|
hrRes = pSinkDisp->Invoke(DISPID_VALUE,
|
|
IID_NULL,
|
|
GetUserDefaultLCID(),
|
|
DISPATCH_METHOD,
|
|
&dpNoArgs,
|
|
NULL,
|
|
NULL,
|
|
NULL);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
return (hrRes);
|
|
}
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
HRESULT CEventBaseDispatcher::CParams::Abort() {
|
|
|
|
return (S_FALSE);
|
|
}
|
|
|
|
|
|
HRESULT CEventBaseDispatcher::Dispatcher(REFGUID rguidEventType, CParams *pParams) {
|
|
HRESULT hrRes;
|
|
CETData *petdData;
|
|
BOOL bObjectCalled = FALSE;
|
|
|
|
petdData = m_Data.Find(rguidEventType);
|
|
if (!petdData) {
|
|
return (S_FALSE);
|
|
}
|
|
for (DWORD dwIdx=0;dwIdx<petdData->Count();dwIdx++) {
|
|
if (!petdData->Index(dwIdx)->m_bIsValid) {
|
|
continue;
|
|
}
|
|
if (bObjectCalled && petdData->Index(dwIdx)->m_bExclusive) {
|
|
continue;
|
|
}
|
|
if (pParams->Abort() == S_OK) {
|
|
break;
|
|
}
|
|
hrRes = pParams->CheckRule(*petdData->Index(dwIdx));
|
|
if (hrRes == S_OK) {
|
|
if (pParams->Abort() == S_OK) {
|
|
break;
|
|
}
|
|
hrRes = pParams->CallObject(m_piEventManager,*petdData->Index(dwIdx));
|
|
if (!SUCCEEDED(hrRes)) {
|
|
continue;
|
|
}
|
|
bObjectCalled = TRUE;
|
|
if ((hrRes == S_FALSE) || petdData->Index(dwIdx)->m_bExclusive) {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
return (bObjectCalled?S_OK:S_FALSE);
|
|
}
|
|
|
|
|
|
HRESULT CEventBaseDispatcher::SetContext(REFGUID rguidEventType, IEventRouter *piRouter, IEventBindings *piBindings) {
|
|
CETData* petData;
|
|
HRESULT hrRes;
|
|
CComPtr<IUnknown> pUnkEnum;
|
|
CComQIPtr<IEnumVARIANT,&IID_IEnumVARIANT> pEnum;
|
|
|
|
if (!piRouter || !piBindings) {
|
|
return (E_POINTER);
|
|
}
|
|
if (!m_piEventManager) {
|
|
hrRes = CoCreateInstance(CLSID_CEventManager,
|
|
NULL,
|
|
CLSCTX_ALL,
|
|
IID_IEventManager,
|
|
(LPVOID *) &m_piEventManager);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
return (hrRes);
|
|
}
|
|
m_piRouter = piRouter;
|
|
}
|
|
petData = m_Data.Find(rguidEventType);
|
|
if (!petData) {
|
|
hrRes = AllocETData(rguidEventType,piBindings,&petData);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
return (hrRes);
|
|
}
|
|
petData->m_guidEventType = rguidEventType;
|
|
hrRes = m_Data.Add(petData);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
delete petData;
|
|
return (hrRes);
|
|
}
|
|
}
|
|
petData->RemoveAll();
|
|
hrRes = piBindings->get__NewEnum(&pUnkEnum);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
return (hrRes);
|
|
}
|
|
pEnum = pUnkEnum;
|
|
if (!pEnum) {
|
|
return (E_NOINTERFACE);
|
|
}
|
|
while (1) {
|
|
CComVariant varValue;
|
|
CComQIPtr<IEventBinding,&IID_IEventBinding> pBinding;
|
|
CBinding *pNewBinding;
|
|
|
|
varValue.Clear();
|
|
hrRes = pEnum->Next(1,&varValue,NULL);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
return (hrRes);
|
|
}
|
|
if (hrRes == S_FALSE) {
|
|
break;
|
|
}
|
|
hrRes = varValue.ChangeType(VT_UNKNOWN);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
_ASSERTE(FALSE);
|
|
continue;
|
|
}
|
|
pBinding = varValue.punkVal;
|
|
if (!pBinding) {
|
|
_ASSERTE(FALSE);
|
|
continue;
|
|
}
|
|
hrRes = AllocBinding(rguidEventType,pBinding,&pNewBinding);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
return (hrRes);
|
|
}
|
|
hrRes = pNewBinding->Init(pBinding);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
return (hrRes);
|
|
}
|
|
hrRes = petData->Add(pNewBinding);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
delete pNewBinding;
|
|
return (hrRes);
|
|
}
|
|
}
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
CEventBaseDispatcher::CETData::CETData() {
|
|
|
|
// nothing
|
|
}
|
|
|
|
|
|
CEventBaseDispatcher::CETData::~CETData() {
|
|
|
|
// nothing
|
|
}
|
|
|
|
|
|
CEventBaseDispatcher::CETData* CEventBaseDispatcher::CETDataList::Find(REFGUID guidEventType) {
|
|
|
|
// tbd - optimize
|
|
for (DWORD dwIdx=0;dwIdx<Count();dwIdx++) {
|
|
if (Index(dwIdx)->m_guidEventType == guidEventType) {
|
|
return (Index(dwIdx));
|
|
}
|
|
}
|
|
return (NULL);
|
|
}
|
|
|
|
|
|
HRESULT CEventBaseDispatcher::AllocBinding(REFGUID rguidEventType,
|
|
IEventBinding *piBinding,
|
|
CBinding **ppNewBinding) {
|
|
|
|
if (ppNewBinding) {
|
|
*ppNewBinding = NULL;
|
|
}
|
|
if (!piBinding || !ppNewBinding) {
|
|
return (E_POINTER);
|
|
}
|
|
*ppNewBinding = new CBinding;
|
|
if (!*ppNewBinding) {
|
|
return (E_OUTOFMEMORY);
|
|
}
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
HRESULT CEventBaseDispatcher::AllocETData(REFGUID guidEventType,
|
|
IEventBindings *piBindings,
|
|
CETData **ppNewETData) {
|
|
|
|
if (ppNewETData) {
|
|
*ppNewETData = NULL;
|
|
}
|
|
if (!piBindings || !ppNewETData) {
|
|
return (E_POINTER);
|
|
}
|
|
*ppNewETData = new CETData;
|
|
if (!*ppNewETData) {
|
|
return (E_OUTOFMEMORY);
|
|
}
|
|
return (S_OK);
|
|
}
|
|
|
|
|
|
static HRESULT SEOGetSources(REFGUID rguidSourceType, IEventSources **ppSources) {
|
|
HRESULT hrRes;
|
|
CComPtr<IEventManager> pManager;
|
|
CComPtr<IEventSourceTypes> pSourceTypes;
|
|
CComPtr<IEventSourceType> pSourceType;
|
|
CComPtr<IEventSources> pSources;
|
|
|
|
if (ppSources) {
|
|
*ppSources = NULL;
|
|
}
|
|
if (!ppSources) {
|
|
hrRes = E_POINTER;
|
|
goto error;
|
|
}
|
|
hrRes = CoCreateInstance(CLSID_CEventManager,NULL,CLSCTX_ALL,IID_IEventManager,(LPVOID *) &pManager);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
hrRes = pManager->get_SourceTypes(&pSourceTypes);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
hrRes = pSourceTypes->Item(&CComVariant((LPCOLESTR) CStringGUID(rguidSourceType)),&pSourceType);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
if (!pSourceType) {
|
|
hrRes = S_FALSE;
|
|
goto error;
|
|
}
|
|
hrRes = pSourceType->get_Sources(ppSources);
|
|
error:
|
|
return (hrRes);
|
|
}
|
|
|
|
|
|
static HRESULT SEOGetSourcesEnum(REFGUID rguidSourceType, IEnumVARIANT **ppEnum) {
|
|
HRESULT hrRes;
|
|
CComPtr<IEventSources> pSources;
|
|
CComPtr<IUnknown> pUnkEnum;
|
|
|
|
if (ppEnum) {
|
|
*ppEnum = NULL;
|
|
}
|
|
if (!ppEnum) {
|
|
hrRes = E_POINTER;
|
|
goto error;
|
|
}
|
|
hrRes = SEOGetSources(rguidSourceType,&pSources);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
if (!pSources) {
|
|
hrRes = S_FALSE;
|
|
goto error;
|
|
}
|
|
hrRes = pSources->get__NewEnum(&pUnkEnum);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
hrRes = pUnkEnum->QueryInterface(IID_IEnumVARIANT,(LPVOID *) ppEnum);
|
|
error:
|
|
return (hrRes);
|
|
}
|
|
|
|
|
|
STDMETHODIMP SEOGetSource(REFGUID rguidSourceType, REFGUID rguidSource, IEventSource **ppSource) {
|
|
HRESULT hrRes;
|
|
CComPtr<IEventSources> pSources;
|
|
|
|
if (ppSource) {
|
|
*ppSource = NULL;
|
|
}
|
|
if (!ppSource) {
|
|
hrRes = E_POINTER;
|
|
goto error;
|
|
}
|
|
hrRes = SEOGetSources(rguidSourceType,&pSources);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
if (!pSources) {
|
|
hrRes = S_FALSE;
|
|
goto error;
|
|
}
|
|
hrRes = pSources->Item(&CComVariant((LPCOLESTR) CStringGUID(rguidSource)),ppSource);
|
|
error:
|
|
return (hrRes);
|
|
}
|
|
|
|
|
|
STDMETHODIMP SEOGetSource(REFGUID rguidSourceType, REFGUID rguidSourceBase, DWORD dwSourceIndex, IEventSource **ppSource) {
|
|
|
|
return (SEOGetSource(rguidSourceType,(REFGUID) CStringGUID(rguidSourceBase,dwSourceIndex),ppSource));
|
|
}
|
|
|
|
|
|
STDMETHODIMP SEOGetSource(REFGUID rguidSourceType, LPCSTR pszDisplayName, IEventSource **ppSource) {
|
|
HRESULT hrRes;
|
|
CComPtr<IEnumVARIANT> pEnum;
|
|
CComVariant varValue;
|
|
CComQIPtr<IEventSource,&IID_IEventSource> pSource;
|
|
CComBSTR strDisplayName;
|
|
CComBSTR strDesiredName;
|
|
|
|
if (ppSource) {
|
|
*ppSource = NULL;
|
|
}
|
|
if (!ppSource || !pszDisplayName) {
|
|
hrRes = E_POINTER;
|
|
goto error;
|
|
}
|
|
hrRes = SEOGetSourcesEnum(rguidSourceType,&pEnum);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
if (!pEnum) {
|
|
hrRes = S_FALSE;
|
|
goto error;
|
|
}
|
|
strDesiredName = pszDisplayName;
|
|
while (1) {
|
|
varValue.Clear();
|
|
hrRes = pEnum->Next(1,&varValue,NULL);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
if (hrRes == S_FALSE) {
|
|
break;
|
|
}
|
|
hrRes = varValue.ChangeType(VT_UNKNOWN);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
pSource = varValue.punkVal;
|
|
if (!pSource) {
|
|
hrRes = E_NOINTERFACE;
|
|
goto error;
|
|
}
|
|
strDisplayName.Empty();
|
|
hrRes = pSource->get_DisplayName(&strDisplayName);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
if (wcscmp(strDisplayName,strDesiredName) == 0) {
|
|
*ppSource = pSource;
|
|
(*ppSource)->AddRef();
|
|
hrRes = S_OK;
|
|
break;
|
|
}
|
|
}
|
|
error:
|
|
return (hrRes);
|
|
}
|
|
|
|
|
|
class CValueBase {
|
|
public:
|
|
virtual BOOL Match(VARIANT *pValue) = 0;
|
|
};
|
|
|
|
|
|
static HRESULT SEOGetSource(REFGUID rguidSourceType, LPCSTR pszProperty, CValueBase *pValue, IEventSource **ppSource) {
|
|
HRESULT hrRes;
|
|
CComPtr<IEnumVARIANT> pEnum;
|
|
CComVariant varValue;
|
|
CComQIPtr<IEventSource,&IID_IEventSource> pSource;
|
|
CComVariant varProperty;
|
|
CComPtr<IEventPropertyBag> pProperties;
|
|
|
|
if (ppSource) {
|
|
*ppSource = NULL;
|
|
}
|
|
if (!ppSource || !pszProperty) {
|
|
hrRes = E_POINTER;
|
|
goto error;
|
|
}
|
|
hrRes = SEOGetSourcesEnum(rguidSourceType,&pEnum);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
if (!pEnum) {
|
|
hrRes = S_FALSE;
|
|
goto error;
|
|
}
|
|
varProperty = pszProperty;
|
|
while (1) {
|
|
varValue.Clear();
|
|
hrRes = pEnum->Next(1,&varValue,NULL);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
if (hrRes == S_FALSE) {
|
|
break;
|
|
}
|
|
hrRes = varValue.ChangeType(VT_UNKNOWN);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
pSource = varValue.punkVal;
|
|
if (!pSource) {
|
|
hrRes = E_NOINTERFACE;
|
|
goto error;
|
|
}
|
|
pProperties.Release();
|
|
hrRes = pSource->get_Properties(&pProperties);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
varValue.Clear();
|
|
hrRes = pProperties->Item(&varProperty,&varValue);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
if (hrRes == S_FALSE) {
|
|
continue;
|
|
}
|
|
if (pValue->Match(&varValue)) {
|
|
*ppSource = pSource;
|
|
(*ppSource)->AddRef();
|
|
hrRes = S_OK;
|
|
break;
|
|
}
|
|
}
|
|
error:
|
|
return (hrRes);
|
|
}
|
|
|
|
|
|
class CValueDWORD : public CValueBase {
|
|
public:
|
|
CValueDWORD(DWORD dwValue) {
|
|
m_dwValue = dwValue;
|
|
};
|
|
virtual BOOL Match(VARIANT *pValue) {
|
|
HRESULT hrRes = VariantChangeType(pValue,pValue,0,VT_I4);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
return (FALSE);
|
|
}
|
|
if ((DWORD) pValue->lVal != m_dwValue) {
|
|
return (FALSE);
|
|
}
|
|
return (TRUE);
|
|
};
|
|
private:
|
|
DWORD m_dwValue;
|
|
};
|
|
|
|
|
|
STDMETHODIMP SEOGetSource(REFGUID rguidSourceType, LPCSTR pszProperty, DWORD dwValue, IEventSource **ppSource) {
|
|
|
|
return (SEOGetSource(rguidSourceType,pszProperty,&CValueDWORD(dwValue),ppSource));
|
|
}
|
|
|
|
|
|
class CValueBSTR : public CValueBase {
|
|
public:
|
|
CValueBSTR(LPCWSTR pszValue) {
|
|
m_strValue = SysAllocString(pszValue);
|
|
};
|
|
CValueBSTR(LPCSTR pszValue) {
|
|
USES_CONVERSION;
|
|
m_strValue = SysAllocString(A2W(pszValue));
|
|
};
|
|
~CValueBSTR() {
|
|
SysFreeString(m_strValue);
|
|
};
|
|
virtual BOOL Match(VARIANT *pValue) {
|
|
HRESULT hrRes = VariantChangeType(pValue,pValue,0,VT_BSTR);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
return (FALSE);
|
|
}
|
|
if (wcscmp(pValue->bstrVal,m_strValue) != 0) {
|
|
return (FALSE);
|
|
}
|
|
return (TRUE);
|
|
};
|
|
private:
|
|
BSTR m_strValue;
|
|
};
|
|
|
|
|
|
STDMETHODIMP SEOGetSource(REFGUID rguidSourceType, LPCSTR pszProperty, LPCSTR pszValue, IEventSource **ppSource) {
|
|
|
|
return (SEOGetSource(rguidSourceType,pszProperty,&CValueBSTR(pszValue),ppSource));
|
|
}
|
|
|
|
|
|
static HRESULT SEOGetRouter(IEventSource *pSource, IEventRouter **ppRouter) {
|
|
HRESULT hrRes;
|
|
CComPtr<IEventBindingManager> pManager;
|
|
CComPtr<IEventRouter> pRouter;
|
|
|
|
if (ppRouter) {
|
|
*ppRouter = NULL;
|
|
}
|
|
if (!pSource || !ppRouter) {
|
|
hrRes = E_POINTER;
|
|
goto error;
|
|
}
|
|
hrRes = pSource->GetBindingManager(&pManager);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
hrRes = CoCreateInstance(CLSID_CEventRouter,NULL,CLSCTX_ALL,IID_IEventRouter,(LPVOID *) &pRouter);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
hrRes = pRouter->put_Database(pManager);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
*ppRouter = pRouter;
|
|
(*ppRouter)->AddRef();
|
|
error:
|
|
return (hrRes);
|
|
}
|
|
|
|
|
|
STDMETHODIMP SEOGetRouter(REFGUID rguidSourceType, REFGUID rguidSource, IEventRouter **ppRouter) {
|
|
HRESULT hrRes;
|
|
CComPtr<IEventSource> pSource;
|
|
|
|
if (ppRouter) {
|
|
*ppRouter = NULL;
|
|
}
|
|
if (!ppRouter) {
|
|
hrRes = E_POINTER;
|
|
goto error;
|
|
}
|
|
hrRes = SEOGetSource(rguidSourceType,rguidSource,&pSource);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
if (!pSource) {
|
|
hrRes = S_FALSE;
|
|
goto error;
|
|
}
|
|
hrRes = SEOGetRouter(pSource,ppRouter);
|
|
error:
|
|
return (hrRes);
|
|
}
|
|
|
|
|
|
STDMETHODIMP SEOGetRouter(REFGUID rguidSourceType, REFGUID rguidSourceBase, DWORD dwSourceIndex, IEventRouter **ppRouter) {
|
|
|
|
return (SEOGetRouter(rguidSourceType,(REFGUID) CStringGUID(rguidSourceBase,dwSourceIndex),ppRouter));
|
|
}
|
|
|
|
|
|
STDMETHODIMP SEOGetRouter(REFGUID rguidSourceType, LPCSTR pszDisplayName, IEventRouter **ppRouter) {
|
|
HRESULT hrRes;
|
|
CComPtr<IEventSource> pSource;
|
|
|
|
if (ppRouter) {
|
|
*ppRouter = NULL;
|
|
}
|
|
if (!ppRouter) {
|
|
hrRes = E_POINTER;
|
|
goto error;
|
|
}
|
|
hrRes = SEOGetSource(rguidSourceType,pszDisplayName,&pSource);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
if (!pSource) {
|
|
hrRes = S_FALSE;
|
|
goto error;
|
|
}
|
|
hrRes = SEOGetRouter(pSource,ppRouter);
|
|
error:
|
|
return (hrRes);
|
|
}
|
|
|
|
|
|
STDMETHODIMP SEOGetRouter(REFGUID rguidSourceType, LPCSTR pszProperty, DWORD dwValue, IEventRouter **ppRouter) {
|
|
HRESULT hrRes;
|
|
CComPtr<IEventSource> pSource;
|
|
|
|
if (ppRouter) {
|
|
*ppRouter = NULL;
|
|
}
|
|
if (!ppRouter) {
|
|
hrRes = E_POINTER;
|
|
goto error;
|
|
}
|
|
hrRes = SEOGetSource(rguidSourceType,pszProperty,dwValue,&pSource);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
if (!pSource) {
|
|
hrRes = S_FALSE;
|
|
goto error;
|
|
}
|
|
hrRes = SEOGetRouter(pSource,ppRouter);
|
|
error:
|
|
return (hrRes);
|
|
}
|
|
|
|
|
|
STDMETHODIMP SEOGetRouter(REFGUID rguidSourceType, LPCSTR pszProperty, LPCSTR pszValue, IEventRouter **ppRouter) {
|
|
HRESULT hrRes;
|
|
CComPtr<IEventSource> pSource;
|
|
|
|
if (ppRouter) {
|
|
*ppRouter = NULL;
|
|
}
|
|
if (!ppRouter) {
|
|
hrRes = E_POINTER;
|
|
goto error;
|
|
}
|
|
hrRes = SEOGetSource(rguidSourceType,pszProperty,pszValue,&pSource);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
goto error;
|
|
}
|
|
if (!pSource) {
|
|
hrRes = S_FALSE;
|
|
goto error;
|
|
}
|
|
hrRes = SEOGetRouter(pSource,ppRouter);
|
|
error:
|
|
return (hrRes);
|
|
}
|
|
|
|
|
|
#include <initguid.h>
|
|
|
|
// This CLSID must match the one in SEO.DLL.
|
|
// {A4BE1350-1051-11d1-AA1E-00AA006BC80B}
|
|
DEFINE_GUID(CLSID_CEventServiceObject,
|
|
0xa4be1350, 0x1051, 0x11d1, 0xaa, 0x1e, 0x0, 0xaa, 0x0, 0x6b, 0xc8, 0xb);
|
|
|
|
|
|
STDMETHODIMP SEOGetServiceHandle(IUnknown **ppUnkHandle) {
|
|
|
|
return (CoCreateInstance(CLSID_CEventServiceObject,
|
|
NULL,
|
|
CLSCTX_ALL,
|
|
IID_IUnknown,
|
|
(LPVOID *) ppUnkHandle));
|
|
}
|
|
|
|
|
|
STDMETHODIMP SEOCreateObject(VARIANT *pvarClass,
|
|
IEventBinding *pBinding,
|
|
IUnknown *pInitProperties,
|
|
REFIID iidDesired,
|
|
IUnknown **ppUnkObject) {
|
|
|
|
return (SEOCreateObjectEx(pvarClass,pBinding,pInitProperties,iidDesired,NULL,ppUnkObject));
|
|
}
|
|
|
|
|
|
STDMETHODIMP SEOCreateObjectEx(VARIANT *pvarClass,
|
|
IEventBinding *pBinding,
|
|
IUnknown *pInitProperties,
|
|
REFIID iidDesired,
|
|
IUnknown *pUnkCreateOptions,
|
|
IUnknown **ppUnkObject) {
|
|
HRESULT hrRes;
|
|
CStringGUID objGuid;
|
|
BSTR strClass;
|
|
CComQIPtr<IEventCreateOptions,&IID_IEventCreateOptions> pOpt;
|
|
|
|
if (ppUnkObject) {
|
|
*ppUnkObject = NULL;
|
|
}
|
|
if (!pvarClass || !ppUnkObject) {
|
|
return (E_POINTER);
|
|
}
|
|
if (pUnkCreateOptions) {
|
|
pOpt = pUnkCreateOptions;
|
|
}
|
|
if (pvarClass->vt == VT_BSTR) {
|
|
strClass = pvarClass->bstrVal;
|
|
} else if (pvarClass->vt == (VT_BYREF|VT_BSTR)) {
|
|
strClass = *pvarClass->pbstrVal;
|
|
} else {
|
|
hrRes = VariantChangeType(pvarClass,pvarClass,0,VT_BSTR);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
return (hrRes);
|
|
}
|
|
strClass = pvarClass->bstrVal;
|
|
}
|
|
objGuid.CalcFromProgID(strClass);
|
|
if (!objGuid) {
|
|
objGuid = strClass;
|
|
if (!objGuid) {
|
|
CComPtr<IBindCtx> pBindCtx;
|
|
CComPtr<IMoniker> pMoniker;
|
|
DWORD dwEaten;
|
|
|
|
if (!pOpt || ((hrRes=pOpt->CreateBindCtx(0,&pBindCtx))==E_NOTIMPL)) {
|
|
hrRes = CreateBindCtx(0,&pBindCtx);
|
|
}
|
|
_ASSERTE(SUCCEEDED(hrRes));
|
|
if (SUCCEEDED(hrRes)) {
|
|
if (!pOpt || ((hrRes=pOpt->MkParseDisplayName(pBindCtx,
|
|
strClass,
|
|
&dwEaten,
|
|
&pMoniker))==E_NOTIMPL)) {
|
|
hrRes = MkParseDisplayName(pBindCtx,strClass,&dwEaten,&pMoniker);
|
|
}
|
|
}
|
|
_ASSERTE(!SUCCEEDED(hrRes)||pMoniker);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
#if 0 // tbd - We try both the normal and the Ex versions of MkParseDisplayName. Just use one.
|
|
pBindCtx.Release();
|
|
hrRes = CreateBindCtx(0,&pBindCtx);
|
|
_ASSERTE(SUCCEEDED(hrRes));
|
|
if (!SUCCEEDED(hrRes)) {
|
|
return (hrRes);
|
|
}
|
|
if (!pOpt||((hrRes=pOpt->MkParseDisplayNameEx(pBindCtx,
|
|
strClass,
|
|
&dwEaten,
|
|
&pMoniker))==E_NOTIMPL) {
|
|
hrRes = MkParseDisplayNameEx(pBindCtx,strClass,&dwEaten,&pMoniker);
|
|
}
|
|
_ASSERTE(!SUCCEEDED(hrRes)||pMoniker);
|
|
if (!SUCCEEDED(hrRes)) {
|
|
return (hrRes);
|
|
}
|
|
#else
|
|
return (hrRes);
|
|
#endif
|
|
}
|
|
pBindCtx.Release();
|
|
if (!pOpt || ((hrRes=pOpt->CreateBindCtx(0,&pBindCtx))==E_NOTIMPL)) {
|
|
hrRes = CreateBindCtx(0,&pBindCtx);
|
|
}
|
|
if (!SUCCEEDED(hrRes)) {
|
|
_ASSERTE(FALSE);
|
|
return (hrRes);
|
|
}
|
|
if (!pOpt || ((hrRes=pOpt->BindToObject(pMoniker,
|
|
pBindCtx,
|
|
NULL,
|
|
iidDesired,
|
|
(LPVOID *) ppUnkObject))==E_NOTIMPL)) {
|
|
hrRes = pMoniker->BindToObject(pBindCtx,NULL,iidDesired,(LPVOID *) ppUnkObject);
|
|
}
|
|
_ASSERTE(!SUCCEEDED(hrRes)||!*ppUnkObject);
|
|
// Fall through
|
|
}
|
|
}
|
|
// At this point, objGuid will only be TRUE if either CalcFromProgID or
|
|
// operator =(LPCOLESTR) succeeded. If both of these failed, then it will
|
|
// be FALSE and we will have attempted to interpret the SinkClass as a
|
|
// moniker.
|
|
if (!!objGuid) { // Use !! to hack-past ambiguous-conversion issues...
|
|
if (!pOpt || ((hrRes=pOpt->CoCreateInstance(objGuid,
|
|
NULL,
|
|
CLSCTX_ALL,
|
|
iidDesired,
|
|
(LPVOID *) ppUnkObject))==E_NOTIMPL)) {
|
|
hrRes = CoCreateInstance(objGuid,NULL,CLSCTX_ALL,iidDesired,(LPVOID *) ppUnkObject);
|
|
}
|
|
_ASSERTE(!SUCCEEDED(hrRes)||*ppUnkObject);
|
|
}
|
|
// At this point, hrRes has the result either from pMoniker->BindToObject or
|
|
// CoCreateInstance.
|
|
if (SUCCEEDED(hrRes)) {
|
|
if (!pOpt || ((hrRes=pOpt->Init(iidDesired,ppUnkObject,pBinding,pInitProperties))==E_NOTIMPL)) {
|
|
hrRes = S_OK;
|
|
CComQIPtr<IEventPersistBinding,&IID_IEventPersistBinding> pBindingInit;
|
|
|
|
if (pBinding) {
|
|
pBindingInit = *ppUnkObject;
|
|
}
|
|
if (pBindingInit) {
|
|
HRESULT hrResTmp;
|
|
|
|
hrResTmp = pBindingInit->Load(pBinding);
|
|
_ASSERTE(SUCCEEDED(hrResTmp));
|
|
} else {
|
|
CComQIPtr<IPersistPropertyBag,&IID_IPersistPropertyBag> pInit;
|
|
|
|
if (pInitProperties) {
|
|
pInit = *ppUnkObject;
|
|
}
|
|
if (pInit) {
|
|
HRESULT hrResTmp;
|
|
CComQIPtr<IPropertyBag,&IID_IPropertyBag> pProps;
|
|
|
|
pProps = pInitProperties;
|
|
_ASSERTE(pProps);
|
|
if (pProps) {
|
|
hrResTmp = pInit->InitNew();
|
|
_ASSERTE(SUCCEEDED(hrResTmp));
|
|
if (SUCCEEDED(hrResTmp)) {
|
|
hrResTmp = pInit->Load(pProps,NULL); // tbd - pass an IErrorLog object
|
|
_ASSERTE(SUCCEEDED(hrResTmp));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (!SUCCEEDED(hrRes)) {
|
|
(*ppUnkObject)->Release();
|
|
*ppUnkObject = NULL;
|
|
}
|
|
}
|
|
return (hrRes);
|
|
}
|