1pub mod dvc;
2
3#[cfg(test)]
4mod tests;
5
6use std::{io, str};
7
8use bitflags::bitflags;
9use ironrdp_core::{ensure_fixed_part_size, Decode, DecodeResult, Encode, EncodeResult, ReadCursor, WriteCursor};
10use thiserror::Error;
11
12use crate::PduError;
13
14const CHANNEL_PDU_HEADER_SIZE: usize = 8;
15
16#[derive(Debug, Clone, PartialEq, Eq)]
18pub struct ChannelPduHeader {
19 pub length: u32,
24 pub flags: ChannelControlFlags,
25}
26
27impl ChannelPduHeader {
28 const NAME: &'static str = "ChannelPduHeader";
29
30 const FIXED_PART_SIZE: usize = CHANNEL_PDU_HEADER_SIZE;
31}
32
33impl Encode for ChannelPduHeader {
34 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
35 ensure_fixed_part_size!(in: dst);
36
37 dst.write_u32(self.length);
38 dst.write_u32(self.flags.bits());
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 ChannelPduHeader {
52 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
53 ensure_fixed_part_size!(in: src);
54
55 let total_length = src.read_u32();
56 let flags = ChannelControlFlags::from_bits_truncate(src.read_u32());
57 Ok(Self {
58 length: total_length,
59 flags,
60 })
61 }
62}
63
64bitflags! {
65 #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
66 pub struct ChannelControlFlags: u32 {
67 const FLAG_FIRST = 0x0000_0001;
68 const FLAG_LAST = 0x0000_0002;
69 const FLAG_SHOW_PROTOCOL = 0x0000_0010;
70 const FLAG_SUSPEND = 0x0000_0020;
71 const FLAG_RESUME = 0x0000_0040;
72 const FLAG_SHADOW_PERSISTENT = 0x0000_0080;
73 const PACKET_COMPRESSED = 0x0020_0000;
74 const PACKET_AT_FRONT = 0x0040_0000;
75 const PACKET_FLUSHED = 0x0080_0000;
76 const COMPRESSION_TYPE_MASK = 0x000F_0000;
77 }
78}
79
80#[derive(Debug, Error)]
81pub enum ChannelError {
82 #[error("IO error")]
83 IOError(#[from] io::Error),
84 #[error("from UTF-8 error")]
85 FromUtf8Error(#[from] std::string::FromUtf8Error),
86 #[error("invalid channel PDU header")]
87 InvalidChannelPduHeader,
88 #[error("invalid channel total data length")]
89 InvalidChannelTotalDataLength,
90 #[error("invalid DVC PDU type")]
91 InvalidDvcPduType,
92 #[error("invalid DVC id length value")]
93 InvalidDVChannelIdLength,
94 #[error("invalid DVC data length value")]
95 InvalidDvcDataLength,
96 #[error("invalid DVC capabilities version")]
97 InvalidDvcCapabilitiesVersion,
98 #[error("invalid DVC message size")]
99 InvalidDvcMessageSize,
100 #[error("invalid DVC total message size: actual ({actual}) > expected ({expected})")]
101 InvalidDvcTotalMessageSize { actual: usize, expected: usize },
102 #[error("PDU error: {0}")]
103 Pdu(PduError),
104}
105
106impl From<PduError> for ChannelError {
107 fn from(e: PduError) -> Self {
108 Self::Pdu(e)
109 }
110}
111
112impl From<ChannelError> for io::Error {
113 fn from(e: ChannelError) -> io::Error {
114 io::Error::other(format!("Virtual channel error: {e}"))
115 }
116}