mirror of https://github.com/FreeRDP/FreeRDP
libfreerdp-core: hook up mppc compressor to fastpath packets
This commit is contained in:
parent
bd55533220
commit
7ecd7c5fdb
|
@ -461,6 +461,16 @@ int add_mppc_enc_suite(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_random(int in_bytes)
|
||||||
|
{
|
||||||
|
int rv;
|
||||||
|
|
||||||
|
rv = rand() % in_bytes;
|
||||||
|
if (rv < 128)
|
||||||
|
rv = 128;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
#if DEBUG_MPPC_ENC_TEST
|
#if DEBUG_MPPC_ENC_TEST
|
||||||
#define DLOG(_args) printf _args
|
#define DLOG(_args) printf _args
|
||||||
#else
|
#else
|
||||||
|
@ -498,7 +508,9 @@ void test_mppc_enc(void)
|
||||||
rdp.mppc->history_ptr = rdp.mppc->history_buf;
|
rdp.mppc->history_ptr = rdp.mppc->history_buf;
|
||||||
|
|
||||||
/* setup encoder for RDP 5.0 */
|
/* setup encoder for RDP 5.0 */
|
||||||
CU_ASSERT((enc = rdp_mppc_enc_new(PROTO_RDP_50)) != NULL);
|
CU_ASSERT((enc = mppc_enc_new(PROTO_RDP_50)) != NULL);
|
||||||
|
|
||||||
|
srand(time(0));
|
||||||
|
|
||||||
/* open image file with pixel data */
|
/* open image file with pixel data */
|
||||||
fd = open("nature.bmp", O_RDONLY);
|
fd = open("nature.bmp", O_RDONLY);
|
||||||
|
@ -510,7 +522,7 @@ void test_mppc_enc(void)
|
||||||
gettimeofday(&start_time, NULL);
|
gettimeofday(&start_time, NULL);
|
||||||
|
|
||||||
/* compress block, decompress it then compare with original data */
|
/* compress block, decompress it then compare with original data */
|
||||||
while ((bytes_read = read(fd, buf, BUF_SIZE)) > 0)
|
while ((bytes_read = read(fd, buf, get_random(BUF_SIZE))) > 0)
|
||||||
{
|
{
|
||||||
block_num++;
|
block_num++;
|
||||||
total += bytes_read;
|
total += bytes_read;
|
||||||
|
@ -577,6 +589,6 @@ void test_mppc_enc(void)
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
rdp_mppc_enc_free(enc);
|
mppc_enc_free(enc);
|
||||||
free(rdp.mppc->history_buf);
|
free(rdp.mppc->history_buf);
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,8 +27,8 @@
|
||||||
#include "orders.h"
|
#include "orders.h"
|
||||||
#include "update.h"
|
#include "update.h"
|
||||||
#include "surface.h"
|
#include "surface.h"
|
||||||
|
|
||||||
#include "fastpath.h"
|
#include "fastpath.h"
|
||||||
|
#include "mppc_enc.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fast-Path packet format is defined in [MS-RDPBCGR] 2.2.9.1.2, which revises
|
* Fast-Path packet format is defined in [MS-RDPBCGR] 2.2.9.1.2, which revises
|
||||||
|
@ -605,12 +605,19 @@ STREAM* fastpath_update_pdu_init(rdpFastPath* fastpath)
|
||||||
|
|
||||||
boolean fastpath_send_update_pdu(rdpFastPath* fastpath, uint8 updateCode, STREAM* s)
|
boolean fastpath_send_update_pdu(rdpFastPath* fastpath, uint8 updateCode, STREAM* s)
|
||||||
{
|
{
|
||||||
rdpRdp *rdp;
|
rdpRdp* rdp;
|
||||||
uint8* bm;
|
uint8* bm;
|
||||||
uint8* ptr;
|
uint8* ptr_to_crypt;
|
||||||
|
uint8* ptr_sig;
|
||||||
int fragment;
|
int fragment;
|
||||||
int sec_bytes;
|
int sec_bytes;
|
||||||
uint16 length;
|
int try_comp;
|
||||||
|
int comp_flags;
|
||||||
|
int header_bytes;
|
||||||
|
int cflags;
|
||||||
|
int pdu_data_bytes;
|
||||||
|
int dlen;
|
||||||
|
int bytes_to_crypt;
|
||||||
boolean result;
|
boolean result;
|
||||||
uint16 pduLength;
|
uint16 pduLength;
|
||||||
uint16 maxLength;
|
uint16 maxLength;
|
||||||
|
@ -618,63 +625,107 @@ boolean fastpath_send_update_pdu(rdpFastPath* fastpath, uint8 updateCode, STREAM
|
||||||
uint8 fragmentation;
|
uint8 fragmentation;
|
||||||
uint8 header;
|
uint8 header;
|
||||||
STREAM* update;
|
STREAM* update;
|
||||||
|
STREAM* comp_update;
|
||||||
|
STREAM* ls;
|
||||||
|
|
||||||
result = true;
|
result = true;
|
||||||
|
|
||||||
rdp = fastpath->rdp;
|
rdp = fastpath->rdp;
|
||||||
sec_bytes = fastpath_get_sec_bytes(rdp);
|
sec_bytes = fastpath_get_sec_bytes(rdp);
|
||||||
maxLength = FASTPATH_MAX_PACKET_SIZE - 6 - sec_bytes;
|
maxLength = FASTPATH_MAX_PACKET_SIZE - 6 - sec_bytes;
|
||||||
totalLength = stream_get_length(s) - 6 - sec_bytes;
|
totalLength = stream_get_length(s) - 6 - sec_bytes;
|
||||||
stream_set_pos(s, 0);
|
stream_set_pos(s, 0);
|
||||||
update = stream_new(0);
|
update = stream_new(0);
|
||||||
|
try_comp = rdp->settings->compression;
|
||||||
|
comp_flags = 0;
|
||||||
|
comp_update = stream_new(0);
|
||||||
|
|
||||||
for (fragment = 0; totalLength > 0; fragment++)
|
for (fragment = 0; totalLength > 0; fragment++)
|
||||||
{
|
{
|
||||||
length = MIN(maxLength, totalLength);
|
ls = s;
|
||||||
totalLength -= length;
|
dlen = MIN(maxLength, totalLength);
|
||||||
pduLength = length + 6 + sec_bytes;
|
cflags = 0;
|
||||||
|
header_bytes = 6 + sec_bytes;
|
||||||
|
pdu_data_bytes = dlen;
|
||||||
|
if (try_comp)
|
||||||
|
{
|
||||||
|
if (compress_rdp(rdp->mppc_enc, ls->p + header_bytes, dlen))
|
||||||
|
{
|
||||||
|
if (rdp->mppc_enc->flags & PACKET_COMPRESSED)
|
||||||
|
{
|
||||||
|
cflags = rdp->mppc_enc->flags;
|
||||||
|
pdu_data_bytes = rdp->mppc_enc->bytes_in_opb;
|
||||||
|
comp_flags = FASTPATH_OUTPUT_COMPRESSION_USED;
|
||||||
|
header_bytes = 7 + sec_bytes;
|
||||||
|
bm = (uint8*) (rdp->mppc_enc->outputBuffer - header_bytes);
|
||||||
|
stream_attach(comp_update, bm, pdu_data_bytes + header_bytes);
|
||||||
|
ls = comp_update;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
printf("fastpath_send_update_pdu: mppc_encode failed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
totalLength -= dlen;
|
||||||
|
pduLength = pdu_data_bytes + header_bytes;
|
||||||
|
|
||||||
if (totalLength == 0)
|
if (totalLength == 0)
|
||||||
fragmentation = (fragment == 0) ? FASTPATH_FRAGMENT_SINGLE : FASTPATH_FRAGMENT_LAST;
|
fragmentation = (fragment == 0) ? FASTPATH_FRAGMENT_SINGLE : FASTPATH_FRAGMENT_LAST;
|
||||||
else
|
else
|
||||||
fragmentation = (fragment == 0) ? FASTPATH_FRAGMENT_FIRST : FASTPATH_FRAGMENT_NEXT;
|
fragmentation = (fragment == 0) ? FASTPATH_FRAGMENT_FIRST : FASTPATH_FRAGMENT_NEXT;
|
||||||
|
|
||||||
stream_get_mark(s, bm);
|
stream_get_mark(ls, bm);
|
||||||
header = 0;
|
header = 0;
|
||||||
if (sec_bytes > 0)
|
if (sec_bytes > 0)
|
||||||
header |= (FASTPATH_OUTPUT_ENCRYPTED << 6);
|
header |= (FASTPATH_OUTPUT_ENCRYPTED << 6);
|
||||||
stream_write_uint8(s, header); /* fpOutputHeader (1 byte) */
|
stream_write_uint8(ls, header); /* fpOutputHeader (1 byte) */
|
||||||
stream_write_uint8(s, 0x80 | (pduLength >> 8)); /* length1 */
|
stream_write_uint8(ls, 0x80 | (pduLength >> 8)); /* length1 */
|
||||||
stream_write_uint8(s, pduLength & 0xFF); /* length2 */
|
stream_write_uint8(ls, pduLength & 0xFF); /* length2 */
|
||||||
|
|
||||||
if (sec_bytes > 0)
|
if (sec_bytes > 0)
|
||||||
stream_seek(s, sec_bytes);
|
stream_seek(ls, sec_bytes);
|
||||||
fastpath_write_update_header(s, updateCode, fragmentation, 0);
|
|
||||||
stream_write_uint16(s, length);
|
fastpath_write_update_header(ls, updateCode, fragmentation, comp_flags);
|
||||||
|
|
||||||
|
/* extra byte if compressed */
|
||||||
|
if (ls == comp_update)
|
||||||
|
{
|
||||||
|
stream_write_uint8(ls, cflags);
|
||||||
|
bytes_to_crypt = pdu_data_bytes + 4;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bytes_to_crypt = pdu_data_bytes + 3;
|
||||||
|
|
||||||
|
stream_write_uint16(ls, pdu_data_bytes);
|
||||||
|
|
||||||
stream_attach(update, bm, pduLength);
|
stream_attach(update, bm, pduLength);
|
||||||
stream_seek(update, pduLength);
|
stream_seek(update, pduLength);
|
||||||
|
|
||||||
if (sec_bytes > 0)
|
if (sec_bytes > 0)
|
||||||
{
|
{
|
||||||
ptr = bm + 3 + sec_bytes;
|
/* does this work ? */
|
||||||
|
ptr_to_crypt = bm + 3 + sec_bytes;
|
||||||
|
ptr_sig = bm + 3;
|
||||||
if (rdp->sec_flags & SEC_SECURE_CHECKSUM)
|
if (rdp->sec_flags & SEC_SECURE_CHECKSUM)
|
||||||
security_salted_mac_signature(rdp, ptr, length + 3, true, bm + 3);
|
security_salted_mac_signature(rdp, ptr_to_crypt, bytes_to_crypt, true, ptr_sig);
|
||||||
else
|
else
|
||||||
security_mac_signature(rdp, ptr, length + 3, bm + 3);
|
security_mac_signature(rdp, ptr_to_crypt, bytes_to_crypt, ptr_sig);
|
||||||
security_encrypt(ptr, length + 3, rdp);
|
security_encrypt(ptr_to_crypt, bytes_to_crypt, rdp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (transport_write(fastpath->rdp->transport, update) < 0)
|
if (transport_write(fastpath->rdp->transport, update) < 0)
|
||||||
{
|
{
|
||||||
stream_detach(update);
|
|
||||||
result = false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
stream_detach(update);
|
|
||||||
|
|
||||||
/* Reserve 6+sec_bytes bytes for the next fragment header, if any. */
|
/* Reserve 6 + sec_bytes bytes for the next fragment header, if any. */
|
||||||
stream_seek(s, length - 6 - sec_bytes);
|
stream_seek(s, dlen - header_bytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stream_detach(update);
|
||||||
|
stream_detach(comp_update);
|
||||||
stream_free(update);
|
stream_free(update);
|
||||||
|
stream_free(comp_update);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -378,7 +378,7 @@ do \
|
||||||
* @return struct rdp_mppc_enc* or nil on failure
|
* @return struct rdp_mppc_enc* or nil on failure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct rdp_mppc_enc* rdp_mppc_enc_new(int protocol_type)
|
struct rdp_mppc_enc* mppc_enc_new(int protocol_type)
|
||||||
{
|
{
|
||||||
struct rdp_mppc_enc* enc;
|
struct rdp_mppc_enc* enc;
|
||||||
|
|
||||||
|
@ -423,7 +423,7 @@ struct rdp_mppc_enc* rdp_mppc_enc_new(int protocol_type)
|
||||||
* @param enc struct to be deinited
|
* @param enc struct to be deinited
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void rdp_mppc_enc_free(struct rdp_mppc_enc* enc)
|
void mppc_enc_free(struct rdp_mppc_enc* enc)
|
||||||
{
|
{
|
||||||
if (enc == NULL)
|
if (enc == NULL)
|
||||||
return;
|
return;
|
||||||
|
@ -506,6 +506,7 @@ boolean compress_rdp_5(struct rdp_mppc_enc* enc, uint8* srcData, int len)
|
||||||
uint32 x;
|
uint32 x;
|
||||||
uint8 data;
|
uint8 data;
|
||||||
uint16 data16;
|
uint16 data16;
|
||||||
|
uint32 historyOffset;
|
||||||
|
|
||||||
opb_index = 0;
|
opb_index = 0;
|
||||||
bits_left = 8;
|
bits_left = 8;
|
||||||
|
@ -527,9 +528,11 @@ boolean compress_rdp_5(struct rdp_mppc_enc* enc, uint8* srcData, int len)
|
||||||
enc->flagsHold |= PACKET_AT_FRONT;
|
enc->flagsHold |= PACKET_AT_FRONT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
historyOffset = enc->historyOffset;
|
||||||
|
|
||||||
/* add / append new data to historyBuffer */
|
/* add / append new data to historyBuffer */
|
||||||
memcpy(&enc->historyBuffer[enc->historyOffset], srcData, len);
|
memcpy(&(enc->historyBuffer[enc->historyOffset]), srcData, len);
|
||||||
historyPointer = &enc->historyBuffer[enc->historyOffset];
|
historyPointer = &(enc->historyBuffer[enc->historyOffset]);
|
||||||
|
|
||||||
/* if we are at start of history buffer, do not attempt to compress */
|
/* if we are at start of history buffer, do not attempt to compress */
|
||||||
/* first 2 bytes,because minimum LoM is 3 */
|
/* first 2 bytes,because minimum LoM is 3 */
|
||||||
|
@ -556,7 +559,7 @@ boolean compress_rdp_5(struct rdp_mppc_enc* enc, uint8* srcData, int len)
|
||||||
enc->historyOffset += len;
|
enc->historyOffset += len;
|
||||||
|
|
||||||
/* point to last byte in new data */
|
/* point to last byte in new data */
|
||||||
hptr_end = &enc->historyBuffer[enc->historyOffset - 1];
|
hptr_end = &(enc->historyBuffer[enc->historyOffset - 1]);
|
||||||
|
|
||||||
while (historyPointer <= hptr_end)
|
while (historyPointer <= hptr_end)
|
||||||
{
|
{
|
||||||
|
@ -566,292 +569,296 @@ boolean compress_rdp_5(struct rdp_mppc_enc* enc, uint8* srcData, int len)
|
||||||
cptr1 = hbuf_start;
|
cptr1 = hbuf_start;
|
||||||
lom = 0;
|
lom = 0;
|
||||||
saved_lom = 0;
|
saved_lom = 0;
|
||||||
keep_looking:
|
|
||||||
/* look for first byte match */
|
|
||||||
while ((cptr1 <= index_ptr) && (*cptr1 != *historyPointer))
|
|
||||||
{
|
|
||||||
cptr1++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cptr1 > index_ptr)
|
while (1)
|
||||||
{
|
{
|
||||||
/* no match found */
|
/* look for first byte match */
|
||||||
if (saved_lom)
|
while ((cptr1 <= index_ptr) && (*cptr1 != *historyPointer))
|
||||||
{
|
{
|
||||||
goto insert_tuple;
|
cptr1++;
|
||||||
}
|
}
|
||||||
goto insert_literal;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* got a one byte match - continue looking */
|
if (cptr1 > index_ptr)
|
||||||
lom = 1;
|
|
||||||
cptr1++;
|
|
||||||
cptr2 = cptr1;
|
|
||||||
cptr3 = historyPointer + 1;
|
|
||||||
while (*(cptr2++) == *(cptr3++))
|
|
||||||
{
|
|
||||||
lom++;
|
|
||||||
if (cptr3 > hptr_end)
|
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (lom < 3)
|
|
||||||
{
|
|
||||||
/* false alarm, keep looking */
|
|
||||||
lom = 0;
|
|
||||||
goto keep_looking;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we got a match */
|
/* got a one byte match - continue looking */
|
||||||
if (lom < saved_lom)
|
lom = 1;
|
||||||
{
|
cptr1++;
|
||||||
/* too small, ignore this match */
|
cptr2 = cptr1;
|
||||||
goto keep_looking;
|
cptr3 = historyPointer + 1;
|
||||||
}
|
while (*(cptr2++) == *(cptr3++))
|
||||||
else if (lom >= saved_lom)
|
|
||||||
{
|
|
||||||
/* this is a longer match, or a match closer to historyPointer */
|
|
||||||
saved_lom = lom;
|
|
||||||
copy_offset = (historyPointer - cptr1) + 1;
|
|
||||||
goto keep_looking;
|
|
||||||
}
|
|
||||||
insert_tuple:
|
|
||||||
DLOG(("<%d: %ld,%d> ", (int) (historyPointer - enc->historyBuffer),
|
|
||||||
(long) copy_offset, saved_lom));
|
|
||||||
lom = saved_lom;
|
|
||||||
historyPointer += lom;
|
|
||||||
|
|
||||||
/*
|
|
||||||
** encode copy_offset and insert into output buffer
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((copy_offset >= 0) && (copy_offset <= 63))
|
|
||||||
{
|
|
||||||
/* insert binary header */
|
|
||||||
data = 0x1f;
|
|
||||||
insert_5_bits(data);
|
|
||||||
|
|
||||||
/* insert 6 bits of copy_offset */
|
|
||||||
data = (char) (copy_offset & 0x3f);
|
|
||||||
insert_6_bits(data);
|
|
||||||
}
|
|
||||||
else if ((copy_offset >= 64) && (copy_offset <= 319))
|
|
||||||
{
|
|
||||||
/* insert binary header */
|
|
||||||
data = 0x1e;
|
|
||||||
insert_5_bits(data);
|
|
||||||
|
|
||||||
/* insert 8 bits of copy offset */
|
|
||||||
data = (char) (copy_offset - 64);
|
|
||||||
insert_8_bits(data);
|
|
||||||
}
|
|
||||||
else if ((copy_offset >= 320) && (copy_offset <= 2367))
|
|
||||||
{
|
|
||||||
/* insert binary header */
|
|
||||||
data = 0x0e;
|
|
||||||
insert_4_bits(data);
|
|
||||||
|
|
||||||
/* insert 11 bits of copy offset */
|
|
||||||
data16 = copy_offset - 320;;
|
|
||||||
insert_11_bits(data16);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* copy_offset is 2368+ */
|
|
||||||
|
|
||||||
/* insert binary header */
|
|
||||||
data = 0x06;
|
|
||||||
insert_3_bits(data);
|
|
||||||
|
|
||||||
/* insert 16 bits of copy offset */
|
|
||||||
data16 = copy_offset - 2368;;
|
|
||||||
insert_16_bits(data16);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
** encode length of match and insert into output buffer
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (lom == 3)
|
|
||||||
{
|
|
||||||
/* binary header is 'zero'; since outputBuffer is zero */
|
|
||||||
/* filled, all we have to do is update bits_left */
|
|
||||||
bits_left--;
|
|
||||||
if (bits_left == 0)
|
|
||||||
{
|
{
|
||||||
opb_index++;
|
lom++;
|
||||||
bits_left = 8;
|
if (cptr3 > hptr_end)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (lom < 3)
|
||||||
|
{
|
||||||
|
/* false alarm, keep looking */
|
||||||
|
lom = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (lom >= saved_lom)
|
||||||
|
{
|
||||||
|
/* this is a longer match, or a match closer to historyPointer */
|
||||||
|
saved_lom = lom;
|
||||||
|
copy_offset = (historyPointer - cptr1) + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((lom >= 4) && (lom <= 7))
|
|
||||||
{
|
|
||||||
/* insert binary header */
|
|
||||||
data = 0x02;
|
|
||||||
insert_2_bits(data);
|
|
||||||
|
|
||||||
/* insert lower 2 bits of LoM */
|
if (saved_lom)
|
||||||
data = (char) (lom - 4);
|
|
||||||
insert_2_bits(data);
|
|
||||||
}
|
|
||||||
else if ((lom >= 8) && (lom <= 15))
|
|
||||||
{
|
{
|
||||||
/* insert binary header */
|
/* insert_tuple */
|
||||||
data = 0x06;
|
|
||||||
insert_3_bits(data);
|
|
||||||
|
|
||||||
/* insert lower 3 bits of LoM */
|
DLOG(("<%d: %ld,%d> ", (int) (historyPointer - enc->historyBuffer),
|
||||||
data = (char) (lom - 8);
|
(long) copy_offset, saved_lom));
|
||||||
insert_3_bits(data);
|
lom = saved_lom;
|
||||||
}
|
historyPointer += lom;
|
||||||
else if ((lom >= 16) && (lom <= 31))
|
|
||||||
{
|
|
||||||
/* insert binary header */
|
|
||||||
data = 0x0e;
|
|
||||||
insert_4_bits(data);
|
|
||||||
|
|
||||||
/* insert lower 4 bits of LoM */
|
/*
|
||||||
data = (char) (lom - 16);
|
** encode copy_offset and insert into output buffer
|
||||||
insert_4_bits(data);
|
*/
|
||||||
}
|
|
||||||
else if ((lom >= 32) && (lom <= 63))
|
|
||||||
{
|
|
||||||
/* insert binary header */
|
|
||||||
data = 0x1e;
|
|
||||||
insert_5_bits(data);
|
|
||||||
|
|
||||||
/* insert lower 5 bits of LoM */
|
if ((copy_offset >= 0) && (copy_offset <= 63))
|
||||||
data = (char) (lom - 32);
|
{
|
||||||
insert_5_bits(data);
|
/* insert binary header */
|
||||||
}
|
data = 0x1f;
|
||||||
else if ((lom >= 64) && (lom <= 127))
|
insert_5_bits(data);
|
||||||
{
|
|
||||||
/* insert binary header */
|
|
||||||
data = 0x3e;
|
|
||||||
insert_6_bits(data);
|
|
||||||
|
|
||||||
/* insert lower 6 bits of LoM */
|
/* insert 6 bits of copy_offset */
|
||||||
data = (char) (lom - 64);
|
data = (char) (copy_offset & 0x3f);
|
||||||
insert_6_bits(data);
|
insert_6_bits(data);
|
||||||
}
|
}
|
||||||
else if ((lom >= 128) && (lom <= 255))
|
else if ((copy_offset >= 64) && (copy_offset <= 319))
|
||||||
{
|
{
|
||||||
/* insert binary header */
|
/* insert binary header */
|
||||||
data = 0x7e;
|
data = 0x1e;
|
||||||
insert_7_bits(data);
|
insert_5_bits(data);
|
||||||
|
|
||||||
/* insert lower 7 bits of LoM */
|
/* insert 8 bits of copy offset */
|
||||||
data = (char) (lom - 128);
|
data = (char) (copy_offset - 64);
|
||||||
insert_7_bits(data);
|
insert_8_bits(data);
|
||||||
}
|
}
|
||||||
else if ((lom >= 256) && (lom <= 511))
|
else if ((copy_offset >= 320) && (copy_offset <= 2367))
|
||||||
{
|
{
|
||||||
/* insert binary header */
|
/* insert binary header */
|
||||||
data = 0xfe;
|
data = 0x0e;
|
||||||
insert_8_bits(data);
|
insert_4_bits(data);
|
||||||
|
|
||||||
/* insert lower 8 bits of LoM */
|
/* insert 11 bits of copy offset */
|
||||||
data = (char) (lom - 256);
|
data16 = copy_offset - 320;;
|
||||||
insert_8_bits(data);
|
insert_11_bits(data16);
|
||||||
}
|
}
|
||||||
else if ((lom >= 512) && (lom <= 1023))
|
else
|
||||||
{
|
{
|
||||||
/* insert binary header */
|
/* copy_offset is 2368+ */
|
||||||
data16 = 0x1fe;
|
|
||||||
insert_9_bits(data16);
|
|
||||||
|
|
||||||
/* insert lower 9 bits of LoM */
|
/* insert binary header */
|
||||||
data16 = lom - 512;
|
data = 0x06;
|
||||||
insert_9_bits(data16);
|
insert_3_bits(data);
|
||||||
}
|
|
||||||
else if ((lom >= 1024) && (lom <= 2047))
|
|
||||||
{
|
|
||||||
/* insert binary header */
|
|
||||||
data16 = 0x3fe;
|
|
||||||
insert_10_bits(data16);
|
|
||||||
|
|
||||||
/* insert 10 lower bits of LoM */
|
/* insert 16 bits of copy offset */
|
||||||
data16 = lom - 1024;
|
data16 = copy_offset - 2368;;
|
||||||
insert_10_bits(data16);
|
insert_16_bits(data16);
|
||||||
}
|
}
|
||||||
else if ((lom >= 2048) && (lom <= 4095))
|
|
||||||
{
|
|
||||||
/* insert binary header */
|
|
||||||
data16 = 0x7fe;
|
|
||||||
insert_11_bits(data16);
|
|
||||||
|
|
||||||
/* insert 11 lower bits of LoM */
|
/*
|
||||||
data16 = lom - 2048;
|
** encode length of match and insert into output buffer
|
||||||
insert_11_bits(data16);
|
*/
|
||||||
}
|
|
||||||
else if ((lom >= 4096) && (lom <= 8191))
|
|
||||||
{
|
|
||||||
/* insert binary header */
|
|
||||||
data16 = 0xffe;
|
|
||||||
insert_12_bits(data16);
|
|
||||||
|
|
||||||
/* insert 12 lower bits of LoM */
|
if (lom == 3)
|
||||||
data16 = lom - 4096;
|
{
|
||||||
insert_12_bits(data16);
|
/* binary header is 'zero'; since outputBuffer is zero */
|
||||||
}
|
/* filled, all we have to do is update bits_left */
|
||||||
else if ((lom >= 8192) && (lom <= 16383))
|
bits_left--;
|
||||||
{
|
if (bits_left == 0)
|
||||||
/* insert binary header */
|
{
|
||||||
data16 = 0x1ffe;
|
opb_index++;
|
||||||
insert_13_bits(data16);
|
bits_left = 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ((lom >= 4) && (lom <= 7))
|
||||||
|
{
|
||||||
|
/* insert binary header */
|
||||||
|
data = 0x02;
|
||||||
|
insert_2_bits(data);
|
||||||
|
|
||||||
/* insert 13 lower bits of LoM */
|
/* insert lower 2 bits of LoM */
|
||||||
data16 = lom - 8192;
|
data = (char) (lom - 4);
|
||||||
insert_13_bits(data16);
|
insert_2_bits(data);
|
||||||
}
|
}
|
||||||
else if ((lom >= 16384) && (lom <= 32767))
|
else if ((lom >= 8) && (lom <= 15))
|
||||||
{
|
{
|
||||||
/* insert binary header */
|
/* insert binary header */
|
||||||
data16 = 0x3ffe;
|
data = 0x06;
|
||||||
insert_14_bits(data16);
|
insert_3_bits(data);
|
||||||
|
|
||||||
/* insert 14 lower bits of LoM */
|
/* insert lower 3 bits of LoM */
|
||||||
data16 = lom - 16384;
|
data = (char) (lom - 8);
|
||||||
insert_14_bits(data16);
|
insert_3_bits(data);
|
||||||
}
|
}
|
||||||
else if ((lom >= 32768) && (lom <= 65535))
|
else if ((lom >= 16) && (lom <= 31))
|
||||||
{
|
{
|
||||||
/* insert binary header */
|
/* insert binary header */
|
||||||
data16 = 0x7ffe;
|
data = 0x0e;
|
||||||
insert_15_bits(data16);
|
insert_4_bits(data);
|
||||||
|
|
||||||
/* insert 15 lower bits of LoM */
|
/* insert lower 4 bits of LoM */
|
||||||
data16 = lom - 32768;
|
data = (char) (lom - 16);
|
||||||
insert_15_bits(data16);
|
insert_4_bits(data);
|
||||||
}
|
}
|
||||||
goto check_len;
|
else if ((lom >= 32) && (lom <= 63))
|
||||||
insert_literal:
|
{
|
||||||
/* data not found in historyBuffer; encode and place data in output buffer */
|
/* insert binary header */
|
||||||
data = *(historyPointer++);
|
data = 0x1e;
|
||||||
DLOG(("%.2x ", (unsigned char) data));
|
insert_5_bits(data);
|
||||||
if (data & 0x80)
|
|
||||||
{
|
/* insert lower 5 bits of LoM */
|
||||||
/* insert encoded literal */
|
data = (char) (lom - 32);
|
||||||
insert_2_bits(0x02);
|
insert_5_bits(data);
|
||||||
data &= 0x7f;
|
}
|
||||||
insert_7_bits(data);
|
else if ((lom >= 64) && (lom <= 127))
|
||||||
|
{
|
||||||
|
/* insert binary header */
|
||||||
|
data = 0x3e;
|
||||||
|
insert_6_bits(data);
|
||||||
|
|
||||||
|
/* insert lower 6 bits of LoM */
|
||||||
|
data = (char) (lom - 64);
|
||||||
|
insert_6_bits(data);
|
||||||
|
}
|
||||||
|
else if ((lom >= 128) && (lom <= 255))
|
||||||
|
{
|
||||||
|
/* insert binary header */
|
||||||
|
data = 0x7e;
|
||||||
|
insert_7_bits(data);
|
||||||
|
|
||||||
|
/* insert lower 7 bits of LoM */
|
||||||
|
data = (char) (lom - 128);
|
||||||
|
insert_7_bits(data);
|
||||||
|
}
|
||||||
|
else if ((lom >= 256) && (lom <= 511))
|
||||||
|
{
|
||||||
|
/* insert binary header */
|
||||||
|
data = 0xfe;
|
||||||
|
insert_8_bits(data);
|
||||||
|
|
||||||
|
/* insert lower 8 bits of LoM */
|
||||||
|
data = (char) (lom - 256);
|
||||||
|
insert_8_bits(data);
|
||||||
|
}
|
||||||
|
else if ((lom >= 512) && (lom <= 1023))
|
||||||
|
{
|
||||||
|
/* insert binary header */
|
||||||
|
data16 = 0x1fe;
|
||||||
|
insert_9_bits(data16);
|
||||||
|
|
||||||
|
/* insert lower 9 bits of LoM */
|
||||||
|
data16 = lom - 512;
|
||||||
|
insert_9_bits(data16);
|
||||||
|
}
|
||||||
|
else if ((lom >= 1024) && (lom <= 2047))
|
||||||
|
{
|
||||||
|
/* insert binary header */
|
||||||
|
data16 = 0x3fe;
|
||||||
|
insert_10_bits(data16);
|
||||||
|
|
||||||
|
/* insert 10 lower bits of LoM */
|
||||||
|
data16 = lom - 1024;
|
||||||
|
insert_10_bits(data16);
|
||||||
|
}
|
||||||
|
else if ((lom >= 2048) && (lom <= 4095))
|
||||||
|
{
|
||||||
|
/* insert binary header */
|
||||||
|
data16 = 0x7fe;
|
||||||
|
insert_11_bits(data16);
|
||||||
|
|
||||||
|
/* insert 11 lower bits of LoM */
|
||||||
|
data16 = lom - 2048;
|
||||||
|
insert_11_bits(data16);
|
||||||
|
}
|
||||||
|
else if ((lom >= 4096) && (lom <= 8191))
|
||||||
|
{
|
||||||
|
/* insert binary header */
|
||||||
|
data16 = 0xffe;
|
||||||
|
insert_12_bits(data16);
|
||||||
|
|
||||||
|
/* insert 12 lower bits of LoM */
|
||||||
|
data16 = lom - 4096;
|
||||||
|
insert_12_bits(data16);
|
||||||
|
}
|
||||||
|
else if ((lom >= 8192) && (lom <= 16383))
|
||||||
|
{
|
||||||
|
/* insert binary header */
|
||||||
|
data16 = 0x1ffe;
|
||||||
|
insert_13_bits(data16);
|
||||||
|
|
||||||
|
/* insert 13 lower bits of LoM */
|
||||||
|
data16 = lom - 8192;
|
||||||
|
insert_13_bits(data16);
|
||||||
|
}
|
||||||
|
else if ((lom >= 16384) && (lom <= 32767))
|
||||||
|
{
|
||||||
|
/* insert binary header */
|
||||||
|
data16 = 0x3ffe;
|
||||||
|
insert_14_bits(data16);
|
||||||
|
|
||||||
|
/* insert 14 lower bits of LoM */
|
||||||
|
data16 = lom - 16384;
|
||||||
|
insert_14_bits(data16);
|
||||||
|
}
|
||||||
|
else if ((lom >= 32768) && (lom <= 65535))
|
||||||
|
{
|
||||||
|
/* insert binary header */
|
||||||
|
data16 = 0x7ffe;
|
||||||
|
insert_15_bits(data16);
|
||||||
|
|
||||||
|
/* insert 15 lower bits of LoM */
|
||||||
|
data16 = lom - 32768;
|
||||||
|
insert_15_bits(data16);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* insert literal */
|
/* insert_literal */
|
||||||
insert_8_bits(data);
|
|
||||||
|
/* data not found in historyBuffer; encode and place data in output buffer */
|
||||||
|
data = *(historyPointer++);
|
||||||
|
DLOG(("%.2x ", (unsigned char) data));
|
||||||
|
if (data & 0x80)
|
||||||
|
{
|
||||||
|
/* insert encoded literal */
|
||||||
|
insert_2_bits(0x02);
|
||||||
|
data &= 0x7f;
|
||||||
|
insert_7_bits(data);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* insert literal */
|
||||||
|
insert_8_bits(data);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
check_len:
|
|
||||||
/* if bits_left == 8, opb_index has already been incremented */
|
/* if bits_left == 8, opb_index has already been incremented */
|
||||||
if ((bits_left == 8) && (opb_index > len))
|
if ((bits_left == 8) && (opb_index > len))
|
||||||
{
|
{
|
||||||
/* compressed data longer than uncompressed data */
|
/* compressed data longer than uncompressed data */
|
||||||
goto give_up;
|
/* give up */
|
||||||
|
enc->historyOffset = historyOffset;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else if (opb_index + 1 > len)
|
else if (opb_index + 1 > len)
|
||||||
{
|
{
|
||||||
/* compressed data longer than uncompressed data */
|
/* compressed data longer than uncompressed data */
|
||||||
goto give_up;
|
/* give up */
|
||||||
|
enc->historyOffset = historyOffset;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
} /* end while (historyPointer < hptr_end) */
|
} /* end while (historyPointer < hptr_end) */
|
||||||
|
|
||||||
|
@ -863,7 +870,9 @@ check_len:
|
||||||
|
|
||||||
if (opb_index > len)
|
if (opb_index > len)
|
||||||
{
|
{
|
||||||
goto give_up;
|
/* give up */
|
||||||
|
enc->historyOffset = historyOffset;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
enc->flags |= PACKET_COMPRESSED;
|
enc->flags |= PACKET_COMPRESSED;
|
||||||
enc->bytes_in_opb = opb_index;
|
enc->bytes_in_opb = opb_index;
|
||||||
|
@ -871,16 +880,6 @@ check_len:
|
||||||
enc->flags |= enc->flagsHold;
|
enc->flags |= enc->flagsHold;
|
||||||
enc->flagsHold = 0;
|
enc->flagsHold = 0;
|
||||||
DLOG(("\n"));
|
DLOG(("\n"));
|
||||||
return true;
|
|
||||||
|
|
||||||
give_up:
|
return true;
|
||||||
|
|
||||||
enc->flagsHold |= PACKET_FLUSHED;
|
|
||||||
enc->bytes_in_opb = 0;
|
|
||||||
|
|
||||||
memset(enc->historyBuffer, 0, enc->buf_len);
|
|
||||||
memcpy(enc->historyBuffer, srcData, len);
|
|
||||||
enc->historyOffset = len;
|
|
||||||
DLOG(("\n"));
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,7 +44,7 @@ struct rdp_mppc_enc
|
||||||
boolean compress_rdp(struct rdp_mppc_enc* enc, uint8* srcData, int len);
|
boolean compress_rdp(struct rdp_mppc_enc* enc, uint8* srcData, int len);
|
||||||
boolean compress_rdp_4(struct rdp_mppc_enc* enc, uint8* srcData, int len);
|
boolean compress_rdp_4(struct rdp_mppc_enc* enc, uint8* srcData, int len);
|
||||||
boolean compress_rdp_5(struct rdp_mppc_enc* enc, uint8* srcData, int len);
|
boolean compress_rdp_5(struct rdp_mppc_enc* enc, uint8* srcData, int len);
|
||||||
struct rdp_mppc_enc* rdp_mppc_enc_new(int protocol_type);
|
struct rdp_mppc_enc* mppc_enc_new(int protocol_type);
|
||||||
void rdp_mppc_enc_free(struct rdp_mppc_enc* enc);
|
void mppc_enc_free(struct rdp_mppc_enc* enc);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
#include "info.h"
|
#include "info.h"
|
||||||
#include "redirection.h"
|
#include "redirection.h"
|
||||||
|
#include "mppc_enc.h"
|
||||||
|
|
||||||
#include <freerdp/crypto/per.h>
|
#include <freerdp/crypto/per.h>
|
||||||
|
|
||||||
|
@ -922,6 +923,7 @@ rdpRdp* rdp_new(freerdp* instance)
|
||||||
rdp->mcs = mcs_new(rdp->transport);
|
rdp->mcs = mcs_new(rdp->transport);
|
||||||
rdp->redirection = redirection_new();
|
rdp->redirection = redirection_new();
|
||||||
rdp->mppc = mppc_new(rdp);
|
rdp->mppc = mppc_new(rdp);
|
||||||
|
rdp->mppc_enc = mppc_enc_new(PROTO_RDP_50);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rdp;
|
return rdp;
|
||||||
|
@ -952,6 +954,7 @@ void rdp_free(rdpRdp* rdp)
|
||||||
mcs_free(rdp->mcs);
|
mcs_free(rdp->mcs);
|
||||||
redirection_free(rdp->redirection);
|
redirection_free(rdp->redirection);
|
||||||
mppc_free(rdp);
|
mppc_free(rdp);
|
||||||
|
mppc_enc_free(rdp->mppc_enc);
|
||||||
xfree(rdp);
|
xfree(rdp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,6 +135,7 @@ struct rdp_rdp
|
||||||
struct rdp_transport* transport;
|
struct rdp_transport* transport;
|
||||||
struct rdp_extension* extension;
|
struct rdp_extension* extension;
|
||||||
struct rdp_mppc* mppc;
|
struct rdp_mppc* mppc;
|
||||||
|
struct rdp_mppc_enc* mppc_enc;
|
||||||
struct crypto_rc4_struct* rc4_decrypt_key;
|
struct crypto_rc4_struct* rc4_decrypt_key;
|
||||||
int decrypt_use_count;
|
int decrypt_use_count;
|
||||||
int decrypt_checksum_use_count;
|
int decrypt_checksum_use_count;
|
||||||
|
|
Loading…
Reference in New Issue