mirror of
https://gitlab.com/cleanflash/installer.git
synced 2026-08-13 02:41:38 +08:00
Add installer / uninstaller for Linux
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
#[cfg(windows)]
|
||||
use crate::uninstaller;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
#[cfg(windows)]
|
||||
use std::thread;
|
||||
#[cfg(windows)]
|
||||
use std::time::Duration;
|
||||
|
||||
/// Attempt to delete a single file, retrying with escalating measures if needed.
|
||||
@@ -10,7 +13,8 @@ pub fn delete_file(path: &Path) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Unregister ActiveX .ocx files before deletion.
|
||||
// Unregister ActiveX .ocx files before deletion (Windows only).
|
||||
#[cfg(windows)]
|
||||
if let Some(ext) = path.extension() {
|
||||
if ext.eq_ignore_ascii_case("ocx") {
|
||||
let _ = uninstaller::unregister_activex(&path.to_string_lossy());
|
||||
|
||||
@@ -5,7 +5,15 @@ pub mod redirection;
|
||||
pub mod registry;
|
||||
pub mod resources;
|
||||
pub mod system_info;
|
||||
|
||||
#[cfg(windows)]
|
||||
#[path = "uninstaller_windows.rs"]
|
||||
pub mod uninstaller;
|
||||
|
||||
#[cfg(not(windows))]
|
||||
#[path = "uninstaller_linux.rs"]
|
||||
pub mod uninstaller;
|
||||
|
||||
pub mod update_checker;
|
||||
pub mod winapi_helpers;
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ use std::fs;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
const MANIFEST_NAME: &str = "org.cleanflash.flash_player";
|
||||
const FIREFOX_MANIFEST_FILENAME: &str = "org.cleanflash.flash_player.firefox.json";
|
||||
const CHROME_MANIFEST_FILENAME: &str = "org.cleanflash.flash_player.chrome.json";
|
||||
const FIREFOX_MANIFEST_FILENAME: &str = "org.cleanflash.flash_player.json";
|
||||
const CHROME_MANIFEST_FILENAME: &str = "org.cleanflash.flash_player.json";
|
||||
const FIREFOX_ALLOWED_EXTENSION: &str = "flash-player@cleanflash.org";
|
||||
const ALLOWED_ORIGIN: &str = "chrome-extension://dcikaadaeajidejkoekdflmfdgeoldcb/";
|
||||
|
||||
@@ -402,12 +402,7 @@ pub fn uninstall_native_host(form: &dyn ProgressCallback) {
|
||||
pub fn uninstall_native_host(form: &dyn ProgressCallback) {
|
||||
form.update_progress_label("Removing native messaging host...", true);
|
||||
|
||||
// Remove the host folder and everything inside it.
|
||||
let install_dir = get_native_host_install_dir();
|
||||
let host_exe = install_dir.join(HOST_BINARY_NAME);
|
||||
let _ = fs::remove_file(&host_exe);
|
||||
let _ = fs::remove_dir_all(&install_dir);
|
||||
|
||||
// Remove the manifests.
|
||||
let home = match std::env::var("HOME") {
|
||||
Ok(h) => PathBuf::from(h),
|
||||
Err(_) => return,
|
||||
@@ -417,6 +412,12 @@ pub fn uninstall_native_host(form: &dyn ProgressCallback) {
|
||||
let _ = fs::remove_file(target.manifest_dir.join(CHROME_MANIFEST_FILENAME));
|
||||
let _ = fs::remove_file(target.manifest_dir.join(FIREFOX_MANIFEST_FILENAME));
|
||||
}
|
||||
|
||||
// Remove the host folder and everything inside it.
|
||||
let install_dir = get_native_host_install_dir();
|
||||
let host_exe = install_dir.join(HOST_BINARY_NAME);
|
||||
let _ = fs::remove_file(&host_exe);
|
||||
let _ = fs::remove_dir_all(&install_dir);
|
||||
}
|
||||
|
||||
/// Check if a registry key exists under HKCU.
|
||||
|
||||
@@ -50,6 +50,7 @@ pub fn run_unmanaged_process(program: &str, args: &[&str]) {
|
||||
|
||||
/// Collect the names of DLL modules loaded in a given process.
|
||||
/// Used to detect whether a browser has Flash DLLs loaded.
|
||||
#[cfg(windows)]
|
||||
pub fn collect_modules(pid: u32) -> Vec<String> {
|
||||
use windows_sys::Win32::Foundation::CloseHandle;
|
||||
use windows_sys::Win32::System::ProcessStatus::{
|
||||
@@ -108,3 +109,8 @@ pub fn collect_modules(pid: u32) -> Vec<String> {
|
||||
|
||||
modules
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub fn collect_modules(_pid: u32) -> Vec<String> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/// Disable WoW64 file system redirection. Returns a cookie to restore later.
|
||||
#[cfg(windows)]
|
||||
pub fn disable_redirection() -> *mut std::ffi::c_void {
|
||||
let mut old_value: *mut std::ffi::c_void = std::ptr::null_mut();
|
||||
unsafe {
|
||||
@@ -8,13 +9,23 @@ pub fn disable_redirection() -> *mut std::ffi::c_void {
|
||||
}
|
||||
|
||||
/// Re-enable WoW64 file system redirection using the cookie from `disable_redirection`.
|
||||
#[cfg(windows)]
|
||||
pub fn enable_redirection(old_value: *mut std::ffi::c_void) {
|
||||
unsafe {
|
||||
Wow64RevertWow64FsRedirection(old_value);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
extern "system" {
|
||||
fn Wow64DisableWow64FsRedirection(old_value: *mut *mut std::ffi::c_void) -> i32;
|
||||
fn Wow64RevertWow64FsRedirection(old_value: *mut std::ffi::c_void) -> i32;
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub fn disable_redirection() -> *mut std::ffi::c_void {
|
||||
std::ptr::null_mut()
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub fn enable_redirection(_old_value: *mut std::ffi::c_void) {}
|
||||
|
||||
@@ -3,6 +3,7 @@ use std::fs;
|
||||
use std::io::Write;
|
||||
|
||||
/// Apply registry contents by writing a .reg file and importing with reg.exe.
|
||||
#[cfg(windows)]
|
||||
pub fn apply_registry(entries: &[&str]) -> Result<(), InstallError> {
|
||||
let combined = entries.join("\n\n");
|
||||
let filled = system_info::fill_string(&combined);
|
||||
@@ -42,3 +43,8 @@ pub fn apply_registry(entries: &[&str]) -> Result<(), InstallError> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub fn apply_registry(_entries: &[&str]) -> Result<(), InstallError> {
|
||||
Ok(())
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
use crate::{native_host, InstallError, ProgressCallback};
|
||||
use std::fs;
|
||||
|
||||
/// Perform the full uninstallation sequence on Linux.
|
||||
///
|
||||
/// This removes the native messaging host binary, the Pepper (pp64) files
|
||||
/// installed alongside it, and the browser manifests.
|
||||
pub fn uninstall(form: &dyn ProgressCallback) -> Result<(), InstallError> {
|
||||
form.update_progress_label("Removing native messaging host...", true);
|
||||
native_host::uninstall_native_host(form);
|
||||
|
||||
// Remove the entire install directory (host binary + pp64 files).
|
||||
let install_dir = native_host::get_native_host_install_dir();
|
||||
if install_dir.exists() {
|
||||
form.update_progress_label("Removing installed files...", true);
|
||||
let _ = fs::remove_dir_all(&install_dir);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
+18
@@ -204,6 +204,7 @@ fn should_kill_conditional_process(name: &str, pid: u32) -> bool {
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn stop_processes() {
|
||||
use windows_sys::Win32::Foundation::CloseHandle;
|
||||
use windows_sys::Win32::System::Threading::{
|
||||
@@ -237,6 +238,12 @@ fn stop_processes() {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn stop_processes() {
|
||||
// Process termination via Windows API not available on Unix.
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn get_process_creation_time(pid: u32) -> u64 {
|
||||
use windows_sys::Win32::Foundation::{CloseHandle, FILETIME};
|
||||
use windows_sys::Win32::System::Threading::{GetProcessTimes, OpenProcess, PROCESS_QUERY_INFORMATION};
|
||||
@@ -255,6 +262,12 @@ fn get_process_creation_time(pid: u32) -> u64 {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn get_process_creation_time(_pid: u32) -> u64 {
|
||||
0
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn enumerate_processes() -> Vec<(u32, String)> {
|
||||
use windows_sys::Win32::System::ProcessStatus::{EnumProcesses, GetModuleBaseNameW};
|
||||
use windows_sys::Win32::System::Threading::{OpenProcess, PROCESS_QUERY_INFORMATION, PROCESS_VM_READ};
|
||||
@@ -302,6 +315,11 @@ fn enumerate_processes() -> Vec<(u32, String)> {
|
||||
results
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
fn enumerate_processes() -> Vec<(u32, String)> {
|
||||
Vec::new()
|
||||
}
|
||||
|
||||
/// Perform the full uninstallation sequence.
|
||||
pub fn uninstall(form: &dyn ProgressCallback) -> Result<(), InstallError> {
|
||||
winapi_helpers::allow_modifications();
|
||||
@@ -1,9 +1,16 @@
|
||||
/// Enable SeRestorePrivilege and SeTakeOwnershipPrivilege for the current process.
|
||||
#[cfg(windows)]
|
||||
pub fn allow_modifications() {
|
||||
let _ = modify_privilege("SeRestorePrivilege\0", true);
|
||||
let _ = modify_privilege("SeTakeOwnershipPrivilege\0", true);
|
||||
}
|
||||
|
||||
#[cfg(not(windows))]
|
||||
pub fn allow_modifications() {
|
||||
// No privilege modifications needed on Unix.
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn modify_privilege(name: &str, enable: bool) -> Result<(), ()> {
|
||||
use windows_sys::Win32::Foundation::CloseHandle;
|
||||
use windows_sys::Win32::Security::{
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
use crate::install_flags::{self, InstallFlags};
|
||||
use clean_flash_common::{native_host, InstallError, ProgressCallback};
|
||||
use std::fs;
|
||||
use std::io::{self, Cursor};
|
||||
|
||||
/// Extract native-host and pp64 entries from the embedded 7z archive,
|
||||
/// placing them next to each other in the native host install directory.
|
||||
fn install_from_archive(
|
||||
archive_bytes: &[u8],
|
||||
form: &dyn ProgressCallback,
|
||||
) -> Result<(), InstallError> {
|
||||
let native_host_dir = native_host::get_native_host_install_dir();
|
||||
let _ = fs::create_dir_all(&native_host_dir);
|
||||
|
||||
form.update_progress_label("Extracting native messaging host files...", true);
|
||||
|
||||
sevenz_rust2::decompress_with_extract_fn(
|
||||
Cursor::new(archive_bytes),
|
||||
".",
|
||||
|entry, reader, _dest| {
|
||||
if entry.is_directory() {
|
||||
io::copy(reader, &mut io::sink()).map_err(sevenz_rust2::Error::from)?;
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
let entry_name = entry.name().to_string();
|
||||
let parts: Vec<&str> = entry_name.split('/').collect();
|
||||
if parts.is_empty() {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
let dirname = parts[0];
|
||||
let install_key = dirname.split('-').next().unwrap_or(dirname);
|
||||
|
||||
// Only extract native-host-64, pp64, and uninstaller entries.
|
||||
let dominated = dirname == "native-host-64"
|
||||
|| install_key == "pp64"
|
||||
|| install_key == "uninstaller";
|
||||
if !dominated {
|
||||
io::copy(reader, &mut io::sink()).map_err(sevenz_rust2::Error::from)?;
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
// Skip debug variants of pp64.
|
||||
if install_key == "pp64" && dirname.contains("-debug") {
|
||||
io::copy(reader, &mut io::sink()).map_err(sevenz_rust2::Error::from)?;
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
if dirname == "native-host-64" {
|
||||
form.update_progress_label("Installing native messaging host...", true);
|
||||
} else if install_key == "pp64" {
|
||||
form.update_progress_label("Installing Pepper plugin files...", true);
|
||||
} else if install_key == "uninstaller" {
|
||||
form.update_progress_label("Extracting uninstaller...", true);
|
||||
}
|
||||
|
||||
let out_name = parts.last().unwrap_or(&dirname);
|
||||
let out_path = native_host_dir.join(out_name);
|
||||
|
||||
let mut buf = Vec::new();
|
||||
reader
|
||||
.read_to_end(&mut buf)
|
||||
.map_err(sevenz_rust2::Error::from)?;
|
||||
fs::write(&out_path, &buf).map_err(sevenz_rust2::Error::from)?;
|
||||
|
||||
// Make binaries executable.
|
||||
#[cfg(unix)]
|
||||
if dirname == "native-host-64" || install_key == "uninstaller" {
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
let _ = fs::set_permissions(&out_path, fs::Permissions::from_mode(0o755));
|
||||
}
|
||||
|
||||
Ok(true)
|
||||
},
|
||||
)
|
||||
.map_err(|e| InstallError::new(format!("Failed to extract archive: {}", e)))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Main install entry point for Linux.
|
||||
pub fn install(
|
||||
form: &dyn ProgressCallback,
|
||||
flags: &mut InstallFlags,
|
||||
) -> Result<(), InstallError> {
|
||||
if flags.is_none_set() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let archive_bytes: &[u8] = include_bytes!("../cleanflash.7z");
|
||||
|
||||
if archive_bytes.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if flags.is_set(install_flags::NATIVE_HOST) {
|
||||
install_from_archive(archive_bytes, form)?;
|
||||
native_host::install_native_host(form)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -2,6 +2,13 @@
|
||||
|
||||
mod install_flags;
|
||||
mod install_form;
|
||||
|
||||
#[cfg(windows)]
|
||||
#[path = "installer_windows.rs"]
|
||||
mod installer;
|
||||
|
||||
#[cfg(not(windows))]
|
||||
#[path = "installer_linux.rs"]
|
||||
mod installer;
|
||||
|
||||
use install_form::{InstallForm, HEIGHT, WIDTH};
|
||||
|
||||
Reference in New Issue
Block a user