From 1030f8dad8aa81ebf01a6a5158ac760e01c2df6f Mon Sep 17 00:00:00 2001 From: clouder Date: Thu, 8 Oct 2015 17:20:44 +0800 Subject: [PATCH 01/23] add values-zh/string.xml --- .../FreeRDPCore/res/values-zh/strings.xml | 199 ++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 client/Android/FreeRDPCore/res/values-zh/strings.xml diff --git a/client/Android/FreeRDPCore/res/values-zh/strings.xml b/client/Android/FreeRDPCore/res/values-zh/strings.xml new file mode 100644 index 000000000..09757f3de --- /dev/null +++ b/client/Android/FreeRDPCore/res/values-zh/strings.xml @@ -0,0 +1,199 @@ + + + + + + 取消 + 继续 + 登陆 + 断开 + + 退出 + 关于 + 帮助 + 新建连接 + 设置 + + 操作 + 连接 + 编辑 + 删除 + + 键盘 + 功能键 + 触控鼠标 + 主目录 + 断开连接 + + 手动连接 + 活动会话数 + + 搜索 + + 登录 + 没有服务 + 连接中 … + 正在断开连接 … + 连接丢失 + 密码错误 + 用户名错误 + 新建连接 + + 主机信息 + 标签* + 远程主机ip或域名 + 端口 + 登录信息 + 登录信息 + 用户名 + 密码 + + 设置 + 显示 + 显示设置 + 颜色深度 + + High Color (16 Bit) + True Color (24 Bit) + Highest Quality (32 Bit) + + + 16 + 24 + 32 + + 分辨率 + 自动 + 全屏 + 自定义 + + 自动 + 全屏 + 自定义 + 640x480 + 720x480 + 800x600 + 1024x768 + 1280x1024 + 1440x900 + 1920x1080 + 1920x1200 + + + 自动 + 全屏 + 自定义 + 640x480 + 720x480 + 800x600 + 1024x768 + 1280x1024 + 1440x900 + 1920x1080 + 1920x1200 + + 宽度 + 高度 + 连接性能 + 性能设置 + RemoteFX + 桌面背景 + 字体平滑 + 桌面拼合 + 拖动是显示窗口内容 + 菜单动画效果 + 视觉样式 + 高级 + 高级设置 + 3G设置 + 使用3G网络时的显示设置 + 使用3G网络时的连接性能 + 路由 + 使用路由 + 路由设置 + SDCard 重定向 + 音频重定向 + + 不要播放 + 在远程主机播放 + 在此设备上播放 + + + 0 + 1 + 2 + + 麦克风重定向 + 连接协议 + + 自动 + RDP + TLS + NLA + + + 0 + 1 + 2 + 3 + + 远程程序 + 工作目录 + Async channel + Async transport + Async input + Async update + 控制台模式 + + ******* + 未设置 + 用户界面 + 隐藏状态栏 + 隐藏缩放控件 + 交换鼠标左右键 + 翻转滚动 + 触摸指针自动滚屏 + 退出时确认是否退出 + 省电设计 + 关闭空闲连接 + 安全 + 接受所有证书 + 清除证书缓存 + %1$d 秒后 + Disabled + + 连接设置 + 设置 + aFreeRDP - FreeRDP for Android + RDP Connections + 帮助 + 关于 + + 不保存即退出? + 点击 “继续” 继续编辑,点击 "取消" 放弃当前更改 + 建立连接失败! + + 由于主机不支持您的设置所以显示设置已经修改为适应主机的设置! + 清除证书缓存成功! + 清楚证书缓存失败! + + 证书验证 + 未能验证远程主机证书的安全性,是否连接? + 请输入您的证书 + 创建快捷方式 + 快捷方式名称: + 连接中 … + 正在登录 … + 关于aFreeRDP + 是否保存连接设置? + 连接设置还没保存! 是否保存? + 保存? + 是否保存更改? + 不再提示 + 退出? + 是否退出? + 清除证书缓存? + 是否清除所有的证书缓存? + Debug Level + Debug Settings + From 32e2f81cc5701d169036b86047642cf96a20435f Mon Sep 17 00:00:00 2001 From: Daniel Bungert Date: Wed, 14 Oct 2015 14:16:19 -0600 Subject: [PATCH 02/23] Clamp ultra-wide glyph opRight vals to desktop width --- libfreerdp/cache/glyph.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/libfreerdp/cache/glyph.c b/libfreerdp/cache/glyph.c index 037c5a5d9..0157d40bc 100644 --- a/libfreerdp/cache/glyph.c +++ b/libfreerdp/cache/glyph.c @@ -260,6 +260,12 @@ BOOL update_gdi_fast_index(rdpContext* context, FAST_INDEX_ORDER* fastIndex) if (opRight == 0) opRight = fastIndex->bkRight; + /* Server can send a massive number (32766) which appears to be + * undocumented special behavior for "Erase all the way right". + * X11 has nondeterministic results asking for a draw that wide. */ + if (opRight > context->instance->settings->DesktopWidth) + opRight = context->instance->settings->DesktopWidth; + if (x == -32768) x = fastIndex->bkLeft; @@ -313,6 +319,10 @@ BOOL update_gdi_fast_glyph(rdpContext* context, FAST_GLYPH_ORDER* fastGlyph) if (opRight == 0) opRight = fastGlyph->bkRight; + /* See update_gdi_fast_index opRight comment. */ + if (opRight > context->instance->settings->DesktopWidth) + opRight = context->instance->settings->DesktopWidth; + if (x == -32768) x = fastGlyph->bkLeft; From 6d3565bd4c52125bda5d8bc0b30690d78615c2f5 Mon Sep 17 00:00:00 2001 From: bjcollins Date: Thu, 15 Oct 2015 14:29:48 -0500 Subject: [PATCH 03/23] Fix xf_rail_paint fencepost error The regions used to store and calculate the invalidRegion are exclusive of the bottom and right edges, not inclusive. Fixes "mouse droppings" in mspaint.exe when moving the mouse leftwards across the canvas. --- client/X11/xf_client.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index a788ab2b1..2df32f49e 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -342,7 +342,7 @@ BOOL xf_sw_end_paint(rdpContext* context) xf_lock_x11(xfc, FALSE); - xf_rail_paint(xfc, x, y, x + w - 1, y + h - 1); + xf_rail_paint(xfc, x, y, x + w, y + h); xf_unlock_x11(xfc, FALSE); } @@ -455,7 +455,7 @@ BOOL xf_hw_end_paint(rdpContext* context) xf_lock_x11(xfc, FALSE); - xf_rail_paint(xfc, x, y, x + w - 1, y + h - 1); + xf_rail_paint(xfc, x, y, x + w, y + h); xf_unlock_x11(xfc, FALSE); } From 964f0addbf873c371e0050b7c5ac5133e88130c1 Mon Sep 17 00:00:00 2001 From: bjcollins Date: Thu, 15 Oct 2015 14:31:15 -0500 Subject: [PATCH 04/23] Do not support fullscreen toggle keyboard sequence in remote_app mode. There is no support in interface for this and the fullscreen code is not designed to handle remote app windows. --- client/X11/xf_keyboard.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/X11/xf_keyboard.c b/client/X11/xf_keyboard.c index 1d6d9c06d..243e920d2 100644 --- a/client/X11/xf_keyboard.c +++ b/client/X11/xf_keyboard.c @@ -466,7 +466,7 @@ BOOL xf_keyboard_handle_special_keys(xfContext* xfc, KeySym keysym) return TRUE; } - if(xfc->fullscreen_toggle) + if(!xfc->remote_app && xfc->fullscreen_toggle) { if (keysym == XK_Return) { From 6934c18adff498441a54c5234501379a8fdd6176 Mon Sep 17 00:00:00 2001 From: bjcollins Date: Thu, 15 Oct 2015 14:35:07 -0500 Subject: [PATCH 05/23] Continue processing all other window orders for new remote app windows instead of existing after only looking at part of the information. For instance, window visibility rects are part of the message with the new order and were being ignored. --- client/X11/xf_rail.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index a4617a228..d407cc476 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -299,6 +299,7 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI appWindow->localWindowOffsetCorrX = 0; appWindow->localWindowOffsetCorrY = 0; + /* Ensure window always gets a window title */ if (fieldFlags & WINDOW_ORDER_FIELD_TITLE) { char* title = NULL; @@ -321,8 +322,6 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI HashTable_Add(xfc->railWindows, (void*) (UINT_PTR) orderInfo->windowId, (void*) appWindow); xf_AppWindowInit(xfc, appWindow); - - return TRUE; } else { From 5bfbee8f787206fc5dd912f396120f09ed654b55 Mon Sep 17 00:00:00 2001 From: bjcollins Date: Thu, 15 Oct 2015 14:39:59 -0500 Subject: [PATCH 06/23] Ensure that app windows always get a window type assigned to them. --- client/X11/xf_window.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index b7a4663e2..802613c6c 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -567,9 +567,11 @@ void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UIN } else { - XChangeProperty(xfc->display, appWindow->handle, xfc->_NET_WM_WINDOW_TYPE, - XA_ATOM, 32, PropModeReplace, (BYTE*) &window_type, 1); + window_type = xfc->_NET_WM_WINDOW_TYPE_NORMAL; } + + XChangeProperty(xfc->display, appWindow->handle, xfc->_NET_WM_WINDOW_TYPE, + XA_ATOM, 32, PropModeReplace, (BYTE*) &window_type, 1); } void xf_SetWindowText(xfContext* xfc, xfAppWindow* appWindow, char* name) From d1a8119dac13702bfba92aaab39f5f6c7e3b631f Mon Sep 17 00:00:00 2001 From: bjcollins Date: Thu, 15 Oct 2015 14:47:10 -0500 Subject: [PATCH 07/23] RemoteApp support Remove use of WindowRects to affect window shape, the VisibilityRects are used for this purpose. --- client/X11/xf_rail.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index d407cc476..d5e949580 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -506,7 +506,8 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI if (fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS) { - xf_SetWindowRects(xfc, appWindow, appWindow->windowRects, appWindow->numWindowRects); + /* We should only be using the visibility rects for shaping the window */ + //xf_SetWindowRects(xfc, appWindow, appWindow->windowRects, appWindow->numWindowRects); } if (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY) From cb4e4cf6fcb38efc6d0f9e2fd03c7036b9ede700 Mon Sep 17 00:00:00 2001 From: bjcollins Date: Thu, 15 Oct 2015 14:59:53 -0500 Subject: [PATCH 08/23] Store Miscellaneous X11 Atoms into variables to match how we handle other X11 Atoms. --- client/X11/xf_client.c | 5 +++++ client/X11/xf_window.c | 20 +++++++++++--------- client/X11/xfreerdp.h | 7 +++++++ 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 2df32f49e..49684cba7 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -1850,7 +1850,11 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context) xfc->_NET_WORKAREA = XInternAtom(xfc->display, "_NET_WORKAREA", False); xfc->_NET_WM_STATE = XInternAtom(xfc->display, "_NET_WM_STATE", False); xfc->_NET_WM_STATE_FULLSCREEN = XInternAtom(xfc->display, "_NET_WM_STATE_FULLSCREEN", False); + xfc->_NET_WM_STATE_MAXIMIZED_HORZ = XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False); + xfc->_NET_WM_STATE_MAXIMIZED_VERT = XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False); xfc->_NET_WM_FULLSCREEN_MONITORS = XInternAtom(xfc->display, "_NET_WM_FULLSCREEN_MONITORS", False); + xfc->_NET_WM_NAME = XInternAtom(xfc->display, "_NET_WM_NAME", False); + xfc->_NET_WM_PID = XInternAtom(xfc->display, "_NET_WM_PID", False); xfc->_NET_WM_WINDOW_TYPE = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE", False); xfc->_NET_WM_WINDOW_TYPE_NORMAL = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE_NORMAL", False); xfc->_NET_WM_WINDOW_TYPE_DIALOG = XInternAtom(xfc->display, "_NET_WM_WINDOW_TYPE_DIALOG", False); @@ -1865,6 +1869,7 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context) xfc->WM_DELETE_WINDOW = XInternAtom(xfc->display, "WM_DELETE_WINDOW", False); xfc->WM_STATE = XInternAtom(xfc->display, "WM_STATE", False); + xfc->UTF8_STRING = XInternAtom(xfc->display, "UTF8_STRING", FALSE); xfc->xfds = ConnectionNumber(xfc->display); xfc->screen_number = DefaultScreen(xfc->display); xfc->screen = ScreenOfDisplay(xfc->display, xfc->screen_number); diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index 802613c6c..b9810e55a 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -327,7 +327,7 @@ static void xf_SetWindowPID(xfContext* xfc, Window window, pid_t pid) if (!pid) pid = getpid(); - am_wm_pid = XInternAtom(xfc->display, "_NET_WM_PID", False); + am_wm_pid = xfc->_NET_WM_PID; XChangeProperty(xfc->display, window, am_wm_pid, XA_CARDINAL, 32, PropModeReplace, (BYTE*) &pid, 1); @@ -579,8 +579,8 @@ void xf_SetWindowText(xfContext* xfc, xfAppWindow* appWindow, char* name) const size_t i = strlen(name); XStoreName(xfc->display, appWindow->handle, name); - Atom wm_Name = XInternAtom(xfc->display, "_NET_WM_NAME", FALSE); - Atom utf8Str = XInternAtom(xfc->display, "UTF8_STRING", FALSE); + Atom wm_Name = xfc->_NET_WM_NAME; + Atom utf8Str = xfc->UTF8_STRING; XChangeProperty(xfc->display, appWindow->handle, wm_Name, utf8Str, 8, PropModeReplace, (unsigned char *)name, i); @@ -823,9 +823,10 @@ void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state) case WINDOW_SHOW_MAXIMIZED: /* Set the window as maximized */ - xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4, 1, - XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False), - XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False), 0); + xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4, + _NET_WM_STATE_ADD, + xfc->_NET_WM_STATE_MAXIMIZED_VERT, + xfc->_NET_WM_STATE_MAXIMIZED_HORZ, 0); /* * This is a workaround for the case where the window is maximized locally before the rail server is told to maximize * the window, this appears to be a race condition where the local window with incomplete data and once the window is @@ -840,9 +841,10 @@ void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state) case WINDOW_SHOW: /* Ensure the window is not maximized */ - xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4, 0, - XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_VERT", False), - XInternAtom(xfc->display, "_NET_WM_STATE_MAXIMIZED_HORZ", False), 0); + xf_SendClientEvent(xfc, appWindow->handle, xfc->_NET_WM_STATE, 4, + _NET_WM_STATE_REMOVE, + xfc->_NET_WM_STATE_MAXIMIZED_VERT, + xfc->_NET_WM_STATE_MAXIMIZED_HORZ, 0); /* * Ignore configure requests until both the Maximized properties have been processed * to prevent condition where WM overrides size of request due to one or both of these properties diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index 5e1bdfab1..a885536c7 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -185,6 +185,8 @@ struct xf_context xfClipboard* clipboard; CliprdrClientContext* cliprdr; + Atom UTF8_STRING; + Atom _NET_WM_ICON; Atom _MOTIF_WM_HINTS; Atom _NET_CURRENT_DESKTOP; @@ -192,11 +194,16 @@ struct xf_context Atom _NET_WM_STATE; Atom _NET_WM_STATE_FULLSCREEN; + Atom _NET_WM_STATE_MAXIMIZED_HORZ; + Atom _NET_WM_STATE_MAXIMIZED_VERT; Atom _NET_WM_STATE_SKIP_TASKBAR; Atom _NET_WM_STATE_SKIP_PAGER; Atom _NET_WM_FULLSCREEN_MONITORS; + Atom _NET_WM_NAME; + Atom _NET_WM_PID; + Atom _NET_WM_WINDOW_TYPE; Atom _NET_WM_WINDOW_TYPE_NORMAL; Atom _NET_WM_WINDOW_TYPE_DIALOG; From cc676c44687c58fc6042b0ec1684b9fcf2263757 Mon Sep 17 00:00:00 2001 From: bjcollins Date: Thu, 15 Oct 2015 18:18:21 -0500 Subject: [PATCH 09/23] Remote app support All window state order offsets are signed according to the RDP spec, lets treat them as such. --- client/X11/xf_window.h | 16 ++++++++-------- include/freerdp/window.h | 16 ++++++++-------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/client/X11/xf_window.h b/client/X11/xf_window.h index 9120fd1df..2fd9de22d 100644 --- a/client/X11/xf_window.h +++ b/client/X11/xf_window.h @@ -102,22 +102,22 @@ struct xf_app_window UINT32 dwExStyle; UINT32 showState; - UINT32 clientOffsetX; - UINT32 clientOffsetY; + INT32 clientOffsetX; + INT32 clientOffsetY; UINT32 clientAreaWidth; UINT32 clientAreaHeight; - UINT32 windowOffsetX; - UINT32 windowOffsetY; - UINT32 windowClientDeltaX; - UINT32 windowClientDeltaY; + INT32 windowOffsetX; + INT32 windowOffsetY; + INT32 windowClientDeltaX; + INT32 windowClientDeltaY; UINT32 windowWidth; UINT32 windowHeight; UINT32 numWindowRects; RECTANGLE_16* windowRects; - UINT32 visibleOffsetX; - UINT32 visibleOffsetY; + INT32 visibleOffsetX; + INT32 visibleOffsetY; UINT32 numVisibilityRects; RECTANGLE_16* visibilityRects; diff --git a/include/freerdp/window.h b/include/freerdp/window.h index c52c35c72..4a5b2b84f 100644 --- a/include/freerdp/window.h +++ b/include/freerdp/window.h @@ -174,22 +174,22 @@ struct _WINDOW_STATE_ORDER UINT32 extendedStyle; UINT32 showState; RAIL_UNICODE_STRING titleInfo; - UINT32 clientOffsetX; - UINT32 clientOffsetY; + INT32 clientOffsetX; + INT32 clientOffsetY; UINT32 clientAreaWidth; UINT32 clientAreaHeight; UINT32 RPContent; UINT32 rootParentHandle; - UINT32 windowOffsetX; - UINT32 windowOffsetY; - UINT32 windowClientDeltaX; - UINT32 windowClientDeltaY; + INT32 windowOffsetX; + INT32 windowOffsetY; + INT32 windowClientDeltaX; + INT32 windowClientDeltaY; UINT32 windowWidth; UINT32 windowHeight; UINT32 numWindowRects; RECTANGLE_16* windowRects; - UINT32 visibleOffsetX; - UINT32 visibleOffsetY; + INT32 visibleOffsetX; + INT32 visibleOffsetY; UINT32 numVisibilityRects; RECTANGLE_16* visibilityRects; }; From 8e27b6d05e9bfcc2b869583f14779bce1c07823e Mon Sep 17 00:00:00 2001 From: bjcollins Date: Thu, 15 Oct 2015 18:41:55 -0500 Subject: [PATCH 10/23] RemoteApp Support 1. Remove all uses of "localWindowOffsetCorr" variables, they added an extra layer of complexity and they are not actually needed to handle coordination of window position/size between the local coordinate system and the remote one. This logic was causing issues in the case where the window was moved off the left side of the screen. 2. Update the xf_setWindowVisibilityRects function to offset the visibility rects as necessary when the window is hanging off the left side of the screen. 3. Stop sending mouse events when doing keyboard moves/sizes(as desired), and stop sending two mouse events for non-keyboard moves/sizes 4. Move location of new UTF8_STRING variable from previous commit 5. Refresh window and window shape for any window position/size updates, this helps keep the local and server windows in sync and works around some race conditions --- client/X11/xf_client.c | 3 +- client/X11/xf_event.c | 3 +- client/X11/xf_rail.c | 125 +++++++++++++++++------------------------ client/X11/xf_window.c | 22 +++----- client/X11/xf_window.h | 2 +- 5 files changed, 66 insertions(+), 89 deletions(-) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 49684cba7..a7afe4bfe 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -1865,11 +1865,12 @@ static BOOL xfreerdp_client_new(freerdp* instance, rdpContext* context) xfc->_NET_WM_STATE_SKIP_PAGER = XInternAtom(xfc->display, "_NET_WM_STATE_SKIP_PAGER", False); xfc->_NET_WM_MOVERESIZE = XInternAtom(xfc->display, "_NET_WM_MOVERESIZE", False); xfc->_NET_MOVERESIZE_WINDOW = XInternAtom(xfc->display, "_NET_MOVERESIZE_WINDOW", False); + + xfc->UTF8_STRING = XInternAtom(xfc->display, "UTF8_STRING", FALSE); xfc->WM_PROTOCOLS = XInternAtom(xfc->display, "WM_PROTOCOLS", False); xfc->WM_DELETE_WINDOW = XInternAtom(xfc->display, "WM_DELETE_WINDOW", False); xfc->WM_STATE = XInternAtom(xfc->display, "WM_STATE", False); - xfc->UTF8_STRING = XInternAtom(xfc->display, "UTF8_STRING", FALSE); xfc->xfds = ConnectionNumber(xfc->display); xfc->screen_number = DefaultScreen(xfc->display); xfc->screen = ScreenOfDisplay(xfc->display, xfc->screen_number); diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index 5f13d503d..18328f392 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -278,7 +278,8 @@ BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window win xf_event_adjust_coordinates(xfc, &x, &y); - input->MouseEvent(input, PTR_FLAGS_MOVE, x, y); + if (!app || xf_AppWindowFromX11Window(xfc,window)->local_move.direction != RAIL_WMSZ_KEYSIZE) + input->MouseEvent(input, PTR_FLAGS_MOVE, x, y); if (xfc->fullscreen && !app) { diff --git a/client/X11/xf_rail.c b/client/X11/xf_rail.c index d5e949580..22a941c53 100644 --- a/client/X11/xf_rail.c +++ b/client/X11/xf_rail.c @@ -119,25 +119,17 @@ void xf_rail_adjust_position(xfContext* xfc, xfAppWindow* appWindow) return; /* If current window position disagrees with RDP window position, send update to RDP server */ - if (appWindow->x != (appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX) || - appWindow->y != (appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY) || + if (appWindow->x != appWindow->windowOffsetX || + appWindow->y != appWindow->windowOffsetY || appWindow->width != appWindow->windowWidth || appWindow->height != appWindow->windowHeight) { - /* - * windowOffset corresponds to the window location on the rail server - * but our local window is based uses a local offset since the windowOffset - * can be negative and but X does not support negative values. Not using an - * offset can result in blank areas for a maximized window - */ windowMove.windowId = appWindow->windowId; /* * Calculate new size/position for the rail window(new values for windowOffsetX/windowOffsetY/windowWidth/windowHeight) on the server - * New position is based on: Current local rail window offset + - * Local offset correction(current correction value to translate the local window offset to the server rail window offset) */ - windowMove.left = appWindow->x + appWindow->localWindowOffsetCorrX; - windowMove.top = appWindow->y + appWindow->localWindowOffsetCorrY; + windowMove.left = appWindow->x; + windowMove.top = appWindow->y; windowMove.right = windowMove.left + appWindow->width; windowMove.bottom = windowMove.top + appWindow->height; @@ -163,12 +155,10 @@ void xf_rail_end_local_move(xfContext* xfc, xfAppWindow* appWindow) /* * Calculate new size/position for the rail window(new values for windowOffsetX/windowOffsetY/windowWidth/windowHeight) on the server - * New position is based on: Current local rail window offset + - * Local offset correction(current correction value to translate the local window offset to the server rail window offset) * */ - windowMove.left = appWindow->x + appWindow->localWindowOffsetCorrX; - windowMove.top = appWindow->y + appWindow->localWindowOffsetCorrY; + windowMove.left = appWindow->x; + windowMove.top = appWindow->y; windowMove.right = windowMove.left + appWindow->width; /* In the update to RDP the position is one past the window */ windowMove.bottom = windowMove.top + appWindow->height; @@ -180,8 +170,6 @@ void xf_rail_end_local_move(xfContext* xfc, xfAppWindow* appWindow) XQueryPointer(xfc->display, appWindow->handle, &root_window, &child_window, &x, &y, &child_x, &child_y, &mask); - input->MouseEvent(input, PTR_FLAGS_BUTTON1, x, y); - /* only send the mouse coordinates if not a keyboard move or size */ if ((appWindow->local_move.direction != _NET_WM_MOVERESIZE_MOVE_KEYBOARD) && (appWindow->local_move.direction != _NET_WM_MOVERESIZE_SIZE_KEYBOARD)) @@ -194,8 +182,8 @@ void xf_rail_end_local_move(xfContext* xfc, xfAppWindow* appWindow) * we can start to receive GDI orders for the new window dimensions before we * receive the RAIL ORDER for the new window size. This avoids that race condition. */ - appWindow->windowOffsetX = windowMove.left; - appWindow->windowOffsetY = windowMove.top; + appWindow->windowOffsetX = appWindow->x; + appWindow->windowOffsetY = appWindow->y; appWindow->windowWidth = appWindow->width; appWindow->windowHeight = appWindow->height; appWindow->local_move.state = LMS_TERMINATING; @@ -277,6 +265,7 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI xfAppWindow* appWindow = NULL; xfContext* xfc = (xfContext*) context; UINT32 fieldFlags = orderInfo->fieldFlags; + BOOL position_or_size_updated = FALSE; if (fieldFlags & WINDOW_ORDER_STATE_NEW) { @@ -296,9 +285,6 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI appWindow->width = appWindow->windowWidth = windowState->windowWidth; appWindow->height = appWindow->windowHeight = windowState->windowHeight; - appWindow->localWindowOffsetCorrX = 0; - appWindow->localWindowOffsetCorrY = 0; - /* Ensure window always gets a window title */ if (fieldFlags & WINDOW_ORDER_FIELD_TITLE) { @@ -332,37 +318,31 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI if (!appWindow) return FALSE; + /* Keep track of any position/size update so that we can force a refresh of the window */ + if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) || + (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) || + (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) || + (fieldFlags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) || + (fieldFlags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) || + (fieldFlags & WINDOW_ORDER_FIELD_VIS_OFFSET) || + (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY)) + { + position_or_size_updated = TRUE; + } + + /* Update Parameters */ - if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) || - (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)) + if (fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) { - if (fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) - { - appWindow->windowOffsetX = windowState->windowOffsetX; - appWindow->windowOffsetY = windowState->windowOffsetY; + appWindow->windowOffsetX = windowState->windowOffsetX; + appWindow->windowOffsetY = windowState->windowOffsetY; + } - /* - * The rail server can give negative window coordinates when updating windowOffsetX and windowOffsetY, - * but we can only send unsigned integers to the rail server. Therefore, we maintain a local offset. - */ - - if (appWindow->windowOffsetX < 0) - appWindow->localWindowOffsetCorrX = 0 - appWindow->windowOffsetX; - else - appWindow->localWindowOffsetCorrX = 0; - - if (appWindow->windowOffsetY < 0) - appWindow->localWindowOffsetCorrY = 0 - appWindow->windowOffsetY; - else - appWindow->localWindowOffsetCorrY = 0; - } - - if (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) - { - appWindow->windowWidth = windowState->windowWidth; - appWindow->windowHeight = windowState->windowHeight; - } + if (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE) + { + appWindow->windowWidth = windowState->windowWidth; + appWindow->windowHeight = windowState->windowHeight; } if (fieldFlags & WINDOW_ORDER_FIELD_OWNER) @@ -478,42 +458,43 @@ static BOOL xf_rail_window_common(rdpContext* context, WINDOW_ORDER_INFO* orderI xf_SetWindowText(xfc, appWindow, appWindow->title); } - if ((fieldFlags & WINDOW_ORDER_FIELD_WND_OFFSET) || - (fieldFlags & WINDOW_ORDER_FIELD_WND_SIZE)) + if (position_or_size_updated) { + UINT32 visibilityRectsOffsetX = (appWindow->visibleOffsetX - (appWindow->clientOffsetX - appWindow->windowClientDeltaX)); + UINT32 visibilityRectsOffsetY = (appWindow->visibleOffsetY - (appWindow->clientOffsetY - appWindow->windowClientDeltaY)); + /* * The rail server like to set the window to a small size when it is minimized even though it is hidden * in some cases this can cause the window not to restore back to its original size. Therefore we don't * update our local window when that rail window state is minimized */ - if (appWindow->rail_state == WINDOW_SHOW_MINIMIZED) - return TRUE; + if (appWindow->rail_state != WINDOW_SHOW_MINIMIZED) + { - /* Do nothing if window is already in the correct position */ - if (appWindow->x == (appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX) && - appWindow->y == (appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY) && + /* Redraw window area if already in the correct position */ + if (appWindow->x == appWindow->windowOffsetX && + appWindow->y == appWindow->windowOffsetY && appWindow->width == appWindow->windowWidth && appWindow->height == appWindow->windowHeight) - { - xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth, appWindow->windowHeight); - } - else - { - xf_MoveWindow(xfc, appWindow, appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX, appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY, - appWindow->windowWidth, appWindow->windowHeight); + { + xf_UpdateWindowArea(xfc, appWindow, 0, 0, appWindow->windowWidth, appWindow->windowHeight); + } + else + { + xf_MoveWindow(xfc, appWindow, appWindow->windowOffsetX, appWindow->windowOffsetY, + appWindow->windowWidth, appWindow->windowHeight); + } + + xf_SetWindowVisibilityRects(xfc, appWindow, visibilityRectsOffsetX, visibilityRectsOffsetY, appWindow->visibilityRects, appWindow->numVisibilityRects); } } - if (fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS) + /* We should only be using the visibility rects for shaping the window */ + /*if (fieldFlags & WINDOW_ORDER_FIELD_WND_RECTS) { - /* We should only be using the visibility rects for shaping the window */ - //xf_SetWindowRects(xfc, appWindow, appWindow->windowRects, appWindow->numWindowRects); - } + xf_SetWindowRects(xfc, appWindow, appWindow->windowRects, appWindow->numWindowRects); + }*/ - if (fieldFlags & WINDOW_ORDER_FIELD_VISIBILITY) - { - xf_SetWindowVisibilityRects(xfc, appWindow, appWindow->visibilityRects, appWindow->numVisibilityRects); - } return TRUE; } diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index b9810e55a..f4c832be3 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -927,7 +927,7 @@ void xf_SetWindowRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rec } -void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rects, int nrects) +void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, UINT32 rectsOffsetX, UINT32 rectsOffsetY, RECTANGLE_16* rects, int nrects) { int i; XRectangle* xrects; @@ -946,7 +946,7 @@ void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, RECTANG xrects[i].height = rects[i].bottom - rects[i].top; } - XShapeCombineRectangles(xfc->display, appWindow->handle, ShapeBounding, 0, 0, xrects, nrects, ShapeSet, 0); + XShapeCombineRectangles(xfc->display, appWindow->handle, ShapeBounding, rectsOffsetX, rectsOffsetY, xrects, nrects, ShapeSet, 0); free(xrects); #endif @@ -955,20 +955,14 @@ void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, RECTANG void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int width, int height) { int ax, ay; - UINT32 translatedWindowOffsetX; - UINT32 translatedWindowOffsetY; - /* Translate the server rail window offset to a local offset */ - translatedWindowOffsetX = (appWindow->windowOffsetX - appWindow->localWindowOffsetCorrX); - translatedWindowOffsetY = (appWindow->windowOffsetY - appWindow->localWindowOffsetCorrY); + ax = x + appWindow->windowOffsetX; + ay = y + appWindow->windowOffsetY; - ax = x + translatedWindowOffsetX; - ay = y + translatedWindowOffsetY; - - if (ax + width > translatedWindowOffsetX + appWindow->width) - width = (translatedWindowOffsetX + appWindow->width - 1) - ax; - if (ay + height > translatedWindowOffsetY + appWindow->height) - height = (translatedWindowOffsetY + appWindow->height - 1) - ay; + if (ax + width > appWindow->windowOffsetX + appWindow->windowWidth) + width = (appWindow->windowOffsetX + appWindow->windowWidth - 1) - ax; + if (ay + height > appWindow->windowOffsetY + appWindow->windowHeight) + height = (appWindow->windowOffsetY + appWindow->windowHeight - 1) - ay; xf_lock_x11(xfc, TRUE); diff --git a/client/X11/xf_window.h b/client/X11/xf_window.h index 2fd9de22d..0a41c798a 100644 --- a/client/X11/xf_window.h +++ b/client/X11/xf_window.h @@ -160,7 +160,7 @@ void xf_MoveWindow(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int wid void xf_ShowWindow(xfContext* xfc, xfAppWindow* appWindow, BYTE state); //void xf_SetWindowIcon(xfContext* xfc, xfAppWindow* appWindow, rdpIcon* icon); void xf_SetWindowRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rects, int nrects); -void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, RECTANGLE_16* rects, int nrects); +void xf_SetWindowVisibilityRects(xfContext* xfc, xfAppWindow* appWindow, UINT32 rectsOffsetX, UINT32 rectsOffsetY, RECTANGLE_16* rects, int nrects); void xf_SetWindowStyle(xfContext* xfc, xfAppWindow* appWindow, UINT32 style, UINT32 ex_style); void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, int width, int height); void xf_DestroyWindow(xfContext* xfc, xfAppWindow* appWindow); From ace5bba0ed722cbf69369782f0124b4c2ed752af Mon Sep 17 00:00:00 2001 From: bjcollins Date: Thu, 15 Oct 2015 19:10:04 -0500 Subject: [PATCH 11/23] Cleanup unnecessary/unintended changes from last commit --- client/X11/xf_event.c | 3 +-- client/X11/xf_window.c | 8 ++++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/client/X11/xf_event.c b/client/X11/xf_event.c index 18328f392..5f13d503d 100644 --- a/client/X11/xf_event.c +++ b/client/X11/xf_event.c @@ -278,8 +278,7 @@ BOOL xf_generic_MotionNotify(xfContext* xfc, int x, int y, int state, Window win xf_event_adjust_coordinates(xfc, &x, &y); - if (!app || xf_AppWindowFromX11Window(xfc,window)->local_move.direction != RAIL_WMSZ_KEYSIZE) - input->MouseEvent(input, PTR_FLAGS_MOVE, x, y); + input->MouseEvent(input, PTR_FLAGS_MOVE, x, y); if (xfc->fullscreen && !app) { diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index f4c832be3..973cc2374 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -959,10 +959,10 @@ void xf_UpdateWindowArea(xfContext* xfc, xfAppWindow* appWindow, int x, int y, i ax = x + appWindow->windowOffsetX; ay = y + appWindow->windowOffsetY; - if (ax + width > appWindow->windowOffsetX + appWindow->windowWidth) - width = (appWindow->windowOffsetX + appWindow->windowWidth - 1) - ax; - if (ay + height > appWindow->windowOffsetY + appWindow->windowHeight) - height = (appWindow->windowOffsetY + appWindow->windowHeight - 1) - ay; + if (ax + width > appWindow->windowOffsetX + appWindow->width) + width = (appWindow->windowOffsetX + appWindow->width - 1) - ax; + if (ay + height > appWindow->windowOffsetY + appWindow->height) + height = (appWindow->windowOffsetY + appWindow->height - 1) - ay; xf_lock_x11(xfc, TRUE); From 934c4ff7a4a405109739604c4ddc9ad830d16a78 Mon Sep 17 00:00:00 2001 From: root Date: Fri, 16 Oct 2015 15:54:26 +0800 Subject: [PATCH 12/23] update values-zh/strings.xml --- client/Android/FreeRDPCore/res/values-zh/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/Android/FreeRDPCore/res/values-zh/strings.xml b/client/Android/FreeRDPCore/res/values-zh/strings.xml index 09757f3de..b4514265c 100644 --- a/client/Android/FreeRDPCore/res/values-zh/strings.xml +++ b/client/Android/FreeRDPCore/res/values-zh/strings.xml @@ -5,7 +5,7 @@ 取消 继续 - 登陆 + 登录 断开 退出 From 25b1e394608db0816b056733f11059b18f61f113 Mon Sep 17 00:00:00 2001 From: Martin Fleisz Date: Thu, 29 Oct 2015 12:45:12 +0100 Subject: [PATCH 13/23] cliprdr/server: Server-side file content receiving used wrong callback --- channels/cliprdr/server/cliprdr_main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/channels/cliprdr/server/cliprdr_main.c b/channels/cliprdr/server/cliprdr_main.c index 96d0dc79d..b082c830e 100644 --- a/channels/cliprdr/server/cliprdr_main.c +++ b/channels/cliprdr/server/cliprdr_main.c @@ -1004,9 +1004,9 @@ static UINT cliprdr_server_receive_filecontents_response(CliprdrServerContext* c response.cbRequested = header->dataLen - 4; response.requestedData = Stream_Pointer(s); /* requestedFileContentsData */ - IFCALLRET(context->ServerFileContentsResponse, error, context, &response); + IFCALLRET(context->ClientFileContentsResponse, error, context, &response); if (error) - WLog_ERR(TAG, "ServerFileContentsResponse failed with error %lu!", error); + WLog_ERR(TAG, "ClientFileContentsResponse failed with error %lu!", error); return error; } From 0f1cedcbb8bdf011737d0cf414fbc26b6610d069 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Tue, 3 Nov 2015 12:05:47 +0100 Subject: [PATCH 14/23] codec/color: fix segfault in freerdp_image32_copy Code path for dstBytesPerPixel == 3 moved src and dst pointers beyond their respective buffers. --- libfreerdp/codec/color.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libfreerdp/codec/color.c b/libfreerdp/codec/color.c index 7e4235cb8..08c5c4284 100644 --- a/libfreerdp/codec/color.c +++ b/libfreerdp/codec/color.c @@ -3444,8 +3444,8 @@ int freerdp_image32_copy(BYTE* pDstData, DWORD DstFormat, int nDstStep, int nXDs pSrcPixel++; } - pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[nSrcStep]; - pDstPixel = (BYTE*) &((BYTE*) pDstPixel)[nDstStep]; + pSrcPixel = (UINT32*) &((BYTE*) pSrcPixel)[nSrcPad]; + pDstPixel = (BYTE*) &((BYTE*) pDstPixel)[nDstPad]; } return 1; From b5288daea5f33a6bcdf04717a0ac49a067f3ce9b Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 3 Nov 2015 16:18:09 +0100 Subject: [PATCH 15/23] Fixed return values. --- winpr/libwinpr/path/path.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/winpr/libwinpr/path/path.c b/winpr/libwinpr/path/path.c index de7b2aaeb..2f853aad0 100644 --- a/winpr/libwinpr/path/path.c +++ b/winpr/libwinpr/path/path.c @@ -596,13 +596,13 @@ HRESULT PathCchRemoveExtensionW(PWSTR pszPath, size_t cchPath) BOOL PathCchIsRootA(PCSTR pszPath) { WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); - return E_NOTIMPL; + return FALSE; } BOOL PathCchIsRootW(PCWSTR pszPath) { WLog_ERR(TAG, "%s: not implemented", __FUNCTION__); - return E_NOTIMPL; + return FALSE; } /** From d4d42710007f9006c0971c63cd778b7e7a9238f3 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Tue, 3 Nov 2015 16:16:49 +0100 Subject: [PATCH 16/23] Disabled client builds if WITH_CLIENT is not set. --- client/CMakeLists.txt | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index b8b769922..37a811db2 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -19,7 +19,7 @@ add_subdirectory(common) -if(FREERDP_VENDOR) +if(FREERDP_VENDOR AND WITH_CLIENT) if(WIN32) add_subdirectory(Windows) else() @@ -58,28 +58,28 @@ if(FREERDP_VENDOR) endif() # Pick up other clients +if(WITH_CLIENT) + set(FILENAME "ModuleOptions.cmake") + file(GLOB FILEPATHS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*/${FILENAME}") -set(FILENAME "ModuleOptions.cmake") -file(GLOB FILEPATHS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*/${FILENAME}") - -foreach(FILEPATH ${FILEPATHS}) - if(${FILEPATH} MATCHES "^([^/]*)/+${FILENAME}") - string(REGEX REPLACE "^([^/]*)/+${FILENAME}" "\\1" FREERDP_CLIENT ${FILEPATH}) - set(FREERDP_CLIENT_ENABLED 0) - include(${FILEPATH}) - if(FREERDP_CLIENT_ENABLED) - if(NOT (${FREERDP_CLIENT_VENDOR} MATCHES "FreeRDP")) - list(APPEND FREERDP_EXTRA_CLIENTS ${FREERDP_CLIENT}) - if(${FREERDP_CLIENT_VENDOR} MATCHES "${VENDOR}") - set(CLIENT_VENDOR_PATH "client/${FREERDP_CLIENT}" PARENT_SCOPE) + foreach(FILEPATH ${FILEPATHS}) + if(${FILEPATH} MATCHES "^([^/]*)/+${FILENAME}") + string(REGEX REPLACE "^([^/]*)/+${FILENAME}" "\\1" FREERDP_CLIENT ${FILEPATH}) + set(FREERDP_CLIENT_ENABLED 0) + include(${FILEPATH}) + if(FREERDP_CLIENT_ENABLED) + if(NOT (${FREERDP_CLIENT_VENDOR} MATCHES "FreeRDP")) + list(APPEND FREERDP_EXTRA_CLIENTS ${FREERDP_CLIENT}) + if(${FREERDP_CLIENT_VENDOR} MATCHES "${VENDOR}") + set(CLIENT_VENDOR_PATH "client/${FREERDP_CLIENT}" PARENT_SCOPE) + endif() endif() endif() endif() - endif() -endforeach() - -foreach(FREERDP_CLIENT ${FREERDP_EXTRA_CLIENTS}) - add_subdirectory(${FREERDP_CLIENT}) -endforeach() + endforeach() + foreach(FREERDP_CLIENT ${FREERDP_EXTRA_CLIENTS}) + add_subdirectory(${FREERDP_CLIENT}) + endforeach() +endif() From 1ba4f9b67ff77b1d28aac8bb3d1de83f71e24c2a Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 4 Nov 2015 09:53:13 +0100 Subject: [PATCH 17/23] Added WITH_CLIENT_COMMON option. --- CMakeLists.txt | 4 ++-- cmake/ConfigOptions.cmake | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e8268be12..718f9ff70 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -776,8 +776,8 @@ if(WITH_CHANNELS) add_subdirectory(channels) endif() -if(WITH_CLIENT) - add_subdirectory(client) +if(WITH_CLIENT_COMMON OR WITH_CLIENT) +add_subdirectory(client) endif() if(WITH_SERVER) diff --git a/cmake/ConfigOptions.cmake b/cmake/ConfigOptions.cmake index 244fdcf6e..871d816c4 100644 --- a/cmake/ConfigOptions.cmake +++ b/cmake/ConfigOptions.cmake @@ -60,7 +60,8 @@ CMAKE_DEPENDENT_OPTION(TESTS_WTSAPI_EXTRA "Build extra WTSAPI tests (interactive option(WITH_SAMPLE "Build sample code" OFF) -option(WITH_CLIENT "Build client binaries" ON) +option(WITH_CLIENT_COMMON "Build client common library" ON) +cmake_dependent_option(WITH_CLIENT "Build client binaries" ON WITH_CLIENT_COMMON ON) option(WITH_SERVER "Build server binaries" OFF) option(STATIC_CHANNELS "Build channels statically" ON) From 9b7c35e122d970285bddf64d142b4c9ed964f45a Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 4 Nov 2015 13:15:37 +0100 Subject: [PATCH 18/23] Fixed WITH_CLIENT_CHANNELS dependencies. --- cmake/ConfigOptions.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmake/ConfigOptions.cmake b/cmake/ConfigOptions.cmake index 871d816c4..9d501c164 100644 --- a/cmake/ConfigOptions.cmake +++ b/cmake/ConfigOptions.cmake @@ -62,15 +62,15 @@ option(WITH_SAMPLE "Build sample code" OFF) option(WITH_CLIENT_COMMON "Build client common library" ON) cmake_dependent_option(WITH_CLIENT "Build client binaries" ON WITH_CLIENT_COMMON ON) + option(WITH_SERVER "Build server binaries" OFF) option(STATIC_CHANNELS "Build channels statically" ON) option(WITH_CHANNELS "Build virtual channel plugins" ON) -if(WITH_CLIENT AND WITH_CHANNELS) - option(WITH_CLIENT_CHANNELS "Build virtual channel plugins" ON) -endif() +cmake_dependent_option(WITH_CLIENT_CHANNELS "Build virtual channel plugins" ON + "WITH_CLIENT_COMMON;WITH_CHANNELS" ON) if(WITH_SERVER AND WITH_CHANNELS) option(WITH_SERVER_CHANNELS "Build virtual channel plugins" ON) From 48be0815c1f12f1f268135a0a214b327d79a9457 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Wed, 4 Nov 2015 15:01:31 +0100 Subject: [PATCH 19/23] client/X11: multimon/fullscreen fixes - fixed wrong calculation of xfc->fullscreenMonitors.[right|bottom] - only use _NET_WM_FULLSCREEN_MONITORS if at least 2 monitors are involved - call XMoveWindow before setting the _NET_WM_STATE_FULLSCREEN property --- client/X11/xf_monitor.c | 27 +++++++++++++-------------- client/X11/xf_window.c | 27 ++++++++++++--------------- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/client/X11/xf_monitor.c b/client/X11/xf_monitor.c index 920323ade..346bcd9c4 100644 --- a/client/X11/xf_monitor.c +++ b/client/X11/xf_monitor.c @@ -120,7 +120,6 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) int i; int nmonitors = 0; int primaryMonitorFound = FALSE; - int vX, vY, vWidth, vHeight; VIRTUAL_SCREEN* vscreen; rdpSettings* settings = xfc->settings; @@ -270,10 +269,10 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) if (settings->MonitorCount) { /* Initialize bounding rectangle for all monitors */ - vWidth = settings->MonitorDefArray[0].width; - vHeight = settings->MonitorDefArray[0].height; - vX = settings->MonitorDefArray[0].x; - vY = settings->MonitorDefArray[0].y; + int vX = settings->MonitorDefArray[0].x; + int vY = settings->MonitorDefArray[0].y; + int vR = vX + settings->MonitorDefArray[0].width; + int vB = vY + settings->MonitorDefArray[0].height; xfc->fullscreenMonitors.top = xfc->fullscreenMonitors.bottom = xfc->fullscreenMonitors.left = xfc->fullscreenMonitors.right = settings->MonitorDefArray[0].orig_screen; @@ -285,36 +284,36 @@ BOOL xf_detect_monitors(xfContext* xfc, UINT32* pMaxWidth, UINT32* pMaxHeight) /* does the same as gdk_rectangle_union */ int destX = MIN(vX, settings->MonitorDefArray[i].x); int destY = MIN(vY, settings->MonitorDefArray[i].y); - int destWidth = MAX(vX + vWidth, settings->MonitorDefArray[i].x + settings->MonitorDefArray[i].width) - destX; - int destHeight = MAX(vY + vHeight, settings->MonitorDefArray[i].y + settings->MonitorDefArray[i].height) - destY; + int destR = MAX(vR, settings->MonitorDefArray[i].x + settings->MonitorDefArray[i].width); + int destB = MAX(vB, settings->MonitorDefArray[i].y + settings->MonitorDefArray[i].height); if (vX != destX) xfc->fullscreenMonitors.left = settings->MonitorDefArray[i].orig_screen; if (vY != destY) xfc->fullscreenMonitors.top = settings->MonitorDefArray[i].orig_screen; - if (vWidth != destWidth) + if (vR != destR) xfc->fullscreenMonitors.right = settings->MonitorDefArray[i].orig_screen; - if (vHeight != destHeight) + if (vB != destB) xfc->fullscreenMonitors.bottom = settings->MonitorDefArray[i].orig_screen; vX = destX; vY = destY; - vWidth = destWidth; - vHeight = destHeight; + vR = destR; + vB = destB; } settings->DesktopPosX = vX; settings->DesktopPosY = vY; vscreen->area.left = 0; - vscreen->area.right = vWidth - 1; + vscreen->area.right = vR - vX - 1; vscreen->area.top = 0; - vscreen->area.bottom = vHeight - 1; + vscreen->area.bottom = vB - vY - 1; if (settings->Workarea) { vscreen->area.top = xfc->workArea.y; - vscreen->area.bottom = (vHeight - (vHeight - (xfc->workArea.height + xfc->workArea.y))) - 1; + vscreen->area.bottom = xfc->workArea.height + xfc->workArea.y - 1; } /* If there are multiple monitors and we have not selected a primary */ diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index b7a4663e2..db8bd255b 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -185,30 +185,27 @@ void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen) */ startX = startX + xfc->instance->settings->MonitorLocalShiftX; startY = startY + xfc->instance->settings->MonitorLocalShiftY; - } - xf_ResizeDesktopWindow(xfc, window, width, height); - - /* Set the fullscreen state */ - xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4, - fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE, - xfc->_NET_WM_STATE_FULLSCREEN, 0, 0); - - /* Only send monitor bounds if they are valid */ - if ((xfc->fullscreenMonitors.top >= 0) && - (xfc->fullscreenMonitors.bottom >= 0) && - (xfc->fullscreenMonitors.left >= 0) && - (xfc->fullscreenMonitors.right >= 0)) - { - xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_FULLSCREEN_MONITORS, 5, + /* Set monitor bounds */ + if (settings->MonitorCount > 1) + { + xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_FULLSCREEN_MONITORS, 5, xfc->fullscreenMonitors.top, xfc->fullscreenMonitors.bottom, xfc->fullscreenMonitors.left, xfc->fullscreenMonitors.right, 1); + } } + xf_ResizeDesktopWindow(xfc, window, width, height); + XMoveWindow(xfc->display, window->handle, startX, startY); + + /* Set the fullscreen state */ + xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4, + fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE, + xfc->_NET_WM_STATE_FULLSCREEN, 0, 0); } /* http://tronche.com/gui/x/xlib/window-information/XGetWindowProperty.html */ From 7ddd15d8deab94a8a2c1d61c792188fa7b6e21a2 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Wed, 4 Nov 2015 17:58:21 +0100 Subject: [PATCH 20/23] client/X11: fix post fullscreen repositioning --- client/X11/xf_window.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index db8bd255b..9e7ed6e38 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -200,12 +200,22 @@ void xf_SetWindowFullscreen(xfContext* xfc, xfWindow* window, BOOL fullscreen) xf_ResizeDesktopWindow(xfc, window, width, height); - XMoveWindow(xfc->display, window->handle, startX, startY); + if (fullscreen) + { + /* enter full screen: move the window before adding NET_WM_STATE_FULLSCREEN */ + XMoveWindow(xfc->display, window->handle, startX, startY); + } /* Set the fullscreen state */ xf_SendClientEvent(xfc, window->handle, xfc->_NET_WM_STATE, 4, fullscreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE, xfc->_NET_WM_STATE_FULLSCREEN, 0, 0); + + if (!fullscreen) + { + /* leave full screen: move the window after removing NET_WM_STATE_FULLSCREEN */ + XMoveWindow(xfc->display, window->handle, startX, startY); + } } /* http://tronche.com/gui/x/xlib/window-information/XGetWindowProperty.html */ From 5fbf26acf2c231d4c4ac0636e4d1055194284b24 Mon Sep 17 00:00:00 2001 From: David FORT Date: Wed, 4 Nov 2015 18:11:19 +0100 Subject: [PATCH 21/23] Add an UDP appender to wLog This appender allows to receive the logs over a network connection using UDP packets. You can see the logs using a listening netcat, for example: nc -ul 127.0.0.1 20000. --- winpr/include/winpr/wlog.h | 12 ++ winpr/libwinpr/utils/CMakeLists.txt | 2 + winpr/libwinpr/utils/wlog/Appender.c | 6 + winpr/libwinpr/utils/wlog/Appender.h | 1 + winpr/libwinpr/utils/wlog/UdpAppender.c | 209 ++++++++++++++++++++++++ winpr/libwinpr/utils/wlog/UdpAppender.h | 35 ++++ winpr/libwinpr/utils/wlog/wlog.c | 2 + 7 files changed, 267 insertions(+) create mode 100644 winpr/libwinpr/utils/wlog/UdpAppender.c create mode 100644 winpr/libwinpr/utils/wlog/UdpAppender.h diff --git a/winpr/include/winpr/wlog.h b/winpr/include/winpr/wlog.h index 7ac9dd002..f7c0efd17 100644 --- a/winpr/include/winpr/wlog.h +++ b/winpr/include/winpr/wlog.h @@ -32,6 +32,7 @@ extern "C" { #include #include +#include typedef struct _wLog wLog; typedef struct _wLogMessage wLogMessage; @@ -115,6 +116,7 @@ struct _wLogLayout #define WLOG_APPENDER_CALLBACK 3 #define WLOG_APPENDER_SYSLOG 4 #define WLOG_APPENDER_JOURNALD 5 +#define WLOG_APPENDER_UDP 6 #define WLOG_PACKET_INBOUND 1 #define WLOG_PACKET_OUTBOUND 2 @@ -213,6 +215,16 @@ struct _wLogJournaldAppender }; typedef struct _wLogJournaldAppender wLogJournaldAppender; +struct _wLogUdpAppender +{ + WLOG_APPENDER_COMMON(); + char *host; + struct sockaddr targetAddr; + int targetAddrLen; + SOCKET sock; +}; +typedef struct _wLogUdpAppender wLogUdpAppender; + /** * Filter diff --git a/winpr/libwinpr/utils/CMakeLists.txt b/winpr/libwinpr/utils/CMakeLists.txt index a84d180f8..2a8411966 100644 --- a/winpr/libwinpr/utils/CMakeLists.txt +++ b/winpr/libwinpr/utils/CMakeLists.txt @@ -94,6 +94,8 @@ set(${MODULE_PREFIX}_WLOG_SRCS wlog/CallbackAppender.h wlog/ConsoleAppender.c wlog/ConsoleAppender.h + wlog/UdpAppender.c + wlog/UdpAppender.h ${SYSLOG_SRCS} ${JOURNALD_SRCS} ) diff --git a/winpr/libwinpr/utils/wlog/Appender.c b/winpr/libwinpr/utils/wlog/Appender.c index 8008f6df3..a9c4d566f 100644 --- a/winpr/libwinpr/utils/wlog/Appender.c +++ b/winpr/libwinpr/utils/wlog/Appender.c @@ -58,6 +58,9 @@ wLogAppender* WLog_Appender_New(wLog* log, DWORD logAppenderType) appender = (wLogAppender*) WLog_JournaldAppender_New(log); break; #endif + case WLOG_APPENDER_UDP: + appender = (wLogAppender*) WLog_UdpAppender_New(log); + break; default: fprintf(stderr, "%s: unknown handler type %d\n", __FUNCTION__, logAppenderType); appender = NULL; @@ -118,6 +121,9 @@ void WLog_Appender_Free(wLog* log, wLogAppender* appender) WLog_JournaldAppender_Free(log, (wLogJournaldAppender *) appender); break; #endif + case WLOG_APPENDER_UDP: + WLog_UdpAppender_Free(log, (wLogUdpAppender *) appender); + break; default: fprintf(stderr, "%s: don't know how to free appender type %d\n", __FUNCTION__, appender->Type); break; diff --git a/winpr/libwinpr/utils/wlog/Appender.h b/winpr/libwinpr/utils/wlog/Appender.h index ccb57085a..6b9b8ee21 100644 --- a/winpr/libwinpr/utils/wlog/Appender.h +++ b/winpr/libwinpr/utils/wlog/Appender.h @@ -26,6 +26,7 @@ #include "wlog/BinaryAppender.h" #include "wlog/ConsoleAppender.h" #include "wlog/CallbackAppender.h" +#include "wlog/UdpAppender.h" #ifdef HAVE_SYSLOG_H #include "wlog/SyslogAppender.h" diff --git a/winpr/libwinpr/utils/wlog/UdpAppender.c b/winpr/libwinpr/utils/wlog/UdpAppender.c new file mode 100644 index 000000000..f20983733 --- /dev/null +++ b/winpr/libwinpr/utils/wlog/UdpAppender.c @@ -0,0 +1,209 @@ +/** + * WinPR: Windows Portable Runtime + * WinPR Logger + * + * Copyright © 2015 Thincast Technologies GmbH + * Copyright © 2015 David FORT + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + + +#include +#include +#include + +#include + +#include "wlog/Message.h" +#include "wlog/UdpAppender.h" + +#ifndef _WIN32 +#include +#include +#include +#endif + +static BOOL WLog_UdpAppender_Open(wLog* log, wLogUdpAppender* appender) +{ + char addressString[256]; + struct addrinfo hints; + struct addrinfo* result; + int status, addrLen; + char *colonPos; + + + if (!log || !appender) + return FALSE; + + if (appender->targetAddrLen) /* already opened */ + return TRUE; + + colonPos = strchr(appender->host, ':'); + if (!colonPos) + return FALSE; + addrLen = colonPos - appender->host; + memcpy(addressString, appender->host, addrLen); + addressString[addrLen] = '\0'; + + ZeroMemory(&hints, sizeof(hints)); + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_DGRAM; + + status = getaddrinfo(addressString, colonPos+1, &hints, &result); + if (status != 0) + return FALSE; + + if (result->ai_addrlen > sizeof(appender->targetAddr)) + { + freeaddrinfo(result); + return FALSE; + } + + memcpy(&appender->targetAddr, result->ai_addr, result->ai_addrlen); + appender->targetAddrLen = result->ai_addrlen; + + + return TRUE; +} + +BOOL Wlog_UdpAppender_SetTarget(wLogUdpAppender* appender, const char *host) +{ + + appender->targetAddrLen = 0; + if (appender->host) + free(appender->host); + + appender->host = _strdup(host); + return (appender->host != NULL) && WLog_UdpAppender_Open(NULL, appender); +} + +static BOOL WLog_UdpAppender_Close(wLog* log, wLogUdpAppender* appender) +{ + if (!log || !appender) + return FALSE; + + return TRUE; +} + +static BOOL WLog_UdpAppender_WriteMessage(wLog* log, wLogUdpAppender* appender, wLogMessage* message) +{ + char prefix[WLOG_MAX_PREFIX_SIZE]; + + if (!log || !appender || !message) + return FALSE; + + message->PrefixString = prefix; + WLog_Layout_GetMessagePrefix(log, appender->Layout, message); + + _sendto(appender->sock, message->PrefixString, strlen(message->PrefixString), + 0, &appender->targetAddr, appender->targetAddrLen); + + _sendto(appender->sock, message->TextString, strlen(message->TextString), + 0, &appender->targetAddr, appender->targetAddrLen); + + _sendto(appender->sock, "\n", 1, 0, &appender->targetAddr, appender->targetAddrLen); + + return TRUE; +} + +static BOOL WLog_UdpAppender_WriteDataMessage(wLog* log, wLogUdpAppender* appender, wLogMessage* message) +{ + if (!log || !appender || !message) + return FALSE; + + return TRUE; +} + +static BOOL WLog_UdpAppender_WriteImageMessage(wLog* log, wLogUdpAppender* appender, wLogMessage* message) +{ + if (!log || !appender || !message) + return FALSE; + + + return TRUE; +} + +wLogUdpAppender* WLog_UdpAppender_New(wLog* log) +{ + wLogUdpAppender* appender; + DWORD nSize; + LPCSTR name; + + appender = (wLogUdpAppender*) calloc(1, sizeof(wLogUdpAppender)); + if (!appender) + return NULL; + + appender->Type = WLOG_APPENDER_UDP; + + appender->Open = (WLOG_APPENDER_OPEN_FN) WLog_UdpAppender_Open; + appender->Close = (WLOG_APPENDER_OPEN_FN) WLog_UdpAppender_Close; + appender->WriteMessage = + (WLOG_APPENDER_WRITE_MESSAGE_FN) WLog_UdpAppender_WriteMessage; + appender->WriteDataMessage = + (WLOG_APPENDER_WRITE_DATA_MESSAGE_FN) WLog_UdpAppender_WriteDataMessage; + appender->WriteImageMessage = + (WLOG_APPENDER_WRITE_IMAGE_MESSAGE_FN) WLog_UdpAppender_WriteImageMessage; + + appender->sock = _socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (appender->sock == INVALID_SOCKET) + goto error_sock; + + name = "WLOG_UDP_TARGET"; + nSize = GetEnvironmentVariableA(name, NULL, 0); + if (nSize) + { + appender->host = (LPSTR) malloc(nSize); + if (!appender->host) + goto error_env_malloc; + + GetEnvironmentVariableA(name, appender->host, nSize); + + if (!WLog_UdpAppender_Open(log, appender)) + goto error_open; + } + else + { + appender->host = _strdup("127.0.0.1:20000"); + if (!appender->host) + goto error_env_malloc; + } + + return appender; + +error_open: + free(appender->host); +error_env_malloc: + closesocket(appender->sock); +error_sock: + free(appender); + return NULL; +} + +void WLog_UdpAppender_Free(wLog* log, wLogUdpAppender* appender) +{ + if (appender) + { + if (appender->sock != INVALID_SOCKET) + { + closesocket(appender->sock); + appender->sock = INVALID_SOCKET; + } + free(appender->host); + free(appender); + } +} diff --git a/winpr/libwinpr/utils/wlog/UdpAppender.h b/winpr/libwinpr/utils/wlog/UdpAppender.h new file mode 100644 index 000000000..cd25345f4 --- /dev/null +++ b/winpr/libwinpr/utils/wlog/UdpAppender.h @@ -0,0 +1,35 @@ +/** + * Copyright © 2015 Thincast Technologies GmbH + * Copyright © 2015 David FORT + * + * Permission to use, copy, modify, distribute, and sell this software and + * its documentation for any purpose is hereby granted without fee, provided + * that the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of the copyright holders not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. The copyright holders make + * no representations about the suitability of this software for any + * purpose. It is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF + * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef WINPR_LIBWINPR_UTILS_WLOG_UDPAPPENDER_H_ +#define WINPR_LIBWINPR_UTILS_WLOG_UDPAPPENDER_H_ + +#include + +#include "wlog/wlog.h" + +WINPR_API wLogUdpAppender* WLog_UdpAppender_New(wLog* log); +WINPR_API void WLog_UdpAppender_Free(wLog* log, wLogUdpAppender* appender); +WINPR_API BOOL Wlog_UdpAppender_SetTarget(wLogUdpAppender* appender, const char *host); + +#endif /* WINPR_LIBWINPR_UTILS_WLOG_UDPAPPENDER_H_ */ diff --git a/winpr/libwinpr/utils/wlog/wlog.c b/winpr/libwinpr/utils/wlog/wlog.c index 7dc6208e8..123fe6384 100644 --- a/winpr/libwinpr/utils/wlog/wlog.c +++ b/winpr/libwinpr/utils/wlog/wlog.c @@ -706,6 +706,8 @@ wLog* WLog_GetRoot() else if (_stricmp(env, "JOURNALD") == 0) logAppenderType = WLOG_APPENDER_JOURNALD; #endif + else if (_stricmp(env, "UDP") == 0) + logAppenderType = WLOG_APPENDER_UDP; free(env); } From d6b5b906f449dc42441dddb6b5db7d76ae01e0d0 Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Thu, 5 Nov 2015 18:10:05 +0100 Subject: [PATCH 22/23] winpr/argv: fix CommandLineToArgvA memory access - fixed access of unitialized memory beyond terminating null - minor simplifications --- winpr/libwinpr/thread/argv.c | 95 ++++++++++-------------------------- 1 file changed, 26 insertions(+), 69 deletions(-) diff --git a/winpr/libwinpr/thread/argv.c b/winpr/libwinpr/thread/argv.c index 2bd7dc4fb..ad96da236 100644 --- a/winpr/libwinpr/thread/argv.c +++ b/winpr/libwinpr/thread/argv.c @@ -101,7 +101,6 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs) LPSTR* pArgs; int maxNumArgs; int maxBufferSize; - int currentIndex; int cmdLineLength; BOOL* lpEscapedChars; LPSTR lpEscapedCmdLine; @@ -167,36 +166,29 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs) p += length; for (i = 0; i < (n / 2); i++) - { - *pOutput = '\\'; - pOutput++; - } + *pOutput++ = '\\'; p += n + 1; if ((n % 2) != 0) lpEscapedChars[pOutput - lpEscapedCmdLine] = TRUE; - *pOutput = '"'; - pOutput++; + *pOutput++ = '"'; pLastEnd = p; } - *pOutput = '\0'; - pOutput++; + *pOutput++ = '\0'; lpCmdLine = (LPCSTR) lpEscapedCmdLine; cmdLineLength = strlen(lpCmdLine); } maxNumArgs = 2; - currentIndex = 0; p = (char*) lpCmdLine; - while (currentIndex < cmdLineLength - 1) + while (p < lpCmdLine + cmdLineLength) { - index = strcspn(p, " \t"); - currentIndex += (index + 1); - p = (char*) &lpCmdLine[currentIndex]; + p += strcspn(p, " \t"); + p += strspn(p, " \t"); maxNumArgs++; } @@ -209,32 +201,24 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs) pArgs = (LPSTR*) buffer; pOutput = (char*) &buffer[maxNumArgs * (sizeof(char*))]; numArgs = 0; - currentIndex = 0; p = (char*) lpCmdLine; - while (currentIndex < cmdLineLength) + while (p < lpCmdLine + cmdLineLength) { - pBeg = pEnd = p; + pBeg = p; while (1) { - index = strcspn(p, " \t\"\0"); - - if ((p[index] == '"') && (lpEscapedChars[&p[index] - lpCmdLine])) - { - p = &p[index + 1]; - continue; - } - - break; + p += strcspn(p, " \t\"\0"); + if ((*p != '"') || !lpEscapedChars[p - lpCmdLine]) + break; + p++; } - if (p[index] != '"') + if (*p != '"') { /* no whitespace escaped with double quotes */ - p = &p[index + 1]; - pEnd = p - 1; - length = (pEnd - pBeg); + length = p - pBeg; CopyMemory(pOutput, pBeg, length); pOutput[length] = '\0'; pArgs[numArgs++] = pOutput; @@ -242,62 +226,35 @@ LPSTR* CommandLineToArgvA(LPCSTR lpCmdLine, int* pNumArgs) } else { - p = &p[index + 1]; + p++; while (1) { - index = strcspn(p, "\"\0"); - - if ((p[index] == '"') && (lpEscapedChars[&p[index] - lpCmdLine])) - { - p = &p[index + 1]; - continue; - } - - break; + p += strcspn(p, "\"\0"); + if ((*p != '"') || !lpEscapedChars[p - lpCmdLine]) + break; + p++; } - if (p[index] != '"') - { + if (*p != '"') WLog_ERR(TAG, "parsing error: uneven number of unescaped double quotes!"); - } - if (p[index] == '\0') - { - p = &p[index + 1]; - pEnd = p - 1; - } - else - { - p = &p[index + 1]; - index = strcspn(p, " \t\0"); - p = &p[index + 1]; - pEnd = p - 1; - } + if (*p && *(++p)) + p += strcspn(p, " \t\0"); - length = 0; pArgs[numArgs++] = pOutput; - while (pBeg < pEnd) + while (pBeg < p) { if (*pBeg != '"') - { - *pOutput = *pBeg; - pOutput++; - length++; - } - + *pOutput++ = *pBeg; pBeg++; } - *pOutput = '\0'; - pOutput++; + *pOutput++ = '\0'; } - while ((*p == ' ') || (*p == '\t')) - p++; - - currentIndex = (p - lpCmdLine); + p += strspn(p, " \t"); } free(lpEscapedCmdLine); From 458aaa121364cc431a35ee8f396631cda996b4ee Mon Sep 17 00:00:00 2001 From: David FORT Date: Fri, 6 Nov 2015 23:17:11 +0100 Subject: [PATCH 23/23] Take in account @nfedera's remarks --- winpr/libwinpr/utils/wlog/UdpAppender.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/winpr/libwinpr/utils/wlog/UdpAppender.c b/winpr/libwinpr/utils/wlog/UdpAppender.c index f20983733..bc161d37b 100644 --- a/winpr/libwinpr/utils/wlog/UdpAppender.c +++ b/winpr/libwinpr/utils/wlog/UdpAppender.c @@ -47,7 +47,7 @@ static BOOL WLog_UdpAppender_Open(wLog* log, wLogUdpAppender* appender) char *colonPos; - if (!log || !appender) + if (!appender) return FALSE; if (appender->targetAddrLen) /* already opened */ @@ -169,7 +169,7 @@ wLogUdpAppender* WLog_UdpAppender_New(wLog* log) { appender->host = (LPSTR) malloc(nSize); if (!appender->host) - goto error_env_malloc; + goto error_host_alloc; GetEnvironmentVariableA(name, appender->host, nSize); @@ -180,14 +180,14 @@ wLogUdpAppender* WLog_UdpAppender_New(wLog* log) { appender->host = _strdup("127.0.0.1:20000"); if (!appender->host) - goto error_env_malloc; + goto error_host_alloc; } return appender; error_open: free(appender->host); -error_env_malloc: +error_host_alloc: closesocket(appender->sock); error_sock: free(appender);