diff options
Diffstat (limited to 'src/attribute/mod.rs')
-rw-r--r-- | src/attribute/mod.rs | 33 |
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 { |