diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2021-06-07 17:28:18 -0500 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2021-06-09 13:47:53 -0500 |
commit | 881a6c9bd0c3b3134277605824dd5a9ceaaf176d (patch) | |
tree | 01d44474bea6f73d265a530510557f5e329291fc /src/burn/engine | |
parent | 9f360945ce3703677701b12267a42334bbe7dca1 (diff) | |
download | wix-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.cpp | 231 | ||||
-rw-r--r-- | src/burn/engine/core.h | 32 | ||||
-rw-r--r-- | src/burn/engine/engine.cpp | 60 |
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 | ||
17 | static HRESULT ParseCommandLine( | 17 | static 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 | ); |
38 | static HRESULT ParsePipeConnection( | 26 | static 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 | ||
176 | LExit: | 161 | LExit: |
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 | 1163 | extern "C" HRESULT CoreParseCommandLine( |
1181 | |||
1182 | static 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 | |||
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: | ||
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 | ||
80 | typedef struct _BURN_ENGINE_COMMAND | ||
81 | { | ||
82 | LPWSTR sczSourceProcessPath; | ||
83 | LPWSTR sczOriginalSource; | ||
84 | } BURN_ENGINE_COMMAND; | ||
85 | |||
80 | typedef struct _BURN_ENGINE_STATE | 86 | typedef 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 | ||
139 | typedef struct _BURN_APPLY_CONTEXT | 148 | typedef struct _BURN_APPLY_CONTEXT |
@@ -222,6 +231,29 @@ HRESULT CoreAppendFileHandleSelfToCommandLine( | |||
222 | void CoreCleanup( | 231 | void CoreCleanup( |
223 | __in BURN_ENGINE_STATE* pEngineState | 232 | __in BURN_ENGINE_STATE* pEngineState |
224 | ); | 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 | ); | ||
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); |