aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-02-03 17:09:50 -0600
committerSean Hall <r.sean.hall@gmail.com>2021-02-04 22:16:10 -0600
commitc6c17104b50936432a3fe9ca214ba9a3dfa32780 (patch)
tree7ad23896fd7e1768a5f81ebb4dc2abe99718eadb
parentfd8c2b0899bfbce07386af245c04eb21dc01cbdf (diff)
downloadwix-c6c17104b50936432a3fe9ca214ba9a3dfa32780.tar.gz
wix-c6c17104b50936432a3fe9ca214ba9a3dfa32780.tar.bz2
wix-c6c17104b50936432a3fe9ca214ba9a3dfa32780.zip
Automatically uninstall the bundle after Quit if eligible.
For now, the requirements are: * The bundle is installed and * The bundle is per-user or has already elevated and * No non-permanent packages are installed and * No non-permanent packages are cached and * No related bundle would run by default during uninstall and * The bundle didn't Uninstall/Cache/Install/Modify/Repair and * The BA didn't opt out of this behavior
-rw-r--r--src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h4
-rw-r--r--src/engine/core.cpp62
-rw-r--r--src/engine/core.h3
-rw-r--r--src/engine/detect.cpp21
-rw-r--r--src/engine/detect.h3
-rw-r--r--src/engine/engine.cpp21
-rw-r--r--src/engine/engine.mc9
-rw-r--r--src/engine/registration.h1
-rw-r--r--src/engine/userexperience.cpp16
-rw-r--r--src/engine/userexperience.h3
10 files changed, 131 insertions, 12 deletions
diff --git a/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h b/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
index c0baa958..48bd813d 100644
--- a/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
+++ b/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
@@ -221,6 +221,9 @@ enum BOOTSTRAPPER_SHUTDOWN_ACTION
221 // restart the engine which will load the bootstrapper application again. 221 // restart the engine which will load the bootstrapper application again.
222 // Typically used to switch from a native bootstrapper application to a managed one. 222 // Typically used to switch from a native bootstrapper application to a managed one.
223 BOOTSTRAPPER_SHUTDOWN_ACTION_RELOAD_BOOTSTRAPPER, 223 BOOTSTRAPPER_SHUTDOWN_ACTION_RELOAD_BOOTSTRAPPER,
224 // Opts out of the engine behavior of trying to uninstall itself
225 // when no non-permanent packages are installed.
226 BOOTSTRAPPER_SHUTDOWN_ACTION_SKIP_CLEANUP,
224}; 227};
225 228
226enum BURN_MSI_PROPERTY 229enum BURN_MSI_PROPERTY
@@ -470,6 +473,7 @@ struct BA_ONDETECTCOMPLETE_ARGS
470{ 473{
471 DWORD cbSize; 474 DWORD cbSize;
472 HRESULT hrStatus; 475 HRESULT hrStatus;
476 BOOL fEligibleForCleanup;
473}; 477};
474 478
475struct BA_ONDETECTCOMPLETE_RESULTS 479struct BA_ONDETECTCOMPLETE_RESULTS
diff --git a/src/engine/core.cpp b/src/engine/core.cpp
index 36471e93..1503f8d8 100644
--- a/src/engine/core.cpp
+++ b/src/engine/core.cpp
@@ -300,7 +300,7 @@ extern "C" HRESULT CoreDetect(
300 ExitOnFailure(hr, "Failed to detect provider key bundle id."); 300 ExitOnFailure(hr, "Failed to detect provider key bundle id.");
301 301
302 // Report the related bundles. 302 // Report the related bundles.
303 hr = DetectReportRelatedBundles(&pEngineState->userExperience, &pEngineState->registration, pEngineState->command.relationType, pEngineState->command.action); 303 hr = DetectReportRelatedBundles(&pEngineState->userExperience, &pEngineState->registration, pEngineState->command.relationType, pEngineState->command.action, &pEngineState->registration.fEligibleForCleanup);
304 ExitOnFailure(hr, "Failed to report detected related bundles."); 304 ExitOnFailure(hr, "Failed to report detected related bundles.");
305 305
306 // Do update detection. 306 // Do update detection.
@@ -344,6 +344,14 @@ extern "C" HRESULT CoreDetect(
344 { 344 {
345 pPackage = pEngineState->packages.rgPackages + iPackage; 345 pPackage = pEngineState->packages.rgPackages + iPackage;
346 346
347 // If any packages that can affect registration are present, then the bundle should not automatically be uninstalled.
348 if (pEngineState->registration.fEligibleForCleanup && pPackage->fCanAffectRegistration &&
349 (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->cacheRegistrationState ||
350 BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->installRegistrationState))
351 {
352 pEngineState->registration.fEligibleForCleanup = FALSE;
353 }
354
347 LogId(REPORT_STANDARD, MSG_DETECTED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingCacheStateToString(pPackage->cache), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->installRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->cacheRegistrationState)); 355 LogId(REPORT_STANDARD, MSG_DETECTED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingCacheStateToString(pPackage->cache), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->installRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->cacheRegistrationState));
348 356
349 if (BURN_PACKAGE_TYPE_MSI == pPackage->type) 357 if (BURN_PACKAGE_TYPE_MSI == pPackage->type)
@@ -377,12 +385,12 @@ LExit:
377 385
378 if (fDetectBegan) 386 if (fDetectBegan)
379 { 387 {
380 UserExperienceOnDetectComplete(&pEngineState->userExperience, hr); 388 UserExperienceOnDetectComplete(&pEngineState->userExperience, hr, pEngineState->registration.fEligibleForCleanup);
381 } 389 }
382 390
383 pEngineState->userExperience.hwndDetect = NULL; 391 pEngineState->userExperience.hwndDetect = NULL;
384 392
385 LogId(REPORT_STANDARD, MSG_DETECT_COMPLETE, hr); 393 LogId(REPORT_STANDARD, MSG_DETECT_COMPLETE, hr, !fDetectBegan ? "(failed)" : LoggingBoolToString(pEngineState->registration.fInstalled), FAILED(hr) ? "(failed)" : LoggingBoolToString(pEngineState->registration.fEligibleForCleanup));
386 394
387 return hr; 395 return hr;
388} 396}
@@ -1053,6 +1061,54 @@ LExit:
1053 return hr; 1061 return hr;
1054} 1062}
1055 1063
1064extern "C" HRESULT CoreCleanup(
1065 __in BURN_ENGINE_STATE* pEngineState
1066 )
1067{
1068 HRESULT hr = S_OK;
1069 LONGLONG llValue = 0;
1070 BOOL fNeedsElevation = pEngineState->registration.fPerMachine && INVALID_HANDLE_VALUE == pEngineState->companionConnection.hPipe;
1071
1072 if (fNeedsElevation)
1073 {
1074 hr = VariableGetNumeric(&pEngineState->variables, BURN_BUNDLE_ELEVATED, &llValue);
1075 ExitOnFailure(hr, "Failed to get value of WixBundleElevated variable during cleanup");
1076
1077 if (llValue)
1078 {
1079 fNeedsElevation = FALSE;
1080 }
1081 }
1082
1083 if (pEngineState->fApplied && BOOTSTRAPPER_ACTION_LAYOUT < pEngineState->plan.action && BOOTSTRAPPER_ACTION_UPDATE_REPLACE > pEngineState->plan.action ||
1084 fNeedsElevation)
1085 {
1086 ExitFunction();
1087 }
1088
1089 if (!pEngineState->fDetected)
1090 {
1091 hr = CoreDetect(pEngineState, pEngineState->hMessageWindow);
1092 ExitOnFailure(hr, "Detect during cleanup failed");
1093 }
1094
1095 if (!pEngineState->registration.fEligibleForCleanup)
1096 {
1097 ExitFunction();
1098 }
1099
1100 hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_UNINSTALL);
1101 ExitOnFailure(hr, "Plan during cleanup failed");
1102
1103 hr = CoreApply(pEngineState, pEngineState->hMessageWindow);
1104 ExitOnFailure(hr, "Apply during cleanup failed");
1105
1106 // Need to think about cache=always
1107
1108LExit:
1109 return hr;
1110}
1111
1056// internal helper functions 1112// internal helper functions
1057 1113
1058static HRESULT ParseCommandLine( 1114static HRESULT ParseCommandLine(
diff --git a/src/engine/core.h b/src/engine/core.h
index fd7311e3..47cfd559 100644
--- a/src/engine/core.h
+++ b/src/engine/core.h
@@ -204,6 +204,9 @@ HRESULT CoreAppendFileHandleSelfToCommandLine(
204 __deref_inout_z LPWSTR* psczCommandLine, 204 __deref_inout_z LPWSTR* psczCommandLine,
205 __deref_inout_z_opt LPWSTR* psczObfuscatedCommandLine 205 __deref_inout_z_opt LPWSTR* psczObfuscatedCommandLine
206 ); 206 );
207HRESULT CoreCleanup(
208 __in BURN_ENGINE_STATE* pEngineState
209 );
207 210
208#if defined(__cplusplus) 211#if defined(__cplusplus)
209} 212}
diff --git a/src/engine/detect.cpp b/src/engine/detect.cpp
index 159df3d0..b702306e 100644
--- a/src/engine/detect.cpp
+++ b/src/engine/detect.cpp
@@ -42,6 +42,7 @@ extern "C" void DetectReset(
42 pRegistration->fEnabledForwardCompatibleBundle = FALSE; 42 pRegistration->fEnabledForwardCompatibleBundle = FALSE;
43 PackageUninitialize(&pRegistration->forwardCompatibleBundle); 43 PackageUninitialize(&pRegistration->forwardCompatibleBundle);
44 pRegistration->fSelfRegisteredAsDependent = FALSE; 44 pRegistration->fSelfRegisteredAsDependent = FALSE;
45 pRegistration->fEligibleForCleanup = FALSE;
45 46
46 if (pRegistration->rgIgnoredDependencies) 47 if (pRegistration->rgIgnoredDependencies)
47 { 48 {
@@ -184,11 +185,14 @@ extern "C" HRESULT DetectReportRelatedBundles(
184 __in BURN_USER_EXPERIENCE* pUX, 185 __in BURN_USER_EXPERIENCE* pUX,
185 __in BURN_REGISTRATION* pRegistration, 186 __in BURN_REGISTRATION* pRegistration,
186 __in BOOTSTRAPPER_RELATION_TYPE relationType, 187 __in BOOTSTRAPPER_RELATION_TYPE relationType,
187 __in BOOTSTRAPPER_ACTION action 188 __in BOOTSTRAPPER_ACTION action,
189 __out BOOL* pfEligibleForCleanup
188 ) 190 )
189{ 191{
190 HRESULT hr = S_OK; 192 HRESULT hr = S_OK;
191 int nCompareResult = 0; 193 int nCompareResult = 0;
194 BOOTSTRAPPER_REQUEST_STATE uninstallRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
195 *pfEligibleForCleanup = pRegistration->fInstalled;
192 196
193 for (DWORD iRelatedBundle = 0; iRelatedBundle < pRegistration->relatedBundles.cRelatedBundles; ++iRelatedBundle) 197 for (DWORD iRelatedBundle = 0; iRelatedBundle < pRegistration->relatedBundles.cRelatedBundles; ++iRelatedBundle)
194 { 198 {
@@ -201,7 +205,7 @@ extern "C" HRESULT DetectReportRelatedBundles(
201 if (BOOTSTRAPPER_RELATION_UPGRADE != relationType && BOOTSTRAPPER_ACTION_UNINSTALL < action) 205 if (BOOTSTRAPPER_RELATION_UPGRADE != relationType && BOOTSTRAPPER_ACTION_UNINSTALL < action)
202 { 206 {
203 hr = VerCompareParsedVersions(pRegistration->pVersion, pRelatedBundle->pVersion, &nCompareResult); 207 hr = VerCompareParsedVersions(pRegistration->pVersion, pRelatedBundle->pVersion, &nCompareResult);
204 ExitOnFailure(hr, "Failed to compare bundle version '%ls' to related bundle version '%ls'", pRegistration->pVersion, pRelatedBundle->pVersion); 208 ExitOnFailure(hr, "Failed to compare bundle version '%ls' to related bundle version '%ls'", pRegistration->pVersion->sczVersion, pRelatedBundle->pVersion->sczVersion);
205 209
206 if (nCompareResult < 0) 210 if (nCompareResult < 0)
207 { 211 {
@@ -244,6 +248,19 @@ extern "C" HRESULT DetectReportRelatedBundles(
244 248
245 hr = UserExperienceOnDetectRelatedBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->relationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->pVersion, operation); 249 hr = UserExperienceOnDetectRelatedBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->relationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->pVersion, operation);
246 ExitOnRootFailure(hr, "BA aborted detect related bundle."); 250 ExitOnRootFailure(hr, "BA aborted detect related bundle.");
251
252 // For now, if any related bundles will be executed during uninstall by default then never automatically clean up the bundle.
253 if (*pfEligibleForCleanup)
254 {
255 uninstallRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
256 hr = PlanDefaultRelatedBundleRequestState(relationType, pRelatedBundle->relationType, BOOTSTRAPPER_ACTION_UNINSTALL, pRegistration->pVersion, pRelatedBundle->pVersion, &uninstallRequestState);
257 ExitOnFailure(hr, "Failed to get the default request state for related bundle for calculating fEligibleForCleanup");
258
259 if (BOOTSTRAPPER_REQUEST_STATE_NONE != uninstallRequestState)
260 {
261 *pfEligibleForCleanup = FALSE;
262 }
263 }
247 } 264 }
248 265
249LExit: 266LExit:
diff --git a/src/engine/detect.h b/src/engine/detect.h
index 01488f1a..7989c9dd 100644
--- a/src/engine/detect.h
+++ b/src/engine/detect.h
@@ -30,7 +30,8 @@ HRESULT DetectReportRelatedBundles(
30 __in BURN_USER_EXPERIENCE* pUX, 30 __in BURN_USER_EXPERIENCE* pUX,
31 __in BURN_REGISTRATION* pRegistration, 31 __in BURN_REGISTRATION* pRegistration,
32 __in BOOTSTRAPPER_RELATION_TYPE relationType, 32 __in BOOTSTRAPPER_RELATION_TYPE relationType,
33 __in BOOTSTRAPPER_ACTION action 33 __in BOOTSTRAPPER_ACTION action,
34 __out BOOL* pfEligibleForCleanup
34 ); 35 );
35 36
36HRESULT DetectUpdate( 37HRESULT DetectUpdate(
diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp
index e3ace592..bc27cb14 100644
--- a/src/engine/engine.cpp
+++ b/src/engine/engine.cpp
@@ -39,7 +39,8 @@ static HRESULT RunRunOnce(
39 ); 39 );
40static HRESULT RunApplication( 40static HRESULT RunApplication(
41 __in BURN_ENGINE_STATE* pEngineState, 41 __in BURN_ENGINE_STATE* pEngineState,
42 __out BOOL* pfReloadApp 42 __out BOOL* pfReloadApp,
43 __out BOOL* pfSkipCleanup
43 ); 44 );
44static HRESULT ProcessMessage( 45static HRESULT ProcessMessage(
45 __in BURN_ENGINE_STATE* pEngineState, 46 __in BURN_ENGINE_STATE* pEngineState,
@@ -529,6 +530,7 @@ static HRESULT RunNormal(
529 HANDLE hPipesCreatedEvent = NULL; 530 HANDLE hPipesCreatedEvent = NULL;
530 BOOL fContinueExecution = TRUE; 531 BOOL fContinueExecution = TRUE;
531 BOOL fReloadApp = FALSE; 532 BOOL fReloadApp = FALSE;
533 BOOL fSkipCleanup = FALSE;
532 BURN_EXTENSION_ENGINE_CONTEXT extensionEngineContext = { }; 534 BURN_EXTENSION_ENGINE_CONTEXT extensionEngineContext = { };
533 535
534 // Initialize logging. 536 // Initialize logging.
@@ -584,11 +586,18 @@ static HRESULT RunNormal(
584 do 586 do
585 { 587 {
586 fReloadApp = FALSE; 588 fReloadApp = FALSE;
589 pEngineState->fQuit = FALSE;
587 590
588 hr = RunApplication(pEngineState, &fReloadApp); 591 hr = RunApplication(pEngineState, &fReloadApp, &fSkipCleanup);
589 ExitOnFailure(hr, "Failed while running "); 592 ExitOnFailure(hr, "Failed while running ");
590 } while (fReloadApp); 593 } while (fReloadApp);
591 594
595 if (!fSkipCleanup)
596 {
597 hr = CoreCleanup(pEngineState);
598 ExitOnFailure(hr, "Failed to cleanup before shutting down");
599 }
600
592LExit: 601LExit:
593 BurnExtensionUnload(&pEngineState->extensions); 602 BurnExtensionUnload(&pEngineState->extensions);
594 603
@@ -732,7 +741,8 @@ LExit:
732 741
733static HRESULT RunApplication( 742static HRESULT RunApplication(
734 __in BURN_ENGINE_STATE* pEngineState, 743 __in BURN_ENGINE_STATE* pEngineState,
735 __out BOOL* pfReloadApp 744 __out BOOL* pfReloadApp,
745 __out BOOL* pfSkipCleanup
736 ) 746 )
737{ 747{
738 HRESULT hr = S_OK; 748 HRESULT hr = S_OK;
@@ -787,6 +797,11 @@ LExit:
787 LogId(REPORT_STANDARD, MSG_BA_REQUESTED_RELOAD); 797 LogId(REPORT_STANDARD, MSG_BA_REQUESTED_RELOAD);
788 *pfReloadApp = TRUE; 798 *pfReloadApp = TRUE;
789 } 799 }
800 else if (BOOTSTRAPPER_SHUTDOWN_ACTION_SKIP_CLEANUP == shutdownAction)
801 {
802 LogId(REPORT_STANDARD, MSG_BA_REQUESTED_SKIP_CLEANUP);
803 *pfSkipCleanup = TRUE;
804 }
790 } 805 }
791 806
792 // Unload BA. 807 // Unload BA.
diff --git a/src/engine/engine.mc b/src/engine/engine.mc
index 59a05676..c90f08e3 100644
--- a/src/engine/engine.mc
+++ b/src/engine/engine.mc
@@ -121,6 +121,13 @@ Language=English
121The manifest contains an invalid version string: '%1!ls!' 121The manifest contains an invalid version string: '%1!ls!'
122. 122.
123 123
124MessageId=14
125Severity=Success
126SymbolicName=MSG_BA_REQUESTED_SKIP_CLEANUP
127Language=English
128Bootstrapper application opted out of any engine behavior to automatically uninstall the bundle during shutdown.
129.
130
124MessageId=51 131MessageId=51
125Severity=Error 132Severity=Error
126SymbolicName=MSG_FAILED_PARSE_CONDITION 133SymbolicName=MSG_FAILED_PARSE_CONDITION
@@ -286,7 +293,7 @@ MessageId=199
286Severity=Success 293Severity=Success
287SymbolicName=MSG_DETECT_COMPLETE 294SymbolicName=MSG_DETECT_COMPLETE
288Language=English 295Language=English
289Detect complete, result: 0x%1!x! 296Detect complete, result: 0x%1!x!, installed: %2!hs!, eligible for cleanup: %3!hs!
290. 297.
291 298
292MessageId=200 299MessageId=200
diff --git a/src/engine/registration.h b/src/engine/registration.h
index c1e52ac9..55d5a4c8 100644
--- a/src/engine/registration.h
+++ b/src/engine/registration.h
@@ -146,6 +146,7 @@ typedef struct _BURN_REGISTRATION
146 UINT cDependents; // Only valid after detect. 146 UINT cDependents; // Only valid after detect.
147 LPCWSTR wzSelfDependent; // Only valid after detect. 147 LPCWSTR wzSelfDependent; // Only valid after detect.
148 BOOL fSelfRegisteredAsDependent; // Only valid after detect. 148 BOOL fSelfRegisteredAsDependent; // Only valid after detect.
149 BOOL fEligibleForCleanup; // Only valid after detect.
149 150
150 LPWSTR sczDetectedProviderKeyBundleId; 151 LPWSTR sczDetectedProviderKeyBundleId;
151 LPWSTR sczAncestors; 152 LPWSTR sczAncestors;
diff --git a/src/engine/userexperience.cpp b/src/engine/userexperience.cpp
index 3a36cab6..a0fb341d 100644
--- a/src/engine/userexperience.cpp
+++ b/src/engine/userexperience.cpp
@@ -736,7 +736,8 @@ LExit:
736 736
737EXTERN_C BAAPI UserExperienceOnDetectComplete( 737EXTERN_C BAAPI UserExperienceOnDetectComplete(
738 __in BURN_USER_EXPERIENCE* pUserExperience, 738 __in BURN_USER_EXPERIENCE* pUserExperience,
739 __in HRESULT hrStatus 739 __in HRESULT hrStatus,
740 __in BOOL fEligibleForCleanup
740 ) 741 )
741{ 742{
742 HRESULT hr = S_OK; 743 HRESULT hr = S_OK;
@@ -745,6 +746,7 @@ EXTERN_C BAAPI UserExperienceOnDetectComplete(
745 746
746 args.cbSize = sizeof(args); 747 args.cbSize = sizeof(args);
747 args.hrStatus = hrStatus; 748 args.hrStatus = hrStatus;
749 args.fEligibleForCleanup = fEligibleForCleanup;
748 750
749 results.cbSize = sizeof(results); 751 results.cbSize = sizeof(results);
750 752
@@ -2296,12 +2298,18 @@ static HRESULT SendBAMessage(
2296{ 2298{
2297 HRESULT hr = S_OK; 2299 HRESULT hr = S_OK;
2298 2300
2301 if (!pUserExperience->hUXModule)
2302 {
2303 ExitFunction();
2304 }
2305
2299 hr = pUserExperience->pfnBAProc(message, pvArgs, pvResults, pUserExperience->pvBAProcContext); 2306 hr = pUserExperience->pfnBAProc(message, pvArgs, pvResults, pUserExperience->pvBAProcContext);
2300 if (hr == E_NOTIMPL) 2307 if (hr == E_NOTIMPL)
2301 { 2308 {
2302 hr = S_OK; 2309 hr = S_OK;
2303 } 2310 }
2304 2311
2312LExit:
2305 return hr; 2313 return hr;
2306} 2314}
2307 2315
@@ -2314,11 +2322,17 @@ static HRESULT SendBAMessageFromInactiveEngine(
2314{ 2322{
2315 HRESULT hr = S_OK; 2323 HRESULT hr = S_OK;
2316 2324
2325 if (!pUserExperience->hUXModule)
2326 {
2327 ExitFunction();
2328 }
2329
2317 UserExperienceDeactivateEngine(pUserExperience); 2330 UserExperienceDeactivateEngine(pUserExperience);
2318 2331
2319 hr = SendBAMessage(pUserExperience, message, pvArgs, pvResults); 2332 hr = SendBAMessage(pUserExperience, message, pvArgs, pvResults);
2320 2333
2321 UserExperienceActivateEngine(pUserExperience); 2334 UserExperienceActivateEngine(pUserExperience);
2322 2335
2336LExit:
2323 return hr; 2337 return hr;
2324} 2338}
diff --git a/src/engine/userexperience.h b/src/engine/userexperience.h
index f51c09ff..363c0f06 100644
--- a/src/engine/userexperience.h
+++ b/src/engine/userexperience.h
@@ -191,7 +191,8 @@ BAAPI UserExperienceOnDetectBegin(
191 ); 191 );
192BAAPI UserExperienceOnDetectComplete( 192BAAPI UserExperienceOnDetectComplete(
193 __in BURN_USER_EXPERIENCE* pUserExperience, 193 __in BURN_USER_EXPERIENCE* pUserExperience,
194 __in HRESULT hrStatus 194 __in HRESULT hrStatus,
195 __in BOOL fEligibleForCleanup
195 ); 196 );
196BAAPI UserExperienceOnDetectForwardCompatibleBundle( 197BAAPI UserExperienceOnDetectForwardCompatibleBundle(
197 __in BURN_USER_EXPERIENCE* pUserExperience, 198 __in BURN_USER_EXPERIENCE* pUserExperience,