aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h13
-rw-r--r--src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs38
-rw-r--r--src/api/burn/WixToolset.Mba.Core/EventArgs.cs26
-rw-r--r--src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs13
-rw-r--r--src/api/burn/WixToolset.Mba.Core/IDefaultBootstrapperApplication.cs16
-rw-r--r--src/api/burn/balutil/inc/BAFunctions.h1
-rw-r--r--src/api/burn/balutil/inc/BalBaseBAFunctions.h8
-rw-r--r--src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h1
-rw-r--r--src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h19
-rw-r--r--src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h12
-rw-r--r--src/api/burn/balutil/inc/IBootstrapperApplication.h6
-rw-r--r--src/burn/engine/core.cpp4
-rw-r--r--src/burn/engine/elevation.cpp21
-rw-r--r--src/burn/engine/elevation.h3
-rw-r--r--src/burn/engine/engine.cpp2
-rw-r--r--src/burn/engine/plan.h1
-rw-r--r--src/burn/engine/uithread.cpp20
-rw-r--r--src/burn/engine/userexperience.cpp25
-rw-r--r--src/burn/engine/userexperience.h5
-rw-r--r--src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp17
-rw-r--r--src/test/burn/TestBA/TestBA.cs9
-rw-r--r--src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp52
-rw-r--r--src/test/burn/TestData/Manual/BundleA/BundleA.wxs7
-rw-r--r--src/test/burn/TestData/Manual/PackageA/PackageA.wixproj4
-rw-r--r--src/test/burn/TestData/Manual/PackageA/ProductA.wxs15
25 files changed, 107 insertions, 231 deletions
diff --git a/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h b/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
index f0b5dad4..228cb6ff 100644
--- a/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
+++ b/src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
@@ -149,7 +149,6 @@ enum BOOTSTRAPPER_APPLICATION_MESSAGE
149 BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPLETE, 149 BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPLETE,
150 BOOTSTRAPPER_APPLICATION_MESSAGE_ONSTARTUP, 150 BOOTSTRAPPER_APPLICATION_MESSAGE_ONSTARTUP,
151 BOOTSTRAPPER_APPLICATION_MESSAGE_ONSHUTDOWN, 151 BOOTSTRAPPER_APPLICATION_MESSAGE_ONSHUTDOWN,
152 BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMSHUTDOWN,
153 BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE, 152 BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE,
154 BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATEBEGIN, 153 BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATEBEGIN,
155 BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATE, 154 BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATE,
@@ -1463,18 +1462,6 @@ struct BA_ONSYSTEMRESTOREPOINTCOMPLETE_RESULTS
1463 DWORD cbSize; 1462 DWORD cbSize;
1464}; 1463};
1465 1464
1466struct BA_ONSYSTEMSHUTDOWN_ARGS
1467{
1468 DWORD cbSize;
1469 DWORD dwEndSession;
1470};
1471
1472struct BA_ONSYSTEMSHUTDOWN_RESULTS
1473{
1474 DWORD cbSize;
1475 BOOL fCancel;
1476};
1477
1478struct BA_ONUNREGISTERBEGIN_ARGS 1465struct BA_ONUNREGISTERBEGIN_ARGS
1479{ 1466{
1480 DWORD cbSize; 1467 DWORD cbSize;
diff --git a/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs b/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs
index 6738a4a6..bb34a33e 100644
--- a/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs
+++ b/src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs
@@ -22,15 +22,12 @@ namespace WixToolset.Mba.Core
22 /// </summary> 22 /// </summary>
23 protected readonly IEngine engine; 23 protected readonly IEngine engine;
24 24
25 private bool applying;
26
27 /// <summary> 25 /// <summary>
28 /// Creates a new instance of the <see cref="BootstrapperApplication"/> class. 26 /// Creates a new instance of the <see cref="BootstrapperApplication"/> class.
29 /// </summary> 27 /// </summary>
30 protected BootstrapperApplication(IEngine engine) 28 protected BootstrapperApplication(IEngine engine)
31 { 29 {
32 this.engine = engine; 30 this.engine = engine;
33 this.applying = false;
34 this.asyncExecution = true; 31 this.asyncExecution = true;
35 } 32 }
36 33
@@ -41,9 +38,6 @@ namespace WixToolset.Mba.Core
41 public event EventHandler<ShutdownEventArgs> Shutdown; 38 public event EventHandler<ShutdownEventArgs> Shutdown;
42 39
43 /// <inheritdoc/> 40 /// <inheritdoc/>
44 public event EventHandler<SystemShutdownEventArgs> SystemShutdown;
45
46 /// <inheritdoc/>
47 public event EventHandler<DetectBeginEventArgs> DetectBegin; 41 public event EventHandler<DetectBeginEventArgs> DetectBegin;
48 42
49 /// <inheritdoc/> 43 /// <inheritdoc/>
@@ -332,25 +326,6 @@ namespace WixToolset.Mba.Core
332 } 326 }
333 327
334 /// <summary> 328 /// <summary>
335 /// Called by the engine, raises the <see cref="SystemShutdown"/> event.
336 /// </summary>
337 /// <param name="args">Additional arguments for this event.</param>
338 protected virtual void OnSystemShutdown(SystemShutdownEventArgs args)
339 {
340 EventHandler<SystemShutdownEventArgs> handler = this.SystemShutdown;
341 if (null != handler)
342 {
343 handler(this, args);
344 }
345 else if (null != args)
346 {
347 // Allow requests to shut down when critical or not applying.
348 bool critical = EndSessionReasons.Critical == (EndSessionReasons.Critical & args.Reasons);
349 args.Cancel = !critical && this.applying;
350 }
351 }
352
353 /// <summary>
354 /// Called by the engine, raises the <see cref="DetectBegin"/> event. 329 /// Called by the engine, raises the <see cref="DetectBegin"/> event.
355 /// </summary> 330 /// </summary>
356 /// <param name="args">Additional arguments for this event.</param> 331 /// <param name="args">Additional arguments for this event.</param>
@@ -1433,15 +1408,6 @@ namespace WixToolset.Mba.Core
1433 return args.HResult; 1408 return args.HResult;
1434 } 1409 }
1435 1410
1436 int IBootstrapperApplication.OnSystemShutdown(EndSessionReasons dwEndSession, ref bool fCancel)
1437 {
1438 SystemShutdownEventArgs args = new SystemShutdownEventArgs(dwEndSession, fCancel);
1439 this.OnSystemShutdown(args);
1440
1441 fCancel = args.Cancel;
1442 return args.HResult;
1443 }
1444
1445 int IBootstrapperApplication.OnDetectBegin(bool fCached, RegistrationType registrationType, int cPackages, ref bool fCancel) 1411 int IBootstrapperApplication.OnDetectBegin(bool fCached, RegistrationType registrationType, int cPackages, ref bool fCancel)
1446 { 1412 {
1447 DetectBeginEventArgs args = new DetectBeginEventArgs(fCached, registrationType, cPackages, fCancel); 1413 DetectBeginEventArgs args = new DetectBeginEventArgs(fCached, registrationType, cPackages, fCancel);
@@ -1693,8 +1659,6 @@ namespace WixToolset.Mba.Core
1693 1659
1694 int IBootstrapperApplication.OnApplyBegin(int dwPhaseCount, ref bool fCancel) 1660 int IBootstrapperApplication.OnApplyBegin(int dwPhaseCount, ref bool fCancel)
1695 { 1661 {
1696 this.applying = true;
1697
1698 ApplyBeginEventArgs args = new ApplyBeginEventArgs(dwPhaseCount, fCancel); 1662 ApplyBeginEventArgs args = new ApplyBeginEventArgs(dwPhaseCount, fCancel);
1699 this.OnApplyBegin(args); 1663 this.OnApplyBegin(args);
1700 1664
@@ -1949,8 +1913,6 @@ namespace WixToolset.Mba.Core
1949 ApplyCompleteEventArgs args = new ApplyCompleteEventArgs(hrStatus, restart, recommendation, pAction); 1913 ApplyCompleteEventArgs args = new ApplyCompleteEventArgs(hrStatus, restart, recommendation, pAction);
1950 this.OnApplyComplete(args); 1914 this.OnApplyComplete(args);
1951 1915
1952 this.applying = false;
1953
1954 pAction = args.Action; 1916 pAction = args.Action;
1955 return args.HResult; 1917 return args.HResult;
1956 } 1918 }
diff --git a/src/api/burn/WixToolset.Mba.Core/EventArgs.cs b/src/api/burn/WixToolset.Mba.Core/EventArgs.cs
index d79ac402..be113700 100644
--- a/src/api/burn/WixToolset.Mba.Core/EventArgs.cs
+++ b/src/api/burn/WixToolset.Mba.Core/EventArgs.cs
@@ -217,32 +217,6 @@ namespace WixToolset.Mba.Core
217 } 217 }
218 218
219 /// <summary> 219 /// <summary>
220 /// Event arguments for <see cref="IDefaultBootstrapperApplication.SystemShutdown"/>
221 /// </summary>
222 [Serializable]
223 public class SystemShutdownEventArgs : CancellableHResultEventArgs
224 {
225 /// <summary />
226 public SystemShutdownEventArgs(EndSessionReasons reasons, bool cancelRecommendation)
227 : base(cancelRecommendation)
228 {
229 this.Reasons = reasons;
230 }
231
232 /// <summary>
233 /// Gets the reason the application is requested to close or being closed.
234 /// </summary>
235 /// <remarks>
236 /// <para>To prevent shutting down or logging off, set <see cref="CancellableHResultEventArgs.Cancel"/> to
237 /// true; otherwise, set it to false.</para>
238 /// <para>If <see cref="SystemShutdownEventArgs.Reasons"/> contains <see cref="EndSessionReasons.Critical"/>
239 /// the bootstrapper cannot prevent the shutdown and only has a few seconds to save state or perform any other
240 /// critical operations before being closed by the operating system.</para>
241 /// </remarks>
242 public EndSessionReasons Reasons { get; private set; }
243 }
244
245 /// <summary>
246 /// Event arguments for <see cref="IDefaultBootstrapperApplication.DetectBegin"/> 220 /// Event arguments for <see cref="IDefaultBootstrapperApplication.DetectBegin"/>
247 /// </summary> 221 /// </summary>
248 [Serializable] 222 [Serializable]
diff --git a/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs b/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs
index 2877d4de..8ce99808 100644
--- a/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs
+++ b/src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs
@@ -51,19 +51,6 @@ namespace WixToolset.Mba.Core
51 int OnShutdown(ref BOOTSTRAPPER_SHUTDOWN_ACTION action); 51 int OnShutdown(ref BOOTSTRAPPER_SHUTDOWN_ACTION action);
52 52
53 /// <summary> 53 /// <summary>
54 /// See <see cref="IDefaultBootstrapperApplication.SystemShutdown"/>.
55 /// </summary>
56 /// <param name="dwEndSession"></param>
57 /// <param name="fCancel"></param>
58 /// <returns></returns>
59 [PreserveSig]
60 [return: MarshalAs(UnmanagedType.I4)]
61 int OnSystemShutdown(
62 [MarshalAs(UnmanagedType.U4)] EndSessionReasons dwEndSession,
63 [MarshalAs(UnmanagedType.Bool)] ref bool fCancel
64 );
65
66 /// <summary>
67 /// See <see cref="IDefaultBootstrapperApplication.DetectBegin"/>. 54 /// See <see cref="IDefaultBootstrapperApplication.DetectBegin"/>.
68 /// </summary> 55 /// </summary>
69 [PreserveSig] 56 [PreserveSig]
diff --git a/src/api/burn/WixToolset.Mba.Core/IDefaultBootstrapperApplication.cs b/src/api/burn/WixToolset.Mba.Core/IDefaultBootstrapperApplication.cs
index 77089e83..2535f756 100644
--- a/src/api/burn/WixToolset.Mba.Core/IDefaultBootstrapperApplication.cs
+++ b/src/api/burn/WixToolset.Mba.Core/IDefaultBootstrapperApplication.cs
@@ -419,22 +419,6 @@ namespace WixToolset.Mba.Core
419 event EventHandler<SystemRestorePointCompleteEventArgs> SystemRestorePointComplete; 419 event EventHandler<SystemRestorePointCompleteEventArgs> SystemRestorePointComplete;
420 420
421 /// <summary> 421 /// <summary>
422 /// Fired when the system is shutting down or user is logging off.
423 /// </summary>
424 /// <remarks>
425 /// <para>To prevent shutting down or logging off, set <see cref="CancellableHResultEventArgs.Cancel"/> to
426 /// true; otherwise, set it to false.</para>
427 /// <para>By default setup will prevent shutting down or logging off between
428 /// <see cref="IDefaultBootstrapperApplication.ApplyBegin"/> and <see cref="IDefaultBootstrapperApplication.ApplyComplete"/>.
429 /// Derivatives can change this behavior by handling <see cref="IDefaultBootstrapperApplication.SystemShutdown"/>.</para>
430 /// <para>If <see cref="SystemShutdownEventArgs.Reasons"/> contains <see cref="EndSessionReasons.Critical"/>
431 /// the bootstrapper cannot prevent the shutdown and only has a few seconds to save state or perform any other
432 /// critical operations before being closed by the operating system.</para>
433 /// <para>This event may be fired on a different thread.</para>
434 /// </remarks>
435 event EventHandler<SystemShutdownEventArgs> SystemShutdown;
436
437 /// <summary>
438 /// Fired when the engine unregisters the bundle. 422 /// Fired when the engine unregisters the bundle.
439 /// </summary> 423 /// </summary>
440 event EventHandler<UnregisterBeginEventArgs> UnregisterBegin; 424 event EventHandler<UnregisterBeginEventArgs> UnregisterBegin;
diff --git a/src/api/burn/balutil/inc/BAFunctions.h b/src/api/burn/balutil/inc/BAFunctions.h
index 9be3f62f..c1057ab6 100644
--- a/src/api/burn/balutil/inc/BAFunctions.h
+++ b/src/api/burn/balutil/inc/BAFunctions.h
@@ -15,7 +15,6 @@ enum BA_FUNCTIONS_MESSAGE
15 BA_FUNCTIONS_MESSAGE_ONPLANCOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPLETE, 15 BA_FUNCTIONS_MESSAGE_ONPLANCOMPLETE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONPLANCOMPLETE,
16 BA_FUNCTIONS_MESSAGE_ONSTARTUP = BOOTSTRAPPER_APPLICATION_MESSAGE_ONSTARTUP, 16 BA_FUNCTIONS_MESSAGE_ONSTARTUP = BOOTSTRAPPER_APPLICATION_MESSAGE_ONSTARTUP,
17 BA_FUNCTIONS_MESSAGE_ONSHUTDOWN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONSHUTDOWN, 17 BA_FUNCTIONS_MESSAGE_ONSHUTDOWN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONSHUTDOWN,
18 BA_FUNCTIONS_MESSAGE_ONSYSTEMSHUTDOWN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMSHUTDOWN,
19 BA_FUNCTIONS_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE, 18 BA_FUNCTIONS_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE,
20 BA_FUNCTIONS_MESSAGE_ONDETECTUPDATEBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATEBEGIN, 19 BA_FUNCTIONS_MESSAGE_ONDETECTUPDATEBEGIN = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATEBEGIN,
21 BA_FUNCTIONS_MESSAGE_ONDETECTUPDATE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATE, 20 BA_FUNCTIONS_MESSAGE_ONDETECTUPDATE = BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTUPDATE,
diff --git a/src/api/burn/balutil/inc/BalBaseBAFunctions.h b/src/api/burn/balutil/inc/BalBaseBAFunctions.h
index 9ff58d2b..ca070553 100644
--- a/src/api/burn/balutil/inc/BalBaseBAFunctions.h
+++ b/src/api/burn/balutil/inc/BalBaseBAFunctions.h
@@ -98,14 +98,6 @@ public: // IBootstrapperApplication
98 return S_OK; 98 return S_OK;
99 } 99 }
100 100
101 virtual STDMETHODIMP OnSystemShutdown(
102 __in DWORD /*dwEndSession*/,
103 __inout BOOL* /*pfCancel*/
104 )
105 {
106 return S_OK;
107 }
108
109 virtual STDMETHODIMP OnDetectBegin( 101 virtual STDMETHODIMP OnDetectBegin(
110 __in BOOL /*fCached*/, 102 __in BOOL /*fCached*/,
111 __in BOOTSTRAPPER_REGISTRATION_TYPE /*registrationType*/, 103 __in BOOTSTRAPPER_REGISTRATION_TYPE /*registrationType*/,
diff --git a/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h b/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h
index 4564ad0c..ff92717d 100644
--- a/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h
+++ b/src/api/burn/balutil/inc/BalBaseBAFunctionsProc.h
@@ -86,7 +86,6 @@ static HRESULT WINAPI BalBaseBAFunctionsProc(
86 case BA_FUNCTIONS_MESSAGE_ONPLANCOMPLETE: 86 case BA_FUNCTIONS_MESSAGE_ONPLANCOMPLETE:
87 case BA_FUNCTIONS_MESSAGE_ONSTARTUP: 87 case BA_FUNCTIONS_MESSAGE_ONSTARTUP:
88 case BA_FUNCTIONS_MESSAGE_ONSHUTDOWN: 88 case BA_FUNCTIONS_MESSAGE_ONSHUTDOWN:
89 case BA_FUNCTIONS_MESSAGE_ONSYSTEMSHUTDOWN:
90 case BA_FUNCTIONS_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE: 89 case BA_FUNCTIONS_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE:
91 case BA_FUNCTIONS_MESSAGE_ONDETECTUPDATEBEGIN: 90 case BA_FUNCTIONS_MESSAGE_ONDETECTUPDATEBEGIN:
92 case BA_FUNCTIONS_MESSAGE_ONDETECTUPDATE: 91 case BA_FUNCTIONS_MESSAGE_ONDETECTUPDATE:
diff --git a/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h b/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h
index 2e848df7..fc9c4dd7 100644
--- a/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h
+++ b/src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h
@@ -94,19 +94,6 @@ public: // IBootstrapperApplication
94 return S_OK; 94 return S_OK;
95 } 95 }
96 96
97 virtual STDMETHODIMP OnSystemShutdown(
98 __in DWORD dwEndSession,
99 __inout BOOL* pfCancel
100 )
101 {
102 HRESULT hr = S_OK;
103
104 // Allow requests to shut down when critical or not applying.
105 *pfCancel = !(ENDSESSION_CRITICAL & dwEndSession || !m_fApplying);
106
107 return hr;
108 }
109
110 virtual STDMETHODIMP OnDetectBegin( 97 virtual STDMETHODIMP OnDetectBegin(
111 __in BOOL /*fCached*/, 98 __in BOOL /*fCached*/,
112 __in BOOTSTRAPPER_REGISTRATION_TYPE /*registrationType*/, 99 __in BOOTSTRAPPER_REGISTRATION_TYPE /*registrationType*/,
@@ -406,8 +393,6 @@ public: // IBootstrapperApplication
406 __inout BOOL* pfCancel 393 __inout BOOL* pfCancel
407 ) 394 )
408 { 395 {
409 m_fApplying = TRUE;
410
411 m_dwProgressPercentage = 0; 396 m_dwProgressPercentage = 0;
412 m_dwOverallProgressPercentage = 0; 397 m_dwOverallProgressPercentage = 0;
413 398
@@ -859,8 +844,6 @@ public: // IBootstrapperApplication
859 *pAction = BOOTSTRAPPER_APPLYCOMPLETE_ACTION_RESTART; 844 *pAction = BOOTSTRAPPER_APPLYCOMPLETE_ACTION_RESTART;
860 } 845 }
861 846
862 m_fApplying = FALSE;
863
864 return hr; 847 return hr;
865 } 848 }
866 849
@@ -1183,7 +1166,6 @@ protected:
1183 ::InitializeCriticalSection(&m_csCanceled); 1166 ::InitializeCriticalSection(&m_csCanceled);
1184 m_fCanceled = FALSE; 1167 m_fCanceled = FALSE;
1185 m_BalInfoCommand = { }; 1168 m_BalInfoCommand = { };
1186 m_fApplying = FALSE;
1187 m_fRollingBack = FALSE; 1169 m_fRollingBack = FALSE;
1188 1170
1189 m_dwProgressPercentage = 0; 1171 m_dwProgressPercentage = 0;
@@ -1212,7 +1194,6 @@ private:
1212 BOOTSTRAPPER_DISPLAY m_display; 1194 BOOTSTRAPPER_DISPLAY m_display;
1213 IBootstrapperEngine* m_pEngine; 1195 IBootstrapperEngine* m_pEngine;
1214 1196
1215 BOOL m_fApplying;
1216 BOOL m_fRollingBack; 1197 BOOL m_fRollingBack;
1217 1198
1218 DWORD m_dwProgressPercentage; 1199 DWORD m_dwProgressPercentage;
diff --git a/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h b/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h
index e35678ad..92243540 100644
--- a/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h
+++ b/src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h
@@ -63,15 +63,6 @@ static HRESULT BalBaseBAProcOnShutdown(
63 return pBA->OnShutdown(&pResults->action); 63 return pBA->OnShutdown(&pResults->action);
64} 64}
65 65
66static HRESULT BalBaseBAProcOnSystemShutdown(
67 __in IBootstrapperApplication* pBA,
68 __in BA_ONSYSTEMSHUTDOWN_ARGS* pArgs,
69 __inout BA_ONSYSTEMSHUTDOWN_RESULTS* pResults
70 )
71{
72 return pBA->OnSystemShutdown(pArgs->dwEndSession, &pResults->fCancel);
73}
74
75static HRESULT BalBaseBAProcOnDetectForwardCompatibleBundle( 66static HRESULT BalBaseBAProcOnDetectForwardCompatibleBundle(
76 __in IBootstrapperApplication* pBA, 67 __in IBootstrapperApplication* pBA,
77 __in BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_ARGS* pArgs, 68 __in BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_ARGS* pArgs,
@@ -803,9 +794,6 @@ static HRESULT WINAPI BalBaseBootstrapperApplicationProc(
803 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSHUTDOWN: 794 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSHUTDOWN:
804 hr = BalBaseBAProcOnShutdown(pBA, reinterpret_cast<BA_ONSHUTDOWN_ARGS*>(pvArgs), reinterpret_cast<BA_ONSHUTDOWN_RESULTS*>(pvResults)); 795 hr = BalBaseBAProcOnShutdown(pBA, reinterpret_cast<BA_ONSHUTDOWN_ARGS*>(pvArgs), reinterpret_cast<BA_ONSHUTDOWN_RESULTS*>(pvResults));
805 break; 796 break;
806 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMSHUTDOWN:
807 hr = BalBaseBAProcOnSystemShutdown(pBA, reinterpret_cast<BA_ONSYSTEMSHUTDOWN_ARGS*>(pvArgs), reinterpret_cast<BA_ONSYSTEMSHUTDOWN_RESULTS*>(pvResults));
808 break;
809 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE: 797 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE:
810 hr = BalBaseBAProcOnDetectForwardCompatibleBundle(pBA, reinterpret_cast<BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_RESULTS*>(pvResults)); 798 hr = BalBaseBAProcOnDetectForwardCompatibleBundle(pBA, reinterpret_cast<BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_RESULTS*>(pvResults));
811 break; 799 break;
diff --git a/src/api/burn/balutil/inc/IBootstrapperApplication.h b/src/api/burn/balutil/inc/IBootstrapperApplication.h
index 6eca90fa..382d5aad 100644
--- a/src/api/burn/balutil/inc/IBootstrapperApplication.h
+++ b/src/api/burn/balutil/inc/IBootstrapperApplication.h
@@ -33,12 +33,6 @@ DECLARE_INTERFACE_IID_(IBootstrapperApplication, IUnknown, "53C31D56-49C0-426B-A
33 __inout BOOTSTRAPPER_SHUTDOWN_ACTION* pAction 33 __inout BOOTSTRAPPER_SHUTDOWN_ACTION* pAction
34 ) = 0; 34 ) = 0;
35 35
36 // OnSystemShutdown - called when the operating system is instructed to shutdown the machine.
37 STDMETHOD(OnSystemShutdown)(
38 __in DWORD dwEndSession,
39 __inout BOOL* pfCancel
40 ) = 0;
41
42 // OnDetectBegin - called when the engine begins detection. 36 // OnDetectBegin - called when the engine begins detection.
43 STDMETHOD(OnDetectBegin)( 37 STDMETHOD(OnDetectBegin)(
44 __in BOOL fCached, 38 __in BOOL fCached,
diff --git a/src/burn/engine/core.cpp b/src/burn/engine/core.cpp
index ec996c4c..19b739f9 100644
--- a/src/burn/engine/core.cpp
+++ b/src/burn/engine/core.cpp
@@ -681,6 +681,8 @@ extern "C" HRESULT CoreApply(
681 hr = ApplyLock(FALSE, &hLock); 681 hr = ApplyLock(FALSE, &hLock);
682 ExitOnFailure(hr, "Another per-user setup is already executing."); 682 ExitOnFailure(hr, "Another per-user setup is already executing.");
683 683
684 pEngineState->plan.fApplying = TRUE;
685
684 // Initialize only after getting a lock. 686 // Initialize only after getting a lock.
685 fApplyInitialize = TRUE; 687 fApplyInitialize = TRUE;
686 ApplyInitialize(); 688 ApplyInitialize();
@@ -814,6 +816,8 @@ LExit:
814 ApplyUninitialize(); 816 ApplyUninitialize();
815 } 817 }
816 818
819 pEngineState->plan.fApplying = FALSE;
820
817 if (hLock) 821 if (hLock)
818 { 822 {
819 ::ReleaseMutex(hLock); 823 ::ReleaseMutex(hLock);
diff --git a/src/burn/engine/elevation.cpp b/src/burn/engine/elevation.cpp
index d2c5c8c6..75b24ec3 100644
--- a/src/burn/engine/elevation.cpp
+++ b/src/burn/engine/elevation.cpp
@@ -94,6 +94,7 @@ typedef struct _BURN_ELEVATION_CHILD_MESSAGE_CONTEXT
94 HANDLE hPipe; 94 HANDLE hPipe;
95 HANDLE* phLock; 95 HANDLE* phLock;
96 BOOL* pfDisabledAutomaticUpdates; 96 BOOL* pfDisabledAutomaticUpdates;
97 BOOL* pfApplying;
97 BURN_APPROVED_EXES* pApprovedExes; 98 BURN_APPROVED_EXES* pApprovedExes;
98 BURN_CACHE* pCache; 99 BURN_CACHE* pCache;
99 BURN_CONTAINERS* pContainers; 100 BURN_CONTAINERS* pContainers;
@@ -176,6 +177,7 @@ static HRESULT OnApplyInitialize(
176 __in BURN_PACKAGES* pPackages, 177 __in BURN_PACKAGES* pPackages,
177 __in HANDLE* phLock, 178 __in HANDLE* phLock,
178 __in BOOL* pfDisabledWindowsUpdate, 179 __in BOOL* pfDisabledWindowsUpdate,
180 __in BOOL* pfApplying,
179 __in BYTE* pbData, 181 __in BYTE* pbData,
180 __in SIZE_T cbData 182 __in SIZE_T cbData
181 ); 183 );
@@ -185,7 +187,8 @@ static HRESULT ElevatedProcessDetect(
185 __in BURN_PACKAGES* pPackages 187 __in BURN_PACKAGES* pPackages
186 ); 188 );
187static HRESULT OnApplyUninitialize( 189static HRESULT OnApplyUninitialize(
188 __in HANDLE* phLock 190 __in HANDLE* phLock,
191 __in BOOL* pfApplying
189 ); 192 );
190static HRESULT OnSessionBegin( 193static HRESULT OnSessionBegin(
191 __in BURN_CACHE* pCache, 194 __in BURN_CACHE* pCache,
@@ -1538,7 +1541,8 @@ extern "C" HRESULT ElevationChildPumpMessages(
1538 __out HANDLE* phLock, 1541 __out HANDLE* phLock,
1539 __out BOOL* pfDisabledAutomaticUpdates, 1542 __out BOOL* pfDisabledAutomaticUpdates,
1540 __out DWORD* pdwChildExitCode, 1543 __out DWORD* pdwChildExitCode,
1541 __out BOOL* pfRestart 1544 __out BOOL* pfRestart,
1545 __out BOOL* pfApplying
1542 ) 1546 )
1543{ 1547{
1544 HRESULT hr = S_OK; 1548 HRESULT hr = S_OK;
@@ -1561,6 +1565,7 @@ extern "C" HRESULT ElevationChildPumpMessages(
1561 context.hPipe = hPipe; 1565 context.hPipe = hPipe;
1562 context.phLock = phLock; 1566 context.phLock = phLock;
1563 context.pfDisabledAutomaticUpdates = pfDisabledAutomaticUpdates; 1567 context.pfDisabledAutomaticUpdates = pfDisabledAutomaticUpdates;
1568 context.pfApplying = pfApplying;
1564 context.pApprovedExes = pApprovedExes; 1569 context.pApprovedExes = pApprovedExes;
1565 context.pCache = pCache; 1570 context.pCache = pCache;
1566 context.pContainers = pContainers; 1571 context.pContainers = pContainers;
@@ -2114,11 +2119,11 @@ static HRESULT ProcessElevatedChildMessage(
2114 break; 2119 break;
2115 2120
2116 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE: 2121 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_INITIALIZE:
2117 hrResult = OnApplyInitialize(pContext->hPipe, pContext->pVariables, pContext->pRegistration, pContext->pPackages, pContext->phLock, pContext->pfDisabledAutomaticUpdates, (BYTE*)pMsg->pvData, pMsg->cbData); 2122 hrResult = OnApplyInitialize(pContext->hPipe, pContext->pVariables, pContext->pRegistration, pContext->pPackages, pContext->phLock, pContext->pfDisabledAutomaticUpdates, pContext->pfApplying, (BYTE*)pMsg->pvData, pMsg->cbData);
2118 break; 2123 break;
2119 2124
2120 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_UNINITIALIZE: 2125 case BURN_ELEVATION_MESSAGE_TYPE_APPLY_UNINITIALIZE:
2121 hrResult = OnApplyUninitialize(pContext->phLock); 2126 hrResult = OnApplyUninitialize(pContext->phLock, pContext->pfApplying);
2122 break; 2127 break;
2123 2128
2124 case BURN_ELEVATION_MESSAGE_TYPE_SESSION_BEGIN: 2129 case BURN_ELEVATION_MESSAGE_TYPE_SESSION_BEGIN:
@@ -2267,6 +2272,7 @@ static HRESULT OnApplyInitialize(
2267 __in BURN_PACKAGES* pPackages, 2272 __in BURN_PACKAGES* pPackages,
2268 __in HANDLE* phLock, 2273 __in HANDLE* phLock,
2269 __in BOOL* pfDisabledWindowsUpdate, 2274 __in BOOL* pfDisabledWindowsUpdate,
2275 __in BOOL* pfApplying,
2270 __in BYTE* pbData, 2276 __in BYTE* pbData,
2271 __in SIZE_T cbData 2277 __in SIZE_T cbData
2272 ) 2278 )
@@ -2296,6 +2302,8 @@ static HRESULT OnApplyInitialize(
2296 hr = ApplyLock(TRUE, phLock); 2302 hr = ApplyLock(TRUE, phLock);
2297 ExitOnFailure(hr, "Failed to acquire lock due to setup in other session."); 2303 ExitOnFailure(hr, "Failed to acquire lock due to setup in other session.");
2298 2304
2305 *pfApplying = TRUE;
2306
2299 // Detect. 2307 // Detect.
2300 hr = ElevatedProcessDetect(pRegistration, pVariables, pPackages); 2308 hr = ElevatedProcessDetect(pRegistration, pVariables, pPackages);
2301 ExitOnFailure(hr, "Failed to run detection in elevated process."); 2309 ExitOnFailure(hr, "Failed to run detection in elevated process.");
@@ -2419,13 +2427,16 @@ LExit:
2419} 2427}
2420 2428
2421static HRESULT OnApplyUninitialize( 2429static HRESULT OnApplyUninitialize(
2422 __in HANDLE* phLock 2430 __in HANDLE* phLock,
2431 __in BOOL* pfApplying
2423 ) 2432 )
2424{ 2433{
2425 Assert(phLock); 2434 Assert(phLock);
2426 2435
2427 // TODO: end system restore point. 2436 // TODO: end system restore point.
2428 2437
2438 *pfApplying = FALSE;
2439
2429 if (*phLock) 2440 if (*phLock)
2430 { 2441 {
2431 ::ReleaseMutex(*phLock); 2442 ::ReleaseMutex(*phLock);
diff --git a/src/burn/engine/elevation.h b/src/burn/engine/elevation.h
index 0dc189c5..d08d2edc 100644
--- a/src/burn/engine/elevation.h
+++ b/src/burn/engine/elevation.h
@@ -180,7 +180,8 @@ HRESULT ElevationChildPumpMessages(
180 __out HANDLE* phLock, 180 __out HANDLE* phLock,
181 __out BOOL* pfDisabledAutomaticUpdates, 181 __out BOOL* pfDisabledAutomaticUpdates,
182 __out DWORD* pdwChildExitCode, 182 __out DWORD* pdwChildExitCode,
183 __out BOOL* pfRestart 183 __out BOOL* pfRestart,
184 __out BOOL* pfApplying
184 ); 185 );
185HRESULT ElevationChildResumeAutomaticUpdates(); 186HRESULT ElevationChildResumeAutomaticUpdates();
186 187
diff --git a/src/burn/engine/engine.cpp b/src/burn/engine/engine.cpp
index 821626f8..ee848acf 100644
--- a/src/burn/engine/engine.cpp
+++ b/src/burn/engine/engine.cpp
@@ -653,7 +653,7 @@ static HRESULT RunElevated(
653 SrpInitialize(TRUE); 653 SrpInitialize(TRUE);
654 654
655 // Pump messages from parent process. 655 // Pump messages from parent process.
656 hr = ElevationChildPumpMessages(pEngineState->dwElevatedLoggingTlsId, pEngineState->companionConnection.hPipe, pEngineState->companionConnection.hCachePipe, &pEngineState->approvedExes, &pEngineState->cache, &pEngineState->containers, &pEngineState->packages, &pEngineState->payloads, &pEngineState->variables, &pEngineState->registration, &pEngineState->userExperience, &hLock, &fDisabledAutomaticUpdates, &pEngineState->userExperience.dwExitCode, &pEngineState->fRestart); 656 hr = ElevationChildPumpMessages(pEngineState->dwElevatedLoggingTlsId, pEngineState->companionConnection.hPipe, pEngineState->companionConnection.hCachePipe, &pEngineState->approvedExes, &pEngineState->cache, &pEngineState->containers, &pEngineState->packages, &pEngineState->payloads, &pEngineState->variables, &pEngineState->registration, &pEngineState->userExperience, &hLock, &fDisabledAutomaticUpdates, &pEngineState->userExperience.dwExitCode, &pEngineState->fRestart, &pEngineState->plan.fApplying);
657 LogRedirect(NULL, NULL); // reset logging so the next failure gets written to "log buffer" for the failure log. 657 LogRedirect(NULL, NULL); // reset logging so the next failure gets written to "log buffer" for the failure log.
658 ExitOnFailure(hr, "Failed to pump messages from parent process."); 658 ExitOnFailure(hr, "Failed to pump messages from parent process.");
659 659
diff --git a/src/burn/engine/plan.h b/src/burn/engine/plan.h
index 2b04e097..46a9a363 100644
--- a/src/burn/engine/plan.h
+++ b/src/burn/engine/plan.h
@@ -264,6 +264,7 @@ typedef struct _BURN_PLAN
264 LPWSTR sczLayoutDirectory; 264 LPWSTR sczLayoutDirectory;
265 BOOL fPlanPackageCacheRollback; 265 BOOL fPlanPackageCacheRollback;
266 BOOL fDowngrade; 266 BOOL fDowngrade;
267 BOOL fApplying;
267 268
268 DWORD64 qwCacheSizeTotal; 269 DWORD64 qwCacheSizeTotal;
269 270
diff --git a/src/burn/engine/uithread.cpp b/src/burn/engine/uithread.cpp
index bb1e5972..cdd8613c 100644
--- a/src/burn/engine/uithread.cpp
+++ b/src/burn/engine/uithread.cpp
@@ -17,8 +17,7 @@ struct UITHREAD_CONTEXT
17struct UITHREAD_INFO 17struct UITHREAD_INFO
18{ 18{
19 BOOL fElevatedEngine; 19 BOOL fElevatedEngine;
20 BURN_USER_EXPERIENCE* pUserExperience; 20 BURN_ENGINE_STATE* pEngineState;
21 BOOL* pfCriticalShutdownInitiated;
22}; 21};
23 22
24 23
@@ -132,8 +131,7 @@ static DWORD WINAPI ThreadProc(
132 fRegistered = TRUE; 131 fRegistered = TRUE;
133 132
134 info.fElevatedEngine = fElevatedEngine; 133 info.fElevatedEngine = fElevatedEngine;
135 info.pUserExperience = &pEngineState->userExperience; 134 info.pEngineState = pEngineState;
136 info.pfCriticalShutdownInitiated = &pEngineState->fCriticalShutdownInitiated;
137 135
138 // Create the window to handle reboots without activating it. 136 // Create the window to handle reboots without activating it.
139 hWnd = ::CreateWindowExW(WS_EX_NOACTIVATE, wc.lpszClassName, NULL, WS_POPUP, 0, 0, 0, 0, HWND_DESKTOP, NULL, pContext->hInstance, &info); 137 hWnd = ::CreateWindowExW(WS_EX_NOACTIVATE, wc.lpszClassName, NULL, WS_POPUP, 0, 0, 0, 0, HWND_DESKTOP, NULL, pContext->hInstance, &info);
@@ -196,21 +194,17 @@ static LRESULT CALLBACK WndProc(
196 { 194 {
197 DWORD dwEndSession = static_cast<DWORD>(lParam); 195 DWORD dwEndSession = static_cast<DWORD>(lParam);
198 BOOL fCritical = ENDSESSION_CRITICAL & dwEndSession; 196 BOOL fCritical = ENDSESSION_CRITICAL & dwEndSession;
199 BOOL fCancel = TRUE; 197 BOOL fCancel = FALSE;
200 BOOL fRet = FALSE; 198 BOOL fRet = FALSE;
201 199
202 // Always block shutdown in the elevated process, but ask the BA in the non-elevated. 200 // Always block shutdown during apply.
203 UITHREAD_INFO* pInfo = reinterpret_cast<UITHREAD_INFO*>(::GetWindowLongPtrW(hWnd, GWLP_USERDATA)); 201 UITHREAD_INFO* pInfo = reinterpret_cast<UITHREAD_INFO*>(::GetWindowLongPtrW(hWnd, GWLP_USERDATA));
204 if (!pInfo->fElevatedEngine) 202 if (pInfo->pEngineState->plan.fApplying)
205 { 203 {
206 // TODO: instead of recommending canceling all non-critical shutdowns, maybe we should only recommend cancel 204 fCancel = TRUE;
207 // when the engine is doing work?
208 fCancel = !fCritical;
209 // TODO: There's a race condition here where the BA may not have been loaded, or already was unloaded.
210 UserExperienceOnSystemShutdown(pInfo->pUserExperience, dwEndSession, &fCancel);
211 } 205 }
212 206
213 *pInfo->pfCriticalShutdownInitiated |= fCritical; 207 pInfo->pEngineState->fCriticalShutdownInitiated |= fCritical;
214 208
215 fRet = !fCancel; 209 fRet = !fCancel;
216 LogId(REPORT_STANDARD, MSG_SYSTEM_SHUTDOWN, LoggingBoolToString(fCritical), LoggingBoolToString(pInfo->fElevatedEngine), LoggingBoolToString(fRet)); 210 LogId(REPORT_STANDARD, MSG_SYSTEM_SHUTDOWN, LoggingBoolToString(fCritical), LoggingBoolToString(pInfo->fElevatedEngine), LoggingBoolToString(fRet));
diff --git a/src/burn/engine/userexperience.cpp b/src/burn/engine/userexperience.cpp
index a3cbcd4a..4325a6ee 100644
--- a/src/burn/engine/userexperience.cpp
+++ b/src/burn/engine/userexperience.cpp
@@ -2631,31 +2631,6 @@ LExit:
2631 return hr; 2631 return hr;
2632} 2632}
2633 2633
2634EXTERN_C BAAPI UserExperienceOnSystemShutdown(
2635 __in BURN_USER_EXPERIENCE* pUserExperience,
2636 __in DWORD dwEndSession,
2637 __inout BOOL* pfCancel
2638 )
2639{
2640 HRESULT hr = S_OK;
2641 BA_ONSYSTEMSHUTDOWN_ARGS args = { };
2642 BA_ONSYSTEMSHUTDOWN_RESULTS results = { };
2643
2644 args.cbSize = sizeof(args);
2645 args.dwEndSession = dwEndSession;
2646
2647 results.cbSize = sizeof(results);
2648 results.fCancel = *pfCancel;
2649
2650 hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMSHUTDOWN, &args, &results);
2651 ExitOnFailure(hr, "BA OnSystemShutdown failed.");
2652
2653 *pfCancel = results.fCancel;
2654
2655LExit:
2656 return hr;
2657}
2658
2659EXTERN_C BAAPI UserExperienceOnUnregisterBegin( 2634EXTERN_C BAAPI UserExperienceOnUnregisterBegin(
2660 __in BURN_USER_EXPERIENCE* pUserExperience, 2635 __in BURN_USER_EXPERIENCE* pUserExperience,
2661 __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType 2636 __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType
diff --git a/src/burn/engine/userexperience.h b/src/burn/engine/userexperience.h
index 2059b521..e7489710 100644
--- a/src/burn/engine/userexperience.h
+++ b/src/burn/engine/userexperience.h
@@ -583,11 +583,6 @@ BAAPI UserExperienceOnSystemRestorePointComplete(
583 __in BURN_USER_EXPERIENCE* pUserExperience, 583 __in BURN_USER_EXPERIENCE* pUserExperience,
584 __in HRESULT hrStatus 584 __in HRESULT hrStatus
585 ); 585 );
586BAAPI UserExperienceOnSystemShutdown(
587 __in BURN_USER_EXPERIENCE* pUserExperience,
588 __in DWORD dwEndSession,
589 __inout BOOL* pfCancel
590 );
591BAAPI UserExperienceOnUnregisterBegin( 586BAAPI UserExperienceOnUnregisterBegin(
592 __in BURN_USER_EXPERIENCE* pUserExperience, 587 __in BURN_USER_EXPERIENCE* pUserExperience,
593 __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType 588 __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType
diff --git a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
index e93dbe90..c89d12c4 100644
--- a/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
+++ b/src/ext/Bal/wixstdba/WixStandardBootstrapperApplication.cpp
@@ -1265,9 +1265,6 @@ public: // IBootstrapperApplication
1265 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSHUTDOWN: 1265 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSHUTDOWN:
1266 OnShutdownFallback(reinterpret_cast<BA_ONSHUTDOWN_ARGS*>(pvArgs), reinterpret_cast<BA_ONSHUTDOWN_RESULTS*>(pvResults)); 1266 OnShutdownFallback(reinterpret_cast<BA_ONSHUTDOWN_ARGS*>(pvArgs), reinterpret_cast<BA_ONSHUTDOWN_RESULTS*>(pvResults));
1267 break; 1267 break;
1268 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONSYSTEMSHUTDOWN:
1269 OnSystemShutdownFallback(reinterpret_cast<BA_ONSYSTEMSHUTDOWN_ARGS*>(pvArgs), reinterpret_cast<BA_ONSYSTEMSHUTDOWN_RESULTS*>(pvResults));
1270 break;
1271 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE: 1268 case BOOTSTRAPPER_APPLICATION_MESSAGE_ONDETECTFORWARDCOMPATIBLEBUNDLE:
1272 OnDetectForwardCompatibleBundleFallback(reinterpret_cast<BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_RESULTS*>(pvResults)); 1269 OnDetectForwardCompatibleBundleFallback(reinterpret_cast<BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_ARGS*>(pvArgs), reinterpret_cast<BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_RESULTS*>(pvResults));
1273 break; 1270 break;
@@ -1544,14 +1541,6 @@ private: // privates
1544 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONSHUTDOWN, pArgs, pResults, m_pvBAFunctionsProcContext); 1541 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONSHUTDOWN, pArgs, pResults, m_pvBAFunctionsProcContext);
1545 } 1542 }
1546 1543
1547 void OnSystemShutdownFallback(
1548 __in BA_ONSYSTEMSHUTDOWN_ARGS* pArgs,
1549 __inout BA_ONSYSTEMSHUTDOWN_RESULTS* pResults
1550 )
1551 {
1552 m_pfnBAFunctionsProc(BA_FUNCTIONS_MESSAGE_ONSYSTEMSHUTDOWN, pArgs, pResults, m_pvBAFunctionsProcContext);
1553 }
1554
1555 void OnDetectForwardCompatibleBundleFallback( 1544 void OnDetectForwardCompatibleBundleFallback(
1556 __in BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_ARGS* pArgs, 1545 __in BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_ARGS* pArgs,
1557 __inout BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_RESULTS* pResults 1546 __inout BA_ONDETECTFORWARDCOMPATIBLEBUNDLE_RESULTS* pResults
@@ -2948,7 +2937,6 @@ private:
2948 { 2937 {
2949#pragma warning(suppress:4312) 2938#pragma warning(suppress:4312)
2950 CWixStandardBootstrapperApplication* pBA = reinterpret_cast<CWixStandardBootstrapperApplication*>(::GetWindowLongPtrW(hWnd, GWLP_USERDATA)); 2939 CWixStandardBootstrapperApplication* pBA = reinterpret_cast<CWixStandardBootstrapperApplication*>(::GetWindowLongPtrW(hWnd, GWLP_USERDATA));
2951 BOOL fCancel = FALSE;
2952 2940
2953 switch (uMsg) 2941 switch (uMsg)
2954 { 2942 {
@@ -2975,11 +2963,6 @@ private:
2975 case WM_THMUTIL_LOADED_CONTROL: 2963 case WM_THMUTIL_LOADED_CONTROL:
2976 return pBA->OnThemeLoadedControl(reinterpret_cast<THEME_LOADEDCONTROL_ARGS*>(wParam), reinterpret_cast<THEME_LOADEDCONTROL_RESULTS*>(lParam)); 2964 return pBA->OnThemeLoadedControl(reinterpret_cast<THEME_LOADEDCONTROL_ARGS*>(wParam), reinterpret_cast<THEME_LOADEDCONTROL_RESULTS*>(lParam));
2977 2965
2978 case WM_QUERYENDSESSION:
2979 fCancel = true;
2980 pBA->OnSystemShutdown(static_cast<DWORD>(lParam), &fCancel);
2981 return !fCancel;
2982
2983 case WM_CLOSE: 2966 case WM_CLOSE:
2984 // If the user chose not to close, do *not* let the default window proc handle the message. 2967 // If the user chose not to close, do *not* let the default window proc handle the message.
2985 if (!pBA->OnClose()) 2968 if (!pBA->OnClose())
diff --git a/src/test/burn/TestBA/TestBA.cs b/src/test/burn/TestBA/TestBA.cs
index b4d74341..5f492efd 100644
--- a/src/test/burn/TestBA/TestBA.cs
+++ b/src/test/burn/TestBA/TestBA.cs
@@ -531,15 +531,6 @@ namespace WixToolset.Test.BA
531 this.ShutdownUiThread(); 531 this.ShutdownUiThread();
532 } 532 }
533 533
534 protected override void OnSystemShutdown(SystemShutdownEventArgs args)
535 {
536 // Always prevent shutdown.
537 this.Log("Disallowed system request to shut down the bootstrapper application.");
538 args.Cancel = true;
539
540 this.ShutdownUiThread();
541 }
542
543 protected override void OnUnregisterBegin(UnregisterBeginEventArgs args) 534 protected override void OnUnregisterBegin(UnregisterBeginEventArgs args)
544 { 535 {
545 if (this.forceKeepRegistration && args.RegistrationType == RegistrationType.None) 536 if (this.forceKeepRegistration && args.RegistrationType == RegistrationType.None)
diff --git a/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp b/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp
index 7c533fea..3cf994fc 100644
--- a/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp
+++ b/src/test/burn/TestData/Manual/BafThmutilTesting/BafThmUtilTesting.cpp
@@ -88,6 +88,56 @@ public: // IBAFunctions
88 return hr; 88 return hr;
89 } 89 }
90 90
91 virtual STDMETHODIMP WndProc(
92 __in HWND hWnd,
93 __in UINT uMsg,
94 __in WPARAM /*wParam*/,
95 __in LPARAM lParam,
96 __inout BOOL* pfProcessed,
97 __inout LRESULT* plResult
98 )
99 {
100 switch (uMsg)
101 {
102 case WM_QUERYENDSESSION:
103 if (BOOTSTRAPPER_DISPLAY_FULL <= m_command.display)
104 {
105 DWORD dwEndSession = static_cast<DWORD>(lParam);
106 if (ENDSESSION_CRITICAL & dwEndSession)
107 {
108 // Return false to get the WM_ENDSESSION message so that critical shutdowns can be delayed.
109 *plResult = FALSE;
110 *pfProcessed = TRUE;
111 }
112 }
113 break;
114 case WM_ENDSESSION:
115 if (BOOTSTRAPPER_DISPLAY_FULL <= m_command.display)
116 {
117 ::MessageBoxW(hWnd, L"WM_ENDSESSION", L"BAFunctions WndProc", MB_OK);
118 }
119 break;
120 }
121 return S_OK;
122 }
123
124public: //IBootstrapperApplication
125 virtual STDMETHODIMP OnExecuteBegin(
126 __in DWORD /*cExecutingPackages*/,
127 __inout BOOL* pfCancel
128 )
129 {
130 if (BOOTSTRAPPER_DISPLAY_FULL <= m_command.display)
131 {
132 if (IDCANCEL == ::MessageBoxW(m_hwndParent, L"Shutdown requests should be denied right now.", L"OnExecuteBegin", MB_OKCANCEL))
133 {
134 *pfCancel = TRUE;
135 }
136 }
137
138 return S_OK;
139 }
140
91private: 141private:
92 HRESULT OnShowTheme() 142 HRESULT OnShowTheme()
93 { 143 {
@@ -138,6 +188,8 @@ private:
138 188
139 ThemeInitializeWindowClass(m_pBafTheme, &wc, CBafThmUtilTesting::TestingWndProc, m_hModule, BAFTHMUTILTESTING_WINDOW_CLASS); 189 ThemeInitializeWindowClass(m_pBafTheme, &wc, CBafThmUtilTesting::TestingWndProc, m_hModule, BAFTHMUTILTESTING_WINDOW_CLASS);
140 190
191 Assert(wc.lpszClassName);
192
141 // If the theme did not provide an icon, try using the icon from the bundle engine. 193 // If the theme did not provide an icon, try using the icon from the bundle engine.
142 if (!wc.hIcon) 194 if (!wc.hIcon)
143 { 195 {
diff --git a/src/test/burn/TestData/Manual/BundleA/BundleA.wxs b/src/test/burn/TestData/Manual/BundleA/BundleA.wxs
index 20706b6a..44abc645 100644
--- a/src/test/burn/TestData/Manual/BundleA/BundleA.wxs
+++ b/src/test/burn/TestData/Manual/BundleA/BundleA.wxs
@@ -1,4 +1,4 @@
1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. --> 1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2 2
3 3
4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal"> 4<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:bal="http://wixtoolset.org/schemas/v4/wxs/bal">
@@ -8,7 +8,10 @@
8 <Payload SourceFile="$(var.BafThmUtilTesting.TargetPath)" bal:BAFunctions="yes" /> 8 <Payload SourceFile="$(var.BafThmUtilTesting.TargetPath)" bal:BAFunctions="yes" />
9 </BootstrapperApplication> 9 </BootstrapperApplication>
10 <PackageGroup Id="BundlePackages"> 10 <PackageGroup Id="BundlePackages">
11 <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)" /> 11 <MsiPackage Id="PackageA" SourceFile="$(var.PackageA.TargetPath)">
12 <MsiProperty Name="FORCERESTARTCA" Value="[FORCERESTARTCA]" />
13 </MsiPackage>
12 </PackageGroup> 14 </PackageGroup>
15 <Variable Name="FORCERESTARTCA" bal:Overridable="yes" />
13 </Fragment> 16 </Fragment>
14</Wix> 17</Wix>
diff --git a/src/test/burn/TestData/Manual/PackageA/PackageA.wixproj b/src/test/burn/TestData/Manual/PackageA/PackageA.wixproj
index c9c81c3a..61dc27ab 100644
--- a/src/test/burn/TestData/Manual/PackageA/PackageA.wixproj
+++ b/src/test/burn/TestData/Manual/PackageA/PackageA.wixproj
@@ -2,8 +2,12 @@
2<Project Sdk="WixToolset.Sdk"> 2<Project Sdk="WixToolset.Sdk">
3 <PropertyGroup> 3 <PropertyGroup>
4 <UpgradeCode>{0D803A6E-8090-4174-8DAC-810ECC2B1BBF}</UpgradeCode> 4 <UpgradeCode>{0D803A6E-8090-4174-8DAC-810ECC2B1BBF}</UpgradeCode>
5 <ProductComponentsRef>true</ProductComponentsRef>
5 </PropertyGroup> 6 </PropertyGroup>
6 <ItemGroup> 7 <ItemGroup>
7 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" /> 8 <Compile Include="..\..\Templates\Package.wxs" Link="Package.wxs" />
8 </ItemGroup> 9 </ItemGroup>
10 <ItemGroup>
11 <PackageReference Include="WixToolset.Util.wixext" />
12 </ItemGroup>
9</Project> \ No newline at end of file 13</Project> \ No newline at end of file
diff --git a/src/test/burn/TestData/Manual/PackageA/ProductA.wxs b/src/test/burn/TestData/Manual/PackageA/ProductA.wxs
new file mode 100644
index 00000000..bf1ef152
--- /dev/null
+++ b/src/test/burn/TestData/Manual/PackageA/ProductA.wxs
@@ -0,0 +1,15 @@
1<!-- Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information. -->
2
3<Wix xmlns="http://wixtoolset.org/schemas/v4/wxs" xmlns:util="http://wixtoolset.org/schemas/v4/wxs/util">
4 <Fragment>
5 <ComponentGroup Id="ProductComponents" />
6
7 <Property Id="FORCERESTARTCA" Secure="yes" />
8 <Property Id="ForceRestartCA" Value="&quot;shutdown.exe&quot; -r -f -t 0" />
9 <CustomAction Id="ForceRestartCA" DllEntry="WixQuietExec" BinaryRef="Wix4UtilCA_X86" Execute="deferred" Return="ignore" />
10
11 <InstallExecuteSequence>
12 <Custom Action="ForceRestartCA" After="InstallFiles" Condition="FORCERESTARTCA = 1" />
13 </InstallExecuteSequence>
14 </Fragment>
15</Wix>