smb_fscc/
query_file_info.rs

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