aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Hall <r.sean.hall@gmail.com>2022-04-13 10:13:10 -0500
committerSean Hall <r.sean.hall@gmail.com>2022-04-13 13:13:48 -0500
commitbe43682720cf9c238aa1efba5940b8e2279c5bc4 (patch)
treebec1c31030fdd961e5dfd8f0954e6b8d3274bee6
parent866413ec39c573a50b7ec0753f643918a1939dee (diff)
downloadwix-be43682720cf9c238aa1efba5940b8e2279c5bc4.tar.gz
wix-be43682720cf9c238aa1efba5940b8e2279c5bc4.tar.bz2
wix-be43682720cf9c238aa1efba5940b8e2279c5bc4.zip
Try to improve fields of bundle symbols.
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixApprovedExeForElevationSymbol.cs16
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixBundleBundlePackageSymbol.cs17
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixBundleExePackageSymbol.cs16
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixBundleMsiFeatureSymbol.cs1
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixBundleMsiPackageSymbol.cs37
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixBundleMspPackageSymbol.cs24
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixBundlePackageSymbol.cs96
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixBundlePatchTargetCodeSymbol.cs22
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixBundlePayloadSymbol.cs39
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixBundleRelatedPackageSymbol.cs64
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixBundleRollbackBoundarySymbol.cs62
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixBundleSymbol.cs65
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixBundleTagSymbol.cs14
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixBundleUpdateSymbol.cs16
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixBundleVariableSymbol.cs48
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixChainSymbol.cs48
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixComponentSearchSymbol.cs19
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixFileSearchSymbol.cs133
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixProductSearchSymbol.cs43
-rw-r--r--src/api/wix/WixToolset.Data/Symbols/WixRegistrySearchSymbol.cs55
-rw-r--r--src/ext/Util/test/WixToolsetTest.Util/UtilExtensionFixture.cs5
-rw-r--r--src/ext/Util/wixext/UtilCompiler.cs103
-rw-r--r--src/test/burn/WixTestTools/BundleVerifier.cs6
-rw-r--r--src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs12
-rw-r--r--src/wix/WixToolset.Core.Burn/Bind/LegacySearchFacade.cs119
-rw-r--r--src/wix/WixToolset.Core.Burn/Bundles/AutomaticallySlipstreamPatchesCommand.cs15
-rw-r--r--src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs6
-rw-r--r--src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs43
-rw-r--r--src/wix/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs2
-rw-r--r--src/wix/WixToolset.Core.Burn/Bundles/ProcessBundlePackageCommand.cs8
-rw-r--r--src/wix/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs22
-rw-r--r--src/wix/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs28
-rw-r--r--src/wix/WixToolset.Core.Burn/Bundles/ProcessMsuPackageCommand.cs2
-rw-r--r--src/wix/WixToolset.Core/Compiler_Bundle.cs35
34 files changed, 923 insertions, 318 deletions
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixApprovedExeForElevationSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixApprovedExeForElevationSymbol.cs
index 04c6e712..1813ce5a 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixApprovedExeForElevationSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixApprovedExeForElevationSymbol.cs
@@ -66,6 +66,20 @@ namespace WixToolset.Data.Symbols
66 set => this.Set((int)WixApprovedExeForElevationSymbolFields.Attributes, (int)value); 66 set => this.Set((int)WixApprovedExeForElevationSymbolFields.Attributes, (int)value);
67 } 67 }
68 68
69 public bool Win64 => (this.Attributes & WixApprovedExeForElevationAttributes.Win64) == WixApprovedExeForElevationAttributes.Win64; 69 public bool Win64
70 {
71 get { return this.Attributes.HasFlag(WixApprovedExeForElevationAttributes.Win64); }
72 set
73 {
74 if (value)
75 {
76 this.Attributes |= WixApprovedExeForElevationAttributes.Win64;
77 }
78 else
79 {
80 this.Attributes &= ~WixApprovedExeForElevationAttributes.Win64;
81 }
82 }
83 }
70 } 84 }
71} 85}
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundleBundlePackageSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundleBundlePackageSymbol.cs
index dcf59e28..24e63881 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixBundleBundlePackageSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixBundleBundlePackageSymbol.cs
@@ -40,7 +40,6 @@ namespace WixToolset.Data.Symbols
40 { 40 {
41 None = 0, 41 None = 0,
42 SupportsBurnProtocol = 1, 42 SupportsBurnProtocol = 1,
43 Win64 = 2,
44 } 43 }
45 44
46 public class WixBundleBundlePackageSymbol : IntermediateSymbol 45 public class WixBundleBundlePackageSymbol : IntermediateSymbol
@@ -106,21 +105,5 @@ namespace WixToolset.Data.Symbols
106 } 105 }
107 } 106 }
108 } 107 }
109
110 public bool Win64
111 {
112 get { return this.Attributes.HasFlag(WixBundleBundlePackageAttributes.Win64); }
113 set
114 {
115 if (value)
116 {
117 this.Attributes |= WixBundleBundlePackageAttributes.Win64;
118 }
119 else
120 {
121 this.Attributes &= ~WixBundleBundlePackageAttributes.Win64;
122 }
123 }
124 }
125 } 108 }
126} 109}
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundleExePackageSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundleExePackageSymbol.cs
index fc891f13..6cf200c2 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixBundleExePackageSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixBundleExePackageSymbol.cs
@@ -90,7 +90,21 @@ namespace WixToolset.Data.Symbols
90 set => this.Set((int)WixBundleExePackageSymbolFields.ExeProtocol, value); 90 set => this.Set((int)WixBundleExePackageSymbolFields.ExeProtocol, value);
91 } 91 }
92 92
93 public bool IsBundle => this.Attributes.HasFlag(WixBundleExePackageAttributes.Bundle); 93 public bool IsBundle
94 {
95 get { return this.Attributes.HasFlag(WixBundleExePackageAttributes.Bundle); }
96 set
97 {
98 if (value)
99 {
100 this.Attributes |= WixBundleExePackageAttributes.Bundle;
101 }
102 else
103 {
104 this.Attributes &= ~WixBundleExePackageAttributes.Bundle;
105 }
106 }
107 }
94 108
95 public bool Repairable => this.RepairCommand != null; 109 public bool Repairable => this.RepairCommand != null;
96 110
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundleMsiFeatureSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundleMsiFeatureSymbol.cs
index f81da5b8..829e81c0 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixBundleMsiFeatureSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixBundleMsiFeatureSymbol.cs
@@ -107,6 +107,7 @@ namespace WixToolset.Data.Symbols
107 set => this.Set((int)WixBundleMsiFeatureSymbolFields.Directory, value); 107 set => this.Set((int)WixBundleMsiFeatureSymbolFields.Directory, value);
108 } 108 }
109 109
110 // Passthrough for Attributes column of Feature table.
110 public int Attributes 111 public int Attributes
111 { 112 {
112 get => (int)this.Fields[(int)WixBundleMsiFeatureSymbolFields.Attributes]; 113 get => (int)this.Fields[(int)WixBundleMsiFeatureSymbolFields.Attributes];
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundleMsiPackageSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundleMsiPackageSymbol.cs
index 21735f64..74d39c6c 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixBundleMsiPackageSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixBundleMsiPackageSymbol.cs
@@ -40,7 +40,8 @@ namespace WixToolset.Data.Symbols
40 [Flags] 40 [Flags]
41 public enum WixBundleMsiPackageAttributes 41 public enum WixBundleMsiPackageAttributes
42 { 42 {
43 EnableFeatureSelection = 0x4, 43 None = 0x0,
44 EnableFeatureSelection = 0x1,
44 ForcePerMachine = 0x2, 45 ForcePerMachine = 0x2,
45 } 46 }
46 47
@@ -98,8 +99,36 @@ namespace WixToolset.Data.Symbols
98 set => this.Set((int)WixBundleMsiPackageSymbolFields.Manufacturer, value); 99 set => this.Set((int)WixBundleMsiPackageSymbolFields.Manufacturer, value);
99 } 100 }
100 101
101 public bool EnableFeatureSelection => (this.Attributes & WixBundleMsiPackageAttributes.EnableFeatureSelection) == WixBundleMsiPackageAttributes.EnableFeatureSelection; 102 public bool EnableFeatureSelection
103 {
104 get { return this.Attributes.HasFlag(WixBundleMsiPackageAttributes.EnableFeatureSelection); }
105 set
106 {
107 if (value)
108 {
109 this.Attributes |= WixBundleMsiPackageAttributes.EnableFeatureSelection;
110 }
111 else
112 {
113 this.Attributes &= ~WixBundleMsiPackageAttributes.EnableFeatureSelection;
114 }
115 }
116 }
102 117
103 public bool ForcePerMachine => (this.Attributes & WixBundleMsiPackageAttributes.ForcePerMachine) == WixBundleMsiPackageAttributes.ForcePerMachine; 118 public bool ForcePerMachine
119 {
120 get { return this.Attributes.HasFlag(WixBundleMsiPackageAttributes.ForcePerMachine); }
121 set
122 {
123 if (value)
124 {
125 this.Attributes |= WixBundleMsiPackageAttributes.ForcePerMachine;
126 }
127 else
128 {
129 this.Attributes &= ~WixBundleMsiPackageAttributes.ForcePerMachine;
130 }
131 }
132 }
104 } 133 }
105} \ No newline at end of file 134}
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundleMspPackageSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundleMspPackageSymbol.cs
index 3784c2ff..46d604a8 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixBundleMspPackageSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixBundleMspPackageSymbol.cs
@@ -34,8 +34,8 @@ namespace WixToolset.Data.Symbols
34 [Flags] 34 [Flags]
35 public enum WixBundleMspPackageAttributes 35 public enum WixBundleMspPackageAttributes
36 { 36 {
37 Slipstream = 0x2, 37 None = 0x0,
38 TargetUnspecified = 0x4, 38 Slipstream = 0x1,
39 } 39 }
40 40
41 public class WixBundleMspPackageSymbol : IntermediateSymbol 41 public class WixBundleMspPackageSymbol : IntermediateSymbol
@@ -74,8 +74,20 @@ namespace WixToolset.Data.Symbols
74 set => this.Set((int)WixBundleMspPackageSymbolFields.PatchXml, value); 74 set => this.Set((int)WixBundleMspPackageSymbolFields.PatchXml, value);
75 } 75 }
76 76
77 public bool Slipstream => (this.Attributes & WixBundleMspPackageAttributes.Slipstream) == WixBundleMspPackageAttributes.Slipstream; 77 public bool Slipstream
78 78 {
79 public bool TargetUnspecified => (this.Attributes & WixBundleMspPackageAttributes.TargetUnspecified) == WixBundleMspPackageAttributes.TargetUnspecified; 79 get { return this.Attributes.HasFlag(WixBundleMspPackageAttributes.Slipstream); }
80 set
81 {
82 if (value)
83 {
84 this.Attributes |= WixBundleMspPackageAttributes.Slipstream;
85 }
86 else
87 {
88 this.Attributes &= ~WixBundleMspPackageAttributes.Slipstream;
89 }
90 }
91 }
80 } 92 }
81} \ No newline at end of file 93}
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundlePackageSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundlePackageSymbol.cs
index e68a9d09..6afe657e 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixBundlePackageSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixBundlePackageSymbol.cs
@@ -16,8 +16,7 @@ namespace WixToolset.Data
16 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.InstallCondition), IntermediateFieldType.String), 16 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.InstallCondition), IntermediateFieldType.String),
17 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.Cache), IntermediateFieldType.String), 17 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.Cache), IntermediateFieldType.String),
18 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.CacheId), IntermediateFieldType.String), 18 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.CacheId), IntermediateFieldType.String),
19 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.Vital), IntermediateFieldType.Bool), 19 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.PerMachine), IntermediateFieldType.Bool),
20 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.PerMachine), IntermediateFieldType.String),
21 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.LogPathVariable), IntermediateFieldType.String), 20 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.LogPathVariable), IntermediateFieldType.String),
22 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.RollbackLogPathVariable), IntermediateFieldType.String), 21 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.RollbackLogPathVariable), IntermediateFieldType.String),
23 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.Size), IntermediateFieldType.LargeNumber), 22 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.Size), IntermediateFieldType.LargeNumber),
@@ -28,7 +27,6 @@ namespace WixToolset.Data
28 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.Description), IntermediateFieldType.String), 27 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.Description), IntermediateFieldType.String),
29 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.RollbackBoundaryRef), IntermediateFieldType.String), 28 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.RollbackBoundaryRef), IntermediateFieldType.String),
30 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.RollbackBoundaryBackwardRef), IntermediateFieldType.String), 29 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.RollbackBoundaryBackwardRef), IntermediateFieldType.String),
31 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.Win64), IntermediateFieldType.Bool),
32 }, 30 },
33 typeof(WixBundlePackageSymbol)); 31 typeof(WixBundlePackageSymbol));
34 } 32 }
@@ -46,7 +44,6 @@ namespace WixToolset.Data.Symbols
46 InstallCondition, 44 InstallCondition,
47 Cache, 45 Cache,
48 CacheId, 46 CacheId,
49 Vital,
50 PerMachine, 47 PerMachine,
51 LogPathVariable, 48 LogPathVariable,
52 RollbackLogPathVariable, 49 RollbackLogPathVariable,
@@ -58,7 +55,6 @@ namespace WixToolset.Data.Symbols
58 Description, 55 Description,
59 RollbackBoundaryRef, 56 RollbackBoundaryRef,
60 RollbackBoundaryBackwardRef, 57 RollbackBoundaryBackwardRef,
61 Win64,
62 } 58 }
63 59
64 /// <summary> 60 /// <summary>
@@ -66,6 +62,7 @@ namespace WixToolset.Data.Symbols
66 /// </summary> 62 /// </summary>
67 public enum WixBundlePackageType 63 public enum WixBundlePackageType
68 { 64 {
65 NotSet = -1,
69 Bundle, 66 Bundle,
70 Exe, 67 Exe,
71 Msi, 68 Msi,
@@ -76,10 +73,11 @@ namespace WixToolset.Data.Symbols
76 [Flags] 73 [Flags]
77 public enum WixBundlePackageAttributes 74 public enum WixBundlePackageAttributes
78 { 75 {
76 None = 0x0,
79 Permanent = 0x1, 77 Permanent = 0x1,
80 Visible = 0x2, 78 Visible = 0x2,
81 PerMachine = 0x4, 79 Win64 = 0x4,
82 Win64 = 0x8, 80 Vital = 0x8,
83 } 81 }
84 82
85 public class WixBundlePackageSymbol : IntermediateSymbol 83 public class WixBundlePackageSymbol : IntermediateSymbol
@@ -96,7 +94,15 @@ namespace WixToolset.Data.Symbols
96 94
97 public WixBundlePackageType Type 95 public WixBundlePackageType Type
98 { 96 {
99 get => (WixBundlePackageType)Enum.Parse(typeof(WixBundlePackageType), (string)this.Fields[(int)WixBundlePackageSymbolFields.Type], true); 97 get
98 {
99 if (Enum.TryParse((string)this.Fields[(int)WixBundlePackageSymbolFields.Type], true, out WixBundlePackageType value))
100 {
101 return value;
102 }
103
104 return WixBundlePackageType.NotSet;
105 }
100 set => this.Set((int)WixBundlePackageSymbolFields.Type, value.ToString()); 106 set => this.Set((int)WixBundlePackageSymbolFields.Type, value.ToString());
101 } 107 }
102 108
@@ -130,16 +136,10 @@ namespace WixToolset.Data.Symbols
130 set => this.Set((int)WixBundlePackageSymbolFields.CacheId, value); 136 set => this.Set((int)WixBundlePackageSymbolFields.CacheId, value);
131 } 137 }
132 138
133 public bool? Vital 139 public bool? PerMachine
134 {
135 get => (bool?)this.Fields[(int)WixBundlePackageSymbolFields.Vital];
136 set => this.Set((int)WixBundlePackageSymbolFields.Vital, value);
137 }
138
139 public YesNoDefaultType PerMachine
140 { 140 {
141 get => Enum.TryParse((string)this.Fields[(int)WixBundlePackageSymbolFields.PerMachine], true, out YesNoDefaultType value) ? value : YesNoDefaultType.NotSet; 141 get => (bool?)this.Fields[(int)WixBundlePackageSymbolFields.PerMachine];
142 set => this.Set((int)WixBundlePackageSymbolFields.PerMachine, value.ToString().ToLowerInvariant()); 142 set => this.Set((int)WixBundlePackageSymbolFields.PerMachine, value);
143 } 143 }
144 144
145 public string LogPathVariable 145 public string LogPathVariable
@@ -202,12 +202,68 @@ namespace WixToolset.Data.Symbols
202 set => this.Set((int)WixBundlePackageSymbolFields.RollbackBoundaryBackwardRef, value); 202 set => this.Set((int)WixBundlePackageSymbolFields.RollbackBoundaryBackwardRef, value);
203 } 203 }
204 204
205 public bool Permanent
206 {
207 get { return this.Attributes.HasFlag(WixBundlePackageAttributes.Permanent); }
208 set
209 {
210 if (value)
211 {
212 this.Attributes |= WixBundlePackageAttributes.Permanent;
213 }
214 else
215 {
216 this.Attributes &= ~WixBundlePackageAttributes.Permanent;
217 }
218 }
219 }
220
221 public bool Visible
222 {
223 get { return this.Attributes.HasFlag(WixBundlePackageAttributes.Visible); }
224 set
225 {
226 if (value)
227 {
228 this.Attributes |= WixBundlePackageAttributes.Visible;
229 }
230 else
231 {
232 this.Attributes &= ~WixBundlePackageAttributes.Visible;
233 }
234 }
235 }
236
205 public bool Win64 237 public bool Win64
206 { 238 {
207 get => (bool)this.Fields[(int)WixBundlePackageSymbolFields.Win64]; 239 get { return this.Attributes.HasFlag(WixBundlePackageAttributes.Win64); }
208 set => this.Set((int)WixBundlePackageSymbolFields.Win64, value); 240 set
241 {
242 if (value)
243 {
244 this.Attributes |= WixBundlePackageAttributes.Win64;
245 }
246 else
247 {
248 this.Attributes &= ~WixBundlePackageAttributes.Win64;
249 }
250 }
209 } 251 }
210 252
211 public bool Permanent => (this.Attributes & WixBundlePackageAttributes.Permanent) == WixBundlePackageAttributes.Permanent; 253 public bool Vital
254 {
255 get { return this.Attributes.HasFlag(WixBundlePackageAttributes.Vital); }
256 set
257 {
258 if (value)
259 {
260 this.Attributes |= WixBundlePackageAttributes.Vital;
261 }
262 else
263 {
264 this.Attributes &= ~WixBundlePackageAttributes.Vital;
265 }
266 }
267 }
212 } 268 }
213} 269}
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundlePatchTargetCodeSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundlePatchTargetCodeSymbol.cs
index b1aa9c77..85f50602 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixBundlePatchTargetCodeSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixBundlePatchTargetCodeSymbol.cs
@@ -13,6 +13,7 @@ namespace WixToolset.Data
13 new IntermediateFieldDefinition(nameof(WixBundlePatchTargetCodeSymbolFields.PackageRef), IntermediateFieldType.String), 13 new IntermediateFieldDefinition(nameof(WixBundlePatchTargetCodeSymbolFields.PackageRef), IntermediateFieldType.String),
14 new IntermediateFieldDefinition(nameof(WixBundlePatchTargetCodeSymbolFields.TargetCode), IntermediateFieldType.String), 14 new IntermediateFieldDefinition(nameof(WixBundlePatchTargetCodeSymbolFields.TargetCode), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(WixBundlePatchTargetCodeSymbolFields.Attributes), IntermediateFieldType.Number), 15 new IntermediateFieldDefinition(nameof(WixBundlePatchTargetCodeSymbolFields.Attributes), IntermediateFieldType.Number),
16 new IntermediateFieldDefinition(nameof(WixBundlePatchTargetCodeSymbolFields.Type), IntermediateFieldType.Number),
16 }, 17 },
17 typeof(WixBundlePatchTargetCodeSymbol)); 18 typeof(WixBundlePatchTargetCodeSymbol));
18 } 19 }
@@ -27,22 +28,31 @@ namespace WixToolset.Data.Symbols
27 PackageRef, 28 PackageRef,
28 TargetCode, 29 TargetCode,
29 Attributes, 30 Attributes,
31 Type,
30 } 32 }
31 33
32 [Flags] 34 [Flags]
33 public enum WixBundlePatchTargetCodeAttributes : int 35 public enum WixBundlePatchTargetCodeAttributes : int
34 { 36 {
35 None = 0, 37 None = 0,
38 }
39
40 public enum WixBundlePatchTargetCodeType
41 {
42 /// <summary>
43 /// The transform has no specific target.
44 /// </summary>
45 Unspecified,
36 46
37 /// <summary> 47 /// <summary>
38 /// The transform targets a specific ProductCode. 48 /// The transform targets a specific ProductCode.
39 /// </summary> 49 /// </summary>
40 TargetsProductCode = 1, 50 ProductCode,
41 51
42 /// <summary> 52 /// <summary>
43 /// The transform targets a specific UpgradeCode. 53 /// The transform targets a specific UpgradeCode.
44 /// </summary> 54 /// </summary>
45 TargetsUpgradeCode = 2, 55 UpgradeCode,
46 } 56 }
47 57
48 public class WixBundlePatchTargetCodeSymbol : IntermediateSymbol 58 public class WixBundlePatchTargetCodeSymbol : IntermediateSymbol
@@ -75,8 +85,10 @@ namespace WixToolset.Data.Symbols
75 set => this.Set((int)WixBundlePatchTargetCodeSymbolFields.Attributes, (int)value); 85 set => this.Set((int)WixBundlePatchTargetCodeSymbolFields.Attributes, (int)value);
76 } 86 }
77 87
78 public bool TargetsProductCode => (this.Attributes & WixBundlePatchTargetCodeAttributes.TargetsProductCode) == WixBundlePatchTargetCodeAttributes.TargetsProductCode; 88 public WixBundlePatchTargetCodeType Type
79 89 {
80 public bool TargetsUpgradeCode => (this.Attributes & WixBundlePatchTargetCodeAttributes.TargetsUpgradeCode) == WixBundlePatchTargetCodeAttributes.TargetsUpgradeCode; 90 get => (WixBundlePatchTargetCodeType)this.Fields[(int)WixBundlePatchTargetCodeSymbolFields.Type].AsNumber();
91 set => this.Set((int)WixBundlePatchTargetCodeSymbolFields.Type, (int)value);
92 }
81 } 93 }
82} 94}
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundlePayloadSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundlePayloadSymbol.cs
index be581fb3..ed2060b3 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixBundlePayloadSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixBundlePayloadSymbol.cs
@@ -10,6 +10,7 @@ namespace WixToolset.Data
10 SymbolDefinitionType.WixBundlePayload, 10 SymbolDefinitionType.WixBundlePayload,
11 new[] 11 new[]
12 { 12 {
13 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.Attributes), IntermediateFieldType.Number),
13 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.Name), IntermediateFieldType.String), 14 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.Name), IntermediateFieldType.String),
14 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.SourceFile), IntermediateFieldType.Path), 15 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.SourceFile), IntermediateFieldType.Path),
15 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.DownloadUrl), IntermediateFieldType.String), 16 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.DownloadUrl), IntermediateFieldType.String),
@@ -21,7 +22,6 @@ namespace WixToolset.Data
21 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.Version), IntermediateFieldType.String), 22 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.Version), IntermediateFieldType.String),
22 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.Hash), IntermediateFieldType.String), 23 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.Hash), IntermediateFieldType.String),
23 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.ContainerRef), IntermediateFieldType.String), 24 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.ContainerRef), IntermediateFieldType.String),
24 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.ContentFile), IntermediateFieldType.Bool),
25 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.EmbeddedId), IntermediateFieldType.String), 25 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.EmbeddedId), IntermediateFieldType.String),
26 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.LayoutOnly), IntermediateFieldType.Bool), 26 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.LayoutOnly), IntermediateFieldType.Bool),
27 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.Packaging), IntermediateFieldType.Number), 27 new IntermediateFieldDefinition(nameof(WixBundlePayloadSymbolFields.Packaging), IntermediateFieldType.Number),
@@ -39,6 +39,7 @@ namespace WixToolset.Data.Symbols
39 39
40 public enum WixBundlePayloadSymbolFields 40 public enum WixBundlePayloadSymbolFields
41 { 41 {
42 Attributes,
42 Name, 43 Name,
43 SourceFile, 44 SourceFile,
44 DownloadUrl, 45 DownloadUrl,
@@ -50,7 +51,6 @@ namespace WixToolset.Data.Symbols
50 Version, 51 Version,
51 Hash, 52 Hash,
52 ContainerRef, 53 ContainerRef,
53 ContentFile,
54 EmbeddedId, 54 EmbeddedId,
55 LayoutOnly, 55 LayoutOnly,
56 Packaging, 56 Packaging,
@@ -59,6 +59,13 @@ namespace WixToolset.Data.Symbols
59 CertificateThumbprint, 59 CertificateThumbprint,
60 } 60 }
61 61
62 [Flags]
63 public enum WixBundlePayloadAttributes
64 {
65 None = 0x0,
66 ContentFile = 0x1,
67 }
68
62 public class WixBundlePayloadSymbol : IntermediateSymbol 69 public class WixBundlePayloadSymbol : IntermediateSymbol
63 { 70 {
64 public WixBundlePayloadSymbol() : base(SymbolDefinitions.WixBundlePayload, null, null) 71 public WixBundlePayloadSymbol() : base(SymbolDefinitions.WixBundlePayload, null, null)
@@ -71,6 +78,12 @@ namespace WixToolset.Data.Symbols
71 78
72 public IntermediateField this[WixBundlePayloadSymbolFields index] => this.Fields[(int)index]; 79 public IntermediateField this[WixBundlePayloadSymbolFields index] => this.Fields[(int)index];
73 80
81 public WixBundlePayloadAttributes Attributes
82 {
83 get => (WixBundlePayloadAttributes)this.Fields[(int)WixBundlePayloadSymbolFields.Attributes].AsNumber();
84 set => this.Set((int)WixBundlePayloadSymbolFields.Attributes, (int)value);
85 }
86
74 public string Name 87 public string Name
75 { 88 {
76 get => (string)this.Fields[(int)WixBundlePayloadSymbolFields.Name]; 89 get => (string)this.Fields[(int)WixBundlePayloadSymbolFields.Name];
@@ -137,12 +150,6 @@ namespace WixToolset.Data.Symbols
137 set => this.Set((int)WixBundlePayloadSymbolFields.ContainerRef, value); 150 set => this.Set((int)WixBundlePayloadSymbolFields.ContainerRef, value);
138 } 151 }
139 152
140 public bool ContentFile
141 {
142 get => (bool)this.Fields[(int)WixBundlePayloadSymbolFields.ContentFile];
143 set => this.Set((int)WixBundlePayloadSymbolFields.ContentFile, value);
144 }
145
146 public string EmbeddedId 153 public string EmbeddedId
147 { 154 {
148 get => (string)this.Fields[(int)WixBundlePayloadSymbolFields.EmbeddedId]; 155 get => (string)this.Fields[(int)WixBundlePayloadSymbolFields.EmbeddedId];
@@ -178,5 +185,21 @@ namespace WixToolset.Data.Symbols
178 get => (string)this.Fields[(int)WixBundlePayloadSymbolFields.CertificateThumbprint]; 185 get => (string)this.Fields[(int)WixBundlePayloadSymbolFields.CertificateThumbprint];
179 set => this.Set((int)WixBundlePayloadSymbolFields.CertificateThumbprint, value); 186 set => this.Set((int)WixBundlePayloadSymbolFields.CertificateThumbprint, value);
180 } 187 }
188
189 public bool ContentFile
190 {
191 get { return this.Attributes.HasFlag(WixBundlePayloadAttributes.ContentFile); }
192 set
193 {
194 if (value)
195 {
196 this.Attributes |= WixBundlePayloadAttributes.ContentFile;
197 }
198 else
199 {
200 this.Attributes &= ~WixBundlePayloadAttributes.ContentFile;
201 }
202 }
203 }
181 } 204 }
182} 205}
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundleRelatedPackageSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundleRelatedPackageSymbol.cs
index 7bd67b7f..77789048 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixBundleRelatedPackageSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixBundleRelatedPackageSymbol.cs
@@ -93,12 +93,68 @@ namespace WixToolset.Data.Symbols
93 set => this.Set((int)WixBundleRelatedPackageSymbolFields.Attributes, (int)value); 93 set => this.Set((int)WixBundleRelatedPackageSymbolFields.Attributes, (int)value);
94 } 94 }
95 95
96 public bool MinInclusive => (this.Attributes & WixBundleRelatedPackageAttributes.MinInclusive) == WixBundleRelatedPackageAttributes.MinInclusive; 96 public bool MinInclusive
97 {
98 get { return this.Attributes.HasFlag(WixBundleRelatedPackageAttributes.MinInclusive); }
99 set
100 {
101 if (value)
102 {
103 this.Attributes |= WixBundleRelatedPackageAttributes.MinInclusive;
104 }
105 else
106 {
107 this.Attributes &= ~WixBundleRelatedPackageAttributes.MinInclusive;
108 }
109 }
110 }
97 111
98 public bool MaxInclusive => (this.Attributes & WixBundleRelatedPackageAttributes.MaxInclusive) == WixBundleRelatedPackageAttributes.MaxInclusive; 112 public bool MaxInclusive
113 {
114 get { return this.Attributes.HasFlag(WixBundleRelatedPackageAttributes.MaxInclusive); }
115 set
116 {
117 if (value)
118 {
119 this.Attributes |= WixBundleRelatedPackageAttributes.MaxInclusive;
120 }
121 else
122 {
123 this.Attributes &= ~WixBundleRelatedPackageAttributes.MaxInclusive;
124 }
125 }
126 }
99 127
100 public bool OnlyDetect => (this.Attributes & WixBundleRelatedPackageAttributes.OnlyDetect) == WixBundleRelatedPackageAttributes.OnlyDetect; 128 public bool OnlyDetect
129 {
130 get { return this.Attributes.HasFlag(WixBundleRelatedPackageAttributes.OnlyDetect); }
131 set
132 {
133 if (value)
134 {
135 this.Attributes |= WixBundleRelatedPackageAttributes.OnlyDetect;
136 }
137 else
138 {
139 this.Attributes &= ~WixBundleRelatedPackageAttributes.OnlyDetect;
140 }
141 }
142 }
101 143
102 public bool LangInclusive => (this.Attributes & WixBundleRelatedPackageAttributes.LangInclusive) == WixBundleRelatedPackageAttributes.LangInclusive; 144 public bool LangInclusive
145 {
146 get { return this.Attributes.HasFlag(WixBundleRelatedPackageAttributes.LangInclusive); }
147 set
148 {
149 if (value)
150 {
151 this.Attributes |= WixBundleRelatedPackageAttributes.LangInclusive;
152 }
153 else
154 {
155 this.Attributes &= ~WixBundleRelatedPackageAttributes.LangInclusive;
156 }
157 }
158 }
103 } 159 }
104} 160}
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundleRollbackBoundarySymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundleRollbackBoundarySymbol.cs
index 1f91cef2..a75e388b 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixBundleRollbackBoundarySymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixBundleRollbackBoundarySymbol.cs
@@ -10,8 +10,7 @@ namespace WixToolset.Data
10 SymbolDefinitionType.WixBundleRollbackBoundary, 10 SymbolDefinitionType.WixBundleRollbackBoundary,
11 new[] 11 new[]
12 { 12 {
13 new IntermediateFieldDefinition(nameof(WixBundleRollbackBoundarySymbolFields.Vital), IntermediateFieldType.Number), 13 new IntermediateFieldDefinition(nameof(WixBundleSymbolFields.Attributes), IntermediateFieldType.Number),
14 new IntermediateFieldDefinition(nameof(WixBundleRollbackBoundarySymbolFields.Transaction), IntermediateFieldType.Number),
15 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.LogPathVariable), IntermediateFieldType.String), 14 new IntermediateFieldDefinition(nameof(WixBundlePackageSymbolFields.LogPathVariable), IntermediateFieldType.String),
16 }, 15 },
17 typeof(WixBundleRollbackBoundarySymbol)); 16 typeof(WixBundleRollbackBoundarySymbol));
@@ -20,13 +19,22 @@ namespace WixToolset.Data
20 19
21namespace WixToolset.Data.Symbols 20namespace WixToolset.Data.Symbols
22{ 21{
22 using System;
23
23 public enum WixBundleRollbackBoundarySymbolFields 24 public enum WixBundleRollbackBoundarySymbolFields
24 { 25 {
25 Vital, 26 Attributes,
26 Transaction,
27 LogPathVariable, 27 LogPathVariable,
28 } 28 }
29 29
30 [Flags]
31 public enum WixBundleRollbackBoundaryAttributes
32 {
33 None = 0x0,
34 Vital = 0x1,
35 Transaction = 0x2,
36 }
37
30 public class WixBundleRollbackBoundarySymbol : IntermediateSymbol 38 public class WixBundleRollbackBoundarySymbol : IntermediateSymbol
31 { 39 {
32 public WixBundleRollbackBoundarySymbol() : base(SymbolDefinitions.WixBundleRollbackBoundary, null, null) 40 public WixBundleRollbackBoundarySymbol() : base(SymbolDefinitions.WixBundleRollbackBoundary, null, null)
@@ -39,16 +47,10 @@ namespace WixToolset.Data.Symbols
39 47
40 public IntermediateField this[WixBundleRollbackBoundarySymbolFields index] => this.Fields[(int)index]; 48 public IntermediateField this[WixBundleRollbackBoundarySymbolFields index] => this.Fields[(int)index];
41 49
42 public bool? Vital 50 public WixBundleRollbackBoundaryAttributes Attributes
43 { 51 {
44 get => (bool?)this.Fields[(int)WixBundleRollbackBoundarySymbolFields.Vital]; 52 get => (WixBundleRollbackBoundaryAttributes)this.Fields[(int)WixBundleRollbackBoundarySymbolFields.Attributes].AsNumber();
45 set => this.Set((int)WixBundleRollbackBoundarySymbolFields.Vital, value); 53 set => this.Set((int)WixBundleRollbackBoundarySymbolFields.Attributes, (int)value);
46 }
47
48 public bool? Transaction
49 {
50 get => (bool?)this.Fields[(int)WixBundleRollbackBoundarySymbolFields.Transaction];
51 set => this.Set((int)WixBundleRollbackBoundarySymbolFields.Transaction, value);
52 } 54 }
53 55
54 public string LogPathVariable 56 public string LogPathVariable
@@ -56,5 +58,37 @@ namespace WixToolset.Data.Symbols
56 get => (string)this.Fields[(int)WixBundleRollbackBoundarySymbolFields.LogPathVariable]; 58 get => (string)this.Fields[(int)WixBundleRollbackBoundarySymbolFields.LogPathVariable];
57 set => this.Set((int)WixBundleRollbackBoundarySymbolFields.LogPathVariable, value); 59 set => this.Set((int)WixBundleRollbackBoundarySymbolFields.LogPathVariable, value);
58 } 60 }
61
62 public bool Vital
63 {
64 get { return this.Attributes.HasFlag(WixBundleRollbackBoundaryAttributes.Vital); }
65 set
66 {
67 if (value)
68 {
69 this.Attributes |= WixBundleRollbackBoundaryAttributes.Vital;
70 }
71 else
72 {
73 this.Attributes &= ~WixBundleRollbackBoundaryAttributes.Vital;
74 }
75 }
76 }
77
78 public bool Transaction
79 {
80 get { return this.Attributes.HasFlag(WixBundleRollbackBoundaryAttributes.Transaction); }
81 set
82 {
83 if (value)
84 {
85 this.Attributes |= WixBundleRollbackBoundaryAttributes.Transaction;
86 }
87 else
88 {
89 this.Attributes &= ~WixBundleRollbackBoundaryAttributes.Transaction;
90 }
91 }
92 }
59 } 93 }
60} \ No newline at end of file 94}
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundleSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundleSymbol.cs
index 72192c15..c4db0c21 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixBundleSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixBundleSymbol.cs
@@ -34,6 +34,7 @@ namespace WixToolset.Data
34 new IntermediateFieldDefinition(nameof(WixBundleSymbolFields.ProviderKey), IntermediateFieldType.String), 34 new IntermediateFieldDefinition(nameof(WixBundleSymbolFields.ProviderKey), IntermediateFieldType.String),
35 new IntermediateFieldDefinition(nameof(WixBundleSymbolFields.InProgressName), IntermediateFieldType.String), 35 new IntermediateFieldDefinition(nameof(WixBundleSymbolFields.InProgressName), IntermediateFieldType.String),
36 new IntermediateFieldDefinition(nameof(WixBundleSymbolFields.CommandLineVariables), IntermediateFieldType.String), 36 new IntermediateFieldDefinition(nameof(WixBundleSymbolFields.CommandLineVariables), IntermediateFieldType.String),
37 new IntermediateFieldDefinition(nameof(WixBundleSymbolFields.DisableModify), IntermediateFieldType.String),
37 }, 38 },
38 typeof(WixBundleSymbol)); 39 typeof(WixBundleSymbol));
39 } 40 }
@@ -69,16 +70,15 @@ namespace WixToolset.Data.Symbols
69 ProviderKey, 70 ProviderKey,
70 InProgressName, 71 InProgressName,
71 CommandLineVariables, 72 CommandLineVariables,
73 DisableModify,
72 } 74 }
73 75
74 [Flags] 76 [Flags]
75 public enum WixBundleAttributes 77 public enum WixBundleAttributes
76 { 78 {
77 None = 0x0, 79 None = 0x0,
78 DisableModify = 0x1, 80 DisableRemove = 0x1,
79 DisableRemove = 0x2, 81 PerMachine = 0x2,
80 SingleChangeUninstallButton = 0x4,
81 PerMachine = 0x8,
82 } 82 }
83 83
84 public enum WixBundleCommandLineVariables 84 public enum WixBundleCommandLineVariables
@@ -87,6 +87,13 @@ namespace WixToolset.Data.Symbols
87 CaseSensitive, 87 CaseSensitive,
88 } 88 }
89 89
90 public enum WixBundleModifyType
91 {
92 Allowed = 0,
93 Disabled = 1,
94 SingleChangeUninstallButton = 2,
95 }
96
90 public class WixBundleSymbol : IntermediateSymbol 97 public class WixBundleSymbol : IntermediateSymbol
91 { 98 {
92 public WixBundleSymbol() : base(SymbolDefinitions.WixBundle, null, null) 99 public WixBundleSymbol() : base(SymbolDefinitions.WixBundle, null, null)
@@ -243,14 +250,52 @@ namespace WixToolset.Data.Symbols
243 set => this.Set((int)WixBundleSymbolFields.CommandLineVariables, (int)value); 250 set => this.Set((int)WixBundleSymbolFields.CommandLineVariables, (int)value);
244 } 251 }
245 252
246 public PackagingType DefaultPackagingType => (this.Compressed.HasValue && !this.Compressed.Value) ? PackagingType.External : PackagingType.Embedded; 253 public WixBundleModifyType DisableModify
247 254 {
248 public bool DisableModify => (this.Attributes & WixBundleAttributes.DisableModify) == WixBundleAttributes.DisableModify; 255 get
256 {
257 if (Enum.TryParse((string)this.Fields[(int)WixBundleSymbolFields.DisableModify], true, out WixBundleModifyType value))
258 {
259 return value;
260 }
261
262 return WixBundleModifyType.Allowed;
263 }
264 set => this.Set((int)WixBundleSymbolFields.DisableModify, value.ToString().ToLowerInvariant());
265 }
249 266
250 public bool DisableRemove => (this.Attributes & WixBundleAttributes.DisableRemove) == WixBundleAttributes.DisableRemove; 267 public PackagingType DefaultPackagingType => (this.Compressed.HasValue && !this.Compressed.Value) ? PackagingType.External : PackagingType.Embedded;
251 268
252 public bool PerMachine => (this.Attributes & WixBundleAttributes.PerMachine) == WixBundleAttributes.PerMachine; 269 public bool DisableRemove
270 {
271 get { return this.Attributes.HasFlag(WixBundleAttributes.DisableRemove); }
272 set
273 {
274 if (value)
275 {
276 this.Attributes |= WixBundleAttributes.DisableRemove;
277 }
278 else
279 {
280 this.Attributes &= ~WixBundleAttributes.DisableRemove;
281 }
282 }
283 }
253 284
254 public bool SingleChangeUninstallButton => (this.Attributes & WixBundleAttributes.SingleChangeUninstallButton) == WixBundleAttributes.SingleChangeUninstallButton; 285 public bool PerMachine
286 {
287 get { return this.Attributes.HasFlag(WixBundleAttributes.PerMachine); }
288 set
289 {
290 if (value)
291 {
292 this.Attributes |= WixBundleAttributes.PerMachine;
293 }
294 else
295 {
296 this.Attributes &= ~WixBundleAttributes.PerMachine;
297 }
298 }
299 }
255 } 300 }
256} 301}
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundleTagSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundleTagSymbol.cs
index d550dae0..590484e0 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixBundleTagSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixBundleTagSymbol.cs
@@ -23,6 +23,8 @@ namespace WixToolset.Data
23 23
24namespace WixToolset.Data.Symbols 24namespace WixToolset.Data.Symbols
25{ 25{
26 using System;
27
26 public enum WixBundleTagSymbolFields 28 public enum WixBundleTagSymbolFields
27 { 29 {
28 Filename, 30 Filename,
@@ -33,6 +35,12 @@ namespace WixToolset.Data.Symbols
33 Xml, 35 Xml,
34 } 36 }
35 37
38 [Flags]
39 public enum WixBundleTagAttributes
40 {
41 None = 0x0,
42 }
43
36 public class WixBundleTagSymbol : IntermediateSymbol 44 public class WixBundleTagSymbol : IntermediateSymbol
37 { 45 {
38 public WixBundleTagSymbol() : base(SymbolDefinitions.WixBundleTag, null, null) 46 public WixBundleTagSymbol() : base(SymbolDefinitions.WixBundleTag, null, null)
@@ -69,10 +77,10 @@ namespace WixToolset.Data.Symbols
69 set => this.Set((int)WixBundleTagSymbolFields.InstallPath, value); 77 set => this.Set((int)WixBundleTagSymbolFields.InstallPath, value);
70 } 78 }
71 79
72 public int Attributes 80 public WixBundleTagAttributes Attributes
73 { 81 {
74 get => this.Fields[(int)WixBundleTagSymbolFields.Attributes].AsNumber(); 82 get => (WixBundleTagAttributes)this.Fields[(int)WixBundleTagSymbolFields.Attributes].AsNumber();
75 set => this.Set((int)WixBundleTagSymbolFields.Attributes, value); 83 set => this.Set((int)WixBundleTagSymbolFields.Attributes, (int)value);
76 } 84 }
77 85
78 public string Xml 86 public string Xml
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundleUpdateSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundleUpdateSymbol.cs
index d27bbc32..514f9e6c 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixBundleUpdateSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixBundleUpdateSymbol.cs
@@ -19,12 +19,20 @@ namespace WixToolset.Data
19 19
20namespace WixToolset.Data.Symbols 20namespace WixToolset.Data.Symbols
21{ 21{
22 using System;
23
22 public enum WixBundleUpdateSymbolFields 24 public enum WixBundleUpdateSymbolFields
23 { 25 {
24 Location, 26 Location,
25 Attributes, 27 Attributes,
26 } 28 }
27 29
30 [Flags]
31 public enum WixBundleUpdateAttributes
32 {
33 None = 0x0,
34 }
35
28 public class WixBundleUpdateSymbol : IntermediateSymbol 36 public class WixBundleUpdateSymbol : IntermediateSymbol
29 { 37 {
30 public WixBundleUpdateSymbol() : base(SymbolDefinitions.WixBundleUpdate, null, null) 38 public WixBundleUpdateSymbol() : base(SymbolDefinitions.WixBundleUpdate, null, null)
@@ -43,10 +51,10 @@ namespace WixToolset.Data.Symbols
43 set => this.Set((int)WixBundleUpdateSymbolFields.Location, value); 51 set => this.Set((int)WixBundleUpdateSymbolFields.Location, value);
44 } 52 }
45 53
46 public int Attributes 54 public WixBundleUpdateAttributes Attributes
47 { 55 {
48 get => (int)this.Fields[(int)WixBundleUpdateSymbolFields.Attributes]; 56 get => (WixBundleUpdateAttributes)this.Fields[(int)WixBundleUpdateSymbolFields.Attributes].AsNumber();
49 set => this.Set((int)WixBundleUpdateSymbolFields.Attributes, value); 57 set => this.Set((int)WixBundleUpdateSymbolFields.Attributes, (int)value);
50 } 58 }
51 } 59 }
52} \ No newline at end of file 60}
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixBundleVariableSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixBundleVariableSymbol.cs
index d68ac682..b8a1923d 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixBundleVariableSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixBundleVariableSymbol.cs
@@ -10,10 +10,9 @@ namespace WixToolset.Data
10 SymbolDefinitionType.WixBundleVariable, 10 SymbolDefinitionType.WixBundleVariable,
11 new[] 11 new[]
12 { 12 {
13 new IntermediateFieldDefinition(nameof(WixBundleVariableSymbolFields.Attributes), IntermediateFieldType.Number),
13 new IntermediateFieldDefinition(nameof(WixBundleVariableSymbolFields.Value), IntermediateFieldType.String), 14 new IntermediateFieldDefinition(nameof(WixBundleVariableSymbolFields.Value), IntermediateFieldType.String),
14 new IntermediateFieldDefinition(nameof(WixBundleVariableSymbolFields.Type), IntermediateFieldType.String), 15 new IntermediateFieldDefinition(nameof(WixBundleVariableSymbolFields.Type), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(WixBundleVariableSymbolFields.Hidden), IntermediateFieldType.Bool),
16 new IntermediateFieldDefinition(nameof(WixBundleVariableSymbolFields.Persisted), IntermediateFieldType.Bool),
17 }, 16 },
18 typeof(WixBundleVariableSymbol)); 17 typeof(WixBundleVariableSymbol));
19 } 18 }
@@ -25,10 +24,17 @@ namespace WixToolset.Data.Symbols
25 24
26 public enum WixBundleVariableSymbolFields 25 public enum WixBundleVariableSymbolFields
27 { 26 {
27 Attributes,
28 Value, 28 Value,
29 Type, 29 Type,
30 Hidden, 30 }
31 Persisted, 31
32 [Flags]
33 public enum WixBundleVariableAttributes
34 {
35 None = 0x0,
36 Hidden = 0x1,
37 Persisted = 0x2,
32 } 38 }
33 39
34 public enum WixBundleVariableType 40 public enum WixBundleVariableType
@@ -52,6 +58,12 @@ namespace WixToolset.Data.Symbols
52 58
53 public IntermediateField this[WixBundleVariableSymbolFields index] => this.Fields[(int)index]; 59 public IntermediateField this[WixBundleVariableSymbolFields index] => this.Fields[(int)index];
54 60
61 public WixBundleVariableAttributes Attributes
62 {
63 get => (WixBundleVariableAttributes)this.Fields[(int)WixBundleVariableSymbolFields.Attributes].AsNumber();
64 set => this.Set((int)WixBundleVariableSymbolFields.Attributes, (int)value);
65 }
66
55 public string Value 67 public string Value
56 { 68 {
57 get => (string)this.Fields[(int)WixBundleVariableSymbolFields.Value]; 69 get => (string)this.Fields[(int)WixBundleVariableSymbolFields.Value];
@@ -66,14 +78,34 @@ namespace WixToolset.Data.Symbols
66 78
67 public bool Hidden 79 public bool Hidden
68 { 80 {
69 get => (bool)this.Fields[(int)WixBundleVariableSymbolFields.Hidden]; 81 get { return this.Attributes.HasFlag(WixBundleVariableAttributes.Hidden); }
70 set => this.Set((int)WixBundleVariableSymbolFields.Hidden, value); 82 set
83 {
84 if (value)
85 {
86 this.Attributes |= WixBundleVariableAttributes.Hidden;
87 }
88 else
89 {
90 this.Attributes &= ~WixBundleVariableAttributes.Hidden;
91 }
92 }
71 } 93 }
72 94
73 public bool Persisted 95 public bool Persisted
74 { 96 {
75 get => (bool)this.Fields[(int)WixBundleVariableSymbolFields.Persisted]; 97 get { return this.Attributes.HasFlag(WixBundleVariableAttributes.Persisted); }
76 set => this.Set((int)WixBundleVariableSymbolFields.Persisted, value); 98 set
99 {
100 if (value)
101 {
102 this.Attributes |= WixBundleVariableAttributes.Persisted;
103 }
104 else
105 {
106 this.Attributes &= ~WixBundleVariableAttributes.Persisted;
107 }
108 }
77 } 109 }
78 } 110 }
79} 111}
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixChainSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixChainSymbol.cs
index 8ec5fc63..2ca1d512 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixChainSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixChainSymbol.cs
@@ -52,10 +52,52 @@ namespace WixToolset.Data.Symbols
52 set => this.Set((int)WixChainSymbolFields.Attributes, (int)value); 52 set => this.Set((int)WixChainSymbolFields.Attributes, (int)value);
53 } 53 }
54 54
55 public bool DisableRollback => (this.Attributes & WixChainAttributes.DisableRollback) == WixChainAttributes.DisableRollback; 55 public bool DisableRollback
56 {
57 get { return this.Attributes.HasFlag(WixChainAttributes.DisableRollback); }
58 set
59 {
60 if (value)
61 {
62 this.Attributes |= WixChainAttributes.DisableRollback;
63 }
64 else
65 {
66 this.Attributes &= ~WixChainAttributes.DisableRollback;
67 }
68 }
69 }
56 70
57 public bool DisableSystemRestore => (this.Attributes & WixChainAttributes.DisableSystemRestore) == WixChainAttributes.DisableSystemRestore; 71 public bool DisableSystemRestore
72 {
73 get { return this.Attributes.HasFlag(WixChainAttributes.DisableSystemRestore); }
74 set
75 {
76 if (value)
77 {
78 this.Attributes |= WixChainAttributes.DisableSystemRestore;
79 }
80 else
81 {
82 this.Attributes &= ~WixChainAttributes.DisableSystemRestore;
83 }
84 }
85 }
58 86
59 public bool ParallelCache => (this.Attributes & WixChainAttributes.ParallelCache) == WixChainAttributes.ParallelCache; 87 public bool ParallelCache
88 {
89 get { return this.Attributes.HasFlag(WixChainAttributes.ParallelCache); }
90 set
91 {
92 if (value)
93 {
94 this.Attributes |= WixChainAttributes.ParallelCache;
95 }
96 else
97 {
98 this.Attributes &= ~WixChainAttributes.ParallelCache;
99 }
100 }
101 }
60 } 102 }
61} 103}
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixComponentSearchSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixComponentSearchSymbol.cs
index 63f7179f..1a930c4e 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixComponentSearchSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixComponentSearchSymbol.cs
@@ -13,6 +13,7 @@ namespace WixToolset.Data
13 new IntermediateFieldDefinition(nameof(WixComponentSearchSymbolFields.Guid), IntermediateFieldType.String), 13 new IntermediateFieldDefinition(nameof(WixComponentSearchSymbolFields.Guid), IntermediateFieldType.String),
14 new IntermediateFieldDefinition(nameof(WixComponentSearchSymbolFields.ProductCode), IntermediateFieldType.String), 14 new IntermediateFieldDefinition(nameof(WixComponentSearchSymbolFields.ProductCode), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(WixComponentSearchSymbolFields.Attributes), IntermediateFieldType.Number), 15 new IntermediateFieldDefinition(nameof(WixComponentSearchSymbolFields.Attributes), IntermediateFieldType.Number),
16 new IntermediateFieldDefinition(nameof(WixComponentSearchSymbolFields.Type), IntermediateFieldType.Number),
16 }, 17 },
17 typeof(WixComponentSearchSymbol)); 18 typeof(WixComponentSearchSymbol));
18 } 19 }
@@ -27,14 +28,20 @@ namespace WixToolset.Data.Symbols
27 Guid, 28 Guid,
28 ProductCode, 29 ProductCode,
29 Attributes, 30 Attributes,
31 Type,
30 } 32 }
31 33
32 [Flags] 34 [Flags]
33 public enum WixComponentSearchAttributes 35 public enum WixComponentSearchAttributes
34 { 36 {
35 KeyPath = 0x1, 37 None = 0x0,
36 State = 0x2, 38 }
37 WantDirectory = 0x4, 39
40 public enum WixComponentSearchType
41 {
42 KeyPath,
43 State,
44 WantDirectory,
38 } 45 }
39 46
40 public class WixComponentSearchSymbol : IntermediateSymbol 47 public class WixComponentSearchSymbol : IntermediateSymbol
@@ -66,5 +73,11 @@ namespace WixToolset.Data.Symbols
66 get => (WixComponentSearchAttributes)this.Fields[(int)WixComponentSearchSymbolFields.Attributes].AsNumber(); 73 get => (WixComponentSearchAttributes)this.Fields[(int)WixComponentSearchSymbolFields.Attributes].AsNumber();
67 set => this.Set((int)WixComponentSearchSymbolFields.Attributes, (int)value); 74 set => this.Set((int)WixComponentSearchSymbolFields.Attributes, (int)value);
68 } 75 }
76
77 public WixComponentSearchType Type
78 {
79 get => (WixComponentSearchType)this.Fields[(int)WixComponentSearchSymbolFields.Type].AsNumber();
80 set => this.Set((int)WixComponentSearchSymbolFields.Type, (int)value);
81 }
69 } 82 }
70} 83}
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixFileSearchSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixFileSearchSymbol.cs
index 027605c7..4f8a370e 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixFileSearchSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixFileSearchSymbol.cs
@@ -19,6 +19,7 @@ namespace WixToolset.Data
19 new IntermediateFieldDefinition(nameof(WixFileSearchSymbolFields.MaxDate), IntermediateFieldType.Number), 19 new IntermediateFieldDefinition(nameof(WixFileSearchSymbolFields.MaxDate), IntermediateFieldType.Number),
20 new IntermediateFieldDefinition(nameof(WixFileSearchSymbolFields.Languages), IntermediateFieldType.String), 20 new IntermediateFieldDefinition(nameof(WixFileSearchSymbolFields.Languages), IntermediateFieldType.String),
21 new IntermediateFieldDefinition(nameof(WixFileSearchSymbolFields.Attributes), IntermediateFieldType.Number), 21 new IntermediateFieldDefinition(nameof(WixFileSearchSymbolFields.Attributes), IntermediateFieldType.Number),
22 new IntermediateFieldDefinition(nameof(WixFileSearchSymbolFields.Type), IntermediateFieldType.Number),
22 }, 23 },
23 typeof(WixFileSearchSymbol)); 24 typeof(WixFileSearchSymbol));
24 } 25 }
@@ -39,21 +40,27 @@ namespace WixToolset.Data.Symbols
39 MaxDate, 40 MaxDate,
40 Languages, 41 Languages,
41 Attributes, 42 Attributes,
43 Type,
42 } 44 }
43 45
44 [Flags] 46 [Flags]
45 public enum WixFileSearchAttributes 47 public enum WixFileSearchAttributes
46 { 48 {
47 Default = 0x001, 49 None = 0x000,
50 IsDirectory = 0x001,
48 MinVersionInclusive = 0x002, 51 MinVersionInclusive = 0x002,
49 MaxVersionInclusive = 0x004, 52 MaxVersionInclusive = 0x004,
50 MinSizeInclusive = 0x008, 53 MinSizeInclusive = 0x008,
51 MaxSizeInclusive = 0x010, 54 MaxSizeInclusive = 0x010,
52 MinDateInclusive = 0x020, 55 MinDateInclusive = 0x020,
53 MaxDateInclusive = 0x040, 56 MaxDateInclusive = 0x040,
54 WantVersion = 0x080, 57 }
55 WantExists = 0x100, 58
56 IsDirectory = 0x200, 59 public enum WixFileSearchType
60 {
61 Path,
62 Version,
63 Exists,
57 } 64 }
58 65
59 public class WixFileSearchSymbol : IntermediateSymbol 66 public class WixFileSearchSymbol : IntermediateSymbol
@@ -121,5 +128,123 @@ namespace WixToolset.Data.Symbols
121 get => (WixFileSearchAttributes)this.Fields[(int)WixFileSearchSymbolFields.Attributes].AsNumber(); 128 get => (WixFileSearchAttributes)this.Fields[(int)WixFileSearchSymbolFields.Attributes].AsNumber();
122 set => this.Set((int)WixFileSearchSymbolFields.Attributes, (int)value); 129 set => this.Set((int)WixFileSearchSymbolFields.Attributes, (int)value);
123 } 130 }
131
132 public WixFileSearchType Type
133 {
134 get => (WixFileSearchType)this.Fields[(int)WixFileSearchSymbolFields.Type].AsNumber();
135 set => this.Set((int)WixFileSearchSymbolFields.Type, (int)value);
136 }
137
138 public bool IsDirectory
139 {
140 get { return this.Attributes.HasFlag(WixFileSearchAttributes.IsDirectory); }
141 set
142 {
143 if (value)
144 {
145 this.Attributes |= WixFileSearchAttributes.IsDirectory;
146 }
147 else
148 {
149 this.Attributes &= ~WixFileSearchAttributes.IsDirectory;
150 }
151 }
152 }
153
154 public bool MinVersionInclusive
155 {
156 get { return this.Attributes.HasFlag(WixFileSearchAttributes.MinVersionInclusive); }
157 set
158 {
159 if (value)
160 {
161 this.Attributes |= WixFileSearchAttributes.MinVersionInclusive;
162 }
163 else
164 {
165 this.Attributes &= ~WixFileSearchAttributes.MinVersionInclusive;
166 }
167 }
168 }
169
170 public bool MaxVersionInclusive
171 {
172 get { return this.Attributes.HasFlag(WixFileSearchAttributes.MaxVersionInclusive); }
173 set
174 {
175 if (value)
176 {
177 this.Attributes |= WixFileSearchAttributes.MaxVersionInclusive;
178 }
179 else
180 {
181 this.Attributes &= ~WixFileSearchAttributes.MaxVersionInclusive;
182 }
183 }
184 }
185
186 public bool MinSizeInclusive
187 {
188 get { return this.Attributes.HasFlag(WixFileSearchAttributes.MinSizeInclusive); }
189 set
190 {
191 if (value)
192 {
193 this.Attributes |= WixFileSearchAttributes.MinSizeInclusive;
194 }
195 else
196 {
197 this.Attributes &= ~WixFileSearchAttributes.MinSizeInclusive;
198 }
199 }
200 }
201
202 public bool MaxSizeInclusive
203 {
204 get { return this.Attributes.HasFlag(WixFileSearchAttributes.MaxSizeInclusive); }
205 set
206 {
207 if (value)
208 {
209 this.Attributes |= WixFileSearchAttributes.MaxSizeInclusive;
210 }
211 else
212 {
213 this.Attributes &= ~WixFileSearchAttributes.MaxSizeInclusive;
214 }
215 }
216 }
217
218 public bool MinDateInclusive
219 {
220 get { return this.Attributes.HasFlag(WixFileSearchAttributes.MinDateInclusive); }
221 set
222 {
223 if (value)
224 {
225 this.Attributes |= WixFileSearchAttributes.MinDateInclusive;
226 }
227 else
228 {
229 this.Attributes &= ~WixFileSearchAttributes.MinDateInclusive;
230 }
231 }
232 }
233
234 public bool MaxDateInclusive
235 {
236 get { return this.Attributes.HasFlag(WixFileSearchAttributes.MaxDateInclusive); }
237 set
238 {
239 if (value)
240 {
241 this.Attributes |= WixFileSearchAttributes.MaxDateInclusive;
242 }
243 else
244 {
245 this.Attributes &= ~WixFileSearchAttributes.MaxDateInclusive;
246 }
247 }
248 }
124 } 249 }
125} 250}
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixProductSearchSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixProductSearchSymbol.cs
index f8a17b64..99360da5 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixProductSearchSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixProductSearchSymbol.cs
@@ -12,6 +12,7 @@ namespace WixToolset.Data
12 { 12 {
13 new IntermediateFieldDefinition(nameof(WixProductSearchSymbolFields.Guid), IntermediateFieldType.String), 13 new IntermediateFieldDefinition(nameof(WixProductSearchSymbolFields.Guid), IntermediateFieldType.String),
14 new IntermediateFieldDefinition(nameof(WixProductSearchSymbolFields.Attributes), IntermediateFieldType.Number), 14 new IntermediateFieldDefinition(nameof(WixProductSearchSymbolFields.Attributes), IntermediateFieldType.Number),
15 new IntermediateFieldDefinition(nameof(WixProductSearchSymbolFields.Type), IntermediateFieldType.Number),
15 }, 16 },
16 typeof(WixProductSearchSymbol)); 17 typeof(WixProductSearchSymbol));
17 } 18 }
@@ -25,16 +26,26 @@ namespace WixToolset.Data.Symbols
25 { 26 {
26 Guid, 27 Guid,
27 Attributes, 28 Attributes,
29 Type,
28 } 30 }
29 31
30 [Flags] 32 [Flags]
31 public enum WixProductSearchAttributes 33 public enum WixProductSearchAttributes
32 { 34 {
33 Version = 0x1, 35 None = 0x0,
34 Language = 0x2, 36
35 State = 0x4, 37 /// <summary>
36 Assignment = 0x8, 38 /// Guid contains the UpgradeCode. If not set, it contains the ProductCode.
37 UpgradeCode = 0x10, 39 /// </summary>
40 UpgradeCode = 0x1,
41 }
42
43 public enum WixProductSearchType
44 {
45 Version,
46 Language,
47 State,
48 Assignment,
38 } 49 }
39 50
40 public class WixProductSearchSymbol : IntermediateSymbol 51 public class WixProductSearchSymbol : IntermediateSymbol
@@ -60,5 +71,27 @@ namespace WixToolset.Data.Symbols
60 get => (WixProductSearchAttributes)this.Fields[(int)WixProductSearchSymbolFields.Attributes].AsNumber(); 71 get => (WixProductSearchAttributes)this.Fields[(int)WixProductSearchSymbolFields.Attributes].AsNumber();
61 set => this.Set((int)WixProductSearchSymbolFields.Attributes, (int)value); 72 set => this.Set((int)WixProductSearchSymbolFields.Attributes, (int)value);
62 } 73 }
74
75 public WixProductSearchType Type
76 {
77 get => (WixProductSearchType)this.Fields[(int)WixProductSearchSymbolFields.Type].AsNumber();
78 set => this.Set((int)WixProductSearchSymbolFields.Type, (int)value);
79 }
80
81 public bool IsUpgradeCode
82 {
83 get { return this.Attributes.HasFlag(WixProductSearchAttributes.UpgradeCode); }
84 set
85 {
86 if (value)
87 {
88 this.Attributes |= WixProductSearchAttributes.UpgradeCode;
89 }
90 else
91 {
92 this.Attributes &= ~WixProductSearchAttributes.UpgradeCode;
93 }
94 }
95 }
63 } 96 }
64} 97}
diff --git a/src/api/wix/WixToolset.Data/Symbols/WixRegistrySearchSymbol.cs b/src/api/wix/WixToolset.Data/Symbols/WixRegistrySearchSymbol.cs
index dffa8410..f1da962b 100644
--- a/src/api/wix/WixToolset.Data/Symbols/WixRegistrySearchSymbol.cs
+++ b/src/api/wix/WixToolset.Data/Symbols/WixRegistrySearchSymbol.cs
@@ -14,6 +14,7 @@ namespace WixToolset.Data
14 new IntermediateFieldDefinition(nameof(WixRegistrySearchSymbolFields.Key), IntermediateFieldType.String), 14 new IntermediateFieldDefinition(nameof(WixRegistrySearchSymbolFields.Key), IntermediateFieldType.String),
15 new IntermediateFieldDefinition(nameof(WixRegistrySearchSymbolFields.Value), IntermediateFieldType.String), 15 new IntermediateFieldDefinition(nameof(WixRegistrySearchSymbolFields.Value), IntermediateFieldType.String),
16 new IntermediateFieldDefinition(nameof(WixRegistrySearchSymbolFields.Attributes), IntermediateFieldType.Number), 16 new IntermediateFieldDefinition(nameof(WixRegistrySearchSymbolFields.Attributes), IntermediateFieldType.Number),
17 new IntermediateFieldDefinition(nameof(WixRegistrySearchSymbolFields.Type), IntermediateFieldType.Number),
17 }, 18 },
18 typeof(WixRegistrySearchSymbol)); 19 typeof(WixRegistrySearchSymbol));
19 } 20 }
@@ -29,17 +30,21 @@ namespace WixToolset.Data.Symbols
29 Key, 30 Key,
30 Value, 31 Value,
31 Attributes, 32 Attributes,
33 Type,
32 } 34 }
33 35
34 [Flags] 36 [Flags]
35 public enum WixRegistrySearchAttributes 37 public enum WixRegistrySearchAttributes
36 { 38 {
37 Raw = 0x01, 39 None = 0x0,
38 Compatible = 0x02, 40 ExpandEnvironmentVariables = 0x01,
39 ExpandEnvironmentVariables = 0x04, 41 Win64 = 0x2,
40 WantValue = 0x08, 42 }
41 WantExists = 0x10, 43
42 Win64 = 0x20, 44 public enum WixRegistrySearchType
45 {
46 Value,
47 Exists,
43 } 48 }
44 49
45 public class WixRegistrySearchSymbol : IntermediateSymbol 50 public class WixRegistrySearchSymbol : IntermediateSymbol
@@ -77,5 +82,43 @@ namespace WixToolset.Data.Symbols
77 get => (WixRegistrySearchAttributes)this.Fields[(int)WixRegistrySearchSymbolFields.Attributes].AsNumber(); 82 get => (WixRegistrySearchAttributes)this.Fields[(int)WixRegistrySearchSymbolFields.Attributes].AsNumber();
78 set => this.Set((int)WixRegistrySearchSymbolFields.Attributes, (int)value); 83 set => this.Set((int)WixRegistrySearchSymbolFields.Attributes, (int)value);
79 } 84 }
85
86 public WixRegistrySearchType Type
87 {
88 get => (WixRegistrySearchType)this.Fields[(int)WixRegistrySearchSymbolFields.Type].AsNumber();
89 set => this.Set((int)WixRegistrySearchSymbolFields.Type, (int)value);
90 }
91
92 public bool ExpandEnvironmentVariables
93 {
94 get { return this.Attributes.HasFlag(WixRegistrySearchAttributes.ExpandEnvironmentVariables); }
95 set
96 {
97 if (value)
98 {
99 this.Attributes |= WixRegistrySearchAttributes.ExpandEnvironmentVariables;
100 }
101 else
102 {
103 this.Attributes &= ~WixRegistrySearchAttributes.ExpandEnvironmentVariables;
104 }
105 }
106 }
107
108 public bool Win64
109 {
110 get { return this.Attributes.HasFlag(WixRegistrySearchAttributes.Win64); }
111 set
112 {
113 if (value)
114 {
115 this.Attributes |= WixRegistrySearchAttributes.Win64;
116 }
117 else
118 {
119 this.Attributes &= ~WixRegistrySearchAttributes.Win64;
120 }
121 }
122 }
80 } 123 }
81} 124}
diff --git a/src/ext/Util/test/WixToolsetTest.Util/UtilExtensionFixture.cs b/src/ext/Util/test/WixToolsetTest.Util/UtilExtensionFixture.cs
index d2a4e34b..32d18e9c 100644
--- a/src/ext/Util/test/WixToolsetTest.Util/UtilExtensionFixture.cs
+++ b/src/ext/Util/test/WixToolsetTest.Util/UtilExtensionFixture.cs
@@ -242,7 +242,6 @@ namespace WixToolsetTest.Util
242 [Fact] 242 [Fact]
243 public void CanBuildBundleWithSearches() 243 public void CanBuildBundleWithSearches()
244 { 244 {
245 var burnStubPath = TestData.Get(@"TestData\.Data\burn.exe");
246 var folder = TestData.Get(@"TestData\BundleWithSearches"); 245 var folder = TestData.Get(@"TestData\BundleWithSearches");
247 var rootFolder = TestData.Get(); 246 var rootFolder = TestData.Get();
248 var wixext = Path.Combine(rootFolder, "WixToolset.Util.wixext.dll"); 247 var wixext = Path.Combine(rootFolder, "WixToolset.Util.wixext.dll");
@@ -269,9 +268,7 @@ namespace WixToolsetTest.Util
269 result.AssertSuccess(); 268 result.AssertSuccess();
270 269
271 Assert.True(File.Exists(bundlePath)); 270 Assert.True(File.Exists(bundlePath));
272#if TODO
273 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.wixpdb"))); 271 Assert.True(File.Exists(Path.Combine(baseFolder, @"bin\test.wixpdb")));
274#endif
275 272
276 var extractResult = BundleExtractor.ExtractBAContainer(null, bundlePath, baFolderPath, extractFolderPath); 273 var extractResult = BundleExtractor.ExtractBAContainer(null, bundlePath, baFolderPath, extractFolderPath);
277 extractResult.AssertSuccess(); 274 extractResult.AssertSuccess();
@@ -293,7 +290,7 @@ namespace WixToolsetTest.Util
293 Assert.Equal("<RegistrySearch Id='RegistrySearchId' Variable='RegistrySearchVariable' " + 290 Assert.Equal("<RegistrySearch Id='RegistrySearchId' Variable='RegistrySearchVariable' " +
294 @"Root='HKLM' Key='SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full' Value='Release' Type='value' VariableType='string' />", utilSearches[3].GetTestXml()); 291 @"Root='HKLM' Key='SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full' Value='Release' Type='value' VariableType='string' />", utilSearches[3].GetTestXml());
295 Assert.Equal("<RegistrySearch Id='RegistrySearchId64' Variable='RegistrySearchVariable64' " + 292 Assert.Equal("<RegistrySearch Id='RegistrySearchId64' Variable='RegistrySearchVariable64' " +
296 @"Root='HKLM' Key='SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full' Value='Release' Type='value' Win64='yes' VariableType='string' />", utilSearches[4].GetTestXml()); 293 @"Root='HKLM' Key='SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full' Value='Release' Win64='yes' Type='value' VariableType='string' />", utilSearches[4].GetTestXml());
297 } 294 }
298 } 295 }
299 296
diff --git a/src/ext/Util/wixext/UtilCompiler.cs b/src/ext/Util/wixext/UtilCompiler.cs
index 09a90928..323e0f6a 100644
--- a/src/ext/Util/wixext/UtilCompiler.cs
+++ b/src/ext/Util/wixext/UtilCompiler.cs
@@ -443,7 +443,8 @@ namespace WixToolset.Util
443 string after = null; 443 string after = null;
444 string guid = null; 444 string guid = null;
445 string productCode = null; 445 string productCode = null;
446 var attributes = WixComponentSearchAttributes.KeyPath; 446 var attributes = WixComponentSearchAttributes.None;
447 var type = WixComponentSearchType.KeyPath;
447 448
448 foreach (var attrib in element.Attributes()) 449 foreach (var attrib in element.Attributes())
449 { 450 {
@@ -468,13 +469,13 @@ namespace WixToolset.Util
468 switch (result) 469 switch (result)
469 { 470 {
470 case "directory": 471 case "directory":
471 attributes = WixComponentSearchAttributes.WantDirectory; 472 type = WixComponentSearchType.WantDirectory;
472 break; 473 break;
473 case "keyPath": 474 case "keyPath":
474 attributes = WixComponentSearchAttributes.KeyPath; 475 type = WixComponentSearchType.KeyPath;
475 break; 476 break;
476 case "state": 477 case "state":
477 attributes = WixComponentSearchAttributes.State; 478 type = WixComponentSearchType.State;
478 break; 479 break;
479 default: 480 default:
480 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, attrib.Parent.Name.LocalName, attrib.Name.LocalName, result, "directory", "keyPath", "state")); 481 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, attrib.Parent.Name.LocalName, attrib.Name.LocalName, result, "directory", "keyPath", "state"));
@@ -499,7 +500,7 @@ namespace WixToolset.Util
499 500
500 if (null == id) 501 if (null == id)
501 { 502 {
502 id = this.ParseHelper.CreateIdentifier("wcs", variable, condition, after, guid, productCode, attributes.ToString()); 503 id = this.ParseHelper.CreateIdentifier("wcs", variable, condition, after, guid, productCode, attributes.ToString(), type.ToString());
503 } 504 }
504 505
505 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); 506 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
@@ -513,6 +514,7 @@ namespace WixToolset.Util
513 Guid = guid, 514 Guid = guid,
514 ProductCode = productCode, 515 ProductCode = productCode,
515 Attributes = attributes, 516 Attributes = attributes,
517 Type = type,
516 }); 518 });
517 } 519 }
518 } 520 }
@@ -983,6 +985,7 @@ namespace WixToolset.Util
983 string after = null; 985 string after = null;
984 string path = null; 986 string path = null;
985 var attributes = WixFileSearchAttributes.IsDirectory; 987 var attributes = WixFileSearchAttributes.IsDirectory;
988 var type = WixFileSearchType.Path;
986 989
987 foreach (var attrib in element.Attributes()) 990 foreach (var attrib in element.Attributes())
988 { 991 {
@@ -1004,7 +1007,7 @@ namespace WixToolset.Util
1004 switch (result) 1007 switch (result)
1005 { 1008 {
1006 case "exists": 1009 case "exists":
1007 attributes |= WixFileSearchAttributes.WantExists; 1010 type = WixFileSearchType.Exists;
1008 break; 1011 break;
1009 default: 1012 default:
1010 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, attrib.Parent.Name.LocalName, attrib.Name.LocalName, result, "exists")); 1013 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, attrib.Parent.Name.LocalName, attrib.Name.LocalName, result, "exists"));
@@ -1029,7 +1032,7 @@ namespace WixToolset.Util
1029 1032
1030 if (null == id) 1033 if (null == id)
1031 { 1034 {
1032 id = this.ParseHelper.CreateIdentifier("wds", variable, condition, after, path, attributes.ToString()); 1035 id = this.ParseHelper.CreateIdentifier("wds", variable, condition, after, path, attributes.ToString(), type.ToString());
1033 } 1036 }
1034 1037
1035 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); 1038 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
@@ -1038,7 +1041,7 @@ namespace WixToolset.Util
1038 1041
1039 if (!this.Messaging.EncounteredError) 1042 if (!this.Messaging.EncounteredError)
1040 { 1043 {
1041 this.CreateWixFileSearchRow(section, sourceLineNumbers, id, path, attributes); 1044 this.CreateWixFileSearchRow(section, sourceLineNumbers, id, path, attributes, type);
1042 } 1045 }
1043 } 1046 }
1044 1047
@@ -1086,7 +1089,8 @@ namespace WixToolset.Util
1086 string condition = null; 1089 string condition = null;
1087 string after = null; 1090 string after = null;
1088 string path = null; 1091 string path = null;
1089 var attributes = WixFileSearchAttributes.Default; 1092 var attributes = WixFileSearchAttributes.None;
1093 var type = WixFileSearchType.Path;
1090 1094
1091 foreach (var attrib in node.Attributes()) 1095 foreach (var attrib in node.Attributes())
1092 { 1096 {
@@ -1108,10 +1112,10 @@ namespace WixToolset.Util
1108 switch (result) 1112 switch (result)
1109 { 1113 {
1110 case "exists": 1114 case "exists":
1111 attributes |= WixFileSearchAttributes.WantExists; 1115 type = WixFileSearchType.Exists;
1112 break; 1116 break;
1113 case "version": 1117 case "version":
1114 attributes |= WixFileSearchAttributes.WantVersion; 1118 type = WixFileSearchType.Version;
1115 break; 1119 break;
1116 default: 1120 default:
1117 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, attrib.Parent.Name.LocalName, attrib.Name.LocalName, result, "exists", "version")); 1121 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, attrib.Parent.Name.LocalName, attrib.Name.LocalName, result, "exists", "version"));
@@ -1136,7 +1140,7 @@ namespace WixToolset.Util
1136 1140
1137 if (null == id) 1141 if (null == id)
1138 { 1142 {
1139 id = this.ParseHelper.CreateIdentifier("wfs", variable, condition, after, path, attributes.ToString()); 1143 id = this.ParseHelper.CreateIdentifier("wfs", variable, condition, after, path, attributes.ToString(), type.ToString());
1140 } 1144 }
1141 1145
1142 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node); 1146 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, node);
@@ -1145,7 +1149,7 @@ namespace WixToolset.Util
1145 1149
1146 if (!this.Messaging.EncounteredError) 1150 if (!this.Messaging.EncounteredError)
1147 { 1151 {
1148 this.CreateWixFileSearchRow(section, sourceLineNumbers, id, path, attributes); 1152 this.CreateWixFileSearchRow(section, sourceLineNumbers, id, path, attributes, type);
1149 } 1153 }
1150 } 1154 }
1151 1155
@@ -1156,12 +1160,14 @@ namespace WixToolset.Util
1156 /// <param name="id">Identifier of the search (key into the WixSearch table)</param> 1160 /// <param name="id">Identifier of the search (key into the WixSearch table)</param>
1157 /// <param name="path">File/directory path to search for.</param> 1161 /// <param name="path">File/directory path to search for.</param>
1158 /// <param name="attributes"></param> 1162 /// <param name="attributes"></param>
1159 private void CreateWixFileSearchRow(IntermediateSection section, SourceLineNumber sourceLineNumbers, Identifier id, string path, WixFileSearchAttributes attributes) 1163 /// <param name="type"></param>
1164 private void CreateWixFileSearchRow(IntermediateSection section, SourceLineNumber sourceLineNumbers, Identifier id, string path, WixFileSearchAttributes attributes, WixFileSearchType type)
1160 { 1165 {
1161 section.AddSymbol(new WixFileSearchSymbol(sourceLineNumbers, id) 1166 section.AddSymbol(new WixFileSearchSymbol(sourceLineNumbers, id)
1162 { 1167 {
1163 Path = path, 1168 Path = path,
1164 Attributes = attributes, 1169 Attributes = attributes,
1170 Type = type,
1165 }); 1171 });
1166 } 1172 }
1167 1173
@@ -2545,7 +2551,8 @@ namespace WixToolset.Util
2545 string after = null; 2551 string after = null;
2546 string productCode = null; 2552 string productCode = null;
2547 string upgradeCode = null; 2553 string upgradeCode = null;
2548 var attributes = WixProductSearchAttributes.Version; 2554 var attributes = WixProductSearchAttributes.None;
2555 var type = WixProductSearchType.Version;
2549 2556
2550 foreach (var attrib in element.Attributes()) 2557 foreach (var attrib in element.Attributes())
2551 { 2558 {
@@ -2570,16 +2577,16 @@ namespace WixToolset.Util
2570 switch (result) 2577 switch (result)
2571 { 2578 {
2572 case "version": 2579 case "version":
2573 attributes = WixProductSearchAttributes.Version; 2580 type = WixProductSearchType.Version;
2574 break; 2581 break;
2575 case "language": 2582 case "language":
2576 attributes = WixProductSearchAttributes.Language; 2583 type = WixProductSearchType.Language;
2577 break; 2584 break;
2578 case "state": 2585 case "state":
2579 attributes = WixProductSearchAttributes.State; 2586 type = WixProductSearchType.State;
2580 break; 2587 break;
2581 case "assignment": 2588 case "assignment":
2582 attributes = WixProductSearchAttributes.Assignment; 2589 type = WixProductSearchType.Assignment;
2583 break; 2590 break;
2584 default: 2591 default:
2585 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, attrib.Parent.Name.LocalName, attrib.Name.LocalName, result, "version", "language", "state", "assignment")); 2592 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, attrib.Parent.Name.LocalName, attrib.Name.LocalName, result, "version", "language", "state", "assignment"));
@@ -2607,9 +2614,21 @@ namespace WixToolset.Util
2607 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "UpgradeCode", "ProductCode")); 2614 this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "UpgradeCode", "ProductCode"));
2608 } 2615 }
2609 2616
2617 string guid;
2618 if (upgradeCode != null)
2619 {
2620 // set an additional flag if this is an upgrade code
2621 attributes |= WixProductSearchAttributes.UpgradeCode;
2622 guid = upgradeCode;
2623 }
2624 else
2625 {
2626 guid = productCode;
2627 }
2628
2610 if (null == id) 2629 if (null == id)
2611 { 2630 {
2612 id = this.ParseHelper.CreateIdentifier("wps", variable, condition, after, productCode ?? upgradeCode, attributes.ToString()); 2631 id = this.ParseHelper.CreateIdentifier("wps", variable, condition, after, guid, attributes.ToString(), type.ToString());
2613 } 2632 }
2614 2633
2615 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); 2634 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
@@ -2618,16 +2637,11 @@ namespace WixToolset.Util
2618 2637
2619 if (!this.Messaging.EncounteredError) 2638 if (!this.Messaging.EncounteredError)
2620 { 2639 {
2621 // set an additional flag if this is an upgrade code
2622 if (null != upgradeCode)
2623 {
2624 attributes |= WixProductSearchAttributes.UpgradeCode;
2625 }
2626
2627 section.AddSymbol(new WixProductSearchSymbol(sourceLineNumbers, id) 2640 section.AddSymbol(new WixProductSearchSymbol(sourceLineNumbers, id)
2628 { 2641 {
2629 Guid = productCode ?? upgradeCode, 2642 Guid = guid,
2630 Attributes = attributes, 2643 Attributes = attributes,
2644 Type = type,
2631 }); 2645 });
2632 } 2646 }
2633 } 2647 }
@@ -2648,7 +2662,8 @@ namespace WixToolset.Util
2648 string value = null; 2662 string value = null;
2649 var expand = YesNoType.NotSet; 2663 var expand = YesNoType.NotSet;
2650 var win64 = this.Context.IsCurrentPlatform64Bit; 2664 var win64 = this.Context.IsCurrentPlatform64Bit;
2651 var attributes = WixRegistrySearchAttributes.Raw | WixRegistrySearchAttributes.WantValue; 2665 var attributes = WixRegistrySearchAttributes.None;
2666 var type = WixRegistrySearchType.Value;
2652 2667
2653 foreach (var attrib in element.Attributes()) 2668 foreach (var attrib in element.Attributes())
2654 { 2669 {
@@ -2692,30 +2707,15 @@ namespace WixToolset.Util
2692 case "ExpandEnvironmentVariables": 2707 case "ExpandEnvironmentVariables":
2693 expand = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib); 2708 expand = this.ParseHelper.GetAttributeYesNoValue(sourceLineNumbers, attrib);
2694 break; 2709 break;
2695 case "Format":
2696 string format = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2697 switch (format)
2698 {
2699 case "raw":
2700 attributes |= WixRegistrySearchAttributes.Raw;
2701 break;
2702 case "compatible":
2703 attributes |= WixRegistrySearchAttributes.Compatible;
2704 break;
2705 default:
2706 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, attrib.Parent.Name.LocalName, attrib.Name.LocalName, format, "raw", "compatible"));
2707 break;
2708 }
2709 break;
2710 case "Result": 2710 case "Result":
2711 var result = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); 2711 var result = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
2712 switch (result) 2712 switch (result)
2713 { 2713 {
2714 case "exists": 2714 case "exists":
2715 attributes |= WixRegistrySearchAttributes.WantExists; 2715 type = WixRegistrySearchType.Exists;
2716 break; 2716 break;
2717 case "value": 2717 case "value":
2718 attributes |= WixRegistrySearchAttributes.WantValue; 2718 type = WixRegistrySearchType.Value;
2719 break; 2719 break;
2720 default: 2720 default:
2721 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, attrib.Parent.Name.LocalName, attrib.Name.LocalName, result, "exists", "value")); 2721 this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, attrib.Parent.Name.LocalName, attrib.Name.LocalName, result, "exists", "value"));
@@ -2743,14 +2743,9 @@ namespace WixToolset.Util
2743 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Key")); 2743 this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Key"));
2744 } 2744 }
2745 2745
2746 if (null == id)
2747 {
2748 id = this.ParseHelper.CreateIdentifier("wrs", variable, condition, after, root.ToString(), key, value, attributes.ToString());
2749 }
2750
2751 if (expand == YesNoType.Yes) 2746 if (expand == YesNoType.Yes)
2752 { 2747 {
2753 if (0 != (attributes & WixRegistrySearchAttributes.WantExists)) 2748 if (type == WixRegistrySearchType.Exists)
2754 { 2749 {
2755 this.Messaging.Write(ErrorMessages.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "ExpandEnvironmentVariables", expand.ToString(), "Result", "exists")); 2750 this.Messaging.Write(ErrorMessages.IllegalAttributeValueWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "ExpandEnvironmentVariables", expand.ToString(), "Result", "exists"));
2756 } 2751 }
@@ -2763,6 +2758,11 @@ namespace WixToolset.Util
2763 attributes |= WixRegistrySearchAttributes.Win64; 2758 attributes |= WixRegistrySearchAttributes.Win64;
2764 } 2759 }
2765 2760
2761 if (null == id)
2762 {
2763 id = this.ParseHelper.CreateIdentifier("wrs", variable, condition, after, root.ToString(), key, value, attributes.ToString(), type.ToString());
2764 }
2765
2766 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); 2766 this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
2767 2767
2768 this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, null); 2768 this.ParseHelper.CreateWixSearchSymbol(section, sourceLineNumbers, element.Name.LocalName, id, variable, condition, after, null);
@@ -2775,6 +2775,7 @@ namespace WixToolset.Util
2775 Key = key, 2775 Key = key,
2776 Value = value, 2776 Value = value,
2777 Attributes = attributes, 2777 Attributes = attributes,
2778 Type = type,
2778 }); 2779 });
2779 } 2780 }
2780 } 2781 }
diff --git a/src/test/burn/WixTestTools/BundleVerifier.cs b/src/test/burn/WixTestTools/BundleVerifier.cs
index a5dbe0ec..56044c5f 100644
--- a/src/test/burn/WixTestTools/BundleVerifier.cs
+++ b/src/test/burn/WixTestTools/BundleVerifier.cs
@@ -120,7 +120,7 @@ namespace WixTestTools
120 var intermediate = Intermediate.Load(wixOutput); 120 var intermediate = Intermediate.Load(wixOutput);
121 var section = intermediate.Sections.Single(); 121 var section = intermediate.Sections.Single();
122 var packageSymbol = section.Symbols.OfType<WixBundlePackageSymbol>().Single(p => p.Id.Id == packageId); 122 var packageSymbol = section.Symbols.OfType<WixBundlePackageSymbol>().Single(p => p.Id.Id == packageId);
123 var cachePath = this.GetPackageCachePathForCacheId(packageSymbol.CacheId, packageSymbol.PerMachine == YesNoDefaultType.Yes); 123 var cachePath = this.GetPackageCachePathForCacheId(packageSymbol.CacheId, packageSymbol.PerMachine == true);
124 if (Directory.Exists(cachePath)) 124 if (Directory.Exists(cachePath))
125 { 125 {
126 Directory.Delete(cachePath, true); 126 Directory.Delete(cachePath, true);
@@ -133,7 +133,7 @@ namespace WixTestTools
133 var intermediate = Intermediate.Load(wixOutput); 133 var intermediate = Intermediate.Load(wixOutput);
134 var section = intermediate.Sections.Single(); 134 var section = intermediate.Sections.Single();
135 var packageSymbol = section.Symbols.OfType<WixBundlePackageSymbol>().Single(p => p.Id.Id == packageId); 135 var packageSymbol = section.Symbols.OfType<WixBundlePackageSymbol>().Single(p => p.Id.Id == packageId);
136 var cachePath = this.GetPackageCachePathForCacheId(packageSymbol.CacheId, packageSymbol.PerMachine == YesNoDefaultType.Yes); 136 var cachePath = this.GetPackageCachePathForCacheId(packageSymbol.CacheId, packageSymbol.PerMachine == true);
137 Assert.Equal(cached, Directory.Exists(cachePath)); 137 Assert.Equal(cached, Directory.Exists(cachePath));
138 } 138 }
139 139
@@ -144,7 +144,7 @@ namespace WixTestTools
144 var section = intermediate.Sections.Single(); 144 var section = intermediate.Sections.Single();
145 var packageSymbol = section.Symbols.OfType<WixBundlePackageSymbol>().Single(p => p.Id.Id == packageId); 145 var packageSymbol = section.Symbols.OfType<WixBundlePackageSymbol>().Single(p => p.Id.Id == packageId);
146 var providerSymbol = section.Symbols.OfType<WixDependencyProviderSymbol>().Single(p => p.ParentRef == packageId); 146 var providerSymbol = section.Symbols.OfType<WixDependencyProviderSymbol>().Single(p => p.ParentRef == packageId);
147 var registryRoot = packageSymbol.PerMachine == YesNoDefaultType.Yes ? Registry.LocalMachine : Registry.CurrentUser; 147 var registryRoot = packageSymbol.PerMachine == true ? Registry.LocalMachine : Registry.CurrentUser;
148 var subkeyPath = Path.Combine(DependencyRegistryRoot, providerSymbol.ProviderKey); 148 var subkeyPath = Path.Combine(DependencyRegistryRoot, providerSymbol.ProviderKey);
149 using var registryKey = registryRoot.OpenSubKey(subkeyPath); 149 using var registryKey = registryRoot.OpenSubKey(subkeyPath);
150 if (registryKey != null) 150 if (registryKey != null)
diff --git a/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs b/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
index edcb0abf..201d2839 100644
--- a/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bind/BindBundleCommand.cs
@@ -102,7 +102,7 @@ namespace WixToolset.Core.Burn
102 102
103 bundleSymbol.ProviderKey = bundleSymbol.BundleId = Guid.NewGuid().ToString("B").ToUpperInvariant(); 103 bundleSymbol.ProviderKey = bundleSymbol.BundleId = Guid.NewGuid().ToString("B").ToUpperInvariant();
104 104
105 bundleSymbol.Attributes |= WixBundleAttributes.PerMachine; // default to per-machine but the first-per user package wil flip the bundle per-user. 105 bundleSymbol.PerMachine = true; // default to per-machine but the first-per user package wil flip the bundle per-user.
106 106
107 this.NormalizeRelatedBundles(bundleSymbol, section); 107 this.NormalizeRelatedBundles(bundleSymbol, section);
108 108
@@ -608,11 +608,11 @@ namespace WixToolset.Core.Burn
608 608
609 foreach (var facade in facades) 609 foreach (var facade in facades)
610 { 610 {
611 if (bundleSymbol.PerMachine && YesNoDefaultType.No == facade.PackageSymbol.PerMachine) 611 if (bundleSymbol.PerMachine && facade.PackageSymbol.PerMachine.HasValue && !facade.PackageSymbol.PerMachine.Value)
612 { 612 {
613 this.Messaging.Write(VerboseMessages.SwitchingToPerUserPackage(facade.PackageSymbol.SourceLineNumbers, facade.PackageId)); 613 this.Messaging.Write(VerboseMessages.SwitchingToPerUserPackage(facade.PackageSymbol.SourceLineNumbers, facade.PackageId));
614 614
615 bundleSymbol.Attributes &= ~WixBundleAttributes.PerMachine; 615 bundleSymbol.PerMachine = false;
616 break; 616 break;
617 } 617 }
618 } 618 }
@@ -620,15 +620,15 @@ namespace WixToolset.Core.Burn
620 foreach (var facade in facades) 620 foreach (var facade in facades)
621 { 621 {
622 // Update package scope from bundle scope if default. 622 // Update package scope from bundle scope if default.
623 if (YesNoDefaultType.Default == facade.PackageSymbol.PerMachine) 623 if (!facade.PackageSymbol.PerMachine.HasValue)
624 { 624 {
625 facade.PackageSymbol.PerMachine = bundleSymbol.PerMachine ? YesNoDefaultType.Yes : YesNoDefaultType.No; 625 facade.PackageSymbol.PerMachine = bundleSymbol.PerMachine;
626 } 626 }
627 627
628 // We will only register packages in the same scope as the bundle. Warn if any packages with providers 628 // We will only register packages in the same scope as the bundle. Warn if any packages with providers
629 // are in a different scope and not permanent (permanents typically don't need a ref-count). 629 // are in a different scope and not permanent (permanents typically don't need a ref-count).
630 if (!bundleSymbol.PerMachine && 630 if (!bundleSymbol.PerMachine &&
631 YesNoDefaultType.Yes == facade.PackageSymbol.PerMachine && 631 facade.PackageSymbol.PerMachine.Value &&
632 !facade.PackageSymbol.Permanent && 632 !facade.PackageSymbol.Permanent &&
633 dependencySymbolsById.ContainsKey(facade.PackageId)) 633 dependencySymbolsById.ContainsKey(facade.PackageId))
634 { 634 {
diff --git a/src/wix/WixToolset.Core.Burn/Bind/LegacySearchFacade.cs b/src/wix/WixToolset.Core.Burn/Bind/LegacySearchFacade.cs
index 24d6f542..c6b6e7ee 100644
--- a/src/wix/WixToolset.Core.Burn/Bind/LegacySearchFacade.cs
+++ b/src/wix/WixToolset.Core.Burn/Bind/LegacySearchFacade.cs
@@ -3,6 +3,7 @@
3namespace WixToolset.Core.Burn 3namespace WixToolset.Core.Burn
4{ 4{
5 using System; 5 using System;
6 using System.Diagnostics;
6 using System.Xml; 7 using System.Xml;
7 using WixToolset.Data; 8 using WixToolset.Data;
8 using WixToolset.Data.Symbols; 9 using WixToolset.Data.Symbols;
@@ -37,6 +38,8 @@ namespace WixToolset.Core.Burn
37 case WixRegistrySearchSymbol symbol: 38 case WixRegistrySearchSymbol symbol:
38 this.WriteRegistrySearchXml(writer, symbol); 39 this.WriteRegistrySearchXml(writer, symbol);
39 break; 40 break;
41 default:
42 throw new NotImplementedException();
40 } 43 }
41 } 44 }
42 45
@@ -53,17 +56,19 @@ namespace WixToolset.Core.Burn
53 writer.WriteAttributeString("ProductCode", searchSymbol.ProductCode); 56 writer.WriteAttributeString("ProductCode", searchSymbol.ProductCode);
54 } 57 }
55 58
56 if (0 != (searchSymbol.Attributes & WixComponentSearchAttributes.KeyPath)) 59 switch (searchSymbol.Type)
57 { 60 {
58 writer.WriteAttributeString("Type", "keyPath"); 61 case WixComponentSearchType.KeyPath:
59 } 62 writer.WriteAttributeString("Type", "keyPath");
60 else if (0 != (searchSymbol.Attributes & WixComponentSearchAttributes.State)) 63 break;
61 { 64 case WixComponentSearchType.State:
62 writer.WriteAttributeString("Type", "state"); 65 writer.WriteAttributeString("Type", "state");
63 } 66 break;
64 else if (0 != (searchSymbol.Attributes & WixComponentSearchAttributes.WantDirectory)) 67 case WixComponentSearchType.WantDirectory:
65 { 68 writer.WriteAttributeString("Type", "directory");
66 writer.WriteAttributeString("Type", "directory"); 69 break;
70 default:
71 throw new NotImplementedException();
67 } 72 }
68 73
69 writer.WriteEndElement(); 74 writer.WriteEndElement();
@@ -71,24 +76,28 @@ namespace WixToolset.Core.Burn
71 76
72 private void WriteFileSearchXml(XmlTextWriter writer, WixFileSearchSymbol searchSymbol) 77 private void WriteFileSearchXml(XmlTextWriter writer, WixFileSearchSymbol searchSymbol)
73 { 78 {
74 writer.WriteStartElement((0 == (searchSymbol.Attributes & WixFileSearchAttributes.IsDirectory)) ? "FileSearch" : "DirectorySearch"); 79 writer.WriteStartElement(!searchSymbol.IsDirectory ? "FileSearch" : "DirectorySearch");
75 80
76 base.WriteXml(writer); 81 base.WriteXml(writer);
77 82
78 writer.WriteAttributeString("Path", searchSymbol.Path); 83 writer.WriteAttributeString("Path", searchSymbol.Path);
79 if (WixFileSearchAttributes.WantExists == (searchSymbol.Attributes & WixFileSearchAttributes.WantExists)) 84
80 { 85 switch (searchSymbol.Type)
81 writer.WriteAttributeString("Type", "exists");
82 }
83 else if (WixFileSearchAttributes.WantVersion == (searchSymbol.Attributes & WixFileSearchAttributes.WantVersion))
84 {
85 // Can never get here for DirectorySearch.
86 writer.WriteAttributeString("Type", "version");
87 }
88 else
89 { 86 {
90 writer.WriteAttributeString("Type", "path"); 87 case WixFileSearchType.Exists:
88 writer.WriteAttributeString("Type", "exists");
89 break;
90 case WixFileSearchType.Version:
91 Debug.Assert(!searchSymbol.IsDirectory, "Version search type is invalid for DirectorySearch");
92 writer.WriteAttributeString("Type", "version");
93 break;
94 case WixFileSearchType.Path:
95 writer.WriteAttributeString("Type", "path");
96 break;
97 default:
98 throw new NotImplementedException();
91 } 99 }
100
92 writer.WriteEndElement(); 101 writer.WriteEndElement();
93 } 102 }
94 103
@@ -98,7 +107,7 @@ namespace WixToolset.Core.Burn
98 107
99 base.WriteXml(writer); 108 base.WriteXml(writer);
100 109
101 if (0 != (symbol.Attributes & WixProductSearchAttributes.UpgradeCode)) 110 if (symbol.IsUpgradeCode)
102 { 111 {
103 writer.WriteAttributeString("UpgradeCode", symbol.Guid); 112 writer.WriteAttributeString("UpgradeCode", symbol.Guid);
104 } 113 }
@@ -107,21 +116,22 @@ namespace WixToolset.Core.Burn
107 writer.WriteAttributeString("ProductCode", symbol.Guid); 116 writer.WriteAttributeString("ProductCode", symbol.Guid);
108 } 117 }
109 118
110 if (0 != (symbol.Attributes & WixProductSearchAttributes.Version)) 119 switch (symbol.Type)
111 {
112 writer.WriteAttributeString("Type", "version");
113 }
114 else if (0 != (symbol.Attributes & WixProductSearchAttributes.Language))
115 {
116 writer.WriteAttributeString("Type", "language");
117 }
118 else if (0 != (symbol.Attributes & WixProductSearchAttributes.State))
119 {
120 writer.WriteAttributeString("Type", "state");
121 }
122 else if (0 != (symbol.Attributes & WixProductSearchAttributes.Assignment))
123 { 120 {
124 writer.WriteAttributeString("Type", "assignment"); 121 case WixProductSearchType.Version:
122 writer.WriteAttributeString("Type", "version");
123 break;
124 case WixProductSearchType.Language:
125 writer.WriteAttributeString("Type", "language");
126 break;
127 case WixProductSearchType.State:
128 writer.WriteAttributeString("Type", "state");
129 break;
130 case WixProductSearchType.Assignment:
131 writer.WriteAttributeString("Type", "assignment");
132 break;
133 default:
134 throw new NotImplementedException();
125 } 135 }
126 136
127 writer.WriteEndElement(); 137 writer.WriteEndElement();
@@ -147,6 +157,8 @@ namespace WixToolset.Core.Burn
147 case RegistryRootType.Users: 157 case RegistryRootType.Users:
148 writer.WriteAttributeString("Root", "HKU"); 158 writer.WriteAttributeString("Root", "HKU");
149 break; 159 break;
160 default:
161 throw new NotImplementedException();
150 } 162 }
151 163
152 writer.WriteAttributeString("Key", symbol.Key); 164 writer.WriteAttributeString("Key", symbol.Key);
@@ -156,27 +168,32 @@ namespace WixToolset.Core.Burn
156 writer.WriteAttributeString("Value", symbol.Value); 168 writer.WriteAttributeString("Value", symbol.Value);
157 } 169 }
158 170
159 var existenceOnly = 0 != (symbol.Attributes & WixRegistrySearchAttributes.WantExists); 171 if (symbol.Win64)
160
161 writer.WriteAttributeString("Type", existenceOnly ? "exists" : "value");
162
163 if (0 != (symbol.Attributes & WixRegistrySearchAttributes.Win64))
164 { 172 {
165 writer.WriteAttributeString("Win64", "yes"); 173 writer.WriteAttributeString("Win64", "yes");
166 } 174 }
167 175
168 if (!existenceOnly) 176 switch (symbol.Type)
169 { 177 {
170 if (0 != (symbol.Attributes & WixRegistrySearchAttributes.ExpandEnvironmentVariables)) 178 case WixRegistrySearchType.Exists:
171 { 179 writer.WriteAttributeString("Type", "exists");
172 writer.WriteAttributeString("ExpandEnvironment", "yes"); 180 break;
173 } 181 case WixRegistrySearchType.Value:
182 writer.WriteAttributeString("Type", "value");
174 183
175 // We *always* say this is VariableType="string". If we end up 184 if (symbol.ExpandEnvironmentVariables)
176 // needing to be more specific, we will have to expand the "Format" 185 {
177 // attribute to allow "number" and "version". 186 writer.WriteAttributeString("ExpandEnvironment", "yes");
187 }
178 188
179 writer.WriteAttributeString("VariableType", "string"); 189 // We *always* say this is VariableType="string".
190 // If we end up needing to be more specific,
191 // we will have to actually implement the "Format" attribute.
192 writer.WriteAttributeString("VariableType", "string");
193
194 break;
195 default:
196 throw new NotImplementedException();
180 } 197 }
181 198
182 writer.WriteEndElement(); 199 writer.WriteEndElement();
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/AutomaticallySlipstreamPatchesCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/AutomaticallySlipstreamPatchesCommand.cs
index 75c60e56..064bc62a 100644
--- a/src/wix/WixToolset.Core.Burn/Bundles/AutomaticallySlipstreamPatchesCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bundles/AutomaticallySlipstreamPatchesCommand.cs
@@ -4,7 +4,6 @@ namespace WixToolset.Core.Burn.Bundles
4{ 4{
5 using System; 5 using System;
6 using System.Collections.Generic; 6 using System.Collections.Generic;
7 using System.Diagnostics;
8 using System.Linq; 7 using System.Linq;
9 using WixToolset.Data; 8 using WixToolset.Data;
10 using WixToolset.Data.Symbols; 9 using WixToolset.Data.Symbols;
@@ -43,7 +42,7 @@ namespace WixToolset.Core.Burn.Bundles
43 // Index target ProductCodes and UpgradeCodes for slipstreamed MSPs. 42 // Index target ProductCodes and UpgradeCodes for slipstreamed MSPs.
44 foreach (var symbol in patchTargetCodeSymbols) 43 foreach (var symbol in patchTargetCodeSymbols)
45 { 44 {
46 if (symbol.TargetsProductCode) 45 if (symbol.Type == WixBundlePatchTargetCodeType.ProductCode)
47 { 46 {
48 if (!targetsProductCode.TryGetValue(symbol.TargetCode, out var symbols)) 47 if (!targetsProductCode.TryGetValue(symbol.TargetCode, out var symbols))
49 { 48 {
@@ -53,13 +52,15 @@ namespace WixToolset.Core.Burn.Bundles
53 52
54 symbols.Add(symbol); 53 symbols.Add(symbol);
55 } 54 }
56 else if (symbol.TargetsUpgradeCode) 55 else if (symbol.Type == WixBundlePatchTargetCodeType.UpgradeCode)
57 { 56 {
58 if (!targetsUpgradeCode.TryGetValue(symbol.TargetCode, out var symbols)) 57 if (!targetsUpgradeCode.TryGetValue(symbol.TargetCode, out var symbols))
59 { 58 {
60 symbols = new List<WixBundlePatchTargetCodeSymbol>(); 59 symbols = new List<WixBundlePatchTargetCodeSymbol>();
61 targetsUpgradeCode.Add(symbol.TargetCode, symbols); 60 targetsUpgradeCode.Add(symbol.TargetCode, symbols);
62 } 61 }
62
63 symbols.Add(symbol);
63 } 64 }
64 } 65 }
65 } 66 }
@@ -74,9 +75,6 @@ namespace WixToolset.Core.Burn.Bundles
74 { 75 {
75 foreach (var symbol in symbols) 76 foreach (var symbol in symbols)
76 { 77 {
77 Debug.Assert(symbol.TargetsProductCode);
78 Debug.Assert(!symbol.TargetsUpgradeCode);
79
80 this.TryAddSlipstreamSymbol(slipstreamMspIds, msi, symbol); 78 this.TryAddSlipstreamSymbol(slipstreamMspIds, msi, symbol);
81 } 79 }
82 } 80 }
@@ -85,13 +83,8 @@ namespace WixToolset.Core.Burn.Bundles
85 { 83 {
86 foreach (var symbol in symbols) 84 foreach (var symbol in symbols)
87 { 85 {
88 Debug.Assert(!symbol.TargetsProductCode);
89 Debug.Assert(symbol.TargetsUpgradeCode);
90
91 this.TryAddSlipstreamSymbol(slipstreamMspIds, msi, symbol); 86 this.TryAddSlipstreamSymbol(slipstreamMspIds, msi, symbol);
92 } 87 }
93
94 symbols = null;
95 } 88 }
96 } 89 }
97 } 90 }
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs
index 42e3381a..b993da87 100644
--- a/src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bundles/CreateBootstrapperApplicationManifestCommand.cs
@@ -127,8 +127,8 @@ namespace WixToolset.Core.Burn.Bundles
127 { 127 {
128 writer.WriteStartElement("WixRollbackBoundary"); 128 writer.WriteStartElement("WixRollbackBoundary");
129 writer.WriteAttributeString("Id", rollbackBoundary.Id.Id); 129 writer.WriteAttributeString("Id", rollbackBoundary.Id.Id);
130 writer.WriteAttributeString("Vital", rollbackBoundary.Vital == false ? "no" : "yes"); 130 writer.WriteAttributeString("Vital", rollbackBoundary.Vital ? "yes" : "no");
131 writer.WriteAttributeString("Transaction", rollbackBoundary.Transaction == true ? "yes" : "no"); 131 writer.WriteAttributeString("Transaction", rollbackBoundary.Transaction ? "yes" : "no");
132 132
133 if (!String.IsNullOrEmpty(rollbackBoundary.LogPathVariable)) 133 if (!String.IsNullOrEmpty(rollbackBoundary.LogPathVariable))
134 { 134 {
@@ -155,7 +155,7 @@ namespace WixToolset.Core.Burn.Bundles
155 writer.WriteStartElement("WixPackageProperties"); 155 writer.WriteStartElement("WixPackageProperties");
156 156
157 writer.WriteAttributeString("Package", package.PackageId); 157 writer.WriteAttributeString("Package", package.PackageId);
158 writer.WriteAttributeString("Vital", package.PackageSymbol.Vital == true ? "yes" : "no"); 158 writer.WriteAttributeString("Vital", package.PackageSymbol.Vital ? "yes" : "no");
159 159
160 if (!String.IsNullOrEmpty(package.PackageSymbol.DisplayName)) 160 if (!String.IsNullOrEmpty(package.PackageSymbol.DisplayName))
161 { 161 {
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
index 14d903db..be5fdf0d 100644
--- a/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bundles/CreateBurnManifestCommand.cs
@@ -186,8 +186,8 @@ namespace WixToolset.Core.Burn.Bundles
186 { 186 {
187 writer.WriteStartElement("RollbackBoundary"); 187 writer.WriteStartElement("RollbackBoundary");
188 writer.WriteAttributeString("Id", rollbackBoundary.Id.Id); 188 writer.WriteAttributeString("Id", rollbackBoundary.Id.Id);
189 writer.WriteAttributeString("Vital", rollbackBoundary.Vital == false ? "no" : "yes"); 189 writer.WriteAttributeString("Vital", rollbackBoundary.Vital ? "yes" : "no");
190 writer.WriteAttributeString("Transaction", rollbackBoundary.Transaction == true ? "yes" : "no"); 190 writer.WriteAttributeString("Transaction", rollbackBoundary.Transaction ? "yes" : "no");
191 191
192 if (!String.IsNullOrEmpty(rollbackBoundary.LogPathVariable)) 192 if (!String.IsNullOrEmpty(rollbackBoundary.LogPathVariable))
193 { 193 {
@@ -246,13 +246,14 @@ namespace WixToolset.Core.Burn.Bundles
246 writer.WriteAttributeString("ParentDisplayName", this.BundleSymbol.ParentName); 246 writer.WriteAttributeString("ParentDisplayName", this.BundleSymbol.ParentName);
247 } 247 }
248 248
249 if (this.BundleSymbol.DisableModify) 249 switch (this.BundleSymbol.DisableModify)
250 { 250 {
251 writer.WriteAttributeString("DisableModify", "yes"); 251 case WixBundleModifyType.Disabled:
252 } 252 writer.WriteAttributeString("DisableModify", "yes");
253 else if (this.BundleSymbol.SingleChangeUninstallButton) 253 break;
254 { 254 case WixBundleModifyType.SingleChangeUninstallButton:
255 writer.WriteAttributeString("DisableModify", "button"); 255 writer.WriteAttributeString("DisableModify", "button");
256 break;
256 } 257 }
257 258
258 if (this.BundleSymbol.DisableRemove) 259 if (this.BundleSymbol.DisableRemove)
@@ -352,9 +353,9 @@ namespace WixToolset.Core.Burn.Bundles
352 writer.WriteAttributeString("CacheId", package.PackageSymbol.CacheId); 353 writer.WriteAttributeString("CacheId", package.PackageSymbol.CacheId);
353 writer.WriteAttributeString("InstallSize", Convert.ToString(package.PackageSymbol.InstallSize)); 354 writer.WriteAttributeString("InstallSize", Convert.ToString(package.PackageSymbol.InstallSize));
354 writer.WriteAttributeString("Size", Convert.ToString(package.PackageSymbol.Size)); 355 writer.WriteAttributeString("Size", Convert.ToString(package.PackageSymbol.Size));
355 writer.WriteAttributeString("PerMachine", YesNoDefaultType.Yes == package.PackageSymbol.PerMachine ? "yes" : "no"); 356 writer.WriteAttributeString("PerMachine", package.PackageSymbol.PerMachine.HasValue && package.PackageSymbol.PerMachine.Value ? "yes" : "no");
356 writer.WriteAttributeString("Permanent", package.PackageSymbol.Permanent ? "yes" : "no"); 357 writer.WriteAttributeString("Permanent", package.PackageSymbol.Permanent ? "yes" : "no");
357 writer.WriteAttributeString("Vital", package.PackageSymbol.Vital == false ? "no" : "yes"); 358 writer.WriteAttributeString("Vital", package.PackageSymbol.Vital ? "yes" : "no");
358 359
359 if (null != package.PackageSymbol.RollbackBoundaryRef) 360 if (null != package.PackageSymbol.RollbackBoundaryRef)
360 { 361 {
@@ -389,9 +390,9 @@ namespace WixToolset.Core.Burn.Bundles
389 writer.WriteAttributeString("UninstallArguments", bundlePackage.UninstallCommand); 390 writer.WriteAttributeString("UninstallArguments", bundlePackage.UninstallCommand);
390 writer.WriteAttributeString("RepairArguments", bundlePackage.RepairCommand); 391 writer.WriteAttributeString("RepairArguments", bundlePackage.RepairCommand);
391 writer.WriteAttributeString("SupportsBurnProtocol", bundlePackage.SupportsBurnProtocol ? "yes" : "no"); 392 writer.WriteAttributeString("SupportsBurnProtocol", bundlePackage.SupportsBurnProtocol ? "yes" : "no");
392 writer.WriteAttributeString("Win64", bundlePackage.Win64 ? "yes" : "no"); 393 writer.WriteAttributeString("Win64", package.PackageSymbol.Win64 ? "yes" : "no");
393 394
394 if (!package.PackageSymbol.Attributes.HasFlag(WixBundlePackageAttributes.Visible)) 395 if (!package.PackageSymbol.Visible)
395 { 396 {
396 writer.WriteAttributeString("HideARP", "yes"); 397 writer.WriteAttributeString("HideARP", "yes");
397 } 398 }
@@ -434,15 +435,15 @@ namespace WixToolset.Core.Burn.Bundles
434 // product codes, add the patch list to the overall list. 435 // product codes, add the patch list to the overall list.
435 if (null != targetCodes) 436 if (null != targetCodes)
436 { 437 {
437 if (!mspPackage.TargetUnspecified) 438 foreach (var patchTargetCode in targetCodesByPatch[mspPackage.Id.Id])
438 { 439 {
439 var patchTargetCodes = targetCodesByPatch[mspPackage.Id.Id]; 440 if (patchTargetCode.Type == WixBundlePatchTargetCodeType.Unspecified)
441 {
442 targetCodes = null;
443 break;
444 }
440 445
441 targetCodes.AddRange(patchTargetCodes); 446 targetCodes.Add(patchTargetCode);
442 }
443 else // we have a patch that targets the world, so throw the whole list away.
444 {
445 targetCodes = null;
446 } 447 }
447 } 448 }
448 } 449 }
@@ -611,9 +612,11 @@ namespace WixToolset.Core.Burn.Bundles
611 { 612 {
612 foreach (var targetCode in targetCodes) 613 foreach (var targetCode in targetCodes)
613 { 614 {
615 Debug.Assert(targetCode.Type == WixBundlePatchTargetCodeType.ProductCode || targetCode.Type == WixBundlePatchTargetCodeType.UpgradeCode);
616
614 writer.WriteStartElement("PatchTargetCode"); 617 writer.WriteStartElement("PatchTargetCode");
615 writer.WriteAttributeString("TargetCode", targetCode.TargetCode); 618 writer.WriteAttributeString("TargetCode", targetCode.TargetCode);
616 writer.WriteAttributeString("Product", targetCode.TargetsProductCode ? "yes" : "no"); 619 writer.WriteAttributeString("Product", targetCode.Type == WixBundlePatchTargetCodeType.ProductCode ? "yes" : "no");
617 writer.WriteEndElement(); 620 writer.WriteEndElement();
618 } 621 }
619 } 622 }
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs
index 87c10190..99e1e196 100644
--- a/src/wix/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bundles/OrderPackagesAndRollbackBoundariesCommand.cs
@@ -57,7 +57,7 @@ namespace WixToolset.Core.Burn.Bundles
57 { 57 {
58 if (this.PackageFacades.TryGetValue(groupSymbol.ChildId, out var facade)) 58 if (this.PackageFacades.TryGetValue(groupSymbol.ChildId, out var facade))
59 { 59 {
60 var insideMsiTransaction = lastRollbackBoundary.Transaction ?? false; 60 var insideMsiTransaction = lastRollbackBoundary.Transaction;
61 61
62 if (null != pendingRollbackBoundary) 62 if (null != pendingRollbackBoundary)
63 { 63 {
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/ProcessBundlePackageCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/ProcessBundlePackageCommand.cs
index 986b7605..aed005ba 100644
--- a/src/wix/WixToolset.Core.Burn/Bundles/ProcessBundlePackageCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bundles/ProcessBundlePackageCommand.cs
@@ -82,7 +82,7 @@ namespace WixToolset.Core.Burn.Bundles
82 case BurnCommon.IMAGE_FILE_MACHINE_ARM64: 82 case BurnCommon.IMAGE_FILE_MACHINE_ARM64:
83 case BurnCommon.IMAGE_FILE_MACHINE_IA64: 83 case BurnCommon.IMAGE_FILE_MACHINE_IA64:
84 case BurnCommon.IMAGE_FILE_MACHINE_LOONGARCH64: 84 case BurnCommon.IMAGE_FILE_MACHINE_LOONGARCH64:
85 bundlePackage.Win64 = true; 85 this.Facade.PackageSymbol.Win64 = true;
86 break; 86 break;
87 case BurnCommon.IMAGE_FILE_MACHINE_EBC: 87 case BurnCommon.IMAGE_FILE_MACHINE_EBC:
88 case BurnCommon.IMAGE_FILE_MACHINE_MIPS16: 88 case BurnCommon.IMAGE_FILE_MACHINE_MIPS16:
@@ -123,11 +123,11 @@ namespace WixToolset.Core.Burn.Bundles
123 return; 123 return;
124 } 124 }
125 125
126 if (BurnCommon.BurnV3Namespace == document.DocumentElement.NamespaceURI && !this.Facade.PackageSymbol.Attributes.HasFlag(WixBundlePackageAttributes.Visible)) 126 if (BurnCommon.BurnV3Namespace == document.DocumentElement.NamespaceURI && !this.Facade.PackageSymbol.Visible)
127 { 127 {
128 this.Messaging.Write(BurnBackendWarnings.HiddenBundleNotSupported(packagePayload.SourceLineNumbers, sourcePath)); 128 this.Messaging.Write(BurnBackendWarnings.HiddenBundleNotSupported(packagePayload.SourceLineNumbers, sourcePath));
129 129
130 this.Facade.PackageSymbol.Attributes |= WixBundlePackageAttributes.Visible; 130 this.Facade.PackageSymbol.Visible = true;
131 } 131 }
132 132
133 namespaceManager.AddNamespace("burn", document.DocumentElement.NamespaceURI); 133 namespaceManager.AddNamespace("burn", document.DocumentElement.NamespaceURI);
@@ -135,7 +135,7 @@ namespace WixToolset.Core.Burn.Bundles
135 var arpElement = document.SelectSingleNode("/burn:BurnManifest/burn:Registration/burn:Arp", namespaceManager) as XmlElement; 135 var arpElement = document.SelectSingleNode("/burn:BurnManifest/burn:Registration/burn:Arp", namespaceManager) as XmlElement;
136 136
137 var perMachine = registrationElement.GetAttribute("PerMachine") == "yes"; 137 var perMachine = registrationElement.GetAttribute("PerMachine") == "yes";
138 this.Facade.PackageSymbol.PerMachine = perMachine ? YesNoDefaultType.Yes : YesNoDefaultType.No; 138 this.Facade.PackageSymbol.PerMachine = perMachine;
139 139
140 var version = registrationElement.GetAttribute("Version"); 140 var version = registrationElement.GetAttribute("Version");
141 packagePayload.Version = version; 141 packagePayload.Version = version;
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs
index c2bceb32..4ca3a730 100644
--- a/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsiPackageCommand.cs
@@ -4,6 +4,7 @@ namespace WixToolset.Core.Burn.Bundles
4{ 4{
5 using System; 5 using System;
6 using System.Collections.Generic; 6 using System.Collections.Generic;
7 using System.Diagnostics;
7 using System.Globalization; 8 using System.Globalization;
8 using System.IO; 9 using System.IO;
9 using System.Linq; 10 using System.Linq;
@@ -88,7 +89,7 @@ namespace WixToolset.Core.Burn.Bundles
88 // in MSI 4.5 and below, if this bit is 0, elevation is required. 89 // in MSI 4.5 and below, if this bit is 0, elevation is required.
89 var perMachine = (0 == (fileAndElevateFlags & 8)); 90 var perMachine = (0 == (fileAndElevateFlags & 8));
90 91
91 this.Facade.PackageSymbol.PerMachine = perMachine ? YesNoDefaultType.Yes : YesNoDefaultType.No; 92 this.Facade.PackageSymbol.PerMachine = perMachine;
92 this.Facade.PackageSymbol.Win64 = this.IsWin64(packagePayload.SourceLineNumbers, sourcePath, platformsAndLanguages); 93 this.Facade.PackageSymbol.Win64 = this.IsWin64(packagePayload.SourceLineNumbers, sourcePath, platformsAndLanguages);
93 } 94 }
94 95
@@ -177,7 +178,7 @@ namespace WixToolset.Core.Burn.Bundles
177 this.CreateRelatedPackages(db); 178 this.CreateRelatedPackages(db);
178 179
179 // If feature selection is enabled, represent the Feature table in the manifest. 180 // If feature selection is enabled, represent the Feature table in the manifest.
180 if ((msiPackage.Attributes & WixBundleMsiPackageAttributes.EnableFeatureSelection) == WixBundleMsiPackageAttributes.EnableFeatureSelection) 181 if (msiPackage.EnableFeatureSelection)
181 { 182 {
182 this.CreateMsiFeatures(db); 183 this.CreateMsiFeatures(db);
183 } 184 }
@@ -240,13 +241,16 @@ namespace WixToolset.Core.Burn.Bundles
240 241
241 private void SetPerMachineAppropriately(string allusers, WixBundleMsiPackageSymbol msiPackage, string sourcePath) 242 private void SetPerMachineAppropriately(string allusers, WixBundleMsiPackageSymbol msiPackage, string sourcePath)
242 { 243 {
244 Debug.Assert(this.Facade.PackageSymbol.PerMachine.HasValue);
245 var perMachine = this.Facade.PackageSymbol.PerMachine.Value;
246
243 // Can ignore ALLUSERS from MsiProperties because it is not allowed there. 247 // Can ignore ALLUSERS from MsiProperties because it is not allowed there.
244 if (msiPackage.ForcePerMachine) 248 if (msiPackage.ForcePerMachine)
245 { 249 {
246 if (YesNoDefaultType.No == this.Facade.PackageSymbol.PerMachine) 250 if (!perMachine)
247 { 251 {
248 this.Messaging.Write(WarningMessages.PerUserButForcingPerMachine(this.Facade.PackageSymbol.SourceLineNumbers, sourcePath)); 252 this.Messaging.Write(WarningMessages.PerUserButForcingPerMachine(this.Facade.PackageSymbol.SourceLineNumbers, sourcePath));
249 this.Facade.PackageSymbol.PerMachine = YesNoDefaultType.Yes; // ensure that we think the package is per-machine. 253 this.Facade.PackageSymbol.PerMachine = true; // ensure that we think the package is per-machine.
250 } 254 }
251 255
252 // Force ALLUSERS=1 via the MSI command-line. 256 // Force ALLUSERS=1 via the MSI command-line.
@@ -257,22 +261,22 @@ namespace WixToolset.Core.Burn.Bundles
257 if (String.IsNullOrEmpty(allusers)) 261 if (String.IsNullOrEmpty(allusers))
258 { 262 {
259 // Not forced per-machine and no ALLUSERS property, flip back to per-user. 263 // Not forced per-machine and no ALLUSERS property, flip back to per-user.
260 if (YesNoDefaultType.Yes == this.Facade.PackageSymbol.PerMachine) 264 if (perMachine)
261 { 265 {
262 this.Messaging.Write(WarningMessages.ImplicitlyPerUser(this.Facade.PackageSymbol.SourceLineNumbers, sourcePath)); 266 this.Messaging.Write(WarningMessages.ImplicitlyPerUser(this.Facade.PackageSymbol.SourceLineNumbers, sourcePath));
263 this.Facade.PackageSymbol.PerMachine = YesNoDefaultType.No; 267 this.Facade.PackageSymbol.PerMachine = false;
264 } 268 }
265 } 269 }
266 else if (allusers.Equals("1", StringComparison.Ordinal)) 270 else if (allusers.Equals("1", StringComparison.Ordinal))
267 { 271 {
268 if (YesNoDefaultType.No == this.Facade.PackageSymbol.PerMachine) 272 if (!perMachine)
269 { 273 {
270 this.Messaging.Write(ErrorMessages.PerUserButAllUsersEquals1(this.Facade.PackageSymbol.SourceLineNumbers, sourcePath)); 274 this.Messaging.Write(ErrorMessages.PerUserButAllUsersEquals1(this.Facade.PackageSymbol.SourceLineNumbers, sourcePath));
271 } 275 }
272 } 276 }
273 else if (allusers.Equals("2", StringComparison.Ordinal)) 277 else if (allusers.Equals("2", StringComparison.Ordinal))
274 { 278 {
275 this.Messaging.Write(WarningMessages.DiscouragedAllUsersValue(this.Facade.PackageSymbol.SourceLineNumbers, sourcePath, (YesNoDefaultType.Yes == this.Facade.PackageSymbol.PerMachine) ? "machine" : "user")); 279 this.Messaging.Write(WarningMessages.DiscouragedAllUsersValue(this.Facade.PackageSymbol.SourceLineNumbers, sourcePath, perMachine ? "machine" : "user"));
276 } 280 }
277 else 281 else
278 { 282 {
@@ -287,7 +291,7 @@ namespace WixToolset.Core.Burn.Bundles
287 if (!msiPropertyNames.Contains("ARPSYSTEMCOMPONENT")) 291 if (!msiPropertyNames.Contains("ARPSYSTEMCOMPONENT"))
288 { 292 {
289 var alreadyVisible = String.IsNullOrEmpty(systemComponent); 293 var alreadyVisible = String.IsNullOrEmpty(systemComponent);
290 var visible = (this.Facade.PackageSymbol.Attributes & WixBundlePackageAttributes.Visible) == WixBundlePackageAttributes.Visible; 294 var visible = this.Facade.PackageSymbol.Visible;
291 295
292 // If not already set to the correct visibility. 296 // If not already set to the correct visibility.
293 if (alreadyVisible != visible) 297 if (alreadyVisible != visible)
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs
index 5f431b38..d306957e 100644
--- a/src/wix/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bundles/ProcessMspPackageCommand.cs
@@ -97,7 +97,7 @@ namespace WixToolset.Core.Burn.Bundles
97 97
98 private void ProcessPatchXml(WixBundlePayloadSymbol packagePayload, WixBundleMspPackageSymbol mspPackage, string sourcePath) 98 private void ProcessPatchXml(WixBundlePayloadSymbol packagePayload, WixBundleMspPackageSymbol mspPackage, string sourcePath)
99 { 99 {
100 var uniqueTargetCodes = new HashSet<string>(); 100 var uniqueTargetCodes = new Dictionary<string, WixBundlePatchTargetCodeSymbol>();
101 101
102 var patchXml = Installer.ExtractPatchXml(sourcePath); 102 var patchXml = Installer.ExtractPatchXml(sourcePath);
103 103
@@ -112,35 +112,42 @@ namespace WixToolset.Core.Burn.Bundles
112 { 112 {
113 // If this patch targets a product code, this is the best case. 113 // If this patch targets a product code, this is the best case.
114 var targetCodeElement = node.SelectSingleNode("p:TargetProductCode", nsmgr); 114 var targetCodeElement = node.SelectSingleNode("p:TargetProductCode", nsmgr);
115 var attributes = WixBundlePatchTargetCodeAttributes.None; 115 WixBundlePatchTargetCodeType type;
116 116
117 if (ProcessMspPackageCommand.TargetsCode(targetCodeElement)) 117 if (ProcessMspPackageCommand.TargetsCode(targetCodeElement))
118 { 118 {
119 attributes = WixBundlePatchTargetCodeAttributes.TargetsProductCode; 119 type = WixBundlePatchTargetCodeType.ProductCode;
120 } 120 }
121 else // maybe targets an upgrade code? 121 else // maybe targets an upgrade code?
122 { 122 {
123 targetCodeElement = node.SelectSingleNode("p:UpgradeCode", nsmgr); 123 targetCodeElement = node.SelectSingleNode("p:UpgradeCode", nsmgr);
124 if (ProcessMspPackageCommand.TargetsCode(targetCodeElement)) 124 if (ProcessMspPackageCommand.TargetsCode(targetCodeElement))
125 { 125 {
126 attributes = WixBundlePatchTargetCodeAttributes.TargetsUpgradeCode; 126 type = WixBundlePatchTargetCodeType.UpgradeCode;
127 } 127 }
128 else // this patch targets an unknown number of products 128 else // this patch targets an unknown number of products
129 { 129 {
130 mspPackage.Attributes |= WixBundleMspPackageAttributes.TargetUnspecified; 130 type = WixBundlePatchTargetCodeType.Unspecified;
131 } 131 }
132 } 132 }
133 133
134 var targetCode = targetCodeElement.InnerText; 134 var targetCode = targetCodeElement.InnerText;
135 135
136 if (uniqueTargetCodes.Add(targetCode)) 136 if (!uniqueTargetCodes.TryGetValue(targetCode, out var existing))
137 { 137 {
138 this.Section.AddSymbol(new WixBundlePatchTargetCodeSymbol(packagePayload.SourceLineNumbers) 138 var symbol = this.Section.AddSymbol(new WixBundlePatchTargetCodeSymbol(packagePayload.SourceLineNumbers)
139 { 139 {
140 PackageRef = packagePayload.Id.Id, 140 PackageRef = packagePayload.Id.Id,
141 TargetCode = targetCode, 141 TargetCode = targetCode,
142 Attributes = attributes 142 Attributes = 0,
143 Type = type,
143 }); 144 });
145
146 uniqueTargetCodes.Add(targetCode, symbol);
147 }
148 else if (type == WixBundlePatchTargetCodeType.Unspecified)
149 {
150 existing.Type = type;
144 } 151 }
145 } 152 }
146 153
@@ -178,6 +185,9 @@ namespace WixToolset.Core.Burn.Bundles
178 } 185 }
179 } 186 }
180 187
181 private static bool TargetsCode(XmlNode node) => "true" == node?.Attributes["Validate"]?.Value; 188 private static bool TargetsCode(XmlNode node)
189 {
190 return "true" == node?.Attributes["Validate"]?.Value;
191 }
182 } 192 }
183} 193}
diff --git a/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsuPackageCommand.cs b/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsuPackageCommand.cs
index af4ab3a8..4c61f6d7 100644
--- a/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsuPackageCommand.cs
+++ b/src/wix/WixToolset.Core.Burn/Bundles/ProcessMsuPackageCommand.cs
@@ -31,7 +31,7 @@ namespace WixToolset.Core.Burn.Bundles
31 this.Facade.PackageSymbol.CacheId = packagePayload.Hash; 31 this.Facade.PackageSymbol.CacheId = packagePayload.Hash;
32 } 32 }
33 33
34 this.Facade.PackageSymbol.PerMachine = YesNoDefaultType.Yes; // MSUs are always per-machine. 34 this.Facade.PackageSymbol.PerMachine = true; // MSUs are always per-machine.
35 } 35 }
36 } 36 }
37} 37}
diff --git a/src/wix/WixToolset.Core/Compiler_Bundle.cs b/src/wix/WixToolset.Core/Compiler_Bundle.cs
index 2632a346..ab405684 100644
--- a/src/wix/WixToolset.Core/Compiler_Bundle.cs
+++ b/src/wix/WixToolset.Core/Compiler_Bundle.cs
@@ -117,6 +117,7 @@ namespace WixToolset.Core
117 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node); 117 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
118 string copyright = null; 118 string copyright = null;
119 string aboutUrl = null; 119 string aboutUrl = null;
120 var modifyType = WixBundleModifyType.Allowed;
120 var compressed = YesNoDefaultType.Default; 121 var compressed = YesNoDefaultType.Default;
121 WixBundleAttributes attributes = 0; 122 WixBundleAttributes attributes = 0;
122 WixBundleCommandLineVariables commandLineVariables = WixBundleCommandLineVariables.UpperCase; 123 WixBundleCommandLineVariables commandLineVariables = WixBundleCommandLineVariables.UpperCase;
@@ -176,12 +177,13 @@ namespace WixToolset.Core
176 switch (value) 177 switch (value)
177 { 178 {
178 case "button": 179 case "button":
179 attributes |= WixBundleAttributes.SingleChangeUninstallButton; 180 modifyType = WixBundleModifyType.SingleChangeUninstallButton;
180 break; 181 break;
181 case "yes": 182 case "yes":
182 attributes |= WixBundleAttributes.DisableModify; 183 modifyType = WixBundleModifyType.Disabled;
183 break; 184 break;
184 case "no": 185 case "no":
186 modifyType = WixBundleModifyType.Allowed;
185 break; 187 break;
186 default: 188 default:
187 this.Core.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, value, "button", "yes", "no")); 189 this.Core.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, value, "button", "yes", "no"));
@@ -415,6 +417,7 @@ namespace WixToolset.Core
415 UpgradeCode = upgradeCode, 417 UpgradeCode = upgradeCode,
416 Version = version, 418 Version = version,
417 Copyright = copyright, 419 Copyright = copyright,
420 DisableModify = modifyType,
418 InProgressName = inProgressName, 421 InProgressName = inProgressName,
419 Name = name, 422 Name = name,
420 Manufacturer = manufacturer, 423 Manufacturer = manufacturer,
@@ -2432,16 +2435,16 @@ namespace WixToolset.Core
2432 DisplayName = displayName, 2435 DisplayName = displayName,
2433 LogPathVariable = logPathVariable, 2436 LogPathVariable = logPathVariable,
2434 RollbackLogPathVariable = rollbackPathVariable, 2437 RollbackLogPathVariable = rollbackPathVariable,
2438 Vital = vital == YesNoType.Yes,
2435 }); 2439 });
2436 2440
2437 if (YesNoType.NotSet != vital) 2441 if (perMachine == YesNoDefaultType.Yes)
2438 { 2442 {
2439 chainPackageSymbol.Vital = (vital == YesNoType.Yes); 2443 chainPackageSymbol.PerMachine = true;
2440 } 2444 }
2441 2445 else if (perMachine == YesNoDefaultType.No)
2442 if (YesNoDefaultType.NotSet != perMachine)
2443 { 2446 {
2444 chainPackageSymbol.PerMachine = perMachine; 2447 chainPackageSymbol.PerMachine = false;
2445 } 2448 }
2446 2449
2447 if (installSize.HasValue) 2450 if (installSize.HasValue)
@@ -2918,21 +2921,15 @@ namespace WixToolset.Core
2918 { 2921 {
2919 this.Core.AddSymbol(new WixChainItemSymbol(sourceLineNumbers, id)); 2922 this.Core.AddSymbol(new WixChainItemSymbol(sourceLineNumbers, id));
2920 2923
2921 var rollbackBoundary = this.Core.AddSymbol(new WixBundleRollbackBoundarySymbol(sourceLineNumbers, id)); 2924 var rollbackBoundary = this.Core.AddSymbol(new WixBundleRollbackBoundarySymbol(sourceLineNumbers, id)
2922
2923 if (YesNoType.NotSet != vital)
2924 { 2925 {
2925 rollbackBoundary.Vital = (vital == YesNoType.Yes); 2926 Transaction = transaction == YesNoType.Yes,
2926 } 2927 Vital = vital == YesNoType.Yes,
2928 });
2927 2929
2928 if (YesNoType.NotSet != transaction) 2930 if (logPathVariable != null)
2929 { 2931 {
2930 rollbackBoundary.Transaction = (transaction == YesNoType.Yes); 2932 rollbackBoundary.LogPathVariable = logPathVariable;
2931
2932 if (logPathVariable != null)
2933 {
2934 rollbackBoundary.LogPathVariable = logPathVariable;
2935 }
2936 } 2933 }
2937 2934
2938 this.CreateChainPackageMetaRows(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.Package, id.Id, previousType, previousId, null); 2935 this.CreateChainPackageMetaRows(sourceLineNumbers, parentType, parentId, ComplexReferenceChildType.Package, id.Id, previousType, previousId, null);