summaryrefslogtreecommitdiff
path: root/src/burn/engine/core.cpp
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-08-03 15:42:08 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-08-04 10:03:57 -0500
commit94b8260fc5c1abc199f8d6145f3db4e2de490463 (patch)
treef8aeebc5b8d3facdab8232f60098ed253b3019cf /src/burn/engine/core.cpp
parent9ae1c04d5fa02ac020885cdad7c592f7bb43d83e (diff)
downloadwix-94b8260fc5c1abc199f8d6145f3db4e2de490463.tar.gz
wix-94b8260fc5c1abc199f8d6145f3db4e2de490463.tar.bz2
wix-94b8260fc5c1abc199f8d6145f3db4e2de490463.zip
Recreate the command line for the clean room process.
Persist /xlog when resuming from RunOnce. Fixes #6259
Diffstat (limited to 'src/burn/engine/core.cpp')
-rw-r--r--src/burn/engine/core.cpp263
1 files changed, 234 insertions, 29 deletions
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp
index ea7f34d1..d8e2454d 100644
--- a/src/burn/engine/core.cpp
+++ b/src/burn/engine/core.cpp
@@ -14,6 +14,19 @@ struct BURN_CACHE_THREAD_CONTEXT
14 14
15// internal function declarations 15// internal function declarations
16 16
17static HRESULT CoreRecreateCommandLine(
18 __deref_inout_z LPWSTR* psczCommandLine,
19 __in BOOTSTRAPPER_ACTION action,
20 __in BURN_ENGINE_COMMAND* pInternalCommand,
21 __in BOOTSTRAPPER_COMMAND* pCommand,
22 __in BOOTSTRAPPER_RELATION_TYPE relationType,
23 __in BOOL fPassthrough
24 );
25static HRESULT AppendLayoutToCommandLine(
26 __in BOOTSTRAPPER_ACTION action,
27 __in_z LPCWSTR wzLayoutDirectory,
28 __deref_inout_z LPWSTR* psczCommandLine
29 );
17static HRESULT GetSanitizedCommandLine( 30static HRESULT GetSanitizedCommandLine(
18 __in BURN_ENGINE_COMMAND* pInternalCommand, 31 __in BURN_ENGINE_COMMAND* pInternalCommand,
19 __in BOOTSTRAPPER_COMMAND* pCommand, 32 __in BOOTSTRAPPER_COMMAND* pCommand,
@@ -924,23 +937,19 @@ extern "C" LPCWSTR CoreRelationTypeToCommandLineString(
924 return wzRelationTypeCommandLine; 937 return wzRelationTypeCommandLine;
925} 938}
926 939
927extern "C" HRESULT CoreRecreateCommandLine( 940static HRESULT CoreRecreateCommandLine(
928 __deref_inout_z LPWSTR* psczCommandLine, 941 __deref_inout_z LPWSTR* psczCommandLine,
929 __in BOOTSTRAPPER_ACTION action, 942 __in BOOTSTRAPPER_ACTION action,
930 __in BURN_ENGINE_COMMAND* pInternalCommand, 943 __in BURN_ENGINE_COMMAND* pInternalCommand,
931 __in BOOTSTRAPPER_COMMAND* pCommand, 944 __in BOOTSTRAPPER_COMMAND* pCommand,
932 __in BOOTSTRAPPER_RELATION_TYPE relationType, 945 __in BOOTSTRAPPER_RELATION_TYPE relationType,
933 __in BOOL fPassthrough, 946 __in BOOL fPassthrough
934 __in_z_opt LPCWSTR wzAppendLogPath
935 ) 947 )
936{ 948{
937 HRESULT hr = S_OK; 949 HRESULT hr = S_OK;
938 LPWSTR scz = NULL; 950 LPWSTR scz = NULL;
939 LPCWSTR wzRelationTypeCommandLine = CoreRelationTypeToCommandLineString(relationType); 951 LPCWSTR wzRelationTypeCommandLine = CoreRelationTypeToCommandLineString(relationType);
940 952
941 hr = StrAllocString(psczCommandLine, L"", 0);
942 ExitOnFailure(hr, "Failed to empty command line.");
943
944 switch (pCommand->display) 953 switch (pCommand->display)
945 { 954 {
946 case BOOTSTRAPPER_DISPLAY_NONE: 955 case BOOTSTRAPPER_DISPLAY_NONE:
@@ -954,6 +963,9 @@ extern "C" HRESULT CoreRecreateCommandLine(
954 963
955 switch (action) 964 switch (action)
956 { 965 {
966 case BOOTSTRAPPER_ACTION_HELP:
967 hr = StrAllocConcat(psczCommandLine, L" /help", 0);
968 break;
957 case BOOTSTRAPPER_ACTION_MODIFY: 969 case BOOTSTRAPPER_ACTION_MODIFY:
958 hr = StrAllocConcat(psczCommandLine, L" /modify", 0); 970 hr = StrAllocConcat(psczCommandLine, L" /modify", 0);
959 break; 971 break;
@@ -985,52 +997,190 @@ extern "C" HRESULT CoreRecreateCommandLine(
985 997
986 if (pInternalCommand->sczAncestors) 998 if (pInternalCommand->sczAncestors)
987 { 999 {
988 hr = StrAllocFormatted(&scz, L" /%ls=%ls", BURN_COMMANDLINE_SWITCH_ANCESTORS, pInternalCommand->sczAncestors); 1000 hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls=%ls", BURN_COMMANDLINE_SWITCH_ANCESTORS, pInternalCommand->sczAncestors);
989 ExitOnFailure(hr, "Failed to format ancestors for command-line.");
990
991 hr = StrAllocConcat(psczCommandLine, scz, 0);
992 ExitOnFailure(hr, "Failed to append ancestors to command-line."); 1001 ExitOnFailure(hr, "Failed to append ancestors to command-line.");
993 } 1002 }
994 1003
995 if (wzRelationTypeCommandLine) 1004 if (wzRelationTypeCommandLine)
996 { 1005 {
997 hr = StrAllocFormatted(&scz, L" /%ls", wzRelationTypeCommandLine); 1006 hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls", wzRelationTypeCommandLine);
998 ExitOnFailure(hr, "Failed to format relation type for command-line.");
999
1000 hr = StrAllocConcat(psczCommandLine, scz, 0);
1001 ExitOnFailure(hr, "Failed to append relation type to command-line."); 1007 ExitOnFailure(hr, "Failed to append relation type to command-line.");
1002 } 1008 }
1003 1009
1004 if (fPassthrough) 1010 if (fPassthrough)
1005 { 1011 {
1006 hr = StrAllocFormatted(&scz, L" /%ls", BURN_COMMANDLINE_SWITCH_PASSTHROUGH); 1012 hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls", BURN_COMMANDLINE_SWITCH_PASSTHROUGH);
1007 ExitOnFailure(hr, "Failed to format passthrough for command-line.");
1008
1009 hr = StrAllocConcat(psczCommandLine, scz, 0);
1010 ExitOnFailure(hr, "Failed to append passthrough to command-line."); 1013 ExitOnFailure(hr, "Failed to append passthrough to command-line.");
1011 } 1014 }
1012 1015
1013 if (wzAppendLogPath && *wzAppendLogPath) 1016 if (pCommand->wzCommandLine && *pCommand->wzCommandLine)
1014 { 1017 {
1015 hr = StrAllocFormatted(&scz, L" /%ls \"%ls\"", BURN_COMMANDLINE_SWITCH_LOG_APPEND, wzAppendLogPath); 1018 hr = StrAllocConcatFormattedSecure(psczCommandLine, L" %ls", pCommand->wzCommandLine);
1016 ExitOnFailure(hr, "Failed to format append log command-line for command-line."); 1019 ExitOnFailure(hr, "Failed to append command-line to command-line.");
1020 }
1017 1021
1018 hr = StrAllocConcat(psczCommandLine, scz, 0); 1022LExit:
1019 ExitOnFailure(hr, "Failed to append log command-line to command-line"); 1023 ReleaseStr(scz);
1024
1025 return hr;
1026}
1027
1028extern "C" HRESULT CoreCreateCleanRoomCommandLine(
1029 __deref_inout_z LPWSTR* psczCommandLine,
1030 __in BURN_ENGINE_STATE* pEngineState,
1031 __in_z LPCWSTR wzCleanRoomBundlePath,
1032 __in_z LPCWSTR wzCurrentProcessPath,
1033 __inout HANDLE* phFileAttached,
1034 __inout HANDLE* phFileSelf
1035 )
1036{
1037 HRESULT hr = S_OK;
1038 BOOTSTRAPPER_COMMAND* pCommand = &pEngineState->command;
1039 BURN_ENGINE_COMMAND* pInternalCommand = &pEngineState->internalCommand;
1040
1041 // The clean room switch must always be at the front of the command line so
1042 // the EngineInCleanRoom function will operate correctly.
1043 hr = StrAllocFormatted(psczCommandLine, L"-%ls=\"%ls\"", BURN_COMMANDLINE_SWITCH_CLEAN_ROOM, wzCurrentProcessPath);
1044 ExitOnFailure(hr, "Failed to allocate parameters for unelevated process.");
1045
1046 // Send a file handle for the child Burn process to access the attached container.
1047 hr = CoreAppendFileHandleAttachedToCommandLine(pEngineState->section.hEngineFile, phFileAttached, psczCommandLine);
1048 ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED);
1049
1050 // Grab a file handle for the child Burn process.
1051 hr = CoreAppendFileHandleSelfToCommandLine(wzCleanRoomBundlePath, phFileSelf, psczCommandLine, NULL);
1052 ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF);
1053
1054 hr = CoreAppendSplashScreenWindowToCommandLine(pCommand->hwndSplashScreen, psczCommandLine);
1055 ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_SPLASH_SCREEN);
1056
1057 if (pInternalCommand->sczLogFile)
1058 {
1059 LPCWSTR wzLogParameter = (BURN_LOGGING_ATTRIBUTE_EXTRADEBUG & pInternalCommand->dwLoggingAttributes) ? L"xlog" : L"log";
1060 hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls", wzLogParameter);
1061 ExitOnFailure(hr, "Failed to append logging switch.");
1062
1063 hr = PathCommandLineAppend(psczCommandLine, pInternalCommand->sczLogFile);
1064 ExitOnFailure(hr, "Failed to append custom log path.");
1020 } 1065 }
1021 1066
1022 if (pCommand->wzCommandLine && *pCommand->wzCommandLine) 1067 hr = AppendLayoutToCommandLine(pCommand->action, pCommand->wzLayoutDirectory, psczCommandLine);
1068 ExitOnFailure(hr, "Failed to append layout.");
1069
1070 switch (pInternalCommand->automaticUpdates)
1023 { 1071 {
1024 hr = StrAllocConcat(psczCommandLine, L" ", 0); 1072 case BURN_AU_PAUSE_ACTION_NONE:
1025 ExitOnFailure(hr, "Failed to append space to command-line."); 1073 hr = StrAllocConcat(psczCommandLine, L" /noaupause", 0);
1074 ExitOnFailure(hr, "Failed to append /noaupause.");
1075 break;
1076 case BURN_AU_PAUSE_ACTION_IFELEVATED_NORESUME:
1077 hr = StrAllocConcat(psczCommandLine, L" /keepaupaused", 0);
1078 ExitOnFailure(hr, "Failed to append /keepaupaused.");
1079 break;
1080 }
1026 1081
1027 hr = StrAllocConcat(psczCommandLine, pCommand->wzCommandLine, 0); 1082 // TODO: This should only be added if it was enabled from the command line.
1028 ExitOnFailure(hr, "Failed to append command-line to command-line."); 1083 if (pInternalCommand->fDisableSystemRestore)
1084 {
1085 hr = StrAllocConcat(psczCommandLine, L" /disablesystemrestore", 0);
1086 ExitOnFailure(hr, "Failed to append /disablesystemrestore.");
1087 }
1088
1089#ifdef ENABLE_UNELEVATE
1090 if (pInternalCommand->fDisableUnelevate)
1091 {
1092 hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls", BURN_COMMANDLINE_SWITCH_DISABLE_UNELEVATE);
1093 ExitOnFailure(hr, "Failed to append switch: %ls.", BURN_COMMANDLINE_SWITCH_DISABLE_UNELEVATE);
1094 }
1095#endif
1096
1097 if (pInternalCommand->sczOriginalSource)
1098 {
1099 hr = StrAllocConcat(psczCommandLine, L" /originalsource", 0);
1100 ExitOnFailure(hr, "Failed to append /originalsource.");
1101
1102 hr = PathCommandLineAppend(psczCommandLine, pInternalCommand->sczOriginalSource);
1103 ExitOnFailure(hr, "Failed to append original source.");
1104 }
1105
1106 if (pEngineState->embeddedConnection.sczName)
1107 {
1108 hr = StrAllocConcatFormatted(psczCommandLine, L" -%ls %ls %ls %u", BURN_COMMANDLINE_SWITCH_EMBEDDED, pEngineState->embeddedConnection.sczName, pEngineState->embeddedConnection.sczSecret, pEngineState->embeddedConnection.dwProcessId);
1109 ExitOnFailure(hr, "Failed to allocate embedded command.");
1110 }
1111
1112 if (pInternalCommand->sczIgnoreDependencies)
1113 {
1114 hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls=%ls", BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES, pInternalCommand->sczIgnoreDependencies);
1115 ExitOnFailure(hr, "Failed to append ignored dependencies to command-line.");
1029 } 1116 }
1030 1117
1118 hr = CoreRecreateCommandLine(psczCommandLine, pCommand->action, pInternalCommand, pCommand, pCommand->relationType, pCommand->fPassthrough);
1119 ExitOnFailure(hr, "Failed to recreate clean room command-line.");
1120
1031LExit: 1121LExit:
1032 ReleaseStr(scz); 1122 return hr;
1123}
1033 1124
1125extern "C" HRESULT CoreCreatePassthroughBundleCommandLine(
1126 __deref_inout_z LPWSTR* psczCommandLine,
1127 __in BURN_ENGINE_COMMAND* pInternalCommand,
1128 __in BOOTSTRAPPER_COMMAND* pCommand
1129 )
1130{
1131 HRESULT hr = S_OK;
1132
1133 // No matter the operation, we're passing the same command-line.
1134 // That's what makes this a passthrough bundle.
1135 hr = CoreRecreateCommandLine(psczCommandLine, pCommand->action, pInternalCommand, pCommand, pCommand->relationType, TRUE);
1136 ExitOnFailure(hr, "Failed to recreate passthrough bundle command-line.");
1137
1138LExit:
1139 return hr;
1140}
1141
1142extern "C" HRESULT CoreCreateResumeCommandLine(
1143 __deref_inout_z LPWSTR* psczCommandLine,
1144 __in BURN_PLAN* pPlan,
1145 __in BURN_LOGGING* pLog
1146 )
1147{
1148 HRESULT hr = S_OK;
1149
1150 hr = StrAllocFormatted(psczCommandLine, L"/%ls", BURN_COMMANDLINE_SWITCH_CLEAN_ROOM);
1151 ExitOnFailure(hr, "Failed to alloc resume command-line.");
1152
1153 if (BURN_LOGGING_ATTRIBUTE_EXTRADEBUG & pPlan->pInternalCommand->dwLoggingAttributes)
1154 {
1155 hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls=%ls", BURN_COMMANDLINE_SWITCH_LOG_MODE, L"x");
1156 ExitOnFailure(hr, "Failed to set log mode in resume command-line.");
1157 }
1158
1159 if (pLog->sczPath && *(pLog->sczPath))
1160 {
1161 hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls \"%ls\"", BURN_COMMANDLINE_SWITCH_LOG_APPEND, pLog->sczPath);
1162 ExitOnFailure(hr, "Failed to set log path in resume command-line.");
1163 }
1164
1165 hr = CoreRecreateCommandLine(psczCommandLine, pPlan->action, pPlan->pInternalCommand, pPlan->pCommand, pPlan->pCommand->relationType, pPlan->pCommand->fPassthrough);
1166 ExitOnFailure(hr, "Failed to recreate resume command-line.");
1167
1168LExit:
1169 return hr;
1170}
1171
1172extern "C" HRESULT CoreCreateUpdateBundleCommandLine(
1173 __deref_inout_z LPWSTR* psczCommandLine,
1174 __in BURN_ENGINE_COMMAND* pInternalCommand,
1175 __in BOOTSTRAPPER_COMMAND* pCommand
1176 )
1177{
1178 HRESULT hr = S_OK;
1179
1180 hr = CoreRecreateCommandLine(psczCommandLine, BOOTSTRAPPER_ACTION_INSTALL, pInternalCommand, pCommand, BOOTSTRAPPER_RELATION_NONE, FALSE);
1181 ExitOnFailure(hr, "Failed to recreate update bundle command-line.");
1182
1183LExit:
1034 return hr; 1184 return hr;
1035} 1185}
1036 1186
@@ -1334,6 +1484,35 @@ extern "C" HRESULT CoreParseCommandLine(
1334 1484
1335 pInternalCommand->dwLoggingAttributes |= BURN_LOGGING_ATTRIBUTE_APPEND; 1485 pInternalCommand->dwLoggingAttributes |= BURN_LOGGING_ATTRIBUTE_APPEND;
1336 } 1486 }
1487 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_LOG_MODE), BURN_COMMANDLINE_SWITCH_LOG_MODE, -1))
1488 {
1489 // Get a pointer to the next character after the switch.
1490 LPCWSTR wzParam = &argv[i][2 + lstrlenW(BURN_COMMANDLINE_SWITCH_LOG_MODE)];
1491 if (L'=' != wzParam[-1] || L'\0' == wzParam[0])
1492 {
1493 fInvalidCommandLine = TRUE;
1494 TraceLog(E_INVALIDARG, "Missing required parameter for switch: %ls", BURN_COMMANDLINE_SWITCH_LOG_MODE);
1495 }
1496 else
1497 {
1498 while (L'\0' != wzParam[0])
1499 {
1500 switch (wzParam[0])
1501 {
1502 case L'x':
1503 pInternalCommand->dwLoggingAttributes |= BURN_LOGGING_ATTRIBUTE_EXTRADEBUG | BURN_LOGGING_ATTRIBUTE_VERBOSE;
1504 break;
1505 default:
1506 // Skip (but log) any other modifiers we don't recognize,
1507 // so that adding future modifiers doesn't break old bundles.
1508 LogId(REPORT_STANDARD, MSG_BURN_UNKNOWN_PRIVATE_SWITCH_MODIFIER, BURN_COMMANDLINE_SWITCH_LOG_MODE, wzParam[0]);
1509 break;
1510 }
1511
1512 ++wzParam;
1513 }
1514 }
1515 }
1337 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_ELEVATED, -1)) 1516 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_ELEVATED, -1))
1338 { 1517 {
1339 if (i + 3 >= argc) 1518 if (i + 3 >= argc)
@@ -1462,7 +1641,9 @@ extern "C" HRESULT CoreParseCommandLine(
1462 } 1641 }
1463 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_DISABLE_UNELEVATE, -1)) 1642 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_DISABLE_UNELEVATE, -1))
1464 { 1643 {
1644#ifdef ENABLE_UNELEVATE
1465 pInternalCommand->fDisableUnelevate = TRUE; 1645 pInternalCommand->fDisableUnelevate = TRUE;
1646#endif
1466 } 1647 }
1467 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RUNONCE, -1)) 1648 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RUNONCE, -1))
1468 { 1649 {
@@ -1628,6 +1809,30 @@ LExit:
1628 1809
1629// internal helper functions 1810// internal helper functions
1630 1811
1812static HRESULT AppendLayoutToCommandLine(
1813 __in BOOTSTRAPPER_ACTION action,
1814 __in_z LPCWSTR wzLayoutDirectory,
1815 __deref_inout_z LPWSTR* psczCommandLine
1816 )
1817{
1818 HRESULT hr = S_OK;
1819
1820 if (BOOTSTRAPPER_ACTION_LAYOUT == action || wzLayoutDirectory)
1821 {
1822 hr = StrAllocConcat(psczCommandLine, L" /layout", 0);
1823 ExitOnFailure(hr, "Failed to append layout switch.");
1824
1825 if (wzLayoutDirectory)
1826 {
1827 hr = PathCommandLineAppend(psczCommandLine, wzLayoutDirectory);
1828 ExitOnFailure(hr, "Failed to append layout directory.");
1829 }
1830 }
1831
1832LExit:
1833 return hr;
1834}
1835
1631static HRESULT GetSanitizedCommandLine( 1836static HRESULT GetSanitizedCommandLine(
1632 __in BURN_ENGINE_COMMAND* pInternalCommand, 1837 __in BURN_ENGINE_COMMAND* pInternalCommand,
1633 __in BOOTSTRAPPER_COMMAND* pCommand, 1838 __in BOOTSTRAPPER_COMMAND* pCommand,