@joebigelow / wix-1 / commits / 2c085b3a

Add InProgressDisplayName for bundles.

#6296

Sean Hall committed May 13, 2021 at 20:46 UTC 2c085b3aa89150fff9a0ea6df2cde0ce56e3066d
28 files changed +391 -170
src/api/burn/WixToolset.BootstrapperCore.Native/inc/BootstrapperApplication.h
+11 -2
@@ -20,6 +20,13 @@ enum BOOTSTRAPPER_RESTART
20 BOOTSTRAPPER_RESTART_ALWAYS,
21 };
22
23 +enum BOOTSTRAPPER_REGISTRATION_TYPE
24 +{
25 + BOOTSTRAPPER_REGISTRATION_TYPE_NONE, // The engine will ignore NONE if it recommended INPROGRESS or FULL.
26 + BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS,
27 + BOOTSTRAPPER_REGISTRATION_TYPE_FULL,
28 +};
29 +
30 enum BOOTSTRAPPER_RESUME_TYPE
31 {
32 BOOTSTRAPPER_RESUME_TYPE_NONE,
@@ -1163,12 +1170,14 @@ struct BA_ONPROGRESS_RESULTS
1170 struct BA_ONREGISTERBEGIN_ARGS
1171 {
1172 DWORD cbSize;
1173 + BOOTSTRAPPER_REGISTRATION_TYPE recommendedRegistrationType;
1174 };
1175
1176 struct BA_ONREGISTERBEGIN_RESULTS
1177 {
1178 DWORD cbSize;
1179 BOOL fCancel;
1180 + BOOTSTRAPPER_REGISTRATION_TYPE registrationType;
1181 };
1182
1183 struct BA_ONREGISTERCOMPLETE_ARGS
@@ -1262,13 +1271,13 @@ struct BA_ONSYSTEMSHUTDOWN_RESULTS
1271 struct BA_ONUNREGISTERBEGIN_ARGS
1272 {
1273 DWORD cbSize;
1265 - BOOL fKeepRegistration;
1274 + BOOTSTRAPPER_REGISTRATION_TYPE recommendedRegistrationType;
1275 };
1276
1277 struct BA_ONUNREGISTERBEGIN_RESULTS
1278 {
1279 DWORD cbSize;
1271 - BOOL fForceKeepRegistration;
1280 + BOOTSTRAPPER_REGISTRATION_TYPE registrationType;
1281 };
1282
1283 struct BA_ONUNREGISTERCOMPLETE_ARGS
src/api/burn/WixToolset.Mba.Core/BootstrapperApplication.cs
+6 -5
@@ -1490,12 +1490,13 @@ namespace WixToolset.Mba.Core
1490 return args.HResult;
1491 }
1492
1493 - int IBootstrapperApplication.OnRegisterBegin(ref bool fCancel)
1493 + int IBootstrapperApplication.OnRegisterBegin(RegistrationType recommendedRegistrationType, ref bool fCancel, ref RegistrationType registrationType)
1494 {
1495 - RegisterBeginEventArgs args = new RegisterBeginEventArgs(fCancel);
1495 + RegisterBeginEventArgs args = new RegisterBeginEventArgs(recommendedRegistrationType, fCancel, registrationType);
1496 this.OnRegisterBegin(args);
1497
1498 fCancel = args.Cancel;
1499 + registrationType = args.RegistrationType;
1500 return args.HResult;
1501 }
1502
@@ -1679,12 +1680,12 @@ namespace WixToolset.Mba.Core
1680 return args.HResult;
1681 }
1682
1682 - int IBootstrapperApplication.OnUnregisterBegin(bool fKeepRegistration, ref bool fForceKeepRegistration)
1683 + int IBootstrapperApplication.OnUnregisterBegin(RegistrationType recommendedRegistrationType, ref RegistrationType registrationType)
1684 {
1684 - UnregisterBeginEventArgs args = new UnregisterBeginEventArgs(fKeepRegistration, fForceKeepRegistration);
1685 + UnregisterBeginEventArgs args = new UnregisterBeginEventArgs(recommendedRegistrationType, registrationType);
1686 this.OnUnregisterBegin(args);
1687
1687 - fForceKeepRegistration = args.ForceKeepRegistration;
1688 + registrationType = args.RegistrationType;
1689 return args.HResult;
1690 }
1691
src/api/burn/WixToolset.Mba.Core/EventArgs.cs
+24 -22
@@ -1184,22 +1184,31 @@ namespace WixToolset.Mba.Core
1184 public class RegisterBeginEventArgs : CancellableHResultEventArgs
1185 {
1186 /// <summary />
1187 - public RegisterBeginEventArgs(bool cancelRecommendation)
1187 + public RegisterBeginEventArgs(RegistrationType recommendedRegistrationType, bool cancelRecommendation, RegistrationType registrationType)
1188 : base(cancelRecommendation)
1189 {
1190 + this.RecommendedRegistrationType = recommendedRegistrationType;
1191 + this.RegistrationType = registrationType;
1192 }
1193 +
1194 + /// <summary>
1195 + /// Gets the recommended registration type.
1196 + /// </summary>
1197 + public RegistrationType RecommendedRegistrationType { get; private set; }
1198 +
1199 + /// <summary>
1200 + /// Gets or sets the registration type.
1201 + /// </summary>
1202 + public RegistrationType RegistrationType { get; set; }
1203 }
1204
1205 /// <summary>
1194 - /// Additional arguments used when the engine has completed registering the location and visilibity of the bundle.
1206 + /// Event arguments for <see cref="IDefaultBootstrapperApplication.RegisterComplete"/>.
1207 /// </summary>
1208 [Serializable]
1209 public class RegisterCompleteEventArgs : StatusEventArgs
1210 {
1199 - /// <summary>
1200 - /// Creates a new instance of the <see cref="RegisterCompleteEventArgs"/> class.
1201 - /// </summary>
1202 - /// <param name="hrStatus">The return code of the operation.</param>
1211 + /// <summary />
1212 public RegisterCompleteEventArgs(int hrStatus)
1213 : base(hrStatus)
1214 {
@@ -1212,26 +1221,22 @@ namespace WixToolset.Mba.Core
1221 [Serializable]
1222 public class UnregisterBeginEventArgs : HResultEventArgs
1223 {
1215 - /// <summary>
1216 - ///
1217 - /// </summary>
1218 - /// <param name="keepRegistration"></param>
1219 - /// <param name="forceKeepRegistration"></param>
1220 - public UnregisterBeginEventArgs(bool keepRegistration, bool forceKeepRegistration)
1224 + /// <summary />
1225 + public UnregisterBeginEventArgs(RegistrationType recommendedRegistrationType, RegistrationType registrationType)
1226 {
1222 - this.KeepRegistration = keepRegistration;
1223 - this.ForceKeepRegistration = forceKeepRegistration;
1227 + this.RecommendedRegistrationType = recommendedRegistrationType;
1228 + this.RegistrationType = registrationType;
1229 }
1230
1231 /// <summary>
1227 - /// Indicates whether the engine will uninstall the bundle.
1232 + /// Gets the recommended registration type.
1233 /// </summary>
1229 - public bool ForceKeepRegistration { get; set; }
1234 + public RegistrationType RecommendedRegistrationType { get; private set; }
1235
1236 /// <summary>
1232 - /// If <see cref="KeepRegistration"/> is FALSE, then this can be set to TRUE to make the engine keep the bundle installed.
1237 + /// Gets or sets the registration type.
1238 /// </summary>
1234 - public bool KeepRegistration { get; private set; }
1239 + public RegistrationType RegistrationType { get; set; }
1240 }
1241
1242 /// <summary>
@@ -1240,10 +1245,7 @@ namespace WixToolset.Mba.Core
1245 [Serializable]
1246 public class UnregisterCompleteEventArgs : StatusEventArgs
1247 {
1243 - /// <summary>
1244 - ///
1245 - /// </summary>
1246 - /// <param name="hrStatus"></param>
1248 + /// <summary />
1249 public UnregisterCompleteEventArgs(int hrStatus)
1250 : base(hrStatus)
1251 {
src/api/burn/WixToolset.Mba.Core/IBootstrapperApplication.cs
+27 -8
@@ -500,12 +500,12 @@ namespace WixToolset.Mba.Core
500 /// <summary>
501 /// See <see cref="IDefaultBootstrapperApplication.RegisterBegin"/>.
502 /// </summary>
503 - /// <param name="fCancel"></param>
504 - /// <returns></returns>
503 [PreserveSig]
504 [return: MarshalAs(UnmanagedType.I4)]
505 int OnRegisterBegin(
508 - [MarshalAs(UnmanagedType.Bool)] ref bool fCancel
506 + [MarshalAs(UnmanagedType.I4)] RegistrationType recommendedRegistrationType,
507 + [MarshalAs(UnmanagedType.Bool)] ref bool fCancel,
508 + [MarshalAs(UnmanagedType.I4)] ref RegistrationType pRegistrationType
509 );
510
511 /// <summary>
@@ -820,14 +820,11 @@ namespace WixToolset.Mba.Core
820 /// <summary>
821 /// See <see cref="IDefaultBootstrapperApplication.UnregisterBegin"/>.
822 /// </summary>
823 - /// <param name="fKeepRegistration"></param>
824 - /// <param name="fForceKeepRegistration"></param>
825 - /// <returns></returns>
823 [PreserveSig]
824 [return: MarshalAs(UnmanagedType.I4)]
825 int OnUnregisterBegin(
829 - [MarshalAs(UnmanagedType.Bool)] bool fKeepRegistration,
830 - [MarshalAs(UnmanagedType.Bool)] ref bool fForceKeepRegistration
826 + [MarshalAs(UnmanagedType.I4)] RegistrationType recommendedRegistrationType,
827 + [MarshalAs(UnmanagedType.I4)] ref RegistrationType pRegistrationType
828 );
829
830 /// <summary>
@@ -1259,6 +1256,28 @@ namespace WixToolset.Mba.Core
1256 Always,
1257 }
1258
1259 + /// <summary>
1260 + /// The display name to use when registering in Add/Remove Programs.
1261 + /// </summary>
1262 + public enum RegistrationType
1263 + {
1264 + /// <summary>
1265 + /// No registration.
1266 + /// The engine will ignore None if it recommended InProgress or Full.
1267 + /// </summary>
1268 + None,
1269 +
1270 + /// <summary>
1271 + /// The in-progress display name.
1272 + /// </summary>
1273 + InProgress,
1274 +
1275 + /// <summary>
1276 + /// The default display name.
1277 + /// </summary>
1278 + Full,
1279 + }
1280 +
1281 /// <summary>
1282 /// Result codes (based on Dialog Box Command IDs from WinUser.h).
1283 /// </summary>
src/api/burn/balutil/inc/BalBaseBAFunctions.h
+5 -3
@@ -379,7 +379,9 @@ public: // IBootstrapperApplication
379 }
380
381 virtual STDMETHODIMP OnRegisterBegin(
382 - __inout BOOL* /*pfCancel*/
382 + __in BOOTSTRAPPER_REGISTRATION_TYPE /*recommendedRegistrationType*/,
383 + __inout BOOL* /*pfCancel*/,
384 + __inout BOOTSTRAPPER_REGISTRATION_TYPE* /*pRegistrationType*/
385 )
386 {
387 return S_OK;
@@ -597,8 +599,8 @@ public: // IBootstrapperApplication
599 }
600
601 virtual STDMETHODIMP OnUnregisterBegin(
600 - __in BOOL /*fKeepRegistration*/,
601 - __inout BOOL* /*pfForceKeepRegistration*/
602 + __in BOOTSTRAPPER_REGISTRATION_TYPE /*recommendedRegistrationType*/,
603 + __inout BOOTSTRAPPER_REGISTRATION_TYPE* /*pRegistrationType*/
604 )
605 {
606 return S_OK;
src/api/burn/balutil/inc/BalBaseBootstrapperApplication.h
+5 -3
@@ -435,7 +435,9 @@ public: // IBootstrapperApplication
435 }
436
437 virtual STDMETHODIMP OnRegisterBegin(
438 - __inout BOOL* pfCancel
438 + __in BOOTSTRAPPER_REGISTRATION_TYPE /*recommendedRegistrationType*/,
439 + __inout BOOL* pfCancel,
440 + __inout BOOTSTRAPPER_REGISTRATION_TYPE* /*pRegistrationType*/
441 )
442 {
443 *pfCancel |= CheckCanceled();
@@ -769,8 +771,8 @@ public: // IBootstrapperApplication
771 }
772
773 virtual STDMETHODIMP OnUnregisterBegin(
772 - __in BOOL /*fKeepRegistration*/,
773 - __inout BOOL* /*pfForceKeepRegistration*/
774 + __in BOOTSTRAPPER_REGISTRATION_TYPE /*recommendedRegistrationType*/,
775 + __inout BOOTSTRAPPER_REGISTRATION_TYPE* /*pRegistrationType*/
776 )
777 {
778 return S_OK;
src/api/burn/balutil/inc/BalBaseBootstrapperApplicationProc.h
+3 -3
@@ -263,11 +263,11 @@ static HRESULT BalBaseBAProcOnError(
263
264 static HRESULT BalBaseBAProcOnRegisterBegin(
265 __in IBootstrapperApplication* pBA,
266 - __in BA_ONREGISTERBEGIN_ARGS* /*pArgs*/,
266 + __in BA_ONREGISTERBEGIN_ARGS* pArgs,
267 __inout BA_ONREGISTERBEGIN_RESULTS* pResults
268 )
269 {
270 - return pBA->OnRegisterBegin(&pResults->fCancel);
270 + return pBA->OnRegisterBegin(pArgs->recommendedRegistrationType, &pResults->fCancel, &pResults->registrationType);
271 }
272
273 static HRESULT BalBaseBAProcOnRegisterComplete(
@@ -456,7 +456,7 @@ static HRESULT BalBaseBAProcOnUnregisterBegin(
456 __inout BA_ONUNREGISTERBEGIN_RESULTS* pResults
457 )
458 {
459 - return pBA->OnUnregisterBegin(pArgs->fKeepRegistration, &pResults->fForceKeepRegistration);
459 + return pBA->OnUnregisterBegin(pArgs->recommendedRegistrationType, &pResults->registrationType);
460 }
461
462 static HRESULT BalBaseBAProcOnUnregisterComplete(
src/api/burn/balutil/inc/IBootstrapperApplication.h
+5 -3
@@ -280,7 +280,9 @@ DECLARE_INTERFACE_IID_(IBootstrapperApplication, IUnknown, "53C31D56-49C0-426B-A
280 // OnRegisterBegin - called when the engine registers the bundle.
281 //
282 STDMETHOD(OnRegisterBegin)(
283 - __inout BOOL* pfCancel
283 + __in BOOTSTRAPPER_REGISTRATION_TYPE recommendedRegistrationType,
284 + __inout BOOL* pfCancel,
285 + __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType
286 ) = 0;
287
288 // OnRegisterComplete - called when the engine registration is
@@ -519,8 +521,8 @@ DECLARE_INTERFACE_IID_(IBootstrapperApplication, IUnknown, "53C31D56-49C0-426B-A
521 // OnUnregisterBegin - called when the engine unregisters the bundle.
522 //
523 STDMETHOD(OnUnregisterBegin)(
522 - __in BOOL fKeepRegistration,
523 - __inout BOOL* pfForceKeepRegistration
524 + __in BOOTSTRAPPER_REGISTRATION_TYPE recommendedRegistrationType,
525 + __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType
526 ) = 0;
527
528 // OnUnregisterComplete - called when the engine unregistration is complete.
src/api/wix/WixToolset.Data/Burn/BurnConstants.cs
+1
@@ -18,6 +18,7 @@ namespace WixToolset.Data.Burn
18 public const string BundleExtensionSearchSymbolDefinitionTag = "WixBundleExtensionSearch";
19
20 // The following constants must stay in sync with src\burn\engine\core.h
21 + public const string BURN_BUNDLE_INPROGRESS_NAME = "WixBundleInProgressName";
22 public const string BURN_BUNDLE_NAME = "WixBundleName";
23 public const string BURN_BUNDLE_ORIGINAL_SOURCE = "WixBundleOriginalSource";
24 public const string BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER = "WixBundleOriginalSourceFolder";
src/api/wix/WixToolset.Data/Symbols/WixBundleSymbol.cs
+8
@@ -32,6 +32,7 @@ namespace WixToolset.Data
32 new IntermediateFieldDefinition(nameof(WixBundleSymbolFields.ParentName), IntermediateFieldType.String),
33 new IntermediateFieldDefinition(nameof(WixBundleSymbolFields.BundleId), IntermediateFieldType.String),
34 new IntermediateFieldDefinition(nameof(WixBundleSymbolFields.ProviderKey), IntermediateFieldType.String),
35 + new IntermediateFieldDefinition(nameof(WixBundleSymbolFields.InProgressName), IntermediateFieldType.String),
36 },
37 typeof(WixBundleSymbol));
38 }
@@ -65,6 +66,7 @@ namespace WixToolset.Data.Symbols
66 ParentName,
67 BundleId,
68 ProviderKey,
69 + InProgressName,
70 }
71
72 [Flags]
@@ -221,6 +223,12 @@ namespace WixToolset.Data.Symbols
223 set => this.Set((int)WixBundleSymbolFields.ProviderKey, value);
224 }
225
226 + public string InProgressName
227 + {
228 + get => (string)this.Fields[(int)WixBundleSymbolFields.InProgressName];
229 + set => this.Set((int)WixBundleSymbolFields.InProgressName, value);
230 + }
231 +
232 public PackagingType DefaultPackagingType => (this.Compressed.HasValue && !this.Compressed.Value) ? PackagingType.External : PackagingType.Embedded;
233
234 public bool DisableModify => (this.Attributes & WixBundleAttributes.DisableModify) == WixBundleAttributes.DisableModify;
src/api/wix/api_wix.sln
+2 -12
@@ -1,7 +1,7 @@
1 
2 Microsoft Visual Studio Solution File, Format Version 12.00
3 -# Visual Studio 15
4 -VisualStudioVersion = 15.0.27004.2009
3 +# Visual Studio Version 16
4 +VisualStudioVersion = 16.0.31205.134
5 MinimumVisualStudioVersion = 10.0.40219.1
6 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WixToolset.Data", "WixToolset.Data\WixToolset.Data.csproj", "{73ADBD3A-8FB2-47DB-BC79-9BC61C40F2E0}"
7 EndProject
@@ -12,43 +12,33 @@ EndProject
12 Global
13 GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 Debug|Any CPU = Debug|Any CPU
15 - Debug|arm = Debug|arm
15 Debug|x64 = Debug|x64
16 Debug|x86 = Debug|x86
17 Release|Any CPU = Release|Any CPU
19 - Release|arm = Release|arm
18 Release|x64 = Release|x64
19 Release|x86 = Release|x86
20 EndGlobalSection
21 GlobalSection(ProjectConfigurationPlatforms) = postSolution
22 {73ADBD3A-8FB2-47DB-BC79-9BC61C40F2E0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 {73ADBD3A-8FB2-47DB-BC79-9BC61C40F2E0}.Debug|Any CPU.Build.0 = Debug|Any CPU
26 - {73ADBD3A-8FB2-47DB-BC79-9BC61C40F2E0}.Debug|arm.ActiveCfg = Debug|Any CPU
27 - {73ADBD3A-8FB2-47DB-BC79-9BC61C40F2E0}.Debug|arm.Build.0 = Debug|Any CPU
24 {73ADBD3A-8FB2-47DB-BC79-9BC61C40F2E0}.Debug|x64.ActiveCfg = Debug|Any CPU
25 {73ADBD3A-8FB2-47DB-BC79-9BC61C40F2E0}.Debug|x64.Build.0 = Debug|Any CPU
26 {73ADBD3A-8FB2-47DB-BC79-9BC61C40F2E0}.Debug|x86.ActiveCfg = Debug|Any CPU
27 {73ADBD3A-8FB2-47DB-BC79-9BC61C40F2E0}.Debug|x86.Build.0 = Debug|Any CPU
28 {73ADBD3A-8FB2-47DB-BC79-9BC61C40F2E0}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 {73ADBD3A-8FB2-47DB-BC79-9BC61C40F2E0}.Release|Any CPU.Build.0 = Release|Any CPU
34 - {73ADBD3A-8FB2-47DB-BC79-9BC61C40F2E0}.Release|arm.ActiveCfg = Release|Any CPU
35 - {73ADBD3A-8FB2-47DB-BC79-9BC61C40F2E0}.Release|arm.Build.0 = Release|Any CPU
30 {73ADBD3A-8FB2-47DB-BC79-9BC61C40F2E0}.Release|x64.ActiveCfg = Release|Any CPU
31 {73ADBD3A-8FB2-47DB-BC79-9BC61C40F2E0}.Release|x64.Build.0 = Release|Any CPU
32 {73ADBD3A-8FB2-47DB-BC79-9BC61C40F2E0}.Release|x86.ActiveCfg = Release|Any CPU
33 {73ADBD3A-8FB2-47DB-BC79-9BC61C40F2E0}.Release|x86.Build.0 = Release|Any CPU
34 {6C1FA8B7-BF3C-4735-95F8-26DEEFEF00C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
35 {6C1FA8B7-BF3C-4735-95F8-26DEEFEF00C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
42 - {6C1FA8B7-BF3C-4735-95F8-26DEEFEF00C8}.Debug|arm.ActiveCfg = Debug|Any CPU
43 - {6C1FA8B7-BF3C-4735-95F8-26DEEFEF00C8}.Debug|arm.Build.0 = Debug|Any CPU
36 {6C1FA8B7-BF3C-4735-95F8-26DEEFEF00C8}.Debug|x64.ActiveCfg = Debug|Any CPU
37 {6C1FA8B7-BF3C-4735-95F8-26DEEFEF00C8}.Debug|x64.Build.0 = Debug|Any CPU
38 {6C1FA8B7-BF3C-4735-95F8-26DEEFEF00C8}.Debug|x86.ActiveCfg = Debug|Any CPU
39 {6C1FA8B7-BF3C-4735-95F8-26DEEFEF00C8}.Debug|x86.Build.0 = Debug|Any CPU
40 {6C1FA8B7-BF3C-4735-95F8-26DEEFEF00C8}.Release|Any CPU.ActiveCfg = Release|Any CPU
41 {6C1FA8B7-BF3C-4735-95F8-26DEEFEF00C8}.Release|Any CPU.Build.0 = Release|Any CPU
50 - {6C1FA8B7-BF3C-4735-95F8-26DEEFEF00C8}.Release|arm.ActiveCfg = Release|Any CPU
51 - {6C1FA8B7-BF3C-4735-95F8-26DEEFEF00C8}.Release|arm.Build.0 = Release|Any CPU
42 {6C1FA8B7-BF3C-4735-95F8-26DEEFEF00C8}.Release|x64.ActiveCfg = Release|Any CPU
43 {6C1FA8B7-BF3C-4735-95F8-26DEEFEF00C8}.Release|x64.Build.0 = Release|Any CPU
44 {6C1FA8B7-BF3C-4735-95F8-26DEEFEF00C8}.Release|x86.ActiveCfg = Release|Any CPU
src/burn/engine/apply.cpp
+61 -26
@@ -75,7 +75,8 @@ static HRESULT WINAPI AuthenticationRequired(
75
76 static void CalculateKeepRegistration(
77 __in BURN_ENGINE_STATE* pEngineState,
78 - __inout BOOL* pfKeepRegistration
78 + __in BOOL fLog,
79 + __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType
80 );
81 static HRESULT ExecuteDependentRegistrationActions(
82 __in HANDLE hPipe,
@@ -376,8 +377,11 @@ extern "C" HRESULT ApplyRegister(
377 {
378 HRESULT hr = S_OK;
379 LPWSTR sczEngineWorkingPath = NULL;
380 + BOOTSTRAPPER_REGISTRATION_TYPE registrationType = BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS;
381
380 - hr = UserExperienceOnRegisterBegin(&pEngineState->userExperience);
382 + CalculateKeepRegistration(pEngineState, FALSE, &registrationType);
383 +
384 + hr = UserExperienceOnRegisterBegin(&pEngineState->userExperience, &registrationType);
385 ExitOnRootFailure(hr, "BA aborted register begin.");
386
387 // If we have a resume mode that suggests the bundle is on the machine.
@@ -386,12 +390,12 @@ extern "C" HRESULT ApplyRegister(
390 // resume previous session
391 if (pEngineState->registration.fPerMachine)
392 {
389 - hr = ElevationSessionResume(pEngineState->companionConnection.hPipe, pEngineState->registration.sczResumeCommandLine, pEngineState->registration.fDisableResume, &pEngineState->variables);
393 + hr = ElevationSessionResume(pEngineState->companionConnection.hPipe, pEngineState->registration.sczResumeCommandLine, pEngineState->registration.fDisableResume, &pEngineState->variables, registrationType);
394 ExitOnFailure(hr, "Failed to resume registration session in per-machine process.");
395 }
396 else
397 {
394 - hr = RegistrationSessionResume(&pEngineState->registration, &pEngineState->variables);
398 + hr = RegistrationSessionResume(&pEngineState->registration, &pEngineState->variables, registrationType);
399 ExitOnFailure(hr, "Failed to resume registration session.");
400 }
401 }
@@ -403,12 +407,12 @@ extern "C" HRESULT ApplyRegister(
407 // begin new session
408 if (pEngineState->registration.fPerMachine)
409 {
406 - hr = ElevationSessionBegin(pEngineState->companionConnection.hPipe, sczEngineWorkingPath, pEngineState->registration.sczResumeCommandLine, pEngineState->registration.fDisableResume, &pEngineState->variables, pEngineState->plan.dwRegistrationOperations, pEngineState->plan.dependencyRegistrationAction, pEngineState->plan.qwEstimatedSize);
410 + hr = ElevationSessionBegin(pEngineState->companionConnection.hPipe, sczEngineWorkingPath, pEngineState->registration.sczResumeCommandLine, pEngineState->registration.fDisableResume, &pEngineState->variables, pEngineState->plan.dwRegistrationOperations, pEngineState->plan.dependencyRegistrationAction, pEngineState->plan.qwEstimatedSize, registrationType);
411 ExitOnFailure(hr, "Failed to begin registration session in per-machine process.");
412 }
413 else
414 {
411 - hr = RegistrationSessionBegin(sczEngineWorkingPath, &pEngineState->registration, &pEngineState->variables, pEngineState->plan.dwRegistrationOperations, pEngineState->plan.dependencyRegistrationAction, pEngineState->plan.qwEstimatedSize);
415 + hr = RegistrationSessionBegin(sczEngineWorkingPath, &pEngineState->registration, &pEngineState->variables, pEngineState->plan.dwRegistrationOperations, pEngineState->plan.dependencyRegistrationAction, pEngineState->plan.qwEstimatedSize, registrationType);
416 ExitOnFailure(hr, "Failed to begin registration session.");
417 }
418 }
@@ -441,17 +445,11 @@ extern "C" HRESULT ApplyUnregister(
445 {
446 HRESULT hr = S_OK;
447 BURN_RESUME_MODE resumeMode = BURN_RESUME_MODE_NONE;
444 - BOOL fKeepRegistration = pEngineState->plan.fDisallowRemoval;
445 -
446 - CalculateKeepRegistration(pEngineState, &fKeepRegistration);
447 -
448 - hr = UserExperienceOnUnregisterBegin(&pEngineState->userExperience, &fKeepRegistration);
449 - ExitOnRootFailure(hr, "BA aborted unregister begin.");
448 + BOOTSTRAPPER_REGISTRATION_TYPE defaultRegistrationType = BOOTSTRAPPER_REGISTRATION_TYPE_NONE;
449 + BOOTSTRAPPER_REGISTRATION_TYPE registrationType = BOOTSTRAPPER_REGISTRATION_TYPE_NONE;
450
451 - // Calculate the correct resume mode. If a restart has been initiated, that trumps all other
451 + // Calculate special cases for the resume mode. If a restart has been initiated, that trumps all other
452 // modes. If the user chose to suspend the install then we'll use that as the resume mode.
453 - // Barring those special cases, if it was determined that we should keep the registration then
454 - // do that, otherwise the resume mode was initialized to none and registration will be removed.
453 if (BOOTSTRAPPER_APPLY_RESTART_INITIATED == restart)
454 {
455 resumeMode = BURN_RESUME_MODE_REBOOT_PENDING;
@@ -460,28 +458,50 @@ extern "C" HRESULT ApplyUnregister(
458 {
459 resumeMode = BURN_RESUME_MODE_SUSPEND;
460 }
463 - else if (fKeepRegistration)
461 + else if (pEngineState->plan.fDisallowRemoval)
462 + {
463 + resumeMode = BURN_RESUME_MODE_ARP;
464 + }
465 +
466 + // If there was a special case, make sure the registration is kept.
467 + if (BURN_RESUME_MODE_NONE < resumeMode)
468 + {
469 + defaultRegistrationType = BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS;
470 + }
471 +
472 + CalculateKeepRegistration(pEngineState, TRUE, &defaultRegistrationType);
473 +
474 + registrationType = defaultRegistrationType;
475 +
476 + hr = UserExperienceOnUnregisterBegin(&pEngineState->userExperience, &registrationType);
477 + ExitOnRootFailure(hr, "BA aborted unregister begin.");
478 +
479 + // Barring the special cases, if it was determined that we should keep the registration then
480 + // do that, otherwise the resume mode is NONE and registration will be removed.
481 + if (BURN_RESUME_MODE_NONE == resumeMode && BOOTSTRAPPER_REGISTRATION_TYPE_NONE < registrationType)
482 {
483 resumeMode = BURN_RESUME_MODE_ARP;
484 }
485
486 // If apply failed in any way and we're going to be keeping the bundle registered then
487 // execute any rollback dependency registration actions.
470 - if (fFailed && fKeepRegistration)
488 + if (fFailed && BURN_RESUME_MODE_NONE < resumeMode)
489 {
490 // Execute any rollback registration actions.
491 HRESULT hrRegistrationRollback = ExecuteDependentRegistrationActions(pEngineState->companionConnection.hPipe, &pEngineState->registration, pEngineState->plan.rgRollbackRegistrationActions, pEngineState->plan.cRollbackRegistrationActions);
474 - UNREFERENCED_PARAMETER(hrRegistrationRollback);
492 + IgnoreRollbackError(hrRegistrationRollback, "Dependent registration actions failed");
493 }
494
495 + LogId(REPORT_STANDARD, MSG_SESSION_END, pEngineState->registration.sczRegistrationKey, LoggingResumeModeToString(resumeMode), LoggingRestartToString(restart), LoggingBoolToString(pEngineState->registration.fDisableResume), LoggingRegistrationTypeToString(defaultRegistrationType), LoggingRegistrationTypeToString(registrationType));
496 +
497 if (pEngineState->registration.fPerMachine)
498 {
479 - hr = ElevationSessionEnd(pEngineState->companionConnection.hPipe, resumeMode, restart, pEngineState->plan.dependencyRegistrationAction);
499 + hr = ElevationSessionEnd(pEngineState->companionConnection.hPipe, resumeMode, restart, pEngineState->plan.dependencyRegistrationAction, registrationType);
500 ExitOnFailure(hr, "Failed to end session in per-machine process.");
501 }
502 else
503 {
484 - hr = RegistrationSessionEnd(&pEngineState->registration, &pEngineState->variables, &pEngineState->packages, resumeMode, restart, pEngineState->plan.dependencyRegistrationAction);
504 + hr = RegistrationSessionEnd(&pEngineState->registration, &pEngineState->variables, &pEngineState->packages, resumeMode, restart, pEngineState->plan.dependencyRegistrationAction, registrationType);
505 ExitOnFailure(hr, "Failed to end session in per-user process.");
506 }
507
@@ -751,10 +771,14 @@ extern "C" void ApplyClean(
771
772 static void CalculateKeepRegistration(
773 __in BURN_ENGINE_STATE* pEngineState,
754 - __inout BOOL* pfKeepRegistration
774 + __in BOOL fLog,
775 + __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType
776 )
777 {
757 - LogId(REPORT_STANDARD, MSG_POST_APPLY_CALCULATE_REGISTRATION);
778 + if (fLog)
779 + {
780 + LogId(REPORT_STANDARD, MSG_POST_APPLY_CALCULATE_REGISTRATION);
781 + }
782
783 for (DWORD i = 0; i < pEngineState->packages.cPackages; ++i)
784 {
@@ -765,17 +789,28 @@ static void CalculateKeepRegistration(
789 MspEngineFinalizeInstallRegistrationState(pPackage);
790 }
791
768 - LogId(REPORT_STANDARD, MSG_POST_APPLY_PACKAGE, pPackage->sczId, LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->installRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->cacheRegistrationState));
792 + if (fLog)
793 + {
794 + LogId(REPORT_STANDARD, MSG_POST_APPLY_PACKAGE, pPackage->sczId, LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->installRegistrationState), LoggingPackageRegistrationStateToString(pPackage->fCanAffectRegistration, pPackage->cacheRegistrationState));
795 + }
796
797 if (!pPackage->fCanAffectRegistration)
798 {
799 continue;
800 }
801
775 - if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->installRegistrationState ||
776 - BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->cacheRegistrationState)
802 + if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->installRegistrationState)
803 + {
804 + *pRegistrationType = BOOTSTRAPPER_REGISTRATION_TYPE_FULL;
805 +
806 + if (!fLog)
807 + {
808 + break;
809 + }
810 + }
811 + else if (BURN_PACKAGE_REGISTRATION_STATE_PRESENT == pPackage->cacheRegistrationState && BOOTSTRAPPER_REGISTRATION_TYPE_NONE == *pRegistrationType)
812 {
778 - *pfKeepRegistration = TRUE;
813 + *pRegistrationType = BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS;
814 }
815 }
816 }
src/burn/engine/core.h
+2 -1
@@ -48,8 +48,9 @@ const LPCWSTR BURN_BUNDLE_UILEVEL = L"WixBundleUILevel";
48 const LPCWSTR BURN_BUNDLE_VERSION = L"WixBundleVersion";
49 const LPCWSTR BURN_REBOOT_PENDING = L"RebootPending";
50
51 -// The following constants must stay in sync with src\wix\Binder.cs
51 +// The following constants must stay in sync with src\api\wix\WixToolset.Data\Burn\BurnConstants.cs
52 const LPCWSTR BURN_BUNDLE_NAME = L"WixBundleName";
53 +const LPCWSTR BURN_BUNDLE_INPROGRESS_NAME = L"WixBundleInProgressName";
54 const LPCWSTR BURN_BUNDLE_ORIGINAL_SOURCE = L"WixBundleOriginalSource";
55 const LPCWSTR BURN_BUNDLE_ORIGINAL_SOURCE_FOLDER = L"WixBundleOriginalSourceFolder";
56 const LPCWSTR BURN_BUNDLE_LAST_USED_SOURCE = L"WixBundleLastUsedSource";
src/burn/engine/elevation.cpp
+30 -6
@@ -477,7 +477,8 @@ extern "C" HRESULT ElevationSessionBegin(
477 __in BURN_VARIABLES* pVariables,
478 __in DWORD dwRegistrationOperations,
479 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
480 - __in DWORD64 qwEstimatedSize
480 + __in DWORD64 qwEstimatedSize,
481 + __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
482 )
483 {
484 HRESULT hr = S_OK;
@@ -504,6 +505,9 @@ extern "C" HRESULT ElevationSessionBegin(
505 hr = BuffWriteNumber64(&pbData, &cbData, qwEstimatedSize);
506 ExitOnFailure(hr, "Failed to write estimated size to message buffer.");
507
508 + hr = BuffWriteNumber(&pbData, &cbData, (DWORD)registrationType);
509 + ExitOnFailure(hr, "Failed to write registration type to message buffer.");
510 +
511 hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData);
512 ExitOnFailure(hr, "Failed to write variables.");
513
@@ -527,7 +531,8 @@ extern "C" HRESULT ElevationSessionResume(
531 __in HANDLE hPipe,
532 __in_z LPCWSTR wzResumeCommandLine,
533 __in BOOL fDisableResume,
530 - __in BURN_VARIABLES* pVariables
534 + __in BURN_VARIABLES* pVariables,
535 + __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
536 )
537 {
538 HRESULT hr = S_OK;
@@ -542,6 +547,9 @@ extern "C" HRESULT ElevationSessionResume(
547 hr = BuffWriteNumber(&pbData, &cbData, fDisableResume);
548 ExitOnFailure(hr, "Failed to write resume flag.");
549
550 + hr = BuffWriteNumber(&pbData, &cbData, (DWORD)registrationType);
551 + ExitOnFailure(hr, "Failed to write registration type to message buffer.");
552 +
553 hr = VariableSerialize(pVariables, FALSE, &pbData, &cbData);
554 ExitOnFailure(hr, "Failed to write variables.");
555
@@ -565,7 +573,8 @@ extern "C" HRESULT ElevationSessionEnd(
573 __in HANDLE hPipe,
574 __in BURN_RESUME_MODE resumeMode,
575 __in BOOTSTRAPPER_APPLY_RESTART restart,
568 - __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction
576 + __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
577 + __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
578 )
579 {
580 HRESULT hr = S_OK;
@@ -583,6 +592,9 @@ extern "C" HRESULT ElevationSessionEnd(
592 hr = BuffWriteNumber(&pbData, &cbData, (DWORD)dependencyRegistrationAction);
593 ExitOnFailure(hr, "Failed to write dependency registration action to message buffer.");
594
595 + hr = BuffWriteNumber(&pbData, &cbData, (DWORD)registrationType);
596 + ExitOnFailure(hr, "Failed to write registration type to message buffer.");
597 +
598 // send message
599 hr = PipeSendMessage(hPipe, BURN_ELEVATION_MESSAGE_TYPE_SESSION_END, pbData, cbData, NULL, NULL, &dwResult);
600 ExitOnFailure(hr, "Failed to send message to per-machine process.");
@@ -2080,6 +2092,7 @@ static HRESULT OnSessionBegin(
2092 DWORD dwRegistrationOperations = 0;
2093 DWORD dwDependencyRegistrationAction = 0;
2094 DWORD64 qwEstimatedSize = 0;
2095 + DWORD dwRegistrationType = 0;
2096
2097 // Deserialize message data.
2098 hr = BuffReadString(pbData, cbData, &iData, &sczEngineWorkingPath);
@@ -2100,11 +2113,14 @@ static HRESULT OnSessionBegin(
2113 hr = BuffReadNumber64(pbData, cbData, &iData, &qwEstimatedSize);
2114 ExitOnFailure(hr, "Failed to read estimated size.");
2115
2116 + hr = BuffReadNumber(pbData, cbData, &iData, &dwRegistrationType);
2117 + ExitOnFailure(hr, "Failed to read dependency registration action.");
2118 +
2119 hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData);
2120 ExitOnFailure(hr, "Failed to read variables.");
2121
2122 // Begin session in per-machine process.
2107 - hr = RegistrationSessionBegin(sczEngineWorkingPath, pRegistration, pVariables, dwRegistrationOperations, (BURN_DEPENDENCY_REGISTRATION_ACTION)dwDependencyRegistrationAction, qwEstimatedSize);
2123 + hr = RegistrationSessionBegin(sczEngineWorkingPath, pRegistration, pVariables, dwRegistrationOperations, (BURN_DEPENDENCY_REGISTRATION_ACTION)dwDependencyRegistrationAction, qwEstimatedSize, (BOOTSTRAPPER_REGISTRATION_TYPE)dwRegistrationType);
2124 ExitOnFailure(hr, "Failed to begin registration session.");
2125
2126 LExit:
@@ -2122,6 +2138,7 @@ static HRESULT OnSessionResume(
2138 {
2139 HRESULT hr = S_OK;
2140 SIZE_T iData = 0;
2141 + DWORD dwRegistrationType = 0;
2142
2143 // Deserialize message data.
2144 hr = BuffReadString(pbData, cbData, &iData, &pRegistration->sczResumeCommandLine);
@@ -2130,11 +2147,14 @@ static HRESULT OnSessionResume(
2147 hr = BuffReadNumber(pbData, cbData, &iData, (DWORD*)&pRegistration->fDisableResume);
2148 ExitOnFailure(hr, "Failed to read resume flag.");
2149
2150 + hr = BuffReadNumber(pbData, cbData, &iData, &dwRegistrationType);
2151 + ExitOnFailure(hr, "Failed to read dependency registration action.");
2152 +
2153 hr = VariableDeserialize(pVariables, FALSE, pbData, cbData, &iData);
2154 ExitOnFailure(hr, "Failed to read variables.");
2155
2156 // resume session in per-machine process
2137 - hr = RegistrationSessionResume(pRegistration, pVariables);
2157 + hr = RegistrationSessionResume(pRegistration, pVariables, (BOOTSTRAPPER_REGISTRATION_TYPE)dwRegistrationType);
2158 ExitOnFailure(hr, "Failed to resume registration session.");
2159
2160 LExit:
@@ -2154,6 +2174,7 @@ static HRESULT OnSessionEnd(
2174 DWORD dwResumeMode = 0;
2175 DWORD dwRestart = 0;
2176 DWORD dwDependencyRegistrationAction = 0;
2177 + DWORD dwRegistrationType = 0;
2178
2179 // Deserialize message data.
2180 hr = BuffReadNumber(pbData, cbData, &iData, &dwResumeMode);
@@ -2165,8 +2186,11 @@ static HRESULT OnSessionEnd(
2186 hr = BuffReadNumber(pbData, cbData, &iData, &dwDependencyRegistrationAction);
2187 ExitOnFailure(hr, "Failed to read dependency registration action.");
2188
2189 + hr = BuffReadNumber(pbData, cbData, &iData, &dwRegistrationType);
2190 + ExitOnFailure(hr, "Failed to read dependency registration action.");
2191 +
2192 // suspend session in per-machine process
2169 - hr = RegistrationSessionEnd(pRegistration, pVariables, pPackages, (BURN_RESUME_MODE)dwResumeMode, (BOOTSTRAPPER_APPLY_RESTART)dwRestart, (BURN_DEPENDENCY_REGISTRATION_ACTION)dwDependencyRegistrationAction);
2193 + hr = RegistrationSessionEnd(pRegistration, pVariables, pPackages, (BURN_RESUME_MODE)dwResumeMode, (BOOTSTRAPPER_APPLY_RESTART)dwRestart, (BURN_DEPENDENCY_REGISTRATION_ACTION)dwDependencyRegistrationAction, (BOOTSTRAPPER_REGISTRATION_TYPE)dwRegistrationType);
2194 ExitOnFailure(hr, "Failed to suspend registration session.");
2195
2196 LExit:
src/burn/engine/elevation.h
+6 -3
@@ -31,19 +31,22 @@ HRESULT ElevationSessionBegin(
31 __in BURN_VARIABLES* pVariables,
32 __in DWORD dwRegistrationOperations,
33 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
34 - __in DWORD64 qwEstimatedSize
34 + __in DWORD64 qwEstimatedSize,
35 + __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
36 );
37 HRESULT ElevationSessionResume(
38 __in HANDLE hPipe,
39 __in_z LPCWSTR wzResumeCommandLine,
40 __in BOOL fDisableResume,
40 - __in BURN_VARIABLES* pVariables
41 + __in BURN_VARIABLES* pVariables,
42 + __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
43 );
44 HRESULT ElevationSessionEnd(
45 __in HANDLE hPipe,
46 __in BURN_RESUME_MODE resumeMode,
47 __in BOOTSTRAPPER_APPLY_RESTART restart,
46 - __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction
48 + __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
49 + __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
50 );
51 HRESULT ElevationSaveState(
52 __in HANDLE hPipe,
src/burn/engine/engine.mc
+1 -1
@@ -889,7 +889,7 @@ MessageId=372
889 Severity=Success
890 SymbolicName=MSG_SESSION_END
891 Language=English
892 -Session end, registration key: %1!ls!, resume: %2!hs!, restart: %3!hs!, disable resume: %4!hs!
892 +Session end, registration key: %1!ls!, resume: %2!hs!, restart: %3!hs!, disable resume: %4!hs!, default registration: %5!hs!, ba requested registration: %6!hs!
893 .
894
895 MessageId=373
src/burn/engine/logging.cpp
+17
@@ -561,6 +561,23 @@ extern "C" LPCSTR LoggingPerMachineToString(
561 return "PerUser";
562 }
563
564 +extern "C" LPCSTR LoggingRegistrationTypeToString(
565 + __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
566 + )
567 +{
568 + switch (registrationType)
569 + {
570 + case BOOTSTRAPPER_REGISTRATION_TYPE_NONE:
571 + return "None";
572 + case BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS:
573 + return "InProgress";
574 + case BOOTSTRAPPER_REGISTRATION_TYPE_FULL:
575 + return "Full";
576 + default:
577 + return "Invalid";
578 + }
579 +}
580 +
581 extern "C" LPCSTR LoggingRestartToString(
582 __in BOOTSTRAPPER_APPLY_RESTART restart
583 )
src/burn/engine/logging.h
+4
@@ -123,6 +123,10 @@ LPCSTR LoggingPerMachineToString(
123 __in BOOL fPerMachine
124 );
125
126 +LPCSTR LoggingRegistrationTypeToString(
127 + __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
128 + );
129 +
130 LPCSTR LoggingRestartToString(
131 __in BOOTSTRAPPER_APPLY_RESTART restart
132 );
src/burn/engine/registration.cpp
+105 -35
@@ -46,12 +46,23 @@ static HRESULT SetPaths(
46 static HRESULT GetBundleManufacturer(
47 __in BURN_REGISTRATION* pRegistration,
48 __in BURN_VARIABLES* pVariables,
49 - __out LPWSTR* psczBundleManufacturer
49 + __out_z LPWSTR* psczBundleManufacturer
50 + );
51 +static HRESULT GetBundleInProgressName(
52 + __in BURN_REGISTRATION* pRegistration,
53 + __in BURN_VARIABLES* pVariables,
54 + __out_z LPWSTR* psczBundleName
55 );
56 static HRESULT GetBundleName(
57 __in BURN_REGISTRATION* pRegistration,
58 __in BURN_VARIABLES* pVariables,
54 - __out LPWSTR* psczBundleName
59 + __out_z LPWSTR* psczBundleName
60 + );
61 +static HRESULT EnsureRegistrationVariable(
62 + __in BURN_VARIABLES* pVariables,
63 + __in_z LPCWSTR wzVariable,
64 + __in_z LPCWSTR wzDefaultValue,
65 + __out_z LPWSTR* psczValue
66 );
67 static HRESULT UpdateResumeMode(
68 __in BURN_REGISTRATION* pRegistration,
@@ -91,7 +102,8 @@ static HRESULT RegWriteStringVariable(
102 static HRESULT UpdateBundleNameRegistration(
103 __in BURN_REGISTRATION* pRegistration,
104 __in BURN_VARIABLES* pVariables,
94 - __in HKEY hkRegistration
105 + __in HKEY hkRegistration,
106 + __in BOOL fInProgressRegistration
107 );
108 static BOOL IsWuRebootPending();
109 static BOOL IsBundleRebootPending(
@@ -176,6 +188,13 @@ extern "C" HRESULT RegistrationParseFromXml(
188 ExitOnFailure(hr, "Failed to get @DisplayName.");
189 }
190
191 + // @InProgressDisplayName
192 + hr = XmlGetAttributeEx(pixnArpNode, L"InProgressDisplayName", &pRegistration->sczInProgressDisplayName);
193 + if (E_NOTFOUND != hr)
194 + {
195 + ExitOnFailure(hr, "Failed to get @InProgressDisplayName.");
196 + }
197 +
198 // @DisplayVersion
199 hr = XmlGetAttributeEx(pixnArpNode, L"DisplayVersion", &pRegistration->sczDisplayVersion);
200 if (E_NOTFOUND != hr)
@@ -372,6 +391,7 @@ extern "C" void RegistrationUninitialize(
391 ReleaseStr(pRegistration->sczStateFile);
392
393 ReleaseStr(pRegistration->sczDisplayName);
394 + ReleaseStr(pRegistration->sczInProgressDisplayName);
395 ReleaseStr(pRegistration->sczDisplayVersion);
396 ReleaseStr(pRegistration->sczPublisher);
397 ReleaseStr(pRegistration->sczHelpLink);
@@ -421,8 +441,7 @@ extern "C" HRESULT RegistrationSetVariables(
441 )
442 {
443 HRESULT hr = S_OK;
424 - LPWSTR sczBundleManufacturer = NULL;
425 - LPWSTR sczBundleName = NULL;
444 + LPWSTR scz = NULL;
445
446 if (pRegistration->fInstalled)
447 {
@@ -431,10 +450,13 @@ extern "C" HRESULT RegistrationSetVariables(
450 }
451
452 // Ensure the registration bundle name is updated.
434 - hr = GetBundleName(pRegistration, pVariables, &sczBundleName);
453 + hr = GetBundleInProgressName(pRegistration, pVariables, &scz);
454 ExitOnFailure(hr, "Failed to initialize bundle name.");
455
437 - hr = GetBundleManufacturer(pRegistration, pVariables, &sczBundleName);
456 + hr = GetBundleName(pRegistration, pVariables, &scz);
457 + ExitOnFailure(hr, "Failed to initialize bundle name.");
458 +
459 + hr = GetBundleManufacturer(pRegistration, pVariables, &scz);
460 ExitOnFailure(hr, "Failed to initialize bundle manufacturer.");
461
462 if (pRegistration->sczActiveParent && *pRegistration->sczActiveParent)
@@ -456,8 +478,7 @@ extern "C" HRESULT RegistrationSetVariables(
478 ExitOnFailure(hr, "Failed to overwrite the bundle reboot-pending built-in variable.");
479
480 LExit:
459 - ReleaseStr(sczBundleManufacturer);
460 - ReleaseStr(sczBundleName);
481 + ReleaseStr(scz);
482
483 return hr;
484 }
@@ -595,7 +616,8 @@ extern "C" HRESULT RegistrationSessionBegin(
616 __in BURN_VARIABLES* pVariables,
617 __in DWORD dwRegistrationOptions,
618 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
598 - __in DWORD64 qwEstimatedSize
619 + __in DWORD64 qwEstimatedSize,
620 + __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
621 )
622 {
623 HRESULT hr = S_OK;
@@ -603,6 +625,8 @@ extern "C" HRESULT RegistrationSessionBegin(
625 HKEY hkRegistration = NULL;
626 LPWSTR sczPublisher = NULL;
627
628 + AssertSz(BOOTSTRAPPER_REGISTRATION_TYPE_NONE != registrationType, "Registration type can't be NONE");
629 +
630 LogId(REPORT_VERBOSE, MSG_SESSION_BEGIN, pRegistration->sczRegistrationKey, dwRegistrationOptions, LoggingBoolToString(pRegistration->fDisableResume));
631
632 // Cache bundle executable.
@@ -668,7 +692,7 @@ extern "C" HRESULT RegistrationSessionBegin(
692 ExitOnFailure(hr, "Failed to write %ls value.", REGISTRY_BUNDLE_DISPLAY_ICON);
693
694 // update display name
671 - hr = UpdateBundleNameRegistration(pRegistration, pVariables, hkRegistration);
695 + hr = UpdateBundleNameRegistration(pRegistration, pVariables, hkRegistration, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS == registrationType);
696 ExitOnFailure(hr, "Failed to update name and publisher.");
697
698 // DisplayVersion: provided by UI
@@ -841,12 +865,15 @@ LExit:
865 *******************************************************************/
866 extern "C" HRESULT RegistrationSessionResume(
867 __in BURN_REGISTRATION* pRegistration,
844 - __in BURN_VARIABLES* pVariables
868 + __in BURN_VARIABLES* pVariables,
869 + __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
870 )
871 {
872 HRESULT hr = S_OK;
873 HKEY hkRegistration = NULL;
874
875 + AssertSz(BOOTSTRAPPER_REGISTRATION_TYPE_NONE != registrationType, "Registration type can't be NONE");
876 +
877 // open registration key
878 hr = RegOpen(pRegistration->hkRoot, pRegistration->sczRegistrationKey, KEY_WRITE, &hkRegistration);
879 ExitOnFailure(hr, "Failed to open registration key.");
@@ -856,7 +883,7 @@ extern "C" HRESULT RegistrationSessionResume(
883 ExitOnFailure(hr, "Failed to update resume mode.");
884
885 // update display name
859 - hr = UpdateBundleNameRegistration(pRegistration, pVariables, hkRegistration);
886 + hr = UpdateBundleNameRegistration(pRegistration, pVariables, hkRegistration, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS == registrationType);
887 ExitOnFailure(hr, "Failed to update name and publisher.");
888
889 LExit:
@@ -876,7 +903,8 @@ extern "C" HRESULT RegistrationSessionEnd(
903 __in BURN_PACKAGES* pPackages,
904 __in BURN_RESUME_MODE resumeMode,
905 __in BOOTSTRAPPER_APPLY_RESTART restart,
879 - __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction
906 + __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
907 + __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
908 )
909 {
910 HRESULT hr = S_OK;
@@ -884,8 +912,6 @@ extern "C" HRESULT RegistrationSessionEnd(
912 HKEY hkRebootRequired = NULL;
913 HKEY hkRegistration = NULL;
914
887 - LogId(REPORT_STANDARD, MSG_SESSION_END, pRegistration->sczRegistrationKey, LoggingResumeModeToString(resumeMode), LoggingRestartToString(restart), LoggingBoolToString(pRegistration->fDisableResume));
888 -
915 // If a restart is required for any reason, write a volatile registry key to track of
916 // of that fact until the reboot has taken place.
917 if (BOOTSTRAPPER_APPLY_RESTART_NONE != restart)
@@ -910,6 +936,8 @@ extern "C" HRESULT RegistrationSessionEnd(
936 // If no resume mode, then remove the bundle registration.
937 if (BURN_RESUME_MODE_NONE == resumeMode)
938 {
939 + AssertSz(BOOTSTRAPPER_REGISTRATION_TYPE_NONE == registrationType, "Registration type must be NONE if resume mode is NONE");
940 +
941 // If we just registered the bundle dependency but something went wrong and caused us to not
942 // keep the bundle registration (like rollback) or we are supposed to unregister the bundle
943 // dependency when unregistering the bundle, do so.
@@ -939,9 +967,15 @@ extern "C" HRESULT RegistrationSessionEnd(
967 }
968 else // the mode needs to be updated so open the registration key.
969 {
970 + AssertSz(BOOTSTRAPPER_REGISTRATION_TYPE_NONE != registrationType, "Registration type must not be NONE if resume mode is not NONE");
971 +
972 // Open registration key.
973 hr = RegOpen(pRegistration->hkRoot, pRegistration->sczRegistrationKey, KEY_WRITE, &hkRegistration);
974 ExitOnFailure(hr, "Failed to open registration key.");
975 +
976 + // update display name
977 + hr = UpdateBundleNameRegistration(pRegistration, pVariables, hkRegistration, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS == registrationType);
978 + ExitOnFailure(hr, "Failed to update name and publisher.");
979 }
980
981 // Update resume mode.
@@ -1133,44 +1167,69 @@ LExit:
1167 static HRESULT GetBundleManufacturer(
1168 __in BURN_REGISTRATION* pRegistration,
1169 __in BURN_VARIABLES* pVariables,
1136 - __out LPWSTR* psczBundleManufacturer
1170 + __out_z LPWSTR* psczBundleManufacturer
1171 )
1172 {
1173 HRESULT hr = S_OK;
1174 LPCWSTR wzPublisher = pRegistration->sczPublisher ? pRegistration->sczPublisher : L"";
1175
1142 - hr = VariableGetString(pVariables, BURN_BUNDLE_MANUFACTURER, psczBundleManufacturer);
1143 - if (E_NOTFOUND == hr)
1144 - {
1145 - hr = VariableSetString(pVariables, BURN_BUNDLE_MANUFACTURER, wzPublisher, FALSE, FALSE);
1146 - ExitOnFailure(hr, "Failed to set bundle manufacturer.");
1147 -
1148 - hr = StrAllocString(psczBundleManufacturer, wzPublisher, 0);
1149 - }
1176 + hr = EnsureRegistrationVariable(pVariables, BURN_BUNDLE_MANUFACTURER, wzPublisher, psczBundleManufacturer);
1177 ExitOnFailure(hr, "Failed to get bundle manufacturer.");
1178
1179 LExit:
1180 return hr;
1181 }
1182
1183 +static HRESULT GetBundleInProgressName(
1184 + __in BURN_REGISTRATION* pRegistration,
1185 + __in BURN_VARIABLES* pVariables,
1186 + __out_z LPWSTR* psczInProgressBundleName
1187 + )
1188 +{
1189 + HRESULT hr = S_OK;
1190 + LPCWSTR wzInProgressDisplayName = pRegistration->sczInProgressDisplayName ? pRegistration->sczInProgressDisplayName : L"";
1191 +
1192 + hr = EnsureRegistrationVariable(pVariables, BURN_BUNDLE_INPROGRESS_NAME, wzInProgressDisplayName, psczInProgressBundleName);
1193 + ExitOnFailure(hr, "Failed to ensure in-progress bundle name.");
1194 +
1195 +LExit:
1196 + return hr;
1197 +}
1198 +
1199 static HRESULT GetBundleName(
1200 __in BURN_REGISTRATION* pRegistration,
1201 __in BURN_VARIABLES* pVariables,
1159 - __out LPWSTR* psczBundleName
1202 + __out_z LPWSTR* psczBundleName
1203 )
1204 {
1205 HRESULT hr = S_OK;
1206 LPCWSTR wzDisplayName = pRegistration->sczDisplayName ? pRegistration->sczDisplayName : L"";
1207
1165 - hr = VariableGetString(pVariables, BURN_BUNDLE_NAME, psczBundleName);
1208 + hr = EnsureRegistrationVariable(pVariables, BURN_BUNDLE_NAME, wzDisplayName, psczBundleName);
1209 + ExitOnFailure(hr, "Failed to ensure bundle name.");
1210 +
1211 +LExit:
1212 + return hr;
1213 +}
1214 +
1215 +static HRESULT EnsureRegistrationVariable(
1216 + __in BURN_VARIABLES* pVariables,
1217 + __in_z LPCWSTR wzVariable,
1218 + __in_z LPCWSTR wzDefaultValue,
1219 + __out_z LPWSTR* psczValue
1220 + )
1221 +{
1222 + HRESULT hr = S_OK;
1223 +
1224 + hr = VariableGetString(pVariables, wzVariable, psczValue);
1225 if (E_NOTFOUND == hr)
1226 {
1168 - hr = VariableSetString(pVariables, BURN_BUNDLE_NAME, wzDisplayName, FALSE, FALSE);
1169 - ExitOnFailure(hr, "Failed to set bundle name.");
1227 + hr = VariableSetString(pVariables, wzVariable, wzDefaultValue, FALSE, FALSE);
1228 + ExitOnFailure(hr, "Failed to set registration variable.");
1229
1171 - hr = StrAllocString(psczBundleName, wzDisplayName, 0);
1230 + hr = StrAllocString(psczValue, wzDefaultValue, 0);
1231 }
1173 - ExitOnFailure(hr, "Failed to get bundle name.");
1232 + ExitOnFailure(hr, "Failed to get registration variable.");
1233
1234 LExit:
1235 return hr;
@@ -1584,15 +1643,26 @@ LExit:
1643 static HRESULT UpdateBundleNameRegistration(
1644 __in BURN_REGISTRATION* pRegistration,
1645 __in BURN_VARIABLES* pVariables,
1587 - __in HKEY hkRegistration
1646 + __in HKEY hkRegistration,
1647 + __in BOOL fInProgressRegistration
1648 )
1649 {
1650 HRESULT hr = S_OK;
1651 LPWSTR sczDisplayName = NULL;
1652
1593 - // DisplayName: provided by UI
1594 - hr = GetBundleName(pRegistration, pVariables, &sczDisplayName);
1595 - hr = RegWriteString(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_DISPLAY_NAME, SUCCEEDED(hr) ? sczDisplayName : pRegistration->sczDisplayName);
1653 + if (fInProgressRegistration)
1654 + {
1655 + hr = GetBundleInProgressName(pRegistration, pVariables, &sczDisplayName);
1656 + ExitOnFailure(hr, "Failed to get bundle in-progress name.");
1657 + }
1658 +
1659 + if (!sczDisplayName || !*sczDisplayName)
1660 + {
1661 + hr = GetBundleName(pRegistration, pVariables, &sczDisplayName);
1662 + ExitOnFailure(hr, "Failed to get bundle name.");
1663 + }
1664 +
1665 + hr = RegWriteString(hkRegistration, BURN_REGISTRATION_REGISTRY_BUNDLE_DISPLAY_NAME, sczDisplayName);
1666 ExitOnFailure(hr, "Failed to write %ls value.", BURN_REGISTRATION_REGISTRY_BUNDLE_DISPLAY_NAME);
1667
1668 LExit:
src/burn/engine/registration.h
+7 -3
@@ -123,6 +123,7 @@ typedef struct _BURN_REGISTRATION
123
124 // ARP registration
125 LPWSTR sczDisplayName;
126 + LPWSTR sczInProgressDisplayName;
127 LPWSTR sczDisplayVersion;
128 LPWSTR sczPublisher;
129 LPWSTR sczHelpLink;
@@ -190,11 +191,13 @@ HRESULT RegistrationSessionBegin(
191 __in BURN_VARIABLES* pVariables,
192 __in DWORD dwRegistrationOptions,
193 __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
193 - __in DWORD64 qwEstimatedSize
194 + __in DWORD64 qwEstimatedSize,
195 + __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
196 );
197 HRESULT RegistrationSessionResume(
198 __in BURN_REGISTRATION* pRegistration,
197 - __in BURN_VARIABLES* pVariables
199 + __in BURN_VARIABLES* pVariables,
200 + __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
201 );
202 HRESULT RegistrationSessionEnd(
203 __in BURN_REGISTRATION* pRegistration,
@@ -202,7 +205,8 @@ HRESULT RegistrationSessionEnd(
205 __in BURN_PACKAGES* pPackages,
206 __in BURN_RESUME_MODE resumeMode,
207 __in BOOTSTRAPPER_APPLY_RESTART restart,
205 - __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction
208 + __in BURN_DEPENDENCY_REGISTRATION_ACTION dependencyRegistrationAction,
209 + __in BOOTSTRAPPER_REGISTRATION_TYPE registrationType
210 );
211 HRESULT RegistrationSaveState(
212 __in BURN_REGISTRATION* pRegistration,
src/burn/engine/userexperience.cpp
+13 -5
@@ -2119,7 +2119,8 @@ EXTERN_C BAAPI UserExperienceOnProgress(
2119 }
2120
2121 EXTERN_C BAAPI UserExperienceOnRegisterBegin(
2122 - __in BURN_USER_EXPERIENCE* pUserExperience
2122 + __in BURN_USER_EXPERIENCE* pUserExperience,
2123 + __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType
2124 )
2125 {
2126 HRESULT hr = S_OK;
@@ -2127,8 +2128,10 @@ EXTERN_C BAAPI UserExperienceOnRegisterBegin(
2128 BA_ONREGISTERBEGIN_RESULTS results = { };
2129
2130 args.cbSize = sizeof(args);
2131 + args.recommendedRegistrationType = *pRegistrationType;
2132
2133 results.cbSize = sizeof(results);
2134 + results.registrationType = *pRegistrationType;
2135
2136 hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONREGISTERBEGIN, &args, &results);
2137 ExitOnFailure(hr, "BA OnRegisterBegin failed.");
@@ -2137,6 +2140,10 @@ EXTERN_C BAAPI UserExperienceOnRegisterBegin(
2140 {
2141 hr = HRESULT_FROM_WIN32(ERROR_INSTALL_USEREXIT);
2142 }
2143 + else if (BOOTSTRAPPER_REGISTRATION_TYPE_NONE < results.registrationType && BOOTSTRAPPER_REGISTRATION_TYPE_FULL >= results.registrationType)
2144 + {
2145 + *pRegistrationType = results.registrationType;
2146 + }
2147
2148 LExit:
2149 return hr;
@@ -2316,7 +2323,7 @@ LExit:
2323
2324 EXTERN_C BAAPI UserExperienceOnUnregisterBegin(
2325 __in BURN_USER_EXPERIENCE* pUserExperience,
2319 - __inout BOOL* pfKeepRegistration
2326 + __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType
2327 )
2328 {
2329 HRESULT hr = S_OK;
@@ -2324,16 +2331,17 @@ EXTERN_C BAAPI UserExperienceOnUnregisterBegin(
2331 BA_ONUNREGISTERBEGIN_RESULTS results = { };
2332
2333 args.cbSize = sizeof(args);
2327 - args.fKeepRegistration = *pfKeepRegistration;
2334 + args.recommendedRegistrationType = *pRegistrationType;
2335
2336 results.cbSize = sizeof(results);
2337 + results.registrationType = *pRegistrationType;
2338
2339 hr = SendBAMessage(pUserExperience, BOOTSTRAPPER_APPLICATION_MESSAGE_ONUNREGISTERBEGIN, &args, &results);
2340 ExitOnFailure(hr, "BA OnUnregisterBegin failed.");
2341
2334 - if (!args.fKeepRegistration && results.fForceKeepRegistration)
2342 + if (BOOTSTRAPPER_REGISTRATION_TYPE_NONE < results.registrationType && BOOTSTRAPPER_REGISTRATION_TYPE_FULL >= results.registrationType)
2343 {
2336 - *pfKeepRegistration = TRUE;
2344 + *pRegistrationType = results.registrationType;
2345 }
2346
2347 LExit:
src/burn/engine/userexperience.h
+3 -2
@@ -486,7 +486,8 @@ BAAPI UserExperienceOnProgress(
486 __in DWORD dwOverallPercentage
487 );
488 BAAPI UserExperienceOnRegisterBegin(
489 - __in BURN_USER_EXPERIENCE* pUserExperience
489 + __in BURN_USER_EXPERIENCE* pUserExperience,
490 + __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType
491 );
492 BAAPI UserExperienceOnRegisterComplete(
493 __in BURN_USER_EXPERIENCE* pUserExperience,
@@ -522,7 +523,7 @@ BAAPI UserExperienceOnSystemShutdown(
523 );
524 BAAPI UserExperienceOnUnregisterBegin(
525 __in BURN_USER_EXPERIENCE* pUserExperience,
525 - __inout BOOL* pfKeepRegistration
526 + __inout BOOTSTRAPPER_REGISTRATION_TYPE* pRegistrationType
527 );
528 BAAPI UserExperienceOnUnregisterComplete(
529 __in BURN_USER_EXPERIENCE* pUserExperience,
src/burn/test/BurnUnitTest/RegistrationTest.cpp
+20 -18
@@ -112,7 +112,7 @@ namespace Bootstrapper
112 TestThrowOnFailure(hr, L"Failed to get current process path.");
113
114 // write registration
115 - hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE | BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0);
115 + hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_CACHE_BUNDLE | BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
116 TestThrowOnFailure(hr, L"Failed to register bundle.");
117
118 // verify that registration was created
@@ -123,7 +123,7 @@ namespace Bootstrapper
123 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)(Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr)));
124
125 // end session
126 - hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER);
126 + hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
127 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
128
129 // verify that registration was removed
@@ -178,7 +178,7 @@ namespace Bootstrapper
178 L" <Payload Id='ux.dll' FilePath='ux.dll' Packaging='embedded' SourcePath='ux.dll' Hash='000000000000' />"
179 L" </UX>"
180 L" <Registration Id='{D54F896D-1952-43e6-9C67-B5652240618C}' UpgradeCode='{D54F896D-1952-43e6-9C67-B5652240618C}' Tag='foo' ProviderKey='foo' Version='1.0.0.0' ExecutableName='setup.exe' PerMachine='no'>"
181 - L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='Product1' DisplayVersion='1.0.0.0' />"
181 + L" <Arp Register='yes' Publisher='WiX Toolset' DisplayName='Product1' InProgressDisplayName='Product1 Installation' DisplayVersion='1.0.0.0' />"
182 L" </Registration>"
183 L"</Bundle>";
184
@@ -205,15 +205,16 @@ namespace Bootstrapper
205 //
206
207 // write registration
208 - hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0);
208 + hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
209 TestThrowOnFailure(hr, L"Failed to register bundle.");
210
211 // verify that registration was created
212 + Assert::Equal<String^>(gcnew String(L"Product1 Installation"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayName"), nullptr));
213 Assert::Equal(Int32(BURN_RESUME_MODE_ACTIVE), (Int32)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"Resume"), nullptr));
214 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr));
215
216 // complete registration
216 - hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER);
217 + hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
218 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
219
220 // verify that registration was updated
@@ -226,7 +227,7 @@ namespace Bootstrapper
227 //
228
229 // write registration
229 - hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, 0);
230 + hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
231 TestThrowOnFailure(hr, L"Failed to register bundle.");
232
233 // verify that registration was updated
@@ -235,7 +236,7 @@ namespace Bootstrapper
236 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr));
237
238 // delete registration
238 - hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER);
239 + hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
240 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
241
242 // verify that registration was removed
@@ -316,7 +317,7 @@ namespace Bootstrapper
317 //
318
319 // write registration
319 - hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0);
320 + hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
321 TestThrowOnFailure(hr, L"Failed to register bundle.");
322
323 // verify that registration was created
@@ -324,10 +325,11 @@ namespace Bootstrapper
325 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr));
326
327 // complete registration
327 - hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER);
328 + hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_REQUIRED, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL);
329 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
330
331 // verify that registration variables were updated
332 + Assert::Equal<String^>(gcnew String(L"Product1"), (String^)Registry::GetValue(gcnew String(TEST_UNINSTALL_KEY), gcnew String(L"DisplayName"), nullptr));
333 registration.fInstalled = TRUE;
334
335 hr = RegistrationSetVariables(&registration, &variables);
@@ -344,7 +346,7 @@ namespace Bootstrapper
346 //
347
348 // delete registration
347 - hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER);
349 + hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
350 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
351
352 // verify that registration was removed
@@ -427,7 +429,7 @@ namespace Bootstrapper
429 //
430
431 // write registration
430 - hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0);
432 + hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
433 TestThrowOnFailure(hr, L"Failed to register bundle.");
434
435 // verify that registration was created
@@ -435,7 +437,7 @@ namespace Bootstrapper
437 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr));
438
439 // finish registration
438 - hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER);
440 + hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_ARP, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_FULL);
441 TestThrowOnFailure(hr, L"Failed to register bundle.");
442
443 // verify that registration was updated
@@ -460,7 +462,7 @@ namespace Bootstrapper
462 //
463
464 // write registration
463 - hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, 0);
465 + hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
466 TestThrowOnFailure(hr, L"Failed to register bundle.");
467
468 // verify that registration was updated
@@ -468,7 +470,7 @@ namespace Bootstrapper
470 Assert::Equal<String^>(String::Concat(L"\"", Path::Combine(cacheDirectory, gcnew String(L"setup.exe")), L"\" /burn.runonce"), (String^)Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr));
471
472 // delete registration
471 - hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER);
473 + hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
474 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
475
476 // verify that registration was removed
@@ -560,7 +562,7 @@ namespace Bootstrapper
562 Assert::Equal((int)BOOTSTRAPPER_RESUME_TYPE_NONE, (int)resumeType);
563
564 // begin session
563 - hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0);
565 + hr = RegistrationSessionBegin(sczCurrentProcess, &registration, &variables, BURN_REGISTRATION_ACTION_OPERATIONS_WRITE_REGISTRATION, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, 0, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
566 TestThrowOnFailure(hr, L"Failed to register bundle.");
567
568 hr = RegistrationSaveState(&registration, rgbData, sizeof(rgbData));
@@ -573,7 +575,7 @@ namespace Bootstrapper
575 Assert::Equal((int)BOOTSTRAPPER_RESUME_TYPE_INTERRUPTED, (int)resumeType);
576
577 // suspend session
576 - hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_SUSPEND, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER);
578 + hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_SUSPEND, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_REGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
579 TestThrowOnFailure(hr, L"Failed to suspend session.");
580
581 // verify that run key was removed
@@ -593,14 +595,14 @@ namespace Bootstrapper
595 Assert::True(0 == memcmp(pbBuffer, rgbData, sizeof(rgbData)));
596
597 // write active resume mode
596 - hr = RegistrationSessionResume(&registration, &variables);
598 + hr = RegistrationSessionResume(&registration, &variables, BOOTSTRAPPER_REGISTRATION_TYPE_INPROGRESS);
599 TestThrowOnFailure(hr, L"Failed to write active resume mode.");
600
601 // verify that run key was put back
602 Assert::NotEqual((Object^)nullptr, Registry::GetValue(gcnew String(TEST_RUN_KEY), gcnew String(L"{D54F896D-1952-43e6-9C67-B5652240618C}"), nullptr));
603
604 // end session
603 - hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER);
605 + hr = RegistrationSessionEnd(&registration, &variables, &packages, BURN_RESUME_MODE_NONE, BOOTSTRAPPER_APPLY_RESTART_NONE, BURN_DEPENDENCY_REGISTRATION_ACTION_UNREGISTER, BOOTSTRAPPER_REGISTRATION_TYPE_NONE);
606 TestThrowOnFailure(hr, L"Failed to unregister bundle.");
607
608 // read resume type after session
src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
+5
@@ -210,6 +210,11 @@ namespace WixToolset.Core.Burn.Bundles
210 writer.WriteAttributeString("DisplayName", this.BundleSymbol.Name);
211 writer.WriteAttributeString("DisplayVersion", this.BundleSymbol.Version);
212
213 + if (!String.IsNullOrEmpty(this.BundleSymbol.InProgressName))
214 + {
215 + writer.WriteAttributeString("InProgressDisplayName", this.BundleSymbol.InProgressName);
216 + }
217 +
218 if (!String.IsNullOrEmpty(this.BundleSymbol.Manufacturer))
219 {
220 writer.WriteAttributeString("Publisher", this.BundleSymbol.Manufacturer);
src/wix/WixToolset.Core/Compiler_Bundle.cs
+17 -7
@@ -122,6 +122,7 @@ namespace WixToolset.Core
122 WixBundleAttributes attributes = 0;
123 string helpTelephone = null;
124 string helpUrl = null;
125 + string inProgressName = null;
126 string manufacturer = null;
127 string name = null;
128 string tag = null;
@@ -190,6 +191,9 @@ namespace WixToolset.Core
191 case "IconSourceFile":
192 iconSourceFile = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
193 break;
194 + case "InProgressName":
195 + inProgressName = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
196 + break;
197 case "Name":
198 name = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
199 break;
@@ -247,6 +251,12 @@ namespace WixToolset.Core
251 }
252 }
253
254 + if (String.IsNullOrEmpty(name) && !String.IsNullOrEmpty(inProgressName))
255 + {
256 + name = inProgressName;
257 + inProgressName = null;
258 + }
259 +
260 if (String.IsNullOrEmpty(name))
261 {
262 logVariablePrefixAndExtension = String.Concat("WixBundleLog:Setup:log");
@@ -280,7 +290,6 @@ namespace WixToolset.Core
290 }
291 }
292
283 - var baSeen = false;
293 var chainSeen = false;
294 var logSeen = false;
295
@@ -294,13 +303,7 @@ namespace WixToolset.Core
303 this.ParseApprovedExeForElevation(child);
304 break;
305 case "BootstrapperApplication":
297 - if (baSeen)
298 - {
299 - var childSourceLineNumbers = Preprocessor.GetSourceLineNumbers(child);
300 - this.Core.Write(ErrorMessages.TooManyChildren(childSourceLineNumbers, node.Name.LocalName, "BootstrapperApplication"));
301 - }
306 this.ParseBootstrapperApplicationElement(child);
303 - baSeen = true;
307 break;
308 case "BootstrapperApplicationRef":
309 this.ParseBootstrapperApplicationRefElement(child);
@@ -397,6 +400,7 @@ namespace WixToolset.Core
400 UpgradeCode = upgradeCode,
401 Version = version,
402 Copyright = copyright,
403 + InProgressName = inProgressName,
404 Name = name,
405 Manufacturer = manufacturer,
406 Attributes = attributes,
@@ -437,6 +441,12 @@ namespace WixToolset.Core
441 });
442
443 // Ensure that the bundle stores the well-known persisted values.
444 + this.Core.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Section, BurnConstants.BURN_BUNDLE_INPROGRESS_NAME))
445 + {
446 + Hidden = false,
447 + Persisted = true,
448 + });
449 +
450 this.Core.AddSymbol(new WixBundleVariableSymbol(sourceLineNumbers, new Identifier(AccessModifier.Section, BurnConstants.BURN_BUNDLE_NAME))
451 {
452 Hidden = false,
src/wix/test/WixToolsetTest.CoreIntegration/BundleFixture.cs
+1 -1
@@ -116,7 +116,7 @@ namespace WixToolsetTest.CoreIntegration
116 var registrationElements = extractResult.SelectManifestNodes("/burn:BurnManifest/burn:Registration");
117 var registrationElement = (XmlNode)Assert.Single(registrationElements);
118 Assert.Equal($"<Registration Id='{bundleSymbol.BundleId}' ExecutableName='test.exe' PerMachine='yes' Tag='' Version='1.0.0.0' ProviderKey='{bundleSymbol.BundleId}'>" +
119 - "<Arp Register='yes' DisplayName='~TestBundle' DisplayVersion='1.0.0.0' Publisher='Example Corporation' />" +
119 + "<Arp Register='yes' DisplayName='~TestBundle' DisplayVersion='1.0.0.0' InProgressDisplayName='~InProgressTestBundle' Publisher='Example Corporation' />" +
120 "</Registration>", registrationElement.GetTestXml());
121
122 var msiPayloads = extractResult.SelectManifestNodes("/burn:BurnManifest/burn:Payload[@Id='test.msi']");
src/wix/test/WixToolsetTest.CoreIntegration/TestData/SimpleBundle/Bundle.en-us.wxl
+1
@@ -6,5 +6,6 @@ This file contains the declaration of all the localizable strings.
6 <WixLocalization xmlns="http://wixtoolset.org/schemas/v4/wxl" Culture="en-US">
7
8 <String Id="BundleName">~TestBundle</String>
9 + <String Id="BundleInProgressName">~InProgressTestBundle</String>
10
11 </WixLocalization>
src/wix/test/WixToolsetTest.CoreIntegration/TestData/SimpleBundle/Bundle.wxs
+1 -1
@@ -1,5 +1,5 @@
1 <Wix xmlns="http://wixtoolset.org/schemas/v4/wxs">
2 - <Bundle Name="!(loc.BundleName)" Version="!(bind.packageVersion.test.msi)" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a">
2 + <Bundle Name="!(loc.BundleName)" InProgressName="!(loc.BundleInProgressName)" Version="!(bind.packageVersion.test.msi)" Manufacturer="Example Corporation" UpgradeCode="047730a5-30fe-4a62-a520-da9381b8226a">
3 <BootstrapperApplication>
4 <BootstrapperApplicationDll SourceFile="fakeba.dll" />
5 </BootstrapperApplication>