aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-04-28 16:43:48 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-04-29 14:05:34 -0500
commit752f0e0576dc27e937c553ed9dce5576bd388e95 (patch)
treef95013ccb3bdea206cf8879d6bbf2411a04663c6
parent7099dd38ab902e7fb92706314fa8710a34f165a5 (diff)
downloadwix-752f0e0576dc27e937c553ed9dce5576bd388e95.tar.gz
wix-752f0e0576dc27e937c553ed9dce5576bd388e95.tar.bz2
wix-752f0e0576dc27e937c553ed9dce5576bd388e95.zip
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.
-rw-r--r--src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h22
-rw-r--r--src/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h1
-rw-r--r--src/engine/core.cpp8
-rw-r--r--src/engine/dependency.cpp1
-rw-r--r--src/engine/exeengine.cpp2
-rw-r--r--src/engine/externalengine.cpp7
-rw-r--r--src/engine/logging.cpp2
-rw-r--r--src/engine/msiengine.cpp20
-rw-r--r--src/engine/mspengine.cpp1
-rw-r--r--src/engine/msuengine.cpp2
-rw-r--r--src/engine/package.cpp8
-rw-r--r--src/engine/package.h10
-rw-r--r--src/engine/plan.cpp97
-rw-r--r--src/engine/plan.h3
-rw-r--r--src/engine/userexperience.cpp22
-rw-r--r--src/engine/userexperience.h13
16 files changed, 117 insertions, 102 deletions
diff --git a/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h b/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
index 603df890..2a6d5c8a 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
103 BOOTSTRAPPER_RELATION_UPDATE, 103 BOOTSTRAPPER_RELATION_UPDATE,
104}; 104};
105 105
106enum BOOTSTRAPPER_CACHE_TYPE
107{
108 BOOTSTRAPPER_CACHE_TYPE_REMOVE,
109 BOOTSTRAPPER_CACHE_TYPE_KEEP,
110 BOOTSTRAPPER_CACHE_TYPE_FORCE,
111};
112
113enum BOOTSTRAPPER_PACKAGE_CONDITION_RESULT
114{
115 BOOTSTRAPPER_PACKAGE_CONDITION_DEFAULT,
116 BOOTSTRAPPER_PACKAGE_CONDITION_FALSE,
117 BOOTSTRAPPER_PACKAGE_CONDITION_TRUE,
118};
119
106enum BOOTSTRAPPER_APPLICATION_MESSAGE 120enum BOOTSTRAPPER_APPLICATION_MESSAGE
107{ 121{
108 BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTBEGIN, 122 BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTBEGIN,
@@ -682,6 +696,7 @@ struct BA_ONDETECTPACKAGECOMPLETE_ARGS
682 LPCWSTR wzPackageId; 696 LPCWSTR wzPackageId;
683 HRESULT hrStatus; 697 HRESULT hrStatus;
684 BOOTSTRAPPER_PACKAGE_STATE state; 698 BOOTSTRAPPER_PACKAGE_STATE state;
699 BOOL fCached;
685}; 700};
686 701
687struct BA_ONDETECTPACKAGECOMPLETE_RESULTS 702struct BA_ONDETECTPACKAGECOMPLETE_RESULTS
@@ -1062,6 +1077,8 @@ struct BA_ONPLANNEDPACKAGE_ARGS
1062 LPCWSTR wzPackageId; 1077 LPCWSTR wzPackageId;
1063 BOOTSTRAPPER_ACTION_STATE execute; 1078 BOOTSTRAPPER_ACTION_STATE execute;
1064 BOOTSTRAPPER_ACTION_STATE rollback; 1079 BOOTSTRAPPER_ACTION_STATE rollback;
1080 BOOL fPlannedCache;
1081 BOOL fPlannedUncache;
1065}; 1082};
1066 1083
1067struct BA_ONPLANNEDPACKAGE_RESULTS 1084struct BA_ONPLANNEDPACKAGE_RESULTS
@@ -1074,8 +1091,10 @@ struct BA_ONPLANPACKAGEBEGIN_ARGS
1074 DWORD cbSize; 1091 DWORD cbSize;
1075 LPCWSTR wzPackageId; 1092 LPCWSTR wzPackageId;
1076 BOOTSTRAPPER_PACKAGE_STATE state; 1093 BOOTSTRAPPER_PACKAGE_STATE state;
1077 BOOL fInstallCondition; 1094 BOOL fCached;
1095 BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition;
1078 BOOTSTRAPPER_REQUEST_STATE recommendedState; 1096 BOOTSTRAPPER_REQUEST_STATE recommendedState;
1097 BOOTSTRAPPER_CACHE_TYPE recommendedCacheType;
1079}; 1098};
1080 1099
1081struct BA_ONPLANPACKAGEBEGIN_RESULTS 1100struct BA_ONPLANPACKAGEBEGIN_RESULTS
@@ -1083,6 +1102,7 @@ struct BA_ONPLANPACKAGEBEGIN_RESULTS
1083 DWORD cbSize; 1102 DWORD cbSize;
1084 BOOL fCancel; 1103 BOOL fCancel;
1085 BOOTSTRAPPER_REQUEST_STATE requestedState; 1104 BOOTSTRAPPER_REQUEST_STATE requestedState;
1105 BOOTSTRAPPER_CACHE_TYPE requestedCacheType;
1086}; 1106};
1087 1107
1088struct BA_ONPLANPACKAGECOMPLETE_ARGS 1108struct BA_ONPLANPACKAGECOMPLETE_ARGS
diff --git a/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h b/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h
index f6804733..9c9b38a5 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
47 BOOTSTRAPPER_PACKAGE_STATE_UNKNOWN, 47 BOOTSTRAPPER_PACKAGE_STATE_UNKNOWN,
48 BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE, 48 BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE,
49 BOOTSTRAPPER_PACKAGE_STATE_ABSENT, 49 BOOTSTRAPPER_PACKAGE_STATE_ABSENT,
50 BOOTSTRAPPER_PACKAGE_STATE_CACHED,
51 BOOTSTRAPPER_PACKAGE_STATE_PRESENT, 50 BOOTSTRAPPER_PACKAGE_STATE_PRESENT,
52 BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED, 51 BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED,
53}; 52};
diff --git a/src/engine/core.cpp b/src/engine/core.cpp
index a915dad0..535043af 100644
--- a/src/engine/core.cpp
+++ b/src/engine/core.cpp
@@ -1640,12 +1640,6 @@ static HRESULT DetectPackage(
1640 ExitOnRootFailure(hr, "Package type not supported by detect yet."); 1640 ExitOnRootFailure(hr, "Package type not supported by detect yet.");
1641 } 1641 }
1642 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
1649LExit: 1643LExit:
1650 if (FAILED(hr)) 1644 if (FAILED(hr))
1651 { 1645 {
@@ -1654,7 +1648,7 @@ LExit:
1654 1648
1655 if (fBegan) 1649 if (fBegan)
1656 { 1650 {
1657 UserExperienceOnDetectPackageComplete(&pEngineState->userExperience, pPackage->sczId, hr, pPackage->currentState); 1651 UserExperienceOnDetectPackageComplete(&pEngineState->userExperience, pPackage->sczId, hr, pPackage->currentState, pPackage->fCached);
1658 } 1652 }
1659 1653
1660 return hr; 1654 return hr;
diff --git a/src/engine/dependency.cpp b/src/engine/dependency.cpp
index c4af207a..876cd8b3 100644
--- a/src/engine/dependency.cpp
+++ b/src/engine/dependency.cpp
@@ -1065,7 +1065,6 @@ static void CalculateDependencyActionStates(
1065 { 1065 {
1066 case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: __fallthrough; 1066 case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: __fallthrough;
1067 case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: __fallthrough; 1067 case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: __fallthrough;
1068 case BOOTSTRAPPER_PACKAGE_STATE_CACHED:
1069 *pDependencyRollbackAction = BURN_DEPENDENCY_ACTION_UNREGISTER; 1068 *pDependencyRollbackAction = BURN_DEPENDENCY_ACTION_UNREGISTER;
1070 break; 1069 break;
1071 } 1070 }
diff --git a/src/engine/exeengine.cpp b/src/engine/exeengine.cpp
index 8900984f..c0ba93e0 100644
--- a/src/engine/exeengine.cpp
+++ b/src/engine/exeengine.cpp
@@ -146,7 +146,7 @@ extern "C" HRESULT ExeEngineDetectPackage(
146 146
147 if (pPackage->fCanAffectRegistration) 147 if (pPackage->fCanAffectRegistration)
148 { 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 } 150 }
151 151
152LExit: 152LExit:
diff --git a/src/engine/externalengine.cpp b/src/engine/externalengine.cpp
index 51a0e229..409353e4 100644
--- a/src/engine/externalengine.cpp
+++ b/src/engine/externalengine.cpp
@@ -582,6 +582,11 @@ HRESULT ExternalEnginePlan(
582{ 582{
583 HRESULT hr = S_OK; 583 HRESULT hr = S_OK;
584 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
585 if (!::PostThreadMessageW(dwThreadId, WM_BURN_PLAN, 0, action)) 590 if (!::PostThreadMessageW(dwThreadId, WM_BURN_PLAN, 0, action))
586 { 591 {
587 ExitWithLastError(hr, "Failed to post plan message."); 592 ExitWithLastError(hr, "Failed to post plan message.");
@@ -622,7 +627,7 @@ HRESULT ExternalEngineApply(
622 ExitOnNull(hwndParent, hr, E_INVALIDARG, "BA passed NULL hwndParent to Apply."); 627 ExitOnNull(hwndParent, hr, E_INVALIDARG, "BA passed NULL hwndParent to Apply.");
623 if (!::IsWindow(hwndParent)) 628 if (!::IsWindow(hwndParent))
624 { 629 {
625 ExitOnFailure(hr = E_INVALIDARG, "BA passed invalid hwndParent to Apply."); 630 ExitOnRootFailure(hr = E_INVALIDARG, "BA passed invalid hwndParent to Apply.");
626 } 631 }
627 632
628 if (!::PostThreadMessageW(dwThreadId, WM_BURN_APPLY, 0, reinterpret_cast<LPARAM>(hwndParent))) 633 if (!::PostThreadMessageW(dwThreadId, WM_BURN_APPLY, 0, reinterpret_cast<LPARAM>(hwndParent)))
diff --git a/src/engine/logging.cpp b/src/engine/logging.cpp
index a1159c41..065ef907 100644
--- a/src/engine/logging.cpp
+++ b/src/engine/logging.cpp
@@ -390,8 +390,6 @@ extern "C" LPCSTR LoggingPackageStateToString(
390 return "Obsolete"; 390 return "Obsolete";
391 case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: 391 case BOOTSTRAPPER_PACKAGE_STATE_ABSENT:
392 return "Absent"; 392 return "Absent";
393 case BOOTSTRAPPER_PACKAGE_STATE_CACHED:
394 return "Cached";
395 case BOOTSTRAPPER_PACKAGE_STATE_PRESENT: 393 case BOOTSTRAPPER_PACKAGE_STATE_PRESENT:
396 return "Present"; 394 return "Present";
397 case BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED: 395 case BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED:
diff --git a/src/engine/msiengine.cpp b/src/engine/msiengine.cpp
index e3dc4671..3e96e5f9 100644
--- a/src/engine/msiengine.cpp
+++ b/src/engine/msiengine.cpp
@@ -700,7 +700,7 @@ extern "C" HRESULT MsiEngineDetectPackage(
700 700
701 if (pPackage->fCanAffectRegistration) 701 if (pPackage->fCanAffectRegistration)
702 { 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 } 704 }
705 705
706LExit: 706LExit:
@@ -768,7 +768,7 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
768 if (pPackage->Msi.cFeatures) 768 if (pPackage->Msi.cFeatures)
769 { 769 {
770 // If the package is present and we're repairing it. 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 772
773 // plan features 773 // plan features
774 for (DWORD i = 0; i < pPackage->Msi.cFeatures; ++i) 774 for (DWORD i = 0; i < pPackage->Msi.cFeatures; ++i)
@@ -829,21 +829,6 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
829 } 829 }
830 break; 830 break;
831 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
847 case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: __fallthrough; 832 case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: __fallthrough;
848 case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: 833 case BOOTSTRAPPER_PACKAGE_STATE_ABSENT:
849 switch (pPackage->requested) 834 switch (pPackage->requested)
@@ -892,7 +877,6 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
892 877
893 case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: __fallthrough; 878 case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: __fallthrough;
894 case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: __fallthrough; 879 case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: __fallthrough;
895 case BOOTSTRAPPER_PACKAGE_STATE_CACHED:
896 // If the package is uninstallable and we requested to put the package on the machine then 880 // If the package is uninstallable and we requested to put the package on the machine then
897 // remove the package during rollback. 881 // remove the package during rollback.
898 if (pPackage->fUninstallable && 882 if (pPackage->fUninstallable &&
diff --git a/src/engine/mspengine.cpp b/src/engine/mspengine.cpp
index d5673700..6d58d324 100644
--- a/src/engine/mspengine.cpp
+++ b/src/engine/mspengine.cpp
@@ -451,7 +451,6 @@ extern "C" HRESULT MspEnginePlanCalculatePackage(
451 break; 451 break;
452 452
453 case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: __fallthrough; 453 case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: __fallthrough;
454 case BOOTSTRAPPER_PACKAGE_STATE_CACHED:
455 switch (pTargetProduct->requested) 454 switch (pTargetProduct->requested)
456 { 455 {
457 case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; 456 case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough;
diff --git a/src/engine/msuengine.cpp b/src/engine/msuengine.cpp
index f807bf6b..6003123b 100644
--- a/src/engine/msuengine.cpp
+++ b/src/engine/msuengine.cpp
@@ -71,7 +71,7 @@ extern "C" HRESULT MsuEngineDetectPackage(
71 71
72 if (pPackage->fCanAffectRegistration) 72 if (pPackage->fCanAffectRegistration)
73 { 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 } 75 }
76 76
77LExit: 77LExit:
diff --git a/src/engine/package.cpp b/src/engine/package.cpp
index dd4e498a..3f8c8b0f 100644
--- a/src/engine/package.cpp
+++ b/src/engine/package.cpp
@@ -118,20 +118,20 @@ extern "C" HRESULT PackagesParseFromXml(
118 { 118 {
119 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"remove", -1)) 119 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"remove", -1))
120 { 120 {
121 pPackage->cacheType = BURN_CACHE_TYPE_NO; 121 pPackage->authoredCacheType = BOOTSTRAPPER_CACHE_TYPE_REMOVE;
122 } 122 }
123 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"keep", -1)) 123 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"keep", -1))
124 { 124 {
125 pPackage->cacheType = BURN_CACHE_TYPE_YES; 125 pPackage->authoredCacheType = BOOTSTRAPPER_CACHE_TYPE_KEEP;
126 } 126 }
127 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"force", -1)) 127 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, 0, scz, -1, L"force", -1))
128 { 128 {
129 pPackage->cacheType = BURN_CACHE_TYPE_ALWAYS; 129 pPackage->authoredCacheType = BOOTSTRAPPER_CACHE_TYPE_FORCE;
130 } 130 }
131 else 131 else
132 { 132 {
133 hr = E_UNEXPECTED; 133 hr = E_UNEXPECTED;
134 ExitOnFailure(hr, "Invalid cache type: %ls", scz); 134 ExitOnRootFailure(hr, "Invalid cache type: %ls", scz);
135 } 135 }
136 } 136 }
137 ExitOnFailure(hr, "Failed to get @Cache."); 137 ExitOnFailure(hr, "Failed to get @Cache.");
diff --git a/src/engine/package.h b/src/engine/package.h
index 2091af94..89a3d6e9 100644
--- a/src/engine/package.h
+++ b/src/engine/package.h
@@ -41,13 +41,6 @@ enum BURN_PACKAGE_TYPE
41 BURN_PACKAGE_TYPE_MSU, 41 BURN_PACKAGE_TYPE_MSU,
42}; 42};
43 43
44enum BURN_CACHE_TYPE
45{
46 BURN_CACHE_TYPE_NO,
47 BURN_CACHE_TYPE_YES,
48 BURN_CACHE_TYPE_ALWAYS,
49};
50
51enum BURN_DEPENDENCY_ACTION 44enum BURN_DEPENDENCY_ACTION
52{ 45{
53 BURN_DEPENDENCY_ACTION_NONE, 46 BURN_DEPENDENCY_ACTION_NONE,
@@ -223,7 +216,7 @@ typedef struct _BURN_PACKAGE
223 BOOL fVital; 216 BOOL fVital;
224 BOOL fCanAffectRegistration; 217 BOOL fCanAffectRegistration;
225 218
226 BURN_CACHE_TYPE cacheType; 219 BOOTSTRAPPER_CACHE_TYPE authoredCacheType;
227 LPWSTR sczCacheId; 220 LPWSTR sczCacheId;
228 221
229 DWORD64 qwInstallSize; 222 DWORD64 qwInstallSize;
@@ -235,6 +228,7 @@ typedef struct _BURN_PACKAGE
235 BOOTSTRAPPER_PACKAGE_STATE currentState; // only valid after Detect. 228 BOOTSTRAPPER_PACKAGE_STATE currentState; // only valid after Detect.
236 BOOL fCached; // only valid after Detect. 229 BOOL fCached; // only valid after Detect.
237 BOOL fPackageProviderExists; // only valid after Detect. 230 BOOL fPackageProviderExists; // only valid after Detect.
231 BOOTSTRAPPER_CACHE_TYPE cacheType; // only valid during Plan.
238 BOOTSTRAPPER_REQUEST_STATE defaultRequested;// only valid during Plan. 232 BOOTSTRAPPER_REQUEST_STATE defaultRequested;// only valid during Plan.
239 BOOTSTRAPPER_REQUEST_STATE requested; // only valid during Plan. 233 BOOTSTRAPPER_REQUEST_STATE requested; // only valid during Plan.
240 BOOL fPlannedCache; // only valid during Plan. 234 BOOL fPlannedCache; // only valid during Plan.
diff --git a/src/engine/plan.cpp b/src/engine/plan.cpp
index e5c1ee36..9a4aa5f1 100644
--- a/src/engine/plan.cpp
+++ b/src/engine/plan.cpp
@@ -137,6 +137,10 @@ static BOOL NeedsCache(
137 __in BURN_PACKAGE* pPackage, 137 __in BURN_PACKAGE* pPackage,
138 __in BOOL fExecute 138 __in BOOL fExecute
139 ); 139 );
140static BOOL ForceCache(
141 __in BURN_PLAN* pPlan,
142 __in BURN_PACKAGE* pPackage
143 );
140 144
141// function definitions 145// function definitions
142 146
@@ -312,28 +316,20 @@ extern "C" HRESULT PlanDefaultPackageRequestState(
312 __in BURN_PACKAGE_TYPE packageType, 316 __in BURN_PACKAGE_TYPE packageType,
313 __in BOOTSTRAPPER_PACKAGE_STATE currentState, 317 __in BOOTSTRAPPER_PACKAGE_STATE currentState,
314 __in BOOL fPermanent, 318 __in BOOL fPermanent,
315 __in BURN_CACHE_TYPE cacheType,
316 __in BOOTSTRAPPER_ACTION action, 319 __in BOOTSTRAPPER_ACTION action,
317 __in BOOL fInstallCondition, 320 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
318 __in BOOTSTRAPPER_RELATION_TYPE relationType, 321 __in BOOTSTRAPPER_RELATION_TYPE relationType,
319 __out BOOTSTRAPPER_REQUEST_STATE* pRequestState 322 __out BOOTSTRAPPER_REQUEST_STATE* pRequestState
320 ) 323 )
321{ 324{
322 HRESULT hr = S_OK; 325 HRESULT hr = S_OK;
323 BOOTSTRAPPER_REQUEST_STATE defaultRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; 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;
325 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.
327 if (BOOTSTRAPPER_ACTION_LAYOUT == action) 329 if (BOOTSTRAPPER_ACTION_LAYOUT == action)
328 { 330 {
329 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE; 331 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE;
330 } 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 }
337 else if (BOOTSTRAPPER_RELATION_PATCH == relationType && BURN_PACKAGE_TYPE_MSP == packageType) 333 else if (BOOTSTRAPPER_RELATION_PATCH == relationType && BURN_PACKAGE_TYPE_MSP == packageType)
338 { 334 {
339 // For patch related bundles, only install a patch if currently absent during install, modify, or repair. 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(
341 { 337 {
342 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; 338 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
343 } 339 }
344 else if (fFallbackToCache)
345 {
346 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE;
347 }
348 else 340 else
349 { 341 {
350 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; 342 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
351 } 343 }
352 } 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 }
353 else if (BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE == currentState && !(BOOTSTRAPPER_ACTION_UNINSTALL == action && BURN_PACKAGE_TYPE_MSP == packageType)) 351 else if (BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE == currentState && !(BOOTSTRAPPER_ACTION_UNINSTALL == action && BURN_PACKAGE_TYPE_MSP == packageType))
354 { 352 {
355 // Obsolete means the package is not on the machine and should not be installed, *except* patches can be obsolete 353 // Obsolete means the package is not on the machine and should not be installed, *except* patches can be obsolete
356 // and present so allow them to be removed during uninstall. Everyone else, gets nothing. 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;
358 } 356 }
359 else // pick the best option for the action state and install condition. 357 else // pick the best option for the action state and install condition.
360 { 358 {
@@ -363,7 +361,7 @@ extern "C" HRESULT PlanDefaultPackageRequestState(
363 361
364 // If we're doing an install, use the install condition 362 // If we're doing an install, use the install condition
365 // to determine whether to use the default request state or make the package absent. 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)
367 { 365 {
368 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT; 366 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT;
369 } 367 }
@@ -371,11 +369,6 @@ extern "C" HRESULT PlanDefaultPackageRequestState(
371 { 369 {
372 *pRequestState = defaultRequestState; 370 *pRequestState = defaultRequestState;
373 } 371 }
374
375 if (fFallbackToCache && BOOTSTRAPPER_REQUEST_STATE_CACHE > *pRequestState)
376 {
377 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE;
378 }
379 } 372 }
380 373
381LExit: 374LExit:
@@ -844,8 +837,8 @@ static HRESULT PlanPackagesHelper(
844 { 837 {
845 DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i; 838 DWORD iPackage = (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) ? cPackages - 1 - i : i;
846 BURN_PACKAGE* pPackage = rgPackages + iPackage; 839 BURN_PACKAGE* pPackage = rgPackages + iPackage;
847 840
848 UserExperienceOnPlannedPackage(pUX, pPackage->sczId, pPackage->execute, pPackage->rollback); 841 UserExperienceOnPlannedPackage(pUX, pPackage->sczId, pPackage->execute, pPackage->rollback, pPackage->fPlannedCache, pPackage->fPlannedUncache);
849 } 842 }
850 843
851LExit: 844LExit:
@@ -861,6 +854,7 @@ static HRESULT InitializePackage(
861 ) 854 )
862{ 855{
863 HRESULT hr = S_OK; 856 HRESULT hr = S_OK;
857 BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition = BOOTSTRAPPER_PACKAGE_CONDITION_DEFAULT;
864 BOOL fInstallCondition = FALSE; 858 BOOL fInstallCondition = FALSE;
865 BOOL fBeginCalled = FALSE; 859 BOOL fBeginCalled = FALSE;
866 860
@@ -874,20 +868,18 @@ static HRESULT InitializePackage(
874 { 868 {
875 hr = ConditionEvaluate(pVariables, pPackage->sczInstallCondition, &fInstallCondition); 869 hr = ConditionEvaluate(pVariables, pPackage->sczInstallCondition, &fInstallCondition);
876 ExitOnFailure(hr, "Failed to evaluate install condition."); 870 ExitOnFailure(hr, "Failed to evaluate install condition.");
877 } 871
878 else 872 installCondition = fInstallCondition ? BOOTSTRAPPER_PACKAGE_CONDITION_TRUE : BOOTSTRAPPER_PACKAGE_CONDITION_FALSE;
879 {
880 fInstallCondition = TRUE;
881 } 873 }
882 874
883 // Remember the default requested state so the engine doesn't get blamed for planning the wrong thing if the BA changes it. 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);
885 ExitOnFailure(hr, "Failed to set default package state."); 877 ExitOnFailure(hr, "Failed to set default package state.");
886 878
887 pPackage->requested = pPackage->defaultRequested; 879 pPackage->requested = pPackage->defaultRequested;
888 fBeginCalled = TRUE; 880 fBeginCalled = TRUE;
889 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);
891 ExitOnRootFailure(hr, "BA aborted plan package begin."); 883 ExitOnRootFailure(hr, "BA aborted plan package begin.");
892 884
893 if (BURN_PACKAGE_TYPE_MSI == pPackage->type) 885 if (BURN_PACKAGE_TYPE_MSI == pPackage->type)
@@ -926,8 +918,11 @@ static HRESULT ProcessPackage(
926 918
927 if (BOOTSTRAPPER_ACTION_LAYOUT == pPlan->action) 919 if (BOOTSTRAPPER_ACTION_LAYOUT == pPlan->action)
928 { 920 {
929 hr = PlanLayoutPackage(pPlan, pPackage); 921 if (BOOTSTRAPPER_REQUEST_STATE_NONE != pPackage->requested)
930 ExitOnFailure(hr, "Failed to plan layout package."); 922 {
923 hr = PlanLayoutPackage(pPlan, pPackage);
924 ExitOnFailure(hr, "Failed to plan layout package.");
925 }
931 } 926 }
932 else 927 else
933 { 928 {
@@ -939,6 +934,17 @@ static HRESULT ProcessPackage(
939 } 934 }
940 else 935 else
941 { 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
942 // Make sure the package is properly ref-counted even if no plan is requested. 948 // Make sure the package is properly ref-counted even if no plan is requested.
943 hr = PlanDependencyActions(fBundlePerMachine, pPlan, pPackage); 949 hr = PlanDependencyActions(fBundlePerMachine, pPlan, pPackage);
944 ExitOnFailure(hr, "Failed to plan dependency actions for package: %ls", pPackage->sczId); 950 ExitOnFailure(hr, "Failed to plan dependency actions for package: %ls", pPackage->sczId);
@@ -1072,8 +1078,7 @@ extern "C" HRESULT PlanExecutePackage(
1072 ) 1078 )
1073{ 1079{
1074 HRESULT hr = S_OK; 1080 HRESULT hr = S_OK;
1075 BOOL fRequestedCache = BOOTSTRAPPER_REQUEST_STATE_CACHE == pPackage->requested || 1081 BOOL fRequestedCache = BOOTSTRAPPER_REQUEST_STATE_CACHE == pPackage->requested || ForceCache(pPlan, pPackage);
1076 BOOTSTRAPPER_REQUEST_STATE_ABSENT < pPackage->requested && BURN_CACHE_TYPE_ALWAYS == pPackage->cacheType;
1077 1082
1078 hr = CalculateExecuteActions(pPackage, pPlan->pActiveRollbackBoundary); 1083 hr = CalculateExecuteActions(pPackage, pPlan->pActiveRollbackBoundary);
1079 ExitOnFailure(hr, "Failed to calculate plan actions for package: %ls", pPackage->sczId); 1084 ExitOnFailure(hr, "Failed to calculate plan actions for package: %ls", pPackage->sczId);
@@ -1097,12 +1102,12 @@ extern "C" HRESULT PlanExecutePackage(
1097 1102
1098 // Add the cache and install size to estimated size if it will be on the machine at the end of the install 1103 // Add the cache and install size to estimated size if it will be on the machine at the end of the install
1099 if (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested || 1104 if (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested ||
1100 BOOTSTRAPPER_REQUEST_STATE_CACHE == pPackage->requested || 1105 fRequestedCache ||
1101 (BOOTSTRAPPER_PACKAGE_STATE_PRESENT == pPackage->currentState && BOOTSTRAPPER_REQUEST_STATE_ABSENT < pPackage->requested) 1106 (BOOTSTRAPPER_PACKAGE_STATE_PRESENT == pPackage->currentState && BOOTSTRAPPER_REQUEST_STATE_ABSENT < pPackage->requested)
1102 ) 1107 )
1103 { 1108 {
1104 // If the package will remain in the cache, add the package size to the estimated size 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)
1106 { 1111 {
1107 pPlan->qwEstimatedSize += pPackage->qwSize; 1112 pPlan->qwEstimatedSize += pPackage->qwSize;
1108 } 1113 }
@@ -1522,12 +1527,12 @@ extern "C" HRESULT PlanCleanPackage(
1522 BURN_CLEAN_ACTION* pCleanAction = NULL; 1527 BURN_CLEAN_ACTION* pCleanAction = NULL;
1523 1528
1524 // The following is a complex set of logic that determines when a package should be cleaned from the cache. 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)
1526 { 1531 {
1527 // The following are all different reasons why the package should be cleaned from the cache. 1532 // The following are all different reasons why the package should be cleaned from the cache.
1528 // The else-ifs are used to make the conditions easier to see (rather than have them combined 1533 // The else-ifs are used to make the conditions easier to see (rather than have them combined
1529 // in one huge condition). 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.
1531 { 1536 {
1532 fPlanCleanPackage = TRUE; 1537 fPlanCleanPackage = TRUE;
1533 } 1538 }
@@ -1867,6 +1872,7 @@ static void ResetPlannedPackageState(
1867 ) 1872 )
1868{ 1873{
1869 // Reset package state that is a result of planning. 1874 // Reset package state that is a result of planning.
1875 pPackage->cacheType = pPackage->authoredCacheType;
1870 pPackage->defaultRequested = BOOTSTRAPPER_REQUEST_STATE_NONE; 1876 pPackage->defaultRequested = BOOTSTRAPPER_REQUEST_STATE_NONE;
1871 pPackage->requested = BOOTSTRAPPER_REQUEST_STATE_NONE; 1877 pPackage->requested = BOOTSTRAPPER_REQUEST_STATE_NONE;
1872 pPackage->fPlannedCache = FALSE; 1878 pPackage->fPlannedCache = FALSE;
@@ -1948,10 +1954,6 @@ static HRESULT GetActionDefaultRequestState(
1948 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; 1954 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
1949 break; 1955 break;
1950 1956
1951 case BOOTSTRAPPER_PACKAGE_STATE_CACHED:
1952 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
1953 break;
1954
1955 default: 1957 default:
1956 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE; 1958 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE;
1957 break; 1959 break;
@@ -1979,10 +1981,6 @@ static HRESULT GetActionDefaultRequestState(
1979 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT; 1981 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_ABSENT;
1980 break; 1982 break;
1981 1983
1982 case BOOTSTRAPPER_PACKAGE_STATE_CACHED:
1983 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_CACHE;
1984 break;
1985
1986 case BOOTSTRAPPER_PACKAGE_STATE_PRESENT: 1984 case BOOTSTRAPPER_PACKAGE_STATE_PRESENT:
1987 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; 1985 *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
1988 break; 1986 break;
@@ -2524,6 +2522,15 @@ static BOOL NeedsCache(
2524 } 2522 }
2525} 2523}
2526 2524
2525static 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
2527static void CacheActionLog( 2534static void CacheActionLog(
2528 __in DWORD iAction, 2535 __in DWORD iAction,
2529 __in BURN_CACHE_ACTION* pAction, 2536 __in BURN_CACHE_ACTION* pAction,
diff --git a/src/engine/plan.h b/src/engine/plan.h
index 4ba2df6a..00ab5516 100644
--- a/src/engine/plan.h
+++ b/src/engine/plan.h
@@ -309,9 +309,8 @@ HRESULT PlanDefaultPackageRequestState(
309 __in BURN_PACKAGE_TYPE packageType, 309 __in BURN_PACKAGE_TYPE packageType,
310 __in BOOTSTRAPPER_PACKAGE_STATE currentState, 310 __in BOOTSTRAPPER_PACKAGE_STATE currentState,
311 __in BOOL fPermanent, 311 __in BOOL fPermanent,
312 __in BURN_CACHE_TYPE cacheType,
313 __in BOOTSTRAPPER_ACTION action, 312 __in BOOTSTRAPPER_ACTION action,
314 __in BOOL fInstallCondition, 313 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
315 __in BOOTSTRAPPER_RELATION_TYPE relationType, 314 __in BOOTSTRAPPER_RELATION_TYPE relationType,
316 __out BOOTSTRAPPER_REQUEST_STATE* pRequestState 315 __out BOOTSTRAPPER_REQUEST_STATE* pRequestState
317 ); 316 );
diff --git a/src/engine/userexperience.cpp b/src/engine/userexperience.cpp
index ab631951..2215a070 100644
--- a/src/engine/userexperience.cpp
+++ b/src/engine/userexperience.cpp
@@ -1141,7 +1141,8 @@ EXTERN_C BAAPI UserExperienceOnDetectPackageComplete(
1141 __in BURN_USER_EXPERIENCE* pUserExperience, 1141 __in BURN_USER_EXPERIENCE* pUserExperience,
1142 __in_z LPCWSTR wzPackageId, 1142 __in_z LPCWSTR wzPackageId,
1143 __in HRESULT hrStatus, 1143 __in HRESULT hrStatus,
1144 __in BOOTSTRAPPER_PACKAGE_STATE state 1144 __in BOOTSTRAPPER_PACKAGE_STATE state,
1145 __in BOOL fCached
1145 ) 1146 )
1146{ 1147{
1147 HRESULT hr = S_OK; 1148 HRESULT hr = S_OK;
@@ -1152,6 +1153,7 @@ EXTERN_C BAAPI UserExperienceOnDetectPackageComplete(
1152 args.wzPackageId = wzPackageId; 1153 args.wzPackageId = wzPackageId;
1153 args.hrStatus = hrStatus; 1154 args.hrStatus = hrStatus;
1154 args.state = state; 1155 args.state = state;
1156 args.fCached = fCached;
1155 1157
1156 results.cbSize = sizeof(results); 1158 results.cbSize = sizeof(results);
1157 1159
@@ -1937,7 +1939,9 @@ EXTERN_C BAAPI UserExperienceOnPlannedPackage(
1937 __in BURN_USER_EXPERIENCE* pUserExperience, 1939 __in BURN_USER_EXPERIENCE* pUserExperience,
1938 __in_z LPCWSTR wzPackageId, 1940 __in_z LPCWSTR wzPackageId,
1939 __in BOOTSTRAPPER_ACTION_STATE execute, 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
1941 ) 1945 )
1942{ 1946{
1943 HRESULT hr = S_OK; 1947 HRESULT hr = S_OK;
@@ -1948,6 +1952,8 @@ EXTERN_C BAAPI UserExperienceOnPlannedPackage(
1948 args.wzPackageId = wzPackageId; 1952 args.wzPackageId = wzPackageId;
1949 args.execute = execute; 1953 args.execute = execute;
1950 args.rollback = rollback; 1954 args.rollback = rollback;
1955 args.fPlannedCache = fPlannedCache;
1956 args.fPlannedUncache = fPlannedUncache;
1951 1957
1952 results.cbSize = sizeof(results); 1958 results.cbSize = sizeof(results);
1953 1959
@@ -1962,8 +1968,10 @@ EXTERN_C BAAPI UserExperienceOnPlanPackageBegin(
1962 __in BURN_USER_EXPERIENCE* pUserExperience, 1968 __in BURN_USER_EXPERIENCE* pUserExperience,
1963 __in_z LPCWSTR wzPackageId, 1969 __in_z LPCWSTR wzPackageId,
1964 __in BOOTSTRAPPER_PACKAGE_STATE state, 1970 __in BOOTSTRAPPER_PACKAGE_STATE state,
1965 __in BOOL fInstallCondition, 1971 __in BOOL fCached,
1966 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState 1972 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
1973 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState,
1974 __inout BOOTSTRAPPER_CACHE_TYPE* pRequestedCacheType
1967 ) 1975 )
1968{ 1976{
1969 HRESULT hr = S_OK; 1977 HRESULT hr = S_OK;
@@ -1973,11 +1981,14 @@ EXTERN_C BAAPI UserExperienceOnPlanPackageBegin(
1973 args.cbSize = sizeof(args); 1981 args.cbSize = sizeof(args);
1974 args.wzPackageId = wzPackageId; 1982 args.wzPackageId = wzPackageId;
1975 args.state = state; 1983 args.state = state;
1976 args.fInstallCondition = fInstallCondition; 1984 args.fCached = fCached;
1985 args.installCondition = installCondition;
1977 args.recommendedState = *pRequestedState; 1986 args.recommendedState = *pRequestedState;
1987 args.recommendedCacheType = *pRequestedCacheType;
1978 1988
1979 results.cbSize = sizeof(results); 1989 results.cbSize = sizeof(results);
1980 results.requestedState = *pRequestedState; 1990 results.requestedState = *pRequestedState;
1991 results.requestedCacheType = *pRequestedCacheType;
1981 1992
1982 hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGEBEGIN, &args, &results); 1993 hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGEBEGIN, &args, &results);
1983 ExitOnFailure(hr, "BA OnPlanPackageBegin failed."); 1994 ExitOnFailure(hr, "BA OnPlanPackageBegin failed.");
@@ -1987,6 +1998,7 @@ EXTERN_C BAAPI UserExperienceOnPlanPackageBegin(
1987 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); 1998 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
1988 } 1999 }
1989 *pRequestedState = results.requestedState; 2000 *pRequestedState = results.requestedState;
2001 *pRequestedCacheType = results.requestedCacheType;
1990 2002
1991LExit: 2003LExit:
1992 return hr; 2004 return hr;
diff --git a/src/engine/userexperience.h b/src/engine/userexperience.h
index e1041624..f2453dca 100644
--- a/src/engine/userexperience.h
+++ b/src/engine/userexperience.h
@@ -279,7 +279,8 @@ BAAPI UserExperienceOnDetectPackageComplete(
279 __in BURN_USER_EXPERIENCE* pUserExperience, 279 __in BURN_USER_EXPERIENCE* pUserExperience,
280 __in_z LPCWSTR wzPackageId, 280 __in_z LPCWSTR wzPackageId,
281 __in HRESULT hrStatus, 281 __in HRESULT hrStatus,
282 __in BOOTSTRAPPER_PACKAGE_STATE state 282 __in BOOTSTRAPPER_PACKAGE_STATE state,
283 __in BOOL fCached
283 ); 284 );
284BAAPI UserExperienceOnDetectRelatedBundle( 285BAAPI UserExperienceOnDetectRelatedBundle(
285 __in BURN_USER_EXPERIENCE* pUserExperience, 286 __in BURN_USER_EXPERIENCE* pUserExperience,
@@ -448,14 +449,18 @@ BAAPI UserExperienceOnPlannedPackage(
448 __in BURN_USER_EXPERIENCE* pUserExperience, 449 __in BURN_USER_EXPERIENCE* pUserExperience,
449 __in_z LPCWSTR wzPackageId, 450 __in_z LPCWSTR wzPackageId,
450 __in BOOTSTRAPPER_ACTION_STATE execute, 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
452 ); 455 );
453BAAPI UserExperienceOnPlanPackageBegin( 456BAAPI UserExperienceOnPlanPackageBegin(
454 __in BURN_USER_EXPERIENCE* pUserExperience, 457 __in BURN_USER_EXPERIENCE* pUserExperience,
455 __in_z LPCWSTR wzPackageId, 458 __in_z LPCWSTR wzPackageId,
456 __in BOOTSTRAPPER_PACKAGE_STATE state, 459 __in BOOTSTRAPPER_PACKAGE_STATE state,
457 __in BOOL fInstallCondition, 460 __in BOOL fCached,
458 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState 461 __in BOOTSTRAPPER_PACKAGE_CONDITION_RESULT installCondition,
462 __inout BOOTSTRAPPER_REQUEST_STATE* pRequestedState,
463 __inout BOOTSTRAPPER_CACHE_TYPE* pRequestedCacheType
459 ); 464 );
460BAAPI UserExperienceOnPlanPackageComplete( 465BAAPI UserExperienceOnPlanPackageComplete(
461 __in BURN_USER_EXPERIENCE* pUserExperience, 466 __in BURN_USER_EXPERIENCE* pUserExperience,