From f43d176f95601ff7524e06247166d4f3b6e61c05 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Fri, 2 Jul 2021 10:18:08 -0500 Subject: Make the BA responsible for parsing restart prompt behavior. Fixes #4975 --- .../inc/BootstrapperApplication.h | 10 ------ .../WixToolset.Mba.Core/BootstrapperCommand.cs | 33 +++++++++++++++----- .../IBootstrapperApplicationFactory.cs | 2 -- .../WixToolset.Mba.Core/IBootstrapperCommand.cs | 5 --- src/api/burn/WixToolset.Mba.Core/IMbaCommand.cs | 5 +++ src/api/burn/WixToolset.Mba.Core/MbaCommand.cs | 2 ++ src/api/burn/balutil/balinfo.cpp | 36 +++++++++++++++++----- .../balutil/inc/BalBaseBootstrapperApplication.h | 28 ++++++++++++++--- src/api/burn/balutil/inc/balinfo.h | 12 +++++++- .../burn/bextutil/inc/BextBaseBundleExtension.h | 2 +- .../TestBootstrapperApplication.cpp | 10 +++--- .../BaseBootstrapperApplicationFactoryFixture.cs | 1 - 12 files changed, 103 insertions(+), 43 deletions(-) (limited to 'src/api') diff --git a/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h b/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h index 56f6b361..8301d45f 100644 --- a/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h +++ b/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h @@ -11,15 +11,6 @@ enum BOOTSTRAPPER_DISPLAY BOOTSTRAPPER_DISPLAY_FULL, }; -enum BOOTSTRAPPER_RESTART -{ - BOOTSTRAPPER_RESTART_UNKNOWN, - BOOTSTRAPPER_RESTART_NEVER, - BOOTSTRAPPER_RESTART_PROMPT, - BOOTSTRAPPER_RESTART_AUTOMATIC, - BOOTSTRAPPER_RESTART_ALWAYS, -}; - enum BOOTSTRAPPER_REGISTRATION_TYPE { BOOTSTRAPPER_REGISTRATION_TYPE_NONE, // The engine will ignore NONE if it recommended INPROGRESS or FULL. @@ -286,7 +277,6 @@ struct BOOTSTRAPPER_COMMAND DWORD cbSize; BOOTSTRAPPER_ACTION action; BOOTSTRAPPER_DISPLAY display; - BOOTSTRAPPER_RESTART restart; LPWSTR wzCommandLine; int nCmdShow; diff --git a/src/api/burn/WixToolset.Mba.Core/BootstrapperCommand.cs b/src/api/burn/WixToolset.Mba.Core/BootstrapperCommand.cs index 345e0448..88a9b9bb 100644 --- a/src/api/burn/WixToolset.Mba.Core/BootstrapperCommand.cs +++ b/src/api/burn/WixToolset.Mba.Core/BootstrapperCommand.cs @@ -17,7 +17,6 @@ namespace WixToolset.Mba.Core /// /// /// - /// /// /// /// @@ -30,7 +29,6 @@ namespace WixToolset.Mba.Core public BootstrapperCommand( LaunchAction action, Display display, - Restart restart, string commandLine, int cmdShow, ResumeType resume, @@ -43,7 +41,6 @@ namespace WixToolset.Mba.Core { this.Action = action; this.Display = display; - this.Restart = restart; this.CommandLine = commandLine; this.CmdShow = cmdShow; this.Resume = resume; @@ -61,9 +58,6 @@ namespace WixToolset.Mba.Core /// public Display Display { get; } - /// - public Restart Restart { get; } - /// public string CommandLine { get; } @@ -97,6 +91,7 @@ namespace WixToolset.Mba.Core var args = ParseCommandLineToArgs(this.CommandLine); var unknownArgs = new List(); var variables = new List>(); + var restart = Restart.Unknown; foreach (var arg in args) { @@ -104,7 +99,25 @@ namespace WixToolset.Mba.Core if (arg[0] == '-' || arg[0] == '/') { - unknownArg = true; + var parameter = arg.Substring(1).ToLowerInvariant(); + switch (parameter) + { + case "norestart": + if (restart == Restart.Unknown) + { + restart = Restart.Never; + } + break; + case "forcerestart": + if (restart == Restart.Unknown) + { + restart = Restart.Always; + } + break; + default: + unknownArg = true; + break; + } } else { @@ -127,8 +140,14 @@ namespace WixToolset.Mba.Core } } + if (restart == Restart.Unknown) + { + restart = this.Display < Display.Full ? Restart.Automatic : Restart.Prompt; + } + return new MbaCommand { + Restart = restart, UnknownCommandLineArgs = unknownArgs.ToArray(), Variables = variables.ToArray(), }; diff --git a/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplicationFactory.cs b/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplicationFactory.cs index 0f9193d0..64e25ff4 100644 --- a/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplicationFactory.cs +++ b/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplicationFactory.cs @@ -35,7 +35,6 @@ namespace WixToolset.Mba.Core [MarshalAs(UnmanagedType.I4)] internal int cbSize; [MarshalAs(UnmanagedType.U4)] private readonly LaunchAction action; [MarshalAs(UnmanagedType.U4)] private readonly Display display; - [MarshalAs(UnmanagedType.U4)] private readonly Restart restart; private readonly IntPtr wzCommandLine; [MarshalAs(UnmanagedType.I4)] private readonly int nCmdShow; [MarshalAs(UnmanagedType.U4)] private readonly ResumeType resume; @@ -51,7 +50,6 @@ namespace WixToolset.Mba.Core return new BootstrapperCommand( this.action, this.display, - this.restart, Marshal.PtrToStringUni(this.wzCommandLine), this.nCmdShow, this.resume, diff --git a/src/api/burn/WixToolset.Mba.Core/IBootstrapperCommand.cs b/src/api/burn/WixToolset.Mba.Core/IBootstrapperCommand.cs index b7baa55c..f583e619 100644 --- a/src/api/burn/WixToolset.Mba.Core/IBootstrapperCommand.cs +++ b/src/api/burn/WixToolset.Mba.Core/IBootstrapperCommand.cs @@ -19,11 +19,6 @@ namespace WixToolset.Mba.Core /// Display Display { get; } - /// - /// Gets the action to perform if a reboot is required. - /// - Restart Restart { get; } - /// /// Gets the command line arguments. /// diff --git a/src/api/burn/WixToolset.Mba.Core/IMbaCommand.cs b/src/api/burn/WixToolset.Mba.Core/IMbaCommand.cs index a3ad68d8..495b2f44 100644 --- a/src/api/burn/WixToolset.Mba.Core/IMbaCommand.cs +++ b/src/api/burn/WixToolset.Mba.Core/IMbaCommand.cs @@ -9,6 +9,11 @@ namespace WixToolset.Mba.Core /// public interface IMbaCommand { + /// + /// Gets the action to perform if a reboot is required. + /// + Restart Restart { get; } + /// /// The command line arguments not parsed into or . /// diff --git a/src/api/burn/WixToolset.Mba.Core/MbaCommand.cs b/src/api/burn/WixToolset.Mba.Core/MbaCommand.cs index 424cde63..8917a334 100644 --- a/src/api/burn/WixToolset.Mba.Core/MbaCommand.cs +++ b/src/api/burn/WixToolset.Mba.Core/MbaCommand.cs @@ -9,6 +9,8 @@ namespace WixToolset.Mba.Core /// internal sealed class MbaCommand : IMbaCommand { + public Restart Restart { get; internal set; } + public string[] UnknownCommandLineArgs { get; internal set; } public KeyValuePair[] Variables { get; internal set; } diff --git a/src/api/burn/balutil/balinfo.cpp b/src/api/burn/balutil/balinfo.cpp index f71784a5..2746f49e 100644 --- a/src/api/burn/balutil/balinfo.cpp +++ b/src/api/burn/balutil/balinfo.cpp @@ -19,7 +19,7 @@ static HRESULT ParseOverridableVariablesFromXml( DAPI_(HRESULT) BalInfoParseCommandLine( __in BAL_INFO_COMMAND* pCommand, - __in LPCWSTR wzCommandLine + __in const BOOTSTRAPPER_COMMAND* pBootstrapperCommand ) { HRESULT hr = S_OK; @@ -29,13 +29,13 @@ DAPI_(HRESULT) BalInfoParseCommandLine( BalInfoUninitializeCommandLine(pCommand); - if (!wzCommandLine || !*wzCommandLine) + if (!pBootstrapperCommand->wzCommandLine || !*pBootstrapperCommand->wzCommandLine) { ExitFunction(); } - hr = AppParseCommandLine(wzCommandLine, &argc, &argv); - ExitOnFailure(hr, "Failed to parse command line."); + hr = AppParseCommandLine(pBootstrapperCommand->wzCommandLine, &argc, &argv); + BalExitOnFailure(hr, "Failed to parse command line."); for (int i = 0; i < argc; ++i) { @@ -43,7 +43,24 @@ DAPI_(HRESULT) BalInfoParseCommandLine( if (argv[i][0] == L'-' || argv[i][0] == L'/') { - fUnknownArg = TRUE; + if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"norestart", -1)) + { + if (BAL_INFO_RESTART_UNKNOWN == pCommand->restart) + { + pCommand->restart = BAL_INFO_RESTART_NEVER; + } + } + else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"forcerestart", -1)) + { + if (BAL_INFO_RESTART_UNKNOWN == pCommand->restart) + { + pCommand->restart = BAL_INFO_RESTART_ALWAYS; + } + } + else + { + fUnknownArg = TRUE; + } } else { @@ -55,10 +72,10 @@ DAPI_(HRESULT) BalInfoParseCommandLine( else { hr = MemEnsureArraySizeForNewItems(reinterpret_cast(&pCommand->rgVariableNames), pCommand->cVariables, 1, sizeof(LPWSTR), 5); - ExitOnFailure(hr, "Failed to ensure size for variable names."); + BalExitOnFailure(hr, "Failed to ensure size for variable names."); hr = MemEnsureArraySizeForNewItems(reinterpret_cast(&pCommand->rgVariableValues), pCommand->cVariables, 1, sizeof(LPWSTR), 5); - ExitOnFailure(hr, "Failed to ensure size for variable values."); + BalExitOnFailure(hr, "Failed to ensure size for variable values."); LPWSTR* psczVariableName = pCommand->rgVariableNames + pCommand->cVariables; LPWSTR* psczVariableValue = pCommand->rgVariableValues + pCommand->cVariables; @@ -86,6 +103,11 @@ DAPI_(HRESULT) BalInfoParseCommandLine( } LExit: + if (BAL_INFO_RESTART_UNKNOWN == pCommand->restart) + { + pCommand->restart = BOOTSTRAPPER_DISPLAY_FULL > pBootstrapperCommand->display ? BAL_INFO_RESTART_AUTOMATIC : BAL_INFO_RESTART_PROMPT; + } + if (argv) { AppFreeCommandLineArgs(argv); diff --git a/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h b/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h index 393987ba..53fa369b 100644 --- a/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h +++ b/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h @@ -9,6 +9,7 @@ #include "IBootstrapperApplication.h" #include "balutil.h" +#include "balinfo.h" #include "balretry.h" class CBalBaseBootstrapperApplication : public IBootstrapperApplication @@ -794,7 +795,7 @@ public: // IBootstrapperApplication { HRESULT hr = S_OK; BOOL fRestartRequired = BOOTSTRAPPER_APPLY_RESTART_REQUIRED == restart; - BOOL fShouldBlockRestart = BOOTSTRAPPER_DISPLAY_FULL <= m_display && BOOTSTRAPPER_RESTART_PROMPT >= m_restart; + BOOL fShouldBlockRestart = BOOTSTRAPPER_DISPLAY_FULL <= m_display && BAL_INFO_RESTART_PROMPT >= m_BalInfoCommand.restart; if (fRestartRequired && !fShouldBlockRestart) { @@ -976,6 +977,22 @@ public: // IBootstrapperApplication return S_OK; } +public: //CBalBaseBootstrapperApplication + virtual STDMETHODIMP Initialize( + __in const BOOTSTRAPPER_CREATE_ARGS* pCreateArgs + ) + { + HRESULT hr = S_OK; + + m_display = pCreateArgs->pCommand->display; + + hr = BalInfoParseCommandLine(&m_BalInfoCommand, pCreateArgs->pCommand); + BalExitOnFailure(hr, "Failed to parse command line with balutil."); + + LExit: + return hr; + } + protected: // // PromptCancel - prompts the user to close (if not forced). @@ -1029,20 +1046,19 @@ protected: CBalBaseBootstrapperApplication( __in IBootstrapperEngine* pEngine, - __in const BOOTSTRAPPER_CREATE_ARGS* pArgs, __in DWORD dwRetryCount = 0, __in DWORD dwRetryTimeout = 1000 ) { m_cReferences = 1; - m_display = pArgs->pCommand->display; - m_restart = pArgs->pCommand->restart; + m_display = BOOTSTRAPPER_DISPLAY_UNKNOWN; pEngine->AddRef(); m_pEngine = pEngine; ::InitializeCriticalSection(&m_csCanceled); m_fCanceled = FALSE; + m_BalInfoCommand = { }; m_fApplying = FALSE; m_fRollingBack = FALSE; @@ -1054,6 +1070,7 @@ protected: virtual ~CBalBaseBootstrapperApplication() { + BalInfoUninitializeCommandLine(&m_BalInfoCommand); BalRetryUninitialize(); ::DeleteCriticalSection(&m_csCanceled); @@ -1064,10 +1081,11 @@ protected: CRITICAL_SECTION m_csCanceled; BOOL m_fCanceled; + BAL_INFO_COMMAND m_BalInfoCommand; + private: long m_cReferences; BOOTSTRAPPER_DISPLAY m_display; - BOOTSTRAPPER_RESTART m_restart; IBootstrapperEngine* m_pEngine; BOOL m_fApplying; diff --git a/src/api/burn/balutil/inc/balinfo.h b/src/api/burn/balutil/inc/balinfo.h index 07a1cbb7..769becb2 100644 --- a/src/api/burn/balutil/inc/balinfo.h +++ b/src/api/burn/balutil/inc/balinfo.h @@ -18,6 +18,15 @@ typedef enum BAL_INFO_PACKAGE_TYPE BAL_INFO_PACKAGE_TYPE_BUNDLE_PATCH, } BAL_INFO_PACKAGE_TYPE; +typedef enum _BAL_INFO_RESTART +{ + BAL_INFO_RESTART_UNKNOWN, + BAL_INFO_RESTART_NEVER, + BAL_INFO_RESTART_PROMPT, + BAL_INFO_RESTART_AUTOMATIC, + BAL_INFO_RESTART_ALWAYS, +} BAL_INFO_RESTART; + typedef enum _BAL_INFO_VARIABLE_COMMAND_LINE_TYPE { BAL_INFO_VARIABLE_COMMAND_LINE_TYPE_UPPER_CASE, @@ -85,6 +94,7 @@ typedef struct _BAL_INFO_COMMAND DWORD cVariables; LPWSTR* rgVariableNames; LPWSTR* rgVariableValues; + BAL_INFO_RESTART restart; } BAL_INFO_COMMAND; @@ -94,7 +104,7 @@ typedef struct _BAL_INFO_COMMAND ********************************************************************/ HRESULT DAPI BalInfoParseCommandLine( __in BAL_INFO_COMMAND* pCommand, - __in LPCWSTR wzCommandLine + __in const BOOTSTRAPPER_COMMAND* pBootstrapperCommand ); diff --git a/src/api/burn/bextutil/inc/BextBaseBundleExtension.h b/src/api/burn/bextutil/inc/BextBaseBundleExtension.h index 69c338e4..a302702e 100644 --- a/src/api/burn/bextutil/inc/BextBaseBundleExtension.h +++ b/src/api/burn/bextutil/inc/BextBaseBundleExtension.h @@ -80,7 +80,7 @@ public: // IBundleExtension public: //CBextBaseBundleExtension virtual STDMETHODIMP Initialize( __in const BUNDLE_EXTENSION_CREATE_ARGS* pCreateArgs - ) + ) { HRESULT hr = S_OK; diff --git a/src/api/burn/test/BalUtilUnitTest/TestBootstrapperApplication.cpp b/src/api/burn/test/BalUtilUnitTest/TestBootstrapperApplication.cpp index 13d22e72..daa1d690 100644 --- a/src/api/burn/test/BalUtilUnitTest/TestBootstrapperApplication.cpp +++ b/src/api/burn/test/BalUtilUnitTest/TestBootstrapperApplication.cpp @@ -8,9 +8,8 @@ class CTestBootstrapperApplication : public CBalBaseBootstrapperApplication { public: CTestBootstrapperApplication( - __in IBootstrapperEngine* pEngine, - __in const BOOTSTRAPPER_CREATE_ARGS* pArgs - ) : CBalBaseBootstrapperApplication(pEngine, pArgs) + __in IBootstrapperEngine* pEngine + ) : CBalBaseBootstrapperApplication(pEngine) { } }; @@ -25,9 +24,12 @@ HRESULT CreateBootstrapperApplication( HRESULT hr = S_OK; CTestBootstrapperApplication* pApplication = NULL; - pApplication = new CTestBootstrapperApplication(pEngine, pArgs); + pApplication = new CTestBootstrapperApplication(pEngine); ExitOnNull(pApplication, hr, E_OUTOFMEMORY, "Failed to create new test bootstrapper application object."); + hr = pApplication->Initialize(pArgs); + ExitOnFailure(hr, "CTestBootstrapperApplication initialization failed."); + pResults->pfnBootstrapperApplicationProc = BalBaseBootstrapperApplicationProc; pResults->pvBootstrapperApplicationProcContext = pApplication; *ppApplication = pApplication; diff --git a/src/api/burn/test/WixToolsetTest.Mba.Core/BaseBootstrapperApplicationFactoryFixture.cs b/src/api/burn/test/WixToolsetTest.Mba.Core/BaseBootstrapperApplicationFactoryFixture.cs index b49b3927..8705ed13 100644 --- a/src/api/burn/test/WixToolsetTest.Mba.Core/BaseBootstrapperApplicationFactoryFixture.cs +++ b/src/api/burn/test/WixToolsetTest.Mba.Core/BaseBootstrapperApplicationFactoryFixture.cs @@ -101,7 +101,6 @@ namespace WixToolsetTest.Mba.Core public int cbSize; public LaunchAction action; public Display display; - public Restart restart; [MarshalAs(UnmanagedType.LPWStr)] public string wzCommandLine; public int nCmdShow; public ResumeType resume; -- cgit v1.2.3-55-g6feb