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:
authorColin Finck <colin@reactos.org>2021-04-21 22:41:28 +0300
committerColin Finck <colin@reactos.org>2021-04-21 22:41:28 +0300
commita724f9775f268ef313982c73c712b389d3faf186 (patch)
treea0c16358af9470319077e8264b58556fd46137e6 /src/structured_values/volume_name.rs
parent11be5cf34e0b455a4677c3eb8cf72032ac97fbe6 (diff)
Implement `NtfsVolumeInformation` and `NtfsVolumeName` structured values
Diffstat (limited to 'src/structured_values/volume_name.rs')
-rw-r--r--src/structured_values/volume_name.rs81
1 files changed, 81 insertions, 0 deletions
diff --git a/src/structured_values/volume_name.rs b/src/structured_values/volume_name.rs
index 53769a7..72bd3bc 100644
--- a/src/structured_values/volume_name.rs
+++ b/src/structured_values/volume_name.rs
@@ -1,2 +1,83 @@
// Copyright 2021 Colin Finck <colin@reactos.org>
// SPDX-License-Identifier: GPL-2.0-or-later
+
+use crate::attribute::NtfsAttributeType;
+use crate::attribute_value::NtfsAttributeValueAttached;
+use crate::error::{NtfsError, Result};
+use crate::string::NtfsString;
+use binread::io::{Read, Seek, SeekFrom};
+use core::mem;
+
+/// The smallest VolumeName attribute has a name containing just a single character.
+const VOLUME_NAME_MIN_SIZE: u64 = mem::size_of::<u16>() as u64;
+
+/// The largest VolumeName attribute has a name containing 128 UTF-16 code points (256 bytes).
+const VOLUME_NAME_MAX_SIZE: u64 = 128 * mem::size_of::<u16>() as u64;
+
+#[derive(Clone, Debug)]
+pub struct NtfsVolumeName {
+ name_position: u64,
+ name_length: u16,
+}
+
+impl NtfsVolumeName {
+ pub(crate) fn new<T>(
+ attribute_position: u64,
+ value_attached: NtfsAttributeValueAttached<'_, T>,
+ value_length: u64,
+ ) -> Result<Self>
+ where
+ T: Read + Seek,
+ {
+ if value_length < VOLUME_NAME_MIN_SIZE {
+ return Err(NtfsError::InvalidAttributeSize {
+ position: attribute_position,
+ ty: NtfsAttributeType::VolumeName,
+ expected: VOLUME_NAME_MIN_SIZE,
+ actual: value_length,
+ });
+ } else if value_length > VOLUME_NAME_MAX_SIZE {
+ return Err(NtfsError::InvalidAttributeSize {
+ position: attribute_position,
+ ty: NtfsAttributeType::VolumeName,
+ expected: VOLUME_NAME_MAX_SIZE,
+ actual: value_length,
+ });
+ }
+
+ let name_position = value_attached.position();
+ let name_length = value_length as u16;
+
+ Ok(Self {
+ name_position,
+ name_length,
+ })
+ }
+
+ /// Returns the volume name length, in bytes.
+ ///
+ /// A volume name has a maximum length of 128 UTF-16 code points (256 bytes).
+ pub fn name_length(&self) -> usize {
+ self.name_length as usize
+ }
+
+ /// Reads the volume name into the given buffer, and returns an
+ /// [`NtfsString`] wrapping that buffer.
+ pub fn read_name<'a, T>(&self, fs: &mut T, buf: &'a mut [u8]) -> Result<NtfsString<'a>>
+ where
+ T: Read + Seek,
+ {
+ let name_length = self.name_length();
+ if buf.len() < name_length {
+ return Err(NtfsError::BufferTooSmall {
+ expected: name_length,
+ actual: buf.len(),
+ });
+ }
+
+ fs.seek(SeekFrom::Start(self.name_position))?;
+ fs.read_exact(&mut buf[..name_length])?;
+
+ Ok(NtfsString(&buf[..name_length]))
+ }
+}