smb_fscc/
query_file_info.rs

1use std::ops::Deref;
2
3use binrw::{NullString, io::TakeSeekExt, prelude::*};
4
5use super::{
6    ChainedItemList, FileAccessMask, FileAttributes, FileBasicInformation, FileFullEaInformation,
7    FileModeInformation, FileNameInformation, FilePipeInformation, FilePositionInformation,
8};
9use crate::file_info_classes;
10use smb_dtyp::binrw_util::prelude::{Boolean, FileTime, SizedWideString};
11
12file_info_classes! {
13    pub QueryFileInfo {
14        pub Access = 8,
15        pub Alignment = 17,
16        pub All = 18,
17        pub AlternateName = 21,
18        pub AttributeTag = 35,
19        pub Basic = 4,
20        pub Compression = 28,
21        pub Ea = 7,
22        pub FullEa = 15,
23        pub Id = 59,
24        pub Internal = 6,
25        pub Mode = 16,
26        pub NetworkOpen = 34,
27        pub NormalizedName = 48,
28        pub Pipe = 23,
29        pub PipeLocal = 24,
30        pub PipeRemote  = 25,
31        pub Position = 14,
32        pub Standard = 5,
33        pub Stream = 22,
34    }, Read
35}
36
37/// A [FileFullEaInformation](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/0eb94f48-6aac-41df-a878-79f4dcfd8989)
38/// structure to be used when querying for extended attributes. You may use [super::SetFileFullEaInformation] for setting.
39pub type QueryFileFullEaInformation = FileFullEaInformation;
40
41pub type FileStreamInformation = ChainedItemList<FileStreamInformationInner>;
42
43#[binrw::binrw]
44#[derive(Debug, PartialEq, Eq)]
45pub struct FileAccessInformation {
46    pub access_flags: FileAccessMask,
47}
48
49#[binrw::binrw]
50#[derive(Debug, PartialEq, Eq)]
51pub struct FileAllInformation {
52    pub basic: FileBasicInformation,
53    pub standard: FileStandardInformation,
54    pub internal: FileInternalInformation,
55    pub ea: FileEaInformation,
56    pub access: FileAccessInformation,
57    pub position: FilePositionInformation,
58    pub mode: FileModeInformation,
59    pub alignment: FileAlignmentInformation,
60    pub name: FileNameInformation,
61}
62
63#[binrw::binrw]
64#[derive(Debug, PartialEq, Eq)]
65#[brw(repr(u32))]
66pub enum FileAlignmentInformation {
67    Byte = 0,
68    Word = 1,
69    Long = 3,
70    Quad = 7,
71    Octa = 0xf,
72    _32Byte = 0x1f,
73    _64Byte = 0x3f,
74    _128Byte = 0x7f,
75    _256Byte = 0xff,
76    _512Byte = 0x1ff,
77}
78
79#[binrw::binrw]
80#[derive(Debug, PartialEq, Eq)]
81pub struct FileAlternateNameInformation {
82    inner: FileNameInformation,
83}
84
85impl Deref for FileAlternateNameInformation {
86    type Target = FileNameInformation;
87
88    fn deref(&self) -> &Self::Target {
89        &self.inner
90    }
91}
92
93#[binrw::binrw]
94#[derive(Debug, PartialEq, Eq)]
95pub struct FileAttributeTagInformation {
96    pub file_attributes: u32,
97    pub reparse_tag: u32,
98}
99
100#[binrw::binrw]
101#[derive(Debug, PartialEq, Eq)]
102pub struct FileCompressionInformation {
103    pub compressed_file_size: u64,
104    pub compression_format: FileCompressionFormat,
105    pub compression_unit: u8,
106    pub chunk_shift: u8,
107    pub cluster_shift: u8,
108
109    #[bw(calc = [0; 3])]
110    _reserved: [u8; 3],
111}
112
113#[binrw::binrw]
114#[derive(Debug, PartialEq, Eq)]
115#[brw(repr(u16))]
116pub enum FileCompressionFormat {
117    None = 0,
118    Lznt1 = 2,
119}
120
121#[binrw::binrw]
122#[derive(Debug, PartialEq, Eq)]
123pub struct FileEaInformation {
124    pub ea_size: u32,
125}
126
127#[binrw::binrw]
128#[derive(Debug, PartialEq, Eq)]
129pub struct FileIdInformation {
130    pub volume_serial_number: u64,
131    pub file_id: u128,
132}
133
134#[binrw::binrw]
135#[derive(Debug, PartialEq, Eq)]
136pub struct FileInternalInformation {
137    pub index_number: u64,
138}
139
140#[binrw::binrw]
141#[derive(Debug, PartialEq, Eq)]
142pub struct FileNetworkOpenInformation {
143    pub creation_time: FileTime,
144    pub last_access_time: FileTime,
145    pub last_write_time: FileTime,
146    pub change_time: FileTime,
147    pub allocation_size: u64,
148    pub end_of_file: u64,
149    pub file_attributes: FileAttributes,
150    #[bw(calc = 0)]
151    _reserved: u32,
152}
153
154#[binrw::binrw]
155#[derive(Debug, PartialEq, Eq)]
156pub struct FileNormalizedNameInformation {
157    inner: FileNameInformation,
158}
159
160impl Deref for FileNormalizedNameInformation {
161    type Target = FileNameInformation;
162
163    fn deref(&self) -> &Self::Target {
164        &self.inner
165    }
166}
167
168#[binrw::binrw]
169#[derive(Debug, PartialEq, Eq)]
170pub struct FilePipeLocalInformation {
171    pub named_pipe_type: NamedPipeType,
172    pub named_pipe_configuration: NamedPipeConfiguration,
173    pub maximum_instances: u32,
174    pub current_instances: u32,
175    pub inbound_quota: u32,
176    pub outbound_quota: u32,
177    pub write_quota: u32,
178    pub named_pipe_state: NamedPipeState,
179    pub named_pipe_end: NamedPipeEnd,
180}
181
182#[binrw::binrw]
183#[derive(Debug, PartialEq, Eq)]
184#[brw(repr(u32))]
185pub enum NamedPipeType {
186    ByteStream = 0,
187    Message = 1,
188}
189
190#[binrw::binrw]
191#[derive(Debug, PartialEq, Eq)]
192#[brw(repr(u32))]
193pub enum NamedPipeConfiguration {
194    Inbound = 0,
195    Outbound = 1,
196    FullDuplex = 2,
197}
198
199#[binrw::binrw]
200#[derive(Debug, PartialEq, Eq)]
201#[brw(repr(u32))]
202pub enum NamedPipeState {
203    Disconnected = 1,
204    Listening = 2,
205    Connected = 3,
206    Closing = 4,
207}
208
209#[binrw::binrw]
210#[derive(Debug, PartialEq, Eq)]
211#[brw(repr(u32))]
212pub enum NamedPipeEnd {
213    Client = 0,
214    Server = 1,
215}
216
217#[binrw::binrw]
218#[derive(Debug, PartialEq, Eq)]
219pub struct FilePipeRemoteInformation {
220    pub collect_data_time: FileTime,
221    pub maximum_collection_count: u32,
222}
223
224#[binrw::binrw]
225#[derive(Debug, PartialEq, Eq)]
226pub struct FileStandardInformation {
227    pub allocation_size: u64,
228    pub end_of_file: u64,
229    pub number_of_links: u32,
230    pub delete_pending: Boolean,
231    pub directory: Boolean,
232    #[bw(calc = 0)]
233    #[br(assert(reserved == 0))]
234    reserved: u16,
235}
236
237#[binrw::binrw]
238#[derive(Debug, PartialEq, Eq)]
239pub struct FileStreamInformationInner {
240    #[bw(try_calc = stream_name.size().try_into())]
241    stream_name_length: u32,
242    pub stream_size: u64,
243    pub stream_allocation_size: u64,
244    #[br(args(stream_name_length as u64))]
245    pub stream_name: SizedWideString,
246}
247
248#[binrw::binrw]
249#[derive(Debug, PartialEq, Eq)]
250#[bw(import(has_next: bool))]
251pub struct FileGetEaInformation {
252    #[bw(try_calc = ea_name.len().try_into())]
253    ea_name_length: u8,
254    #[br(map_stream = |s| s.take_seek(ea_name_length as u64))]
255    pub ea_name: NullString,
256}
257
258impl FileGetEaInformation {
259    pub fn new<S: Into<String>>(name: S) -> Self {
260        Self {
261            ea_name: NullString::from(name.into()),
262        }
263    }
264}