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:
Peter Kallden 2004-04-30 06:18:08 +00:00
parent aa8d0a2e9f
commit ecdd66ff04
3 changed files with 75 additions and 39 deletions

22
mppc.c
View File

@ -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
View File

@ -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
View File

@ -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);