pub mod header;
pub mod raw;
pub mod x10;
pub mod x20;
pub mod x30;
pub mod x40;
pub mod x80;
pub mod x90;
use crate::err::Result;
use crate::{impl_serialize_for_bitflags, ReadSeek};
use bitflags::bitflags;
use crate::attribute::raw::RawAttribute;
use crate::attribute::x10::StandardInfoAttr;
use crate::attribute::x20::AttributeListAttr;
use crate::attribute::x30::FileNameAttr;
use crate::attribute::header::{MftAttributeHeader, ResidentHeader};
use crate::attribute::x40::ObjectIdAttr;
use crate::attribute::x80::DataAttr;
use crate::attribute::x90::IndexRootAttr;
use serde::Serialize;
#[derive(Serialize, Clone, Debug)]
pub struct MftAttribute {
pub header: MftAttributeHeader,
pub data: MftAttributeContent,
}
impl MftAttributeContent {
pub fn from_stream_resident<S: ReadSeek>(
stream: &mut S,
header: &MftAttributeHeader,
resident: &ResidentHeader,
) -> Result<Self> {
match header.type_code {
MftAttributeType::StandardInformation => Ok(MftAttributeContent::AttrX10(
StandardInfoAttr::from_reader(stream)?,
)),
MftAttributeType::AttributeList => Ok(MftAttributeContent::AttrX20(
AttributeListAttr::from_stream(stream)?,
)),
MftAttributeType::FileName => Ok(MftAttributeContent::AttrX30(
FileNameAttr::from_stream(stream)?,
)),
MftAttributeType::DATA => Ok(MftAttributeContent::AttrX80(DataAttr::from_stream(
stream,
resident.data_size as usize,
)?)),
MftAttributeType::ObjectId => Ok(MftAttributeContent::AttrX40(
ObjectIdAttr::from_stream(stream, resident.data_size as usize)?,
)),
MftAttributeType::IndexRoot => Ok(MftAttributeContent::AttrX90(
IndexRootAttr::from_stream(stream)?,
)),
_ => Ok(MftAttributeContent::Raw(RawAttribute::from_stream(
stream,
header.type_code.clone(),
resident.data_size as usize,
)?)),
}
}
pub fn into_index_root(self) -> Option<IndexRootAttr> {
match self {
MftAttributeContent::AttrX90(content) => Some(content),
_ => None,
}
}
pub fn into_object_id(self) -> Option<ObjectIdAttr> {
match self {
MftAttributeContent::AttrX40(content) => Some(content),
_ => None,
}
}
pub fn into_standard_info(self) -> Option<StandardInfoAttr> {
match self {
MftAttributeContent::AttrX10(content) => Some(content),
_ => None,
}
}
pub fn into_data(self) -> Option<DataAttr> {
match self {
MftAttributeContent::AttrX80(content) => Some(content),
_ => None,
}
}
pub fn into_file_name(self) -> Option<FileNameAttr> {
match self {
MftAttributeContent::AttrX30(content) => Some(content),
_ => None,
}
}
}
#[derive(Serialize, Clone, Debug)]
#[serde(untagged)]
pub enum MftAttributeContent {
Raw(RawAttribute),
AttrX80(DataAttr),
AttrX10(StandardInfoAttr),
AttrX20(AttributeListAttr),
AttrX30(FileNameAttr),
AttrX40(ObjectIdAttr),
AttrX90(IndexRootAttr),
None,
}
#[derive(Serialize, Debug, Clone, FromPrimitive, ToPrimitive, PartialOrd, PartialEq)]
#[repr(u32)]
pub enum MftAttributeType {
StandardInformation = 0x10_u32,
AttributeList = 0x20_u32,
FileName = 0x30_u32,
ObjectId = 0x40_u32,
SecurityDescriptor = 0x50_u32,
VolumeName = 0x60_u32,
VolumeInformation = 0x70_u32,
DATA = 0x80_u32,
IndexRoot = 0x90_u32,
IndexAllocation = 0xA0_u32,
BITMAP = 0xB0_u32,
ReparsePoint = 0xC0_u32,
EaInformation = 0xD0_u32,
EA = 0xE0_u32,
LoggedUtilityStream = 0x100_u32,
}
bitflags! {
pub struct FileAttributeFlags: u32 {
const FILE_ATTRIBUTE_READONLY = 0x0000_0001;
const FILE_ATTRIBUTE_HIDDEN = 0x0000_0002;
const FILE_ATTRIBUTE_SYSTEM = 0x0000_0004;
const FILE_ATTRIBUTE_ARCHIVE = 0x0000_0020;
const FILE_ATTRIBUTE_DEVICE = 0x0000_0040;
const FILE_ATTRIBUTE_NORMAL = 0x0000_0080;
const FILE_ATTRIBUTE_TEMPORARY = 0x0000_0100;
const FILE_ATTRIBUTE_SPARSE_FILE = 0x0000_0200;
const FILE_ATTRIBUTE_REPARSE_POINT = 0x0000_0400;
const FILE_ATTRIBUTE_COMPRESSED = 0x0000_0800;
const FILE_ATTRIBUTE_OFFLINE = 0x0000_1000;
const FILE_ATTRIBUTE_NOT_CONTENT_INDEXED = 0x0000_2000;
const FILE_ATTRIBUTE_ENCRYPTED = 0x0000_4000;
}
}
impl_serialize_for_bitflags! {FileAttributeFlags}
bitflags! {
#[derive(Default)]
pub struct AttributeDataFlags: u16 {
const IS_COMPRESSED = 0x0001;
const COMPRESSION_MASK = 0x00FF;
const ENCRYPTED = 0x4000;
const SPARSE = 0x8000;
}
}
impl_serialize_for_bitflags! {AttributeDataFlags}