use Firewall in empty_session

This commit is contained in:
2025-12-12 03:52:40 -05:00
committed by sapphire
parent d185ab1a57
commit 50b5388f8a
2 changed files with 27 additions and 41 deletions
+23 -38
View File
@@ -1,18 +1,12 @@
use crate::util::{countdown::Countdown, system_info::SystemInfo}; use crate::util::{
countdown::Countdown,
firewall::{Firewall, RuleDirection, RuleMode, RuleProtocol},
system_info::SystemInfo,
};
use std::{ use std::{
error::Error, error::Error,
time::{Duration, Instant}, time::{Duration, Instant},
}; };
use windows::{
Win32::{
NetworkManagement::WindowsFirewall::{
INetFwPolicy2, INetFwRule, NET_FW_ACTION_BLOCK, NET_FW_IP_PROTOCOL_UDP,
NET_FW_RULE_DIR_IN, NET_FW_RULE_DIR_OUT, NetFwPolicy2, NetFwRule,
},
System::Com::{CLSCTX_INPROC_SERVER, CoCreateInstance},
},
core::BSTR,
};
const FILTER_NAME_EMPTY_SESSION_IN: &str = "[GTA Tools] Block inbound UDP traffic for all of GTA V"; const FILTER_NAME_EMPTY_SESSION_IN: &str = "[GTA Tools] Block inbound UDP traffic for all of GTA V";
const FILTER_NAME_EMPTY_SESSION_OUT: &str = const FILTER_NAME_EMPTY_SESSION_OUT: &str =
@@ -38,51 +32,42 @@ impl Default for EmptySession {
} }
impl EmptySession { impl EmptySession {
pub fn run_timers(&mut self) -> Result<(), Box<dyn Error>> { pub fn run_timers(&mut self, firewall: &Firewall) -> Result<(), Box<dyn Error>> {
if self.disabled { if self.disabled {
self.countdown.count(); self.countdown.count();
} else { } else {
self.countdown.reset(); self.countdown.reset();
} }
if self.interval.elapsed() >= INTERVAL { if self.interval.elapsed() >= INTERVAL {
deactivate()?; deactivate(firewall)?;
self.disabled = false; self.disabled = false;
} }
Ok(()) Ok(())
} }
} }
pub fn activate(system_info: &mut SystemInfo) -> Result<bool, Box<dyn Error>> { pub fn activate(system_info: &mut SystemInfo, firewall: &Firewall) -> Result<bool, Box<dyn Error>> {
let Some(exe_path) = system_info.get_game_exe_path() else { let Some(exe_path) = system_info.get_game_exe_path() else {
log::info!("wasn't able to find game exe"); log::info!("wasn't able to find game exe");
return Ok(false); return Ok(false);
}; };
for (direction, filter_name) in [ firewall.add(
(NET_FW_RULE_DIR_IN, FILTER_NAME_EMPTY_SESSION_IN), FILTER_NAME_EMPTY_SESSION_IN,
(NET_FW_RULE_DIR_OUT, FILTER_NAME_EMPTY_SESSION_OUT), RuleMode::Executable(exe_path.to_path_buf()),
] { RuleDirection::In,
let policy: INetFwPolicy2 = RuleProtocol::Udp,
unsafe { CoCreateInstance(&NetFwPolicy2, None, CLSCTX_INPROC_SERVER) }?; )?;
let rules = unsafe { policy.Rules() }?; firewall.add(
unsafe { rules.Remove(&BSTR::from(filter_name)) }?; FILTER_NAME_EMPTY_SESSION_OUT,
let rule: INetFwRule = unsafe { CoCreateInstance(&NetFwRule, None, CLSCTX_INPROC_SERVER) }?; RuleMode::Executable(exe_path.to_path_buf()),
unsafe { rule.SetName(&BSTR::from(filter_name)) }?; RuleDirection::Out,
unsafe { rule.SetApplicationName(&BSTR::from(exe_path.to_string_lossy().to_string())) }?; RuleProtocol::Udp,
unsafe { rule.SetDirection(direction) }?; )?;
unsafe { rule.SetEnabled(true.into()) }?;
unsafe { rule.SetAction(NET_FW_ACTION_BLOCK) }?;
unsafe { rule.SetProtocol(NET_FW_IP_PROTOCOL_UDP.0) }?;
unsafe { rules.Add(&rule) }?;
}
Ok(true) Ok(true)
} }
pub fn deactivate() -> Result<(), Box<dyn Error>> { pub fn deactivate(firewall: &Firewall) -> Result<(), Box<dyn Error>> {
let policy: INetFwPolicy2 = firewall.remove(FILTER_NAME_EMPTY_SESSION_IN)?;
unsafe { CoCreateInstance(&NetFwPolicy2, None, CLSCTX_INPROC_SERVER) }?; firewall.remove(FILTER_NAME_EMPTY_SESSION_OUT)?;
let rules = unsafe { policy.Rules() }?;
for filter_name in [FILTER_NAME_EMPTY_SESSION_IN, FILTER_NAME_EMPTY_SESSION_OUT] {
unsafe { rules.Remove(&BSTR::from(filter_name)) }?;
}
Ok(()) Ok(())
} }
+4 -3
View File
@@ -61,7 +61,7 @@ pub struct App {
impl eframe::App for App { impl eframe::App for App {
fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) {
ctx.request_repaint_after(Duration::from_millis(100)); ctx.request_repaint_after(Duration::from_millis(100));
self.empty_session.run_timers().unwrap(); self.empty_session.run_timers(&self.firewall).unwrap();
egui::TopBottomPanel::bottom("bottom_panel") egui::TopBottomPanel::bottom("bottom_panel")
.exact_height(25.0) .exact_height(25.0)
.show(ctx, |ui| { .show(ctx, |ui| {
@@ -123,7 +123,8 @@ impl App {
ui.add_enabled_ui(!self.empty_session.disabled, |ui| { ui.add_enabled_ui(!self.empty_session.disabled, |ui| {
ui.horizontal(|ui| { ui.horizontal(|ui| {
if ui.button("Empty current session").clicked() if ui.button("Empty current session").clicked()
&& features::empty_session::activate(&mut self.system_info).unwrap() && features::empty_session::activate(&mut self.system_info, &self.firewall)
.unwrap()
{ {
self.empty_session.interval = Instant::now(); self.empty_session.interval = Instant::now();
self.empty_session.disabled = true; self.empty_session.disabled = true;
@@ -333,7 +334,7 @@ impl Drop for App {
} }
.set(); .set();
// make sure we are not network blocking game // make sure we are not network blocking game
if let Err(why) = features::empty_session::deactivate() { if let Err(why) = features::empty_session::deactivate(&self.firewall) {
log::error!("couldn't deactivate empty session: {why}"); log::error!("couldn't deactivate empty session: {why}");
} }
} }