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