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.
1339 lines
43 KiB
1339 lines
43 KiB
/*++
|
|
|
|
Copyright (C) 1996-1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
EVALTREE.H
|
|
|
|
Abstract:
|
|
|
|
WBEM Evaluation Tree
|
|
|
|
History:
|
|
|
|
--*/
|
|
|
|
#ifndef __WBEM_EVALUTAION_TREE__H_
|
|
#define __WBEM_EVALUTAION_TREE__H_
|
|
|
|
#include "esscpol.h"
|
|
#include <parmdefs.h>
|
|
#include <ql.h>
|
|
#include <sync.h>
|
|
#include <limits.h>
|
|
#include <sortarr.h>
|
|
#include <newnew.h>
|
|
#include <wbemmeta.h>
|
|
#include <wbemdnf.h>
|
|
#include <fastall.h>
|
|
#include <like.h>
|
|
|
|
// Uncomment this to enable tree checking.
|
|
//#define CHECK_TREES
|
|
|
|
#ifdef CHECK_TREES
|
|
class CTreeChecker;
|
|
#endif
|
|
|
|
typedef DWORD_PTR QueryID;
|
|
#define InvalidID UINT_MAX
|
|
|
|
enum {EVAL_VALUE_TRUE, EVAL_VALUE_FALSE, EVAL_VALUE_INVALID};
|
|
|
|
#define WBEM_FLAG_MANDATORY_MERGE 0x100
|
|
#define MAX_TOKENS_IN_DNF 100
|
|
|
|
// This is where we keep the extracted embedded objects
|
|
class ESSCLI_POLARITY CObjectInfo
|
|
{
|
|
protected:
|
|
long m_lLength;
|
|
_IWmiObject** m_apObj;
|
|
|
|
public:
|
|
CObjectInfo() : m_apObj(NULL), m_lLength(0){}
|
|
~CObjectInfo();
|
|
|
|
long GetLength() {return m_lLength;}
|
|
bool SetLength(long lLength);
|
|
void Clear();
|
|
|
|
INTERNAL _IWmiObject* GetObjectAt(long lIndex)
|
|
{return m_apObj[lIndex];}
|
|
void SetObjectAt(long lIndex, READ_ONLY _IWmiObject* pObj);
|
|
};
|
|
|
|
// This is where we keep what we've learned about the object in the query
|
|
// as we move down the tree.
|
|
class CImplicationList
|
|
{
|
|
public:
|
|
struct CRecord
|
|
{
|
|
CPropertyName m_PropName;
|
|
_IWmiObject* m_pClass;
|
|
long m_lObjIndex;
|
|
CWStringArray m_awsNotClasses;
|
|
int m_nNull;
|
|
|
|
public:
|
|
CRecord(CPropertyName& PropName, long lObjIndex)
|
|
: m_PropName(PropName), m_pClass(NULL), m_lObjIndex(lObjIndex),
|
|
m_nNull(EVAL_VALUE_INVALID)
|
|
{}
|
|
CRecord(const CRecord& Other);
|
|
~CRecord();
|
|
|
|
HRESULT ImproveKnown(_IWmiObject* pClass);
|
|
HRESULT ImproveKnownNot(LPCWSTR wszClassName);
|
|
HRESULT ImproveKnownNull();
|
|
|
|
void Dump(FILE* f, int nOffset);
|
|
|
|
private:
|
|
|
|
CRecord& operator=( const CRecord& Other );
|
|
};
|
|
|
|
protected:
|
|
long m_lRequiredDepth;
|
|
CUniquePointerArray<CRecord> m_apRecords;
|
|
long m_lNextIndex;
|
|
CImplicationList* m_pParent;
|
|
long m_lFlags;
|
|
|
|
protected:
|
|
void FindBestComputedContainer(CPropertyName* pPropName,
|
|
long* plRecord, long* plMatched);
|
|
HRESULT MergeIn(CImplicationList::CRecord* pRecord);
|
|
HRESULT FindRecordForProp(CPropertyName* pPropName, long lNumElements,
|
|
long* plRecord);
|
|
HRESULT FindOrCreateRecordForProp(CPropertyName* pPropName,
|
|
CImplicationList::CRecord** ppRecord);
|
|
|
|
private:
|
|
|
|
CImplicationList& operator=( const CImplicationList& Other );
|
|
|
|
public:
|
|
CImplicationList(long lFlags = 0);
|
|
CImplicationList(CImplicationList& Other, bool bLink = true);
|
|
~CImplicationList();
|
|
|
|
|
|
HRESULT FindBestComputedContainer(CPropertyName* pPropName,
|
|
long* plFirstUnknownProp, long* plObjIndex,
|
|
RELEASE_ME _IWmiObject** ppContainerClass);
|
|
HRESULT FindClassForProp(CPropertyName* pPropName,
|
|
long lNumElements, RELEASE_ME _IWmiObject** ppClass);
|
|
HRESULT AddComputation(CPropertyName& PropName,
|
|
_IWmiObject* pClass, long* plObjIndex);
|
|
HRESULT MergeIn(CImplicationList* pList);
|
|
|
|
|
|
long GetRequiredDepth();
|
|
void RequireDepth(long lDepth);
|
|
HRESULT ImproveKnown(CPropertyName* pPropName, _IWmiObject* pClass);
|
|
HRESULT ImproveKnownNot(CPropertyName* pPropName, LPCWSTR wszClassName);
|
|
HRESULT ImproveKnownNull(CPropertyName* pPropName);
|
|
|
|
bool IsMergeMandatory()
|
|
{return ((m_lFlags & WBEM_FLAG_MANDATORY_MERGE) != 0);}
|
|
|
|
bool IsEmpty() {return m_apRecords.GetSize() == 0;}
|
|
void Dump(FILE* f, int nOffset);
|
|
};
|
|
|
|
// Wrapper for arbitrary values
|
|
class CTokenValue
|
|
{
|
|
protected:
|
|
VARIANT m_v;
|
|
public:
|
|
CTokenValue();
|
|
CTokenValue(CTokenValue& Other);
|
|
~CTokenValue();
|
|
|
|
bool SetVariant(VARIANT& v);
|
|
void operator=(CTokenValue& Other);
|
|
|
|
operator signed char() const {return (signed char)V_I4(&m_v);}
|
|
operator unsigned char() const {return (unsigned char)V_I4(&m_v);}
|
|
operator unsigned short() const {return (unsigned short)V_I4(&m_v);}
|
|
operator long() const {return (long)V_I4(&m_v);}
|
|
operator unsigned long() const;
|
|
operator __int64() const;
|
|
operator unsigned __int64() const;
|
|
operator float() const;
|
|
operator double() const;
|
|
operator short() const;
|
|
operator WString() const;
|
|
operator CInternalString() const {return CInternalString((WString)*this);}
|
|
|
|
int Compare(const CTokenValue& Other) const;
|
|
|
|
BOOL operator<(const CTokenValue& Other) const
|
|
{return Compare(Other) < 0;}
|
|
BOOL operator>(const CTokenValue& Other) const
|
|
{return Compare(Other) > 0;}
|
|
BOOL operator==(const CTokenValue& Other) const
|
|
{return Compare(Other) == 0;}
|
|
};
|
|
|
|
enum {EVAL_OP_AND, EVAL_OP_OR, EVAL_OP_COMBINE, EVAL_OP_INVERSE_COMBINE};
|
|
inline int FlipEvalOp(int nOp)
|
|
{
|
|
if(nOp == EVAL_OP_COMBINE) return EVAL_OP_INVERSE_COMBINE;
|
|
else if(nOp == EVAL_OP_INVERSE_COMBINE) return EVAL_OP_COMBINE;
|
|
else return nOp;
|
|
}
|
|
|
|
enum
|
|
{
|
|
EVAL_NODE_TYPE_VALUE,
|
|
EVAL_NODE_TYPE_BRANCH,
|
|
EVAL_NODE_TYPE_OR,
|
|
EVAL_NODE_TYPE_INHERITANCE,
|
|
EVAL_NODE_TYPE_SCALAR,
|
|
EVAL_NODE_TYPE_TWO_SCALARS,
|
|
EVAL_NODE_TYPE_STRING,
|
|
EVAL_NODE_TYPE_TWO_STRINGS,
|
|
EVAL_NODE_TYPE_MISMATCHED_INTS,
|
|
EVAL_NODE_TYPE_MISMATCHED_FLOATS,
|
|
EVAL_NODE_TYPE_MISMATCHED_STRINGS,
|
|
EVAL_NODE_TYPE_DUMB,
|
|
EVAL_NODE_TYPE_LIKE_STRING
|
|
};
|
|
|
|
// Base class for all sorts of operations one can perform on leaf nodes of a
|
|
// tree. When applied to a leaf, it can change it, and return a value from the
|
|
// list below to control the rest of the traversal
|
|
enum
|
|
{
|
|
WBEM_DISPOSITION_NORMAL = 0,
|
|
WBEM_DISPOSITION_STOPLEVEL = 1,
|
|
WBEM_DISPOSITION_STOPALL = 2,
|
|
WBEM_DISPOSITION_FLAG_DELETE = 16,
|
|
WBEM_DISPOSITION_FLAG_INVALIDATE = 32
|
|
};
|
|
|
|
class CLeafPredicate
|
|
{
|
|
public:
|
|
virtual DWORD operator()(class CValueNode* pLeaf) = 0;
|
|
|
|
};
|
|
|
|
class CProjectionFilter
|
|
{
|
|
public:
|
|
virtual bool IsInSet(class CEvalNode* pNode) = 0;
|
|
};
|
|
|
|
typedef enum {e_Sufficient, e_Necessary} EProjectionType;
|
|
|
|
// Base class for all nodes in the tree
|
|
class ESSCLI_POLARITY CEvalNode
|
|
{
|
|
protected:
|
|
// int m_nType;
|
|
virtual int GetType() = 0;
|
|
|
|
private:
|
|
CEvalNode& operator=( const CEvalNode& ); // notimpl
|
|
|
|
public:
|
|
CEvalNode();
|
|
CEvalNode(const CEvalNode& other);
|
|
virtual ~CEvalNode();
|
|
|
|
// NULL EvalNode interpreted as a Value Node with all false
|
|
static int GetType(CEvalNode *pNode)
|
|
{
|
|
if (pNode)
|
|
return pNode->GetType();
|
|
else
|
|
return EVAL_NODE_TYPE_VALUE;
|
|
}
|
|
|
|
|
|
virtual CEvalNode* Clone() const = 0;
|
|
virtual HRESULT CombineWith(CEvalNode* pArg2, int nOp,
|
|
CContextMetaData* pNamespace, CImplicationList& Implications,
|
|
bool bDeleteThis, bool bDeleteArg2, CEvalNode** ppRes)=0;
|
|
virtual int Compare(CEvalNode* pOther) = 0;
|
|
virtual DWORD ApplyPredicate(CLeafPredicate* pPred) = 0;
|
|
virtual void Dump(FILE* f, int nOffset) = 0;
|
|
#ifdef CHECK_TREES
|
|
virtual void CheckNode(CTreeChecker *pCheck);
|
|
#endif
|
|
|
|
virtual HRESULT Optimize(CContextMetaData* pNamespace, CEvalNode** ppNew)
|
|
{*ppNew = this; return WBEM_S_NO_ERROR;}
|
|
virtual bool IsInvalid() {return false;}
|
|
|
|
static bool IsInvalid(CEvalNode* pNode)
|
|
{
|
|
if(pNode)
|
|
return pNode->IsInvalid();
|
|
else
|
|
return false;
|
|
}
|
|
|
|
virtual bool IsAllFalse() {return false;}
|
|
static bool IsAllFalse(CEvalNode* pNode)
|
|
{
|
|
if(pNode)
|
|
return pNode->IsAllFalse();
|
|
else
|
|
return true; // empty node is FALSE
|
|
}
|
|
|
|
virtual bool IsNoop(int nOp) {return false;}
|
|
static bool IsNoop(CEvalNode* pNode, int nOp);
|
|
|
|
virtual CImplicationList* GetExtraImplications() = 0;
|
|
virtual HRESULT SetExtraImplications(CImplicationList* pList) = 0;
|
|
|
|
static void PrintOffset(FILE* f, int nOffset);
|
|
static CEvalNode* CloneNode(const CEvalNode* pNode);
|
|
virtual HRESULT Project(CContextMetaData* pMeta,
|
|
CImplicationList& Implications,
|
|
CProjectionFilter* pFilter,
|
|
EProjectionType eType, bool bDeleteThis,
|
|
CEvalNode** ppNewNode) = 0;
|
|
static void DumpNode(FILE* f, int nOffset, CEvalNode* pNode);
|
|
|
|
};
|
|
|
|
// just like CFlexArray, except:
|
|
// array is always sorted
|
|
// duplicates are not allowed
|
|
// deals with QueryIDs (unsigneds), rather than pointers
|
|
// intended for use by CValueNode, not necessarily as a generic sorted array
|
|
// ASSUMPTION: pointer is same size as an unsigned
|
|
class ESSCLI_POLARITY CSortedArray : protected CFlexArray
|
|
{
|
|
public:
|
|
// Constructs a sorted array at an initial size and
|
|
// specifies the initial size and growth-size chunk.
|
|
// =================================================
|
|
CSortedArray(int nInitialSize = 32,
|
|
int nGrowBy = 32
|
|
) : CFlexArray(nInitialSize, nGrowBy)
|
|
{}
|
|
|
|
|
|
CSortedArray(unsigned nElements, QueryID* pArray);
|
|
// ~CSortedArray(); don't need it, yet...
|
|
|
|
void operator=(const CSortedArray &that)
|
|
{((CFlexArray&)*this = (CFlexArray&)that); }
|
|
|
|
int inline Size() const { return CFlexArray::Size(); }
|
|
|
|
inline QueryID GetAt(int nIndex)
|
|
{ return (QueryID)CFlexArray::GetAt(nIndex); }
|
|
|
|
inline void Empty() { CFlexArray::Empty(); }
|
|
inline void SetSize(int nSize) {CFlexArray::SetSize(nSize);}
|
|
|
|
void DebugDump() { CFlexArray::DebugDump(); }
|
|
|
|
// copies this array to destination
|
|
// returns number of elements copied
|
|
unsigned CopyTo(QueryID* pDest, unsigned size);
|
|
|
|
//returns zero if arrays are equivalent
|
|
// same number of USED elements w/ same values
|
|
int Compare(CSortedArray& otherArray);
|
|
|
|
// finds n in array
|
|
// return index of found element
|
|
// returns -1 if not found
|
|
unsigned Find(QueryID n);
|
|
|
|
// inserts n in proper position in array
|
|
void Insert(QueryID n);
|
|
|
|
// removes n from array
|
|
// returns true if it did
|
|
bool Remove(QueryID n);
|
|
|
|
// add to end of array
|
|
inline int Add(QueryID n) { return CFlexArray::Add((void *)n); };
|
|
|
|
// changes all QueryID's to begin at newBase
|
|
// e.g. if the array is {0,1,5}
|
|
// Rebase(6) will change to {6,7,11}
|
|
void Rebase(QueryID newBase);
|
|
|
|
// Retrieves internal pointer to the data in the array
|
|
inline QueryID* GetArrayPtr() {return (QueryID*)CFlexArray::GetArrayPtr();}
|
|
|
|
// Retrieves the pointer to the data in the array and empties the array
|
|
// The caller is responsible for the memory returned
|
|
inline QueryID* UnbindPtr() {return (QueryID*)CFlexArray::UnbindPtr();}
|
|
|
|
// Copies the data (but not the extent) from another array
|
|
// Its own data is overwritten
|
|
inline int CopyDataFrom(const CSortedArray& aOther)
|
|
{return CFlexArray::CopyDataFrom(aOther);}
|
|
|
|
int AddDataFrom(const CSortedArray& aOther);
|
|
int AddDataFrom(const QueryID* pOtherArray, unsigned nValues);
|
|
|
|
|
|
int CopyDataFrom(const QueryID* pArray, unsigned nElements);
|
|
|
|
protected:
|
|
|
|
};
|
|
|
|
// Leaf node --- contains the list of queries that matched
|
|
class CValueNode : public CEvalNode
|
|
{
|
|
protected:
|
|
DWORD m_nValues;
|
|
// this data member MUST be the last in the class
|
|
// to allow an array size defined at runtime
|
|
// this array is always assumed to be sorted
|
|
QueryID m_trueIDs[1];
|
|
|
|
unsigned ORarrays(QueryID* pArray1, unsigned size1,
|
|
QueryID* pArray2, unsigned size2,
|
|
QueryID* pOutput);
|
|
|
|
unsigned ANDarrays(QueryID* pArray1, unsigned size1,
|
|
QueryID* pArray2, unsigned size2,
|
|
QueryID* pOutput);
|
|
|
|
unsigned CombineArrays(QueryID* pArray1, unsigned size1,
|
|
QueryID* pArray2, unsigned size2,
|
|
QueryID* pOutput);
|
|
|
|
|
|
// ctors moved to 'protected' to force callers to use the CreateNode function
|
|
CValueNode()
|
|
{}
|
|
|
|
CValueNode(int nNumValues);
|
|
virtual int GetType();
|
|
|
|
public:
|
|
|
|
virtual ~CValueNode();
|
|
static CValueNode* CreateNode(size_t nNumValues);
|
|
static CValueNode* CreateNode(CSortedArray& values);
|
|
|
|
void *operator new( size_t stAllocateBlock, unsigned nEntries = 0);
|
|
|
|
// VC 5 only allows one delete operator per class
|
|
#if _MSC_VER >= 1200
|
|
void operator delete( void *p, unsigned nEntries );
|
|
#endif
|
|
void operator delete(void* p) { ::delete[] (byte*)p; };
|
|
|
|
|
|
// changes all QueryID's to begin at newBase
|
|
// e.g. if the array is {0,1,5}
|
|
// Rebase(6) will change to {6,7,11}
|
|
|
|
DWORD GetNumTrues() {return m_nValues;}
|
|
void Rebase(QueryID newBase);
|
|
|
|
unsigned FindQueryID(QueryID n);
|
|
|
|
int GetAt(int nIndex)
|
|
{
|
|
if (FindQueryID(nIndex) != InvalidID)
|
|
return EVAL_VALUE_TRUE;
|
|
else
|
|
return EVAL_VALUE_FALSE;
|
|
}
|
|
|
|
bool IsAllFalse()
|
|
{
|
|
return (m_nValues == 0);
|
|
}
|
|
static bool IsAllFalse(CValueNode* pNode)
|
|
{
|
|
if (pNode)
|
|
return pNode->IsAllFalse();
|
|
else
|
|
return true;
|
|
}
|
|
|
|
static bool IsNoop(CValueNode* pNode, int nOp);
|
|
bool IsNoop(int nOp)
|
|
{
|
|
return IsNoop(this, nOp);
|
|
}
|
|
|
|
static bool AreAnyTrue(CValueNode* pNode)
|
|
{
|
|
if (pNode)
|
|
return (pNode->m_nValues > 0);
|
|
else
|
|
return false;
|
|
}
|
|
|
|
CEvalNode* Clone() const;
|
|
HRESULT CombineWith(CEvalNode* pArg2, int nOp,
|
|
CContextMetaData* pNamespace, CImplicationList& Implications,
|
|
bool bDeleteThis, bool bDeleteArg2, CEvalNode** ppRes);
|
|
int Compare(CEvalNode* pOther);
|
|
HRESULT TryShortCircuit(CEvalNode* pArg2, int nOp, bool bDeleteThis,
|
|
bool bDeleteArg2, CEvalNode** ppRes);
|
|
|
|
DWORD ApplyPredicate(CLeafPredicate* pPred) {return (*pPred)(this);}
|
|
|
|
bool RemoveQueryID(QueryID nQuery);
|
|
|
|
void CopyTruesTo(CSortedArray& trueIDs) const
|
|
{trueIDs.CopyDataFrom(m_trueIDs, m_nValues);}
|
|
|
|
void AddTruesTo(CSortedArray& trueIDs) const
|
|
{
|
|
int nWasSize = trueIDs.Size();
|
|
if(nWasSize == 0)
|
|
trueIDs.CopyDataFrom((QueryID*)&m_trueIDs, m_nValues);
|
|
else if (m_nValues > 0)
|
|
trueIDs.AddDataFrom((QueryID*)&m_trueIDs, m_nValues);
|
|
}
|
|
|
|
|
|
static CValueNode* GetStandardTrue();
|
|
static CValueNode* GetStandardFalse() { return NULL; };
|
|
static CValueNode* GetStandardInvalid();
|
|
|
|
virtual CImplicationList* GetExtraImplications() {return NULL;}
|
|
virtual HRESULT SetExtraImplications(CImplicationList* pList)
|
|
{
|
|
// CValueNodes don't use or need this, so just delete it.
|
|
delete pList;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
virtual HRESULT Project(CContextMetaData* pMeta,
|
|
CImplicationList& Implications,
|
|
CProjectionFilter* pFilter,
|
|
EProjectionType eType, bool bDeleteThis,
|
|
CEvalNode** ppNewNode);
|
|
|
|
virtual void Dump(FILE* f, int nOffset);
|
|
};
|
|
|
|
class CInvalidNode : public CValueNode
|
|
{
|
|
public:
|
|
CInvalidNode() : CValueNode(0){}
|
|
|
|
bool IsInvalid() {return true;}
|
|
void Dump(FILE* f, int nOffset);
|
|
};
|
|
|
|
|
|
|
|
// Contains information about the portion of the node exclusing the last
|
|
// component of the property name
|
|
|
|
class CEmbeddingInfo
|
|
{
|
|
protected:
|
|
CPropertyName m_EmbeddedObjPropName;
|
|
|
|
long m_lStartingObjIndex;
|
|
long m_lNumJumps;
|
|
|
|
struct JumpInfo {
|
|
long lJump;
|
|
long lTarget;
|
|
}* m_aJumps;
|
|
|
|
public:
|
|
CEmbeddingInfo();
|
|
CEmbeddingInfo(const CEmbeddingInfo& Other);
|
|
~CEmbeddingInfo();
|
|
void operator=(const CEmbeddingInfo& Other);
|
|
|
|
CPropertyName* GetEmbeddedObjPropName() {return &m_EmbeddedObjPropName;}
|
|
void SetEmbeddedObjPropName(CPropertyName& Name)
|
|
{m_EmbeddedObjPropName = Name;}
|
|
|
|
bool SetPropertyNameButLast(const CPropertyName& Name);
|
|
|
|
BOOL operator==(const CEmbeddingInfo& Other);
|
|
BOOL operator!=(const CEmbeddingInfo& Other)
|
|
{return !(*this == Other);}
|
|
|
|
HRESULT Compile(CContextMetaData* pNamespace,
|
|
CImplicationList& Implications,
|
|
_IWmiObject** ppResultClass);
|
|
HRESULT GetContainerObject(CObjectInfo& ObjInfo,
|
|
INTERNAL _IWmiObject** ppInst);
|
|
int ComparePrecedence(const CEmbeddingInfo* pOther);
|
|
bool AreJumpsRelated( const CEmbeddingInfo* pInfo );
|
|
bool MixInJumps(const CEmbeddingInfo* pInfo );
|
|
bool IsEmpty() const;
|
|
void Dump(FILE* f);
|
|
};
|
|
|
|
|
|
// A node that is interested in the implications that have accrued
|
|
|
|
class CNodeWithImplications : public CEvalNode
|
|
{
|
|
protected:
|
|
CImplicationList* m_pExtraImplications;
|
|
|
|
private :
|
|
CNodeWithImplications& operator=( const CNodeWithImplications& ); // notimpl
|
|
|
|
public:
|
|
CNodeWithImplications() : m_pExtraImplications(NULL){}
|
|
CNodeWithImplications(const CNodeWithImplications& Other);
|
|
~CNodeWithImplications()
|
|
{
|
|
delete m_pExtraImplications;
|
|
}
|
|
|
|
virtual CImplicationList* GetExtraImplications()
|
|
{
|
|
return m_pExtraImplications;
|
|
}
|
|
virtual HRESULT SetExtraImplications(ACQUIRE CImplicationList* pList)
|
|
{
|
|
if(m_pExtraImplications)
|
|
delete m_pExtraImplications;
|
|
m_pExtraImplications = pList;
|
|
return S_OK;
|
|
}
|
|
void Dump(FILE* f, int nOffset);
|
|
};
|
|
|
|
|
|
class CBranchIterator
|
|
{
|
|
public:
|
|
virtual ~CBranchIterator(){}
|
|
virtual INTERNAL CEvalNode* GetNode() = 0;
|
|
virtual void SetNode(ACQUIRE CEvalNode* pNode) = 0;
|
|
|
|
virtual bool IsValid() = 0;
|
|
virtual void Advance() = 0;
|
|
|
|
virtual HRESULT RecordBranch(CContextMetaData* pMeta,
|
|
CImplicationList& Implications) = 0;
|
|
};
|
|
|
|
// A node with a test and a whole bunch of branches, including a special one for
|
|
// the case where the thing being tested was NULL
|
|
|
|
class CBranchingNode : public CNodeWithImplications
|
|
{
|
|
// protected:
|
|
public: // because I don't know how to make a template a friend
|
|
CUniquePointerArray<CEvalNode> m_apBranches;
|
|
CEvalNode* m_pNullBranch;
|
|
|
|
CEmbeddingInfo* m_pInfo;
|
|
|
|
protected:
|
|
void operator=(const CBranchingNode& Other);
|
|
HRESULT CompileEmbeddingPortion(CContextMetaData* pNamespace,
|
|
CImplicationList& Implications,
|
|
_IWmiObject** ppResultClass)
|
|
{
|
|
if (!m_pInfo)
|
|
return WBEM_S_NO_ERROR;
|
|
else
|
|
return m_pInfo->Compile(pNamespace, Implications, ppResultClass);
|
|
}
|
|
|
|
HRESULT GetContainerObject(CObjectInfo& ObjInfo,
|
|
INTERNAL _IWmiObject** ppInst)
|
|
{
|
|
if (!m_pInfo)
|
|
{
|
|
// this SEEMS to be the behavior of the code prior to changes
|
|
*ppInst = ObjInfo.GetObjectAt(0);
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
else
|
|
return m_pInfo->GetContainerObject(ObjInfo, ppInst);
|
|
}
|
|
|
|
bool SetEmbeddedObjPropName(CPropertyName& Name);
|
|
bool MixInJumps(const CEmbeddingInfo* pInfo);
|
|
|
|
HRESULT StoreBranchImplications(CContextMetaData* pNamespace,
|
|
int nBranchIndex, CEvalNode* pResult);
|
|
public:
|
|
CBranchingNode();
|
|
CBranchingNode(const CBranchingNode& Other, BOOL bChildren = TRUE);
|
|
~CBranchingNode();
|
|
|
|
virtual int GetType();
|
|
virtual long GetSubType() = 0;
|
|
CUniquePointerArray<CEvalNode>& GetBranches() {return m_apBranches;}
|
|
CEvalNode* GetNullBranch() {return m_pNullBranch;}
|
|
void SetNullBranch(CEvalNode* pBranch);
|
|
CPropertyName* GetEmbeddedObjPropName()
|
|
{
|
|
if (!m_pInfo)
|
|
return NULL;
|
|
else
|
|
return m_pInfo->GetEmbeddedObjPropName();
|
|
}
|
|
|
|
virtual DWORD ApplyPredicate(CLeafPredicate* pPred);
|
|
virtual DELETE_ME CBranchIterator* GetBranchIterator();
|
|
|
|
virtual int ComparePrecedence(CBranchingNode* pOther) = 0;
|
|
virtual int Compare(CEvalNode* pNode);
|
|
virtual int SubCompare(CEvalNode* pNode) = 0;
|
|
|
|
virtual HRESULT Evaluate(CObjectInfo& ObjInfo,
|
|
INTERNAL CEvalNode** ppNext) = 0;
|
|
virtual HRESULT CombineBranchesWith(CBranchingNode* pArg2, int nOp,
|
|
CContextMetaData* pNamespace,
|
|
CImplicationList& Implications,
|
|
bool bDeleteThis, bool bDeleteArg2,
|
|
CEvalNode** ppRes) = 0;
|
|
virtual HRESULT RecordBranch(CContextMetaData* pNamespace,
|
|
CImplicationList& Implications,
|
|
long lBranchIndex)
|
|
{return WBEM_S_NO_ERROR;}
|
|
virtual HRESULT OptimizeSelf() {return WBEM_S_NO_ERROR;}
|
|
|
|
HRESULT AdjustCompile(CContextMetaData* pNamespace,
|
|
CImplicationList& Implications)
|
|
{
|
|
if (!m_pInfo)
|
|
return WBEM_S_NO_ERROR;
|
|
else
|
|
return m_pInfo->Compile(pNamespace, Implications, NULL);
|
|
}
|
|
|
|
HRESULT CombineWith(CEvalNode* pArg2, int nOp,
|
|
CContextMetaData* pNamespace,
|
|
CImplicationList& Implications,
|
|
bool bDeleteThis, bool bDeleteArg2,
|
|
CEvalNode** ppRes);
|
|
virtual HRESULT CombineInOrderWith(CEvalNode* pArg2,
|
|
int nOp, CContextMetaData* pNamespace,
|
|
CImplicationList& OrigImplications,
|
|
bool bDeleteThis, bool bDeleteArg2,
|
|
CEvalNode** ppRes);
|
|
virtual HRESULT Optimize(CContextMetaData* pNamespace, CEvalNode** ppNew);
|
|
BOOL AreAllSame(CEvalNode** apNodes, int nSize, int* pnFoundIndex);
|
|
static int ComparePrecedence(CBranchingNode* pArg1, CBranchingNode* pArg2);
|
|
|
|
HRESULT Project(CContextMetaData* pMeta, CImplicationList& Implications,
|
|
CProjectionFilter* pFilter, EProjectionType eType,
|
|
bool bDeleteThis, CEvalNode** ppNewNode);
|
|
void Dump(FILE* f, int nOffset);
|
|
#ifdef CHECK_TREES
|
|
virtual void CheckNode(CTreeChecker *pCheck);
|
|
#endif
|
|
friend class CDefaultBranchIterator;
|
|
};
|
|
|
|
class CDefaultBranchIterator : public CBranchIterator
|
|
{
|
|
protected:
|
|
CBranchingNode* m_pNode;
|
|
int m_nIndex;
|
|
|
|
public:
|
|
CDefaultBranchIterator(CBranchingNode* pNode) : m_pNode(pNode), m_nIndex(-1)
|
|
{}
|
|
|
|
virtual INTERNAL CEvalNode* GetNode()
|
|
{
|
|
if(m_nIndex == -1)
|
|
return m_pNode->m_pNullBranch;
|
|
else
|
|
return m_pNode->m_apBranches[m_nIndex];
|
|
}
|
|
virtual void SetNode(ACQUIRE CEvalNode* pNode)
|
|
{
|
|
CEvalNode* pOld;
|
|
if(m_nIndex == -1)
|
|
m_pNode->m_pNullBranch = pNode;
|
|
else
|
|
m_pNode->m_apBranches.SetAt(m_nIndex, pNode, &pOld);
|
|
}
|
|
|
|
virtual bool IsValid() { return m_nIndex < m_pNode->m_apBranches.GetSize();}
|
|
virtual void Advance() { m_nIndex++;}
|
|
virtual HRESULT RecordBranch(CContextMetaData* pMeta,
|
|
CImplicationList& Implications)
|
|
{
|
|
return m_pNode->RecordBranch(pMeta, Implications, m_nIndex);
|
|
}
|
|
};
|
|
|
|
|
|
|
|
|
|
// The node where a property is tested against a value. The property is
|
|
// identified by a handle
|
|
class CPropertyNode : public CBranchingNode
|
|
{
|
|
protected:
|
|
long m_lPropHandle;
|
|
WString m_wsPropName;
|
|
|
|
private:
|
|
CPropertyNode& operator=( const CPropertyNode& ); // notimpl
|
|
|
|
public:
|
|
CPropertyNode()
|
|
: m_lPropHandle(-1)
|
|
{}
|
|
CPropertyNode(const CPropertyNode& Other, BOOL bChildren = TRUE)
|
|
: CBranchingNode(Other, bChildren), m_lPropHandle(Other.m_lPropHandle),
|
|
m_wsPropName(Other.m_wsPropName)
|
|
{}
|
|
virtual ~CPropertyNode(){}
|
|
|
|
virtual int ComparePrecedence(CBranchingNode* pOther);
|
|
bool SetPropertyInfo(LPCWSTR wszPropName, long lPropHandle);
|
|
LPCWSTR GetPropertyName() {return m_wsPropName;}
|
|
bool SetEmbeddingInfo(const CEmbeddingInfo* pInfo);
|
|
virtual HRESULT SetNullTest(int nOperator);
|
|
virtual HRESULT SetOperator(int nOperator);
|
|
|
|
virtual HRESULT SetTest(VARIANT& v) = 0;
|
|
};
|
|
|
|
// An element in the array of test points
|
|
template<class TPropType>
|
|
struct CTestPoint
|
|
{
|
|
TPropType m_Test;
|
|
CEvalNode* m_pLeftOf;
|
|
CEvalNode* m_pAt;
|
|
|
|
CTestPoint() : m_pLeftOf(NULL), m_pAt(NULL){}
|
|
void Destruct() {delete m_pLeftOf; delete m_pAt;}
|
|
};
|
|
|
|
template<class TPropType>
|
|
struct CTestPointCompare
|
|
{
|
|
typedef CTestPoint<TPropType> TTestPoint;
|
|
|
|
inline int Compare(const TPropType& t, const TTestPoint& p) const
|
|
{
|
|
if(t < p.m_Test)
|
|
return -1;
|
|
else if(t == p.m_Test)
|
|
return 0;
|
|
else return 1;
|
|
}
|
|
inline int Compare(const TPropType& t1, const TPropType& t2) const
|
|
{
|
|
if(t1 < t2)
|
|
return -1;
|
|
else if(t1 == t2)
|
|
return 0;
|
|
else return 1;
|
|
}
|
|
inline int Compare(const TTestPoint& p1, const TTestPoint& p2) const
|
|
{
|
|
return Compare(p1.m_Test, p2);
|
|
}
|
|
inline const TPropType& Extract(const TTestPoint& p) const
|
|
{
|
|
return p.m_Test;
|
|
}
|
|
};
|
|
|
|
template<class TPropType>
|
|
struct CTestPointManager
|
|
{
|
|
typedef CTestPoint<TPropType> TTestPoint;
|
|
|
|
void AddRefElement(TTestPoint& p){}
|
|
void ReleaseElement(TTestPoint& p) {p.Destruct();}
|
|
};
|
|
|
|
template<class TPropType>
|
|
class CFullCompareNode : public CPropertyNode
|
|
{
|
|
// protected:
|
|
public: // because I can't make a template a friend of this one??
|
|
typedef CSmartSortedTree<
|
|
TPropType,
|
|
CTestPoint<TPropType>,
|
|
CTestPointManager<TPropType>,
|
|
CTestPointCompare<TPropType> > TTestPointArray;
|
|
|
|
typedef typename TTestPointArray::TIterator TTestPointIterator;
|
|
typedef typename TTestPointArray::TConstIterator TConstTestPointIterator;
|
|
TTestPointArray m_aTestPoints;
|
|
CEvalNode* m_pRightMost;
|
|
|
|
public:
|
|
CFullCompareNode() : m_pRightMost(NULL)
|
|
{}
|
|
CFullCompareNode(const CFullCompareNode<TPropType>& Other,
|
|
BOOL bChildren = TRUE);
|
|
virtual ~CFullCompareNode();
|
|
|
|
HRESULT CombineBranchesWith(CBranchingNode* pArg2, int nOp,
|
|
CContextMetaData* pNamespace,
|
|
CImplicationList& Implications,
|
|
bool bDeleteThis, bool bDeleteArg2,
|
|
CEvalNode** ppRes);
|
|
HRESULT CombineInOrderWith(CEvalNode* pArg2,
|
|
int nOp, CContextMetaData* pNamespace,
|
|
CImplicationList& OrigImplications,
|
|
bool bDeleteThis, bool bDeleteArg2,
|
|
CEvalNode** ppRes);
|
|
int SubCompare(CEvalNode* pOther);
|
|
virtual HRESULT OptimizeSelf();
|
|
virtual HRESULT SetTest(VARIANT& v);
|
|
|
|
virtual DWORD ApplyPredicate(CLeafPredicate* pPred);
|
|
virtual DELETE_ME CBranchIterator* GetBranchIterator()
|
|
{
|
|
return new CFullCompareBranchIterator<TPropType>(this);
|
|
}
|
|
virtual HRESULT Optimize(CContextMetaData* pNamespace, CEvalNode** ppNew);
|
|
HRESULT SetNullTest(int nOperator);
|
|
HRESULT SetOperator(int nOperator);
|
|
|
|
protected:
|
|
HRESULT CombineWithBranchesToLeft(
|
|
TTestPointIterator itWalk, TTestPointIterator itLast,
|
|
CEvalNode* pArg2,
|
|
int nOp, CContextMetaData* pNamespace,
|
|
CImplicationList& OrigImplications);
|
|
HRESULT InsertLess(
|
|
TTestPointIterator it,
|
|
TTestPointIterator it2, TTestPointIterator& itLast,
|
|
int nOp, CContextMetaData* pNamespace,
|
|
CImplicationList& OrigImplications, bool bDeleteArg2);
|
|
HRESULT InsertMatching(
|
|
TTestPointIterator it,
|
|
TTestPointIterator it2, TTestPointIterator& itLast,
|
|
int nOp, CContextMetaData* pNamespace,
|
|
CImplicationList& OrigImplications, bool bDeleteArg2);
|
|
|
|
};
|
|
|
|
template<class TPropType>
|
|
class CFullCompareBranchIterator : public CBranchIterator
|
|
{
|
|
protected:
|
|
CFullCompareNode<TPropType>* m_pNode;
|
|
typename CFullCompareNode<TPropType>::TTestPointIterator m_it;
|
|
typename CFullCompareNode<TPropType>::TTestPointIterator m_itEnd;
|
|
bool m_bLeft;
|
|
bool m_bValid;
|
|
|
|
public:
|
|
CFullCompareBranchIterator(CFullCompareNode<TPropType>* pNode)
|
|
: m_pNode(pNode), m_it(pNode->m_aTestPoints.Begin()), m_bLeft(true),
|
|
m_itEnd(pNode->m_aTestPoints.End()), m_bValid(true)
|
|
{}
|
|
|
|
virtual INTERNAL CEvalNode* GetNode()
|
|
{
|
|
if(m_it == m_itEnd)
|
|
{
|
|
if(m_bLeft)
|
|
return m_pNode->m_pRightMost;
|
|
else
|
|
return m_pNode->m_pNullBranch;
|
|
}
|
|
else
|
|
{
|
|
if(m_bLeft)
|
|
return m_it->m_pLeftOf;
|
|
else
|
|
return m_it->m_pAt;
|
|
}
|
|
}
|
|
virtual void SetNode(ACQUIRE CEvalNode* pNode)
|
|
{
|
|
if(m_it == m_itEnd)
|
|
{
|
|
if(m_bLeft)
|
|
m_pNode->m_pRightMost = pNode;
|
|
else
|
|
m_pNode->m_pNullBranch = pNode;
|
|
}
|
|
else
|
|
{
|
|
if(m_bLeft)
|
|
m_it->m_pLeftOf = pNode;
|
|
else
|
|
m_it->m_pAt = pNode;
|
|
}
|
|
}
|
|
|
|
virtual bool IsValid() { return m_bValid;}
|
|
virtual void Advance()
|
|
{
|
|
if(m_bLeft)
|
|
m_bLeft = false;
|
|
else if(m_it == m_itEnd)
|
|
m_bValid = false;
|
|
else
|
|
{
|
|
m_it++;
|
|
m_bLeft = true;
|
|
}
|
|
}
|
|
virtual HRESULT RecordBranch(CContextMetaData* pMeta,
|
|
CImplicationList& Implications)
|
|
{
|
|
return S_OK; // fullcompare nodes don't have implications
|
|
}
|
|
};
|
|
|
|
|
|
|
|
template<class TPropType>
|
|
class CScalarPropNode : public CFullCompareNode<TPropType>
|
|
{
|
|
public:
|
|
CScalarPropNode() : CFullCompareNode<TPropType>()
|
|
{}
|
|
CScalarPropNode(const CScalarPropNode<TPropType>& Other,
|
|
BOOL bChildren = TRUE)
|
|
: CFullCompareNode<TPropType>(Other, bChildren)
|
|
{}
|
|
virtual ~CScalarPropNode(){}
|
|
|
|
virtual long GetSubType() {return EVAL_NODE_TYPE_SCALAR; }
|
|
virtual HRESULT Evaluate(CObjectInfo& ObjInfo, INTERNAL CEvalNode** ppNext);
|
|
virtual CEvalNode* Clone() const
|
|
{return new CScalarPropNode<TPropType>(*this);}
|
|
virtual CBranchingNode* CloneSelf() const
|
|
{return new CScalarPropNode<TPropType>(*this, FALSE);}
|
|
virtual void Dump(FILE* f, int nOffset);
|
|
};
|
|
|
|
class CStringPropNode : public CFullCompareNode<CInternalString>
|
|
{
|
|
public:
|
|
CStringPropNode()
|
|
: CFullCompareNode<CInternalString>()
|
|
{}
|
|
CStringPropNode(const CStringPropNode& Other, BOOL bChildren = TRUE);
|
|
virtual ~CStringPropNode();
|
|
|
|
virtual long GetSubType() { return EVAL_NODE_TYPE_STRING; }
|
|
|
|
virtual HRESULT Evaluate(CObjectInfo& ObjInfo, INTERNAL CEvalNode** ppNext);
|
|
virtual CEvalNode* Clone() const {return new CStringPropNode(*this);}
|
|
virtual CBranchingNode* CloneSelf() const
|
|
{return new CStringPropNode(*this, FALSE);}
|
|
virtual void Dump(FILE* f, int nOffset);
|
|
};
|
|
|
|
class CLikeStringPropNode : public CPropertyNode
|
|
{
|
|
protected:
|
|
|
|
CLike m_Like;
|
|
|
|
private:
|
|
CLikeStringPropNode& operator=( const CLikeStringPropNode& ); // notimpl
|
|
|
|
public:
|
|
|
|
CLikeStringPropNode() {} ;
|
|
CLikeStringPropNode(const CLikeStringPropNode& Other, BOOL bChildren=TRUE);
|
|
|
|
virtual long GetSubType() { return EVAL_NODE_TYPE_LIKE_STRING; }
|
|
|
|
virtual int ComparePrecedence(CBranchingNode* pNode);
|
|
virtual int SubCompare(CEvalNode* pNode);
|
|
|
|
virtual HRESULT SetTest( VARIANT& v );
|
|
|
|
virtual HRESULT Evaluate( CObjectInfo& ObjInfo, CEvalNode** ppNext );
|
|
|
|
virtual HRESULT CombineBranchesWith( CBranchingNode* pArg2, int nOp,
|
|
CContextMetaData* pNamespace,
|
|
CImplicationList& Implications,
|
|
bool bDeleteThis, bool bDeleteArg2,
|
|
CEvalNode** ppRes );
|
|
virtual HRESULT OptimizeSelf();
|
|
|
|
virtual CEvalNode* Clone() const {return new CLikeStringPropNode(*this);}
|
|
virtual CBranchingNode* CloneSelf() const
|
|
{return new CLikeStringPropNode(*this, FALSE);}
|
|
virtual void Dump(FILE* f, int nOffset);
|
|
};
|
|
|
|
|
|
class CInheritanceNode : public CBranchingNode
|
|
{
|
|
protected:
|
|
long m_lDerivationIndex;
|
|
|
|
long m_lNumPoints;
|
|
CCompressedString** m_apcsTestPoints;
|
|
|
|
private:
|
|
CInheritanceNode& operator= ( const CInheritanceNode& Other ); // notimpl
|
|
|
|
public:
|
|
CInheritanceNode();
|
|
CInheritanceNode(const CInheritanceNode& Other, BOOL bChildren = TRUE);
|
|
virtual ~CInheritanceNode();
|
|
|
|
virtual long GetSubType();
|
|
virtual HRESULT Evaluate(CObjectInfo& ObjInfo, INTERNAL CEvalNode** ppNext);
|
|
virtual int ComparePrecedence(CBranchingNode* pOther);
|
|
virtual CEvalNode* Clone() const {return new CInheritanceNode(*this);}
|
|
virtual CBranchingNode* CloneSelf() const
|
|
{return new CInheritanceNode(*this, FALSE);}
|
|
virtual HRESULT Compile(CContextMetaData* pNamespace,
|
|
CImplicationList& Implications);
|
|
virtual HRESULT CombineBranchesWith(CBranchingNode* pArg2, int nOp,
|
|
CContextMetaData* pNamespace,
|
|
CImplicationList& Implications,
|
|
bool bDeleteThis, bool bDeleteArg2,
|
|
CEvalNode** ppRes);
|
|
virtual HRESULT RecordBranch(CContextMetaData* pNamespace,
|
|
CImplicationList& Implications,
|
|
long lBranchIndex);
|
|
virtual int SubCompare(CEvalNode* pOther);
|
|
virtual HRESULT OptimizeSelf();
|
|
HRESULT Optimize(CContextMetaData* pNamespace, CEvalNode** ppNew);
|
|
void RemoveTestPoint(int nIndex);
|
|
HRESULT Project(CContextMetaData* pMeta, CImplicationList& Implications,
|
|
CProjectionFilter* pFilter,
|
|
EProjectionType eType, bool bDeleteThis,
|
|
CEvalNode** ppNewNode);
|
|
virtual void Dump(FILE* f, int nOffset);
|
|
public:
|
|
HRESULT AddClass(CContextMetaData* pNamespace, LPCWSTR wszClassName,
|
|
CEvalNode* pDestination);
|
|
HRESULT AddClass(CContextMetaData* pNamespace,
|
|
LPCWSTR wszClassName, _IWmiObject* pClass,
|
|
CEvalNode* pDestination);
|
|
bool SetPropertyInfo(CContextMetaData* pNamespace, CPropertyName& PropName);
|
|
protected:
|
|
void RemoveAllTestPoints();
|
|
|
|
HRESULT ComputeUsageForMerge(CInheritanceNode* pArg2,
|
|
CContextMetaData* pNamespace,
|
|
CImplicationList& OrigImplications,
|
|
bool bDeleteThis, bool bDeleteArg2,
|
|
DWORD* pdwFirstNoneCount,
|
|
DWORD* pdwSecondNoneCount,
|
|
bool* pbBothNonePossible);
|
|
|
|
};
|
|
|
|
class COrNode : public CNodeWithImplications
|
|
{
|
|
protected:
|
|
CUniquePointerArray<CEvalNode> m_apBranches;
|
|
|
|
void operator=(const COrNode& Other);
|
|
|
|
public:
|
|
COrNode(){}
|
|
COrNode(const COrNode& Other) {*this = Other;}
|
|
virtual ~COrNode(){}
|
|
HRESULT AddBranch(CEvalNode* pNewBranch);
|
|
|
|
virtual int GetType() {return EVAL_NODE_TYPE_OR;}
|
|
virtual CEvalNode* Clone() const {return new COrNode(*this);}
|
|
|
|
virtual HRESULT CombineWith(CEvalNode* pArg2, int nOp,
|
|
CContextMetaData* pNamespace, CImplicationList& Implications,
|
|
bool bDeleteThis, bool bDeleteArg2, CEvalNode** ppRes);
|
|
virtual int Compare(CEvalNode* pOther);
|
|
virtual DWORD ApplyPredicate(CLeafPredicate* pPred);
|
|
virtual void Dump(FILE* f, int nOffset);
|
|
virtual HRESULT Evaluate(CObjectInfo& Info, CSortedArray& trueIDs);
|
|
virtual HRESULT Optimize(CContextMetaData* pNamespace, CEvalNode** ppNew);
|
|
HRESULT Project(CContextMetaData* pMeta, CImplicationList& Implications,
|
|
CProjectionFilter* pFilter,
|
|
EProjectionType eType, bool bDeleteThis,
|
|
CEvalNode** ppNewNode);
|
|
|
|
protected:
|
|
HRESULT CombineWithOrNode(COrNode* pArg2, int nOp,
|
|
CContextMetaData* pNamespace, CImplicationList& Implications,
|
|
bool bDeleteThis, bool bDeleteArg2, CEvalNode** ppRes);
|
|
};
|
|
|
|
|
|
class ESSCLI_POLARITY CEvalTree
|
|
{
|
|
protected:
|
|
long m_lRef;
|
|
CCritSec m_cs;
|
|
|
|
CEvalNode* m_pStart;
|
|
CObjectInfo m_ObjectInfo;
|
|
int m_nNumValues;
|
|
|
|
protected:
|
|
class CRemoveIndexPredicate : public CLeafPredicate
|
|
{
|
|
protected:
|
|
int m_nIndex;
|
|
public:
|
|
CRemoveIndexPredicate(int nIndex) : m_nIndex(nIndex){}
|
|
DWORD operator()(CValueNode* pLeaf);
|
|
};
|
|
|
|
class CRemoveFailureAtIndexPredicate : public CLeafPredicate
|
|
{
|
|
protected:
|
|
int m_nIndex;
|
|
public:
|
|
CRemoveFailureAtIndexPredicate(int nIndex) : m_nIndex(nIndex){}
|
|
DWORD operator()(CValueNode* pLeaf);
|
|
};
|
|
|
|
class CRebasePredicate : public CLeafPredicate
|
|
{
|
|
public:
|
|
CRebasePredicate(QueryID newBase) :
|
|
m_newBase(newBase)
|
|
{}
|
|
|
|
virtual DWORD operator()(class CValueNode* pLeaf);
|
|
|
|
private:
|
|
QueryID m_newBase;
|
|
};
|
|
|
|
|
|
protected:
|
|
static HRESULT InnerCombine(CEvalNode* pArg1, CEvalNode* pArg2, int nOp,
|
|
CContextMetaData* pNamespace,
|
|
CImplicationList& Implications,
|
|
bool bDeleteArg1, bool bDeleteArg2, CEvalNode** ppRes);
|
|
public:
|
|
CEvalTree();
|
|
CEvalTree(const CEvalTree& Other);
|
|
~CEvalTree();
|
|
void operator=(const CEvalTree& Other);
|
|
|
|
bool SetBool(BOOL bVal);
|
|
bool IsFalse();
|
|
bool IsValid();
|
|
|
|
HRESULT CreateFromQuery(CContextMetaData* pNamespace,
|
|
LPCWSTR wszQuery,
|
|
long lFlags,
|
|
long lMaxTokens = MAX_TOKENS_IN_DNF );
|
|
|
|
HRESULT CreateFromQuery(CContextMetaData* pNamespace,
|
|
QL_LEVEL_1_RPN_EXPRESSION* pQuery, long lFlags,
|
|
long lMaxTokens = MAX_TOKENS_IN_DNF );
|
|
|
|
HRESULT CreateFromQuery(CContextMetaData* pNamespace,
|
|
LPCWSTR wszClassName, int nNumTokens,
|
|
QL_LEVEL_1_TOKEN* apTokens, long lFlags,
|
|
long lMaxTokens = MAX_TOKENS_IN_DNF );
|
|
|
|
static HRESULT CreateFromConjunction(CContextMetaData* pNamespace,
|
|
CImplicationList& Implications,
|
|
CConjunction* pConj,
|
|
CEvalNode** ppRes);
|
|
HRESULT CreateFromDNF(CContextMetaData* pNamespace,
|
|
CImplicationList& Implications,
|
|
CDNFExpression* pDNF,
|
|
CEvalNode** ppRes);
|
|
HRESULT CombineWith(CEvalTree& Other, CContextMetaData* pNamespace,
|
|
int nOp, long lFlags = 0);
|
|
|
|
HRESULT Optimize(CContextMetaData* pNamespace);
|
|
HRESULT Evaluate(IWbemObjectAccess* pObj, CSortedArray& aTrues);
|
|
static HRESULT Evaluate(CObjectInfo& Info, CEvalNode* pStart,
|
|
CSortedArray& trueIDs);
|
|
static HRESULT Combine(CEvalNode* pArg1, CEvalNode* pArg2, int nOp,
|
|
CContextMetaData* pNamespace,
|
|
CImplicationList& Implications,
|
|
bool bDeleteArg1, bool bDeleteArg2, CEvalNode** ppRes);
|
|
static HRESULT CombineInOrder(CBranchingNode* pArg1, CEvalNode* pArg2,
|
|
int nOp,
|
|
CContextMetaData* pNamespace,
|
|
CImplicationList& Implications,
|
|
bool bDeleteArg1, bool bDeleteArg2,
|
|
CEvalNode** ppRes);
|
|
static HRESULT IsMergeAdvisable(CEvalNode* pArg1, CEvalNode* pArg2,
|
|
CImplicationList& Implications);
|
|
static HRESULT BuildFromToken(CContextMetaData* pNamespace,
|
|
CImplicationList& Implications,
|
|
QL_LEVEL_1_TOKEN& Token, CEvalNode** ppRes);
|
|
|
|
static HRESULT BuildTwoPropFromToken(CContextMetaData* pNamespace,
|
|
CImplicationList& Implications,
|
|
QL_LEVEL_1_TOKEN& Token, CEvalNode** ppRes);
|
|
|
|
|
|
static int Compare(CEvalNode* pArg1, CEvalNode* pArg2);
|
|
|
|
HRESULT RemoveIndex(int nIndex);
|
|
HRESULT UtilizeGuarantee(CEvalTree& Guaranteed,
|
|
CContextMetaData* pNamespace);
|
|
HRESULT ApplyPredicate(CLeafPredicate* pPred);
|
|
static inline bool IsNotEmpty(CEvalNode* pNode);
|
|
|
|
void Rebase(QueryID newBase);
|
|
|
|
HRESULT CreateProjection(CEvalTree& Old, CContextMetaData* pMeta,
|
|
CProjectionFilter* pFilter,
|
|
EProjectionType eType, bool bDeleteOld);
|
|
static HRESULT Project(CContextMetaData* pMeta,
|
|
CImplicationList& Implications,
|
|
CEvalNode* pOldNode, CProjectionFilter* pFilter,
|
|
EProjectionType eType, bool bDeleteOld,
|
|
CEvalNode** ppNewNode);
|
|
bool Clear();
|
|
void Dump(FILE* f);
|
|
#ifdef CHECK_TREES
|
|
void CheckNodes(CTreeChecker *pCheck);
|
|
#endif
|
|
|
|
protected:
|
|
static HRESULT CombineLeafWithBranch(CValueNode* pArg1,
|
|
CBranchingNode* pArg2, int nOp,
|
|
CContextMetaData* pNamespace,
|
|
CImplicationList& Implications,
|
|
bool bDeleteArg1, bool bDeleteArg2,
|
|
CEvalNode** ppRes);
|
|
|
|
};
|
|
|
|
class ESSCLI_POLARITY CPropertyProjectionFilter : public CProjectionFilter
|
|
{
|
|
CUniquePointerArray<CPropertyName>* m_papProperties;
|
|
public:
|
|
CPropertyProjectionFilter();
|
|
~CPropertyProjectionFilter();
|
|
virtual bool IsInSet(CEvalNode* pNode);
|
|
|
|
bool AddProperty(const CPropertyName& Prop);
|
|
};
|
|
|
|
//#include "evaltree.inl"
|
|
HRESULT CoreGetNumParents(_IWmiObject* pClass, ULONG *plNumParents);
|
|
RELEASE_ME _IWmiObject* CoreGetEmbeddedObj(_IWmiObject* pObj, long lHandle);
|
|
INTERNAL CCompressedString* CoreGetPropertyString(_IWmiObject* pObj,
|
|
long lHandle);
|
|
INTERNAL CCompressedString* CoreGetClassInternal(_IWmiObject* pObj);
|
|
INTERNAL CCompressedString* CoreGetParentAtIndex(_IWmiObject* pObj,
|
|
long lIndex);
|
|
|
|
#endif
|