From 70adfc49cb05da4e7b9eb50a0c47635d2d20b366 Mon Sep 17 00:00:00 2001 From: Rob Mensching Date: Mon, 12 Apr 2021 23:52:13 -0700 Subject: Layout using the source engine handle --- src/engine/apply.cpp | 44 ++++++++++++++++++++++++++---- src/engine/engine.vcxproj | 4 +-- src/engine/packages.config | 2 +- src/stub/packages.config | 2 +- src/stub/stub.vcxproj | 4 +-- src/test/BurnUnitTest/BurnUnitTest.vcxproj | 4 +-- src/test/BurnUnitTest/packages.config | 6 ++-- 7 files changed, 49 insertions(+), 17 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( __inout DWORD64* pqwSuccessfulCachedProgress ); static HRESULT LayoutBundle( + __in HANDLE hSourceEngineFile, __in BURN_USER_EXPERIENCE* pUX, __in BURN_VARIABLES* pVariables, __in HANDLE hPipe, @@ -114,6 +115,7 @@ static HRESULT PromptForSource( ); static HRESULT CopyPayload( __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, + __in HANDLE hSourceFile, __in_z LPCWSTR wzSourcePath, __in_z LPCWSTR wzDestinationPath ); @@ -510,7 +512,7 @@ extern "C" HRESULT ApplyCache( break; case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE: - hr = LayoutBundle(pUX, pVariables, hPipe, pCacheAction->bundleLayout.sczExecutableName, pCacheAction->bundleLayout.sczLayoutDirectory, pCacheAction->bundleLayout.sczUnverifiedPath, qwSuccessfulCachedProgress, pPlan->qwCacheSizeTotal); + hr = LayoutBundle(hSourceEngineFile, pUX, pVariables, hPipe, pCacheAction->bundleLayout.sczExecutableName, pCacheAction->bundleLayout.sczLayoutDirectory, pCacheAction->bundleLayout.sczUnverifiedPath, qwSuccessfulCachedProgress, pPlan->qwCacheSizeTotal); if (SUCCEEDED(hr)) { UpdateCacheSuccessProgress(pPlan, pCacheAction, &qwSuccessfulCachedProgress); @@ -1053,6 +1055,7 @@ static void UpdateCacheSuccessProgress( } static HRESULT LayoutBundle( + __in HANDLE hSourceEngineFile, __in BURN_USER_EXPERIENCE* pUX, __in BURN_VARIABLES* pVariables, __in HANDLE hPipe, @@ -1090,7 +1093,7 @@ static HRESULT LayoutBundle( hr = PathCompare(sczBundlePath, sczDestinationPath, &nEquivalentPaths); ExitOnFailure(hr, "Failed to determine if layout bundle path was equivalent with current process path."); - if (CSTR_EQUAL == nEquivalentPaths) + if (CSTR_EQUAL == nEquivalentPaths && FileExistsEx(sczDestinationPath, NULL)) { ExitFunction1(hr = S_OK); } @@ -1112,7 +1115,7 @@ static HRESULT LayoutBundle( hr = UserExperienceOnCacheAcquireBegin(pUX, NULL, NULL, BOOTSTRAPPER_CACHE_OPERATION_COPY, sczBundlePath); ExitOnRootFailure(hr, "BA aborted cache acquire begin."); - hr = CopyPayload(&progress, sczBundlePath, wzUnverifiedPath); + hr = CopyPayload(&progress, hSourceEngineFile, sczBundlePath, wzUnverifiedPath); // Error handling happens after sending complete message to BA. UserExperienceOnCacheAcquireComplete(pUX, NULL, NULL, hr, &fRetryAcquire); @@ -1239,7 +1242,7 @@ static HRESULT AcquireContainerOrPayload( hr = UserExperienceOnCacheAcquireBegin(pUX, wzPackageOrContainerId, wzPayloadId, BOOTSTRAPPER_CACHE_OPERATION_COPY, sczSourceFullPath); ExitOnRootFailure(hr, "BA aborted cache acquire begin."); - hr = CopyPayload(&progress, sczSourceFullPath, wzDestinationPath); + hr = CopyPayload(&progress, INVALID_HANDLE_VALUE, sczSourceFullPath, wzDestinationPath); // Error handling happens after sending complete message to BA. // We successfully copied from a source location, set that as the last used source. @@ -1432,6 +1435,7 @@ LExit: static HRESULT CopyPayload( __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, + __in HANDLE hSourceFile, __in_z LPCWSTR wzSourcePath, __in_z LPCWSTR wzDestinationPath ) @@ -1440,6 +1444,8 @@ static HRESULT CopyPayload( DWORD dwFileAttributes = 0; LPCWSTR wzPackageOrContainerId = pProgress->pContainer ? pProgress->pContainer->sczId : pProgress->pPackage ? pProgress->pPackage->sczId : L""; LPCWSTR wzPayloadId = pProgress->pPayload ? pProgress->pPayload->sczKey : L""; + HANDLE hDestinationFile = INVALID_HANDLE_VALUE; + HANDLE hSourceOpenedFile = INVALID_HANDLE_VALUE; DWORD dwLogId = pProgress->pContainer ? (pProgress->pPayload ? MSG_ACQUIRE_CONTAINER_PAYLOAD : MSG_ACQUIRE_CONTAINER) : pProgress->pPackage ? MSG_ACQUIRE_PACKAGE_PAYLOAD : MSG_ACQUIRE_BUNDLE_PAYLOAD; LogId(REPORT_STANDARD, dwLogId, wzPackageOrContainerId, wzPayloadId, "copy", wzSourcePath); @@ -1457,7 +1463,30 @@ static HRESULT CopyPayload( } } - if (!::CopyFileExW(wzSourcePath, wzDestinationPath, CacheProgressRoutine, pProgress, &pProgress->fCancel, 0)) + if (INVALID_HANDLE_VALUE == hSourceFile) + { + 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); + if (INVALID_HANDLE_VALUE == hSourceOpenedFile) + { + ExitWithLastError(hr, "Failed to open source file to copy payload from: '%ls' to: %ls.", wzSourcePath, wzDestinationPath); + } + + hSourceFile = hSourceOpenedFile; + } + else + { + hr = FileSetPointer(hSourceFile, 0, NULL, FILE_BEGIN); + ExitOnRootFailure(hr, "Failed to read from start of source file to copy payload from: '%ls' to: %ls.", wzSourcePath, wzDestinationPath); + } + + 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); + if (INVALID_HANDLE_VALUE == hDestinationFile) + { + ExitWithLastError(hr, "Failed to open destination file to copy payload from: '%ls' to: %ls.", wzSourcePath, wzDestinationPath); + } + + hr = FileCopyUsingHandlesWithProgress(hSourceFile, hDestinationFile, 0, CacheProgressRoutine, pProgress); + if (FAILED(hr)) { if (pProgress->fCancel) { @@ -1466,11 +1495,14 @@ static HRESULT CopyPayload( } else { - ExitWithLastError(hr, "Failed attempt to copy payload from: '%ls' to: %ls.", wzSourcePath, wzDestinationPath); + ExitOnRootFailure(hr, "Failed attempt to copy payload from: '%ls' to: %ls.", wzSourcePath, wzDestinationPath); } } LExit: + ReleaseFileHandle(hDestinationFile); + ReleaseFileHandle(hSourceOpenedFile); + return hr; } diff --git a/src/engine/engine.vcxproj b/src/engine/engine.vcxproj index 666b3f37..a6deb18d 100644 --- a/src/engine/engine.vcxproj +++ b/src/engine/engine.vcxproj @@ -1,7 +1,7 @@ - + Debug @@ -165,7 +165,7 @@ rc.exe -fo "$(OutDir)engine.res" "$(IntDir)engine.messages.rc" This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. - + \ No newline at end of file diff --git a/src/engine/packages.config b/src/engine/packages.config index 1d09f0a7..125a949e 100644 --- a/src/engine/packages.config +++ b/src/engine/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/src/stub/packages.config b/src/stub/packages.config index eb05a40b..4f75128a 100644 --- a/src/stub/packages.config +++ b/src/stub/packages.config @@ -4,5 +4,5 @@ - + \ No newline at end of file diff --git a/src/stub/stub.vcxproj b/src/stub/stub.vcxproj index ae9c21df..2b8bd8ea 100644 --- a/src/stub/stub.vcxproj +++ b/src/stub/stub.vcxproj @@ -2,10 +2,10 @@ + - @@ -117,6 +117,6 @@ - + \ No newline at end of file diff --git a/src/test/BurnUnitTest/BurnUnitTest.vcxproj b/src/test/BurnUnitTest/BurnUnitTest.vcxproj index b57ebb16..11f96590 100644 --- a/src/test/BurnUnitTest/BurnUnitTest.vcxproj +++ b/src/test/BurnUnitTest/BurnUnitTest.vcxproj @@ -3,8 +3,8 @@ + - Debug @@ -97,6 +97,6 @@ - + \ No newline at end of file diff --git a/src/test/BurnUnitTest/packages.config b/src/test/BurnUnitTest/packages.config index a7b88aa1..21d87cf8 100644 --- a/src/test/BurnUnitTest/packages.config +++ b/src/test/BurnUnitTest/packages.config @@ -1,6 +1,9 @@  + + + @@ -8,7 +11,4 @@ - - - \ No newline at end of file -- cgit v1.2.3-55-g6feb