Source code of Windows XP (NT5)
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.

1291 lines
21 KiB

  1. //***************************************************************************
  2. //
  3. // (c) 2000 by Microsoft Corp. All Rights Reserved.
  4. //
  5. // queryparse.cpp
  6. //
  7. // a-davcoo 02-Mar-00 Implements the query parser and analysis
  8. // interfaces.
  9. //
  10. //***************************************************************************
  11. #include "precomp.h"
  12. #include <stdio.h>
  13. #include "queryparse.h"
  14. #include "wbemcli.h"
  15. #include "wqllex.h"
  16. CWbemQNode::CWbemQNode (IWbemQuery *query, const SWQLNode *node) : m_query(query), m_node(node)
  17. {
  18. m_cRef=1;
  19. m_query->AddRef();
  20. }
  21. CWbemQNode::~CWbemQNode (void)
  22. {
  23. }
  24. HRESULT CWbemQNode::QueryInterface (REFIID riid, void **ppv)
  25. {
  26. if (IID_IUnknown==riid || IID_IWbemQNode==riid)
  27. {
  28. *ppv=this;
  29. }
  30. else
  31. {
  32. *ppv=NULL;
  33. }
  34. if (NULL!=*ppv)
  35. {
  36. AddRef();
  37. return NOERROR;
  38. }
  39. return E_NOINTERFACE;
  40. };
  41. ULONG CWbemQNode::AddRef(void)
  42. {
  43. m_query->AddRef();
  44. return InterlockedIncrement (&m_cRef);
  45. };
  46. ULONG CWbemQNode::Release(void)
  47. {
  48. m_query->Release();
  49. if (!InterlockedDecrement (&m_cRef))
  50. {
  51. delete this;
  52. }
  53. return m_cRef;
  54. };
  55. HRESULT CWbemQNode::GetNodeType(
  56. /* [out] */ DWORD __RPC_FAR *pdwType)
  57. {
  58. if (pdwType==NULL)
  59. {
  60. return WBEM_E_INVALID_PARAMETER;
  61. }
  62. *pdwType=m_node->m_dwNodeType;
  63. return WBEM_S_NO_ERROR;
  64. }
  65. HRESULT CWbemQNode::GetNodeInfo(
  66. /* [in] */ LPCWSTR pszName,
  67. /* [in] */ DWORD dwFlags,
  68. /* [in] */ DWORD dwBufSize,
  69. /* [out] */ LPVOID pMem)
  70. {
  71. switch (m_node->m_dwNodeType)
  72. {
  73. case WBEMQ_TYPE_SWQLNode_Select:
  74. {
  75. return WBEM_E_NOT_AVAILABLE;
  76. }
  77. case WBEMQ_TYPE_SWQLNode_TableRefs:
  78. {
  79. return WBEM_E_NOT_AVAILABLE;
  80. }
  81. case WBEMQ_TYPE_SWQLNode_ColumnList:
  82. {
  83. return WBEM_E_NOT_AVAILABLE;
  84. }
  85. case WBEMQ_TYPE_SWQLNode_FromClause:
  86. {
  87. return WBEM_E_NOT_AVAILABLE;
  88. }
  89. case WBEMQ_TYPE_SWQLNode_Sql89Join:
  90. {
  91. return WBEM_E_NOT_AVAILABLE;
  92. }
  93. case WBEMQ_TYPE_SWQLNode_Join:
  94. {
  95. return WBEM_E_NOT_AVAILABLE;
  96. }
  97. case WBEMQ_TYPE_SWQLNode_JoinPair:
  98. {
  99. return WBEM_E_NOT_AVAILABLE;
  100. }
  101. case WBEMQ_TYPE_SWQLNode_TableRef:
  102. {
  103. return WBEM_E_NOT_AVAILABLE;
  104. }
  105. case WBEMQ_TYPE_SWQLNode_OnClause:
  106. {
  107. return WBEM_E_NOT_AVAILABLE;
  108. }
  109. case WBEMQ_TYPE_SWQLNode_WhereClause:
  110. {
  111. return WBEM_E_NOT_AVAILABLE;
  112. }
  113. case WBEMQ_TYPE_SWQLNode_RelExpr:
  114. {
  115. return WBEM_E_NOT_AVAILABLE;
  116. }
  117. case WBEMQ_TYPE_SWQLNode_WhereOptions:
  118. {
  119. return WBEM_E_NOT_AVAILABLE;
  120. }
  121. case WBEMQ_TYPE_SWQLNode_GroupBy:
  122. {
  123. return WBEM_E_NOT_AVAILABLE;
  124. }
  125. case WBEMQ_TYPE_SWQLNode_Having:
  126. {
  127. return WBEM_E_NOT_AVAILABLE;
  128. }
  129. case WBEMQ_TYPE_SWQLNode_OrderBy:
  130. {
  131. return WBEM_E_NOT_AVAILABLE;
  132. }
  133. case WBEMQ_TYPE_SWQLNode_Datepart:
  134. {
  135. return WBEM_E_NOT_AVAILABLE;
  136. }
  137. }
  138. return WBEM_E_INVALID_PARAMETER;
  139. }
  140. HRESULT CWbemQNode::GetSubNode(
  141. /* [in] */ DWORD dwFlags,
  142. /* [out] */ IWbemQNode __RPC_FAR *__RPC_FAR *pSubnode)
  143. {
  144. if (pSubnode==NULL)
  145. {
  146. return WBEM_E_INVALID_PARAMETER;
  147. }
  148. switch (dwFlags)
  149. {
  150. case WBEMQ_FLAG_LEFTNODE:
  151. {
  152. if (m_node->m_pLeft==NULL)
  153. {
  154. return WBEM_E_NOT_AVAILABLE;
  155. }
  156. else
  157. {
  158. CWbemQNode *node=new CWbemQNode(m_query, m_node->m_pLeft);
  159. if (node==NULL)
  160. {
  161. return WBEM_E_OUT_OF_MEMORY;
  162. }
  163. HRESULT hr=node->QueryInterface (IID_IWbemQNode, (void **)pSubnode);
  164. node->Release();
  165. return hr;
  166. }
  167. }
  168. case WBEMQ_FLAG_RIGHTNODE:
  169. {
  170. if (m_node->m_pRight==NULL)
  171. {
  172. return WBEM_E_NOT_AVAILABLE;
  173. }
  174. else
  175. {
  176. CWbemQNode *node=new CWbemQNode(m_query, m_node->m_pRight);
  177. if (node==NULL)
  178. {
  179. return WBEM_E_OUT_OF_MEMORY;
  180. }
  181. HRESULT hr=node->QueryInterface (IID_IWbemQNode, (void **)pSubnode);
  182. node->Release();
  183. return hr;
  184. }
  185. }
  186. default:
  187. {
  188. return WBEM_E_INVALID_PARAMETER;
  189. }
  190. }
  191. return WBEM_E_FAILED;
  192. }
  193. CWbemQuery::CWbemQuery (void)
  194. {
  195. m_cRef=1;
  196. m_parser=NULL;
  197. m_class=NULL;
  198. }
  199. CWbemQuery::~CWbemQuery (void)
  200. {
  201. delete m_parser;
  202. if (m_class)
  203. {
  204. m_class->Release();
  205. }
  206. }
  207. HRESULT CWbemQuery::Empty (void)
  208. {
  209. delete m_parser;
  210. m_parser=NULL;
  211. if (m_class)
  212. {
  213. m_class->Release();
  214. m_class=NULL;
  215. }
  216. return WBEM_S_NO_ERROR;
  217. }
  218. void CWbemQuery::InitEmpty (void)
  219. {
  220. }
  221. HRESULT CWbemQuery::QueryInterface (REFIID riid, void **ppv)
  222. {
  223. if (IID_IUnknown==riid || IID_IWbemQuery==riid)
  224. {
  225. *ppv=this;
  226. }
  227. else
  228. {
  229. *ppv=NULL;
  230. }
  231. if (NULL!=*ppv)
  232. {
  233. AddRef();
  234. return NOERROR;
  235. }
  236. return E_NOINTERFACE;
  237. };
  238. ULONG CWbemQuery::AddRef(void)
  239. {
  240. return InterlockedIncrement (&m_cRef);
  241. };
  242. ULONG CWbemQuery::Release(void)
  243. {
  244. if (!InterlockedDecrement (&m_cRef))
  245. {
  246. delete this;
  247. }
  248. return m_cRef;
  249. };
  250. HRESULT CWbemQuery::SetLanguageFeatures(
  251. /* [in] */ long lFlags,
  252. /* [in] */ ULONG uArraySize,
  253. /* [in] */ ULONG __RPC_FAR *puFeatures)
  254. {
  255. return WBEM_E_NOT_AVAILABLE;
  256. }
  257. HRESULT CWbemQuery::TestLanguageFeature(
  258. /* [in,out] */ ULONG *uArraySize,
  259. /* [out] */ ULONG *puFeatures)
  260. {
  261. if (m_parser==NULL)
  262. {
  263. return WBEM_E_INVALID_QUERY;
  264. }
  265. if (uArraySize==NULL)
  266. {
  267. return WBEM_E_INVALID_PARAMETER;
  268. }
  269. if (puFeatures==NULL)
  270. {
  271. *uArraySize=0;
  272. }
  273. return WBEM_E_NOT_AVAILABLE;
  274. }
  275. HRESULT CWbemQuery::Parse(
  276. /* [in] */ LPCWSTR pszLang,
  277. /* [in] */ LPCWSTR pszQuery,
  278. /* [in] */ ULONG uFlags)
  279. {
  280. if (pszQuery==NULL)
  281. {
  282. return WBEM_E_INVALID_PARAMETER;
  283. }
  284. delete m_parser;
  285. m_parser=NULL;
  286. if (!_wcsicmp (pszLang, L"wql"))
  287. {
  288. CTextLexSource query(pszQuery);
  289. m_parser=new CWQLParser(&query);
  290. if (m_parser==NULL)
  291. {
  292. return WBEM_E_OUT_OF_MEMORY;
  293. }
  294. else
  295. {
  296. HRESULT hr=LookupParserError(m_parser->Parse());
  297. if (FAILED(hr))
  298. {
  299. delete m_parser;
  300. m_parser=NULL;
  301. }
  302. return hr;
  303. }
  304. }
  305. else if (!_wcsicmp (pszLang, L"sql"))
  306. {
  307. return WBEM_E_NOT_AVAILABLE;
  308. }
  309. else
  310. {
  311. return WBEM_E_INVALID_PARAMETER;
  312. }
  313. }
  314. HRESULT CWbemQuery::GetAnalysis(
  315. /* [in] */ ULONG uFlags,
  316. /* [in] */ REFIID riid,
  317. /* [iid_is][out] */ LPVOID __RPC_FAR *pObj)
  318. {
  319. if (pObj==NULL)
  320. {
  321. return WBEM_E_INVALID_PARAMETER;
  322. }
  323. if (m_parser==NULL || m_parser->GetParseRoot()==NULL)
  324. {
  325. return WBEM_E_INVALID_QUERY;
  326. }
  327. HRESULT hr=WBEM_E_INVALID_PARAMETER;
  328. *pObj=NULL;
  329. if (riid==IID_IWbemClassObject)
  330. {
  331. if (uFlags==WBEMQ_FLAG_SUMMARY_OBJECT)
  332. {
  333. hr=GetAnalysis ((IWbemClassObject **)pObj);
  334. }
  335. }
  336. else if (riid==IID_IWbemQNode)
  337. {
  338. if (uFlags==WBEMQ_FLAG_ANALYSIS_AST)
  339. {
  340. hr=GetAnalysis ((IWbemQNode **)pObj);
  341. }
  342. }
  343. else
  344. {
  345. if (uFlags==WBEMQ_FLAG_RPN_TOKENS)
  346. {
  347. hr=WBEM_E_NOT_AVAILABLE;
  348. }
  349. }
  350. return hr;
  351. }
  352. HRESULT CWbemQuery::GetAnalysis (IWbemQNode **ppObject)
  353. {
  354. HRESULT hr=WBEM_E_FAILED;
  355. CWbemQNode *node=new CWbemQNode(this, m_parser->GetParseRoot());
  356. if (node==NULL)
  357. {
  358. hr=WBEM_E_OUT_OF_MEMORY;
  359. }
  360. else
  361. {
  362. hr=node->QueryInterface (IID_IWbemQNode, (void **)ppObject);
  363. node->Release();
  364. }
  365. return hr;
  366. }
  367. HRESULT CWbemQuery::GetAnalysis (IWbemClassObject **ppObject)
  368. {
  369. *ppObject=NULL;
  370. return WBEM_E_NOT_AVAILABLE;
  371. }
  372. HRESULT CWbemQuery::TestObject(
  373. /* [in] */ ULONG uFlags,
  374. /* [in] */ REFIID riid,
  375. /* [iid_is][in] */ LPVOID pObj)
  376. {
  377. if (pObj==NULL)
  378. {
  379. return WBEM_E_INVALID_PARAMETER;
  380. }
  381. if (m_parser==NULL)
  382. {
  383. return WBEM_E_INVALID_QUERY;
  384. }
  385. _IWmiObject *pWmiObject=NULL;
  386. HRESULT hr=WBEM_E_INVALID_PARAMETER;
  387. if (riid==IID_IWbemClassObject)
  388. {
  389. hr=((IWbemClassObject *)pObj)->QueryInterface (IID__IWmiObject, (void **)&pWmiObject);
  390. }
  391. else if (riid==IID__IWmiObject)
  392. {
  393. pWmiObject=(_IWmiObject *)pObj;
  394. hr=pWmiObject->AddRef();
  395. }
  396. if (SUCCEEDED(hr))
  397. {
  398. hr=TestObject (pWmiObject);
  399. }
  400. if (pWmiObject!=NULL)
  401. {
  402. pWmiObject->Release();
  403. }
  404. return hr;
  405. }
  406. HRESULT CWbemQuery::TestObject (_IWmiObject *pObject)
  407. {
  408. const SWQLNode_WhereClause *pWhere=(SWQLNode_WhereClause *)m_parser->GetWhereClauseRoot();
  409. if (pWhere==NULL)
  410. {
  411. // No where clause.
  412. return WBEM_S_NO_ERROR;
  413. }
  414. const SWQLNode_RelExpr *pExpr=(SWQLNode_RelExpr *)pWhere->m_pLeft;
  415. if (pExpr==NULL)
  416. {
  417. // No expression.
  418. return WBEM_S_NO_ERROR;
  419. }
  420. return TestObject (pObject, pExpr);
  421. }
  422. HRESULT CWbemQuery::TestObject (_IWmiObject *pObject, const SWQLNode_RelExpr *pExpr)
  423. {
  424. HRESULT hr=WBEM_E_FAILED;
  425. switch (pExpr->m_dwExprType)
  426. {
  427. case WQL_TOK_TYPED_EXPR:
  428. {
  429. hr=TestExpression (pObject, pExpr->m_pTypedExpr);
  430. break;
  431. }
  432. case WQL_TOK_AND:
  433. {
  434. hr=TestObject (pObject, (SWQLNode_RelExpr *)pExpr->m_pLeft);
  435. if (hr!=WBEM_S_FALSE)
  436. {
  437. hr=TestObject (pObject, (SWQLNode_RelExpr *)pExpr->m_pRight);
  438. }
  439. break;
  440. }
  441. case WQL_TOK_OR:
  442. {
  443. hr=TestObject (pObject, (SWQLNode_RelExpr *)pExpr->m_pLeft);
  444. if (hr==WBEM_S_FALSE)
  445. {
  446. hr=TestObject (pObject, (SWQLNode_RelExpr *)pExpr->m_pRight);
  447. }
  448. break;
  449. }
  450. case WQL_TOK_NOT:
  451. {
  452. hr=TestObject (pObject, (SWQLNode_RelExpr *)pExpr->m_pLeft);
  453. if (hr==WBEM_S_FALSE)
  454. {
  455. hr=WBEM_S_NO_ERROR;
  456. }
  457. else if (hr==WBEM_S_NO_ERROR)
  458. {
  459. hr=WBEM_S_FALSE;
  460. }
  461. break;
  462. }
  463. }
  464. return hr;
  465. }
  466. HRESULT CWbemQuery::TestExpression (_IWmiObject *pObject, const SWQLTypedExpr *pExpr)
  467. {
  468. CIMTYPE cimtype;
  469. long handle;
  470. HRESULT hr=pObject->GetPropertyHandleEx (pExpr->m_pColRef, 0, &cimtype, &handle);
  471. if (SUCCEEDED(hr))
  472. {
  473. void *pProperty=NULL;
  474. hr=pObject->GetPropAddrByHandle (handle, 0, NULL, &pProperty);
  475. if (SUCCEEDED(hr))
  476. {
  477. switch (cimtype)
  478. {
  479. case CIM_SINT8:
  480. case CIM_SINT16:
  481. case CIM_SINT32:
  482. case CIM_SINT64:
  483. {
  484. __int64 prop;
  485. switch (cimtype)
  486. {
  487. case CIM_SINT8:
  488. {
  489. prop=*((__int8 *)pProperty);
  490. break;
  491. }
  492. case CIM_SINT16:
  493. {
  494. prop=*((__int16 *)pProperty);
  495. break;
  496. }
  497. case CIM_SINT32:
  498. {
  499. prop=*((__int32 *)pProperty);
  500. break;
  501. }
  502. case CIM_SINT64:
  503. {
  504. prop=*((__int64 *)pProperty);
  505. break;
  506. }
  507. }
  508. __int64 value=GetNumeric (pExpr->m_pConstValue);
  509. hr=CompareNumeric (prop, value, pExpr->m_dwRelOperator);
  510. break;
  511. }
  512. case CIM_UINT8:
  513. case CIM_UINT16:
  514. case CIM_UINT32:
  515. case CIM_UINT64:
  516. {
  517. unsigned __int64 prop;
  518. switch (cimtype)
  519. {
  520. case CIM_UINT8:
  521. {
  522. prop=*((unsigned __int8 *)pProperty);
  523. break;
  524. }
  525. case CIM_UINT16:
  526. {
  527. prop=*((unsigned __int16 *)pProperty);
  528. break;
  529. }
  530. case CIM_UINT32:
  531. {
  532. prop=*((unsigned __int32 *)pProperty);
  533. break;
  534. }
  535. case CIM_UINT64:
  536. {
  537. prop=*((unsigned __int64 *)pProperty);
  538. break;
  539. }
  540. }
  541. unsigned __int64 value=GetNumeric (pExpr->m_pConstValue);
  542. hr=CompareNumeric (prop, value, pExpr->m_dwRelOperator);
  543. break;
  544. }
  545. case CIM_BOOLEAN:
  546. {
  547. unsigned __int16 temp=*((unsigned __int16 *)pProperty);
  548. bool prop=(temp!=0);
  549. bool value=GetBoolean (pExpr->m_pConstValue);
  550. hr=CompareBoolean (prop, value, pExpr->m_dwRelOperator);
  551. break;
  552. }
  553. case CIM_CHAR16:
  554. case CIM_STRING:
  555. {
  556. LPWSTR prop=NULL;
  557. switch (cimtype)
  558. {
  559. case CIM_CHAR16:
  560. {
  561. prop=new wchar_t[wcslen((wchar_t *)pProperty)+1];
  562. if (prop==NULL)
  563. {
  564. hr=WBEM_E_OUT_OF_MEMORY;
  565. }
  566. else
  567. {
  568. wcscpy (prop, (wchar_t *)pProperty);
  569. }
  570. break;
  571. }
  572. case CIM_STRING:
  573. {
  574. prop=new wchar_t[strlen((char *)pProperty)+1];
  575. if (prop==NULL)
  576. {
  577. hr=WBEM_E_OUT_OF_MEMORY;
  578. }
  579. else
  580. {
  581. mbstowcs (prop, (char *)pProperty, strlen((char *)pProperty)+1);
  582. }
  583. break;
  584. }
  585. }
  586. if (SUCCEEDED(hr))
  587. {
  588. LPWSTR value=GetString (pExpr->m_pConstValue);
  589. hr=CompareString (prop, value, pExpr->m_dwRelOperator);
  590. delete [] value;
  591. }
  592. delete [] prop;
  593. break;
  594. }
  595. default:
  596. {
  597. hr=WBEM_E_NOT_AVAILABLE;
  598. break;
  599. }
  600. }
  601. }
  602. }
  603. return hr;
  604. }
  605. HRESULT CWbemQuery::GetQueryInfo(
  606. /* [in] */ ULONG uInfoId,
  607. /* [in] */ LPCWSTR pszParam,
  608. /* [out] */ VARIANT __RPC_FAR *pv)
  609. {
  610. if (m_parser==NULL)
  611. {
  612. return WBEM_E_INVALID_QUERY;
  613. }
  614. switch (uInfoId)
  615. {
  616. case WBEMQ_INF_IS_QUERY_LF1_UNARY:
  617. {
  618. return TestLF1Unary();
  619. }
  620. case WBEMQ_INF_IS_QUERY_CONJUNCTIVE:
  621. {
  622. return TestConjunctive();
  623. }
  624. case WBEMQ_INF_SELECT_STAR:
  625. {
  626. DWORD features=m_parser->GetFeatureFlags();
  627. return (features & CWQLParser::Feature_SelectAll) ? WBEM_S_NO_ERROR : WBEM_S_FALSE;
  628. }
  629. case WBEMQ_INF_TARGET_CLASS:
  630. {
  631. if (pv==NULL)
  632. {
  633. return WBEM_E_INVALID_PARAMETER;
  634. }
  635. return TargetClass (pv);
  636. }
  637. case WBEMQ_INF_SELECTED_PROPS:
  638. {
  639. if (pv==NULL)
  640. {
  641. return WBEM_E_INVALID_PARAMETER;
  642. }
  643. return SelectedProps (pv);
  644. }
  645. case WBEMQ_INF_PROP_TEST_EQ:
  646. {
  647. if (pv==NULL)
  648. {
  649. return WBEM_E_INVALID_PARAMETER;
  650. }
  651. return PropertyEqualityValue (pszParam, pv);
  652. }
  653. }
  654. return WBEM_E_INVALID_PARAMETER;
  655. }
  656. HRESULT CWbemQuery::TargetClass (VARIANT *pv)
  657. {
  658. const SWQLNode_FromClause *pFrom=(SWQLNode_FromClause *)m_parser->GetFromClause();
  659. if (pFrom==NULL)
  660. {
  661. return WBEM_E_INVALID_QUERY;
  662. }
  663. const SWQLNode_TableRef *pTableRef=(SWQLNode_TableRef *)pFrom->m_pLeft;
  664. BSTR bstrVal=SysAllocString (pTableRef->m_pTableName);
  665. if (bstrVal==NULL)
  666. {
  667. return WBEM_E_OUT_OF_MEMORY;
  668. }
  669. VariantInit (pv);
  670. pv->bstrVal=bstrVal;
  671. return WBEM_S_NO_ERROR;
  672. }
  673. HRESULT CWbemQuery::SelectedProps (VARIANT *pv)
  674. {
  675. const SWQLNode_ColumnList *pColumnList=(SWQLNode_ColumnList *)m_parser->GetColumnList();
  676. if (pColumnList==NULL)
  677. {
  678. return WBEM_E_INVALID_QUERY;
  679. }
  680. HRESULT hr=WBEM_S_NO_ERROR;
  681. const CFlexArray *columns=&(pColumnList->m_aColumnRefs);
  682. int numcols=columns->Size();
  683. SAFEARRAY *paColumns=NULL;
  684. if (numcols>0)
  685. {
  686. SAFEARRAYBOUND bound[1];
  687. bound[0].lLbound=0;
  688. bound[0].cElements=numcols;
  689. paColumns=SafeArrayCreate (VT_BSTR, 1, bound);
  690. if (paColumns==NULL)
  691. {
  692. hr=WBEM_E_OUT_OF_MEMORY;
  693. }
  694. else
  695. {
  696. for (int i=0; i<numcols; i++)
  697. {
  698. const SWQLColRef *pColumn=(SWQLColRef *)columns->GetAt (i);
  699. BSTR bstrVal=SysAllocString (pColumn->m_pColName);
  700. if (bstrVal==NULL)
  701. {
  702. hr=WBEM_E_OUT_OF_MEMORY;
  703. break;
  704. }
  705. else
  706. {
  707. long index=i;
  708. hr=SafeArrayPutElement (paColumns, &index, bstrVal);
  709. if (FAILED(hr))
  710. {
  711. break;
  712. }
  713. }
  714. }
  715. }
  716. }
  717. if (FAILED(hr) && paColumns!=NULL)
  718. {
  719. SafeArrayDestroy (paColumns);
  720. }
  721. else
  722. {
  723. VariantInit (pv);
  724. pv->parray=paColumns;
  725. }
  726. return hr;
  727. }
  728. HRESULT CWbemQuery::TestConjunctive (void)
  729. {
  730. const SWQLNode_WhereClause *pWhere=(SWQLNode_WhereClause *)m_parser->GetWhereClauseRoot();
  731. if (pWhere==NULL)
  732. {
  733. // No where clause.
  734. return WBEM_S_FALSE;
  735. }
  736. const SWQLNode_RelExpr *pExpr=(SWQLNode_RelExpr *)pWhere->m_pLeft;
  737. if (pExpr==NULL)
  738. {
  739. // No expression.
  740. return WBEM_S_FALSE;
  741. }
  742. // Perform an in-order traversal of expression sub-tree.
  743. return TestConjunctive (pExpr);
  744. }
  745. HRESULT CWbemQuery::TestConjunctive (const SWQLNode_RelExpr *pExpr)
  746. {
  747. if (pExpr->m_dwExprType==WQL_TOK_TYPED_EXPR || pExpr->m_dwExprType==WQL_TOK_AND)
  748. {
  749. const SWQLNode_RelExpr *pLeft=(SWQLNode_RelExpr *)pExpr->m_pLeft;
  750. if (pLeft!=NULL && TestConjunctive (pLeft)==WBEM_S_FALSE)
  751. {
  752. return WBEM_S_FALSE;
  753. }
  754. const SWQLNode_RelExpr *pRight=(SWQLNode_RelExpr *)pExpr->m_pRight;
  755. if (pRight!=NULL && TestConjunctive (pRight)==WBEM_S_FALSE)
  756. {
  757. return WBEM_S_FALSE;
  758. }
  759. return WBEM_S_NO_ERROR;
  760. }
  761. return WBEM_S_FALSE;
  762. }
  763. HRESULT CWbemQuery::PropertyEqualityValue (LPCWSTR pszParam, VARIANT *pv)
  764. {
  765. const SWQLNode_WhereClause *pWhere=(SWQLNode_WhereClause *)m_parser->GetWhereClauseRoot();
  766. if (pWhere==NULL)
  767. {
  768. // No where clause.
  769. return WBEM_E_NOT_FOUND;
  770. }
  771. const SWQLNode_RelExpr *pExpr=(SWQLNode_RelExpr *)pWhere->m_pLeft;
  772. if (pExpr==NULL)
  773. {
  774. // No expression.
  775. return WBEM_E_NOT_FOUND;
  776. }
  777. // Perform an in-order traversal of expression sub-tree.
  778. return PropertyEqualityValue (pExpr, pszParam, pv);
  779. }
  780. HRESULT CWbemQuery::PropertyEqualityValue (const SWQLNode_RelExpr *pExpr, LPCWSTR pszParam, VARIANT *pv)
  781. {
  782. if (pExpr->m_dwExprType==WQL_TOK_TYPED_EXPR)
  783. {
  784. const SWQLTypedExpr *pTypedExpr=pExpr->m_pTypedExpr;
  785. if (_wcsicmp (pTypedExpr->m_pColRef, pszParam)==0)
  786. {
  787. if (pTypedExpr->m_dwRelOperator!=WQL_TOK_EQ)
  788. {
  789. return WBEM_S_FALSE;
  790. }
  791. else
  792. {
  793. VariantInit (pv);
  794. /// A-DAVCOO: Need to fill the variant with the value in the pTypedExpr.
  795. return WBEM_S_NO_ERROR;
  796. }
  797. }
  798. }
  799. else
  800. {
  801. const SWQLNode_RelExpr *pLeft=(SWQLNode_RelExpr *)pExpr->m_pLeft;
  802. if (pLeft!=NULL)
  803. {
  804. HRESULT hr=PropertyEqualityValue (pLeft, pszParam, pv);
  805. if (hr!=WBEM_E_NOT_FOUND)
  806. {
  807. return hr;
  808. }
  809. }
  810. const SWQLNode_RelExpr *pRight=(SWQLNode_RelExpr *)pExpr->m_pRight;
  811. if (pRight!=NULL)
  812. {
  813. HRESULT hr=PropertyEqualityValue (pRight, pszParam, pv);
  814. if (hr!=WBEM_E_NOT_FOUND)
  815. {
  816. return hr;
  817. }
  818. }
  819. }
  820. return WBEM_E_NOT_FOUND;
  821. }
  822. HRESULT CWbemQuery::TestLF1Unary (void)
  823. {
  824. const SWQLNode_FromClause *pFrom=(SWQLNode_FromClause *)m_parser->GetFromClause();
  825. if (pFrom!=NULL)
  826. {
  827. const SWQLNode *pLeft=pFrom->m_pLeft;
  828. if (pLeft->m_dwNodeType!=WBEMQ_TYPE_SWQLNode_TableRef)
  829. {
  830. return WBEM_S_FALSE;
  831. }
  832. }
  833. return WBEM_S_NO_ERROR;
  834. }
  835. HRESULT CWbemQuery::AttachClassDef(
  836. /* [in] */ REFIID riid,
  837. /* [iid_is][in] */ LPVOID pClassDef)
  838. {
  839. if (pClassDef==NULL)
  840. {
  841. return WBEM_E_INVALID_PARAMETER;
  842. }
  843. _IWmiObject *pClass=NULL;
  844. HRESULT hr=WBEM_E_INVALID_PARAMETER;
  845. if (riid==IID_IWbemClassObject)
  846. {
  847. hr=((IWbemClassObject *)pClassDef)->QueryInterface (IID__IWmiObject, (void **)&pClass);
  848. }
  849. else if (riid==IID__IWmiObject)
  850. {
  851. pClass=(_IWmiObject *)pClassDef;
  852. hr=pClass->AddRef();
  853. }
  854. if (SUCCEEDED(hr))
  855. {
  856. if (m_class!=NULL)
  857. {
  858. m_class->Release();
  859. }
  860. m_class=pClass;
  861. }
  862. return hr;
  863. }
  864. HRESULT CWbemQuery::LookupParserError (int error)
  865. {
  866. switch (error)
  867. {
  868. case CWQLParser::SUCCESS:
  869. {
  870. return WBEM_S_NO_ERROR;
  871. }
  872. case CWQLParser::SYNTAX_ERROR:
  873. case CWQLParser::LEXICAL_ERROR:
  874. {
  875. return WBEM_E_INVALID_QUERY;
  876. }
  877. case CWQLParser::BUFFER_TOO_SMALL:
  878. {
  879. return WBEM_E_BUFFER_TOO_SMALL;
  880. }
  881. case CWQLParser::FAILED:
  882. case CWQLParser::INTERNAL_ERROR:
  883. {
  884. return WBEM_E_FAILED;
  885. }
  886. default:
  887. {
  888. return WBEM_E_FAILED;
  889. }
  890. }
  891. }
  892. __int64 CWbemQuery::GetNumeric (const SWQLTypedConst *pExpr)
  893. {
  894. __int64 dRet=0;
  895. if (pExpr)
  896. {
  897. switch (pExpr->m_dwType)
  898. {
  899. case VT_LPWSTR:
  900. {
  901. dRet=_wtoi64 (pExpr->m_Value.m_pString);
  902. break;
  903. }
  904. case VT_I4:
  905. {
  906. dRet=pExpr->m_Value.m_lValue;
  907. break;
  908. }
  909. case VT_R4:
  910. {
  911. dRet=(__int64)pExpr->m_Value.m_dblValue;
  912. break;
  913. }
  914. case VT_BOOL:
  915. {
  916. dRet=pExpr->m_Value.m_bValue;
  917. break;
  918. }
  919. default:
  920. {
  921. dRet=0;
  922. break;
  923. }
  924. }
  925. }
  926. return dRet;
  927. }
  928. LPWSTR CWbemQuery::GetString (const SWQLTypedConst *pExpr)
  929. {
  930. LPWSTR lpRet=NULL;
  931. if (pExpr)
  932. {
  933. switch (pExpr->m_dwType)
  934. {
  935. case VT_LPWSTR:
  936. {
  937. lpRet=new wchar_t[wcslen (pExpr->m_Value.m_pString)+1];
  938. wcscpy (lpRet, pExpr->m_Value.m_pString);
  939. break;
  940. }
  941. case VT_I4:
  942. {
  943. lpRet=new wchar_t[30];
  944. swprintf (lpRet, L"%ld", pExpr->m_Value.m_lValue);
  945. break;
  946. }
  947. case VT_R4:
  948. {
  949. lpRet=new wchar_t[30];
  950. swprintf (lpRet, L"%lG", pExpr->m_Value.m_dblValue);
  951. break;
  952. }
  953. case VT_BOOL:
  954. {
  955. lpRet=new wchar_t[30];
  956. swprintf (lpRet, L"%I64d", (__int64)pExpr->m_Value.m_bValue);
  957. break;
  958. }
  959. default:
  960. {
  961. lpRet=NULL;
  962. break;
  963. }
  964. }
  965. }
  966. return lpRet;
  967. }
  968. bool CWbemQuery::GetBoolean (const SWQLTypedConst *pExpr)
  969. {
  970. return (GetNumeric (pExpr)!=0);
  971. }
  972. HRESULT CWbemQuery::CompareNumeric (__int64 prop, __int64 value, DWORD relation)
  973. {
  974. HRESULT hr=WBEM_E_NOT_AVAILABLE;
  975. switch (relation)
  976. {
  977. case WQL_TOK_LE:
  978. {
  979. hr=(prop<=value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
  980. break;
  981. }
  982. case WQL_TOK_GE:
  983. {
  984. hr=(prop>=value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
  985. break;
  986. }
  987. case WQL_TOK_EQ:
  988. {
  989. hr=(prop==value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
  990. break;
  991. }
  992. case WQL_TOK_NE:
  993. {
  994. hr=(prop!=value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
  995. break;
  996. }
  997. case WQL_TOK_LT:
  998. {
  999. hr=(prop<value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
  1000. break;
  1001. }
  1002. case WQL_TOK_GT:
  1003. {
  1004. hr=(prop>value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
  1005. break;
  1006. }
  1007. }
  1008. return hr;
  1009. }
  1010. HRESULT CWbemQuery::CompareNumeric (unsigned __int64 prop, unsigned __int64 value, DWORD relation)
  1011. {
  1012. HRESULT hr=WBEM_E_NOT_AVAILABLE;
  1013. switch (relation)
  1014. {
  1015. case WQL_TOK_LE:
  1016. {
  1017. hr=(prop<=value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
  1018. break;
  1019. }
  1020. case WQL_TOK_GE:
  1021. {
  1022. hr=(prop>=value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
  1023. break;
  1024. }
  1025. case WQL_TOK_EQ:
  1026. {
  1027. hr=(prop==value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
  1028. break;
  1029. }
  1030. case WQL_TOK_NE:
  1031. {
  1032. hr=(prop!=value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
  1033. break;
  1034. }
  1035. case WQL_TOK_LT:
  1036. {
  1037. hr=(prop<value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
  1038. break;
  1039. }
  1040. case WQL_TOK_GT:
  1041. {
  1042. hr=(prop>value ? WBEM_S_NO_ERROR : WBEM_S_FALSE);
  1043. break;
  1044. }
  1045. }
  1046. return hr;
  1047. }
  1048. HRESULT CWbemQuery::CompareBoolean (bool prop, bool value, DWORD relation)
  1049. {
  1050. return CompareNumeric ((unsigned __int64)(prop ? 1 : 0), (unsigned __int64)(value ? 1 : 0), relation);
  1051. }
  1052. HRESULT CWbemQuery::CompareString (LPWSTR prop, LPWSTR value, DWORD relation)
  1053. {
  1054. return WBEM_E_NOT_AVAILABLE;
  1055. }