diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2021-02-01 20:36:39 -0600 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2021-02-04 22:16:10 -0600 |
| commit | cc5fe7c79aad14819df1b4cb134884b80a945141 (patch) | |
| tree | 4b0ab44744a6b989f784292d438ef0654d9b03ac /src/engine/plan.cpp | |
| parent | cede270b2bd3da6bd8d5205b8834e786c8d6c1ce (diff) | |
| download | wix-cc5fe7c79aad14819df1b4cb134884b80a945141.tar.gz wix-cc5fe7c79aad14819df1b4cb134884b80a945141.tar.bz2 wix-cc5fe7c79aad14819df1b4cb134884b80a945141.zip | |
Move registry checks for dependency ref-counting into Detect.
Diffstat (limited to 'src/engine/plan.cpp')
| -rw-r--r-- | src/engine/plan.cpp | 104 |
1 files changed, 63 insertions, 41 deletions
diff --git a/src/engine/plan.cpp b/src/engine/plan.cpp index a45eab62..6f5407b9 100644 --- a/src/engine/plan.cpp +++ b/src/engine/plan.cpp | |||
| @@ -574,15 +574,12 @@ extern "C" HRESULT PlanRegistration( | |||
| 574 | __in BURN_REGISTRATION* pRegistration, | 574 | __in BURN_REGISTRATION* pRegistration, |
| 575 | __in BOOTSTRAPPER_RESUME_TYPE resumeType, | 575 | __in BOOTSTRAPPER_RESUME_TYPE resumeType, |
| 576 | __in BOOTSTRAPPER_RELATION_TYPE relationType, | 576 | __in BOOTSTRAPPER_RELATION_TYPE relationType, |
| 577 | __in_z_opt LPCWSTR wzIgnoreDependencies, | ||
| 578 | __out BOOL* pfContinuePlanning | 577 | __out BOOL* pfContinuePlanning |
| 579 | ) | 578 | ) |
| 580 | { | 579 | { |
| 581 | HRESULT hr = S_OK; | 580 | HRESULT hr = S_OK; |
| 582 | LPCWSTR wzSelfDependent = NULL; | 581 | STRINGDICT_HANDLE sdBundleDependents = NULL; |
| 583 | STRINGDICT_HANDLE sdIgnoreDependents = NULL; | 582 | STRINGDICT_HANDLE sdIgnoreDependents = NULL; |
| 584 | DEPENDENCY* rgDependencies = NULL; | ||
| 585 | UINT cDependencies = 0; | ||
| 586 | 583 | ||
| 587 | pPlan->fRegister = TRUE; // register the bundle since we're modifying machine state. | 584 | pPlan->fRegister = TRUE; // register the bundle since we're modifying machine state. |
| 588 | 585 | ||
| @@ -591,17 +588,6 @@ extern "C" HRESULT PlanRegistration( | |||
| 591 | 588 | ||
| 592 | pPlan->fDisallowRemoval = FALSE; // by default the bundle can be planned to be removed | 589 | pPlan->fDisallowRemoval = FALSE; // by default the bundle can be planned to be removed |
| 593 | 590 | ||
| 594 | // If no parent was specified at all, use the bundle id as the self dependent. | ||
| 595 | if (!pRegistration->sczActiveParent) | ||
| 596 | { | ||
| 597 | wzSelfDependent = pRegistration->sczId; | ||
| 598 | } | ||
| 599 | else if (*pRegistration->sczActiveParent) // if parent was specified use that as the self dependent. | ||
| 600 | { | ||
| 601 | wzSelfDependent = pRegistration->sczActiveParent; | ||
| 602 | } | ||
| 603 | // else parent:none was used which means we should not register a dependency on ourself. | ||
| 604 | |||
| 605 | if (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) | 591 | if (BOOTSTRAPPER_ACTION_UNINSTALL == pPlan->action) |
| 606 | { | 592 | { |
| 607 | // If our provider key was detected and it points to our current bundle then we can | 593 | // If our provider key was detected and it points to our current bundle then we can |
| @@ -622,12 +608,12 @@ extern "C" HRESULT PlanRegistration( | |||
| 622 | 608 | ||
| 623 | // If the self-dependent dependent exists, plan its removal. If we did not do this, we | 609 | // If the self-dependent dependent exists, plan its removal. If we did not do this, we |
| 624 | // would prevent self-removal. | 610 | // would prevent self-removal. |
| 625 | if (wzSelfDependent && DependencyDependentExists(pRegistration, wzSelfDependent)) | 611 | if (pRegistration->fSelfRegisteredAsDependent) |
| 626 | { | 612 | { |
| 627 | hr = AddRegistrationAction(pPlan, BURN_DEPENDENT_REGISTRATION_ACTION_TYPE_UNREGISTER, wzSelfDependent, pRegistration->sczId); | 613 | hr = AddRegistrationAction(pPlan, BURN_DEPENDENT_REGISTRATION_ACTION_TYPE_UNREGISTER, pRegistration->wzSelfDependent, pRegistration->sczId); |
| 628 | ExitOnFailure(hr, "Failed to allocate registration action."); | 614 | ExitOnFailure(hr, "Failed to allocate registration action."); |
| 629 | 615 | ||
| 630 | hr = DependencyAddIgnoreDependencies(sdIgnoreDependents, wzSelfDependent); | 616 | hr = DependencyAddIgnoreDependencies(sdIgnoreDependents, pRegistration->wzSelfDependent); |
| 631 | ExitOnFailure(hr, "Failed to add self-dependent to ignore dependents."); | 617 | ExitOnFailure(hr, "Failed to add self-dependent to ignore dependents."); |
| 632 | } | 618 | } |
| 633 | 619 | ||
| @@ -637,10 +623,20 @@ extern "C" HRESULT PlanRegistration( | |||
| 637 | if (BOOTSTRAPPER_RELATION_UPGRADE != relationType) | 623 | if (BOOTSTRAPPER_RELATION_UPGRADE != relationType) |
| 638 | { | 624 | { |
| 639 | // If there were other dependencies to ignore, add them. | 625 | // If there were other dependencies to ignore, add them. |
| 640 | if (wzIgnoreDependencies && *wzIgnoreDependencies) | 626 | for (DWORD iDependency = 0; iDependency < pRegistration->cIgnoredDependencies; ++iDependency) |
| 641 | { | 627 | { |
| 642 | hr = DependencyAddIgnoreDependencies(sdIgnoreDependents, wzIgnoreDependencies); | 628 | DEPENDENCY* pDependency = pRegistration->rgIgnoredDependencies + iDependency; |
| 643 | ExitOnFailure(hr, "Failed to add dependents ignored from command-line."); | 629 | |
| 630 | hr = DictKeyExists(sdIgnoreDependents, pDependency->sczKey); | ||
| 631 | if (E_NOTFOUND != hr) | ||
| 632 | { | ||
| 633 | ExitOnFailure(hr, "Failed to check the dictionary of ignored dependents."); | ||
| 634 | } | ||
| 635 | else | ||
| 636 | { | ||
| 637 | hr = DictAddKey(sdIgnoreDependents, pDependency->sczKey); | ||
| 638 | ExitOnFailure(hr, "Failed to add dependent key to ignored dependents."); | ||
| 639 | } | ||
| 644 | } | 640 | } |
| 645 | 641 | ||
| 646 | // For addon or patch bundles, dependent related bundles should be ignored. This allows | 642 | // For addon or patch bundles, dependent related bundles should be ignored. This allows |
| @@ -661,22 +657,29 @@ extern "C" HRESULT PlanRegistration( | |||
| 661 | } | 657 | } |
| 662 | } | 658 | } |
| 663 | 659 | ||
| 664 | // If there are any (non-ignored and not-planned-to-be-removed) dependents left, uninstall. | 660 | // If there are any (non-ignored and not-planned-to-be-removed) dependents left, skip planning. |
| 665 | hr = DepCheckDependents(pRegistration->hkRoot, pRegistration->sczProviderKey, 0, sdIgnoreDependents, &rgDependencies, &cDependencies); | 661 | for (DWORD iDependent = 0; iDependent < pRegistration->cDependents; ++iDependent) |
| 666 | if (E_FILENOTFOUND == hr) | ||
| 667 | { | 662 | { |
| 668 | hr = S_OK; | 663 | DEPENDENCY* pDependent = pRegistration->rgDependents + iDependent; |
| 669 | } | 664 | |
| 670 | else if (SUCCEEDED(hr) && cDependencies) | 665 | hr = DictKeyExists(sdIgnoreDependents, pDependent->sczKey); |
| 671 | { | 666 | if (E_NOTFOUND == hr) |
| 672 | // TODO: callback to the BA and let it have the option to ignore any of these dependents? | 667 | { |
| 668 | hr = S_OK; | ||
| 673 | 669 | ||
| 674 | pPlan->fDisallowRemoval = TRUE; // ensure the registration stays | 670 | // TODO: callback to the BA and let it have the option to ignore this dependent? |
| 675 | *pfContinuePlanning = FALSE; // skip the rest of planning. | 671 | if (!pPlan->fDisallowRemoval) |
| 672 | { | ||
| 673 | pPlan->fDisallowRemoval = TRUE; // ensure the registration stays | ||
| 674 | *pfContinuePlanning = FALSE; // skip the rest of planning. | ||
| 675 | |||
| 676 | LogId(REPORT_STANDARD, MSG_PLAN_SKIPPED_DUE_TO_DEPENDENTS); | ||
| 677 | } | ||
| 676 | 678 | ||
| 677 | LogId(REPORT_STANDARD, MSG_PLAN_SKIPPED_DUE_TO_DEPENDENTS, cDependencies); | 679 | LogId(REPORT_VERBOSE, MSG_DEPENDENCY_BUNDLE_DEPENDENT, pDependent->sczKey, LoggingStringOrUnknownIfNull(pDependent->sczName)); |
| 680 | } | ||
| 681 | ExitOnFailure(hr, "Failed to check for remaining dependents during planning."); | ||
| 678 | } | 682 | } |
| 679 | ExitOnFailure(hr, "Failed to check for remaining dependents during planning."); | ||
| 680 | } | 683 | } |
| 681 | } | 684 | } |
| 682 | else | 685 | else |
| @@ -707,6 +710,23 @@ extern "C" HRESULT PlanRegistration( | |||
| 707 | // if broken. | 710 | // if broken. |
| 708 | pPlan->dependencyRegistrationAction = BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER; | 711 | pPlan->dependencyRegistrationAction = BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER; |
| 709 | 712 | ||
| 713 | // Create the dictionary of bundle dependents. | ||
| 714 | hr = DictCreateStringList(&sdBundleDependents, 5, DICT_FLAG_CASEINSENSITIVE); | ||
| 715 | ExitOnFailure(hr, "Failed to create the string dictionary."); | ||
| 716 | |||
| 717 | for (DWORD iDependent = 0; iDependent < pRegistration->cDependents; ++iDependent) | ||
| 718 | { | ||
| 719 | DEPENDENCY* pDependent = pRegistration->rgDependents + iDependent; | ||
| 720 | |||
| 721 | hr = DictKeyExists(sdBundleDependents, pDependent->sczKey); | ||
| 722 | if (E_NOTFOUND == hr) | ||
| 723 | { | ||
| 724 | hr = DictAddKey(sdBundleDependents, pDependent->sczKey); | ||
| 725 | ExitOnFailure(hr, "Failed to add dependent key to bundle dependents."); | ||
| 726 | } | ||
| 727 | ExitOnFailure(hr, "Failed to check the dictionary of bundle dependents."); | ||
| 728 | } | ||
| 729 | |||
| 710 | // Register each dependent related bundle. The ensures that addons and patches are reference | 730 | // Register each dependent related bundle. The ensures that addons and patches are reference |
| 711 | // counted and stick around until the last targeted bundle is removed. | 731 | // counted and stick around until the last targeted bundle is removed. |
| 712 | for (DWORD i = 0; i < pRegistration->relatedBundles.cRelatedBundles; ++i) | 732 | for (DWORD i = 0; i < pRegistration->relatedBundles.cRelatedBundles; ++i) |
| @@ -719,11 +739,16 @@ extern "C" HRESULT PlanRegistration( | |||
| 719 | { | 739 | { |
| 720 | const BURN_DEPENDENCY_PROVIDER* pProvider = pRelatedBundle->package.rgDependencyProviders + j; | 740 | const BURN_DEPENDENCY_PROVIDER* pProvider = pRelatedBundle->package.rgDependencyProviders + j; |
| 721 | 741 | ||
| 722 | if (!DependencyDependentExists(pRegistration, pProvider->sczKey)) | 742 | hr = DictKeyExists(sdBundleDependents, pProvider->sczKey); |
| 743 | if (E_NOTFOUND == hr) | ||
| 723 | { | 744 | { |
| 745 | hr = DictAddKey(sdBundleDependents, pProvider->sczKey); | ||
| 746 | ExitOnFailure(hr, "Failed to add new dependent key to bundle dependents."); | ||
| 747 | |||
| 724 | hr = AddRegistrationAction(pPlan, BURN_DEPENDENT_REGISTRATION_ACTION_TYPE_REGISTER, pProvider->sczKey, pRelatedBundle->package.sczId); | 748 | hr = AddRegistrationAction(pPlan, BURN_DEPENDENT_REGISTRATION_ACTION_TYPE_REGISTER, pProvider->sczKey, pRelatedBundle->package.sczId); |
| 725 | ExitOnFailure(hr, "Failed to add registration action for dependent related bundle."); | 749 | ExitOnFailure(hr, "Failed to add registration action for dependent related bundle."); |
| 726 | } | 750 | } |
| 751 | ExitOnFailure(hr, "Failed to check the dictionary of bundle dependents."); | ||
| 727 | } | 752 | } |
| 728 | } | 753 | } |
| 729 | } | 754 | } |
| @@ -731,19 +756,16 @@ extern "C" HRESULT PlanRegistration( | |||
| 731 | // Only do the following if we decided there was a dependent self to register. If so and and an explicit parent was | 756 | // Only do the following if we decided there was a dependent self to register. If so and and an explicit parent was |
| 732 | // provided, register dependent self. Otherwise, if this bundle is not an addon or patch bundle then self-regisiter | 757 | // provided, register dependent self. Otherwise, if this bundle is not an addon or patch bundle then self-regisiter |
| 733 | // as our own dependent. | 758 | // as our own dependent. |
| 734 | if (wzSelfDependent && (pRegistration->sczActiveParent || !fAddonOrPatchBundle)) | 759 | if (pRegistration->wzSelfDependent && !pRegistration->fSelfRegisteredAsDependent && (pRegistration->sczActiveParent || !fAddonOrPatchBundle)) |
| 735 | { | 760 | { |
| 736 | if (!DependencyDependentExists(pRegistration, wzSelfDependent)) | 761 | hr = AddRegistrationAction(pPlan, BURN_DEPENDENT_REGISTRATION_ACTION_TYPE_REGISTER, pRegistration->wzSelfDependent, pRegistration->sczId); |
| 737 | { | 762 | ExitOnFailure(hr, "Failed to add registration action for self dependent."); |
| 738 | hr = AddRegistrationAction(pPlan, BURN_DEPENDENT_REGISTRATION_ACTION_TYPE_REGISTER, wzSelfDependent, pRegistration->sczId); | ||
| 739 | ExitOnFailure(hr, "Failed to add registration action for self dependent."); | ||
| 740 | } | ||
| 741 | } | 763 | } |
| 742 | } | 764 | } |
| 743 | 765 | ||
| 744 | LExit: | 766 | LExit: |
| 767 | ReleaseDict(sdBundleDependents); | ||
| 745 | ReleaseDict(sdIgnoreDependents); | 768 | ReleaseDict(sdIgnoreDependents); |
| 746 | ReleaseDependencyArray(rgDependencies, cDependencies); | ||
| 747 | 769 | ||
| 748 | return hr; | 770 | return hr; |
| 749 | } | 771 | } |
