Update Burn command line parsing to handle unknown args separately.
Parse whole command line in InitializeEngineState but store the indices of unknown args. This allows the engine earlier access to the configuration from the command line, while still allowing CoreInitialize to sanitize the command line before logging it.
Sean Hall committed
Jun 7, 2021 at 17:28 UTC
881a6c9bd0c3b3134277605824dd5a9ceaaf176d
3 files changed
+181
-142
src/burn/engine/core.cpp
+141
-90
@@ -14,26 +14,14 @@ struct BURN_CACHE_THREAD_CONTEXT
14
15
// internal function declarations
16
17
-static HRESULT ParseCommandLine(
17
+static HRESULT GetSanitizedCommandLine(
18
__in int argc,
19
__in LPWSTR* argv,
20
__in BOOTSTRAPPER_COMMAND* pCommand,
21
- __in BURN_PIPE_CONNECTION* pCompanionConnection,
22
- __in BURN_PIPE_CONNECTION* pEmbeddedConnection,
21
__in BURN_VARIABLES* pVariables,
24
- __out BURN_MODE* pMode,
25
- __out BURN_AU_PAUSE_ACTION* pAutomaticUpdates,
26
- __out BOOL* pfDisableSystemRestore,
27
- __out_z LPWSTR* psczSourceProcessPath,
28
- __out_z LPWSTR* psczOriginalSource,
29
- __out BOOL* pfDisableUnelevate,
30
- __out DWORD *pdwLoggingAttributes,
31
- __out_z LPWSTR* psczLogFile,
32
- __out_z LPWSTR* psczActiveParent,
33
- __out_z LPWSTR* psczIgnoreDependencies,
34
- __out_z LPWSTR* psczAncestors,
35
- __out_z LPWSTR* psczSanitizedCommandLine,
36
- __inout BOOL* pfInvalidCommandLine
22
+ __in DWORD cUnknownArgs,
23
+ __in int* rgUnknownArgs,
24
+ __inout_z LPWSTR* psczSanitizedCommandLine
25
);
26
static HRESULT ParsePipeConnection(
27
__in_ecount(3) LPWSTR* rgArgs,
@@ -78,9 +66,7 @@ extern "C" HRESULT CoreInitialize(
66
SIZE_T cbBuffer = 0;
67
BURN_CONTAINER_CONTEXT containerContext = { };
68
BOOL fElevated = FALSE;
81
- LPWSTR sczSourceProcessPath = NULL;
69
LPWSTR sczSourceProcessFolder = NULL;
83
- LPWSTR sczOriginalSource = NULL;
70
71
// Initialize variables.
72
hr = VariableInitialize(&pEngineState->variables);
@@ -103,9 +89,8 @@ extern "C" HRESULT CoreInitialize(
89
hr = ContainersInitialize(&pEngineState->containers, &pEngineState->section);
90
ExitOnFailure(hr, "Failed to initialize containers.");
91
106
- // Parse command line.
107
- hr = ParseCommandLine(pEngineState->argc, pEngineState->argv, &pEngineState->command, &pEngineState->companionConnection, &pEngineState->embeddedConnection, &pEngineState->variables, &pEngineState->mode, &pEngineState->automaticUpdates, &pEngineState->fDisableSystemRestore, &sczSourceProcessPath, &sczOriginalSource, &pEngineState->fDisableUnelevate, &pEngineState->log.dwAttributes, &pEngineState->log.sczPath, &pEngineState->registration.sczActiveParent, &pEngineState->sczIgnoreDependencies, &pEngineState->registration.sczAncestors, &sczSanitizedCommandLine, &pEngineState->fInvalidCommandLine);
108
- ExitOnFailure(hr, "Fatal error while parsing command line.");
92
+ hr = GetSanitizedCommandLine(pEngineState->argc, pEngineState->argv, &pEngineState->command, &pEngineState->variables, pEngineState->cUnknownArgs, pEngineState->rgUnknownArgs, &sczSanitizedCommandLine);
93
+ ExitOnFailure(hr, "Fatal error while sanitizing command line.");
94
95
LogId(REPORT_STANDARD, MSG_BURN_COMMAND_LINE, sczSanitizedCommandLine ? sczSanitizedCommandLine : L"");
96
@@ -129,12 +114,12 @@ extern "C" HRESULT CoreInitialize(
114
hr = VariableSetNumeric(&pEngineState->variables, BURN_BUNDLE_UILEVEL, pEngineState->command.display, TRUE);
115
ExitOnFailure(hr, "Failed to overwrite the %ls built-in variable.", BURN_BUNDLE_UILEVEL);
116
132
- if (sczSourceProcessPath)
117
+ if (pEngineState->internalCommand.sczSourceProcessPath)
118
{
134
- hr = VariableSetString(&pEngineState->variables, BURN_BUNDLE_SOURCE_PROCESS_PATH, sczSourceProcessPath, TRUE, FALSE);
119
+ hr = VariableSetString(&pEngineState->variables, BURN_BUNDLE_SOURCE_PROCESS_PATH, pEngineState->internalCommand.sczSourceProcessPath, TRUE, FALSE);
120
ExitOnFailure(hr, "Failed to set source process path variable.");
121
137
- hr = PathGetDirectory(sczSourceProcessPath, &sczSourceProcessFolder);
122
+ hr = PathGetDirectory(pEngineState->internalCommand.sczSourceProcessPath, &sczSourceProcessFolder);
123
ExitOnFailure(hr, "Failed to get source process folder from path.");
124
125
hr = VariableSetString(&pEngineState->variables, BURN_BUNDLE_SOURCE_PROCESS_FOLDER, sczSourceProcessFolder, TRUE, FALSE);
@@ -143,15 +128,15 @@ extern "C" HRESULT CoreInitialize(
128
129
// Set BURN_BUNDLE_ORIGINAL_SOURCE, if it was passed in on the command line.
130
// Needs to be done after ManifestLoadXmlFromBuffer.
146
- if (sczOriginalSource)
131
+ if (pEngineState->internalCommand.sczOriginalSource)
132
{
148
- hr = VariableSetString(&pEngineState->variables, BURN_BUNDLE_ORIGINAL_SOURCE, sczOriginalSource, FALSE, FALSE);
133
+ hr = VariableSetString(&pEngineState->variables, BURN_BUNDLE_ORIGINAL_SOURCE, pEngineState->internalCommand.sczOriginalSource, FALSE, FALSE);
134
ExitOnFailure(hr, "Failed to set original source variable.");
135
}
136
137
if (BURN_MODE_UNTRUSTED == pEngineState->mode || BURN_MODE_NORMAL == pEngineState->mode || BURN_MODE_EMBEDDED == pEngineState->mode)
138
{
154
- hr = CacheInitialize(&pEngineState->registration, &pEngineState->variables, sczSourceProcessPath);
139
+ hr = CacheInitialize(&pEngineState->registration, &pEngineState->variables, pEngineState->internalCommand.sczSourceProcessPath);
140
ExitOnFailure(hr, "Failed to initialize internal cache functionality.");
141
}
142
@@ -174,9 +159,7 @@ extern "C" HRESULT CoreInitialize(
159
}
160
161
LExit:
177
- ReleaseStr(sczOriginalSource);
162
ReleaseStr(sczSourceProcessFolder);
179
- ReleaseStr(sczSourceProcessPath);
163
ContainerClose(&containerContext);
164
ReleaseStr(sczStreamName);
165
ReleaseStr(sczSanitizedCommandLine);
@@ -1177,43 +1160,38 @@ LExit:
1160
LogId(REPORT_STANDARD, MSG_CLEANUP_COMPLETE, hr);
1161
}
1162
1180
-// internal helper functions
1181
-
1182
-static HRESULT ParseCommandLine(
1163
+extern "C" HRESULT CoreParseCommandLine(
1164
__in int argc,
1165
__in LPWSTR* argv,
1166
__in BOOTSTRAPPER_COMMAND* pCommand,
1167
__in BURN_PIPE_CONNECTION* pCompanionConnection,
1168
__in BURN_PIPE_CONNECTION* pEmbeddedConnection,
1188
- __in BURN_VARIABLES* pVariables,
1189
- __out BURN_MODE* pMode,
1190
- __out BURN_AU_PAUSE_ACTION* pAutomaticUpdates,
1191
- __out BOOL* pfDisableSystemRestore,
1192
- __out_z LPWSTR* psczSourceProcessPath,
1193
- __out_z LPWSTR* psczOriginalSource,
1194
- __out BOOL* pfDisableUnelevate,
1195
- __out DWORD *pdwLoggingAttributes,
1196
- __out_z LPWSTR* psczLogFile,
1197
- __out_z LPWSTR* psczActiveParent,
1198
- __out_z LPWSTR* psczIgnoreDependencies,
1199
- __out_z LPWSTR* psczAncestors,
1200
- __out_z LPWSTR* psczSanitizedCommandLine,
1201
- __inout BOOL* pfInvalidCommandLine
1169
+ __inout BURN_MODE* pMode,
1170
+ __inout BURN_AU_PAUSE_ACTION* pAutomaticUpdates,
1171
+ __inout BOOL* pfDisableSystemRestore,
1172
+ __inout_z LPWSTR* psczSourceProcessPath,
1173
+ __inout_z LPWSTR* psczOriginalSource,
1174
+ __inout HANDLE* phSectionFile,
1175
+ __inout HANDLE* phSourceEngineFile,
1176
+ __inout BOOL* pfDisableUnelevate,
1177
+ __inout DWORD* pdwLoggingAttributes,
1178
+ __inout_z LPWSTR* psczLogFile,
1179
+ __inout_z LPWSTR* psczActiveParent,
1180
+ __inout_z LPWSTR* psczIgnoreDependencies,
1181
+ __inout_z LPWSTR* psczAncestors,
1182
+ __inout BOOL* pfInvalidCommandLine,
1183
+ __inout DWORD* pcUnknownArgs,
1184
+ __inout int** prgUnknownArgs
1185
)
1186
{
1187
HRESULT hr = S_OK;
1188
BOOL fUnknownArg = FALSE;
1206
- BOOL fHidden = FALSE;
1207
- LPWSTR sczCommandLine = NULL;
1208
- LPWSTR sczSanitizedArgument = NULL;
1209
- LPWSTR sczVariableName = NULL;
1189
BOOL fInvalidCommandLine = FALSE;
1190
+ DWORD64 qw = 0;
1191
1192
for (int i = 0; i < argc; ++i)
1193
{
1194
fUnknownArg = FALSE;
1215
- int originalIndex = i;
1216
- ReleaseNullStr(sczSanitizedArgument);
1195
1196
if (argv[i][0] == L'-' || argv[i][0] == L'/')
1197
{
@@ -1414,6 +1392,12 @@ static HRESULT ParseCommandLine(
1392
}
1393
else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_CLEAN_ROOM), BURN_COMMANDLINE_SWITCH_CLEAN_ROOM, lstrlenW(BURN_COMMANDLINE_SWITCH_CLEAN_ROOM)))
1394
{
1395
+ if (BURN_MODE_UNTRUSTED != *pMode)
1396
+ {
1397
+ fInvalidCommandLine = TRUE;
1398
+ TraceLog(E_INVALIDARG, "Multiple mode command-line switches were provided.");
1399
+ }
1400
+
1401
// Get a pointer to the next character after the switch.
1402
LPCWSTR wzParam = &argv[i][1 + lstrlenW(BURN_COMMANDLINE_SWITCH_CLEAN_ROOM)];
1403
if (L'=' != wzParam[0] || L'\0' == wzParam[1])
@@ -1428,12 +1412,6 @@ static HRESULT ParseCommandLine(
1412
hr = StrAllocString(psczSourceProcessPath, wzParam + 1, 0);
1413
ExitOnFailure(hr, "Failed to copy source process path.");
1414
}
1431
-
1432
- if (BURN_MODE_UNTRUSTED != *pMode)
1433
- {
1434
- fInvalidCommandLine = TRUE;
1435
- TraceLog(E_INVALIDARG, "Multiple mode command-line switches were provided.");
1436
- }
1415
}
1416
else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_EMBEDDED, -1))
1417
{
@@ -1551,11 +1529,47 @@ static HRESULT ParseCommandLine(
1529
}
1530
else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED), BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED, lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED)))
1531
{
1554
- // Already processed in InitializeEngineState.
1532
+ LPCWSTR wzParam = &argv[i][2 + lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED)];
1533
+ if (L'=' != wzParam[-1] || L'\0' == wzParam[0])
1534
+ {
1535
+ fInvalidCommandLine = TRUE;
1536
+ TraceLog(E_INVALIDARG, "Missing required parameter for switch: %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED);
1537
+ }
1538
+ else
1539
+ {
1540
+ hr = StrStringToUInt64(wzParam, 0, &qw);
1541
+ if (FAILED(hr))
1542
+ {
1543
+ TraceLog(hr, "Failed to parse file handle: '%ls'", wzParam);
1544
+ hr = S_OK;
1545
+ }
1546
+ else
1547
+ {
1548
+ *phSourceEngineFile = (HANDLE)qw;
1549
+ }
1550
+ }
1551
}
1552
else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF), BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF, lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF)))
1553
{
1558
- // Already processed in InitializeEngineState.
1554
+ LPCWSTR wzParam = &argv[i][2 + lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF)];
1555
+ if (L'=' != wzParam[-1] || L'\0' == wzParam[0])
1556
+ {
1557
+ fInvalidCommandLine = TRUE;
1558
+ TraceLog(E_INVALIDARG, "Missing required parameter for switch: %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF);
1559
+ }
1560
+ else
1561
+ {
1562
+ hr = StrStringToUInt64(wzParam, 0, &qw);
1563
+ if (FAILED(hr))
1564
+ {
1565
+ TraceLog(hr, "Failed to parse file handle: '%ls'", wzParam);
1566
+ hr = S_OK;
1567
+ }
1568
+ else
1569
+ {
1570
+ *phSectionFile = (HANDLE)qw;
1571
+ }
1572
+ }
1573
}
1574
else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_PREFIX), BURN_COMMANDLINE_SWITCH_PREFIX, lstrlenW(BURN_COMMANDLINE_SWITCH_PREFIX)))
1575
{
@@ -1571,40 +1585,15 @@ static HRESULT ParseCommandLine(
1585
else
1586
{
1587
fUnknownArg = TRUE;
1574
-
1575
- const wchar_t* pwc = wcschr(argv[i], L'=');
1576
- if (pwc)
1577
- {
1578
- hr = StrAllocString(&sczVariableName, argv[i], pwc - argv[i]);
1579
- ExitOnFailure(hr, "Failed to copy variable name.");
1580
-
1581
- hr = VariableIsHidden(pVariables, sczVariableName, &fHidden);
1582
- ExitOnFailure(hr, "Failed to determine whether variable is hidden.");
1583
-
1584
- if (fHidden)
1585
- {
1586
- hr = StrAllocFormatted(&sczSanitizedArgument, L"%ls=*****", sczVariableName);
1587
- ExitOnFailure(hr, "Failed to copy sanitized argument.");
1588
- }
1589
- }
1588
}
1589
1592
- // Remember command-line switch to pass off to UX.
1590
if (fUnknownArg)
1591
{
1595
- PathCommandLineAppend(&pCommand->wzCommandLine, argv[i]);
1596
- }
1592
+ hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgUnknownArgs), *pcUnknownArgs, 1, sizeof(int), 5);
1593
+ ExitOnFailure(hr, "Failed to ensure size for unknown args.");
1594
1598
- if (sczSanitizedArgument)
1599
- {
1600
- PathCommandLineAppend(psczSanitizedCommandLine, sczSanitizedArgument);
1601
- }
1602
- else
1603
- {
1604
- for (; originalIndex <= i; ++originalIndex)
1605
- {
1606
- PathCommandLineAppend(psczSanitizedCommandLine, argv[originalIndex]);
1607
- }
1595
+ (*prgUnknownArgs)[*pcUnknownArgs] = i;
1596
+ *pcUnknownArgs += 1;
1597
}
1598
}
1599
@@ -1637,9 +1626,71 @@ LExit:
1626
*pfInvalidCommandLine = TRUE;
1627
}
1628
1629
+ return hr;
1630
+}
1631
+
1632
+// internal helper functions
1633
+
1634
+static HRESULT GetSanitizedCommandLine(
1635
+ __in int argc,
1636
+ __in LPWSTR* argv,
1637
+ __in BOOTSTRAPPER_COMMAND* pCommand,
1638
+ __in BURN_VARIABLES* pVariables,
1639
+ __in DWORD cUnknownArgs,
1640
+ __in int* rgUnknownArgs,
1641
+ __inout_z LPWSTR* psczSanitizedCommandLine
1642
+ )
1643
+{
1644
+ HRESULT hr = S_OK;
1645
+ DWORD dwUnknownArgIndex = 0;
1646
+ BOOL fHidden = FALSE;
1647
+ LPWSTR sczSanitizedArgument = NULL;
1648
+ LPWSTR sczVariableName = NULL;
1649
+
1650
+ for (int i = 0; i < argc; ++i)
1651
+ {
1652
+ fHidden = FALSE;
1653
+
1654
+ if (dwUnknownArgIndex < cUnknownArgs && rgUnknownArgs[dwUnknownArgIndex] == i)
1655
+ {
1656
+ ++dwUnknownArgIndex;
1657
+
1658
+ if (argv[i][0] != L'-' && argv[i][0] != L'/')
1659
+ {
1660
+ const wchar_t* pwc = wcschr(argv[i], L'=');
1661
+ if (pwc)
1662
+ {
1663
+ hr = StrAllocString(&sczVariableName, argv[i], pwc - argv[i]);
1664
+ ExitOnFailure(hr, "Failed to copy variable name.");
1665
+
1666
+ hr = VariableIsHidden(pVariables, sczVariableName, &fHidden);
1667
+ ExitOnFailure(hr, "Failed to determine whether variable is hidden.");
1668
+
1669
+ if (fHidden)
1670
+ {
1671
+ hr = StrAllocFormatted(&sczSanitizedArgument, L"%ls=*****", sczVariableName);
1672
+ ExitOnFailure(hr, "Failed to copy sanitized argument.");
1673
+ }
1674
+ }
1675
+ }
1676
+
1677
+ // Remember command-line switch to pass off to BA.
1678
+ PathCommandLineAppend(&pCommand->wzCommandLine, argv[i]);
1679
+ }
1680
+
1681
+ if (fHidden)
1682
+ {
1683
+ PathCommandLineAppend(psczSanitizedCommandLine, sczSanitizedArgument);
1684
+ }
1685
+ else
1686
+ {
1687
+ PathCommandLineAppend(psczSanitizedCommandLine, argv[i]);
1688
+ }
1689
+ }
1690
+
1691
+LExit:
1692
ReleaseStr(sczVariableName);
1693
ReleaseStr(sczSanitizedArgument);
1642
- ReleaseStr(sczCommandLine);
1694
1695
return hr;
1696
}
src/burn/engine/core.h
+32
@@ -77,6 +77,12 @@ enum BURN_AU_PAUSE_ACTION
77
78
// structs
79
80
+typedef struct _BURN_ENGINE_COMMAND
81
+{
82
+ LPWSTR sczSourceProcessPath;
83
+ LPWSTR sczOriginalSource;
84
+} BURN_ENGINE_COMMAND;
85
+
86
typedef struct _BURN_ENGINE_STATE
87
{
88
// UX flow control
@@ -134,6 +140,9 @@ typedef struct _BURN_ENGINE_STATE
140
int argc;
141
LPWSTR* argv;
142
BOOL fInvalidCommandLine;
143
+ BURN_ENGINE_COMMAND internalCommand;
144
+ DWORD cUnknownArgs;
145
+ int* rgUnknownArgs;
146
} BURN_ENGINE_STATE;
147
148
typedef struct _BURN_APPLY_CONTEXT
@@ -222,6 +231,29 @@ HRESULT CoreAppendFileHandleSelfToCommandLine(
231
void CoreCleanup(
232
__in BURN_ENGINE_STATE* pEngineState
233
);
234
+HRESULT CoreParseCommandLine(
235
+ __in int argc,
236
+ __in LPWSTR* argv,
237
+ __in BOOTSTRAPPER_COMMAND* pCommand,
238
+ __in BURN_PIPE_CONNECTION* pCompanionConnection,
239
+ __in BURN_PIPE_CONNECTION* pEmbeddedConnection,
240
+ __inout BURN_MODE* pMode,
241
+ __inout BURN_AU_PAUSE_ACTION* pAutomaticUpdates,
242
+ __inout BOOL* pfDisableSystemRestore,
243
+ __inout_z LPWSTR* psczSourceProcessPath,
244
+ __inout_z LPWSTR* psczOriginalSource,
245
+ __inout HANDLE* phSectionFile,
246
+ __inout HANDLE* phSourceEngineFile,
247
+ __inout BOOL* pfDisableUnelevate,
248
+ __inout DWORD* pdwLoggingAttributes,
249
+ __inout_z LPWSTR* psczLogFile,
250
+ __inout_z LPWSTR* psczActiveParent,
251
+ __inout_z LPWSTR* psczIgnoreDependencies,
252
+ __inout_z LPWSTR* psczAncestors,
253
+ __inout BOOL* pfInvalidCommandLine,
254
+ __inout DWORD* pcUnknownArgs,
255
+ __inout int** prgUnknownArgs
256
+ );
257
258
#if defined(__cplusplus)
259
}
src/burn/engine/engine.cpp
+8
-52
@@ -321,10 +321,8 @@ static HRESULT InitializeEngineState(
321
)
322
{
323
HRESULT hr = S_OK;
324
- LPCWSTR wzParam = NULL;
324
HANDLE hSectionFile = hEngineFile;
325
HANDLE hSourceEngineFile = INVALID_HANDLE_VALUE;
327
- DWORD64 qw = 0;
326
327
pEngineState->automaticUpdates = BURN_AU_PAUSE_ACTION_IFELEVATED;
328
pEngineState->dwElevatedLoggingTlsId = TLS_OUT_OF_INDEXES;
@@ -332,56 +330,9 @@ static HRESULT InitializeEngineState(
330
PipeConnectionInitialize(&pEngineState->companionConnection);
331
PipeConnectionInitialize(&pEngineState->embeddedConnection);
332
335
- for (int i = 0; i < pEngineState->argc; ++i)
336
- {
337
- if (pEngineState->argv[i][0] == L'-')
338
- {
339
- if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &pEngineState->argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED), BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED, lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED)))
340
- {
341
- wzParam = &pEngineState->argv[i][2 + lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED)];
342
- if (L'=' != wzParam[-1] || L'\0' == wzParam[0])
343
- {
344
- pEngineState->fInvalidCommandLine = TRUE;
345
- TraceLog(E_INVALIDARG, "Missing required parameter for switch: %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED);
346
- }
347
- else
348
- {
349
- hr = StrStringToUInt64(wzParam, 0, &qw);
350
- if (FAILED(hr))
351
- {
352
- TraceLog(hr, "Failed to parse file handle: '%ls'", wzParam);
353
- hr = S_OK;
354
- }
355
- else
356
- {
357
- hSourceEngineFile = (HANDLE)qw;
358
- }
359
- }
360
- }
361
- if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &pEngineState->argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF), BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF, lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF)))
362
- {
363
- wzParam = &pEngineState->argv[i][2 + lstrlenW(BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF)];
364
- if (L'=' != wzParam[-1] || L'\0' == wzParam[0])
365
- {
366
- pEngineState->fInvalidCommandLine = TRUE;
367
- TraceLog(E_INVALIDARG, "Missing required parameter for switch: %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF);
368
- }
369
- else
370
- {
371
- hr = StrStringToUInt64(wzParam, 0, &qw);
372
- if (FAILED(hr))
373
- {
374
- TraceLog(hr, "Failed to parse file handle: '%ls'", wzParam);
375
- hr = S_OK;
376
- }
377
- else
378
- {
379
- hSectionFile = (HANDLE)qw;
380
- }
381
- }
382
- }
383
- }
384
- }
333
+ // Parse command line.
334
+ hr = CoreParseCommandLine(pEngineState->argc, pEngineState->argv, &pEngineState->command, &pEngineState->companionConnection, &pEngineState->embeddedConnection, &pEngineState->mode, &pEngineState->automaticUpdates, &pEngineState->fDisableSystemRestore, &pEngineState->internalCommand.sczSourceProcessPath, &pEngineState->internalCommand.sczOriginalSource, &hSectionFile, &hSourceEngineFile, &pEngineState->fDisableUnelevate, &pEngineState->log.dwAttributes, &pEngineState->log.sczPath, &pEngineState->registration.sczActiveParent, &pEngineState->sczIgnoreDependencies, &pEngineState->registration.sczAncestors, &pEngineState->fInvalidCommandLine, &pEngineState->cUnknownArgs, &pEngineState->rgUnknownArgs);
335
+ ExitOnFailure(hr, "Fatal error while parsing command line.");
336
337
hr = SectionInitialize(&pEngineState->section, hSectionFile, hSourceEngineFile);
338
ExitOnFailure(hr, "Failed to initialize engine section.");
@@ -399,6 +350,8 @@ static void UninitializeEngineState(
350
AppFreeCommandLineArgs(pEngineState->argv);
351
}
352
353
+ ReleaseMem(pEngineState->rgUnknownArgs);
354
+
355
ReleaseStr(pEngineState->sczIgnoreDependencies);
356
357
PipeConnectionUninitialize(&pEngineState->embeddedConnection);
@@ -427,6 +380,9 @@ static void UninitializeEngineState(
380
ReleaseStr(pEngineState->command.wzLayoutDirectory);
381
ReleaseStr(pEngineState->command.wzCommandLine);
382
383
+ ReleaseStr(pEngineState->internalCommand.sczOriginalSource);
384
+ ReleaseStr(pEngineState->internalCommand.sczSourceProcessPath);
385
+
386
ReleaseStr(pEngineState->log.sczExtension);
387
ReleaseStr(pEngineState->log.sczPrefix);
388
ReleaseStr(pEngineState->log.sczPath);