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(®istration, &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(®istration, &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(®istration, &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(®istration, &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(®istration, &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(®istration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);