2003-03-27 14:07:28 +01:00
|
|
|
/* -*- c-basic-offset: 8 -*-
|
|
|
|
rdesktop: A Remote Desktop Protocol client.
|
2017-10-13 13:45:07 +02:00
|
|
|
Protocol services - RDP Fast-Path PDU processing
|
2011-04-13 13:13:04 +02:00
|
|
|
Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
|
2011-09-28 11:36:59 +02:00
|
|
|
Copyright 2003-2008 Erik Forsberg <forsberg@cendio.se> for Cendio AB
|
2017-10-13 13:37:37 +02:00
|
|
|
Copyright 2017 Karl Mikaelsson <derfian@cendio.se> for Cendio AB
|
2004-06-16 05:08:55 +02:00
|
|
|
|
2010-01-12 09:31:06 +01:00
|
|
|
This program is free software: you can redistribute it and/or modify
|
2003-03-27 14:07:28 +01:00
|
|
|
it under the terms of the GNU General Public License as published by
|
2010-01-12 09:31:06 +01:00
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
2003-03-27 14:07:28 +01:00
|
|
|
(at your option) any later version.
|
2004-06-16 05:08:55 +02:00
|
|
|
|
2003-03-27 14:07:28 +01:00
|
|
|
This program is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
2004-06-16 05:08:55 +02:00
|
|
|
|
2003-03-27 14:07:28 +01:00
|
|
|
You should have received a copy of the GNU General Public License
|
2010-01-12 09:31:06 +01:00
|
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
2003-03-27 14:07:28 +01:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include "rdesktop.h"
|
|
|
|
|
2003-08-01 19:01:58 +02:00
|
|
|
extern uint8 *g_next_packet;
|
2003-03-27 14:07:28 +01:00
|
|
|
|
2004-04-30 08:18:08 +02:00
|
|
|
extern RDPCOMP g_mppc_dict;
|
|
|
|
|
2017-10-13 14:35:48 +02:00
|
|
|
|
|
|
|
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);
|
2019-04-04 14:58:15 +02:00
|
|
|
ui_move_pointer(x, y);
|
2017-10-13 14:35:48 +02:00
|
|
|
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:
|
2018-10-29 15:50:44 +01:00
|
|
|
logger(Protocol, Warning,
|
|
|
|
"process_ts_fp_updates_by_code(), unhandled opcode %d", code);
|
2017-10-13 14:35:48 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2003-03-27 14:07:28 +01:00
|
|
|
void
|
2017-10-13 13:45:07 +02:00
|
|
|
process_ts_fp_updates(STREAM s)
|
2003-03-27 14:07:28 +01:00
|
|
|
{
|
2017-10-13 14:35:48 +02:00
|
|
|
uint16 length;
|
2017-10-13 13:45:07 +02:00
|
|
|
uint8 hdr, code, frag, comp, ctype = 0;
|
2003-03-27 14:07:28 +01:00
|
|
|
uint8 *next;
|
|
|
|
|
2004-04-30 08:18:08 +02:00
|
|
|
uint32 roff, rlen;
|
|
|
|
struct stream *ns = &(g_mppc_dict.ns);
|
|
|
|
struct stream *ts;
|
|
|
|
|
2019-04-11 16:30:09 +02:00
|
|
|
static STREAM assembled[16] = { 0 };
|
2017-10-13 14:35:48 +02:00
|
|
|
|
2004-06-16 05:08:55 +02:00
|
|
|
ui_begin_update();
|
2003-03-27 14:07:28 +01:00
|
|
|
while (s->p < s->end)
|
|
|
|
{
|
2017-10-13 13:45:07 +02:00
|
|
|
/* Reading a number of TS_FP_UPDATE structures from the stream here.. */
|
|
|
|
in_uint8(s, hdr); /* updateHeader */
|
|
|
|
code = hdr & 0x0F; /* |- updateCode */
|
|
|
|
frag = hdr & 0x30; /* |- fragmentation */
|
|
|
|
comp = hdr & 0xC0; /* `- compression */
|
|
|
|
|
|
|
|
if (comp & FASTPATH_OUTPUT_COMPRESSION_USED)
|
|
|
|
in_uint8(s, ctype); /* compressionFlags */
|
|
|
|
|
|
|
|
in_uint16_le(s, length); /* length */
|
|
|
|
|
2003-08-01 19:01:58 +02:00
|
|
|
g_next_packet = next = s->p + length;
|
2003-03-27 14:07:28 +01:00
|
|
|
|
2004-04-30 08:18:08 +02:00
|
|
|
if (ctype & RDP_MPPC_COMPRESSED)
|
|
|
|
{
|
|
|
|
if (mppc_expand(s->p, length, ctype, &roff, &rlen) == -1)
|
2017-01-26 14:19:40 +01:00
|
|
|
logger(Protocol, Error,
|
2017-10-13 13:45:07 +02:00
|
|
|
"process_ts_fp_update_pdu(), error while decompressing packet");
|
2004-04-30 08:18:08 +02:00
|
|
|
|
|
|
|
/* allocate memory and copy the uncompressed data into the temporary stream */
|
2004-06-16 00:45:12 +02:00
|
|
|
ns->data = (uint8 *) xrealloc(ns->data, rlen);
|
2004-04-30 08:18:08 +02:00
|
|
|
|
|
|
|
memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
|
|
|
|
|
|
|
|
ns->size = rlen;
|
|
|
|
ns->end = (ns->data + ns->size);
|
|
|
|
ns->p = ns->data;
|
|
|
|
ns->rdp_hdr = ns->p;
|
|
|
|
|
2017-11-03 12:33:00 +01:00
|
|
|
length = rlen;
|
2004-04-30 08:18:08 +02:00
|
|
|
ts = ns;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ts = s;
|
|
|
|
|
2017-10-13 14:35:48 +02:00
|
|
|
if (frag == FASTPATH_FRAGMENT_SINGLE)
|
|
|
|
{
|
|
|
|
process_ts_fp_update_by_code(ts, code);
|
|
|
|
}
|
2018-10-29 15:50:44 +01:00
|
|
|
else /* Fragmented packet, we must reassemble */
|
2003-03-27 14:07:28 +01:00
|
|
|
{
|
2017-10-13 14:35:48 +02:00
|
|
|
if (assembled[code] == NULL)
|
|
|
|
{
|
|
|
|
assembled[code] = xmalloc(sizeof(struct stream));
|
|
|
|
memset(assembled[code], 0, sizeof(struct stream));
|
2018-10-29 15:50:44 +01:00
|
|
|
s_realloc(assembled[code],
|
|
|
|
RDESKTOP_FASTPATH_MULTIFRAGMENT_MAX_SIZE);
|
2017-10-13 14:35:48 +02:00
|
|
|
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);
|
|
|
|
}
|
2003-03-27 14:07:28 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
s->p = next;
|
|
|
|
}
|
2004-06-16 05:08:55 +02:00
|
|
|
ui_end_update();
|
2003-03-27 14:07:28 +01:00
|
|
|
}
|