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:40:33 +0300
committerColin Finck <colin@reactos.org>2021-04-21 22:40:33 +0300
commit11be5cf34e0b455a4677c3eb8cf72032ac97fbe6 (patch)
treeb59bac06904c224e54619736de27afe30c72d443
parentc815c5e771eb9f29291594c25ee247b365adcd68 (diff)
Implement the `NtfsObjectId` structured value along with `NtfsGuid`.
-rw-r--r--src/attribute.rs9
-rw-r--r--src/guid.rs53
-rw-r--r--src/lib.rs2
-rw-r--r--src/structured_values/mod.rs1
-rw-r--r--src/structured_values/object_id.rs75
5 files changed, 138 insertions, 2 deletions
diff --git a/src/attribute.rs b/src/attribute.rs
index dd56811..9be8ebe 100644
--- a/src/attribute.rs
+++ b/src/attribute.rs
@@ -5,7 +5,9 @@ use crate::attribute_value::{NtfsAttributeResidentValue, NtfsAttributeValue};
use crate::error::{NtfsError, Result};
use crate::ntfs_file::NtfsFile;
use crate::string::NtfsString;
-use crate::structured_values::{NtfsFileName, NtfsStandardInformation, NtfsStructuredValue};
+use crate::structured_values::{
+ NtfsFileName, NtfsObjectId, NtfsStandardInformation, NtfsStructuredValue,
+};
use binread::io::{Read, Seek, SeekFrom};
use binread::{BinRead, BinReaderExt};
use bitflags::bitflags;
@@ -246,7 +248,10 @@ impl NtfsAttribute {
let inner = NtfsFileName::new(self.position, attached_value, self.value_length())?;
Ok(NtfsStructuredValue::FileName(inner))
}
- NtfsAttributeType::ObjectId => panic!("TODO"),
+ NtfsAttributeType::ObjectId => {
+ let inner = NtfsObjectId::new(self.position, attached_value, self.value_length())?;
+ Ok(NtfsStructuredValue::ObjectId(inner))
+ }
NtfsAttributeType::SecurityDescriptor => panic!("TODO"),
NtfsAttributeType::VolumeName => panic!("TODO"),
NtfsAttributeType::VolumeInformation => panic!("TODO"),
diff --git a/src/guid.rs b/src/guid.rs
new file mode 100644
index 0000000..4deee30
--- /dev/null
+++ b/src/guid.rs
@@ -0,0 +1,53 @@
+// Copyright 2021 Colin Finck <colin@reactos.org>
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+use binread::BinRead;
+use core::fmt;
+
+/// Size of a single GUID on disk (= size of all GUID fields).
+pub(crate) const GUID_SIZE: u64 = 16;
+
+#[derive(BinRead, Clone, Debug, Eq, PartialEq)]
+pub struct NtfsGuid {
+ pub data1: u32,
+ pub data2: u16,
+ pub data3: u16,
+ pub data4: [u8; 8],
+}
+
+impl fmt::Display for NtfsGuid {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(
+ f,
+ "{:8X}-{:4X}-{:4X}-{:2X}{:2X}-{:2X}{:2X}{:2X}{:2X}{:2X}{:2X}",
+ self.data1,
+ self.data2,
+ self.data3,
+ self.data4[0],
+ self.data4[1],
+ self.data4[2],
+ self.data4[3],
+ self.data4[4],
+ self.data4[5],
+ self.data4[6],
+ self.data4[7]
+ )
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use super::*;
+
+ #[test]
+ fn test_guid() {
+ let guid = NtfsGuid {
+ data1: 0x67c8770b,
+ data2: 0x44f1,
+ data3: 0x410a,
+ data4: [0xab, 0x9a, 0xf9, 0xb5, 0x44, 0x6f, 0x13, 0xee],
+ };
+ let guid_string = guid.to_string();
+ assert_eq!(guid_string, "67C8770B-44F1-410A-AB9A-F9B5446F13EE");
+ }
+}
diff --git a/src/lib.rs b/src/lib.rs
index 673092b..f52feef 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -13,6 +13,7 @@ mod attribute;
mod attribute_value;
mod boot_sector;
mod error;
+mod guid;
mod ntfs;
mod ntfs_file;
mod string;
@@ -22,6 +23,7 @@ mod time;
pub use crate::attribute::*;
pub use crate::attribute_value::*;
pub use crate::error::*;
+pub use crate::guid::*;
pub use crate::ntfs::*;
pub use crate::ntfs_file::*;
pub use crate::string::*;
diff --git a/src/structured_values/mod.rs b/src/structured_values/mod.rs
index df4aa90..4a18d91 100644
--- a/src/structured_values/mod.rs
+++ b/src/structured_values/mod.rs
@@ -41,4 +41,5 @@ bitflags! {
pub enum NtfsStructuredValue {
StandardInformation(NtfsStandardInformation),
FileName(NtfsFileName),
+ ObjectId(NtfsObjectId),
}
diff --git a/src/structured_values/object_id.rs b/src/structured_values/object_id.rs
index 53769a7..adc96c8 100644
--- a/src/structured_values/object_id.rs
+++ b/src/structured_values/object_id.rs
@@ -1,2 +1,77 @@
// 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::guid::{NtfsGuid, GUID_SIZE};
+use binread::io::{Read, Seek};
+use binread::BinReaderExt;
+
+#[derive(Clone, Debug)]
+pub struct NtfsObjectId {
+ object_id: NtfsGuid,
+ birth_volume_id: Option<NtfsGuid>,
+ birth_object_id: Option<NtfsGuid>,
+ domain_id: Option<NtfsGuid>,
+}
+
+impl NtfsObjectId {
+ pub(crate) fn new<T>(
+ attribute_position: u64,
+ mut value_attached: NtfsAttributeValueAttached<'_, T>,
+ value_length: u64,
+ ) -> Result<Self>
+ where
+ T: Read + Seek,
+ {
+ if value_length < GUID_SIZE {
+ return Err(NtfsError::InvalidAttributeSize {
+ position: attribute_position,
+ ty: NtfsAttributeType::ObjectId,
+ expected: GUID_SIZE,
+ actual: value_length,
+ });
+ }
+
+ let object_id = value_attached.read_le::<NtfsGuid>()?;
+
+ let mut birth_volume_id = None;
+ if value_length >= 2 * GUID_SIZE {
+ birth_volume_id = Some(value_attached.read_le::<NtfsGuid>()?);
+ }
+
+ let mut birth_object_id = None;
+ if value_length >= 3 * GUID_SIZE {
+ birth_object_id = Some(value_attached.read_le::<NtfsGuid>()?);
+ }
+
+ let mut domain_id = None;
+ if value_length >= 4 * GUID_SIZE {
+ domain_id = Some(value_attached.read_le::<NtfsGuid>()?);
+ }
+
+ Ok(Self {
+ object_id,
+ birth_volume_id,
+ birth_object_id,
+ domain_id,
+ })
+ }
+
+ pub fn birth_object_id(&self) -> Option<&NtfsGuid> {
+ self.birth_object_id.as_ref()
+ }
+
+ pub fn birth_volume_id(&self) -> Option<&NtfsGuid> {
+ self.birth_volume_id.as_ref()
+ }
+
+ pub fn domain_id(&self) -> Option<&NtfsGuid> {
+ self.domain_id.as_ref()
+ }
+
+ pub fn object_id(&self) -> &NtfsGuid {
+ &self.object_id
+ }
+}