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.
432 lines
9.3 KiB
432 lines
9.3 KiB
/*++
|
|
|
|
Copyright (C) 1996-1999 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
WBEMDNF.CPP
|
|
|
|
Abstract:
|
|
|
|
WBEM Evaluation Tree
|
|
|
|
History:
|
|
|
|
--*/
|
|
|
|
#include "precomp.h"
|
|
#include <stdio.h>
|
|
#pragma warning(disable:4786)
|
|
#include <wbemcomn.h>
|
|
#include <genutils.h>
|
|
#include <wbemdnf.h>
|
|
|
|
HRESULT CDNFExpression::CreateFromTokens(QL_LEVEL_1_TOKEN*& pLastToken,
|
|
BOOL bNegate, long& lTokensAllowed)
|
|
{
|
|
HRESULT hres;
|
|
|
|
QL_LEVEL_1_TOKEN& Head = *pLastToken;
|
|
if(Head.nTokenType == QL1_OP_EXPRESSION)
|
|
{
|
|
if(lTokensAllowed <= 0)
|
|
return WBEM_E_QUOTA_VIOLATION;
|
|
else
|
|
lTokensAllowed--;
|
|
|
|
if(!CreateFromToken(Head, bNegate))
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
pLastToken--;
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
// Build arguments
|
|
// ===============
|
|
|
|
pLastToken--;
|
|
|
|
if(Head.nTokenType == QL1_NOT)
|
|
{
|
|
if(lTokensAllowed <= 0)
|
|
return WBEM_E_QUOTA_VIOLATION;
|
|
else
|
|
lTokensAllowed--;
|
|
|
|
hres = CreateFromTokens(pLastToken, !bNegate, lTokensAllowed);
|
|
return hres;
|
|
}
|
|
|
|
long lChildCount = lTokensAllowed;
|
|
|
|
CDNFExpression Arg1;
|
|
hres = Arg1.CreateFromTokens(pLastToken, bNegate, lChildCount);
|
|
if(FAILED(hres))
|
|
return hres;
|
|
|
|
CDNFExpression Arg2;
|
|
hres = Arg2.CreateFromTokens(pLastToken, bNegate, lChildCount);
|
|
if(FAILED(hres))
|
|
return hres;
|
|
|
|
if( Head.nTokenType == QL1_AND )
|
|
{
|
|
if ( !bNegate )
|
|
{
|
|
hres = CreateAnd( Arg1, Arg2, lTokensAllowed );
|
|
}
|
|
else
|
|
{
|
|
hres = CreateOr( Arg1, Arg2, lTokensAllowed );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if ( !bNegate )
|
|
{
|
|
hres = CreateOr( Arg1, Arg2, lTokensAllowed );
|
|
}
|
|
else
|
|
{
|
|
hres = CreateAnd( Arg1, Arg2, lTokensAllowed );
|
|
}
|
|
}
|
|
|
|
return hres;
|
|
}
|
|
|
|
HRESULT CDNFExpression::CreateAnd(CDNFExpression& Arg1, CDNFExpression& Arg2,
|
|
long& lTokensAllowed)
|
|
{
|
|
for(long lFirst = 0; lFirst < Arg1.GetNumTerms(); lFirst++)
|
|
{
|
|
for(long lSecond = 0; lSecond < Arg2.GetNumTerms(); lSecond++)
|
|
{
|
|
CConjunction* pNewTerm = NULL;
|
|
try
|
|
{
|
|
pNewTerm = new CConjunction(*Arg1.GetTermAt(lFirst),
|
|
*Arg2.GetTermAt(lSecond));
|
|
}
|
|
catch(...)
|
|
{
|
|
pNewTerm = NULL;
|
|
}
|
|
if(pNewTerm == NULL)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
long lTokens = pNewTerm->GetNumTokens();
|
|
if(lTokens > lTokensAllowed)
|
|
{
|
|
delete pNewTerm;
|
|
return WBEM_E_QUOTA_VIOLATION;
|
|
}
|
|
else
|
|
{
|
|
lTokensAllowed -= lTokens;
|
|
}
|
|
|
|
m_apTerms.Add(pNewTerm);
|
|
}
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CDNFExpression::CreateOr(CDNFExpression& Arg1, CDNFExpression& Arg2,
|
|
long& lTokensAllowed)
|
|
{
|
|
int i;
|
|
for(i = 0; i < Arg1.GetNumTerms(); i++)
|
|
{
|
|
CConjunction* pConj = NULL;
|
|
try
|
|
{
|
|
pConj = new CConjunction(*Arg1.GetTermAt(i));
|
|
}
|
|
catch(...)
|
|
{
|
|
pConj = NULL;
|
|
}
|
|
if(pConj == NULL)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
long lTokens = pConj->GetNumTokens();
|
|
if(lTokens > lTokensAllowed)
|
|
{
|
|
delete pConj;
|
|
return WBEM_E_QUOTA_VIOLATION;
|
|
}
|
|
else
|
|
{
|
|
lTokensAllowed -= lTokens;
|
|
}
|
|
|
|
m_apTerms.Add(pConj);
|
|
}
|
|
|
|
for(i = 0; i < Arg2.GetNumTerms(); i++)
|
|
{
|
|
CConjunction* pConj = NULL;
|
|
try
|
|
{
|
|
pConj = new CConjunction(*Arg2.GetTermAt(i));
|
|
}
|
|
catch(...)
|
|
{
|
|
pConj = NULL;
|
|
}
|
|
if(pConj == NULL)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
long lTokens = pConj->GetNumTokens();
|
|
if(lTokens > lTokensAllowed)
|
|
{
|
|
delete pConj;
|
|
return WBEM_E_QUOTA_VIOLATION;
|
|
}
|
|
else
|
|
{
|
|
lTokensAllowed -= lTokens;
|
|
}
|
|
|
|
m_apTerms.Add(pConj);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
BOOL CDNFExpression::CreateFromToken(QL_LEVEL_1_TOKEN& Token, BOOL bNegate)
|
|
{
|
|
try
|
|
{
|
|
CConjunction* pConj = new CConjunction(Token, bNegate);
|
|
if(pConj == NULL)
|
|
return FALSE;
|
|
if(m_apTerms.Add(pConj) < 0)
|
|
return FALSE;
|
|
}
|
|
catch(...)
|
|
{
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
void CDNFExpression::Sort()
|
|
{
|
|
for(int i = 0; i < m_apTerms.GetSize(); i++)
|
|
{
|
|
m_apTerms[i]->Sort();
|
|
}
|
|
}
|
|
|
|
HRESULT CDNFExpression::GetNecessaryProjection(CTokenFilter* pFilter,
|
|
CDNFExpression** ppResult)
|
|
{
|
|
*ppResult = NULL;
|
|
CDNFExpression* pResult = new CDNFExpression;
|
|
for(int i = 0; i < m_apTerms.GetSize(); i++)
|
|
{
|
|
CConjunction* pConj = NULL;
|
|
HRESULT hres = m_apTerms[i]->GetNecessaryProjection(pFilter, &pConj);
|
|
if(FAILED(hres))
|
|
{
|
|
delete pResult;
|
|
return hres;
|
|
}
|
|
|
|
if(pConj->GetNumTokens() == 0)
|
|
{
|
|
//
|
|
// This conjunction is empty, meaning that no necessary condition
|
|
// exists for the projection in question. That means that the
|
|
// entire projection is empty as well --- no restrictions.
|
|
//
|
|
|
|
pResult->m_apTerms.RemoveAll();
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
else
|
|
{
|
|
pResult->m_apTerms.Add(pConj);
|
|
}
|
|
}
|
|
|
|
*ppResult = pResult;
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
|
|
CReuseMemoryManager CConjunction::mstatic_Manager(sizeof CConjunction);
|
|
|
|
void *CConjunction::operator new(size_t nBlock)
|
|
{
|
|
return mstatic_Manager.Allocate();
|
|
}
|
|
void CConjunction::operator delete(void* p)
|
|
{
|
|
mstatic_Manager.Free(p);
|
|
}
|
|
|
|
CConjunction::CConjunction()
|
|
{
|
|
}
|
|
|
|
CConjunction::CConjunction(QL_LEVEL_1_TOKEN& Token, BOOL bNegate)
|
|
{
|
|
QL_LEVEL_1_TOKEN * pToken = new QL_LEVEL_1_TOKEN( Token );
|
|
|
|
if ( NULL == pToken )
|
|
{
|
|
throw CX_MemoryException();
|
|
}
|
|
|
|
m_apTokens.Add( pToken );
|
|
|
|
if(bNegate)
|
|
{
|
|
m_apTokens[0]->nOperator = NegateOperator(m_apTokens[0]->nOperator);
|
|
}
|
|
}
|
|
|
|
CConjunction::CConjunction(CConjunction& Other)
|
|
{
|
|
for(int i = 0; i < Other.GetNumTokens(); i++)
|
|
{
|
|
QL_LEVEL_1_TOKEN * pToken = new QL_LEVEL_1_TOKEN( *Other.GetTokenAt( i ) );
|
|
|
|
if ( NULL == pToken )
|
|
{
|
|
throw CX_MemoryException();
|
|
}
|
|
|
|
m_apTokens.Add( pToken );
|
|
}
|
|
}
|
|
|
|
CConjunction::CConjunction(CConjunction& Other1, CConjunction& Other2)
|
|
{
|
|
int i;
|
|
for(i = 0; i < Other1.GetNumTokens(); i++)
|
|
{
|
|
QL_LEVEL_1_TOKEN * pToken = new QL_LEVEL_1_TOKEN( *Other1.GetTokenAt( i ) );
|
|
|
|
if ( NULL == pToken )
|
|
{
|
|
throw CX_MemoryException();
|
|
}
|
|
|
|
m_apTokens.Add( pToken );
|
|
}
|
|
|
|
for(i = 0; i < Other2.GetNumTokens(); i++)
|
|
{
|
|
QL_LEVEL_1_TOKEN * pToken = new QL_LEVEL_1_TOKEN( *Other2.GetTokenAt( i ) );
|
|
|
|
if ( NULL == pToken )
|
|
{
|
|
throw CX_MemoryException();
|
|
}
|
|
|
|
m_apTokens.Add( pToken );
|
|
}
|
|
}
|
|
|
|
int CConjunction::NegateOperator(int nOperator)
|
|
{
|
|
switch(nOperator)
|
|
{
|
|
case QL1_OPERATOR_EQUALS:
|
|
return QL1_OPERATOR_NOTEQUALS;
|
|
|
|
case QL1_OPERATOR_NOTEQUALS:
|
|
return QL1_OPERATOR_EQUALS;
|
|
|
|
case QL1_OPERATOR_GREATER:
|
|
return QL1_OPERATOR_LESSOREQUALS;
|
|
|
|
case QL1_OPERATOR_LESS:
|
|
return QL1_OPERATOR_GREATEROREQUALS;
|
|
|
|
case QL1_OPERATOR_LESSOREQUALS:
|
|
return QL1_OPERATOR_GREATER;
|
|
|
|
case QL1_OPERATOR_GREATEROREQUALS:
|
|
return QL1_OPERATOR_LESS;
|
|
|
|
case QL1_OPERATOR_LIKE:
|
|
return QL1_OPERATOR_UNLIKE;
|
|
|
|
case QL1_OPERATOR_UNLIKE:
|
|
return QL1_OPERATOR_LIKE;
|
|
|
|
case QL1_OPERATOR_ISA:
|
|
return QL1_OPERATOR_ISNOTA;
|
|
|
|
case QL1_OPERATOR_ISNOTA:
|
|
return QL1_OPERATOR_ISA;
|
|
|
|
case QL1_OPERATOR_INV_ISA:
|
|
return QL1_OPERATOR_INV_ISNOTA;
|
|
|
|
case QL1_OPERATOR_INV_ISNOTA:
|
|
return QL1_OPERATOR_INV_ISA;
|
|
}
|
|
|
|
return nOperator;
|
|
}
|
|
|
|
|
|
#pragma optimize("", off)
|
|
|
|
void CConjunction::Sort()
|
|
{
|
|
int i = 0;
|
|
|
|
while(i < m_apTokens.GetSize() - 1)
|
|
{
|
|
int nLeft = m_apTokens[i]->PropertyName.GetNumElements();
|
|
int nRight = m_apTokens[i+1]->PropertyName.GetNumElements();
|
|
if(nLeft > nRight)
|
|
{
|
|
m_apTokens.Swap(i, i+1);
|
|
if(i != 0)
|
|
{
|
|
i--;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
i++;
|
|
}
|
|
}
|
|
}
|
|
#pragma optimize("", on)
|
|
|
|
|
|
// returns an empty conjunction if no necessary condition exists
|
|
HRESULT CConjunction::GetNecessaryProjection(CTokenFilter* pFilter,
|
|
CConjunction** ppResult)
|
|
{
|
|
*ppResult = NULL;
|
|
CConjunction* pResult = new CConjunction;
|
|
if(pResult == NULL)
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
|
|
for(int i = 0; i < m_apTokens.GetSize(); i++)
|
|
{
|
|
if(pFilter->IsRelevant(m_apTokens[i]))
|
|
{
|
|
if(!pResult->AddToken(m_apTokens[i]))
|
|
{
|
|
delete pResult;
|
|
return WBEM_E_OUT_OF_MEMORY;
|
|
}
|
|
}
|
|
}
|
|
|
|
*ppResult = pResult;
|
|
return WBEM_S_NO_ERROR;
|
|
}
|
|
|