Source code of Windows XP (NT5)
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.
 
 
 
 
 
 

333 lines
7.5 KiB

/*===================================================================
Microsoft Denali
Microsoft Confidential.
Copyright 1997 Microsoft Corporation. All Rights Reserved.
Component: MetaUtil object
File: MetaSchm.h
Owner: t-BrianM
This file contains the headers for the CMetaSchemaTable object and
other schema related objects.
===================================================================*/
#ifndef __METASCHM_H_
#define __METASCHM_H_
#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000
#include "resource.h" // main symbols
// Ripped from schemini.hxx
struct PropValue {
DWORD dwMetaID;
DWORD dwSynID;
DWORD dwMetaType;
DWORD dwFlags;
DWORD dwMask;
DWORD dwMetaFlags;
DWORD dwUserGroup;
BOOL fMultiValued;
};
// All hash table sizes are prime numbers between powers of 2
// and are ~10x larger than the expected number of items.
#define SCHEMA_HASH_SIZE 181
#define PROPERTY_HASH_SIZE 1559
#define CLASS_HASH_SIZE 181
#define CLASS_PROPERTY_HASH_SIZE 709
/*
* C P r o p I n f o
*
* C P r o p I n f o T a b l e
*
* Internal classes used to store and represent property information
*/
class CPropInfoTable;
class CPropInfo {
friend CPropInfoTable;
public:
CPropInfo() : m_dwId(0),
m_tszName(NULL),
m_pType(NULL),
m_pCIdHashNext(NULL),
m_pCNameHashNext(NULL) { }
HRESULT Init(DWORD dwId);
HRESULT SetName(LPCTSTR tszName);
HRESULT SetTypeInfo(PropValue *pType);
~CPropInfo() {
if (m_tszName != NULL) delete m_tszName;
if (m_pType != NULL) delete m_pType;
}
DWORD GetId() { return m_dwId; }
LPCTSTR GetName() { return m_tszName; }
PropValue *GetTypeInfo() { return m_pType; }
private:
DWORD m_dwId;
LPTSTR m_tszName;
PropValue *m_pType;
CPropInfo *m_pCNameHashNext;
CPropInfo *m_pCIdHashNext;
};
class CPropInfoTable {
public:
CPropInfoTable();
~CPropInfoTable();
HRESULT Load(CComPtr<IMSAdminBase> &pIMeta, METADATA_HANDLE hMDComp);
void Unload();
CPropInfo *GetPropInfo(DWORD dwId);
CPropInfo *GetPropInfo(LPCTSTR tszName);
private:
BOOL m_fLoaded;
CPropInfo *m_rgCPropIdTable[PROPERTY_HASH_SIZE];
CPropInfo *m_rgCPropNameTable[PROPERTY_HASH_SIZE];
unsigned int IdHash(DWORD dwId) { return dwId % PROPERTY_HASH_SIZE; }
unsigned int NameHash(LPCTSTR tszName);
};
/*
* C C l a s s P r o p I n f o
*
* C C l a s s I n f o
*
* C C l a s s I n f o T a b l e
*
* Internal classes used to store and represent class information
*/
class CClassInfoTable;
class CClassInfo;
class CClassPropInfo {
friend CClassInfo;
public:
CClassPropInfo() : m_dwId(0),
m_fMandatory(FALSE),
m_pCHashNext(NULL),
m_pCListNext(NULL) {}
HRESULT Init(DWORD dwId, BOOL fMandatory) {
m_dwId = dwId;
m_fMandatory = fMandatory;
return S_OK;
}
DWORD GetId() { return m_dwId; }
BOOL IsMandatory() { return m_fMandatory; }
CClassPropInfo *GetListNext() { return m_pCListNext; }
private:
DWORD m_dwId;
BOOL m_fMandatory;
// Property default information could also be added...
CClassPropInfo *m_pCHashNext;
CClassPropInfo *m_pCListNext;
};
class CClassInfo {
friend CClassInfoTable;
public:
CClassInfo();
HRESULT Init(LPCTSTR tszName);
~CClassInfo();
HRESULT Load(CComPtr<IMSAdminBase> &pIMeta, METADATA_HANDLE hMDClasses);
void Unload();
CClassPropInfo *GetProperty(DWORD dwId);
CClassPropInfo *GetOptionalPropList() { return m_pCOptionalPropList; }
CClassPropInfo *GetMandatoryPropList() { return m_pCMandatoryPropList; }
private:
LPTSTR m_tszName;
CClassInfo *m_pCHashNext;
BOOL m_fLoaded;
CClassPropInfo *m_rgCPropTable[CLASS_PROPERTY_HASH_SIZE];
CClassPropInfo *m_pCOptionalPropList;
CClassPropInfo *m_pCMandatoryPropList;
unsigned int Hash(DWORD dwId) { return dwId % CLASS_PROPERTY_HASH_SIZE; }
};
class CClassInfoTable {
public:
CClassInfoTable();
~CClassInfoTable();
HRESULT Load(CComPtr<IMSAdminBase> &pIMeta, METADATA_HANDLE hMDComp);
void Unload();
CClassInfo *GetClassInfo(LPCTSTR tszName);
private:
BOOL m_fLoaded;
CClassInfo *m_rgCClassTable[CLASS_HASH_SIZE];
unsigned int Hash(LPCTSTR tszName);
};
/*
* C M e t a S c h e m a
*
* Internal class used to store schema information for a machine
*/
class CMetaSchemaTable;
class CMetaSchema {
friend CMetaSchemaTable;
public:
CMetaSchema() : m_fPropTableDirty(TRUE),
m_fClassTableDirty(TRUE),
m_tszMachineName(NULL),
m_pCNextSchema(NULL) { }
HRESULT Init(const CComPtr<IMSAdminBase> &pIMeta, LPCTSTR tszMachineName);
~CMetaSchema() { if (m_tszMachineName != NULL) delete m_tszMachineName; }
CPropInfo *GetPropInfo(DWORD dwId);
CPropInfo *GetPropInfo(LPCTSTR tszName);
CClassInfo *GetClassInfo(LPCTSTR tszClassName);
CClassPropInfo *GetClassPropInfo(LPCTSTR tszClassName, DWORD dwPropId);
CClassPropInfo *GetMandatoryClassPropList(LPCTSTR tszClassName);
CClassPropInfo *GetOptionalClassPropList(LPCTSTR tszClassName);
void ChangeNotification(LPTSTR tszKey, MD_CHANGE_OBJECT *pcoChangeObject);
private:
LPTSTR m_tszMachineName;
BOOL m_fPropTableDirty;
BOOL m_fClassTableDirty;
CPropInfoTable m_CPropInfoTable;
CClassInfoTable m_CClassInfoTable;
// Pointer to IMSAdminBase so we don't have to recreate it multiple times
CComPtr<IMSAdminBase> m_pIMeta;
CMetaSchema *m_pCNextSchema;
HRESULT LoadPropTable();
HRESULT LoadClassTable();
};
/*
* C M e t a S c h e m a T a b l e
*
* Implements IMetaSchemaTable. Stores all of the schema information
* for all of the machines. I made it global so it can persist after
* CMetaUtil is destructed.
*/
class CMSAdminBaseSink;
class CMetaSchemaTable {
public:
CMetaSchemaTable();
~CMetaSchemaTable();
DWORD AddRef() { return ++m_dwNumRef; }
DWORD Release() {
m_dwNumRef--;
if (!m_dwNumRef) {
delete this;
return 0;
}
return m_dwNumRef;
}
void Load();
void Unload();
CPropInfo *GetPropInfo(LPCTSTR tszKey, DWORD dwPropId);
CPropInfo *GetPropInfo(LPCTSTR tszKey, LPCTSTR tszPropName);
CClassInfo *GetClassInfo(LPCTSTR tszKey, LPCTSTR tszClassName);
CClassPropInfo *GetClassPropInfo(LPCTSTR tszKey, LPCTSTR tszClassName, DWORD dwPropId);
CClassPropInfo *GetMandatoryClassPropList(LPCTSTR tszKey, LPCTSTR tszClassName);
CClassPropInfo *GetOptionalClassPropList(LPCTSTR tszKey, LPCTSTR tszClassName);
// Event sink callback
HRESULT SinkNotify(DWORD dwMDNumElements, MD_CHANGE_OBJECT pcoChangeObject[]);
private:
DWORD m_dwNumRef;
BOOL m_fLoaded;
CMetaSchema *m_rgCSchemaTable[SCHEMA_HASH_SIZE];
CComObject<CMSAdminBaseSink> *m_CMSAdminBaseSink;
// Pointer to IMSAdminBase so we don't have to recreate it multiple times
CComPtr<IMSAdminBase> m_pIMeta;
CMetaSchema *GetSchema(LPCTSTR tszKey);
unsigned int Hash(LPCTSTR tszName);
};
/*
* C M S A d m i n B a s e S i n k
*
* Minimal ATL COM object that catches change notification events from the
* metabase object and passes them on to the CMetaSchemaTable object.
*/
class CMSAdminBaseSink :
public IMSAdminBaseSink,
public CComObjectRoot
{
public:
CMSAdminBaseSink();
~CMSAdminBaseSink();
BEGIN_COM_MAP(CMSAdminBaseSink)
COM_INTERFACE_ENTRY(IMSAdminBaseSink)
END_COM_MAP()
// DECLARE_NOT_AGGREGATABLE(CMSAdminBaseSink)
// IMSAdminBaseSink
STDMETHOD(SinkNotify)(DWORD dwMDNumElements, MD_CHANGE_OBJECT pcoChangeObject[]);
STDMETHOD(ShutdownNotify)(void);
// No Interface
HRESULT Connect(CComPtr<IMSAdminBase> &pIMeta, CMetaSchemaTable *pCMetaSchemaTable);
void Disconnect();
private:
BOOL m_fConnected;
DWORD m_dwCookie;
CComPtr<IConnectionPoint> m_pIMetaConn;
CMetaSchemaTable *m_pCMetaSchemaTable;
};
#endif // #ifndef __METASCHM_H_