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.
This commit is contained in:
akallabeth 2020-03-19 09:04:59 +01:00
parent 9223eea61e
commit 88ad9ca56b
5 changed files with 31 additions and 13 deletions

View File

@ -114,6 +114,13 @@ struct _TS_BITMAP_DATA_EX
}; };
typedef struct _TS_BITMAP_DATA_EX 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 struct _SURFACE_BITS_COMMAND
{ {
UINT32 cmdType; UINT32 cmdType;

View File

@ -85,13 +85,14 @@ static BOOL update_recv_surfcmd_bitmap_ex(wStream* s, TS_BITMAP_DATA_EX* bmp)
return TRUE; 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 }; SURFACE_BITS_COMMAND cmd = { 0 };
if (Stream_GetRemainingLength(s) < 8) if (Stream_GetRemainingLength(s) < 8)
goto fail; goto fail;
cmd.cmdType = cmdType;
Stream_Read_UINT16(s, cmd.destLeft); Stream_Read_UINT16(s, cmd.destLeft);
Stream_Read_UINT16(s, cmd.destTop); Stream_Read_UINT16(s, cmd.destTop);
Stream_Read_UINT16(s, cmd.destRight); 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_SET_SURFACE_BITS:
case CMDTYPE_STREAM_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; return -1;
break; 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)) if (!Stream_EnsureRemainingCapacity(s, SURFCMD_SURFACE_BITS_HEADER_LENGTH))
return FALSE; 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->destLeft);
Stream_Write_UINT16(s, cmd->destTop); Stream_Write_UINT16(s, cmd->destTop);
Stream_Write_UINT16(s, cmd->destRight); Stream_Write_UINT16(s, cmd->destRight);

View File

@ -28,13 +28,6 @@
#define SURFCMD_SURFACE_BITS_HEADER_LENGTH 22 #define SURFCMD_SURFACE_BITS_HEADER_LENGTH 22
#define SURFCMD_FRAME_MARKER_LENGTH 8 #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 int update_recv_surfcmds(rdpUpdate* update, wStream* s);
FREERDP_LOCAL BOOL update_write_surfcmd_surface_bits(wStream* s, const SURFACE_BITS_COMMAND* cmd); FREERDP_LOCAL BOOL update_write_surfcmd_surface_bits(wStream* s, const SURFACE_BITS_COMMAND* cmd);

View File

@ -71,7 +71,8 @@ static BOOL test_peer_context_new(freerdp_peer* client, rdpContext* ctx)
if (!(context->nsc_context = nsc_context_new())) if (!(context->nsc_context = nsc_context_new()))
goto fail_nsc_context; 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))) if (!(context->s = Stream_New(NULL, 65536)))
goto fail_stream_new; 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) static void test_peer_begin_frame(freerdp_peer* client)
{ {
rdpUpdate* update = client->update; rdpUpdate* update = client->update;
SURFACE_FRAME_MARKER fm; SURFACE_FRAME_MARKER fm = { 0 };
testPeerContext* context = (testPeerContext*)client->context; testPeerContext* context = (testPeerContext*)client->context;
fm.frameAction = SURFACECMD_FRAMEACTION_BEGIN; fm.frameAction = SURFACECMD_FRAMEACTION_BEGIN;
fm.frameId = context->frame_id; 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) static void test_peer_end_frame(freerdp_peer* client)
{ {
rdpUpdate* update = client->update; rdpUpdate* update = client->update;
SURFACE_FRAME_MARKER fm; SURFACE_FRAME_MARKER fm = { 0 };
testPeerContext* context = (testPeerContext*)client->context; testPeerContext* context = (testPeerContext*)client->context;
fm.frameAction = SURFACECMD_FRAMEACTION_END; fm.frameAction = SURFACECMD_FRAMEACTION_END;
fm.frameId = context->frame_id; 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.bmp.codecID = client->settings->NSCodecId;
} }
cmd.cmdType = CMDTYPE_SET_SURFACE_BITS;
cmd.destLeft = 0; cmd.destLeft = 0;
cmd.destTop = 0; cmd.destTop = 0;
cmd.destRight = rect.width; 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.bmp.codecID = client->settings->NSCodecId;
} }
cmd.cmdType = CMDTYPE_SET_SURFACE_BITS;
cmd.destLeft = context->icon_x; cmd.destLeft = context->icon_x;
cmd.destTop = context->icon_y; cmd.destTop = context->icon_y;
cmd.destRight = context->icon_x + context->icon_width; 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.bmp.codecID = client->settings->NSCodecId;
} }
cmd.cmdType = CMDTYPE_SET_SURFACE_BITS;
cmd.destLeft = x; cmd.destLeft = x;
cmd.destTop = y; cmd.destTop = y;
cmd.destRight = x + context->icon_width; cmd.destRight = x + context->icon_width;

View File

@ -976,6 +976,7 @@ static BOOL shadow_client_send_surface_bits(rdpShadowClient* client, BYTE* pSrcD
return FALSE; return FALSE;
} }
cmd.cmdType = CMDTYPE_SET_SURFACE_BITS;
cmd.bmp.codecID = settings->RemoteFxCodecId; cmd.bmp.codecID = settings->RemoteFxCodecId;
cmd.destLeft = 0; cmd.destLeft = 0;
cmd.destTop = 0; cmd.destTop = 0;
@ -1040,6 +1041,7 @@ static BOOL shadow_client_send_surface_bits(rdpShadowClient* client, BYTE* pSrcD
Stream_SetPosition(s, 0); Stream_SetPosition(s, 0);
pSrcData = &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)]; pSrcData = &pSrcData[(nYSrc * nSrcStep) + (nXSrc * 4)];
nsc_compose_message(encoder->nsc, s, pSrcData, nWidth, nHeight, nSrcStep); nsc_compose_message(encoder->nsc, s, pSrcData, nWidth, nHeight, nSrcStep);
cmd.cmdType = CMDTYPE_SET_SURFACE_BITS;
cmd.bmp.bpp = 32; cmd.bmp.bpp = 32;
cmd.bmp.codecID = settings->NSCodecId; cmd.bmp.codecID = settings->NSCodecId;
cmd.destLeft = nXSrc; cmd.destLeft = nXSrc;