aboutsummaryrefslogtreecommitdiff
path: root/src/engine/plan.cpp
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-04-16 09:40:18 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-04-19 23:12:55 -0500
commit941c47e5a3f57ce9626b447a95740b1444e69343 (patch)
tree6225b78f5fc7c8f88a2abf187a6a76d45b36ec26 /src/engine/plan.cpp
parentd32f770ca05748df9e356444c7e617d5eeedb60c (diff)
downloadwix-941c47e5a3f57ce9626b447a95740b1444e69343.tar.gz
wix-941c47e5a3f57ce9626b447a95740b1444e69343.tar.bz2
wix-941c47e5a3f57ce9626b447a95740b1444e69343.zip
Detect a package as cached if any of its payloads exist.
Detect is supposed to be fast, so it can't fully verify every payload for every package. The engine was wasting its time by trying to verify file sizes without the hash. Even worse, it was making decisions during planning based on that insufficient verification. Contributes to #3640
Diffstat (limited to 'src/engine/plan.cpp')
-rw-r--r--src/engine/plan.cpp76
1 files changed, 31 insertions, 45 deletions
diff --git a/src/engine/plan.cpp b/src/engine/plan.cpp
index c75c1753..187b1f15 100644
--- a/src/engine/plan.cpp
+++ b/src/engine/plan.cpp
@@ -31,8 +31,7 @@ static HRESULT PlanPackagesHelper(
31 __in BURN_VARIABLES* pVariables, 31 __in BURN_VARIABLES* pVariables,
32 __in BOOTSTRAPPER_DISPLAY display, 32 __in BOOTSTRAPPER_DISPLAY display,
33 __in BOOTSTRAPPER_RELATION_TYPE relationType, 33 __in BOOTSTRAPPER_RELATION_TYPE relationType,
34 __in_z_opt LPCWSTR wzLayoutDirectory, 34 __in_z_opt LPCWSTR wzLayoutDirectory
35 __inout HANDLE* phSyncpointEvent
36 ); 35 );
37static HRESULT InitializePackage( 36static HRESULT InitializePackage(
38 __in BURN_PLAN* pPlan, 37 __in BURN_PLAN* pPlan,
@@ -564,13 +563,12 @@ extern "C" HRESULT PlanPackages(
564 __in BURN_VARIABLES* pVariables, 563 __in BURN_VARIABLES* pVariables,
565 __in BOOTSTRAPPER_DISPLAY display, 564 __in BOOTSTRAPPER_DISPLAY display,
566 __in BOOTSTRAPPER_RELATION_TYPE relationType, 565 __in BOOTSTRAPPER_RELATION_TYPE relationType,
567 __in_z_opt LPCWSTR wzLayoutDirectory, 566 __in_z_opt LPCWSTR wzLayoutDirectory
568 __inout HANDLE* phSyncpointEvent
569 ) 567 )
570{ 568{
571 HRESULT hr = S_OK; 569 HRESULT hr = S_OK;
572 570
573 hr = PlanPackagesHelper(pPackages->rgPackages, pPackages->cPackages, TRUE, pUX, pPlan, pLog, pVariables, display, relationType, wzLayoutDirectory, phSyncpointEvent); 571 hr = PlanPackagesHelper(pPackages->rgPackages, pPackages->cPackages, TRUE, pUX, pPlan, pLog, pVariables, display, relationType, wzLayoutDirectory);
574 572
575 return hr; 573 return hr;
576} 574}
@@ -776,8 +774,7 @@ extern "C" HRESULT PlanPassThroughBundle(
776 __in BURN_LOGGING* pLog, 774 __in BURN_LOGGING* pLog,
777 __in BURN_VARIABLES* pVariables, 775 __in BURN_VARIABLES* pVariables,
778 __in BOOTSTRAPPER_DISPLAY display, 776 __in BOOTSTRAPPER_DISPLAY display,
779 __in BOOTSTRAPPER_RELATION_TYPE relationType, 777 __in BOOTSTRAPPER_RELATION_TYPE relationType
780 __inout HANDLE* phSyncpointEvent
781 ) 778 )
782{ 779{
783 HRESULT hr = S_OK; 780 HRESULT hr = S_OK;
@@ -785,7 +782,7 @@ extern "C" HRESULT PlanPassThroughBundle(
785 // Plan passthrough package. 782 // Plan passthrough package.
786 // Passthrough packages are never cleaned up by the calling bundle (they delete themselves when appropriate) 783 // Passthrough packages are never cleaned up by the calling bundle (they delete themselves when appropriate)
787 // so we don't need to plan clean up. 784 // so we don't need to plan clean up.
788 hr = PlanPackagesHelper(pPackage, 1, FALSE, pUX, pPlan, pLog, pVariables, display, relationType, NULL, phSyncpointEvent); 785 hr = PlanPackagesHelper(pPackage, 1, FALSE, pUX, pPlan, pLog, pVariables, display, relationType, NULL);
789 ExitOnFailure(hr, "Failed to process passthrough package."); 786 ExitOnFailure(hr, "Failed to process passthrough package.");
790 787
791LExit: 788LExit:
@@ -799,14 +796,13 @@ extern "C" HRESULT PlanUpdateBundle(
799 __in BURN_LOGGING* pLog, 796 __in BURN_LOGGING* pLog,
800 __in BURN_VARIABLES* pVariables, 797 __in BURN_VARIABLES* pVariables,
801 __in BOOTSTRAPPER_DISPLAY display, 798 __in BOOTSTRAPPER_DISPLAY display,
802 __in BOOTSTRAPPER_RELATION_TYPE relationType, 799 __in BOOTSTRAPPER_RELATION_TYPE relationType
803 __inout HANDLE* phSyncpointEvent
804 ) 800 )
805{ 801{
806 HRESULT hr = S_OK; 802 HRESULT hr = S_OK;
807 803
808 // Plan update package. 804 // Plan update package.
809 hr = PlanPackagesHelper(pPackage, 1, TRUE, pUX, pPlan, pLog, pVariables, display, relationType, NULL, phSyncpointEvent); 805 hr = PlanPackagesHelper(pPackage, 1, TRUE, pUX, pPlan, pLog, pVariables, display, relationType, NULL);
810 ExitOnFailure(hr, "Failed to process update package."); 806 ExitOnFailure(hr, "Failed to process update package.");
811 807
812LExit: 808LExit:
@@ -823,13 +819,13 @@ static HRESULT PlanPackagesHelper(
823 __in BURN_VARIABLES* pVariables, 819 __in BURN_VARIABLES* pVariables,
824 __in BOOTSTRAPPER_DISPLAY display, 820 __in BOOTSTRAPPER_DISPLAY display,
825 __in BOOTSTRAPPER_RELATION_TYPE relationType, 821 __in BOOTSTRAPPER_RELATION_TYPE relationType,
826 __in_z_opt LPCWSTR wzLayoutDirectory, 822 __in_z_opt LPCWSTR wzLayoutDirectory
827 __inout HANDLE* phSyncpointEvent
828 ) 823 )
829{ 824{
830 HRESULT hr = S_OK; 825 HRESULT hr = S_OK;
831 BOOL fBundlePerMachine = pPlan->fPerMachine; // bundle is per-machine if plan starts per-machine. 826 BOOL fBundlePerMachine = pPlan->fPerMachine; // bundle is per-machine if plan starts per-machine.
832 BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL; 827 BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL;
828 HANDLE hSyncpointEvent = NULL;
833 829
834 // Initialize the packages. 830 // Initialize the packages.
835 for (DWORD i = 0; i < cPackages; ++i) 831 for (DWORD i = 0; i < cPackages; ++i)
@@ -860,7 +856,7 @@ static HRESULT PlanPackagesHelper(
860 DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i; 856 DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i;
861 BURN_PACKAGE* pPackage = rgPackages + iPackage; 857 BURN_PACKAGE* pPackage = rgPackages + iPackage;
862 858
863 hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, display, wzLayoutDirectory, phSyncpointEvent, &pRollbackBoundary); 859 hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, display, wzLayoutDirectory, &hSyncpointEvent, &pRollbackBoundary);
864 ExitOnFailure(hr, "Failed to process package."); 860 ExitOnFailure(hr, "Failed to process package.");
865 } 861 }
866 862
@@ -1126,10 +1122,11 @@ extern "C" HRESULT PlanExecutePackage(
1126 hr = AddCachePackage(pPlan, pPackage, phSyncpointEvent); 1122 hr = AddCachePackage(pPlan, pPackage, phSyncpointEvent);
1127 ExitOnFailure(hr, "Failed to plan cache package."); 1123 ExitOnFailure(hr, "Failed to plan cache package.");
1128 } 1124 }
1129 else if (BURN_CACHE_STATE_COMPLETE != pPackage->cache && NeedsCache(pPackage, FALSE)) 1125 else if (!pPackage->fCached && NeedsCache(pPackage, FALSE))
1130 { 1126 {
1127 // TODO: this decision should be made during apply instead of plan based on whether the package is actually cached.
1131 // If the package is not in the cache, disable any rollback that would require the package from the cache. 1128 // If the package is not in the cache, disable any rollback that would require the package from the cache.
1132 LogId(REPORT_STANDARD, MSG_PLAN_DISABLING_ROLLBACK_NO_CACHE, pPackage->sczId, LoggingCacheStateToString(pPackage->cache), LoggingActionStateToString(pPackage->rollback)); 1129 LogId(REPORT_STANDARD, MSG_PLAN_DISABLING_ROLLBACK_NO_CACHE, pPackage->sczId, LoggingActionStateToString(pPackage->rollback));
1133 pPackage->rollback = BOOTSTRAPPER_ACTION_STATE_NONE; 1130 pPackage->rollback = BOOTSTRAPPER_ACTION_STATE_NONE;
1134 } 1131 }
1135 1132
@@ -1162,19 +1159,19 @@ extern "C" HRESULT PlanExecutePackage(
1162 switch (pPackage->type) 1159 switch (pPackage->type)
1163 { 1160 {
1164 case BURN_PACKAGE_TYPE_EXE: 1161 case BURN_PACKAGE_TYPE_EXE:
1165 hr = ExeEnginePlanAddPackage(NULL, pPackage, pPlan, pLog, pVariables, *phSyncpointEvent, pPackage->fAcquire); 1162 hr = ExeEnginePlanAddPackage(NULL, pPackage, pPlan, pLog, pVariables, *phSyncpointEvent);
1166 break; 1163 break;
1167 1164
1168 case BURN_PACKAGE_TYPE_MSI: 1165 case BURN_PACKAGE_TYPE_MSI:
1169 hr = MsiEnginePlanAddPackage(display, pUserExperience, pPackage, pPlan, pLog, pVariables, *phSyncpointEvent, pPackage->fAcquire); 1166 hr = MsiEnginePlanAddPackage(display, pUserExperience, pPackage, pPlan, pLog, pVariables, *phSyncpointEvent);
1170 break; 1167 break;
1171 1168
1172 case BURN_PACKAGE_TYPE_MSP: 1169 case BURN_PACKAGE_TYPE_MSP:
1173 hr = MspEnginePlanAddPackage(display, pUserExperience, pPackage, pPlan, pLog, pVariables, *phSyncpointEvent, pPackage->fAcquire); 1170 hr = MspEnginePlanAddPackage(display, pUserExperience, pPackage, pPlan, pLog, pVariables, *phSyncpointEvent);
1174 break; 1171 break;
1175 1172
1176 case BURN_PACKAGE_TYPE_MSU: 1173 case BURN_PACKAGE_TYPE_MSU:
1177 hr = MsuEnginePlanAddPackage(pPackage, pPlan, pLog, pVariables, *phSyncpointEvent, pPackage->fAcquire); 1174 hr = MsuEnginePlanAddPackage(pPackage, pPlan, pLog, pVariables, *phSyncpointEvent);
1178 break; 1175 break;
1179 1176
1180 default: 1177 default:
@@ -1368,7 +1365,6 @@ extern "C" HRESULT PlanRelatedBundlesComplete(
1368 __in BURN_PLAN* pPlan, 1365 __in BURN_PLAN* pPlan,
1369 __in BURN_LOGGING* pLog, 1366 __in BURN_LOGGING* pLog,
1370 __in BURN_VARIABLES* pVariables, 1367 __in BURN_VARIABLES* pVariables,
1371 __inout HANDLE* phSyncpointEvent,
1372 __in DWORD dwExecuteActionEarlyIndex 1368 __in DWORD dwExecuteActionEarlyIndex
1373 ) 1369 )
1374{ 1370{
@@ -1488,7 +1484,7 @@ extern "C" HRESULT PlanRelatedBundlesComplete(
1488 } 1484 }
1489 } 1485 }
1490 1486
1491 hr = ExeEnginePlanAddPackage(pdwInsertIndex, &pRelatedBundle->package, pPlan, pLog, pVariables, *phSyncpointEvent, FALSE); 1487 hr = ExeEnginePlanAddPackage(pdwInsertIndex, &pRelatedBundle->package, pPlan, pLog, pVariables, NULL);
1492 ExitOnFailure(hr, "Failed to add to plan related bundle: %ls", pRelatedBundle->package.sczId); 1488 ExitOnFailure(hr, "Failed to add to plan related bundle: %ls", pRelatedBundle->package.sczId);
1493 1489
1494 // Calculate package states based on reference count for addon and patch related bundles. 1490 // Calculate package states based on reference count for addon and patch related bundles.
@@ -1560,11 +1556,8 @@ extern "C" HRESULT PlanCleanPackage(
1560 BOOL fPlanCleanPackage = FALSE; 1556 BOOL fPlanCleanPackage = FALSE;
1561 BURN_CLEAN_ACTION* pCleanAction = NULL; 1557 BURN_CLEAN_ACTION* pCleanAction = NULL;
1562 1558
1563 // The following is a complex set of logic that determines when a package should be cleaned 1559 // The following is a complex set of logic that determines when a package should be cleaned from the cache.
1564 // from the cache. Start by noting that we only clean if the package is being acquired or 1560 if (BURN_CACHE_TYPE_ALWAYS > pPackage->cacheType || BOOTSTRAPPER_ACTION_CACHE > pPlan->action)
1565 // already cached and the package is not supposed to always be cached.
1566 if ((pPackage->fAcquire || BURN_CACHE_STATE_PARTIAL == pPackage->cache || BURN_CACHE_STATE_COMPLETE == pPackage->cache) &&
1567 (BURN_CACHE_TYPE_ALWAYS > pPackage->cacheType || BOOTSTRAPPER_ACTION_CACHE > pPlan->action))
1568 { 1561 {
1569 // The following are all different reasons why the package should be cleaned from the cache. 1562 // The following are all different reasons why the package should be cleaned from the cache.
1570 // The else-ifs are used to make the conditions easier to see (rather than have them combined 1563 // The else-ifs are used to make the conditions easier to see (rather than have them combined
@@ -1607,7 +1600,7 @@ extern "C" HRESULT PlanCleanPackage(
1607 1600
1608 pCleanAction->pPackage = pPackage; 1601 pCleanAction->pPackage = pPackage;
1609 1602
1610 pPackage->fUncache = TRUE; 1603 pPackage->fPlannedUncache = TRUE;
1611 1604
1612 if (pPackage->fCanAffectRegistration) 1605 if (pPackage->fCanAffectRegistration)
1613 { 1606 {
@@ -1622,8 +1615,7 @@ LExit:
1622extern "C" HRESULT PlanExecuteCacheSyncAndRollback( 1615extern "C" HRESULT PlanExecuteCacheSyncAndRollback(
1623 __in BURN_PLAN* pPlan, 1616 __in BURN_PLAN* pPlan,
1624 __in BURN_PACKAGE* pPackage, 1617 __in BURN_PACKAGE* pPackage,
1625 __in HANDLE hCacheEvent, 1618 __in HANDLE hCacheEvent
1626 __in BOOL fPlanPackageCacheRollback
1627 ) 1619 )
1628{ 1620{
1629 HRESULT hr = S_OK; 1621 HRESULT hr = S_OK;
@@ -1635,17 +1627,14 @@ extern "C" HRESULT PlanExecuteCacheSyncAndRollback(
1635 pAction->type = BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT; 1627 pAction->type = BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT;
1636 pAction->syncpoint.hEvent = hCacheEvent; 1628 pAction->syncpoint.hEvent = hCacheEvent;
1637 1629
1638 if (fPlanPackageCacheRollback) 1630 hr = PlanAppendRollbackAction(pPlan, &pAction);
1639 { 1631 ExitOnFailure(hr, "Failed to append rollback action.");
1640 hr = PlanAppendRollbackAction(pPlan, &pAction);
1641 ExitOnFailure(hr, "Failed to append rollback action.");
1642 1632
1643 pAction->type = BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE; 1633 pAction->type = BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE;
1644 pAction->uncachePackage.pPackage = pPackage; 1634 pAction->uncachePackage.pPackage = pPackage;
1645 1635
1646 hr = PlanExecuteCheckpoint(pPlan); 1636 hr = PlanExecuteCheckpoint(pPlan);
1647 ExitOnFailure(hr, "Failed to append execute checkpoint for cache rollback."); 1637 ExitOnFailure(hr, "Failed to append execute checkpoint for cache rollback.");
1648 }
1649 1638
1650LExit: 1639LExit:
1651 return hr; 1640 return hr;
@@ -1895,8 +1884,8 @@ static void ResetPlannedPackageState(
1895 // Reset package state that is a result of planning. 1884 // Reset package state that is a result of planning.
1896 pPackage->defaultRequested = BOOTSTRAPPER_REQUEST_STATE_NONE; 1885 pPackage->defaultRequested = BOOTSTRAPPER_REQUEST_STATE_NONE;
1897 pPackage->requested = BOOTSTRAPPER_REQUEST_STATE_NONE; 1886 pPackage->requested = BOOTSTRAPPER_REQUEST_STATE_NONE;
1898 pPackage->fAcquire = FALSE; 1887 pPackage->fPlannedCache = FALSE;
1899 pPackage->fUncache = FALSE; 1888 pPackage->fPlannedUncache = FALSE;
1900 pPackage->execute = BOOTSTRAPPER_ACTION_STATE_NONE; 1889 pPackage->execute = BOOTSTRAPPER_ACTION_STATE_NONE;
1901 pPackage->rollback = BOOTSTRAPPER_ACTION_STATE_NONE; 1890 pPackage->rollback = BOOTSTRAPPER_ACTION_STATE_NONE;
1902 pPackage->providerExecute = BURN_DEPENDENCY_ACTION_NONE; 1891 pPackage->providerExecute = BURN_DEPENDENCY_ACTION_NONE;
@@ -2191,10 +2180,7 @@ static HRESULT AddCachePackageHelper(
2191 2180
2192 ++pPlan->cOverallProgressTicksTotal; 2181 ++pPlan->cOverallProgressTicksTotal;
2193 2182
2194 // If the package was not already fully cached then note that we planned the cache here. Otherwise, we only 2183 pPackage->fPlannedCache = TRUE;
2195 // did cache operations to verify the cache is valid so we did not plan the acquisition of the package.
2196 pPackage->fAcquire = (BURN_CACHE_STATE_COMPLETE != pPackage->cache);
2197
2198 if (pPackage->fCanAffectRegistration) 2184 if (pPackage->fCanAffectRegistration)
2199 { 2185 {
2200 pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT; 2186 pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;