diff options
Diffstat (limited to 'src/engine/plan.cpp')
-rw-r--r-- | src/engine/plan.cpp | 97 |
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 | ); |
140 | static 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 | ||
381 | LExit: | 374 | LExit: |
@@ -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 | ||
851 | LExit: | 844 | LExit: |
@@ -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 | ||
2525 | static 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 | |||
2527 | static void CacheActionLog( | 2534 | static void CacheActionLog( |
2528 | __in DWORD iAction, | 2535 | __in DWORD iAction, |
2529 | __in BURN_CACHE_ACTION* pAction, | 2536 | __in BURN_CACHE_ACTION* pAction, |