diff --git a/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h b/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h index 603df89..2a6d5c8 100644 --- a/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h +++ b/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h @@ -103,6 +103,20 @@ enum BOOTSTRAPPER_RELATION_TYPE BOOTSTRAPPER_RELATION_UPDATE, }; +enum BOOTSTRAPPER_CACHE_TYPE +{ + BOOTSTRAPPER_CACHE_TYPE_REMOVE, + BOOTSTRAPPER_CACHE_TYPE_KEEP, + BOOTSTRAPPER_CACHE_TYPE_FORCE, +}; + +enum BOOTSTRAPPER_PACKAGE_CONDITION_RESULT +{ + BOOTSTRAPPER_PACKAGE_CONDITION_DEFAULT, + BOOTSTRAPPER_PACKAGE_CONDITION_FALSE, + BOOTSTRAPPER_PACKAGE_CONDITION_TRUE, +}; + enum BOOTSTRAPPER_APPLICATION_MESSAGE { BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTBEGIN, @@ -682,6 +696,7 @@ struct BA_ONDETECTPACKAGECOMPLETE_ARGS LPCWSTR wzPackageId; HRESULT hrStatus; BOOTSTRAPPER_PACKAGE_STATE state; + BOOL fCached; }; struct BA_ONDETECTPACKAGECOMPLETE_RESULTS @@ -1062,6 +1077,8 @@ struct BA_ONPLANNEDPACKAGE_ARGS LPCWSTR wzPackageId; BOOTSTRAPPER_ACTION_STATE execute; BOOTSTRAPPER_ACTION_STATE rollback; + BOOL fPlannedCache; + BOOL fPlannedUncache; }; struct BA_ONPLANNEDPACKAGE_RESULTS @@ -1074,8 +1091,10 @@ struct BA_ONPLANPACKAGEBEGIN_ARGS DWORD cbSize; LPCWSTR wzPackageId; BOOTSTRAPPER_PACKAGE_STATE state; - BOOL fInstallCondition; + BOOL fCached; + BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition; BOOTSTRAPPER_REQUEST_STATE recommendedState; + BOOTSTRAPPER_CACHE_TYPE recommendedCacheType; }; struct BA_ONPLANPACKAGEBEGIN_RESULTS @@ -1083,6 +1102,7 @@ struct BA_ONPLANPACKAGEBEGIN_RESULTS DWORD cbSize; BOOL fCancel; BOOTSTRAPPER_REQUEST_STATE requestedState; + BOOTSTRAPPER_CACHE_TYPE requestedCacheType; }; struct BA_ONPLANPACKAGECOMPLETE_ARGS diff --git a/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h b/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h index f680473..9c9b38a 100644 --- a/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h +++ b/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h @@ -47,7 +47,6 @@ enum BOOTSTRAPPER_PACKAGE_STATE BOOTSTRAPPER_PACKAGE_STATE_UNKNOWN, BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE, BOOTSTRAPPER_PACKAGE_STATE_ABSENT, - BOOTSTRAPPER_PACKAGE_STATE_CACHED, BOOTSTRAPPER_PACKAGE_STATE_PRESENT, BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED, }; diff --git a/src/engine/core.cpp b/src/engine/core.cpp index a915dad..535043a 100644 --- a/src/engine/core.cpp +++ b/src/engine/core.cpp @@ -1640,12 +1640,6 @@ static HRESULT DetectPackage( ExitOnRootFailure(hr, "Package type not supported by detect yet."); } - // TODO: consider how to notify the UX that a package is cached. - //else if (BOOTSTRAPPER_PACKAGE_STATE_CACHED > pPackage->currentState && pPackage->fCached) - //{ - // pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_CACHED; - //} - LExit: if (FAILED(hr)) { @@ -1654,7 +1648,7 @@ LExit: if (fBegan) { - UserExperienceOnDetectPackageComplete(&pEngineState->userExperience, pPackage->sczId, hr, pPackage->currentState); + UserExperienceOnDetectPackageComplete(&pEngineState->userExperience, pPackage->sczId, hr, pPackage->currentState, pPackage->fCached); } return hr; diff --git a/src/engine/dependency.cpp b/src/engine/dependency.cpp index c4af207..876cd8b 100644 --- a/src/engine/dependency.cpp +++ b/src/engine/dependency.cpp @@ -1065,7 +1065,6 @@ static void CalculateDependencyActionStates( { case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: __fallthrough; case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: __fallthrough; - case BOOTSTRAPPER_PACKAGE_STATE_CACHED: *pDependencyRollbackAction = BURN_DEPENDENCY_ACTION_UNREGISTER; break; } diff --git a/src/engine/exeengine.cpp b/src/engine/exeengine.cpp index 8900984..c0ba93e 100644 --- a/src/engine/exeengine.cpp +++ b/src/engine/exeengine.cpp @@ -146,7 +146,7 @@ extern "C" HRESULT ExeEngineDetectPackage( if (pPackage->fCanAffectRegistration) { - pPackage->installRegistrationState = BOOTSTRAPPER_PACKAGE_STATE_CACHED < pPackage->currentState ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT; + pPackage->installRegistrationState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT < pPackage->currentState ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT; } LExit: diff --git a/src/engine/externalengine.cpp b/src/engine/externalengine.cpp index 51a0e22..409353e 100644 --- a/src/engine/externalengine.cpp +++ b/src/engine/externalengine.cpp @@ -582,6 +582,11 @@ HRESULT ExternalEnginePlan( { HRESULT hr = S_OK; + if (BOOTSTRAPPER_ACTION_LAYOUT > action || BOOTSTRAPPER_ACTION_UPDATE_REPLACE_EMBEDDED < action) + { + ExitOnRootFailure(hr = E_INVALIDARG, "BA passed invalid action to Plan: %u.", action); + } + if (!::PostThreadMessageW(dwThreadId, WM_BURN_PLAN, 0, action)) { ExitWithLastError(hr, "Failed to post plan message."); @@ -622,7 +627,7 @@ HRESULT ExternalEngineApply( ExitOnNull(hwndParent, hr, E_INVALIDARG, "BA passed NULL hwndParent to Apply."); if (!::IsWindow(hwndParent)) { - ExitOnFailure(hr = E_INVALIDARG, "BA passed invalid hwndParent to Apply."); + ExitOnRootFailure(hr = E_INVALIDARG, "BA passed invalid hwndParent to Apply."); } if (!::PostThreadMessageW(dwThreadId, WM_BURN_APPLY, 0, reinterpret_cast(hwndParent))) diff --git a/src/engine/logging.cpp b/src/engine/logging.cpp index a1159c4..065ef90 100644 --- a/src/engine/logging.cpp +++ b/src/engine/logging.cpp @@ -390,8 +390,6 @@ extern "C" LPCSTR LoggingPackageStateToString( return "Obsolete"; case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: return "Absent"; - case BOOTSTRAPPER_PACKAGE_STATE_CACHED: - return "Cached"; case BOOTSTRAPPER_PACKAGE_STATE_PRESENT: return "Present"; case BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED: diff --git a/src/engine/msiengine.cpp b/src/engine/msiengine.cpp index e3dc467..3e96e5f 100644 --- a/src/engine/msiengine.cpp +++ b/src/engine/msiengine.cpp @@ -700,7 +700,7 @@ extern "C" HRESULT MsiEngineDetectPackage( if (pPackage->fCanAffectRegistration) { - pPackage->installRegistrationState = BOOTSTRAPPER_PACKAGE_STATE_CACHED < pPackage->currentState ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT; + pPackage->installRegistrationState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT < pPackage->currentState ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT; } LExit: @@ -768,7 +768,7 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage( if (pPackage->Msi.cFeatures) { // If the package is present and we're repairing it. - BOOL fRepairingPackage = (BOOTSTRAPPER_PACKAGE_STATE_CACHED < pPackage->currentState && BOOTSTRAPPER_REQUEST_STATE_REPAIR == pPackage->requested); + BOOL fRepairingPackage = (BOOTSTRAPPER_PACKAGE_STATE_ABSENT < pPackage->currentState && BOOTSTRAPPER_REQUEST_STATE_REPAIR == pPackage->requested); // plan features for (DWORD i = 0; i < pPackage->Msi.cFeatures; ++i) @@ -829,21 +829,6 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage( } break; - case BOOTSTRAPPER_PACKAGE_STATE_CACHED: - switch (pPackage->requested) - { - case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; - case BOOTSTRAPPER_REQUEST_STATE_MEND: __fallthrough; - case BOOTSTRAPPER_REQUEST_STATE_REPAIR: - execute = BOOTSTRAPPER_ACTION_STATE_INSTALL; - break; - - default: - execute = BOOTSTRAPPER_ACTION_STATE_NONE; - break; - } - break; - case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: __fallthrough; case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: switch (pPackage->requested) @@ -892,7 +877,6 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage( case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: __fallthrough; case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: __fallthrough; - case BOOTSTRAPPER_PACKAGE_STATE_CACHED: // If the package is uninstallable and we requested to put the package on the machine then // remove the package during rollback. if (pPackage->fUninstallable && diff --git a/src/engine/mspengine.cpp b/src/engine/mspengine.cpp index d567370..6d58d32 100644 --- a/src/engine/mspengine.cpp +++ b/src/engine/mspengine.cpp @@ -451,7 +451,6 @@ extern "C" HRESULT MspEnginePlanCalculatePackage( break; case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: __fallthrough; - case BOOTSTRAPPER_PACKAGE_STATE_CACHED: switch (pTargetProduct->requested) { case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; diff --git a/src/engine/msuengine.cpp b/src/engine/msuengine.cpp index f807bf6..6003123 100644 --- a/src/engine/msuengine.cpp +++ b/src/engine/msuengine.cpp @@ -71,7 +71,7 @@ extern "C" HRESULT MsuEngineDetectPackage( if (pPackage->fCanAffectRegistration) { - pPackage->installRegistrationState = BOOTSTRAPPER_PACKAGE_STATE_CACHED < pPackage->currentState ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT; + pPackage->installRegistrationState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT < pPackage->currentState ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT; } LExit: diff --git a/src/engine/package.cpp b/src/engine/package.cpp index dd4e498..3f8c8b0 100644 --- a/src/engine/package.cpp +++ b/src/engine/package.cpp @@ -118,20 +118,20 @@ extern "C" HRESULT PackagesParseFromXml( { if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"remove", -1)) { - pPackage->cacheType = BURN_CACHE_TYPE_NO; + pPackage->authoredCacheType = BOOTSTRAPPER_CACHE_TYPE_REMOVE; } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"keep", -1)) { - pPackage->cacheType = BURN_CACHE_TYPE_YES; + pPackage->authoredCacheType = BOOTSTRAPPER_CACHE_TYPE_KEEP; } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"force", -1)) { - pPackage->cacheType = BURN_CACHE_TYPE_ALWAYS; + pPackage->authoredCacheType = BOOTSTRAPPER_CACHE_TYPE_FORCE; } else { hr = E_UNEXPECTED; - ExitOnFailure(hr, "Invalid cache type: %ls", scz); + ExitOnRootFailure(hr, "Invalid cache type: %ls", scz); } } ExitOnFailure(hr, "Failed to get @Cache."); diff --git a/src/engine/package.h b/src/engine/package.h index 2091af9..89a3d6e 100644 --- a/src/engine/package.h +++ b/src/engine/package.h @@ -41,13 +41,6 @@ enum BURN_PACKAGE_TYPE BURN_PACKAGE_TYPE_MSU, }; -enum BURN_CACHE_TYPE -{ - BURN_CACHE_TYPE_NO, - BURN_CACHE_TYPE_YES, - BURN_CACHE_TYPE_ALWAYS, -}; - enum BURN_DEPENDENCY_ACTION { BURN_DEPENDENCY_ACTION_NONE, @@ -223,7 +216,7 @@ typedef struct _BURN_PACKAGE BOOL fVital; BOOL fCanAffectRegistration; - BURN_CACHE_TYPE cacheType; + BOOTSTRAPPER_CACHE_TYPE authoredCacheType; LPWSTR sczCacheId; DWORD64 qwInstallSize; @@ -235,6 +228,7 @@ typedef struct _BURN_PACKAGE BOOTSTRAPPER_PACKAGE_STATE currentState; // only valid after Detect. BOOL fCached; // only valid after Detect. BOOL fPackageProviderExists; // only valid after Detect. + BOOTSTRAPPER_CACHE_TYPE cacheType; // only valid during Plan. BOOTSTRAPPER_REQUEST_STATE defaultRequested;// only valid during Plan. BOOTSTRAPPER_REQUEST_STATE requested; // only valid during Plan. BOOL fPlannedCache; // only valid during Plan. diff --git a/src/engine/plan.cpp b/src/engine/plan.cpp index e5c1ee3..9a4aa5f 100644 --- a/src/engine/plan.cpp +++ b/src/engine/plan.cpp @@ -137,6 +137,10 @@ static BOOL NeedsCache( __in BURN_PACKAGE* pPackage, __in BOOL fExecute ); +static BOOL ForceCache( + __in BURN_PLAN* pPlan, + __in BURN_PACKAGE* pPackage + ); // function definitions @@ -312,28 +316,20 @@ extern "C" HRESULT PlanDefaultPackageRequestState( __in BURN_PACKAGE_TYPE packageType, __in BOOTSTRAPPER_PACKAGE_STATE currentState, __in BOOL fPermanent, - __in BURN_CACHE_TYPE cacheType, __in BOOTSTRAPPER_ACTION action, - __in BOOL fInstallCondition, + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, __in BOOTSTRAPPER_RELATION_TYPE relationType, __out BOOTSTRAPPER_REQUEST_STATE* pRequestState ) { HRESULT hr = S_OK; BOOTSTRAPPER_REQUEST_STATE defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; - BOOL fFallbackToCache = BURN_CACHE_TYPE_ALWAYS == cacheType && BOOTSTRAPPER_ACTION_UNINSTALL != action && BOOTSTRAPPER_PACKAGE_STATE_CACHED > currentState; - // If doing layout, then always default to requesting the file be cached. + // If doing layout, then always default to requesting the package be cached. if (BOOTSTRAPPER_ACTION_LAYOUT == action) { *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE; } - else if (BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED == currentState && BOOTSTRAPPER_ACTION_UNINSTALL != action) - { - // Superseded means the package is on the machine but not active, so only uninstall operations are allowed. - // Requesting present makes sure always-cached packages are cached. - *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; - } else if (BOOTSTRAPPER_RELATION_PATCH == relationType && BURN_PACKAGE_TYPE_MSP == packageType) { // For patch related bundles, only install a patch if currently absent during install, modify, or repair. @@ -341,20 +337,22 @@ extern "C" HRESULT PlanDefaultPackageRequestState( { *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; } - else if (fFallbackToCache) - { - *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE; - } else { *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; } } + else if (BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED == currentState && BOOTSTRAPPER_ACTION_UNINSTALL != action) + { + // Superseded means the package is on the machine but not active, so only uninstall operations are allowed. + // All other operations do nothing. + *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; + } else if (BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE == currentState && !(BOOTSTRAPPER_ACTION_UNINSTALL == action && BURN_PACKAGE_TYPE_MSP == packageType)) { // Obsolete means the package is not on the machine and should not be installed, *except* patches can be obsolete // and present so allow them to be removed during uninstall. Everyone else, gets nothing. - *pRequestState = fFallbackToCache ? BOOTSTRAPPER_REQUEST_STATE_CACHE : BOOTSTRAPPER_REQUEST_STATE_NONE; + *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; } else // pick the best option for the action state and install condition. { @@ -363,7 +361,7 @@ extern "C" HRESULT PlanDefaultPackageRequestState( // If we're doing an install, use the install condition // to determine whether to use the default request state or make the package absent. - if (BOOTSTRAPPER_ACTION_UNINSTALL != action && !fInstallCondition) + if (BOOTSTRAPPER_ACTION_UNINSTALL != action && BOOTSTRAPPER_PACKAGE_CONDITION_FALSE == installCondition) { *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT; } @@ -371,11 +369,6 @@ extern "C" HRESULT PlanDefaultPackageRequestState( { *pRequestState = defaultRequestState; } - - if (fFallbackToCache && BOOTSTRAPPER_REQUEST_STATE_CACHE > *pRequestState) - { - *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE; - } } LExit: @@ -844,8 +837,8 @@ static HRESULT PlanPackagesHelper( { DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i; BURN_PACKAGE* pPackage = rgPackages + iPackage; - - UserExperienceOnPlannedPackage(pUX, pPackage->sczId, pPackage->execute, pPackage->rollback); + + UserExperienceOnPlannedPackage(pUX, pPackage->sczId, pPackage->execute, pPackage->rollback, pPackage->fPlannedCache, pPackage->fPlannedUncache); } LExit: @@ -861,6 +854,7 @@ static HRESULT InitializePackage( ) { HRESULT hr = S_OK; + BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition = BOOTSTRAPPER_PACKAGE_CONDITION_DEFAULT; BOOL fInstallCondition = FALSE; BOOL fBeginCalled = FALSE; @@ -874,20 +868,18 @@ static HRESULT InitializePackage( { hr = ConditionEvaluate(pVariables, pPackage->sczInstallCondition, &fInstallCondition); ExitOnFailure(hr, "Failed to evaluate install condition."); - } - else - { - fInstallCondition = TRUE; + + installCondition = fInstallCondition ? BOOTSTRAPPER_PACKAGE_CONDITION_TRUE : BOOTSTRAPPER_PACKAGE_CONDITION_FALSE; } // Remember the default requested state so the engine doesn't get blamed for planning the wrong thing if the BA changes it. - hr = PlanDefaultPackageRequestState(pPackage->type, pPackage->currentState, !pPackage->fUninstallable, pPackage->cacheType, pPlan->action, fInstallCondition, relationType, &pPackage->defaultRequested); + hr = PlanDefaultPackageRequestState(pPackage->type, pPackage->currentState, !pPackage->fUninstallable, pPlan->action, installCondition, relationType, &pPackage->defaultRequested); ExitOnFailure(hr, "Failed to set default package state."); pPackage->requested = pPackage->defaultRequested; fBeginCalled = TRUE; - hr = UserExperienceOnPlanPackageBegin(pUX, pPackage->sczId, pPackage->currentState, fInstallCondition, &pPackage->requested); + hr = UserExperienceOnPlanPackageBegin(pUX, pPackage->sczId, pPackage->currentState, pPackage->fCached, installCondition, &pPackage->requested, &pPackage->cacheType); ExitOnRootFailure(hr, "BA aborted plan package begin."); if (BURN_PACKAGE_TYPE_MSI == pPackage->type) @@ -926,8 +918,11 @@ static HRESULT ProcessPackage( if (BOOTSTRAPPER_ACTION_LAYOUT == pPlan->action) { - hr = PlanLayoutPackage(pPlan, pPackage); - ExitOnFailure(hr, "Failed to plan layout package."); + if (BOOTSTRAPPER_REQUEST_STATE_NONE != pPackage->requested) + { + hr = PlanLayoutPackage(pPlan, pPackage); + ExitOnFailure(hr, "Failed to plan layout package."); + } } else { @@ -939,6 +934,17 @@ static HRESULT ProcessPackage( } else { + if (ForceCache(pPlan, pPackage)) + { + hr = AddCachePackage(pPlan, pPackage, phSyncpointEvent); + ExitOnFailure(hr, "Failed to plan cache package."); + + if (pPackage->fPerMachine) + { + pPlan->fPerMachine = TRUE; + } + } + // Make sure the package is properly ref-counted even if no plan is requested. hr = PlanDependencyActions(fBundlePerMachine, pPlan, pPackage); ExitOnFailure(hr, "Failed to plan dependency actions for package: %ls", pPackage->sczId); @@ -1072,8 +1078,7 @@ extern "C" HRESULT PlanExecutePackage( ) { HRESULT hr = S_OK; - BOOL fRequestedCache = BOOTSTRAPPER_REQUEST_STATE_CACHE == pPackage->requested || - BOOTSTRAPPER_REQUEST_STATE_ABSENT < pPackage->requested && BURN_CACHE_TYPE_ALWAYS == pPackage->cacheType; + BOOL fRequestedCache = BOOTSTRAPPER_REQUEST_STATE_CACHE == pPackage->requested || ForceCache(pPlan, pPackage); hr = CalculateExecuteActions(pPackage, pPlan->pActiveRollbackBoundary); ExitOnFailure(hr, "Failed to calculate plan actions for package: %ls", pPackage->sczId); @@ -1097,12 +1102,12 @@ extern "C" HRESULT PlanExecutePackage( // Add the cache and install size to estimated size if it will be on the machine at the end of the install if (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested || - BOOTSTRAPPER_REQUEST_STATE_CACHE == pPackage->requested || + fRequestedCache || (BOOTSTRAPPER_PACKAGE_STATE_PRESENT == pPackage->currentState && BOOTSTRAPPER_REQUEST_STATE_ABSENT < pPackage->requested) ) { // If the package will remain in the cache, add the package size to the estimated size - if (BURN_CACHE_TYPE_NO < pPackage->cacheType) + if (BOOTSTRAPPER_CACHE_TYPE_REMOVE < pPackage->cacheType) { pPlan->qwEstimatedSize += pPackage->qwSize; } @@ -1522,12 +1527,12 @@ extern "C" HRESULT PlanCleanPackage( BURN_CLEAN_ACTION* pCleanAction = NULL; // The following is a complex set of logic that determines when a package should be cleaned from the cache. - if (BURN_CACHE_TYPE_ALWAYS > pPackage->cacheType || BOOTSTRAPPER_ACTION_CACHE > pPlan->action) + if (BOOTSTRAPPER_CACHE_TYPE_FORCE > pPackage->cacheType || BOOTSTRAPPER_ACTION_CACHE > pPlan->action) { // The following are all different reasons why the package should be cleaned from the cache. // The else-ifs are used to make the conditions easier to see (rather than have them combined // in one huge condition). - if (BURN_CACHE_TYPE_YES > pPackage->cacheType) // easy, package is not supposed to stay cached. + if (BOOTSTRAPPER_CACHE_TYPE_KEEP > pPackage->cacheType) // easy, package is not supposed to stay cached. { fPlanCleanPackage = TRUE; } @@ -1867,6 +1872,7 @@ static void ResetPlannedPackageState( ) { // Reset package state that is a result of planning. + pPackage->cacheType = pPackage->authoredCacheType; pPackage->defaultRequested = BOOTSTRAPPER_REQUEST_STATE_NONE; pPackage->requested = BOOTSTRAPPER_REQUEST_STATE_NONE; pPackage->fPlannedCache = FALSE; @@ -1948,10 +1954,6 @@ static HRESULT GetActionDefaultRequestState( *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; break; - case BOOTSTRAPPER_PACKAGE_STATE_CACHED: - *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; - break; - default: *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE; break; @@ -1979,10 +1981,6 @@ static HRESULT GetActionDefaultRequestState( *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT; break; - case BOOTSTRAPPER_PACKAGE_STATE_CACHED: - *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE; - break; - case BOOTSTRAPPER_PACKAGE_STATE_PRESENT: *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; break; @@ -2524,6 +2522,15 @@ static BOOL NeedsCache( } } +static BOOL ForceCache( + __in BURN_PLAN* pPlan, + __in BURN_PACKAGE* pPackage + ) +{ + // All packages that have cacheType set to force should be cached if the bundle is going to be present. + return BOOTSTRAPPER_CACHE_TYPE_FORCE == pPackage->cacheType && BOOTSTRAPPER_ACTION_UNINSTALL < pPlan->action; +} + static void CacheActionLog( __in DWORD iAction, __in BURN_CACHE_ACTION* pAction, diff --git a/src/engine/plan.h b/src/engine/plan.h index 4ba2df6..00ab551 100644 --- a/src/engine/plan.h +++ b/src/engine/plan.h @@ -309,9 +309,8 @@ HRESULT PlanDefaultPackageRequestState( __in BURN_PACKAGE_TYPE packageType, __in BOOTSTRAPPER_PACKAGE_STATE currentState, __in BOOL fPermanent, - __in BURN_CACHE_TYPE cacheType, __in BOOTSTRAPPER_ACTION action, - __in BOOL fInstallCondition, + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, __in BOOTSTRAPPER_RELATION_TYPE relationType, __out BOOTSTRAPPER_REQUEST_STATE* pRequestState ); diff --git a/src/engine/userexperience.cpp b/src/engine/userexperience.cpp index ab63195..2215a07 100644 --- a/src/engine/userexperience.cpp +++ b/src/engine/userexperience.cpp @@ -1141,7 +1141,8 @@ EXTERN_C BAAPI UserExperienceOnDetectPackageComplete( __in BURN_USER_EXPERIENCE* pUserExperience, __in_z LPCWSTR wzPackageId, __in HRESULT hrStatus, - __in BOOTSTRAPPER_PACKAGE_STATE state + __in BOOTSTRAPPER_PACKAGE_STATE state, + __in BOOL fCached ) { HRESULT hr = S_OK; @@ -1152,6 +1153,7 @@ EXTERN_C BAAPI UserExperienceOnDetectPackageComplete( args.wzPackageId = wzPackageId; args.hrStatus = hrStatus; args.state = state; + args.fCached = fCached; results.cbSize = sizeof(results); @@ -1937,7 +1939,9 @@ EXTERN_C BAAPI UserExperienceOnPlannedPackage( __in BURN_USER_EXPERIENCE* pUserExperience, __in_z LPCWSTR wzPackageId, __in BOOTSTRAPPER_ACTION_STATE execute, - __in BOOTSTRAPPER_ACTION_STATE rollback + __in BOOTSTRAPPER_ACTION_STATE rollback, + __in BOOL fPlannedCache, + __in BOOL fPlannedUncache ) { HRESULT hr = S_OK; @@ -1948,6 +1952,8 @@ EXTERN_C BAAPI UserExperienceOnPlannedPackage( args.wzPackageId = wzPackageId; args.execute = execute; args.rollback = rollback; + args.fPlannedCache = fPlannedCache; + args.fPlannedUncache = fPlannedUncache; results.cbSize = sizeof(results); @@ -1962,8 +1968,10 @@ EXTERN_C BAAPI UserExperienceOnPlanPackageBegin( __in BURN_USER_EXPERIENCE* pUserExperience, __in_z LPCWSTR wzPackageId, __in BOOTSTRAPPER_PACKAGE_STATE state, - __in BOOL fInstallCondition, - __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState + __in BOOL fCached, + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, + __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState, + __inout BOOTSTRAPPER_CACHE_TYPE* pRequestedCacheType ) { HRESULT hr = S_OK; @@ -1973,11 +1981,14 @@ EXTERN_C BAAPI UserExperienceOnPlanPackageBegin( args.cbSize = sizeof(args); args.wzPackageId = wzPackageId; args.state = state; - args.fInstallCondition = fInstallCondition; + args.fCached = fCached; + args.installCondition = installCondition; args.recommendedState = *pRequestedState; + args.recommendedCacheType = *pRequestedCacheType; results.cbSize = sizeof(results); results.requestedState = *pRequestedState; + results.requestedCacheType = *pRequestedCacheType; hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGEBEGIN, &args, &results); ExitOnFailure(hr, "BA OnPlanPackageBegin failed."); @@ -1987,6 +1998,7 @@ EXTERN_C BAAPI UserExperienceOnPlanPackageBegin( hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); } *pRequestedState = results.requestedState; + *pRequestedCacheType = results.requestedCacheType; LExit: return hr; diff --git a/src/engine/userexperience.h b/src/engine/userexperience.h index e104162..f2453dc 100644 --- a/src/engine/userexperience.h +++ b/src/engine/userexperience.h @@ -279,7 +279,8 @@ BAAPI UserExperienceOnDetectPackageComplete( __in BURN_USER_EXPERIENCE* pUserExperience, __in_z LPCWSTR wzPackageId, __in HRESULT hrStatus, - __in BOOTSTRAPPER_PACKAGE_STATE state + __in BOOTSTRAPPER_PACKAGE_STATE state, + __in BOOL fCached ); BAAPI UserExperienceOnDetectRelatedBundle( __in BURN_USER_EXPERIENCE* pUserExperience, @@ -448,14 +449,18 @@ BAAPI UserExperienceOnPlannedPackage( __in BURN_USER_EXPERIENCE* pUserExperience, __in_z LPCWSTR wzPackageId, __in BOOTSTRAPPER_ACTION_STATE execute, - __in BOOTSTRAPPER_ACTION_STATE rollback + __in BOOTSTRAPPER_ACTION_STATE rollback, + __in BOOL fPlannedCache, + __in BOOL fPlannedUncache ); BAAPI UserExperienceOnPlanPackageBegin( __in BURN_USER_EXPERIENCE* pUserExperience, __in_z LPCWSTR wzPackageId, __in BOOTSTRAPPER_PACKAGE_STATE state, - __in BOOL fInstallCondition, - __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState + __in BOOL fCached, + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition, + __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState, + __inout BOOTSTRAPPER_CACHE_TYPE* pRequestedCacheType ); BAAPI UserExperienceOnPlanPackageComplete( __in BURN_USER_EXPERIENCE* pUserExperience,