mirror of https://github.com/tongzx/nt5src
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
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
|
|
|