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 FASTPATH_OUTPUT_COMPRESSION_USED (0x2 << 6)
|
||||||
|
|
||||||
|
#define RDESKTOP_FASTPATH_MULTIFRAGMENT_MAX_SIZE 32767
|
||||||
|
|
||||||
/* ISO PDU codes */
|
/* ISO PDU codes */
|
||||||
enum ISO_PDU_CODE
|
enum ISO_PDU_CODE
|
||||||
{
|
{
|
||||||
@ -378,6 +380,9 @@ enum RDP_INPUT_DEVICE
|
|||||||
#define RDP_CAPLEN_BMPCACHE2 0x28
|
#define RDP_CAPLEN_BMPCACHE2 0x28
|
||||||
#define BMPCACHE2_FLAG_PERSIST ((uint32)1<<31)
|
#define BMPCACHE2_FLAG_PERSIST ((uint32)1<<31)
|
||||||
|
|
||||||
|
#define RDP_CAPSET_MULTIFRAGMENTUPDATE 26
|
||||||
|
#define RDP_CAPLEN_MULTIFRAGMENTUPDATE 8
|
||||||
|
|
||||||
#define RDP_SOURCE "MSTSC"
|
#define RDP_SOURCE "MSTSC"
|
||||||
|
|
||||||
/* Logon flags */
|
/* 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 */
|
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
|
#define RDP5_FLAG 0x0030
|
||||||
/* Send a confirm active PDU */
|
/* Send a confirm active PDU */
|
||||||
static void
|
static void
|
||||||
@ -954,6 +962,7 @@ rdp_send_confirm_active(void)
|
|||||||
RDP_CAPLEN_FONT +
|
RDP_CAPLEN_FONT +
|
||||||
RDP_CAPLEN_SOUND +
|
RDP_CAPLEN_SOUND +
|
||||||
RDP_CAPLEN_GLYPHCACHE +
|
RDP_CAPLEN_GLYPHCACHE +
|
||||||
|
RDP_CAPLEN_MULTIFRAGMENTUPDATE +
|
||||||
4 /* w2k fix, sessionid */ ;
|
4 /* w2k fix, sessionid */ ;
|
||||||
|
|
||||||
if (g_rdp_version >= RDP_V5)
|
if (g_rdp_version >= RDP_V5)
|
||||||
@ -979,7 +988,7 @@ rdp_send_confirm_active(void)
|
|||||||
out_uint16_le(s, caplen);
|
out_uint16_le(s, caplen);
|
||||||
|
|
||||||
out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
|
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 */
|
out_uint8s(s, 2); /* pad */
|
||||||
|
|
||||||
rdp_out_ts_general_capabilityset(s);
|
rdp_out_ts_general_capabilityset(s);
|
||||||
@ -1005,6 +1014,7 @@ rdp_send_confirm_active(void)
|
|||||||
rdp_out_ts_sound_capabilityset(s);
|
rdp_out_ts_sound_capabilityset(s);
|
||||||
rdp_out_ts_font_capabilityset(s);
|
rdp_out_ts_font_capabilityset(s);
|
||||||
rdp_out_ts_glyphcache_capabilityset(s);
|
rdp_out_ts_glyphcache_capabilityset(s);
|
||||||
|
rdp_out_ts_multifragmentupdate_capabilityset(s);
|
||||||
|
|
||||||
s_mark_end(s);
|
s_mark_end(s);
|
||||||
sec_send(s, sec_flags);
|
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;
|
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
|
void
|
||||||
process_ts_fp_updates(STREAM s)
|
process_ts_fp_updates(STREAM s)
|
||||||
{
|
{
|
||||||
uint16 length, count, x, y;
|
uint16 length;
|
||||||
uint8 hdr, code, frag, comp, ctype = 0;
|
uint8 hdr, code, frag, comp, ctype = 0;
|
||||||
uint8 *next;
|
uint8 *next;
|
||||||
|
|
||||||
@ -36,6 +85,8 @@ process_ts_fp_updates(STREAM s)
|
|||||||
struct stream *ns = &(g_mppc_dict.ns);
|
struct stream *ns = &(g_mppc_dict.ns);
|
||||||
struct stream *ts;
|
struct stream *ts;
|
||||||
|
|
||||||
|
static STREAM assembled[0x0F] = { 0 };
|
||||||
|
|
||||||
ui_begin_update();
|
ui_begin_update();
|
||||||
while (s->p < s->end)
|
while (s->p < s->end)
|
||||||
{
|
{
|
||||||
@ -73,46 +124,33 @@ process_ts_fp_updates(STREAM s)
|
|||||||
else
|
else
|
||||||
ts = s;
|
ts = s;
|
||||||
|
|
||||||
switch (code)
|
if (frag == FASTPATH_FRAGMENT_SINGLE)
|
||||||
{
|
{
|
||||||
case FASTPATH_UPDATETYPE_ORDERS:
|
process_ts_fp_update_by_code(ts, code);
|
||||||
in_uint16_le(ts, count);
|
}
|
||||||
process_orders(ts, count);
|
else /* Fragmented packet, we must reassemble */
|
||||||
break;
|
{
|
||||||
case FASTPATH_UPDATETYPE_BITMAP:
|
if (assembled[code] == NULL)
|
||||||
in_uint8s(ts, 2); /* part length */
|
{
|
||||||
process_bitmap_updates(ts);
|
assembled[code] = xmalloc(sizeof(struct stream));
|
||||||
break;
|
memset(assembled[code], 0, sizeof(struct stream));
|
||||||
case FASTPATH_UPDATETYPE_PALETTE:
|
s_realloc(assembled[code], RDESKTOP_FASTPATH_MULTIFRAGMENT_MAX_SIZE);
|
||||||
in_uint8s(ts, 2); /* uint16 = 2 */
|
s_reset(assembled[code]);
|
||||||
process_palette(ts);
|
}
|
||||||
break;
|
|
||||||
case FASTPATH_UPDATETYPE_SYNCHRONIZE:
|
if (frag == FASTPATH_FRAGMENT_FIRST)
|
||||||
break;
|
{
|
||||||
case FASTPATH_UPDATETYPE_PTR_NULL:
|
s_reset(assembled[code]);
|
||||||
ui_set_null_cursor();
|
}
|
||||||
break;
|
|
||||||
case FASTPATH_UPDATETYPE_PTR_DEFAULT:
|
out_uint8p(assembled[code], ts->p, length);
|
||||||
set_system_pointer(SYSPTR_DEFAULT);
|
|
||||||
break;
|
if (frag == FASTPATH_FRAGMENT_LAST)
|
||||||
case FASTPATH_UPDATETYPE_PTR_POSITION:
|
{
|
||||||
in_uint16_le(ts, x);
|
s_mark_end(assembled[code]);
|
||||||
in_uint16_le(ts, y);
|
assembled[code]->p = assembled[code]->data;
|
||||||
if (s_check(ts))
|
process_ts_fp_update_by_code(assembled[code], code);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s->p = next;
|
s->p = next;
|
||||||
|
Loading…
Reference in New Issue
Block a user