smb_msg/info/
set.rs

1//! SMB2 Set Info Request/Response messages.
2
3use crate::{FileId, query_info_data};
4
5use super::{NullByte, common::*};
6use binrw::io::TakeSeekExt;
7use binrw::prelude::*;
8use smb_dtyp::{SecurityDescriptor, binrw_util::prelude::*};
9use smb_fscc::*;
10
11#[binrw::binrw]
12#[derive(Debug, PartialEq, Eq)]
13pub struct SetInfoRequest {
14    #[bw(calc = 33)]
15    #[br(assert(_structure_size == 33))]
16    _structure_size: u16,
17    #[bw(calc = data.info_type())]
18    pub info_type: InfoType,
19    pub info_class: SetInfoClass,
20    #[bw(calc = PosMarker::default())]
21    buffer_length: PosMarker<u32>,
22    #[bw(calc = PosMarker::default())]
23    _buffer_offset: PosMarker<u16>,
24    #[bw(calc = 0)]
25    _reserved: u16,
26    pub additional_information: AdditionalInfo,
27    pub file_id: FileId,
28    #[br(map_stream = |s| s.take_seek(buffer_length.value as u64))]
29    #[br(args(info_type))]
30    #[bw(write_with = PosMarker::write_aoff_size, args(&_buffer_offset, &buffer_length))]
31    pub data: SetInfoData,
32}
33
34query_info_data! {
35    SetInfoData
36    File: RawSetInfoData<SetFileInfo>,
37    FileSystem: RawSetInfoData<SetFileSystemInfo>,
38    Security: SecurityDescriptor,
39    Quota: ChainedItemList<FileQuotaInformation>,
40}
41
42/// A helper class for [SetInfoRequest] to contain the information
43/// class to set. In cases of no class, it will be set to a null byte (0u8).
44#[binrw::binrw]
45#[derive(Debug, PartialEq, Eq)]
46pub enum SetInfoClass {
47    File(SetFileInfoClass),
48    FileSystem(SetFileSystemInfoClass),
49    Security(NullByte),
50    Quota(NullByte),
51}
52
53impl From<SetFileInfoClass> for SetInfoClass {
54    fn from(val: SetFileInfoClass) -> Self {
55        SetInfoClass::File(val)
56    }
57}
58
59impl From<SetFileSystemInfoClass> for SetInfoClass {
60    fn from(val: SetFileSystemInfoClass) -> Self {
61        SetInfoClass::FileSystem(val)
62    }
63}
64
65impl SetInfoData {
66    /// This is a helper function to convert the [SetInfoData] to
67    /// a [SetInfoRequest].
68    pub fn to_req(
69        self,
70        info_class: SetInfoClass,
71        file_id: FileId,
72        additional_info: AdditionalInfo,
73    ) -> SetInfoRequest {
74        // Validate the info class and data combination
75        // to ensure they are compatible.
76        match (&info_class, &self) {
77            (SetInfoClass::File(_), SetInfoData::File(_)) => {}
78            (SetInfoClass::FileSystem(_), SetInfoData::FileSystem(_)) => {}
79            (SetInfoClass::Security(_), SetInfoData::Security(_)) => {}
80            (SetInfoClass::Quota(_), SetInfoData::Quota(_)) => {}
81            _ => panic!("Invalid info class and data combination"),
82        }
83
84        SetInfoRequest {
85            info_class,
86            additional_information: additional_info,
87            file_id,
88            data: self,
89        }
90    }
91}
92
93#[binrw::binrw]
94#[derive(Debug, PartialEq, Eq)]
95pub struct SetInfoResponse {
96    #[bw(calc = 2)]
97    #[br(assert(_structure_size == 2))]
98    _structure_size: u16,
99}
100
101#[cfg(test)]
102mod tests {
103    use super::*;
104    use crate::*;
105    use smb_dtyp::*;
106    use smb_tests::*;
107
108    test_request! {
109        SetInfo {
110            info_class: SetInfoClass::File(SetFileInfoClass::RenameInformation),
111            data: SetInfoData::from(RawSetInfoData::from(SetFileInfo::RenameInformation(FileRenameInformation {
112                replace_if_exists: false.into(),
113                root_directory: 0,
114                file_name: "hello\\myNewFile.txt".into(),
115            }))),
116            file_id: make_guid!("00000042-000e-0000-0500-10000e000000").into(),
117            additional_information: AdditionalInfo::new(),
118        } => "2100010a3a0000006000000000000000420000000e000000050010000e0000000000000000000000000000000000000026000000680065006c006c006f005c006d0079004e0065007700460069006c0065002e00740078007400"
119    }
120
121    test_binrw! {
122        struct SetInfoResponse {} => "0200"
123    }
124}