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.cpp97
1 files changed, 52 insertions, 45 deletions
diff --git a/src/engine/plan.cpp b/src/engine/plan.cpp
index e5c1ee36..9a4aa5f1 100644
--- a/src/engine/plan.cpp
+++ b/src/engine/plan.cpp
@@ -137,6 +137,10 @@ static BOOL NeedsCache(
137 __in BURN_PACKAGE* pPackage, 137 __in BURN_PACKAGE* pPackage,
138 __in BOOL fExecute 138 __in BOOL fExecute
139 ); 139 );
140static BOOL ForceCache(
141 __in BURN_PLAN* pPlan,
142 __in BURN_PACKAGE* pPackage
143 );
140 144
141// function definitions 145// function definitions
142 146
@@ -312,28 +316,20 @@ extern "C" HRESULT PlanDefaultPackageRequestState(
312 __in BURN_PACKAGE_TYPE packageType, 316 __in BURN_PACKAGE_TYPE packageType,
313 __in BOOTSTRAPPER_PACKAGE_STATE currentState, 317 __in BOOTSTRAPPER_PACKAGE_STATE currentState,
314 __in BOOL fPermanent, 318 __in BOOL fPermanent,
315 __in BURN_CACHE_TYPE cacheType,
316 __in BOOTSTRAPPER_ACTION action, 319 __in BOOTSTRAPPER_ACTION action,
317 __in BOOL fInstallCondition, 320 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
318 __in BOOTSTRAPPER_RELATION_TYPE relationType, 321 __in BOOTSTRAPPER_RELATION_TYPE relationType,
319 __out BOOTSTRAPPER_REQUEST_STATE* pRequestState 322 __out BOOTSTRAPPER_REQUEST_STATE* pRequestState
320 ) 323 )
321{ 324{
322 HRESULT hr = S_OK; 325 HRESULT hr = S_OK;
323 BOOTSTRAPPER_REQUEST_STATE defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; 326 BOOTSTRAPPER_REQUEST_STATE defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
324 BOOL fFallbackToCache = BURN_CACHE_TYPE_ALWAYS == cacheType && BOOTSTRAPPER_ACTION_UNINSTALL != action && BOOTSTRAPPER_PACKAGE_STATE_CACHED > currentState;
325 327
326 // If doing layout, then always default to requesting the file be cached. 328 // If doing layout, then always default to requesting the package be cached.
327 if (BOOTSTRAPPER_ACTION_LAYOUT == action) 329 if (BOOTSTRAPPER_ACTION_LAYOUT == action)
328 { 330 {
329 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE; 331 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE;
330 } 332 }
331 else if (BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED == currentState && BOOTSTRAPPER_ACTION_UNINSTALL != action)
332 {
333 // Superseded means the package is on the machine but not active, so only uninstall operations are allowed.
334 // Requesting present makes sure always-cached packages are cached.
335 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
336 }
337 else if (BOOTSTRAPPER_RELATION_PATCH == relationType && BURN_PACKAGE_TYPE_MSP == packageType) 333 else if (BOOTSTRAPPER_RELATION_PATCH == relationType && BURN_PACKAGE_TYPE_MSP == packageType)
338 { 334 {
339 // For patch related bundles, only install a patch if currently absent during install, modify, or repair. 335 // For patch related bundles, only install a patch if currently absent during install, modify, or repair.
@@ -341,20 +337,22 @@ extern "C" HRESULT PlanDefaultPackageRequestState(
341 { 337 {
342 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; 338 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
343 } 339 }
344 else if (fFallbackToCache)
345 {
346 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE;
347 }
348 else 340 else
349 { 341 {
350 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; 342 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
351 } 343 }
352 } 344 }
345 else if (BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED == currentState && BOOTSTRAPPER_ACTION_UNINSTALL != action)
346 {
347 // Superseded means the package is on the machine but not active, so only uninstall operations are allowed.
348 // All other operations do nothing.
349 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
350 }
353 else if (BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE == currentState && !(BOOTSTRAPPER_ACTION_UNINSTALL == action && BURN_PACKAGE_TYPE_MSP == packageType)) 351 else if (BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE == currentState && !(BOOTSTRAPPER_ACTION_UNINSTALL == action && BURN_PACKAGE_TYPE_MSP == packageType))
354 { 352 {
355 // Obsolete means the package is not on the machine and should not be installed, *except* patches can be obsolete 353 // Obsolete means the package is not on the machine and should not be installed, *except* patches can be obsolete
356 // and present so allow them to be removed during uninstall. Everyone else, gets nothing. 354 // and present so allow them to be removed during uninstall. Everyone else, gets nothing.
357 *pRequestState = fFallbackToCache ? BOOTSTRAPPER_REQUEST_STATE_CACHE : BOOTSTRAPPER_REQUEST_STATE_NONE; 355 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
358 } 356 }
359 else // pick the best option for the action state and install condition. 357 else // pick the best option for the action state and install condition.
360 { 358 {
@@ -363,7 +361,7 @@ extern "C" HRESULT PlanDefaultPackageRequestState(
363 361
364 // If we're doing an install, use the install condition 362 // If we're doing an install, use the install condition
365 // to determine whether to use the default request state or make the package absent. 363 // to determine whether to use the default request state or make the package absent.
366 if (BOOTSTRAPPER_ACTION_UNINSTALL != action && !fInstallCondition) 364 if (BOOTSTRAPPER_ACTION_UNINSTALL != action && BOOTSTRAPPER_PACKAGE_CONDITION_FALSE == installCondition)
367 { 365 {
368 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT; 366 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT;
369 } 367 }
@@ -371,11 +369,6 @@ extern "C" HRESULT PlanDefaultPackageRequestState(
371 { 369 {
372 *pRequestState = defaultRequestState; 370 *pRequestState = defaultRequestState;
373 } 371 }
374
375 if (fFallbackToCache && BOOTSTRAPPER_REQUEST_STATE_CACHE > *pRequestState)
376 {
377 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE;
378 }
379 } 372 }
380 373
381LExit: 374LExit:
@@ -844,8 +837,8 @@ static HRESULT PlanPackagesHelper(
844 { 837 {
845 DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i; 838 DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i;
846 BURN_PACKAGE* pPackage = rgPackages + iPackage; 839 BURN_PACKAGE* pPackage = rgPackages + iPackage;
847 840
848 UserExperienceOnPlannedPackage(pUX, pPackage->sczId, pPackage->execute, pPackage->rollback); 841 UserExperienceOnPlannedPackage(pUX, pPackage->sczId, pPackage->execute, pPackage->rollback, pPackage->fPlannedCache, pPackage->fPlannedUncache);
849 } 842 }
850 843
851LExit: 844LExit:
@@ -861,6 +854,7 @@ static HRESULT InitializePackage(
861 ) 854 )
862{ 855{
863 HRESULT hr = S_OK; 856 HRESULT hr = S_OK;
857 BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition = BOOTSTRAPPER_PACKAGE_CONDITION_DEFAULT;
864 BOOL fInstallCondition = FALSE; 858 BOOL fInstallCondition = FALSE;
865 BOOL fBeginCalled = FALSE; 859 BOOL fBeginCalled = FALSE;
866 860
@@ -874,20 +868,18 @@ static HRESULT InitializePackage(
874 { 868 {
875 hr = ConditionEvaluate(pVariables, pPackage->sczInstallCondition, &fInstallCondition); 869 hr = ConditionEvaluate(pVariables, pPackage->sczInstallCondition, &fInstallCondition);
876 ExitOnFailure(hr, "Failed to evaluate install condition."); 870 ExitOnFailure(hr, "Failed to evaluate install condition.");
877 } 871
878 else 872 installCondition = fInstallCondition ? BOOTSTRAPPER_PACKAGE_CONDITION_TRUE : BOOTSTRAPPER_PACKAGE_CONDITION_FALSE;
879 {
880 fInstallCondition = TRUE;
881 } 873 }
882 874
883 // Remember the default requested state so the engine doesn't get blamed for planning the wrong thing if the BA changes it. 875 // Remember the default requested state so the engine doesn't get blamed for planning the wrong thing if the BA changes it.
884 hr = PlanDefaultPackageRequestState(pPackage->type, pPackage->currentState, !pPackage->fUninstallable, pPackage->cacheType, pPlan->action, fInstallCondition, relationType, &pPackage->defaultRequested); 876 hr = PlanDefaultPackageRequestState(pPackage->type, pPackage->currentState, !pPackage->fUninstallable, pPlan->action, installCondition, relationType, &pPackage->defaultRequested);
885 ExitOnFailure(hr, "Failed to set default package state."); 877 ExitOnFailure(hr, "Failed to set default package state.");
886 878
887 pPackage->requested = pPackage->defaultRequested; 879 pPackage->requested = pPackage->defaultRequested;
888 fBeginCalled = TRUE; 880 fBeginCalled = TRUE;
889 881
890 hr = UserExperienceOnPlanPackageBegin(pUX, pPackage->sczId, pPackage->currentState, fInstallCondition, &pPackage->requested); 882 hr = UserExperienceOnPlanPackageBegin(pUX, pPackage->sczId, pPackage->currentState, pPackage->fCached, installCondition, &pPackage->requested, &pPackage->cacheType);
891 ExitOnRootFailure(hr, "BA aborted plan package begin."); 883 ExitOnRootFailure(hr, "BA aborted plan package begin.");
892 884
893 if (BURN_PACKAGE_TYPE_MSI == pPackage->type) 885 if (BURN_PACKAGE_TYPE_MSI == pPackage->type)
@@ -926,8 +918,11 @@ static HRESULT ProcessPackage(
926 918
927 if (BOOTSTRAPPER_ACTION_LAYOUT == pPlan->action) 919 if (BOOTSTRAPPER_ACTION_LAYOUT == pPlan->action)
928 { 920 {
929 hr = PlanLayoutPackage(pPlan, pPackage); 921 if (BOOTSTRAPPER_REQUEST_STATE_NONE != pPackage->requested)
930 ExitOnFailure(hr, "Failed to plan layout package."); 922 {
923 hr = PlanLayoutPackage(pPlan, pPackage);
924 ExitOnFailure(hr, "Failed to plan layout package.");
925 }
931 } 926 }
932 else 927 else
933 { 928 {
@@ -939,6 +934,17 @@ static HRESULT ProcessPackage(
939 } 934 }
940 else 935 else
941 { 936 {
937 if (ForceCache(pPlan, pPackage))
938 {
939 hr = AddCachePackage(pPlan, pPackage, phSyncpointEvent);
940 ExitOnFailure(hr, "Failed to plan cache package.");
941
942 if (pPackage->fPerMachine)
943 {
944 pPlan->fPerMachine = TRUE;
945 }
946 }
947
942 // Make sure the package is properly ref-counted even if no plan is requested. 948 // Make sure the package is properly ref-counted even if no plan is requested.
943 hr = PlanDependencyActions(fBundlePerMachine, pPlan, pPackage); 949 hr = PlanDependencyActions(fBundlePerMachine, pPlan, pPackage);
944 ExitOnFailure(hr, "Failed to plan dependency actions for package: %ls", pPackage->sczId); 950 ExitOnFailure(hr, "Failed to plan dependency actions for package: %ls", pPackage->sczId);
@@ -1072,8 +1078,7 @@ extern "C" HRESULT PlanExecutePackage(
1072 ) 1078 )
1073{ 1079{
1074 HRESULT hr = S_OK; 1080 HRESULT hr = S_OK;
1075 BOOL fRequestedCache = BOOTSTRAPPER_REQUEST_STATE_CACHE == pPackage->requested || 1081 BOOL fRequestedCache = BOOTSTRAPPER_REQUEST_STATE_CACHE == pPackage->requested || ForceCache(pPlan, pPackage);
1076 BOOTSTRAPPER_REQUEST_STATE_ABSENT < pPackage->requested && BURN_CACHE_TYPE_ALWAYS == pPackage->cacheType;
1077 1082
1078 hr = CalculateExecuteActions(pPackage, pPlan->pActiveRollbackBoundary); 1083 hr = CalculateExecuteActions(pPackage, pPlan->pActiveRollbackBoundary);
1079 ExitOnFailure(hr, "Failed to calculate plan actions for package: %ls", pPackage->sczId); 1084 ExitOnFailure(hr, "Failed to calculate plan actions for package: %ls", pPackage->sczId);
@@ -1097,12 +1102,12 @@ extern "C" HRESULT PlanExecutePackage(
1097 1102
1098 // Add the cache and install size to estimated size if it will be on the machine at the end of the install 1103 // Add the cache and install size to estimated size if it will be on the machine at the end of the install
1099 if (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested || 1104 if (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested ||
1100 BOOTSTRAPPER_REQUEST_STATE_CACHE == pPackage->requested || 1105 fRequestedCache ||
1101 (BOOTSTRAPPER_PACKAGE_STATE_PRESENT == pPackage->currentState && BOOTSTRAPPER_REQUEST_STATE_ABSENT < pPackage->requested) 1106 (BOOTSTRAPPER_PACKAGE_STATE_PRESENT == pPackage->currentState && BOOTSTRAPPER_REQUEST_STATE_ABSENT < pPackage->requested)
1102 ) 1107 )
1103 { 1108 {
1104 // If the package will remain in the cache, add the package size to the estimated size 1109 // If the package will remain in the cache, add the package size to the estimated size
1105 if (BURN_CACHE_TYPE_NO < pPackage->cacheType) 1110 if (BOOTSTRAPPER_CACHE_TYPE_REMOVE < pPackage->cacheType)
1106 { 1111 {
1107 pPlan->qwEstimatedSize += pPackage->qwSize; 1112 pPlan->qwEstimatedSize += pPackage->qwSize;
1108 } 1113 }
@@ -1522,12 +1527,12 @@ extern "C" HRESULT PlanCleanPackage(
1522 BURN_CLEAN_ACTION* pCleanAction = NULL; 1527 BURN_CLEAN_ACTION* pCleanAction = NULL;
1523 1528
1524 // The following is a complex set of logic that determines when a package should be cleaned from the cache. 1529 // The following is a complex set of logic that determines when a package should be cleaned from the cache.
1525 if (BURN_CACHE_TYPE_ALWAYS > pPackage->cacheType || BOOTSTRAPPER_ACTION_CACHE > pPlan->action) 1530 if (BOOTSTRAPPER_CACHE_TYPE_FORCE > pPackage->cacheType || BOOTSTRAPPER_ACTION_CACHE > pPlan->action)
1526 { 1531 {
1527 // The following are all different reasons why the package should be cleaned from the cache. 1532 // The following are all different reasons why the package should be cleaned from the cache.
1528 // The else-ifs are used to make the conditions easier to see (rather than have them combined 1533 // The else-ifs are used to make the conditions easier to see (rather than have them combined
1529 // in one huge condition). 1534 // in one huge condition).
1530 if (BURN_CACHE_TYPE_YES > pPackage->cacheType) // easy, package is not supposed to stay cached. 1535 if (BOOTSTRAPPER_CACHE_TYPE_KEEP > pPackage->cacheType) // easy, package is not supposed to stay cached.
1531 { 1536 {
1532 fPlanCleanPackage = TRUE; 1537 fPlanCleanPackage = TRUE;
1533 } 1538 }
@@ -1867,6 +1872,7 @@ static void ResetPlannedPackageState(
1867 ) 1872 )
1868{ 1873{
1869 // Reset package state that is a result of planning. 1874 // Reset package state that is a result of planning.
1875 pPackage->cacheType = pPackage->authoredCacheType;
1870 pPackage->defaultRequested = BOOTSTRAPPER_REQUEST_STATE_NONE; 1876 pPackage->defaultRequested = BOOTSTRAPPER_REQUEST_STATE_NONE;
1871 pPackage->requested = BOOTSTRAPPER_REQUEST_STATE_NONE; 1877 pPackage->requested = BOOTSTRAPPER_REQUEST_STATE_NONE;
1872 pPackage->fPlannedCache = FALSE; 1878 pPackage->fPlannedCache = FALSE;
@@ -1948,10 +1954,6 @@ static HRESULT GetActionDefaultRequestState(
1948 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; 1954 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
1949 break; 1955 break;
1950 1956
1951 case BOOTSTRAPPER_PACKAGE_STATE_CACHED:
1952 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
1953 break;
1954
1955 default: 1957 default:
1956 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE; 1958 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE;
1957 break; 1959 break;
@@ -1979,10 +1981,6 @@ static HRESULT GetActionDefaultRequestState(
1979 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT; 1981 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT;
1980 break; 1982 break;
1981 1983
1982 case BOOTSTRAPPER_PACKAGE_STATE_CACHED:
1983 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE;
1984 break;
1985
1986 case BOOTSTRAPPER_PACKAGE_STATE_PRESENT: 1984 case BOOTSTRAPPER_PACKAGE_STATE_PRESENT:
1987 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; 1985 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
1988 break; 1986 break;
@@ -2524,6 +2522,15 @@ static BOOL NeedsCache(
2524 } 2522 }
2525} 2523}
2526 2524
2525static BOOL ForceCache(
2526 __in BURN_PLAN* pPlan,
2527 __in BURN_PACKAGE* pPackage
2528 )
2529{
2530 // All packages that have cacheType set to force should be cached if the bundle is going to be present.
2531 return BOOTSTRAPPER_CACHE_TYPE_FORCE == pPackage->cacheType && BOOTSTRAPPER_ACTION_UNINSTALL < pPlan->action;
2532}
2533
2527static void CacheActionLog( 2534static void CacheActionLog(
2528 __in DWORD iAction, 2535 __in DWORD iAction,
2529 __in BURN_CACHE_ACTION* pAction, 2536 __in BURN_CACHE_ACTION* pAction,