diff options
Diffstat (limited to 'src/burn/engine/cache.cpp')
| -rw-r--r-- | src/burn/engine/cache.cpp | 95 |
1 files changed, 80 insertions, 15 deletions
diff --git a/src/burn/engine/cache.cpp b/src/burn/engine/cache.cpp index 02cad4a5..44267cbc 100644 --- a/src/burn/engine/cache.cpp +++ b/src/burn/engine/cache.cpp | |||
| @@ -114,10 +114,16 @@ static HRESULT RemoveBundleOrPackage( | |||
| 114 | __in_z LPCWSTR wzBundleOrPackageId, | 114 | __in_z LPCWSTR wzBundleOrPackageId, |
| 115 | __in_z LPCWSTR wzCacheId | 115 | __in_z LPCWSTR wzCacheId |
| 116 | ); | 116 | ); |
| 117 | static HRESULT VerifyFileSize( | ||
| 118 | __in HANDLE hFile, | ||
| 119 | __in DWORD64 qwFileSize, | ||
| 120 | __in_z LPCWSTR wzUnverifiedPayloadPath | ||
| 121 | ); | ||
| 117 | static HRESULT VerifyHash( | 122 | static HRESULT VerifyHash( |
| 118 | __in BYTE* pbHash, | 123 | __in BYTE* pbHash, |
| 119 | __in DWORD cbHash, | 124 | __in DWORD cbHash, |
| 120 | __in DWORD64 qwFileSize, | 125 | __in DWORD64 qwFileSize, |
| 126 | __in BOOL fVerifyFileSize, | ||
| 121 | __in_z LPCWSTR wzUnverifiedPayloadPath, | 127 | __in_z LPCWSTR wzUnverifiedPayloadPath, |
| 122 | __in HANDLE hFile, | 128 | __in HANDLE hFile, |
| 123 | __in BURN_CACHE_STEP cacheStep, | 129 | __in BURN_CACHE_STEP cacheStep, |
| @@ -1513,11 +1519,16 @@ static HRESULT VerifyThenTransferContainer( | |||
| 1513 | ExitWithLastError(hr, "Failed to open container in working path: %ls", wzUnverifiedContainerPath); | 1519 | ExitWithLastError(hr, "Failed to open container in working path: %ls", wzUnverifiedContainerPath); |
| 1514 | } | 1520 | } |
| 1515 | 1521 | ||
| 1516 | // Container should have a hash we can use to verify with. | 1522 | |
| 1517 | if (pContainer->pbHash) | 1523 | switch (pContainer->verification) |
| 1518 | { | 1524 | { |
| 1519 | hr = VerifyHash(pContainer->pbHash, pContainer->cbHash, pContainer->qwFileSize, wzUnverifiedContainerPath, hFile, BURN_CACHE_STEP_HASH, pfnCacheMessageHandler, pfnProgress, pContext); | 1525 | case BURN_CONTAINER_VERIFICATION_HASH: |
| 1526 | hr = VerifyHash(pContainer->pbHash, pContainer->cbHash, pContainer->qwFileSize, TRUE, wzUnverifiedContainerPath, hFile, BURN_CACHE_STEP_HASH, pfnCacheMessageHandler, pfnProgress, pContext); | ||
| 1520 | ExitOnFailure(hr, "Failed to verify container hash: %ls", wzCachedPath); | 1527 | ExitOnFailure(hr, "Failed to verify container hash: %ls", wzCachedPath); |
| 1528 | break; | ||
| 1529 | default: | ||
| 1530 | ExitOnRootFailure(hr = E_INVALIDARG, "Container has no verification information: %ls", pContainer->sczId); | ||
| 1531 | break; | ||
| 1521 | } | 1532 | } |
| 1522 | 1533 | ||
| 1523 | LogStringLine(REPORT_STANDARD, "%ls container from working path '%ls' to path '%ls'", fMove ? L"Moving" : L"Copying", wzUnverifiedContainerPath, wzCachedPath); | 1534 | LogStringLine(REPORT_STANDARD, "%ls container from working path '%ls' to path '%ls'", fMove ? L"Moving" : L"Copying", wzUnverifiedContainerPath, wzCachedPath); |
| @@ -1550,10 +1561,16 @@ static HRESULT VerifyThenTransferPayload( | |||
| 1550 | ExitWithLastError(hr, "Failed to open payload in working path: %ls", wzUnverifiedPayloadPath); | 1561 | ExitWithLastError(hr, "Failed to open payload in working path: %ls", wzUnverifiedPayloadPath); |
| 1551 | } | 1562 | } |
| 1552 | 1563 | ||
| 1553 | if (pPayload->pbHash) // the payload should have a hash we can use to verify it. | 1564 | switch (pPayload->verification) |
| 1554 | { | 1565 | { |
| 1555 | hr = VerifyHash(pPayload->pbHash, pPayload->cbHash, pPayload->qwFileSize, wzUnverifiedPayloadPath, hFile, BURN_CACHE_STEP_HASH, pfnCacheMessageHandler, pfnProgress, pContext); | 1566 | case BURN_PAYLOAD_VERIFICATION_HASH: |
| 1567 | hr = VerifyHash(pPayload->pbHash, pPayload->cbHash, pPayload->qwFileSize, TRUE, wzUnverifiedPayloadPath, hFile, BURN_CACHE_STEP_HASH, pfnCacheMessageHandler, pfnProgress, pContext); | ||
| 1556 | ExitOnFailure(hr, "Failed to verify payload hash: %ls", wzCachedPath); | 1568 | ExitOnFailure(hr, "Failed to verify payload hash: %ls", wzCachedPath); |
| 1569 | break; | ||
| 1570 | case BURN_PAYLOAD_VERIFICATION_UPDATE_BUNDLE: __fallthrough; | ||
| 1571 | default: | ||
| 1572 | ExitOnRootFailure(hr = E_INVALIDARG, "Payload has no verification information: %ls", pPayload->sczKey); | ||
| 1573 | break; | ||
| 1557 | } | 1574 | } |
| 1558 | 1575 | ||
| 1559 | LogStringLine(REPORT_STANDARD, "%ls payload from working path '%ls' to path '%ls'", fMove ? L"Moving" : L"Copying", wzUnverifiedPayloadPath, wzCachedPath); | 1576 | LogStringLine(REPORT_STANDARD, "%ls payload from working path '%ls' to path '%ls'", fMove ? L"Moving" : L"Copying", wzUnverifiedPayloadPath, wzCachedPath); |
| @@ -1627,10 +1644,15 @@ static HRESULT VerifyFileAgainstContainer( | |||
| 1627 | ExitOnRootFailure(hr, "Failed to open container at path: %ls", wzVerifyPath); | 1644 | ExitOnRootFailure(hr, "Failed to open container at path: %ls", wzVerifyPath); |
| 1628 | } | 1645 | } |
| 1629 | 1646 | ||
| 1630 | if (pContainer->pbHash) // the container should have a hash we can use to verify it. | 1647 | switch (pContainer->verification) |
| 1631 | { | 1648 | { |
| 1632 | hr = VerifyHash(pContainer->pbHash, pContainer->cbHash, pContainer->qwFileSize, wzVerifyPath, hFile, cacheStep, pfnCacheMessageHandler, pfnProgress, pContext); | 1649 | case BURN_CONTAINER_VERIFICATION_HASH: |
| 1650 | hr = VerifyHash(pContainer->pbHash, pContainer->cbHash, pContainer->qwFileSize, TRUE, wzVerifyPath, hFile, cacheStep, pfnCacheMessageHandler, pfnProgress, pContext); | ||
| 1633 | ExitOnFailure(hr, "Failed to verify hash of container: %ls", pContainer->sczId); | 1651 | ExitOnFailure(hr, "Failed to verify hash of container: %ls", pContainer->sczId); |
| 1652 | break; | ||
| 1653 | default: | ||
| 1654 | ExitOnRootFailure(hr = E_INVALIDARG, "Container has no verification information: %ls", pContainer->sczId); | ||
| 1655 | break; | ||
| 1634 | } | 1656 | } |
| 1635 | 1657 | ||
| 1636 | if (fAlreadyCached) | 1658 | if (fAlreadyCached) |
| @@ -1667,6 +1689,7 @@ static HRESULT VerifyFileAgainstPayload( | |||
| 1667 | { | 1689 | { |
| 1668 | HRESULT hr = S_OK; | 1690 | HRESULT hr = S_OK; |
| 1669 | HANDLE hFile = INVALID_HANDLE_VALUE; | 1691 | HANDLE hFile = INVALID_HANDLE_VALUE; |
| 1692 | BOOL fVerifyFileSize = FALSE; | ||
| 1670 | 1693 | ||
| 1671 | // Get the payload on disk actual hash. | 1694 | // Get the payload on disk actual hash. |
| 1672 | hFile = ::CreateFileW(wzVerifyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); | 1695 | hFile = ::CreateFileW(wzVerifyPath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL); |
| @@ -1680,10 +1703,33 @@ static HRESULT VerifyFileAgainstPayload( | |||
| 1680 | ExitOnRootFailure(hr, "Failed to open payload at path: %ls", wzVerifyPath); | 1703 | ExitOnRootFailure(hr, "Failed to open payload at path: %ls", wzVerifyPath); |
| 1681 | } | 1704 | } |
| 1682 | 1705 | ||
| 1683 | if (pPayload->pbHash) // the payload should have a hash we can use to verify it. | 1706 | switch (pPayload->verification) |
| 1684 | { | 1707 | { |
| 1685 | hr = VerifyHash(pPayload->pbHash, pPayload->cbHash, pPayload->qwFileSize, wzVerifyPath, hFile, cacheStep, pfnCacheMessageHandler, pfnProgress, pContext); | 1708 | case BURN_PAYLOAD_VERIFICATION_HASH: |
| 1709 | fVerifyFileSize = TRUE; | ||
| 1710 | |||
| 1711 | hr = VerifyHash(pPayload->pbHash, pPayload->cbHash, pPayload->qwFileSize, fVerifyFileSize, wzVerifyPath, hFile, cacheStep, pfnCacheMessageHandler, pfnProgress, pContext); | ||
| 1686 | ExitOnFailure(hr, "Failed to verify hash of payload: %ls", pPayload->sczKey); | 1712 | ExitOnFailure(hr, "Failed to verify hash of payload: %ls", pPayload->sczKey); |
| 1713 | |||
| 1714 | break; | ||
| 1715 | case BURN_PAYLOAD_VERIFICATION_UPDATE_BUNDLE: | ||
| 1716 | fVerifyFileSize = 0 != pPayload->qwFileSize; | ||
| 1717 | |||
| 1718 | if (pPayload->pbHash) | ||
| 1719 | { | ||
| 1720 | hr = VerifyHash(pPayload->pbHash, pPayload->cbHash, pPayload->qwFileSize, fVerifyFileSize, wzVerifyPath, hFile, cacheStep, pfnCacheMessageHandler, pfnProgress, pContext); | ||
| 1721 | ExitOnFailure(hr, "Failed to verify hash of payload: %ls", pPayload->sczKey); | ||
| 1722 | } | ||
| 1723 | else if (fVerifyFileSize) | ||
| 1724 | { | ||
| 1725 | hr = VerifyFileSize(hFile, pPayload->qwFileSize, wzVerifyPath); | ||
| 1726 | ExitOnFailure(hr, "Failed to verify file size for path: %ls", wzVerifyPath); | ||
| 1727 | } | ||
| 1728 | |||
| 1729 | break; | ||
| 1730 | default: | ||
| 1731 | ExitOnRootFailure(hr = E_INVALIDARG, "Payload has no verification information: %ls", pPayload->sczKey); | ||
| 1732 | break; | ||
| 1687 | } | 1733 | } |
| 1688 | 1734 | ||
| 1689 | if (fAlreadyCached) | 1735 | if (fAlreadyCached) |
| @@ -2015,10 +2061,32 @@ LExit: | |||
| 2015 | return hr; | 2061 | return hr; |
| 2016 | } | 2062 | } |
| 2017 | 2063 | ||
| 2064 | static HRESULT VerifyFileSize( | ||
| 2065 | __in HANDLE hFile, | ||
| 2066 | __in DWORD64 qwFileSize, | ||
| 2067 | __in_z LPCWSTR wzUnverifiedPayloadPath | ||
| 2068 | ) | ||
| 2069 | { | ||
| 2070 | HRESULT hr = S_OK; | ||
| 2071 | LONGLONG llSize = 0; | ||
| 2072 | |||
| 2073 | hr = FileSizeByHandle(hFile, &llSize); | ||
| 2074 | ExitOnFailure(hr, "Failed to get file size for path: %ls", wzUnverifiedPayloadPath); | ||
| 2075 | |||
| 2076 | if (static_cast<DWORD64>(llSize) != qwFileSize) | ||
| 2077 | { | ||
| 2078 | ExitOnRootFailure(hr = ERROR_FILE_CORRUPT, "File size mismatch for path: %ls, expected: %llu, actual: %lld", wzUnverifiedPayloadPath, qwFileSize, llSize); | ||
| 2079 | } | ||
| 2080 | |||
| 2081 | LExit: | ||
| 2082 | return hr; | ||
| 2083 | } | ||
| 2084 | |||
| 2018 | static HRESULT VerifyHash( | 2085 | static HRESULT VerifyHash( |
| 2019 | __in BYTE* pbHash, | 2086 | __in BYTE* pbHash, |
| 2020 | __in DWORD cbHash, | 2087 | __in DWORD cbHash, |
| 2021 | __in DWORD64 qwFileSize, | 2088 | __in DWORD64 qwFileSize, |
| 2089 | __in BOOL fVerifyFileSize, | ||
| 2022 | __in_z LPCWSTR wzUnverifiedPayloadPath, | 2090 | __in_z LPCWSTR wzUnverifiedPayloadPath, |
| 2023 | __in HANDLE hFile, | 2091 | __in HANDLE hFile, |
| 2024 | __in BURN_CACHE_STEP cacheStep, | 2092 | __in BURN_CACHE_STEP cacheStep, |
| @@ -2032,19 +2100,16 @@ static HRESULT VerifyHash( | |||
| 2032 | HRESULT hr = S_OK; | 2100 | HRESULT hr = S_OK; |
| 2033 | BYTE rgbActualHash[SHA512_HASH_LEN] = { }; | 2101 | BYTE rgbActualHash[SHA512_HASH_LEN] = { }; |
| 2034 | DWORD64 qwHashedBytes = 0; | 2102 | DWORD64 qwHashedBytes = 0; |
| 2035 | LONGLONG llSize = 0; | ||
| 2036 | LPWSTR pszExpected = NULL; | 2103 | LPWSTR pszExpected = NULL; |
| 2037 | LPWSTR pszActual = NULL; | 2104 | LPWSTR pszActual = NULL; |
| 2038 | 2105 | ||
| 2039 | hr = SendCacheBeginMessage(pfnCacheMessageHandler, pContext, cacheStep); | 2106 | hr = SendCacheBeginMessage(pfnCacheMessageHandler, pContext, cacheStep); |
| 2040 | ExitOnFailure(hr, "Aborted cache verify hash begin."); | 2107 | ExitOnFailure(hr, "Aborted cache verify hash begin."); |
| 2041 | 2108 | ||
| 2042 | hr = FileSizeByHandle(hFile, &llSize); | 2109 | if (fVerifyFileSize) |
| 2043 | ExitOnFailure(hr, "Failed to get file size for path: %ls", wzUnverifiedPayloadPath); | ||
| 2044 | |||
| 2045 | if (static_cast<DWORD64>(llSize) != qwFileSize) | ||
| 2046 | { | 2110 | { |
| 2047 | ExitOnFailure(hr = ERROR_FILE_CORRUPT, "File size mismatch for path: %ls, expected: %llu, actual: %lld", wzUnverifiedPayloadPath, qwFileSize, llSize); | 2111 | hr = VerifyFileSize(hFile, qwFileSize, wzUnverifiedPayloadPath); |
| 2112 | ExitOnFailure(hr, "Failed to verify file size for path: %ls", wzUnverifiedPayloadPath); | ||
| 2048 | } | 2113 | } |
| 2049 | 2114 | ||
| 2050 | // TODO: create a cryp hash file that sends progress. | 2115 | // TODO: create a cryp hash file that sends progress. |
