Modernize FirewallCompiler and tuples.
Sean Hall committed
Apr 9, 2020 at 09:01 UTC
2427be20a103957f204b753db45ee89ad636bb08
9 files changed
+112
-92
src/test/WixToolsetTest.Firewall/FirewallExtensionFixture.cs
+1
-1
@@ -20,7 +20,7 @@ namespace WixToolsetTest.Firewall
20
Assert.Equal(new[]
21
{
22
"WixFirewallException:ExampleFirewall\texample\t*\t42\t6\t\t0\t2147483647\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo\tAn example firewall",
23
- }, results.OrderBy(s => s).ToArray());
23
+ }, results);
24
}
25
26
private static void Build(string[] args)
src/wixext/FirewallCompiler.cs
+24
-26
@@ -28,8 +28,8 @@ namespace WixToolset.Firewall
28
switch (parentElement.Name.LocalName)
29
{
30
case "File":
31
- string fileId = context["FileId"];
32
- string fileComponentId = context["ComponentId"];
31
+ var fileId = context["FileId"];
32
+ var fileComponentId = context["ComponentId"];
33
34
switch (element.Name.LocalName)
35
{
@@ -42,7 +42,7 @@ namespace WixToolset.Firewall
42
}
43
break;
44
case "Component":
45
- string componentId = context["ComponentId"];
45
+ var componentId = context["ComponentId"];
46
47
switch (element.Name.LocalName)
48
{
@@ -68,22 +68,20 @@ namespace WixToolset.Firewall
68
/// <param name="fileId">The file identifier of the parent element (null if nested under Component).</param>
69
private void ParseFirewallExceptionElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId, string fileId)
70
{
71
- SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
71
+ var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
72
Identifier id = null;
73
string name = null;
74
int attributes = 0;
75
string file = null;
76
string program = null;
77
string port = null;
78
- string protocolValue = null;
78
int? protocol = null;
80
- string profileValue = null;
79
int? profile = null;
80
string scope = null;
81
string remoteAddresses = null;
82
string description = null;
83
86
- foreach (XAttribute attrib in element.Attributes())
84
+ foreach (var attrib in element.Attributes())
85
{
86
if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
87
{
@@ -125,7 +123,7 @@ namespace WixToolset.Firewall
123
port = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
124
break;
125
case "Protocol":
128
- protocolValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
126
+ var protocolValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
127
switch (protocolValue)
128
{
129
case "tcp":
@@ -155,7 +153,7 @@ namespace WixToolset.Firewall
153
}
154
break;
155
case "Profile":
158
- profileValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
156
+ var profileValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib);
157
switch (profileValue)
158
{
159
case "domain":
@@ -190,11 +188,10 @@ namespace WixToolset.Firewall
188
}
189
190
// parse RemoteAddress children
193
- foreach (XElement child in element.Elements())
191
+ foreach (var child in element.Elements())
192
{
193
if (this.Namespace == child.Name.Namespace)
194
{
197
- SourceLineNumber childSourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(child);
195
switch (child.Name.LocalName)
196
{
197
case "RemoteAddress":
@@ -218,12 +215,12 @@ namespace WixToolset.Firewall
215
}
216
}
217
221
- // Id and Name are required
218
if (null == id)
219
{
224
- this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Id"));
220
+ id = this.ParseHelper.CreateIdentifier("fex", name, remoteAddresses, componentId);
221
}
222
223
+ // Name is required
224
if (null == name)
225
{
226
this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name"));
@@ -255,14 +252,14 @@ namespace WixToolset.Firewall
252
fileId = file;
253
}
254
258
- var tuple = new WixFirewallExceptionTuple(sourceLineNumbers, id)
255
+ var tuple = section.AddTuple(new WixFirewallExceptionTuple(sourceLineNumbers, id)
256
{
257
Name = name,
258
RemoteAddresses = remoteAddresses,
259
Profile = profile ?? FirewallConstants.NET_FW_PROFILE2_ALL,
260
ComponentRef = componentId,
261
Description = description,
265
- };
262
+ });
263
264
if (!String.IsNullOrEmpty(port))
265
{
@@ -275,12 +272,15 @@ namespace WixToolset.Firewall
272
}
273
}
274
278
- tuple.Protocol = protocol.Value;
275
+ if (protocol.HasValue)
276
+ {
277
+ tuple.Protocol = protocol.Value;
278
+ }
279
280
if (!String.IsNullOrEmpty(fileId))
281
{
282
tuple.Program = $"[#{fileId}]";
283
- this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "File", fileId);
283
+ this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.File, fileId);
284
}
285
else if (!String.IsNullOrEmpty(program))
286
{
@@ -292,19 +292,17 @@ namespace WixToolset.Firewall
292
tuple.Attributes = attributes;
293
}
294
295
- section.Tuples.Add(tuple);
296
-
295
if (this.Context.Platform == Platform.ARM)
296
{
297
// Ensure ARM version of the CA is referenced
300
- this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "WixSchedFirewallExceptionsInstall_ARM");
301
- this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "WixSchedFirewallExceptionsUninstall_ARM");
298
+ this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.CustomAction, "WixSchedFirewallExceptionsInstall_ARM");
299
+ this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.CustomAction, "WixSchedFirewallExceptionsUninstall_ARM");
300
}
301
else
302
{
303
// All other supported platforms use x86
306
- this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "WixSchedFirewallExceptionsInstall");
307
- this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "WixSchedFirewallExceptionsUninstall");
304
+ this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.CustomAction, "WixSchedFirewallExceptionsInstall");
305
+ this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.CustomAction, "WixSchedFirewallExceptionsUninstall");
306
}
307
}
308
}
@@ -315,10 +313,10 @@ namespace WixToolset.Firewall
313
/// <param name="element">The element to parse.</param>
314
private void ParseRemoteAddressElement(Intermediate intermediate, IntermediateSection section, XElement element, ref string remoteAddresses)
315
{
318
- SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
316
+ var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element);
317
318
// no attributes
321
- foreach (XAttribute attrib in element.Attributes())
319
+ foreach (var attrib in element.Attributes())
320
{
321
if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace)
322
{
@@ -332,7 +330,7 @@ namespace WixToolset.Firewall
330
331
this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element);
332
335
- string address = this.ParseHelper.GetTrimmedInnerText(element);
333
+ var address = this.ParseHelper.GetTrimmedInnerText(element);
334
if (String.IsNullOrEmpty(address))
335
{
336
this.Messaging.Write(FirewallErrors.IllegalEmptyRemoteAddress(sourceLineNumbers));
src/wixext/FirewallExtensionData.cs
+1
-2
@@ -4,7 +4,6 @@ namespace WixToolset.Firewall
4
{
5
using WixToolset.Data;
6
using WixToolset.Extensibility;
7
- using WixToolset.Firewall.Tuples;
7
8
public sealed class FirewallExtensionData : BaseExtensionData
9
{
@@ -12,7 +11,7 @@ namespace WixToolset.Firewall
11
12
public override bool TryGetTupleDefinitionByName(string name, out IntermediateTupleDefinition tupleDefinition)
13
{
15
- tupleDefinition = (name == FirewallTupleDefinitionNames.WixFirewallException) ? FirewallTupleDefinitions.WixFirewallException : null;
14
+ tupleDefinition = FirewallTupleDefinitions.ByName(name);
15
return tupleDefinition != null;
16
}
17
src/wixext/FirewallTableDefinitions.cs
new
+33
@@ -0,0 +1,33 @@
1
+// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
+
3
+namespace WixToolset.Firewall
4
+{
5
+ using WixToolset.Data.WindowsInstaller;
6
+
7
+ public static class FirewallTableDefinitions
8
+ {
9
+ public static readonly TableDefinition WixFirewallException = new TableDefinition(
10
+ "WixFirewallException",
11
+ new[]
12
+ {
13
+ new ColumnDefinition("WixFirewallException", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "The primary key, a non-localized token.", modularizeType: ColumnModularizeType.Column),
14
+ new ColumnDefinition("Name", ColumnType.Localized, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Localizable display name.", modularizeType: ColumnModularizeType.Property),
15
+ new ColumnDefinition("RemoteAddresses", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Remote address to accept incoming connections from.", modularizeType: ColumnModularizeType.Property),
16
+ new ColumnDefinition("Port", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, minValue: 1, description: "Port number.", modularizeType: ColumnModularizeType.Property),
17
+ new ColumnDefinition("Protocol", ColumnType.Number, 1, primaryKey: false, nullable: true, ColumnCategory.Integer, minValue: 6, maxValue: 17, description: "Protocol (6=TCP; 17=UDP)."),
18
+ new ColumnDefinition("Program", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Exception for a program (formatted path name).", modularizeType: ColumnModularizeType.Property),
19
+ new ColumnDefinition("Attributes", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Vital=1"),
20
+ new ColumnDefinition("Profile", ColumnType.Number, 4, primaryKey: false, nullable: false, ColumnCategory.Integer, minValue: 1, maxValue: 2147483647, description: "Profile (1=domain; 2=private; 4=public; 2147483647=all)."),
21
+ new ColumnDefinition("Component_", ColumnType.String, 72, primaryKey: false, nullable: false, ColumnCategory.Identifier, keyTable: "Component", keyColumn: 1, description: "Foreign key into the Component table referencing component that controls the firewall configuration.", modularizeType: ColumnModularizeType.Column),
22
+ new ColumnDefinition("Description", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Description displayed in Windows Firewall manager for this firewall rule."),
23
+ },
24
+ tupleDefinitionName: FirewallTupleDefinitions.WixFirewallException.Name,
25
+ tupleIdIsPrimaryKey: true
26
+ );
27
+
28
+ public static readonly TableDefinition[] All = new[]
29
+ {
30
+ WixFirewallException,
31
+ };
32
+ }
33
+}
src/wixext/FirewallWindowsInstallerBackendExtension.cs
+2
-17
@@ -1,30 +1,15 @@
1
-// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
1
+// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3
namespace WixToolset.Firewall
4
{
5
using System.Collections.Generic;
6
using System.Linq;
7
using System.Xml;
8
- using WixToolset.Data;
8
using WixToolset.Data.WindowsInstaller;
9
using WixToolset.Extensibility;
10
11
public class FirewallWindowsInstallerBackendBinderExtension : BaseWindowsInstallerBackendBinderExtension
12
{
14
- private static readonly TableDefinition[] Tables = LoadTables();
15
-
16
- public override IEnumerable<TableDefinition> TableDefinitions => Tables;
17
-
18
- public override bool TryAddTupleToOutput(IntermediateTuple tuple, WindowsInstallerData output) => this.BackendHelper.TryAddTupleToOutputMatchingTableDefinitions(tuple, output, this.TableDefinitionsForTuples, true);
19
-
20
- private static TableDefinition[] LoadTables()
21
- {
22
- using (var resourceStream = typeof(FirewallWindowsInstallerBackendBinderExtension).Assembly.GetManifestResourceStream("WixToolset.Firewall.tables.xml"))
23
- using (var reader = XmlReader.Create(resourceStream))
24
- {
25
- var tables = TableDefinitionCollection.Load(reader);
26
- return tables.ToArray();
27
- }
28
- }
13
+ public override IEnumerable<TableDefinition> TableDefinitions => FirewallTableDefinitions.All;
14
}
15
}
src/wixext/Tuples/FirewallTupleDefinitions.cs
+26
-17
@@ -1,30 +1,39 @@
1
// Copyright (c) .NET Foundation and contributors. All rights reserved. Licensed under the Microsoft Reciprocal License. See LICENSE.TXT file in the project root for full license information.
2
3
-namespace WixToolset.Firewall.Tuples
3
+namespace WixToolset.Firewall
4
{
5
+ using System;
6
using WixToolset.Data;
7
7
- public static class FirewallTupleDefinitionNames
8
+ public enum FirewallTupleDefinitionType
9
{
9
- public static string WixFirewallException { get; } = "WixFirewallException";
10
+ WixFirewallException,
11
}
12
13
public static partial class FirewallTupleDefinitions
14
{
14
- public static readonly IntermediateTupleDefinition WixFirewallException = new IntermediateTupleDefinition(
15
- FirewallTupleDefinitionNames.WixFirewallException,
16
- new[]
15
+ public static readonly Version Version = new Version("4.0.0");
16
+
17
+ public static IntermediateTupleDefinition ByName(string name)
18
+ {
19
+ if (!Enum.TryParse(name, out FirewallTupleDefinitionType type))
20
{
18
- new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Name), IntermediateFieldType.String),
19
- new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.RemoteAddresses), IntermediateFieldType.String),
20
- new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Port), IntermediateFieldType.String),
21
- new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Protocol), IntermediateFieldType.Number),
22
- new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Program), IntermediateFieldType.String),
23
- new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Attributes), IntermediateFieldType.Number),
24
- new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Profile), IntermediateFieldType.Number),
25
- new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.ComponentRef), IntermediateFieldType.String),
26
- new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Description), IntermediateFieldType.String),
27
- },
28
- typeof(WixFirewallExceptionTuple));
21
+ return null;
22
+ }
23
+
24
+ return ByType(type);
25
+ }
26
+
27
+ public static IntermediateTupleDefinition ByType(FirewallTupleDefinitionType type)
28
+ {
29
+ switch (type)
30
+ {
31
+ case FirewallTupleDefinitionType.WixFirewallException:
32
+ return FirewallTupleDefinitions.WixFirewallException;
33
+
34
+ default:
35
+ throw new ArgumentOutOfRangeException(nameof(type));
36
+ }
37
+ }
38
}
39
}
src/wixext/Tuples/WixFirewallExceptionTuple.cs
+25
@@ -1,5 +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
3
+namespace WixToolset.Firewall
4
+{
5
+ using WixToolset.Data;
6
+ using WixToolset.Firewall.Tuples;
7
+
8
+ public static partial class FirewallTupleDefinitions
9
+ {
10
+ public static readonly IntermediateTupleDefinition WixFirewallException = new IntermediateTupleDefinition(
11
+ FirewallTupleDefinitionType.WixFirewallException.ToString(),
12
+ new[]
13
+ {
14
+ new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Name), IntermediateFieldType.String),
15
+ new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.RemoteAddresses), IntermediateFieldType.String),
16
+ new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Port), IntermediateFieldType.String),
17
+ new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Protocol), IntermediateFieldType.Number),
18
+ new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Program), IntermediateFieldType.String),
19
+ new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Attributes), IntermediateFieldType.Number),
20
+ new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Profile), IntermediateFieldType.Number),
21
+ new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.ComponentRef), IntermediateFieldType.String),
22
+ new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Description), IntermediateFieldType.String),
23
+ },
24
+ typeof(WixFirewallExceptionTuple));
25
+ }
26
+}
27
+
28
namespace WixToolset.Firewall.Tuples
29
{
30
using WixToolset.Data;
src/wixext/WixToolset.Firewall.wixext.csproj
-1
@@ -14,7 +14,6 @@
14
<ItemGroup>
15
<Content Include="$(MSBuildThisFileName).targets" />
16
<Content Include="firewall.xsd" PackagePath="tools" />
17
- <EmbeddedResource Include="tables.xml" />
17
<EmbeddedResource Include="$(OutputPath)..\firewall.wixlib" />
18
</ItemGroup>
19
src/wixext/tables.xml
deleted
-28
@@ -1,28 +0,0 @@
1
-<?xml version="1.0" encoding="utf-8"?>
2
-<!-- 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. -->
3
-
4
-
5
-<tableDefinitions xmlns="http://wixtoolset.org/schemas/v4/wi/tables">
6
- <tableDefinition name="WixFirewallException">
7
- <columnDefinition name="WixFirewallException" type="string" length="72" primaryKey="yes" modularize="column"
8
- category="identifier" description="The primary key, a non-localized token." />
9
- <columnDefinition name="Name" type="localized" length="255" nullable="yes" modularize="property"
10
- category="formatted" description="Localizable display name." />
11
- <columnDefinition name="RemoteAddresses" type="string" length="0" modularize="property"
12
- category="formatted" description="Remote address to accept incoming connections from." />
13
- <columnDefinition name="Port" type="string" length="0" modularize="property" nullable="yes"
14
- category="formatted" minValue="1" description="Port number." />
15
- <columnDefinition name="Protocol" type="number" length="1" nullable="yes"
16
- category="integer" minValue="6" maxValue="17" description="Protocol (6=TCP; 17=UDP)." />
17
- <columnDefinition name="Program" type="string" length="255" nullable="yes" modularize="property"
18
- category="formatted" description="Exception for a program (formatted path name)." />
19
- <columnDefinition name="Attributes" type="number" length="4" nullable="yes"
20
- description="Vital=1" />
21
- <columnDefinition name="Profile" type="number" length="4" nullable="no"
22
- category="integer" minValue="1" maxValue="2147483647" description="Profile (1=domain; 2=private; 4=public; 2147483647=all)." />
23
- <columnDefinition name="Component_" type="string" length="72" modularize="column"
24
- keyTable="Component" keyColumn="1" category="identifier" description="Foreign key into the Component table referencing component that controls the firewall configuration."/>
25
- <columnDefinition name="Description" type="string" length="255" nullable="yes"
26
- category="formatted" description="Description displayed in Windows Firewall manager for this firewall rule."/>
27
- </tableDefinition>
28
-</tableDefinitions>