From acf86637a6350d269e1ae1aa907e38f5138a0fa9 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Fri, 16 Apr 2021 10:43:21 -0500 Subject: Add OnCacheVerifyProgress, though currently it only reports at the end. --- .../inc/BootstrapperApplication.h | 17 ++++ src/engine/apply.cpp | 92 ++++++++++++++-------- src/engine/userexperience.cpp | 34 ++++++++ src/engine/userexperience.h | 8 ++ 4 files changed, 118 insertions(+), 33 deletions(-) diff --git a/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h b/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h index cf330c29..9fb6ffff 100644 --- a/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h +++ b/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h @@ -149,6 +149,7 @@ enum BOOTSTRAPPER_APPLICATION_MESSAGE BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMRESTOREPOINTCOMPLETE, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDPACKAGE, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANFORWARDCOMPATIBLEBUNDLE, + BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYPROGRESS, }; enum BOOTSTRAPPER_APPLYCOMPLETE_ACTION @@ -454,6 +455,22 @@ struct BA_ONCACHEVERIFYCOMPLETE_RESULTS BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action; }; +struct BA_ONCACHEVERIFYPROGRESS_ARGS +{ + DWORD cbSize; + LPCWSTR wzPackageOrContainerId; + LPCWSTR wzPayloadId; + DWORD64 dw64Progress; + DWORD64 dw64Total; + DWORD dwOverallPercentage; +}; + +struct BA_ONCACHEVERIFYPROGRESS_RESULTS +{ + DWORD cbSize; + BOOL fCancel; +}; + struct BA_ONCOMMITMSITRANSACTIONBEGIN_ARGS { DWORD cbSize; diff --git a/src/engine/apply.cpp b/src/engine/apply.cpp index a2ec023e..6d1743e2 100644 --- a/src/engine/apply.cpp +++ b/src/engine/apply.cpp @@ -11,6 +11,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, +}; + // structs typedef struct _BURN_CACHE_CONTEXT @@ -29,16 +35,17 @@ typedef struct _BURN_CACHE_CONTEXT LPWSTR sczLastUsedFolderCandidate; } BURN_CACHE_CONTEXT; -typedef struct _BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT +typedef struct _BURN_CACHE_PROGRESS_CONTEXT { BURN_CACHE_CONTEXT* pCacheContext; + BURN_CACHE_PROGRESS_TYPE type; BURN_CONTAINER* pContainer; BURN_PACKAGE* pPackage; BURN_PAYLOAD* pPayload; BOOL fCancel; HRESULT hrError; -} BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT; +} BURN_CACHE_PROGRESS_CONTEXT; typedef struct _BURN_EXECUTE_CONTEXT { @@ -111,7 +118,7 @@ static HRESULT ApplyAcquireContainerOrPayload( __in_opt BURN_PAYLOAD* pPayload ); static HRESULT AcquireContainerOrPayload( - __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, + __in BURN_CACHE_PROGRESS_CONTEXT* pProgress, __out BOOL* pfRetry ); static HRESULT LayoutOrCacheContainerOrPayload( @@ -127,17 +134,17 @@ static HRESULT PreparePayloadDestinationPath( __in_z LPCWSTR wzDestinationPath ); static HRESULT CopyPayload( - __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, + __in BURN_CACHE_PROGRESS_CONTEXT* pProgress, __in HANDLE hSourceFile, __in_z LPCWSTR wzSourcePath, __in_z LPCWSTR wzDestinationPath ); static HRESULT DownloadPayload( - __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, + __in BURN_CACHE_PROGRESS_CONTEXT* pProgress, __in_z LPCWSTR wzDestinationPath ); static HRESULT CompleteCacheProgress( - __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pContext, + __in BURN_CACHE_PROGRESS_CONTEXT* pContext, __in DWORD64 qwFileSize ); static DWORD CALLBACK CacheProgressRoutine( @@ -921,13 +928,6 @@ static HRESULT ApplyLayoutContainer( hr = LayoutOrCacheContainerOrPayload(pContext, pContainer, NULL, NULL, TRUE, cTryAgainAttempts, &fRetry); if (SUCCEEDED(hr)) { - if (pContext->sczLastUsedFolderCandidate) - { - // We successfully copied from a source location, set that as the last used source. - CacheSetLastUsedSource(pContext->pVariables, pContext->sczLastUsedFolderCandidate, pContainer->sczFilePath); - } - - pContext->qwSuccessfulCacheProgress += pContainer->qwFileSize; break; } else @@ -988,13 +988,6 @@ static HRESULT ApplyProcessPayload( hr = LayoutOrCacheContainerOrPayload(pContext, NULL, pPackage, pPayload, FALSE, cTryAgainAttempts, &fRetry); if (SUCCEEDED(hr)) { - if (pContext->sczLastUsedFolderCandidate) - { - // We successfully copied from a source location, set that as the last used source. - CacheSetLastUsedSource(pContext->pVariables, pContext->sczLastUsedFolderCandidate, pPayload->sczFilePath); - } - - pContext->qwSuccessfulCacheProgress += pPayload->qwFileSize; break; } else @@ -1092,10 +1085,12 @@ static HRESULT LayoutBundle( LPWSTR sczDestinationPath = NULL; int nEquivalentPaths = 0; BOOTSTRAPPER_CACHE_OPERATION cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_NONE; - BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT progress = { }; + BURN_CACHE_PROGRESS_CONTEXT progress = { }; BOOL fRetry = FALSE; BOOL fRetryAcquire = FALSE; + progress.pCacheContext = pContext; + hr = VariableGetString(pContext->pVariables, BURN_BUNDLE_SOURCE_PROCESS_PATH, &sczBundlePath); if (FAILED(hr)) { @@ -1122,12 +1117,11 @@ static HRESULT LayoutBundle( ExitFunction1(hr = S_OK); } - progress.pCacheContext = pContext; - do { hr = S_OK; fRetry = FALSE; + progress.type = BURN_CACHE_PROGRESS_TYPE_ACQUIRE; for (;;) { @@ -1156,6 +1150,8 @@ static HRESULT LayoutBundle( break; } + progress.type = BURN_CACHE_PROGRESS_TYPE_VERIFY; + do { hr = UserExperienceOnCacheVerifyBegin(pContext->pUX, NULL, NULL); @@ -1170,6 +1166,11 @@ static HRESULT LayoutBundle( hr = CacheLayoutBundle(wzExecutableName, pContext->wzLayoutDirectory, wzUnverifiedPath); } + if (SUCCEEDED(hr)) + { + hr = CompleteCacheProgress(&progress, qwBundleSize); + } + BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE; UserExperienceOnCacheVerifyComplete(pContext->pUX, NULL, NULL, hr, &action); if (BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYVERIFICATION == action) @@ -1189,8 +1190,6 @@ static HRESULT LayoutBundle( } while (fRetry); LogExitOnFailure(hr, MSG_FAILED_LAYOUT_BUNDLE, "Failed to layout bundle: %ls to layout directory: %ls", sczBundlePath, pContext->wzLayoutDirectory); - pContext->qwSuccessfulCacheProgress += qwBundleSize; - LExit: ReleaseStr(sczDestinationPath); ReleaseStr(sczBundleDownloadUrl); @@ -1209,10 +1208,11 @@ static HRESULT ApplyAcquireContainerOrPayload( AssertSz(pContainer || pPayload, "Must provide a container or a payload."); HRESULT hr = S_OK; - BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT progress = { }; + BURN_CACHE_PROGRESS_CONTEXT progress = { }; BOOL fRetry = FALSE; progress.pCacheContext = pContext; + progress.type = BURN_CACHE_PROGRESS_TYPE_ACQUIRE; progress.pContainer = pContainer; progress.pPackage = pPackage; progress.pPayload = pPayload; @@ -1235,7 +1235,7 @@ LExit: } static HRESULT AcquireContainerOrPayload( - __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, + __in BURN_CACHE_PROGRESS_CONTEXT* pProgress, __out BOOL* pfRetry ) { @@ -1373,6 +1373,7 @@ static HRESULT LayoutOrCacheContainerOrPayload( LPCWSTR wzUnverifiedPath = pContainer ? pContainer->sczUnverifiedPath : pPayload->sczUnverifiedPath; LPCWSTR wzPayloadId = pPayload ? pPayload->sczKey : L""; BOOL fCanAffectRegistration = FALSE; + BURN_CACHE_PROGRESS_CONTEXT progress = { }; if (!pContext->wzLayoutDirectory) { @@ -1383,6 +1384,11 @@ static HRESULT LayoutOrCacheContainerOrPayload( } *pfRetry = FALSE; + progress.pCacheContext = pContext; + progress.type = BURN_CACHE_PROGRESS_TYPE_VERIFY; + progress.pContainer = pContainer; + progress.pPackage = pPackage; + progress.pPayload = pPayload; do { @@ -1409,6 +1415,11 @@ static HRESULT LayoutOrCacheContainerOrPayload( hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, wzUnverifiedPath, fMove); } + if (SUCCEEDED(hr)) + { + hr = CompleteCacheProgress(&progress, pContainer ? pContainer->qwFileSize : pPayload->qwFileSize); + } + if (SUCCEEDED(hr) && fCanAffectRegistration) { pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT; @@ -1460,7 +1471,7 @@ LExit: } static HRESULT CopyPayload( - __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, + __in BURN_CACHE_PROGRESS_CONTEXT* pProgress, __in HANDLE hSourceFile, __in_z LPCWSTR wzSourcePath, __in_z LPCWSTR wzDestinationPath @@ -1522,7 +1533,7 @@ LExit: } static HRESULT DownloadPayload( - __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, + __in BURN_CACHE_PROGRESS_CONTEXT* pProgress, __in_z LPCWSTR wzDestinationPath ) { @@ -1618,7 +1629,7 @@ LExit: } static HRESULT CompleteCacheProgress( - __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pContext, + __in BURN_CACHE_PROGRESS_CONTEXT* pContext, __in DWORD64 qwFileSize ) { @@ -1634,6 +1645,12 @@ static HRESULT CompleteCacheProgress( if (PROGRESS_CONTINUE == dwResult) { pContext->pCacheContext->qwSuccessfulCacheProgress += qwFileSize; + + if (BURN_CACHE_PROGRESS_TYPE_VERIFY == 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->pPayload->sczFilePath); + } } else if (PROGRESS_CANCEL == dwResult) { @@ -1664,7 +1681,7 @@ static DWORD CALLBACK CacheProgressRoutine( { HRESULT hr = S_OK; DWORD dwResult = PROGRESS_CONTINUE; - BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress = static_cast(lpData); + BURN_CACHE_PROGRESS_CONTEXT* pProgress = static_cast(lpData); LPCWSTR wzPackageOrContainerId = pProgress->pContainer ? pProgress->pContainer->sczId : pProgress->pPackage ? pProgress->pPackage->sczId : NULL; LPCWSTR wzPayloadId = pProgress->pPayload ? pProgress->pPayload->sczKey : NULL; DWORD64 qwCacheProgress = pProgress->pCacheContext->qwSuccessfulCacheProgress + TotalBytesTransferred.QuadPart; @@ -1675,8 +1692,17 @@ static DWORD CALLBACK CacheProgressRoutine( } DWORD dwOverallPercentage = pProgress->pCacheContext->qwTotalCacheSize ? static_cast(qwCacheProgress * 100 / pProgress->pCacheContext->qwTotalCacheSize) : 0; - 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); + switch (pProgress->type) + { + case BURN_CACHE_PROGRESS_TYPE_ACQUIRE: + 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); + break; + } LExit: if (HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) == hr) diff --git a/src/engine/userexperience.cpp b/src/engine/userexperience.cpp index f6ae1491..b42eb5a7 100644 --- a/src/engine/userexperience.cpp +++ b/src/engine/userexperience.cpp @@ -732,6 +732,40 @@ LExit: return hr; } +EXTERN_C BAAPI UserExperienceOnCacheVerifyProgress( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in DWORD64 dw64Progress, + __in DWORD64 dw64Total, + __in DWORD dwOverallPercentage + ) +{ + HRESULT hr = S_OK; + BA_ONCACHEVERIFYPROGRESS_ARGS args = { }; + BA_ONCACHEVERIFYPROGRESS_RESULTS results = { }; + + args.cbSize = sizeof(args); + args.wzPackageOrContainerId = wzPackageOrContainerId; + args.wzPayloadId = wzPayloadId; + args.dw64Progress = dw64Progress; + args.dw64Total = dw64Total; + args.dwOverallPercentage = dwOverallPercentage; + + results.cbSize = sizeof(results); + + hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYPROGRESS, &args, &results); + ExitOnFailure(hr, "BA OnCacheVerifyProgress failed."); + + if (results.fCancel) + { + hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); + } + +LExit: + return hr; +} + EXTERN_C BAAPI UserExperienceOnCommitMsiTransactionBegin( __in BURN_USER_EXPERIENCE* pUserExperience, __in LPCWSTR wzTransactionId diff --git a/src/engine/userexperience.h b/src/engine/userexperience.h index dd1fb086..e09c9ec1 100644 --- a/src/engine/userexperience.h +++ b/src/engine/userexperience.h @@ -189,6 +189,14 @@ BAAPI UserExperienceOnCacheVerifyComplete( __in HRESULT hrStatus, __inout BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION* pAction ); +BAAPI UserExperienceOnCacheVerifyProgress( + __in BURN_USER_EXPERIENCE* pUserExperience, + __in_z_opt LPCWSTR wzPackageOrContainerId, + __in_z_opt LPCWSTR wzPayloadId, + __in DWORD64 dw64Progress, + __in DWORD64 dw64Total, + __in DWORD dwOverallPercentage + ); BAAPI UserExperienceOnCommitMsiTransactionBegin( __in BURN_USER_EXPERIENCE* pUserExperience, __in LPCWSTR wzTransactionId -- cgit v1.2.3-55-g6feb