@joebigelow / wix-1 / commits / 94b8260f

Recreate the command line for the clean room process.

Persist /xlog when resuming from RunOnce. Fixes #6259

Sean Hall committed Aug 3, 2021 at 15:42 UTC 94b8260fc5c1abc199f8d6145f3db4e2de490463
10 files changed +284 -78
src/burn/engine/core.cpp
+234 -29
@@ -14,6 +14,19 @@ struct BURN_CACHE_THREAD_CONTEXT
14
15 // internal function declarations
16
17 +static 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 + );
25 +static HRESULT AppendLayoutToCommandLine(
26 + __in BOOTSTRAPPER_ACTION action,
27 + __in_z LPCWSTR wzLayoutDirectory,
28 + __deref_inout_z LPWSTR* psczCommandLine
29 + );
30 static HRESULT GetSanitizedCommandLine(
31 __in BURN_ENGINE_COMMAND* pInternalCommand,
32 __in BOOTSTRAPPER_COMMAND* pCommand,
@@ -924,23 +937,19 @@ extern "C" LPCWSTR CoreRelationTypeToCommandLineString(
937 return wzRelationTypeCommandLine;
938 }
939
927 -extern "C" HRESULT CoreRecreateCommandLine(
940 +static HRESULT CoreRecreateCommandLine(
941 __deref_inout_z LPWSTR* psczCommandLine,
942 __in BOOTSTRAPPER_ACTION action,
943 __in BURN_ENGINE_COMMAND* pInternalCommand,
944 __in BOOTSTRAPPER_COMMAND* pCommand,
945 __in BOOTSTRAPPER_RELATION_TYPE relationType,
933 - __in BOOL fPassthrough,
934 - __in_z_opt LPCWSTR wzAppendLogPath
946 + __in BOOL fPassthrough
947 )
948 {
949 HRESULT hr = S_OK;
950 LPWSTR scz = NULL;
951 LPCWSTR wzRelationTypeCommandLine = CoreRelationTypeToCommandLineString(relationType);
952
941 - hr = StrAllocString(psczCommandLine, L"", 0);
942 - ExitOnFailure(hr, "Failed to empty command line.");
943 -
953 switch (pCommand->display)
954 {
955 case BOOTSTRAPPER_DISPLAY_NONE:
@@ -954,6 +963,9 @@ extern "C" HRESULT CoreRecreateCommandLine(
963
964 switch (action)
965 {
966 + case BOOTSTRAPPER_ACTION_HELP:
967 + hr = StrAllocConcat(psczCommandLine, L" /help", 0);
968 + break;
969 case BOOTSTRAPPER_ACTION_MODIFY:
970 hr = StrAllocConcat(psczCommandLine, L" /modify", 0);
971 break;
@@ -985,52 +997,190 @@ extern "C" HRESULT CoreRecreateCommandLine(
997
998 if (pInternalCommand->sczAncestors)
999 {
988 - hr = StrAllocFormatted(&scz, 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);
1000 + hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls=%ls", BURN_COMMANDLINE_SWITCH_ANCESTORS, pInternalCommand->sczAncestors);
1001 ExitOnFailure(hr, "Failed to append ancestors to command-line.");
1002 }
1003
1004 if (wzRelationTypeCommandLine)
1005 {
997 - hr = StrAllocFormatted(&scz, L" /%ls", wzRelationTypeCommandLine);
998 - ExitOnFailure(hr, "Failed to format relation type for command-line.");
999 -
1000 - hr = StrAllocConcat(psczCommandLine, scz, 0);
1006 + hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls", wzRelationTypeCommandLine);
1007 ExitOnFailure(hr, "Failed to append relation type to command-line.");
1008 }
1009
1010 if (fPassthrough)
1011 {
1006 - hr = StrAllocFormatted(&scz, L" /%ls", BURN_COMMANDLINE_SWITCH_PASSTHROUGH);
1007 - ExitOnFailure(hr, "Failed to format passthrough for command-line.");
1008 -
1009 - hr = StrAllocConcat(psczCommandLine, scz, 0);
1012 + hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls", BURN_COMMANDLINE_SWITCH_PASSTHROUGH);
1013 ExitOnFailure(hr, "Failed to append passthrough to command-line.");
1014 }
1015
1013 - if (wzAppendLogPath && *wzAppendLogPath)
1016 + if (pCommand->wzCommandLine && *pCommand->wzCommandLine)
1017 {
1015 - hr = StrAllocFormatted(&scz, L" /%ls \"%ls\"", BURN_COMMANDLINE_SWITCH_LOG_APPEND, wzAppendLogPath);
1016 - ExitOnFailure(hr, "Failed to format append log command-line for command-line.");
1018 + hr = StrAllocConcatFormattedSecure(psczCommandLine, L" %ls", pCommand->wzCommandLine);
1019 + ExitOnFailure(hr, "Failed to append command-line to command-line.");
1020 + }
1021
1018 - hr = StrAllocConcat(psczCommandLine, scz, 0);
1019 - ExitOnFailure(hr, "Failed to append log command-line to command-line");
1022 +LExit:
1023 + ReleaseStr(scz);
1024 +
1025 + return hr;
1026 +}
1027 +
1028 +extern "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.");
1065 }
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)
1071 {
1024 - hr = StrAllocConcat(psczCommandLine, L" ", 0);
1025 - ExitOnFailure(hr, "Failed to append space to command-line.");
1072 + case BURN_AU_PAUSE_ACTION_NONE:
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 + }
1081
1027 - hr = StrAllocConcat(psczCommandLine, pCommand->wzCommandLine, 0);
1028 - ExitOnFailure(hr, "Failed to append command-line to command-line.");
1082 + // TODO: This should only be added if it was enabled from the 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.");
1116 }
1117
1118 + hr = CoreRecreateCommandLine(psczCommandLine, pCommand->action, pInternalCommand, pCommand, pCommand->relationType, pCommand->fPassthrough);
1119 + ExitOnFailure(hr, "Failed to recreate clean room command-line.");
1120 +
1121 LExit:
1032 - ReleaseStr(scz);
1122 + return hr;
1123 +}
1124
1125 +extern "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 +
1138 +LExit:
1139 + return hr;
1140 +}
1141 +
1142 +extern "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 +
1168 +LExit:
1169 + return hr;
1170 +}
1171 +
1172 +extern "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 +
1183 +LExit:
1184 return hr;
1185 }
1186
@@ -1334,6 +1484,35 @@ extern "C" HRESULT CoreParseCommandLine(
1484
1485 pInternalCommand->dwLoggingAttributes |= BURN_LOGGING_ATTRIBUTE_APPEND;
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 + }
1516 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_ELEVATED, -1))
1517 {
1518 if (i + 3 >= argc)
@@ -1462,7 +1641,9 @@ extern "C" HRESULT CoreParseCommandLine(
1641 }
1642 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_DISABLE_UNELEVATE, -1))
1643 {
1644 +#ifdef ENABLE_UNELEVATE
1645 pInternalCommand->fDisableUnelevate = TRUE;
1646 +#endif
1647 }
1648 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RUNONCE, -1))
1649 {
@@ -1628,6 +1809,30 @@ LExit:
1809
1810 // internal helper functions
1811
1812 +static 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 +
1832 +LExit:
1833 + return hr;
1834 +}
1835 +
1836 static HRESULT GetSanitizedCommandLine(
1837 __in BURN_ENGINE_COMMAND* pInternalCommand,
1838 __in BOOTSTRAPPER_COMMAND* pCommand,
src/burn/engine/core.h
+23 -6
@@ -18,6 +18,7 @@ const LPCWSTR BURN_COMMANDLINE_SWITCH_ELEVATED = L"burn.elevated";
18 const LPCWSTR BURN_COMMANDLINE_SWITCH_EMBEDDED = L"burn.embedded";
19 const LPCWSTR BURN_COMMANDLINE_SWITCH_RUNONCE = L"burn.runonce";
20 const LPCWSTR BURN_COMMANDLINE_SWITCH_LOG_APPEND = L"burn.log.append";
21 +const LPCWSTR BURN_COMMANDLINE_SWITCH_LOG_MODE = L"burn.log.mode";
22 const LPCWSTR BURN_COMMANDLINE_SWITCH_RELATED_DETECT = L"burn.related.detect";
23 const LPCWSTR BURN_COMMANDLINE_SWITCH_RELATED_UPGRADE = L"burn.related.upgrade";
24 const LPCWSTR BURN_COMMANDLINE_SWITCH_RELATED_ADDON = L"burn.related.addon";
@@ -89,7 +90,9 @@ typedef struct _BURN_ENGINE_COMMAND
90 BURN_MODE mode;
91 BURN_AU_PAUSE_ACTION automaticUpdates;
92 BOOL fDisableSystemRestore;
93 +#ifdef ENABLE_UNELEVATE
94 BOOL fDisableUnelevate;
95 +#endif
96 BOOL fInitiallyElevated;
97
98 LPWSTR sczActiveParent;
@@ -215,14 +218,28 @@ HRESULT CoreSaveEngineState(
218 LPCWSTR CoreRelationTypeToCommandLineString(
219 __in BOOTSTRAPPER_RELATION_TYPE relationType
220 );
218 -HRESULT CoreRecreateCommandLine(
221 +HRESULT CoreCreateCleanRoomCommandLine(
222 + __deref_inout_z LPWSTR* psczCommandLine,
223 + __in BURN_ENGINE_STATE* pEngineState,
224 + __in_z LPCWSTR wzCleanRoomBundlePath,
225 + __in_z LPCWSTR wzCurrentProcessPath,
226 + __inout HANDLE* phFileAttached,
227 + __inout HANDLE* phFileSelf
228 + );
229 +HRESULT CoreCreatePassthroughBundleCommandLine(
230 __deref_inout_z LPWSTR* psczCommandLine,
220 - __in BOOTSTRAPPER_ACTION action,
231 __in BURN_ENGINE_COMMAND* pInternalCommand,
222 - __in BOOTSTRAPPER_COMMAND* pCommand,
223 - __in BOOTSTRAPPER_RELATION_TYPE relationType,
224 - __in BOOL fPassthrough,
225 - __in_z_opt LPCWSTR wzAppendLogPath
232 + __in BOOTSTRAPPER_COMMAND* pCommand
233 + );
234 +HRESULT CoreCreateResumeCommandLine(
235 + __deref_inout_z LPWSTR* psczCommandLine,
236 + __in BURN_PLAN* pPlan,
237 + __in BURN_LOGGING* pLog
238 + );
239 +HRESULT CoreCreateUpdateBundleCommandLine(
240 + __deref_inout_z LPWSTR* psczCommandLine,
241 + __in BURN_ENGINE_COMMAND* pInternalCommand,
242 + __in BOOTSTRAPPER_COMMAND* pCommand
243 );
244 HRESULT CoreAppendFileHandleAttachedToCommandLine(
245 __in HANDLE hFileWithAttachedContainer,
src/burn/engine/engine.cpp
+3 -21
@@ -17,7 +17,6 @@ static void UninitializeEngineState(
17 __in BURN_ENGINE_STATE* pEngineState
18 );
19 static HRESULT RunUntrusted(
20 - __in LPCWSTR wzCommandLine,
20 __in BURN_ENGINE_STATE* pEngineState
21 );
22 static HRESULT RunNormal(
@@ -195,7 +194,7 @@ extern "C" HRESULT EngineRun(
194 switch (engineState.internalCommand.mode)
195 {
196 case BURN_MODE_UNTRUSTED:
198 - hr = RunUntrusted(wzCommandLine, &engineState);
197 + hr = RunUntrusted(&engineState);
198 ExitOnFailure(hr, "Failed to run untrusted mode.");
199 break;
200
@@ -411,7 +410,6 @@ static void UninitializeEngineState(
410 }
411
412 static HRESULT RunUntrusted(
414 - __in LPCWSTR wzCommandLine,
413 __in BURN_ENGINE_STATE* pEngineState
414 )
415 {
@@ -450,24 +448,8 @@ static HRESULT RunUntrusted(
448 wzCleanRoomBundlePath = sczCachedCleanRoomBundlePath;
449 }
450
453 - // The clean room switch must always be at the front of the command line so
454 - // the EngineInCleanRoom function will operate correctly.
455 - hr = StrAllocFormatted(&sczParameters, L"-%ls=\"%ls\"", BURN_COMMANDLINE_SWITCH_CLEAN_ROOM, sczCurrentProcessPath);
456 - ExitOnFailure(hr, "Failed to allocate parameters for unelevated process.");
457 -
458 - // Send a file handle for the child Burn process to access the attached container.
459 - hr = CoreAppendFileHandleAttachedToCommandLine(pEngineState->section.hEngineFile, &hFileAttached, &sczParameters);
460 - ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED);
461 -
462 - // Grab a file handle for the child Burn process.
463 - hr = CoreAppendFileHandleSelfToCommandLine(wzCleanRoomBundlePath, &hFileSelf, &sczParameters, NULL);
464 - ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF);
465 -
466 - hr = CoreAppendSplashScreenWindowToCommandLine(pEngineState->command.hwndSplashScreen, &sczParameters);
467 - ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_SPLASH_SCREEN);
468 -
469 - hr = StrAllocConcatFormattedSecure(&sczParameters, L" %ls", wzCommandLine);
470 - ExitOnFailure(hr, "Failed to append original command line.");
451 + hr = CoreCreateCleanRoomCommandLine(&sczParameters, pEngineState, wzCleanRoomBundlePath, sczCurrentProcessPath, &hFileAttached, &hFileSelf);
452 + ExitOnFailure(hr, "Failed to create clean room command-line.");
453
454 #ifdef ENABLE_UNELEVATE
455 // TODO: Pass file handle to unelevated process if this ever gets reenabled.
src/burn/engine/engine.mc
+7
@@ -135,6 +135,13 @@ Language=English
135 Failed to parse command line.
136 .
137
138 +MessageId=16
139 +Severity=Warning
140 +SymbolicName=MSG_BURN_UNKNOWN_PRIVATE_SWITCH_MODIFIER
141 +Language=English
142 +Unknown burn internal command-line switch modifier encountered, switch: '%1!ls!', modifier: '%2!c!'.
143 +.
144 +
145 MessageId=51
146 Severity=Error
147 SymbolicName=MSG_FAILED_PARSE_CONDITION
src/burn/engine/externalengine.cpp
+2 -2
@@ -295,8 +295,8 @@ HRESULT ExternalEngineSetUpdate(
295 {
296 UpdateUninitialize(&pEngineState->update);
297
298 - hr = CoreRecreateCommandLine(&sczCommandline, BOOTSTRAPPER_ACTION_INSTALL, &pEngineState->internalCommand, &pEngineState->command, BOOTSTRAPPER_RELATION_NONE, FALSE, NULL);
299 - ExitOnFailure(hr, "Failed to recreate command-line for update bundle.");
298 + hr = CoreCreateUpdateBundleCommandLine(&sczCommandline, &pEngineState->internalCommand, &pEngineState->command);
299 + ExitOnFailure(hr, "Failed to create command-line for update bundle.");
300
301 // Bundles would fail to use the downloaded update bundle, as the running bundle would be one of the search paths.
302 // Here I am generating a random guid, but in the future it would be nice if the feed would provide the ID of the update.
src/burn/engine/plan.cpp
+3 -4
@@ -479,7 +479,7 @@ extern "C" HRESULT PlanForwardCompatibleBundles(
479
480 if (!fIgnoreBundle)
481 {
482 - hr = PseudoBundleInitializePassthrough(&pPlan->forwardCompatibleBundle, pPlan->pInternalCommand, pPlan->pCommand, NULL, &pRelatedBundle->package);
482 + hr = PseudoBundleInitializePassthrough(&pPlan->forwardCompatibleBundle, pPlan->pInternalCommand, pPlan->pCommand, &pRelatedBundle->package);
483 ExitOnFailure(hr, "Failed to initialize pass through bundle.");
484
485 pPlan->fEnabledForwardCompatibleBundle = TRUE;
@@ -1780,11 +1780,10 @@ extern "C" HRESULT PlanSetResumeCommand(
1780 )
1781 {
1782 HRESULT hr = S_OK;
1783 - BOOTSTRAPPER_COMMAND* pCommand = pPlan->pCommand;
1783
1784 // build the resume command-line.
1786 - hr = CoreRecreateCommandLine(&pRegistration->sczResumeCommandLine, pPlan->action, pPlan->pInternalCommand, pCommand, pCommand->relationType, pCommand->fPassthrough, pLog->sczPath);
1787 - ExitOnFailure(hr, "Failed to recreate resume command-line.");
1785 + hr = CoreCreateResumeCommandLine(&pRegistration->sczResumeCommandLine, pPlan, pLog);
1786 + ExitOnFailure(hr, "Failed to create resume command-line.");
1787
1788 LExit:
1789 return hr;
src/burn/engine/pseudobundle.cpp
+2 -5
@@ -165,7 +165,6 @@ extern "C" HRESULT PseudoBundleInitializePassthrough(
165 __in BURN_PACKAGE* pPassthroughPackage,
166 __in BURN_ENGINE_COMMAND* pInternalCommand,
167 __in BOOTSTRAPPER_COMMAND* pCommand,
168 - __in_z_opt LPCWSTR wzAppendLogPath,
168 __in BURN_PACKAGE* pPackage
169 )
170 {
@@ -202,10 +201,8 @@ extern "C" HRESULT PseudoBundleInitializePassthrough(
201
202 pPassthroughPackage->Exe.protocol = pPackage->Exe.protocol;
203
205 - // No matter the operation, we're passing the same command-line. That's what makes
206 - // this a passthrough bundle.
207 - hr = CoreRecreateCommandLine(&sczArguments, pCommand->action, pInternalCommand, pCommand, pCommand->relationType, TRUE, wzAppendLogPath);
208 - ExitOnFailure(hr, "Failed to recreate command-line arguments.");
204 + hr = CoreCreatePassthroughBundleCommandLine(&sczArguments, pInternalCommand, pCommand);
205 + ExitOnFailure(hr, "Failed to create command-line arguments.");
206
207 hr = StrAllocString(&pPassthroughPackage->Exe.sczInstallArguments, sczArguments, 0);
208 ExitOnFailure(hr, "Failed to copy install arguments for passthrough bundle package");
src/burn/engine/pseudobundle.h
-1
@@ -30,7 +30,6 @@ HRESULT PseudoBundleInitializePassthrough(
30 __in BURN_PACKAGE* pPassthroughPackage,
31 __in BURN_ENGINE_COMMAND* pInternalCommand,
32 __in BOOTSTRAPPER_COMMAND* pCommand,
33 - __in_z_opt LPCWSTR wzAppendLogPath,
33 __in BURN_PACKAGE* pPackage
34 );
35
src/burn/engine/registration.cpp
+4 -4
@@ -1322,7 +1322,7 @@ static HRESULT UpdateResumeMode(
1322 DWORD er = ERROR_SUCCESS;
1323 HKEY hkRebootRequired = NULL;
1324 HKEY hkRun = NULL;
1325 - LPWSTR sczResumeCommandLine = NULL;
1325 + LPWSTR sczRunOnceCommandLine = NULL;
1326 LPCWSTR sczResumeKey = REGISTRY_RUN_ONCE_KEY;
1327
1328 LogId(REPORT_STANDARD, MSG_SESSION_UPDATE, pRegistration->sczRegistrationKey, LoggingResumeModeToString(resumeMode), LoggingBoolToString(fRestartInitiated), LoggingBoolToString(pRegistration->fDisableResume));
@@ -1354,14 +1354,14 @@ static HRESULT UpdateResumeMode(
1354 if ((BURN_RESUME_MODE_ACTIVE == resumeMode || fRestartInitiated) && !pRegistration->fDisableResume)
1355 {
1356 // append RunOnce switch
1357 - hr = StrAllocFormatted(&sczResumeCommandLine, L"\"%ls\" /%ls", pRegistration->sczCacheExecutablePath, BURN_COMMANDLINE_SWITCH_RUNONCE);
1357 + hr = StrAllocFormatted(&sczRunOnceCommandLine, L"\"%ls\" /%ls /%ls", pRegistration->sczCacheExecutablePath, BURN_COMMANDLINE_SWITCH_CLEAN_ROOM, BURN_COMMANDLINE_SWITCH_RUNONCE);
1358 ExitOnFailure(hr, "Failed to format resume command line for RunOnce.");
1359
1360 // write run key
1361 hr = RegCreate(pRegistration->hkRoot, sczResumeKey, KEY_WRITE, &hkRun);
1362 ExitOnFailure(hr, "Failed to create run key.");
1363
1364 - hr = RegWriteString(hkRun, pRegistration->sczId, sczResumeCommandLine);
1364 + hr = RegWriteString(hkRun, pRegistration->sczId, sczRunOnceCommandLine);
1365 ExitOnFailure(hr, "Failed to write run key value.");
1366
1367 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_RESUME_COMMAND_LINE, pRegistration->sczResumeCommandLine);
@@ -1398,7 +1398,7 @@ static HRESULT UpdateResumeMode(
1398 }
1399
1400 LExit:
1401 - ReleaseStr(sczResumeCommandLine);
1401 + ReleaseStr(sczRunOnceCommandLine);
1402 ReleaseRegKey(hkRebootRequired);
1403 ReleaseRegKey(hkRun);
1404
src/burn/test/BurnUnitTest/RegistrationTest.cpp
+6 -6
@@ -133,7 +133,7 @@ namespace Bootstrapper
133 Assert::True(File::Exists(Path::Combine(cacheDirectory, gcnew String(L"setup.exe"))));
134
135 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
136 - Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)(Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)));
136 + Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)(Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)));
137
138 // end session
139 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
@@ -234,7 +234,7 @@ namespace Bootstrapper
234 // verify that registration was created
235 Assert::Equal<String^>(gcnew String(L"Product1 Installation"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayName"), nullptr));
236 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
237 - Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
237 + Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
238
239 // complete registration
240 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
@@ -256,7 +256,7 @@ namespace Bootstrapper
256 // verify that registration was updated
257 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
258 Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr));
259 - Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
259 + Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
260
261 // delete registration
262 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
@@ -355,7 +355,7 @@ namespace Bootstrapper
355
356 // verify that registration was created
357 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
358 - Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
358 + Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
359
360 // complete registration
361 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL);
@@ -477,7 +477,7 @@ namespace Bootstrapper
477
478 // verify that registration was created
479 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
480 - Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
480 + Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
481
482 // finish registration
483 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL);
@@ -510,7 +510,7 @@ namespace Bootstrapper
510
511 // verify that registration was updated
512 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
513 - Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
513 + Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
514
515 // delete registration
516 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);