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.rs33
1 files changed, 30 insertions, 3 deletions
diff --git a/src/attribute/mod.rs b/src/attribute/mod.rs
index 8ac11ce..e1842c4 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 {