1use binrw::prelude::*;
4use modular_bitfield::prelude::*;
5
6#[smb_message_binrw]
7#[derive(Copy, Clone)]
8#[brw(repr(u8))]
9pub enum InfoType {
10 File = 0x1,
11 FileSystem = 0x2,
12 Security = 0x3,
13 Quota = 0x4,
14}
15
16#[smb_dtyp::mbitfield]
17pub struct AdditionalInfo {
18 pub owner_security_information: bool,
19 pub group_security_information: bool,
20 pub dacl_security_information: bool,
21 pub sacl_security_information: bool,
22
23 pub label_security_information: bool,
24 pub attribute_security_information: bool,
25 pub scope_security_information: bool,
26
27 #[skip]
28 __: B9,
29 pub backup_security_information: bool,
30 #[skip]
31 __: B15,
32}
33
34macro_rules! query_info_data {
44 ($name:ident $($info_type:ident: $content:ty, )+) => {
45 pastey::paste! {
46 #[allow(unused_imports)]
47 use binrw::prelude::*;
48 #[allow(unused_imports)]
49 use binrw::meta::WriteEndian;
50
51 #[doc = concat!("Enum to hold the different info types for ", stringify!($name),
52 ", that are used within SMB requests for querying or setting information.")]
53 #[binrw::binrw]
54 #[derive(Debug, PartialEq, Eq)]
55 #[brw(little)]
56 #[br(import(info_type: InfoType))]
57 pub enum $name {
58 $(
59 #[br(pre_assert(info_type == InfoType::$info_type))]
60 $info_type($content),
61 )+
62 }
63
64 impl $name {
65 $(
67 #[doc = concat!("Get the inner content as [`", stringify!($content), "`].")]
68 pub fn [<as_ $info_type:lower>](self) -> Result<$content, $crate::SmbMsgError> {
69 match self {
70 $name::$info_type(data) => Ok(data),
71 _ => Err($crate::SmbMsgError::UnexpectedContent {
72 expected: stringify!($info_type),
73 actual: self.name(),
74 }),
75 }
76 }
77 )+
78
79 pub fn info_type(&self) -> InfoType {
81 match self {
82 $(
83 $name::$info_type(_) => InfoType::$info_type,
84 )+
85 }
86 }
87
88 pub fn name(&self) -> &'static str {
90 match self {
91 $(
92 $name::$info_type(_) => stringify!($info_type),
93 )+
94 }
95 }
96 }
97
98 $(
100 impl From<$content> for $name {
101 fn from(value: $content) -> Self {
102 $name::$info_type(value)
103 }
104 }
105 )+
106
107 #[binrw::binrw]
108 #[derive(Debug, PartialEq, Eq)]
109 pub struct [<Raw $name>]<T>
110 where
111 T: Sized,
112 {
113 #[br(parse_with = binrw::helpers::until_eof)]
114 data: Vec<u8>,
115
116 phantom: std::marker::PhantomData<T>,
117 }
118
119
120 impl<T> [<Raw $name>]<T>
121 where
122 T: Sized,
123 {
124 pub fn data(&self) -> &[u8] {
125 &self.data
126 }
127 }
128
129 impl<T> [<Raw $name>]<T>
130 where
131 T: Sized,
132 T: BinRead<Args<'static> = (T::Class,)> + FileInfoType,
133 {
134 pub fn parse(&self, class: T::Class) -> Result<T, $crate::SmbMsgError> {
136 let mut cursor = std::io::Cursor::new(&self.data);
137 let value = T::read_le_args(&mut cursor, (class,))?;
138 Ok(value)
139 }
140 }
141
142 impl<T> From<T> for [<Raw $name>]<T>
143 where
144 for<'a> T: BinWrite<Args<'a> = ()>,
145 {
146 fn from(value: T) -> Self {
147 let mut cursor = std::io::Cursor::new(Vec::new());
148 value.write_le(&mut cursor).unwrap();
149 Self {
150 data: cursor.into_inner(),
151 phantom: std::marker::PhantomData,
152 }
153 }
154 }
155 }
156 };
157}
158
159pub(crate) use query_info_data;
160use smb_msg_derive::smb_message_binrw;