From 5be64a4a22f15977a53f6f3a2eb744f7c49d533f Mon Sep 17 00:00:00 2001 From: felikcat <29991266+felikcat@users.noreply.github.com> Date: Tue, 10 Dec 2024 19:39:12 -0800 Subject: [PATCH] 1.4.2 --- Cargo.lock | 14 +-- Cargo.toml | 10 +- Images/W11Boost_GUI.png | Bin 24715 -> 27077 bytes src/common.rs | 37 ++++++ src/gui.rs | 267 +++++++++++++++++++++------------------- src/gui/appx_support.rs | 7 +- src/main.rs | 40 +----- 7 files changed, 194 insertions(+), 181 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f7d2172..6fda347 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 4 [[package]] name = "W11Boost" -version = "1.4.1" +version = "1.4.2" dependencies = [ "chrono", "curl", @@ -67,9 +67,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.38" +version = "0.4.39" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" dependencies = [ "android-tzdata", "iana-time-zone", @@ -147,9 +147,9 @@ dependencies = [ [[package]] name = "fltk" -version = "1.4.36" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3425eb42cd32d91ecacb9a51abce5eadb95805bc2a5bd0865af296d9c567e55" +checksum = "f182aa7eccef8015c19cd8d1f85da528ca32d2eb3effaccd7c8d4ff22e244174" dependencies = [ "bitflags", "crossbeam-channel", @@ -161,9 +161,9 @@ dependencies = [ [[package]] name = "fltk-sys" -version = "1.4.36" +version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6064d919361d236997a98584263cb645d17beff0dd15b151f9bbfd19ddc4d37" +checksum = "02fe436baa9112e5b7f6fcce5274d6b3d9ba9108b29efd02f36f53e436da28da" dependencies = [ "cmake", "cmk", diff --git a/Cargo.toml b/Cargo.toml index 865dfe8..6a251b1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "W11Boost" -version = "1.4.1" +version = "1.4.2" edition = "2024" build = "build.rs" authors = ["felikcat"] @@ -8,11 +8,11 @@ authors = ["felikcat"] [package.metadata.winres] CompanyName = "felikcat" FileDescription = "https://github.com/felikcat/W11Boost" -FileVersion = "1.4.1.0" +FileVersion = "1.4.2.0" LegalCopyright = "© 2024 felikcat, AGPL3 License" OriginalFilename = "W11Boost.exe" ProductName = "W11Boost" -ProductVersion = "1.4.1.0" +ProductVersion = "1.4.2.0" # Optimize for size. [profile.release] @@ -24,7 +24,7 @@ codegen-units = 1 [dependencies] fltk-theme = "0.7.3" curl = "0.4.47" -chrono = "0.4.38" +chrono = "0.4.39" widestring = "1.1.0" [dependencies.winsafe] @@ -55,7 +55,7 @@ features = [ ] [dependencies.fltk] -version = "^1.4.36" +version = "^1.5" features = [ "use-ninja" ] diff --git a/Images/W11Boost_GUI.png b/Images/W11Boost_GUI.png index b7388b248db18cbf02447dd1c4e33964438e2d8c..f43027425afc053d4ea53bd0a58da58cfe6fc66f 100644 GIT binary patch literal 27077 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 literal 24715 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 diff --git a/src/common.rs b/src/common.rs index 97bbe27..2e30fcc 100644 --- a/src/common.rs +++ b/src/common.rs @@ -1,11 +1,20 @@ use chrono::{Datelike, Timelike, Utc}; use fltk::app; +use windows_sys::Win32::System::SystemServices::MAXIMUM_ALLOWED; +use windows_sys::Win32::System::Threading::{OpenProcess, OpenProcessToken}; use std::error::Error; +use std::os::raw::c_void; use std::fs::{self, OpenOptions}; use std::io::Write; use std::path::PathBuf; +use std::ptr::null_mut; use windows::Win32::Foundation::ERROR_SUCCESS; use windows::Win32::System::Registry::{REG_DWORD, REG_SZ, RegCreateKeyW, RegSetValueExW}; +use windows_sys::Win32::Foundation::INVALID_HANDLE_VALUE; +use windows_sys::Win32::Security::{ + DuplicateTokenEx, SECURITY_ATTRIBUTES, SecurityImpersonation, + TOKEN_ALL_ACCESS, TOKEN_DUPLICATE, TokenImpersonation, +}; use windows::core::PCWSTR; use windows::{ Win32::System::{ @@ -345,3 +354,31 @@ pub fn save_registry_gpo( Ok(()) } + +pub fn create_access_token_from_pid(process_id: u32) -> Result<*mut c_void, Box> { + let mut dup_token = INVALID_HANDLE_VALUE; + unsafe { + let process = OpenProcess(MAXIMUM_ALLOWED, 0, process_id); + if !process.is_null() { + let mut token = INVALID_HANDLE_VALUE; + OpenProcessToken(process, TOKEN_DUPLICATE, &mut token); + + let attributes = SECURITY_ATTRIBUTES { + nLength: size_of::() as u32, + lpSecurityDescriptor: null_mut(), + bInheritHandle: 0, + }; + + DuplicateTokenEx( + token, + TOKEN_ALL_ACCESS, + &attributes, + SecurityImpersonation, + TokenImpersonation, + &mut dup_token, + ); + } + } + + Ok(dup_token) +} diff --git a/src/gui.rs b/src/gui.rs index 134ce44..d095fff 100644 --- a/src/gui.rs +++ b/src/gui.rs @@ -2,23 +2,31 @@ mod appx_support; mod create_system_restore_point; mod defaults; mod disable_defender_and_smartscreen; +mod disable_recall; mod disable_sleep; mod disable_vbs; mod reduce_forensics; mod reduce_online_data_collection; mod remove_w11boost; -mod disable_recall; +use crate::common::center; use fltk::{ - app::{self, Screen}, button::{Button, CheckButton}, dialog, draw::{self}, enums::{self, Color}, frame::{self}, prelude::*, widget::Widget, window::Window + app::{self, Screen}, + button::{Button, CheckButton}, + dialog, + draw::{self}, + enums::{self, Color}, + frame::{self}, + prelude::*, + widget::Widget, + window::Window, }; use fltk_theme::{ColorTheme, color_themes}; use std::{ - borrow::BorrowMut, cell::RefCell, error::Error, mem, - process::{exit, Command}, + process::{Command, exit}, rc::Rc, }; use windows::Win32::{ @@ -27,7 +35,6 @@ use windows::Win32::{ HWND_TOPMOST, SWP_FRAMECHANGED, SWP_NOMOVE, SWP_NOSIZE, SWP_SHOWWINDOW, SetWindowPos, }, }; -use crate::common::center; type MyCheckboxes = Vec>; @@ -54,13 +61,16 @@ pub fn draw_gui() -> Result<(), Box> { titlebar_close.set_frame(enums::FrameType::NoBox); titlebar_close.set_callback(move |_| exit(0)); - let apply = Rc::new(RefCell::new(Button::new( - 0, - 0, - (wind.width() - 6) / 2, - (wind.height() * 14) / 100, - "Apply W11Boost", - ).center_of(&wind))); + let apply = Rc::new(RefCell::new( + Button::new( + 0, + 0, + (wind.width() - 6) / 2, + (wind.height() * 14) / 100, + "Apply W11Boost", + ) + .center_of(&wind), + )); let remove = Rc::new(RefCell::new(Button::new( wind.width() / 2, @@ -70,29 +80,26 @@ pub fn draw_gui() -> Result<(), Box> { "Remove W11Boost", ))); - let apply = Rc::clone(&apply); - let mut apply_mut = (*apply).borrow_mut(); - - let apply_height = apply_mut.clone().height(); - apply_mut.set_pos(2, wind.height() - apply_height - 2); // Put the apply button at the bottom; wow! - - let remove = Rc::clone(&remove); - let mut remove_mut = (*remove).borrow_mut(); - - remove_mut.clone().center_of(&wind); - - let remove_width = remove_mut.width(); - let remove_height = remove_mut.height(); - remove_mut.set_pos( - wind.width() - remove_width - 2, - wind.height() - remove_height - 2, - ); - - remove_mut.set_label_font(enums::Font::by_name(&font)); - remove_mut.set_label_size(16); + { + let mut apply_mut = apply.borrow_mut(); + let apply_height = apply_mut.height(); + apply_mut.set_pos(2, wind.height() - apply_height - 2); + apply_mut.set_label_font(enums::Font::by_name(&font)); + apply_mut.set_label_size(16); + } - apply_mut.set_label_font(enums::Font::by_name(&font)); - apply_mut.set_label_size(16); + { + let mut remove_mut = remove.borrow_mut(); + remove_mut.clone().center_of(&wind); + let remove_width = remove_mut.width(); + let remove_height = remove_mut.height(); + remove_mut.set_pos( + wind.width() - remove_width - 2, + wind.height() - remove_height - 2, + ); + remove_mut.set_label_font(enums::Font::by_name(&font)); + remove_mut.set_label_size(16); + } let checkbox_height = wind.height() / 12; @@ -167,14 +174,8 @@ pub fn draw_gui() -> Result<(), Box> { checkbox_height, "Disable Windows Recall", )), - RefCell::new(CheckButton::new( - wind.width() / 2, - titlebar.height() + checkbox_height, - wind.width() / 2, - checkbox_height, - "Disable Windows Copilot", - )), - ].to_vec(); + ] + .to_vec(); for checkbox in &my_checkboxes { let mut checkbox = checkbox.borrow_mut(); @@ -185,36 +186,36 @@ pub fn draw_gui() -> Result<(), Box> { my_checkboxes[2].borrow_mut().set_value(true); // "Create a system restore point" my_checkboxes[8].borrow_mut().set_value(true); // "Add in non-intrusive tweaks" - let frame0 = RefCell::new( + let frame0 = Rc::new(RefCell::new( Widget::default() .with_size(wind.width(), wind.height() - titlebar.height()) .with_pos(0, titlebar.height()), - ); - - let frame0 = frame0.clone(); - - frame0 - .borrow_mut() - .set_frame(enums::FrameType::BorderBox); - frame0.borrow_mut().draw(move |f| { - let label = f.label(); - let txt = label.split(" ").nth(0).unwrap(); - let x = f.x(); - let y = f.y(); - let w = f.w(); - let h = f.h(); - - draw::push_clip(x, y, w, h); - draw::draw_box(f.frame(), x, y, w, h, f.color()); - draw::set_draw_color(f.label_color()); - draw::set_font(enums::Font::by_name(&font), 16); - draw::draw_text2(txt, x, y - 16, w, h, f.align()); - draw::pop_clip(); - }); - frame0 - .borrow_mut() - .set_label("Applying W11Boost, please wait..."); - frame0.borrow_mut().hide(); + )); + + { + let frame0 = Rc::clone(&frame0); + frame0.borrow_mut().set_frame(enums::FrameType::BorderBox); + let font = font.clone(); + frame0.borrow_mut().draw(move |f| { + let label = f.label(); + let txt = label.split(" ").nth(0).unwrap(); + let x = f.x(); + let y = f.y(); + let w = f.w(); + let h = f.h(); + + draw::push_clip(x, y, w, h); + draw::draw_box(f.frame(), x, y, w, h, f.color()); + draw::set_draw_color(f.label_color()); + draw::set_font(enums::Font::by_name(&font), 16); + draw::draw_text2(txt, x, y - 16, w, h, f.align()); + draw::pop_clip(); + }); + frame0 + .borrow_mut() + .set_label("Applying W11Boost, please wait..."); + frame0.borrow_mut().hide(); + } wind.end(); wind.show(); @@ -263,17 +264,17 @@ pub fn draw_gui() -> Result<(), Box> { }); fn hide_elements( - frame0: &mut impl WidgetExt, - apply: &mut impl ButtonExt, - remove: &mut impl ButtonExt, + frame0: &Rc>, + apply: &Rc>, + remove: &Rc>, my_checkboxes: &[RefCell], ) { - frame0.show(); - frame0.top_window(); + frame0.borrow_mut().show(); + frame0.borrow_mut().top_window(); // So these aren't accidentally clicked. - apply.hide(); - remove.hide(); + apply.borrow_mut().hide(); + remove.borrow_mut().hide(); for checkbox in my_checkboxes { checkbox.borrow_mut().hide(); } @@ -284,26 +285,26 @@ pub fn draw_gui() -> Result<(), Box> { } fn show_elements( - frame0: &mut impl WidgetExt, - apply: &mut impl ButtonExt, - remove: &mut impl ButtonExt, + frame0: &Rc>, + apply: &Rc>, + remove: &Rc>, my_checkboxes: &[RefCell], ) { // Does not require a manual redraw. - frame0.hide(); - apply.show(); - remove.show(); + frame0.borrow_mut().hide(); + apply.borrow_mut().show(); + remove.borrow_mut().show(); for checkbox in my_checkboxes { checkbox.borrow_mut().show(); } } - - (*apply_mut).set_callback({ - let frame0 = frame0.clone(); - let apply = apply.clone(); - let remove = remove.clone(); - let my_checkboxes = my_checkboxes.clone(); - move |_| { + + { + let frame0 = Rc::clone(&frame0); + let apply_cloned = Rc::clone(&apply); + let remove_cloned = Rc::clone(&remove); + let my_checkboxes_cloned = my_checkboxes.clone(); + apply.borrow_mut().set_callback(move |_| { let choice = dialog::choice2( center().0, center().1, @@ -314,75 +315,81 @@ pub fn draw_gui() -> Result<(), Box> { ); if choice == Some(0) { hide_elements( - &mut *frame0.borrow_mut(), - &mut *(*apply).borrow_mut(), - &mut *(*remove).borrow_mut(), - &my_checkboxes, + &frame0, + &apply_cloned, + &remove_cloned, + &my_checkboxes_cloned, ); // Has to be first! - if let Ok(checkbox) = my_checkboxes[2].try_borrow_mut() { + if let Ok(checkbox) = my_checkboxes_cloned[2].try_borrow() { if checkbox.is_checked() { create_system_restore_point::run() .expect("create_system_restore_point::run failed"); } } - if let Ok(checkbox) = my_checkboxes[0].try_borrow_mut() { + if let Ok(checkbox) = my_checkboxes_cloned[0].try_borrow() { if checkbox.is_checked() { reduce_forensics::run().expect("reduce_forensics::run failed"); } } - if let Ok(checkbox) = my_checkboxes[1].try_borrow_mut() { + if let Ok(checkbox) = my_checkboxes_cloned[1].try_borrow() { if checkbox.is_checked() { reduce_online_data_collection::run() .expect("reduce_online_data_collection::run failed"); } } - if let Ok(checkbox) = my_checkboxes[3].try_borrow_mut() { + if let Ok(checkbox) = my_checkboxes_cloned[3].try_borrow() { if checkbox.is_checked() { - Command::new("wsreset.exe") - .output() + let mut child = Command::new("wsreset.exe") + .args(&["-i"]) + .spawn() .expect("wsreset.exe failed to execute"); + + child.wait().expect("wsreset.exe -> failed to wait for the child process"); } } - if let Ok(checkbox) = my_checkboxes[4].try_borrow_mut() { + if let Ok(checkbox) = my_checkboxes_cloned[4].try_borrow() { if checkbox.is_checked() { appx_support::install().expect("appx_support::install failed"); } } - if let Ok(checkbox) = my_checkboxes[5].try_borrow_mut() { + if let Ok(checkbox) = my_checkboxes_cloned[5].try_borrow() { if checkbox.is_checked() { disable_defender_and_smartscreen::run() .expect("disable_defender_and_smartscreen::run failed"); } } - if let Ok(checkbox) = my_checkboxes[6].try_borrow_mut() { + if let Ok(checkbox) = my_checkboxes_cloned[6].try_borrow() { if checkbox.is_checked() { disable_sleep::run().expect("disable_sleep::run failed"); } } - if let Ok(checkbox) = my_checkboxes[7].try_borrow_mut() { + if let Ok(checkbox) = my_checkboxes_cloned[7].try_borrow() { if checkbox.is_checked() { disable_vbs::run().expect("disable_vbs::run failed"); } } - if let Ok(checkbox) = my_checkboxes[8].try_borrow_mut() { + if let Ok(checkbox) = my_checkboxes_cloned[8].try_borrow() { if checkbox.is_checked() { defaults::run().expect("defaults::run failed"); } } - if let Ok(checkbox) = my_checkboxes[9].try_borrow_mut() { + if let Ok(checkbox) = my_checkboxes_cloned[9].try_borrow() { if checkbox.is_checked() { disable_recall::run().expect("disable_recall::run failed"); } } - if my_checkboxes.iter().all(|checkbox| checkbox.try_borrow_mut().map_or(false, | cb| !cb.is_checked())) { + if my_checkboxes_cloned + .iter() + .all(|checkbox| checkbox.borrow().value() == false) + { dialog::message( center().0, center().1, @@ -397,21 +404,21 @@ pub fn draw_gui() -> Result<(), Box> { } show_elements( - &mut *frame0.borrow_mut(), - &mut *(*apply).borrow_mut(), - &mut *(*remove).borrow_mut(), - &my_checkboxes, + &frame0, + &apply_cloned, + &remove_cloned, + &my_checkboxes_cloned, ); } - } - }); + }); + } - (*remove_mut).borrow_mut().set_callback({ - let frame0 = frame0.clone(); - let apply = apply.clone(); - let remove = remove.clone(); - let my_checkboxes = my_checkboxes.clone(); - move |_| { + { + let frame0 = Rc::clone(&frame0); + let apply_cloned = Rc::clone(&apply); + let remove_cloned = Rc::clone(&remove); + let my_checkboxes_cloned = my_checkboxes.clone(); + remove.borrow_mut().set_callback(move |_| { let choice = dialog::choice2( center().0, center().1, @@ -422,32 +429,32 @@ pub fn draw_gui() -> Result<(), Box> { ); if choice == Some(0) { hide_elements( - &mut *frame0.borrow_mut(), - &mut *(*apply).borrow_mut(), - &mut *(*remove).borrow_mut(), - &my_checkboxes, + &frame0, + &apply_cloned, + &remove_cloned, + &my_checkboxes_cloned, ); if let Ok(_) = remove_w11boost::run() { dialog::message( center().0, center().1, - "W11Boost applied your preferences successfully, please reboot.", + "W11Boost has been removed successfully, please reboot.", ); } else { eprintln!("remove_w11boost::run failed"); } show_elements( - &mut *frame0.borrow_mut(), - &mut *(*apply).borrow_mut(), - &mut *(*remove).borrow_mut(), - &my_checkboxes, + &frame0, + &apply_cloned, + &remove_cloned, + &my_checkboxes_cloned, ); } - } - }); + }); + } app.run().unwrap(); - + Ok(()) } diff --git a/src/gui/appx_support.rs b/src/gui/appx_support.rs index a8c78bd..cc8beec 100644 --- a/src/gui/appx_support.rs +++ b/src/gui/appx_support.rs @@ -34,13 +34,14 @@ pub fn install() -> Result<(), Box> { easy.perform() .expect("appx_support::install -> Failed to curl perform"); - Command::new("powershell.exe") + let mut child = Command::new("powershell.exe") .args([ "-Command", - r#"Add-AppxPackage ([Environment]::GetFolderPath("CommonDesktopDirectory") + "\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle""# + r#"Add-AppxPackage ([Environment]::GetFolderPath("CommonDesktopDirectory") + "\Microsoft.DesktopAppInstaller_8wekyb3d8bbwe.msixbundle")"# ]) - .output() + .spawn() .expect("appx_support::install -> Failed to install the msixbundle"); + child.wait().expect("appx_support::install -> Failed to wait for the child process"); Ok(()) } diff --git a/src/main.rs b/src/main.rs index f0651d0..c3142f3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,30 +1,26 @@ pub mod common; mod gui; -use common::center; +use common::{center, create_access_token_from_pid}; use fltk::dialog; use gui::draw_gui; +use windows_sys::Win32::Security::ImpersonateLoggedOnUser; use std::error::Error; -use std::os::raw::c_void; use std::ptr::null_mut; use std::time::Duration; use std::{mem, thread}; +use windows_sys::Win32::Foundation::CloseHandle; use windows::Win32::System::Services::{ CloseServiceHandle, OpenSCManagerW, OpenServiceW, QueryServiceStatusEx, SC_MANAGER_CONNECT, SC_STATUS_PROCESS_INFO, SERVICE_QUERY_STATUS, SERVICE_RUNNING, SERVICE_START, SERVICE_STATUS_PROCESS, SERVICE_STOPPED, StartServiceW, }; use windows::core::w; -use windows_sys::Win32::Foundation::{CloseHandle, INVALID_HANDLE_VALUE}; -use windows_sys::Win32::Security::{ - DuplicateTokenEx, ImpersonateLoggedOnUser, SECURITY_ATTRIBUTES, SecurityImpersonation, - TOKEN_ALL_ACCESS, TOKEN_DUPLICATE, TokenImpersonation, -}; use windows_sys::Win32::System::SystemServices::MAXIMUM_ALLOWED; use windows_sys::Win32::System::Threading::{ CREATE_UNICODE_ENVIRONMENT, CreateProcessWithTokenW, LOGON_WITH_PROFILE, OpenProcessToken, PROCESS_INFORMATION, STARTUPINFOW, }; -use windows_sys::Win32::System::Threading::{GetCurrentProcess, OpenProcess}; +use windows_sys::Win32::System::Threading::GetCurrentProcess; use winsafe::{self as ws, co, prelude::*}; fn get_pid_from_process_name(process_name: &str) -> Result> { @@ -63,34 +59,6 @@ fn impersonate_as_system() -> Result> { Ok(success) } -fn create_access_token_from_pid(process_id: u32) -> Result<*mut c_void, Box> { - let mut dup_token = INVALID_HANDLE_VALUE; - unsafe { - let process = OpenProcess(MAXIMUM_ALLOWED, 0, process_id); - if !process.is_null() { - let mut token = INVALID_HANDLE_VALUE; - OpenProcessToken(process, TOKEN_DUPLICATE, &mut token); - - let attributes = SECURITY_ATTRIBUTES { - nLength: size_of::() as u32, - lpSecurityDescriptor: null_mut(), - bInheritHandle: 0, - }; - - DuplicateTokenEx( - token, - TOKEN_ALL_ACCESS, - &attributes, - SecurityImpersonation, - TokenImpersonation, - &mut dup_token, - ); - } - } - - Ok(dup_token) -} - fn start_trusted_installer_service() -> Result> { const SLEEP_INTERVAL: u64 = 100; const MAX_ATTEMPTS: u32 = 50; // 50 * 100ms = 5 seconds