Skip to content

Commit 419738f

Browse files
authored
fixing reader (#21)
1 parent 5a0e859 commit 419738f

File tree

1 file changed

+27
-12
lines changed

1 file changed

+27
-12
lines changed

Diff for: src/reader.rs

+27-12
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ enum ReaderType {
2525
BlockDevice,
2626
}
2727

28-
const SECTOR_SIZE: usize = 512; // 512 Bytes
2928
const CLUSTER_SIZE: usize = 4096; // 4 KiB
3029
const ENTRY_SIZE: usize = 1024; // 1 KiB
3130
const SIGNATURES: [&[u8]; 3] = [b"FILE", b"BAAD", b"0000"];
@@ -76,16 +75,9 @@ impl Reader {
7675
}
7776

7877
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())?;
8879

80+
let mut file = File::open(&self.path)?;
8981
let mut mft_entry = vec![0; ENTRY_SIZE];
9082
file.seek(SeekFrom::Start(offset as u64))?; // Seek to the start of the MFT
9183
file.read_exact(&mut mft_entry)?; // Read the first entry
@@ -146,8 +138,31 @@ impl Reader {
146138
}
147139
}
148140

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+
}
151166
}
152167

153168
fn find_block_device(mount_point: &Path) -> std::io::Result<Option<PathBuf>> {

0 commit comments

Comments
 (0)