1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use crate::err::{Result};

use log::trace;
use byteorder::{LittleEndian, ReadBytesExt};
use chrono::{DateTime, Utc};
use serde::Serialize;
use std::io::Read;
use winstructs::timestamp::WinTimestamp;

#[derive(Serialize, Debug, Clone)]
pub struct StandardInfoAttr {
    pub created: DateTime<Utc>,
    pub modified: DateTime<Utc>,
    pub mft_modified: DateTime<Utc>,
    pub accessed: DateTime<Utc>,
    pub file_flags: u32,
    pub max_version: u32,
    pub version: u32,
    pub class_id: u32,
    pub owner_id: u32,
    pub security_id: u32,
    pub quota: u64,
    pub usn: u64,
}

impl StandardInfoAttr {
    /// Parse a Standard Information attrbiute buffer.
    ///
    /// # Example
    ///
    /// Parse a raw buffer.
    ///
    /// ```
    /// use rustymft::attr_x10::StandardInfoAttr;
    /// # fn test_standard_information() {
    /// let attribute_buffer: &[u8] = &[
    /// 	0x2F,0x6D,0xB6,0x6F,0x0C,0x97,0xCE,0x01,0x56,0xCD,0x1A,0x75,0x73,0xB5,0xCE,0x01,
    /// 	0x56,0xCD,0x1A,0x75,0x73,0xB5,0xCE,0x01,0x56,0xCD,0x1A,0x75,0x73,0xB5,0xCE,0x01,
    /// 	0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    /// 	0x00,0x00,0x00,0x00,0xB0,0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
    /// 	0x68,0x58,0xA0,0x0A,0x02,0x00,0x00,0x00
    /// ];
    ///
    /// let attribute = StandardInfoAttr::new(attribute_buffer).unwrap();
    ///
    /// assert_eq!(attribute.created.0, 130207518909951279);
    /// assert_eq!(attribute.modified.0, 130240946730880342);
    /// assert_eq!(attribute.mft_modified.0, 130240946730880342);
    /// assert_eq!(attribute.accessed.0, 130240946730880342);
    /// assert_eq!(attribute.file_flags, 32);
    /// assert_eq!(attribute.max_version, 0);
    /// assert_eq!(attribute.version, 0);
    /// assert_eq!(attribute.class_id, 0);
    /// assert_eq!(attribute.security_id, 1456);
    /// assert_eq!(attribute.quota, 0);
    /// assert_eq!(attribute.usn, 8768215144);
    /// # }
    /// ```
    pub fn from_reader<R: Read>(reader: &mut R) -> Result<StandardInfoAttr> {
        trace!("StandardInfoAttr");
        let created = WinTimestamp::from_reader(reader)?.to_datetime();
        let modified = WinTimestamp::from_reader(reader)?.to_datetime();
        let mft_modified = WinTimestamp::from_reader(reader)?.to_datetime();
        let accessed = WinTimestamp::from_reader(reader)?.to_datetime();
        let file_flags = reader.read_u32::<LittleEndian>()?;
        let max_version = reader.read_u32::<LittleEndian>()?;
        let version = reader.read_u32::<LittleEndian>()?;
        let class_id = reader.read_u32::<LittleEndian>()?;
        let owner_id = reader.read_u32::<LittleEndian>()?;
        let security_id = reader.read_u32::<LittleEndian>()?;
        let quota = reader.read_u64::<LittleEndian>()?;
        let usn = reader.read_u64::<LittleEndian>()?;

        Ok(StandardInfoAttr {
            created,
            modified,
            mft_modified,
            accessed,
            file_flags,
            max_version,
            version,
            class_id,
            owner_id,
            security_id,
            quota,
            usn,
        })
    }
}