aboutsummaryrefslogtreecommitdiff
path: root/src/engine/plan.cpp
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-02-01 20:36:39 -0600
committerSean Hall <r.sean.hall@gmail.com>2021-02-04 22:16:10 -0600
commitcc5fe7c79aad14819df1b4cb134884b80a945141 (patch)
tree4b0ab44744a6b989f784292d438ef0654d9b03ac /src/engine/plan.cpp
parentcede270b2bd3da6bd8d5205b8834e786c8d6c1ce (diff)
downloadwix-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.cpp104
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
744LExit: 766LExit:
767 ReleaseDict(sdBundleDependents);
745 ReleaseDict(sdIgnoreDependents); 768 ReleaseDict(sdIgnoreDependents);
746 ReleaseDependencyArray(rgDependencies, cDependencies);
747 769
748 return hr; 770 return hr;
749} 771}