mirror of
https://gitlab.com/cleanflash/installer.git
synced 2026-08-12 18:31:37 +08:00
Install native host
This commit is contained in:
@@ -9,8 +9,9 @@ pub const PLAYER_START_MENU: u32 = 1 << 4;
|
||||
pub const PLAYER_DESKTOP: u32 = 1 << 5;
|
||||
pub const X64: u32 = 1 << 6;
|
||||
pub const DEBUG: u32 = 1 << 7;
|
||||
pub const NATIVE_HOST: u32 = 1 << 8;
|
||||
|
||||
const UNINSTALL_TICKS: u32 = 9;
|
||||
const UNINSTALL_TICKS: u32 = 10;
|
||||
const INSTALL_GENERAL_TICKS: u32 = 5;
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
@@ -65,6 +66,10 @@ impl InstallFlags {
|
||||
ticks += 1;
|
||||
}
|
||||
|
||||
if self.is_set(NATIVE_HOST) {
|
||||
ticks += 1;
|
||||
}
|
||||
|
||||
ticks += UNINSTALL_TICKS;
|
||||
ticks += INSTALL_GENERAL_TICKS;
|
||||
ticks
|
||||
|
||||
@@ -26,6 +26,10 @@ const COMPLETE_INSTALL_TEXT: &str = "Clean Flash Player has been successfully in
|
||||
Don't forget, Flash Player is no longer compatible with new browsers.\n\n\
|
||||
For browser recommendations and Flash Player updates, check out Clean Flash Player's website!";
|
||||
|
||||
const COMPLETE_INSTALL_WITH_EXTENSION_TEXT: &str = "Clean Flash Player has been successfully installed!\n\n\
|
||||
To use Flash in modern browsers, install the Clean Flash Player extension into your browser.\n\n\
|
||||
For Flash Player updates, check out Clean Flash Player's website!";
|
||||
|
||||
const COMPLETE_UNINSTALL_TEXT: &str = "\nAll versions of Flash Player have been successfully uninstalled.\n\n\
|
||||
If you ever change your mind, check out Clean Flash Player's website!";
|
||||
|
||||
@@ -66,6 +70,8 @@ pub struct InstallForm {
|
||||
pub disclaimer_box: ImageCheckBox,
|
||||
// Choice panel (browser plugins)
|
||||
pub browser_ask_label: Label,
|
||||
pub native_host_box: ImageCheckBox,
|
||||
pub native_host_label: Label,
|
||||
pub pepper_box: ImageCheckBox,
|
||||
pub pepper_label: Label,
|
||||
pub netscape_box: ImageCheckBox,
|
||||
@@ -130,7 +136,7 @@ impl InstallForm {
|
||||
|
||||
let fonts = FontManager::new();
|
||||
|
||||
Self {
|
||||
let mut form = Self {
|
||||
scale,
|
||||
panel: Panel::Disclaimer,
|
||||
title_text,
|
||||
@@ -143,12 +149,14 @@ impl InstallForm {
|
||||
disclaimer_box: chk(PANEL_X, PANEL_Y),
|
||||
// Choice panel
|
||||
browser_ask_label: lbl(PANEL_X - 2, PANEL_Y + 2, "Which browser plugins would you like to install?", 15.0),
|
||||
pepper_box: chk(PANEL_X, PANEL_Y + 47),
|
||||
pepper_label: lbl(PANEL_X + 24, PANEL_Y + 47, "Pepper API (PPAPI)\n(Chrome/Opera/Brave)", 15.0),
|
||||
netscape_box: chk(PANEL_X + 186, PANEL_Y + 47),
|
||||
netscape_label: lbl(PANEL_X + 210, PANEL_Y + 47, "Netscape API (NPAPI)\n(Firefox/ESR/Waterfox)", 15.0),
|
||||
activex_box: chk(PANEL_X + 365, PANEL_Y + 47),
|
||||
activex_label: lbl(PANEL_X + 389, PANEL_Y + 47, "ActiveX (OCX)\n(IE/Embedded/Desktop)", 15.0),
|
||||
native_host_box: chk(PANEL_X, PANEL_Y + 27),
|
||||
native_host_label: lbl(PANEL_X + 24, PANEL_Y + 27, "Modern Browsers (MV3)\n(Chrome/Firefox/Edge)", 15.0),
|
||||
pepper_box: chk(PANEL_X, PANEL_Y + 73),
|
||||
pepper_label: lbl(PANEL_X + 24, PANEL_Y + 73, "Pepper API (PPAPI)\n(Chrome/Opera/Brave)", 15.0),
|
||||
netscape_box: chk(PANEL_X + 186, PANEL_Y + 73),
|
||||
netscape_label: lbl(PANEL_X + 210, PANEL_Y + 73, "Netscape API (NPAPI)\n(Firefox/ESR/Waterfox)", 15.0),
|
||||
activex_box: chk(PANEL_X + 365, PANEL_Y + 73),
|
||||
activex_label: lbl(PANEL_X + 389, PANEL_Y + 73, "ActiveX (OCX)\n(IE/Embedded/Desktop)", 15.0),
|
||||
// Player choice panel
|
||||
player_ask_label: lbl(PANEL_X - 2, PANEL_Y + 2, "Would you like to install the standalone Flash Player?", 15.0),
|
||||
player_box: chk(PANEL_X, PANEL_Y + 47),
|
||||
@@ -194,7 +202,29 @@ The following details could be useful. Press the Retry button to try again.",
|
||||
})),
|
||||
fonts,
|
||||
prev_mouse_down: false,
|
||||
};
|
||||
|
||||
// Modern browser support should be the default choice.
|
||||
form.native_host_box.checked = true;
|
||||
|
||||
// On non-Windows platforms, disable legacy browser plugins and player options.
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
{
|
||||
form.pepper_box.checked = false;
|
||||
form.pepper_box.enabled = false;
|
||||
form.netscape_box.checked = false;
|
||||
form.netscape_box.enabled = false;
|
||||
form.activex_box.checked = false;
|
||||
form.activex_box.enabled = false;
|
||||
form.player_box.checked = false;
|
||||
form.player_box.enabled = false;
|
||||
form.player_desktop_box.checked = false;
|
||||
form.player_desktop_box.enabled = false;
|
||||
form.player_start_menu_box.checked = false;
|
||||
form.player_start_menu_box.enabled = false;
|
||||
}
|
||||
|
||||
form
|
||||
}
|
||||
|
||||
/// Scale a logical integer coordinate to physical pixels.
|
||||
@@ -296,16 +326,30 @@ The following details could be useful. Press the Retry button to try again.",
|
||||
}
|
||||
}
|
||||
Panel::Choice => {
|
||||
self.native_host_box.toggle_if_clicked(mx, my, mouse_released);
|
||||
self.pepper_box.toggle_if_clicked(mx, my, mouse_released);
|
||||
self.netscape_box.toggle_if_clicked(mx, my, mouse_released);
|
||||
self.activex_box.toggle_if_clicked(mx, my, mouse_released);
|
||||
if self.pepper_label.clicked(mx, my, mouse_released, &self.fonts) {
|
||||
if self.native_host_box.enabled
|
||||
&& self
|
||||
.native_host_label
|
||||
.clicked(mx, my, mouse_released, &self.fonts)
|
||||
{
|
||||
self.native_host_box.checked = !self.native_host_box.checked;
|
||||
}
|
||||
if self.pepper_box.enabled
|
||||
&& self.pepper_label.clicked(mx, my, mouse_released, &self.fonts)
|
||||
{
|
||||
self.pepper_box.checked = !self.pepper_box.checked;
|
||||
}
|
||||
if self.netscape_label.clicked(mx, my, mouse_released, &self.fonts) {
|
||||
if self.netscape_box.enabled
|
||||
&& self.netscape_label.clicked(mx, my, mouse_released, &self.fonts)
|
||||
{
|
||||
self.netscape_box.checked = !self.netscape_box.checked;
|
||||
}
|
||||
if self.activex_label.clicked(mx, my, mouse_released, &self.fonts) {
|
||||
if self.activex_box.enabled
|
||||
&& self.activex_label.clicked(mx, my, mouse_released, &self.fonts)
|
||||
{
|
||||
self.activex_box.checked = !self.activex_box.checked;
|
||||
}
|
||||
}
|
||||
@@ -313,13 +357,25 @@ The following details could be useful. Press the Retry button to try again.",
|
||||
self.player_box.toggle_if_clicked(mx, my, mouse_released);
|
||||
self.player_desktop_box.toggle_if_clicked(mx, my, mouse_released);
|
||||
self.player_start_menu_box.toggle_if_clicked(mx, my, mouse_released);
|
||||
if self.player_label.clicked(mx, my, mouse_released, &self.fonts) {
|
||||
if self.player_box.enabled
|
||||
&& self.player_label.clicked(mx, my, mouse_released, &self.fonts)
|
||||
{
|
||||
self.player_box.checked = !self.player_box.checked;
|
||||
}
|
||||
if self.player_desktop_label.clicked(mx, my, mouse_released, &self.fonts) && self.player_box.checked {
|
||||
if self.player_desktop_box.enabled
|
||||
&& self
|
||||
.player_desktop_label
|
||||
.clicked(mx, my, mouse_released, &self.fonts)
|
||||
&& self.player_box.checked
|
||||
{
|
||||
self.player_desktop_box.checked = !self.player_desktop_box.checked;
|
||||
}
|
||||
if self.player_start_menu_label.clicked(mx, my, mouse_released, &self.fonts) && self.player_box.checked {
|
||||
if self.player_start_menu_box.enabled
|
||||
&& self
|
||||
.player_start_menu_label
|
||||
.clicked(mx, my, mouse_released, &self.fonts)
|
||||
&& self.player_box.checked
|
||||
{
|
||||
self.player_start_menu_box.checked = !self.player_start_menu_box.checked;
|
||||
}
|
||||
// Disable sub-options when player unchecked.
|
||||
@@ -359,7 +415,13 @@ The following details could be useful. Press the Retry button to try again.",
|
||||
Panel::Choice => self.open_disclaimer(),
|
||||
Panel::PlayerChoice => self.open_choice(),
|
||||
Panel::DebugChoice => self.open_player_choice(),
|
||||
Panel::BeforeInstall => self.open_debug_choice(),
|
||||
Panel::BeforeInstall => {
|
||||
if cfg!(target_os = "windows") {
|
||||
self.open_debug_choice();
|
||||
} else {
|
||||
self.open_choice();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
@@ -367,7 +429,13 @@ The following details could be useful. Press the Retry button to try again.",
|
||||
fn on_next_clicked(&mut self) {
|
||||
match self.panel {
|
||||
Panel::Disclaimer => self.open_choice(),
|
||||
Panel::Choice => self.open_player_choice(),
|
||||
Panel::Choice => {
|
||||
if cfg!(target_os = "windows") {
|
||||
self.open_player_choice();
|
||||
} else {
|
||||
self.open_before_install();
|
||||
}
|
||||
}
|
||||
Panel::PlayerChoice => self.open_debug_choice(),
|
||||
Panel::DebugChoice => self.open_before_install(),
|
||||
Panel::BeforeInstall | Panel::Failure => self.open_install(),
|
||||
@@ -418,10 +486,13 @@ The following details could be useful. Press the Retry button to try again.",
|
||||
self.prev_button.enabled = true;
|
||||
|
||||
let has_plugins =
|
||||
self.pepper_box.checked || self.netscape_box.checked || self.activex_box.checked || self.player_box.checked;
|
||||
self.native_host_box.checked || self.pepper_box.checked || self.netscape_box.checked || self.activex_box.checked || self.player_box.checked;
|
||||
|
||||
if has_plugins {
|
||||
let mut browsers = Vec::new();
|
||||
if self.native_host_box.checked {
|
||||
browsers.push("Modern Browsers (via extension)");
|
||||
}
|
||||
if self.pepper_box.checked {
|
||||
browsers.push("Google Chrome");
|
||||
}
|
||||
@@ -458,6 +529,7 @@ The installer will completely remove all versions of Flash Player from this comp
|
||||
self.next_button.visible = false;
|
||||
|
||||
let mut flags = InstallFlags::new();
|
||||
flags.set_conditionally(self.native_host_box.checked, install_flags::NATIVE_HOST);
|
||||
flags.set_conditionally(self.pepper_box.checked, install_flags::PEPPER);
|
||||
flags.set_conditionally(self.netscape_box.checked, install_flags::NETSCAPE);
|
||||
flags.set_conditionally(self.activex_box.checked, install_flags::ACTIVEX);
|
||||
@@ -529,7 +601,9 @@ The installer will completely remove all versions of Flash Player from this comp
|
||||
self.prev_button.enabled = true;
|
||||
self.next_button.visible = false;
|
||||
|
||||
if self.pepper_box.checked || self.netscape_box.checked || self.activex_box.checked {
|
||||
if self.native_host_box.checked {
|
||||
self.complete_label.text = COMPLETE_INSTALL_WITH_EXTENSION_TEXT.to_string();
|
||||
} else if self.pepper_box.checked || self.netscape_box.checked || self.activex_box.checked {
|
||||
self.complete_label.text = COMPLETE_INSTALL_TEXT.to_string();
|
||||
} else {
|
||||
self.complete_label.text = COMPLETE_UNINSTALL_TEXT.to_string();
|
||||
@@ -553,6 +627,8 @@ The installer will completely remove all versions of Flash Player from this comp
|
||||
|
||||
fn draw_choice(&self, r: &mut Renderer) {
|
||||
self.browser_ask_label.draw(r, &self.fonts);
|
||||
self.native_host_box.draw(r);
|
||||
self.native_host_label.draw(r, &self.fonts);
|
||||
self.pepper_box.draw(r);
|
||||
self.pepper_label.draw(r, &self.fonts);
|
||||
self.netscape_box.draw(r);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::install_flags::{self, InstallFlags};
|
||||
use clean_flash_common::{
|
||||
process_utils, registry, resources, system_info, InstallError, ProgressCallback,
|
||||
native_host, process_utils, registry, resources, system_info, InstallError, ProgressCallback,
|
||||
};
|
||||
use std::env;
|
||||
use std::fs;
|
||||
@@ -89,6 +89,7 @@ fn install_from_archive(
|
||||
let flash64_path = si.flash64_path.clone();
|
||||
let system32_path = si.system32_path.clone();
|
||||
let flash_program32_path = si.flash_program32_path.clone();
|
||||
let native_host_dir = native_host::get_native_host_install_dir();
|
||||
|
||||
let mut registry_to_apply: Vec<&str> = vec![resources::INSTALL_GENERAL];
|
||||
|
||||
@@ -179,6 +180,24 @@ fn install_from_archive(
|
||||
registry_instructions: Some(resources::INSTALL_PP_64),
|
||||
},
|
||||
),
|
||||
(
|
||||
"native-host-64",
|
||||
InstallEntry {
|
||||
install_text: "Installing native messaging host (64-bit)...",
|
||||
required_flags: install_flags::NATIVE_HOST | install_flags::X64,
|
||||
target_directory: native_host_dir.clone(),
|
||||
registry_instructions: None,
|
||||
},
|
||||
),
|
||||
(
|
||||
"native-host-32",
|
||||
InstallEntry {
|
||||
install_text: "Installing native messaging host (32-bit)...",
|
||||
required_flags: install_flags::NATIVE_HOST,
|
||||
target_directory: native_host_dir.clone(),
|
||||
registry_instructions: None,
|
||||
},
|
||||
),
|
||||
];
|
||||
|
||||
let legacy = si.is_legacy_windows();
|
||||
@@ -202,24 +221,48 @@ fn install_from_archive(
|
||||
|
||||
let filename = parts[0];
|
||||
let install_key = filename.split('-').next().unwrap_or(filename);
|
||||
let is_pp32 = install_key == "pp32";
|
||||
let is_pp64 = install_key == "pp64";
|
||||
let should_extract_pepper_for_native_host =
|
||||
flags.is_set(install_flags::NATIVE_HOST)
|
||||
&& ((si.is_64bit && is_pp64) || (!si.is_64bit && is_pp32));
|
||||
|
||||
// Find the matching entry.
|
||||
let Some((_key, install_entry)) = entries.iter().find(|(k, _)| *k == install_key)
|
||||
// Find the matching entry: try exact match on full dirname first,
|
||||
// then fall back to first segment before '-'.
|
||||
let Some((_key, install_entry)) = entries
|
||||
.iter()
|
||||
.find(|(k, _)| *k == filename)
|
||||
.or_else(|| entries.iter().find(|(k, _)| *k == install_key))
|
||||
else {
|
||||
io::copy(reader, &mut io::sink()).map_err(sevenz_rust2::Error::from)?;
|
||||
return Ok(true);
|
||||
};
|
||||
|
||||
// Check required flags.
|
||||
let should_install_by_flags = install_entry.required_flags == install_flags::NONE
|
||||
|| flags.is_set(install_entry.required_flags);
|
||||
if install_entry.required_flags != install_flags::NONE
|
||||
&& !flags.is_set(install_entry.required_flags)
|
||||
&& !(should_extract_pepper_for_native_host && (is_pp32 || is_pp64))
|
||||
{
|
||||
io::copy(reader, &mut io::sink()).map_err(sevenz_rust2::Error::from)?;
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
// Check debug flag match.
|
||||
if install_entry.required_flags != install_flags::NONE {
|
||||
// For native-host: on 64-bit use only native-host-64, on 32-bit use only native-host-32.
|
||||
if filename == "native-host-32" && si.is_64bit {
|
||||
io::copy(reader, &mut io::sink()).map_err(sevenz_rust2::Error::from)?;
|
||||
return Ok(true);
|
||||
}
|
||||
if filename == "native-host-64" && !si.is_64bit {
|
||||
io::copy(reader, &mut io::sink()).map_err(sevenz_rust2::Error::from)?;
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
// Check debug flag match (skip native-host entries from this check).
|
||||
if install_entry.required_flags != install_flags::NONE
|
||||
&& (install_entry.required_flags & install_flags::NATIVE_HOST) == 0
|
||||
{
|
||||
let is_debug_file = filename.contains("-debug");
|
||||
if flags.is_set(install_flags::DEBUG) != is_debug_file {
|
||||
io::copy(reader, &mut io::sink()).map_err(sevenz_rust2::Error::from)?;
|
||||
@@ -236,14 +279,31 @@ fn install_from_archive(
|
||||
}
|
||||
}
|
||||
|
||||
form.update_progress_label(install_entry.install_text, true);
|
||||
let extract_for_native_host_only = !should_install_by_flags
|
||||
&& should_extract_pepper_for_native_host
|
||||
&& (is_pp32 || is_pp64);
|
||||
|
||||
if extract_for_native_host_only {
|
||||
form.update_progress_label(
|
||||
"Extracting Pepper files required by modern browser support...",
|
||||
true,
|
||||
);
|
||||
} else {
|
||||
form.update_progress_label(install_entry.install_text, true);
|
||||
}
|
||||
|
||||
let target_directory = if extract_for_native_host_only {
|
||||
native_host_dir.clone()
|
||||
} else {
|
||||
install_entry.target_directory.clone()
|
||||
};
|
||||
|
||||
// Ensure target directory exists.
|
||||
let _ = fs::create_dir_all(&install_entry.target_directory);
|
||||
let _ = fs::create_dir_all(&target_directory);
|
||||
|
||||
// Extract file: use just the file name (strip any path prefix).
|
||||
let out_name = parts.last().unwrap_or(&filename);
|
||||
let out_path = install_entry.target_directory.join(out_name);
|
||||
let out_path = target_directory.join(out_name);
|
||||
|
||||
let mut buf = Vec::new();
|
||||
reader.read_to_end(&mut buf).map_err(sevenz_rust2::Error::from)?;
|
||||
@@ -319,6 +379,11 @@ fn install_from_archive(
|
||||
}
|
||||
}
|
||||
|
||||
// Install native messaging host manifests for detected browsers.
|
||||
if flags.is_set(install_flags::NATIVE_HOST) {
|
||||
native_host::install_native_host(form)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
//#![windows_subsystem = "windows"]
|
||||
#![windows_subsystem = "windows"]
|
||||
|
||||
mod install_flags;
|
||||
mod install_form;
|
||||
@@ -34,8 +34,8 @@ fn main() {
|
||||
// Set window icon from the resource embedded by build.rs.
|
||||
clean_flash_ui::set_window_icon(&window);
|
||||
|
||||
// Cap at ~60 fps.
|
||||
window.set_target_fps(60);
|
||||
// Cap at ~24 fps.
|
||||
window.set_target_fps(24);
|
||||
|
||||
// Renderer operates at physical resolution; the form layout is scaled accordingly.
|
||||
let mut renderer = Renderer::new(phys_w, phys_h);
|
||||
|
||||
Reference in New Issue
Block a user