2 * FreeRDP: A Remote Desktop Protocol Client
3 * Implements Microsoft Point to Point Compression (MPPC) protocol
5 * Copyright 2011 Laxmikant Rashinkar <LK.Rashinkar@gmail.com>
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
23 static uint8 HuffLengthLEC[] =
25 0x6, 0x6, 0x6, 0x6, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x8, 0x8, 0x8, 0x8,
26 0x8, 0x8, 0x8, 0x9, 0x8, 0x9, 0x9, 0x9, 0x9, 0x8, 0x8, 0x9, 0x9, 0x9, 0x9, 0x9,
27 0x8, 0x9, 0x9, 0xa, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0xa, 0x9, 0xa, 0xa, 0xa,
28 0x9, 0x9, 0x9, 0xa, 0x9, 0xa, 0xa, 0xa, 0x9, 0x9, 0xa, 0xa, 0x9, 0xa, 0x9, 0x9,
29 0x8, 0x9, 0x9, 0x9, 0x9, 0xa, 0xa, 0xa, 0x9, 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa,
30 0x9, 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa,
31 0x8, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa,
32 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0x9,
33 0x7, 0x9, 0x9, 0xa, 0x9, 0xa, 0xa, 0xa, 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa,
34 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa,
35 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xd, 0xa, 0xa, 0xa, 0xa,
36 0xa, 0xa, 0xb, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa,
37 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0x9, 0xa, 0xa, 0xa,
38 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa,
39 0x9, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0xa, 0x9, 0xa,
40 0x8, 0x9, 0x9, 0xa, 0x9, 0xa, 0xa, 0xa, 0x9, 0xa, 0xa, 0xa, 0x9, 0x9, 0x8, 0x7,
41 0xd, 0xd, 0x7, 0x7, 0xa, 0x7, 0x7, 0x6, 0x6, 0x6, 0x6, 0x5, 0x6, 0x6, 0x6, 0x5,
42 0x6, 0x5, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6, 0x6,
43 0x8, 0x5, 0x6, 0x7, 0x7
47 static uint16 HuffIndexLEC[512] =
49 0x007b, 0xff1f, 0xff0d, 0xfe27, 0xfe00, 0xff05, 0xff17, 0xfe68, 0x00c5, 0xfe07, 0xff13, 0xfec0, 0xff08, 0xfe18, 0xff1b, 0xfeb3,
50 0xfe03, 0x00a2, 0xfe42, 0xff10, 0xfe0b, 0xfe02, 0xfe91, 0xff19, 0xfe80, 0x00e9, 0xfe3a, 0xff15, 0xfe12, 0x0057, 0xfed7, 0xff1d,
51 0xff0e, 0xfe35, 0xfe69, 0xff22, 0xff18, 0xfe7a, 0xfe01, 0xff23, 0xff14, 0xfef4, 0xfeb4, 0xfe09, 0xff1c, 0xfec4, 0xff09, 0xfe60,
52 0xfe70, 0xff12, 0xfe05, 0xfe92, 0xfea1, 0xff1a, 0xfe0f, 0xff07, 0xfe56, 0xff16, 0xff02, 0xfed8, 0xfee8, 0xff1e, 0xfe1d, 0x003b,
53 0xffff, 0xff06, 0xffff, 0xfe71, 0xfe89, 0xffff, 0xffff, 0xfe2c, 0xfe2b, 0xfe20, 0xffff, 0xfebb, 0xfecf, 0xfe08, 0xffff, 0xfee0,
54 0xfe0d, 0xffff, 0xfe99, 0xffff, 0xfe04, 0xfeaa, 0xfe49, 0xffff, 0xfe17, 0xfe61, 0xfedf, 0xffff, 0xfeff, 0xfef6, 0xfe4c, 0xffff,
55 0xffff, 0xfe87, 0xffff, 0xff24, 0xffff, 0xfe3c, 0xfe72, 0xffff, 0xffff, 0xfece, 0xffff, 0xfefe, 0xffff, 0xfe23, 0xfebc, 0xfe0a,
56 0xfea9, 0xffff, 0xfe11, 0xffff, 0xfe82, 0xffff, 0xfe06, 0xfe9a, 0xfef5, 0xffff, 0xfe22, 0xfe4d, 0xfe5f, 0xffff, 0xff03, 0xfee1,
57 0xffff, 0xfeca, 0xfecc, 0xffff, 0xfe19, 0xffff, 0xfeb7, 0xffff, 0xffff, 0xfe83, 0xfe29, 0xffff, 0xffff, 0xffff, 0xfe6c, 0xffff,
58 0xfeed, 0xffff, 0xffff, 0xfe46, 0xfe5c, 0xfe15, 0xffff, 0xfedb, 0xfea6, 0xffff, 0xffff, 0xfe44, 0xffff, 0xfe0c, 0xffff, 0xfe95,
59 0xfefc, 0xffff, 0xffff, 0xfeb8, 0x16c9, 0xffff, 0xfef0, 0xffff, 0xfe38, 0xffff, 0xffff, 0xfe6d, 0xfe7e, 0xffff, 0xffff, 0xffff,
60 0xffff, 0xfe5b, 0xfedc, 0xffff, 0xffff, 0xfeec, 0xfe47, 0xfe1f, 0xffff, 0xfe7f, 0xfe96, 0xffff, 0xffff, 0xfea5, 0xffff, 0xfe10,
61 0xfe40, 0xfe32, 0xfebf, 0xffff, 0xffff, 0xfed4, 0xfef1, 0xffff, 0xffff, 0xffff, 0xfe75, 0xffff, 0xffff, 0xfe8d, 0xfe31, 0xffff,
62 0xfe65, 0xfe1b, 0xffff, 0xfee4, 0xfefb, 0xffff, 0xffff, 0xfe52, 0xffff, 0xfe0e, 0xffff, 0xfe9d, 0xfeaf, 0xffff, 0xffff, 0xfe51,
63 0xfed3, 0xffff, 0xff20, 0xffff, 0xfe2f, 0xffff, 0xffff, 0xfec1, 0xfe8c, 0xffff, 0xffff, 0xffff, 0xfe3f, 0xffff, 0xffff, 0xfe76,
64 0xffff, 0xfefa, 0xfe53, 0xfe25, 0xffff, 0xfe64, 0xfee5, 0xffff, 0xffff, 0xfeae, 0xffff, 0xfe13, 0xffff, 0xfe88, 0xfe9e, 0xffff,
65 0xfe43, 0xffff, 0xffff, 0xfea4, 0xfe93, 0xffff, 0xffff, 0xffff, 0xfe3d, 0xffff, 0xffff, 0xfeeb, 0xfed9, 0xffff, 0xfe14, 0xfe5a,
66 0xffff, 0xfe28, 0xfe7d, 0xffff, 0xffff, 0xfe6a, 0xffff, 0xffff, 0xff01, 0xfec6, 0xfec8, 0xffff, 0xffff, 0xfeb5, 0xffff, 0xffff,
67 0xffff, 0xfe94, 0xfe78, 0xffff, 0xffff, 0xffff, 0xfea3, 0xffff, 0xffff, 0xfeda, 0xfe58, 0xffff, 0xfe1e, 0xfe45, 0xfeea, 0xffff,
68 0xfe6b, 0xffff, 0xffff, 0xfe37, 0xffff, 0xffff, 0xffff, 0xfe7c, 0xfeb6, 0xffff, 0xffff, 0xfef8, 0xffff, 0xffff, 0xffff, 0xfec7,
69 0xfe9b, 0xffff, 0xffff, 0xffff, 0xfe50, 0xffff, 0xffff, 0xfead, 0xfee2, 0xffff, 0xfe1a, 0xfe63, 0xfe4e, 0xffff, 0xffff, 0xfef9,
70 0xffff, 0xfe73, 0xffff, 0xffff, 0xffff, 0xfe30, 0xfe8b, 0xffff, 0xffff, 0xfebd, 0xfe2e, 0x0100, 0xffff, 0xfeee, 0xfed2, 0xffff,
71 0xffff, 0xffff, 0xfeac, 0xffff, 0xffff, 0xfe9c, 0xfe84, 0xffff, 0xfe24, 0xfe4f, 0xfef7, 0xffff, 0xffff, 0xfee3, 0xfe62, 0xffff,
72 0xffff, 0xffff, 0xffff, 0xfe8a, 0xfe74, 0xffff, 0xffff, 0xfe3e, 0xffff, 0xffff, 0xffff, 0xfed1, 0xfebe, 0xffff, 0xffff, 0xfe2d,
73 0xffff, 0xfe4a, 0xfef3, 0xffff, 0xffff, 0xfedd, 0xfe5e, 0xfe16, 0xffff, 0xfe48, 0xfea8, 0xffff, 0xfeab, 0xfe97, 0xffff, 0xffff,
74 0xfed0, 0xffff, 0xffff, 0xfecd, 0xfeb9, 0xffff, 0xffff, 0xffff, 0xfe2a, 0xffff, 0xffff, 0xfe86, 0xfe6e, 0xffff, 0xffff, 0xffff,
75 0xfede, 0xffff, 0xffff, 0xfe5d, 0xfe4b, 0xfe21, 0xffff, 0xfeef, 0xfe98, 0xffff, 0xffff, 0xfe81, 0xffff, 0xffff, 0xffff, 0xfea7,
76 0xffff, 0xfeba, 0xfefd, 0xffff, 0xffff, 0xffff, 0xfecb, 0xffff, 0xffff, 0xfe6f, 0xfe39, 0xffff, 0xffff, 0xffff, 0xfe85, 0xffff,
77 0x010c, 0xfee6, 0xfe67, 0xfe1c, 0xffff, 0xfe54, 0xfeb2, 0xffff, 0xffff, 0xfe9f, 0xffff, 0xffff, 0xffff, 0xfe59, 0xfeb1, 0xffff,
78 0xfec2, 0xffff, 0xffff, 0xfe36, 0xfef2, 0xffff, 0xffff, 0xfed6, 0xfe77, 0xffff, 0xffff, 0xffff, 0xfe33, 0xffff, 0xffff, 0xfe8f,
79 0xfe55, 0xfe26, 0x010a, 0xff04, 0xfee7, 0xffff, 0x0121, 0xfe66, 0xffff, 0xffff, 0xffff, 0xfeb0, 0xfea0, 0xffff, 0x010f, 0xfe90,
80 0xffff, 0xffff, 0xfed5, 0xffff, 0xffff, 0xfec3, 0xfe34, 0xffff, 0xffff, 0xffff, 0xfe8e, 0xffff, 0x0111, 0xfe79, 0xfe41, 0x010b
83 static uint16 LECHTab[] =
85 511, 0, 508, 448, 494, 347, 486, 482
89 static uint8 HuffLenLOM[] =
91 0x4, 0x2, 0x3, 0x4, 0x3, 0x4, 0x4, 0x5, 0x4, 0x5, 0x5, 0x6, 0x6, 0x7, 0x7, 0x8,
92 0x7, 0x8, 0x8, 0x9, 0x9, 0x8, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9, 0x9
96 static uint16 HuffIndexLOM[] =
98 0x0fe1, 0x0fe0, 0x0fe2, 0x0fe8, 0x000e, 0x0fe5, 0x0fe4, 0x0fea, 0x0ff1, 0x0fe3, 0x0015, 0x0fe7, 0x0fef, 0x0046, 0x0ff0, 0x0fed,
99 0x0fff, 0x0ff7, 0x0ffb, 0x0019, 0x0ffd, 0x0ff4, 0x012c, 0x0feb, 0x0ffe, 0x0ff6, 0x0ffa, 0x0089, 0x0ffc, 0x0ff3, 0x0ff8, 0x0ff2
102 static uint8 LOMHTab[] =
108 static uint8 CopyOffsetBitsLUT[] =
110 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15
113 static uint32 CopyOffsetBaseLUT[] =
115 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537,
116 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577, 32769, 49153, 65537
119 static uint8 LoMBitsLUT[] =
121 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 6, 6, 8, 8, 14, 14
124 static uint16 LoMBaseLUT[] =
126 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18, 22, 26, 30,
127 34, 42, 50, 58, 66, 82, 98, 114, 130, 194, 258, 514, 2, 2
131 uint16 LEChash(uint16 key)
133 return ((key & 0x1ff) ^ (key >> 9) ^ (key >> 4) ^ (key >> 7));
136 uint16 LOMhash(uint16 key)
138 return ((key & 0x1f) ^ (key >> 5) ^ (key >> 9));
141 uint16 miniLEChash(uint16 key)
144 h = ((((key >> 8) ^ (key & 0xff)) >> 2) & 0xf);
150 uint8 miniLOMhash(uint16 key)
152 return ((key >> 4) ^ (key >> 6) ^ (key >> 7));
155 uint16 getLECindex(uint16 huff)
157 uint16 h = HuffIndexLEC[LEChash(huff)];
161 return HuffIndexLEC[LECHTab[miniLEChash(huff)]];
164 uint16 getLOMindex(uint16 huff)
166 uint16 h = HuffIndexLOM[LOMhash(huff)];
172 return HuffIndexLOM[LOMHTab[miniLOMhash(huff)]];
175 int decompress_rdp(rdpRdp* rdp, uint8* cbuf, int len, int ctype, uint32* roff, uint32* rlen)
177 int type = ctype & 0x0f;
181 case PACKET_COMPR_TYPE_8K:
182 return decompress_rdp_4(rdp, cbuf, len, ctype, roff, rlen);
185 case PACKET_COMPR_TYPE_64K:
186 return decompress_rdp_5(rdp, cbuf, len, ctype, roff, rlen);
189 case PACKET_COMPR_TYPE_RDP6:
190 return decompress_rdp_6(rdp, cbuf, len, ctype, roff, rlen);
193 case PACKET_COMPR_TYPE_RDP61:
194 return decompress_rdp_61(rdp, cbuf, len, ctype, roff, rlen);
198 printf("mppc.c: invalid RDP compression code 0x%2.2x\n", type);
204 * decompress RDP 4 data
206 * @param rdp per session information
207 * @param cbuf compressed data
208 * @param len length of compressed data
209 * @param ctype compression flags
210 * @param roff starting offset of uncompressed data
211 * @param rlen length of uncompressed data
213 * @return True on success, False on failure
216 int decompress_rdp_4(rdpRdp* rdp, uint8* cbuf, int len, int ctype, uint32* roff, uint32* rlen)
218 uint8* history_buf; /* uncompressed data goes here */
219 uint8* history_ptr; /* points to next free slot in history_buf */
220 uint32 d32; /* we process 4 compressed bytes at a time */
221 uint16 copy_offset; /* location to copy data from */
222 uint16 lom; /* length of match */
223 uint8* src_ptr; /* used while copying compressed data */
224 uint8* cptr; /* points to next byte in cbuf */
225 uint8 cur_byte; /* last byte fetched from cbuf */
226 int bits_left; /* bits left in d34 for processing */
227 int cur_bits_left; /* bits left in cur_byte for processing */
231 printf("decompress_rdp_4:\n");
233 if ((rdp->mppc == NULL) || (rdp->mppc->history_buf == NULL))
235 printf("decompress_rdp_4: null\n");
249 /* get start of history buffer */
250 history_buf = rdp->mppc->history_buf;
252 /* get next free slot in history buffer */
253 history_ptr = rdp->mppc->history_ptr;
254 *roff = history_ptr - history_buf;
256 if (ctype & PACKET_AT_FRONT)
258 /* place compressed data at start of history buffer */
259 history_ptr = rdp->mppc->history_buf;
260 rdp->mppc->history_ptr = rdp->mppc->history_buf;
264 if (ctype & PACKET_FLUSHED)
266 /* re-init history buffer */
267 history_ptr = rdp->mppc->history_buf;
268 memset(history_buf, 0, RDP6_HISTORY_BUF_SIZE);
272 if ((ctype & PACKET_COMPRESSED) != PACKET_COMPRESSED)
274 /* data in cbuf is not compressed - copy to history buf as is */
275 memcpy(history_ptr, cbuf, len);
277 *rlen = history_ptr - rdp->mppc->history_ptr;
278 rdp->mppc->history_ptr = history_ptr;
282 /* load initial data */
284 while (cptr < cbuf + len)
296 if (cptr < cbuf + len)
307 ** start uncompressing data in cbuf
310 while (bits_left >= 8)
313 value 0xxxxxxx = literal, not encoded
314 value 10xxxxxx = literal, encoded
315 value 1111xxxx = copy offset 0 - 63
316 value 1110xxxx = copy offset 64 - 319
317 value 110xxxxx = copy offset 320 - 8191
321 at this point, we are guaranteed that d32 has 32 bits to
322 be processed, unless we have reached end of cbuf
327 if ((d32 & 0x80000000) == 0)
330 *history_ptr++ = d32 >> 24;
334 else if ((d32 & 0xc0000000) == 0x80000000)
336 /* got encoded literal */
338 *history_ptr++ = (d32 >> 25) | 0x80;
342 else if ((d32 & 0xf0000000) == 0xf0000000)
344 /* got copy offset in range 0 - 63, */
345 /* with 6 bit copy offset */
347 copy_offset = d32 >> 26;
351 else if ((d32 & 0xf0000000) == 0xe0000000)
353 /* got copy offset in range 64 - 319, */
354 /* with 8 bit copy offset */
356 copy_offset = d32 >> 24;
361 else if ((d32 & 0xe0000000) == 0xc0000000)
363 /* got copy offset in range 320 - 8191, */
364 /* with 13 bits copy offset */
366 copy_offset = d32 >> 19;
373 ** get more bits before we process length of match
376 /* how may bits do we need to get? */
377 tmp = 32 - bits_left;
381 if (cur_bits_left < tmp)
383 /* we have less bits than we need */
384 i32 = cur_byte >> (8 - cur_bits_left);
385 d32 |= i32 << ((32 - bits_left) - cur_bits_left);
386 bits_left += cur_bits_left;
387 tmp -= cur_bits_left;
388 if (cptr < cbuf + len)
390 /* more compressed data available */
396 /* no more compressed data available */
401 else if (cur_bits_left > tmp)
403 /* we have more bits than we need */
404 d32 |= cur_byte >> (8 - tmp);
406 cur_bits_left -= tmp;
412 /* we have just the right amount of bits */
413 d32 |= cur_byte >> (8 - tmp);
415 if (cptr < cbuf + len)
434 ** compute Length of Match
438 lengh of match Encoding (binary header + LoM bits
439 -------------- ----------------------------------
441 4...7 10 + 2 lower bits of L-o-M
442 8...15 110 + 3 lower bits of L-o-M
443 16...31 1110 + 4 lower bits of L-o-M
444 32...63 11110 + 5 lower bits of L-o-M
445 64...127 111110 + 6 lower bits of L-o-M
446 128...255 1111110 + 7 lower bits of L-o-M
447 256...511 11111110 + 8 lower bits of L-o-M
448 512...1023 111111110 + 9 lower bits of L-o-M
449 1024...2047 1111111110 + 10 lower bits of L-o-M
450 2048...4095 11111111110 + 11 lower bits of L-o-M
451 4096...8191 111111111110 + 12 lower bits of L-o-M
454 if ((d32 & 0x80000000) == 0)
456 /* lom is fixed to 3 */
461 else if ((d32 & 0xc0000000) == 0x80000000)
463 /* 2 lower bits of LoM */
464 lom = ((d32 >> 28) & 0x03) + 4;
468 else if ((d32 & 0xe0000000) == 0xc0000000)
470 /* 3 lower bits of LoM */
471 lom = ((d32 >> 26) & 0x07) + 8;
475 else if ((d32 & 0xf0000000) == 0xe0000000)
477 /* 4 lower bits of LoM */
478 lom = ((d32 >> 24) & 0x0f) + 16;
482 else if ((d32 & 0xf8000000) == 0xf0000000)
484 /* 5 lower bits of LoM */
485 lom = ((d32 >> 22) & 0x1f) + 32;
489 else if ((d32 & 0xfc000000) == 0xf8000000)
491 /* 6 lower bits of LoM */
492 lom = ((d32 >> 20) & 0x3f) + 64;
496 else if ((d32 & 0xfe000000) == 0xfc000000)
498 /* 7 lower bits of LoM */
499 lom = ((d32 >> 18) & 0x7f) + 128;
503 else if ((d32 & 0xff000000) == 0xfe000000)
505 /* 8 lower bits of LoM */
506 lom = ((d32 >> 16) & 0xff) + 256;
510 else if ((d32 & 0xff800000) == 0xff000000)
512 /* 9 lower bits of LoM */
513 lom = ((d32 >> 14) & 0x1ff) + 512;
517 else if ((d32 & 0xffc00000) == 0xff800000)
519 /* 10 lower bits of LoM */
520 lom = ((d32 >> 12) & 0x3ff) + 1024;
524 else if ((d32 & 0xffe00000) == 0xffc00000)
526 /* 11 lower bits of LoM */
527 lom = ((d32 >> 10) & 0x7ff) + 2048;
531 else if ((d32 & 0xfff00000) == 0xffe00000)
533 /* 12 lower bits of LoM */
534 lom = ((d32 >> 8) & 0xfff) + 4096;
539 /* now that we have copy_offset and LoM, process them */
541 src_ptr = history_ptr - copy_offset;
542 if (src_ptr >= rdp->mppc->history_buf)
544 /* data does not wrap around */
547 *history_ptr++ = *src_ptr++;
553 src_ptr = rdp->mppc->history_buf_end - (copy_offset - (history_ptr - rdp->mppc->history_buf));
555 while (lom && (src_ptr <= rdp->mppc->history_buf_end))
557 *history_ptr++ = *src_ptr++;
561 src_ptr = rdp->mppc->history_buf;
564 *history_ptr++ = *src_ptr++;
570 ** get more bits before we restart the loop
573 /* how may bits do we need to get? */
574 tmp = 32 - bits_left;
578 if (cur_bits_left < tmp)
580 /* we have less bits than we need */
581 i32 = cur_byte >> (8 - cur_bits_left);
582 d32 |= i32 << ((32 - bits_left) - cur_bits_left);
583 bits_left += cur_bits_left;
584 tmp -= cur_bits_left;
585 if (cptr < cbuf + len)
587 /* more compressed data available */
593 /* no more compressed data available */
598 else if (cur_bits_left > tmp)
600 /* we have more bits than we need */
601 d32 |= cur_byte >> (8 - tmp);
603 cur_bits_left -= tmp;
609 /* we have just the right amount of bits */
610 d32 |= cur_byte >> (8 - tmp);
612 if (cptr < cbuf + len)
624 } /* end while (bits_left >= 8) */
626 *rlen = history_ptr - rdp->mppc->history_ptr;
628 rdp->mppc->history_ptr = history_ptr;
634 * decompress RDP 5 data
636 * @param rdp per session information
637 * @param cbuf compressed data
638 * @param len length of compressed data
639 * @param ctype compression flags
640 * @param roff starting offset of uncompressed data
641 * @param rlen length of uncompressed data
643 * @return True on success, False on failure
646 int decompress_rdp_5(rdpRdp* rdp, uint8* cbuf, int len, int ctype, uint32* roff, uint32* rlen)
648 uint8* history_buf; /* uncompressed data goes here */
649 uint8* history_ptr; /* points to next free slot in bistory_buf */
650 uint32 d32; /* we process 4 compressed bytes at a time */
651 uint16 copy_offset; /* location to copy data from */
652 uint16 lom; /* length of match */
653 uint8* src_ptr; /* used while copying compressed data */
654 uint8* cptr; /* points to next byte in cbuf */
655 uint8 cur_byte; /* last byte fetched from cbuf */
656 int bits_left; /* bits left in d32 for processing */
657 int cur_bits_left; /* bits left in cur_byte for processing */
661 if ((rdp->mppc == NULL) || (rdp->mppc->history_buf == NULL))
663 printf("decompress_rdp_5: null\n");
677 /* get start of history buffer */
678 history_buf = rdp->mppc->history_buf;
680 /* get next free slot in history buffer */
681 history_ptr = rdp->mppc->history_ptr;
682 *roff = history_ptr - history_buf;
684 if (ctype & PACKET_AT_FRONT)
686 /* place compressed data at start of history buffer */
687 history_ptr = rdp->mppc->history_buf;
688 rdp->mppc->history_ptr = rdp->mppc->history_buf;
692 if (ctype & PACKET_FLUSHED)
694 /* re-init history buffer */
695 history_ptr = rdp->mppc->history_buf;
696 memset(history_buf, 0, RDP6_HISTORY_BUF_SIZE);
700 if ((ctype & PACKET_COMPRESSED) != PACKET_COMPRESSED)
702 /* data in cbuf is not compressed - copy to history buf as is */
703 memcpy(history_ptr, cbuf, len);
705 *rlen = history_ptr - rdp->mppc->history_ptr;
706 rdp->mppc->history_ptr = history_ptr;
710 /* load initial data */
712 while (cptr < cbuf + len)
724 if (cptr < cbuf + len)
735 ** start uncompressing data in cbuf
738 while (bits_left >= 8)
741 value 0xxxxxxx = literal, not encoded
742 value 10xxxxxx = literal, encoded
743 value 11111xxx = copy offset 0 - 63
744 value 11110xxx = copy offset 64 - 319
745 value 1110xxxx = copy offset 320 - 2367
746 value 110xxxxx = copy offset 2368+
750 at this point, we are guaranteed that d32 has 32 bits to
751 be processed, unless we have reached end of cbuf
756 if ((d32 & 0x80000000) == 0)
759 *history_ptr++ = d32 >> 24;
763 else if ((d32 & 0xc0000000) == 0x80000000)
765 /* got encoded literal */
767 *history_ptr++ = (d32 >> 25) | 0x80;
771 else if ((d32 & 0xf8000000) == 0xf8000000)
773 /* got copy offset in range 0 - 63, */
774 /* with 6 bit copy offset */
776 copy_offset = d32 >> 26;
780 else if ((d32 & 0xf8000000) == 0xf0000000)
782 /* got copy offset in range 64 - 319, */
783 /* with 8 bit copy offset */
785 copy_offset = d32 >> 24;
790 else if ((d32 & 0xf0000000) == 0xe0000000)
792 /* got copy offset in range 320 - 2367, */
793 /* with 11 bits copy offset */
795 copy_offset = d32 >> 21;
800 else if ((d32 & 0xe0000000) == 0xc0000000)
802 /* got copy offset in range 2368+, */
803 /* with 16 bits copy offset */
805 copy_offset = d32 >> 16;
812 ** get more bits before we process length of match
815 /* how may bits do we need to get? */
816 tmp = 32 - bits_left;
820 if (cur_bits_left < tmp)
822 /* we have less bits than we need */
823 i32 = cur_byte >> (8 - cur_bits_left);
824 d32 |= i32 << ((32 - bits_left) - cur_bits_left);
825 bits_left += cur_bits_left;
826 tmp -= cur_bits_left;
827 if (cptr < cbuf + len)
829 /* more compressed data available */
835 /* no more compressed data available */
840 else if (cur_bits_left > tmp)
842 /* we have more bits than we need */
843 d32 |= cur_byte >> (8 - tmp);
845 cur_bits_left -= tmp;
851 /* we have just the right amount of bits */
852 d32 |= cur_byte >> (8 - tmp);
854 if (cptr < cbuf + len)
873 ** compute Length of Match
877 lengh of match Encoding (binary header + LoM bits
878 -------------- ----------------------------------
880 4..7 10 + 2 lower bits of LoM
881 8..15 110 + 3 lower bits of LoM
882 16..31 1110 + 4 lower bits of LoM
883 32..63 1111-0 + 5 lower bits of LoM
884 64..127 1111-10 + 6 lower bits of LoM
885 128..255 1111-110 + 7 lower bits of LoM
886 256..511 1111-1110 + 8 lower bits of LoM
887 512..1023 1111-1111-0 + 9 lower bits of LoM
888 1024..2047 1111-1111-10 + 10 lower bits of LoM
889 2048..4095 1111-1111-110 + 11 lower bits of LoM
890 4096..8191 1111-1111-1110 + 12 lower bits of LoM
891 8192..16383 1111-1111-1111-0 + 13 lower bits of LoM
892 16384..32767 1111-1111-1111-10 + 14 lower bits of LoM
893 32768..65535 1111-1111-1111-110 + 15 lower bits of LoM
896 if ((d32 & 0x80000000) == 0)
898 /* lom is fixed to 3 */
903 else if ((d32 & 0xc0000000) == 0x80000000)
905 /* 2 lower bits of LoM */
906 lom = ((d32 >> 28) & 0x03) + 4;
910 else if ((d32 & 0xe0000000) == 0xc0000000)
912 /* 3 lower bits of LoM */
913 lom = ((d32 >> 26) & 0x07) + 8;
917 else if ((d32 & 0xf0000000) == 0xe0000000)
919 /* 4 lower bits of LoM */
920 lom = ((d32 >> 24) & 0x0f) + 16;
924 else if ((d32 & 0xf8000000) == 0xf0000000)
926 /* 5 lower bits of LoM */
927 lom = ((d32 >> 22) & 0x1f) + 32;
931 else if ((d32 & 0xfc000000) == 0xf8000000)
933 /* 6 lower bits of LoM */
934 lom = ((d32 >> 20) & 0x3f) + 64;
938 else if ((d32 & 0xfe000000) == 0xfc000000)
940 /* 7 lower bits of LoM */
941 lom = ((d32 >> 18) & 0x7f) + 128;
945 else if ((d32 & 0xff000000) == 0xfe000000)
947 /* 8 lower bits of LoM */
948 lom = ((d32 >> 16) & 0xff) + 256;
952 else if ((d32 & 0xff800000) == 0xff000000)
954 /* 9 lower bits of LoM */
955 lom = ((d32 >> 14) & 0x1ff) + 512;
959 else if ((d32 & 0xffc00000) == 0xff800000)
961 /* 10 lower bits of LoM */
962 lom = ((d32 >> 12) & 0x3ff) + 1024;
966 else if ((d32 & 0xffe00000) == 0xffc00000)
968 /* 11 lower bits of LoM */
969 lom = ((d32 >> 10) & 0x7ff) + 2048;
973 else if ((d32 & 0xfff00000) == 0xffe00000)
975 /* 12 lower bits of LoM */
976 lom = ((d32 >> 8) & 0xfff) + 4096;
980 else if ((d32 & 0xfff80000) == 0xfff00000)
982 /* 13 lower bits of LoM */
983 lom = ((d32 >> 6) & 0x1fff) + 8192;
987 else if ((d32 & 0xfffc0000) == 0xfff80000)
989 /* 14 lower bits of LoM */
990 lom = ((d32 >> 4) & 0x3fff) + 16384;
994 else if ((d32 & 0xfffe0000) == 0xfffc0000)
996 /* 15 lower bits of LoM */
997 lom = ((d32 >> 2) & 0x7fff) + 32768;
1002 /* now that we have copy_offset and LoM, process them */
1004 src_ptr = history_ptr - copy_offset;
1005 if (src_ptr >= rdp->mppc->history_buf)
1007 /* data does not wrap around */
1010 *history_ptr++ = *src_ptr++;
1016 src_ptr = rdp->mppc->history_buf_end - (copy_offset - (history_ptr - rdp->mppc->history_buf));
1018 while (lom && (src_ptr <= rdp->mppc->history_buf_end))
1020 *history_ptr++ = *src_ptr++;
1024 src_ptr = rdp->mppc->history_buf;
1027 *history_ptr++ = *src_ptr++;
1033 ** get more bits before we restart the loop
1036 /* how may bits do we need to get? */
1037 tmp = 32 - bits_left;
1041 if (cur_bits_left < tmp)
1043 /* we have less bits than we need */
1044 i32 = cur_byte >> (8 - cur_bits_left);
1045 d32 |= i32 << ((32 - bits_left) - cur_bits_left);
1046 bits_left += cur_bits_left;
1047 tmp -= cur_bits_left;
1048 if (cptr < cbuf + len)
1050 /* more compressed data available */
1056 /* no more compressed data available */
1061 else if (cur_bits_left > tmp)
1063 /* we have more bits than we need */
1064 d32 |= cur_byte >> (8 - tmp);
1066 cur_bits_left -= tmp;
1072 /* we have just the right amount of bits */
1073 d32 |= cur_byte >> (8 - tmp);
1075 if (cptr < cbuf + len)
1088 } /* end while (cptr < cbuf + len) */
1090 *rlen = history_ptr - rdp->mppc->history_ptr;
1092 rdp->mppc->history_ptr = history_ptr;
1098 * decompress RDP 6 data
1100 * @param rdp per session information
1101 * @param cbuf compressed data
1102 * @param len length of compressed data
1103 * @param ctype compression flags
1104 * @param roff starting offset of uncompressed data
1105 * @param rlen length of uncompressed data
1107 * @return True on success, False on failure
1110 int decompress_rdp_6(rdpRdp* rdp, uint8* cbuf, int len, int ctype, uint32* roff, uint32* rlen)
1112 uint8* history_buf; /* uncompressed data goes here */
1113 uint16* offset_cache; /* Copy Offset cache */
1114 uint8* history_ptr; /* points to next free slot in bistory_buf */
1115 uint32 d32; /* we process 4 compressed bytes at a time */
1116 uint16 copy_offset; /* location to copy data from */
1117 uint16 lom; /* length of match */
1118 uint8* src_ptr; /* used while copying compressed data */
1119 uint8* cptr; /* points to next byte in cbuf */
1120 uint8 cur_byte; /* last byte fetched from cbuf */
1121 int bits_left; /* bits left in d32 for processing */
1122 int cur_bits_left; /* bits left in cur_byte for processing */
1126 if ((rdp->mppc == NULL) || (rdp->mppc->history_buf == NULL))
1128 printf("decompress_rdp_6: null\n");
1142 /* get start of history buffer */
1143 history_buf = rdp->mppc->history_buf;
1145 /* get start of offset_cache */
1146 offset_cache = rdp->mppc->offset_cache;
1148 /* get next free slot in history buffer */
1149 history_ptr = rdp->mppc->history_ptr;
1150 *roff = history_ptr - history_buf;
1152 if (ctype & PACKET_AT_FRONT)
1154 printf("need to look later\n");
1155 /* slid history_buf and reset history_buf to middle */
1156 memcpy(history_buf, (history_buf + 32768), (history_ptr -history_buf - 32768));
1157 memcpy((history_buf + (history_ptr - history_buf - 32768)), cbuf, len);
1158 history_ptr = history_buf + 32768;
1162 if (ctype & PACKET_FLUSHED)
1164 /* re-init history buffer */
1165 history_ptr = rdp->mppc->history_buf;
1166 memset(history_buf, 0, RDP6_HISTORY_BUF_SIZE);
1167 memset(offset_cache, 0, RDP6_OFFSET_CACHE_SIZE);
1171 if ((ctype & PACKET_COMPRESSED) != PACKET_COMPRESSED)
1173 /* data in cbuf is not compressed - copy to history buf as is */
1174 memcpy(history_ptr, cbuf, len);
1176 *rlen = history_ptr - rdp->mppc->history_ptr;
1177 rdp->mppc->history_ptr = history_ptr;
1181 /* load initial data */
1183 while (cptr < cbuf + len)
1195 if (cptr < cbuf + len)
1206 ** start uncompressing data in cbuf
1214 * decompress RDP 6.1 data
1216 * @param rdp per session information
1217 * @param cbuf compressed data
1218 * @param len length of compressed data
1219 * @param ctype compression flags
1220 * @param roff starting offset of uncompressed data
1221 * @param rlen length of uncompressed data
1223 * @return True on success, False on failure
1226 int decompress_rdp_61(rdpRdp* rdp, uint8* cbuf, int len, int ctype, uint32* roff, uint32* rlen)
1232 * allocate space to store history buffer
1234 * @param rdp rdp struct that contains rdp_mppc struct
1235 * @return pointer to new struct, or NULL on failure
1238 struct rdp_mppc* mppc_new(rdpRdp* rdp)
1240 struct rdp_mppc* ptr;
1242 ptr = (struct rdp_mppc*) xmalloc(sizeof(struct rdp_mppc));
1246 printf("mppc_new(): system out of memory\n");
1250 ptr->history_buf = (uint8*) xmalloc(RDP6_HISTORY_BUF_SIZE);
1251 ptr->offset_cache = (uint16*) xzalloc(RDP6_OFFSET_CACHE_SIZE);
1253 if (!ptr->history_buf)
1255 printf("mppc_new(): system out of memory\n");
1260 ptr->history_ptr = ptr->history_buf;
1261 ptr->history_buf_end = ptr->history_buf + RDP6_HISTORY_BUF_SIZE - 1;
1267 * free history buffer
1269 * @param rdp rdp struct that contains rdp_mppc struct
1272 void mppc_free(rdpRdp* rdp)
1279 if (rdp->mppc->history_buf)
1281 xfree(rdp->mppc->history_buf);
1282 rdp->mppc->history_buf = NULL;
1283 rdp->mppc->history_ptr = NULL;
1286 if (rdp->mppc->offset_cache)
1288 xfree(rdp->mppc->offset_cache);