summaryrefslogtreecommitdiff
path: root/src/burn/engine/apply.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/burn/engine/apply.cpp')
-rw-r--r--src/burn/engine/apply.cpp93
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
2545static 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
2563LExit:
2564 return fSkip;
2565}
2566
2536static HRESULT ExecuteRelatedBundle( 2567static 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(
2599LExit: 2630LExit:
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.