|
29 | 29 | #include "ms-rdpbcgr.h" |
30 | 30 |
|
31 | 31 | #define MAX_BITMAP_BUF_SIZE (16 * 1024) /* 16K */ |
| 32 | +#define TS_MONITOR_ATTRIBUTES_SIZE 20 /* [MS-RDPBCGR] 2.2.1.3.9 */ |
32 | 33 |
|
33 | 34 | /******************************************************************************/ |
34 | 35 | struct xrdp_session *EXPORT_CC |
@@ -1764,6 +1765,97 @@ libxrdp_send_session_info(struct xrdp_session *session, const char *data, |
1764 | 1765 | return xrdp_rdp_send_session_info(rdp, data, data_bytes); |
1765 | 1766 | } |
1766 | 1767 |
|
| 1768 | +/*****************************************************************************/ |
| 1769 | +/* |
| 1770 | + Sanitise extended monitor attributes |
| 1771 | +
|
| 1772 | + The extended attributes are received from either |
| 1773 | + [MS-RDPEDISP] 2.2.2.2.1 (DISPLAYCONTROL_MONITOR_LAYOUT), or |
| 1774 | + [MS-RDPBCGR] 2.2.1.3.9.1 (TS_MONITOR_ATTRIBUTES) |
| 1775 | +
|
| 1776 | + @param monitor_layout struct containing extended attributes |
| 1777 | +*/ |
| 1778 | +static void |
| 1779 | +sanitise_extended_monitor_attributes(struct monitor_info *monitor_layout) |
| 1780 | +{ |
| 1781 | + /* if EITHER physical_width or physical_height are |
| 1782 | + * out of range, BOTH must be ignored. |
| 1783 | + */ |
| 1784 | + if (monitor_layout->physical_width > 10000 |
| 1785 | + || monitor_layout->physical_width < 10) |
| 1786 | + { |
| 1787 | + LOG(LOG_LEVEL_WARNING, "sanitise_extended_monitor_attributes:" |
| 1788 | + " physical_width is not within valid range." |
| 1789 | + " Setting physical_width to 0mm," |
| 1790 | + " Setting physical_height to 0mm," |
| 1791 | + " physical_width was: %d", |
| 1792 | + monitor_layout->physical_width); |
| 1793 | + monitor_layout->physical_width = 0; |
| 1794 | + monitor_layout->physical_height = 0; |
| 1795 | + } |
| 1796 | + |
| 1797 | + if (monitor_layout->physical_height > 10000 |
| 1798 | + || monitor_layout->physical_height < 10) |
| 1799 | + { |
| 1800 | + LOG(LOG_LEVEL_WARNING, "sanitise_extended_monitor_attributes:" |
| 1801 | + " physical_height is not within valid range." |
| 1802 | + " Setting physical_width to 0mm," |
| 1803 | + " Setting physical_height to 0mm," |
| 1804 | + " physical_height was: %d", |
| 1805 | + monitor_layout->physical_height); |
| 1806 | + monitor_layout->physical_width = 0; |
| 1807 | + monitor_layout->physical_height = 0; |
| 1808 | + } |
| 1809 | + |
| 1810 | + switch (monitor_layout->orientation) |
| 1811 | + { |
| 1812 | + case ORIENTATION_LANDSCAPE: |
| 1813 | + case ORIENTATION_PORTRAIT: |
| 1814 | + case ORIENTATION_LANDSCAPE_FLIPPED: |
| 1815 | + case ORIENTATION_PORTRAIT_FLIPPED: |
| 1816 | + break; |
| 1817 | + default: |
| 1818 | + LOG(LOG_LEVEL_WARNING, "sanitise_extended_monitor_attributes:" |
| 1819 | + " Orientation is not one of %d, %d, %d, or %d." |
| 1820 | + " Value was %d and ignored and set to default value of LANDSCAPE.", |
| 1821 | + ORIENTATION_LANDSCAPE, |
| 1822 | + ORIENTATION_PORTRAIT, |
| 1823 | + ORIENTATION_LANDSCAPE_FLIPPED, |
| 1824 | + ORIENTATION_PORTRAIT_FLIPPED, |
| 1825 | + monitor_layout->orientation); |
| 1826 | + monitor_layout->orientation = ORIENTATION_LANDSCAPE; |
| 1827 | + } |
| 1828 | + |
| 1829 | + int check_desktop_scale_factor |
| 1830 | + = monitor_layout->desktop_scale_factor < 100 |
| 1831 | + || monitor_layout->desktop_scale_factor > 500; |
| 1832 | + if (check_desktop_scale_factor) |
| 1833 | + { |
| 1834 | + LOG(LOG_LEVEL_WARNING, "sanitise_extended_monitor_attributes:" |
| 1835 | + " desktop_scale_factor is not within valid range" |
| 1836 | + " of [100, 500]. Assuming 100. Value was: %d", |
| 1837 | + monitor_layout->desktop_scale_factor); |
| 1838 | + } |
| 1839 | + |
| 1840 | + int check_device_scale_factor |
| 1841 | + = monitor_layout->device_scale_factor != 100 |
| 1842 | + && monitor_layout->device_scale_factor != 140 |
| 1843 | + && monitor_layout->device_scale_factor != 180; |
| 1844 | + if (check_device_scale_factor) |
| 1845 | + { |
| 1846 | + LOG(LOG_LEVEL_WARNING, "sanitise_extended_monitor_attributes:" |
| 1847 | + " device_scale_factor a valid value (One of 100, 140, 180)." |
| 1848 | + " Assuming 100. Value was: %d", |
| 1849 | + monitor_layout->device_scale_factor); |
| 1850 | + } |
| 1851 | + |
| 1852 | + if (check_desktop_scale_factor || check_device_scale_factor) |
| 1853 | + { |
| 1854 | + monitor_layout->desktop_scale_factor = 100; |
| 1855 | + monitor_layout->device_scale_factor = 100; |
| 1856 | + } |
| 1857 | +} |
| 1858 | + |
1767 | 1859 | /*****************************************************************************/ |
1768 | 1860 | /* |
1769 | 1861 | Process a [MS-RDPBCGR] TS_UD_CS_MONITOR message. |
@@ -1907,87 +1999,11 @@ libxrdp_process_monitor_stream(struct stream *s, |
1907 | 1999 |
|
1908 | 2000 | in_uint32_le(s, monitor_layout->physical_width); |
1909 | 2001 | in_uint32_le(s, monitor_layout->physical_height); |
1910 | | - |
1911 | | - /* Per spec (2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT), |
1912 | | - * if EITHER physical_width or physical_height are |
1913 | | - * out of range, BOTH must be ignored. |
1914 | | - */ |
1915 | | - if (monitor_layout->physical_width > 10000 |
1916 | | - || monitor_layout->physical_width < 10) |
1917 | | - { |
1918 | | - LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:" |
1919 | | - " physical_width is not within valid range." |
1920 | | - " Setting physical_width to 0mm," |
1921 | | - " Setting physical_height to 0mm," |
1922 | | - " physical_width was: %d", |
1923 | | - monitor_layout->physical_width); |
1924 | | - monitor_layout->physical_width = 0; |
1925 | | - monitor_layout->physical_height = 0; |
1926 | | - } |
1927 | | - |
1928 | | - if (monitor_layout->physical_height > 10000 |
1929 | | - || monitor_layout->physical_height < 10) |
1930 | | - { |
1931 | | - LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:" |
1932 | | - " physical_height is not within valid range." |
1933 | | - " Setting physical_width to 0mm," |
1934 | | - " Setting physical_height to 0mm," |
1935 | | - " physical_height was: %d", |
1936 | | - monitor_layout->physical_height); |
1937 | | - monitor_layout->physical_width = 0; |
1938 | | - monitor_layout->physical_height = 0; |
1939 | | - } |
1940 | | - |
1941 | 2002 | in_uint32_le(s, monitor_layout->orientation); |
1942 | | - switch (monitor_layout->orientation) |
1943 | | - { |
1944 | | - case ORIENTATION_LANDSCAPE: |
1945 | | - case ORIENTATION_PORTRAIT: |
1946 | | - case ORIENTATION_LANDSCAPE_FLIPPED: |
1947 | | - case ORIENTATION_PORTRAIT_FLIPPED: |
1948 | | - break; |
1949 | | - default: |
1950 | | - LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:" |
1951 | | - " Orientation is not one of %d, %d, %d, or %d." |
1952 | | - " Value was %d and ignored and set to default value of LANDSCAPE.", |
1953 | | - ORIENTATION_LANDSCAPE, |
1954 | | - ORIENTATION_PORTRAIT, |
1955 | | - ORIENTATION_LANDSCAPE_FLIPPED, |
1956 | | - ORIENTATION_PORTRAIT_FLIPPED, |
1957 | | - monitor_layout->orientation); |
1958 | | - monitor_layout->orientation = ORIENTATION_LANDSCAPE; |
1959 | | - } |
1960 | | - |
1961 | 2003 | in_uint32_le(s, monitor_layout->desktop_scale_factor); |
1962 | | - int check_desktop_scale_factor |
1963 | | - = monitor_layout->desktop_scale_factor < 100 |
1964 | | - || monitor_layout->desktop_scale_factor > 500; |
1965 | | - if (check_desktop_scale_factor) |
1966 | | - { |
1967 | | - LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:" |
1968 | | - " desktop_scale_factor is not within valid range" |
1969 | | - " of [100, 500]. Assuming 100. Value was: %d", |
1970 | | - monitor_layout->desktop_scale_factor); |
1971 | | - } |
1972 | | - |
1973 | 2004 | in_uint32_le(s, monitor_layout->device_scale_factor); |
1974 | | - int check_device_scale_factor |
1975 | | - = monitor_layout->device_scale_factor != 100 |
1976 | | - && monitor_layout->device_scale_factor != 140 |
1977 | | - && monitor_layout->device_scale_factor != 180; |
1978 | | - if (check_device_scale_factor) |
1979 | | - { |
1980 | | - LOG(LOG_LEVEL_WARNING, "libxrdp_process_monitor_stream:" |
1981 | | - " device_scale_factor a valid value (One of 100, 140, 180)." |
1982 | | - " Assuming 100. Value was: %d", |
1983 | | - monitor_layout->device_scale_factor); |
1984 | | - } |
1985 | 2005 |
|
1986 | | - if (check_desktop_scale_factor || check_device_scale_factor) |
1987 | | - { |
1988 | | - monitor_layout->desktop_scale_factor = 100; |
1989 | | - monitor_layout->device_scale_factor = 100; |
1990 | | - } |
| 2006 | + sanitise_extended_monitor_attributes(monitor_layout); |
1991 | 2007 |
|
1992 | 2008 | /* |
1993 | 2009 | * 2.2.2.2.1 DISPLAYCONTROL_MONITOR_LAYOUT |
@@ -2137,5 +2153,108 @@ libxrdp_process_monitor_stream(struct stream *s, |
2137 | 2153 | monitor_layout->bottom = |
2138 | 2154 | monitor_layout->bottom - all_monitors_encompassing_bounds.top; |
2139 | 2155 | } |
| 2156 | + |
| 2157 | + return 0; |
| 2158 | +} |
| 2159 | + |
| 2160 | +/*****************************************************************************/ |
| 2161 | +int |
| 2162 | +libxrdp_process_monitor_ex_stream(struct stream *s, |
| 2163 | + struct display_size_description *description) |
| 2164 | +{ |
| 2165 | + uint32_t num_monitor; |
| 2166 | + uint32_t monitor_index; |
| 2167 | + uint32_t attribute_size; |
| 2168 | + struct monitor_info *monitor_layout; |
| 2169 | + |
| 2170 | + LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_process_monitor_ex_stream:"); |
| 2171 | + if (description == NULL) |
| 2172 | + { |
| 2173 | + LOG_DEVEL(LOG_LEVEL_ERROR, "libxrdp_process_monitor_ex_stream: " |
| 2174 | + "description was null. " |
| 2175 | + " Valid pointer to allocated description expected."); |
| 2176 | + return SEC_PROCESS_MONITORS_ERR; |
| 2177 | + } |
| 2178 | + |
| 2179 | + if (!s_check_rem_and_log(s, 4, |
| 2180 | + "libxrdp_process_monitor_ex_stream:" |
| 2181 | + " Parsing [MS-RDPBCGR] TS_UD_CS_MONITOR_EX")) |
| 2182 | + { |
| 2183 | + return SEC_PROCESS_MONITORS_ERR; |
| 2184 | + } |
| 2185 | + |
| 2186 | + in_uint32_le(s, attribute_size); |
| 2187 | + if (attribute_size != TS_MONITOR_ATTRIBUTES_SIZE) |
| 2188 | + { |
| 2189 | + LOG(LOG_LEVEL_ERROR, |
| 2190 | + "libxrdp_process_monitor_ex_stream: [MS-RDPBCGR] Protocol" |
| 2191 | + " error: TS_UD_CS_MONITOR_EX monitorAttributeSize" |
| 2192 | + " MUST be %d, received: %d", |
| 2193 | + TS_MONITOR_ATTRIBUTES_SIZE, attribute_size); |
| 2194 | + return SEC_PROCESS_MONITORS_ERR; |
| 2195 | + } |
| 2196 | + |
| 2197 | + in_uint32_le(s, num_monitor); |
| 2198 | + LOG(LOG_LEVEL_DEBUG, "libxrdp_process_monitor_ex_stream:" |
| 2199 | + " The number of monitors received is: %d", |
| 2200 | + num_monitor); |
| 2201 | + |
| 2202 | + if (num_monitor != description->monitorCount) |
| 2203 | + { |
| 2204 | + LOG(LOG_LEVEL_ERROR, |
| 2205 | + "libxrdp_process_monitor_ex_stream: [MS-RDPBCGR] Protocol" |
| 2206 | + " error: TS_UD_CS_MONITOR monitorCount" |
| 2207 | + " MUST be %d, received: %d", |
| 2208 | + description->monitorCount, num_monitor); |
| 2209 | + return SEC_PROCESS_MONITORS_ERR; |
| 2210 | + } |
| 2211 | + |
| 2212 | + for (monitor_index = 0; monitor_index < num_monitor; ++monitor_index) |
| 2213 | + { |
| 2214 | + if (!s_check_rem_and_log(s, attribute_size, |
| 2215 | + "libxrdp_process_monitor_ex_stream:" |
| 2216 | + " Parsing TS_UD_CS_MONITOR_EX")) |
| 2217 | + { |
| 2218 | + return SEC_PROCESS_MONITORS_ERR; |
| 2219 | + } |
| 2220 | + |
| 2221 | + monitor_layout = description->minfo + monitor_index; |
| 2222 | + |
| 2223 | + in_uint32_le(s, monitor_layout->physical_width); |
| 2224 | + in_uint32_le(s, monitor_layout->physical_height); |
| 2225 | + in_uint32_le(s, monitor_layout->orientation); |
| 2226 | + in_uint32_le(s, monitor_layout->desktop_scale_factor); |
| 2227 | + in_uint32_le(s, monitor_layout->device_scale_factor); |
| 2228 | + |
| 2229 | + sanitise_extended_monitor_attributes(monitor_layout); |
| 2230 | + |
| 2231 | + LOG_DEVEL(LOG_LEVEL_INFO, "libxrdp_process_monitor_ex_stream:" |
| 2232 | + " Received [MS-RDPBCGR] 2.2.1.3.9.1 " |
| 2233 | + " TS_MONITOR_ATTRIBUTES" |
| 2234 | + " Index: %d, PhysicalWidth %d, PhysicalHeight %d," |
| 2235 | + " Orientation %d, DesktopScaleFactor %d," |
| 2236 | + " DeviceScaleFactor %d", |
| 2237 | + monitor_index, |
| 2238 | + monitor_layout->physical_width, |
| 2239 | + monitor_layout->physical_height, |
| 2240 | + monitor_layout->orientation, |
| 2241 | + monitor_layout->desktop_scale_factor, |
| 2242 | + monitor_layout->device_scale_factor); |
| 2243 | + } |
| 2244 | + |
| 2245 | + /* Update non negative monitor info values */ |
| 2246 | + const struct monitor_info *src = description->minfo; |
| 2247 | + struct monitor_info *dst = description->minfo_wm; |
| 2248 | + for (monitor_index = 0; monitor_index < num_monitor; ++monitor_index) |
| 2249 | + { |
| 2250 | + dst->physical_width = src->physical_width; |
| 2251 | + dst->physical_height = src->physical_height; |
| 2252 | + dst->orientation = src->orientation; |
| 2253 | + dst->desktop_scale_factor = src->desktop_scale_factor; |
| 2254 | + dst->device_scale_factor = src->device_scale_factor; |
| 2255 | + ++src; |
| 2256 | + ++dst; |
| 2257 | + } |
| 2258 | + |
2140 | 2259 | return 0; |
2141 | 2260 | } |
0 commit comments