diff options
Diffstat (limited to 'src/burn/engine/apply.cpp')
-rw-r--r-- | src/burn/engine/apply.cpp | 137 |
1 files changed, 120 insertions, 17 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) |