aboutsummaryrefslogtreecommitdiff
path: root/src/engine/cache.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/cache.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/cache.cpp')
-rw-r--r--src/engine/cache.cpp25
1 files changed, 18 insertions, 7 deletions
diff --git a/src/engine/cache.cpp b/src/engine/cache.cpp
index 2349a357..667ca9e0 100644
--- a/src/engine/cache.cpp
+++ b/src/engine/cache.cpp
@@ -91,6 +91,7 @@ static HRESULT RemoveBundleOrPackage(
91static HRESULT VerifyHash( 91static HRESULT VerifyHash(
92 __in BYTE* pbHash, 92 __in BYTE* pbHash,
93 __in DWORD cbHash, 93 __in DWORD cbHash,
94 __in DWORD64 qwFileSize,
94 __in_z LPCWSTR wzUnverifiedPayloadPath, 95 __in_z LPCWSTR wzUnverifiedPayloadPath,
95 __in HANDLE hFile 96 __in HANDLE hFile
96 ); 97 );
@@ -1288,7 +1289,7 @@ static HRESULT VerifyThenTransferContainer(
1288 // Container should have a hash we can use to verify with. 1289 // Container should have a hash we can use to verify with.
1289 if (pContainer->pbHash) 1290 if (pContainer->pbHash)
1290 { 1291 {
1291 hr = VerifyHash(pContainer->pbHash, pContainer->cbHash, wzUnverifiedContainerPath, hFile); 1292 hr = VerifyHash(pContainer->pbHash, pContainer->cbHash, pContainer->qwFileSize, wzUnverifiedContainerPath, hFile);
1292 ExitOnFailure(hr, "Failed to verify container hash: %ls", wzCachedPath); 1293 ExitOnFailure(hr, "Failed to verify container hash: %ls", wzCachedPath);
1293 } 1294 }
1294 1295
@@ -1330,7 +1331,7 @@ static HRESULT VerifyThenTransferPayload(
1330 1331
1331 if (pPayload->pbHash) // the payload should have a hash we can use to verify it. 1332 if (pPayload->pbHash) // the payload should have a hash we can use to verify it.
1332 { 1333 {
1333 hr = VerifyHash(pPayload->pbHash, pPayload->cbHash, wzUnverifiedPayloadPath, hFile); 1334 hr = VerifyHash(pPayload->pbHash, pPayload->cbHash, pPayload->qwFileSize, wzUnverifiedPayloadPath, hFile);
1334 ExitOnFailure(hr, "Failed to verify payload hash: %ls", wzCachedPath); 1335 ExitOnFailure(hr, "Failed to verify payload hash: %ls", wzCachedPath);
1335 } 1336 }
1336 1337
@@ -1398,7 +1399,7 @@ static HRESULT VerifyFileAgainstPayload(
1398 1399
1399 if (pPayload->pbHash) // the payload should have a hash we can use to verify it. 1400 if (pPayload->pbHash) // the payload should have a hash we can use to verify it.
1400 { 1401 {
1401 hr = VerifyHash(pPayload->pbHash, pPayload->cbHash, wzVerifyPath, hFile); 1402 hr = VerifyHash(pPayload->pbHash, pPayload->cbHash, pPayload->qwFileSize, wzVerifyPath, hFile);
1402 ExitOnFailure(hr, "Failed to verify hash of payload: %ls", pPayload->sczKey); 1403 ExitOnFailure(hr, "Failed to verify hash of payload: %ls", pPayload->sczKey);
1403 } 1404 }
1404 1405
@@ -1712,7 +1713,7 @@ static HRESULT RemoveBundleOrPackage(
1712 } 1713 }
1713 } 1714 }
1714 1715
1715 if (FAILED(hr)) 1716 if (E_PATHNOTFOUND != hr && FAILED(hr))
1716 { 1717 {
1717 LogId(REPORT_STANDARD, fBundle ? MSG_UNABLE_UNCACHE_BUNDLE : MSG_UNABLE_UNCACHE_PACKAGE, wzBundleOrPackageId, sczDirectory, hr); 1718 LogId(REPORT_STANDARD, fBundle ? MSG_UNABLE_UNCACHE_BUNDLE : MSG_UNABLE_UNCACHE_PACKAGE, wzBundleOrPackageId, sczDirectory, hr);
1718 hr = S_OK; 1719 hr = S_OK;
@@ -1743,6 +1744,7 @@ LExit:
1743static HRESULT VerifyHash( 1744static HRESULT VerifyHash(
1744 __in BYTE* pbHash, 1745 __in BYTE* pbHash,
1745 __in DWORD cbHash, 1746 __in DWORD cbHash,
1747 __in DWORD64 qwFileSize,
1746 __in_z LPCWSTR wzUnverifiedPayloadPath, 1748 __in_z LPCWSTR wzUnverifiedPayloadPath,
1747 __in HANDLE hFile 1749 __in HANDLE hFile
1748 ) 1750 )
@@ -1751,22 +1753,31 @@ static HRESULT VerifyHash(
1751 1753
1752 HRESULT hr = S_OK; 1754 HRESULT hr = S_OK;
1753 BYTE rgbActualHash[SHA512_HASH_LEN] = { }; 1755 BYTE rgbActualHash[SHA512_HASH_LEN] = { };
1754 DWORD64 qwHashedBytes; 1756 DWORD64 qwHashedBytes = 0;
1757 LONGLONG llSize = 0;
1755 LPWSTR pszExpected = NULL; 1758 LPWSTR pszExpected = NULL;
1756 LPWSTR pszActual = NULL; 1759 LPWSTR pszActual = NULL;
1757 1760
1761 hr = FileSizeByHandle(hFile, &llSize);
1762 ExitOnFailure(hr, "Failed to get file size for path: %ls", wzUnverifiedPayloadPath);
1763
1764 if (static_cast<DWORD64>(llSize) != qwFileSize)
1765 {
1766 ExitOnFailure(hr = ERROR_FILE_CORRUPT, "File size mismatch for path: %ls, expected: %llu, actual: %lld", wzUnverifiedPayloadPath, qwFileSize, llSize);
1767 }
1768
1758 // TODO: create a cryp hash file that sends progress. 1769 // TODO: create a cryp hash file that sends progress.
1759 hr = CrypHashFileHandle(hFile, PROV_RSA_AES, CALG_SHA_512, rgbActualHash, sizeof(rgbActualHash), &qwHashedBytes); 1770 hr = CrypHashFileHandle(hFile, PROV_RSA_AES, CALG_SHA_512, rgbActualHash, sizeof(rgbActualHash), &qwHashedBytes);
1760 ExitOnFailure(hr, "Failed to calculate hash for path: %ls", wzUnverifiedPayloadPath); 1771 ExitOnFailure(hr, "Failed to calculate hash for path: %ls", wzUnverifiedPayloadPath);
1761 1772
1762 // Compare hashes. 1773 // Compare hashes.
1763 if (cbHash != sizeof(rgbActualHash) || 0 != memcmp(pbHash, rgbActualHash, SHA512_HASH_LEN)) 1774 if (cbHash != sizeof(rgbActualHash) || 0 != memcmp(pbHash, rgbActualHash, sizeof(rgbActualHash)))
1764 { 1775 {
1765 hr = CRYPT_E_HASH_VALUE; 1776 hr = CRYPT_E_HASH_VALUE;
1766 1777
1767 // Best effort to log the expected and actual hash value strings. 1778 // Best effort to log the expected and actual hash value strings.
1768 if (SUCCEEDED(StrAllocHexEncode(pbHash, cbHash, &pszExpected)) && 1779 if (SUCCEEDED(StrAllocHexEncode(pbHash, cbHash, &pszExpected)) &&
1769 SUCCEEDED(StrAllocHexEncode(rgbActualHash, (SIZE_T)qwHashedBytes, &pszActual))) 1780 SUCCEEDED(StrAllocHexEncode(rgbActualHash, sizeof(rgbActualHash), &pszActual)))
1770 { 1781 {
1771 ExitOnFailure(hr, "Hash mismatch for path: %ls, expected: %ls, actual: %ls", wzUnverifiedPayloadPath, pszExpected, pszActual); 1782 ExitOnFailure(hr, "Hash mismatch for path: %ls, expected: %ls, actual: %ls", wzUnverifiedPayloadPath, pszExpected, pszActual);
1772 } 1783 }