aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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