@joebigelow / wix / commits / 39725a1a

Require re-Detect after Apply.

Sean Hall committed Feb 2, 2021 at 16:57 UTC 39725a1a6d1c72a6748bd3c306af32bcae6dbf8f
7 files changed +92 -7
src/engine/core.cpp
+46 -7
@@ -242,6 +242,13 @@ extern "C" HRESULT CoreDetect(
242
243 LogId(REPORT_STANDARD, MSG_DETECT_BEGIN, pEngineState->packages.cPackages);
244
245 + // Always reset the detect state which means the plan should be reset too.
246 + pEngineState->fDetected = FALSE;
247 + pEngineState->fPlanned = FALSE;
248 + pEngineState->fApplied = FALSE;
249 + DetectReset(&pEngineState->registration, &pEngineState->packages);
250 + PlanReset(&pEngineState->plan, &pEngineState->packages);
251 +
252 // Detect if bundle installed state has changed since start up. This
253 // only happens if Apply() changed the state of bundle (installed or
254 // uninstalled). In that case, Detect() can be used here to reset
@@ -266,10 +273,6 @@ extern "C" HRESULT CoreDetect(
273
274 pEngineState->userExperience.hwndDetect = hwndParent;
275
269 - // Always reset the detect state which means the plan should be reset too.
270 - DetectReset(&pEngineState->registration, &pEngineState->packages);
271 - PlanReset(&pEngineState->plan, &pEngineState->packages);
272 -
276 hr = SearchesExecute(&pEngineState->searches, &pEngineState->variables);
277 ExitOnFailure(hr, "Failed to execute searches.");
278
@@ -365,6 +368,11 @@ LExit:
368 hr = hrFirstPackageFailure;
369 }
370
371 + if (SUCCEEDED(hr))
372 + {
373 + pEngineState->fDetected = TRUE;
374 + }
375 +
376 if (fDetectBegan)
377 {
378 UserExperienceOnDetectComplete(&pEngineState->userExperience, hr);
@@ -388,6 +396,7 @@ extern "C" HRESULT CorePlan(
396 HANDLE hSyncpointEvent = NULL;
397 BURN_PACKAGE* pUpgradeBundlePackage = NULL;
398 BURN_PACKAGE* pForwardCompatibleBundlePackage = NULL;
399 + BOOL fContinuePlanning = TRUE; // assume we won't skip planning due to dependencies.
400
401 LogId(REPORT_STANDARD, MSG_PLAN_BEGIN, pEngineState->packages.cPackages, LoggingBurnActionToString(action));
402
@@ -395,7 +404,17 @@ extern "C" HRESULT CorePlan(
404 hr = UserExperienceOnPlanBegin(&pEngineState->userExperience, pEngineState->packages.cPackages);
405 ExitOnRootFailure(hr, "BA aborted plan begin.");
406
407 + if (!pEngineState->fDetected)
408 + {
409 + ExitOnFailure(hr = E_INVALIDSTATE, "Plan cannot be done without a successful Detect.");
410 + }
411 + else if (pEngineState->fApplied)
412 + {
413 + ExitOnFailure(hr = E_INVALIDSTATE, "Plan requires a new successful Detect after calling Apply.");
414 + }
415 +
416 // Always reset the plan.
417 + pEngineState->fPlanned = FALSE;
418 PlanReset(&pEngineState->plan, &pEngineState->packages);
419
420 // Remember the overall action state in the plan since it shapes the changes
@@ -447,7 +466,6 @@ extern "C" HRESULT CorePlan(
466 }
467 else // doing an action that modifies the machine state.
468 {
450 - BOOL fContinuePlanning = TRUE; // assume we'll be able to keep planning after registration.
469 pEngineState->plan.fPerMachine = pEngineState->registration.fPerMachine; // default the scope of the plan to the per-machine state of the bundle.
470
471 hr = PlanRegistration(&pEngineState->plan, &pEngineState->registration, pEngineState->command.resumeType, pEngineState->command.relationType, &fContinuePlanning);
@@ -477,12 +495,20 @@ extern "C" HRESULT CorePlan(
495 hr = PlanFinalizeActions(&pEngineState->plan);
496 ExitOnFailure(hr, "Failed to remove unnecessary actions from plan.");
497
480 - // Finally, display all packages and related bundles in the log.
481 - LogPackages(pUpgradeBundlePackage, pForwardCompatibleBundlePackage, &pEngineState->packages, &pEngineState->registration.relatedBundles, action);
498 + if (fContinuePlanning)
499 + {
500 + // Finally, display all packages and related bundles in the log.
501 + LogPackages(pUpgradeBundlePackage, pForwardCompatibleBundlePackage, &pEngineState->packages, &pEngineState->registration.relatedBundles, action);
502 + }
503
504 PlanDump(&pEngineState->plan);
505
506 LExit:
507 + if (SUCCEEDED(hr))
508 + {
509 + pEngineState->fPlanned = TRUE;
510 + }
511 +
512 if (fPlanBegan)
513 {
514 UserExperienceOnPlanComplete(&pEngineState->userExperience, hr);
@@ -549,6 +575,15 @@ extern "C" HRESULT CoreApply(
575
576 LogId(REPORT_STANDARD, MSG_APPLY_BEGIN);
577
578 + if (!pEngineState->fPlanned)
579 + {
580 + ExitOnFailure(hr = E_INVALIDSTATE, "Apply cannot be done without a successful Plan.");
581 + }
582 + else if (pEngineState->fApplied)
583 + {
584 + ExitOnFailure(hr = E_INVALIDSTATE, "Plans cannot be applied multiple times.");
585 + }
586 +
587 // Ensure any previous attempts to execute are reset.
588 ApplyReset(&pEngineState->userExperience, &pEngineState->packages);
589
@@ -564,6 +599,8 @@ extern "C" HRESULT CoreApply(
599 hr = UserExperienceOnApplyBegin(&pEngineState->userExperience, dwPhaseCount);
600 ExitOnRootFailure(hr, "BA aborted apply begin.");
601
602 + pEngineState->fApplied = TRUE;
603 +
604 // Abort if this bundle already requires a restart.
605 if (BOOTSTRAPPER_RESUME_TYPE_REBOOT_PENDING == pEngineState->command.resumeType)
606 {
@@ -758,6 +795,8 @@ extern "C" HRESULT CoreQuit(
795
796 LogId(REPORT_STANDARD, MSG_QUIT, nExitCode);
797
798 + pEngineState->fQuit = TRUE;
799 +
800 ::PostQuitMessage(nExitCode); // go bye-bye.
801
802 return hr;
src/engine/core.h
+4
@@ -78,6 +78,10 @@ enum BURN_AU_PAUSE_ACTION
78 typedef struct _BURN_ENGINE_STATE
79 {
80 // UX flow control
81 + BOOL fDetected;
82 + BOOL fPlanned;
83 + BOOL fApplied;
84 + BOOL fQuit;
85 //BOOL fSuspend; // Is TRUE when UX made Suspend() call on core.
86 //BOOL fForcedReboot; // Is TRUE when UX made Reboot() call on core.
87 //BOOL fCancelled; // Is TRUE when UX return cancel on UX OnXXX() methods.
src/engine/engine.cpp
+7
@@ -804,6 +804,12 @@ static HRESULT ProcessMessage(
804
805 UserExperienceActivateEngine(&pEngineState->userExperience);
806
807 + if (pEngineState->fQuit)
808 + {
809 + LogId(REPORT_WARNING, MSG_IGNORE_OPERATION_AFTER_QUIT, LoggingBurnMessageToString(pmsg->message));
810 + ExitFunction1(hr = E_INVALIDSTATE);
811 + }
812 +
813 switch (pmsg->message)
814 {
815 case WM_BURN_DETECT:
@@ -831,6 +837,7 @@ static HRESULT ProcessMessage(
837 break;
838 }
839
840 +LExit:
841 UserExperienceDeactivateEngine(&pEngineState->userExperience);
842
843 return hr;
src/engine/engine.mc
+7
@@ -170,6 +170,13 @@ Language=English
170 Condition '%1!ls!' contains invalid version string '%2!ls!'.
171 .
172
173 +MessageId=58
174 +Severity=Warning
175 +SymbolicName=MSG_IGNORE_OPERATION_AFTER_QUIT
176 +Language=English
177 +Bootstrapper application already requested to quit, ignoring request: '%1!hs!'.
178 +.
179 +
180 MessageId=100
181 Severity=Success
182 SymbolicName=MSG_DETECT_BEGIN
src/engine/logging.cpp
+23
@@ -289,6 +289,29 @@ extern "C" LPCSTR LoggingBurnActionToString(
289 }
290 }
291
292 +LPCSTR LoggingBurnMessageToString(
293 + __in UINT message
294 + )
295 +{
296 + switch (message)
297 + {
298 + case WM_BURN_APPLY:
299 + return "Apply";
300 + case WM_BURN_DETECT:
301 + return "Detect";
302 + case WM_BURN_ELEVATE:
303 + return "Elevate";
304 + case WM_BURN_LAUNCH_APPROVED_EXE:
305 + return "LaunchApprovedExe";
306 + case WM_BURN_PLAN:
307 + return "Plan";
308 + case WM_BURN_QUIT:
309 + return "Quit";
310 + default:
311 + return "Invalid";
312 + }
313 +}
314 +
315 extern "C" LPCSTR LoggingActionStateToString(
316 __in BOOTSTRAPPER_ACTION_STATE actionState
317 )
src/engine/logging.h
+4
@@ -65,6 +65,10 @@ LPCSTR LoggingBurnActionToString(
65 __in BOOTSTRAPPER_ACTION action
66 );
67
68 +LPCSTR LoggingBurnMessageToString(
69 + __in UINT message
70 + );
71 +
72 LPCSTR LoggingActionStateToString(
73 __in BOOTSTRAPPER_ACTION_STATE actionState
74 );
src/test/BurnUnitTest/PlanTest.cpp
+1
@@ -568,6 +568,7 @@ namespace Bootstrapper
568 NativeAssert::Succeeded(hr, "Failed to add the bundle provider key to the list of dependencies to ignore.");
569
570 pEngineState->userExperience.fEngineActive = TRUE;
571 + pEngineState->fDetected = TRUE;
572 }
573
574 void DetectAttachedContainerAsAttached(BURN_ENGINE_STATE* pEngineState)