aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-02-02 16:57:33 -0600
committerSean Hall <r.sean.hall@gmail.com>2021-02-04 22:16:10 -0600
commit39725a1a6d1c72a6748bd3c306af32bcae6dbf8f (patch)
treefe37f5ad08878e2f8d36c92762a784fd13c39df2
parentbb7d4bdc09d0b52a65b8cf3b5ae629f385fc8011 (diff)
downloadwix-39725a1a6d1c72a6748bd3c306af32bcae6dbf8f.tar.gz
wix-39725a1a6d1c72a6748bd3c306af32bcae6dbf8f.tar.bz2
wix-39725a1a6d1c72a6748bd3c306af32bcae6dbf8f.zip
Require re-Detect after Apply.
-rw-r--r--src/engine/core.cpp53
-rw-r--r--src/engine/core.h4
-rw-r--r--src/engine/engine.cpp7
-rw-r--r--src/engine/engine.mc7
-rw-r--r--src/engine/logging.cpp23
-rw-r--r--src/engine/logging.h4
-rw-r--r--src/test/BurnUnitTest/PlanTest.cpp1
7 files changed, 92 insertions, 7 deletions
diff --git a/src/engine/core.cpp b/src/engine/core.cpp
index a644d377..a4c118a3 100644
--- a/src/engine/core.cpp
+++ b/src/engine/core.cpp
@@ -242,6 +242,13 @@ extern "C" HRESULT CoreDetect(
242 242
243 LogId(REPORT_STANDARD, MSG_DETECT_BEGIN, pEngineState->packages.cPackages); 243 LogId(REPORT_STANDARD, MSG_DETECT_BEGIN, pEngineState->packages.cPackages);
244 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
245 // Detect if bundle installed state has changed since start up. This 252 // Detect if bundle installed state has changed since start up. This
246 // only happens if Apply() changed the state of bundle (installed or 253 // only happens if Apply() changed the state of bundle (installed or
247 // uninstalled). In that case, Detect() can be used here to reset 254 // uninstalled). In that case, Detect() can be used here to reset
@@ -266,10 +273,6 @@ extern "C" HRESULT CoreDetect(
266 273
267 pEngineState->userExperience.hwndDetect = hwndParent; 274 pEngineState->userExperience.hwndDetect = hwndParent;
268 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
273 hr = SearchesExecute(&pEngineState->searches, &pEngineState->variables); 276 hr = SearchesExecute(&pEngineState->searches, &pEngineState->variables);
274 ExitOnFailure(hr, "Failed to execute searches."); 277 ExitOnFailure(hr, "Failed to execute searches.");
275 278
@@ -365,6 +368,11 @@ LExit:
365 hr = hrFirstPackageFailure; 368 hr = hrFirstPackageFailure;
366 } 369 }
367 370
371 if (SUCCEEDED(hr))
372 {
373 pEngineState->fDetected = TRUE;
374 }
375
368 if (fDetectBegan) 376 if (fDetectBegan)
369 { 377 {
370 UserExperienceOnDetectComplete(&pEngineState->userExperience, hr); 378 UserExperienceOnDetectComplete(&pEngineState->userExperience, hr);
@@ -388,6 +396,7 @@ extern "C" HRESULT CorePlan(
388 HANDLE hSyncpointEvent = NULL; 396 HANDLE hSyncpointEvent = NULL;
389 BURN_PACKAGE* pUpgradeBundlePackage = NULL; 397 BURN_PACKAGE* pUpgradeBundlePackage = NULL;
390 BURN_PACKAGE* pForwardCompatibleBundlePackage = NULL; 398 BURN_PACKAGE* pForwardCompatibleBundlePackage = NULL;
399 BOOL fContinuePlanning = TRUE; // assume we won't skip planning due to dependencies.
391 400
392 LogId(REPORT_STANDARD, MSG_PLAN_BEGIN, pEngineState->packages.cPackages, LoggingBurnActionToString(action)); 401 LogId(REPORT_STANDARD, MSG_PLAN_BEGIN, pEngineState->packages.cPackages, LoggingBurnActionToString(action));
393 402
@@ -395,7 +404,17 @@ extern "C" HRESULT CorePlan(
395 hr = UserExperienceOnPlanBegin(&pEngineState->userExperience, pEngineState->packages.cPackages); 404 hr = UserExperienceOnPlanBegin(&pEngineState->userExperience, pEngineState->packages.cPackages);
396 ExitOnRootFailure(hr, "BA aborted plan begin."); 405 ExitOnRootFailure(hr, "BA aborted plan begin.");
397 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
398 // Always reset the plan. 416 // Always reset the plan.
417 pEngineState->fPlanned = FALSE;
399 PlanReset(&pEngineState->plan, &pEngineState->packages); 418 PlanReset(&pEngineState->plan, &pEngineState->packages);
400 419
401 // Remember the overall action state in the plan since it shapes the changes 420 // Remember the overall action state in the plan since it shapes the changes
@@ -447,7 +466,6 @@ extern "C" HRESULT CorePlan(
447 } 466 }
448 else // doing an action that modifies the machine state. 467 else // doing an action that modifies the machine state.
449 { 468 {
450 BOOL fContinuePlanning = TRUE; // assume we'll be able to keep planning after registration.
451 pEngineState->plan.fPerMachine = pEngineState->registration.fPerMachine; // default the scope of the plan to the per-machine state of the bundle. 469 pEngineState->plan.fPerMachine = pEngineState->registration.fPerMachine; // default the scope of the plan to the per-machine state of the bundle.
452 470
453 hr = PlanRegistration(&pEngineState->plan, &pEngineState->registration, pEngineState->command.resumeType, pEngineState->command.relationType, &fContinuePlanning); 471 hr = PlanRegistration(&pEngineState->plan, &pEngineState->registration, pEngineState->command.resumeType, pEngineState->command.relationType, &fContinuePlanning);
@@ -477,12 +495,20 @@ extern "C" HRESULT CorePlan(
477 hr = PlanFinalizeActions(&pEngineState->plan); 495 hr = PlanFinalizeActions(&pEngineState->plan);
478 ExitOnFailure(hr, "Failed to remove unnecessary actions from plan."); 496 ExitOnFailure(hr, "Failed to remove unnecessary actions from plan.");
479 497
480 // Finally, display all packages and related bundles in the log. 498 if (fContinuePlanning)
481 LogPackages(pUpgradeBundlePackage, pForwardCompatibleBundlePackage, &pEngineState->packages, &pEngineState->registration.relatedBundles, action); 499 {
500 // Finally, display all packages and related bundles in the log.
501 LogPackages(pUpgradeBundlePackage, pForwardCompatibleBundlePackage, &pEngineState->packages, &pEngineState->registration.relatedBundles, action);
502 }
482 503
483 PlanDump(&pEngineState->plan); 504 PlanDump(&pEngineState->plan);
484 505
485LExit: 506LExit:
507 if (SUCCEEDED(hr))
508 {
509 pEngineState->fPlanned = TRUE;
510 }
511
486 if (fPlanBegan) 512 if (fPlanBegan)
487 { 513 {
488 UserExperienceOnPlanComplete(&pEngineState->userExperience, hr); 514 UserExperienceOnPlanComplete(&pEngineState->userExperience, hr);
@@ -549,6 +575,15 @@ extern "C" HRESULT CoreApply(
549 575
550 LogId(REPORT_STANDARD, MSG_APPLY_BEGIN); 576 LogId(REPORT_STANDARD, MSG_APPLY_BEGIN);
551 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
552 // Ensure any previous attempts to execute are reset. 587 // Ensure any previous attempts to execute are reset.
553 ApplyReset(&pEngineState->userExperience, &pEngineState->packages); 588 ApplyReset(&pEngineState->userExperience, &pEngineState->packages);
554 589
@@ -564,6 +599,8 @@ extern "C" HRESULT CoreApply(
564 hr = UserExperienceOnApplyBegin(&pEngineState->userExperience, dwPhaseCount); 599 hr = UserExperienceOnApplyBegin(&pEngineState->userExperience, dwPhaseCount);
565 ExitOnRootFailure(hr, "BA aborted apply begin."); 600 ExitOnRootFailure(hr, "BA aborted apply begin.");
566 601
602 pEngineState->fApplied = TRUE;
603
567 // Abort if this bundle already requires a restart. 604 // Abort if this bundle already requires a restart.
568 if (BOOTSTRAPPER_RESUME_TYPE_REBOOT_PENDING == pEngineState->command.resumeType) 605 if (BOOTSTRAPPER_RESUME_TYPE_REBOOT_PENDING == pEngineState->command.resumeType)
569 { 606 {
@@ -758,6 +795,8 @@ extern "C" HRESULT CoreQuit(
758 795
759 LogId(REPORT_STANDARD, MSG_QUIT, nExitCode); 796 LogId(REPORT_STANDARD, MSG_QUIT, nExitCode);
760 797
798 pEngineState->fQuit = TRUE;
799
761 ::PostQuitMessage(nExitCode); // go bye-bye. 800 ::PostQuitMessage(nExitCode); // go bye-bye.
762 801
763 return hr; 802 return hr;
diff --git a/src/engine/core.h b/src/engine/core.h
index fae4bfe5..fd7311e3 100644
--- a/src/engine/core.h
+++ b/src/engine/core.h
@@ -78,6 +78,10 @@ enum BURN_AU_PAUSE_ACTION
78typedef struct _BURN_ENGINE_STATE 78typedef struct _BURN_ENGINE_STATE
79{ 79{
80 // UX flow control 80 // UX flow control
81 BOOL fDetected;
82 BOOL fPlanned;
83 BOOL fApplied;
84 BOOL fQuit;
81 //BOOL fSuspend; // Is TRUE when UX made Suspend() call on core. 85 //BOOL fSuspend; // Is TRUE when UX made Suspend() call on core.
82 //BOOL fForcedReboot; // Is TRUE when UX made Reboot() call on core. 86 //BOOL fForcedReboot; // Is TRUE when UX made Reboot() call on core.
83 //BOOL fCancelled; // Is TRUE when UX return cancel on UX OnXXX() methods. 87 //BOOL fCancelled; // Is TRUE when UX return cancel on UX OnXXX() methods.
diff --git a/src/engine/engine.cpp b/src/engine/engine.cpp
index 2c6bad03..e3ace592 100644
--- a/src/engine/engine.cpp
+++ b/src/engine/engine.cpp
@@ -804,6 +804,12 @@ static HRESULT ProcessMessage(
804 804
805 UserExperienceActivateEngine(&pEngineState->userExperience); 805 UserExperienceActivateEngine(&pEngineState->userExperience);
806 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
807 switch (pmsg->message) 813 switch (pmsg->message)
808 { 814 {
809 case WM_BURN_DETECT: 815 case WM_BURN_DETECT:
@@ -831,6 +837,7 @@ static HRESULT ProcessMessage(
831 break; 837 break;
832 } 838 }
833 839
840LExit:
834 UserExperienceDeactivateEngine(&pEngineState->userExperience); 841 UserExperienceDeactivateEngine(&pEngineState->userExperience);
835 842
836 return hr; 843 return hr;
diff --git a/src/engine/engine.mc b/src/engine/engine.mc
index b120c5bb..d2135839 100644
--- a/src/engine/engine.mc
+++ b/src/engine/engine.mc
@@ -170,6 +170,13 @@ Language=English
170Condition '%1!ls!' contains invalid version string '%2!ls!'. 170Condition '%1!ls!' contains invalid version string '%2!ls!'.
171. 171.
172 172
173MessageId=58
174Severity=Warning
175SymbolicName=MSG_IGNORE_OPERATION_AFTER_QUIT
176Language=English
177Bootstrapper application already requested to quit, ignoring request: '%1!hs!'.
178.
179
173MessageId=100 180MessageId=100
174Severity=Success 181Severity=Success
175SymbolicName=MSG_DETECT_BEGIN 182SymbolicName=MSG_DETECT_BEGIN
diff --git a/src/engine/logging.cpp b/src/engine/logging.cpp
index 49b2bcc3..9dca527a 100644
--- a/src/engine/logging.cpp
+++ b/src/engine/logging.cpp
@@ -289,6 +289,29 @@ extern "C" LPCSTR LoggingBurnActionToString(
289 } 289 }
290} 290}
291 291
292LPCSTR 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
292extern "C" LPCSTR LoggingActionStateToString( 315extern "C" LPCSTR LoggingActionStateToString(
293 __in BOOTSTRAPPER_ACTION_STATE actionState 316 __in BOOTSTRAPPER_ACTION_STATE actionState
294 ) 317 )
diff --git a/src/engine/logging.h b/src/engine/logging.h
index 381a295b..b5c6c052 100644
--- a/src/engine/logging.h
+++ b/src/engine/logging.h
@@ -65,6 +65,10 @@ LPCSTR LoggingBurnActionToString(
65 __in BOOTSTRAPPER_ACTION action 65 __in BOOTSTRAPPER_ACTION action
66 ); 66 );
67 67
68LPCSTR LoggingBurnMessageToString(
69 __in UINT message
70 );
71
68LPCSTR LoggingActionStateToString( 72LPCSTR LoggingActionStateToString(
69 __in BOOTSTRAPPER_ACTION_STATE actionState 73 __in BOOTSTRAPPER_ACTION_STATE actionState
70 ); 74 );
diff --git a/src/test/BurnUnitTest/PlanTest.cpp b/src/test/BurnUnitTest/PlanTest.cpp
index 10b12e7b..a65bef4d 100644
--- a/src/test/BurnUnitTest/PlanTest.cpp
+++ b/src/test/BurnUnitTest/PlanTest.cpp
@@ -568,6 +568,7 @@ namespace Bootstrapper
568 NativeAssert::Succeeded(hr, "Failed to add the bundle provider key to the list of dependencies to ignore."); 568 NativeAssert::Succeeded(hr, "Failed to add the bundle provider key to the list of dependencies to ignore.");
569 569
570 pEngineState->userExperience.fEngineActive = TRUE; 570 pEngineState->userExperience.fEngineActive = TRUE;
571 pEngineState->fDetected = TRUE;
571 } 572 }
572 573
573 void DetectAttachedContainerAsAttached(BURN_ENGINE_STATE* pEngineState) 574 void DetectAttachedContainerAsAttached(BURN_ENGINE_STATE* pEngineState)