use std::path::Path;
use crate::error::Result;
use crate::pe::parse_pe_file;
use crate::types::{Architecture, PeFile};
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct XllInfo {
pub path: std::path::PathBuf,
pub name: String,
pub architecture: Architecture,
pub has_auto_open: bool,
pub has_auto_close: bool,
pub has_auto_free: bool,
pub has_addin_manager_info: bool,
pub export_count: usize,
pub exports: Vec<String>,
}
pub fn xll_info(path: impl AsRef<Path>) -> Result<XllInfo> {
let pe = parse_pe_file(path.as_ref())?;
let name = pe
.path
.file_stem()
.and_then(|n| n.to_str())
.unwrap_or("unknown")
.to_string();
let export_names = pe.export_names();
Ok(XllInfo {
path: pe.path.clone(),
name,
architecture: pe.architecture,
has_auto_open: export_names.iter().any(|n| n == "xlAutoOpen"),
has_auto_close: export_names.iter().any(|n| n == "xlAutoClose"),
has_auto_free: export_names.iter().any(|n| n == "xlAutoFree12"),
has_addin_manager_info: export_names.iter().any(|n| n == "xlAddInManagerInfo12"),
export_count: pe.exports.len(),
exports: export_names,
})
}
pub fn verify_xll_entry_points(pe: &PeFile) -> bool {
let names = pe.export_names();
names.iter().any(|n| n == "xlAutoOpen") && names.iter().any(|n| n == "xlAutoFree12")
}
pub fn is_valid_xll(path: impl AsRef<Path>) -> Result<bool> {
let pe = parse_pe_file(path.as_ref())?;
Ok(verify_xll_entry_points(&pe))
}