aboutsummaryrefslogtreecommitdiff
path: root/src/WixToolset.Core
diff options
context:
space:
mode:
authorRob Mensching <rob@firegiant.com>2021-02-25 09:58:20 -0800
committerRob Mensching <rob@firegiant.com>2021-02-27 07:47:08 -0800
commit760fb810ba5ecc3c6ce752a9bfa3755f7b7c0f6a (patch)
tree3ad06ffe520f31142e23ce9e752473110d232ec5 /src/WixToolset.Core
parent4536440f8d76346bcd120fe9e1410e428f855ee9 (diff)
downloadwix-760fb810ba5ecc3c6ce752a9bfa3755f7b7c0f6a.tar.gz
wix-760fb810ba5ecc3c6ce752a9bfa3755f7b7c0f6a.tar.bz2
wix-760fb810ba5ecc3c6ce752a9bfa3755f7b7c0f6a.zip
Absorb Tag.wixext into Core as SoftwareTag element
Resolves wixtoolset/issues#5949
Diffstat (limited to 'src/WixToolset.Core')
-rw-r--r--src/WixToolset.Core/Bind/FileFacade.cs2
-rw-r--r--src/WixToolset.Core/CompilerCore.cs1
-rw-r--r--src/WixToolset.Core/CompilerErrors.cs30
-rw-r--r--src/WixToolset.Core/Compiler_2.cs3
-rw-r--r--src/WixToolset.Core/Compiler_Bundle.cs3
-rw-r--r--src/WixToolset.Core/Compiler_Patch.cs3
-rw-r--r--src/WixToolset.Core/Compiler_Tag.cs315
7 files changed, 355 insertions, 2 deletions
diff --git a/src/WixToolset.Core/Bind/FileFacade.cs b/src/WixToolset.Core/Bind/FileFacade.cs
index ec4e9725..9705cd01 100644
--- a/src/WixToolset.Core/Bind/FileFacade.cs
+++ b/src/WixToolset.Core/Bind/FileFacade.cs
@@ -125,7 +125,7 @@ namespace WixToolset.Core.Bind
125 125
126 public SourceLineNumber SourceLineNumber => this.FileRow == null ? this.FileSymbol.SourceLineNumbers : this.FileRow.SourceLineNumbers; 126 public SourceLineNumber SourceLineNumber => this.FileRow == null ? this.FileSymbol.SourceLineNumbers : this.FileRow.SourceLineNumbers;
127 127
128 public string SourcePath => this.FileRow == null ? this.FileSymbol.Source.Path : this.FileRow.Source; 128 public string SourcePath => this.FileRow == null ? this.FileSymbol.Source?.Path : this.FileRow.Source;
129 129
130 public bool Compressed => this.FileRow == null ? (this.FileSymbol.Attributes & FileSymbolAttributes.Compressed) == FileSymbolAttributes.Compressed : (this.FileRow.Attributes & WindowsInstallerConstants.MsidbFileAttributesCompressed) == WindowsInstallerConstants.MsidbFileAttributesCompressed; 130 public bool Compressed => this.FileRow == null ? (this.FileSymbol.Attributes & FileSymbolAttributes.Compressed) == FileSymbolAttributes.Compressed : (this.FileRow.Attributes & WindowsInstallerConstants.MsidbFileAttributesCompressed) == WindowsInstallerConstants.MsidbFileAttributesCompressed;
131 131
diff --git a/src/WixToolset.Core/CompilerCore.cs b/src/WixToolset.Core/CompilerCore.cs
index 1f6d6329..53e0f3fc 100644
--- a/src/WixToolset.Core/CompilerCore.cs
+++ b/src/WixToolset.Core/CompilerCore.cs
@@ -6,7 +6,6 @@ namespace WixToolset.Core
6 using System.Collections; 6 using System.Collections;
7 using System.Collections.Generic; 7 using System.Collections.Generic;
8 using System.Diagnostics; 8 using System.Diagnostics;
9 using System.Diagnostics.CodeAnalysis;
10 using System.Globalization; 9 using System.Globalization;
11 using System.Reflection; 10 using System.Reflection;
12 using System.Text; 11 using System.Text;
diff --git a/src/WixToolset.Core/CompilerErrors.cs b/src/WixToolset.Core/CompilerErrors.cs
new file mode 100644
index 00000000..da64c376
--- /dev/null
+++ b/src/WixToolset.Core/CompilerErrors.cs
@@ -0,0 +1,30 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Core
4{
5 using WixToolset.Data;
6
7 internal static class CompilerErrors
8 {
9 public static Message IllegalName(SourceLineNumber sourceLineNumbers, string parentElement, string name)
10 {
11 return Message(sourceLineNumbers, Ids.IllegalName, "The Tag/@Name attribute value, '{1}', contains invalid filename identifiers. The Tag/@Name may have defaulted from the {0}/@Name attrbute. If so, use the Tag/@Name attribute to provide a valid filename. Any character except for the follow may be used: \\ ? | > < : / * \".", parentElement, name);
12 }
13
14 public static Message ExampleRegid(SourceLineNumber sourceLineNumbers, string regid)
15 {
16 return Message(sourceLineNumbers, Ids.ExampleRegid, "Regid '{0}' is a placeholder that must be replaced with an appropriate value for your installation. Use the simplified URI for your organization or project.", regid);
17 }
18
19 private static Message Message(SourceLineNumber sourceLineNumber, Ids id, string format, params object[] args)
20 {
21 return new Message(sourceLineNumber, MessageLevel.Error, (int)id, format, args);
22 }
23
24 public enum Ids
25 {
26 IllegalName = 6601,
27 ExampleRegid = 6602,
28 }
29 }
30}
diff --git a/src/WixToolset.Core/Compiler_2.cs b/src/WixToolset.Core/Compiler_2.cs
index 09d56e49..295392c8 100644
--- a/src/WixToolset.Core/Compiler_2.cs
+++ b/src/WixToolset.Core/Compiler_2.cs
@@ -316,6 +316,9 @@ namespace WixToolset.Core
316 string parentName = null; 316 string parentName = null;
317 this.ParseSFPCatalogElement(child, ref parentName); 317 this.ParseSFPCatalogElement(child, ref parentName);
318 break; 318 break;
319 case "SoftwareTag":
320 this.ParsePackageTagElement(child);
321 break;
319 case "SummaryInformation": 322 case "SummaryInformation":
320 this.ParseSummaryInformationElement(child, ref isCodepageSet, ref isPackageNameSet, ref isKeywordsSet, ref isPackageAuthorSet); 323 this.ParseSummaryInformationElement(child, ref isCodepageSet, ref isPackageNameSet, ref isKeywordsSet, ref isPackageAuthorSet);
321 break; 324 break;
diff --git a/src/WixToolset.Core/Compiler_Bundle.cs b/src/WixToolset.Core/Compiler_Bundle.cs
index 7a386de7..1ee09166 100644
--- a/src/WixToolset.Core/Compiler_Bundle.cs
+++ b/src/WixToolset.Core/Compiler_Bundle.cs
@@ -346,6 +346,9 @@ namespace WixToolset.Core
346 case "SetVariableRef": 346 case "SetVariableRef":
347 this.ParseSimpleRefElement(child, SymbolDefinitions.WixSetVariable); 347 this.ParseSimpleRefElement(child, SymbolDefinitions.WixSetVariable);
348 break; 348 break;
349 case "SoftwareTag":
350 this.ParseBundleTagElement(child);
351 break;
349 case "Update": 352 case "Update":
350 this.ParseUpdateElement(child); 353 this.ParseUpdateElement(child);
351 break; 354 break;
diff --git a/src/WixToolset.Core/Compiler_Patch.cs b/src/WixToolset.Core/Compiler_Patch.cs
index 2fb1affb..83737c43 100644
--- a/src/WixToolset.Core/Compiler_Patch.cs
+++ b/src/WixToolset.Core/Compiler_Patch.cs
@@ -410,6 +410,9 @@ namespace WixToolset.Core
410 case "PropertyRef": 410 case "PropertyRef":
411 this.ParsePatchChildRefElement(child, "Property"); 411 this.ParsePatchChildRefElement(child, "Property");
412 break; 412 break;
413 case "SoftwareTagRef":
414 this.ParseTagRefElement(child);
415 break;
413 case "UIRef": 416 case "UIRef":
414 this.ParsePatchChildRefElement(child, "WixUI"); 417 this.ParsePatchChildRefElement(child, "WixUI");
415 break; 418 break;
diff --git a/src/WixToolset.Core/Compiler_Tag.cs b/src/WixToolset.Core/Compiler_Tag.cs
new file mode 100644
index 00000000..2b3523c8
--- /dev/null
+++ b/src/WixToolset.Core/Compiler_Tag.cs
@@ -0,0 +1,315 @@
1// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3namespace WixToolset.Core
4{
5 using System;
6 using System.Xml.Linq;
7 using WixToolset.Data;
8 using WixToolset.Data.Symbols;
9
10 /// <summary>
11 /// Compiler of the WiX toolset.
12 /// </summary>
13 internal partial class Compiler : ICompiler
14 {
15 /// <summary>
16 /// Parses a Tag element for Software Id Tag registration under a Bundle element.
17 /// </summary>
18 /// <param name="node">The element to parse.</param>
19 private void ParseBundleTagElement(XElement node)
20 {
21 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
22 string name = null;
23 string regid = null;
24 string installPath = null;
25
26 foreach (var attrib in node.Attributes())
27 {
28 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
29 {
30 switch (attrib.Name.LocalName)
31 {
32 case "Name":
33 name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false);
34 break;
35 case "Regid":
36 regid = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
37 break;
38 case "InstallDirectory":
39 case "Bitness":
40 this.Core.Write(ErrorMessages.ExpectedParentWithAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Package"));
41 break;
42 case "InstallPath":
43 installPath = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
44 break;
45 default:
46 this.Core.UnexpectedAttribute(node, attrib);
47 break;
48 }
49 }
50 else
51 {
52 this.Core.ParseExtensionAttribute(node, attrib);
53 }
54 }
55
56 this.Core.ParseForExtensionElements(node);
57
58 if (String.IsNullOrEmpty(name))
59 {
60 name = node.Parent?.Attribute("Name")?.Value;
61
62 if (String.IsNullOrEmpty(name))
63 {
64 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
65 }
66 }
67
68 if (!String.IsNullOrEmpty(name) && !this.Core.IsValidLongFilename(name))
69 {
70 this.Core.Write(CompilerErrors.IllegalName(sourceLineNumbers, node.Name.LocalName, name));
71 }
72
73 if (String.IsNullOrEmpty(regid))
74 {
75 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Regid"));
76 }
77 else if (regid.Equals("example.com", StringComparison.OrdinalIgnoreCase))
78 {
79 this.Core.Write(CompilerErrors.ExampleRegid(sourceLineNumbers, regid));
80 }
81
82 if (String.IsNullOrEmpty(installPath))
83 {
84 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "InstallPath"));
85 }
86
87 if (!this.Core.EncounteredError)
88 {
89 this.Core.AddSymbol(new WixBundleTagSymbol(sourceLineNumbers)
90 {
91 Filename = String.Concat(name, ".swidtag"),
92 Regid = regid,
93 Name = name,
94 InstallPath = installPath
95 });
96 }
97 }
98
99 /// <summary>
100 /// Parses a Tag element for Software Id Tag registration under a Package element.
101 /// </summary>
102 /// <param name="node">The element to parse.</param>
103 private void ParsePackageTagElement(XElement node)
104 {
105 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
106 Identifier id = null;
107 string name = null;
108 string regid = null;
109 string feature = null;
110 string installDirectory = null;
111 var win64 = this.Context.IsCurrentPlatform64Bit;
112
113 foreach (var attrib in node.Attributes())
114 {
115 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
116 {
117 switch (attrib.Name.LocalName)
118 {
119 case "Id":
120 id = this.Core.GetAttributeIdentifier(sourceLineNumbers, attrib);
121 break;
122 case "Name":
123 name = this.Core.GetAttributeLongFilename(sourceLineNumbers, attrib, false);
124 break;
125 case "Regid":
126 regid = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
127 break;
128 case "Feature":
129 feature = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
130 break;
131 case "InstallDirectory":
132 installDirectory = this.Core.GetAttributeIdentifierValue(sourceLineNumbers, attrib);
133 break;
134 case "InstallPath":
135 this.Core.Write(ErrorMessages.ExpectedParentWithAttribute(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, "Bundle"));
136 break;
137 case "Bitness":
138 var bitnessValue = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
139 switch (bitnessValue)
140 {
141 case "always32":
142 win64 = false;
143 break;
144 case "always64":
145 win64 = true;
146 break;
147 case "default":
148 case "":
149 break;
150 default:
151 this.Core.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, node.Name.LocalName, attrib.Name.LocalName, bitnessValue, "default", "always32", "always64"));
152 break;
153 }
154 break;
155 default:
156 this.Core.UnexpectedAttribute(node, attrib);
157 break;
158 }
159 }
160 else
161 {
162 this.Core.ParseExtensionAttribute(node, attrib);
163 }
164 }
165
166 this.Core.ParseForExtensionElements(node);
167
168 if (String.IsNullOrEmpty(name))
169 {
170 name = node.Parent?.Attribute("Name")?.Value;
171
172 if (String.IsNullOrEmpty(name))
173 {
174 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Name"));
175 }
176 }
177
178 if (!String.IsNullOrEmpty(name) && !this.Core.IsValidLongFilename(name))
179 {
180 this.Core.Write(CompilerErrors.IllegalName(sourceLineNumbers, node.Name.LocalName, name));
181 }
182
183 if (String.IsNullOrEmpty(regid))
184 {
185 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Regid"));
186 }
187 else if (regid.Equals("example.com", StringComparison.OrdinalIgnoreCase))
188 {
189 this.Core.Write(CompilerErrors.ExampleRegid(sourceLineNumbers, regid));
190 return;
191 }
192 else if (id == null)
193 {
194 id = this.CreateTagId(regid);
195 }
196
197 if (String.IsNullOrEmpty(installDirectory))
198 {
199 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "InstallDirectory"));
200 }
201
202 if (!this.Core.EncounteredError)
203 {
204 var fileName = String.Concat(name, ".swidtag");
205
206 this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Directory, installDirectory);
207 this.Core.AddSymbol(new DirectorySymbol(sourceLineNumbers, id)
208 {
209 Name = "swidtag",
210 ParentDirectoryRef = installDirectory,
211 ComponentGuidGenerationSeed = "4BAD0C8B-3AF0-BFE3-CC83-094749A1C4B1"
212 });
213
214 this.Core.AddSymbol(new ComponentSymbol(sourceLineNumbers, id)
215 {
216 ComponentId = "*",
217 DirectoryRef = id.Id,
218 KeyPath = id.Id,
219 KeyPathType = ComponentKeyPathType.File,
220 Location = ComponentLocation.LocalOnly,
221 Win64 = win64
222 });
223
224 this.Core.AddSymbol(new FileSymbol(sourceLineNumbers, id)
225 {
226 ComponentRef = id.Id,
227 Name = fileName,
228 DiskId = 1,
229 Attributes = FileSymbolAttributes.ReadOnly,
230 });
231
232 if (!String.IsNullOrEmpty(feature))
233 {
234 this.Core.CreateSimpleReference(sourceLineNumbers, SymbolDefinitions.Feature, feature);
235 }
236 else
237 {
238 feature = "WixSwidTag";
239 this.Core.AddSymbol(new FeatureSymbol(sourceLineNumbers, new Identifier(AccessModifier.Private, feature))
240 {
241 Title = "ISO/IEC 19770-2",
242 Level = 1,
243 InstallDefault = FeatureInstallDefault.Local,
244 Display = 0,
245 DisallowAdvertise = true,
246 DisallowAbsent = true,
247 });
248 }
249 this.Core.CreateComplexReference(sourceLineNumbers, ComplexReferenceParentType.Feature, feature, null, ComplexReferenceChildType.Component, id.Id, true);
250
251 this.Core.EnsureTable(sourceLineNumbers, "SoftwareIdentificationTag");
252 this.Core.AddSymbol(new WixProductTagSymbol(sourceLineNumbers, id)
253 {
254 FileRef = id.Id,
255 Regid = regid,
256 Name = name
257 });
258 }
259 }
260
261 /// <summary>
262 /// Parses a TagRef element for Software Id Tag registration under a PatchFamily element.
263 /// </summary>
264 /// <param name="node">The element to parse.</param>
265 private void ParseTagRefElement(XElement node)
266 {
267 var sourceLineNumbers = Preprocessor.GetSourceLineNumbers(node);
268 string regid = null;
269
270 foreach (var attrib in node.Attributes())
271 {
272 if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || CompilerCore.WixNamespace == attrib.Name.Namespace)
273 {
274 switch (attrib.Name.LocalName)
275 {
276 case "Regid":
277 regid = this.Core.GetAttributeValue(sourceLineNumbers, attrib);
278 break;
279 default:
280 this.Core.UnexpectedAttribute(node, attrib);
281 break;
282 }
283 }
284 else
285 {
286 this.Core.ParseExtensionAttribute(node, attrib);
287 }
288 }
289
290 this.Core.ParseForExtensionElements(node);
291
292 if (String.IsNullOrEmpty(regid))
293 {
294 this.Core.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, node.Name.LocalName, "Regid"));
295 }
296 else if (regid.Equals("example.com", StringComparison.OrdinalIgnoreCase))
297 {
298 this.Core.Write(CompilerErrors.ExampleRegid(sourceLineNumbers, regid));
299 }
300
301 if (!this.Core.EncounteredError)
302 {
303 var id = this.CreateTagId(regid);
304
305 this.Core.AddSymbol(new WixPatchRefSymbol(sourceLineNumbers, id)
306 {
307 Table = SymbolDefinitions.Component.Name,
308 PrimaryKeys = id.Id
309 });
310 }
311 }
312
313 private Identifier CreateTagId(string regid) => this.Core.CreateIdentifier("tag", regid, ".product.tag");
314 }
315}