ironrdp_pdu/rdp/
finalization_messages.rs

1use bitflags::bitflags;
2use ironrdp_core::{
3    cast_length, ensure_fixed_part_size, invalid_field_err, Decode, DecodeResult, Encode, EncodeResult, ReadCursor,
4    WriteCursor,
5};
6use num_derive::{FromPrimitive, ToPrimitive};
7use num_traits::{FromPrimitive as _, ToPrimitive as _};
8
9use crate::gcc;
10
11const SYNCHRONIZE_PDU_SIZE: usize = 2 + 2;
12const CONTROL_PDU_SIZE: usize = 2 + 2 + 4;
13const FONT_PDU_SIZE: usize = 2 * 4;
14const SYNCHRONIZE_MESSAGE_TYPE: u16 = 1;
15const MAX_MONITOR_COUNT: u32 = 64;
16
17#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct SynchronizePdu {
19    pub target_user_id: u16,
20}
21
22impl SynchronizePdu {
23    const NAME: &'static str = "SynchronizePdu";
24
25    const FIXED_PART_SIZE: usize = SYNCHRONIZE_PDU_SIZE;
26}
27
28impl Encode for SynchronizePdu {
29    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
30        ensure_fixed_part_size!(in: dst);
31
32        dst.write_u16(SYNCHRONIZE_MESSAGE_TYPE);
33        dst.write_u16(self.target_user_id);
34
35        Ok(())
36    }
37
38    fn name(&self) -> &'static str {
39        Self::NAME
40    }
41
42    fn size(&self) -> usize {
43        SYNCHRONIZE_PDU_SIZE
44    }
45}
46
47impl<'de> Decode<'de> for SynchronizePdu {
48    fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
49        ensure_fixed_part_size!(in: src);
50
51        let message_type = src.read_u16();
52        if message_type != SYNCHRONIZE_MESSAGE_TYPE {
53            return Err(invalid_field_err!("messageType", "invalid message type"));
54        }
55
56        let target_user_id = src.read_u16();
57
58        Ok(Self { target_user_id })
59    }
60}
61
62#[derive(Debug, Clone, PartialEq, Eq)]
63pub struct ControlPdu {
64    pub action: ControlAction,
65    pub grant_id: u16,
66    pub control_id: u32,
67}
68
69impl ControlPdu {
70    const NAME: &'static str = "ControlPdu";
71
72    const FIXED_PART_SIZE: usize = CONTROL_PDU_SIZE;
73}
74
75impl Encode for ControlPdu {
76    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
77        ensure_fixed_part_size!(in: dst);
78
79        dst.write_u16(self.action.to_u16().unwrap());
80        dst.write_u16(self.grant_id);
81        dst.write_u32(self.control_id);
82
83        Ok(())
84    }
85
86    fn name(&self) -> &'static str {
87        Self::NAME
88    }
89
90    fn size(&self) -> usize {
91        Self::FIXED_PART_SIZE
92    }
93}
94
95impl<'de> Decode<'de> for ControlPdu {
96    fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
97        ensure_fixed_part_size!(in: src);
98
99        let action = ControlAction::from_u16(src.read_u16())
100            .ok_or_else(|| invalid_field_err!("action", "invalid control action"))?;
101        let grant_id = src.read_u16();
102        let control_id = src.read_u32();
103
104        Ok(Self {
105            action,
106            grant_id,
107            control_id,
108        })
109    }
110}
111
112/// [2.2.1.22.1] Font Map PDU Data (TS_FONT_MAP_PDU)
113///
114/// [2.2.1.22.1]: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/b4e557f3-7540-46fc-815d-0c12299cf1ee
115#[derive(Debug, Clone, PartialEq, Eq)]
116pub struct FontPdu {
117    pub number: u16,
118    pub total_number: u16,
119    pub flags: SequenceFlags,
120    pub entry_size: u16,
121}
122
123impl Default for FontPdu {
124    fn default() -> Self {
125        // Those values are recommended in [2.2.1.22.1].
126        Self {
127            number: 0,
128            total_number: 0,
129            flags: SequenceFlags::FIRST | SequenceFlags::LAST,
130            entry_size: 4,
131        }
132    }
133}
134
135impl FontPdu {
136    const NAME: &'static str = "FontPdu";
137
138    const FIXED_PART_SIZE: usize = FONT_PDU_SIZE;
139}
140
141impl Encode for FontPdu {
142    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
143        ensure_fixed_part_size!(in: dst);
144
145        dst.write_u16(self.number);
146        dst.write_u16(self.total_number);
147        dst.write_u16(self.flags.bits());
148        dst.write_u16(self.entry_size);
149
150        Ok(())
151    }
152
153    fn name(&self) -> &'static str {
154        Self::NAME
155    }
156
157    fn size(&self) -> usize {
158        Self::FIXED_PART_SIZE
159    }
160}
161
162impl<'de> Decode<'de> for FontPdu {
163    fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
164        ensure_fixed_part_size!(in: src);
165
166        let number = src.read_u16();
167        let total_number = src.read_u16();
168        let flags = SequenceFlags::from_bits(src.read_u16())
169            .ok_or_else(|| invalid_field_err!("flags", "invalid sequence flags"))?;
170        let entry_size = src.read_u16();
171
172        Ok(Self {
173            number,
174            total_number,
175            flags,
176            entry_size,
177        })
178    }
179}
180
181#[derive(Debug, Clone, PartialEq, Eq)]
182pub struct MonitorLayoutPdu {
183    pub monitors: Vec<gcc::Monitor>,
184}
185
186impl MonitorLayoutPdu {
187    const NAME: &'static str = "MonitorLayoutPdu";
188
189    const FIXED_PART_SIZE: usize = 4 /* nMonitors */;
190}
191
192impl Encode for MonitorLayoutPdu {
193    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
194        ensure_fixed_part_size!(in: dst);
195
196        dst.write_u32(cast_length!("nMonitors", self.monitors.len())?);
197
198        for monitor in self.monitors.iter() {
199            monitor.encode(dst)?;
200        }
201
202        Ok(())
203    }
204
205    fn name(&self) -> &'static str {
206        Self::NAME
207    }
208
209    fn size(&self) -> usize {
210        Self::FIXED_PART_SIZE + self.monitors.len() * gcc::MONITOR_SIZE
211    }
212}
213
214impl<'de> Decode<'de> for MonitorLayoutPdu {
215    fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
216        ensure_fixed_part_size!(in: src);
217
218        let monitor_count = src.read_u32();
219        if monitor_count > MAX_MONITOR_COUNT {
220            return Err(invalid_field_err!("nMonitors", "invalid monitor count"));
221        }
222
223        let mut monitors = Vec::with_capacity(monitor_count as usize);
224        for _ in 0..monitor_count {
225            monitors.push(gcc::Monitor::decode(src)?);
226        }
227
228        Ok(Self { monitors })
229    }
230}
231
232#[repr(u16)]
233#[derive(Debug, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
234pub enum ControlAction {
235    RequestControl = 1,
236    GrantedControl = 2,
237    Detach = 3,
238    Cooperate = 4,
239}
240
241bitflags! {
242    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
243    pub struct SequenceFlags: u16 {
244        const FIRST = 1;
245        const LAST = 2;
246    }
247}