aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2022-04-22 16:55:29 -0500
committerSean Hall <r.sean.hall@gmail.com>2022-04-23 15:40:21 -0500
commit72e20f682c0d64102e86439ba5527dd0d71932ae (patch)
treec62618b0f6b99d3bffa3c6cd01251a29b84fcc05 /src
parentb82c6a2b7d451212fb0b2e32ca4d5d86c953d81a (diff)
downloadwix-72e20f682c0d64102e86439ba5527dd0d71932ae.tar.gz
wix-72e20f682c0d64102e86439ba5527dd0d71932ae.tar.bz2
wix-72e20f682c0d64102e86439ba5527dd0d71932ae.zip
Add RepairCondition.
Fixes 6758
Diffstat (limited to 'src')
-rw-r--r--src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h1
-rw-r--r--src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs4
-rw-r--r--src/api/burn/WixToolset.Mba.Core/EventArgs.cs8
-rw-r--r--src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs1
-rw-r--r--src/api/burn/WixToolset.Mba.Core/IPackageInfo.cs7
-rw-r--r--src/api/burn/WixToolset.Mba.Core/PackageInfo.cs5
-rw-r--r--src/api/burn/balutil/balinfo.cpp7
-rw-r--r--src/api/burn/balutil/inc/BalBaseBAFunctions.h1
-rw-r--r--src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h1
-rw-r--r--src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h2
-rw-r--r--src/api/burn/balutil/inc/IBootstrapperApplication.h1
-rw-r--r--src/api/burn/balutil/inc/balinfo.h1
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixBundlePackageSymbol.cs8
-rw-r--r--src/burn/engine/package.cpp5
-rw-r--r--src/burn/engine/package.h1
-rw-r--r--src/burn/engine/plan.cpp24
-rw-r--r--src/burn/engine/plan.h1
-rw-r--r--src/burn/engine/userexperience.cpp2
-rw-r--r--src/burn/engine/userexperience.h1
-rw-r--r--src/burn/test/BurnUnitTest/PlanTest.cpp95
-rw-r--r--src/burn/test/BurnUnitTest/TestData/PlanTest/BundlePackage_Multiple_manifest.xml2
-rw-r--r--src/burn/test/BurnUnitTest/VariableTest.cpp1
-rw-r--r--src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp3
-rw-r--r--src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs5
-rw-r--r--src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs5
-rw-r--r--src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs5
-rw-r--r--src/wix/WixToolset.Core/Compiler_Bundle.cs11
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs2
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/BundlePackageFixture.cs4
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/ExePackageFixture.cs24
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundlePackage/V3BundlePackage.wxs2
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/CustomPackageDescription/CustomPackageDescription.wxs2
-rw-r--r--src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/RepairConditionWithoutRepairArguments.wxs12
33 files changed, 237 insertions, 17 deletions
diff --git a/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h b/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
index fbbd10ee..f0b5dad4 100644
--- a/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
+++ b/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
@@ -1243,6 +1243,7 @@ struct BA_ONPLANPACKAGEBEGIN_ARGS
1243 BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition; 1243 BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition;
1244 BOOTSTRAPPER_REQUEST_STATE recommendedState; 1244 BOOTSTRAPPER_REQUEST_STATE recommendedState;
1245 BOOTSTRAPPER_CACHE_TYPE recommendedCacheType; 1245 BOOTSTRAPPER_CACHE_TYPE recommendedCacheType;
1246 BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition;
1246}; 1247};
1247 1248
1248struct BA_ONPLANPACKAGEBEGIN_RESULTS 1249struct BA_ONPLANPACKAGEBEGIN_RESULTS
diff --git a/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs b/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs
index 41738bf6..6738a4a6 100644
--- a/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs
+++ b/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs
@@ -1598,9 +1598,9 @@ namespace WixToolset.Mba.Core
1598 return args.HResult; 1598 return args.HResult;
1599 } 1599 }
1600 1600
1601 int IBootstrapperApplication.OnPlanPackageBegin(string wzPackageId, PackageState state, bool fCached, BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, RequestState recommendedState, BOOTSTRAPPER_CACHE_TYPE recommendedCacheType, ref RequestState pRequestedState, ref BOOTSTRAPPER_CACHE_TYPE pRequestedCacheType, ref bool fCancel) 1601 int IBootstrapperApplication.OnPlanPackageBegin(string wzPackageId, PackageState state, bool fCached, BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition, RequestState recommendedState, BOOTSTRAPPER_CACHE_TYPE recommendedCacheType, ref RequestState pRequestedState, ref BOOTSTRAPPER_CACHE_TYPE pRequestedCacheType, ref bool fCancel)
1602 { 1602 {
1603 PlanPackageBeginEventArgs args = new PlanPackageBeginEventArgs(wzPackageId, state, fCached, installCondition, recommendedState, recommendedCacheType, pRequestedState, pRequestedCacheType, fCancel); 1603 PlanPackageBeginEventArgs args = new PlanPackageBeginEventArgs(wzPackageId, state, fCached, installCondition, repairCondition, recommendedState, recommendedCacheType, pRequestedState, pRequestedCacheType, fCancel);
1604 this.OnPlanPackageBegin(args); 1604 this.OnPlanPackageBegin(args);
1605 1605
1606 pRequestedState = args.State; 1606 pRequestedState = args.State;
diff --git a/src/api/burn/WixToolset.Mba.Core/EventArgs.cs b/src/api/burn/WixToolset.Mba.Core/EventArgs.cs
index 07b14b3d..d79ac402 100644
--- a/src/api/burn/WixToolset.Mba.Core/EventArgs.cs
+++ b/src/api/burn/WixToolset.Mba.Core/EventArgs.cs
@@ -783,13 +783,14 @@ namespace WixToolset.Mba.Core
783 public class PlanPackageBeginEventArgs : CancellableHResultEventArgs 783 public class PlanPackageBeginEventArgs : CancellableHResultEventArgs
784 { 784 {
785 /// <summary /> 785 /// <summary />
786 public PlanPackageBeginEventArgs(string packageId, PackageState currentState, bool cached, BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, RequestState recommendedState, BOOTSTRAPPER_CACHE_TYPE recommendedCacheType, RequestState state, BOOTSTRAPPER_CACHE_TYPE cacheType, bool cancelRecommendation) 786 public PlanPackageBeginEventArgs(string packageId, PackageState currentState, bool cached, BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition, RequestState recommendedState, BOOTSTRAPPER_CACHE_TYPE recommendedCacheType, RequestState state, BOOTSTRAPPER_CACHE_TYPE cacheType, bool cancelRecommendation)
787 : base(cancelRecommendation) 787 : base(cancelRecommendation)
788 { 788 {
789 this.PackageId = packageId; 789 this.PackageId = packageId;
790 this.CurrentState = currentState; 790 this.CurrentState = currentState;
791 this.Cached = cached; 791 this.Cached = cached;
792 this.InstallCondition = installCondition; 792 this.InstallCondition = installCondition;
793 this.RepairCondition = repairCondition;
793 this.RecommendedState = recommendedState; 794 this.RecommendedState = recommendedState;
794 this.RecommendedCacheType = recommendedCacheType; 795 this.RecommendedCacheType = recommendedCacheType;
795 this.State = state; 796 this.State = state;
@@ -817,6 +818,11 @@ namespace WixToolset.Mba.Core
817 public BOOTSTRAPPER_PACKAGE_CONDITION_RESULT InstallCondition { get; private set; } 818 public BOOTSTRAPPER_PACKAGE_CONDITION_RESULT InstallCondition { get; private set; }
818 819
819 /// <summary> 820 /// <summary>
821 /// Gets the evaluated result of the package's repair condition.
822 /// </summary>
823 public BOOTSTRAPPER_PACKAGE_CONDITION_RESULT RepairCondition { get; private set; }
824
825 /// <summary>
820 /// Gets the recommended requested state for the package. 826 /// Gets the recommended requested state for the package.
821 /// </summary> 827 /// </summary>
822 public RequestState RecommendedState { get; private set; } 828 public RequestState RecommendedState { get; private set; }
diff --git a/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs b/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs
index ae642474..2877d4de 100644
--- a/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs
+++ b/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs
@@ -314,6 +314,7 @@ namespace WixToolset.Mba.Core
314 [MarshalAs(UnmanagedType.U4)] PackageState state, 314 [MarshalAs(UnmanagedType.U4)] PackageState state,
315 [MarshalAs(UnmanagedType.Bool)] bool fCached, 315 [MarshalAs(UnmanagedType.Bool)] bool fCached,
316 [MarshalAs(UnmanagedType.U4)] BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, 316 [MarshalAs(UnmanagedType.U4)] BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
317 [MarshalAs(UnmanagedType.U4)] BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition,
317 [MarshalAs(UnmanagedType.U4)] RequestState recommendedState, 318 [MarshalAs(UnmanagedType.U4)] RequestState recommendedState,
318 [MarshalAs(UnmanagedType.U4)] BOOTSTRAPPER_CACHE_TYPE recommendedCacheType, 319 [MarshalAs(UnmanagedType.U4)] BOOTSTRAPPER_CACHE_TYPE recommendedCacheType,
319 [MarshalAs(UnmanagedType.U4)] ref RequestState pRequestedState, 320 [MarshalAs(UnmanagedType.U4)] ref RequestState pRequestedState,
diff --git a/src/api/burn/WixToolset.Mba.Core/IPackageInfo.cs b/src/api/burn/WixToolset.Mba.Core/IPackageInfo.cs
index a1d99b10..ee3be820 100644
--- a/src/api/burn/WixToolset.Mba.Core/IPackageInfo.cs
+++ b/src/api/burn/WixToolset.Mba.Core/IPackageInfo.cs
@@ -45,6 +45,11 @@ namespace WixToolset.Mba.Core
45 /// <summary> 45 /// <summary>
46 /// 46 ///
47 /// </summary> 47 /// </summary>
48 string RepairCondition { get; }
49
50 /// <summary>
51 ///
52 /// </summary>
48 bool Permanent { get; } 53 bool Permanent { get; }
49 54
50 /// <summary> 55 /// <summary>
@@ -87,4 +92,4 @@ namespace WixToolset.Mba.Core
87 /// </summary> 92 /// </summary>
88 bool Vital { get; } 93 bool Vital { get; }
89 } 94 }
90} \ No newline at end of file 95}
diff --git a/src/api/burn/WixToolset.Mba.Core/PackageInfo.cs b/src/api/burn/WixToolset.Mba.Core/PackageInfo.cs
index 39fe4d73..e400cbe4 100644
--- a/src/api/burn/WixToolset.Mba.Core/PackageInfo.cs
+++ b/src/api/burn/WixToolset.Mba.Core/PackageInfo.cs
@@ -102,6 +102,9 @@ namespace WixToolset.Mba.Core
102 public string InstallCondition { get; internal set; } 102 public string InstallCondition { get; internal set; }
103 103
104 /// <inheritdoc/> 104 /// <inheritdoc/>
105 public string RepairCondition { get; internal set; }
106
107 /// <inheritdoc/>
105 public BOOTSTRAPPER_CACHE_TYPE CacheType { get; internal set; } 108 public BOOTSTRAPPER_CACHE_TYPE CacheType { get; internal set; }
106 109
107 /// <inheritdoc/> 110 /// <inheritdoc/>
@@ -174,6 +177,8 @@ namespace WixToolset.Mba.Core
174 177
175 package.InstallCondition = BootstrapperApplicationData.GetAttribute(node, "InstallCondition"); 178 package.InstallCondition = BootstrapperApplicationData.GetAttribute(node, "InstallCondition");
176 179
180 package.RepairCondition = BootstrapperApplicationData.GetAttribute(node, "RepairCondition");
181
177 packagesById.Add(package.Id, package); 182 packagesById.Add(package.Id, package);
178 } 183 }
179 184
diff --git a/src/api/burn/balutil/balinfo.cpp b/src/api/burn/balutil/balinfo.cpp
index f0eb9904..29e453f6 100644
--- a/src/api/burn/balutil/balinfo.cpp
+++ b/src/api/burn/balutil/balinfo.cpp
@@ -304,6 +304,7 @@ DAPI_(void) BalInfoUninitialize(
304 ReleaseStr(pBundle->packages.rgPackages[i].sczUpgradeCode); 304 ReleaseStr(pBundle->packages.rgPackages[i].sczUpgradeCode);
305 ReleaseStr(pBundle->packages.rgPackages[i].sczVersion); 305 ReleaseStr(pBundle->packages.rgPackages[i].sczVersion);
306 ReleaseStr(pBundle->packages.rgPackages[i].sczInstallCondition); 306 ReleaseStr(pBundle->packages.rgPackages[i].sczInstallCondition);
307 ReleaseStr(pBundle->packages.rgPackages[i].sczRepairCondition);
307 ReleaseStr(pBundle->packages.rgPackages[i].sczPrereqLicenseFile); 308 ReleaseStr(pBundle->packages.rgPackages[i].sczPrereqLicenseFile);
308 ReleaseStr(pBundle->packages.rgPackages[i].sczPrereqLicenseUrl); 309 ReleaseStr(pBundle->packages.rgPackages[i].sczPrereqLicenseUrl);
309 } 310 }
@@ -484,6 +485,12 @@ static HRESULT ParsePackagesFromXml(
484 ExitOnFailure(hr, "Failed to get install condition for package."); 485 ExitOnFailure(hr, "Failed to get install condition for package.");
485 } 486 }
486 487
488 hr = XmlGetAttributeEx(pNode, L"RepairCondition", &prgPackages[iPackage].sczRepairCondition);
489 if (E_NOTFOUND != hr)
490 {
491 ExitOnFailure(hr, "Failed to get repair condition for package.");
492 }
493
487 hr = XmlGetAttributeEx(pNode, L"Cache", &scz); 494 hr = XmlGetAttributeEx(pNode, L"Cache", &scz);
488 ExitOnFailure(hr, "Failed to get cache type for package."); 495 ExitOnFailure(hr, "Failed to get cache type for package.");
489 496
diff --git a/src/api/burn/balutil/inc/BalBaseBAFunctions.h b/src/api/burn/balutil/inc/BalBaseBAFunctions.h
index 6bde05d2..9ff58d2b 100644
--- a/src/api/burn/balutil/inc/BalBaseBAFunctions.h
+++ b/src/api/burn/balutil/inc/BalBaseBAFunctions.h
@@ -276,6 +276,7 @@ public: // IBootstrapperApplication
276 __in BOOTSTRAPPER_PACKAGE_STATE /*state*/, 276 __in BOOTSTRAPPER_PACKAGE_STATE /*state*/,
277 __in BOOL /*fCached*/, 277 __in BOOL /*fCached*/,
278 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT /*installCondition*/, 278 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT /*installCondition*/,
279 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT /*repairCondition*/,
279 __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/, 280 __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/,
280 __in BOOTSTRAPPER_CACHE_TYPE /*recommendedCacheType*/, 281 __in BOOTSTRAPPER_CACHE_TYPE /*recommendedCacheType*/,
281 __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestState*/, 282 __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestState*/,
diff --git a/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h b/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h
index b661c7c9..2e848df7 100644
--- a/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h
+++ b/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h
@@ -290,6 +290,7 @@ public: // IBootstrapperApplication
290 __in BOOTSTRAPPER_PACKAGE_STATE /*state*/, 290 __in BOOTSTRAPPER_PACKAGE_STATE /*state*/,
291 __in BOOL /*fCached*/, 291 __in BOOL /*fCached*/,
292 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT /*installCondition*/, 292 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT /*installCondition*/,
293 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT /*repairCondition*/,
293 __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/, 294 __in BOOTSTRAPPER_REQUEST_STATE /*recommendedState*/,
294 __in BOOTSTRAPPER_CACHE_TYPE /*recommendedCacheType*/, 295 __in BOOTSTRAPPER_CACHE_TYPE /*recommendedCacheType*/,
295 __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestState*/, 296 __inout BOOTSTRAPPER_REQUEST_STATE* /*pRequestState*/,
diff --git a/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h b/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h
index 4ef7bac5..e35678ad 100644
--- a/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h
+++ b/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h
@@ -195,7 +195,7 @@ static HRESULT BalBaseBAProcOnPlanPackageBegin(
195 __inout BA_ONPLANPACKAGEBEGIN_RESULTS* pResults 195 __inout BA_ONPLANPACKAGEBEGIN_RESULTS* pResults
196 ) 196 )
197{ 197{
198 return pBA->OnPlanPackageBegin(pArgs->wzPackageId, pArgs->state, pArgs->fCached, pArgs->installCondition, pArgs->recommendedState, pArgs->recommendedCacheType, &pResults->requestedState, &pResults->requestedCacheType, &pResults->fCancel); 198 return pBA->OnPlanPackageBegin(pArgs->wzPackageId, pArgs->state, pArgs->fCached, pArgs->installCondition, pArgs->repairCondition, pArgs->recommendedState, pArgs->recommendedCacheType, &pResults->requestedState, &pResults->requestedCacheType, &pResults->fCancel);
199} 199}
200 200
201static HRESULT BalBaseBAProcOnPlanCompatibleMsiPackageBegin( 201static HRESULT BalBaseBAProcOnPlanCompatibleMsiPackageBegin(
diff --git a/src/api/burn/balutil/inc/IBootstrapperApplication.h b/src/api/burn/balutil/inc/IBootstrapperApplication.h
index a4840228..6eca90fa 100644
--- a/src/api/burn/balutil/inc/IBootstrapperApplication.h
+++ b/src/api/burn/balutil/inc/IBootstrapperApplication.h
@@ -182,6 +182,7 @@ DECLARE_INTERFACE_IID_(IBootstrapperApplication, IUnknown, "53C31D56-49C0-426B-A
182 __in BOOTSTRAPPER_PACKAGE_STATE state, 182 __in BOOTSTRAPPER_PACKAGE_STATE state,
183 __in BOOL fCached, 183 __in BOOL fCached,
184 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, 184 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
185 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition,
185 __in BOOTSTRAPPER_REQUEST_STATE recommendedState, 186 __in BOOTSTRAPPER_REQUEST_STATE recommendedState,
186 __in BOOTSTRAPPER_CACHE_TYPE recommendedCacheType, 187 __in BOOTSTRAPPER_CACHE_TYPE recommendedCacheType,
187 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState, 188 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState,
diff --git a/src/api/burn/balutil/inc/balinfo.h b/src/api/burn/balutil/inc/balinfo.h
index 0c7a5b93..cd61f34d 100644
--- a/src/api/burn/balutil/inc/balinfo.h
+++ b/src/api/burn/balutil/inc/balinfo.h
@@ -49,6 +49,7 @@ typedef struct _BAL_INFO_PACKAGE
49 LPWSTR sczUpgradeCode; 49 LPWSTR sczUpgradeCode;
50 LPWSTR sczVersion; 50 LPWSTR sczVersion;
51 LPWSTR sczInstallCondition; 51 LPWSTR sczInstallCondition;
52 LPWSTR sczRepairCondition;
52 BOOTSTRAPPER_CACHE_TYPE cacheType; 53 BOOTSTRAPPER_CACHE_TYPE cacheType;
53 BOOL fPrereqPackage; 54 BOOL fPrereqPackage;
54 LPWSTR sczPrereqLicenseFile; 55 LPWSTR sczPrereqLicenseFile;
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundlePackageSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundlePackageSymbol.cs
index 6afe657e..8d625664 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixBundlePackageSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixBundlePackageSymbol.cs
@@ -14,6 +14,7 @@ namespace WixToolset.Data
14 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.PayloadRef), IntermediateFieldType.String), 14 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.PayloadRef), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.Attributes), IntermediateFieldType.Number), 15 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.Attributes), IntermediateFieldType.Number),
16 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.InstallCondition), IntermediateFieldType.String), 16 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.InstallCondition), IntermediateFieldType.String),
17 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.RepairCondition), IntermediateFieldType.String),
17 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.Cache), IntermediateFieldType.String), 18 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.Cache), IntermediateFieldType.String),
18 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.CacheId), IntermediateFieldType.String), 19 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.CacheId), IntermediateFieldType.String),
19 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.PerMachine), IntermediateFieldType.Bool), 20 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.PerMachine), IntermediateFieldType.Bool),
@@ -42,6 +43,7 @@ namespace WixToolset.Data.Symbols
42 PayloadRef, 43 PayloadRef,
43 Attributes, 44 Attributes,
44 InstallCondition, 45 InstallCondition,
46 RepairCondition,
45 Cache, 47 Cache,
46 CacheId, 48 CacheId,
47 PerMachine, 49 PerMachine,
@@ -124,6 +126,12 @@ namespace WixToolset.Data.Symbols
124 set => this.Set((int)WixBundlePackageSymbolFields.InstallCondition, value); 126 set => this.Set((int)WixBundlePackageSymbolFields.InstallCondition, value);
125 } 127 }
126 128
129 public string RepairCondition
130 {
131 get => (string)this.Fields[(int)WixBundlePackageSymbolFields.RepairCondition];
132 set => this.Set((int)WixBundlePackageSymbolFields.RepairCondition, value);
133 }
134
127 public BundleCacheType? Cache 135 public BundleCacheType? Cache
128 { 136 {
129 get => Enum.TryParse((string)this.Fields[(int)WixBundlePackageSymbolFields.Cache], true, out BundleCacheType value) ? value : (BundleCacheType?)null; 137 get => Enum.TryParse((string)this.Fields[(int)WixBundlePackageSymbolFields.Cache], true, out BundleCacheType value) ? value : (BundleCacheType?)null;
diff --git a/src/burn/engine/package.cpp b/src/burn/engine/package.cpp
index 89203ada..88e7cb9d 100644
--- a/src/burn/engine/package.cpp
+++ b/src/burn/engine/package.cpp
@@ -178,6 +178,10 @@ extern "C" HRESULT PackagesParseFromXml(
178 hr = XmlGetAttributeEx(pixnNode, L"InstallCondition", &pPackage->sczInstallCondition); 178 hr = XmlGetAttributeEx(pixnNode, L"InstallCondition", &pPackage->sczInstallCondition);
179 ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @InstallCondition."); 179 ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @InstallCondition.");
180 180
181 // @RepairCondition
182 hr = XmlGetAttributeEx(pixnNode, L"RepairCondition", &pPackage->sczRepairCondition);
183 ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @RepairCondition.");
184
181 // @RollbackBoundaryForward 185 // @RollbackBoundaryForward
182 hr = XmlGetAttributeEx(pixnNode, L"RollbackBoundaryForward", &scz); 186 hr = XmlGetAttributeEx(pixnNode, L"RollbackBoundaryForward", &scz);
183 ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @RollbackBoundaryForward."); 187 ExitOnOptionalXmlQueryFailure(hr, fFoundXml, "Failed to get @RollbackBoundaryForward.");
@@ -362,6 +366,7 @@ extern "C" void PackageUninitialize(
362 ReleaseStr(pPackage->sczLogPathVariable); 366 ReleaseStr(pPackage->sczLogPathVariable);
363 ReleaseStr(pPackage->sczRollbackLogPathVariable); 367 ReleaseStr(pPackage->sczRollbackLogPathVariable);
364 ReleaseStr(pPackage->sczInstallCondition); 368 ReleaseStr(pPackage->sczInstallCondition);
369 ReleaseStr(pPackage->sczRepairCondition);
365 ReleaseStr(pPackage->sczCacheId); 370 ReleaseStr(pPackage->sczCacheId);
366 371
367 if (pPackage->rgDependencyProviders) 372 if (pPackage->rgDependencyProviders)
diff --git a/src/burn/engine/package.h b/src/burn/engine/package.h
index eb8e7543..3ec77baf 100644
--- a/src/burn/engine/package.h
+++ b/src/burn/engine/package.h
@@ -250,6 +250,7 @@ typedef struct _BURN_PACKAGE
250 LPWSTR sczRollbackLogPathVariable; // name of the variable that will be set to the rollback path. 250 LPWSTR sczRollbackLogPathVariable; // name of the variable that will be set to the rollback path.
251 251
252 LPWSTR sczInstallCondition; 252 LPWSTR sczInstallCondition;
253 LPWSTR sczRepairCondition;
253 BOOL fPerMachine; 254 BOOL fPerMachine;
254 BOOL fPermanent; 255 BOOL fPermanent;
255 BOOL fVital; 256 BOOL fVital;
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp
index 2c267415..47da22c0 100644
--- a/src/burn/engine/plan.cpp
+++ b/src/burn/engine/plan.cpp
@@ -347,6 +347,7 @@ extern "C" HRESULT PlanDefaultPackageRequestState(
347 __in BOOTSTRAPPER_PACKAGE_STATE currentState, 347 __in BOOTSTRAPPER_PACKAGE_STATE currentState,
348 __in BOOTSTRAPPER_ACTION action, 348 __in BOOTSTRAPPER_ACTION action,
349 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, 349 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
350 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition,
350 __in BOOTSTRAPPER_RELATION_TYPE relationType, 351 __in BOOTSTRAPPER_RELATION_TYPE relationType,
351 __out BOOTSTRAPPER_REQUEST_STATE* pRequestState 352 __out BOOTSTRAPPER_REQUEST_STATE* pRequestState
352 ) 353 )
@@ -408,6 +409,10 @@ extern "C" HRESULT PlanDefaultPackageRequestState(
408 { 409 {
409 defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT <= defaultRequestState ? BOOTSTRAPPER_REQUEST_STATE_NONE : defaultRequestState; 410 defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT <= defaultRequestState ? BOOTSTRAPPER_REQUEST_STATE_NONE : defaultRequestState;
410 } 411 }
412 else if (BOOTSTRAPPER_ACTION_REPAIR == action && BOOTSTRAPPER_PACKAGE_CONDITION_FALSE == repairCondition)
413 {
414 defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
415 }
411 } 416 }
412 417
413 *pRequestState = defaultRequestState; 418 *pRequestState = defaultRequestState;
@@ -905,7 +910,8 @@ static HRESULT InitializePackage(
905{ 910{
906 HRESULT hr = S_OK; 911 HRESULT hr = S_OK;
907 BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition = BOOTSTRAPPER_PACKAGE_CONDITION_DEFAULT; 912 BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition = BOOTSTRAPPER_PACKAGE_CONDITION_DEFAULT;
908 BOOL fInstallCondition = FALSE; 913 BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition = BOOTSTRAPPER_PACKAGE_CONDITION_DEFAULT;
914 BOOL fEvaluatedCondition = FALSE;
909 BOOL fBeginCalled = FALSE; 915 BOOL fBeginCalled = FALSE;
910 BOOTSTRAPPER_RELATION_TYPE relationType = pPlan->pCommand->relationType; 916 BOOTSTRAPPER_RELATION_TYPE relationType = pPlan->pCommand->relationType;
911 917
@@ -927,20 +933,28 @@ static HRESULT InitializePackage(
927 933
928 if (pPackage->sczInstallCondition && *pPackage->sczInstallCondition) 934 if (pPackage->sczInstallCondition && *pPackage->sczInstallCondition)
929 { 935 {
930 hr = ConditionEvaluate(pVariables, pPackage->sczInstallCondition, &fInstallCondition); 936 hr = ConditionEvaluate(pVariables, pPackage->sczInstallCondition, &fEvaluatedCondition);
931 ExitOnFailure(hr, "Failed to evaluate install condition."); 937 ExitOnFailure(hr, "Failed to evaluate install condition.");
932 938
933 installCondition = fInstallCondition ? BOOTSTRAPPER_PACKAGE_CONDITION_TRUE : BOOTSTRAPPER_PACKAGE_CONDITION_FALSE; 939 installCondition = fEvaluatedCondition ? BOOTSTRAPPER_PACKAGE_CONDITION_TRUE : BOOTSTRAPPER_PACKAGE_CONDITION_FALSE;
940 }
941
942 if (pPackage->sczRepairCondition && *pPackage->sczRepairCondition)
943 {
944 hr = ConditionEvaluate(pVariables, pPackage->sczRepairCondition, &fEvaluatedCondition);
945 ExitOnFailure(hr, "Failed to evaluate repair condition.");
946
947 repairCondition = fEvaluatedCondition ? BOOTSTRAPPER_PACKAGE_CONDITION_TRUE : BOOTSTRAPPER_PACKAGE_CONDITION_FALSE;
934 } 948 }
935 949
936 // Remember the default requested state so the engine doesn't get blamed for planning the wrong thing if the BA changes it. 950 // Remember the default requested state so the engine doesn't get blamed for planning the wrong thing if the BA changes it.
937 hr = PlanDefaultPackageRequestState(pPackage->type, pPackage->currentState, pPlan->action, installCondition, relationType, &pPackage->defaultRequested); 951 hr = PlanDefaultPackageRequestState(pPackage->type, pPackage->currentState, pPlan->action, installCondition, repairCondition, relationType, &pPackage->defaultRequested);
938 ExitOnFailure(hr, "Failed to set default package state."); 952 ExitOnFailure(hr, "Failed to set default package state.");
939 953
940 pPackage->requested = pPackage->defaultRequested; 954 pPackage->requested = pPackage->defaultRequested;
941 fBeginCalled = TRUE; 955 fBeginCalled = TRUE;
942 956
943 hr = UserExperienceOnPlanPackageBegin(pUX, pPackage->sczId, pPackage->currentState, pPackage->fCached, installCondition, &pPackage->requested, &pPackage->cacheType); 957 hr = UserExperienceOnPlanPackageBegin(pUX, pPackage->sczId, pPackage->currentState, pPackage->fCached, installCondition, repairCondition, &pPackage->requested, &pPackage->cacheType);
944 ExitOnRootFailure(hr, "BA aborted plan package begin."); 958 ExitOnRootFailure(hr, "BA aborted plan package begin.");
945 959
946 if (BURN_PACKAGE_TYPE_MSI == pPackage->type) 960 if (BURN_PACKAGE_TYPE_MSI == pPackage->type)
diff --git a/src/burn/engine/plan.h b/src/burn/engine/plan.h
index 87214cc8..fbb7a5a1 100644
--- a/src/burn/engine/plan.h
+++ b/src/burn/engine/plan.h
@@ -342,6 +342,7 @@ HRESULT PlanDefaultPackageRequestState(
342 __in BOOTSTRAPPER_PACKAGE_STATE currentState, 342 __in BOOTSTRAPPER_PACKAGE_STATE currentState,
343 __in BOOTSTRAPPER_ACTION action, 343 __in BOOTSTRAPPER_ACTION action,
344 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, 344 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
345 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition,
345 __in BOOTSTRAPPER_RELATION_TYPE relationType, 346 __in BOOTSTRAPPER_RELATION_TYPE relationType,
346 __out BOOTSTRAPPER_REQUEST_STATE* pRequestState 347 __out BOOTSTRAPPER_REQUEST_STATE* pRequestState
347 ); 348 );
diff --git a/src/burn/engine/userexperience.cpp b/src/burn/engine/userexperience.cpp
index a1a010d2..a3cbcd4a 100644
--- a/src/burn/engine/userexperience.cpp
+++ b/src/burn/engine/userexperience.cpp
@@ -2169,6 +2169,7 @@ EXTERN_C BAAPI UserExperienceOnPlanPackageBegin(
2169 __in BOOTSTRAPPER_PACKAGE_STATE state, 2169 __in BOOTSTRAPPER_PACKAGE_STATE state,
2170 __in BOOL fCached, 2170 __in BOOL fCached,
2171 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, 2171 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
2172 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition,
2172 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState, 2173 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState,
2173 __inout BOOTSTRAPPER_CACHE_TYPE* pRequestedCacheType 2174 __inout BOOTSTRAPPER_CACHE_TYPE* pRequestedCacheType
2174 ) 2175 )
@@ -2182,6 +2183,7 @@ EXTERN_C BAAPI UserExperienceOnPlanPackageBegin(
2182 args.state = state; 2183 args.state = state;
2183 args.fCached = fCached; 2184 args.fCached = fCached;
2184 args.installCondition = installCondition; 2185 args.installCondition = installCondition;
2186 args.repairCondition = repairCondition;
2185 args.recommendedState = *pRequestedState; 2187 args.recommendedState = *pRequestedState;
2186 args.recommendedCacheType = *pRequestedCacheType; 2188 args.recommendedCacheType = *pRequestedCacheType;
2187 2189
diff --git a/src/burn/engine/userexperience.h b/src/burn/engine/userexperience.h
index 90a047ed..2059b521 100644
--- a/src/burn/engine/userexperience.h
+++ b/src/burn/engine/userexperience.h
@@ -501,6 +501,7 @@ BAAPI UserExperienceOnPlanPackageBegin(
501 __in BOOTSTRAPPER_PACKAGE_STATE state, 501 __in BOOTSTRAPPER_PACKAGE_STATE state,
502 __in BOOL fCached, 502 __in BOOL fCached,
503 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, 503 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
504 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition,
504 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState, 505 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState,
505 __inout BOOTSTRAPPER_CACHE_TYPE* pRequestedCacheType 506 __inout BOOTSTRAPPER_CACHE_TYPE* pRequestedCacheType
506 ); 507 );
diff --git a/src/burn/test/BurnUnitTest/PlanTest.cpp b/src/burn/test/BurnUnitTest/PlanTest.cpp
index 87bbbffd..f69606a0 100644
--- a/src/burn/test/BurnUnitTest/PlanTest.cpp
+++ b/src/burn/test/BurnUnitTest/PlanTest.cpp
@@ -459,6 +459,101 @@ namespace Bootstrapper
459 } 459 }
460 460
461 [Fact] 461 [Fact]
462 void MultipleBundlePackageRepairTest()
463 {
464 HRESULT hr = S_OK;
465 BURN_ENGINE_STATE engineState = { };
466 BURN_ENGINE_STATE* pEngineState = &engineState;
467 BURN_PLAN* pPlan = &engineState.plan;
468
469 InitializeEngineStateForCorePlan(wzMultipleBundlePackageManifestFileName, pEngineState);
470 DetectAttachedContainerAsAttached(pEngineState);
471 DetectPackagesAsPresentAndCached(pEngineState);
472
473 hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_REPAIR);
474 NativeAssert::Succeeded(hr, "CorePlan failed");
475
476 Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_REPAIR, pPlan->action);
477 NativeAssert::StringEqual(L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}", pPlan->wzBundleId);
478 NativeAssert::StringEqual(L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}", pPlan->wzBundleProviderKey);
479 Assert::Equal<BOOL>(FALSE, pPlan->fEnabledForwardCompatibleBundle);
480 Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
481 Assert::Equal<BOOL>(TRUE, pPlan->fCanAffectMachineState);
482 Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
483 Assert::Equal<BOOL>(FALSE, pPlan->fDisallowRemoval);
484 Assert::Equal<BOOL>(FALSE, pPlan->fDowngrade);
485 Assert::Equal<DWORD>(BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE | BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_PROVIDER_KEY, pPlan->dwRegistrationOperations);
486
487 BOOL fRollback = FALSE;
488 DWORD dwIndex = 0;
489 Assert::Equal(dwIndex, pPlan->cRegistrationActions);
490
491 fRollback = TRUE;
492 dwIndex = 0;
493 Assert::Equal(dwIndex, pPlan->cRollbackRegistrationActions);
494
495 fRollback = FALSE;
496 dwIndex = 0;
497 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 2);
498 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageB");
499 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++);
500 Assert::Equal(dwIndex, pPlan->cCacheActions);
501
502 fRollback = TRUE;
503 dwIndex = 0;
504 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
505
506 Assert::Equal(18575450ull, pPlan->qwEstimatedSize);
507 Assert::Equal(52254105ull, pPlan->qwCacheSizeTotal);
508
509 fRollback = FALSE;
510 dwIndex = 0;
511 DWORD dwExecuteCheckpointId = 1;
512 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
513 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}", registerActions1, 1);
514 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
515 dwExecuteCheckpointId += 1; // cache checkpoints
516 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
517 ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageB");
518 ValidateExecuteBundlePackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_REPAIR, L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}");
519 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}", registerActions1, 1);
520 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
521 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
522 ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++);
523 Assert::Equal(dwIndex, pPlan->cExecuteActions);
524
525 fRollback = TRUE;
526 dwIndex = 0;
527 dwExecuteCheckpointId = 1;
528 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
529 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
530 dwExecuteCheckpointId += 1; // cache checkpoints
531 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
532 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
533 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
534 ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++);
535 Assert::Equal(dwIndex, pPlan->cRollbackActions);
536
537 Assert::Equal(1ul, pPlan->cExecutePackagesTotal);
538 Assert::Equal(2ul, pPlan->cOverallProgressTicksTotal);
539
540 dwIndex = 0;
541 Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions);
542
543 dwIndex = 0;
544 ValidateCleanAction(pPlan, dwIndex++, L"NetFx48Web");
545 Assert::Equal(dwIndex, pPlan->cCleanActions);
546
547 UINT uIndex = 0;
548 ValidatePlannedProvider(pPlan, uIndex++, L"{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}", NULL);
549 Assert::Equal(uIndex, pPlan->cPlannedProviders);
550
551 Assert::Equal(3ul, pEngineState->packages.cPackages);
552 ValidateNonPermanentPackageExpectedStates(&pEngineState->packages.rgPackages[1], L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, BURN_PACKAGE_REGISTRATION_STATE_PRESENT);
553 ValidateNonPermanentPackageExpectedStates(&pEngineState->packages.rgPackages[2], L"PackageB", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, BURN_PACKAGE_REGISTRATION_STATE_PRESENT);
554 }
555
556 [Fact]
462 void OrphanCompatiblePackageTest() 557 void OrphanCompatiblePackageTest()
463 { 558 {
464 HRESULT hr = S_OK; 559 HRESULT hr = S_OK;
diff --git a/src/burn/test/BurnUnitTest/TestData/PlanTest/BundlePackage_Multiple_manifest.xml b/src/burn/test/BurnUnitTest/TestData/PlanTest/BundlePackage_Multiple_manifest.xml
index 0b521faa..b02c2056 100644
--- a/src/burn/test/BurnUnitTest/TestData/PlanTest/BundlePackage_Multiple_manifest.xml
+++ b/src/burn/test/BurnUnitTest/TestData/PlanTest/BundlePackage_Multiple_manifest.xml
@@ -1 +1 @@
<?xml version="1.0" encoding="utf-8"?><BurnManifest xmlns="http://wixtoolset.org/schemas/v4/2008/Burn"><Log PathVariable="WixBundleLog" Prefix="~BundlePackageTests_MultipleBundlePackagesBundle" Extension=".log" /><RelatedBundle Id="{86D214FB-8D74-456C-99B3-6557ECA6159C}" Action="Upgrade" /><Variable Id="TestGroupName" Value="BundlePackageTests" Type="string" Hidden="no" Persisted="no" /><Variable Id="WixBundleInProgressName" Hidden="no" Persisted="yes" /><Variable Id="WixBundleName" Hidden="no" Persisted="yes" /><Variable Id="WixBundleOriginalSource" Hidden="no" Persisted="yes" /><Variable Id="WixBundleOriginalSourceFolder" Hidden="no" Persisted="yes" /><Variable Id="WixBundleLastUsedSource" Hidden="no" Persisted="yes" /><RegistrySearch Id="NETFRAMEWORK45" Variable="NETFRAMEWORK45" Root="HKLM" Key="SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" Value="Release" Type="value" VariableType="string" /><UX><Payload Id="WixManagedBootstrapperApplicationHost" FilePath="mbahost.dll" SourcePath="u30" /><Payload Id="payO60IVK4ATGzPpMz3rwVbUWl6DyU" FilePath="WixToolset.Mba.Host.config" SourcePath="u0" /><Payload Id="payxj4zDAKL2NVlz4ohp0GvwFHepyI" FilePath="TestBA.dll" SourcePath="u1" /><Payload Id="pay1hOSAUC8_D633cD2TXpIXCL30OU" FilePath="mbanative.dll" SourcePath="u2" /><Payload Id="payujy6Izl_BlUNfHt2eI.ADfjYAv4" FilePath="WixToolset.Mba.Core.dll" SourcePath="u3" /><Payload Id="payR4EbR4OTDZpPEycWaSSM_gZRBWM" FilePath="mbapreq.thm" SourcePath="u4" /><Payload Id="paylVCy2Ecl8pHPdJTCQZryUG4T9us" FilePath="mbapreq.png" SourcePath="u5" /><Payload Id="payTaG4B_lob1aLcKFaOqSSG3MPMpU" FilePath="mbapreq.wxl" SourcePath="u6" /><Payload Id="payZwIGuiezVTitZOoZKxyh2DdRSGs" FilePath="1028\mbapreq.wxl" SourcePath="u7" /><Payload Id="pay.herBWX.LlOh8jLsx24aWdunV_0" FilePath="1029\mbapreq.wxl" SourcePath="u8" /><Payload Id="pay8DkMszYsoxxdgX14huLDMYXylQg" FilePath="1030\mbapreq.wxl" SourcePath="u9" /><Payload Id="payPaHpoTeOdkW.TK99IDwktNLhTAg" FilePath="1031\mbapreq.wxl" SourcePath="u10" /><Payload Id="pay45AtAzterLTMzZgdxxtuYvaiXwU" FilePath="1032\mbapreq.wxl" SourcePath="u11" /><Payload Id="payA2VEKIqhePyNIEmr14eyH3JoVLc" FilePath="1035\mbapreq.wxl" SourcePath="u12" /><Payload Id="payvre23ObscjzhcaFIifUAkXMdPa8" FilePath="1036\mbapreq.wxl" SourcePath="u13" /><Payload Id="paytxUV3vuBbG2c.a9c.d_sZX2x6wA" FilePath="1038\mbapreq.wxl" SourcePath="u14" /><Payload Id="payYvMWRK9xelo5.sQn7jRkJIaBp9A" FilePath="1040\mbapreq.wxl" SourcePath="u15" /><Payload Id="pay68KKSApyQimbA25t6kSbqhdeH10" FilePath="1041\mbapreq.wxl" SourcePath="u16" /><Payload Id="paypiqxaHpYZqx.9eDVjQrj1igLbRY" FilePath="1042\mbapreq.wxl" SourcePath="u17" /><Payload Id="payTO0YwZzxKpbqdrBVUcVRTu3BFe8" FilePath="1043\mbapreq.wxl" SourcePath="u18" /><Payload Id="payIXg2ldBJukRzhqWolJVOEbTmF34" FilePath="1044\mbapreq.wxl" SourcePath="u19" /><Payload Id="payOHIZbSkIvrpwKkkXI173tv3u3B4" FilePath="1045\mbapreq.wxl" SourcePath="u20" /><Payload Id="payQRQ_UZl_R2UtV0xDXB2yeH2bg3E" FilePath="1046\mbapreq.wxl" SourcePath="u21" /><Payload Id="payhrejLLBfc1i27iN._QPhQ4K337I" FilePath="1049\mbapreq.wxl" SourcePath="u22" /><Payload Id="payqEzaDNzxB68vGp29jgDcCos6dvg" FilePath="1051\mbapreq.wxl" SourcePath="u23" /><Payload Id="paydz8Vk8xSTyYohgGXTSIxWGXL5.Q" FilePath="1053\mbapreq.wxl" SourcePath="u24" /><Payload Id="pay0HRUZTlbC3taSOffJBsEj92Br8Y" FilePath="1055\mbapreq.wxl" SourcePath="u25" /><Payload Id="payIvUOkc_EMH7laMFehefNolV8hZo" FilePath="1060\mbapreq.wxl" SourcePath="u26" /><Payload Id="payLFhOb.rHuk4sW5CYAPMShG0NjGI" FilePath="2052\mbapreq.wxl" SourcePath="u27" /><Payload Id="payqIKCmERK7Nhxx_nNXvRxdKqKDbI" FilePath="2070\mbapreq.wxl" SourcePath="u28" /><Payload Id="payqeWUzIVaEqjuRXN0z8ECC3Y4tCc" FilePath="3082\mbapreq.wxl" SourcePath="u29" /><Payload Id="paylfeHEjJSSTnNzY9QMZM2Ye3Ipy4" FilePath="mbapreq.dll" SourcePath="u31" /><Payload Id="payDPxs6uy8nbky.R7zhir2RRAfc.c" FilePath="WixToolset.Mba.Host.dll" SourcePath="u32" /><Payload Id="uxTxMXPVMXwQrPTMIGa5WGt93w0Ns" FilePath="BootstrapperApplicationData.xml" SourcePath="u33" /><Payload Id="uxYRbgitOs0K878jn5L_z7LdJ21KI" FilePath="BundleExtensionData.xml" SourcePath="u34" /></UX><Container Id="WixAttachedContainer" FileSize="15696370" Hash="0F9966B421400E481D394DB4C4D7F0F92548E5BEB79B98880C926E817E8C1F381EC8A17053E2E66AE7132A3C9ECE441629E6A1FB3452C5C9282280C40252F141" FilePath="MultipleBundlePackagesBundle.exe" AttachedIndex="1" Attached="yes" Primary="yes" /><Payload Id="NetFx48Web" FilePath="redist\ndp48-web.exe" FileSize="1439328" CertificateRootPublicKeyIdentifier="F49F9B33E25E33CCA0BFB15A62B7C29FFAB3880B" CertificateRootThumbprint="ABDCA79AF9DD48A0EA702AD45260B3C03093FB4B" DownloadUrl="https://go.microsoft.com/fwlink/?LinkId=2085155" Packaging="external" SourcePath="redist\ndp48-web.exe" /><Payload Id="PackageA" FilePath="BundleA.exe" FileSize="5241635" Hash="20E1AFF76DE4693CB2876DC6BCCA0152DB16BE49AEDE2CD581C03FC39AB89DEA12BC25CB435F06E4D7D2B4443CE8A8935D5E92E2E49A4981B60A273980E4B29B" Packaging="embedded" SourcePath="a0" Container="WixAttachedContainer" /><Payload Id="PackageB" FilePath="BundleB_x64.exe" FileSize="10450821" Hash="43A58873D61D6E0FA83F6C5266F2F05FEA9BC85D11C195493B7FD9F0B4AA799C1EFCB78D76DCED32124D2EC62A4E7114B62CDE6F0B87E42A7E28CDBB0DA0FF8E" Packaging="embedded" SourcePath="a1" Container="WixAttachedContainer" /><RollbackBoundary Id="WixDefaultBoundary" Vital="yes" Transaction="no" /><Registration Id="{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}" ExecutableName="MultipleBundlePackagesBundle.exe" PerMachine="yes" Tag="" Version="1.0.0.0" ProviderKey="{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}"><Arp Register="yes" DisplayName="~BundlePackageTests - MultipleBundlePackagesBundle" DisplayVersion="1.0.0.0" /></Registration><Chain><ExePackage Id="NetFx48Web" Cache="remove" CacheId="642721C60D52051C7F3434D8710FE3406A7CFE10B2B39E90EA847719ED1697D7C614F2DF44AD50412B1DF8C98DD78FDC57CA1D047D28C81AC158092E5FB18040" InstallSize="1439328" Size="1439328" PerMachine="yes" Permanent="yes" Vital="yes" RollbackBoundaryForward="WixDefaultBoundary" LogPathVariable="NetFx48WebLog" RollbackLogPathVariable="WixBundleRollbackLog_NetFx48Web" DetectCondition="NETFRAMEWORK45 &gt;= 528040" InstallArguments="/q /norestart /log &quot;[NetFx48WebLog].html&quot;" UninstallArguments="" Uninstallable="no" RepairArguments="" Repairable="no" Protocol="netfx4"><PayloadRef Id="NetFx48Web" /></ExePackage><BundlePackage Id="PackageA" Cache="keep" CacheId="{B39CEE4D-CCD7-4797-BE3A-6613BD1DC4BE}v1.0.0.0" InstallSize="2169" Size="5241635" Version="1.0.0.0" PerMachine="yes" Permanent="no" Vital="yes" LogPathVariable="WixBundleLog_PackageA" RollbackLogPathVariable="WixBundleRollbackLog_PackageA" BundleId="{B39CEE4D-CCD7-4797-BE3A-6613BD1DC4BE}" InstallArguments="" UninstallArguments="" RepairArguments="" SupportsBurnProtocol="yes" Win64="no"><Provides Key="{B39CEE4D-CCD7-4797-BE3A-6613BD1DC4BE}" Version="1.0.0.0" DisplayName="~BasicFunctionalityTests - BundleA" Imported="yes" /><RelatedBundle Id="{8C7E2C47-1EE7-4BBE-99A2-EAB7F3693F48}" Action="Upgrade" /><PayloadRef Id="PackageA" /></BundlePackage><BundlePackage Id="PackageB" Cache="keep" CacheId="{7506235A-7C59-4750-82C7-EB460A87ED3A}v1.0.0.0" InstallSize="1441497" Size="10450821" Version="1.0.0.0" PerMachine="yes" Permanent="no" Vital="yes" RollbackBoundaryBackward="WixDefaultBoundary" LogPathVariable="WixBundleLog_PackageB" RollbackLogPathVariable="WixBundleRollbackLog_PackageB" BundleId="{7506235A-7C59-4750-82C7-EB460A87ED3A}" InstallArguments="" UninstallArguments="" RepairArguments="" SupportsBurnProtocol="yes" Win64="yes"><Provides Key="{7506235A-7C59-4750-82C7-EB460A87ED3A}" Version="1.0.0.0" DisplayName="~BasicFunctionalityTests - BundleB_x64" Imported="yes" /><RelatedBundle Id="{79F45B7A-D990-46E4-819B-078D87C3321A}" Action="Upgrade" /><PayloadRef Id="PackageB" /></BundlePackage></Chain><CommandLine Variables="upperCase" /></BurnManifest> <?xml version="1.0" encoding="utf-8"?><BurnManifest xmlns="http://wixtoolset.org/schemas/v4/2008/Burn"><Log PathVariable="WixBundleLog" Prefix="~BundlePackageTests_MultipleBundlePackagesBundle" Extension=".log" /><RelatedBundle Id="{86D214FB-8D74-456C-99B3-6557ECA6159C}" Action="Upgrade" /><Variable Id="TestGroupName" Value="BundlePackageTests" Type="string" Hidden="no" Persisted="no" /><Variable Id="WixBundleInProgressName" Hidden="no" Persisted="yes" /><Variable Id="WixBundleName" Hidden="no" Persisted="yes" /><Variable Id="WixBundleOriginalSource" Hidden="no" Persisted="yes" /><Variable Id="WixBundleOriginalSourceFolder" Hidden="no" Persisted="yes" /><Variable Id="WixBundleLastUsedSource" Hidden="no" Persisted="yes" /><RegistrySearch Id="NETFRAMEWORK45" Variable="NETFRAMEWORK45" Root="HKLM" Key="SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full" Value="Release" Type="value" VariableType="string" /><UX><Payload Id="WixManagedBootstrapperApplicationHost" FilePath="mbahost.dll" SourcePath="u30" /><Payload Id="payO60IVK4ATGzPpMz3rwVbUWl6DyU" FilePath="WixToolset.Mba.Host.config" SourcePath="u0" /><Payload Id="payxj4zDAKL2NVlz4ohp0GvwFHepyI" FilePath="TestBA.dll" SourcePath="u1" /><Payload Id="pay1hOSAUC8_D633cD2TXpIXCL30OU" FilePath="mbanative.dll" SourcePath="u2" /><Payload Id="payujy6Izl_BlUNfHt2eI.ADfjYAv4" FilePath="WixToolset.Mba.Core.dll" SourcePath="u3" /><Payload Id="payR4EbR4OTDZpPEycWaSSM_gZRBWM" FilePath="mbapreq.thm" SourcePath="u4" /><Payload Id="paylVCy2Ecl8pHPdJTCQZryUG4T9us" FilePath="mbapreq.png" SourcePath="u5" /><Payload Id="payTaG4B_lob1aLcKFaOqSSG3MPMpU" FilePath="mbapreq.wxl" SourcePath="u6" /><Payload Id="payZwIGuiezVTitZOoZKxyh2DdRSGs" FilePath="1028\mbapreq.wxl" SourcePath="u7" /><Payload Id="pay.herBWX.LlOh8jLsx24aWdunV_0" FilePath="1029\mbapreq.wxl" SourcePath="u8" /><Payload Id="pay8DkMszYsoxxdgX14huLDMYXylQg" FilePath="1030\mbapreq.wxl" SourcePath="u9" /><Payload Id="payPaHpoTeOdkW.TK99IDwktNLhTAg" FilePath="1031\mbapreq.wxl" SourcePath="u10" /><Payload Id="pay45AtAzterLTMzZgdxxtuYvaiXwU" FilePath="1032\mbapreq.wxl" SourcePath="u11" /><Payload Id="payA2VEKIqhePyNIEmr14eyH3JoVLc" FilePath="1035\mbapreq.wxl" SourcePath="u12" /><Payload Id="payvre23ObscjzhcaFIifUAkXMdPa8" FilePath="1036\mbapreq.wxl" SourcePath="u13" /><Payload Id="paytxUV3vuBbG2c.a9c.d_sZX2x6wA" FilePath="1038\mbapreq.wxl" SourcePath="u14" /><Payload Id="payYvMWRK9xelo5.sQn7jRkJIaBp9A" FilePath="1040\mbapreq.wxl" SourcePath="u15" /><Payload Id="pay68KKSApyQimbA25t6kSbqhdeH10" FilePath="1041\mbapreq.wxl" SourcePath="u16" /><Payload Id="paypiqxaHpYZqx.9eDVjQrj1igLbRY" FilePath="1042\mbapreq.wxl" SourcePath="u17" /><Payload Id="payTO0YwZzxKpbqdrBVUcVRTu3BFe8" FilePath="1043\mbapreq.wxl" SourcePath="u18" /><Payload Id="payIXg2ldBJukRzhqWolJVOEbTmF34" FilePath="1044\mbapreq.wxl" SourcePath="u19" /><Payload Id="payOHIZbSkIvrpwKkkXI173tv3u3B4" FilePath="1045\mbapreq.wxl" SourcePath="u20" /><Payload Id="payQRQ_UZl_R2UtV0xDXB2yeH2bg3E" FilePath="1046\mbapreq.wxl" SourcePath="u21" /><Payload Id="payhrejLLBfc1i27iN._QPhQ4K337I" FilePath="1049\mbapreq.wxl" SourcePath="u22" /><Payload Id="payqEzaDNzxB68vGp29jgDcCos6dvg" FilePath="1051\mbapreq.wxl" SourcePath="u23" /><Payload Id="paydz8Vk8xSTyYohgGXTSIxWGXL5.Q" FilePath="1053\mbapreq.wxl" SourcePath="u24" /><Payload Id="pay0HRUZTlbC3taSOffJBsEj92Br8Y" FilePath="1055\mbapreq.wxl" SourcePath="u25" /><Payload Id="payIvUOkc_EMH7laMFehefNolV8hZo" FilePath="1060\mbapreq.wxl" SourcePath="u26" /><Payload Id="payLFhOb.rHuk4sW5CYAPMShG0NjGI" FilePath="2052\mbapreq.wxl" SourcePath="u27" /><Payload Id="payqIKCmERK7Nhxx_nNXvRxdKqKDbI" FilePath="2070\mbapreq.wxl" SourcePath="u28" /><Payload Id="payqeWUzIVaEqjuRXN0z8ECC3Y4tCc" FilePath="3082\mbapreq.wxl" SourcePath="u29" /><Payload Id="paylfeHEjJSSTnNzY9QMZM2Ye3Ipy4" FilePath="mbapreq.dll" SourcePath="u31" /><Payload Id="payDPxs6uy8nbky.R7zhir2RRAfc.c" FilePath="WixToolset.Mba.Host.dll" SourcePath="u32" /><Payload Id="uxTxMXPVMXwQrPTMIGa5WGt93w0Ns" FilePath="BootstrapperApplicationData.xml" SourcePath="u33" /><Payload Id="uxYRbgitOs0K878jn5L_z7LdJ21KI" FilePath="BundleExtensionData.xml" SourcePath="u34" /></UX><Container Id="WixAttachedContainer" FileSize="15696370" Hash="0F9966B421400E481D394DB4C4D7F0F92548E5BEB79B98880C926E817E8C1F381EC8A17053E2E66AE7132A3C9ECE441629E6A1FB3452C5C9282280C40252F141" FilePath="MultipleBundlePackagesBundle.exe" AttachedIndex="1" Attached="yes" Primary="yes" /><Payload Id="NetFx48Web" FilePath="redist\ndp48-web.exe" FileSize="1439328" CertificateRootPublicKeyIdentifier="F49F9B33E25E33CCA0BFB15A62B7C29FFAB3880B" CertificateRootThumbprint="ABDCA79AF9DD48A0EA702AD45260B3C03093FB4B" DownloadUrl="https://go.microsoft.com/fwlink/?LinkId=2085155" Packaging="external" SourcePath="redist\ndp48-web.exe" /><Payload Id="PackageA" FilePath="BundleA.exe" FileSize="5241635" Hash="20E1AFF76DE4693CB2876DC6BCCA0152DB16BE49AEDE2CD581C03FC39AB89DEA12BC25CB435F06E4D7D2B4443CE8A8935D5E92E2E49A4981B60A273980E4B29B" Packaging="embedded" SourcePath="a0" Container="WixAttachedContainer" /><Payload Id="PackageB" FilePath="BundleB_x64.exe" FileSize="10450821" Hash="43A58873D61D6E0FA83F6C5266F2F05FEA9BC85D11C195493B7FD9F0B4AA799C1EFCB78D76DCED32124D2EC62A4E7114B62CDE6F0B87E42A7E28CDBB0DA0FF8E" Packaging="embedded" SourcePath="a1" Container="WixAttachedContainer" /><RollbackBoundary Id="WixDefaultBoundary" Vital="yes" Transaction="no" /><Registration Id="{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}" ExecutableName="MultipleBundlePackagesBundle.exe" PerMachine="yes" Tag="" Version="1.0.0.0" ProviderKey="{35192ED0-C70A-49B2-9D12-3B1FA39B5E6F}"><Arp Register="yes" DisplayName="~BundlePackageTests - MultipleBundlePackagesBundle" DisplayVersion="1.0.0.0" /></Registration><Chain><ExePackage Id="NetFx48Web" Cache="remove" CacheId="642721C60D52051C7F3434D8710FE3406A7CFE10B2B39E90EA847719ED1697D7C614F2DF44AD50412B1DF8C98DD78FDC57CA1D047D28C81AC158092E5FB18040" InstallSize="1439328" Size="1439328" PerMachine="yes" Permanent="yes" Vital="yes" RollbackBoundaryForward="WixDefaultBoundary" LogPathVariable="NetFx48WebLog" RollbackLogPathVariable="WixBundleRollbackLog_NetFx48Web" DetectCondition="NETFRAMEWORK45 &gt;= 528040" InstallArguments="/q /norestart /log &quot;[NetFx48WebLog].html&quot;" UninstallArguments="" Uninstallable="no" RepairArguments="" Repairable="no" Protocol="netfx4"><PayloadRef Id="NetFx48Web" /></ExePackage><BundlePackage Id="PackageA" Cache="keep" CacheId="{B39CEE4D-CCD7-4797-BE3A-6613BD1DC4BE}v1.0.0.0" InstallSize="2169" Size="5241635" Version="1.0.0.0" PerMachine="yes" Permanent="no" Vital="yes" RepairCondition="0" LogPathVariable="WixBundleLog_PackageA" RollbackLogPathVariable="WixBundleRollbackLog_PackageA" BundleId="{B39CEE4D-CCD7-4797-BE3A-6613BD1DC4BE}" InstallArguments="" UninstallArguments="" RepairArguments="" SupportsBurnProtocol="yes" Win64="no"><Provides Key="{B39CEE4D-CCD7-4797-BE3A-6613BD1DC4BE}" Version="1.0.0.0" DisplayName="~BasicFunctionalityTests - BundleA" Imported="yes" /><RelatedBundle Id="{8C7E2C47-1EE7-4BBE-99A2-EAB7F3693F48}" Action="Upgrade" /><PayloadRef Id="PackageA" /></BundlePackage><BundlePackage Id="PackageB" Cache="keep" CacheId="{7506235A-7C59-4750-82C7-EB460A87ED3A}v1.0.0.0" InstallSize="1441497" Size="10450821" Version="1.0.0.0" PerMachine="yes" Permanent="no" Vital="yes" RollbackBoundaryBackward="WixDefaultBoundary" LogPathVariable="WixBundleLog_PackageB" RollbackLogPathVariable="WixBundleRollbackLog_PackageB" BundleId="{7506235A-7C59-4750-82C7-EB460A87ED3A}" InstallArguments="" UninstallArguments="" RepairArguments="" SupportsBurnProtocol="yes" Win64="yes"><Provides Key="{7506235A-7C59-4750-82C7-EB460A87ED3A}" Version="1.0.0.0" DisplayName="~BasicFunctionalityTests - BundleB_x64" Imported="yes" /><RelatedBundle Id="{79F45B7A-D990-46E4-819B-078D87C3321A}" Action="Upgrade" /><PayloadRef Id="PackageB" /></BundlePackage></Chain><CommandLine Variables="upperCase" /></BurnManifest>
diff --git a/src/burn/test/BurnUnitTest/VariableTest.cpp b/src/burn/test/BurnUnitTest/VariableTest.cpp
index d0361c0e..1d5fc6f3 100644
--- a/src/burn/test/BurnUnitTest/VariableTest.cpp
+++ b/src/burn/test/BurnUnitTest/VariableTest.cpp
@@ -388,6 +388,7 @@ namespace Bootstrapper
388 Assert::True(EvaluateFailureConditionHelper(&variables, L"1A")); 388 Assert::True(EvaluateFailureConditionHelper(&variables, L"1A"));
389 Assert::True(EvaluateFailureConditionHelper(&variables, L"*")); 389 Assert::True(EvaluateFailureConditionHelper(&variables, L"*"));
390 390
391 Assert::False(EvaluateFailureConditionHelper(&variables, L"0"));
391 Assert::True(EvaluateFailureConditionHelper(&variables, L"1 == 1")); 392 Assert::True(EvaluateFailureConditionHelper(&variables, L"1 == 1"));
392 } 393 }
393 finally 394 finally
diff --git a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
index 969aca9d..e93dbe90 100644
--- a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
+++ b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
@@ -425,6 +425,7 @@ public: // IBootstrapperApplication
425 __in BOOTSTRAPPER_PACKAGE_STATE state, 425 __in BOOTSTRAPPER_PACKAGE_STATE state,
426 __in BOOL fCached, 426 __in BOOL fCached,
427 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, 427 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
428 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT repairCondition,
428 __in BOOTSTRAPPER_REQUEST_STATE recommendedState, 429 __in BOOTSTRAPPER_REQUEST_STATE recommendedState,
429 __in BOOTSTRAPPER_CACHE_TYPE recommendedCacheType, 430 __in BOOTSTRAPPER_CACHE_TYPE recommendedCacheType,
430 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestState, 431 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestState,
@@ -485,7 +486,7 @@ public: // IBootstrapperApplication
485 } 486 }
486 } 487 }
487 488
488 return CBalBaseBootstrapperApplication::OnPlanPackageBegin(wzPackageId, state, fCached, installCondition, recommendedState, recommendedCacheType, pRequestState, pRequestedCacheType, pfCancel); 489 return CBalBaseBootstrapperApplication::OnPlanPackageBegin(wzPackageId, state, fCached, installCondition, repairCondition, recommendedState, recommendedCacheType, pRequestState, pRequestedCacheType, pfCancel);
489 } 490 }
490 491
491 492
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs
index 39347d19..3167ccd3 100644
--- a/src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs
@@ -206,6 +206,11 @@ namespace WixToolset.Core.Burn.Bundles
206 writer.WriteAttributeString("InstallCondition", package.PackageSymbol.InstallCondition); 206 writer.WriteAttributeString("InstallCondition", package.PackageSymbol.InstallCondition);
207 } 207 }
208 208
209 if (!String.IsNullOrEmpty(package.PackageSymbol.RepairCondition))
210 {
211 writer.WriteAttributeString("RepairCondition", package.PackageSymbol.RepairCondition);
212 }
213
209 switch (package.PackageSymbol.Cache) 214 switch (package.PackageSymbol.Cache)
210 { 215 {
211 case BundleCacheType.Remove: 216 case BundleCacheType.Remove:
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
index 68f5002f..78e02534 100644
--- a/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
@@ -389,6 +389,11 @@ namespace WixToolset.Core.Burn.Bundles
389 writer.WriteAttributeString("InstallCondition", package.PackageSymbol.InstallCondition); 389 writer.WriteAttributeString("InstallCondition", package.PackageSymbol.InstallCondition);
390 } 390 }
391 391
392 if (!String.IsNullOrEmpty(package.PackageSymbol.RepairCondition))
393 {
394 writer.WriteAttributeString("RepairCondition", package.PackageSymbol.RepairCondition);
395 }
396
392 if (package.SpecificPackageSymbol is WixBundleBundlePackageSymbol bundlePackage) // BUNDLE 397 if (package.SpecificPackageSymbol is WixBundleBundlePackageSymbol bundlePackage) // BUNDLE
393 { 398 {
394 writer.WriteAttributeString("BundleId", bundlePackage.BundleId); 399 writer.WriteAttributeString("BundleId", bundlePackage.BundleId);
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs
index 3ffb8df4..5d9acb4a 100644
--- a/src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bundles/PerformBundleBackendValidationCommand.cs
@@ -91,6 +91,11 @@ namespace WixToolset.Core.Burn.Bundles
91 { 91 {
92 this.BackendHelper.ValidateBundleCondition(symbol.SourceLineNumbers, elementName, "InstallCondition", symbol.InstallCondition, BundleConditionPhase.Plan); 92 this.BackendHelper.ValidateBundleCondition(symbol.SourceLineNumbers, elementName, "InstallCondition", symbol.InstallCondition, BundleConditionPhase.Plan);
93 } 93 }
94
95 if (!String.IsNullOrEmpty(symbol.RepairCondition))
96 {
97 this.BackendHelper.ValidateBundleCondition(symbol.SourceLineNumbers, elementName, "RepairCondition", symbol.RepairCondition, BundleConditionPhase.Plan);
98 }
94 } 99 }
95 100
96 private void ValidateBundlePackage(WixBundleBundlePackageSymbol symbol, WixBundlePackageSymbol packageSymbol) 101 private void ValidateBundlePackage(WixBundleBundlePackageSymbol symbol, WixBundlePackageSymbol packageSymbol)
diff --git a/src/wix/WixToolset.Core/Compiler_Bundle.cs b/src/wix/WixToolset.Core/Compiler_Bundle.cs
index 4cbfe58a..bd1d70f3 100644
--- a/src/wix/WixToolset.Core/Compiler_Bundle.cs
+++ b/src/wix/WixToolset.Core/Compiler_Bundle.cs
@@ -2003,6 +2003,7 @@ namespace WixToolset.Core
2003 }; 2003 };
2004 string after = null; 2004 string after = null;
2005 string installCondition = null; 2005 string installCondition = null;
2006 string repairCondition = null;
2006 var cache = BundleCacheType.Keep; // the default is to cache everything in tradeoff for stability over disk space. 2007 var cache = BundleCacheType.Keep; // the default is to cache everything in tradeoff for stability over disk space.
2007 string cacheId = null; 2008 string cacheId = null;
2008 string description = null; 2009 string description = null;
@@ -2061,6 +2062,10 @@ namespace WixToolset.Core
2061 case "InstallCondition": 2062 case "InstallCondition":
2062 installCondition = this.Core.GetAttributeValue(sourceLineNumbers, attrib); 2063 installCondition = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2063 break; 2064 break;
2065 case "RepairCondition":
2066 repairCondition = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2067 allowed = (packageType != WixBundlePackageType.Msu);
2068 break;
2064 case "Cache": 2069 case "Cache":
2065 var value = this.Core.GetAttributeValue(sourceLineNumbers, attrib); 2070 var value = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
2066 switch (value) 2071 switch (value)
@@ -2262,6 +2267,11 @@ namespace WixToolset.Core
2262 } 2267 }
2263 } 2268 }
2264 2269
2270 if (repairArguments == null && repairCondition != null)
2271 {
2272 this.Core.Write(ErrorMessages.ExpectedAttributeWithValueWithOtherAttribute(sourceLineNumbers, node.Name.LocalName, "RepairArguments", "RepairCondition"));
2273 }
2274
2265 // Validate the protocol if provided. 2275 // Validate the protocol if provided.
2266 if (!String.IsNullOrEmpty(protocol)) 2276 if (!String.IsNullOrEmpty(protocol))
2267 { 2277 {
@@ -2429,6 +2439,7 @@ namespace WixToolset.Core
2429 Type = packageType, 2439 Type = packageType,
2430 Attributes = attributes, 2440 Attributes = attributes,
2431 InstallCondition = installCondition, 2441 InstallCondition = installCondition,
2442 RepairCondition = repairCondition,
2432 Cache = cache, 2443 Cache = cache,
2433 CacheId = cacheId, 2444 CacheId = cacheId,
2434 Description = description, 2445 Description = description,
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs
index 08ffea33..368cd961 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/BundleManifestFixture.cs
@@ -88,7 +88,7 @@ namespace WixToolsetTest.CoreIntegration
88 { "WixPackageProperties", new List<string> { "DownloadSize", "PackageSize", "InstalledSize", "Version" } }, 88 { "WixPackageProperties", new List<string> { "DownloadSize", "PackageSize", "InstalledSize", "Version" } },
89 }; 89 };
90 Assert.Equal(3, packageElements.Count); 90 Assert.Equal(3, packageElements.Count);
91 Assert.Equal("<WixPackageProperties Package='burn.exe' Vital='yes' DisplayName='Windows Installer XML Toolset' Description='WiX Toolset Bootstrapper' DownloadSize='*' PackageSize='*' InstalledSize='*' PackageType='Exe' Permanent='yes' LogPathVariable='WixBundleLog_burn.exe' RollbackLogPathVariable='WixBundleRollbackLog_burn.exe' Compressed='yes' Version='*' Cache='keep' />", packageElements[0].GetTestXml(ignoreAttributesByElementName)); 91 Assert.Equal("<WixPackageProperties Package='burn.exe' Vital='yes' DisplayName='Windows Installer XML Toolset' Description='WiX Toolset Bootstrapper' DownloadSize='*' PackageSize='*' InstalledSize='*' PackageType='Exe' Permanent='yes' LogPathVariable='WixBundleLog_burn.exe' RollbackLogPathVariable='WixBundleRollbackLog_burn.exe' Compressed='yes' Version='*' RepairCondition='RepairRedists' Cache='keep' />", packageElements[0].GetTestXml(ignoreAttributesByElementName));
92 Assert.Equal("<WixPackageProperties Package='RemotePayloadExe' Vital='yes' DisplayName='Override RemotePayload display name' Description='Override RemotePayload description' DownloadSize='1' PackageSize='1' InstalledSize='1' PackageType='Exe' Permanent='yes' LogPathVariable='WixBundleLog_RemotePayloadExe' RollbackLogPathVariable='WixBundleRollbackLog_RemotePayloadExe' Compressed='no' Version='1.0.0.0' Cache='keep' />", packageElements[1].GetTestXml()); 92 Assert.Equal("<WixPackageProperties Package='RemotePayloadExe' Vital='yes' DisplayName='Override RemotePayload display name' Description='Override RemotePayload description' DownloadSize='1' PackageSize='1' InstalledSize='1' PackageType='Exe' Permanent='yes' LogPathVariable='WixBundleLog_RemotePayloadExe' RollbackLogPathVariable='WixBundleRollbackLog_RemotePayloadExe' Compressed='no' Version='1.0.0.0' Cache='keep' />", packageElements[1].GetTestXml());
93 Assert.Equal("<WixPackageProperties Package='calc.exe' Vital='yes' DisplayName='Override harvested display name' Description='Override harvested description' DownloadSize='*' PackageSize='*' InstalledSize='*' PackageType='Exe' Permanent='yes' LogPathVariable='WixBundleLog_calc.exe' RollbackLogPathVariable='WixBundleRollbackLog_calc.exe' Compressed='yes' Version='*' Cache='keep' />", packageElements[2].GetTestXml(ignoreAttributesByElementName)); 93 Assert.Equal("<WixPackageProperties Package='calc.exe' Vital='yes' DisplayName='Override harvested display name' Description='Override harvested description' DownloadSize='*' PackageSize='*' InstalledSize='*' PackageType='Exe' Permanent='yes' LogPathVariable='WixBundleLog_calc.exe' RollbackLogPathVariable='WixBundleRollbackLog_calc.exe' Compressed='yes' Version='*' Cache='keep' />", packageElements[2].GetTestXml(ignoreAttributesByElementName));
94 } 94 }
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/BundlePackageFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/BundlePackageFixture.cs
index 621d0871..63659936 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/BundlePackageFixture.cs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/BundlePackageFixture.cs
@@ -354,7 +354,7 @@ namespace WixToolsetTest.CoreIntegration
354 .ToArray(); 354 .ToArray();
355 WixAssert.CompareLineByLine(new string[] 355 WixAssert.CompareLineByLine(new string[]
356 { 356 {
357 $"<BundlePackage Id='v3bundle.exe' Cache='keep' CacheId='{chainBundleId}v1.0.0.0' InstallSize='1135' Size='*' PerMachine='yes' Permanent='no' Vital='yes' RollbackBoundaryForward='WixDefaultBoundary' RollbackBoundaryBackward='WixDefaultBoundary' LogPathVariable='WixBundleLog_v3bundle.exe' RollbackLogPathVariable='WixBundleRollbackLog_v3bundle.exe' BundleId='{chainBundleId}' Version='1.0.0.0' InstallArguments='' UninstallArguments='' RepairArguments='' SupportsBurnProtocol='yes' Win64='no'>" + 357 $"<BundlePackage Id='v3bundle.exe' Cache='keep' CacheId='{chainBundleId}v1.0.0.0' InstallSize='1135' Size='*' PerMachine='yes' Permanent='no' Vital='yes' RollbackBoundaryForward='WixDefaultBoundary' RollbackBoundaryBackward='WixDefaultBoundary' LogPathVariable='WixBundleLog_v3bundle.exe' RollbackLogPathVariable='WixBundleRollbackLog_v3bundle.exe' RepairCondition='0' BundleId='{chainBundleId}' Version='1.0.0.0' InstallArguments='' UninstallArguments='' RepairArguments='' SupportsBurnProtocol='yes' Win64='no'>" +
358 "<Provides Key='{215a70db-ab35-48c7-be51-d66eaac87177}' Version='1.0.0.0' DisplayName='CustomV3Theme' Imported='yes' />" + 358 "<Provides Key='{215a70db-ab35-48c7-be51-d66eaac87177}' Version='1.0.0.0' DisplayName='CustomV3Theme' Imported='yes' />" +
359 "<RelatedBundle Id='{2BF4C01F-C132-4E70-97AB-2BC68C7CCD10}' Action='Upgrade' />" + 359 "<RelatedBundle Id='{2BF4C01F-C132-4E70-97AB-2BC68C7CCD10}' Action='Upgrade' />" +
360 "<PayloadRef Id='v3bundle.exe' />" + 360 "<PayloadRef Id='v3bundle.exe' />" +
@@ -382,7 +382,7 @@ namespace WixToolsetTest.CoreIntegration
382 .ToArray(); 382 .ToArray();
383 WixAssert.CompareLineByLine(new string[] 383 WixAssert.CompareLineByLine(new string[]
384 { 384 {
385 "<WixPackageProperties Package='v3bundle.exe' Vital='yes' DisplayName='CustomV3Theme' Description='CustomV3Theme' DownloadSize='*' PackageSize='*' InstalledSize='1135' PackageType='Bundle' Permanent='no' LogPathVariable='WixBundleLog_v3bundle.exe' RollbackLogPathVariable='WixBundleRollbackLog_v3bundle.exe' Compressed='yes' Version='1.0.0.0' Cache='keep' />", 385 "<WixPackageProperties Package='v3bundle.exe' Vital='yes' DisplayName='CustomV3Theme' Description='CustomV3Theme' DownloadSize='*' PackageSize='*' InstalledSize='1135' PackageType='Bundle' Permanent='no' LogPathVariable='WixBundleLog_v3bundle.exe' RollbackLogPathVariable='WixBundleRollbackLog_v3bundle.exe' Compressed='yes' Version='1.0.0.0' RepairCondition='0' Cache='keep' />",
386 }, packageElements); 386 }, packageElements);
387 } 387 }
388 } 388 }
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/ExePackageFixture.cs b/src/wix/test/WixToolsetTest.CoreIntegration/ExePackageFixture.cs
index 15885b94..67f295e8 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/ExePackageFixture.cs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/ExePackageFixture.cs
@@ -36,6 +36,30 @@ namespace WixToolsetTest.CoreIntegration
36 } 36 }
37 37
38 [Fact] 38 [Fact]
39 public void ErrorWhenRepairConditionWithoutRepairArguments()
40 {
41 var folder = TestData.Get(@"TestData", "ExePackage");
42
43 using (var fs = new DisposableFileSystem())
44 {
45 var baseFolder = fs.GetFolder();
46
47 var result = WixRunner.Execute(new[]
48 {
49 "build",
50 Path.Combine(folder, "RepairConditionWithoutRepairArguments.wxs"),
51 "-o", Path.Combine(baseFolder, "test.wixlib")
52 });
53
54 WixAssert.CompareLineByLine(new[]
55 {
56 "The ExePackage/@RepairArguments attribute is required to have a value when attribute RepairCondition is present.",
57 }, result.Messages.Select(m => m.ToString()).ToArray());
58 Assert.Equal(401, result.ExitCode);
59 }
60 }
61
62 [Fact]
39 public void ErrorWhenRequireDetectCondition() 63 public void ErrorWhenRequireDetectCondition()
40 { 64 {
41 var folder = TestData.Get(@"TestData", "ExePackage"); 65 var folder = TestData.Get(@"TestData", "ExePackage");
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundlePackage/V3BundlePackage.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundlePackage/V3BundlePackage.wxs
index 192bb6d7..36a36618 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundlePackage/V3BundlePackage.wxs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/BundlePackage/V3BundlePackage.wxs
@@ -4,7 +4,7 @@
4 <BootstrapperApplicationDll SourceFile="fakeba.dll" /> 4 <BootstrapperApplicationDll SourceFile="fakeba.dll" />
5 </BootstrapperApplication> 5 </BootstrapperApplication>
6 <Chain> 6 <Chain>
7 <BundlePackage SourceFile="v3bundle.exe" /> 7 <BundlePackage SourceFile="v3bundle.exe" RepairCondition="0" />
8 </Chain> 8 </Chain>
9 </Bundle> 9 </Bundle>
10</Wix> 10</Wix>
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/CustomPackageDescription/CustomPackageDescription.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/CustomPackageDescription/CustomPackageDescription.wxs
index 10c4f91f..47284d1f 100644
--- a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/CustomPackageDescription/CustomPackageDescription.wxs
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/CustomPackageDescription/CustomPackageDescription.wxs
@@ -2,7 +2,7 @@
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs"> 2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 <Fragment> 3 <Fragment>
4 <PackageGroup Id="BundlePackages"> 4 <PackageGroup Id="BundlePackages">
5 <ExePackage DetectCondition="ForTestPurposesOnly" SourceFile="burn.exe" Permanent="yes" /> 5 <ExePackage DetectCondition="ForTestPurposesOnly" SourceFile="burn.exe" Permanent="yes" RepairArguments="-repair" RepairCondition="RepairRedists" />
6 <ExePackage Id="RemotePayloadExe" DetectCondition="ForTestPurposesOnly" Description="Override RemotePayload description" DisplayName="Override RemotePayload display name" Permanent="yes"> 6 <ExePackage Id="RemotePayloadExe" DetectCondition="ForTestPurposesOnly" Description="Override RemotePayload description" DisplayName="Override RemotePayload display name" Permanent="yes">
7 <ExePackagePayload Description="RemotePayload description" Hash="a" ProductName="RemotePayload product name" Size="1" Version="1.0.0.0" Name="fake.exe" DownloadUrl="example.com" /> 7 <ExePackagePayload Description="RemotePayload description" Hash="a" ProductName="RemotePayload product name" Size="1" Version="1.0.0.0" Name="fake.exe" DownloadUrl="example.com" />
8 </ExePackage> 8 </ExePackage>
diff --git a/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/RepairConditionWithoutRepairArguments.wxs b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/RepairConditionWithoutRepairArguments.wxs
new file mode 100644
index 00000000..764e7a5a
--- /dev/null
+++ b/src/wix/test/WixToolsetTest.CoreIntegration/TestData/ExePackage/RepairConditionWithoutRepairArguments.wxs
@@ -0,0 +1,12 @@
1<?xml version="1.0" encoding="utf-8"?>
2<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
3 <Fragment>
4 <PackageGroup Id="TestPackageGroup">
5 <ExePackage RepairCondition="0"
6 InstallArguments="-install"
7 Permanent="yes"
8 DetectCondition="fake"
9 SourceFile="testsetup.exe" />
10 </PackageGroup>
11 </Fragment>
12</Wix>