1use std::io::Read;
2
3use crate::{
4 result::{ZipError, ZipResult},
5 unstable::LittleEndianReadExt,
6};
7
8#[derive(Clone, Debug)]
17pub struct Ntfs {
18 mtime: u64,
19 atime: u64,
20 ctime: u64,
21}
22
23impl Ntfs {
24 pub fn try_from_reader<R>(reader: &mut R, len: u16) -> ZipResult<Self>
30 where
31 R: Read,
32 {
33 if len != 32 {
34 return Err(ZipError::UnsupportedArchive(
35 "NTFS extra field has an unsupported length",
36 ));
37 }
38
39 let _ = reader.read_u32_le()?;
41
42 let tag = reader.read_u16_le()?;
43 if tag != 0x0001 {
44 return Err(ZipError::UnsupportedArchive(
45 "NTFS extra field has an unsupported attribute tag",
46 ));
47 }
48 let size = reader.read_u16_le()?;
49 if size != 24 {
50 return Err(ZipError::UnsupportedArchive(
51 "NTFS extra field has an unsupported attribute size",
52 ));
53 }
54
55 let mtime = reader.read_u64_le()?;
56 let atime = reader.read_u64_le()?;
57 let ctime = reader.read_u64_le()?;
58 Ok(Self {
59 mtime,
60 atime,
61 ctime,
62 })
63 }
64
65 pub fn mtime(&self) -> u64 {
67 self.mtime
68 }
69
70 #[cfg(feature = "nt-time")]
72 pub fn modified_file_time(&self) -> nt_time::FileTime {
73 nt_time::FileTime::new(self.mtime)
74 }
75
76 pub fn atime(&self) -> u64 {
78 self.atime
79 }
80
81 #[cfg(feature = "nt-time")]
83 pub fn accessed_file_time(&self) -> nt_time::FileTime {
84 nt_time::FileTime::new(self.atime)
85 }
86
87 pub fn ctime(&self) -> u64 {
89 self.ctime
90 }
91
92 #[cfg(feature = "nt-time")]
94 pub fn created_file_time(&self) -> nt_time::FileTime {
95 nt_time::FileTime::new(self.ctime)
96 }
97}