Leaked source code of windows server 2003
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.

1122 lines
19 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. m_Valid (FALSE),
  432. m_ServObjs (NULL),
  433. m_NSPaths (NULL),
  434. m_Count (0),
  435. m_hrServError ( WBEM_S_NO_ERROR )
  436. {
  437. if (NULL != ns_path)
  438. {
  439. Parse(ns_path);
  440. }
  441. }
  442. CNSpaceQualifierItem::~CNSpaceQualifierItem()
  443. {
  444. if (NULL != m_ServObjs)
  445. {
  446. for (UINT x = 0; x < m_Count; x++)
  447. {
  448. if (NULL != m_ServObjs[x])
  449. {
  450. m_ServObjs[x]->Release();
  451. }
  452. }
  453. delete [] m_ServObjs;
  454. }
  455. if (m_NSPaths != NULL)
  456. {
  457. delete [] m_NSPaths;
  458. }
  459. }
  460. void CNSpaceQualifierItem::Parse(const wchar_t* ns_path)
  461. {
  462. wchar_t* buff = _wcsdup(ns_path);
  463. if (buff == NULL)
  464. {
  465. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  466. }
  467. wchar_t* tmp = wcsstr(buff, NS_DELIMIT);
  468. CFreeBuff _1(buff);
  469. if (tmp == NULL)
  470. {
  471. m_NSPaths = new CStringW[1];
  472. m_NSPaths[0] = buff;
  473. m_NSPaths[0].TrimLeft();
  474. if (m_NSPaths[0].IsEmpty())
  475. {
  476. delete [] m_NSPaths;
  477. m_NSPaths = NULL;
  478. }
  479. else
  480. {
  481. m_Count = 1;
  482. m_Valid = TRUE;
  483. m_NSPaths[0].TrimRight();
  484. }
  485. }
  486. else
  487. {
  488. wchar_t** tmpbuff = (wchar_t**)malloc(MAX_QUERIES*sizeof(wchar_t*));
  489. if (tmpbuff == NULL)
  490. {
  491. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  492. }
  493. CFreeBuff _2(tmpbuff);
  494. if (tmp != buff)
  495. {
  496. tmpbuff[0] = buff;
  497. m_Count++;
  498. }
  499. while (TRUE)
  500. {
  501. *tmp = L'\0';
  502. tmp = tmp + 2;
  503. if (*tmp != L'\0')
  504. {
  505. tmpbuff[m_Count] = tmp;
  506. tmp = wcsstr(tmpbuff[m_Count], NS_DELIMIT);
  507. m_Count++;
  508. if (tmp == NULL)
  509. {
  510. break;
  511. }
  512. if ( (m_Count > 0) && (0 == (m_Count%MAX_QUERIES)) )
  513. {
  514. UINT x = _msize(tmpbuff);
  515. wchar_t** tmp = (wchar_t**)realloc(tmpbuff, x+(MAX_QUERIES*sizeof(wchar_t*)));
  516. if (tmp == NULL)
  517. {
  518. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  519. }
  520. tmpbuff = tmp;
  521. _2.SetBuff(tmpbuff);
  522. }
  523. }
  524. else
  525. {
  526. break;
  527. }
  528. }
  529. if (m_Count > 0)
  530. {
  531. m_NSPaths = new CStringW[m_Count];
  532. for (UINT x=0; x < m_Count; x++)
  533. {
  534. m_NSPaths[x] = tmpbuff[x];
  535. m_NSPaths[x].TrimLeft();
  536. if (m_NSPaths[x].IsEmpty())
  537. {
  538. break;
  539. }
  540. else
  541. {
  542. m_NSPaths[x].TrimRight();
  543. }
  544. }
  545. if (!m_NSPaths[m_Count-1].IsEmpty())
  546. {
  547. m_Valid = TRUE;
  548. }
  549. }
  550. }
  551. }
  552. CJoinOnQualifierArray::CJoinOnQualifierArray()
  553. {
  554. m_Count = 0;
  555. m_AClasses = NULL;
  556. m_AProps = NULL;
  557. m_BClasses = NULL;
  558. m_BProps = NULL;
  559. m_Ops = NULL;
  560. m_Buff = NULL;
  561. m_Valid = FALSE;
  562. m_bDone = NULL;
  563. }
  564. CJoinOnQualifierArray::~CJoinOnQualifierArray()
  565. {
  566. if (NULL != m_AClasses)
  567. {
  568. free(m_AClasses);
  569. }
  570. if (NULL != m_BClasses)
  571. {
  572. free(m_BClasses);
  573. }
  574. if (NULL != m_AProps)
  575. {
  576. free(m_AProps);
  577. }
  578. if (NULL != m_BProps)
  579. {
  580. free(m_BProps);
  581. }
  582. if (NULL != m_Ops)
  583. {
  584. free(m_Ops);
  585. }
  586. if (NULL != m_Buff)
  587. {
  588. free(m_Buff);
  589. }
  590. if (NULL != m_bDone)
  591. {
  592. delete [] m_bDone;
  593. }
  594. m_AllClasses.RemoveAll();
  595. }
  596. BOOL CJoinOnQualifierArray::Set(const wchar_t* jStr)
  597. {
  598. if (NULL != jStr)
  599. {
  600. Parse(jStr);
  601. }
  602. return m_Valid;
  603. }
  604. void CJoinOnQualifierArray::Parse(const wchar_t* qualStr)
  605. {
  606. m_Buff = _wcsdup(qualStr);
  607. wchar_t* tmp = m_Buff;
  608. m_Valid = TRUE;
  609. m_AClasses = (wchar_t**)malloc(MAX_QUERIES*sizeof(wchar_t*));
  610. if (m_AClasses == NULL)
  611. {
  612. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  613. }
  614. m_BClasses = (wchar_t**)malloc(MAX_QUERIES*sizeof(wchar_t*));
  615. if (m_BClasses == NULL)
  616. {
  617. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  618. }
  619. m_AProps = (wchar_t**)malloc(MAX_QUERIES*sizeof(wchar_t*));
  620. if (m_AProps == NULL)
  621. {
  622. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  623. }
  624. m_BProps = (wchar_t**)malloc(MAX_QUERIES*sizeof(wchar_t*));
  625. if (m_BProps == NULL)
  626. {
  627. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  628. }
  629. m_Ops = (UINT*)malloc(MAX_QUERIES*sizeof(UINT));
  630. if (m_Ops == NULL)
  631. {
  632. throw Heap_Exception(Heap_Exception::HEAP_ERROR::E_ALLOCATION_ERROR);
  633. }
  634. while ((tmp != NULL) && (L'\0' != *tmp) && (m_Valid))
  635. {
  636. m_AClasses[m_Count] = GetClassStr(tmp);
  637. if ((NULL != m_AClasses[m_Count]) && (L'\0' != *(m_AClasses[m_Count])))
  638. {
  639. m_AllClasses.SetAt(m_AClasses[m_Count], 0);
  640. m_AProps[m_Count] = GetPropertyStrAndOperator(tmp, m_Ops[m_Count]);
  641. if ((NULL != m_AProps[m_Count]) && (L'\0' != *(m_AProps[m_Count])) && (0 != m_Ops[m_Count]))
  642. {
  643. m_BClasses[m_Count] = GetClassStr(tmp);
  644. if ((NULL != m_BClasses[m_Count]) && (L'\0' != *(m_BClasses[m_Count])))
  645. {
  646. m_AllClasses.SetAt(m_BClasses[m_Count], 0);
  647. m_BProps[m_Count] = GetPropertyStr(tmp);
  648. if ((NULL != m_BProps[m_Count]) && (L'\0' != *(m_BProps[m_Count])) && StripAnd(tmp))
  649. {
  650. m_Count++;
  651. if ((tmp != NULL) && (L'\0' != *tmp) && (m_Count > 0) && (0 == (m_Count%MAX_QUERIES)) )
  652. {
  653. UINT x = _msize(m_AClasses);
  654. realloc_throw(&m_AClasses, x+(MAX_QUERIES*sizeof(wchar_t*)));
  655. realloc_throw(&m_BClasses, x+(MAX_QUERIES*sizeof(wchar_t*)));
  656. realloc_throw(&m_AProps, x+(MAX_QUERIES*sizeof(wchar_t*)));
  657. realloc_throw(&m_BProps, x+(MAX_QUERIES*sizeof(wchar_t*)));
  658. x = _msize(m_Ops);
  659. realloc_throw(&m_Ops, x+(MAX_QUERIES*sizeof(UINT)));
  660. }
  661. }
  662. else
  663. {
  664. m_Valid = FALSE;
  665. }
  666. }
  667. else
  668. {
  669. m_Valid = FALSE;
  670. }
  671. }
  672. else
  673. {
  674. m_Valid = FALSE;
  675. }
  676. }
  677. else
  678. {
  679. m_Valid = FALSE;
  680. }
  681. }
  682. if (0 == m_Count)
  683. {
  684. m_Valid = FALSE;
  685. }
  686. if (!m_Valid)
  687. {
  688. if (NULL != m_AClasses)
  689. {
  690. free(m_AClasses);
  691. m_AClasses = NULL;
  692. }
  693. if (NULL != m_BClasses)
  694. {
  695. free(m_BClasses);
  696. m_BClasses = NULL;
  697. }
  698. if (NULL != m_AProps)
  699. {
  700. free(m_AProps);
  701. m_AProps = NULL;
  702. }
  703. if (NULL != m_BProps)
  704. {
  705. free(m_BProps);
  706. m_BProps = NULL;
  707. }
  708. if (NULL != m_Ops)
  709. {
  710. free(m_Ops);
  711. m_Ops = NULL;
  712. }
  713. if (NULL != m_Buff)
  714. {
  715. free(m_Buff);
  716. m_Buff = NULL;
  717. }
  718. }
  719. else
  720. {
  721. m_bDone = new BOOL[m_Count];
  722. memset((void *)m_bDone, 0, sizeof(BOOL)*m_Count);
  723. }
  724. }
  725. wchar_t* CJoinOnQualifierArray::SkipSpace(wchar_t*& src)
  726. {
  727. while (iswspace(*src))
  728. {
  729. if (*src != L'\0')
  730. {
  731. *src = L'\0';
  732. src++;
  733. }
  734. }
  735. return ((*src == L'\0') ? NULL : src);
  736. }
  737. wchar_t* CJoinOnQualifierArray::SkipToSpecial(wchar_t*& src)
  738. {
  739. while ((*src != L'.') && (*src != L'=') && (*src != L'!') && (*src != L'<')
  740. && !iswspace(*src) && (*src != L'\0'))
  741. {
  742. src++;
  743. }
  744. return ((*src == L'\0') ? NULL : src);
  745. }
  746. wchar_t* CJoinOnQualifierArray::GetClassStr(wchar_t*& src)
  747. {
  748. wchar_t* ret = SkipSpace(src);
  749. if (NULL != ret)
  750. {
  751. src = SkipToSpecial(src);
  752. if ((NULL != src) && (src != ret) && ((*src == L'.')))
  753. {
  754. *src = L'\0';
  755. src++;
  756. }
  757. else
  758. {
  759. ret = NULL;
  760. }
  761. }
  762. return ret;
  763. }
  764. wchar_t* CJoinOnQualifierArray::GetPropertyStrAndOperator(wchar_t*& src, UINT& op)
  765. {
  766. wchar_t* ret = src;
  767. op = NO_OPERATOR;
  768. src = SkipToSpecial(src);
  769. src = SkipSpace(src);
  770. if ((NULL != src) && (src != ret))
  771. {
  772. if (*src == L'=')
  773. {
  774. *src = L'\0';
  775. op = EQUALS_OPERATOR;
  776. src++;
  777. }
  778. else if (*src == L'!')
  779. {
  780. wchar_t* prev = src;
  781. src++;
  782. if (*src == L'=')
  783. {
  784. *prev = L'\0';
  785. op = NOT_EQUALS_OPERATOR;
  786. src++;
  787. }
  788. else
  789. {
  790. ret = NULL;
  791. }
  792. }
  793. else if (*src == L'<')
  794. {
  795. wchar_t* prev = src;
  796. src++;
  797. if (*src == L'>')
  798. {
  799. *prev = L'\0';
  800. op = NOT_EQUALS_OPERATOR;
  801. src++;
  802. }
  803. else
  804. {
  805. ret = NULL;
  806. }
  807. }
  808. }
  809. else
  810. {
  811. ret = NULL;
  812. }
  813. return ret;
  814. }
  815. wchar_t* CJoinOnQualifierArray::GetPropertyStr(wchar_t*& src)
  816. {
  817. wchar_t* ret = src;
  818. src = SkipToSpecial(src);
  819. if (NULL != src)
  820. {
  821. if ( (src != ret) && iswspace(*src) )
  822. {
  823. if (*src != L'\0')
  824. {
  825. *src = L'\0';
  826. src++;
  827. }
  828. }
  829. else
  830. {
  831. ret = NULL;
  832. }
  833. }
  834. return ret;
  835. }
  836. BOOL CJoinOnQualifierArray::StripAnd(wchar_t*& src)
  837. {
  838. if (NULL == src)
  839. {
  840. return TRUE;
  841. }
  842. src = SkipSpace(src);
  843. if (NULL == src)
  844. {
  845. return TRUE;
  846. }
  847. if ((*src == L'a') || (*src == L'A'))
  848. {
  849. src++;
  850. if ((*src == L'n') || (*src == L'N'))
  851. {
  852. src++;
  853. if ((*src == L'd') || (*src == L'D'))
  854. {
  855. src++;
  856. wchar_t* tmp = src;
  857. src = SkipSpace(src);
  858. if ((NULL != src) && (tmp != src))
  859. {
  860. return TRUE;
  861. }
  862. }
  863. }
  864. }
  865. return FALSE;
  866. }
  867. BOOL CJoinOnQualifierArray::ValidateJoin()
  868. {
  869. if (!m_Valid)
  870. {
  871. return m_Valid;
  872. }
  873. CMap<CStringW, LPCWSTR, UINT, UINT> validatedClasses;
  874. CArray<CStringW, LPCWSTR> spareClasses;
  875. UINT x = 0;
  876. if (_wcsicmp(m_AClasses[x], m_BClasses[x]) == 0)
  877. {
  878. m_Valid = FALSE;
  879. }
  880. else
  881. {
  882. validatedClasses.SetAt(m_AClasses[x], 0);
  883. validatedClasses.SetAt(m_BClasses[x], 0);
  884. x++;
  885. }
  886. while ((m_Valid) && (x < m_Count))
  887. {
  888. if (_wcsicmp(m_AClasses[x], m_BClasses[x]) == 0)
  889. {
  890. m_Valid = FALSE;
  891. }
  892. else
  893. {
  894. UINT val;
  895. if (validatedClasses.Lookup(m_AClasses[x], val))
  896. {
  897. validatedClasses.SetAt(m_BClasses[x], 0);
  898. }
  899. else
  900. {
  901. if (validatedClasses.Lookup(m_BClasses[x], val))
  902. {
  903. validatedClasses.SetAt(m_AClasses[x], 0);
  904. }
  905. else
  906. {
  907. spareClasses.Add(m_AClasses[x]);
  908. spareClasses.Add(m_BClasses[x]);
  909. }
  910. }
  911. }
  912. x++;
  913. }
  914. while ( m_Valid && (0 != spareClasses.GetSize()) )
  915. {
  916. m_Valid = FALSE;
  917. for (int i = 0; i < spareClasses.GetSize(); i++)
  918. {
  919. UINT val;
  920. if (validatedClasses.Lookup(spareClasses[i], val))
  921. {
  922. if (0 == (i%2))
  923. {
  924. validatedClasses.SetAt(spareClasses[i+1], 0);
  925. spareClasses.RemoveAt(i, 2);
  926. i -= 1;
  927. }
  928. else
  929. {
  930. validatedClasses.SetAt(spareClasses[i-1], 0);
  931. spareClasses.RemoveAt(i-1, 2);
  932. i -= 2;
  933. }
  934. m_Valid = TRUE;
  935. }
  936. }
  937. }
  938. spareClasses.RemoveAll();
  939. validatedClasses.RemoveAll();
  940. return m_Valid;
  941. }
  942. CPropertyQualifierItem::CPropertyQualifierItem(const wchar_t* prop, BOOL bHD, BOOL bKy, CIMTYPE ct, CStringW rfto, BOOL bDt)
  943. {
  944. if (NULL != prop)
  945. {
  946. m_ViewPropertyName = prop;
  947. }
  948. m_bDirect = bDt;
  949. m_HiddenDefault = bHD;
  950. m_bKey = bKy;
  951. m_CimType = ct;
  952. m_RefTo = rfto;
  953. }
  954. CPropertyQualifierItem::~CPropertyQualifierItem()
  955. {
  956. m_SrcPropertyNames.RemoveAll();
  957. }