remove conditional elevation

This commit is contained in:
2026-06-28 16:14:49 +01:00
parent 054c86e2d2
commit 1f296c3880
6 changed files with 103 additions and 176 deletions
-2
View File
@@ -28,12 +28,10 @@ serde_json = "1.0.143"
strum = { version = "0.27.2", features = ["derive"] }
windows = { version = "0.62.0", features = [
"Win32_NetworkManagement_WindowsFirewall",
"Win32_Security",
"Win32_System_Com",
"Win32_System_Diagnostics_ToolHelp",
"Win32_System_Threading",
"Win32_UI_Input_KeyboardAndMouse",
"Win32_UI_Shell",
"Win32_UI_WindowsAndMessaging",
] }
winreg = "0.55.0"
+11
View File
@@ -6,6 +6,17 @@ fn main() {
.set("LegalCopyright", "futile <git@futile.eu>")
.set_language(0x0009)
.set_icon("assets/icon.ico")
.set_manifest(
r#"<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" uiAccess="false"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>"#,
)
.compile()
.unwrap();
embed_latest_git_hash();
+87 -110
View File
@@ -29,7 +29,6 @@ enum Stage {
#[derive(Debug)]
pub struct Flags {
pub elevated: bool,
pub debug: bool,
closing: bool,
}
@@ -37,7 +36,6 @@ pub struct Flags {
impl Default for Flags {
fn default() -> Self {
Self {
elevated: win::is_elevated(),
debug: false,
closing: false,
}
@@ -67,15 +65,6 @@ impl eframe::App for App {
.show(ctx, |ui| {
ui.with_layout(egui::Layout::left_to_right(egui::Align::Center), |ui| {
ui.build_menu(&mut self.stage);
ui.with_layout(egui::Layout::right_to_left(egui::Align::Center), |ui| {
let button = ui
.add_enabled(!self.flags.elevated, egui::Button::new("Elevate"))
.on_hover_text("Relaunch ourselves as administrator.")
.on_disabled_hover_text("We are already running elevated.");
if button.clicked() {
win::elevate(win::ElevationExitMethod::Gentle(&mut self.flags.closing));
}
});
});
});
egui::CentralPanel::default().show(ctx, |ui| {
@@ -120,7 +109,7 @@ impl App {
fn show_session_section(&mut self, _ctx: &egui::Context, ui: &mut egui::Ui) {
ui.header("Session");
ui.add_enabled_ui(self.flags.elevated && !self.empty_session.disabled, |ui| {
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, &self.firewall)
@@ -156,77 +145,70 @@ impl App {
egui::Frame::new()
.outer_margin(egui::vec2(0.0, -2.0))
.show(ui, |ui| {
ui.add_enabled_ui(self.flags.elevated, |ui| {
let label = ui.horizontal(|ui| {
let label = match self.settings.block_method {
BlockMethod::EntireGame => ui.label("Game's network access"),
BlockMethod::SaveServer => ui.label("Rockstar save server access"),
};
ui.add_space(1.0);
ui.create_indicator_dot(match self.game_networking.blocked {
BlockedStatus::Executable
if self.settings.block_method == BlockMethod::EntireGame =>
{
colours::RED
}
BlockedStatus::Server
if self.settings.block_method == BlockMethod::SaveServer =>
{
colours::RED
}
_ => colours::GREEN,
});
label
let label = ui.horizontal(|ui| {
let label = match self.settings.block_method {
BlockMethod::EntireGame => ui.label("Game's network access"),
BlockMethod::SaveServer => ui.label("Rockstar save server access"),
};
ui.add_space(1.0);
ui.create_indicator_dot(match self.game_networking.blocked {
BlockedStatus::Executable
if self.settings.block_method == BlockMethod::EntireGame =>
{
colours::RED
}
BlockedStatus::Server
if self.settings.block_method == BlockMethod::SaveServer =>
{
colours::RED
}
_ => colours::GREEN,
});
ui.allocate_ui_with_layout(
egui::vec2(label.inner.rect.width(), 0.0),
egui::Layout::top_down(egui::Align::Min),
|ui| {
ui.columns(2, |columns| {
columns[0].vertical_centered_justified(|ui| {
if ui.button("Block").clicked() {
match self.settings.block_method {
BlockMethod::EntireGame => {
self.game_networking
.block_exe(
&mut self.system_info,
&self.firewall,
)
.unwrap();
}
BlockMethod::SaveServer => {
self.game_networking
.block_save_server(
&self.settings.save_server_ip,
&self.firewall,
)
.unwrap();
}
label
});
ui.allocate_ui_with_layout(
egui::vec2(label.inner.rect.width(), 0.0),
egui::Layout::top_down(egui::Align::Min),
|ui| {
ui.columns(2, |columns| {
columns[0].vertical_centered_justified(|ui| {
if ui.button("Block").clicked() {
match self.settings.block_method {
BlockMethod::EntireGame => {
self.game_networking
.block_exe(&mut self.system_info, &self.firewall)
.unwrap();
}
BlockMethod::SaveServer => {
self.game_networking
.block_save_server(
&self.settings.save_server_ip,
&self.firewall,
)
.unwrap();
}
}
});
columns[1].vertical_centered_justified(|ui| {
if ui.button("Unblock").clicked() {
match self.settings.block_method {
BlockMethod::EntireGame => {
self.game_networking
.unblock_exe(&self.firewall)
.unwrap();
}
BlockMethod::SaveServer => {
self.game_networking
.unblock_save_server(&self.firewall)
.unwrap();
}
}
}
});
}
});
},
);
})
.response
.on_disabled_hover_text("This requires administrator.\nUse the Elevate button.");
columns[1].vertical_centered_justified(|ui| {
if ui.button("Unblock").clicked() {
match self.settings.block_method {
BlockMethod::EntireGame => {
self.game_networking
.unblock_exe(&self.firewall)
.unwrap();
}
BlockMethod::SaveServer => {
self.game_networking
.unblock_save_server(&self.firewall)
.unwrap();
}
}
}
});
});
},
);
});
}
@@ -238,7 +220,6 @@ impl App {
fn show_settings_stage(&mut self, ctx: &egui::Context, ui: &mut egui::Ui) {
ui.collapsing("General", |ui| {
ui.checkbox(&mut self.settings.start_elevated, "Always start elevated");
ui.horizontal(|ui| {
let selection = self.settings.theme;
egui::ComboBox::from_id_salt("Theme")
@@ -263,39 +244,35 @@ impl App {
});
});
ui.collapsing("Network", |ui| {
ui.add_enabled_ui(self.flags.elevated, |ui| {
ui.horizontal(|ui| {
egui::ComboBox::from_id_salt("Block method")
.selected_text(self.settings.block_method.to_string())
.show_ui(ui, |ui| {
ui.build_menu(&mut self.settings.block_method);
});
ui.label("Block method");
if let Err(why) = self
.game_networking
.ensure_block_exclusivity(self.settings.block_method, &self.firewall)
{
log::warn!("Couldn't ensure block exclusivity: {why}");
}
});
if self.settings.block_method == BlockMethod::SaveServer {
ui.horizontal(|ui| {
egui::ComboBox::from_id_salt("Block method")
.selected_text(self.settings.block_method.to_string())
.show_ui(ui, |ui| {
ui.build_menu(&mut self.settings.block_method);
});
ui.label("Block method");
if let Err(why) = self
.game_networking
.ensure_block_exclusivity(self.settings.block_method, &self.firewall)
{
log::warn!("Couldn't ensure block exclusivity: {why}");
ui.add(
egui::TextEdit::singleline(&mut self.settings.save_server_ip)
.char_limit(15)
.desired_width(92.0),
);
ui.label("Save server IP");
if self.settings.save_server_ip != Settings::default().save_server_ip {
if ui.button("").clicked() {
self.settings.save_server_ip = String::from(ROCKSTAR_SAVE_SERVER);
}
}
});
if self.settings.block_method == BlockMethod::SaveServer {
ui.horizontal(|ui| {
ui.add(
egui::TextEdit::singleline(&mut self.settings.save_server_ip)
.char_limit(15)
.desired_width(92.0),
);
ui.label("Save server IP");
if self.settings.save_server_ip != Settings::default().save_server_ip {
if ui.button("").clicked() {
self.settings.save_server_ip = String::from(ROCKSTAR_SAVE_SERVER);
}
}
});
}
})
.response
.on_disabled_hover_text("This requires administrator.\nUse the Elevate button.");
};
});
ui.collapsing("Miscellaneous", |ui| {
if ui.button("Open storage path").clicked() {
+1 -5
View File
@@ -3,7 +3,7 @@ use crate::{
app::{App, WINDOW_SIZE},
tools,
},
util::{persistent_state::PersistentState, win},
util::persistent_state::PersistentState,
};
use eframe::egui;
use windows::Win32::System::Com::{COINIT_APARTMENTTHREADED, CoInitializeEx};
@@ -21,10 +21,6 @@ fn app_creator(
if let Some(persistent_state) = PersistentState::get() {
persistent_state.apply_to(&mut app);
}
// check if we're elevated. if not, and the user wants an elevated launch - relaunch elevated
if !app.flags.elevated && app.settings.start_elevated {
win::elevate(win::ElevationExitMethod::Forced);
}
// refresh system info because it initializes with nothing
app.system_info.refresh();
// enable image loading support in egui
-2
View File
@@ -55,7 +55,6 @@ pub enum BlockMethod {
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Settings {
pub start_elevated: bool,
pub theme: Theme,
pub launch_version: LaunchVersion,
pub save_server_ip: String,
@@ -65,7 +64,6 @@ pub struct Settings {
impl Default for Settings {
fn default() -> Self {
Self {
start_elevated: false,
theme: Theme::default(),
launch_version: LaunchVersion::default(),
block_method: BlockMethod::default(),
+4 -57
View File
@@ -1,25 +1,10 @@
use windows::{
Win32::{
Foundation::{CloseHandle, HANDLE},
Security::{GetTokenInformation, TOKEN_ELEVATION, TOKEN_QUERY, TokenElevation},
System::Threading::{GetCurrentProcess, OpenProcessToken},
UI::{
Input::KeyboardAndMouse::{GetAsyncKeyState, VIRTUAL_KEY},
Shell::ShellExecuteW,
WindowsAndMessaging::{
CURSOR_SHOWING, CURSORINFO, GetCursorInfo, GetForegroundWindow, GetWindowTextW,
SW_NORMAL,
},
},
use windows::Win32::UI::{
Input::KeyboardAndMouse::{GetAsyncKeyState, VIRTUAL_KEY},
WindowsAndMessaging::{
CURSOR_SHOWING, CURSORINFO, GetCursorInfo, GetForegroundWindow, GetWindowTextW,
},
core::{HSTRING, PCWSTR},
};
pub enum ElevationExitMethod<'a> {
Gentle(&'a mut bool),
Forced,
}
pub fn is_cursor_visible() -> bool {
let mut ci = CURSORINFO {
cbSize: u32::try_from(std::mem::size_of::<CURSORINFO>()).unwrap(),
@@ -42,44 +27,6 @@ pub fn is_any_key_pressed(keys: &[VIRTUAL_KEY]) -> bool {
.any(|&key| unsafe { GetAsyncKeyState(i32::from(key.0)) } & i16::MIN != 0)
}
pub fn elevate(closing: ElevationExitMethod) {
let exe = std::env::current_exe().unwrap();
unsafe {
ShellExecuteW(
None,
&HSTRING::from("runas"),
&HSTRING::from(exe.as_path()),
PCWSTR::null(),
PCWSTR::null(),
SW_NORMAL,
);
}
match closing {
ElevationExitMethod::Gentle(closing) => *closing = true,
ElevationExitMethod::Forced => std::process::exit(0),
}
}
pub fn is_elevated() -> bool {
let mut token: HANDLE = HANDLE::default();
if unsafe { OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &raw mut token) }.is_err() {
return false;
}
let mut elevation = TOKEN_ELEVATION::default();
let mut size = u32::try_from(std::mem::size_of::<TOKEN_ELEVATION>()).unwrap();
let result = unsafe {
GetTokenInformation(
token,
TokenElevation,
Some((&raw mut elevation).cast()),
size,
&raw mut size,
)
};
unsafe { CloseHandle(token) }.unwrap();
result.is_ok() && elevation.TokenIsElevated != 0
}
pub fn is_system_theme_light() -> bool {
use winreg::RegKey;
let hkcu = RegKey::predef(winreg::enums::HKEY_CURRENT_USER);