diff --git a/ServerPickerX/ServerPickerX.csproj b/ServerPickerX/ServerPickerX.csproj
index 62d2272..64d084c 100644
--- a/ServerPickerX/ServerPickerX.csproj
+++ b/ServerPickerX/ServerPickerX.csproj
@@ -6,6 +6,8 @@
true
true
+
+ true
partial
@@ -20,8 +22,8 @@
https://github.com/FN-FAL113/server-picker-x
https://github.com/FN-FAL113/server-picker-x
Assets\favicon.ico
- 1.0.3.0
- 1.0.3.0
+ 1.0.4.0
+ 1.0.4.0
@@ -31,6 +33,10 @@
+
+ libs\Interop.NetFwTypeLib.dll
+ true
+
diff --git a/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs b/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs
index 433da09..4684002 100644
--- a/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs
+++ b/ServerPickerX/Services/SystemFirewalls/WindowsFirewallService.cs
@@ -10,6 +10,7 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
+using NetFwTypeLib;
namespace ServerPickerX.Services.SystemFirewalls
{
@@ -20,73 +21,64 @@ public class WindowsFirewallService(
IProcessService _processService
) : ISystemFirewallService
{
+ private const string _firewallRulePrefix = "server_picker_x_";
+ private const NET_FW_RULE_DIRECTION_ _firewallRuleDirectionOutbound = NET_FW_RULE_DIRECTION_.NET_FW_RULE_DIR_OUT;
+ private const NET_FW_ACTION_ _firewallRuleActionBlock = NET_FW_ACTION_.NET_FW_ACTION_BLOCK;
+ private const int _firewallRuleProtocolAny = 256;
+ private const int _firewallRuleProfilesAll = int.MaxValue;
+
public async Task BlockServersAsync(ObservableCollection serverModels)
{
- foreach (var serverModel in serverModels)
+ try
{
- string ipAddresses = string.Join(",", serverModel.RelayModels.Select(s => s.IPv4).ToList());
-
- using var process = _processService.CreateProcess("cmd.exe");
-
- process.StartInfo.Arguments = $"/c {Path.Combine(Environment.SystemDirectory, "netsh.exe")} " +
- "advfirewall firewall " +
- "add rule " +
- "name=server_picker_x_" + serverModel.Description.Replace(" ", "") +
- " dir=out action=block protocol=ANY " + "remoteip=" + ipAddresses;
-
- try
- {
- process.Start();
- await process.WaitForExitAsync();
-
- string stdOut = process.StandardOutput.ReadToEnd().Trim();
- string stdErr = process.StandardError.ReadToEnd().Trim();
+ INetFwPolicy2 firewallPolicy = GetFirewallPolicyApi();
+ INetFwRules firewallRules = firewallPolicy.Rules;
- if (process.ExitCode > 0)
- {
- await _loggerService.LogWarningAsync("StdOut: " + stdOut + " StdErr: " + stdErr);
- }
- }
- catch (Exception ex)
+ foreach (var serverModel in serverModels)
{
- // Perform debugging here if necessary (log error or through debugger breakpoints)
- throw;
+ string ruleName = GetFirewallRuleName(serverModel);
+ string ipAddresses = string.Join(",", serverModel.RelayModels.Select(s => s.IPv4));
+
+ RemoveFirewallRuleByName(firewallRules, ruleName);
+
+ INetFwRule firewallRule = CreateFirewallRuleApi();
+ firewallRule.Name = ruleName;
+ firewallRule.Description = serverModel.Description;
+ firewallRule.Direction = _firewallRuleDirectionOutbound;
+ firewallRule.Action = _firewallRuleActionBlock;
+ firewallRule.Protocol = _firewallRuleProtocolAny;
+ firewallRule.RemoteAddresses = ipAddresses;
+ firewallRule.Enabled = true;
+ firewallRule.Profiles = _firewallRuleProfilesAll;
+
+ firewallRules.Add(firewallRule);
}
}
+ catch (Exception ex)
+ {
+ await _loggerService.LogErrorAsync(ex.Message);
+ throw;
+ }
}
public async Task UnblockServersAsync(ObservableCollection serverModels)
{
- foreach (var serverModel in serverModels)
+ try
{
- string ipAddresses = string.Join(",", serverModel.RelayModels.Select(s => s.IPv4).ToList());
-
- using var process = _processService.CreateProcess("cmd.exe");
-
- process.StartInfo.Arguments = $"/c {Path.Combine(Environment.SystemDirectory, "netsh.exe")} " +
- "advfirewall firewall " +
- "delete rule " +
- "name=server_picker_x_" + serverModel.Description.Replace(" ", "");
+ INetFwPolicy2 firewallPolicy = GetFirewallPolicyApi();
+ INetFwRules firewallRules = firewallPolicy.Rules;
- try
- {
- process.Start();
- await process.WaitForExitAsync();
-
- string stdOut = process.StandardOutput.ReadToEnd().Trim();
- string stdErr = process.StandardError.ReadToEnd().Trim();
-
- if (process.ExitCode > 0)
- {
- await _loggerService.LogWarningAsync("StdOut: " + stdOut + " StdErr: " + stdErr);
- }
- }
- catch (Exception ex)
+ foreach (var serverModel in serverModels)
{
- // Perform debugging here if necessary (log error or through debugger breakpoints)
- throw;
+ string ruleName = GetFirewallRuleName(serverModel);
+ RemoveFirewallRuleByName(firewallRules, ruleName);
}
}
+ catch (Exception ex)
+ {
+ await _loggerService.LogErrorAsync(ex.Message);
+ throw;
+ }
}
public async Task ResetFirewallAsync()
@@ -97,10 +89,7 @@ public async Task ResetFirewallAsync()
MsBox.Avalonia.Enums.Icon.Warning
);
- if (!result)
- {
- return;
- }
+ if (!result) return;
using Process process = _processService.CreateProcess("cmd.exe");
@@ -127,9 +116,36 @@ await _messageBoxService.ShowMessageBoxAsync(
}
catch (Exception ex)
{
- // Perform debugging here if necessary (log error or through debugger breakpoints)
+ await _loggerService.LogErrorAsync(ex.Message);
throw;
}
}
+
+ public INetFwPolicy2 GetFirewallPolicyApi()
+ => (INetFwPolicy2)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("E2B3C97F-6AE1-41AC-817A-F6F92166D7DD"))!)!;
+
+ public INetFwRule CreateFirewallRuleApi()
+ => (INetFwRule)Activator.CreateInstance(Type.GetTypeFromCLSID(new Guid("2C5BC43E-3369-4C33-AB0C-BE9469677AF4"))!)!;
+
+ public string GetFirewallRuleName(ServerModel serverModel)
+ => _firewallRulePrefix + serverModel.Description.Replace(" ", "");
+
+ public void RemoveFirewallRuleByName(INetFwRules firewallRules, string ruleName)
+ {
+ while (TryGetFirewallRule(firewallRules, ruleName) != null)
+ {
+ firewallRules.Remove(ruleName);
+ }
+ }
+
+ public INetFwRule? TryGetFirewallRule(INetFwRules firewallRules, string ruleName)
+ {
+ try
+ {
+ return firewallRules.Item(ruleName);
+ } catch {
+ return null;
+ }
+ }
}
-}
\ No newline at end of file
+}
diff --git a/ServerPickerX/libs/Interop.NetFwTypeLib.dll b/ServerPickerX/libs/Interop.NetFwTypeLib.dll
new file mode 100644
index 0000000..d52e0ed
Binary files /dev/null and b/ServerPickerX/libs/Interop.NetFwTypeLib.dll differ