From 0e18ee6de2799800fa685b7b9d2fecb16dbbfb21 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Tue, 19 Aug 2014 11:59:47 +0200 Subject: [PATCH 01/12] build: fix compilation for non monolithic builds set_complex_link_libraries isn't required anymore for winpr since it's always build monolithic. --- server/shadow/CMakeLists.txt | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/server/shadow/CMakeLists.txt b/server/shadow/CMakeLists.txt index c5a104768..e68c84589 100644 --- a/server/shadow/CMakeLists.txt +++ b/server/shadow/CMakeLists.txt @@ -190,13 +190,8 @@ set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS MODULE freerdp MODULES freerdp-core freerdp-common freerdp-codec freerdp-primitives freerdp-utils freerdp-gdi freerdp-crypto freerdp-locale) -set_complex_link_libraries(VARIABLE ${MODULE_PREFIX}_LIBS - MONOLITHIC ${MONOLITHIC_BUILD} - MODULE winpr - MODULES winpr-sspi winpr-crt winpr-utils winpr-input winpr-sysinfo) - list(APPEND ${MODULE_PREFIX}_LIBS freerdp-client) -list(APPEND ${MODULE_PREFIX}_LIBS winpr-makecert-tool) +list(APPEND ${MODULE_PREFIX}_LIBS winpr-makecert-tool winpr) target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS}) From 5bf59b08107ef0042f825e5c098e0c0bf8038314 Mon Sep 17 00:00:00 2001 From: Daryl Poe Date: Fri, 15 Aug 2014 15:45:06 -0600 Subject: [PATCH 02/12] handle user@corp.net username correctly (cherry picked from commit 248c9185084e99121ea5e99610384bb3a2c0f803) --- client/common/cmdline.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/client/common/cmdline.c b/client/common/cmdline.c index 6fd21c5f3..345e11cde 100644 --- a/client/common/cmdline.c +++ b/client/common/cmdline.c @@ -816,21 +816,12 @@ int freerdp_parse_username(char* username, char** user, char** domain) } else { - p = strchr(username, '@'); - - if (p) - { - length = (int) (p - username); - *user = (char*) malloc(length + 1); - strncpy(*user, username, length); - (*user)[length] = '\0'; - *domain = _strdup(&p[1]); - } - else - { - *user = _strdup(username); - *domain = NULL; - } + /* Do not break up the name for '@'; both credSSP and the + * ClientInfo PDU expect 'user@corp.net' to be transmitted + * as username 'user@corp.net', domain empty. + */ + *user = _strdup(username); + *domain = NULL; } return 0; From e95b6aece9cbf06d9f9f038f304a5f504889e042 Mon Sep 17 00:00:00 2001 From: erbth Date: Tue, 19 Aug 2014 22:59:22 +0200 Subject: [PATCH 03/12] (hopefully) proper window style setup in wfreerdp at startup --- client/Windows/wf_interface.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/client/Windows/wf_interface.c b/client/Windows/wf_interface.c index 6effa7cf0..3fb115d43 100644 --- a/client/Windows/wf_interface.c +++ b/client/Windows/wf_interface.c @@ -394,10 +394,12 @@ BOOL wf_post_connect(freerdp* instance) if (settings->EmbeddedWindow) settings->Decorations = FALSE; - if (!settings->Decorations) + if (wfc->fullscreen) + dwStyle = WS_POPUP; + else if (!settings->Decorations) dwStyle = WS_CHILD | WS_BORDER; else - dwStyle = 0; + dwStyle = WS_CAPTION | WS_OVERLAPPED | WS_SYSMENU | WS_MINIMIZEBOX | WS_SIZEBOX | WS_MAXIMIZEBOX; if (!wfc->hwnd) { From 27fc3ee64d82bc44d9530600c6a21930c37b69c0 Mon Sep 17 00:00:00 2001 From: Daniel Bungert Date: Wed, 20 Aug 2014 03:54:05 -0600 Subject: [PATCH 04/12] Fix multiple cases of use of uninitialized vars * Zeroing xevent helped address some erratic behavior. * valgrind complained about using xfBitmap uninitialized during shutdown, traced it back to the initialization. Bitmap_Prototype->size > sizeof(rdpBitmap). * Early exit from recv_tpkt_pdu is necessary to address a shutdown crash - the channelId value was being used without being set in the disconnect case. --- client/X11/xf_window.c | 2 ++ libfreerdp/core/graphics.c | 9 ++++++--- libfreerdp/core/peer.c | 3 +++ libfreerdp/core/rdp.c | 3 +++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/client/X11/xf_window.c b/client/X11/xf_window.c index 7df1f8768..51779905a 100644 --- a/client/X11/xf_window.c +++ b/client/X11/xf_window.c @@ -114,6 +114,8 @@ void xf_SendClientEvent(xfContext *xfc, xfWindow *window, Atom atom, unsigned in unsigned int i; va_list argp; va_start(argp, numArgs); + + ZeroMemory(&xevent, sizeof(XEvent)); xevent.xclient.type = ClientMessage; xevent.xclient.serial = 0; xevent.xclient.send_event = False; diff --git a/libfreerdp/core/graphics.c b/libfreerdp/core/graphics.c index 58de46834..7f991bb81 100644 --- a/libfreerdp/core/graphics.c +++ b/libfreerdp/core/graphics.c @@ -37,7 +37,8 @@ rdpBitmap* Bitmap_Alloc(rdpContext* context) if (bitmap) { - CopyMemory(bitmap, context->graphics->Bitmap_Prototype, sizeof(rdpBitmap)); + ZeroMemory(bitmap, graphics->Bitmap_Prototype->size); + CopyMemory(bitmap, graphics->Bitmap_Prototype, sizeof(rdpBitmap)); bitmap->data = NULL; } @@ -99,7 +100,8 @@ rdpPointer* Pointer_Alloc(rdpContext* context) if (pointer) { - CopyMemory(pointer, context->graphics->Pointer_Prototype, sizeof(rdpPointer)); + ZeroMemory(pointer, graphics->Pointer_Prototype->size); + CopyMemory(pointer, graphics->Pointer_Prototype, sizeof(rdpPointer)); } return pointer; @@ -165,7 +167,8 @@ rdpGlyph* Glyph_Alloc(rdpContext* context) if (glyph) { - CopyMemory(glyph, context->graphics->Glyph_Prototype, sizeof(rdpGlyph)); + ZeroMemory(glyph, graphics->Glyph_Prototype->size); + CopyMemory(glyph, graphics->Glyph_Prototype, sizeof(rdpGlyph)); } return glyph; diff --git a/libfreerdp/core/peer.c b/libfreerdp/core/peer.c index 0d0920280..e2f3f48f2 100644 --- a/libfreerdp/core/peer.c +++ b/libfreerdp/core/peer.c @@ -184,6 +184,9 @@ static int peer_recv_tpkt_pdu(freerdp_peer* client, wStream* s) return -1; } + if (rdp->disconnect) + return 0; + if (rdp->settings->DisableEncryption) { if (!rdp_read_security_header(s, &securityFlags)) diff --git a/libfreerdp/core/rdp.c b/libfreerdp/core/rdp.c index e5a2e3956..170b93b60 100644 --- a/libfreerdp/core/rdp.c +++ b/libfreerdp/core/rdp.c @@ -989,6 +989,9 @@ static int rdp_recv_tpkt_pdu(rdpRdp* rdp, wStream* s) return -1; } + if (rdp->disconnect) + return 0; + if (rdp->settings->DisableEncryption) { if (!rdp_read_security_header(s, &securityFlags)) From 08d60d01e0a56b339b2c1ba616d86012f42e4337 Mon Sep 17 00:00:00 2001 From: Pavel Tsekov Date: Thu, 21 Aug 2014 03:35:34 +0300 Subject: [PATCH 05/12] Adjust the code to work with the new GDI color representation. * client/X11/xf_gdi.c: Use freerdp_color_convert_drawing_order_color_to_gdi_color() to convert from drawing order color representation to GDI color representation troughout. * client/X11/xf_graphics.c: Likewise. --- client/X11/xf_gdi.c | 22 +++++++++++----------- client/X11/xf_graphics.c | 8 ++------ 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index 1ab20af06..59414d147 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -337,8 +337,8 @@ void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) brush = &patblt->brush; xf_set_rop3(xfc, gdi_rop3_code(patblt->bRop)); - foreColor = freerdp_color_convert_var(patblt->foreColor, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); - backColor = freerdp_color_convert_var(patblt->backColor, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); + foreColor = freerdp_color_convert_drawing_order_color_to_gdi_color(patblt->foreColor, context->settings->ColorDepth, xfc->clrconv); + backColor = freerdp_color_convert_drawing_order_color_to_gdi_color(patblt->backColor, context->settings->ColorDepth, xfc->clrconv); if (brush->style == GDI_BS_SOLID) { @@ -457,7 +457,7 @@ void xf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) xf_lock_x11(xfc, FALSE); - color = freerdp_color_convert_var(opaque_rect->color, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); + color = freerdp_color_convert_drawing_order_color_to_gdi_color(opaque_rect->color, context->settings->ColorDepth, xfc->clrconv); XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); @@ -491,7 +491,7 @@ void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult xf_lock_x11(xfc, FALSE); - color = freerdp_color_convert_var(multi_opaque_rect->color, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); + color = freerdp_color_convert_drawing_order_color_to_gdi_color(multi_opaque_rect->color, context->settings->ColorDepth, xfc->clrconv); XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); @@ -533,7 +533,7 @@ void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to) xf_lock_x11(xfc, FALSE); xf_set_rop2(xfc, line_to->bRop2); - color = freerdp_color_convert_var(line_to->penColor, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); + color = freerdp_color_convert_drawing_order_color_to_gdi_color(line_to->penColor, context->settings->ColorDepth, xfc->clrconv); XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetForeground(xfc->display, xfc->gc, color); @@ -583,7 +583,7 @@ void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) xf_lock_x11(xfc, FALSE); xf_set_rop2(xfc, polyline->bRop2); - color = freerdp_color_convert_var(polyline->penColor, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); + color = freerdp_color_convert_drawing_order_color_to_gdi_color(polyline->penColor, context->settings->ColorDepth, xfc->clrconv); XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetForeground(xfc->display, xfc->gc, color); @@ -679,8 +679,8 @@ void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) brush = &mem3blt->brush; bitmap = (xfBitmap*) mem3blt->bitmap; xf_set_rop3(xfc, gdi_rop3_code(mem3blt->bRop)); - foreColor = freerdp_color_convert_var(mem3blt->foreColor, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); - backColor = freerdp_color_convert_var(mem3blt->backColor, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); + foreColor = freerdp_color_convert_drawing_order_color_to_gdi_color(mem3blt->foreColor, context->settings->ColorDepth, xfc->clrconv); + backColor = freerdp_color_convert_drawing_order_color_to_gdi_color(mem3blt->backColor, context->settings->ColorDepth, xfc->clrconv); if (brush->style == GDI_BS_PATTERN) { @@ -752,7 +752,7 @@ void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc) xf_lock_x11(xfc, FALSE); xf_set_rop2(xfc, polygon_sc->bRop2); - brush_color = freerdp_color_convert_var(polygon_sc->brushColor, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); + brush_color = freerdp_color_convert_drawing_order_color_to_gdi_color(polygon_sc->brushColor, context->settings->ColorDepth, xfc->clrconv); npoints = polygon_sc->numPoints + 1; points = malloc(sizeof(XPoint) * npoints); @@ -813,8 +813,8 @@ void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb) brush = &(polygon_cb->brush); xf_set_rop2(xfc, polygon_cb->bRop2); - foreColor = freerdp_color_convert_var(polygon_cb->foreColor, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); - backColor = freerdp_color_convert_var(polygon_cb->backColor, context->settings->ColorDepth, xfc->bpp, xfc->clrconv); + foreColor = freerdp_color_convert_drawing_order_color_to_gdi_color(polygon_cb->foreColor, context->settings->ColorDepth, xfc->clrconv); + backColor = freerdp_color_convert_drawing_order_color_to_gdi_color(polygon_cb->backColor, context->settings->ColorDepth, xfc->clrconv); npoints = polygon_cb->numPoints + 1; points = malloc(sizeof(XPoint) * npoints); diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c index 83e815cbf..f010a5ea5 100644 --- a/client/X11/xf_graphics.c +++ b/client/X11/xf_graphics.c @@ -392,13 +392,9 @@ void xf_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height xfContext* context_ = (xfContext*) context; xfContext* xfc = (xfContext*) context; - bgcolor = (xfc->clrconv->invert)? - freerdp_color_convert_var_bgr(bgcolor, context_->settings->ColorDepth, xfc->bpp, xfc->clrconv): - freerdp_color_convert_var_rgb(bgcolor, context_->settings->ColorDepth, xfc->bpp, xfc->clrconv); + bgcolor = freerdp_color_convert_drawing_order_color_to_gdi_color(bgcolor, context->settings->ColorDepth, xfc->clrconv); - fgcolor = (xfc->clrconv->invert)? - freerdp_color_convert_var_bgr(fgcolor, context_->settings->ColorDepth, xfc->bpp, xfc->clrconv): - freerdp_color_convert_var_rgb(fgcolor, context_->settings->ColorDepth, xfc->bpp, xfc->clrconv); + fgcolor = freerdp_color_convert_drawing_order_color_to_gdi_color(fgcolor, context->settings->ColorDepth, xfc->clrconv); xf_lock_x11(xfc, FALSE); From 91ef3ed843927f51b3f5a1f9f4d8d92b8e185c64 Mon Sep 17 00:00:00 2001 From: erbth Date: Mon, 25 Aug 2014 15:12:44 +0200 Subject: [PATCH 06/12] WM_GETMINMAXINFO: use latest determined canvas diff --- client/Windows/wf_event.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/client/Windows/wf_event.c b/client/Windows/wf_event.c index cc54df906..1f2c9c87a 100644 --- a/client/Windows/wf_event.c +++ b/client/Windows/wf_event.c @@ -255,7 +255,10 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam // Set maximum window size for resizing minmax = (MINMAXINFO*) lParam; - wf_update_canvas_diff(wfc); + + //always use the last determined canvas diff, because it could be + //that the window is minimized when this gets called + //wf_update_canvas_diff(wfc); if (!wfc->fullscreen) { From cd23e5c0d588b8a8b2fd7e61961293a2b04606c3 Mon Sep 17 00:00:00 2001 From: erbth Date: Mon, 25 Aug 2014 15:24:04 +0200 Subject: [PATCH 07/12] wfreerdp: WM_SIZE: only update canvas diff if window size is bigger than 0 --- client/Windows/wf_event.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/client/Windows/wf_event.c b/client/Windows/wf_event.c index 1f2c9c87a..941ff5234 100644 --- a/client/Windows/wf_event.c +++ b/client/Windows/wf_event.c @@ -284,11 +284,14 @@ LRESULT CALLBACK wf_event_proc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam wfc->client_y = windowRect.top; } - wf_size_scrollbars(wfc, LOWORD(lParam), HIWORD(lParam)); + if (wfc->client_width && wfc->client_height) + { + wf_size_scrollbars(wfc, LOWORD(lParam), HIWORD(lParam)); - // Workaround: when the window is maximized, the call to "ShowScrollBars" returns TRUE but has no effect. - if (wParam == SIZE_MAXIMIZED && !wfc->fullscreen) - SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_NOMOVE | SWP_FRAMECHANGED); + // Workaround: when the window is maximized, the call to "ShowScrollBars" returns TRUE but has no effect. + if (wParam == SIZE_MAXIMIZED && !wfc->fullscreen) + SetWindowPos(wfc->hwnd, HWND_TOP, 0, 0, windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, SWP_NOMOVE | SWP_FRAMECHANGED); + } break; From 551ee0566a83fb5b756f49f587d269ef88b7f141 Mon Sep 17 00:00:00 2001 From: Vic Lee Date: Thu, 28 Aug 2014 23:16:32 +0800 Subject: [PATCH 08/12] channels: fix memory leak in stream pools. --- channels/drdynvc/client/dvcman.c | 4 ++-- channels/drdynvc/client/dvcman.h | 1 + libfreerdp/utils/svc_plugin.c | 1 - 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/channels/drdynvc/client/dvcman.c b/channels/drdynvc/client/dvcman.c index d7e6fbf36..f9e4873b8 100644 --- a/channels/drdynvc/client/dvcman.c +++ b/channels/drdynvc/client/dvcman.c @@ -476,7 +476,7 @@ int dvcman_receive_channel_data_first(IWTSVirtualChannelManager* pChannelMgr, UI Stream_Release(channel->dvc_data); channel->dvc_data = StreamPool_Take(channel->dvcman->pool, length); - Stream_AddRef(channel->dvc_data); + channel->dvc_data_length = length; return 0; } @@ -508,7 +508,7 @@ int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, UINT32 C Stream_Write(channel->dvc_data, Stream_Pointer(data), dataSize); - if (((size_t) Stream_GetPosition(channel->dvc_data)) >= Stream_Capacity(channel->dvc_data)) + if (((size_t) Stream_GetPosition(channel->dvc_data)) >= channel->dvc_data_length) { Stream_SealLength(channel->dvc_data); Stream_SetPosition(channel->dvc_data, 0); diff --git a/channels/drdynvc/client/dvcman.h b/channels/drdynvc/client/dvcman.h index 04781deab..20f0edeb0 100644 --- a/channels/drdynvc/client/dvcman.h +++ b/channels/drdynvc/client/dvcman.h @@ -82,6 +82,7 @@ struct _DVCMAN_CHANNEL IWTSVirtualChannelCallback* channel_callback; wStream* dvc_data; + UINT32 dvc_data_length; CRITICAL_SECTION lock; }; typedef struct _DVCMAN_CHANNEL DVCMAN_CHANNEL; diff --git a/libfreerdp/utils/svc_plugin.c b/libfreerdp/utils/svc_plugin.c index b57dc1d9d..a52763852 100644 --- a/libfreerdp/utils/svc_plugin.c +++ b/libfreerdp/utils/svc_plugin.c @@ -106,7 +106,6 @@ static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, UINT3 Stream_Release(plugin->data_in); plugin->data_in = StreamPool_Take(plugin->pool, totalLength); - Stream_AddRef(plugin->data_in); } s = plugin->data_in; From 3e355c9f79df20a4626747b2ff65aab420aacb89 Mon Sep 17 00:00:00 2001 From: Bernhard Miklautz Date: Fri, 29 Aug 2014 16:37:14 +0200 Subject: [PATCH 09/12] channels: fix possible overflow in logging Fixes clang compiler warning: "warning: the value of the size argument in 'strncat' is too large, might lead to a buffer overflow [-Wstrncat-size]" strncat requires an extra byte for '\0' so dest needs to have a size of n+1 --- include/freerdp/channels/log.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/freerdp/channels/log.h b/include/freerdp/channels/log.h index 8e8d6c330..f2125a68c 100644 --- a/include/freerdp/channels/log.h +++ b/include/freerdp/channels/log.h @@ -28,8 +28,8 @@ wLogMessage msg; \ wLog *log; \ \ - strncat(tag, "com.freerdp.channels.", sizeof(tag)); \ - strncat(tag, dbg_str, sizeof(tag) - sizeof("com.freerdp.channels.")); \ + strncat(tag, "com.freerdp.channels.", sizeof(tag) - 1); \ + strncat(tag, dbg_str, sizeof(tag) - 1 - sizeof("com.freerdp.channels.")); \ log = WLog_Get(tag); \ \ msg.Type = WLOG_MESSAGE_TEXT; \ From e393499ff89eaa8c4d5dafce9d4e5f3cd5f94eea Mon Sep 17 00:00:00 2001 From: Norbert Federa Date: Tue, 2 Sep 2014 15:42:44 +0200 Subject: [PATCH 10/12] rdpdr/drive: fixes for hung peers & info requests drive_file_init: only allow directories and regular files This is fixes issue #2071 Even if the server is only interested in getting a file's or directory's attributes FreeRDP still tries to open the object with read permissions. If the FreeRDP client has no read permissions for this object the call will fail which forces the server to perform some expensive workarounds (e.g. getting to the stat buffers via a directory enumeration request). On Linux we can try to open the file or directory with the O_PATH flag in order to obtain a file descriptor who's only purpose is to perform operations that act purely at the file descriptor level. --- channels/drive/client/drive_file.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/channels/drive/client/drive_file.c b/channels/drive/client/drive_file.c index ab3e96837..5f3aa4718 100644 --- a/channels/drive/client/drive_file.c +++ b/channels/drive/client/drive_file.c @@ -49,7 +49,9 @@ #endif #ifdef HAVE_FCNTL_H +#define __USE_GNU /* for O_PATH */ #include +#undef __USE_GNU #endif #ifdef _WIN32 @@ -192,6 +194,11 @@ static BOOL drive_file_init(DRIVE_FILE* file, UINT32 DesiredAccess, UINT32 Creat if (STAT(file->fullpath, &st) == 0) { file->is_dir = (S_ISDIR(st.st_mode) ? TRUE : FALSE); + if (!file->is_dir && !S_ISREG(st.st_mode)) + { + file->err = EPERM; + return TRUE; + } #ifndef WIN32 if (st.st_size > (unsigned long) 0x07FFFFFFF) largeFile = TRUE; @@ -306,6 +313,25 @@ DRIVE_FILE* drive_file_new(const char* base_path, const char* path, UINT32 id, return NULL; } +#if defined(__linux__) && defined(O_PATH) + if (file->fd < 0 && file->err == EACCES) + { + /** + * We have no access permissions for the file or directory but if the + * peer is only interested in reading the object's attributes we can try + * to obtain a file descriptor who's only purpose is to perform + * operations that act purely at the file descriptor level. + * See open(2) + **/ + { + if ((file->fd = OPEN(file->fullpath, O_PATH)) >= 0) + { + file->err = 0; + } + } + } +#endif + return file; } From cdfcbeff5ceb13044153a77150b3f720f324df23 Mon Sep 17 00:00:00 2001 From: Pavel Tsekov Date: Thu, 4 Sep 2014 12:44:03 +0300 Subject: [PATCH 11/12] X11: Convert GDI color to X11 color troughout. * client/X11/xf_client.c (xf_pre_connect): Set the field `colormap' of `struct xfContext' to the default colormap. * client/X11/xfreerdp.h (xf_gdi_get_color): Declare new external function. * client/X11/xf_gdi.c (xf_gdi_get_color): Define new external function. Use xf_gdi_get_color() to get the appropriate X color index from the GDI color representation. * client/X11/xf_graphics.c: Likewise. --- client/X11/xf_client.c | 1 + client/X11/xf_gdi.c | 33 +++++++++++++++++++++++++++++++++ client/X11/xf_graphics.c | 3 +++ client/X11/xfreerdp.h | 2 ++ 4 files changed, 39 insertions(+) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 56de3fcf9..4e4b674f6 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -794,6 +794,7 @@ BOOL xf_pre_connect(freerdp *instance) xfc->grab_keyboard = settings->GrabKeyboard; xfc->fullscreen_toggle = settings->ToggleFullscreen; xf_detect_monitors(xfc, settings); + xfc->colormap = DefaultColormap(xfc->display, xfc->screen_number); return TRUE; } diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index 59414d147..a376fab12 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -214,6 +214,28 @@ BOOL xf_set_rop3(xfContext* xfc, int rop3) return TRUE; } +unsigned long xf_gdi_get_color(xfContext* xfc, GDI_COLOR color) +{ + XColor x11_color; + + x11_color.flags = DoRed | DoGreen | DoBlue; + GetRGB32(x11_color.red, x11_color.green, x11_color.blue, color); + x11_color.red = x11_color.red << 8; + x11_color.green = x11_color.green << 8; + x11_color.blue = x11_color.blue << 8; + + if (XAllocColor(xfc->display, xfc->colormap, &x11_color) != 0) + { + XFreeColors(xfc->display, xfc->colormap, &x11_color.pixel, 1, 0); + } + else + { + x11_color.pixel = BlackPixel(xfc->display, xfc->screen_number); + } + + return x11_color.pixel; +} + Pixmap xf_brush_new(xfContext* xfc, int width, int height, int bpp, BYTE* data) { Pixmap bitmap; @@ -338,7 +360,9 @@ void xf_gdi_patblt(rdpContext* context, PATBLT_ORDER* patblt) xf_set_rop3(xfc, gdi_rop3_code(patblt->bRop)); foreColor = freerdp_color_convert_drawing_order_color_to_gdi_color(patblt->foreColor, context->settings->ColorDepth, xfc->clrconv); + foreColor = xf_gdi_get_color(xfc, foreColor); backColor = freerdp_color_convert_drawing_order_color_to_gdi_color(patblt->backColor, context->settings->ColorDepth, xfc->clrconv); + backColor = xf_gdi_get_color(xfc, backColor); if (brush->style == GDI_BS_SOLID) { @@ -458,6 +482,7 @@ void xf_gdi_opaque_rect(rdpContext* context, OPAQUE_RECT_ORDER* opaque_rect) xf_lock_x11(xfc, FALSE); color = freerdp_color_convert_drawing_order_color_to_gdi_color(opaque_rect->color, context->settings->ColorDepth, xfc->clrconv); + color = xf_gdi_get_color(xfc, color); XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); @@ -492,6 +517,7 @@ void xf_gdi_multi_opaque_rect(rdpContext* context, MULTI_OPAQUE_RECT_ORDER* mult xf_lock_x11(xfc, FALSE); color = freerdp_color_convert_drawing_order_color_to_gdi_color(multi_opaque_rect->color, context->settings->ColorDepth, xfc->clrconv); + color = xf_gdi_get_color(xfc, color); XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); @@ -534,6 +560,7 @@ void xf_gdi_line_to(rdpContext* context, LINE_TO_ORDER* line_to) xf_set_rop2(xfc, line_to->bRop2); color = freerdp_color_convert_drawing_order_color_to_gdi_color(line_to->penColor, context->settings->ColorDepth, xfc->clrconv); + color = xf_gdi_get_color(xfc, color); XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetForeground(xfc->display, xfc->gc, color); @@ -584,6 +611,7 @@ void xf_gdi_polyline(rdpContext* context, POLYLINE_ORDER* polyline) xf_set_rop2(xfc, polyline->bRop2); color = freerdp_color_convert_drawing_order_color_to_gdi_color(polyline->penColor, context->settings->ColorDepth, xfc->clrconv); + color = xf_gdi_get_color(xfc, color); XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetForeground(xfc->display, xfc->gc, color); @@ -680,7 +708,9 @@ void xf_gdi_mem3blt(rdpContext* context, MEM3BLT_ORDER* mem3blt) bitmap = (xfBitmap*) mem3blt->bitmap; xf_set_rop3(xfc, gdi_rop3_code(mem3blt->bRop)); foreColor = freerdp_color_convert_drawing_order_color_to_gdi_color(mem3blt->foreColor, context->settings->ColorDepth, xfc->clrconv); + foreColor = xf_gdi_get_color(xfc, foreColor); backColor = freerdp_color_convert_drawing_order_color_to_gdi_color(mem3blt->backColor, context->settings->ColorDepth, xfc->clrconv); + backColor = xf_gdi_get_color(xfc, backColor); if (brush->style == GDI_BS_PATTERN) { @@ -753,6 +783,7 @@ void xf_gdi_polygon_sc(rdpContext* context, POLYGON_SC_ORDER* polygon_sc) xf_set_rop2(xfc, polygon_sc->bRop2); brush_color = freerdp_color_convert_drawing_order_color_to_gdi_color(polygon_sc->brushColor, context->settings->ColorDepth, xfc->clrconv); + brush_color = xf_gdi_get_color(xfc, brush_color); npoints = polygon_sc->numPoints + 1; points = malloc(sizeof(XPoint) * npoints); @@ -814,7 +845,9 @@ void xf_gdi_polygon_cb(rdpContext* context, POLYGON_CB_ORDER* polygon_cb) brush = &(polygon_cb->brush); xf_set_rop2(xfc, polygon_cb->bRop2); foreColor = freerdp_color_convert_drawing_order_color_to_gdi_color(polygon_cb->foreColor, context->settings->ColorDepth, xfc->clrconv); + foreColor = xf_gdi_get_color(xfc, foreColor); backColor = freerdp_color_convert_drawing_order_color_to_gdi_color(polygon_cb->backColor, context->settings->ColorDepth, xfc->clrconv); + backColor = xf_gdi_get_color(xfc, backColor); npoints = polygon_cb->numPoints + 1; points = malloc(sizeof(XPoint) * npoints); diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c index f010a5ea5..d9ca075a6 100644 --- a/client/X11/xf_graphics.c +++ b/client/X11/xf_graphics.c @@ -398,6 +398,9 @@ void xf_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height xf_lock_x11(xfc, FALSE); + fgcolor = xf_gdi_get_color(xfc, fgcolor); + bgcolor = xf_gdi_get_color(xfc, bgcolor); + XSetFunction(xfc->display, xfc->gc, GXcopy); XSetFillStyle(xfc->display, xfc->gc, FillSolid); XSetForeground(xfc->display, xfc->gc, fgcolor); diff --git a/client/X11/xfreerdp.h b/client/X11/xfreerdp.h index d0a8e3cfb..bf67c1223 100644 --- a/client/X11/xfreerdp.h +++ b/client/X11/xfreerdp.h @@ -243,6 +243,8 @@ void xf_unlock_x11(xfContext* xfc, BOOL display); void xf_draw_screen_scaled(xfContext* xfc, int x, int y, int w, int h, BOOL scale); void xf_transform_window(xfContext* xfc); +unsigned long xf_gdi_get_color(xfContext* xfc, GDI_COLOR color); + FREERDP_API DWORD xf_exit_code_from_disconnect_reason(DWORD reason); #endif /* __XFREERDP_H */ From 66bbbf0519b145b0df26771fd7570e9570bbb0b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Fri, 5 Sep 2014 16:06:19 -0400 Subject: [PATCH 12/12] libfreerdp-gdi: enable altsec frame markers --- client/X11/xf_client.c | 69 +++++++++++++++++++++++--------------- client/X11/xf_gdi.c | 7 ++++ client/X11/xf_graphics.c | 1 - libfreerdp/core/settings.c | 2 +- libfreerdp/core/update.c | 2 ++ libfreerdp/gdi/gdi.c | 7 ++++ 6 files changed, 59 insertions(+), 29 deletions(-) diff --git a/client/X11/xf_client.c b/client/X11/xf_client.c index 4df36d82f..a803edf74 100644 --- a/client/X11/xf_client.c +++ b/client/X11/xf_client.c @@ -180,31 +180,41 @@ void xf_draw_screen_scaled(xfContext *xfc, int x, int y, int w, int h, BOOL scal void xf_sw_begin_paint(rdpContext *context) { - rdpGdi *gdi = context->gdi; + rdpGdi* gdi = context->gdi; gdi->primary->hdc->hwnd->invalid->null = 1; gdi->primary->hdc->hwnd->ninvalid = 0; } void xf_sw_end_paint(rdpContext *context) { - rdpGdi *gdi; + int i; INT32 x, y; UINT32 w, h; - xfContext *xfc = (xfContext *) context; - gdi = context->gdi; - if(!xfc->remote_app) + int ninvalid; + HGDI_RGN cinvalid; + xfContext* xfc = (xfContext*) context; + rdpGdi* gdi = context->gdi; + + x = gdi->primary->hdc->hwnd->invalid->x; + y = gdi->primary->hdc->hwnd->invalid->y; + w = gdi->primary->hdc->hwnd->invalid->w; + h = gdi->primary->hdc->hwnd->invalid->h; + + ninvalid = gdi->primary->hdc->hwnd->ninvalid; + cinvalid = gdi->primary->hdc->hwnd->cinvalid; + + if (!xfc->remote_app) { - if(!xfc->complex_regions) + if (!xfc->complex_regions) { - if(gdi->primary->hdc->hwnd->invalid->null) + if (gdi->primary->hdc->hwnd->invalid->null) return; - x = gdi->primary->hdc->hwnd->invalid->x; - y = gdi->primary->hdc->hwnd->invalid->y; - w = gdi->primary->hdc->hwnd->invalid->w; - h = gdi->primary->hdc->hwnd->invalid->h; + xf_lock_x11(xfc, FALSE); + XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h); - if((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y)) + + if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y)) { xf_draw_screen_scaled(xfc, x, y, w, h, TRUE); } @@ -212,27 +222,27 @@ void xf_sw_end_paint(rdpContext *context) { XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, x, y, w, h, x, y); } + xf_unlock_x11(xfc, FALSE); } else { - int i; - int ninvalid; - HGDI_RGN cinvalid; - if(gdi->primary->hdc->hwnd->ninvalid < 1) + if (gdi->primary->hdc->hwnd->ninvalid < 1) return; - ninvalid = gdi->primary->hdc->hwnd->ninvalid; - cinvalid = gdi->primary->hdc->hwnd->cinvalid; + xf_lock_x11(xfc, FALSE); - for(i = 0; i < ninvalid; i++) + + for (i = 0; i < ninvalid; i++) { x = cinvalid[i].x; y = cinvalid[i].y; w = cinvalid[i].w; h = cinvalid[i].h; + //combine xfc->primary with xfc->image XPutImage(xfc->display, xfc->primary, xfc->gc, xfc->image, x, y, x, y, w, h); - if((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y)) + + if ((xfc->settings->ScalingFactor != 1.0) || (xfc->offset_x) || (xfc->offset_y)) { xf_draw_screen_scaled(xfc, x, y, w, h, TRUE); } @@ -241,20 +251,21 @@ void xf_sw_end_paint(rdpContext *context) XCopyArea(xfc->display, xfc->primary, xfc->window->handle, xfc->gc, x, y, w, h, x, y); } } + XFlush(xfc->display); + xf_unlock_x11(xfc, FALSE); } } else { - if(gdi->primary->hdc->hwnd->invalid->null) + if (gdi->primary->hdc->hwnd->invalid->null) return; - x = gdi->primary->hdc->hwnd->invalid->x; - y = gdi->primary->hdc->hwnd->invalid->y; - w = gdi->primary->hdc->hwnd->invalid->w; - h = gdi->primary->hdc->hwnd->invalid->h; + xf_lock_x11(xfc, FALSE); + xf_rail_paint(xfc, context->rail, x, y, x + w - 1, y + h - 1); + xf_unlock_x11(xfc, FALSE); } } @@ -264,12 +275,15 @@ void xf_sw_desktop_resize(rdpContext *context) rdpSettings *settings; xfContext *xfc = (xfContext *) context; settings = xfc->instance->settings; + xf_lock_x11(xfc, TRUE); - if(!xfc->fullscreen) + + if (!xfc->fullscreen) { rdpGdi *gdi = context->gdi; gdi_resize(gdi, xfc->width, xfc->height); - if(xfc->image) + + if (xfc->image) { xfc->image->data = NULL; XDestroyImage(xfc->image); @@ -277,6 +291,7 @@ void xf_sw_desktop_resize(rdpContext *context) (char *) gdi->primary_buffer, gdi->width, gdi->height, xfc->scanline_pad, 0); } } + xf_unlock_x11(xfc, TRUE); } diff --git a/client/X11/xf_gdi.c b/client/X11/xf_gdi.c index efd536d7f..c18846370 100644 --- a/client/X11/xf_gdi.c +++ b/client/X11/xf_gdi.c @@ -949,6 +949,11 @@ void xf_gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb) DEBUG_WARN( "EllipseCB\n"); } +void xf_gdi_frame_marker(rdpContext* context, FRAME_MARKER_ORDER* frameMarker) +{ + +} + void xf_gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker) { rdpSettings* settings; @@ -1187,5 +1192,7 @@ void xf_gdi_register_update_callbacks(rdpUpdate* update) update->SurfaceBits = xf_gdi_surface_bits; update->SurfaceFrameMarker = xf_gdi_surface_frame_marker; + + update->altsec->FrameMarker = xf_gdi_frame_marker; } diff --git a/client/X11/xf_graphics.c b/client/X11/xf_graphics.c index 971302ff3..330977684 100644 --- a/client/X11/xf_graphics.c +++ b/client/X11/xf_graphics.c @@ -389,7 +389,6 @@ void xf_Glyph_Draw(rdpContext* context, rdpGlyph* glyph, int x, int y) void xf_Glyph_BeginDraw(rdpContext* context, int x, int y, int width, int height, UINT32 bgcolor, UINT32 fgcolor) { - xfContext* context_ = (xfContext*) context; xfContext* xfc = (xfContext*) context; bgcolor = freerdp_color_convert_drawing_order_color_to_gdi_color(bgcolor, context->settings->ColorDepth, xfc->clrconv); diff --git a/libfreerdp/core/settings.c b/libfreerdp/core/settings.c index feb811967..0eec9b087 100644 --- a/libfreerdp/core/settings.c +++ b/libfreerdp/core/settings.c @@ -321,7 +321,7 @@ rdpSettings* freerdp_settings_new(DWORD flags) settings->DrawGdiPlusEnabled = FALSE; - settings->FrameMarkerCommandEnabled = FALSE; + settings->FrameMarkerCommandEnabled = TRUE; settings->SurfaceFrameMarkerEnabled = TRUE; settings->BitmapCacheV3Enabled = FALSE; diff --git a/libfreerdp/core/update.c b/libfreerdp/core/update.c index b400aaeed..11ff7c0a7 100644 --- a/libfreerdp/core/update.c +++ b/libfreerdp/core/update.c @@ -164,6 +164,8 @@ BOOL update_read_bitmap_update(rdpUpdate* update, wStream* s, BITMAP_UPDATE* bit Stream_Read_UINT16(s, bitmapUpdate->number); /* numberRectangles (2 bytes) */ + WLog_Print(update->log, WLOG_DEBUG, "BitmapUpdate: %d", bitmapUpdate->number); + if (bitmapUpdate->number > bitmapUpdate->count) { UINT16 count; diff --git a/libfreerdp/gdi/gdi.c b/libfreerdp/gdi/gdi.c index ee767cfd3..d78d780d9 100644 --- a/libfreerdp/gdi/gdi.c +++ b/libfreerdp/gdi/gdi.c @@ -764,6 +764,11 @@ void gdi_ellipse_cb(rdpContext* context, ELLIPSE_CB_ORDER* ellipse_cb) DEBUG_WARN( "EllipseCB\n"); } +void gdi_frame_marker(rdpContext* context, FRAME_MARKER_ORDER* frameMarker) +{ + +} + void gdi_surface_frame_marker(rdpContext* context, SURFACE_FRAME_MARKER* surface_frame_marker) { DEBUG_GDI("frameId %d frameAction %d", @@ -943,6 +948,8 @@ void gdi_register_update_callbacks(rdpUpdate* update) update->SurfaceBits = gdi_surface_bits; update->SurfaceFrameMarker = gdi_surface_frame_marker; + + update->altsec->FrameMarker = gdi_frame_marker; } void gdi_init_primary(rdpGdi* gdi)