diff options
| author | Sean Hall <r.sean.hall@gmail.com> | 2021-02-22 16:16:12 -0600 |
|---|---|---|
| committer | Sean Hall <r.sean.hall@gmail.com> | 2021-02-22 20:25:06 -0600 |
| commit | 4f4c85ed66f1b2dfb1bec76d54d7b50c637d5bfa (patch) | |
| tree | 6de8e63ad46626ec457af256d481e81d726f3860 /src/engine/mspengine.cpp | |
| parent | d0d93beac0b79fa9c3d43398813954988afda18f (diff) | |
| download | wix-4f4c85ed66f1b2dfb1bec76d54d7b50c637d5bfa.tar.gz wix-4f4c85ed66f1b2dfb1bec76d54d7b50c637d5bfa.tar.bz2 wix-4f4c85ed66f1b2dfb1bec76d54d7b50c637d5bfa.zip | |
Add patch target for slipstream MSI package even if not installed.
Fixes #3897
Diffstat (limited to 'src/engine/mspengine.cpp')
| -rw-r--r-- | src/engine/mspengine.cpp | 196 |
1 files changed, 130 insertions, 66 deletions
diff --git a/src/engine/mspengine.cpp b/src/engine/mspengine.cpp index 14db27a6..4b7f9a0a 100644 --- a/src/engine/mspengine.cpp +++ b/src/engine/mspengine.cpp | |||
| @@ -30,18 +30,23 @@ static HRESULT AddPossibleTargetProduct( | |||
| 30 | __inout DWORD* pcPossibleTargetProducts | 30 | __inout DWORD* pcPossibleTargetProducts |
| 31 | ); | 31 | ); |
| 32 | static HRESULT AddDetectedTargetProduct( | 32 | static HRESULT AddDetectedTargetProduct( |
| 33 | __in BURN_PACKAGES* pPackages, | ||
| 34 | __in BURN_PACKAGE* pPackage, | 33 | __in BURN_PACKAGE* pPackage, |
| 35 | __in DWORD dwOrder, | 34 | __in DWORD dwOrder, |
| 36 | __in_z LPCWSTR wzProductCode, | 35 | __in_z LPCWSTR wzProductCode, |
| 37 | __in MSIINSTALLCONTEXT context | 36 | __in MSIINSTALLCONTEXT context, |
| 37 | __out DWORD* pdwTargetProductIndex | ||
| 38 | ); | ||
| 39 | static HRESULT AddMsiChainedPatch( | ||
| 40 | __in BURN_PACKAGE* pPackage, | ||
| 41 | __in BURN_PACKAGE* pMspPackage, | ||
| 42 | __in DWORD dwMspTargetProductIndex, | ||
| 43 | __out DWORD* pdwChainedPatchIndex | ||
| 38 | ); | 44 | ); |
| 39 | static void DeterminePatchChainedTarget( | 45 | static HRESULT DeterminePatchChainedTarget( |
| 40 | __in BURN_PACKAGES* pPackages, | 46 | __in BURN_PACKAGES* pPackages, |
| 41 | __in BURN_PACKAGE* pMspPackage, | 47 | __in BURN_PACKAGE* pMspPackage, |
| 42 | __in LPCWSTR wzTargetProductCode, | 48 | __in LPCWSTR wzTargetProductCode, |
| 43 | __out BURN_PACKAGE** ppChainedTargetPackage, | 49 | __in DWORD dwMspTargetProductIndex |
| 44 | __out BOOL* pfSlipstreamed | ||
| 45 | ); | 50 | ); |
| 46 | static HRESULT PlanTargetProduct( | 51 | static HRESULT PlanTargetProduct( |
| 47 | __in BOOTSTRAPPER_DISPLAY display, | 52 | __in BOOTSTRAPPER_DISPLAY display, |
| @@ -159,16 +164,20 @@ extern "C" HRESULT MspEngineDetectInitialize( | |||
| 159 | { | 164 | { |
| 160 | for (DWORD iPatchInfo = 0; iPatchInfo < pPackages->cPatchInfo; ++iPatchInfo) | 165 | for (DWORD iPatchInfo = 0; iPatchInfo < pPackages->cPatchInfo; ++iPatchInfo) |
| 161 | { | 166 | { |
| 162 | if (ERROR_SUCCESS == pPackages->rgPatchInfo[iPatchInfo].uStatus) | 167 | hr = HRESULT_FROM_WIN32(pPackages->rgPatchInfo[iPatchInfo].uStatus); |
| 163 | { | 168 | BURN_PACKAGE* pMspPackage = pPackages->rgPatchInfoToPackage[iPatchInfo]; |
| 164 | BURN_PACKAGE* pMspPackage = pPackages->rgPatchInfoToPackage[iPatchInfo]; | 169 | Assert(BURN_PACKAGE_TYPE_MSP == pMspPackage->type); |
| 165 | Assert(BURN_PACKAGE_TYPE_MSP == pMspPackage->type); | ||
| 166 | 170 | ||
| 171 | if (S_OK == hr) | ||
| 172 | { | ||
| 167 | // Note that we do add superseded and obsolete MSP packages. Package Detect and Plan will sort them out later. | 173 | // Note that we do add superseded and obsolete MSP packages. Package Detect and Plan will sort them out later. |
| 168 | hr = AddDetectedTargetProduct(pPackages, pMspPackage, pPackages->rgPatchInfo[iPatchInfo].dwOrder, pPossibleTargetProduct->wzProductCode, pPossibleTargetProduct->context); | 174 | hr = MspEngineAddDetectedTargetProduct(pPackages, pMspPackage, pPackages->rgPatchInfo[iPatchInfo].dwOrder, pPossibleTargetProduct->wzProductCode, pPossibleTargetProduct->context); |
| 169 | ExitOnFailure(hr, "Failed to add target product code to package: %ls", pMspPackage->sczId); | 175 | ExitOnFailure(hr, "Failed to add target product code to package: %ls", pMspPackage->sczId); |
| 170 | } | 176 | } |
| 171 | // TODO: should we log something for this error case? | 177 | else |
| 178 | { | ||
| 179 | LogStringLine(REPORT_DEBUG, " 0x%x: Patch applicability failed for package: %ls", hr, pMspPackage->sczId); | ||
| 180 | } | ||
| 172 | } | 181 | } |
| 173 | } | 182 | } |
| 174 | else | 183 | else |
| @@ -192,6 +201,54 @@ LExit: | |||
| 192 | return hr; | 201 | return hr; |
| 193 | } | 202 | } |
| 194 | 203 | ||
| 204 | extern "C" HRESULT MspEngineAddDetectedTargetProduct( | ||
| 205 | __in BURN_PACKAGES* pPackages, | ||
| 206 | __in BURN_PACKAGE* pPackage, | ||
| 207 | __in DWORD dwOrder, | ||
| 208 | __in_z LPCWSTR wzProductCode, | ||
| 209 | __in MSIINSTALLCONTEXT context | ||
| 210 | ) | ||
| 211 | { | ||
| 212 | HRESULT hr = S_OK; | ||
| 213 | DWORD dwTargetProductIndex = 0; | ||
| 214 | |||
| 215 | hr = AddDetectedTargetProduct(pPackage, dwOrder, wzProductCode, context, &dwTargetProductIndex); | ||
| 216 | ExitOnFailure(hr, "Failed to add detected target product."); | ||
| 217 | |||
| 218 | hr = DeterminePatchChainedTarget(pPackages, pPackage, wzProductCode, dwTargetProductIndex); | ||
| 219 | ExitOnFailure(hr, "Failed to determine patch chained target."); | ||
| 220 | |||
| 221 | LExit: | ||
| 222 | return hr; | ||
| 223 | } | ||
| 224 | |||
| 225 | extern "C" HRESULT MspEngineAddMissingSlipstreamTarget( | ||
| 226 | __in BURN_PACKAGE* pMsiPackage, | ||
| 227 | __in BURN_SLIPSTREAM_MSP* pSlipstreamMsp | ||
| 228 | ) | ||
| 229 | { | ||
| 230 | HRESULT hr = S_OK; | ||
| 231 | DWORD dwTargetProductIndex = 0; | ||
| 232 | BURN_MSPTARGETPRODUCT* pTargetProduct = NULL; | ||
| 233 | DWORD dwChainedPatchIndex = 0; | ||
| 234 | |||
| 235 | hr = AddDetectedTargetProduct(pSlipstreamMsp->pMspPackage, 0, pMsiPackage->Msi.sczProductCode, pMsiPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED, &dwTargetProductIndex); | ||
| 236 | ExitOnFailure(hr, "Failed to add missing slipstream target."); | ||
| 237 | |||
| 238 | pTargetProduct = pSlipstreamMsp->pMspPackage->Msp.rgTargetProducts + dwTargetProductIndex; | ||
| 239 | pTargetProduct->fSlipstream = TRUE; | ||
| 240 | pTargetProduct->fSlipstreamRequired = TRUE; | ||
| 241 | pTargetProduct->pChainedTargetPackage = pMsiPackage; | ||
| 242 | |||
| 243 | hr = AddMsiChainedPatch(pMsiPackage, pSlipstreamMsp->pMspPackage, dwTargetProductIndex, &dwChainedPatchIndex); | ||
| 244 | ExitOnFailure(hr, "Failed to add chained patch."); | ||
| 245 | |||
| 246 | pSlipstreamMsp->dwMsiChainedPatchIndex = dwChainedPatchIndex; | ||
| 247 | |||
| 248 | LExit: | ||
| 249 | return hr; | ||
| 250 | } | ||
| 251 | |||
| 195 | extern "C" HRESULT MspEngineDetectPackage( | 252 | extern "C" HRESULT MspEngineDetectPackage( |
| 196 | __in BURN_PACKAGE* pPackage, | 253 | __in BURN_PACKAGE* pPackage, |
| 197 | __in BURN_USER_EXPERIENCE* pUserExperience | 254 | __in BURN_USER_EXPERIENCE* pUserExperience |
| @@ -219,7 +276,6 @@ extern "C" HRESULT MspEngineDetectPackage( | |||
| 219 | for (DWORD i = 0; i < pPackage->Msp.cTargetProductCodes; ++i) | 276 | for (DWORD i = 0; i < pPackage->Msp.cTargetProductCodes; ++i) |
| 220 | { | 277 | { |
| 221 | BURN_MSPTARGETPRODUCT* pTargetProduct = pPackage->Msp.rgTargetProducts + i; | 278 | BURN_MSPTARGETPRODUCT* pTargetProduct = pPackage->Msp.rgTargetProducts + i; |
| 222 | BOOL fInstalled = FALSE; | ||
| 223 | 279 | ||
| 224 | hr = WiuGetPatchInfoEx(pPackage->Msp.sczPatchCode, pTargetProduct->wzTargetProductCode, NULL, pTargetProduct->context, INSTALLPROPERTY_PATCHSTATE, &sczState); | 280 | hr = WiuGetPatchInfoEx(pPackage->Msp.sczPatchCode, pTargetProduct->wzTargetProductCode, NULL, pTargetProduct->context, INSTALLPROPERTY_PATCHSTATE, &sczState); |
| 225 | if (SUCCEEDED(hr)) | 281 | if (SUCCEEDED(hr)) |
| @@ -227,17 +283,17 @@ extern "C" HRESULT MspEngineDetectPackage( | |||
| 227 | switch (*sczState) | 283 | switch (*sczState) |
| 228 | { | 284 | { |
| 229 | case '1': | 285 | case '1': |
| 230 | fInstalled = TRUE; | 286 | pTargetProduct->fInstalled = TRUE; |
| 231 | pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_PRESENT; | 287 | pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_PRESENT; |
| 232 | break; | 288 | break; |
| 233 | 289 | ||
| 234 | case '2': | 290 | case '2': |
| 235 | fInstalled = TRUE; | 291 | pTargetProduct->fInstalled = TRUE; |
| 236 | pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED; | 292 | pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED; |
| 237 | break; | 293 | break; |
| 238 | 294 | ||
| 239 | case '4': | 295 | case '4': |
| 240 | fInstalled = TRUE; | 296 | pTargetProduct->fInstalled = TRUE; |
| 241 | pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE; | 297 | pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE; |
| 242 | break; | 298 | break; |
| 243 | 299 | ||
| @@ -246,7 +302,7 @@ extern "C" HRESULT MspEngineDetectPackage( | |||
| 246 | break; | 302 | break; |
| 247 | } | 303 | } |
| 248 | } | 304 | } |
| 249 | else if (HRESULT_FROM_WIN32(ERROR_UNKNOWN_PATCH) == hr) | 305 | else if (HRESULT_FROM_WIN32(ERROR_UNKNOWN_PATCH) == hr || HRESULT_FROM_WIN32(ERROR_UNKNOWN_PRODUCT) == hr) |
| 250 | { | 306 | { |
| 251 | pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT; | 307 | pTargetProduct->patchPackageState = BOOTSTRAPPER_PACKAGE_STATE_ABSENT; |
| 252 | hr = S_OK; | 308 | hr = S_OK; |
| @@ -260,9 +316,9 @@ extern "C" HRESULT MspEngineDetectPackage( | |||
| 260 | 316 | ||
| 261 | if (pPackage->fCanAffectRegistration) | 317 | if (pPackage->fCanAffectRegistration) |
| 262 | { | 318 | { |
| 263 | pTargetProduct->registrationState = fInstalled ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT; | 319 | pTargetProduct->registrationState = pTargetProduct->fInstalled ? BURN_PACKAGE_REGISTRATION_STATE_PRESENT : BURN_PACKAGE_REGISTRATION_STATE_ABSENT; |
| 264 | 320 | ||
| 265 | if (fInstalled) | 321 | if (pTargetProduct->fInstalled) |
| 266 | { | 322 | { |
| 267 | pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT; | 323 | pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT; |
| 268 | } | 324 | } |
| @@ -290,6 +346,13 @@ extern "C" HRESULT MspEnginePlanInitializePackage( | |||
| 290 | { | 346 | { |
| 291 | BURN_MSPTARGETPRODUCT* pTargetProduct = pPackage->Msp.rgTargetProducts + i; | 347 | BURN_MSPTARGETPRODUCT* pTargetProduct = pPackage->Msp.rgTargetProducts + i; |
| 292 | 348 | ||
| 349 | if (!pTargetProduct->fInstalled && pTargetProduct->fSlipstreamRequired && BOOTSTRAPPER_REQUEST_STATE_PRESENT > pTargetProduct->pChainedTargetPackage->requested) | ||
| 350 | { | ||
| 351 | // There's no way to apply the patch if the target isn't installed. | ||
| 352 | pTargetProduct->defaultRequested = pTargetProduct->requested = BOOTSTRAPPER_REQUEST_STATE_NONE; | ||
| 353 | continue; | ||
| 354 | } | ||
| 355 | |||
| 293 | pTargetProduct->defaultRequested = pTargetProduct->requested = pPackage->requested; | 356 | pTargetProduct->defaultRequested = pTargetProduct->requested = pPackage->requested; |
| 294 | 357 | ||
| 295 | hr = UserExperienceOnPlanPatchTarget(pUserExperience, pPackage->sczId, pTargetProduct->wzTargetProductCode, &pTargetProduct->requested); | 358 | hr = UserExperienceOnPlanPatchTarget(pUserExperience, pPackage->sczId, pTargetProduct->wzTargetProductCode, &pTargetProduct->requested); |
| @@ -637,32 +700,6 @@ LExit: | |||
| 637 | return hr; | 700 | return hr; |
| 638 | } | 701 | } |
| 639 | 702 | ||
| 640 | extern "C" void MspEngineSlipstreamUpdateState( | ||
| 641 | __in BURN_PACKAGE* pPackage, | ||
| 642 | __in BOOTSTRAPPER_ACTION_STATE execute, | ||
| 643 | __in BOOTSTRAPPER_ACTION_STATE rollback | ||
| 644 | ) | ||
| 645 | { | ||
| 646 | Assert(BURN_PACKAGE_TYPE_MSP == pPackage->type); | ||
| 647 | |||
| 648 | // If the dependency manager set our state then that means something else | ||
| 649 | // is dependent on our package. That trumps whatever the slipstream update | ||
| 650 | // state might set. | ||
| 651 | if (!pPackage->fDependencyManagerWasHere) | ||
| 652 | { | ||
| 653 | // The highest aggregate action state found will be returned. | ||
| 654 | if (pPackage->execute < execute) | ||
| 655 | { | ||
| 656 | pPackage->execute = execute; | ||
| 657 | } | ||
| 658 | |||
| 659 | if (pPackage->rollback < rollback) | ||
| 660 | { | ||
| 661 | pPackage->rollback = rollback; | ||
| 662 | } | ||
| 663 | } | ||
| 664 | } | ||
| 665 | |||
| 666 | extern "C" void MspEngineUpdateInstallRegistrationState( | 703 | extern "C" void MspEngineUpdateInstallRegistrationState( |
| 667 | __in BURN_EXECUTE_ACTION* pAction, | 704 | __in BURN_EXECUTE_ACTION* pAction, |
| 668 | __in HRESULT hrExecute, | 705 | __in HRESULT hrExecute, |
| @@ -926,43 +963,68 @@ LExit: | |||
| 926 | } | 963 | } |
| 927 | 964 | ||
| 928 | static HRESULT AddDetectedTargetProduct( | 965 | static HRESULT AddDetectedTargetProduct( |
| 929 | __in BURN_PACKAGES* pPackages, | ||
| 930 | __in BURN_PACKAGE* pPackage, | 966 | __in BURN_PACKAGE* pPackage, |
| 931 | __in DWORD dwOrder, | 967 | __in DWORD dwOrder, |
| 932 | __in_z LPCWSTR wzProductCode, | 968 | __in_z LPCWSTR wzProductCode, |
| 933 | __in MSIINSTALLCONTEXT context | 969 | __in MSIINSTALLCONTEXT context, |
| 970 | __out DWORD* pdwTargetProductIndex | ||
| 934 | ) | 971 | ) |
| 935 | { | 972 | { |
| 936 | HRESULT hr = S_OK; | 973 | HRESULT hr = S_OK; |
| 974 | BURN_MSPTARGETPRODUCT* pTargetProduct = NULL; | ||
| 975 | |||
| 976 | *pdwTargetProductIndex = BURN_PACKAGE_INVALID_PATCH_INDEX; | ||
| 937 | 977 | ||
| 938 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pPackage->Msp.rgTargetProducts), pPackage->Msp.cTargetProductCodes + 1, sizeof(BURN_MSPTARGETPRODUCT), 5); | 978 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pPackage->Msp.rgTargetProducts), pPackage->Msp.cTargetProductCodes + 1, sizeof(BURN_MSPTARGETPRODUCT), 5); |
| 939 | ExitOnFailure(hr, "Failed to ensure enough target product codes were allocated."); | 979 | ExitOnFailure(hr, "Failed to ensure enough target product codes were allocated."); |
| 940 | 980 | ||
| 941 | hr = ::StringCchCopyW(pPackage->Msp.rgTargetProducts[pPackage->Msp.cTargetProductCodes].wzTargetProductCode, countof(pPackage->Msp.rgTargetProducts[pPackage->Msp.cTargetProductCodes].wzTargetProductCode), wzProductCode); | 981 | pTargetProduct = pPackage->Msp.rgTargetProducts + pPackage->Msp.cTargetProductCodes; |
| 982 | |||
| 983 | hr = ::StringCchCopyW(pTargetProduct->wzTargetProductCode, countof(pTargetProduct->wzTargetProductCode), wzProductCode); | ||
| 942 | ExitOnFailure(hr, "Failed to copy target product code."); | 984 | ExitOnFailure(hr, "Failed to copy target product code."); |
| 943 | 985 | ||
| 944 | DeterminePatchChainedTarget(pPackages, pPackage, wzProductCode, | 986 | pTargetProduct->context = context; |
| 945 | &pPackage->Msp.rgTargetProducts[pPackage->Msp.cTargetProductCodes].pChainedTargetPackage, | 987 | pTargetProduct->dwOrder = dwOrder; |
| 946 | &pPackage->Msp.rgTargetProducts[pPackage->Msp.cTargetProductCodes].fSlipstream); | ||
| 947 | 988 | ||
| 948 | pPackage->Msp.rgTargetProducts[pPackage->Msp.cTargetProductCodes].context = context; | 989 | *pdwTargetProductIndex = pPackage->Msp.cTargetProductCodes; |
| 949 | pPackage->Msp.rgTargetProducts[pPackage->Msp.cTargetProductCodes].dwOrder = dwOrder; | ||
| 950 | ++pPackage->Msp.cTargetProductCodes; | 990 | ++pPackage->Msp.cTargetProductCodes; |
| 951 | 991 | ||
| 952 | LExit: | 992 | LExit: |
| 953 | return hr; | 993 | return hr; |
| 954 | } | 994 | } |
| 955 | 995 | ||
| 956 | static void DeterminePatchChainedTarget( | 996 | static HRESULT AddMsiChainedPatch( |
| 997 | __in BURN_PACKAGE* pPackage, | ||
| 998 | __in BURN_PACKAGE* pMspPackage, | ||
| 999 | __in DWORD dwMspTargetProductIndex, | ||
| 1000 | __out DWORD* pdwChainedPatchIndex | ||
| 1001 | ) | ||
| 1002 | { | ||
| 1003 | HRESULT hr = S_OK; | ||
| 1004 | |||
| 1005 | hr = MemEnsureArraySize(reinterpret_cast<LPVOID*>(&pPackage->Msi.rgChainedPatches), pPackage->Msi.cChainedPatches + 1, sizeof(BURN_CHAINED_PATCH), 5); | ||
| 1006 | ExitOnFailure(hr, "Failed to ensure enough chained patches were allocated."); | ||
| 1007 | |||
| 1008 | BURN_CHAINED_PATCH* pChainedPatch = pPackage->Msi.rgChainedPatches + pPackage->Msi.cChainedPatches; | ||
| 1009 | pChainedPatch->pMspPackage = pMspPackage; | ||
| 1010 | pChainedPatch->dwMspTargetProductIndex = dwMspTargetProductIndex; | ||
| 1011 | |||
| 1012 | *pdwChainedPatchIndex = pPackage->Msi.cChainedPatches; | ||
| 1013 | ++pPackage->Msi.cChainedPatches; | ||
| 1014 | LExit: | ||
| 1015 | return hr; | ||
| 1016 | } | ||
| 1017 | |||
| 1018 | static HRESULT DeterminePatchChainedTarget( | ||
| 957 | __in BURN_PACKAGES* pPackages, | 1019 | __in BURN_PACKAGES* pPackages, |
| 958 | __in BURN_PACKAGE* pMspPackage, | 1020 | __in BURN_PACKAGE* pMspPackage, |
| 959 | __in LPCWSTR wzTargetProductCode, | 1021 | __in LPCWSTR wzTargetProductCode, |
| 960 | __out BURN_PACKAGE** ppChainedTargetPackage, | 1022 | __in DWORD dwMspTargetProductIndex |
| 961 | __out BOOL* pfSlipstreamed | ||
| 962 | ) | 1023 | ) |
| 963 | { | 1024 | { |
| 964 | BURN_PACKAGE* pTargetMsiPackage = NULL; | 1025 | HRESULT hr = S_OK; |
| 965 | BOOL fSlipstreamed = FALSE; | 1026 | DWORD dwChainedPatchIndex = 0; |
| 1027 | BURN_MSPTARGETPRODUCT* pTargetProduct = pMspPackage->Msp.rgTargetProducts + dwMspTargetProductIndex; | ||
| 966 | 1028 | ||
| 967 | for (DWORD iPackage = 0; iPackage < pPackages->cPackages; ++iPackage) | 1029 | for (DWORD iPackage = 0; iPackage < pPackages->cPackages; ++iPackage) |
| 968 | { | 1030 | { |
| @@ -970,15 +1032,19 @@ static void DeterminePatchChainedTarget( | |||
| 970 | 1032 | ||
| 971 | if (BURN_PACKAGE_TYPE_MSI == pPackage->type && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzTargetProductCode, -1, pPackage->Msi.sczProductCode, -1)) | 1033 | if (BURN_PACKAGE_TYPE_MSI == pPackage->type && CSTR_EQUAL == ::CompareStringW(LOCALE_NEUTRAL, 0, wzTargetProductCode, -1, pPackage->Msi.sczProductCode, -1)) |
| 972 | { | 1034 | { |
| 973 | pTargetMsiPackage = pPackage; | 1035 | pTargetProduct->pChainedTargetPackage = pPackage; |
| 1036 | |||
| 1037 | hr = AddMsiChainedPatch(pPackage, pMspPackage, dwMspTargetProductIndex, &dwChainedPatchIndex); | ||
| 1038 | ExitOnFailure(hr, "Failed to add chained patch."); | ||
| 974 | 1039 | ||
| 975 | for (DWORD j = 0; j < pPackage->Msi.cSlipstreamMspPackages; ++j) | 1040 | for (DWORD j = 0; j < pPackage->Msi.cSlipstreamMspPackages; ++j) |
| 976 | { | 1041 | { |
| 977 | BURN_PACKAGE* pSlipstreamMsp = pPackage->Msi.rgpSlipstreamMspPackages[j]; | 1042 | BURN_SLIPSTREAM_MSP* pSlipstreamMsp = pPackage->Msi.rgSlipstreamMsps + j; |
| 978 | if (pSlipstreamMsp == pMspPackage) | 1043 | if (pSlipstreamMsp->pMspPackage == pMspPackage) |
| 979 | { | 1044 | { |
| 980 | AssertSz(!fSlipstreamed, "An MSP should only show up as a slipstreamed patch in an MSI once."); | 1045 | AssertSz(BURN_PACKAGE_INVALID_PATCH_INDEX == pSlipstreamMsp->dwMsiChainedPatchIndex, "An MSP should only show up as a slipstreamed patch in an MSI once."); |
| 981 | fSlipstreamed = TRUE; | 1046 | pTargetProduct->fSlipstream = TRUE; |
| 1047 | pSlipstreamMsp->dwMsiChainedPatchIndex = dwChainedPatchIndex; | ||
| 982 | break; | 1048 | break; |
| 983 | } | 1049 | } |
| 984 | } | 1050 | } |
| @@ -987,10 +1053,8 @@ static void DeterminePatchChainedTarget( | |||
| 987 | } | 1053 | } |
| 988 | } | 1054 | } |
| 989 | 1055 | ||
| 990 | *ppChainedTargetPackage = pTargetMsiPackage; | 1056 | LExit: |
| 991 | *pfSlipstreamed = fSlipstreamed; | 1057 | return hr; |
| 992 | |||
| 993 | return; | ||
| 994 | } | 1058 | } |
| 995 | 1059 | ||
| 996 | static HRESULT PlanTargetProduct( | 1060 | static HRESULT PlanTargetProduct( |
