@joebigelow / wix / commits / f0e19e43

Don't uninstall superseded MSI packages.

7147

Sean Hall committed Jan 15, 2023 at 23:03 UTC f0e19e4355c29aa90e2b761031d61904ba1d8ffd
3 files changed +93 -5
src/burn/engine/msiengine.cpp
+3 -2
@@ -904,7 +904,7 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
904 else if ((BOOTSTRAPPER_REQUEST_STATE_ABSENT == pPackage->requested || BOOTSTRAPPER_REQUEST_STATE_CACHE == pPackage->requested) &&
905 !pPackage->fPermanent) // removing a package that should be removed.
906 {
907 - execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL;
907 + execute = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED == pPackage->currentState ? BOOTSTRAPPER_ACTION_STATE_NONE : BOOTSTRAPPER_ACTION_STATE_UNINSTALL;
908 }
909 else if (BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT == pPackage->requested)
910 {
@@ -968,9 +968,10 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
968 case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
969 rollback = BOOTSTRAPPER_ACTION_STATE_NONE;
970 break;
971 + case BOOTSTRAPPER_REQUEST_STATE_CACHE: __fallthrough;
972 case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT: __fallthrough;
973 case BOOTSTRAPPER_REQUEST_STATE_ABSENT:
973 - rollback = BOOTSTRAPPER_ACTION_STATE_INSTALL;
974 + rollback = BOOTSTRAPPER_ACTION_STATE_UNINSTALL == execute ? BOOTSTRAPPER_ACTION_STATE_INSTALL : BOOTSTRAPPER_ACTION_STATE_NONE;
975 break;
976 default:
977 rollback = BOOTSTRAPPER_ACTION_STATE_NONE;
src/burn/test/BurnUnitTest/PlanTest.cpp
+90 -2
@@ -2227,6 +2227,96 @@ namespace Bootstrapper
2227 ValidateNonPermanentPackageExpectedStates(&pEngineState->packages.rgPackages[0], L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_IGNORED, BURN_PACKAGE_REGISTRATION_STATE_IGNORED);
2228 }
2229
2230 + [Fact]
2231 + void SingleMsiUninstallTestFromUpgradeBundleWithMinorUpdatePackage()
2232 + {
2233 + HRESULT hr = S_OK;
2234 + BURN_ENGINE_STATE engineState = { };
2235 + BURN_ENGINE_STATE* pEngineState = &engineState;
2236 + BURN_PLAN* pPlan = &engineState.plan;
2237 +
2238 + InitializeEngineStateForCorePlan(wzSingleMsiManifestFileName, pEngineState);
2239 + DetectAsRelatedUpgradeBundle(&engineState, L"{02940F3E-C83E-452D-BFCF-C943777ACEAE}", L"2.0.0.0");
2240 + pEngineState->packages.rgPackages[0].currentState = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED;
2241 + pEngineState->packages.rgPackages[0].Msi.operation = BOOTSTRAPPER_RELATED_OPERATION_DOWNGRADE;
2242 +
2243 + hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_UNINSTALL);
2244 + NativeAssert::Succeeded(hr, "CorePlan failed");
2245 +
2246 + Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_UNINSTALL, pPlan->action);
2247 + NativeAssert::StringEqual(L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", pPlan->wzBundleId);
2248 + NativeAssert::StringEqual(L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", pPlan->wzBundleProviderKey);
2249 + Assert::Equal<BOOL>(FALSE, pPlan->fEnabledForwardCompatibleBundle);
2250 + Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
2251 + Assert::Equal<BOOL>(TRUE, pPlan->fCanAffectMachineState);
2252 + Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
2253 + Assert::Equal<BOOL>(FALSE, pPlan->fDisallowRemoval);
2254 + Assert::Equal<BOOL>(FALSE, pPlan->fDowngrade);
2255 + Assert::Equal<DWORD>(BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE | BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_PROVIDER_KEY, pPlan->dwRegistrationOperations);
2256 +
2257 + BOOL fRollback = FALSE;
2258 + DWORD dwIndex = 0;
2259 + ValidateDependentRegistrationAction(pPlan, fRollback, dwIndex++, FALSE, L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}");
2260 + Assert::Equal(dwIndex, pPlan->cRegistrationActions);
2261 +
2262 + fRollback = TRUE;
2263 + dwIndex = 0;
2264 + ValidateDependentRegistrationAction(pPlan, fRollback, dwIndex++, TRUE, L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}");
2265 + Assert::Equal(dwIndex, pPlan->cRollbackRegistrationActions);
2266 +
2267 + fRollback = FALSE;
2268 + dwIndex = 0;
2269 + Assert::Equal(dwIndex, pPlan->cCacheActions);
2270 +
2271 + fRollback = TRUE;
2272 + dwIndex = 0;
2273 + Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
2274 +
2275 + Assert::Equal(0ull, pPlan->qwCacheSizeTotal);
2276 +
2277 + fRollback = FALSE;
2278 + dwIndex = 0;
2279 + DWORD dwExecuteCheckpointId = 1;
2280 + ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
2281 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2282 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", unregisterActions1, 1);
2283 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2284 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", unregisterActions1, 1);
2285 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2286 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2287 + ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++);
2288 + Assert::Equal(dwIndex, pPlan->cExecuteActions);
2289 +
2290 + fRollback = TRUE;
2291 + dwIndex = 0;
2292 + dwExecuteCheckpointId = 1;
2293 + ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
2294 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", registerActions1, 1);
2295 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2296 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", registerActions1, 1);
2297 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2298 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2299 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
2300 + ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++);
2301 + Assert::Equal(dwIndex, pPlan->cRollbackActions);
2302 +
2303 + Assert::Equal(0ul, pPlan->cExecutePackagesTotal);
2304 + Assert::Equal(0ul, pPlan->cOverallProgressTicksTotal);
2305 +
2306 + dwIndex = 0;
2307 + Assert::Equal(dwIndex, pPlan->cRestoreRelatedBundleActions);
2308 +
2309 + dwIndex = 0;
2310 + Assert::Equal(dwIndex, pPlan->cCleanActions);
2311 +
2312 + UINT uIndex = 0;
2313 + ValidatePlannedProvider(pPlan, uIndex++, L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", NULL);
2314 + Assert::Equal(uIndex, pPlan->cPlannedProviders);
2315 +
2316 + Assert::Equal(1ul, pEngineState->packages.cPackages);
2317 + ValidateNonPermanentPackageExpectedStates(&pEngineState->packages.rgPackages[0], L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_IGNORED, BURN_PACKAGE_REGISTRATION_STATE_IGNORED);
2318 + }
2319 +
2320 [Fact]
2321 void SingleMsiUnsafeUninstallTest()
2322 {
@@ -3117,8 +3207,6 @@ namespace Bootstrapper
3207 {
3208 for (DWORD j = 0; j < pPackage->Msi.cSlipstreamMspPackages; ++j)
3209 {
3120 - pPackage->currentState = BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED;
3121 -
3210 BURN_PACKAGE* pMspPackage = pPackage->Msi.rgSlipstreamMsps[j].pMspPackage;
3211 MspEngineAddDetectedTargetProduct(&pEngineState->packages, pMspPackage, j, pPackage->Msi.sczProductCode, pPackage->fPerMachine ? MSIINSTALLCONTEXT_MACHINE : MSIINSTALLCONTEXT_USERUNMANAGED);
3212
src/test/burn/TestData/FeatureTests/PackageAv1/Package.wxs
-1
@@ -48,7 +48,6 @@
48 <Fragment>
49 <Component Id="RegistryComponent" Directory="INSTALLFOLDER">
50 <RegistryValue Root="HKLM" Key="Software\WiX\Tests\$(var.TestGroupName)" Name="$(var.PackageName)" Value="!(bind.Property.TestVersion)" Type="string" />
51 - <Provides Key="WiX.$(var.TestGroupName).A,v1.0" />
51 </Component>
52 </Fragment>
53