@joebigelow / wix-1 / commits / 881a6c9b

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);