diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2021-03-10 15:47:59 -0600 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2021-03-11 20:24:18 -0600 |
commit | 10ef9d5bfbf81f454113a1c2716009831a916222 (patch) | |
tree | 9e2fd8c917787ceba5e4c7f873d715eafbda6920 | |
parent | 778b65643f19df94947d390a5a17023043d840b4 (diff) | |
download | wix-10ef9d5bfbf81f454113a1c2716009831a916222.tar.gz wix-10ef9d5bfbf81f454113a1c2716009831a916222.tar.bz2 wix-10ef9d5bfbf81f454113a1c2716009831a916222.zip |
Determine whether to ignore forward compatible bundles during Plan.
-rw-r--r-- | src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h | 20 | ||||
-rw-r--r-- | src/engine/core.cpp | 65 | ||||
-rw-r--r-- | src/engine/dependency.cpp | 23 | ||||
-rw-r--r-- | src/engine/dependency.h | 10 | ||||
-rw-r--r-- | src/engine/detect.cpp | 48 | ||||
-rw-r--r-- | src/engine/detect.h | 3 | ||||
-rw-r--r-- | src/engine/engine.mc | 2 | ||||
-rw-r--r-- | src/engine/plan.cpp | 68 | ||||
-rw-r--r-- | src/engine/plan.h | 10 | ||||
-rw-r--r-- | src/engine/registration.h | 6 | ||||
-rw-r--r-- | src/engine/userexperience.cpp | 43 | ||||
-rw-r--r-- | src/engine/userexperience.h | 12 |
12 files changed, 200 insertions, 110 deletions
diff --git a/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h b/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h index 6cf3477c..c3242167 100644 --- a/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h +++ b/src/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h | |||
@@ -143,6 +143,7 @@ enum BOOTSTRAPPER_APPLICATION_MESSAGE | |||
143 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMRESTOREPOINTBEGIN, | 143 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMRESTOREPOINTBEGIN, |
144 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMRESTOREPOINTCOMPLETE, | 144 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMRESTOREPOINTCOMPLETE, |
145 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDPACKAGE, | 145 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANNEDPACKAGE, |
146 | BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANFORWARDCOMPATIBLEBUNDLE, | ||
146 | }; | 147 | }; |
147 | 148 | ||
148 | enum BOOTSTRAPPER_APPLYCOMPLETE_ACTION | 149 | enum BOOTSTRAPPER_APPLYCOMPLETE_ACTION |
@@ -496,7 +497,6 @@ struct BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_RESULTS | |||
496 | { | 497 | { |
497 | DWORD cbSize; | 498 | DWORD cbSize; |
498 | BOOL fCancel; | 499 | BOOL fCancel; |
499 | BOOL fIgnoreBundle; | ||
500 | }; | 500 | }; |
501 | 501 | ||
502 | struct BA_ONDETECTMSIFEATURE_ARGS | 502 | struct BA_ONDETECTMSIFEATURE_ARGS |
@@ -854,6 +854,24 @@ struct BA_ONPLANCOMPLETE_RESULTS | |||
854 | DWORD cbSize; | 854 | DWORD cbSize; |
855 | }; | 855 | }; |
856 | 856 | ||
857 | struct BA_ONPLANFORWARDCOMPATIBLEBUNDLE_ARGS | ||
858 | { | ||
859 | DWORD cbSize; | ||
860 | LPCWSTR wzBundleId; | ||
861 | BOOTSTRAPPER_RELATION_TYPE relationType; | ||
862 | LPCWSTR wzBundleTag; | ||
863 | BOOL fPerMachine; | ||
864 | LPCWSTR wzVersion; | ||
865 | BOOL fRecommendedIgnoreBundle; | ||
866 | }; | ||
867 | |||
868 | struct BA_ONPLANFORWARDCOMPATIBLEBUNDLE_RESULTS | ||
869 | { | ||
870 | DWORD cbSize; | ||
871 | BOOL fCancel; | ||
872 | BOOL fIgnoreBundle; | ||
873 | }; | ||
874 | |||
857 | struct BA_ONPLANMSIFEATURE_ARGS | 875 | struct BA_ONPLANMSIFEATURE_ARGS |
858 | { | 876 | { |
859 | DWORD cbSize; | 877 | DWORD cbSize; |
diff --git a/src/engine/core.cpp b/src/engine/core.cpp index 2f18e4d2..eb8a84fe 100644 --- a/src/engine/core.cpp +++ b/src/engine/core.cpp | |||
@@ -319,15 +319,8 @@ extern "C" HRESULT CoreDetect( | |||
319 | hr = DependencyDetectProviderKeyBundleId(&pEngineState->registration); | 319 | hr = DependencyDetectProviderKeyBundleId(&pEngineState->registration); |
320 | if (SUCCEEDED(hr)) | 320 | if (SUCCEEDED(hr)) |
321 | { | 321 | { |
322 | hr = DetectForwardCompatibleBundle(&pEngineState->userExperience, &pEngineState->command, &pEngineState->registration); | 322 | hr = DetectForwardCompatibleBundles(&pEngineState->userExperience, &pEngineState->registration); |
323 | ExitOnFailure(hr, "Failed to detect forward compatible bundle."); | 323 | ExitOnFailure(hr, "Failed to detect forward compatible bundle."); |
324 | |||
325 | // If a forward compatible bundle was detected, skip rest of bundle detection | ||
326 | // since we will passthrough. | ||
327 | if (pEngineState->registration.fEnabledForwardCompatibleBundle) | ||
328 | { | ||
329 | ExitFunction(); | ||
330 | } | ||
331 | } | 324 | } |
332 | else if (E_NOTFOUND == hr) | 325 | else if (E_NOTFOUND == hr) |
333 | { | 326 | { |
@@ -504,39 +497,45 @@ extern "C" HRESULT CorePlan( | |||
504 | hr = PlanUpdateBundle(&pEngineState->userExperience, pUpgradeBundlePackage, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType, &hSyncpointEvent); | 497 | hr = PlanUpdateBundle(&pEngineState->userExperience, pUpgradeBundlePackage, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType, &hSyncpointEvent); |
505 | ExitOnFailure(hr, "Failed to plan update."); | 498 | ExitOnFailure(hr, "Failed to plan update."); |
506 | } | 499 | } |
507 | else if (pEngineState->registration.fEnabledForwardCompatibleBundle) | 500 | else |
508 | { | 501 | { |
509 | Assert(!pEngineState->plan.fPerMachine); | 502 | hr = PlanForwardCompatibleBundles(&pEngineState->userExperience, &pEngineState->command, &pEngineState->plan, &pEngineState->registration, action); |
503 | ExitOnFailure(hr, "Failed to plan forward compatible bundles."); | ||
510 | 504 | ||
511 | pForwardCompatibleBundlePackage = &pEngineState->registration.forwardCompatibleBundle; | 505 | if (pEngineState->plan.fEnabledForwardCompatibleBundle) |
512 | 506 | { | |
513 | hr = PlanPassThroughBundle(&pEngineState->userExperience, pForwardCompatibleBundlePackage, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType, &hSyncpointEvent); | 507 | Assert(!pEngineState->plan.fPerMachine); |
514 | ExitOnFailure(hr, "Failed to plan passthrough."); | ||
515 | } | ||
516 | else // doing an action that modifies the machine state. | ||
517 | { | ||
518 | pEngineState->plan.fPerMachine = pEngineState->registration.fPerMachine; // default the scope of the plan to the per-machine state of the bundle. | ||
519 | 508 | ||
520 | hr = PlanRegistration(&pEngineState->plan, &pEngineState->registration, pEngineState->command.resumeType, pEngineState->command.relationType, &fContinuePlanning); | 509 | pForwardCompatibleBundlePackage = &pEngineState->plan.forwardCompatibleBundle; |
521 | ExitOnFailure(hr, "Failed to plan registration."); | ||
522 | 510 | ||
523 | if (fContinuePlanning) | 511 | hr = PlanPassThroughBundle(&pEngineState->userExperience, pForwardCompatibleBundlePackage, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType, &hSyncpointEvent); |
512 | ExitOnFailure(hr, "Failed to plan passthrough."); | ||
513 | } | ||
514 | else // doing an action that modifies the machine state. | ||
524 | { | 515 | { |
525 | // Remember the early index, because we want to be able to insert some related bundles | 516 | pEngineState->plan.fPerMachine = pEngineState->registration.fPerMachine; // default the scope of the plan to the per-machine state of the bundle. |
526 | // into the plan before other executed packages. This particularly occurs for uninstallation | ||
527 | // of addons and patches, which should be uninstalled before the main product. | ||
528 | DWORD dwExecuteActionEarlyIndex = pEngineState->plan.cExecuteActions; | ||
529 | 517 | ||
530 | // Plan the related bundles first to support downgrades with ref-counting. | 518 | hr = PlanRegistration(&pEngineState->plan, &pEngineState->registration, pEngineState->command.resumeType, pEngineState->command.relationType, &fContinuePlanning); |
531 | hr = PlanRelatedBundlesBegin(&pEngineState->userExperience, &pEngineState->registration, pEngineState->command.relationType, &pEngineState->plan); | 519 | ExitOnFailure(hr, "Failed to plan registration."); |
532 | ExitOnFailure(hr, "Failed to plan related bundles."); | ||
533 | 520 | ||
534 | hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType, NULL, &hSyncpointEvent); | 521 | if (fContinuePlanning) |
535 | ExitOnFailure(hr, "Failed to plan packages."); | 522 | { |
523 | // Remember the early index, because we want to be able to insert some related bundles | ||
524 | // into the plan before other executed packages. This particularly occurs for uninstallation | ||
525 | // of addons and patches, which should be uninstalled before the main product. | ||
526 | DWORD dwExecuteActionEarlyIndex = pEngineState->plan.cExecuteActions; | ||
536 | 527 | ||
537 | // Schedule the update of related bundles last. | 528 | // Plan the related bundles first to support downgrades with ref-counting. |
538 | hr = PlanRelatedBundlesComplete(&pEngineState->registration, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, &hSyncpointEvent, dwExecuteActionEarlyIndex); | 529 | hr = PlanRelatedBundlesBegin(&pEngineState->userExperience, &pEngineState->registration, pEngineState->command.relationType, &pEngineState->plan); |
539 | ExitOnFailure(hr, "Failed to schedule related bundles."); | 530 | ExitOnFailure(hr, "Failed to plan related bundles."); |
531 | |||
532 | hr = PlanPackages(&pEngineState->userExperience, &pEngineState->packages, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, pEngineState->command.display, pEngineState->command.relationType, NULL, &hSyncpointEvent); | ||
533 | ExitOnFailure(hr, "Failed to plan packages."); | ||
534 | |||
535 | // Schedule the update of related bundles last. | ||
536 | hr = PlanRelatedBundlesComplete(&pEngineState->registration, &pEngineState->plan, &pEngineState->log, &pEngineState->variables, &hSyncpointEvent, dwExecuteActionEarlyIndex); | ||
537 | ExitOnFailure(hr, "Failed to schedule related bundles."); | ||
538 | } | ||
540 | } | 539 | } |
541 | } | 540 | } |
542 | 541 | ||
diff --git a/src/engine/dependency.cpp b/src/engine/dependency.cpp index 4833de94..9ab76551 100644 --- a/src/engine/dependency.cpp +++ b/src/engine/dependency.cpp | |||
@@ -234,6 +234,8 @@ extern "C" HRESULT DependencyDetect( | |||
234 | BURN_REGISTRATION* pRegistration = &pEngineState->registration; | 234 | BURN_REGISTRATION* pRegistration = &pEngineState->registration; |
235 | STRINGDICT_HANDLE sdIgnoredDependents = NULL; | 235 | STRINGDICT_HANDLE sdIgnoredDependents = NULL; |
236 | BURN_PACKAGE* pPackage = NULL; | 236 | BURN_PACKAGE* pPackage = NULL; |
237 | BOOL fSelfDependent = NULL != pRegistration->wzSelfDependent; | ||
238 | BOOL fActiveParent = NULL != pRegistration->sczActiveParent && NULL != *pRegistration->sczActiveParent; | ||
237 | 239 | ||
238 | // Always leave this empty so that all dependents get detected. Plan will ignore dependents based on its own logic. | 240 | // Always leave this empty so that all dependents get detected. Plan will ignore dependents based on its own logic. |
239 | hr = DictCreateStringList(&sdIgnoredDependents, INITIAL_STRINGDICT_SIZE, DICT_FLAG_CASEINSENSITIVE); | 241 | hr = DictCreateStringList(&sdIgnoredDependents, INITIAL_STRINGDICT_SIZE, DICT_FLAG_CASEINSENSITIVE); |
@@ -263,16 +265,20 @@ extern "C" HRESULT DependencyDetect( | |||
263 | ExitOnFailure(hr, "Failed to detect dependents for related bundle '%ls'", pPackage->sczId); | 265 | ExitOnFailure(hr, "Failed to detect dependents for related bundle '%ls'", pPackage->sczId); |
264 | } | 266 | } |
265 | 267 | ||
266 | if (pRegistration->wzSelfDependent) | 268 | if (fSelfDependent || fActiveParent) |
267 | { | 269 | { |
268 | for (DWORD i = 0; i < pRegistration->cDependents; ++i) | 270 | for (DWORD i = 0; i < pRegistration->cDependents; ++i) |
269 | { | 271 | { |
270 | DEPENDENCY* pDependent = pRegistration->rgDependents + i; | 272 | DEPENDENCY* pDependent = pRegistration->rgDependents + i; |
271 | 273 | ||
272 | if (CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->wzSelfDependent, -1, pDependent->sczKey, -1)) | 274 | if (fActiveParent && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->sczActiveParent, -1, pDependent->sczKey, -1)) |
275 | { | ||
276 | pRegistration->fParentRegisteredAsDependent = TRUE; | ||
277 | } | ||
278 | |||
279 | if (fSelfDependent && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->wzSelfDependent, -1, pDependent->sczKey, -1)) | ||
273 | { | 280 | { |
274 | pRegistration->fSelfRegisteredAsDependent = TRUE; | 281 | pRegistration->fSelfRegisteredAsDependent = TRUE; |
275 | break; | ||
276 | } | 282 | } |
277 | } | 283 | } |
278 | } | 284 | } |
@@ -348,17 +354,6 @@ LExit: | |||
348 | return hr; | 354 | return hr; |
349 | } | 355 | } |
350 | 356 | ||
351 | extern "C" BOOL DependencyDependentExists( | ||
352 | __in const BURN_REGISTRATION* pRegistration, | ||
353 | __in_z LPCWSTR wzDependentProviderKey | ||
354 | ) | ||
355 | { | ||
356 | HRESULT hr = S_OK; | ||
357 | |||
358 | hr = DepDependentExists(pRegistration->hkRoot, pRegistration->sczProviderKey, wzDependentProviderKey); | ||
359 | return SUCCEEDED(hr); | ||
360 | } | ||
361 | |||
362 | extern "C" HRESULT DependencyPlanPackageBegin( | 357 | extern "C" HRESULT DependencyPlanPackageBegin( |
363 | __in BOOL fPerMachine, | 358 | __in BOOL fPerMachine, |
364 | __in BURN_PACKAGE* pPackage, | 359 | __in BURN_PACKAGE* pPackage, |
diff --git a/src/engine/dependency.h b/src/engine/dependency.h index efb9f2f2..06a01a20 100644 --- a/src/engine/dependency.h +++ b/src/engine/dependency.h | |||
@@ -85,16 +85,6 @@ HRESULT DependencyAddIgnoreDependencies( | |||
85 | ); | 85 | ); |
86 | 86 | ||
87 | /******************************************************************** | 87 | /******************************************************************** |
88 | DependencyDependentExists - Checks to see if the provider key is | ||
89 | already dependent on this bundle. | ||
90 | |||
91 | *********************************************************************/ | ||
92 | BOOL DependencyDependentExists( | ||
93 | __in const BURN_REGISTRATION* pRegistration, | ||
94 | __in_z LPCWSTR wzDependentProviderKey | ||
95 | ); | ||
96 | |||
97 | /******************************************************************** | ||
98 | DependencyPlanPackageBegin - Updates the dependency registration | 88 | DependencyPlanPackageBegin - Updates the dependency registration |
99 | action depending on the calculated state for the package. | 89 | action depending on the calculated state for the package. |
100 | 90 | ||
diff --git a/src/engine/detect.cpp b/src/engine/detect.cpp index 4265cf9b..74e8b9ca 100644 --- a/src/engine/detect.cpp +++ b/src/engine/detect.cpp | |||
@@ -39,9 +39,9 @@ extern "C" void DetectReset( | |||
39 | { | 39 | { |
40 | RelatedBundlesUninitialize(&pRegistration->relatedBundles); | 40 | RelatedBundlesUninitialize(&pRegistration->relatedBundles); |
41 | ReleaseNullStr(pRegistration->sczDetectedProviderKeyBundleId); | 41 | ReleaseNullStr(pRegistration->sczDetectedProviderKeyBundleId); |
42 | pRegistration->fEnabledForwardCompatibleBundle = FALSE; | ||
43 | PackageUninitialize(&pRegistration->forwardCompatibleBundle); | ||
44 | pRegistration->fSelfRegisteredAsDependent = FALSE; | 42 | pRegistration->fSelfRegisteredAsDependent = FALSE; |
43 | pRegistration->fParentRegisteredAsDependent = FALSE; | ||
44 | pRegistration->fForwardCompatibleBundleExists = FALSE; | ||
45 | pRegistration->fEligibleForCleanup = FALSE; | 45 | pRegistration->fEligibleForCleanup = FALSE; |
46 | 46 | ||
47 | if (pRegistration->rgIgnoredDependencies) | 47 | if (pRegistration->rgIgnoredDependencies) |
@@ -120,46 +120,20 @@ extern "C" void DetectReset( | |||
120 | } | 120 | } |
121 | } | 121 | } |
122 | 122 | ||
123 | extern "C" HRESULT DetectForwardCompatibleBundle( | 123 | extern "C" HRESULT DetectForwardCompatibleBundles( |
124 | __in BURN_USER_EXPERIENCE* pUX, | 124 | __in BURN_USER_EXPERIENCE* pUX, |
125 | __in BOOTSTRAPPER_COMMAND* pCommand, | ||
126 | __in BURN_REGISTRATION* pRegistration | 125 | __in BURN_REGISTRATION* pRegistration |
127 | ) | 126 | ) |
128 | { | 127 | { |
129 | HRESULT hr = S_OK; | 128 | HRESULT hr = S_OK; |
130 | BOOL fRecommendIgnore = TRUE; | ||
131 | BOOL fIgnoreBundle = FALSE; | ||
132 | int nCompareResult = 0; | 129 | int nCompareResult = 0; |
133 | 130 | ||
134 | if (pRegistration->sczDetectedProviderKeyBundleId && | 131 | if (pRegistration->sczDetectedProviderKeyBundleId && |
135 | CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->sczDetectedProviderKeyBundleId, -1, pRegistration->sczId, -1)) | 132 | CSTR_EQUAL != ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->sczDetectedProviderKeyBundleId, -1, pRegistration->sczId, -1)) |
136 | { | 133 | { |
137 | // Only change the recommendation if an active parent was provided. | ||
138 | if (pRegistration->sczActiveParent && *pRegistration->sczActiveParent) | ||
139 | { | ||
140 | // On install, recommend running the forward compatible bundle because there is an active parent. This | ||
141 | // will essentially register the parent with the forward compatible bundle. | ||
142 | if (BOOTSTRAPPER_ACTION_INSTALL == pCommand->action) | ||
143 | { | ||
144 | fRecommendIgnore = FALSE; | ||
145 | } | ||
146 | else if (BOOTSTRAPPER_ACTION_UNINSTALL == pCommand->action || | ||
147 | BOOTSTRAPPER_ACTION_MODIFY == pCommand->action || | ||
148 | BOOTSTRAPPER_ACTION_REPAIR == pCommand->action) | ||
149 | { | ||
150 | // When modifying the bundle, only recommend running the forward compatible bundle if the parent | ||
151 | // is already registered as a dependent of the provider key. | ||
152 | if (DependencyDependentExists(pRegistration, pRegistration->sczActiveParent)) | ||
153 | { | ||
154 | fRecommendIgnore = FALSE; | ||
155 | } | ||
156 | } | ||
157 | } | ||
158 | |||
159 | for (DWORD iRelatedBundle = 0; iRelatedBundle < pRegistration->relatedBundles.cRelatedBundles; ++iRelatedBundle) | 134 | for (DWORD iRelatedBundle = 0; iRelatedBundle < pRegistration->relatedBundles.cRelatedBundles; ++iRelatedBundle) |
160 | { | 135 | { |
161 | BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgRelatedBundles + iRelatedBundle; | 136 | BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgRelatedBundles + iRelatedBundle; |
162 | fIgnoreBundle = fRecommendIgnore; | ||
163 | 137 | ||
164 | if (BOOTSTRAPPER_RELATION_UPGRADE == pRelatedBundle->relationType && | 138 | if (BOOTSTRAPPER_RELATION_UPGRADE == pRelatedBundle->relationType && |
165 | CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->sczDetectedProviderKeyBundleId, -1, pRelatedBundle->package.sczId, -1)) | 139 | CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, NORM_IGNORECASE, pRegistration->sczDetectedProviderKeyBundleId, -1, pRelatedBundle->package.sczId, -1)) |
@@ -169,19 +143,13 @@ extern "C" HRESULT DetectForwardCompatibleBundle( | |||
169 | 143 | ||
170 | if (nCompareResult <= 0) | 144 | if (nCompareResult <= 0) |
171 | { | 145 | { |
172 | hr = UserExperienceOnDetectForwardCompatibleBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->relationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->pVersion, &fIgnoreBundle); | 146 | pRelatedBundle->fForwardCompatible = TRUE; |
173 | ExitOnRootFailure(hr, "BA aborted detect forward compatible bundle."); | 147 | pRegistration->fForwardCompatibleBundleExists = TRUE; |
174 | |||
175 | if (!fIgnoreBundle) | ||
176 | { | ||
177 | hr = PseudoBundleInitializePassthrough(&pRegistration->forwardCompatibleBundle, pCommand, NULL, pRegistration->sczActiveParent, pRegistration->sczAncestors, &pRelatedBundle->package); | ||
178 | ExitOnFailure(hr, "Failed to initialize update bundle."); | ||
179 | 148 | ||
180 | pRegistration->fEnabledForwardCompatibleBundle = TRUE; | 149 | hr = UserExperienceOnDetectForwardCompatibleBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->relationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->pVersion); |
181 | } | 150 | ExitOnRootFailure(hr, "BA aborted detect forward compatible bundle."); |
182 | 151 | ||
183 | LogId(REPORT_STANDARD, MSG_DETECTED_FORWARD_COMPATIBLE_BUNDLE, pRelatedBundle->package.sczId, LoggingRelationTypeToString(pRelatedBundle->relationType), LoggingPerMachineToString(pRelatedBundle->package.fPerMachine), pRelatedBundle->pVersion->sczVersion, LoggingBoolToString(pRegistration->fEnabledForwardCompatibleBundle)); | 152 | LogId(REPORT_STANDARD, MSG_DETECTED_FORWARD_COMPATIBLE_BUNDLE, pRelatedBundle->package.sczId, LoggingRelationTypeToString(pRelatedBundle->relationType), LoggingPerMachineToString(pRelatedBundle->package.fPerMachine), pRelatedBundle->pVersion->sczVersion); |
184 | break; | ||
185 | } | 153 | } |
186 | } | 154 | } |
187 | } | 155 | } |
diff --git a/src/engine/detect.h b/src/engine/detect.h index 7989c9dd..9bc34882 100644 --- a/src/engine/detect.h +++ b/src/engine/detect.h | |||
@@ -20,9 +20,8 @@ void DetectReset( | |||
20 | __in BURN_PACKAGES* pPackages | 20 | __in BURN_PACKAGES* pPackages |
21 | ); | 21 | ); |
22 | 22 | ||
23 | HRESULT DetectForwardCompatibleBundle( | 23 | HRESULT DetectForwardCompatibleBundles( |
24 | __in BURN_USER_EXPERIENCE* pUX, | 24 | __in BURN_USER_EXPERIENCE* pUX, |
25 | __in BOOTSTRAPPER_COMMAND* pCommand, | ||
26 | __in BURN_REGISTRATION* pRegistration | 25 | __in BURN_REGISTRATION* pRegistration |
27 | ); | 26 | ); |
28 | 27 | ||
diff --git a/src/engine/engine.mc b/src/engine/engine.mc index f7b18c59..687d2b60 100644 --- a/src/engine/engine.mc +++ b/src/engine/engine.mc | |||
@@ -237,7 +237,7 @@ MessageId=107 | |||
237 | Severity=Success | 237 | Severity=Success |
238 | SymbolicName=MSG_DETECTED_FORWARD_COMPATIBLE_BUNDLE | 238 | SymbolicName=MSG_DETECTED_FORWARD_COMPATIBLE_BUNDLE |
239 | Language=English | 239 | Language=English |
240 | Detected forward compatible bundle: %1!ls!, type: %2!hs!, scope: %3!hs!, version: %4!ls!, enabled: %5!hs! | 240 | Detected forward compatible bundle: %1!ls!, type: %2!hs!, scope: %3!hs!, version: %4!ls! |
241 | . | 241 | . |
242 | 242 | ||
243 | MessageId=120 | 243 | MessageId=120 |
diff --git a/src/engine/plan.cpp b/src/engine/plan.cpp index 4f29209f..87607382 100644 --- a/src/engine/plan.cpp +++ b/src/engine/plan.cpp | |||
@@ -194,6 +194,8 @@ extern "C" void PlanReset( | |||
194 | __in BURN_PACKAGES* pPackages | 194 | __in BURN_PACKAGES* pPackages |
195 | ) | 195 | ) |
196 | { | 196 | { |
197 | PackageUninitialize(&pPlan->forwardCompatibleBundle); | ||
198 | |||
197 | if (pPlan->rgRegistrationActions) | 199 | if (pPlan->rgRegistrationActions) |
198 | { | 200 | { |
199 | for (DWORD i = 0; i < pPlan->cRegistrationActions; ++i) | 201 | for (DWORD i = 0; i < pPlan->cRegistrationActions; ++i) |
@@ -488,6 +490,72 @@ LExit: | |||
488 | return hr; | 490 | return hr; |
489 | } | 491 | } |
490 | 492 | ||
493 | extern "C" HRESULT PlanForwardCompatibleBundles( | ||
494 | __in BURN_USER_EXPERIENCE* pUX, | ||
495 | __in BOOTSTRAPPER_COMMAND* pCommand, | ||
496 | __in BURN_PLAN* pPlan, | ||
497 | __in BURN_REGISTRATION* pRegistration, | ||
498 | __in BOOTSTRAPPER_ACTION action | ||
499 | ) | ||
500 | { | ||
501 | HRESULT hr = S_OK; | ||
502 | BOOL fRecommendIgnore = TRUE; | ||
503 | BOOL fIgnoreBundle = FALSE; | ||
504 | |||
505 | if (!pRegistration->fForwardCompatibleBundleExists) | ||
506 | { | ||
507 | ExitFunction(); | ||
508 | } | ||
509 | |||
510 | // Only change the recommendation if an active parent was provided. | ||
511 | if (pRegistration->sczActiveParent && *pRegistration->sczActiveParent) | ||
512 | { | ||
513 | // On install, recommend running the forward compatible bundle because there is an active parent. This | ||
514 | // will essentially register the parent with the forward compatible bundle. | ||
515 | if (BOOTSTRAPPER_ACTION_INSTALL == action) | ||
516 | { | ||
517 | fRecommendIgnore = FALSE; | ||
518 | } | ||
519 | else if (BOOTSTRAPPER_ACTION_UNINSTALL == action || | ||
520 | BOOTSTRAPPER_ACTION_MODIFY == action || | ||
521 | BOOTSTRAPPER_ACTION_REPAIR == action) | ||
522 | { | ||
523 | // When modifying the bundle, only recommend running the forward compatible bundle if the parent | ||
524 | // is already registered as a dependent of the provider key. | ||
525 | if (pRegistration->fParentRegisteredAsDependent) | ||
526 | { | ||
527 | fRecommendIgnore = FALSE; | ||
528 | } | ||
529 | } | ||
530 | } | ||
531 | |||
532 | for (DWORD iRelatedBundle = 0; iRelatedBundle < pRegistration->relatedBundles.cRelatedBundles; ++iRelatedBundle) | ||
533 | { | ||
534 | BURN_RELATED_BUNDLE* pRelatedBundle = pRegistration->relatedBundles.rgRelatedBundles + iRelatedBundle; | ||
535 | if (!pRelatedBundle->fForwardCompatible) | ||
536 | { | ||
537 | continue; | ||
538 | } | ||
539 | |||
540 | fIgnoreBundle = fRecommendIgnore; | ||
541 | |||
542 | hr = UserExperienceOnPlanForwardCompatibleBundle(pUX, pRelatedBundle->package.sczId, pRelatedBundle->relationType, pRelatedBundle->sczTag, pRelatedBundle->package.fPerMachine, pRelatedBundle->pVersion, &fIgnoreBundle); | ||
543 | ExitOnRootFailure(hr, "BA aborted plan forward compatible bundle."); | ||
544 | |||
545 | if (!fIgnoreBundle) | ||
546 | { | ||
547 | hr = PseudoBundleInitializePassthrough(&pPlan->forwardCompatibleBundle, pCommand, NULL, pRegistration->sczActiveParent, pRegistration->sczAncestors, &pRelatedBundle->package); | ||
548 | ExitOnFailure(hr, "Failed to initialize pass through bundle."); | ||
549 | |||
550 | pPlan->fEnabledForwardCompatibleBundle = TRUE; | ||
551 | break; | ||
552 | } | ||
553 | } | ||
554 | |||
555 | LExit: | ||
556 | return hr; | ||
557 | } | ||
558 | |||
491 | extern "C" HRESULT PlanPackages( | 559 | extern "C" HRESULT PlanPackages( |
492 | __in BURN_USER_EXPERIENCE* pUX, | 560 | __in BURN_USER_EXPERIENCE* pUX, |
493 | __in BURN_PACKAGES* pPackages, | 561 | __in BURN_PACKAGES* pPackages, |
diff --git a/src/engine/plan.h b/src/engine/plan.h index c679d368..e72186c7 100644 --- a/src/engine/plan.h +++ b/src/engine/plan.h | |||
@@ -322,6 +322,9 @@ typedef struct _BURN_PLAN | |||
322 | DWORD cExecutePackagesTotal; | 322 | DWORD cExecutePackagesTotal; |
323 | DWORD cOverallProgressTicksTotal; | 323 | DWORD cOverallProgressTicksTotal; |
324 | 324 | ||
325 | BOOL fEnabledForwardCompatibleBundle; | ||
326 | BURN_PACKAGE forwardCompatibleBundle; | ||
327 | |||
325 | BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction; | 328 | BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction; |
326 | 329 | ||
327 | BURN_DEPENDENT_REGISTRATION_ACTION* rgRegistrationActions; | 330 | BURN_DEPENDENT_REGISTRATION_ACTION* rgRegistrationActions; |
@@ -392,6 +395,13 @@ HRESULT PlanLayoutBundle( | |||
392 | __in BURN_PAYLOADS* pPayloads, | 395 | __in BURN_PAYLOADS* pPayloads, |
393 | __out_z LPWSTR* psczLayoutDirectory | 396 | __out_z LPWSTR* psczLayoutDirectory |
394 | ); | 397 | ); |
398 | HRESULT PlanForwardCompatibleBundles( | ||
399 | __in BURN_USER_EXPERIENCE* pUX, | ||
400 | __in BOOTSTRAPPER_COMMAND* pCommand, | ||
401 | __in BURN_PLAN* pPlan, | ||
402 | __in BURN_REGISTRATION* pRegistration, | ||
403 | __in BOOTSTRAPPER_ACTION action | ||
404 | ); | ||
395 | HRESULT PlanPackages( | 405 | HRESULT PlanPackages( |
396 | __in BURN_USER_EXPERIENCE* pUX, | 406 | __in BURN_USER_EXPERIENCE* pUX, |
397 | __in BURN_PACKAGES* pPackages, | 407 | __in BURN_PACKAGES* pPackages, |
diff --git a/src/engine/registration.h b/src/engine/registration.h index 4aca5a05..bb87b6e9 100644 --- a/src/engine/registration.h +++ b/src/engine/registration.h | |||
@@ -58,6 +58,7 @@ typedef struct _BURN_UPDATE_REGISTRATION | |||
58 | typedef struct _BURN_RELATED_BUNDLE | 58 | typedef struct _BURN_RELATED_BUNDLE |
59 | { | 59 | { |
60 | BOOTSTRAPPER_RELATION_TYPE relationType; | 60 | BOOTSTRAPPER_RELATION_TYPE relationType; |
61 | BOOL fForwardCompatible; | ||
61 | 62 | ||
62 | VERUTIL_VERSION* pVersion; | 63 | VERUTIL_VERSION* pVersion; |
63 | LPWSTR sczTag; | 64 | LPWSTR sczTag; |
@@ -146,14 +147,13 @@ typedef struct _BURN_REGISTRATION | |||
146 | UINT cDependents; // Only valid after detect. | 147 | UINT cDependents; // Only valid after detect. |
147 | LPCWSTR wzSelfDependent; // Only valid after detect. | 148 | LPCWSTR wzSelfDependent; // Only valid after detect. |
148 | BOOL fSelfRegisteredAsDependent; // Only valid after detect. | 149 | BOOL fSelfRegisteredAsDependent; // Only valid after detect. |
150 | BOOL fParentRegisteredAsDependent; // Only valid after detect. | ||
151 | BOOL fForwardCompatibleBundleExists; // Only valid after detect. | ||
149 | BOOL fEligibleForCleanup; // Only valid after detect. | 152 | BOOL fEligibleForCleanup; // Only valid after detect. |
150 | 153 | ||
151 | LPWSTR sczDetectedProviderKeyBundleId; | 154 | LPWSTR sczDetectedProviderKeyBundleId; |
152 | LPWSTR sczAncestors; | 155 | LPWSTR sczAncestors; |
153 | LPWSTR sczBundlePackageAncestors; | 156 | LPWSTR sczBundlePackageAncestors; |
154 | |||
155 | BOOL fEnabledForwardCompatibleBundle; | ||
156 | BURN_PACKAGE forwardCompatibleBundle; | ||
157 | } BURN_REGISTRATION; | 157 | } BURN_REGISTRATION; |
158 | 158 | ||
159 | 159 | ||
diff --git a/src/engine/userexperience.cpp b/src/engine/userexperience.cpp index 40a30c5d..e1e32a87 100644 --- a/src/engine/userexperience.cpp +++ b/src/engine/userexperience.cpp | |||
@@ -763,8 +763,7 @@ EXTERN_C BAAPI UserExperienceOnDetectForwardCompatibleBundle( | |||
763 | __in BOOTSTRAPPER_RELATION_TYPE relationType, | 763 | __in BOOTSTRAPPER_RELATION_TYPE relationType, |
764 | __in_z LPCWSTR wzBundleTag, | 764 | __in_z LPCWSTR wzBundleTag, |
765 | __in BOOL fPerMachine, | 765 | __in BOOL fPerMachine, |
766 | __in VERUTIL_VERSION* pVersion, | 766 | __in VERUTIL_VERSION* pVersion |
767 | __inout BOOL* pfIgnoreBundle | ||
768 | ) | 767 | ) |
769 | { | 768 | { |
770 | HRESULT hr = S_OK; | 769 | HRESULT hr = S_OK; |
@@ -779,7 +778,6 @@ EXTERN_C BAAPI UserExperienceOnDetectForwardCompatibleBundle( | |||
779 | args.wzVersion = pVersion->sczVersion; | 778 | args.wzVersion = pVersion->sczVersion; |
780 | 779 | ||
781 | results.cbSize = sizeof(results); | 780 | results.cbSize = sizeof(results); |
782 | results.fIgnoreBundle = *pfIgnoreBundle; | ||
783 | 781 | ||
784 | hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE, &args, &results); | 782 | hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE, &args, &results); |
785 | ExitOnFailure(hr, "BA OnDetectForwardCompatibleBundle failed."); | 783 | ExitOnFailure(hr, "BA OnDetectForwardCompatibleBundle failed."); |
@@ -788,7 +786,6 @@ EXTERN_C BAAPI UserExperienceOnDetectForwardCompatibleBundle( | |||
788 | { | 786 | { |
789 | hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); | 787 | hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); |
790 | } | 788 | } |
791 | *pfIgnoreBundle = results.fIgnoreBundle; | ||
792 | 789 | ||
793 | LExit: | 790 | LExit: |
794 | return hr; | 791 | return hr; |
@@ -1567,6 +1564,44 @@ LExit: | |||
1567 | return hr; | 1564 | return hr; |
1568 | } | 1565 | } |
1569 | 1566 | ||
1567 | EXTERN_C BAAPI UserExperienceOnPlanForwardCompatibleBundle( | ||
1568 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
1569 | __in_z LPCWSTR wzBundleId, | ||
1570 | __in BOOTSTRAPPER_RELATION_TYPE relationType, | ||
1571 | __in_z LPCWSTR wzBundleTag, | ||
1572 | __in BOOL fPerMachine, | ||
1573 | __in VERUTIL_VERSION* pVersion, | ||
1574 | __inout BOOL* pfIgnoreBundle | ||
1575 | ) | ||
1576 | { | ||
1577 | HRESULT hr = S_OK; | ||
1578 | BA_ONPLANFORWARDCOMPATIBLEBUNDLE_ARGS args = { }; | ||
1579 | BA_ONPLANFORWARDCOMPATIBLEBUNDLE_RESULTS results = { }; | ||
1580 | |||
1581 | args.cbSize = sizeof(args); | ||
1582 | args.wzBundleId = wzBundleId; | ||
1583 | args.relationType = relationType; | ||
1584 | args.wzBundleTag = wzBundleTag; | ||
1585 | args.fPerMachine = fPerMachine; | ||
1586 | args.wzVersion = pVersion->sczVersion; | ||
1587 | args.fRecommendedIgnoreBundle = *pfIgnoreBundle; | ||
1588 | |||
1589 | results.cbSize = sizeof(results); | ||
1590 | results.fIgnoreBundle = *pfIgnoreBundle; | ||
1591 | |||
1592 | hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANFORWARDCOMPATIBLEBUNDLE, &args, &results); | ||
1593 | ExitOnFailure(hr, "BA OnPlanForwardCompatibleBundle failed."); | ||
1594 | |||
1595 | if (results.fCancel) | ||
1596 | { | ||
1597 | hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT); | ||
1598 | } | ||
1599 | *pfIgnoreBundle = results.fIgnoreBundle; | ||
1600 | |||
1601 | LExit: | ||
1602 | return hr; | ||
1603 | } | ||
1604 | |||
1570 | EXTERN_C BAAPI UserExperienceOnPlanMsiPackage( | 1605 | EXTERN_C BAAPI UserExperienceOnPlanMsiPackage( |
1571 | __in BURN_USER_EXPERIENCE* pUserExperience, | 1606 | __in BURN_USER_EXPERIENCE* pUserExperience, |
1572 | __in_z LPCWSTR wzPackageId, | 1607 | __in_z LPCWSTR wzPackageId, |
diff --git a/src/engine/userexperience.h b/src/engine/userexperience.h index 754a9030..eccc0786 100644 --- a/src/engine/userexperience.h +++ b/src/engine/userexperience.h | |||
@@ -200,8 +200,7 @@ BAAPI UserExperienceOnDetectForwardCompatibleBundle( | |||
200 | __in BOOTSTRAPPER_RELATION_TYPE relationType, | 200 | __in BOOTSTRAPPER_RELATION_TYPE relationType, |
201 | __in_z LPCWSTR wzBundleTag, | 201 | __in_z LPCWSTR wzBundleTag, |
202 | __in BOOL fPerMachine, | 202 | __in BOOL fPerMachine, |
203 | __in VERUTIL_VERSION* pVersion, | 203 | __in VERUTIL_VERSION* pVersion |
204 | __inout BOOL* pfIgnoreBundle | ||
205 | ); | 204 | ); |
206 | BAAPI UserExperienceOnDetectMsiFeature( | 205 | BAAPI UserExperienceOnDetectMsiFeature( |
207 | __in BURN_USER_EXPERIENCE* pUserExperience, | 206 | __in BURN_USER_EXPERIENCE* pUserExperience, |
@@ -357,6 +356,15 @@ BAAPI UserExperienceOnPlanComplete( | |||
357 | __in BURN_USER_EXPERIENCE* pUserExperience, | 356 | __in BURN_USER_EXPERIENCE* pUserExperience, |
358 | __in HRESULT hrStatus | 357 | __in HRESULT hrStatus |
359 | ); | 358 | ); |
359 | BAAPI UserExperienceOnPlanForwardCompatibleBundle( | ||
360 | __in BURN_USER_EXPERIENCE* pUserExperience, | ||
361 | __in_z LPCWSTR wzBundleId, | ||
362 | __in BOOTSTRAPPER_RELATION_TYPE relationType, | ||
363 | __in_z LPCWSTR wzBundleTag, | ||
364 | __in BOOL fPerMachine, | ||
365 | __in VERUTIL_VERSION* pVersion, | ||
366 | __inout BOOL* pfIgnoreBundle | ||
367 | ); | ||
360 | BAAPI UserExperienceOnPlanMsiFeature( | 368 | BAAPI UserExperienceOnPlanMsiFeature( |
361 | __in BURN_USER_EXPERIENCE* pUserExperience, | 369 | __in BURN_USER_EXPERIENCE* pUserExperience, |
362 | __in_z LPCWSTR wzPackageId, | 370 | __in_z LPCWSTR wzPackageId, |