aboutsummaryrefslogtreecommitdiff
path: root/src/burn/engine
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-06-07 17:28:18 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-06-09 13:47:53 -0500
commit881a6c9bd0c3b3134277605824dd5a9ceaaf176d (patch)
tree01d44474bea6f73d265a530510557f5e329291fc /src/burn/engine
parent9f360945ce3703677701b12267a42334bbe7dca1 (diff)
downloadwix-881a6c9bd0c3b3134277605824dd5a9ceaaf176d.tar.gz
wix-881a6c9bd0c3b3134277605824dd5a9ceaaf176d.tar.bz2
wix-881a6c9bd0c3b3134277605824dd5a9ceaaf176d.zip
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.
Diffstat (limited to 'src/burn/engine')
-rw-r--r--src/burn/engine/core.cpp231
-rw-r--r--src/burn/engine/core.h32
-rw-r--r--src/burn/engine/engine.cpp60
3 files changed, 181 insertions, 142 deletions
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp
index 478aa692..dc976eb4 100644
--- a/src/burn/engine/core.cpp
+++ b/src/burn/engine/core.cpp
@@ -14,26 +14,14 @@ struct BURN_CACHE_THREAD_CONTEXT
14 14
15// internal function declarations 15// internal function declarations
16 16
17static HRESULT ParseCommandLine( 17static HRESULT GetSanitizedCommandLine(
18 __in int argc, 18 __in int argc,
19 __in LPWSTR* argv, 19 __in LPWSTR* argv,
20 __in BOOTSTRAPPER_COMMAND* pCommand, 20 __in BOOTSTRAPPER_COMMAND* pCommand,
21 __in BURN_PIPE_CONNECTION* pCompanionConnection,
22 __in BURN_PIPE_CONNECTION* pEmbeddedConnection,
23 __in BURN_VARIABLES* pVariables, 21 __in BURN_VARIABLES* pVariables,
24 __out BURN_MODE* pMode, 22 __in DWORD cUnknownArgs,
25 __out BURN_AU_PAUSE_ACTION* pAutomaticUpdates, 23 __in int* rgUnknownArgs,
26 __out BOOL* pfDisableSystemRestore, 24 __inout_z LPWSTR* psczSanitizedCommandLine
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
37 ); 25 );
38static HRESULT ParsePipeConnection( 26static HRESULT ParsePipeConnection(
39 __in_ecount(3) LPWSTR* rgArgs, 27 __in_ecount(3) LPWSTR* rgArgs,
@@ -78,9 +66,7 @@ extern "C" HRESULT CoreInitialize(
78 SIZE_T cbBuffer = 0; 66 SIZE_T cbBuffer = 0;
79 BURN_CONTAINER_CONTEXT containerContext = { }; 67 BURN_CONTAINER_CONTEXT containerContext = { };
80 BOOL fElevated = FALSE; 68 BOOL fElevated = FALSE;
81 LPWSTR sczSourceProcessPath = NULL;
82 LPWSTR sczSourceProcessFolder = NULL; 69 LPWSTR sczSourceProcessFolder = NULL;
83 LPWSTR sczOriginalSource = NULL;
84 70
85 // Initialize variables. 71 // Initialize variables.
86 hr = VariableInitialize(&pEngineState->variables); 72 hr = VariableInitialize(&pEngineState->variables);
@@ -103,9 +89,8 @@ extern "C" HRESULT CoreInitialize(
103 hr = ContainersInitialize(&pEngineState->containers, &pEngineState->section); 89 hr = ContainersInitialize(&pEngineState->containers, &pEngineState->section);
104 ExitOnFailure(hr, "Failed to initialize containers."); 90 ExitOnFailure(hr, "Failed to initialize containers.");
105 91
106 // Parse command line. 92 hr = GetSanitizedCommandLine(pEngineState->argc, pEngineState->argv, &pEngineState->command, &pEngineState->variables, pEngineState->cUnknownArgs, pEngineState->rgUnknownArgs, &sczSanitizedCommandLine);
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); 93 ExitOnFailure(hr, "Fatal error while sanitizing command line.");
108 ExitOnFailure(hr, "Fatal error while parsing command line.");
109 94
110 LogId(REPORT_STANDARD, MSG_BURN_COMMAND_LINE, sczSanitizedCommandLine ? sczSanitizedCommandLine : L""); 95 LogId(REPORT_STANDARD, MSG_BURN_COMMAND_LINE, sczSanitizedCommandLine ? sczSanitizedCommandLine : L"");
111 96
@@ -129,12 +114,12 @@ extern "C" HRESULT CoreInitialize(
129 hr = VariableSetNumeric(&pEngineState->variables, BURN_BUNDLE_UILEVEL, pEngineState->command.display, TRUE); 114 hr = VariableSetNumeric(&pEngineState->variables, BURN_BUNDLE_UILEVEL, pEngineState->command.display, TRUE);
130 ExitOnFailure(hr, "Failed to overwrite the %ls built-in variable.", BURN_BUNDLE_UILEVEL); 115 ExitOnFailure(hr, "Failed to overwrite the %ls built-in variable.", BURN_BUNDLE_UILEVEL);
131 116
132 if (sczSourceProcessPath) 117 if (pEngineState->internalCommand.sczSourceProcessPath)
133 { 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);
135 ExitOnFailure(hr, "Failed to set source process path variable."); 120 ExitOnFailure(hr, "Failed to set source process path variable.");
136 121
137 hr = PathGetDirectory(sczSourceProcessPath, &sczSourceProcessFolder); 122 hr = PathGetDirectory(pEngineState->internalCommand.sczSourceProcessPath, &sczSourceProcessFolder);
138 ExitOnFailure(hr, "Failed to get source process folder from path."); 123 ExitOnFailure(hr, "Failed to get source process folder from path.");
139 124
140 hr = VariableSetString(&pEngineState->variables, BURN_BUNDLE_SOURCE_PROCESS_FOLDER, sczSourceProcessFolder, TRUE, FALSE); 125 hr = VariableSetString(&pEngineState->variables, BURN_BUNDLE_SOURCE_PROCESS_FOLDER, sczSourceProcessFolder, TRUE, FALSE);
@@ -143,15 +128,15 @@ extern "C" HRESULT CoreInitialize(
143 128
144 // Set BURN_BUNDLE_ORIGINAL_SOURCE, if it was passed in on the command line. 129 // Set BURN_BUNDLE_ORIGINAL_SOURCE, if it was passed in on the command line.
145 // Needs to be done after ManifestLoadXmlFromBuffer. 130 // Needs to be done after ManifestLoadXmlFromBuffer.
146 if (sczOriginalSource) 131 if (pEngineState->internalCommand.sczOriginalSource)
147 { 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);
149 ExitOnFailure(hr, "Failed to set original source variable."); 134 ExitOnFailure(hr, "Failed to set original source variable.");
150 } 135 }
151 136
152 if (BURN_MODE_UNTRUSTED == pEngineState->mode || BURN_MODE_NORMAL == pEngineState->mode || BURN_MODE_EMBEDDED == pEngineState->mode) 137 if (BURN_MODE_UNTRUSTED == pEngineState->mode || BURN_MODE_NORMAL == pEngineState->mode || BURN_MODE_EMBEDDED == pEngineState->mode)
153 { 138 {
154 hr = CacheInitialize(&pEngineState->registration, &pEngineState->variables, sczSourceProcessPath); 139 hr = CacheInitialize(&pEngineState->registration, &pEngineState->variables, pEngineState->internalCommand.sczSourceProcessPath);
155 ExitOnFailure(hr, "Failed to initialize internal cache functionality."); 140 ExitOnFailure(hr, "Failed to initialize internal cache functionality.");
156 } 141 }
157 142
@@ -174,9 +159,7 @@ extern "C" HRESULT CoreInitialize(
174 } 159 }
175 160
176LExit: 161LExit:
177 ReleaseStr(sczOriginalSource);
178 ReleaseStr(sczSourceProcessFolder); 162 ReleaseStr(sczSourceProcessFolder);
179 ReleaseStr(sczSourceProcessPath);
180 ContainerClose(&containerContext); 163 ContainerClose(&containerContext);
181 ReleaseStr(sczStreamName); 164 ReleaseStr(sczStreamName);
182 ReleaseStr(sczSanitizedCommandLine); 165 ReleaseStr(sczSanitizedCommandLine);
@@ -1177,43 +1160,38 @@ LExit:
1177 LogId(REPORT_STANDARD, MSG_CLEANUP_COMPLETE, hr); 1160 LogId(REPORT_STANDARD, MSG_CLEANUP_COMPLETE, hr);
1178} 1161}
1179 1162
1180// internal helper functions 1163extern "C" HRESULT CoreParseCommandLine(
1181
1182static HRESULT ParseCommandLine(
1183 __in int argc, 1164 __in int argc,
1184 __in LPWSTR* argv, 1165 __in LPWSTR* argv,
1185 __in BOOTSTRAPPER_COMMAND* pCommand, 1166 __in BOOTSTRAPPER_COMMAND* pCommand,
1186 __in BURN_PIPE_CONNECTION* pCompanionConnection, 1167 __in BURN_PIPE_CONNECTION* pCompanionConnection,
1187 __in BURN_PIPE_CONNECTION* pEmbeddedConnection, 1168 __in BURN_PIPE_CONNECTION* pEmbeddedConnection,
1188 __in BURN_VARIABLES* pVariables, 1169 __inout BURN_MODE* pMode,
1189 __out BURN_MODE* pMode, 1170 __inout BURN_AU_PAUSE_ACTION* pAutomaticUpdates,
1190 __out BURN_AU_PAUSE_ACTION* pAutomaticUpdates, 1171 __inout BOOL* pfDisableSystemRestore,
1191 __out BOOL* pfDisableSystemRestore, 1172 __inout_z LPWSTR* psczSourceProcessPath,
1192 __out_z LPWSTR* psczSourceProcessPath, 1173 __inout_z LPWSTR* psczOriginalSource,
1193 __out_z LPWSTR* psczOriginalSource, 1174 __inout HANDLE* phSectionFile,
1194 __out BOOL* pfDisableUnelevate, 1175 __inout HANDLE* phSourceEngineFile,
1195 __out DWORD *pdwLoggingAttributes, 1176 __inout BOOL* pfDisableUnelevate,
1196 __out_z LPWSTR* psczLogFile, 1177 __inout DWORD* pdwLoggingAttributes,
1197 __out_z LPWSTR* psczActiveParent, 1178 __inout_z LPWSTR* psczLogFile,
1198 __out_z LPWSTR* psczIgnoreDependencies, 1179 __inout_z LPWSTR* psczActiveParent,
1199 __out_z LPWSTR* psczAncestors, 1180 __inout_z LPWSTR* psczIgnoreDependencies,
1200 __out_z LPWSTR* psczSanitizedCommandLine, 1181 __inout_z LPWSTR* psczAncestors,
1201 __inout BOOL* pfInvalidCommandLine 1182 __inout BOOL* pfInvalidCommandLine,
1183 __inout DWORD* pcUnknownArgs,
1184 __inout int** prgUnknownArgs
1202 ) 1185 )
1203{ 1186{
1204 HRESULT hr = S_OK; 1187 HRESULT hr = S_OK;
1205 BOOL fUnknownArg = FALSE; 1188 BOOL fUnknownArg = FALSE;
1206 BOOL fHidden = FALSE;
1207 LPWSTR sczCommandLine = NULL;
1208 LPWSTR sczSanitizedArgument = NULL;
1209 LPWSTR sczVariableName = NULL;
1210 BOOL fInvalidCommandLine = FALSE; 1189 BOOL fInvalidCommandLine = FALSE;
1190 DWORD64 qw = 0;
1211 1191
1212 for (int i = 0; i < argc; ++i) 1192 for (int i = 0; i < argc; ++i)
1213 { 1193 {
1214 fUnknownArg = FALSE; 1194 fUnknownArg = FALSE;
1215 int originalIndex = i;
1216 ReleaseNullStr(sczSanitizedArgument);
1217 1195
1218 if (argv[i][0] == L'-' || argv[i][0] == L'/') 1196 if (argv[i][0] == L'-' || argv[i][0] == L'/')
1219 { 1197 {
@@ -1414,6 +1392,12 @@ static HRESULT ParseCommandLine(
1414 } 1392 }
1415 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))) 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)))
1416 { 1394 {
1395 if (BURN_MODE_UNTRUSTED != *pMode)
1396 {
1397 fInvalidCommandLine = TRUE;
1398 TraceLog(E_INVALIDARG, "Multiple mode command-line switches were provided.");
1399 }
1400
1417 // Get a pointer to the next character after the switch. 1401 // Get a pointer to the next character after the switch.
1418 LPCWSTR wzParam = &argv[i][1 + lstrlenW(BURN_COMMANDLINE_SWITCH_CLEAN_ROOM)]; 1402 LPCWSTR wzParam = &argv[i][1 + lstrlenW(BURN_COMMANDLINE_SWITCH_CLEAN_ROOM)];
1419 if (L'=' != wzParam[0] || L'\0' == wzParam[1]) 1403 if (L'=' != wzParam[0] || L'\0' == wzParam[1])
@@ -1428,12 +1412,6 @@ static HRESULT ParseCommandLine(
1428 hr = StrAllocString(psczSourceProcessPath, wzParam + 1, 0); 1412 hr = StrAllocString(psczSourceProcessPath, wzParam + 1, 0);
1429 ExitOnFailure(hr, "Failed to copy source process path."); 1413 ExitOnFailure(hr, "Failed to copy source process path.");
1430 } 1414 }
1431
1432 if (BURN_MODE_UNTRUSTED != *pMode)
1433 {
1434 fInvalidCommandLine = TRUE;
1435 TraceLog(E_INVALIDARG, "Multiple mode command-line switches were provided.");
1436 }
1437 } 1415 }
1438 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_EMBEDDED, -1)) 1416 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_EMBEDDED, -1))
1439 { 1417 {
@@ -1551,11 +1529,47 @@ static HRESULT ParseCommandLine(
1551 } 1529 }
1552 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))) 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)))
1553 { 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 }
1555 } 1551 }
1556 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))) 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)))
1557 { 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 }
1559 } 1573 }
1560 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))) 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)))
1561 { 1575 {
@@ -1571,40 +1585,15 @@ static HRESULT ParseCommandLine(
1571 else 1585 else
1572 { 1586 {
1573 fUnknownArg = TRUE; 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 }
1590 } 1588 }
1591 1589
1592 // Remember command-line switch to pass off to UX.
1593 if (fUnknownArg) 1590 if (fUnknownArg)
1594 { 1591 {
1595 PathCommandLineAppend(&pCommand->wzCommandLine, argv[i]); 1592 hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(prgUnknownArgs), *pcUnknownArgs, 1, sizeof(int), 5);
1596 } 1593 ExitOnFailure(hr, "Failed to ensure size for unknown args.");
1597 1594
1598 if (sczSanitizedArgument) 1595 (*prgUnknownArgs)[*pcUnknownArgs] = i;
1599 { 1596 *pcUnknownArgs += 1;
1600 PathCommandLineAppend(psczSanitizedCommandLine, sczSanitizedArgument);
1601 }
1602 else
1603 {
1604 for (; originalIndex <= i; ++originalIndex)
1605 {
1606 PathCommandLineAppend(psczSanitizedCommandLine, argv[originalIndex]);
1607 }
1608 } 1597 }
1609 } 1598 }
1610 1599
@@ -1637,9 +1626,71 @@ LExit:
1637 *pfInvalidCommandLine = TRUE; 1626 *pfInvalidCommandLine = TRUE;
1638 } 1627 }
1639 1628
1629 return hr;
1630}
1631
1632// internal helper functions
1633
1634static 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
1691LExit:
1640 ReleaseStr(sczVariableName); 1692 ReleaseStr(sczVariableName);
1641 ReleaseStr(sczSanitizedArgument); 1693 ReleaseStr(sczSanitizedArgument);
1642 ReleaseStr(sczCommandLine);
1643 1694
1644 return hr; 1695 return hr;
1645} 1696}
diff --git a/src/burn/engine/core.h b/src/burn/engine/core.h
index 7e9d99bb..7b1be47e 100644
--- a/src/burn/engine/core.h
+++ b/src/burn/engine/core.h
@@ -77,6 +77,12 @@ enum BURN_AU_PAUSE_ACTION
77 77
78// structs 78// structs
79 79
80typedef struct _BURN_ENGINE_COMMAND
81{
82 LPWSTR sczSourceProcessPath;
83 LPWSTR sczOriginalSource;
84} BURN_ENGINE_COMMAND;
85
80typedef struct _BURN_ENGINE_STATE 86typedef struct _BURN_ENGINE_STATE
81{ 87{
82 // UX flow control 88 // UX flow control
@@ -134,6 +140,9 @@ typedef struct _BURN_ENGINE_STATE
134 int argc; 140 int argc;
135 LPWSTR* argv; 141 LPWSTR* argv;
136 BOOL fInvalidCommandLine; 142 BOOL fInvalidCommandLine;
143 BURN_ENGINE_COMMAND internalCommand;
144 DWORD cUnknownArgs;
145 int* rgUnknownArgs;
137} BURN_ENGINE_STATE; 146} BURN_ENGINE_STATE;
138 147
139typedef struct _BURN_APPLY_CONTEXT 148typedef struct _BURN_APPLY_CONTEXT
@@ -222,6 +231,29 @@ HRESULT CoreAppendFileHandleSelfToCommandLine(
222void CoreCleanup( 231void CoreCleanup(
223 __in BURN_ENGINE_STATE* pEngineState 232 __in BURN_ENGINE_STATE* pEngineState
224 ); 233 );
234HRESULT 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 );
225 257
226#if defined(__cplusplus) 258#if defined(__cplusplus)
227} 259}
diff --git a/src/burn/engine/engine.cpp b/src/burn/engine/engine.cpp
index f9dd2184..1314ddc6 100644
--- a/src/burn/engine/engine.cpp
+++ b/src/burn/engine/engine.cpp
@@ -321,10 +321,8 @@ static HRESULT InitializeEngineState(
321 ) 321 )
322{ 322{
323 HRESULT hr = S_OK; 323 HRESULT hr = S_OK;
324 LPCWSTR wzParam = NULL;
325 HANDLE hSectionFile = hEngineFile; 324 HANDLE hSectionFile = hEngineFile;
326 HANDLE hSourceEngineFile = INVALID_HANDLE_VALUE; 325 HANDLE hSourceEngineFile = INVALID_HANDLE_VALUE;
327 DWORD64 qw = 0;
328 326
329 pEngineState->automaticUpdates = BURN_AU_PAUSE_ACTION_IFELEVATED; 327 pEngineState->automaticUpdates = BURN_AU_PAUSE_ACTION_IFELEVATED;
330 pEngineState->dwElevatedLoggingTlsId = TLS_OUT_OF_INDEXES; 328 pEngineState->dwElevatedLoggingTlsId = TLS_OUT_OF_INDEXES;
@@ -332,56 +330,9 @@ static HRESULT InitializeEngineState(
332 PipeConnectionInitialize(&pEngineState->companionConnection); 330 PipeConnectionInitialize(&pEngineState->companionConnection);
333 PipeConnectionInitialize(&pEngineState->embeddedConnection); 331 PipeConnectionInitialize(&pEngineState->embeddedConnection);
334 332
335 for (int i = 0; i < pEngineState->argc; ++i) 333 // Parse command line.
336 { 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);
337 if (pEngineState->argv[i][0] == L'-') 335 ExitOnFailure(hr, "Fatal error while parsing command line.");
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 }
385 336
386 hr = SectionInitialize(&pEngineState->section, hSectionFile, hSourceEngineFile); 337 hr = SectionInitialize(&pEngineState->section, hSectionFile, hSourceEngineFile);
387 ExitOnFailure(hr, "Failed to initialize engine section."); 338 ExitOnFailure(hr, "Failed to initialize engine section.");
@@ -399,6 +350,8 @@ static void UninitializeEngineState(
399 AppFreeCommandLineArgs(pEngineState->argv); 350 AppFreeCommandLineArgs(pEngineState->argv);
400 } 351 }
401 352
353 ReleaseMem(pEngineState->rgUnknownArgs);
354
402 ReleaseStr(pEngineState->sczIgnoreDependencies); 355 ReleaseStr(pEngineState->sczIgnoreDependencies);
403 356
404 PipeConnectionUninitialize(&pEngineState->embeddedConnection); 357 PipeConnectionUninitialize(&pEngineState->embeddedConnection);
@@ -427,6 +380,9 @@ static void UninitializeEngineState(
427 ReleaseStr(pEngineState->command.wzLayoutDirectory); 380 ReleaseStr(pEngineState->command.wzLayoutDirectory);
428 ReleaseStr(pEngineState->command.wzCommandLine); 381 ReleaseStr(pEngineState->command.wzCommandLine);
429 382
383 ReleaseStr(pEngineState->internalCommand.sczOriginalSource);
384 ReleaseStr(pEngineState->internalCommand.sczSourceProcessPath);
385
430 ReleaseStr(pEngineState->log.sczExtension); 386 ReleaseStr(pEngineState->log.sczExtension);
431 ReleaseStr(pEngineState->log.sczPrefix); 387 ReleaseStr(pEngineState->log.sczPrefix);
432 ReleaseStr(pEngineState->log.sczPath); 388 ReleaseStr(pEngineState->log.sczPath);