smb_server_proto_smb1/
tree_connect.rs1use smb_server_proto::buf::Reader;
4
5use crate::session_setup::BodyError;
6
7#[derive(Debug)]
9pub struct TreeConnectReq {
10 pub path: String,
12 pub service: String,
14}
15
16impl TreeConnectReq {
17 pub fn parse(
20 words: &[u8],
21 data: &[u8],
22 unicode: bool,
23 data_base: usize,
24 ) -> Result<Self, BodyError> {
25 use super::session_setup::BodyError;
26 if words.len() < 8 || data.is_empty() {
27 return Err(BodyError::TooShort);
28 }
29 let pw_len = u16le(words, 6) as usize;
30 if pw_len > data.len() {
31 return Err(BodyError::BadBlob);
32 }
33 let mut rd = Reader::new(data, pw_len);
37 let path = rd.zstring(unicode, data_base);
38 let service = rd.zstring(false, data_base);
39 Ok(Self { path, service })
40 }
41}
42
43fn u16le(w: &[u8], off: usize) -> u16 {
44 w.get(off..off + 2)
45 .map(|s| u16::from_le_bytes(s.try_into().unwrap()))
46 .unwrap_or(0)
47}
48
49pub fn build_response(
52 optional_support: u16,
53 service: &str,
54 native_fs: &str,
55 unicode: bool,
56 params_base_abs: usize,
57) -> (Vec<u8>, Vec<u8>) {
58 let mut params = Vec::with_capacity(8);
59 params.push(0xFF);
60 params.push(0);
61 params.extend_from_slice(&0u16.to_le_bytes());
62 params.extend_from_slice(&optional_support.to_le_bytes());
63
64 let bytes_start_abs = params_base_abs;
65 let mut bytes = Vec::new();
66 bytes.extend_from_slice(service.as_bytes());
68 bytes.push(0);
69 while (bytes_start_abs + bytes.len()) & 1 != 0 && unicode {
70 bytes.push(0);
71 }
72 if unicode {
73 for u in native_fs.encode_utf16() {
74 bytes.extend_from_slice(&u.to_le_bytes());
75 }
76 bytes.extend_from_slice(&[0, 0]);
77 } else {
78 bytes.extend_from_slice(native_fs.as_bytes());
79 bytes.push(0);
80 }
81 (params, bytes)
82}