Merge pull request #4288 from hardening/disp_channel

Disp channel changes and improvements
This commit is contained in:
Martin Fleisz 2017-12-05 10:56:14 +01:00 committed by GitHub
commit ed9a4b7d45
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 104 additions and 62 deletions

View File

@ -176,8 +176,11 @@ UINT disp_send_display_control_monitor_layout_pdu(DISP_CHANNEL_CALLBACK* callbac
UINT disp_recv_display_control_caps_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* s) UINT disp_recv_display_control_caps_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* s)
{ {
DISP_PLUGIN* disp; DISP_PLUGIN* disp;
DispClientContext *context;
UINT ret = CHANNEL_RC_OK;
disp = (DISP_PLUGIN*) callback->plugin; disp = (DISP_PLUGIN*) callback->plugin;
context = (DispClientContext *)disp->iface.pInterface;
if (Stream_GetRemainingLength(s) < 12) if (Stream_GetRemainingLength(s) < 12)
{ {
@ -188,10 +191,11 @@ UINT disp_recv_display_control_caps_pdu(DISP_CHANNEL_CALLBACK* callback, wStream
Stream_Read_UINT32(s, disp->MaxNumMonitors); /* MaxNumMonitors (4 bytes) */ Stream_Read_UINT32(s, disp->MaxNumMonitors); /* MaxNumMonitors (4 bytes) */
Stream_Read_UINT32(s, disp->MaxMonitorAreaFactorA); /* MaxMonitorAreaFactorA (4 bytes) */ Stream_Read_UINT32(s, disp->MaxMonitorAreaFactorA); /* MaxMonitorAreaFactorA (4 bytes) */
Stream_Read_UINT32(s, disp->MaxMonitorAreaFactorB); /* MaxMonitorAreaFactorB (4 bytes) */ Stream_Read_UINT32(s, disp->MaxMonitorAreaFactorB); /* MaxMonitorAreaFactorB (4 bytes) */
//WLog_ERR(TAG, "DisplayControlCapsPdu: MaxNumMonitors: %"PRIu32" MaxMonitorAreaFactorA: %"PRIu32" MaxMonitorAreaFactorB: %"PRIu32"",
// disp->MaxNumMonitors, disp->MaxMonitorAreaFactorA, disp->MaxMonitorAreaFactorB);
return CHANNEL_RC_OK; if (context->DisplayControlCaps)
ret = context->DisplayControlCaps(context, disp->MaxNumMonitors, disp->MaxMonitorAreaFactorA, disp->MaxMonitorAreaFactorB);
return ret;
} }
/** /**

View File

@ -486,7 +486,7 @@ static UINT dvcman_create_channel(IWTSVirtualChannelManager* pChannelMgr,
listener->iface.pInterface); listener->iface.pInterface);
if (error) if (error)
WLog_ERR(TAG, "context.ReceiveSamples failed with error %"PRIu32"", error); WLog_ERR(TAG, "context.OnChannelConnected failed with error %"PRIu32"", error);
return error; return error;
} }
@ -520,8 +520,8 @@ static UINT dvcman_open_channel(IWTSVirtualChannelManager* pChannelMgr,
DVCMAN_CHANNEL* channel; DVCMAN_CHANNEL* channel;
IWTSVirtualChannelCallback* pCallback; IWTSVirtualChannelCallback* pCallback;
UINT error; UINT error;
channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId);
channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId);
if (!channel) if (!channel)
{ {
WLog_ERR(TAG, "ChannelId %"PRIu32" not found!", ChannelId); WLog_ERR(TAG, "ChannelId %"PRIu32" not found!", ChannelId);
@ -948,11 +948,9 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp,
WLog_Print(drdynvc->log, WLOG_DEBUG, "process_create_request: ChannelId=%"PRIu32" ChannelName=%s", WLog_Print(drdynvc->log, WLOG_DEBUG, "process_create_request: ChannelId=%"PRIu32" ChannelName=%s",
ChannelId, ChannelId,
Stream_Pointer(s)); Stream_Pointer(s));
channel_status = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, channel_status = dvcman_create_channel(drdynvc->channel_mgr, ChannelId, (char*) Stream_Pointer(s));
(char*) Stream_Pointer(s));
data_out = Stream_New(NULL, pos + 4); data_out = Stream_New(NULL, pos + 4);
if (!data_out)
if (!s)
{ {
WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!"); WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!");
return CHANNEL_RC_NO_MEMORY; return CHANNEL_RC_NO_MEMORY;
@ -970,12 +968,10 @@ static UINT drdynvc_process_create_request(drdynvcPlugin* drdynvc, int Sp,
else else
{ {
WLog_Print(drdynvc->log, WLOG_DEBUG, "no listener"); WLog_Print(drdynvc->log, WLOG_DEBUG, "no listener");
Stream_Write_UINT32(data_out, Stream_Write_UINT32(data_out, (UINT32)0xC0000001); /* same code used by mstsc */
(UINT32) 0xC0000001); /* same code used by mstsc */
} }
status = drdynvc_send(drdynvc, data_out); status = drdynvc_send(drdynvc, data_out);
if (status != CHANNEL_RC_OK) if (status != CHANNEL_RC_OK)
{ {
WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]", WLog_ERR(TAG, "VirtualChannelWriteEx failed with %s [%08"PRIX32"]",
@ -1063,7 +1059,6 @@ static UINT drdynvc_process_close_request(drdynvcPlugin* drdynvc, int Sp,
} }
data_out = Stream_New(NULL, 4); data_out = Stream_New(NULL, 4);
if (!data_out) if (!data_out)
{ {
WLog_ERR(TAG, "Stream_New failed!"); WLog_ERR(TAG, "Stream_New failed!");

View File

@ -145,6 +145,10 @@ set(XRENDER_FEATURE_TYPE "RECOMMENDED")
set(XRENDER_FEATURE_PURPOSE "rendering") set(XRENDER_FEATURE_PURPOSE "rendering")
set(XRENDER_FEATURE_DESCRIPTION "X11 render extension") set(XRENDER_FEATURE_DESCRIPTION "X11 render extension")
set(XRANDR_FEATURE_TYPE "RECOMMENDED")
set(XRANDR_FEATURE_PURPOSE "tracking output configuration")
set(XRANDR_FEATURE_DESCRIPTION "X11 randr extension")
set(XFIXES_FEATURE_TYPE "RECOMMENDED") set(XFIXES_FEATURE_TYPE "RECOMMENDED")
set(XFIXES_FEATURE_PURPOSE "X11 xfixes extension") set(XFIXES_FEATURE_PURPOSE "X11 xfixes extension")
set(XFIXES_FEATURE_DESCRIPTION "Useful additions to the X11 core protocol") set(XFIXES_FEATURE_DESCRIPTION "Useful additions to the X11 core protocol")
@ -156,6 +160,7 @@ find_feature(Xcursor ${XCURSOR_FEATURE_TYPE} ${XCURSOR_FEATURE_PURPOSE} ${XCURSO
find_feature(Xv ${XV_FEATURE_TYPE} ${XV_FEATURE_PURPOSE} ${XV_FEATURE_DESCRIPTION}) find_feature(Xv ${XV_FEATURE_TYPE} ${XV_FEATURE_PURPOSE} ${XV_FEATURE_DESCRIPTION})
find_feature(Xi ${XI_FEATURE_TYPE} ${XI_FEATURE_PURPOSE} ${XI_FEATURE_DESCRIPTION}) find_feature(Xi ${XI_FEATURE_TYPE} ${XI_FEATURE_PURPOSE} ${XI_FEATURE_DESCRIPTION})
find_feature(Xrender ${XRENDER_FEATURE_TYPE} ${XRENDER_FEATURE_PURPOSE} ${XRENDER_FEATURE_DESCRIPTION}) find_feature(Xrender ${XRENDER_FEATURE_TYPE} ${XRENDER_FEATURE_PURPOSE} ${XRENDER_FEATURE_DESCRIPTION})
find_feature(XRandR ${XRANDR_FEATURE_TYPE} ${XRANDR_FEATURE_PURPOSE} ${XRANDR_FEATURE_DESCRIPTION})
find_feature(Xfixes ${XFIXES_FEATURE_TYPE} ${XFIXES_FEATURE_PURPOSE} ${XFIXES_FEATURE_DESCRIPTION}) find_feature(Xfixes ${XFIXES_FEATURE_TYPE} ${XFIXES_FEATURE_PURPOSE} ${XFIXES_FEATURE_DESCRIPTION})
if(WITH_XINERAMA) if(WITH_XINERAMA)
@ -194,6 +199,12 @@ if(WITH_XRENDER)
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XRENDER_LIBRARIES}) set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XRENDER_LIBRARIES})
endif() endif()
if(NOT APPLE AND WITH_XRANDR)
add_definitions(-DWITH_XRANDR)
include_directories(${XRANDR_INCLUDE_DIRS})
set(${MODULE_PREFIX}_LIBS ${${MODULE_PREFIX}_LIBS} ${XRANDR_LIBRARIES})
endif()
if(WITH_XFIXES) if(WITH_XFIXES)
add_definitions(-DWITH_XFIXES) add_definitions(-DWITH_XFIXES)
include_directories(${XFIXES_INCLUDE_DIRS}) include_directories(${XFIXES_INCLUDE_DIRS})

View File

@ -3,6 +3,7 @@
* X11 Monitor Handling * X11 Monitor Handling
* *
* Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com> * Copyright 2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
* Copyright 2017 David Fort <contact@hardening-consulting.com>
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@ -37,30 +38,50 @@
#include <X11/extensions/Xinerama.h> #include <X11/extensions/Xinerama.h>
#endif #endif
#ifdef WITH_XRANDR
#include <X11/extensions/Xrandr.h>
#include <X11/extensions/randr.h>
#endif
#include "xf_monitor.h" #include "xf_monitor.h"
/* See MSDN Section on Multiple Display Monitors: http://msdn.microsoft.com/en-us/library/dd145071 */ /* See MSDN Section on Multiple Display Monitors: http://msdn.microsoft.com/en-us/library/dd145071 */
int xf_list_monitors(xfContext* xfc) int xf_list_monitors(xfContext* xfc)
{ {
#ifdef WITH_XINERAMA
Display* display; Display* display;
int major, minor; int major, minor;
int i, nmonitors = 0; int i, nmonitors = 0;
XineramaScreenInfo* screen = NULL;
display = XOpenDisplay(NULL);
display = XOpenDisplay(NULL);
if (!display) if (!display)
{ {
WLog_ERR(TAG, "failed to open X display"); WLog_ERR(TAG, "failed to open X display");
return -1; return -1;
} }
#ifdef WITH_XRANDR
if (XRRQueryExtension(xfc->display, &major, &minor))
{
XRRMonitorInfo *monitors = XRRGetMonitors(xfc->display, DefaultRootWindow(xfc->display), 1, &nmonitors);
for (i = 0; i < nmonitors; i++)
{
printf(" %s [%d] %hdx%hd\t+%hd+%hd\n",
monitors[i].primary ? "*" : " ", i,
monitors[i].width, monitors[i].height,
monitors[i].x, monitors[i].y);
}
XRRFreeMonitors(monitors);
} else
#endif
#ifdef WITH_XINERAMA
if (XineramaQueryExtension(display, &major, &minor)) if (XineramaQueryExtension(display, &major, &minor))
{ {
if (XineramaIsActive(display)) if (XineramaIsActive(display))
{ {
screen = XineramaQueryScreens(display, &nmonitors); XineramaScreenInfo* screen = XineramaQueryScreens(display, &nmonitors);
for (i = 0; i < nmonitors; i++) for (i = 0; i < nmonitors; i++)
{ {
@ -72,25 +93,16 @@ int xf_list_monitors(xfContext* xfc)
XFree(screen); XFree(screen);
} }
} } else
XCloseDisplay(display);
#else #else
Screen* screen;
Display* display;
display = XOpenDisplay(NULL);
if (!display)
{ {
WLog_ERR(TAG, "failed to open X display"); Screen* screen = ScreenOfDisplay(display, DefaultScreen(display));
return -1; printf(" * [0] %dx%d\t+0+0\n", WidthOfScreen(screen), HeightOfScreen(screen));
} }
screen = ScreenOfDisplay(display, DefaultScreen(display));
printf(" * [0] %dx%d\t+0+0\n", WidthOfScreen(screen),
HeightOfScreen(screen));
XCloseDisplay(display);
#endif #endif
XCloseDisplay(display);
return 0; return 0;
} }
@ -123,9 +135,8 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
Window _dummy_w; Window _dummy_w;
int current_monitor = 0; int current_monitor = 0;
Screen* screen; Screen* screen;
#ifdef WITH_XINERAMA #if defined WITH_XINERAMA || defined WITH_XRANDR
int major, minor; int major, minor;
XineramaScreenInfo* screenInfo = NULL;
#endif #endif
vscreen = &xfc->vscreen; vscreen = &xfc->vscreen;
*pMaxWidth = settings->DesktopWidth; *pMaxWidth = settings->DesktopWidth;
@ -137,41 +148,59 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight)
&_dummy_i, &_dummy_i, (void*) &_dummy_i)) &_dummy_i, &_dummy_i, (void*) &_dummy_i))
mouse_x = mouse_y = 0; mouse_x = mouse_y = 0;
#ifdef WITH_XINERAMA #ifdef WITH_XRANDR
if (XRRQueryExtension(xfc->display, &major, &minor))
if (XineramaQueryExtension(xfc->display, &major, &minor))
{ {
if (XineramaIsActive(xfc->display)) XRRMonitorInfo *monitors = XRRGetMonitors(xfc->display, DefaultRootWindow(xfc->display), 1, &vscreen->nmonitors);
if (vscreen->nmonitors > 16)
vscreen->nmonitors = 0;
if (vscreen->nmonitors)
{ {
screenInfo = XineramaQueryScreens(xfc->display, &vscreen->nmonitors); for (i = 0; i < vscreen->nmonitors; i++)
if (vscreen->nmonitors > 16)
vscreen->nmonitors = 0;
if (vscreen->nmonitors)
{ {
for (i = 0; i < vscreen->nmonitors; i++) vscreen->monitors[i].area.left = monitors[i].x;
{ vscreen->monitors[i].area.top = monitors[i].y;
vscreen->monitors[i].area.left = screenInfo[i].x_org; vscreen->monitors[i].area.right = monitors[i].x + monitors[i].width - 1;
vscreen->monitors[i].area.top = screenInfo[i].y_org; vscreen->monitors[i].area.bottom = monitors[i].y + monitors[i].height - 1;
vscreen->monitors[i].area.right = screenInfo[i].x_org + screenInfo[i].width - 1; vscreen->monitors[i].primary = monitors[i].primary > 0;
vscreen->monitors[i].area.bottom = screenInfo[i].y_org + screenInfo[i].height -
1;
/* Determine which monitor that the mouse cursor is on */
if ((mouse_x >= vscreen->monitors[i].area.left) &&
(mouse_x <= vscreen->monitors[i].area.right) &&
(mouse_y >= vscreen->monitors[i].area.top) &&
(mouse_y <= vscreen->monitors[i].area.bottom))
current_monitor = i;
}
} }
XFree(screenInfo);
} }
} XRRFreeMonitors(monitors);
} else
#endif #endif
#ifdef WITH_XINERAMA
if (XineramaQueryExtension(xfc->display, &major, &minor) && XineramaIsActive(xfc->display))
{
XineramaScreenInfo* screenInfo = XineramaQueryScreens(xfc->display, &vscreen->nmonitors);
if (vscreen->nmonitors > 16)
vscreen->nmonitors = 0;
if (vscreen->nmonitors)
{
for (i = 0; i < vscreen->nmonitors; i++)
{
vscreen->monitors[i].area.left = screenInfo[i].x_org;
vscreen->monitors[i].area.top = screenInfo[i].y_org;
vscreen->monitors[i].area.right = screenInfo[i].x_org + screenInfo[i].width - 1;
vscreen->monitors[i].area.bottom = screenInfo[i].y_org + screenInfo[i].height - 1;
/* Determine which monitor that the mouse cursor is on */
if ((mouse_x >= vscreen->monitors[i].area.left) &&
(mouse_x <= vscreen->monitors[i].area.right) &&
(mouse_y >= vscreen->monitors[i].area.top) &&
(mouse_y <= vscreen->monitors[i].area.bottom))
current_monitor = i;
}
}
XFree(screenInfo);
}
#endif
xfc->fullscreenMonitors.top = xfc->fullscreenMonitors.bottom = xfc->fullscreenMonitors.top = xfc->fullscreenMonitors.bottom =
xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right = 0; xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right = 0;

View File

@ -52,6 +52,8 @@ typedef struct _DISPLAY_CONTROL_MONITOR_LAYOUT DISPLAY_CONTROL_MONITOR_LAYOUT;
typedef struct _disp_client_context DispClientContext; typedef struct _disp_client_context DispClientContext;
typedef UINT (*pcDispCaps)(DispClientContext* context, UINT32 MaxNumMonitors, UINT32 MaxMonitorAreaFactorA,
UINT32 MaxMonitorAreaFactorB);
typedef UINT (*pcDispSendMonitorLayout)(DispClientContext* context, UINT32 NumMonitors, DISPLAY_CONTROL_MONITOR_LAYOUT* Monitors); typedef UINT (*pcDispSendMonitorLayout)(DispClientContext* context, UINT32 NumMonitors, DISPLAY_CONTROL_MONITOR_LAYOUT* Monitors);
struct _disp_client_context struct _disp_client_context
@ -59,6 +61,7 @@ struct _disp_client_context
void* handle; void* handle;
void* custom; void* custom;
pcDispCaps DisplayControlCaps;
pcDispSendMonitorLayout SendMonitorLayout; pcDispSendMonitorLayout SendMonitorLayout;
}; };