diff options
Diffstat (limited to 'src/engine/plan.cpp')
-rw-r--r-- | src/engine/plan.cpp | 287 |
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 | ); |
157 | static HRESULT FinalizeSlipstreamPatchActions( | 157 | static 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 | ); |
162 | static void CalculateExpectedRegistrationStates( | ||
163 | __in BURN_PACKAGE* rgPackages, | ||
164 | __in DWORD cPackages | ||
165 | ); | ||
162 | static HRESULT PlanDependencyActions( | 166 | static 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 | ||
1511 | LExit: | ||
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 | ||
2767 | static HRESULT FinalizeSlipstreamPatchActions( | 2712 | static 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 | ||
2812 | LExit: | 2783 | static 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 | ||
2816 | static HRESULT PlanDependencyActions( | 2852 | static 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: |