aboutsummaryrefslogtreecommitdiff
path: root/src/engine/core.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/core.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/core.cpp')
-rw-r--r--src/engine/core.cpp44
1 files changed, 15 insertions, 29 deletions
diff --git a/src/engine/core.cpp b/src/engine/core.cpp
index 50ed6ea0..7341e4b8 100644
--- a/src/engine/core.cpp
+++ b/src/engine/core.cpp
@@ -388,7 +388,7 @@ extern "C" HRESULT CoreDetect(
388 pEngineState->registration.fEligibleForCleanup = FALSE; 388 pEngineState->registration.fEligibleForCleanup = FALSE;
389 } 389 }
390 390
391 LogId(REPORT_STANDARD, MSG_DETECTED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingCacheStateToString(pPackage->cache), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->installRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->cacheRegistrationState)); 391 LogId(REPORT_STANDARD, MSG_DETECTED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingBoolToString(pPackage->fCached), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->installRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->cacheRegistrationState));
392 392
393 if (BURN_PACKAGE_TYPE_MSI == pPackage->type) 393 if (BURN_PACKAGE_TYPE_MSI == pPackage->type)
394 { 394 {
@@ -439,7 +439,6 @@ extern "C" HRESULT CorePlan(
439 HRESULT hr = S_OK; 439 HRESULT hr = S_OK;
440 BOOL fPlanBegan = FALSE; 440 BOOL fPlanBegan = FALSE;
441 LPWSTR sczLayoutDirectory = NULL; 441 LPWSTR sczLayoutDirectory = NULL;
442 HANDLE hSyncpointEvent = NULL;
443 BURN_PACKAGE* pUpgradeBundlePackage = NULL; 442 BURN_PACKAGE* pUpgradeBundlePackage = NULL;
444 BURN_PACKAGE* pForwardCompatibleBundlePackage = NULL; 443 BURN_PACKAGE* pForwardCompatibleBundlePackage = NULL;
445 BOOL fContinuePlanning = TRUE; // assume we won't skip planning due to dependencies. 444 BOOL fContinuePlanning = TRUE; // assume we won't skip planning due to dependencies.
@@ -489,7 +488,7 @@ extern "C" HRESULT CorePlan(
489 ExitOnFailure(hr, "Failed to plan the layout of the bundle."); 488 ExitOnFailure(hr, "Failed to plan the layout of the bundle.");
490 489
491 // Plan the packages' layout. 490 // Plan the packages' layout.
492 hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType, sczLayoutDirectory, &hSyncpointEvent); 491 hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType, sczLayoutDirectory);
493 ExitOnFailure(hr, "Failed to plan packages."); 492 ExitOnFailure(hr, "Failed to plan packages.");
494 } 493 }
495 else if (BOOTSTRAPPER_ACTION_UPDATE_REPLACE == action || BOOTSTRAPPER_ACTION_UPDATE_REPLACE_EMBEDDED == action) 494 else if (BOOTSTRAPPER_ACTION_UPDATE_REPLACE == action || BOOTSTRAPPER_ACTION_UPDATE_REPLACE_EMBEDDED == action)
@@ -498,7 +497,7 @@ extern "C" HRESULT CorePlan(
498 497
499 pUpgradeBundlePackage = &pEngineState->update.package; 498 pUpgradeBundlePackage = &pEngineState->update.package;
500 499
501 hr = PlanUpdateBundle(&pEngineState->userExperience, pUpgradeBundlePackage, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType, &hSyncpointEvent); 500 hr = PlanUpdateBundle(&pEngineState->userExperience, pUpgradeBundlePackage, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType);
502 ExitOnFailure(hr, "Failed to plan update."); 501 ExitOnFailure(hr, "Failed to plan update.");
503 } 502 }
504 else 503 else
@@ -512,7 +511,7 @@ extern "C" HRESULT CorePlan(
512 511
513 pForwardCompatibleBundlePackage = &pEngineState->plan.forwardCompatibleBundle; 512 pForwardCompatibleBundlePackage = &pEngineState->plan.forwardCompatibleBundle;
514 513
515 hr = PlanPassThroughBundle(&pEngineState->userExperience, pForwardCompatibleBundlePackage, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType, &hSyncpointEvent); 514 hr = PlanPassThroughBundle(&pEngineState->userExperience, pForwardCompatibleBundlePackage, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType);
516 ExitOnFailure(hr, "Failed to plan passthrough."); 515 ExitOnFailure(hr, "Failed to plan passthrough.");
517 } 516 }
518 else // doing an action that modifies the machine state. 517 else // doing an action that modifies the machine state.
@@ -533,11 +532,11 @@ extern "C" HRESULT CorePlan(
533 hr = PlanRelatedBundlesBegin(&pEngineState->userExperience, &pEngineState->registration, pEngineState->command.relationType, &pEngineState->plan); 532 hr = PlanRelatedBundlesBegin(&pEngineState->userExperience, &pEngineState->registration, pEngineState->command.relationType, &pEngineState->plan);
534 ExitOnFailure(hr, "Failed to plan related bundles."); 533 ExitOnFailure(hr, "Failed to plan related bundles.");
535 534
536 hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType, NULL, &hSyncpointEvent); 535 hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType, NULL);
537 ExitOnFailure(hr, "Failed to plan packages."); 536 ExitOnFailure(hr, "Failed to plan packages.");
538 537
539 // Schedule the update of related bundles last. 538 // Schedule the update of related bundles last.
540 hr = PlanRelatedBundlesComplete(&pEngineState->registration, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, &hSyncpointEvent, dwExecuteActionEarlyIndex); 539 hr = PlanRelatedBundlesComplete(&pEngineState->registration, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, dwExecuteActionEarlyIndex);
541 ExitOnFailure(hr, "Failed to schedule related bundles."); 540 ExitOnFailure(hr, "Failed to schedule related bundles.");
542 } 541 }
543 } 542 }
@@ -1669,9 +1668,8 @@ static HRESULT DetectPackagePayloadsCached(
1669{ 1668{
1670 HRESULT hr = S_OK; 1669 HRESULT hr = S_OK;
1671 LPWSTR sczCachePath = NULL; 1670 LPWSTR sczCachePath = NULL;
1672 BURN_CACHE_STATE cache = BURN_CACHE_STATE_NONE; // assume the package will not be cached. 1671 BOOL fCached = FALSE; // assume the package is not cached.
1673 LPWSTR sczPayloadCachePath = NULL; 1672 LPWSTR sczPayloadCachePath = NULL;
1674 LONGLONG llSize = 0;
1675 1673
1676 if (pPackage->sczCacheId && *pPackage->sczCacheId) 1674 if (pPackage->sczCacheId && *pPackage->sczCacheId)
1677 { 1675 {
@@ -1681,9 +1679,7 @@ static HRESULT DetectPackagePayloadsCached(
1681 // If the cached directory exists, we have something. 1679 // If the cached directory exists, we have something.
1682 if (DirExists(sczCachePath, NULL)) 1680 if (DirExists(sczCachePath, NULL))
1683 { 1681 {
1684 cache = BURN_CACHE_STATE_COMPLETE; // assume all payloads are cached. 1682 // Check all payloads to see if they exist.
1685
1686 // Check all payloads to see if any are missing or not the right size.
1687 for (DWORD i = 0; i < pPackage->cPayloads; ++i) 1683 for (DWORD i = 0; i < pPackage->cPayloads; ++i)
1688 { 1684 {
1689 BURN_PACKAGE_PAYLOAD* pPackagePayload = pPackage->rgPayloads + i; 1685 BURN_PACKAGE_PAYLOAD* pPackagePayload = pPackage->rgPayloads + i;
@@ -1691,35 +1687,25 @@ static HRESULT DetectPackagePayloadsCached(
1691 hr = PathConcat(sczCachePath, pPackagePayload->pPayload->sczFilePath, &sczPayloadCachePath); 1687 hr = PathConcat(sczCachePath, pPackagePayload->pPayload->sczFilePath, &sczPayloadCachePath);
1692 ExitOnFailure(hr, "Failed to concat payload cache path."); 1688 ExitOnFailure(hr, "Failed to concat payload cache path.");
1693 1689
1694 hr = FileSize(sczPayloadCachePath, &llSize); 1690 if (FileExistsEx(sczPayloadCachePath, NULL))
1695 if (SUCCEEDED(hr) && static_cast<DWORD64>(llSize) != pPackagePayload->pPayload->qwFileSize)
1696 {
1697 hr = HRESULT_FROM_WIN32(ERROR_FILE_CORRUPT); // size did not match expectations, so cache must have the wrong file.
1698 }
1699
1700 if (SUCCEEDED(hr))
1701 { 1691 {
1702 // TODO: should we do a full on hash verification on the file to ensure 1692 // TODO: We shouldn't track whether the payload was cached since all we did was check whether the file exists.
1703 // the exact right file is cached?
1704
1705 pPackagePayload->fCached = TRUE; 1693 pPackagePayload->fCached = TRUE;
1694 fCached = TRUE;
1706 } 1695 }
1707 else 1696 else
1708 { 1697 {
1709 LogId(REPORT_STANDARD, MSG_DETECT_PACKAGE_NOT_FULLY_CACHED, pPackage->sczId, pPackagePayload->pPayload->sczKey, hr); 1698 LogId(REPORT_STANDARD, MSG_DETECT_PACKAGE_NOT_FULLY_CACHED, pPackage->sczId, pPackagePayload->pPayload->sczKey);
1710
1711 cache = BURN_CACHE_STATE_PARTIAL; // found a payload that was not cached so we are partial.
1712 hr = S_OK;
1713 } 1699 }
1714 } 1700 }
1715 } 1701 }
1716 } 1702 }
1717 1703
1718 pPackage->cache = cache; 1704 pPackage->fCached = fCached;
1719 1705
1720 if (pPackage->fCanAffectRegistration) 1706 if (pPackage->fCanAffectRegistration)
1721 { 1707 {
1722 pPackage->cacheRegistrationState = BURN_CACHE_STATE_NONE < pPackage->cache ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT; 1708 pPackage->cacheRegistrationState = pPackage->fCached ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
1723 } 1709 }
1724 1710
1725LExit: 1711LExit:
@@ -1808,7 +1794,7 @@ static void LogPackages(
1808 const DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == action) ? pPackages->cPackages - 1 - i : i; 1794 const DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == action) ? pPackages->cPackages - 1 - i : i;
1809 const BURN_PACKAGE* pPackage = &pPackages->rgPackages[iPackage]; 1795 const BURN_PACKAGE* pPackage = &pPackages->rgPackages[iPackage];
1810 1796
1811 LogId(REPORT_STANDARD, MSG_PLANNED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingRequestStateToString(pPackage->defaultRequested), LoggingRequestStateToString(pPackage->requested), LoggingActionStateToString(pPackage->execute), LoggingActionStateToString(pPackage->rollback), LoggingBoolToString(pPackage->fAcquire), LoggingBoolToString(pPackage->fUncache), LoggingDependencyActionToString(pPackage->dependencyExecute), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->expectedInstallRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->expectedCacheRegistrationState)); 1797 LogId(REPORT_STANDARD, MSG_PLANNED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingRequestStateToString(pPackage->defaultRequested), LoggingRequestStateToString(pPackage->requested), LoggingActionStateToString(pPackage->execute), LoggingActionStateToString(pPackage->rollback), LoggingBoolToString(pPackage->fPlannedCache), LoggingBoolToString(pPackage->fPlannedUncache), LoggingDependencyActionToString(pPackage->dependencyExecute), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->expectedInstallRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->expectedCacheRegistrationState));
1812 1798
1813 if (BURN_PACKAGE_TYPE_MSI == pPackage->type) 1799 if (BURN_PACKAGE_TYPE_MSI == pPackage->type)
1814 { 1800 {