Skip to content

Commit

Permalink
Enable fragmented Fast-Path Updates
Browse files Browse the repository at this point in the history
Fragmented updates are concatenated into temporary streams (one per
update type) that are processed when receiving an update with the
FASTPATH_FRAGMENT_LAST bit set.
  • Loading branch information
derfian committed Oct 16, 2017
1 parent 8e3ec9e commit 0c7b411
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 41 deletions.
5 changes: 5 additions & 0 deletions constants.h
Expand Up @@ -57,6 +57,8 @@

#define FASTPATH_OUTPUT_COMPRESSION_USED (0x2 << 6)

#define RDESKTOP_FASTPATH_MULTIFRAGMENT_MAX_SIZE 32767

/* ISO PDU codes */
enum ISO_PDU_CODE
{
Expand Down Expand Up @@ -378,6 +380,9 @@ enum RDP_INPUT_DEVICE
#define RDP_CAPLEN_BMPCACHE2 0x28
#define BMPCACHE2_FLAG_PERSIST ((uint32)1<<31)

#define RDP_CAPSET_MULTIFRAGMENTUPDATE 26
#define RDP_CAPLEN_MULTIFRAGMENTUPDATE 8

#define RDP_SOURCE "MSTSC"

/* Logon flags */
Expand Down
12 changes: 11 additions & 1 deletion rdp.c
Expand Up @@ -934,6 +934,14 @@ rdp_out_ts_glyphcache_capabilityset(STREAM s)
out_uint16_le(s, 0); /* pad2octets */
}

static void
rdp_out_ts_multifragmentupdate_capabilityset(STREAM s)
{
out_uint16_le(s, RDP_CAPSET_MULTIFRAGMENTUPDATE);
out_uint16_le(s, RDP_CAPLEN_MULTIFRAGMENTUPDATE);
out_uint32_le(s, RDESKTOP_FASTPATH_MULTIFRAGMENT_MAX_SIZE); /* MaxRequestSize */
}

#define RDP5_FLAG 0x0030
/* Send a confirm active PDU */
static void
Expand All @@ -954,6 +962,7 @@ rdp_send_confirm_active(void)
RDP_CAPLEN_FONT +
RDP_CAPLEN_SOUND +
RDP_CAPLEN_GLYPHCACHE +
RDP_CAPLEN_MULTIFRAGMENTUPDATE +
4 /* w2k fix, sessionid */ ;

if (g_rdp_version >= RDP_V5)
Expand All @@ -979,7 +988,7 @@ rdp_send_confirm_active(void)
out_uint16_le(s, caplen);

out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
out_uint16_le(s, 0xe); /* num_caps */
out_uint16_le(s, 15); /* num_caps */
out_uint8s(s, 2); /* pad */

rdp_out_ts_general_capabilityset(s);
Expand All @@ -1005,6 +1014,7 @@ rdp_send_confirm_active(void)
rdp_out_ts_sound_capabilityset(s);
rdp_out_ts_font_capabilityset(s);
rdp_out_ts_glyphcache_capabilityset(s);
rdp_out_ts_multifragmentupdate_capabilityset(s);

s_mark_end(s);
sec_send(s, sec_flags);
Expand Down
118 changes: 78 additions & 40 deletions rdp5.c
Expand Up @@ -25,17 +25,68 @@ extern uint8 *g_next_packet;

extern RDPCOMP g_mppc_dict;


static void
process_ts_fp_update_by_code(STREAM s, uint8 code)
{
uint16 count, x, y;

switch (code)
{
case FASTPATH_UPDATETYPE_ORDERS:
in_uint16_le(s, count);
process_orders(s, count);
break;
case FASTPATH_UPDATETYPE_BITMAP:
in_uint8s(s, 2); /* part length */
process_bitmap_updates(s);
break;
case FASTPATH_UPDATETYPE_PALETTE:
in_uint8s(s, 2); /* uint16 = 2 */
process_palette(s);
break;
case FASTPATH_UPDATETYPE_SYNCHRONIZE:
break;
case FASTPATH_UPDATETYPE_PTR_NULL:
ui_set_null_cursor();
break;
case FASTPATH_UPDATETYPE_PTR_DEFAULT:
set_system_pointer(SYSPTR_DEFAULT);
break;
case FASTPATH_UPDATETYPE_PTR_POSITION:
in_uint16_le(s, x);
in_uint16_le(s, y);
if (s_check(s))
ui_move_pointer(x, y);
break;
case FASTPATH_UPDATETYPE_COLOR:
process_colour_pointer_pdu(s);
break;
case FASTPATH_UPDATETYPE_CACHED:
process_cached_pointer_pdu(s);
break;
case FASTPATH_UPDATETYPE_POINTER:
process_new_pointer_pdu(s);
break;
default:
logger(Protocol, Warning, "process_ts_fp_updates_by_code(), unhandled opcode %d",
code);
}
}

void
process_ts_fp_updates(STREAM s)
{
uint16 length, count, x, y;
uint16 length;
uint8 hdr, code, frag, comp, ctype = 0;
uint8 *next;

uint32 roff, rlen;
struct stream *ns = &(g_mppc_dict.ns);
struct stream *ts;

static STREAM assembled[0x0F] = { 0 };

ui_begin_update();
while (s->p < s->end)
{
Expand Down Expand Up @@ -73,46 +124,33 @@ process_ts_fp_updates(STREAM s)
else
ts = s;

switch (code)
if (frag == FASTPATH_FRAGMENT_SINGLE)
{
process_ts_fp_update_by_code(ts, code);
}
else /* Fragmented packet, we must reassemble */
{
case FASTPATH_UPDATETYPE_ORDERS:
in_uint16_le(ts, count);
process_orders(ts, count);
break;
case FASTPATH_UPDATETYPE_BITMAP:
in_uint8s(ts, 2); /* part length */
process_bitmap_updates(ts);
break;
case FASTPATH_UPDATETYPE_PALETTE:
in_uint8s(ts, 2); /* uint16 = 2 */
process_palette(ts);
break;
case FASTPATH_UPDATETYPE_SYNCHRONIZE:
break;
case FASTPATH_UPDATETYPE_PTR_NULL:
ui_set_null_cursor();
break;
case FASTPATH_UPDATETYPE_PTR_DEFAULT:
set_system_pointer(SYSPTR_DEFAULT);
break;
case FASTPATH_UPDATETYPE_PTR_POSITION:
in_uint16_le(ts, x);
in_uint16_le(ts, y);
if (s_check(ts))
ui_move_pointer(x, y);
break;
case FASTPATH_UPDATETYPE_COLOR:
process_colour_pointer_pdu(ts);
break;
case FASTPATH_UPDATETYPE_CACHED:
process_cached_pointer_pdu(ts);
break;
case FASTPATH_UPDATETYPE_POINTER:
process_new_pointer_pdu(ts);
break;
default:
logger(Protocol, Warning, "process_ts_fp_updates(), unhandled opcode %d",
code);
if (assembled[code] == NULL)
{
assembled[code] = xmalloc(sizeof(struct stream));
memset(assembled[code], 0, sizeof(struct stream));
s_realloc(assembled[code], RDESKTOP_FASTPATH_MULTIFRAGMENT_MAX_SIZE);
s_reset(assembled[code]);
}

if (frag == FASTPATH_FRAGMENT_FIRST)
{
s_reset(assembled[code]);
}

out_uint8p(assembled[code], ts->p, length);

if (frag == FASTPATH_FRAGMENT_LAST)
{
s_mark_end(assembled[code]);
assembled[code]->p = assembled[code]->data;
process_ts_fp_update_by_code(assembled[code], code);
}
}

s->p = next;
Expand Down

0 comments on commit 0c7b411

Please sign in to comment.