From 780cd25e41f2d2982807a0a2a24a734684d27fe6 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Fri, 15 May 2020 13:48:38 +1000 Subject: WIXFEAT:6164 Add OnPlanMsiPackage. --- src/WixToolset.Mba.Core/BootstrapperApplication.cs | 34 ++++++- src/WixToolset.Mba.Core/EventArgs.cs | 74 +++++++++++++- .../IBootstrapperApplication.cs | 109 +++++++++++++++++++++ src/balutil/inc/BAFunctions.h | 1 + src/balutil/inc/BalBaseBAFunctions.h | 15 +++ src/balutil/inc/BalBaseBAFunctionsProc.h | 1 + src/balutil/inc/BalBaseBootstrapperApplication.h | 16 +++ .../inc/BalBaseBootstrapperApplicationProc.h | 14 ++- src/balutil/inc/IBootstrapperApplication.h | 14 +++ 9 files changed, 274 insertions(+), 4 deletions(-) diff --git a/src/WixToolset.Mba.Core/BootstrapperApplication.cs b/src/WixToolset.Mba.Core/BootstrapperApplication.cs index 249c17c9..9ee909dc 100644 --- a/src/WixToolset.Mba.Core/BootstrapperApplication.cs +++ b/src/WixToolset.Mba.Core/BootstrapperApplication.cs @@ -161,6 +161,11 @@ namespace WixToolset.Mba.Core /// public event EventHandler PlanMsiFeature; + /// + /// Fired when the engine is planning an MSI or MSP package. + /// + public event EventHandler PlanMsiPackage; + /// /// Fired when the engine has completed planning the installation of a specific package. /// @@ -658,6 +663,19 @@ namespace WixToolset.Mba.Core } } + /// + /// Called when the engine is planning an MSI or MSP package. + /// + /// Additional arguments for this event. + protected virtual void OnPlanMsiPackage(PlanMsiPackageEventArgs args) + { + EventHandler handler = this.PlanMsiPackage; + if (null != handler) + { + handler(this, args); + } + } + /// /// Called when then engine has completed planning the installation of a specific package. /// @@ -1288,6 +1306,18 @@ namespace WixToolset.Mba.Core return args.HResult; } + int IBootstrapperApplication.OnPlanMsiPackage(string wzPackageId, bool fExecute, ActionState action, ref bool fCancel, ref BURN_MSI_PROPERTY actionMsiProperty, ref INSTALLUILEVEL uiLevel, ref bool fDisableExternalUiHandler) + { + PlanMsiPackageEventArgs args = new PlanMsiPackageEventArgs(wzPackageId, fExecute, action, fCancel, actionMsiProperty, uiLevel, fDisableExternalUiHandler); + this.OnPlanMsiPackage(args); + + fCancel = args.Cancel; + actionMsiProperty = args.ActionMsiProperty; + uiLevel = args.UiLevel; + fDisableExternalUiHandler = args.DisableExternalUiHandler; + return args.HResult; + } + int IBootstrapperApplication.OnPlanPackageComplete(string wzPackageId, int hrStatus, PackageState state, RequestState requested, ActionState execute, ActionState rollback) { var args = new PlanPackageCompleteEventArgs(wzPackageId, hrStatus, state, requested, execute, rollback); @@ -1466,9 +1496,9 @@ namespace WixToolset.Mba.Core return args.HResult; } - int IBootstrapperApplication.OnExecutePackageBegin(string wzPackageId, bool fExecute, ActionState action, ref bool fCancel) + int IBootstrapperApplication.OnExecutePackageBegin(string wzPackageId, bool fExecute, ActionState action, INSTALLUILEVEL uiLevel, bool fDisableExternalUiHandler, ref bool fCancel) { - ExecutePackageBeginEventArgs args = new ExecutePackageBeginEventArgs(wzPackageId, fExecute, action, fCancel); + ExecutePackageBeginEventArgs args = new ExecutePackageBeginEventArgs(wzPackageId, fExecute, action, uiLevel, fDisableExternalUiHandler, fCancel); this.OnExecutePackageBegin(args); fCancel = args.Cancel; diff --git a/src/WixToolset.Mba.Core/EventArgs.cs b/src/WixToolset.Mba.Core/EventArgs.cs index ca0fa173..e739a853 100644 --- a/src/WixToolset.Mba.Core/EventArgs.cs +++ b/src/WixToolset.Mba.Core/EventArgs.cs @@ -995,6 +995,64 @@ namespace WixToolset.Mba.Core public FeatureState State { get; set; } } + /// + /// Additional arguments used when the engine is planning an MSI or MSP package. + /// + [Serializable] + public class PlanMsiPackageEventArgs : CancellableHResultEventArgs + { + /// + /// Creates a new instance of the class. + /// + /// The identity of the package planned for. + /// Whether the package is planned to execute or roll back. + /// The action planned for the package. + /// The recommendation from the engine. + /// The requested MSI property to add. + /// The requested internal UI level. + /// Whether Burn is requested to set up an external UI handler. + public PlanMsiPackageEventArgs(string packageId, bool shouldExecute, ActionState action, bool cancelRecommendation, BURN_MSI_PROPERTY actionMsiProperty, INSTALLUILEVEL uiLevel, bool disableExternalUiHandler) + : base(cancelRecommendation) + { + this.PackageId = packageId; + this.ShouldExecute = shouldExecute; + this.Action = action; + this.ActionMsiProperty = actionMsiProperty; + this.UiLevel = uiLevel; + this.DisableExternalUiHandler = disableExternalUiHandler; + } + + /// + /// Gets identity of the package planned for. + /// + public string PackageId { get; private set; } + + /// + /// Gets whether the package is planned to execute or roll back. + /// + public bool ShouldExecute { get; private set; } + + /// + /// Gets the action planned for the package. + /// + public ActionState Action { get; private set; } + + /// + /// Gets or sets the requested MSI property to add. + /// + public BURN_MSI_PROPERTY ActionMsiProperty { get; set; } + + /// + /// Gets or sets the requested internal UI level. + /// + public INSTALLUILEVEL UiLevel { get; set; } + + /// + /// Gets or sets whether Burn is requested to set up an external UI handler. + /// + public bool DisableExternalUiHandler { get; set; } + } + /// /// Additional arguments used when then engine has completed planning the installation of a specific package. /// @@ -1503,13 +1561,17 @@ namespace WixToolset.Mba.Core /// The identity of the package to act on. /// Whether the package is being executed or rolled back. /// The action about to be executed. + /// The internal UI level (if this is an MSI or MSP package). + /// Whether Burn will set up an external UI handler (if this is an MSI or MSP package). /// The recommendation from the engine. - public ExecutePackageBeginEventArgs(string packageId, bool shouldExecute, ActionState action, bool cancelRecommendation) + public ExecutePackageBeginEventArgs(string packageId, bool shouldExecute, ActionState action, INSTALLUILEVEL uiLevel, bool disableExternalUiHandler, bool cancelRecommendation) : base(cancelRecommendation) { this.PackageId = packageId; this.ShouldExecute = shouldExecute; this.Action = action; + this.UiLevel = uiLevel; + this.DisableExternalUiHandler = disableExternalUiHandler; } /// @@ -1526,6 +1588,16 @@ namespace WixToolset.Mba.Core /// Gets the action about to be executed. /// public ActionState Action { get; private set; } + + /// + /// Gets the internal UI level (if this is an MSI or MSP package). + /// + public INSTALLUILEVEL UiLevel { get; private set; } + + /// + /// Gets whether Burn will set up an external UI handler (if this is an MSI or MSP package). + /// + public bool DisableExternalUiHandler { get; private set; } } /// diff --git a/src/WixToolset.Mba.Core/IBootstrapperApplication.cs b/src/WixToolset.Mba.Core/IBootstrapperApplication.cs index c4daaf32..fa655282 100644 --- a/src/WixToolset.Mba.Core/IBootstrapperApplication.cs +++ b/src/WixToolset.Mba.Core/IBootstrapperApplication.cs @@ -219,6 +219,18 @@ namespace WixToolset.Mba.Core [MarshalAs(UnmanagedType.Bool)] ref bool fCancel ); + [PreserveSig] + [return: MarshalAs(UnmanagedType.I4)] + int OnPlanMsiPackage( + [MarshalAs(UnmanagedType.LPWStr)] string wzPackageId, + [MarshalAs(UnmanagedType.Bool)] bool fExecute, + [MarshalAs(UnmanagedType.U4)] ActionState action, + [MarshalAs(UnmanagedType.Bool)] ref bool fCancel, + [MarshalAs(UnmanagedType.U4)] ref BURN_MSI_PROPERTY actionMsiProperty, + [MarshalAs(UnmanagedType.U4)] ref INSTALLUILEVEL uiLevel, + [MarshalAs(UnmanagedType.Bool)] ref bool fDisableExternalUiHandler + ); + [PreserveSig] [return: MarshalAs(UnmanagedType.I4)] int OnPlanPackageComplete( @@ -393,6 +405,8 @@ namespace WixToolset.Mba.Core [MarshalAs(UnmanagedType.LPWStr)] string wzPackageId, [MarshalAs(UnmanagedType.Bool)] bool fExecute, [MarshalAs(UnmanagedType.U4)] ActionState action, + [MarshalAs(UnmanagedType.U4)] INSTALLUILEVEL uiLevel, + [MarshalAs(UnmanagedType.Bool)] bool fDisableExternalUiHandler, [MarshalAs(UnmanagedType.Bool)] ref bool fCancel ); @@ -832,4 +846,99 @@ namespace WixToolset.Mba.Core Restart, ReloadBootstrapper, } + + /// + /// The property Burn will add so the MSI can know the planned action for the package. + /// + public enum BURN_MSI_PROPERTY + { + /// + /// No property will be added. + /// + None, + + /// + /// Add BURNMSIINSTALL=1 + /// + Install, + + /// + /// Add BURNMSIMODFIY=1 + /// + Modify, + + /// + /// Add BURNMSIREPAIR=1 + /// + Repair, + + /// + /// Add BURNMSIUNINSTALL=1 + /// + Uninstall, + } + + /// + /// From msi.h + /// https://docs.microsoft.com/en-us/windows/win32/api/msi/nf-msi-msisetinternalui + /// + [Flags] + public enum INSTALLUILEVEL + { + /// + /// UI level is unchanged + /// + NoChange = 0, + + /// + /// default UI is used + /// + Default = 1, + + /// + /// completely silent installation + /// + None = 2, + + /// + /// simple progress and error handling + /// + Basic = 3, + + /// + /// authored UI, wizard dialogs suppressed + /// + Reduced = 4, + + /// + /// authored UI with wizards, progress, errors + /// + Full = 5, + + /// + /// display success/failure dialog at end of install + /// + EndDialog = 0x80, + + /// + /// display only progress dialog + /// + ProgressOnly = 0x40, + + /// + /// do not display the cancel button in basic UI + /// + HideCancel = 0x20, + + /// + /// force display of source resolution even if quiet + /// + SourceResOnly = 0x100, + + /// + /// show UAC prompt even if quiet + /// Can only be used if on Windows Installer 5.0 or later + /// + UacOnly = 0x200, + } } diff --git a/src/balutil/inc/BAFunctions.h b/src/balutil/inc/BAFunctions.h index 1338253d..8101afdb 100644 --- a/src/balutil/inc/BAFunctions.h +++ b/src/balutil/inc/BAFunctions.h @@ -64,6 +64,7 @@ enum BA_FUNCTIONS_MESSAGE BA_FUNCTIONS_MESSAGE_ONAPPLYCOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONAPPLYCOMPLETE, BA_FUNCTIONS_MESSAGE_ONLAUNCHAPPROVEDEXEBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXEBEGIN, BA_FUNCTIONS_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE, + BA_FUNCTIONS_MESSAGE_ONPLANMSIPACKAGE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANMSIPACKAGE, BA_FUNCTIONS_MESSAGE_ONTHEMELOADED = 1024, BA_FUNCTIONS_MESSAGE_WNDPROC, diff --git a/src/balutil/inc/BalBaseBAFunctions.h b/src/balutil/inc/BalBaseBAFunctions.h index 411524fb..4e095fb8 100644 --- a/src/balutil/inc/BalBaseBAFunctions.h +++ b/src/balutil/inc/BalBaseBAFunctions.h @@ -298,6 +298,19 @@ public: // IBootstrapperApplication return S_OK; } + virtual STDMETHODIMP OnPlanMsiPackage( + __in_z LPCWSTR /*wzPackageId*/, + __in BOOL /*fExecute*/, + __in BOOTSTRAPPER_ACTION_STATE /*action*/, + __inout BOOL* /*pfCancel*/, + __inout BURN_MSI_PROPERTY* /*pActionMsiProperty*/, + __inout INSTALLUILEVEL* /*pUiLevel*/, + __inout BOOL* /*pfDisableExternalUiHandler*/ + ) + { + return S_OK; + } + virtual STDMETHODIMP OnPlanPackageComplete( __in_z LPCWSTR /*wzPackageId*/, __in HRESULT /*hrStatus*/, @@ -490,6 +503,8 @@ public: // IBootstrapperApplication __in_z LPCWSTR /*wzPackageId*/, __in BOOL /*fExecute*/, __in BOOTSTRAPPER_ACTION_STATE /*action*/, + __in INSTALLUILEVEL /*uiLevel*/, + __in BOOL /*fDisableExternalUiHandler*/, __inout BOOL* /*pfCancel*/ ) { diff --git a/src/balutil/inc/BalBaseBAFunctionsProc.h b/src/balutil/inc/BalBaseBAFunctionsProc.h index da0a71f7..f6ebd9f6 100644 --- a/src/balutil/inc/BalBaseBAFunctionsProc.h +++ b/src/balutil/inc/BalBaseBAFunctionsProc.h @@ -99,6 +99,7 @@ static HRESULT WINAPI BalBaseBAFunctionsProc( case BA_FUNCTIONS_MESSAGE_ONAPPLYCOMPLETE: case BA_FUNCTIONS_MESSAGE_ONLAUNCHAPPROVEDEXEBEGIN: case BA_FUNCTIONS_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE: + case BA_FUNCTIONS_MESSAGE_ONPLANMSIPACKAGE: hr = BalBaseBootstrapperApplicationProc((BOOTSTRAPPER_APPLICATION_MESSAGE)message, pvArgs, pvResults, pvContext); break; case BA_FUNCTIONS_MESSAGE_ONTHEMELOADED: diff --git a/src/balutil/inc/BalBaseBootstrapperApplication.h b/src/balutil/inc/BalBaseBootstrapperApplication.h index 269777a6..1d014419 100644 --- a/src/balutil/inc/BalBaseBootstrapperApplication.h +++ b/src/balutil/inc/BalBaseBootstrapperApplication.h @@ -311,6 +311,20 @@ public: // IBootstrapperApplication return S_OK; } + virtual STDMETHODIMP OnPlanMsiPackage( + __in_z LPCWSTR /*wzPackageId*/, + __in BOOL /*fExecute*/, + __in BOOTSTRAPPER_ACTION_STATE /*action*/, + __inout BOOL* pfCancel, + __inout BURN_MSI_PROPERTY* /*pActionMsiProperty*/, + __inout INSTALLUILEVEL* /*pUiLevel*/, + __inout BOOL* /*pfDisableExternalUiHandler*/ + ) + { + *pfCancel |= CheckCanceled(); + return S_OK; + } + virtual STDMETHODIMP OnPlanPackageComplete( __in_z LPCWSTR /*wzPackageId*/, __in HRESULT /*hrStatus*/, @@ -604,6 +618,8 @@ public: // IBootstrapperApplication __in_z LPCWSTR wzPackageId, __in BOOL fExecute, __in BOOTSTRAPPER_ACTION_STATE /*action*/, + __in INSTALLUILEVEL /*uiLevel*/, + __in BOOL /*fDisableExternalUiHandler*/, __inout BOOL* pfCancel ) { diff --git a/src/balutil/inc/BalBaseBootstrapperApplicationProc.h b/src/balutil/inc/BalBaseBootstrapperApplicationProc.h index 35bc0a9e..d25af1f7 100644 --- a/src/balutil/inc/BalBaseBootstrapperApplicationProc.h +++ b/src/balutil/inc/BalBaseBootstrapperApplicationProc.h @@ -402,7 +402,7 @@ static HRESULT BalBaseBAProcOnExecutePackageBegin( __inout BA_ONEXECUTEPACKAGEBEGIN_RESULTS* pResults ) { - return pBA->OnExecutePackageBegin(pArgs->wzPackageId, pArgs->fExecute, pArgs->action, &pResults->fCancel); + return pBA->OnExecutePackageBegin(pArgs->wzPackageId, pArgs->fExecute, pArgs->action, pArgs->uiLevel, pArgs->fDisableExternalUiHandler, &pResults->fCancel); } static HRESULT BalBaseBAProcOnExecutePatchTarget( @@ -504,6 +504,15 @@ static HRESULT BalBaseBAProcOnLaunchApprovedExeComplete( return pBA->OnLaunchApprovedExeComplete(pArgs->hrStatus, pArgs->dwProcessId); } +static HRESULT BalBaseBAProcOnPlanMsiPackage( + __in IBootstrapperApplication* pBA, + __in BA_ONPLANMSIPACKAGE_ARGS* pArgs, + __inout BA_ONPLANMSIPACKAGE_RESULTS* pResults + ) +{ + return pBA->OnPlanMsiPackage(pArgs->wzPackageId, pArgs->fExecute, pArgs->action, &pResults->fCancel, &pResults->actionMsiProperty, &pResults->uiLevel, &pResults->fDisableExternalUiHandler); +} + /******************************************************************* BalBaseBootstrapperApplicationProc - requires pvContext to be of type IBootstrapperApplication. Provides a default mapping between the new message based BA interface and @@ -689,6 +698,9 @@ static HRESULT WINAPI BalBaseBootstrapperApplicationProc( case BOOTSTRAPPER_APPLICATION_MESSAGE_ONLAUNCHAPPROVEDEXECOMPLETE: hr = BalBaseBAProcOnLaunchApprovedExeComplete(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); break; + case BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANMSIPACKAGE: + hr = BalBaseBAProcOnPlanMsiPackage(pBA, reinterpret_cast(pvArgs), reinterpret_cast(pvResults)); + break; } } diff --git a/src/balutil/inc/IBootstrapperApplication.h b/src/balutil/inc/IBootstrapperApplication.h index 30b456c7..e17d2589 100644 --- a/src/balutil/inc/IBootstrapperApplication.h +++ b/src/balutil/inc/IBootstrapperApplication.h @@ -194,6 +194,18 @@ DECLARE_INTERFACE_IID_(IBootstrapperApplication, IUnknown, "53C31D56-49C0-426B-A __inout BOOL* pfCancel ) = 0; + // OnPlanMsiPackage - called when the engine plans an MSI or MSP package. + // + STDMETHOD(OnPlanMsiPackage)( + __in_z LPCWSTR wzPackageId, + __in BOOL fExecute, // false means rollback. + __in BOOTSTRAPPER_ACTION_STATE action, + __inout BOOL* pfCancel, + __inout BURN_MSI_PROPERTY* pActionMsiProperty, + __inout INSTALLUILEVEL* pUiLevel, + __inout BOOL* pfDisableExternalUiHandler + ) = 0; + // OnPlanPackageComplete - called after the engine plans a package. // STDMETHOD(OnPlanPackageComplete)( @@ -390,6 +402,8 @@ DECLARE_INTERFACE_IID_(IBootstrapperApplication, IUnknown, "53C31D56-49C0-426B-A __in_z LPCWSTR wzPackageId, __in BOOL fExecute, // false means rollback. __in BOOTSTRAPPER_ACTION_STATE action, + __in INSTALLUILEVEL uiLevel, + __in BOOL fDisableExternalUiHandler, __inout BOOL* pfCancel ) = 0; -- cgit v1.2.3-55-g6feb