From 5ed5a24fae06b35351235d708b6ab410d8310d33 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Sun, 16 Jan 2022 16:35:36 -0600 Subject: Add BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT. Make BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT uninstall even if detected absent. Remove fPseudoBundle. --- .../inc/BootstrapperEngine.h | 1 + .../WixToolset.Mba.Core/IBootstrapperEngine.cs | 5 + src/burn/engine/bundlepackageengine.cpp | 11 +- src/burn/engine/exeengine.cpp | 11 +- src/burn/engine/logging.cpp | 2 + src/burn/engine/msiengine.cpp | 36 ++-- src/burn/engine/mspengine.cpp | 29 +++- src/burn/engine/msuengine.cpp | 10 ++ src/burn/engine/package.h | 3 +- src/burn/engine/plan.cpp | 58 ++++--- src/burn/engine/pseudobundle.cpp | 5 +- src/burn/test/BurnUnitTest/PlanTest.cpp | 183 ++++++++++++++++++++- 12 files changed, 308 insertions(+), 46 deletions(-) (limited to 'src') diff --git a/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h b/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h index 56405685..d45c7b2a 100644 --- a/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h +++ b/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h @@ -57,6 +57,7 @@ enum BOOTSTRAPPER_REQUEST_STATE BOOTSTRAPPER_REQUEST_STATE_ABSENT, BOOTSTRAPPER_REQUEST_STATE_CACHE, BOOTSTRAPPER_REQUEST_STATE_PRESENT, + BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT, BOOTSTRAPPER_REQUEST_STATE_REPAIR, }; diff --git a/src/api/burn/WixToolset.Mba.Core/IBootstrapperEngine.cs b/src/api/burn/WixToolset.Mba.Core/IBootstrapperEngine.cs index 681c6f2c..8ead0919 100644 --- a/src/api/burn/WixToolset.Mba.Core/IBootstrapperEngine.cs +++ b/src/api/burn/WixToolset.Mba.Core/IBootstrapperEngine.cs @@ -487,6 +487,11 @@ namespace WixToolset.Mba.Core /// Present, + /// + /// + /// + ForcePresent, + /// /// /// diff --git a/src/burn/engine/bundlepackageengine.cpp b/src/burn/engine/bundlepackageengine.cpp index ece0fc3a..cd84601f 100644 --- a/src/burn/engine/bundlepackageengine.cpp +++ b/src/burn/engine/bundlepackageengine.cpp @@ -48,7 +48,7 @@ extern "C" HRESULT BundlePackageEnginePlanCalculatePackage( switch (pPackage->requested) { case BOOTSTRAPPER_REQUEST_STATE_PRESENT: - execute = pPackage->Bundle.fPseudoBundle ? BOOTSTRAPPER_ACTION_STATE_INSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; + execute = BOOTSTRAPPER_ACTION_STATE_NONE; break; case BOOTSTRAPPER_REQUEST_STATE_REPAIR: execute = pPackage->Bundle.fRepairable ? BOOTSTRAPPER_ACTION_STATE_REPAIR : BOOTSTRAPPER_ACTION_STATE_NONE; @@ -60,6 +60,9 @@ extern "C" HRESULT BundlePackageEnginePlanCalculatePackage( case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL; break; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: + execute = BOOTSTRAPPER_ACTION_STATE_INSTALL; + break; default: execute = BOOTSTRAPPER_ACTION_STATE_NONE; break; @@ -70,9 +73,13 @@ extern "C" HRESULT BundlePackageEnginePlanCalculatePackage( switch (pPackage->requested) { case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough; case BOOTSTRAPPER_REQUEST_STATE_REPAIR: execute = BOOTSTRAPPER_ACTION_STATE_INSTALL; break; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: + execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL; + break; default: execute = BOOTSTRAPPER_ACTION_STATE_NONE; break; @@ -93,6 +100,7 @@ extern "C" HRESULT BundlePackageEnginePlanCalculatePackage( switch (pPackage->requested) { case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough; case BOOTSTRAPPER_REQUEST_STATE_REPAIR: rollback = BOOTSTRAPPER_ACTION_STATE_NONE; break; @@ -110,6 +118,7 @@ extern "C" HRESULT BundlePackageEnginePlanCalculatePackage( switch (pPackage->requested) { case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough; case BOOTSTRAPPER_REQUEST_STATE_REPAIR: rollback = !pPackage->fPermanent ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; break; diff --git a/src/burn/engine/exeengine.cpp b/src/burn/engine/exeengine.cpp index cf10448f..b13650e5 100644 --- a/src/burn/engine/exeengine.cpp +++ b/src/burn/engine/exeengine.cpp @@ -165,7 +165,7 @@ extern "C" HRESULT ExeEnginePlanCalculatePackage( switch (pPackage->requested) { case BOOTSTRAPPER_REQUEST_STATE_PRESENT: - execute = pPackage->Exe.fPseudoBundle ? BOOTSTRAPPER_ACTION_STATE_INSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; + execute = BOOTSTRAPPER_ACTION_STATE_NONE; break; case BOOTSTRAPPER_REQUEST_STATE_REPAIR: execute = pPackage->Exe.fRepairable ? BOOTSTRAPPER_ACTION_STATE_REPAIR : BOOTSTRAPPER_ACTION_STATE_NONE; @@ -177,6 +177,9 @@ extern "C" HRESULT ExeEnginePlanCalculatePackage( case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: execute = pPackage->Exe.fUninstallable ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; break; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: + execute = BOOTSTRAPPER_ACTION_STATE_INSTALL; + break; default: execute = BOOTSTRAPPER_ACTION_STATE_NONE; break; @@ -187,9 +190,13 @@ extern "C" HRESULT ExeEnginePlanCalculatePackage( switch (pPackage->requested) { case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough; case BOOTSTRAPPER_REQUEST_STATE_REPAIR: execute = BOOTSTRAPPER_ACTION_STATE_INSTALL; break; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: + execute = pPackage->Exe.fUninstallable ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; + break; default: execute = BOOTSTRAPPER_ACTION_STATE_NONE; break; @@ -210,6 +217,7 @@ extern "C" HRESULT ExeEnginePlanCalculatePackage( switch (pPackage->requested) { case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough; case BOOTSTRAPPER_REQUEST_STATE_REPAIR: rollback = BOOTSTRAPPER_ACTION_STATE_NONE; break; @@ -227,6 +235,7 @@ extern "C" HRESULT ExeEnginePlanCalculatePackage( switch (pPackage->requested) { case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough; case BOOTSTRAPPER_REQUEST_STATE_REPAIR: rollback = !pPackage->fPermanent ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; break; diff --git a/src/burn/engine/logging.cpp b/src/burn/engine/logging.cpp index 7c048523..c5dd0ed8 100644 --- a/src/burn/engine/logging.cpp +++ b/src/burn/engine/logging.cpp @@ -779,6 +779,8 @@ extern "C" LPCSTR LoggingRequestStateToString( return "Cache"; case BOOTSTRAPPER_REQUEST_STATE_PRESENT: return "Present"; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: + return "ForcePresent"; case BOOTSTRAPPER_REQUEST_STATE_REPAIR: return "Repair"; default: diff --git a/src/burn/engine/msiengine.cpp b/src/burn/engine/msiengine.cpp index 9dd2312e..e3a80c9f 100644 --- a/src/burn/engine/msiengine.cpp +++ b/src/burn/engine/msiengine.cpp @@ -920,6 +920,10 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage( { execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL; } + else if (BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT == pPackage->requested) + { + execute = BOOTSTRAPPER_ACTION_STATE_INSTALL; + } else { execute = BOOTSTRAPPER_ACTION_STATE_NONE; @@ -931,10 +935,15 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage( switch (pPackage->requested) { case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough; case BOOTSTRAPPER_REQUEST_STATE_REPAIR: execute = BOOTSTRAPPER_ACTION_STATE_INSTALL; break; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: + execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL; + break; + default: execute = BOOTSTRAPPER_ACTION_STATE_NONE; break; @@ -958,6 +967,7 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage( case BOOTSTRAPPER_REQUEST_STATE_PRESENT: rollback = fRollbackFeatureActionDelta ? BOOTSTRAPPER_ACTION_STATE_MODIFY : BOOTSTRAPPER_ACTION_STATE_NONE; break; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough; case BOOTSTRAPPER_REQUEST_STATE_REPAIR: rollback = BOOTSTRAPPER_ACTION_STATE_NONE; break; @@ -972,11 +982,12 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage( break; case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: __fallthrough; - case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: __fallthrough; + case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: // If the package is not permanent and we requested to put the package on the machine then // remove the package during rollback. if (!pPackage->fPermanent && (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested || + BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT == pPackage->requested || BOOTSTRAPPER_REQUEST_STATE_REPAIR == pPackage->requested)) { rollback = BOOTSTRAPPER_ACTION_STATE_UNINSTALL; @@ -1040,6 +1051,18 @@ extern "C" HRESULT MsiEnginePlanAddPackage( hr = DependencyPlanPackage(NULL, pPackage, pPlan); ExitOnFailure(hr, "Failed to plan package dependency actions."); + if (pPackage->compatiblePackage.fRemove) + { + hr = PlanAppendExecuteAction(pPlan, &pAction); + ExitOnFailure(hr, "Failed to append execute action."); + + pAction->type = BURN_EXECUTE_ACTION_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE; + pAction->uninstallMsiCompatiblePackage.pParentPackage = pPackage; + pAction->uninstallMsiCompatiblePackage.dwLoggingAttributes = pLog->dwAttributes; + + LoggingSetCompatiblePackageVariable(pPackage, pLog, pVariables, &pAction->uninstallMsiCompatiblePackage.sczLogPath); // ignore errors. + } + // add rollback action if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->rollback) { @@ -1085,17 +1108,6 @@ extern "C" HRESULT MsiEnginePlanAddPackage( LoggingSetPackageVariable(pPackage, NULL, FALSE, pLog, pVariables, &pAction->msiPackage.sczLogPath); // ignore errors. pAction->msiPackage.dwLoggingAttributes = pLog->dwAttributes; } - else if (pPackage->compatiblePackage.fRemove) - { - hr = PlanAppendExecuteAction(pPlan, &pAction); - ExitOnFailure(hr, "Failed to append execute action."); - - pAction->type = BURN_EXECUTE_ACTION_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE; - pAction->uninstallMsiCompatiblePackage.pParentPackage = pPackage; - pAction->uninstallMsiCompatiblePackage.dwLoggingAttributes = pLog->dwAttributes; - - LoggingSetCompatiblePackageVariable(pPackage, pLog, pVariables, &pAction->uninstallMsiCompatiblePackage.sczLogPath); // ignore errors. - } LExit: ReleaseMem(rgFeatureActions); diff --git a/src/burn/engine/mspengine.cpp b/src/burn/engine/mspengine.cpp index bc6a482a..7403e78c 100644 --- a/src/burn/engine/mspengine.cpp +++ b/src/burn/engine/mspengine.cpp @@ -404,6 +404,11 @@ extern "C" HRESULT MspEnginePlanCalculatePackage( execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL; break; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: + execute = BOOTSTRAPPER_ACTION_STATE_INSTALL; + fWillUninstallAll = FALSE; + break; + default: execute = BOOTSTRAPPER_ACTION_STATE_NONE; fWillUninstallAll = FALSE; @@ -415,11 +420,16 @@ extern "C" HRESULT MspEnginePlanCalculatePackage( switch (pTargetProduct->requested) { case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough; case BOOTSTRAPPER_REQUEST_STATE_REPAIR: execute = BOOTSTRAPPER_ACTION_STATE_INSTALL; fWillUninstallAll = FALSE; break; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: + execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL; + break; + default: execute = BOOTSTRAPPER_ACTION_STATE_NONE; break; @@ -427,9 +437,25 @@ extern "C" HRESULT MspEnginePlanCalculatePackage( break; default: - if (pTargetProduct->fInstalled) + switch (pTargetProduct->requested) { + case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: + execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL; + break; + + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: + execute = BOOTSTRAPPER_ACTION_STATE_INSTALL; fWillUninstallAll = FALSE; + break; + + default: + execute = BOOTSTRAPPER_ACTION_STATE_NONE; + + if (pTargetProduct->fInstalled) + { + fWillUninstallAll = FALSE; + } + break; } break; } @@ -457,6 +483,7 @@ extern "C" HRESULT MspEnginePlanCalculatePackage( switch (pTargetProduct->requested) { case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough; case BOOTSTRAPPER_REQUEST_STATE_REPAIR: rollback = !pPackage->fPermanent ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; break; diff --git a/src/burn/engine/msuengine.cpp b/src/burn/engine/msuengine.cpp index 44386a6d..091bbe62 100644 --- a/src/burn/engine/msuengine.cpp +++ b/src/burn/engine/msuengine.cpp @@ -124,6 +124,10 @@ extern "C" HRESULT MsuEnginePlanCalculatePackage( execute = pPackage->Msu.fUninstallable ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; break; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: + execute = BOOTSTRAPPER_ACTION_STATE_INSTALL; + break; + default: execute = BOOTSTRAPPER_ACTION_STATE_NONE; break; @@ -134,10 +138,15 @@ extern "C" HRESULT MsuEnginePlanCalculatePackage( switch (pPackage->requested) { case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough; case BOOTSTRAPPER_REQUEST_STATE_REPAIR: execute = BOOTSTRAPPER_ACTION_STATE_INSTALL; break; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: + execute = pPackage->Msu.fUninstallable ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; + break; + default: execute = BOOTSTRAPPER_ACTION_STATE_NONE; break; @@ -172,6 +181,7 @@ extern "C" HRESULT MsuEnginePlanCalculatePackage( switch (pPackage->requested) { case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough; + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough; case BOOTSTRAPPER_REQUEST_STATE_REPAIR: rollback = !pPackage->fPermanent ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE; break; diff --git a/src/burn/engine/package.h b/src/burn/engine/package.h index bbd74ac9..eb812e20 100644 --- a/src/burn/engine/package.h +++ b/src/burn/engine/package.h @@ -303,7 +303,6 @@ typedef struct _BURN_PACKAGE LPCWSTR wzAncestors; // points directly into engine state. LPCWSTR wzEngineWorkingDirectory; // points directly into engine state. - BOOL fPseudoBundle; BOOL fRepairable; BOOL fSupportsBurnProtocol; @@ -320,7 +319,7 @@ typedef struct _BURN_PACKAGE LPWSTR sczRepairArguments; LPWSTR sczUninstallArguments; - BOOL fPseudoBundle; + BOOL fPseudoPackage; BOOL fFireAndForget; BOOL fRepairable; BOOL fUninstallable; diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp index b714aab8..2649ee39 100644 --- a/src/burn/engine/plan.cpp +++ b/src/burn/engine/plan.cpp @@ -9,6 +9,10 @@ // internal function definitions +static void PlannedExecutePackage( + __in BURN_PLAN* pPlan, + __in BURN_PACKAGE* pPackage + ); static void UninitializeRegistrationAction( __in BURN_DEPENDENT_REGISTRATION_ACTION* pAction ); @@ -855,13 +859,13 @@ static HRESULT InitializePackage( BOOL fBeginCalled = FALSE; BOOTSTRAPPER_RELATION_TYPE relationType = pPlan->pCommand->relationType; - if (BURN_PACKAGE_TYPE_EXE == pPackage->type && pPackage->Exe.fPseudoBundle) + if (BURN_PACKAGE_TYPE_EXE == pPackage->type && pPackage->Exe.fPseudoPackage) { - // Exe pseudo bundles are not configurable. + // Exe pseudo packages are not configurable. // The BA already requested this package to be executed // * by the overall plan action for UpdateReplace // * by enabling the forward compatible bundle for Passthrough - pPackage->defaultRequested = pPackage->requested = BOOTSTRAPPER_REQUEST_STATE_PRESENT; + pPackage->defaultRequested = pPackage->requested = BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT; ExitFunction(); } @@ -1164,18 +1168,15 @@ extern "C" HRESULT PlanExecutePackage( ExitOnFailure(hr, "Failed to complete plan dependency actions for package: %ls", pPackage->sczId); // If we are going to take any action on this package, add progress for it. - if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute || BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->rollback || pPackage->compatiblePackage.fRemove) + if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute || BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->rollback) { - LoggingIncrementPackageSequence(); - - ++pPlan->cExecutePackagesTotal; - ++pPlan->cOverallProgressTicksTotal; + PlannedExecutePackage(pPlan, pPackage); + } - // If package is per-machine and is being executed, flag the plan to be per-machine as well. - if (pPackage->fPerMachine) - { - pPlan->fPerMachine = TRUE; - } + // If we are going to take any action on the compatible package, add progress for it. + if (pPackage->compatiblePackage.fRemove) + { + PlannedExecutePackage(pPlan, pPackage); } LExit: @@ -1219,7 +1220,7 @@ extern "C" HRESULT PlanDefaultRelatedBundleRequestState( } else if (BOOTSTRAPPER_ACTION_INSTALL == action || BOOTSTRAPPER_ACTION_MODIFY == action) { - *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT; + *pRequestState = BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT; } else if (BOOTSTRAPPER_ACTION_REPAIR == action) { @@ -1478,16 +1479,7 @@ extern "C" HRESULT PlanRelatedBundlesComplete( // If we are going to take any action on this package, add progress for it. if (BOOTSTRAPPER_ACTION_STATE_NONE != pRelatedBundle->package.execute || BOOTSTRAPPER_ACTION_STATE_NONE != pRelatedBundle->package.rollback) { - LoggingIncrementPackageSequence(); - - ++pPlan->cExecutePackagesTotal; - ++pPlan->cOverallProgressTicksTotal; - } - - // If package is per-machine and is being executed, flag the plan to be per-machine as well. - if (pRelatedBundle->package.fPerMachine) - { - pPlan->fPerMachine = TRUE; + PlannedExecutePackage(pPlan, &pRelatedBundle->package); } } else if (BOOTSTRAPPER_RELATION_ADDON == pRelatedBundle->relationType || BOOTSTRAPPER_RELATION_PATCH == pRelatedBundle->relationType) @@ -1847,6 +1839,24 @@ LExit: // internal function definitions + +static void PlannedExecutePackage( + __in BURN_PLAN* pPlan, + __in BURN_PACKAGE* pPackage + ) +{ + LoggingIncrementPackageSequence(); + + ++pPlan->cExecutePackagesTotal; + ++pPlan->cOverallProgressTicksTotal; + + // If package is per-machine and is being executed, flag the plan to be per-machine as well. + if (pPackage->fPerMachine) + { + pPlan->fPerMachine = TRUE; + } +} + static void UninitializeRegistrationAction( __in BURN_DEPENDENT_REGISTRATION_ACTION* pAction ) diff --git a/src/burn/engine/pseudobundle.cpp b/src/burn/engine/pseudobundle.cpp index 153d76e6..94b095c5 100644 --- a/src/burn/engine/pseudobundle.cpp +++ b/src/burn/engine/pseudobundle.cpp @@ -51,7 +51,6 @@ extern "C" HRESULT PseudoBundleInitializeRelated( pPackage->fVital = FALSE; pPackage->fPermanent = FALSE; - pPackage->Bundle.fPseudoBundle = TRUE; pPackage->Bundle.fRepairable = TRUE; pPackage->Bundle.fSupportsBurnProtocol = fSupportsBurnProtocol; @@ -114,7 +113,7 @@ extern "C" HRESULT PseudoBundleInitializePassthrough( pPassthroughPackage->fVital = pPackage->fVital; pPassthroughPackage->fPermanent = TRUE; - pPassthroughPackage->Exe.fPseudoBundle = TRUE; + pPassthroughPackage->Exe.fPseudoPackage = TRUE; pPassthroughPackage->Exe.fUninstallable = FALSE; pPassthroughPackage->Exe.protocol = pPackage->Bundle.fSupportsBurnProtocol ? BURN_EXE_PROTOCOL_TYPE_BURN : BURN_EXE_PROTOCOL_TYPE_NONE; @@ -195,7 +194,7 @@ extern "C" HRESULT PseudoBundleInitializeUpdateBundle( // Trust the BA to only use UPDATE_REPLACE_EMBEDDED when appropriate. pPackage->Exe.protocol = BURN_EXE_PROTOCOL_TYPE_BURN; - pPackage->Exe.fPseudoBundle = TRUE; + pPackage->Exe.fPseudoPackage = TRUE; hr = StrAllocString(&pPackage->sczId, wzId, 0); ExitOnFailure(hr, "Failed to copy id for update bundle."); diff --git a/src/burn/test/BurnUnitTest/PlanTest.cpp b/src/burn/test/BurnUnitTest/PlanTest.cpp index 281c32e0..9d86b7cc 100644 --- a/src/burn/test/BurnUnitTest/PlanTest.cpp +++ b/src/burn/test/BurnUnitTest/PlanTest.cpp @@ -13,6 +13,11 @@ static LPCWSTR wzMsiTransactionManifestFileName = L"MsiTransaction_BundleAv1_man static LPCWSTR wzSingleMsiManifestFileName = L"BasicFunctionality_BundleA_manifest.xml"; static LPCWSTR wzSlipstreamManifestFileName = L"Slipstream_BundleA_manifest.xml"; +static BOOL vfUsePackageRequestState = FALSE; +static BOOTSTRAPPER_REQUEST_STATE vPackageRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; +static BOOL vfUseRelatedBundleRequestState = FALSE; +static BOOTSTRAPPER_REQUEST_STATE vRelatedBundleRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE; + namespace Microsoft { namespace Tools @@ -513,6 +518,158 @@ namespace Bootstrapper ValidateNonPermanentPackageExpectedStates(&pEngineState->packages.rgPackages[0], L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, BURN_PACKAGE_REGISTRATION_STATE_ABSENT); } + [Fact] + void SingleMsiForceAbsentTest() + { + HRESULT hr = S_OK; + BURN_ENGINE_STATE engineState = { }; + BURN_ENGINE_STATE* pEngineState = &engineState; + BURN_PLAN* pPlan = &engineState.plan; + + InitializeEngineStateForCorePlan(wzSingleMsiManifestFileName, pEngineState); + DetectAttachedContainerAsAttached(pEngineState); + DetectPackagesAsAbsent(pEngineState); + DetectUpgradeBundle(pEngineState, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", L"0.9.0.0"); + + vfUsePackageRequestState = TRUE; + vPackageRequestState = BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT; + vfUseRelatedBundleRequestState = TRUE; + vRelatedBundleRequestState = BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT; + + hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_UNINSTALL); + NativeAssert::Succeeded(hr, "CorePlan failed"); + + Assert::Equal(BOOTSTRAPPER_ACTION_UNINSTALL, pPlan->action); + Assert::Equal(TRUE, pPlan->fPerMachine); + Assert::Equal(FALSE, pPlan->fDisableRollback); + + BOOL fRollback = FALSE; + DWORD dwIndex = 0; + Assert::Equal(dwIndex, pPlan->cCacheActions); + + fRollback = TRUE; + dwIndex = 0; + Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); + + Assert::Equal(0ull, pPlan->qwEstimatedSize); + Assert::Equal(0ull, pPlan->qwCacheSizeTotal); + + fRollback = FALSE; + dwIndex = 0; + DWORD dwExecuteCheckpointId = 1; + ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", BURN_DEPENDENCY_ACTION_UNREGISTER); + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_UNREGISTER); + ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, BURN_MSI_PROPERTY_UNINSTALL, INSTALLUILEVEL_NONE, FALSE, BOOTSTRAPPER_MSI_FILE_VERSIONING_MISSING_OR_OLDER, 0); + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); + ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); + ValidateExecuteRelatedBundle(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, NULL); + Assert::Equal(dwIndex, pPlan->cExecuteActions); + + fRollback = TRUE; + dwIndex = 0; + dwExecuteCheckpointId = 1; + ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); + ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); + ValidateExecuteRelatedBundle(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL); + Assert::Equal(dwIndex, pPlan->cRollbackActions); + + Assert::Equal(2ul, pPlan->cExecutePackagesTotal); + Assert::Equal(2ul, pPlan->cOverallProgressTicksTotal); + + dwIndex = 0; + ValidateCleanAction(pPlan, dwIndex++, L"PackageA"); + Assert::Equal(dwIndex, pPlan->cCleanActions); + + UINT uIndex = 0; + ValidatePlannedProvider(pPlan, uIndex++, L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", NULL); + ValidatePlannedProvider(pPlan, uIndex++, L"{64633047-D172-4BBB-B202-64337D15C952}", NULL); + Assert::Equal(uIndex, pPlan->cPlannedProviders); + + Assert::Equal(1ul, pEngineState->packages.cPackages); + ValidateNonPermanentPackageExpectedStates(&pEngineState->packages.rgPackages[0], L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_ABSENT, BURN_PACKAGE_REGISTRATION_STATE_ABSENT); + } + + [Fact] + void SingleMsiForcePresentTest() + { + HRESULT hr = S_OK; + BURN_ENGINE_STATE engineState = { }; + BURN_ENGINE_STATE* pEngineState = &engineState; + BURN_PLAN* pPlan = &engineState.plan; + + InitializeEngineStateForCorePlan(wzSingleMsiManifestFileName, pEngineState); + DetectPackagesAsPresentAndCached(pEngineState); + DetectUpgradeBundle(pEngineState, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", L"0.9.0.0"); + + vfUsePackageRequestState = TRUE; + vPackageRequestState = BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT; + vfUseRelatedBundleRequestState = TRUE; + vRelatedBundleRequestState = BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT; + + hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_MODIFY); + NativeAssert::Succeeded(hr, "CorePlan failed"); + + Assert::Equal(BOOTSTRAPPER_ACTION_MODIFY, pPlan->action); + Assert::Equal(TRUE, pPlan->fPerMachine); + Assert::Equal(FALSE, pPlan->fDisableRollback); + + BOOL fRollback = FALSE; + DWORD dwIndex = 0; + ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1); + ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++); + Assert::Equal(dwIndex, pPlan->cCacheActions); + + fRollback = TRUE; + dwIndex = 0; + Assert::Equal(dwIndex, pPlan->cRollbackCacheActions); + + Assert::Equal(35694ull, pPlan->qwEstimatedSize); + Assert::Equal(175674ull, pPlan->qwCacheSizeTotal); + + fRollback = FALSE; + dwIndex = 0; + DWORD dwExecuteCheckpointId = 2; + ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA"); + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER); + ValidateExecuteMsiPackage(pPlan, fRollback, dwIndex++, L"PackageA", BOOTSTRAPPER_ACTION_STATE_INSTALL, BURN_MSI_PROPERTY_INSTALL, INSTALLUILEVEL_NONE, FALSE, BOOTSTRAPPER_MSI_FILE_VERSIONING_MISSING_OR_OLDER, 0); + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", BURN_DEPENDENCY_ACTION_REGISTER); + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); + ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); + ValidateExecuteRelatedBundle(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL); + Assert::Equal(dwIndex, pPlan->cExecuteActions); + + fRollback = TRUE; + dwIndex = 0; + dwExecuteCheckpointId = 2; + ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE); + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++); + ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++); + Assert::Equal(dwIndex, pPlan->cRollbackActions); + + Assert::Equal(2ul, pPlan->cExecutePackagesTotal); + Assert::Equal(3ul, pPlan->cOverallProgressTicksTotal); + + dwIndex = 0; + Assert::Equal(dwIndex, pPlan->cCleanActions); + + UINT uIndex = 0; + ValidatePlannedProvider(pPlan, uIndex++, L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", NULL); + Assert::Equal(uIndex, pPlan->cPlannedProviders); + + Assert::Equal(1ul, pEngineState->packages.cPackages); + ValidateNonPermanentPackageExpectedStates(&pEngineState->packages.rgPackages[0], L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, BURN_PACKAGE_REGISTRATION_STATE_PRESENT); + } + [Fact] void SingleMsiInstallTest() { @@ -1015,6 +1172,9 @@ namespace Bootstrapper HRESULT hr = S_OK; LPWSTR sczFilePath = NULL; + vfUsePackageRequestState = FALSE; + vfUseRelatedBundleRequestState = FALSE; + ::InitializeCriticalSection(&pEngineState->userExperience.csEngineActive); hr = CacheInitialize(&pEngineState->cache, &pEngineState->internalCommand); @@ -1046,6 +1206,7 @@ namespace Bootstrapper hr = CacheInitializeSources(&pEngineState->cache, &pEngineState->registration, &pEngineState->variables, &pEngineState->internalCommand); NativeAssert::Succeeded(hr, "Failed to initialize cache sources."); + pEngineState->userExperience.hUXModule = reinterpret_cast(1); pEngineState->userExperience.pfnBAProc = PlanTestBAProc; } @@ -1676,11 +1837,29 @@ namespace Bootstrapper } static HRESULT WINAPI PlanTestBAProc( - __in BOOTSTRAPPER_APPLICATION_MESSAGE /*message*/, + __in BOOTSTRAPPER_APPLICATION_MESSAGE message, __in const LPVOID /*pvArgs*/, - __inout LPVOID /*pvResults*/, + __inout LPVOID pvResults, __in_opt LPVOID /*pvContext*/ ) { + switch (message) + { + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGEBEGIN: + if (vfUsePackageRequestState) + { + BA_ONPLANPACKAGEBEGIN_RESULTS* pResults = reinterpret_cast(pvResults); + pResults->requestedState = vPackageRequestState; + } + break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRELATEDBUNDLE: + if (vfUseRelatedBundleRequestState) + { + BA_ONPLANRELATEDBUNDLE_RESULTS* pResults = reinterpret_cast(pvResults); + pResults->requestedState = vRelatedBundleRequestState; + } + break; + } + return S_OK; } -- cgit v1.2.3-55-g6feb