rdp5 decompression, but only <= 8-bit depth.
git-svn-id: svn://svn.code.sf.net/p/rdesktop/code/trunk/rdesktop@686 423420c4-83ab-492f-b58f-81f9feb106b5
This commit is contained in:
parent
aa8d0a2e9f
commit
ecdd66ff04
22
mppc.c
22
mppc.c
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "rdesktop.h"
|
#include "rdesktop.h"
|
||||||
|
|
||||||
/* mppc-like??? decompression */
|
/* mppc decompression */
|
||||||
/* http://www.faqs.org/rfcs/rfc2118.html */
|
/* http://www.faqs.org/rfcs/rfc2118.html */
|
||||||
|
|
||||||
/* TODO: research the below statements */
|
/* TODO: research the below statements */
|
||||||
@ -18,11 +18,15 @@
|
|||||||
/* already paying royalties */
|
/* already paying royalties */
|
||||||
/* through the CAL licenses? */
|
/* through the CAL licenses? */
|
||||||
|
|
||||||
/* the dictionary is empty when init. like */
|
/* as the rfc states the algorithm seems to */
|
||||||
/* LZ78, which is not patented */
|
/* be LZ77 with a sliding buffer */
|
||||||
|
/* that is empty at init. */
|
||||||
|
|
||||||
|
/* as of my limited knowledge these patents */
|
||||||
|
/* has expired. */
|
||||||
|
|
||||||
|
|
||||||
RDPCOMP mppc_dict;
|
RDPCOMP g_mppc_dict;
|
||||||
|
|
||||||
int
|
int
|
||||||
mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen)
|
mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen)
|
||||||
@ -33,7 +37,7 @@ mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen
|
|||||||
int match_len;
|
int match_len;
|
||||||
int old_offset, match_bits;
|
int old_offset, match_bits;
|
||||||
|
|
||||||
signed char *dict = &(mppc_dict.hist);
|
signed char *dict = &(g_mppc_dict.hist);
|
||||||
|
|
||||||
if ((ctype & RDP_MPPC_COMPRESSED) == 0)
|
if ((ctype & RDP_MPPC_COMPRESSED) == 0)
|
||||||
{
|
{
|
||||||
@ -44,19 +48,19 @@ mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen
|
|||||||
|
|
||||||
if ((ctype & RDP_MPPC_RESET) != 0)
|
if ((ctype & RDP_MPPC_RESET) != 0)
|
||||||
{
|
{
|
||||||
mppc_dict.roff = 0;
|
g_mppc_dict.roff = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ctype & RDP_MPPC_FLUSH) != 0)
|
if ((ctype & RDP_MPPC_FLUSH) != 0)
|
||||||
{
|
{
|
||||||
memset(dict, 0, RDP_MPPC_DICT_SIZE);
|
memset(dict, 0, RDP_MPPC_DICT_SIZE);
|
||||||
mppc_dict.roff = 0;
|
g_mppc_dict.roff = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
*roff = 0;
|
*roff = 0;
|
||||||
*rlen = 0;
|
*rlen = 0;
|
||||||
|
|
||||||
walker = mppc_dict.roff;
|
walker = g_mppc_dict.roff;
|
||||||
|
|
||||||
next_offset = walker;
|
next_offset = walker;
|
||||||
old_offset = next_offset;
|
old_offset = next_offset;
|
||||||
@ -267,7 +271,7 @@ mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen
|
|||||||
while (1);
|
while (1);
|
||||||
|
|
||||||
/* store history offset */
|
/* store history offset */
|
||||||
mppc_dict.roff = next_offset;
|
g_mppc_dict.roff = next_offset;
|
||||||
|
|
||||||
*roff = old_offset;
|
*roff = old_offset;
|
||||||
*rlen = next_offset - old_offset;
|
*rlen = next_offset - old_offset;
|
||||||
|
29
rdp.c
29
rdp.c
@ -38,7 +38,7 @@ extern BOOL g_bitmap_cache;
|
|||||||
uint8 *g_next_packet;
|
uint8 *g_next_packet;
|
||||||
uint32 g_rdp_shareid;
|
uint32 g_rdp_shareid;
|
||||||
|
|
||||||
extern RDPCOMP mppc_dict;
|
extern RDPCOMP g_mppc_dict;
|
||||||
|
|
||||||
#if WITH_DEBUG
|
#if WITH_DEBUG
|
||||||
static uint32 g_packetno;
|
static uint32 g_packetno;
|
||||||
@ -176,16 +176,16 @@ rdp_send_logon_info(uint32 flags, char *domain, char *user,
|
|||||||
time_t t = time(NULL);
|
time_t t = time(NULL);
|
||||||
time_t tzone;
|
time_t tzone;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* enable rdp compression */
|
||||||
|
/* some problems still exist with rdp5 */
|
||||||
|
flags |= RDP_COMPRESSION;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!g_use_rdp5 || 1 == g_server_rdp_version)
|
if (!g_use_rdp5 || 1 == g_server_rdp_version)
|
||||||
{
|
{
|
||||||
DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
|
DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* enable rdp compression */
|
|
||||||
/* decompression also works with rdp5 */
|
|
||||||
/* but there are some unknown opcodes */
|
|
||||||
flags |= RDP_COMPRESSION;
|
|
||||||
#endif
|
|
||||||
s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
|
s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
|
||||||
+ len_program + len_directory + 10);
|
+ len_program + len_directory + 10);
|
||||||
|
|
||||||
@ -962,8 +962,7 @@ process_data_pdu(STREAM s, uint32 * ext_disc_reason)
|
|||||||
|
|
||||||
uint32 roff, rlen;
|
uint32 roff, rlen;
|
||||||
|
|
||||||
struct stream *ns = &(mppc_dict.ns);
|
struct stream *ns = &(g_mppc_dict.ns);
|
||||||
uint8 *dict = (mppc_dict.hist);
|
|
||||||
|
|
||||||
in_uint8s(s, 6); /* shareid, pad, streamid */
|
in_uint8s(s, 6); /* shareid, pad, streamid */
|
||||||
in_uint16(s, len);
|
in_uint16(s, len);
|
||||||
@ -978,18 +977,14 @@ process_data_pdu(STREAM s, uint32 * ext_disc_reason)
|
|||||||
if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
|
if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
|
||||||
error("error while decompressing packet\n");
|
error("error while decompressing packet\n");
|
||||||
|
|
||||||
len -= 18;
|
//len -= 18;
|
||||||
|
|
||||||
/* this should never happen */
|
|
||||||
if (len != rlen)
|
|
||||||
error("decompression error len != rlen\n");
|
|
||||||
|
|
||||||
/* allocate memory and copy the uncompressed data into the temporary stream */
|
/* allocate memory and copy the uncompressed data into the temporary stream */
|
||||||
ns->data = xrealloc(ns->data, len);
|
ns->data = xrealloc(ns->data, rlen);
|
||||||
|
|
||||||
memcpy((ns->data), (unsigned char *) (mppc_dict.hist + roff), len);
|
memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
|
||||||
|
|
||||||
ns->size = len;
|
ns->size = rlen;
|
||||||
ns->end = (ns->data + ns->size);
|
ns->end = (ns->data + ns->size);
|
||||||
ns->p = ns->data;
|
ns->p = ns->data;
|
||||||
ns->rdp_hdr = ns->p;
|
ns->rdp_hdr = ns->p;
|
||||||
|
63
rdp5.c
63
rdp5.c
@ -23,13 +23,19 @@
|
|||||||
|
|
||||||
extern uint8 *g_next_packet;
|
extern uint8 *g_next_packet;
|
||||||
|
|
||||||
|
extern RDPCOMP g_mppc_dict;
|
||||||
|
|
||||||
void
|
void
|
||||||
rdp5_process(STREAM s, BOOL encryption)
|
rdp5_process(STREAM s, BOOL encryption)
|
||||||
{
|
{
|
||||||
uint16 length, count, x, y;
|
uint16 length, count, x, y;
|
||||||
uint8 type;
|
uint8 type, ctype;
|
||||||
uint8 *next;
|
uint8 *next;
|
||||||
|
|
||||||
|
uint32 roff, rlen;
|
||||||
|
struct stream *ns = &(g_mppc_dict.ns);
|
||||||
|
struct stream *ts;
|
||||||
|
|
||||||
if (encryption)
|
if (encryption)
|
||||||
{
|
{
|
||||||
in_uint8s(s, 8); /* signature */
|
in_uint8s(s, 8); /* signature */
|
||||||
@ -44,9 +50,40 @@ rdp5_process(STREAM s, BOOL encryption)
|
|||||||
while (s->p < s->end)
|
while (s->p < s->end)
|
||||||
{
|
{
|
||||||
in_uint8(s, type);
|
in_uint8(s, type);
|
||||||
in_uint16_le(s, length);
|
if (type & RDP_COMPRESSION)
|
||||||
|
{
|
||||||
|
in_uint8(s, ctype);
|
||||||
|
in_uint16_le(s, length);
|
||||||
|
type ^= RDP_COMPRESSION;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ctype = 0;
|
||||||
|
in_uint16_le(s, length);
|
||||||
|
}
|
||||||
g_next_packet = next = s->p + length;
|
g_next_packet = next = s->p + length;
|
||||||
|
|
||||||
|
if (ctype & RDP_MPPC_COMPRESSED)
|
||||||
|
{
|
||||||
|
|
||||||
|
if (mppc_expand(s->p, length, ctype, &roff, &rlen) == -1)
|
||||||
|
error("error while decompressing packet\n");
|
||||||
|
|
||||||
|
/* allocate memory and copy the uncompressed data into the temporary stream */
|
||||||
|
ns->data = xrealloc(ns->data, rlen);
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
ts = ns;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ts = s;
|
||||||
|
|
||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
/* Thanks to Jeroen Meijer <jdmeijer at yahoo
|
/* Thanks to Jeroen Meijer <jdmeijer at yahoo
|
||||||
@ -54,16 +91,16 @@ rdp5_process(STREAM s, BOOL encryption)
|
|||||||
most of the opcodes here. Especially opcode
|
most of the opcodes here. Especially opcode
|
||||||
8! :) */
|
8! :) */
|
||||||
case 0: /* orders */
|
case 0: /* orders */
|
||||||
in_uint16_le(s, count);
|
in_uint16_le(ts, count);
|
||||||
process_orders(s, count);
|
process_orders(ts, count);
|
||||||
break;
|
break;
|
||||||
case 1: /* bitmap update (???) */
|
case 1: /* bitmap update (???) */
|
||||||
in_uint8s(s, 2); /* part length */
|
in_uint8s(ts, 2); /* part length */
|
||||||
process_bitmap_updates(s);
|
process_bitmap_updates(ts);
|
||||||
break;
|
break;
|
||||||
case 2: /* palette */
|
case 2: /* palette */
|
||||||
in_uint8s(s, 2); /* uint16 = 2 */
|
in_uint8s(ts, 2); /* uint16 = 2 */
|
||||||
process_palette(s);
|
process_palette(ts);
|
||||||
break;
|
break;
|
||||||
case 3: /* probably an palette with offset 3. Weird */
|
case 3: /* probably an palette with offset 3. Weird */
|
||||||
break;
|
break;
|
||||||
@ -71,16 +108,16 @@ rdp5_process(STREAM s, BOOL encryption)
|
|||||||
ui_set_null_cursor();
|
ui_set_null_cursor();
|
||||||
break;
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
in_uint16_le(s, x);
|
in_uint16_le(ts, x);
|
||||||
in_uint16_le(s, y);
|
in_uint16_le(ts, y);
|
||||||
if (s_check(s))
|
if (s_check(ts))
|
||||||
ui_move_pointer(x, y);
|
ui_move_pointer(x, y);
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
process_colour_pointer_pdu(s);
|
process_colour_pointer_pdu(ts);
|
||||||
break;
|
break;
|
||||||
case 10:
|
case 10:
|
||||||
process_cached_pointer_pdu(s);
|
process_cached_pointer_pdu(ts);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
unimpl("RDP5 opcode %d\n", type);
|
unimpl("RDP5 opcode %d\n", type);
|
||||||
|
Loading…
Reference in New Issue
Block a user