smb_fscc/
common_info.rs

1//! File Information Classes for getting/setting file information, and common structs.
2//!
3//! See [crate::QueryFileInfo] and [crate::SetFileInfo] enums.
4//!
5//! [MS-FSCC 2.4](<https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/4718fc40-e539-4014-8e33-b675af74e3e1>)
6
7#![allow(clippy::identity_op)]
8
9use std::ops::Deref;
10
11use binrw::{NullString, prelude::*};
12use modular_bitfield::prelude::*;
13
14use smb_dtyp::binrw_util::prelude::*;
15
16use crate::{ChainedItemList, FileAttributes};
17
18/// Query or Set file information.
19///
20/// [MS-FSCC 2.4.7](<https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/16023025-8a78-492f-8b96-c873b042ac50>)
21#[binrw::binrw]
22#[derive(Debug, PartialEq, Eq)]
23pub struct FileBasicInformation {
24    /// The time when the file was created.
25    pub creation_time: FileTime,
26    /// The time when the file was last accessed.
27    pub last_access_time: FileTime,
28    /// The time when data was last written to the file.
29    pub last_write_time: FileTime,
30    /// The time when the file was last changed.
31    pub change_time: FileTime,
32    /// The file attributes.
33    pub file_attributes: FileAttributes,
34    #[bw(calc = 0)]
35    _reserved: u32,
36}
37
38/// Query or Set extended attribute (EA) information for a file.
39///
40/// [MS-FSCC 2.4.16](<https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/0eb94f48-6aac-41df-a878-79f4dcfd8989>)
41#[binrw::binrw]
42#[derive(Debug, PartialEq, Eq)]
43pub struct FileFullEaInformationInner {
44    /// Can contain zero or more of the following flag values. Unused bit fields should be set to 0.
45    pub flags: EaFlags,
46    #[bw(try_calc = ea_name.len().try_into())]
47    ea_name_length: u8,
48    #[bw(calc = ea_value.len() as u16)]
49    ea_value_length: u16,
50    /// The name of the extended attribute. This field is not null-terminated.
51    #[br(assert(ea_name.len() == ea_name_length as usize))]
52    pub ea_name: NullString,
53    /// The value of the extended attribute. This field can be zero bytes in length.
54    #[br(count = ea_value_length)]
55    pub ea_value: Vec<u8>,
56}
57
58/// Extended Attribute (EA) Flags
59///
60/// See [`FileFullEaInformationInner`]
61#[bitfield]
62#[derive(BinWrite, BinRead, Debug, Default, Clone, Copy, PartialEq, Eq)]
63#[bw(map = |&x| Self::into_bytes(x))]
64#[br(map = Self::from_bytes)]
65#[repr(u8)]
66pub struct EaFlags {
67    #[skip]
68    __: B7,
69    /// If this flag is set, the file to which the EA belongs cannot be interpreted by applications that do not understand EAs.
70    pub file_need_ea: bool,
71}
72
73pub type FileFullEaInformation = ChainedItemList<FileFullEaInformationInner, 4>;
74
75/// Query or Set file mode information.
76///
77/// [MS-FSCC 2.4.31](<https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/52df7798-8330-474b-ac31-9afe8075640c>)
78#[bitfield]
79#[derive(BinWrite, BinRead, Debug, Default, Clone, Copy, PartialEq, Eq)]
80#[bw(map = |&x| Self::into_bytes(x))]
81#[br(map = Self::from_bytes)]
82pub struct FileModeInformation {
83    #[skip]
84    __: bool,
85    /// When set, system caching is not performed on the file.
86    pub write_through: bool,
87    /// When set, all access to the file is sequential.
88    pub sequential_access: bool,
89    /// When set, the file cannot be cached or buffered in a driver's internal buffers.
90    pub no_intermediate_buffering: bool,
91
92    /// When set, all operations on the file are performed synchronously. Waits in the system to synchronize I/O queuing and completion are alertable.
93    pub synchronous_io_alert: bool,
94    /// When set, all operations on the file are performed synchronously. Waits in the system to synchronize I/O queuing and completion are not alertable.
95    pub synchronous_io_non_alert: bool,
96    #[skip]
97    __: B6,
98
99    /// When set, the file will be deleted when the last handle to the file is closed.
100    pub delete_on_close: bool,
101    #[skip]
102    __: B19,
103}
104
105/// Query or Set named pipe information.
106///
107/// [MS-FSCC 2.4.37](<https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/cd805dd2-9248-4024-ac0f-b87a702dd366>)
108#[binrw::binrw]
109#[derive(Debug, PartialEq, Eq)]
110pub struct FilePipeInformation {
111    /// The named pipe read mode.
112    pub read_mode: PipeReadMode,
113    /// The named pipe completion mode.
114    pub completion_mode: PipeCompletionMode,
115}
116
117/// Named pipe read mode values.
118#[binrw::binrw]
119#[derive(Debug, PartialEq, Eq)]
120#[brw(repr(u32))]
121pub enum PipeReadMode {
122    /// Data is read from the pipe as a stream of bytes.
123    Stream = 0,
124    /// Data is read from the pipe as a stream of messages.
125    Message = 1,
126}
127
128/// Named pipe completion mode values.
129#[binrw::binrw]
130#[derive(Debug, PartialEq, Eq)]
131#[brw(repr(u32))]
132pub enum PipeCompletionMode {
133    /// Blocking mode is enabled. When the pipe handle is specified in a call to the ReadFile or WriteFile function, the operations are not completed until there is data to read or all data is written.
134    Queue = 0,
135    /// Nonblocking mode is enabled. When the pipe handle is specified in a call to the ReadFile or WriteFile function, the operations complete immediately.
136    Complete = 1,
137}
138
139/// Query or Set the current byte offset of the file pointer.
140///
141/// [MS-FSCC 2.4.40](<https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/e3ce4a39-327e-495c-99b6-6b61606b6f16>)
142#[binrw::binrw]
143#[derive(Debug, PartialEq, Eq)]
144pub struct FilePositionInformation {
145    /// The byte offset of the file pointer from the beginning of the file.
146    pub current_byte_offset: u64,
147}
148
149/// Query the name of a file.
150///
151/// [MS-FSCC 2.4.32](<https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/cb30e415-54c5-4483-a346-822ea90e1e89>)
152#[binrw::binrw]
153#[derive(Debug, PartialEq, Eq)]
154pub struct FileNameInformation {
155    #[bw(try_calc = file_name.size().try_into())]
156    file_name_length: u32,
157    /// The full path name of the file.
158    #[br(args { size: SizedStringSize::bytes(file_name_length)})]
159    pub file_name: SizedWideString,
160}
161
162impl Deref for FileNameInformation {
163    type Target = SizedWideString;
164
165    fn deref(&self) -> &Self::Target {
166        &self.file_name
167    }
168}
169
170impl From<SizedWideString> for FileNameInformation {
171    fn from(value: SizedWideString) -> Self {
172        Self { file_name: value }
173    }
174}
175
176impl From<&str> for FileNameInformation {
177    fn from(value: &str) -> Self {
178        Self {
179            file_name: SizedWideString::from(value),
180        }
181    }
182}
183
184/// Reparse Tag Values
185///
186/// Each reparse point has a reparse tag.
187/// The reparse tag uniquely identifies the owner of that reparse point.
188/// The owner is the implementer of the file system filter driver associated with a reparse tag.
189///
190/// [MS-FSCC 2.1.2.1](<https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/c8e77b37-3909-4fe6-a4ea-2b9d423b1ee4>):
191#[binrw::binrw]
192#[derive(Debug, PartialEq, Eq)]
193#[repr(u32)]
194#[brw(repr(u32))]
195pub enum ReparseTag {
196    /// Reserved reparse tag value.
197    ReservedZero = 0x00000000,
198
199    /// Reserved reparse tag value.
200    ReservedOne = 0x00000001,
201
202    /// Reserved reparse tag value.
203    ReservedTwo = 0x00000002,
204
205    /// Used for mount point support, specified in section 2.1.2.5.
206    MountPoint = 0xA0000003,
207
208    /// Obsolete. Used by legacy Hierarchical Storage Manager Product.
209    HSM = 0xC0000004,
210
211    /// Home server drive extender.<3>
212    DriveExtender = 0x80000005,
213
214    /// Obsolete. Used by legacy Hierarchical Storage Manager Product.
215    HSM2 = 0x80000006,
216
217    /// Used by single-instance storage (SIS) filter driver. Server-side interpretation only, not meaningful over the wire.
218    SIS = 0x80000007,
219
220    /// Used by the WIM Mount filter. Server-side interpretation only, not meaningful over the wire.
221    WIM = 0x80000008,
222
223    /// Obsolete. Used by Clustered Shared Volumes (CSV) version 1 in Windows Server 2008 R2 operating system. Server-side interpretation only, not meaningful over the wire.
224    CSV = 0x80000009,
225
226    /// Used by the DFS filter. The DFS is described in the Distributed File System (DFS): Referral Protocol Specification [MS-DFSC]. Server-side interpretation only, not meaningful over the wire.
227    DFS = 0x8000000A,
228
229    /// Used by filter manager test harness.<4>
230    FilterManager = 0x8000000B,
231
232    /// Used for symbolic link support. See section 2.1.2.4.
233    Symlink = 0xA000000C,
234
235    /// Used by Microsoft Internet Information Services (IIS) caching. Server-side interpretation only, not meaningful over the wire.
236    IISCache = 0xA0000010,
237
238    /// Used by the DFS filter. The DFS is described in [MS-DFSC]. Server-side interpretation only, not meaningful over the wire.
239    DFSR = 0x80000012,
240
241    /// Used by the Data Deduplication (Dedup) filter. Server-side interpretation only, not meaningful over the wire.
242    Dedup = 0x80000013,
243
244    /// Not used.
245    Appxstrm = 0xC0000014,
246
247    /// Used by the Network File System (NFS) component. Server-side interpretation only, not meaningful over the wire.
248    NFS = 0x80000014,
249
250    /// Obsolete. Used by Windows Shell for legacy placeholder files in Windows 8.1. Server-side interpretation only, not meaningful over the wire.
251    FilePlaceholder = 0x80000015,
252
253    /// Used by the Dynamic File filter. Server-side interpretation only, not meaningful over the wire.
254    DFM = 0x80000016,
255
256    /// Used by the Windows Overlay filter, for either WIMBoot or single-file compression. Server-side interpretation only, not meaningful over the wire.
257    WOF = 0x80000017,
258
259    /// Used by the Windows Container Isolation filter. Server-side interpretation only, not meaningful over the wire.
260    WCI = 0x80000018,
261
262    /// Used by the Windows Container Isolation filter. Server-side interpretation only, not meaningful over the wire.
263    Wci1 = 0x90001018,
264
265    /// Used by NPFS to indicate a named pipe symbolic link from a server silo into the host silo. Server-side interpretation only, not meaningful over the wire.
266    GlobalReparse = 0xA0000019,
267
268    /// Used by the Cloud Files filter, for files managed by a sync engine such as Microsoft OneDrive. Server-side interpretation only, not meaningful over the wire.
269    Cloud = 0x9000001A,
270
271    /// Used by the Cloud Files filter, for files managed by a sync engine such as OneDrive. Server-side interpretation only, not meaningful over the wire.
272    Cloud1 = 0x9000101A,
273
274    /// Used by the Cloud Files filter, for files managed by a sync engine such as OneDrive. Server-side interpretation only, not meaningful over the wire.
275    Cloud2 = 0x9000201A,
276
277    /// Used by the Cloud Files filter, for files managed by a sync engine such as OneDrive. Server-side interpretation only, not meaningful over the wire.
278    Cloud3 = 0x9000301A,
279
280    /// Used by the Cloud Files filter, for files managed by a sync engine such as OneDrive. Server-side interpretation only, not meaningful over the wire.
281    Cloud4 = 0x9000401A,
282
283    /// Used by the Cloud Files filter, for files managed by a sync engine such as OneDrive. Server-side interpretation only, not meaningful over the wire.
284    Cloud5 = 0x9000501A,
285
286    /// Used by the Cloud Files filter, for files managed by a sync engine such as OneDrive. Server-side interpretation only, not meaningful over the wire.
287    Cloud6 = 0x9000601A,
288
289    /// Used by the Cloud Files filter, for files managed by a sync engine such as OneDrive. Server-side interpretation only, not meaningful over the wire.
290    Cloud7 = 0x9000701A,
291
292    /// Used by the Cloud Files filter, for files managed by a sync engine such as OneDrive. Server-side interpretation only, not meaningful over the wire.
293    Cloud8 = 0x9000801A,
294
295    /// Used by the Cloud Files filter, for files managed by a sync engine such as OneDrive. Server-side interpretation only, not meaningful over the wire.
296    Cloud9 = 0x9000901A,
297
298    /// Used by the Cloud Files filter, for files managed by a sync engine such as OneDrive. Server-side interpretation only, not meaningful over the wire.
299    CloudA = 0x9000A01A,
300
301    /// Used by the Cloud Files filter, for files managed by a sync engine such as OneDrive. Server-side interpretation only, not meaningful over the wire.
302    CloudB = 0x9000B01A,
303
304    /// Used by the Cloud Files filter, for files managed by a sync engine such as OneDrive. Server-side interpretation only, not meaningful over the wire.
305    CloudC = 0x9000C01A,
306
307    /// Used by the Cloud Files filter, for files managed by a sync engine such as OneDrive. Server-side interpretation only, not meaningful over the wire.
308    CloudD = 0x9000D01A,
309
310    /// Used by the Cloud Files filter, for files managed by a sync engine such as OneDrive. Server-side interpretation only, not meaningful over the wire.
311    CloudE = 0x9000E01A,
312
313    /// Used by the Cloud Files filter, for files managed by a sync engine such as OneDrive. Server-side interpretation only, not meaningful over the wire.
314    CloudF = 0x9000F01A,
315
316    /// Used by Universal Windows Platform (UWP) packages to encode information that allows the application to be launched by CreateProcess. Server-side interpretation only, not meaningful over the wire.
317    Appexeclink = 0x8000001B,
318
319    /// Used by the Windows Projected File System filter, for files managed by a user mode provider such as VFS for Git. Server-side interpretation only, not meaningful over the wire.
320    Projfs = 0x9000001C,
321
322    /// Used by the Windows Subsystem for Linux (WSL) to represent a UNIX symbolic link. Server-side interpretation only, not meaningful over the wire.
323    LxSymlink = 0xA000001D,
324
325    /// Used by the Azure File Sync (AFS) filter. Server-side interpretation only, not meaningful over the wire.
326    StorageSync = 0x8000001E,
327
328    /// Used by the Azure File Sync (AFS) filter for folder. Server-side interpretation only, not meaningful over the wire.
329    StorageSyncFolder = 0x90000027,
330
331    /// Used by the Windows Container Isolation filter. Server-side interpretation only, not meaningful over the wire.
332    WciTombstone = 0xA000001F,
333
334    /// Used by the Windows Container Isolation filter. Server-side interpretation only, not meaningful over the wire.
335    Unhandled = 0x80000020,
336
337    /// Not used.
338    Onedrive = 0x80000021,
339
340    /// Used by the Windows Projected File System filter, for files managed by a user mode provider such as VFS for Git. Server-side interpretation only, not meaningful over the wire.
341    ProjfsTombstone = 0xA0000022,
342
343    /// Used by the Windows Subsystem for Linux (WSL) to represent a UNIX domain socket. Server-side interpretation only, not meaningful over the wire.
344    AfUnix = 0x80000023,
345
346    /// Used by the Windows Subsystem for Linux (WSL) to represent a UNIX FIFO (named pipe). Server-side interpretation only, not meaningful over the wire.
347    LxFifo = 0x80000024,
348
349    /// Used by the Windows Subsystem for Linux (WSL) to represent a UNIX character special file. Server-side interpretation only, not meaningful over the wire.
350    LxChr = 0x80000025,
351
352    /// Used by the Windows Subsystem for Linux (WSL) to represent a UNIX block special file. Server-side interpretation only, not meaningful over the wire.
353    LxBlk = 0x80000026,
354
355    /// Used by the Windows Container Isolation filter. Server-side interpretation only, not meaningful over the wire.
356    WciLink = 0xA0000027,
357
358    /// Used by the Windows Container Isolation filter. Server-side interpretation only, not meaningful over the wire.
359    WciLink1 = 0xA0001027,
360}
361
362#[cfg(test)]
363mod tests {
364    use super::*;
365    use smb_tests::*;
366
367    test_binrw! {
368        FileFullEaInformation: FileFullEaInformation::from(vec![
369            FileFullEaInformationInner {
370                flags: EaFlags::new(),
371                ea_name: "$CI.CATALOGHINT".into(),
372                ea_value: vec![0x1, 0x0, 0x63, 0x0, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2d, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x2d, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2d, 0x44, 0x65, 0x73, 0x6b, 0x74, 0x6f, 0x70, 0x2d, 0x52, 0x65, 0x71, 0x75, 0x69, 0x72, 0x65, 0x64, 0x2d, 0x50, 0x61, 0x63, 0x6b, 0x61, 0x67, 0x65, 0x30, 0x34, 0x31, 0x30, 0x32, 0x31, 0x7e, 0x33, 0x31, 0x62, 0x66, 0x33, 0x38, 0x35, 0x36, 0x61, 0x64, 0x33, 0x36, 0x34, 0x65, 0x33, 0x35, 0x7e, 0x61, 0x72, 0x6d, 0x36, 0x34, 0x7e, 0x7e, 0x31, 0x30, 0x2e, 0x30, 0x2e, 0x32, 0x32, 0x36, 0x32, 0x31, 0x2e, 0x35, 0x31, 0x38, 0x35, 0x2e, 0x63, 0x61, 0x74]
373            },
374            FileFullEaInformationInner {
375                flags: EaFlags::new(),
376                ea_name: "SKTEXT".into(),
377                ea_value: vec![0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x6e, 0x6f, 0x74, 0x20, 0x72, 0x65, 0x61, 0x6c, 0x6c, 0x79, 0x20, 0x74, 0x68, 0x65, 0x20, 0x53, 0x4b, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x6a, 0x75, 0x73, 0x74, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x66, 0x61, 0x6b, 0x65, 0x20, 0x74, 0x6f, 0x20, 0x68, 0x61, 0x76, 0x65, 0x20, 0x73, 0x6f, 0x6d, 0x65, 0x20, 0x66, 0x75, 0x6e, 0x0]
378            },
379        ]) => "80000000000f67002443492e434154414c4f4748494e5400010063004d6963726f736f66742d57696e646f77732d436c69656e742d4465736b746f702d52657175697265642d5061636b6167653034313032317e333162663338353661643336346533357e61726d36347e7e31302e302e32323632312e353138352e636174000000000000064100534b544558540054686973206973206e6f74207265616c6c792074686520534b2c206974206973206a75737420736f6d652066616b6520746f206861766520736f6d652066756e00"
380    }
381
382    test_binrw! {
383        struct FilePipeInformation {
384            read_mode: PipeReadMode::Message,
385            completion_mode: PipeCompletionMode::Queue,
386        } => "0100000000000000"
387    }
388}