@@ -2298,160 +2298,192 @@ xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s)
22982298 return 0 ;
22992299}
23002300
2301- /*****************************************************************************/
2302- /* Process a [MS-RDPBCGR] TS_UD_CS_MONITOR message.
2303- reads the client monitors data */
2304- static int
2305- xrdp_sec_process_mcs_data_monitors (struct xrdp_sec * self , struct stream * s )
2306- {
2307- int index ;
2308- int monitorCount ;
2309- int flags ;
2310- int x1 ;
2311- int y1 ;
2312- int x2 ;
2313- int y2 ;
2314- int got_primary ;
2315- struct xrdp_client_info * client_info = (struct xrdp_client_info * )NULL ;
2301+ struct display_size_description *
2302+ process_monitor_stream (struct stream * s , int full_parameters ) {
2303+ struct display_size_description * description = (struct display_size_description * )
2304+ g_malloc (sizeof (struct display_size_description ), 1 );
23162305
2317- client_info = & (self -> rdp_layer -> client_info );
2306+ int NumMonitor ;
2307+ struct monitor_info * monitor_layout ;
2308+ struct xrdp_rect rect = {8192 , 8192 , -8192 , -8192 };
23182309
2319- /* this is an option set in xrdp.ini */
2320- if (client_info -> multimon != 1 ) /* are multi-monitors allowed ? */
2321- {
2322- LOG (LOG_LEVEL_INFO , "Multi-monitor is disabled by server config" );
2323- return 0 ;
2324- }
2325- if (!s_check_rem_and_log (s , 8 , "Parsing [MS-RDPBCGR] TS_UD_CS_MONITOR" ))
2326- {
2327- return 1 ;
2328- }
2329- in_uint32_le (s , flags ); /* flags */
2330- in_uint32_le (s , monitorCount );
2331- LOG_DEVEL (LOG_LEVEL_TRACE , "Received [MS-RDPBCGR] TS_UD_CS_MONITOR "
2332- "flags 0x%8.8x, monitorCount %d" , flags , monitorCount );
2310+ in_uint32_le (s , NumMonitor );
2311+ LOG (LOG_LEVEL_DEBUG , " NumMonitor %d" , NumMonitor );
23332312
2334- //verify flags - must be 0x0
2335- if (flags != 0 )
2336- {
2337- LOG (LOG_LEVEL_ERROR ,
2338- "[MS-RDPBCGR] Protocol error: TS_UD_CS_MONITOR flags MUST be zero, "
2339- "received: 0x%8.8x" , flags );
2340- return 1 ;
2341- }
2342- //verify monitorCount - max 16
2343- if (monitorCount > 16 )
2313+ if (NumMonitor >= CLIENT_MONITOR_DATA_MAXIMUM_MONITORS )
23442314 {
23452315 LOG (LOG_LEVEL_ERROR ,
23462316 "[MS-RDPBCGR] Protocol error: TS_UD_CS_MONITOR monitorCount "
2347- "MUST be less than 16, received: %d" , monitorCount );
2348- return 1 ;
2317+ "MUST be less than 16, received: %d" , NumMonitor );
2318+ goto exit_error ;
23492319 }
23502320
2351- client_info -> monitorCount = monitorCount ;
2321+ description -> monitorCount = NumMonitor ;
2322+
2323+ int got_primary = 0 ;
23522324
2353- x1 = 0 ;
2354- y1 = 0 ;
2355- x2 = 0 ;
2356- y2 = 0 ;
2357- got_primary = 0 ;
2358- /* Add client_monitor_data to client_info struct, will later pass to X11rdp */
2359- for (index = 0 ; index < monitorCount ; index ++ )
2325+ for (int monitor_index = 0 ; monitor_index < NumMonitor ; ++ monitor_index )
23602326 {
2361- if (!s_check_rem_and_log (s , 20 , "Parsing [MS-RDPBCGR] TS_UD_CS_MONITOR.TS_MONITOR_DEF " ))
2327+ if (!s_check_rem_and_log (s , full_parameters == 0 ? 20 : 40 , "Parsing monitor definitions. " ))
23622328 {
2363- return 1 ;
2329+ goto exit_error ;
2330+ }
2331+
2332+ monitor_layout = description -> minfo + monitor_index ;
2333+ if (full_parameters != 0 ) {
2334+ in_uint32_le (s , monitor_layout -> flags );
23642335 }
2365- in_uint32_le (s , client_info -> minfo [index ].left );
2366- in_uint32_le (s , client_info -> minfo [index ].top );
2367- in_uint32_le (s , client_info -> minfo [index ].right );
2368- in_uint32_le (s , client_info -> minfo [index ].bottom );
2369- in_uint32_le (s , client_info -> minfo [index ].is_primary );
2370-
2371- LOG_DEVEL (LOG_LEVEL_TRACE , "Received [MS-RDPBCGR] "
2372- "TS_UD_CS_MONITOR.TS_MONITOR_DEF %d "
2373- "left %d, top %d, right %d, bottom %d, flags 0x%8.8x" ,
2374- index ,
2375- client_info -> minfo [index ].left ,
2376- client_info -> minfo [index ].top ,
2377- client_info -> minfo [index ].right ,
2378- client_info -> minfo [index ].bottom ,
2379- client_info -> minfo [index ].is_primary );
2380-
2381- if (index == 0 )
2382- {
2383- x1 = client_info -> minfo [index ].left ;
2384- y1 = client_info -> minfo [index ].top ;
2385- x2 = client_info -> minfo [index ].right ;
2386- y2 = client_info -> minfo [index ].bottom ;
2336+ in_uint32_le (s , monitor_layout -> left );
2337+ in_uint32_le (s , monitor_layout -> top );
2338+ in_uint32_le (s , monitor_layout -> width );
2339+ in_uint32_le (s , monitor_layout -> height );
2340+ if (full_parameters != 0 ) {
2341+ in_uint32_le (s , monitor_layout -> physical_width );
2342+ in_uint32_le (s , monitor_layout -> physical_height );
2343+ in_uint32_le (s , monitor_layout -> orientation );
2344+ in_uint32_le (s , monitor_layout -> desktop_scale_factor );
2345+ in_uint32_le (s , monitor_layout -> device_scale_factor );
2346+ }
2347+
2348+ monitor_layout -> right = monitor_layout -> left + monitor_layout -> width ;
2349+ monitor_layout -> bottom = monitor_layout -> top + monitor_layout -> height ;
2350+
2351+ if (full_parameters != 0 )
2352+ {
2353+ LOG (LOG_LEVEL_INFO , " Index: %d, Flags 0x%8.8x Left %d Top %d "
2354+ "Width %d Height %d PhysicalWidth %d PhysicalHeight %d "
2355+ "Orientation %d DesktopScaleFactor %d DeviceScaleFactor %d" ,
2356+ monitor_index , monitor_layout -> flags , monitor_layout -> left ,
2357+ monitor_layout -> top , monitor_layout -> width , monitor_layout -> height ,
2358+ monitor_layout -> physical_width , monitor_layout -> physical_height ,
2359+ monitor_layout -> orientation , monitor_layout -> desktop_scale_factor ,
2360+ monitor_layout -> device_scale_factor );
23872361 }
23882362 else
23892363 {
2390- x1 = MIN (x1 , client_info -> minfo [index ].left );
2391- y1 = MIN (y1 , client_info -> minfo [index ].top );
2392- x2 = MAX (x2 , client_info -> minfo [index ].right );
2393- y2 = MAX (y2 , client_info -> minfo [index ].bottom );
2364+ LOG_DEVEL (LOG_LEVEL_TRACE , "Received [MS-RDPBCGR] "
2365+ "TS_UD_CS_MONITOR.TS_MONITOR_DEF %d "
2366+ "left %d, top %d, right %d, bottom %d, flags 0x%8.8x" ,
2367+ monitor_index ,
2368+ monitor_layout -> left ,
2369+ monitor_layout -> top ,
2370+ monitor_layout -> right ,
2371+ monitor_layout -> bottom ,
2372+ monitor_layout -> is_primary );
23942373 }
23952374
2396- if (client_info -> minfo [ index ]. is_primary )
2375+ if (monitor_index == 0 )
23972376 {
2398- got_primary = 1 ;
2377+ rect .left = monitor_layout -> left ;
2378+ rect .top = monitor_layout -> top ;
2379+ rect .right = monitor_layout -> right ;
2380+ rect .bottom = monitor_layout -> bottom ;
2381+ }
2382+ else
2383+ {
2384+ rect .left = MIN (monitor_layout -> left , rect .left );
2385+ rect .top = MIN (monitor_layout -> top , rect .top );
2386+ rect .right = MAX (rect .right , monitor_layout -> right );
2387+ rect .bottom = MAX (rect .bottom , monitor_layout -> bottom );
23992388 }
24002389
2401- LOG (LOG_LEVEL_DEBUG ,
2402- "Client monitor [%d]: left= %d, top= %d, right= %d, bottom= %d, "
2403- "is_primary?= %d" ,
2404- index ,
2405- client_info -> minfo [index ].left ,
2406- client_info -> minfo [index ].top ,
2407- client_info -> minfo [index ].right ,
2408- client_info -> minfo [index ].bottom ,
2409- client_info -> minfo [index ].is_primary );
2390+ if (monitor_layout -> is_primary )
2391+ {
2392+ got_primary = 1 ;
2393+ }
24102394 }
24112395
24122396 if (!got_primary )
24132397 {
24142398 /* no primary monitor was set, choose the leftmost monitor as primary */
2415- for (index = 0 ; index < monitorCount ; index ++ )
2399+ for (int monitor_index = 0 ; monitor_index < NumMonitor ; ++ monitor_index )
24162400 {
2417- if ( client_info -> minfo [ index ]. left == x1 &&
2418- client_info -> minfo [ index ]. top == y1 )
2401+ monitor_layout = description -> minfo + monitor_index ;
2402+ if ( monitor_layout -> left != rect . left || monitor_layout -> top != rect . top )
24192403 {
2420- client_info -> minfo [index ].is_primary = 1 ;
2421- break ;
2404+ continue ;
24222405 }
2406+ monitor_layout -> is_primary = 1 ;
24232407 }
24242408 }
24252409
24262410 /* set wm geometry */
2427- if ((x2 > x1 ) && (y2 > y1 ))
2411+ if ((rect . right > rect . left ) && (rect . bottom > rect . top ))
24282412 {
2429- client_info -> width = ( x2 - x1 ) + 1 ;
2430- client_info -> height = ( y2 - y1 ) + 1 ;
2413+ description -> session_width = rect . right - rect . left ;
2414+ description -> session_height = rect . bottom - rect . top ;
24312415 }
24322416 /* make sure virtual desktop size is ok */
2433- if (client_info -> width > 0x7FFE || client_info -> width < 0xC8 ||
2434- client_info -> height > 0x7FFE || client_info -> height < 0xC8 )
2417+ if (description -> session_width > 0x7FFE || description -> session_width < 0xC8 ||
2418+ description -> session_height > 0x7FFE || description -> session_height < 0xC8 )
24352419 {
2436- LOG (LOG_LEVEL_ERROR ,
2420+ LOG (LOG_LEVEL_INFO ,
24372421 "Client supplied virtual desktop width or height is invalid. "
24382422 "Allowed width range: min %d, max %d. Width received: %d. "
24392423 "Allowed height range: min %d, max %d. Height received: %d" ,
2440- 0xC8 , 0x7FFE , client_info -> width ,
2441- 0xC8 , 0x7FFE , client_info -> height );
2442- return 1 ; /* error */
2424+ 0xC8 , 0x7FFE , description -> session_width ,
2425+ 0xC8 , 0x7FFE , description -> session_width );
2426+ goto exit_error ;
24432427 }
24442428
24452429 /* keep a copy of non negative monitor info values for xrdp_wm usage */
2446- for (index = 0 ; index < monitorCount ; index ++ )
2430+ for (int monitor_index = 0 ; monitor_index < NumMonitor ; ++ monitor_index )
2431+ {
2432+ monitor_layout = description -> minfo_wm + monitor_index ;
2433+
2434+ g_memcpy (monitor_layout , description -> minfo + monitor_index , sizeof (struct monitor_info ));
2435+
2436+ monitor_layout -> left = monitor_layout -> left - rect .left ;
2437+ monitor_layout -> top = monitor_layout -> top - rect .top ;
2438+ monitor_layout -> right = monitor_layout -> right - rect .left ;
2439+ monitor_layout -> bottom = monitor_layout -> bottom - rect .top ;
2440+ }
2441+ return description ;
2442+ exit_error :
2443+ g_free (description );
2444+ return NULL ;
2445+ }
2446+
2447+ /*****************************************************************************/
2448+ /* Process a [MS-RDPBCGR] TS_UD_CS_MONITOR message.
2449+ reads the client monitors data */
2450+ static int
2451+ xrdp_sec_process_mcs_data_monitors (struct xrdp_sec * self , struct stream * s )
2452+ {
2453+ int flags ;
2454+ struct xrdp_client_info * client_info = & (self -> rdp_layer -> client_info );
2455+
2456+ /* this is an option set in xrdp.ini */
2457+ if (client_info -> multimon != 1 ) /* are multi-monitors allowed ? */
2458+ {
2459+ LOG (LOG_LEVEL_INFO , "Multi-monitor is disabled by server config" );
2460+ return 0 ;
2461+ }
2462+ if (!s_check_rem_and_log (s , 8 , "Parsing [MS-RDPBCGR] TS_UD_CS_MONITOR" ))
2463+ {
2464+ return 1 ;
2465+ }
2466+ in_uint32_le (s , flags ); /* flags */
2467+
2468+ //verify flags - must be 0x0
2469+ if (flags != 0 )
24472470 {
2448- client_info -> minfo_wm [index ].left = client_info -> minfo [index ].left - x1 ;
2449- client_info -> minfo_wm [index ].top = client_info -> minfo [index ].top - y1 ;
2450- client_info -> minfo_wm [index ].right = client_info -> minfo [index ].right - x1 ;
2451- client_info -> minfo_wm [index ].bottom = client_info -> minfo [index ].bottom - y1 ;
2452- client_info -> minfo_wm [index ].is_primary = client_info -> minfo [index ].is_primary ;
2471+ LOG (LOG_LEVEL_ERROR ,
2472+ "[MS-RDPBCGR] Protocol error: TS_UD_CS_MONITOR flags MUST be zero, "
2473+ "received: 0x%8.8x" , flags );
2474+ return 1 ;
24532475 }
24542476
2477+ struct display_size_description * description = process_monitor_stream (s , 0 );
2478+
2479+ client_info -> monitorCount = description -> monitorCount ;
2480+ client_info -> width = description -> session_width ;
2481+ client_info -> height = description -> session_height ;
2482+ g_memcpy (client_info -> minfo , description -> minfo , sizeof (struct monitor_info ) * CLIENT_MONITOR_DATA_MAXIMUM_MONITORS );
2483+ g_memcpy (client_info -> minfo_wm , description -> minfo_wm , sizeof (struct monitor_info ) * CLIENT_MONITOR_DATA_MAXIMUM_MONITORS );
2484+
2485+ g_free (description );
2486+
24552487 return 0 ;
24562488}
24572489
0 commit comments