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