|
|
//***************************************************************************
//
// VPQUALS.CPP
//
// Module: WBEM VIEW PROVIDER
//
// Purpose: Contains the implementation of qualifier storage classes
//
// Copyright (c) 1998-2001 Microsoft Corporation, All Rights Reserved
//
//***************************************************************************
#include "precomp.h"
#include <provexpt.h>
#include <malloc.h>
#include <provcoll.h>
#include <provtempl.h>
#include <provmt.h>
#include <typeinfo.h>
#include <process.h>
#include <objbase.h>
#include <wbemidl.h>
#include <stdio.h>
#include <provcont.h>
#include <provevt.h>
#include <provthrd.h>
#include <provlog.h>
#include <cominit.h>
#include <dsgetdc.h>
#include <lmcons.h>
#include <instpath.h>
#include <genlex.h>
#include <sql_1.h>
#include <objpath.h>
#include <vpdefs.h>
#include <vpquals.h>
#include <vpserv.h>
#include <vptasks.h>
CStringW GetStringFromRPNToken(SQL_LEVEL_1_TOKEN* pRPNToken) { CStringW ret;
if (NULL != pRPNToken->pPropertyName) { ret = L'('; ret += pRPNToken->pPropertyName;
switch(pRPNToken->nOperator) { case SQL_LEVEL_1_TOKEN::OP_EQUAL: { ret += L'='; } break; case SQL_LEVEL_1_TOKEN::OP_NOT_EQUAL: { ret += L"<>"; } break; case SQL_LEVEL_1_TOKEN::OP_EQUALorGREATERTHAN: { ret += L">="; } break; case SQL_LEVEL_1_TOKEN::OP_EQUALorLESSTHAN: { ret += L"<="; } break; case SQL_LEVEL_1_TOKEN::OP_LESSTHAN: { ret += L'<'; } break; case SQL_LEVEL_1_TOKEN::OP_GREATERTHAN: { ret += L'>'; } break; case SQL_LEVEL_1_TOKEN::OP_LIKE: { ret += L" like "; } break; default: { ret.Empty(); } }
if (!ret.IsEmpty()) { switch (pRPNToken->vConstValue.vt) { case VT_NULL: { ret += L"null)"; } break; case VT_BSTR: { if (pRPNToken->bConstIsStrNumeric) { ret += pRPNToken->vConstValue.bstrVal; ret += L')'; } else { ret += L'\"'; wchar_t* buff = new wchar_t[(wcslen(pRPNToken->vConstValue.bstrVal)*2) + 1]; wchar_t* tmp = pRPNToken->vConstValue.bstrVal; wchar_t* tmpBuff = buff;
while (*tmp != NULL) { if ((*tmp == L'\\') || (*tmp == L'"')) { *tmpBuff = L'\\'; *tmpBuff++; }
*tmpBuff = *tmp; *tmpBuff++; *tmp++; }
*tmpBuff = 0; ret += buff; delete [] buff; ret += L"\")"; } } break; case VT_BOOL: { if (pRPNToken->vConstValue.boolVal == VARIANT_TRUE) { ret += L"TRUE)"; } else { ret += L"FALSE)"; } } break ;
case VT_I4: { WCHAR tmpBuff[20]; tmpBuff[0] = L'\0';
if ( swprintf(tmpBuff, L"%d", pRPNToken->vConstValue.lVal) ) { ret += tmpBuff; ret += ')'; } else { ret.Empty(); } } break; case VT_I2: { WCHAR tmpBuff[20]; tmpBuff[0] = L'\0';
if ( swprintf(tmpBuff, L"%d", (int)pRPNToken->vConstValue.iVal) ) { ret += tmpBuff; ret += ')'; } else { ret.Empty(); } } break; case VT_UI1: { WCHAR tmpBuff[20]; tmpBuff[0] = L'\0';
if ( swprintf(tmpBuff, L"%d", (int)pRPNToken->vConstValue.bVal) ) { ret += tmpBuff; ret += ')'; } else { ret.Empty(); } } break; case VT_R4: { WCHAR tmpBuff[25]; tmpBuff[0] = L'\0';
if ( swprintf(tmpBuff, L"%G", pRPNToken->vConstValue.fltVal) ) { ret += tmpBuff; ret += ')'; } else { ret.Empty(); } } break; case VT_R8: { WCHAR tmpBuff[25]; tmpBuff[0] = L'\0';
if ( swprintf(tmpBuff, L"%lG", pRPNToken->vConstValue.dblVal) ) { ret += tmpBuff; ret += ')'; } else { ret.Empty(); } } break; default: { ret.Empty(); } } } } return ret; }
CStringW GetStringFromRPN(SQL_LEVEL_1_RPN_EXPRESSION* pRPN, DWORD num_extra, SQL_LEVEL_1_TOKEN* pExtraTokens, BOOL bAllprops) { CStringW ret;
if (NULL == pRPN) { return ret; }
if (NULL != pRPN->bsClassName) { CStringW props;
if ((bAllprops) || (0 == pRPN->nNumberOfProperties)) { props = L'*'; } else { props = pRPN->pbsRequestedPropertyNames[0];
for (int x = 1; x < pRPN->nNumberOfProperties; x++) { props += L", "; props += pRPN->pbsRequestedPropertyNames[x]; }
props += L", "; props += WBEM_PROPERTY_PATH; props += L", "; props += WBEM_PROPERTY_SERVER; }
ret = L"Select "; ret += props; ret += L" From "; ret += pRPN->bsClassName;
if ((0 != pRPN->nNumTokens) || (0 != num_extra)) { CStringW whereStr; CArray<CStringW, LPCWSTR> exprStack;
//not likely to get more than five expressions in a row!
//if we do, we'll grow the array!
exprStack.SetSize(0, 5); DWORD stack_count = 0;
for (int x = 0; x < (pRPN->nNumTokens + num_extra); x++) { SQL_LEVEL_1_TOKEN* pToken;
if (x < pRPN->nNumTokens) { pToken = &(pRPN->pArrayOfTokens[x]); } else { pToken = &(pExtraTokens[x - pRPN->nNumTokens]); }
if (SQL_LEVEL_1_TOKEN::OP_EXPRESSION == pToken->nTokenType) { if (whereStr.IsEmpty()) { whereStr = GetStringFromRPNToken(pToken);
if (whereStr.IsEmpty()) { ret.Empty(); break; } } else { exprStack.SetAtGrow(stack_count, GetStringFromRPNToken(pToken));
if (exprStack[stack_count].IsEmpty()) { ret.Empty(); break; }
stack_count++; } } else if (SQL_LEVEL_1_TOKEN::TOKEN_NOT == pToken->nTokenType) { CStringW tempStr(L"(Not "); if (stack_count > 0) { tempStr += exprStack[stack_count-1]; tempStr += L')'; exprStack.SetAt(stack_count-1, tempStr); } else if (!whereStr.IsEmpty()) { tempStr += whereStr; tempStr += L')'; whereStr = tempStr; } else { ret.Empty(); break; } } else { CStringW opStr; if (SQL_LEVEL_1_TOKEN::TOKEN_AND == pToken->nTokenType) { opStr = L" And "; } else if (SQL_LEVEL_1_TOKEN::TOKEN_OR == pToken->nTokenType) { opStr = L" Or "; } else { ret.Empty(); break; }
CStringW tempStr(L'(');
if (stack_count > 1) { tempStr += exprStack[stack_count-2]; tempStr += opStr; tempStr += exprStack[stack_count-1]; tempStr += L')'; exprStack.SetAt(stack_count-2, tempStr); stack_count = stack_count--; } else if (stack_count == 1) { tempStr += whereStr; tempStr += opStr; tempStr += exprStack[0]; tempStr += L')'; whereStr = tempStr; stack_count = 0; } else { ret.Empty(); whereStr.Empty(); break; } } }
exprStack.RemoveAll();
if (whereStr.IsEmpty() || (stack_count != 0)) { ret.Empty(); } else { ret += L" Where "; ret += whereStr; } } }
return ret; }
CSourceQualifierItem::CSourceQualifierItem(wchar_t* qry, IWbemClassObject* obj) : m_pClassObj(NULL), m_RPNExpr(NULL) { m_isValid = FALSE;
m_QueryStr = qry;
if (NULL != qry) { CTextLexSource querySource(qry); SQL1_Parser sqlParser(&querySource); m_isValid = SQL1_Parser::SUCCESS == sqlParser.Parse(&m_RPNExpr); }
m_pClassObj = obj;
if (NULL != m_pClassObj) { m_pClassObj->AddRef(); } }
CSourceQualifierItem::~CSourceQualifierItem() { if (NULL != m_RPNExpr) { delete m_RPNExpr; }
if (NULL != m_pClassObj) { m_pClassObj->Release(); } }
void CSourceQualifierItem::SetClassObject(IWbemClassObject* pObj) { if (NULL != m_pClassObj) { m_pClassObj->Release(); }
if (NULL != pObj) { pObj->AddRef(); }
m_pClassObj = pObj; }
IWbemClassObject* CSourceQualifierItem::GetClassObject() { if (NULL != m_pClassObj) { m_pClassObj->AddRef(); }
return m_pClassObj; }
BSTR CSourceQualifierItem::GetClassName() { if (NULL != m_RPNExpr) { return m_RPNExpr->bsClassName; }
return NULL; }
CNSpaceQualifierItem::CNSpaceQualifierItem(const wchar_t* ns_path) :
m_Valid (FALSE), m_ServObjs (NULL), m_NSPaths (NULL), m_Count (0),
m_hrServError ( WBEM_S_NO_ERROR )
{ if (NULL != ns_path) { Parse(ns_path); } }
CNSpaceQualifierItem::~CNSpaceQualifierItem() { if (NULL != m_ServObjs) { for (UINT x = 0; x < m_Count; x++) { if (NULL != m_ServObjs[x]) { m_ServObjs[x]->Release(); } }
delete [] m_ServObjs; }
if (m_NSPaths != NULL) { delete [] m_NSPaths; } }
void CNSpaceQualifierItem::Parse(const wchar_t* ns_path) { wchar_t* buff = _wcsdup(ns_path);
if (buff == NULL) { throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR); }
wchar_t* tmp = wcsstr(buff, NS_DELIMIT); CFreeBuff _1(buff);
if (tmp == NULL) { m_NSPaths = new CStringW[1]; m_NSPaths[0] = buff; m_NSPaths[0].TrimLeft();
if (m_NSPaths[0].IsEmpty()) { delete [] m_NSPaths; m_NSPaths = NULL; } else { m_Count = 1; m_Valid = TRUE; m_NSPaths[0].TrimRight(); } } else { wchar_t** tmpbuff = (wchar_t**)malloc(MAX_QUERIES*sizeof(wchar_t*));
if (tmpbuff == NULL) { throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR); }
CFreeBuff _2(tmpbuff);
if (tmp != buff) { tmpbuff[0] = buff; m_Count++; }
while (TRUE) { *tmp = L'\0'; tmp = tmp + 2; if (*tmp != L'\0') { tmpbuff[m_Count] = tmp; tmp = wcsstr(tmpbuff[m_Count], NS_DELIMIT); m_Count++;
if (tmp == NULL) { break; } if ( (m_Count > 0) && (0 == (m_Count%MAX_QUERIES)) ) { UINT x = _msize(tmpbuff); wchar_t** tmp = (wchar_t**)realloc(tmpbuff, x+(MAX_QUERIES*sizeof(wchar_t*))); if (tmp == NULL) { throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR); } tmpbuff = tmp; _2.SetBuff(tmpbuff);
} } else { break; } }
if (m_Count > 0) { m_NSPaths = new CStringW[m_Count];
for (UINT x=0; x < m_Count; x++) { m_NSPaths[x] = tmpbuff[x]; m_NSPaths[x].TrimLeft();
if (m_NSPaths[x].IsEmpty()) { break; } else { m_NSPaths[x].TrimRight(); } }
if (!m_NSPaths[m_Count-1].IsEmpty()) { m_Valid = TRUE; } } } }
CJoinOnQualifierArray::CJoinOnQualifierArray() { m_Count = 0; m_AClasses = NULL; m_AProps = NULL; m_BClasses = NULL; m_BProps = NULL; m_Ops = NULL; m_Buff = NULL; m_Valid = FALSE; m_bDone = NULL; }
CJoinOnQualifierArray::~CJoinOnQualifierArray() { if (NULL != m_AClasses) { free(m_AClasses); }
if (NULL != m_BClasses) { free(m_BClasses); }
if (NULL != m_AProps) { free(m_AProps); }
if (NULL != m_BProps) { free(m_BProps); }
if (NULL != m_Ops) { free(m_Ops); }
if (NULL != m_Buff) { free(m_Buff); }
if (NULL != m_bDone) { delete [] m_bDone; }
m_AllClasses.RemoveAll(); }
BOOL CJoinOnQualifierArray::Set(const wchar_t* jStr) { if (NULL != jStr) { Parse(jStr); }
return m_Valid; }
void CJoinOnQualifierArray::Parse(const wchar_t* qualStr) { m_Buff = _wcsdup(qualStr); wchar_t* tmp = m_Buff; m_Valid = TRUE; m_AClasses = (wchar_t**)malloc(MAX_QUERIES*sizeof(wchar_t*));
if (m_AClasses == NULL) { throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR); }
m_BClasses = (wchar_t**)malloc(MAX_QUERIES*sizeof(wchar_t*));
if (m_BClasses == NULL) { throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR); }
m_AProps = (wchar_t**)malloc(MAX_QUERIES*sizeof(wchar_t*));
if (m_AProps == NULL) { throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR); }
m_BProps = (wchar_t**)malloc(MAX_QUERIES*sizeof(wchar_t*));
if (m_BProps == NULL) { throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR); }
m_Ops = (UINT*)malloc(MAX_QUERIES*sizeof(UINT));
if (m_Ops == NULL) { throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR); }
while ((tmp != NULL) && (L'\0' != *tmp) && (m_Valid)) { m_AClasses[m_Count] = GetClassStr(tmp);
if ((NULL != m_AClasses[m_Count]) && (L'\0' != *(m_AClasses[m_Count]))) { m_AllClasses.SetAt(m_AClasses[m_Count], 0); m_AProps[m_Count] = GetPropertyStrAndOperator(tmp, m_Ops[m_Count]);
if ((NULL != m_AProps[m_Count]) && (L'\0' != *(m_AProps[m_Count])) && (0 != m_Ops[m_Count])) { m_BClasses[m_Count] = GetClassStr(tmp);
if ((NULL != m_BClasses[m_Count]) && (L'\0' != *(m_BClasses[m_Count]))) { m_AllClasses.SetAt(m_BClasses[m_Count], 0); m_BProps[m_Count] = GetPropertyStr(tmp);
if ((NULL != m_BProps[m_Count]) && (L'\0' != *(m_BProps[m_Count])) && StripAnd(tmp)) { m_Count++;
if ((tmp != NULL) && (L'\0' != *tmp) && (m_Count > 0) && (0 == (m_Count%MAX_QUERIES)) ) { UINT x = _msize(m_AClasses); realloc_throw(&m_AClasses, x+(MAX_QUERIES*sizeof(wchar_t*))); realloc_throw(&m_BClasses, x+(MAX_QUERIES*sizeof(wchar_t*))); realloc_throw(&m_AProps, x+(MAX_QUERIES*sizeof(wchar_t*))); realloc_throw(&m_BProps, x+(MAX_QUERIES*sizeof(wchar_t*))); x = _msize(m_Ops); realloc_throw(&m_Ops, x+(MAX_QUERIES*sizeof(UINT))); } } else { m_Valid = FALSE; } } else { m_Valid = FALSE; } } else { m_Valid = FALSE; } } else { m_Valid = FALSE; } }
if (0 == m_Count) { m_Valid = FALSE; }
if (!m_Valid) { if (NULL != m_AClasses) { free(m_AClasses); m_AClasses = NULL; }
if (NULL != m_BClasses) { free(m_BClasses); m_BClasses = NULL; }
if (NULL != m_AProps) { free(m_AProps); m_AProps = NULL; }
if (NULL != m_BProps) { free(m_BProps); m_BProps = NULL; }
if (NULL != m_Ops) { free(m_Ops); m_Ops = NULL; }
if (NULL != m_Buff) { free(m_Buff); m_Buff = NULL; } } else { m_bDone = new BOOL[m_Count]; memset((void *)m_bDone, 0, sizeof(BOOL)*m_Count); } }
wchar_t* CJoinOnQualifierArray::SkipSpace(wchar_t*& src) { while (iswspace(*src)) { if (*src != L'\0') { *src = L'\0'; src++; } }
return ((*src == L'\0') ? NULL : src); }
wchar_t* CJoinOnQualifierArray::SkipToSpecial(wchar_t*& src) { while ((*src != L'.') && (*src != L'=') && (*src != L'!') && (*src != L'<') && !iswspace(*src) && (*src != L'\0')) { src++; }
return ((*src == L'\0') ? NULL : src); }
wchar_t* CJoinOnQualifierArray::GetClassStr(wchar_t*& src) { wchar_t* ret = SkipSpace(src);
if (NULL != ret) { src = SkipToSpecial(src);
if ((NULL != src) && (src != ret) && ((*src == L'.'))) { *src = L'\0'; src++; } else { ret = NULL; } }
return ret; }
wchar_t* CJoinOnQualifierArray::GetPropertyStrAndOperator(wchar_t*& src, UINT& op) { wchar_t* ret = src; op = NO_OPERATOR;
src = SkipToSpecial(src); src = SkipSpace(src);
if ((NULL != src) && (src != ret)) { if (*src == L'=') { *src = L'\0'; op = EQUALS_OPERATOR; src++; } else if (*src == L'!') { wchar_t* prev = src; src++;
if (*src == L'=') { *prev = L'\0'; op = NOT_EQUALS_OPERATOR; src++; } else { ret = NULL; } } else if (*src == L'<') { wchar_t* prev = src; src++;
if (*src == L'>') { *prev = L'\0'; op = NOT_EQUALS_OPERATOR; src++; } else { ret = NULL; } } } else { ret = NULL; }
return ret; }
wchar_t* CJoinOnQualifierArray::GetPropertyStr(wchar_t*& src) { wchar_t* ret = src; src = SkipToSpecial(src);
if (NULL != src) { if ( (src != ret) && iswspace(*src) ) { if (*src != L'\0') { *src = L'\0'; src++; } } else { ret = NULL; } }
return ret; }
BOOL CJoinOnQualifierArray::StripAnd(wchar_t*& src) {
if (NULL == src) { return TRUE; }
src = SkipSpace(src);
if (NULL == src) { return TRUE; }
if ((*src == L'a') || (*src == L'A')) { src++;
if ((*src == L'n') || (*src == L'N')) { src++;
if ((*src == L'd') || (*src == L'D')) { src++; wchar_t* tmp = src; src = SkipSpace(src);
if ((NULL != src) && (tmp != src)) { return TRUE; } } } }
return FALSE; }
BOOL CJoinOnQualifierArray::ValidateJoin() { if (!m_Valid) { return m_Valid; }
CMap<CStringW, LPCWSTR, UINT, UINT> validatedClasses; CArray<CStringW, LPCWSTR> spareClasses; UINT x = 0;
if (_wcsicmp(m_AClasses[x], m_BClasses[x]) == 0) { m_Valid = FALSE; } else { validatedClasses.SetAt(m_AClasses[x], 0); validatedClasses.SetAt(m_BClasses[x], 0); x++; }
while ((m_Valid) && (x < m_Count)) { if (_wcsicmp(m_AClasses[x], m_BClasses[x]) == 0) { m_Valid = FALSE; } else { UINT val;
if (validatedClasses.Lookup(m_AClasses[x], val)) { validatedClasses.SetAt(m_BClasses[x], 0); } else { if (validatedClasses.Lookup(m_BClasses[x], val)) { validatedClasses.SetAt(m_AClasses[x], 0); } else { spareClasses.Add(m_AClasses[x]); spareClasses.Add(m_BClasses[x]); } } }
x++; }
while ( m_Valid && (0 != spareClasses.GetSize()) ) { m_Valid = FALSE; for (int i = 0; i < spareClasses.GetSize(); i++) { UINT val;
if (validatedClasses.Lookup(spareClasses[i], val)) { if (0 == (i%2)) { validatedClasses.SetAt(spareClasses[i+1], 0); spareClasses.RemoveAt(i, 2); i -= 1; } else { validatedClasses.SetAt(spareClasses[i-1], 0); spareClasses.RemoveAt(i-1, 2); i -= 2; }
m_Valid = TRUE; } } }
spareClasses.RemoveAll(); validatedClasses.RemoveAll();
return m_Valid; }
CPropertyQualifierItem::CPropertyQualifierItem(const wchar_t* prop, BOOL bHD, BOOL bKy, CIMTYPE ct, CStringW rfto, BOOL bDt) { if (NULL != prop) { m_ViewPropertyName = prop; }
m_bDirect = bDt; m_HiddenDefault = bHD; m_bKey = bKy; m_CimType = ct; m_RefTo = rfto; }
CPropertyQualifierItem::~CPropertyQualifierItem() { m_SrcPropertyNames.RemoveAll(); }
|