diff options
Diffstat (limited to 'src/engine/apply.cpp')
| -rw-r--r-- | src/engine/apply.cpp | 44 |
1 files changed, 38 insertions, 6 deletions
diff --git a/src/engine/apply.cpp b/src/engine/apply.cpp index dc40c50d..2815f7da 100644 --- a/src/engine/apply.cpp +++ b/src/engine/apply.cpp | |||
| @@ -69,6 +69,7 @@ static void UpdateCacheSuccessProgress( | |||
| 69 | __inout DWORD64* pqwSuccessfulCachedProgress | 69 | __inout DWORD64* pqwSuccessfulCachedProgress |
| 70 | ); | 70 | ); |
| 71 | static HRESULT LayoutBundle( | 71 | static HRESULT LayoutBundle( |
| 72 | __in HANDLE hSourceEngineFile, | ||
| 72 | __in BURN_USER_EXPERIENCE* pUX, | 73 | __in BURN_USER_EXPERIENCE* pUX, |
| 73 | __in BURN_VARIABLES* pVariables, | 74 | __in BURN_VARIABLES* pVariables, |
| 74 | __in HANDLE hPipe, | 75 | __in HANDLE hPipe, |
| @@ -114,6 +115,7 @@ static HRESULT PromptForSource( | |||
| 114 | ); | 115 | ); |
| 115 | static HRESULT CopyPayload( | 116 | static HRESULT CopyPayload( |
| 116 | __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, | 117 | __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, |
| 118 | __in HANDLE hSourceFile, | ||
| 117 | __in_z LPCWSTR wzSourcePath, | 119 | __in_z LPCWSTR wzSourcePath, |
| 118 | __in_z LPCWSTR wzDestinationPath | 120 | __in_z LPCWSTR wzDestinationPath |
| 119 | ); | 121 | ); |
| @@ -510,7 +512,7 @@ extern "C" HRESULT ApplyCache( | |||
| 510 | break; | 512 | break; |
| 511 | 513 | ||
| 512 | case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE: | 514 | case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE: |
| 513 | hr = LayoutBundle(pUX, pVariables, hPipe, pCacheAction->bundleLayout.sczExecutableName, pCacheAction->bundleLayout.sczLayoutDirectory, pCacheAction->bundleLayout.sczUnverifiedPath, qwSuccessfulCachedProgress, pPlan->qwCacheSizeTotal); | 515 | hr = LayoutBundle(hSourceEngineFile, pUX, pVariables, hPipe, pCacheAction->bundleLayout.sczExecutableName, pCacheAction->bundleLayout.sczLayoutDirectory, pCacheAction->bundleLayout.sczUnverifiedPath, qwSuccessfulCachedProgress, pPlan->qwCacheSizeTotal); |
| 514 | if (SUCCEEDED(hr)) | 516 | if (SUCCEEDED(hr)) |
| 515 | { | 517 | { |
| 516 | UpdateCacheSuccessProgress(pPlan, pCacheAction, &qwSuccessfulCachedProgress); | 518 | UpdateCacheSuccessProgress(pPlan, pCacheAction, &qwSuccessfulCachedProgress); |
| @@ -1053,6 +1055,7 @@ static void UpdateCacheSuccessProgress( | |||
| 1053 | } | 1055 | } |
| 1054 | 1056 | ||
| 1055 | static HRESULT LayoutBundle( | 1057 | static HRESULT LayoutBundle( |
| 1058 | __in HANDLE hSourceEngineFile, | ||
| 1056 | __in BURN_USER_EXPERIENCE* pUX, | 1059 | __in BURN_USER_EXPERIENCE* pUX, |
| 1057 | __in BURN_VARIABLES* pVariables, | 1060 | __in BURN_VARIABLES* pVariables, |
| 1058 | __in HANDLE hPipe, | 1061 | __in HANDLE hPipe, |
| @@ -1090,7 +1093,7 @@ static HRESULT LayoutBundle( | |||
| 1090 | hr = PathCompare(sczBundlePath, sczDestinationPath, &nEquivalentPaths); | 1093 | hr = PathCompare(sczBundlePath, sczDestinationPath, &nEquivalentPaths); |
| 1091 | ExitOnFailure(hr, "Failed to determine if layout bundle path was equivalent with current process path."); | 1094 | ExitOnFailure(hr, "Failed to determine if layout bundle path was equivalent with current process path."); |
| 1092 | 1095 | ||
| 1093 | if (CSTR_EQUAL == nEquivalentPaths) | 1096 | if (CSTR_EQUAL == nEquivalentPaths && FileExistsEx(sczDestinationPath, NULL)) |
| 1094 | { | 1097 | { |
| 1095 | ExitFunction1(hr = S_OK); | 1098 | ExitFunction1(hr = S_OK); |
| 1096 | } | 1099 | } |
| @@ -1112,7 +1115,7 @@ static HRESULT LayoutBundle( | |||
| 1112 | hr = UserExperienceOnCacheAcquireBegin(pUX, NULL, NULL, BOOTSTRAPPER_CACHE_OPERATION_COPY, sczBundlePath); | 1115 | hr = UserExperienceOnCacheAcquireBegin(pUX, NULL, NULL, BOOTSTRAPPER_CACHE_OPERATION_COPY, sczBundlePath); |
| 1113 | ExitOnRootFailure(hr, "BA aborted cache acquire begin."); | 1116 | ExitOnRootFailure(hr, "BA aborted cache acquire begin."); |
| 1114 | 1117 | ||
| 1115 | hr = CopyPayload(&progress, sczBundlePath, wzUnverifiedPath); | 1118 | hr = CopyPayload(&progress, hSourceEngineFile, sczBundlePath, wzUnverifiedPath); |
| 1116 | // Error handling happens after sending complete message to BA. | 1119 | // Error handling happens after sending complete message to BA. |
| 1117 | 1120 | ||
| 1118 | UserExperienceOnCacheAcquireComplete(pUX, NULL, NULL, hr, &fRetryAcquire); | 1121 | UserExperienceOnCacheAcquireComplete(pUX, NULL, NULL, hr, &fRetryAcquire); |
| @@ -1239,7 +1242,7 @@ static HRESULT AcquireContainerOrPayload( | |||
| 1239 | hr = UserExperienceOnCacheAcquireBegin(pUX, wzPackageOrContainerId, wzPayloadId, BOOTSTRAPPER_CACHE_OPERATION_COPY, sczSourceFullPath); | 1242 | hr = UserExperienceOnCacheAcquireBegin(pUX, wzPackageOrContainerId, wzPayloadId, BOOTSTRAPPER_CACHE_OPERATION_COPY, sczSourceFullPath); |
| 1240 | ExitOnRootFailure(hr, "BA aborted cache acquire begin."); | 1243 | ExitOnRootFailure(hr, "BA aborted cache acquire begin."); |
| 1241 | 1244 | ||
| 1242 | hr = CopyPayload(&progress, sczSourceFullPath, wzDestinationPath); | 1245 | hr = CopyPayload(&progress, INVALID_HANDLE_VALUE, sczSourceFullPath, wzDestinationPath); |
| 1243 | // Error handling happens after sending complete message to BA. | 1246 | // Error handling happens after sending complete message to BA. |
| 1244 | 1247 | ||
| 1245 | // We successfully copied from a source location, set that as the last used source. | 1248 | // We successfully copied from a source location, set that as the last used source. |
| @@ -1432,6 +1435,7 @@ LExit: | |||
| 1432 | 1435 | ||
| 1433 | static HRESULT CopyPayload( | 1436 | static HRESULT CopyPayload( |
| 1434 | __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, | 1437 | __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, |
| 1438 | __in HANDLE hSourceFile, | ||
| 1435 | __in_z LPCWSTR wzSourcePath, | 1439 | __in_z LPCWSTR wzSourcePath, |
| 1436 | __in_z LPCWSTR wzDestinationPath | 1440 | __in_z LPCWSTR wzDestinationPath |
| 1437 | ) | 1441 | ) |
| @@ -1440,6 +1444,8 @@ static HRESULT CopyPayload( | |||
| 1440 | DWORD dwFileAttributes = 0; | 1444 | DWORD dwFileAttributes = 0; |
| 1441 | LPCWSTR wzPackageOrContainerId = pProgress->pContainer ? pProgress->pContainer->sczId : pProgress->pPackage ? pProgress->pPackage->sczId : L""; | 1445 | LPCWSTR wzPackageOrContainerId = pProgress->pContainer ? pProgress->pContainer->sczId : pProgress->pPackage ? pProgress->pPackage->sczId : L""; |
| 1442 | LPCWSTR wzPayloadId = pProgress->pPayload ? pProgress->pPayload->sczKey : L""; | 1446 | LPCWSTR wzPayloadId = pProgress->pPayload ? pProgress->pPayload->sczKey : L""; |
| 1447 | HANDLE hDestinationFile = INVALID_HANDLE_VALUE; | ||
| 1448 | HANDLE hSourceOpenedFile = INVALID_HANDLE_VALUE; | ||
| 1443 | 1449 | ||
| 1444 | DWORD dwLogId = pProgress->pContainer ? (pProgress->pPayload ? MSG_ACQUIRE_CONTAINER_PAYLOAD : MSG_ACQUIRE_CONTAINER) : pProgress->pPackage ? MSG_ACQUIRE_PACKAGE_PAYLOAD : MSG_ACQUIRE_BUNDLE_PAYLOAD; | 1450 | DWORD dwLogId = pProgress->pContainer ? (pProgress->pPayload ? MSG_ACQUIRE_CONTAINER_PAYLOAD : MSG_ACQUIRE_CONTAINER) : pProgress->pPackage ? MSG_ACQUIRE_PACKAGE_PAYLOAD : MSG_ACQUIRE_BUNDLE_PAYLOAD; |
| 1445 | LogId(REPORT_STANDARD, dwLogId, wzPackageOrContainerId, wzPayloadId, "copy", wzSourcePath); | 1451 | LogId(REPORT_STANDARD, dwLogId, wzPackageOrContainerId, wzPayloadId, "copy", wzSourcePath); |
| @@ -1457,7 +1463,30 @@ static HRESULT CopyPayload( | |||
| 1457 | } | 1463 | } |
| 1458 | } | 1464 | } |
| 1459 | 1465 | ||
| 1460 | if (!::CopyFileExW(wzSourcePath, wzDestinationPath, CacheProgressRoutine, pProgress, &pProgress->fCancel, 0)) | 1466 | if (INVALID_HANDLE_VALUE == hSourceFile) |
| 1467 | { | ||
| 1468 | hSourceOpenedFile = ::CreateFileW(wzSourcePath, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); | ||
| 1469 | if (INVALID_HANDLE_VALUE == hSourceOpenedFile) | ||
| 1470 | { | ||
| 1471 | ExitWithLastError(hr, "Failed to open source file to copy payload from: '%ls' to: %ls.", wzSourcePath, wzDestinationPath); | ||
| 1472 | } | ||
| 1473 | |||
| 1474 | hSourceFile = hSourceOpenedFile; | ||
| 1475 | } | ||
| 1476 | else | ||
| 1477 | { | ||
| 1478 | hr = FileSetPointer(hSourceFile, 0, NULL, FILE_BEGIN); | ||
| 1479 | ExitOnRootFailure(hr, "Failed to read from start of source file to copy payload from: '%ls' to: %ls.", wzSourcePath, wzDestinationPath); | ||
| 1480 | } | ||
| 1481 | |||
| 1482 | hDestinationFile = ::CreateFileW(wzDestinationPath, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL); | ||
| 1483 | if (INVALID_HANDLE_VALUE == hDestinationFile) | ||
| 1484 | { | ||
| 1485 | ExitWithLastError(hr, "Failed to open destination file to copy payload from: '%ls' to: %ls.", wzSourcePath, wzDestinationPath); | ||
| 1486 | } | ||
| 1487 | |||
| 1488 | hr = FileCopyUsingHandlesWithProgress(hSourceFile, hDestinationFile, 0, CacheProgressRoutine, pProgress); | ||
| 1489 | if (FAILED(hr)) | ||
| 1461 | { | 1490 | { |
| 1462 | if (pProgress->fCancel) | 1491 | if (pProgress->fCancel) |
| 1463 | { | 1492 | { |
| @@ -1466,11 +1495,14 @@ static HRESULT CopyPayload( | |||
| 1466 | } | 1495 | } |
| 1467 | else | 1496 | else |
| 1468 | { | 1497 | { |
| 1469 | ExitWithLastError(hr, "Failed attempt to copy payload from: '%ls' to: %ls.", wzSourcePath, wzDestinationPath); | 1498 | ExitOnRootFailure(hr, "Failed attempt to copy payload from: '%ls' to: %ls.", wzSourcePath, wzDestinationPath); |
| 1470 | } | 1499 | } |
| 1471 | } | 1500 | } |
| 1472 | 1501 | ||
| 1473 | LExit: | 1502 | LExit: |
| 1503 | ReleaseFileHandle(hDestinationFile); | ||
| 1504 | ReleaseFileHandle(hSourceOpenedFile); | ||
| 1505 | |||
| 1474 | return hr; | 1506 | return hr; |
| 1475 | } | 1507 | } |
| 1476 | 1508 | ||
