1use ironrdp_core::{
2 ensure_fixed_part_size, invalid_field_err, Decode, DecodeResult, Encode, EncodeResult, ReadCursor, WriteCursor,
3};
4use num_derive::{FromPrimitive, ToPrimitive};
5use num_traits::{FromPrimitive, ToPrimitive};
6
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub struct ServerSetErrorInfoPdu(pub ErrorInfo);
9
10impl ServerSetErrorInfoPdu {
11 const NAME: &'static str = "ServerSetErrorInfoPdu";
12
13 const FIXED_PART_SIZE: usize = 4 ;
14}
15
16impl Encode for ServerSetErrorInfoPdu {
17 fn encode(&self, dst: &mut WriteCursor<'_>) -> EncodeResult<()> {
18 ensure_fixed_part_size!(in: dst);
19
20 dst.write_u32(self.0.to_u32().unwrap());
21
22 Ok(())
23 }
24
25 fn name(&self) -> &'static str {
26 Self::NAME
27 }
28
29 fn size(&self) -> usize {
30 Self::FIXED_PART_SIZE
31 }
32}
33
34impl<'de> Decode<'de> for ServerSetErrorInfoPdu {
35 fn decode(src: &mut ReadCursor<'de>) -> DecodeResult<Self> {
36 ensure_fixed_part_size!(in: src);
37
38 let error_info = src.read_u32();
39 let error_info =
40 ErrorInfo::from_u32(error_info).ok_or_else(|| invalid_field_err!("errorInfo", "unexpected info code"))?;
41
42 Ok(Self(error_info))
43 }
44}
45
46#[derive(Debug, Copy, Clone, PartialEq, Eq)]
47pub enum ErrorInfo {
48 ProtocolIndependentCode(ProtocolIndependentCode),
49 ProtocolIndependentLicensingCode(ProtocolIndependentLicensingCode),
50 ProtocolIndependentConnectionBrokerCode(ProtocolIndependentConnectionBrokerCode),
51 RdpSpecificCode(RdpSpecificCode),
52}
53
54impl ErrorInfo {
55 pub fn description(self) -> String {
56 match self {
57 Self::ProtocolIndependentCode(c) => {
58 format!("[Protocol independent error] {}", c.description())
59 }
60 Self::ProtocolIndependentLicensingCode(c) => {
61 format!("[Protocol independent licensing error] {}", c.description())
62 }
63 Self::ProtocolIndependentConnectionBrokerCode(c) => {
64 format!("[Protocol independent connection broker error] {}", c.description())
65 }
66 Self::RdpSpecificCode(c) => format!("[RDP specific code]: {}", c.description()),
67 }
68 }
69}
70
71impl FromPrimitive for ErrorInfo {
72 fn from_i64(n: i64) -> Option<Self> {
73 if let Some(v) = ProtocolIndependentCode::from_i64(n) {
74 Some(Self::ProtocolIndependentCode(v))
75 } else if let Some(v) = ProtocolIndependentLicensingCode::from_i64(n) {
76 Some(Self::ProtocolIndependentLicensingCode(v))
77 } else if let Some(v) = ProtocolIndependentConnectionBrokerCode::from_i64(n) {
78 Some(Self::ProtocolIndependentConnectionBrokerCode(v))
79 } else {
80 RdpSpecificCode::from_i64(n).map(Self::RdpSpecificCode)
81 }
82 }
83
84 fn from_u64(n: u64) -> Option<Self> {
85 if let Some(v) = ProtocolIndependentCode::from_u64(n) {
86 Some(Self::ProtocolIndependentCode(v))
87 } else if let Some(v) = ProtocolIndependentLicensingCode::from_u64(n) {
88 Some(Self::ProtocolIndependentLicensingCode(v))
89 } else if let Some(v) = ProtocolIndependentConnectionBrokerCode::from_u64(n) {
90 Some(Self::ProtocolIndependentConnectionBrokerCode(v))
91 } else {
92 RdpSpecificCode::from_u64(n).map(Self::RdpSpecificCode)
93 }
94 }
95}
96
97impl ToPrimitive for ErrorInfo {
98 fn to_i64(&self) -> Option<i64> {
99 match self {
100 Self::ProtocolIndependentCode(c) => c.to_i64(),
101 Self::ProtocolIndependentLicensingCode(c) => c.to_i64(),
102 Self::ProtocolIndependentConnectionBrokerCode(c) => c.to_i64(),
103 Self::RdpSpecificCode(c) => c.to_i64(),
104 }
105 }
106
107 fn to_u64(&self) -> Option<u64> {
108 match self {
109 Self::ProtocolIndependentCode(c) => c.to_u64(),
110 Self::ProtocolIndependentLicensingCode(c) => c.to_u64(),
111 Self::ProtocolIndependentConnectionBrokerCode(c) => c.to_u64(),
112 Self::RdpSpecificCode(c) => c.to_u64(),
113 }
114 }
115}
116
117#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
118pub enum ProtocolIndependentCode {
119 None = 0x0000_0000,
120 RpcInitiatedDisconnect = 0x0000_0001,
121 RpcInitiatedLogoff = 0x0000_0002,
122 IdleTimeout = 0x0000_0003,
123 LogonTimeout = 0x0000_0004,
124 DisconnectedByOtherconnection = 0x0000_0005,
125 OutOfMemory = 0x0000_0006,
126 ServerDeniedConnection = 0x0000_0007,
127 ServerInsufficientPrivileges = 0x0000_0009,
128 ServerFreshCredentialsRequired = 0x0000_000A,
129 RpcInitiatedDisconnectByuser = 0x0000_000B,
130 LogoffByUser = 0x0000_000C,
131 CloseStackOnDriverNotReady = 0x0000_000F,
132 ServerDwmCrash = 0x0000_0010,
133 CloseStackOnDriverFailure = 0x0000_0011,
134 CloseStackOnDriverIfaceFailure = 0x0000_0012,
135 ServerWinlogonCrash = 0x0000_0017,
136 ServerCsrssCrash = 0x0000_0018,
137}
138
139impl ProtocolIndependentCode {
140 pub fn description(&self) -> &str {
141 match self {
142 Self::None => "No error has occurred",
143 Self::RpcInitiatedDisconnect => "The disconnection was initiated by an administrative tool on the server in another session",
144 Self::RpcInitiatedLogoff => "The disconnection was due to a forced logoff initiated by an administrative tool on the server in another session",
145 Self::IdleTimeout => "The idle session limit timer on the server has elapsed",
146 Self::LogonTimeout => "The active session limit timer on the server has elapsed",
147 Self::DisconnectedByOtherconnection => "Another user connected to the server, forcing the disconnection of the current connection",
148 Self::OutOfMemory => "The server ran out of available memory resources",
149 Self::ServerDeniedConnection => "The server denied the connection",
150 Self::ServerInsufficientPrivileges => "The user cannot connect to the server due to insufficient access privileges",
151 Self::ServerFreshCredentialsRequired => "The server does not accept saved user credentials and requires that the user enter their credentials for each connection",
152 Self::RpcInitiatedDisconnectByuser => "The disconnection was initiated by an administrative tool on the server running in the user's session",
153 Self::LogoffByUser => "The disconnection was initiated by the user logging off his or her session on the server",
154 Self::CloseStackOnDriverNotReady => "The display driver in the remote session did not report any status within the time allotted for startup",
155 Self::ServerDwmCrash => "The DWM process running in the remote session terminated unexpectedly",
156 Self::CloseStackOnDriverFailure => "The display driver in the remote session was unable to complete all the tasks required for startup",
157 Self::CloseStackOnDriverIfaceFailure => "The display driver in the remote session started up successfully, but due to internal failures was not usable by the remoting stack",
158 Self::ServerWinlogonCrash => "The Winlogon process running in the remote session terminated unexpectedly",
159 Self::ServerCsrssCrash => "The CSRSS process running in the remote session terminated unexpectedly",
160 }
161 }
162}
163
164#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
165pub enum ProtocolIndependentLicensingCode {
166 Internal = 0x0000_0100,
167 NoLicenseServer = 0x0000_0101,
168 NoLicense = 0x0000_0102,
169 BadClientMsg = 0x0000_0103,
170 HwidDoesntMatchLicense = 0x0000_0104,
171 BadClientLicense = 0x0000_0105,
172 CantFinishProtocol = 0x0000_0106,
173 ClientEndedProtocol = 0x0000_0107,
174 BadClientEncryption = 0x0000_0108,
175 CantUpgradeLicense = 0x0000_0109,
176 NoRemoteConnections = 0x0000_010A,
177}
178
179impl ProtocolIndependentLicensingCode {
180 pub fn description(&self) -> &str {
181 match self {
182 Self::Internal => "An internal error has occurred in the Terminal Services licensing component",
183 Self::NoLicenseServer => "A Remote Desktop License Server could not be found to provide a license",
184 Self::NoLicense => "There are no Client Access Licenses available for the target remote computer",
185 Self::BadClientMsg => "The remote computer received an invalid licensing message from the client",
186 Self::HwidDoesntMatchLicense => "The Client Access License stored by the client has been modified",
187 Self::BadClientLicense => "The Client Access License stored by the client is in an invalid format",
188 Self::CantFinishProtocol => "Network problems have caused the licensing protocol to be terminated",
189 Self::ClientEndedProtocol => "The client prematurely ended the licensing protocol",
190 Self::BadClientEncryption => "A licensing message was incorrectly encrypted",
191 Self::CantUpgradeLicense => {
192 "The Client Access License stored by the client could not be upgraded or renewed"
193 }
194 Self::NoRemoteConnections => "The remote computer is not licensed to accept remote connections",
195 }
196 }
197}
198
199#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
200pub enum ProtocolIndependentConnectionBrokerCode {
201 DestinationNotFound = 0x0000_0400,
202 LoadingDestination = 0x0000_0402,
203 RedirectingToDestination = 0x0000_0404,
204 SessionOnlineVmWake = 0x0000_0405,
205 SessionOnlineVmBoot = 0x0000_0406,
206 SessionOnlineVmNoDns = 0x0000_0407,
207 DestinationPoolNotFree = 0x0000_0408,
208 ConnectionCancelled = 0x0000_0409,
209 ConnectionErrorInvalidSettings = 0x0000_0410,
210 SessionOnlineVmBootTimeout = 0x0000_0411,
211 SessionOnlineVmSessmonFailed = 0x0000_0412,
212}
213
214impl ProtocolIndependentConnectionBrokerCode {
215 pub fn description(&self) -> &str {
216 match self {
217 Self::DestinationNotFound => "The target endpoint could not be found",
218 Self::LoadingDestination => "The target endpoint to which the client is being redirected is disconnecting from the Connection Broker",
219 Self::RedirectingToDestination => "An error occurred while the connection was being redirected to the target endpoint",
220 Self::SessionOnlineVmWake => "An error occurred while the target endpoint (a virtual machine) was being awakened",
221 Self::SessionOnlineVmBoot => "An error occurred while the target endpoint (a virtual machine) was being started",
222 Self::SessionOnlineVmNoDns => "The IP address of the target endpoint (a virtual machine) cannot be determined",
223 Self::DestinationPoolNotFree => "There are no available endpoints in the pool managed by the Connection Broker",
224 Self::ConnectionCancelled => "Processing of the connection has been canceled",
225 Self::ConnectionErrorInvalidSettings => "The settings contained in the routingToken field of the X.224 Connection Request PDU cannot be validated",
226 Self::SessionOnlineVmBootTimeout => "A time-out occurred while the target endpoint (a virtual machine) was being started",
227 Self::SessionOnlineVmSessmonFailed => "A session monitoring error occurred while the target endpoint (a virtual machine) was being started",
228 }
229 }
230}
231
232#[derive(Debug, Copy, Clone, PartialEq, Eq, FromPrimitive, ToPrimitive)]
233pub enum RdpSpecificCode {
234 UnknownPduType2 = 0x0000_10C9,
235 UnknownPduType = 0x0000_10CA,
236 DataPdusEquence = 0x0000_10CB,
237 ControlPduSequence = 0x0000_10CD,
238 InvalidControlPduAction = 0x0000_10CE,
239 InvalidInputPduType = 0x0000_10CF,
240 InvalidInputPduMouse = 0x0000_10D0,
241 InvalidRefreshRectPdu = 0x0000_10D1,
242 CreateUserDataFailed = 0x0000_10D2,
243 ConnectFailed = 0x0000_10D3,
244 ConfirmActiveWrongShareId = 0x0000_10D4,
245 ConfirmActiveWrongOriginator = 0x0000_10D5,
246 PersistentKeyPduBadLength = 0x0000_10DA,
247 PersistentKeyPduIllegalFirst = 0x0000_10DB,
248 PersistentKeyPduTooManyTotalKeys = 0x0000_10DC,
249 PersistentKeyPduTooManyCacheKeys = 0x0000_10DD,
250 InputPduBadLength = 0x0000_10DE,
251 BitmapCacheErrorPduBadLength = 0x0000_10DF,
252 SecurityDataTooShort = 0x0000_10E0,
253 VcHannelDataTooShort = 0x0000_10E1,
254 ShareDataTooShort = 0x0000_10E2,
255 BadSuppressOutputPdu = 0x0000_10E3,
256 ConfirmActivePduTooShort = 0x0000_10E5,
257 CapabilitySetTooSmall = 0x0000_10E7,
258 CapabilitySetTooLarge = 0x0000_10E8,
259 NoCursorCache = 0x0000_10E9,
260 BadCapabilities = 0x0000_10EA,
261 VirtualChannelDecompressionError = 0x0000_10EC,
262 InvalidVcCompressionType = 0x0000_10ED,
263 InvalidChannelId = 0x0000_10EF,
264 VirtualChannelsTooMany = 0x0000_10F0,
265 RemoteAppsNotEnabled = 0x0000_10F3,
266 CacheCapabilityNotSet = 0x0000_10F4,
267 BitmapCacheErrorPduBadLength2 = 0x0000_10F5,
268 OffscrCacheErrorPduBadLength = 0x0000_10F6,
269 DngCacheErrorPduBadLength = 0x0000_10F7,
270 GdiPlusPduBadLength = 0x0000_10F8,
271 SecurityDataTooShort2 = 0x0000_1111,
272 SecurityDataTooShort3 = 0x0000_1112,
273 SecurityDataTooShort4 = 0x0000_1113,
274 SecurityDataTooShort5 = 0x0000_1114,
275 SecurityDataTooShort6 = 0x0000_1115,
276 SecurityDataTooShort7 = 0x0000_1116,
277 SecurityDataTooShort8 = 0x0000_1117,
278 SecurityDataTooShort9 = 0x0000_1118,
279 SecurityDataTooShort10 = 0x0000_1119,
280 SecurityDataTooShort11 = 0x0000_111A,
281 SecurityDataTooShort12 = 0x0000_111B,
282 SecurityDataTooShort13 = 0x0000_111C,
283 SecurityDataTooShort14 = 0x0000_111D,
284 SecurityDataTooShort15 = 0x0000_111E,
285 SecurityDataTooShort16 = 0x0000_111F,
286 SecurityDataTooShort17 = 0x0000_1120,
287 SecurityDataTooShort18 = 0x0000_1121,
288 SecurityDataTooShort19 = 0x0000_1122,
289 SecurityDataTooShort20 = 0x0000_1123,
290 SecurityDataTooShort21 = 0x0000_1124,
291 SecurityDataTooShort22 = 0x0000_1125,
292 SecurityDataTooShort23 = 0x0000_1126,
293 BadMonitorData = 0x0000_1129,
294 VcDecompressedReassembleFailed = 0x0000_112A,
295 VcDataTooLong = 0x0000_112B,
296 BadFrameAckData = 0x0000_112C,
297 GraphicsModeNotSupported = 0x0000_112D,
298 GraphicsSubsystemResetFailed = 0x0000_112E,
299 GraphicsSubsystemFailed = 0x0000_112F,
300 TimezoneKeyNameLengthTooShort = 0x0000_1130,
301 TimezoneKeyNameLengthTooLong = 0x0000_1131,
302 DynamicDstDisabledFieldMissing = 0x0000_1132,
303 VcDecodingError = 0x0000_1133,
304 VirtualDesktopTooLarge = 0x0000_1134,
305 MonitorGeometryValidationFailed = 0x0000_1135,
306 InvalidMonitorCount = 0x0000_1136,
307 UpdateSessionKeyFailed = 0x0000_1191,
308 DecryptFailed = 0x0000_1192,
309 EncryptFailed = 0x0000_1193,
310 EncPkgMismatch = 0x0000_1194,
311 DecryptFailed2 = 0x0000_1195,
312}
313
314impl RdpSpecificCode {
315 pub fn description(&self) -> &str {
316 match self {
317 Self::UnknownPduType2 => "Unknown pduType2 field in a received Share Data Header",
318 Self::UnknownPduType => "Unknown pduType field in a received Share Control Header",
319 Self::DataPdusEquence => "An out-of-sequence Slow-Path Data PDU has been received",
320 Self::ControlPduSequence => "An out-of-sequence Slow-Path Non-Data PDU has been received",
321 Self::InvalidControlPduAction => "A Control PDU has been received with an invalid action field",
322 Self::InvalidInputPduType => "One of two possible errors: A Slow-Path Input Event has been received with an invalid messageType field; or A Fast-Path Input Event has been received with an invalid eventCode field",
323 Self::InvalidInputPduMouse => "One of two possible errors: A Slow-Path Mouse Event or Extended Mouse Event has been received with an invalid pointerFlags field; or A Fast-Path Mouse Event or Fast-Path Extended Mouse Event has been received with an invalid pointerFlags field",
324 Self::InvalidRefreshRectPdu => "An invalid Refresh Rect PDU has been received",
325 Self::CreateUserDataFailed => "The server failed to construct the GCC Conference Create Response user data",
326 Self::ConnectFailed => "Processing during the Channel Connection phase of the RDP Connection Sequence has failed",
327 Self::ConfirmActiveWrongShareId => "A Confirm Active PDU was received from the client with an invalid shareID field",
328 Self::ConfirmActiveWrongOriginator => "A Confirm Active PDU was received from the client with an invalid originatorID field",
329 Self::PersistentKeyPduBadLength => "There is not enough data to process a Persistent Key List PDU",
330 Self::PersistentKeyPduIllegalFirst => "A Persistent Key List PDU marked as PERSIST_PDU_FIRST (0x01) was received after the reception of a prior Persistent Key List PDU also marked as PERSIST_PDU_FIRST",
331 Self::PersistentKeyPduTooManyTotalKeys => "A Persistent Key List PDU was received which specified a total number of bitmap cache entries larger than 262144",
332 Self::PersistentKeyPduTooManyCacheKeys => "A Persistent Key List PDU was received which specified an invalid total number of keys for a bitmap cache (the number of entries that can be stored within each bitmap cache is specified in the Revision 1 or 2 Bitmap Cache Capability Set that is sent from client to server)",
333 Self::InputPduBadLength => "There is not enough data to process Input Event PDU Data or a Fast-Path Input Event PDU",
334 Self::BitmapCacheErrorPduBadLength => "There is not enough data to process the shareDataHeader, NumInfoBlocks, Pad1, and Pad2 fields of the Bitmap Cache Error PDU Data",
335 Self::SecurityDataTooShort => "One of two possible errors: The dataSignature field of the Fast-Path Input Event PDU does not contain enough data; or The fipsInformation and dataSignature fields of the Fast-Path Input Event PDU do not contain enough data",
336 Self::VcHannelDataTooShort => "One of two possible errors: There is not enough data in the Client Network Data to read the virtual channel configuration data; or There is not enough data to read a complete Channel PDU Header",
337 Self::ShareDataTooShort => "One of four possible errors: There is not enough data to process Control PDU Data; or There is not enough data to read a complete Share Control Header; or There is not enough data to read a complete Share Data Header of a Slow-Path Data PDU; or There is not enough data to process Font List PDU Data",
338 Self::BadSuppressOutputPdu => "One of two possible errors: There is not enough data to process Suppress Output PDU Data; or The allowDisplayUpdates field of the Suppress Output PDU Data is invalid",
339 Self::ConfirmActivePduTooShort => "One of two possible errors: There is not enough data to read the shareControlHeader, shareID, originatorID, lengthSourceDescriptor, and lengthCombinedCapabilities fields of the Confirm Active PDU Data; or There is not enough data to read the sourceDescriptor, numberCapabilities, pad2Octets, and capabilitySets fields of the Confirm Active PDU Data",
340 Self::CapabilitySetTooSmall => "There is not enough data to read the capabilitySetType and the lengthCapability fields in a received Capability Set",
341 Self::CapabilitySetTooLarge => "A Capability Set has been received with a lengthCapability field that contains a value greater than the total length of the data received",
342 Self::NoCursorCache => "One of two possible errors: Both the colorPointerCacheSize and pointerCacheSize fields in the Pointer Capability Set are set to zero; or The pointerCacheSize field in the Pointer Capability Set is not present, and the colorPointerCacheSize field is set to zero",
343 Self::BadCapabilities => "The capabilities received from the client in the Confirm Active PDU were not accepted by the server",
344 Self::VirtualChannelDecompressionError => "An error occurred while using the bulk compressor to decompress a Virtual Channel PDU",
345 Self::InvalidVcCompressionType => "An invalid bulk compression package was specified in the flags field of the Channel PDU Header",
346 Self::InvalidChannelId => "An invalid MCS channel ID was specified in the mcsPdu field of the Virtual Channel PDU)",
347 Self::VirtualChannelsTooMany => "The client requested more than the maximum allowed 31 static virtual channels in the Client Network Data",
348 Self::RemoteAppsNotEnabled => "The INFO_RAIL flag (0x0000_8000) MUST be set in the flags field of the Info Packet as the session on the remote server can only host remote applications",
349 Self::CacheCapabilityNotSet => "The client sent a Persistent Key List PDU without including the prerequisite Revision 2 Bitmap Cache Capability Set in the Confirm Active PDU",
350 Self::BitmapCacheErrorPduBadLength2 => "The NumInfoBlocks field in the Bitmap Cache Error PDU Data is inconsistent with the amount of data in the Info field",
351 Self::OffscrCacheErrorPduBadLength => "There is not enough data to process an Offscreen Bitmap Cache Error PDU",
352 Self::DngCacheErrorPduBadLength => "There is not enough data to process a DrawNineGrid Cache Error PDU",
353 Self::GdiPlusPduBadLength => "There is not enough data to process a GDI+ Error PDU",
354 Self::SecurityDataTooShort2 => "There is not enough data to read a Basic Security Header",
355 Self::SecurityDataTooShort3 => "There is not enough data to read a Non-FIPS Security Header or FIPS Security Header",
356 Self::SecurityDataTooShort4 => "There is not enough data to read the basicSecurityHeader and length fields of the Security Exchange PDU Data",
357 Self::SecurityDataTooShort5 => "There is not enough data to read the CodePage, flags, cbDomain, cbUserName, cbPassword, cbAlternateShell, cbWorkingDir, Domain, UserName, Password, AlternateShell, and WorkingDir fields in the Info Packet",
358 Self::SecurityDataTooShort6 => "There is not enough data to read the CodePage, flags, cbDomain, cbUserName, cbPassword, cbAlternateShell, and cbWorkingDir fields in the Info Packet",
359 Self::SecurityDataTooShort7 => "There is not enough data to read the clientAddressFamily and cbClientAddress fields in the Extended Info Packet",
360 Self::SecurityDataTooShort8 => "There is not enough data to read the clientAddress field in the Extended Info Packet",
361 Self::SecurityDataTooShort9 => "There is not enough data to read the cbClientDir field in the Extended Info Packet",
362 Self::SecurityDataTooShort10 => "There is not enough data to read the clientDir field in the Extended Info Packet",
363 Self::SecurityDataTooShort11 => "There is not enough data to read the clientTimeZone field in the Extended Info Packet",
364 Self::SecurityDataTooShort12 => "There is not enough data to read the clientSessionId field in the Extended Info Packet",
365 Self::SecurityDataTooShort13 => "There is not enough data to read the performanceFlags field in the Extended Info Packet",
366 Self::SecurityDataTooShort14 => "There is not enough data to read the cbAutoReconnectCookie field in the Extended Info Packet",
367 Self::SecurityDataTooShort15 => "There is not enough data to read the autoReconnectCookie field in the Extended Info Packet",
368 Self::SecurityDataTooShort16 => "The cbAutoReconnectCookie field in the Extended Info Packet contains a value which is larger than the maximum allowed length of 128 bytes",
369 Self::SecurityDataTooShort17 => "There is not enough data to read the clientAddressFamily and cbClientAddress fields in the Extended Info Packet",
370 Self::SecurityDataTooShort18 => "There is not enough data to read the clientAddress field in the Extended Info Packet",
371 Self::SecurityDataTooShort19 => "There is not enough data to read the cbClientDir field in the Extended Info Packet",
372 Self::SecurityDataTooShort20 => "There is not enough data to read the clientDir field in the Extended Info Packet",
373 Self::SecurityDataTooShort21 => "There is not enough data to read the clientTimeZone field in the Extended Info Packet",
374 Self::SecurityDataTooShort22 => "There is not enough data to read the clientSessionId field in the Extended Info Packet",
375 Self::SecurityDataTooShort23 => "There is not enough data to read the Client Info PDU Data",
376 Self::BadMonitorData => "The number of TS_MONITOR_DEF structures present in the monitorDefArray field of the Client Monitor Data is less than the value specified in monitorCount field",
377 Self::VcDecompressedReassembleFailed => "The server-side decompression buffer is invalid, or the size of the decompressed VC data exceeds the chunking size specified in the Virtual Channel Capability Set",
378 Self::VcDataTooLong => "The size of a received Virtual Channel PDU exceeds the chunking size specified in the Virtual Channel Capability Set",
379 Self::BadFrameAckData => "There is not enough data to read a TS_FRAME_ACKNOWLEDGE_PDU",
380 Self::GraphicsModeNotSupported => "The graphics mode requested by the client is not supported by the server",
381 Self::GraphicsSubsystemResetFailed => "The server-side graphics subsystem failed to reset",
382 Self::GraphicsSubsystemFailed => "The server-side graphics subsystem is in an error state and unable to continue graphics encoding",
383 Self::TimezoneKeyNameLengthTooShort => "There is not enough data to read the cbDynamicDSTTimeZoneKeyName field in the Extended Info Packet",
384 Self::TimezoneKeyNameLengthTooLong => "The length reported in the cbDynamicDSTTimeZoneKeyName field of the Extended Info Packet is too long",
385 Self::DynamicDstDisabledFieldMissing => "The dynamicDaylightTimeDisabled field is not present in the Extended Info Packet",
386 Self::VcDecodingError => "An error occurred when processing dynamic virtual channel data",
387 Self::VirtualDesktopTooLarge => "The width or height of the virtual desktop defined by the monitor layout in the Client Monitor Data is larger than the maximum allowed value of 32,766",
388 Self::MonitorGeometryValidationFailed => "The monitor geometry defined by the Client Monitor Data is invalid",
389 Self::InvalidMonitorCount => "The monitorCount field in the Client Monitor Data is too large",
390 Self::UpdateSessionKeyFailed => "An attempt to update the session keys while using Standard RDP Security mechanisms failed",
391 Self::DecryptFailed => "One of two possible error conditions: Decryption using Standard RDP Security mechanisms failed; or Session key creation using Standard RDP Security mechanisms failed",
392 Self::EncryptFailed => "Encryption using Standard RDP Security mechanisms failed",
393 Self::EncPkgMismatch => "Failed to find a usable Encryption Method in the encryptionMethods field of the Client Security Data",
394 Self::DecryptFailed2 => "Unencrypted data was encountered in a protocol stream which is meant to be encrypted with Standard RDP Security mechanisms",
395 }
396 }
397}
398
399#[cfg(test)]
400mod tests {
401 use ironrdp_core::{decode, encode_vec};
402
403 use super::*;
404
405 const SERVER_SET_ERROR_INFO_BUFFER: [u8; 4] = [0x00, 0x01, 0x00, 0x00];
406
407 const SERVER_SET_ERROR_INFO: ServerSetErrorInfoPdu = ServerSetErrorInfoPdu(
408 ErrorInfo::ProtocolIndependentLicensingCode(ProtocolIndependentLicensingCode::Internal),
409 );
410
411 #[test]
412 fn from_buffer_correctly_parses_server_set_error_info() {
413 assert_eq!(
414 SERVER_SET_ERROR_INFO,
415 decode(SERVER_SET_ERROR_INFO_BUFFER.as_ref()).unwrap()
416 );
417 }
418
419 #[test]
420 fn to_buffer_correctly_serializes_server_set_error_info() {
421 let expected = SERVER_SET_ERROR_INFO_BUFFER.as_ref();
422
423 let buffer = encode_vec(&SERVER_SET_ERROR_INFO).unwrap();
424 assert_eq!(expected, buffer.as_slice());
425 }
426
427 #[test]
428 fn buffer_length_is_correct_for_server_set_error_info() {
429 assert_eq!(SERVER_SET_ERROR_INFO_BUFFER.len(), SERVER_SET_ERROR_INFO.size());
430 }
431}