diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2021-04-16 10:18:24 -0500 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2021-04-19 23:12:55 -0500 |
commit | b941c2754748251520dc5032d11396c9844fad8e (patch) | |
tree | 1106c2cffdb3aecfc206daebfb6e99894fd222b2 | |
parent | 90cdf39e6e6b7d676ca33bee031fa2b865bb5fbd (diff) | |
download | wix-b941c2754748251520dc5032d11396c9844fad8e.tar.gz wix-b941c2754748251520dc5032d11396c9844fad8e.tar.bz2 wix-b941c2754748251520dc5032d11396c9844fad8e.zip |
Verify file in the cache before trying to acquire it.
-rw-r--r-- | src/engine/apply.cpp | 36 | ||||
-rw-r--r-- | src/engine/cache.cpp | 76 | ||||
-rw-r--r-- | src/engine/cache.h | 10 | ||||
-rw-r--r-- | src/engine/package.h | 1 | ||||
-rw-r--r-- | src/engine/plan.cpp | 2 |
5 files changed, 116 insertions, 9 deletions
diff --git a/src/engine/apply.cpp b/src/engine/apply.cpp index 7e03ebf9..dffbc6d6 100644 --- a/src/engine/apply.cpp +++ b/src/engine/apply.cpp | |||
@@ -768,6 +768,12 @@ static HRESULT ApplyCachePackage( | |||
768 | HRESULT hr = S_OK; | 768 | HRESULT hr = S_OK; |
769 | BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION cachePackageCompleteAction = BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE; | 769 | BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION cachePackageCompleteAction = BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE; |
770 | 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 | |||
771 | for (;;) | 777 | for (;;) |
772 | { | 778 | { |
773 | hr = UserExperienceOnCachePackageBegin(pContext->pUX, pPackage->sczId, pPackage->payloads.cPayloads, pPackage->payloads.qwTotalSize); | 779 | hr = UserExperienceOnCachePackageBegin(pContext->pUX, pPackage->sczId, pPackage->payloads.cPayloads, pPackage->payloads.qwTotalSize); |
@@ -872,6 +878,14 @@ static HRESULT ApplyLayoutContainer( | |||
872 | 878 | ||
873 | Assert(!pContainer->fAttached); | 879 | Assert(!pContainer->fAttached); |
874 | 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 | |||
875 | for (;;) | 889 | for (;;) |
876 | { | 890 | { |
877 | fRetry = FALSE; | 891 | fRetry = FALSE; |
@@ -916,7 +930,20 @@ static HRESULT ApplyProcessPayload( | |||
916 | DWORD cTryAgainAttempts = 0; | 930 | DWORD cTryAgainAttempts = 0; |
917 | BOOL fRetry = FALSE; | 931 | BOOL fRetry = FALSE; |
918 | 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 | } | ||
920 | 947 | ||
921 | for (;;) | 948 | for (;;) |
922 | { | 949 | { |
@@ -924,12 +951,7 @@ static HRESULT ApplyProcessPayload( | |||
924 | 951 | ||
925 | if (pPayload->pContainer) | 952 | if (pPayload->pContainer) |
926 | { | 953 | { |
927 | if (pContext->wzLayoutDirectory) | 954 | // TODO: only extract container if payload isn't already extracted |
928 | { | ||
929 | ExitFunction(); | ||
930 | } | ||
931 | |||
932 | // TODO: only extract container if payload isn't already cached and isn't already extracted | ||
933 | hr = ApplyExtractContainer(pContext, pPayload->pContainer); | 955 | hr = ApplyExtractContainer(pContext, pPayload->pContainer); |
934 | ExitOnFailure(hr, "Failed to extract container for payload: %ls", pPayload->sczKey); | 956 | ExitOnFailure(hr, "Failed to extract container for payload: %ls", pPayload->sczKey); |
935 | } | 957 | } |
diff --git a/src/engine/cache.cpp b/src/engine/cache.cpp index 6ddbfb50..6ac313e0 100644 --- a/src/engine/cache.cpp +++ b/src/engine/cache.cpp | |||
@@ -57,6 +57,10 @@ static HRESULT TransferWorkingPathToUnverifiedPath( | |||
57 | __in_z LPCWSTR wzUnverifiedPayloadPath, | 57 | __in_z LPCWSTR wzUnverifiedPayloadPath, |
58 | __in BOOL fMove | 58 | __in BOOL fMove |
59 | ); | 59 | ); |
60 | static HRESULT VerifyFileAgainstContainer( | ||
61 | __in BURN_CONTAINER* pContainer, | ||
62 | __in_z LPCWSTR wzVerifyPath | ||
63 | ); | ||
60 | static HRESULT VerifyFileAgainstPayload( | 64 | static HRESULT VerifyFileAgainstPayload( |
61 | __in BURN_PAYLOAD* pPayload, | 65 | __in BURN_PAYLOAD* pPayload, |
62 | __in_z LPCWSTR wzVerifyPath | 66 | __in_z LPCWSTR wzVerifyPath |
@@ -837,7 +841,7 @@ LExit: | |||
837 | extern "C" HRESULT CacheCompletePayload( | 841 | extern "C" HRESULT CacheCompletePayload( |
838 | __in BOOL fPerMachine, | 842 | __in BOOL fPerMachine, |
839 | __in BURN_PAYLOAD* pPayload, | 843 | __in BURN_PAYLOAD* pPayload, |
840 | __in_z_opt LPCWSTR wzCacheId, | 844 | __in_z LPCWSTR wzCacheId, |
841 | __in_z LPCWSTR wzWorkingPayloadPath, | 845 | __in_z LPCWSTR wzWorkingPayloadPath, |
842 | __in BOOL fMove | 846 | __in BOOL fMove |
843 | ) | 847 | ) |
@@ -910,6 +914,44 @@ LExit: | |||
910 | return hr; | 914 | return hr; |
911 | } | 915 | } |
912 | 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 | |||
913 | extern "C" HRESULT CacheRemoveWorkingFolder( | 955 | extern "C" HRESULT CacheRemoveWorkingFolder( |
914 | __in_z_opt LPCWSTR wzBundleId | 956 | __in_z_opt LPCWSTR wzBundleId |
915 | ) | 957 | ) |
@@ -1383,6 +1425,38 @@ LExit: | |||
1383 | return hr; | 1425 | return hr; |
1384 | } | 1426 | } |
1385 | 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 | |||
1386 | static HRESULT VerifyFileAgainstPayload( | 1460 | static HRESULT VerifyFileAgainstPayload( |
1387 | __in BURN_PAYLOAD* pPayload, | 1461 | __in BURN_PAYLOAD* pPayload, |
1388 | __in_z LPCWSTR wzVerifyPath | 1462 | __in_z LPCWSTR wzVerifyPath |
diff --git a/src/engine/cache.h b/src/engine/cache.h index 52b111e9..acc7acb7 100644 --- a/src/engine/cache.h +++ b/src/engine/cache.h | |||
@@ -119,10 +119,18 @@ HRESULT CacheLayoutPayload( | |||
119 | HRESULT CacheCompletePayload( | 119 | HRESULT CacheCompletePayload( |
120 | __in BOOL fPerMachine, | 120 | __in BOOL fPerMachine, |
121 | __in BURN_PAYLOAD* pPayload, | 121 | __in BURN_PAYLOAD* pPayload, |
122 | __in_z_opt LPCWSTR wzCacheId, | 122 | __in_z LPCWSTR wzCacheId, |
123 | __in_z LPCWSTR wzUnverifiedPayloadPath, | 123 | __in_z LPCWSTR wzUnverifiedPayloadPath, |
124 | __in BOOL fMove | 124 | __in BOOL fMove |
125 | ); | 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 | ); | ||
126 | HRESULT CacheRemoveWorkingFolder( | 134 | HRESULT CacheRemoveWorkingFolder( |
127 | __in_z_opt LPCWSTR wzBundleId | 135 | __in_z_opt LPCWSTR wzBundleId |
128 | ); | 136 | ); |
diff --git a/src/engine/package.h b/src/engine/package.h index 34a3af26..2091af94 100644 --- a/src/engine/package.h +++ b/src/engine/package.h | |||
@@ -246,6 +246,7 @@ typedef struct _BURN_PACKAGE | |||
246 | BURN_DEPENDENCY_ACTION dependencyExecute; // only valid during Plan. | 246 | BURN_DEPENDENCY_ACTION dependencyExecute; // only valid during Plan. |
247 | BURN_DEPENDENCY_ACTION dependencyRollback; // only valid during Plan. | 247 | BURN_DEPENDENCY_ACTION dependencyRollback; // only valid during Plan. |
248 | BOOL fDependencyManagerWasHere; // only valid during Plan. | 248 | BOOL fDependencyManagerWasHere; // only valid during Plan. |
249 | LPWSTR sczCacheFolder; // only valid during Apply. | ||
249 | HRESULT hrCacheResult; // only valid during Apply. | 250 | HRESULT hrCacheResult; // only valid during Apply. |
250 | 251 | ||
251 | BURN_PACKAGE_REGISTRATION_STATE cacheRegistrationState; // initialized during Detect, updated during Apply. | 252 | BURN_PACKAGE_REGISTRATION_STATE cacheRegistrationState; // initialized during Detect, updated during Apply. |
diff --git a/src/engine/plan.cpp b/src/engine/plan.cpp index ce577da5..cfe4893b 100644 --- a/src/engine/plan.cpp +++ b/src/engine/plan.cpp | |||
@@ -1863,6 +1863,8 @@ static void ResetPlannedPackageState( | |||
1863 | pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; | 1863 | pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; |
1864 | pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; | 1864 | pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; |
1865 | 1865 | ||
1866 | ReleaseNullStr(pPackage->sczCacheFolder); | ||
1867 | |||
1866 | if (BURN_PACKAGE_TYPE_MSI == pPackage->type) | 1868 | if (BURN_PACKAGE_TYPE_MSI == pPackage->type) |
1867 | { | 1869 | { |
1868 | for (DWORD i = 0; i < pPackage->Msi.cFeatures; ++i) | 1870 | for (DWORD i = 0; i < pPackage->Msi.cFeatures; ++i) |