diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2022-03-18 20:16:07 -0500 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2022-03-19 12:07:32 -0500 |
| commit | fbc1a73743368211d5d8c7fc0625adf6eb9ca50c (patch) | |
| tree | c314d72b4b25afab7a27be664a1bffa5bdd80b3a /src/burn/engine/apply.cpp | |
| parent | fb54576f1d05e82ba47cd718c4c4f8b3bad624c9 (diff) | |
| download | wix-fbc1a73743368211d5d8c7fc0625adf6eb9ca50c.tar.gz wix-fbc1a73743368211d5d8c7fc0625adf6eb9ca50c.tar.bz2 wix-fbc1a73743368211d5d8c7fc0625adf6eb9ca50c.zip | |
Add checkpoint so Exe and Msu packages rollback after being cancelled.
Fixes 5950
Diffstat (limited to 'src/burn/engine/apply.cpp')
| -rw-r--r-- | src/burn/engine/apply.cpp | 93 |
1 files changed, 71 insertions, 22 deletions
diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp index 73b5b396..6af5c040 100644 --- a/src/burn/engine/apply.cpp +++ b/src/burn/engine/apply.cpp | |||
| @@ -63,6 +63,7 @@ typedef struct _BURN_EXECUTE_CONTEXT | |||
| 63 | LPCWSTR wzExecutingPackageId; | 63 | LPCWSTR wzExecutingPackageId; |
| 64 | DWORD cExecutedPackages; | 64 | DWORD cExecutedPackages; |
| 65 | DWORD cExecutePackagesTotal; | 65 | DWORD cExecutePackagesTotal; |
| 66 | BOOL fAbandonedProcess; | ||
| 66 | } BURN_EXECUTE_CONTEXT; | 67 | } BURN_EXECUTE_CONTEXT; |
| 67 | 68 | ||
| 68 | 69 | ||
| @@ -322,6 +323,7 @@ static HRESULT ExecutePackageComplete( | |||
| 322 | __in BURN_VARIABLES* pVariables, | 323 | __in BURN_VARIABLES* pVariables, |
| 323 | __in LPCWSTR wzPackageId, | 324 | __in LPCWSTR wzPackageId, |
| 324 | __in BOOL fPackageVital, | 325 | __in BOOL fPackageVital, |
| 326 | __in BOOL fAbandonedProcess, | ||
| 325 | __in HRESULT hrOverall, | 327 | __in HRESULT hrOverall, |
| 326 | __in HRESULT hrExecute, | 328 | __in HRESULT hrExecute, |
| 327 | __in BOOL fRollback, | 329 | __in BOOL fRollback, |
| @@ -369,6 +371,7 @@ extern "C" void ApplyReset( | |||
| 369 | BURN_PACKAGE* pPackage = pPackages->rgPackages + i; | 371 | BURN_PACKAGE* pPackage = pPackages->rgPackages + i; |
| 370 | pPackage->hrCacheResult = S_OK; | 372 | pPackage->hrCacheResult = S_OK; |
| 371 | pPackage->fReachedExecution = FALSE; | 373 | pPackage->fReachedExecution = FALSE; |
| 374 | pPackage->fAbandonedProcess = FALSE; | ||
| 372 | pPackage->transactionRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; | 375 | pPackage->transactionRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; |
| 373 | } | 376 | } |
| 374 | } | 377 | } |
| @@ -715,6 +718,9 @@ extern "C" HRESULT ApplyExecute( | |||
| 715 | continue; | 718 | continue; |
| 716 | } | 719 | } |
| 717 | 720 | ||
| 721 | context.wzExecutingPackageId = NULL; | ||
| 722 | context.fAbandonedProcess = FALSE; | ||
| 723 | |||
| 718 | // If we are seeking the end of the rollback boundary, skip if this action wasn't it. | 724 | // If we are seeking the end of the rollback boundary, skip if this action wasn't it. |
| 719 | if (fSeekRollbackBoundaryEnd) | 725 | if (fSeekRollbackBoundaryEnd) |
| 720 | { | 726 | { |
| @@ -2437,6 +2443,9 @@ static HRESULT DoRollbackActions( | |||
| 2437 | continue; | 2443 | continue; |
| 2438 | } | 2444 | } |
| 2439 | 2445 | ||
| 2446 | pContext->wzExecutingPackageId = NULL; | ||
| 2447 | pContext->fAbandonedProcess = FALSE; | ||
| 2448 | |||
| 2440 | if (BURN_EXECUTE_ACTION_TYPE_CHECKPOINT == pRollbackAction->type) | 2449 | if (BURN_EXECUTE_ACTION_TYPE_CHECKPOINT == pRollbackAction->type) |
| 2441 | { | 2450 | { |
| 2442 | if (pRollbackAction->checkpoint.dwId == dwCheckpoint) | 2451 | if (pRollbackAction->checkpoint.dwId == dwCheckpoint) |
| @@ -2533,6 +2542,28 @@ LExit: | |||
| 2533 | return hr; | 2542 | return hr; |
| 2534 | } | 2543 | } |
| 2535 | 2544 | ||
| 2545 | static BOOL ShouldSkipPackage( | ||
| 2546 | __in BURN_PACKAGE* pPackage, | ||
| 2547 | __in BOOL fRollback | ||
| 2548 | ) | ||
| 2549 | { | ||
| 2550 | BOOL fSkip = FALSE; | ||
| 2551 | |||
| 2552 | if (FAILED(pPackage->hrCacheResult)) | ||
| 2553 | { | ||
| 2554 | LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pPackage->sczId, pPackage->hrCacheResult); | ||
| 2555 | ExitFunction1(fSkip = TRUE); | ||
| 2556 | } | ||
| 2557 | else if (fRollback && pPackage->fAbandonedProcess) | ||
| 2558 | { | ||
| 2559 | LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_PACKAGE_WITH_ABANDONED_PROCESS, pPackage->sczId); | ||
| 2560 | ExitFunction1(fSkip = TRUE); | ||
| 2561 | } | ||
| 2562 | |||
| 2563 | LExit: | ||
| 2564 | return fSkip; | ||
| 2565 | } | ||
| 2566 | |||
| 2536 | static HRESULT ExecuteRelatedBundle( | 2567 | static HRESULT ExecuteRelatedBundle( |
| 2537 | __in BURN_ENGINE_STATE* pEngineState, | 2568 | __in BURN_ENGINE_STATE* pEngineState, |
| 2538 | __in BURN_EXECUTE_ACTION* pExecuteAction, | 2569 | __in BURN_EXECUTE_ACTION* pExecuteAction, |
| @@ -2551,13 +2582,13 @@ static HRESULT ExecuteRelatedBundle( | |||
| 2551 | BURN_RELATED_BUNDLE* pRelatedBundle = pExecuteAction->relatedBundle.pRelatedBundle; | 2582 | BURN_RELATED_BUNDLE* pRelatedBundle = pExecuteAction->relatedBundle.pRelatedBundle; |
| 2552 | BURN_PACKAGE* pPackage = &pRelatedBundle->package; | 2583 | BURN_PACKAGE* pPackage = &pRelatedBundle->package; |
| 2553 | 2584 | ||
| 2554 | if (FAILED(pPackage->hrCacheResult)) | 2585 | Assert(pContext->fRollback == fRollback); |
| 2586 | |||
| 2587 | if (ShouldSkipPackage(pPackage, fRollback)) | ||
| 2555 | { | 2588 | { |
| 2556 | LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pPackage->sczId, pPackage->hrCacheResult); | ||
| 2557 | ExitFunction1(hr = S_OK); | 2589 | ExitFunction1(hr = S_OK); |
| 2558 | } | 2590 | } |
| 2559 | 2591 | ||
| 2560 | Assert(pContext->fRollback == fRollback); | ||
| 2561 | pContext->wzExecutingPackageId = pPackage->sczId; | 2592 | pContext->wzExecutingPackageId = pPackage->sczId; |
| 2562 | fBeginCalled = TRUE; | 2593 | fBeginCalled = TRUE; |
| 2563 | 2594 | ||
| @@ -2599,7 +2630,8 @@ static HRESULT ExecuteRelatedBundle( | |||
| 2599 | LExit: | 2630 | LExit: |
| 2600 | if (fBeginCalled) | 2631 | if (fBeginCalled) |
| 2601 | { | 2632 | { |
| 2602 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | 2633 | pPackage->fAbandonedProcess = pContext->fAbandonedProcess; |
| 2634 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, pPackage->fAbandonedProcess, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | ||
| 2603 | } | 2635 | } |
| 2604 | 2636 | ||
| 2605 | return hr; | 2637 | return hr; |
| @@ -2624,6 +2656,9 @@ static HRESULT DoRestoreRelatedBundleActions( | |||
| 2624 | continue; | 2656 | continue; |
| 2625 | } | 2657 | } |
| 2626 | 2658 | ||
| 2659 | pContext->wzExecutingPackageId = NULL; | ||
| 2660 | pContext->fAbandonedProcess = FALSE; | ||
| 2661 | |||
| 2627 | BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE; | 2662 | BOOTSTRAPPER_APPLY_RESTART restart = BOOTSTRAPPER_APPLY_RESTART_NONE; |
| 2628 | switch (pRestoreRelatedBundleAction->type) | 2663 | switch (pRestoreRelatedBundleAction->type) |
| 2629 | { | 2664 | { |
| @@ -2665,13 +2700,13 @@ static HRESULT ExecuteExePackage( | |||
| 2665 | BOOL fExecuted = FALSE; | 2700 | BOOL fExecuted = FALSE; |
| 2666 | BURN_PACKAGE* pPackage = pExecuteAction->exePackage.pPackage; | 2701 | BURN_PACKAGE* pPackage = pExecuteAction->exePackage.pPackage; |
| 2667 | 2702 | ||
| 2668 | if (FAILED(pPackage->hrCacheResult)) | 2703 | Assert(pContext->fRollback == fRollback); |
| 2704 | |||
| 2705 | if (ShouldSkipPackage(pPackage, fRollback)) | ||
| 2669 | { | 2706 | { |
| 2670 | LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pPackage->sczId, pPackage->hrCacheResult); | ||
| 2671 | ExitFunction1(hr = S_OK); | 2707 | ExitFunction1(hr = S_OK); |
| 2672 | } | 2708 | } |
| 2673 | 2709 | ||
| 2674 | Assert(pContext->fRollback == fRollback); | ||
| 2675 | pContext->wzExecutingPackageId = pPackage->sczId; | 2710 | pContext->wzExecutingPackageId = pPackage->sczId; |
| 2676 | fBeginCalled = TRUE; | 2711 | fBeginCalled = TRUE; |
| 2677 | 2712 | ||
| @@ -2720,7 +2755,8 @@ LExit: | |||
| 2720 | 2755 | ||
| 2721 | if (fBeginCalled) | 2756 | if (fBeginCalled) |
| 2722 | { | 2757 | { |
| 2723 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | 2758 | pPackage->fAbandonedProcess = pContext->fAbandonedProcess; |
| 2759 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, pPackage->fAbandonedProcess, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | ||
| 2724 | } | 2760 | } |
| 2725 | 2761 | ||
| 2726 | return hr; | 2762 | return hr; |
| @@ -2743,13 +2779,13 @@ static HRESULT ExecuteMsiPackage( | |||
| 2743 | BOOL fExecuted = FALSE; | 2779 | BOOL fExecuted = FALSE; |
| 2744 | BURN_PACKAGE* pPackage = pExecuteAction->msiPackage.pPackage; | 2780 | BURN_PACKAGE* pPackage = pExecuteAction->msiPackage.pPackage; |
| 2745 | 2781 | ||
| 2746 | if (FAILED(pPackage->hrCacheResult)) | 2782 | Assert(pContext->fRollback == fRollback); |
| 2783 | |||
| 2784 | if (ShouldSkipPackage(pPackage, fRollback)) | ||
| 2747 | { | 2785 | { |
| 2748 | LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pPackage->sczId, pPackage->hrCacheResult); | ||
| 2749 | ExitFunction1(hr = S_OK); | 2786 | ExitFunction1(hr = S_OK); |
| 2750 | } | 2787 | } |
| 2751 | 2788 | ||
| 2752 | Assert(pContext->fRollback == fRollback); | ||
| 2753 | pContext->wzExecutingPackageId = pPackage->sczId; | 2789 | pContext->wzExecutingPackageId = pPackage->sczId; |
| 2754 | fBeginCalled = TRUE; | 2790 | fBeginCalled = TRUE; |
| 2755 | 2791 | ||
| @@ -2784,7 +2820,8 @@ LExit: | |||
| 2784 | 2820 | ||
| 2785 | if (fBeginCalled) | 2821 | if (fBeginCalled) |
| 2786 | { | 2822 | { |
| 2787 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | 2823 | Assert(!pContext->fAbandonedProcess); |
| 2824 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, FALSE, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | ||
| 2788 | } | 2825 | } |
| 2789 | 2826 | ||
| 2790 | return hr; | 2827 | return hr; |
| @@ -2807,13 +2844,13 @@ static HRESULT ExecuteMspPackage( | |||
| 2807 | BOOL fExecuted = FALSE; | 2844 | BOOL fExecuted = FALSE; |
| 2808 | BURN_PACKAGE* pPackage = pExecuteAction->mspTarget.pPackage; | 2845 | BURN_PACKAGE* pPackage = pExecuteAction->mspTarget.pPackage; |
| 2809 | 2846 | ||
| 2810 | if (FAILED(pPackage->hrCacheResult)) | 2847 | Assert(pContext->fRollback == fRollback); |
| 2848 | |||
| 2849 | if (ShouldSkipPackage(pPackage, fRollback)) | ||
| 2811 | { | 2850 | { |
| 2812 | LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pPackage->sczId, pPackage->hrCacheResult); | ||
| 2813 | ExitFunction1(hr = S_OK); | 2851 | ExitFunction1(hr = S_OK); |
| 2814 | } | 2852 | } |
| 2815 | 2853 | ||
| 2816 | Assert(pContext->fRollback == fRollback); | ||
| 2817 | pContext->wzExecutingPackageId = pPackage->sczId; | 2854 | pContext->wzExecutingPackageId = pPackage->sczId; |
| 2818 | fBeginCalled = TRUE; | 2855 | fBeginCalled = TRUE; |
| 2819 | 2856 | ||
| @@ -2857,7 +2894,8 @@ LExit: | |||
| 2857 | 2894 | ||
| 2858 | if (fBeginCalled) | 2895 | if (fBeginCalled) |
| 2859 | { | 2896 | { |
| 2860 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | 2897 | Assert(!pContext->fAbandonedProcess); |
| 2898 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, FALSE, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | ||
| 2861 | } | 2899 | } |
| 2862 | 2900 | ||
| 2863 | return hr; | 2901 | return hr; |
| @@ -2882,13 +2920,13 @@ static HRESULT ExecuteMsuPackage( | |||
| 2882 | BOOL fExecuted = FALSE; | 2920 | BOOL fExecuted = FALSE; |
| 2883 | BURN_PACKAGE* pPackage = pExecuteAction->msuPackage.pPackage; | 2921 | BURN_PACKAGE* pPackage = pExecuteAction->msuPackage.pPackage; |
| 2884 | 2922 | ||
| 2885 | if (FAILED(pPackage->hrCacheResult)) | 2923 | Assert(pContext->fRollback == fRollback); |
| 2924 | |||
| 2925 | if (ShouldSkipPackage(pPackage, fRollback)) | ||
| 2886 | { | 2926 | { |
| 2887 | LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pPackage->sczId, pPackage->hrCacheResult); | ||
| 2888 | ExitFunction1(hr = S_OK); | 2927 | ExitFunction1(hr = S_OK); |
| 2889 | } | 2928 | } |
| 2890 | 2929 | ||
| 2891 | Assert(pContext->fRollback == fRollback); | ||
| 2892 | pContext->wzExecutingPackageId = pPackage->sczId; | 2930 | pContext->wzExecutingPackageId = pPackage->sczId; |
| 2893 | fBeginCalled = TRUE; | 2931 | fBeginCalled = TRUE; |
| 2894 | 2932 | ||
| @@ -2937,7 +2975,8 @@ LExit: | |||
| 2937 | 2975 | ||
| 2938 | if (fBeginCalled) | 2976 | if (fBeginCalled) |
| 2939 | { | 2977 | { |
| 2940 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | 2978 | pPackage->fAbandonedProcess = pContext->fAbandonedProcess; |
| 2979 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pPackage->sczId, pPackage->fVital, pPackage->fAbandonedProcess, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | ||
| 2941 | } | 2980 | } |
| 2942 | 2981 | ||
| 2943 | return hr; | 2982 | return hr; |
| @@ -3256,7 +3295,8 @@ LExit: | |||
| 3256 | 3295 | ||
| 3257 | if (fBeginCalled) | 3296 | if (fBeginCalled) |
| 3258 | { | 3297 | { |
| 3259 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pContext->wzExecutingPackageId, FALSE, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | 3298 | Assert(!pContext->fAbandonedProcess); |
| 3299 | hr = ExecutePackageComplete(&pEngineState->userExperience, &pEngineState->variables, pContext->wzExecutingPackageId, FALSE, FALSE, hr, hrExecute, fRollback, pRestart, pfRetry, pfSuspend); | ||
| 3260 | } | 3300 | } |
| 3261 | 3301 | ||
| 3262 | return hr; | 3302 | return hr; |
| @@ -3334,6 +3374,14 @@ static int GenericExecuteMessageHandler( | |||
| 3334 | } | 3374 | } |
| 3335 | break; | 3375 | break; |
| 3336 | 3376 | ||
| 3377 | case GENERIC_EXECUTE_MESSAGE_PROCESS_STARTED: | ||
| 3378 | pContext->fAbandonedProcess = TRUE; | ||
| 3379 | break; | ||
| 3380 | |||
| 3381 | case GENERIC_EXECUTE_MESSAGE_PROCESS_COMPLETED: | ||
| 3382 | pContext->fAbandonedProcess = FALSE; | ||
| 3383 | break; | ||
| 3384 | |||
| 3337 | case GENERIC_EXECUTE_MESSAGE_ERROR: | 3385 | case GENERIC_EXECUTE_MESSAGE_ERROR: |
| 3338 | UserExperienceOnError(pContext->pUX, BOOTSTRAPPER_ERROR_TYPE_EXE_PACKAGE, pContext->wzExecutingPackageId, pMessage->error.dwErrorCode, pMessage->error.wzMessage, pMessage->dwUIHint, 0, NULL, &nResult); // ignore return value. | 3386 | UserExperienceOnError(pContext->pUX, BOOTSTRAPPER_ERROR_TYPE_EXE_PACKAGE, pContext->wzExecutingPackageId, pMessage->error.dwErrorCode, pMessage->error.wzMessage, pMessage->dwUIHint, 0, NULL, &nResult); // ignore return value. |
| 3339 | break; | 3387 | break; |
| @@ -3428,6 +3476,7 @@ static HRESULT ExecutePackageComplete( | |||
| 3428 | __in BURN_VARIABLES* pVariables, | 3476 | __in BURN_VARIABLES* pVariables, |
| 3429 | __in LPCWSTR wzPackageId, | 3477 | __in LPCWSTR wzPackageId, |
| 3430 | __in BOOL fPackageVital, | 3478 | __in BOOL fPackageVital, |
| 3479 | __in BOOL fAbandonedProcess, | ||
| 3431 | __in HRESULT hrOverall, | 3480 | __in HRESULT hrOverall, |
| 3432 | __in HRESULT hrExecute, | 3481 | __in HRESULT hrExecute, |
| 3433 | __in BOOL fRollback, | 3482 | __in BOOL fRollback, |
| @@ -3445,7 +3494,7 @@ static HRESULT ExecutePackageComplete( | |||
| 3445 | { | 3494 | { |
| 3446 | *pRestart = BOOTSTRAPPER_APPLY_RESTART_INITIATED; | 3495 | *pRestart = BOOTSTRAPPER_APPLY_RESTART_INITIATED; |
| 3447 | } | 3496 | } |
| 3448 | *pfRetry = (FAILED(hrExecute) && BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_RETRY == executePackageCompleteAction); // allow retry only on failures. | 3497 | *pfRetry = (FAILED(hrExecute) && BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_RETRY == executePackageCompleteAction && !fAbandonedProcess); // allow retry only on failures. |
| 3449 | *pfSuspend = (BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_SUSPEND == executePackageCompleteAction); | 3498 | *pfSuspend = (BOOTSTRAPPER_EXECUTEPACKAGECOMPLETE_ACTION_SUSPEND == executePackageCompleteAction); |
| 3450 | 3499 | ||
| 3451 | // Remember this package as the package that initiated the forced restart. | 3500 | // Remember this package as the package that initiated the forced restart. |
