1use std::io;
2
3use ironrdp_core::{
4 cast_length, decode, ensure_fixed_part_size, ensure_size, invalid_field_err, unsupported_value_err, write_padding,
5 Decode, DecodeResult, Encode, EncodeResult, ReadCursor, WriteCursor,
6};
7use num_derive::{FromPrimitive, ToPrimitive};
8use num_traits::{FromPrimitive as _, ToPrimitive as _};
9use thiserror::Error;
10
11use crate::{utils, PduError};
12
13mod bitmap;
14mod bitmap_cache;
15mod bitmap_codecs;
16mod brush;
17mod frame_acknowledge;
18mod general;
19mod glyph_cache;
20mod input;
21mod large_pointer;
22mod multifragment_update;
23mod offscreen_bitmap_cache;
24mod order;
25mod pointer;
26mod sound;
27mod surface_commands;
28mod virtual_channel;
29
30pub use self::bitmap::{Bitmap, BitmapDrawingFlags};
31pub use self::bitmap_cache::{
32 BitmapCache, BitmapCacheRev2, CacheEntry, CacheFlags, CellInfo, BITMAP_CACHE_ENTRIES_NUM,
33};
34pub use self::bitmap_codecs::{
35 client_codecs_capabilities, server_codecs_capabilities, BitmapCodecs, CaptureFlags, Codec, CodecId, CodecProperty,
36 EntropyBits, Guid, NsCodec, RemoteFxContainer, RfxCaps, RfxCapset, RfxClientCapsContainer, RfxICap, RfxICapFlags,
37 CODEC_ID_NONE, CODEC_ID_QOI, CODEC_ID_QOIZ, CODEC_ID_REMOTEFX,
38};
39pub use self::brush::{Brush, SupportLevel};
40pub use self::frame_acknowledge::FrameAcknowledge;
41pub use self::general::{General, GeneralExtraFlags, MajorPlatformType, MinorPlatformType, PROTOCOL_VER};
42pub use self::glyph_cache::{CacheDefinition, GlyphCache, GlyphSupportLevel, GLYPH_CACHE_NUM};
43pub use self::input::{Input, InputFlags};
44pub use self::large_pointer::{LargePointer, LargePointerSupportFlags};
45pub use self::multifragment_update::MultifragmentUpdate;
46pub use self::offscreen_bitmap_cache::OffscreenBitmapCache;
47pub use self::order::{Order, OrderFlags, OrderSupportExFlags, OrderSupportIndex};
48pub use self::pointer::Pointer;
49pub use self::sound::{Sound, SoundFlags};
50pub use self::surface_commands::{CmdFlags, SurfaceCommands};
51pub use self::virtual_channel::{VirtualChannel, VirtualChannelFlags};
52
53pub const SERVER_CHANNEL_ID: u16 = 0x03ea;
54
55const SOURCE_DESCRIPTOR_LENGTH_FIELD_SIZE: usize = 2;
56const COMBINED_CAPABILITIES_LENGTH_FIELD_SIZE: usize = 2;
57const NUMBER_CAPABILITIES_FIELD_SIZE: usize = 2;
58const PADDING_SIZE: usize = 2;
59const SESSION_ID_FIELD_SIZE: usize = 4;
60const CAPABILITY_SET_TYPE_FIELD_SIZE: usize = 2;
61const CAPABILITY_SET_LENGTH_FIELD_SIZE: usize = 2;
62const ORIGINATOR_ID_FIELD_SIZE: usize = 2;
63
64const NULL_TERMINATOR: &str = "\0";
65
66#[derive(Debug, Clone, PartialEq, Eq)]
70pub struct ServerDemandActive {
71 pub pdu: DemandActive,
72}
73
74impl ServerDemandActive {
75 const NAME: &'static str = "ServerDemandActive";
76
77 const FIXED_PART_SIZE: usize = SESSION_ID_FIELD_SIZE;
78}
79
80impl Encode for ServerDemandActive {
81 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
82 ensure_size!(in: dst, size: self.size());
83
84 self.pdu.encode(dst)?;
85 dst.write_u32(0); Ok(())
88 }
89
90 fn name(&self) -> &'static str {
91 Self::NAME
92 }
93
94 fn size(&self) -> usize {
95 Self::FIXED_PART_SIZE + self.pdu.size()
96 }
97}
98
99impl<'de> Decode<'de> for ServerDemandActive {
100 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
101 let pdu = DemandActive::decode(src)?;
102
103 ensure_size!(in: src, size: 4);
104 let _session_id = src.read_u32();
105
106 Ok(Self { pdu })
107 }
108}
109
110#[derive(Debug, Clone, PartialEq, Eq)]
114pub struct ClientConfirmActive {
115 pub originator_id: u16,
122 pub pdu: DemandActive,
123}
124
125impl ClientConfirmActive {
126 const NAME: &'static str = "ClientConfirmActive";
127
128 const FIXED_PART_SIZE: usize = ORIGINATOR_ID_FIELD_SIZE;
129}
130
131impl Encode for ClientConfirmActive {
132 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
133 ensure_fixed_part_size!(in: dst);
134
135 dst.write_u16(self.originator_id);
136
137 self.pdu.encode(dst)
138 }
139
140 fn name(&self) -> &'static str {
141 Self::NAME
142 }
143
144 fn size(&self) -> usize {
145 Self::FIXED_PART_SIZE + self.pdu.size()
146 }
147}
148
149impl<'de> Decode<'de> for ClientConfirmActive {
150 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
151 ensure_fixed_part_size!(in: src);
152
153 let originator_id = src.read_u16();
154 let pdu = DemandActive::decode(src)?;
155
156 Ok(Self { originator_id, pdu })
157 }
158}
159
160#[derive(Debug, Clone, PartialEq, Eq)]
164pub struct DemandActive {
165 pub source_descriptor: String,
166 pub capability_sets: Vec<CapabilitySet>,
167}
168
169impl DemandActive {
170 const NAME: &'static str = "DemandActive";
171
172 const FIXED_PART_SIZE: usize = SOURCE_DESCRIPTOR_LENGTH_FIELD_SIZE + COMBINED_CAPABILITIES_LENGTH_FIELD_SIZE;
173}
174
175impl Encode for DemandActive {
176 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
177 ensure_size!(in: dst, size: self.size());
178
179 let combined_length = self.capability_sets.iter().map(Encode::size).sum::<usize>()
180 + NUMBER_CAPABILITIES_FIELD_SIZE
181 + PADDING_SIZE;
182
183 dst.write_u16(cast_length!(
184 "sourceDescLen",
185 self.source_descriptor.len() + NULL_TERMINATOR.len()
186 )?);
187 dst.write_u16(cast_length!("combinedLen", combined_length)?);
188 dst.write_slice(self.source_descriptor.as_ref());
189 dst.write_slice(NULL_TERMINATOR.as_bytes());
190 dst.write_u16(cast_length!("len", self.capability_sets.len())?);
191 write_padding!(dst, 2);
192
193 for capability_set in self.capability_sets.iter() {
194 capability_set.encode(dst)?;
195 }
196
197 Ok(())
198 }
199
200 fn name(&self) -> &'static str {
201 Self::NAME
202 }
203
204 fn size(&self) -> usize {
205 Self::FIXED_PART_SIZE
206 + self.source_descriptor.len()
207 + 1
208 + NUMBER_CAPABILITIES_FIELD_SIZE
209 + PADDING_SIZE
210 + self.capability_sets.iter().map(Encode::size).sum::<usize>()
211 }
212}
213
214impl<'de> Decode<'de> for DemandActive {
215 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
216 ensure_fixed_part_size!(in: src);
217
218 let source_descriptor_length = src.read_u16() as usize;
219 let _combined_capabilities_length = src.read_u16() as usize;
221
222 ensure_size!(in: src, size: source_descriptor_length);
223 let source_descriptor = utils::decode_string(
224 src.read_slice(source_descriptor_length),
225 utils::CharacterSet::Ansi,
226 false,
227 )?;
228
229 ensure_size!(in: src, size: 2 + 2);
230 let capability_sets_count = src.read_u16() as usize;
231 let _padding = src.read_u16();
232
233 let mut capability_sets = Vec::with_capacity(capability_sets_count);
234
235 for _ in 0..capability_sets_count {
236 capability_sets.push(CapabilitySet::decode(src)?);
237 }
238
239 Ok(Self {
240 source_descriptor,
241 capability_sets,
242 })
243 }
244}
245
246#[derive(Debug, Clone, PartialEq, Eq)]
247pub enum CapabilitySet {
248 General(General),
250 Bitmap(Bitmap),
251 Order(Order),
252 BitmapCache(BitmapCache),
253 BitmapCacheRev2(BitmapCacheRev2),
254 Pointer(Pointer),
255 Sound(Sound),
256 Input(Input),
257 Brush(Brush),
258 GlyphCache(GlyphCache),
259 OffscreenBitmapCache(OffscreenBitmapCache),
260 VirtualChannel(VirtualChannel),
261
262 Control(Vec<u8>),
264 WindowActivation(Vec<u8>),
265 Share(Vec<u8>),
266 Font(Vec<u8>),
267 BitmapCacheHostSupport(Vec<u8>),
268 DesktopComposition(Vec<u8>),
269 MultiFragmentUpdate(MultifragmentUpdate),
270 LargePointer(LargePointer),
271 SurfaceCommands(SurfaceCommands),
272 BitmapCodecs(BitmapCodecs),
273
274 FrameAcknowledge(FrameAcknowledge),
276 ColorCache(Vec<u8>),
277 DrawNineGridCache(Vec<u8>),
278 DrawGdiPlus(Vec<u8>),
279 Rail(Vec<u8>),
280 WindowList(Vec<u8>),
281 BitmapCacheV3(Vec<u8>),
282}
283
284impl CapabilitySet {
285 const NAME: &'static str = "CapabilitySet";
286
287 const FIXED_PART_SIZE: usize = CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE;
288}
289
290impl Encode for CapabilitySet {
291 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
292 ensure_size!(in: dst, size: self.size());
293
294 match self {
295 CapabilitySet::General(capset) => {
296 dst.write_u16(CapabilitySetType::General.to_u16().unwrap());
297 dst.write_u16(cast_length!(
298 "len",
299 capset.size() + CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE
300 )?);
301 capset.encode(dst)?;
302 }
303 CapabilitySet::Bitmap(capset) => {
304 dst.write_u16(CapabilitySetType::Bitmap.to_u16().unwrap());
305 dst.write_u16(cast_length!(
306 "len",
307 capset.size() + CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE
308 )?);
309 capset.encode(dst)?;
310 }
311 CapabilitySet::Order(capset) => {
312 dst.write_u16(CapabilitySetType::Order.to_u16().unwrap());
313 dst.write_u16(cast_length!(
314 "len",
315 capset.size() + CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE
316 )?);
317 capset.encode(dst)?;
318 }
319 CapabilitySet::BitmapCache(capset) => {
320 dst.write_u16(CapabilitySetType::BitmapCache.to_u16().unwrap());
321 dst.write_u16(cast_length!(
322 "len",
323 capset.size() + CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE
324 )?);
325 capset.encode(dst)?;
326 }
327 CapabilitySet::BitmapCacheRev2(capset) => {
328 dst.write_u16(CapabilitySetType::BitmapCacheRev2.to_u16().unwrap());
329 dst.write_u16(cast_length!(
330 "len",
331 capset.size() + CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE
332 )?);
333 capset.encode(dst)?;
334 }
335 CapabilitySet::Pointer(capset) => {
336 dst.write_u16(CapabilitySetType::Pointer.to_u16().unwrap());
337 dst.write_u16(cast_length!(
338 "len",
339 capset.size() + CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE
340 )?);
341 capset.encode(dst)?;
342 }
343 CapabilitySet::Sound(capset) => {
344 dst.write_u16(CapabilitySetType::Sound.to_u16().unwrap());
345 dst.write_u16(cast_length!(
346 "len",
347 capset.size() + CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE
348 )?);
349 capset.encode(dst)?;
350 }
351 CapabilitySet::Input(capset) => {
352 dst.write_u16(CapabilitySetType::Input.to_u16().unwrap());
353 dst.write_u16(cast_length!(
354 "len",
355 capset.size() + CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE
356 )?);
357 capset.encode(dst)?;
358 }
359 CapabilitySet::Brush(capset) => {
360 dst.write_u16(CapabilitySetType::Brush.to_u16().unwrap());
361 dst.write_u16(cast_length!(
362 "len",
363 capset.size() + CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE
364 )?);
365 capset.encode(dst)?;
366 }
367 CapabilitySet::GlyphCache(capset) => {
368 dst.write_u16(CapabilitySetType::GlyphCache.to_u16().unwrap());
369 dst.write_u16(cast_length!(
370 "len",
371 capset.size() + CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE
372 )?);
373 capset.encode(dst)?;
374 }
375 CapabilitySet::OffscreenBitmapCache(capset) => {
376 dst.write_u16(CapabilitySetType::OffscreenBitmapCache.to_u16().unwrap());
377 dst.write_u16(cast_length!(
378 "len",
379 capset.size() + CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE
380 )?);
381 capset.encode(dst)?;
382 }
383 CapabilitySet::VirtualChannel(capset) => {
384 dst.write_u16(CapabilitySetType::VirtualChannel.to_u16().unwrap());
385 dst.write_u16(cast_length!(
386 "len",
387 capset.size() + CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE
388 )?);
389 capset.encode(dst)?;
390 }
391 CapabilitySet::SurfaceCommands(capset) => {
392 dst.write_u16(CapabilitySetType::SurfaceCommands.to_u16().unwrap());
393 dst.write_u16(cast_length!(
394 "len",
395 capset.size() + CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE
396 )?);
397 capset.encode(dst)?;
398 }
399 CapabilitySet::BitmapCodecs(capset) => {
400 dst.write_u16(CapabilitySetType::BitmapCodecs.to_u16().unwrap());
401 dst.write_u16(cast_length!(
402 "len",
403 capset.size() + CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE
404 )?);
405 capset.encode(dst)?;
406 }
407 CapabilitySet::MultiFragmentUpdate(capset) => {
408 dst.write_u16(CapabilitySetType::MultiFragmentUpdate.to_u16().unwrap());
409 dst.write_u16(cast_length!(
410 "len",
411 capset.size() + CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE
412 )?);
413 capset.encode(dst)?;
414 }
415 CapabilitySet::LargePointer(capset) => {
416 dst.write_u16(CapabilitySetType::LargePointer.to_u16().unwrap());
417 dst.write_u16(cast_length!(
418 "len",
419 capset.size() + CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE
420 )?);
421 capset.encode(dst)?;
422 }
423 CapabilitySet::FrameAcknowledge(capset) => {
424 dst.write_u16(CapabilitySetType::FrameAcknowledge.to_u16().unwrap());
425 dst.write_u16(cast_length!(
426 "len",
427 capset.size() + CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE
428 )?);
429 capset.encode(dst)?;
430 }
431 _ => {
432 let (capability_set_type, capability_set_buffer) = match self {
433 CapabilitySet::Control(buffer) => (CapabilitySetType::Control, buffer),
434 CapabilitySet::WindowActivation(buffer) => (CapabilitySetType::WindowActivation, buffer),
435 CapabilitySet::Share(buffer) => (CapabilitySetType::Share, buffer),
436 CapabilitySet::Font(buffer) => (CapabilitySetType::Font, buffer),
437 CapabilitySet::BitmapCacheHostSupport(buffer) => {
438 (CapabilitySetType::BitmapCacheHostSupport, buffer)
439 }
440 CapabilitySet::DesktopComposition(buffer) => (CapabilitySetType::DesktopComposition, buffer),
441 CapabilitySet::ColorCache(buffer) => (CapabilitySetType::ColorCache, buffer),
442 CapabilitySet::DrawNineGridCache(buffer) => (CapabilitySetType::DrawNineGridCache, buffer),
443 CapabilitySet::DrawGdiPlus(buffer) => (CapabilitySetType::DrawGdiPlus, buffer),
444 CapabilitySet::Rail(buffer) => (CapabilitySetType::Rail, buffer),
445 CapabilitySet::WindowList(buffer) => (CapabilitySetType::WindowList, buffer),
446 _ => unreachable!(),
447 };
448
449 dst.write_u16(capability_set_type.to_u16().unwrap());
450 dst.write_u16(cast_length!(
451 "len",
452 capability_set_buffer.len() + CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE
453 )?);
454 dst.write_slice(capability_set_buffer);
455 }
456 };
457 Ok(())
458 }
459
460 fn name(&self) -> &'static str {
461 Self::NAME
462 }
463
464 fn size(&self) -> usize {
465 Self::FIXED_PART_SIZE
466 + match self {
467 CapabilitySet::General(capset) => capset.size(),
468 CapabilitySet::Bitmap(capset) => capset.size(),
469 CapabilitySet::Order(capset) => capset.size(),
470 CapabilitySet::BitmapCache(capset) => capset.size(),
471 CapabilitySet::BitmapCacheRev2(capset) => capset.size(),
472 CapabilitySet::Pointer(capset) => capset.size(),
473 CapabilitySet::Sound(capset) => capset.size(),
474 CapabilitySet::Input(capset) => capset.size(),
475 CapabilitySet::Brush(capset) => capset.size(),
476 CapabilitySet::GlyphCache(capset) => capset.size(),
477 CapabilitySet::OffscreenBitmapCache(capset) => capset.size(),
478 CapabilitySet::VirtualChannel(capset) => capset.size(),
479 CapabilitySet::SurfaceCommands(capset) => capset.size(),
480 CapabilitySet::BitmapCodecs(capset) => capset.size(),
481 CapabilitySet::MultiFragmentUpdate(capset) => capset.size(),
482 CapabilitySet::LargePointer(capset) => capset.size(),
483 CapabilitySet::FrameAcknowledge(capset) => capset.size(),
484 CapabilitySet::Control(buffer)
485 | CapabilitySet::WindowActivation(buffer)
486 | CapabilitySet::Share(buffer)
487 | CapabilitySet::Font(buffer)
488 | CapabilitySet::BitmapCacheHostSupport(buffer)
489 | CapabilitySet::DesktopComposition(buffer)
490 | CapabilitySet::ColorCache(buffer)
491 | CapabilitySet::DrawNineGridCache(buffer)
492 | CapabilitySet::DrawGdiPlus(buffer)
493 | CapabilitySet::Rail(buffer)
494 | CapabilitySet::WindowList(buffer)
495 | CapabilitySet::BitmapCacheV3(buffer) => buffer.len(),
496 }
497 }
498}
499
500impl<'de> Decode<'de> for CapabilitySet {
501 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
502 ensure_fixed_part_size!(in: src);
503
504 let capability_set_type_raw = src.read_u16();
505 let capability_set_type = CapabilitySetType::from_u16(capability_set_type_raw).ok_or_else(|| {
506 unsupported_value_err!(
507 "capabilitySetType",
508 format!("invalid capability set type: {}", capability_set_type_raw)
509 )
510 })?;
511
512 let length = src.read_u16() as usize;
513
514 if length < CAPABILITY_SET_TYPE_FIELD_SIZE + CAPABILITY_SET_LENGTH_FIELD_SIZE {
515 return Err(invalid_field_err!("len", "invalid capability set length"));
516 }
517
518 let buffer_length = length - CAPABILITY_SET_TYPE_FIELD_SIZE - CAPABILITY_SET_LENGTH_FIELD_SIZE;
519 ensure_size!(in: src, size: buffer_length);
520 let capability_set_buffer = src.read_slice(buffer_length);
521
522 match capability_set_type {
523 CapabilitySetType::General => Ok(CapabilitySet::General(decode(capability_set_buffer)?)),
524 CapabilitySetType::Bitmap => Ok(CapabilitySet::Bitmap(decode(capability_set_buffer)?)),
525 CapabilitySetType::Order => Ok(CapabilitySet::Order(decode(capability_set_buffer)?)),
526 CapabilitySetType::BitmapCache => Ok(CapabilitySet::BitmapCache(decode(capability_set_buffer)?)),
527 CapabilitySetType::BitmapCacheRev2 => Ok(CapabilitySet::BitmapCacheRev2(decode(capability_set_buffer)?)),
528 CapabilitySetType::Pointer => Ok(CapabilitySet::Pointer(decode(capability_set_buffer)?)),
529 CapabilitySetType::Sound => Ok(CapabilitySet::Sound(decode(capability_set_buffer)?)),
530 CapabilitySetType::Input => Ok(CapabilitySet::Input(decode(capability_set_buffer)?)),
531 CapabilitySetType::Brush => Ok(CapabilitySet::Brush(decode(capability_set_buffer)?)),
532 CapabilitySetType::GlyphCache => Ok(CapabilitySet::GlyphCache(decode(capability_set_buffer)?)),
533 CapabilitySetType::OffscreenBitmapCache => {
534 Ok(CapabilitySet::OffscreenBitmapCache(decode(capability_set_buffer)?))
535 }
536 CapabilitySetType::VirtualChannel => Ok(CapabilitySet::VirtualChannel(decode(capability_set_buffer)?)),
537 CapabilitySetType::SurfaceCommands => Ok(CapabilitySet::SurfaceCommands(decode(capability_set_buffer)?)),
538 CapabilitySetType::BitmapCodecs => Ok(CapabilitySet::BitmapCodecs(decode(capability_set_buffer)?)),
539
540 CapabilitySetType::Control => Ok(CapabilitySet::Control(capability_set_buffer.into())),
541 CapabilitySetType::WindowActivation => Ok(CapabilitySet::WindowActivation(capability_set_buffer.into())),
542 CapabilitySetType::Share => Ok(CapabilitySet::Share(capability_set_buffer.into())),
543 CapabilitySetType::Font => Ok(CapabilitySet::Font(capability_set_buffer.into())),
544 CapabilitySetType::BitmapCacheHostSupport => {
545 Ok(CapabilitySet::BitmapCacheHostSupport(capability_set_buffer.into()))
546 }
547 CapabilitySetType::DesktopComposition => {
548 Ok(CapabilitySet::DesktopComposition(capability_set_buffer.into()))
549 }
550 CapabilitySetType::MultiFragmentUpdate => {
551 Ok(CapabilitySet::MultiFragmentUpdate(decode(capability_set_buffer)?))
552 }
553 CapabilitySetType::LargePointer => Ok(CapabilitySet::LargePointer(decode(capability_set_buffer)?)),
554 CapabilitySetType::ColorCache => Ok(CapabilitySet::ColorCache(capability_set_buffer.into())),
555 CapabilitySetType::DrawNineGridCache => Ok(CapabilitySet::DrawNineGridCache(capability_set_buffer.into())),
556 CapabilitySetType::DrawGdiPlus => Ok(CapabilitySet::DrawGdiPlus(capability_set_buffer.into())),
557 CapabilitySetType::Rail => Ok(CapabilitySet::Rail(capability_set_buffer.into())),
558 CapabilitySetType::WindowList => Ok(CapabilitySet::WindowList(capability_set_buffer.into())),
559 CapabilitySetType::FrameAcknowledge => Ok(CapabilitySet::FrameAcknowledge(decode(capability_set_buffer)?)),
560 CapabilitySetType::BitmapCacheV3CodecID => Ok(CapabilitySet::BitmapCacheV3(capability_set_buffer.into())),
561 }
562 }
563}
564
565#[derive(Copy, Clone, Debug, FromPrimitive, ToPrimitive)]
566enum CapabilitySetType {
567 General = 0x01,
568 Bitmap = 0x02,
569 Order = 0x03,
570 BitmapCache = 0x04,
571 Control = 0x05,
572 BitmapCacheV3CodecID = 0x06,
573 WindowActivation = 0x07,
574 Pointer = 0x08,
575 Share = 0x09,
576 ColorCache = 0x0a,
577 Sound = 0x0c,
578 Input = 0x0d,
579 Font = 0x0e,
580 Brush = 0x0f,
581 GlyphCache = 0x10,
582 OffscreenBitmapCache = 0x11,
583 BitmapCacheHostSupport = 0x12,
584 BitmapCacheRev2 = 0x13,
585 VirtualChannel = 0x14,
586 DrawNineGridCache = 0x15,
587 DrawGdiPlus = 0x16,
588 Rail = 0x17,
589 WindowList = 0x18,
590 DesktopComposition = 0x19,
591 MultiFragmentUpdate = 0x1a,
592 LargePointer = 0x1b,
593 SurfaceCommands = 0x1c,
594 BitmapCodecs = 0x1d,
595 FrameAcknowledge = 0x1e,
596}
597
598#[derive(Debug, Error)]
599pub enum CapabilitySetsError {
600 #[error("IO error")]
601 IOError(#[from] io::Error),
602 #[error("UTF-8 error")]
603 Utf8Error(#[from] std::string::FromUtf8Error),
604 #[error("invalid type field")]
605 InvalidType,
606 #[error("invalid bitmap compression field")]
607 InvalidCompressionFlag,
608 #[error("invalid multiple rectangle support field")]
609 InvalidMultipleRectSupport,
610 #[error("invalid protocol version field")]
611 InvalidProtocolVersion,
612 #[error("invalid compression types field")]
613 InvalidCompressionTypes,
614 #[error("invalid update capability flags field")]
615 InvalidUpdateCapFlag,
616 #[error("invalid remote unshare flag field")]
617 InvalidRemoteUnshareFlag,
618 #[error("invalid compression level field")]
619 InvalidCompressionLevel,
620 #[error("invalid brush support level field")]
621 InvalidBrushSupportLevel,
622 #[error("invalid glyph support level field")]
623 InvalidGlyphSupportLevel,
624 #[error("invalid RemoteFX capability version")]
625 InvalidRfxICapVersion,
626 #[error("invalid RemoteFX capability tile size")]
627 InvalidRfxICapTileSize,
628 #[error("invalid RemoteFXICap color conversion bits")]
629 InvalidRfxICapColorConvBits,
630 #[error("invalid RemoteFXICap transform bits")]
631 InvalidRfxICapTransformBits,
632 #[error("invalid RemoteFXICap entropy bits field")]
633 InvalidRfxICapEntropyBits,
634 #[error("invalid RemoteFX capability set block type")]
635 InvalidRfxCapsetBlockType,
636 #[error("invalid RemoteFX capability set type")]
637 InvalidRfxCapsetType,
638 #[error("invalid RemoteFX capabilities block type")]
639 InvalidRfxCapsBlockType,
640 #[error("invalid RemoteFX capabilities block length")]
641 InvalidRfxCapsBockLength,
642 #[error("invalid number of capability sets in RemoteFX capabilities")]
643 InvalidRfxCapsNumCapsets,
644 #[error("invalid codec property field")]
645 InvalidCodecProperty,
646 #[error("invalid codec ID")]
647 InvalidCodecID,
648 #[error("invalid channel chunk size field")]
649 InvalidChunkSize,
650 #[error("invalid codec property length for the current property ID")]
651 InvalidPropertyLength,
652 #[error("invalid data length")]
653 InvalidLength,
654 #[error("PDU error: {0}")]
655 Pdu(PduError),
656}
657
658impl From<PduError> for CapabilitySetsError {
659 fn from(e: PduError) -> Self {
660 Self::Pdu(e)
661 }
662}