Leaked source code of windows server 2003
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.
 
 
 
 
 
 

660 lines
14 KiB

#include "sqleval.h"
#include <stdio.h>
#include <genlex.h>
#include <sqllex.h>
#include <sql_1.h>
// CSqlWmiEvalee
CSqlWmiEvalee::~CSqlWmiEvalee()
{
if(m_pInstance)
m_pInstance->Release();
}
CSqlWmiEvalee::CSqlWmiEvalee(
IWbemClassObject* pInst)
:m_pInstance(NULL)
{
m_pInstance = pInst;
if(m_pInstance)
m_pInstance->AddRef();
VariantInit(&m_v);
}
const VARIANT*
CSqlWmiEvalee::Get(
WCHAR* wszName)
{
VariantClear(&m_v);
BSTR bstr = SysAllocString(wszName);
if (bstr != NULL)
{
SCODE sc = m_pInstance->Get(
bstr,
0,
&m_v,
NULL,
NULL);
SysFreeString(bstr);
if(sc != S_OK)
throw sc;
}
return &m_v;
}
// CSqlEval
CSqlEval*
CSqlEval::CreateClass(
SQL_LEVEL_1_RPN_EXPRESSION* pExpr,
int* pNumberOfToken)
{
if(pExpr== NULL || *pNumberOfToken<= 0)
return NULL;
SQL_LEVEL_1_TOKEN* pToken = pExpr->pArrayOfTokens+(*pNumberOfToken-1);
// (*pNumberOfToken)--;
switch(pToken->nTokenType)
{
case SQL_LEVEL_1_TOKEN::TOKEN_AND:
return new CSqlEvalAnd(
pExpr,
pNumberOfToken);
case SQL_LEVEL_1_TOKEN::TOKEN_OR:
return new CSqlEvalOr(
pExpr,
pNumberOfToken);
case SQL_LEVEL_1_TOKEN::OP_EXPRESSION:
return new CSqlEvalExp(
pExpr,
pNumberOfToken);
}
return NULL;
}
BOOL
CSqlEval::Evaluate(
CSqlEvalee* pInst)
{
return TRUE;
}
// CSqlEvalAnd
CSqlEvalAnd::~CSqlEvalAnd()
{
delete m_left;
delete m_right;
}
CSqlEvalAnd::CSqlEvalAnd(
SQL_LEVEL_1_RPN_EXPRESSION* pExpr,
int* pTokens)
:m_left(NULL),m_right(NULL)
{
(*pTokens)-- ;
m_left = CSqlEval::CreateClass(
pExpr,
pTokens);
m_right = CSqlEval::CreateClass(
pExpr,
pTokens);
}
BOOL
CSqlEvalAnd::Evaluate(
CSqlEvalee* pInst)
{
return m_left->Evaluate(pInst) && m_right->Evaluate(pInst);
}
void
CSqlEvalAnd::GenerateQueryEnum(CQueryEnumerator& qeInst)
{
CQueryEnumerator qeNew = qeInst;
m_left->GenerateQueryEnum(qeNew);
m_right->GenerateQueryEnum(qeInst);
qeInst.And(qeNew);
}
// CSqlEvalOR
CSqlEvalOr::~CSqlEvalOr()
{
delete m_left;
delete m_right;
}
CSqlEvalOr::CSqlEvalOr(
SQL_LEVEL_1_RPN_EXPRESSION* pExpr,
int* pTokens)
:m_left(NULL),m_right(NULL)
{
(*pTokens)-- ;
m_left = CSqlEval::CreateClass(
pExpr,
pTokens);
m_right = CSqlEval::CreateClass(
pExpr,
pTokens);
}
BOOL
CSqlEvalOr::Evaluate(
CSqlEvalee* pInst)
{
return m_left->Evaluate(pInst) || m_right->Evaluate(pInst);
}
void
CSqlEvalOr::GenerateQueryEnum(CQueryEnumerator& qeInst)
{
CQueryEnumerator qeNew = qeInst;
m_left->GenerateQueryEnum(qeNew);
m_right->GenerateQueryEnum(qeInst);
qeInst.Or(qeNew);
}
// CSqlEvalExp
CSqlEvalExp::~CSqlEvalExp()
{
SysFreeString(m_BstrName);
VariantClear(&m_v);
}
CSqlEvalExp::CSqlEvalExp(
SQL_LEVEL_1_RPN_EXPRESSION* pExpr,
int* pTokens)
:m_BstrName(NULL)
{
VariantInit(&m_v);
SQL_LEVEL_1_TOKEN* pToken = pExpr->pArrayOfTokens+(*pTokens-1);
(*pTokens)--;
m_BstrName = SysAllocString(pToken->pPropertyName);
HRESULT hr = VariantCopy(&m_v, &(pToken->vConstValue));
if ( FAILED( hr ) )
{
throw WBEM_E_OUT_OF_MEMORY;
}
m_op = pToken->nOperator;
switch(m_v.vt)
{
case VT_I2:
m_dw = m_v.iVal;
m_DataType = IntergerType;
break;
case VT_I4:
m_dw = m_v.lVal;
m_DataType = IntergerType;
break;
case VT_BOOL:
m_DataType = IntergerType;
m_dw = m_v.boolVal;
break;
case VT_BSTR:
m_DataType = StringType;
m_bstr = m_v.bstrVal;
break;
default:
throw WBEM_E_INVALID_PARAMETER;
}
}
BOOL
CSqlEvalExp::Evaluate(
CSqlEvalee* pInst)
{
BOOL Result=FALSE;
const VARIANT* pv = pInst->Get(m_BstrName);
switch(m_DataType)
{
case IntergerType:
DWORD dw;
switch(pv->vt)
{
case VT_I2:
dw = pv->iVal;
break;
case VT_I4:
dw = pv->lVal;
break;
case VT_BOOL:
dw = pv->boolVal;
break;
}
// compare
switch(m_op)
{
case SQL_LEVEL_1_TOKEN::OP_EQUAL:
Result = (dw == m_dw);
break;
case SQL_LEVEL_1_TOKEN::OP_NOT_EQUAL:
Result = !(dw == m_dw);
break;
case SQL_LEVEL_1_TOKEN::OP_EQUALorGREATERTHAN:
Result = (dw >= m_dw);
break;
case SQL_LEVEL_1_TOKEN::OP_EQUALorLESSTHAN:
Result = (dw <= m_dw);
break;
case SQL_LEVEL_1_TOKEN::OP_LESSTHAN:
Result = (dw < m_dw);
break;
case SQL_LEVEL_1_TOKEN::OP_GREATERTHAN:
Result = (dw > m_dw);
break;
}
break;
case StringType:
int rt = _wcsicmp(pv->bstrVal, m_bstr);
switch(m_op)
{
case SQL_LEVEL_1_TOKEN::OP_EQUAL:
Result = (rt == 0);
break;
case SQL_LEVEL_1_TOKEN::OP_NOT_EQUAL:
Result = !(rt == 0);
break;
case SQL_LEVEL_1_TOKEN::OP_EQUALorGREATERTHAN:
Result = (rt > 0 || rt == 0);
break;
case SQL_LEVEL_1_TOKEN::OP_EQUALorLESSTHAN:
Result = (rt < 0 || rt == 0);
break;
case SQL_LEVEL_1_TOKEN::OP_LESSTHAN:
Result = (rt < 0);
break;
case SQL_LEVEL_1_TOKEN::OP_GREATERTHAN:
Result = (rt > 0 );
break;
}
break;
}
return Result;
}
void
CSqlEvalExp::GenerateQueryEnum(CQueryEnumerator& qeInst)
{
int nSize = qeInst.m_QueryFields.Size();
const WCHAR** ppName = qeInst.m_QueryFields.Data();
WCHAR** ppWstr = new WCHAR*[nSize];
if ( ppWstr )
{
for(int i=0; i< nSize; i++)
{
if(_wcsicmp( m_BstrName, ppName[i]) == 0)
{
ppWstr[i] = m_v.bstrVal;
}
else
ppWstr[i] = NULL;
}
CQueryEnumerator::CStringArray strArray(
ppWstr,
nSize);
delete [] ppWstr;
qeInst.ArrayAdd(strArray);
}
}
//CQueryEnumerator;
CQueryEnumerator::CQueryEnumerator(
WCHAR** ppKeyName,
int cArg ):
m_index(0),m_cNumOfRecordInSet(0),
m_QuerySet(NULL), m_MaxSize(INITIAL_SIZE)
{
m_QueryFields = CStringArray(
ppKeyName,
cArg);
}
CQueryEnumerator::CQueryEnumerator(
CQueryEnumerator& instEnumerator)
:m_index(0), m_MaxSize(INITIAL_SIZE),
m_QuerySet(NULL), m_cNumOfRecordInSet(0)
{
m_QueryFields = instEnumerator.m_QueryFields;
int nSize = instEnumerator.m_cNumOfRecordInSet;
for(int i=0; i< nSize; i++)
{
ArrayAdd(instEnumerator.m_QuerySet[i]);
}
}
CQueryEnumerator::~CQueryEnumerator()
{
ArrayDelete();
}
/*
DWORD
CQueryEnumerator::InitEnumerator(
WCHAR** wszFieldNames,
int cArg,
CSqlEval* pEval)
{
m_QueryFields = CStringArray(
wszFieldNames,
cArg);
return S_OK;
}
*/
const
WCHAR**
CQueryEnumerator::GetNext(int& cElement)
{
if(m_index == m_cNumOfRecordInSet)
{
return NULL;
}
else
{
cElement = m_QuerySet[m_index].Size();
return m_QuerySet[m_index++].Data();
}
}
void
CQueryEnumerator::ArrayMerge(
CQueryEnumerator::CStringArray& strArray)
{
for(int i=0; i< m_cNumOfRecordInSet; i++)
{
// if all element of strArray are null, no need to proceed
if( !strArray.IsNULL())
m_QuerySet[i].Merge(strArray);
}
}
void
CQueryEnumerator::ArrayAdd(
CQueryEnumerator::CStringArray & strArray )
{
// if all elements are null for strArray, means no keys are
// selected,we should therefore replace M_querySet this StrArray
if ( strArray.IsNULL() )
{
ArrayDelete();
}
if ( m_QuerySet == NULL )
{
m_QuerySet = new CStringArray[ m_MaxSize ];
if ( !m_QuerySet )
{
return;
}
}
// if array is full, then expand
if ( m_index == m_MaxSize )
{
CStringArray * pOldSet = m_QuerySet;
m_MaxSize = m_MaxSize * 2;
m_QuerySet = new CStringArray[ m_MaxSize ];
if ( !m_QuerySet )
{
return;
}
for( int i =0; i < m_MaxSize; i++ )
{
if( i < m_index )
{
m_QuerySet[ i ] = pOldSet[ i ];
}
}
delete [] pOldSet;
}
if ( !( m_cNumOfRecordInSet > 0 && ( m_QuerySet[0] ).IsNULL() ) )
{
m_QuerySet[ m_index++ ] = strArray;
m_cNumOfRecordInSet = m_index;
}
}
void
CQueryEnumerator::ArrayDelete()
{
delete [] m_QuerySet;
m_QuerySet = NULL;
m_cNumOfRecordInSet = 0;
m_MaxSize = INITIAL_SIZE;
m_index = 0;
}
void
CQueryEnumerator::And(
CQueryEnumerator& instEnumerator)
{
int nSize = instEnumerator.m_cNumOfRecordInSet;
if ( nSize > 0 )
{
CQueryEnumerator qeOld = *this;
ArrayDelete();
for ( int i=0; i< nSize; i++ )
{
CQueryEnumerator qeNew = qeOld;
if ( !qeNew.m_QuerySet )
{
return;
}
qeNew.ArrayMerge( instEnumerator.m_QuerySet[ i ] );
for ( int j=0; j< qeNew.m_cNumOfRecordInSet; ++j )
{
ArrayAdd( qeNew.m_QuerySet[ j ] );
}
}
}
}
void
CQueryEnumerator::Or(
CQueryEnumerator& instEnumerator)
{
for(int i=0; i< instEnumerator.m_cNumOfRecordInSet; i++)
{
if(instEnumerator.m_QuerySet[i].IsNULL())
{
if(m_cNumOfRecordInSet > 0)
ArrayDelete();
ArrayAdd(instEnumerator.m_QuerySet[i]);
}
else
{
ArrayAdd(instEnumerator.m_QuerySet[i]);
}
}
}
void
CQueryEnumerator::Reset()
{
m_index = 0;
}
// CStringArray
CQueryEnumerator::CStringArray::CStringArray()
:m_ppWstr(NULL), m_cNumString(0), m_bIsNull(TRUE)
{
}
CQueryEnumerator::CStringArray::~CStringArray()
{
if(m_ppWstr != NULL)
{
for (int i=0; i< m_cNumString; i++)
{
delete [] m_ppWstr[i];
}
delete [] m_ppWstr;
}
}
CQueryEnumerator::CStringArray::CStringArray(
WCHAR **ppWstrInput,
int cNumString)
:m_ppWstr(NULL)
{
m_cNumString = cNumString;
m_bIsNull = !StringArrayCopy(
&m_ppWstr,
ppWstrInput,
cNumString);
}
CQueryEnumerator::CStringArray::CStringArray(
CQueryEnumerator::CStringArray& strArray)
:m_ppWstr(NULL)
{
m_cNumString = strArray.m_cNumString;
m_bIsNull = !StringArrayCopy(
&m_ppWstr,
strArray.m_ppWstr,
strArray.m_cNumString);
}
CQueryEnumerator::CStringArray&
CQueryEnumerator::CStringArray::operator =(
CQueryEnumerator::CStringArray& strArray)
{
if(m_ppWstr != NULL)
{
for (int i=0; i< m_cNumString; i++)
{
delete [] *m_ppWstr;
*m_ppWstr = NULL;
}
delete [] m_ppWstr;
m_ppWstr = NULL;
}
m_cNumString = strArray.m_cNumString;
m_bIsNull= !StringArrayCopy(
&m_ppWstr,
strArray.m_ppWstr,
strArray.m_cNumString);
return *this;
}
int CQueryEnumerator::CStringArray::Size()
{
return m_cNumString;
}
const
WCHAR**
CQueryEnumerator::CStringArray::Data()
{
return (const WCHAR**) m_ppWstr;
}
// return true if any element is copied,
// false if no element is copied, and no element set to NULL
BOOL
CQueryEnumerator::CStringArray::StringArrayCopy(
WCHAR*** pppDest,
WCHAR** ppSrc,
int cArgs)
{
BOOL bFlag = FALSE;
if(cArgs >0 && ppSrc != NULL)
{
*pppDest = new WCHAR*[cArgs];
if ( *pppDest )
{
for(int i=0; i< cArgs; i++)
{
(*pppDest)[i] = NULL;
if(ppSrc[i] != NULL)
{
int len = wcslen(ppSrc[i]);
(*pppDest)[i] = new WCHAR[len+1];
if ( (*pppDest)[i] == NULL )
{
//
// Free memory already allocated on allocation failure.
//
for ( int j = 0; j < i; ++j )
{
delete [] (*pppDest)[ j ];
}
delete [] *pppDest;
*pppDest = NULL;
throw WBEM_E_OUT_OF_MEMORY;
}
wcscpy((*pppDest)[i], ppSrc[i]);
bFlag = TRUE;
}
}
}
}
return bFlag;
}
void
CQueryEnumerator::CStringArray::Merge(
CQueryEnumerator::CStringArray& instStrArray)
{
if(instStrArray.Size() != m_cNumString)
throw WBEM_E_FAILED;
const WCHAR** ppSrc = instStrArray.Data();
for(int i=0; i<m_cNumString; i++)
{
// if source is null, we leave target string as it was
if( ppSrc[i] != NULL)
{
if(m_ppWstr[i] == NULL)
{
m_ppWstr[i] = new WCHAR[wcslen(ppSrc[i])+1];
if ( m_ppWstr[i] == NULL )
{
throw WBEM_E_OUT_OF_MEMORY;
}
wcscpy(m_ppWstr[i], ppSrc[i]);
}
else
{
// a key can not take two different value
if(_wcsicmp(m_ppWstr[i], ppSrc[i]) != 0)
throw WBEM_E_INVALID_PARAMETER;
}
}
}
}