diff options
author | Sean Hall <r.sean.hall@gmail.com> | 2021-08-03 15:42:08 -0500 |
---|---|---|
committer | Sean Hall <r.sean.hall@gmail.com> | 2021-08-04 10:03:57 -0500 |
commit | 94b8260fc5c1abc199f8d6145f3db4e2de490463 (patch) | |
tree | f8aeebc5b8d3facdab8232f60098ed253b3019cf /src/burn/engine/core.cpp | |
parent | 9ae1c04d5fa02ac020885cdad7c592f7bb43d83e (diff) | |
download | wix-94b8260fc5c1abc199f8d6145f3db4e2de490463.tar.gz wix-94b8260fc5c1abc199f8d6145f3db4e2de490463.tar.bz2 wix-94b8260fc5c1abc199f8d6145f3db4e2de490463.zip |
Recreate the command line for the clean room process.
Persist /xlog when resuming from RunOnce.
Fixes #6259
Diffstat (limited to 'src/burn/engine/core.cpp')
-rw-r--r-- | src/burn/engine/core.cpp | 263 |
1 files changed, 234 insertions, 29 deletions
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp index ea7f34d1..d8e2454d 100644 --- a/src/burn/engine/core.cpp +++ b/src/burn/engine/core.cpp | |||
@@ -14,6 +14,19 @@ struct BURN_CACHE_THREAD_CONTEXT | |||
14 | 14 | ||
15 | // internal function declarations | 15 | // internal function declarations |
16 | 16 | ||
17 | static HRESULT CoreRecreateCommandLine( | ||
18 | __deref_inout_z LPWSTR* psczCommandLine, | ||
19 | __in BOOTSTRAPPER_ACTION action, | ||
20 | __in BURN_ENGINE_COMMAND* pInternalCommand, | ||
21 | __in BOOTSTRAPPER_COMMAND* pCommand, | ||
22 | __in BOOTSTRAPPER_RELATION_TYPE relationType, | ||
23 | __in BOOL fPassthrough | ||
24 | ); | ||
25 | static HRESULT AppendLayoutToCommandLine( | ||
26 | __in BOOTSTRAPPER_ACTION action, | ||
27 | __in_z LPCWSTR wzLayoutDirectory, | ||
28 | __deref_inout_z LPWSTR* psczCommandLine | ||
29 | ); | ||
17 | static HRESULT GetSanitizedCommandLine( | 30 | static HRESULT GetSanitizedCommandLine( |
18 | __in BURN_ENGINE_COMMAND* pInternalCommand, | 31 | __in BURN_ENGINE_COMMAND* pInternalCommand, |
19 | __in BOOTSTRAPPER_COMMAND* pCommand, | 32 | __in BOOTSTRAPPER_COMMAND* pCommand, |
@@ -924,23 +937,19 @@ extern "C" LPCWSTR CoreRelationTypeToCommandLineString( | |||
924 | return wzRelationTypeCommandLine; | 937 | return wzRelationTypeCommandLine; |
925 | } | 938 | } |
926 | 939 | ||
927 | extern "C" HRESULT CoreRecreateCommandLine( | 940 | static HRESULT CoreRecreateCommandLine( |
928 | __deref_inout_z LPWSTR* psczCommandLine, | 941 | __deref_inout_z LPWSTR* psczCommandLine, |
929 | __in BOOTSTRAPPER_ACTION action, | 942 | __in BOOTSTRAPPER_ACTION action, |
930 | __in BURN_ENGINE_COMMAND* pInternalCommand, | 943 | __in BURN_ENGINE_COMMAND* pInternalCommand, |
931 | __in BOOTSTRAPPER_COMMAND* pCommand, | 944 | __in BOOTSTRAPPER_COMMAND* pCommand, |
932 | __in BOOTSTRAPPER_RELATION_TYPE relationType, | 945 | __in BOOTSTRAPPER_RELATION_TYPE relationType, |
933 | __in BOOL fPassthrough, | 946 | __in BOOL fPassthrough |
934 | __in_z_opt LPCWSTR wzAppendLogPath | ||
935 | ) | 947 | ) |
936 | { | 948 | { |
937 | HRESULT hr = S_OK; | 949 | HRESULT hr = S_OK; |
938 | LPWSTR scz = NULL; | 950 | LPWSTR scz = NULL; |
939 | LPCWSTR wzRelationTypeCommandLine = CoreRelationTypeToCommandLineString(relationType); | 951 | LPCWSTR wzRelationTypeCommandLine = CoreRelationTypeToCommandLineString(relationType); |
940 | 952 | ||
941 | hr = StrAllocString(psczCommandLine, L"", 0); | ||
942 | ExitOnFailure(hr, "Failed to empty command line."); | ||
943 | |||
944 | switch (pCommand->display) | 953 | switch (pCommand->display) |
945 | { | 954 | { |
946 | case BOOTSTRAPPER_DISPLAY_NONE: | 955 | case BOOTSTRAPPER_DISPLAY_NONE: |
@@ -954,6 +963,9 @@ extern "C" HRESULT CoreRecreateCommandLine( | |||
954 | 963 | ||
955 | switch (action) | 964 | switch (action) |
956 | { | 965 | { |
966 | case BOOTSTRAPPER_ACTION_HELP: | ||
967 | hr = StrAllocConcat(psczCommandLine, L" /help", 0); | ||
968 | break; | ||
957 | case BOOTSTRAPPER_ACTION_MODIFY: | 969 | case BOOTSTRAPPER_ACTION_MODIFY: |
958 | hr = StrAllocConcat(psczCommandLine, L" /modify", 0); | 970 | hr = StrAllocConcat(psczCommandLine, L" /modify", 0); |
959 | break; | 971 | break; |
@@ -985,52 +997,190 @@ extern "C" HRESULT CoreRecreateCommandLine( | |||
985 | 997 | ||
986 | if (pInternalCommand->sczAncestors) | 998 | if (pInternalCommand->sczAncestors) |
987 | { | 999 | { |
988 | hr = StrAllocFormatted(&scz, L" /%ls=%ls", BURN_COMMANDLINE_SWITCH_ANCESTORS, pInternalCommand->sczAncestors); | 1000 | hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls=%ls", BURN_COMMANDLINE_SWITCH_ANCESTORS, pInternalCommand->sczAncestors); |
989 | ExitOnFailure(hr, "Failed to format ancestors for command-line."); | ||
990 | |||
991 | hr = StrAllocConcat(psczCommandLine, scz, 0); | ||
992 | ExitOnFailure(hr, "Failed to append ancestors to command-line."); | 1001 | ExitOnFailure(hr, "Failed to append ancestors to command-line."); |
993 | } | 1002 | } |
994 | 1003 | ||
995 | if (wzRelationTypeCommandLine) | 1004 | if (wzRelationTypeCommandLine) |
996 | { | 1005 | { |
997 | hr = StrAllocFormatted(&scz, L" /%ls", wzRelationTypeCommandLine); | 1006 | hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls", wzRelationTypeCommandLine); |
998 | ExitOnFailure(hr, "Failed to format relation type for command-line."); | ||
999 | |||
1000 | hr = StrAllocConcat(psczCommandLine, scz, 0); | ||
1001 | ExitOnFailure(hr, "Failed to append relation type to command-line."); | 1007 | ExitOnFailure(hr, "Failed to append relation type to command-line."); |
1002 | } | 1008 | } |
1003 | 1009 | ||
1004 | if (fPassthrough) | 1010 | if (fPassthrough) |
1005 | { | 1011 | { |
1006 | hr = StrAllocFormatted(&scz, L" /%ls", BURN_COMMANDLINE_SWITCH_PASSTHROUGH); | 1012 | hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls", BURN_COMMANDLINE_SWITCH_PASSTHROUGH); |
1007 | ExitOnFailure(hr, "Failed to format passthrough for command-line."); | ||
1008 | |||
1009 | hr = StrAllocConcat(psczCommandLine, scz, 0); | ||
1010 | ExitOnFailure(hr, "Failed to append passthrough to command-line."); | 1013 | ExitOnFailure(hr, "Failed to append passthrough to command-line."); |
1011 | } | 1014 | } |
1012 | 1015 | ||
1013 | if (wzAppendLogPath && *wzAppendLogPath) | 1016 | if (pCommand->wzCommandLine && *pCommand->wzCommandLine) |
1014 | { | 1017 | { |
1015 | hr = StrAllocFormatted(&scz, L" /%ls \"%ls\"", BURN_COMMANDLINE_SWITCH_LOG_APPEND, wzAppendLogPath); | 1018 | hr = StrAllocConcatFormattedSecure(psczCommandLine, L" %ls", pCommand->wzCommandLine); |
1016 | ExitOnFailure(hr, "Failed to format append log command-line for command-line."); | 1019 | ExitOnFailure(hr, "Failed to append command-line to command-line."); |
1020 | } | ||
1017 | 1021 | ||
1018 | hr = StrAllocConcat(psczCommandLine, scz, 0); | 1022 | LExit: |
1019 | ExitOnFailure(hr, "Failed to append log command-line to command-line"); | 1023 | ReleaseStr(scz); |
1024 | |||
1025 | return hr; | ||
1026 | } | ||
1027 | |||
1028 | extern "C" HRESULT CoreCreateCleanRoomCommandLine( | ||
1029 | __deref_inout_z LPWSTR* psczCommandLine, | ||
1030 | __in BURN_ENGINE_STATE* pEngineState, | ||
1031 | __in_z LPCWSTR wzCleanRoomBundlePath, | ||
1032 | __in_z LPCWSTR wzCurrentProcessPath, | ||
1033 | __inout HANDLE* phFileAttached, | ||
1034 | __inout HANDLE* phFileSelf | ||
1035 | ) | ||
1036 | { | ||
1037 | HRESULT hr = S_OK; | ||
1038 | BOOTSTRAPPER_COMMAND* pCommand = &pEngineState->command; | ||
1039 | BURN_ENGINE_COMMAND* pInternalCommand = &pEngineState->internalCommand; | ||
1040 | |||
1041 | // The clean room switch must always be at the front of the command line so | ||
1042 | // the EngineInCleanRoom function will operate correctly. | ||
1043 | hr = StrAllocFormatted(psczCommandLine, L"-%ls=\"%ls\"", BURN_COMMANDLINE_SWITCH_CLEAN_ROOM, wzCurrentProcessPath); | ||
1044 | ExitOnFailure(hr, "Failed to allocate parameters for unelevated process."); | ||
1045 | |||
1046 | // Send a file handle for the child Burn process to access the attached container. | ||
1047 | hr = CoreAppendFileHandleAttachedToCommandLine(pEngineState->section.hEngineFile, phFileAttached, psczCommandLine); | ||
1048 | ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED); | ||
1049 | |||
1050 | // Grab a file handle for the child Burn process. | ||
1051 | hr = CoreAppendFileHandleSelfToCommandLine(wzCleanRoomBundlePath, phFileSelf, psczCommandLine, NULL); | ||
1052 | ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF); | ||
1053 | |||
1054 | hr = CoreAppendSplashScreenWindowToCommandLine(pCommand->hwndSplashScreen, psczCommandLine); | ||
1055 | ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_SPLASH_SCREEN); | ||
1056 | |||
1057 | if (pInternalCommand->sczLogFile) | ||
1058 | { | ||
1059 | LPCWSTR wzLogParameter = (BURN_LOGGING_ATTRIBUTE_EXTRADEBUG & pInternalCommand->dwLoggingAttributes) ? L"xlog" : L"log"; | ||
1060 | hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls", wzLogParameter); | ||
1061 | ExitOnFailure(hr, "Failed to append logging switch."); | ||
1062 | |||
1063 | hr = PathCommandLineAppend(psczCommandLine, pInternalCommand->sczLogFile); | ||
1064 | ExitOnFailure(hr, "Failed to append custom log path."); | ||
1020 | } | 1065 | } |
1021 | 1066 | ||
1022 | if (pCommand->wzCommandLine && *pCommand->wzCommandLine) | 1067 | hr = AppendLayoutToCommandLine(pCommand->action, pCommand->wzLayoutDirectory, psczCommandLine); |
1068 | ExitOnFailure(hr, "Failed to append layout."); | ||
1069 | |||
1070 | switch (pInternalCommand->automaticUpdates) | ||
1023 | { | 1071 | { |
1024 | hr = StrAllocConcat(psczCommandLine, L" ", 0); | 1072 | case BURN_AU_PAUSE_ACTION_NONE: |
1025 | ExitOnFailure(hr, "Failed to append space to command-line."); | 1073 | hr = StrAllocConcat(psczCommandLine, L" /noaupause", 0); |
1074 | ExitOnFailure(hr, "Failed to append /noaupause."); | ||
1075 | break; | ||
1076 | case BURN_AU_PAUSE_ACTION_IFELEVATED_NORESUME: | ||
1077 | hr = StrAllocConcat(psczCommandLine, L" /keepaupaused", 0); | ||
1078 | ExitOnFailure(hr, "Failed to append /keepaupaused."); | ||
1079 | break; | ||
1080 | } | ||
1026 | 1081 | ||
1027 | hr = StrAllocConcat(psczCommandLine, pCommand->wzCommandLine, 0); | 1082 | // TODO: This should only be added if it was enabled from the command line. |
1028 | ExitOnFailure(hr, "Failed to append command-line to command-line."); | 1083 | if (pInternalCommand->fDisableSystemRestore) |
1084 | { | ||
1085 | hr = StrAllocConcat(psczCommandLine, L" /disablesystemrestore", 0); | ||
1086 | ExitOnFailure(hr, "Failed to append /disablesystemrestore."); | ||
1087 | } | ||
1088 | |||
1089 | #ifdef ENABLE_UNELEVATE | ||
1090 | if (pInternalCommand->fDisableUnelevate) | ||
1091 | { | ||
1092 | hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls", BURN_COMMANDLINE_SWITCH_DISABLE_UNELEVATE); | ||
1093 | ExitOnFailure(hr, "Failed to append switch: %ls.", BURN_COMMANDLINE_SWITCH_DISABLE_UNELEVATE); | ||
1094 | } | ||
1095 | #endif | ||
1096 | |||
1097 | if (pInternalCommand->sczOriginalSource) | ||
1098 | { | ||
1099 | hr = StrAllocConcat(psczCommandLine, L" /originalsource", 0); | ||
1100 | ExitOnFailure(hr, "Failed to append /originalsource."); | ||
1101 | |||
1102 | hr = PathCommandLineAppend(psczCommandLine, pInternalCommand->sczOriginalSource); | ||
1103 | ExitOnFailure(hr, "Failed to append original source."); | ||
1104 | } | ||
1105 | |||
1106 | if (pEngineState->embeddedConnection.sczName) | ||
1107 | { | ||
1108 | hr = StrAllocConcatFormatted(psczCommandLine, L" -%ls %ls %ls %u", BURN_COMMANDLINE_SWITCH_EMBEDDED, pEngineState->embeddedConnection.sczName, pEngineState->embeddedConnection.sczSecret, pEngineState->embeddedConnection.dwProcessId); | ||
1109 | ExitOnFailure(hr, "Failed to allocate embedded command."); | ||
1110 | } | ||
1111 | |||
1112 | if (pInternalCommand->sczIgnoreDependencies) | ||
1113 | { | ||
1114 | hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls=%ls", BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES, pInternalCommand->sczIgnoreDependencies); | ||
1115 | ExitOnFailure(hr, "Failed to append ignored dependencies to command-line."); | ||
1029 | } | 1116 | } |
1030 | 1117 | ||
1118 | hr = CoreRecreateCommandLine(psczCommandLine, pCommand->action, pInternalCommand, pCommand, pCommand->relationType, pCommand->fPassthrough); | ||
1119 | ExitOnFailure(hr, "Failed to recreate clean room command-line."); | ||
1120 | |||
1031 | LExit: | 1121 | LExit: |
1032 | ReleaseStr(scz); | 1122 | return hr; |
1123 | } | ||
1033 | 1124 | ||
1125 | extern "C" HRESULT CoreCreatePassthroughBundleCommandLine( | ||
1126 | __deref_inout_z LPWSTR* psczCommandLine, | ||
1127 | __in BURN_ENGINE_COMMAND* pInternalCommand, | ||
1128 | __in BOOTSTRAPPER_COMMAND* pCommand | ||
1129 | ) | ||
1130 | { | ||
1131 | HRESULT hr = S_OK; | ||
1132 | |||
1133 | // No matter the operation, we're passing the same command-line. | ||
1134 | // That's what makes this a passthrough bundle. | ||
1135 | hr = CoreRecreateCommandLine(psczCommandLine, pCommand->action, pInternalCommand, pCommand, pCommand->relationType, TRUE); | ||
1136 | ExitOnFailure(hr, "Failed to recreate passthrough bundle command-line."); | ||
1137 | |||
1138 | LExit: | ||
1139 | return hr; | ||
1140 | } | ||
1141 | |||
1142 | extern "C" HRESULT CoreCreateResumeCommandLine( | ||
1143 | __deref_inout_z LPWSTR* psczCommandLine, | ||
1144 | __in BURN_PLAN* pPlan, | ||
1145 | __in BURN_LOGGING* pLog | ||
1146 | ) | ||
1147 | { | ||
1148 | HRESULT hr = S_OK; | ||
1149 | |||
1150 | hr = StrAllocFormatted(psczCommandLine, L"/%ls", BURN_COMMANDLINE_SWITCH_CLEAN_ROOM); | ||
1151 | ExitOnFailure(hr, "Failed to alloc resume command-line."); | ||
1152 | |||
1153 | if (BURN_LOGGING_ATTRIBUTE_EXTRADEBUG & pPlan->pInternalCommand->dwLoggingAttributes) | ||
1154 | { | ||
1155 | hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls=%ls", BURN_COMMANDLINE_SWITCH_LOG_MODE, L"x"); | ||
1156 | ExitOnFailure(hr, "Failed to set log mode in resume command-line."); | ||
1157 | } | ||
1158 | |||
1159 | if (pLog->sczPath && *(pLog->sczPath)) | ||
1160 | { | ||
1161 | hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls \"%ls\"", BURN_COMMANDLINE_SWITCH_LOG_APPEND, pLog->sczPath); | ||
1162 | ExitOnFailure(hr, "Failed to set log path in resume command-line."); | ||
1163 | } | ||
1164 | |||
1165 | hr = CoreRecreateCommandLine(psczCommandLine, pPlan->action, pPlan->pInternalCommand, pPlan->pCommand, pPlan->pCommand->relationType, pPlan->pCommand->fPassthrough); | ||
1166 | ExitOnFailure(hr, "Failed to recreate resume command-line."); | ||
1167 | |||
1168 | LExit: | ||
1169 | return hr; | ||
1170 | } | ||
1171 | |||
1172 | extern "C" HRESULT CoreCreateUpdateBundleCommandLine( | ||
1173 | __deref_inout_z LPWSTR* psczCommandLine, | ||
1174 | __in BURN_ENGINE_COMMAND* pInternalCommand, | ||
1175 | __in BOOTSTRAPPER_COMMAND* pCommand | ||
1176 | ) | ||
1177 | { | ||
1178 | HRESULT hr = S_OK; | ||
1179 | |||
1180 | hr = CoreRecreateCommandLine(psczCommandLine, BOOTSTRAPPER_ACTION_INSTALL, pInternalCommand, pCommand, BOOTSTRAPPER_RELATION_NONE, FALSE); | ||
1181 | ExitOnFailure(hr, "Failed to recreate update bundle command-line."); | ||
1182 | |||
1183 | LExit: | ||
1034 | return hr; | 1184 | return hr; |
1035 | } | 1185 | } |
1036 | 1186 | ||
@@ -1334,6 +1484,35 @@ extern "C" HRESULT CoreParseCommandLine( | |||
1334 | 1484 | ||
1335 | pInternalCommand->dwLoggingAttributes |= BURN_LOGGING_ATTRIBUTE_APPEND; | 1485 | pInternalCommand->dwLoggingAttributes |= BURN_LOGGING_ATTRIBUTE_APPEND; |
1336 | } | 1486 | } |
1487 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_LOG_MODE), BURN_COMMANDLINE_SWITCH_LOG_MODE, -1)) | ||
1488 | { | ||
1489 | // Get a pointer to the next character after the switch. | ||
1490 | LPCWSTR wzParam = &argv[i][2 + lstrlenW(BURN_COMMANDLINE_SWITCH_LOG_MODE)]; | ||
1491 | if (L'=' != wzParam[-1] || L'\0' == wzParam[0]) | ||
1492 | { | ||
1493 | fInvalidCommandLine = TRUE; | ||
1494 | TraceLog(E_INVALIDARG, "Missing required parameter for switch: %ls", BURN_COMMANDLINE_SWITCH_LOG_MODE); | ||
1495 | } | ||
1496 | else | ||
1497 | { | ||
1498 | while (L'\0' != wzParam[0]) | ||
1499 | { | ||
1500 | switch (wzParam[0]) | ||
1501 | { | ||
1502 | case L'x': | ||
1503 | pInternalCommand->dwLoggingAttributes |= BURN_LOGGING_ATTRIBUTE_EXTRADEBUG | BURN_LOGGING_ATTRIBUTE_VERBOSE; | ||
1504 | break; | ||
1505 | default: | ||
1506 | // Skip (but log) any other modifiers we don't recognize, | ||
1507 | // so that adding future modifiers doesn't break old bundles. | ||
1508 | LogId(REPORT_STANDARD, MSG_BURN_UNKNOWN_PRIVATE_SWITCH_MODIFIER, BURN_COMMANDLINE_SWITCH_LOG_MODE, wzParam[0]); | ||
1509 | break; | ||
1510 | } | ||
1511 | |||
1512 | ++wzParam; | ||
1513 | } | ||
1514 | } | ||
1515 | } | ||
1337 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_ELEVATED, -1)) | 1516 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_ELEVATED, -1)) |
1338 | { | 1517 | { |
1339 | if (i + 3 >= argc) | 1518 | if (i + 3 >= argc) |
@@ -1462,7 +1641,9 @@ extern "C" HRESULT CoreParseCommandLine( | |||
1462 | } | 1641 | } |
1463 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_DISABLE_UNELEVATE, -1)) | 1642 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_DISABLE_UNELEVATE, -1)) |
1464 | { | 1643 | { |
1644 | #ifdef ENABLE_UNELEVATE | ||
1465 | pInternalCommand->fDisableUnelevate = TRUE; | 1645 | pInternalCommand->fDisableUnelevate = TRUE; |
1646 | #endif | ||
1466 | } | 1647 | } |
1467 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RUNONCE, -1)) | 1648 | else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RUNONCE, -1)) |
1468 | { | 1649 | { |
@@ -1628,6 +1809,30 @@ LExit: | |||
1628 | 1809 | ||
1629 | // internal helper functions | 1810 | // internal helper functions |
1630 | 1811 | ||
1812 | static HRESULT AppendLayoutToCommandLine( | ||
1813 | __in BOOTSTRAPPER_ACTION action, | ||
1814 | __in_z LPCWSTR wzLayoutDirectory, | ||
1815 | __deref_inout_z LPWSTR* psczCommandLine | ||
1816 | ) | ||
1817 | { | ||
1818 | HRESULT hr = S_OK; | ||
1819 | |||
1820 | if (BOOTSTRAPPER_ACTION_LAYOUT == action || wzLayoutDirectory) | ||
1821 | { | ||
1822 | hr = StrAllocConcat(psczCommandLine, L" /layout", 0); | ||
1823 | ExitOnFailure(hr, "Failed to append layout switch."); | ||
1824 | |||
1825 | if (wzLayoutDirectory) | ||
1826 | { | ||
1827 | hr = PathCommandLineAppend(psczCommandLine, wzLayoutDirectory); | ||
1828 | ExitOnFailure(hr, "Failed to append layout directory."); | ||
1829 | } | ||
1830 | } | ||
1831 | |||
1832 | LExit: | ||
1833 | return hr; | ||
1834 | } | ||
1835 | |||
1631 | static HRESULT GetSanitizedCommandLine( | 1836 | static HRESULT GetSanitizedCommandLine( |
1632 | __in BURN_ENGINE_COMMAND* pInternalCommand, | 1837 | __in BURN_ENGINE_COMMAND* pInternalCommand, |
1633 | __in BOOTSTRAPPER_COMMAND* pCommand, | 1838 | __in BOOTSTRAPPER_COMMAND* pCommand, |