// This file is part of Deja-vu. // // Deja-vu is free software: you can redistribute it and/or modify it // under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // Deja-vu is distributed in the hope that it will be useful, but // WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. // See the GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with Deja-vu. If not, see . // use std::{env, fmt, fs::read_dir, path::PathBuf, process::Command}; use serde::{Deserialize, Serialize}; use tracing::info; use walkdir::WalkDir; #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] pub struct Driver { pub name: String, pub path: PathBuf, pub inf_paths: Vec, } impl Driver { fn new() -> Driver { Driver { name: String::new(), path: PathBuf::new(), inf_paths: Vec::new(), } } } impl Default for Driver { fn default() -> Driver { Driver::new() } } impl fmt::Display for Driver { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.name) } } /// # Panics /// /// Will panic if a driver fails to load pub fn load(inf_paths: &Vec) { if cfg!(windows) { // Load drivers into live environment for inf in inf_paths { let inf = inf.clone(); if let Ok(path) = inf.into_os_string().into_string() { info!("Installing driver: {}", &path); Command::new("drvload") .arg(path) .output() .expect("Failed to load driver"); } } } } pub fn scan() -> Vec { let mut drivers: Vec = Vec::new(); if let Ok(exe_path) = env::current_exe() { let driver_path = exe_path.with_file_name("drivers"); if let Ok(dir_entry) = read_dir(driver_path) { for entry in dir_entry.flatten() { if entry.path().is_dir() { if let Ok(name) = entry.file_name().into_string() { drivers.push(Driver { name, path: entry.path(), inf_paths: Vec::new(), }); } } } } } drivers.sort(); drivers.reverse(); for driver in &mut drivers { if &driver.name[..1] == "0" { driver.name = String::from(&driver.name[1..]); } for entry in WalkDir::new(&driver.path) .into_iter() .filter_map(Result::ok) { if let Some(ext) = entry.path().extension() { if ext == "inf" { driver.inf_paths.push(entry.into_path()); } } } } drivers }