From 88ad9ca56bcd422fb4c9ccfe9aa4378cb0c788ba Mon Sep 17 00:00:00 2001 From: akallabeth Date: Thu, 19 Mar 2020 09:04:59 +0100 Subject: [PATCH] Fix sending/receiving surface bits command. * Pass on proper command type to application * On send let the server implementation decide to send 2.2.9.2.1 Set Surface Bits Command (TS_SURFCMD_SET_SURF_BITS) or 2.2.9.2.2 Stream Surface Bits Command (TS_SURFCMD_STREAM_SURF_BITS) Thanks to @viniciusjarina for tracing the issue down. --- include/freerdp/update.h | 7 +++++++ libfreerdp/core/surface.c | 18 +++++++++++++++--- libfreerdp/core/surface.h | 7 ------- server/Sample/sfreerdp.c | 10 +++++++--- server/shadow/shadow_client.c | 2 ++ 5 files changed, 31 insertions(+), 13 deletions(-) diff --git a/include/freerdp/update.h b/include/freerdp/update.h index aa1c40417..d2797a28e 100644 --- a/include/freerdp/update.h +++ b/include/freerdp/update.h @@ -114,6 +114,13 @@ struct _TS_BITMAP_DATA_EX }; typedef struct _TS_BITMAP_DATA_EX TS_BITMAP_DATA_EX; +enum SURFCMD_CMDTYPE +{ + CMDTYPE_SET_SURFACE_BITS = 0x0001, + CMDTYPE_FRAME_MARKER = 0x0004, + CMDTYPE_STREAM_SURFACE_BITS = 0x0006 +}; + struct _SURFACE_BITS_COMMAND { UINT32 cmdType; diff --git a/libfreerdp/core/surface.c b/libfreerdp/core/surface.c index db51e6812..76ca962c7 100644 --- a/libfreerdp/core/surface.c +++ b/libfreerdp/core/surface.c @@ -85,13 +85,14 @@ static BOOL update_recv_surfcmd_bitmap_ex(wStream* s, TS_BITMAP_DATA_EX* bmp) return TRUE; } -static BOOL update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s) +static BOOL update_recv_surfcmd_surface_bits(rdpUpdate* update, wStream* s, UINT16 cmdType) { SURFACE_BITS_COMMAND cmd = { 0 }; if (Stream_GetRemainingLength(s) < 8) goto fail; + cmd.cmdType = cmdType; Stream_Read_UINT16(s, cmd.destLeft); Stream_Read_UINT16(s, cmd.destTop); Stream_Read_UINT16(s, cmd.destRight); @@ -148,7 +149,7 @@ int update_recv_surfcmds(rdpUpdate* update, wStream* s) { case CMDTYPE_SET_SURFACE_BITS: case CMDTYPE_STREAM_SURFACE_BITS: - if (!update_recv_surfcmd_surface_bits(update, s)) + if (!update_recv_surfcmd_surface_bits(update, s, cmdType)) return -1; break; @@ -226,7 +227,18 @@ BOOL update_write_surfcmd_surface_bits(wStream* s, const SURFACE_BITS_COMMAND* c if (!Stream_EnsureRemainingCapacity(s, SURFCMD_SURFACE_BITS_HEADER_LENGTH)) return FALSE; - Stream_Write_UINT16(s, CMDTYPE_STREAM_SURFACE_BITS); + switch (cmd->cmdType) + { + case CMDTYPE_SET_SURFACE_BITS: + case CMDTYPE_STREAM_SURFACE_BITS: + break; + default: + WLog_ERR(TAG, "%s SURFACE_BITS_COMMAND->cmdType 0x%08" PRIx32 " not allowed.", + cmd->cmdType); + return FALSE; + } + + Stream_Write_UINT16(s, cmd->cmdType); Stream_Write_UINT16(s, cmd->destLeft); Stream_Write_UINT16(s, cmd->destTop); Stream_Write_UINT16(s, cmd->destRight); diff --git a/libfreerdp/core/surface.h b/libfreerdp/core/surface.h index aa4819a50..9e43cb489 100644 --- a/libfreerdp/core/surface.h +++ b/libfreerdp/core/surface.h @@ -28,13 +28,6 @@ #define SURFCMD_SURFACE_BITS_HEADER_LENGTH 22 #define SURFCMD_FRAME_MARKER_LENGTH 8 -enum SURFCMD_CMDTYPE -{ - CMDTYPE_SET_SURFACE_BITS = 0x0001, - CMDTYPE_FRAME_MARKER = 0x0004, - CMDTYPE_STREAM_SURFACE_BITS = 0x0006 -}; - FREERDP_LOCAL int update_recv_surfcmds(rdpUpdate* update, wStream* s); FREERDP_LOCAL BOOL update_write_surfcmd_surface_bits(wStream* s, const SURFACE_BITS_COMMAND* cmd); diff --git a/server/Sample/sfreerdp.c b/server/Sample/sfreerdp.c index f8ea493e9..73fe06d46 100644 --- a/server/Sample/sfreerdp.c +++ b/server/Sample/sfreerdp.c @@ -71,7 +71,8 @@ static BOOL test_peer_context_new(freerdp_peer* client, rdpContext* ctx) if (!(context->nsc_context = nsc_context_new())) goto fail_nsc_context; - nsc_context_set_pixel_format(context->nsc_context, PIXEL_FORMAT_RGB24); + if (!nsc_context_set_parameters(context->nsc_context, NSC_COLOR_FORMAT, PIXEL_FORMAT_RGB24)) + goto fail_stream_new; if (!(context->s = Stream_New(NULL, 65536))) goto fail_stream_new; @@ -151,7 +152,7 @@ static wStream* test_peer_stream_init(testPeerContext* context) static void test_peer_begin_frame(freerdp_peer* client) { rdpUpdate* update = client->update; - SURFACE_FRAME_MARKER fm; + SURFACE_FRAME_MARKER fm = { 0 }; testPeerContext* context = (testPeerContext*)client->context; fm.frameAction = SURFACECMD_FRAMEACTION_BEGIN; fm.frameId = context->frame_id; @@ -161,7 +162,7 @@ static void test_peer_begin_frame(freerdp_peer* client) static void test_peer_end_frame(freerdp_peer* client) { rdpUpdate* update = client->update; - SURFACE_FRAME_MARKER fm; + SURFACE_FRAME_MARKER fm = { 0 }; testPeerContext* context = (testPeerContext*)client->context; fm.frameAction = SURFACECMD_FRAMEACTION_END; fm.frameId = context->frame_id; @@ -215,6 +216,7 @@ static BOOL test_peer_draw_background(freerdp_peer* client) cmd.bmp.codecID = client->settings->NSCodecId; } + cmd.cmdType = CMDTYPE_SET_SURFACE_BITS; cmd.destLeft = 0; cmd.destTop = 0; cmd.destRight = rect.width; @@ -337,6 +339,7 @@ static void test_peer_draw_icon(freerdp_peer* client, int x, int y) cmd.bmp.codecID = client->settings->NSCodecId; } + cmd.cmdType = CMDTYPE_SET_SURFACE_BITS; cmd.destLeft = context->icon_x; cmd.destTop = context->icon_y; cmd.destRight = context->icon_x + context->icon_width; @@ -365,6 +368,7 @@ static void test_peer_draw_icon(freerdp_peer* client, int x, int y) cmd.bmp.codecID = client->settings->NSCodecId; } + cmd.cmdType = CMDTYPE_SET_SURFACE_BITS; cmd.destLeft = x; cmd.destTop = y; cmd.destRight = x + context->icon_width; diff --git a/server/shadow/shadow_client.c b/server/shadow/shadow_client.c index e90e7f664..90cf632c4 100644 --- a/server/shadow/shadow_client.c +++ b/server/shadow/shadow_client.c @@ -976,6 +976,7 @@ static BOOL shadow_client_send_surface_bits(rdpShadowClient* client, BYTE* pSrcD return FALSE; } + cmd.cmdType = CMDTYPE_SET_SURFACE_BITS; cmd.bmp.codecID = settings->RemoteFxCodecId; cmd.destLeft = 0; cmd.destTop = 0; @@ -1040,6 +1041,7 @@ static BOOL shadow_client_send_surface_bits(rdpShadowClient* client, BYTE* pSrcD Stream_SetPosition(s, 0); pSrcData = &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)]; nsc_compose_message(encoder->nsc, s, pSrcData, nWidth, nHeight, nSrcStep); + cmd.cmdType = CMDTYPE_SET_SURFACE_BITS; cmd.bmp.bpp = 32; cmd.bmp.codecID = settings->NSCodecId; cmd.destLeft = nXSrc;