From 2427be20a103957f204b753db45ee89ad636bb08 Mon Sep 17 00:00:00 2001 From: Sean Hall Date: Thu, 9 Apr 2020 09:01:29 +1000 Subject: Modernize FirewallCompiler and tuples. --- .../FirewallExtensionFixture.cs | 2 +- src/wixext/FirewallCompiler.cs | 50 +++++++++++----------- src/wixext/FirewallExtensionData.cs | 3 +- src/wixext/FirewallTableDefinitions.cs | 33 ++++++++++++++ .../FirewallWindowsInstallerBackendExtension.cs | 19 +------- src/wixext/Tuples/FirewallTupleDefinitions.cs | 43 +++++++++++-------- src/wixext/Tuples/WixFirewallExceptionTuple.cs | 25 +++++++++++ src/wixext/WixToolset.Firewall.wixext.csproj | 1 - src/wixext/tables.xml | 28 ------------ 9 files changed, 112 insertions(+), 92 deletions(-) create mode 100644 src/wixext/FirewallTableDefinitions.cs delete mode 100644 src/wixext/tables.xml diff --git a/src/test/WixToolsetTest.Firewall/FirewallExtensionFixture.cs b/src/test/WixToolsetTest.Firewall/FirewallExtensionFixture.cs index e3c41181..fa64f7d3 100644 --- a/src/test/WixToolsetTest.Firewall/FirewallExtensionFixture.cs +++ b/src/test/WixToolsetTest.Firewall/FirewallExtensionFixture.cs @@ -20,7 +20,7 @@ namespace WixToolsetTest.Firewall Assert.Equal(new[] { "WixFirewallException:ExampleFirewall\texample\t*\t42\t6\t\t0\t2147483647\tfilF5_pLhBuF5b4N9XEo52g_hUM5Lo\tAn example firewall", - }, results.OrderBy(s => s).ToArray()); + }, results); } private static void Build(string[] args) diff --git a/src/wixext/FirewallCompiler.cs b/src/wixext/FirewallCompiler.cs index 353afff3..16136954 100644 --- a/src/wixext/FirewallCompiler.cs +++ b/src/wixext/FirewallCompiler.cs @@ -28,8 +28,8 @@ namespace WixToolset.Firewall switch (parentElement.Name.LocalName) { case "File": - string fileId = context["FileId"]; - string fileComponentId = context["ComponentId"]; + var fileId = context["FileId"]; + var fileComponentId = context["ComponentId"]; switch (element.Name.LocalName) { @@ -42,7 +42,7 @@ namespace WixToolset.Firewall } break; case "Component": - string componentId = context["ComponentId"]; + var componentId = context["ComponentId"]; switch (element.Name.LocalName) { @@ -68,22 +68,20 @@ namespace WixToolset.Firewall /// The file identifier of the parent element (null if nested under Component). private void ParseFirewallExceptionElement(Intermediate intermediate, IntermediateSection section, XElement element, string componentId, string fileId) { - SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); Identifier id = null; string name = null; int attributes = 0; string file = null; string program = null; string port = null; - string protocolValue = null; int? protocol = null; - string profileValue = null; int? profile = null; string scope = null; string remoteAddresses = null; string description = null; - foreach (XAttribute attrib in element.Attributes()) + foreach (var attrib in element.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { @@ -125,7 +123,7 @@ namespace WixToolset.Firewall port = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); break; case "Protocol": - protocolValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + var protocolValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); switch (protocolValue) { case "tcp": @@ -155,7 +153,7 @@ namespace WixToolset.Firewall } break; case "Profile": - profileValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); + var profileValue = this.ParseHelper.GetAttributeValue(sourceLineNumbers, attrib); switch (profileValue) { case "domain": @@ -190,11 +188,10 @@ namespace WixToolset.Firewall } // parse RemoteAddress children - foreach (XElement child in element.Elements()) + foreach (var child in element.Elements()) { if (this.Namespace == child.Name.Namespace) { - SourceLineNumber childSourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(child); switch (child.Name.LocalName) { case "RemoteAddress": @@ -218,12 +215,12 @@ namespace WixToolset.Firewall } } - // Id and Name are required if (null == id) { - this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Id")); + id = this.ParseHelper.CreateIdentifier("fex", name, remoteAddresses, componentId); } + // Name is required if (null == name) { this.Messaging.Write(ErrorMessages.ExpectedAttribute(sourceLineNumbers, element.Name.LocalName, "Name")); @@ -255,14 +252,14 @@ namespace WixToolset.Firewall fileId = file; } - var tuple = new WixFirewallExceptionTuple(sourceLineNumbers, id) + var tuple = section.AddTuple(new WixFirewallExceptionTuple(sourceLineNumbers, id) { Name = name, RemoteAddresses = remoteAddresses, Profile = profile ?? FirewallConstants.NET_FW_PROFILE2_ALL, ComponentRef = componentId, Description = description, - }; + }); if (!String.IsNullOrEmpty(port)) { @@ -275,12 +272,15 @@ namespace WixToolset.Firewall } } - tuple.Protocol = protocol.Value; + if (protocol.HasValue) + { + tuple.Protocol = protocol.Value; + } if (!String.IsNullOrEmpty(fileId)) { tuple.Program = $"[#{fileId}]"; - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "File", fileId); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.File, fileId); } else if (!String.IsNullOrEmpty(program)) { @@ -292,19 +292,17 @@ namespace WixToolset.Firewall tuple.Attributes = attributes; } - section.Tuples.Add(tuple); - if (this.Context.Platform == Platform.ARM) { // Ensure ARM version of the CA is referenced - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "WixSchedFirewallExceptionsInstall_ARM"); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "WixSchedFirewallExceptionsUninstall_ARM"); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.CustomAction, "WixSchedFirewallExceptionsInstall_ARM"); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.CustomAction, "WixSchedFirewallExceptionsUninstall_ARM"); } else { // All other supported platforms use x86 - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "WixSchedFirewallExceptionsInstall"); - this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, "CustomAction", "WixSchedFirewallExceptionsUninstall"); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.CustomAction, "WixSchedFirewallExceptionsInstall"); + this.ParseHelper.CreateSimpleReference(section, sourceLineNumbers, TupleDefinitions.CustomAction, "WixSchedFirewallExceptionsUninstall"); } } } @@ -315,10 +313,10 @@ namespace WixToolset.Firewall /// The element to parse. private void ParseRemoteAddressElement(Intermediate intermediate, IntermediateSection section, XElement element, ref string remoteAddresses) { - SourceLineNumber sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); + var sourceLineNumbers = this.ParseHelper.GetSourceLineNumbers(element); // no attributes - foreach (XAttribute attrib in element.Attributes()) + foreach (var attrib in element.Attributes()) { if (String.IsNullOrEmpty(attrib.Name.NamespaceName) || this.Namespace == attrib.Name.Namespace) { @@ -332,7 +330,7 @@ namespace WixToolset.Firewall this.ParseHelper.ParseForExtensionElements(this.Context.Extensions, intermediate, section, element); - string address = this.ParseHelper.GetTrimmedInnerText(element); + var address = this.ParseHelper.GetTrimmedInnerText(element); if (String.IsNullOrEmpty(address)) { this.Messaging.Write(FirewallErrors.IllegalEmptyRemoteAddress(sourceLineNumbers)); diff --git a/src/wixext/FirewallExtensionData.cs b/src/wixext/FirewallExtensionData.cs index 78939c4e..44cae0d6 100644 --- a/src/wixext/FirewallExtensionData.cs +++ b/src/wixext/FirewallExtensionData.cs @@ -4,7 +4,6 @@ namespace WixToolset.Firewall { using WixToolset.Data; using WixToolset.Extensibility; - using WixToolset.Firewall.Tuples; public sealed class FirewallExtensionData : BaseExtensionData { @@ -12,7 +11,7 @@ namespace WixToolset.Firewall public override bool TryGetTupleDefinitionByName(string name, out IntermediateTupleDefinition tupleDefinition) { - tupleDefinition = (name == FirewallTupleDefinitionNames.WixFirewallException) ? FirewallTupleDefinitions.WixFirewallException : null; + tupleDefinition = FirewallTupleDefinitions.ByName(name); return tupleDefinition != null; } diff --git a/src/wixext/FirewallTableDefinitions.cs b/src/wixext/FirewallTableDefinitions.cs new file mode 100644 index 00000000..d6e469b8 --- /dev/null +++ b/src/wixext/FirewallTableDefinitions.cs @@ -0,0 +1,33 @@ +// 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. + +namespace WixToolset.Firewall +{ + using WixToolset.Data.WindowsInstaller; + + public static class FirewallTableDefinitions + { + public static readonly TableDefinition WixFirewallException = new TableDefinition( + "WixFirewallException", + new[] + { + new ColumnDefinition("WixFirewallException", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "The primary key, a non-localized token.", modularizeType: ColumnModularizeType.Column), + new ColumnDefinition("Name", ColumnType.Localized, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Localizable display name.", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("RemoteAddresses", ColumnType.String, 0, primaryKey: false, nullable: false, ColumnCategory.Formatted, description: "Remote address to accept incoming connections from.", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("Port", ColumnType.String, 0, primaryKey: false, nullable: true, ColumnCategory.Formatted, minValue: 1, description: "Port number.", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("Protocol", ColumnType.Number, 1, primaryKey: false, nullable: true, ColumnCategory.Integer, minValue: 6, maxValue: 17, description: "Protocol (6=TCP; 17=UDP)."), + new ColumnDefinition("Program", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Exception for a program (formatted path name).", modularizeType: ColumnModularizeType.Property), + new ColumnDefinition("Attributes", ColumnType.Number, 4, primaryKey: false, nullable: true, ColumnCategory.Unknown, description: "Vital=1"), + 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)."), + 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), + new ColumnDefinition("Description", ColumnType.String, 255, primaryKey: false, nullable: true, ColumnCategory.Formatted, description: "Description displayed in Windows Firewall manager for this firewall rule."), + }, + tupleDefinitionName: FirewallTupleDefinitions.WixFirewallException.Name, + tupleIdIsPrimaryKey: true + ); + + public static readonly TableDefinition[] All = new[] + { + WixFirewallException, + }; + } +} diff --git a/src/wixext/FirewallWindowsInstallerBackendExtension.cs b/src/wixext/FirewallWindowsInstallerBackendExtension.cs index 7b731710..dea355b4 100644 --- a/src/wixext/FirewallWindowsInstallerBackendExtension.cs +++ b/src/wixext/FirewallWindowsInstallerBackendExtension.cs @@ -1,30 +1,15 @@ -// 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. +// 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. namespace WixToolset.Firewall { using System.Collections.Generic; using System.Linq; using System.Xml; - using WixToolset.Data; using WixToolset.Data.WindowsInstaller; using WixToolset.Extensibility; public class FirewallWindowsInstallerBackendBinderExtension : BaseWindowsInstallerBackendBinderExtension { - private static readonly TableDefinition[] Tables = LoadTables(); - - public override IEnumerable TableDefinitions => Tables; - - public override bool TryAddTupleToOutput(IntermediateTuple tuple, WindowsInstallerData output) => this.BackendHelper.TryAddTupleToOutputMatchingTableDefinitions(tuple, output, this.TableDefinitionsForTuples, true); - - private static TableDefinition[] LoadTables() - { - using (var resourceStream = typeof(FirewallWindowsInstallerBackendBinderExtension).Assembly.GetManifestResourceStream("WixToolset.Firewall.tables.xml")) - using (var reader = XmlReader.Create(resourceStream)) - { - var tables = TableDefinitionCollection.Load(reader); - return tables.ToArray(); - } - } + public override IEnumerable TableDefinitions => FirewallTableDefinitions.All; } } diff --git a/src/wixext/Tuples/FirewallTupleDefinitions.cs b/src/wixext/Tuples/FirewallTupleDefinitions.cs index df595c18..2710380e 100644 --- a/src/wixext/Tuples/FirewallTupleDefinitions.cs +++ b/src/wixext/Tuples/FirewallTupleDefinitions.cs @@ -1,30 +1,39 @@ // 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. -namespace WixToolset.Firewall.Tuples +namespace WixToolset.Firewall { + using System; using WixToolset.Data; - public static class FirewallTupleDefinitionNames + public enum FirewallTupleDefinitionType { - public static string WixFirewallException { get; } = "WixFirewallException"; + WixFirewallException, } public static partial class FirewallTupleDefinitions { - public static readonly IntermediateTupleDefinition WixFirewallException = new IntermediateTupleDefinition( - FirewallTupleDefinitionNames.WixFirewallException, - new[] + public static readonly Version Version = new Version("4.0.0"); + + public static IntermediateTupleDefinition ByName(string name) + { + if (!Enum.TryParse(name, out FirewallTupleDefinitionType type)) { - new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Name), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.RemoteAddresses), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Port), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Protocol), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Program), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Attributes), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Profile), IntermediateFieldType.Number), - new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.ComponentRef), IntermediateFieldType.String), - new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Description), IntermediateFieldType.String), - }, - typeof(WixFirewallExceptionTuple)); + return null; + } + + return ByType(type); + } + + public static IntermediateTupleDefinition ByType(FirewallTupleDefinitionType type) + { + switch (type) + { + case FirewallTupleDefinitionType.WixFirewallException: + return FirewallTupleDefinitions.WixFirewallException; + + default: + throw new ArgumentOutOfRangeException(nameof(type)); + } + } } } diff --git a/src/wixext/Tuples/WixFirewallExceptionTuple.cs b/src/wixext/Tuples/WixFirewallExceptionTuple.cs index 3c7cda3a..d08b9e45 100644 --- a/src/wixext/Tuples/WixFirewallExceptionTuple.cs +++ b/src/wixext/Tuples/WixFirewallExceptionTuple.cs @@ -1,5 +1,30 @@ // 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. +namespace WixToolset.Firewall +{ + using WixToolset.Data; + using WixToolset.Firewall.Tuples; + + public static partial class FirewallTupleDefinitions + { + public static readonly IntermediateTupleDefinition WixFirewallException = new IntermediateTupleDefinition( + FirewallTupleDefinitionType.WixFirewallException.ToString(), + new[] + { + new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Name), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.RemoteAddresses), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Port), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Protocol), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Program), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Attributes), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Profile), IntermediateFieldType.Number), + new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.ComponentRef), IntermediateFieldType.String), + new IntermediateFieldDefinition(nameof(WixFirewallExceptionTupleFields.Description), IntermediateFieldType.String), + }, + typeof(WixFirewallExceptionTuple)); + } +} + namespace WixToolset.Firewall.Tuples { using WixToolset.Data; diff --git a/src/wixext/WixToolset.Firewall.wixext.csproj b/src/wixext/WixToolset.Firewall.wixext.csproj index b0fe04d1..07d5de56 100644 --- a/src/wixext/WixToolset.Firewall.wixext.csproj +++ b/src/wixext/WixToolset.Firewall.wixext.csproj @@ -14,7 +14,6 @@ - diff --git a/src/wixext/tables.xml b/src/wixext/tables.xml deleted file mode 100644 index b0c32305..00000000 --- a/src/wixext/tables.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - -- cgit v1.2.3-55-g6feb