332 lines
9.3 KiB
C++
332 lines
9.3 KiB
C++
/*++
|
|
|
|
Copyright (c) 1996 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
seolib.h
|
|
|
|
Abstract:
|
|
|
|
This module contains definitions for useful utility
|
|
classes and functions for the Server Extentions Object
|
|
system.
|
|
|
|
Author:
|
|
|
|
Don Dumitru (dondu@microsoft.com)
|
|
|
|
Revision History:
|
|
|
|
dondu 05/20/97 Created.
|
|
dondu 07/03/97 Rewrite.
|
|
|
|
--*/
|
|
|
|
#include "rwnew.h"
|
|
#include "seoexports.h"
|
|
|
|
/*
|
|
|
|
See the ddrop2 test program for an example of how to
|
|
use the CEventBaseDispatcher class.
|
|
|
|
*/
|
|
|
|
|
|
template<class T, DWORD dwGrowBy=4>
|
|
class CSEOGrowableList {
|
|
public:
|
|
|
|
CSEOGrowableList() {
|
|
m_dwCount = 0;
|
|
m_dwAlloc = 0;
|
|
m_apData = NULL;
|
|
};
|
|
|
|
~CSEOGrowableList() {
|
|
RemoveAll();
|
|
};
|
|
|
|
DWORD Count() {
|
|
return (m_dwCount);
|
|
};
|
|
|
|
T* Index(DWORD dwIdx) {
|
|
T *pRet = NULL;
|
|
|
|
m_slData.ShareLock();
|
|
|
|
if (dwIdx<m_dwCount) {
|
|
pRet = m_apData[dwIdx];
|
|
}
|
|
|
|
m_slData.ShareUnlock();
|
|
|
|
return pRet;
|
|
};
|
|
|
|
T& operator[](DWORD dwIdx) {
|
|
T *pRet = Index(dwIdx);
|
|
_ASSERTE(pRet);
|
|
return *pRet;
|
|
};
|
|
|
|
virtual int Compare(T* p1, T* p2) {
|
|
// don't sort by default
|
|
return (1);
|
|
};
|
|
|
|
HRESULT Add(T* pNewData) {
|
|
|
|
if (!pNewData) {
|
|
return (E_POINTER);
|
|
}
|
|
|
|
m_slData.ExclusiveLock();
|
|
|
|
// Check if we have space for the new item and allocate more memory if necessary
|
|
if (m_dwCount == m_dwAlloc) {
|
|
|
|
// Allocate
|
|
T** pNewData = (T**)realloc(m_apData,sizeof(T*)*(m_dwAlloc+dwGrowBy));
|
|
if (!pNewData) {
|
|
m_slData.ExclusiveUnlock();
|
|
return(E_OUTOFMEMORY);
|
|
}
|
|
m_apData = pNewData;
|
|
m_dwAlloc += dwGrowBy;
|
|
|
|
// Clear new memory
|
|
memset(m_apData+m_dwCount,0,sizeof(T*)*dwGrowBy);
|
|
}
|
|
|
|
// Now find the position for the new item - we loop from the
|
|
// end to the start so that we can minimize the cost inserting
|
|
// unsorted items
|
|
for (DWORD dwIdx=m_dwCount;dwIdx>0;dwIdx--) {
|
|
int iCmpRes = Compare(pNewData,m_apData[dwIdx-1]);
|
|
if (iCmpRes < 0) {
|
|
continue;
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Now move the items past the new item and insert it
|
|
memmove(m_apData+dwIdx+1,m_apData+dwIdx,sizeof(T*)*(m_dwCount-dwIdx));
|
|
m_apData[dwIdx] = pNewData;
|
|
m_dwCount++;
|
|
|
|
m_slData.ExclusiveUnlock();
|
|
|
|
return (S_OK);
|
|
};
|
|
|
|
void Remove(DWORD dwIdx, T **ppT) {
|
|
if (!ppT) {
|
|
_ASSERTE(FALSE);
|
|
return;
|
|
}
|
|
|
|
m_slData.ExclusiveLock();
|
|
|
|
if (dwIdx >= m_dwCount) {
|
|
_ASSERTE(FALSE);
|
|
*ppT = NULL;
|
|
return;
|
|
}
|
|
*ppT = m_apData[dwIdx];
|
|
memmove(&m_apData[dwIdx],&m_apData[dwIdx+1],sizeof(m_apData[0])*(m_dwCount-dwIdx-1));
|
|
m_dwCount--;
|
|
|
|
m_slData.ExclusiveUnlock();
|
|
};
|
|
|
|
void Remove(DWORD dwIdx) {
|
|
T *pT;
|
|
Remove(dwIdx,&pT);
|
|
delete pT;
|
|
};
|
|
|
|
void RemoveAll() {
|
|
|
|
m_slData.ExclusiveLock();
|
|
|
|
if (m_apData) {
|
|
for (DWORD dwIdx=0;dwIdx<m_dwCount;dwIdx++) {
|
|
delete m_apData[dwIdx];
|
|
}
|
|
free(m_apData);
|
|
}
|
|
m_dwCount = 0;
|
|
m_dwAlloc = 0;
|
|
m_apData = NULL;
|
|
|
|
m_slData.ExclusiveUnlock();
|
|
}
|
|
|
|
protected:
|
|
DWORD m_dwCount;
|
|
DWORD m_dwAlloc;
|
|
T** m_apData;
|
|
CShareLockNH m_slData;
|
|
};
|
|
|
|
|
|
class CEventBaseDispatcher : public IEventDispatcher {
|
|
public:
|
|
|
|
CEventBaseDispatcher();
|
|
|
|
virtual ~CEventBaseDispatcher();
|
|
|
|
class CBinding {
|
|
public:
|
|
CBinding();
|
|
virtual ~CBinding();
|
|
virtual HRESULT Init(IEventBinding *piBinding);
|
|
virtual int Compare(const CBinding& b) const;
|
|
static HRESULT InitRuleEngine(IEventBinding *piBinding, REFIID iidDesired, IUnknown **ppUnkRuleEngine);
|
|
virtual HRESULT InitRuleEngine();
|
|
public:
|
|
BOOL m_bIsValid;
|
|
CComPtr<IEventBinding> m_piBinding;
|
|
BOOL m_bExclusive;
|
|
DWORD m_dwPriority;
|
|
};
|
|
|
|
class CBindingList : public CSEOGrowableList<CBinding> {
|
|
public:
|
|
virtual int Compare(CBinding* p1, CBinding* p2);
|
|
};
|
|
|
|
class CParams {
|
|
public:
|
|
virtual HRESULT CheckRule(CBinding& bBinding);
|
|
// returns S_OK if the object should be called
|
|
// returns S_FALSE if the object should not be called
|
|
// any other return value causes the object to not be called
|
|
virtual HRESULT CallObject(IEventManager *piManager, CBinding& bBinding);
|
|
// returns S_OK if the object was called
|
|
// returns S_FALSE if the object was called and if no other objects should be called
|
|
// returns FAILED() if the object was not called
|
|
virtual HRESULT CallObject(CBinding& bBinding, IUnknown *pUnkSink);
|
|
// returns S_OK if the object was called
|
|
// returns S_FALSE if the object was called and if no other objects should be called
|
|
// returns FAILED() if the object was not called
|
|
virtual HRESULT Abort();
|
|
// returns S_OK if processing should end
|
|
// returns S_FALSE if processing should continue
|
|
// any other return value causes processing to continue
|
|
};
|
|
|
|
virtual HRESULT Dispatcher(REFGUID rguidEventType, CParams *pParams);
|
|
// returns S_OK if at least one sink was called
|
|
// returns S_FALSE if no sinks were called
|
|
// returns FAILED() if some super-catastrophic error happened
|
|
|
|
// IEventDispatcher
|
|
public:
|
|
HRESULT STDMETHODCALLTYPE SetContext(REFGUID rguidEventType,
|
|
IEventRouter *piRouter,
|
|
IEventBindings *piBindings);
|
|
|
|
public:
|
|
|
|
class CETData : public CBindingList {
|
|
public:
|
|
CETData();
|
|
virtual ~CETData();
|
|
public:
|
|
GUID m_guidEventType;
|
|
};
|
|
|
|
class CETDataList : public CSEOGrowableList<CETData> {
|
|
public:
|
|
CETData* Find(REFGUID guidEventType);
|
|
};
|
|
|
|
virtual HRESULT AllocBinding(REFGUID rguidEventType,
|
|
IEventBinding *pBinding,
|
|
CBinding **ppNewBinding);
|
|
virtual HRESULT AllocETData(REFGUID rguidEventType,
|
|
IEventBindings *piBindings,
|
|
CETData **ppNewETData);
|
|
|
|
CComPtr<IEventRouter> m_piRouter;
|
|
CETDataList m_Data;
|
|
CComPtr<IEventManager> m_piEventManager;
|
|
};
|
|
|
|
class CEventCreateOptionsBase : public IEventCreateOptions {
|
|
HRESULT STDMETHODCALLTYPE QueryInterface (REFIID riidDesired, LPVOID *ppvResult) {
|
|
|
|
if (ppvResult) {
|
|
*ppvResult = NULL;
|
|
}
|
|
if (!ppvResult) {
|
|
return (E_NOTIMPL);
|
|
}
|
|
if (riidDesired == IID_IUnknown) {
|
|
*ppvResult = (IUnknown *) this;
|
|
} else if (riidDesired == IID_IDispatch) {
|
|
*ppvResult = (IDispatch *) this;
|
|
} else if (riidDesired == IID_IEventCreateOptions) {
|
|
*ppvResult = (IEventCreateOptions *) this;
|
|
}
|
|
return ((*ppvResult)?S_OK:E_NOINTERFACE);
|
|
};
|
|
ULONG STDMETHODCALLTYPE AddRef() {
|
|
return (2);
|
|
};
|
|
ULONG STDMETHODCALLTYPE Release() {
|
|
return (1);
|
|
};
|
|
HRESULT STDMETHODCALLTYPE GetTypeInfoCount(unsigned int *) {
|
|
return (E_NOTIMPL);
|
|
};
|
|
HRESULT STDMETHODCALLTYPE GetTypeInfo(unsigned int, LCID, ITypeInfo **) {
|
|
return (E_NOTIMPL);
|
|
};
|
|
HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID, LPOLESTR *, unsigned int, LCID, DISPID *) {
|
|
return (E_NOTIMPL);
|
|
};
|
|
HRESULT STDMETHODCALLTYPE Invoke(DISPID, REFIID, LCID, WORD, DISPPARAMS *, VARIANT *, EXCEPINFO *, unsigned int *) {
|
|
return (E_NOTIMPL);
|
|
};
|
|
HRESULT STDMETHODCALLTYPE CreateBindCtx(DWORD, IBindCtx **) {
|
|
return (E_NOTIMPL);
|
|
};
|
|
HRESULT STDMETHODCALLTYPE MkParseDisplayName(IBindCtx *, LPCOLESTR, ULONG *, IMoniker **) {
|
|
return (E_NOTIMPL);
|
|
};
|
|
HRESULT STDMETHODCALLTYPE BindToObject(IMoniker *, IBindCtx *, IMoniker *, REFIID, LPVOID *) {
|
|
return (E_NOTIMPL);
|
|
};
|
|
HRESULT STDMETHODCALLTYPE CoCreateInstance(REFCLSID, IUnknown *, DWORD, REFIID, LPVOID *) {
|
|
return (E_NOTIMPL);
|
|
};
|
|
HRESULT STDMETHODCALLTYPE Init(REFIID riidDesired, IUnknown **ppObject, IEventBinding *pBinding, IUnknown *pInitProps) {
|
|
return (E_NOTIMPL);
|
|
};
|
|
};
|
|
|
|
|
|
// All these functions return S_OK if they succeed, and S_FALSE if the source type or source is
|
|
// not present. They return FAILED() on various catastrophic errors.
|
|
STDMETHODIMP SEOGetSource(REFGUID rguidSourceType, REFGUID rguidSource, IEventSource **ppSource);
|
|
STDMETHODIMP SEOGetSource(REFGUID rguidSourceType, REFGUID rguidSourceBase, DWORD dwSourceIndex, IEventSource **ppSource);
|
|
STDMETHODIMP SEOGetSource(REFGUID rguidSourceType, LPCSTR pszDisplayName, IEventSource **ppSource);
|
|
STDMETHODIMP SEOGetSource(REFGUID rguidSourceType, LPCSTR pszProperty, DWORD dwValue, IEventSource **ppSource);
|
|
STDMETHODIMP SEOGetSource(REFGUID rguidSourceType, LPCSTR pszProperty, LPCSTR pszValue, IEventSource **ppSource);
|
|
STDMETHODIMP SEOGetRouter(REFGUID rguidSourceType, REFGUID rguidSource, IEventRouter **ppRouter);
|
|
STDMETHODIMP SEOGetRouter(REFGUID rguidSourceType, REFGUID rguidSourceBase, DWORD dwSourceIndex, IEventRouter **ppRouter);
|
|
STDMETHODIMP SEOGetRouter(REFGUID rguidSourceType, LPCSTR pszDisplayName, IEventRouter **ppRouter);
|
|
STDMETHODIMP SEOGetRouter(REFGUID rguidSourceType, LPCSTR pszProperty, DWORD dwValue, IEventRouter **ppRouter);
|
|
STDMETHODIMP SEOGetRouter(REFGUID rguidSourceType, LPCSTR pszProperty, LPCSTR pszValue, IEventRouter **ppRouter);
|
|
|
|
STDMETHODIMP SEOGetServiceHandle(IUnknown **ppUnkHandle);
|
|
|
|
STDMETHODIMP SEOCreateObject(VARIANT *pvarClass, IEventBinding *pBinding, IUnknown *pInitProperties, REFIID iidDesired, IUnknown **ppUnkObject);
|
|
STDMETHODIMP SEOCreateObjectEx(VARIANT *pvarClass, IEventBinding *pBinding, IUnknown *pInitProperties, REFIID iidDesired, IUnknown *pUnkCreateOptions, IUnknown **ppUnkObject);
|