remove conditional elevation
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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
@@ -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
@@ -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
|
||||
|
||||
@@ -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
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user