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.
 
 
 
 
 
 

214 lines
6.5 KiB

/*++
Copyright (C) 2000-2001 Microsoft Corporation
--*/
#ifndef __WMI_A51__HIECACHE__H_
#define __WMI_A51__HIECACHE__H_
//
// NOTE: it is critical that things be marked in the cache while the repository
// lock is held! Otherwise, invalidation/completion logic will break
//
#include <wbemint.h>
#include <map>
#include <sync.h>
#include <wstlallc.h>
#include <lockst.h>
#include "a51tools.h"
class wcscless : public binary_function<LPCWSTR, LPCWSTR, bool>
{
public:
bool operator()(const LPCWSTR& wcs1, const LPCWSTR& wcs2) const
{return wcscmp(wcs1, wcs2) < 0;}
};
typedef enum {e_KeynessUnknown, e_Keyed, e_NotKeyed} EKeyNess;
class CClassRecord
{
protected:
static long s_nRecords;
long m_lRef;
CClassRecord* m_pMoreRecentlyUsed;
CClassRecord* m_pLessRecentlyUsed;
LPWSTR m_wszClassName;
WCHAR m_wszHash[MAX_HASH_LEN+1];
_IWmiObject* m_pClassDef;
DWORD m_dwClassDefSize;
CClassRecord* m_pParent;
EKeyNess m_eIsKeyed;
CPointerArray<CClassRecord> m_apChildren;
bool m_bTreeComplete;
bool m_bChildrenComplete;
LONGLONG m_lLastChildInvalidationIndex;
DWORD m_dwLastUsed;
int m_nStatus;
__int64 m_nClassDefCachedTime;
bool m_bRead;
bool m_bSystemClass;
public:
CClassRecord(LPCWSTR wszClassName, LPCWSTR wszHash);
virtual ~CClassRecord();
void AddRef() {InterlockedIncrement(&m_lRef);}
void Release() {if(InterlockedDecrement(&m_lRef) == 0) delete this;}
HRESULT EnsureChild(CClassRecord* pChild);
HRESULT RemoveChild(CClassRecord* pChild);
friend class CHierarchyCache;
friend class CForestCache;
};
class CForestCache;
class CHierarchyCache
{
protected:
static long s_nCaches;
long m_lRef;
typedef std::map<LPCWSTR, CClassRecord*, wcscless, wbem_allocator<CClassRecord*> > TMap;
typedef TMap::iterator TIterator;
CForestCache* m_pForest;
TMap m_map;
LONGLONG m_lNextInvalidationIndex;
HRESULT m_hresError;
public:
CHierarchyCache(CForestCache* pForest);
virtual ~CHierarchyCache();
long AddRef() {return InterlockedIncrement(&m_lRef);}
long Release() { long lRet = InterlockedDecrement(&m_lRef); if (0 == lRet) delete this; return lRet; }
HRESULT AssertClass(_IWmiObject* pClass, LPCWSTR wszClassName,
bool bClone, __int64 nTime, bool bSystemClass);
HRESULT InvalidateClass(LPCWSTR wszClassName);
HRESULT DoneWithChildren(LPCWSTR wszClassName, bool bRecursive,
LONGLONG lStartingIndex,
CClassRecord* pRecord = NULL);
HRESULT DoneWithChildrenByHash(LPCWSTR wszHash, bool bRecursive,
LONGLONG lStartIndex);
LONGLONG GetLastInvalidationIndex() {return m_lNextInvalidationIndex-1;}
void SetError(HRESULT hresError);
HRESULT GetError();
void Clear();
public:
RELEASE_ME _IWmiObject* GetClassDef(LPCWSTR wszClassName,
bool bClone, __int64* pnTime = NULL,
bool* pbRead = NULL);
HRESULT EnumChildren(LPCWSTR wszClassName, bool bRecursive,
CWStringArray& awsChildren);
HRESULT EnumChildKeysByKey(LPCWSTR wszClassKey,
CWStringArray& awsChildKeys);
HRESULT GetKeyRootByKey(LPCWSTR wszKey,
TEMPFREE_ME LPWSTR* pwszKeyRoot);
HRESULT GetKeyRoot(LPCWSTR wszClassName,
TEMPFREE_ME LPWSTR* pwszKeyRoot);
HRESULT GetKeyRootByRecord(CClassRecord* pRecord,
TEMPFREE_ME LPWSTR* pwszKeyRoot);
DELETE_ME LPWSTR GetParent(LPCWSTR wszClassName);
RELEASE_ME _IWmiObject* GetClassDefByHash(LPCWSTR wszHash, bool bClone,
__int64* pnTime = NULL,
bool* pbRead = NULL,
bool *pbSystemClass = NULL);
protected:
INTERNAL CClassRecord* FindClass(LPCWSTR wszClassName);
INTERNAL CClassRecord* FindClassByKey(LPCWSTR wszKey);
RELEASE_ME _IWmiObject* GetClassDefFromRecord(CClassRecord* pRecord,
bool bClone);
INTERNAL CClassRecord* EnsureClass(LPCWSTR wszClassName);
HRESULT EnumChildrenInternal(CClassRecord* pRecord,
bool bRecursive,
CWStringArray& awsChildren);
HRESULT InvalidateClassInternal(CClassRecord* pRecord);
HRESULT DoneWithChildrenByRecord(CClassRecord* pRecord,
bool bRecursive, LONGLONG lStartIndex);
static void MakeKey(LPCWSTR wszClassName, LPWSTR wszKey);
};
class CForestCache
{
protected:
CriticalSection m_cs;
CClassRecord* m_pMostRecentlyUsed;
CClassRecord* m_pLeastRecentlyUsed;
DWORD m_dwMaxMemory;
DWORD m_dwMaxAgeMs;
DWORD m_dwTotalMemory;
HANDLE m_hCurrentTimer;
long m_lRef;
BOOL m_bInit;
typedef std::map<WString, CHierarchyCache*, WSiless, wbem_allocator<CHierarchyCache*> > TMap;
typedef TMap::iterator TIterator;
TMap m_map;
bool m_bAssertedInTransaction;
public:
CForestCache() : m_dwMaxMemory(0xFFFFFFFF), m_dwTotalMemory(0),
m_pMostRecentlyUsed(NULL), m_pLeastRecentlyUsed(NULL),
m_dwMaxAgeMs(0), m_hCurrentTimer(NULL),
m_lRef(1), m_bInit(FALSE), m_bAssertedInTransaction(false),
m_cs(THROW_LOCK,0x80000000 | 400L)
{
}
~CForestCache();
HRESULT Initialize();
HRESULT Deinitialize();
void SetMaxMemory(DWORD dwMaxMemory, DWORD dwMaxAgeMs);
bool MakeRoom(DWORD dwSize);
bool Flush();
void MakeMostRecentlyUsed(CClassRecord* pRecord);
void Add(CClassRecord* pRecord);
void RemoveRecord(CClassRecord* pRecord);
void BeginTransaction();
bool MarkAsserted(CHierarchyCache* pCache, LPCWSTR wszClassName);
void CommitTransaction();
void AbortTransaction();
public:
CHierarchyCache* GetNamespaceCache(LPCWSTR wszNamespace);
void ReleaseNamespaceCache(LPCWSTR wszNamespace, CHierarchyCache* pCache);
long AddRef() { return InterlockedIncrement(&m_lRef);}
long Release() { long lRet = InterlockedDecrement(&m_lRef); if (!lRet) delete this; return lRet;}
void Clear();
protected:
CriticalSection & GetLock() {return m_cs;}
bool Test();
void Untie(CClassRecord* pRecord);
void TimerCallback();
static void staticTimerCallback(VOID* pParam, BOOLEAN);
friend class CHierarchyCache;
};
#endif