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