diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2021-02-02 16:57:33 -0600 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2021-02-04 22:16:10 -0600 |
commit | 39725a1a6d1c72a6748bd3c306af32bcae6dbf8f (patch) | |
tree | fe37f5ad08878e2f8d36c92762a784fd13c39df2 | |
parent | bb7d4bdc09d0b52a65b8cf3b5ae629f385fc8011 (diff) | |
download | wix-39725a1a6d1c72a6748bd3c306af32bcae6dbf8f.tar.gz wix-39725a1a6d1c72a6748bd3c306af32bcae6dbf8f.tar.bz2 wix-39725a1a6d1c72a6748bd3c306af32bcae6dbf8f.zip |
Require re-Detect after Apply.
-rw-r--r-- | src/engine/core.cpp | 53 | ||||
-rw-r--r-- | src/engine/core.h | 4 | ||||
-rw-r--r-- | src/engine/engine.cpp | 7 | ||||
-rw-r--r-- | src/engine/engine.mc | 7 | ||||
-rw-r--r-- | src/engine/logging.cpp | 23 | ||||
-rw-r--r-- | src/engine/logging.h | 4 | ||||
-rw-r--r-- | src/test/BurnUnitTest/PlanTest.cpp | 1 |
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 | ||
485 | LExit: | 506 | LExit: |
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 | |||
78 | typedef struct _BURN_ENGINE_STATE | 78 | typedef 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 | ||
840 | LExit: | ||
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 | |||
170 | Condition '%1!ls!' contains invalid version string '%2!ls!'. | 170 | Condition '%1!ls!' contains invalid version string '%2!ls!'. |
171 | . | 171 | . |
172 | 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 | |||
173 | MessageId=100 | 180 | MessageId=100 |
174 | Severity=Success | 181 | Severity=Success |
175 | SymbolicName=MSG_DETECT_BEGIN | 182 | SymbolicName=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 | ||
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 | |||
292 | extern "C" LPCSTR LoggingActionStateToString( | 315 | extern "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 | ||
68 | LPCSTR LoggingBurnMessageToString( | ||
69 | __in UINT message | ||
70 | ); | ||
71 | |||
68 | LPCSTR LoggingActionStateToString( | 72 | LPCSTR 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) |