From 94b8260fc5c1abc199f8d6145f3db4e2de490463 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Tue, 3 Aug 2021 15:42:08 -0500 Subject: Recreate the command line for the clean room process. Persist /xlog when resuming from RunOnce. Fixes #6259 --- src/burn/engine/core.cpp | 263 +++++++++++++++++++++--- src/burn/engine/core.h | 29 ++- src/burn/engine/engine.cpp | 24 +-- src/burn/engine/engine.mc | 7 + src/burn/engine/externalengine.cpp | 4 +- src/burn/engine/plan.cpp | 7 +- src/burn/engine/pseudobundle.cpp | 7 +- src/burn/engine/pseudobundle.h | 1 - src/burn/engine/registration.cpp | 8 +- src/burn/test/BurnUnitTest/RegistrationTest.cpp | 12 +- 10 files changed, 284 insertions(+), 78 deletions(-) (limited to 'src/burn') 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 // internal function declarations +static HRESULT CoreRecreateCommandLine( + __deref_inout_z LPWSTR* psczCommandLine, + __in BOOTSTRAPPER_ACTION action, + __in BURN_ENGINE_COMMAND* pInternalCommand, + __in BOOTSTRAPPER_COMMAND* pCommand, + __in BOOTSTRAPPER_RELATION_TYPE relationType, + __in BOOL fPassthrough + ); +static HRESULT AppendLayoutToCommandLine( + __in BOOTSTRAPPER_ACTION action, + __in_z LPCWSTR wzLayoutDirectory, + __deref_inout_z LPWSTR* psczCommandLine + ); static HRESULT GetSanitizedCommandLine( __in BURN_ENGINE_COMMAND* pInternalCommand, __in BOOTSTRAPPER_COMMAND* pCommand, @@ -924,23 +937,19 @@ extern "C" LPCWSTR CoreRelationTypeToCommandLineString( return wzRelationTypeCommandLine; } -extern "C" HRESULT CoreRecreateCommandLine( +static HRESULT CoreRecreateCommandLine( __deref_inout_z LPWSTR* psczCommandLine, __in BOOTSTRAPPER_ACTION action, __in BURN_ENGINE_COMMAND* pInternalCommand, __in BOOTSTRAPPER_COMMAND* pCommand, __in BOOTSTRAPPER_RELATION_TYPE relationType, - __in BOOL fPassthrough, - __in_z_opt LPCWSTR wzAppendLogPath + __in BOOL fPassthrough ) { HRESULT hr = S_OK; LPWSTR scz = NULL; LPCWSTR wzRelationTypeCommandLine = CoreRelationTypeToCommandLineString(relationType); - hr = StrAllocString(psczCommandLine, L"", 0); - ExitOnFailure(hr, "Failed to empty command line."); - switch (pCommand->display) { case BOOTSTRAPPER_DISPLAY_NONE: @@ -954,6 +963,9 @@ extern "C" HRESULT CoreRecreateCommandLine( switch (action) { + case BOOTSTRAPPER_ACTION_HELP: + hr = StrAllocConcat(psczCommandLine, L" /help", 0); + break; case BOOTSTRAPPER_ACTION_MODIFY: hr = StrAllocConcat(psczCommandLine, L" /modify", 0); break; @@ -985,52 +997,190 @@ extern "C" HRESULT CoreRecreateCommandLine( if (pInternalCommand->sczAncestors) { - hr = StrAllocFormatted(&scz, L" /%ls=%ls", BURN_COMMANDLINE_SWITCH_ANCESTORS, pInternalCommand->sczAncestors); - ExitOnFailure(hr, "Failed to format ancestors for command-line."); - - hr = StrAllocConcat(psczCommandLine, scz, 0); + hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls=%ls", BURN_COMMANDLINE_SWITCH_ANCESTORS, pInternalCommand->sczAncestors); ExitOnFailure(hr, "Failed to append ancestors to command-line."); } if (wzRelationTypeCommandLine) { - hr = StrAllocFormatted(&scz, L" /%ls", wzRelationTypeCommandLine); - ExitOnFailure(hr, "Failed to format relation type for command-line."); - - hr = StrAllocConcat(psczCommandLine, scz, 0); + hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls", wzRelationTypeCommandLine); ExitOnFailure(hr, "Failed to append relation type to command-line."); } if (fPassthrough) { - hr = StrAllocFormatted(&scz, L" /%ls", BURN_COMMANDLINE_SWITCH_PASSTHROUGH); - ExitOnFailure(hr, "Failed to format passthrough for command-line."); - - hr = StrAllocConcat(psczCommandLine, scz, 0); + hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls", BURN_COMMANDLINE_SWITCH_PASSTHROUGH); ExitOnFailure(hr, "Failed to append passthrough to command-line."); } - if (wzAppendLogPath && *wzAppendLogPath) + if (pCommand->wzCommandLine && *pCommand->wzCommandLine) { - hr = StrAllocFormatted(&scz, L" /%ls \"%ls\"", BURN_COMMANDLINE_SWITCH_LOG_APPEND, wzAppendLogPath); - ExitOnFailure(hr, "Failed to format append log command-line for command-line."); + hr = StrAllocConcatFormattedSecure(psczCommandLine, L" %ls", pCommand->wzCommandLine); + ExitOnFailure(hr, "Failed to append command-line to command-line."); + } - hr = StrAllocConcat(psczCommandLine, scz, 0); - ExitOnFailure(hr, "Failed to append log command-line to command-line"); +LExit: + ReleaseStr(scz); + + return hr; +} + +extern "C" HRESULT CoreCreateCleanRoomCommandLine( + __deref_inout_z LPWSTR* psczCommandLine, + __in BURN_ENGINE_STATE* pEngineState, + __in_z LPCWSTR wzCleanRoomBundlePath, + __in_z LPCWSTR wzCurrentProcessPath, + __inout HANDLE* phFileAttached, + __inout HANDLE* phFileSelf + ) +{ + HRESULT hr = S_OK; + BOOTSTRAPPER_COMMAND* pCommand = &pEngineState->command; + BURN_ENGINE_COMMAND* pInternalCommand = &pEngineState->internalCommand; + + // The clean room switch must always be at the front of the command line so + // the EngineInCleanRoom function will operate correctly. + hr = StrAllocFormatted(psczCommandLine, L"-%ls=\"%ls\"", BURN_COMMANDLINE_SWITCH_CLEAN_ROOM, wzCurrentProcessPath); + ExitOnFailure(hr, "Failed to allocate parameters for unelevated process."); + + // Send a file handle for the child Burn process to access the attached container. + hr = CoreAppendFileHandleAttachedToCommandLine(pEngineState->section.hEngineFile, phFileAttached, psczCommandLine); + ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED); + + // Grab a file handle for the child Burn process. + hr = CoreAppendFileHandleSelfToCommandLine(wzCleanRoomBundlePath, phFileSelf, psczCommandLine, NULL); + ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF); + + hr = CoreAppendSplashScreenWindowToCommandLine(pCommand->hwndSplashScreen, psczCommandLine); + ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_SPLASH_SCREEN); + + if (pInternalCommand->sczLogFile) + { + LPCWSTR wzLogParameter = (BURN_LOGGING_ATTRIBUTE_EXTRADEBUG & pInternalCommand->dwLoggingAttributes) ? L"xlog" : L"log"; + hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls", wzLogParameter); + ExitOnFailure(hr, "Failed to append logging switch."); + + hr = PathCommandLineAppend(psczCommandLine, pInternalCommand->sczLogFile); + ExitOnFailure(hr, "Failed to append custom log path."); } - if (pCommand->wzCommandLine && *pCommand->wzCommandLine) + hr = AppendLayoutToCommandLine(pCommand->action, pCommand->wzLayoutDirectory, psczCommandLine); + ExitOnFailure(hr, "Failed to append layout."); + + switch (pInternalCommand->automaticUpdates) { - hr = StrAllocConcat(psczCommandLine, L" ", 0); - ExitOnFailure(hr, "Failed to append space to command-line."); + case BURN_AU_PAUSE_ACTION_NONE: + hr = StrAllocConcat(psczCommandLine, L" /noaupause", 0); + ExitOnFailure(hr, "Failed to append /noaupause."); + break; + case BURN_AU_PAUSE_ACTION_IFELEVATED_NORESUME: + hr = StrAllocConcat(psczCommandLine, L" /keepaupaused", 0); + ExitOnFailure(hr, "Failed to append /keepaupaused."); + break; + } - hr = StrAllocConcat(psczCommandLine, pCommand->wzCommandLine, 0); - ExitOnFailure(hr, "Failed to append command-line to command-line."); + // TODO: This should only be added if it was enabled from the command line. + if (pInternalCommand->fDisableSystemRestore) + { + hr = StrAllocConcat(psczCommandLine, L" /disablesystemrestore", 0); + ExitOnFailure(hr, "Failed to append /disablesystemrestore."); + } + +#ifdef ENABLE_UNELEVATE + if (pInternalCommand->fDisableUnelevate) + { + hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls", BURN_COMMANDLINE_SWITCH_DISABLE_UNELEVATE); + ExitOnFailure(hr, "Failed to append switch: %ls.", BURN_COMMANDLINE_SWITCH_DISABLE_UNELEVATE); + } +#endif + + if (pInternalCommand->sczOriginalSource) + { + hr = StrAllocConcat(psczCommandLine, L" /originalsource", 0); + ExitOnFailure(hr, "Failed to append /originalsource."); + + hr = PathCommandLineAppend(psczCommandLine, pInternalCommand->sczOriginalSource); + ExitOnFailure(hr, "Failed to append original source."); + } + + if (pEngineState->embeddedConnection.sczName) + { + hr = StrAllocConcatFormatted(psczCommandLine, L" -%ls %ls %ls %u", BURN_COMMANDLINE_SWITCH_EMBEDDED, pEngineState->embeddedConnection.sczName, pEngineState->embeddedConnection.sczSecret, pEngineState->embeddedConnection.dwProcessId); + ExitOnFailure(hr, "Failed to allocate embedded command."); + } + + if (pInternalCommand->sczIgnoreDependencies) + { + hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls=%ls", BURN_COMMANDLINE_SWITCH_IGNOREDEPENDENCIES, pInternalCommand->sczIgnoreDependencies); + ExitOnFailure(hr, "Failed to append ignored dependencies to command-line."); } + hr = CoreRecreateCommandLine(psczCommandLine, pCommand->action, pInternalCommand, pCommand, pCommand->relationType, pCommand->fPassthrough); + ExitOnFailure(hr, "Failed to recreate clean room command-line."); + LExit: - ReleaseStr(scz); + return hr; +} +extern "C" HRESULT CoreCreatePassthroughBundleCommandLine( + __deref_inout_z LPWSTR* psczCommandLine, + __in BURN_ENGINE_COMMAND* pInternalCommand, + __in BOOTSTRAPPER_COMMAND* pCommand + ) +{ + HRESULT hr = S_OK; + + // No matter the operation, we're passing the same command-line. + // That's what makes this a passthrough bundle. + hr = CoreRecreateCommandLine(psczCommandLine, pCommand->action, pInternalCommand, pCommand, pCommand->relationType, TRUE); + ExitOnFailure(hr, "Failed to recreate passthrough bundle command-line."); + +LExit: + return hr; +} + +extern "C" HRESULT CoreCreateResumeCommandLine( + __deref_inout_z LPWSTR* psczCommandLine, + __in BURN_PLAN* pPlan, + __in BURN_LOGGING* pLog + ) +{ + HRESULT hr = S_OK; + + hr = StrAllocFormatted(psczCommandLine, L"/%ls", BURN_COMMANDLINE_SWITCH_CLEAN_ROOM); + ExitOnFailure(hr, "Failed to alloc resume command-line."); + + if (BURN_LOGGING_ATTRIBUTE_EXTRADEBUG & pPlan->pInternalCommand->dwLoggingAttributes) + { + hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls=%ls", BURN_COMMANDLINE_SWITCH_LOG_MODE, L"x"); + ExitOnFailure(hr, "Failed to set log mode in resume command-line."); + } + + if (pLog->sczPath && *(pLog->sczPath)) + { + hr = StrAllocConcatFormatted(psczCommandLine, L" /%ls \"%ls\"", BURN_COMMANDLINE_SWITCH_LOG_APPEND, pLog->sczPath); + ExitOnFailure(hr, "Failed to set log path in resume command-line."); + } + + hr = CoreRecreateCommandLine(psczCommandLine, pPlan->action, pPlan->pInternalCommand, pPlan->pCommand, pPlan->pCommand->relationType, pPlan->pCommand->fPassthrough); + ExitOnFailure(hr, "Failed to recreate resume command-line."); + +LExit: + return hr; +} + +extern "C" HRESULT CoreCreateUpdateBundleCommandLine( + __deref_inout_z LPWSTR* psczCommandLine, + __in BURN_ENGINE_COMMAND* pInternalCommand, + __in BOOTSTRAPPER_COMMAND* pCommand + ) +{ + HRESULT hr = S_OK; + + hr = CoreRecreateCommandLine(psczCommandLine, BOOTSTRAPPER_ACTION_INSTALL, pInternalCommand, pCommand, BOOTSTRAPPER_RELATION_NONE, FALSE); + ExitOnFailure(hr, "Failed to recreate update bundle command-line."); + +LExit: return hr; } @@ -1334,6 +1484,35 @@ extern "C" HRESULT CoreParseCommandLine( pInternalCommand->dwLoggingAttributes |= BURN_LOGGING_ATTRIBUTE_APPEND; } + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], lstrlenW(BURN_COMMANDLINE_SWITCH_LOG_MODE), BURN_COMMANDLINE_SWITCH_LOG_MODE, -1)) + { + // Get a pointer to the next character after the switch. + LPCWSTR wzParam = &argv[i][2 + lstrlenW(BURN_COMMANDLINE_SWITCH_LOG_MODE)]; + if (L'=' != wzParam[-1] || L'\0' == wzParam[0]) + { + fInvalidCommandLine = TRUE; + TraceLog(E_INVALIDARG, "Missing required parameter for switch: %ls", BURN_COMMANDLINE_SWITCH_LOG_MODE); + } + else + { + while (L'\0' != wzParam[0]) + { + switch (wzParam[0]) + { + case L'x': + pInternalCommand->dwLoggingAttributes |= BURN_LOGGING_ATTRIBUTE_EXTRADEBUG | BURN_LOGGING_ATTRIBUTE_VERBOSE; + break; + default: + // Skip (but log) any other modifiers we don't recognize, + // so that adding future modifiers doesn't break old bundles. + LogId(REPORT_STANDARD, MSG_BURN_UNKNOWN_PRIVATE_SWITCH_MODIFIER, BURN_COMMANDLINE_SWITCH_LOG_MODE, wzParam[0]); + break; + } + + ++wzParam; + } + } + } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_ELEVATED, -1)) { if (i + 3 >= argc) @@ -1462,7 +1641,9 @@ extern "C" HRESULT CoreParseCommandLine( } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_DISABLE_UNELEVATE, -1)) { +#ifdef ENABLE_UNELEVATE pInternalCommand->fDisableUnelevate = TRUE; +#endif } else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, BURN_COMMANDLINE_SWITCH_RUNONCE, -1)) { @@ -1628,6 +1809,30 @@ LExit: // internal helper functions +static HRESULT AppendLayoutToCommandLine( + __in BOOTSTRAPPER_ACTION action, + __in_z LPCWSTR wzLayoutDirectory, + __deref_inout_z LPWSTR* psczCommandLine + ) +{ + HRESULT hr = S_OK; + + if (BOOTSTRAPPER_ACTION_LAYOUT == action || wzLayoutDirectory) + { + hr = StrAllocConcat(psczCommandLine, L" /layout", 0); + ExitOnFailure(hr, "Failed to append layout switch."); + + if (wzLayoutDirectory) + { + hr = PathCommandLineAppend(psczCommandLine, wzLayoutDirectory); + ExitOnFailure(hr, "Failed to append layout directory."); + } + } + +LExit: + return hr; +} + static HRESULT GetSanitizedCommandLine( __in BURN_ENGINE_COMMAND* pInternalCommand, __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"; const LPCWSTR BURN_COMMANDLINE_SWITCH_EMBEDDED = L"burn.embedded"; const LPCWSTR BURN_COMMANDLINE_SWITCH_RUNONCE = L"burn.runonce"; const LPCWSTR BURN_COMMANDLINE_SWITCH_LOG_APPEND = L"burn.log.append"; +const LPCWSTR BURN_COMMANDLINE_SWITCH_LOG_MODE = L"burn.log.mode"; const LPCWSTR BURN_COMMANDLINE_SWITCH_RELATED_DETECT = L"burn.related.detect"; const LPCWSTR BURN_COMMANDLINE_SWITCH_RELATED_UPGRADE = L"burn.related.upgrade"; const LPCWSTR BURN_COMMANDLINE_SWITCH_RELATED_ADDON = L"burn.related.addon"; @@ -89,7 +90,9 @@ typedef struct _BURN_ENGINE_COMMAND BURN_MODE mode; BURN_AU_PAUSE_ACTION automaticUpdates; BOOL fDisableSystemRestore; +#ifdef ENABLE_UNELEVATE BOOL fDisableUnelevate; +#endif BOOL fInitiallyElevated; LPWSTR sczActiveParent; @@ -215,14 +218,28 @@ HRESULT CoreSaveEngineState( LPCWSTR CoreRelationTypeToCommandLineString( __in BOOTSTRAPPER_RELATION_TYPE relationType ); -HRESULT CoreRecreateCommandLine( +HRESULT CoreCreateCleanRoomCommandLine( + __deref_inout_z LPWSTR* psczCommandLine, + __in BURN_ENGINE_STATE* pEngineState, + __in_z LPCWSTR wzCleanRoomBundlePath, + __in_z LPCWSTR wzCurrentProcessPath, + __inout HANDLE* phFileAttached, + __inout HANDLE* phFileSelf + ); +HRESULT CoreCreatePassthroughBundleCommandLine( __deref_inout_z LPWSTR* psczCommandLine, - __in BOOTSTRAPPER_ACTION action, __in BURN_ENGINE_COMMAND* pInternalCommand, - __in BOOTSTRAPPER_COMMAND* pCommand, - __in BOOTSTRAPPER_RELATION_TYPE relationType, - __in BOOL fPassthrough, - __in_z_opt LPCWSTR wzAppendLogPath + __in BOOTSTRAPPER_COMMAND* pCommand + ); +HRESULT CoreCreateResumeCommandLine( + __deref_inout_z LPWSTR* psczCommandLine, + __in BURN_PLAN* pPlan, + __in BURN_LOGGING* pLog + ); +HRESULT CoreCreateUpdateBundleCommandLine( + __deref_inout_z LPWSTR* psczCommandLine, + __in BURN_ENGINE_COMMAND* pInternalCommand, + __in BOOTSTRAPPER_COMMAND* pCommand ); HRESULT CoreAppendFileHandleAttachedToCommandLine( __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( __in BURN_ENGINE_STATE* pEngineState ); static HRESULT RunUntrusted( - __in LPCWSTR wzCommandLine, __in BURN_ENGINE_STATE* pEngineState ); static HRESULT RunNormal( @@ -195,7 +194,7 @@ extern "C" HRESULT EngineRun( switch (engineState.internalCommand.mode) { case BURN_MODE_UNTRUSTED: - hr = RunUntrusted(wzCommandLine, &engineState); + hr = RunUntrusted(&engineState); ExitOnFailure(hr, "Failed to run untrusted mode."); break; @@ -411,7 +410,6 @@ static void UninitializeEngineState( } static HRESULT RunUntrusted( - __in LPCWSTR wzCommandLine, __in BURN_ENGINE_STATE* pEngineState ) { @@ -450,24 +448,8 @@ static HRESULT RunUntrusted( wzCleanRoomBundlePath = sczCachedCleanRoomBundlePath; } - // The clean room switch must always be at the front of the command line so - // the EngineInCleanRoom function will operate correctly. - hr = StrAllocFormatted(&sczParameters, L"-%ls=\"%ls\"", BURN_COMMANDLINE_SWITCH_CLEAN_ROOM, sczCurrentProcessPath); - ExitOnFailure(hr, "Failed to allocate parameters for unelevated process."); - - // Send a file handle for the child Burn process to access the attached container. - hr = CoreAppendFileHandleAttachedToCommandLine(pEngineState->section.hEngineFile, &hFileAttached, &sczParameters); - ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_ATTACHED); - - // Grab a file handle for the child Burn process. - hr = CoreAppendFileHandleSelfToCommandLine(wzCleanRoomBundlePath, &hFileSelf, &sczParameters, NULL); - ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_FILEHANDLE_SELF); - - hr = CoreAppendSplashScreenWindowToCommandLine(pEngineState->command.hwndSplashScreen, &sczParameters); - ExitOnFailure(hr, "Failed to append %ls", BURN_COMMANDLINE_SWITCH_SPLASH_SCREEN); - - hr = StrAllocConcatFormattedSecure(&sczParameters, L" %ls", wzCommandLine); - ExitOnFailure(hr, "Failed to append original command line."); + hr = CoreCreateCleanRoomCommandLine(&sczParameters, pEngineState, wzCleanRoomBundlePath, sczCurrentProcessPath, &hFileAttached, &hFileSelf); + ExitOnFailure(hr, "Failed to create clean room command-line."); #ifdef ENABLE_UNELEVATE // 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 Failed to parse command line. . +MessageId=16 +Severity=Warning +SymbolicName=MSG_BURN_UNKNOWN_PRIVATE_SWITCH_MODIFIER +Language=English +Unknown burn internal command-line switch modifier encountered, switch: '%1!ls!', modifier: '%2!c!'. +. + MessageId=51 Severity=Error SymbolicName=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( { UpdateUninitialize(&pEngineState->update); - hr = CoreRecreateCommandLine(&sczCommandline, BOOTSTRAPPER_ACTION_INSTALL, &pEngineState->internalCommand, &pEngineState->command, BOOTSTRAPPER_RELATION_NONE, FALSE, NULL); - ExitOnFailure(hr, "Failed to recreate command-line for update bundle."); + hr = CoreCreateUpdateBundleCommandLine(&sczCommandline, &pEngineState->internalCommand, &pEngineState->command); + ExitOnFailure(hr, "Failed to create command-line for update bundle."); // Bundles would fail to use the downloaded update bundle, as the running bundle would be one of the search paths. // 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( if (!fIgnoreBundle) { - hr = PseudoBundleInitializePassthrough(&pPlan->forwardCompatibleBundle, pPlan->pInternalCommand, pPlan->pCommand, NULL, &pRelatedBundle->package); + hr = PseudoBundleInitializePassthrough(&pPlan->forwardCompatibleBundle, pPlan->pInternalCommand, pPlan->pCommand, &pRelatedBundle->package); ExitOnFailure(hr, "Failed to initialize pass through bundle."); pPlan->fEnabledForwardCompatibleBundle = TRUE; @@ -1780,11 +1780,10 @@ extern "C" HRESULT PlanSetResumeCommand( ) { HRESULT hr = S_OK; - BOOTSTRAPPER_COMMAND* pCommand = pPlan->pCommand; // build the resume command-line. - hr = CoreRecreateCommandLine(&pRegistration->sczResumeCommandLine, pPlan->action, pPlan->pInternalCommand, pCommand, pCommand->relationType, pCommand->fPassthrough, pLog->sczPath); - ExitOnFailure(hr, "Failed to recreate resume command-line."); + hr = CoreCreateResumeCommandLine(&pRegistration->sczResumeCommandLine, pPlan, pLog); + ExitOnFailure(hr, "Failed to create resume command-line."); LExit: 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( __in BURN_PACKAGE* pPassthroughPackage, __in BURN_ENGINE_COMMAND* pInternalCommand, __in BOOTSTRAPPER_COMMAND* pCommand, - __in_z_opt LPCWSTR wzAppendLogPath, __in BURN_PACKAGE* pPackage ) { @@ -202,10 +201,8 @@ extern "C" HRESULT PseudoBundleInitializePassthrough( pPassthroughPackage->Exe.protocol = pPackage->Exe.protocol; - // No matter the operation, we're passing the same command-line. That's what makes - // this a passthrough bundle. - hr = CoreRecreateCommandLine(&sczArguments, pCommand->action, pInternalCommand, pCommand, pCommand->relationType, TRUE, wzAppendLogPath); - ExitOnFailure(hr, "Failed to recreate command-line arguments."); + hr = CoreCreatePassthroughBundleCommandLine(&sczArguments, pInternalCommand, pCommand); + ExitOnFailure(hr, "Failed to create command-line arguments."); hr = StrAllocString(&pPassthroughPackage->Exe.sczInstallArguments, sczArguments, 0); 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( __in BURN_PACKAGE* pPassthroughPackage, __in BURN_ENGINE_COMMAND* pInternalCommand, __in BOOTSTRAPPER_COMMAND* pCommand, - __in_z_opt LPCWSTR wzAppendLogPath, __in BURN_PACKAGE* pPackage ); 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( DWORD er = ERROR_SUCCESS; HKEY hkRebootRequired = NULL; HKEY hkRun = NULL; - LPWSTR sczResumeCommandLine = NULL; + LPWSTR sczRunOnceCommandLine = NULL; LPCWSTR sczResumeKey = REGISTRY_RUN_ONCE_KEY; LogId(REPORT_STANDARD, MSG_SESSION_UPDATE, pRegistration->sczRegistrationKey, LoggingResumeModeToString(resumeMode), LoggingBoolToString(fRestartInitiated), LoggingBoolToString(pRegistration->fDisableResume)); @@ -1354,14 +1354,14 @@ static HRESULT UpdateResumeMode( if ((BURN_RESUME_MODE_ACTIVE == resumeMode || fRestartInitiated) && !pRegistration->fDisableResume) { // append RunOnce switch - hr = StrAllocFormatted(&sczResumeCommandLine, L"\"%ls\" /%ls", pRegistration->sczCacheExecutablePath, BURN_COMMANDLINE_SWITCH_RUNONCE); + hr = StrAllocFormatted(&sczRunOnceCommandLine, L"\"%ls\" /%ls /%ls", pRegistration->sczCacheExecutablePath, BURN_COMMANDLINE_SWITCH_CLEAN_ROOM, BURN_COMMANDLINE_SWITCH_RUNONCE); ExitOnFailure(hr, "Failed to format resume command line for RunOnce."); // write run key hr = RegCreate(pRegistration->hkRoot, sczResumeKey, KEY_WRITE, &hkRun); ExitOnFailure(hr, "Failed to create run key."); - hr = RegWriteString(hkRun, pRegistration->sczId, sczResumeCommandLine); + hr = RegWriteString(hkRun, pRegistration->sczId, sczRunOnceCommandLine); ExitOnFailure(hr, "Failed to write run key value."); hr = RegWriteString(hkRegistration, REGISTRY_BUNDLE_RESUME_COMMAND_LINE, pRegistration->sczResumeCommandLine); @@ -1398,7 +1398,7 @@ static HRESULT UpdateResumeMode( } LExit: - ReleaseStr(sczResumeCommandLine); + ReleaseStr(sczRunOnceCommandLine); ReleaseRegKey(hkRebootRequired); ReleaseRegKey(hkRun); 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 Assert::True(File::Exists(Path::Combine(cacheDirectory, gcnew String(L"setup.exe")))); Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); - Assert::Equal(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))); + Assert::Equal(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))); // end session hr = RegistrationSessionEnd(®istration, &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 // verify that registration was created Assert::Equal(gcnew String(L"Product1 Installation"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayName"), nullptr)); Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); - Assert::Equal(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)); + Assert::Equal(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)); // complete registration hr = RegistrationSessionEnd(®istration, &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 // verify that registration was updated Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); Assert::Equal(1, (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Installed"), nullptr)); - Assert::Equal(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)); + Assert::Equal(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)); // delete registration hr = RegistrationSessionEnd(®istration, &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 // verify that registration was created Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); - Assert::Equal(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)); + Assert::Equal(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)); // complete registration hr = RegistrationSessionEnd(®istration, &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 // verify that registration was created Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); - Assert::Equal(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)); + Assert::Equal(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)); // finish registration hr = RegistrationSessionEnd(®istration, &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 // verify that registration was updated Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr)); - Assert::Equal(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)); + Assert::Equal(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)); // delete registration hr = RegistrationSessionEnd(®istration, &cache, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE); -- cgit v1.2.3-55-g6feb