diff --git a/common/ms-rdpbcgr.h b/common/ms-rdpbcgr.h index e993c270..6129f98f 100644 --- a/common/ms-rdpbcgr.h +++ b/common/ms-rdpbcgr.h @@ -57,6 +57,7 @@ #define SEC_TAG_CLI_CHANNELS 0xc003 /* CS_CHANNELS? */ #define SEC_TAG_CLI_4 0xc004 /* CS_CLUSTER? */ #define SEC_TAG_CLI_MONITOR 0xc005 /* CS_MONITOR */ +#define SEC_TAG_CLI_MONITOR_EX 0xc008 /* CS_MONITOR_EX */ /* Client Core Data: colorDepth, postBeta2ColorDepth (2.2.1.3.2) */ #define RNS_UD_COLOR_4BPP 0xCA00 diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h index bf57de09..6ba13d3f 100644 --- a/common/xrdp_client_info.h +++ b/common/xrdp_client_info.h @@ -38,7 +38,8 @@ struct monitor_info int bottom; int flags; - /* From 2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT */ + /* From [MS-RDPEDISP] 2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT, or + * [MS-RDPBCGR] 2.2.1.3.9.1 (TS_MONITOR_ATTRIBUTES) */ unsigned int physical_width; unsigned int physical_height; unsigned int orientation; @@ -205,6 +206,13 @@ struct xrdp_client_info /* xrdp.override_* values */ struct xrdp_keyboard_overrides xrdp_keyboard_overrides; + + /* These values are optionally send over as part of TS_UD_CS_CORE. + * They can be used as a fallback for a single monitor session + * if physical sizes are not available in the monitor-specific + * data */ + unsigned int session_physical_width; /* in mm */ + unsigned int session_physical_height; /* in mm */ }; /* yyyymmdd of last incompatible change to xrdp_client_info */ diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index 7018961f..e418fb63 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -29,6 +29,7 @@ #include "ms-rdpbcgr.h" #define MAX_BITMAP_BUF_SIZE (16 * 1024) /* 16K */ +#define TS_MONITOR_ATTRIBUTES_SIZE 20 /* [MS-RDPBCGR] 2.2.1.3.9 */ /******************************************************************************/ struct xrdp_session *EXPORT_CC @@ -1764,6 +1765,97 @@ libxrdp_send_session_info(struct xrdp_session *session, const char *data, return xrdp_rdp_send_session_info(rdp, data, data_bytes); } +/*****************************************************************************/ +/* + Sanitise extended monitor attributes + + The extended attributes are received from either + [MS-RDPEDISP] 2.2.2.2.1 (DISPLAYCONTROL_MONITOR_LAYOUT), or + [MS-RDPBCGR] 2.2.1.3.9.1 (TS_MONITOR_ATTRIBUTES) + + @param monitor_layout struct containing extended attributes +*/ +static void +sanitise_extended_monitor_attributes(struct monitor_info *monitor_layout) +{ + /* if EITHER physical_width or physical_height are + * out of range, BOTH must be ignored. + */ + if (monitor_layout->physical_width > 10000 + || monitor_layout->physical_width < 10) + { + LOG(LOG_LEVEL_WARNING, "sanitise_extended_monitor_attributes:" + " physical_width is not within valid range." + " Setting physical_width to 0mm," + " Setting physical_height to 0mm," + " physical_width was: %d", + monitor_layout->physical_width); + monitor_layout->physical_width = 0; + monitor_layout->physical_height = 0; + } + + if (monitor_layout->physical_height > 10000 + || monitor_layout->physical_height < 10) + { + LOG(LOG_LEVEL_WARNING, "sanitise_extended_monitor_attributes:" + " physical_height is not within valid range." + " Setting physical_width to 0mm," + " Setting physical_height to 0mm," + " physical_height was: %d", + monitor_layout->physical_height); + monitor_layout->physical_width = 0; + monitor_layout->physical_height = 0; + } + + switch (monitor_layout->orientation) + { + case ORIENTATION_LANDSCAPE: + case ORIENTATION_PORTRAIT: + case ORIENTATION_LANDSCAPE_FLIPPED: + case ORIENTATION_PORTRAIT_FLIPPED: + break; + default: + LOG(LOG_LEVEL_WARNING, "sanitise_extended_monitor_attributes:" + " Orientation is not one of %d, %d, %d, or %d." + " Value was %d and ignored and set to default value of LANDSCAPE.", + ORIENTATION_LANDSCAPE, + ORIENTATION_PORTRAIT, + ORIENTATION_LANDSCAPE_FLIPPED, + ORIENTATION_PORTRAIT_FLIPPED, + monitor_layout->orientation); + monitor_layout->orientation = ORIENTATION_LANDSCAPE; + } + + int check_desktop_scale_factor + = monitor_layout->desktop_scale_factor < 100 + || monitor_layout->desktop_scale_factor > 500; + if (check_desktop_scale_factor) + { + LOG(LOG_LEVEL_WARNING, "sanitise_extended_monitor_attributes:" + " desktop_scale_factor is not within valid range" + " of [100, 500]. Assuming 100. Value was: %d", + monitor_layout->desktop_scale_factor); + } + + int check_device_scale_factor + = monitor_layout->device_scale_factor != 100 + && monitor_layout->device_scale_factor != 140 + && monitor_layout->device_scale_factor != 180; + if (check_device_scale_factor) + { + LOG(LOG_LEVEL_WARNING, "sanitise_extended_monitor_attributes:" + " device_scale_factor a valid value (One of 100, 140, 180)." + " Assuming 100. Value was: %d", + monitor_layout->device_scale_factor); + } + + if (check_desktop_scale_factor || check_device_scale_factor) + { + monitor_layout->desktop_scale_factor = 100; + monitor_layout->device_scale_factor = 100; + } +} + /*****************************************************************************/ /* Process a [MS-RDPBCGR] TS_UD_CS_MONITOR message. @@ -1907,87 +1999,11 @@ libxrdp_process_monitor_stream(struct stream *s, in_uint32_le(s, monitor_layout->physical_width); in_uint32_le(s, monitor_layout->physical_height); - - /* Per spec (2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT), - * if EITHER physical_width or physical_height are - * out of range, BOTH must be ignored. - */ - if (monitor_layout->physical_width > 10000 - || monitor_layout->physical_width < 10) - { - LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:" - " physical_width is not within valid range." - " Setting physical_width to 0mm," - " Setting physical_height to 0mm," - " physical_width was: %d", - monitor_layout->physical_width); - monitor_layout->physical_width = 0; - monitor_layout->physical_height = 0; - } - - if (monitor_layout->physical_height > 10000 - || monitor_layout->physical_height < 10) - { - LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:" - " physical_height is not within valid range." - " Setting physical_width to 0mm," - " Setting physical_height to 0mm," - " physical_height was: %d", - monitor_layout->physical_height); - monitor_layout->physical_width = 0; - monitor_layout->physical_height = 0; - } - in_uint32_le(s, monitor_layout->orientation); - switch (monitor_layout->orientation) - { - case ORIENTATION_LANDSCAPE: - case ORIENTATION_PORTRAIT: - case ORIENTATION_LANDSCAPE_FLIPPED: - case ORIENTATION_PORTRAIT_FLIPPED: - break; - default: - LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:" - " Orientation is not one of %d, %d, %d, or %d." - " Value was %d and ignored and set to default value of LANDSCAPE.", - ORIENTATION_LANDSCAPE, - ORIENTATION_PORTRAIT, - ORIENTATION_LANDSCAPE_FLIPPED, - ORIENTATION_PORTRAIT_FLIPPED, - monitor_layout->orientation); - monitor_layout->orientation = ORIENTATION_LANDSCAPE; - } - in_uint32_le(s, monitor_layout->desktop_scale_factor); - int check_desktop_scale_factor - = monitor_layout->desktop_scale_factor < 100 - || monitor_layout->desktop_scale_factor > 500; - if (check_desktop_scale_factor) - { - LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:" - " desktop_scale_factor is not within valid range" - " of [100, 500]. Assuming 100. Value was: %d", - monitor_layout->desktop_scale_factor); - } - in_uint32_le(s, monitor_layout->device_scale_factor); - int check_device_scale_factor - = monitor_layout->device_scale_factor != 100 - && monitor_layout->device_scale_factor != 140 - && monitor_layout->device_scale_factor != 180; - if (check_device_scale_factor) - { - LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:" - " device_scale_factor a valid value (One of 100, 140, 180)." - " Assuming 100. Value was: %d", - monitor_layout->device_scale_factor); - } - if (check_desktop_scale_factor || check_device_scale_factor) - { - monitor_layout->desktop_scale_factor = 100; - monitor_layout->device_scale_factor = 100; - } + sanitise_extended_monitor_attributes(monitor_layout); /* * 2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT @@ -2137,5 +2153,108 @@ libxrdp_process_monitor_stream(struct stream *s, monitor_layout->bottom = monitor_layout->bottom - all_monitors_encompassing_bounds.top; } + + return 0; +} + +/*****************************************************************************/ +int +libxrdp_process_monitor_ex_stream(struct stream *s, + struct display_size_description *description) +{ + uint32_t num_monitor; + uint32_t monitor_index; + uint32_t attribute_size; + struct monitor_info *monitor_layout; + + LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_process_monitor_ex_stream:"); + if (description == NULL) + { + LOG_DEVEL(LOG_LEVEL_ERROR, "libxrdp_process_monitor_ex_stream: " + "description was null. " + " Valid pointer to allocated description expected."); + return SEC_PROCESS_MONITORS_ERR; + } + + if (!s_check_rem_and_log(s, 4, + "libxrdp_process_monitor_ex_stream:" + " Parsing [MS-RDPBCGR] TS_UD_CS_MONITOR_EX")) + { + return SEC_PROCESS_MONITORS_ERR; + } + + in_uint32_le(s, attribute_size); + if (attribute_size != TS_MONITOR_ATTRIBUTES_SIZE) + { + LOG(LOG_LEVEL_ERROR, + "libxrdp_process_monitor_ex_stream: [MS-RDPBCGR] Protocol" + " error: TS_UD_CS_MONITOR_EX monitorAttributeSize" + " MUST be %d, received: %d", + TS_MONITOR_ATTRIBUTES_SIZE, attribute_size); + return SEC_PROCESS_MONITORS_ERR; + } + + in_uint32_le(s, num_monitor); + LOG(LOG_LEVEL_DEBUG, "libxrdp_process_monitor_ex_stream:" + " The number of monitors received is: %d", + num_monitor); + + if (num_monitor != description->monitorCount) + { + LOG(LOG_LEVEL_ERROR, + "libxrdp_process_monitor_ex_stream: [MS-RDPBCGR] Protocol" + " error: TS_UD_CS_MONITOR monitorCount" + " MUST be %d, received: %d", + description->monitorCount, num_monitor); + return SEC_PROCESS_MONITORS_ERR; + } + + for (monitor_index = 0; monitor_index < num_monitor; ++monitor_index) + { + if (!s_check_rem_and_log(s, attribute_size, + "libxrdp_process_monitor_ex_stream:" + " Parsing TS_UD_CS_MONITOR_EX")) + { + return SEC_PROCESS_MONITORS_ERR; + } + + monitor_layout = description->minfo + monitor_index; + + in_uint32_le(s, monitor_layout->physical_width); + in_uint32_le(s, monitor_layout->physical_height); + in_uint32_le(s, monitor_layout->orientation); + in_uint32_le(s, monitor_layout->desktop_scale_factor); + in_uint32_le(s, monitor_layout->device_scale_factor); + + sanitise_extended_monitor_attributes(monitor_layout); + + LOG_DEVEL(LOG_LEVEL_INFO, "libxrdp_process_monitor_ex_stream:" + " Received [MS-RDPBCGR] 2.2.1.3.9.1 " + " TS_MONITOR_ATTRIBUTES" + " Index: %d, PhysicalWidth %d, PhysicalHeight %d," + " Orientation %d, DesktopScaleFactor %d," + " DeviceScaleFactor %d", + monitor_index, + monitor_layout->physical_width, + monitor_layout->physical_height, + monitor_layout->orientation, + monitor_layout->desktop_scale_factor, + monitor_layout->device_scale_factor); + } + + /* Update non negative monitor info values */ + const struct monitor_info *src = description->minfo; + struct monitor_info *dst = description->minfo_wm; + for (monitor_index = 0; monitor_index < num_monitor; ++monitor_index) + { + dst->physical_width = src->physical_width; + dst->physical_height = src->physical_height; + dst->orientation = src->orientation; + dst->desktop_scale_factor = src->desktop_scale_factor; + dst->device_scale_factor = src->device_scale_factor; + ++src; + ++dst; + } + return 0; } diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index 19ba95d1..8fd54016 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -364,9 +364,10 @@ xrdp_mcs_disconnect(struct xrdp_mcs *self); /* xrdp_sec.c */ /* - These are error return codes for both: + These are error return codes for:- 1. xrdp_sec_process_mcs_data_monitors 2. libxrdp_process_monitor_stream + 3. libxrdp_process_monitor_ex_stream To clarify any reason for a non-zero response code. */ #define SEC_PROCESS_MONITORS_ERR 1 diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h index af006868..68b37362 100644 --- a/libxrdp/libxrdpinc.h +++ b/libxrdp/libxrdpinc.h @@ -324,4 +324,19 @@ int EXPORT_CC libxrdp_process_monitor_stream(struct stream *s, struct display_size_description *description, int full_parameters); +/** + * Processes a stream that is based on [MS-RDPBCGR] 2.2.1.3.9 Client + * Monitor Extended Data (TS_UD_CS_MONITOR_EX) + * + * Data is stored in a struct which has already been read by + * libxrdp_process_monitor_stream() withj full_parameters set to 0. + * + * @param s Stream to read data from. Stream is read up to monitorAttributeSize + * @param description Result of reading TS_UD_CS_MONITOR PDU + * @return 0 if the data is processed, non-zero if there is an error. + */ +int EXPORT_CC +libxrdp_process_monitor_ex_stream(struct stream *s, + struct display_size_description *description); + #endif diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index bde7d3fa..24b44338 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -1953,19 +1953,23 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s) char clientName[INFO_CLIENT_NAME_BYTES / 2] = { '\0' }; UNUSED_VAR(version); + struct xrdp_client_info *client_info = &self->rdp_layer->client_info; + /* Clear physical sizes. These are optional and may not be read later */ + client_info->session_physical_width = 0; + client_info->session_physical_height = 0; - /* TS_UD_CS_CORE requiered fields */ + /* TS_UD_CS_CORE required fields */ in_uint32_le(s, version); - in_uint16_le(s, self->rdp_layer->client_info.display_sizes.session_width); - in_uint16_le(s, self->rdp_layer->client_info.display_sizes.session_height); + in_uint16_le(s, client_info->display_sizes.session_width); + in_uint16_le(s, client_info->display_sizes.session_height); in_uint16_le(s, colorDepth); switch (colorDepth) { case RNS_UD_COLOR_4BPP: - self->rdp_layer->client_info.bpp = 4; + client_info->bpp = 4; break; case RNS_UD_COLOR_8BPP: - self->rdp_layer->client_info.bpp = 8; + client_info->bpp = 8; break; } in_uint8s(s, 2); /* SASSequence */ @@ -1985,8 +1989,8 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s) "keyboardSubType (ignored), keyboardFunctionKey (ignored), " "imeFileName (ignored)", version, - self->rdp_layer->client_info.display_sizes.session_width, - self->rdp_layer->client_info.display_sizes.session_height, + client_info->display_sizes.session_width, + client_info->display_sizes.session_height, (colorDepth == 0xca00 ? "RNS_UD_COLOR_4BPP" : colorDepth == 0xca01 ? "RNS_UD_COLOR_8BPP" : "unknown"), clientName); @@ -2005,19 +2009,19 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s) switch (postBeta2ColorDepth) { case RNS_UD_COLOR_4BPP: - self->rdp_layer->client_info.bpp = 4; + client_info->bpp = 4; break; case RNS_UD_COLOR_8BPP : - self->rdp_layer->client_info.bpp = 8; + client_info->bpp = 8; break; case RNS_UD_COLOR_16BPP_555: - self->rdp_layer->client_info.bpp = 15; + client_info->bpp = 15; break; case RNS_UD_COLOR_16BPP_565: - self->rdp_layer->client_info.bpp = 16; + client_info->bpp = 16; break; case RNS_UD_COLOR_24BPP: - self->rdp_layer->client_info.bpp = 24; + client_info->bpp = 24; break; } if (!s_check_rem(s, 2)) @@ -2049,7 +2053,7 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s) highColorDepth == 0x0010 ? "HIGH_COLOR_16BPP" : highColorDepth == 0x0018 ? "HIGH_COLOR_24BPP" : "unknown"); - self->rdp_layer->client_info.bpp = highColorDepth; + client_info->bpp = highColorDepth; if (!s_check_rem(s, 2)) { @@ -2069,13 +2073,13 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s) return 0; } in_uint16_le(s, earlyCapabilityFlags); - self->rdp_layer->client_info.mcs_early_capability_flags = earlyCapabilityFlags; + client_info->mcs_early_capability_flags = earlyCapabilityFlags; LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE " " earlyCapabilityFlags 0x%4.4x", earlyCapabilityFlags); if ((earlyCapabilityFlags & 0x0002) && (supportedColorDepths & 0x0008)) { - self->rdp_layer->client_info.bpp = 32; + client_info->bpp = 32; } if (!s_check_rem(s, 64)) @@ -2090,10 +2094,10 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s) { return 0; } - in_uint8(s, self->rdp_layer->client_info.mcs_connection_type); /* connectionType */ + in_uint8(s, client_info->mcs_connection_type); /* connectionType */ LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE " " connectionType 0x%2.2x", - self->rdp_layer->client_info.mcs_connection_type); + client_info->mcs_connection_type); if (!s_check_rem(s, 1)) { @@ -2111,22 +2115,43 @@ xrdp_sec_process_mcs_data_CS_CORE(struct xrdp_sec *self, struct stream *s) LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE " " serverSelectedProtocol (ignored)"); + /* + * Non-zero values for the desktop physical width and height values + * are only sent if the client has a single monitor. For multiple + * monitors, the physical size of each monitor is sent in the + * TS_UD_CS_MONITOR_EX PDU */ if (!s_check_rem(s, 4)) { return 0; } - in_uint8s(s, 4); /* desktopPhysicalWidth */ + in_uint32_le(s, client_info->session_physical_width); LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE " - " desktopPhysicalWidth (ignored)"); + " desktopPhysicalWidth %u", + client_info->session_physical_width); if (!s_check_rem(s, 4)) { + client_info->session_physical_width = 0; return 0; } - in_uint8s(s, 4); /* desktopPhysicalHeight */ + in_uint32_le(s, client_info->session_physical_height); LOG_DEVEL(LOG_LEVEL_TRACE, "Received [MS-RDPBCGR] TS_UD_CS_CORE " - " desktopPhysicalHeight (ignored)"); + " desktopPhysicalHeight %u", + client_info->session_physical_height); + /* MS-RDPBCGR 2.2.1.3.2 */ + if (client_info->session_physical_width < 10 || + client_info->session_physical_width > 10000 || + client_info->session_physical_height < 10 || + client_info->session_physical_height > 10000) + { + LOG(LOG_LEVEL_WARNING, + "Physical desktop dimensions (%ux%u) are invalid", + client_info->session_physical_width, + client_info->session_physical_height); + client_info->session_physical_width = 0; + client_info->session_physical_height = 0; + } if (!s_check_rem(s, 2)) { return 0; @@ -2407,6 +2432,45 @@ xrdp_sec_process_mcs_data_monitors(struct xrdp_sec *self, struct stream *s) return error; } +/*****************************************************************************/ +/* Process a [MS-RDPBCGR] TS_UD_CS_MONITOR_EX message. + reads the client monitor's extended data */ +int +xrdp_sec_process_mcs_data_monitors_ex(struct xrdp_sec *self, struct stream *s) +{ + int flags; + struct xrdp_client_info *client_info = &(self->rdp_layer->client_info); + + LOG_DEVEL(LOG_LEVEL_TRACE, "xrdp_sec_process_mcs_data_monitors_ex:"); + + /* this is an option set in xrdp.ini */ + if (client_info->multimon != 1) /* are multi-monitors allowed ? */ + { + /* This should already be logged in + xrdp_sec_process_mcs_data_monitors() */ + return 0; + } + if (!s_check_rem_and_log(s, 4, + "xrdp_sec_process_mcs_data_monitors_ex:" + " Parsing [MS-RDPBCGR] TS_UD_CS_MONITOR_EX")) + { + return SEC_PROCESS_MONITORS_ERR; + } + in_uint32_le(s, flags); /* flags */ + + //verify flags - must be 0x0 + if (flags != 0) + { + LOG(LOG_LEVEL_ERROR, + "xrdp_sec_process_mcs_data_monitors_ex: [MS-RDPBCGR]" + " Protocol error: TS_UD_CS_MONITOR_EX flags MUST be zero," + " received: 0x%8.8x", flags); + return SEC_PROCESS_MONITORS_ERR; + } + + return libxrdp_process_monitor_ex_stream(s, &client_info->display_sizes); +} + /*****************************************************************************/ /* Process a Client MCS Connect Initial PDU with GCC Conference Create Request. process client mcs data, we need some things in here to create the server @@ -2418,6 +2482,7 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self) char *hold_p = (char *)NULL; int tag = 0; int size = 0; + struct xrdp_client_info *client_info = &self->rdp_layer->client_info; s = &(self->client_mcs_data); /* set p to beginning */ @@ -2486,8 +2551,15 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self) return 1; } break; + case SEC_TAG_CLI_MONITOR_EX: /* CS_MONITOR_EX 0xC008 */ + if (xrdp_sec_process_mcs_data_monitors_ex(self, s) != 0) + { + LOG(LOG_LEVEL_ERROR, + "Processing [MS-RDPBCGR] TS_UD_CS_MONITOR_EX failed"); + return 1; + } + break; /* CS_MCS_MSGCHANNEL 0xC006 - CS_MONITOR_EX 0xC008 CS_MULTITRANSPORT 0xC00A SC_CORE 0x0C01 SC_SECURITY 0x0C02 @@ -2504,19 +2576,17 @@ xrdp_sec_process_mcs_data(struct xrdp_sec *self) s->p = hold_p + size; } - if (self->rdp_layer->client_info.max_bpp > 0) + if (client_info->max_bpp > 0) { - if (self->rdp_layer->client_info.bpp > - self->rdp_layer->client_info.max_bpp) + if (client_info->bpp > client_info->max_bpp) { LOG(LOG_LEVEL_WARNING, "Client requested %d bpp color depth, " "but the server configuration is limited to %d bpp. " "Downgrading the color depth to %d bits-per-pixel.", - self->rdp_layer->client_info.bpp, - self->rdp_layer->client_info.max_bpp, - self->rdp_layer->client_info.max_bpp); - self->rdp_layer->client_info.bpp = - self->rdp_layer->client_info.max_bpp; + client_info->bpp, + client_info->max_bpp, + client_info->max_bpp); + client_info->bpp = client_info->max_bpp; } }