aboutsummaryrefslogtreecommitdiff
path: root/src/engine/mspengine.cpp
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-02-02 18:09:58 -0600
committerSean Hall <r.sean.hall@gmail.com>2021-02-04 22:16:10 -0600
commitfd8c2b0899bfbce07386af245c04eb21dc01cbdf (patch)
tree33d928124b0028729916189ddb9f239a9574c75d /src/engine/mspengine.cpp
parent39725a1a6d1c72a6748bd3c306af32bcae6dbf8f (diff)
downloadwix-fd8c2b0899bfbce07386af245c04eb21dc01cbdf.tar.gz
wix-fd8c2b0899bfbce07386af245c04eb21dc01cbdf.tar.bz2
wix-fd8c2b0899bfbce07386af245c04eb21dc01cbdf.zip
Update the logic for determining when the bundle should be registered.
The basic rule is that if a non-permanent package is present at the end of the chain, then the bundle should be registered. If no non-permanent packages are present at the end of the chain, then the bundle should not be registered. This required tracking what actually happened with each package during Apply. Include cache status in registration calculation. Include dependency ref-counting when determining whether the bundle should be registered.
Diffstat (limited to 'src/engine/mspengine.cpp')
-rw-r--r--src/engine/mspengine.cpp109
1 files changed, 107 insertions, 2 deletions
diff --git a/src/engine/mspengine.cpp b/src/engine/mspengine.cpp
index c432b78b..c0329d79 100644
--- a/src/engine/mspengine.cpp
+++ b/src/engine/mspengine.cpp
@@ -200,20 +200,26 @@ extern "C" HRESULT MspEngineDetectPackage(
200 HRESULT hr = S_OK; 200 HRESULT hr = S_OK;
201 LPWSTR sczState = NULL; 201 LPWSTR sczState = NULL;
202 202
203 if (pPackage->fCanAffectRegistration)
204 {
205 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
206 }
207
203 if (0 == pPackage->Msp.cTargetProductCodes) 208 if (0 == pPackage->Msp.cTargetProductCodes)
204 { 209 {
205 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT; 210 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT;
206 } 211 }
207 else 212 else
208 { 213 {
209 // Start the package state at the the highest state then loop through all the 214 // Start the package state at the highest state then loop through all the
210 // target product codes and end up setting the current state to the lowest 215 // target product codes and end up setting the current state to the lowest
211 // package state applied to the the target product codes. 216 // package state applied to the target product codes.
212 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED; 217 pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED;
213 218
214 for (DWORD i = 0; i < pPackage->Msp.cTargetProductCodes; ++i) 219 for (DWORD i = 0; i < pPackage->Msp.cTargetProductCodes; ++i)
215 { 220 {
216 BURN_MSPTARGETPRODUCT* pTargetProduct = pPackage->Msp.rgTargetProducts + i; 221 BURN_MSPTARGETPRODUCT* pTargetProduct = pPackage->Msp.rgTargetProducts + i;
222 BOOL fInstalled = FALSE;
217 223
218 hr = WiuGetPatchInfoEx(pPackage->Msp.sczPatchCode, pTargetProduct->wzTargetProductCode, NULL, pTargetProduct->context, INSTALLPROPERTY_PATCHSTATE, &sczState); 224 hr = WiuGetPatchInfoEx(pPackage->Msp.sczPatchCode, pTargetProduct->wzTargetProductCode, NULL, pTargetProduct->context, INSTALLPROPERTY_PATCHSTATE, &sczState);
219 if (SUCCEEDED(hr)) 225 if (SUCCEEDED(hr))
@@ -221,14 +227,17 @@ extern "C" HRESULT MspEngineDetectPackage(
221 switch (*sczState) 227 switch (*sczState)
222 { 228 {
223 case '1': 229 case '1':
230 fInstalled = TRUE;
224 pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_PRESENT; 231 pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_PRESENT;
225 break; 232 break;
226 233
227 case '2': 234 case '2':
235 fInstalled = TRUE;
228 pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED; 236 pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED;
229 break; 237 break;
230 238
231 case '4': 239 case '4':
240 fInstalled = TRUE;
232 pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE; 241 pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE;
233 break; 242 break;
234 243
@@ -249,6 +258,16 @@ extern "C" HRESULT MspEngineDetectPackage(
249 pPackage->currentState = pTargetProduct->patchPackageState; 258 pPackage->currentState = pTargetProduct->patchPackageState;
250 } 259 }
251 260
261 if (pPackage->fCanAffectRegistration)
262 {
263 pTargetProduct->registrationState = fInstalled ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
264
265 if (fInstalled)
266 {
267 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
268 }
269 }
270
252 hr = UserExperienceOnDetectTargetMsiPackage(pUserExperience, pPackage->sczId, pTargetProduct->wzTargetProductCode, pTargetProduct->patchPackageState); 271 hr = UserExperienceOnDetectTargetMsiPackage(pUserExperience, pPackage->sczId, pTargetProduct->wzTargetProductCode, pTargetProduct->patchPackageState);
253 ExitOnRootFailure(hr, "BA aborted detect target MSI package."); 272 ExitOnRootFailure(hr, "BA aborted detect target MSI package.");
254 } 273 }
@@ -642,6 +661,92 @@ extern "C" void MspEngineSlipstreamUpdateState(
642 } 661 }
643} 662}
644 663
664extern "C" void MspEngineUpdateInstallRegistrationState(
665 __in BURN_EXECUTE_ACTION* pAction,
666 __in HRESULT hrExecute,
667 __in BOOL fInsideMsiTransaction
668 )
669{
670 BURN_PACKAGE_REGISTRATION_STATE newState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
671
672 if (FAILED(hrExecute))
673 {
674 ExitFunction();
675 }
676
677 if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pAction->mspTarget.action)
678 {
679 newState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
680 }
681 else
682 {
683 newState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
684 }
685
686 for (DWORD i = 0; i < pAction->mspTarget.cOrderedPatches; ++i)
687 {
688 BURN_ORDERED_PATCHES* pOrderedPatches = pAction->mspTarget.rgOrderedPatches + i;
689 BURN_PACKAGE* pPackage = pOrderedPatches->pPackage;
690 BURN_MSPTARGETPRODUCT* pTargetProduct = NULL;
691
692 Assert(BURN_PACKAGE_TYPE_MSP == pPackage->type);
693
694 if (!pPackage->fCanAffectRegistration)
695 {
696 continue;
697 }
698
699 for (DWORD j = 0; j < pPackage->Msp.cTargetProductCodes; ++j)
700 {
701 pTargetProduct = pPackage->Msp.rgTargetProducts + j;
702 if (pAction->mspTarget.fPerMachineTarget == (MSIINSTALLCONTEXT_MACHINE == pTargetProduct->context) &&
703 CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, pAction->mspTarget.sczTargetProductCode, -1, pTargetProduct->wzTargetProductCode, -1))
704 {
705 break;
706 }
707
708 pTargetProduct = NULL;
709 }
710
711 if (!pTargetProduct)
712 {
713 AssertSz(pTargetProduct, "Ordered patch didn't have corresponding target product");
714 continue;
715 }
716
717 if (fInsideMsiTransaction)
718 {
719 pTargetProduct->transactionRegistrationState = newState;
720 }
721 else
722 {
723 pTargetProduct->registrationState = newState;
724 }
725 }
726
727LExit:
728 return;
729}
730
731extern "C" void MspEngineFinalizeInstallRegistrationState(
732 __in BURN_PACKAGE* pPackage
733 )
734{
735 Assert(pPackage->fCanAffectRegistration);
736 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
737
738 for (DWORD i = 0; i < pPackage->Msp.cTargetProductCodes; ++i)
739 {
740 BURN_MSPTARGETPRODUCT* pTargetProduct = pPackage->Msp.rgTargetProducts + i;
741
742 if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pTargetProduct->registrationState)
743 {
744 pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
745 break;
746 }
747 }
748}
749
645 750
646// internal helper functions 751// internal helper functions
647 752