Add MEND request state to repair any missing files in MSI packages
Rob Mensching committed
Apr 13, 2021 at 00:09 UTC
6f7bb97daa1ae6bf2486b1c566c29e1b524b7548
4 files changed
+23
-6
src/WixToolset.BootstrapperCore.Native/inc/BootstrapperEngine.h
+2
@@ -37,6 +37,7 @@ enum BOOTSTRAPPER_ACTION_STATE
37
BOOTSTRAPPER_ACTION_STATE_UNINSTALL,
38
BOOTSTRAPPER_ACTION_STATE_INSTALL,
39
BOOTSTRAPPER_ACTION_STATE_MODIFY,
40
+ BOOTSTRAPPER_ACTION_STATE_MEND,
41
BOOTSTRAPPER_ACTION_STATE_REPAIR,
42
BOOTSTRAPPER_ACTION_STATE_MINOR_UPGRADE,
43
};
@@ -58,6 +59,7 @@ enum BOOTSTRAPPER_REQUEST_STATE
59
BOOTSTRAPPER_REQUEST_STATE_ABSENT,
60
BOOTSTRAPPER_REQUEST_STATE_CACHE,
61
BOOTSTRAPPER_REQUEST_STATE_PRESENT,
62
+ BOOTSTRAPPER_REQUEST_STATE_MEND,
63
BOOTSTRAPPER_REQUEST_STATE_REPAIR,
64
};
65
src/engine/dependency.cpp
+2
@@ -1025,6 +1025,7 @@ static void CalculateDependencyActionStates(
1025
}
1026
break;
1027
case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough;
1028
+ case BOOTSTRAPPER_REQUEST_STATE_MEND: __fallthrough;
1029
case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
1030
// Register if the package is requested but already installed.
1031
switch (pPackage->currentState)
@@ -1048,6 +1049,7 @@ static void CalculateDependencyActionStates(
1049
break;
1050
case BOOTSTRAPPER_ACTION_STATE_INSTALL: __fallthrough;
1051
case BOOTSTRAPPER_ACTION_STATE_MODIFY: __fallthrough;
1052
+ case BOOTSTRAPPER_ACTION_STATE_MEND: __fallthrough;
1053
case BOOTSTRAPPER_ACTION_STATE_REPAIR: __fallthrough;
1054
case BOOTSTRAPPER_ACTION_STATE_MINOR_UPGRADE: __fallthrough;
1055
*pDependencyExecuteAction = BURN_DEPENDENCY_ACTION_REGISTER;
src/engine/logging.cpp
+4
@@ -326,6 +326,8 @@ extern "C" LPCSTR LoggingActionStateToString(
326
return "Install";
327
case BOOTSTRAPPER_ACTION_STATE_MODIFY:
328
return "Modify";
329
+ case BOOTSTRAPPER_ACTION_STATE_MEND:
330
+ return "Mend";
331
case BOOTSTRAPPER_ACTION_STATE_REPAIR:
332
return "Repair";
333
case BOOTSTRAPPER_ACTION_STATE_MINOR_UPGRADE:
@@ -665,6 +667,8 @@ extern "C" LPCSTR LoggingRequestStateToString(
667
return "Cache";
668
case BOOTSTRAPPER_REQUEST_STATE_PRESENT:
669
return "Present";
670
+ case BOOTSTRAPPER_REQUEST_STATE_MEND:
671
+ return "Mend";
672
case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
673
return "Repair";
674
default:
src/engine/msiengine.cpp
+15
-6
@@ -789,7 +789,7 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
789
{
790
case BOOTSTRAPPER_PACKAGE_STATE_PRESENT: __fallthrough;
791
case BOOTSTRAPPER_PACKAGE_STATE_SUPERSEDED:
792
- if (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested || BOOTSTRAPPER_REQUEST_STATE_REPAIR == pPackage->requested)
792
+ if (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested || BOOTSTRAPPER_REQUEST_STATE_MEND == pPackage->requested || BOOTSTRAPPER_REQUEST_STATE_REPAIR == pPackage->requested)
793
{
794
hr = VerCompareParsedVersions(pVersion, pInstalledVersion, &nCompareResult);
795
ExitOnFailure(hr, "Failed to compare '%ls' to '%ls' for planning.", pVersion->sczVersion, pInstalledVersion->sczVersion);
@@ -801,6 +801,10 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
801
{
802
execute = BOOTSTRAPPER_ACTION_STATE_MINOR_UPGRADE;
803
}
804
+ else if (BOOTSTRAPPER_REQUEST_STATE_MEND == pPackage->requested)
805
+ {
806
+ execute = BOOTSTRAPPER_ACTION_STATE_MEND;
807
+ }
808
else if (BOOTSTRAPPER_REQUEST_STATE_REPAIR == pPackage->requested)
809
{
810
execute = BOOTSTRAPPER_ACTION_STATE_REPAIR;
@@ -829,6 +833,7 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
833
switch (pPackage->requested)
834
{
835
case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough;
836
+ case BOOTSTRAPPER_REQUEST_STATE_MEND: __fallthrough;
837
case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
838
execute = BOOTSTRAPPER_ACTION_STATE_INSTALL;
839
break;
@@ -844,6 +849,7 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
849
switch (pPackage->requested)
850
{
851
case BOOTSTRAPPER_REQUEST_STATE_PRESENT: __fallthrough;
852
+ case BOOTSTRAPPER_REQUEST_STATE_MEND: __fallthrough;
853
case BOOTSTRAPPER_REQUEST_STATE_REPAIR:
854
execute = BOOTSTRAPPER_ACTION_STATE_INSTALL;
855
break;
@@ -887,10 +893,12 @@ extern "C" HRESULT MsiEnginePlanCalculatePackage(
893
case BOOTSTRAPPER_PACKAGE_STATE_OBSOLETE: __fallthrough;
894
case BOOTSTRAPPER_PACKAGE_STATE_ABSENT: __fallthrough;
895
case BOOTSTRAPPER_PACKAGE_STATE_CACHED:
890
- // If we requested to put the package on the machine then remove the package during rollback
891
- // if the package is uninstallable.
892
- if ((BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested || BOOTSTRAPPER_REQUEST_STATE_REPAIR == pPackage->requested) &&
893
- pPackage->fUninstallable)
896
+ // If the package is uninstallable and we requested to put the package on the machine then
897
+ // remove the package during rollback.
898
+ if (pPackage->fUninstallable &&
899
+ (BOOTSTRAPPER_REQUEST_STATE_PRESENT == pPackage->requested ||
900
+ BOOTSTRAPPER_REQUEST_STATE_MEND == pPackage->requested ||
901
+ BOOTSTRAPPER_REQUEST_STATE_REPAIR == pPackage->requested))
902
{
903
rollback = BOOTSTRAPPER_ACTION_STATE_UNINSTALL;
904
}
@@ -1228,11 +1236,12 @@ extern "C" HRESULT MsiEngineExecutePackage(
1236
break;
1237
1238
case BOOTSTRAPPER_ACTION_STATE_MODIFY: __fallthrough;
1239
+ case BOOTSTRAPPER_ACTION_STATE_MEND: __fallthrough;
1240
case BOOTSTRAPPER_ACTION_STATE_REPAIR:
1241
{
1242
LPCWSTR wzReinstallAll = (BOOTSTRAPPER_ACTION_STATE_MODIFY == pExecuteAction->msiPackage.action ||
1243
pExecuteAction->msiPackage.pPackage->Msi.cFeatures) ? L"" : L" REINSTALL=ALL";
1235
- LPCWSTR wzReinstallMode = (BOOTSTRAPPER_ACTION_STATE_MODIFY == pExecuteAction->msiPackage.action) ? L"o" : L"e";
1244
+ LPCWSTR wzReinstallMode = (BOOTSTRAPPER_ACTION_STATE_MODIFY == pExecuteAction->msiPackage.action || BOOTSTRAPPER_ACTION_STATE_MEND == pExecuteAction->msiPackage.action) ? L"o" : L"e";
1245
1246
hr = StrAllocFormattedSecure(&sczProperties, L"%ls%ls REINSTALLMODE=\"cmus%ls\" REBOOT=ReallySuppress", sczProperties ? sczProperties : L"", wzReinstallAll, wzReinstallMode);
1247
ExitOnFailure(hr, "Failed to add reinstall mode and reboot suppression properties on repair.");