ironrdp_pdu/rdp/capability_sets/
order.rs1#[cfg(test)]
2mod tests;
3
4use bitflags::bitflags;
5use ironrdp_core::{ensure_fixed_part_size, Decode, DecodeResult, Encode, EncodeResult, ReadCursor, WriteCursor};
6
7const ORDER_LENGTH: usize = 84;
8const ORD_LEVEL_1_ORDERS: u16 = 1;
9const SUPPORT_ARRAY_LEN: usize = 32;
10const DESKTOP_SAVE_Y_GRAN_VAL: u16 = 20;
11
12#[derive(Copy, Clone)]
13pub enum OrderSupportIndex {
14 DstBlt = 0x00,
15 PatBlt = 0x01,
16 ScrBlt = 0x02,
17 MemBlt = 0x03,
18 Mem3Blt = 0x04,
19 DrawnInEGrid = 0x07,
20 LineTo = 0x08,
21 MultiDrawnInEGrid = 0x09,
22 SaveBitmap = 0x0B,
23 MultiDstBlt = 0x0F,
24 MultiPatBlt = 0x10,
25 MultiScrBlt = 0x11,
26 MultiOpaqueRect = 0x12,
27 Fast = 0x13,
28 PolygonSC = 0x14,
29 PolygonCB = 0x15,
30 Polyline = 0x16,
31 FastGlyph = 0x18,
32 EllipseSC = 0x19,
33 EllipseCB = 0x1A,
34 Index = 0x1B,
35}
36
37bitflags! {
38 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
39 pub struct OrderFlags: u16 {
40 const NEGOTIATE_ORDER_SUPPORT = 0x0002;
41 const ZERO_BOUNDS_DELTAS_SUPPORT = 0x0008;
42 const COLOR_INDEX_SUPPORT = 0x0020;
43 const SOLID_PATTERN_BRUSH_ONLY = 0x0040;
44 const ORDER_FLAGS_EXTRA_FLAGS = 0x0080;
45 }
46}
47
48bitflags! {
49 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
50 pub struct OrderSupportExFlags: u16 {
51 const CACHE_BITMAP_REV3_SUPPORT = 2;
52 const ALTSEC_FRAME_MARKER_SUPPORT = 4;
53 }
54}
55
56#[derive(Debug, PartialEq, Eq, Clone)]
57pub struct Order {
58 pub order_flags: OrderFlags,
59 order_support: [u8; SUPPORT_ARRAY_LEN],
60 pub order_support_ex_flags: OrderSupportExFlags,
61 pub desktop_save_size: u32,
62 pub text_ansi_code_page: u16,
63}
64
65impl Order {
66 const NAME: &'static str = "Order";
67
68 const FIXED_PART_SIZE: usize = ORDER_LENGTH;
69
70 pub fn new(
71 order_flags: OrderFlags,
72 order_support_ex_flags: OrderSupportExFlags,
73 desktop_save_size: u32,
74 text_ansi_code_page: u16,
75 ) -> Self {
76 Self {
77 order_flags,
78 order_support: [0; SUPPORT_ARRAY_LEN],
79 order_support_ex_flags,
80 desktop_save_size,
81 text_ansi_code_page,
82 }
83 }
84
85 pub fn set_support_flag(&mut self, flag: OrderSupportIndex, value: bool) {
86 self.order_support[flag as usize] = u8::from(value)
87 }
88
89 pub fn get_support_flag(&mut self, flag: OrderSupportIndex) -> bool {
90 self.order_support[flag as usize] == 1
91 }
92}
93
94impl Encode for Order {
95 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
96 ensure_fixed_part_size!(in: dst);
97
98 dst.write_u128(0);
99
100 dst.write_u32(0); dst.write_u16(1); dst.write_u16(DESKTOP_SAVE_Y_GRAN_VAL);
103 dst.write_u16(0); dst.write_u16(ORD_LEVEL_1_ORDERS); dst.write_u16(0); dst.write_u16(self.order_flags.bits());
107 dst.write_slice(&self.order_support);
108 dst.write_u16(0); dst.write_u16(self.order_support_ex_flags.bits());
110 dst.write_u32(0); dst.write_u32(self.desktop_save_size);
112 dst.write_u16(0); dst.write_u16(0); dst.write_u16(self.text_ansi_code_page);
115 dst.write_u16(0); Ok(())
118 }
119
120 fn name(&self) -> &'static str {
121 Self::NAME
122 }
123
124 fn size(&self) -> usize {
125 Self::FIXED_PART_SIZE
126 }
127}
128
129impl<'de> Decode<'de> for Order {
130 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
131 ensure_fixed_part_size!(in: src);
132
133 let _terminal_descriptor = src.read_u128();
134 let _padding = src.read_u32();
135 let _desktop_save_x_granularity = src.read_u16();
136 let _desktop_save_y_granularity = src.read_u16();
137 let _padding = src.read_u16();
138 let _max_order_level = src.read_u16();
139 let _num_fonts = src.read_u16();
140
141 let order_flags = OrderFlags::from_bits_truncate(src.read_u16());
142 let order_support = src.read_array();
143
144 let _text_flags = src.read_u16();
145
146 let order_support_ex_flags = OrderSupportExFlags::from_bits_truncate(src.read_u16());
147
148 let _padding = src.read_u32();
149 let desktop_save_size = src.read_u32();
150 let _padding = src.read_u16();
151 let _padding = src.read_u16();
152 let text_ansi_code_page = src.read_u16();
153 let _padding = src.read_u16();
154
155 Ok(Order {
156 order_flags,
157 order_support,
158 order_support_ex_flags,
159 desktop_save_size,
160 text_ansi_code_page,
161 })
162 }
163}