diff options
Diffstat (limited to 'src/engine/mspengine.cpp')
-rw-r--r-- | src/engine/mspengine.cpp | 109 |
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 | ||
664 | extern "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 | |||
727 | LExit: | ||
728 | return; | ||
729 | } | ||
730 | |||
731 | extern "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 | ||