@joebigelow / wix-1 / commits / acf86637

Add OnCacheVerifyProgress, though currently it only reports at the end.

Sean Hall committed Apr 16, 2021 at 10:43 UTC acf86637a6350d269e1ae1aa907e38f5138a0fa9
4 files changed +118 -33
src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
+17
@@ -149,6 +149,7 @@ enum BOOTSTRAPPER_APPLICATION_MESSAGE
149 BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMRESTOREPOINTCOMPLETE,
150 BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDPACKAGE,
151 BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANFORWARDCOMPATIBLEBUNDLE,
152 + BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEVERIFYPROGRESS,
153 };
154
155 enum BOOTSTRAPPER_APPLYCOMPLETE_ACTION
@@ -454,6 +455,22 @@ struct BA_ONCACHEVERIFYCOMPLETE_RESULTS
455 BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action;
456 };
457
458 +struct BA_ONCACHEVERIFYPROGRESS_ARGS
459 +{
460 + DWORD cbSize;
461 + LPCWSTR wzPackageOrContainerId;
462 + LPCWSTR wzPayloadId;
463 + DWORD64 dw64Progress;
464 + DWORD64 dw64Total;
465 + DWORD dwOverallPercentage;
466 +};
467 +
468 +struct BA_ONCACHEVERIFYPROGRESS_RESULTS
469 +{
470 + DWORD cbSize;
471 + BOOL fCancel;
472 +};
473 +
474 struct BA_ONCOMMITMSITRANSACTIONBEGIN_ARGS
475 {
476 DWORD cbSize;
src/engine/apply.cpp
+59 -33
@@ -11,6 +11,12 @@
11
12 const DWORD BURN_CACHE_MAX_RECOMMENDED_VERIFY_TRYAGAIN_ATTEMPTS = 2;
13
14 +enum BURN_CACHE_PROGRESS_TYPE
15 +{
16 + BURN_CACHE_PROGRESS_TYPE_ACQUIRE,
17 + BURN_CACHE_PROGRESS_TYPE_VERIFY,
18 +};
19 +
20 // structs
21
22 typedef struct _BURN_CACHE_CONTEXT
@@ -29,16 +35,17 @@ typedef struct _BURN_CACHE_CONTEXT
35 LPWSTR sczLastUsedFolderCandidate;
36 } BURN_CACHE_CONTEXT;
37
32 -typedef struct _BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT
38 +typedef struct _BURN_CACHE_PROGRESS_CONTEXT
39 {
40 BURN_CACHE_CONTEXT* pCacheContext;
41 + BURN_CACHE_PROGRESS_TYPE type;
42 BURN_CONTAINER* pContainer;
43 BURN_PACKAGE* pPackage;
44 BURN_PAYLOAD* pPayload;
45
46 BOOL fCancel;
47 HRESULT hrError;
41 -} BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT;
48 +} BURN_CACHE_PROGRESS_CONTEXT;
49
50 typedef struct _BURN_EXECUTE_CONTEXT
51 {
@@ -111,7 +118,7 @@ static HRESULT ApplyAcquireContainerOrPayload(
118 __in_opt BURN_PAYLOAD* pPayload
119 );
120 static HRESULT AcquireContainerOrPayload(
114 - __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress,
121 + __in BURN_CACHE_PROGRESS_CONTEXT* pProgress,
122 __out BOOL* pfRetry
123 );
124 static HRESULT LayoutOrCacheContainerOrPayload(
@@ -127,17 +134,17 @@ static HRESULT PreparePayloadDestinationPath(
134 __in_z LPCWSTR wzDestinationPath
135 );
136 static HRESULT CopyPayload(
130 - __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress,
137 + __in BURN_CACHE_PROGRESS_CONTEXT* pProgress,
138 __in HANDLE hSourceFile,
139 __in_z LPCWSTR wzSourcePath,
140 __in_z LPCWSTR wzDestinationPath
141 );
142 static HRESULT DownloadPayload(
136 - __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress,
143 + __in BURN_CACHE_PROGRESS_CONTEXT* pProgress,
144 __in_z LPCWSTR wzDestinationPath
145 );
146 static HRESULT CompleteCacheProgress(
140 - __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pContext,
147 + __in BURN_CACHE_PROGRESS_CONTEXT* pContext,
148 __in DWORD64 qwFileSize
149 );
150 static DWORD CALLBACK CacheProgressRoutine(
@@ -921,13 +928,6 @@ static HRESULT ApplyLayoutContainer(
928 hr = LayoutOrCacheContainerOrPayload(pContext, pContainer, NULL, NULL, TRUE, cTryAgainAttempts, &fRetry);
929 if (SUCCEEDED(hr))
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;
932 }
933 else
@@ -988,13 +988,6 @@ static HRESULT ApplyProcessPayload(
988 hr = LayoutOrCacheContainerOrPayload(pContext, NULL, pPackage, pPayload, FALSE, cTryAgainAttempts, &fRetry);
989 if (SUCCEEDED(hr))
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;
991 break;
992 }
993 else
@@ -1092,10 +1085,12 @@ static HRESULT LayoutBundle(
1085 LPWSTR sczDestinationPath = NULL;
1086 int nEquivalentPaths = 0;
1087 BOOTSTRAPPER_CACHE_OPERATION cacheOperation = BOOTSTRAPPER_CACHE_OPERATION_NONE;
1095 - BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT progress = { };
1088 + BURN_CACHE_PROGRESS_CONTEXT progress = { };
1089 BOOL fRetry = FALSE;
1090 BOOL fRetryAcquire = FALSE;
1091
1092 + progress.pCacheContext = pContext;
1093 +
1094 hr = VariableGetString(pContext->pVariables, BURN_BUNDLE_SOURCE_PROCESS_PATH, &sczBundlePath);
1095 if (FAILED(hr))
1096 {
@@ -1122,12 +1117,11 @@ static HRESULT LayoutBundle(
1117 ExitFunction1(hr = S_OK);
1118 }
1119
1125 - progress.pCacheContext = pContext;
1126 -
1120 do
1121 {
1122 hr = S_OK;
1123 fRetry = FALSE;
1124 + progress.type = BURN_CACHE_PROGRESS_TYPE_ACQUIRE;
1125
1126 for (;;)
1127 {
@@ -1156,6 +1150,8 @@ static HRESULT LayoutBundle(
1150 break;
1151 }
1152
1153 + progress.type = BURN_CACHE_PROGRESS_TYPE_VERIFY;
1154 +
1155 do
1156 {
1157 hr = UserExperienceOnCacheVerifyBegin(pContext->pUX, NULL, NULL);
@@ -1170,6 +1166,11 @@ static HRESULT LayoutBundle(
1166 hr = CacheLayoutBundle(wzExecutableName, pContext->wzLayoutDirectory, wzUnverifiedPath);
1167 }
1168
1169 + if (SUCCEEDED(hr))
1170 + {
1171 + hr = CompleteCacheProgress(&progress, qwBundleSize);
1172 + }
1173 +
1174 BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE;
1175 UserExperienceOnCacheVerifyComplete(pContext->pUX, NULL, NULL, hr, &action);
1176 if (BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYVERIFICATION == action)
@@ -1189,8 +1190,6 @@ static HRESULT LayoutBundle(
1190 } while (fRetry);
1191 LogExitOnFailure(hr, MSG_FAILED_LAYOUT_BUNDLE, "Failed to layout bundle: %ls to layout directory: %ls", sczBundlePath, pContext->wzLayoutDirectory);
1192
1192 - pContext->qwSuccessfulCacheProgress += qwBundleSize;
1193 -
1193 LExit:
1194 ReleaseStr(sczDestinationPath);
1195 ReleaseStr(sczBundleDownloadUrl);
@@ -1209,10 +1208,11 @@ static HRESULT ApplyAcquireContainerOrPayload(
1208 AssertSz(pContainer || pPayload, "Must provide a container or a payload.");
1209
1210 HRESULT hr = S_OK;
1212 - BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT progress = { };
1211 + BURN_CACHE_PROGRESS_CONTEXT progress = { };
1212 BOOL fRetry = FALSE;
1213
1214 progress.pCacheContext = pContext;
1215 + progress.type = BURN_CACHE_PROGRESS_TYPE_ACQUIRE;
1216 progress.pContainer = pContainer;
1217 progress.pPackage = pPackage;
1218 progress.pPayload = pPayload;
@@ -1235,7 +1235,7 @@ LExit:
1235 }
1236
1237 static HRESULT AcquireContainerOrPayload(
1238 - __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress,
1238 + __in BURN_CACHE_PROGRESS_CONTEXT* pProgress,
1239 __out BOOL* pfRetry
1240 )
1241 {
@@ -1373,6 +1373,7 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1373 LPCWSTR wzUnverifiedPath = pContainer ? pContainer->sczUnverifiedPath : pPayload->sczUnverifiedPath;
1374 LPCWSTR wzPayloadId = pPayload ? pPayload->sczKey : L"";
1375 BOOL fCanAffectRegistration = FALSE;
1376 + BURN_CACHE_PROGRESS_CONTEXT progress = { };
1377
1378 if (!pContext->wzLayoutDirectory)
1379 {
@@ -1383,6 +1384,11 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1384 }
1385
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;
1392
1393 do
1394 {
@@ -1409,6 +1415,11 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1415 hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, wzUnverifiedPath, fMove);
1416 }
1417
1418 + if (SUCCEEDED(hr))
1419 + {
1420 + hr = CompleteCacheProgress(&progress, pContainer ? pContainer->qwFileSize : pPayload->qwFileSize);
1421 + }
1422 +
1423 if (SUCCEEDED(hr) && fCanAffectRegistration)
1424 {
1425 pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
@@ -1460,7 +1471,7 @@ LExit:
1471 }
1472
1473 static HRESULT CopyPayload(
1463 - __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress,
1474 + __in BURN_CACHE_PROGRESS_CONTEXT* pProgress,
1475 __in HANDLE hSourceFile,
1476 __in_z LPCWSTR wzSourcePath,
1477 __in_z LPCWSTR wzDestinationPath
@@ -1522,7 +1533,7 @@ LExit:
1533 }
1534
1535 static HRESULT DownloadPayload(
1525 - __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pProgress,
1536 + __in BURN_CACHE_PROGRESS_CONTEXT* pProgress,
1537 __in_z LPCWSTR wzDestinationPath
1538 )
1539 {
@@ -1618,7 +1629,7 @@ LExit:
1629 }
1630
1631 static HRESULT CompleteCacheProgress(
1621 - __in BURN_CACHE_ACQUIRE_PROGRESS_CONTEXT* pContext,
1632 + __in BURN_CACHE_PROGRESS_CONTEXT* pContext,
1633 __in DWORD64 qwFileSize
1634 )
1635 {
@@ -1634,6 +1645,12 @@ static HRESULT CompleteCacheProgress(
1645 if (PROGRESS_CONTINUE == dwResult)
1646 {
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 + }
1654 }
1655 else if (PROGRESS_CANCEL == dwResult)
1656 {
@@ -1664,7 +1681,7 @@ static DWORD CALLBACK CacheProgressRoutine(
1681 {
1682 HRESULT hr = S_OK;
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);
1685 LPCWSTR wzPackageOrContainerId = pProgress->pContainer ? pProgress->pContainer->sczId : pProgress->pPackage ? pProgress->pPackage->sczId : NULL;
1686 LPCWSTR wzPayloadId = pProgress->pPayload ? pProgress->pPayload->sczKey : NULL;
1687 DWORD64 qwCacheProgress = pProgress->pCacheContext->qwSuccessfulCacheProgress + TotalBytesTransferred.QuadPart;
@@ -1675,8 +1692,17 @@ static DWORD CALLBACK CacheProgressRoutine(
1692 }
1693 DWORD dwOverallPercentage = pProgress->pCacheContext->qwTotalCacheSize ? static_cast<DWORD>(qwCacheProgress * 100 / pProgress->pCacheContext->qwTotalCacheSize) : 0;
1694
1678 - hr = UserExperienceOnCacheAcquireProgress(pProgress->pCacheContext->pUX, wzPackageOrContainerId, wzPayloadId, TotalBytesTransferred.QuadPart, TotalFileSize.QuadPart, dwOverallPercentage);
1679 - ExitOnRootFailure(hr, "BA aborted acquire of %hs: %ls", pProgress->pContainer ? "container" : "payload", pProgress->pContainer ? wzPackageOrContainerId : wzPayloadId);
1695 + switch (pProgress->type)
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 + }
1706
1707 LExit:
1708 if (HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT) == hr)
src/engine/userexperience.cpp
+34
@@ -732,6 +732,40 @@ LExit:
732 return hr;
733 }
734
735 +EXTERN_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 +
765 +LExit:
766 + return hr;
767 +}
768 +
769 EXTERN_C BAAPI UserExperienceOnCommitMsiTransactionBegin(
770 __in BURN_USER_EXPERIENCE* pUserExperience,
771 __in LPCWSTR wzTransactionId
src/engine/userexperience.h
+8
@@ -189,6 +189,14 @@ BAAPI UserExperienceOnCacheVerifyComplete(
189 __in HRESULT hrStatus,
190 __inout BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION* pAction
191 );
192 +BAAPI 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 + );
200 BAAPI UserExperienceOnCommitMsiTransactionBegin(
201 __in BURN_USER_EXPERIENCE* pUserExperience,
202 __in LPCWSTR wzTransactionId