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.

772 lines
21 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, bDeleteArg2, &pNewChildNode);
  189. if (bDeleteArg2)
  190. pOther->m_apBranches.Discard(i);
  191. if (bDeleteThis)
  192. m_apBranches.Discard(i);
  193. pNewNode->m_apBranches.Discard(i);
  194. pNewNode->m_apBranches.SetAt(i, pNewChildNode);
  195. }
  196. if(pDeleteMe)
  197. {
  198. pDeleteMe->m_pNullBranch = NULL;
  199. delete pDeleteMe;
  200. }
  201. if (SUCCEEDED(hRes))
  202. *ppRes = pNewNode;
  203. else
  204. {
  205. *ppRes = NULL;
  206. }
  207. return hRes;
  208. }
  209. // given a property handle, will retrieve proper property, probably.
  210. CVar* CTwoPropNode::GetPropVariant(_IWmiObject* pObj, long lHandle, CIMTYPE* pct)
  211. {
  212. CVar *pVar = NULL;
  213. BSTR bstrName;
  214. if (SUCCEEDED(pObj->GetPropertyInfoByHandle(lHandle, &bstrName, pct)))
  215. {
  216. CSysFreeMe sfm(bstrName);
  217. //
  218. // Get it into a VARIANT
  219. //
  220. VARIANT v;
  221. if(FAILED(pObj->Get(bstrName, 0, &v, NULL, NULL)))
  222. return NULL;
  223. // Convert it to a CVar
  224. if (pVar = new CVar)
  225. pVar->SetVariant(&v);
  226. }
  227. return pVar;
  228. }
  229. // ***************************
  230. // **** Two String Prop Node ****
  231. // ***************************
  232. CEvalNode* CTwoStringPropNode::Clone() const
  233. {
  234. return (CEvalNode *) new CTwoStringPropNode(*this, true);
  235. }
  236. CTwoPropNode* CTwoStringPropNode::CloneSelfWithoutChildren() const
  237. {
  238. return (CTwoPropNode *) new CTwoStringPropNode(*this, false);
  239. }
  240. long CTwoStringPropNode::GetSubType()
  241. {
  242. return EVAL_NODE_TYPE_TWO_STRINGS;
  243. }
  244. HRESULT CTwoStringPropNode::Evaluate(CObjectInfo& ObjInfo,
  245. INTERNAL CEvalNode** ppNext)
  246. {
  247. HRESULT herslut = WBEM_S_NO_ERROR;
  248. _IWmiObject* pLeftObj;
  249. _IWmiObject* pRightObj;
  250. if(SUCCEEDED(herslut = GetContainerObject(ObjInfo, &pLeftObj))
  251. &&
  252. SUCCEEDED(herslut = GetRightContainerObject(ObjInfo, &pRightObj)))
  253. {
  254. CCompressedString* pLeftStr;
  255. CCompressedString* pRightStr;
  256. pLeftStr = CoreGetPropertyString(pLeftObj, m_lPropHandle);
  257. pRightStr = CoreGetPropertyString(pRightObj, m_lRightPropHandle);
  258. if ((pLeftStr == NULL) || (pRightStr == NULL))
  259. {
  260. *ppNext = m_pNullBranch;
  261. herslut = WBEM_S_NO_ERROR;
  262. }
  263. else
  264. {
  265. int nCompare = pLeftStr->CheapCompare(*pRightStr);
  266. // TODO: check to see if CheapCompare is guaranteed to return -1,0,1
  267. // if so, then the multiple else if becomes
  268. // *ppNext = m_apBranches[EQ + nCompare];
  269. if (nCompare < 0)
  270. *ppNext = m_apBranches[LT];
  271. else if (nCompare > 0)
  272. *ppNext = m_apBranches[GT];
  273. else
  274. *ppNext = m_apBranches[EQ];
  275. herslut = WBEM_S_NO_ERROR;
  276. }
  277. }
  278. return herslut;
  279. }
  280. // *******************************
  281. // **** Two Mismatched Prop Node ****
  282. // *******************************
  283. HRESULT CTwoMismatchedPropNode::Evaluate(CObjectInfo& ObjInfo, INTERNAL CEvalNode** ppNext)
  284. {
  285. CVar *pLeftVar = NULL;
  286. CVar *pRightVar = NULL;
  287. HRESULT hr = WBEM_E_FAILED; // guilty until proven innocent
  288. CIMTYPE ct;
  289. _IWmiObject* pLeftObj = NULL;
  290. _IWmiObject* pRightObj = NULL;
  291. // if we can get the objects and variants...
  292. if ((SUCCEEDED(hr = GetContainerObject(ObjInfo, &pLeftObj))
  293. &&
  294. SUCCEEDED(hr = GetRightContainerObject(ObjInfo, &pRightObj)))
  295. &&
  296. (pLeftVar = GetPropVariant(pLeftObj, m_lPropHandle, &ct))
  297. &&
  298. (pRightVar = GetPropVariant(pRightObj, m_lRightPropHandle, &ct)) )
  299. {
  300. if (pLeftVar->IsDataNull() || pRightVar->IsDataNull())
  301. {
  302. *ppNext = m_pNullBranch;
  303. hr = WBEM_S_NO_ERROR;
  304. }
  305. else
  306. hr = Evaluate(pLeftVar, pRightVar, ppNext);
  307. }
  308. else if (SUCCEEDED(hr))
  309. // if we got here, it's because one of the GetPropVariant's didn't
  310. hr = WBEM_E_INVALID_PARAMETER;
  311. delete pLeftVar;
  312. delete pRightVar;
  313. return hr;
  314. }
  315. // **************************************
  316. // **** Two Mismatched String Prop Node ****
  317. // **************************************
  318. CEvalNode* CTwoMismatchedStringNode::Clone() const
  319. {
  320. return (CEvalNode *) new CTwoMismatchedStringNode(*this, true);
  321. }
  322. CTwoPropNode* CTwoMismatchedStringNode::CloneSelfWithoutChildren() const
  323. {
  324. return (CTwoPropNode *) new CTwoMismatchedStringNode(*this, false);
  325. }
  326. // type identification
  327. long CTwoMismatchedStringNode::GetSubType()
  328. {
  329. return EVAL_NODE_TYPE_MISMATCHED_STRINGS;
  330. }
  331. // string evaluation: promote them all to strings
  332. // and do a lexagraphic compare..
  333. HRESULT CTwoMismatchedStringNode::Evaluate(CVar *pLeftVar, CVar *pRightVar, INTERNAL CEvalNode** ppNext)
  334. {
  335. HRESULT hr = WBEM_E_FAILED; // guilty until proven innocent
  336. if (pLeftVar->ChangeTypeTo(VT_BSTR) && pRightVar->ChangeTypeTo(VT_BSTR))
  337. {
  338. int nCompare = wcscmp(pLeftVar->GetLPWSTR(), pRightVar->GetLPWSTR());
  339. if (nCompare < 0)
  340. *ppNext = m_apBranches[LT];
  341. else if (nCompare > 0)
  342. *ppNext = m_apBranches[GT];
  343. else
  344. *ppNext = m_apBranches[EQ];
  345. hr = WBEM_S_NO_ERROR;
  346. }
  347. else
  348. hr = WBEM_E_FAILED;
  349. return hr;
  350. }
  351. // ************************************
  352. // **** Two Mismatched UINT Prop Node ****
  353. // ************************************
  354. CEvalNode* CTwoMismatchedUIntNode::Clone() const
  355. {
  356. return (CEvalNode *) new CTwoMismatchedUIntNode(*this, true);
  357. }
  358. CTwoPropNode* CTwoMismatchedUIntNode::CloneSelfWithoutChildren() const
  359. {
  360. return (CTwoPropNode *) new CTwoMismatchedUIntNode(*this, false);
  361. }
  362. // type identification
  363. long CTwoMismatchedUIntNode::GetSubType()
  364. {
  365. return EVAL_NODE_TYPE_MISMATCHED_INTS;
  366. }
  367. HRESULT CTwoMismatchedUIntNode::Evaluate(CVar *pLeftVar, CVar *pRightVar, INTERNAL CEvalNode** ppNext)
  368. {
  369. HRESULT hr = WBEM_E_FAILED; // guilty until proven innocent
  370. bool bLeftChanged, bRightChanged;
  371. bLeftChanged = pLeftVar->ChangeTypeTo(VT_UI4);
  372. bRightChanged = pRightVar->ChangeTypeTo(VT_UI4);
  373. if (bLeftChanged && bRightChanged)
  374. {
  375. if (pLeftVar->GetDWORD() < pRightVar->GetDWORD())
  376. *ppNext = m_apBranches[LT];
  377. else if (pLeftVar->GetDWORD() > pRightVar->GetDWORD())
  378. *ppNext = m_apBranches[GT];
  379. else
  380. *ppNext = m_apBranches[EQ];
  381. hr = WBEM_S_NO_ERROR;
  382. }
  383. // attempt to handle signed/unsigned mismatches
  384. else if (bLeftChanged &&
  385. pRightVar->ChangeTypeTo(VT_I4) &&
  386. pRightVar->GetLong() < 0)
  387. {
  388. *ppNext = m_apBranches[GT];
  389. hr = WBEM_S_NO_ERROR;
  390. }
  391. else if (bRightChanged &&
  392. pLeftVar->ChangeTypeTo(VT_I4) &&
  393. pLeftVar->GetLong() < 0)
  394. {
  395. *ppNext = m_apBranches[LT];
  396. hr = WBEM_S_NO_ERROR;
  397. }
  398. else
  399. hr = WBEM_E_TYPE_MISMATCH;
  400. return hr;
  401. }
  402. // ***********************************
  403. // **** Two Mismatched int Prop Node ****
  404. // ***********************************
  405. CEvalNode* CTwoMismatchedIntNode::Clone() const
  406. {
  407. return (CEvalNode *) new CTwoMismatchedIntNode(*this, true);
  408. }
  409. CTwoPropNode* CTwoMismatchedIntNode::CloneSelfWithoutChildren() const
  410. {
  411. return (CTwoPropNode *) new CTwoMismatchedIntNode(*this, false);
  412. }
  413. // type identification
  414. long CTwoMismatchedIntNode::GetSubType()
  415. {
  416. return EVAL_NODE_TYPE_MISMATCHED_INTS;
  417. }
  418. HRESULT CTwoMismatchedIntNode::Evaluate(CVar *pLeftVar, CVar *pRightVar, INTERNAL CEvalNode** ppNext)
  419. {
  420. HRESULT hr = WBEM_E_FAILED; // guilty until proven innocent
  421. bool bLeftChanged, bRightChanged;
  422. bLeftChanged = pLeftVar->ChangeTypeTo(VT_I4);
  423. bRightChanged = pRightVar->ChangeTypeTo(VT_I4);
  424. if (bLeftChanged && bRightChanged)
  425. {
  426. if (pLeftVar->GetLong() < pRightVar->GetLong())
  427. *ppNext = m_apBranches[LT];
  428. else if (pLeftVar->GetLong() > pRightVar->GetLong())
  429. *ppNext = m_apBranches[GT];
  430. else
  431. *ppNext = m_apBranches[EQ];
  432. hr = WBEM_S_NO_ERROR;
  433. }
  434. // attempt to handle signed/unsigned mismatches
  435. else if (bLeftChanged &&
  436. pRightVar->ChangeTypeTo(VT_UI4) &&
  437. pRightVar->GetDWORD() > _I32_MAX)
  438. {
  439. *ppNext = m_apBranches[LT];
  440. hr = WBEM_S_NO_ERROR;
  441. }
  442. else if (bRightChanged &&
  443. pLeftVar->ChangeTypeTo(VT_UI4) &&
  444. pLeftVar->GetDWORD() > _I32_MAX)
  445. {
  446. *ppNext = m_apBranches[GT];
  447. hr = WBEM_S_NO_ERROR;
  448. }
  449. else
  450. hr = WBEM_E_TYPE_MISMATCH;
  451. return hr;
  452. }
  453. // **************************************
  454. // **** Two Mismatched int 64 Prop Node ****
  455. // **************************************
  456. CEvalNode* CTwoMismatchedInt64Node::Clone() const
  457. {
  458. return (CEvalNode *) new CTwoMismatchedInt64Node(*this, true);
  459. }
  460. CTwoPropNode* CTwoMismatchedInt64Node::CloneSelfWithoutChildren() const
  461. {
  462. return (CTwoPropNode *) new CTwoMismatchedInt64Node(*this, false);
  463. }
  464. // type identification
  465. long CTwoMismatchedInt64Node::GetSubType()
  466. {
  467. return EVAL_NODE_TYPE_MISMATCHED_INTS;
  468. }
  469. HRESULT CTwoMismatchedInt64Node::Evaluate(CVar *pLeftVar, CVar *pRightVar, INTERNAL CEvalNode** ppNext)
  470. {
  471. HRESULT hr = WBEM_E_FAILED; // guilty until proven innocent
  472. __int64 i64Left, i64Right;
  473. unsigned __int64 ui64;
  474. if (pLeftVar->ChangeTypeTo(VT_BSTR) &&
  475. pRightVar->ChangeTypeTo(VT_BSTR))
  476. {
  477. if ((pLeftVar->GetLPWSTR() == NULL) || (pRightVar->GetLPWSTR() == NULL))
  478. *ppNext = m_pNullBranch;
  479. else
  480. {
  481. bool bReadLeft, bReadRight;
  482. bReadLeft = ReadI64(pLeftVar->GetLPWSTR(), i64Left);
  483. bReadRight = ReadI64(pRightVar->GetLPWSTR(), i64Right);
  484. if (bReadLeft && bReadRight)
  485. {
  486. if (i64Left < i64Right)
  487. *ppNext = m_apBranches[LT];
  488. else if (i64Left > i64Right)
  489. *ppNext = m_apBranches[GT];
  490. else
  491. *ppNext = m_apBranches[EQ];
  492. hr = WBEM_S_NO_ERROR;
  493. }
  494. // try to cover ourselves with signed/unsigned mismatches
  495. // note that this is a redundant check - if the other side
  496. // were a unsigned int 64, this node should have been a UInt64 node.
  497. else if (bReadLeft &&
  498. ReadUI64(pRightVar->GetLPWSTR(), ui64)
  499. && (ui64 >= _I64_MAX))
  500. {
  501. *ppNext = m_apBranches[LT];
  502. hr = WBEM_S_NO_ERROR;
  503. }
  504. else if (bReadRight &&
  505. ReadUI64(pLeftVar->GetLPWSTR(), ui64)
  506. && (ui64 >= _I64_MAX))
  507. {
  508. *ppNext = m_apBranches[GT];
  509. hr = WBEM_S_NO_ERROR;
  510. }
  511. else
  512. hr = WBEM_E_TYPE_MISMATCH;
  513. } // if ((pLeftVar->GetLPWSTR() == NULL)...
  514. } // if (pLeftVar->ChangeTypeTo(VT_BSTR)
  515. else
  516. hr = WBEM_E_TYPE_MISMATCH;
  517. return hr;
  518. }
  519. // ***********************************************
  520. // **** Two Mismatched unsigned int 64 Prop Node ****
  521. // ***********************************************
  522. CEvalNode* CTwoMismatchedUInt64Node::Clone() const
  523. {
  524. return (CEvalNode *) new CTwoMismatchedUInt64Node(*this, true);
  525. }
  526. CTwoPropNode* CTwoMismatchedUInt64Node::CloneSelfWithoutChildren() const
  527. {
  528. return (CTwoPropNode *) new CTwoMismatchedUInt64Node(*this, false);
  529. }
  530. // type identification
  531. long CTwoMismatchedUInt64Node::GetSubType()
  532. {
  533. return EVAL_NODE_TYPE_MISMATCHED_INTS;
  534. }
  535. HRESULT CTwoMismatchedUInt64Node::Evaluate(CVar *pLeftVar, CVar *pRightVar, INTERNAL CEvalNode** ppNext)
  536. {
  537. HRESULT hr = WBEM_E_FAILED; // guilty until proven innocent
  538. unsigned __int64 i64Left, i64Right;
  539. __int64 i64;
  540. if (pLeftVar->ChangeTypeTo(VT_BSTR) &&
  541. pRightVar->ChangeTypeTo(VT_BSTR))
  542. {
  543. if ((pLeftVar->GetLPWSTR() == NULL) || (pRightVar->GetLPWSTR() == NULL))
  544. *ppNext = m_pNullBranch;
  545. else
  546. {
  547. bool bReadLeft, bReadRight;
  548. bReadLeft = ReadUI64(pLeftVar->GetLPWSTR(), i64Left);
  549. bReadRight = ReadUI64(pRightVar->GetLPWSTR(), i64Right);
  550. if (bReadLeft && bReadRight)
  551. {
  552. if (i64Left < i64Right)
  553. *ppNext = m_apBranches[LT];
  554. else if (i64Left > i64Right)
  555. *ppNext = m_apBranches[GT];
  556. else
  557. *ppNext = m_apBranches[EQ];
  558. hr = WBEM_S_NO_ERROR;
  559. }
  560. // try to cover ourselves with signed/unsigned mismatches
  561. else if (bReadLeft &&
  562. ReadI64(pRightVar->GetLPWSTR(), i64)
  563. && (i64 < 0))
  564. {
  565. *ppNext = m_apBranches[GT];
  566. hr = WBEM_S_NO_ERROR;
  567. }
  568. else if (bReadRight &&
  569. ReadI64(pLeftVar->GetLPWSTR(), i64)
  570. && (i64 < 0))
  571. {
  572. *ppNext = m_apBranches[LT];
  573. hr = WBEM_S_NO_ERROR;
  574. }
  575. else
  576. hr = WBEM_E_TYPE_MISMATCH;
  577. }
  578. }
  579. else
  580. hr = WBEM_E_TYPE_MISMATCH;
  581. return hr;
  582. }
  583. // *************************************
  584. // **** Two Mismatched Float Prop Node ****
  585. // *************************************
  586. CEvalNode* CTwoMismatchedFloatNode::Clone() const
  587. {
  588. return (CEvalNode *) new CTwoMismatchedFloatNode(*this, true);
  589. }
  590. CTwoPropNode* CTwoMismatchedFloatNode::CloneSelfWithoutChildren() const
  591. {
  592. return (CTwoPropNode *) new CTwoMismatchedFloatNode(*this, false);
  593. }
  594. // type identification
  595. long CTwoMismatchedFloatNode::GetSubType()
  596. {
  597. return EVAL_NODE_TYPE_MISMATCHED_FLOATS;
  598. }
  599. HRESULT CTwoMismatchedFloatNode::Evaluate(CVar *pLeftVar, CVar *pRightVar, INTERNAL CEvalNode** ppNext)
  600. {
  601. HRESULT hr = WBEM_E_TYPE_MISMATCH; // guilty until proven innocent
  602. if (pLeftVar->ChangeTypeTo(VT_R8) && pRightVar->ChangeTypeTo(VT_R8))
  603. {
  604. if (pLeftVar->GetDouble() < pRightVar->GetDouble())
  605. *ppNext = m_apBranches[LT];
  606. else if (pLeftVar->GetDouble() > pRightVar->GetDouble())
  607. *ppNext = m_apBranches[GT];
  608. else
  609. *ppNext = m_apBranches[EQ];
  610. hr = WBEM_S_NO_ERROR;
  611. }
  612. return hr;
  613. }
  614. #pragma warning(default: 4800)