aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-08-03 15:42:08 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-08-04 10:03:57 -0500
commit94b8260fc5c1abc199f8d6145f3db4e2de490463 (patch)
treef8aeebc5b8d3facdab8232f60098ed253b3019cf
parent9ae1c04d5fa02ac020885cdad7c592f7bb43d83e (diff)
downloadwix-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
-rw-r--r--src/burn/engine/core.cpp263
-rw-r--r--src/burn/engine/core.h29
-rw-r--r--src/burn/engine/engine.cpp24
-rw-r--r--src/burn/engine/engine.mc7
-rw-r--r--src/burn/engine/externalengine.cpp4
-rw-r--r--src/burn/engine/plan.cpp7
-rw-r--r--src/burn/engine/pseudobundle.cpp7
-rw-r--r--src/burn/engine/pseudobundle.h1
-rw-r--r--src/burn/engine/registration.cpp8
-rw-r--r--src/burn/test/BurnUnitTest/RegistrationTest.cpp12
10 files changed, 284 insertions, 78 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
17static 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 );
25static HRESULT AppendLayoutToCommandLine(
26 __in BOOTSTRAPPER_ACTION action,
27 __in_z LPCWSTR wzLayoutDirectory,
28 __deref_inout_z LPWSTR* psczCommandLine
29 );
17static HRESULT GetSanitizedCommandLine( 30static 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
927extern "C" HRESULT CoreRecreateCommandLine( 940static 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); 1022LExit:
1019 ExitOnFailure(hr, "Failed to append log command-line to command-line"); 1023 ReleaseStr(scz);
1024
1025 return hr;
1026}
1027
1028extern "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
1031LExit: 1121LExit:
1032 ReleaseStr(scz); 1122 return hr;
1123}
1033 1124
1125extern "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
1138LExit:
1139 return hr;
1140}
1141
1142extern "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
1168LExit:
1169 return hr;
1170}
1171
1172extern "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
1183LExit:
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
1812static 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
1832LExit:
1833 return hr;
1834}
1835
1631static HRESULT GetSanitizedCommandLine( 1836static HRESULT GetSanitizedCommandLine(
1632 __in BURN_ENGINE_COMMAND* pInternalCommand, 1837 __in BURN_ENGINE_COMMAND* pInternalCommand,
1633 __in BOOTSTRAPPER_COMMAND* pCommand, 1838 __in BOOTSTRAPPER_COMMAND* pCommand,
diff --git a/src/burn/engine/core.h b/src/burn/engine/core.h
index ec557d48..fb6c0668 100644
--- a/src/burn/engine/core.h
+++ b/src/burn/engine/core.h
@@ -18,6 +18,7 @@ const LPCWSTR BURN_COMMANDLINE_SWITCH_ELEVATED = L"burn.elevated";
18const LPCWSTR BURN_COMMANDLINE_SWITCH_EMBEDDED = L"burn.embedded"; 18const LPCWSTR BURN_COMMANDLINE_SWITCH_EMBEDDED = L"burn.embedded";
19const LPCWSTR BURN_COMMANDLINE_SWITCH_RUNONCE = L"burn.runonce"; 19const LPCWSTR BURN_COMMANDLINE_SWITCH_RUNONCE = L"burn.runonce";
20const LPCWSTR BURN_COMMANDLINE_SWITCH_LOG_APPEND = L"burn.log.append"; 20const LPCWSTR BURN_COMMANDLINE_SWITCH_LOG_APPEND = L"burn.log.append";
21const LPCWSTR BURN_COMMANDLINE_SWITCH_LOG_MODE = L"burn.log.mode";
21const LPCWSTR BURN_COMMANDLINE_SWITCH_RELATED_DETECT = L"burn.related.detect"; 22const LPCWSTR BURN_COMMANDLINE_SWITCH_RELATED_DETECT = L"burn.related.detect";
22const LPCWSTR BURN_COMMANDLINE_SWITCH_RELATED_UPGRADE = L"burn.related.upgrade"; 23const LPCWSTR BURN_COMMANDLINE_SWITCH_RELATED_UPGRADE = L"burn.related.upgrade";
23const LPCWSTR BURN_COMMANDLINE_SWITCH_RELATED_ADDON = L"burn.related.addon"; 24const LPCWSTR BURN_COMMANDLINE_SWITCH_RELATED_ADDON = L"burn.related.addon";
@@ -89,7 +90,9 @@ typedef struct _BURN_ENGINE_COMMAND
89 BURN_MODE mode; 90 BURN_MODE mode;
90 BURN_AU_PAUSE_ACTION automaticUpdates; 91 BURN_AU_PAUSE_ACTION automaticUpdates;
91 BOOL fDisableSystemRestore; 92 BOOL fDisableSystemRestore;
93#ifdef ENABLE_UNELEVATE
92 BOOL fDisableUnelevate; 94 BOOL fDisableUnelevate;
95#endif
93 BOOL fInitiallyElevated; 96 BOOL fInitiallyElevated;
94 97
95 LPWSTR sczActiveParent; 98 LPWSTR sczActiveParent;
@@ -215,14 +218,28 @@ HRESULT CoreSaveEngineState(
215LPCWSTR CoreRelationTypeToCommandLineString( 218LPCWSTR CoreRelationTypeToCommandLineString(
216 __in BOOTSTRAPPER_RELATION_TYPE relationType 219 __in BOOTSTRAPPER_RELATION_TYPE relationType
217 ); 220 );
218HRESULT CoreRecreateCommandLine( 221HRESULT CoreCreateCleanRoomCommandLine(
222 __deref_inout_z LPWSTR* psczCommandLine,
223 __in BURN_ENGINE_STATE* pEngineState,
224 __in_z LPCWSTR wzCleanRoomBundlePath,
225 __in_z LPCWSTR wzCurrentProcessPath,
226 __inout HANDLE* phFileAttached,
227 __inout HANDLE* phFileSelf
228 );
229HRESULT CoreCreatePassthroughBundleCommandLine(
219 __deref_inout_z LPWSTR* psczCommandLine, 230 __deref_inout_z LPWSTR* psczCommandLine,
220 __in BOOTSTRAPPER_ACTION action,
221 __in BURN_ENGINE_COMMAND* pInternalCommand, 231 __in BURN_ENGINE_COMMAND* pInternalCommand,
222 __in BOOTSTRAPPER_COMMAND* pCommand, 232 __in BOOTSTRAPPER_COMMAND* pCommand
223 __in BOOTSTRAPPER_RELATION_TYPE relationType, 233 );
224 __in BOOL fPassthrough, 234HRESULT CoreCreateResumeCommandLine(
225 __in_z_opt LPCWSTR wzAppendLogPath 235 __deref_inout_z LPWSTR* psczCommandLine,
236 __in BURN_PLAN* pPlan,
237 __in BURN_LOGGING* pLog
238 );
239HRESULT CoreCreateUpdateBundleCommandLine(
240 __deref_inout_z LPWSTR* psczCommandLine,
241 __in BURN_ENGINE_COMMAND* pInternalCommand,
242 __in BOOTSTRAPPER_COMMAND* pCommand
226 ); 243 );
227HRESULT CoreAppendFileHandleAttachedToCommandLine( 244HRESULT CoreAppendFileHandleAttachedToCommandLine(
228 __in HANDLE hFileWithAttachedContainer, 245 __in HANDLE hFileWithAttachedContainer,
diff --git a/src/burn/engine/engine.cpp b/src/burn/engine/engine.cpp
index e65600b5..99471e0d 100644
--- a/src/burn/engine/engine.cpp
+++ b/src/burn/engine/engine.cpp
@@ -17,7 +17,6 @@ static void UninitializeEngineState(
17 __in BURN_ENGINE_STATE* pEngineState 17 __in BURN_ENGINE_STATE* pEngineState
18 ); 18 );
19static HRESULT RunUntrusted( 19static HRESULT RunUntrusted(
20 __in LPCWSTR wzCommandLine,
21 __in BURN_ENGINE_STATE* pEngineState 20 __in BURN_ENGINE_STATE* pEngineState
22 ); 21 );
23static HRESULT RunNormal( 22static HRESULT RunNormal(
@@ -195,7 +194,7 @@ extern "C" HRESULT EngineRun(
195 switch (engineState.internalCommand.mode) 194 switch (engineState.internalCommand.mode)
196 { 195 {
197 case BURN_MODE_UNTRUSTED: 196 case BURN_MODE_UNTRUSTED:
198 hr = RunUntrusted(wzCommandLine, &engineState); 197 hr = RunUntrusted(&engineState);
199 ExitOnFailure(hr, "Failed to run untrusted mode."); 198 ExitOnFailure(hr, "Failed to run untrusted mode.");
200 break; 199 break;
201 200
@@ -411,7 +410,6 @@ static void UninitializeEngineState(
411} 410}
412 411
413static HRESULT RunUntrusted( 412static HRESULT RunUntrusted(
414 __in LPCWSTR wzCommandLine,
415 __in BURN_ENGINE_STATE* pEngineState 413 __in BURN_ENGINE_STATE* pEngineState
416 ) 414 )
417{ 415{
@@ -450,24 +448,8 @@ static HRESULT RunUntrusted(
450 wzCleanRoomBundlePath = sczCachedCleanRoomBundlePath; 448 wzCleanRoomBundlePath = sczCachedCleanRoomBundlePath;
451 } 449 }
452 450
453 // The clean room switch must always be at the front of the command line so 451 hr = CoreCreateCleanRoomCommandLine(&sczParameters, pEngineState, wzCleanRoomBundlePath, sczCurrentProcessPath, &hFileAttached, &hFileSelf);
454 // the EngineInCleanRoom function will operate correctly. 452 ExitOnFailure(hr, "Failed to create clean room command-line.");
455 hr = StrAllocFormatted(&sczParameters, L"-%ls=\"%ls\"", BURN_COMMANDLINE_SWITCH_CLEAN_ROOM, sczCurrentProcessPath);
456 ExitOnFailure(hr, "Failed to allocate parameters for unelevated process.");
457
458 // Send a file handle for the child Burn process to access the attached container.
459 hr = CoreAppendFileHandleAttachedToCommandLine(pEngineState->section.hEngineFile, &hFileAttached, &sczParameters);
460 ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED);
461
462 // Grab a file handle for the child Burn process.
463 hr = CoreAppendFileHandleSelfToCommandLine(wzCleanRoomBundlePath, &hFileSelf, &sczParameters, NULL);
464 ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF);
465
466 hr = CoreAppendSplashScreenWindowToCommandLine(pEngineState->command.hwndSplashScreen, &sczParameters);
467 ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_SPLASH_SCREEN);
468
469 hr = StrAllocConcatFormattedSecure(&sczParameters, L" %ls", wzCommandLine);
470 ExitOnFailure(hr, "Failed to append original command line.");
471 453
472#ifdef ENABLE_UNELEVATE 454#ifdef ENABLE_UNELEVATE
473 // TODO: Pass file handle to unelevated process if this ever gets reenabled. 455 // TODO: Pass file handle to unelevated process if this ever gets reenabled.
diff --git a/src/burn/engine/engine.mc b/src/burn/engine/engine.mc
index 77590223..a587415d 100644
--- a/src/burn/engine/engine.mc
+++ b/src/burn/engine/engine.mc
@@ -135,6 +135,13 @@ Language=English
135Failed to parse command line. 135Failed to parse command line.
136. 136.
137 137
138MessageId=16
139Severity=Warning
140SymbolicName=MSG_BURN_UNKNOWN_PRIVATE_SWITCH_MODIFIER
141Language=English
142Unknown burn internal command-line switch modifier encountered, switch: '%1!ls!', modifier: '%2!c!'.
143.
144
138MessageId=51 145MessageId=51
139Severity=Error 146Severity=Error
140SymbolicName=MSG_FAILED_PARSE_CONDITION 147SymbolicName=MSG_FAILED_PARSE_CONDITION
diff --git a/src/burn/engine/externalengine.cpp b/src/burn/engine/externalengine.cpp
index 27db35cc..da84c83d 100644
--- a/src/burn/engine/externalengine.cpp
+++ b/src/burn/engine/externalengine.cpp
@@ -295,8 +295,8 @@ HRESULT ExternalEngineSetUpdate(
295 { 295 {
296 UpdateUninitialize(&pEngineState->update); 296 UpdateUninitialize(&pEngineState->update);
297 297
298 hr = CoreRecreateCommandLine(&sczCommandline, BOOTSTRAPPER_ACTION_INSTALL, &pEngineState->internalCommand, &pEngineState->command, BOOTSTRAPPER_RELATION_NONE, FALSE, NULL); 298 hr = CoreCreateUpdateBundleCommandLine(&sczCommandline, &pEngineState->internalCommand, &pEngineState->command);
299 ExitOnFailure(hr, "Failed to recreate command-line for update bundle."); 299 ExitOnFailure(hr, "Failed to create command-line for update bundle.");
300 300
301 // Bundles would fail to use the downloaded update bundle, as the running bundle would be one of the search paths. 301 // Bundles would fail to use the downloaded update bundle, as the running bundle would be one of the search paths.
302 // Here I am generating a random guid, but in the future it would be nice if the feed would provide the ID of the update. 302 // Here I am generating a random guid, but in the future it would be nice if the feed would provide the ID of the update.
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp
index f3d37978..f77e8e2a 100644
--- a/src/burn/engine/plan.cpp
+++ b/src/burn/engine/plan.cpp
@@ -479,7 +479,7 @@ extern "C" HRESULT PlanForwardCompatibleBundles(
479 479
480 if (!fIgnoreBundle) 480 if (!fIgnoreBundle)
481 { 481 {
482 hr = PseudoBundleInitializePassthrough(&pPlan->forwardCompatibleBundle, pPlan->pInternalCommand, pPlan->pCommand, NULL, &pRelatedBundle->package); 482 hr = PseudoBundleInitializePassthrough(&pPlan->forwardCompatibleBundle, pPlan->pInternalCommand, pPlan->pCommand, &pRelatedBundle->package);
483 ExitOnFailure(hr, "Failed to initialize pass through bundle."); 483 ExitOnFailure(hr, "Failed to initialize pass through bundle.");
484 484
485 pPlan->fEnabledForwardCompatibleBundle = TRUE; 485 pPlan->fEnabledForwardCompatibleBundle = TRUE;
@@ -1780,11 +1780,10 @@ extern "C" HRESULT PlanSetResumeCommand(
1780 ) 1780 )
1781{ 1781{
1782 HRESULT hr = S_OK; 1782 HRESULT hr = S_OK;
1783 BOOTSTRAPPER_COMMAND* pCommand = pPlan->pCommand;
1784 1783
1785 // build the resume command-line. 1784 // build the resume command-line.
1786 hr = CoreRecreateCommandLine(&pRegistration->sczResumeCommandLine, pPlan->action, pPlan->pInternalCommand, pCommand, pCommand->relationType, pCommand->fPassthrough, pLog->sczPath); 1785 hr = CoreCreateResumeCommandLine(&pRegistration->sczResumeCommandLine, pPlan, pLog);
1787 ExitOnFailure(hr, "Failed to recreate resume command-line."); 1786 ExitOnFailure(hr, "Failed to create resume command-line.");
1788 1787
1789LExit: 1788LExit:
1790 return hr; 1789 return hr;
diff --git a/src/burn/engine/pseudobundle.cpp b/src/burn/engine/pseudobundle.cpp
index 00007247..52b7bd8a 100644
--- a/src/burn/engine/pseudobundle.cpp
+++ b/src/burn/engine/pseudobundle.cpp
@@ -165,7 +165,6 @@ extern "C" HRESULT PseudoBundleInitializePassthrough(
165 __in BURN_PACKAGE* pPassthroughPackage, 165 __in BURN_PACKAGE* pPassthroughPackage,
166 __in BURN_ENGINE_COMMAND* pInternalCommand, 166 __in BURN_ENGINE_COMMAND* pInternalCommand,
167 __in BOOTSTRAPPER_COMMAND* pCommand, 167 __in BOOTSTRAPPER_COMMAND* pCommand,
168 __in_z_opt LPCWSTR wzAppendLogPath,
169 __in BURN_PACKAGE* pPackage 168 __in BURN_PACKAGE* pPackage
170 ) 169 )
171{ 170{
@@ -202,10 +201,8 @@ extern "C" HRESULT PseudoBundleInitializePassthrough(
202 201
203 pPassthroughPackage->Exe.protocol = pPackage->Exe.protocol; 202 pPassthroughPackage->Exe.protocol = pPackage->Exe.protocol;
204 203
205 // No matter the operation, we're passing the same command-line. That's what makes 204 hr = CoreCreatePassthroughBundleCommandLine(&sczArguments, pInternalCommand, pCommand);
206 // this a passthrough bundle. 205 ExitOnFailure(hr, "Failed to create command-line arguments.");
207 hr = CoreRecreateCommandLine(&sczArguments, pCommand->action, pInternalCommand, pCommand, pCommand->relationType, TRUE, wzAppendLogPath);
208 ExitOnFailure(hr, "Failed to recreate command-line arguments.");
209 206
210 hr = StrAllocString(&pPassthroughPackage->Exe.sczInstallArguments, sczArguments, 0); 207 hr = StrAllocString(&pPassthroughPackage->Exe.sczInstallArguments, sczArguments, 0);
211 ExitOnFailure(hr, "Failed to copy install arguments for passthrough bundle package"); 208 ExitOnFailure(hr, "Failed to copy install arguments for passthrough bundle package");
diff --git a/src/burn/engine/pseudobundle.h b/src/burn/engine/pseudobundle.h
index 5c4ca836..aa26d29d 100644
--- a/src/burn/engine/pseudobundle.h
+++ b/src/burn/engine/pseudobundle.h
@@ -30,7 +30,6 @@ HRESULT PseudoBundleInitializePassthrough(
30 __in BURN_PACKAGE* pPassthroughPackage, 30 __in BURN_PACKAGE* pPassthroughPackage,
31 __in BURN_ENGINE_COMMAND* pInternalCommand, 31 __in BURN_ENGINE_COMMAND* pInternalCommand,
32 __in BOOTSTRAPPER_COMMAND* pCommand, 32 __in BOOTSTRAPPER_COMMAND* pCommand,
33 __in_z_opt LPCWSTR wzAppendLogPath,
34 __in BURN_PACKAGE* pPackage 33 __in BURN_PACKAGE* pPackage
35 ); 34 );
36 35
diff --git a/src/burn/engine/registration.cpp b/src/burn/engine/registration.cpp
index 0fb9da5b..54a5a928 100644
--- a/src/burn/engine/registration.cpp
+++ b/src/burn/engine/registration.cpp
@@ -1322,7 +1322,7 @@ static HRESULT UpdateResumeMode(
1322 DWORD er = ERROR_SUCCESS; 1322 DWORD er = ERROR_SUCCESS;
1323 HKEY hkRebootRequired = NULL; 1323 HKEY hkRebootRequired = NULL;
1324 HKEY hkRun = NULL; 1324 HKEY hkRun = NULL;
1325 LPWSTR sczResumeCommandLine = NULL; 1325 LPWSTR sczRunOnceCommandLine = NULL;
1326 LPCWSTR sczResumeKey = REGISTRY_RUN_ONCE_KEY; 1326 LPCWSTR sczResumeKey = REGISTRY_RUN_ONCE_KEY;
1327 1327
1328 LogId(REPORT_STANDARD, MSG_SESSION_UPDATE, pRegistration->sczRegistrationKey, LoggingResumeModeToString(resumeMode), LoggingBoolToString(fRestartInitiated), LoggingBoolToString(pRegistration->fDisableResume)); 1328 LogId(REPORT_STANDARD, MSG_SESSION_UPDATE, pRegistration->sczRegistrationKey, LoggingResumeModeToString(resumeMode), LoggingBoolToString(fRestartInitiated), LoggingBoolToString(pRegistration->fDisableResume));
@@ -1354,14 +1354,14 @@ static HRESULT UpdateResumeMode(
1354 if ((BURN_RESUME_MODE_ACTIVE == resumeMode || fRestartInitiated) && !pRegistration->fDisableResume) 1354 if ((BURN_RESUME_MODE_ACTIVE == resumeMode || fRestartInitiated) && !pRegistration->fDisableResume)
1355 { 1355 {
1356 // append RunOnce switch 1356 // append RunOnce switch
1357 hr = StrAllocFormatted(&sczResumeCommandLine, L"\"%ls\" /%ls", pRegistration->sczCacheExecutablePath, BURN_COMMANDLINE_SWITCH_RUNONCE); 1357 hr = StrAllocFormatted(&sczRunOnceCommandLine, L"\"%ls\" /%ls /%ls", pRegistration->sczCacheExecutablePath, BURN_COMMANDLINE_SWITCH_CLEAN_ROOM, BURN_COMMANDLINE_SWITCH_RUNONCE);
1358 ExitOnFailure(hr, "Failed to format resume command line for RunOnce."); 1358 ExitOnFailure(hr, "Failed to format resume command line for RunOnce.");
1359 1359
1360 // write run key 1360 // write run key
1361 hr = RegCreate(pRegistration->hkRoot, sczResumeKey, KEY_WRITE, &hkRun); 1361 hr = RegCreate(pRegistration->hkRoot, sczResumeKey, KEY_WRITE, &hkRun);
1362 ExitOnFailure(hr, "Failed to create run key."); 1362 ExitOnFailure(hr, "Failed to create run key.");
1363 1363
1364 hr = RegWriteString(hkRun, pRegistration->sczId, sczResumeCommandLine); 1364 hr = RegWriteString(hkRun, pRegistration->sczId, sczRunOnceCommandLine);
1365 ExitOnFailure(hr, "Failed to write run key value."); 1365 ExitOnFailure(hr, "Failed to write run key value.");
1366 1366
1367 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_RESUME_COMMAND_LINE, pRegistration->sczResumeCommandLine); 1367 hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_RESUME_COMMAND_LINE, pRegistration->sczResumeCommandLine);
@@ -1398,7 +1398,7 @@ static HRESULT UpdateResumeMode(
1398 } 1398 }
1399 1399
1400LExit: 1400LExit:
1401 ReleaseStr(sczResumeCommandLine); 1401 ReleaseStr(sczRunOnceCommandLine);
1402 ReleaseRegKey(hkRebootRequired); 1402 ReleaseRegKey(hkRebootRequired);
1403 ReleaseRegKey(hkRun); 1403 ReleaseRegKey(hkRun);
1404 1404
diff --git a/src/burn/test/BurnUnitTest/RegistrationTest.cpp b/src/burn/test/BurnUnitTest/RegistrationTest.cpp
index 32ff9ea2..94937ef6 100644
--- a/src/burn/test/BurnUnitTest/RegistrationTest.cpp
+++ b/src/burn/test/BurnUnitTest/RegistrationTest.cpp
@@ -133,7 +133,7 @@ namespace Bootstrapper
133 Assert::True(File::Exists(Path::Combine(cacheDirectory, gcnew String(L"setup.exe")))); 133 Assert::True(File::Exists(Path::Combine(cacheDirectory, gcnew String(L"setup.exe"))));
134 134
135 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 135 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
136 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)(Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr))); 136 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)(Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)));
137 137
138 // end session 138 // end session
139 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 139 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
@@ -234,7 +234,7 @@ namespace Bootstrapper
234 // verify that registration was created 234 // verify that registration was created
235 Assert::Equal<String^>(gcnew String(L"Product1 Installation"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayName"), nullptr)); 235 Assert::Equal<String^>(gcnew String(L"Product1 Installation"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayName"), nullptr));
236 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 236 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
237 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 237 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
238 238
239 // complete registration 239 // complete registration
240 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS); 240 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
@@ -256,7 +256,7 @@ namespace Bootstrapper
256 // verify that registration was updated 256 // verify that registration was updated
257 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 257 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
258 Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); 258 Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr));
259 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 259 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
260 260
261 // delete registration 261 // delete registration
262 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 262 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
@@ -355,7 +355,7 @@ namespace Bootstrapper
355 355
356 // verify that registration was created 356 // verify that registration was created
357 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 357 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
358 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 358 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
359 359
360 // complete registration 360 // complete registration
361 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL); 361 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL);
@@ -477,7 +477,7 @@ namespace Bootstrapper
477 477
478 // verify that registration was created 478 // verify that registration was created
479 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 479 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
480 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 480 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
481 481
482 // finish registration 482 // finish registration
483 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL); 483 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL);
@@ -510,7 +510,7 @@ namespace Bootstrapper
510 510
511 // verify that registration was updated 511 // verify that registration was updated
512 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); 512 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
513 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr)); 513 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.clean.room /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(TEST_BUNDLE_ID), nullptr));
514 514
515 // delete registration 515 // delete registration
516 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); 516 hr = RegistrationSessionEnd(&registration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);