@joebigelow / wix-1 / commits / 752f0e05

Let BA override the package's cache type during Plan. Rename cache types to REMOVE, KEEP, FORCE. Change implementation of FORCE to not be through CACHED request state. Create package condition enum so BA can tell when InstallCondition wasn't specified. Tell BA when package is cached. Tell BA when package is planned to be cached and uncached.

Let BA override the package's cache type during Plan. Rename cache types to REMOVE, KEEP, FORCE. Change implementation of FORCE to not be through CACHED request state. Create package condition enum so BA can tell when InstallCondition wasn't specified. Tell BA when package is cached. Tell BA when package is planned to be cached and uncached.

Sean Hall committed Apr 28, 2021 at 16:43 UTC 752f0e0576dc27e937c553ed9dce5576bd388e95
16 files changed +117 -102
src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
+21 -1
@@ -103,6 +103,20 @@ enum BOOTSTRAPPER_RELATION_TYPE
103 BOOTSTRAPPER_RELATION_UPDATE,
104 };
105
106 +enum BOOTSTRAPPER_CACHE_TYPE
107 +{
108 + BOOTSTRAPPER_CACHE_TYPE_REMOVE,
109 + BOOTSTRAPPER_CACHE_TYPE_KEEP,
110 + BOOTSTRAPPER_CACHE_TYPE_FORCE,
111 +};
112 +
113 +enum BOOTSTRAPPER_PACKAGE_CONDITION_RESULT
114 +{
115 + BOOTSTRAPPER_PACKAGE_CONDITION_DEFAULT,
116 + BOOTSTRAPPER_PACKAGE_CONDITION_FALSE,
117 + BOOTSTRAPPER_PACKAGE_CONDITION_TRUE,
118 +};
119 +
120 enum BOOTSTRAPPER_APPLICATION_MESSAGE
121 {
122 BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTBEGIN,
@@ -682,6 +696,7 @@ struct BA_ONDETECTPACKAGECOMPLETE_ARGS
696 LPCWSTR wzPackageId;
697 HRESULT hrStatus;
698 BOOTSTRAPPER_PACKAGE_STATE state;
699 + BOOL fCached;
700 };
701
702 struct BA_ONDETECTPACKAGECOMPLETE_RESULTS
@@ -1062,6 +1077,8 @@ struct BA_ONPLANNEDPACKAGE_ARGS
1077 LPCWSTR wzPackageId;
1078 BOOTSTRAPPER_ACTION_STATE execute;
1079 BOOTSTRAPPER_ACTION_STATE rollback;
1080 + BOOL fPlannedCache;
1081 + BOOL fPlannedUncache;
1082 };
1083
1084 struct BA_ONPLANNEDPACKAGE_RESULTS
@@ -1074,8 +1091,10 @@ struct BA_ONPLANPACKAGEBEGIN_ARGS
1091 DWORD cbSize;
1092 LPCWSTR wzPackageId;
1093 BOOTSTRAPPER_PACKAGE_STATE state;
1077 - BOOL fInstallCondition;
1094 + BOOL fCached;
1095 + BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition;
1096 BOOTSTRAPPER_REQUEST_STATE recommendedState;
1097 + BOOTSTRAPPER_CACHE_TYPE recommendedCacheType;
1098 };
1099
1100 struct BA_ONPLANPACKAGEBEGIN_RESULTS
@@ -1083,6 +1102,7 @@ struct BA_ONPLANPACKAGEBEGIN_RESULTS
1102 DWORD cbSize;
1103 BOOL fCancel;
1104 BOOTSTRAPPER_REQUEST_STATE requestedState;
1105 + BOOTSTRAPPER_CACHE_TYPE requestedCacheType;
1106 };
1107
1108 struct BA_ONPLANPACKAGECOMPLETE_ARGS
src/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h
-1
@@ -47,7 +47,6 @@ enum BOOTSTRAPPER_PACKAGE_STATE
47 BOOTSTRAPPER_PACKAGE_STATE_UNKNOWN,
48 BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE,
49 BOOTSTRAPPER_PACKAGE_STATE_ABSENT,
50 - BOOTSTRAPPER_PACKAGE_STATE_CACHED,
50 BOOTSTRAPPER_PACKAGE_STATE_PRESENT,
51 BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED,
52 };
src/engine/core.cpp
+1 -7
@@ -1640,12 +1640,6 @@ static HRESULT DetectPackage(
1640 ExitOnRootFailure(hr, "Package type not supported by detect yet.");
1641 }
1642
1643 - // TODO: consider how to notify the UX that a package is cached.
1644 - //else if (BOOTSTRAPPER_PACKAGE_STATE_CACHED > pPackage->currentState && pPackage->fCached)
1645 - //{
1646 - // pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_CACHED;
1647 - //}
1648 -
1643 LExit:
1644 if (FAILED(hr))
1645 {
@@ -1654,7 +1648,7 @@ LExit:
1648
1649 if (fBegan)
1650 {
1657 - UserExperienceOnDetectPackageComplete(&pEngineState->userExperience, pPackage->sczId, hr, pPackage->currentState);
1651 + UserExperienceOnDetectPackageComplete(&pEngineState->userExperience, pPackage->sczId, hr, pPackage->currentState, pPackage->fCached);
1652 }
1653
1654 return hr;
src/engine/dependency.cpp
-1
@@ -1065,7 +1065,6 @@ static void CalculateDependencyActionStates(
1065 {
1066 case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: __fallthrough;
1067 case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: __fallthrough;
1068 - case BOOTSTRAPPER_PACKAGE_STATE_CACHED:
1068 *pDependencyRollbackAction = BURN_DEPENDENCY_ACTION_UNREGISTER;
1069 break;
1070 }
src/engine/exeengine.cpp
+1 -1
@@ -146,7 +146,7 @@ extern "C" HRESULT ExeEngineDetectPackage(
146
147 if (pPackage->fCanAffectRegistration)
148 {
149 - pPackage->installRegistrationState = BOOTSTRAPPER_PACKAGE_STATE_CACHED < pPackage->currentState ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
149 + pPackage->installRegistrationState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT < pPackage->currentState ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
150 }
151
152 LExit:
src/engine/externalengine.cpp
+6 -1
@@ -582,6 +582,11 @@ HRESULT ExternalEnginePlan(
582 {
583 HRESULT hr = S_OK;
584
585 + if (BOOTSTRAPPER_ACTION_LAYOUT > action || BOOTSTRAPPER_ACTION_UPDATE_REPLACE_EMBEDDED < action)
586 + {
587 + ExitOnRootFailure(hr = E_INVALIDARG, "BA passed invalid action to Plan: %u.", action);
588 + }
589 +
590 if (!::PostThreadMessageW(dwThreadId, WM_BURN_PLAN, 0, action))
591 {
592 ExitWithLastError(hr, "Failed to post plan message.");
@@ -622,7 +627,7 @@ HRESULT ExternalEngineApply(
627 ExitOnNull(hwndParent, hr, E_INVALIDARG, "BA passed NULL hwndParent to Apply.");
628 if (!::IsWindow(hwndParent))
629 {
625 - ExitOnFailure(hr = E_INVALIDARG, "BA passed invalid hwndParent to Apply.");
630 + ExitOnRootFailure(hr = E_INVALIDARG, "BA passed invalid hwndParent to Apply.");
631 }
632
633 if (!::PostThreadMessageW(dwThreadId, WM_BURN_APPLY, 0, reinterpret_cast<LPARAM>(hwndParent)))
src/engine/logging.cpp
-2
@@ -390,8 +390,6 @@ extern "C" LPCSTR LoggingPackageStateToString(
390 return "Obsolete";
391 case BOOTSTRAPPER_PACKAGE_STATE_ABSENT:
392 return "Absent";
393 - case BOOTSTRAPPER_PACKAGE_STATE_CACHED:
394 - return "Cached";
393 case BOOTSTRAPPER_PACKAGE_STATE_PRESENT:
394 return "Present";
395 case BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED:
src/engine/msiengine.cpp
+2 -18
@@ -700,7 +700,7 @@ extern "C" HRESULT MsiEngineDetectPackage(
700
701 if (pPackage->fCanAffectRegistration)
702 {
703 - pPackage->installRegistrationState = BOOTSTRAPPER_PACKAGE_STATE_CACHED < pPackage->currentState ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
703 + pPackage->installRegistrationState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT < pPackage->currentState ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
704 }
705
706 LExit:
@@ -768,7 +768,7 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
768 if (pPackage->Msi.cFeatures)
769 {
770 // If the package is present and we're repairing it.
771 - BOOL fRepairingPackage = (BOOTSTRAPPER_PACKAGE_STATE_CACHED < pPackage->currentState && BOOTSTRAPPER_REQUEST_STATE_REPAIR == pPackage->requested);
771 + BOOL fRepairingPackage = (BOOTSTRAPPER_PACKAGE_STATE_ABSENT < pPackage->currentState && BOOTSTRAPPER_REQUEST_STATE_REPAIR == pPackage->requested);
772
773 // plan features
774 for (DWORD i = 0; i < pPackage->Msi.cFeatures; ++i)
@@ -829,21 +829,6 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
829 }
830 break;
831
832 - case BOOTSTRAPPER_PACKAGE_STATE_CACHED:
833 - switch (pPackage->requested)
834 - {
835 - case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough;
836 - case BOOTSTRAPPER_REQUEST_STATE_MEND: __fallthrough;
837 - case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
838 - execute = BOOTSTRAPPER_ACTION_STATE_INSTALL;
839 - break;
840 -
841 - default:
842 - execute = BOOTSTRAPPER_ACTION_STATE_NONE;
843 - break;
844 - }
845 - break;
846 -
832 case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: __fallthrough;
833 case BOOTSTRAPPER_PACKAGE_STATE_ABSENT:
834 switch (pPackage->requested)
@@ -892,7 +877,6 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
877
878 case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: __fallthrough;
879 case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: __fallthrough;
895 - case BOOTSTRAPPER_PACKAGE_STATE_CACHED:
880 // If the package is uninstallable and we requested to put the package on the machine then
881 // remove the package during rollback.
882 if (pPackage->fUninstallable &&
src/engine/mspengine.cpp
-1
@@ -451,7 +451,6 @@ extern "C" HRESULT MspEnginePlanCalculatePackage(
451 break;
452
453 case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: __fallthrough;
454 - case BOOTSTRAPPER_PACKAGE_STATE_CACHED:
454 switch (pTargetProduct->requested)
455 {
456 case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough;
src/engine/msuengine.cpp
+1 -1
@@ -71,7 +71,7 @@ extern "C" HRESULT MsuEngineDetectPackage(
71
72 if (pPackage->fCanAffectRegistration)
73 {
74 - pPackage->installRegistrationState = BOOTSTRAPPER_PACKAGE_STATE_CACHED < pPackage->currentState ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
74 + pPackage->installRegistrationState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT < pPackage->currentState ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
75 }
76
77 LExit:
src/engine/package.cpp
+4 -4
@@ -118,20 +118,20 @@ extern "C" HRESULT PackagesParseFromXml(
118 {
119 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"remove", -1))
120 {
121 - pPackage->cacheType = BURN_CACHE_TYPE_NO;
121 + pPackage->authoredCacheType = BOOTSTRAPPER_CACHE_TYPE_REMOVE;
122 }
123 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"keep", -1))
124 {
125 - pPackage->cacheType = BURN_CACHE_TYPE_YES;
125 + pPackage->authoredCacheType = BOOTSTRAPPER_CACHE_TYPE_KEEP;
126 }
127 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"force", -1))
128 {
129 - pPackage->cacheType = BURN_CACHE_TYPE_ALWAYS;
129 + pPackage->authoredCacheType = BOOTSTRAPPER_CACHE_TYPE_FORCE;
130 }
131 else
132 {
133 hr = E_UNEXPECTED;
134 - ExitOnFailure(hr, "Invalid cache type: %ls", scz);
134 + ExitOnRootFailure(hr, "Invalid cache type: %ls", scz);
135 }
136 }
137 ExitOnFailure(hr, "Failed to get @Cache.");
src/engine/package.h
+2 -8
@@ -41,13 +41,6 @@ enum BURN_PACKAGE_TYPE
41 BURN_PACKAGE_TYPE_MSU,
42 };
43
44 -enum BURN_CACHE_TYPE
45 -{
46 - BURN_CACHE_TYPE_NO,
47 - BURN_CACHE_TYPE_YES,
48 - BURN_CACHE_TYPE_ALWAYS,
49 -};
50 -
44 enum BURN_DEPENDENCY_ACTION
45 {
46 BURN_DEPENDENCY_ACTION_NONE,
@@ -223,7 +216,7 @@ typedef struct _BURN_PACKAGE
216 BOOL fVital;
217 BOOL fCanAffectRegistration;
218
226 - BURN_CACHE_TYPE cacheType;
219 + BOOTSTRAPPER_CACHE_TYPE authoredCacheType;
220 LPWSTR sczCacheId;
221
222 DWORD64 qwInstallSize;
@@ -235,6 +228,7 @@ typedef struct _BURN_PACKAGE
228 BOOTSTRAPPER_PACKAGE_STATE currentState; // only valid after Detect.
229 BOOL fCached; // only valid after Detect.
230 BOOL fPackageProviderExists; // only valid after Detect.
231 + BOOTSTRAPPER_CACHE_TYPE cacheType; // only valid during Plan.
232 BOOTSTRAPPER_REQUEST_STATE defaultRequested;// only valid during Plan.
233 BOOTSTRAPPER_REQUEST_STATE requested; // only valid during Plan.
234 BOOL fPlannedCache; // only valid during Plan.
src/engine/plan.cpp
+52 -45
@@ -137,6 +137,10 @@ static BOOL NeedsCache(
137 __in BURN_PACKAGE* pPackage,
138 __in BOOL fExecute
139 );
140 +static BOOL ForceCache(
141 + __in BURN_PLAN* pPlan,
142 + __in BURN_PACKAGE* pPackage
143 + );
144
145 // function definitions
146
@@ -312,28 +316,20 @@ extern "C" HRESULT PlanDefaultPackageRequestState(
316 __in BURN_PACKAGE_TYPE packageType,
317 __in BOOTSTRAPPER_PACKAGE_STATE currentState,
318 __in BOOL fPermanent,
315 - __in BURN_CACHE_TYPE cacheType,
319 __in BOOTSTRAPPER_ACTION action,
317 - __in BOOL fInstallCondition,
320 + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
321 __in BOOTSTRAPPER_RELATION_TYPE relationType,
322 __out BOOTSTRAPPER_REQUEST_STATE* pRequestState
323 )
324 {
325 HRESULT hr = S_OK;
326 BOOTSTRAPPER_REQUEST_STATE defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
324 - BOOL fFallbackToCache = BURN_CACHE_TYPE_ALWAYS == cacheType && BOOTSTRAPPER_ACTION_UNINSTALL != action && BOOTSTRAPPER_PACKAGE_STATE_CACHED > currentState;
327
326 - // If doing layout, then always default to requesting the file be cached.
328 + // If doing layout, then always default to requesting the package be cached.
329 if (BOOTSTRAPPER_ACTION_LAYOUT == action)
330 {
331 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE;
332 }
331 - else if (BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED == currentState && BOOTSTRAPPER_ACTION_UNINSTALL != action)
332 - {
333 - // Superseded means the package is on the machine but not active, so only uninstall operations are allowed.
334 - // Requesting present makes sure always-cached packages are cached.
335 - *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
336 - }
333 else if (BOOTSTRAPPER_RELATION_PATCH == relationType && BURN_PACKAGE_TYPE_MSP == packageType)
334 {
335 // For patch related bundles, only install a patch if currently absent during install, modify, or repair.
@@ -341,20 +337,22 @@ extern "C" HRESULT PlanDefaultPackageRequestState(
337 {
338 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
339 }
344 - else if (fFallbackToCache)
345 - {
346 - *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE;
347 - }
340 else
341 {
342 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
343 }
344 }
345 + else if (BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED == currentState && BOOTSTRAPPER_ACTION_UNINSTALL != action)
346 + {
347 + // Superseded means the package is on the machine but not active, so only uninstall operations are allowed.
348 + // All other operations do nothing.
349 + *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
350 + }
351 else if (BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE == currentState && !(BOOTSTRAPPER_ACTION_UNINSTALL == action && BURN_PACKAGE_TYPE_MSP == packageType))
352 {
353 // Obsolete means the package is not on the machine and should not be installed, *except* patches can be obsolete
354 // and present so allow them to be removed during uninstall. Everyone else, gets nothing.
357 - *pRequestState = fFallbackToCache ? BOOTSTRAPPER_REQUEST_STATE_CACHE : BOOTSTRAPPER_REQUEST_STATE_NONE;
355 + *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
356 }
357 else // pick the best option for the action state and install condition.
358 {
@@ -363,7 +361,7 @@ extern "C" HRESULT PlanDefaultPackageRequestState(
361
362 // If we're doing an install, use the install condition
363 // to determine whether to use the default request state or make the package absent.
366 - if (BOOTSTRAPPER_ACTION_UNINSTALL != action && !fInstallCondition)
364 + if (BOOTSTRAPPER_ACTION_UNINSTALL != action && BOOTSTRAPPER_PACKAGE_CONDITION_FALSE == installCondition)
365 {
366 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT;
367 }
@@ -371,11 +369,6 @@ extern "C" HRESULT PlanDefaultPackageRequestState(
369 {
370 *pRequestState = defaultRequestState;
371 }
374 -
375 - if (fFallbackToCache && BOOTSTRAPPER_REQUEST_STATE_CACHE > *pRequestState)
376 - {
377 - *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE;
378 - }
372 }
373
374 LExit:
@@ -844,8 +837,8 @@ static HRESULT PlanPackagesHelper(
837 {
838 DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i;
839 BURN_PACKAGE* pPackage = rgPackages + iPackage;
847 -
848 - UserExperienceOnPlannedPackage(pUX, pPackage->sczId, pPackage->execute, pPackage->rollback);
840 +
841 + UserExperienceOnPlannedPackage(pUX, pPackage->sczId, pPackage->execute, pPackage->rollback, pPackage->fPlannedCache, pPackage->fPlannedUncache);
842 }
843
844 LExit:
@@ -861,6 +854,7 @@ static HRESULT InitializePackage(
854 )
855 {
856 HRESULT hr = S_OK;
857 + BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition = BOOTSTRAPPER_PACKAGE_CONDITION_DEFAULT;
858 BOOL fInstallCondition = FALSE;
859 BOOL fBeginCalled = FALSE;
860
@@ -874,20 +868,18 @@ static HRESULT InitializePackage(
868 {
869 hr = ConditionEvaluate(pVariables, pPackage->sczInstallCondition, &fInstallCondition);
870 ExitOnFailure(hr, "Failed to evaluate install condition.");
877 - }
878 - else
879 - {
880 - fInstallCondition = TRUE;
871 +
872 + installCondition = fInstallCondition ? BOOTSTRAPPER_PACKAGE_CONDITION_TRUE : BOOTSTRAPPER_PACKAGE_CONDITION_FALSE;
873 }
874
875 // Remember the default requested state so the engine doesn't get blamed for planning the wrong thing if the BA changes it.
884 - hr = PlanDefaultPackageRequestState(pPackage->type, pPackage->currentState, !pPackage->fUninstallable, pPackage->cacheType, pPlan->action, fInstallCondition, relationType, &pPackage->defaultRequested);
876 + hr = PlanDefaultPackageRequestState(pPackage->type, pPackage->currentState, !pPackage->fUninstallable, pPlan->action, installCondition, relationType, &pPackage->defaultRequested);
877 ExitOnFailure(hr, "Failed to set default package state.");
878
879 pPackage->requested = pPackage->defaultRequested;
880 fBeginCalled = TRUE;
881
890 - hr = UserExperienceOnPlanPackageBegin(pUX, pPackage->sczId, pPackage->currentState, fInstallCondition, &pPackage->requested);
882 + hr = UserExperienceOnPlanPackageBegin(pUX, pPackage->sczId, pPackage->currentState, pPackage->fCached, installCondition, &pPackage->requested, &pPackage->cacheType);
883 ExitOnRootFailure(hr, "BA aborted plan package begin.");
884
885 if (BURN_PACKAGE_TYPE_MSI == pPackage->type)
@@ -926,8 +918,11 @@ static HRESULT ProcessPackage(
918
919 if (BOOTSTRAPPER_ACTION_LAYOUT == pPlan->action)
920 {
929 - hr = PlanLayoutPackage(pPlan, pPackage);
930 - ExitOnFailure(hr, "Failed to plan layout package.");
921 + if (BOOTSTRAPPER_REQUEST_STATE_NONE != pPackage->requested)
922 + {
923 + hr = PlanLayoutPackage(pPlan, pPackage);
924 + ExitOnFailure(hr, "Failed to plan layout package.");
925 + }
926 }
927 else
928 {
@@ -939,6 +934,17 @@ static HRESULT ProcessPackage(
934 }
935 else
936 {
937 + if (ForceCache(pPlan, pPackage))
938 + {
939 + hr = AddCachePackage(pPlan, pPackage, phSyncpointEvent);
940 + ExitOnFailure(hr, "Failed to plan cache package.");
941 +
942 + if (pPackage->fPerMachine)
943 + {
944 + pPlan->fPerMachine = TRUE;
945 + }
946 + }
947 +
948 // Make sure the package is properly ref-counted even if no plan is requested.
949 hr = PlanDependencyActions(fBundlePerMachine, pPlan, pPackage);
950 ExitOnFailure(hr, "Failed to plan dependency actions for package: %ls", pPackage->sczId);
@@ -1072,8 +1078,7 @@ extern "C" HRESULT PlanExecutePackage(
1078 )
1079 {
1080 HRESULT hr = S_OK;
1075 - BOOL fRequestedCache = BOOTSTRAPPER_REQUEST_STATE_CACHE == pPackage->requested ||
1076 - BOOTSTRAPPER_REQUEST_STATE_ABSENT < pPackage->requested && BURN_CACHE_TYPE_ALWAYS == pPackage->cacheType;
1081 + BOOL fRequestedCache = BOOTSTRAPPER_REQUEST_STATE_CACHE == pPackage->requested || ForceCache(pPlan, pPackage);
1082
1083 hr = CalculateExecuteActions(pPackage, pPlan->pActiveRollbackBoundary);
1084 ExitOnFailure(hr, "Failed to calculate plan actions for package: %ls", pPackage->sczId);
@@ -1097,12 +1102,12 @@ extern "C" HRESULT PlanExecutePackage(
1102
1103 // Add the cache and install size to estimated size if it will be on the machine at the end of the install
1104 if (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested ||
1100 - BOOTSTRAPPER_REQUEST_STATE_CACHE == pPackage->requested ||
1105 + fRequestedCache ||
1106 (BOOTSTRAPPER_PACKAGE_STATE_PRESENT == pPackage->currentState && BOOTSTRAPPER_REQUEST_STATE_ABSENT < pPackage->requested)
1107 )
1108 {
1109 // If the package will remain in the cache, add the package size to the estimated size
1105 - if (BURN_CACHE_TYPE_NO < pPackage->cacheType)
1110 + if (BOOTSTRAPPER_CACHE_TYPE_REMOVE < pPackage->cacheType)
1111 {
1112 pPlan->qwEstimatedSize += pPackage->qwSize;
1113 }
@@ -1522,12 +1527,12 @@ extern "C" HRESULT PlanCleanPackage(
1527 BURN_CLEAN_ACTION* pCleanAction = NULL;
1528
1529 // The following is a complex set of logic that determines when a package should be cleaned from the cache.
1525 - if (BURN_CACHE_TYPE_ALWAYS > pPackage->cacheType || BOOTSTRAPPER_ACTION_CACHE > pPlan->action)
1530 + if (BOOTSTRAPPER_CACHE_TYPE_FORCE > pPackage->cacheType || BOOTSTRAPPER_ACTION_CACHE > pPlan->action)
1531 {
1532 // The following are all different reasons why the package should be cleaned from the cache.
1533 // The else-ifs are used to make the conditions easier to see (rather than have them combined
1534 // in one huge condition).
1530 - if (BURN_CACHE_TYPE_YES > pPackage->cacheType) // easy, package is not supposed to stay cached.
1535 + if (BOOTSTRAPPER_CACHE_TYPE_KEEP > pPackage->cacheType) // easy, package is not supposed to stay cached.
1536 {
1537 fPlanCleanPackage = TRUE;
1538 }
@@ -1867,6 +1872,7 @@ static void ResetPlannedPackageState(
1872 )
1873 {
1874 // Reset package state that is a result of planning.
1875 + pPackage->cacheType = pPackage->authoredCacheType;
1876 pPackage->defaultRequested = BOOTSTRAPPER_REQUEST_STATE_NONE;
1877 pPackage->requested = BOOTSTRAPPER_REQUEST_STATE_NONE;
1878 pPackage->fPlannedCache = FALSE;
@@ -1948,10 +1954,6 @@ static HRESULT GetActionDefaultRequestState(
1954 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
1955 break;
1956
1951 - case BOOTSTRAPPER_PACKAGE_STATE_CACHED:
1952 - *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
1953 - break;
1954 -
1957 default:
1958 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE;
1959 break;
@@ -1979,10 +1981,6 @@ static HRESULT GetActionDefaultRequestState(
1981 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT;
1982 break;
1983
1982 - case BOOTSTRAPPER_PACKAGE_STATE_CACHED:
1983 - *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE;
1984 - break;
1985 -
1984 case BOOTSTRAPPER_PACKAGE_STATE_PRESENT:
1985 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
1986 break;
@@ -2524,6 +2522,15 @@ static BOOL NeedsCache(
2522 }
2523 }
2524
2525 +static BOOL ForceCache(
2526 + __in BURN_PLAN* pPlan,
2527 + __in BURN_PACKAGE* pPackage
2528 + )
2529 +{
2530 + // All packages that have cacheType set to force should be cached if the bundle is going to be present.
2531 + return BOOTSTRAPPER_CACHE_TYPE_FORCE == pPackage->cacheType && BOOTSTRAPPER_ACTION_UNINSTALL < pPlan->action;
2532 +}
2533 +
2534 static void CacheActionLog(
2535 __in DWORD iAction,
2536 __in BURN_CACHE_ACTION* pAction,
src/engine/plan.h
+1 -2
@@ -309,9 +309,8 @@ HRESULT PlanDefaultPackageRequestState(
309 __in BURN_PACKAGE_TYPE packageType,
310 __in BOOTSTRAPPER_PACKAGE_STATE currentState,
311 __in BOOL fPermanent,
312 - __in BURN_CACHE_TYPE cacheType,
312 __in BOOTSTRAPPER_ACTION action,
314 - __in BOOL fInstallCondition,
313 + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
314 __in BOOTSTRAPPER_RELATION_TYPE relationType,
315 __out BOOTSTRAPPER_REQUEST_STATE* pRequestState
316 );
src/engine/userexperience.cpp
+17 -5
@@ -1141,7 +1141,8 @@ EXTERN_C BAAPI UserExperienceOnDetectPackageComplete(
1141 __in BURN_USER_EXPERIENCE* pUserExperience,
1142 __in_z LPCWSTR wzPackageId,
1143 __in HRESULT hrStatus,
1144 - __in BOOTSTRAPPER_PACKAGE_STATE state
1144 + __in BOOTSTRAPPER_PACKAGE_STATE state,
1145 + __in BOOL fCached
1146 )
1147 {
1148 HRESULT hr = S_OK;
@@ -1152,6 +1153,7 @@ EXTERN_C BAAPI UserExperienceOnDetectPackageComplete(
1153 args.wzPackageId = wzPackageId;
1154 args.hrStatus = hrStatus;
1155 args.state = state;
1156 + args.fCached = fCached;
1157
1158 results.cbSize = sizeof(results);
1159
@@ -1937,7 +1939,9 @@ EXTERN_C BAAPI UserExperienceOnPlannedPackage(
1939 __in BURN_USER_EXPERIENCE* pUserExperience,
1940 __in_z LPCWSTR wzPackageId,
1941 __in BOOTSTRAPPER_ACTION_STATE execute,
1940 - __in BOOTSTRAPPER_ACTION_STATE rollback
1942 + __in BOOTSTRAPPER_ACTION_STATE rollback,
1943 + __in BOOL fPlannedCache,
1944 + __in BOOL fPlannedUncache
1945 )
1946 {
1947 HRESULT hr = S_OK;
@@ -1948,6 +1952,8 @@ EXTERN_C BAAPI UserExperienceOnPlannedPackage(
1952 args.wzPackageId = wzPackageId;
1953 args.execute = execute;
1954 args.rollback = rollback;
1955 + args.fPlannedCache = fPlannedCache;
1956 + args.fPlannedUncache = fPlannedUncache;
1957
1958 results.cbSize = sizeof(results);
1959
@@ -1962,8 +1968,10 @@ EXTERN_C BAAPI UserExperienceOnPlanPackageBegin(
1968 __in BURN_USER_EXPERIENCE* pUserExperience,
1969 __in_z LPCWSTR wzPackageId,
1970 __in BOOTSTRAPPER_PACKAGE_STATE state,
1965 - __in BOOL fInstallCondition,
1966 - __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState
1971 + __in BOOL fCached,
1972 + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
1973 + __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState,
1974 + __inout BOOTSTRAPPER_CACHE_TYPE* pRequestedCacheType
1975 )
1976 {
1977 HRESULT hr = S_OK;
@@ -1973,11 +1981,14 @@ EXTERN_C BAAPI UserExperienceOnPlanPackageBegin(
1981 args.cbSize = sizeof(args);
1982 args.wzPackageId = wzPackageId;
1983 args.state = state;
1976 - args.fInstallCondition = fInstallCondition;
1984 + args.fCached = fCached;
1985 + args.installCondition = installCondition;
1986 args.recommendedState = *pRequestedState;
1987 + args.recommendedCacheType = *pRequestedCacheType;
1988
1989 results.cbSize = sizeof(results);
1990 results.requestedState = *pRequestedState;
1991 + results.requestedCacheType = *pRequestedCacheType;
1992
1993 hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGEBEGIN, &args, &results);
1994 ExitOnFailure(hr, "BA OnPlanPackageBegin failed.");
@@ -1987,6 +1998,7 @@ EXTERN_C BAAPI UserExperienceOnPlanPackageBegin(
1998 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
1999 }
2000 *pRequestedState = results.requestedState;
2001 + *pRequestedCacheType = results.requestedCacheType;
2002
2003 LExit:
2004 return hr;
src/engine/userexperience.h
+9 -4
@@ -279,7 +279,8 @@ BAAPI UserExperienceOnDetectPackageComplete(
279 __in BURN_USER_EXPERIENCE* pUserExperience,
280 __in_z LPCWSTR wzPackageId,
281 __in HRESULT hrStatus,
282 - __in BOOTSTRAPPER_PACKAGE_STATE state
282 + __in BOOTSTRAPPER_PACKAGE_STATE state,
283 + __in BOOL fCached
284 );
285 BAAPI UserExperienceOnDetectRelatedBundle(
286 __in BURN_USER_EXPERIENCE* pUserExperience,
@@ -448,14 +449,18 @@ BAAPI UserExperienceOnPlannedPackage(
449 __in BURN_USER_EXPERIENCE* pUserExperience,
450 __in_z LPCWSTR wzPackageId,
451 __in BOOTSTRAPPER_ACTION_STATE execute,
451 - __in BOOTSTRAPPER_ACTION_STATE rollback
452 + __in BOOTSTRAPPER_ACTION_STATE rollback,
453 + __in BOOL fPlannedCache,
454 + __in BOOL fPlannedUncache
455 );
456 BAAPI UserExperienceOnPlanPackageBegin(
457 __in BURN_USER_EXPERIENCE* pUserExperience,
458 __in_z LPCWSTR wzPackageId,
459 __in BOOTSTRAPPER_PACKAGE_STATE state,
457 - __in BOOL fInstallCondition,
458 - __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState
460 + __in BOOL fCached,
461 + __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
462 + __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState,
463 + __inout BOOTSTRAPPER_CACHE_TYPE* pRequestedCacheType
464 );
465 BAAPI UserExperienceOnPlanPackageComplete(
466 __in BURN_USER_EXPERIENCE* pUserExperience,