-
Notifications
You must be signed in to change notification settings - Fork 34
Open
Description
I'm trying to recover deleted files from an NTFS partition using the ntfs crate, but I can't see deleted files in my implementation. Here's my code snippet:
fn main() -> binrw::BinResult<()> {
let name = r"\\.\PhysicalDrive0";
let mut wname: Vec<_> = name.encode_utf16().collect();
wname.push(0);
// let cname = ffi::CString::new("t").unwrap();
let mut file = fs::File::open(r"\\.\D:").unwrap();
let h = file.as_raw_handle() as *mut winapi::ctypes::c_void;
// 2. 获取磁盘扇区大小
let mut geometry = [0u8; 256]; // 足够容纳 DISK_GEOMETRY 结构
let mut bytes_returned = 0;
let _result = unsafe {
ioapiset::DeviceIoControl(
h,
winioctl::IOCTL_DISK_GET_DRIVE_GEOMETRY,
std::ptr::null_mut(),
0,
geometry.as_mut_ptr() as *mut _,
geometry.len() as u32,
&mut bytes_returned,
std::ptr::null_mut(),
)
};
let g = geometry.as_ptr() as *const winioctl::DISK_GEOMETRY;
let g = unsafe { g.as_ref() }.unwrap();
let mut data = vec![0u8; g.BytesPerSector as usize * 200];
file.read_exact(&mut data)?;
// let mut r = Cursor::new(data);
let mut r = AlignedAccess::new(&mut file, g.BytesPerSector as _)?;
let ntfs = Ntfs::new(&mut r).unwrap();
let root = ntfs.root_directory(&mut r).unwrap();
let index = root.directory_index(&mut r).unwrap();
let mut stack = vec![root.clone()];
let mut curr = BTreeMap::new();
loop {
let bindings = stack.last().unwrap().directory_index(&mut r).unwrap();
let mut iter = bindings.entries();
while let Some(Ok(entry)) = iter.next(&mut r) {
let pos = entry.position();
// ntfs.file(&mut r, pos);
// ntfs::NtfsFile::new(
// &ntfs,
// &mut r,
// pos.value().unwrap(),
// entry.file_reference().file_record_number(),
// );
let key = entry.key().unwrap().unwrap();
let name: Vec<u16> = key
.name()
.0
.chunks(2)
.map(|x| u16::from_le_bytes(x.try_into().unwrap()))
.collect();
let name = String::from_utf16(&name).unwrap();
let file = ntfs
.file(&mut r, entry.file_reference().file_record_number())
.unwrap();
file.is_directory();
// println!(
// "[{}] {} 0b{:b}",
// name,
// file.is_directory(),
// file.flags().bits()
// );
curr.insert(name.to_owned(), file);
println!("insert [{name}]");
}
let mut line = String::new();
std::io::stdin().lock().read_line(&mut line).unwrap();
// println!("------- {:?}", curr.get(line.trim()));
if let Some(file) = curr.get(line.trim()) {
println!("cd {line}");
stack.push(file.to_owned());
}
}
Ok(())
}
Problem:
The current implementation only lists active files. How can I:
Access deleted files' metadata (timestamps, original size)
Recover file entries marked as deleted
Scan unallocated MFT entries?
Additional Questions:
Does the ntfs crate support working with deleted file records?
Are there any examples for low-level MFT parsing?
How to detect files marked with FILE_RECORD_SEGMENT_IN_USE flag cleared?
Environment:
Windows 10
rustc 1.88.0-nightly (4824c2bb7 2025-05-02)
rustup 1.28.1 (f9edccde0 2025-03-05)
ntfs crate 0.4.0
Metadata
Metadata
Assignees
Labels
No labels