#include "sqleval.h" #include #include #include #include // 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); VariantCopy(&m_v, &(pToken->vConstValue)); 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() { } /* 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 ) { 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