aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-04-16 10:43:21 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-04-19 23:12:55 -0500
commitacf86637a6350d269e1ae1aa907e38f5138a0fa9 (patch)
treea8b8713e26e0a620aa8b983b7c2fb769524ecc3a
parent31539e7a5baf0f75f3cd0e4764c003bb6a8310ce (diff)
downloadwix-acf86637a6350d269e1ae1aa907e38f5138a0fa9.tar.gz
wix-acf86637a6350d269e1ae1aa907e38f5138a0fa9.tar.bz2
wix-acf86637a6350d269e1ae1aa907e38f5138a0fa9.zip
Add OnCacheVerifyProgress, though currently it only reports at the end.
-rw-r--r--src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h17
-rw-r--r--src/engine/apply.cpp92
-rw-r--r--src/engine/userexperience.cpp34
-rw-r--r--src/engine/userexperience.h8
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
149 BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMRESTOREPOINTCOMPLETE, 149 BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMRESTOREPOINTCOMPLETE,
150 BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDPACKAGE, 150 BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDPACKAGE,
151 BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANFORWARDCOMPATIBLEBUNDLE, 151 BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANFORWARDCOMPATIBLEBUNDLE,
152 BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYPROGRESS,
152}; 153};
153 154
154enum BOOTSTRAPPER_APPLYCOMPLETE_ACTION 155enum BOOTSTRAPPER_APPLYCOMPLETE_ACTION
@@ -454,6 +455,22 @@ struct BA_ONCACHEVERIFYCOMPLETE_RESULTS
454 BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action; 455 BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action;
455}; 456};
456 457
458struct BA_ONCACHEVERIFYPROGRESS_ARGS
459{
460 DWORD cbSize;
461 LPCWSTR wzPackageOrContainerId;
462 LPCWSTR wzPayloadId;
463 DWORD64 dw64Progress;
464 DWORD64 dw64Total;
465 DWORD dwOverallPercentage;
466};
467
468struct BA_ONCACHEVERIFYPROGRESS_RESULTS
469{
470 DWORD cbSize;
471 BOOL fCancel;
472};
473
457struct BA_ONCOMMITMSITRANSACTIONBEGIN_ARGS 474struct BA_ONCOMMITMSITRANSACTIONBEGIN_ARGS
458{ 475{
459 DWORD cbSize; 476 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 @@
11 11
12const DWORD BURN_CACHE_MAX_RECOMMENDED_VERIFY_TRYAGAIN_ATTEMPTS = 2; 12const DWORD BURN_CACHE_MAX_RECOMMENDED_VERIFY_TRYAGAIN_ATTEMPTS = 2;
13 13
14enum BURN_CACHE_PROGRESS_TYPE
15{
16 BURN_CACHE_PROGRESS_TYPE_ACQUIRE,
17 BURN_CACHE_PROGRESS_TYPE_VERIFY,
18};
19
14// structs 20// structs
15 21
16typedef struct _BURN_CACHE_CONTEXT 22typedef struct _BURN_CACHE_CONTEXT
@@ -29,16 +35,17 @@ typedef struct _BURN_CACHE_CONTEXT
29 LPWSTR sczLastUsedFolderCandidate; 35 LPWSTR sczLastUsedFolderCandidate;
30} BURN_CACHE_CONTEXT; 36} BURN_CACHE_CONTEXT;
31 37
32typedef struct _BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT 38typedef struct _BURN_CACHE_PROGRESS_CONTEXT
33{ 39{
34 BURN_CACHE_CONTEXT* pCacheContext; 40 BURN_CACHE_CONTEXT* pCacheContext;
41 BURN_CACHE_PROGRESS_TYPE type;
35 BURN_CONTAINER* pContainer; 42 BURN_CONTAINER* pContainer;
36 BURN_PACKAGE* pPackage; 43 BURN_PACKAGE* pPackage;
37 BURN_PAYLOAD* pPayload; 44 BURN_PAYLOAD* pPayload;
38 45
39 BOOL fCancel; 46 BOOL fCancel;
40 HRESULT hrError; 47 HRESULT hrError;
41} BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT; 48} BURN_CACHE_PROGRESS_CONTEXT;
42 49
43typedef struct _BURN_EXECUTE_CONTEXT 50typedef struct _BURN_EXECUTE_CONTEXT
44{ 51{
@@ -111,7 +118,7 @@ static HRESULT ApplyAcquireContainerOrPayload(
111 __in_opt BURN_PAYLOAD* pPayload 118 __in_opt BURN_PAYLOAD* pPayload
112 ); 119 );
113static HRESULT AcquireContainerOrPayload( 120static HRESULT AcquireContainerOrPayload(
114 __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, 121 __in BURN_CACHE_PROGRESS_CONTEXT* pProgress,
115 __out BOOL* pfRetry 122 __out BOOL* pfRetry
116 ); 123 );
117static HRESULT LayoutOrCacheContainerOrPayload( 124static HRESULT LayoutOrCacheContainerOrPayload(
@@ -127,17 +134,17 @@ static HRESULT PreparePayloadDestinationPath(
127 __in_z LPCWSTR wzDestinationPath 134 __in_z LPCWSTR wzDestinationPath
128 ); 135 );
129static HRESULT CopyPayload( 136static HRESULT CopyPayload(
130 __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, 137 __in BURN_CACHE_PROGRESS_CONTEXT* pProgress,
131 __in HANDLE hSourceFile, 138 __in HANDLE hSourceFile,
132 __in_z LPCWSTR wzSourcePath, 139 __in_z LPCWSTR wzSourcePath,
133 __in_z LPCWSTR wzDestinationPath 140 __in_z LPCWSTR wzDestinationPath
134 ); 141 );
135static HRESULT DownloadPayload( 142static HRESULT DownloadPayload(
136 __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, 143 __in BURN_CACHE_PROGRESS_CONTEXT* pProgress,
137 __in_z LPCWSTR wzDestinationPath 144 __in_z LPCWSTR wzDestinationPath
138 ); 145 );
139static HRESULT CompleteCacheProgress( 146static HRESULT CompleteCacheProgress(
140 __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pContext, 147 __in BURN_CACHE_PROGRESS_CONTEXT* pContext,
141 __in DWORD64 qwFileSize 148 __in DWORD64 qwFileSize
142 ); 149 );
143static DWORD CALLBACK CacheProgressRoutine( 150static DWORD CALLBACK CacheProgressRoutine(
@@ -921,13 +928,6 @@ static HRESULT ApplyLayoutContainer(
921 hr = LayoutOrCacheContainerOrPayload(pContext, pContainer, NULL, NULL, TRUE, cTryAgainAttempts, &fRetry); 928 hr = LayoutOrCacheContainerOrPayload(pContext, pContainer, NULL, NULL, TRUE, cTryAgainAttempts, &fRetry);
922 if (SUCCEEDED(hr)) 929 if (SUCCEEDED(hr))
923 { 930 {
924 if (pContext->sczLastUsedFolderCandidate)
925 {
926 // We successfully copied from a source location, set that as the last used source.
927 CacheSetLastUsedSource(pContext->pVariables, pContext->sczLastUsedFolderCandidate, pContainer->sczFilePath);
928 }
929
930 pContext->qwSuccessfulCacheProgress += pContainer->qwFileSize;
931 break; 931 break;
932 } 932 }
933 else 933 else
@@ -988,13 +988,6 @@ static HRESULT ApplyProcessPayload(
988 hr = LayoutOrCacheContainerOrPayload(pContext, NULL, pPackage, pPayload, FALSE, cTryAgainAttempts, &fRetry); 988 hr = LayoutOrCacheContainerOrPayload(pContext, NULL, pPackage, pPayload, FALSE, cTryAgainAttempts, &fRetry);
989 if (SUCCEEDED(hr)) 989 if (SUCCEEDED(hr))
990 { 990 {
991 if (pContext->sczLastUsedFolderCandidate)
992 {
993 // We successfully copied from a source location, set that as the last used source.
994 CacheSetLastUsedSource(pContext->pVariables, pContext->sczLastUsedFolderCandidate, pPayload->sczFilePath);
995 }
996
997 pContext->qwSuccessfulCacheProgress += pPayload->qwFileSize;
998 break; 991 break;
999 } 992 }
1000 else 993 else
@@ -1092,10 +1085,12 @@ static HRESULT LayoutBundle(
1092 LPWSTR sczDestinationPath = NULL; 1085 LPWSTR sczDestinationPath = NULL;
1093 int nEquivalentPaths = 0; 1086 int nEquivalentPaths = 0;
1094 BOOTSTRAPPER_CACHE_OPERATION cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_NONE; 1087 BOOTSTRAPPER_CACHE_OPERATION cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_NONE;
1095 BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT progress = { }; 1088 BURN_CACHE_PROGRESS_CONTEXT progress = { };
1096 BOOL fRetry = FALSE; 1089 BOOL fRetry = FALSE;
1097 BOOL fRetryAcquire = FALSE; 1090 BOOL fRetryAcquire = FALSE;
1098 1091
1092 progress.pCacheContext = pContext;
1093
1099 hr = VariableGetString(pContext->pVariables, BURN_BUNDLE_SOURCE_PROCESS_PATH, &sczBundlePath); 1094 hr = VariableGetString(pContext->pVariables, BURN_BUNDLE_SOURCE_PROCESS_PATH, &sczBundlePath);
1100 if (FAILED(hr)) 1095 if (FAILED(hr))
1101 { 1096 {
@@ -1122,12 +1117,11 @@ static HRESULT LayoutBundle(
1122 ExitFunction1(hr = S_OK); 1117 ExitFunction1(hr = S_OK);
1123 } 1118 }
1124 1119
1125 progress.pCacheContext = pContext;
1126
1127 do 1120 do
1128 { 1121 {
1129 hr = S_OK; 1122 hr = S_OK;
1130 fRetry = FALSE; 1123 fRetry = FALSE;
1124 progress.type = BURN_CACHE_PROGRESS_TYPE_ACQUIRE;
1131 1125
1132 for (;;) 1126 for (;;)
1133 { 1127 {
@@ -1156,6 +1150,8 @@ static HRESULT LayoutBundle(
1156 break; 1150 break;
1157 } 1151 }
1158 1152
1153 progress.type = BURN_CACHE_PROGRESS_TYPE_VERIFY;
1154
1159 do 1155 do
1160 { 1156 {
1161 hr = UserExperienceOnCacheVerifyBegin(pContext->pUX, NULL, NULL); 1157 hr = UserExperienceOnCacheVerifyBegin(pContext->pUX, NULL, NULL);
@@ -1170,6 +1166,11 @@ static HRESULT LayoutBundle(
1170 hr = CacheLayoutBundle(wzExecutableName, pContext->wzLayoutDirectory, wzUnverifiedPath); 1166 hr = CacheLayoutBundle(wzExecutableName, pContext->wzLayoutDirectory, wzUnverifiedPath);
1171 } 1167 }
1172 1168
1169 if (SUCCEEDED(hr))
1170 {
1171 hr = CompleteCacheProgress(&progress, qwBundleSize);
1172 }
1173
1173 BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE; 1174 BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE;
1174 UserExperienceOnCacheVerifyComplete(pContext->pUX, NULL, NULL, hr, &action); 1175 UserExperienceOnCacheVerifyComplete(pContext->pUX, NULL, NULL, hr, &action);
1175 if (BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYVERIFICATION == action) 1176 if (BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYVERIFICATION == action)
@@ -1189,8 +1190,6 @@ static HRESULT LayoutBundle(
1189 } while (fRetry); 1190 } while (fRetry);
1190 LogExitOnFailure(hr, MSG_FAILED_LAYOUT_BUNDLE, "Failed to layout bundle: %ls to layout directory: %ls", sczBundlePath, pContext->wzLayoutDirectory); 1191 LogExitOnFailure(hr, MSG_FAILED_LAYOUT_BUNDLE, "Failed to layout bundle: %ls to layout directory: %ls", sczBundlePath, pContext->wzLayoutDirectory);
1191 1192
1192 pContext->qwSuccessfulCacheProgress += qwBundleSize;
1193
1194LExit: 1193LExit:
1195 ReleaseStr(sczDestinationPath); 1194 ReleaseStr(sczDestinationPath);
1196 ReleaseStr(sczBundleDownloadUrl); 1195 ReleaseStr(sczBundleDownloadUrl);
@@ -1209,10 +1208,11 @@ static HRESULT ApplyAcquireContainerOrPayload(
1209 AssertSz(pContainer || pPayload, "Must provide a container or a payload."); 1208 AssertSz(pContainer || pPayload, "Must provide a container or a payload.");
1210 1209
1211 HRESULT hr = S_OK; 1210 HRESULT hr = S_OK;
1212 BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT progress = { }; 1211 BURN_CACHE_PROGRESS_CONTEXT progress = { };
1213 BOOL fRetry = FALSE; 1212 BOOL fRetry = FALSE;
1214 1213
1215 progress.pCacheContext = pContext; 1214 progress.pCacheContext = pContext;
1215 progress.type = BURN_CACHE_PROGRESS_TYPE_ACQUIRE;
1216 progress.pContainer = pContainer; 1216 progress.pContainer = pContainer;
1217 progress.pPackage = pPackage; 1217 progress.pPackage = pPackage;
1218 progress.pPayload = pPayload; 1218 progress.pPayload = pPayload;
@@ -1235,7 +1235,7 @@ LExit:
1235} 1235}
1236 1236
1237static HRESULT AcquireContainerOrPayload( 1237static HRESULT AcquireContainerOrPayload(
1238 __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, 1238 __in BURN_CACHE_PROGRESS_CONTEXT* pProgress,
1239 __out BOOL* pfRetry 1239 __out BOOL* pfRetry
1240 ) 1240 )
1241{ 1241{
@@ -1373,6 +1373,7 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1373 LPCWSTR wzUnverifiedPath = pContainer ? pContainer->sczUnverifiedPath : pPayload->sczUnverifiedPath; 1373 LPCWSTR wzUnverifiedPath = pContainer ? pContainer->sczUnverifiedPath : pPayload->sczUnverifiedPath;
1374 LPCWSTR wzPayloadId = pPayload ? pPayload->sczKey : L""; 1374 LPCWSTR wzPayloadId = pPayload ? pPayload->sczKey : L"";
1375 BOOL fCanAffectRegistration = FALSE; 1375 BOOL fCanAffectRegistration = FALSE;
1376 BURN_CACHE_PROGRESS_CONTEXT progress = { };
1376 1377
1377 if (!pContext->wzLayoutDirectory) 1378 if (!pContext->wzLayoutDirectory)
1378 { 1379 {
@@ -1383,6 +1384,11 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1383 } 1384 }
1384 1385
1385 *pfRetry = FALSE; 1386 *pfRetry = FALSE;
1387 progress.pCacheContext = pContext;
1388 progress.type = BURN_CACHE_PROGRESS_TYPE_VERIFY;
1389 progress.pContainer = pContainer;
1390 progress.pPackage = pPackage;
1391 progress.pPayload = pPayload;
1386 1392
1387 do 1393 do
1388 { 1394 {
@@ -1409,6 +1415,11 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1409 hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, wzUnverifiedPath, fMove); 1415 hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, wzUnverifiedPath, fMove);
1410 } 1416 }
1411 1417
1418 if (SUCCEEDED(hr))
1419 {
1420 hr = CompleteCacheProgress(&progress, pContainer ? pContainer->qwFileSize : pPayload->qwFileSize);
1421 }
1422
1412 if (SUCCEEDED(hr) && fCanAffectRegistration) 1423 if (SUCCEEDED(hr) && fCanAffectRegistration)
1413 { 1424 {
1414 pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT; 1425 pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
@@ -1460,7 +1471,7 @@ LExit:
1460} 1471}
1461 1472
1462static HRESULT CopyPayload( 1473static HRESULT CopyPayload(
1463 __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, 1474 __in BURN_CACHE_PROGRESS_CONTEXT* pProgress,
1464 __in HANDLE hSourceFile, 1475 __in HANDLE hSourceFile,
1465 __in_z LPCWSTR wzSourcePath, 1476 __in_z LPCWSTR wzSourcePath,
1466 __in_z LPCWSTR wzDestinationPath 1477 __in_z LPCWSTR wzDestinationPath
@@ -1522,7 +1533,7 @@ LExit:
1522} 1533}
1523 1534
1524static HRESULT DownloadPayload( 1535static HRESULT DownloadPayload(
1525 __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress, 1536 __in BURN_CACHE_PROGRESS_CONTEXT* pProgress,
1526 __in_z LPCWSTR wzDestinationPath 1537 __in_z LPCWSTR wzDestinationPath
1527 ) 1538 )
1528{ 1539{
@@ -1618,7 +1629,7 @@ LExit:
1618} 1629}
1619 1630
1620static HRESULT CompleteCacheProgress( 1631static HRESULT CompleteCacheProgress(
1621 __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pContext, 1632 __in BURN_CACHE_PROGRESS_CONTEXT* pContext,
1622 __in DWORD64 qwFileSize 1633 __in DWORD64 qwFileSize
1623 ) 1634 )
1624{ 1635{
@@ -1634,6 +1645,12 @@ static HRESULT CompleteCacheProgress(
1634 if (PROGRESS_CONTINUE == dwResult) 1645 if (PROGRESS_CONTINUE == dwResult)
1635 { 1646 {
1636 pContext->pCacheContext->qwSuccessfulCacheProgress += qwFileSize; 1647 pContext->pCacheContext->qwSuccessfulCacheProgress += qwFileSize;
1648
1649 if (BURN_CACHE_PROGRESS_TYPE_VERIFY == pContext->type && pContext->pCacheContext->sczLastUsedFolderCandidate)
1650 {
1651 // We successfully copied from a source location, set that as the last used source.
1652 CacheSetLastUsedSource(pContext->pCacheContext->pVariables, pContext->pCacheContext->sczLastUsedFolderCandidate, pContext->pContainer ? pContext->pContainer->sczFilePath : pContext->pPayload->sczFilePath);
1653 }
1637 } 1654 }
1638 else if (PROGRESS_CANCEL == dwResult) 1655 else if (PROGRESS_CANCEL == dwResult)
1639 { 1656 {
@@ -1664,7 +1681,7 @@ static DWORD CALLBACK CacheProgressRoutine(
1664{ 1681{
1665 HRESULT hr = S_OK; 1682 HRESULT hr = S_OK;
1666 DWORD dwResult = PROGRESS_CONTINUE; 1683 DWORD dwResult = PROGRESS_CONTINUE;
1667 BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress = static_cast<BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT*>(lpData); 1684 BURN_CACHE_PROGRESS_CONTEXT* pProgress = static_cast<BURN_CACHE_PROGRESS_CONTEXT*>(lpData);
1668 LPCWSTR wzPackageOrContainerId = pProgress->pContainer ? pProgress->pContainer->sczId : pProgress->pPackage ? pProgress->pPackage->sczId : NULL; 1685 LPCWSTR wzPackageOrContainerId = pProgress->pContainer ? pProgress->pContainer->sczId : pProgress->pPackage ? pProgress->pPackage->sczId : NULL;
1669 LPCWSTR wzPayloadId = pProgress->pPayload ? pProgress->pPayload->sczKey : NULL; 1686 LPCWSTR wzPayloadId = pProgress->pPayload ? pProgress->pPayload->sczKey : NULL;
1670 DWORD64 qwCacheProgress = pProgress->pCacheContext->qwSuccessfulCacheProgress + TotalBytesTransferred.QuadPart; 1687 DWORD64 qwCacheProgress = pProgress->pCacheContext->qwSuccessfulCacheProgress + TotalBytesTransferred.QuadPart;
@@ -1675,8 +1692,17 @@ static DWORD CALLBACK CacheProgressRoutine(
1675 } 1692 }
1676 DWORD dwOverallPercentage = pProgress->pCacheContext->qwTotalCacheSize ? static_cast<DWORD>(qwCacheProgress * 100 / pProgress->pCacheContext->qwTotalCacheSize) : 0; 1693 DWORD dwOverallPercentage = pProgress->pCacheContext->qwTotalCacheSize ? static_cast<DWORD>(qwCacheProgress * 100 / pProgress->pCacheContext->qwTotalCacheSize) : 0;
1677 1694
1678 hr = UserExperienceOnCacheAcquireProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage); 1695 switch (pProgress->type)
1679 ExitOnRootFailure(hr, "BA aborted acquire of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId); 1696 {
1697 case BURN_CACHE_PROGRESS_TYPE_ACQUIRE:
1698 hr = UserExperienceOnCacheAcquireProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage);
1699 ExitOnRootFailure(hr, "BA aborted acquire of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId);
1700 break;
1701 case BURN_CACHE_PROGRESS_TYPE_VERIFY:
1702 hr = UserExperienceOnCacheVerifyProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage);
1703 ExitOnRootFailure(hr, "BA aborted verify of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId);
1704 break;
1705 }
1680 1706
1681LExit: 1707LExit:
1682 if (HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) == hr) 1708 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:
732 return hr; 732 return hr;
733} 733}
734 734
735EXTERN_C BAAPI UserExperienceOnCacheVerifyProgress(
736 __in BURN_USER_EXPERIENCE* pUserExperience,
737 __in_z_opt LPCWSTR wzPackageOrContainerId,
738 __in_z_opt LPCWSTR wzPayloadId,
739 __in DWORD64 dw64Progress,
740 __in DWORD64 dw64Total,
741 __in DWORD dwOverallPercentage
742 )
743{
744 HRESULT hr = S_OK;
745 BA_ONCACHEVERIFYPROGRESS_ARGS args = { };
746 BA_ONCACHEVERIFYPROGRESS_RESULTS results = { };
747
748 args.cbSize = sizeof(args);
749 args.wzPackageOrContainerId = wzPackageOrContainerId;
750 args.wzPayloadId = wzPayloadId;
751 args.dw64Progress = dw64Progress;
752 args.dw64Total = dw64Total;
753 args.dwOverallPercentage = dwOverallPercentage;
754
755 results.cbSize = sizeof(results);
756
757 hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYPROGRESS, &args, &results);
758 ExitOnFailure(hr, "BA OnCacheVerifyProgress failed.");
759
760 if (results.fCancel)
761 {
762 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
763 }
764
765LExit:
766 return hr;
767}
768
735EXTERN_C BAAPI UserExperienceOnCommitMsiTransactionBegin( 769EXTERN_C BAAPI UserExperienceOnCommitMsiTransactionBegin(
736 __in BURN_USER_EXPERIENCE* pUserExperience, 770 __in BURN_USER_EXPERIENCE* pUserExperience,
737 __in LPCWSTR wzTransactionId 771 __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(
189 __in HRESULT hrStatus, 189 __in HRESULT hrStatus,
190 __inout BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION* pAction 190 __inout BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION* pAction
191 ); 191 );
192BAAPI UserExperienceOnCacheVerifyProgress(
193 __in BURN_USER_EXPERIENCE* pUserExperience,
194 __in_z_opt LPCWSTR wzPackageOrContainerId,
195 __in_z_opt LPCWSTR wzPayloadId,
196 __in DWORD64 dw64Progress,
197 __in DWORD64 dw64Total,
198 __in DWORD dwOverallPercentage
199 );
192BAAPI UserExperienceOnCommitMsiTransactionBegin( 200BAAPI UserExperienceOnCommitMsiTransactionBegin(
193 __in BURN_USER_EXPERIENCE* pUserExperience, 201 __in BURN_USER_EXPERIENCE* pUserExperience,
194 __in LPCWSTR wzTransactionId 202 __in LPCWSTR wzTransactionId