Make sure OnCache*Begin events always pair with their complete event.
Sean Hall committed
Apr 16, 2021 at 13:53 UTC
26151ceeb5c57e3fd0bf73e9c13d8d72b41cce74
1 file changed
+85
-36
src/engine/apply.cpp
+85
-36
@@ -802,26 +802,34 @@ static HRESULT ApplyCachePackage(
802
)
803
{
804
HRESULT hr = S_OK;
805
+ BOOL fCanceledBegin = FALSE;
806
BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION cachePackageCompleteAction = BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE;
807
808
for (;;)
809
{
809
- hr = UserExperienceOnCachePackageBegin(pContext->pUX, pPackage->sczId, pPackage->payloads.cItems, pPackage->payloads.qwTotalSize);
810
- LogExitOnFailure(hr, MSG_USER_CANCELED, "Cancel during cache: %ls: %ls", L"begin cache package", pPackage->sczId);
810
+ fCanceledBegin = FALSE;
811
812
- for (DWORD i = 0; i < pPackage->payloads.cItems; ++i)
812
+ hr = UserExperienceOnCachePackageBegin(pContext->pUX, pPackage->sczId, pPackage->payloads.cItems, pPackage->payloads.qwTotalSize);
813
+ if (FAILED(hr))
814
{
814
- BURN_PAYLOAD_GROUP_ITEM* pPayloadGroupItem = pPackage->payloads.rgItems + i;
815
-
816
- hr = ApplyProcessPayload(pContext, pPackage, pPayloadGroupItem);
817
- if (FAILED(hr))
815
+ fCanceledBegin = TRUE;
816
+ }
817
+ else
818
+ {
819
+ for (DWORD i = 0; i < pPackage->payloads.cItems; ++i)
820
{
819
- break;
821
+ BURN_PAYLOAD_GROUP_ITEM* pPayloadGroupItem = pPackage->payloads.rgItems + i;
822
+
823
+ hr = ApplyProcessPayload(pContext, pPackage, pPayloadGroupItem);
824
+ if (FAILED(hr))
825
+ {
826
+ break;
827
+ }
828
}
829
}
830
831
pPackage->hrCacheResult = hr;
824
- cachePackageCompleteAction = SUCCEEDED(hr) || pPackage->fVital ? BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE : BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_IGNORE;
832
+ cachePackageCompleteAction = SUCCEEDED(hr) || pPackage->fVital || fCanceledBegin ? BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE : BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_IGNORE;
833
UserExperienceOnCachePackageComplete(pContext->pUX, pPackage->sczId, hr, &cachePackageCompleteAction);
834
835
if (SUCCEEDED(hr))
@@ -856,6 +864,10 @@ static HRESULT ApplyCachePackage(
864
LogId(REPORT_STANDARD, MSG_APPLY_CONTINUING_NONVITAL_PACKAGE, pPackage->sczId, hr);
865
hr = S_OK;
866
}
867
+ else if (fCanceledBegin)
868
+ {
869
+ LogExitOnFailure(hr, MSG_USER_CANCELED, "Cancel during cache: %ls: %ls", L"begin cache package", pPackage->sczId);
870
+ }
871
872
break;
873
}
@@ -1208,6 +1220,7 @@ static HRESULT LayoutBundle(
1220
BURN_CACHE_PROGRESS_CONTEXT progress = { };
1221
BOOL fRetry = FALSE;
1222
BOOL fRetryAcquire = FALSE;
1223
+ BOOL fCanceledBegin = FALSE;
1224
1225
progress.pCacheContext = pContext;
1226
@@ -1259,17 +1272,24 @@ static HRESULT LayoutBundle(
1272
{
1273
fRetryAcquire = FALSE;
1274
progress.fCancel = FALSE;
1275
+ fCanceledBegin = FALSE;
1276
1277
hr = UserExperienceOnCacheAcquireBegin(pContext->pUX, NULL, NULL, &sczBundlePath, &sczBundleDownloadUrl, NULL, &cacheOperation);
1264
- ExitOnRootFailure(hr, "BA aborted cache acquire begin.");
1278
1266
- hr = CopyPayload(&progress, pContext->hSourceEngineFile, sczBundlePath, wzUnverifiedPath);
1267
- // Error handling happens after sending complete message to BA.
1268
-
1269
- // If succeeded, send 100% complete here to make sure progress was sent to the BA.
1270
- if (SUCCEEDED(hr))
1279
+ if (FAILED(hr))
1280
{
1272
- hr = CompleteCacheProgress(&progress, qwBundleSize);
1281
+ fCanceledBegin = TRUE;
1282
+ }
1283
+ else
1284
+ {
1285
+ hr = CopyPayload(&progress, pContext->hSourceEngineFile, sczBundlePath, wzUnverifiedPath);
1286
+ // Error handling happens after sending complete message to BA.
1287
+
1288
+ // If succeeded, send 100% complete here to make sure progress was sent to the BA.
1289
+ if (SUCCEEDED(hr))
1290
+ {
1291
+ hr = CompleteCacheProgress(&progress, qwBundleSize);
1292
+ }
1293
}
1294
1295
UserExperienceOnCacheAcquireComplete(pContext->pUX, NULL, NULL, hr, &fRetryAcquire);
@@ -1277,6 +1297,10 @@ static HRESULT LayoutBundle(
1297
{
1298
continue;
1299
}
1300
+ else if (fCanceledBegin)
1301
+ {
1302
+ ExitOnRootFailure(hr, "BA aborted cache acquire begin.");
1303
+ }
1304
1305
ExitOnFailure(hr, "Failed to copy bundle from: '%ls' to: '%ls'", sczBundlePath, wzUnverifiedPath);
1306
break;
@@ -1286,14 +1310,22 @@ static HRESULT LayoutBundle(
1310
1311
do
1312
{
1289
- hr = UserExperienceOnCacheVerifyBegin(pContext->pUX, NULL, NULL);
1290
- ExitOnRootFailure(hr, "BA aborted cache verify begin.");
1313
+ fCanceledBegin = FALSE;
1314
1292
- hr = CacheLayoutBundle(wzExecutableName, pContext->wzLayoutDirectory, wzUnverifiedPath);
1315
+ hr = UserExperienceOnCacheVerifyBegin(pContext->pUX, NULL, NULL);
1316
1294
- if (SUCCEEDED(hr))
1317
+ if (FAILED(hr))
1318
{
1296
- hr = CompleteCacheProgress(&progress, qwBundleSize);
1319
+ fCanceledBegin = TRUE;
1320
+ }
1321
+ else
1322
+ {
1323
+ hr = CacheLayoutBundle(wzExecutableName, pContext->wzLayoutDirectory, wzUnverifiedPath);
1324
+
1325
+ if (SUCCEEDED(hr))
1326
+ {
1327
+ hr = CompleteCacheProgress(&progress, qwBundleSize);
1328
+ }
1329
}
1330
1331
BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE;
@@ -1306,6 +1338,10 @@ static HRESULT LayoutBundle(
1338
{
1339
fRetry = TRUE; // go back and retry acquire.
1340
}
1341
+ else if (fCanceledBegin)
1342
+ {
1343
+ ExitOnRootFailure(hr, "BA aborted cache verify begin.");
1344
+ }
1345
} while (S_FALSE == hr);
1346
1347
if (fRetry)
@@ -1500,6 +1536,7 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1536
BOOL fCanAffectRegistration = FALSE;
1537
BURN_CACHE_PROGRESS_CONTEXT progress = { };
1538
BOOL fMove = !pPayload || 1 == pPayload->cRemainingInstances;
1539
+ BOOL fCanceledBegin = FALSE;
1540
1541
if (pContainer)
1542
{
@@ -1529,27 +1566,35 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1566
1567
do
1568
{
1569
+ fCanceledBegin = FALSE;
1570
+
1571
hr = UserExperienceOnCacheVerifyBegin(pContext->pUX, wzPackageOrContainerId, wzPayloadId);
1533
- ExitOnRootFailure(hr, "BA aborted cache verify begin.");
1572
1535
- if (pContext->wzLayoutDirectory) // layout the container or payload.
1573
+ if (FAILED(hr))
1574
+ {
1575
+ fCanceledBegin = TRUE;
1576
+ }
1577
+ else
1578
{
1537
- if (pContainer)
1579
+ if (pContext->wzLayoutDirectory) // layout the container or payload.
1580
{
1539
- hr = CacheLayoutContainer(pContainer, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove);
1581
+ if (pContainer)
1582
+ {
1583
+ hr = CacheLayoutContainer(pContainer, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove);
1584
+ }
1585
+ else
1586
+ {
1587
+ hr = CacheLayoutPayload(pPayload, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove);
1588
+ }
1589
}
1541
- else
1590
+ else if (INVALID_HANDLE_VALUE != pContext->hPipe) // pass the decision off to the elevated process.
1591
{
1543
- hr = CacheLayoutPayload(pPayload, pContext->wzLayoutDirectory, wzUnverifiedPath, fMove);
1592
+ hr = ElevationCacheCompletePayload(pContext->hPipe, pPackage, pPayload, wzUnverifiedPath, fMove);
1593
+ }
1594
+ else // complete the payload.
1595
+ {
1596
+ hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, wzUnverifiedPath, fMove);
1597
}
1545
- }
1546
- else if (INVALID_HANDLE_VALUE != pContext->hPipe) // pass the decision off to the elevated process.
1547
- {
1548
- hr = ElevationCacheCompletePayload(pContext->hPipe, pPackage, pPayload, wzUnverifiedPath, fMove);
1549
- }
1550
- else // complete the payload.
1551
- {
1552
- hr = CacheCompletePayload(pPackage->fPerMachine, pPayload, pPackage->sczCacheId, wzUnverifiedPath, fMove);
1598
}
1599
1600
if (SUCCEEDED(hr))
@@ -1562,7 +1607,7 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1607
pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
1608
}
1609
1565
- BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = FAILED(hr) && cTryAgainAttempts < BURN_CACHE_MAX_RECOMMENDED_VERIFY_TRYAGAIN_ATTEMPTS ? BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYACQUISITION : BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE;
1610
+ BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION action = FAILED(hr) && !fCanceledBegin && cTryAgainAttempts < BURN_CACHE_MAX_RECOMMENDED_VERIFY_TRYAGAIN_ATTEMPTS ? BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYACQUISITION : BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_NONE;
1611
UserExperienceOnCacheVerifyComplete(pContext->pUX, wzPackageOrContainerId, wzPayloadId, hr, &action);
1612
if (BOOTSTRAPPER_CACHEVERIFYCOMPLETE_ACTION_RETRYVERIFICATION == action)
1613
{
@@ -1572,6 +1617,10 @@ static HRESULT LayoutOrCacheContainerOrPayload(
1617
{
1618
*pfRetry = TRUE; // go back and retry acquire.
1619
}
1620
+ else if (fCanceledBegin)
1621
+ {
1622
+ ExitOnRootFailure(hr, "BA aborted cache verify begin.");
1623
+ }
1624
} while (S_FALSE == hr);
1625
1626
if (SUCCEEDED(hr) && pPayloadGroupItem)