aboutsummaryrefslogtreecommitdiff
path: root/src/engine/condition.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/engine/condition.cpp125
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
76struct 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 );
95static HRESULT ParseValue( 101static 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 );
99static HRESULT Expect( 105static HRESULT Expect(
100 __in BURN_CONDITION_PARSE_CONTEXT* pContext, 106 __in BURN_CONDITION_PARSE_CONTEXT* pContext,
@@ -103,10 +109,10 @@ static HRESULT Expect(
103static HRESULT NextSymbol( 109static HRESULT NextSymbol(
104 __in BURN_CONDITION_PARSE_CONTEXT* pContext 110 __in BURN_CONDITION_PARSE_CONTEXT* pContext
105 ); 111 );
106static HRESULT CompareValues( 112static 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 );
112static HRESULT CompareStringValues( 118static 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
417LExit: 423LExit:
418 BVariantUninitialize(&firstValue); 424 BVariantUninitialize(&firstOperand.Value);
419 BVariantUninitialize(&secondValue); 425 BVariantUninitialize(&secondOperand.Value);
420 return hr; 426 return hr;
421} 427}
422 428
423static HRESULT ParseValue( 429static 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//
760static HRESULT CompareValues( 779static 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)