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:
Diffstat (limited to 'src/attribute/mod.rs')
-rw-r--r--src/attribute/mod.rs45
1 files changed, 41 insertions, 4 deletions
diff --git a/src/attribute/mod.rs b/src/attribute/mod.rs
index 8ac11ce..481d69c 100644
--- a/src/attribute/mod.rs
+++ b/src/attribute/mod.rs
@@ -10,6 +10,8 @@ pub mod x90;
use crate::err::Result;
use crate::{impl_serialize_for_bitflags, ReadSeek};
+use std::io::Cursor;
+
use bitflags::bitflags;
use crate::attribute::raw::RawAttribute;
@@ -39,9 +41,26 @@ impl MftAttributeContent {
MftAttributeType::StandardInformation => Ok(MftAttributeContent::AttrX10(
StandardInfoAttr::from_reader(stream)?,
)),
- MftAttributeType::AttributeList => Ok(MftAttributeContent::AttrX20(
- AttributeListAttr::from_stream(stream)?,
- )),
+ MftAttributeType::AttributeList => {
+ // An attribute list is a buffer of attribute entries which are varying sizes if
+ // the attributes contain names. Thus, we must know when to stop reading. To
+ // do this, we will create a buffer of the attribute, and stop reading attribute
+ // entries when we reach the end of the buffer.
+ let content_size = resident.data_size;
+
+ let mut attribute_buffer = vec![0; content_size as usize];
+ stream.read_exact(&mut attribute_buffer)?;
+
+ // Create a new stream that the attribute will read from.
+ let mut new_stream = Cursor::new(attribute_buffer);
+
+ let attr_list = AttributeListAttr::from_stream(
+ &mut new_stream,
+ Some(content_size as u64)
+ )?;
+
+ Ok(MftAttributeContent::AttrX20(attr_list))
+ },
MftAttributeType::FileName => Ok(MftAttributeContent::AttrX30(
FileNameAttr::from_stream(stream)?,
)),
@@ -67,6 +86,14 @@ impl MftAttributeContent {
}
}
+ /// Converts the given attributes into a 'AttributeListAttr', consuming the object attribute object.
+ pub fn into_attribute_list(self) -> Option<AttributeListAttr> {
+ match self {
+ MftAttributeContent::AttrX20(content) => Some(content),
+ _ => None,
+ }
+ }
+
/// Converts the given attributes into a `IndexRootAttr`, consuming the object attribute object.
pub fn into_index_root(self) -> Option<IndexRootAttr> {
match self {
@@ -109,11 +136,11 @@ impl MftAttributeContent {
#[serde(untagged)]
pub enum MftAttributeContent {
Raw(RawAttribute),
- AttrX80(DataAttr),
AttrX10(StandardInfoAttr),
AttrX20(AttributeListAttr),
AttrX30(FileNameAttr),
AttrX40(ObjectIdAttr),
+ AttrX80(DataAttr),
AttrX90(IndexRootAttr),
/// Empty - used when data is non resident.
None,
@@ -158,10 +185,15 @@ pub enum MftAttributeType {
}
bitflags! {
+ /// Flag sources:
+ /// https://github.com/EricZimmerman/MFT/blob/3bed2626ee85e9a96a6db70a17407d0c3696056a/MFT/Attributes/StandardInfo.cs#L10
+ /// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/ca28ec38-f155-4768-81d6-4bfeb8586fc9
+ ///
pub struct FileAttributeFlags: u32 {
const FILE_ATTRIBUTE_READONLY = 0x0000_0001;
const FILE_ATTRIBUTE_HIDDEN = 0x0000_0002;
const FILE_ATTRIBUTE_SYSTEM = 0x0000_0004;
+ const FILE_ATTRIBUTE_DIRECTORY = 0x0000_0010;
const FILE_ATTRIBUTE_ARCHIVE = 0x0000_0020;
const FILE_ATTRIBUTE_DEVICE = 0x0000_0040;
const FILE_ATTRIBUTE_NORMAL = 0x0000_0080;
@@ -172,6 +204,11 @@ bitflags! {
const FILE_ATTRIBUTE_OFFLINE = 0x0000_1000;
const FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x0000_2000;
const FILE_ATTRIBUTE_ENCRYPTED = 0x0000_4000;
+ const FILE_ATTRIBUTE_INTEGRITY_STREAM = 0x0000_8000;
+ const FILE_ATTRIBUTE_NO_SCRUB_DATA = 0x0002_0000;
+ const FILE_ATTRIBUTE_HAS_EA = 0x0004_0000;
+ const FILE_ATTRIBUTE_IS_DIRECTORY = 0x1000_0000;
+ const FILE_ATTRIBUTE_INDEX_VIEW = 0x2000_0000;
}
}