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 | } |