diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2022-08-03 14:55:23 -0500 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2022-08-03 15:57:24 -0500 |
commit | 124fef398a26bc8e139e889a2345602d2478590c (patch) | |
tree | 002c77e0c1d72b0cc0e46bed3c6f02d4179625fe /src/burn | |
parent | a896fec453056aa5e1ad803b04a672d2dceda981 (diff) | |
download | wix-124fef398a26bc8e139e889a2345602d2478590c.tar.gz wix-124fef398a26bc8e139e889a2345602d2478590c.tar.bz2 wix-124fef398a26bc8e139e889a2345602d2478590c.zip |
Add ability to skip a local path candidate if it failed verification.
Fixes 6818
Diffstat (limited to 'src/burn')
-rw-r--r-- | src/burn/engine/apply.cpp | 137 | ||||
-rw-r--r-- | src/burn/engine/cache.cpp | 70 | ||||
-rw-r--r-- | src/burn/engine/cache.h | 5 | ||||
-rw-r--r-- | src/burn/engine/container.cpp | 1 | ||||
-rw-r--r-- | src/burn/engine/container.h | 4 | ||||
-rw-r--r-- | src/burn/engine/elevation.cpp | 23 | ||||
-rw-r--r-- | src/burn/engine/payload.cpp | 1 | ||||
-rw-r--r-- | src/burn/engine/payload.h | 3 | ||||
-rw-r--r-- | src/burn/engine/plan.cpp | 6 |
9 files changed, 221 insertions, 29 deletions
diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp index dd99a5cd..31d756a8 100644 --- a/src/burn/engine/apply.cpp +++ b/src/burn/engine/apply.cpp | |||
@@ -38,7 +38,7 @@ typedef struct _BURN_CACHE_CONTEXT | |||
38 | LPWSTR* rgSearchPaths; | 38 | LPWSTR* rgSearchPaths; |
39 | DWORD cSearchPaths; | 39 | DWORD cSearchPaths; |
40 | DWORD cSearchPathsMax; | 40 | DWORD cSearchPathsMax; |
41 | LPWSTR sczLastUsedFolderCandidate; | 41 | LPWSTR sczLocalAcquisitionSourcePath; |
42 | } BURN_CACHE_CONTEXT; | 42 | } BURN_CACHE_CONTEXT; |
43 | 43 | ||
44 | typedef struct _BURN_CACHE_PROGRESS_CONTEXT | 44 | typedef struct _BURN_CACHE_PROGRESS_CONTEXT |
@@ -92,6 +92,16 @@ static HRESULT ApplyCachePackage( | |||
92 | __in BURN_CACHE_CONTEXT* pContext, | 92 | __in BURN_CACHE_CONTEXT* pContext, |
93 | __in BURN_PACKAGE* pPackage | 93 | __in BURN_PACKAGE* pPackage |
94 | ); | 94 | ); |
95 | static void FinalizeContainerAcquisition( | ||
96 | __in BURN_CACHE_CONTEXT* pContext, | ||
97 | __in BURN_CONTAINER* pContainer, | ||
98 | __in BOOL fSuccess | ||
99 | ); | ||
100 | static void FinalizePayloadAcquisition( | ||
101 | __in BURN_CACHE_CONTEXT* pContext, | ||
102 | __in BURN_PAYLOAD* pPayload, | ||
103 | __in BOOL fSuccess | ||
104 | ); | ||
95 | static HRESULT ApplyExtractContainer( | 105 | static HRESULT ApplyExtractContainer( |
96 | __in BURN_CACHE_CONTEXT* pContext, | 106 | __in BURN_CACHE_CONTEXT* pContext, |
97 | __in BURN_CONTAINER* pContainer | 107 | __in BURN_CONTAINER* pContainer |
@@ -667,7 +677,7 @@ LExit: | |||
667 | ReleaseNullStr(cacheContext.rgSearchPaths[i]); | 677 | ReleaseNullStr(cacheContext.rgSearchPaths[i]); |
668 | } | 678 | } |
669 | ReleaseMem(cacheContext.rgSearchPaths); | 679 | ReleaseMem(cacheContext.rgSearchPaths); |
670 | ReleaseStr(cacheContext.sczLastUsedFolderCandidate); | 680 | ReleaseStr(cacheContext.sczLocalAcquisitionSourcePath); |
671 | 681 | ||
672 | UserExperienceOnCacheComplete(pUX, hr); | 682 | UserExperienceOnCacheComplete(pUX, hr); |
673 | return hr; | 683 | return hr; |
@@ -1038,6 +1048,46 @@ LExit: | |||
1038 | return hr; | 1048 | return hr; |
1039 | } | 1049 | } |
1040 | 1050 | ||
1051 | static void FinalizeContainerAcquisition( | ||
1052 | __in BURN_CACHE_CONTEXT* pContext, | ||
1053 | __in BURN_CONTAINER* pContainer, | ||
1054 | __in BOOL fSuccess | ||
1055 | ) | ||
1056 | { | ||
1057 | ReleaseNullStr(pContainer->sczFailedLocalAcquisitionPath); | ||
1058 | |||
1059 | if (fSuccess) | ||
1060 | { | ||
1061 | ReleaseNullStr(pContext->sczLocalAcquisitionSourcePath); | ||
1062 | pContainer->fFailedVerificationFromAcquisition = FALSE; | ||
1063 | } | ||
1064 | else if (pContext->sczLocalAcquisitionSourcePath) | ||
1065 | { | ||
1066 | pContainer->sczFailedLocalAcquisitionPath = pContext->sczLocalAcquisitionSourcePath; | ||
1067 | pContext->sczLocalAcquisitionSourcePath = NULL; | ||
1068 | } | ||
1069 | } | ||
1070 | |||
1071 | static void FinalizePayloadAcquisition( | ||
1072 | __in BURN_CACHE_CONTEXT* pContext, | ||
1073 | __in BURN_PAYLOAD* pPayload, | ||
1074 | __in BOOL fSuccess | ||
1075 | ) | ||
1076 | { | ||
1077 | ReleaseNullStr(pPayload->sczFailedLocalAcquisitionPath); | ||
1078 | |||
1079 | if (fSuccess) | ||
1080 | { | ||
1081 | ReleaseNullStr(pContext->sczLocalAcquisitionSourcePath); | ||
1082 | pPayload->fFailedVerificationFromAcquisition = FALSE; | ||
1083 | } | ||
1084 | else if (pContext->sczLocalAcquisitionSourcePath) | ||
1085 | { | ||
1086 | pPayload->sczFailedLocalAcquisitionPath = pContext->sczLocalAcquisitionSourcePath; | ||
1087 | pContext->sczLocalAcquisitionSourcePath = NULL; | ||
1088 | } | ||
1089 | } | ||
1090 | |||
1041 | static HRESULT ApplyExtractContainer( | 1091 | static HRESULT ApplyExtractContainer( |
1042 | __in BURN_CACHE_CONTEXT* pContext, | 1092 | __in BURN_CACHE_CONTEXT* pContext, |
1043 | __in BURN_CONTAINER* pContainer | 1093 | __in BURN_CONTAINER* pContainer |
@@ -1066,10 +1116,11 @@ static HRESULT ApplyExtractContainer( | |||
1066 | hr = ExtractContainer(pContext, pContainer); | 1116 | hr = ExtractContainer(pContext, pContainer); |
1067 | LogExitOnFailure(hr, MSG_FAILED_EXTRACT_CONTAINER, "Failed to extract payloads from container: %ls to working path: %ls", pContainer->sczId, pContainer->sczUnverifiedPath); | 1117 | LogExitOnFailure(hr, MSG_FAILED_EXTRACT_CONTAINER, "Failed to extract payloads from container: %ls to working path: %ls", pContainer->sczId, pContainer->sczUnverifiedPath); |
1068 | 1118 | ||
1069 | if (pContext->sczLastUsedFolderCandidate) | 1119 | if (pContext->sczLocalAcquisitionSourcePath) |
1070 | { | 1120 | { |
1071 | // We successfully copied from a source location, set that as the last used source. | 1121 | // We successfully copied from a source location, set that as the last used source. |
1072 | CacheSetLastUsedSource(pContext->pVariables, pContext->sczLastUsedFolderCandidate, pContainer->sczFilePath); | 1122 | CacheSetLastUsedSource(pContext->pVariables, pContext->sczLocalAcquisitionSourcePath, pContainer->sczFilePath); |
1123 | ReleaseNullStr(pContext->sczLocalAcquisitionSourcePath); | ||
1073 | } | 1124 | } |
1074 | 1125 | ||
1075 | if (pContainer->qwExtractSizeTotal < pContainer->qwCommittedExtractProgress) | 1126 | if (pContainer->qwExtractSizeTotal < pContainer->qwCommittedExtractProgress) |
@@ -1086,7 +1137,7 @@ static HRESULT ApplyExtractContainer( | |||
1086 | pContainer->qwCommittedExtractProgress = pContainer->qwExtractSizeTotal; | 1137 | pContainer->qwCommittedExtractProgress = pContainer->qwExtractSizeTotal; |
1087 | 1138 | ||
1088 | LExit: | 1139 | LExit: |
1089 | ReleaseNullStr(pContext->sczLastUsedFolderCandidate); | 1140 | FinalizeContainerAcquisition(pContext, pContainer, SUCCEEDED(hr)); |
1090 | 1141 | ||
1091 | return hr; | 1142 | return hr; |
1092 | } | 1143 | } |
@@ -1157,13 +1208,13 @@ static HRESULT ApplyLayoutContainer( | |||
1157 | ++cTryAgainAttempts; | 1208 | ++cTryAgainAttempts; |
1158 | pContext->qwSuccessfulCacheProgress -= pContainer->qwCommittedCacheProgress; | 1209 | pContext->qwSuccessfulCacheProgress -= pContainer->qwCommittedCacheProgress; |
1159 | pContainer->qwCommittedCacheProgress = 0; | 1210 | pContainer->qwCommittedCacheProgress = 0; |
1160 | ReleaseNullStr(pContext->sczLastUsedFolderCandidate); | 1211 | FinalizeContainerAcquisition(pContext, pContainer, FALSE); |
1161 | LogErrorId(hr, MSG_CACHE_RETRYING_CONTAINER, pContainer->sczId, NULL, NULL); | 1212 | LogErrorId(hr, MSG_CACHE_RETRYING_CONTAINER, pContainer->sczId, NULL, NULL); |
1162 | } | 1213 | } |
1163 | } | 1214 | } |
1164 | 1215 | ||
1165 | LExit: | 1216 | LExit: |
1166 | ReleaseNullStr(pContext->sczLastUsedFolderCandidate); | 1217 | FinalizeContainerAcquisition(pContext, pContainer, SUCCEEDED(hr)); |
1167 | 1218 | ||
1168 | return hr; | 1219 | return hr; |
1169 | } | 1220 | } |
@@ -1230,13 +1281,13 @@ static HRESULT ApplyProcessPayload( | |||
1230 | ++cTryAgainAttempts; | 1281 | ++cTryAgainAttempts; |
1231 | pContext->qwSuccessfulCacheProgress -= pPayloadGroupItem->qwCommittedCacheProgress; | 1282 | pContext->qwSuccessfulCacheProgress -= pPayloadGroupItem->qwCommittedCacheProgress; |
1232 | pPayloadGroupItem->qwCommittedCacheProgress = 0; | 1283 | pPayloadGroupItem->qwCommittedCacheProgress = 0; |
1233 | ReleaseNullStr(pContext->sczLastUsedFolderCandidate); | 1284 | FinalizePayloadAcquisition(pContext, pPayload, FALSE); |
1234 | LogErrorId(hr, MSG_CACHE_RETRYING_PAYLOAD, pPayload->sczKey, NULL, NULL); | 1285 | LogErrorId(hr, MSG_CACHE_RETRYING_PAYLOAD, pPayload->sczKey, NULL, NULL); |
1235 | } | 1286 | } |
1236 | } | 1287 | } |
1237 | 1288 | ||
1238 | LExit: | 1289 | LExit: |
1239 | ReleaseNullStr(pContext->sczLastUsedFolderCandidate); | 1290 | FinalizePayloadAcquisition(pContext, pPayload, SUCCEEDED(hr)); |
1240 | 1291 | ||
1241 | return hr; | 1292 | return hr; |
1242 | } | 1293 | } |
@@ -1570,6 +1621,7 @@ static HRESULT AcquireContainerOrPayload( | |||
1570 | BOOL fPreferExtract = FALSE; | 1621 | BOOL fPreferExtract = FALSE; |
1571 | DWORD64 qwFileSize = 0; | 1622 | DWORD64 qwFileSize = 0; |
1572 | BOOL fMinimumFileSize = FALSE; | 1623 | BOOL fMinimumFileSize = FALSE; |
1624 | BOOL fEqual = FALSE; | ||
1573 | 1625 | ||
1574 | if (pContainer) | 1626 | if (pContainer) |
1575 | { | 1627 | { |
@@ -1615,21 +1667,44 @@ static HRESULT AcquireContainerOrPayload( | |||
1615 | // When a payload comes from a container, the container has the highest chance of being correct. | 1667 | // When a payload comes from a container, the container has the highest chance of being correct. |
1616 | // But we want to avoid extracting the container multiple times. | 1668 | // But we want to avoid extracting the container multiple times. |
1617 | // So only consider the destination path, which means the container was already extracted. | 1669 | // So only consider the destination path, which means the container was already extracted. |
1618 | if (IsValidLocalFile(pContext->rgSearchPaths[dwDestinationSearchPath], qwFileSize, fMinimumFileSize)) | 1670 | if (!pPayload->fFailedVerificationFromAcquisition && IsValidLocalFile(pContext->rgSearchPaths[dwDestinationSearchPath], qwFileSize, fMinimumFileSize)) |
1619 | { | 1671 | { |
1620 | fFoundLocal = TRUE; | 1672 | fFoundLocal = TRUE; |
1621 | dwChosenSearchPath = dwDestinationSearchPath; | 1673 | dwChosenSearchPath = dwDestinationSearchPath; |
1622 | } | 1674 | } |
1623 | else // don't prefer the container if extracting it already failed. | 1675 | else // don't prefer the container if it was already extracted. |
1624 | { | 1676 | { |
1625 | fPreferExtract = SUCCEEDED(pPayload->pContainer->hrExtract); | 1677 | fPreferExtract = !pPayload->pContainer->fExtracted; |
1626 | } | 1678 | } |
1627 | } | 1679 | } |
1628 | 1680 | ||
1629 | if (!fFoundLocal) | 1681 | if (!fFoundLocal) |
1630 | { | 1682 | { |
1683 | BOOL fFailedVerificationFromAcquisition = pContainer ? pContainer->fFailedVerificationFromAcquisition : pPayload->fFailedVerificationFromAcquisition; | ||
1684 | LPCWSTR wzFailedLocalAcquisitionPath = pContainer ? pContainer->sczFailedLocalAcquisitionPath : pPayload->sczFailedLocalAcquisitionPath; | ||
1685 | |||
1631 | for (DWORD i = 0; i < pContext->cSearchPaths; ++i) | 1686 | for (DWORD i = 0; i < pContext->cSearchPaths; ++i) |
1632 | { | 1687 | { |
1688 | // If the file failed verification from acquisition then certain paths should not be considered. | ||
1689 | if (fFailedVerificationFromAcquisition) | ||
1690 | { | ||
1691 | if (i == dwDestinationSearchPath) | ||
1692 | { | ||
1693 | continue; | ||
1694 | } | ||
1695 | |||
1696 | if (wzFailedLocalAcquisitionPath) | ||
1697 | { | ||
1698 | hr = PathCompareCanonicalized(pContext->rgSearchPaths[i], wzFailedLocalAcquisitionPath, &fEqual); | ||
1699 | ExitOnFailure(hr, "Failed to compare '%ls' to '%ls'.", pContext->rgSearchPaths[i], wzFailedLocalAcquisitionPath); | ||
1700 | |||
1701 | if (fEqual) | ||
1702 | { | ||
1703 | continue; | ||
1704 | } | ||
1705 | } | ||
1706 | } | ||
1707 | |||
1633 | // If the file exists locally with the correct size, choose it. | 1708 | // If the file exists locally with the correct size, choose it. |
1634 | if (IsValidLocalFile(pContext->rgSearchPaths[i], qwFileSize, fMinimumFileSize)) | 1709 | if (IsValidLocalFile(pContext->rgSearchPaths[i], qwFileSize, fMinimumFileSize)) |
1635 | { | 1710 | { |
@@ -1703,7 +1778,7 @@ static HRESULT AcquireContainerOrPayload( | |||
1703 | ExitOnFailure(hr, "Failed to copy payload: %ls", wzPayloadId); | 1778 | ExitOnFailure(hr, "Failed to copy payload: %ls", wzPayloadId); |
1704 | 1779 | ||
1705 | // Store the source path so it can be used as the LastUsedFolder if it passes verification. | 1780 | // Store the source path so it can be used as the LastUsedFolder if it passes verification. |
1706 | pContext->sczLastUsedFolderCandidate = pContext->rgSearchPaths[dwChosenSearchPath]; | 1781 | pContext->sczLocalAcquisitionSourcePath = pContext->rgSearchPaths[dwChosenSearchPath]; |
1707 | pContext->rgSearchPaths[dwChosenSearchPath] = NULL; | 1782 | pContext->rgSearchPaths[dwChosenSearchPath] = NULL; |
1708 | } | 1783 | } |
1709 | 1784 | ||
@@ -1731,12 +1806,14 @@ static HRESULT AcquireContainerOrPayload( | |||
1731 | LExit: | 1806 | LExit: |
1732 | if (BOOTSTRAPPER_CACHE_OPERATION_EXTRACT == cacheOperation) | 1807 | if (BOOTSTRAPPER_CACHE_OPERATION_EXTRACT == cacheOperation) |
1733 | { | 1808 | { |
1734 | if (FAILED(hr) && SUCCEEDED(pPayload->pContainer->hrExtract) && | 1809 | // If this was the first extraction attempt and it failed |
1810 | // but there was a different method of acquisition available then recommend retrying. | ||
1811 | if (FAILED(hr) && !pPayload->pContainer->fExtracted && | ||
1735 | (fFoundLocal || pPayload->downloadSource.sczUrl && *pPayload->downloadSource.sczUrl)) | 1812 | (fFoundLocal || pPayload->downloadSource.sczUrl && *pPayload->downloadSource.sczUrl)) |
1736 | { | 1813 | { |
1737 | *pfRetry = TRUE; | 1814 | *pfRetry = TRUE; |
1738 | } | 1815 | } |
1739 | pPayload->pContainer->hrExtract = hr; | 1816 | pPayload->pContainer->fExtracted = TRUE; |
1740 | } | 1817 | } |
1741 | UserExperienceOnCacheAcquireComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr, pfRetry); | 1818 | UserExperienceOnCacheAcquireComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr, pfRetry); |
1742 | 1819 | ||
@@ -2103,6 +2180,31 @@ static HRESULT CALLBACK CacheMessageHandler( | |||
2103 | hr = UserExperienceOnCacheContainerOrPayloadVerifyComplete(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, hr); | 2180 | hr = UserExperienceOnCacheContainerOrPayloadVerifyComplete(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, hr); |
2104 | break; | 2181 | break; |
2105 | } | 2182 | } |
2183 | case BURN_CACHE_MESSAGE_FAILURE: | ||
2184 | switch (pMessage->failure.cacheStep) | ||
2185 | { | ||
2186 | case BURN_CACHE_STEP_HASH: | ||
2187 | if (pProgress->pContainer) | ||
2188 | { | ||
2189 | LogStringLine(REPORT_DEBUG, "Verification failed on container: %ls", pProgress->pContainer->sczId); | ||
2190 | pProgress->pContainer->fFailedVerificationFromAcquisition = TRUE; | ||
2191 | } | ||
2192 | else if (pProgress->pPayloadGroupItem) | ||
2193 | { | ||
2194 | LogStringLine(REPORT_DEBUG, "Verification failed on payload group item: %ls", pProgress->pPayloadGroupItem->pPayload->sczKey); | ||
2195 | pProgress->pPayloadGroupItem->pPayload->fFailedVerificationFromAcquisition = TRUE; | ||
2196 | } | ||
2197 | else if (pProgress->pPayload) | ||
2198 | { | ||
2199 | LogStringLine(REPORT_DEBUG, "Verification failed on payload: %ls", pProgress->pPayload->sczKey); | ||
2200 | pProgress->pPayload->fFailedVerificationFromAcquisition = TRUE; | ||
2201 | } | ||
2202 | else | ||
2203 | { | ||
2204 | LogStringLine(REPORT_DEBUG, "Verification failed on unknown item"); | ||
2205 | } | ||
2206 | break; | ||
2207 | } | ||
2106 | } | 2208 | } |
2107 | 2209 | ||
2108 | return hr; | 2210 | return hr; |
@@ -2159,10 +2261,11 @@ static HRESULT CompleteCacheProgress( | |||
2159 | pContext->pPayloadGroupItem->qwCommittedCacheProgress += qwFileSize; | 2261 | pContext->pPayloadGroupItem->qwCommittedCacheProgress += qwFileSize; |
2160 | } | 2262 | } |
2161 | 2263 | ||
2162 | if (BURN_CACHE_PROGRESS_TYPE_FINALIZE == pContext->type && pContext->pCacheContext->sczLastUsedFolderCandidate) | 2264 | if (BURN_CACHE_PROGRESS_TYPE_FINALIZE == pContext->type && pContext->pCacheContext->sczLocalAcquisitionSourcePath) |
2163 | { | 2265 | { |
2164 | // We successfully copied from a source location, set that as the last used source. | 2266 | // We successfully copied from a source location, set that as the last used source. |
2165 | CacheSetLastUsedSource(pContext->pCacheContext->pVariables, pContext->pCacheContext->sczLastUsedFolderCandidate, pContext->pContainer ? pContext->pContainer->sczFilePath : pContext->pPayloadGroupItem->pPayload->sczFilePath); | 2267 | CacheSetLastUsedSource(pContext->pCacheContext->pVariables, pContext->pCacheContext->sczLocalAcquisitionSourcePath, pContext->pContainer ? pContext->pContainer->sczFilePath : pContext->pPayloadGroupItem->pPayload->sczFilePath); |
2268 | ReleaseNullStr(pContext->pCacheContext->sczLocalAcquisitionSourcePath); | ||
2166 | } | 2269 | } |
2167 | } | 2270 | } |
2168 | else if (PROGRESS_CANCEL == dwResult) | 2271 | else if (PROGRESS_CANCEL == dwResult) |
diff --git a/src/burn/engine/cache.cpp b/src/burn/engine/cache.cpp index eb5cc508..a23ce9ed 100644 --- a/src/burn/engine/cache.cpp +++ b/src/burn/engine/cache.cpp | |||
@@ -12,7 +12,11 @@ static const DWORD FILE_OPERATION_RETRY_WAIT = 2000; | |||
12 | static HRESULT CacheVerifyPayloadSignature( | 12 | static HRESULT CacheVerifyPayloadSignature( |
13 | __in BURN_PAYLOAD* pPayload, | 13 | __in BURN_PAYLOAD* pPayload, |
14 | __in_z LPCWSTR wzUnverifiedPayloadPath, | 14 | __in_z LPCWSTR wzUnverifiedPayloadPath, |
15 | __in HANDLE hFile | 15 | __in HANDLE hFile, |
16 | __in BURN_CACHE_STEP cacheStep, | ||
17 | __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, | ||
18 | __in LPPROGRESS_ROUTINE pfnProgress, | ||
19 | __in LPVOID pContext | ||
16 | ); | 20 | ); |
17 | static HRESULT CalculatePotentialBaseWorkingFolders( | 21 | static HRESULT CalculatePotentialBaseWorkingFolders( |
18 | __in BURN_CACHE* pCache, | 22 | __in BURN_CACHE* pCache, |
@@ -159,7 +163,11 @@ static HRESULT SendCacheCompleteMessage( | |||
159 | __in LPVOID pContext, | 163 | __in LPVOID pContext, |
160 | __in HRESULT hrStatus | 164 | __in HRESULT hrStatus |
161 | ); | 165 | ); |
162 | 166 | static HRESULT SendCacheFailureMessage( | |
167 | __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, | ||
168 | __in LPVOID pContext, | ||
169 | __in BURN_CACHE_STEP cacheStep | ||
170 | ); | ||
163 | 171 | ||
164 | extern "C" HRESULT CacheInitialize( | 172 | extern "C" HRESULT CacheInitialize( |
165 | __in BURN_CACHE* pCache, | 173 | __in BURN_CACHE* pCache, |
@@ -1254,11 +1262,16 @@ LExit: | |||
1254 | static HRESULT CacheVerifyPayloadSignature( | 1262 | static HRESULT CacheVerifyPayloadSignature( |
1255 | __in BURN_PAYLOAD* pPayload, | 1263 | __in BURN_PAYLOAD* pPayload, |
1256 | __in_z LPCWSTR wzUnverifiedPayloadPath, | 1264 | __in_z LPCWSTR wzUnverifiedPayloadPath, |
1257 | __in HANDLE hFile | 1265 | __in HANDLE hFile, |
1266 | __in BURN_CACHE_STEP cacheStep, | ||
1267 | __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, | ||
1268 | __in LPPROGRESS_ROUTINE /*pfnProgress*/, | ||
1269 | __in LPVOID pContext | ||
1258 | ) | 1270 | ) |
1259 | { | 1271 | { |
1260 | HRESULT hr = S_OK; | 1272 | HRESULT hr = S_OK; |
1261 | LONG er = ERROR_SUCCESS; | 1273 | LONG er = ERROR_SUCCESS; |
1274 | BOOL fFailedVerification = FALSE; | ||
1262 | 1275 | ||
1263 | GUID guidAuthenticode = WINTRUST_ACTION_GENERIC_VERIFY_V2; | 1276 | GUID guidAuthenticode = WINTRUST_ACTION_GENERIC_VERIFY_V2; |
1264 | WINTRUST_FILE_INFO wfi = { }; | 1277 | WINTRUST_FILE_INFO wfi = { }; |
@@ -1266,6 +1279,11 @@ static HRESULT CacheVerifyPayloadSignature( | |||
1266 | CRYPT_PROVIDER_DATA* pProviderData = NULL; | 1279 | CRYPT_PROVIDER_DATA* pProviderData = NULL; |
1267 | CRYPT_PROVIDER_SGNR* pSigner = NULL; | 1280 | CRYPT_PROVIDER_SGNR* pSigner = NULL; |
1268 | 1281 | ||
1282 | hr = SendCacheBeginMessage(pfnCacheMessageHandler, pContext, cacheStep); | ||
1283 | ExitOnFailure(hr, "Aborted cache verify payload signature begin."); | ||
1284 | |||
1285 | fFailedVerification = TRUE; | ||
1286 | |||
1269 | // Verify the payload assuming online. | 1287 | // Verify the payload assuming online. |
1270 | wfi.cbStruct = sizeof(wfi); | 1288 | wfi.cbStruct = sizeof(wfi); |
1271 | wfi.pcwszFilePath = wzUnverifiedPayloadPath; | 1289 | wfi.pcwszFilePath = wzUnverifiedPayloadPath; |
@@ -1297,7 +1315,19 @@ static HRESULT CacheVerifyPayloadSignature( | |||
1297 | hr = VerifyPayloadAgainstCertChain(pPayload, pSigner->pChainContext); | 1315 | hr = VerifyPayloadAgainstCertChain(pPayload, pSigner->pChainContext); |
1298 | ExitOnFailure(hr, "Failed to verify expected payload against actual certificate chain."); | 1316 | ExitOnFailure(hr, "Failed to verify expected payload against actual certificate chain."); |
1299 | 1317 | ||
1318 | fFailedVerification = FALSE; | ||
1319 | |||
1320 | hr = SendCacheSuccessMessage(pfnCacheMessageHandler, pContext, pPayload->qwFileSize); | ||
1321 | |||
1300 | LExit: | 1322 | LExit: |
1323 | if (fFailedVerification) | ||
1324 | { | ||
1325 | // Make sure the BA process marks this payload as having failed verification. | ||
1326 | SendCacheFailureMessage(pfnCacheMessageHandler, pContext, cacheStep); | ||
1327 | } | ||
1328 | |||
1329 | SendCacheCompleteMessage(pfnCacheMessageHandler, pContext, hr); | ||
1330 | |||
1301 | return hr; | 1331 | return hr; |
1302 | } | 1332 | } |
1303 | 1333 | ||
@@ -1744,7 +1774,7 @@ static HRESULT VerifyThenTransferPayload( | |||
1744 | switch (pPayload->verification) | 1774 | switch (pPayload->verification) |
1745 | { | 1775 | { |
1746 | case BURN_PAYLOAD_VERIFICATION_AUTHENTICODE: | 1776 | case BURN_PAYLOAD_VERIFICATION_AUTHENTICODE: |
1747 | hr = CacheVerifyPayloadSignature(pPayload, wzUnverifiedPayloadPath, hFile); | 1777 | hr = CacheVerifyPayloadSignature(pPayload, wzUnverifiedPayloadPath, hFile, BURN_CACHE_STEP_HASH, pfnCacheMessageHandler, pfnProgress, pContext); |
1748 | ExitOnFailure(hr, "Failed to verify payload signature: %ls", wzCachedPath); | 1778 | ExitOnFailure(hr, "Failed to verify payload signature: %ls", wzCachedPath); |
1749 | break; | 1779 | break; |
1750 | case BURN_PAYLOAD_VERIFICATION_HASH: | 1780 | case BURN_PAYLOAD_VERIFICATION_HASH: |
@@ -1890,7 +1920,7 @@ static HRESULT VerifyFileAgainstPayload( | |||
1890 | switch (pPayload->verification) | 1920 | switch (pPayload->verification) |
1891 | { | 1921 | { |
1892 | case BURN_PAYLOAD_VERIFICATION_AUTHENTICODE: | 1922 | case BURN_PAYLOAD_VERIFICATION_AUTHENTICODE: |
1893 | hr = CacheVerifyPayloadSignature(pPayload, wzVerifyPath, hFile); | 1923 | hr = CacheVerifyPayloadSignature(pPayload, wzVerifyPath, hFile, cacheStep, pfnCacheMessageHandler, pfnProgress, pContext); |
1894 | ExitOnFailure(hr, "Failed to verify signature of payload: %ls", pPayload->sczKey); | 1924 | ExitOnFailure(hr, "Failed to verify signature of payload: %ls", pPayload->sczKey); |
1895 | break; | 1925 | break; |
1896 | case BURN_PAYLOAD_VERIFICATION_HASH: | 1926 | case BURN_PAYLOAD_VERIFICATION_HASH: |
@@ -2285,17 +2315,18 @@ static HRESULT VerifyHash( | |||
2285 | __in LPVOID pContext | 2315 | __in LPVOID pContext |
2286 | ) | 2316 | ) |
2287 | { | 2317 | { |
2288 | UNREFERENCED_PARAMETER(wzUnverifiedPayloadPath); | ||
2289 | |||
2290 | HRESULT hr = S_OK; | 2318 | HRESULT hr = S_OK; |
2291 | BYTE rgbActualHash[SHA512_HASH_LEN] = { }; | 2319 | BYTE rgbActualHash[SHA512_HASH_LEN] = { }; |
2292 | DWORD64 qwHashedBytes = 0; | 2320 | DWORD64 qwHashedBytes = 0; |
2293 | LPWSTR pszExpected = NULL; | 2321 | LPWSTR pszExpected = NULL; |
2294 | LPWSTR pszActual = NULL; | 2322 | LPWSTR pszActual = NULL; |
2323 | BOOL fFailedVerification = FALSE; | ||
2295 | 2324 | ||
2296 | hr = SendCacheBeginMessage(pfnCacheMessageHandler, pContext, cacheStep); | 2325 | hr = SendCacheBeginMessage(pfnCacheMessageHandler, pContext, cacheStep); |
2297 | ExitOnFailure(hr, "Aborted cache verify hash begin."); | 2326 | ExitOnFailure(hr, "Aborted cache verify hash begin."); |
2298 | 2327 | ||
2328 | fFailedVerification = TRUE; | ||
2329 | |||
2299 | if (fVerifyFileSize) | 2330 | if (fVerifyFileSize) |
2300 | { | 2331 | { |
2301 | hr = VerifyFileSize(hFile, qwFileSize, wzUnverifiedPayloadPath); | 2332 | hr = VerifyFileSize(hFile, qwFileSize, wzUnverifiedPayloadPath); |
@@ -2323,9 +2354,17 @@ static HRESULT VerifyHash( | |||
2323 | } | 2354 | } |
2324 | } | 2355 | } |
2325 | 2356 | ||
2357 | fFailedVerification = FALSE; | ||
2358 | |||
2326 | hr = SendCacheSuccessMessage(pfnCacheMessageHandler, pContext, qwFileSize); | 2359 | hr = SendCacheSuccessMessage(pfnCacheMessageHandler, pContext, qwFileSize); |
2327 | 2360 | ||
2328 | LExit: | 2361 | LExit: |
2362 | if (fFailedVerification) | ||
2363 | { | ||
2364 | // Make sure the BA process marks this container or payload as having failed verification. | ||
2365 | SendCacheFailureMessage(pfnCacheMessageHandler, pContext, cacheStep); | ||
2366 | } | ||
2367 | |||
2329 | SendCacheCompleteMessage(pfnCacheMessageHandler, pContext, hr); | 2368 | SendCacheCompleteMessage(pfnCacheMessageHandler, pContext, hr); |
2330 | 2369 | ||
2331 | ReleaseStr(pszActual); | 2370 | ReleaseStr(pszActual); |
@@ -2448,3 +2487,20 @@ static HRESULT SendCacheCompleteMessage( | |||
2448 | 2487 | ||
2449 | return hr; | 2488 | return hr; |
2450 | } | 2489 | } |
2490 | |||
2491 | static HRESULT SendCacheFailureMessage( | ||
2492 | __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, | ||
2493 | __in LPVOID pContext, | ||
2494 | __in BURN_CACHE_STEP cacheStep | ||
2495 | ) | ||
2496 | { | ||
2497 | HRESULT hr = S_OK; | ||
2498 | BURN_CACHE_MESSAGE message = { }; | ||
2499 | |||
2500 | message.type = BURN_CACHE_MESSAGE_FAILURE; | ||
2501 | message.failure.cacheStep = cacheStep; | ||
2502 | |||
2503 | hr = pfnCacheMessageHandler(&message, pContext); | ||
2504 | |||
2505 | return hr; | ||
2506 | } | ||
diff --git a/src/burn/engine/cache.h b/src/burn/engine/cache.h index 9c698b4b..cc28166e 100644 --- a/src/burn/engine/cache.h +++ b/src/burn/engine/cache.h | |||
@@ -13,6 +13,7 @@ enum BURN_CACHE_MESSAGE_TYPE | |||
13 | BURN_CACHE_MESSAGE_BEGIN, | 13 | BURN_CACHE_MESSAGE_BEGIN, |
14 | BURN_CACHE_MESSAGE_SUCCESS, | 14 | BURN_CACHE_MESSAGE_SUCCESS, |
15 | BURN_CACHE_MESSAGE_COMPLETE, | 15 | BURN_CACHE_MESSAGE_COMPLETE, |
16 | BURN_CACHE_MESSAGE_FAILURE, | ||
16 | }; | 17 | }; |
17 | 18 | ||
18 | enum BURN_CACHE_STEP | 19 | enum BURN_CACHE_STEP |
@@ -68,6 +69,10 @@ typedef struct _BURN_CACHE_MESSAGE | |||
68 | { | 69 | { |
69 | HRESULT hrStatus; | 70 | HRESULT hrStatus; |
70 | } complete; | 71 | } complete; |
72 | struct | ||
73 | { | ||
74 | BURN_CACHE_STEP cacheStep; | ||
75 | } failure; | ||
71 | }; | 76 | }; |
72 | } BURN_CACHE_MESSAGE; | 77 | } BURN_CACHE_MESSAGE; |
73 | 78 | ||
diff --git a/src/burn/engine/container.cpp b/src/burn/engine/container.cpp index 2f21baa8..e6b91532 100644 --- a/src/burn/engine/container.cpp +++ b/src/burn/engine/container.cpp | |||
@@ -173,6 +173,7 @@ extern "C" void ContainersUninitialize( | |||
173 | ReleaseStr(pContainer->downloadSource.sczUser); | 173 | ReleaseStr(pContainer->downloadSource.sczUser); |
174 | ReleaseStr(pContainer->downloadSource.sczPassword); | 174 | ReleaseStr(pContainer->downloadSource.sczPassword); |
175 | ReleaseStr(pContainer->sczUnverifiedPath); | 175 | ReleaseStr(pContainer->sczUnverifiedPath); |
176 | ReleaseStr(pContainer->sczFailedLocalAcquisitionPath); | ||
176 | ReleaseDict(pContainer->sdhPayloads); | 177 | ReleaseDict(pContainer->sdhPayloads); |
177 | } | 178 | } |
178 | MemFree(pContainers->rgContainers); | 179 | MemFree(pContainers->rgContainers); |
diff --git a/src/burn/engine/container.h b/src/burn/engine/container.h index f35f1da5..a38afa90 100644 --- a/src/burn/engine/container.h +++ b/src/burn/engine/container.h | |||
@@ -88,7 +88,9 @@ typedef struct _BURN_CONTAINER | |||
88 | DWORD64 qwExtractSizeTotal; | 88 | DWORD64 qwExtractSizeTotal; |
89 | DWORD64 qwCommittedCacheProgress; | 89 | DWORD64 qwCommittedCacheProgress; |
90 | DWORD64 qwCommittedExtractProgress; | 90 | DWORD64 qwCommittedExtractProgress; |
91 | HRESULT hrExtract; | 91 | BOOL fExtracted; |
92 | BOOL fFailedVerificationFromAcquisition; | ||
93 | LPWSTR sczFailedLocalAcquisitionPath; | ||
92 | } BURN_CONTAINER; | 94 | } BURN_CONTAINER; |
93 | 95 | ||
94 | typedef struct _BURN_CONTAINERS | 96 | typedef struct _BURN_CONTAINERS |
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp index e165a257..ef9c6e97 100644 --- a/src/burn/engine/elevation.cpp +++ b/src/burn/engine/elevation.cpp | |||
@@ -42,6 +42,7 @@ typedef enum _BURN_ELEVATION_MESSAGE_TYPE | |||
42 | BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_BEGIN, | 42 | BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_BEGIN, |
43 | BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_COMPLETE, | 43 | BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_COMPLETE, |
44 | BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS, | 44 | BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS, |
45 | BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_FAILURE, | ||
45 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS, | 46 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS, |
46 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_CANCEL, | 47 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_CANCEL, |
47 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_STARTED, | 48 | BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROCESS_STARTED, |
@@ -1792,11 +1793,19 @@ static HRESULT ProcessBurnCacheMessages( | |||
1792 | case BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS: | 1793 | case BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS: |
1793 | // read message parameters | 1794 | // read message parameters |
1794 | hr = BuffReadNumber64((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.success.qwFileSize); | 1795 | hr = BuffReadNumber64((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.success.qwFileSize); |
1795 | ExitOnFailure(hr, "Failed to read begin cache step."); | 1796 | ExitOnFailure(hr, "Failed to read success file size."); |
1796 | 1797 | ||
1797 | message.type = BURN_CACHE_MESSAGE_SUCCESS; | 1798 | message.type = BURN_CACHE_MESSAGE_SUCCESS; |
1798 | break; | 1799 | break; |
1799 | 1800 | ||
1801 | case BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_FAILURE: | ||
1802 | // read message parameters | ||
1803 | hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, reinterpret_cast<DWORD*>(&message.failure.cacheStep)); | ||
1804 | ExitOnFailure(hr, "Failed to read failure cache step."); | ||
1805 | |||
1806 | message.type = BURN_CACHE_MESSAGE_FAILURE; | ||
1807 | break; | ||
1808 | |||
1800 | case BURN_ELEVATION_MESSAGE_TYPE_PROGRESS_ROUTINE: | 1809 | case BURN_ELEVATION_MESSAGE_TYPE_PROGRESS_ROUTINE: |
1801 | fProgressRoutine = TRUE; | 1810 | fProgressRoutine = TRUE; |
1802 | break; | 1811 | break; |
@@ -3511,7 +3520,7 @@ static HRESULT CALLBACK BurnCacheMessageHandler( | |||
3511 | case BURN_CACHE_MESSAGE_BEGIN: | 3520 | case BURN_CACHE_MESSAGE_BEGIN: |
3512 | // serialize message data | 3521 | // serialize message data |
3513 | hr = BuffWriteNumber(&pbData, &cbData, pMessage->begin.cacheStep); | 3522 | hr = BuffWriteNumber(&pbData, &cbData, pMessage->begin.cacheStep); |
3514 | ExitOnFailure(hr, "Failed to write progress percentage to message buffer."); | 3523 | ExitOnFailure(hr, "Failed to write cache step to message buffer."); |
3515 | 3524 | ||
3516 | dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_BEGIN; | 3525 | dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_BEGIN; |
3517 | break; | 3526 | break; |
@@ -3526,10 +3535,18 @@ static HRESULT CALLBACK BurnCacheMessageHandler( | |||
3526 | 3535 | ||
3527 | case BURN_CACHE_MESSAGE_SUCCESS: | 3536 | case BURN_CACHE_MESSAGE_SUCCESS: |
3528 | hr = BuffWriteNumber64(&pbData, &cbData, pMessage->success.qwFileSize); | 3537 | hr = BuffWriteNumber64(&pbData, &cbData, pMessage->success.qwFileSize); |
3529 | ExitOnFailure(hr, "Failed to count of files in use to message buffer."); | 3538 | ExitOnFailure(hr, "Failed to write file size to message buffer."); |
3530 | 3539 | ||
3531 | dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS; | 3540 | dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS; |
3532 | break; | 3541 | break; |
3542 | |||
3543 | case BURN_CACHE_MESSAGE_FAILURE: | ||
3544 | // serialize message data | ||
3545 | hr = BuffWriteNumber(&pbData, &cbData, pMessage->failure.cacheStep); | ||
3546 | ExitOnFailure(hr, "Failed to write cache step to message buffer."); | ||
3547 | |||
3548 | dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_FAILURE; | ||
3549 | break; | ||
3533 | } | 3550 | } |
3534 | 3551 | ||
3535 | // send message | 3552 | // send message |
diff --git a/src/burn/engine/payload.cpp b/src/burn/engine/payload.cpp index a4450bf7..fe3d673e 100644 --- a/src/burn/engine/payload.cpp +++ b/src/burn/engine/payload.cpp | |||
@@ -240,6 +240,7 @@ extern "C" void PayloadUninitialize( | |||
240 | ReleaseMem(pPayload->pbCertificateRootPublicKeyIdentifier); | 240 | ReleaseMem(pPayload->pbCertificateRootPublicKeyIdentifier); |
241 | ReleaseStr(pPayload->sczSourcePath); | 241 | ReleaseStr(pPayload->sczSourcePath); |
242 | ReleaseStr(pPayload->sczLocalFilePath); | 242 | ReleaseStr(pPayload->sczLocalFilePath); |
243 | ReleaseStr(pPayload->sczFailedLocalAcquisitionPath); | ||
243 | ReleaseStr(pPayload->downloadSource.sczUrl); | 244 | ReleaseStr(pPayload->downloadSource.sczUrl); |
244 | ReleaseStr(pPayload->downloadSource.sczUser); | 245 | ReleaseStr(pPayload->downloadSource.sczUser); |
245 | ReleaseStr(pPayload->downloadSource.sczPassword); | 246 | ReleaseStr(pPayload->downloadSource.sczPassword); |
diff --git a/src/burn/engine/payload.h b/src/burn/engine/payload.h index 14738506..351fd058 100644 --- a/src/burn/engine/payload.h +++ b/src/burn/engine/payload.h | |||
@@ -60,6 +60,9 @@ typedef struct _BURN_PAYLOAD | |||
60 | 60 | ||
61 | LPWSTR sczUnverifiedPath; | 61 | LPWSTR sczUnverifiedPath; |
62 | DWORD cRemainingInstances; | 62 | DWORD cRemainingInstances; |
63 | |||
64 | BOOL fFailedVerificationFromAcquisition; | ||
65 | LPWSTR sczFailedLocalAcquisitionPath; | ||
63 | } BURN_PAYLOAD; | 66 | } BURN_PAYLOAD; |
64 | 67 | ||
65 | typedef struct _BURN_PAYLOADS | 68 | typedef struct _BURN_PAYLOADS |
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index 5c9ebe08..e6997b64 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp | |||
@@ -2105,7 +2105,9 @@ static void ResetPlannedContainerState( | |||
2105 | pContainer->qwExtractSizeTotal = 0; | 2105 | pContainer->qwExtractSizeTotal = 0; |
2106 | pContainer->qwCommittedCacheProgress = 0; | 2106 | pContainer->qwCommittedCacheProgress = 0; |
2107 | pContainer->qwCommittedExtractProgress = 0; | 2107 | pContainer->qwCommittedExtractProgress = 0; |
2108 | pContainer->hrExtract = S_OK; | 2108 | pContainer->fExtracted = FALSE; |
2109 | pContainer->fFailedVerificationFromAcquisition = FALSE; | ||
2110 | ReleaseNullStr(pContainer->sczFailedLocalAcquisitionPath); | ||
2109 | } | 2111 | } |
2110 | 2112 | ||
2111 | static void ResetPlannedPayloadsState( | 2113 | static void ResetPlannedPayloadsState( |
@@ -2118,7 +2120,9 @@ static void ResetPlannedPayloadsState( | |||
2118 | 2120 | ||
2119 | pPayload->cRemainingInstances = 0; | 2121 | pPayload->cRemainingInstances = 0; |
2120 | pPayload->state = BURN_PAYLOAD_STATE_NONE; | 2122 | pPayload->state = BURN_PAYLOAD_STATE_NONE; |
2123 | pPayload->fFailedVerificationFromAcquisition = FALSE; | ||
2121 | ReleaseNullStr(pPayload->sczLocalFilePath); | 2124 | ReleaseNullStr(pPayload->sczLocalFilePath); |
2125 | ReleaseNullStr(pPayload->sczFailedLocalAcquisitionPath); | ||
2122 | } | 2126 | } |
2123 | } | 2127 | } |
2124 | 2128 | ||