aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-02-03 17:16:21 -0600
committerSean Hall <r.sean.hall@gmail.com>2021-02-04 22:16:10 -0600
commitdc992c49f30e0d2b912a6449a33b4448ef862f31 (patch)
treec93be4f365aeb0b87b7a361d55bdb34999b3d2d7
parentc6c17104b50936432a3fe9ca214ba9a3dfa32780 (diff)
downloadwix-dc992c49f30e0d2b912a6449a33b4448ef862f31.tar.gz
wix-dc992c49f30e0d2b912a6449a33b4448ef862f31.tar.bz2
wix-dc992c49f30e0d2b912a6449a33b4448ef862f31.zip
Change the implementation of Cache="always" to request the CACHE state.
This makes it possible for the prereq BA to not cache those packages while installing the prereqs, which allows the engine to automatically cleanup if necessary. #6297 for this commit and the previous 6.
-rw-r--r--src/engine/plan.cpp96
-rw-r--r--src/engine/plan.h9
-rw-r--r--src/test/BurnUnitTest/PlanTest.cpp2
3 files changed, 30 insertions, 77 deletions
diff --git a/src/engine/plan.cpp b/src/engine/plan.cpp
index 1aaec252..a11d0e78 100644
--- a/src/engine/plan.cpp
+++ b/src/engine/plan.cpp
@@ -153,7 +153,6 @@ static HRESULT CalculateExecuteActions(
153 __out_opt BOOL* pfBARequestedCache 153 __out_opt BOOL* pfBARequestedCache
154 ); 154 );
155static BOOL NeedsCache( 155static BOOL NeedsCache(
156 __in BURN_PLAN* pPlan,
157 __in BURN_PACKAGE* pPackage 156 __in BURN_PACKAGE* pPackage
158 ); 157 );
159static HRESULT CreateContainerProgress( 158static HRESULT CreateContainerProgress(
@@ -323,6 +322,7 @@ extern "C" HRESULT PlanDefaultPackageRequestState(
323 __in BURN_PACKAGE_TYPE packageType, 322 __in BURN_PACKAGE_TYPE packageType,
324 __in BOOTSTRAPPER_PACKAGE_STATE currentState, 323 __in BOOTSTRAPPER_PACKAGE_STATE currentState,
325 __in BOOL fPermanent, 324 __in BOOL fPermanent,
325 __in BURN_CACHE_TYPE cacheType,
326 __in BOOTSTRAPPER_ACTION action, 326 __in BOOTSTRAPPER_ACTION action,
327 __in BURN_VARIABLES* pVariables, 327 __in BURN_VARIABLES* pVariables,
328 __in_z_opt LPCWSTR wzInstallCondition, 328 __in_z_opt LPCWSTR wzInstallCondition,
@@ -333,12 +333,19 @@ extern "C" HRESULT PlanDefaultPackageRequestState(
333 HRESULT hr = S_OK; 333 HRESULT hr = S_OK;
334 BOOTSTRAPPER_REQUEST_STATE defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; 334 BOOTSTRAPPER_REQUEST_STATE defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
335 BOOL fCondition = FALSE; 335 BOOL fCondition = FALSE;
336 BOOL fFallbackToCache = BURN_CACHE_TYPE_ALWAYS == cacheType && BOOTSTRAPPER_ACTION_UNINSTALL != action && BOOTSTRAPPER_PACKAGE_STATE_CACHED > currentState;
336 337
337 // If doing layout, then always default to requesting the file be cached. 338 // If doing layout, then always default to requesting the file be cached.
338 if (BOOTSTRAPPER_ACTION_LAYOUT == action) 339 if (BOOTSTRAPPER_ACTION_LAYOUT == action)
339 { 340 {
340 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE; 341 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE;
341 } 342 }
343 else if (BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED == currentState && BOOTSTRAPPER_ACTION_UNINSTALL != action)
344 {
345 // Superseded means the package is on the machine but not active, so only uninstall operations are allowed.
346 // Requesting present makes sure always-cached packages are cached.
347 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
348 }
342 else if (BOOTSTRAPPER_RELATION_PATCH == relationType && BURN_PACKAGE_TYPE_MSP == packageType) 349 else if (BOOTSTRAPPER_RELATION_PATCH == relationType && BURN_PACKAGE_TYPE_MSP == packageType)
343 { 350 {
344 // For patch related bundles, only install a patch if currently absent during install, modify, or repair. 351 // For patch related bundles, only install a patch if currently absent during install, modify, or repair.
@@ -346,22 +353,20 @@ extern "C" HRESULT PlanDefaultPackageRequestState(
346 { 353 {
347 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; 354 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
348 } 355 }
356 else if (fFallbackToCache)
357 {
358 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE;
359 }
349 else 360 else
350 { 361 {
351 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; 362 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
352 } 363 }
353 } 364 }
354 else if (BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED == currentState && BOOTSTRAPPER_ACTION_UNINSTALL != action)
355 {
356 // Superseded means the package is on the machine but not active, so only uninstall operations are allowed.
357 // All other operations do nothing.
358 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
359 }
360 else if (BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE == currentState && !(BOOTSTRAPPER_ACTION_UNINSTALL == action && BURN_PACKAGE_TYPE_MSP == packageType)) 365 else if (BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE == currentState && !(BOOTSTRAPPER_ACTION_UNINSTALL == action && BURN_PACKAGE_TYPE_MSP == packageType))
361 { 366 {
362 // Obsolete means the package is not on the machine and should not be installed, *except* patches can be obsolete 367 // Obsolete means the package is not on the machine and should not be installed, *except* patches can be obsolete
363 // and present so allow them to be removed during uninstall. Everyone else, gets nothing. 368 // and present so allow them to be removed during uninstall. Everyone else, gets nothing.
364 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; 369 *pRequestState = fFallbackToCache ? BOOTSTRAPPER_REQUEST_STATE_CACHE : BOOTSTRAPPER_REQUEST_STATE_NONE;
365 } 370 }
366 else // pick the best option for the action state and install condition. 371 else // pick the best option for the action state and install condition.
367 { 372 {
@@ -381,6 +386,11 @@ extern "C" HRESULT PlanDefaultPackageRequestState(
381 { 386 {
382 *pRequestState = defaultRequestState; 387 *pRequestState = defaultRequestState;
383 } 388 }
389
390 if (fFallbackToCache && BOOTSTRAPPER_REQUEST_STATE_CACHE > *pRequestState)
391 {
392 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE;
393 }
384 } 394 }
385 395
386LExit: 396LExit:
@@ -816,7 +826,7 @@ static HRESULT ProcessPackage(
816 BOOL fPlanPackageBegan = FALSE; 826 BOOL fPlanPackageBegan = FALSE;
817 827
818 // Remember the default requested state so the engine doesn't get blamed for planning the wrong thing if the BA changes it. 828 // Remember the default requested state so the engine doesn't get blamed for planning the wrong thing if the BA changes it.
819 hr = PlanDefaultPackageRequestState(pPackage->type, pPackage->currentState, !pPackage->fUninstallable, pPlan->action, pVariables, pPackage->sczInstallCondition, relationType, &pPackage->defaultRequested); 829 hr = PlanDefaultPackageRequestState(pPackage->type, pPackage->currentState, !pPackage->fUninstallable, pPackage->cacheType, pPlan->action, pVariables, pPackage->sczInstallCondition, relationType, &pPackage->defaultRequested);
820 ExitOnFailure(hr, "Failed to set default package state."); 830 ExitOnFailure(hr, "Failed to set default package state.");
821 831
822 pPackage->requested = pPackage->defaultRequested; 832 pPackage->requested = pPackage->defaultRequested;
@@ -863,18 +873,9 @@ static HRESULT ProcessPackage(
863 } 873 }
864 else if (BOOTSTRAPPER_ACTION_LAYOUT != pPlan->action) 874 else if (BOOTSTRAPPER_ACTION_LAYOUT != pPlan->action)
865 { 875 {
866 // All packages that have cacheType set to always should be cached if the bundle is going to be present. 876 // Make sure the package is properly ref-counted even if no plan is requested.
867 if (BURN_CACHE_TYPE_ALWAYS == pPackage->cacheType && BOOTSTRAPPER_ACTION_INSTALL <= pPlan->action) 877 hr = PlanDependencyActions(fBundlePerMachine, pPlan, pPackage);
868 { 878 ExitOnFailure(hr, "Failed to plan dependency actions for package: %ls", pPackage->sczId);
869 hr = PlanCachePackage(fBundlePerMachine, pUX, pPlan, pPackage, pVariables, phSyncpointEvent);
870 ExitOnFailure(hr, "Failed to plan cache package.");
871 }
872 else
873 {
874 // Make sure the package is properly ref-counted even if no plan is requested.
875 hr = PlanDependencyActions(fBundlePerMachine, pPlan, pPackage);
876 ExitOnFailure(hr, "Failed to plan dependency actions for package: %ls", pPackage->sczId);
877 }
878 } 879 }
879 880
880 if (pPackage->fCanAffectRegistration) 881 if (pPackage->fCanAffectRegistration)
@@ -1008,41 +1009,6 @@ LExit:
1008 return hr; 1009 return hr;
1009} 1010}
1010 1011
1011extern "C" HRESULT PlanCachePackage(
1012 __in BOOL fPerMachine,
1013 __in BURN_USER_EXPERIENCE* pUserExperience,
1014 __in BURN_PLAN* pPlan,
1015 __in BURN_PACKAGE* pPackage,
1016 __in BURN_VARIABLES* pVariables,
1017 __out HANDLE* phSyncpointEvent
1018 )
1019{
1020 HRESULT hr = S_OK;
1021 BOOL fBARequestedCache = FALSE;
1022
1023 // Calculate the execute actions because we need them to decide whether the package should be cached.
1024 hr = CalculateExecuteActions(pUserExperience, pPackage, pVariables, pPlan->pActiveRollbackBoundary, &fBARequestedCache);
1025 ExitOnFailure(hr, "Failed to calculate execute actions for package: %ls", pPackage->sczId);
1026
1027 if (fBARequestedCache || NeedsCache(pPlan, pPackage))
1028 {
1029 hr = AddCachePackage(pPlan, pPackage, phSyncpointEvent);
1030 ExitOnFailure(hr, "Failed to plan cache package.");
1031
1032 if (pPackage->fPerMachine)
1033 {
1034 pPlan->fPerMachine = TRUE;
1035 }
1036 }
1037
1038 // Make sure the package is properly ref-counted.
1039 hr = PlanDependencyActions(fPerMachine, pPlan, pPackage);
1040 ExitOnFailure(hr, "Failed to plan dependency actions for package: %ls", pPackage->sczId);
1041
1042LExit:
1043 return hr;
1044}
1045
1046extern "C" HRESULT PlanExecutePackage( 1012extern "C" HRESULT PlanExecutePackage(
1047 __in BOOL fPerMachine, 1013 __in BOOL fPerMachine,
1048 __in BOOTSTRAPPER_DISPLAY display, 1014 __in BOOTSTRAPPER_DISPLAY display,
@@ -1064,7 +1030,7 @@ extern "C" HRESULT PlanExecutePackage(
1064 hr = DependencyPlanPackageBegin(fPerMachine, pPackage, pPlan); 1030 hr = DependencyPlanPackageBegin(fPerMachine, pPackage, pPlan);
1065 ExitOnFailure(hr, "Failed to begin plan dependency actions for package: %ls", pPackage->sczId); 1031 ExitOnFailure(hr, "Failed to begin plan dependency actions for package: %ls", pPackage->sczId);
1066 1032
1067 if (fBARequestedCache || NeedsCache(pPlan, pPackage)) 1033 if (fBARequestedCache || NeedsCache(pPackage))
1068 { 1034 {
1069 hr = AddCachePackage(pPlan, pPackage, phSyncpointEvent); 1035 hr = AddCachePackage(pPlan, pPackage, phSyncpointEvent);
1070 ExitOnFailure(hr, "Failed to plan cache package."); 1036 ExitOnFailure(hr, "Failed to plan cache package.");
@@ -1079,12 +1045,12 @@ extern "C" HRESULT PlanExecutePackage(
1079 1045
1080 // Add the cache and install size to estimated size if it will be on the machine at the end of the install 1046 // Add the cache and install size to estimated size if it will be on the machine at the end of the install
1081 if (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested || 1047 if (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested ||
1082 (BOOTSTRAPPER_PACKAGE_STATE_PRESENT == pPackage->currentState && BOOTSTRAPPER_REQUEST_STATE_ABSENT < pPackage->requested) || 1048 BOOTSTRAPPER_REQUEST_STATE_CACHE == pPackage->requested ||
1083 BURN_CACHE_TYPE_ALWAYS == pPackage->cacheType 1049 (BOOTSTRAPPER_PACKAGE_STATE_PRESENT == pPackage->currentState && BOOTSTRAPPER_REQUEST_STATE_ABSENT < pPackage->requested)
1084 ) 1050 )
1085 { 1051 {
1086 // If the package will remain in the cache, add the package size to the estimated size 1052 // If the package will remain in the cache, add the package size to the estimated size
1087 if (BURN_CACHE_TYPE_YES <= pPackage->cacheType) 1053 if (BURN_CACHE_TYPE_NO < pPackage->cacheType)
1088 { 1054 {
1089 pPlan->qwEstimatedSize += pPackage->qwSize; 1055 pPlan->qwEstimatedSize += pPackage->qwSize;
1090 } 1056 }
@@ -1511,7 +1477,7 @@ extern "C" HRESULT PlanCleanPackage(
1511 // from the cache. Start by noting that we only clean if the package is being acquired or 1477 // from the cache. Start by noting that we only clean if the package is being acquired or
1512 // already cached and the package is not supposed to always be cached. 1478 // already cached and the package is not supposed to always be cached.
1513 if ((pPackage->fAcquire || BURN_CACHE_STATE_PARTIAL == pPackage->cache || BURN_CACHE_STATE_COMPLETE == pPackage->cache) && 1479 if ((pPackage->fAcquire || BURN_CACHE_STATE_PARTIAL == pPackage->cache || BURN_CACHE_STATE_COMPLETE == pPackage->cache) &&
1514 (BURN_CACHE_TYPE_ALWAYS > pPackage->cacheType || BOOTSTRAPPER_ACTION_INSTALL > pPlan->action)) 1480 (BURN_CACHE_TYPE_ALWAYS > pPackage->cacheType || BOOTSTRAPPER_ACTION_CACHE > pPlan->action))
1515 { 1481 {
1516 // The following are all different reasons why the package should be cleaned from the cache. 1482 // The following are all different reasons why the package should be cleaned from the cache.
1517 // The else-ifs are used to make the conditions easier to see (rather than have them combined 1483 // The else-ifs are used to make the conditions easier to see (rather than have them combined
@@ -2836,16 +2802,10 @@ LExit:
2836} 2802}
2837 2803
2838static BOOL NeedsCache( 2804static BOOL NeedsCache(
2839 __in BURN_PLAN* pPlan,
2840 __in BURN_PACKAGE* pPackage 2805 __in BURN_PACKAGE* pPackage
2841 ) 2806 )
2842{ 2807{
2843 // All packages that have cacheType set to always should be cached if the bundle is going to be present. 2808 if (BURN_PACKAGE_TYPE_EXE == pPackage->type) // Exe packages require the package for all operations (even uninstall).
2844 if (BURN_CACHE_TYPE_ALWAYS == pPackage->cacheType && BOOTSTRAPPER_ACTION_INSTALL <= pPlan->action)
2845 {
2846 return TRUE;
2847 }
2848 else if (BURN_PACKAGE_TYPE_EXE == pPackage->type) // Exe packages require the package for all operations (even uninstall).
2849 { 2809 {
2850 return BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute; 2810 return BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute;
2851 } 2811 }
diff --git a/src/engine/plan.h b/src/engine/plan.h
index 6c12b5fa..2f6c9dd3 100644
--- a/src/engine/plan.h
+++ b/src/engine/plan.h
@@ -380,6 +380,7 @@ HRESULT PlanDefaultPackageRequestState(
380 __in BURN_PACKAGE_TYPE packageType, 380 __in BURN_PACKAGE_TYPE packageType,
381 __in BOOTSTRAPPER_PACKAGE_STATE currentState, 381 __in BOOTSTRAPPER_PACKAGE_STATE currentState,
382 __in BOOL fPermanent, 382 __in BOOL fPermanent,
383 __in BURN_CACHE_TYPE cacheType,
383 __in BOOTSTRAPPER_ACTION action, 384 __in BOOTSTRAPPER_ACTION action,
384 __in BURN_VARIABLES* pVariables, 385 __in BURN_VARIABLES* pVariables,
385 __in_z_opt LPCWSTR wzInstallCondition, 386 __in_z_opt LPCWSTR wzInstallCondition,
@@ -439,14 +440,6 @@ HRESULT PlanLayoutPackage(
439 __in BURN_PACKAGE* pPackage, 440 __in BURN_PACKAGE* pPackage,
440 __in_z_opt LPCWSTR wzLayoutDirectory 441 __in_z_opt LPCWSTR wzLayoutDirectory
441 ); 442 );
442HRESULT PlanCachePackage(
443 __in BOOL fPerMachine,
444 __in BURN_USER_EXPERIENCE* pUserExperience,
445 __in BURN_PLAN* pPlan,
446 __in BURN_PACKAGE* pPackage,
447 __in BURN_VARIABLES* pVariables,
448 __out HANDLE* phSyncpointEvent
449 );
450HRESULT PlanExecutePackage( 443HRESULT PlanExecutePackage(
451 __in BOOL fPerMachine, 444 __in BOOL fPerMachine,
452 __in BOOTSTRAPPER_DISPLAY display, 445 __in BOOTSTRAPPER_DISPLAY display,
diff --git a/src/test/BurnUnitTest/PlanTest.cpp b/src/test/BurnUnitTest/PlanTest.cpp
index a50c64e1..629c293f 100644
--- a/src/test/BurnUnitTest/PlanTest.cpp
+++ b/src/test/BurnUnitTest/PlanTest.cpp
@@ -317,7 +317,7 @@ namespace Bootstrapper
317 dwIndex = 0; 317 dwIndex = 0;
318 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); 318 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
319 319
320 Assert::Equal(0ull, pPlan->qwEstimatedSize); 320 Assert::Equal(33743ull, pPlan->qwEstimatedSize);
321 Assert::Equal(33743ull, pPlan->qwCacheSizeTotal); 321 Assert::Equal(33743ull, pPlan->qwCacheSizeTotal);
322 322
323 fRollback = FALSE; 323 fRollback = FALSE;