@joebigelow / wix / commits / b941c275

Verify file in the cache before trying to acquire it.

Sean Hall committed Apr 16, 2021 at 10:18 UTC b941c2754748251520dc5032d11396c9844fad8e
5 files changed +116 -9
src/engine/apply.cpp
+29 -7
@@ -768,6 +768,12 @@ static HRESULT ApplyCachePackage(
768 HRESULT hr = S_OK;
769 BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION cachePackageCompleteAction = BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE;
770
771 + if (!pPackage->sczCacheFolder && !pContext->wzLayoutDirectory)
772 + {
773 + hr = CacheGetCompletedPath(pPackage->fPerMachine, pPackage->sczCacheId, &pPackage->sczCacheFolder);
774 + ExitOnFailure(hr, "Failed to get cached path for package with cache id: %ls", pPackage->sczCacheId);
775 + }
776 +
777 for (;;)
778 {
779 hr = UserExperienceOnCachePackageBegin(pContext->pUX, pPackage->sczId, pPackage->payloads.cPayloads, pPackage->payloads.qwTotalSize);
@@ -872,6 +878,14 @@ static HRESULT ApplyLayoutContainer(
878
879 Assert(!pContainer->fAttached);
880
881 + hr = CacheVerifyContainer(pContainer, pContext->wzLayoutDirectory);
882 + if (SUCCEEDED(hr))
883 + {
884 + // TODO: send Acquire and Verify messages to BA?
885 + pContext->qwSuccessfulCacheProgress += pContainer->qwFileSize * 2;
886 + ExitFunction();
887 + }
888 +
889 for (;;)
890 {
891 fRetry = FALSE;
@@ -916,7 +930,20 @@ static HRESULT ApplyProcessPayload(
930 DWORD cTryAgainAttempts = 0;
931 BOOL fRetry = FALSE;
932
919 - Assert(pContext->pPayloads || pContext->wzLayoutDirectory);
933 + Assert(pContext->pPayloads && pPackage || pContext->wzLayoutDirectory);
934 +
935 + if (pPayload->pContainer && pContext->wzLayoutDirectory)
936 + {
937 + ExitFunction();
938 + }
939 +
940 + hr = CacheVerifyPayload(pPayload, pContext->wzLayoutDirectory ? pContext->wzLayoutDirectory : pPackage->sczCacheFolder);
941 + if (SUCCEEDED(hr))
942 + {
943 + // TODO: send Acquire and Verify messages to BA?
944 + pContext->qwSuccessfulCacheProgress += pPayload->qwFileSize * 2;
945 + ExitFunction();
946 + }
947
948 for (;;)
949 {
@@ -924,12 +951,7 @@ static HRESULT ApplyProcessPayload(
951
952 if (pPayload->pContainer)
953 {
927 - if (pContext->wzLayoutDirectory)
928 - {
929 - ExitFunction();
930 - }
931 -
932 - // TODO: only extract container if payload isn't already cached and isn't already extracted
954 + // TODO: only extract container if payload isn't already extracted
955 hr = ApplyExtractContainer(pContext, pPayload->pContainer);
956 ExitOnFailure(hr, "Failed to extract container for payload: %ls", pPayload->sczKey);
957 }
src/engine/cache.cpp
+75 -1
@@ -57,6 +57,10 @@ static HRESULT TransferWorkingPathToUnverifiedPath(
57 __in_z LPCWSTR wzUnverifiedPayloadPath,
58 __in BOOL fMove
59 );
60 +static HRESULT VerifyFileAgainstContainer(
61 + __in BURN_CONTAINER* pContainer,
62 + __in_z LPCWSTR wzVerifyPath
63 + );
64 static HRESULT VerifyFileAgainstPayload(
65 __in BURN_PAYLOAD* pPayload,
66 __in_z LPCWSTR wzVerifyPath
@@ -837,7 +841,7 @@ LExit:
841 extern "C" HRESULT CacheCompletePayload(
842 __in BOOL fPerMachine,
843 __in BURN_PAYLOAD* pPayload,
840 - __in_z_opt LPCWSTR wzCacheId,
844 + __in_z LPCWSTR wzCacheId,
845 __in_z LPCWSTR wzWorkingPayloadPath,
846 __in BOOL fMove
847 )
@@ -910,6 +914,44 @@ LExit:
914 return hr;
915 }
916
917 +extern "C" HRESULT CacheVerifyContainer(
918 + __in BURN_CONTAINER* pContainer,
919 + __in_z LPCWSTR wzCachedDirectory
920 + )
921 +{
922 + HRESULT hr = S_OK;
923 + LPWSTR sczCachedPath = NULL;
924 +
925 + hr = PathConcat(wzCachedDirectory, pContainer->sczFilePath, &sczCachedPath);
926 + ExitOnFailure(hr, "Failed to concat complete cached path.");
927 +
928 + hr = VerifyFileAgainstContainer(pContainer, sczCachedPath);
929 +
930 +LExit:
931 + ReleaseStr(sczCachedPath);
932 +
933 + return hr;
934 +}
935 +
936 +extern "C" HRESULT CacheVerifyPayload(
937 + __in BURN_PAYLOAD* pPayload,
938 + __in_z LPCWSTR wzCachedDirectory
939 + )
940 +{
941 + HRESULT hr = S_OK;
942 + LPWSTR sczCachedPath = NULL;
943 +
944 + hr = PathConcat(wzCachedDirectory, pPayload->sczFilePath, &sczCachedPath);
945 + ExitOnFailure(hr, "Failed to concat complete cached path.");
946 +
947 + hr = VerifyFileAgainstPayload(pPayload, sczCachedPath);
948 +
949 +LExit:
950 + ReleaseStr(sczCachedPath);
951 +
952 + return hr;
953 +}
954 +
955 extern "C" HRESULT CacheRemoveWorkingFolder(
956 __in_z_opt LPCWSTR wzBundleId
957 )
@@ -1383,6 +1425,38 @@ LExit:
1425 return hr;
1426 }
1427
1428 +static HRESULT VerifyFileAgainstContainer(
1429 + __in BURN_CONTAINER* pContainer,
1430 + __in_z LPCWSTR wzVerifyPath
1431 + )
1432 +{
1433 + HRESULT hr = S_OK;
1434 + HANDLE hFile = INVALID_HANDLE_VALUE;
1435 +
1436 + // Get the container on disk actual hash.
1437 + hFile = ::CreateFileW(wzVerifyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
1438 + if (INVALID_HANDLE_VALUE == hFile)
1439 + {
1440 + hr = HRESULT_FROM_WIN32(::GetLastError());
1441 + if (E_PATHNOTFOUND == hr || E_FILENOTFOUND == hr)
1442 + {
1443 + ExitFunction(); // do not log error when the file was not found.
1444 + }
1445 + ExitOnRootFailure(hr, "Failed to open container at path: %ls", wzVerifyPath);
1446 + }
1447 +
1448 + if (pContainer->pbHash) // the container should have a hash we can use to verify it.
1449 + {
1450 + hr = VerifyHash(pContainer->pbHash, pContainer->cbHash, pContainer->qwFileSize, wzVerifyPath, hFile);
1451 + ExitOnFailure(hr, "Failed to verify hash of container: %ls", pContainer->sczId);
1452 + }
1453 +
1454 +LExit:
1455 + ReleaseFileHandle(hFile);
1456 +
1457 + return hr;
1458 +}
1459 +
1460 static HRESULT VerifyFileAgainstPayload(
1461 __in BURN_PAYLOAD* pPayload,
1462 __in_z LPCWSTR wzVerifyPath
src/engine/cache.h
+9 -1
@@ -119,10 +119,18 @@ HRESULT CacheLayoutPayload(
119 HRESULT CacheCompletePayload(
120 __in BOOL fPerMachine,
121 __in BURN_PAYLOAD* pPayload,
122 - __in_z_opt LPCWSTR wzCacheId,
122 + __in_z LPCWSTR wzCacheId,
123 __in_z LPCWSTR wzUnverifiedPayloadPath,
124 __in BOOL fMove
125 );
126 +HRESULT CacheVerifyContainer(
127 + __in BURN_CONTAINER* pContainer,
128 + __in_z LPCWSTR wzCachedDirectory
129 + );
130 +HRESULT CacheVerifyPayload(
131 + __in BURN_PAYLOAD* pPayload,
132 + __in_z LPCWSTR wzCachedDirectory
133 + );
134 HRESULT CacheRemoveWorkingFolder(
135 __in_z_opt LPCWSTR wzBundleId
136 );
src/engine/package.h
+1
@@ -246,6 +246,7 @@ typedef struct _BURN_PACKAGE
246 BURN_DEPENDENCY_ACTION dependencyExecute; // only valid during Plan.
247 BURN_DEPENDENCY_ACTION dependencyRollback; // only valid during Plan.
248 BOOL fDependencyManagerWasHere; // only valid during Plan.
249 + LPWSTR sczCacheFolder; // only valid during Apply.
250 HRESULT hrCacheResult; // only valid during Apply.
251
252 BURN_PACKAGE_REGISTRATION_STATE cacheRegistrationState; // initialized during Detect, updated during Apply.
src/engine/plan.cpp
+2
@@ -1863,6 +1863,8 @@ static void ResetPlannedPackageState(
1863 pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
1864 pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
1865
1866 + ReleaseNullStr(pPackage->sczCacheFolder);
1867 +
1868 if (BURN_PACKAGE_TYPE_MSI == pPackage->type)
1869 {
1870 for (DWORD i = 0; i < pPackage->Msi.cFeatures; ++i)