From 6b50e978819a4d9377700d1dd12acd551bd9c38c Mon Sep 17 00:00:00 2001 From: reece394 <31659691+reece394@users.noreply.github.com> Date: Sat, 11 Jan 2025 15:24:58 +0000 Subject: [PATCH] Attempt to Update Bitflags --- Cargo.toml | 2 +- src/attribute/mod.rs | 69 +++++++++++++++++++++++++++++++++++++++++++- src/attribute/x90.rs | 56 +++++++++++++++++++++++++++++++++++ src/entry.rs | 26 +++++++++++++++++ src/macros.rs | 2 +- 5 files changed, 152 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 2758303..b742457 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ edition = "2021" log = { version = "0.4", features = ["release_max_level_debug"] } encoding = "0.2" byteorder = "1" -bitflags = "1" +bitflags = "2.7" serde = { version = "1", features = ["derive"] } serde_json = "1" csv = "1" diff --git a/src/attribute/mod.rs b/src/attribute/mod.rs index c00fb42..22570b2 100644 --- a/src/attribute/mod.rs +++ b/src/attribute/mod.rs @@ -13,6 +13,7 @@ use crate::err::Result; use crate::impl_serialize_for_bitflags; use std::io::{Cursor, Read, Seek}; +use std::fmt; use bitflags::bitflags; @@ -211,6 +212,7 @@ bitflags! { /// /// /// + #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct FileAttributeFlags: u32 { const FILE_ATTRIBUTE_READONLY = 0x0000_0001; const FILE_ATTRIBUTE_HIDDEN = 0x0000_0002; @@ -234,10 +236,50 @@ bitflags! { } } +impl fmt::Display for FileAttributeFlags { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut first = true; + for flag in [ + FileAttributeFlags::FILE_ATTRIBUTE_READONLY, + FileAttributeFlags::FILE_ATTRIBUTE_HIDDEN, + FileAttributeFlags::FILE_ATTRIBUTE_SYSTEM, + FileAttributeFlags::FILE_ATTRIBUTE_DIRECTORY, + FileAttributeFlags::FILE_ATTRIBUTE_ARCHIVE, + FileAttributeFlags::FILE_ATTRIBUTE_DEVICE, + FileAttributeFlags::FILE_ATTRIBUTE_NORMAL, + FileAttributeFlags::FILE_ATTRIBUTE_TEMPORARY, + FileAttributeFlags::FILE_ATTRIBUTE_SPARSE_FILE, + FileAttributeFlags::FILE_ATTRIBUTE_REPARSE_POINT, + FileAttributeFlags::FILE_ATTRIBUTE_COMPRESSED, + FileAttributeFlags::FILE_ATTRIBUTE_OFFLINE, + FileAttributeFlags::FILE_ATTRIBUTE_NOT_CONTENT_INDEXED, + FileAttributeFlags::FILE_ATTRIBUTE_ENCRYPTED, + FileAttributeFlags::FILE_ATTRIBUTE_INTEGRITY_STREAM, + FileAttributeFlags::FILE_ATTRIBUTE_NO_SCRUB_DATA, + FileAttributeFlags::FILE_ATTRIBUTE_HAS_EA, + FileAttributeFlags::FILE_ATTRIBUTE_IS_DIRECTORY, + FileAttributeFlags::FILE_ATTRIBUTE_INDEX_VIEW, + // Add other flags as needed + ] { + if self.contains(flag) { + if !first { + write!(f, " | ")?; + } + let flag_str = format!("{:?}", flag); + let flag_str = flag_str.strip_prefix("FileAttributeFlags(").unwrap_or(&flag_str); + let flag_str = flag_str.strip_suffix(")").unwrap_or(&flag_str); + write!(f, "{}", flag_str)?; + first = false; + } + } + Ok(()) + } +} + impl_serialize_for_bitflags! {FileAttributeFlags} bitflags! { - #[derive(Default)] + #[derive(Default, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct AttributeDataFlags: u16 { const IS_COMPRESSED = 0x0001; const COMPRESSION_MASK = 0x00FF; @@ -246,4 +288,29 @@ bitflags! { } } +impl fmt::Display for AttributeDataFlags { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut first = true; + for flag in [ + AttributeDataFlags::IS_COMPRESSED, + AttributeDataFlags::COMPRESSION_MASK, + AttributeDataFlags::ENCRYPTED, + AttributeDataFlags::SPARSE, + // Add other flags as needed + ] { + if self.contains(flag) { + if !first { + write!(f, " | ")?; + } + let flag_str = format!("{:?}", flag); + let flag_str = flag_str.strip_prefix("AttributeDataFlags(").unwrap_or(&flag_str); + let flag_str = flag_str.strip_suffix(")").unwrap_or(&flag_str); + write!(f, "{}", flag_str)?; + first = false; + } + } + Ok(()) + } +} + impl_serialize_for_bitflags! {AttributeDataFlags} diff --git a/src/attribute/x90.rs b/src/attribute/x90.rs index 2bef640..7f8392f 100644 --- a/src/attribute/x90.rs +++ b/src/attribute/x90.rs @@ -10,6 +10,7 @@ use bitflags::bitflags; use serde::Serialize; use winstructs::ntfs::mft_reference::MftReference; use std::io::SeekFrom; +use std::fmt; use num_derive::FromPrimitive; use num_traits::FromPrimitive; @@ -51,11 +52,41 @@ pub enum IndexCollationRules { } bitflags! { + #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct IndexRootFlags: u32 { const SMALL_INDEX = 0x00; const LARGE_INDEX = 0x01; } } + +impl fmt::Display for IndexRootFlags { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut first = true; + for flag in [ + IndexRootFlags::SMALL_INDEX, + IndexRootFlags::LARGE_INDEX, + // Add other flags as needed + ] { + if self.contains(flag) { + if !first { + write!(f, " | ")?; + } + let flag_str = if flag.bits() == 0x00 { + "SMALL_INDEX".to_string() + } else { + let flag_str = format!("{:?}", flag); + let flag_str = flag_str.strip_prefix("IndexRootFlags(").unwrap_or(&flag_str); + let flag_str = flag_str.strip_suffix(")").unwrap_or(&flag_str); + flag_str.to_string() + }; + write!(f, "{}", flag_str)?; + first = false; + } + } + Ok(()) + } +} + impl_serialize_for_bitflags! {IndexRootFlags} impl IndexRootAttr { @@ -102,11 +133,36 @@ pub struct IndexEntryHeader { pub fname_info: FileNameAttr } bitflags! { + #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct IndexEntryFlags: u32 { const INDEX_ENTRY_NODE = 0x01; const INDEX_ENTRY_END = 0x02; } } + +impl fmt::Display for IndexEntryFlags { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut first = true; + for flag in [ + IndexEntryFlags::INDEX_ENTRY_NODE, + IndexEntryFlags::INDEX_ENTRY_END, + // Add other flags as needed + ] { + if self.contains(flag) { + if !first { + write!(f, " | ")?; + } + let flag_str = format!("{:?}", flag); + let flag_str = flag_str.strip_prefix("IndexEntryFlags(").unwrap_or(&flag_str); + let flag_str = flag_str.strip_suffix(")").unwrap_or(&flag_str); + write!(f, "{}", flag_str)?; + first = false; + } + } + Ok(()) + } +} + impl_serialize_for_bitflags! {IndexEntryFlags} impl IndexEntryHeader { diff --git a/src/entry.rs b/src/entry.rs index cfb4faf..fa368d1 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -18,6 +18,7 @@ use crate::attribute::{MftAttribute, MftAttributeContent, MftAttributeType}; use std::io::Read; use std::io::SeekFrom; use std::io::{Cursor, Seek}; +use std::fmt; const SEQUENCE_NUMBER_STRIDE: usize = 512; @@ -83,6 +84,7 @@ pub struct EntryHeader { pub record_number: u64, } bitflags! { + #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Clone, Copy)] pub struct EntryFlags: u16 { const ALLOCATED = 0x01; const INDEX_PRESENT = 0x02; @@ -91,6 +93,30 @@ bitflags! { } } +impl fmt::Display for EntryFlags { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut first = true; + for flag in [ + EntryFlags::ALLOCATED, + EntryFlags::INDEX_PRESENT, + EntryFlags::IS_EXTENSION, + EntryFlags::SPECIAL_INDEX_PRESENT, + ] { + if self.contains(flag) { + if !first { + write!(f, " | ")?; + } + let flag_str = format!("{:?}", flag); + let flag_str = flag_str.strip_prefix("EntryFlags(").unwrap_or(&flag_str); + let flag_str = flag_str.strip_suffix(")").unwrap_or(&flag_str); + write!(f, "{}", flag_str)?; + first = false; + } + } + Ok(()) + } +} + impl_serialize_for_bitflags! {EntryFlags} impl EntryHeader { diff --git a/src/macros.rs b/src/macros.rs index c643413..3efe42b 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -6,7 +6,7 @@ macro_rules! impl_serialize_for_bitflags { where S: serde::ser::Serializer, { - serializer.serialize_str(&format!("{:?}", &self)) + serializer.serialize_str(&self.to_string()) } } };