Fix patch registration states during plan and apply.
Add logging for slipstreamed patches. #6297
This commit is contained in:
Родитель
4f4c85ed66
Коммит
a98115d996
|
@ -2032,7 +2032,7 @@ static HRESULT ExecuteMsiPackage(
|
|||
LExit:
|
||||
if (fExecuted)
|
||||
{
|
||||
MsiEngineUpdateInstallRegistrationState(pExecuteAction, hrExecute, fInsideMsiTransaction);
|
||||
MsiEngineUpdateInstallRegistrationState(pExecuteAction, fRollback, hrExecute, fInsideMsiTransaction);
|
||||
}
|
||||
|
||||
if (fBeginCalled)
|
||||
|
@ -2248,7 +2248,20 @@ static HRESULT ExecuteDependencyAction(
|
|||
{
|
||||
pAction->packageDependency.pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
|
||||
}
|
||||
if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pAction->packageDependency.pPackage->installRegistrationState)
|
||||
|
||||
if (BURN_PACKAGE_TYPE_MSP == pAction->packageDependency.pPackage->type)
|
||||
{
|
||||
for (DWORD i = 0; i < pAction->packageDependency.pPackage->Msp.cTargetProductCodes; ++i)
|
||||
{
|
||||
BURN_MSPTARGETPRODUCT* pTargetProduct = pAction->packageDependency.pPackage->Msp.rgTargetProducts + i;
|
||||
|
||||
if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pTargetProduct->registrationState)
|
||||
{
|
||||
pTargetProduct->registrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pAction->packageDependency.pPackage->installRegistrationState)
|
||||
{
|
||||
pAction->packageDependency.pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
|
||||
}
|
||||
|
@ -2259,7 +2272,20 @@ static HRESULT ExecuteDependencyAction(
|
|||
{
|
||||
pAction->packageDependency.pPackage->cacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
|
||||
}
|
||||
if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pAction->packageDependency.pPackage->installRegistrationState)
|
||||
|
||||
if (BURN_PACKAGE_TYPE_MSP == pAction->packageDependency.pPackage->type)
|
||||
{
|
||||
for (DWORD i = 0; i < pAction->packageDependency.pPackage->Msp.cTargetProductCodes; ++i)
|
||||
{
|
||||
BURN_MSPTARGETPRODUCT* pTargetProduct = pAction->packageDependency.pPackage->Msp.rgTargetProducts + i;
|
||||
|
||||
if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pTargetProduct->registrationState)
|
||||
{
|
||||
pTargetProduct->registrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pAction->packageDependency.pPackage->installRegistrationState)
|
||||
{
|
||||
pAction->packageDependency.pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
|
||||
}
|
||||
|
|
|
@ -1814,15 +1814,30 @@ static void LogPackages(
|
|||
|
||||
LogId(REPORT_STANDARD, MSG_PLANNED_PACKAGE, pPackage->sczId, LoggingPackageStateToString(pPackage->currentState), LoggingRequestStateToString(pPackage->defaultRequested), LoggingRequestStateToString(pPackage->requested), LoggingActionStateToString(pPackage->execute), LoggingActionStateToString(pPackage->rollback), LoggingBoolToString(pPackage->fAcquire), LoggingBoolToString(pPackage->fUncache), LoggingDependencyActionToString(pPackage->dependencyExecute), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->expectedInstallRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->expectedCacheRegistrationState));
|
||||
|
||||
if (BURN_PACKAGE_TYPE_MSI == pPackage->type && pPackage->Msi.cFeatures)
|
||||
if (BURN_PACKAGE_TYPE_MSI == pPackage->type)
|
||||
{
|
||||
LogId(REPORT_STANDARD, MSG_PLANNED_MSI_FEATURES, pPackage->Msi.cFeatures, pPackage->sczId);
|
||||
|
||||
for (DWORD j = 0; j < pPackage->Msi.cFeatures; ++j)
|
||||
if (pPackage->Msi.cFeatures)
|
||||
{
|
||||
const BURN_MSIFEATURE* pFeature = &pPackage->Msi.rgFeatures[j];
|
||||
LogId(REPORT_STANDARD, MSG_PLANNED_MSI_FEATURES, pPackage->Msi.cFeatures, pPackage->sczId);
|
||||
|
||||
LogId(REPORT_STANDARD, MSG_PLANNED_MSI_FEATURE, pFeature->sczId, LoggingMsiFeatureStateToString(pFeature->currentState), LoggingMsiFeatureStateToString(pFeature->defaultRequested), LoggingMsiFeatureStateToString(pFeature->requested), LoggingMsiFeatureActionToString(pFeature->execute), LoggingMsiFeatureActionToString(pFeature->rollback));
|
||||
for (DWORD j = 0; j < pPackage->Msi.cFeatures; ++j)
|
||||
{
|
||||
const BURN_MSIFEATURE* pFeature = &pPackage->Msi.rgFeatures[j];
|
||||
|
||||
LogId(REPORT_STANDARD, MSG_PLANNED_MSI_FEATURE, pFeature->sczId, LoggingMsiFeatureStateToString(pFeature->currentState), LoggingMsiFeatureStateToString(pFeature->defaultRequested), LoggingMsiFeatureStateToString(pFeature->requested), LoggingMsiFeatureActionToString(pFeature->execute), LoggingMsiFeatureActionToString(pFeature->rollback));
|
||||
}
|
||||
}
|
||||
|
||||
if (pPackage->Msi.cSlipstreamMspPackages)
|
||||
{
|
||||
LogId(REPORT_STANDARD, MSG_PLANNED_SLIPSTREAMED_MSP_TARGETS, pPackage->Msi.cSlipstreamMspPackages, pPackage->sczId);
|
||||
|
||||
for (DWORD j = 0; j < pPackage->Msi.cSlipstreamMspPackages; ++j)
|
||||
{
|
||||
const BURN_SLIPSTREAM_MSP* pSlipstreamMsp = &pPackage->Msi.rgSlipstreamMsps[j];
|
||||
|
||||
LogId(REPORT_STANDARD, MSG_PLANNED_SLIPSTREAMED_MSP_TARGET, pSlipstreamMsp->pMspPackage->sczId, LoggingActionStateToString(pSlipstreamMsp->execute), LoggingActionStateToString(pSlipstreamMsp->rollback));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (BURN_PACKAGE_TYPE_MSP == pPackage->type && pPackage->Msp.cTargetProductCodes)
|
||||
|
|
|
@ -774,6 +774,18 @@ static HRESULT DetectPackageDependents(
|
|||
{
|
||||
pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
|
||||
}
|
||||
if (BURN_PACKAGE_TYPE_MSP == pPackage->type)
|
||||
{
|
||||
for (DWORD i = 0; i < pPackage->Msp.cTargetProductCodes; ++i)
|
||||
{
|
||||
BURN_MSPTARGETPRODUCT* pTargetProduct = pPackage->Msp.rgTargetProducts + i;
|
||||
|
||||
if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pTargetProduct->registrationState)
|
||||
{
|
||||
pTargetProduct->registrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LExit:
|
||||
|
|
|
@ -855,6 +855,9 @@ extern "C" HRESULT ElevationExecuteMsiPackage(
|
|||
DWORD dwResult = 0;
|
||||
|
||||
// serialize message data
|
||||
hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fRollback);
|
||||
ExitOnFailure(hr, "Failed to write rollback flag to message buffer.");
|
||||
|
||||
hr = BuffWriteString(&pbData, &cbData, pExecuteAction->msiPackage.pPackage->sczId);
|
||||
ExitOnFailure(hr, "Failed to write package id to message buffer.");
|
||||
|
||||
|
@ -886,16 +889,15 @@ extern "C" HRESULT ElevationExecuteMsiPackage(
|
|||
// Slipstream patches actions.
|
||||
for (DWORD i = 0; i < pExecuteAction->msiPackage.pPackage->Msi.cSlipstreamMspPackages; ++i)
|
||||
{
|
||||
hr = BuffWriteNumber(&pbData, &cbData, (DWORD)pExecuteAction->msiPackage.rgSlipstreamPatches[i]);
|
||||
BURN_SLIPSTREAM_MSP* pSlipstreamMsp = pExecuteAction->msiPackage.pPackage->Msi.rgSlipstreamMsps + i;
|
||||
BOOTSTRAPPER_ACTION_STATE* pAction = fRollback ? &pSlipstreamMsp->rollback : &pSlipstreamMsp->execute;
|
||||
hr = BuffWriteNumber(&pbData, &cbData, (DWORD)*pAction);
|
||||
ExitOnFailure(hr, "Failed to write slipstream patch action to message buffer.");
|
||||
}
|
||||
|
||||
hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData);
|
||||
ExitOnFailure(hr, "Failed to write variables.");
|
||||
|
||||
hr = BuffWriteNumber(&pbData, &cbData, (DWORD)fRollback);
|
||||
ExitOnFailure(hr, "Failed to write rollback flag to message buffer.");
|
||||
|
||||
|
||||
// send message
|
||||
context.pfnMessageHandler = pfnMessageHandler;
|
||||
|
@ -2263,6 +2265,9 @@ static HRESULT OnExecuteMsiPackage(
|
|||
executeAction.type = BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE;
|
||||
|
||||
// Deserialize message data.
|
||||
hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback);
|
||||
ExitOnFailure(hr, "Failed to read rollback flag.");
|
||||
|
||||
hr = BuffReadString(pbData, cbData, &iData, &sczPackage);
|
||||
ExitOnFailure(hr, "Failed to read MSI package id.");
|
||||
|
||||
|
@ -2303,12 +2308,11 @@ static HRESULT OnExecuteMsiPackage(
|
|||
// Read slipstream patches actions.
|
||||
if (executeAction.msiPackage.pPackage->Msi.cSlipstreamMspPackages)
|
||||
{
|
||||
executeAction.msiPackage.rgSlipstreamPatches = (BOOTSTRAPPER_ACTION_STATE*)MemAlloc(executeAction.msiPackage.pPackage->Msi.cSlipstreamMspPackages * sizeof(BOOTSTRAPPER_ACTION_STATE), TRUE);
|
||||
ExitOnNull(executeAction.msiPackage.rgSlipstreamPatches, hr, E_OUTOFMEMORY, "Failed to allocate memory for slipstream patch actions.");
|
||||
|
||||
for (DWORD i = 0; i < executeAction.msiPackage.pPackage->Msi.cSlipstreamMspPackages; ++i)
|
||||
{
|
||||
hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&executeAction.msiPackage.rgSlipstreamPatches[i]);
|
||||
BURN_SLIPSTREAM_MSP* pSlipstreamMsp = executeAction.msiPackage.pPackage->Msi.rgSlipstreamMsps + i;
|
||||
BOOTSTRAPPER_ACTION_STATE* pAction = fRollback ? &pSlipstreamMsp->rollback : &pSlipstreamMsp->execute;
|
||||
hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)pAction);
|
||||
ExitOnFailure(hr, "Failed to read slipstream action.");
|
||||
}
|
||||
}
|
||||
|
@ -2316,9 +2320,6 @@ static HRESULT OnExecuteMsiPackage(
|
|||
hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData);
|
||||
ExitOnFailure(hr, "Failed to read variables.");
|
||||
|
||||
hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&fRollback);
|
||||
ExitOnFailure(hr, "Failed to read rollback flag.");
|
||||
|
||||
// Execute MSI package.
|
||||
hr = MsiEngineExecutePackage(hwndParent, &executeAction, pVariables, fRollback, MsiExecuteMessageHandler, hPipe, &msiRestart);
|
||||
ExitOnFailure(hr, "Failed to execute MSI package.");
|
||||
|
|
|
@ -321,14 +321,14 @@ MessageId=203
|
|||
Severity=Success
|
||||
SymbolicName=MSG_PLANNED_MSI_FEATURE
|
||||
Language=English
|
||||
Planned feature: %1!ls!, state: %2!hs!, default requested: %3!hs!, ba requested: %4!hs!, execute action: %5!hs!, rollback action: %6!hs!
|
||||
Planned feature: %1!ls!, state: %2!hs!, default requested: %3!hs!, ba requested: %4!hs!, execute action: %5!hs!, rollback action: %6!hs!
|
||||
.
|
||||
|
||||
MessageId=204
|
||||
Severity=Success
|
||||
SymbolicName=MSG_PLANNED_MSI_FEATURES
|
||||
Language=English
|
||||
Plan %1!u! msi features for package: %2!ls!
|
||||
Plan %1!u! msi features for package: %2!ls!
|
||||
.
|
||||
|
||||
MessageId=205
|
||||
|
@ -419,14 +419,28 @@ MessageId=218
|
|||
Severity=Success
|
||||
SymbolicName=MSG_PLANNED_MSP_TARGETS
|
||||
Language=English
|
||||
Plan %1!u! patch targets for package: %2!ls!
|
||||
Plan %1!u! patch targets for package: %2!ls!
|
||||
.
|
||||
|
||||
MessageId=219
|
||||
Severity=Success
|
||||
SymbolicName=MSG_PLANNED_MSP_TARGET
|
||||
Language=English
|
||||
Planned patch target: %1!ls!, state: %2!hs!, default requested: %3!hs!, ba requested: %4!hs!, execute: %5!hs!, rollback: %6!hs!
|
||||
Planned patch target: %1!ls!, state: %2!hs!, default requested: %3!hs!, ba requested: %4!hs!, execute: %5!hs!, rollback: %6!hs!
|
||||
.
|
||||
|
||||
MessageId=220
|
||||
Severity=Success
|
||||
SymbolicName=MSG_PLANNED_SLIPSTREAMED_MSP_TARGETS
|
||||
Language=English
|
||||
Plan %1!u! slipstream patches for package: %2!ls!
|
||||
.
|
||||
|
||||
MessageId=221
|
||||
Severity=Success
|
||||
SymbolicName=MSG_PLANNED_SLIPSTREAMED_MSP_TARGET
|
||||
Language=English
|
||||
Planned slipstreamed patch: %1!ls!, execute: %2!hs!, rollback: %3!hs!
|
||||
.
|
||||
|
||||
MessageId=299
|
||||
|
|
|
@ -42,7 +42,7 @@ static HRESULT ConcatFeatureActionProperties(
|
|||
);
|
||||
static HRESULT ConcatPatchProperty(
|
||||
__in BURN_PACKAGE* pPackage,
|
||||
__in_opt BOOTSTRAPPER_ACTION_STATE* rgSlipstreamPatchActions,
|
||||
__in BOOL fRollback,
|
||||
__inout_z LPWSTR* psczArguments
|
||||
);
|
||||
static void RegisterSourceDirectory(
|
||||
|
@ -1180,10 +1180,10 @@ extern "C" HRESULT MsiEngineExecutePackage(
|
|||
ExitOnFailure(hr, "Failed to add feature action properties to obfuscated argument string.");
|
||||
|
||||
// add slipstream patch properties
|
||||
hr = ConcatPatchProperty(pExecuteAction->msiPackage.pPackage, pExecuteAction->msiPackage.rgSlipstreamPatches, &sczProperties);
|
||||
hr = ConcatPatchProperty(pExecuteAction->msiPackage.pPackage, fRollback, &sczProperties);
|
||||
ExitOnFailure(hr, "Failed to add patch properties to argument string.");
|
||||
|
||||
hr = ConcatPatchProperty(pExecuteAction->msiPackage.pPackage, pExecuteAction->msiPackage.rgSlipstreamPatches, &sczObfuscatedProperties);
|
||||
hr = ConcatPatchProperty(pExecuteAction->msiPackage.pPackage, fRollback, &sczObfuscatedProperties);
|
||||
ExitOnFailure(hr, "Failed to add patch properties to obfuscated argument string.");
|
||||
|
||||
hr = MsiEngineConcatActionProperty(pExecuteAction->msiPackage.actionMsiProperty, &sczProperties);
|
||||
|
@ -1432,6 +1432,7 @@ extern "C" HRESULT MsiEngineCalculateInstallUiLevel(
|
|||
|
||||
extern "C" void MsiEngineUpdateInstallRegistrationState(
|
||||
__in BURN_EXECUTE_ACTION* pAction,
|
||||
__in BOOL fRollback,
|
||||
__in HRESULT hrExecute,
|
||||
__in BOOL fInsideMsiTransaction
|
||||
)
|
||||
|
@ -1462,6 +1463,49 @@ extern "C" void MsiEngineUpdateInstallRegistrationState(
|
|||
pPackage->installRegistrationState = newState;
|
||||
}
|
||||
|
||||
if (BURN_PACKAGE_REGISTRATION_STATE_ABSENT == newState)
|
||||
{
|
||||
for (DWORD i = 0; i < pPackage->Msi.cChainedPatches; ++i)
|
||||
{
|
||||
BURN_CHAINED_PATCH* pChainedPatch = pPackage->Msi.rgChainedPatches + i;
|
||||
BURN_MSPTARGETPRODUCT* pTargetProduct = pChainedPatch->pMspPackage->Msp.rgTargetProducts + pChainedPatch->dwMspTargetProductIndex;
|
||||
|
||||
if (fInsideMsiTransaction)
|
||||
{
|
||||
pTargetProduct->transactionRegistrationState = newState;
|
||||
}
|
||||
else
|
||||
{
|
||||
pTargetProduct->registrationState = newState;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (DWORD i = 0; i < pPackage->Msi.cSlipstreamMspPackages; ++i)
|
||||
{
|
||||
BURN_SLIPSTREAM_MSP* pSlipstreamMsp = pPackage->Msi.rgSlipstreamMsps + i;
|
||||
BOOTSTRAPPER_ACTION_STATE patchExecuteAction = fRollback ? pSlipstreamMsp->rollback : pSlipstreamMsp->execute;
|
||||
|
||||
if (BOOTSTRAPPER_ACTION_STATE_INSTALL > patchExecuteAction)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
BURN_CHAINED_PATCH* pChainedPatch = pPackage->Msi.rgChainedPatches + pSlipstreamMsp->dwMsiChainedPatchIndex;
|
||||
BURN_MSPTARGETPRODUCT* pTargetProduct = pChainedPatch->pMspPackage->Msp.rgTargetProducts + pChainedPatch->dwMspTargetProductIndex;
|
||||
|
||||
if (fInsideMsiTransaction)
|
||||
{
|
||||
pTargetProduct->transactionRegistrationState = newState;
|
||||
}
|
||||
else
|
||||
{
|
||||
pTargetProduct->registrationState = newState;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LExit:
|
||||
return;
|
||||
}
|
||||
|
@ -1911,7 +1955,7 @@ LExit:
|
|||
|
||||
static HRESULT ConcatPatchProperty(
|
||||
__in BURN_PACKAGE* pPackage,
|
||||
__in_opt BOOTSTRAPPER_ACTION_STATE* rgSlipstreamPatchActions,
|
||||
__in BOOL fRollback,
|
||||
__inout_z LPWSTR* psczArguments
|
||||
)
|
||||
{
|
||||
|
@ -1921,14 +1965,14 @@ static HRESULT ConcatPatchProperty(
|
|||
LPWSTR sczPatches = NULL;
|
||||
|
||||
// If there are slipstream patch actions, build up their patch action.
|
||||
if (rgSlipstreamPatchActions)
|
||||
if (pPackage->Msi.cSlipstreamMspPackages)
|
||||
{
|
||||
for (DWORD i = 0; i < pPackage->Msi.cSlipstreamMspPackages; ++i)
|
||||
{
|
||||
BURN_PACKAGE* pMspPackage = pPackage->Msi.rgSlipstreamMsps[i].pMspPackage;
|
||||
AssertSz(BURN_PACKAGE_TYPE_MSP == pMspPackage->type, "Only MSP packages can be slipstream patches.");
|
||||
BURN_SLIPSTREAM_MSP* pSlipstreamMsp = pPackage->Msi.rgSlipstreamMsps + i;
|
||||
BURN_PACKAGE* pMspPackage = pSlipstreamMsp->pMspPackage;
|
||||
BOOTSTRAPPER_ACTION_STATE patchExecuteAction = fRollback ? pSlipstreamMsp->rollback : pSlipstreamMsp->execute;
|
||||
|
||||
BOOTSTRAPPER_ACTION_STATE patchExecuteAction = rgSlipstreamPatchActions[i];
|
||||
if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL < patchExecuteAction)
|
||||
{
|
||||
hr = CacheGetCompletedPath(pMspPackage->fPerMachine, pMspPackage->sczCacheId, &sczCachedDirectory);
|
||||
|
|
|
@ -95,6 +95,7 @@ HRESULT MsiEngineCalculateInstallUiLevel(
|
|||
);
|
||||
void MsiEngineUpdateInstallRegistrationState(
|
||||
__in BURN_EXECUTE_ACTION* pAction,
|
||||
__in BOOL fRollback,
|
||||
__in HRESULT hrExecute,
|
||||
__in BOOL fInsideMsiTransaction
|
||||
);
|
||||
|
|
|
@ -372,6 +372,7 @@ extern "C" HRESULT MspEnginePlanCalculatePackage(
|
|||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
BOOL fWillUninstallAll = TRUE;
|
||||
|
||||
for (DWORD i = 0; i < pPackage->Msp.cTargetProductCodes; ++i)
|
||||
{
|
||||
|
@ -388,6 +389,7 @@ extern "C" HRESULT MspEnginePlanCalculatePackage(
|
|||
{
|
||||
case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
|
||||
execute = BOOTSTRAPPER_ACTION_STATE_REPAIR;
|
||||
fWillUninstallAll = FALSE;
|
||||
break;
|
||||
|
||||
case BOOTSTRAPPER_REQUEST_STATE_ABSENT: __fallthrough;
|
||||
|
@ -401,6 +403,7 @@ extern "C" HRESULT MspEnginePlanCalculatePackage(
|
|||
|
||||
default:
|
||||
execute = BOOTSTRAPPER_ACTION_STATE_NONE;
|
||||
fWillUninstallAll = FALSE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -411,6 +414,7 @@ extern "C" HRESULT MspEnginePlanCalculatePackage(
|
|||
case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough;
|
||||
case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
|
||||
execute = BOOTSTRAPPER_ACTION_STATE_INSTALL;
|
||||
fWillUninstallAll = FALSE;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -418,6 +422,13 @@ extern "C" HRESULT MspEnginePlanCalculatePackage(
|
|||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (pTargetProduct->fInstalled)
|
||||
{
|
||||
fWillUninstallAll = FALSE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// Calculate the rollback action if there is an execute action.
|
||||
|
@ -475,6 +486,13 @@ extern "C" HRESULT MspEnginePlanCalculatePackage(
|
|||
}
|
||||
}
|
||||
|
||||
// The dependency manager will do the wrong thing if the package level action is UNINSTALL
|
||||
// when the patch will still be applied to at least one product.
|
||||
if (!fWillUninstallAll && BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pPackage->execute)
|
||||
{
|
||||
pPackage->execute = BOOTSTRAPPER_ACTION_STATE_NONE;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
@ -776,16 +794,22 @@ extern "C" void MspEngineFinalizeInstallRegistrationState(
|
|||
ExitFunction();
|
||||
}
|
||||
|
||||
pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
|
||||
|
||||
for (DWORD i = 0; i < pPackage->Msp.cTargetProductCodes; ++i)
|
||||
if (!pPackage->Msp.cTargetProductCodes)
|
||||
{
|
||||
BURN_MSPTARGETPRODUCT* pTargetProduct = pPackage->Msp.rgTargetProducts + i;
|
||||
pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
|
||||
}
|
||||
else
|
||||
{
|
||||
pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
|
||||
|
||||
if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pTargetProduct->registrationState)
|
||||
for (DWORD i = 0; i < pPackage->Msp.cTargetProductCodes; ++i)
|
||||
{
|
||||
pPackage->installRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
|
||||
break;
|
||||
BURN_MSPTARGETPRODUCT* pTargetProduct = pPackage->Msp.rgTargetProducts + i;
|
||||
|
||||
if (pPackage->installRegistrationState < pTargetProduct->registrationState)
|
||||
{
|
||||
pPackage->installRegistrationState = pTargetProduct->registrationState;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -83,8 +83,8 @@ enum BOOTSTRAPPER_FEATURE_ACTION
|
|||
enum BURN_PACKAGE_REGISTRATION_STATE
|
||||
{
|
||||
BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN,
|
||||
BURN_PACKAGE_REGISTRATION_STATE_IGNORED,
|
||||
BURN_PACKAGE_REGISTRATION_STATE_ABSENT,
|
||||
BURN_PACKAGE_REGISTRATION_STATE_IGNORED,
|
||||
BURN_PACKAGE_REGISTRATION_STATE_PRESENT,
|
||||
};
|
||||
|
||||
|
@ -186,6 +186,9 @@ typedef struct _BURN_SLIPSTREAM_MSP
|
|||
{
|
||||
BURN_PACKAGE* pMspPackage;
|
||||
DWORD dwMsiChainedPatchIndex; // index into the Msi.rgChainedPatches
|
||||
|
||||
BOOTSTRAPPER_ACTION_STATE execute; // only valid during Plan.
|
||||
BOOTSTRAPPER_ACTION_STATE rollback; // only valid during Plan.
|
||||
} BURN_SLIPSTREAM_MSP;
|
||||
|
||||
typedef struct _BURN_PACKAGE_PAYLOAD
|
||||
|
|
|
@ -154,11 +154,15 @@ static void RemoveUnnecessaryActions(
|
|||
__in BURN_EXECUTE_ACTION* rgActions,
|
||||
__in DWORD cActions
|
||||
);
|
||||
static HRESULT FinalizeSlipstreamPatchActions(
|
||||
static void FinalizePatchActions(
|
||||
__in BOOL fExecute,
|
||||
__in BURN_EXECUTE_ACTION* rgActions,
|
||||
__in DWORD cActions
|
||||
);
|
||||
static void CalculateExpectedRegistrationStates(
|
||||
__in BURN_PACKAGE* rgPackages,
|
||||
__in DWORD cPackages
|
||||
);
|
||||
static HRESULT PlanDependencyActions(
|
||||
__in BOOL fBundlePerMachine,
|
||||
__in BURN_PLAN* pPlan,
|
||||
|
@ -301,7 +305,6 @@ extern "C" void PlanUninitializeExecuteAction(
|
|||
case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE:
|
||||
ReleaseStr(pExecuteAction->msiPackage.sczLogPath);
|
||||
ReleaseMem(pExecuteAction->msiPackage.rgFeatures);
|
||||
ReleaseMem(pExecuteAction->msiPackage.rgSlipstreamPatches);
|
||||
break;
|
||||
|
||||
case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET:
|
||||
|
@ -823,6 +826,8 @@ static HRESULT PlanPackagesHelper(
|
|||
hr = PlanFinalizeActions(pPlan);
|
||||
ExitOnFailure(hr, "Failed to remove unnecessary actions from plan.");
|
||||
|
||||
CalculateExpectedRegistrationStates(rgPackages, cPackages);
|
||||
|
||||
// Let the BA know the actions that were planned.
|
||||
for (DWORD i = 0; i < cPackages; ++i)
|
||||
{
|
||||
|
@ -848,6 +853,12 @@ static HRESULT InitializePackage(
|
|||
BOOL fInstallCondition = FALSE;
|
||||
BOOL fBeginCalled = FALSE;
|
||||
|
||||
if (pPackage->fCanAffectRegistration)
|
||||
{
|
||||
pPackage->expectedCacheRegistrationState = pPackage->cacheRegistrationState;
|
||||
pPackage->expectedInstallRegistrationState = pPackage->installRegistrationState;
|
||||
}
|
||||
|
||||
if (pPackage->sczInstallCondition && *pPackage->sczInstallCondition)
|
||||
{
|
||||
hr = ConditionEvaluate(pVariables, pPackage->sczInstallCondition, &fInstallCondition);
|
||||
|
@ -903,68 +914,24 @@ static HRESULT ProcessPackage(
|
|||
hr = ProcessPackageRollbackBoundary(pPlan, pEffectiveRollbackBoundary, ppRollbackBoundary);
|
||||
ExitOnFailure(hr, "Failed to process package rollback boundary.");
|
||||
|
||||
if (pPackage->fCanAffectRegistration)
|
||||
if (BOOTSTRAPPER_ACTION_LAYOUT == pPlan->action)
|
||||
{
|
||||
pPackage->expectedCacheRegistrationState = pPackage->cacheRegistrationState;
|
||||
pPackage->expectedInstallRegistrationState = pPackage->installRegistrationState;
|
||||
hr = PlanLayoutPackage(pPlan, pPackage, wzLayoutDirectory);
|
||||
ExitOnFailure(hr, "Failed to plan layout package.");
|
||||
}
|
||||
|
||||
// If the package is in a requested state, plan it.
|
||||
if (BOOTSTRAPPER_REQUEST_STATE_NONE != pPackage->requested)
|
||||
else
|
||||
{
|
||||
if (BOOTSTRAPPER_ACTION_LAYOUT == pPlan->action)
|
||||
if (BOOTSTRAPPER_REQUEST_STATE_NONE != pPackage->requested)
|
||||
{
|
||||
hr = PlanLayoutPackage(pPlan, pPackage, wzLayoutDirectory);
|
||||
ExitOnFailure(hr, "Failed to plan layout package.");
|
||||
// If the package is in a requested state, plan it.
|
||||
hr = PlanExecutePackage(fBundlePerMachine, display, pUX, pPlan, pPackage, pLog, pVariables, phSyncpointEvent);
|
||||
ExitOnFailure(hr, "Failed to plan execute package.");
|
||||
}
|
||||
else
|
||||
{
|
||||
hr = PlanExecutePackage(fBundlePerMachine, display, pUX, pPlan, pPackage, pLog, pVariables, phSyncpointEvent);
|
||||
ExitOnFailure(hr, "Failed to plan execute package.");
|
||||
|
||||
if (pPackage->fCanAffectRegistration)
|
||||
{
|
||||
if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL < pPackage->execute)
|
||||
{
|
||||
pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
|
||||
}
|
||||
else if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pPackage->execute)
|
||||
{
|
||||
pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (BOOTSTRAPPER_ACTION_LAYOUT != pPlan->action)
|
||||
{
|
||||
// Make sure the package is properly ref-counted even if no plan is requested.
|
||||
hr = PlanDependencyActions(fBundlePerMachine, pPlan, pPackage);
|
||||
ExitOnFailure(hr, "Failed to plan dependency actions for package: %ls", pPackage->sczId);
|
||||
}
|
||||
|
||||
if (pPackage->fCanAffectRegistration)
|
||||
{
|
||||
if (BURN_DEPENDENCY_ACTION_REGISTER == pPackage->dependencyExecute)
|
||||
{
|
||||
if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pPackage->expectedCacheRegistrationState)
|
||||
{
|
||||
pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
|
||||
}
|
||||
if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pPackage->expectedInstallRegistrationState)
|
||||
{
|
||||
pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
|
||||
}
|
||||
}
|
||||
else if (BURN_DEPENDENCY_ACTION_UNREGISTER == pPackage->dependencyExecute)
|
||||
{
|
||||
if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->expectedCacheRegistrationState)
|
||||
{
|
||||
pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
|
||||
}
|
||||
if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->expectedInstallRegistrationState)
|
||||
{
|
||||
pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
|
||||
}
|
||||
// Make sure the package is properly ref-counted even if no plan is requested.
|
||||
hr = PlanDependencyActions(fBundlePerMachine, pPlan, pPackage);
|
||||
ExitOnFailure(hr, "Failed to plan dependency actions for package: %ls", pPackage->sczId);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1498,17 +1465,14 @@ extern "C" HRESULT PlanFinalizeActions(
|
|||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
FinalizePatchActions(TRUE, pPlan->rgExecuteActions, pPlan->cExecuteActions);
|
||||
|
||||
FinalizePatchActions(FALSE, pPlan->rgRollbackActions, pPlan->cRollbackActions);
|
||||
|
||||
RemoveUnnecessaryActions(TRUE, pPlan->rgExecuteActions, pPlan->cExecuteActions);
|
||||
|
||||
RemoveUnnecessaryActions(FALSE, pPlan->rgRollbackActions, pPlan->cRollbackActions);
|
||||
|
||||
hr = FinalizeSlipstreamPatchActions(TRUE, pPlan->rgExecuteActions, pPlan->cExecuteActions);
|
||||
ExitOnFailure(hr, "Failed to finalize slipstream execute actions.");
|
||||
|
||||
hr = FinalizeSlipstreamPatchActions(FALSE, pPlan->rgRollbackActions, pPlan->cRollbackActions);
|
||||
ExitOnFailure(hr, "Failed to finalize slipstream rollback actions.");
|
||||
|
||||
LExit:
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
@ -1868,7 +1832,7 @@ static void ResetPlannedPackageState(
|
|||
pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
|
||||
pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_UNKNOWN;
|
||||
|
||||
if (BURN_PACKAGE_TYPE_MSI == pPackage->type && pPackage->Msi.rgFeatures)
|
||||
if (BURN_PACKAGE_TYPE_MSI == pPackage->type)
|
||||
{
|
||||
for (DWORD i = 0; i < pPackage->Msi.cFeatures; ++i)
|
||||
{
|
||||
|
@ -1880,6 +1844,14 @@ static void ResetPlannedPackageState(
|
|||
pFeature->execute = BOOTSTRAPPER_FEATURE_ACTION_NONE;
|
||||
pFeature->rollback = BOOTSTRAPPER_FEATURE_ACTION_NONE;
|
||||
}
|
||||
|
||||
for (DWORD i = 0; i < pPackage->Msi.cSlipstreamMspPackages; ++i)
|
||||
{
|
||||
BURN_SLIPSTREAM_MSP* pSlipstreamMsp = &pPackage->Msi.rgSlipstreamMsps[i];
|
||||
|
||||
pSlipstreamMsp->execute = BOOTSTRAPPER_ACTION_STATE_NONE;
|
||||
pSlipstreamMsp->rollback = BOOTSTRAPPER_ACTION_STATE_NONE;
|
||||
}
|
||||
}
|
||||
else if (BURN_PACKAGE_TYPE_MSP == pPackage->type && pPackage->Msp.rgTargetProducts)
|
||||
{
|
||||
|
@ -2716,47 +2688,91 @@ static void RemoveUnnecessaryActions(
|
|||
{
|
||||
BURN_EXECUTE_ACTION* pAction = rgActions + i;
|
||||
|
||||
// If this MSP targets a package in the chain, check the target's execute state
|
||||
// to see if this patch should be skipped.
|
||||
if (BURN_EXECUTE_ACTION_TYPE_MSP_TARGET == pAction->type && pAction->mspTarget.pChainedTargetPackage)
|
||||
{
|
||||
BURN_MSPTARGETPRODUCT* pFirstTargetProduct = pAction->mspTarget.rgOrderedPatches->pTargetProduct;
|
||||
BURN_PATCH_SKIP_STATE skipState = fExecute ? pFirstTargetProduct->executeSkip : pFirstTargetProduct->rollbackSkip;
|
||||
BOOTSTRAPPER_ACTION_STATE chainedTargetPackageAction = fExecute ? pAction->mspTarget.pChainedTargetPackage->execute : pAction->mspTarget.pChainedTargetPackage->rollback;
|
||||
BURN_PATCH_SKIP_STATE skipState = BURN_PATCH_SKIP_STATE_NONE;
|
||||
if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == chainedTargetPackageAction)
|
||||
|
||||
switch (skipState)
|
||||
{
|
||||
skipState = BURN_PATCH_SKIP_STATE_TARGET_UNINSTALL;
|
||||
case BURN_PATCH_SKIP_STATE_TARGET_UNINSTALL:
|
||||
pAction->fDeleted = TRUE;
|
||||
LogId(REPORT_STANDARD, MSG_PLAN_SKIP_PATCH_ACTION, pAction->mspTarget.pPackage->sczId, LoggingActionStateToString(pAction->mspTarget.action), pAction->mspTarget.pChainedTargetPackage->sczId, LoggingActionStateToString(chainedTargetPackageAction), szExecuteOrRollback);
|
||||
break;
|
||||
case BURN_PATCH_SKIP_STATE_SLIPSTREAM:
|
||||
pAction->fDeleted = TRUE;
|
||||
LogId(REPORT_STANDARD, MSG_PLAN_SKIP_SLIPSTREAM_ACTION, pAction->mspTarget.pPackage->sczId, LoggingActionStateToString(pAction->mspTarget.action), pAction->mspTarget.pChainedTargetPackage->sczId, LoggingActionStateToString(chainedTargetPackageAction), szExecuteOrRollback);
|
||||
break;
|
||||
}
|
||||
else if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL < chainedTargetPackageAction && pAction->mspTarget.fSlipstream && BOOTSTRAPPER_ACTION_STATE_UNINSTALL < pAction->mspTarget.action)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void FinalizePatchActions(
|
||||
__in BOOL fExecute,
|
||||
__in BURN_EXECUTE_ACTION* rgActions,
|
||||
__in DWORD cActions
|
||||
)
|
||||
{
|
||||
for (DWORD i = 0; i < cActions; ++i)
|
||||
{
|
||||
BURN_EXECUTE_ACTION* pAction = rgActions + i;
|
||||
|
||||
if (BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE == pAction->type)
|
||||
{
|
||||
BURN_PACKAGE* pPackage = pAction->msiPackage.pPackage;
|
||||
AssertSz(BOOTSTRAPPER_ACTION_STATE_NONE < pAction->msiPackage.action, "Planned execute MSI action to do nothing");
|
||||
|
||||
if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pAction->msiPackage.action)
|
||||
{
|
||||
// If we are uninstalling the MSI, we must skip all the patches.
|
||||
for (DWORD j = 0; j < pPackage->Msi.cChainedPatches; ++j)
|
||||
{
|
||||
BURN_CHAINED_PATCH* pChainedPatch = pPackage->Msi.rgChainedPatches + j;
|
||||
BURN_MSPTARGETPRODUCT* pTargetProduct = pChainedPatch->pMspPackage->Msp.rgTargetProducts + pChainedPatch->dwMspTargetProductIndex;
|
||||
|
||||
if (fExecute)
|
||||
{
|
||||
pTargetProduct->execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL;
|
||||
pTargetProduct->executeSkip = BURN_PATCH_SKIP_STATE_TARGET_UNINSTALL;
|
||||
}
|
||||
else
|
||||
{
|
||||
pTargetProduct->rollback = BOOTSTRAPPER_ACTION_STATE_UNINSTALL;
|
||||
pTargetProduct->rollbackSkip = BURN_PATCH_SKIP_STATE_TARGET_UNINSTALL;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the slipstream target is being installed or upgraded (not uninstalled or repaired) then we will slipstream so skip
|
||||
// this action to install the patch standalone. Also, if the slipstream target is being repaired and the patch is being
|
||||
// the patch's standalone action. Also, if the slipstream target is being repaired and the patch is being
|
||||
// repaired, skip this operation since it will be redundant.
|
||||
//
|
||||
// The primary goal here is to ensure that a slipstream patch that is yet not installed is installed even if the MSI
|
||||
// is already on the machine. The slipstream must be installed standalone if the MSI is being repaired.
|
||||
if (BOOTSTRAPPER_ACTION_STATE_REPAIR != chainedTargetPackageAction || BOOTSTRAPPER_ACTION_STATE_REPAIR == pAction->mspTarget.action)
|
||||
for (DWORD j = 0; j < pPackage->Msi.cSlipstreamMspPackages; ++j)
|
||||
{
|
||||
skipState = BURN_PATCH_SKIP_STATE_SLIPSTREAM;
|
||||
LogId(REPORT_STANDARD, MSG_PLAN_SKIP_SLIPSTREAM_ACTION, pAction->mspTarget.pPackage->sczId, LoggingActionStateToString(pAction->mspTarget.action), pAction->mspTarget.pChainedTargetPackage->sczId, LoggingActionStateToString(chainedTargetPackageAction), szExecuteOrRollback);
|
||||
}
|
||||
}
|
||||
BURN_SLIPSTREAM_MSP* pSlipstreamMsp = pPackage->Msi.rgSlipstreamMsps + j;
|
||||
BURN_CHAINED_PATCH* pChainedPatch = pPackage->Msi.rgChainedPatches + pSlipstreamMsp->dwMsiChainedPatchIndex;
|
||||
BURN_MSPTARGETPRODUCT* pTargetProduct = pSlipstreamMsp->pMspPackage->Msp.rgTargetProducts + pChainedPatch->dwMspTargetProductIndex;
|
||||
BOOTSTRAPPER_ACTION_STATE action = fExecute ? pTargetProduct->execute : pTargetProduct->rollback;
|
||||
BOOL fSlipstream = BOOTSTRAPPER_ACTION_STATE_UNINSTALL < action &&
|
||||
(BOOTSTRAPPER_ACTION_STATE_REPAIR != pAction->msiPackage.action || BOOTSTRAPPER_ACTION_STATE_REPAIR == action);
|
||||
|
||||
if (BURN_PATCH_SKIP_STATE_NONE != skipState)
|
||||
{
|
||||
pAction->fDeleted = TRUE;
|
||||
|
||||
for (DWORD j = 0; j < pAction->mspTarget.cOrderedPatches; ++j)
|
||||
{
|
||||
BURN_MSPTARGETPRODUCT* pTargetProduct = pAction->mspTarget.rgOrderedPatches[j].pTargetProduct;
|
||||
|
||||
if (fExecute)
|
||||
if (fSlipstream)
|
||||
{
|
||||
pTargetProduct->executeSkip = skipState;
|
||||
}
|
||||
else
|
||||
{
|
||||
pTargetProduct->rollbackSkip = skipState;
|
||||
if (fExecute)
|
||||
{
|
||||
pSlipstreamMsp->execute = action;
|
||||
pTargetProduct->executeSkip = BURN_PATCH_SKIP_STATE_SLIPSTREAM;
|
||||
}
|
||||
else
|
||||
{
|
||||
pSlipstreamMsp->rollback = action;
|
||||
pTargetProduct->rollbackSkip = BURN_PATCH_SKIP_STATE_SLIPSTREAM;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2764,53 +2780,73 @@ static void RemoveUnnecessaryActions(
|
|||
}
|
||||
}
|
||||
|
||||
static HRESULT FinalizeSlipstreamPatchActions(
|
||||
__in BOOL fExecute,
|
||||
__in BURN_EXECUTE_ACTION* rgActions,
|
||||
__in DWORD cActions
|
||||
static void CalculateExpectedRegistrationStates(
|
||||
__in BURN_PACKAGE* rgPackages,
|
||||
__in DWORD cPackages
|
||||
)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
for (DWORD i = 0; i < cActions; ++i)
|
||||
for (DWORD i = 0; i < cPackages; ++i)
|
||||
{
|
||||
BURN_EXECUTE_ACTION* pAction = rgActions + i;
|
||||
BURN_PACKAGE* pPackage = rgPackages + i;
|
||||
|
||||
// If this MSI package contains slipstream patches store the slipstream actions.
|
||||
if (BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE == pAction->type && pAction->msiPackage.pPackage->Msi.cSlipstreamMspPackages)
|
||||
// MspPackages can have actions throughout the plan, so the plan needed to be finalized before anything could be calculated.
|
||||
if (BURN_PACKAGE_TYPE_MSP == pPackage->type && !pPackage->fDependencyManagerWasHere)
|
||||
{
|
||||
BURN_PACKAGE* pPackage = pAction->msiPackage.pPackage;
|
||||
pPackage->execute = BOOTSTRAPPER_ACTION_STATE_NONE;
|
||||
pPackage->rollback = BOOTSTRAPPER_ACTION_STATE_NONE;
|
||||
|
||||
// By default all slipstream actions will be initialized to "no action" (aka: 0).
|
||||
pAction->msiPackage.rgSlipstreamPatches = (BOOTSTRAPPER_ACTION_STATE*)MemAlloc(sizeof(BOOTSTRAPPER_ACTION_STATE) * pPackage->Msi.cSlipstreamMspPackages, TRUE);
|
||||
ExitOnNull(pAction->msiPackage.rgSlipstreamPatches, hr, E_OUTOFMEMORY, "Failed to allocate memory for patch actions.");
|
||||
|
||||
// If we are uninstalling or repairing the MSI, we must ignore all the slipstream patches because they cannot
|
||||
// be applied right now.
|
||||
if (BOOTSTRAPPER_ACTION_STATE_REPAIR != pAction->msiPackage.action && BOOTSTRAPPER_ACTION_STATE_UNINSTALL != pAction->msiPackage.action)
|
||||
for (DWORD j = 0; j < pPackage->Msp.cTargetProductCodes; ++j)
|
||||
{
|
||||
for (DWORD j = 0; j < pPackage->Msi.cSlipstreamMspPackages; ++j)
|
||||
{
|
||||
BURN_PACKAGE* pMspPackage = pPackage->Msi.rgSlipstreamMsps[j].pMspPackage;
|
||||
AssertSz(BURN_PACKAGE_TYPE_MSP == pMspPackage->type, "Only MSP packages can be slipstream patches.");
|
||||
BURN_MSPTARGETPRODUCT* pTargetProduct = pPackage->Msp.rgTargetProducts + j;
|
||||
|
||||
pAction->msiPackage.rgSlipstreamPatches[j] = fExecute ? pMspPackage->execute : pMspPackage->rollback;
|
||||
for (DWORD k = 0; k < pMspPackage->Msp.cTargetProductCodes; ++k)
|
||||
{
|
||||
BURN_MSPTARGETPRODUCT* pTargetProduct = pMspPackage->Msp.rgTargetProducts + k;
|
||||
if (pPackage == pTargetProduct->pChainedTargetPackage)
|
||||
{
|
||||
pAction->msiPackage.rgSlipstreamPatches[j] = fExecute ? pTargetProduct->execute : pTargetProduct->rollback;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// The highest aggregate action state found will be used.
|
||||
if (pPackage->execute < pTargetProduct->execute)
|
||||
{
|
||||
pPackage->execute = pTargetProduct->execute;
|
||||
}
|
||||
|
||||
if (pPackage->rollback < pTargetProduct->rollback)
|
||||
{
|
||||
pPackage->rollback = pTargetProduct->rollback;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pPackage->fCanAffectRegistration)
|
||||
{
|
||||
if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL < pPackage->execute)
|
||||
{
|
||||
pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
|
||||
}
|
||||
else if (BOOTSTRAPPER_ACTION_STATE_UNINSTALL == pPackage->execute)
|
||||
{
|
||||
pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_ABSENT;
|
||||
}
|
||||
|
||||
if (BURN_DEPENDENCY_ACTION_REGISTER == pPackage->dependencyExecute)
|
||||
{
|
||||
if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pPackage->expectedCacheRegistrationState)
|
||||
{
|
||||
pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
|
||||
}
|
||||
if (BURN_PACKAGE_REGISTRATION_STATE_IGNORED == pPackage->expectedInstallRegistrationState)
|
||||
{
|
||||
pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_PRESENT;
|
||||
}
|
||||
}
|
||||
else if (BURN_DEPENDENCY_ACTION_UNREGISTER == pPackage->dependencyExecute)
|
||||
{
|
||||
if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->expectedCacheRegistrationState)
|
||||
{
|
||||
pPackage->expectedCacheRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
|
||||
}
|
||||
if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->expectedInstallRegistrationState)
|
||||
{
|
||||
pPackage->expectedInstallRegistrationState = BURN_PACKAGE_REGISTRATION_STATE_IGNORED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LExit:
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT PlanDependencyActions(
|
||||
|
@ -3064,6 +3100,11 @@ static void ExecuteActionLog(
|
|||
|
||||
case BURN_EXECUTE_ACTION_TYPE_MSI_PACKAGE:
|
||||
LogStringLine(PlanDumpLevel, "%ls action[%u]: MSI_PACKAGE package id: %ls, action: %hs, action msi property: %ls, ui level: %u, disable externaluihandler: %ls, log path: %ls, logging attrib: %u", wzBase, iAction, pAction->msiPackage.pPackage->sczId, LoggingActionStateToString(pAction->msiPackage.action), LoggingBurnMsiPropertyToString(pAction->msiPackage.actionMsiProperty), pAction->msiPackage.uiLevel, pAction->msiPackage.fDisableExternalUiHandler ? L"yes" : L"no", pAction->msiPackage.sczLogPath, pAction->msiPackage.dwLoggingAttributes);
|
||||
for (DWORD j = 0; j < pAction->msiPackage.pPackage->Msi.cSlipstreamMspPackages; ++j)
|
||||
{
|
||||
const BURN_SLIPSTREAM_MSP* pSlipstreamMsp = pAction->msiPackage.pPackage->Msi.rgSlipstreamMsps + j;
|
||||
LogStringLine(PlanDumpLevel, " Patch[%u]: msp package id: %ls, action: %hs", j, pSlipstreamMsp->pMspPackage->sczId, LoggingActionStateToString(fRollback ? pSlipstreamMsp->rollback : pSlipstreamMsp->execute));
|
||||
}
|
||||
break;
|
||||
|
||||
case BURN_EXECUTE_ACTION_TYPE_MSP_TARGET:
|
||||
|
|
|
@ -253,7 +253,6 @@ typedef struct _BURN_EXECUTE_ACTION
|
|||
BOOTSTRAPPER_ACTION_STATE action;
|
||||
|
||||
BOOTSTRAPPER_FEATURE_ACTION* rgFeatures;
|
||||
BOOTSTRAPPER_ACTION_STATE* rgSlipstreamPatches;
|
||||
} msiPackage;
|
||||
struct
|
||||
{
|
||||
|
|
|
@ -760,7 +760,7 @@ namespace Bootstrapper
|
|||
Assert::Equal(3ul, pEngineState->packages.cPackages);
|
||||
ValidatePermanentPackageExpectedStates(&pEngineState->packages.rgPackages[0], L"NetFx48Web");
|
||||
ValidateNonPermanentPackageExpectedStates(&pEngineState->packages.rgPackages[1], L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, BURN_PACKAGE_REGISTRATION_STATE_PRESENT);
|
||||
ValidateNonPermanentPackageExpectedStates(&pEngineState->packages.rgPackages[2], L"PatchA", BURN_PACKAGE_REGISTRATION_STATE_ABSENT, BURN_PACKAGE_REGISTRATION_STATE_PRESENT);
|
||||
ValidateNonPermanentPackageExpectedStates(&pEngineState->packages.rgPackages[2], L"PatchA", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, BURN_PACKAGE_REGISTRATION_STATE_PRESENT);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
|
|
Загрузка…
Ссылка в новой задаче