aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2020-11-01 14:16:32 -0600
committerSean Hall <r.sean.hall@gmail.com>2020-11-01 18:35:01 -0600
commitb5553689ed1b1bd32f854654f56935c039a9b13b (patch)
tree6afcbd397eebab56c8235b30ee10d4d07d89de2b
parent79d7d3aa1de224d90d5e3a1174b3158ffe49b6f3 (diff)
downloadwix-b5553689ed1b1bd32f854654f56935c039a9b13b.tar.gz
wix-b5553689ed1b1bd32f854654f56935c039a9b13b.tar.bz2
wix-b5553689ed1b1bd32f854654f56935c039a9b13b.zip
WIXFEAT:6258 - Format variables when evaluating condition.
-rw-r--r--src/engine/condition.cpp11
-rw-r--r--src/engine/variable.cpp114
-rw-r--r--src/engine/variable.h3
-rw-r--r--src/test/BurnUnitTest/VariableHelpers.cpp4
-rw-r--r--src/test/BurnUnitTest/VariableHelpers.h2
-rw-r--r--src/test/BurnUnitTest/VariableTest.cpp33
6 files changed, 112 insertions, 55 deletions
diff --git a/src/engine/condition.cpp b/src/engine/condition.cpp
index 224eb0da..d6038b34 100644
--- a/src/engine/condition.cpp
+++ b/src/engine/condition.cpp
@@ -432,6 +432,7 @@ static HRESULT ParseOperand(
432 ) 432 )
433{ 433{
434 HRESULT hr = S_OK; 434 HRESULT hr = S_OK;
435 LPWSTR sczFormatted = NULL;
435 436
436 // Symbols don't encrypt their value, so can access the value directly. 437 // Symbols don't encrypt their value, so can access the value directly.
437 switch (pContext->NextSymbol.Type) 438 switch (pContext->NextSymbol.Type)
@@ -451,9 +452,11 @@ static HRESULT ParseOperand(
451 452
452 if (BURN_VARIANT_TYPE_FORMATTED == pOperand->Value.Type) 453 if (BURN_VARIANT_TYPE_FORMATTED == pOperand->Value.Type)
453 { 454 {
454 // TODO: actually format the value? 455 hr = VariableGetFormatted(pContext->pVariables, pContext->NextSymbol.Value.sczValue, &sczFormatted, &pOperand->fHidden);
455 hr = BVariantChangeType(&pOperand->Value, BURN_VARIANT_TYPE_STRING); 456 ExitOnRootFailure(hr, "Failed to format variable '%ls' 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); 457
458 hr = BVariantSetString(&pOperand->Value, sczFormatted, 0, FALSE);
459 ExitOnRootFailure(hr, "Failed to store formatted value for variable '%ls' for condition '%ls'", pContext->NextSymbol.Value.sczValue, pContext->wzCondition);
457 } 460 }
458 break; 461 break;
459 462
@@ -477,6 +480,8 @@ static HRESULT ParseOperand(
477 ExitOnFailure(hr, "Failed to read next symbol."); 480 ExitOnFailure(hr, "Failed to read next symbol.");
478 481
479LExit: 482LExit:
483 StrSecureZeroFreeString(sczFormatted);
484
480 return hr; 485 return hr;
481} 486}
482 487
diff --git a/src/engine/variable.cpp b/src/engine/variable.cpp
index 3425b92c..8b6b318b 100644
--- a/src/engine/variable.cpp
+++ b/src/engine/variable.cpp
@@ -54,7 +54,14 @@ static HRESULT FormatString(
54 __in_z LPCWSTR wzIn, 54 __in_z LPCWSTR wzIn,
55 __out_z_opt LPWSTR* psczOut, 55 __out_z_opt LPWSTR* psczOut,
56 __out_opt DWORD* pcchOut, 56 __out_opt DWORD* pcchOut,
57 __in BOOL fObfuscateHiddenVariables 57 __in BOOL fObfuscateHiddenVariables,
58 __out BOOL* pfContainsHiddenVariable
59 );
60static HRESULT GetFormatted(
61 __in BURN_VARIABLES* pVariables,
62 __in_z LPCWSTR wzVariable,
63 __out_z LPWSTR* psczValue,
64 __out BOOL* pfContainsHiddenVariable
58 ); 65 );
59static HRESULT AddBuiltInVariable( 66static HRESULT AddBuiltInVariable(
60 __in BURN_VARIABLES* pVariables, 67 __in BURN_VARIABLES* pVariables,
@@ -629,43 +636,18 @@ LExit:
629extern "C" HRESULT VariableGetFormatted( 636extern "C" HRESULT VariableGetFormatted(
630 __in BURN_VARIABLES* pVariables, 637 __in BURN_VARIABLES* pVariables,
631 __in_z LPCWSTR wzVariable, 638 __in_z LPCWSTR wzVariable,
632 __out_z LPWSTR* psczValue 639 __out_z LPWSTR* psczValue,
640 __out BOOL* pfContainsHiddenVariable
633 ) 641 )
634{ 642{
635 HRESULT hr = S_OK; 643 HRESULT hr = S_OK;
636 BURN_VARIABLE* pVariable = NULL;
637 LPWSTR scz = NULL;
638
639 ::EnterCriticalSection(&pVariables->csAccess);
640 644
641 hr = GetVariable(pVariables, wzVariable, &pVariable); 645 if (pfContainsHiddenVariable)
642 if (SUCCEEDED(hr) && BURN_VARIANT_TYPE_NONE == pVariable->Value.Type)
643 { 646 {
644 ExitFunction1(hr = E_NOTFOUND); 647 *pfContainsHiddenVariable = FALSE;
645 }
646 else if (E_NOTFOUND == hr)
647 {
648 ExitFunction();
649 } 648 }
650 ExitOnFailure(hr, "Failed to get variable: %ls", wzVariable);
651 649
652 if (BURN_VARIANT_TYPE_FORMATTED == pVariable->Value.Type) 650 hr = GetFormatted(pVariables, wzVariable, psczValue, pfContainsHiddenVariable);
653 {
654 hr = BVariantGetString(&pVariable->Value, &scz);
655 ExitOnFailure(hr, "Failed to get unformatted string.");
656
657 hr = VariableFormatString(pVariables, scz, psczValue, NULL);
658 ExitOnFailure(hr, "Failed to format value '%ls' of variable: %ls", pVariable->fHidden ? L"*****" : pVariable->Value.sczValue, wzVariable);
659 }
660 else
661 {
662 hr = BVariantGetString(&pVariable->Value, psczValue);
663 ExitOnFailure(hr, "Failed to get value as string for variable: %ls", wzVariable);
664 }
665
666LExit:
667 ::LeaveCriticalSection(&pVariables->csAccess);
668 StrSecureZeroFreeString(scz);
669 651
670 return hr; 652 return hr;
671} 653}
@@ -736,7 +718,7 @@ extern "C" HRESULT VariableFormatString(
736 __out_opt DWORD* pcchOut 718 __out_opt DWORD* pcchOut
737 ) 719 )
738{ 720{
739 return FormatString(pVariables, wzIn, psczOut, pcchOut, FALSE); 721 return FormatString(pVariables, wzIn, psczOut, pcchOut, FALSE, NULL);
740} 722}
741 723
742extern "C" HRESULT VariableFormatStringObfuscated( 724extern "C" HRESULT VariableFormatStringObfuscated(
@@ -746,7 +728,7 @@ extern "C" HRESULT VariableFormatStringObfuscated(
746 __out_opt DWORD* pcchOut 728 __out_opt DWORD* pcchOut
747 ) 729 )
748{ 730{
749 return FormatString(pVariables, wzIn, psczOut, pcchOut, TRUE); 731 return FormatString(pVariables, wzIn, psczOut, pcchOut, TRUE, NULL);
750} 732}
751 733
752extern "C" HRESULT VariableEscapeString( 734extern "C" HRESULT VariableEscapeString(
@@ -1116,7 +1098,8 @@ static HRESULT FormatString(
1116 __in_z LPCWSTR wzIn, 1098 __in_z LPCWSTR wzIn,
1117 __out_z_opt LPWSTR* psczOut, 1099 __out_z_opt LPWSTR* psczOut,
1118 __out_opt DWORD* pcchOut, 1100 __out_opt DWORD* pcchOut,
1119 __in BOOL fObfuscateHiddenVariables 1101 __in BOOL fObfuscateHiddenVariables,
1102 __out BOOL* pfContainsHiddenVariable
1120 ) 1103 )
1121{ 1104{
1122 HRESULT hr = S_OK; 1105 HRESULT hr = S_OK;
@@ -1204,20 +1187,22 @@ static HRESULT FormatString(
1204 } 1187 }
1205 else 1188 else
1206 { 1189 {
1207 if (fObfuscateHiddenVariables) 1190 hr = VariableIsHidden(pVariables, scz, &fHidden);
1191 ExitOnFailure(hr, "Failed to determine variable visibility: '%ls'.", scz);
1192
1193 if (pfContainsHiddenVariable)
1208 { 1194 {
1209 hr = VariableIsHidden(pVariables, scz, &fHidden); 1195 *pfContainsHiddenVariable |= fHidden;
1210 ExitOnFailure(hr, "Failed to determine variable visibility: '%ls'.", scz);
1211 } 1196 }
1212 1197
1213 if (fHidden) 1198 if (fObfuscateHiddenVariables && fHidden)
1214 { 1199 {
1215 hr = StrAllocString(&rgVariables[cVariables], L"*****", 0); 1200 hr = StrAllocString(&rgVariables[cVariables], L"*****", 0);
1216 } 1201 }
1217 else 1202 else
1218 { 1203 {
1219 // get formatted variable value 1204 // get formatted variable value
1220 hr = VariableGetFormatted(pVariables, scz, &rgVariables[cVariables]); 1205 hr = GetFormatted(pVariables, scz, &rgVariables[cVariables], pfContainsHiddenVariable);
1221 if (E_NOTFOUND == hr) // variable not found 1206 if (E_NOTFOUND == hr) // variable not found
1222 { 1207 {
1223 hr = StrAllocStringSecure(&rgVariables[cVariables], L"", 0); 1208 hr = StrAllocStringSecure(&rgVariables[cVariables], L"", 0);
@@ -1327,6 +1312,57 @@ LExit:
1327 return hr; 1312 return hr;
1328} 1313}
1329 1314
1315// The contents of psczOut may be sensitive, should keep encrypted and SecureZeroFree.
1316static HRESULT GetFormatted(
1317 __in BURN_VARIABLES* pVariables,
1318 __in_z LPCWSTR wzVariable,
1319 __out_z LPWSTR* psczValue,
1320 __out BOOL* pfContainsHiddenVariable
1321 )
1322{
1323 HRESULT hr = S_OK;
1324 BURN_VARIABLE* pVariable = NULL;
1325 LPWSTR scz = NULL;
1326
1327 ::EnterCriticalSection(&pVariables->csAccess);
1328
1329 hr = GetVariable(pVariables, wzVariable, &pVariable);
1330 if (SUCCEEDED(hr) && BURN_VARIANT_TYPE_NONE == pVariable->Value.Type)
1331 {
1332 ExitFunction1(hr = E_NOTFOUND);
1333 }
1334 else if (E_NOTFOUND == hr)
1335 {
1336 ExitFunction();
1337 }
1338 ExitOnFailure(hr, "Failed to get variable: %ls", wzVariable);
1339
1340 if (pfContainsHiddenVariable)
1341 {
1342 *pfContainsHiddenVariable |= pVariable->fHidden;
1343 }
1344
1345 if (BURN_VARIANT_TYPE_FORMATTED == pVariable->Value.Type)
1346 {
1347 hr = BVariantGetString(&pVariable->Value, &scz);
1348 ExitOnFailure(hr, "Failed to get unformatted string.");
1349
1350 hr = FormatString(pVariables, scz, psczValue, NULL, FALSE, pfContainsHiddenVariable);
1351 ExitOnFailure(hr, "Failed to format value '%ls' of variable: %ls", pVariable->fHidden ? L"*****" : pVariable->Value.sczValue, wzVariable);
1352 }
1353 else
1354 {
1355 hr = BVariantGetString(&pVariable->Value, psczValue);
1356 ExitOnFailure(hr, "Failed to get value as string for variable: %ls", wzVariable);
1357 }
1358
1359LExit:
1360 ::LeaveCriticalSection(&pVariables->csAccess);
1361 StrSecureZeroFreeString(scz);
1362
1363 return hr;
1364}
1365
1330static HRESULT AddBuiltInVariable( 1366static HRESULT AddBuiltInVariable(
1331 __in BURN_VARIABLES* pVariables, 1367 __in BURN_VARIABLES* pVariables,
1332 __in LPCWSTR wzVariable, 1368 __in LPCWSTR wzVariable,
diff --git a/src/engine/variable.h b/src/engine/variable.h
index 6437c32f..713fe6e3 100644
--- a/src/engine/variable.h
+++ b/src/engine/variable.h
@@ -95,7 +95,8 @@ HRESULT VariableGetVariant(
95HRESULT VariableGetFormatted( 95HRESULT VariableGetFormatted(
96 __in BURN_VARIABLES* pVariables, 96 __in BURN_VARIABLES* pVariables,
97 __in_z LPCWSTR wzVariable, 97 __in_z LPCWSTR wzVariable,
98 __out_z LPWSTR* psczValue 98 __out_z LPWSTR* psczValue,
99 __out BOOL* pfContainsHiddenVariable
99 ); 100 );
100HRESULT VariableSetNumeric( 101HRESULT VariableSetNumeric(
101 __in BURN_VARIABLES* pVariables, 102 __in BURN_VARIABLES* pVariables,
diff --git a/src/test/BurnUnitTest/VariableHelpers.cpp b/src/test/BurnUnitTest/VariableHelpers.cpp
index 99ba492a..40f958f8 100644
--- a/src/test/BurnUnitTest/VariableHelpers.cpp
+++ b/src/test/BurnUnitTest/VariableHelpers.cpp
@@ -98,13 +98,13 @@ namespace Bootstrapper
98 } 98 }
99 } 99 }
100 100
101 String^ VariableGetFormattedHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable) 101 String^ VariableGetFormattedHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable, BOOL* pfContainsHiddenVariable)
102 { 102 {
103 HRESULT hr = S_OK; 103 HRESULT hr = S_OK;
104 LPWSTR scz = NULL; 104 LPWSTR scz = NULL;
105 try 105 try
106 { 106 {
107 hr = VariableGetFormatted(pVariables, wzVariable, &scz); 107 hr = VariableGetFormatted(pVariables, wzVariable, &scz, pfContainsHiddenVariable);
108 TestThrowOnFailure1(hr, L"Failed to get formatted: %s", wzVariable); 108 TestThrowOnFailure1(hr, L"Failed to get formatted: %s", wzVariable);
109 109
110 return gcnew String(scz); 110 return gcnew String(scz);
diff --git a/src/test/BurnUnitTest/VariableHelpers.h b/src/test/BurnUnitTest/VariableHelpers.h
index 96122219..d460c60f 100644
--- a/src/test/BurnUnitTest/VariableHelpers.h
+++ b/src/test/BurnUnitTest/VariableHelpers.h
@@ -20,7 +20,7 @@ void VariableSetVersionHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable, LP
20System::String^ VariableGetStringHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable); 20System::String^ VariableGetStringHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable);
21__int64 VariableGetNumericHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable); 21__int64 VariableGetNumericHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable);
22System::String^ VariableGetVersionHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable); 22System::String^ VariableGetVersionHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable);
23System::String^ VariableGetFormattedHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable); 23System::String^ VariableGetFormattedHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable, BOOL* pfContainsHiddenVariable);
24System::String^ VariableFormatStringHelper(BURN_VARIABLES* pVariables, LPCWSTR wzIn); 24System::String^ VariableFormatStringHelper(BURN_VARIABLES* pVariables, LPCWSTR wzIn);
25System::String^ VariableEscapeStringHelper(LPCWSTR wzIn); 25System::String^ VariableEscapeStringHelper(LPCWSTR wzIn);
26bool EvaluateConditionHelper(BURN_VARIABLES* pVariables, LPCWSTR wzCondition); 26bool EvaluateConditionHelper(BURN_VARIABLES* pVariables, LPCWSTR wzCondition);
diff --git a/src/test/BurnUnitTest/VariableTest.cpp b/src/test/BurnUnitTest/VariableTest.cpp
index f5511199..676c134e 100644
--- a/src/test/BurnUnitTest/VariableTest.cpp
+++ b/src/test/BurnUnitTest/VariableTest.cpp
@@ -80,6 +80,7 @@ namespace Bootstrapper
80 HRESULT hr = S_OK; 80 HRESULT hr = S_OK;
81 IXMLDOMElement* pixeBundle = NULL; 81 IXMLDOMElement* pixeBundle = NULL;
82 BURN_VARIABLES variables = { }; 82 BURN_VARIABLES variables = { };
83 BOOL fContainsHiddenData = FALSE;
83 try 84 try
84 { 85 {
85 LPCWSTR wzDocument = 86 LPCWSTR wzDocument =
@@ -90,6 +91,7 @@ namespace Bootstrapper
90 L" <Variable Id='Var4' Hidden='no' Persisted='no' />" 91 L" <Variable Id='Var4' Hidden='no' Persisted='no' />"
91 L" <Variable Id='Var5' Type='string' Value='' Hidden='no' Persisted='no' />" 92 L" <Variable Id='Var5' Type='string' Value='' Hidden='no' Persisted='no' />"
92 L" <Variable Id='Var6' Type='formatted' Value='[Formatted]' Hidden='no' Persisted='no' />" 93 L" <Variable Id='Var6' Type='formatted' Value='[Formatted]' Hidden='no' Persisted='no' />"
94 L" <Variable Id='Formatted' Type='formatted' Value='supersecret' Hidden='yes' Persisted='no' />"
93 L"</Bundle>"; 95 L"</Bundle>";
94 96
95 hr = VariableInitialize(&variables); 97 hr = VariableInitialize(&variables);
@@ -99,7 +101,7 @@ namespace Bootstrapper
99 LoadBundleXmlHelper(wzDocument, &pixeBundle); 101 LoadBundleXmlHelper(wzDocument, &pixeBundle);
100 102
101 hr = VariablesParseFromXml(&variables, pixeBundle); 103 hr = VariablesParseFromXml(&variables, pixeBundle);
102 TestThrowOnFailure(hr, L"Failed to parse searches from XML."); 104 TestThrowOnFailure(hr, L"Failed to parse variables from XML.");
103 105
104 // get and verify variable values 106 // get and verify variable values
105 Assert::Equal((int)BURN_VARIANT_TYPE_NUMERIC, VariableGetTypeHelper(&variables, L"Var1")); 107 Assert::Equal((int)BURN_VARIANT_TYPE_NUMERIC, VariableGetTypeHelper(&variables, L"Var1"));
@@ -112,6 +114,12 @@ namespace Bootstrapper
112 Assert::Equal<String^>(gcnew String(L"String value."), VariableGetStringHelper(&variables, L"Var2")); 114 Assert::Equal<String^>(gcnew String(L"String value."), VariableGetStringHelper(&variables, L"Var2"));
113 Assert::Equal<String^>(gcnew String(L"1.2.3.4"), VariableGetVersionHelper(&variables, L"Var3")); 115 Assert::Equal<String^>(gcnew String(L"1.2.3.4"), VariableGetVersionHelper(&variables, L"Var3"));
114 Assert::Equal<String^>(gcnew String(L"[Formatted]"), VariableGetStringHelper(&variables, L"Var6")); 116 Assert::Equal<String^>(gcnew String(L"[Formatted]"), VariableGetStringHelper(&variables, L"Var6"));
117 Assert::Equal<String^>(gcnew String(L"supersecret"), VariableGetFormattedHelper(&variables, L"Formatted", &fContainsHiddenData));
118 Assert::Equal<BOOL>(TRUE, fContainsHiddenData);
119 Assert::Equal<String^>(gcnew String(L"supersecret"), VariableGetFormattedHelper(&variables, L"Var6", &fContainsHiddenData));
120 Assert::Equal<BOOL>(TRUE, fContainsHiddenData);
121 Assert::Equal<String^>(gcnew String(L"String value."), VariableGetFormattedHelper(&variables, L"Var2", &fContainsHiddenData));
122 Assert::Equal<BOOL>(FALSE, fContainsHiddenData);
115 } 123 }
116 finally 124 finally
117 { 125 {
@@ -127,6 +135,7 @@ namespace Bootstrapper
127 BURN_VARIABLES variables = { }; 135 BURN_VARIABLES variables = { };
128 LPWSTR scz = NULL; 136 LPWSTR scz = NULL;
129 DWORD cch = 0; 137 DWORD cch = 0;
138 BOOL fContainsHiddenData = FALSE;
130 try 139 try
131 { 140 {
132 hr = VariableInitialize(&variables); 141 hr = VariableInitialize(&variables);
@@ -155,12 +164,18 @@ namespace Bootstrapper
155 Assert::Equal<String^>(gcnew String(L"]"), VariableFormatStringHelper(&variables, L"[\\]]")); 164 Assert::Equal<String^>(gcnew String(L"]"), VariableFormatStringHelper(&variables, L"[\\]]"));
156 Assert::Equal<String^>(gcnew String(L"[]"), VariableFormatStringHelper(&variables, L"[]")); 165 Assert::Equal<String^>(gcnew String(L"[]"), VariableFormatStringHelper(&variables, L"[]"));
157 Assert::Equal<String^>(gcnew String(L"[NONE"), VariableFormatStringHelper(&variables, L"[NONE")); 166 Assert::Equal<String^>(gcnew String(L"[NONE"), VariableFormatStringHelper(&variables, L"[NONE"));
158 Assert::Equal<String^>(gcnew String(L"VAL2"), VariableGetFormattedHelper(&variables, L"PROP2")); 167 Assert::Equal<String^>(gcnew String(L"VAL2"), VariableGetFormattedHelper(&variables, L"PROP2", &fContainsHiddenData));
159 Assert::Equal<String^>(gcnew String(L"3"), VariableGetFormattedHelper(&variables, L"PROP3")); 168 Assert::Equal<BOOL>(FALSE, fContainsHiddenData);
160 Assert::Equal<String^>(gcnew String(L"[PROP1]"), VariableGetFormattedHelper(&variables, L"PROP4")); 169 Assert::Equal<String^>(gcnew String(L"3"), VariableGetFormattedHelper(&variables, L"PROP3", &fContainsHiddenData));
161 Assert::Equal<String^>(gcnew String(L"[PROP2]"), VariableGetFormattedHelper(&variables, L"PROP5")); 170 Assert::Equal<BOOL>(FALSE, fContainsHiddenData);
162 Assert::Equal<String^>(gcnew String(L"[PROP1]"), VariableGetFormattedHelper(&variables, L"PROP6")); 171 Assert::Equal<String^>(gcnew String(L"[PROP1]"), VariableGetFormattedHelper(&variables, L"PROP4", &fContainsHiddenData));
163 Assert::Equal<String^>(gcnew String(L"[PROP2]"), VariableGetFormattedHelper(&variables, L"PROP7")); 172 Assert::Equal<BOOL>(FALSE, fContainsHiddenData);
173 Assert::Equal<String^>(gcnew String(L"[PROP2]"), VariableGetFormattedHelper(&variables, L"PROP5", &fContainsHiddenData));
174 Assert::Equal<BOOL>(FALSE, fContainsHiddenData);
175 Assert::Equal<String^>(gcnew String(L"[PROP1]"), VariableGetFormattedHelper(&variables, L"PROP6", &fContainsHiddenData));
176 Assert::Equal<BOOL>(FALSE, fContainsHiddenData);
177 Assert::Equal<String^>(gcnew String(L"[PROP2]"), VariableGetFormattedHelper(&variables, L"PROP7", &fContainsHiddenData));
178 Assert::Equal<BOOL>(FALSE, fContainsHiddenData);
164 179
165 hr = VariableFormatString(&variables, L"PRE [PROP1] POST", &scz, &cch); 180 hr = VariableFormatString(&variables, L"PRE [PROP1] POST", &scz, &cch);
166 TestThrowOnFailure(hr, L"Failed to format string"); 181 TestThrowOnFailure(hr, L"Failed to format string");
@@ -235,8 +250,8 @@ namespace Bootstrapper
235 Assert::True(EvaluateConditionHelper(&variables, L"_PROP9")); 250 Assert::True(EvaluateConditionHelper(&variables, L"_PROP9"));
236 Assert::True(EvaluateConditionHelper(&variables, L"PROP16")); 251 Assert::True(EvaluateConditionHelper(&variables, L"PROP16"));
237 Assert::True(EvaluateConditionHelper(&variables, L"PROP17")); 252 Assert::True(EvaluateConditionHelper(&variables, L"PROP17"));
238 Assert::True(EvaluateConditionHelper(&variables, L"PROP24")); 253 Assert::True(EvaluateConditionHelper(&variables, L"PROP24=\"VAL1\""));
239 Assert::True(EvaluateConditionHelper(&variables, L"PROP25")); 254 Assert::False(EvaluateConditionHelper(&variables, L"PROP25"));
240 Assert::True(EvaluateConditionHelper(&variables, L"PROP26")); 255 Assert::True(EvaluateConditionHelper(&variables, L"PROP26"));
241 Assert::True(EvaluateConditionHelper(&variables, L"PROP27")); 256 Assert::True(EvaluateConditionHelper(&variables, L"PROP27"));
242 257