Files
unixtract/src/formats.rs
T

292 lines
11 KiB
Rust
Raw Normal View History

2026-06-04 19:46:23 +08:00
//! Format registry and detection/extraction framework.
//!
//! Each supported firmware format has a detector function (`is_*_file`) that
//! checks whether a given input matches that format, and an extractor function
//! (`extract_*`) that performs the actual extraction. The [`Format`] struct
//! pairs these together, and [`get_registry`] returns the ordered list of all
//! supported formats.
//!
//! **Important**: The order of formats in the registry matters. Some formats
//! can contain other formats as inner payloads, so the outer format must be
//! detected first. Ordering constraints are noted in comments.
2026-02-05 15:18:26 +01:00
use std::any::Any;
2026-02-05 18:53:35 +01:00
use crate::AppContext;
2026-02-05 15:18:26 +01:00
2026-06-04 19:46:23 +08:00
/// A supported firmware format with its detector and extractor functions.
///
/// The `detector_func` returns `Some(ctx)` if the input matches this format,
/// where `ctx` is an opaque box of format-specific context data that will be
/// passed to the `extractor_func`. Returns `None` if the format doesn't match.
2026-02-05 15:18:26 +01:00
pub struct Format {
pub name: &'static str,
2026-02-05 18:53:35 +01:00
pub detector_func: fn(&AppContext) -> Result<Option<Box<dyn Any>>, Box<dyn std::error::Error>>,
pub extractor_func: fn(&AppContext, Box<dyn Any>) -> Result<(), Box<dyn std::error::Error>>,
2026-02-05 15:18:26 +01:00
}
2025-09-12 22:18:53 +02:00
pub mod mstar;
pub mod mstar_secure_old;
pub mod samsung_old;
pub mod nvt_timg;
2025-10-06 22:44:30 +02:00
pub mod pfl_upg;
pub mod sddl_sec;
2025-10-07 13:29:44 +02:00
pub mod novatek;
2025-10-19 14:56:51 +02:00
pub mod ruf;
pub mod invincible_image;
2025-10-29 18:36:42 +01:00
pub mod slp;
pub mod roku;
2025-10-31 19:37:03 +01:00
pub mod sony_bdp;
2025-11-02 12:40:46 +01:00
pub mod rvp;
2025-11-05 22:57:54 +01:00
pub mod funai_upg;
pub mod funai_upg_phl;
2026-02-20 21:05:51 +01:00
pub mod funai_bdp;
pub mod funai_mstar;
2025-11-19 23:39:33 +01:00
pub mod pana_dvd;
2025-12-12 22:14:01 +01:00
pub mod android_ota_payload;
2025-12-21 21:10:40 +01:00
pub mod bdl;
pub mod amlogic;
pub mod sdboot;
2026-04-08 18:34:22 +02:00
pub mod sdimage;
2026-04-09 16:28:49 +02:00
pub mod cd5;
2026-04-27 18:37:03 +02:00
pub mod gx_dvb;
2026-05-01 21:38:35 +02:00
pub mod onkyo;
2026-05-04 13:58:34 +02:00
pub mod philips_bdp;
2026-05-24 22:18:58 +02:00
pub mod tsb_bin;
2026-06-04 19:46:23 +08:00
pub mod pup;
pub mod vestel;
2026-06-05 11:39:12 +08:00
pub mod novatek_raw;
2026-06-04 19:46:23 +08:00
pub mod msd;
pub mod msd10;
pub mod msd11;
pub mod epk;
pub mod epk1;
pub mod epk2;
pub mod epk2b;
2025-10-12 19:08:46 +02:00
pub mod epk3;
pub mod mtk_pkg;
pub mod mtk_pkg_old;
pub mod mtk_pkg_new;
2026-02-05 15:18:26 +01:00
pub mod mtk_bdp;
2026-06-04 19:46:23 +08:00
/// Returns the ordered list of all supported firmware formats.
///
/// Formats are tried in order during detection; the first match wins. This
/// means that container formats (which embed other formats) must appear
/// before their inner formats to avoid misdetection.
2026-02-05 15:18:26 +01:00
pub fn get_registry() -> Vec<Format> {
return vec![
2026-02-17 17:28:59 +01:00
Format {
name: "mstar",
detector_func: crate::formats::mstar::is_mstar_file,
extractor_func: crate::formats::mstar::extract_mstar,
},
Format {
name: "samsung_old",
detector_func: crate::formats::samsung_old::is_samsung_old_dir,
extractor_func: crate::formats::samsung_old::extract_samsung_old,
},
Format {
name: "nvt_timg",
detector_func: crate::formats::nvt_timg::is_nvt_timg_file,
extractor_func: crate::formats::nvt_timg::extract_nvt_timg,
},
Format {
name: "pfl_upg",
detector_func: crate::formats::pfl_upg::is_pfl_upg_file,
extractor_func: crate::formats::pfl_upg::extract_pfl_upg,
},
Format {
name: "sddl_sec",
detector_func: crate::formats::sddl_sec::is_sddl_sec_file,
extractor_func: crate::formats::sddl_sec::extract_sddl_sec,
},
Format {
name: "sdboot",
detector_func: crate::formats::sdboot::is_sdboot_file,
extractor_func: crate::formats::sdboot::extract_sdboot,
},
2026-04-08 18:34:22 +02:00
Format {
name: "sdimage",
detector_func: crate::formats::sdimage::is_sdimage_file,
extractor_func: crate::formats::sdimage::extract_sdimage,
},
2026-02-17 17:28:59 +01:00
Format {
name: "novatek",
detector_func: crate::formats::novatek::is_novatek_file,
extractor_func: crate::formats::novatek::extract_novatek,
},
Format {
name: "ruf",
detector_func: crate::formats::ruf::is_ruf_file,
extractor_func: crate::formats::ruf::extract_ruf,
},
Format {
name: "invincible_image",
detector_func: crate::formats::invincible_image::is_invincible_image_file,
extractor_func: crate::formats::invincible_image::extract_invincible_image,
},
Format {
name: "slp",
detector_func: crate::formats::slp::is_slp_file,
extractor_func: crate::formats::slp::extract_slp,
},
Format {
name: "roku",
detector_func: crate::formats::roku::is_roku_file,
extractor_func: crate::formats::roku::extract_roku,
},
Format {
name: "sony_bdp",
detector_func: crate::formats::sony_bdp::is_sony_bdp_file,
extractor_func: crate::formats::sony_bdp::extract_sony_bdp,
},
Format {
name: "rvp",
detector_func: crate::formats::rvp::is_rvp_file,
extractor_func: crate::formats::rvp::extract_rvp,
},
Format {
name: "funai_upg",
detector_func: crate::formats::funai_upg::is_funai_upg_file,
extractor_func: crate::formats::funai_upg::extract_funai_upg,
},
Format {
name: "funai_upg_phl",
detector_func: crate::formats::funai_upg_phl::is_funai_upg_phl_file,
extractor_func: crate::formats::funai_upg_phl::extract_funai_upg_phl,
},
2026-02-20 21:05:51 +01:00
Format {
name: "funai_bdp",
detector_func: crate::formats::funai_bdp::is_funai_bdp_file,
extractor_func: crate::formats::funai_bdp::extract_funai_bdp,
},
Format {
name: "funai_mstar", // ORDER: needs to be placed BELOW mstar_secure_old
detector_func: crate::formats::funai_mstar::is_funai_mstar_file, //because, it can end with mstar_secure_old payload, but because it is not aligned to the start of the file, extraction will fail
extractor_func: crate::formats::funai_mstar::extract_funai_mstar,
},
2026-02-17 17:28:59 +01:00
Format {
name: "pana_dvd",
detector_func: crate::formats::pana_dvd::is_pana_dvd_file,
extractor_func: crate::formats::pana_dvd::extract_pana_dvd,
},
Format {
name: "android_ota_payload",
detector_func: crate::formats::android_ota_payload::is_android_ota_payload_file,
extractor_func: crate::formats::android_ota_payload::extract_android_ota_payload,
},
Format {
name: "bdl",
detector_func: crate::formats::bdl::is_bdl_file,
extractor_func: crate::formats::bdl::extract_bdl,
},
Format {
name: "amlogic",
detector_func: crate::formats::amlogic::is_amlogic_file,
extractor_func: crate::formats::amlogic::extract_amlogic,
},
Format {
name: "pup",
detector_func: crate::formats::pup::is_pup_file,
extractor_func: crate::formats::pup::extract_pup,
},
Format {
name: "msd10",
detector_func: crate::formats::msd10::is_msd10_file,
extractor_func: crate::formats::msd10::extract_msd10,
},
Format {
name: "msd11",
detector_func: crate::formats::msd11::is_msd11_file,
extractor_func: crate::formats::msd11::extract_msd11,
},
Format {
name: "epk",
detector_func: crate::formats::epk::is_epk_file,
extractor_func: crate::formats::epk::extract_epk,
},
Format {
name: "epk1",
detector_func: crate::formats::epk1::is_epk1_file,
extractor_func: crate::formats::epk1::extract_epk1,
},
Format {
name: "epk2",
detector_func: crate::formats::epk2::is_epk2_file,
extractor_func: crate::formats::epk2::extract_epk2,
},
Format {
name: "epk2b",
detector_func: crate::formats::epk2b::is_epk2b_file,
extractor_func: crate::formats::epk2b::extract_epk2b,
},
Format {
name: "epk3",
detector_func: crate::formats::epk3::is_epk3_file,
extractor_func: crate::formats::epk3::extract_epk3,
},
Format {
name: "mtk_pkg",
detector_func: crate::formats::mtk_pkg::is_mtk_pkg_file,
extractor_func: crate::formats::mtk_pkg::extract_mtk_pkg,
},
Format {
name: "mtk_pkg_old",
detector_func: crate::formats::mtk_pkg_old::is_mtk_pkg_old_file,
extractor_func: crate::formats::mtk_pkg_old::extract_mtk_pkg_old,
},
Format {
name: "mtk_pkg_new",
detector_func: crate::formats::mtk_pkg_new::is_mtk_pkg_new_file,
extractor_func: crate::formats::mtk_pkg_new::extract_mtk_pkg_new,
},
2026-05-04 13:58:34 +02:00
Format {
name: "philips_bdp",
detector_func: crate::formats::philips_bdp::is_philips_bdp_file, //ORDER: needs to be placed below mtk_bdp
extractor_func: crate::formats::philips_bdp::extract_philips_bdp, //because, it can end with mtk_bdp payload, but because it is not aligned to the start of the file, extraction will fail
2026-05-04 13:58:34 +02:00
},
2026-02-17 17:28:59 +01:00
Format {
name: "mtk_bdp",
detector_func: crate::formats::mtk_bdp::is_mtk_bdp_file,
extractor_func: crate::formats::mtk_bdp::extract_mtk_bdp,
},
2026-04-09 16:28:49 +02:00
Format {
name: "cd5",
detector_func: crate::formats::cd5::is_cd5_file,
extractor_func: crate::formats::cd5::extract_cd5,
},
2026-04-27 18:37:03 +02:00
Format {
name: "gx_dvb",
detector_func: crate::formats::gx_dvb::is_gx_dvb_file,
extractor_func: crate::formats::gx_dvb::extract_gx_dvb,
},
2026-05-01 21:38:35 +02:00
Format {
name: "onkyo",
detector_func: crate::formats::onkyo::is_onkyo_file,
extractor_func: crate::formats::onkyo::extract_onkyo,
},
Format {
name: "mstar_secure_old",
detector_func: crate::formats::mstar_secure_old::is_mstar_secure_old_file,
extractor_func: crate::formats::mstar_secure_old::extract_mstar_secure_old,
},
2026-05-24 22:18:58 +02:00
Format {
name: "tsb_bin",
detector_func: crate::formats::tsb_bin::is_tsb_bin_file,
extractor_func: crate::formats::tsb_bin::extract_tsb_bin,
},
2026-06-04 19:46:23 +08:00
Format {
name: "vestel",
detector_func: crate::formats::vestel::is_vestel_file,
extractor_func: crate::formats::vestel::extract_vestel,
2026-06-05 11:39:12 +08:00
},
Format {
name: "novatek_raw",
detector_func: crate::formats::novatek_raw::is_novatek_raw_file,
extractor_func: crate::formats::novatek_raw::extract_novatek_raw,
},
]
2026-02-05 15:18:26 +01:00
}