1use std::io;
2
3use ironrdp_core::{
4 ensure_fixed_part_size, ensure_size, invalid_field_err, read_padding, write_padding, Decode, DecodeResult, Encode,
5 EncodeResult, ReadCursor, WriteCursor,
6};
7use num_derive::{FromPrimitive, ToPrimitive};
8use num_traits::{FromPrimitive as _, ToPrimitive as _};
9use thiserror::Error;
10
11pub mod fast_path;
12pub mod mouse;
13pub mod mouse_rel;
14pub mod mouse_x;
15pub mod scan_code;
16pub mod sync;
17pub mod unicode;
18pub mod unused;
19
20pub use self::mouse::MousePdu;
21pub use self::mouse_rel::MouseRelPdu;
22pub use self::mouse_x::MouseXPdu;
23pub use self::scan_code::ScanCodePdu;
24pub use self::sync::SyncPdu;
25pub use self::unicode::UnicodePdu;
26pub use self::unused::UnusedPdu;
27
28#[derive(Debug, Clone, PartialEq, Eq)]
29pub struct InputEventPdu(pub Vec<InputEvent>);
30
31impl InputEventPdu {
32 const NAME: &'static str = "InputEventPdu";
33
34 const FIXED_PART_SIZE: usize = 4 ;
35}
36
37impl Encode for InputEventPdu {
38 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
39 ensure_size!(in: dst, size: self.size());
40
41 dst.write_u16(self.0.len() as u16);
42 write_padding!(dst, 2);
43
44 for event in self.0.iter() {
45 event.encode(dst)?;
46 }
47
48 Ok(())
49 }
50
51 fn name(&self) -> &'static str {
52 Self::NAME
53 }
54
55 fn size(&self) -> usize {
56 4 + self.0.iter().map(Encode::size).sum::<usize>()
57 }
58}
59
60impl<'de> Decode<'de> for InputEventPdu {
61 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
62 ensure_fixed_part_size!(in: src);
63
64 let number_of_events = src.read_u16();
65 read_padding!(src, 2);
66
67 let events = (0..number_of_events)
68 .map(|_| InputEvent::decode(src))
69 .collect::<Result<Vec<_>, _>>()?;
70
71 Ok(Self(events))
72 }
73}
74
75#[derive(Debug, Clone, PartialEq, Eq)]
76pub enum InputEvent {
77 Sync(SyncPdu),
78 Unused(UnusedPdu),
79 ScanCode(ScanCodePdu),
80 Unicode(UnicodePdu),
81 Mouse(MousePdu),
82 MouseX(MouseXPdu),
83 MouseRel(MouseRelPdu),
84}
85
86impl InputEvent {
87 const NAME: &'static str = "InputEvent";
88
89 const FIXED_PART_SIZE: usize = 4 + 2 ;
90}
91
92impl Encode for InputEvent {
93 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
94 ensure_fixed_part_size!(in: dst);
95
96 dst.write_u32(0); dst.write_u16(InputEventType::from(self).to_u16().unwrap());
98
99 match self {
100 Self::Sync(pdu) => pdu.encode(dst),
101 Self::Unused(pdu) => pdu.encode(dst),
102 Self::ScanCode(pdu) => pdu.encode(dst),
103 Self::Unicode(pdu) => pdu.encode(dst),
104 Self::Mouse(pdu) => pdu.encode(dst),
105 Self::MouseX(pdu) => pdu.encode(dst),
106 Self::MouseRel(pdu) => pdu.encode(dst),
107 }
108 }
109
110 fn name(&self) -> &'static str {
111 Self::NAME
112 }
113
114 fn size(&self) -> usize {
115 Self::FIXED_PART_SIZE
116 + match self {
117 Self::Sync(pdu) => pdu.size(),
118 Self::Unused(pdu) => pdu.size(),
119 Self::ScanCode(pdu) => pdu.size(),
120 Self::Unicode(pdu) => pdu.size(),
121 Self::Mouse(pdu) => pdu.size(),
122 Self::MouseX(pdu) => pdu.size(),
123 Self::MouseRel(pdu) => pdu.size(),
124 }
125 }
126}
127
128impl<'de> Decode<'de> for InputEvent {
129 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
130 ensure_fixed_part_size!(in: src);
131
132 let _event_time = src.read_u32(); let event_type = src.read_u16();
134 let event_type = InputEventType::from_u16(event_type)
135 .ok_or_else(|| invalid_field_err!("eventType", "invalid input event type"))?;
136
137 match event_type {
138 InputEventType::Sync => Ok(Self::Sync(SyncPdu::decode(src)?)),
139 InputEventType::Unused => Ok(Self::Unused(UnusedPdu::decode(src)?)),
140 InputEventType::ScanCode => Ok(Self::ScanCode(ScanCodePdu::decode(src)?)),
141 InputEventType::Unicode => Ok(Self::Unicode(UnicodePdu::decode(src)?)),
142 InputEventType::Mouse => Ok(Self::Mouse(MousePdu::decode(src)?)),
143 InputEventType::MouseX => Ok(Self::MouseX(MouseXPdu::decode(src)?)),
144 InputEventType::MouseRel => Ok(Self::MouseRel(MouseRelPdu::decode(src)?)),
145 }
146 }
147}
148
149#[derive(Debug, Copy, Clone, PartialEq, FromPrimitive, ToPrimitive)]
150#[repr(u16)]
151enum InputEventType {
152 Sync = 0x0000,
153 Unused = 0x0002,
154 ScanCode = 0x0004,
155 Unicode = 0x0005,
156 Mouse = 0x8001,
157 MouseX = 0x8002,
158 MouseRel = 0x8004,
159}
160
161impl From<&InputEvent> for InputEventType {
162 fn from(event: &InputEvent) -> Self {
163 match event {
164 InputEvent::Sync(_) => Self::Sync,
165 InputEvent::Unused(_) => Self::Unused,
166 InputEvent::ScanCode(_) => Self::ScanCode,
167 InputEvent::Unicode(_) => Self::Unicode,
168 InputEvent::Mouse(_) => Self::Mouse,
169 InputEvent::MouseX(_) => Self::MouseX,
170 InputEvent::MouseRel(_) => Self::MouseRel,
171 }
172 }
173}
174
175#[derive(Debug, Error)]
176pub enum InputEventError {
177 #[error("IO error")]
178 IOError(#[from] io::Error),
179 #[error("invalid Input Event type: {0}")]
180 InvalidInputEventType(u16),
181 #[error("encryption not supported")]
182 EncryptionNotSupported,
183 #[error("event code not supported {0}")]
184 EventCodeUnsupported(u8),
185 #[error("keyboard flags not supported {0}")]
186 KeyboardFlagsUnsupported(u8),
187 #[error("synchronize flags not supported {0}")]
188 SynchronizeFlagsUnsupported(u8),
189 #[error("Fast-Path Input Event PDU is empty")]
190 EmptyFastPathInput,
191}