@joebigelow / wix-1 / commits / d21eed76

WIXFEAT:4763 Change "string" variable type to literal and add "formatted".

Sean Hall committed Jul 31, 2020 at 17:06 UTC d21eed76c48960707561c45c492c10a6a23c052e
25 files changed +313 -214
src/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h
+1
@@ -398,6 +398,7 @@ typedef struct _BAENGINE_SETVARIABLESTRING_ARGS
398 DWORD cbSize;
399 LPCWSTR wzVariable;
400 LPCWSTR wzValue;
401 + BOOL fFormatted;
402 } BAENGINE_SETVARIABLESTRING_ARGS;
403
404 typedef struct _BAENGINE_SETVARIABLESTRING_RESULTS
src/WixToolset.BootstrapperCore.Native/inc/BundleExtensionEngine.h
+1 -13
@@ -24,7 +24,6 @@ enum BUNDLE_EXTENSION_ENGINE_MESSAGE
24 BUNDLE_EXTENSION_ENGINE_MESSAGE_GETVARIABLESTRING,
25 BUNDLE_EXTENSION_ENGINE_MESSAGE_GETVARIABLEVERSION,
26 BUNDLE_EXTENSION_ENGINE_MESSAGE_LOG,
27 - BUNDLE_EXTENSION_ENGINE_MESSAGE_SETVARIABLELITERALSTRING,
27 BUNDLE_EXTENSION_ENGINE_MESSAGE_SETVARIABLENUMERIC,
28 BUNDLE_EXTENSION_ENGINE_MESSAGE_SETVARIABLESTRING,
29 BUNDLE_EXTENSION_ENGINE_MESSAGE_SETVARIABLEVERSION,
@@ -124,18 +123,6 @@ typedef struct _BUNDLE_EXTENSION_ENGINE_LOG_RESULTS
123 DWORD cbSize;
124 } BUNDLE_EXTENSION_ENGINE_LOG_RESULTS;
125
127 -typedef struct _BUNDLE_EXTENSION_ENGINE_SETVARIABLELITERALSTRING_ARGS
128 -{
129 - DWORD cbSize;
130 - LPCWSTR wzVariable;
131 - LPCWSTR wzValue;
132 -} BUNDLE_EXTENSION_ENGINE_SETVARIABLELITERALSTRING_ARGS;
133 -
134 -typedef struct _BUNDLE_EXTENSION_ENGINE_SETVARIABLELITERALSTRING_RESULTS
135 -{
136 - DWORD cbSize;
137 -} BUNDLE_EXTENSION_ENGINE_SETVARIABLELITERALSTRING_RESULTS;
138 -
126 typedef struct _BUNDLE_EXTENSION_ENGINE_SETVARIABLENUMERIC_ARGS
127 {
128 DWORD cbSize;
@@ -153,6 +140,7 @@ typedef struct _BUNDLE_EXTENSION_ENGINE_SETVARIABLESTRING_ARGS
140 DWORD cbSize;
141 LPCWSTR wzVariable;
142 LPCWSTR wzValue;
143 + BOOL fFormatted;
144 } BUNDLE_EXTENSION_ENGINE_SETVARIABLESTRING_ARGS;
145
146 typedef struct _BUNDLE_EXTENSION_ENGINE_SETVARIABLESTRING_RESULTS
src/engine/EngineForApplication.cpp
+1 -1
@@ -592,7 +592,7 @@ static HRESULT BAEngineSetVariableString(
592
593 if (wzVariable && *wzVariable)
594 {
595 - hr = VariableSetString(&pContext->pEngineState->variables, wzVariable, wzValue, FALSE);
595 + hr = VariableSetString(&pContext->pEngineState->variables, wzVariable, wzValue, FALSE, pArgs->fFormatted);
596 ExitOnFailure(hr, "Failed to set string variable.");
597 }
598 else
src/engine/EngineForExtension.cpp
+1 -29
@@ -245,31 +245,6 @@ LExit:
245 return hr;
246 }
247
248 -static HRESULT BEEngineSetVariableLiteralString(
249 - __in BURN_EXTENSION_ENGINE_CONTEXT* pContext,
250 - __in const BUNDLE_EXTENSION_ENGINE_SETVARIABLELITERALSTRING_ARGS* pArgs,
251 - __in BUNDLE_EXTENSION_ENGINE_SETVARIABLELITERALSTRING_RESULTS* /*pResults*/
252 - )
253 -{
254 - HRESULT hr = S_OK;
255 - LPCWSTR wzVariable = pArgs->wzVariable;
256 - LPCWSTR wzValue = pArgs->wzValue;
257 -
258 - if (wzVariable && *wzVariable)
259 - {
260 - hr = VariableSetLiteralString(&pContext->pEngineState->variables, wzVariable, wzValue, FALSE);
261 - ExitOnFailure(hr, "Failed to set literal string variable.");
262 - }
263 - else
264 - {
265 - hr = E_INVALIDARG;
266 - ExitOnFailure(hr, "Bundle Extension did not provide variable name.");
267 - }
268 -
269 -LExit:
270 - return hr;
271 -}
272 -
248 static HRESULT BEEngineSetVariableNumeric(
249 __in BURN_EXTENSION_ENGINE_CONTEXT* pContext,
250 __in const BUNDLE_EXTENSION_ENGINE_SETVARIABLENUMERIC_ARGS* pArgs,
@@ -307,7 +282,7 @@ static HRESULT BEEngineSetVariableString(
282
283 if (wzVariable && *wzVariable)
284 {
310 - hr = VariableSetString(&pContext->pEngineState->variables, wzVariable, wzValue, FALSE);
285 + hr = VariableSetString(&pContext->pEngineState->variables, wzVariable, wzValue, FALSE, pArgs->fFormatted);
286 ExitOnFailure(hr, "Failed to set string variable.");
287 }
288 else
@@ -383,9 +358,6 @@ HRESULT WINAPI EngineForExtensionProc(
358 case BUNDLE_EXTENSION_ENGINE_MESSAGE_LOG:
359 hr = BEEngineLog(pContext, reinterpret_cast<BUNDLE_EXTENSION_ENGINE_LOG_ARGS*>(pvArgs), reinterpret_cast<BUNDLE_EXTENSION_ENGINE_LOG_RESULTS*>(pvResults));
360 break;
386 - case BUNDLE_EXTENSION_ENGINE_MESSAGE_SETVARIABLELITERALSTRING:
387 - hr = BEEngineSetVariableLiteralString(pContext, reinterpret_cast<BUNDLE_EXTENSION_ENGINE_SETVARIABLELITERALSTRING_ARGS*>(pvArgs), reinterpret_cast<BUNDLE_EXTENSION_ENGINE_SETVARIABLELITERALSTRING_RESULTS*>(pvResults));
388 - break;
361 case BUNDLE_EXTENSION_ENGINE_MESSAGE_SETVARIABLENUMERIC:
362 hr = BEEngineSetVariableNumeric(pContext, reinterpret_cast<BUNDLE_EXTENSION_ENGINE_SETVARIABLENUMERIC_ARGS*>(pvArgs), reinterpret_cast<BUNDLE_EXTENSION_ENGINE_SETVARIABLENUMERIC_RESULTS*>(pvResults));
363 break;
src/engine/apply.cpp
+2 -2
@@ -272,7 +272,7 @@ extern "C" HRESULT ApplySetVariables(
272 {
273 HRESULT hr = S_OK;
274
275 - hr = VariableSetString(pVariables, BURN_BUNDLE_FORCED_RESTART_PACKAGE, NULL, TRUE);
275 + hr = VariableSetString(pVariables, BURN_BUNDLE_FORCED_RESTART_PACKAGE, NULL, TRUE, FALSE);
276 ExitOnFailure(hr, "Failed to set the bundle forced restart package built-in variable.");
277
278 LExit:
@@ -2493,7 +2493,7 @@ static HRESULT ExecutePackageComplete(
2493 if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == *pRestart)
2494 {
2495 // Best effort to set the forced restart package variable.
2496 - VariableSetString(pVariables, BURN_BUNDLE_FORCED_RESTART_PACKAGE, pPackage->sczId, TRUE);
2496 + VariableSetString(pVariables, BURN_BUNDLE_FORCED_RESTART_PACKAGE, pPackage->sczId, TRUE, FALSE);
2497 }
2498
2499 // If we're retrying, leave a message in the log file and say everything is okay.
src/engine/cache.cpp
+3 -3
@@ -157,7 +157,7 @@ extern "C" HRESULT CacheInitialize(
157 hr = VariableGetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE, &sczOriginalSource);
158 if (E_NOTFOUND == hr)
159 {
160 - hr = VariableSetLiteralString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE, wzSourceProcessPath, FALSE);
160 + hr = VariableSetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE, wzSourceProcessPath, FALSE, FALSE);
161 ExitOnFailure(hr, "Failed to set original source variable.");
162
163 hr = StrAllocString(&sczOriginalSource, wzSourceProcessPath, 0);
@@ -170,7 +170,7 @@ extern "C" HRESULT CacheInitialize(
170 hr = PathGetDirectory(sczOriginalSource, &sczOriginalSourceFolder);
171 ExitOnFailure(hr, "Failed to get directory from original source path.");
172
173 - hr = VariableSetLiteralString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER, sczOriginalSourceFolder, FALSE);
173 + hr = VariableSetString(pVariables, BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER, sczOriginalSourceFolder, FALSE, FALSE);
174 ExitOnFailure(hr, "Failed to set original source directory variable.");
175 }
176 }
@@ -549,7 +549,7 @@ extern "C" HRESULT CacheSetLastUsedSource(
549
550 if (CSTR_EQUAL != nCompare)
551 {
552 - hr = VariableSetLiteralString(pVariables, BURN_BUNDLE_LAST_USED_SOURCE, sczSourceFolder, FALSE);
552 + hr = VariableSetString(pVariables, BURN_BUNDLE_LAST_USED_SOURCE, sczSourceFolder, FALSE, FALSE);
553 ExitOnFailure(hr, "Failed to set last source.");
554 }
555 }
src/engine/condition.cpp
+9 -2
@@ -439,6 +439,13 @@ static HRESULT ParseValue(
439 {
440 ExitOnRootFailure(hr, "Failed to find variable.");
441 }
442 +
443 + if (BURN_VARIANT_TYPE_FORMATTED == pValue->Type)
444 + {
445 + // TODO: actually format the value?
446 + hr = BVariantChangeType(pValue, BURN_VARIANT_TYPE_STRING);
447 + ExitOnRootFailure(hr, "Failed to change variable '%ls' type for condition '%ls'", pContext->NextSymbol.Value.sczValue, pContext->wzCondition);
448 + }
449 break;
450
451 case BURN_SYMBOL_TYPE_NUMBER: __fallthrough;
@@ -642,7 +649,7 @@ static HRESULT NextSymbol(
649 ++n; // terminating '"'
650
651 pContext->NextSymbol.Type = BURN_SYMBOL_TYPE_LITERAL;
645 - hr = BVariantSetString(&pContext->NextSymbol.Value, &pContext->wzRead[1], n - 2);
652 + hr = BVariantSetString(&pContext->NextSymbol.Value, &pContext->wzRead[1], n - 2, FALSE);
653 ExitOnFailure(hr, "Failed to set symbol value.");
654 break;
655 default:
@@ -746,7 +753,7 @@ static HRESULT NextSymbol(
753 {
754 // identifier
755 pContext->NextSymbol.Type = BURN_SYMBOL_TYPE_IDENTIFIER;
749 - hr = BVariantSetString(&pContext->NextSymbol.Value, pContext->wzRead, n);
756 + hr = BVariantSetString(&pContext->NextSymbol.Value, pContext->wzRead, n, FALSE);
757 ExitOnFailure(hr, "Failed to set symbol value.");
758 }
759 }
src/engine/core.cpp
+4 -4
@@ -113,13 +113,13 @@ extern "C" HRESULT CoreInitialize(
113
114 if (sczSourceProcessPath)
115 {
116 - hr = VariableSetLiteralString(&pEngineState->variables, BURN_BUNDLE_SOURCE_PROCESS_PATH, sczSourceProcessPath, TRUE);
116 + hr = VariableSetString(&pEngineState->variables, BURN_BUNDLE_SOURCE_PROCESS_PATH, sczSourceProcessPath, TRUE, FALSE);
117 ExitOnFailure(hr, "Failed to set source process path variable.");
118
119 hr = PathGetDirectory(sczSourceProcessPath, &sczSourceProcessFolder);
120 ExitOnFailure(hr, "Failed to get source process folder from path.");
121
122 - hr = VariableSetLiteralString(&pEngineState->variables, BURN_BUNDLE_SOURCE_PROCESS_FOLDER, sczSourceProcessFolder, TRUE);
122 + hr = VariableSetString(&pEngineState->variables, BURN_BUNDLE_SOURCE_PROCESS_FOLDER, sczSourceProcessFolder, TRUE, FALSE);
123 ExitOnFailure(hr, "Failed to set source process folder variable.");
124 }
125
@@ -127,7 +127,7 @@ extern "C" HRESULT CoreInitialize(
127 // Needs to be done after ManifestLoadXmlFromBuffer.
128 if (sczOriginalSource)
129 {
130 - hr = VariableSetLiteralString(&pEngineState->variables, BURN_BUNDLE_ORIGINAL_SOURCE, sczOriginalSource, FALSE);
130 + hr = VariableSetString(&pEngineState->variables, BURN_BUNDLE_ORIGINAL_SOURCE, sczOriginalSource, FALSE, FALSE);
131 ExitOnFailure(hr, "Failed to set original source variable.");
132 }
133
@@ -258,7 +258,7 @@ extern "C" HRESULT CoreDetect(
258 }
259 else
260 {
261 - hr = VariableSetString(&pEngineState->variables, BURN_BUNDLE_INSTALLED, NULL, TRUE);
261 + hr = VariableSetString(&pEngineState->variables, BURN_BUNDLE_INSTALLED, NULL, TRUE, FALSE);
262 ExitOnFailure(hr, "Failed to unset the bundle installed built-in variable.");
263 }
264
src/engine/engine.cpp
+1 -1
@@ -538,7 +538,7 @@ static HRESULT RunNormal(
538 // If a layout directory was specified on the command-line, set it as a well-known variable.
539 if (pEngineState->command.wzLayoutDirectory && *pEngineState->command.wzLayoutDirectory)
540 {
541 - hr = VariableSetString(&pEngineState->variables, BURN_BUNDLE_LAYOUT_DIRECTORY, pEngineState->command.wzLayoutDirectory, FALSE);
541 + hr = VariableSetString(&pEngineState->variables, BURN_BUNDLE_LAYOUT_DIRECTORY, pEngineState->command.wzLayoutDirectory, FALSE, FALSE);
542 ExitOnFailure(hr, "Failed to set layout directory variable to value provided from command-line.");
543 }
544
src/engine/exeengine.cpp
+3 -3
@@ -399,7 +399,7 @@ extern "C" HRESULT ExeEngineExecutePackage(
399 ExitOnFailure(hr, "Failed to get cached path for package: %ls", pExecuteAction->exePackage.pPackage->sczId);
400
401 // Best effort to set the execute package cache folder and action variables.
402 - VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE);
402 + VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE, FALSE);
403 VariableSetNumeric(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_ACTION, pExecuteAction->exePackage.action, TRUE);
404
405 hr = PathConcat(sczCachedDirectory, pExecuteAction->exePackage.pPackage->rgPayloads[0].pPayload->sczFilePath, &sczExecutablePath);
@@ -591,8 +591,8 @@ LExit:
591 ReleaseFileHandle(hExecutableFile);
592
593 // Best effort to clear the execute package cache folder and action variables.
594 - VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, NULL, TRUE);
595 - VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_ACTION, NULL, TRUE);
594 + VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, NULL, TRUE, FALSE);
595 + VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_ACTION, NULL, TRUE, FALSE);
596
597 return hr;
598 }
src/engine/logging.cpp
+2 -2
@@ -149,7 +149,7 @@ extern "C" HRESULT LoggingOpen(
149
150 if (pLog->sczPathVariable && *pLog->sczPathVariable)
151 {
152 - VariableSetString(pVariables, pLog->sczPathVariable, pLog->sczPath, FALSE); // Ignore failure.
152 + VariableSetString(pVariables, pLog->sczPathVariable, pLog->sczPath, FALSE, FALSE); // Ignore failure.
153 }
154 }
155
@@ -220,7 +220,7 @@ extern "C" HRESULT LoggingSetPackageVariable(
220 hr = StrAllocFormatted(&sczLogPath, L"%ls%hs%ls_%03u_%ls%ls.%ls", pLog->sczPrefix, wzSuffix && *wzSuffix ? "_" : "", wzSuffix && *wzSuffix ? wzSuffix : L"", vdwPackageSequence, pPackage->sczId, fRollback ? L"_rollback" : L"", pLog->sczExtension);
221 ExitOnFailure(hr, "Failed to allocate path for package log.");
222
223 - hr = VariableSetString(pVariables, fRollback ? pPackage->sczRollbackLogPathVariable : pPackage->sczLogPathVariable, sczLogPath, FALSE);
223 + hr = VariableSetString(pVariables, fRollback ? pPackage->sczRollbackLogPathVariable : pPackage->sczLogPathVariable, sczLogPath, FALSE, FALSE);
224 ExitOnFailure(hr, "Failed to set log path into variable.");
225
226 if (psczLogPath)
src/engine/msiengine.cpp
+3 -3
@@ -1156,7 +1156,7 @@ extern "C" HRESULT MsiEngineExecutePackage(
1156 ExitOnFailure(hr, "Failed to get cached path for package: %ls", pExecuteAction->msiPackage.pPackage->sczId);
1157
1158 // Best effort to set the execute package cache folder variable.
1159 - VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE);
1159 + VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE, FALSE);
1160
1161 hr = PathConcat(sczCachedDirectory, pExecuteAction->msiPackage.pPackage->rgPayloads[0].pPayload->sczFilePath, &sczMsiPath);
1162 ExitOnFailure(hr, "Failed to build MSI path.");
@@ -1313,8 +1313,8 @@ LExit:
1313 }
1314
1315 // Best effort to clear the execute package cache folder and action variables.
1316 - VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, NULL, TRUE);
1317 - VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_ACTION, NULL, TRUE);
1316 + VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, NULL, TRUE, FALSE);
1317 + VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_ACTION, NULL, TRUE, FALSE);
1318
1319 return hr;
1320 }
src/engine/mspengine.cpp
+3 -3
@@ -488,7 +488,7 @@ extern "C" HRESULT MspEngineExecutePackage(
488
489 // TODO: Figure out if this makes sense -- the variable is set to the last patch's path only
490 // Best effort to set the execute package cache folder variable.
491 - VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE);
491 + VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE, FALSE);
492
493 hr = PathConcat(sczCachedDirectory, pMspPackage->rgPayloads[0].pPayload->sczFilePath, &sczMspPath);
494 ExitOnFailure(hr, "Failed to build MSP path.");
@@ -609,8 +609,8 @@ LExit:
609 }
610
611 // Best effort to clear the execute package cache folder and action variables.
612 - VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, NULL, TRUE);
613 - VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_ACTION, NULL, TRUE);
612 + VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, NULL, TRUE, FALSE);
613 + VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_ACTION, NULL, TRUE, FALSE);
614
615 return hr;
616 }
src/engine/msuengine.cpp
+2 -2
@@ -310,7 +310,7 @@ extern "C" HRESULT MsuEngineExecutePackage(
310 ExitOnFailure(hr, "Failed to get cached path for package: %ls", pExecuteAction->msuPackage.pPackage->sczId);
311
312 // Best effort to set the execute package cache folder variable.
313 - VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE);
313 + VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, sczCachedDirectory, TRUE, FALSE);
314
315 hr = PathConcat(sczCachedDirectory, pExecuteAction->msuPackage.pPackage->rgPayloads[0].pPayload->sczFilePath, &sczMsuPath);
316 ExitOnFailure(hr, "Failed to build MSU path.");
@@ -419,7 +419,7 @@ LExit:
419 }
420
421 // Best effort to clear the execute package cache folder variable.
422 - VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, NULL, TRUE);
422 + VariableSetString(pVariables, BURN_BUNDLE_EXECUTE_PACKAGE_CACHE_FOLDER, NULL, TRUE, FALSE);
423
424 return hr;
425 }
src/engine/registration.cpp
+5 -5
@@ -426,14 +426,14 @@ extern "C" HRESULT RegistrationSetVariables(
426
427 if (pRegistration->sczActiveParent && *pRegistration->sczActiveParent)
428 {
429 - hr = VariableSetString(pVariables, BURN_BUNDLE_ACTIVE_PARENT, pRegistration->sczActiveParent, TRUE);
429 + hr = VariableSetString(pVariables, BURN_BUNDLE_ACTIVE_PARENT, pRegistration->sczActiveParent, TRUE, FALSE);
430 ExitOnFailure(hr, "Failed to overwrite the bundle active parent built-in variable.");
431 }
432
433 - hr = VariableSetString(pVariables, BURN_BUNDLE_PROVIDER_KEY, pRegistration->sczProviderKey, TRUE);
433 + hr = VariableSetString(pVariables, BURN_BUNDLE_PROVIDER_KEY, pRegistration->sczProviderKey, TRUE, FALSE);
434 ExitOnFailure(hr, "Failed to overwrite the bundle provider key built-in variable.");
435
436 - hr = VariableSetString(pVariables, BURN_BUNDLE_TAG, pRegistration->sczTag, TRUE);
436 + hr = VariableSetString(pVariables, BURN_BUNDLE_TAG, pRegistration->sczTag, TRUE, FALSE);
437 ExitOnFailure(hr, "Failed to overwrite the bundle tag built-in variable.");
438
439 hr = VariableSetVersion(pVariables, BURN_BUNDLE_VERSION, pRegistration->qwVersion, TRUE);
@@ -1129,7 +1129,7 @@ static HRESULT GetBundleManufacturer(
1129 hr = VariableGetString(pVariables, BURN_BUNDLE_MANUFACTURER, psczBundleManufacturer);
1130 if (E_NOTFOUND == hr)
1131 {
1132 - hr = VariableSetLiteralString(pVariables, BURN_BUNDLE_MANUFACTURER, pRegistration->sczPublisher, FALSE);
1132 + hr = VariableSetString(pVariables, BURN_BUNDLE_MANUFACTURER, pRegistration->sczPublisher, FALSE, FALSE);
1133 ExitOnFailure(hr, "Failed to set bundle manufacturer.");
1134
1135 hr = StrAllocString(psczBundleManufacturer, pRegistration->sczPublisher, 0);
@@ -1151,7 +1151,7 @@ static HRESULT GetBundleName(
1151 hr = VariableGetString(pVariables, BURN_BUNDLE_NAME, psczBundleName);
1152 if (E_NOTFOUND == hr)
1153 {
1154 - hr = VariableSetLiteralString(pVariables, BURN_BUNDLE_NAME, pRegistration->sczDisplayName, FALSE);
1154 + hr = VariableSetString(pVariables, BURN_BUNDLE_NAME, pRegistration->sczDisplayName, FALSE, FALSE);
1155 ExitOnFailure(hr, "Failed to set bundle name.");
1156
1157 hr = StrAllocString(psczBundleName, pRegistration->sczDisplayName, 0);
src/engine/search.cpp
+22 -14
@@ -239,7 +239,11 @@ extern "C" HRESULT SearchesParseFromXml(
239 hr = XmlGetAttributeEx(pixnNode, L"VariableType", &scz);
240 ExitOnFailure(hr, "Failed to get @VariableType.");
241
242 - if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"numeric", -1))
242 + if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"formatted", -1))
243 + {
244 + pSearch->RegistrySearch.VariableType = BURN_VARIANT_TYPE_FORMATTED;
245 + }
246 + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"numeric", -1))
247 {
248 pSearch->RegistrySearch.VariableType = BURN_VARIANT_TYPE_NUMERIC;
249 }
@@ -403,14 +407,18 @@ extern "C" HRESULT SearchesParseFromXml(
407 {
408 ExitOnFailure(hr, "Failed to get @Value.");
409
406 - hr = BVariantSetString(&pSearch->SetVariable.value, scz, 0);
410 + hr = BVariantSetString(&pSearch->SetVariable.value, scz, 0, FALSE);
411 ExitOnFailure(hr, "Failed to set variant value.");
412
413 // @Type
414 hr = XmlGetAttributeEx(pixnNode, L"Type", &scz);
415 ExitOnFailure(hr, "Failed to get @Type.");
416
413 - if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"numeric", -1))
417 + if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"formatted", -1))
418 + {
419 + valueType = BURN_VARIANT_TYPE_FORMATTED;
420 + }
421 + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"numeric", -1))
422 {
423 valueType = BURN_VARIANT_TYPE_NUMERIC;
424 }
@@ -673,7 +681,7 @@ static HRESULT DirectorySearchPath(
681 }
682 else if (dwAttributes & FILE_ATTRIBUTE_DIRECTORY)
683 {
676 - hr = VariableSetLiteralString(pVariables, pSearch->sczVariable, sczPath, FALSE);
684 + hr = VariableSetString(pVariables, pSearch->sczVariable, sczPath, FALSE, FALSE);
685 ExitOnFailure(hr, "Failed to set directory search path variable.");
686 }
687 else // must have found a file.
@@ -793,7 +801,7 @@ static HRESULT FileSearchPath(
801 }
802 else // found our file.
803 {
796 - hr = VariableSetLiteralString(pVariables, pSearch->sczVariable, sczPath, FALSE);
804 + hr = VariableSetString(pVariables, pSearch->sczVariable, sczPath, FALSE, FALSE);
805 ExitOnFailure(hr, "Failed to set variable to file search path.");
806 }
807
@@ -933,7 +941,7 @@ static HRESULT RegistrySearchValue(
941 {
942 // What if there is a hidden variable in sczKey?
943 LogStringLine(REPORT_STANDARD, "Registry key not found. Key = '%ls'", sczKey);
936 - hr = VariableSetLiteralVariant(pVariables, pSearch->sczVariable, &value);
944 + hr = VariableSetVariant(pVariables, pSearch->sczVariable, &value);
945 ExitOnFailure(hr, "Failed to clear variable.");
946 ExitFunction1(hr = S_OK);
947 }
@@ -945,7 +953,7 @@ static HRESULT RegistrySearchValue(
953 {
954 // What if there is a hidden variable in sczKey or sczValue?
955 LogStringLine(REPORT_STANDARD, "Registry value not found. Key = '%ls', Value = '%ls'", sczKey, sczValue);
948 - hr = VariableSetLiteralVariant(pVariables, pSearch->sczVariable, &value);
956 + hr = VariableSetVariant(pVariables, pSearch->sczVariable, &value);
957 ExitOnFailure(hr, "Failed to clear variable.");
958 ExitFunction1(hr = S_OK);
959 }
@@ -995,7 +1003,7 @@ static HRESULT RegistrySearchValue(
1003 }
1004 __fallthrough;
1005 case REG_SZ:
998 - hr = BVariantSetString(&value, (LPCWSTR)pData, 0);
1006 + hr = BVariantSetString(&value, (LPCWSTR)pData, 0, FALSE);
1007 break;
1008 default:
1009 ExitOnFailure(hr = E_NOTIMPL, "Unsupported registry key value type. Type = '%u'", dwType);
@@ -1006,8 +1014,8 @@ static HRESULT RegistrySearchValue(
1014 hr = BVariantChangeType(&value, pSearch->RegistrySearch.VariableType);
1015 ExitOnFailure(hr, "Failed to change value type.");
1016
1009 - // Set variable as a literal.
1010 - hr = VariableSetLiteralVariant(pVariables, pSearch->sczVariable, &value);
1017 + // Set variable.
1018 + hr = VariableSetVariant(pVariables, pSearch->sczVariable, &value);
1019 ExitOnFailure(hr, "Failed to set variable.");
1020
1021 LExit:
@@ -1077,7 +1085,7 @@ static HRESULT MsiComponentSearch(
1085 case BURN_MSI_COMPONENT_SEARCH_TYPE_KEYPATH:
1086 if (INSTALLSTATE_ABSENT == is || INSTALLSTATE_LOCAL == is || INSTALLSTATE_SOURCE == is)
1087 {
1080 - hr = VariableSetLiteralString(pVariables, pSearch->sczVariable, sczPath, FALSE);
1088 + hr = VariableSetString(pVariables, pSearch->sczVariable, sczPath, FALSE, FALSE);
1089 }
1090 break;
1091 case BURN_MSI_COMPONENT_SEARCH_TYPE_STATE:
@@ -1093,7 +1101,7 @@ static HRESULT MsiComponentSearch(
1101 wz[1] = L'\0';
1102 }
1103
1096 - hr = VariableSetLiteralString(pVariables, pSearch->sczVariable, sczPath, FALSE);
1104 + hr = VariableSetString(pVariables, pSearch->sczVariable, sczPath, FALSE, FALSE);
1105 }
1106 break;
1107 }
@@ -1234,8 +1242,8 @@ static HRESULT MsiProductSearch(
1242 hr = BVariantChangeType(&value, type);
1243 ExitOnFailure(hr, "Failed to change value type.");
1244
1237 - // Set variable as a literal.
1238 - hr = VariableSetLiteralVariant(pVariables, pSearch->sczVariable, &value);
1245 + // Set variable.
1246 + hr = VariableSetVariant(pVariables, pSearch->sczVariable, &value);
1247 ExitOnFailure(hr, "Failed to set variable.");
1248
1249 LExit:
src/engine/variable.cpp
+36 -66
@@ -83,7 +83,6 @@ static HRESULT SetVariableValue(
83 __in BURN_VARIABLES* pVariables,
84 __in_z LPCWSTR wzVariable,
85 __in BURN_VARIANT* pVariant,
86 - __in BOOL fLiteral,
86 __in SET_VARIABLE setBuiltin,
87 __in BOOL fLog
88 );
@@ -335,14 +334,22 @@ extern "C" HRESULT VariablesParseFromXml(
334 {
335 ExitOnFailure(hr, "Failed to get @Value.");
336
338 - hr = BVariantSetString(&value, scz, 0);
337 + hr = BVariantSetString(&value, scz, 0, FALSE);
338 ExitOnFailure(hr, "Failed to set variant value.");
339
340 // @Type
341 hr = XmlGetAttributeEx(pixnNode, L"Type", &scz);
342 ExitOnFailure(hr, "Failed to get @Type.");
343
345 - if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"numeric", -1))
344 + if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"formatted", -1))
345 + {
346 + if (!fHidden)
347 + {
348 + LogStringLine(REPORT_STANDARD, "Initializing formatted variable '%ls' to value '%ls'", sczId, value.sczValue);
349 + }
350 + valueType = BURN_VARIANT_TYPE_FORMATTED;
351 + }
352 + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"numeric", -1))
353 {
354 if (!fHidden)
355 {
@@ -637,10 +644,7 @@ extern "C" HRESULT VariableGetFormatted(
644 }
645 ExitOnFailure(hr, "Failed to get variable: %ls", wzVariable);
646
640 - // Strings need to get expanded unless they're built-in or literal because they're guaranteed not to have embedded variables.
641 - if (BURN_VARIANT_TYPE_STRING == pVariable->Value.Type &&
642 - BURN_VARIABLE_INTERNAL_TYPE_NORMAL == pVariable->internalType &&
643 - !pVariable->fLiteral)
647 + if (BURN_VARIANT_TYPE_FORMATTED == pVariable->Value.Type)
648 {
649 hr = BVariantGetString(&pVariable->Value, &scz);
650 ExitOnFailure(hr, "Failed to get unformatted string.");
@@ -674,39 +678,24 @@ extern "C" HRESULT VariableSetNumeric(
678 variant.llValue = llValue;
679 variant.Type = BURN_VARIANT_TYPE_NUMERIC;
680
677 - return SetVariableValue(pVariables, wzVariable, &variant, FALSE, fOverwriteBuiltIn ? SET_VARIABLE_OVERRIDE_BUILTIN : SET_VARIABLE_NOT_BUILTIN, TRUE);
678 -}
679 -
680 -extern "C" HRESULT VariableSetLiteralString(
681 - __in BURN_VARIABLES* pVariables,
682 - __in_z LPCWSTR wzVariable,
683 - __in_z_opt LPCWSTR wzValue,
684 - __in BOOL fOverwriteBuiltIn
685 - )
686 -{
687 - BURN_VARIANT variant = { };
688 -
689 - // We're not going to encrypt this value, so can access the value directly.
690 - variant.sczValue = (LPWSTR)wzValue;
691 - variant.Type = BURN_VARIANT_TYPE_STRING;
692 -
693 - return SetVariableValue(pVariables, wzVariable, &variant, TRUE, fOverwriteBuiltIn ? SET_VARIABLE_OVERRIDE_BUILTIN : SET_VARIABLE_NOT_BUILTIN, TRUE);
681 + return SetVariableValue(pVariables, wzVariable, &variant, fOverwriteBuiltIn ? SET_VARIABLE_OVERRIDE_BUILTIN : SET_VARIABLE_NOT_BUILTIN, TRUE);
682 }
683
684 extern "C" HRESULT VariableSetString(
685 __in BURN_VARIABLES* pVariables,
686 __in_z LPCWSTR wzVariable,
687 __in_z_opt LPCWSTR wzValue,
700 - __in BOOL fOverwriteBuiltIn
688 + __in BOOL fOverwriteBuiltIn,
689 + __in BOOL fFormatted
690 )
691 {
692 BURN_VARIANT variant = { };
693
694 // We're not going to encrypt this value, so can access the value directly.
695 variant.sczValue = (LPWSTR)wzValue;
707 - variant.Type = BURN_VARIANT_TYPE_STRING;
696 + variant.Type = fFormatted ? BURN_VARIANT_TYPE_FORMATTED : BURN_VARIANT_TYPE_STRING;
697
709 - return SetVariableValue(pVariables, wzVariable, &variant, FALSE, fOverwriteBuiltIn ? SET_VARIABLE_OVERRIDE_BUILTIN : SET_VARIABLE_NOT_BUILTIN, TRUE);
698 + return SetVariableValue(pVariables, wzVariable, &variant, fOverwriteBuiltIn ? SET_VARIABLE_OVERRIDE_BUILTIN : SET_VARIABLE_NOT_BUILTIN, TRUE);
699 }
700
701 extern "C" HRESULT VariableSetVersion(
@@ -722,16 +711,7 @@ extern "C" HRESULT VariableSetVersion(
711 variant.qwValue = qwValue;
712 variant.Type = BURN_VARIANT_TYPE_VERSION;
713
725 - return SetVariableValue(pVariables, wzVariable, &variant, FALSE, fOverwriteBuiltIn ? SET_VARIABLE_OVERRIDE_BUILTIN : SET_VARIABLE_NOT_BUILTIN, TRUE);
726 -}
727 -
728 -extern "C" HRESULT VariableSetLiteralVariant(
729 - __in BURN_VARIABLES* pVariables,
730 - __in_z LPCWSTR wzVariable,
731 - __in BURN_VARIANT* pVariant
732 - )
733 -{
734 - return SetVariableValue(pVariables, wzVariable, pVariant, TRUE, SET_VARIABLE_NOT_BUILTIN, TRUE);
714 + return SetVariableValue(pVariables, wzVariable, &variant, fOverwriteBuiltIn ? SET_VARIABLE_OVERRIDE_BUILTIN : SET_VARIABLE_NOT_BUILTIN, TRUE);
715 }
716
717 extern "C" HRESULT VariableSetVariant(
@@ -740,7 +720,7 @@ extern "C" HRESULT VariableSetVariant(
720 __in BURN_VARIANT * pVariant
721 )
722 {
743 - return SetVariableValue(pVariables, wzVariable, pVariant, FALSE, SET_VARIABLE_NOT_BUILTIN, TRUE);
723 + return SetVariableValue(pVariables, wzVariable, pVariant, SET_VARIABLE_NOT_BUILTIN, TRUE);
724 }
725
726 // The contents of psczOut may be sensitive, should keep encrypted and SecureZeroFree
@@ -888,6 +868,7 @@ extern "C" HRESULT VariableSerialize(
868
869 SecureZeroMemory(&qw, sizeof(qw));
870 break;
871 + case BURN_VARIANT_TYPE_FORMATTED: __fallthrough;
872 case BURN_VARIANT_TYPE_STRING:
873 hr = BVariantGetString(&pVariable->Value, &scz);
874 ExitOnFailure(hr, "Failed to get string.");
@@ -901,10 +882,6 @@ extern "C" HRESULT VariableSerialize(
882 hr = E_INVALIDARG;
883 ExitOnFailure(hr, "Unsupported variable type.");
884 }
904 -
905 - // Write literal flag.
906 - hr = BuffWriteNumber(ppbBuffer, piBuffer, (DWORD)pVariable->fLiteral);
907 - ExitOnFailure(hr, "Failed to write literal flag.");
885 }
886
887 LExit:
@@ -928,7 +905,6 @@ extern "C" HRESULT VariableDeserialize(
905 DWORD cVariables = 0;
906 LPWSTR sczName = NULL;
907 BOOL fIncluded = FALSE;
931 - BOOL fLiteral = FALSE;
908 BURN_VARIANT value = { };
909 LPWSTR scz = NULL;
910 DWORD64 qw = 0;
@@ -982,11 +958,12 @@ extern "C" HRESULT VariableDeserialize(
958
959 SecureZeroMemory(&qw, sizeof(qw));
960 break;
961 + case BURN_VARIANT_TYPE_FORMATTED: __fallthrough;
962 case BURN_VARIANT_TYPE_STRING:
963 hr = BuffReadString(pbBuffer, cbBuffer, piBuffer, &scz);
964 ExitOnFailure(hr, "Failed to read variable value as string.");
965
989 - hr = BVariantSetString(&value, scz, NULL);
966 + hr = BVariantSetString(&value, scz, NULL, BURN_VARIANT_TYPE_FORMATTED == value.Type);
967 ExitOnFailure(hr, "Failed to set variable value.");
968
969 ReleaseNullStrSecure(scz);
@@ -996,12 +973,8 @@ extern "C" HRESULT VariableDeserialize(
973 ExitOnFailure(hr, "Unsupported variable type.");
974 }
975
999 - // Read variable literal flag.
1000 - hr = BuffReadNumber(pbBuffer, cbBuffer, piBuffer, (DWORD*)&fLiteral);
1001 - ExitOnFailure(hr, "Failed to read variable literal flag.");
1002 -
976 // Set variable.
1004 - hr = SetVariableValue(pVariables, sczName, &value, fLiteral, fWasPersisted ? SET_VARIABLE_OVERRIDE_PERSISTED_BUILTINS : SET_VARIABLE_ANY, FALSE);
977 + hr = SetVariableValue(pVariables, sczName, &value, fWasPersisted ? SET_VARIABLE_OVERRIDE_PERSISTED_BUILTINS : SET_VARIABLE_ANY, FALSE);
978 ExitOnFailure(hr, "Failed to set variable.");
979
980 // Clean up.
@@ -1525,7 +1498,6 @@ static HRESULT SetVariableValue(
1498 __in BURN_VARIABLES* pVariables,
1499 __in_z LPCWSTR wzVariable,
1500 __in BURN_VARIANT* pVariant,
1528 - __in BOOL fLiteral,
1501 __in SET_VARIABLE setBuiltin,
1502 __in BOOL fLog
1503 )
@@ -1587,6 +1559,7 @@ static HRESULT SetVariableValue(
1559 LogStringLine(REPORT_STANDARD, "Setting numeric variable '%ls' to value %lld", wzVariable, pVariant->llValue);
1560 break;
1561
1562 + case BURN_VARIANT_TYPE_FORMATTED: __fallthrough;
1563 case BURN_VARIANT_TYPE_STRING:
1564 if (!pVariant->sczValue)
1565 {
@@ -1594,7 +1567,7 @@ static HRESULT SetVariableValue(
1567 }
1568 else
1569 {
1597 - LogStringLine(REPORT_STANDARD, "Setting string variable '%ls' to value '%ls'", wzVariable, pVariant->sczValue);
1570 + LogStringLine(REPORT_STANDARD, "Setting %ls variable '%ls' to value '%ls'", BURN_VARIANT_TYPE_FORMATTED == pVariant->Type ? L"formatted" : L"string", wzVariable, pVariant->sczValue);
1571 }
1572 break;
1573
@@ -1613,9 +1586,6 @@ static HRESULT SetVariableValue(
1586 hr = BVariantSetValue(&pVariables->rgVariables[iVariable].Value, pVariant);
1587 ExitOnFailure(hr, "Failed to set value of variable: %ls", wzVariable);
1588
1616 - // Update variable literal flag.
1617 - pVariables->rgVariables[iVariable].fLiteral = fLiteral;
1618 -
1589 LExit:
1590 ::LeaveCriticalSection(&pVariables->csAccess);
1591
@@ -1827,7 +1797,7 @@ static HRESULT InitializeVariableComputerName(
1797 }
1798
1799 // set value
1830 - hr = BVariantSetString(pValue, wzComputerName, 0);
1800 + hr = BVariantSetString(pValue, wzComputerName, 0, FALSE);
1801 ExitOnFailure(hr, "Failed to set variant value.");
1802
1803 LExit:
@@ -1875,7 +1845,7 @@ static HRESULT InitializeVariableCsidlFolder(
1845 ExitOnRootFailure(hr, "Failed to get shell folder.");
1846
1847 // set value
1878 - hr = BVariantSetString(pValue, sczPath, 0);
1848 + hr = BVariantSetString(pValue, sczPath, 0, FALSE);
1849 ExitOnFailure(hr, "Failed to set variant value.");
1850
1851 LExit:
@@ -1901,7 +1871,7 @@ static HRESULT InitializeVariableTempFolder(
1871 }
1872
1873 // set value
1904 - hr = BVariantSetString(pValue, wzPath, 0);
1874 + hr = BVariantSetString(pValue, wzPath, 0, FALSE);
1875 ExitOnFailure(hr, "Failed to set variant value.");
1876
1877 LExit:
@@ -1972,7 +1942,7 @@ static HRESULT InitializeVariableSystemFolder(
1942 }
1943
1944 // set value
1975 - hr = BVariantSetString(pValue, wzSystemFolder, 0);
1945 + hr = BVariantSetString(pValue, wzSystemFolder, 0, FALSE);
1946 ExitOnFailure(hr, "Failed to set system folder variant value.");
1947
1948 LExit:
@@ -2003,7 +1973,7 @@ static HRESULT InitializeVariableWindowsVolumeFolder(
1973 }
1974
1975 // set value
2006 - hr = BVariantSetString(pValue, wzVolumePath, 0);
1976 + hr = BVariantSetString(pValue, wzVolumePath, 0, FALSE);
1977 ExitOnFailure(hr, "Failed to set variant value.");
1978
1979 LExit:
@@ -2130,7 +2100,7 @@ static HRESULT InitializeVariableString(
2100 LPCWSTR wzValue = (LPCWSTR)dwpData;
2101
2102 // set value
2133 - hr = BVariantSetString(pValue, wzValue, 0);
2103 + hr = BVariantSetString(pValue, wzValue, 0, FALSE);
2104 ExitOnFailure(hr, "Failed to set variant value.");
2105
2106 LExit:
@@ -2176,7 +2146,7 @@ static HRESULT InitializeVariableRegistryFolder(
2146 ExitOnFailure(hr, "Failed to get 64-bit folder.");
2147
2148 // set value
2179 - hr = BVariantSetString(pValue, sczPath, 0);
2149 + hr = BVariantSetString(pValue, sczPath, 0, FALSE);
2150 ExitOnFailure(hr, "Failed to set variant value.");
2151
2152 LExit:
@@ -2212,7 +2182,7 @@ static HRESULT InitializeVariable6432Folder(
2182 }
2183
2184 // set value
2215 - hr = BVariantSetString(pValue, sczPath, 0);
2185 + hr = BVariantSetString(pValue, sczPath, 0, FALSE);
2186 ExitOnFailure(hr, "Failed to set variant value.");
2187
2188 LExit:
@@ -2249,7 +2219,7 @@ static HRESULT InitializeVariableDate(
2219 }
2220
2221 // set value
2252 - hr = BVariantSetString(pValue, sczDate, cchDate);
2222 + hr = BVariantSetString(pValue, sczDate, cchDate, FALSE);
2223 ExitOnFailure(hr, "Failed to set variant value.");
2224
2225 LExit:
@@ -2266,7 +2236,7 @@ static HRESULT InitializeVariableInstallerName(
2236 HRESULT hr = S_OK;
2237
2238 // set value
2269 - hr = BVariantSetString(pValue, L"WiX Burn", 0);
2239 + hr = BVariantSetString(pValue, L"WiX Burn", 0, FALSE);
2240 ExitOnFailure(hr, "Failed to set variant value.");
2241
2242 LExit:
@@ -2285,7 +2255,7 @@ static HRESULT InitializeVariableInstallerVersion(
2255 ExitOnFailure(hr, "Failed to copy the engine version.");
2256
2257 // set value
2288 - hr = BVariantSetString(pValue, sczVersion, 0);
2258 + hr = BVariantSetString(pValue, sczVersion, 0, FALSE);
2259 ExitOnFailure(hr, "Failed to set variant value.");
2260
2261 LExit:
@@ -2325,7 +2295,7 @@ static HRESULT InitializeVariableLogonUser(
2295 }
2296
2297 // set value
2328 - hr = BVariantSetString(pValue, wzUserName, 0);
2298 + hr = BVariantSetString(pValue, wzUserName, 0, FALSE);
2299 ExitOnFailure(hr, "Failed to set variant value.");
2300
2301 LExit:
src/engine/variable.h
+3 -14
@@ -39,8 +39,7 @@ typedef struct _BURN_VARIABLE
39 {
40 LPWSTR sczName;
41 BURN_VARIANT Value;
42 - BOOL fHidden;
43 - BOOL fLiteral; // if fLiteral, then when formatting this variable its value should be used as is (don't continue recursively formatting).
42 + BOOL fHidden;
43 BOOL fPersisted;
44
45 // used for late initialization of built-in variables
@@ -104,17 +103,12 @@ HRESULT VariableSetNumeric(
103 __in LONGLONG llValue,
104 __in BOOL fOverwriteBuiltIn
105 );
107 -HRESULT VariableSetLiteralString(
108 - __in BURN_VARIABLES* pVariables,
109 - __in_z LPCWSTR wzVariable,
110 - __in_z_opt LPCWSTR wzValue,
111 - __in BOOL fOverwriteBuiltIn
112 - );
106 HRESULT VariableSetString(
107 __in BURN_VARIABLES* pVariables,
108 __in_z LPCWSTR wzVariable,
109 __in_z_opt LPCWSTR wzValue,
117 - __in BOOL fOverwriteBuiltIn
110 + __in BOOL fOverwriteBuiltIn,
111 + __in BOOL fFormatted
112 );
113 HRESULT VariableSetVersion(
114 __in BURN_VARIABLES* pVariables,
@@ -122,11 +116,6 @@ HRESULT VariableSetVersion(
116 __in DWORD64 qwValue,
117 __in BOOL fOverwriteBuiltIn
118 );
125 -HRESULT VariableSetLiteralVariant(
126 - __in BURN_VARIABLES* pVariables,
127 - __in_z LPCWSTR wzVariable,
128 - __in BURN_VARIANT* pVariant
129 - );
119 HRESULT VariableSetVariant(
120 __in BURN_VARIABLES* pVariables,
121 __in_z LPCWSTR wzVariable,
src/engine/variant.cpp
+26 -8
@@ -32,7 +32,8 @@ extern "C" void BVariantUninitialize(
32 __in BURN_VARIANT* pVariant
33 )
34 {
35 - if (BURN_VARIANT_TYPE_STRING == pVariant->Type)
35 + if (BURN_VARIANT_TYPE_FORMATTED == pVariant->Type ||
36 + BURN_VARIANT_TYPE_STRING == pVariant->Type)
37 {
38 StrSecureZeroFreeString(pVariant->sczValue);
39 }
@@ -53,6 +54,7 @@ extern "C" HRESULT BVariantGetNumeric(
54 case BURN_VARIANT_TYPE_NUMERIC:
55 BVariantRetrieveNumeric(pVariant, pllValue);
56 break;
57 + case BURN_VARIANT_TYPE_FORMATTED: __fallthrough;
58 case BURN_VARIANT_TYPE_STRING:
59 hr = BVariantRetrieveDecryptedString(pVariant, &sczValue);
60 if (SUCCEEDED(hr))
@@ -97,6 +99,7 @@ extern "C" HRESULT BVariantGetString(
99 }
100 SecureZeroMemory(&llValue, sizeof(llValue));
101 break;
102 + case BURN_VARIANT_TYPE_FORMATTED: __fallthrough;
103 case BURN_VARIANT_TYPE_STRING:
104 hr = BVariantRetrieveDecryptedString(pVariant, psczValue);
105 break;
@@ -136,6 +139,7 @@ extern "C" HRESULT BVariantGetVersion(
139 case BURN_VARIANT_TYPE_NUMERIC:
140 BVariantRetrieveNumeric(pVariant, (LONGLONG*)pqwValue);
141 break;
142 + case BURN_VARIANT_TYPE_FORMATTED: __fallthrough;
143 case BURN_VARIANT_TYPE_STRING:
144 hr = BVariantRetrieveDecryptedString(pVariant, &sczValue);
145 if (SUCCEEDED(hr))
@@ -167,7 +171,8 @@ extern "C" HRESULT BVariantSetNumeric(
171 HRESULT hr = S_OK;
172 BOOL fEncrypt = pVariant->fEncryptString;
173
170 - if (BURN_VARIANT_TYPE_STRING == pVariant->Type)
174 + if (BURN_VARIANT_TYPE_FORMATTED == pVariant->Type ||
175 + BURN_VARIANT_TYPE_STRING == pVariant->Type)
176 {
177 StrSecureZeroFreeString(pVariant->sczValue);
178 }
@@ -182,7 +187,8 @@ extern "C" HRESULT BVariantSetNumeric(
187 extern "C" HRESULT BVariantSetString(
188 __in BURN_VARIANT* pVariant,
189 __in_z_opt LPCWSTR wzValue,
185 - __in DWORD_PTR cchValue
190 + __in DWORD_PTR cchValue,
191 + __in BOOL fFormatted
192 )
193 {
194 HRESULT hr = S_OK;
@@ -194,7 +200,8 @@ extern "C" HRESULT BVariantSetString(
200 }
201 else // assign the value.
202 {
197 - if (BURN_VARIANT_TYPE_STRING != pVariant->Type)
203 + if (BURN_VARIANT_TYPE_FORMATTED != pVariant->Type &&
204 + BURN_VARIANT_TYPE_STRING != pVariant->Type)
205 {
206 memset(pVariant, 0, sizeof(BURN_VARIANT));
207 }
@@ -207,7 +214,7 @@ extern "C" HRESULT BVariantSetString(
214 hr = StrAllocStringSecure(&pVariant->sczValue, wzValue, cchValue);
215 ExitOnFailure(hr, "Failed to copy string.");
216
210 - pVariant->Type = BURN_VARIANT_TYPE_STRING;
217 + pVariant->Type = fFormatted ? BURN_VARIANT_TYPE_FORMATTED : BURN_VARIANT_TYPE_STRING;
218 }
219
220 LExit:
@@ -223,7 +230,8 @@ extern "C" HRESULT BVariantSetVersion(
230 HRESULT hr = S_OK;
231 BOOL fEncryptValue = pVariant->fEncryptString;
232
226 - if (BURN_VARIANT_TYPE_STRING == pVariant->Type)
233 + if (BURN_VARIANT_TYPE_FORMATTED == pVariant->Type ||
234 + BURN_VARIANT_TYPE_STRING == pVariant->Type)
235 {
236 StrSecureZeroFreeString(pVariant->sczValue);
237 }
@@ -259,11 +267,12 @@ extern "C" HRESULT BVariantSetValue(
267 }
268 SecureZeroMemory(&llValue, sizeof(llValue));
269 break;
270 + case BURN_VARIANT_TYPE_FORMATTED: __fallthrough;
271 case BURN_VARIANT_TYPE_STRING:
272 hr = BVariantGetString(pValue, &sczValue);
273 if (SUCCEEDED(hr))
274 {
266 - hr = BVariantSetString(pVariant, sczValue, 0);
275 + hr = BVariantSetString(pVariant, sczValue, 0, BURN_VARIANT_TYPE_FORMATTED == pValue->Type);
276 }
277 StrSecureZeroFreeString(sczValue);
278 break;
@@ -310,11 +319,12 @@ extern "C" HRESULT BVariantCopy(
319 }
320 SecureZeroMemory(&llValue, sizeof(llValue));
321 break;
322 + case BURN_VARIANT_TYPE_FORMATTED: __fallthrough;
323 case BURN_VARIANT_TYPE_STRING:
324 hr = BVariantGetString(pSource, &sczValue);
325 if (SUCCEEDED(hr))
326 {
317 - hr = BVariantSetString(pTarget, sczValue, 0);
327 + hr = BVariantSetString(pTarget, sczValue, 0, BURN_VARIANT_TYPE_FORMATTED == pSource->Type);
328 }
329 StrSecureZeroFreeString(sczValue);
330 break;
@@ -350,6 +360,12 @@ extern "C" HRESULT BVariantChangeType(
360 {
361 ExitFunction(); // variant already is of the requested type
362 }
363 + else if (BURN_VARIANT_TYPE_FORMATTED == pVariant->Type && BURN_VARIANT_TYPE_STRING == type ||
364 + BURN_VARIANT_TYPE_STRING == pVariant->Type && BURN_VARIANT_TYPE_FORMATTED == type)
365 + {
366 + pVariant->Type = type;
367 + ExitFunction();
368 + }
369
370 switch (type)
371 {
@@ -359,6 +375,7 @@ extern "C" HRESULT BVariantChangeType(
375 case BURN_VARIANT_TYPE_NUMERIC:
376 hr = BVariantGetNumeric(pVariant, &variant.llValue);
377 break;
378 + case BURN_VARIANT_TYPE_FORMATTED: __fallthrough;
379 case BURN_VARIANT_TYPE_STRING:
380 hr = BVariantGetString(pVariant, &variant.sczValue);
381 break;
@@ -400,6 +417,7 @@ extern "C" HRESULT BVariantSetEncryption(
417 case BURN_VARIANT_TYPE_VERSION:
418 hr = S_OK;
419 break;
420 + case BURN_VARIANT_TYPE_FORMATTED: __fallthrough;
421 case BURN_VARIANT_TYPE_STRING:
422 hr = BVariantEncryptString(pVariant, fEncrypt);
423 break;
src/engine/variant.h
+4 -2
@@ -12,8 +12,9 @@ extern "C" {
12 enum BURN_VARIANT_TYPE
13 {
14 BURN_VARIANT_TYPE_NONE,
15 + BURN_VARIANT_TYPE_FORMATTED,
16 BURN_VARIANT_TYPE_NUMERIC,
16 - BURN_VARIANT_TYPE_STRING,
17 + BURN_VARIANT_TYPE_STRING, // when formatting this value should be used as is (don't continue recursively formatting).
18 BURN_VARIANT_TYPE_VERSION,
19 };
20
@@ -57,7 +58,8 @@ HRESULT BVariantSetNumeric(
58 HRESULT BVariantSetString(
59 __in BURN_VARIANT* pVariant,
60 __in_z_opt LPCWSTR wzValue,
60 - __in DWORD_PTR cchValue
61 + __in DWORD_PTR cchValue,
62 + __in BOOL fFormatted
63 );
64 HRESULT BVariantSetVersion(
65 __in BURN_VARIANT* pVariant,
src/test/BurnUnitTest/SearchTest.cpp
+79 -8
@@ -66,8 +66,8 @@ namespace Bootstrapper
66 pin_ptr<const WCHAR> wzDirectory1 = PtrToStringChars(this->TestContext->TestDirectory);
67 pin_ptr<const WCHAR> wzDirectory2 = PtrToStringChars(System::IO::Path::Combine(this->TestContext->TestDirectory, gcnew String(L"none")));
68
69 - VariableSetStringHelper(&variables, L"Directory1", wzDirectory1);
70 - VariableSetStringHelper(&variables, L"Directory2", wzDirectory2);
69 + VariableSetStringHelper(&variables, L"Directory1", wzDirectory1, FALSE);
70 + VariableSetStringHelper(&variables, L"Directory2", wzDirectory2, FALSE);
71
72 LPCWSTR wzDocument =
73 L"<Bundle>"
@@ -117,8 +117,8 @@ namespace Bootstrapper
117 hr = FileVersion(wzFile2, &uliVersion.HighPart, &uliVersion.LowPart);
118 TestThrowOnFailure(hr, L"Failed to get DLL version.");
119
120 - VariableSetStringHelper(&variables, L"File1", wzFile1);
121 - VariableSetStringHelper(&variables, L"File2", wzFile2);
120 + VariableSetStringHelper(&variables, L"File1", wzFile1, FALSE);
121 + VariableSetStringHelper(&variables, L"File2", wzFile2, FALSE);
122
123 LPCWSTR wzDocument =
124 L"<Bundle>"
@@ -191,8 +191,8 @@ namespace Bootstrapper
191 Assert::True(SUCCEEDED(hr));
192 }
193
194 - VariableSetStringHelper(&variables, L"MyKey", L"SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value");
195 - VariableSetStringHelper(&variables, L"MyValue", L"String");
194 + VariableSetStringHelper(&variables, L"MyKey", L"SOFTWARE\\Microsoft\\WiX_Burn_UnitTest\\Value", FALSE);
195 + VariableSetStringHelper(&variables, L"MyValue", L"String", FALSE);
196
197 LPCWSTR wzDocument =
198 L"<Bundle>"
@@ -219,8 +219,9 @@ namespace Bootstrapper
219 L" <RegistrySearch Id='Search21' Type='value' Root='HKCU' Key='SOFTWARE\\Classes\\CLSID\\WiX_Burn_UnitTest\\Bitness' Value='TestStringSpecificToBitness' Variable='Variable21' VariableType='string' Win64='no' />"
220 L" <RegistrySearch Id='Search22' Type='value' Root='HKCU' Key='SOFTWARE\\Classes\\CLSID\\WiX_Burn_UnitTest\\Bitness' Value='TestStringSpecificToBitness' Variable='Variable22' VariableType='string' Win64='yes' />"
221 L" <RegistrySearch Id='Search23' Type='exists' Root='HKU' Key='.DEFAULT\\Environment' Variable='Variable23' />"
222 - L" <RegistrySearch Id='Search23' Type='exists' Root='HKU' Key='.DEFAULT\\System\\NetworkServiceSidSubkeyDoesNotExist' Variable='Variable24' />"
223 - L" <RegistrySearch Id='Search24' Type='value' Root='HKCR' Key='.msi' Variable='Variable25' VariableType='string' />"
222 + L" <RegistrySearch Id='Search24' Type='exists' Root='HKU' Key='.DEFAULT\\System\\NetworkServiceSidSubkeyDoesNotExist' Variable='Variable24' />"
223 + L" <RegistrySearch Id='Search25' Type='value' Root='HKCR' Key='.msi' Variable='Variable25' VariableType='string' />"
224 + L" <RegistrySearch Id='Search26' Type='value' Root='HKCR' Key='.msi' Variable='Variable26' VariableType='formatted' />"
225 L"</Bundle>";
226
227 // load XML document
@@ -263,6 +264,7 @@ namespace Bootstrapper
264 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Variable23"));
265 Assert::Equal(0ll, VariableGetNumericHelper(&variables, L"Variable24"));
266 Assert::Equal<String^>(gcnew String(L"Msi.Package"), VariableGetStringHelper(&variables, L"Variable25"));
267 + Assert::Equal<String^>(gcnew String(L"Msi.Package"), VariableGetStringHelper(&variables, L"Variable26"));
268 }
269 finally
270 {
@@ -525,6 +527,75 @@ namespace Bootstrapper
527 SearchesUninitialize(&searches);
528 }
529 }
530 +
531 + [Fact]
532 + void SetVariableSearchTest()
533 + {
534 + HRESULT hr = S_OK;
535 + IXMLDOMElement* pixeBundle = NULL;
536 + BURN_VARIABLES variables = { };
537 + BURN_SEARCHES searches = { };
538 + BURN_EXTENSIONS burnExtensions = { };
539 + try
540 + {
541 + LPCWSTR wzDocument =
542 + L"<Bundle>"
543 + L" <SetVariable Id='Search1' Type='string' Value='VAL1' Variable='PROP1' />"
544 + L" <SetVariable Id='Search2' Type='numeric' Value='2' Variable='PROP2' />"
545 + L" <SetVariable Id='Search3' Type='string' Value='VAL3' Variable='PROP3' />"
546 + L" <SetVariable Id='Search4' Type='string' Value='VAL4' Variable='PROP4' />"
547 + L" <SetVariable Id='Search5' Type='string' Value='VAL5' Variable='PROP5' />"
548 + L" <SetVariable Id='Search6' Type='string' Value='VAL6' Variable='PROP6' />"
549 + L" <SetVariable Id='Search7' Type='string' Value='7' Variable='PROP7' />"
550 + L" <SetVariable Id='Search8' Type='version' Value='1.1.0.0' Variable='PROP8' />"
551 + L" <SetVariable Id='Search9' Type='formatted' Value='[VAL9]' Variable='PROP9' />"
552 + L" <SetVariable Id='Search10' Type='numeric' Value='42' Variable='OVERWRITTEN_STRING' />"
553 + L" <SetVariable Id='Search11' Type='string' Value='NEW' Variable='OVERWRITTEN_NUMBER' />"
554 + L" <SetVariable Id='Search12' Variable='REMOVED_NUMBER' />"
555 + L"</Bundle>";
556 +
557 + hr = VariableInitialize(&variables);
558 + TestThrowOnFailure(hr, L"Failed to initialize variables.");
559 +
560 + // set variables
561 + VariableSetStringHelper(&variables, L"OVERWRITTEN_STRING", L"ORIGINAL", FALSE);
562 + VariableSetNumericHelper(&variables, L"OVERWRITTEN_NUMBER", 5);
563 + VariableSetNumericHelper(&variables, L"REMOVED_NUMBER", 22);
564 +
565 + // load XML document
566 + LoadBundleXmlHelper(wzDocument, &pixeBundle);
567 +
568 + hr = SearchesParseFromXml(&searches, &burnExtensions, pixeBundle);
569 + TestThrowOnFailure(hr, L"Failed to parse searches from XML.");
570 +
571 + // execute searches
572 + hr = SearchesExecute(&searches, &variables);
573 + TestThrowOnFailure(hr, L"Failed to execute searches.");
574 +
575 + // check variable values
576 + Assert::Equal<String^>(gcnew String(L"VAL1"), VariableGetStringHelper(&variables, L"PROP1"));
577 + Assert::Equal(2ll, VariableGetNumericHelper(&variables, L"PROP2"));
578 + Assert::Equal<String^>(gcnew String(L"2"), VariableGetStringHelper(&variables, L"PROP2"));
579 + Assert::Equal<String^>(gcnew String(L"VAL3"), VariableGetStringHelper(&variables, L"PROP3"));
580 + Assert::Equal<String^>(gcnew String(L"VAL4"), VariableGetStringHelper(&variables, L"PROP4"));
581 + Assert::Equal<String^>(gcnew String(L"VAL5"), VariableGetStringHelper(&variables, L"PROP5"));
582 + Assert::Equal<String^>(gcnew String(L"VAL6"), VariableGetStringHelper(&variables, L"PROP6"));
583 + Assert::Equal(7ll, VariableGetNumericHelper(&variables, L"PROP7"));
584 + Assert::Equal(MAKEQWORDVERSION(1, 1, 0, 0), VariableGetVersionHelper(&variables, L"PROP8"));
585 + Assert::Equal<String^>(gcnew String(L"1.1.0.0"), VariableGetStringHelper(&variables, L"PROP8"));
586 + Assert::Equal<String^>(gcnew String(L"[VAL9]"), VariableGetStringHelper(&variables, L"PROP9"));
587 +
588 + Assert::Equal(42ll, VariableGetNumericHelper(&variables, L"OVERWRITTEN_STRING"));
589 + Assert::Equal<String^>(gcnew String(L"NEW"), VariableGetStringHelper(&variables, L"OVERWRITTEN_NUMBER"));
590 + Assert::Equal((int)BURN_VARIANT_TYPE_NONE, VariableGetTypeHelper(&variables, L"REMOVED_NUMBER"));
591 + }
592 + finally
593 + {
594 + ReleaseObject(pixeBundle);
595 + VariablesUninitialize(&variables);
596 + SearchesUninitialize(&searches);
597 + }
598 + }
599 };
600 }
601 }
src/test/BurnUnitTest/VariableHelpers.cpp
+2 -2
@@ -17,11 +17,11 @@ namespace Test
17 {
18 namespace Bootstrapper
19 {
20 - void VariableSetStringHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable, LPCWSTR wzValue)
20 + void VariableSetStringHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable, LPCWSTR wzValue, BOOL fFormatted)
21 {
22 HRESULT hr = S_OK;
23
24 - hr = VariableSetString(pVariables, wzVariable, wzValue, FALSE);
24 + hr = VariableSetString(pVariables, wzVariable, wzValue, FALSE, fFormatted);
25 TestThrowOnFailure2(hr, L"Failed to set %s to: %s", wzVariable, wzValue);
26 }
27
src/test/BurnUnitTest/VariableHelpers.h
+1 -1
@@ -14,7 +14,7 @@ namespace Bootstrapper
14 {
15
16
17 -void VariableSetStringHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable, LPCWSTR wzValue);
17 +void VariableSetStringHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable, LPCWSTR wzValue, BOOL fFormatted);
18 void VariableSetNumericHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable, LONGLONG llValue);
19 void VariableSetVersionHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable, DWORD64 qwValue);
20 System::String^ VariableGetStringHelper(BURN_VARIABLES* pVariables, LPCWSTR wzVariable);
src/test/BurnUnitTest/VariableTest.cpp
+49 -20
@@ -35,21 +35,22 @@ namespace Bootstrapper
35 TestThrowOnFailure(hr, L"Failed to initialize variables.");
36
37 // set variables
38 - VariableSetStringHelper(&variables, L"PROP1", L"VAL1");
38 + VariableSetStringHelper(&variables, L"PROP1", L"VAL1", FALSE);
39 VariableSetNumericHelper(&variables, L"PROP2", 2);
40 - VariableSetStringHelper(&variables, L"PROP5", L"VAL5");
41 - VariableSetStringHelper(&variables, L"PROP3", L"VAL3");
42 - VariableSetStringHelper(&variables, L"PROP4", L"VAL4");
43 - VariableSetStringHelper(&variables, L"PROP6", L"VAL6");
44 - VariableSetStringHelper(&variables, L"PROP7", L"7");
40 + VariableSetStringHelper(&variables, L"PROP5", L"VAL5", FALSE);
41 + VariableSetStringHelper(&variables, L"PROP3", L"VAL3", FALSE);
42 + VariableSetStringHelper(&variables, L"PROP4", L"VAL4", FALSE);
43 + VariableSetStringHelper(&variables, L"PROP6", L"VAL6", FALSE);
44 + VariableSetStringHelper(&variables, L"PROP7", L"7", FALSE);
45 VariableSetVersionHelper(&variables, L"PROP8", MAKEQWORDVERSION(1,1,0,0));
46 + VariableSetStringHelper(&variables, L"PROP9", L"[VAL9]", TRUE);
47
48 // set overwritten variables
48 - VariableSetStringHelper(&variables, L"OVERWRITTEN_STRING", L"ORIGINAL");
49 + VariableSetStringHelper(&variables, L"OVERWRITTEN_STRING", L"ORIGINAL", FALSE);
50 VariableSetNumericHelper(&variables, L"OVERWRITTEN_STRING", 42);
51
52 VariableSetNumericHelper(&variables, L"OVERWRITTEN_NUMBER", 5);
52 - VariableSetStringHelper(&variables, L"OVERWRITTEN_NUMBER", L"NEW");
53 + VariableSetStringHelper(&variables, L"OVERWRITTEN_NUMBER", L"NEW", FALSE);
54
55 // get and verify variable values
56 Assert::Equal<String^>(gcnew String(L"VAL1"), VariableGetStringHelper(&variables, L"PROP1"));
@@ -62,6 +63,7 @@ namespace Bootstrapper
63 Assert::Equal(7ll, VariableGetNumericHelper(&variables, L"PROP7"));
64 Assert::Equal(MAKEQWORDVERSION(1,1,0,0), VariableGetVersionHelper(&variables, L"PROP8"));
65 Assert::Equal<String^>(gcnew String(L"1.1.0.0"), VariableGetStringHelper(&variables, L"PROP8"));
66 + Assert::Equal<String^>(gcnew String(L"[VAL9]"), VariableGetStringHelper(&variables, L"PROP9"));
67
68 Assert::Equal(42ll, VariableGetNumericHelper(&variables, L"OVERWRITTEN_STRING"));
69 Assert::Equal<String^>(gcnew String(L"NEW"), VariableGetStringHelper(&variables, L"OVERWRITTEN_NUMBER"));
@@ -87,6 +89,7 @@ namespace Bootstrapper
89 L" <Variable Id='Var3' Type='version' Value='1.2.3.4' Hidden='no' Persisted='no' />"
90 L" <Variable Id='Var4' Hidden='no' Persisted='no' />"
91 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"</Bundle>";
94
95 hr = VariableInitialize(&variables);
@@ -103,10 +106,12 @@ namespace Bootstrapper
106 Assert::Equal((int)BURN_VARIANT_TYPE_STRING, VariableGetTypeHelper(&variables, L"Var2"));
107 Assert::Equal((int)BURN_VARIANT_TYPE_VERSION, VariableGetTypeHelper(&variables, L"Var3"));
108 Assert::Equal((int)BURN_VARIANT_TYPE_NONE, VariableGetTypeHelper(&variables, L"Var4"));
109 + Assert::Equal((int)BURN_VARIANT_TYPE_FORMATTED, VariableGetTypeHelper(&variables, L"Var6"));
110
111 Assert::Equal(1ll, VariableGetNumericHelper(&variables, L"Var1"));
112 Assert::Equal<String^>(gcnew String(L"String value."), VariableGetStringHelper(&variables, L"Var2"));
113 Assert::Equal(MAKEQWORDVERSION(1,2,3,4), VariableGetVersionHelper(&variables, L"Var3"));
114 + Assert::Equal<String^>(gcnew String(L"[Formatted]"), VariableGetStringHelper(&variables, L"Var6"));
115 }
116 finally
117 {
@@ -128,9 +133,13 @@ namespace Bootstrapper
133 TestThrowOnFailure(hr, L"Failed to initialize variables.");
134
135 // set variables
131 - VariableSetStringHelper(&variables, L"PROP1", L"VAL1");
132 - VariableSetStringHelper(&variables, L"PROP2", L"VAL2");
136 + VariableSetStringHelper(&variables, L"PROP1", L"VAL1", FALSE);
137 + VariableSetStringHelper(&variables, L"PROP2", L"VAL2", FALSE);
138 VariableSetNumericHelper(&variables, L"PROP3", 3);
139 + VariableSetStringHelper(&variables, L"PROP4", L"[PROP1]", FALSE);
140 + VariableSetStringHelper(&variables, L"PROP5", L"[PROP2]", FALSE);
141 + VariableSetStringHelper(&variables, L"PROP6", L"[PROP4]", TRUE);
142 + VariableSetStringHelper(&variables, L"PROP7", L"[PROP5]", TRUE);
143
144 // test string formatting
145 Assert::Equal<String^>(gcnew String(L"NOPROP"), VariableFormatStringHelper(&variables, L"NOPROP"));
@@ -148,6 +157,10 @@ namespace Bootstrapper
157 Assert::Equal<String^>(gcnew String(L"[NONE"), VariableFormatStringHelper(&variables, L"[NONE"));
158 Assert::Equal<String^>(gcnew String(L"VAL2"), VariableGetFormattedHelper(&variables, L"PROP2"));
159 Assert::Equal<String^>(gcnew String(L"3"), VariableGetFormattedHelper(&variables, L"PROP3"));
160 + Assert::Equal<String^>(gcnew String(L"[PROP1]"), VariableGetFormattedHelper(&variables, L"PROP4"));
161 + Assert::Equal<String^>(gcnew String(L"[PROP2]"), VariableGetFormattedHelper(&variables, L"PROP5"));
162 + Assert::Equal<String^>(gcnew String(L"[PROP1]"), VariableGetFormattedHelper(&variables, L"PROP6"));
163 + Assert::Equal<String^>(gcnew String(L"[PROP2]"), VariableGetFormattedHelper(&variables, L"PROP7"));
164
165 hr = VariableFormatString(&variables, L"PRE [PROP1] POST", &scz, &cch);
166 TestThrowOnFailure(hr, L"Failed to format string");
@@ -186,15 +199,15 @@ namespace Bootstrapper
199 TestThrowOnFailure(hr, L"Failed to initialize variables.");
200
201 // set variables
189 - VariableSetStringHelper(&variables, L"PROP1", L"VAL1");
190 - VariableSetStringHelper(&variables, L"PROP2", L"VAL2");
191 - VariableSetStringHelper(&variables, L"PROP3", L"VAL3");
192 - VariableSetStringHelper(&variables, L"PROP4", L"BEGIN MID END");
202 + VariableSetStringHelper(&variables, L"PROP1", L"VAL1", FALSE);
203 + VariableSetStringHelper(&variables, L"PROP2", L"VAL2", FALSE);
204 + VariableSetStringHelper(&variables, L"PROP3", L"VAL3", FALSE);
205 + VariableSetStringHelper(&variables, L"PROP4", L"BEGIN MID END", FALSE);
206 VariableSetNumericHelper(&variables, L"PROP5", 5);
207 VariableSetNumericHelper(&variables, L"PROP6", 6);
195 - VariableSetStringHelper(&variables, L"PROP7", L"");
208 + VariableSetStringHelper(&variables, L"PROP7", L"", FALSE);
209 VariableSetNumericHelper(&variables, L"PROP8", 0);
197 - VariableSetStringHelper(&variables, L"_PROP9", L"VAL9");
210 + VariableSetStringHelper(&variables, L"_PROP9", L"VAL9", FALSE);
211 VariableSetNumericHelper(&variables, L"PROP10", -10);
212 VariableSetNumericHelper(&variables, L"PROP11", 9223372036854775807ll);
213 VariableSetNumericHelper(&variables, L"PROP12", -9223372036854775808ll);
@@ -208,7 +221,11 @@ namespace Bootstrapper
221 VariableSetVersionHelper(&variables, L"PROP20", MAKEQWORDVERSION(1,1,1,1));
222 VariableSetNumericHelper(&variables, L"vPROP21", 1);
223 VariableSetVersionHelper(&variables, L"PROP22", MAKEQWORDVERSION(65535,65535,65535,65535));
211 - VariableSetStringHelper(&variables, L"PROP23", L"1.1.1");
224 + VariableSetStringHelper(&variables, L"PROP23", L"1.1.1", FALSE);
225 + VariableSetStringHelper(&variables, L"PROP24", L"[PROP1]", TRUE);
226 + VariableSetStringHelper(&variables, L"PROP25", L"[PROP7]", TRUE);
227 + VariableSetStringHelper(&variables, L"PROP26", L"[PROP8]", TRUE);
228 + VariableSetStringHelper(&variables, L"PROP27", L"[PROP16]", TRUE);
229
230 // test conditions
231 Assert::True(EvaluateConditionHelper(&variables, L"PROP1"));
@@ -218,6 +235,10 @@ namespace Bootstrapper
235 Assert::True(EvaluateConditionHelper(&variables, L"_PROP9"));
236 Assert::False(EvaluateConditionHelper(&variables, L"PROP16"));
237 Assert::True(EvaluateConditionHelper(&variables, L"PROP17"));
238 + Assert::True(EvaluateConditionHelper(&variables, L"PROP24"));
239 + Assert::True(EvaluateConditionHelper(&variables, L"PROP25"));
240 + Assert::True(EvaluateConditionHelper(&variables, L"PROP26"));
241 + Assert::True(EvaluateConditionHelper(&variables, L"PROP27"));
242
243 Assert::True(EvaluateConditionHelper(&variables, L"PROP1 = \"VAL1\""));
244 Assert::False(EvaluateConditionHelper(&variables, L"NONE = \"NOT\""));
@@ -365,10 +386,11 @@ namespace Bootstrapper
386 hr = VariableInitialize(&variables1);
387 TestThrowOnFailure(hr, L"Failed to initialize variables.");
388
368 - VariableSetStringHelper(&variables1, L"PROP1", L"VAL1");
389 + VariableSetStringHelper(&variables1, L"PROP1", L"VAL1", FALSE);
390 VariableSetNumericHelper(&variables1, L"PROP2", 2);
391 VariableSetVersionHelper(&variables1, L"PROP3", MAKEQWORDVERSION(1,1,1,1));
371 - VariableSetStringHelper(&variables1, L"PROP4", L"VAL4");
392 + VariableSetStringHelper(&variables1, L"PROP4", L"VAL4", FALSE);
393 + VariableSetStringHelper(&variables1, L"PROP5", L"[PROP1]", TRUE);
394
395 hr = VariableSerialize(&variables1, FALSE, &pbBuffer, &cbBuffer);
396 TestThrowOnFailure(hr, L"Failed to serialize variables.");
@@ -384,6 +406,13 @@ namespace Bootstrapper
406 Assert::Equal(2ll, VariableGetNumericHelper(&variables2, L"PROP2"));
407 Assert::Equal(MAKEQWORDVERSION(1,1,1,1), VariableGetVersionHelper(&variables2, L"PROP3"));
408 Assert::Equal<String^>(gcnew String(L"VAL4"), VariableGetStringHelper(&variables2, L"PROP4"));
409 + Assert::Equal<String^>(gcnew String(L"[PROP1]"), VariableGetStringHelper(&variables2, L"PROP5"));
410 +
411 + Assert::Equal((int)BURN_VARIANT_TYPE_STRING, VariableGetTypeHelper(&variables2, L"PROP1"));
412 + Assert::Equal((int)BURN_VARIANT_TYPE_NUMERIC, VariableGetTypeHelper(&variables2, L"PROP2"));
413 + Assert::Equal((int)BURN_VARIANT_TYPE_VERSION, VariableGetTypeHelper(&variables2, L"PROP3"));
414 + Assert::Equal((int)BURN_VARIANT_TYPE_STRING, VariableGetTypeHelper(&variables2, L"PROP4"));
415 + Assert::Equal((int)BURN_VARIANT_TYPE_FORMATTED, VariableGetTypeHelper(&variables2, L"PROP5"));
416 }
417 finally
418 {
@@ -420,7 +449,7 @@ namespace Bootstrapper
449 }
450
451 // attempt to set a built-in property
423 - hr = VariableSetString(&variables, L"VersionNT", L"VAL", FALSE);
452 + hr = VariableSetString(&variables, L"VersionNT", L"VAL", FALSE, FALSE);
453 Assert::Equal(E_INVALIDARG, hr);
454 Assert::False(EvaluateConditionHelper(&variables, L"VersionNT = \"VAL\""));
455
src/test/BurnUnitTest/VariantTest.cpp
+50 -6
@@ -25,9 +25,9 @@ namespace Bootstrapper
25 [Fact]
26 void VariantBasicTest()
27 {
28 - BURN_VARIANT expectedVariants[8];
29 - BURN_VARIANT actualVariants[8];
30 - for (DWORD i = 0; i < 8; i++)
28 + BURN_VARIANT expectedVariants[10];
29 + BURN_VARIANT actualVariants[10];
30 + for (DWORD i = 0; i < 10; i++)
31 {
32 BVariantUninitialize(expectedVariants + i);
33 BVariantUninitialize(actualVariants + i);
@@ -43,6 +43,8 @@ namespace Bootstrapper
43 InitVersionValue(expectedVariants + 5, MAKEQWORDVERSION(1, 1, 1, 0), TRUE, L"PROP6", actualVariants + 5);
44 InitStringValue(expectedVariants + 6, L"7", TRUE, L"PROP7", actualVariants + 6);
45 InitNumericValue(expectedVariants + 7, 11, TRUE, L"PROP8", actualVariants + 7);
46 + InitFormattedValue(expectedVariants + 8, L"VAL9", FALSE, L"PROP9", actualVariants + 8);
47 + InitFormattedValue(expectedVariants + 9, L"VAL10", TRUE, L"PROP10", actualVariants + 9);
48
49 VerifyNumericValue(expectedVariants + 0, actualVariants + 0);
50 VerifyStringValue(expectedVariants + 1, actualVariants + 1);
@@ -52,10 +54,12 @@ namespace Bootstrapper
54 VerifyVersionValue(expectedVariants + 5, actualVariants + 5);
55 VerifyStringValue(expectedVariants + 6, actualVariants + 6);
56 VerifyNumericValue(expectedVariants + 7, actualVariants + 7);
57 + VerifyFormattedValue(expectedVariants + 8, actualVariants + 8);
58 + VerifyFormattedValue(expectedVariants + 9, actualVariants + 9);
59 }
60 finally
61 {
58 - for (DWORD i = 0; i < 8; i++)
62 + for (DWORD i = 0; i < 10; i++)
63 {
64 BVariantUninitialize(expectedVariants + i);
65 BVariantUninitialize(actualVariants + i);
@@ -64,6 +68,26 @@ namespace Bootstrapper
68 }
69
70 private:
71 + void InitFormattedValue(BURN_VARIANT* pValue, LPWSTR wzValue, BOOL fHidden, LPCWSTR wz, BURN_VARIANT* pActualValue)
72 + {
73 + HRESULT hr = S_OK;
74 + pValue->Type = BURN_VARIANT_TYPE_FORMATTED;
75 +
76 + hr = StrAllocString(&pValue->sczValue, wzValue, 0);
77 + NativeAssert::Succeeded(hr, "Failed to alloc string: {0}", wzValue);
78 +
79 + hr = BVariantCopy(pValue, pActualValue);
80 + NativeAssert::Succeeded(hr, "Failed to copy variant {0}", wz);
81 +
82 + if (fHidden)
83 + {
84 + hr = BVariantSetEncryption(pActualValue, TRUE);
85 + NativeAssert::Succeeded(hr, "Failed to encrypt variant {0}", wz);
86 +
87 + NativeAssert::True(pActualValue->fEncryptString);
88 + }
89 + }
90 +
91 void InitNoneValue(BURN_VARIANT* pValue, BOOL fHidden, LPCWSTR wz, BURN_VARIANT* pActualValue)
92 {
93 HRESULT hr = S_OK;
@@ -137,6 +161,26 @@ namespace Bootstrapper
161 }
162 }
163
164 + void VerifyFormattedValue(BURN_VARIANT* pExpectedValue, BURN_VARIANT* pActualValue)
165 + {
166 + HRESULT hr = S_OK;
167 + LPWSTR sczValue = NULL;
168 + NativeAssert::Equal<DWORD>(BURN_VARIANT_TYPE_FORMATTED, pExpectedValue->Type);
169 + NativeAssert::Equal<DWORD>(BURN_VARIANT_TYPE_FORMATTED, pActualValue->Type);
170 +
171 + try
172 + {
173 + hr = BVariantGetString(pActualValue, &sczValue);
174 + NativeAssert::Succeeded(hr, "Failed to get string value");
175 +
176 + NativeAssert::StringEqual(pExpectedValue->sczValue, sczValue);
177 + }
178 + finally
179 + {
180 + ReleaseStr(sczValue);
181 + }
182 + }
183 +
184 void VerifyNumericValue(BURN_VARIANT* pExpectedValue, BURN_VARIANT* pActualValue)
185 {
186 HRESULT hr = S_OK;
@@ -167,7 +211,7 @@ namespace Bootstrapper
211 try
212 {
213 hr = BVariantGetString(pActualValue, &sczValue);
170 - NativeAssert::Succeeded(hr, "Failed to get numeric value");
214 + NativeAssert::Succeeded(hr, "Failed to get string value");
215
216 NativeAssert::StringEqual(pExpectedValue->sczValue, sczValue);
217 }
@@ -185,7 +229,7 @@ namespace Bootstrapper
229 NativeAssert::Equal<DWORD>(BURN_VARIANT_TYPE_VERSION, pActualValue->Type);
230
231 hr = BVariantGetVersion(pActualValue, &qwValue);
188 - NativeAssert::Succeeded(hr, "Failed to get numeric value");
232 + NativeAssert::Succeeded(hr, "Failed to get version value");
233
234 NativeAssert::Equal<DWORD64>(pExpectedValue->qwValue, qwValue);
235 }