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

github.com/windirstat/ntfs.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/structured_values/file_name.rs')
-rw-r--r--src/structured_values/file_name.rs93
1 files changed, 56 insertions, 37 deletions
diff --git a/src/structured_values/file_name.rs b/src/structured_values/file_name.rs
index 22f104e..3628495 100644
--- a/src/structured_values/file_name.rs
+++ b/src/structured_values/file_name.rs
@@ -6,12 +6,11 @@ use crate::error::{NtfsError, Result};
use crate::file_reference::NtfsFileReference;
use crate::indexes::NtfsIndexEntryKey;
use crate::string::NtfsString;
-use crate::structured_values::{
- NtfsFileAttributeFlags, NtfsStructuredValue, NtfsStructuredValueFromSlice,
-};
+use crate::structured_values::{NtfsFileAttributeFlags, NtfsStructuredValue};
use crate::time::NtfsTime;
+use crate::value::NtfsValue;
use arrayvec::ArrayVec;
-use binread::io::Cursor;
+use binread::io::{Cursor, Read, Seek};
use binread::{BinRead, BinReaderExt};
use core::mem;
use enumn::N;
@@ -58,6 +57,32 @@ pub struct NtfsFileName {
}
impl NtfsFileName {
+ fn new<T>(r: &mut T, position: u64, value_length: u64) -> Result<Self>
+ where
+ T: Read + Seek,
+ {
+ if value_length < FILE_NAME_MIN_SIZE as u64 {
+ return Err(NtfsError::InvalidStructuredValueSize {
+ position,
+ ty: NtfsAttributeType::FileName,
+ expected: FILE_NAME_MIN_SIZE as u64,
+ actual: value_length,
+ });
+ }
+
+ let header = r.read_le::<FileNameHeader>()?;
+
+ let mut file_name = Self {
+ header,
+ name: ArrayVec::from([0u8; NAME_MAX_SIZE]),
+ };
+ file_name.validate_name_length(value_length, position)?;
+ file_name.validate_namespace(position)?;
+ file_name.read_name(r)?;
+
+ Ok(file_name)
+ }
+
pub fn access_time(&self) -> NtfsTime {
self.header.access_time
}
@@ -112,15 +137,21 @@ impl NtfsFileName {
self.header.parent_directory_reference
}
- fn read_name(&mut self, data: &[u8]) {
- debug_assert!(self.name.is_empty());
- let start = FILE_NAME_HEADER_SIZE;
- let end = start + self.name_length();
- self.name.try_extend_from_slice(&data[start..end]).unwrap();
+ fn read_name<T>(&mut self, r: &mut T) -> Result<()>
+ where
+ T: Read + Seek,
+ {
+ debug_assert_eq!(self.name.len(), NAME_MAX_SIZE);
+
+ let name_length = self.name_length();
+ r.read_exact(&mut self.name[..name_length])?;
+ self.name.truncate(name_length);
+
+ Ok(())
}
- fn validate_name_length(&self, data_size: usize, position: u64) -> Result<()> {
- let total_size = FILE_NAME_HEADER_SIZE + self.name_length();
+ fn validate_name_length(&self, data_size: u64, position: u64) -> Result<()> {
+ let total_size = (FILE_NAME_HEADER_SIZE + self.name_length()) as u64;
if total_size > data_size {
return Err(NtfsError::InvalidStructuredValueSize {
@@ -146,40 +177,28 @@ impl NtfsFileName {
}
}
-impl NtfsStructuredValue for NtfsFileName {
+impl<'n, 'f> NtfsStructuredValue<'n, 'f> for NtfsFileName {
const TY: NtfsAttributeType = NtfsAttributeType::FileName;
-}
-impl<'s> NtfsStructuredValueFromSlice<'s> for NtfsFileName {
- fn from_slice(slice: &'s [u8], position: u64) -> Result<Self> {
- if slice.len() < FILE_NAME_MIN_SIZE {
- return Err(NtfsError::InvalidStructuredValueSize {
- position,
- ty: NtfsAttributeType::FileName,
- expected: FILE_NAME_MIN_SIZE,
- actual: slice.len(),
- });
- }
-
- let mut cursor = Cursor::new(slice);
- let header = cursor.read_le::<FileNameHeader>()?;
+ fn from_value<T>(fs: &mut T, value: NtfsValue<'n, 'f>) -> Result<Self>
+ where
+ T: Read + Seek,
+ {
+ let position = value.data_position().unwrap();
+ let value_length = value.len();
- let mut file_name = Self {
- header,
- name: ArrayVec::new(),
- };
- file_name.validate_name_length(slice.len(), position)?;
- file_name.validate_namespace(position)?;
- file_name.read_name(slice);
-
- Ok(file_name)
+ let mut value_attached = value.attach(fs);
+ Self::new(&mut value_attached, position, value_length)
}
}
// `NtfsFileName` is special in the regard that the index entry key has the same structure as the structured value.
impl NtfsIndexEntryKey for NtfsFileName {
fn key_from_slice(slice: &[u8], position: u64) -> Result<Self> {
- Self::from_slice(slice, position)
+ let value_length = slice.len() as u64;
+
+ let mut cursor = Cursor::new(slice);
+ Self::new(&mut cursor, position, value_length)
}
}
@@ -209,7 +228,7 @@ mod tests {
// Check the actual "file name" of the MFT.
let file_name = attribute
- .resident_structured_value::<NtfsFileName>()
+ .structured_value::<_, NtfsFileName>(&mut testfs1)
.unwrap();
let creation_time = file_name.creation_time();