windows-nt/Source/XPSP1/NT/admin/wmi/wbem/common/wmiutils/queryparse.cpp
2020-09-26 16:20:57 +08:00

1292 lines
21 KiB
C++

//***************************************************************************
//
// (c) 2000 by Microsoft Corp. All Rights Reserved.
//
// queryparse.cpp
//
// a-davcoo 02-Mar-00 Implements the query parser and analysis
// interfaces.
//
//***************************************************************************
#include "precomp.h"
#include <stdio.h>
#include "queryparse.h"
#include "wbemcli.h"
#include "wqllex.h"
CWbemQNode::CWbemQNode (IWbemQuery *query, const SWQLNode *node) : m_query(query), m_node(node)
{
m_cRef=1;
m_query->AddRef();
}
CWbemQNode::~CWbemQNode (void)
{
}
HRESULT CWbemQNode::QueryInterface (REFIID riid, void **ppv)
{
if (IID_IUnknown==riid || IID_IWbemQNode==riid)
{
*ppv=this;
}
else
{
*ppv=NULL;
}
if (NULL!=*ppv)
{
AddRef();
return NOERROR;
}
return E_NOINTERFACE;
};
ULONG CWbemQNode::AddRef(void)
{
m_query->AddRef();
return InterlockedIncrement (&m_cRef);
};
ULONG CWbemQNode::Release(void)
{
m_query->Release();
if (!InterlockedDecrement (&m_cRef))
{
delete this;
}
return m_cRef;
};
HRESULT CWbemQNode::GetNodeType(
/* [out] */ DWORD __RPC_FAR *pdwType)
{
if (pdwType==NULL)
{
return WBEM_E_INVALID_PARAMETER;
}
*pdwType=m_node->m_dwNodeType;
return WBEM_S_NO_ERROR;
}
HRESULT CWbemQNode::GetNodeInfo(
/* [in] */ LPCWSTR pszName,
/* [in] */ DWORD dwFlags,
/* [in] */ DWORD dwBufSize,
/* [out] */ LPVOID pMem)
{
switch (m_node->m_dwNodeType)
{
case WBEMQ_TYPE_SWQLNode_Select:
{
return WBEM_E_NOT_AVAILABLE;
}
case WBEMQ_TYPE_SWQLNode_TableRefs:
{
return WBEM_E_NOT_AVAILABLE;
}
case WBEMQ_TYPE_SWQLNode_ColumnList:
{
return WBEM_E_NOT_AVAILABLE;
}
case WBEMQ_TYPE_SWQLNode_FromClause:
{
return WBEM_E_NOT_AVAILABLE;
}
case WBEMQ_TYPE_SWQLNode_Sql89Join:
{
return WBEM_E_NOT_AVAILABLE;
}
case WBEMQ_TYPE_SWQLNode_Join:
{
return WBEM_E_NOT_AVAILABLE;
}
case WBEMQ_TYPE_SWQLNode_JoinPair:
{
return WBEM_E_NOT_AVAILABLE;
}
case WBEMQ_TYPE_SWQLNode_TableRef:
{
return WBEM_E_NOT_AVAILABLE;
}
case WBEMQ_TYPE_SWQLNode_OnClause:
{
return WBEM_E_NOT_AVAILABLE;
}
case WBEMQ_TYPE_SWQLNode_WhereClause:
{
return WBEM_E_NOT_AVAILABLE;
}
case WBEMQ_TYPE_SWQLNode_RelExpr:
{
return WBEM_E_NOT_AVAILABLE;
}
case WBEMQ_TYPE_SWQLNode_WhereOptions:
{
return WBEM_E_NOT_AVAILABLE;
}
case WBEMQ_TYPE_SWQLNode_GroupBy:
{
return WBEM_E_NOT_AVAILABLE;
}
case WBEMQ_TYPE_SWQLNode_Having:
{
return WBEM_E_NOT_AVAILABLE;
}
case WBEMQ_TYPE_SWQLNode_OrderBy:
{
return WBEM_E_NOT_AVAILABLE;
}
case WBEMQ_TYPE_SWQLNode_Datepart:
{
return WBEM_E_NOT_AVAILABLE;
}
}
return WBEM_E_INVALID_PARAMETER;
}
HRESULT CWbemQNode::GetSubNode(
/* [in] */ DWORD dwFlags,
/* [out] */ IWbemQNode __RPC_FAR *__RPC_FAR *pSubnode)
{
if (pSubnode==NULL)
{
return WBEM_E_INVALID_PARAMETER;
}
switch (dwFlags)
{
case WBEMQ_FLAG_LEFTNODE:
{
if (m_node->m_pLeft==NULL)
{
return WBEM_E_NOT_AVAILABLE;
}
else
{
CWbemQNode *node=new CWbemQNode(m_query, m_node->m_pLeft);
if (node==NULL)
{
return WBEM_E_OUT_OF_MEMORY;
}
HRESULT hr=node->QueryInterface (IID_IWbemQNode, (void **)pSubnode);
node->Release();
return hr;
}
}
case WBEMQ_FLAG_RIGHTNODE:
{
if (m_node->m_pRight==NULL)
{
return WBEM_E_NOT_AVAILABLE;
}
else
{
CWbemQNode *node=new CWbemQNode(m_query, m_node->m_pRight);
if (node==NULL)
{
return WBEM_E_OUT_OF_MEMORY;
}
HRESULT hr=node->QueryInterface (IID_IWbemQNode, (void **)pSubnode);
node->Release();
return hr;
}
}
default:
{
return WBEM_E_INVALID_PARAMETER;
}
}
return WBEM_E_FAILED;
}
CWbemQuery::CWbemQuery (void)
{
m_cRef=1;
m_parser=NULL;
m_class=NULL;
}
CWbemQuery::~CWbemQuery (void)
{
delete m_parser;
if (m_class)
{
m_class->Release();
}
}
HRESULT CWbemQuery::Empty (void)
{
delete m_parser;
m_parser=NULL;
if (m_class)
{
m_class->Release();
m_class=NULL;
}
return WBEM_S_NO_ERROR;
}
void CWbemQuery::InitEmpty (void)
{
}
HRESULT CWbemQuery::QueryInterface (REFIID riid, void **ppv)
{
if (IID_IUnknown==riid || IID_IWbemQuery==riid)
{
*ppv=this;
}
else
{
*ppv=NULL;
}
if (NULL!=*ppv)
{
AddRef();
return NOERROR;
}
return E_NOINTERFACE;
};
ULONG CWbemQuery::AddRef(void)
{
return InterlockedIncrement (&m_cRef);
};
ULONG CWbemQuery::Release(void)
{
if (!InterlockedDecrement (&m_cRef))
{
delete this;
}
return m_cRef;
};
HRESULT CWbemQuery::SetLanguageFeatures(
/* [in] */ long lFlags,
/* [in] */ ULONG uArraySize,
/* [in] */ ULONG __RPC_FAR *puFeatures)
{
return WBEM_E_NOT_AVAILABLE;
}
HRESULT CWbemQuery::TestLanguageFeature(
/* [in,out] */ ULONG *uArraySize,
/* [out] */ ULONG *puFeatures)
{
if (m_parser==NULL)
{
return WBEM_E_INVALID_QUERY;
}
if (uArraySize==NULL)
{
return WBEM_E_INVALID_PARAMETER;
}
if (puFeatures==NULL)
{
*uArraySize=0;
}
return WBEM_E_NOT_AVAILABLE;
}
HRESULT CWbemQuery::Parse(
/* [in] */ LPCWSTR pszLang,
/* [in] */ LPCWSTR pszQuery,
/* [in] */ ULONG uFlags)
{
if (pszQuery==NULL)
{
return WBEM_E_INVALID_PARAMETER;
}
delete m_parser;
m_parser=NULL;
if (!_wcsicmp (pszLang, L"wql"))
{
CTextLexSource query(pszQuery);
m_parser=new CWQLParser(&query);
if (m_parser==NULL)
{
return WBEM_E_OUT_OF_MEMORY;
}
else
{
HRESULT hr=LookupParserError(m_parser->Parse());
if (FAILED(hr))
{
delete m_parser;
m_parser=NULL;
}
return hr;
}
}
else if (!_wcsicmp (pszLang, L"sql"))
{
return WBEM_E_NOT_AVAILABLE;
}
else
{
return WBEM_E_INVALID_PARAMETER;
}
}
HRESULT CWbemQuery::GetAnalysis(
/* [in] */ ULONG uFlags,
/* [in] */ REFIID riid,
/* [iid_is][out] */ LPVOID __RPC_FAR *pObj)
{
if (pObj==NULL)
{
return WBEM_E_INVALID_PARAMETER;
}
if (m_parser==NULL || m_parser->GetParseRoot()==NULL)
{
return WBEM_E_INVALID_QUERY;
}
HRESULT hr=WBEM_E_INVALID_PARAMETER;
*pObj=NULL;
if (riid==IID_IWbemClassObject)
{
if (uFlags==WBEMQ_FLAG_SUMMARY_OBJECT)
{
hr=GetAnalysis ((IWbemClassObject **)pObj);
}
}
else if (riid==IID_IWbemQNode)
{
if (uFlags==WBEMQ_FLAG_ANALYSIS_AST)
{
hr=GetAnalysis ((IWbemQNode **)pObj);
}
}
else
{
if (uFlags==WBEMQ_FLAG_RPN_TOKENS)
{
hr=WBEM_E_NOT_AVAILABLE;
}
}
return hr;
}
HRESULT CWbemQuery::GetAnalysis (IWbemQNode **ppObject)
{
HRESULT hr=WBEM_E_FAILED;
CWbemQNode *node=new CWbemQNode(this, m_parser->GetParseRoot());
if (node==NULL)
{
hr=WBEM_E_OUT_OF_MEMORY;
}
else
{
hr=node->QueryInterface (IID_IWbemQNode, (void **)ppObject);
node->Release();
}
return hr;
}
HRESULT CWbemQuery::GetAnalysis (IWbemClassObject **ppObject)
{
*ppObject=NULL;
return WBEM_E_NOT_AVAILABLE;
}
HRESULT CWbemQuery::TestObject(
/* [in] */ ULONG uFlags,
/* [in] */ REFIID riid,
/* [iid_is][in] */ LPVOID pObj)
{
if (pObj==NULL)
{
return WBEM_E_INVALID_PARAMETER;
}
if (m_parser==NULL)
{
return WBEM_E_INVALID_QUERY;
}
_IWmiObject *pWmiObject=NULL;
HRESULT hr=WBEM_E_INVALID_PARAMETER;
if (riid==IID_IWbemClassObject)
{
hr=((IWbemClassObject *)pObj)->QueryInterface (IID__IWmiObject, (void **)&pWmiObject);
}
else if (riid==IID__IWmiObject)
{
pWmiObject=(_IWmiObject *)pObj;
hr=pWmiObject->AddRef();
}
if (SUCCEEDED(hr))
{
hr=TestObject (pWmiObject);
}
if (pWmiObject!=NULL)
{
pWmiObject->Release();
}
return hr;
}
HRESULT CWbemQuery::TestObject (_IWmiObject *pObject)
{
const SWQLNode_WhereClause *pWhere=(SWQLNode_WhereClause *)m_parser->GetWhereClauseRoot();
if (pWhere==NULL)
{
// No where clause.
return WBEM_S_NO_ERROR;
}
const SWQLNode_RelExpr *pExpr=(SWQLNode_RelExpr *)pWhere->m_pLeft;
if (pExpr==NULL)
{
// No expression.
return WBEM_S_NO_ERROR;
}
return TestObject (pObject, pExpr);
}
HRESULT CWbemQuery::TestObject (_IWmiObject *pObject, const SWQLNode_RelExpr *pExpr)
{
HRESULT hr=WBEM_E_FAILED;
switch (pExpr->m_dwExprType)
{
case WQL_TOK_TYPED_EXPR:
{
hr=TestExpression (pObject, pExpr->m_pTypedExpr);
break;
}
case WQL_TOK_AND:
{
hr=TestObject (pObject, (SWQLNode_RelExpr *)pExpr->m_pLeft);
if (hr!=WBEM_S_FALSE)
{
hr=TestObject (pObject, (SWQLNode_RelExpr *)pExpr->m_pRight);
}
break;
}
case WQL_TOK_OR:
{
hr=TestObject (pObject, (SWQLNode_RelExpr *)pExpr->m_pLeft);
if (hr==WBEM_S_FALSE)
{
hr=TestObject (pObject, (SWQLNode_RelExpr *)pExpr->m_pRight);
}
break;
}
case WQL_TOK_NOT:
{
hr=TestObject (pObject, (SWQLNode_RelExpr *)pExpr->m_pLeft);
if (hr==WBEM_S_FALSE)
{
hr=WBEM_S_NO_ERROR;
}
else if (hr==WBEM_S_NO_ERROR)
{
hr=WBEM_S_FALSE;
}
break;
}
}
return hr;
}
HRESULT CWbemQuery::TestExpression (_IWmiObject *pObject, const SWQLTypedExpr *pExpr)
{
CIMTYPE cimtype;
long handle;
HRESULT hr=pObject->GetPropertyHandleEx (pExpr->m_pColRef, 0, &cimtype, &handle);
if (SUCCEEDED(hr))
{
void *pProperty=NULL;
hr=pObject->GetPropAddrByHandle (handle, 0, NULL, &pProperty);
if (SUCCEEDED(hr))
{
switch (cimtype)
{
case CIM_SINT8:
case CIM_SINT16:
case CIM_SINT32:
case CIM_SINT64:
{
__int64 prop;
switch (cimtype)
{
case CIM_SINT8:
{
prop=*((__int8 *)pProperty);
break;
}
case CIM_SINT16:
{
prop=*((__int16 *)pProperty);
break;
}
case CIM_SINT32:
{
prop=*((__int32 *)pProperty);
break;
}
case CIM_SINT64:
{
prop=*((__int64 *)pProperty);
break;
}
}
__int64 value=GetNumeric (pExpr->m_pConstValue);
hr=CompareNumeric (prop, value, pExpr->m_dwRelOperator);
break;
}
case CIM_UINT8:
case CIM_UINT16:
case CIM_UINT32:
case CIM_UINT64:
{
unsigned __int64 prop;
switch (cimtype)
{
case CIM_UINT8:
{
prop=*((unsigned __int8 *)pProperty);
break;
}
case CIM_UINT16:
{
prop=*((unsigned __int16 *)pProperty);
break;
}
case CIM_UINT32:
{
prop=*((unsigned __int32 *)pProperty);
break;
}
case CIM_UINT64:
{
prop=*((unsigned __int64 *)pProperty);
break;
}
}
unsigned __int64 value=GetNumeric (pExpr->m_pConstValue);
hr=CompareNumeric (prop, value, pExpr->m_dwRelOperator);
break;
}
case CIM_BOOLEAN:
{
unsigned __int16 temp=*((unsigned __int16 *)pProperty);
bool prop=(temp!=0);
bool value=GetBoolean (pExpr->m_pConstValue);
hr=CompareBoolean (prop, value, pExpr->m_dwRelOperator);
break;
}
case CIM_CHAR16:
case CIM_STRING:
{
LPWSTR prop=NULL;
switch (cimtype)
{
case CIM_CHAR16:
{
prop=new wchar_t[wcslen((wchar_t *)pProperty)+1];
if (prop==NULL)
{
hr=WBEM_E_OUT_OF_MEMORY;
}
else
{
wcscpy (prop, (wchar_t *)pProperty);
}
break;
}
case CIM_STRING:
{
prop=new wchar_t[strlen((char *)pProperty)+1];
if (prop==NULL)
{
hr=WBEM_E_OUT_OF_MEMORY;
}
else
{
mbstowcs (prop, (char *)pProperty, strlen((char *)pProperty)+1);
}
break;
}
}
if (SUCCEEDED(hr))
{
LPWSTR value=GetString (pExpr->m_pConstValue);
hr=CompareString (prop, value, pExpr->m_dwRelOperator);
delete [] value;
}
delete [] prop;
break;
}
default:
{
hr=WBEM_E_NOT_AVAILABLE;
break;
}
}
}
}
return hr;
}
HRESULT CWbemQuery::GetQueryInfo(
/* [in] */ ULONG uInfoId,
/* [in] */ LPCWSTR pszParam,
/* [out] */ VARIANT __RPC_FAR *pv)
{
if (m_parser==NULL)
{
return WBEM_E_INVALID_QUERY;
}
switch (uInfoId)
{
case WBEMQ_INF_IS_QUERY_LF1_UNARY:
{
return TestLF1Unary();
}
case WBEMQ_INF_IS_QUERY_CONJUNCTIVE:
{
return TestConjunctive();
}
case WBEMQ_INF_SELECT_STAR:
{
DWORD features=m_parser->GetFeatureFlags();
return (features & CWQLParser::Feature_SelectAll) ? WBEM_S_NO_ERROR : WBEM_S_FALSE;
}
case WBEMQ_INF_TARGET_CLASS:
{
if (pv==NULL)
{
return WBEM_E_INVALID_PARAMETER;
}
return TargetClass (pv);
}
case WBEMQ_INF_SELECTED_PROPS:
{
if (pv==NULL)
{
return WBEM_E_INVALID_PARAMETER;
}
return SelectedProps (pv);
}
case WBEMQ_INF_PROP_TEST_EQ:
{
if (pv==NULL)
{
return WBEM_E_INVALID_PARAMETER;
}
return PropertyEqualityValue (pszParam, pv);
}
}
return WBEM_E_INVALID_PARAMETER;
}
HRESULT CWbemQuery::TargetClass (VARIANT *pv)
{
const SWQLNode_FromClause *pFrom=(SWQLNode_FromClause *)m_parser->GetFromClause();
if (pFrom==NULL)
{
return WBEM_E_INVALID_QUERY;
}
const SWQLNode_TableRef *pTableRef=(SWQLNode_TableRef *)pFrom->m_pLeft;
BSTR bstrVal=SysAllocString (pTableRef->m_pTableName);
if (bstrVal==NULL)
{
return WBEM_E_OUT_OF_MEMORY;
}
VariantInit (pv);
pv->bstrVal=bstrVal;
return WBEM_S_NO_ERROR;
}
HRESULT CWbemQuery::SelectedProps (VARIANT *pv)
{
const SWQLNode_ColumnList *pColumnList=(SWQLNode_ColumnList *)m_parser->GetColumnList();
if (pColumnList==NULL)
{
return WBEM_E_INVALID_QUERY;
}
HRESULT hr=WBEM_S_NO_ERROR;
const CFlexArray *columns=&(pColumnList->m_aColumnRefs);
int numcols=columns->Size();
SAFEARRAY *paColumns=NULL;
if (numcols>0)
{
SAFEARRAYBOUND bound[1];
bound[0].lLbound=0;
bound[0].cElements=numcols;
paColumns=SafeArrayCreate (VT_BSTR, 1, bound);
if (paColumns==NULL)
{
hr=WBEM_E_OUT_OF_MEMORY;
}
else
{
for (int i=0; i<numcols; i++)
{
const SWQLColRef *pColumn=(SWQLColRef *)columns->GetAt (i);
BSTR bstrVal=SysAllocString (pColumn->m_pColName);
if (bstrVal==NULL)
{
hr=WBEM_E_OUT_OF_MEMORY;
break;
}
else
{
long index=i;
hr=SafeArrayPutElement (paColumns, &index, bstrVal);
if (FAILED(hr))
{
break;
}
}
}
}
}
if (FAILED(hr) && paColumns!=NULL)
{
SafeArrayDestroy (paColumns);
}
else
{
VariantInit (pv);
pv->parray=paColumns;
}
return hr;
}
HRESULT CWbemQuery::TestConjunctive (void)
{
const SWQLNode_WhereClause *pWhere=(SWQLNode_WhereClause *)m_parser->GetWhereClauseRoot();
if (pWhere==NULL)
{
// No where clause.
return WBEM_S_FALSE;
}
const SWQLNode_RelExpr *pExpr=(SWQLNode_RelExpr *)pWhere->m_pLeft;
if (pExpr==NULL)
{
// No expression.
return WBEM_S_FALSE;
}
// Perform an in-order traversal of expression sub-tree.
return TestConjunctive (pExpr);
}
HRESULT CWbemQuery::TestConjunctive (const SWQLNode_RelExpr *pExpr)
{
if (pExpr->m_dwExprType==WQL_TOK_TYPED_EXPR || pExpr->m_dwExprType==WQL_TOK_AND)
{
const SWQLNode_RelExpr *pLeft=(SWQLNode_RelExpr *)pExpr->m_pLeft;
if (pLeft!=NULL && TestConjunctive (pLeft)==WBEM_S_FALSE)
{
return WBEM_S_FALSE;
}
const SWQLNode_RelExpr *pRight=(SWQLNode_RelExpr *)pExpr->m_pRight;
if (pRight!=NULL && TestConjunctive (pRight)==WBEM_S_FALSE)
{
return WBEM_S_FALSE;
}
return WBEM_S_NO_ERROR;
}
return WBEM_S_FALSE;
}
HRESULT CWbemQuery::PropertyEqualityValue (LPCWSTR pszParam, VARIANT *pv)
{
const SWQLNode_WhereClause *pWhere=(SWQLNode_WhereClause *)m_parser->GetWhereClauseRoot();
if (pWhere==NULL)
{
// No where clause.
return WBEM_E_NOT_FOUND;
}
const SWQLNode_RelExpr *pExpr=(SWQLNode_RelExpr *)pWhere->m_pLeft;
if (pExpr==NULL)
{
// No expression.
return WBEM_E_NOT_FOUND;
}
// Perform an in-order traversal of expression sub-tree.
return PropertyEqualityValue (pExpr, pszParam, pv);
}
HRESULT CWbemQuery::PropertyEqualityValue (const SWQLNode_RelExpr *pExpr, LPCWSTR pszParam, VARIANT *pv)
{
if (pExpr->m_dwExprType==WQL_TOK_TYPED_EXPR)
{
const SWQLTypedExpr *pTypedExpr=pExpr->m_pTypedExpr;
if (_wcsicmp (pTypedExpr->m_pColRef, pszParam)==0)
{
if (pTypedExpr->m_dwRelOperator!=WQL_TOK_EQ)
{
return WBEM_S_FALSE;
}
else
{
VariantInit (pv);
/// A-DAVCOO: Need to fill the variant with the value in the pTypedExpr.
return WBEM_S_NO_ERROR;
}
}
}
else
{
const SWQLNode_RelExpr *pLeft=(SWQLNode_RelExpr *)pExpr->m_pLeft;
if (pLeft!=NULL)
{
HRESULT hr=PropertyEqualityValue (pLeft, pszParam, pv);
if (hr!=WBEM_E_NOT_FOUND)
{
return hr;
}
}
const SWQLNode_RelExpr *pRight=(SWQLNode_RelExpr *)pExpr->m_pRight;
if (pRight!=NULL)
{
HRESULT hr=PropertyEqualityValue (pRight, pszParam, pv);
if (hr!=WBEM_E_NOT_FOUND)
{
return hr;
}
}
}
return WBEM_E_NOT_FOUND;
}
HRESULT CWbemQuery::TestLF1Unary (void)
{
const SWQLNode_FromClause *pFrom=(SWQLNode_FromClause *)m_parser->GetFromClause();
if (pFrom!=NULL)
{
const SWQLNode *pLeft=pFrom->m_pLeft;
if (pLeft->m_dwNodeType!=WBEMQ_TYPE_SWQLNode_TableRef)
{
return WBEM_S_FALSE;
}
}
return WBEM_S_NO_ERROR;
}
HRESULT CWbemQuery::AttachClassDef(
/* [in] */ REFIID riid,
/* [iid_is][in] */ LPVOID pClassDef)
{
if (pClassDef==NULL)
{
return WBEM_E_INVALID_PARAMETER;
}
_IWmiObject *pClass=NULL;
HRESULT hr=WBEM_E_INVALID_PARAMETER;
if (riid==IID_IWbemClassObject)
{
hr=((IWbemClassObject *)pClassDef)->QueryInterface (IID__IWmiObject, (void **)&pClass);
}
else if (riid==IID__IWmiObject)
{
pClass=(_IWmiObject *)pClassDef;
hr=pClass->AddRef();
}
if (SUCCEEDED(hr))
{
if (m_class!=NULL)
{
m_class->Release();
}
m_class=pClass;
}
return hr;
}
HRESULT CWbemQuery::LookupParserError (int error)
{
switch (error)
{
case CWQLParser::SUCCESS:
{
return WBEM_S_NO_ERROR;
}
case CWQLParser::SYNTAX_ERROR:
case CWQLParser::LEXICAL_ERROR:
{
return WBEM_E_INVALID_QUERY;
}
case CWQLParser::BUFFER_TOO_SMALL:
{
return WBEM_E_BUFFER_TOO_SMALL;
}
case CWQLParser::FAILED:
case CWQLParser::INTERNAL_ERROR:
{
return WBEM_E_FAILED;
}
default:
{
return WBEM_E_FAILED;
}
}
}
__int64 CWbemQuery::GetNumeric (const SWQLTypedConst *pExpr)
{
__int64 dRet=0;
if (pExpr)
{
switch (pExpr->m_dwType)
{
case VT_LPWSTR:
{
dRet=_wtoi64 (pExpr->m_Value.m_pString);
break;
}
case VT_I4:
{
dRet=pExpr->m_Value.m_lValue;
break;
}
case VT_R4:
{
dRet=(__int64)pExpr->m_Value.m_dblValue;
break;
}
case VT_BOOL:
{
dRet=pExpr->m_Value.m_bValue;
break;
}
default:
{
dRet=0;
break;
}
}
}
return dRet;
}
LPWSTR CWbemQuery::GetString (const SWQLTypedConst *pExpr)
{
LPWSTR lpRet=NULL;
if (pExpr)
{
switch (pExpr->m_dwType)
{
case VT_LPWSTR:
{
lpRet=new wchar_t[wcslen (pExpr->m_Value.m_pString)+1];
wcscpy (lpRet, pExpr->m_Value.m_pString);
break;
}
case VT_I4:
{
lpRet=new wchar_t[30];
swprintf (lpRet, L"%ld", pExpr->m_Value.m_lValue);
break;
}
case VT_R4:
{
lpRet=new wchar_t[30];
swprintf (lpRet, L"%lG", pExpr->m_Value.m_dblValue);
break;
}
case VT_BOOL:
{
lpRet=new wchar_t[30];
swprintf (lpRet, L"%I64d", (__int64)pExpr->m_Value.m_bValue);
break;
}
default:
{
lpRet=NULL;
break;
}
}
}
return lpRet;
}
bool CWbemQuery::GetBoolean (const SWQLTypedConst *pExpr)
{
return (GetNumeric (pExpr)!=0);
}
HRESULT CWbemQuery::CompareNumeric (__int64 prop, __int64 value, DWORD relation)
{
HRESULT hr=WBEM_E_NOT_AVAILABLE;
switch (relation)
{
case WQL_TOK_LE:
{
hr=(prop<=value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
break;
}
case WQL_TOK_GE:
{
hr=(prop>=value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
break;
}
case WQL_TOK_EQ:
{
hr=(prop==value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
break;
}
case WQL_TOK_NE:
{
hr=(prop!=value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
break;
}
case WQL_TOK_LT:
{
hr=(prop<value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
break;
}
case WQL_TOK_GT:
{
hr=(prop>value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
break;
}
}
return hr;
}
HRESULT CWbemQuery::CompareNumeric (unsigned __int64 prop, unsigned __int64 value, DWORD relation)
{
HRESULT hr=WBEM_E_NOT_AVAILABLE;
switch (relation)
{
case WQL_TOK_LE:
{
hr=(prop<=value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
break;
}
case WQL_TOK_GE:
{
hr=(prop>=value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
break;
}
case WQL_TOK_EQ:
{
hr=(prop==value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
break;
}
case WQL_TOK_NE:
{
hr=(prop!=value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
break;
}
case WQL_TOK_LT:
{
hr=(prop<value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
break;
}
case WQL_TOK_GT:
{
hr=(prop>value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
break;
}
}
return hr;
}
HRESULT CWbemQuery::CompareBoolean (bool prop, bool value, DWORD relation)
{
return CompareNumeric ((unsigned __int64)(prop ? 1 : 0), (unsigned __int64)(value ? 1 : 0), relation);
}
HRESULT CWbemQuery::CompareString (LPWSTR prop, LPWSTR value, DWORD relation)
{
return WBEM_E_NOT_AVAILABLE;
}