diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/engine/apply.cpp | 317 | ||||
| -rw-r--r-- | src/engine/engine.mc | 21 | ||||
| -rw-r--r-- | src/engine/plan.cpp | 8 |
3 files changed, 185 insertions, 161 deletions
diff --git a/src/engine/apply.cpp b/src/engine/apply.cpp index c39a7746..e62db4d2 100644 --- a/src/engine/apply.cpp +++ b/src/engine/apply.cpp | |||
| @@ -37,7 +37,7 @@ typedef struct _BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT | |||
| 37 | BURN_PAYLOAD* pPayload; | 37 | BURN_PAYLOAD* pPayload; |
| 38 | 38 | ||
| 39 | BOOL fCancel; | 39 | BOOL fCancel; |
| 40 | BOOL fError; | 40 | HRESULT hrError; |
| 41 | } BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT; | 41 | } BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT; |
| 42 | 42 | ||
| 43 | typedef struct _BURN_EXECUTE_CONTEXT | 43 | typedef struct _BURN_EXECUTE_CONTEXT |
| @@ -102,12 +102,16 @@ static HRESULT LayoutBundle( | |||
| 102 | __in_z LPCWSTR wzExecutableName, | 102 | __in_z LPCWSTR wzExecutableName, |
| 103 | __in_z LPCWSTR wzUnverifiedPath | 103 | __in_z LPCWSTR wzUnverifiedPath |
| 104 | ); | 104 | ); |
| 105 | static HRESULT AcquireContainerOrPayload( | 105 | static HRESULT ApplyAcquireContainerOrPayload( |
| 106 | __in BURN_CACHE_CONTEXT* pContext, | 106 | __in BURN_CACHE_CONTEXT* pContext, |
| 107 | __in_opt BURN_CONTAINER* pContainer, | 107 | __in_opt BURN_CONTAINER* pContainer, |
| 108 | __in_opt BURN_PACKAGE* pPackage, | 108 | __in_opt BURN_PACKAGE* pPackage, |
| 109 | __in_opt BURN_PAYLOAD* pPayload | 109 | __in_opt BURN_PAYLOAD* pPayload |
| 110 | ); | 110 | ); |
| 111 | static HRESULT AcquireContainerOrPayload( | ||
| 112 | __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, | ||
| 113 | __out BOOL* pfRetry | ||
| 114 | ); | ||
| 111 | static HRESULT LayoutOrCacheContainerOrPayload( | 115 | static HRESULT LayoutOrCacheContainerOrPayload( |
| 112 | __in BURN_CACHE_CONTEXT* pContext, | 116 | __in BURN_CACHE_CONTEXT* pContext, |
| 113 | __in_opt BURN_CONTAINER* pContainer, | 117 | __in_opt BURN_CONTAINER* pContainer, |
| @@ -127,6 +131,10 @@ static HRESULT DownloadPayload( | |||
| 127 | __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, | 131 | __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, |
| 128 | __in_z LPCWSTR wzDestinationPath | 132 | __in_z LPCWSTR wzDestinationPath |
| 129 | ); | 133 | ); |
| 134 | static HRESULT CompleteCacheProgress( | ||
| 135 | __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pContext, | ||
| 136 | __in DWORD64 qwFileSize | ||
| 137 | ); | ||
| 130 | static DWORD CALLBACK CacheProgressRoutine( | 138 | static DWORD CALLBACK CacheProgressRoutine( |
| 131 | __in LARGE_INTEGER TotalFileSize, | 139 | __in LARGE_INTEGER TotalFileSize, |
| 132 | __in LARGE_INTEGER TotalBytesTransferred, | 140 | __in LARGE_INTEGER TotalBytesTransferred, |
| @@ -833,12 +841,10 @@ static HRESULT ApplyExtractContainer( | |||
| 833 | 841 | ||
| 834 | if (!pContainer->fActuallyAttached) | 842 | if (!pContainer->fActuallyAttached) |
| 835 | { | 843 | { |
| 836 | hr = AcquireContainerOrPayload(pContext, pContainer, NULL, NULL); | 844 | hr = ApplyAcquireContainerOrPayload(pContext, pContainer, NULL, NULL); |
| 837 | LogExitOnFailure(hr, MSG_FAILED_ACQUIRE_CONTAINER, "Failed to acquire container: %ls to working path: %ls", pContainer->sczId, pContainer->sczUnverifiedPath); | 845 | LogExitOnFailure(hr, MSG_FAILED_ACQUIRE_CONTAINER, "Failed to acquire container: %ls to working path: %ls", pContainer->sczId, pContainer->sczUnverifiedPath); |
| 838 | } | 846 | } |
| 839 | 847 | ||
| 840 | pContext->qwSuccessfulCacheProgress += pContainer->qwFileSize; | ||
| 841 | |||
| 842 | hr = ExtractContainer(pContext, pContainer); | 848 | hr = ExtractContainer(pContext, pContainer); |
| 843 | LogExitOnFailure(hr, MSG_FAILED_EXTRACT_CONTAINER, "Failed to extract payloads from container: %ls to working path: %ls", pContainer->sczId, pContainer->sczUnverifiedPath); | 849 | LogExitOnFailure(hr, MSG_FAILED_EXTRACT_CONTAINER, "Failed to extract payloads from container: %ls to working path: %ls", pContainer->sczId, pContainer->sczUnverifiedPath); |
| 844 | 850 | ||
| @@ -903,11 +909,9 @@ static HRESULT ApplyLayoutContainer( | |||
| 903 | { | 909 | { |
| 904 | fRetry = FALSE; | 910 | fRetry = FALSE; |
| 905 | 911 | ||
| 906 | hr = AcquireContainerOrPayload(pContext, pContainer, NULL, NULL); | 912 | hr = ApplyAcquireContainerOrPayload(pContext, pContainer, NULL, NULL); |
| 907 | LogExitOnFailure(hr, MSG_FAILED_ACQUIRE_CONTAINER, "Failed to acquire container: %ls to working path: %ls", pContainer->sczId, pContainer->sczUnverifiedPath); | 913 | LogExitOnFailure(hr, MSG_FAILED_ACQUIRE_CONTAINER, "Failed to acquire container: %ls to working path: %ls", pContainer->sczId, pContainer->sczUnverifiedPath); |
| 908 | 914 | ||
| 909 | pContext->qwSuccessfulCacheProgress += pContainer->qwFileSize; | ||
| 910 | |||
| 911 | hr = LayoutOrCacheContainerOrPayload(pContext, pContainer, NULL, NULL, TRUE, cTryAgainAttempts, &fRetry); | 915 | hr = LayoutOrCacheContainerOrPayload(pContext, pContainer, NULL, NULL, TRUE, cTryAgainAttempts, &fRetry); |
| 912 | if (SUCCEEDED(hr)) | 916 | if (SUCCEEDED(hr)) |
| 913 | { | 917 | { |
| @@ -932,7 +936,7 @@ static HRESULT ApplyLayoutContainer( | |||
| 932 | ++cTryAgainAttempts; | 936 | ++cTryAgainAttempts; |
| 933 | pContext->qwSuccessfulCacheProgress -= pContainer->qwFileSize; | 937 | pContext->qwSuccessfulCacheProgress -= pContainer->qwFileSize; |
| 934 | ReleaseNullStr(pContext->sczLastUsedFolderCandidate); | 938 | ReleaseNullStr(pContext->sczLastUsedFolderCandidate); |
| 935 | LogErrorId(hr, MSG_APPLY_RETRYING_PAYLOAD, pContainer->sczId, NULL, NULL); | 939 | LogErrorId(hr, MSG_APPLY_RETRYING_CONTAINER, pContainer->sczId, NULL, NULL); |
| 936 | } | 940 | } |
| 937 | } | 941 | } |
| 938 | 942 | ||
| @@ -971,11 +975,9 @@ static HRESULT ApplyProcessPayload( | |||
| 971 | { | 975 | { |
| 972 | fRetry = FALSE; | 976 | fRetry = FALSE; |
| 973 | 977 | ||
| 974 | hr = AcquireContainerOrPayload(pContext, NULL, pPackage, pPayload); | 978 | hr = ApplyAcquireContainerOrPayload(pContext, NULL, pPackage, pPayload); |
| 975 | LogExitOnFailure(hr, MSG_FAILED_ACQUIRE_PAYLOAD, "Failed to acquire payload: %ls to working path: %ls", pPayload->sczKey, pPayload->sczUnverifiedPath); | 979 | LogExitOnFailure(hr, MSG_FAILED_ACQUIRE_PAYLOAD, "Failed to acquire payload: %ls to working path: %ls", pPayload->sczKey, pPayload->sczUnverifiedPath); |
| 976 | 980 | ||
| 977 | pContext->qwSuccessfulCacheProgress += pPayload->qwFileSize; | ||
| 978 | |||
| 979 | // TODO: set fMove to TRUE appropriately | 981 | // TODO: set fMove to TRUE appropriately |
| 980 | hr = LayoutOrCacheContainerOrPayload(pContext, NULL, pPackage, pPayload, FALSE, cTryAgainAttempts, &fRetry); | 982 | hr = LayoutOrCacheContainerOrPayload(pContext, NULL, pPackage, pPayload, FALSE, cTryAgainAttempts, &fRetry); |
| 981 | if (SUCCEEDED(hr)) | 983 | if (SUCCEEDED(hr)) |
| @@ -1172,7 +1174,7 @@ LExit: | |||
| 1172 | return hr; | 1174 | return hr; |
| 1173 | } | 1175 | } |
| 1174 | 1176 | ||
| 1175 | static HRESULT AcquireContainerOrPayload( | 1177 | static HRESULT ApplyAcquireContainerOrPayload( |
| 1176 | __in BURN_CACHE_CONTEXT* pContext, | 1178 | __in BURN_CACHE_CONTEXT* pContext, |
| 1177 | __in_opt BURN_CONTAINER* pContainer, | 1179 | __in_opt BURN_CONTAINER* pContainer, |
| 1178 | __in_opt BURN_PACKAGE* pPackage, | 1180 | __in_opt BURN_PACKAGE* pPackage, |
| @@ -1182,164 +1184,149 @@ static HRESULT AcquireContainerOrPayload( | |||
| 1182 | AssertSz(pContainer || pPayload, "Must provide a container or a payload."); | 1184 | AssertSz(pContainer || pPayload, "Must provide a container or a payload."); |
| 1183 | 1185 | ||
| 1184 | HRESULT hr = S_OK; | 1186 | HRESULT hr = S_OK; |
| 1187 | BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT progress = { }; | ||
| 1188 | BOOL fRetry = FALSE; | ||
| 1189 | |||
| 1190 | progress.pCacheContext = pContext; | ||
| 1191 | progress.pContainer = pContainer; | ||
| 1192 | progress.pPackage = pPackage; | ||
| 1193 | progress.pPayload = pPayload; | ||
| 1194 | |||
| 1195 | do | ||
| 1196 | { | ||
| 1197 | hr = AcquireContainerOrPayload(&progress, &fRetry); | ||
| 1198 | |||
| 1199 | if (fRetry) | ||
| 1200 | { | ||
| 1201 | hr = S_OK; | ||
| 1202 | LogErrorId(hr, pContainer ? MSG_APPLY_RETRYING_ACQUIRE_CONTAINER : MSG_APPLY_RETRYING_ACQUIRE_PAYLOAD, pContainer ? pContainer->sczId : pPayload->sczKey, NULL, NULL); | ||
| 1203 | } | ||
| 1204 | |||
| 1205 | ExitOnFailure(hr, "Failed to acquire %hs: %ls", pContainer ? "container" : "payload", pContainer ? pContainer->sczId : pPayload->sczKey); | ||
| 1206 | } while (fRetry); | ||
| 1207 | |||
| 1208 | LExit: | ||
| 1209 | return hr; | ||
| 1210 | } | ||
| 1211 | |||
| 1212 | static HRESULT AcquireContainerOrPayload( | ||
| 1213 | __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, | ||
| 1214 | __out BOOL* pfRetry | ||
| 1215 | ) | ||
| 1216 | { | ||
| 1217 | BURN_CACHE_CONTEXT* pContext = pProgress->pCacheContext; | ||
| 1218 | BURN_CONTAINER* pContainer = pProgress->pContainer; | ||
| 1219 | BURN_PACKAGE* pPackage = pProgress->pPackage; | ||
| 1220 | BURN_PAYLOAD* pPayload = pProgress->pPayload; | ||
| 1221 | AssertSz(pContainer || pPayload, "Must provide a container or a payload."); | ||
| 1222 | |||
| 1223 | HRESULT hr = S_OK; | ||
| 1185 | int nEquivalentPaths = 0; | 1224 | int nEquivalentPaths = 0; |
| 1186 | LPCWSTR wzPackageOrContainerId = pContainer ? pContainer->sczId : pPackage ? pPackage->sczId : NULL; | 1225 | LPCWSTR wzPackageOrContainerId = pContainer ? pContainer->sczId : pPackage ? pPackage->sczId : NULL; |
| 1187 | LPCWSTR wzPayloadId = pPayload ? pPayload->sczKey : NULL; | 1226 | LPCWSTR wzPayloadId = pPayload ? pPayload->sczKey : NULL; |
| 1188 | LPCWSTR wzPayloadContainerId = pPayload && pPayload->pContainer ? pPayload->pContainer->sczId : NULL; | 1227 | LPCWSTR wzPayloadContainerId = pPayload && pPayload->pContainer ? pPayload->pContainer->sczId : NULL; |
| 1189 | LPCWSTR wzDestinationPath = pContainer ? pContainer->sczUnverifiedPath: pPayload->sczUnverifiedPath; | 1228 | LPCWSTR wzDestinationPath = pContainer ? pContainer->sczUnverifiedPath: pPayload->sczUnverifiedPath; |
| 1190 | LPCWSTR wzRelativePath = pContainer ? pContainer->sczFilePath : pPayload->sczFilePath; | 1229 | LPCWSTR wzRelativePath = pContainer ? pContainer->sczFilePath : pPayload->sczFilePath; |
| 1191 | BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT progress = { }; | ||
| 1192 | BOOL fBeginCalled = FALSE; | ||
| 1193 | BOOL fRetry = FALSE; | ||
| 1194 | DWORD dwChosenSearchPath = 0; | 1230 | DWORD dwChosenSearchPath = 0; |
| 1195 | BOOTSTRAPPER_CACHE_OPERATION cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_NONE; | 1231 | BOOTSTRAPPER_CACHE_OPERATION cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_NONE; |
| 1196 | LPWSTR* pwzDownloadUrl = pContainer ? &pContainer->downloadSource.sczUrl : &pPayload->downloadSource.sczUrl; | 1232 | LPWSTR* pwzDownloadUrl = pContainer ? &pContainer->downloadSource.sczUrl : &pPayload->downloadSource.sczUrl; |
| 1197 | LPWSTR* pwzSourcePath = pContainer ? &pContainer->sczSourcePath : &pPayload->sczSourcePath; | 1233 | LPWSTR* pwzSourcePath = pContainer ? &pContainer->sczSourcePath : &pPayload->sczSourcePath; |
| 1234 | BOOL fFoundLocal = FALSE; | ||
| 1198 | 1235 | ||
| 1199 | progress.pCacheContext = pContext; | 1236 | pContext->cSearchPaths = 0; |
| 1200 | progress.pContainer = pContainer; | 1237 | *pfRetry = FALSE; |
| 1201 | progress.pPackage = pPackage; | 1238 | pProgress->fCancel = FALSE; |
| 1202 | progress.pPayload = pPayload; | ||
| 1203 | |||
| 1204 | do | ||
| 1205 | { | ||
| 1206 | BOOL fFoundLocal = FALSE; | ||
| 1207 | 1239 | ||
| 1208 | pContext->cSearchPaths = 0; | 1240 | hr = UserExperienceOnCacheAcquireBegin(pContext->pUX, wzPackageOrContainerId, wzPayloadId, pwzSourcePath, pwzDownloadUrl, wzPayloadContainerId, &cacheOperation); |
| 1209 | dwChosenSearchPath = 0; | 1241 | ExitOnRootFailure(hr, "BA aborted cache acquire begin."); |
| 1210 | fRetry = FALSE; | ||
| 1211 | progress.fCancel = FALSE; | ||
| 1212 | fBeginCalled = TRUE; | ||
| 1213 | 1242 | ||
| 1214 | hr = UserExperienceOnCacheAcquireBegin(pContext->pUX, wzPackageOrContainerId, wzPayloadId, pwzSourcePath, pwzDownloadUrl, wzPayloadContainerId, &cacheOperation); | 1243 | // Skip the Resolving event and probing local paths if the BA already knew it wanted to download or extract. |
| 1215 | ExitOnRootFailure(hr, "BA aborted cache acquire begin."); | 1244 | if (BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD != cacheOperation && |
| 1245 | BOOTSTRAPPER_CACHE_OPERATION_EXTRACT != cacheOperation) | ||
| 1246 | { | ||
| 1247 | hr = CacheGetLocalSourcePaths(wzRelativePath, *pwzSourcePath, wzDestinationPath, pContext->wzLayoutDirectory, pContext->pVariables, &pContext->rgSearchPaths, &pContext->cSearchPaths); | ||
| 1248 | ExitOnFailure(hr, "Failed to search local source."); | ||
| 1216 | 1249 | ||
| 1217 | // Skip the Resolving event and probing local paths if the BA already knew it wanted to download or extract. | 1250 | for (DWORD i = 0; i < pContext->cSearchPaths; ++i) |
| 1218 | if (BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD != cacheOperation && | ||
| 1219 | BOOTSTRAPPER_CACHE_OPERATION_EXTRACT != cacheOperation) | ||
| 1220 | { | 1251 | { |
| 1221 | hr = CacheGetLocalSourcePaths(wzRelativePath, *pwzSourcePath, wzDestinationPath, pContext->wzLayoutDirectory, pContext->pVariables, &pContext->rgSearchPaths, &pContext->cSearchPaths); | 1252 | // If the file exists locally, choose it. |
| 1222 | ExitOnFailure(hr, "Failed to search local source."); | 1253 | if (FileExistsEx(pContext->rgSearchPaths[i], NULL)) |
| 1223 | |||
| 1224 | for (DWORD i = 0; i < pContext->cSearchPaths; ++i) | ||
| 1225 | { | 1254 | { |
| 1226 | // If the file exists locally, choose it. | 1255 | dwChosenSearchPath = i; |
| 1227 | if (FileExistsEx(pContext->rgSearchPaths[i], NULL)) | ||
| 1228 | { | ||
| 1229 | dwChosenSearchPath = i; | ||
| 1230 | 1256 | ||
| 1231 | fFoundLocal = TRUE; | 1257 | fFoundLocal = TRUE; |
| 1232 | break; | 1258 | break; |
| 1233 | } | ||
| 1234 | } | 1259 | } |
| 1260 | } | ||
| 1235 | 1261 | ||
| 1236 | if (BOOTSTRAPPER_CACHE_OPERATION_COPY == cacheOperation) | 1262 | if (BOOTSTRAPPER_CACHE_OPERATION_COPY == cacheOperation) |
| 1237 | { | 1263 | { |
| 1238 | if (!fFoundLocal) | 1264 | if (!fFoundLocal) |
| 1239 | { | ||
| 1240 | cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_NONE; | ||
| 1241 | } | ||
| 1242 | } | ||
| 1243 | else | ||
| 1244 | { | 1265 | { |
| 1245 | if (fFoundLocal) // the file exists locally, so copy it. | 1266 | cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_NONE; |
| 1246 | { | ||
| 1247 | cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_COPY; | ||
| 1248 | } | ||
| 1249 | else if (wzPayloadContainerId) | ||
| 1250 | { | ||
| 1251 | cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_EXTRACT; | ||
| 1252 | } | ||
| 1253 | else if (*pwzDownloadUrl && **pwzDownloadUrl) | ||
| 1254 | { | ||
| 1255 | cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD; | ||
| 1256 | } | ||
| 1257 | } | 1267 | } |
| 1258 | |||
| 1259 | // Let the BA have a chance to override the action, but their chance to change the source is during begin or complete. | ||
| 1260 | hr = UserExperienceOnCacheAcquireResolving(pContext->pUX, wzPackageOrContainerId, wzPayloadId, pContext->rgSearchPaths, pContext->cSearchPaths, fFoundLocal, &dwChosenSearchPath, *pwzDownloadUrl, wzPayloadContainerId, &cacheOperation); | ||
| 1261 | ExitOnRootFailure(hr, "BA aborted cache acquire resolving."); | ||
| 1262 | } | 1268 | } |
| 1263 | 1269 | else | |
| 1264 | switch (cacheOperation) | ||
| 1265 | { | 1270 | { |
| 1266 | case BOOTSTRAPPER_CACHE_OPERATION_COPY: | 1271 | if (fFoundLocal) // the file exists locally, so copy it. |
| 1267 | // If the source path and destination path are different, do the copy (otherwise there's no point). | ||
| 1268 | hr = PathCompare(pContext->rgSearchPaths[dwChosenSearchPath], wzDestinationPath, &nEquivalentPaths); | ||
| 1269 | ExitOnFailure(hr, "Failed to determine if payload paths were equivalent, source: %ls, destination: %ls.", pContext->rgSearchPaths[dwChosenSearchPath], wzDestinationPath); | ||
| 1270 | |||
| 1271 | if (CSTR_EQUAL != nEquivalentPaths) | ||
| 1272 | { | 1272 | { |
| 1273 | hr = CopyPayload(&progress, INVALID_HANDLE_VALUE, pContext->rgSearchPaths[dwChosenSearchPath], wzDestinationPath); | 1273 | cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_COPY; |
| 1274 | // Error handling happens after sending complete message to BA. | ||
| 1275 | |||
| 1276 | // Store the source path so it can be used as the LastUsedFolder if it passes verification. | ||
| 1277 | pContext->sczLastUsedFolderCandidate = pContext->rgSearchPaths[dwChosenSearchPath]; | ||
| 1278 | pContext->rgSearchPaths[dwChosenSearchPath] = NULL; | ||
| 1279 | } | 1274 | } |
| 1280 | 1275 | else if (wzPayloadContainerId) | |
| 1281 | fBeginCalled = FALSE; | ||
| 1282 | UserExperienceOnCacheAcquireComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr, &fRetry); | ||
| 1283 | if (fRetry) | ||
| 1284 | { | 1276 | { |
| 1285 | hr = S_OK; | 1277 | cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_EXTRACT; |
| 1286 | } | 1278 | } |
| 1287 | 1279 | else if (*pwzDownloadUrl && **pwzDownloadUrl) | |
| 1288 | ExitOnFailure(hr, "Failed to acquire payload from: '%ls' to working path: '%ls'", pContext->rgSearchPaths[dwChosenSearchPath], wzDestinationPath); | ||
| 1289 | |||
| 1290 | break; | ||
| 1291 | case BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD: | ||
| 1292 | hr = DownloadPayload(&progress, wzDestinationPath); | ||
| 1293 | // Error handling happens after sending complete message to BA. | ||
| 1294 | |||
| 1295 | fBeginCalled = FALSE; | ||
| 1296 | UserExperienceOnCacheAcquireComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr, &fRetry); | ||
| 1297 | if (fRetry) | ||
| 1298 | { | 1280 | { |
| 1299 | hr = S_OK; | 1281 | cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD; |
| 1300 | } | 1282 | } |
| 1283 | } | ||
| 1301 | 1284 | ||
| 1302 | ExitOnFailure(hr, "Failed to acquire payload from: '%ls' to working path: '%ls'", *pwzDownloadUrl, wzDestinationPath); | 1285 | // Let the BA have a chance to override the action, but their chance to change the source is during begin or complete. |
| 1286 | hr = UserExperienceOnCacheAcquireResolving(pContext->pUX, wzPackageOrContainerId, wzPayloadId, pContext->rgSearchPaths, pContext->cSearchPaths, fFoundLocal, &dwChosenSearchPath, *pwzDownloadUrl, wzPayloadContainerId, &cacheOperation); | ||
| 1287 | ExitOnRootFailure(hr, "BA aborted cache acquire resolving."); | ||
| 1288 | } | ||
| 1303 | 1289 | ||
| 1304 | break; | 1290 | switch (cacheOperation) |
| 1305 | case BOOTSTRAPPER_CACHE_OPERATION_EXTRACT: | 1291 | { |
| 1306 | Assert(pPayload->pContainer); | 1292 | case BOOTSTRAPPER_CACHE_OPERATION_COPY: |
| 1293 | // If the source path and destination path are different, do the copy (otherwise there's no point). | ||
| 1294 | hr = PathCompare(pContext->rgSearchPaths[dwChosenSearchPath], wzDestinationPath, &nEquivalentPaths); | ||
| 1295 | ExitOnFailure(hr, "Failed to determine if payload paths were equivalent, source: %ls, destination: %ls.", pContext->rgSearchPaths[dwChosenSearchPath], wzDestinationPath); | ||
| 1307 | 1296 | ||
| 1308 | hr = ApplyExtractContainer(pContext, pPayload->pContainer); | 1297 | if (CSTR_EQUAL != nEquivalentPaths) |
| 1309 | // Error handling happens after sending complete message to BA. | 1298 | { |
| 1299 | hr = CopyPayload(pProgress, INVALID_HANDLE_VALUE, pContext->rgSearchPaths[dwChosenSearchPath], wzDestinationPath); | ||
| 1300 | ExitOnFailure(hr, "Failed to copy payload: %ls", wzPayloadId); | ||
| 1310 | 1301 | ||
| 1311 | fBeginCalled = FALSE; | 1302 | // Store the source path so it can be used as the LastUsedFolder if it passes verification. |
| 1312 | UserExperienceOnCacheAcquireComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr, &fRetry); | 1303 | pContext->sczLastUsedFolderCandidate = pContext->rgSearchPaths[dwChosenSearchPath]; |
| 1313 | if (fRetry) | 1304 | pContext->rgSearchPaths[dwChosenSearchPath] = NULL; |
| 1314 | { | 1305 | } |
| 1315 | hr = S_OK; | ||
| 1316 | } | ||
| 1317 | 1306 | ||
| 1318 | ExitOnFailure(hr, "Failed to extract container for payload: %ls", wzPayloadId); | 1307 | break; |
| 1308 | case BOOTSTRAPPER_CACHE_OPERATION_DOWNLOAD: | ||
| 1309 | hr = DownloadPayload(pProgress, wzDestinationPath); | ||
| 1310 | ExitOnFailure(hr, "Failed to download payload: %ls", wzPayloadId); | ||
| 1319 | 1311 | ||
| 1320 | break; | 1312 | break; |
| 1321 | case BOOTSTRAPPER_CACHE_OPERATION_NONE: | 1313 | case BOOTSTRAPPER_CACHE_OPERATION_EXTRACT: |
| 1322 | hr = E_FILENOTFOUND; | 1314 | Assert(pPayload->pContainer); |
| 1323 | LogErrorId(hr, MSG_RESOLVE_SOURCE_FAILED, wzPayloadId, pPackage ? pPackage->sczId : NULL, pContainer ? pContainer->sczId : NULL); | ||
| 1324 | 1315 | ||
| 1325 | fBeginCalled = FALSE; | 1316 | hr = ApplyExtractContainer(pContext, pPayload->pContainer); |
| 1326 | UserExperienceOnCacheAcquireComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr, &fRetry); | 1317 | ExitOnFailure(hr, "Failed to extract container for payload: %ls", wzPayloadId); |
| 1327 | if (fRetry) | ||
| 1328 | { | ||
| 1329 | hr = S_OK; | ||
| 1330 | } | ||
| 1331 | 1318 | ||
| 1332 | ExitOnFailure(hr, "Failed to resolve source, payload: %ls, package: %ls, container: %ls", wzPayloadId, pPackage ? pPackage->sczId : NULL, pContainer ? pContainer->sczId : NULL); | 1319 | break; |
| 1320 | default: | ||
| 1321 | hr = E_FILENOTFOUND; | ||
| 1322 | LogExitOnFailure(hr, MSG_RESOLVE_SOURCE_FAILED, "Failed to resolve source, payload: %ls, package: %ls, container: %ls", wzPayloadId, pPackage ? pPackage->sczId : NULL, pContainer ? pContainer->sczId : NULL); | ||
| 1323 | } | ||
| 1333 | 1324 | ||
| 1334 | break; | 1325 | // Send 100% complete here. This is sometimes the only progress sent to the BA. |
| 1335 | } | 1326 | hr = CompleteCacheProgress(pProgress, pContainer ? pContainer->qwFileSize : pPayload->qwFileSize); |
| 1336 | } while (fRetry); | ||
| 1337 | 1327 | ||
| 1338 | LExit: | 1328 | LExit: |
| 1339 | if (fBeginCalled) | 1329 | UserExperienceOnCacheAcquireComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr, pfRetry); |
| 1340 | { | ||
| 1341 | UserExperienceOnCacheAcquireComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr, &fRetry); | ||
| 1342 | } | ||
| 1343 | 1330 | ||
| 1344 | pContext->cSearchPathsMax = max(pContext->cSearchPaths, pContext->cSearchPathsMax); | 1331 | pContext->cSearchPathsMax = max(pContext->cSearchPaths, pContext->cSearchPathsMax); |
| 1345 | 1332 | ||
| @@ -1360,9 +1347,6 @@ static HRESULT LayoutOrCacheContainerOrPayload( | |||
| 1360 | LPCWSTR wzPackageOrContainerId = pContainer ? pContainer->sczId : pPackage ? pPackage->sczId : L""; | 1347 | LPCWSTR wzPackageOrContainerId = pContainer ? pContainer->sczId : pPackage ? pPackage->sczId : L""; |
| 1361 | LPCWSTR wzUnverifiedPath = pContainer ? pContainer->sczUnverifiedPath : pPayload->sczUnverifiedPath; | 1348 | LPCWSTR wzUnverifiedPath = pContainer ? pContainer->sczUnverifiedPath : pPayload->sczUnverifiedPath; |
| 1362 | LPCWSTR wzPayloadId = pPayload ? pPayload->sczKey : L""; | 1349 | LPCWSTR wzPayloadId = pPayload ? pPayload->sczKey : L""; |
| 1363 | LARGE_INTEGER liContainerOrPayloadSize = { }; | ||
| 1364 | LARGE_INTEGER liZero = { }; | ||
| 1365 | BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT progress = { }; | ||
| 1366 | BOOL fCanAffectRegistration = FALSE; | 1350 | BOOL fCanAffectRegistration = FALSE; |
| 1367 | 1351 | ||
| 1368 | if (!pContext->wzLayoutDirectory) | 1352 | if (!pContext->wzLayoutDirectory) |
| @@ -1373,13 +1357,6 @@ static HRESULT LayoutOrCacheContainerOrPayload( | |||
| 1373 | fCanAffectRegistration = pPackage->fCanAffectRegistration; | 1357 | fCanAffectRegistration = pPackage->fCanAffectRegistration; |
| 1374 | } | 1358 | } |
| 1375 | 1359 | ||
| 1376 | liContainerOrPayloadSize.QuadPart = pContainer ? pContainer->qwFileSize : pPayload->qwFileSize; | ||
| 1377 | |||
| 1378 | progress.pCacheContext = pContext; | ||
| 1379 | progress.pContainer = pContainer; | ||
| 1380 | progress.pPackage = pPackage; | ||
| 1381 | progress.pPayload = pPayload; | ||
| 1382 | |||
| 1383 | *pfRetry = FALSE; | 1360 | *pfRetry = FALSE; |
| 1384 | 1361 | ||
| 1385 | do | 1362 | do |
| @@ -1407,25 +1384,9 @@ static HRESULT LayoutOrCacheContainerOrPayload( | |||
| 1407 | hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, wzUnverifiedPath, fMove); | 1384 | hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, wzUnverifiedPath, fMove); |
| 1408 | } | 1385 | } |
| 1409 | 1386 | ||
| 1410 | // If succeeded, send 100% complete here. If the payload was already cached this is the first progress the BA | 1387 | if (SUCCEEDED(hr) && fCanAffectRegistration) |
| 1411 | // will get. | ||
| 1412 | if (SUCCEEDED(hr)) | ||
| 1413 | { | 1388 | { |
| 1414 | if (fCanAffectRegistration) | 1389 | pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT; |
| 1415 | { | ||
| 1416 | pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT; | ||
| 1417 | } | ||
| 1418 | |||
| 1419 | CacheProgressRoutine(liContainerOrPayloadSize, liContainerOrPayloadSize, liZero, liZero, 0, 0, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, &progress); | ||
| 1420 | if (progress.fCancel) | ||
| 1421 | { | ||
| 1422 | hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); | ||
| 1423 | } | ||
| 1424 | else if (progress.fError) | ||
| 1425 | { | ||
| 1426 | hr = HRESULT_FROM_WIN32(ERROR_INSTALL_FAILURE); | ||
| 1427 | } | ||
| 1428 | ExitOnRootFailure(hr, "BA aborted verify of %hs: %ls", pContainer ? "container" : "payload", pContainer ? wzPackageOrContainerId : wzPayloadId); | ||
| 1429 | } | 1390 | } |
| 1430 | 1391 | ||
| 1431 | BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = FAILED(hr) && cTryAgainAttempts < BURN_CACHE_MAX_RECOMMENDED_VERIFY_TRYAGAIN_ATTEMPTS ? BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYACQUISITION : BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE; | 1392 | BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = FAILED(hr) && cTryAgainAttempts < BURN_CACHE_MAX_RECOMMENDED_VERIFY_TRYAGAIN_ATTEMPTS ? BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYACQUISITION : BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE; |
| @@ -1624,6 +1585,39 @@ LExit: | |||
| 1624 | return hr; | 1585 | return hr; |
| 1625 | } | 1586 | } |
| 1626 | 1587 | ||
| 1588 | static HRESULT CompleteCacheProgress( | ||
| 1589 | __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pContext, | ||
| 1590 | __in DWORD64 qwFileSize | ||
| 1591 | ) | ||
| 1592 | { | ||
| 1593 | HRESULT hr = S_OK; | ||
| 1594 | LARGE_INTEGER liContainerOrPayloadSize = { }; | ||
| 1595 | LARGE_INTEGER liZero = { }; | ||
| 1596 | DWORD dwResult = 0; | ||
| 1597 | |||
| 1598 | liContainerOrPayloadSize.QuadPart = qwFileSize; | ||
| 1599 | |||
| 1600 | dwResult = CacheProgressRoutine(liContainerOrPayloadSize, liContainerOrPayloadSize, liZero, liZero, 0, 0, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, pContext); | ||
| 1601 | |||
| 1602 | if (PROGRESS_CONTINUE == dwResult) | ||
| 1603 | { | ||
| 1604 | pContext->pCacheContext->qwSuccessfulCacheProgress += qwFileSize; | ||
| 1605 | } | ||
| 1606 | else if (PROGRESS_CANCEL == dwResult) | ||
| 1607 | { | ||
| 1608 | if (pContext->fCancel) | ||
| 1609 | { | ||
| 1610 | hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); | ||
| 1611 | } | ||
| 1612 | else | ||
| 1613 | { | ||
| 1614 | hr = pContext->hrError; | ||
| 1615 | } | ||
| 1616 | } | ||
| 1617 | |||
| 1618 | return hr; | ||
| 1619 | } | ||
| 1620 | |||
| 1627 | static DWORD CALLBACK CacheProgressRoutine( | 1621 | static DWORD CALLBACK CacheProgressRoutine( |
| 1628 | __in LARGE_INTEGER TotalFileSize, | 1622 | __in LARGE_INTEGER TotalFileSize, |
| 1629 | __in LARGE_INTEGER TotalBytesTransferred, | 1623 | __in LARGE_INTEGER TotalBytesTransferred, |
| @@ -1650,6 +1644,9 @@ static DWORD CALLBACK CacheProgressRoutine( | |||
| 1650 | DWORD dwOverallPercentage = pProgress->pCacheContext->qwTotalCacheSize ? static_cast<DWORD>(qwCacheProgress * 100 / pProgress->pCacheContext->qwTotalCacheSize) : 0; | 1644 | DWORD dwOverallPercentage = pProgress->pCacheContext->qwTotalCacheSize ? static_cast<DWORD>(qwCacheProgress * 100 / pProgress->pCacheContext->qwTotalCacheSize) : 0; |
| 1651 | 1645 | ||
| 1652 | hr = UserExperienceOnCacheAcquireProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage); | 1646 | hr = UserExperienceOnCacheAcquireProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage); |
| 1647 | ExitOnRootFailure(hr, "BA aborted acquire of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId); | ||
| 1648 | |||
| 1649 | LExit: | ||
| 1653 | if (HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) == hr) | 1650 | if (HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) == hr) |
| 1654 | { | 1651 | { |
| 1655 | dwResult = PROGRESS_CANCEL; | 1652 | dwResult = PROGRESS_CANCEL; |
| @@ -1658,7 +1655,7 @@ static DWORD CALLBACK CacheProgressRoutine( | |||
| 1658 | else if (FAILED(hr)) | 1655 | else if (FAILED(hr)) |
| 1659 | { | 1656 | { |
| 1660 | dwResult = PROGRESS_CANCEL; | 1657 | dwResult = PROGRESS_CANCEL; |
| 1661 | pProgress->fError = TRUE; | 1658 | pProgress->hrError = hr; |
| 1662 | } | 1659 | } |
| 1663 | else | 1660 | else |
| 1664 | { | 1661 | { |
diff --git a/src/engine/engine.mc b/src/engine/engine.mc index f03bc1ea..0e19d3bb 100644 --- a/src/engine/engine.mc +++ b/src/engine/engine.mc | |||
| @@ -724,6 +724,13 @@ Language=English | |||
| 724 | Acquiring package: %1!ls!, payload: %2!ls!, %3!hs! from: %4!ls! | 724 | Acquiring package: %1!ls!, payload: %2!ls!, %3!hs! from: %4!ls! |
| 725 | . | 725 | . |
| 726 | 726 | ||
| 727 | MessageId=347 | ||
| 728 | Severity=Warning | ||
| 729 | SymbolicName=MSG_APPLY_RETRYING_CONTAINER | ||
| 730 | Language=English | ||
| 731 | Application requested retry of container: %2!ls!, encountered error: %1!ls!. Retrying... | ||
| 732 | . | ||
| 733 | |||
| 727 | MessageId=348 | 734 | MessageId=348 |
| 728 | Severity=Warning | 735 | Severity=Warning |
| 729 | SymbolicName=MSG_APPLY_RETRYING_PACKAGE | 736 | SymbolicName=MSG_APPLY_RETRYING_PACKAGE |
| @@ -780,6 +787,20 @@ Language=English | |||
| 780 | Unable to register source directory: %1!ls!, product: %2!ls!, reason: 0x%3!x!. Continuing... | 787 | Unable to register source directory: %1!ls!, product: %2!ls!, reason: 0x%3!x!. Continuing... |
| 781 | . | 788 | . |
| 782 | 789 | ||
| 790 | MessageId=356 | ||
| 791 | Severity=Warning | ||
| 792 | SymbolicName=MSG_APPLY_RETRYING_ACQUIRE_CONTAINER | ||
| 793 | Language=English | ||
| 794 | Application requested retry acquire of container: %2!ls!, encountered error: %1!ls!. Retrying... | ||
| 795 | . | ||
| 796 | |||
| 797 | MessageId=357 | ||
| 798 | Severity=Warning | ||
| 799 | SymbolicName=MSG_APPLY_RETRYING_ACQUIRE_PAYLOAD | ||
| 800 | Language=English | ||
| 801 | Application requested retry acquire of payload: %2!ls!, encountered error: %1!ls!. Retrying... | ||
| 802 | . | ||
| 803 | |||
| 783 | MessageId=358 | 804 | MessageId=358 |
| 784 | Severity=Success | 805 | Severity=Success |
| 785 | SymbolicName=MSG_PAUSE_AU_STARTING | 806 | SymbolicName=MSG_PAUSE_AU_STARTING |
diff --git a/src/engine/plan.cpp b/src/engine/plan.cpp index cfe4893b..a37dcc89 100644 --- a/src/engine/plan.cpp +++ b/src/engine/plan.cpp | |||
| @@ -1010,7 +1010,13 @@ extern "C" HRESULT PlanLayoutContainer( | |||
| 1010 | } | 1010 | } |
| 1011 | else | 1011 | else |
| 1012 | { | 1012 | { |
| 1013 | pPlan->qwCacheSizeTotal += 2 * pContainer->qwFileSize; | 1013 | if (!pContainer->fActuallyAttached) |
| 1014 | { | ||
| 1015 | pPlan->qwCacheSizeTotal += pContainer->qwFileSize; | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | // TODO: This should be the sum of all uncompressed payloads in the container, ideally restricted to the payloads that were actually planned. | ||
| 1019 | pPlan->qwCacheSizeTotal += pContainer->qwFileSize; | ||
| 1014 | } | 1020 | } |
| 1015 | 1021 | ||
| 1016 | if (!pContainer->sczUnverifiedPath) | 1022 | if (!pContainer->sczUnverifiedPath) |
