@joebigelow / wix / commits / 27c6deca

Put back the rollback cache package functionality and fix its bugs.

#3719, #4711, #5750

Sean Hall committed May 4, 2021 at 19:25 UTC 27c6decae94536cae338731b6cb765aa92776486
18 files changed +189 -220
src/burn/engine/apply.cpp
+58 -41
@@ -335,6 +335,7 @@ extern "C" void ApplyReset(
335 {
336 BURN_PACKAGE* pPackage = pPackages->rgPackages + i;
337 pPackage->hrCacheResult = S_OK;
338 + pPackage->fReachedExecution = FALSE;
339 pPackage->transactionRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
340 }
341 }
@@ -433,7 +434,7 @@ LExit:
434
435 extern "C" HRESULT ApplyUnregister(
436 __in BURN_ENGINE_STATE* pEngineState,
436 - __in BOOL fFailedOrRollback,
437 + __in BOOL fFailed,
438 __in BOOL fSuspend,
439 __in BOOTSTRAPPER_APPLY_RESTART restart
440 )
@@ -466,7 +467,7 @@ extern "C" HRESULT ApplyUnregister(
467
468 // If apply failed in any way and we're going to be keeping the bundle registered then
469 // execute any rollback dependency registration actions.
469 - if (fFailedOrRollback && fKeepRegistration)
470 + if (fFailed && fKeepRegistration)
471 {
472 // Execute any rollback registration actions.
473 HRESULT hrRegistrationRollback = ExecuteDependentRegistrationActions(pEngineState->companionConnection.hPipe, &pEngineState->registration, pEngineState->plan.rgRollbackRegistrationActions, pEngineState->plan.cRollbackRegistrationActions);
@@ -587,11 +588,7 @@ extern "C" HRESULT ApplyCache(
588 }
589
590 LExit:
590 - if (FAILED(hr))
591 - {
592 - DoRollbackCache(pUX, pPlan, hPipe, dwCheckpoint);
593 - pContext->fRollback = TRUE;
594 - }
591 + pContext->dwCacheCheckpoint = dwCheckpoint;
592
593 // Clean up any remanents in the cache.
594 if (INVALID_HANDLE_VALUE != hPipe)
@@ -612,6 +609,16 @@ LExit:
609 return hr;
610 }
611
612 +extern "C" void ApplyCacheRollback(
613 + __in BURN_USER_EXPERIENCE* pUX,
614 + __in BURN_PLAN* pPlan,
615 + __in HANDLE hPipe,
616 + __in BURN_APPLY_CONTEXT* pContext
617 + )
618 +{
619 + DoRollbackCache(pUX, pPlan, hPipe, pContext->dwCacheCheckpoint);
620 +}
621 +
622 extern "C" HRESULT ApplyExecute(
623 __in BURN_ENGINE_STATE* pEngineState,
624 __in BURN_APPLY_CONTEXT* pApplyContext,
@@ -687,7 +694,6 @@ extern "C" HRESULT ApplyExecute(
694 IgnoreRollbackError(hrRollback, "Failed commit transaction from disable rollback");
695 }
696
690 - pApplyContext->fRollback = TRUE;
697 break;
698 }
699
@@ -708,7 +714,6 @@ extern "C" HRESULT ApplyExecute(
714 // If the rollback boundary is vital, end execution here.
715 if (pRollbackBoundary && pRollbackBoundary->fVital)
716 {
711 - pApplyContext->fRollback = TRUE;
717 break;
718 }
719
@@ -2110,41 +2115,44 @@ static void DoRollbackCache(
2115 )
2116 {
2117 HRESULT hr = S_OK;
2113 - DWORD iCheckpoint = 0;
2118 + BURN_PACKAGE* pPackage = NULL;
2119 + DWORD dwLastCheckpoint = 0;
2120
2115 - // Scan to last checkpoint.
2116 - for (DWORD i = 0; i < pPlan->cRollbackCacheActions; ++i)
2121 + // Rollback cache actions.
2122 + for (DWORD i = pPlan->cRollbackCacheActions; i > 0; --i)
2123 {
2118 - BURN_CACHE_ACTION* pRollbackCacheAction = &pPlan->rgRollbackCacheActions[i];
2124 + BURN_CACHE_ACTION* pRollbackCacheAction = &pPlan->rgRollbackCacheActions[i - 1];
2125
2120 - if (BURN_CACHE_ACTION_TYPE_CHECKPOINT == pRollbackCacheAction->type && pRollbackCacheAction->checkpoint.dwId == dwCheckpoint)
2126 + switch (pRollbackCacheAction->type)
2127 {
2122 - iCheckpoint = i;
2128 + case BURN_CACHE_ACTION_TYPE_CHECKPOINT:
2129 + dwLastCheckpoint = pRollbackCacheAction->checkpoint.dwId;
2130 break;
2124 - }
2125 - }
2131
2127 - // Rollback cache actions.
2128 - if (iCheckpoint)
2129 - {
2130 - // i has to be a signed integer so it doesn't get decremented to 0xFFFFFFFF.
2131 - for (int i = iCheckpoint - 1; i >= 0; --i)
2132 - {
2133 - BURN_CACHE_ACTION* pRollbackCacheAction = &pPlan->rgRollbackCacheActions[i];
2132 + case BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE:
2133 + pPackage = pRollbackCacheAction->rollbackPackage.pPackage;
2134
2135 - switch (pRollbackCacheAction->type)
2135 + // If the package was executed then it's up to ApplyExecute to rollback its cache.
2136 + if (!pPackage->fReachedExecution)
2137 {
2137 - case BURN_CACHE_ACTION_TYPE_CHECKPOINT:
2138 - break;
2139 -
2140 - case BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE:
2141 - hr = CleanPackage(hPipe, pRollbackCacheAction->rollbackPackage.pPackage);
2142 - break;
2143 -
2144 - default:
2145 - AssertSz(FALSE, "Invalid rollback cache action.");
2146 - break;
2138 + if (!pPackage->fCached) // only rollback when it wasn't already cached.
2139 + {
2140 + if (dwLastCheckpoint <= dwCheckpoint) // only rollback when it was attempted to be cached.
2141 + {
2142 + hr = CleanPackage(hPipe, pPackage);
2143 + }
2144 + }
2145 + else if (pPackage->fCanAffectRegistration)
2146 + {
2147 + // Don't let this already cached package cause the registration to be kept if the bundle failed and wasn't already registered.
2148 + pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
2149 + }
2150 }
2151 + break;
2152 +
2153 + default:
2154 + AssertSz(FALSE, "Invalid rollback cache action.");
2155 + break;
2156 }
2157 }
2158 }
@@ -2180,9 +2188,11 @@ static HRESULT DoExecuteAction(
2188 *ppCheckpoint = &pExecuteAction->checkpoint;
2189 break;
2190
2183 - case BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT:
2191 + case BURN_EXECUTE_ACTION_TYPE_WAIT_CACHE_PACKAGE:
2192 + pExecuteAction->waitCachePackage.pPackage->fReachedExecution = TRUE;
2193 +
2194 // wait for cache sync-point
2185 - rghWait[0] = pExecuteAction->syncpoint.hEvent;
2195 + rghWait[0] = pExecuteAction->waitCachePackage.pPackage->hCacheEvent;
2196 rghWait[1] = pContext->pApplyContext->hCacheThread;
2197 switch (::WaitForMultipleObjects(rghWait[1] ? 2 : 1, rghWait, FALSE, INFINITE))
2198 {
@@ -2354,10 +2364,17 @@ static HRESULT DoRollbackActions(
2364 ExitFunction1(hr = S_OK);
2365
2366 case BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE:
2357 - // TODO: This used to be skipped if the package was already cached.
2358 - // Need to figure out new logic for when (if?) to skip it.
2359 - hr = CleanPackage(pEngineState->companionConnection.hPipe, pRollbackAction->uncachePackage.pPackage);
2360 - IgnoreRollbackError(hr, "Failed to uncache package for rollback.");
2367 + if (!pRollbackAction->uncachePackage.pPackage->fCached) // only rollback when it wasn't already cached.
2368 + {
2369 + hr = CleanPackage(pEngineState->companionConnection.hPipe, pRollbackAction->uncachePackage.pPackage);
2370 + IgnoreRollbackError(hr, "Failed to uncache package for rollback.");
2371 + }
2372 + else if (pRollbackAction->uncachePackage.pPackage->fCanAffectRegistration)
2373 + {
2374 + // Don't let this already cached package cause the registration to be kept if the bundle failed and wasn't already registered.
2375 + pRollbackAction->uncachePackage.pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
2376 + }
2377 +
2378 break;
2379
2380 default:
src/burn/engine/apply.h
+7 -1
@@ -71,7 +71,7 @@ HRESULT ApplyRegister(
71 );
72 HRESULT ApplyUnregister(
73 __in BURN_ENGINE_STATE* pEngineState,
74 - __in BOOL fFailedOrRollback,
74 + __in BOOL fFailed,
75 __in BOOL fSuspend,
76 __in BOOTSTRAPPER_APPLY_RESTART restart
77 );
@@ -83,6 +83,12 @@ HRESULT ApplyCache(
83 __in HANDLE hPipe,
84 __in BURN_APPLY_CONTEXT* pContext
85 );
86 +void ApplyCacheRollback(
87 + __in BURN_USER_EXPERIENCE* pUX,
88 + __in BURN_PLAN* pPlan,
89 + __in HANDLE hPipe,
90 + __in BURN_APPLY_CONTEXT* pContext
91 + );
92 HRESULT ApplyExecute(
93 __in BURN_ENGINE_STATE* pEngineState,
94 __in BURN_APPLY_CONTEXT* pApplyContext,
src/burn/engine/core.cpp
+21 -8
@@ -467,6 +467,7 @@ extern "C" HRESULT CorePlan(
467 pEngineState->plan.wzBundleId = pEngineState->registration.sczId;
468 pEngineState->plan.wzBundleProviderKey = pEngineState->registration.sczId;
469 pEngineState->plan.fDisableRollback = pEngineState->fDisableRollback;
470 + pEngineState->plan.fBundleAlreadyRegistered = pEngineState->registration.fInstalled;
471
472 hr = PlanSetVariables(action, &pEngineState->variables);
473 ExitOnFailure(hr, "Failed to update action.");
@@ -613,6 +614,7 @@ extern "C" HRESULT CoreApply(
614 BURN_APPLY_CONTEXT applyContext = { };
615 BOOL fDeleteApplyCs = FALSE;
616 BURN_CACHE_THREAD_CONTEXT cacheThreadContext = { };
617 + BOOL fRollbackCache = FALSE;
618 DWORD dwPhaseCount = 0;
619 BOOTSTRAPPER_APPLYCOMPLETE_ACTION applyCompleteAction = BOOTSTRAPPER_APPLYCOMPLETE_ACTION_NONE;
620
@@ -713,6 +715,8 @@ extern "C" HRESULT CoreApply(
715 applyContext.hCacheThread = ::CreateThread(NULL, 0, CacheThreadProc, &cacheThreadContext, 0, NULL);
716 ExitOnNullWithLastError(applyContext.hCacheThread, hr, "Failed to create cache thread.");
717
718 + fRollbackCache = TRUE;
719 +
720 // If we're not caching in parallel, wait for the cache thread to terminate.
721 if (!pEngineState->fParallelCacheAndExecute)
722 {
@@ -740,23 +744,32 @@ extern "C" HRESULT CoreApply(
744 }
745 }
746
743 - // If something went wrong or force restarted, skip cleaning.
744 - if (FAILED(hr) || applyContext.fRollback || fSuspend || BOOTSTRAPPER_APPLY_RESTART_INITIATED == restart)
747 + if (fSuspend || BOOTSTRAPPER_APPLY_RESTART_INITIATED == restart)
748 {
746 - ExitFunction();
749 + // Leave cache alone.
750 + fRollbackCache = FALSE;
751 }
748 -
749 - // Clean.
750 - if (pEngineState->plan.cCleanActions)
752 + else if (SUCCEEDED(hr))
753 {
752 - ApplyClean(&pEngineState->userExperience, &pEngineState->plan, pEngineState->companionConnection.hPipe);
754 + // Clean.
755 + fRollbackCache = FALSE;
756 +
757 + if (pEngineState->plan.cCleanActions)
758 + {
759 + ApplyClean(&pEngineState->userExperience, &pEngineState->plan, pEngineState->companionConnection.hPipe);
760 + }
761 }
762
763 LExit:
764 + if (fRollbackCache)
765 + {
766 + ApplyCacheRollback(&pEngineState->userExperience, &pEngineState->plan, pEngineState->companionConnection.hCachePipe, &applyContext);
767 + }
768 +
769 // Unregister.
770 if (fRegistered)
771 {
759 - ApplyUnregister(pEngineState, FAILED(hr) || applyContext.fRollback, fSuspend, restart);
772 + ApplyUnregister(pEngineState, FAILED(hr), fSuspend, restart);
773 }
774
775 if (fElevated)
src/burn/engine/core.h
+1 -1
@@ -138,8 +138,8 @@ typedef struct _BURN_APPLY_CONTEXT
138 {
139 CRITICAL_SECTION csApply;
140 DWORD cOverallProgressTicks;
141 - BOOL fRollback;
141 HANDLE hCacheThread;
142 + DWORD dwCacheCheckpoint;
143 } BURN_APPLY_CONTEXT;
144
145
src/burn/engine/exeengine.cpp
+1 -9
@@ -268,20 +268,12 @@ extern "C" HRESULT ExeEnginePlanAddPackage(
268 __in BURN_PACKAGE* pPackage,
269 __in BURN_PLAN* pPlan,
270 __in BURN_LOGGING* pLog,
271 - __in BURN_VARIABLES* pVariables,
272 - __in_opt HANDLE hCacheEvent
271 + __in BURN_VARIABLES* pVariables
272 )
273 {
274 HRESULT hr = S_OK;
275 BURN_EXECUTE_ACTION* pAction = NULL;
276
278 - // add wait for cache
279 - if (hCacheEvent)
280 - {
281 - hr = PlanExecuteCacheSyncAndRollback(pPlan, pPackage, hCacheEvent);
282 - ExitOnFailure(hr, "Failed to plan package cache syncpoint");
283 - }
284 -
277 hr = DependencyPlanPackage(pdwInsertSequence, pPackage, pPlan);
278 ExitOnFailure(hr, "Failed to plan package dependency actions.");
279
src/burn/engine/exeengine.h
+1 -2
@@ -28,8 +28,7 @@ HRESULT ExeEnginePlanAddPackage(
28 __in BURN_PACKAGE* pPackage,
29 __in BURN_PLAN* pPlan,
30 __in BURN_LOGGING* pLog,
31 - __in BURN_VARIABLES* pVariables,
32 - __in_opt HANDLE hCacheEvent
31 + __in BURN_VARIABLES* pVariables
32 );
33 HRESULT ExeEngineExecutePackage(
34 __in BURN_EXECUTE_ACTION* pExecuteAction,
src/burn/engine/msiengine.cpp
+1 -9
@@ -915,8 +915,7 @@ extern "C" HRESULT MsiEnginePlanAddPackage(
915 __in BURN_PACKAGE* pPackage,
916 __in BURN_PLAN* pPlan,
917 __in BURN_LOGGING* pLog,
918 - __in BURN_VARIABLES* pVariables,
919 - __in_opt HANDLE hCacheEvent
918 + __in BURN_VARIABLES* pVariables
919 )
920 {
921 HRESULT hr = S_OK;
@@ -943,13 +942,6 @@ extern "C" HRESULT MsiEnginePlanAddPackage(
942 }
943 }
944
946 - // add wait for cache
947 - if (hCacheEvent)
948 - {
949 - hr = PlanExecuteCacheSyncAndRollback(pPlan, pPackage, hCacheEvent);
950 - ExitOnFailure(hr, "Failed to plan package cache syncpoint");
951 - }
952 -
945 hr = DependencyPlanPackage(NULL, pPackage, pPlan);
946 ExitOnFailure(hr, "Failed to plan package dependency actions.");
947
src/burn/engine/msiengine.h
+1 -2
@@ -49,8 +49,7 @@ HRESULT MsiEnginePlanAddPackage(
49 __in BURN_PACKAGE* pPackage,
50 __in BURN_PLAN* pPlan,
51 __in BURN_LOGGING* pLog,
52 - __in BURN_VARIABLES* pVariables,
53 - __in_opt HANDLE hCacheEvent
52 + __in BURN_VARIABLES* pVariables
53 );
54 HRESULT MsiEngineBeginTransaction(
55 __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary
src/burn/engine/mspengine.cpp
+10 -21
@@ -57,8 +57,7 @@ static HRESULT PlanTargetProduct(
57 __in BURN_VARIABLES* pVariables,
58 __in BOOTSTRAPPER_ACTION_STATE actionState,
59 __in BURN_PACKAGE* pPackage,
60 - __in BURN_MSPTARGETPRODUCT* pTargetProduct,
61 - __in_opt HANDLE hCacheEvent
60 + __in BURN_MSPTARGETPRODUCT* pTargetProduct
61 );
62
63
@@ -504,21 +503,11 @@ extern "C" HRESULT MspEnginePlanAddPackage(
503 __in BURN_PACKAGE* pPackage,
504 __in BURN_PLAN* pPlan,
505 __in BURN_LOGGING* pLog,
507 - __in BURN_VARIABLES* pVariables,
508 - __in_opt HANDLE hCacheEvent
506 + __in BURN_VARIABLES* pVariables
507 )
508 {
509 HRESULT hr = S_OK;
510
513 - // TODO: need to handle the case where this patch adds itself to an earlier patch's list of target products. That would
514 - // essentially bump this patch earlier in the plan and we need to make sure this patch is downloaded.
515 - // add wait for cache
516 - if (hCacheEvent)
517 - {
518 - hr = PlanExecuteCacheSyncAndRollback(pPlan, pPackage, hCacheEvent);
519 - ExitOnFailure(hr, "Failed to plan package cache syncpoint");
520 - }
521 -
511 hr = DependencyPlanPackage(NULL, pPackage, pPlan);
512 ExitOnFailure(hr, "Failed to plan package dependency actions.");
513
@@ -536,13 +525,13 @@ extern "C" HRESULT MspEnginePlanAddPackage(
525
526 if (BOOTSTRAPPER_ACTION_STATE_NONE != pTargetProduct->execute)
527 {
539 - hr = PlanTargetProduct(display, pUserExperience, FALSE, pPlan, pLog, pVariables, pTargetProduct->execute, pPackage, pTargetProduct, hCacheEvent);
528 + hr = PlanTargetProduct(display, pUserExperience, FALSE, pPlan, pLog, pVariables, pTargetProduct->execute, pPackage, pTargetProduct);
529 ExitOnFailure(hr, "Failed to plan target product.");
530 }
531
532 if (BOOTSTRAPPER_ACTION_STATE_NONE != pTargetProduct->rollback)
533 {
545 - hr = PlanTargetProduct(display, pUserExperience, TRUE, pPlan, pLog, pVariables, pTargetProduct->rollback, pPackage, pTargetProduct, hCacheEvent);
534 + hr = PlanTargetProduct(display, pUserExperience, TRUE, pPlan, pLog, pVariables, pTargetProduct->rollback, pPackage, pTargetProduct);
535 ExitOnFailure(hr, "Failed to plan rollback target product.");
536 }
537 }
@@ -1089,8 +1078,7 @@ static HRESULT PlanTargetProduct(
1078 __in BURN_VARIABLES* pVariables,
1079 __in BOOTSTRAPPER_ACTION_STATE actionState,
1080 __in BURN_PACKAGE* pPackage,
1092 - __in BURN_MSPTARGETPRODUCT* pTargetProduct,
1093 - __in_opt HANDLE hCacheEvent
1081 + __in BURN_MSPTARGETPRODUCT* pTargetProduct
1082 )
1083 {
1084 HRESULT hr = S_OK;
@@ -1153,16 +1141,17 @@ static HRESULT PlanTargetProduct(
1141 }
1142 else
1143 {
1156 - if (!fRollback && hCacheEvent)
1144 + if (!fRollback && pPackage->hCacheEvent)
1145 {
1158 - // Since a previouse MSP target action is being updated with the new MSP,
1146 + // TODO: need to properly handle rolling back the caching of the package since this causes cache and execute plans to get out of sync.
1147 + // Since a previous MSP target action is being updated with the new MSP,
1148 // insert a wait syncpoint to before this action since we need to cache the current MSI before using it.
1149 BURN_EXECUTE_ACTION* pWaitSyncPointAction = NULL;
1150 hr = PlanInsertExecuteAction(dwInsertSequence, pPlan, &pWaitSyncPointAction);
1151 ExitOnFailure(hr, "Failed to insert execute action.");
1152
1164 - pWaitSyncPointAction->type = BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT;
1165 - pWaitSyncPointAction->syncpoint.hEvent = hCacheEvent;
1153 + pWaitSyncPointAction->type = BURN_EXECUTE_ACTION_TYPE_WAIT_CACHE_PACKAGE;
1154 + pWaitSyncPointAction->waitCachePackage.pPackage = pPackage;
1155
1156 // Since we inserted an action before the MSP target action that we will be updating, need to update the pointer.
1157 pAction = pPlan->rgExecuteActions + (dwInsertSequence + 1);
src/burn/engine/mspengine.h
+1 -2
@@ -57,8 +57,7 @@ HRESULT MspEnginePlanAddPackage(
57 __in BURN_PACKAGE* pPackage,
58 __in BURN_PLAN* pPlan,
59 __in BURN_LOGGING* pLog,
60 - __in BURN_VARIABLES* pVariables,
61 - __in_opt HANDLE hCacheEvent
60 + __in BURN_VARIABLES* pVariables
61 );
62 HRESULT MspEngineExecutePackage(
63 __in_opt HWND hwndParent,
src/burn/engine/msuengine.cpp
+1 -9
@@ -192,20 +192,12 @@ extern "C" HRESULT MsuEnginePlanAddPackage(
192 __in BURN_PACKAGE* pPackage,
193 __in BURN_PLAN* pPlan,
194 __in BURN_LOGGING* pLog,
195 - __in BURN_VARIABLES* pVariables,
196 - __in HANDLE hCacheEvent
195 + __in BURN_VARIABLES* pVariables
196 )
197 {
198 HRESULT hr = S_OK;
199 BURN_EXECUTE_ACTION* pAction = NULL;
200
202 - // add wait for cache
203 - if (hCacheEvent)
204 - {
205 - hr = PlanExecuteCacheSyncAndRollback(pPlan, pPackage, hCacheEvent);
206 - ExitOnFailure(hr, "Failed to plan package cache syncpoint");
207 - }
208 -
201 hr = DependencyPlanPackage(NULL, pPackage, pPlan);
202 ExitOnFailure(hr, "Failed to plan package dependency actions.");
203
src/burn/engine/msuengine.h
+1 -2
@@ -27,8 +27,7 @@ HRESULT MsuEnginePlanAddPackage(
27 __in BURN_PACKAGE* pPackage,
28 __in BURN_PLAN* pPlan,
29 __in BURN_LOGGING* pLog,
30 - __in BURN_VARIABLES* pVariables,
31 - __in HANDLE hCacheEvent
30 + __in BURN_VARIABLES* pVariables
31 );
32 HRESULT MsuEngineExecutePackage(
33 __in BURN_EXECUTE_ACTION* pExecuteAction,
src/burn/engine/package.h
+2
@@ -240,8 +240,10 @@ typedef struct _BURN_PACKAGE
240 BURN_DEPENDENCY_ACTION dependencyExecute; // only valid during Plan.
241 BURN_DEPENDENCY_ACTION dependencyRollback; // only valid during Plan.
242 BOOL fDependencyManagerWasHere; // only valid during Plan.
243 + HANDLE hCacheEvent; // only valid during Plan.
244 LPWSTR sczCacheFolder; // only valid during Apply.
245 HRESULT hrCacheResult; // only valid during Apply.
246 + BOOL fReachedExecution; // only valid during Apply.
247
248 BURN_PACKAGE_REGISTRATION_STATE cacheRegistrationState; // initialized during Detect, updated during Apply.
249 BURN_PACKAGE_REGISTRATION_STATE installRegistrationState; // initialized during Detect, updated during Apply.
src/burn/engine/plan.cpp
+46 -82
@@ -55,7 +55,6 @@ static HRESULT ProcessPackage(
55 __in BURN_LOGGING* pLog,
56 __in BURN_VARIABLES* pVariables,
57 __in BOOTSTRAPPER_DISPLAY display,
58 - __inout HANDLE* phSyncpointEvent,
58 __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary
59 );
60 static HRESULT ProcessPackageRollbackBoundary(
@@ -77,23 +76,16 @@ static HRESULT AddRegistrationAction(
76 );
77 static HRESULT AddCachePackage(
78 __in BURN_PLAN* pPlan,
80 - __in BURN_PACKAGE* pPackage,
81 - __out HANDLE* phSyncpointEvent
79 + __in BURN_PACKAGE* pPackage
80 );
81 static HRESULT AddCachePackageHelper(
82 __in BURN_PLAN* pPlan,
85 - __in BURN_PACKAGE* pPackage,
86 - __out HANDLE* phSyncpointEvent
83 + __in BURN_PACKAGE* pPackage
84 );
85 static HRESULT AddCacheSlipstreamMsps(
86 __in BURN_PLAN* pPlan,
87 __in BURN_PACKAGE* pPackage
88 );
92 -static BOOL AlreadyPlannedCachePackage(
93 - __in BURN_PLAN* pPlan,
94 - __in_z LPCWSTR wzPackageId,
95 - __out HANDLE* phSyncpointEvent
96 - );
89 static DWORD GetNextCheckpointId(
90 __in BURN_PLAN* pPlan
91 );
@@ -765,7 +757,6 @@ static HRESULT PlanPackagesHelper(
757 HRESULT hr = S_OK;
758 BOOL fBundlePerMachine = pPlan->fPerMachine; // bundle is per-machine if plan starts per-machine.
759 BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL;
768 - HANDLE hSyncpointEvent = NULL;
760
761 // Initialize the packages.
762 for (DWORD i = 0; i < cPackages; ++i)
@@ -796,7 +787,7 @@ static HRESULT PlanPackagesHelper(
787 DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i;
788 BURN_PACKAGE* pPackage = rgPackages + iPackage;
789
799 - hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, display, &hSyncpointEvent, &pRollbackBoundary);
790 + hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, display, &pRollbackBoundary);
791 ExitOnFailure(hr, "Failed to process package.");
792 }
793
@@ -902,7 +893,6 @@ static HRESULT ProcessPackage(
893 __in BURN_LOGGING* pLog,
894 __in BURN_VARIABLES* pVariables,
895 __in BOOTSTRAPPER_DISPLAY display,
905 - __inout HANDLE* phSyncpointEvent,
896 __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary
897 )
898 {
@@ -926,14 +916,14 @@ static HRESULT ProcessPackage(
916 if (BOOTSTRAPPER_REQUEST_STATE_NONE != pPackage->requested)
917 {
918 // If the package is in a requested state, plan it.
929 - hr = PlanExecutePackage(fBundlePerMachine, display, pUX, pPlan, pPackage, pLog, pVariables, phSyncpointEvent);
919 + hr = PlanExecutePackage(fBundlePerMachine, display, pUX, pPlan, pPackage, pLog, pVariables);
920 ExitOnFailure(hr, "Failed to plan execute package.");
921 }
922 else
923 {
924 if (ForceCache(pPlan, pPackage))
925 {
936 - hr = AddCachePackage(pPlan, pPackage, phSyncpointEvent);
926 + hr = AddCachePackage(pPlan, pPackage);
927 ExitOnFailure(hr, "Failed to plan cache package.");
928
929 if (pPackage->fPerMachine)
@@ -1072,8 +1062,7 @@ extern "C" HRESULT PlanExecutePackage(
1062 __in BURN_PLAN* pPlan,
1063 __in BURN_PACKAGE* pPackage,
1064 __in BURN_LOGGING* pLog,
1075 - __in BURN_VARIABLES* pVariables,
1076 - __inout HANDLE* phSyncpointEvent
1065 + __in BURN_VARIABLES* pVariables
1066 )
1067 {
1068 HRESULT hr = S_OK;
@@ -1088,7 +1077,7 @@ extern "C" HRESULT PlanExecutePackage(
1077
1078 if (fRequestedCache || NeedsCache(pPackage, TRUE))
1079 {
1091 - hr = AddCachePackage(pPlan, pPackage, phSyncpointEvent);
1080 + hr = AddCachePackage(pPlan, pPackage);
1081 ExitOnFailure(hr, "Failed to plan cache package.");
1082 }
1083 else if (!pPackage->fCached && NeedsCache(pPackage, FALSE))
@@ -1128,19 +1117,19 @@ extern "C" HRESULT PlanExecutePackage(
1117 switch (pPackage->type)
1118 {
1119 case BURN_PACKAGE_TYPE_EXE:
1131 - hr = ExeEnginePlanAddPackage(NULL, pPackage, pPlan, pLog, pVariables, *phSyncpointEvent);
1120 + hr = ExeEnginePlanAddPackage(NULL, pPackage, pPlan, pLog, pVariables);
1121 break;
1122
1123 case BURN_PACKAGE_TYPE_MSI:
1135 - hr = MsiEnginePlanAddPackage(display, pUserExperience, pPackage, pPlan, pLog, pVariables, *phSyncpointEvent);
1124 + hr = MsiEnginePlanAddPackage(display, pUserExperience, pPackage, pPlan, pLog, pVariables);
1125 break;
1126
1127 case BURN_PACKAGE_TYPE_MSP:
1139 - hr = MspEnginePlanAddPackage(display, pUserExperience, pPackage, pPlan, pLog, pVariables, *phSyncpointEvent);
1128 + hr = MspEnginePlanAddPackage(display, pUserExperience, pPackage, pPlan, pLog, pVariables);
1129 break;
1130
1131 case BURN_PACKAGE_TYPE_MSU:
1143 - hr = MsuEnginePlanAddPackage(pPackage, pPlan, pLog, pVariables, *phSyncpointEvent);
1132 + hr = MsuEnginePlanAddPackage(pPackage, pPlan, pLog, pVariables);
1133 break;
1134
1135 default:
@@ -1453,7 +1442,7 @@ extern "C" HRESULT PlanRelatedBundlesComplete(
1442 }
1443 }
1444
1456 - hr = ExeEnginePlanAddPackage(pdwInsertIndex, &pRelatedBundle->package, pPlan, pLog, pVariables, NULL);
1445 + hr = ExeEnginePlanAddPackage(pdwInsertIndex, &pRelatedBundle->package, pPlan, pLog, pVariables);
1446 ExitOnFailure(hr, "Failed to add to plan related bundle: %ls", pRelatedBundle->package.sczId);
1447
1448 // Calculate package states based on reference count for addon and patch related bundles.
@@ -1583,28 +1572,30 @@ LExit:
1572
1573 extern "C" HRESULT PlanExecuteCacheSyncAndRollback(
1574 __in BURN_PLAN* pPlan,
1586 - __in BURN_PACKAGE* pPackage,
1587 - __in HANDLE hCacheEvent
1575 + __in BURN_PACKAGE* pPackage
1576 )
1577 {
1578 HRESULT hr = S_OK;
1579 BURN_EXECUTE_ACTION* pAction = NULL;
1580
1593 - hr = PlanAppendExecuteAction(pPlan, &pAction);
1594 - ExitOnFailure(hr, "Failed to append wait action for caching.");
1595 -
1596 - pAction->type = BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT;
1597 - pAction->syncpoint.hEvent = hCacheEvent;
1598 -
1599 - hr = PlanAppendRollbackAction(pPlan, &pAction);
1600 - ExitOnFailure(hr, "Failed to append rollback action.");
1581 + if (!pPlan->fBundleAlreadyRegistered)
1582 + {
1583 + hr = PlanAppendRollbackAction(pPlan, &pAction);
1584 + ExitOnFailure(hr, "Failed to append rollback action.");
1585
1602 - pAction->type = BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE;
1603 - pAction->uncachePackage.pPackage = pPackage;
1586 + pAction->type = BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE;
1587 + pAction->uncachePackage.pPackage = pPackage;
1588 + }
1589
1590 hr = PlanExecuteCheckpoint(pPlan);
1591 ExitOnFailure(hr, "Failed to append execute checkpoint for cache rollback.");
1592
1593 + hr = PlanAppendExecuteAction(pPlan, &pAction);
1594 + ExitOnFailure(hr, "Failed to append wait action for caching.");
1595 +
1596 + pAction->type = BURN_EXECUTE_ACTION_TYPE_WAIT_CACHE_PACKAGE;
1597 + pAction->waitCachePackage.pPackage = pPackage;
1598 +
1599 LExit:
1600 return hr;
1601 }
@@ -1885,6 +1876,7 @@ static void ResetPlannedPackageState(
1876 pPackage->fDependencyManagerWasHere = FALSE;
1877 pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
1878 pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
1879 + pPackage->hCacheEvent = NULL;
1880
1881 ReleaseNullStr(pPackage->sczCacheFolder);
1882
@@ -2046,8 +2038,7 @@ LExit:
2038
2039 static HRESULT AddCachePackage(
2040 __in BURN_PLAN* pPlan,
2049 - __in BURN_PACKAGE* pPackage,
2050 - __out HANDLE* phSyncpointEvent
2041 + __in BURN_PACKAGE* pPackage
2042 )
2043 {
2044 HRESULT hr = S_OK;
@@ -2059,7 +2050,7 @@ static HRESULT AddCachePackage(
2050 ExitOnFailure(hr, "Failed to plan slipstream patches for package.");
2051 }
2052
2062 - hr = AddCachePackageHelper(pPlan, pPackage, phSyncpointEvent);
2053 + hr = AddCachePackageHelper(pPlan, pPackage);
2054 ExitOnFailure(hr, "Failed to plan cache package.");
2055
2056 LExit:
@@ -2068,8 +2059,7 @@ LExit:
2059
2060 static HRESULT AddCachePackageHelper(
2061 __in BURN_PLAN* pPlan,
2071 - __in BURN_PACKAGE* pPackage,
2072 - __out HANDLE* phSyncpointEvent
2062 + __in BURN_PACKAGE* pPackage
2063 )
2064 {
2065 AssertSz(pPackage->sczCacheId && *pPackage->sczCacheId, "AddCachePackageHelper() expects the package to have a cache id.");
@@ -2083,8 +2073,7 @@ static HRESULT AddCachePackageHelper(
2073 ExitFunction();
2074 }
2075
2086 - BOOL fPlanned = AlreadyPlannedCachePackage(pPlan, pPackage->sczId, phSyncpointEvent);
2087 - if (fPlanned)
2076 + if (pPackage->hCacheEvent) // Only cache the package once.
2077 {
2078 ExitFunction();
2079 }
@@ -2100,12 +2089,15 @@ static HRESULT AddCachePackageHelper(
2089 pCacheAction->type = BURN_CACHE_ACTION_TYPE_CHECKPOINT;
2090 pCacheAction->checkpoint.dwId = dwCheckpoint;
2091
2103 - // Only plan the cache rollback if the package is also going to be uninstalled;
2104 - // otherwise, future operations like repair will not be able to locate the cached package.
2105 - BOOL fPlanCacheRollback = (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pPackage->rollback);
2106 -
2107 - if (fPlanCacheRollback)
2092 + if (!pPlan->fBundleAlreadyRegistered)
2093 {
2094 + // Create a package cache rollback action *before* the checkpoint.
2095 + hr = AppendRollbackCacheAction(pPlan, &pCacheAction);
2096 + ExitOnFailure(hr, "Failed to append rollback cache action.");
2097 +
2098 + pCacheAction->type = BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE;
2099 + pCacheAction->rollbackPackage.pPackage = pPackage;
2100 +
2101 hr = AppendRollbackCacheAction(pPlan, &pCacheAction);
2102 ExitOnFailure(hr, "Failed to append rollback cache action.");
2103
@@ -2124,7 +2116,10 @@ static HRESULT AddCachePackageHelper(
2116 pCacheAction->syncpoint.hEvent = ::CreateEventW(NULL, TRUE, FALSE, NULL);
2117 ExitOnNullWithLastError(pCacheAction->syncpoint.hEvent, hr, "Failed to create syncpoint event.");
2118
2127 - *phSyncpointEvent = pCacheAction->syncpoint.hEvent;
2119 + pPackage->hCacheEvent = pCacheAction->syncpoint.hEvent;
2120 +
2121 + hr = PlanExecuteCacheSyncAndRollback(pPlan, pPackage);
2122 + ExitOnFailure(hr, "Failed to plan package cache syncpoint");
2123
2124 pPackage->fPlannedCache = TRUE;
2125 if (pPackage->fCanAffectRegistration)
@@ -2142,7 +2137,6 @@ static HRESULT AddCacheSlipstreamMsps(
2137 )
2138 {
2139 HRESULT hr = S_OK;
2145 - HANDLE hIgnored = NULL;
2140
2141 AssertSz(BURN_PACKAGE_TYPE_MSI == pPackage->type, "Only MSI packages can have slipstream patches.");
2142
@@ -2151,7 +2145,7 @@ static HRESULT AddCacheSlipstreamMsps(
2145 BURN_PACKAGE* pMspPackage = pPackage->Msi.rgSlipstreamMsps[i].pMspPackage;
2146 AssertSz(BURN_PACKAGE_TYPE_MSP == pMspPackage->type, "Only MSP packages can be slipstream patches.");
2147
2154 - hr = AddCachePackageHelper(pPlan, pMspPackage, &hIgnored);
2148 + hr = AddCachePackageHelper(pPlan, pMspPackage);
2149 ExitOnFailure(hr, "Failed to plan slipstream MSP: %ls", pMspPackage->sczId);
2150 }
2151
@@ -2159,36 +2153,6 @@ LExit:
2153 return hr;
2154 }
2155
2162 -static BOOL AlreadyPlannedCachePackage(
2163 - __in BURN_PLAN* pPlan,
2164 - __in_z LPCWSTR wzPackageId,
2165 - __out HANDLE* phSyncpointEvent
2166 - )
2167 -{
2168 - BOOL fPlanned = FALSE;
2169 -
2170 - for (DWORD iCacheAction = 0; iCacheAction < pPlan->cCacheActions; ++iCacheAction)
2171 - {
2172 - BURN_CACHE_ACTION* pCacheAction = pPlan->rgCacheActions + iCacheAction;
2173 -
2174 - if (BURN_CACHE_ACTION_TYPE_PACKAGE == pCacheAction->type)
2175 - {
2176 - if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pCacheAction->package.pPackage->sczId, -1, wzPackageId, -1))
2177 - {
2178 - if (iCacheAction + 1 < pPlan->cCacheActions && BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT == pPlan->rgCacheActions[iCacheAction + 1].type)
2179 - {
2180 - *phSyncpointEvent = pPlan->rgCacheActions[iCacheAction + 1].syncpoint.hEvent;
2181 - }
2182 -
2183 - fPlanned = TRUE;
2184 - break;
2185 - }
2186 - }
2187 - }
2188 -
2189 - return fPlanned;
2190 -}
2191 -
2156 static DWORD GetNextCheckpointId(
2157 __in BURN_PLAN* pPlan
2158 )
@@ -2635,8 +2599,8 @@ static void ExecuteActionLog(
2599 LogStringLine(PlanDumpLevel, "%ls action[%u]: ROLLBACK_BOUNDARY id: %ls, vital: %ls", wzBase, iAction, pAction->rollbackBoundary.pRollbackBoundary->sczId, pAction->rollbackBoundary.pRollbackBoundary->fVital ? L"yes" : L"no");
2600 break;
2601
2638 - case BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT:
2639 - LogStringLine(PlanDumpLevel, "%ls action[%u]: WAIT_SYNCPOINT event handle: 0x%p", wzBase, iAction, pAction->syncpoint.hEvent);
2602 + case BURN_EXECUTE_ACTION_TYPE_WAIT_CACHE_PACKAGE:
2603 + LogStringLine(PlanDumpLevel, "%ls action[%u]: WAIT_CACHE_PACKAGE id: %ls, event handle: 0x%p", wzBase, iAction, pAction->waitCachePackage.pPackage->sczId, pAction->waitCachePackage.pPackage->hCacheEvent);
2604 break;
2605
2606 case BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE:
src/burn/engine/plan.h
+6 -7
@@ -48,7 +48,7 @@ enum BURN_EXECUTE_ACTION_TYPE
48 {
49 BURN_EXECUTE_ACTION_TYPE_NONE,
50 BURN_EXECUTE_ACTION_TYPE_CHECKPOINT,
51 - BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT,
51 + BURN_EXECUTE_ACTION_TYPE_WAIT_CACHE_PACKAGE,
52 BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE,
53 BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE,
54 BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE,
@@ -151,8 +151,8 @@ typedef struct _BURN_EXECUTE_ACTION
151 BURN_EXECUTE_ACTION_CHECKPOINT checkpoint;
152 struct
153 {
154 - HANDLE hEvent;
155 - } syncpoint;
154 + BURN_PACKAGE* pPackage;
155 + } waitCachePackage;
156 struct
157 {
158 BURN_PACKAGE* pPackage;
@@ -240,6 +240,7 @@ typedef struct _BURN_PLAN
240 BOOL fAffectedMachineState;
241 BOOL fIgnoreAllDependents;
242 LPWSTR sczLayoutDirectory;
243 + BOOL fBundleAlreadyRegistered;
244
245 DWORD64 qwCacheSizeTotal;
246
@@ -377,8 +378,7 @@ HRESULT PlanExecutePackage(
378 __in BURN_PLAN* pPlan,
379 __in BURN_PACKAGE* pPackage,
380 __in BURN_LOGGING* pLog,
380 - __in BURN_VARIABLES* pVariables,
381 - __inout HANDLE* phSyncpointEvent
381 + __in BURN_VARIABLES* pVariables
382 );
383 HRESULT PlanDefaultRelatedBundleRequestState(
384 __in BOOTSTRAPPER_RELATION_TYPE commandRelationType,
@@ -410,8 +410,7 @@ HRESULT PlanCleanPackage(
410 );
411 HRESULT PlanExecuteCacheSyncAndRollback(
412 __in BURN_PLAN* pPlan,
413 - __in BURN_PACKAGE* pPackage,
414 - __in HANDLE hCacheEvent
413 + __in BURN_PACKAGE* pPackage
414 );
415 HRESULT PlanExecuteCheckpoint(
416 __in BURN_PLAN* pPlan
src/burn/test/BurnUnitTest/PlanTest.cpp
+29 -22
@@ -67,7 +67,12 @@ namespace Bootstrapper
67
68 fRollback = TRUE;
69 dwIndex = 0;
70 + ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageA");
71 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
72 + ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageB");
73 + ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 9);
74 + ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageC");
75 + ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 14);
76 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
77
78 Assert::Equal(107082ull, pPlan->qwEstimatedSize);
@@ -77,8 +82,8 @@ namespace Bootstrapper
82 dwIndex = 0;
83 DWORD dwExecuteCheckpointId = 2;
84 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
80 - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent);
85 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
86 + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
87 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
88 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER);
89 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -90,18 +95,18 @@ namespace Bootstrapper
95 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ", TRUE, TRUE);
96 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
97 ValidateExecuteBeginMsiTransaction(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ");
93 - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[5].syncpoint.hEvent);
98 dwExecuteCheckpointId += 1; // cache checkpoints
99 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
100 + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageB");
101 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
102 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageB", BURN_DEPENDENCY_ACTION_REGISTER);
103 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
104 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
105 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_REGISTER);
106 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
102 - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[8].syncpoint.hEvent);
107 dwExecuteCheckpointId += 1; // cache checkpoints
108 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
109 + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageC");
110 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
111 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageC", BURN_DEPENDENCY_ACTION_REGISTER);
112 ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageC", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0);
@@ -304,6 +309,7 @@ namespace Bootstrapper
309
310 fRollback = TRUE;
311 dwIndex = 0;
312 + ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageA");
313 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
314 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
315
@@ -314,8 +320,8 @@ namespace Bootstrapper
320 dwIndex = 0;
321 DWORD dwExecuteCheckpointId = 2;
322 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
317 - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent);
323 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
324 + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
325 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
326 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER);
327 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -385,6 +391,8 @@ namespace Bootstrapper
391
392 fRollback = TRUE;
393 dwIndex = 0;
394 + ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageA");
395 + ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
396 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
397
398 Assert::Equal(33743ull, pPlan->qwEstimatedSize);
@@ -394,8 +402,8 @@ namespace Bootstrapper
402 dwIndex = 0;
403 DWORD dwExecuteCheckpointId = 2;
404 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
397 - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent);
405 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
406 + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
407 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
408 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
409 Assert::Equal(dwIndex, pPlan->cExecuteActions);
@@ -454,6 +462,7 @@ namespace Bootstrapper
462
463 fRollback = TRUE;
464 dwIndex = 0;
465 + ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageA");
466 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
467 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
468
@@ -464,8 +473,8 @@ namespace Bootstrapper
473 dwIndex = 0;
474 DWORD dwExecuteCheckpointId = 2;
475 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
467 - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent);
476 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
477 + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
478 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
479 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER);
480 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -731,14 +740,13 @@ namespace Bootstrapper
740 ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 3);
741 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PatchA");
742 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++);
734 - ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 4);
743 + ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 5);
744 ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
745 ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++);
746 Assert::Equal(dwIndex, pPlan->cCacheActions);
747
748 fRollback = TRUE;
749 dwIndex = 0;
741 - ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 4);
750 Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
751
752 Assert::Equal(3055111ull, pPlan->qwEstimatedSize);
@@ -749,11 +757,14 @@ namespace Bootstrapper
757 DWORD dwExecuteCheckpointId = 2;
758 BURN_EXECUTE_ACTION* pExecuteAction = NULL;
759 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
752 - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent);
760 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
754 - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[8].syncpoint.hEvent);
755 - dwExecuteCheckpointId += 2; // cache checkpoints
761 + dwExecuteCheckpointId += 1; // cache checkpoints
762 + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"NetFx48Web");
763 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
764 + dwExecuteCheckpointId += 1; // cache checkpoints
765 + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PatchA");
766 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
767 + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
768 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
769 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER);
770 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -761,8 +772,6 @@ namespace Bootstrapper
772 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
773 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{22D1DDBA-284D-40A7-BD14-95EA07906F21}", BURN_DEPENDENCY_ACTION_REGISTER);
774 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
764 - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[5].syncpoint.hEvent);
765 - ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
775 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
776 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PatchA", BURN_DEPENDENCY_ACTION_REGISTER);
777 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, TRUE);
@@ -777,10 +786,10 @@ namespace Bootstrapper
786 dwIndex = 0;
787 dwExecuteCheckpointId = 2;
788 ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
780 - ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"NetFx48Web");
789 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
782 - dwExecuteCheckpointId += 2; // cache checkpoints
783 - ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
790 + dwExecuteCheckpointId += 1; // cache checkpoints
791 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
792 + dwExecuteCheckpointId += 1; // cache checkpoints
793 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
794 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_UNREGISTER);
795 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
@@ -789,8 +798,6 @@ namespace Bootstrapper
798 ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{22D1DDBA-284D-40A7-BD14-95EA07906F21}", BURN_DEPENDENCY_ACTION_UNREGISTER);
799 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
800 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
792 - ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PatchA");
793 - ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
801 ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PatchA", BURN_DEPENDENCY_ACTION_UNREGISTER);
802 ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
803 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, TRUE);
@@ -1414,16 +1421,16 @@ namespace Bootstrapper
1421 Assert::Equal<BOOL>(FALSE, pAction->fDeleted);
1422 }
1423
1417 - void ValidateExecuteWaitSyncpoint(
1424 + void ValidateExecuteWaitCachePackage(
1425 __in BURN_PLAN* pPlan,
1426 __in BOOL fRollback,
1427 __in DWORD dwIndex,
1421 - __in HANDLE hEvent
1428 + __in_z LPCWSTR wzPackageId
1429 )
1430 {
1431 BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex);
1425 - Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT, pAction->type);
1426 - Assert::Equal((DWORD_PTR)hEvent, (DWORD_PTR)pAction->syncpoint.hEvent);
1432 + Assert::Equal<DWORD>(BURN_EXECUTE_ACTION_TYPE_WAIT_CACHE_PACKAGE, pAction->type);
1433 + NativeAssert::StringEqual(wzPackageId, pAction->waitCachePackage.pPackage->sczId);
1434 Assert::Equal<BOOL>(FALSE, pAction->fDeleted);
1435 }
1436
src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs
+1 -1
@@ -79,7 +79,7 @@ namespace WixToolsetTest.BurnE2E
79 packageA.VerifyInstalled(false);
80 }
81
82 - [Fact(Skip = "https://github.com/wixtoolset/issues/issues/exea")]
82 + [Fact]
83 public void CanKeepUpgradedPackageAfterUninstallUpgradedBundle()
84 {
85 var testRegistryValueExe = "ExeA";
src/test/burn/WixToolsetTest.BurnE2E/FailureTests.cs
+1 -1
@@ -64,7 +64,7 @@ namespace WixToolsetTest.BurnE2E
64 packageB.VerifyInstalled(false);
65 }
66
67 - [Fact(Skip = "https://github.com/wixtoolset/issues/issues/5750")]
67 + [Fact]
68 public void CanCancelExecuteWhileCaching()
69 {
70 var packageA = this.CreatePackageInstaller("PackageA");