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.

785 lines
22 KiB

  1. /*++
  2. Copyright (C) 1996-1999 Microsoft Corporation
  3. Module Name:
  4. TWOPROPNODE.CPP
  5. Abstract:
  6. Two Prop Node
  7. History:
  8. --*/
  9. // classes to support a two-property node for the eval tree
  10. // this will be much like the CPropertyNode defined in EvalTree.h
  11. // but it will compare a property against another property
  12. // rather than a property to a constant
  13. #include "precomp.h"
  14. #include <stdio.h>
  15. #pragma warning(disable:4786)
  16. #include <wbemcomn.h>
  17. #include <genutils.h>
  18. #include "TwoPropNode.h"
  19. // warning about performance hits when converting an int to a bool
  20. #pragma warning(disable: 4800)
  21. // this is only a test
  22. // TTwoScalarPropNode<int> foolishMortal;
  23. // set offset into object for the right property
  24. // "tell me which property I'm operating on"
  25. void CTwoPropNode::SetRightPropertyInfo(LPCWSTR wszPropName, long lPropHandle)
  26. {
  27. m_lRightPropHandle = lPropHandle;
  28. }
  29. void CTwoPropNode::SetRightEmbeddingInfo(const CEmbeddingInfo* pInfo)
  30. {
  31. try
  32. {
  33. if (pInfo && !pInfo->IsEmpty())
  34. {
  35. if (!m_pRightInfo)
  36. m_pRightInfo = new CEmbeddingInfo(*pInfo);
  37. else
  38. *m_pRightInfo = *pInfo;
  39. }
  40. else
  41. {
  42. delete m_pRightInfo;
  43. m_pRightInfo = NULL;
  44. }
  45. }
  46. catch(CX_MemoryException)
  47. {
  48. }
  49. }
  50. HRESULT CTwoPropNode::GetRightContainerObject(CObjectInfo& ObjInfo,
  51. INTERNAL _IWmiObject** ppInst)
  52. {
  53. if (!m_pRightInfo)
  54. {
  55. *ppInst = ObjInfo.GetObjectAt(0);
  56. return WBEM_S_NO_ERROR;
  57. }
  58. else
  59. return m_pRightInfo->GetContainerObject(ObjInfo, ppInst);
  60. }
  61. HRESULT CTwoPropNode::CompileRightEmbeddingPortion(CContextMetaData* pNamespace,
  62. CImplicationList& Implications,
  63. _IWmiObject** ppResultClass)
  64. {
  65. if (!m_pRightInfo)
  66. return WBEM_E_FAILED;
  67. else
  68. return m_pRightInfo->Compile(pNamespace, Implications, ppResultClass);
  69. }
  70. void CTwoPropNode::SetRightEmbeddedObjPropName(CPropertyName& Name)
  71. {
  72. if (m_pRightInfo)
  73. m_pRightInfo->SetEmbeddedObjPropName(Name);
  74. }
  75. void CTwoPropNode::MixInJumpsRightObj(const CEmbeddingInfo* pParent)
  76. {
  77. if (pParent && m_pRightInfo)
  78. m_pRightInfo->MixInJumps(pParent);
  79. }
  80. CPropertyName* CTwoPropNode::GetRightEmbeddedObjPropName()
  81. {
  82. if (!m_pRightInfo)
  83. return NULL;
  84. else
  85. return m_pRightInfo->GetEmbeddedObjPropName();
  86. }
  87. // compare precedence of this node to that node
  88. int CTwoPropNode::ComparePrecedence(CBranchingNode* pOther)
  89. {
  90. int nCompare;
  91. nCompare = GetSubType() - pOther->GetSubType();
  92. if(nCompare) return nCompare;
  93. CTwoPropNode* pOtherNode = (CTwoPropNode*)pOther;
  94. nCompare = m_pRightInfo->ComparePrecedence(pOtherNode->m_pRightInfo);
  95. if (nCompare == 0)
  96. {
  97. nCompare = CPropertyNode::ComparePrecedence(pOther);
  98. if (nCompare == 0)
  99. nCompare = m_lRightPropHandle - pOtherNode->m_lRightPropHandle;
  100. }
  101. return nCompare;
  102. }
  103. HRESULT CTwoPropNode::AdjustCompile(CContextMetaData* pNamespace,
  104. CImplicationList& Implications)
  105. {
  106. HRESULT hRes;
  107. if (SUCCEEDED(hRes = CBranchingNode::AdjustCompile(pNamespace, Implications)))
  108. if (m_pRightInfo)
  109. hRes = m_pRightInfo->Compile(pNamespace, Implications, NULL);
  110. else
  111. hRes = WBEM_E_FAILED;
  112. return hRes;
  113. }
  114. HRESULT CTwoPropNode::OptimizeSelf()
  115. {
  116. // can't combine our three branches - nothing to do.
  117. return WBEM_S_NO_ERROR;
  118. }
  119. HRESULT CTwoPropNode::SetTest(VARIANT& v)
  120. {
  121. // again, nothing to do, our test is determined by the Right side property
  122. // (this should never be called, but doesn't hurt anything)
  123. return WBEM_S_NO_ERROR;
  124. }
  125. void CTwoPropNode::Dump(FILE* f, int nOffset)
  126. {
  127. PrintOffset(f, nOffset);
  128. if (m_pInfo)
  129. m_pInfo->Dump(f);
  130. if (m_pRightInfo)
  131. m_pRightInfo->Dump(f);
  132. fprintf(f, ", LeftPropHandle = (0x%x)\n", m_lPropHandle);
  133. fprintf(f, ", RightPropHandle = (0x%x)\n", m_lRightPropHandle);
  134. fprintf(f, "Branches:\n");
  135. PrintOffset(f, nOffset);
  136. // "i = (Operations)((int)(i) + 1)" is basically i++, with all the BS needed to make the compiler happy.
  137. // thank you K&R for saddling us with a nearly useless enum type!
  138. for (Operations i = LT; i < NOperations; i = (Operations)((int)(i) + 1))
  139. {
  140. DumpNode(f, nOffset+1, m_apBranches[i]);
  141. fprintf(f, "\n");
  142. }
  143. fprintf(f, "NULL->\n");
  144. DumpNode(f, nOffset+1, m_pNullBranch);
  145. }
  146. int CTwoPropNode::SubCompare(CEvalNode* pRawOther)
  147. {
  148. CTwoPropNode* pOther =
  149. (CTwoPropNode*)pRawOther;
  150. int nCompare;
  151. nCompare = m_lPropHandle - pOther->m_lPropHandle;
  152. if(nCompare)
  153. return nCompare;
  154. nCompare = m_lRightPropHandle - pOther->m_lRightPropHandle;
  155. if(nCompare)
  156. return nCompare;
  157. nCompare = m_apBranches.GetSize() - pOther->m_apBranches.GetSize();
  158. if(nCompare)
  159. return nCompare;
  160. return TRUE;
  161. }
  162. HRESULT CTwoPropNode::CombineBranchesWith(CBranchingNode* pArg2, int nOp,
  163. CContextMetaData* pNamespace,
  164. CImplicationList& Implications,
  165. bool bDeleteThis, bool bDeleteArg2,
  166. CEvalNode** ppRes)
  167. {
  168. // step one, determine whether we can reuse a node
  169. CTwoPropNode* pNewNode = NULL;
  170. CTwoPropNode* pDeleteMe = NULL;
  171. if (bDeleteThis && bDeleteArg2)
  172. {
  173. pNewNode = this;
  174. pDeleteMe = (CTwoPropNode*) pArg2;
  175. }
  176. else if (bDeleteThis)
  177. pNewNode = this;
  178. else if (bDeleteArg2)
  179. pNewNode = (CTwoPropNode*) pArg2;
  180. else
  181. pNewNode = CloneSelfWithoutChildren();
  182. HRESULT hRes = WBEM_S_NO_ERROR;
  183. CTwoPropNode* pOther = (CTwoPropNode*)pArg2;
  184. for (int i = LT; i < NOperations && SUCCEEDED(hRes); i++)
  185. {
  186. CEvalNode* pNewChildNode = NULL;
  187. hRes = CEvalTree::Combine( m_apBranches[i], pOther->m_apBranches[i],
  188. nOp, pNamespace, Implications, bDeleteThis,
  189. bDeleteArg2, &pNewChildNode);
  190. if ( FAILED(hRes) )
  191. break;
  192. if (bDeleteArg2)
  193. pOther->m_apBranches.Discard(i);
  194. if (bDeleteThis)
  195. m_apBranches.Discard(i);
  196. pNewNode->m_apBranches.Discard(i);
  197. pNewNode->m_apBranches.SetAt(i, pNewChildNode);
  198. }
  199. if (SUCCEEDED(hRes))
  200. {
  201. if(pDeleteMe)
  202. {
  203. pDeleteMe->m_pNullBranch = NULL;
  204. delete pDeleteMe;
  205. }
  206. *ppRes = pNewNode;
  207. }
  208. else
  209. {
  210. *ppRes = NULL;
  211. }
  212. return hRes;
  213. }
  214. // given a property handle, will retrieve proper property, probably.
  215. CVar* CTwoPropNode::GetPropVariant(_IWmiObject* pObj, long lHandle, CIMTYPE* pct)
  216. {
  217. CVar *pVar = NULL;
  218. BSTR bstrName;
  219. if (SUCCEEDED(pObj->GetPropertyInfoByHandle(lHandle, &bstrName, pct)))
  220. {
  221. CSysFreeMe sfm(bstrName);
  222. //
  223. // Get it into a VARIANT
  224. //
  225. VARIANT v;
  226. if(FAILED(pObj->Get(bstrName, 0, &v, NULL, NULL)))
  227. return NULL;
  228. // Convert it to a CVar
  229. if (pVar = new CVar)
  230. pVar->SetVariant(&v);
  231. VariantClear( &v );
  232. }
  233. return pVar;
  234. }
  235. // ***************************
  236. // **** Two String Prop Node ****
  237. // ***************************
  238. CEvalNode* CTwoStringPropNode::Clone() const
  239. {
  240. return (CEvalNode *) new CTwoStringPropNode(*this, true);
  241. }
  242. CTwoPropNode* CTwoStringPropNode::CloneSelfWithoutChildren() const
  243. {
  244. return (CTwoPropNode *) new CTwoStringPropNode(*this, false);
  245. }
  246. long CTwoStringPropNode::GetSubType()
  247. {
  248. return EVAL_NODE_TYPE_TWO_STRINGS;
  249. }
  250. HRESULT CTwoStringPropNode::Evaluate(CObjectInfo& ObjInfo,
  251. INTERNAL CEvalNode** ppNext)
  252. {
  253. HRESULT herslut = WBEM_S_NO_ERROR;
  254. _IWmiObject* pLeftObj;
  255. _IWmiObject* pRightObj;
  256. if(SUCCEEDED(herslut = GetContainerObject(ObjInfo, &pLeftObj))
  257. &&
  258. SUCCEEDED(herslut = GetRightContainerObject(ObjInfo, &pRightObj)))
  259. {
  260. CCompressedString* pLeftStr;
  261. CCompressedString* pRightStr;
  262. pLeftStr = CoreGetPropertyString(pLeftObj, m_lPropHandle);
  263. pRightStr = CoreGetPropertyString(pRightObj, m_lRightPropHandle);
  264. if ((pLeftStr == NULL) || (pRightStr == NULL))
  265. {
  266. *ppNext = m_pNullBranch;
  267. herslut = WBEM_S_NO_ERROR;
  268. }
  269. else
  270. {
  271. int nCompare = pLeftStr->CheapCompare(*pRightStr);
  272. // TODO: check to see if CheapCompare is guaranteed to return -1,0,1
  273. // if so, then the multiple else if becomes
  274. // *ppNext = m_apBranches[EQ + nCompare];
  275. if (nCompare < 0)
  276. *ppNext = m_apBranches[LT];
  277. else if (nCompare > 0)
  278. *ppNext = m_apBranches[GT];
  279. else
  280. *ppNext = m_apBranches[EQ];
  281. herslut = WBEM_S_NO_ERROR;
  282. }
  283. }
  284. return herslut;
  285. }
  286. // *******************************
  287. // **** Two Mismatched Prop Node ****
  288. // *******************************
  289. HRESULT CTwoMismatchedPropNode::Evaluate(CObjectInfo& ObjInfo, INTERNAL CEvalNode** ppNext)
  290. {
  291. CVar *pLeftVar = NULL;
  292. CVar *pRightVar = NULL;
  293. *ppNext = NULL;
  294. HRESULT hr = WBEM_E_FAILED; // guilty until proven innocent
  295. CIMTYPE ct;
  296. _IWmiObject* pLeftObj = NULL;
  297. _IWmiObject* pRightObj = NULL;
  298. // if we can get the objects and variants...
  299. if ((SUCCEEDED(hr = GetContainerObject(ObjInfo, &pLeftObj))
  300. &&
  301. SUCCEEDED(hr = GetRightContainerObject(ObjInfo, &pRightObj)))
  302. &&
  303. (pLeftVar = GetPropVariant(pLeftObj, m_lPropHandle, &ct))
  304. &&
  305. (pRightVar = GetPropVariant(pRightObj, m_lRightPropHandle, &ct)) )
  306. {
  307. if (pLeftVar->IsDataNull() || pRightVar->IsDataNull())
  308. {
  309. *ppNext = m_pNullBranch;
  310. hr = WBEM_S_NO_ERROR;
  311. }
  312. else
  313. hr = Evaluate(pLeftVar, pRightVar, ppNext);
  314. }
  315. else if (SUCCEEDED(hr))
  316. // if we got here, it's because one of the GetPropVariant's didn't
  317. hr = WBEM_E_INVALID_PARAMETER;
  318. delete pLeftVar;
  319. delete pRightVar;
  320. return hr;
  321. }
  322. // **************************************
  323. // **** Two Mismatched String Prop Node ****
  324. // **************************************
  325. CEvalNode* CTwoMismatchedStringNode::Clone() const
  326. {
  327. return (CEvalNode *) new CTwoMismatchedStringNode(*this, true);
  328. }
  329. CTwoPropNode* CTwoMismatchedStringNode::CloneSelfWithoutChildren() const
  330. {
  331. return (CTwoPropNode *) new CTwoMismatchedStringNode(*this, false);
  332. }
  333. // type identification
  334. long CTwoMismatchedStringNode::GetSubType()
  335. {
  336. return EVAL_NODE_TYPE_MISMATCHED_STRINGS;
  337. }
  338. // string evaluation: promote them all to strings
  339. // and do a lexagraphic compare..
  340. HRESULT CTwoMismatchedStringNode::Evaluate(CVar *pLeftVar, CVar *pRightVar, INTERNAL CEvalNode** ppNext)
  341. {
  342. *ppNext = NULL;
  343. HRESULT hr = WBEM_E_FAILED; // guilty until proven innocent
  344. if (pLeftVar->ChangeTypeTo(VT_BSTR) && pRightVar->ChangeTypeTo(VT_BSTR))
  345. {
  346. int nCompare = wcscmp(pLeftVar->GetLPWSTR(), pRightVar->GetLPWSTR());
  347. if (nCompare < 0)
  348. *ppNext = m_apBranches[LT];
  349. else if (nCompare > 0)
  350. *ppNext = m_apBranches[GT];
  351. else
  352. *ppNext = m_apBranches[EQ];
  353. hr = WBEM_S_NO_ERROR;
  354. }
  355. else
  356. hr = WBEM_E_FAILED;
  357. return hr;
  358. }
  359. // ************************************
  360. // **** Two Mismatched UINT Prop Node ****
  361. // ************************************
  362. CEvalNode* CTwoMismatchedUIntNode::Clone() const
  363. {
  364. return (CEvalNode *) new CTwoMismatchedUIntNode(*this, true);
  365. }
  366. CTwoPropNode* CTwoMismatchedUIntNode::CloneSelfWithoutChildren() const
  367. {
  368. return (CTwoPropNode *) new CTwoMismatchedUIntNode(*this, false);
  369. }
  370. // type identification
  371. long CTwoMismatchedUIntNode::GetSubType()
  372. {
  373. return EVAL_NODE_TYPE_MISMATCHED_INTS;
  374. }
  375. HRESULT CTwoMismatchedUIntNode::Evaluate(CVar *pLeftVar, CVar *pRightVar, INTERNAL CEvalNode** ppNext)
  376. {
  377. *ppNext = NULL;
  378. HRESULT hr = WBEM_E_FAILED; // guilty until proven innocent
  379. bool bLeftChanged, bRightChanged;
  380. bLeftChanged = pLeftVar->ChangeTypeTo(VT_UI4);
  381. bRightChanged = pRightVar->ChangeTypeTo(VT_UI4);
  382. if (bLeftChanged && bRightChanged)
  383. {
  384. if (pLeftVar->GetDWORD() < pRightVar->GetDWORD())
  385. *ppNext = m_apBranches[LT];
  386. else if (pLeftVar->GetDWORD() > pRightVar->GetDWORD())
  387. *ppNext = m_apBranches[GT];
  388. else
  389. *ppNext = m_apBranches[EQ];
  390. hr = WBEM_S_NO_ERROR;
  391. }
  392. // attempt to handle signed/unsigned mismatches
  393. else if (bLeftChanged &&
  394. pRightVar->ChangeTypeTo(VT_I4) &&
  395. pRightVar->GetLong() < 0)
  396. {
  397. *ppNext = m_apBranches[GT];
  398. hr = WBEM_S_NO_ERROR;
  399. }
  400. else if (bRightChanged &&
  401. pLeftVar->ChangeTypeTo(VT_I4) &&
  402. pLeftVar->GetLong() < 0)
  403. {
  404. *ppNext = m_apBranches[LT];
  405. hr = WBEM_S_NO_ERROR;
  406. }
  407. else
  408. hr = WBEM_E_TYPE_MISMATCH;
  409. return hr;
  410. }
  411. // ***********************************
  412. // **** Two Mismatched int Prop Node ****
  413. // ***********************************
  414. CEvalNode* CTwoMismatchedIntNode::Clone() const
  415. {
  416. return (CEvalNode *) new CTwoMismatchedIntNode(*this, true);
  417. }
  418. CTwoPropNode* CTwoMismatchedIntNode::CloneSelfWithoutChildren() const
  419. {
  420. return (CTwoPropNode *) new CTwoMismatchedIntNode(*this, false);
  421. }
  422. // type identification
  423. long CTwoMismatchedIntNode::GetSubType()
  424. {
  425. return EVAL_NODE_TYPE_MISMATCHED_INTS;
  426. }
  427. HRESULT CTwoMismatchedIntNode::Evaluate(CVar *pLeftVar, CVar *pRightVar, INTERNAL CEvalNode** ppNext)
  428. {
  429. HRESULT hr = WBEM_E_FAILED; // guilty until proven innocent
  430. bool bLeftChanged, bRightChanged;
  431. bLeftChanged = pLeftVar->ChangeTypeTo(VT_I4);
  432. bRightChanged = pRightVar->ChangeTypeTo(VT_I4);
  433. if (bLeftChanged && bRightChanged)
  434. {
  435. if (pLeftVar->GetLong() < pRightVar->GetLong())
  436. *ppNext = m_apBranches[LT];
  437. else if (pLeftVar->GetLong() > pRightVar->GetLong())
  438. *ppNext = m_apBranches[GT];
  439. else
  440. *ppNext = m_apBranches[EQ];
  441. hr = WBEM_S_NO_ERROR;
  442. }
  443. // attempt to handle signed/unsigned mismatches
  444. else if (bLeftChanged &&
  445. pRightVar->ChangeTypeTo(VT_UI4) &&
  446. pRightVar->GetDWORD() > _I32_MAX)
  447. {
  448. *ppNext = m_apBranches[LT];
  449. hr = WBEM_S_NO_ERROR;
  450. }
  451. else if (bRightChanged &&
  452. pLeftVar->ChangeTypeTo(VT_UI4) &&
  453. pLeftVar->GetDWORD() > _I32_MAX)
  454. {
  455. *ppNext = m_apBranches[GT];
  456. hr = WBEM_S_NO_ERROR;
  457. }
  458. else
  459. hr = WBEM_E_TYPE_MISMATCH;
  460. return hr;
  461. }
  462. // **************************************
  463. // **** Two Mismatched int 64 Prop Node ****
  464. // **************************************
  465. CEvalNode* CTwoMismatchedInt64Node::Clone() const
  466. {
  467. return (CEvalNode *) new CTwoMismatchedInt64Node(*this, true);
  468. }
  469. CTwoPropNode* CTwoMismatchedInt64Node::CloneSelfWithoutChildren() const
  470. {
  471. return (CTwoPropNode *) new CTwoMismatchedInt64Node(*this, false);
  472. }
  473. // type identification
  474. long CTwoMismatchedInt64Node::GetSubType()
  475. {
  476. return EVAL_NODE_TYPE_MISMATCHED_INTS;
  477. }
  478. HRESULT CTwoMismatchedInt64Node::Evaluate(CVar *pLeftVar, CVar *pRightVar, INTERNAL CEvalNode** ppNext)
  479. {
  480. *ppNext = NULL;
  481. HRESULT hr = WBEM_E_FAILED; // guilty until proven innocent
  482. __int64 i64Left, i64Right;
  483. unsigned __int64 ui64;
  484. if (pLeftVar->ChangeTypeTo(VT_BSTR) &&
  485. pRightVar->ChangeTypeTo(VT_BSTR))
  486. {
  487. if ((pLeftVar->GetLPWSTR() == NULL) || (pRightVar->GetLPWSTR() == NULL))
  488. *ppNext = m_pNullBranch;
  489. else
  490. {
  491. bool bReadLeft, bReadRight;
  492. bReadLeft = ReadI64(pLeftVar->GetLPWSTR(), i64Left);
  493. bReadRight = ReadI64(pRightVar->GetLPWSTR(), i64Right);
  494. if (bReadLeft && bReadRight)
  495. {
  496. if (i64Left < i64Right)
  497. *ppNext = m_apBranches[LT];
  498. else if (i64Left > i64Right)
  499. *ppNext = m_apBranches[GT];
  500. else
  501. *ppNext = m_apBranches[EQ];
  502. hr = WBEM_S_NO_ERROR;
  503. }
  504. // try to cover ourselves with signed/unsigned mismatches
  505. // note that this is a redundant check - if the other side
  506. // were a unsigned int 64, this node should have been a UInt64 node.
  507. else if (bReadLeft &&
  508. ReadUI64(pRightVar->GetLPWSTR(), ui64)
  509. && (ui64 >= _I64_MAX))
  510. {
  511. *ppNext = m_apBranches[LT];
  512. hr = WBEM_S_NO_ERROR;
  513. }
  514. else if (bReadRight &&
  515. ReadUI64(pLeftVar->GetLPWSTR(), ui64)
  516. && (ui64 >= _I64_MAX))
  517. {
  518. *ppNext = m_apBranches[GT];
  519. hr = WBEM_S_NO_ERROR;
  520. }
  521. else
  522. hr = WBEM_E_TYPE_MISMATCH;
  523. } // if ((pLeftVar->GetLPWSTR() == NULL)...
  524. } // if (pLeftVar->ChangeTypeTo(VT_BSTR)
  525. else
  526. hr = WBEM_E_TYPE_MISMATCH;
  527. return hr;
  528. }
  529. // ***********************************************
  530. // **** Two Mismatched unsigned int 64 Prop Node ****
  531. // ***********************************************
  532. CEvalNode* CTwoMismatchedUInt64Node::Clone() const
  533. {
  534. return (CEvalNode *) new CTwoMismatchedUInt64Node(*this, true);
  535. }
  536. CTwoPropNode* CTwoMismatchedUInt64Node::CloneSelfWithoutChildren() const
  537. {
  538. return (CTwoPropNode *) new CTwoMismatchedUInt64Node(*this, false);
  539. }
  540. // type identification
  541. long CTwoMismatchedUInt64Node::GetSubType()
  542. {
  543. return EVAL_NODE_TYPE_MISMATCHED_INTS;
  544. }
  545. HRESULT CTwoMismatchedUInt64Node::Evaluate(CVar *pLeftVar, CVar *pRightVar, INTERNAL CEvalNode** ppNext)
  546. {
  547. *ppNext = NULL;
  548. HRESULT hr = WBEM_E_FAILED; // guilty until proven innocent
  549. unsigned __int64 i64Left, i64Right;
  550. __int64 i64;
  551. if (pLeftVar->ChangeTypeTo(VT_BSTR) &&
  552. pRightVar->ChangeTypeTo(VT_BSTR))
  553. {
  554. if ((pLeftVar->GetLPWSTR() == NULL) || (pRightVar->GetLPWSTR() == NULL))
  555. *ppNext = m_pNullBranch;
  556. else
  557. {
  558. bool bReadLeft, bReadRight;
  559. bReadLeft = ReadUI64(pLeftVar->GetLPWSTR(), i64Left);
  560. bReadRight = ReadUI64(pRightVar->GetLPWSTR(), i64Right);
  561. if (bReadLeft && bReadRight)
  562. {
  563. if (i64Left < i64Right)
  564. *ppNext = m_apBranches[LT];
  565. else if (i64Left > i64Right)
  566. *ppNext = m_apBranches[GT];
  567. else
  568. *ppNext = m_apBranches[EQ];
  569. hr = WBEM_S_NO_ERROR;
  570. }
  571. // try to cover ourselves with signed/unsigned mismatches
  572. else if (bReadLeft &&
  573. ReadI64(pRightVar->GetLPWSTR(), i64)
  574. && (i64 < 0))
  575. {
  576. *ppNext = m_apBranches[GT];
  577. hr = WBEM_S_NO_ERROR;
  578. }
  579. else if (bReadRight &&
  580. ReadI64(pLeftVar->GetLPWSTR(), i64)
  581. && (i64 < 0))
  582. {
  583. *ppNext = m_apBranches[LT];
  584. hr = WBEM_S_NO_ERROR;
  585. }
  586. else
  587. hr = WBEM_E_TYPE_MISMATCH;
  588. }
  589. }
  590. else
  591. hr = WBEM_E_TYPE_MISMATCH;
  592. return hr;
  593. }
  594. // *************************************
  595. // **** Two Mismatched Float Prop Node ****
  596. // *************************************
  597. CEvalNode* CTwoMismatchedFloatNode::Clone() const
  598. {
  599. return (CEvalNode *) new CTwoMismatchedFloatNode(*this, true);
  600. }
  601. CTwoPropNode* CTwoMismatchedFloatNode::CloneSelfWithoutChildren() const
  602. {
  603. return (CTwoPropNode *) new CTwoMismatchedFloatNode(*this, false);
  604. }
  605. // type identification
  606. long CTwoMismatchedFloatNode::GetSubType()
  607. {
  608. return EVAL_NODE_TYPE_MISMATCHED_FLOATS;
  609. }
  610. HRESULT CTwoMismatchedFloatNode::Evaluate(CVar *pLeftVar, CVar *pRightVar, INTERNAL CEvalNode** ppNext)
  611. {
  612. *ppNext = NULL;
  613. HRESULT hr = WBEM_E_TYPE_MISMATCH; // guilty until proven innocent
  614. if (pLeftVar->ChangeTypeTo(VT_R8) && pRightVar->ChangeTypeTo(VT_R8))
  615. {
  616. if (pLeftVar->GetDouble() < pRightVar->GetDouble())
  617. *ppNext = m_apBranches[LT];
  618. else if (pLeftVar->GetDouble() > pRightVar->GetDouble())
  619. *ppNext = m_apBranches[GT];
  620. else
  621. *ppNext = m_apBranches[EQ];
  622. hr = WBEM_S_NO_ERROR;
  623. }
  624. return hr;
  625. }
  626. #pragma warning(default: 4800)