1use crate::integrity::{adler32, EwfIntegrity, EwfIntegrityAnomaly, SECTION_DESCRIPTOR_SIZE};
2
3pub struct EwfRepair {
4 data: Vec<u8>,
5}
6
7pub struct RepairReport {
8 pub data: Vec<u8>,
9 pub repairs: Vec<Repaired>,
10 pub cannot_repair: Vec<CannotRepair>,
11}
12
13#[derive(Debug, Clone)]
14pub enum Repaired {
15 SectionDescriptorCrc { offset: u64, section_type: String },
16}
17
18#[derive(Debug, Clone)]
19pub enum CannotRepair {
20 HashMismatch {
21 computed: [u8; 16],
22 stored: [u8; 16],
23 },
24}
25
26impl EwfRepair {
27 pub fn new(data: Vec<u8>) -> Self {
28 Self { data }
29 }
30
31 pub fn repair(mut self) -> RepairReport {
32 let mut repairs = Vec::new();
33 let mut cannot_repair = Vec::new();
34
35 let anomalies = EwfIntegrity::new(&self.data).analyse();
36
37 for anomaly in anomalies {
38 match anomaly {
39 EwfIntegrityAnomaly::SectionDescriptorCrcMismatch {
40 offset,
41 section_type,
42 ..
43 } => {
44 let off = offset as usize;
45 if off + SECTION_DESCRIPTOR_SIZE <= self.data.len() {
46 let correct = adler32(&self.data[off..off + 72]);
47 self.data[off + 72..off + 76].copy_from_slice(&correct.to_le_bytes());
48 repairs.push(Repaired::SectionDescriptorCrc {
49 offset,
50 section_type,
51 });
52 }
53 }
54 EwfIntegrityAnomaly::HashMismatch { computed, stored } => {
55 cannot_repair.push(CannotRepair::HashMismatch { computed, stored });
56 }
57 _ => {}
58 }
59 }
60
61 RepairReport {
62 data: self.data,
63 repairs,
64 cannot_repair,
65 }
66 }
67}