@@ -25,7 +25,6 @@ enum ReaderType {
25
25
BlockDevice ,
26
26
}
27
27
28
- const SECTOR_SIZE : usize = 512 ; // 512 Bytes
29
28
const CLUSTER_SIZE : usize = 4096 ; // 4 KiB
30
29
const ENTRY_SIZE : usize = 1024 ; // 1 KiB
31
30
const SIGNATURES : [ & [ u8 ] ; 3 ] = [ b"FILE" , b"BAAD" , b"0000" ] ;
@@ -76,16 +75,9 @@ impl Reader {
76
75
}
77
76
78
77
fn read_mft_bytes ( & self ) -> Result < Vec < u8 > > {
79
- let mut file = File :: open ( & self . path ) ?;
80
-
81
- let mut buffer = vec ! [ 0 ; SECTOR_SIZE * 20 ] ;
82
- file. read_exact ( & mut buffer) ?;
83
-
84
- let offset = find_mft_signature ( & buffer) . ok_or_else ( || crate :: errors:: Error :: Any {
85
- detail : "Couldn't find MFT signature meaning that this is probably not NTFS partition"
86
- . to_string ( ) ,
87
- } ) ?;
78
+ let offset = find_mft_signature ( self . path . as_path ( ) ) ?;
88
79
80
+ let mut file = File :: open ( & self . path ) ?;
89
81
let mut mft_entry = vec ! [ 0 ; ENTRY_SIZE ] ;
90
82
file. seek ( SeekFrom :: Start ( offset as u64 ) ) ?; // Seek to the start of the MFT
91
83
file. read_exact ( & mut mft_entry) ?; // Read the first entry
@@ -146,8 +138,31 @@ impl Reader {
146
138
}
147
139
}
148
140
149
- fn find_mft_signature ( buffer : & [ u8 ] ) -> Option < usize > {
150
- ( 0 ..buffer. len ( ) - 4 ) . find ( |& i| SIGNATURES . contains ( & & buffer[ i..i + 4 ] ) )
141
+ fn find_mft_signature < P > ( path : P ) -> Result < usize >
142
+ where
143
+ P : AsRef < Path > ,
144
+ {
145
+ let mut file = File :: open ( path) ?;
146
+ let mut total_length = file. metadata ( ) ?. len ( ) as i64 ;
147
+ let mut buffer_size = 4 * CLUSTER_SIZE ;
148
+
149
+ loop {
150
+ total_length -= buffer_size as i64 ;
151
+ if total_length < 0 {
152
+ buffer_size += buffer_size. wrapping_add ( total_length as usize ) // for the last entry section
153
+ }
154
+ let mut buffer = vec ! [ 0 ; buffer_size] ;
155
+ file. read_exact ( & mut buffer) ?;
156
+ let found = ( 0 ..buffer. len ( ) - 4 ) . find ( |& i| SIGNATURES . contains ( & & buffer[ i..i + 4 ] ) ) ;
157
+ if let Some ( offset) = found {
158
+ return Ok ( offset) ;
159
+ }
160
+ if total_length < 0 {
161
+ return Err ( crate :: errors:: Error :: Any {
162
+ detail : "read the whole disk, couldn't find signature" . to_string ( ) ,
163
+ } ) ;
164
+ }
165
+ }
151
166
}
152
167
153
168
fn find_block_device ( mount_point : & Path ) -> std:: io:: Result < Option < PathBuf > > {
0 commit comments