use forensic_rs::{info, traits::registry::{auto_close_key, RegHiveKey, RegistryReader}, utils::time::Filetime};
use super::{read_value_string_or_empty, read_value_u32_or_empty};
#[derive(Clone, Debug, Default)]
pub struct InventoryDriverBinary {
pub driver_name: String,
pub inf: String,
pub driver_version: String,
pub product: String,
pub product_version: String,
pub wdf_version: String,
pub driver_company : String,
pub driver_package_strong_name : String,
pub service : String,
pub driver_in_box : u32,
pub driver_signed : u32,
pub driver_is_kernel_mode : u32,
pub driver_id : String,
pub driver_last_write_time : String,
pub driver_type : u32,
pub driver_timestamp : u32,
pub driver_check_sum : u32,
pub image_size : u32,
pub timestamp : Filetime,
}
pub struct InventoryDriverBinaryIter<'a, R : RegistryReader> {
pub(crate) pos : u32,
pub(crate) key : RegHiveKey,
pub(crate) reader : &'a R
}
impl<'a, R: RegistryReader> Iterator for InventoryDriverBinaryIter<'a, R> {
type Item = InventoryDriverBinary;
fn next(&mut self) -> Option<Self::Item> {
if self.key == RegHiveKey::Hkey(0) {
return None
}
let pos = self.pos;
self.pos += 1;
let next_subkey = self.reader.key_at(self.key, pos).ok()?;
let key = self.reader.open_key(self.key, &next_subkey).ok()?;
match auto_close_key(self.reader, key, || {
let driver_name : String = read_value_string_or_empty(self.reader, key, "DriverName");
let inf: String = read_value_string_or_empty(self.reader, key, "Inf");
let driver_version : String = read_value_string_or_empty(self.reader, key, "DriverVersion");
let product : String = read_value_string_or_empty(self.reader, key, "Product");
let product_version : String = read_value_string_or_empty(self.reader, key, "ProductVersion");
let wdf_version : String = read_value_string_or_empty(self.reader, key, "WdfVersion");
let driver_company : String = read_value_string_or_empty(self.reader, key, "DriverCompany");
let driver_package_strong_name = read_value_string_or_empty(self.reader, key, "DriverPackageStrongName");
let service = read_value_string_or_empty(self.reader, key, "Service");
let driver_in_box : u32 = read_value_u32_or_empty(self.reader, key, "DriverInBox");
let driver_signed : u32 = read_value_u32_or_empty(self.reader, key, "DriverSigned");
let driver_is_kernel_mode : u32 = read_value_u32_or_empty(self.reader, key, "DriverIsKernelMode");
let driver_id = read_value_string_or_empty(self.reader, key, "DriverId");
let driver_last_write_time = read_value_string_or_empty(self.reader, key, "DriverLastWriteTime");
let driver_type : u32 = read_value_u32_or_empty(self.reader, key, "DriverType");
let driver_timestamp : u32 = read_value_u32_or_empty(self.reader, key, "DriverTimeStamp");
let driver_check_sum : u32 = read_value_u32_or_empty(self.reader, key, "DriverCheckSum");
let image_size : u32 = read_value_u32_or_empty(self.reader, key, "ImageSize");
let key_info = self.reader.key_info(key)?;
Ok(InventoryDriverBinary {
driver_name,
inf,
driver_version,
product,
product_version,
wdf_version,
driver_company,
driver_package_strong_name,
service,
driver_in_box,
driver_signed,
driver_is_kernel_mode,
driver_id,
driver_last_write_time,
driver_type,
driver_timestamp,
driver_check_sum,
image_size,
timestamp : key_info.last_write_time
})
}) {
Ok(v) => Some(v),
Err(e) => {
info!("Error getting AmCache File {}", e);
None
}
}
}
}
impl<'a, R: RegistryReader> Drop for InventoryDriverBinaryIter<'a, R> {
fn drop(&mut self) {
self.reader.close_key(self.key);
self.key = RegHiveKey::Hkey(0);
}
}