Fixed EGFX capability parsing, respect length fields.

Disable RDPGFX_CAPVERSION_106 as we currently do not support scaled
outputs.
This commit is contained in:
Armin Novak 2019-02-27 17:15:43 +01:00
parent e8c8e7b6d0
commit 69e9571d9e
3 changed files with 33 additions and 21 deletions

View File

@ -55,6 +55,7 @@
static UINT rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback)
{
UINT error;
UINT32 x;
wStream* s;
UINT16 index;
RDPGFX_PLUGIN* gfx;
@ -118,12 +119,10 @@ static UINT rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback)
caps10Flags |= RDPGFX_CAPS_FLAG_AVC_DISABLED;
#endif
capsSet->flags = caps10Flags;
/*
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_101;
capsSet->length = 0x10;
capsSet->flags = 0;
*/
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_101;
capsSet->length = 0x10;
capsSet->flags = 0;
capsSet = &capsSets[pdu.capsSetCount++];
capsSet->version = RDPGFX_CAPVERSION_102;
capsSet->length = 0x4;
@ -145,12 +144,21 @@ static UINT rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback)
capsSet->length = 0x4;
capsSet->flags = caps10Flags;
capsSet = &capsSets[pdu.capsSetCount++];
/* TODO: Until RDPGFX_MAP_SURFACE_TO_SCALED_OUTPUT_PDU and
* RDPGFX_MAP_SURFACE_TO_SCALED_WINDOW_PDU are not implemented do not
* announce the following version */
#if 0
capsSet->version = RDPGFX_CAPVERSION_106;
capsSet->length = 0x4;
capsSet->flags = caps10Flags;
#endif
}
header.pduLength = RDPGFX_HEADER_SIZE + 2 + (pdu.capsSetCount * RDPGFX_CAPSET_SIZE);
header.pduLength = RDPGFX_HEADER_SIZE + 2;
for (x = 0; x < pdu.capsSetCount; x++)
header.pduLength += RDPGFX_CAPSET_BASE_SIZE + capsSets[x].length;
WLog_Print(gfx->log, WLOG_DEBUG, "SendCapsAdvertisePdu %"PRIu16"", pdu.capsSetCount);
s = Stream_New(NULL, header.pduLength);
@ -172,6 +180,7 @@ static UINT rdpgfx_send_caps_advertise_pdu(RDPGFX_CHANNEL_CALLBACK* callback)
Stream_Write_UINT32(s, capsSet->version); /* version (4 bytes) */
Stream_Write_UINT32(s, capsSet->length); /* capsDataLength (4 bytes) */
Stream_Write_UINT32(s, capsSet->flags); /* capsData (4 bytes) */
Stream_Zero(s, capsSet->length - 4);
}
Stream_SealLength(s);

View File

@ -204,7 +204,7 @@ static UINT rdpgfx_send_caps_confirm_pdu(RdpgfxServerContext* context,
{
RDPGFX_CAPSET* capsSet = capsConfirm->capsSet;
wStream* s = rdpgfx_server_single_packet_new(
RDPGFX_CMDID_CAPSCONFIRM, RDPGFX_CAPSET_SIZE);
RDPGFX_CMDID_CAPSCONFIRM, RDPGFX_CAPSET_BASE_SIZE + capsSet->length);
if (!s)
{
@ -213,8 +213,16 @@ static UINT rdpgfx_send_caps_confirm_pdu(RdpgfxServerContext* context,
}
Stream_Write_UINT32(s, capsSet->version); /* version (4 bytes) */
Stream_Write_UINT32(s, 4); /* capsDataLength (4 bytes) */
Stream_Write_UINT32(s, capsSet->flags); /* capsData (4 bytes) */
Stream_Write_UINT32(s, capsSet->length); /* capsDataLength (4 bytes) */
if (capsSet->length >= 4)
{
Stream_Write_UINT32(s, capsSet->flags); /* capsData (4 bytes) */
Stream_Zero(s, capsSet->length - 4);
}
else
Stream_Zero(s, capsSet->length);
return rdpgfx_server_single_packet_send(context, s);
}
@ -1196,13 +1204,13 @@ static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context,
Stream_Read_UINT16(s, pdu.capsSetCount); /* capsSetCount (2 bytes) */
if (Stream_GetRemainingLength(s) < (pdu.capsSetCount * RDPGFX_CAPSET_SIZE))
if (Stream_GetRemainingLength(s) < (pdu.capsSetCount * (RDPGFX_CAPSET_BASE_SIZE + 4)))
{
WLog_ERR(TAG, "not enough data!");
return ERROR_INVALID_DATA;
}
capsSets = calloc(pdu.capsSetCount, RDPGFX_CAPSET_SIZE);
capsSets = calloc(pdu.capsSetCount, (RDPGFX_CAPSET_BASE_SIZE + 4));
if (!capsSets)
return ERROR_OUTOFMEMORY;
@ -1215,15 +1223,10 @@ static UINT rdpgfx_recv_caps_advertise_pdu(RdpgfxServerContext* context,
Stream_Read_UINT32(s, capsSet->version); /* version (4 bytes) */
Stream_Read_UINT32(s, capsDataLength); /* capsDataLength (4 bytes) */
if (capsDataLength != 4)
{
WLog_ERR(TAG, "capsDataLength does not equal to 4: %"PRIu32"",
capsDataLength);
free(capsSets);
return ERROR_INVALID_DATA;
}
if (capsDataLength >= 4)
Stream_Peek_UINT32(s, capsSet->flags); /* capsData (4 bytes) */
Stream_Read_UINT32(s, capsSet->flags); /* capsData (4 bytes) */
Stream_Seek(s, capsSet->length);
}
if (context)

View File

@ -102,7 +102,7 @@ typedef struct _RDPGFX_HEADER RDPGFX_HEADER;
#define RDPGFX_CAPVERSION_106 0x000A0601 /** [MS-RDPEGFX] 2.2.3.9 */
#define RDPGFX_NUMBER_CAPSETS 9
#define RDPGFX_CAPSET_SIZE 12
#define RDPGFX_CAPSET_BASE_SIZE 8
struct _RDPGFX_CAPSET
{