aboutsummaryrefslogtreecommitdiff
path: root/src/engine/plan.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/plan.cpp')
-rw-r--r--src/engine/plan.cpp287
1 files changed, 164 insertions, 123 deletions
diff --git a/src/engine/plan.cpp b/src/engine/plan.cpp
index 86a07dfb..b3cb0ee3 100644
--- a/src/engine/plan.cpp
+++ b/src/engine/plan.cpp
@@ -154,11 +154,15 @@ static void RemoveUnnecessaryActions(
154 __in BURN_EXECUTE_ACTION* rgActions, 154 __in BURN_EXECUTE_ACTION* rgActions,
155 __in DWORD cActions 155 __in DWORD cActions
156 ); 156 );
157static HRESULT FinalizeSlipstreamPatchActions( 157static void FinalizePatchActions(
158 __in BOOL fExecute, 158 __in BOOL fExecute,
159 __in BURN_EXECUTE_ACTION* rgActions, 159 __in BURN_EXECUTE_ACTION* rgActions,
160 __in DWORD cActions 160 __in DWORD cActions
161 ); 161 );
162static void CalculateExpectedRegistrationStates(
163 __in BURN_PACKAGE* rgPackages,
164 __in DWORD cPackages
165 );
162static HRESULT PlanDependencyActions( 166static HRESULT PlanDependencyActions(
163 __in BOOL fBundlePerMachine, 167 __in BOOL fBundlePerMachine,
164 __in BURN_PLAN* pPlan, 168 __in BURN_PLAN* pPlan,
@@ -301,7 +305,6 @@ extern "C" void PlanUninitializeExecuteAction(
301 case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: 305 case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE:
302 ReleaseStr(pExecuteAction->msiPackage.sczLogPath); 306 ReleaseStr(pExecuteAction->msiPackage.sczLogPath);
303 ReleaseMem(pExecuteAction->msiPackage.rgFeatures); 307 ReleaseMem(pExecuteAction->msiPackage.rgFeatures);
304 ReleaseMem(pExecuteAction->msiPackage.rgSlipstreamPatches);
305 break; 308 break;
306 309
307 case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET: 310 case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET:
@@ -823,6 +826,8 @@ static HRESULT PlanPackagesHelper(
823 hr = PlanFinalizeActions(pPlan); 826 hr = PlanFinalizeActions(pPlan);
824 ExitOnFailure(hr, "Failed to remove unnecessary actions from plan."); 827 ExitOnFailure(hr, "Failed to remove unnecessary actions from plan.");
825 828
829 CalculateExpectedRegistrationStates(rgPackages, cPackages);
830
826 // Let the BA know the actions that were planned. 831 // Let the BA know the actions that were planned.
827 for (DWORD i = 0; i < cPackages; ++i) 832 for (DWORD i = 0; i < cPackages; ++i)
828 { 833 {
@@ -848,6 +853,12 @@ static HRESULT InitializePackage(
848 BOOL fInstallCondition = FALSE; 853 BOOL fInstallCondition = FALSE;
849 BOOL fBeginCalled = FALSE; 854 BOOL fBeginCalled = FALSE;
850 855
856 if (pPackage->fCanAffectRegistration)
857 {
858 pPackage->expectedCacheRegistrationState = pPackage->cacheRegistrationState;
859 pPackage->expectedInstallRegistrationState = pPackage->installRegistrationState;
860 }
861
851 if (pPackage->sczInstallCondition && *pPackage->sczInstallCondition) 862 if (pPackage->sczInstallCondition && *pPackage->sczInstallCondition)
852 { 863 {
853 hr = ConditionEvaluate(pVariables, pPackage->sczInstallCondition, &fInstallCondition); 864 hr = ConditionEvaluate(pVariables, pPackage->sczInstallCondition, &fInstallCondition);
@@ -903,68 +914,24 @@ static HRESULT ProcessPackage(
903 hr = ProcessPackageRollbackBoundary(pPlan, pEffectiveRollbackBoundary, ppRollbackBoundary); 914 hr = ProcessPackageRollbackBoundary(pPlan, pEffectiveRollbackBoundary, ppRollbackBoundary);
904 ExitOnFailure(hr, "Failed to process package rollback boundary."); 915 ExitOnFailure(hr, "Failed to process package rollback boundary.");
905 916
906 if (pPackage->fCanAffectRegistration) 917 if (BOOTSTRAPPER_ACTION_LAYOUT == pPlan->action)
907 { 918 {
908 pPackage->expectedCacheRegistrationState = pPackage->cacheRegistrationState; 919 hr = PlanLayoutPackage(pPlan, pPackage, wzLayoutDirectory);
909 pPackage->expectedInstallRegistrationState = pPackage->installRegistrationState; 920 ExitOnFailure(hr, "Failed to plan layout package.");
910 } 921 }
911 922 else
912 // If the package is in a requested state, plan it.
913 if (BOOTSTRAPPER_REQUEST_STATE_NONE != pPackage->requested)
914 { 923 {
915 if (BOOTSTRAPPER_ACTION_LAYOUT == pPlan->action) 924 if (BOOTSTRAPPER_REQUEST_STATE_NONE != pPackage->requested)
916 {
917 hr = PlanLayoutPackage(pPlan, pPackage, wzLayoutDirectory);
918 ExitOnFailure(hr, "Failed to plan layout package.");
919 }
920 else
921 { 925 {
926 // If the package is in a requested state, plan it.
922 hr = PlanExecutePackage(fBundlePerMachine, display, pUX, pPlan, pPackage, pLog, pVariables, phSyncpointEvent); 927 hr = PlanExecutePackage(fBundlePerMachine, display, pUX, pPlan, pPackage, pLog, pVariables, phSyncpointEvent);
923 ExitOnFailure(hr, "Failed to plan execute package."); 928 ExitOnFailure(hr, "Failed to plan execute package.");
924
925 if (pPackage->fCanAffectRegistration)
926 {
927 if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL < pPackage->execute)
928 {
929 pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
930 }
931 else if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pPackage->execute)
932 {
933 pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
934 }
935 }
936 }
937 }
938 else if (BOOTSTRAPPER_ACTION_LAYOUT != pPlan->action)
939 {
940 // Make sure the package is properly ref-counted even if no plan is requested.
941 hr = PlanDependencyActions(fBundlePerMachine, pPlan, pPackage);
942 ExitOnFailure(hr, "Failed to plan dependency actions for package: %ls", pPackage->sczId);
943 }
944
945 if (pPackage->fCanAffectRegistration)
946 {
947 if (BURN_DEPENDENCY_ACTION_REGISTER == pPackage->dependencyExecute)
948 {
949 if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pPackage->expectedCacheRegistrationState)
950 {
951 pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
952 }
953 if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pPackage->expectedInstallRegistrationState)
954 {
955 pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
956 }
957 } 929 }
958 else if (BURN_DEPENDENCY_ACTION_UNREGISTER == pPackage->dependencyExecute) 930 else
959 { 931 {
960 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->expectedCacheRegistrationState) 932 // Make sure the package is properly ref-counted even if no plan is requested.
961 { 933 hr = PlanDependencyActions(fBundlePerMachine, pPlan, pPackage);
962 pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED; 934 ExitOnFailure(hr, "Failed to plan dependency actions for package: %ls", pPackage->sczId);
963 }
964 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->expectedInstallRegistrationState)
965 {
966 pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
967 }
968 } 935 }
969 } 936 }
970 937
@@ -1498,17 +1465,14 @@ extern "C" HRESULT PlanFinalizeActions(
1498{ 1465{
1499 HRESULT hr = S_OK; 1466 HRESULT hr = S_OK;
1500 1467
1501 RemoveUnnecessaryActions(TRUE, pPlan->rgExecuteActions, pPlan->cExecuteActions); 1468 FinalizePatchActions(TRUE, pPlan->rgExecuteActions, pPlan->cExecuteActions);
1502 1469
1503 RemoveUnnecessaryActions(FALSE, pPlan->rgRollbackActions, pPlan->cRollbackActions); 1470 FinalizePatchActions(FALSE, pPlan->rgRollbackActions, pPlan->cRollbackActions);
1504 1471
1505 hr = FinalizeSlipstreamPatchActions(TRUE, pPlan->rgExecuteActions, pPlan->cExecuteActions); 1472 RemoveUnnecessaryActions(TRUE, pPlan->rgExecuteActions, pPlan->cExecuteActions);
1506 ExitOnFailure(hr, "Failed to finalize slipstream execute actions.");
1507 1473
1508 hr = FinalizeSlipstreamPatchActions(FALSE, pPlan->rgRollbackActions, pPlan->cRollbackActions); 1474 RemoveUnnecessaryActions(FALSE, pPlan->rgRollbackActions, pPlan->cRollbackActions);
1509 ExitOnFailure(hr, "Failed to finalize slipstream rollback actions.");
1510 1475
1511LExit:
1512 return hr; 1476 return hr;
1513} 1477}
1514 1478
@@ -1868,7 +1832,7 @@ static void ResetPlannedPackageState(
1868 pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; 1832 pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
1869 pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; 1833 pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
1870 1834
1871 if (BURN_PACKAGE_TYPE_MSI == pPackage->type && pPackage->Msi.rgFeatures) 1835 if (BURN_PACKAGE_TYPE_MSI == pPackage->type)
1872 { 1836 {
1873 for (DWORD i = 0; i < pPackage->Msi.cFeatures; ++i) 1837 for (DWORD i = 0; i < pPackage->Msi.cFeatures; ++i)
1874 { 1838 {
@@ -1880,6 +1844,14 @@ static void ResetPlannedPackageState(
1880 pFeature->execute = BOOTSTRAPPER_FEATURE_ACTION_NONE; 1844 pFeature->execute = BOOTSTRAPPER_FEATURE_ACTION_NONE;
1881 pFeature->rollback = BOOTSTRAPPER_FEATURE_ACTION_NONE; 1845 pFeature->rollback = BOOTSTRAPPER_FEATURE_ACTION_NONE;
1882 } 1846 }
1847
1848 for (DWORD i = 0; i < pPackage->Msi.cSlipstreamMspPackages; ++i)
1849 {
1850 BURN_SLIPSTREAM_MSP* pSlipstreamMsp = &pPackage->Msi.rgSlipstreamMsps[i];
1851
1852 pSlipstreamMsp->execute = BOOTSTRAPPER_ACTION_STATE_NONE;
1853 pSlipstreamMsp->rollback = BOOTSTRAPPER_ACTION_STATE_NONE;
1854 }
1883 } 1855 }
1884 else if (BURN_PACKAGE_TYPE_MSP == pPackage->type && pPackage->Msp.rgTargetProducts) 1856 else if (BURN_PACKAGE_TYPE_MSP == pPackage->type && pPackage->Msp.rgTargetProducts)
1885 { 1857 {
@@ -2716,101 +2688,165 @@ static void RemoveUnnecessaryActions(
2716 { 2688 {
2717 BURN_EXECUTE_ACTION* pAction = rgActions + i; 2689 BURN_EXECUTE_ACTION* pAction = rgActions + i;
2718 2690
2719 // If this MSP targets a package in the chain, check the target's execute state
2720 // to see if this patch should be skipped.
2721 if (BURN_EXECUTE_ACTION_TYPE_MSP_TARGET == pAction->type && pAction->mspTarget.pChainedTargetPackage) 2691 if (BURN_EXECUTE_ACTION_TYPE_MSP_TARGET == pAction->type && pAction->mspTarget.pChainedTargetPackage)
2722 { 2692 {
2693 BURN_MSPTARGETPRODUCT* pFirstTargetProduct = pAction->mspTarget.rgOrderedPatches->pTargetProduct;
2694 BURN_PATCH_SKIP_STATE skipState = fExecute ? pFirstTargetProduct->executeSkip : pFirstTargetProduct->rollbackSkip;
2723 BOOTSTRAPPER_ACTION_STATE chainedTargetPackageAction = fExecute ? pAction->mspTarget.pChainedTargetPackage->execute : pAction->mspTarget.pChainedTargetPackage->rollback; 2695 BOOTSTRAPPER_ACTION_STATE chainedTargetPackageAction = fExecute ? pAction->mspTarget.pChainedTargetPackage->execute : pAction->mspTarget.pChainedTargetPackage->rollback;
2724 BURN_PATCH_SKIP_STATE skipState = BURN_PATCH_SKIP_STATE_NONE;
2725 if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == chainedTargetPackageAction)
2726 {
2727 skipState = BURN_PATCH_SKIP_STATE_TARGET_UNINSTALL;
2728 LogId(REPORT_STANDARD, MSG_PLAN_SKIP_PATCH_ACTION, pAction->mspTarget.pPackage->sczId, LoggingActionStateToString(pAction->mspTarget.action), pAction->mspTarget.pChainedTargetPackage->sczId, LoggingActionStateToString(chainedTargetPackageAction), szExecuteOrRollback);
2729 }
2730 else if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL < chainedTargetPackageAction && pAction->mspTarget.fSlipstream && BOOTSTRAPPER_ACTION_STATE_UNINSTALL < pAction->mspTarget.action)
2731 {
2732 // If the slipstream target is being installed or upgraded (not uninstalled or repaired) then we will slipstream so skip
2733 // this action to install the patch standalone. Also, if the slipstream target is being repaired and the patch is being
2734 // repaired, skip this operation since it will be redundant.
2735 //
2736 // The primary goal here is to ensure that a slipstream patch that is yet not installed is installed even if the MSI
2737 // is already on the machine. The slipstream must be installed standalone if the MSI is being repaired.
2738 if (BOOTSTRAPPER_ACTION_STATE_REPAIR != chainedTargetPackageAction || BOOTSTRAPPER_ACTION_STATE_REPAIR == pAction->mspTarget.action)
2739 {
2740 skipState = BURN_PATCH_SKIP_STATE_SLIPSTREAM;
2741 LogId(REPORT_STANDARD, MSG_PLAN_SKIP_SLIPSTREAM_ACTION, pAction->mspTarget.pPackage->sczId, LoggingActionStateToString(pAction->mspTarget.action), pAction->mspTarget.pChainedTargetPackage->sczId, LoggingActionStateToString(chainedTargetPackageAction), szExecuteOrRollback);
2742 }
2743 }
2744 2696
2745 if (BURN_PATCH_SKIP_STATE_NONE != skipState) 2697 switch (skipState)
2746 { 2698 {
2699 case BURN_PATCH_SKIP_STATE_TARGET_UNINSTALL:
2747 pAction->fDeleted = TRUE; 2700 pAction->fDeleted = TRUE;
2748 2701 LogId(REPORT_STANDARD, MSG_PLAN_SKIP_PATCH_ACTION, pAction->mspTarget.pPackage->sczId, LoggingActionStateToString(pAction->mspTarget.action), pAction->mspTarget.pChainedTargetPackage->sczId, LoggingActionStateToString(chainedTargetPackageAction), szExecuteOrRollback);
2749 for (DWORD j = 0; j < pAction->mspTarget.cOrderedPatches; ++j) 2702 break;
2750 { 2703 case BURN_PATCH_SKIP_STATE_SLIPSTREAM:
2751 BURN_MSPTARGETPRODUCT* pTargetProduct = pAction->mspTarget.rgOrderedPatches[j].pTargetProduct; 2704 pAction->fDeleted = TRUE;
2752 2705 LogId(REPORT_STANDARD, MSG_PLAN_SKIP_SLIPSTREAM_ACTION, pAction->mspTarget.pPackage->sczId, LoggingActionStateToString(pAction->mspTarget.action), pAction->mspTarget.pChainedTargetPackage->sczId, LoggingActionStateToString(chainedTargetPackageAction), szExecuteOrRollback);
2753 if (fExecute) 2706 break;
2754 {
2755 pTargetProduct->executeSkip = skipState;
2756 }
2757 else
2758 {
2759 pTargetProduct->rollbackSkip = skipState;
2760 }
2761 }
2762 } 2707 }
2763 } 2708 }
2764 } 2709 }
2765} 2710}
2766 2711
2767static HRESULT FinalizeSlipstreamPatchActions( 2712static void FinalizePatchActions(
2768 __in BOOL fExecute, 2713 __in BOOL fExecute,
2769 __in BURN_EXECUTE_ACTION* rgActions, 2714 __in BURN_EXECUTE_ACTION* rgActions,
2770 __in DWORD cActions 2715 __in DWORD cActions
2771 ) 2716 )
2772{ 2717{
2773 HRESULT hr = S_OK;
2774
2775 for (DWORD i = 0; i < cActions; ++i) 2718 for (DWORD i = 0; i < cActions; ++i)
2776 { 2719 {
2777 BURN_EXECUTE_ACTION* pAction = rgActions + i; 2720 BURN_EXECUTE_ACTION* pAction = rgActions + i;
2778 2721
2779 // If this MSI package contains slipstream patches store the slipstream actions. 2722 if (BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE == pAction->type)
2780 if (BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE == pAction->type && pAction->msiPackage.pPackage->Msi.cSlipstreamMspPackages)
2781 { 2723 {
2782 BURN_PACKAGE* pPackage = pAction->msiPackage.pPackage; 2724 BURN_PACKAGE* pPackage = pAction->msiPackage.pPackage;
2725 AssertSz(BOOTSTRAPPER_ACTION_STATE_NONE < pAction->msiPackage.action, "Planned execute MSI action to do nothing");
2783 2726
2784 // By default all slipstream actions will be initialized to "no action" (aka: 0). 2727 if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pAction->msiPackage.action)
2785 pAction->msiPackage.rgSlipstreamPatches = (BOOTSTRAPPER_ACTION_STATE*)MemAlloc(sizeof(BOOTSTRAPPER_ACTION_STATE) * pPackage->Msi.cSlipstreamMspPackages, TRUE); 2728 {
2786 ExitOnNull(pAction->msiPackage.rgSlipstreamPatches, hr, E_OUTOFMEMORY, "Failed to allocate memory for patch actions."); 2729 // If we are uninstalling the MSI, we must skip all the patches.
2730 for (DWORD j = 0; j < pPackage->Msi.cChainedPatches; ++j)
2731 {
2732 BURN_CHAINED_PATCH* pChainedPatch = pPackage->Msi.rgChainedPatches + j;
2733 BURN_MSPTARGETPRODUCT* pTargetProduct = pChainedPatch->pMspPackage->Msp.rgTargetProducts + pChainedPatch->dwMspTargetProductIndex;
2787 2734
2788 // If we are uninstalling or repairing the MSI, we must ignore all the slipstream patches because they cannot 2735 if (fExecute)
2789 // be applied right now. 2736 {
2790 if (BOOTSTRAPPER_ACTION_STATE_REPAIR != pAction->msiPackage.action && BOOTSTRAPPER_ACTION_STATE_UNINSTALL != pAction->msiPackage.action) 2737 pTargetProduct->execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL;
2738 pTargetProduct->executeSkip = BURN_PATCH_SKIP_STATE_TARGET_UNINSTALL;
2739 }
2740 else
2741 {
2742 pTargetProduct->rollback = BOOTSTRAPPER_ACTION_STATE_UNINSTALL;
2743 pTargetProduct->rollbackSkip = BURN_PATCH_SKIP_STATE_TARGET_UNINSTALL;
2744 }
2745 }
2746 }
2747 else
2791 { 2748 {
2749 // If the slipstream target is being installed or upgraded (not uninstalled or repaired) then we will slipstream so skip
2750 // the patch's standalone action. Also, if the slipstream target is being repaired and the patch is being
2751 // repaired, skip this operation since it will be redundant.
2752 //
2753 // The primary goal here is to ensure that a slipstream patch that is yet not installed is installed even if the MSI
2754 // is already on the machine. The slipstream must be installed standalone if the MSI is being repaired.
2792 for (DWORD j = 0; j < pPackage->Msi.cSlipstreamMspPackages; ++j) 2755 for (DWORD j = 0; j < pPackage->Msi.cSlipstreamMspPackages; ++j)
2793 { 2756 {
2794 BURN_PACKAGE* pMspPackage = pPackage->Msi.rgSlipstreamMsps[j].pMspPackage; 2757 BURN_SLIPSTREAM_MSP* pSlipstreamMsp = pPackage->Msi.rgSlipstreamMsps + j;
2795 AssertSz(BURN_PACKAGE_TYPE_MSP == pMspPackage->type, "Only MSP packages can be slipstream patches."); 2758 BURN_CHAINED_PATCH* pChainedPatch = pPackage->Msi.rgChainedPatches + pSlipstreamMsp->dwMsiChainedPatchIndex;
2796 2759 BURN_MSPTARGETPRODUCT* pTargetProduct = pSlipstreamMsp->pMspPackage->Msp.rgTargetProducts + pChainedPatch->dwMspTargetProductIndex;
2797 pAction->msiPackage.rgSlipstreamPatches[j] = fExecute ? pMspPackage->execute : pMspPackage->rollback; 2760 BOOTSTRAPPER_ACTION_STATE action = fExecute ? pTargetProduct->execute : pTargetProduct->rollback;
2798 for (DWORD k = 0; k < pMspPackage->Msp.cTargetProductCodes; ++k) 2761 BOOL fSlipstream = BOOTSTRAPPER_ACTION_STATE_UNINSTALL < action &&
2762 (BOOTSTRAPPER_ACTION_STATE_REPAIR != pAction->msiPackage.action || BOOTSTRAPPER_ACTION_STATE_REPAIR == action);
2763
2764 if (fSlipstream)
2799 { 2765 {
2800 BURN_MSPTARGETPRODUCT* pTargetProduct = pMspPackage->Msp.rgTargetProducts + k; 2766 if (fExecute)
2801 if (pPackage == pTargetProduct->pChainedTargetPackage) 2767 {
2768 pSlipstreamMsp->execute = action;
2769 pTargetProduct->executeSkip = BURN_PATCH_SKIP_STATE_SLIPSTREAM;
2770 }
2771 else
2802 { 2772 {
2803 pAction->msiPackage.rgSlipstreamPatches[j] = fExecute ? pTargetProduct->execute : pTargetProduct->rollback; 2773 pSlipstreamMsp->rollback = action;
2804 break; 2774 pTargetProduct->rollbackSkip = BURN_PATCH_SKIP_STATE_SLIPSTREAM;
2805 } 2775 }
2806 } 2776 }
2807 } 2777 }
2808 } 2778 }
2809 } 2779 }
2810 } 2780 }
2781}
2811 2782
2812LExit: 2783static void CalculateExpectedRegistrationStates(
2813 return hr; 2784 __in BURN_PACKAGE* rgPackages,
2785 __in DWORD cPackages
2786 )
2787{
2788 for (DWORD i = 0; i < cPackages; ++i)
2789 {
2790 BURN_PACKAGE* pPackage = rgPackages + i;
2791
2792 // MspPackages can have actions throughout the plan, so the plan needed to be finalized before anything could be calculated.
2793 if (BURN_PACKAGE_TYPE_MSP == pPackage->type && !pPackage->fDependencyManagerWasHere)
2794 {
2795 pPackage->execute = BOOTSTRAPPER_ACTION_STATE_NONE;
2796 pPackage->rollback = BOOTSTRAPPER_ACTION_STATE_NONE;
2797
2798 for (DWORD j = 0; j < pPackage->Msp.cTargetProductCodes; ++j)
2799 {
2800 BURN_MSPTARGETPRODUCT* pTargetProduct = pPackage->Msp.rgTargetProducts + j;
2801
2802 // The highest aggregate action state found will be used.
2803 if (pPackage->execute < pTargetProduct->execute)
2804 {
2805 pPackage->execute = pTargetProduct->execute;
2806 }
2807
2808 if (pPackage->rollback < pTargetProduct->rollback)
2809 {
2810 pPackage->rollback = pTargetProduct->rollback;
2811 }
2812 }
2813 }
2814
2815 if (pPackage->fCanAffectRegistration)
2816 {
2817 if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL < pPackage->execute)
2818 {
2819 pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
2820 }
2821 else if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pPackage->execute)
2822 {
2823 pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
2824 }
2825
2826 if (BURN_DEPENDENCY_ACTION_REGISTER == pPackage->dependencyExecute)
2827 {
2828 if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pPackage->expectedCacheRegistrationState)
2829 {
2830 pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
2831 }
2832 if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pPackage->expectedInstallRegistrationState)
2833 {
2834 pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
2835 }
2836 }
2837 else if (BURN_DEPENDENCY_ACTION_UNREGISTER == pPackage->dependencyExecute)
2838 {
2839 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->expectedCacheRegistrationState)
2840 {
2841 pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
2842 }
2843 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->expectedInstallRegistrationState)
2844 {
2845 pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
2846 }
2847 }
2848 }
2849 }
2814} 2850}
2815 2851
2816static HRESULT PlanDependencyActions( 2852static HRESULT PlanDependencyActions(
@@ -3064,6 +3100,11 @@ static void ExecuteActionLog(
3064 3100
3065 case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE: 3101 case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE:
3066 LogStringLine(PlanDumpLevel, "%ls action[%u]: MSI_PACKAGE package id: %ls, action: %hs, action msi property: %ls, ui level: %u, disable externaluihandler: %ls, log path: %ls, logging attrib: %u", wzBase, iAction, pAction->msiPackage.pPackage->sczId, LoggingActionStateToString(pAction->msiPackage.action), LoggingBurnMsiPropertyToString(pAction->msiPackage.actionMsiProperty), pAction->msiPackage.uiLevel, pAction->msiPackage.fDisableExternalUiHandler ? L"yes" : L"no", pAction->msiPackage.sczLogPath, pAction->msiPackage.dwLoggingAttributes); 3102 LogStringLine(PlanDumpLevel, "%ls action[%u]: MSI_PACKAGE package id: %ls, action: %hs, action msi property: %ls, ui level: %u, disable externaluihandler: %ls, log path: %ls, logging attrib: %u", wzBase, iAction, pAction->msiPackage.pPackage->sczId, LoggingActionStateToString(pAction->msiPackage.action), LoggingBurnMsiPropertyToString(pAction->msiPackage.actionMsiProperty), pAction->msiPackage.uiLevel, pAction->msiPackage.fDisableExternalUiHandler ? L"yes" : L"no", pAction->msiPackage.sczLogPath, pAction->msiPackage.dwLoggingAttributes);
3103 for (DWORD j = 0; j < pAction->msiPackage.pPackage->Msi.cSlipstreamMspPackages; ++j)
3104 {
3105 const BURN_SLIPSTREAM_MSP* pSlipstreamMsp = pAction->msiPackage.pPackage->Msi.rgSlipstreamMsps + j;
3106 LogStringLine(PlanDumpLevel, " Patch[%u]: msp package id: %ls, action: %hs", j, pSlipstreamMsp->pMspPackage->sczId, LoggingActionStateToString(fRollback ? pSlipstreamMsp->rollback : pSlipstreamMsp->execute));
3107 }
3067 break; 3108 break;
3068 3109
3069 case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET: 3110 case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET: