1mod graphics_messages;
2
3pub use graphics_messages::{
4 Avc420BitmapStream, Avc444BitmapStream, CacheImportReplyPdu, CacheToSurfacePdu, CapabilitiesAdvertisePdu,
5 CapabilitiesConfirmPdu, CapabilitiesV103Flags, CapabilitiesV104Flags, CapabilitiesV107Flags, CapabilitiesV10Flags,
6 CapabilitiesV81Flags, CapabilitiesV8Flags, CapabilitySet, Codec1Type, Codec2Type, Color, CreateSurfacePdu,
7 DeleteEncodingContextPdu, DeleteSurfacePdu, Encoding, EndFramePdu, EvictCacheEntryPdu, FrameAcknowledgePdu,
8 MapSurfaceToOutputPdu, MapSurfaceToScaledOutputPdu, MapSurfaceToScaledWindowPdu, PixelFormat, Point, QuantQuality,
9 QueueDepth, ResetGraphicsPdu, SolidFillPdu, StartFramePdu, SurfaceToCachePdu, SurfaceToSurfacePdu, Timestamp,
10 WireToSurface1Pdu, WireToSurface2Pdu,
11};
12use ironrdp_core::{
13 cast_length, ensure_fixed_part_size, ensure_size, invalid_field_err, Decode, DecodeResult, Encode, EncodeResult,
14 ReadCursor, WriteCursor,
15};
16use num_derive::{FromPrimitive, ToPrimitive};
17use num_traits::{FromPrimitive as _, ToPrimitive as _};
18
19#[derive(Debug, Clone, PartialEq, Eq)]
20pub enum ServerPdu {
21 WireToSurface1(WireToSurface1Pdu),
22 WireToSurface2(WireToSurface2Pdu),
23 DeleteEncodingContext(DeleteEncodingContextPdu),
24 SolidFill(SolidFillPdu),
25 SurfaceToSurface(SurfaceToSurfacePdu),
26 SurfaceToCache(SurfaceToCachePdu),
27 CacheToSurface(CacheToSurfacePdu),
28 EvictCacheEntry(EvictCacheEntryPdu),
29 CreateSurface(CreateSurfacePdu),
30 DeleteSurface(DeleteSurfacePdu),
31 StartFrame(StartFramePdu),
32 EndFrame(EndFramePdu),
33 ResetGraphics(ResetGraphicsPdu),
34 MapSurfaceToOutput(MapSurfaceToOutputPdu),
35 CapabilitiesConfirm(CapabilitiesConfirmPdu),
36 CacheImportReply(CacheImportReplyPdu),
37 MapSurfaceToScaledOutput(MapSurfaceToScaledOutputPdu),
38 MapSurfaceToScaledWindow(MapSurfaceToScaledWindowPdu),
39}
40
41const RDP_GFX_HEADER_SIZE: usize = 2 + 2 + 4 ;
42
43impl ServerPdu {
44 const NAME: &'static str = "GfxServerPdu";
45
46 const FIXED_PART_SIZE: usize = RDP_GFX_HEADER_SIZE;
47}
48
49impl Encode for ServerPdu {
50 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
51 ensure_size!(in: dst, size: self.size());
52
53 let buffer_length = self.size();
54
55 dst.write_u16(ServerPduType::from(self).to_u16().unwrap());
56 dst.write_u16(0); dst.write_u32(cast_length!("bufferLen", buffer_length)?);
58
59 match self {
60 ServerPdu::WireToSurface1(pdu) => pdu.encode(dst),
61 ServerPdu::WireToSurface2(pdu) => pdu.encode(dst),
62 ServerPdu::DeleteEncodingContext(pdu) => pdu.encode(dst),
63 ServerPdu::SolidFill(pdu) => pdu.encode(dst),
64 ServerPdu::SurfaceToSurface(pdu) => pdu.encode(dst),
65 ServerPdu::SurfaceToCache(pdu) => pdu.encode(dst),
66 ServerPdu::CacheToSurface(pdu) => pdu.encode(dst),
67 ServerPdu::CreateSurface(pdu) => pdu.encode(dst),
68 ServerPdu::DeleteSurface(pdu) => pdu.encode(dst),
69 ServerPdu::ResetGraphics(pdu) => pdu.encode(dst),
70 ServerPdu::MapSurfaceToOutput(pdu) => pdu.encode(dst),
71 ServerPdu::MapSurfaceToScaledOutput(pdu) => pdu.encode(dst),
72 ServerPdu::MapSurfaceToScaledWindow(pdu) => pdu.encode(dst),
73 ServerPdu::StartFrame(pdu) => pdu.encode(dst),
74 ServerPdu::EndFrame(pdu) => pdu.encode(dst),
75 ServerPdu::EvictCacheEntry(pdu) => pdu.encode(dst),
76 ServerPdu::CapabilitiesConfirm(pdu) => pdu.encode(dst),
77 ServerPdu::CacheImportReply(pdu) => pdu.encode(dst),
78 }
79 }
80
81 fn name(&self) -> &'static str {
82 Self::NAME
83 }
84
85 fn size(&self) -> usize {
86 Self::FIXED_PART_SIZE
87 + match self {
88 ServerPdu::WireToSurface1(pdu) => pdu.size(),
89 ServerPdu::WireToSurface2(pdu) => pdu.size(),
90 ServerPdu::DeleteEncodingContext(pdu) => pdu.size(),
91 ServerPdu::SolidFill(pdu) => pdu.size(),
92 ServerPdu::SurfaceToSurface(pdu) => pdu.size(),
93 ServerPdu::SurfaceToCache(pdu) => pdu.size(),
94 ServerPdu::CacheToSurface(pdu) => pdu.size(),
95 ServerPdu::CreateSurface(pdu) => pdu.size(),
96 ServerPdu::DeleteSurface(pdu) => pdu.size(),
97 ServerPdu::ResetGraphics(pdu) => pdu.size(),
98 ServerPdu::MapSurfaceToOutput(pdu) => pdu.size(),
99 ServerPdu::MapSurfaceToScaledOutput(pdu) => pdu.size(),
100 ServerPdu::MapSurfaceToScaledWindow(pdu) => pdu.size(),
101 ServerPdu::StartFrame(pdu) => pdu.size(),
102 ServerPdu::EndFrame(pdu) => pdu.size(),
103 ServerPdu::EvictCacheEntry(pdu) => pdu.size(),
104 ServerPdu::CapabilitiesConfirm(pdu) => pdu.size(),
105 ServerPdu::CacheImportReply(pdu) => pdu.size(),
106 }
107 }
108}
109
110impl<'a> Decode<'a> for ServerPdu {
111 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
112 ensure_fixed_part_size!(in: src);
113
114 let pdu_type = ServerPduType::from_u16(src.read_u16())
115 .ok_or_else(|| invalid_field_err!("serverPduType", "invalid pdu type"))?;
116 let _flags = src.read_u16();
117 let pdu_length = cast_length!("pduLen", src.read_u32())?;
118
119 let (server_pdu, buffer_length) = {
120 let pdu = match pdu_type {
121 ServerPduType::DeleteEncodingContext => {
122 ServerPdu::DeleteEncodingContext(DeleteEncodingContextPdu::decode(src)?)
123 }
124 ServerPduType::WireToSurface1 => ServerPdu::WireToSurface1(WireToSurface1Pdu::decode(src)?),
125 ServerPduType::WireToSurface2 => ServerPdu::WireToSurface2(WireToSurface2Pdu::decode(src)?),
126 ServerPduType::SolidFill => ServerPdu::SolidFill(SolidFillPdu::decode(src)?),
127 ServerPduType::SurfaceToSurface => ServerPdu::SurfaceToSurface(SurfaceToSurfacePdu::decode(src)?),
128 ServerPduType::SurfaceToCache => ServerPdu::SurfaceToCache(SurfaceToCachePdu::decode(src)?),
129 ServerPduType::CacheToSurface => ServerPdu::CacheToSurface(CacheToSurfacePdu::decode(src)?),
130 ServerPduType::EvictCacheEntry => ServerPdu::EvictCacheEntry(EvictCacheEntryPdu::decode(src)?),
131 ServerPduType::CreateSurface => ServerPdu::CreateSurface(CreateSurfacePdu::decode(src)?),
132 ServerPduType::DeleteSurface => ServerPdu::DeleteSurface(DeleteSurfacePdu::decode(src)?),
133 ServerPduType::StartFrame => ServerPdu::StartFrame(StartFramePdu::decode(src)?),
134 ServerPduType::EndFrame => ServerPdu::EndFrame(EndFramePdu::decode(src)?),
135 ServerPduType::ResetGraphics => ServerPdu::ResetGraphics(ResetGraphicsPdu::decode(src)?),
136 ServerPduType::MapSurfaceToOutput => ServerPdu::MapSurfaceToOutput(MapSurfaceToOutputPdu::decode(src)?),
137 ServerPduType::CapabilitiesConfirm => {
138 ServerPdu::CapabilitiesConfirm(CapabilitiesConfirmPdu::decode(src)?)
139 }
140 ServerPduType::CacheImportReply => ServerPdu::CacheImportReply(CacheImportReplyPdu::decode(src)?),
141 ServerPduType::MapSurfaceToScaledOutput => {
142 ServerPdu::MapSurfaceToScaledOutput(MapSurfaceToScaledOutputPdu::decode(src)?)
143 }
144 ServerPduType::MapSurfaceToScaledWindow => {
145 ServerPdu::MapSurfaceToScaledWindow(MapSurfaceToScaledWindowPdu::decode(src)?)
146 }
147 _ => return Err(invalid_field_err!("pduType", "invalid pdu type")),
148 };
149 let buffer_length = pdu.size();
150
151 (pdu, buffer_length)
152 };
153
154 if buffer_length != pdu_length {
155 Err(invalid_field_err!("len", "invalid pdu length"))
156 } else {
157 Ok(server_pdu)
158 }
159 }
160}
161
162#[derive(Debug, Clone, PartialEq, Eq)]
163pub enum ClientPdu {
164 FrameAcknowledge(FrameAcknowledgePdu),
165 CapabilitiesAdvertise(CapabilitiesAdvertisePdu),
166}
167
168impl ClientPdu {
169 const NAME: &'static str = "GfxClientPdu";
170
171 const FIXED_PART_SIZE: usize = RDP_GFX_HEADER_SIZE;
172}
173
174impl Encode for ClientPdu {
175 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
176 ensure_size!(in: dst, size: self.size());
177
178 dst.write_u16(ClientPduType::from(self).to_u16().unwrap());
179 dst.write_u16(0); dst.write_u32(cast_length!("bufferLen", self.size())?);
181
182 match self {
183 ClientPdu::FrameAcknowledge(pdu) => pdu.encode(dst),
184 ClientPdu::CapabilitiesAdvertise(pdu) => pdu.encode(dst),
185 }
186 }
187
188 fn name(&self) -> &'static str {
189 Self::NAME
190 }
191
192 fn size(&self) -> usize {
193 Self::FIXED_PART_SIZE
194 + match self {
195 ClientPdu::FrameAcknowledge(pdu) => pdu.size(),
196 ClientPdu::CapabilitiesAdvertise(pdu) => pdu.size(),
197 }
198 }
199}
200
201impl<'a> Decode<'a> for ClientPdu {
202 fn decode(src: &mut ReadCursor<'a>) -> DecodeResult<Self> {
203 let pdu_type = ClientPduType::from_u16(src.read_u16())
204 .ok_or_else(|| invalid_field_err!("clientPduType", "invalid pdu type"))?;
205 let _flags = src.read_u16();
206 let pdu_length = cast_length!("bufferLen", src.read_u32())?;
207
208 let client_pdu = match pdu_type {
209 ClientPduType::FrameAcknowledge => ClientPdu::FrameAcknowledge(FrameAcknowledgePdu::decode(src)?),
210 ClientPduType::CapabilitiesAdvertise => {
211 ClientPdu::CapabilitiesAdvertise(CapabilitiesAdvertisePdu::decode(src)?)
212 }
213 _ => return Err(invalid_field_err!("pduType", "invalid pdu type")),
214 };
215
216 if client_pdu.size() != pdu_length {
217 Err(invalid_field_err!("len", "invalid pdu length"))
218 } else {
219 Ok(client_pdu)
220 }
221 }
222}
223
224#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
225pub enum ClientPduType {
226 FrameAcknowledge = 0x0d,
227 CacheImportOffer = 0x10,
228 CapabilitiesAdvertise = 0x12,
229 QoeFrameAcknowledge = 0x16,
230}
231
232impl<'a> From<&'a ClientPdu> for ClientPduType {
233 fn from(c: &'a ClientPdu) -> Self {
234 match c {
235 ClientPdu::FrameAcknowledge(_) => Self::FrameAcknowledge,
236 ClientPdu::CapabilitiesAdvertise(_) => Self::CapabilitiesAdvertise,
237 }
238 }
239}
240
241#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
242pub enum ServerPduType {
243 WireToSurface1 = 0x01,
244 WireToSurface2 = 0x02,
245 DeleteEncodingContext = 0x03,
246 SolidFill = 0x04,
247 SurfaceToSurface = 0x05,
248 SurfaceToCache = 0x06,
249 CacheToSurface = 0x07,
250 EvictCacheEntry = 0x08,
251 CreateSurface = 0x09,
252 DeleteSurface = 0x0a,
253 StartFrame = 0x0b,
254 EndFrame = 0x0c,
255 ResetGraphics = 0x0e,
256 MapSurfaceToOutput = 0x0f,
257 CacheImportReply = 0x11,
258 CapabilitiesConfirm = 0x13,
259 MapSurfaceToWindow = 0x15,
260 MapSurfaceToScaledOutput = 0x17,
261 MapSurfaceToScaledWindow = 0x18,
262}
263
264impl<'a> From<&'a ServerPdu> for ServerPduType {
265 fn from(s: &'a ServerPdu) -> Self {
266 match s {
267 ServerPdu::WireToSurface1(_) => Self::WireToSurface1,
268 ServerPdu::WireToSurface2(_) => Self::WireToSurface2,
269 ServerPdu::DeleteEncodingContext(_) => Self::DeleteEncodingContext,
270 ServerPdu::SolidFill(_) => Self::SolidFill,
271 ServerPdu::SurfaceToSurface(_) => Self::SurfaceToSurface,
272 ServerPdu::SurfaceToCache(_) => Self::SurfaceToCache,
273 ServerPdu::CacheToSurface(_) => Self::CacheToSurface,
274 ServerPdu::EvictCacheEntry(_) => Self::EvictCacheEntry,
275 ServerPdu::CreateSurface(_) => Self::CreateSurface,
276 ServerPdu::DeleteSurface(_) => Self::DeleteSurface,
277 ServerPdu::StartFrame(_) => Self::StartFrame,
278 ServerPdu::EndFrame(_) => Self::EndFrame,
279 ServerPdu::ResetGraphics(_) => Self::ResetGraphics,
280 ServerPdu::MapSurfaceToOutput(_) => Self::MapSurfaceToOutput,
281 ServerPdu::MapSurfaceToScaledOutput(_) => Self::MapSurfaceToScaledOutput,
282 ServerPdu::MapSurfaceToScaledWindow(_) => Self::MapSurfaceToScaledWindow,
283 ServerPdu::CapabilitiesConfirm(_) => Self::CapabilitiesConfirm,
284 ServerPdu::CacheImportReply(_) => Self::CacheImportReply,
285 }
286 }
287}