Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/mft.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOmer Ben-Amram <omerbenamram@gmail.com>2019-05-08 21:39:26 +0300
committerOmer Ben-Amram <omerbenamram@gmail.com>2019-05-08 21:39:39 +0300
commite8f6804dca46eecd819aeeb61213da5a024a2e9b (patch)
tree2a3fe7c8471ccc21ec86e61b871707640727f326
parent5e48d3c0b2886aa1b82e2007bc36ac631c5dcb94 (diff)
fix doc-tests
-rw-r--r--Cargo.toml2
-rw-r--r--src/attr_x10.rs35
-rw-r--r--src/attr_x30.rs40
-rw-r--r--src/attribute.rs2
-rw-r--r--src/bin/mft_dump.rs2
-rw-r--r--src/entry.rs18
-rw-r--r--src/enumerator.rs2
-rw-r--r--src/err.rs4
-rw-r--r--src/mft.rs40
9 files changed, 81 insertions, 64 deletions
diff --git a/Cargo.toml b/Cargo.toml
index 0c932ac..6c39fd9 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -20,7 +20,7 @@ serde = {version = "1.0.91", features = ["derive"]}
serde_json = "1.0.39"
env_logger = "0.6.1"
snafu = "0.2.3"
-winstructs = "0.1.0"
+winstructs = {git = "https://github.com/omerbenamram/winstructs.git", branch = "master"}
[dependencies.jmespath]
version = "^0.1.1"
diff --git a/src/attr_x10.rs b/src/attr_x10.rs
index 4e08223..3366714 100644
--- a/src/attr_x10.rs
+++ b/src/attr_x10.rs
@@ -1,11 +1,12 @@
-use crate::err::{Result};
+use crate::err::{self, Result};
-use log::trace;
use byteorder::{LittleEndian, ReadBytesExt};
use chrono::{DateTime, Utc};
+use log::trace;
use serde::Serialize;
use std::io::Read;
use winstructs::timestamp::WinTimestamp;
+use snafu::ResultExt;
#[derive(Serialize, Debug, Clone)]
pub struct StandardInfoAttr {
@@ -31,7 +32,8 @@ impl StandardInfoAttr {
/// Parse a raw buffer.
///
/// ```
- /// use rustymft::attr_x10::StandardInfoAttr;
+ /// use mft::attr_x10::StandardInfoAttr;
+ /// # use std::io::Cursor;
/// # fn test_standard_information() {
/// let attribute_buffer: &[u8] = &[
/// 0x2F,0x6D,0xB6,0x6F,0x0C,0x97,0xCE,0x01,0x56,0xCD,0x1A,0x75,0x73,0xB5,0xCE,0x01,
@@ -41,12 +43,12 @@ impl StandardInfoAttr {
/// 0x68,0x58,0xA0,0x0A,0x02,0x00,0x00,0x00
/// ];
///
- /// let attribute = StandardInfoAttr::new(attribute_buffer).unwrap();
+ /// let attribute = StandardInfoAttr::from_reader(&mut Cursor::new(attribute_buffer)).unwrap();
///
- /// assert_eq!(attribute.created.0, 130207518909951279);
- /// assert_eq!(attribute.modified.0, 130240946730880342);
- /// assert_eq!(attribute.mft_modified.0, 130240946730880342);
- /// assert_eq!(attribute.accessed.0, 130240946730880342);
+ /// assert_eq!(attribute.created.timestamp(), 130207518909951279);
+ /// assert_eq!(attribute.modified.timestamp(), 130240946730880342);
+ /// assert_eq!(attribute.mft_modified.timestamp(), 130240946730880342);
+ /// assert_eq!(attribute.accessed.timestamp(), 130240946730880342);
/// assert_eq!(attribute.file_flags, 32);
/// assert_eq!(attribute.max_version, 0);
/// assert_eq!(attribute.version, 0);
@@ -58,10 +60,19 @@ impl StandardInfoAttr {
/// ```
pub fn from_reader<R: Read>(reader: &mut R) -> Result<StandardInfoAttr> {
trace!("StandardInfoAttr");
- let created = WinTimestamp::from_reader(reader)?.to_datetime();
- let modified = WinTimestamp::from_reader(reader)?.to_datetime();
- let mft_modified = WinTimestamp::from_reader(reader)?.to_datetime();
- let accessed = WinTimestamp::from_reader(reader)?.to_datetime();
+ let created = WinTimestamp::from_reader(reader)
+ .context(err::FailedToReadWindowsTime)?
+ .to_datetime();
+ let modified = WinTimestamp::from_reader(reader)
+ .context(err::FailedToReadWindowsTime)?
+ .to_datetime();
+ let mft_modified = WinTimestamp::from_reader(reader)
+ .context(err::FailedToReadWindowsTime)?
+ .to_datetime();
+ let accessed = WinTimestamp::from_reader(reader)
+ .context(err::FailedToReadWindowsTime)?
+ .to_datetime();
+
let file_flags = reader.read_u32::<LittleEndian>()?;
let max_version = reader.read_u32::<LittleEndian>()?;
let version = reader.read_u32::<LittleEndian>()?;
diff --git a/src/attr_x30.rs b/src/attr_x30.rs
index 105aec8..63564e7 100644
--- a/src/attr_x30.rs
+++ b/src/attr_x30.rs
@@ -10,7 +10,8 @@ use std::io::Read;
use chrono::{DateTime, Utc};
use serde::Serialize;
-use winstructs::reference::MftReference;
+use snafu::ResultExt;
+use winstructs::ntfs::mft_reference::MftReference;
use winstructs::timestamp::WinTimestamp;
#[derive(Serialize, Clone, Debug)]
@@ -30,7 +31,6 @@ pub struct FileNameAttr {
pub fullname: Option<String>,
}
-// TODO: fix docs (use correct idioms)
impl FileNameAttr {
/// Parse a Filename attrbiute buffer.
///
@@ -39,7 +39,8 @@ impl FileNameAttr {
/// Parse a raw buffer.
///
/// ```
- /// use rustymft::attr_x30::FileNameAttr;
+ /// use mft::attr_x30::FileNameAttr;
+ /// # use std::io::Cursor;
/// # fn test_filename_attribute() {
/// let attribute_buffer: &[u8] = &[
/// 0x05,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0xD5,0x2D,0x48,0x58,0x43,0x5F,0xCE,0x01,
@@ -50,16 +51,13 @@ impl FileNameAttr {
/// 0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00
/// ];
///
- /// let attribute = match FileNameAttr::new(attribute_buffer) {
- /// Ok(attribute) => attribute,
- /// Err(error) => panic!(error)
- /// };
+ /// let attribute = FileNameAttr::from_reader(&mut Cursor::new(attribute_buffer)).unwrap();
///
- /// assert_eq!(attribute.parent.0, 1407374883553285);
- /// assert_eq!(attribute.created.0, 130146182088895957);
- /// assert_eq!(attribute.modified.0, 130146182088895957);
- /// assert_eq!(attribute.mft_modified.0, 130146182088895957);
- /// assert_eq!(attribute.accessed.0, 130146182088895957);
+ /// assert_eq!(attribute.parent.entry, 1407374883553285);
+ /// assert_eq!(attribute.created.timestamp(), 130146182088895957);
+ /// assert_eq!(attribute.modified.timestamp(), 130146182088895957);
+ /// assert_eq!(attribute.mft_modified.timestamp(), 130146182088895957);
+ /// assert_eq!(attribute.accessed.timestamp(), 130146182088895957);
/// assert_eq!(attribute.logical_size, 67108864);
/// assert_eq!(attribute.physical_size, 67108864);
/// assert_eq!(attribute.flags, 6);
@@ -71,11 +69,19 @@ impl FileNameAttr {
/// ```
pub fn from_reader<R: Read>(reader: &mut R) -> Result<FileNameAttr> {
trace!("FileNameAttr");
- let parent = MftReference(reader.read_u64::<LittleEndian>()?);
- let created = WinTimestamp::from_reader(reader)?.to_datetime();
- let modified = WinTimestamp::from_reader(reader)?.to_datetime();
- let mft_modified = WinTimestamp::from_reader(reader)?.to_datetime();
- let accessed = WinTimestamp::from_reader(reader)?.to_datetime();
+ let parent = MftReference::from_reader(reader).context(err::FailedToReadMftReference)?;
+ let created = WinTimestamp::from_reader(reader)
+ .context(err::FailedToReadWindowsTime)?
+ .to_datetime();
+ let modified = WinTimestamp::from_reader(reader)
+ .context(err::FailedToReadWindowsTime)?
+ .to_datetime();
+ let mft_modified = WinTimestamp::from_reader(reader)
+ .context(err::FailedToReadWindowsTime)?
+ .to_datetime();
+ let accessed = WinTimestamp::from_reader(reader)
+ .context(err::FailedToReadWindowsTime)?
+ .to_datetime();
let logical_size = reader.read_u64::<LittleEndian>()?;
let physical_size = reader.read_u64::<LittleEndian>()?;
let flags = reader.read_u32::<LittleEndian>()?;
diff --git a/src/attribute.rs b/src/attribute.rs
index 6c6db92..17faad2 100644
--- a/src/attribute.rs
+++ b/src/attribute.rs
@@ -3,7 +3,7 @@ use crate::attr_x30::FileNameAttr;
use crate::err::{self, Result};
use crate::utils::read_utf16_string;
use crate::{utils, ReadSeek};
-use log::debug;
+
use bitflags::bitflags;
use byteorder::{LittleEndian, ReadBytesExt};
diff --git a/src/bin/mft_dump.rs b/src/bin/mft_dump.rs
index 2648916..3f7037d 100644
--- a/src/bin/mft_dump.rs
+++ b/src/bin/mft_dump.rs
@@ -1,6 +1,6 @@
use clap::{App, Arg};
use env_logger;
-use log::{debug, error, info, warn};
+use log::{info, warn};
use mft::mft::MftHandler;
fn process_file(filename: &str, indent: bool) -> bool {
diff --git a/src/entry.rs b/src/entry.rs
index 8aa3c38..6f45b5c 100644
--- a/src/entry.rs
+++ b/src/entry.rs
@@ -3,14 +3,12 @@ use crate::err::{self, Result};
use crate::attr_x10::StandardInfoAttr;
use crate::attr_x30::FileNameAttr;
use crate::enumerator::PathMapping;
-use crate::mft::MftHandler;
+
use crate::{attribute, ReadSeek};
use log::debug;
-use snafu::ensure;
-
-use std::collections::BTreeMap;
+use snafu::{ensure, ResultExt};
-use winstructs::reference::MftReference;
+use winstructs::ntfs::mft_reference::MftReference;
use byteorder::{LittleEndian, ReadBytesExt};
@@ -20,7 +18,6 @@ use serde::{ser, Serialize};
use crate::attribute::MftAttribute;
use std::io::Cursor;
use std::io::Read;
-use std::io::Seek;
use std::io::SeekFrom;
//https://github.com/libyal/libfsntfs/blob/master/documentation/New%20Technologies%20File%20System%20(NTFS).asciidoc#5-the-master-file-table-mft
@@ -89,7 +86,8 @@ impl EntryHeader {
let flags = EntryFlags::from_bits_truncate(reader.read_u16::<LittleEndian>()?);
let entry_size_real = reader.read_u32::<LittleEndian>()?;
let entry_size_allocated = reader.read_u32::<LittleEndian>()?;
- let base_reference = MftReference(reader.read_u64::<LittleEndian>()?);
+ let base_reference =
+ MftReference::from_reader(reader).context(err::FailedToReadMftReference)?;
let next_attribute_id = reader.read_u16::<LittleEndian>()?;
ensure!(
@@ -100,7 +98,7 @@ impl EntryHeader {
let _padding = reader.read_u16::<LittleEndian>()?;
let record_number = u64::from(reader.read_u32::<LittleEndian>()?);
- let entry_reference = MftReference::get_from_entry_and_seq(record_number as u64, sequence);
+ let entry_reference = MftReference::new(record_number as u64, sequence);
Ok(EntryHeader {
signature,
@@ -157,7 +155,7 @@ impl MftEntry {
if attrib.namespace != 2 {
return Some(PathMapping {
name: attrib.name.clone(),
- parent: MftReference(attrib.parent.0),
+ parent: attrib.parent.clone(),
});
}
}
@@ -287,7 +285,7 @@ mod tests {
assert_eq!(entry_header.flags.bits(), 5);
assert_eq!(entry_header.entry_size_real, 840);
assert_eq!(entry_header.entry_size_allocated, 1024);
- assert_eq!(entry_header.base_reference.0, 0);
+ assert_eq!(entry_header.base_reference.entry, 0);
assert_eq!(entry_header.next_attribute_id, 6);
assert_eq!(entry_header.record_number, 38357);
}
diff --git a/src/enumerator.rs b/src/enumerator.rs
index ad6a322..eb5e6e5 100644
--- a/src/enumerator.rs
+++ b/src/enumerator.rs
@@ -1,5 +1,5 @@
use std::collections::HashMap;
-use winstructs::reference::MftReference;
+use winstructs::ntfs::mft_reference::MftReference;
#[derive(Hash, Eq, PartialEq, Debug, Clone)]
pub struct PathMapping {
diff --git a/src/err.rs b/src/err.rs
index 99c80a2..0ab083b 100644
--- a/src/err.rs
+++ b/src/err.rs
@@ -22,6 +22,10 @@ pub enum Error {
UnhandledResidentFlag { flag: u8, offset: u64 },
#[snafu(display("Expected usa_offset `{}` to equal 48", offset))]
InvalidUsaOffset { offset: u16 },
+ #[snafu(display("Failed to read MftReference: `{}`", "source"))]
+ FailedToReadMftReference { source: winstructs::err::Error },
+ #[snafu(display("Failed to read WindowsTime: `{}`", "source"))]
+ FailedToReadWindowsTime { source: winstructs::err::Error },
#[snafu(display("An unexpected error has occurred: {}", detail))]
Any { detail: String },
}
diff --git a/src/mft.rs b/src/mft.rs
index 71acbf7..9569cc9 100644
--- a/src/mft.rs
+++ b/src/mft.rs
@@ -1,20 +1,20 @@
-use crate::ReadSeek;
use crate::entry::MftEntry;
use crate::enumerator::{PathEnumerator, PathMapping};
use crate::err::{self, Result};
+
use log::debug;
use snafu::ResultExt;
use std::fs::File;
use std::io::{BufReader, Read, Seek, SeekFrom};
use std::path::Path;
-use winstructs::reference::MftReference;
+use winstructs::ntfs::mft_reference::MftReference;
pub struct MftHandler {
file: BufReader<File>,
path_enumerator: PathEnumerator,
- _entry_size: u32,
- _offset: u64,
- _size: u64,
+ entry_size: u32,
+ offset: u64,
+ size: u64,
}
impl MftHandler {
@@ -23,42 +23,40 @@ impl MftHandler {
let mut mft_fh = File::open(f).context(err::FailedToOpenFile { path: f.to_owned() })?;
- debug!("Seek!");
// TODO: remove this, and find a better way
let size = match mft_fh.seek(SeekFrom::End(0)) {
Err(e) => panic!("Error: {}", e),
Ok(size) => size,
};
- debug!("After Seek!");
let filehandle = BufReader::with_capacity(4096, mft_fh);
Ok(MftHandler {
file: filehandle,
path_enumerator: PathEnumerator::new(),
- _entry_size: 1024,
- _offset: 0,
- _size: size,
+ entry_size: 1024,
+ offset: 0,
+ size,
})
}
pub fn set_entry_size(&mut self, entry_size: u32) {
- self._entry_size = entry_size
+ self.entry_size = entry_size
}
pub fn get_entry_count(&self) -> u64 {
- self._size / u64::from(self._entry_size)
+ self.size / u64::from(self.entry_size)
}
pub fn entry(&mut self, entry: u64) -> Result<MftEntry> {
debug!("Reading entry {}", entry);
self.file
- .seek(SeekFrom::Start(entry * u64::from(self._entry_size)))?;
+ .seek(SeekFrom::Start(entry * u64::from(self.entry_size)))?;
- let mut entry_buffer = vec![0; self._entry_size as usize];
+ let mut entry_buffer = vec![0; self.entry_size as usize];
self.file.read_exact(&mut entry_buffer)?;
- let mut mft_entry = self.entry_from_buffer(entry_buffer, entry)?;
+ let mft_entry = self.entry_from_buffer(entry_buffer, entry)?;
// We need to set the path if dir
if let Some(mapping) = mft_entry.get_pathmap() {
@@ -69,7 +67,7 @@ impl MftHandler {
}
// TODO: don't do this mutably from here.
-// mft_entry.set_full_names(self);
+ // mft_entry.set_full_names(self);
Ok(mft_entry)
}
@@ -92,18 +90,18 @@ impl MftHandler {
fn enumerate_path_stack(&mut self, name_stack: &mut Vec<String>, reference: MftReference) {
// 1407374883553285 (5-5)
- if reference.0 == 1_407_374_883_553_285 {
+ if reference.entry == 1_407_374_883_553_285 {
} else {
match self.path_enumerator.get_mapping(reference) {
Some(mapping) => {
- self.enumerate_path_stack(name_stack, mapping.parent.clone());
+ self.enumerate_path_stack(name_stack, mapping.parent);
name_stack.push(mapping.name.clone());
}
None => {
// Mapping not exists
// Get entry number for this reference that does not exist
- let entry = reference.get_entry_number();
+ let entry = reference.entry;
// Gat mapping for it
match self.get_mapping_from_entry(entry) {
Ok(mapping) => match mapping {
@@ -126,9 +124,9 @@ impl MftHandler {
fn get_mapping_from_entry(&mut self, entry: u64) -> Result<Option<PathMapping>> {
self.file
- .seek(SeekFrom::Start(entry * self._entry_size as u64))?;
+ .seek(SeekFrom::Start(entry * u64::from(self.entry_size)))?;
- let mut entry_buffer = vec![0; self._entry_size as usize];
+ let mut entry_buffer = vec![0; self.entry_size as usize];
self.file.read_exact(&mut entry_buffer)?;
let mft_entry = self.entry_from_buffer(entry_buffer, entry)?;