diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2021-04-16 09:40:18 -0500 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2021-04-19 23:12:55 -0500 |
commit | 941c47e5a3f57ce9626b447a95740b1444e69343 (patch) | |
tree | 6225b78f5fc7c8f88a2abf187a6a76d45b36ec26 /src/engine/plan.cpp | |
parent | d32f770ca05748df9e356444c7e617d5eeedb60c (diff) | |
download | wix-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.cpp | 76 |
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 | ); |
37 | static HRESULT InitializePackage( | 36 | static 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 | ||
791 | LExit: | 788 | LExit: |
@@ -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 | ||
812 | LExit: | 808 | LExit: |
@@ -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: | |||
1622 | extern "C" HRESULT PlanExecuteCacheSyncAndRollback( | 1615 | extern "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 | ||
1650 | LExit: | 1639 | LExit: |
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; |