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.

1147 lines
18 KiB

  1. //***************************************************************************
  2. //
  3. // VPQUALS.CPP
  4. //
  5. // Module: WBEM VIEW PROVIDER
  6. //
  7. // Purpose: Contains the implementation of qualifier storage classes
  8. //
  9. // Copyright (c) 1998-2001 Microsoft Corporation, All Rights Reserved
  10. //
  11. //***************************************************************************
  12. #include "precomp.h"
  13. #include <provexpt.h>
  14. #include <malloc.h>
  15. #include <provcoll.h>
  16. #include <provtempl.h>
  17. #include <provmt.h>
  18. #include <typeinfo.h>
  19. #include <process.h>
  20. #include <objbase.h>
  21. #include <wbemidl.h>
  22. #include <stdio.h>
  23. #include <provcont.h>
  24. #include <provevt.h>
  25. #include <provthrd.h>
  26. #include <provlog.h>
  27. #include <cominit.h>
  28. #include <dsgetdc.h>
  29. #include <lmcons.h>
  30. #include <instpath.h>
  31. #include <genlex.h>
  32. #include <sql_1.h>
  33. #include <objpath.h>
  34. #include <vpdefs.h>
  35. #include <vpquals.h>
  36. #include <vpserv.h>
  37. #include <vptasks.h>
  38. CStringW GetStringFromRPNToken(SQL_LEVEL_1_TOKEN* pRPNToken)
  39. {
  40. CStringW ret;
  41. if (NULL != pRPNToken->pPropertyName)
  42. {
  43. ret = L'(';
  44. ret += pRPNToken->pPropertyName;
  45. switch(pRPNToken->nOperator)
  46. {
  47. case SQL_LEVEL_1_TOKEN::OP_EQUAL:
  48. {
  49. ret += L'=';
  50. }
  51. break;
  52. case SQL_LEVEL_1_TOKEN::OP_NOT_EQUAL:
  53. {
  54. ret += L"<>";
  55. }
  56. break;
  57. case SQL_LEVEL_1_TOKEN::OP_EQUALorGREATERTHAN:
  58. {
  59. ret += L">=";
  60. }
  61. break;
  62. case SQL_LEVEL_1_TOKEN::OP_EQUALorLESSTHAN:
  63. {
  64. ret += L"<=";
  65. }
  66. break;
  67. case SQL_LEVEL_1_TOKEN::OP_LESSTHAN:
  68. {
  69. ret += L'<';
  70. }
  71. break;
  72. case SQL_LEVEL_1_TOKEN::OP_GREATERTHAN:
  73. {
  74. ret += L'>';
  75. }
  76. break;
  77. case SQL_LEVEL_1_TOKEN::OP_LIKE:
  78. {
  79. ret += L" like ";
  80. }
  81. break;
  82. default:
  83. {
  84. ret.Empty();
  85. }
  86. }
  87. if (!ret.IsEmpty())
  88. {
  89. switch (pRPNToken->vConstValue.vt)
  90. {
  91. case VT_NULL:
  92. {
  93. ret += L"null)";
  94. }
  95. break;
  96. case VT_BSTR:
  97. {
  98. if (pRPNToken->bConstIsStrNumeric)
  99. {
  100. ret += pRPNToken->vConstValue.bstrVal;
  101. ret += L')';
  102. }
  103. else
  104. {
  105. ret += L'\"';
  106. wchar_t* buff = new wchar_t[(wcslen(pRPNToken->vConstValue.bstrVal)*2) + 1];
  107. wchar_t* tmp = pRPNToken->vConstValue.bstrVal;
  108. wchar_t* tmpBuff = buff;
  109. while (*tmp != NULL)
  110. {
  111. if ((*tmp == L'\\') || (*tmp == L'"'))
  112. {
  113. *tmpBuff = L'\\';
  114. *tmpBuff++;
  115. }
  116. *tmpBuff = *tmp;
  117. *tmpBuff++;
  118. *tmp++;
  119. }
  120. *tmpBuff = 0;
  121. ret += buff;
  122. delete [] buff;
  123. ret += L"\")";
  124. }
  125. }
  126. break;
  127. case VT_BOOL:
  128. {
  129. if (pRPNToken->vConstValue.boolVal == VARIANT_TRUE)
  130. {
  131. ret += L"TRUE)";
  132. }
  133. else
  134. {
  135. ret += L"FALSE)";
  136. }
  137. }
  138. break ;
  139. case VT_I4:
  140. {
  141. WCHAR tmpBuff[20];
  142. tmpBuff[0] = L'\0';
  143. if ( swprintf(tmpBuff, L"%d", pRPNToken->vConstValue.lVal) )
  144. {
  145. ret += tmpBuff;
  146. ret += ')';
  147. }
  148. else
  149. {
  150. ret.Empty();
  151. }
  152. }
  153. break;
  154. case VT_I2:
  155. {
  156. WCHAR tmpBuff[20];
  157. tmpBuff[0] = L'\0';
  158. if ( swprintf(tmpBuff, L"%d", (int)pRPNToken->vConstValue.iVal) )
  159. {
  160. ret += tmpBuff;
  161. ret += ')';
  162. }
  163. else
  164. {
  165. ret.Empty();
  166. }
  167. }
  168. break;
  169. case VT_UI1:
  170. {
  171. WCHAR tmpBuff[20];
  172. tmpBuff[0] = L'\0';
  173. if ( swprintf(tmpBuff, L"%d", (int)pRPNToken->vConstValue.bVal) )
  174. {
  175. ret += tmpBuff;
  176. ret += ')';
  177. }
  178. else
  179. {
  180. ret.Empty();
  181. }
  182. }
  183. break;
  184. case VT_R4:
  185. {
  186. WCHAR tmpBuff[25];
  187. tmpBuff[0] = L'\0';
  188. if ( swprintf(tmpBuff, L"%G", pRPNToken->vConstValue.fltVal) )
  189. {
  190. ret += tmpBuff;
  191. ret += ')';
  192. }
  193. else
  194. {
  195. ret.Empty();
  196. }
  197. }
  198. break;
  199. case VT_R8:
  200. {
  201. WCHAR tmpBuff[25];
  202. tmpBuff[0] = L'\0';
  203. if ( swprintf(tmpBuff, L"%lG", pRPNToken->vConstValue.dblVal) )
  204. {
  205. ret += tmpBuff;
  206. ret += ')';
  207. }
  208. else
  209. {
  210. ret.Empty();
  211. }
  212. }
  213. break;
  214. default:
  215. {
  216. ret.Empty();
  217. }
  218. }
  219. }
  220. }
  221. return ret;
  222. }
  223. CStringW GetStringFromRPN(SQL_LEVEL_1_RPN_EXPRESSION* pRPN, DWORD num_extra,
  224. SQL_LEVEL_1_TOKEN* pExtraTokens, BOOL bAllprops)
  225. {
  226. CStringW ret;
  227. if (NULL == pRPN)
  228. {
  229. return ret;
  230. }
  231. if (NULL != pRPN->bsClassName)
  232. {
  233. CStringW props;
  234. if ((bAllprops) || (0 == pRPN->nNumberOfProperties))
  235. {
  236. props = L'*';
  237. }
  238. else
  239. {
  240. props = pRPN->pbsRequestedPropertyNames[0];
  241. for (int x = 1; x < pRPN->nNumberOfProperties; x++)
  242. {
  243. props += L", ";
  244. props += pRPN->pbsRequestedPropertyNames[x];
  245. }
  246. props += L", ";
  247. props += WBEM_PROPERTY_PATH;
  248. props += L", ";
  249. props += WBEM_PROPERTY_SERVER;
  250. }
  251. ret = L"Select ";
  252. ret += props;
  253. ret += L" From ";
  254. ret += pRPN->bsClassName;
  255. if ((0 != pRPN->nNumTokens) || (0 != num_extra))
  256. {
  257. CStringW whereStr;
  258. CArray<CStringW, LPCWSTR> exprStack;
  259. //not likely to get more than five expressions in a row!
  260. //if we do, we'll grow the array!
  261. exprStack.SetSize(0, 5);
  262. DWORD stack_count = 0;
  263. for (int x = 0; x < (pRPN->nNumTokens + num_extra); x++)
  264. {
  265. SQL_LEVEL_1_TOKEN* pToken;
  266. if (x < pRPN->nNumTokens)
  267. {
  268. pToken = &(pRPN->pArrayOfTokens[x]);
  269. }
  270. else
  271. {
  272. pToken = &(pExtraTokens[x - pRPN->nNumTokens]);
  273. }
  274. if (SQL_LEVEL_1_TOKEN::OP_EXPRESSION == pToken->nTokenType)
  275. {
  276. if (whereStr.IsEmpty())
  277. {
  278. whereStr = GetStringFromRPNToken(pToken);
  279. if (whereStr.IsEmpty())
  280. {
  281. ret.Empty();
  282. break;
  283. }
  284. }
  285. else
  286. {
  287. exprStack.SetAtGrow(stack_count, GetStringFromRPNToken(pToken));
  288. if (exprStack[stack_count].IsEmpty())
  289. {
  290. ret.Empty();
  291. break;
  292. }
  293. stack_count++;
  294. }
  295. }
  296. else if (SQL_LEVEL_1_TOKEN::TOKEN_NOT == pToken->nTokenType)
  297. {
  298. CStringW tempStr(L"(Not ");
  299. if (stack_count > 0)
  300. {
  301. tempStr += exprStack[stack_count-1];
  302. tempStr += L')';
  303. exprStack.SetAt(stack_count-1, tempStr);
  304. }
  305. else if (!whereStr.IsEmpty())
  306. {
  307. tempStr += whereStr;
  308. tempStr += L')';
  309. whereStr = tempStr;
  310. }
  311. else
  312. {
  313. ret.Empty();
  314. break;
  315. }
  316. }
  317. else
  318. {
  319. CStringW opStr;
  320. if (SQL_LEVEL_1_TOKEN::TOKEN_AND == pToken->nTokenType)
  321. {
  322. opStr = L" And ";
  323. }
  324. else if (SQL_LEVEL_1_TOKEN::TOKEN_OR == pToken->nTokenType)
  325. {
  326. opStr = L" Or ";
  327. }
  328. else
  329. {
  330. ret.Empty();
  331. break;
  332. }
  333. CStringW tempStr(L'(');
  334. if (stack_count > 1)
  335. {
  336. tempStr += exprStack[stack_count-2];
  337. tempStr += opStr;
  338. tempStr += exprStack[stack_count-1];
  339. tempStr += L')';
  340. exprStack.SetAt(stack_count-2, tempStr);
  341. stack_count = stack_count--;
  342. }
  343. else if (stack_count == 1)
  344. {
  345. tempStr += whereStr;
  346. tempStr += opStr;
  347. tempStr += exprStack[0];
  348. tempStr += L')';
  349. whereStr = tempStr;
  350. stack_count = 0;
  351. }
  352. else
  353. {
  354. ret.Empty();
  355. whereStr.Empty();
  356. break;
  357. }
  358. }
  359. }
  360. exprStack.RemoveAll();
  361. if (whereStr.IsEmpty() || (stack_count != 0))
  362. {
  363. ret.Empty();
  364. }
  365. else
  366. {
  367. ret += L" Where ";
  368. ret += whereStr;
  369. }
  370. }
  371. }
  372. return ret;
  373. }
  374. CSourceQualifierItem::CSourceQualifierItem(wchar_t* qry, IWbemClassObject* obj)
  375. : m_pClassObj(NULL), m_RPNExpr(NULL)
  376. {
  377. m_isValid = FALSE;
  378. m_QueryStr = qry;
  379. if (NULL != qry)
  380. {
  381. CTextLexSource querySource(qry);
  382. SQL1_Parser sqlParser(&querySource);
  383. m_isValid = SQL1_Parser::SUCCESS == sqlParser.Parse(&m_RPNExpr);
  384. }
  385. m_pClassObj = obj;
  386. if (NULL != m_pClassObj)
  387. {
  388. m_pClassObj->AddRef();
  389. }
  390. }
  391. CSourceQualifierItem::~CSourceQualifierItem()
  392. {
  393. if (NULL != m_RPNExpr)
  394. {
  395. delete m_RPNExpr;
  396. }
  397. if (NULL != m_pClassObj)
  398. {
  399. m_pClassObj->Release();
  400. }
  401. }
  402. void CSourceQualifierItem::SetClassObject(IWbemClassObject* pObj)
  403. {
  404. if (NULL != m_pClassObj)
  405. {
  406. m_pClassObj->Release();
  407. }
  408. if (NULL != pObj)
  409. {
  410. pObj->AddRef();
  411. }
  412. m_pClassObj = pObj;
  413. }
  414. IWbemClassObject* CSourceQualifierItem::GetClassObject()
  415. {
  416. if (NULL != m_pClassObj)
  417. {
  418. m_pClassObj->AddRef();
  419. }
  420. return m_pClassObj;
  421. }
  422. BSTR CSourceQualifierItem::GetClassName()
  423. {
  424. if (NULL != m_RPNExpr)
  425. {
  426. return m_RPNExpr->bsClassName;
  427. }
  428. return NULL;
  429. }
  430. CNSpaceQualifierItem::CNSpaceQualifierItem(const wchar_t* ns_path)
  431. {
  432. m_Valid = FALSE;
  433. m_ServObjs = NULL;
  434. m_NSPaths = NULL;
  435. m_Count = 0;
  436. if (NULL != ns_path)
  437. {
  438. Parse(ns_path);
  439. }
  440. }
  441. CNSpaceQualifierItem::~CNSpaceQualifierItem()
  442. {
  443. if (NULL != m_ServObjs)
  444. {
  445. for (UINT x = 0; x < m_Count; x++)
  446. {
  447. if (NULL != m_ServObjs[x])
  448. {
  449. m_ServObjs[x]->Release();
  450. }
  451. }
  452. delete [] m_ServObjs;
  453. }
  454. if (m_NSPaths != NULL)
  455. {
  456. delete [] m_NSPaths;
  457. }
  458. }
  459. void CNSpaceQualifierItem::Parse(const wchar_t* ns_path)
  460. {
  461. wchar_t* buff = _wcsdup(ns_path);
  462. if (buff == NULL)
  463. {
  464. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  465. }
  466. wchar_t* tmp = wcsstr(buff, NS_DELIMIT);
  467. CFreeBuff _1(buff);
  468. if (tmp == NULL)
  469. {
  470. m_NSPaths = new CStringW[1];
  471. m_NSPaths[0] = buff;
  472. m_NSPaths[0].TrimLeft();
  473. if (m_NSPaths[0].IsEmpty())
  474. {
  475. delete [] m_NSPaths;
  476. m_NSPaths = NULL;
  477. }
  478. else
  479. {
  480. m_Count = 1;
  481. m_Valid = TRUE;
  482. m_NSPaths[0].TrimRight();
  483. }
  484. }
  485. else
  486. {
  487. wchar_t** tmpbuff = (wchar_t**)malloc(MAX_QUERIES*sizeof(wchar_t*));
  488. if (tmpbuff == NULL)
  489. {
  490. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  491. }
  492. CFreeBuff _2(tmpbuff);
  493. if (tmp != buff)
  494. {
  495. tmpbuff[0] = buff;
  496. m_Count++;
  497. }
  498. while (TRUE)
  499. {
  500. *tmp = L'\0';
  501. tmp = tmp + 2;
  502. if (*tmp != L'\0')
  503. {
  504. tmpbuff[m_Count] = tmp;
  505. tmp = wcsstr(tmpbuff[m_Count], NS_DELIMIT);
  506. m_Count++;
  507. if (tmp == NULL)
  508. {
  509. break;
  510. }
  511. if ( (m_Count > 0) && (0 == (m_Count%MAX_QUERIES)) )
  512. {
  513. UINT x = _msize(tmpbuff);
  514. tmpbuff = (wchar_t**)realloc(tmpbuff, x+(MAX_QUERIES*sizeof(wchar_t*)));
  515. _2.SetBuff(tmpbuff);
  516. if (tmpbuff == NULL)
  517. {
  518. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  519. }
  520. }
  521. }
  522. else
  523. {
  524. break;
  525. }
  526. }
  527. if (m_Count > 0)
  528. {
  529. m_NSPaths = new CStringW[m_Count];
  530. for (UINT x=0; x < m_Count; x++)
  531. {
  532. m_NSPaths[x] = tmpbuff[x];
  533. m_NSPaths[x].TrimLeft();
  534. if (m_NSPaths[x].IsEmpty())
  535. {
  536. break;
  537. }
  538. else
  539. {
  540. m_NSPaths[x].TrimRight();
  541. }
  542. }
  543. if (!m_NSPaths[m_Count-1].IsEmpty())
  544. {
  545. m_Valid = TRUE;
  546. }
  547. }
  548. }
  549. }
  550. CJoinOnQualifierArray::CJoinOnQualifierArray()
  551. {
  552. m_Count = 0;
  553. m_AClasses = NULL;
  554. m_AProps = NULL;
  555. m_BClasses = NULL;
  556. m_BProps = NULL;
  557. m_Ops = NULL;
  558. m_Buff = NULL;
  559. m_Valid = FALSE;
  560. m_bDone = NULL;
  561. }
  562. CJoinOnQualifierArray::~CJoinOnQualifierArray()
  563. {
  564. if (NULL != m_AClasses)
  565. {
  566. free(m_AClasses);
  567. }
  568. if (NULL != m_BClasses)
  569. {
  570. free(m_BClasses);
  571. }
  572. if (NULL != m_AProps)
  573. {
  574. free(m_AProps);
  575. }
  576. if (NULL != m_BProps)
  577. {
  578. free(m_BProps);
  579. }
  580. if (NULL != m_Ops)
  581. {
  582. free(m_Ops);
  583. }
  584. if (NULL != m_Buff)
  585. {
  586. free(m_Buff);
  587. }
  588. if (NULL != m_bDone)
  589. {
  590. delete [] m_bDone;
  591. }
  592. m_AllClasses.RemoveAll();
  593. }
  594. BOOL CJoinOnQualifierArray::Set(const wchar_t* jStr)
  595. {
  596. if (NULL != jStr)
  597. {
  598. Parse(jStr);
  599. }
  600. return m_Valid;
  601. }
  602. void CJoinOnQualifierArray::Parse(const wchar_t* qualStr)
  603. {
  604. m_Buff = _wcsdup(qualStr);
  605. wchar_t* tmp = m_Buff;
  606. m_Valid = TRUE;
  607. m_AClasses = (wchar_t**)malloc(MAX_QUERIES*sizeof(wchar_t*));
  608. if (m_AClasses == NULL)
  609. {
  610. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  611. }
  612. m_BClasses = (wchar_t**)malloc(MAX_QUERIES*sizeof(wchar_t*));
  613. if (m_BClasses == NULL)
  614. {
  615. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  616. }
  617. m_AProps = (wchar_t**)malloc(MAX_QUERIES*sizeof(wchar_t*));
  618. if (m_AProps == NULL)
  619. {
  620. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  621. }
  622. m_BProps = (wchar_t**)malloc(MAX_QUERIES*sizeof(wchar_t*));
  623. if (m_BProps == NULL)
  624. {
  625. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  626. }
  627. m_Ops = (UINT*)malloc(MAX_QUERIES*sizeof(UINT));
  628. if (m_Ops == NULL)
  629. {
  630. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  631. }
  632. while ((tmp != NULL) && (L'\0' != *tmp) && (m_Valid))
  633. {
  634. m_AClasses[m_Count] = GetClassStr(tmp);
  635. if ((NULL != m_AClasses[m_Count]) && (L'\0' != *(m_AClasses[m_Count])))
  636. {
  637. m_AllClasses.SetAt(m_AClasses[m_Count], 0);
  638. m_AProps[m_Count] = GetPropertyStrAndOperator(tmp, m_Ops[m_Count]);
  639. if ((NULL != m_AProps[m_Count]) && (L'\0' != *(m_AProps[m_Count])) && (0 != m_Ops[m_Count]))
  640. {
  641. m_BClasses[m_Count] = GetClassStr(tmp);
  642. if ((NULL != m_BClasses[m_Count]) && (L'\0' != *(m_BClasses[m_Count])))
  643. {
  644. m_AllClasses.SetAt(m_BClasses[m_Count], 0);
  645. m_BProps[m_Count] = GetPropertyStr(tmp);
  646. if ((NULL != m_BProps[m_Count]) && (L'\0' != *(m_BProps[m_Count])) && StripAnd(tmp))
  647. {
  648. m_Count++;
  649. if ((tmp != NULL) && (L'\0' != *tmp) && (m_Count > 0) && (0 == (m_Count%MAX_QUERIES)) )
  650. {
  651. UINT x = _msize(m_AClasses);
  652. m_AClasses = (wchar_t**)realloc(m_AClasses, x+(MAX_QUERIES*sizeof(wchar_t*)));
  653. if (m_AClasses == NULL)
  654. {
  655. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  656. }
  657. m_BClasses = (wchar_t**)realloc(m_BClasses, x+(MAX_QUERIES*sizeof(wchar_t*)));
  658. if (m_BClasses == NULL)
  659. {
  660. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  661. }
  662. m_AProps = (wchar_t**)realloc(m_AProps, x+(MAX_QUERIES*sizeof(wchar_t*)));
  663. if (m_AProps == NULL)
  664. {
  665. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  666. }
  667. m_BProps = (wchar_t**)realloc(m_BProps, x+(MAX_QUERIES*sizeof(wchar_t*)));
  668. if (m_BProps == NULL)
  669. {
  670. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  671. }
  672. x = _msize(m_Ops);
  673. m_Ops = (UINT*)realloc(m_Ops, x+(MAX_QUERIES*sizeof(UINT)));
  674. if (m_Ops == NULL)
  675. {
  676. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  677. }
  678. }
  679. }
  680. else
  681. {
  682. m_Valid = FALSE;
  683. }
  684. }
  685. else
  686. {
  687. m_Valid = FALSE;
  688. }
  689. }
  690. else
  691. {
  692. m_Valid = FALSE;
  693. }
  694. }
  695. else
  696. {
  697. m_Valid = FALSE;
  698. }
  699. }
  700. if (0 == m_Count)
  701. {
  702. m_Valid = FALSE;
  703. }
  704. if (!m_Valid)
  705. {
  706. if (NULL != m_AClasses)
  707. {
  708. free(m_AClasses);
  709. m_AClasses = NULL;
  710. }
  711. if (NULL != m_BClasses)
  712. {
  713. free(m_BClasses);
  714. m_BClasses = NULL;
  715. }
  716. if (NULL != m_AProps)
  717. {
  718. free(m_AProps);
  719. m_AProps = NULL;
  720. }
  721. if (NULL != m_BProps)
  722. {
  723. free(m_BProps);
  724. m_BProps = NULL;
  725. }
  726. if (NULL != m_Ops)
  727. {
  728. free(m_Ops);
  729. m_Ops = NULL;
  730. }
  731. if (NULL != m_Buff)
  732. {
  733. free(m_Buff);
  734. m_Buff = NULL;
  735. }
  736. }
  737. else
  738. {
  739. m_bDone = new BOOL[m_Count];
  740. memset((void *)m_bDone, 0, sizeof(BOOL)*m_Count);
  741. }
  742. }
  743. wchar_t* CJoinOnQualifierArray::SkipSpace(wchar_t*& src)
  744. {
  745. while (iswspace(*src))
  746. {
  747. if (*src != L'\0')
  748. {
  749. *src = L'\0';
  750. src++;
  751. }
  752. }
  753. return ((*src == L'\0') ? NULL : src);
  754. }
  755. wchar_t* CJoinOnQualifierArray::SkipToSpecial(wchar_t*& src)
  756. {
  757. while ((*src != L'.') && (*src != L'=') && (*src != L'!') && (*src != L'<')
  758. && !iswspace(*src) && (*src != L'\0'))
  759. {
  760. src++;
  761. }
  762. return ((*src == L'\0') ? NULL : src);
  763. }
  764. wchar_t* CJoinOnQualifierArray::GetClassStr(wchar_t*& src)
  765. {
  766. wchar_t* ret = SkipSpace(src);
  767. if (NULL != ret)
  768. {
  769. src = SkipToSpecial(src);
  770. if ((NULL != src) && (src != ret) && ((*src == L'.')))
  771. {
  772. *src = L'\0';
  773. src++;
  774. }
  775. else
  776. {
  777. ret = NULL;
  778. }
  779. }
  780. return ret;
  781. }
  782. wchar_t* CJoinOnQualifierArray::GetPropertyStrAndOperator(wchar_t*& src, UINT& op)
  783. {
  784. wchar_t* ret = src;
  785. op = NO_OPERATOR;
  786. src = SkipToSpecial(src);
  787. src = SkipSpace(src);
  788. if ((NULL != src) && (src != ret))
  789. {
  790. if (*src == L'=')
  791. {
  792. *src = L'\0';
  793. op = EQUALS_OPERATOR;
  794. src++;
  795. }
  796. else if (*src == L'!')
  797. {
  798. wchar_t* prev = src;
  799. src++;
  800. if (*src == L'=')
  801. {
  802. *prev = L'\0';
  803. op = NOT_EQUALS_OPERATOR;
  804. src++;
  805. }
  806. else
  807. {
  808. ret = NULL;
  809. }
  810. }
  811. else if (*src == L'<')
  812. {
  813. wchar_t* prev = src;
  814. src++;
  815. if (*src == L'>')
  816. {
  817. *prev = L'\0';
  818. op = NOT_EQUALS_OPERATOR;
  819. src++;
  820. }
  821. else
  822. {
  823. ret = NULL;
  824. }
  825. }
  826. }
  827. else
  828. {
  829. ret = NULL;
  830. }
  831. return ret;
  832. }
  833. wchar_t* CJoinOnQualifierArray::GetPropertyStr(wchar_t*& src)
  834. {
  835. wchar_t* ret = src;
  836. src = SkipToSpecial(src);
  837. if (NULL != src)
  838. {
  839. if ( (src != ret) && iswspace(*src) )
  840. {
  841. if (*src != L'\0')
  842. {
  843. *src = L'\0';
  844. src++;
  845. }
  846. }
  847. else
  848. {
  849. ret = NULL;
  850. }
  851. }
  852. return ret;
  853. }
  854. BOOL CJoinOnQualifierArray::StripAnd(wchar_t*& src)
  855. {
  856. if (NULL == src)
  857. {
  858. return TRUE;
  859. }
  860. src = SkipSpace(src);
  861. if (NULL == src)
  862. {
  863. return TRUE;
  864. }
  865. if ((*src == L'a') || (*src == L'A'))
  866. {
  867. src++;
  868. if ((*src == L'n') || (*src == L'N'))
  869. {
  870. src++;
  871. if ((*src == L'd') || (*src == L'D'))
  872. {
  873. src++;
  874. wchar_t* tmp = src;
  875. src = SkipSpace(src);
  876. if ((NULL != src) && (tmp != src))
  877. {
  878. return TRUE;
  879. }
  880. }
  881. }
  882. }
  883. return FALSE;
  884. }
  885. BOOL CJoinOnQualifierArray::ValidateJoin()
  886. {
  887. if (!m_Valid)
  888. {
  889. return m_Valid;
  890. }
  891. CMap<CStringW, LPCWSTR, UINT, UINT> validatedClasses;
  892. CArray<CStringW, LPCWSTR> spareClasses;
  893. UINT x = 0;
  894. if (_wcsicmp(m_AClasses[x], m_BClasses[x]) == 0)
  895. {
  896. m_Valid = FALSE;
  897. }
  898. else
  899. {
  900. validatedClasses.SetAt(m_AClasses[x], 0);
  901. validatedClasses.SetAt(m_BClasses[x], 0);
  902. x++;
  903. }
  904. while ((m_Valid) && (x < m_Count))
  905. {
  906. if (_wcsicmp(m_AClasses[x], m_BClasses[x]) == 0)
  907. {
  908. m_Valid = FALSE;
  909. }
  910. else
  911. {
  912. UINT val;
  913. if (validatedClasses.Lookup(m_AClasses[x], val))
  914. {
  915. validatedClasses.SetAt(m_BClasses[x], 0);
  916. }
  917. else
  918. {
  919. if (validatedClasses.Lookup(m_BClasses[x], val))
  920. {
  921. validatedClasses.SetAt(m_AClasses[x], 0);
  922. }
  923. else
  924. {
  925. spareClasses.Add(m_AClasses[x]);
  926. spareClasses.Add(m_BClasses[x]);
  927. }
  928. }
  929. }
  930. x++;
  931. }
  932. while ( m_Valid && (0 != spareClasses.GetSize()) )
  933. {
  934. m_Valid = FALSE;
  935. for (int i = 0; i < spareClasses.GetSize(); i++)
  936. {
  937. UINT val;
  938. if (validatedClasses.Lookup(spareClasses[i], val))
  939. {
  940. if (0 == (i%2))
  941. {
  942. validatedClasses.SetAt(spareClasses[i+1], 0);
  943. spareClasses.RemoveAt(i, 2);
  944. i -= 1;
  945. }
  946. else
  947. {
  948. validatedClasses.SetAt(spareClasses[i-1], 0);
  949. spareClasses.RemoveAt(i-1, 2);
  950. i -= 2;
  951. }
  952. m_Valid = TRUE;
  953. }
  954. }
  955. }
  956. spareClasses.RemoveAll();
  957. validatedClasses.RemoveAll();
  958. return m_Valid;
  959. }
  960. CPropertyQualifierItem::CPropertyQualifierItem(const wchar_t* prop, BOOL bHD, BOOL bKy, CIMTYPE ct, CStringW rfto, BOOL bDt)
  961. {
  962. if (NULL != prop)
  963. {
  964. m_ViewPropertyName = prop;
  965. }
  966. m_bDirect = bDt;
  967. m_HiddenDefault = bHD;
  968. m_bKey = bKy;
  969. m_CimType = ct;
  970. m_RefTo = rfto;
  971. }
  972. CPropertyQualifierItem::~CPropertyQualifierItem()
  973. {
  974. m_SrcPropertyNames.RemoveAll();
  975. }