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-21 16:26:21 +0300
committerOmer Ben-Amram <omerbenamram@gmail.com>2019-05-21 16:26:21 +0300
commitbd571a7b262e1abf7b8297a3f6d76244ecf4082a (patch)
tree3ed4f0980ec8ae7190cacf37e1f451015e64c2dd
parent9c98e3d935e71800abaf8409873904ea170d59e5 (diff)
prefer win32 entries
-rw-r--r--src/attribute/x30.rs15
-rw-r--r--src/bin/mft_dump.rs11
-rw-r--r--src/err.rs2
-rw-r--r--src/mft.rs7
4 files changed, 30 insertions, 5 deletions
diff --git a/src/attribute/x30.rs b/src/attribute/x30.rs
index f073b9e..1e764fb 100644
--- a/src/attribute/x30.rs
+++ b/src/attribute/x30.rs
@@ -2,18 +2,29 @@ use crate::attribute::FileAttributeFlags;
use crate::err::{self, Result};
use crate::ReadSeek;
use log::trace;
+use snafu::OptionExt;
use byteorder::{LittleEndian, ReadBytesExt};
use encoding::all::UTF_16LE;
use encoding::{DecoderTrap, Encoding};
use chrono::{DateTime, Utc};
+use num_traits::FromPrimitive;
use serde::Serialize;
use snafu::ResultExt;
use winstructs::ntfs::mft_reference::MftReference;
use winstructs::timestamp::WinTimestamp;
+#[derive(FromPrimitive, Serialize, Clone, Debug, PartialOrd, PartialEq)]
+#[repr(u8)]
+pub enum FileNamespace {
+ POSIX = 0,
+ Win32 = 1,
+ DOS = 2,
+ Win32AndDos = 3,
+}
+
#[derive(Serialize, Clone, Debug)]
pub struct FileNameAttr {
pub parent: MftReference,
@@ -26,7 +37,7 @@ pub struct FileNameAttr {
pub flags: FileAttributeFlags,
pub reparse_value: u32,
pub name_length: u8,
- pub namespace: u8,
+ pub namespace: FileNamespace,
pub name: String,
}
@@ -86,6 +97,8 @@ impl FileNameAttr {
let reparse_value = stream.read_u32::<LittleEndian>()?;
let name_length = stream.read_u8()?;
let namespace = stream.read_u8()?;
+ let namespace =
+ FileNamespace::from_u8(namespace).context(err::UnknownNamespace { namespace })?;
let mut name_buffer = vec![0; (name_length as usize * 2) as usize];
stream.read_exact(&mut name_buffer)?;
diff --git a/src/bin/mft_dump.rs b/src/bin/mft_dump.rs
index c7ee604..0ca9406 100644
--- a/src/bin/mft_dump.rs
+++ b/src/bin/mft_dump.rs
@@ -11,6 +11,8 @@ use mft::{MftAttribute, MftEntry, ReadSeek};
use serde::Serialize;
use chrono::{DateTime, Utc};
+use mft::attribute::x30::FileNamespace;
+use mft::attribute::MftAttributeType::FileName;
use std::cmp::max;
use std::io;
use std::io::Write;
@@ -89,8 +91,10 @@ impl FlatMftEntryWithName {
for attr in entry_attributes.iter() {
if let MftAttributeContent::AttrX30(data) = &attr.data {
- file_name = Some(data.clone());
- break;
+ if [FileNamespace::Win32, FileNamespace::Win32AndDos].contains(&data.namespace) {
+ file_name = Some(data.clone());
+ break;
+ }
}
}
for attr in entry_attributes.iter() {
@@ -102,8 +106,7 @@ impl FlatMftEntryWithName {
let has_ads = entry_attributes
.iter()
- .find(|a| a.header.type_code == MftAttributeType::DATA && a.header.name_size > 0)
- .is_some();
+ .any(|a| a.header.type_code == MftAttributeType::DATA && a.header.name_size > 0);
FlatMftEntryWithName {
entry_id: entry.header.record_number,
diff --git a/src/err.rs b/src/err.rs
index 02bc09d..bfcad21 100644
--- a/src/err.rs
+++ b/src/err.rs
@@ -23,6 +23,8 @@ pub enum Error {
InvalidEntrySignature { bad_sig: Vec<u8> },
#[snafu(display("Unknown `AttributeType`: {:04X}", attribute_type))]
UnknownAttributeType { attribute_type: u32 },
+ #[snafu(display("Unknown filename namespace {}", namespace))]
+ UnknownNamespace { namespace: u8 },
#[snafu(display("Unhandled resident flag: {} (offset: {})", flag, offset))]
UnhandledResidentFlag { flag: u8, offset: u64 },
#[snafu(display(
diff --git a/src/mft.rs b/src/mft.rs
index 56fa2d9..f8d6d0a 100644
--- a/src/mft.rs
+++ b/src/mft.rs
@@ -7,6 +7,7 @@ use snafu::ResultExt;
use crate::attribute::MftAttributeContent::AttrX30;
+use crate::attribute::x30::FileNamespace;
use cached::stores::SizedCache;
use cached::Cached;
use std::fs::{self, File};
@@ -100,6 +101,12 @@ impl<T: ReadSeek> MftParser<T> {
for attribute in entry.iter_attributes().filter_map(|a| a.ok()) {
if let AttrX30(filename_header) = attribute.data {
+ if ![FileNamespace::Win32, FileNamespace::Win32AndDos]
+ .contains(&filename_header.namespace)
+ {
+ continue;
+ }
+
let parent_entry_id = filename_header.parent.entry;
// MFT entry 5 is the root path.