diff --git a/src/ext/Firewall/ca/firewall.cpp b/src/ext/Firewall/ca/firewall.cpp index b45cbcdd7..35c8be6e3 100644 --- a/src/ext/Firewall/ca/firewall.cpp +++ b/src/ext/Firewall/ca/firewall.cpp @@ -79,7 +79,7 @@ static UINT SchedFirewallExceptions( hr = WcaGetRecordString(hRec, feqComponent, &pwzComponent); ExitOnFailure(hr, "Failed to get firewall exception component."); - hr = WcaGetRecordString(hRec, feqDescription, &pwzDescription); + hr = WcaGetRecordFormattedString(hRec, feqDescription, &pwzDescription); ExitOnFailure(hr, "Failed to get firewall exception description."); hr = WcaGetRecordInteger(hRec, feqDirection, &iDirection); diff --git a/src/test/burn/WixTestTools/Firewall/RuleDetails.cs b/src/test/burn/WixTestTools/Firewall/RuleDetails.cs index 38a80bb8f..d1e53de4f 100644 --- a/src/test/burn/WixTestTools/Firewall/RuleDetails.cs +++ b/src/test/burn/WixTestTools/Firewall/RuleDetails.cs @@ -164,7 +164,7 @@ public RuleDetails(INetFwRule3 rule) public bool? Enabled { get; set; } /// - /// This property is optional. It specifies the group to which an individual rule belongs and groups multiple rules into a single line in the Windows Firewall control panel
+ /// This property is optional. It specifies the group to which an individual rule belongs and groups multiple rules into a single line in the Windows Firewall control panel.
/// This allows the users to enable or disable multiple rules with a single click.
/// The Grouping property can also be specified using indirect strings.
/// Example: "Simple Group Name"
@@ -193,7 +193,7 @@ public RuleDetails(INetFwRule3 rule) /// /// This property is optional. The NET_FW_ACTION enumerated type specifies the action for this rule.
- /// NET_FW_ACTION_ALLOW is the default value. Profiles can be combined from the following values:
+ /// NET_FW_ACTION_ALLOW is the default value. The Action must be specified from the following list of values:
/// o NET_FW_ACTION_BLOCK = 0x0
/// o NET_FW_ACTION_ALLOW = 0x1
///
diff --git a/src/test/burn/WixTestTools/Firewall/UniqueCheck.cs b/src/test/burn/WixTestTools/Firewall/UniqueCheck.cs index 83a1e57a6..598350f9c 100644 --- a/src/test/burn/WixTestTools/Firewall/UniqueCheck.cs +++ b/src/test/burn/WixTestTools/Firewall/UniqueCheck.cs @@ -6,7 +6,7 @@ namespace WixTestTools.Firewall /// /// A lot of firewall rules don't follow the Microsoft recommendation of using unique names.
- /// This class helps to disambiguate the rules based on Name, Direction, Profile, Protocol, ApplicationName and the LocalUserOwner. + /// This class helps to disambiguate the rules based on Name, Direction, Profile, Protocol, ApplicationName, LocalUserOwner and RemoteAddresses. ///
public class UniqueCheck { @@ -22,6 +22,7 @@ public UniqueCheck(RuleDetails details) this.Protocol = details.Protocol; this.ApplicationName = details.ApplicationName; this.LocalUserOwner = details.LocalUserOwner; + this.RemoteAddresses = details.RemoteAddresses; } @@ -37,6 +38,7 @@ public UniqueCheck(RuleDetails details) public string LocalUserOwner { get; set; } + public string RemoteAddresses { get; set; } public bool FirewallRuleIsUnique(INetFwRule3 rule) { @@ -70,6 +72,11 @@ public bool FirewallRuleIsUnique(INetFwRule3 rule) return false; } + if (this.RemoteAddresses != null && rule.RemoteAddresses != this.RemoteAddresses) + { + return false; + } + return true; } } diff --git a/src/test/burn/WixTestTools/Firewall/Verifier.cs b/src/test/burn/WixTestTools/Firewall/Verifier.cs index d3f32c5c7..c1bf32195 100644 --- a/src/test/burn/WixTestTools/Firewall/Verifier.cs +++ b/src/test/burn/WixTestTools/Firewall/Verifier.cs @@ -281,7 +281,9 @@ public static void VerifyFirewallRule(string name, RuleDetails expected, UniqueC Assert.True(expected.ServiceName == actual.ServiceName, FormatErrorMessage(name, "ServiceNames", expected.ServiceName, actual.ServiceName, unique)); Assert.True(expected.Protocol == actual.Protocol, FormatErrorMessage(name, "Protocols", expected.Protocol, actual.Protocol, unique)); Assert.True(expected.LocalPorts == actual.LocalPorts, FormatErrorMessage(name, "LocalPorts", expected.LocalPorts, actual.LocalPorts, unique)); + Assert.True(expected.LocalAddresses == actual.LocalAddresses, FormatErrorMessage(name, "LocalAddresses", expected.LocalAddresses, actual.LocalAddresses, unique)); Assert.True(expected.RemotePorts == actual.RemotePorts, FormatErrorMessage(name, "RemotePorts", expected.RemotePorts, actual.RemotePorts, unique)); + Assert.True(expected.RemoteAddresses == actual.RemoteAddresses, FormatErrorMessage(name, "RemoteAddresses", expected.RemoteAddresses, actual.RemoteAddresses, unique)); Assert.True(expected.IcmpTypesAndCodes == actual.IcmpTypesAndCodes, FormatErrorMessage(name, "IcmpTypesAndCodes", expected.IcmpTypesAndCodes, actual.Description, unique)); Assert.True(expected.Direction == actual.Direction, FormatErrorMessage(name, "Directions", expected.Direction, actual.Direction, unique)); Assert.Equal(expected.Interfaces, actual.Interfaces); diff --git a/src/test/msi/TestData/FirewallExtensionTests/DynamicFirewallRules/DynamicFirewallRules.wixproj b/src/test/msi/TestData/FirewallExtensionTests/DynamicFirewallRules/DynamicFirewallRules.wixproj new file mode 100644 index 000000000..b39f73875 --- /dev/null +++ b/src/test/msi/TestData/FirewallExtensionTests/DynamicFirewallRules/DynamicFirewallRules.wixproj @@ -0,0 +1,13 @@ + + + + {C587F355-26FF-4D17-801F-50505C348D99} + true + + + + + + + + \ No newline at end of file diff --git a/src/test/msi/TestData/FirewallExtensionTests/DynamicFirewallRules/product.wxs b/src/test/msi/TestData/FirewallExtensionTests/DynamicFirewallRules/product.wxs new file mode 100644 index 000000000..6bc45c10b --- /dev/null +++ b/src/test/msi/TestData/FirewallExtensionTests/DynamicFirewallRules/product.wxs @@ -0,0 +1,50 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/msi/WixToolsetTest.MsiE2E/FirewallExtensionTests.cs b/src/test/msi/WixToolsetTest.MsiE2E/FirewallExtensionTests.cs index fce958458..3e605d7af 100644 --- a/src/test/msi/WixToolsetTest.MsiE2E/FirewallExtensionTests.cs +++ b/src/test/msi/WixToolsetTest.MsiE2E/FirewallExtensionTests.cs @@ -200,5 +200,82 @@ public void MissingApplicationFirewallRuleIsAddedAfterRepair() Verifier.VerifyFirewallRule("WiXToolset401 Test - 0001", expected); } + + [RuntimeFact] + public void FirewallRulesUseFormattedStringProperties() + { + var product = this.CreatePackageInstaller("DynamicFirewallRules"); + product.InstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); + + var expected1 = new RuleDetails("WiXToolset401 Test - 0003") + { + Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, + ApplicationName = this.TestContext.GetTestInstallFolder(false, Path.Combine("DynamicFirewallRules", "product.wxs")), + Description = "WiX Toolset firewall exception rule integration test - dynamic app description 9999", + Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, + EdgeTraversal = true, + EdgeTraversalOptions = 1, + Enabled = true, + InterfaceTypes = "All", + LocalAddresses = "*", + Profiles = Int32.MaxValue, + Protocol = 6, + RemoteAddresses = "LocalSubnet", + SecureFlags = 0, + LocalPorts = "9999", + RemotePorts = "*", + }; + + Verifier.VerifyFirewallRule("WiXToolset401 Test - 0003", expected1); + + var expected2 = new RuleDetails("WiXToolset401 Test - 0004") + { + Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, + Description = "WiX Toolset firewall exception rule integration test - dynamic port description 9999", + 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 = "9999", + RemotePorts = "*", + }; + + Verifier.VerifyFirewallRule("WiXToolset401 Test - 0004", expected2); + + + var expected3 = new RuleDetails("WiXToolset401 Test - 0005 - 9999") + { + Action = NET_FW_ACTION_.NET_FW_ACTION_ALLOW, + ApplicationName = Path.Combine(Environment.GetEnvironmentVariable("windir"), "system32", "9999.exe"), + Description = "WiX Toolset firewall exception rule integration test - dynamic Name 9999", + Direction = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_IN, + EdgeTraversal = true, + EdgeTraversalOptions = 1, + Enabled = true, + InterfaceTypes = "All", + LocalAddresses = "*", + Profiles = 2, + Protocol = 17, + RemoteAddresses = "127.0.0.1/255.255.255.255,192.168.1.1/255.255.255.255", + SecureFlags = 0, + LocalPorts = "9999", + RemotePorts = "*", + }; + + Verifier.VerifyFirewallRule("WiXToolset401 Test - 0005 - 9999", expected3); + + product.UninstallProduct(MSIExec.MSIExecReturnCode.SUCCESS); + + // verify the firewall exceptions have been removed. + Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0003")); + Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0004")); + Assert.False(Verifier.FirewallRuleExists("WiXToolset401 Test - 0005 - 9999")); + } } }