smb_server_proto_smb1/
misc.rs1fn u16le(w: &[u8], off: usize) -> u16 {
6 w.get(off..off + 2)
7 .map(|s| u16::from_le_bytes(s.try_into().unwrap()))
8 .unwrap_or(0)
9}
10
11#[derive(Debug)]
13pub struct CloseReq {
14 pub fid: u16,
16 pub mtime: u32,
18}
19
20impl CloseReq {
21 pub fn parse(words: &[u8]) -> Option<Self> {
23 if words.len() < 6 {
24 return None;
25 }
26 Some(CloseReq {
27 fid: u16le(words, 0),
28 mtime: u32le(words, 2),
29 })
30 }
31}
32
33pub fn empty_response(_command: u8) -> (Vec<u8>, Vec<u8>) {
35 (Vec::new(), Vec::new())
36}
37
38pub fn flush_fid(words: &[u8]) -> Option<u16> {
40 words.len().checked_sub(2).map(|_| u16le(words, 0))
41}
42
43#[derive(Debug)]
45pub struct EchoReq {
46 pub count: u16,
48 pub data: Vec<u8>,
50}
51
52impl EchoReq {
53 pub fn parse(words: &[u8], data: &[u8]) -> Self {
55 EchoReq { count: u16le(words, 0).max(1), data: data.to_vec() }
56 }
57
58 pub fn build_response(seq: u16, data: &[u8]) -> (Vec<u8>, Vec<u8>) {
60 let mut params = Vec::with_capacity(4);
61 params.extend_from_slice(&seq.to_le_bytes());
62 params.extend_from_slice(&0u16.to_le_bytes());
63 let mut bytes = Vec::new();
64 bytes.extend_from_slice(data);
65 (params, bytes)
66 }
67}
68
69#[derive(Debug)]
71pub struct LogoffResp;
72impl LogoffResp {
73 pub fn body() -> (Vec<u8>, Vec<u8>) {
75 (vec![0xFF, 0, 0, 0], Vec::new())
76 }
77}
78
79#[derive(Debug)]
81pub struct TreeDisconnectResp;
82impl TreeDisconnectResp {
83 pub fn body() -> (Vec<u8>, Vec<u8>) {
85 (Vec::new(), Vec::new())
86 }
87}
88
89#[derive(Debug)]
91pub struct QueryDiskInfo {
92 pub total_units: u32,
94 pub free_units: u32,
96 pub bps: u16,
98 pub spc: u16,
100}
101
102impl QueryDiskInfo {
103 pub fn encode(&self) -> Vec<u8> {
105 let mut p = Vec::with_capacity(10);
106 p.extend_from_slice(&self.total_units.to_le_bytes());
107 p.extend_from_slice(&self.free_units.to_le_bytes());
108 p.extend_from_slice(&self.bps.to_le_bytes());
109 p.extend_from_slice(&self.spc.to_le_bytes());
110 p.extend_from_slice(&0u16.to_le_bytes()); p
112 }
113}
114
115#[derive(Debug)]
117pub struct SeekReq {
118 pub fid: u16,
120 pub mode: u16,
122 pub offset: i64,
124}
125
126impl SeekReq {
127 pub fn parse(words: &[u8]) -> Option<Self> {
129 if words.len() < 8 {
130 return None;
131 }
132 Some(SeekReq {
133 fid: u16le(words, 0),
134 mode: u16le(words, 2),
135 offset: i32::from_le_bytes(words.get(4..8)?.try_into().ok()?) as i64,
136 })
137 }
138
139 pub fn build_response(new_pos: u64) -> Vec<u8> {
141 (new_pos as u32).to_le_bytes().to_vec()
142 }
143}
144
145#[derive(Debug)]
147pub struct LockingAndxReq;
148
149impl LockingAndxReq {
150 pub fn build_response() -> Vec<u8> {
152 vec![0xFF, 0, 0, 0]
153 }
154}
155
156#[derive(Debug)]
158pub struct NtCancel;
159
160fn u32le(w: &[u8], off: usize) -> u32 {
161 w.get(off..off + 4)
162 .map(|s| u32::from_le_bytes(s.try_into().unwrap()))
163 .unwrap_or(0)
164}