1use crate::FileId;
4
5use super::{NullByte, common::*};
6#[cfg(feature = "server")]
7use binrw::io::TakeSeekExt;
8use binrw::prelude::*;
9use smb_dtyp::{SecurityDescriptor, binrw_util::prelude::*};
10use smb_fscc::*;
11use smb_msg_derive::*;
12
13#[smb_request(size = 33)]
21pub struct SetInfoRequest {
22 #[bw(calc = data.info_type())]
24 #[br(temp)]
25 pub info_type: InfoType,
26 pub info_class: SetInfoClass,
28 #[bw(calc = PosMarker::default())]
30 #[br(temp)]
31 buffer_length: PosMarker<u32>,
32 #[bw(calc = PosMarker::default())]
34 #[br(temp)]
35 _buffer_offset: PosMarker<u16>,
36 reserved: u16,
37 pub additional_information: AdditionalInfo,
39 pub file_id: FileId,
41 #[br(map_stream = |s| s.take_seek(buffer_length.value as u64))]
43 #[br(args(info_type))]
44 #[bw(write_with = PosMarker::write_aoff_size, args(&_buffer_offset, &buffer_length))]
45 pub data: SetInfoData,
46}
47
48query_info_data! {
49 SetInfoData
50 File: RawSetInfoData<SetFileInfo>,
51 FileSystem: RawSetInfoData<SetFileSystemInfo>,
52 Security: SecurityDescriptor,
53 Quota: ChainedItemList<FileQuotaInformation>,
54}
55
56#[smb_message_binrw]
63pub enum SetInfoClass {
64 File(SetFileInfoClass),
66 FileSystem(SetFileSystemInfoClass),
68 Security(NullByte),
70 Quota(NullByte),
72}
73
74impl From<SetFileInfoClass> for SetInfoClass {
75 fn from(val: SetFileInfoClass) -> Self {
76 SetInfoClass::File(val)
77 }
78}
79
80impl From<SetFileSystemInfoClass> for SetInfoClass {
81 fn from(val: SetFileSystemInfoClass) -> Self {
82 SetInfoClass::FileSystem(val)
83 }
84}
85
86impl SetInfoData {
87 pub fn to_req(
97 self,
98 info_class: SetInfoClass,
99 file_id: FileId,
100 additional_info: AdditionalInfo,
101 ) -> SetInfoRequest {
102 match (&info_class, &self) {
105 (SetInfoClass::File(_), SetInfoData::File(_)) => {}
106 (SetInfoClass::FileSystem(_), SetInfoData::FileSystem(_)) => {}
107 (SetInfoClass::Security(_), SetInfoData::Security(_)) => {}
108 (SetInfoClass::Quota(_), SetInfoData::Quota(_)) => {}
109 _ => panic!("Invalid info class and data combination"),
110 }
111
112 SetInfoRequest {
113 info_class,
114 additional_information: additional_info,
115 file_id,
116 data: self,
117 }
118 }
119}
120
121#[smb_response(size = 2)]
128#[derive(Default)]
129pub struct SetInfoResponse {}
130
131#[cfg(test)]
132mod tests {
133 use super::*;
134 use crate::*;
135 use smb_dtyp::*;
136
137 test_request! {
138 SetInfo {
139 info_class: SetInfoClass::File(SetFileInfoClass::RenameInformation),
140 data: SetInfoData::from(RawSetInfoData::from(SetFileInfo::RenameInformation(FileRenameInformation {
141 replace_if_exists: false.into(),
142 root_directory: 0,
143 file_name: "hello\\myNewFile.txt".into(),
144 }))),
145 file_id: make_guid!("00000042-000e-0000-0500-10000e000000").into(),
146 additional_information: AdditionalInfo::new(),
147 } => "2100010a3a0000006000000000000000420000000e000000050010000e0000000000000000000000000000000000000026000000680065006c006c006f005c006d0079004e0065007700460069006c0065002e00740078007400"
148 }
149
150 test_binrw_response! {
151 struct SetInfoResponse {} => "0200"
152 }
153}