rdp/core/capability.rs
1use model::data::{Component, U16, U32, DynOption, MessageOption, Message, DataType, Check, Trame, to_vec};
2use model::error::{RdpResult, Error, RdpError, RdpErrorKind};
3use std::io::Cursor;
4use core::gcc::{KeyboardLayout, KeyboardType};
5use num_enum::TryFromPrimitive;
6use std::convert::TryFrom;
7
8/// All capabilities that can be negotiated
9/// between client and server
10/// This is done by the global channel
11#[repr(u16)]
12#[derive(Eq, PartialEq, Hash, Debug, TryFromPrimitive)]
13pub enum CapabilitySetType {
14 CapstypeGeneral = 0x0001,
15 CapstypeBitmap = 0x0002,
16 CapstypeOrder = 0x0003,
17 CapstypeBitmapcache = 0x0004,
18 CapstypeControl = 0x0005,
19 CapstypeActivation = 0x0007,
20 CapstypePointer = 0x0008,
21 CapstypeShare = 0x0009,
22 CapstypeColorcache = 0x000A,
23 CapstypeSound = 0x000C,
24 CapstypeInput = 0x000D,
25 CapstypeFont = 0x000E,
26 CapstypeBrush = 0x000F,
27 CapstypeGlyphcache = 0x0010,
28 CapstypeOffscreencache = 0x0011,
29 CapstypeBitmapcacheHostsupport = 0x0012,
30 CapstypeBitmapcacheRev2 = 0x0013,
31 CapstypeVirtualchannel = 0x0014,
32 CapstypeDrawninegridcache = 0x0015,
33 CapstypeDrawgdiplus = 0x0016,
34 CapstypeRail = 0x0017,
35 CapstypeWindow = 0x0018,
36 CapsettypeCompdesk = 0x0019,
37 CapsettypeMultifragmentupdate = 0x001A,
38 CapsettypeLargePointer = 0x001B,
39 CapsettypeSurfaceCommands = 0x001C,
40 CapsettypeBitmapCodecs = 0x001D,
41 CapssettypeFrameAcknowledge = 0x001E
42}
43
44/// A capability
45/// Composed by a type and structured
46/// component
47///
48/// # Example
49/// ```rust, ignore
50/// use rdp::core::capability::{Capability, CapabilitySetType};
51/// let capability = Capability {
52/// cap_type: CapabilitySetType::CapstypePointer,
53/// message: component![
54/// "colorPointerFlag" => U16::LE(0),
55/// "colorPointerCacheSize" => U16::LE(20)
56/// ]
57/// };
58/// ```
59pub struct Capability {
60 pub cap_type: CapabilitySetType,
61 pub message: Component
62}
63
64impl Capability {
65 /// Parse the capability from a parent capability_set
66 ///
67 /// # Example
68 /// ```
69 /// #[macro_use]
70 /// # extern crate rdp;
71 /// # use rdp::model::data::{DataType};
72 /// # use rdp::model::error::{Error, RdpError, RdpResult, RdpErrorKind};
73 /// # use rdp::core::capability::{capability_set, ts_general_capability_set, Capability};
74 /// # fn main() {
75 /// let example = capability_set(Some(ts_general_capability_set(Some(4))));
76 /// let general_capability = Capability::from_capability_set(&example).unwrap();
77 /// assert_eq!(cast!(DataType::U16, general_capability.message["extraFlags"]).unwrap(), 4)
78 /// # }
79 /// ```
80 pub fn from_capability_set(capability_set: &Component) -> RdpResult<Capability> {
81 let cap_type = CapabilitySetType::try_from(cast!(DataType::U16, capability_set["capabilitySetType"])?)?;
82 let mut capability = match cap_type {
83 CapabilitySetType::CapstypeGeneral => ts_general_capability_set(None),
84 CapabilitySetType::CapstypeBitmap => ts_bitmap_capability_set(None, None, None),
85 CapabilitySetType::CapstypeOrder => ts_order_capability_set(None),
86 CapabilitySetType::CapstypeBitmapcache => ts_bitmap_cache_capability_set(),
87 CapabilitySetType::CapstypePointer => ts_pointer_capability_set(),
88 CapabilitySetType::CapstypeInput => ts_input_capability_set(None, None),
89 CapabilitySetType::CapstypeBrush => ts_brush_capability_set(),
90 CapabilitySetType::CapstypeGlyphcache => ts_glyph_capability_set(),
91 CapabilitySetType::CapstypeOffscreencache => ts_offscreen_capability_set(),
92 CapabilitySetType::CapstypeVirtualchannel => ts_virtualchannel_capability_set(),
93 CapabilitySetType::CapstypeSound => ts_sound_capability_set(),
94 CapabilitySetType::CapsettypeMultifragmentupdate => ts_multifragment_update_capability_ts(),
95 _ => {
96 return Err(Error::RdpError(RdpError::new(RdpErrorKind::Unknown, &format!("CAPABILITY: Unknown capability {:?}", cap_type))))
97 }
98 };
99 capability.message.read(&mut Cursor::new(cast!(DataType::Slice, capability_set["capabilitySet"])?))?;
100 Ok(capability)
101 }
102}
103
104/// General capability payload
105///
106/// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/d705c3b6-a392-4b32-9610-391f6af62323
107///
108/// # Example
109/// ```
110/// #[macro_use]
111/// # extern crate rdp;
112/// # use rdp::model::data::DataType;
113/// # use rdp::model::error::{Error, RdpError, RdpResult, RdpErrorKind};
114/// fn main() {
115/// use rdp::core::capability::{capability_set, ts_general_capability_set, CapabilitySetType};
116/// let capability_set = capability_set(Some(ts_general_capability_set(Some(2))));
117/// assert_eq!(cast!(DataType::U16, capability_set["capabilitySetType"]).unwrap(), CapabilitySetType::CapstypeGeneral as u16)
118/// }
119/// ```
120pub fn capability_set(capability: Option<Capability>) -> Component {
121 let default_capability = capability.unwrap_or(Capability{ cap_type: CapabilitySetType::CapstypeGeneral, message: component![]});
122 component![
123 "capabilitySetType" => U16::LE(default_capability.cap_type as u16),
124 "lengthCapability" => DynOption::new(U16::LE(default_capability.message.length() as u16 + 4), |length| MessageOption::Size("capabilitySet".to_string(), length.inner() as usize - 4)),
125 "capabilitySet" => to_vec(&default_capability.message)
126 ]
127}
128
129#[repr(u16)]
130#[allow(dead_code)]
131enum MajorType {
132 OsmajortypeUnspecified = 0x0000,
133 OsmajortypeWindows = 0x0001,
134 OsmajortypeOs2 = 0x0002,
135 OsmajortypeMacintosh = 0x0003,
136 OsmajortypeUnix = 0x0004,
137 OsmajortypeIos = 0x0005,
138 OsmajortypeOsx = 0x0006,
139 OsmajortypeAndroid = 0x0007
140}
141
142#[allow(dead_code)]
143enum MinorType {
144 OsminortypeUnspecified = 0x0000,
145 OsminortypeWindows31x = 0x0001,
146 OsminortypeWindows95 = 0x0002,
147 OsminortypeWindowsNt = 0x0003,
148 OsminortypeOs2V21 = 0x0004,
149 OsminortypePowerPc = 0x0005,
150 OsminortypeMacintosh = 0x0006,
151 OsminortypeNativeXserver = 0x0007,
152 OsminortypePseudoXserver = 0x0008,
153 OsminortypeWindowsRt = 0x0009
154}
155
156#[repr(u16)]
157pub enum GeneralExtraFlag {
158 FastpathOutputSupported = 0x0001,
159 NoBitmapCompressionHdr = 0x0400,
160 LongCredentialsSupported = 0x0004,
161 AutoreconnectSupported = 0x0008,
162 EncSaltedChecksum = 0x0010
163}
164
165/// General capability
166/// This capability is send by both side
167///
168/// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/41dc6845-07dc-4af6-bc14-d8281acd4877
169///
170/// # Example
171/// ```
172/// use rdp::core::capability::{capability_set, ts_general_capability_set};
173/// use rdp::model::data::to_vec;
174/// let capability_set = capability_set(Some(ts_general_capability_set(Some(8))));
175/// assert_eq!(to_vec(&capability_set), [1, 0, 24, 0, 1, 0, 3, 0, 0, 2, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0])
176/// ```
177pub fn ts_general_capability_set(extra_flags: Option<u16>) -> Capability {
178 Capability {
179 cap_type: CapabilitySetType::CapstypeGeneral,
180 message: component![
181 "osMajorType" => U16::LE(MajorType::OsmajortypeWindows as u16),
182 "osMinorType" => U16::LE(MinorType::OsminortypeWindowsNt as u16),
183 "protocolVersion" => Check::new(U16::LE(0x0200)),
184 "pad2octetsA" => U16::LE(0),
185 "generalCompressionTypes" => Check::new(U16::LE(0)),
186 "extraFlags" => U16::LE(extra_flags.unwrap_or(0)),
187 "updateCapabilityFlag" => Check::new(U16::LE(0)),
188 "remoteUnshareFlag" => Check::new(U16::LE(0)),
189 "generalCompressionLevel" => Check::new(U16::LE(0)),
190 "refreshRectSupport" => 0 as u8,
191 "suppressOutputSupport" => 0 as u8
192 ]
193 }
194}
195
196/// Bitmap capability
197/// Here we can set Bit per pixel
198/// Screen Size
199///
200/// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/76670547-e35c-4b95-a242-5729a21b83f6
201///
202/// # Example
203/// ```
204/// use rdp::core::capability::{capability_set, ts_bitmap_capability_set};
205/// use rdp::model::data::to_vec;
206/// let capability_set = capability_set(Some(ts_bitmap_capability_set(Some(24), Some(800), Some(600))));
207/// assert_eq!(to_vec(&capability_set), [2, 0, 28, 0, 24, 0, 1, 0, 1, 0, 1, 0, 32, 3, 88, 2, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0])
208/// ```
209pub fn ts_bitmap_capability_set(preferred_bits_per_pixel: Option<u16>, desktop_width: Option<u16>, desktop_height: Option<u16>) -> Capability {
210 Capability {
211 cap_type: CapabilitySetType::CapstypeBitmap,
212 message: component![
213 "preferredBitsPerPixel" => U16::LE(preferred_bits_per_pixel.unwrap_or(0)),
214 "receive1BitPerPixel" => Check::new(U16::LE(0x0001)),
215 "receive4BitsPerPixel" => Check::new(U16::LE(0x0001)),
216 "receive8BitsPerPixel" => Check::new(U16::LE(0x0001)),
217 "desktopWidth" => U16::LE(desktop_width.unwrap_or(0)),
218 "desktopHeight" => U16::LE(desktop_height.unwrap_or(0)),
219 "pad2octets" => U16::LE(0),
220 "desktopResizeFlag" => U16::LE(0),
221 "bitmapCompressionFlag" => Check::new(U16::LE(0x0001)),
222 "highColorFlags" => Check::new(0 as u8),
223 "drawingFlags" => 0 as u8,
224 "multipleRectangleSupport" => Check::new(U16::LE(0x0001)),
225 "pad2octetsB" => U16::LE(0)
226 ]
227 }
228}
229
230#[repr(u16)]
231#[allow(dead_code)]
232pub enum OrderFlag {
233 NEGOTIATEORDERSUPPORT = 0x0002,
234 ZEROBOUNDSDELTASSUPPORT = 0x0008,
235 COLORINDEXSUPPORT = 0x0020,
236 SOLIDPATTERNBRUSHONLY = 0x0040,
237 OrderflagsExtraFlags = 0x0080
238}
239
240/// Order capability
241/// Some graphical orders options
242///
243/// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/9f409c29-480c-4751-9665-510b8ffff294
244///
245/// # Example
246/// ```
247/// use rdp::core::capability::{capability_set, ts_order_capability_set};
248/// use rdp::model::data::to_vec;
249/// let capability_set = capability_set(Some(ts_order_capability_set(Some(24))));
250/// assert_eq!(to_vec(&capability_set), vec![3, 0, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 20, 0, 0, 0, 1, 0, 0, 0, 24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 132, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0])
251/// ```
252pub fn ts_order_capability_set(order_flags: Option<u16>) -> Capability {
253 Capability {
254 cap_type: CapabilitySetType::CapstypeOrder,
255 message: component![
256 "terminalDescriptor" => vec![0 as u8; 16],
257 "pad4octetsA" => U32::LE(0),
258 "desktopSaveXGranularity" => U16::LE(1),
259 "desktopSaveYGranularity" => U16::LE(20),
260 "pad2octetsA" => U16::LE(0),
261 "maximumOrderLevel" => U16::LE(1),
262 "numberFonts" => U16::LE(0),
263 "orderFlags" => U16::LE(order_flags.unwrap_or(OrderFlag::NEGOTIATEORDERSUPPORT as u16)),
264 "orderSupport" => vec![0 as u8; 32],
265 "textFlags" => U16::LE(0),
266 "orderSupportExFlags" => U16::LE(0),
267 "pad4octetsB" => U32::LE(0),
268 "desktopSaveSize" => U32::LE(480*480),
269 "pad2octetsC" => U16::LE(0),
270 "pad2octetsD" => U16::LE(0),
271 "textANSICodePage" => U16::LE(0),
272 "pad2octetsE" => U16::LE(0)
273 ]
274 }
275}
276
277/// Bitmap cache is use as an optimization
278///
279/// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/101d40a7-56c0-40e1-bcb9-1475ff63cb9d
280///
281/// # Example
282/// ```
283/// use rdp::core::capability::{capability_set, ts_bitmap_cache_capability_set};
284/// use rdp::model::data::to_vec;
285/// let capability_set = capability_set(Some(ts_bitmap_cache_capability_set()));
286/// assert_eq!(to_vec(&capability_set), vec![4, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
287/// ```
288pub fn ts_bitmap_cache_capability_set() -> Capability {
289 Capability {
290 cap_type: CapabilitySetType::CapstypeBitmapcache,
291 message: component![
292 "pad1" => U32::LE(0),
293 "pad2" => U32::LE(0),
294 "pad3" => U32::LE(0),
295 "pad4" => U32::LE(0),
296 "pad5" => U32::LE(0),
297 "pad6" => U32::LE(0),
298 "cache0Entries" => U16::LE(0),
299 "cache0MaximumCellSize" => U16::LE(0),
300 "cache1Entries" => U16::LE(0),
301 "cache1MaximumCellSize" => U16::LE(0),
302 "cache2Entries" => U16::LE(0),
303 "cache2MaximumCellSize" => U16::LE(0)
304 ]
305 }
306}
307
308/// Pointer capability
309/// send by both client and server
310///
311/// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/925e2c05-c13f-44b1-aa20-23082051fef9
312///
313/// # Example
314/// ```
315/// use rdp::core::capability::{capability_set, ts_pointer_capability_set};
316/// use rdp::model::data::to_vec;
317/// let capability_set = capability_set(Some(ts_pointer_capability_set()));
318/// assert_eq!(to_vec(&capability_set), vec![8, 0, 8, 0, 0, 0, 20, 0])
319/// ```
320pub fn ts_pointer_capability_set() -> Capability {
321 Capability {
322 cap_type: CapabilitySetType::CapstypePointer,
323 message: component![
324 "colorPointerFlag" => U16::LE(0),
325 "colorPointerCacheSize" => U16::LE(20)
326 ]
327 }
328}
329
330#[repr(u16)]
331pub enum InputFlags {
332 /// Raw Keyboard scancode
333 /// This is the most convenient way to send keyboard event
334 /// This fearture is supported by rdp-rs
335 InputFlagScancodes = 0x0001,
336 /// This is the extended mouse event
337 /// with more button code
338 /// This feature is supported by rdp-rs
339 InputFlagMousex = 0x0004,
340 /// The capability to send fastpath input
341 /// This feature is NOT supported by rdp-rs
342 InputFlagFastpathInput = 0x0008,
343 /// In order to send keyboard scancode
344 /// We can send directly UNICODE code of char
345 /// Usefull if we want to send script
346 /// This feature is supported by rdp-rs
347 InputFlagUnicode = 0x0010,
348 InputFlagFastpathInput2 = 0x0020,
349 InputFlagUnused1 = 0x0040,
350 InputFlagUnused2 = 0x0080,
351 /// Support of the mouse wheel
352 /// This feature is supported by rdp-rs
353 TsInputFlagMouseHwheel = 0x0100
354}
355
356/// Send input capability
357///
358/// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/b3bc76ae-9ee5-454f-b197-ede845ca69cc
359///
360/// # Example
361/// ```
362/// use rdp::core::capability::{capability_set, ts_input_capability_set, InputFlags};
363/// use rdp::model::data::to_vec;
364/// use rdp::core::gcc::KeyboardLayout;
365/// let capability_set = capability_set(Some(ts_input_capability_set(Some(InputFlags::InputFlagScancodes as u16), Some(KeyboardLayout::French))));
366/// assert_eq!(to_vec(&capability_set), vec![13, 0, 88, 0, 1, 0, 0, 0, 12, 4, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
367/// ```
368pub fn ts_input_capability_set(input_flags: Option<u16>, keyboard_layout: Option<KeyboardLayout>) -> Capability {
369 Capability {
370 cap_type: CapabilitySetType::CapstypeInput,
371 message: component![
372 "inputFlags" => U16::LE(input_flags.unwrap_or(0)),
373 "pad2octetsA" => U16::LE(0),
374 "keyboardLayout" => U32::LE(keyboard_layout.unwrap_or(KeyboardLayout::French) as u32),
375 "keyboardType" => U32::LE(KeyboardType::Ibm101102Keys as u32),
376 "keyboardSubType" => U32::LE(0),
377 "keyboardFunctionKey" => U32::LE(12),
378 "imeFileName" => vec![0 as u8; 64]
379 ]
380 }
381}
382
383/// Brush capability
384/// send from client to server
385///
386/// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/8b6a830f-3dde-4a84-9250-21ffa7d2e342
387/// # Example
388/// ```
389/// use rdp::core::capability::{capability_set, ts_brush_capability_set};
390/// use rdp::model::data::to_vec;
391/// use rdp::core::gcc::KeyboardLayout;
392/// let capability_set = capability_set(Some(ts_brush_capability_set()));
393/// assert_eq!(to_vec(&capability_set), vec![15, 0, 8, 0, 0, 0, 0, 0])
394/// ```
395pub fn ts_brush_capability_set() -> Capability {
396 Capability {
397 cap_type: CapabilitySetType::CapstypeBrush,
398 message: component![
399 "brushSupportLevel" => U32::LE(0)
400 ]
401 }
402}
403
404/// Glyph cache entry
405///
406/// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/cae26830-263c-4c1e-97c2-b561faded3d9
407fn cache_entry() -> Component {
408 component![
409 "cacheEntries" => U16::LE(0),
410 "cacheMaximumCellSize" => U16::LE(0)
411 ]
412}
413
414
415/// Glyph capability set
416/// send from client to server
417///
418/// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/8e292483-9b0f-43b9-be14-dc6cd07e1615
419///
420/// # Example
421/// ```
422/// use rdp::core::capability::{capability_set, ts_glyph_capability_set};
423/// use rdp::model::data::to_vec;
424/// use rdp::core::gcc::KeyboardLayout;
425/// let capability_set = capability_set(Some(ts_glyph_capability_set()));
426/// assert_eq!(to_vec(&capability_set), vec![16, 0, 52, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
427/// ```
428pub fn ts_glyph_capability_set() -> Capability {
429 Capability {
430 cap_type: CapabilitySetType::CapstypeGlyphcache,
431 message: component![
432 "glyphCache" => trame![
433 cache_entry(), cache_entry(), cache_entry(), cache_entry(), cache_entry(),
434 cache_entry(), cache_entry(), cache_entry(), cache_entry(), cache_entry()
435 ],
436 "fragCache" => U32::LE(0),
437 "glyphSupportLevel" => U16::LE(0),
438 "pad2octets" => U16::LE(0)
439 ]
440 }
441}
442
443/// Offscreen capability
444/// send from client to server
445///
446/// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/412fa921-2faa-4f1b-ab5f-242cdabc04f9
447///
448/// # Example
449/// ```
450/// use rdp::core::capability::{capability_set, ts_offscreen_capability_set};
451/// use rdp::model::data::to_vec;
452/// use rdp::core::gcc::KeyboardLayout;
453/// let capability_set = capability_set(Some(ts_offscreen_capability_set()));
454/// assert_eq!(to_vec(&capability_set), vec![17, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0])
455/// ```
456pub fn ts_offscreen_capability_set() -> Capability {
457 Capability {
458 cap_type: CapabilitySetType::CapstypeOffscreencache,
459 message: component![
460 "offscreenSupportLevel" => U32::LE(0),
461 "offscreenCacheSize" => U16::LE(0),
462 "offscreenCacheEntries" => U16::LE(0)
463 ]
464 }
465}
466
467/// Virtual channel capability
468/// send by both side (client server)
469///
470/// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/a8593178-80c0-4b80-876c-cb77e62cecfc
471///
472/// # Example
473/// ```
474/// use rdp::core::capability::{capability_set, ts_virtualchannel_capability_set};
475/// use rdp::model::data::to_vec;
476/// use rdp::core::gcc::KeyboardLayout;
477/// let capability_set = capability_set(Some(ts_virtualchannel_capability_set()));
478/// assert_eq!(to_vec(&capability_set), vec![20, 0, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0])
479/// ```
480pub fn ts_virtualchannel_capability_set() -> Capability {
481 Capability {
482 cap_type: CapabilitySetType::CapstypeVirtualchannel,
483 message: component![
484 "flags" => U32::LE(0),
485 "VCChunkSize" => Some(U32::LE(0))
486 ]
487 }
488}
489
490/// Sound capability
491/// send from client server
492///
493/// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/fadb6a2c-18fa-4fa7-a155-e970d9b1ac59
494///
495/// # Example
496/// ```
497/// use rdp::core::capability::{capability_set, ts_sound_capability_set};
498/// use rdp::model::data::to_vec;
499/// use rdp::core::gcc::KeyboardLayout;
500/// let capability_set = capability_set(Some(ts_sound_capability_set()));
501/// assert_eq!(to_vec(&capability_set), vec![12, 0, 8, 0, 0, 0, 0, 0])
502/// ```
503pub fn ts_sound_capability_set() -> Capability {
504 Capability {
505 cap_type: CapabilitySetType::CapstypeSound,
506 message: component![
507 "soundFlags" => U16::LE(0),
508 "pad2octetsA" => U16::LE(0)
509 ]
510 }
511}
512
513/// Multi fragment capability
514/// send by both side (client, server)
515///
516/// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/01717954-716a-424d-af35-28fb2b86df89
517///
518/// /// # Example
519/// ```
520/// use rdp::core::capability::{capability_set, ts_multifragment_update_capability_ts};
521/// use rdp::model::data::to_vec;
522/// use rdp::core::gcc::KeyboardLayout;
523/// let capability_set = capability_set(Some(ts_multifragment_update_capability_ts()));
524/// assert_eq!(to_vec(&capability_set), vec![26, 0, 8, 0, 0, 0, 0, 0])
525/// ```
526pub fn ts_multifragment_update_capability_ts() -> Capability {
527 Capability {
528 cap_type: CapabilitySetType::CapsettypeMultifragmentupdate,
529 message: component![
530 "MaxRequestSize" => U32::LE(0)
531 ]
532 }
533}