Leaked source code of windows server 2003
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.
 
 
 
 
 
 

540 lines
17 KiB

/*++
Copyright (c) 1997 Microsoft Corporation
Module Name:
metabag.h
Abstract:
This module contains the definition for the
ISEODictionary object on the Metabase.
Author:
Andy Jacobs ([email protected])
Revision History:
andyj 03/11/97 created
--*/
// METABAG.h : Declaration of the CSEOMetaDictionary
//#define TIMEOUT 15000
#define ALWAYS_LOCK 0
#define SafeStrlen(x) ((x)?wcslen(x):0)
class CGlobalInterfaceImpl {
public:
void Init() {
m_pUnkObject = NULL;
m_piGIT = NULL;
};
void Term() {
if (m_pUnkObject) {
m_pUnkObject->Release();
m_pUnkObject = NULL;
}
if (m_piGIT) {
HRESULT hrRes = m_piGIT->RevokeInterfaceFromGlobal(m_dwCookie);
_ASSERTE(SUCCEEDED(hrRes));
m_piGIT->Release();
m_piGIT = NULL;
}
};
bool operator!() {
return (!m_pUnkObject&&!m_piGIT);
};
operator bool() {
return (m_pUnkObject||m_piGIT);
};
protected:
HRESULT Load(REFCLSID rclsid, REFIID riid) {
return (LoadImpl(rclsid,riid,NULL));
};
HRESULT Load(REFIID riid, IUnknown *pUnkObject) {
if (!pUnkObject) {
return (E_POINTER);
}
return (LoadImpl(GUID_NULL,riid,pUnkObject));
};
HRESULT GetInterface(REFIID riid, IUnknown **ppUnkObject) {
if (ppUnkObject) {
*ppUnkObject = NULL;
}
if (!ppUnkObject) {
return (E_POINTER);
}
_ASSERTE(m_pUnkObject||m_piGIT); // Not loaded.
_ASSERTE(!m_pUnkObject||!m_piGIT); // Internal error.
if (m_pUnkObject) {
*ppUnkObject = m_pUnkObject;
(*ppUnkObject)->AddRef();
return (S_OK);
}
if (m_piGIT) {
return (m_piGIT->GetInterfaceFromGlobal(m_dwCookie,riid,(LPVOID *) ppUnkObject));
}
return (E_FAIL);
};
HRESULT GetInterfaceQI(REFIID riid, REFIID riidDesired, LPVOID *ppvObject) {
CComPtr<IUnknown> pUnkObject;
HRESULT hrRes;
if (ppvObject) {
*ppvObject = NULL;
}
if (!ppvObject) {
return (E_POINTER);
}
hrRes = GetInterface(riid,&pUnkObject);
if (!SUCCEEDED(hrRes)) {
return (hrRes);
}
return (pUnkObject->QueryInterface(riidDesired,ppvObject));
};
private:
HRESULT LoadImpl(REFCLSID rclsid, REFIID riid, IUnknown *pUnkObject) {
HRESULT hrRes;
hrRes = CoCreateInstance(CLSID_StdGlobalInterfaceTable,
NULL,
CLSCTX_ALL,
IID_IGlobalInterfaceTable,
(LPVOID *) &m_piGIT);
_ASSERTE(SUCCEEDED(hrRes)); // Should always succeed on NT4 SP3 and later.
if (!SUCCEEDED(hrRes) && (hrRes != REGDB_E_CLASSNOTREG)) {
return (hrRes);
}
if (!pUnkObject) {
hrRes = CoCreateInstance(rclsid,NULL,CLSCTX_ALL,riid,(LPVOID *) &m_pUnkObject);
if (!SUCCEEDED(hrRes)) {
if (m_piGIT) {
m_piGIT->Release();
m_piGIT = NULL;
}
return (hrRes);
}
} else {
m_pUnkObject = pUnkObject;
m_pUnkObject->AddRef();
}
if (m_piGIT) {
hrRes = m_piGIT->RegisterInterfaceInGlobal(m_pUnkObject,riid,&m_dwCookie);
m_pUnkObject->Release();
m_pUnkObject = NULL;
if (!SUCCEEDED(hrRes)) {
m_piGIT->Release();
m_piGIT = NULL;
return (hrRes);
}
}
return (S_OK);
};
IUnknown *m_pUnkObject;
DWORD m_dwCookie;
IGlobalInterfaceTable *m_piGIT;
};
template<class T, const IID *pIID>
class CGlobalInterface : public CGlobalInterfaceImpl {
public:
HRESULT Load(REFCLSID rclsid) {
return (CGlobalInterfaceImpl::Load(rclsid,*pIID));
};
HRESULT Load(T *pT) {
if (!pT) {
return (E_POINTER);
}
return (CGlobalInterfaceImpl::Load(*pIID,(IUnknown *) pT));
};
HRESULT GetInterface(T **ppT) {
return (CGlobalInterfaceImpl::GetInterface(*pIID,(IUnknown **) ppT));
};
HRESULT GetInterfaceQI(REFIID riidDesired,LPVOID *ppv) {
return (CGlobalInterfaceImpl::GetInterfaceQI(*pIID,riidDesired,ppv));
};
};
struct IMSAdminBaseW;
class CSEOMetabaseLock;
enum LockStatus {Closed, Read, Write, Error, DontCare, InitError};
class CSEOMetabase { // Wrapper for Metabase funcitons
public:
CSEOMetabase() {
m_mhHandle = METADATA_MASTER_ROOT_HANDLE;
m_eStatus = Closed; // Closed until we delegate
m_pszPath = (LPWSTR) MyMalloc(sizeof(*m_pszPath));
m_pmbDefer = NULL;
if(!m_pszPath) {
m_hrInitRes = E_OUTOFMEMORY;
goto Exit;
}
*m_pszPath = 0;
m_hrInitRes = InitializeMetabase();
Exit:
if(!SUCCEEDED(m_hrInitRes)) {
m_eStatus = InitError;
}
};
~CSEOMetabase() {
if(!m_pmbDefer) SetStatus(Closed); // Close self on cleanup
if (SUCCEEDED(m_hrInitRes)) {
TerminateMetabase();
}
if(m_pszPath) MyFree(m_pszPath);
m_pszPath = NULL;
m_pmbDefer = NULL;
};
void operator=(const CSEOMetabase &mbMetabase) {
SetPath(mbMetabase.m_pszPath);
};
HRESULT InitShare(CSEOMetabase *pmbOther, LPCWSTR pszPath, LPUNKNOWN punkOwner = NULL) {
LPWSTR pszTmp = NULL;
m_punkDeferOwner = punkOwner;
m_pmbDefer = pmbOther;
if (pszPath) {
pszTmp = (LPWSTR) MyMalloc(sizeof(*pszPath)*(SafeStrlen(pszPath) + 1));
if(!pszTmp) return E_OUTOFMEMORY;
wcscpy(pszTmp, pszPath);
}
if(m_pszPath) MyFree(m_pszPath);
m_pszPath = pszTmp;
return S_OK;
};
LockStatus Status() const {
return (m_pmbDefer ? m_pmbDefer->Status() : m_eStatus);
};
HRESULT SetStatus(LockStatus ls, long lTimeout=15000);
HRESULT EnumKeys(LPCWSTR pszPath, DWORD dwNum, LPWSTR pszName);
HRESULT AddKey(LPCWSTR pszPathBuf);
HRESULT DeleteKey(LPCWSTR pszPathBuf);
HRESULT GetData(LPCWSTR path, DWORD &dwType, DWORD &dwLen, PBYTE pbData);
HRESULT SetData(LPCWSTR path, DWORD dwType, DWORD dwLen, PBYTE pbData);
HRESULT SetDWord(LPCWSTR path, DWORD dwData) {
return SetData(path, DWORD_METADATA, sizeof(DWORD), (PBYTE) &dwData);
};
HRESULT SetString(LPCWSTR path, LPCWSTR psData, int iLen = -1) {
if(iLen < 0) iLen = sizeof(*psData) * (SafeStrlen(psData) + 1);
return SetData(path, STRING_METADATA, iLen, (PBYTE) psData);
};
METADATA_HANDLE GetHandle() {
if(m_pmbDefer) {
return m_pmbDefer->GetHandle();
} else {
return m_mhHandle; // Not defering, so use our handle
}
};
int GetPathLength() {
int iRet = SafeStrlen(m_pszPath);
if(m_pmbDefer) {
iRet += (3 + m_pmbDefer->GetPathLength());
}
return iRet;
};
LPCWSTR GetRelPath(LPWSTR psRet) { // Get the Relative Path from the original deferer
if(!psRet) return psRet;
if(m_pmbDefer) {
LPWSTR psBuf = (LPWSTR) alloca(sizeof(*psBuf)*(m_pmbDefer->GetPathLength() + 1));
m_pmbDefer->GetRelPath(psBuf);
ConcatinatePaths(psRet,psBuf,m_pszPath);
} else {
*psRet = 0; // Empty string
}
return psRet;
};
LPCWSTR GetPath(LPWSTR psRet) {
if(!psRet) return psRet;
if(m_pmbDefer) {
LPWSTR psBuf = (LPWSTR) alloca(sizeof(*psBuf)*(m_pmbDefer->GetPathLength() + 1));
m_pmbDefer->GetPath(psBuf);
ConcatinatePaths(psRet, psBuf,m_pszPath);
} else {
wcscpy(psRet,m_pszPath);
}
return psRet;
};
void AppendPath(LPCWSTR pszPathParam) {
LPWSTR pszPath = (LPWSTR) alloca(sizeof(*pszPath)*(SafeStrlen(m_pszPath)+SafeStrlen(pszPathParam)+3));
ConcatinatePaths(pszPath,m_pszPath,pszPathParam);
SetPath(pszPath);
};
void SetPath(LPCWSTR pszPath) {
LPWSTR pszTmp = NULL;
SetStatus(Closed); // Make sure we're closed
if (pszPath) {
pszTmp = (LPWSTR) MyMalloc((sizeof(*pszTmp))*(SafeStrlen(pszPath)+3));
if(!pszTmp)
return;
ConcatinatePaths(pszTmp,pszPath,NULL);
}
if(m_pszPath) MyFree(m_pszPath);
m_pszPath = pszTmp;
};
static HRESULT InitializeMetabase();
static HRESULT TerminateMetabase();
protected:
void ConcatinatePaths(LPWSTR pszResult, LPCWSTR pszP1, LPCWSTR pszP2);
HRESULT OpenPath(CSEOMetabaseLock &mbLocker, LPCWSTR pszPath,
LPWSTR pszPathBuf, DWORD &dwId, LockStatus lsOpen = Read);
private:
LPWSTR m_pszPath;
METADATA_HANDLE m_mhHandle;
LockStatus m_eStatus;
CSEOMetabase *m_pmbDefer; // Defer to this object if set
CComPtr<IUnknown> m_punkDeferOwner; // Keep reference count
HRESULT m_hrInitRes;
static CGlobalInterface<IMSAdminBaseW,&IID_IMSAdminBase_W> m_MetabaseHandle;
static CGlobalInterface<IMSAdminBaseW,&IID_IMSAdminBase_W> m_MetabaseChangeHandle;
static int m_iCount; // Number of calls to InitializeMetabase()
};
class CSEOMetabaseLock {
public:
CSEOMetabaseLock(CSEOMetabase *piObject, LockStatus ls = DontCare) {
m_bChanged = FALSE;
m_piObject = piObject;
if(DontCare != ls) SetStatus(ls);
};
~CSEOMetabaseLock() {
if(m_bChanged) SetStatus(m_lsPrevious);
};
HRESULT SetStatus(LockStatus ls) {
if(!m_piObject) return E_FAIL; // Not initialized
m_lsPrevious = m_piObject->Status();
HRESULT hRes = m_piObject->SetStatus(ls);
LockStatus lsNewStatus = m_piObject->Status();
if((lsNewStatus != m_lsPrevious) && (hRes != S_FALSE)) m_bChanged = TRUE;
if(lsNewStatus == Closed) m_bChanged = FALSE;
return hRes;
};
private:
CSEOMetabase *m_piObject;
BOOL m_bChanged; // True if we are responsible for restoring in our destructor
LockStatus m_lsPrevious;
};
// The following macro may be inserted in a method to support
// reading/writing from just that method if handle not already opened.
// The object will take care of closing the handle if needed, etc.
#define METABASE_HELPER(x,y) CSEOMetabaseLock mbHelper(x, y)
/////////////////////////////////////////////////////////////////////////////
// CSEOMetaDictionary
class ATL_NO_VTABLE CSEOMetaDictionary :
public CComObjectRootEx<CComMultiThreadModelNoCS>,
public CComCoClass<CSEOMetaDictionary, &CLSID_CSEOMetaDictionary>,
public ISEOInitObject,
public IDispatchImpl<ISEODictionary, &IID_ISEODictionary, &LIBID_SEOLib>,
public IPropertyBag,
public IDispatchImpl<IEventPropertyBag, &IID_IEventPropertyBag, &LIBID_SEOLib>,
public IDispatchImpl<IEventLock, &IID_IEventLock, &LIBID_SEOLib>,
public IConnectionPointContainerImpl<CSEOMetaDictionary>,
// public IConnectionPointImpl<CSEOMetaDictionary, &IID_IEventNotifyBindingChange>
public CSEOConnectionPointImpl<CSEOMetaDictionary, &IID_IEventNotifyBindingChange>
{
friend class CSEOMetaDictionaryEnum; // Helper class
public:
HRESULT FinalConstruct();
void FinalRelease();
HRESULT OnChange(LPCWSTR *apszPath);
HRESULT GetVariantA(LPCSTR pszName, VARIANT *pvarResult, BOOL bCreate);
HRESULT GetVariantW(LPCWSTR pszName, VARIANT *pvarResult, BOOL bCreate);
DECLARE_PROTECT_FINAL_CONSTRUCT();
DECLARE_REGISTRY_RESOURCEID_EX(IDR_StdAfx,
L"SEOMetaDictionary Class",
L"SEO.SEOMetaDictionary.1",
L"SEO.SEOMetaDictionary");
BEGIN_COM_MAP(CSEOMetaDictionary)
COM_INTERFACE_ENTRY(ISEODictionary)
COM_INTERFACE_ENTRY(ISEOInitObject)
COM_INTERFACE_ENTRY_AGGREGATE(IID_IMarshal, m_pUnkMarshaler.p)
COM_INTERFACE_ENTRY(IPropertyBag)
COM_INTERFACE_ENTRY(IEventPropertyBag)
COM_INTERFACE_ENTRY_IID(IID_IDispatch, IEventPropertyBag)
COM_INTERFACE_ENTRY(IEventLock)
COM_INTERFACE_ENTRY_IMPL(IConnectionPointContainer)
END_COM_MAP()
BEGIN_CONNECTION_POINT_MAP(CSEOMetaDictionary)
CONNECTION_POINT_ENTRY(IID_IEventNotifyBindingChange)
END_CONNECTION_POINT_MAP()
// CSEOConnectionPointImp<>
public:
void AdviseCalled(IUnknown *pUnk, DWORD *pdwCookie, REFIID riid, DWORD dwCount);
void UnadviseCalled(DWORD dwCookie, REFIID riid, DWORD dwCount);
// ISEODictionary
public:
virtual /* [id][propget][helpstring] */ HRESULT STDMETHODCALLTYPE get_Item(
/* [in] */ VARIANT __RPC_FAR *pvarName,
/* [retval][out] */ VARIANT __RPC_FAR *pvarResult);
virtual /* [propput][helpstring] */ HRESULT STDMETHODCALLTYPE put_Item(
/* [in] */ VARIANT __RPC_FAR *pvarName,
/* [in] */ VARIANT __RPC_FAR *pvarValue);
virtual /* [hidden][id][propget][helpstring] */ HRESULT STDMETHODCALLTYPE get__NewEnum(
/* [retval][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppunkResult);
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetVariantA(
/* [in] */ LPCSTR pszName,
/* [retval][out] */ VARIANT __RPC_FAR *pvarResult);
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetVariantW(
/* [in] */ LPCWSTR pszName,
/* [retval][out] */ VARIANT __RPC_FAR *pvarResult);
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetVariantA(
/* [in] */ LPCSTR pszName,
/* [in] */ VARIANT __RPC_FAR *pvarValue);
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetVariantW(
/* [in] */ LPCWSTR pszName,
/* [in] */ VARIANT __RPC_FAR *pvarValue);
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetStringA(
/* [in] */ LPCSTR pszName,
/* [out][in] */ DWORD __RPC_FAR *pchCount,
/* [retval][size_is][out] */ LPSTR pszResult);
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetStringW(
/* [in] */ LPCWSTR pszName,
/* [out][in] */ DWORD __RPC_FAR *pchCount,
/* [retval][size_is][out] */ LPWSTR pszResult);
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetStringA(
/* [in] */ LPCSTR pszName,
/* [in] */ DWORD chCount,
/* [size_is][in] */ LPCSTR pszValue);
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetStringW(
/* [in] */ LPCWSTR pszName,
/* [in] */ DWORD chCount,
/* [size_is][in] */ LPCWSTR pszValue);
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetDWordA(
/* [in] */ LPCSTR pszName,
/* [retval][out] */ DWORD __RPC_FAR *pdwResult);
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetDWordW(
/* [in] */ LPCWSTR pszName,
/* [retval][out] */ DWORD __RPC_FAR *pdwResult);
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetDWordA(
/* [in] */ LPCSTR pszName,
/* [in] */ DWORD dwValue);
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetDWordW(
/* [in] */ LPCWSTR pszName,
/* [in] */ DWORD dwValue);
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetInterfaceA(
/* [in] */ LPCSTR pszName,
/* [in] */ REFIID iidDesired,
/* [retval][iid_is][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppunkResult);
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE GetInterfaceW(
/* [in] */ LPCWSTR pszName,
/* [in] */ REFIID iidDesired,
/* [retval][iid_is][out] */ IUnknown __RPC_FAR *__RPC_FAR *ppunkResult);
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetInterfaceA(
/* [in] */ LPCSTR pszName,
/* [in] */ IUnknown __RPC_FAR *punkValue);
virtual /* [helpstring] */ HRESULT STDMETHODCALLTYPE SetInterfaceW(
/* [in] */ LPCWSTR pszName,
/* [in] */ IUnknown __RPC_FAR *punkValue);
// ISEOInitObject (IPersistPropertyBag)
public:
virtual HRESULT STDMETHODCALLTYPE GetClassID(/* [out] */ CLSID __RPC_FAR *pClassID);
virtual HRESULT STDMETHODCALLTYPE InitNew(void);
virtual HRESULT STDMETHODCALLTYPE Load(
/* [in] */ IPropertyBag __RPC_FAR *pPropBag,
/* [in] */ IErrorLog __RPC_FAR *pErrorLog);
virtual HRESULT STDMETHODCALLTYPE Save(
/* [in] */ IPropertyBag __RPC_FAR *pPropBag,
/* [in] */ BOOL fClearDirty,
/* [in] */ BOOL fSaveAllProperties);
// IPropertyBag
public:
HRESULT STDMETHODCALLTYPE Read(LPCOLESTR pszPropName, VARIANT *pVar, IErrorLog *pErrorLog);
HRESULT STDMETHODCALLTYPE Write(LPCOLESTR pszPropName, VARIANT *pVar);
// IEventPropertyBag
public:
HRESULT STDMETHODCALLTYPE Item(VARIANT *pvarPropDesired, VARIANT *pvarPropValue);
HRESULT STDMETHODCALLTYPE Name(long lPropIndex, BSTR *pbstrPropName);
HRESULT STDMETHODCALLTYPE Add(BSTR pszPropName, VARIANT *pvarPropValue);
HRESULT STDMETHODCALLTYPE Remove(VARIANT *pvarPropDesired);
HRESULT STDMETHODCALLTYPE get_Count(long *plCount);
/* Just use the get__NewEnum from ISEODictionary
HRESULT STDMETHODCALLTYPE get__NewEnum(IUnknown **ppUnkEnum); */
DECLARE_GET_CONTROLLING_UNKNOWN();
// IEventLock
public:
HRESULT STDMETHODCALLTYPE LockRead(int iTimeoutMS);
HRESULT STDMETHODCALLTYPE UnlockRead();
HRESULT STDMETHODCALLTYPE LockWrite(int iTimeoutMS);
HRESULT STDMETHODCALLTYPE UnlockWrite();
protected:
HRESULT CopyDictionary(LPCWSTR pszName, ISEODictionary *pBag);
HRESULT Init(const CSEOMetabase &pmbOther, LPCWSTR pszPath) {
m_mbHelper = pmbOther;
m_mbHelper.AppendPath(pszPath);
return S_OK;
};
HRESULT InitShare(CSEOMetabase &pmbOther, LPCWSTR pszPath) {
return m_mbHelper.InitShare(&pmbOther, pszPath,
this->GetControllingUnknown());
};
private: // Private data
CSEOMetabase m_mbHelper; // The master helper
CComPtr<IUnknown> m_pUnkMarshaler;
};