ironrdp_pdu/rdp/capability_sets/
bitmap_cache.rs

1#[cfg(test)]
2mod tests;
3
4use bitflags::bitflags;
5use ironrdp_core::{
6    ensure_fixed_part_size, read_padding, write_padding, Decode, DecodeResult, Encode, EncodeResult, ReadCursor,
7    WriteCursor,
8};
9
10pub const BITMAP_CACHE_ENTRIES_NUM: usize = 3;
11
12const BITMAP_CACHE_LENGTH: usize = 36;
13const BITMAP_CACHE_REV2_LENGTH: usize = 36;
14const CELL_INFO_LENGTH: usize = 4;
15const BITMAP_CACHE_REV2_CELL_INFO_NUM: usize = 5;
16const CACHE_ENTRY_LENGTH: usize = 4;
17
18#[derive(Debug, PartialEq, Eq, Clone)]
19pub struct BitmapCache {
20    pub caches: [CacheEntry; BITMAP_CACHE_ENTRIES_NUM],
21}
22
23impl BitmapCache {
24    const NAME: &'static str = "BitmapCache";
25
26    const FIXED_PART_SIZE: usize = BITMAP_CACHE_LENGTH;
27}
28
29impl Encode for BitmapCache {
30    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
31        ensure_fixed_part_size!(in: dst);
32
33        write_padding!(dst, 24);
34
35        for cache in self.caches.iter() {
36            cache.encode(dst)?;
37        }
38
39        Ok(())
40    }
41
42    fn name(&self) -> &'static str {
43        Self::NAME
44    }
45
46    fn size(&self) -> usize {
47        Self::FIXED_PART_SIZE
48    }
49}
50
51impl<'de> Decode<'de> for BitmapCache {
52    fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
53        ensure_fixed_part_size!(in: src);
54
55        read_padding!(src, 24);
56
57        let mut caches = [CacheEntry::default(); BITMAP_CACHE_ENTRIES_NUM];
58
59        for cache in caches.iter_mut() {
60            *cache = CacheEntry::decode(src)?;
61        }
62
63        Ok(BitmapCache { caches })
64    }
65}
66
67#[derive(Debug, PartialEq, Eq, Copy, Clone, Default)]
68pub struct CacheEntry {
69    pub entries: u16,
70    pub max_cell_size: u16,
71}
72
73impl CacheEntry {
74    const NAME: &'static str = "CacheEntry";
75
76    const FIXED_PART_SIZE: usize = CACHE_ENTRY_LENGTH;
77}
78
79impl Encode for CacheEntry {
80    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
81        ensure_fixed_part_size!(in: dst);
82
83        dst.write_u16(self.entries);
84        dst.write_u16(self.max_cell_size);
85
86        Ok(())
87    }
88
89    fn name(&self) -> &'static str {
90        Self::NAME
91    }
92
93    fn size(&self) -> usize {
94        Self::FIXED_PART_SIZE
95    }
96}
97
98impl<'de> Decode<'de> for CacheEntry {
99    fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
100        ensure_fixed_part_size!(in: src);
101
102        let entries = src.read_u16();
103        let max_cell_size = src.read_u16();
104
105        Ok(CacheEntry { entries, max_cell_size })
106    }
107}
108
109bitflags! {
110    #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
111    pub struct CacheFlags: u16 {
112        const PERSISTENT_KEYS_EXPECTED_FLAG = 1;
113        const ALLOW_CACHE_WAITING_LIST_FLAG = 2;
114    }
115}
116
117#[derive(Debug, PartialEq, Eq, Clone)]
118pub struct BitmapCacheRev2 {
119    pub cache_flags: CacheFlags,
120    pub num_cell_caches: u8,
121    pub cache_cell_info: [CellInfo; BITMAP_CACHE_REV2_CELL_INFO_NUM],
122}
123
124impl BitmapCacheRev2 {
125    const NAME: &'static str = "BitmapCacheRev2";
126
127    const FIXED_PART_SIZE: usize = BITMAP_CACHE_REV2_LENGTH;
128}
129
130impl Encode for BitmapCacheRev2 {
131    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
132        ensure_fixed_part_size!(in: dst);
133
134        dst.write_u16(self.cache_flags.bits());
135        write_padding!(dst, 1);
136        dst.write_u8(self.num_cell_caches);
137
138        for cell_info in self.cache_cell_info.iter() {
139            cell_info.encode(dst)?;
140        }
141
142        write_padding!(dst, 12);
143
144        Ok(())
145    }
146
147    fn name(&self) -> &'static str {
148        Self::NAME
149    }
150
151    fn size(&self) -> usize {
152        Self::FIXED_PART_SIZE
153    }
154}
155
156impl<'de> Decode<'de> for BitmapCacheRev2 {
157    fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
158        ensure_fixed_part_size!(in: src);
159
160        let cache_flags = CacheFlags::from_bits_truncate(src.read_u16());
161        let _padding = src.read_u8();
162        let num_cell_caches = src.read_u8();
163
164        let mut cache_cell_info = [CellInfo::default(); BITMAP_CACHE_REV2_CELL_INFO_NUM];
165
166        for cell in cache_cell_info.iter_mut() {
167            *cell = CellInfo::decode(src)?;
168        }
169
170        read_padding!(src, 12);
171
172        Ok(BitmapCacheRev2 {
173            cache_flags,
174            num_cell_caches,
175            cache_cell_info,
176        })
177    }
178}
179
180#[derive(Debug, PartialEq, Eq, Copy, Clone, Default)]
181pub struct CellInfo {
182    pub num_entries: u32,
183    pub is_cache_persistent: bool,
184}
185
186impl CellInfo {
187    const NAME: &'static str = "CellInfo";
188
189    const FIXED_PART_SIZE: usize = CELL_INFO_LENGTH;
190}
191
192impl Encode for CellInfo {
193    fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
194        ensure_fixed_part_size!(in: dst);
195
196        let mut data = self.num_entries;
197
198        if self.is_cache_persistent {
199            data |= 1 << 31;
200        }
201
202        dst.write_u32(data);
203
204        Ok(())
205    }
206
207    fn name(&self) -> &'static str {
208        Self::NAME
209    }
210
211    fn size(&self) -> usize {
212        Self::FIXED_PART_SIZE
213    }
214}
215
216impl<'de> Decode<'de> for CellInfo {
217    fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
218        ensure_fixed_part_size!(in: src);
219
220        let cell_info = src.read_u32();
221
222        let num_entries = cell_info & !(1 << 31);
223        let is_cache_persistent = cell_info >> 31 != 0;
224
225        Ok(CellInfo {
226            num_entries,
227            is_cache_persistent,
228        })
229    }
230}