ironrdp_pdu/rdp/
capability_sets.rs

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/// [2.2.1.13.1] Server Demand Active PDU
67///
68/// [2.2.1.13.1]: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/a07abad1-38bb-4a1a-96c9-253e3d5440df
69#[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); // This field is ignored by the client
86
87        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/// [2.2.1.13.2] Client Confirm Active PDU
111///
112/// [2.2.1.13.2]: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/4c3c2710-0bf0-4c54-8e69-aff40ffcde66
113#[derive(Debug, Clone, PartialEq, Eq)]
114pub struct ClientConfirmActive {
115    /// According to [MSDN](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/4e9722c3-ad83-43f5-af5a-529f73d88b48),
116    /// this field MUST be set to [SERVER_CHANNEL_ID](constant.SERVER_CHANNEL_ID.html).
117    /// However, the Microsoft RDP client takes this value from a server's
118    /// [PduSource](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/73d01865-2eae-407f-9b2c-87e31daac471)
119    /// field of the [Server Demand Active PDU](https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/bd612af5-cb54-43a2-9646-438bc3ecf5db).
120    /// Therefore, checking the `originator_id` field is the responsibility of the user of the library.
121    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/// 2.2.1.13.1.1 Demand Active PDU Data (TS_DEMAND_ACTIVE_PDU)
161///
162/// [2.2.1.13.1.1]: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/bd612af5-cb54-43a2-9646-438bc3ecf5db
163#[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        // The combined size in bytes of the numberCapabilities, pad2Octets, and capabilitySets fields.
220        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    // mandatory
249    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    // optional
263    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    // other
275    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}