@joebigelow / wix / commits / 5ed5a24f

Add BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT.

Make BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT uninstall even if detected absent. Remove fPseudoBundle.

Sean Hall committed Jan 16, 2022 at 16:35 UTC 5ed5a24fae06b35351235d708b6ab410d8310d33
12 files changed +308 -46
src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h
+1
@@ -57,6 +57,7 @@ enum BOOTSTRAPPER_REQUEST_STATE
57 BOOTSTRAPPER_REQUEST_STATE_ABSENT,
58 BOOTSTRAPPER_REQUEST_STATE_CACHE,
59 BOOTSTRAPPER_REQUEST_STATE_PRESENT,
60 + BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT,
61 BOOTSTRAPPER_REQUEST_STATE_REPAIR,
62 };
63
src/api/burn/WixToolset.Mba.Core/IBootstrapperEngine.cs
+5
@@ -487,6 +487,11 @@ namespace WixToolset.Mba.Core
487 /// </summary>
488 Present,
489
490 + /// <summary>
491 + ///
492 + /// </summary>
493 + ForcePresent,
494 +
495 /// <summary>
496 ///
497 /// </summary>
src/burn/engine/bundlepackageengine.cpp
+10 -1
@@ -48,7 +48,7 @@ extern "C" HRESULT BundlePackageEnginePlanCalculatePackage(
48 switch (pPackage->requested)
49 {
50 case BOOTSTRAPPER_REQUEST_STATE_PRESENT:
51 - execute = pPackage->Bundle.fPseudoBundle ? BOOTSTRAPPER_ACTION_STATE_INSTALL : BOOTSTRAPPER_ACTION_STATE_NONE;
51 + execute = BOOTSTRAPPER_ACTION_STATE_NONE;
52 break;
53 case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
54 execute = pPackage->Bundle.fRepairable ? BOOTSTRAPPER_ACTION_STATE_REPAIR : BOOTSTRAPPER_ACTION_STATE_NONE;
@@ -60,6 +60,9 @@ extern "C" HRESULT BundlePackageEnginePlanCalculatePackage(
60 case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT:
61 execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL;
62 break;
63 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT:
64 + execute = BOOTSTRAPPER_ACTION_STATE_INSTALL;
65 + break;
66 default:
67 execute = BOOTSTRAPPER_ACTION_STATE_NONE;
68 break;
@@ -70,9 +73,13 @@ extern "C" HRESULT BundlePackageEnginePlanCalculatePackage(
73 switch (pPackage->requested)
74 {
75 case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough;
76 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough;
77 case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
78 execute = BOOTSTRAPPER_ACTION_STATE_INSTALL;
79 break;
80 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT:
81 + execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL;
82 + break;
83 default:
84 execute = BOOTSTRAPPER_ACTION_STATE_NONE;
85 break;
@@ -93,6 +100,7 @@ extern "C" HRESULT BundlePackageEnginePlanCalculatePackage(
100 switch (pPackage->requested)
101 {
102 case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough;
103 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough;
104 case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
105 rollback = BOOTSTRAPPER_ACTION_STATE_NONE;
106 break;
@@ -110,6 +118,7 @@ extern "C" HRESULT BundlePackageEnginePlanCalculatePackage(
118 switch (pPackage->requested)
119 {
120 case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough;
121 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough;
122 case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
123 rollback = !pPackage->fPermanent ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE;
124 break;
src/burn/engine/exeengine.cpp
+10 -1
@@ -165,7 +165,7 @@ extern "C" HRESULT ExeEnginePlanCalculatePackage(
165 switch (pPackage->requested)
166 {
167 case BOOTSTRAPPER_REQUEST_STATE_PRESENT:
168 - execute = pPackage->Exe.fPseudoBundle ? BOOTSTRAPPER_ACTION_STATE_INSTALL : BOOTSTRAPPER_ACTION_STATE_NONE;
168 + execute = BOOTSTRAPPER_ACTION_STATE_NONE;
169 break;
170 case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
171 execute = pPackage->Exe.fRepairable ? BOOTSTRAPPER_ACTION_STATE_REPAIR : BOOTSTRAPPER_ACTION_STATE_NONE;
@@ -177,6 +177,9 @@ extern "C" HRESULT ExeEnginePlanCalculatePackage(
177 case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT:
178 execute = pPackage->Exe.fUninstallable ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE;
179 break;
180 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT:
181 + execute = BOOTSTRAPPER_ACTION_STATE_INSTALL;
182 + break;
183 default:
184 execute = BOOTSTRAPPER_ACTION_STATE_NONE;
185 break;
@@ -187,9 +190,13 @@ extern "C" HRESULT ExeEnginePlanCalculatePackage(
190 switch (pPackage->requested)
191 {
192 case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough;
193 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough;
194 case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
195 execute = BOOTSTRAPPER_ACTION_STATE_INSTALL;
196 break;
197 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT:
198 + execute = pPackage->Exe.fUninstallable ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE;
199 + break;
200 default:
201 execute = BOOTSTRAPPER_ACTION_STATE_NONE;
202 break;
@@ -210,6 +217,7 @@ extern "C" HRESULT ExeEnginePlanCalculatePackage(
217 switch (pPackage->requested)
218 {
219 case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough;
220 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough;
221 case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
222 rollback = BOOTSTRAPPER_ACTION_STATE_NONE;
223 break;
@@ -227,6 +235,7 @@ extern "C" HRESULT ExeEnginePlanCalculatePackage(
235 switch (pPackage->requested)
236 {
237 case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough;
238 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough;
239 case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
240 rollback = !pPackage->fPermanent ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE;
241 break;
src/burn/engine/logging.cpp
+2
@@ -779,6 +779,8 @@ extern "C" LPCSTR LoggingRequestStateToString(
779 return "Cache";
780 case BOOTSTRAPPER_REQUEST_STATE_PRESENT:
781 return "Present";
782 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT:
783 + return "ForcePresent";
784 case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
785 return "Repair";
786 default:
src/burn/engine/msiengine.cpp
+24 -12
@@ -920,6 +920,10 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
920 {
921 execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL;
922 }
923 + else if (BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT == pPackage->requested)
924 + {
925 + execute = BOOTSTRAPPER_ACTION_STATE_INSTALL;
926 + }
927 else
928 {
929 execute = BOOTSTRAPPER_ACTION_STATE_NONE;
@@ -931,10 +935,15 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
935 switch (pPackage->requested)
936 {
937 case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough;
938 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough;
939 case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
940 execute = BOOTSTRAPPER_ACTION_STATE_INSTALL;
941 break;
942
943 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT:
944 + execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL;
945 + break;
946 +
947 default:
948 execute = BOOTSTRAPPER_ACTION_STATE_NONE;
949 break;
@@ -958,6 +967,7 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
967 case BOOTSTRAPPER_REQUEST_STATE_PRESENT:
968 rollback = fRollbackFeatureActionDelta ? BOOTSTRAPPER_ACTION_STATE_MODIFY : BOOTSTRAPPER_ACTION_STATE_NONE;
969 break;
970 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough;
971 case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
972 rollback = BOOTSTRAPPER_ACTION_STATE_NONE;
973 break;
@@ -972,11 +982,12 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
982 break;
983
984 case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: __fallthrough;
975 - case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: __fallthrough;
985 + case BOOTSTRAPPER_PACKAGE_STATE_ABSENT:
986 // If the package is not permanent and we requested to put the package on the machine then
987 // remove the package during rollback.
988 if (!pPackage->fPermanent &&
989 (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested ||
990 + BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT == pPackage->requested ||
991 BOOTSTRAPPER_REQUEST_STATE_REPAIR == pPackage->requested))
992 {
993 rollback = BOOTSTRAPPER_ACTION_STATE_UNINSTALL;
@@ -1040,6 +1051,18 @@ extern "C" HRESULT MsiEnginePlanAddPackage(
1051 hr = DependencyPlanPackage(NULL, pPackage, pPlan);
1052 ExitOnFailure(hr, "Failed to plan package dependency actions.");
1053
1054 + if (pPackage->compatiblePackage.fRemove)
1055 + {
1056 + hr = PlanAppendExecuteAction(pPlan, &pAction);
1057 + ExitOnFailure(hr, "Failed to append execute action.");
1058 +
1059 + pAction->type = BURN_EXECUTE_ACTION_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE;
1060 + pAction->uninstallMsiCompatiblePackage.pParentPackage = pPackage;
1061 + pAction->uninstallMsiCompatiblePackage.dwLoggingAttributes = pLog->dwAttributes;
1062 +
1063 + LoggingSetCompatiblePackageVariable(pPackage, pLog, pVariables, &pAction->uninstallMsiCompatiblePackage.sczLogPath); // ignore errors.
1064 + }
1065 +
1066 // add rollback action
1067 if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->rollback)
1068 {
@@ -1085,17 +1108,6 @@ extern "C" HRESULT MsiEnginePlanAddPackage(
1108 LoggingSetPackageVariable(pPackage, NULL, FALSE, pLog, pVariables, &pAction->msiPackage.sczLogPath); // ignore errors.
1109 pAction->msiPackage.dwLoggingAttributes = pLog->dwAttributes;
1110 }
1088 - else if (pPackage->compatiblePackage.fRemove)
1089 - {
1090 - hr = PlanAppendExecuteAction(pPlan, &pAction);
1091 - ExitOnFailure(hr, "Failed to append execute action.");
1092 -
1093 - pAction->type = BURN_EXECUTE_ACTION_TYPE_UNINSTALL_MSI_COMPATIBLE_PACKAGE;
1094 - pAction->uninstallMsiCompatiblePackage.pParentPackage = pPackage;
1095 - pAction->uninstallMsiCompatiblePackage.dwLoggingAttributes = pLog->dwAttributes;
1096 -
1097 - LoggingSetCompatiblePackageVariable(pPackage, pLog, pVariables, &pAction->uninstallMsiCompatiblePackage.sczLogPath); // ignore errors.
1098 - }
1111
1112 LExit:
1113 ReleaseMem(rgFeatureActions);
src/burn/engine/mspengine.cpp
+28 -1
@@ -404,6 +404,11 @@ extern "C" HRESULT MspEnginePlanCalculatePackage(
404 execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL;
405 break;
406
407 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT:
408 + execute = BOOTSTRAPPER_ACTION_STATE_INSTALL;
409 + fWillUninstallAll = FALSE;
410 + break;
411 +
412 default:
413 execute = BOOTSTRAPPER_ACTION_STATE_NONE;
414 fWillUninstallAll = FALSE;
@@ -415,11 +420,16 @@ extern "C" HRESULT MspEnginePlanCalculatePackage(
420 switch (pTargetProduct->requested)
421 {
422 case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough;
423 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough;
424 case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
425 execute = BOOTSTRAPPER_ACTION_STATE_INSTALL;
426 fWillUninstallAll = FALSE;
427 break;
428
429 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT:
430 + execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL;
431 + break;
432 +
433 default:
434 execute = BOOTSTRAPPER_ACTION_STATE_NONE;
435 break;
@@ -427,9 +437,25 @@ extern "C" HRESULT MspEnginePlanCalculatePackage(
437 break;
438
439 default:
430 - if (pTargetProduct->fInstalled)
440 + switch (pTargetProduct->requested)
441 {
442 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT:
443 + execute = BOOTSTRAPPER_ACTION_STATE_UNINSTALL;
444 + break;
445 +
446 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT:
447 + execute = BOOTSTRAPPER_ACTION_STATE_INSTALL;
448 fWillUninstallAll = FALSE;
449 + break;
450 +
451 + default:
452 + execute = BOOTSTRAPPER_ACTION_STATE_NONE;
453 +
454 + if (pTargetProduct->fInstalled)
455 + {
456 + fWillUninstallAll = FALSE;
457 + }
458 + break;
459 }
460 break;
461 }
@@ -457,6 +483,7 @@ extern "C" HRESULT MspEnginePlanCalculatePackage(
483 switch (pTargetProduct->requested)
484 {
485 case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough;
486 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough;
487 case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
488 rollback = !pPackage->fPermanent ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE;
489 break;
src/burn/engine/msuengine.cpp
+10
@@ -124,6 +124,10 @@ extern "C" HRESULT MsuEnginePlanCalculatePackage(
124 execute = pPackage->Msu.fUninstallable ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE;
125 break;
126
127 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT:
128 + execute = BOOTSTRAPPER_ACTION_STATE_INSTALL;
129 + break;
130 +
131 default:
132 execute = BOOTSTRAPPER_ACTION_STATE_NONE;
133 break;
@@ -134,10 +138,15 @@ extern "C" HRESULT MsuEnginePlanCalculatePackage(
138 switch (pPackage->requested)
139 {
140 case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough;
141 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough;
142 case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
143 execute = BOOTSTRAPPER_ACTION_STATE_INSTALL;
144 break;
145
146 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT:
147 + execute = pPackage->Msu.fUninstallable ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE;
148 + break;
149 +
150 default:
151 execute = BOOTSTRAPPER_ACTION_STATE_NONE;
152 break;
@@ -172,6 +181,7 @@ extern "C" HRESULT MsuEnginePlanCalculatePackage(
181 switch (pPackage->requested)
182 {
183 case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough;
184 + case BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT: __fallthrough;
185 case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
186 rollback = !pPackage->fPermanent ? BOOTSTRAPPER_ACTION_STATE_UNINSTALL : BOOTSTRAPPER_ACTION_STATE_NONE;
187 break;
src/burn/engine/package.h
+1 -2
@@ -303,7 +303,6 @@ typedef struct _BURN_PACKAGE
303 LPCWSTR wzAncestors; // points directly into engine state.
304 LPCWSTR wzEngineWorkingDirectory; // points directly into engine state.
305
306 - BOOL fPseudoBundle;
306 BOOL fRepairable;
307 BOOL fSupportsBurnProtocol;
308
@@ -320,7 +319,7 @@ typedef struct _BURN_PACKAGE
319 LPWSTR sczRepairArguments;
320 LPWSTR sczUninstallArguments;
321
323 - BOOL fPseudoBundle;
322 + BOOL fPseudoPackage;
323 BOOL fFireAndForget;
324 BOOL fRepairable;
325 BOOL fUninstallable;
src/burn/engine/plan.cpp
+34 -24
@@ -9,6 +9,10 @@
9
10 // internal function definitions
11
12 +static void PlannedExecutePackage(
13 + __in BURN_PLAN* pPlan,
14 + __in BURN_PACKAGE* pPackage
15 + );
16 static void UninitializeRegistrationAction(
17 __in BURN_DEPENDENT_REGISTRATION_ACTION* pAction
18 );
@@ -855,13 +859,13 @@ static HRESULT InitializePackage(
859 BOOL fBeginCalled = FALSE;
860 BOOTSTRAPPER_RELATION_TYPE relationType = pPlan->pCommand->relationType;
861
858 - if (BURN_PACKAGE_TYPE_EXE == pPackage->type && pPackage->Exe.fPseudoBundle)
862 + if (BURN_PACKAGE_TYPE_EXE == pPackage->type && pPackage->Exe.fPseudoPackage)
863 {
860 - // Exe pseudo bundles are not configurable.
864 + // Exe pseudo packages are not configurable.
865 // The BA already requested this package to be executed
866 // * by the overall plan action for UpdateReplace
867 // * by enabling the forward compatible bundle for Passthrough
864 - pPackage->defaultRequested = pPackage->requested = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
868 + pPackage->defaultRequested = pPackage->requested = BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT;
869 ExitFunction();
870 }
871
@@ -1164,18 +1168,15 @@ extern "C" HRESULT PlanExecutePackage(
1168 ExitOnFailure(hr, "Failed to complete plan dependency actions for package: %ls", pPackage->sczId);
1169
1170 // If we are going to take any action on this package, add progress for it.
1167 - if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute || BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->rollback || pPackage->compatiblePackage.fRemove)
1171 + if (BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->execute || BOOTSTRAPPER_ACTION_STATE_NONE != pPackage->rollback)
1172 {
1169 - LoggingIncrementPackageSequence();
1170 -
1171 - ++pPlan->cExecutePackagesTotal;
1172 - ++pPlan->cOverallProgressTicksTotal;
1173 + PlannedExecutePackage(pPlan, pPackage);
1174 + }
1175
1174 - // If package is per-machine and is being executed, flag the plan to be per-machine as well.
1175 - if (pPackage->fPerMachine)
1176 - {
1177 - pPlan->fPerMachine = TRUE;
1178 - }
1176 + // If we are going to take any action on the compatible package, add progress for it.
1177 + if (pPackage->compatiblePackage.fRemove)
1178 + {
1179 + PlannedExecutePackage(pPlan, pPackage);
1180 }
1181
1182 LExit:
@@ -1219,7 +1220,7 @@ extern "C" HRESULT PlanDefaultRelatedBundleRequestState(
1220 }
1221 else if (BOOTSTRAPPER_ACTION_INSTALL == action || BOOTSTRAPPER_ACTION_MODIFY == action)
1222 {
1222 - *pRequestState = BOOTSTRAPPER_REQUEST_STATE_PRESENT;
1223 + *pRequestState = BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT;
1224 }
1225 else if (BOOTSTRAPPER_ACTION_REPAIR == action)
1226 {
@@ -1478,16 +1479,7 @@ extern "C" HRESULT PlanRelatedBundlesComplete(
1479 // If we are going to take any action on this package, add progress for it.
1480 if (BOOTSTRAPPER_ACTION_STATE_NONE != pRelatedBundle->package.execute || BOOTSTRAPPER_ACTION_STATE_NONE != pRelatedBundle->package.rollback)
1481 {
1481 - LoggingIncrementPackageSequence();
1482 -
1483 - ++pPlan->cExecutePackagesTotal;
1484 - ++pPlan->cOverallProgressTicksTotal;
1485 - }
1486 -
1487 - // If package is per-machine and is being executed, flag the plan to be per-machine as well.
1488 - if (pRelatedBundle->package.fPerMachine)
1489 - {
1490 - pPlan->fPerMachine = TRUE;
1482 + PlannedExecutePackage(pPlan, &pRelatedBundle->package);
1483 }
1484 }
1485 else if (BOOTSTRAPPER_RELATION_ADDON == pRelatedBundle->relationType || BOOTSTRAPPER_RELATION_PATCH == pRelatedBundle->relationType)
@@ -1847,6 +1839,24 @@ LExit:
1839
1840 // internal function definitions
1841
1842 +
1843 +static void PlannedExecutePackage(
1844 + __in BURN_PLAN* pPlan,
1845 + __in BURN_PACKAGE* pPackage
1846 + )
1847 +{
1848 + LoggingIncrementPackageSequence();
1849 +
1850 + ++pPlan->cExecutePackagesTotal;
1851 + ++pPlan->cOverallProgressTicksTotal;
1852 +
1853 + // If package is per-machine and is being executed, flag the plan to be per-machine as well.
1854 + if (pPackage->fPerMachine)
1855 + {
1856 + pPlan->fPerMachine = TRUE;
1857 + }
1858 +}
1859 +
1860 static void UninitializeRegistrationAction(
1861 __in BURN_DEPENDENT_REGISTRATION_ACTION* pAction
1862 )
src/burn/engine/pseudobundle.cpp
+2 -3
@@ -51,7 +51,6 @@ extern "C" HRESULT PseudoBundleInitializeRelated(
51 pPackage->fVital = FALSE;
52
53 pPackage->fPermanent = FALSE;
54 - pPackage->Bundle.fPseudoBundle = TRUE;
54 pPackage->Bundle.fRepairable = TRUE;
55 pPackage->Bundle.fSupportsBurnProtocol = fSupportsBurnProtocol;
56
@@ -114,7 +113,7 @@ extern "C" HRESULT PseudoBundleInitializePassthrough(
113 pPassthroughPackage->fVital = pPackage->fVital;
114 pPassthroughPackage->fPermanent = TRUE;
115
117 - pPassthroughPackage->Exe.fPseudoBundle = TRUE;
116 + pPassthroughPackage->Exe.fPseudoPackage = TRUE;
117 pPassthroughPackage->Exe.fUninstallable = FALSE;
118 pPassthroughPackage->Exe.protocol = pPackage->Bundle.fSupportsBurnProtocol ? BURN_EXE_PROTOCOL_TYPE_BURN : BURN_EXE_PROTOCOL_TYPE_NONE;
119
@@ -195,7 +194,7 @@ extern "C" HRESULT PseudoBundleInitializeUpdateBundle(
194
195 // Trust the BA to only use UPDATE_REPLACE_EMBEDDED when appropriate.
196 pPackage->Exe.protocol = BURN_EXE_PROTOCOL_TYPE_BURN;
198 - pPackage->Exe.fPseudoBundle = TRUE;
197 + pPackage->Exe.fPseudoPackage = TRUE;
198
199 hr = StrAllocString(&pPackage->sczId, wzId, 0);
200 ExitOnFailure(hr, "Failed to copy id for update bundle.");
src/burn/test/BurnUnitTest/PlanTest.cpp
+181 -2
@@ -13,6 +13,11 @@ static LPCWSTR wzMsiTransactionManifestFileName = L"MsiTransaction_BundleAv1_man
13 static LPCWSTR wzSingleMsiManifestFileName = L"BasicFunctionality_BundleA_manifest.xml";
14 static LPCWSTR wzSlipstreamManifestFileName = L"Slipstream_BundleA_manifest.xml";
15
16 +static BOOL vfUsePackageRequestState = FALSE;
17 +static BOOTSTRAPPER_REQUEST_STATE vPackageRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
18 +static BOOL vfUseRelatedBundleRequestState = FALSE;
19 +static BOOTSTRAPPER_REQUEST_STATE vRelatedBundleRequestState = BOOTSTRAPPER_REQUEST_STATE_NONE;
20 +
21 namespace Microsoft
22 {
23 namespace Tools
@@ -513,6 +518,158 @@ namespace Bootstrapper
518 ValidateNonPermanentPackageExpectedStates(&pEngineState->packages.rgPackages[0], L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, BURN_PACKAGE_REGISTRATION_STATE_ABSENT);
519 }
520
521 + [Fact]
522 + void SingleMsiForceAbsentTest()
523 + {
524 + HRESULT hr = S_OK;
525 + BURN_ENGINE_STATE engineState = { };
526 + BURN_ENGINE_STATE* pEngineState = &engineState;
527 + BURN_PLAN* pPlan = &engineState.plan;
528 +
529 + InitializeEngineStateForCorePlan(wzSingleMsiManifestFileName, pEngineState);
530 + DetectAttachedContainerAsAttached(pEngineState);
531 + DetectPackagesAsAbsent(pEngineState);
532 + DetectUpgradeBundle(pEngineState, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", L"0.9.0.0");
533 +
534 + vfUsePackageRequestState = TRUE;
535 + vPackageRequestState = BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT;
536 + vfUseRelatedBundleRequestState = TRUE;
537 + vRelatedBundleRequestState = BOOTSTRAPPER_REQUEST_STATE_FORCE_ABSENT;
538 +
539 + hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_UNINSTALL);
540 + NativeAssert::Succeeded(hr, "CorePlan failed");
541 +
542 + Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_UNINSTALL, pPlan->action);
543 + Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
544 + Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
545 +
546 + BOOL fRollback = FALSE;
547 + DWORD dwIndex = 0;
548 + Assert::Equal(dwIndex, pPlan->cCacheActions);
549 +
550 + fRollback = TRUE;
551 + dwIndex = 0;
552 + Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
553 +
554 + Assert::Equal(0ull, pPlan->qwEstimatedSize);
555 + Assert::Equal(0ull, pPlan->qwCacheSizeTotal);
556 +
557 + fRollback = FALSE;
558 + dwIndex = 0;
559 + DWORD dwExecuteCheckpointId = 1;
560 + ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
561 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", BURN_DEPENDENCY_ACTION_UNREGISTER);
562 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_UNREGISTER);
563 + 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);
564 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
565 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
566 + ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++);
567 + ValidateExecuteRelatedBundle(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_UNINSTALL, NULL);
568 + Assert::Equal(dwIndex, pPlan->cExecuteActions);
569 +
570 + fRollback = TRUE;
571 + dwIndex = 0;
572 + dwExecuteCheckpointId = 1;
573 + ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
574 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
575 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
576 + ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++);
577 + ValidateExecuteRelatedBundle(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL);
578 + Assert::Equal(dwIndex, pPlan->cRollbackActions);
579 +
580 + Assert::Equal(2ul, pPlan->cExecutePackagesTotal);
581 + Assert::Equal(2ul, pPlan->cOverallProgressTicksTotal);
582 +
583 + dwIndex = 0;
584 + ValidateCleanAction(pPlan, dwIndex++, L"PackageA");
585 + Assert::Equal(dwIndex, pPlan->cCleanActions);
586 +
587 + UINT uIndex = 0;
588 + ValidatePlannedProvider(pPlan, uIndex++, L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", NULL);
589 + ValidatePlannedProvider(pPlan, uIndex++, L"{64633047-D172-4BBB-B202-64337D15C952}", NULL);
590 + Assert::Equal(uIndex, pPlan->cPlannedProviders);
591 +
592 + Assert::Equal(1ul, pEngineState->packages.cPackages);
593 + ValidateNonPermanentPackageExpectedStates(&pEngineState->packages.rgPackages[0], L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_ABSENT, BURN_PACKAGE_REGISTRATION_STATE_ABSENT);
594 + }
595 +
596 + [Fact]
597 + void SingleMsiForcePresentTest()
598 + {
599 + HRESULT hr = S_OK;
600 + BURN_ENGINE_STATE engineState = { };
601 + BURN_ENGINE_STATE* pEngineState = &engineState;
602 + BURN_PLAN* pPlan = &engineState.plan;
603 +
604 + InitializeEngineStateForCorePlan(wzSingleMsiManifestFileName, pEngineState);
605 + DetectPackagesAsPresentAndCached(pEngineState);
606 + DetectUpgradeBundle(pEngineState, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", L"0.9.0.0");
607 +
608 + vfUsePackageRequestState = TRUE;
609 + vPackageRequestState = BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT;
610 + vfUseRelatedBundleRequestState = TRUE;
611 + vRelatedBundleRequestState = BOOTSTRAPPER_REQUEST_STATE_FORCE_PRESENT;
612 +
613 + hr = CorePlan(pEngineState, BOOTSTRAPPER_ACTION_MODIFY);
614 + NativeAssert::Succeeded(hr, "CorePlan failed");
615 +
616 + Assert::Equal<DWORD>(BOOTSTRAPPER_ACTION_MODIFY, pPlan->action);
617 + Assert::Equal<BOOL>(TRUE, pPlan->fPerMachine);
618 + Assert::Equal<BOOL>(FALSE, pPlan->fDisableRollback);
619 +
620 + BOOL fRollback = FALSE;
621 + DWORD dwIndex = 0;
622 + ValidateCacheCheckpoint(pPlan, fRollback, dwIndex++, 1);
623 + ValidateCachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
624 + ValidateCacheSignalSyncpoint(pPlan, fRollback, dwIndex++);
625 + Assert::Equal(dwIndex, pPlan->cCacheActions);
626 +
627 + fRollback = TRUE;
628 + dwIndex = 0;
629 + Assert::Equal(dwIndex, pPlan->cRollbackCacheActions);
630 +
631 + Assert::Equal(35694ull, pPlan->qwEstimatedSize);
632 + Assert::Equal(175674ull, pPlan->qwCacheSizeTotal);
633 +
634 + fRollback = FALSE;
635 + dwIndex = 0;
636 + DWORD dwExecuteCheckpointId = 2;
637 + ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
638 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
639 + ValidateExecuteWaitCachePackage(pPlan, fRollback, dwIndex++, L"PackageA");
640 + ValidateExecutePackageProvider(pPlan, fRollback, dwIndex++, L"PackageA", BURN_DEPENDENCY_ACTION_REGISTER);
641 + 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);
642 + ValidateExecutePackageDependency(pPlan, fRollback, dwIndex++, L"PackageA", L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", BURN_DEPENDENCY_ACTION_REGISTER);
643 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
644 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
645 + ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++);
646 + ValidateExecuteRelatedBundle(pPlan, fRollback, dwIndex++, L"{FD9920AD-DBCA-4C6C-8CD5-B47431CE8D21}", BOOTSTRAPPER_ACTION_STATE_INSTALL, NULL);
647 + Assert::Equal(dwIndex, pPlan->cExecuteActions);
648 +
649 + fRollback = TRUE;
650 + dwIndex = 0;
651 + dwExecuteCheckpointId = 2;
652 + ValidateExecuteRollbackBoundaryStart(pPlan, fRollback, dwIndex++, L"WixDefaultBoundary", TRUE, FALSE);
653 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
654 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
655 + ValidateExecuteCheckpoint(pPlan, fRollback, dwIndex++, dwExecuteCheckpointId++);
656 + ValidateExecuteRollbackBoundaryEnd(pPlan, fRollback, dwIndex++);
657 + Assert::Equal(dwIndex, pPlan->cRollbackActions);
658 +
659 + Assert::Equal(2ul, pPlan->cExecutePackagesTotal);
660 + Assert::Equal(3ul, pPlan->cOverallProgressTicksTotal);
661 +
662 + dwIndex = 0;
663 + Assert::Equal(dwIndex, pPlan->cCleanActions);
664 +
665 + UINT uIndex = 0;
666 + ValidatePlannedProvider(pPlan, uIndex++, L"{A6F0CBF7-1578-450C-B9D7-9CF2EEC40002}", NULL);
667 + Assert::Equal(uIndex, pPlan->cPlannedProviders);
668 +
669 + Assert::Equal(1ul, pEngineState->packages.cPackages);
670 + ValidateNonPermanentPackageExpectedStates(&pEngineState->packages.rgPackages[0], L"PackageA", BURN_PACKAGE_REGISTRATION_STATE_PRESENT, BURN_PACKAGE_REGISTRATION_STATE_PRESENT);
671 + }
672 +
673 [Fact]
674 void SingleMsiInstallTest()
675 {
@@ -1015,6 +1172,9 @@ namespace Bootstrapper
1172 HRESULT hr = S_OK;
1173 LPWSTR sczFilePath = NULL;
1174
1175 + vfUsePackageRequestState = FALSE;
1176 + vfUseRelatedBundleRequestState = FALSE;
1177 +
1178 ::InitializeCriticalSection(&pEngineState->userExperience.csEngineActive);
1179
1180 hr = CacheInitialize(&pEngineState->cache, &pEngineState->internalCommand);
@@ -1046,6 +1206,7 @@ namespace Bootstrapper
1206 hr = CacheInitializeSources(&pEngineState->cache, &pEngineState->registration, &pEngineState->variables, &pEngineState->internalCommand);
1207 NativeAssert::Succeeded(hr, "Failed to initialize cache sources.");
1208
1209 + pEngineState->userExperience.hUXModule = reinterpret_cast<HMODULE>(1);
1210 pEngineState->userExperience.pfnBAProc = PlanTestBAProc;
1211 }
1212
@@ -1676,11 +1837,29 @@ namespace Bootstrapper
1837 }
1838
1839 static HRESULT WINAPI PlanTestBAProc(
1679 - __in BOOTSTRAPPER_APPLICATION_MESSAGE /*message*/,
1840 + __in BOOTSTRAPPER_APPLICATION_MESSAGE message,
1841 __in const LPVOID /*pvArgs*/,
1681 - __inout LPVOID /*pvResults*/,
1842 + __inout LPVOID pvResults,
1843 __in_opt LPVOID /*pvContext*/
1844 )
1845 {
1846 + switch (message)
1847 + {
1848 + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANPACKAGEBEGIN:
1849 + if (vfUsePackageRequestState)
1850 + {
1851 + BA_ONPLANPACKAGEBEGIN_RESULTS* pResults = reinterpret_cast<BA_ONPLANPACKAGEBEGIN_RESULTS*>(pvResults);
1852 + pResults->requestedState = vPackageRequestState;
1853 + }
1854 + break;
1855 + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANRELATEDBUNDLE:
1856 + if (vfUseRelatedBundleRequestState)
1857 + {
1858 + BA_ONPLANRELATEDBUNDLE_RESULTS* pResults = reinterpret_cast<BA_ONPLANRELATEDBUNDLE_RESULTS*>(pvResults);
1859 + pResults->requestedState = vRelatedBundleRequestState;
1860 + }
1861 + break;
1862 + }
1863 +
1864 return S_OK;
1865 }