diff --git a/src/features/empty_session.rs b/src/features/empty_session.rs index b286d09..ebeeee0 100644 --- a/src/features/empty_session.rs +++ b/src/features/empty_session.rs @@ -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::{ error::Error, 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_OUT: &str = @@ -38,51 +32,42 @@ impl Default for EmptySession { } impl EmptySession { - pub fn run_timers(&mut self) -> Result<(), Box> { + pub fn run_timers(&mut self, firewall: &Firewall) -> Result<(), Box> { if self.disabled { self.countdown.count(); } else { self.countdown.reset(); } if self.interval.elapsed() >= INTERVAL { - deactivate()?; + deactivate(firewall)?; self.disabled = false; } Ok(()) } } -pub fn activate(system_info: &mut SystemInfo) -> Result> { +pub fn activate(system_info: &mut SystemInfo, firewall: &Firewall) -> Result> { let Some(exe_path) = system_info.get_game_exe_path() else { log::info!("wasn't able to find game exe"); return Ok(false); }; - for (direction, filter_name) in [ - (NET_FW_RULE_DIR_IN, FILTER_NAME_EMPTY_SESSION_IN), - (NET_FW_RULE_DIR_OUT, FILTER_NAME_EMPTY_SESSION_OUT), - ] { - let policy: INetFwPolicy2 = - unsafe { CoCreateInstance(&NetFwPolicy2, None, CLSCTX_INPROC_SERVER) }?; - let rules = unsafe { policy.Rules() }?; - unsafe { rules.Remove(&BSTR::from(filter_name)) }?; - let rule: INetFwRule = unsafe { CoCreateInstance(&NetFwRule, None, CLSCTX_INPROC_SERVER) }?; - unsafe { rule.SetName(&BSTR::from(filter_name)) }?; - unsafe { rule.SetApplicationName(&BSTR::from(exe_path.to_string_lossy().to_string())) }?; - 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) }?; - } + firewall.add( + FILTER_NAME_EMPTY_SESSION_IN, + RuleMode::Executable(exe_path.to_path_buf()), + RuleDirection::In, + RuleProtocol::Udp, + )?; + firewall.add( + FILTER_NAME_EMPTY_SESSION_OUT, + RuleMode::Executable(exe_path.to_path_buf()), + RuleDirection::Out, + RuleProtocol::Udp, + )?; Ok(true) } -pub fn deactivate() -> Result<(), Box> { - let policy: INetFwPolicy2 = - unsafe { CoCreateInstance(&NetFwPolicy2, None, CLSCTX_INPROC_SERVER) }?; - 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)) }?; - } +pub fn deactivate(firewall: &Firewall) -> Result<(), Box> { + firewall.remove(FILTER_NAME_EMPTY_SESSION_IN)?; + firewall.remove(FILTER_NAME_EMPTY_SESSION_OUT)?; Ok(()) } diff --git a/src/gui/app.rs b/src/gui/app.rs index 890ca27..f0255cb 100644 --- a/src/gui/app.rs +++ b/src/gui/app.rs @@ -61,7 +61,7 @@ pub struct App { impl eframe::App for App { fn update(&mut self, ctx: &egui::Context, _frame: &mut eframe::Frame) { 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") .exact_height(25.0) .show(ctx, |ui| { @@ -123,7 +123,8 @@ impl App { ui.add_enabled_ui(!self.empty_session.disabled, |ui| { ui.horizontal(|ui| { 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.disabled = true; @@ -333,7 +334,7 @@ impl Drop for App { } .set(); // 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}"); } }