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
}