aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2021-07-02 10:18:08 -0500
committerSean Hall <r.sean.hall@gmail.com>2021-07-02 12:50:09 -0500
commitf43d176f95601ff7524e06247166d4f3b6e61c05 (patch)
tree2e3580ca60c85e1d07a0ab4a2b1279d25fd41f6c
parent9bdf3730cd43e1af8a4ea9be6cf2fba77fcff2d2 (diff)
downloadwix-f43d176f95601ff7524e06247166d4f3b6e61c05.tar.gz
wix-f43d176f95601ff7524e06247166d4f3b6e61c05.tar.bz2
wix-f43d176f95601ff7524e06247166d4f3b6e61c05.zip
Make the BA responsible for parsing restart prompt behavior.
Fixes #4975
-rw-r--r--src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h10
-rw-r--r--src/api/burn/WixToolset.Mba.Core/BootstrapperCommand.cs33
-rw-r--r--src/api/burn/WixToolset.Mba.Core/IBootstrapperApplicationFactory.cs2
-rw-r--r--src/api/burn/WixToolset.Mba.Core/IBootstrapperCommand.cs5
-rw-r--r--src/api/burn/WixToolset.Mba.Core/IMbaCommand.cs5
-rw-r--r--src/api/burn/WixToolset.Mba.Core/MbaCommand.cs2
-rw-r--r--src/api/burn/balutil/balinfo.cpp36
-rw-r--r--src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h28
-rw-r--r--src/api/burn/balutil/inc/balinfo.h12
-rw-r--r--src/api/burn/bextutil/inc/BextBaseBundleExtension.h2
-rw-r--r--src/api/burn/test/BalUtilUnitTest/TestBootstrapperApplication.cpp10
-rw-r--r--src/api/burn/test/WixToolsetTest.Mba.Core/BaseBootstrapperApplicationFactoryFixture.cs1
-rw-r--r--src/burn/engine/core.cpp39
-rw-r--r--src/burn/engine/core.h1
-rw-r--r--src/burn/engine/externalengine.cpp2
-rw-r--r--src/burn/engine/plan.cpp2
-rw-r--r--src/burn/engine/pseudobundle.cpp2
-rw-r--r--src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp127
-rw-r--r--src/ext/Util/be/UtilBundleExtension.cpp4
19 files changed, 180 insertions, 143 deletions
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
11 BOOTSTRAPPER_DISPLAY_FULL, 11 BOOTSTRAPPER_DISPLAY_FULL,
12}; 12};
13 13
14enum BOOTSTRAPPER_RESTART
15{
16 BOOTSTRAPPER_RESTART_UNKNOWN,
17 BOOTSTRAPPER_RESTART_NEVER,
18 BOOTSTRAPPER_RESTART_PROMPT,
19 BOOTSTRAPPER_RESTART_AUTOMATIC,
20 BOOTSTRAPPER_RESTART_ALWAYS,
21};
22
23enum BOOTSTRAPPER_REGISTRATION_TYPE 14enum BOOTSTRAPPER_REGISTRATION_TYPE
24{ 15{
25 BOOTSTRAPPER_REGISTRATION_TYPE_NONE, // The engine will ignore NONE if it recommended INPROGRESS or FULL. 16 BOOTSTRAPPER_REGISTRATION_TYPE_NONE, // The engine will ignore NONE if it recommended INPROGRESS or FULL.
@@ -286,7 +277,6 @@ struct BOOTSTRAPPER_COMMAND
286 DWORD cbSize; 277 DWORD cbSize;
287 BOOTSTRAPPER_ACTION action; 278 BOOTSTRAPPER_ACTION action;
288 BOOTSTRAPPER_DISPLAY display; 279 BOOTSTRAPPER_DISPLAY display;
289 BOOTSTRAPPER_RESTART restart;
290 280
291 LPWSTR wzCommandLine; 281 LPWSTR wzCommandLine;
292 int nCmdShow; 282 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
17 /// </summary> 17 /// </summary>
18 /// <param name="action"></param> 18 /// <param name="action"></param>
19 /// <param name="display"></param> 19 /// <param name="display"></param>
20 /// <param name="restart"></param>
21 /// <param name="commandLine"></param> 20 /// <param name="commandLine"></param>
22 /// <param name="cmdShow"></param> 21 /// <param name="cmdShow"></param>
23 /// <param name="resume"></param> 22 /// <param name="resume"></param>
@@ -30,7 +29,6 @@ namespace WixToolset.Mba.Core
30 public BootstrapperCommand( 29 public BootstrapperCommand(
31 LaunchAction action, 30 LaunchAction action,
32 Display display, 31 Display display,
33 Restart restart,
34 string commandLine, 32 string commandLine,
35 int cmdShow, 33 int cmdShow,
36 ResumeType resume, 34 ResumeType resume,
@@ -43,7 +41,6 @@ namespace WixToolset.Mba.Core
43 { 41 {
44 this.Action = action; 42 this.Action = action;
45 this.Display = display; 43 this.Display = display;
46 this.Restart = restart;
47 this.CommandLine = commandLine; 44 this.CommandLine = commandLine;
48 this.CmdShow = cmdShow; 45 this.CmdShow = cmdShow;
49 this.Resume = resume; 46 this.Resume = resume;
@@ -62,9 +59,6 @@ namespace WixToolset.Mba.Core
62 public Display Display { get; } 59 public Display Display { get; }
63 60
64 /// <inheritdoc/> 61 /// <inheritdoc/>
65 public Restart Restart { get; }
66
67 /// <inheritdoc/>
68 public string CommandLine { get; } 62 public string CommandLine { get; }
69 63
70 /// <inheritdoc/> 64 /// <inheritdoc/>
@@ -97,6 +91,7 @@ namespace WixToolset.Mba.Core
97 var args = ParseCommandLineToArgs(this.CommandLine); 91 var args = ParseCommandLineToArgs(this.CommandLine);
98 var unknownArgs = new List<string>(); 92 var unknownArgs = new List<string>();
99 var variables = new List<KeyValuePair<string, string>>(); 93 var variables = new List<KeyValuePair<string, string>>();
94 var restart = Restart.Unknown;
100 95
101 foreach (var arg in args) 96 foreach (var arg in args)
102 { 97 {
@@ -104,7 +99,25 @@ namespace WixToolset.Mba.Core
104 99
105 if (arg[0] == '-' || arg[0] == '/') 100 if (arg[0] == '-' || arg[0] == '/')
106 { 101 {
107 unknownArg = true; 102 var parameter = arg.Substring(1).ToLowerInvariant();
103 switch (parameter)
104 {
105 case "norestart":
106 if (restart == Restart.Unknown)
107 {
108 restart = Restart.Never;
109 }
110 break;
111 case "forcerestart":
112 if (restart == Restart.Unknown)
113 {
114 restart = Restart.Always;
115 }
116 break;
117 default:
118 unknownArg = true;
119 break;
120 }
108 } 121 }
109 else 122 else
110 { 123 {
@@ -127,8 +140,14 @@ namespace WixToolset.Mba.Core
127 } 140 }
128 } 141 }
129 142
143 if (restart == Restart.Unknown)
144 {
145 restart = this.Display < Display.Full ? Restart.Automatic : Restart.Prompt;
146 }
147
130 return new MbaCommand 148 return new MbaCommand
131 { 149 {
150 Restart = restart,
132 UnknownCommandLineArgs = unknownArgs.ToArray(), 151 UnknownCommandLineArgs = unknownArgs.ToArray(),
133 Variables = variables.ToArray(), 152 Variables = variables.ToArray(),
134 }; 153 };
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
35 [MarshalAs(UnmanagedType.I4)] internal int cbSize; 35 [MarshalAs(UnmanagedType.I4)] internal int cbSize;
36 [MarshalAs(UnmanagedType.U4)] private readonly LaunchAction action; 36 [MarshalAs(UnmanagedType.U4)] private readonly LaunchAction action;
37 [MarshalAs(UnmanagedType.U4)] private readonly Display display; 37 [MarshalAs(UnmanagedType.U4)] private readonly Display display;
38 [MarshalAs(UnmanagedType.U4)] private readonly Restart restart;
39 private readonly IntPtr wzCommandLine; 38 private readonly IntPtr wzCommandLine;
40 [MarshalAs(UnmanagedType.I4)] private readonly int nCmdShow; 39 [MarshalAs(UnmanagedType.I4)] private readonly int nCmdShow;
41 [MarshalAs(UnmanagedType.U4)] private readonly ResumeType resume; 40 [MarshalAs(UnmanagedType.U4)] private readonly ResumeType resume;
@@ -51,7 +50,6 @@ namespace WixToolset.Mba.Core
51 return new BootstrapperCommand( 50 return new BootstrapperCommand(
52 this.action, 51 this.action,
53 this.display, 52 this.display,
54 this.restart,
55 Marshal.PtrToStringUni(this.wzCommandLine), 53 Marshal.PtrToStringUni(this.wzCommandLine),
56 this.nCmdShow, 54 this.nCmdShow,
57 this.resume, 55 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
@@ -20,11 +20,6 @@ namespace WixToolset.Mba.Core
20 Display Display { get; } 20 Display Display { get; }
21 21
22 /// <summary> 22 /// <summary>
23 /// Gets the action to perform if a reboot is required.
24 /// </summary>
25 Restart Restart { get; }
26
27 /// <summary>
28 /// Gets the command line arguments. 23 /// Gets the command line arguments.
29 /// </summary> 24 /// </summary>
30 /// <returns> 25 /// <returns>
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
@@ -10,6 +10,11 @@ namespace WixToolset.Mba.Core
10 public interface IMbaCommand 10 public interface IMbaCommand
11 { 11 {
12 /// <summary> 12 /// <summary>
13 /// Gets the action to perform if a reboot is required.
14 /// </summary>
15 Restart Restart { get; }
16
17 /// <summary>
13 /// The command line arguments not parsed into <see cref="IBootstrapperCommand"/> or <see cref="IMbaCommand"/>. 18 /// The command line arguments not parsed into <see cref="IBootstrapperCommand"/> or <see cref="IMbaCommand"/>.
14 /// </summary> 19 /// </summary>
15 string[] UnknownCommandLineArgs { get; } 20 string[] UnknownCommandLineArgs { get; }
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
9 /// </summary> 9 /// </summary>
10 internal sealed class MbaCommand : IMbaCommand 10 internal sealed class MbaCommand : IMbaCommand
11 { 11 {
12 public Restart Restart { get; internal set; }
13
12 public string[] UnknownCommandLineArgs { get; internal set; } 14 public string[] UnknownCommandLineArgs { get; internal set; }
13 15
14 public KeyValuePair<string, string>[] Variables { get; internal set; } 16 public KeyValuePair<string, string>[] 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(
19 19
20DAPI_(HRESULT) BalInfoParseCommandLine( 20DAPI_(HRESULT) BalInfoParseCommandLine(
21 __in BAL_INFO_COMMAND* pCommand, 21 __in BAL_INFO_COMMAND* pCommand,
22 __in LPCWSTR wzCommandLine 22 __in const BOOTSTRAPPER_COMMAND* pBootstrapperCommand
23 ) 23 )
24{ 24{
25 HRESULT hr = S_OK; 25 HRESULT hr = S_OK;
@@ -29,13 +29,13 @@ DAPI_(HRESULT) BalInfoParseCommandLine(
29 29
30 BalInfoUninitializeCommandLine(pCommand); 30 BalInfoUninitializeCommandLine(pCommand);
31 31
32 if (!wzCommandLine || !*wzCommandLine) 32 if (!pBootstrapperCommand->wzCommandLine || !*pBootstrapperCommand->wzCommandLine)
33 { 33 {
34 ExitFunction(); 34 ExitFunction();
35 } 35 }
36 36
37 hr = AppParseCommandLine(wzCommandLine, &argc, &argv); 37 hr = AppParseCommandLine(pBootstrapperCommand->wzCommandLine, &argc, &argv);
38 ExitOnFailure(hr, "Failed to parse command line."); 38 BalExitOnFailure(hr, "Failed to parse command line.");
39 39
40 for (int i = 0; i < argc; ++i) 40 for (int i = 0; i < argc; ++i)
41 { 41 {
@@ -43,7 +43,24 @@ DAPI_(HRESULT) BalInfoParseCommandLine(
43 43
44 if (argv[i][0] == L'-' || argv[i][0] == L'/') 44 if (argv[i][0] == L'-' || argv[i][0] == L'/')
45 { 45 {
46 fUnknownArg = TRUE; 46 if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"norestart", -1))
47 {
48 if (BAL_INFO_RESTART_UNKNOWN == pCommand->restart)
49 {
50 pCommand->restart = BAL_INFO_RESTART_NEVER;
51 }
52 }
53 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"forcerestart", -1))
54 {
55 if (BAL_INFO_RESTART_UNKNOWN == pCommand->restart)
56 {
57 pCommand->restart = BAL_INFO_RESTART_ALWAYS;
58 }
59 }
60 else
61 {
62 fUnknownArg = TRUE;
63 }
47 } 64 }
48 else 65 else
49 { 66 {
@@ -55,10 +72,10 @@ DAPI_(HRESULT) BalInfoParseCommandLine(
55 else 72 else
56 { 73 {
57 hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(&pCommand->rgVariableNames), pCommand->cVariables, 1, sizeof(LPWSTR), 5); 74 hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(&pCommand->rgVariableNames), pCommand->cVariables, 1, sizeof(LPWSTR), 5);
58 ExitOnFailure(hr, "Failed to ensure size for variable names."); 75 BalExitOnFailure(hr, "Failed to ensure size for variable names.");
59 76
60 hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(&pCommand->rgVariableValues), pCommand->cVariables, 1, sizeof(LPWSTR), 5); 77 hr = MemEnsureArraySizeForNewItems(reinterpret_cast<LPVOID*>(&pCommand->rgVariableValues), pCommand->cVariables, 1, sizeof(LPWSTR), 5);
61 ExitOnFailure(hr, "Failed to ensure size for variable values."); 78 BalExitOnFailure(hr, "Failed to ensure size for variable values.");
62 79
63 LPWSTR* psczVariableName = pCommand->rgVariableNames + pCommand->cVariables; 80 LPWSTR* psczVariableName = pCommand->rgVariableNames + pCommand->cVariables;
64 LPWSTR* psczVariableValue = pCommand->rgVariableValues + pCommand->cVariables; 81 LPWSTR* psczVariableValue = pCommand->rgVariableValues + pCommand->cVariables;
@@ -86,6 +103,11 @@ DAPI_(HRESULT) BalInfoParseCommandLine(
86 } 103 }
87 104
88LExit: 105LExit:
106 if (BAL_INFO_RESTART_UNKNOWN == pCommand->restart)
107 {
108 pCommand->restart = BOOTSTRAPPER_DISPLAY_FULL > pBootstrapperCommand->display ? BAL_INFO_RESTART_AUTOMATIC : BAL_INFO_RESTART_PROMPT;
109 }
110
89 if (argv) 111 if (argv)
90 { 112 {
91 AppFreeCommandLineArgs(argv); 113 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 @@
9#include "IBootstrapperApplication.h" 9#include "IBootstrapperApplication.h"
10 10
11#include "balutil.h" 11#include "balutil.h"
12#include "balinfo.h"
12#include "balretry.h" 13#include "balretry.h"
13 14
14class CBalBaseBootstrapperApplication : public IBootstrapperApplication 15class CBalBaseBootstrapperApplication : public IBootstrapperApplication
@@ -794,7 +795,7 @@ public: // IBootstrapperApplication
794 { 795 {
795 HRESULT hr = S_OK; 796 HRESULT hr = S_OK;
796 BOOL fRestartRequired = BOOTSTRAPPER_APPLY_RESTART_REQUIRED == restart; 797 BOOL fRestartRequired = BOOTSTRAPPER_APPLY_RESTART_REQUIRED == restart;
797 BOOL fShouldBlockRestart = BOOTSTRAPPER_DISPLAY_FULL <= m_display && BOOTSTRAPPER_RESTART_PROMPT >= m_restart; 798 BOOL fShouldBlockRestart = BOOTSTRAPPER_DISPLAY_FULL <= m_display && BAL_INFO_RESTART_PROMPT >= m_BalInfoCommand.restart;
798 799
799 if (fRestartRequired && !fShouldBlockRestart) 800 if (fRestartRequired && !fShouldBlockRestart)
800 { 801 {
@@ -976,6 +977,22 @@ public: // IBootstrapperApplication
976 return S_OK; 977 return S_OK;
977 } 978 }
978 979
980public: //CBalBaseBootstrapperApplication
981 virtual STDMETHODIMP Initialize(
982 __in const BOOTSTRAPPER_CREATE_ARGS* pCreateArgs
983 )
984 {
985 HRESULT hr = S_OK;
986
987 m_display = pCreateArgs->pCommand->display;
988
989 hr = BalInfoParseCommandLine(&m_BalInfoCommand, pCreateArgs->pCommand);
990 BalExitOnFailure(hr, "Failed to parse command line with balutil.");
991
992 LExit:
993 return hr;
994 }
995
979protected: 996protected:
980 // 997 //
981 // PromptCancel - prompts the user to close (if not forced). 998 // PromptCancel - prompts the user to close (if not forced).
@@ -1029,20 +1046,19 @@ protected:
1029 1046
1030 CBalBaseBootstrapperApplication( 1047 CBalBaseBootstrapperApplication(
1031 __in IBootstrapperEngine* pEngine, 1048 __in IBootstrapperEngine* pEngine,
1032 __in const BOOTSTRAPPER_CREATE_ARGS* pArgs,
1033 __in DWORD dwRetryCount = 0, 1049 __in DWORD dwRetryCount = 0,
1034 __in DWORD dwRetryTimeout = 1000 1050 __in DWORD dwRetryTimeout = 1000
1035 ) 1051 )
1036 { 1052 {
1037 m_cReferences = 1; 1053 m_cReferences = 1;
1038 m_display = pArgs->pCommand->display; 1054 m_display = BOOTSTRAPPER_DISPLAY_UNKNOWN;
1039 m_restart = pArgs->pCommand->restart;
1040 1055
1041 pEngine->AddRef(); 1056 pEngine->AddRef();
1042 m_pEngine = pEngine; 1057 m_pEngine = pEngine;
1043 1058
1044 ::InitializeCriticalSection(&m_csCanceled); 1059 ::InitializeCriticalSection(&m_csCanceled);
1045 m_fCanceled = FALSE; 1060 m_fCanceled = FALSE;
1061 m_BalInfoCommand = { };
1046 m_fApplying = FALSE; 1062 m_fApplying = FALSE;
1047 m_fRollingBack = FALSE; 1063 m_fRollingBack = FALSE;
1048 1064
@@ -1054,6 +1070,7 @@ protected:
1054 1070
1055 virtual ~CBalBaseBootstrapperApplication() 1071 virtual ~CBalBaseBootstrapperApplication()
1056 { 1072 {
1073 BalInfoUninitializeCommandLine(&m_BalInfoCommand);
1057 BalRetryUninitialize(); 1074 BalRetryUninitialize();
1058 ::DeleteCriticalSection(&m_csCanceled); 1075 ::DeleteCriticalSection(&m_csCanceled);
1059 1076
@@ -1064,10 +1081,11 @@ protected:
1064 CRITICAL_SECTION m_csCanceled; 1081 CRITICAL_SECTION m_csCanceled;
1065 BOOL m_fCanceled; 1082 BOOL m_fCanceled;
1066 1083
1084 BAL_INFO_COMMAND m_BalInfoCommand;
1085
1067private: 1086private:
1068 long m_cReferences; 1087 long m_cReferences;
1069 BOOTSTRAPPER_DISPLAY m_display; 1088 BOOTSTRAPPER_DISPLAY m_display;
1070 BOOTSTRAPPER_RESTART m_restart;
1071 IBootstrapperEngine* m_pEngine; 1089 IBootstrapperEngine* m_pEngine;
1072 1090
1073 BOOL m_fApplying; 1091 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
18 BAL_INFO_PACKAGE_TYPE_BUNDLE_PATCH, 18 BAL_INFO_PACKAGE_TYPE_BUNDLE_PATCH,
19} BAL_INFO_PACKAGE_TYPE; 19} BAL_INFO_PACKAGE_TYPE;
20 20
21typedef enum _BAL_INFO_RESTART
22{
23 BAL_INFO_RESTART_UNKNOWN,
24 BAL_INFO_RESTART_NEVER,
25 BAL_INFO_RESTART_PROMPT,
26 BAL_INFO_RESTART_AUTOMATIC,
27 BAL_INFO_RESTART_ALWAYS,
28} BAL_INFO_RESTART;
29
21typedef enum _BAL_INFO_VARIABLE_COMMAND_LINE_TYPE 30typedef enum _BAL_INFO_VARIABLE_COMMAND_LINE_TYPE
22{ 31{
23 BAL_INFO_VARIABLE_COMMAND_LINE_TYPE_UPPER_CASE, 32 BAL_INFO_VARIABLE_COMMAND_LINE_TYPE_UPPER_CASE,
@@ -85,6 +94,7 @@ typedef struct _BAL_INFO_COMMAND
85 DWORD cVariables; 94 DWORD cVariables;
86 LPWSTR* rgVariableNames; 95 LPWSTR* rgVariableNames;
87 LPWSTR* rgVariableValues; 96 LPWSTR* rgVariableValues;
97 BAL_INFO_RESTART restart;
88} BAL_INFO_COMMAND; 98} BAL_INFO_COMMAND;
89 99
90 100
@@ -94,7 +104,7 @@ typedef struct _BAL_INFO_COMMAND
94********************************************************************/ 104********************************************************************/
95HRESULT DAPI BalInfoParseCommandLine( 105HRESULT DAPI BalInfoParseCommandLine(
96 __in BAL_INFO_COMMAND* pCommand, 106 __in BAL_INFO_COMMAND* pCommand,
97 __in LPCWSTR wzCommandLine 107 __in const BOOTSTRAPPER_COMMAND* pBootstrapperCommand
98 ); 108 );
99 109
100 110
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
80public: //CBextBaseBundleExtension 80public: //CBextBaseBundleExtension
81 virtual STDMETHODIMP Initialize( 81 virtual STDMETHODIMP Initialize(
82 __in const BUNDLE_EXTENSION_CREATE_ARGS* pCreateArgs 82 __in const BUNDLE_EXTENSION_CREATE_ARGS* pCreateArgs
83 ) 83 )
84 { 84 {
85 HRESULT hr = S_OK; 85 HRESULT hr = S_OK;
86 86
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
8{ 8{
9public: 9public:
10 CTestBootstrapperApplication( 10 CTestBootstrapperApplication(
11 __in IBootstrapperEngine* pEngine, 11 __in IBootstrapperEngine* pEngine
12 __in const BOOTSTRAPPER_CREATE_ARGS* pArgs 12 ) : CBalBaseBootstrapperApplication(pEngine)
13 ) : CBalBaseBootstrapperApplication(pEngine, pArgs)
14 { 13 {
15 } 14 }
16}; 15};
@@ -25,9 +24,12 @@ HRESULT CreateBootstrapperApplication(
25 HRESULT hr = S_OK; 24 HRESULT hr = S_OK;
26 CTestBootstrapperApplication* pApplication = NULL; 25 CTestBootstrapperApplication* pApplication = NULL;
27 26
28 pApplication = new CTestBootstrapperApplication(pEngine, pArgs); 27 pApplication = new CTestBootstrapperApplication(pEngine);
29 ExitOnNull(pApplication, hr, E_OUTOFMEMORY, "Failed to create new test bootstrapper application object."); 28 ExitOnNull(pApplication, hr, E_OUTOFMEMORY, "Failed to create new test bootstrapper application object.");
30 29
30 hr = pApplication->Initialize(pArgs);
31 ExitOnFailure(hr, "CTestBootstrapperApplication initialization failed.");
32
31 pResults->pfnBootstrapperApplicationProc = BalBaseBootstrapperApplicationProc; 33 pResults->pfnBootstrapperApplicationProc = BalBaseBootstrapperApplicationProc;
32 pResults->pvBootstrapperApplicationProcContext = pApplication; 34 pResults->pvBootstrapperApplicationProcContext = pApplication;
33 *ppApplication = pApplication; 35 *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
101 public int cbSize; 101 public int cbSize;
102 public LaunchAction action; 102 public LaunchAction action;
103 public Display display; 103 public Display display;
104 public Restart restart;
105 [MarshalAs(UnmanagedType.LPWStr)] public string wzCommandLine; 104 [MarshalAs(UnmanagedType.LPWStr)] public string wzCommandLine;
106 public int nCmdShow; 105 public int nCmdShow;
107 public ResumeType resume; 106 public ResumeType resume;
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp
index 8b97952c..f71103a8 100644
--- a/src/burn/engine/core.cpp
+++ b/src/burn/engine/core.cpp
@@ -924,7 +924,6 @@ extern "C" HRESULT CoreRecreateCommandLine(
924 __deref_inout_z LPWSTR* psczCommandLine, 924 __deref_inout_z LPWSTR* psczCommandLine,
925 __in BOOTSTRAPPER_ACTION action, 925 __in BOOTSTRAPPER_ACTION action,
926 __in BOOTSTRAPPER_DISPLAY display, 926 __in BOOTSTRAPPER_DISPLAY display,
927 __in BOOTSTRAPPER_RESTART restart,
928 __in BOOTSTRAPPER_RELATION_TYPE relationType, 927 __in BOOTSTRAPPER_RELATION_TYPE relationType,
929 __in BOOL fPassthrough, 928 __in BOOL fPassthrough,
930 __in_z_opt LPCWSTR wzActiveParent, 929 __in_z_opt LPCWSTR wzActiveParent,
@@ -965,17 +964,6 @@ extern "C" HRESULT CoreRecreateCommandLine(
965 } 964 }
966 ExitOnFailure(hr, "Failed to append action state to command-line"); 965 ExitOnFailure(hr, "Failed to append action state to command-line");
967 966
968 switch (restart)
969 {
970 case BOOTSTRAPPER_RESTART_ALWAYS:
971 hr = StrAllocConcat(psczCommandLine, L" /forcerestart", 0);
972 break;
973 case BOOTSTRAPPER_RESTART_NEVER:
974 hr = StrAllocConcat(psczCommandLine, L" /norestart", 0);
975 break;
976 }
977 ExitOnFailure(hr, "Failed to append restart state to command-line");
978
979 if (wzActiveParent) 967 if (wzActiveParent)
980 { 968 {
981 if (*wzActiveParent) 969 if (*wzActiveParent)
@@ -1246,32 +1234,10 @@ extern "C" HRESULT CoreParseCommandLine(
1246 CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"silent", -1)) 1234 CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"silent", -1))
1247 { 1235 {
1248 pCommand->display = BOOTSTRAPPER_DISPLAY_NONE; 1236 pCommand->display = BOOTSTRAPPER_DISPLAY_NONE;
1249
1250 if (BOOTSTRAPPER_RESTART_UNKNOWN == pCommand->restart)
1251 {
1252 pCommand->restart = BOOTSTRAPPER_RESTART_AUTOMATIC;
1253 }
1254 } 1237 }
1255 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"passive", -1)) 1238 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"passive", -1))
1256 { 1239 {
1257 pCommand->display = BOOTSTRAPPER_DISPLAY_PASSIVE; 1240 pCommand->display = BOOTSTRAPPER_DISPLAY_PASSIVE;
1258
1259 if (BOOTSTRAPPER_RESTART_UNKNOWN == pCommand->restart)
1260 {
1261 pCommand->restart = BOOTSTRAPPER_RESTART_AUTOMATIC;
1262 }
1263 }
1264 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"norestart", -1))
1265 {
1266 pCommand->restart = BOOTSTRAPPER_RESTART_NEVER;
1267 }
1268 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"forcerestart", -1))
1269 {
1270 pCommand->restart = BOOTSTRAPPER_RESTART_ALWAYS;
1271 }
1272 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"promptrestart", -1))
1273 {
1274 pCommand->restart = BOOTSTRAPPER_RESTART_PROMPT;
1275 } 1241 }
1276 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"layout", -1)) 1242 else if (CSTR_EQUAL == ::CompareStringW(LOCALE_INVARIANT, NORM_IGNORECASE, &argv[i][1], -1, L"layout", -1))
1277 { 1243 {
@@ -1653,11 +1619,6 @@ extern "C" HRESULT CoreParseCommandLine(
1653 pCommand->display = BOOTSTRAPPER_DISPLAY_FULL; 1619 pCommand->display = BOOTSTRAPPER_DISPLAY_FULL;
1654 } 1620 }
1655 1621
1656 if (BOOTSTRAPPER_RESTART_UNKNOWN == pCommand->restart)
1657 {
1658 pCommand->restart = BOOTSTRAPPER_RESTART_PROMPT;
1659 }
1660
1661LExit: 1622LExit:
1662 if (fInvalidCommandLine) 1623 if (fInvalidCommandLine)
1663 { 1624 {
diff --git a/src/burn/engine/core.h b/src/burn/engine/core.h
index 0a92d64f..3fa1f04a 100644
--- a/src/burn/engine/core.h
+++ b/src/burn/engine/core.h
@@ -210,7 +210,6 @@ HRESULT CoreRecreateCommandLine(
210 __deref_inout_z LPWSTR* psczCommandLine, 210 __deref_inout_z LPWSTR* psczCommandLine,
211 __in BOOTSTRAPPER_ACTION action, 211 __in BOOTSTRAPPER_ACTION action,
212 __in BOOTSTRAPPER_DISPLAY display, 212 __in BOOTSTRAPPER_DISPLAY display,
213 __in BOOTSTRAPPER_RESTART restart,
214 __in BOOTSTRAPPER_RELATION_TYPE relationType, 213 __in BOOTSTRAPPER_RELATION_TYPE relationType,
215 __in BOOL fPassthrough, 214 __in BOOL fPassthrough,
216 __in_z_opt LPCWSTR wzActiveParent, 215 __in_z_opt LPCWSTR wzActiveParent,
diff --git a/src/burn/engine/externalengine.cpp b/src/burn/engine/externalengine.cpp
index 409353e4..a5f75bd4 100644
--- a/src/burn/engine/externalengine.cpp
+++ b/src/burn/engine/externalengine.cpp
@@ -295,7 +295,7 @@ HRESULT ExternalEngineSetUpdate(
295 { 295 {
296 UpdateUninitialize(&pEngineState->update); 296 UpdateUninitialize(&pEngineState->update);
297 297
298 hr = CoreRecreateCommandLine(&sczCommandline, BOOTSTRAPPER_ACTION_INSTALL, pEngineState->command.display, pEngineState->command.restart, BOOTSTRAPPER_RELATION_NONE, FALSE, pEngineState->registration.sczActiveParent, pEngineState->registration.sczAncestors, NULL, pEngineState->command.wzCommandLine); 298 hr = CoreRecreateCommandLine(&sczCommandline, BOOTSTRAPPER_ACTION_INSTALL, pEngineState->command.display, BOOTSTRAPPER_RELATION_NONE, FALSE, pEngineState->registration.sczActiveParent, pEngineState->registration.sczAncestors, NULL, pEngineState->command.wzCommandLine);
299 ExitOnFailure(hr, "Failed to recreate command-line for update bundle."); 299 ExitOnFailure(hr, "Failed to recreate 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.
diff --git a/src/burn/engine/plan.cpp b/src/burn/engine/plan.cpp
index d1f07508..3d6fc65f 100644
--- a/src/burn/engine/plan.cpp
+++ b/src/burn/engine/plan.cpp
@@ -1783,7 +1783,7 @@ extern "C" HRESULT PlanSetResumeCommand(
1783 HRESULT hr = S_OK; 1783 HRESULT hr = S_OK;
1784 1784
1785 // build the resume command-line. 1785 // build the resume command-line.
1786 hr = CoreRecreateCommandLine(&pRegistration->sczResumeCommandLine, action, pCommand->display, pCommand->restart, pCommand->relationType, pCommand->fPassthrough, pRegistration->sczActiveParent, pRegistration->sczAncestors, pLog->sczPath, pCommand->wzCommandLine); 1786 hr = CoreRecreateCommandLine(&pRegistration->sczResumeCommandLine, action, pCommand->display, pCommand->relationType, pCommand->fPassthrough, pRegistration->sczActiveParent, pRegistration->sczAncestors, pLog->sczPath, pCommand->wzCommandLine);
1787 ExitOnFailure(hr, "Failed to recreate resume command-line."); 1787 ExitOnFailure(hr, "Failed to recreate resume command-line.");
1788 1788
1789LExit: 1789LExit:
diff --git a/src/burn/engine/pseudobundle.cpp b/src/burn/engine/pseudobundle.cpp
index 1b2eae75..351fe044 100644
--- a/src/burn/engine/pseudobundle.cpp
+++ b/src/burn/engine/pseudobundle.cpp
@@ -205,7 +205,7 @@ extern "C" HRESULT PseudoBundleInitializePassthrough(
205 205
206 // No matter the operation, we're passing the same command-line. That's what makes 206 // No matter the operation, we're passing the same command-line. That's what makes
207 // this a passthrough bundle. 207 // this a passthrough bundle.
208 hr = CoreRecreateCommandLine(&sczArguments, pCommand->action, pCommand->display, pCommand->restart, pCommand->relationType, TRUE, wzActiveParent, wzAncestors, wzAppendLogPath, pCommand->wzCommandLine); 208 hr = CoreRecreateCommandLine(&sczArguments, pCommand->action, pCommand->display, pCommand->relationType, TRUE, wzActiveParent, wzAncestors, wzAppendLogPath, pCommand->wzCommandLine);
209 ExitOnFailure(hr, "Failed to recreate command-line arguments."); 209 ExitOnFailure(hr, "Failed to recreate command-line arguments.");
210 210
211 hr = StrAllocString(&pPassthroughPackage->Exe.sczInstallArguments, sczArguments, 0); 211 hr = StrAllocString(&pPassthroughPackage->Exe.sczInstallArguments, sczArguments, 0);
diff --git a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
index 9f0b0082..bbe926f1 100644
--- a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
+++ b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
@@ -206,7 +206,7 @@ public: // IBootstrapperApplication
206 m_hUiThread = ::CreateThread(NULL, 0, UiThreadProc, this, 0, &dwUIThreadId); 206 m_hUiThread = ::CreateThread(NULL, 0, UiThreadProc, this, 0, &dwUIThreadId);
207 if (!m_hUiThread) 207 if (!m_hUiThread)
208 { 208 {
209 ExitWithLastError(hr, "Failed to create UI thread."); 209 BalExitWithLastError(hr, "Failed to create UI thread.");
210 } 210 }
211 211
212 LExit: 212 LExit:
@@ -1100,10 +1100,10 @@ public: // IBootstrapperApplication
1100 m_fRestartRequired = BOOTSTRAPPER_APPLY_RESTART_NONE != restart; 1100 m_fRestartRequired = BOOTSTRAPPER_APPLY_RESTART_NONE != restart;
1101 BalSetStringVariable(WIXSTDBA_VARIABLE_RESTART_REQUIRED, m_fRestartRequired ? L"1" : NULL, FALSE); 1101 BalSetStringVariable(WIXSTDBA_VARIABLE_RESTART_REQUIRED, m_fRestartRequired ? L"1" : NULL, FALSE);
1102 1102
1103 m_fShouldRestart = m_fRestartRequired && BOOTSTRAPPER_RESTART_NEVER < m_command.restart; 1103 m_fShouldRestart = m_fRestartRequired && BAL_INFO_RESTART_NEVER < m_BalInfoCommand.restart;
1104 1104
1105 // Automatically restart if we're not displaying a UI or the command line said to always allow restarts. 1105 // Automatically restart if we're not displaying a UI or the command line said to always allow restarts.
1106 m_fAllowRestart = m_fShouldRestart && (BOOTSTRAPPER_DISPLAY_FULL > m_command.display || BOOTSTRAPPER_RESTART_PROMPT < m_command.restart); 1106 m_fAllowRestart = m_fShouldRestart && (BOOTSTRAPPER_DISPLAY_FULL > m_command.display || BAL_INFO_RESTART_PROMPT < m_BalInfoCommand.restart);
1107 1107
1108 if (m_fPrereq) 1108 if (m_fPrereq)
1109 { 1109 {
@@ -1986,6 +1986,62 @@ private: // privates
1986 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEPAYLOADEXTRACTPROGRESS, pArgs, pResults, m_pvBAFunctionsProcContext); 1986 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONCACHEPAYLOADEXTRACTPROGRESS, pArgs, pResults, m_pvBAFunctionsProcContext);
1987 } 1987 }
1988 1988
1989
1990public: //CBalBaseBootstrapperApplication
1991 virtual STDMETHODIMP Initialize(
1992 __in const BOOTSTRAPPER_CREATE_ARGS* pCreateArgs
1993 )
1994 {
1995 HRESULT hr = S_OK;
1996 LONGLONG llInstalled = 0;
1997
1998 hr = __super::Initialize(pCreateArgs);
1999 BalExitOnFailure(hr, "CBalBaseBootstrapperApplication initialization failed.");
2000
2001 memcpy_s(&m_command, sizeof(m_command), pCreateArgs->pCommand, sizeof(BOOTSTRAPPER_COMMAND));
2002 memcpy_s(&m_createArgs, sizeof(m_createArgs), pCreateArgs, sizeof(BOOTSTRAPPER_CREATE_ARGS));
2003 m_createArgs.pCommand = &m_command;
2004
2005 if (m_fPrereq)
2006 {
2007 // Pre-req BA should only show help or do an install (to launch the Managed BA which can then do the right action).
2008 if (BOOTSTRAPPER_ACTION_HELP != m_command.action)
2009 {
2010 m_command.action = BOOTSTRAPPER_ACTION_INSTALL;
2011 }
2012 }
2013 else // maybe modify the action state if the bundle is or is not already installed.
2014 {
2015 hr = BalGetNumericVariable(L"WixBundleInstalled", &llInstalled);
2016 if (SUCCEEDED(hr) && BOOTSTRAPPER_RESUME_TYPE_REBOOT != m_command.resumeType && llInstalled && BOOTSTRAPPER_ACTION_INSTALL == m_command.action)
2017 {
2018 m_command.action = BOOTSTRAPPER_ACTION_MODIFY;
2019 }
2020 else if (!llInstalled && (BOOTSTRAPPER_ACTION_MODIFY == m_command.action || BOOTSTRAPPER_ACTION_REPAIR == m_command.action))
2021 {
2022 m_command.action = BOOTSTRAPPER_ACTION_INSTALL;
2023 }
2024 }
2025
2026 // When resuming from restart doing some install-like operation, try to find the package that forced the
2027 // restart. We'll use this information during planning.
2028 if (BOOTSTRAPPER_RESUME_TYPE_REBOOT == m_command.resumeType && BOOTSTRAPPER_ACTION_UNINSTALL < m_command.action)
2029 {
2030 // Ensure the forced restart package variable is null when it is an empty string.
2031 hr = BalGetStringVariable(L"WixBundleForcedRestartPackage", &m_sczAfterForcedRestartPackage);
2032 if (FAILED(hr) || !m_sczAfterForcedRestartPackage || !*m_sczAfterForcedRestartPackage)
2033 {
2034 ReleaseNullStr(m_sczAfterForcedRestartPackage);
2035 }
2036 }
2037
2038 hr = S_OK;
2039
2040 LExit:
2041 return hr;
2042 }
2043
2044private:
1989 // 2045 //
1990 // UiThreadProc - entrypoint for UI thread. 2046 // UiThreadProc - entrypoint for UI thread.
1991 // 2047 //
@@ -2172,9 +2228,6 @@ private: // privates
2172 LPWSTR* argv = NULL; 2228 LPWSTR* argv = NULL;
2173 BOOL fUnknownArg = FALSE; 2229 BOOL fUnknownArg = FALSE;
2174 2230
2175 hr = BalInfoParseCommandLine(&m_BalInfoCommand, m_command.wzCommandLine);
2176 BalExitOnFailure(hr, "Failed to parse command line with balutil.");
2177
2178 argc = m_BalInfoCommand.cUnknownArgs; 2231 argc = m_BalInfoCommand.cUnknownArgs;
2179 argv = m_BalInfoCommand.rgUnknownArgs; 2232 argv = m_BalInfoCommand.rgUnknownArgs;
2180 2233
@@ -3139,7 +3192,7 @@ private: // privates
3139 BOOL fLaunchTargetExists = FALSE; 3192 BOOL fLaunchTargetExists = FALSE;
3140 if (m_fShouldRestart) 3193 if (m_fShouldRestart)
3141 { 3194 {
3142 if (BOOTSTRAPPER_RESTART_PROMPT == m_command.restart) 3195 if (BAL_INFO_RESTART_PROMPT == m_BalInfoCommand.restart)
3143 { 3196 {
3144 fEnableRestartButton = TRUE; 3197 fEnableRestartButton = TRUE;
3145 } 3198 }
@@ -3240,7 +3293,7 @@ private: // privates
3240 3293
3241 if (m_fShouldRestart) 3294 if (m_fShouldRestart)
3242 { 3295 {
3243 if (BOOTSTRAPPER_RESTART_PROMPT == m_command.restart) 3296 if (BAL_INFO_RESTART_PROMPT == m_BalInfoCommand.restart)
3244 { 3297 {
3245 fEnableRestartButton = TRUE; 3298 fEnableRestartButton = TRUE;
3246 } 3299 }
@@ -3832,57 +3885,20 @@ public:
3832 __in HMODULE hModule, 3885 __in HMODULE hModule,
3833 __in BOOL fPrereq, 3886 __in BOOL fPrereq,
3834 __in HRESULT hrHostInitialization, 3887 __in HRESULT hrHostInitialization,
3835 __in IBootstrapperEngine* pEngine, 3888 __in IBootstrapperEngine* pEngine
3836 __in const BOOTSTRAPPER_CREATE_ARGS* pArgs 3889 ) : CBalBaseBootstrapperApplication(pEngine, 3, 3000)
3837 ) : CBalBaseBootstrapperApplication(pEngine, pArgs, 3, 3000)
3838 { 3890 {
3839 m_hModule = hModule; 3891 m_hModule = hModule;
3840 memcpy_s(&m_command, sizeof(m_command), pArgs->pCommand, sizeof(BOOTSTRAPPER_COMMAND)); 3892 m_command = { };
3841 memcpy_s(&m_createArgs, sizeof(m_createArgs), pArgs, sizeof(BOOTSTRAPPER_CREATE_ARGS)); 3893 m_createArgs = { };
3842 m_createArgs.pCommand = &m_command;
3843
3844 if (fPrereq)
3845 {
3846 // Pre-req BA should only show help or do an install (to launch the Managed BA which can then do the right action).
3847 if (BOOTSTRAPPER_ACTION_HELP != m_command.action)
3848 {
3849 m_command.action = BOOTSTRAPPER_ACTION_INSTALL;
3850 }
3851 }
3852 else // maybe modify the action state if the bundle is or is not already installed.
3853 {
3854 LONGLONG llInstalled = 0;
3855 HRESULT hr = BalGetNumericVariable(L"WixBundleInstalled", &llInstalled);
3856 if (SUCCEEDED(hr) && BOOTSTRAPPER_RESUME_TYPE_REBOOT != m_command.resumeType && 0 < llInstalled && BOOTSTRAPPER_ACTION_INSTALL == m_command.action)
3857 {
3858 m_command.action = BOOTSTRAPPER_ACTION_MODIFY;
3859 }
3860 else if (0 == llInstalled && (BOOTSTRAPPER_ACTION_MODIFY == m_command.action || BOOTSTRAPPER_ACTION_REPAIR == m_command.action))
3861 {
3862 m_command.action = BOOTSTRAPPER_ACTION_INSTALL;
3863 }
3864 }
3865 3894
3866 m_plannedAction = BOOTSTRAPPER_ACTION_UNKNOWN; 3895 m_plannedAction = BOOTSTRAPPER_ACTION_UNKNOWN;
3867 3896
3868 // When resuming from restart doing some install-like operation, try to find the package that forced the
3869 // restart. We'll use this information during planning.
3870 m_sczAfterForcedRestartPackage = NULL; 3897 m_sczAfterForcedRestartPackage = NULL;
3871 3898
3872 if (BOOTSTRAPPER_RESUME_TYPE_REBOOT == m_command.resumeType && BOOTSTRAPPER_ACTION_UNINSTALL < m_command.action)
3873 {
3874 // Ensure the forced restart package variable is null when it is an empty string.
3875 HRESULT hr = BalGetStringVariable(L"WixBundleForcedRestartPackage", &m_sczAfterForcedRestartPackage);
3876 if (FAILED(hr) || !m_sczAfterForcedRestartPackage || !*m_sczAfterForcedRestartPackage)
3877 {
3878 ReleaseNullStr(m_sczAfterForcedRestartPackage);
3879 }
3880 }
3881
3882 m_pWixLoc = NULL; 3899 m_pWixLoc = NULL;
3883 memset(&m_Bundle, 0, sizeof(m_Bundle)); 3900 m_Bundle = { };
3884 memset(&m_BalInfoCommand, 0, sizeof(m_BalInfoCommand)); 3901 m_Conditions = { };
3885 memset(&m_Conditions, 0, sizeof(m_Conditions));
3886 m_sczConfirmCloseMessage = NULL; 3902 m_sczConfirmCloseMessage = NULL;
3887 m_sczFailedMessage = NULL; 3903 m_sczFailedMessage = NULL;
3888 3904
@@ -3947,7 +3963,6 @@ public:
3947 ReleaseStr(m_sczConfirmCloseMessage); 3963 ReleaseStr(m_sczConfirmCloseMessage);
3948 BalConditionsUninitialize(&m_Conditions); 3964 BalConditionsUninitialize(&m_Conditions);
3949 BalInfoUninitialize(&m_Bundle); 3965 BalInfoUninitialize(&m_Bundle);
3950 BalInfoUninitializeCommandLine(&m_BalInfoCommand);
3951 LocFree(m_pWixLoc); 3966 LocFree(m_pWixLoc);
3952 3967
3953 ReleaseStr(m_sczLanguage); 3968 ReleaseStr(m_sczLanguage);
@@ -3980,7 +3995,6 @@ private:
3980 3995
3981 WIX_LOCALIZATION* m_pWixLoc; 3996 WIX_LOCALIZATION* m_pWixLoc;
3982 BAL_INFO_BUNDLE m_Bundle; 3997 BAL_INFO_BUNDLE m_Bundle;
3983 BAL_INFO_COMMAND m_BalInfoCommand;
3984 BAL_CONDITIONS m_Conditions; 3998 BAL_CONDITIONS m_Conditions;
3985 LPWSTR m_sczFailedMessage; 3999 LPWSTR m_sczFailedMessage;
3986 LPWSTR m_sczConfirmCloseMessage; 4000 LPWSTR m_sczConfirmCloseMessage;
@@ -4049,8 +4063,11 @@ HRESULT CreateBootstrapperApplication(
4049 BalExitOnFailure(hr = E_INVALIDARG, "Engine requested Unknown display type."); 4063 BalExitOnFailure(hr = E_INVALIDARG, "Engine requested Unknown display type.");
4050 } 4064 }
4051 4065
4052 pApplication = new CWixStandardBootstrapperApplication(hModule, fPrereq, hrHostInitialization, pEngine, pArgs); 4066 pApplication = new CWixStandardBootstrapperApplication(hModule, fPrereq, hrHostInitialization, pEngine);
4053 ExitOnNull(pApplication, hr, E_OUTOFMEMORY, "Failed to create new standard bootstrapper application object."); 4067 BalExitOnNull(pApplication, hr, E_OUTOFMEMORY, "Failed to create new standard bootstrapper application object.");
4068
4069 hr = pApplication->Initialize(pArgs);
4070 ExitOnFailure(hr, "CWixStandardBootstrapperApplication initialization failed.");
4054 4071
4055 pResults->pfnBootstrapperApplicationProc = BalBaseBootstrapperApplicationProc; 4072 pResults->pfnBootstrapperApplicationProc = BalBaseBootstrapperApplicationProc;
4056 pResults->pvBootstrapperApplicationProcContext = pApplication; 4073 pResults->pvBootstrapperApplicationProcContext = pApplication;
diff --git a/src/ext/Util/be/UtilBundleExtension.cpp b/src/ext/Util/be/UtilBundleExtension.cpp
index 2ac842a5..110599fa 100644
--- a/src/ext/Util/be/UtilBundleExtension.cpp
+++ b/src/ext/Util/be/UtilBundleExtension.cpp
@@ -27,7 +27,7 @@ public: //CBextBaseBundleExtension
27 IXMLDOMDocument* pixdManifest = NULL; 27 IXMLDOMDocument* pixdManifest = NULL;
28 IXMLDOMNode* pixnBundleExtension = NULL; 28 IXMLDOMNode* pixnBundleExtension = NULL;
29 29
30 hr = CBextBaseBundleExtension::Initialize(pCreateArgs); 30 hr = __super::Initialize(pCreateArgs);
31 ExitOnFailure(hr, "CBextBaseBundleExtension initialization failed."); 31 ExitOnFailure(hr, "CBextBaseBundleExtension initialization failed.");
32 32
33 hr = XmlLoadDocumentFromFile(m_sczBundleExtensionDataPath, &pixdManifest); 33 hr = XmlLoadDocumentFromFile(m_sczBundleExtensionDataPath, &pixdManifest);
@@ -76,7 +76,7 @@ HRESULT UtilBundleExtensionCreate(
76 ExitOnNull(pExtension, hr, E_OUTOFMEMORY, "Failed to create new CWixUtilBundleExtension."); 76 ExitOnNull(pExtension, hr, E_OUTOFMEMORY, "Failed to create new CWixUtilBundleExtension.");
77 77
78 hr = pExtension->Initialize(pArgs); 78 hr = pExtension->Initialize(pArgs);
79 ExitOnFailure(hr, "CWixUtilBundleExtension initialization failed"); 79 ExitOnFailure(hr, "CWixUtilBundleExtension initialization failed.");
80 80
81 *ppBundleExtension = pExtension; 81 *ppBundleExtension = pExtension;
82 pExtension = NULL; 82 pExtension = NULL;