windows-nt/Source/XPSP1/NT/admin/wmi/wbem/providers/viewprovider/vpquals.cpp

1148 lines
18 KiB
C++
Raw Normal View History

2020-09-26 03:20:57 -05:00
//***************************************************************************
//
// 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;
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);
tmpbuff = (wchar_t**)realloc(tmpbuff, x+(MAX_QUERIES*sizeof(wchar_t*)));
_2.SetBuff(tmpbuff);
if (tmpbuff == NULL)
{
throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
}
}
}
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);
m_AClasses = (wchar_t**)realloc(m_AClasses, x+(MAX_QUERIES*sizeof(wchar_t*)));
if (m_AClasses == NULL)
{
throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
}
m_BClasses = (wchar_t**)realloc(m_BClasses, x+(MAX_QUERIES*sizeof(wchar_t*)));
if (m_BClasses == NULL)
{
throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
}
m_AProps = (wchar_t**)realloc(m_AProps, x+(MAX_QUERIES*sizeof(wchar_t*)));
if (m_AProps == NULL)
{
throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
}
m_BProps = (wchar_t**)realloc(m_BProps, x+(MAX_QUERIES*sizeof(wchar_t*)));
if (m_BProps == NULL)
{
throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
}
x = _msize(m_Ops);
m_Ops = (UINT*)realloc(m_Ops, x+(MAX_QUERIES*sizeof(UINT)));
if (m_Ops == NULL)
{
throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
}
}
}
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();
}