diff --git a/src/ext/Firewall/ca/firewall.cpp b/src/ext/Firewall/ca/firewall.cpp
index 2a1ef8256..eed6f9df9 100644
--- a/src/ext/Firewall/ca/firewall.cpp
+++ b/src/ext/Firewall/ca/firewall.cpp
@@ -3,7 +3,7 @@
#include "precomp.h"
LPCWSTR vcsFirewallExceptionQuery =
- L"SELECT `Name`, `RemoteAddresses`, `Port`, `Protocol`, `Program`, `Attributes`, `Profile`, `Component_`, `Description`, `Direction` FROM `Wix4FirewallException`";
+ L"SELECT `Name`, `RemoteAddresses`, `Port`, `Protocol`, `Program`, `Attributes`, `Profile`, `Component_`, `Description`, `Direction` FROM `Wix5FirewallException`";
enum eFirewallExceptionQuery { feqName = 1, feqRemoteAddresses, feqPort, feqProtocol, feqProgram, feqAttributes, feqProfile, feqComponent, feqDescription, feqDirection };
enum eFirewallExceptionTarget { fetPort = 1, fetApplication, fetUnknown };
enum eFirewallExceptionAttributes { feaIgnoreFailures = 1 };
@@ -49,15 +49,15 @@ static UINT SchedFirewallExceptions(
ExitOnFailure(hr, "Failed to initialize");
// anything to do?
- if (S_OK != WcaTableExists(L"Wix4FirewallException"))
+ if (S_OK != WcaTableExists(L"Wix5FirewallException"))
{
- WcaLog(LOGMSG_STANDARD, "Wix4FirewallException table doesn't exist, so there are no firewall exceptions to configure.");
+ WcaLog(LOGMSG_STANDARD, "Wix5FirewallException table doesn't exist, so there are no firewall exceptions to configure.");
ExitFunction();
}
// query and loop through all the firewall exceptions
hr = WcaOpenExecuteView(vcsFirewallExceptionQuery, &hView);
- ExitOnFailure(hr, "Failed to open view on Wix4FirewallException table");
+ ExitOnFailure(hr, "Failed to open view on Wix5FirewallException table");
while (S_OK == (hr = WcaFetchRecord(hView, &hRec)))
{
@@ -150,7 +150,7 @@ static UINT SchedFirewallExceptions(
{
hr = S_OK;
}
- ExitOnFailure(hr, "failure occured while processing Wix4FirewallException table");
+ ExitOnFailure(hr, "failure occured while processing Wix5FirewallException table");
// schedule ExecFirewallExceptions if there's anything to do
if (pwzCustomActionData && *pwzCustomActionData)
@@ -159,16 +159,16 @@ static UINT SchedFirewallExceptions(
if (WCA_TODO_INSTALL == todoSched)
{
- hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"RollbackFirewallExceptionsInstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION);
+ hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"RollbackFirewallExceptionsInstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION);
ExitOnFailure(hr, "failed to schedule firewall install exceptions rollback");
- hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"ExecFirewallExceptionsInstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION);
+ hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"ExecFirewallExceptionsInstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION);
ExitOnFailure(hr, "failed to schedule firewall install exceptions execution");
}
else
{
- hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"RollbackFirewallExceptionsUninstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION);
+ hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"RollbackFirewallExceptionsUninstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION);
ExitOnFailure(hr, "failed to schedule firewall uninstall exceptions rollback");
- hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION(L"ExecFirewallExceptionsUninstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION);
+ hr = WcaDoDeferredAction(CUSTOM_ACTION_DECORATION5(L"ExecFirewallExceptionsUninstall"), pwzCustomActionData, cFirewallExceptions * COST_FIREWALL_EXCEPTION);
ExitOnFailure(hr, "failed to schedule firewall uninstall exceptions execution");
}
}
diff --git a/src/ext/Firewall/test/WixToolsetTest.Firewall/FirewallExtensionFixture.cs b/src/ext/Firewall/test/WixToolsetTest.Firewall/FirewallExtensionFixture.cs
index 06a877f6a..7119e92da 100644
--- a/src/ext/Firewall/test/WixToolsetTest.Firewall/FirewallExtensionFixture.cs
+++ b/src/ext/Firewall/test/WixToolsetTest.Firewall/FirewallExtensionFixture.cs
@@ -18,17 +18,21 @@ public void CanBuildUsingFirewall()
var folder = TestData.Get(@"TestData\UsingFirewall");
var build = new Builder(folder, typeof(FirewallExtensionFactory), new[] { folder });
- var results = build.BuildAndQuery(Build, "Wix4FirewallException", "CustomAction");
+ var results = build.BuildAndQuery(Build, "Wix5FirewallException", "CustomAction");
WixAssert.CompareLineByLine(new[]
{
- "CustomAction:Wix4ExecFirewallExceptionsInstall_X86\t3073\tWix4FWCA_X86\tExecFirewallExceptions\t",
- "CustomAction:Wix4ExecFirewallExceptionsUninstall_X86\t3073\tWix4FWCA_X86\tExecFirewallExceptions\t",
- "CustomAction:Wix4RollbackFirewallExceptionsInstall_X86\t3329\tWix4FWCA_X86\tExecFirewallExceptions\t",
- "CustomAction:Wix4RollbackFirewallExceptionsUninstall_X86\t3329\tWix4FWCA_X86\tExecFirewallExceptions\t",
- "CustomAction:Wix4SchedFirewallExceptionsInstall_X86\t1\tWix4FWCA_X86\tSchedFirewallExceptionsInstall\t",
- "CustomAction:Wix4SchedFirewallExceptionsUninstall_X86\t1\tWix4FWCA_X86\tSchedFirewallExceptionsUninstall\t",
- "Wix4FirewallException:ExampleFirewall\tExampleApp\t*\t42\t6\t[#filNdJBJmq3UCUIwmXS8x21aAsvqzk]\t0\t2147483647\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tAn app-based firewall exception\t1",
- "Wix4FirewallException:fex70IVsYNnbwiHQrEepmdTPKH8XYs\tExamplePort\tLocalSubnet\t42\t6\t\t0\t2147483647\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tA port-based firewall exception\t2",
+ "CustomAction:Wix5ExecFirewallExceptionsInstall_X86\t3073\tWix5FWCA_X86\tExecFirewallExceptions\t",
+ "CustomAction:Wix5ExecFirewallExceptionsUninstall_X86\t3073\tWix5FWCA_X86\tExecFirewallExceptions\t",
+ "CustomAction:Wix5RollbackFirewallExceptionsInstall_X86\t3329\tWix5FWCA_X86\tExecFirewallExceptions\t",
+ "CustomAction:Wix5RollbackFirewallExceptionsUninstall_X86\t3329\tWix5FWCA_X86\tExecFirewallExceptions\t",
+ "CustomAction:Wix5SchedFirewallExceptionsInstall_X86\t1\tWix5FWCA_X86\tSchedFirewallExceptionsInstall\t",
+ "CustomAction:Wix5SchedFirewallExceptionsUninstall_X86\t1\tWix5FWCA_X86\tSchedFirewallExceptionsUninstall\t",
+ "Wix5FirewallException:ExampleFirewall\tExampleApp\t*\t42\t6\t[#filNdJBJmq3UCUIwmXS8x21aAsvqzk]\t0\t2147483647\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tAn app-based firewall exception\t1",
+ "Wix5FirewallException:fex_ZpDsnKyHlYiA24JHzvFxm3uLZ8\tExampleDefaultGatewayScope\tDefaultGateway\t4432\t6\t\t0\t2\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tdefaultGateway scope firewall exception\t1",
+ "Wix5FirewallException:fex6bkfWwpiRGI.wVFx0T7W4LXIHxU\tExampleDHCPScope\tdhcp\t\t211\ttest.exe\t0\t4\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tDHCP scope firewall exception\t1",
+ "Wix5FirewallException:fex70IVsYNnbwiHQrEepmdTPKH8XYs\tExamplePort\tLocalSubnet\t42\t6\t\t0\t2147483647\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tA port-based firewall exception\t2",
+ "Wix5FirewallException:fexXxaXCXXFh.UxO_BjmZxi1B1du_Q\tExampleWINSScope\twins\t6573\t6\t\t0\t1\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tWINS scope firewall exception\t1",
+ "Wix5FirewallException:fexxY71H2ZBkPalv7uid1Yy4qaA_lA\tExampleDNSScope\tdns\t356\t17\t\t0\t2147483647\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tDNS scope firewall exception\t1",
}, results);
}
@@ -38,17 +42,21 @@ public void CanBuildUsingFirewallARM64()
var folder = TestData.Get(@"TestData\UsingFirewall");
var build = new Builder(folder, typeof(FirewallExtensionFactory), new[] { folder });
- var results = build.BuildAndQuery(BuildARM64, "Wix4FirewallException", "CustomAction");
+ var results = build.BuildAndQuery(BuildARM64, "Wix5FirewallException", "CustomAction");
WixAssert.CompareLineByLine(new[]
{
- "CustomAction:Wix4ExecFirewallExceptionsInstall_A64\t3073\tWix4FWCA_A64\tExecFirewallExceptions\t",
- "CustomAction:Wix4ExecFirewallExceptionsUninstall_A64\t3073\tWix4FWCA_A64\tExecFirewallExceptions\t",
- "CustomAction:Wix4RollbackFirewallExceptionsInstall_A64\t3329\tWix4FWCA_A64\tExecFirewallExceptions\t",
- "CustomAction:Wix4RollbackFirewallExceptionsUninstall_A64\t3329\tWix4FWCA_A64\tExecFirewallExceptions\t",
- "CustomAction:Wix4SchedFirewallExceptionsInstall_A64\t1\tWix4FWCA_A64\tSchedFirewallExceptionsInstall\t",
- "CustomAction:Wix4SchedFirewallExceptionsUninstall_A64\t1\tWix4FWCA_A64\tSchedFirewallExceptionsUninstall\t",
- "Wix4FirewallException:ExampleFirewall\tExampleApp\t*\t42\t6\t[#filNdJBJmq3UCUIwmXS8x21aAsvqzk]\t0\t2147483647\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tAn app-based firewall exception\t1",
- "Wix4FirewallException:fex70IVsYNnbwiHQrEepmdTPKH8XYs\tExamplePort\tLocalSubnet\t42\t6\t\t0\t2147483647\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tA port-based firewall exception\t2",
+ "CustomAction:Wix5ExecFirewallExceptionsInstall_A64\t3073\tWix5FWCA_A64\tExecFirewallExceptions\t",
+ "CustomAction:Wix5ExecFirewallExceptionsUninstall_A64\t3073\tWix5FWCA_A64\tExecFirewallExceptions\t",
+ "CustomAction:Wix5RollbackFirewallExceptionsInstall_A64\t3329\tWix5FWCA_A64\tExecFirewallExceptions\t",
+ "CustomAction:Wix5RollbackFirewallExceptionsUninstall_A64\t3329\tWix5FWCA_A64\tExecFirewallExceptions\t",
+ "CustomAction:Wix5SchedFirewallExceptionsInstall_A64\t1\tWix5FWCA_A64\tSchedFirewallExceptionsInstall\t",
+ "CustomAction:Wix5SchedFirewallExceptionsUninstall_A64\t1\tWix5FWCA_A64\tSchedFirewallExceptionsUninstall\t",
+ "Wix5FirewallException:ExampleFirewall\tExampleApp\t*\t42\t6\t[#filNdJBJmq3UCUIwmXS8x21aAsvqzk]\t0\t2147483647\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tAn app-based firewall exception\t1",
+ "Wix5FirewallException:fex_ZpDsnKyHlYiA24JHzvFxm3uLZ8\tExampleDefaultGatewayScope\tDefaultGateway\t4432\t6\t\t0\t2\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tdefaultGateway scope firewall exception\t1",
+ "Wix5FirewallException:fex6bkfWwpiRGI.wVFx0T7W4LXIHxU\tExampleDHCPScope\tdhcp\t\t211\ttest.exe\t0\t4\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tDHCP scope firewall exception\t1",
+ "Wix5FirewallException:fex70IVsYNnbwiHQrEepmdTPKH8XYs\tExamplePort\tLocalSubnet\t42\t6\t\t0\t2147483647\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tA port-based firewall exception\t2",
+ "Wix5FirewallException:fexXxaXCXXFh.UxO_BjmZxi1B1du_Q\tExampleWINSScope\twins\t6573\t6\t\t0\t1\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tWINS scope firewall exception\t1",
+ "Wix5FirewallException:fexxY71H2ZBkPalv7uid1Yy4qaA_lA\tExampleDNSScope\tdns\t356\t17\t\t0\t2147483647\tfilNdJBJmq3UCUIwmXS8x21aAsvqzk\tDNS scope firewall exception\t1",
}, results);
}
@@ -71,8 +79,17 @@ public void CanRoundtripFirewallExceptions()
{
"FirewallException",
"FirewallException",
+ "FirewallException",
+ "FirewallException",
+ "FirewallException",
+ "FirewallException",
}, actual.Select(a => a.Name).ToArray());
+ }
+ [Fact]
+ public void RoundtripAttributesAreCorrectForApp()
+ {
+ var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "ExampleApp");
WixAssert.CompareLineByLine(new[]
{
"Id=ExampleFirewall",
@@ -85,8 +102,13 @@ public void CanRoundtripFirewallExceptions()
"Description=An app-based firewall exception",
"Outbound=no",
"xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall",
- }, actual[0].Attributes);
+ }, actual.Attributes);
+ }
+ [Fact]
+ public void RoundtripAttributesAreCorrectForPort()
+ {
+ var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "ExamplePort");
WixAssert.CompareLineByLine(new[]
{
"Id=fex70IVsYNnbwiHQrEepmdTPKH8XYs",
@@ -98,7 +120,79 @@ public void CanRoundtripFirewallExceptions()
"Description=A port-based firewall exception",
"Outbound=yes",
"xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall",
- }, actual[1].Attributes);
+ }, actual.Attributes);
+ }
+
+ [Fact]
+ public void RoundtripAttributesAreCorrectForDNSScope()
+ {
+ var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "ExampleDNSScope");
+ WixAssert.CompareLineByLine(new[]
+ {
+ "Id=fexxY71H2ZBkPalv7uid1Yy4qaA_lA",
+ "Name=ExampleDNSScope",
+ "Scope=DNS",
+ "Port=356",
+ "Protocol=udp",
+ "Profile=all",
+ "Description=DNS scope firewall exception",
+ "Outbound=no",
+ "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall",
+ }, actual.Attributes);
+ }
+
+ [Fact]
+ public void RoundtripAttributesAreCorrectForDHCPScope()
+ {
+ var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "ExampleDHCPScope");
+ WixAssert.CompareLineByLine(new[]
+ {
+ "Id=fex6bkfWwpiRGI.wVFx0T7W4LXIHxU",
+ "Name=ExampleDHCPScope",
+ "Scope=DHCP",
+ "Protocol=211",
+ "Program=test.exe",
+ "Profile=public",
+ "Description=DHCP scope firewall exception",
+ "Outbound=no",
+ "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall"
+ }, actual.Attributes);
+ }
+
+ [Fact]
+ public void RoundtripAttributesAreCorrectForWINSScope()
+ {
+ var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "ExampleWINSScope");
+ WixAssert.CompareLineByLine(new[]
+ {
+ "Id=fexXxaXCXXFh.UxO_BjmZxi1B1du_Q",
+ "Name=ExampleWINSScope",
+ "Scope=WINS",
+ "Port=6573",
+ "Protocol=tcp",
+ "Profile=domain",
+ "Description=WINS scope firewall exception",
+ "Outbound=no",
+ "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall",
+ }, actual.Attributes);
+ }
+
+ [Fact]
+ public void RoundtripAttributesAreCorrectForDefaultGatewayScope()
+ {
+ var actual = BuildAndDecompileAndBuild("http://wixtoolset.org/schemas/v4/wxs/firewall", "ExampleDefaultGatewayScope");
+ WixAssert.CompareLineByLine(new[]
+ {
+ "Id=fex_ZpDsnKyHlYiA24JHzvFxm3uLZ8",
+ "Name=ExampleDefaultGatewayScope",
+ "Scope=defaultGateway",
+ "Port=4432",
+ "Protocol=tcp",
+ "Profile=private",
+ "Description=defaultGateway scope firewall exception",
+ "Outbound=no",
+ "xmlns=http://wixtoolset.org/schemas/v4/wxs/firewall",
+ }, actual.Attributes);
}
private static void Build(string[] args)
@@ -122,5 +216,31 @@ private static void Decompile(string[] args)
var result = WixRunner.Execute(args);
result.AssertSuccess();
}
+ class AttributeVerifier
+ {
+ public string Name { get; set; }
+ public string[] Attributes { get; set; }
+ }
+
+ private static AttributeVerifier BuildAndDecompileAndBuild(string nameSpace, string ruleName)
+ {
+ var folder = TestData.Get(@"TestData", "UsingFirewall");
+ var build = new Builder(folder, typeof(FirewallExtensionFactory), new[] { folder });
+ var output = Path.Combine(folder, $"Firewall{ruleName}.xml");
+
+ build.BuildAndDecompileAndBuild(Build, Decompile, output);
+
+ var doc = XDocument.Load(output);
+ var actual = doc.Descendants()
+ .Where(e => e.Name.Namespace == nameSpace)
+ .Select(fe => new AttributeVerifier
+ {
+ Name = fe.Attributes().Single(a => a.Name.LocalName == "Name").Value,
+ Attributes = fe.Attributes().Select(a => $"{a.Name.LocalName}={a.Value}").ToArray()
+ })
+ .Single(av => av.Name == ruleName);
+
+ return actual;
+ }
}
}
diff --git a/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingFirewall/PackageComponents.wxs b/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingFirewall/PackageComponents.wxs
index c712d8959..957aa6427 100644
--- a/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingFirewall/PackageComponents.wxs
+++ b/src/ext/Firewall/test/WixToolsetTest.Firewall/TestData/UsingFirewall/PackageComponents.wxs
@@ -12,6 +12,10 @@
+
+
+
+
diff --git a/src/ext/Firewall/wixext/FirewallCompiler.cs b/src/ext/Firewall/wixext/FirewallCompiler.cs
index 19ee0b6dc..ed49ba9c4 100644
--- a/src/ext/Firewall/wixext/FirewallCompiler.cs
+++ b/src/ext/Firewall/wixext/FirewallCompiler.cs
@@ -135,7 +135,12 @@ private void ParseFirewallExceptionElement(Intermediate intermediate, Intermedia
protocol = FirewallConstants.NET_FW_IP_PROTOCOL_UDP;
break;
default:
- this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Protocol", protocolValue, "tcp", "udp"));
+ int parsedProtocol;
+ if (!Int32.TryParse(protocolValue, out parsedProtocol) || parsedProtocol > 255 || parsedProtocol < 0)
+ {
+ this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Protocol", protocolValue, "tcp", "udp", "0-255"));
+ }
+ protocol = parsedProtocol;
break;
}
break;
@@ -149,8 +154,20 @@ private void ParseFirewallExceptionElement(Intermediate intermediate, Intermedia
case "localSubnet":
remoteAddresses = "LocalSubnet";
break;
+ case "DNS":
+ remoteAddresses = "dns";
+ break;
+ case "DHCP":
+ remoteAddresses = "dhcp";
+ break;
+ case "WINS":
+ remoteAddresses = "wins";
+ break;
+ case "defaultGateway":
+ remoteAddresses = "DefaultGateway";
+ break;
default:
- this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Scope", scope, "any", "localSubnet"));
+ this.Messaging.Write(ErrorMessages.IllegalAttributeValue(sourceLineNumbers, element.Name.LocalName, "Scope", scope, "any", "localSubnet", "DNS", "DHCP", "WINS", "defaultGateway"));
break;
}
break;
@@ -251,6 +268,21 @@ private void ParseFirewallExceptionElement(Intermediate intermediate, Intermedia
this.Messaging.Write(FirewallErrors.NoExceptionSpecified(sourceLineNumbers));
}
+ // Ports can only be specified if the protocol is TCP or UDP.
+ if (!String.IsNullOrEmpty(port) && protocol.HasValue)
+ {
+ switch(protocol.Value)
+ {
+ case FirewallConstants.NET_FW_IP_PROTOCOL_TCP:
+ case FirewallConstants.NET_FW_IP_PROTOCOL_UDP:
+ break;
+
+ default:
+ this.Messaging.Write(ErrorMessages.IllegalAttributeWithOtherAttribute(sourceLineNumbers, element.Name.LocalName, "Port", "Protocol", protocol.Value.ToString()));
+ break;
+ }
+ }
+
if (!this.Messaging.EncounteredError)
{
// at this point, File attribute and File parent element are treated the same
@@ -300,8 +332,8 @@ private void ParseFirewallExceptionElement(Intermediate intermediate, Intermedia
symbol.Attributes = attributes;
}
- this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4SchedFirewallExceptionsInstall", this.Context.Platform, CustomActionPlatforms.ARM64 | CustomActionPlatforms.X64 | CustomActionPlatforms.X86);
- this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix4SchedFirewallExceptionsUninstall", this.Context.Platform, CustomActionPlatforms.ARM64 | CustomActionPlatforms.X64 | CustomActionPlatforms.X86);
+ this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix5SchedFirewallExceptionsInstall", this.Context.Platform, CustomActionPlatforms.ARM64 | CustomActionPlatforms.X64 | CustomActionPlatforms.X86);
+ this.ParseHelper.CreateCustomActionReference(sourceLineNumbers, section, "Wix5SchedFirewallExceptionsUninstall", this.Context.Platform, CustomActionPlatforms.ARM64 | CustomActionPlatforms.X64 | CustomActionPlatforms.X86);
}
}
diff --git a/src/ext/Firewall/wixext/FirewallDecompiler.cs b/src/ext/Firewall/wixext/FirewallDecompiler.cs
index 69f2c3f4d..9ddd8a9a3 100644
--- a/src/ext/Firewall/wixext/FirewallDecompiler.cs
+++ b/src/ext/Firewall/wixext/FirewallDecompiler.cs
@@ -32,7 +32,7 @@ public override bool TryDecompileTable(Table table)
{
switch (table.Name)
{
- case "Wix4FirewallException":
+ case "Wix5FirewallException":
this.DecompileWixFirewallExceptionTable(table);
break;
default:
@@ -69,18 +69,29 @@ private void DecompileWixFirewallExceptionTable(Table table)
string[] addresses = ((string)row[2]).Split(',');
if (addresses.Length == 1)
{
- // special-case the Scope attribute values
- if (addresses[0] == "*")
+ switch(addresses[0])
{
- firewallException.Add(new XAttribute("Scope", "any"));
- }
- else if (addresses[0] == "LocalSubnet")
- {
- firewallException.Add(new XAttribute("Scope", "localSubnet"));
- }
- else
- {
- FirewallDecompiler.AddRemoteAddress(firewallException, addresses[0]);
+ case "*":
+ firewallException.Add(new XAttribute("Scope", "any"));
+ break;
+ case "LocalSubnet":
+ firewallException.Add(new XAttribute("Scope", "localSubnet"));
+ break;
+ case "dns":
+ firewallException.Add(new XAttribute("Scope", "DNS"));
+ break;
+ case "dhcp":
+ firewallException.Add(new XAttribute("Scope", "DHCP"));
+ break;
+ case "wins":
+ firewallException.Add(new XAttribute("Scope", "WINS"));
+ break;
+ case "DefaultGateway":
+ firewallException.Add(new XAttribute("Scope", "defaultGateway"));
+ break;
+ default:
+ FirewallDecompiler.AddRemoteAddress(firewallException, addresses[0]);
+ break;
}
}
else
@@ -107,6 +118,9 @@ private void DecompileWixFirewallExceptionTable(Table table)
case FirewallConstants.NET_FW_IP_PROTOCOL_UDP:
firewallException.Add(new XAttribute("Protocol", "udp"));
break;
+ default:
+ firewallException.Add(new XAttribute("Protocol", row[4]));
+ break;
}
}
@@ -183,7 +197,7 @@ private static XAttribute AttributeIfNotNull(string name, bool value)
/// Collection of all tables.
private void FinalizeFirewallExceptionTable(TableIndexedCollection tables)
{
- if (tables.TryGetTable("Wix4FirewallException", out var firewallExceptionTable))
+ if (tables.TryGetTable("Wix5FirewallException", out var firewallExceptionTable))
{
foreach (var row in firewallExceptionTable.Rows)
{
diff --git a/src/ext/Firewall/wixext/FirewallTableDefinitions.cs b/src/ext/Firewall/wixext/FirewallTableDefinitions.cs
index 04918f5f0..26dedbf1d 100644
--- a/src/ext/Firewall/wixext/FirewallTableDefinitions.cs
+++ b/src/ext/Firewall/wixext/FirewallTableDefinitions.cs
@@ -7,15 +7,15 @@ namespace WixToolset.Firewall
public static class FirewallTableDefinitions
{
public static readonly TableDefinition WixFirewallException = new TableDefinition(
- "Wix4FirewallException",
+ "Wix5FirewallException",
FirewallSymbolDefinitions.WixFirewallException,
new[]
{
- new ColumnDefinition("Wix4FirewallException", ColumnType.String, 72, primaryKey: true, nullable: false, ColumnCategory.Identifier, description: "The primary key, a non-localized token.", modularizeType: ColumnModularizeType.Column),
+ new ColumnDefinition("Wix5FirewallException", 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("Protocol", ColumnType.Number, 1, primaryKey: false, nullable: true, ColumnCategory.Integer, minValue: 0, maxValue: 255, description: "Protocol (6=TCP; 17=UDP). https://www.iana.org/assignments/protocol-numbers"),
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)."),
diff --git a/src/ext/Firewall/wixlib/FirewallExtension_Platform.wxi b/src/ext/Firewall/wixlib/FirewallExtension_Platform.wxi
index ae02bcd0b..736a54b08 100644
--- a/src/ext/Firewall/wixlib/FirewallExtension_Platform.wxi
+++ b/src/ext/Firewall/wixlib/FirewallExtension_Platform.wxi
@@ -6,32 +6,32 @@
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+
+
-
-
+
+
-
+
diff --git a/src/ext/caDecor.h b/src/ext/caDecor.h
index da274650f..060032cf8 100644
--- a/src/ext/caDecor.h
+++ b/src/ext/caDecor.h
@@ -11,3 +11,13 @@
#else
#define CUSTOM_ACTION_DECORATION(f) L"Wix4" f L"_X86"
#endif
+
+#if defined(_M_ARM64)
+#define CUSTOM_ACTION_DECORATION5(f) L"Wix5" f L"_A64"
+#elif defined(_M_AMD64)
+#define CUSTOM_ACTION_DECORATION5(f) L"Wix5" f L"_X64"
+#elif defined(_M_ARM)
+#define CUSTOM_ACTION_DECORATION5(f) L"Wix5" f L"_ARM"
+#else
+#define CUSTOM_ACTION_DECORATION5(f) L"Wix5" f L"_X86"
+#endif
diff --git a/src/ext/caDecor.wxi b/src/ext/caDecor.wxi
index b17115183..256d7586b 100644
--- a/src/ext/caDecor.wxi
+++ b/src/ext/caDecor.wxi
@@ -8,6 +8,12 @@
+
+
+
+
+
+
diff --git a/src/test/msi/TestData/FirewallExtensionTests/ProtocolRules/ProtocolRules.wixproj b/src/test/msi/TestData/FirewallExtensionTests/ProtocolRules/ProtocolRules.wixproj
new file mode 100644
index 000000000..b1770b0f4
--- /dev/null
+++ b/src/test/msi/TestData/FirewallExtensionTests/ProtocolRules/ProtocolRules.wixproj
@@ -0,0 +1,13 @@
+
+
+
+ {4D188568-1CCF-4EEE-BC27-17C3DCC83E58}
+ true
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/msi/TestData/FirewallExtensionTests/ProtocolRules/product.wxs b/src/test/msi/TestData/FirewallExtensionTests/ProtocolRules/product.wxs
new file mode 100644
index 000000000..6a28ad0ae
--- /dev/null
+++ b/src/test/msi/TestData/FirewallExtensionTests/ProtocolRules/product.wxs
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/msi/TestData/FirewallExtensionTests/ScopeRules/ScopeRules.wixproj b/src/test/msi/TestData/FirewallExtensionTests/ScopeRules/ScopeRules.wixproj
new file mode 100644
index 000000000..b1770b0f4
--- /dev/null
+++ b/src/test/msi/TestData/FirewallExtensionTests/ScopeRules/ScopeRules.wixproj
@@ -0,0 +1,13 @@
+
+
+
+ {4D188568-1CCF-4EEE-BC27-17C3DCC83E58}
+ true
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/test/msi/TestData/FirewallExtensionTests/ScopeRules/product.wxs b/src/test/msi/TestData/FirewallExtensionTests/ScopeRules/product.wxs
new file mode 100644
index 000000000..776c86750
--- /dev/null
+++ b/src/test/msi/TestData/FirewallExtensionTests/ScopeRules/product.wxs
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/test/msi/WixToolsetTest.MsiE2E/FirewallExtensionTests.cs b/src/test/msi/WixToolsetTest.MsiE2E/FirewallExtensionTests.cs
index 4106cd724..ce55aa142 100644
--- a/src/test/msi/WixToolsetTest.MsiE2E/FirewallExtensionTests.cs
+++ b/src/test/msi/WixToolsetTest.MsiE2E/FirewallExtensionTests.cs
@@ -315,5 +315,222 @@ public void SucceedWhenIgnoreOnFailureIsSet()
var log2 = product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS, "NORULENAME=1");
Assert.True(LogVerifier.MessageInLogFile(log2, "failed to remove firewall rule"));
}
+
+ [RuntimeFact]
+ public void VarietyOfProtocolValuesCanBeUsed()
+ {
+ var product = this.CreatePackageInstaller("ProtocolRules");
+ product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS);
+
+ var expected1 = new RuleDetails("WiXToolset401 Test - 0009")
+ {
+ Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW,
+ Description = "WiX Toolset firewall exception rule integration test - protocol TCP",
+ Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN,
+ EdgeTraversal = false,
+ EdgeTraversalOptions = 0,
+ Enabled = true,
+ InterfaceTypes = "All",
+ LocalAddresses = "*",
+ Profiles = Int32.MaxValue,
+ Protocol = 6,
+ RemoteAddresses = "*",
+ SecureFlags = 0,
+ LocalPorts = "900",
+ RemotePorts = "*",
+ };
+
+ Verifier.VerifyFirewallRule("WiXToolset401 Test - 0009", expected1);
+
+
+ var expected2 = new RuleDetails("WiXToolset401 Test - 0010")
+ {
+ Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW,
+ Description = "WiX Toolset firewall exception rule integration test - protocol UDP",
+ Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN,
+ EdgeTraversal = false,
+ EdgeTraversalOptions = 0,
+ Enabled = true,
+ InterfaceTypes = "All",
+ LocalAddresses = "*",
+ Profiles = Int32.MaxValue,
+ Protocol = 17,
+ RemoteAddresses = "*",
+ SecureFlags = 0,
+ LocalPorts = "1000",
+ RemotePorts = "*",
+ };
+
+ Verifier.VerifyFirewallRule("WiXToolset401 Test - 0010", expected2);
+
+
+ var expected3 = new RuleDetails("WiXToolset401 Test - 0011")
+ {
+ Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW,
+ ApplicationName = "test.exe",
+ Description = "WiX Toolset firewall exception rule integration test - ports can only be specified if protocol is TCP or UDP",
+ Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN,
+ EdgeTraversal = true,
+ EdgeTraversalOptions = 1,
+ Enabled = true,
+ InterfaceTypes = "All",
+ LocalAddresses = "*",
+ Profiles = Int32.MaxValue,
+ Protocol = 134,
+ RemoteAddresses = "*",
+ SecureFlags = 0,
+ };
+
+ Verifier.VerifyFirewallRule("WiXToolset401 Test - 0011", expected3);
+
+ product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS);
+
+ // verify the firewall exceptions have been removed.
+ Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0009"));
+ Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0010"));
+ Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0011"));
+ }
+
+ [RuntimeFact]
+ public void FullSetOfScopeValuesCanBeUsed()
+ {
+ var product = this.CreatePackageInstaller("ScopeRules");
+ product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS);
+
+ var expected1 = new RuleDetails("WiXToolset401 Test - 0012")
+ {
+ Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW,
+ Description = "WiX Toolset firewall exception rule integration test - scope any",
+ Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN,
+ EdgeTraversal = false,
+ EdgeTraversalOptions = 0,
+ Enabled = true,
+ InterfaceTypes = "All",
+ LocalAddresses = "*",
+ Profiles = Int32.MaxValue,
+ Protocol = 6,
+ RemoteAddresses = "*",
+ SecureFlags = 0,
+ LocalPorts = "1200",
+ RemotePorts = "*",
+ };
+
+ Verifier.VerifyFirewallRule("WiXToolset401 Test - 0012", expected1);
+
+
+ var expected2 = new RuleDetails("WiXToolset401 Test - 0013")
+ {
+ Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW,
+ Description = "WiX Toolset firewall exception rule integration test - scope local subnet",
+ Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN,
+ EdgeTraversal = false,
+ EdgeTraversalOptions = 0,
+ Enabled = true,
+ InterfaceTypes = "All",
+ LocalAddresses = "*",
+ Profiles = Int32.MaxValue,
+ Protocol = 6,
+ RemoteAddresses = "LocalSubnet",
+ SecureFlags = 0,
+ LocalPorts = "1300",
+ RemotePorts = "*",
+ };
+
+ Verifier.VerifyFirewallRule("WiXToolset401 Test - 0013", expected2);
+
+
+ var expected3 = new RuleDetails("WiXToolset401 Test - 0014")
+ {
+ Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW,
+ Description = "WiX Toolset firewall exception rule integration test - scope DNS",
+ Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN,
+ EdgeTraversal = false,
+ EdgeTraversalOptions = 0,
+ Enabled = true,
+ InterfaceTypes = "All",
+ LocalAddresses = "*",
+ Profiles = Int32.MaxValue,
+ Protocol = 6,
+ RemoteAddresses = "DNS",
+ SecureFlags = 0,
+ LocalPorts = "1400",
+ RemotePorts = "*",
+ };
+
+ Verifier.VerifyFirewallRule("WiXToolset401 Test - 0014", expected3);
+
+
+ var expected4 = new RuleDetails("WiXToolset401 Test - 0015")
+ {
+ Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW,
+ Description = "WiX Toolset firewall exception rule integration test - scope DHCP",
+ Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN,
+ EdgeTraversal = false,
+ EdgeTraversalOptions = 0,
+ Enabled = true,
+ InterfaceTypes = "All",
+ LocalAddresses = "*",
+ Profiles = Int32.MaxValue,
+ Protocol = 6,
+ RemoteAddresses = "DHCP",
+ SecureFlags = 0,
+ LocalPorts = "1500",
+ RemotePorts = "*",
+ };
+
+ Verifier.VerifyFirewallRule("WiXToolset401 Test - 0015", expected4);
+
+
+ var expected5 = new RuleDetails("WiXToolset401 Test - 0016")
+ {
+ Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW,
+ Description = "WiX Toolset firewall exception rule integration test - scope WINS",
+ Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN,
+ EdgeTraversal = false,
+ EdgeTraversalOptions = 0,
+ Enabled = true,
+ InterfaceTypes = "All",
+ LocalAddresses = "*",
+ Profiles = Int32.MaxValue,
+ Protocol = 6,
+ RemoteAddresses = "WINS",
+ SecureFlags = 0,
+ LocalPorts = "1600",
+ RemotePorts = "*",
+ };
+
+ Verifier.VerifyFirewallRule("WiXToolset401 Test - 0016", expected5);
+
+
+ var expected6 = new RuleDetails("WiXToolset401 Test - 0017")
+ {
+ Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW,
+ Description = "WiX Toolset firewall exception rule integration test - scope default gateway",
+ Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN,
+ EdgeTraversal = false,
+ EdgeTraversalOptions = 0,
+ Enabled = true,
+ InterfaceTypes = "All",
+ LocalAddresses = "*",
+ Profiles = Int32.MaxValue,
+ Protocol = 6,
+ RemoteAddresses = "DefaultGateway",
+ SecureFlags = 0,
+ LocalPorts = "1700",
+ RemotePorts = "*",
+ };
+
+ Verifier.VerifyFirewallRule("WiXToolset401 Test - 0017", expected6);
+
+ product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS);
+
+ // verify the firewall exceptions have been removed.
+ Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0012"));
+ Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0013"));
+ Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0014"));
+ Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0015"));
+ Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0016"));
+ Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0017"));
+ }
}
}
diff --git a/src/wix/WixToolset.Converters/WixConverter.cs b/src/wix/WixToolset.Converters/WixConverter.cs
index f3675ecc6..178b90bee 100644
--- a/src/wix/WixToolset.Converters/WixConverter.cs
+++ b/src/wix/WixToolset.Converters/WixConverter.cs
@@ -205,8 +205,8 @@ public sealed class WixConverter
{ "WixDependencyRequire", "Wix4DependencyRequire_" },
{ "WixDependencyCheck", "Wix4DependencyCheck_" },
{ "WixQueryDirectXCaps", "Wix4QueryDirectXCaps_" },
- { "WixSchedFirewallExceptionsUninstall", "Wix4SchedFirewallExceptionsUninstall_" },
- { "WixSchedFirewallExceptionsInstall", "Wix4SchedFirewallExceptionsInstall_" },
+ { "WixSchedFirewallExceptionsUninstall", "Wix5SchedFirewallExceptionsUninstall_" },
+ { "WixSchedFirewallExceptionsInstall", "Wix5SchedFirewallExceptionsInstall_" },
{ "WixSchedHttpUrlReservationsUninstall", "Wix4SchedHttpUrlReservationsUninstall_" },
{ "WixSchedHttpUrlReservationsInstall", "Wix4SchedHttpUrlReservationsInstall_" },
{ "ConfigureIIs", "Wix4ConfigureIIs_" },