aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2022-03-04 17:55:17 -0600
committerSean Hall <r.sean.hall@gmail.com>2022-03-05 16:22:04 -0600
commite027c6c571a4bc8c818244e2b0c5015eb4ef3110 (patch)
tree8149aa491766bfe8a883f921831a52133abceea5
parentbaf09c19c5a0f0d3f9533f9084f094066c1be7d9 (diff)
downloadwix-e027c6c571a4bc8c818244e2b0c5015eb4ef3110.tar.gz
wix-e027c6c571a4bc8c818244e2b0c5015eb4ef3110.tar.bz2
wix-e027c6c571a4bc8c818244e2b0c5015eb4ef3110.zip
Change ARP property Installed to 0 when registrationType is InProgress.
Being registered in ARP and "installed" were always separate concepts, and some things like fEligibleForCleanup were looking at the wrong thing. This also allows the BA to tell the difference.
-rw-r--r--src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h2
-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.cs2
-rw-r--r--src/api/burn/balutil/inc/BalBaseBAFunctions.h2
-rw-r--r--src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h2
-rw-r--r--src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h2
-rw-r--r--src/api/burn/balutil/inc/IBootstrapperApplication.h2
-rw-r--r--src/burn/engine/core.cpp27
-rw-r--r--src/burn/engine/detect.cpp2
-rw-r--r--src/burn/engine/engine.mc2
-rw-r--r--src/burn/engine/plan.cpp4
-rw-r--r--src/burn/engine/plan.h2
-rw-r--r--src/burn/engine/registration.cpp57
-rw-r--r--src/burn/engine/registration.h6
-rw-r--r--src/burn/engine/userexperience.cpp6
-rw-r--r--src/burn/engine/userexperience.h2
-rw-r--r--src/burn/engine/variable.cpp4
-rw-r--r--src/burn/test/BurnUnitTest/PlanTest.cpp6
-rw-r--r--src/burn/test/BurnUnitTest/RegistrationTest.cpp6
-rw-r--r--src/ext/Bal/Samples/bafunctions/WixSampleBAFunctions.cpp4
-rw-r--r--src/test/burn/WixToolset.WixBA/InstallationViewModel.cs6
22 files changed, 86 insertions, 72 deletions
diff --git a/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h b/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
index 5c6258d0..9a5fb8f8 100644
--- a/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
+++ b/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
@@ -642,7 +642,7 @@ struct BA_ONCOMMITMSITRANSACTIONCOMPLETE_RESULTS
642struct BA_ONDETECTBEGIN_ARGS 642struct BA_ONDETECTBEGIN_ARGS
643{ 643{
644 DWORD cbSize; 644 DWORD cbSize;
645 BOOL fInstalled; 645 BOOTSTRAPPER_REGISTRATION_TYPE registrationType;
646 DWORD cPackages; 646 DWORD cPackages;
647 BOOL fCached; 647 BOOL fCached;
648}; 648};
diff --git a/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs b/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs
index b08e66c0..1df992be 100644
--- a/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs
+++ b/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs
@@ -1378,9 +1378,9 @@ namespace WixToolset.Mba.Core
1378 return args.HResult; 1378 return args.HResult;
1379 } 1379 }
1380 1380
1381 int IBootstrapperApplication.OnDetectBegin(bool fCached, bool fInstalled, int cPackages, ref bool fCancel) 1381 int IBootstrapperApplication.OnDetectBegin(bool fCached, RegistrationType registrationType, int cPackages, ref bool fCancel)
1382 { 1382 {
1383 DetectBeginEventArgs args = new DetectBeginEventArgs(fCached, fInstalled, cPackages, fCancel); 1383 DetectBeginEventArgs args = new DetectBeginEventArgs(fCached, registrationType, cPackages, fCancel);
1384 this.OnDetectBegin(args); 1384 this.OnDetectBegin(args);
1385 1385
1386 fCancel = args.Cancel; 1386 fCancel = args.Cancel;
diff --git a/src/api/burn/WixToolset.Mba.Core/EventArgs.cs b/src/api/burn/WixToolset.Mba.Core/EventArgs.cs
index 2e1e1be3..816757cc 100644
--- a/src/api/burn/WixToolset.Mba.Core/EventArgs.cs
+++ b/src/api/burn/WixToolset.Mba.Core/EventArgs.cs
@@ -249,11 +249,11 @@ namespace WixToolset.Mba.Core
249 public class DetectBeginEventArgs : CancellableHResultEventArgs 249 public class DetectBeginEventArgs : CancellableHResultEventArgs
250 { 250 {
251 /// <summary /> 251 /// <summary />
252 public DetectBeginEventArgs(bool cached, bool installed, int packageCount, bool cancelRecommendation) 252 public DetectBeginEventArgs(bool cached, RegistrationType registrationType, int packageCount, bool cancelRecommendation)
253 : base(cancelRecommendation) 253 : base(cancelRecommendation)
254 { 254 {
255 this.Cached = cached; 255 this.Cached = cached;
256 this.Installed = installed; 256 this.RegistrationType = registrationType;
257 this.PackageCount = packageCount; 257 this.PackageCount = packageCount;
258 } 258 }
259 259
@@ -263,9 +263,9 @@ namespace WixToolset.Mba.Core
263 public bool Cached { get; private set; } 263 public bool Cached { get; private set; }
264 264
265 /// <summary> 265 /// <summary>
266 /// Gets whether the bundle is installed. 266 /// Gets the bundle's registration state.
267 /// </summary> 267 /// </summary>
268 public bool Installed { get; private set; } 268 public RegistrationType RegistrationType { get; private set; }
269 269
270 /// <summary> 270 /// <summary>
271 /// Gets the number of packages to detect. 271 /// Gets the number of packages to detect.
diff --git a/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs b/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs
index 4fbe5e18..489e3b6d 100644
--- a/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs
+++ b/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs
@@ -70,7 +70,7 @@ namespace WixToolset.Mba.Core
70 [return: MarshalAs(UnmanagedType.I4)] 70 [return: MarshalAs(UnmanagedType.I4)]
71 int OnDetectBegin( 71 int OnDetectBegin(
72 [MarshalAs(UnmanagedType.Bool)] bool fCached, 72 [MarshalAs(UnmanagedType.Bool)] bool fCached,
73 [MarshalAs(UnmanagedType.Bool)] bool fInstalled, 73 [MarshalAs(UnmanagedType.U4)] RegistrationType registrationType,
74 [MarshalAs(UnmanagedType.U4)] int cPackages, 74 [MarshalAs(UnmanagedType.U4)] int cPackages,
75 [MarshalAs(UnmanagedType.Bool)] ref bool fCancel 75 [MarshalAs(UnmanagedType.Bool)] ref bool fCancel
76 ); 76 );
diff --git a/src/api/burn/balutil/inc/BalBaseBAFunctions.h b/src/api/burn/balutil/inc/BalBaseBAFunctions.h
index e98ebc9f..60a70e3e 100644
--- a/src/api/burn/balutil/inc/BalBaseBAFunctions.h
+++ b/src/api/burn/balutil/inc/BalBaseBAFunctions.h
@@ -108,7 +108,7 @@ public: // IBootstrapperApplication
108 108
109 virtual STDMETHODIMP OnDetectBegin( 109 virtual STDMETHODIMP OnDetectBegin(
110 __in BOOL /*fCached*/, 110 __in BOOL /*fCached*/,
111 __in BOOL /*fInstalled*/, 111 __in BOOTSTRAPPER_REGISTRATION_TYPE /*registrationType*/,
112 __in DWORD /*cPackages*/, 112 __in DWORD /*cPackages*/,
113 __inout BOOL* /*pfCancel*/ 113 __inout BOOL* /*pfCancel*/
114 ) 114 )
diff --git a/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h b/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h
index 6a24f24b..7b3cf827 100644
--- a/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h
+++ b/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h
@@ -109,7 +109,7 @@ public: // IBootstrapperApplication
109 109
110 virtual STDMETHODIMP OnDetectBegin( 110 virtual STDMETHODIMP OnDetectBegin(
111 __in BOOL /*fCached*/, 111 __in BOOL /*fCached*/,
112 __in BOOL /*fInstalled*/, 112 __in BOOTSTRAPPER_REGISTRATION_TYPE /*registrationType*/,
113 __in DWORD /*cPackages*/, 113 __in DWORD /*cPackages*/,
114 __inout BOOL* pfCancel 114 __inout BOOL* pfCancel
115 ) 115 )
diff --git a/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h b/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h
index d40390e5..8c3b8b72 100644
--- a/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h
+++ b/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h
@@ -15,7 +15,7 @@ static HRESULT BalBaseBAProcOnDetectBegin(
15 __inout BA_ONDETECTBEGIN_RESULTS* pResults 15 __inout BA_ONDETECTBEGIN_RESULTS* pResults
16 ) 16 )
17{ 17{
18 return pBA->OnDetectBegin(pArgs->fCached, pArgs->fInstalled, pArgs->cPackages, &pResults->fCancel); 18 return pBA->OnDetectBegin(pArgs->fCached, pArgs->registrationType, pArgs->cPackages, &pResults->fCancel);
19} 19}
20 20
21static HRESULT BalBaseBAProcOnDetectComplete( 21static HRESULT BalBaseBAProcOnDetectComplete(
diff --git a/src/api/burn/balutil/inc/IBootstrapperApplication.h b/src/api/burn/balutil/inc/IBootstrapperApplication.h
index 5932c06e..e916d41e 100644
--- a/src/api/burn/balutil/inc/IBootstrapperApplication.h
+++ b/src/api/burn/balutil/inc/IBootstrapperApplication.h
@@ -42,7 +42,7 @@ DECLARE_INTERFACE_IID_(IBootstrapperApplication, IUnknown, "53C31D56-49C0-426B-A
42 // OnDetectBegin - called when the engine begins detection. 42 // OnDetectBegin - called when the engine begins detection.
43 STDMETHOD(OnDetectBegin)( 43 STDMETHOD(OnDetectBegin)(
44 __in BOOL fCached, 44 __in BOOL fCached,
45 __in BOOL fInstalled, 45 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType,
46 __in DWORD cPackages, 46 __in DWORD cPackages,
47 __inout BOOL* pfCancel 47 __inout BOOL* pfCancel
48 ) = 0; 48 ) = 0;
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp
index 9d5364a4..ca4d607b 100644
--- a/src/burn/engine/core.cpp
+++ b/src/burn/engine/core.cpp
@@ -315,26 +315,19 @@ extern "C" HRESULT CoreDetect(
315 DetectReset(&pEngineState->registration, &pEngineState->packages); 315 DetectReset(&pEngineState->registration, &pEngineState->packages);
316 PlanReset(&pEngineState->plan, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads); 316 PlanReset(&pEngineState->plan, &pEngineState->containers, &pEngineState->packages, &pEngineState->layoutPayloads);
317 317
318 // Detect if bundle installed state has changed since start up. This 318 // Detect if bundle installed state has changed since start up.
319 // only happens if Apply() changed the state of bundle (installed or 319 // This only happens if Apply() changed the state of bundle (installed, in progress, or uninstalled).
320 // uninstalled). In that case, Detect() can be used here to reset 320 // In that case, Detect() can be used here to reset the installed state.
321 // the installed state. 321 // Of course, there's also cases outside of this bundle's control,
322 // like other processes messing with its registration.
322 hr = RegistrationDetectInstalled(&pEngineState->registration); 323 hr = RegistrationDetectInstalled(&pEngineState->registration);
323 ExitOnFailure(hr, "Failed to detect bundle install state."); 324 ExitOnFailure(hr, "Failed to detect bundle install state.");
324 325
325 if (pEngineState->registration.fInstalled) 326 hr = RegistrationSetDynamicVariables(&pEngineState->registration, &pEngineState->variables);
326 { 327 ExitOnFailure(hr, "Failed to reset the dynamic registration variables during detect.");
327 hr = VariableSetNumeric(&pEngineState->variables, BURN_BUNDLE_INSTALLED, 1, TRUE);
328 ExitOnFailure(hr, "Failed to set the bundle installed built-in variable.");
329 }
330 else
331 {
332 hr = VariableSetString(&pEngineState->variables, BURN_BUNDLE_INSTALLED, NULL, TRUE, FALSE);
333 ExitOnFailure(hr, "Failed to unset the bundle installed built-in variable.");
334 }
335 328
336 fDetectBegan = TRUE; 329 fDetectBegan = TRUE;
337 hr = UserExperienceOnDetectBegin(&pEngineState->userExperience, pEngineState->registration.fCached, pEngineState->registration.fInstalled, pEngineState->packages.cPackages); 330 hr = UserExperienceOnDetectBegin(&pEngineState->userExperience, pEngineState->registration.fCached, pEngineState->registration.detectedRegistrationType, pEngineState->packages.cPackages);
338 ExitOnRootFailure(hr, "UX aborted detect begin."); 331 ExitOnRootFailure(hr, "UX aborted detect begin.");
339 332
340 pEngineState->userExperience.hwndDetect = hwndParent; 333 pEngineState->userExperience.hwndDetect = hwndParent;
@@ -444,7 +437,7 @@ LExit:
444 437
445 pEngineState->userExperience.hwndDetect = NULL; 438 pEngineState->userExperience.hwndDetect = NULL;
446 439
447 LogId(REPORT_STANDARD, MSG_DETECT_COMPLETE, hr, !fDetectBegan ? "(failed)" : LoggingBoolToString(pEngineState->registration.fInstalled), !fDetectBegan ? "(failed)" : LoggingBoolToString(pEngineState->registration.fCached), FAILED(hr) ? "(failed)" : LoggingBoolToString(pEngineState->registration.fEligibleForCleanup)); 440 LogId(REPORT_STANDARD, MSG_DETECT_COMPLETE, hr, !fDetectBegan ? "(failed)" : LoggingRegistrationTypeToString(pEngineState->registration.detectedRegistrationType), !fDetectBegan ? "(failed)" : LoggingBoolToString(pEngineState->registration.fCached), FAILED(hr) ? "(failed)" : LoggingBoolToString(pEngineState->registration.fEligibleForCleanup));
448 441
449 return hr; 442 return hr;
450} 443}
@@ -489,7 +482,7 @@ extern "C" HRESULT CorePlan(
489 pEngineState->plan.wzBundleId = pEngineState->registration.sczId; 482 pEngineState->plan.wzBundleId = pEngineState->registration.sczId;
490 pEngineState->plan.wzBundleProviderKey = pEngineState->registration.sczId; 483 pEngineState->plan.wzBundleProviderKey = pEngineState->registration.sczId;
491 pEngineState->plan.fDisableRollback = pEngineState->fDisableRollback || BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL == pEngineState->plan.action; 484 pEngineState->plan.fDisableRollback = pEngineState->fDisableRollback || BOOTSTRAPPER_ACTION_UNSAFE_UNINSTALL == pEngineState->plan.action;
492 pEngineState->plan.fBundleAlreadyRegistered = pEngineState->registration.fInstalled; 485 pEngineState->plan.fPlanPackageCacheRollback = BOOTSTRAPPER_REGISTRATION_TYPE_NONE == pEngineState->registration.detectedRegistrationType;
493 486
494 hr = PlanSetVariables(action, &pEngineState->variables); 487 hr = PlanSetVariables(action, &pEngineState->variables);
495 ExitOnFailure(hr, "Failed to update action."); 488 ExitOnFailure(hr, "Failed to update action.");
diff --git a/src/burn/engine/detect.cpp b/src/burn/engine/detect.cpp
index 3bd39784..f7a030ff 100644
--- a/src/burn/engine/detect.cpp
+++ b/src/burn/engine/detect.cpp
@@ -165,7 +165,7 @@ extern "C" HRESULT DetectReportRelatedBundles(
165{ 165{
166 HRESULT hr = S_OK; 166 HRESULT hr = S_OK;
167 BOOTSTRAPPER_REQUEST_STATE uninstallRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; 167 BOOTSTRAPPER_REQUEST_STATE uninstallRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
168 *pfEligibleForCleanup = pRegistration->fInstalled || pRegistration->fCached; 168 *pfEligibleForCleanup = BOOTSTRAPPER_REGISTRATION_TYPE_NONE != pRegistration->detectedRegistrationType || pRegistration->fCached;
169 169
170 for (DWORD iRelatedBundle = 0; iRelatedBundle < pRegistration->relatedBundles.cRelatedBundles; ++iRelatedBundle) 170 for (DWORD iRelatedBundle = 0; iRelatedBundle < pRegistration->relatedBundles.cRelatedBundles; ++iRelatedBundle)
171 { 171 {
diff --git a/src/burn/engine/engine.mc b/src/burn/engine/engine.mc
index 4425af12..6a826365 100644
--- a/src/burn/engine/engine.mc
+++ b/src/burn/engine/engine.mc
@@ -335,7 +335,7 @@ MessageId=199
335Severity=Success 335Severity=Success
336SymbolicName=MSG_DETECT_COMPLETE 336SymbolicName=MSG_DETECT_COMPLETE
337Language=English 337Language=English
338Detect complete, result: 0x%1!x!, installed: %2!hs!, cached: %3!hs!, eligible for cleanup: %4!hs! 338Detect complete, result: 0x%1!x!, registration state: %2!hs!, cached: %3!hs!, eligible for cleanup: %4!hs!
339. 339.
340 340
341MessageId=200 341MessageId=200
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp
index 49dd83f4..c9337df5 100644
--- a/src/burn/engine/plan.cpp
+++ b/src/burn/engine/plan.cpp
@@ -1692,7 +1692,7 @@ extern "C" HRESULT PlanExecuteCacheSyncAndRollback(
1692 HRESULT hr = S_OK; 1692 HRESULT hr = S_OK;
1693 BURN_EXECUTE_ACTION* pAction = NULL; 1693 BURN_EXECUTE_ACTION* pAction = NULL;
1694 1694
1695 if (!pPlan->fBundleAlreadyRegistered) 1695 if (pPlan->fPlanPackageCacheRollback)
1696 { 1696 {
1697 hr = PlanAppendRollbackAction(pPlan, &pAction); 1697 hr = PlanAppendRollbackAction(pPlan, &pAction);
1698 ExitOnFailure(hr, "Failed to append rollback action."); 1698 ExitOnFailure(hr, "Failed to append rollback action.");
@@ -2241,7 +2241,7 @@ static HRESULT AddCachePackageHelper(
2241 pCacheAction->type = BURN_CACHE_ACTION_TYPE_CHECKPOINT; 2241 pCacheAction->type = BURN_CACHE_ACTION_TYPE_CHECKPOINT;
2242 pCacheAction->checkpoint.dwId = dwCheckpoint; 2242 pCacheAction->checkpoint.dwId = dwCheckpoint;
2243 2243
2244 if (!pPlan->fBundleAlreadyRegistered) 2244 if (pPlan->fPlanPackageCacheRollback)
2245 { 2245 {
2246 // Create a package cache rollback action *before* the checkpoint. 2246 // Create a package cache rollback action *before* the checkpoint.
2247 hr = AppendRollbackCacheAction(pPlan, &pCacheAction); 2247 hr = AppendRollbackCacheAction(pPlan, &pCacheAction);
diff --git a/src/burn/engine/plan.h b/src/burn/engine/plan.h
index c0936970..63bcd3ce 100644
--- a/src/burn/engine/plan.h
+++ b/src/burn/engine/plan.h
@@ -249,7 +249,7 @@ typedef struct _BURN_PLAN
249 BOOL fDisableRollback; 249 BOOL fDisableRollback;
250 BOOL fAffectedMachineState; 250 BOOL fAffectedMachineState;
251 LPWSTR sczLayoutDirectory; 251 LPWSTR sczLayoutDirectory;
252 BOOL fBundleAlreadyRegistered; 252 BOOL fPlanPackageCacheRollback;
253 253
254 DWORD64 qwCacheSizeTotal; 254 DWORD64 qwCacheSizeTotal;
255 255
diff --git a/src/burn/engine/registration.cpp b/src/burn/engine/registration.cpp
index a1b1b607..fcefe5e0 100644
--- a/src/burn/engine/registration.cpp
+++ b/src/burn/engine/registration.cpp
@@ -69,6 +69,7 @@ static HRESULT UpdateResumeMode(
69 __in BURN_REGISTRATION* pRegistration, 69 __in BURN_REGISTRATION* pRegistration,
70 __in HKEY hkRegistration, 70 __in HKEY hkRegistration,
71 __in BURN_RESUME_MODE resumeMode, 71 __in BURN_RESUME_MODE resumeMode,
72 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType,
72 __in BOOL fRestartInitiated 73 __in BOOL fRestartInitiated
73 ); 74 );
74static HRESULT ParseRelatedCodes( 75static HRESULT ParseRelatedCodes(
@@ -444,11 +445,8 @@ extern "C" HRESULT RegistrationSetVariables(
444 HRESULT hr = S_OK; 445 HRESULT hr = S_OK;
445 LPWSTR scz = NULL; 446 LPWSTR scz = NULL;
446 447
447 if (pRegistration->fInstalled) 448 hr = RegistrationSetDynamicVariables(pRegistration, pVariables);
448 { 449 ExitOnFailure(hr, "Failed to set the dynamic registration variables.");
449 hr = VariableSetNumeric(pVariables, BURN_BUNDLE_INSTALLED, 1, TRUE);
450 ExitOnFailure(hr, "Failed to set the bundle installed built-in variable.");
451 }
452 450
453 // Ensure the registration bundle name is updated. 451 // Ensure the registration bundle name is updated.
454 hr = GetBundleInProgressName(pRegistration, pVariables, &scz); 452 hr = GetBundleInProgressName(pRegistration, pVariables, &scz);
@@ -469,12 +467,32 @@ extern "C" HRESULT RegistrationSetVariables(
469 hr = VariableSetVersion(pVariables, BURN_BUNDLE_VERSION, pRegistration->pVersion, TRUE); 467 hr = VariableSetVersion(pVariables, BURN_BUNDLE_VERSION, pRegistration->pVersion, TRUE);
470 ExitOnFailure(hr, "Failed to overwrite the bundle version built-in variable."); 468 ExitOnFailure(hr, "Failed to overwrite the bundle version built-in variable.");
471 469
470LExit:
471 ReleaseStr(scz);
472
473 return hr;
474}
475
476/*******************************************************************
477 RegistrationSetDynamicVariables - Initializes bundle variables that
478 map to registration entities that can change during execution.
479
480*******************************************************************/
481extern "C" HRESULT RegistrationSetDynamicVariables(
482 __in BURN_REGISTRATION* pRegistration,
483 __in BURN_VARIABLES* pVariables
484 )
485{
486 HRESULT hr = S_OK;
487 LONGLONG llInstalled = BOOTSTRAPPER_REGISTRATION_TYPE_FULL == pRegistration->detectedRegistrationType ? 1 : 0;
488
489 hr = VariableSetNumeric(pVariables, BURN_BUNDLE_INSTALLED, llInstalled, TRUE);
490 ExitOnFailure(hr, "Failed to set the bundle installed built-in variable.");
491
472 hr = VariableSetNumeric(pVariables, BURN_REBOOT_PENDING, IsWuRebootPending() || IsRegistryRebootPending(), TRUE); 492 hr = VariableSetNumeric(pVariables, BURN_REBOOT_PENDING, IsWuRebootPending() || IsRegistryRebootPending(), TRUE);
473 ExitOnFailure(hr, "Failed to overwrite the bundle reboot-pending built-in variable."); 493 ExitOnFailure(hr, "Failed to overwrite the bundle reboot-pending built-in variable.");
474 494
475LExit: 495LExit:
476 ReleaseStr(scz);
477
478 return hr; 496 return hr;
479} 497}
480 498
@@ -487,12 +505,15 @@ extern "C" HRESULT RegistrationDetectInstalled(
487 DWORD dwInstalled = 0; 505 DWORD dwInstalled = 0;
488 506
489 pRegistration->fCached = FileExistsEx(pRegistration->sczCacheExecutablePath, NULL); 507 pRegistration->fCached = FileExistsEx(pRegistration->sczCacheExecutablePath, NULL);
508 pRegistration->detectedRegistrationType = BOOTSTRAPPER_REGISTRATION_TYPE_NONE;
490 509
491 // open registration key 510 // open registration key
492 hr = RegOpen(pRegistration->hkRoot, pRegistration->sczRegistrationKey, KEY_QUERY_VALUE, &hkRegistration); 511 hr = RegOpen(pRegistration->hkRoot, pRegistration->sczRegistrationKey, KEY_QUERY_VALUE, &hkRegistration);
493 if (SUCCEEDED(hr)) 512 if (SUCCEEDED(hr))
494 { 513 {
495 hr = RegReadNumber(hkRegistration, REGISTRY_BUNDLE_INSTALLED, &dwInstalled); 514 hr = RegReadNumber(hkRegistration, REGISTRY_BUNDLE_INSTALLED, &dwInstalled);
515
516 pRegistration->detectedRegistrationType = (1 == dwInstalled) ? BOOTSTRAPPER_REGISTRATION_TYPE_FULL : BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS;
496 } 517 }
497 518
498 // Not finding the key or value is okay. 519 // Not finding the key or value is okay.
@@ -501,8 +522,6 @@ extern "C" HRESULT RegistrationDetectInstalled(
501 hr = S_OK; 522 hr = S_OK;
502 } 523 }
503 524
504 pRegistration->fInstalled = (1 == dwInstalled);
505
506 ReleaseRegKey(hkRegistration); 525 ReleaseRegKey(hkRegistration);
507 return hr; 526 return hr;
508} 527}
@@ -833,7 +852,7 @@ extern "C" HRESULT RegistrationSessionBegin(
833 } 852 }
834 853
835 // update resume mode 854 // update resume mode
836 hr = UpdateResumeMode(pRegistration, hkRegistration, BURN_RESUME_MODE_ACTIVE, FALSE); 855 hr = UpdateResumeMode(pRegistration, hkRegistration, BURN_RESUME_MODE_ACTIVE, registrationType, FALSE);
837 ExitOnFailure(hr, "Failed to update resume mode."); 856 ExitOnFailure(hr, "Failed to update resume mode.");
838 857
839LExit: 858LExit:
@@ -864,7 +883,7 @@ extern "C" HRESULT RegistrationSessionResume(
864 ExitOnFailure(hr, "Failed to open registration key."); 883 ExitOnFailure(hr, "Failed to open registration key.");
865 884
866 // update resume mode 885 // update resume mode
867 hr = UpdateResumeMode(pRegistration, hkRegistration, BURN_RESUME_MODE_ACTIVE, FALSE); 886 hr = UpdateResumeMode(pRegistration, hkRegistration, BURN_RESUME_MODE_ACTIVE, registrationType, FALSE);
868 ExitOnFailure(hr, "Failed to update resume mode."); 887 ExitOnFailure(hr, "Failed to update resume mode.");
869 888
870 // update display name 889 // update display name
@@ -934,7 +953,7 @@ extern "C" HRESULT RegistrationSessionEnd(
934 } 953 }
935 954
936 // Update resume mode. 955 // Update resume mode.
937 hr = UpdateResumeMode(pRegistration, hkRegistration, resumeMode, BOOTSTRAPPER_APPLY_RESTART_INITIATED == restart); 956 hr = UpdateResumeMode(pRegistration, hkRegistration, resumeMode, registrationType, BOOTSTRAPPER_APPLY_RESTART_INITIATED == restart);
938 ExitOnFailure(hr, "Failed to update resume mode."); 957 ExitOnFailure(hr, "Failed to update resume mode.");
939 958
940LExit: 959LExit:
@@ -1271,6 +1290,7 @@ static HRESULT UpdateResumeMode(
1271 __in BURN_REGISTRATION* pRegistration, 1290 __in BURN_REGISTRATION* pRegistration,
1272 __in HKEY hkRegistration, 1291 __in HKEY hkRegistration,
1273 __in BURN_RESUME_MODE resumeMode, 1292 __in BURN_RESUME_MODE resumeMode,
1293 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType,
1274 __in BOOL fRestartInitiated 1294 __in BOOL fRestartInitiated
1275 ) 1295 )
1276{ 1296{
@@ -1289,16 +1309,9 @@ static HRESULT UpdateResumeMode(
1289 hr = RegWriteNumber(hkRegistration, L"Resume", (DWORD)resumeMode); 1309 hr = RegWriteNumber(hkRegistration, L"Resume", (DWORD)resumeMode);
1290 ExitOnFailure(hr, "Failed to write Resume value."); 1310 ExitOnFailure(hr, "Failed to write Resume value.");
1291 1311
1292 // Write the Installed value *only* when the mode is ARP. This will tell us 1312 // Write Installed value.
1293 // that the bundle considers itself "installed" on the machine. Note that we 1313 hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_INSTALLED, BOOTSTRAPPER_REGISTRATION_TYPE_FULL == registrationType ? 1 : 0);
1294 // never change the value to "0" after that. The bundle will be considered 1314 ExitOnFailure(hr, "Failed to write Installed value.");
1295 // "uninstalled" when all of the registration is removed.
1296 if (BURN_RESUME_MODE_ARP == resumeMode)
1297 {
1298 // Write Installed value.
1299 hr = RegWriteNumber(hkRegistration, REGISTRY_BUNDLE_INSTALLED, 1);
1300 ExitOnFailure(hr, "Failed to write Installed value.");
1301 }
1302 } 1315 }
1303 1316
1304 // If the engine is active write the run key so we resume if there is an unexpected 1317 // If the engine is active write the run key so we resume if there is an unexpected
diff --git a/src/burn/engine/registration.h b/src/burn/engine/registration.h
index 64191828..bfaab1f1 100644
--- a/src/burn/engine/registration.h
+++ b/src/burn/engine/registration.h
@@ -93,7 +93,7 @@ typedef struct _BURN_REGISTRATION
93 BOOL fRegisterArp; 93 BOOL fRegisterArp;
94 BOOL fDisableResume; 94 BOOL fDisableResume;
95 BOOL fCached; 95 BOOL fCached;
96 BOOL fInstalled; 96 BOOTSTRAPPER_REGISTRATION_TYPE detectedRegistrationType;
97 LPWSTR sczId; 97 LPWSTR sczId;
98 LPWSTR sczTag; 98 LPWSTR sczTag;
99 99
@@ -171,6 +171,10 @@ HRESULT RegistrationSetVariables(
171 __in BURN_REGISTRATION* pRegistration, 171 __in BURN_REGISTRATION* pRegistration,
172 __in BURN_VARIABLES* pVariables 172 __in BURN_VARIABLES* pVariables
173 ); 173 );
174HRESULT RegistrationSetDynamicVariables(
175 __in BURN_REGISTRATION* pRegistration,
176 __in BURN_VARIABLES* pVariables
177 );
174HRESULT RegistrationDetectInstalled( 178HRESULT RegistrationDetectInstalled(
175 __in BURN_REGISTRATION* pRegistration 179 __in BURN_REGISTRATION* pRegistration
176 ); 180 );
diff --git a/src/burn/engine/userexperience.cpp b/src/burn/engine/userexperience.cpp
index a2f33f80..f299772b 100644
--- a/src/burn/engine/userexperience.cpp
+++ b/src/burn/engine/userexperience.cpp
@@ -104,7 +104,7 @@ extern "C" HRESULT UserExperienceLoad(
104 args.pCommand = pCommand; 104 args.pCommand = pCommand;
105 args.pfnBootstrapperEngineProc = EngineForApplicationProc; 105 args.pfnBootstrapperEngineProc = EngineForApplicationProc;
106 args.pvBootstrapperEngineProcContext = pEngineContext; 106 args.pvBootstrapperEngineProcContext = pEngineContext;
107 args.qwEngineAPIVersion = MAKEQWORDVERSION(2022, 2, 22, 0); 107 args.qwEngineAPIVersion = MAKEQWORDVERSION(2022, 3, 4, 0);
108 108
109 results.cbSize = sizeof(BOOTSTRAPPER_CREATE_RESULTS); 109 results.cbSize = sizeof(BOOTSTRAPPER_CREATE_RESULTS);
110 110
@@ -988,7 +988,7 @@ LExit:
988EXTERN_C BAAPI UserExperienceOnDetectBegin( 988EXTERN_C BAAPI UserExperienceOnDetectBegin(
989 __in BURN_USER_EXPERIENCE* pUserExperience, 989 __in BURN_USER_EXPERIENCE* pUserExperience,
990 __in BOOL fCached, 990 __in BOOL fCached,
991 __in BOOL fInstalled, 991 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType,
992 __in DWORD cPackages 992 __in DWORD cPackages
993 ) 993 )
994{ 994{
@@ -998,7 +998,7 @@ EXTERN_C BAAPI UserExperienceOnDetectBegin(
998 998
999 args.cbSize = sizeof(args); 999 args.cbSize = sizeof(args);
1000 args.cPackages = cPackages; 1000 args.cPackages = cPackages;
1001 args.fInstalled = fInstalled; 1001 args.registrationType = registrationType;
1002 args.fCached = fCached; 1002 args.fCached = fCached;
1003 1003
1004 results.cbSize = sizeof(results); 1004 results.cbSize = sizeof(results);
diff --git a/src/burn/engine/userexperience.h b/src/burn/engine/userexperience.h
index 8106d7f7..37fa5174 100644
--- a/src/burn/engine/userexperience.h
+++ b/src/burn/engine/userexperience.h
@@ -245,7 +245,7 @@ BAAPI UserExperienceOnCommitMsiTransactionComplete(
245BAAPI UserExperienceOnDetectBegin( 245BAAPI UserExperienceOnDetectBegin(
246 __in BURN_USER_EXPERIENCE* pUserExperience, 246 __in BURN_USER_EXPERIENCE* pUserExperience,
247 __in BOOL fCached, 247 __in BOOL fCached,
248 __in BOOL fInstalled, 248 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType,
249 __in DWORD cPackages 249 __in DWORD cPackages
250 ); 250 );
251BAAPI UserExperienceOnDetectCompatibleMsiPackage( 251BAAPI UserExperienceOnDetectCompatibleMsiPackage(
diff --git a/src/burn/engine/variable.cpp b/src/burn/engine/variable.cpp
index b3dcdb7d..5d92590c 100644
--- a/src/burn/engine/variable.cpp
+++ b/src/burn/engine/variable.cpp
@@ -248,6 +248,7 @@ extern "C" HRESULT VariableInitialize(
248#endif 248#endif
249 {L"ProgramFiles6432Folder", InitializeVariable6432Folder, CSIDL_PROGRAM_FILES}, 249 {L"ProgramFiles6432Folder", InitializeVariable6432Folder, CSIDL_PROGRAM_FILES},
250 {L"ProgramMenuFolder", InitializeVariableCsidlFolder, CSIDL_PROGRAMS}, 250 {L"ProgramMenuFolder", InitializeVariableCsidlFolder, CSIDL_PROGRAMS},
251 {L"RebootPending", InitializeVariableNumeric, 0},
251 {L"SendToFolder", InitializeVariableCsidlFolder, CSIDL_SENDTO}, 252 {L"SendToFolder", InitializeVariableCsidlFolder, CSIDL_SENDTO},
252 {L"ServicePackLevel", InitializeVariableVersionNT, OS_INFO_VARIABLE_ServicePackLevel}, 253 {L"ServicePackLevel", InitializeVariableVersionNT, OS_INFO_VARIABLE_ServicePackLevel},
253 {L"StartMenuFolder", InitializeVariableCsidlFolder, CSIDL_STARTMENU}, 254 {L"StartMenuFolder", InitializeVariableCsidlFolder, CSIDL_STARTMENU},
@@ -1571,6 +1572,9 @@ static HRESULT SetVariableValue(
1571 // Insert element if not found. 1572 // Insert element if not found.
1572 if (S_FALSE == hr) 1573 if (S_FALSE == hr)
1573 { 1574 {
1575 // Not possible from external callers so just assert.
1576 AssertSz(SET_VARIABLE_OVERRIDE_BUILTIN != setBuiltin, "Intent to set missing built-in variable.");
1577
1574 hr = InsertVariable(pVariables, wzVariable, iVariable); 1578 hr = InsertVariable(pVariables, wzVariable, iVariable);
1575 ExitOnFailure(hr, "Failed to insert variable '%ls'.", wzVariable); 1579 ExitOnFailure(hr, "Failed to insert variable '%ls'.", wzVariable);
1576 } 1580 }
diff --git a/src/burn/test/BurnUnitTest/PlanTest.cpp b/src/burn/test/BurnUnitTest/PlanTest.cpp
index ba28713f..685d2ca9 100644
--- a/src/burn/test/BurnUnitTest/PlanTest.cpp
+++ b/src/burn/test/BurnUnitTest/PlanTest.cpp
@@ -792,7 +792,7 @@ namespace Bootstrapper
792 InitializeEngineStateForCorePlan(wzSingleMsiManifestFileName, pEngineState); 792 InitializeEngineStateForCorePlan(wzSingleMsiManifestFileName, pEngineState);
793 DetectPackagesAsAbsent(pEngineState); 793 DetectPackagesAsAbsent(pEngineState);
794 794
795 pEngineState->registration.fInstalled = TRUE; 795 pEngineState->registration.detectedRegistrationType = BOOTSTRAPPER_REGISTRATION_TYPE_FULL;
796 796
797 hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_MODIFY); 797 hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_MODIFY);
798 NativeAssert::Succeeded(hr, "CorePlan failed"); 798 NativeAssert::Succeeded(hr, "CorePlan failed");
@@ -1457,7 +1457,7 @@ namespace Bootstrapper
1457 { 1457 {
1458 PlanTestDetect(pEngineState); 1458 PlanTestDetect(pEngineState);
1459 1459
1460 pEngineState->registration.fInstalled = TRUE; 1460 pEngineState->registration.detectedRegistrationType = BOOTSTRAPPER_REGISTRATION_TYPE_FULL;
1461 1461
1462 for (DWORD i = 0; i < pEngineState->packages.cPackages; ++i) 1462 for (DWORD i = 0; i < pEngineState->packages.cPackages; ++i)
1463 { 1463 {
@@ -1486,7 +1486,7 @@ namespace Bootstrapper
1486 { 1486 {
1487 PlanTestDetect(pEngineState); 1487 PlanTestDetect(pEngineState);
1488 1488
1489 pEngineState->registration.fInstalled = TRUE; 1489 pEngineState->registration.detectedRegistrationType = BOOTSTRAPPER_REGISTRATION_TYPE_FULL;
1490 1490
1491 for (DWORD i = 0; i < pEngineState->packages.cPackages; ++i) 1491 for (DWORD i = 0; i < pEngineState->packages.cPackages; ++i)
1492 { 1492 {
diff --git a/src/burn/test/BurnUnitTest/RegistrationTest.cpp b/src/burn/test/BurnUnitTest/RegistrationTest.cpp
index 6a10961d..86ea86b0 100644
--- a/src/burn/test/BurnUnitTest/RegistrationTest.cpp
+++ b/src/burn/test/BurnUnitTest/RegistrationTest.cpp
@@ -218,7 +218,7 @@ namespace Bootstrapper
218 218
219 // verify that registration was updated 219 // verify that registration was updated
220 this->ValidateUninstallKeyResume(Int32(BURN_RESUME_MODE_ARP)); 220 this->ValidateUninstallKeyResume(Int32(BURN_RESUME_MODE_ARP));
221 this->ValidateUninstallKeyInstalled(1); 221 this->ValidateUninstallKeyInstalled(0);
222 this->ValidateRunOnceKeyString(TEST_BUNDLE_ID, nullptr); 222 this->ValidateRunOnceKeyString(TEST_BUNDLE_ID, nullptr);
223 223
224 // 224 //
@@ -231,7 +231,7 @@ namespace Bootstrapper
231 231
232 // verify that registration was updated 232 // verify that registration was updated
233 this->ValidateUninstallKeyResume(Int32(BURN_RESUME_MODE_ACTIVE)); 233 this->ValidateUninstallKeyResume(Int32(BURN_RESUME_MODE_ACTIVE));
234 this->ValidateUninstallKeyInstalled(1); 234 this->ValidateUninstallKeyInstalled(0);
235 this->ValidateRunOnceKeyEntry(cacheExePath); 235 this->ValidateRunOnceKeyEntry(cacheExePath);
236 236
237 // delete registration 237 // delete registration
@@ -337,7 +337,7 @@ namespace Bootstrapper
337 337
338 // verify that registration variables were updated 338 // verify that registration variables were updated
339 this->ValidateUninstallKeyDisplayName(L"Product1"); 339 this->ValidateUninstallKeyDisplayName(L"Product1");
340 registration.fInstalled = TRUE; 340 registration.detectedRegistrationType = BOOTSTRAPPER_REGISTRATION_TYPE_FULL;
341 341
342 hr = RegistrationSetVariables(&registration, &variables); 342 hr = RegistrationSetVariables(&registration, &variables);
343 TestThrowOnFailure(hr, L"Failed to set registration variables."); 343 TestThrowOnFailure(hr, L"Failed to set registration variables.");
diff --git a/src/ext/Bal/Samples/bafunctions/WixSampleBAFunctions.cpp b/src/ext/Bal/Samples/bafunctions/WixSampleBAFunctions.cpp
index 870b219b..5383efbf 100644
--- a/src/ext/Bal/Samples/bafunctions/WixSampleBAFunctions.cpp
+++ b/src/ext/Bal/Samples/bafunctions/WixSampleBAFunctions.cpp
@@ -9,14 +9,14 @@ class CWixSampleBAFunctions : public CBalBaseBAFunctions
9public: // IBootstrapperApplication 9public: // IBootstrapperApplication
10 virtual STDMETHODIMP OnDetectBegin( 10 virtual STDMETHODIMP OnDetectBegin(
11 __in BOOL fCached, 11 __in BOOL fCached,
12 __in BOOL fInstalled, 12 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType,
13 __in DWORD cPackages, 13 __in DWORD cPackages,
14 __inout BOOL* pfCancel 14 __inout BOOL* pfCancel
15 ) 15 )
16 { 16 {
17 HRESULT hr = S_OK; 17 HRESULT hr = S_OK;
18 18
19 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Running detect begin BA function. fCached=%d, fInstalled=%d, cPackages=%u, fCancel=%d", fCached, fInstalled, cPackages, *pfCancel); 19 BalLog(BOOTSTRAPPER_LOG_LEVEL_STANDARD, "Running detect begin BA function. fCached=%d, registrationType=%d, cPackages=%u, fCancel=%d", fCached, registrationType, cPackages, *pfCancel);
20 20
21 //------------------------------------------------------------------------------------------------- 21 //-------------------------------------------------------------------------------------------------
22 // YOUR CODE GOES HERE 22 // YOUR CODE GOES HERE
diff --git a/src/test/burn/WixToolset.WixBA/InstallationViewModel.cs b/src/test/burn/WixToolset.WixBA/InstallationViewModel.cs
index e056b943..3a71779a 100644
--- a/src/test/burn/WixToolset.WixBA/InstallationViewModel.cs
+++ b/src/test/burn/WixToolset.WixBA/InstallationViewModel.cs
@@ -53,9 +53,9 @@ namespace WixToolset.WixBA
53 /// </summary> 53 /// </summary>
54 public class InstallationViewModel : PropertyNotifyBase 54 public class InstallationViewModel : PropertyNotifyBase
55 { 55 {
56 private RootViewModel root; 56 private readonly RootViewModel root;
57 57
58 private Dictionary<string, int> downloadRetries; 58 private readonly Dictionary<string, int> downloadRetries;
59 private bool downgrade; 59 private bool downgrade;
60 private string downgradeMessage; 60 private string downgradeMessage;
61 61
@@ -407,7 +407,7 @@ namespace WixToolset.WixBA
407 407
408 private void DetectBegin(object sender, DetectBeginEventArgs e) 408 private void DetectBegin(object sender, DetectBeginEventArgs e)
409 { 409 {
410 this.root.DetectState = e.Installed ? DetectionState.Present : DetectionState.Absent; 410 this.root.DetectState = RegistrationType.Full == e.RegistrationType ? DetectionState.Present : DetectionState.Absent;
411 WixBA.Model.PlannedAction = LaunchAction.Unknown; 411 WixBA.Model.PlannedAction = LaunchAction.Unknown;
412 } 412 }
413 413