diff options
Diffstat (limited to '')
-rw-r--r-- | src/engine/condition.cpp | 125 |
1 files changed, 73 insertions, 52 deletions
diff --git a/src/engine/condition.cpp b/src/engine/condition.cpp index 32a7a0b8..224eb0da 100644 --- a/src/engine/condition.cpp +++ b/src/engine/condition.cpp | |||
@@ -73,6 +73,12 @@ struct BURN_CONDITION_PARSE_CONTEXT | |||
73 | BOOL fError; | 73 | BOOL fError; |
74 | }; | 74 | }; |
75 | 75 | ||
76 | struct BURN_CONDITION_OPERAND | ||
77 | { | ||
78 | BOOL fHidden; | ||
79 | BURN_VARIANT Value; | ||
80 | }; | ||
81 | |||
76 | 82 | ||
77 | // internal function declarations | 83 | // internal function declarations |
78 | 84 | ||
@@ -92,9 +98,9 @@ static HRESULT ParseTerm( | |||
92 | __in BURN_CONDITION_PARSE_CONTEXT* pContext, | 98 | __in BURN_CONDITION_PARSE_CONTEXT* pContext, |
93 | __out BOOL* pf | 99 | __out BOOL* pf |
94 | ); | 100 | ); |
95 | static HRESULT ParseValue( | 101 | static HRESULT ParseOperand( |
96 | __in BURN_CONDITION_PARSE_CONTEXT* pContext, | 102 | __in BURN_CONDITION_PARSE_CONTEXT* pContext, |
97 | __out BURN_VARIANT* pValue | 103 | __out BURN_CONDITION_OPERAND* pOperand |
98 | ); | 104 | ); |
99 | static HRESULT Expect( | 105 | static HRESULT Expect( |
100 | __in BURN_CONDITION_PARSE_CONTEXT* pContext, | 106 | __in BURN_CONDITION_PARSE_CONTEXT* pContext, |
@@ -103,10 +109,10 @@ static HRESULT Expect( | |||
103 | static HRESULT NextSymbol( | 109 | static HRESULT NextSymbol( |
104 | __in BURN_CONDITION_PARSE_CONTEXT* pContext | 110 | __in BURN_CONDITION_PARSE_CONTEXT* pContext |
105 | ); | 111 | ); |
106 | static HRESULT CompareValues( | 112 | static HRESULT CompareOperands( |
107 | __in BURN_SYMBOL_TYPE comparison, | 113 | __in BURN_SYMBOL_TYPE comparison, |
108 | __in BURN_VARIANT leftOperand, | 114 | __in BURN_CONDITION_OPERAND* pLeftOperand, |
109 | __in BURN_VARIANT rightOperand, | 115 | __in BURN_CONDITION_OPERAND* pRightOperand, |
110 | __out BOOL* pfResult | 116 | __out BOOL* pfResult |
111 | ); | 117 | ); |
112 | static HRESULT CompareStringValues( | 118 | static HRESULT CompareStringValues( |
@@ -342,8 +348,8 @@ static HRESULT ParseTerm( | |||
342 | ) | 348 | ) |
343 | { | 349 | { |
344 | HRESULT hr = S_OK; | 350 | HRESULT hr = S_OK; |
345 | BURN_VARIANT firstValue = { }; | 351 | BURN_CONDITION_OPERAND firstOperand = { }; |
346 | BURN_VARIANT secondValue = { }; | 352 | BURN_CONDITION_OPERAND secondOperand = { }; |
347 | 353 | ||
348 | if (BURN_SYMBOL_TYPE_LPAREN == pContext->NextSymbol.Type) | 354 | if (BURN_SYMBOL_TYPE_LPAREN == pContext->NextSymbol.Type) |
349 | { | 355 | { |
@@ -359,8 +365,8 @@ static HRESULT ParseTerm( | |||
359 | ExitFunction1(hr = S_OK); | 365 | ExitFunction1(hr = S_OK); |
360 | } | 366 | } |
361 | 367 | ||
362 | hr = ParseValue(pContext, &firstValue); | 368 | hr = ParseOperand(pContext, &firstOperand); |
363 | ExitOnFailure(hr, "Failed to parse value."); | 369 | ExitOnFailure(hr, "Failed to parse operand."); |
364 | 370 | ||
365 | if (COMPARISON & pContext->NextSymbol.Type) | 371 | if (COMPARISON & pContext->NextSymbol.Type) |
366 | { | 372 | { |
@@ -369,24 +375,24 @@ static HRESULT ParseTerm( | |||
369 | hr = NextSymbol(pContext); | 375 | hr = NextSymbol(pContext); |
370 | ExitOnFailure(hr, "Failed to read next symbol."); | 376 | ExitOnFailure(hr, "Failed to read next symbol."); |
371 | 377 | ||
372 | hr = ParseValue(pContext, &secondValue); | 378 | hr = ParseOperand(pContext, &secondOperand); |
373 | ExitOnFailure(hr, "Failed to parse value."); | 379 | ExitOnFailure(hr, "Failed to parse operand."); |
374 | 380 | ||
375 | hr = CompareValues(comparison, firstValue, secondValue, pf); | 381 | hr = CompareOperands(comparison, &firstOperand, &secondOperand, pf); |
376 | ExitOnFailure(hr, "Failed to compare value."); | 382 | ExitOnFailure(hr, "Failed to compare operands."); |
377 | } | 383 | } |
378 | else | 384 | else |
379 | { | 385 | { |
380 | LONGLONG llValue = 0; | 386 | LONGLONG llValue = 0; |
381 | LPWSTR sczValue = NULL; | 387 | LPWSTR sczValue = NULL; |
382 | VERUTIL_VERSION* pVersion = NULL; | 388 | VERUTIL_VERSION* pVersion = NULL; |
383 | switch (firstValue.Type) | 389 | switch (firstOperand.Value.Type) |
384 | { | 390 | { |
385 | case BURN_VARIANT_TYPE_NONE: | 391 | case BURN_VARIANT_TYPE_NONE: |
386 | *pf = FALSE; | 392 | *pf = FALSE; |
387 | break; | 393 | break; |
388 | case BURN_VARIANT_TYPE_STRING: | 394 | case BURN_VARIANT_TYPE_STRING: |
389 | hr = BVariantGetString(&firstValue, &sczValue); | 395 | hr = BVariantGetString(&firstOperand.Value, &sczValue); |
390 | if (SUCCEEDED(hr)) | 396 | if (SUCCEEDED(hr)) |
391 | { | 397 | { |
392 | *pf = sczValue && *sczValue; | 398 | *pf = sczValue && *sczValue; |
@@ -394,7 +400,7 @@ static HRESULT ParseTerm( | |||
394 | StrSecureZeroFreeString(sczValue); | 400 | StrSecureZeroFreeString(sczValue); |
395 | break; | 401 | break; |
396 | case BURN_VARIANT_TYPE_NUMERIC: | 402 | case BURN_VARIANT_TYPE_NUMERIC: |
397 | hr = BVariantGetNumeric(&firstValue, &llValue); | 403 | hr = BVariantGetNumeric(&firstOperand.Value, &llValue); |
398 | if (SUCCEEDED(hr)) | 404 | if (SUCCEEDED(hr)) |
399 | { | 405 | { |
400 | *pf = 0 != llValue; | 406 | *pf = 0 != llValue; |
@@ -402,7 +408,7 @@ static HRESULT ParseTerm( | |||
402 | SecureZeroMemory(&llValue, sizeof(llValue)); | 408 | SecureZeroMemory(&llValue, sizeof(llValue)); |
403 | break; | 409 | break; |
404 | case BURN_VARIANT_TYPE_VERSION: | 410 | case BURN_VARIANT_TYPE_VERSION: |
405 | hr = BVariantGetVersion(&firstValue, &pVersion); | 411 | hr = BVariantGetVersionHidden(&firstOperand.Value, firstOperand.fHidden, &pVersion); |
406 | if (SUCCEEDED(hr)) | 412 | if (SUCCEEDED(hr)) |
407 | { | 413 | { |
408 | *pf = 0 != *pVersion->sczVersion; | 414 | *pf = 0 != *pVersion->sczVersion; |
@@ -415,14 +421,14 @@ static HRESULT ParseTerm( | |||
415 | } | 421 | } |
416 | 422 | ||
417 | LExit: | 423 | LExit: |
418 | BVariantUninitialize(&firstValue); | 424 | BVariantUninitialize(&firstOperand.Value); |
419 | BVariantUninitialize(&secondValue); | 425 | BVariantUninitialize(&secondOperand.Value); |
420 | return hr; | 426 | return hr; |
421 | } | 427 | } |
422 | 428 | ||
423 | static HRESULT ParseValue( | 429 | static HRESULT ParseOperand( |
424 | __in BURN_CONDITION_PARSE_CONTEXT* pContext, | 430 | __in BURN_CONDITION_PARSE_CONTEXT* pContext, |
425 | __out BURN_VARIANT* pValue | 431 | __out BURN_CONDITION_OPERAND* pOperand |
426 | ) | 432 | ) |
427 | { | 433 | { |
428 | HRESULT hr = S_OK; | 434 | HRESULT hr = S_OK; |
@@ -434,16 +440,19 @@ static HRESULT ParseValue( | |||
434 | Assert(BURN_VARIANT_TYPE_STRING == pContext->NextSymbol.Value.Type); | 440 | Assert(BURN_VARIANT_TYPE_STRING == pContext->NextSymbol.Value.Type); |
435 | 441 | ||
436 | // find variable | 442 | // find variable |
437 | hr = VariableGetVariant(pContext->pVariables, pContext->NextSymbol.Value.sczValue, pValue); | 443 | hr = VariableGetVariant(pContext->pVariables, pContext->NextSymbol.Value.sczValue, &pOperand->Value); |
438 | if (E_NOTFOUND != hr) | 444 | if (E_NOTFOUND != hr) |
439 | { | 445 | { |
440 | ExitOnRootFailure(hr, "Failed to find variable."); | 446 | ExitOnRootFailure(hr, "Failed to find variable."); |
447 | |||
448 | hr = VariableIsHidden(pContext->pVariables, pContext->NextSymbol.Value.sczValue, &pOperand->fHidden); | ||
449 | ExitOnRootFailure(hr, "Failed to get if variable is hidden."); | ||
441 | } | 450 | } |
442 | 451 | ||
443 | if (BURN_VARIANT_TYPE_FORMATTED == pValue->Type) | 452 | if (BURN_VARIANT_TYPE_FORMATTED == pOperand->Value.Type) |
444 | { | 453 | { |
445 | // TODO: actually format the value? | 454 | // TODO: actually format the value? |
446 | hr = BVariantChangeType(pValue, BURN_VARIANT_TYPE_STRING); | 455 | hr = BVariantChangeType(&pOperand->Value, BURN_VARIANT_TYPE_STRING); |
447 | ExitOnRootFailure(hr, "Failed to change variable '%ls' type for condition '%ls'", pContext->NextSymbol.Value.sczValue, pContext->wzCondition); | 456 | ExitOnRootFailure(hr, "Failed to change variable '%ls' type for condition '%ls'", pContext->NextSymbol.Value.sczValue, pContext->wzCondition); |
448 | } | 457 | } |
449 | break; | 458 | break; |
@@ -451,8 +460,9 @@ static HRESULT ParseValue( | |||
451 | case BURN_SYMBOL_TYPE_NUMBER: __fallthrough; | 460 | case BURN_SYMBOL_TYPE_NUMBER: __fallthrough; |
452 | case BURN_SYMBOL_TYPE_LITERAL: __fallthrough; | 461 | case BURN_SYMBOL_TYPE_LITERAL: __fallthrough; |
453 | case BURN_SYMBOL_TYPE_VERSION: | 462 | case BURN_SYMBOL_TYPE_VERSION: |
463 | pOperand->fHidden = FALSE; | ||
454 | // steal value of symbol | 464 | // steal value of symbol |
455 | memcpy_s(pValue, sizeof(BURN_VARIANT), &pContext->NextSymbol.Value, sizeof(BURN_VARIANT)); | 465 | memcpy_s(&pOperand->Value, sizeof(BURN_VARIANT), &pContext->NextSymbol.Value, sizeof(BURN_VARIANT)); |
456 | memset(&pContext->NextSymbol.Value, 0, sizeof(BURN_VARIANT)); | 466 | memset(&pContext->NextSymbol.Value, 0, sizeof(BURN_VARIANT)); |
457 | break; | 467 | break; |
458 | 468 | ||
@@ -692,8 +702,13 @@ static HRESULT NextSymbol( | |||
692 | do | 702 | do |
693 | { | 703 | { |
694 | ++n; | 704 | ++n; |
695 | ::GetStringTypeW(CT_CTYPE1, &pContext->wzRead[n], 1, &charType); | 705 | } while (pContext->wzRead[n] >= L'0' && pContext->wzRead[n] <= L'9' || |
696 | } while (L'\0' != pContext->wzRead[n] && C1_BLANK != (C1_BLANK & charType)); | 706 | pContext->wzRead[n] >= L'A' && pContext->wzRead[n] <= L'Z' || |
707 | pContext->wzRead[n] >= L'a' && pContext->wzRead[n] <= L'z' || | ||
708 | pContext->wzRead[n] == L'_' || | ||
709 | pContext->wzRead[n] == L'+' || | ||
710 | pContext->wzRead[n] == L'-' || | ||
711 | pContext->wzRead[n] == L'.'); | ||
697 | 712 | ||
698 | // Symbols don't encrypt their value, so can access the value directly. | 713 | // Symbols don't encrypt their value, so can access the value directly. |
699 | hr = VerParseVersion(&pContext->wzRead[1], n - 1, FALSE, &pContext->NextSymbol.Value.pValue); | 714 | hr = VerParseVersion(&pContext->wzRead[1], n - 1, FALSE, &pContext->NextSymbol.Value.pValue); |
@@ -703,6 +718,10 @@ static HRESULT NextSymbol( | |||
703 | hr = E_INVALIDDATA; | 718 | hr = E_INVALIDDATA; |
704 | ExitOnRootFailure(hr, "Failed to parse condition \"%ls\". Invalid version format, at position %d.", pContext->wzCondition, iPosition); | 719 | ExitOnRootFailure(hr, "Failed to parse condition \"%ls\". Invalid version format, at position %d.", pContext->wzCondition, iPosition); |
705 | } | 720 | } |
721 | else if (pContext->NextSymbol.Value.pValue->fInvalid) | ||
722 | { | ||
723 | LogId(REPORT_WARNING, MSG_CONDITION_INVALID_VERSION, pContext->wzCondition, pContext->NextSymbol.Value.pValue->sczVersion); | ||
724 | } | ||
706 | 725 | ||
707 | pContext->NextSymbol.Value.Type = BURN_VARIANT_TYPE_VERSION; | 726 | pContext->NextSymbol.Value.Type = BURN_VARIANT_TYPE_VERSION; |
708 | pContext->NextSymbol.Type = BURN_SYMBOL_TYPE_VERSION; | 727 | pContext->NextSymbol.Type = BURN_SYMBOL_TYPE_VERSION; |
@@ -755,12 +774,12 @@ LExit: | |||
755 | } | 774 | } |
756 | 775 | ||
757 | // | 776 | // |
758 | // CompareValues - compares two variant values using a given comparison. | 777 | // CompareOperands - compares two variant values using a given comparison. |
759 | // | 778 | // |
760 | static HRESULT CompareValues( | 779 | static HRESULT CompareOperands( |
761 | __in BURN_SYMBOL_TYPE comparison, | 780 | __in BURN_SYMBOL_TYPE comparison, |
762 | __in BURN_VARIANT leftOperand, | 781 | __in BURN_CONDITION_OPERAND* pLeftOperand, |
763 | __in BURN_VARIANT rightOperand, | 782 | __in BURN_CONDITION_OPERAND* pRightOperand, |
764 | __out BOOL* pfResult | 783 | __out BOOL* pfResult |
765 | ) | 784 | ) |
766 | { | 785 | { |
@@ -771,37 +790,39 @@ static HRESULT CompareValues( | |||
771 | LONGLONG llRight = 0; | 790 | LONGLONG llRight = 0; |
772 | VERUTIL_VERSION* pVersionRight = 0; | 791 | VERUTIL_VERSION* pVersionRight = 0; |
773 | LPWSTR sczRight = NULL; | 792 | LPWSTR sczRight = NULL; |
793 | BURN_VARIANT* pLeftValue = &pLeftOperand->Value; | ||
794 | BURN_VARIANT* pRightValue = &pRightOperand->Value; | ||
774 | 795 | ||
775 | // get values to compare based on type | 796 | // get values to compare based on type |
776 | if (BURN_VARIANT_TYPE_STRING == leftOperand.Type && BURN_VARIANT_TYPE_STRING == rightOperand.Type) | 797 | if (BURN_VARIANT_TYPE_STRING == pLeftValue->Type && BURN_VARIANT_TYPE_STRING == pRightValue->Type) |
777 | { | 798 | { |
778 | hr = BVariantGetString(&leftOperand, &sczLeft); | 799 | hr = BVariantGetString(pLeftValue, &sczLeft); |
779 | ExitOnFailure(hr, "Failed to get the left string"); | 800 | ExitOnFailure(hr, "Failed to get the left string"); |
780 | hr = BVariantGetString(&rightOperand, &sczRight); | 801 | hr = BVariantGetString(pRightValue, &sczRight); |
781 | ExitOnFailure(hr, "Failed to get the right string"); | 802 | ExitOnFailure(hr, "Failed to get the right string"); |
782 | hr = CompareStringValues(comparison, sczLeft, sczRight, pfResult); | 803 | hr = CompareStringValues(comparison, sczLeft, sczRight, pfResult); |
783 | } | 804 | } |
784 | else if (BURN_VARIANT_TYPE_NUMERIC == leftOperand.Type && BURN_VARIANT_TYPE_NUMERIC == rightOperand.Type) | 805 | else if (BURN_VARIANT_TYPE_NUMERIC == pLeftValue->Type && BURN_VARIANT_TYPE_NUMERIC == pRightValue->Type) |
785 | { | 806 | { |
786 | hr = BVariantGetNumeric(&leftOperand, &llLeft); | 807 | hr = BVariantGetNumeric(pLeftValue, &llLeft); |
787 | ExitOnFailure(hr, "Failed to get the left numeric"); | 808 | ExitOnFailure(hr, "Failed to get the left numeric"); |
788 | hr = BVariantGetNumeric(&rightOperand, &llRight); | 809 | hr = BVariantGetNumeric(pRightValue, &llRight); |
789 | ExitOnFailure(hr, "Failed to get the right numeric"); | 810 | ExitOnFailure(hr, "Failed to get the right numeric"); |
790 | hr = CompareIntegerValues(comparison, llLeft, llRight, pfResult); | 811 | hr = CompareIntegerValues(comparison, llLeft, llRight, pfResult); |
791 | } | 812 | } |
792 | else if (BURN_VARIANT_TYPE_VERSION == leftOperand.Type && BURN_VARIANT_TYPE_VERSION == rightOperand.Type) | 813 | else if (BURN_VARIANT_TYPE_VERSION == pLeftValue->Type && BURN_VARIANT_TYPE_VERSION == pRightValue->Type) |
793 | { | 814 | { |
794 | hr = BVariantGetVersion(&leftOperand, &pVersionLeft); | 815 | hr = BVariantGetVersionHidden(pLeftValue, pLeftOperand->fHidden, &pVersionLeft); |
795 | ExitOnFailure(hr, "Failed to get the left version"); | 816 | ExitOnFailure(hr, "Failed to get the left version"); |
796 | hr = BVariantGetVersion(&rightOperand, &pVersionRight); | 817 | hr = BVariantGetVersionHidden(pRightValue, pRightOperand->fHidden, &pVersionRight); |
797 | ExitOnFailure(hr, "Failed to get the right version"); | 818 | ExitOnFailure(hr, "Failed to get the right version"); |
798 | hr = CompareVersionValues(comparison, pVersionLeft, pVersionRight, pfResult); | 819 | hr = CompareVersionValues(comparison, pVersionLeft, pVersionRight, pfResult); |
799 | } | 820 | } |
800 | else if (BURN_VARIANT_TYPE_VERSION == leftOperand.Type && BURN_VARIANT_TYPE_STRING == rightOperand.Type) | 821 | else if (BURN_VARIANT_TYPE_VERSION == pLeftValue->Type && BURN_VARIANT_TYPE_STRING == pRightValue->Type) |
801 | { | 822 | { |
802 | hr = BVariantGetVersion(&leftOperand, &pVersionLeft); | 823 | hr = BVariantGetVersionHidden(pLeftValue, pLeftOperand->fHidden, &pVersionLeft); |
803 | ExitOnFailure(hr, "Failed to get the left version"); | 824 | ExitOnFailure(hr, "Failed to get the left version"); |
804 | hr = BVariantGetVersion(&rightOperand, &pVersionRight); | 825 | hr = BVariantGetVersionHidden(pRightValue, pRightOperand->fHidden, &pVersionRight); |
805 | if (FAILED(hr)) | 826 | if (FAILED(hr)) |
806 | { | 827 | { |
807 | if (DISP_E_TYPEMISMATCH != hr) | 828 | if (DISP_E_TYPEMISMATCH != hr) |
@@ -816,11 +837,11 @@ static HRESULT CompareValues( | |||
816 | hr = CompareVersionValues(comparison, pVersionLeft, pVersionRight, pfResult); | 837 | hr = CompareVersionValues(comparison, pVersionLeft, pVersionRight, pfResult); |
817 | } | 838 | } |
818 | } | 839 | } |
819 | else if (BURN_VARIANT_TYPE_STRING == leftOperand.Type && BURN_VARIANT_TYPE_VERSION == rightOperand.Type) | 840 | else if (BURN_VARIANT_TYPE_STRING == pLeftValue->Type && BURN_VARIANT_TYPE_VERSION == pRightValue->Type) |
820 | { | 841 | { |
821 | hr = BVariantGetVersion(&rightOperand, &pVersionRight); | 842 | hr = BVariantGetVersionHidden(pRightValue, pRightOperand->fHidden, &pVersionRight); |
822 | ExitOnFailure(hr, "Failed to get the right version"); | 843 | ExitOnFailure(hr, "Failed to get the right version"); |
823 | hr = BVariantGetVersion(&leftOperand, &pVersionLeft); | 844 | hr = BVariantGetVersionHidden(pLeftValue, pLeftOperand->fHidden, &pVersionLeft); |
824 | if (FAILED(hr)) | 845 | if (FAILED(hr)) |
825 | { | 846 | { |
826 | if (DISP_E_TYPEMISMATCH != hr) | 847 | if (DISP_E_TYPEMISMATCH != hr) |
@@ -835,11 +856,11 @@ static HRESULT CompareValues( | |||
835 | hr = CompareVersionValues(comparison, pVersionLeft, pVersionRight, pfResult); | 856 | hr = CompareVersionValues(comparison, pVersionLeft, pVersionRight, pfResult); |
836 | } | 857 | } |
837 | } | 858 | } |
838 | else if (BURN_VARIANT_TYPE_NUMERIC == leftOperand.Type && BURN_VARIANT_TYPE_STRING == rightOperand.Type) | 859 | else if (BURN_VARIANT_TYPE_NUMERIC == pLeftValue->Type && BURN_VARIANT_TYPE_STRING == pRightValue->Type) |
839 | { | 860 | { |
840 | hr = BVariantGetNumeric(&leftOperand, &llLeft); | 861 | hr = BVariantGetNumeric(pLeftValue, &llLeft); |
841 | ExitOnFailure(hr, "Failed to get the left numeric"); | 862 | ExitOnFailure(hr, "Failed to get the left numeric"); |
842 | hr = BVariantGetNumeric(&rightOperand, &llRight); | 863 | hr = BVariantGetNumeric(pRightValue, &llRight); |
843 | if (FAILED(hr)) | 864 | if (FAILED(hr)) |
844 | { | 865 | { |
845 | if (DISP_E_TYPEMISMATCH != hr) | 866 | if (DISP_E_TYPEMISMATCH != hr) |
@@ -854,11 +875,11 @@ static HRESULT CompareValues( | |||
854 | hr = CompareIntegerValues(comparison, llLeft, llRight, pfResult); | 875 | hr = CompareIntegerValues(comparison, llLeft, llRight, pfResult); |
855 | } | 876 | } |
856 | } | 877 | } |
857 | else if (BURN_VARIANT_TYPE_STRING == leftOperand.Type && BURN_VARIANT_TYPE_NUMERIC == rightOperand.Type) | 878 | else if (BURN_VARIANT_TYPE_STRING == pLeftValue->Type && BURN_VARIANT_TYPE_NUMERIC == pRightValue->Type) |
858 | { | 879 | { |
859 | hr = BVariantGetNumeric(&rightOperand, &llRight); | 880 | hr = BVariantGetNumeric(pRightValue, &llRight); |
860 | ExitOnFailure(hr, "Failed to get the right numeric"); | 881 | ExitOnFailure(hr, "Failed to get the right numeric"); |
861 | hr = BVariantGetNumeric(&leftOperand, &llLeft); | 882 | hr = BVariantGetNumeric(pLeftValue, &llLeft); |
862 | if (FAILED(hr)) | 883 | if (FAILED(hr)) |
863 | { | 884 | { |
864 | if (DISP_E_TYPEMISMATCH != hr) | 885 | if (DISP_E_TYPEMISMATCH != hr) |