aboutsummaryrefslogtreecommitdiff
path: root/src/burn/engine/apply.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/burn/engine/apply.cpp')
-rw-r--r--src/burn/engine/apply.cpp137
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
44typedef struct _BURN_CACHE_PROGRESS_CONTEXT 44typedef 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 );
95static void FinalizeContainerAcquisition(
96 __in BURN_CACHE_CONTEXT* pContext,
97 __in BURN_CONTAINER* pContainer,
98 __in BOOL fSuccess
99 );
100static void FinalizePayloadAcquisition(
101 __in BURN_CACHE_CONTEXT* pContext,
102 __in BURN_PAYLOAD* pPayload,
103 __in BOOL fSuccess
104 );
95static HRESULT ApplyExtractContainer( 105static 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
1051static 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
1071static 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
1041static HRESULT ApplyExtractContainer( 1091static 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
1088LExit: 1139LExit:
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
1165LExit: 1216LExit:
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
1238LExit: 1289LExit:
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(
1731LExit: 1806LExit:
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)