aboutsummaryrefslogtreecommitdiff
path: root/src/burn
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2022-06-14 15:09:49 -0500
committerSean Hall <r.sean.hall@gmail.com>2022-06-14 21:51:14 -0500
commitdea657295df261bb0e3e4d620eeae321531e3a11 (patch)
tree718a4b3c9697a2b6e926ad74404dc22f2cc4d22b /src/burn
parent6f6e4ced9f398ff37a44b91fdba62479cde29d06 (diff)
downloadwix-dea657295df261bb0e3e4d620eeae321531e3a11.tar.gz
wix-dea657295df261bb0e3e4d620eeae321531e3a11.tar.bz2
wix-dea657295df261bb0e3e4d620eeae321531e3a11.zip
Add ability for non-vital cache package action.
Diffstat (limited to 'src/burn')
-rw-r--r--src/burn/engine/apply.cpp51
-rw-r--r--src/burn/engine/core.cpp2
-rw-r--r--src/burn/engine/engine.mc4
-rw-r--r--src/burn/engine/logging.cpp29
-rw-r--r--src/burn/engine/logging.h8
-rw-r--r--src/burn/engine/package.h12
-rw-r--r--src/burn/engine/plan.cpp111
-rw-r--r--src/burn/engine/plan.h5
-rw-r--r--src/burn/engine/userexperience.cpp40
-rw-r--r--src/burn/engine/userexperience.h9
-rw-r--r--src/burn/test/BurnUnitTest/PlanTest.cpp179
11 files changed, 323 insertions, 127 deletions
diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp
index 048cd98b..d215cfe5 100644
--- a/src/burn/engine/apply.cpp
+++ b/src/burn/engine/apply.cpp
@@ -110,7 +110,8 @@ static HRESULT ApplyLayoutContainer(
110static HRESULT ApplyProcessPayload( 110static HRESULT ApplyProcessPayload(
111 __in BURN_CACHE_CONTEXT* pContext, 111 __in BURN_CACHE_CONTEXT* pContext,
112 __in_opt BURN_PACKAGE* pPackage, 112 __in_opt BURN_PACKAGE* pPackage,
113 __in BURN_PAYLOAD_GROUP_ITEM* pPayloadGroupItem 113 __in BURN_PAYLOAD_GROUP_ITEM* pPayloadGroupItem,
114 __in BOOL fVital
114 ); 115 );
115static HRESULT ApplyCacheVerifyContainerOrPayload( 116static HRESULT ApplyCacheVerifyContainerOrPayload(
116 __in BURN_CACHE_CONTEXT* pContext, 117 __in BURN_CACHE_CONTEXT* pContext,
@@ -203,6 +204,10 @@ static HRESULT DoRollbackActions(
203 __in DWORD dwCheckpoint, 204 __in DWORD dwCheckpoint,
204 __out BOOTSTRAPPER_APPLY_RESTART* pRestart 205 __out BOOTSTRAPPER_APPLY_RESTART* pRestart
205 ); 206 );
207static BOOL ShouldSkipPackage(
208 __in BURN_PACKAGE* pPackage,
209 __in BOOL fRollback
210 );
206static HRESULT ExecuteRelatedBundle( 211static HRESULT ExecuteRelatedBundle(
207 __in BURN_ENGINE_STATE* pEngineState, 212 __in BURN_ENGINE_STATE* pEngineState,
208 __in BURN_EXECUTE_ACTION* pExecuteAction, 213 __in BURN_EXECUTE_ACTION* pExecuteAction,
@@ -379,6 +384,7 @@ extern "C" void ApplyReset(
379 { 384 {
380 BURN_PACKAGE* pPackage = pPackages->rgPackages + i; 385 BURN_PACKAGE* pPackage = pPackages->rgPackages + i;
381 pPackage->hrCacheResult = S_OK; 386 pPackage->hrCacheResult = S_OK;
387 pPackage->fAcquireOptionalSource = FALSE;
382 pPackage->fReachedExecution = FALSE; 388 pPackage->fReachedExecution = FALSE;
383 pPackage->fAbandonedProcess = FALSE; 389 pPackage->fAbandonedProcess = FALSE;
384 pPackage->transactionRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; 390 pPackage->transactionRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
@@ -633,7 +639,7 @@ extern "C" HRESULT ApplyCache(
633 break; 639 break;
634 640
635 case BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT: 641 case BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT:
636 if (!::SetEvent(pCacheAction->syncpoint.hEvent)) 642 if (!::SetEvent(pCacheAction->syncpoint.pPackage->hCacheEvent))
637 { 643 {
638 ExitWithLastError(hr, "Failed to set syncpoint event."); 644 ExitWithLastError(hr, "Failed to set syncpoint event.");
639 } 645 }
@@ -959,12 +965,13 @@ static HRESULT ApplyCachePackage(
959 HRESULT hr = S_OK; 965 HRESULT hr = S_OK;
960 BOOL fCanceledBegin = FALSE; 966 BOOL fCanceledBegin = FALSE;
961 BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION cachePackageCompleteAction = BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE; 967 BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION cachePackageCompleteAction = BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE;
968 BOOL fVital = pPackage->fCacheVital;
962 969
963 for (;;) 970 for (;;)
964 { 971 {
965 fCanceledBegin = FALSE; 972 fCanceledBegin = FALSE;
966 973
967 hr = UserExperienceOnCachePackageBegin(pContext->pUX, pPackage->sczId, pPackage->payloads.cItems, pPackage->payloads.qwTotalSize); 974 hr = UserExperienceOnCachePackageBegin(pContext->pUX, pPackage->sczId, pPackage->payloads.cItems, pPackage->payloads.qwTotalSize, fVital);
968 if (FAILED(hr)) 975 if (FAILED(hr))
969 { 976 {
970 fCanceledBegin = TRUE; 977 fCanceledBegin = TRUE;
@@ -975,7 +982,7 @@ static HRESULT ApplyCachePackage(
975 { 982 {
976 BURN_PAYLOAD_GROUP_ITEM* pPayloadGroupItem = pPackage->payloads.rgItems + i; 983 BURN_PAYLOAD_GROUP_ITEM* pPayloadGroupItem = pPackage->payloads.rgItems + i;
977 984
978 hr = ApplyProcessPayload(pContext, pPackage, pPayloadGroupItem); 985 hr = ApplyProcessPayload(pContext, pPackage, pPayloadGroupItem, fVital);
979 if (FAILED(hr)) 986 if (FAILED(hr))
980 { 987 {
981 break; 988 break;
@@ -984,7 +991,7 @@ static HRESULT ApplyCachePackage(
984 } 991 }
985 992
986 pPackage->hrCacheResult = hr; 993 pPackage->hrCacheResult = hr;
987 cachePackageCompleteAction = SUCCEEDED(hr) || pPackage->fVital || fCanceledBegin ? BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE : BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_IGNORE; 994 cachePackageCompleteAction = SUCCEEDED(hr) || (pPackage->fVital && fVital) || fCanceledBegin ? BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_NONE : BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_IGNORE;
988 UserExperienceOnCachePackageComplete(pContext->pUX, pPackage->sczId, hr, &cachePackageCompleteAction); 995 UserExperienceOnCachePackageComplete(pContext->pUX, pPackage->sczId, hr, &cachePackageCompleteAction);
989 996
990 if (SUCCEEDED(hr)) 997 if (SUCCEEDED(hr))
@@ -1014,7 +1021,7 @@ static HRESULT ApplyCachePackage(
1014 1021
1015 continue; 1022 continue;
1016 } 1023 }
1017 else if (BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_IGNORE == cachePackageCompleteAction && !pPackage->fVital) // ignore non-vital download failures. 1024 else if (BOOTSTRAPPER_CACHEPACKAGECOMPLETE_ACTION_IGNORE == cachePackageCompleteAction && (!pPackage->fVital || !fVital)) // ignore non-vital download failures.
1018 { 1025 {
1019 LogId(REPORT_STANDARD, MSG_CACHE_CONTINUING_NONVITAL_PACKAGE, pPackage->sczId, hr); 1026 LogId(REPORT_STANDARD, MSG_CACHE_CONTINUING_NONVITAL_PACKAGE, pPackage->sczId, hr);
1020 hr = S_OK; 1027 hr = S_OK;
@@ -1101,7 +1108,7 @@ static HRESULT ApplyLayoutBundle(
1101 { 1108 {
1102 BURN_PAYLOAD_GROUP_ITEM* pPayloadGroupItem = pPayloads->rgItems + i; 1109 BURN_PAYLOAD_GROUP_ITEM* pPayloadGroupItem = pPayloads->rgItems + i;
1103 1110
1104 hr = ApplyProcessPayload(pContext, NULL, pPayloadGroupItem); 1111 hr = ApplyProcessPayload(pContext, NULL, pPayloadGroupItem, TRUE);
1105 ExitOnFailure(hr, "Failed to layout bundle payload: %ls", pPayloadGroupItem->pPayload->sczKey); 1112 ExitOnFailure(hr, "Failed to layout bundle payload: %ls", pPayloadGroupItem->pPayload->sczKey);
1106 } 1113 }
1107 1114
@@ -1164,12 +1171,14 @@ LExit:
1164static HRESULT ApplyProcessPayload( 1171static HRESULT ApplyProcessPayload(
1165 __in BURN_CACHE_CONTEXT* pContext, 1172 __in BURN_CACHE_CONTEXT* pContext,
1166 __in_opt BURN_PACKAGE* pPackage, 1173 __in_opt BURN_PACKAGE* pPackage,
1167 __in BURN_PAYLOAD_GROUP_ITEM* pPayloadGroupItem 1174 __in BURN_PAYLOAD_GROUP_ITEM* pPayloadGroupItem,
1175 __in BOOL fVital
1168 ) 1176 )
1169{ 1177{
1170 HRESULT hr = S_OK; 1178 HRESULT hr = S_OK;
1171 DWORD cTryAgainAttempts = 0; 1179 DWORD cTryAgainAttempts = 0;
1172 BOOL fRetry = FALSE; 1180 BOOL fRetry = FALSE;
1181 BOOTSTRAPPER_CACHEPACKAGENONVITALVALIDATIONFAILURE_ACTION action = BOOTSTRAPPER_CACHEPACKAGENONVITALVALIDATIONFAILURE_ACTION_NONE;
1173 BURN_PAYLOAD* pPayload = pPayloadGroupItem->pPayload; 1182 BURN_PAYLOAD* pPayload = pPayloadGroupItem->pPayload;
1174 1183
1175 Assert(pContext->pPayloads && pPackage || pContext->wzLayoutDirectory); 1184 Assert(pContext->pPayloads && pPackage || pContext->wzLayoutDirectory);
@@ -1184,6 +1193,18 @@ static HRESULT ApplyProcessPayload(
1184 { 1193 {
1185 ExitFunction(); 1194 ExitFunction();
1186 } 1195 }
1196 else if (pPackage && !pPackage->fAcquireOptionalSource && !fVital)
1197 {
1198 HRESULT hrResponse = UserExperienceOnCachePackageNonVitalValidationFailure(pContext->pUX, pPackage->sczId, hr, &action);
1199 ExitOnRootFailure(hrResponse, "BA aborted cache package non-vital failure.");
1200
1201 if (BOOTSTRAPPER_CACHEPACKAGENONVITALVALIDATIONFAILURE_ACTION_ACQUIRE != action)
1202 {
1203 ExitFunction();
1204 }
1205
1206 pPackage->fAcquireOptionalSource = TRUE;
1207 }
1187 1208
1188 for (;;) 1209 for (;;)
1189 { 1210 {
@@ -2567,10 +2588,20 @@ static BOOL ShouldSkipPackage(
2567 ) 2588 )
2568{ 2589{
2569 BOOL fSkip = FALSE; 2590 BOOL fSkip = FALSE;
2591 BURN_CACHE_PACKAGE_TYPE cachePackageType = fRollback ? pPackage->rollbackCacheType : pPackage->executeCacheType;
2592 BOOL fCacheVital = BURN_CACHE_PACKAGE_TYPE_REQUIRED == cachePackageType;
2570 2593
2571 if (FAILED(pPackage->hrCacheResult)) 2594 if (fCacheVital && FAILED(pPackage->hrCacheResult))
2572 { 2595 {
2573 LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pPackage->sczId, pPackage->hrCacheResult); 2596 if (fRollback)
2597 {
2598 LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_ROLLBACK_NO_CACHE, pPackage->sczId, pPackage->hrCacheResult, LoggingActionStateToString(pPackage->rollback));
2599 }
2600 else
2601 {
2602 LogId(REPORT_STANDARD, MSG_APPLY_SKIPPED_FAILED_CACHED_PACKAGE, pPackage->sczId, pPackage->hrCacheResult);
2603 }
2604
2574 ExitFunction1(fSkip = TRUE); 2605 ExitFunction1(fSkip = TRUE);
2575 } 2606 }
2576 else if (fRollback && pPackage->fAbandonedProcess) 2607 else if (fRollback && pPackage->fAbandonedProcess)
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp
index 8dfa0010..c1e3a12c 100644
--- a/src/burn/engine/core.cpp
+++ b/src/burn/engine/core.cpp
@@ -2329,7 +2329,7 @@ static void LogPackages(
2329 LogRollbackBoundary(pPackage->pRollbackBoundaryBackward); 2329 LogRollbackBoundary(pPackage->pRollbackBoundaryBackward);
2330 } 2330 }
2331 2331
2332 LogId(REPORT_STANDARD, MSG_PLANNED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingRequestStateToString(pPackage->defaultRequested), LoggingRequestStateToString(pPackage->requested), LoggingActionStateToString(pPackage->execute), LoggingActionStateToString(pPackage->rollback), LoggingCacheTypeToString(pPackage->authoredCacheType), LoggingCacheTypeToString(pPackage->cacheType), LoggingBoolToString(pPackage->fPlannedCache), LoggingBoolToString(pPackage->fPlannedUncache), LoggingDependencyActionToString(pPackage->dependencyExecute), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->expectedInstallRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->expectedCacheRegistrationState)); 2332 LogId(REPORT_STANDARD, MSG_PLANNED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingRequestStateToString(pPackage->defaultRequested), LoggingRequestStateToString(pPackage->requested), LoggingActionStateToString(pPackage->execute), LoggingActionStateToString(pPackage->rollback), LoggingCacheTypeToString(pPackage->authoredCacheType), LoggingCacheTypeToString(pPackage->cacheType), LoggingPlannedCacheToString(pPackage), LoggingBoolToString(pPackage->fPlannedUncache), LoggingDependencyActionToString(pPackage->dependencyExecute), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->expectedInstallRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->expectedCacheRegistrationState));
2333 2333
2334 if (BURN_PACKAGE_TYPE_MSI == pPackage->type) 2334 if (BURN_PACKAGE_TYPE_MSI == pPackage->type)
2335 { 2335 {
diff --git a/src/burn/engine/engine.mc b/src/burn/engine/engine.mc
index 52524edb..f5e3ca27 100644
--- a/src/burn/engine/engine.mc
+++ b/src/burn/engine/engine.mc
@@ -417,9 +417,9 @@ Planned related bundle: %1!ls!, detect type: %2!hs!, default plan type: %3!hs!,
417 417
418MessageId=208 418MessageId=208
419Severity=Warning 419Severity=Warning
420SymbolicName=MSG_PLAN_DISABLING_ROLLBACK_NO_CACHE 420SymbolicName=MSG_APPLY_SKIPPED_ROLLBACK_NO_CACHE
421Language=English 421Language=English
422Plan disabled rollback due to incomplete cache for package: %1!ls!, original rollback action: %2!hs! 422Skipping apply rollback of package: %1!ls! due to cache error: 0x%2!x!, original rollback action: %3!hs!. Continuing...
423. 423.
424 424
425MessageId=209 425MessageId=209
diff --git a/src/burn/engine/logging.cpp b/src/burn/engine/logging.cpp
index 77f5079c..1020d01f 100644
--- a/src/burn/engine/logging.cpp
+++ b/src/burn/engine/logging.cpp
@@ -445,6 +445,23 @@ extern "C" LPCSTR LoggingCacheTypeToString(
445 } 445 }
446} 446}
447 447
448extern "C" LPCSTR LoggingCachePackageTypeToString(
449 BURN_CACHE_PACKAGE_TYPE cachePackageType
450 )
451{
452 switch (cachePackageType)
453 {
454 case BURN_CACHE_PACKAGE_TYPE_NONE:
455 return "None";
456 case BURN_CACHE_PACKAGE_TYPE_OPTIONAL:
457 return "Optional";
458 case BURN_CACHE_PACKAGE_TYPE_REQUIRED:
459 return "Required";
460 default:
461 return "Invalid";
462 }
463}
464
448extern "C" LPCSTR LoggingDependencyActionToString( 465extern "C" LPCSTR LoggingDependencyActionToString(
449 BURN_DEPENDENCY_ACTION action 466 BURN_DEPENDENCY_ACTION action
450 ) 467 )
@@ -669,6 +686,18 @@ extern "C" LPCSTR LoggingPerMachineToString(
669 return "PerUser"; 686 return "PerUser";
670} 687}
671 688
689extern "C" LPCSTR LoggingPlannedCacheToString(
690 __in const BURN_PACKAGE* pPackage
691 )
692{
693 if (!pPackage->hCacheEvent)
694 {
695 return "No";
696 }
697
698 return pPackage->fCacheVital ? "Vital" : "NonVital";
699}
700
672extern "C" LPCSTR LoggingRegistrationTypeToString( 701extern "C" LPCSTR LoggingRegistrationTypeToString(
673 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType 702 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
674 ) 703 )
diff --git a/src/burn/engine/logging.h b/src/burn/engine/logging.h
index 857394b9..000b04f8 100644
--- a/src/burn/engine/logging.h
+++ b/src/burn/engine/logging.h
@@ -92,6 +92,10 @@ LPCSTR LoggingCacheTypeToString(
92 BOOTSTRAPPER_CACHE_TYPE cacheType 92 BOOTSTRAPPER_CACHE_TYPE cacheType
93 ); 93 );
94 94
95LPCSTR LoggingCachePackageTypeToString(
96 BURN_CACHE_PACKAGE_TYPE cachePackageType
97 );
98
95LPCSTR LoggingDependencyActionToString( 99LPCSTR LoggingDependencyActionToString(
96 BURN_DEPENDENCY_ACTION action 100 BURN_DEPENDENCY_ACTION action
97 ); 101 );
@@ -142,6 +146,10 @@ LPCSTR LoggingPerMachineToString(
142 __in BOOL fPerMachine 146 __in BOOL fPerMachine
143 ); 147 );
144 148
149LPCSTR LoggingPlannedCacheToString(
150 __in const BURN_PACKAGE* pPackage
151 );
152
145LPCSTR LoggingRegistrationTypeToString( 153LPCSTR LoggingRegistrationTypeToString(
146 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType 154 __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
147 ); 155 );
diff --git a/src/burn/engine/package.h b/src/burn/engine/package.h
index 85f34de5..5fccf50a 100644
--- a/src/burn/engine/package.h
+++ b/src/burn/engine/package.h
@@ -16,6 +16,13 @@ typedef _BURN_PACKAGE BURN_PACKAGE;
16 16
17const DWORD BURN_PACKAGE_INVALID_PATCH_INDEX = 0x80000000; 17const DWORD BURN_PACKAGE_INVALID_PATCH_INDEX = 0x80000000;
18 18
19enum BURN_CACHE_PACKAGE_TYPE
20{
21 BURN_CACHE_PACKAGE_TYPE_NONE,
22 BURN_CACHE_PACKAGE_TYPE_OPTIONAL,
23 BURN_CACHE_PACKAGE_TYPE_REQUIRED,
24};
25
19enum BURN_EXE_DETECTION_TYPE 26enum BURN_EXE_DETECTION_TYPE
20{ 27{
21 BURN_EXE_DETECTION_TYPE_NONE, 28 BURN_EXE_DETECTION_TYPE_NONE,
@@ -277,7 +284,7 @@ typedef struct _BURN_PACKAGE
277 BOOTSTRAPPER_CACHE_TYPE cacheType; // only valid during Plan. 284 BOOTSTRAPPER_CACHE_TYPE cacheType; // only valid during Plan.
278 BOOTSTRAPPER_REQUEST_STATE defaultRequested;// only valid during Plan. 285 BOOTSTRAPPER_REQUEST_STATE defaultRequested;// only valid during Plan.
279 BOOTSTRAPPER_REQUEST_STATE requested; // only valid during Plan. 286 BOOTSTRAPPER_REQUEST_STATE requested; // only valid during Plan.
280 BOOL fPlannedCache; // only valid during Plan. 287 BOOL fCacheVital; // only valid during Plan.
281 BOOL fPlannedUncache; // only valid during Plan. 288 BOOL fPlannedUncache; // only valid during Plan.
282 BOOTSTRAPPER_ACTION_STATE execute; // only valid during Plan. 289 BOOTSTRAPPER_ACTION_STATE execute; // only valid during Plan.
283 BOOTSTRAPPER_ACTION_STATE rollback; // only valid during Plan. 290 BOOTSTRAPPER_ACTION_STATE rollback; // only valid during Plan.
@@ -286,9 +293,12 @@ typedef struct _BURN_PACKAGE
286 BURN_DEPENDENCY_ACTION dependencyExecute; // only valid during Plan. 293 BURN_DEPENDENCY_ACTION dependencyExecute; // only valid during Plan.
287 BURN_DEPENDENCY_ACTION dependencyRollback; // only valid during Plan. 294 BURN_DEPENDENCY_ACTION dependencyRollback; // only valid during Plan.
288 BOOL fDependencyManagerWasHere; // only valid during Plan. 295 BOOL fDependencyManagerWasHere; // only valid during Plan.
296 BURN_CACHE_PACKAGE_TYPE executeCacheType; // only valid during Plan.
297 BURN_CACHE_PACKAGE_TYPE rollbackCacheType; // only valid during Plan.
289 HANDLE hCacheEvent; // only valid during Plan. 298 HANDLE hCacheEvent; // only valid during Plan.
290 LPWSTR sczCacheFolder; // only valid during Apply. 299 LPWSTR sczCacheFolder; // only valid during Apply.
291 HRESULT hrCacheResult; // only valid during Apply. 300 HRESULT hrCacheResult; // only valid during Apply.
301 BOOL fAcquireOptionalSource; // only valid during Apply.
292 BOOL fReachedExecution; // only valid during Apply. 302 BOOL fReachedExecution; // only valid during Apply.
293 BOOL fAbandonedProcess; // only valid during Apply. 303 BOOL fAbandonedProcess; // only valid during Apply.
294 304
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp
index 419d3272..18f9b274 100644
--- a/src/burn/engine/plan.cpp
+++ b/src/burn/engine/plan.cpp
@@ -78,11 +78,13 @@ static HRESULT AddRegistrationAction(
78 ); 78 );
79static HRESULT AddCachePackage( 79static HRESULT AddCachePackage(
80 __in BURN_PLAN* pPlan, 80 __in BURN_PLAN* pPlan,
81 __in BURN_PACKAGE* pPackage 81 __in BURN_PACKAGE* pPackage,
82 __in BOOL fVital
82 ); 83 );
83static HRESULT AddCachePackageHelper( 84static HRESULT AddCachePackageHelper(
84 __in BURN_PLAN* pPlan, 85 __in BURN_PLAN* pPlan,
85 __in BURN_PACKAGE* pPackage 86 __in BURN_PACKAGE* pPackage,
87 __in BOOL fVital
86 ); 88 );
87static HRESULT AddCacheSlipstreamMsps( 89static HRESULT AddCacheSlipstreamMsps(
88 __in BURN_PLAN* pPlan, 90 __in BURN_PLAN* pPlan,
@@ -134,7 +136,7 @@ static HRESULT CalculateExecuteActions(
134 __in BURN_PACKAGE* pPackage, 136 __in BURN_PACKAGE* pPackage,
135 __in_opt BURN_ROLLBACK_BOUNDARY* pActiveRollbackBoundary 137 __in_opt BURN_ROLLBACK_BOUNDARY* pActiveRollbackBoundary
136 ); 138 );
137static BOOL NeedsCache( 139static BURN_CACHE_PACKAGE_TYPE GetCachePackageType(
138 __in BURN_PACKAGE* pPackage, 140 __in BURN_PACKAGE* pPackage,
139 __in BOOL fExecute 141 __in BOOL fExecute
140 ); 142 );
@@ -894,7 +896,7 @@ static HRESULT PlanPackagesHelper(
894 DWORD iPackage = fReverseOrder ? cPackages - 1 - i : i; 896 DWORD iPackage = fReverseOrder ? cPackages - 1 - i : i;
895 BURN_PACKAGE* pPackage = rgPackages + iPackage; 897 BURN_PACKAGE* pPackage = rgPackages + iPackage;
896 898
897 UserExperienceOnPlannedPackage(pUX, pPackage->sczId, pPackage->execute, pPackage->rollback, pPackage->fPlannedCache, pPackage->fPlannedUncache); 899 UserExperienceOnPlannedPackage(pUX, pPackage->sczId, pPackage->execute, pPackage->rollback, NULL != pPackage->hCacheEvent, pPackage->fPlannedUncache);
898 900
899 if (pPackage->compatiblePackage.fPlannable) 901 if (pPackage->compatiblePackage.fPlannable)
900 { 902 {
@@ -999,7 +1001,7 @@ static HRESULT ProcessPackage(
999 { 1001 {
1000 if (BOOTSTRAPPER_REQUEST_STATE_NONE != pPackage->requested) 1002 if (BOOTSTRAPPER_REQUEST_STATE_NONE != pPackage->requested)
1001 { 1003 {
1002 hr = PlanLayoutPackage(pPlan, pPackage); 1004 hr = PlanLayoutPackage(pPlan, pPackage, TRUE);
1003 ExitOnFailure(hr, "Failed to plan layout package."); 1005 ExitOnFailure(hr, "Failed to plan layout package.");
1004 } 1006 }
1005 } 1007 }
@@ -1015,7 +1017,7 @@ static HRESULT ProcessPackage(
1015 { 1017 {
1016 if (ForceCache(pPlan, pPackage)) 1018 if (ForceCache(pPlan, pPackage))
1017 { 1019 {
1018 hr = AddCachePackage(pPlan, pPackage); 1020 hr = AddCachePackage(pPlan, pPackage, TRUE);
1019 ExitOnFailure(hr, "Failed to plan cache package."); 1021 ExitOnFailure(hr, "Failed to plan cache package.");
1020 1022
1021 if (pPackage->fPerMachine) 1023 if (pPackage->fPerMachine)
@@ -1127,7 +1129,8 @@ LExit:
1127 1129
1128extern "C" HRESULT PlanLayoutPackage( 1130extern "C" HRESULT PlanLayoutPackage(
1129 __in BURN_PLAN* pPlan, 1131 __in BURN_PLAN* pPlan,
1130 __in BURN_PACKAGE* pPackage 1132 __in BURN_PACKAGE* pPackage,
1133 __in BOOL fVital
1131 ) 1134 )
1132{ 1135{
1133 HRESULT hr = S_OK; 1136 HRESULT hr = S_OK;
@@ -1143,6 +1146,7 @@ extern "C" HRESULT PlanLayoutPackage(
1143 1146
1144 pCacheAction->type = BURN_CACHE_ACTION_TYPE_PACKAGE; 1147 pCacheAction->type = BURN_CACHE_ACTION_TYPE_PACKAGE;
1145 pCacheAction->package.pPackage = pPackage; 1148 pCacheAction->package.pPackage = pPackage;
1149 pPackage->fCacheVital = fVital;
1146 1150
1147 ++pPlan->cOverallProgressTicksTotal; 1151 ++pPlan->cOverallProgressTicksTotal;
1148 1152
@@ -1170,18 +1174,14 @@ extern "C" HRESULT PlanExecutePackage(
1170 hr = DependencyPlanPackageBegin(fPerMachine, pPackage, pPlan); 1174 hr = DependencyPlanPackageBegin(fPerMachine, pPackage, pPlan);
1171 ExitOnFailure(hr, "Failed to begin plan dependency actions for package: %ls", pPackage->sczId); 1175 ExitOnFailure(hr, "Failed to begin plan dependency actions for package: %ls", pPackage->sczId);
1172 1176
1173 if (fRequestedCache || NeedsCache(pPackage, TRUE)) 1177 pPackage->executeCacheType = fRequestedCache ? BURN_CACHE_PACKAGE_TYPE_REQUIRED : GetCachePackageType(pPackage, TRUE);
1178 pPackage->rollbackCacheType = GetCachePackageType(pPackage, FALSE);
1179
1180 if (BURN_CACHE_PACKAGE_TYPE_NONE != pPackage->executeCacheType || BURN_CACHE_PACKAGE_TYPE_NONE != pPackage->rollbackCacheType)
1174 { 1181 {
1175 hr = AddCachePackage(pPlan, pPackage); 1182 hr = AddCachePackage(pPlan, pPackage, BURN_CACHE_PACKAGE_TYPE_REQUIRED == pPackage->executeCacheType);
1176 ExitOnFailure(hr, "Failed to plan cache package."); 1183 ExitOnFailure(hr, "Failed to plan cache package.");
1177 } 1184 }
1178 else if (!pPackage->fCached && NeedsCache(pPackage, FALSE))
1179 {
1180 // TODO: this decision should be made during apply instead of plan based on whether the package is actually cached.
1181 // If the package is not in the cache, disable any rollback that would require the package from the cache.
1182 LogId(REPORT_STANDARD, MSG_PLAN_DISABLING_ROLLBACK_NO_CACHE, pPackage->sczId, LoggingActionStateToString(pPackage->rollback));
1183 pPackage->rollback = BOOTSTRAPPER_ACTION_STATE_NONE;
1184 }
1185 1185
1186 // Add execute actions. 1186 // Add execute actions.
1187 switch (pPackage->type) 1187 switch (pPackage->type)
@@ -1364,6 +1364,8 @@ extern "C" HRESULT PlanRelatedBundlesInitialize(
1364 pRelatedBundle->package.requested = BOOTSTRAPPER_REQUEST_STATE_NONE; 1364 pRelatedBundle->package.requested = BOOTSTRAPPER_REQUEST_STATE_NONE;
1365 pRelatedBundle->defaultPlanRelationType = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_NONE; 1365 pRelatedBundle->defaultPlanRelationType = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_NONE;
1366 pRelatedBundle->planRelationType = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_NONE; 1366 pRelatedBundle->planRelationType = BOOTSTRAPPER_RELATED_BUNDLE_PLAN_TYPE_NONE;
1367 pRelatedBundle->package.executeCacheType = BURN_CACHE_PACKAGE_TYPE_NONE;
1368 pRelatedBundle->package.rollbackCacheType = BURN_CACHE_PACKAGE_TYPE_NONE;
1367 1369
1368 // Determine the plan relation type even if later it is ignored due to the planned action, the command relation type, or the related bundle not being plannable. 1370 // Determine the plan relation type even if later it is ignored due to the planned action, the command relation type, or the related bundle not being plannable.
1369 // This gives more information to the BA in case it wants to override default behavior. 1371 // This gives more information to the BA in case it wants to override default behavior.
@@ -2088,10 +2090,6 @@ static void UninitializeCacheAction(
2088{ 2090{
2089 switch (pCacheAction->type) 2091 switch (pCacheAction->type)
2090 { 2092 {
2091 case BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT:
2092 ReleaseHandle(pCacheAction->syncpoint.hEvent);
2093 break;
2094
2095 case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE: 2093 case BURN_CACHE_ACTION_TYPE_LAYOUT_BUNDLE:
2096 ReleaseStr(pCacheAction->bundleLayout.sczExecutableName); 2094 ReleaseStr(pCacheAction->bundleLayout.sczExecutableName);
2097 ReleaseStr(pCacheAction->bundleLayout.sczUnverifiedPath); 2095 ReleaseStr(pCacheAction->bundleLayout.sczUnverifiedPath);
@@ -2145,7 +2143,7 @@ static void ResetPlannedPackageState(
2145 pPackage->cacheType = pPackage->authoredCacheType; 2143 pPackage->cacheType = pPackage->authoredCacheType;
2146 pPackage->defaultRequested = BOOTSTRAPPER_REQUEST_STATE_NONE; 2144 pPackage->defaultRequested = BOOTSTRAPPER_REQUEST_STATE_NONE;
2147 pPackage->requested = BOOTSTRAPPER_REQUEST_STATE_NONE; 2145 pPackage->requested = BOOTSTRAPPER_REQUEST_STATE_NONE;
2148 pPackage->fPlannedCache = FALSE; 2146 pPackage->fCacheVital = FALSE;
2149 pPackage->fPlannedUncache = FALSE; 2147 pPackage->fPlannedUncache = FALSE;
2150 pPackage->execute = BOOTSTRAPPER_ACTION_STATE_NONE; 2148 pPackage->execute = BOOTSTRAPPER_ACTION_STATE_NONE;
2151 pPackage->rollback = BOOTSTRAPPER_ACTION_STATE_NONE; 2149 pPackage->rollback = BOOTSTRAPPER_ACTION_STATE_NONE;
@@ -2156,7 +2154,9 @@ static void ResetPlannedPackageState(
2156 pPackage->fDependencyManagerWasHere = FALSE; 2154 pPackage->fDependencyManagerWasHere = FALSE;
2157 pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; 2155 pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
2158 pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; 2156 pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
2159 pPackage->hCacheEvent = NULL; 2157 pPackage->executeCacheType = BURN_CACHE_PACKAGE_TYPE_NONE;
2158 pPackage->rollbackCacheType = BURN_CACHE_PACKAGE_TYPE_NONE;
2159 ReleaseHandle(pPackage->hCacheEvent);
2160 2160
2161 ReleaseNullStr(pPackage->sczCacheFolder); 2161 ReleaseNullStr(pPackage->sczCacheFolder);
2162 2162
@@ -2314,19 +2314,21 @@ LExit:
2314 2314
2315static HRESULT AddCachePackage( 2315static HRESULT AddCachePackage(
2316 __in BURN_PLAN* pPlan, 2316 __in BURN_PLAN* pPlan,
2317 __in BURN_PACKAGE* pPackage 2317 __in BURN_PACKAGE* pPackage,
2318 __in BOOL fVital
2318 ) 2319 )
2319{ 2320{
2320 HRESULT hr = S_OK; 2321 HRESULT hr = S_OK;
2321 2322
2322 // If this is an MSI package with slipstream MSPs, ensure the MSPs are cached first. 2323 // If this is an MSI package with slipstream MSPs, ensure the MSPs are cached first.
2323 if (BURN_PACKAGE_TYPE_MSI == pPackage->type && 0 < pPackage->Msi.cSlipstreamMspPackages) 2324 // TODO: Slipstream packages are not accounted for when caching the MSI package is optional.
2325 if (BURN_PACKAGE_TYPE_MSI == pPackage->type && 0 < pPackage->Msi.cSlipstreamMspPackages && fVital)
2324 { 2326 {
2325 hr = AddCacheSlipstreamMsps(pPlan, pPackage); 2327 hr = AddCacheSlipstreamMsps(pPlan, pPackage);
2326 ExitOnFailure(hr, "Failed to plan slipstream patches for package."); 2328 ExitOnFailure(hr, "Failed to plan slipstream patches for package.");
2327 } 2329 }
2328 2330
2329 hr = AddCachePackageHelper(pPlan, pPackage); 2331 hr = AddCachePackageHelper(pPlan, pPackage, fVital);
2330 ExitOnFailure(hr, "Failed to plan cache package."); 2332 ExitOnFailure(hr, "Failed to plan cache package.");
2331 2333
2332LExit: 2334LExit:
@@ -2335,7 +2337,8 @@ LExit:
2335 2337
2336static HRESULT AddCachePackageHelper( 2338static HRESULT AddCachePackageHelper(
2337 __in BURN_PLAN* pPlan, 2339 __in BURN_PLAN* pPlan,
2338 __in BURN_PACKAGE* pPackage 2340 __in BURN_PACKAGE* pPackage,
2341 __in BOOL fVital
2339 ) 2342 )
2340{ 2343{
2341 AssertSz(pPackage->sczCacheId && *pPackage->sczCacheId, "AddCachePackageHelper() expects the package to have a cache id."); 2344 AssertSz(pPackage->sczCacheId && *pPackage->sczCacheId, "AddCachePackageHelper() expects the package to have a cache id.");
@@ -2354,6 +2357,9 @@ static HRESULT AddCachePackageHelper(
2354 ExitFunction(); 2357 ExitFunction();
2355 } 2358 }
2356 2359
2360 pPackage->hCacheEvent = ::CreateEventW(NULL, TRUE, FALSE, NULL);
2361 ExitOnNullWithLastError(pPackage->hCacheEvent, hr, "Failed to create syncpoint event.");
2362
2357 // Cache checkpoints happen before the package is cached because downloading packages' 2363 // Cache checkpoints happen before the package is cached because downloading packages'
2358 // payloads will not roll themselves back the way installation packages rollback on 2364 // payloads will not roll themselves back the way installation packages rollback on
2359 // failure automatically. 2365 // failure automatically.
@@ -2381,7 +2387,7 @@ static HRESULT AddCachePackageHelper(
2381 pCacheAction->checkpoint.dwId = dwCheckpoint; 2387 pCacheAction->checkpoint.dwId = dwCheckpoint;
2382 } 2388 }
2383 2389
2384 hr = PlanLayoutPackage(pPlan, pPackage); 2390 hr = PlanLayoutPackage(pPlan, pPackage, fVital);
2385 ExitOnFailure(hr, "Failed to plan cache for package."); 2391 ExitOnFailure(hr, "Failed to plan cache for package.");
2386 2392
2387 // Create syncpoint action. 2393 // Create syncpoint action.
@@ -2389,15 +2395,11 @@ static HRESULT AddCachePackageHelper(
2389 ExitOnFailure(hr, "Failed to append cache action."); 2395 ExitOnFailure(hr, "Failed to append cache action.");
2390 2396
2391 pCacheAction->type = BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT; 2397 pCacheAction->type = BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT;
2392 pCacheAction->syncpoint.hEvent = ::CreateEventW(NULL, TRUE, FALSE, NULL); 2398 pCacheAction->syncpoint.pPackage = pPackage;
2393 ExitOnNullWithLastError(pCacheAction->syncpoint.hEvent, hr, "Failed to create syncpoint event.");
2394
2395 pPackage->hCacheEvent = pCacheAction->syncpoint.hEvent;
2396 2399
2397 hr = PlanExecuteCacheSyncAndRollback(pPlan, pPackage); 2400 hr = PlanExecuteCacheSyncAndRollback(pPlan, pPackage);
2398 ExitOnFailure(hr, "Failed to plan package cache syncpoint"); 2401 ExitOnFailure(hr, "Failed to plan package cache syncpoint");
2399 2402
2400 pPackage->fPlannedCache = TRUE;
2401 if (pPackage->fCanAffectRegistration) 2403 if (pPackage->fCanAffectRegistration)
2402 { 2404 {
2403 pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT; 2405 pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
@@ -2421,7 +2423,7 @@ static HRESULT AddCacheSlipstreamMsps(
2421 BURN_PACKAGE* pMspPackage = pPackage->Msi.rgSlipstreamMsps[i].pMspPackage; 2423 BURN_PACKAGE* pMspPackage = pPackage->Msi.rgSlipstreamMsps[i].pMspPackage;
2422 AssertSz(BURN_PACKAGE_TYPE_MSP == pMspPackage->type, "Only MSP packages can be slipstream patches."); 2424 AssertSz(BURN_PACKAGE_TYPE_MSP == pMspPackage->type, "Only MSP packages can be slipstream patches.");
2423 2425
2424 hr = AddCachePackageHelper(pPlan, pMspPackage); 2426 hr = AddCachePackageHelper(pPlan, pMspPackage, TRUE);
2425 ExitOnFailure(hr, "Failed to plan slipstream MSP: %ls", pMspPackage->sczId); 2427 ExitOnFailure(hr, "Failed to plan slipstream MSP: %ls", pMspPackage->sczId);
2426 } 2428 }
2427 2429
@@ -2791,22 +2793,41 @@ LExit:
2791 return hr; 2793 return hr;
2792} 2794}
2793 2795
2794static BOOL NeedsCache( 2796static BURN_CACHE_PACKAGE_TYPE GetCachePackageType(
2795 __in BURN_PACKAGE* pPackage, 2797 __in BURN_PACKAGE* pPackage,
2796 __in BOOL fExecute 2798 __in BOOL fExecute
2797 ) 2799 )
2798{ 2800{
2799 BOOTSTRAPPER_ACTION_STATE action = fExecute ? pPackage->execute : pPackage->rollback; 2801 BURN_CACHE_PACKAGE_TYPE cachePackageType = BURN_CACHE_PACKAGE_TYPE_NONE;
2800 // TODO: bundles could theoretically use package cache 2802
2801 if (BURN_PACKAGE_TYPE_BUNDLE == pPackage->type || // Bundle and Exe packages require the package for all operations (even uninstall). 2803 switch (fExecute ? pPackage->execute : pPackage->rollback)
2802 BURN_PACKAGE_TYPE_EXE == pPackage->type && BURN_EXE_DETECTION_TYPE_ARP != pPackage->Exe.detectionType)
2803 {
2804 return BOOTSTRAPPER_ACTION_STATE_NONE != action;
2805 }
2806 else // The other package types can uninstall without the original package.
2807 { 2804 {
2808 return BOOTSTRAPPER_ACTION_STATE_UNINSTALL < action; 2805 case BOOTSTRAPPER_ACTION_STATE_NONE:
2806 break;
2807 case BOOTSTRAPPER_ACTION_STATE_UNINSTALL:
2808 if (BURN_PACKAGE_TYPE_BUNDLE == pPackage->type ||
2809 BURN_PACKAGE_TYPE_EXE == pPackage->type && BURN_EXE_DETECTION_TYPE_ARP != pPackage->Exe.detectionType)
2810 {
2811 // Bundle and non-ArpEntry Exe packages require the package for all operations (even uninstall).
2812 // TODO: bundles could theoretically use package cache.
2813 cachePackageType = BURN_CACHE_PACKAGE_TYPE_REQUIRED;
2814 }
2815 else
2816 {
2817 // The other package types can uninstall without the original package.
2818 cachePackageType = BURN_CACHE_PACKAGE_TYPE_NONE;
2819 }
2820 break;
2821 case BOOTSTRAPPER_ACTION_STATE_INSTALL: __fallthrough;
2822 case BOOTSTRAPPER_ACTION_STATE_MODIFY: __fallthrough;
2823 case BOOTSTRAPPER_ACTION_STATE_REPAIR: __fallthrough;
2824 case BOOTSTRAPPER_ACTION_STATE_MINOR_UPGRADE: __fallthrough;
2825 default:
2826 cachePackageType = BURN_CACHE_PACKAGE_TYPE_REQUIRED;
2827 break;
2809 } 2828 }
2829
2830 return cachePackageType;
2810} 2831}
2811 2832
2812static BOOL ForceCache( 2833static BOOL ForceCache(
@@ -2881,7 +2902,7 @@ static void CacheActionLog(
2881 break; 2902 break;
2882 2903
2883 case BURN_CACHE_ACTION_TYPE_PACKAGE: 2904 case BURN_CACHE_ACTION_TYPE_PACKAGE:
2884 LogStringLine(PlanDumpLevel, "%ls action[%u]: PACKAGE id: %ls", wzBase, iAction, pAction->package.pPackage->sczId); 2905 LogStringLine(PlanDumpLevel, "%ls action[%u]: PACKAGE id: %ls, vital: %hs, execute cache type: %hs, rollback cache type: %hs", wzBase, iAction, pAction->package.pPackage->sczId, LoggingBoolToString(pAction->package.pPackage->fCacheVital), LoggingCachePackageTypeToString(pAction->package.pPackage->executeCacheType), LoggingCachePackageTypeToString(pAction->package.pPackage->rollbackCacheType));
2885 break; 2906 break;
2886 2907
2887 case BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE: 2908 case BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE:
@@ -2889,7 +2910,7 @@ static void CacheActionLog(
2889 break; 2910 break;
2890 2911
2891 case BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT: 2912 case BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT:
2892 LogStringLine(PlanDumpLevel, "%ls action[%u]: SIGNAL_SYNCPOINT event handle: 0x%p", wzBase, iAction, pAction->syncpoint.hEvent); 2913 LogStringLine(PlanDumpLevel, "%ls action[%u]: SIGNAL_SYNCPOINT package id: %ls, event handle: 0x%p", wzBase, iAction, pAction->syncpoint.pPackage->sczId, pAction->syncpoint.pPackage->hCacheEvent);
2893 break; 2914 break;
2894 2915
2895 default: 2916 default:
diff --git a/src/burn/engine/plan.h b/src/burn/engine/plan.h
index 46a9a363..386de2c6 100644
--- a/src/burn/engine/plan.h
+++ b/src/burn/engine/plan.h
@@ -117,7 +117,7 @@ typedef struct _BURN_CACHE_ACTION
117 } rollbackPackage; 117 } rollbackPackage;
118 struct 118 struct
119 { 119 {
120 HANDLE hEvent; 120 BURN_PACKAGE* pPackage;
121 } syncpoint; 121 } syncpoint;
122 struct 122 struct
123 { 123 {
@@ -392,7 +392,8 @@ HRESULT PlanLayoutContainer(
392 ); 392 );
393HRESULT PlanLayoutPackage( 393HRESULT PlanLayoutPackage(
394 __in BURN_PLAN* pPlan, 394 __in BURN_PLAN* pPlan,
395 __in BURN_PACKAGE* pPackage 395 __in BURN_PACKAGE* pPackage,
396 __in BOOL fVital
396 ); 397 );
397HRESULT PlanExecutePackage( 398HRESULT PlanExecutePackage(
398 __in BOOL fPerMachine, 399 __in BOOL fPerMachine,
diff --git a/src/burn/engine/userexperience.cpp b/src/burn/engine/userexperience.cpp
index 87ef4de1..a97234ef 100644
--- a/src/burn/engine/userexperience.cpp
+++ b/src/burn/engine/userexperience.cpp
@@ -104,7 +104,7 @@ extern "C" HRESULT UserExperienceLoad(
104 args.pCommand = pCommand; 104 args.pCommand = pCommand;
105 args.pfnBootstrapperEngineProc = EngineForApplicationProc; 105 args.pfnBootstrapperEngineProc = EngineForApplicationProc;
106 args.pvBootstrapperEngineProcContext = pEngineContext; 106 args.pvBootstrapperEngineProcContext = pEngineContext;
107 args.qwEngineAPIVersion = MAKEQWORDVERSION(2022, 3, 31, 0); 107 args.qwEngineAPIVersion = MAKEQWORDVERSION(2022, 6, 10, 0);
108 108
109 results.cbSize = sizeof(BOOTSTRAPPER_CREATE_RESULTS); 109 results.cbSize = sizeof(BOOTSTRAPPER_CREATE_RESULTS);
110 110
@@ -726,7 +726,8 @@ EXTERN_C BAAPI UserExperienceOnCachePackageBegin(
726 __in BURN_USER_EXPERIENCE* pUserExperience, 726 __in BURN_USER_EXPERIENCE* pUserExperience,
727 __in_z LPCWSTR wzPackageId, 727 __in_z LPCWSTR wzPackageId,
728 __in DWORD cCachePayloads, 728 __in DWORD cCachePayloads,
729 __in DWORD64 dw64PackageCacheSize 729 __in DWORD64 dw64PackageCacheSize,
730 __in BOOL fVital
730 ) 731 )
731{ 732{
732 HRESULT hr = S_OK; 733 HRESULT hr = S_OK;
@@ -737,6 +738,7 @@ EXTERN_C BAAPI UserExperienceOnCachePackageBegin(
737 args.wzPackageId = wzPackageId; 738 args.wzPackageId = wzPackageId;
738 args.cCachePayloads = cCachePayloads; 739 args.cCachePayloads = cCachePayloads;
739 args.dw64PackageCacheSize = dw64PackageCacheSize; 740 args.dw64PackageCacheSize = dw64PackageCacheSize;
741 args.fVital = fVital;
740 742
741 results.cbSize = sizeof(results); 743 results.cbSize = sizeof(results);
742 744
@@ -783,6 +785,40 @@ LExit:
783 return hr; 785 return hr;
784} 786}
785 787
788EXTERN_C BAAPI UserExperienceOnCachePackageNonVitalValidationFailure(
789 __in BURN_USER_EXPERIENCE* pUserExperience,
790 __in_z LPCWSTR wzPackageId,
791 __in HRESULT hrStatus,
792 __inout BOOTSTRAPPER_CACHEPACKAGENONVITALVALIDATIONFAILURE_ACTION* pAction
793 )
794{
795 HRESULT hr = S_OK;
796 BA_ONCACHEPACKAGENONVITALVALIDATIONFAILURE_ARGS args = { };
797 BA_ONCACHEPACKAGENONVITALVALIDATIONFAILURE_RESULTS results = { };
798
799 args.cbSize = sizeof(args);
800 args.wzPackageId = wzPackageId;
801 args.hrStatus = hrStatus;
802 args.recommendation = *pAction;
803
804 results.cbSize = sizeof(results);
805 results.action = *pAction;
806
807 hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONCACHEPACKAGENONVITALVALIDATIONFAILURE, &args, &results);
808 ExitOnFailure(hr, "BA OnCachePackageNonVitalValidationFailure failed.");
809
810 switch (results.action)
811 {
812 case BOOTSTRAPPER_CACHEPACKAGENONVITALVALIDATIONFAILURE_ACTION_NONE: __fallthrough;
813 case BOOTSTRAPPER_CACHEPACKAGENONVITALVALIDATIONFAILURE_ACTION_ACQUIRE:
814 *pAction = results.action;
815 break;
816 }
817
818LExit:
819 return hr;
820}
821
786EXTERN_C BAAPI UserExperienceOnCachePayloadExtractBegin( 822EXTERN_C BAAPI UserExperienceOnCachePayloadExtractBegin(
787 __in BURN_USER_EXPERIENCE* pUserExperience, 823 __in BURN_USER_EXPERIENCE* pUserExperience,
788 __in_z_opt LPCWSTR wzContainerId, 824 __in_z_opt LPCWSTR wzContainerId,
diff --git a/src/burn/engine/userexperience.h b/src/burn/engine/userexperience.h
index 94b73f7d..9f183208 100644
--- a/src/burn/engine/userexperience.h
+++ b/src/burn/engine/userexperience.h
@@ -189,7 +189,14 @@ BAAPI UserExperienceOnCachePackageBegin(
189 __in BURN_USER_EXPERIENCE* pUserExperience, 189 __in BURN_USER_EXPERIENCE* pUserExperience,
190 __in_z LPCWSTR wzPackageId, 190 __in_z LPCWSTR wzPackageId,
191 __in DWORD cCachePayloads, 191 __in DWORD cCachePayloads,
192 __in DWORD64 dw64PackageCacheSize 192 __in DWORD64 dw64PackageCacheSize,
193 __in BOOL fVital
194 );
195BAAPI UserExperienceOnCachePackageNonVitalValidationFailure(
196 __in BURN_USER_EXPERIENCE* pUserExperience,
197 __in_z LPCWSTR wzPackageId,
198 __in HRESULT hrStatus,
199 __inout BOOTSTRAPPER_CACHEPACKAGENONVITALVALIDATIONFAILURE_ACTION* pAction
193 ); 200 );
194BAAPI UserExperienceOnCachePackageComplete( 201BAAPI UserExperienceOnCachePackageComplete(
195 __in BURN_USER_EXPERIENCE* pUserExperience, 202 __in BURN_USER_EXPERIENCE* pUserExperience,
diff --git a/src/burn/test/BurnUnitTest/PlanTest.cpp b/src/burn/test/BurnUnitTest/PlanTest.cpp
index 2135d9f5..37027ada 100644
--- a/src/burn/test/BurnUnitTest/PlanTest.cpp
+++ b/src/burn/test/BurnUnitTest/PlanTest.cpp
@@ -87,8 +87,8 @@ namespace Bootstrapper
87 fRollback = FALSE; 87 fRollback = FALSE;
88 dwIndex = 0; 88 dwIndex = 0;
89 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); 89 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
90 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"TestExe"); 90 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"TestExe", TRUE, BURN_CACHE_PACKAGE_TYPE_REQUIRED, BURN_CACHE_PACKAGE_TYPE_NONE);
91 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); 91 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"TestExe");
92 Assert::Equal(dwIndex, pPlan->cCacheActions); 92 Assert::Equal(dwIndex, pPlan->cCacheActions);
93 93
94 fRollback = TRUE; 94 fRollback = TRUE;
@@ -259,19 +259,24 @@ namespace Bootstrapper
259 259
260 fRollback = FALSE; 260 fRollback = FALSE;
261 dwIndex = 0; 261 dwIndex = 0;
262 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
263 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"TestExe", FALSE, BURN_CACHE_PACKAGE_TYPE_NONE, BURN_CACHE_PACKAGE_TYPE_REQUIRED);
264 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"TestExe");
262 Assert::Equal(dwIndex, pPlan->cCacheActions); 265 Assert::Equal(dwIndex, pPlan->cCacheActions);
263 266
264 fRollback = TRUE; 267 fRollback = TRUE;
265 dwIndex = 0; 268 dwIndex = 0;
266 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); 269 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
267 270
268 Assert::Equal(0ull, pPlan->qwCacheSizeTotal); 271 Assert::Equal(143724ull, pPlan->qwCacheSizeTotal);
269 272
270 fRollback = FALSE; 273 fRollback = FALSE;
271 dwIndex = 0; 274 dwIndex = 0;
272 DWORD dwExecuteCheckpointId = 1; 275 DWORD dwExecuteCheckpointId = 2;
273 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); 276 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
274 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 277 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
278 ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"TestExe");
279 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
275 ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"TestExe", BOOTSTRAPPER_ACTION_STATE_UNINSTALL); 280 ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"TestExe", BOOTSTRAPPER_ACTION_STATE_UNINSTALL);
276 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 281 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
277 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 282 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -280,8 +285,9 @@ namespace Bootstrapper
280 285
281 fRollback = TRUE; 286 fRollback = TRUE;
282 dwIndex = 0; 287 dwIndex = 0;
283 dwExecuteCheckpointId = 1; 288 dwExecuteCheckpointId = 2;
284 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); 289 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
290 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
285 ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"TestExe", BOOTSTRAPPER_ACTION_STATE_INSTALL); 291 ValidateExecuteExePackage(pPlan, fRollback, dwIndex++, L"TestExe", BOOTSTRAPPER_ACTION_STATE_INSTALL);
286 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 292 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
287 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 293 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -290,7 +296,7 @@ namespace Bootstrapper
290 Assert::Equal(dwIndex, pPlan->cRollbackActions); 296 Assert::Equal(dwIndex, pPlan->cRollbackActions);
291 297
292 Assert::Equal(1ul, pPlan->cExecutePackagesTotal); 298 Assert::Equal(1ul, pPlan->cExecutePackagesTotal);
293 Assert::Equal(1ul, pPlan->cOverallProgressTicksTotal); 299 Assert::Equal(2ul, pPlan->cOverallProgressTicksTotal);
294 300
295 dwIndex = 0; 301 dwIndex = 0;
296 Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions); 302 Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions);
@@ -347,14 +353,14 @@ namespace Bootstrapper
347 fRollback = FALSE; 353 fRollback = FALSE;
348 dwIndex = 0; 354 dwIndex = 0;
349 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); 355 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
350 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); 356 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA", TRUE, BURN_CACHE_PACKAGE_TYPE_REQUIRED, BURN_CACHE_PACKAGE_TYPE_NONE);
351 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); 357 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PackageA");
352 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 9); 358 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 9);
353 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageB"); 359 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageB", TRUE, BURN_CACHE_PACKAGE_TYPE_REQUIRED, BURN_CACHE_PACKAGE_TYPE_NONE);
354 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); 360 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PackageB");
355 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 14); 361 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 14);
356 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageC"); 362 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageC", TRUE, BURN_CACHE_PACKAGE_TYPE_REQUIRED, BURN_CACHE_PACKAGE_TYPE_NONE);
357 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); 363 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PackageC");
358 Assert::Equal(dwIndex, pPlan->cCacheActions); 364 Assert::Equal(dwIndex, pPlan->cCacheActions);
359 365
360 fRollback = TRUE; 366 fRollback = TRUE;
@@ -506,13 +512,16 @@ namespace Bootstrapper
506 512
507 fRollback = FALSE; 513 fRollback = FALSE;
508 dwIndex = 0; 514 dwIndex = 0;
515 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 9);
516 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA", FALSE, BURN_CACHE_PACKAGE_TYPE_NONE, BURN_CACHE_PACKAGE_TYPE_REQUIRED);
517 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PackageA");
509 Assert::Equal(dwIndex, pPlan->cCacheActions); 518 Assert::Equal(dwIndex, pPlan->cCacheActions);
510 519
511 fRollback = TRUE; 520 fRollback = TRUE;
512 dwIndex = 0; 521 dwIndex = 0;
513 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); 522 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
514 523
515 Assert::Equal(0ull, pPlan->qwCacheSizeTotal); 524 Assert::Equal(185118ull, pPlan->qwCacheSizeTotal);
516 525
517 fRollback = FALSE; 526 fRollback = FALSE;
518 dwIndex = 0; 527 dwIndex = 0;
@@ -536,6 +545,9 @@ namespace Bootstrapper
536 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 545 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
537 ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); 546 ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++);
538 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); 547 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
548 dwExecuteCheckpointId += 1; // cache checkpoints
549 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
550 ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
539 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 551 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
540 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", unregisterActions1, 1); 552 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", unregisterActions1, 1);
541 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 553 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -565,6 +577,8 @@ namespace Bootstrapper
565 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 577 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
566 ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); 578 ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++);
567 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); 579 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
580 dwExecuteCheckpointId += 1; // cache checkpoints
581 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
568 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", registerActions1, 1); 582 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", registerActions1, 1);
569 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 583 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
570 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", registerActions1, 1); 584 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", registerActions1, 1);
@@ -577,7 +591,7 @@ namespace Bootstrapper
577 Assert::Equal(dwIndex, pPlan->cRollbackActions); 591 Assert::Equal(dwIndex, pPlan->cRollbackActions);
578 592
579 Assert::Equal(3ul, pPlan->cExecutePackagesTotal); 593 Assert::Equal(3ul, pPlan->cExecutePackagesTotal);
580 Assert::Equal(3ul, pPlan->cOverallProgressTicksTotal); 594 Assert::Equal(4ul, pPlan->cOverallProgressTicksTotal);
581 595
582 dwIndex = 0; 596 dwIndex = 0;
583 Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions); 597 Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions);
@@ -640,11 +654,11 @@ namespace Bootstrapper
640 fRollback = FALSE; 654 fRollback = FALSE;
641 dwIndex = 0; 655 dwIndex = 0;
642 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); 656 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
643 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); 657 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA", TRUE, BURN_CACHE_PACKAGE_TYPE_REQUIRED, BURN_CACHE_PACKAGE_TYPE_REQUIRED);
644 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); 658 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PackageA");
645 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 6); 659 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 6);
646 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageB"); 660 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageB", TRUE, BURN_CACHE_PACKAGE_TYPE_REQUIRED, BURN_CACHE_PACKAGE_TYPE_REQUIRED);
647 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); 661 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PackageB");
648 Assert::Equal(dwIndex, pPlan->cCacheActions); 662 Assert::Equal(dwIndex, pPlan->cCacheActions);
649 663
650 fRollback = TRUE; 664 fRollback = TRUE;
@@ -753,8 +767,8 @@ namespace Bootstrapper
753 fRollback = FALSE; 767 fRollback = FALSE;
754 dwIndex = 0; 768 dwIndex = 0;
755 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 2); 769 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 2);
756 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageB"); 770 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageB", TRUE, BURN_CACHE_PACKAGE_TYPE_REQUIRED, BURN_CACHE_PACKAGE_TYPE_NONE);
757 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); 771 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PackageB");
758 Assert::Equal(dwIndex, pPlan->cCacheActions); 772 Assert::Equal(dwIndex, pPlan->cCacheActions);
759 773
760 fRollback = TRUE; 774 fRollback = TRUE;
@@ -949,8 +963,8 @@ namespace Bootstrapper
949 fRollback = FALSE; 963 fRollback = FALSE;
950 dwIndex = 0; 964 dwIndex = 0;
951 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); 965 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
952 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); 966 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA", TRUE, BURN_CACHE_PACKAGE_TYPE_REQUIRED, BURN_CACHE_PACKAGE_TYPE_NONE);
953 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); 967 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PackageA");
954 Assert::Equal(dwIndex, pPlan->cCacheActions); 968 Assert::Equal(dwIndex, pPlan->cCacheActions);
955 969
956 fRollback = TRUE; 970 fRollback = TRUE;
@@ -1068,8 +1082,8 @@ namespace Bootstrapper
1068 fRollback = FALSE; 1082 fRollback = FALSE;
1069 dwIndex = 0; 1083 dwIndex = 0;
1070 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); 1084 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
1071 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); 1085 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA", TRUE, BURN_CACHE_PACKAGE_TYPE_REQUIRED, BURN_CACHE_PACKAGE_TYPE_NONE);
1072 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); 1086 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PackageA");
1073 Assert::Equal(dwIndex, pPlan->cCacheActions); 1087 Assert::Equal(dwIndex, pPlan->cCacheActions);
1074 1088
1075 fRollback = TRUE; 1089 fRollback = TRUE;
@@ -1170,8 +1184,8 @@ namespace Bootstrapper
1170 fRollback = FALSE; 1184 fRollback = FALSE;
1171 dwIndex = 0; 1185 dwIndex = 0;
1172 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); 1186 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
1173 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"ExeA"); 1187 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"ExeA", TRUE, BURN_CACHE_PACKAGE_TYPE_REQUIRED, BURN_CACHE_PACKAGE_TYPE_REQUIRED);
1174 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); 1188 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"ExeA");
1175 Assert::Equal(dwIndex, pPlan->cCacheActions); 1189 Assert::Equal(dwIndex, pPlan->cCacheActions);
1176 1190
1177 fRollback = TRUE; 1191 fRollback = TRUE;
@@ -1264,8 +1278,8 @@ namespace Bootstrapper
1264 fRollback = FALSE; 1278 fRollback = FALSE;
1265 dwIndex = 0; 1279 dwIndex = 0;
1266 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); 1280 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
1267 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); 1281 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA", TRUE, BURN_CACHE_PACKAGE_TYPE_REQUIRED, BURN_CACHE_PACKAGE_TYPE_NONE);
1268 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); 1282 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PackageA");
1269 Assert::Equal(dwIndex, pPlan->cCacheActions); 1283 Assert::Equal(dwIndex, pPlan->cCacheActions);
1270 1284
1271 fRollback = TRUE; 1285 fRollback = TRUE;
@@ -1515,8 +1529,8 @@ namespace Bootstrapper
1515 fRollback = FALSE; 1529 fRollback = FALSE;
1516 dwIndex = 0; 1530 dwIndex = 0;
1517 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); 1531 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
1518 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); 1532 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA", TRUE, BURN_CACHE_PACKAGE_TYPE_REQUIRED, BURN_CACHE_PACKAGE_TYPE_NONE);
1519 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); 1533 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PackageA");
1520 Assert::Equal(dwIndex, pPlan->cCacheActions); 1534 Assert::Equal(dwIndex, pPlan->cCacheActions);
1521 1535
1522 fRollback = TRUE; 1536 fRollback = TRUE;
@@ -1610,8 +1624,8 @@ namespace Bootstrapper
1610 fRollback = FALSE; 1624 fRollback = FALSE;
1611 dwIndex = 0; 1625 dwIndex = 0;
1612 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); 1626 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
1613 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); 1627 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA", TRUE, BURN_CACHE_PACKAGE_TYPE_REQUIRED, BURN_CACHE_PACKAGE_TYPE_NONE);
1614 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); 1628 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PackageA");
1615 Assert::Equal(dwIndex, pPlan->cCacheActions); 1629 Assert::Equal(dwIndex, pPlan->cCacheActions);
1616 1630
1617 fRollback = TRUE; 1631 fRollback = TRUE;
@@ -1794,19 +1808,24 @@ namespace Bootstrapper
1794 1808
1795 fRollback = FALSE; 1809 fRollback = FALSE;
1796 dwIndex = 0; 1810 dwIndex = 0;
1811 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
1812 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA", FALSE, BURN_CACHE_PACKAGE_TYPE_NONE, BURN_CACHE_PACKAGE_TYPE_REQUIRED);
1813 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PackageA");
1797 Assert::Equal(dwIndex, pPlan->cCacheActions); 1814 Assert::Equal(dwIndex, pPlan->cCacheActions);
1798 1815
1799 fRollback = TRUE; 1816 fRollback = TRUE;
1800 dwIndex = 0; 1817 dwIndex = 0;
1801 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); 1818 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
1802 1819
1803 Assert::Equal(0ull, pPlan->qwCacheSizeTotal); 1820 Assert::Equal(175674ull, pPlan->qwCacheSizeTotal);
1804 1821
1805 fRollback = FALSE; 1822 fRollback = FALSE;
1806 dwIndex = 0; 1823 dwIndex = 0;
1807 DWORD dwExecuteCheckpointId = 1; 1824 DWORD dwExecuteCheckpointId = 2;
1808 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); 1825 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
1809 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 1826 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
1827 ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
1828 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
1810 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", unregisterActions1, 1); 1829 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", unregisterActions1, 1);
1811 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 1830 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
1812 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", unregisterActions1, 1); 1831 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", unregisterActions1, 1);
@@ -1819,8 +1838,9 @@ namespace Bootstrapper
1819 1838
1820 fRollback = TRUE; 1839 fRollback = TRUE;
1821 dwIndex = 0; 1840 dwIndex = 0;
1822 dwExecuteCheckpointId = 1; 1841 dwExecuteCheckpointId = 2;
1823 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); 1842 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
1843 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
1824 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", registerActions1, 1); 1844 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", registerActions1, 1);
1825 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 1845 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
1826 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", registerActions1, 1); 1846 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", registerActions1, 1);
@@ -1833,7 +1853,7 @@ namespace Bootstrapper
1833 Assert::Equal(dwIndex, pPlan->cRollbackActions); 1853 Assert::Equal(dwIndex, pPlan->cRollbackActions);
1834 1854
1835 Assert::Equal(1ul, pPlan->cExecutePackagesTotal); 1855 Assert::Equal(1ul, pPlan->cExecutePackagesTotal);
1836 Assert::Equal(1ul, pPlan->cOverallProgressTicksTotal); 1856 Assert::Equal(2ul, pPlan->cOverallProgressTicksTotal);
1837 1857
1838 dwIndex = 0; 1858 dwIndex = 0;
1839 Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions); 1859 Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions);
@@ -2043,19 +2063,24 @@ namespace Bootstrapper
2043 2063
2044 fRollback = FALSE; 2064 fRollback = FALSE;
2045 dwIndex = 0; 2065 dwIndex = 0;
2066 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
2067 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA", FALSE, BURN_CACHE_PACKAGE_TYPE_NONE, BURN_CACHE_PACKAGE_TYPE_REQUIRED);
2068 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PackageA");
2046 Assert::Equal(dwIndex, pPlan->cCacheActions); 2069 Assert::Equal(dwIndex, pPlan->cCacheActions);
2047 2070
2048 fRollback = TRUE; 2071 fRollback = TRUE;
2049 dwIndex = 0; 2072 dwIndex = 0;
2050 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); 2073 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
2051 2074
2052 Assert::Equal(0ull, pPlan->qwCacheSizeTotal); 2075 Assert::Equal(175674ull, pPlan->qwCacheSizeTotal);
2053 2076
2054 fRollback = FALSE; 2077 fRollback = FALSE;
2055 dwIndex = 0; 2078 dwIndex = 0;
2056 DWORD dwExecuteCheckpointId = 1; 2079 DWORD dwExecuteCheckpointId = 2;
2057 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); 2080 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
2058 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 2081 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2082 ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
2083 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2059 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", unregisterActions1, 1); 2084 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", unregisterActions1, 1);
2060 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 2085 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2061 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", unregisterActions1, 1); 2086 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", unregisterActions1, 1);
@@ -2068,8 +2093,9 @@ namespace Bootstrapper
2068 2093
2069 fRollback = TRUE; 2094 fRollback = TRUE;
2070 dwIndex = 0; 2095 dwIndex = 0;
2071 dwExecuteCheckpointId = 1; 2096 dwExecuteCheckpointId = 2;
2072 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); 2097 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
2098 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2073 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", registerActions1, 1); 2099 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", registerActions1, 1);
2074 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 2100 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2075 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", registerActions1, 1); 2101 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", registerActions1, 1);
@@ -2082,7 +2108,7 @@ namespace Bootstrapper
2082 Assert::Equal(dwIndex, pPlan->cRollbackActions); 2108 Assert::Equal(dwIndex, pPlan->cRollbackActions);
2083 2109
2084 Assert::Equal(1ul, pPlan->cExecutePackagesTotal); 2110 Assert::Equal(1ul, pPlan->cExecutePackagesTotal);
2085 Assert::Equal(1ul, pPlan->cOverallProgressTicksTotal); 2111 Assert::Equal(2ul, pPlan->cOverallProgressTicksTotal);
2086 2112
2087 dwIndex = 0; 2113 dwIndex = 0;
2088 Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions); 2114 Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions);
@@ -2139,8 +2165,8 @@ namespace Bootstrapper
2139 fRollback = FALSE; 2165 fRollback = FALSE;
2140 dwIndex = 0; 2166 dwIndex = 0;
2141 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); 2167 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
2142 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"test.msu"); 2168 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"test.msu", TRUE, BURN_CACHE_PACKAGE_TYPE_REQUIRED, BURN_CACHE_PACKAGE_TYPE_NONE);
2143 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); 2169 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"test.msu");
2144 Assert::Equal(dwIndex, pPlan->cCacheActions); 2170 Assert::Equal(dwIndex, pPlan->cCacheActions);
2145 2171
2146 fRollback = TRUE; 2172 fRollback = TRUE;
@@ -2233,14 +2259,14 @@ namespace Bootstrapper
2233 fRollback = FALSE; 2259 fRollback = FALSE;
2234 dwIndex = 0; 2260 dwIndex = 0;
2235 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); 2261 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
2236 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"NetFx48Web"); 2262 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"NetFx48Web", TRUE, BURN_CACHE_PACKAGE_TYPE_REQUIRED, BURN_CACHE_PACKAGE_TYPE_NONE);
2237 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); 2263 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"NetFx48Web");
2238 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 3); 2264 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 3);
2239 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PatchA"); 2265 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PatchA", TRUE, BURN_CACHE_PACKAGE_TYPE_REQUIRED, BURN_CACHE_PACKAGE_TYPE_NONE);
2240 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); 2266 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PatchA");
2241 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 5); 2267 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 5);
2242 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); 2268 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA", TRUE, BURN_CACHE_PACKAGE_TYPE_REQUIRED, BURN_CACHE_PACKAGE_TYPE_NONE);
2243 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); 2269 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PackageA");
2244 Assert::Equal(dwIndex, pPlan->cCacheActions); 2270 Assert::Equal(dwIndex, pPlan->cCacheActions);
2245 2271
2246 fRollback = TRUE; 2272 fRollback = TRUE;
@@ -2363,26 +2389,37 @@ namespace Bootstrapper
2363 2389
2364 fRollback = FALSE; 2390 fRollback = FALSE;
2365 dwIndex = 0; 2391 dwIndex = 0;
2392 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
2393 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PatchA", FALSE, BURN_CACHE_PACKAGE_TYPE_NONE, BURN_CACHE_PACKAGE_TYPE_REQUIRED);
2394 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PatchA");
2395 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 6);
2396 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA", FALSE, BURN_CACHE_PACKAGE_TYPE_NONE, BURN_CACHE_PACKAGE_TYPE_REQUIRED);
2397 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PackageA");
2366 Assert::Equal(dwIndex, pPlan->cCacheActions); 2398 Assert::Equal(dwIndex, pPlan->cCacheActions);
2367 2399
2368 fRollback = TRUE; 2400 fRollback = TRUE;
2369 dwIndex = 0; 2401 dwIndex = 0;
2370 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); 2402 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
2371 2403
2372 Assert::Equal(0ull, pPlan->qwCacheSizeTotal); 2404 Assert::Equal(212992ull, pPlan->qwCacheSizeTotal);
2373 2405
2374 fRollback = FALSE; 2406 fRollback = FALSE;
2375 dwIndex = 0; 2407 dwIndex = 0;
2376 DWORD dwExecuteCheckpointId = 1; 2408 DWORD dwExecuteCheckpointId = 2;
2377 BURN_EXECUTE_ACTION* pExecuteAction = NULL; 2409 BURN_EXECUTE_ACTION* pExecuteAction = NULL;
2378 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); 2410 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
2379 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 2411 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2412 ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PatchA");
2413 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2380 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PatchA", L"{22D1DDBA-284D-40A7-BD14-95EA07906F21}", unregisterActions1, 1); 2414 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PatchA", L"{22D1DDBA-284D-40A7-BD14-95EA07906F21}", unregisterActions1, 1);
2381 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 2415 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2382 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PatchA", unregisterActions1, 1); 2416 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PatchA", unregisterActions1, 1);
2383 pExecuteAction = ValidateDeletedExecuteMspTarget(pPlan, fRollback, dwIndex++, L"PatchA", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, L"{5FF7F534-3FFC-41E0-80CD-E6361E5E7B7B}", TRUE, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, BOOTSTRAPPER_MSI_FILE_VERSIONING_MISSING_OR_OLDER, TRUE); 2417 pExecuteAction = ValidateDeletedExecuteMspTarget(pPlan, fRollback, dwIndex++, L"PatchA", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, L"{5FF7F534-3FFC-41E0-80CD-E6361E5E7B7B}", TRUE, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, BOOTSTRAPPER_MSI_FILE_VERSIONING_MISSING_OR_OLDER, TRUE);
2384 ValidateExecuteMspTargetPatch(pExecuteAction, 0, L"PatchA"); 2418 ValidateExecuteMspTargetPatch(pExecuteAction, 0, L"PatchA");
2385 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 2419 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2420 dwExecuteCheckpointId += 1; // cache checkpoints
2421 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2422 ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
2386 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 2423 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2387 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{22D1DDBA-284D-40A7-BD14-95EA07906F21}", unregisterActions1, 1); 2424 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{22D1DDBA-284D-40A7-BD14-95EA07906F21}", unregisterActions1, 1);
2388 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 2425 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -2396,8 +2433,9 @@ namespace Bootstrapper
2396 2433
2397 fRollback = TRUE; 2434 fRollback = TRUE;
2398 dwIndex = 0; 2435 dwIndex = 0;
2399 dwExecuteCheckpointId = 1; 2436 dwExecuteCheckpointId = 2;
2400 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); 2437 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
2438 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2401 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PatchA", L"{22D1DDBA-284D-40A7-BD14-95EA07906F21}", registerActions1, 1); 2439 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PatchA", L"{22D1DDBA-284D-40A7-BD14-95EA07906F21}", registerActions1, 1);
2402 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 2440 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2403 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PatchA", registerActions1, 1); 2441 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PatchA", registerActions1, 1);
@@ -2405,6 +2443,8 @@ namespace Bootstrapper
2405 pExecuteAction = ValidateDeletedExecuteMspTarget(pPlan, fRollback, dwIndex++, L"PatchA", BOOTSTRAPPER_ACTION_STATE_INSTALL, L"{5FF7F534-3FFC-41E0-80CD-E6361E5E7B7B}", TRUE, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, BOOTSTRAPPER_MSI_FILE_VERSIONING_MISSING_OR_OLDER, TRUE); 2443 pExecuteAction = ValidateDeletedExecuteMspTarget(pPlan, fRollback, dwIndex++, L"PatchA", BOOTSTRAPPER_ACTION_STATE_INSTALL, L"{5FF7F534-3FFC-41E0-80CD-E6361E5E7B7B}", TRUE, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, BOOTSTRAPPER_MSI_FILE_VERSIONING_MISSING_OR_OLDER, TRUE);
2406 ValidateExecuteMspTargetPatch(pExecuteAction, 0, L"PatchA"); 2444 ValidateExecuteMspTargetPatch(pExecuteAction, 0, L"PatchA");
2407 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 2445 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2446 dwExecuteCheckpointId += 1; // cache checkpoints
2447 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2408 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{22D1DDBA-284D-40A7-BD14-95EA07906F21}", registerActions1, 1); 2448 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{22D1DDBA-284D-40A7-BD14-95EA07906F21}", registerActions1, 1);
2409 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 2449 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2410 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", registerActions1, 1); 2450 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", registerActions1, 1);
@@ -2417,7 +2457,7 @@ namespace Bootstrapper
2417 Assert::Equal(dwIndex, pPlan->cRollbackActions); 2457 Assert::Equal(dwIndex, pPlan->cRollbackActions);
2418 2458
2419 Assert::Equal(2ul, pPlan->cExecutePackagesTotal); 2459 Assert::Equal(2ul, pPlan->cExecutePackagesTotal);
2420 Assert::Equal(2ul, pPlan->cOverallProgressTicksTotal); 2460 Assert::Equal(4ul, pPlan->cOverallProgressTicksTotal);
2421 2461
2422 dwIndex = 0; 2462 dwIndex = 0;
2423 Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions); 2463 Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions);
@@ -2479,19 +2519,24 @@ namespace Bootstrapper
2479 2519
2480 fRollback = FALSE; 2520 fRollback = FALSE;
2481 dwIndex = 0; 2521 dwIndex = 0;
2522 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
2523 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA", FALSE, BURN_CACHE_PACKAGE_TYPE_NONE, BURN_CACHE_PACKAGE_TYPE_REQUIRED);
2524 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PackageA");
2482 Assert::Equal(dwIndex, pPlan->cCacheActions); 2525 Assert::Equal(dwIndex, pPlan->cCacheActions);
2483 2526
2484 fRollback = TRUE; 2527 fRollback = TRUE;
2485 dwIndex = 0; 2528 dwIndex = 0;
2486 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); 2529 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
2487 2530
2488 Assert::Equal(0ull, pPlan->qwCacheSizeTotal); 2531 Assert::Equal(131072ull, pPlan->qwCacheSizeTotal);
2489 2532
2490 fRollback = FALSE; 2533 fRollback = FALSE;
2491 dwIndex = 0; 2534 dwIndex = 0;
2492 DWORD dwExecuteCheckpointId = 1; 2535 DWORD dwExecuteCheckpointId = 2;
2493 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); 2536 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
2494 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 2537 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2538 ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
2539 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2495 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{22D1DDBA-284D-40A7-BD14-95EA07906F21}", unregisterActions1, 1); 2540 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{22D1DDBA-284D-40A7-BD14-95EA07906F21}", unregisterActions1, 1);
2496 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 2541 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2497 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", unregisterActions1, 1); 2542 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", unregisterActions1, 1);
@@ -2504,8 +2549,9 @@ namespace Bootstrapper
2504 2549
2505 fRollback = TRUE; 2550 fRollback = TRUE;
2506 dwIndex = 0; 2551 dwIndex = 0;
2507 dwExecuteCheckpointId = 1; 2552 dwExecuteCheckpointId = 2;
2508 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); 2553 ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
2554 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2509 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{22D1DDBA-284D-40A7-BD14-95EA07906F21}", registerActions1, 1); 2555 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{22D1DDBA-284D-40A7-BD14-95EA07906F21}", registerActions1, 1);
2510 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 2556 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2511 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", registerActions1, 1); 2557 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", registerActions1, 1);
@@ -2518,7 +2564,7 @@ namespace Bootstrapper
2518 Assert::Equal(dwIndex, pPlan->cRollbackActions); 2564 Assert::Equal(dwIndex, pPlan->cRollbackActions);
2519 2565
2520 Assert::Equal(1ul, pPlan->cExecutePackagesTotal); 2566 Assert::Equal(1ul, pPlan->cExecutePackagesTotal);
2521 Assert::Equal(1ul, pPlan->cOverallProgressTicksTotal); 2567 Assert::Equal(2ul, pPlan->cOverallProgressTicksTotal);
2522 2568
2523 dwIndex = 0; 2569 dwIndex = 0;
2524 Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions); 2570 Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions);
@@ -2575,11 +2621,11 @@ namespace Bootstrapper
2575 fRollback = FALSE; 2621 fRollback = FALSE;
2576 dwIndex = 0; 2622 dwIndex = 0;
2577 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); 2623 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
2578 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"NetFx48Web"); 2624 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"NetFx48Web", TRUE, BURN_CACHE_PACKAGE_TYPE_REQUIRED, BURN_CACHE_PACKAGE_TYPE_NONE);
2579 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); 2625 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"NetFx48Web");
2580 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 4); 2626 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 4);
2581 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); 2627 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA", TRUE, BURN_CACHE_PACKAGE_TYPE_REQUIRED, BURN_CACHE_PACKAGE_TYPE_NONE);
2582 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); 2628 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++, L"PackageA");
2583 Assert::Equal(dwIndex, pPlan->cCacheActions); 2629 Assert::Equal(dwIndex, pPlan->cCacheActions);
2584 2630
2585 fRollback = TRUE; 2631 fRollback = TRUE;
@@ -3008,12 +3054,18 @@ namespace Bootstrapper
3008 __in BURN_PLAN* pPlan, 3054 __in BURN_PLAN* pPlan,
3009 __in BOOL fRollback, 3055 __in BOOL fRollback,
3010 __in DWORD dwIndex, 3056 __in DWORD dwIndex,
3011 __in LPCWSTR wzPackageId 3057 __in LPCWSTR wzPackageId,
3058 __in BOOL fVital,
3059 __in BURN_CACHE_PACKAGE_TYPE executeCacheType,
3060 __in BURN_CACHE_PACKAGE_TYPE rollbackCacheType
3012 ) 3061 )
3013 { 3062 {
3014 BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex); 3063 BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
3015 Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_PACKAGE, pAction->type); 3064 Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_PACKAGE, pAction->type);
3016 NativeAssert::StringEqual(wzPackageId, pAction->package.pPackage->sczId); 3065 NativeAssert::StringEqual(wzPackageId, pAction->package.pPackage->sczId);
3066 Assert::Equal<BOOL>(fVital, pAction->package.pPackage->fCacheVital);
3067 Assert::Equal<DWORD>(executeCacheType, pAction->package.pPackage->executeCacheType);
3068 Assert::Equal<DWORD>(rollbackCacheType, pAction->package.pPackage->rollbackCacheType);
3017 return dwIndex + 1; 3069 return dwIndex + 1;
3018 } 3070 }
3019 3071
@@ -3032,12 +3084,13 @@ namespace Bootstrapper
3032 void ValidateCacheSignalSyncpoint( 3084 void ValidateCacheSignalSyncpoint(
3033 __in BURN_PLAN* pPlan, 3085 __in BURN_PLAN* pPlan,
3034 __in BOOL fRollback, 3086 __in BOOL fRollback,
3035 __in DWORD dwIndex 3087 __in DWORD dwIndex,
3088 __in LPCWSTR wzPackageId
3036 ) 3089 )
3037 { 3090 {
3038 BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex); 3091 BURN_CACHE_ACTION* pAction = ValidateCacheActionExists(pPlan, fRollback, dwIndex);
3039 Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT, pAction->type); 3092 Assert::Equal<DWORD>(BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT, pAction->type);
3040 Assert::NotEqual((DWORD_PTR)NULL, (DWORD_PTR)pAction->syncpoint.hEvent); 3093 NativeAssert::StringEqual(wzPackageId, pAction->syncpoint.pPackage->sczId);
3041 } 3094 }
3042 3095
3043 void ValidateCleanAction( 3096 void ValidateCleanAction(