Enable fragmented Fast-Path Updates
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.
This commit is contained in:
parent
8e3ec9e57b
commit
0c7b4117ab
@ -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
|
||||
{
|
||||
@ -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 */
|
||||
|
12
rdp.c
12
rdp.c
@ -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
|
||||
@ -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)
|
||||
@ -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);
|
||||
@ -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);
|
||||
|
118
rdp5.c
118
rdp5.c
@ -25,10 +25,59 @@ 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;
|
||||
|
||||
@ -36,6 +85,8 @@ process_ts_fp_updates(STREAM s)
|
||||
struct stream *ns = &(g_mppc_dict.ns);
|
||||
struct stream *ts;
|
||||
|
||||
static STREAM assembled[0x0F] = { 0 };
|
||||
|
||||
ui_begin_update();
|
||||
while (s->p < s->end)
|
||||
{
|
||||
@ -73,46 +124,33 @@ process_ts_fp_updates(STREAM s)
|
||||
else
|
||||
ts = s;
|
||||
|
||||
switch (code)
|
||||
if (frag == FASTPATH_FRAGMENT_SINGLE)
|
||||
{
|
||||
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);
|
||||
process_ts_fp_update_by_code(ts, code);
|
||||
}
|
||||
else /* Fragmented packet, we must reassemble */
|
||||
{
|
||||
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;
|
||||
|
Loading…
Reference in New Issue
Block a user