From d4c76dd11f5a096b4fd3ee9c5efc1f44559ac3da Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Sat, 17 Apr 2021 20:58:32 -0500 Subject: Send more progress during cache verification. Add verifyStep to OnCacheVerifyProgress. Send OnContainerOrPayloadVerify events only if file existed in cache. --- .../inc/BootstrapperApplication.h | 8 + src/engine/apply.cpp | 171 +++++++++----- src/engine/cache.cpp | 263 ++++++++++++++++----- src/engine/cache.h | 74 +++++- src/engine/elevation.cpp | 253 +++++++++++++++++++- src/engine/elevation.h | 10 +- src/engine/plan.cpp | 18 +- src/engine/userexperience.cpp | 4 +- src/engine/userexperience.h | 3 +- src/test/BurnUnitTest/CacheTest.cpp | 46 +++- src/test/BurnUnitTest/PlanTest.cpp | 10 +- 11 files changed, 712 insertions(+), 148 deletions(-) diff --git a/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h b/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h index e1920107..d8994c26 100644 --- a/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h +++ b/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h @@ -64,6 +64,13 @@ enum BOOTSTRAPPER_CACHE_OPERATION BOOTSTRAPPER_CACHE_OPERATION_EXTRACT, }; +enum BOOTSTRAPPER_CACHE_VERIFY_STEP +{ + BOOTSTRAPPER_CACHE_VERIFY_STEP_STAGE, + BOOTSTRAPPER_CACHE_VERIFY_STEP_HASH, + BOOTSTRAPPER_CACHE_VERIFY_STEP_FINALIZE, +}; + enum BOOTSTRAPPER_APPLY_RESTART { BOOTSTRAPPER_APPLY_RESTART_NONE, @@ -553,6 +560,7 @@ struct BA_ONCACHEVERIFYPROGRESS_ARGS DWORD64 dw64Progress; DWORD64 dw64Total; DWORD dwOverallPercentage; + BOOTSTRAPPER_CACHE_VERIFY_STEP verifyStep; }; struct BA_ONCACHEVERIFYPROGRESS_RESULTS diff --git a/src/engine/apply.cpp b/src/engine/apply.cpp index 304c88f4..6f6225b4 100644 --- a/src/engine/apply.cpp +++ b/src/engine/apply.cpp @@ -14,9 +14,12 @@ const DWORD BURN_CACHE_MAX_RECOMMENDED_VERIFY_TRYAGAIN_ATTEMPTS = 2; enum BURN_CACHE_PROGRESS_TYPE { BURN_CACHE_PROGRESS_TYPE_ACQUIRE, - BURN_CACHE_PROGRESS_TYPE_VERIFY, BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY, BURN_CACHE_PROGRESS_TYPE_EXTRACT, + BURN_CACHE_PROGRESS_TYPE_FINALIZE, + BURN_CACHE_PROGRESS_TYPE_HASH, + BURN_CACHE_PROGRESS_TYPE_PAYLOAD_VERIFY, + BURN_CACHE_PROGRESS_TYPE_STAGE, }; // structs @@ -151,6 +154,10 @@ static HRESULT DownloadPayload( __in BURN_CACHE_PROGRESS_CONTEXT* pProgress, __in_z LPCWSTR wzDestinationPath ); +static HRESULT CALLBACK CacheMessageHandler( + __in BURN_CACHE_MESSAGE* pMessage, + __in LPVOID pvContext + ); static HRESULT CompleteCacheProgress( __in BURN_CACHE_PROGRESS_CONTEXT* pContext, __in DWORD64 qwFileSize @@ -993,7 +1000,8 @@ static HRESULT ApplyLayoutContainer( } ++cTryAgainAttempts; - pContext->qwSuccessfulCacheProgress -= pContainer->qwFileSize; + pContext->qwSuccessfulCacheProgress -= pContainer->qwCommittedCacheProgress; + pContainer->qwCommittedCacheProgress = 0; ReleaseNullStr(pContext->sczLastUsedFolderCandidate); LogErrorId(hr, MSG_APPLY_RETRYING_CONTAINER, pContainer->sczId, NULL, NULL); } @@ -1075,49 +1083,25 @@ static HRESULT ApplyCacheVerifyContainerOrPayload( HRESULT hr = S_OK; BURN_CACHE_PROGRESS_CONTEXT progress = { }; - LPCWSTR wzPackageOrContainerId = pContainer ? pContainer->sczId : pPackage ? pPackage->sczId : NULL; - LPCWSTR wzPayloadId = pPayloadGroupItem ? pPayloadGroupItem->pPayload->sczKey : NULL; - DWORD64 qwFileSize = pContainer ? pContainer->qwFileSize : pPayloadGroupItem->pPayload->qwFileSize; progress.pCacheContext = pContext; progress.pContainer = pContainer; progress.pPackage = pPackage; progress.pPayloadGroupItem = pPayloadGroupItem; - progress.type = BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY; - - hr = UserExperienceOnCacheContainerOrPayloadVerifyBegin(pContext->pUX, wzPackageOrContainerId, wzPayloadId); - ExitOnRootFailure(hr, "BA aborted cache container or payload verify begin."); if (pContainer) { - hr = CacheVerifyContainer(pContainer, pContext->wzLayoutDirectory); + hr = CacheVerifyContainer(pContainer, pContext->wzLayoutDirectory, CacheMessageHandler, CacheProgressRoutine, &progress); } else if (!pContext->wzLayoutDirectory && INVALID_HANDLE_VALUE != pContext->hPipe) { - hr = ElevationCacheVerifyPayload(pContext->hPipe, pPackage, pPayloadGroupItem->pPayload); + hr = ElevationCacheVerifyPayload(pContext->hPipe, pPackage, pPayloadGroupItem->pPayload, CacheMessageHandler, CacheProgressRoutine, &progress); } else { - hr = CacheVerifyPayload(pPayloadGroupItem->pPayload, pContext->wzLayoutDirectory ? pContext->wzLayoutDirectory : pPackage->sczCacheFolder); - } - - // This was best effort to avoid acquiring the container or payload. - if (FAILED(hr)) - { - ExitFunction(); + hr = CacheVerifyPayload(pPayloadGroupItem->pPayload, pContext->wzLayoutDirectory ? pContext->wzLayoutDirectory : pPackage->sczCacheFolder, CacheMessageHandler, CacheProgressRoutine, &progress); } - pContext->qwSuccessfulCacheProgress += qwFileSize; - if (pPayloadGroupItem) - { - pPayloadGroupItem->qwCommittedCacheProgress += qwFileSize; - } - - hr = CompleteCacheProgress(&progress, qwFileSize); - -LExit: - UserExperienceOnCacheContainerOrPayloadVerifyComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr); - return hr; } @@ -1252,8 +1236,6 @@ static HRESULT LayoutBundle( ExitOnRootFailure(hr, "BA aborted cache payload verify begin."); } - pContext->qwSuccessfulCacheProgress += qwBundleSize; - progress.type = BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY; hr = CompleteCacheProgress(&progress, qwBundleSize); @@ -1306,8 +1288,6 @@ static HRESULT LayoutBundle( break; } - progress.type = BURN_CACHE_PROGRESS_TYPE_VERIFY; - do { fCanceledBegin = FALSE; @@ -1320,12 +1300,7 @@ static HRESULT LayoutBundle( } else { - hr = CacheLayoutBundle(wzExecutableName, pContext->wzLayoutDirectory, wzUnverifiedPath); - - if (SUCCEEDED(hr)) - { - hr = CompleteCacheProgress(&progress, qwBundleSize); - } + hr = CacheLayoutBundle(wzExecutableName, pContext->wzLayoutDirectory, wzUnverifiedPath, qwBundleSize, CacheMessageHandler, CacheProgressRoutine, &progress); } BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE; @@ -1346,7 +1321,7 @@ static HRESULT LayoutBundle( if (fRetry) { - pContext->qwSuccessfulCacheProgress -= qwBundleSize; + pContext->qwSuccessfulCacheProgress -= qwBundleSize; // Acquire } } while (fRetry); LogExitOnFailure(hr, MSG_FAILED_LAYOUT_BUNDLE, "Failed to layout bundle: %ls to layout directory: %ls", sczBundlePath, pContext->wzLayoutDirectory); @@ -1559,7 +1534,6 @@ static HRESULT LayoutOrCacheContainerOrPayload( *pfRetry = FALSE; progress.pCacheContext = pContext; - progress.type = BURN_CACHE_PROGRESS_TYPE_VERIFY; progress.pContainer = pContainer; progress.pPackage = pPackage; progress.pPayloadGroupItem = pPayloadGroupItem; @@ -1580,28 +1554,23 @@ static HRESULT LayoutOrCacheContainerOrPayload( { if (pContainer) { - hr = CacheLayoutContainer(pContainer, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove); + hr = CacheLayoutContainer(pContainer, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove, CacheMessageHandler, CacheProgressRoutine, &progress); } else { - hr = CacheLayoutPayload(pPayload, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove); + hr = CacheLayoutPayload(pPayload, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove, CacheMessageHandler, CacheProgressRoutine, &progress); } } else if (INVALID_HANDLE_VALUE != pContext->hPipe) // pass the decision off to the elevated process. { - hr = ElevationCacheCompletePayload(pContext->hPipe, pPackage, pPayload, wzUnverifiedPath, fMove); + hr = ElevationCacheCompletePayload(pContext->hPipe, pPackage, pPayload, wzUnverifiedPath, fMove, CacheMessageHandler, CacheProgressRoutine, &progress); } else // complete the payload. { - hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, wzUnverifiedPath, fMove); + hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, wzUnverifiedPath, fMove, CacheMessageHandler, CacheProgressRoutine, &progress); } } - if (SUCCEEDED(hr)) - { - hr = CompleteCacheProgress(&progress, pContainer ? pContainer->qwFileSize : pPayload->qwFileSize); - } - if (SUCCEEDED(hr) && fCanAffectRegistration) { pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT; @@ -1820,6 +1789,54 @@ LExit: return hr; } +static HRESULT CALLBACK CacheMessageHandler( + __in BURN_CACHE_MESSAGE* pMessage, + __in LPVOID pvContext + ) +{ + HRESULT hr = S_OK; + BURN_CACHE_PROGRESS_CONTEXT* pProgress = static_cast(pvContext); + LPCWSTR wzPackageOrContainerId = pProgress->pContainer ? pProgress->pContainer->sczId : pProgress->pPackage ? pProgress->pPackage->sczId : NULL; + LPCWSTR wzPayloadId = pProgress->pPayloadGroupItem ? pProgress->pPayloadGroupItem->pPayload->sczKey : pProgress->pPayload ? pProgress->pPayload->sczKey : NULL; + + switch (pMessage->type) + { + case BURN_CACHE_MESSAGE_BEGIN: + switch (pMessage->begin.cacheStep) + { + case BURN_CACHE_STEP_HASH_TO_SKIP_ACQUIRE: + pProgress->type = BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY; + hr = UserExperienceOnCacheContainerOrPayloadVerifyBegin(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId); + break; + case BURN_CACHE_STEP_HASH_TO_SKIP_VERIFY: + pProgress->type = BURN_CACHE_PROGRESS_TYPE_PAYLOAD_VERIFY; + break; + case BURN_CACHE_STEP_STAGE: + pProgress->type = BURN_CACHE_PROGRESS_TYPE_STAGE; + break; + case BURN_CACHE_STEP_HASH: + pProgress->type = BURN_CACHE_PROGRESS_TYPE_HASH; + break; + case BURN_CACHE_STEP_FINALIZE: + pProgress->type = BURN_CACHE_PROGRESS_TYPE_FINALIZE; + break; + } + break; + case BURN_CACHE_MESSAGE_SUCCESS: + hr = CompleteCacheProgress(pProgress, pMessage->success.qwFileSize); + break; + case BURN_CACHE_MESSAGE_COMPLETE: + switch (pProgress->type) + { + case BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY: + hr = UserExperienceOnCacheContainerOrPayloadVerifyComplete(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, hr); + break; + } + } + + return hr; +} + static HRESULT CompleteCacheProgress( __in BURN_CACHE_PROGRESS_CONTEXT* pContext, __in DWORD64 qwFileSize @@ -1829,9 +1846,29 @@ static HRESULT CompleteCacheProgress( LARGE_INTEGER liContainerOrPayloadSize = { }; LARGE_INTEGER liZero = { }; DWORD dwResult = 0; + DWORD64 qwCommitSize = 0; liContainerOrPayloadSize.QuadPart = qwFileSize; + // Need to commit the steps that were skipped. + if (BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY == pContext->type || BURN_CACHE_PROGRESS_TYPE_PAYLOAD_VERIFY == pContext->type) + { + Assert(!pContext->pPayload); + + qwCommitSize = qwFileSize * (pContext->pCacheContext->wzLayoutDirectory ? 2 : 3); // Acquire (+ Stage) + Hash + Finalize - 1 (that's added later) + + pContext->pCacheContext->qwSuccessfulCacheProgress += qwCommitSize; + + if (pContext->pContainer) + { + pContext->pContainer->qwCommittedCacheProgress += qwCommitSize; + } + else if (pContext->pPayloadGroupItem) + { + pContext->pPayloadGroupItem->qwCommittedCacheProgress += qwCommitSize; + } + } + dwResult = CacheProgressRoutine(liContainerOrPayloadSize, liContainerOrPayloadSize, liZero, liZero, 0, 0, INVALID_HANDLE_VALUE, INVALID_HANDLE_VALUE, pContext); if (PROGRESS_CONTINUE == dwResult) @@ -1851,7 +1888,7 @@ static HRESULT CompleteCacheProgress( pContext->pPayloadGroupItem->qwCommittedCacheProgress += qwFileSize; } - if (BURN_CACHE_PROGRESS_TYPE_VERIFY == pContext->type && pContext->pCacheContext->sczLastUsedFolderCandidate) + if (BURN_CACHE_PROGRESS_TYPE_FINALIZE == pContext->type && pContext->pCacheContext->sczLastUsedFolderCandidate) { // We successfully copied from a source location, set that as the last used source. CacheSetLastUsedSource(pContext->pCacheContext->pVariables, pContext->pCacheContext->sczLastUsedFolderCandidate, pContext->pContainer ? pContext->pContainer->sczFilePath : pContext->pPayloadGroupItem->pPayload->sczFilePath); @@ -1867,6 +1904,20 @@ static HRESULT CompleteCacheProgress( { hr = pContext->hrError; } + + if (qwCommitSize) + { + pContext->pCacheContext->qwSuccessfulCacheProgress -= qwCommitSize; + + if (pContext->pContainer) + { + pContext->pContainer->qwCommittedCacheProgress -= qwCommitSize; + } + else if (pContext->pPayloadGroupItem) + { + pContext->pPayloadGroupItem->qwCommittedCacheProgress -= qwCommitSize; + } + } } return hr; @@ -1903,9 +1954,21 @@ static DWORD CALLBACK CacheProgressRoutine( hr = UserExperienceOnCacheAcquireProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage); ExitOnRootFailure(hr, "BA aborted acquire of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId); break; - case BURN_CACHE_PROGRESS_TYPE_VERIFY: - hr = UserExperienceOnCacheVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage); - ExitOnRootFailure(hr, "BA aborted verify of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId); + case BURN_CACHE_PROGRESS_TYPE_PAYLOAD_VERIFY: + hr = UserExperienceOnCacheVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage, BOOTSTRAPPER_CACHE_VERIFY_STEP_HASH); + ExitOnRootFailure(hr, "BA aborted payload verify step during verify of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId); + break; + case BURN_CACHE_PROGRESS_TYPE_STAGE: + hr = UserExperienceOnCacheVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage, BOOTSTRAPPER_CACHE_VERIFY_STEP_STAGE); + ExitOnRootFailure(hr, "BA aborted stage step during verify of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId); + break; + case BURN_CACHE_PROGRESS_TYPE_HASH: + hr = UserExperienceOnCacheVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage, BOOTSTRAPPER_CACHE_VERIFY_STEP_HASH); + ExitOnRootFailure(hr, "BA aborted hash step during verify of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId); + break; + case BURN_CACHE_PROGRESS_TYPE_FINALIZE: + hr = UserExperienceOnCacheVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage, BOOTSTRAPPER_CACHE_VERIFY_STEP_FINALIZE); + ExitOnRootFailure(hr, "BA aborted finalize step during verify of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId); break; case BURN_CACHE_PROGRESS_TYPE_CONTAINER_OR_PAYLOAD_VERIFY: hr = UserExperienceOnCacheContainerOrPayloadVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage); diff --git a/src/engine/cache.cpp b/src/engine/cache.cpp index 9aa94d1d..16f2c1e5 100644 --- a/src/engine/cache.cpp +++ b/src/engine/cache.cpp @@ -44,28 +44,47 @@ static HRESULT VerifyThenTransferContainer( __in BURN_CONTAINER* pContainer, __in_z LPCWSTR wzCachedPath, __in_z LPCWSTR wzUnverifiedContainerPath, - __in BOOL fMove + __in BOOL fMove, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ); static HRESULT VerifyThenTransferPayload( __in BURN_PAYLOAD* pPayload, __in_z LPCWSTR wzCachedPath, __in_z LPCWSTR wzUnverifiedPayloadPath, - __in BOOL fMove + __in BOOL fMove, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ); -static HRESULT TransferWorkingPathToUnverifiedPath( - __in_z LPCWSTR wzWorkingPath, - __in_z LPCWSTR wzUnverifiedPayloadPath, - __in BOOL fMove +static HRESULT CacheTransferFileWithRetry( + __in_z LPCWSTR wzSourcePath, + __in_z LPCWSTR wzDestinationPath, + __in BOOL fMove, + __in BURN_CACHE_STEP cacheStep, + __in DWORD64 qwFileSize, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ); static HRESULT VerifyFileAgainstContainer( __in BURN_CONTAINER* pContainer, __in_z LPCWSTR wzVerifyPath, - __in BOOL fAlreadyCached + __in BOOL fAlreadyCached, + __in BURN_CACHE_STEP cacheStep, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ); static HRESULT VerifyFileAgainstPayload( __in BURN_PAYLOAD* pPayload, __in_z LPCWSTR wzVerifyPath, - __in BOOL fAlreadyCached + __in BOOL fAlreadyCached, + __in BURN_CACHE_STEP cacheStep, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ); static HRESULT ResetPathPermissions( __in BOOL fPerMachine, @@ -99,7 +118,26 @@ static HRESULT VerifyHash( __in DWORD cbHash, __in DWORD64 qwFileSize, __in_z LPCWSTR wzUnverifiedPayloadPath, - __in HANDLE hFile + __in HANDLE hFile, + __in BURN_CACHE_STEP cacheStep, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext + ); +static HRESULT SendCacheBeginMessage( + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPVOID pContext, + __in BURN_CACHE_STEP cacheStep + ); +static HRESULT SendCacheSuccessMessage( + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPVOID pContext, + __in DWORD64 qwFileSize + ); +static HRESULT SendCacheCompleteMessage( + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPVOID pContext, + __in HRESULT hrStatus ); @@ -754,7 +792,11 @@ LExit: extern "C" HRESULT CacheLayoutBundle( __in_z LPCWSTR wzExecutableName, __in_z LPCWSTR wzLayoutDirectory, - __in_z LPCWSTR wzSourceBundlePath + __in_z LPCWSTR wzSourceBundlePath, + __in DWORD64 qwBundleSize, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ) { HRESULT hr = S_OK; @@ -765,7 +807,7 @@ extern "C" HRESULT CacheLayoutBundle( LogStringLine(REPORT_STANDARD, "Layout bundle from: '%ls' to: '%ls'", wzSourceBundlePath, sczTargetPath); - hr = FileEnsureMoveWithRetry(wzSourceBundlePath, sczTargetPath, TRUE, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT); + hr = CacheTransferFileWithRetry(wzSourceBundlePath, sczTargetPath, TRUE, BURN_CACHE_STEP_FINALIZE, qwBundleSize, pfnCacheMessageHandler, pfnProgress, pContext); ExitOnFailure(hr, "Failed to layout bundle from: '%ls' to '%ls'", wzSourceBundlePath, sczTargetPath); LExit: @@ -838,7 +880,10 @@ extern "C" HRESULT CacheLayoutContainer( __in BURN_CONTAINER* pContainer, __in_z_opt LPCWSTR wzLayoutDirectory, __in_z LPCWSTR wzUnverifiedContainerPath, - __in BOOL fMove + __in BOOL fMove, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ) { HRESULT hr = S_OK; @@ -847,7 +892,7 @@ extern "C" HRESULT CacheLayoutContainer( hr = PathConcat(wzLayoutDirectory, pContainer->sczFilePath, &sczCachedPath); ExitOnFailure(hr, "Failed to concat complete cached path."); - hr = VerifyThenTransferContainer(pContainer, sczCachedPath, wzUnverifiedContainerPath, fMove); + hr = VerifyThenTransferContainer(pContainer, sczCachedPath, wzUnverifiedContainerPath, fMove, pfnCacheMessageHandler, pfnProgress, pContext); ExitOnFailure(hr, "Failed to layout container from cached path: %ls", sczCachedPath); LExit: @@ -860,7 +905,10 @@ extern "C" HRESULT CacheLayoutPayload( __in BURN_PAYLOAD* pPayload, __in_z_opt LPCWSTR wzLayoutDirectory, __in_z LPCWSTR wzUnverifiedPayloadPath, - __in BOOL fMove + __in BOOL fMove, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ) { HRESULT hr = S_OK; @@ -869,7 +917,7 @@ extern "C" HRESULT CacheLayoutPayload( hr = PathConcat(wzLayoutDirectory, pPayload->sczFilePath, &sczCachedPath); ExitOnFailure(hr, "Failed to concat complete cached path."); - hr = VerifyThenTransferPayload(pPayload, sczCachedPath, wzUnverifiedPayloadPath, fMove); + hr = VerifyThenTransferPayload(pPayload, sczCachedPath, wzUnverifiedPayloadPath, fMove, pfnCacheMessageHandler, pfnProgress, pContext); ExitOnFailure(hr, "Failed to layout payload from cached payload: %ls", sczCachedPath); LExit: @@ -883,7 +931,10 @@ extern "C" HRESULT CacheCompletePayload( __in BURN_PAYLOAD* pPayload, __in_z LPCWSTR wzCacheId, __in_z LPCWSTR wzWorkingPayloadPath, - __in BOOL fMove + __in BOOL fMove, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ) { HRESULT hr = S_OK; @@ -898,7 +949,7 @@ extern "C" HRESULT CacheCompletePayload( ExitOnFailure(hr, "Failed to concat complete cached path."); // If the cached file matches what we expected, we're good. - hr = VerifyFileAgainstPayload(pPayload, sczCachedPath, TRUE); + hr = VerifyFileAgainstPayload(pPayload, sczCachedPath, TRUE, BURN_CACHE_STEP_HASH_TO_SKIP_VERIFY, pfnCacheMessageHandler, pfnProgress, pContext); if (SUCCEEDED(hr)) { ExitFunction(); @@ -910,10 +961,21 @@ extern "C" HRESULT CacheCompletePayload( // If the working path exists, let's get it into the unverified path so we can reset the ACLs and verify the file. if (FileExistsEx(wzWorkingPayloadPath, NULL)) { - hr = TransferWorkingPathToUnverifiedPath(wzWorkingPayloadPath, sczUnverifiedPayloadPath, fMove); + hr = CacheTransferFileWithRetry(wzWorkingPayloadPath, sczUnverifiedPayloadPath, fMove, BURN_CACHE_STEP_STAGE, pPayload->qwFileSize, pfnCacheMessageHandler, pfnProgress, pContext); ExitOnFailure(hr, "Failed to transfer working path to unverified path for payload: %ls.", pPayload->sczKey); } - else if (!FileExistsEx(sczUnverifiedPayloadPath, NULL)) // if the working path and unverified path do not exist, nothing we can do. + else if (FileExistsEx(sczUnverifiedPayloadPath, NULL)) + { + // Make sure the staging progress is sent even though there was nothing to do. + hr = SendCacheBeginMessage(pfnCacheMessageHandler, pContext, BURN_CACHE_STEP_STAGE); + if (SUCCEEDED(hr)) + { + hr = SendCacheSuccessMessage(pfnCacheMessageHandler, pContext, pPayload->qwFileSize); + } + SendCacheCompleteMessage(pfnCacheMessageHandler, pContext, hr); + ExitOnFailure(hr, "Aborted transferring working path to unverified path for payload: %ls.", pPayload->sczKey); + } + else // if the working path and unverified path do not exist, nothing we can do. { hr = E_FILENOTFOUND; ExitOnFailure(hr, "Failed to find payload: %ls in working path: %ls and unverified path: %ls", pPayload->sczKey, wzWorkingPayloadPath, sczUnverifiedPayloadPath); @@ -922,12 +984,12 @@ extern "C" HRESULT CacheCompletePayload( hr = ResetPathPermissions(fPerMachine, sczUnverifiedPayloadPath); ExitOnFailure(hr, "Failed to reset permissions on unverified cached payload: %ls", pPayload->sczKey); - hr = VerifyFileAgainstPayload(pPayload, sczUnverifiedPayloadPath, FALSE); + hr = VerifyFileAgainstPayload(pPayload, sczUnverifiedPayloadPath, FALSE, BURN_CACHE_STEP_HASH, pfnCacheMessageHandler, pfnProgress, pContext); LogExitOnFailure(hr, MSG_FAILED_VERIFY_PAYLOAD, "Failed to verify payload: %ls at path: %ls", pPayload->sczKey, sczUnverifiedPayloadPath, NULL); LogId(REPORT_STANDARD, MSG_VERIFIED_ACQUIRED_PAYLOAD, pPayload->sczKey, sczUnverifiedPayloadPath, fMove ? "moving" : "copying", sczCachedPath); - hr = FileEnsureMoveWithRetry(sczUnverifiedPayloadPath, sczCachedPath, TRUE, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT); + hr = CacheTransferFileWithRetry(sczUnverifiedPayloadPath, sczCachedPath, TRUE, BURN_CACHE_STEP_FINALIZE, pPayload->qwFileSize, pfnCacheMessageHandler, pfnProgress, pContext); ExitOnFailure(hr, "Failed to move verified file to complete payload path: %ls", sczCachedPath); ::DecryptFileW(sczCachedPath, 0); // Let's try to make sure it's not encrypted. @@ -942,7 +1004,10 @@ LExit: extern "C" HRESULT CacheVerifyContainer( __in BURN_CONTAINER* pContainer, - __in_z LPCWSTR wzCachedDirectory + __in_z LPCWSTR wzCachedDirectory, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ) { HRESULT hr = S_OK; @@ -951,7 +1016,7 @@ extern "C" HRESULT CacheVerifyContainer( hr = PathConcat(wzCachedDirectory, pContainer->sczFilePath, &sczCachedPath); ExitOnFailure(hr, "Failed to concat complete cached path."); - hr = VerifyFileAgainstContainer(pContainer, sczCachedPath, TRUE); + hr = VerifyFileAgainstContainer(pContainer, sczCachedPath, TRUE, BURN_CACHE_STEP_HASH_TO_SKIP_ACQUIRE, pfnCacheMessageHandler, pfnProgress, pContext); LExit: ReleaseStr(sczCachedPath); @@ -961,7 +1026,10 @@ LExit: extern "C" HRESULT CacheVerifyPayload( __in BURN_PAYLOAD* pPayload, - __in_z LPCWSTR wzCachedDirectory + __in_z LPCWSTR wzCachedDirectory, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ) { HRESULT hr = S_OK; @@ -970,7 +1038,7 @@ extern "C" HRESULT CacheVerifyPayload( hr = PathConcat(wzCachedDirectory, pPayload->sczFilePath, &sczCachedPath); ExitOnFailure(hr, "Failed to concat complete cached path."); - hr = VerifyFileAgainstPayload(pPayload, sczCachedPath, TRUE); + hr = VerifyFileAgainstPayload(pPayload, sczCachedPath, TRUE, BURN_CACHE_STEP_HASH_TO_SKIP_ACQUIRE, pfnCacheMessageHandler, pfnProgress, pContext); LExit: ReleaseStr(sczCachedPath); @@ -1342,7 +1410,10 @@ static HRESULT VerifyThenTransferContainer( __in BURN_CONTAINER* pContainer, __in_z LPCWSTR wzCachedPath, __in_z LPCWSTR wzUnverifiedContainerPath, - __in BOOL fMove + __in BOOL fMove, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ) { HRESULT hr = S_OK; @@ -1358,22 +1429,13 @@ static HRESULT VerifyThenTransferContainer( // Container should have a hash we can use to verify with. if (pContainer->pbHash) { - hr = VerifyHash(pContainer->pbHash, pContainer->cbHash, pContainer->qwFileSize, wzUnverifiedContainerPath, hFile); + hr = VerifyHash(pContainer->pbHash, pContainer->cbHash, pContainer->qwFileSize, wzUnverifiedContainerPath, hFile, BURN_CACHE_STEP_HASH, pfnCacheMessageHandler, pfnProgress, pContext); ExitOnFailure(hr, "Failed to verify container hash: %ls", wzCachedPath); } LogStringLine(REPORT_STANDARD, "%ls container from working path '%ls' to path '%ls'", fMove ? L"Moving" : L"Copying", wzUnverifiedContainerPath, wzCachedPath); - if (fMove) - { - hr = FileEnsureMoveWithRetry(wzUnverifiedContainerPath, wzCachedPath, TRUE, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT); - ExitOnFailure(hr, "Failed to move %ls to %ls", wzUnverifiedContainerPath, wzCachedPath); - } - else - { - hr = FileEnsureCopyWithRetry(wzUnverifiedContainerPath, wzCachedPath, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT); - ExitOnFailure(hr, "Failed to copy %ls to %ls", wzUnverifiedContainerPath, wzCachedPath); - } + hr = CacheTransferFileWithRetry(wzUnverifiedContainerPath, wzCachedPath, fMove, BURN_CACHE_STEP_FINALIZE, pContainer->qwFileSize, pfnCacheMessageHandler, pfnProgress, pContext); LExit: ReleaseFileHandle(hFile); @@ -1385,7 +1447,10 @@ static HRESULT VerifyThenTransferPayload( __in BURN_PAYLOAD* pPayload, __in_z LPCWSTR wzCachedPath, __in_z LPCWSTR wzUnverifiedPayloadPath, - __in BOOL fMove + __in BOOL fMove, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ) { HRESULT hr = S_OK; @@ -1400,22 +1465,13 @@ static HRESULT VerifyThenTransferPayload( if (pPayload->pbHash) // the payload should have a hash we can use to verify it. { - hr = VerifyHash(pPayload->pbHash, pPayload->cbHash, pPayload->qwFileSize, wzUnverifiedPayloadPath, hFile); + hr = VerifyHash(pPayload->pbHash, pPayload->cbHash, pPayload->qwFileSize, wzUnverifiedPayloadPath, hFile, BURN_CACHE_STEP_HASH, pfnCacheMessageHandler, pfnProgress, pContext); ExitOnFailure(hr, "Failed to verify payload hash: %ls", wzCachedPath); } LogStringLine(REPORT_STANDARD, "%ls payload from working path '%ls' to path '%ls'", fMove ? L"Moving" : L"Copying", wzUnverifiedPayloadPath, wzCachedPath); - if (fMove) - { - hr = FileEnsureMoveWithRetry(wzUnverifiedPayloadPath, wzCachedPath, TRUE, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT); - ExitOnFailure(hr, "Failed to move %ls to %ls", wzUnverifiedPayloadPath, wzCachedPath); - } - else - { - hr = FileEnsureCopyWithRetry(wzUnverifiedPayloadPath, wzCachedPath, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT); - ExitOnFailure(hr, "Failed to copy %ls to %ls", wzUnverifiedPayloadPath, wzCachedPath); - } + hr = CacheTransferFileWithRetry(wzUnverifiedPayloadPath, wzCachedPath, fMove, BURN_CACHE_STEP_FINALIZE, pPayload->qwFileSize, pfnCacheMessageHandler, pfnProgress, pContext); LExit: ReleaseFileHandle(hFile); @@ -1423,33 +1479,50 @@ LExit: return hr; } -static HRESULT TransferWorkingPathToUnverifiedPath( - __in_z LPCWSTR wzWorkingPath, - __in_z LPCWSTR wzUnverifiedPayloadPath, - __in BOOL fMove +static HRESULT CacheTransferFileWithRetry( + __in_z LPCWSTR wzSourcePath, + __in_z LPCWSTR wzDestinationPath, + __in BOOL fMove, + __in BURN_CACHE_STEP cacheStep, + __in DWORD64 qwFileSize, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE /*pfnProgress*/, + __in LPVOID pContext ) { HRESULT hr = S_OK; + hr = SendCacheBeginMessage(pfnCacheMessageHandler, pContext, cacheStep); + ExitOnFailure(hr, "Aborted cache file transfer begin."); + + // TODO: send progress during the file transfer. if (fMove) { - hr = FileEnsureMoveWithRetry(wzWorkingPath, wzUnverifiedPayloadPath, TRUE, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT); - ExitOnFailure(hr, "Failed to move %ls to %ls", wzWorkingPath, wzUnverifiedPayloadPath); + hr = FileEnsureMoveWithRetry(wzSourcePath, wzDestinationPath, TRUE, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT); + ExitOnFailure(hr, "Failed to move %ls to %ls", wzSourcePath, wzDestinationPath); } else { - hr = FileEnsureCopyWithRetry(wzWorkingPath, wzUnverifiedPayloadPath, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT); - ExitOnFailure(hr, "Failed to copy %ls to %ls", wzWorkingPath, wzUnverifiedPayloadPath); + hr = FileEnsureCopyWithRetry(wzSourcePath, wzDestinationPath, TRUE, FILE_OPERATION_RETRY_COUNT, FILE_OPERATION_RETRY_WAIT); + ExitOnFailure(hr, "Failed to copy %ls to %ls", wzSourcePath, wzDestinationPath); } + hr = SendCacheSuccessMessage(pfnCacheMessageHandler, pContext, qwFileSize); + LExit: + SendCacheCompleteMessage(pfnCacheMessageHandler, pContext, hr); + return hr; } static HRESULT VerifyFileAgainstContainer( __in BURN_CONTAINER* pContainer, __in_z LPCWSTR wzVerifyPath, - __in BOOL fAlreadyCached + __in BOOL fAlreadyCached, + __in BURN_CACHE_STEP cacheStep, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ) { HRESULT hr = S_OK; @@ -1469,7 +1542,7 @@ static HRESULT VerifyFileAgainstContainer( if (pContainer->pbHash) // the container should have a hash we can use to verify it. { - hr = VerifyHash(pContainer->pbHash, pContainer->cbHash, pContainer->qwFileSize, wzVerifyPath, hFile); + hr = VerifyHash(pContainer->pbHash, pContainer->cbHash, pContainer->qwFileSize, wzVerifyPath, hFile, cacheStep, pfnCacheMessageHandler, pfnProgress, pContext); ExitOnFailure(hr, "Failed to verify hash of container: %ls", pContainer->sczId); } @@ -1498,7 +1571,11 @@ LExit: static HRESULT VerifyFileAgainstPayload( __in BURN_PAYLOAD* pPayload, __in_z LPCWSTR wzVerifyPath, - __in BOOL fAlreadyCached + __in BOOL fAlreadyCached, + __in BURN_CACHE_STEP cacheStep, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ) { HRESULT hr = S_OK; @@ -1518,7 +1595,7 @@ static HRESULT VerifyFileAgainstPayload( if (pPayload->pbHash) // the payload should have a hash we can use to verify it. { - hr = VerifyHash(pPayload->pbHash, pPayload->cbHash, pPayload->qwFileSize, wzVerifyPath, hFile); + hr = VerifyHash(pPayload->pbHash, pPayload->cbHash, pPayload->qwFileSize, wzVerifyPath, hFile, cacheStep, pfnCacheMessageHandler, pfnProgress, pContext); ExitOnFailure(hr, "Failed to verify hash of payload: %ls", pPayload->sczKey); } @@ -1881,7 +1958,11 @@ static HRESULT VerifyHash( __in DWORD cbHash, __in DWORD64 qwFileSize, __in_z LPCWSTR wzUnverifiedPayloadPath, - __in HANDLE hFile + __in HANDLE hFile, + __in BURN_CACHE_STEP cacheStep, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE /*pfnProgress*/, + __in LPVOID pContext ) { UNREFERENCED_PARAMETER(wzUnverifiedPayloadPath); @@ -1893,6 +1974,9 @@ static HRESULT VerifyHash( LPWSTR pszExpected = NULL; LPWSTR pszActual = NULL; + hr = SendCacheBeginMessage(pfnCacheMessageHandler, pContext, cacheStep); + ExitOnFailure(hr, "Aborted cache verify hash begin."); + hr = FileSizeByHandle(hFile, &llSize); ExitOnFailure(hr, "Failed to get file size for path: %ls", wzUnverifiedPayloadPath); @@ -1922,9 +2006,64 @@ static HRESULT VerifyHash( } } + hr = SendCacheSuccessMessage(pfnCacheMessageHandler, pContext, qwFileSize); + LExit: + SendCacheCompleteMessage(pfnCacheMessageHandler, pContext, hr); + ReleaseStr(pszActual); ReleaseStr(pszExpected); return hr; } + +static HRESULT SendCacheBeginMessage( + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPVOID pContext, + __in BURN_CACHE_STEP cacheStep + ) +{ + HRESULT hr = S_OK; + BURN_CACHE_MESSAGE message = { }; + + message.type = BURN_CACHE_MESSAGE_BEGIN; + message.begin.cacheStep = cacheStep; + + hr = pfnCacheMessageHandler(&message, pContext); + + return hr; +} + +static HRESULT SendCacheSuccessMessage( + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPVOID pContext, + __in DWORD64 qwFileSize + ) +{ + HRESULT hr = S_OK; + BURN_CACHE_MESSAGE message = { }; + + message.type = BURN_CACHE_MESSAGE_SUCCESS; + message.success.qwFileSize = qwFileSize; + + hr = pfnCacheMessageHandler(&message, pContext); + + return hr; +} + +static HRESULT SendCacheCompleteMessage( + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPVOID pContext, + __in HRESULT hrStatus + ) +{ + HRESULT hr = S_OK; + BURN_CACHE_MESSAGE message = { }; + + message.type = BURN_CACHE_MESSAGE_COMPLETE; + message.complete.hrStatus = hrStatus; + + hr = pfnCacheMessageHandler(&message, pContext); + + return hr; +} diff --git a/src/engine/cache.h b/src/engine/cache.h index cf062a85..cd964649 100644 --- a/src/engine/cache.h +++ b/src/engine/cache.h @@ -7,7 +7,48 @@ extern "C" { #endif -// structs + +enum BURN_CACHE_MESSAGE_TYPE +{ + BURN_CACHE_MESSAGE_BEGIN, + BURN_CACHE_MESSAGE_SUCCESS, + BURN_CACHE_MESSAGE_COMPLETE, +}; + +enum BURN_CACHE_STEP +{ + BURN_CACHE_STEP_HASH_TO_SKIP_ACQUIRE, + BURN_CACHE_STEP_HASH_TO_SKIP_VERIFY, + BURN_CACHE_STEP_STAGE, + BURN_CACHE_STEP_HASH, + BURN_CACHE_STEP_FINALIZE, +}; + +typedef struct _BURN_CACHE_MESSAGE +{ + BURN_CACHE_MESSAGE_TYPE type; + + union + { + struct + { + BURN_CACHE_STEP cacheStep; + } begin; + struct + { + DWORD64 qwFileSize; + } success; + struct + { + HRESULT hrStatus; + } complete; + }; +} BURN_CACHE_MESSAGE; + +typedef HRESULT(CALLBACK* PFN_BURNCACHEMESSAGEHANDLER)( + __in BURN_CACHE_MESSAGE* pMessage, + __in LPVOID pvContext + ); // functions @@ -95,7 +136,11 @@ HRESULT CacheBundleToWorkingDirectory( HRESULT CacheLayoutBundle( __in_z LPCWSTR wzExecutableName, __in_z LPCWSTR wzLayoutDirectory, - __in_z LPCWSTR wzSourceBundlePath + __in_z LPCWSTR wzSourceBundlePath, + __in DWORD64 qwBundleSize, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ); HRESULT CacheCompleteBundle( __in BOOL fPerMachine, @@ -110,28 +155,43 @@ HRESULT CacheLayoutContainer( __in BURN_CONTAINER* pContainer, __in_z_opt LPCWSTR wzLayoutDirectory, __in_z LPCWSTR wzUnverifiedContainerPath, - __in BOOL fMove + __in BOOL fMove, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ); HRESULT CacheLayoutPayload( __in BURN_PAYLOAD* pPayload, __in_z_opt LPCWSTR wzLayoutDirectory, __in_z LPCWSTR wzUnverifiedPayloadPath, - __in BOOL fMove + __in BOOL fMove, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ); HRESULT CacheCompletePayload( __in BOOL fPerMachine, __in BURN_PAYLOAD* pPayload, __in_z LPCWSTR wzCacheId, __in_z LPCWSTR wzUnverifiedPayloadPath, - __in BOOL fMove + __in BOOL fMove, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ); HRESULT CacheVerifyContainer( __in BURN_CONTAINER* pContainer, - __in_z LPCWSTR wzCachedDirectory + __in_z LPCWSTR wzCachedDirectory, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ); HRESULT CacheVerifyPayload( __in BURN_PAYLOAD* pPayload, - __in_z LPCWSTR wzCachedDirectory + __in_z LPCWSTR wzCachedDirectory, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ); HRESULT CacheRemoveWorkingFolder( __in_z_opt LPCWSTR wzBundleId diff --git a/src/engine/elevation.cpp b/src/engine/elevation.cpp index 502c5462..3a448923 100644 --- a/src/engine/elevation.cpp +++ b/src/engine/elevation.cpp @@ -35,11 +35,15 @@ typedef enum _BURN_ELEVATION_MESSAGE_TYPE BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_PAUSE_AU_COMPLETE, BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_BEGIN, BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE_SYSTEM_RESTORE_POINT_COMPLETE, + BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_BEGIN, + BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_COMPLETE, + BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_PROGRESS, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_ERROR, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_MSI_MESSAGE, BURN_ELEVATION_MESSAGE_TYPE_EXECUTE_FILES_IN_USE, BURN_ELEVATION_MESSAGE_TYPE_LAUNCH_APPROVED_EXE_PROCESSID, + BURN_ELEVATION_MESSAGE_TYPE_PROGRESS_ROUTINE, } BURN_ELEVATION_MESSAGE_TYPE; @@ -52,6 +56,13 @@ typedef struct _BURN_ELEVATION_APPLY_INITIALIZE_MESSAGE_CONTEXT BOOL fSrpCompleteNeeded; } BURN_ELEVATION_APPLY_INITIALIZE_MESSAGE_CONTEXT; +typedef struct _BURN_ELEVATION_CACHE_MESSAGE_CONTEXT +{ + PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler; + LPPROGRESS_ROUTINE pfnProgress; + LPVOID pvContext; +} BURN_ELEVATION_CACHE_MESSAGE_CONTEXT; + typedef struct _BURN_ELEVATION_GENERIC_MESSAGE_CONTEXT { PFN_GENERICMESSAGEHANDLER pfnGenericMessageHandler; @@ -99,6 +110,11 @@ static HRESULT ProcessApplyInitializeMessages( __in_opt LPVOID pvContext, __out DWORD* pdwResult ); +static HRESULT ProcessBurnCacheMessages( + __in BURN_PIPE_MESSAGE* pMsg, + __in LPVOID pvContext, + __out DWORD* pdwResult + ); static HRESULT ProcessGenericExecuteMessages( __in BURN_PIPE_MESSAGE* pMsg, __in LPVOID pvContext, @@ -114,6 +130,12 @@ static HRESULT ProcessLaunchApprovedExeMessages( __in_opt LPVOID pvContext, __out DWORD* pdwResult ); +static HRESULT ProcessProgressRoutineMessage( + __in BURN_PIPE_MESSAGE* pMsg, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pvContext, + __out DWORD* pdwResult + ); static HRESULT ProcessElevatedChildMessage( __in BURN_PIPE_MESSAGE* pMsg, __in_opt LPVOID pvContext, @@ -165,12 +187,14 @@ static HRESULT OnSaveState( __in DWORD cbData ); static HRESULT OnCacheCompletePayload( + __in HANDLE hPipe, __in BURN_PACKAGES* pPackages, __in BURN_PAYLOADS* pPayloads, __in BYTE* pbData, __in DWORD cbData ); static HRESULT OnCacheVerifyPayload( + __in HANDLE hPipe, __in BURN_PACKAGES* pPackages, __in BURN_PAYLOADS* pPayloads, __in BYTE* pbData, @@ -225,6 +249,21 @@ static HRESULT OnExecutePackageDependencyAction( __in BYTE* pbData, __in DWORD cbData ); +static HRESULT CALLBACK BurnCacheMessageHandler( + __in BURN_CACHE_MESSAGE* pMessage, + __in LPVOID pvContext + ); +static DWORD CALLBACK ElevatedProgressRoutine( + __in LARGE_INTEGER TotalFileSize, + __in LARGE_INTEGER TotalBytesTransferred, + __in LARGE_INTEGER StreamSize, + __in LARGE_INTEGER StreamBytesTransferred, + __in DWORD dwStreamNumber, + __in DWORD dwCallbackReason, + __in HANDLE hSourceFile, + __in HANDLE hDestinationFile, + __in_opt LPVOID lpData + ); static int GenericExecuteMessageHandler( __in GENERIC_EXECUTE_MESSAGE* pMessage, __in LPVOID pvContext @@ -582,13 +621,21 @@ extern "C" HRESULT ElevationCacheCompletePayload( __in BURN_PACKAGE* pPackage, __in BURN_PAYLOAD* pPayload, __in_z LPCWSTR wzUnverifiedPath, - __in BOOL fMove + __in BOOL fMove, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ) { HRESULT hr = S_OK; BYTE* pbData = NULL; SIZE_T cbData = 0; DWORD dwResult = 0; + BURN_ELEVATION_CACHE_MESSAGE_CONTEXT context = { }; + + context.pfnCacheMessageHandler = pfnCacheMessageHandler; + context.pfnProgress = pfnProgress; + context.pvContext = pContext; // serialize message data hr = BuffWriteString(&pbData, &cbData, pPackage->sczId); @@ -604,7 +651,7 @@ extern "C" HRESULT ElevationCacheCompletePayload( ExitOnFailure(hr, "Failed to write move flag to message buffer."); // send message - hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD, pbData, cbData, NULL, NULL, &dwResult); + hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD, pbData, cbData, ProcessBurnCacheMessages, &context, &dwResult); ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD message to per-machine process."); hr = (HRESULT)dwResult; @@ -618,13 +665,21 @@ LExit: extern "C" HRESULT ElevationCacheVerifyPayload( __in HANDLE hPipe, __in BURN_PACKAGE* pPackage, - __in BURN_PAYLOAD* pPayload + __in BURN_PAYLOAD* pPayload, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ) { HRESULT hr = S_OK; BYTE* pbData = NULL; SIZE_T cbData = 0; DWORD dwResult = 0; + BURN_ELEVATION_CACHE_MESSAGE_CONTEXT context = { }; + + context.pfnCacheMessageHandler = pfnCacheMessageHandler; + context.pfnProgress = pfnProgress; + context.pvContext = pContext; // serialize message data hr = BuffWriteString(&pbData, &cbData, pPackage->sczId); @@ -634,7 +689,7 @@ extern "C" HRESULT ElevationCacheVerifyPayload( ExitOnFailure(hr, "Failed to write payload id to message buffer."); // send message - hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD, pbData, cbData, NULL, NULL, &dwResult); + hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD, pbData, cbData, ProcessBurnCacheMessages, &context, &dwResult); ExitOnFailure(hr, "Failed to send BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD message to per-machine process."); hr = (HRESULT)dwResult; @@ -1377,6 +1432,69 @@ LExit: return hr; } +static HRESULT ProcessBurnCacheMessages( + __in BURN_PIPE_MESSAGE* pMsg, + __in LPVOID pvContext, + __out DWORD* pdwResult + ) +{ + HRESULT hr = S_OK; + SIZE_T iData = 0; + BURN_ELEVATION_CACHE_MESSAGE_CONTEXT* pContext = static_cast(pvContext); + BURN_CACHE_MESSAGE message = { }; + BOOL fProgressRoutine = FALSE; + + // Process the message. + switch (pMsg->dwMessage) + { + case BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_BEGIN: + // read message parameters + hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, reinterpret_cast(&message.begin.cacheStep)); + ExitOnFailure(hr, "Failed to read begin cache step."); + + message.type = BURN_CACHE_MESSAGE_BEGIN; + break; + + case BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_COMPLETE: + // read message parameters + hr = BuffReadNumber((BYTE*)pMsg->pvData, pMsg->cbData, &iData, reinterpret_cast(&message.complete.hrStatus)); + ExitOnFailure(hr, "Failed to read complete hresult."); + + message.type = BURN_CACHE_MESSAGE_COMPLETE; + break; + + case BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS: + // read message parameters + hr = BuffReadNumber64((BYTE*)pMsg->pvData, pMsg->cbData, &iData, &message.success.qwFileSize); + ExitOnFailure(hr, "Failed to read begin cache step."); + + message.type = BURN_CACHE_MESSAGE_SUCCESS; + break; + + case BURN_ELEVATION_MESSAGE_TYPE_PROGRESS_ROUTINE: + fProgressRoutine = TRUE; + break; + + default: + hr = E_INVALIDARG; + ExitOnRootFailure(hr, "Invalid burn cache message."); + break; + } + + if (fProgressRoutine) + { + hr = ProcessProgressRoutineMessage(pMsg, pContext->pfnProgress, pContext->pvContext, pdwResult); + } + else + { + hr = pContext->pfnCacheMessageHandler(&message, pContext->pvContext); + *pdwResult = static_cast(hr); + } + +LExit: + return hr; +} + static HRESULT ProcessGenericExecuteMessages( __in BURN_PIPE_MESSAGE* pMsg, __in LPVOID pvContext, @@ -1596,11 +1714,41 @@ LExit: return hr; } +static HRESULT ProcessProgressRoutineMessage( + __in BURN_PIPE_MESSAGE* pMsg, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pvContext, + __out DWORD* pdwResult + ) +{ + HRESULT hr = S_OK; + SIZE_T iData = 0; + LARGE_INTEGER liTotalFileSize = { }; + LARGE_INTEGER liTotalBytesTransferred = { }; + LARGE_INTEGER liStreamSize = { }; + LARGE_INTEGER liStreamBytesTransferred = { }; + DWORD dwStreamNumber = 0; + DWORD dwCallbackReason = CALLBACK_CHUNK_FINISHED; + HANDLE hSourceFile = INVALID_HANDLE_VALUE; + HANDLE hDestinationFile = INVALID_HANDLE_VALUE; + + hr = BuffReadNumber64((BYTE*)pMsg->pvData, pMsg->cbData, &iData, reinterpret_cast(&liTotalFileSize.QuadPart)); + ExitOnFailure(hr, "Failed to read total file size for progress."); + + hr = BuffReadNumber64((BYTE*)pMsg->pvData, pMsg->cbData, &iData, reinterpret_cast(&liTotalBytesTransferred.QuadPart)); + ExitOnFailure(hr, "Failed to read total bytes transferred for progress."); + + *pdwResult = pfnProgress(liTotalFileSize, liTotalBytesTransferred, liStreamSize, liStreamBytesTransferred, dwStreamNumber, dwCallbackReason, hSourceFile, hDestinationFile, pvContext); + +LExit: + return hr; +} + static HRESULT ProcessElevatedChildMessage( __in BURN_PIPE_MESSAGE* pMsg, __in_opt LPVOID pvContext, __out DWORD* pdwResult -) + ) { HRESULT hr = S_OK; BURN_ELEVATION_CHILD_MESSAGE_CONTEXT* pContext = static_cast(pvContext); @@ -1705,11 +1853,11 @@ static HRESULT ProcessElevatedChildCacheMessage( switch (pMsg->dwMessage) { case BURN_ELEVATION_MESSAGE_TYPE_CACHE_COMPLETE_PAYLOAD: - hrResult = OnCacheCompletePayload(pContext->pPackages, pContext->pPayloads, (BYTE*)pMsg->pvData, pMsg->cbData); + hrResult = OnCacheCompletePayload(pContext->hPipe, pContext->pPackages, pContext->pPayloads, (BYTE*)pMsg->pvData, pMsg->cbData); break; case BURN_ELEVATION_MESSAGE_TYPE_CACHE_VERIFY_PAYLOAD: - hrResult = OnCacheVerifyPayload(pContext->pPackages, pContext->pPayloads, (BYTE*)pMsg->pvData, pMsg->cbData); + hrResult = OnCacheVerifyPayload(pContext->hPipe, pContext->pPackages, pContext->pPayloads, (BYTE*)pMsg->pvData, pMsg->cbData); break; case BURN_ELEVATION_MESSAGE_TYPE_CACHE_CLEANUP: @@ -2002,6 +2150,7 @@ LExit: } static HRESULT OnCacheCompletePayload( + __in HANDLE hPipe, __in BURN_PACKAGES* pPackages, __in BURN_PAYLOADS* pPayloads, __in BYTE* pbData, @@ -2043,7 +2192,7 @@ static HRESULT OnCacheCompletePayload( if (pPackage && pPayload) // complete payload. { - hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, sczUnverifiedPath, fMove); + hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, sczUnverifiedPath, fMove, BurnCacheMessageHandler, ElevatedProgressRoutine, hPipe); ExitOnFailure(hr, "Failed to cache payload: %ls", pPayload->sczKey); } else @@ -2060,6 +2209,7 @@ LExit: } static HRESULT OnCacheVerifyPayload( + __in HANDLE hPipe, __in BURN_PACKAGES* pPackages, __in BURN_PAYLOADS* pPayloads, __in BYTE* pbData, @@ -2097,7 +2247,7 @@ static HRESULT OnCacheVerifyPayload( hr = CacheGetCompletedPath(TRUE, pPackage->sczCacheId, &sczCacheDirectory); ExitOnFailure(hr, "Failed to get cached path for package with cache id: %ls", pPackage->sczCacheId); - hr = CacheVerifyPayload(pPayload, sczCacheDirectory); + hr = CacheVerifyPayload(pPayload, sczCacheDirectory, BurnCacheMessageHandler, ElevatedProgressRoutine, hPipe); } else { @@ -2573,6 +2723,91 @@ LExit: return hr; } +static HRESULT CALLBACK BurnCacheMessageHandler( + __in BURN_CACHE_MESSAGE* pMessage, + __in LPVOID pvContext + ) +{ + HRESULT hr = S_OK; + DWORD dwResult = 0; + HANDLE hPipe = (HANDLE)pvContext; + BYTE* pbData = NULL; + SIZE_T cbData = 0; + DWORD dwMessage = 0; + + switch (pMessage->type) + { + case BURN_CACHE_MESSAGE_BEGIN: + // serialize message data + hr = BuffWriteNumber(&pbData, &cbData, pMessage->begin.cacheStep); + ExitOnFailure(hr, "Failed to write progress percentage to message buffer."); + + dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_BEGIN; + break; + + case BURN_CACHE_MESSAGE_COMPLETE: + // serialize message data + hr = BuffWriteNumber(&pbData, &cbData, pMessage->complete.hrStatus); + ExitOnFailure(hr, "Failed to write error code to message buffer."); + + dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_COMPLETE; + break; + + case BURN_CACHE_MESSAGE_SUCCESS: + hr = BuffWriteNumber64(&pbData, &cbData, pMessage->success.qwFileSize); + ExitOnFailure(hr, "Failed to count of files in use to message buffer."); + + dwMessage = BURN_ELEVATION_MESSAGE_TYPE_BURN_CACHE_SUCCESS; + break; + } + + // send message + hr = PipeSendMessage(hPipe, dwMessage, pbData, cbData, NULL, NULL, &dwResult); + ExitOnFailure(hr, "Failed to send burn cache message to per-user process."); + + hr = dwResult; + +LExit: + ReleaseBuffer(pbData); + + return hr; +} + +static DWORD CALLBACK ElevatedProgressRoutine( + __in LARGE_INTEGER TotalFileSize, + __in LARGE_INTEGER TotalBytesTransferred, + __in LARGE_INTEGER /*StreamSize*/, + __in LARGE_INTEGER /*StreamBytesTransferred*/, + __in DWORD /*dwStreamNumber*/, + __in DWORD /*dwCallbackReason*/, + __in HANDLE /*hSourceFile*/, + __in HANDLE /*hDestinationFile*/, + __in_opt LPVOID lpData + ) +{ + HRESULT hr = S_OK; + DWORD dwResult = 0; + HANDLE hPipe = (HANDLE)lpData; + BYTE* pbData = NULL; + SIZE_T cbData = 0; + DWORD dwMessage = BURN_ELEVATION_MESSAGE_TYPE_PROGRESS_ROUTINE; + + hr = BuffWriteNumber64(&pbData, &cbData, TotalFileSize.QuadPart); + ExitOnFailure(hr, "Failed to write total file size progress to message buffer."); + + hr = BuffWriteNumber64(&pbData, &cbData, TotalBytesTransferred.QuadPart); + ExitOnFailure(hr, "Failed to write total bytes transferred progress to message buffer."); + + // send message + hr = PipeSendMessage(hPipe, dwMessage, pbData, cbData, NULL, NULL, &dwResult); + ExitOnFailure(hr, "Failed to send progress routine message to per-user process."); + +LExit: + ReleaseBuffer(pbData); + + return dwResult; +} + static int GenericExecuteMessageHandler( __in GENERIC_EXECUTE_MESSAGE* pMessage, __in LPVOID pvContext diff --git a/src/engine/elevation.h b/src/engine/elevation.h index fd7ee110..9244f36c 100644 --- a/src/engine/elevation.h +++ b/src/engine/elevation.h @@ -55,12 +55,18 @@ HRESULT ElevationCacheCompletePayload( __in BURN_PACKAGE* pPackage, __in BURN_PAYLOAD* pPayload, __in_z LPCWSTR wzUnverifiedPath, - __in BOOL fMove + __in BOOL fMove, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ); HRESULT ElevationCacheVerifyPayload( __in HANDLE hPipe, __in BURN_PACKAGE* pPackage, - __in BURN_PAYLOAD* pPayload + __in BURN_PAYLOAD* pPayload, + __in PFN_BURNCACHEMESSAGEHANDLER pfnCacheMessageHandler, + __in LPPROGRESS_ROUTINE pfnProgress, + __in LPVOID pContext ); HRESULT ElevationCacheCleanup( __in HANDLE hPipe diff --git a/src/engine/plan.cpp b/src/engine/plan.cpp index bf929835..f662c445 100644 --- a/src/engine/plan.cpp +++ b/src/engine/plan.cpp @@ -431,8 +431,8 @@ extern "C" HRESULT PlanLayoutBundle( pCacheAction->bundleLayout.qwBundleSize = qwBundleSize; pCacheAction->bundleLayout.pPayloadGroup = pLayoutPayloads; - // Acquire + Verify - pPlan->qwCacheSizeTotal += 2 * qwBundleSize; + // Acquire + Verify + Finalize + pPlan->qwCacheSizeTotal += 3 * qwBundleSize; ++pPlan->cOverallProgressTicksTotal; @@ -1006,8 +1006,8 @@ extern "C" HRESULT PlanLayoutContainer( pCacheAction->type = BURN_CACHE_ACTION_TYPE_CONTAINER; pCacheAction->container.pContainer = pContainer; - // Acquire + Verify - pPlan->qwCacheSizeTotal += 2 * pContainer->qwFileSize; + // Acquire + Verify + Finalize + pPlan->qwCacheSizeTotal += 3 * pContainer->qwFileSize; } } else @@ -2249,8 +2249,14 @@ static HRESULT ProcessPayloadGroup( if (!pPlan->sczLayoutDirectory || !pPayload->pContainer) { - // Acquire + Verify - pPlan->qwCacheSizeTotal += 2 * pPayload->qwFileSize; + // Acquire + Verify + Finalize + pPlan->qwCacheSizeTotal += 3 * pPayload->qwFileSize; + + if (!pPlan->sczLayoutDirectory) + { + // Staging + pPlan->qwCacheSizeTotal += pPayload->qwFileSize; + } } if (!pPlan->sczLayoutDirectory && pPayload->pContainer && 1 == pPayload->cRemainingInstances) diff --git a/src/engine/userexperience.cpp b/src/engine/userexperience.cpp index 279a00b5..8c6f29f3 100644 --- a/src/engine/userexperience.cpp +++ b/src/engine/userexperience.cpp @@ -912,7 +912,8 @@ EXTERN_C BAAPI UserExperienceOnCacheVerifyProgress( __in_z_opt LPCWSTR wzPayloadId, __in DWORD64 dw64Progress, __in DWORD64 dw64Total, - __in DWORD dwOverallPercentage + __in DWORD dwOverallPercentage, + __in BOOTSTRAPPER_CACHE_VERIFY_STEP verifyStep ) { HRESULT hr = S_OK; @@ -925,6 +926,7 @@ EXTERN_C BAAPI UserExperienceOnCacheVerifyProgress( args.dw64Progress = dw64Progress; args.dw64Total = dw64Total; args.dwOverallPercentage = dwOverallPercentage; + args.verifyStep = verifyStep; results.cbSize = sizeof(results); diff --git a/src/engine/userexperience.h b/src/engine/userexperience.h index a848e60d..58e0431e 100644 --- a/src/engine/userexperience.h +++ b/src/engine/userexperience.h @@ -233,7 +233,8 @@ BAAPI UserExperienceOnCacheVerifyProgress( __in_z_opt LPCWSTR wzPayloadId, __in DWORD64 dw64Progress, __in DWORD64 dw64Total, - __in DWORD dwOverallPercentage + __in DWORD dwOverallPercentage, + __in BOOTSTRAPPER_CACHE_VERIFY_STEP verifyStep ); BAAPI UserExperienceOnCommitMsiTransactionBegin( __in BURN_USER_EXPERIENCE* pUserExperience, diff --git a/src/test/BurnUnitTest/CacheTest.cpp b/src/test/BurnUnitTest/CacheTest.cpp index fc0b4531..d0cc237f 100644 --- a/src/test/BurnUnitTest/CacheTest.cpp +++ b/src/test/BurnUnitTest/CacheTest.cpp @@ -2,6 +2,26 @@ #include "precomp.h" +static HRESULT CALLBACK CacheTestEventRoutine( + __in BURN_CACHE_MESSAGE* pMessage, + __in LPVOID pvContext + ); + +static DWORD CALLBACK CacheTestProgressRoutine( + __in LARGE_INTEGER TotalFileSize, + __in LARGE_INTEGER TotalBytesTransferred, + __in LARGE_INTEGER StreamSize, + __in LARGE_INTEGER StreamBytesTransferred, + __in DWORD dwStreamNumber, + __in DWORD dwCallbackReason, + __in HANDLE hSourceFile, + __in HANDLE hDestinationFile, + __in_opt LPVOID lpData + ); + +typedef struct _CACHE_TEST_CONTEXT +{ +} CACHE_TEST_CONTEXT; namespace Microsoft { @@ -33,6 +53,7 @@ namespace Bootstrapper LPWSTR sczPayloadPath = NULL; BYTE* pb = NULL; DWORD cb = NULL; + CACHE_TEST_CONTEXT context = { }; try { @@ -51,7 +72,7 @@ namespace Bootstrapper payload.pbHash = pb; payload.cbHash = cb; - hr = CacheCompletePayload(package.fPerMachine, &payload, package.sczCacheId, sczPayloadPath, FALSE); + hr = CacheCompletePayload(package.fPerMachine, &payload, package.sczCacheId, sczPayloadPath, FALSE, CacheTestEventRoutine, CacheTestProgressRoutine, &context); Assert::Equal(S_OK, hr); } finally @@ -73,3 +94,26 @@ namespace Bootstrapper } } } + +static HRESULT CALLBACK CacheTestEventRoutine( + __in BURN_CACHE_MESSAGE* /*pMessage*/, + __in LPVOID /*pvContext*/ + ) +{ + return S_OK; +} + +static DWORD CALLBACK CacheTestProgressRoutine( + __in LARGE_INTEGER /*TotalFileSize*/, + __in LARGE_INTEGER /*TotalBytesTransferred*/, + __in LARGE_INTEGER /*StreamSize*/, + __in LARGE_INTEGER /*StreamBytesTransferred*/, + __in DWORD /*dwStreamNumber*/, + __in DWORD /*dwCallbackReason*/, + __in HANDLE /*hSourceFile*/, + __in HANDLE /*hDestinationFile*/, + __in_opt LPVOID /*lpData*/ + ) +{ + return PROGRESS_QUIET; +} diff --git a/src/test/BurnUnitTest/PlanTest.cpp b/src/test/BurnUnitTest/PlanTest.cpp index c073696b..a7c1d83c 100644 --- a/src/test/BurnUnitTest/PlanTest.cpp +++ b/src/test/BurnUnitTest/PlanTest.cpp @@ -71,7 +71,7 @@ namespace Bootstrapper Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); Assert::Equal(107082ull, pPlan->qwEstimatedSize); - Assert::Equal(303687ull, pPlan->qwCacheSizeTotal); + Assert::Equal(506145ull, pPlan->qwCacheSizeTotal); fRollback = FALSE; dwIndex = 0; @@ -308,7 +308,7 @@ namespace Bootstrapper Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); Assert::Equal(35694ull, pPlan->qwEstimatedSize); - Assert::Equal(101229ull, pPlan->qwCacheSizeTotal); + Assert::Equal(168715ull, pPlan->qwCacheSizeTotal); fRollback = FALSE; dwIndex = 0; @@ -388,7 +388,7 @@ namespace Bootstrapper Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); Assert::Equal(33743ull, pPlan->qwEstimatedSize); - Assert::Equal(101229ull, pPlan->qwCacheSizeTotal); + Assert::Equal(168715ull, pPlan->qwCacheSizeTotal); fRollback = FALSE; dwIndex = 0; @@ -458,7 +458,7 @@ namespace Bootstrapper Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); Assert::Equal(35694ull, pPlan->qwEstimatedSize); - Assert::Equal(101229ull, pPlan->qwCacheSizeTotal); + Assert::Equal(168715ull, pPlan->qwCacheSizeTotal); fRollback = FALSE; dwIndex = 0; @@ -739,7 +739,7 @@ namespace Bootstrapper Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); Assert::Equal(3055111ull, pPlan->qwEstimatedSize); - Assert::Equal(106496ull, pPlan->qwCacheSizeTotal); + Assert::Equal(212992ull, pPlan->qwCacheSizeTotal); fRollback = FALSE; dwIndex = 0; -- cgit v1.2.3-55-g6feb