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 /src/engine | |
| parent | 778b65643f19df94947d390a5a17023043d840b4 (diff) | |
| download | wix-10ef9d5bfbf81f454113a1c2716009831a916222.tar.gz wix-10ef9d5bfbf81f454113a1c2716009831a916222.tar.bz2 wix-10ef9d5bfbf81f454113a1c2716009831a916222.zip | |
Determine whether to ignore forward compatible bundles during Plan.
Diffstat (limited to 'src/engine')
| -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 |
11 files changed, 181 insertions, 109 deletions
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, |
