1use bitflags::bitflags;
2use ironrdp_core::{
3 cast_length, ensure_fixed_part_size, ensure_size, invalid_field_err, not_enough_bytes_err, other_err, read_padding,
4 write_padding, Decode, DecodeResult, Encode, EncodeResult, ReadCursor, WriteCursor,
5};
6use num_derive::{FromPrimitive, ToPrimitive};
7use num_traits::{FromPrimitive as _, ToPrimitive as _};
8
9use crate::codecs::rfx::FrameAcknowledgePdu;
10use crate::input::InputEventPdu;
11use crate::rdp::capability_sets::{ClientConfirmActive, ServerDemandActive};
12use crate::rdp::client_info;
13use crate::rdp::finalization_messages::{ControlPdu, FontPdu, MonitorLayoutPdu, SynchronizePdu};
14use crate::rdp::refresh_rectangle::RefreshRectanglePdu;
15use crate::rdp::server_error_info::ServerSetErrorInfoPdu;
16use crate::rdp::session_info::SaveSessionInfoPdu;
17use crate::rdp::suppress_output::SuppressOutputPdu;
18
19pub const BASIC_SECURITY_HEADER_SIZE: usize = 4;
20pub const SHARE_DATA_HEADER_COMPRESSION_MASK: u8 = 0xF;
21const SHARE_CONTROL_HEADER_MASK: u16 = 0xF;
22const SHARE_CONTROL_HEADER_SIZE: usize = 2 * 3 + 4;
23
24const PROTOCOL_VERSION: u16 = 0x10;
25
26const PADDING_FIELD_SIZE: usize = 1;
28const STREAM_ID_FIELD_SIZE: usize = 1;
29const UNCOMPRESSED_LENGTH_FIELD_SIZE: usize = 2;
30const PDU_TYPE_FIELD_SIZE: usize = 1;
31const COMPRESSION_TYPE_FIELD_SIZE: usize = 1;
32const COMPRESSED_LENGTH_FIELD_SIZE: usize = 2;
33
34#[derive(Debug, Clone, PartialEq, Eq)]
35pub struct BasicSecurityHeader {
36 pub flags: BasicSecurityHeaderFlags,
37}
38
39impl BasicSecurityHeader {
40 const NAME: &'static str = "BasicSecurityHeader";
41
42 pub const FIXED_PART_SIZE: usize = BASIC_SECURITY_HEADER_SIZE;
43}
44
45impl Encode for BasicSecurityHeader {
46 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
47 ensure_fixed_part_size!(in: dst);
48
49 dst.write_u16(self.flags.bits());
50 dst.write_u16(0); Ok(())
52 }
53
54 fn name(&self) -> &'static str {
55 Self::NAME
56 }
57
58 fn size(&self) -> usize {
59 Self::FIXED_PART_SIZE
60 }
61}
62
63impl<'de> Decode<'de> for BasicSecurityHeader {
64 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
65 ensure_fixed_part_size!(in: src);
66
67 let flags = BasicSecurityHeaderFlags::from_bits(src.read_u16())
68 .ok_or_else(|| invalid_field_err!("securityHeader", "invalid basic security header"))?;
69 let _flags_hi = src.read_u16(); Ok(Self { flags })
72 }
73}
74
75#[derive(Debug, Clone, PartialEq, Eq)]
76pub struct ShareControlHeader {
77 pub share_control_pdu: ShareControlPdu,
78 pub pdu_source: u16,
79 pub share_id: u32,
80}
81
82impl ShareControlHeader {
83 const NAME: &'static str = "ShareControlHeader";
84
85 const FIXED_PART_SIZE: usize = SHARE_CONTROL_HEADER_SIZE;
86}
87
88impl Encode for ShareControlHeader {
89 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
90 ensure_size!(in: dst, size: self.size());
91
92 let pdu_type_with_version = PROTOCOL_VERSION | self.share_control_pdu.share_header_type().to_u16().unwrap();
93
94 dst.write_u16(cast_length!(
95 "len",
96 self.share_control_pdu.size() + SHARE_CONTROL_HEADER_SIZE
97 )?);
98 dst.write_u16(pdu_type_with_version);
99 dst.write_u16(self.pdu_source);
100 dst.write_u32(self.share_id);
101
102 self.share_control_pdu.encode(dst)
103 }
104
105 fn name(&self) -> &'static str {
106 Self::NAME
107 }
108
109 fn size(&self) -> usize {
110 Self::FIXED_PART_SIZE + self.share_control_pdu.size()
111 }
112}
113
114impl<'de> Decode<'de> for ShareControlHeader {
115 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
116 ensure_fixed_part_size!(in: src);
117
118 let total_length = src.read_u16() as usize;
119 let pdu_type_with_version = src.read_u16();
120 let pdu_source = src.read_u16();
121 let share_id = src.read_u32();
122
123 let pdu_type = ShareControlPduType::from_u16(pdu_type_with_version & SHARE_CONTROL_HEADER_MASK)
124 .ok_or_else(|| invalid_field_err!("pdu_type", "invalid pdu type"))?;
125 let pdu_version = pdu_type_with_version & !SHARE_CONTROL_HEADER_MASK;
126 if pdu_version != PROTOCOL_VERSION {
127 return Err(invalid_field_err!("pdu_version", "invalid PDU version"));
128 }
129
130 let share_pdu = ShareControlPdu::from_type(src, pdu_type)?;
131 let header = Self {
132 share_control_pdu: share_pdu,
133 pdu_source,
134 share_id,
135 };
136
137 if pdu_type == ShareControlPduType::DataPdu {
138 let header_length = header.size();
142
143 if header_length != total_length {
144 if total_length < header_length {
145 return Err(not_enough_bytes_err!(total_length, header_length));
146 }
147
148 let padding = total_length - header_length;
149 ensure_size!(in: src, size: padding);
150 read_padding!(src, padding);
151 }
152 }
153
154 Ok(header)
155 }
156}
157
158#[derive(Debug, Clone, PartialEq, Eq)]
159pub enum ShareControlPdu {
160 ServerDemandActive(ServerDemandActive),
161 ClientConfirmActive(ClientConfirmActive),
162 Data(ShareDataHeader),
163 ServerDeactivateAll(ServerDeactivateAll),
164}
165
166impl ShareControlPdu {
167 const NAME: &'static str = "ShareControlPdu";
168
169 pub fn as_short_name(&self) -> &str {
170 match self {
171 ShareControlPdu::ServerDemandActive(_) => "Server Demand Active PDU",
172 ShareControlPdu::ClientConfirmActive(_) => "Client Confirm Active PDU",
173 ShareControlPdu::Data(_) => "Data PDU",
174 ShareControlPdu::ServerDeactivateAll(_) => "Server Deactivate All PDU",
175 }
176 }
177
178 pub fn share_header_type(&self) -> ShareControlPduType {
179 match self {
180 ShareControlPdu::ServerDemandActive(_) => ShareControlPduType::DemandActivePdu,
181 ShareControlPdu::ClientConfirmActive(_) => ShareControlPduType::ConfirmActivePdu,
182 ShareControlPdu::Data(_) => ShareControlPduType::DataPdu,
183 ShareControlPdu::ServerDeactivateAll(_) => ShareControlPduType::DeactivateAllPdu,
184 }
185 }
186
187 pub fn from_type(src: &mut ReadCursor<'_>, share_type: ShareControlPduType) -> DecodeResult<Self> {
188 match share_type {
189 ShareControlPduType::DemandActivePdu => {
190 Ok(ShareControlPdu::ServerDemandActive(ServerDemandActive::decode(src)?))
191 }
192 ShareControlPduType::ConfirmActivePdu => {
193 Ok(ShareControlPdu::ClientConfirmActive(ClientConfirmActive::decode(src)?))
194 }
195 ShareControlPduType::DataPdu => Ok(ShareControlPdu::Data(ShareDataHeader::decode(src)?)),
196 ShareControlPduType::DeactivateAllPdu => {
197 Ok(ShareControlPdu::ServerDeactivateAll(ServerDeactivateAll::decode(src)?))
198 }
199 _ => Err(invalid_field_err!("share_type", "unexpected share control PDU type")),
200 }
201 }
202}
203
204impl Encode for ShareControlPdu {
205 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
206 match self {
207 ShareControlPdu::ServerDemandActive(pdu) => pdu.encode(dst),
208 ShareControlPdu::ClientConfirmActive(pdu) => pdu.encode(dst),
209 ShareControlPdu::Data(share_data_header) => share_data_header.encode(dst),
210 ShareControlPdu::ServerDeactivateAll(deactivate_all) => deactivate_all.encode(dst),
211 }
212 }
213
214 fn name(&self) -> &'static str {
215 Self::NAME
216 }
217
218 fn size(&self) -> usize {
219 match self {
220 ShareControlPdu::ServerDemandActive(pdu) => pdu.size(),
221 ShareControlPdu::ClientConfirmActive(pdu) => pdu.size(),
222 ShareControlPdu::Data(share_data_header) => share_data_header.size(),
223 ShareControlPdu::ServerDeactivateAll(deactivate_all) => deactivate_all.size(),
224 }
225 }
226}
227
228#[derive(Debug, Clone, PartialEq, Eq)]
229pub struct ShareDataHeader {
230 pub share_data_pdu: ShareDataPdu,
231 pub stream_priority: StreamPriority,
232 pub compression_flags: CompressionFlags,
233 pub compression_type: client_info::CompressionType,
234}
235
236impl ShareDataHeader {
237 const NAME: &'static str = "ShareDataHeader";
238
239 const FIXED_PART_SIZE: usize = PADDING_FIELD_SIZE
240 + STREAM_ID_FIELD_SIZE
241 + UNCOMPRESSED_LENGTH_FIELD_SIZE
242 + PDU_TYPE_FIELD_SIZE
243 + COMPRESSION_TYPE_FIELD_SIZE
244 + COMPRESSED_LENGTH_FIELD_SIZE;
245}
246
247impl Encode for ShareDataHeader {
248 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
249 ensure_size!(in: dst, size: self.size());
250
251 if self.compression_flags.is_empty() {
252 let compression_flags_with_type = self.compression_flags.bits() | self.compression_type.to_u8().unwrap();
253
254 write_padding!(dst, 1);
255 dst.write_u8(self.stream_priority.to_u8().unwrap());
256 dst.write_u16(cast_length!(
257 "uncompressedLength",
258 self.share_data_pdu.size()
259 + PDU_TYPE_FIELD_SIZE
260 + COMPRESSION_TYPE_FIELD_SIZE
261 + COMPRESSED_LENGTH_FIELD_SIZE
262 )?);
263 dst.write_u8(self.share_data_pdu.share_header_type().to_u8().unwrap());
264 dst.write_u8(compression_flags_with_type);
265 dst.write_u16(0); self.share_data_pdu.encode(dst)
268 } else {
269 Err(other_err!("Compression is not implemented"))
270 }
271 }
272
273 fn name(&self) -> &'static str {
274 Self::NAME
275 }
276
277 fn size(&self) -> usize {
278 Self::FIXED_PART_SIZE + self.share_data_pdu.size()
279 }
280}
281
282impl<'de> Decode<'de> for ShareDataHeader {
283 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
284 ensure_fixed_part_size!(in: src);
285
286 read_padding!(src, 1);
287 let stream_priority = StreamPriority::from_u8(src.read_u8())
288 .ok_or_else(|| invalid_field_err!("streamPriority", "Invalid stream priority"))?;
289 let _uncompressed_length = src.read_u16();
290 let pdu_type = ShareDataPduType::from_u8(src.read_u8())
291 .ok_or_else(|| invalid_field_err!("pduType", "Invalid pdu type"))?;
292 let compression_flags_with_type = src.read_u8();
293
294 let compression_flags =
295 CompressionFlags::from_bits_truncate(compression_flags_with_type & !SHARE_DATA_HEADER_COMPRESSION_MASK);
296 let compression_type =
297 client_info::CompressionType::from_u8(compression_flags_with_type & SHARE_DATA_HEADER_COMPRESSION_MASK)
298 .ok_or_else(|| invalid_field_err!("compressionType", "Invalid compression type"))?;
299 let _compressed_length = src.read_u16();
300
301 let share_data_pdu = ShareDataPdu::from_type(src, pdu_type)?;
302
303 Ok(Self {
304 share_data_pdu,
305 stream_priority,
306 compression_flags,
307 compression_type,
308 })
309 }
310}
311
312#[derive(Debug, Clone, PartialEq, Eq)]
313pub enum ShareDataPdu {
314 Synchronize(SynchronizePdu),
315 Control(ControlPdu),
316 FontList(FontPdu),
317 FontMap(FontPdu),
318 MonitorLayout(MonitorLayoutPdu),
319 SaveSessionInfo(SaveSessionInfoPdu),
320 FrameAcknowledge(FrameAcknowledgePdu),
321 ServerSetErrorInfo(ServerSetErrorInfoPdu),
322 Input(InputEventPdu),
323 ShutdownRequest,
324 ShutdownDenied,
325 SuppressOutput(SuppressOutputPdu),
326 RefreshRectangle(RefreshRectanglePdu),
327 Update(Vec<u8>),
328 Pointer(Vec<u8>),
329 PlaySound(Vec<u8>),
330 SetKeyboardIndicators(Vec<u8>),
331 BitmapCachePersistentList(Vec<u8>),
332 BitmapCacheErrorPdu(Vec<u8>),
333 SetKeyboardImeStatus(Vec<u8>),
334 OffscreenCacheErrorPdu(Vec<u8>),
335 DrawNineGridErrorPdu(Vec<u8>),
336 DrawGdiPusErrorPdu(Vec<u8>),
337 ArcStatusPdu(Vec<u8>),
338 StatusInfoPdu(Vec<u8>),
339}
340
341impl ShareDataPdu {
342 const NAME: &'static str = "ShareDataPdu";
343
344 pub fn as_short_name(&self) -> &str {
345 match self {
346 ShareDataPdu::Synchronize(_) => "Synchronize PDU",
347 ShareDataPdu::Control(_) => "Control PDU",
348 ShareDataPdu::FontList(_) => "FontList PDU",
349 ShareDataPdu::FontMap(_) => "Font Map PDU",
350 ShareDataPdu::MonitorLayout(_) => "Monitor Layout PDU",
351 ShareDataPdu::SaveSessionInfo(_) => "Save session info PDU",
352 ShareDataPdu::FrameAcknowledge(_) => "Frame Acknowledge PDU",
353 ShareDataPdu::ServerSetErrorInfo(_) => "Server Set Error Info PDU",
354 ShareDataPdu::Input(_) => "Server Input PDU",
355 ShareDataPdu::ShutdownRequest => "Shutdown Request PDU",
356 ShareDataPdu::ShutdownDenied => "Shutdown Denied PDU",
357 ShareDataPdu::SuppressOutput(_) => "Suppress Output PDU",
358 ShareDataPdu::RefreshRectangle(_) => "Refresh Rectangle PDU",
359 ShareDataPdu::Update(_) => "Update PDU",
360 ShareDataPdu::Pointer(_) => "Pointer PDU",
361 ShareDataPdu::PlaySound(_) => "Play Sound PDU",
362 ShareDataPdu::SetKeyboardIndicators(_) => "Set Keyboard Indicators PDU",
363 ShareDataPdu::BitmapCachePersistentList(_) => "Bitmap Cache Persistent List PDU",
364 ShareDataPdu::BitmapCacheErrorPdu(_) => "Bitmap Cache Error PDU",
365 ShareDataPdu::SetKeyboardImeStatus(_) => "Set Keyboard IME Status PDU",
366 ShareDataPdu::OffscreenCacheErrorPdu(_) => "Offscreen Cache Error PDU",
367 ShareDataPdu::DrawNineGridErrorPdu(_) => "Draw Nine Grid Error PDU",
368 ShareDataPdu::DrawGdiPusErrorPdu(_) => "Draw GDI PUS Error PDU",
369 ShareDataPdu::ArcStatusPdu(_) => "Arc Status PDU",
370 ShareDataPdu::StatusInfoPdu(_) => "Status Info PDU",
371 }
372 }
373
374 pub fn share_header_type(&self) -> ShareDataPduType {
375 match self {
376 ShareDataPdu::Synchronize(_) => ShareDataPduType::Synchronize,
377 ShareDataPdu::Control(_) => ShareDataPduType::Control,
378 ShareDataPdu::FontList(_) => ShareDataPduType::FontList,
379 ShareDataPdu::FontMap(_) => ShareDataPduType::FontMap,
380 ShareDataPdu::MonitorLayout(_) => ShareDataPduType::MonitorLayoutPdu,
381 ShareDataPdu::SaveSessionInfo(_) => ShareDataPduType::SaveSessionInfo,
382 ShareDataPdu::FrameAcknowledge(_) => ShareDataPduType::FrameAcknowledgePdu,
383 ShareDataPdu::ServerSetErrorInfo(_) => ShareDataPduType::SetErrorInfoPdu,
384 ShareDataPdu::Input(_) => ShareDataPduType::Input,
385 ShareDataPdu::ShutdownRequest => ShareDataPduType::ShutdownRequest,
386 ShareDataPdu::ShutdownDenied => ShareDataPduType::ShutdownDenied,
387 ShareDataPdu::SuppressOutput(_) => ShareDataPduType::SuppressOutput,
388 ShareDataPdu::RefreshRectangle(_) => ShareDataPduType::RefreshRectangle,
389 ShareDataPdu::Update(_) => ShareDataPduType::Update,
390 ShareDataPdu::Pointer(_) => ShareDataPduType::Pointer,
391 ShareDataPdu::PlaySound(_) => ShareDataPduType::PlaySound,
392 ShareDataPdu::SetKeyboardIndicators(_) => ShareDataPduType::SetKeyboardIndicators,
393 ShareDataPdu::BitmapCachePersistentList(_) => ShareDataPduType::BitmapCachePersistentList,
394 ShareDataPdu::BitmapCacheErrorPdu(_) => ShareDataPduType::BitmapCacheErrorPdu,
395 ShareDataPdu::SetKeyboardImeStatus(_) => ShareDataPduType::SetKeyboardImeStatus,
396 ShareDataPdu::OffscreenCacheErrorPdu(_) => ShareDataPduType::OffscreenCacheErrorPdu,
397 ShareDataPdu::DrawNineGridErrorPdu(_) => ShareDataPduType::DrawNineGridErrorPdu,
398 ShareDataPdu::DrawGdiPusErrorPdu(_) => ShareDataPduType::DrawGdiPusErrorPdu,
399 ShareDataPdu::ArcStatusPdu(_) => ShareDataPduType::ArcStatusPdu,
400 ShareDataPdu::StatusInfoPdu(_) => ShareDataPduType::StatusInfoPdu,
401 }
402 }
403
404 fn from_type(src: &mut ReadCursor<'_>, share_type: ShareDataPduType) -> DecodeResult<Self> {
405 match share_type {
406 ShareDataPduType::Synchronize => Ok(ShareDataPdu::Synchronize(SynchronizePdu::decode(src)?)),
407 ShareDataPduType::Control => Ok(ShareDataPdu::Control(ControlPdu::decode(src)?)),
408 ShareDataPduType::FontList => Ok(ShareDataPdu::FontList(FontPdu::decode(src)?)),
409 ShareDataPduType::FontMap => Ok(ShareDataPdu::FontMap(FontPdu::decode(src)?)),
410 ShareDataPduType::MonitorLayoutPdu => Ok(ShareDataPdu::MonitorLayout(MonitorLayoutPdu::decode(src)?)),
411 ShareDataPduType::SaveSessionInfo => Ok(ShareDataPdu::SaveSessionInfo(SaveSessionInfoPdu::decode(src)?)),
412 ShareDataPduType::FrameAcknowledgePdu => {
413 Ok(ShareDataPdu::FrameAcknowledge(FrameAcknowledgePdu::decode(src)?))
414 }
415 ShareDataPduType::SetErrorInfoPdu => {
416 Ok(ShareDataPdu::ServerSetErrorInfo(ServerSetErrorInfoPdu::decode(src)?))
417 }
418 ShareDataPduType::Input => Ok(ShareDataPdu::Input(InputEventPdu::decode(src)?)),
419 ShareDataPduType::ShutdownRequest => Ok(ShareDataPdu::ShutdownRequest),
420 ShareDataPduType::ShutdownDenied => Ok(ShareDataPdu::ShutdownDenied),
421 ShareDataPduType::SuppressOutput => Ok(ShareDataPdu::SuppressOutput(SuppressOutputPdu::decode(src)?)),
422 ShareDataPduType::RefreshRectangle => Ok(ShareDataPdu::RefreshRectangle(RefreshRectanglePdu::decode(src)?)),
423 ShareDataPduType::Update => Ok(ShareDataPdu::Update(src.remaining().to_vec())),
424 ShareDataPduType::Pointer => Ok(ShareDataPdu::Pointer(src.remaining().to_vec())),
425 ShareDataPduType::PlaySound => Ok(ShareDataPdu::PlaySound(src.remaining().to_vec())),
426 ShareDataPduType::SetKeyboardIndicators => {
427 Ok(ShareDataPdu::SetKeyboardIndicators(src.remaining().to_vec()))
428 }
429 ShareDataPduType::BitmapCachePersistentList => {
430 Ok(ShareDataPdu::BitmapCachePersistentList(src.remaining().to_vec()))
431 }
432 ShareDataPduType::BitmapCacheErrorPdu => Ok(ShareDataPdu::BitmapCacheErrorPdu(src.remaining().to_vec())),
433 ShareDataPduType::SetKeyboardImeStatus => Ok(ShareDataPdu::SetKeyboardImeStatus(src.remaining().to_vec())),
434 ShareDataPduType::OffscreenCacheErrorPdu => {
435 Ok(ShareDataPdu::OffscreenCacheErrorPdu(src.remaining().to_vec()))
436 }
437 ShareDataPduType::DrawNineGridErrorPdu => Ok(ShareDataPdu::DrawNineGridErrorPdu(src.remaining().to_vec())),
438 ShareDataPduType::DrawGdiPusErrorPdu => Ok(ShareDataPdu::DrawGdiPusErrorPdu(src.remaining().to_vec())),
439 ShareDataPduType::ArcStatusPdu => Ok(ShareDataPdu::ArcStatusPdu(src.remaining().to_vec())),
440 ShareDataPduType::StatusInfoPdu => Ok(ShareDataPdu::StatusInfoPdu(src.remaining().to_vec())),
441 }
442 }
443}
444
445impl Encode for ShareDataPdu {
446 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
447 match self {
448 ShareDataPdu::Synchronize(pdu) => pdu.encode(dst),
449 ShareDataPdu::Control(pdu) => pdu.encode(dst),
450 ShareDataPdu::FontList(pdu) | ShareDataPdu::FontMap(pdu) => pdu.encode(dst),
451 ShareDataPdu::MonitorLayout(pdu) => pdu.encode(dst),
452 ShareDataPdu::SaveSessionInfo(pdu) => pdu.encode(dst),
453 ShareDataPdu::FrameAcknowledge(pdu) => pdu.encode(dst),
454 ShareDataPdu::ServerSetErrorInfo(pdu) => pdu.encode(dst),
455 ShareDataPdu::Input(pdu) => pdu.encode(dst),
456 ShareDataPdu::ShutdownRequest | ShareDataPdu::ShutdownDenied => Ok(()),
457 ShareDataPdu::SuppressOutput(pdu) => pdu.encode(dst),
458 ShareDataPdu::RefreshRectangle(pdu) => pdu.encode(dst),
459 _ => Err(other_err!("Encoding not implemented")),
460 }
461 }
462
463 fn name(&self) -> &'static str {
464 Self::NAME
465 }
466
467 fn size(&self) -> usize {
468 match self {
469 ShareDataPdu::Synchronize(pdu) => pdu.size(),
470 ShareDataPdu::Control(pdu) => pdu.size(),
471 ShareDataPdu::FontList(pdu) | ShareDataPdu::FontMap(pdu) => pdu.size(),
472 ShareDataPdu::MonitorLayout(pdu) => pdu.size(),
473 ShareDataPdu::SaveSessionInfo(pdu) => pdu.size(),
474 ShareDataPdu::FrameAcknowledge(pdu) => pdu.size(),
475 ShareDataPdu::ServerSetErrorInfo(pdu) => pdu.size(),
476 ShareDataPdu::Input(pdu) => pdu.size(),
477 ShareDataPdu::ShutdownRequest | ShareDataPdu::ShutdownDenied => 0,
478 ShareDataPdu::SuppressOutput(pdu) => pdu.size(),
479 ShareDataPdu::RefreshRectangle(pdu) => pdu.size(),
480 ShareDataPdu::Update(buffer)
481 | ShareDataPdu::Pointer(buffer)
482 | ShareDataPdu::PlaySound(buffer)
483 | ShareDataPdu::SetKeyboardIndicators(buffer)
484 | ShareDataPdu::BitmapCachePersistentList(buffer)
485 | ShareDataPdu::BitmapCacheErrorPdu(buffer)
486 | ShareDataPdu::SetKeyboardImeStatus(buffer)
487 | ShareDataPdu::OffscreenCacheErrorPdu(buffer)
488 | ShareDataPdu::DrawNineGridErrorPdu(buffer)
489 | ShareDataPdu::DrawGdiPusErrorPdu(buffer)
490 | ShareDataPdu::ArcStatusPdu(buffer)
491 | ShareDataPdu::StatusInfoPdu(buffer) => buffer.len(),
492 }
493 }
494}
495
496bitflags! {
497 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
498 pub struct BasicSecurityHeaderFlags: u16 {
499 const EXCHANGE_PKT = 0x0001;
500 const TRANSPORT_REQ = 0x0002;
501 const TRANSPORT_RSP = 0x0004;
502 const ENCRYPT = 0x0008;
503 const RESET_SEQNO = 0x0010;
504 const IGNORE_SEQNO = 0x0020;
505 const INFO_PKT = 0x0040;
506 const LICENSE_PKT = 0x0080;
507 const LICENSE_ENCRYPT_CS = 0x0100;
508 const LICENSE_ENCRYPT_SC = 0x0200;
509 const REDIRECTION_PKT = 0x0400;
510 const SECURE_CHECKSUM = 0x0800;
511 const AUTODETECT_REQ = 0x1000;
512 const AUTODETECT_RSP = 0x2000;
513 const HEARTBEAT = 0x4000;
514 const FLAGSHI_VALID = 0x8000;
515 }
516}
517
518#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
519pub enum StreamPriority {
520 Undefined = 0,
521 Low = 1,
522 Medium = 2,
523 High = 4,
524}
525
526#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
527pub enum ShareControlPduType {
528 DemandActivePdu = 0x1,
529 ConfirmActivePdu = 0x3,
530 DeactivateAllPdu = 0x6,
531 DataPdu = 0x7,
532 ServerRedirect = 0xa,
533}
534
535#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
536#[repr(u8)]
537pub enum ShareDataPduType {
538 Update = 0x02,
539 Control = 0x14,
540 Pointer = 0x1b,
541 Input = 0x1c,
542 Synchronize = 0x1f,
543 RefreshRectangle = 0x21,
544 PlaySound = 0x22,
545 SuppressOutput = 0x23,
546 ShutdownRequest = 0x24,
547 ShutdownDenied = 0x25,
548 SaveSessionInfo = 0x26,
549 FontList = 0x27,
550 FontMap = 0x28,
551 SetKeyboardIndicators = 0x29,
552 BitmapCachePersistentList = 0x2b,
553 BitmapCacheErrorPdu = 0x2c,
554 SetKeyboardImeStatus = 0x2d,
555 OffscreenCacheErrorPdu = 0x2e,
556 SetErrorInfoPdu = 0x2f,
557 DrawNineGridErrorPdu = 0x30,
558 DrawGdiPusErrorPdu = 0x31,
559 ArcStatusPdu = 0x32,
560 StatusInfoPdu = 0x36,
561 MonitorLayoutPdu = 0x37,
562 FrameAcknowledgePdu = 0x38,
563}
564
565bitflags! {
566 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
567 pub struct CompressionFlags: u8 {
568 const COMPRESSED = 0x20;
569 const AT_FRONT = 0x40;
570 const FLUSHED = 0x80;
571 }
572}
573
574#[derive(Debug, Clone, PartialEq, Eq)]
578pub struct ServerDeactivateAll;
579
580impl ServerDeactivateAll {
581 const FIXED_PART_SIZE: usize = 2 + 1 ;
582}
583
584impl Decode<'_> for ServerDeactivateAll {
585 fn decode(src: &mut ReadCursor<'_>) -> DecodeResult<Self> {
586 ensure_fixed_part_size!(in: src);
587 let length_source_descriptor = src.read_u16();
588 ensure_size!(in: src, size: length_source_descriptor.into());
589 let _ = src.read_slice(length_source_descriptor.into());
590 Ok(Self)
591 }
592}
593
594impl Encode for ServerDeactivateAll {
595 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
596 ensure_fixed_part_size!(in: dst);
597 dst.write_u16(1);
599 dst.write_u8(0);
601 Ok(())
602 }
603
604 fn name(&self) -> &'static str {
605 "Server Deactivate All"
606 }
607
608 fn size(&self) -> usize {
609 Self::FIXED_PART_SIZE
610 }
611}