File tree 5 files changed +47
-9
lines changed
5 files changed +47
-9
lines changed Original file line number Diff line number Diff line change @@ -61,12 +61,12 @@ impl CliParsed {
61
61
62
62
pub fn parse_and_validate ( args : Cli ) -> Result < Self , UndeleteError > {
63
63
if args. volume . is_none ( ) && args. image . is_none ( ) {
64
- return Err ( UndeleteError :: ParseError (
64
+ return Err ( UndeleteError :: Parse (
65
65
"Either volume or image must be specified" . to_string ( ) ,
66
66
) ) ;
67
67
}
68
68
if args. volume . is_some ( ) && args. image . is_some ( ) {
69
- return Err ( UndeleteError :: ParseError (
69
+ return Err ( UndeleteError :: Parse (
70
70
"Only one of volume or image must be specified" . to_string ( ) ,
71
71
) ) ;
72
72
}
Original file line number Diff line number Diff line change 1
1
#[ derive( Debug ) ]
2
2
pub enum UndeleteError {
3
- ParseError ( String ) ,
4
- InitializationError ( String ) ,
3
+ Parse ( String ) ,
4
+ Initialization ( String ) ,
5
+ Write ( String ) ,
5
6
}
Original file line number Diff line number Diff line change
1
+ use std:: path:: PathBuf ;
2
+
1
3
use clap:: Parser ;
2
4
use cli:: Cli ;
3
5
use errors:: UndeleteError ;
@@ -24,8 +26,27 @@ fn main() -> Result<(), UndeleteError> {
24
26
}
25
27
} ;
26
28
27
- for entry in parser. get_all_entry_names ( ) {
28
- info ! ( "Entry: {:?}" , entry) ;
29
+ let message = match args. dry_run {
30
+ true => "Dry run mode enabled, no files will be written to disk" ,
31
+ false => "Dry run mode disabled, files will be written to disk" ,
32
+ } ;
33
+ info ! ( "{}" , message) ;
34
+
35
+ for entry in parser. get_all_entries ( ) . iter ( ) . filter ( |e| !e. is_allocated ) {
36
+ let calculated_path = PathBuf :: from ( & args. output_dir ) . join ( & entry. filename ) ;
37
+ info ! (
38
+ "Found deleted entry '{}' with {}B of data, will write it to {}" ,
39
+ entry. filename,
40
+ entry. data. len( ) ,
41
+ calculated_path. display( )
42
+ ) ;
43
+ if !args. dry_run {
44
+ match std:: fs:: write ( calculated_path. clone ( ) , & entry. data ) {
45
+ Ok ( _) => info ! ( "Successfully wrote '{}' to disk" , calculated_path. display( ) ) ,
46
+ Err ( e) => return Err ( UndeleteError :: Write ( e. to_string ( ) ) ) ,
47
+ }
48
+ }
29
49
}
50
+
30
51
Ok ( ( ) )
31
52
}
Original file line number Diff line number Diff line change @@ -13,7 +13,7 @@ impl ParserWrapper {
13
13
pub fn new ( path : PathBuf ) -> Result < Self , UndeleteError > {
14
14
let parser = match MftParser :: from_path ( path) {
15
15
Ok ( p) => p,
16
- Err ( e) => return Err ( UndeleteError :: InitializationError ( e. to_string ( ) ) ) ,
16
+ Err ( e) => return Err ( UndeleteError :: Initialization ( e. to_string ( ) ) ) ,
17
17
} ;
18
18
Ok ( Self { parser } )
19
19
}
@@ -80,7 +80,7 @@ impl ParserWrapper {
80
80
}
81
81
}
82
82
83
- pub fn get_all_entry_names ( & mut self ) -> Vec < UndeleteFileEntry > {
83
+ pub fn get_all_entries ( & mut self ) -> Vec < UndeleteFileEntry > {
84
84
let found = self
85
85
. parser
86
86
. iter_entries ( )
@@ -123,7 +123,7 @@ mod tests {
123
123
fn parser_get_entry_names ( ) {
124
124
let entries = ParserWrapper :: new ( PathBuf :: from ( "test_data/MFT_TEST" ) )
125
125
. unwrap ( )
126
- . get_all_entry_names ( ) ;
126
+ . get_all_entries ( ) ;
127
127
128
128
assert ! ( !entries. is_empty( ) ) ;
129
129
}
Original file line number Diff line number Diff line change @@ -8,6 +8,7 @@ pub struct UndeleteFileEntry {
8
8
pub filename : String ,
9
9
pub is_allocated : bool ,
10
10
pub record_number : u64 ,
11
+ pub data : Vec < u8 > ,
11
12
}
12
13
13
14
impl From < MftEntry > for UndeleteFileEntry {
@@ -23,13 +24,28 @@ impl From<MftEntry> for UndeleteFileEntry {
23
24
} )
24
25
. next ( ) ;
25
26
27
+ let data = value
28
+ . iter_attributes_matching ( Some ( vec ! [ MftAttributeType :: DATA ] ) )
29
+ . filter_map ( |attr| match attr {
30
+ Ok ( attribute) => match attribute. data {
31
+ MftAttributeContent :: AttrX80 ( data) => Some ( data) ,
32
+ _ => None ,
33
+ } ,
34
+ Err ( _) => None ,
35
+ } )
36
+ . next ( ) ;
37
+
26
38
UndeleteFileEntry {
27
39
filename : match file_attribute {
28
40
Some ( attr) => attr. name ,
29
41
None => "" . to_string ( ) ,
30
42
} ,
31
43
is_allocated : value. is_allocated ( ) ,
32
44
record_number : value. header . record_number ,
45
+ data : match data {
46
+ Some ( d) => d. data ( ) . to_vec ( ) ,
47
+ None => vec ! [ ] ,
48
+ } ,
33
49
}
34
50
}
35
51
}
You can’t perform that action at this time.
0 commit comments