Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/windirstat/RustyMft.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatthew seyer <matthew.seyer@gmail.com>2017-11-07 08:27:22 +0300
committermatthew seyer <matthew.seyer@gmail.com>2017-11-07 08:27:22 +0300
commit659a3af5e432cef670290f690ec4ea33e3517822 (patch)
treec600c4200b5d8ed150f97263e9db2bc1855f45aa
parentf3207e646cee4195cb8255ab97d8dca5dd414998 (diff)
Parse attributes from buffer ref; Switched to doc-tests; Removed serialize derivative and added serialization method;HEADmaster
-rw-r--r--src/attr_x10.rs137
-rw-r--r--src/attr_x30.rs151
2 files changed, 180 insertions, 108 deletions
diff --git a/src/attr_x10.rs b/src/attr_x10.rs
index c3982bc..f012b21 100644
--- a/src/attr_x10.rs
+++ b/src/attr_x10.rs
@@ -1,11 +1,10 @@
use errors::{MftError};
use rwinstructs::timestamp::{WinTimestamp};
-use rwinstructs::serialize::{serialize_u64};
-use byteorder::{ReadBytesExt, LittleEndian};
-use std::io::Read;
-use std::mem;
+use byteorder::{ReadBytesExt,LittleEndian};
+use serde::ser::SerializeStruct;
+use serde::ser;
-#[derive(Serialize, Clone, Debug)]
+#[derive(Debug, Clone)]
pub struct StandardInfoAttr {
pub created: WinTimestamp,
pub modified: WinTimestamp,
@@ -17,63 +16,91 @@ pub struct StandardInfoAttr {
pub class_id: u32,
pub owner_id: u32,
pub security_id: u32,
- #[serde(serialize_with = "serialize_u64")]
pub quota: u64,
- #[serde(serialize_with = "serialize_u64")]
pub usn: u64
}
impl StandardInfoAttr {
- pub fn new<R: Read>(mut reader: R) -> Result<StandardInfoAttr,MftError> {
- let mut attribute: StandardInfoAttr = unsafe {
- mem::zeroed()
- };
+ /// 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 new(mut buffer: &[u8])->Result<StandardInfoAttr,MftError> {
+ let created = WinTimestamp(buffer.read_u64::<LittleEndian>()?);
+ let modified = WinTimestamp(buffer.read_u64::<LittleEndian>()?);
+ let mft_modified = WinTimestamp(buffer.read_u64::<LittleEndian>()?);
+ let accessed = WinTimestamp(buffer.read_u64::<LittleEndian>()?);
+ let file_flags = buffer.read_u32::<LittleEndian>()?;
+ let max_version = buffer.read_u32::<LittleEndian>()?;
+ let version = buffer.read_u32::<LittleEndian>()?;
+ let class_id = buffer.read_u32::<LittleEndian>()?;
+ let owner_id = buffer.read_u32::<LittleEndian>()?;
+ let security_id = buffer.read_u32::<LittleEndian>()?;
+ let quota = buffer.read_u64::<LittleEndian>()?;
+ let usn = buffer.read_u64::<LittleEndian>()?;
- attribute.created = WinTimestamp(reader.read_u64::<LittleEndian>()?);
- attribute.modified = WinTimestamp(reader.read_u64::<LittleEndian>()?);
- attribute.mft_modified = WinTimestamp(reader.read_u64::<LittleEndian>()?);
- attribute.accessed = WinTimestamp(reader.read_u64::<LittleEndian>()?);
- attribute.file_flags = reader.read_u32::<LittleEndian>()?;
- attribute.max_version = reader.read_u32::<LittleEndian>()?;
- attribute.version = reader.read_u32::<LittleEndian>()?;
- attribute.class_id = reader.read_u32::<LittleEndian>()?;
- attribute.owner_id = reader.read_u32::<LittleEndian>()?;
- attribute.security_id = reader.read_u32::<LittleEndian>()?;
- attribute.quota = reader.read_u64::<LittleEndian>()?;
- attribute.usn = reader.read_u64::<LittleEndian>()?;
-
- Ok(attribute)
+ Ok(
+ StandardInfoAttr {
+ created: created,
+ modified: modified,
+ mft_modified: mft_modified,
+ accessed: accessed,
+ file_flags: file_flags,
+ max_version: max_version,
+ version: version,
+ class_id: class_id,
+ owner_id: owner_id,
+ security_id: security_id,
+ quota: quota,
+ usn: usn
+ }
+ )
}
}
-#[cfg(test)]
-mod tests {
- use super::StandardInfoAttr;
-
- #[test]
- fn si_attribute_test_01() {
- 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 = match StandardInfoAttr::new(attribute_buffer) {
- Ok(attribute) => attribute,
- Err(error) => panic!(error)
- };
-
- 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);
+impl ser::Serialize for StandardInfoAttr {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where S: ser::Serializer
+ {
+ let mut state = serializer.serialize_struct("StandardInfoAttr", 5)?;
+ state.serialize_field("created", &format!("{}",&self.created))?;
+ state.serialize_field("modified", &format!("{}",&self.created))?;
+ state.serialize_field("mft_modified", &format!("{}",&self.created))?;
+ state.serialize_field("accessed", &format!("{}",&self.created))?;
+ state.serialize_field("file_flags", &self.file_flags)?;
+ state.serialize_field("max_version", &self.max_version)?;
+ state.serialize_field("class_id", &self.class_id)?;
+ state.serialize_field("owner_id", &self.owner_id)?;
+ state.serialize_field("security_id", &self.security_id)?;
+ state.serialize_field("quota", &format!("{}",&self.quota))?;
+ state.serialize_field("usn", &format!("{}",&self.usn))?;
+ state.end()
}
}
diff --git a/src/attr_x30.rs b/src/attr_x30.rs
index 9218156..2c722ac 100644
--- a/src/attr_x30.rs
+++ b/src/attr_x30.rs
@@ -1,23 +1,22 @@
use errors::{MftError};
use rwinstructs::timestamp::{WinTimestamp};
use rwinstructs::reference::{MftReference};
-use rwinstructs::serialize::{serialize_u64};
use byteorder::{ReadBytesExt, LittleEndian};
use encoding::{Encoding, DecoderTrap};
use encoding::all::UTF_16LE;
use std::io::Read;
use std::mem;
+use serde::ser::SerializeStruct;
+use serde::ser;
-#[derive(Serialize, Clone, Debug)]
+#[derive(Clone, Debug)]
pub struct FileNameAttr {
pub parent: MftReference,
pub created: WinTimestamp,
pub modified: WinTimestamp,
pub mft_modified: WinTimestamp,
pub accessed: WinTimestamp,
- #[serde(serialize_with = "serialize_u64")]
pub logical_size: u64,
- #[serde(serialize_with = "serialize_u64")]
pub physical_size: u64,
pub flags: u32,
pub reparse_value: u32,
@@ -27,27 +26,60 @@ pub struct FileNameAttr {
pub fullname: Option<String>
}
impl FileNameAttr {
- pub fn new<R: Read>(mut reader: R) -> Result<FileNameAttr,MftError> {
- let mut attribute: FileNameAttr = unsafe {
- mem::zeroed()
- };
-
- attribute.parent = MftReference(reader.read_u64::<LittleEndian>()?);
- attribute.created = WinTimestamp(reader.read_u64::<LittleEndian>()?);
- attribute.modified = WinTimestamp(reader.read_u64::<LittleEndian>()?);
- attribute.mft_modified = WinTimestamp(reader.read_u64::<LittleEndian>()?);
- attribute.accessed = WinTimestamp(reader.read_u64::<LittleEndian>()?);
- attribute.logical_size = reader.read_u64::<LittleEndian>()?;
- attribute.physical_size = reader.read_u64::<LittleEndian>()?;
- attribute.flags = reader.read_u32::<LittleEndian>()?;
- attribute.reparse_value = reader.read_u32::<LittleEndian>()?;
- attribute.name_length = reader.read_u8()?;
- attribute.namespace = reader.read_u8()?;
+ /// Parse a Filename attrbiute buffer.
+ ///
+ /// # Example
+ ///
+ /// Parse a raw buffer.
+ ///
+ /// ```
+ /// use rustymft::attr_x30::FileNameAttr;
+ /// # fn test_filename_attribute() {
+ /// let attribute_buffer: &[u8] = &[
+ /// 0x05,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0xD5,0x2D,0x48,0x58,0x43,0x5F,0xCE,0x01,
+ /// 0xD5,0x2D,0x48,0x58,0x43,0x5F,0xCE,0x01,0xD5,0x2D,0x48,0x58,0x43,0x5F,0xCE,0x01,
+ /// 0xD5,0x2D,0x48,0x58,0x43,0x5F,0xCE,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,
+ /// 0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ /// 0x08,0x03,0x24,0x00,0x4C,0x00,0x6F,0x00,0x67,0x00,0x46,0x00,0x69,0x00,0x6C,0x00,
+ /// 0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ /// ];
+ ///
+ /// let attribute = match FileNameAttr::new(attribute_buffer) {
+ /// Ok(attribute) => attribute,
+ /// Err(error) => panic!(error)
+ /// };
+ ///
+ /// assert_eq!(attribute.parent.0, 1407374883553285);
+ /// assert_eq!(attribute.created.0, 130146182088895957);
+ /// assert_eq!(attribute.modified.0, 130146182088895957);
+ /// assert_eq!(attribute.mft_modified.0, 130146182088895957);
+ /// assert_eq!(attribute.accessed.0, 130146182088895957);
+ /// assert_eq!(attribute.logical_size, 67108864);
+ /// assert_eq!(attribute.physical_size, 67108864);
+ /// assert_eq!(attribute.flags, 6);
+ /// assert_eq!(attribute.reparse_value, 0);
+ /// assert_eq!(attribute.name_length, 8);
+ /// assert_eq!(attribute.namespace, 3);
+ /// assert_eq!(attribute.name, "$LogFile");
+ /// # }
+ /// ```
+ pub fn new(mut buffer: &[u8]) -> Result<FileNameAttr,MftError> {
+ let parent = MftReference(buffer.read_u64::<LittleEndian>()?);
+ let created = WinTimestamp(buffer.read_u64::<LittleEndian>()?);
+ let modified = WinTimestamp(buffer.read_u64::<LittleEndian>()?);
+ let mft_modified = WinTimestamp(buffer.read_u64::<LittleEndian>()?);
+ let accessed = WinTimestamp(buffer.read_u64::<LittleEndian>()?);
+ let logical_size = buffer.read_u64::<LittleEndian>()?;
+ let physical_size = buffer.read_u64::<LittleEndian>()?;
+ let flags = buffer.read_u32::<LittleEndian>()?;
+ let reparse_value = buffer.read_u32::<LittleEndian>()?;
+ let name_length = buffer.read_u8()?;
+ let namespace = buffer.read_u8()?;
- let mut name_buffer = vec![0; (attribute.name_length as usize * 2) as usize];
- reader.read_exact(&mut name_buffer)?;
+ let mut name_buffer = vec![0; (name_length as usize * 2) as usize];
+ buffer.read_exact(&mut name_buffer)?;
- attribute.name = match UTF_16LE.decode(&name_buffer,DecoderTrap::Ignore){
+ let name = match UTF_16LE.decode(&name_buffer,DecoderTrap::Ignore){
Ok(filename) => filename,
Err(error) => return Err(
MftError::decode_error(
@@ -56,41 +88,54 @@ impl FileNameAttr {
)
};
- Ok(attribute)
+ let fullname = None;
+
+ Ok(
+ FileNameAttr {
+ parent: parent,
+ created: created,
+ modified: modified,
+ mft_modified: mft_modified,
+ accessed: accessed,
+ logical_size: logical_size,
+ physical_size: physical_size,
+ flags: flags,
+ reparse_value: reparse_value,
+ name_length: name_length,
+ namespace: namespace,
+ name: name,
+ fullname: fullname
+ }
+ )
}
}
-#[cfg(test)]
-mod tests {
- use super::FileNameAttr;
+impl ser::Serialize for FileNameAttr {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where S: ser::Serializer
+ {
+ let mut state = serializer.serialize_struct("FileNameAttr", 13)?;
- #[test]
- fn fn_attribute_test_01() {
- let attribute_buffer: &[u8] = &[
- 0x05,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0xD5,0x2D,0x48,0x58,0x43,0x5F,0xCE,0x01,
- 0xD5,0x2D,0x48,0x58,0x43,0x5F,0xCE,0x01,0xD5,0x2D,0x48,0x58,0x43,0x5F,0xCE,0x01,
- 0xD5,0x2D,0x48,0x58,0x43,0x5F,0xCE,0x01,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,
- 0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
- 0x08,0x03,0x24,0x00,0x4C,0x00,0x6F,0x00,0x67,0x00,0x46,0x00,0x69,0x00,0x6C,0x00,
- 0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00
- ];
+ state.serialize_field("parent",&self.parent)?;
+ state.serialize_field("created", &format!("{}",&self.created))?;
+ state.serialize_field("modified", &format!("{}",&self.modified))?;
+ state.serialize_field("mft_modified", &format!("{}",&self.mft_modified))?;
+ state.serialize_field("accessed", &self.accessed)?;
+ state.serialize_field("logical_size", &self.logical_size)?;
+ state.serialize_field("physical_size", &self.physical_size)?;
+ state.serialize_field("flags", &self.flags)?;
+ state.serialize_field("reparse_value", &self.reparse_value)?;
+ state.serialize_field("name_length", &self.name_length)?;
+ state.serialize_field("namespace", &self.namespace)?;
+ state.serialize_field("name", &format!("{}",&self.name))?;
- let attribute = match FileNameAttr::new(attribute_buffer) {
- Ok(attribute) => attribute,
- Err(error) => panic!(error)
- };
+ match self.fullname {
+ Some(ref fullname) => {
+ state.serialize_field("fullname", &format!("{}",&fullname))?;
+ },
+ None => {}
+ }
- assert_eq!(attribute.parent.0, 1407374883553285);
- assert_eq!(attribute.created.0, 130146182088895957);
- assert_eq!(attribute.modified.0, 130146182088895957);
- assert_eq!(attribute.mft_modified.0, 130146182088895957);
- assert_eq!(attribute.accessed.0, 130146182088895957);
- assert_eq!(attribute.logical_size, 67108864);
- assert_eq!(attribute.physical_size, 67108864);
- assert_eq!(attribute.flags, 6);
- assert_eq!(attribute.reparse_value, 0);
- assert_eq!(attribute.name_length, 8);
- assert_eq!(attribute.namespace, 3);
- assert_eq!(attribute.name, "$LogFile");
+ state.end()
}
}