From 27c6decae94536cae338731b6cb765aa92776486 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Tue, 4 May 2021 19:25:07 -0500 Subject: Put back the rollback cache package functionality and fix its bugs. #3719, #4711, #5750 --- src/burn/engine/apply.cpp | 99 +++++++++------- src/burn/engine/apply.h | 8 +- src/burn/engine/core.cpp | 29 +++-- src/burn/engine/core.h | 2 +- src/burn/engine/exeengine.cpp | 10 +- src/burn/engine/exeengine.h | 3 +- src/burn/engine/msiengine.cpp | 10 +- src/burn/engine/msiengine.h | 3 +- src/burn/engine/mspengine.cpp | 31 ++--- src/burn/engine/mspengine.h | 3 +- src/burn/engine/msuengine.cpp | 10 +- src/burn/engine/msuengine.h | 3 +- src/burn/engine/package.h | 2 + src/burn/engine/plan.cpp | 128 ++++++++------------- src/burn/engine/plan.h | 13 +-- src/burn/test/BurnUnitTest/PlanTest.cpp | 51 ++++---- .../burn/WixToolsetTest.BurnE2E/DependencyTests.cs | 2 +- .../burn/WixToolsetTest.BurnE2E/FailureTests.cs | 2 +- 18 files changed, 189 insertions(+), 220 deletions(-) (limited to 'src') diff --git a/src/burn/engine/apply.cpp b/src/burn/engine/apply.cpp index 4d527409..aad9e6eb 100644 --- a/src/burn/engine/apply.cpp +++ b/src/burn/engine/apply.cpp @@ -335,6 +335,7 @@ extern "C" void ApplyReset( { BURN_PACKAGE* pPackage = pPackages->rgPackages + i; pPackage->hrCacheResult = S_OK; + pPackage->fReachedExecution = FALSE; pPackage->transactionRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; } } @@ -433,7 +434,7 @@ LExit: extern "C" HRESULT ApplyUnregister( __in BURN_ENGINE_STATE* pEngineState, - __in BOOL fFailedOrRollback, + __in BOOL fFailed, __in BOOL fSuspend, __in BOOTSTRAPPER_APPLY_RESTART restart ) @@ -466,7 +467,7 @@ extern "C" HRESULT ApplyUnregister( // If apply failed in any way and we're going to be keeping the bundle registered then // execute any rollback dependency registration actions. - if (fFailedOrRollback && fKeepRegistration) + if (fFailed && fKeepRegistration) { // Execute any rollback registration actions. HRESULT hrRegistrationRollback = ExecuteDependentRegistrationActions(pEngineState->companionConnection.hPipe, &pEngineState->registration, pEngineState->plan.rgRollbackRegistrationActions, pEngineState->plan.cRollbackRegistrationActions); @@ -587,11 +588,7 @@ extern "C" HRESULT ApplyCache( } LExit: - if (FAILED(hr)) - { - DoRollbackCache(pUX, pPlan, hPipe, dwCheckpoint); - pContext->fRollback = TRUE; - } + pContext->dwCacheCheckpoint = dwCheckpoint; // Clean up any remanents in the cache. if (INVALID_HANDLE_VALUE != hPipe) @@ -612,6 +609,16 @@ LExit: return hr; } +extern "C" void ApplyCacheRollback( + __in BURN_USER_EXPERIENCE* pUX, + __in BURN_PLAN* pPlan, + __in HANDLE hPipe, + __in BURN_APPLY_CONTEXT* pContext + ) +{ + DoRollbackCache(pUX, pPlan, hPipe, pContext->dwCacheCheckpoint); +} + extern "C" HRESULT ApplyExecute( __in BURN_ENGINE_STATE* pEngineState, __in BURN_APPLY_CONTEXT* pApplyContext, @@ -687,7 +694,6 @@ extern "C" HRESULT ApplyExecute( IgnoreRollbackError(hrRollback, "Failed commit transaction from disable rollback"); } - pApplyContext->fRollback = TRUE; break; } @@ -708,7 +714,6 @@ extern "C" HRESULT ApplyExecute( // If the rollback boundary is vital, end execution here. if (pRollbackBoundary && pRollbackBoundary->fVital) { - pApplyContext->fRollback = TRUE; break; } @@ -2110,41 +2115,44 @@ static void DoRollbackCache( ) { HRESULT hr = S_OK; - DWORD iCheckpoint = 0; + BURN_PACKAGE* pPackage = NULL; + DWORD dwLastCheckpoint = 0; - // Scan to last checkpoint. - for (DWORD i = 0; i < pPlan->cRollbackCacheActions; ++i) + // Rollback cache actions. + for (DWORD i = pPlan->cRollbackCacheActions; i > 0; --i) { - BURN_CACHE_ACTION* pRollbackCacheAction = &pPlan->rgRollbackCacheActions[i]; + BURN_CACHE_ACTION* pRollbackCacheAction = &pPlan->rgRollbackCacheActions[i - 1]; - if (BURN_CACHE_ACTION_TYPE_CHECKPOINT == pRollbackCacheAction->type && pRollbackCacheAction->checkpoint.dwId == dwCheckpoint) + switch (pRollbackCacheAction->type) { - iCheckpoint = i; + case BURN_CACHE_ACTION_TYPE_CHECKPOINT: + dwLastCheckpoint = pRollbackCacheAction->checkpoint.dwId; break; - } - } - // Rollback cache actions. - if (iCheckpoint) - { - // i has to be a signed integer so it doesn't get decremented to 0xFFFFFFFF. - for (int i = iCheckpoint - 1; i >= 0; --i) - { - BURN_CACHE_ACTION* pRollbackCacheAction = &pPlan->rgRollbackCacheActions[i]; + case BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE: + pPackage = pRollbackCacheAction->rollbackPackage.pPackage; - switch (pRollbackCacheAction->type) + // If the package was executed then it's up to ApplyExecute to rollback its cache. + if (!pPackage->fReachedExecution) { - case BURN_CACHE_ACTION_TYPE_CHECKPOINT: - break; - - case BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE: - hr = CleanPackage(hPipe, pRollbackCacheAction->rollbackPackage.pPackage); - break; - - default: - AssertSz(FALSE, "Invalid rollback cache action."); - break; + if (!pPackage->fCached) // only rollback when it wasn't already cached. + { + if (dwLastCheckpoint <= dwCheckpoint) // only rollback when it was attempted to be cached. + { + hr = CleanPackage(hPipe, pPackage); + } + } + else if (pPackage->fCanAffectRegistration) + { + // Don't let this already cached package cause the registration to be kept if the bundle failed and wasn't already registered. + pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED; + } } + break; + + default: + AssertSz(FALSE, "Invalid rollback cache action."); + break; } } } @@ -2180,9 +2188,11 @@ static HRESULT DoExecuteAction( *ppCheckpoint = &pExecuteAction->checkpoint; break; - case BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT: + case BURN_EXECUTE_ACTION_TYPE_WAIT_CACHE_PACKAGE: + pExecuteAction->waitCachePackage.pPackage->fReachedExecution = TRUE; + // wait for cache sync-point - rghWait[0] = pExecuteAction->syncpoint.hEvent; + rghWait[0] = pExecuteAction->waitCachePackage.pPackage->hCacheEvent; rghWait[1] = pContext->pApplyContext->hCacheThread; switch (::WaitForMultipleObjects(rghWait[1] ? 2 : 1, rghWait, FALSE, INFINITE)) { @@ -2354,10 +2364,17 @@ static HRESULT DoRollbackActions( ExitFunction1(hr = S_OK); case BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE: - // TODO: This used to be skipped if the package was already cached. - // Need to figure out new logic for when (if?) to skip it. - hr = CleanPackage(pEngineState->companionConnection.hPipe, pRollbackAction->uncachePackage.pPackage); - IgnoreRollbackError(hr, "Failed to uncache package for rollback."); + if (!pRollbackAction->uncachePackage.pPackage->fCached) // only rollback when it wasn't already cached. + { + hr = CleanPackage(pEngineState->companionConnection.hPipe, pRollbackAction->uncachePackage.pPackage); + IgnoreRollbackError(hr, "Failed to uncache package for rollback."); + } + else if (pRollbackAction->uncachePackage.pPackage->fCanAffectRegistration) + { + // Don't let this already cached package cause the registration to be kept if the bundle failed and wasn't already registered. + pRollbackAction->uncachePackage.pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED; + } + break; default: diff --git a/src/burn/engine/apply.h b/src/burn/engine/apply.h index 39580297..45270f92 100644 --- a/src/burn/engine/apply.h +++ b/src/burn/engine/apply.h @@ -71,7 +71,7 @@ HRESULT ApplyRegister( ); HRESULT ApplyUnregister( __in BURN_ENGINE_STATE* pEngineState, - __in BOOL fFailedOrRollback, + __in BOOL fFailed, __in BOOL fSuspend, __in BOOTSTRAPPER_APPLY_RESTART restart ); @@ -83,6 +83,12 @@ HRESULT ApplyCache( __in HANDLE hPipe, __in BURN_APPLY_CONTEXT* pContext ); +void ApplyCacheRollback( + __in BURN_USER_EXPERIENCE* pUX, + __in BURN_PLAN* pPlan, + __in HANDLE hPipe, + __in BURN_APPLY_CONTEXT* pContext + ); HRESULT ApplyExecute( __in BURN_ENGINE_STATE* pEngineState, __in BURN_APPLY_CONTEXT* pApplyContext, diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp index 601f29a0..aab49cb7 100644 --- a/src/burn/engine/core.cpp +++ b/src/burn/engine/core.cpp @@ -467,6 +467,7 @@ extern "C" HRESULT CorePlan( pEngineState->plan.wzBundleId = pEngineState->registration.sczId; pEngineState->plan.wzBundleProviderKey = pEngineState->registration.sczId; pEngineState->plan.fDisableRollback = pEngineState->fDisableRollback; + pEngineState->plan.fBundleAlreadyRegistered = pEngineState->registration.fInstalled; hr = PlanSetVariables(action, &pEngineState->variables); ExitOnFailure(hr, "Failed to update action."); @@ -613,6 +614,7 @@ extern "C" HRESULT CoreApply( BURN_APPLY_CONTEXT applyContext = { }; BOOL fDeleteApplyCs = FALSE; BURN_CACHE_THREAD_CONTEXT cacheThreadContext = { }; + BOOL fRollbackCache = FALSE; DWORD dwPhaseCount = 0; BOOTSTRAPPER_APPLYCOMPLETE_ACTION applyCompleteAction = BOOTSTRAPPER_APPLYCOMPLETE_ACTION_NONE; @@ -713,6 +715,8 @@ extern "C" HRESULT CoreApply( applyContext.hCacheThread = ::CreateThread(NULL, 0, CacheThreadProc, &cacheThreadContext, 0, NULL); ExitOnNullWithLastError(applyContext.hCacheThread, hr, "Failed to create cache thread."); + fRollbackCache = TRUE; + // If we're not caching in parallel, wait for the cache thread to terminate. if (!pEngineState->fParallelCacheAndExecute) { @@ -740,23 +744,32 @@ extern "C" HRESULT CoreApply( } } - // If something went wrong or force restarted, skip cleaning. - if (FAILED(hr) || applyContext.fRollback || fSuspend || BOOTSTRAPPER_APPLY_RESTART_INITIATED == restart) + if (fSuspend || BOOTSTRAPPER_APPLY_RESTART_INITIATED == restart) { - ExitFunction(); + // Leave cache alone. + fRollbackCache = FALSE; } - - // Clean. - if (pEngineState->plan.cCleanActions) + else if (SUCCEEDED(hr)) { - ApplyClean(&pEngineState->userExperience, &pEngineState->plan, pEngineState->companionConnection.hPipe); + // Clean. + fRollbackCache = FALSE; + + if (pEngineState->plan.cCleanActions) + { + ApplyClean(&pEngineState->userExperience, &pEngineState->plan, pEngineState->companionConnection.hPipe); + } } LExit: + if (fRollbackCache) + { + ApplyCacheRollback(&pEngineState->userExperience, &pEngineState->plan, pEngineState->companionConnection.hCachePipe, &applyContext); + } + // Unregister. if (fRegistered) { - ApplyUnregister(pEngineState, FAILED(hr) || applyContext.fRollback, fSuspend, restart); + ApplyUnregister(pEngineState, FAILED(hr), fSuspend, restart); } if (fElevated) diff --git a/src/burn/engine/core.h b/src/burn/engine/core.h index 9f779366..27cb2e25 100644 --- a/src/burn/engine/core.h +++ b/src/burn/engine/core.h @@ -138,8 +138,8 @@ typedef struct _BURN_APPLY_CONTEXT { CRITICAL_SECTION csApply; DWORD cOverallProgressTicks; - BOOL fRollback; HANDLE hCacheThread; + DWORD dwCacheCheckpoint; } BURN_APPLY_CONTEXT; diff --git a/src/burn/engine/exeengine.cpp b/src/burn/engine/exeengine.cpp index c0ba93e0..13d4f6c6 100644 --- a/src/burn/engine/exeengine.cpp +++ b/src/burn/engine/exeengine.cpp @@ -268,20 +268,12 @@ extern "C" HRESULT ExeEnginePlanAddPackage( __in BURN_PACKAGE* pPackage, __in BURN_PLAN* pPlan, __in BURN_LOGGING* pLog, - __in BURN_VARIABLES* pVariables, - __in_opt HANDLE hCacheEvent + __in BURN_VARIABLES* pVariables ) { HRESULT hr = S_OK; BURN_EXECUTE_ACTION* pAction = NULL; - // add wait for cache - if (hCacheEvent) - { - hr = PlanExecuteCacheSyncAndRollback(pPlan, pPackage, hCacheEvent); - ExitOnFailure(hr, "Failed to plan package cache syncpoint"); - } - hr = DependencyPlanPackage(pdwInsertSequence, pPackage, pPlan); ExitOnFailure(hr, "Failed to plan package dependency actions."); diff --git a/src/burn/engine/exeengine.h b/src/burn/engine/exeengine.h index e032ea01..4fec2dd9 100644 --- a/src/burn/engine/exeengine.h +++ b/src/burn/engine/exeengine.h @@ -28,8 +28,7 @@ HRESULT ExeEnginePlanAddPackage( __in BURN_PACKAGE* pPackage, __in BURN_PLAN* pPlan, __in BURN_LOGGING* pLog, - __in BURN_VARIABLES* pVariables, - __in_opt HANDLE hCacheEvent + __in BURN_VARIABLES* pVariables ); HRESULT ExeEngineExecutePackage( __in BURN_EXECUTE_ACTION* pExecuteAction, diff --git a/src/burn/engine/msiengine.cpp b/src/burn/engine/msiengine.cpp index 3e96e5f9..a579fa17 100644 --- a/src/burn/engine/msiengine.cpp +++ b/src/burn/engine/msiengine.cpp @@ -915,8 +915,7 @@ extern "C" HRESULT MsiEnginePlanAddPackage( __in BURN_PACKAGE* pPackage, __in BURN_PLAN* pPlan, __in BURN_LOGGING* pLog, - __in BURN_VARIABLES* pVariables, - __in_opt HANDLE hCacheEvent + __in BURN_VARIABLES* pVariables ) { HRESULT hr = S_OK; @@ -943,13 +942,6 @@ extern "C" HRESULT MsiEnginePlanAddPackage( } } - // add wait for cache - if (hCacheEvent) - { - hr = PlanExecuteCacheSyncAndRollback(pPlan, pPackage, hCacheEvent); - ExitOnFailure(hr, "Failed to plan package cache syncpoint"); - } - hr = DependencyPlanPackage(NULL, pPackage, pPlan); ExitOnFailure(hr, "Failed to plan package dependency actions."); diff --git a/src/burn/engine/msiengine.h b/src/burn/engine/msiengine.h index 8b5bcdd0..e4155a62 100644 --- a/src/burn/engine/msiengine.h +++ b/src/burn/engine/msiengine.h @@ -49,8 +49,7 @@ HRESULT MsiEnginePlanAddPackage( __in BURN_PACKAGE* pPackage, __in BURN_PLAN* pPlan, __in BURN_LOGGING* pLog, - __in BURN_VARIABLES* pVariables, - __in_opt HANDLE hCacheEvent + __in BURN_VARIABLES* pVariables ); HRESULT MsiEngineBeginTransaction( __in BURN_ROLLBACK_BOUNDARY* pRollbackBoundary diff --git a/src/burn/engine/mspengine.cpp b/src/burn/engine/mspengine.cpp index 6d58d324..4a82598f 100644 --- a/src/burn/engine/mspengine.cpp +++ b/src/burn/engine/mspengine.cpp @@ -57,8 +57,7 @@ static HRESULT PlanTargetProduct( __in BURN_VARIABLES* pVariables, __in BOOTSTRAPPER_ACTION_STATE actionState, __in BURN_PACKAGE* pPackage, - __in BURN_MSPTARGETPRODUCT* pTargetProduct, - __in_opt HANDLE hCacheEvent + __in BURN_MSPTARGETPRODUCT* pTargetProduct ); @@ -504,21 +503,11 @@ extern "C" HRESULT MspEnginePlanAddPackage( __in BURN_PACKAGE* pPackage, __in BURN_PLAN* pPlan, __in BURN_LOGGING* pLog, - __in BURN_VARIABLES* pVariables, - __in_opt HANDLE hCacheEvent + __in BURN_VARIABLES* pVariables ) { HRESULT hr = S_OK; - // TODO: need to handle the case where this patch adds itself to an earlier patch's list of target products. That would - // essentially bump this patch earlier in the plan and we need to make sure this patch is downloaded. - // add wait for cache - if (hCacheEvent) - { - hr = PlanExecuteCacheSyncAndRollback(pPlan, pPackage, hCacheEvent); - ExitOnFailure(hr, "Failed to plan package cache syncpoint"); - } - hr = DependencyPlanPackage(NULL, pPackage, pPlan); ExitOnFailure(hr, "Failed to plan package dependency actions."); @@ -536,13 +525,13 @@ extern "C" HRESULT MspEnginePlanAddPackage( if (BOOTSTRAPPER_ACTION_STATE_NONE != pTargetProduct->execute) { - hr = PlanTargetProduct(display, pUserExperience, FALSE, pPlan, pLog, pVariables, pTargetProduct->execute, pPackage, pTargetProduct, hCacheEvent); + hr = PlanTargetProduct(display, pUserExperience, FALSE, pPlan, pLog, pVariables, pTargetProduct->execute, pPackage, pTargetProduct); ExitOnFailure(hr, "Failed to plan target product."); } if (BOOTSTRAPPER_ACTION_STATE_NONE != pTargetProduct->rollback) { - hr = PlanTargetProduct(display, pUserExperience, TRUE, pPlan, pLog, pVariables, pTargetProduct->rollback, pPackage, pTargetProduct, hCacheEvent); + hr = PlanTargetProduct(display, pUserExperience, TRUE, pPlan, pLog, pVariables, pTargetProduct->rollback, pPackage, pTargetProduct); ExitOnFailure(hr, "Failed to plan rollback target product."); } } @@ -1089,8 +1078,7 @@ static HRESULT PlanTargetProduct( __in BURN_VARIABLES* pVariables, __in BOOTSTRAPPER_ACTION_STATE actionState, __in BURN_PACKAGE* pPackage, - __in BURN_MSPTARGETPRODUCT* pTargetProduct, - __in_opt HANDLE hCacheEvent + __in BURN_MSPTARGETPRODUCT* pTargetProduct ) { HRESULT hr = S_OK; @@ -1153,16 +1141,17 @@ static HRESULT PlanTargetProduct( } else { - if (!fRollback && hCacheEvent) + if (!fRollback && pPackage->hCacheEvent) { - // Since a previouse MSP target action is being updated with the new MSP, + // TODO: need to properly handle rolling back the caching of the package since this causes cache and execute plans to get out of sync. + // Since a previous MSP target action is being updated with the new MSP, // insert a wait syncpoint to before this action since we need to cache the current MSI before using it. BURN_EXECUTE_ACTION* pWaitSyncPointAction = NULL; hr = PlanInsertExecuteAction(dwInsertSequence, pPlan, &pWaitSyncPointAction); ExitOnFailure(hr, "Failed to insert execute action."); - pWaitSyncPointAction->type = BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT; - pWaitSyncPointAction->syncpoint.hEvent = hCacheEvent; + pWaitSyncPointAction->type = BURN_EXECUTE_ACTION_TYPE_WAIT_CACHE_PACKAGE; + pWaitSyncPointAction->waitCachePackage.pPackage = pPackage; // Since we inserted an action before the MSP target action that we will be updating, need to update the pointer. pAction = pPlan->rgExecuteActions + (dwInsertSequence + 1); diff --git a/src/burn/engine/mspengine.h b/src/burn/engine/mspengine.h index 79998030..a8835d7b 100644 --- a/src/burn/engine/mspengine.h +++ b/src/burn/engine/mspengine.h @@ -57,8 +57,7 @@ HRESULT MspEnginePlanAddPackage( __in BURN_PACKAGE* pPackage, __in BURN_PLAN* pPlan, __in BURN_LOGGING* pLog, - __in BURN_VARIABLES* pVariables, - __in_opt HANDLE hCacheEvent + __in BURN_VARIABLES* pVariables ); HRESULT MspEngineExecutePackage( __in_opt HWND hwndParent, diff --git a/src/burn/engine/msuengine.cpp b/src/burn/engine/msuengine.cpp index 6003123b..d6722bbf 100644 --- a/src/burn/engine/msuengine.cpp +++ b/src/burn/engine/msuengine.cpp @@ -192,20 +192,12 @@ extern "C" HRESULT MsuEnginePlanAddPackage( __in BURN_PACKAGE* pPackage, __in BURN_PLAN* pPlan, __in BURN_LOGGING* pLog, - __in BURN_VARIABLES* pVariables, - __in HANDLE hCacheEvent + __in BURN_VARIABLES* pVariables ) { HRESULT hr = S_OK; BURN_EXECUTE_ACTION* pAction = NULL; - // add wait for cache - if (hCacheEvent) - { - hr = PlanExecuteCacheSyncAndRollback(pPlan, pPackage, hCacheEvent); - ExitOnFailure(hr, "Failed to plan package cache syncpoint"); - } - hr = DependencyPlanPackage(NULL, pPackage, pPlan); ExitOnFailure(hr, "Failed to plan package dependency actions."); diff --git a/src/burn/engine/msuengine.h b/src/burn/engine/msuengine.h index fda7a5ab..23dd5301 100644 --- a/src/burn/engine/msuengine.h +++ b/src/burn/engine/msuengine.h @@ -27,8 +27,7 @@ HRESULT MsuEnginePlanAddPackage( __in BURN_PACKAGE* pPackage, __in BURN_PLAN* pPlan, __in BURN_LOGGING* pLog, - __in BURN_VARIABLES* pVariables, - __in HANDLE hCacheEvent + __in BURN_VARIABLES* pVariables ); HRESULT MsuEngineExecutePackage( __in BURN_EXECUTE_ACTION* pExecuteAction, diff --git a/src/burn/engine/package.h b/src/burn/engine/package.h index 89a3d6e9..94f27c23 100644 --- a/src/burn/engine/package.h +++ b/src/burn/engine/package.h @@ -240,8 +240,10 @@ typedef struct _BURN_PACKAGE BURN_DEPENDENCY_ACTION dependencyExecute; // only valid during Plan. BURN_DEPENDENCY_ACTION dependencyRollback; // only valid during Plan. BOOL fDependencyManagerWasHere; // only valid during Plan. + HANDLE hCacheEvent; // only valid during Plan. LPWSTR sczCacheFolder; // only valid during Apply. HRESULT hrCacheResult; // only valid during Apply. + BOOL fReachedExecution; // only valid during Apply. BURN_PACKAGE_REGISTRATION_STATE cacheRegistrationState; // initialized during Detect, updated during Apply. BURN_PACKAGE_REGISTRATION_STATE installRegistrationState; // initialized during Detect, updated during Apply. diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index f0ae2a44..d1f07508 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp @@ -55,7 +55,6 @@ static HRESULT ProcessPackage( __in BURN_LOGGING* pLog, __in BURN_VARIABLES* pVariables, __in BOOTSTRAPPER_DISPLAY display, - __inout HANDLE* phSyncpointEvent, __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary ); static HRESULT ProcessPackageRollbackBoundary( @@ -77,23 +76,16 @@ static HRESULT AddRegistrationAction( ); static HRESULT AddCachePackage( __in BURN_PLAN* pPlan, - __in BURN_PACKAGE* pPackage, - __out HANDLE* phSyncpointEvent + __in BURN_PACKAGE* pPackage ); static HRESULT AddCachePackageHelper( __in BURN_PLAN* pPlan, - __in BURN_PACKAGE* pPackage, - __out HANDLE* phSyncpointEvent + __in BURN_PACKAGE* pPackage ); static HRESULT AddCacheSlipstreamMsps( __in BURN_PLAN* pPlan, __in BURN_PACKAGE* pPackage ); -static BOOL AlreadyPlannedCachePackage( - __in BURN_PLAN* pPlan, - __in_z LPCWSTR wzPackageId, - __out HANDLE* phSyncpointEvent - ); static DWORD GetNextCheckpointId( __in BURN_PLAN* pPlan ); @@ -765,7 +757,6 @@ static HRESULT PlanPackagesHelper( HRESULT hr = S_OK; BOOL fBundlePerMachine = pPlan->fPerMachine; // bundle is per-machine if plan starts per-machine. BURN_ROLLBACK_BOUNDARY* pRollbackBoundary = NULL; - HANDLE hSyncpointEvent = NULL; // Initialize the packages. for (DWORD i = 0; i < cPackages; ++i) @@ -796,7 +787,7 @@ static HRESULT PlanPackagesHelper( DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i; BURN_PACKAGE* pPackage = rgPackages + iPackage; - hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, display, &hSyncpointEvent, &pRollbackBoundary); + hr = ProcessPackage(fBundlePerMachine, pUX, pPlan, pPackage, pLog, pVariables, display, &pRollbackBoundary); ExitOnFailure(hr, "Failed to process package."); } @@ -902,7 +893,6 @@ static HRESULT ProcessPackage( __in BURN_LOGGING* pLog, __in BURN_VARIABLES* pVariables, __in BOOTSTRAPPER_DISPLAY display, - __inout HANDLE* phSyncpointEvent, __inout BURN_ROLLBACK_BOUNDARY** ppRollbackBoundary ) { @@ -926,14 +916,14 @@ static HRESULT ProcessPackage( if (BOOTSTRAPPER_REQUEST_STATE_NONE != pPackage->requested) { // If the package is in a requested state, plan it. - hr = PlanExecutePackage(fBundlePerMachine, display, pUX, pPlan, pPackage, pLog, pVariables, phSyncpointEvent); + hr = PlanExecutePackage(fBundlePerMachine, display, pUX, pPlan, pPackage, pLog, pVariables); ExitOnFailure(hr, "Failed to plan execute package."); } else { if (ForceCache(pPlan, pPackage)) { - hr = AddCachePackage(pPlan, pPackage, phSyncpointEvent); + hr = AddCachePackage(pPlan, pPackage); ExitOnFailure(hr, "Failed to plan cache package."); if (pPackage->fPerMachine) @@ -1072,8 +1062,7 @@ extern "C" HRESULT PlanExecutePackage( __in BURN_PLAN* pPlan, __in BURN_PACKAGE* pPackage, __in BURN_LOGGING* pLog, - __in BURN_VARIABLES* pVariables, - __inout HANDLE* phSyncpointEvent + __in BURN_VARIABLES* pVariables ) { HRESULT hr = S_OK; @@ -1088,7 +1077,7 @@ extern "C" HRESULT PlanExecutePackage( if (fRequestedCache || NeedsCache(pPackage, TRUE)) { - hr = AddCachePackage(pPlan, pPackage, phSyncpointEvent); + hr = AddCachePackage(pPlan, pPackage); ExitOnFailure(hr, "Failed to plan cache package."); } else if (!pPackage->fCached && NeedsCache(pPackage, FALSE)) @@ -1128,19 +1117,19 @@ extern "C" HRESULT PlanExecutePackage( switch (pPackage->type) { case BURN_PACKAGE_TYPE_EXE: - hr = ExeEnginePlanAddPackage(NULL, pPackage, pPlan, pLog, pVariables, *phSyncpointEvent); + hr = ExeEnginePlanAddPackage(NULL, pPackage, pPlan, pLog, pVariables); break; case BURN_PACKAGE_TYPE_MSI: - hr = MsiEnginePlanAddPackage(display, pUserExperience, pPackage, pPlan, pLog, pVariables, *phSyncpointEvent); + hr = MsiEnginePlanAddPackage(display, pUserExperience, pPackage, pPlan, pLog, pVariables); break; case BURN_PACKAGE_TYPE_MSP: - hr = MspEnginePlanAddPackage(display, pUserExperience, pPackage, pPlan, pLog, pVariables, *phSyncpointEvent); + hr = MspEnginePlanAddPackage(display, pUserExperience, pPackage, pPlan, pLog, pVariables); break; case BURN_PACKAGE_TYPE_MSU: - hr = MsuEnginePlanAddPackage(pPackage, pPlan, pLog, pVariables, *phSyncpointEvent); + hr = MsuEnginePlanAddPackage(pPackage, pPlan, pLog, pVariables); break; default: @@ -1453,7 +1442,7 @@ extern "C" HRESULT PlanRelatedBundlesComplete( } } - hr = ExeEnginePlanAddPackage(pdwInsertIndex, &pRelatedBundle->package, pPlan, pLog, pVariables, NULL); + hr = ExeEnginePlanAddPackage(pdwInsertIndex, &pRelatedBundle->package, pPlan, pLog, pVariables); ExitOnFailure(hr, "Failed to add to plan related bundle: %ls", pRelatedBundle->package.sczId); // Calculate package states based on reference count for addon and patch related bundles. @@ -1583,28 +1572,30 @@ LExit: extern "C" HRESULT PlanExecuteCacheSyncAndRollback( __in BURN_PLAN* pPlan, - __in BURN_PACKAGE* pPackage, - __in HANDLE hCacheEvent + __in BURN_PACKAGE* pPackage ) { HRESULT hr = S_OK; BURN_EXECUTE_ACTION* pAction = NULL; - hr = PlanAppendExecuteAction(pPlan, &pAction); - ExitOnFailure(hr, "Failed to append wait action for caching."); - - pAction->type = BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT; - pAction->syncpoint.hEvent = hCacheEvent; - - hr = PlanAppendRollbackAction(pPlan, &pAction); - ExitOnFailure(hr, "Failed to append rollback action."); + if (!pPlan->fBundleAlreadyRegistered) + { + hr = PlanAppendRollbackAction(pPlan, &pAction); + ExitOnFailure(hr, "Failed to append rollback action."); - pAction->type = BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE; - pAction->uncachePackage.pPackage = pPackage; + pAction->type = BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE; + pAction->uncachePackage.pPackage = pPackage; + } hr = PlanExecuteCheckpoint(pPlan); ExitOnFailure(hr, "Failed to append execute checkpoint for cache rollback."); + hr = PlanAppendExecuteAction(pPlan, &pAction); + ExitOnFailure(hr, "Failed to append wait action for caching."); + + pAction->type = BURN_EXECUTE_ACTION_TYPE_WAIT_CACHE_PACKAGE; + pAction->waitCachePackage.pPackage = pPackage; + LExit: return hr; } @@ -1885,6 +1876,7 @@ static void ResetPlannedPackageState( pPackage->fDependencyManagerWasHere = FALSE; pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN; + pPackage->hCacheEvent = NULL; ReleaseNullStr(pPackage->sczCacheFolder); @@ -2046,8 +2038,7 @@ LExit: static HRESULT AddCachePackage( __in BURN_PLAN* pPlan, - __in BURN_PACKAGE* pPackage, - __out HANDLE* phSyncpointEvent + __in BURN_PACKAGE* pPackage ) { HRESULT hr = S_OK; @@ -2059,7 +2050,7 @@ static HRESULT AddCachePackage( ExitOnFailure(hr, "Failed to plan slipstream patches for package."); } - hr = AddCachePackageHelper(pPlan, pPackage, phSyncpointEvent); + hr = AddCachePackageHelper(pPlan, pPackage); ExitOnFailure(hr, "Failed to plan cache package."); LExit: @@ -2068,8 +2059,7 @@ LExit: static HRESULT AddCachePackageHelper( __in BURN_PLAN* pPlan, - __in BURN_PACKAGE* pPackage, - __out HANDLE* phSyncpointEvent + __in BURN_PACKAGE* pPackage ) { AssertSz(pPackage->sczCacheId && *pPackage->sczCacheId, "AddCachePackageHelper() expects the package to have a cache id."); @@ -2083,8 +2073,7 @@ static HRESULT AddCachePackageHelper( ExitFunction(); } - BOOL fPlanned = AlreadyPlannedCachePackage(pPlan, pPackage->sczId, phSyncpointEvent); - if (fPlanned) + if (pPackage->hCacheEvent) // Only cache the package once. { ExitFunction(); } @@ -2100,12 +2089,15 @@ static HRESULT AddCachePackageHelper( pCacheAction->type = BURN_CACHE_ACTION_TYPE_CHECKPOINT; pCacheAction->checkpoint.dwId = dwCheckpoint; - // Only plan the cache rollback if the package is also going to be uninstalled; - // otherwise, future operations like repair will not be able to locate the cached package. - BOOL fPlanCacheRollback = (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pPackage->rollback); - - if (fPlanCacheRollback) + if (!pPlan->fBundleAlreadyRegistered) { + // Create a package cache rollback action *before* the checkpoint. + hr = AppendRollbackCacheAction(pPlan, &pCacheAction); + ExitOnFailure(hr, "Failed to append rollback cache action."); + + pCacheAction->type = BURN_CACHE_ACTION_TYPE_ROLLBACK_PACKAGE; + pCacheAction->rollbackPackage.pPackage = pPackage; + hr = AppendRollbackCacheAction(pPlan, &pCacheAction); ExitOnFailure(hr, "Failed to append rollback cache action."); @@ -2124,7 +2116,10 @@ static HRESULT AddCachePackageHelper( pCacheAction->syncpoint.hEvent = ::CreateEventW(NULL, TRUE, FALSE, NULL); ExitOnNullWithLastError(pCacheAction->syncpoint.hEvent, hr, "Failed to create syncpoint event."); - *phSyncpointEvent = pCacheAction->syncpoint.hEvent; + pPackage->hCacheEvent = pCacheAction->syncpoint.hEvent; + + hr = PlanExecuteCacheSyncAndRollback(pPlan, pPackage); + ExitOnFailure(hr, "Failed to plan package cache syncpoint"); pPackage->fPlannedCache = TRUE; if (pPackage->fCanAffectRegistration) @@ -2142,7 +2137,6 @@ static HRESULT AddCacheSlipstreamMsps( ) { HRESULT hr = S_OK; - HANDLE hIgnored = NULL; AssertSz(BURN_PACKAGE_TYPE_MSI == pPackage->type, "Only MSI packages can have slipstream patches."); @@ -2151,7 +2145,7 @@ static HRESULT AddCacheSlipstreamMsps( BURN_PACKAGE* pMspPackage = pPackage->Msi.rgSlipstreamMsps[i].pMspPackage; AssertSz(BURN_PACKAGE_TYPE_MSP == pMspPackage->type, "Only MSP packages can be slipstream patches."); - hr = AddCachePackageHelper(pPlan, pMspPackage, &hIgnored); + hr = AddCachePackageHelper(pPlan, pMspPackage); ExitOnFailure(hr, "Failed to plan slipstream MSP: %ls", pMspPackage->sczId); } @@ -2159,36 +2153,6 @@ LExit: return hr; } -static BOOL AlreadyPlannedCachePackage( - __in BURN_PLAN* pPlan, - __in_z LPCWSTR wzPackageId, - __out HANDLE* phSyncpointEvent - ) -{ - BOOL fPlanned = FALSE; - - for (DWORD iCacheAction = 0; iCacheAction < pPlan->cCacheActions; ++iCacheAction) - { - BURN_CACHE_ACTION* pCacheAction = pPlan->rgCacheActions + iCacheAction; - - if (BURN_CACHE_ACTION_TYPE_PACKAGE == pCacheAction->type) - { - if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pCacheAction->package.pPackage->sczId, -1, wzPackageId, -1)) - { - if (iCacheAction + 1 < pPlan->cCacheActions && BURN_CACHE_ACTION_TYPE_SIGNAL_SYNCPOINT == pPlan->rgCacheActions[iCacheAction + 1].type) - { - *phSyncpointEvent = pPlan->rgCacheActions[iCacheAction + 1].syncpoint.hEvent; - } - - fPlanned = TRUE; - break; - } - } - } - - return fPlanned; -} - static DWORD GetNextCheckpointId( __in BURN_PLAN* pPlan ) @@ -2635,8 +2599,8 @@ static void ExecuteActionLog( 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"); break; - case BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT: - LogStringLine(PlanDumpLevel, "%ls action[%u]: WAIT_SYNCPOINT event handle: 0x%p", wzBase, iAction, pAction->syncpoint.hEvent); + case BURN_EXECUTE_ACTION_TYPE_WAIT_CACHE_PACKAGE: + LogStringLine(PlanDumpLevel, "%ls action[%u]: WAIT_CACHE_PACKAGE id: %ls, event handle: 0x%p", wzBase, iAction, pAction->waitCachePackage.pPackage->sczId, pAction->waitCachePackage.pPackage->hCacheEvent); break; case BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE: diff --git a/src/burn/engine/plan.h b/src/burn/engine/plan.h index 00ab5516..6db464e1 100644 --- a/src/burn/engine/plan.h +++ b/src/burn/engine/plan.h @@ -48,7 +48,7 @@ enum BURN_EXECUTE_ACTION_TYPE { BURN_EXECUTE_ACTION_TYPE_NONE, BURN_EXECUTE_ACTION_TYPE_CHECKPOINT, - BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT, + BURN_EXECUTE_ACTION_TYPE_WAIT_CACHE_PACKAGE, BURN_EXECUTE_ACTION_TYPE_UNCACHE_PACKAGE, BURN_EXECUTE_ACTION_TYPE_EXE_PACKAGE, BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE, @@ -151,8 +151,8 @@ typedef struct _BURN_EXECUTE_ACTION BURN_EXECUTE_ACTION_CHECKPOINT checkpoint; struct { - HANDLE hEvent; - } syncpoint; + BURN_PACKAGE* pPackage; + } waitCachePackage; struct { BURN_PACKAGE* pPackage; @@ -240,6 +240,7 @@ typedef struct _BURN_PLAN BOOL fAffectedMachineState; BOOL fIgnoreAllDependents; LPWSTR sczLayoutDirectory; + BOOL fBundleAlreadyRegistered; DWORD64 qwCacheSizeTotal; @@ -377,8 +378,7 @@ HRESULT PlanExecutePackage( __in BURN_PLAN* pPlan, __in BURN_PACKAGE* pPackage, __in BURN_LOGGING* pLog, - __in BURN_VARIABLES* pVariables, - __inout HANDLE* phSyncpointEvent + __in BURN_VARIABLES* pVariables ); HRESULT PlanDefaultRelatedBundleRequestState( __in BOOTSTRAPPER_RELATION_TYPE commandRelationType, @@ -410,8 +410,7 @@ HRESULT PlanCleanPackage( ); HRESULT PlanExecuteCacheSyncAndRollback( __in BURN_PLAN* pPlan, - __in BURN_PACKAGE* pPackage, - __in HANDLE hCacheEvent + __in BURN_PACKAGE* pPackage ); HRESULT PlanExecuteCheckpoint( __in BURN_PLAN* pPlan diff --git a/src/burn/test/BurnUnitTest/PlanTest.cpp b/src/burn/test/BurnUnitTest/PlanTest.cpp index 23192349..3cb42c5f 100644 --- a/src/burn/test/BurnUnitTest/PlanTest.cpp +++ b/src/burn/test/BurnUnitTest/PlanTest.cpp @@ -67,7 +67,12 @@ namespace Bootstrapper fRollback = TRUE; dwIndex = 0; + ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageA"); ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); + ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageB"); + ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 9); + ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageC"); + ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 14); Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); Assert::Equal(107082ull, pPlan->qwEstimatedSize); @@ -77,8 +82,8 @@ namespace Bootstrapper dwIndex = 0; DWORD dwExecuteCheckpointId = 2; ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); @@ -90,18 +95,18 @@ namespace Bootstrapper ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ", TRUE, TRUE); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecuteBeginMsiTransaction(pPlan, fRollback, dwIndex++, L"rbaOCA08D8ky7uBOK71_6FWz1K3TuQ"); - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[5].syncpoint.hEvent); dwExecuteCheckpointId += 1; // cache checkpoints ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageB"); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageB", BURN_DEPENDENCY_ACTION_REGISTER); ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageB", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageB", L"{E6469F05-BDC8-4EB8-B218-67412543EFAA}", BURN_DEPENDENCY_ACTION_REGISTER); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[8].syncpoint.hEvent); dwExecuteCheckpointId += 1; // cache checkpoints ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageC"); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageC", BURN_DEPENDENCY_ACTION_REGISTER); ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageC", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, 0); @@ -304,6 +309,7 @@ namespace Bootstrapper fRollback = TRUE; dwIndex = 0; + ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageA"); ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); @@ -314,8 +320,8 @@ namespace Bootstrapper dwIndex = 0; DWORD dwExecuteCheckpointId = 2; ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); @@ -385,6 +391,8 @@ namespace Bootstrapper fRollback = TRUE; dwIndex = 0; + ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageA"); + ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); Assert::Equal(33743ull, pPlan->qwEstimatedSize); @@ -394,8 +402,8 @@ namespace Bootstrapper dwIndex = 0; DWORD dwExecuteCheckpointId = 2; ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); Assert::Equal(dwIndex, pPlan->cExecuteActions); @@ -454,6 +462,7 @@ namespace Bootstrapper fRollback = TRUE; dwIndex = 0; + ValidateCacheRollbackPackage(pPlan, fRollback, dwIndex++, L"PackageA"); ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); @@ -464,8 +473,8 @@ namespace Bootstrapper dwIndex = 0; DWORD dwExecuteCheckpointId = 2; ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); @@ -731,14 +740,13 @@ namespace Bootstrapper ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 3); ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PatchA"); ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); - ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 4); + ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 5); ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); Assert::Equal(dwIndex, pPlan->cCacheActions); fRollback = TRUE; dwIndex = 0; - ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 4); Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); Assert::Equal(3055111ull, pPlan->qwEstimatedSize); @@ -749,11 +757,14 @@ namespace Bootstrapper DWORD dwExecuteCheckpointId = 2; BURN_EXECUTE_ACTION* pExecuteAction = NULL; ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[2].syncpoint.hEvent); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[8].syncpoint.hEvent); - dwExecuteCheckpointId += 2; // cache checkpoints + dwExecuteCheckpointId += 1; // cache checkpoints + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"NetFx48Web"); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); + dwExecuteCheckpointId += 1; // cache checkpoints + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PatchA"); + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); @@ -761,8 +772,6 @@ namespace Bootstrapper ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{22D1DDBA-284D-40A7-BD14-95EA07906F21}", BURN_DEPENDENCY_ACTION_REGISTER); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); - ValidateExecuteWaitSyncpoint(pPlan, fRollback, dwIndex++, pPlan->rgCacheActions[5].syncpoint.hEvent); - ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PatchA", BURN_DEPENDENCY_ACTION_REGISTER); 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 dwIndex = 0; dwExecuteCheckpointId = 2; ValidateExecuteRollbackBoundary(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); - ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"NetFx48Web"); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); - dwExecuteCheckpointId += 2; // cache checkpoints - ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); + dwExecuteCheckpointId += 1; // cache checkpoints + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); + dwExecuteCheckpointId += 1; // cache checkpoints ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_UNREGISTER); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); @@ -789,8 +798,6 @@ namespace Bootstrapper ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{22D1DDBA-284D-40A7-BD14-95EA07906F21}", BURN_DEPENDENCY_ACTION_UNREGISTER); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); - ValidateExecuteUncachePackage(pPlan, fRollback, dwIndex++, L"PatchA"); - ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PatchA", BURN_DEPENDENCY_ACTION_UNREGISTER); ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); 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 Assert::Equal(FALSE, pAction->fDeleted); } - void ValidateExecuteWaitSyncpoint( + void ValidateExecuteWaitCachePackage( __in BURN_PLAN* pPlan, __in BOOL fRollback, __in DWORD dwIndex, - __in HANDLE hEvent + __in_z LPCWSTR wzPackageId ) { BURN_EXECUTE_ACTION* pAction = ValidateExecuteActionExists(pPlan, fRollback, dwIndex); - Assert::Equal(BURN_EXECUTE_ACTION_TYPE_WAIT_SYNCPOINT, pAction->type); - Assert::Equal((DWORD_PTR)hEvent, (DWORD_PTR)pAction->syncpoint.hEvent); + Assert::Equal(BURN_EXECUTE_ACTION_TYPE_WAIT_CACHE_PACKAGE, pAction->type); + NativeAssert::StringEqual(wzPackageId, pAction->waitCachePackage.pPackage->sczId); Assert::Equal(FALSE, pAction->fDeleted); } diff --git a/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs index d563bbe7..08370631 100644 --- a/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs +++ b/src/test/burn/WixToolsetTest.BurnE2E/DependencyTests.cs @@ -79,7 +79,7 @@ namespace WixToolsetTest.BurnE2E packageA.VerifyInstalled(false); } - [Fact(Skip = "https://github.com/wixtoolset/issues/issues/exea")] + [Fact] public void CanKeepUpgradedPackageAfterUninstallUpgradedBundle() { var testRegistryValueExe = "ExeA"; diff --git a/src/test/burn/WixToolsetTest.BurnE2E/FailureTests.cs b/src/test/burn/WixToolsetTest.BurnE2E/FailureTests.cs index a11a5eb6..d8428a54 100644 --- a/src/test/burn/WixToolsetTest.BurnE2E/FailureTests.cs +++ b/src/test/burn/WixToolsetTest.BurnE2E/FailureTests.cs @@ -64,7 +64,7 @@ namespace WixToolsetTest.BurnE2E packageB.VerifyInstalled(false); } - [Fact(Skip = "https://github.com/wixtoolset/issues/issues/5750")] + [Fact] public void CanCancelExecuteWhileCaching() { var packageA = this.CreatePackageInstaller("PackageA"); -- cgit v1.2.3-55-g6feb