Initial commit - from Precise source
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-core / mppc.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol Client
3  * Implements Microsoft Point to Point Compression (MPPC) protocol
4  *
5  * Copyright 2011 Laxmikant Rashinkar <LK.Rashinkar@gmail.com>
6  *
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
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  */
19
20 #include "rdp.h"
21
22 #if 0
23 static uint8 HuffLengthLEC[] =
24 {
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
44 };
45 #endif
46
47 static uint16 HuffIndexLEC[512] =
48 {
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
81 };
82
83 static uint16 LECHTab[] =
84 {
85         511, 0, 508, 448, 494, 347, 486, 482
86 };
87
88 #if 0
89 static uint8 HuffLenLOM[] =
90 {
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
93 };
94 #endif
95
96 static uint16 HuffIndexLOM[] =
97 {
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
100 };
101
102 static uint8 LOMHTab[] =
103 {
104         0, 4, 10, 19
105 };
106
107 #if 0
108 static uint8 CopyOffsetBitsLUT[] =
109 {
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
111 };
112
113 static uint32 CopyOffsetBaseLUT[] =
114 {
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
117 };
118
119 static uint8 LoMBitsLUT[] =
120 {
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
122 };
123
124 static uint16 LoMBaseLUT[] =
125 {
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
128 };
129 #endif
130
131 uint16 LEChash(uint16 key)
132 {
133         return ((key & 0x1ff) ^ (key  >> 9) ^ (key >> 4) ^ (key >> 7));
134 }
135
136 uint16 LOMhash(uint16 key)
137 {
138         return ((key & 0x1f) ^ (key  >> 5) ^ (key >> 9));
139 }
140                         
141 uint16 miniLEChash(uint16 key)
142 {
143         uint16 h;
144         h = ((((key >> 8) ^ (key & 0xff)) >> 2) & 0xf);
145         if(key >> 9)
146                 h = ~h;
147         return (h % 12);
148 }
149
150 uint8 miniLOMhash(uint16 key)
151 {
152         return ((key >> 4) ^ (key >> 6) ^ (key >> 7));
153 }
154
155 uint16 getLECindex(uint16 huff)
156 {
157         uint16 h = HuffIndexLEC[LEChash(huff)];
158         if((h ^ huff) >> 9)
159                 return h & 0x1ff;
160         else
161                 return HuffIndexLEC[LECHTab[miniLEChash(huff)]];
162 }
163
164 uint16 getLOMindex(uint16 huff)
165 {
166         uint16 h = HuffIndexLOM[LOMhash(huff)];
167         if((h ^ huff) >> 5)
168         {       
169                 return h & 0x1f;
170         }       
171         else
172                 return HuffIndexLOM[LOMHTab[miniLOMhash(huff)]];
173 }
174
175 int decompress_rdp(rdpRdp* rdp, uint8* cbuf, int len, int ctype, uint32* roff, uint32* rlen)
176 {
177         int type = ctype & 0x0f;
178
179         switch (type)
180         {
181                 case PACKET_COMPR_TYPE_8K:
182                         return decompress_rdp_4(rdp, cbuf, len, ctype, roff, rlen);
183                         break;
184
185                 case PACKET_COMPR_TYPE_64K:
186                         return decompress_rdp_5(rdp, cbuf, len, ctype, roff, rlen);
187                         break;
188
189                 case PACKET_COMPR_TYPE_RDP6:
190                         return decompress_rdp_6(rdp, cbuf, len, ctype, roff, rlen);
191                         break;
192
193                 case PACKET_COMPR_TYPE_RDP61:
194                         return decompress_rdp_61(rdp, cbuf, len, ctype, roff, rlen);
195                         break;
196
197                 default:
198                         printf("mppc.c: invalid RDP compression code 0x%2.2x\n", type);
199                         return false;
200         }
201 }
202
203 /**
204  * decompress RDP 4 data
205  *
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
212  *
213  * @return        True on success, False on failure
214  */
215
216 int decompress_rdp_4(rdpRdp* rdp, uint8* cbuf, int len, int ctype, uint32* roff, uint32* rlen)
217 {
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 */
228         int       tmp;
229         uint32    i32;
230
231         printf("decompress_rdp_4:\n");
232
233         if ((rdp->mppc == NULL) || (rdp->mppc->history_buf == NULL))
234         {
235                 printf("decompress_rdp_4: null\n");
236                 return false;
237         }
238
239         src_ptr = 0;
240         cptr = cbuf;
241         copy_offset = 0;
242         lom = 0;
243         bits_left = 0;
244         cur_bits_left = 0;
245         d32 = 0;
246         cur_byte = 0;
247         *rlen = 0;
248
249         /* get start of history buffer */
250         history_buf = rdp->mppc->history_buf;
251
252         /* get next free slot in history buffer */
253         history_ptr = rdp->mppc->history_ptr;
254         *roff = history_ptr - history_buf;
255
256         if (ctype & PACKET_AT_FRONT)
257         {
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;
261                 *roff = 0;
262         }
263
264         if (ctype & PACKET_FLUSHED)
265         {
266                 /* re-init history buffer */
267                 history_ptr = rdp->mppc->history_buf;
268                 memset(history_buf, 0, RDP6_HISTORY_BUF_SIZE);
269                 *roff = 0;
270         }
271
272         if ((ctype & PACKET_COMPRESSED) != PACKET_COMPRESSED)
273         {
274                 /* data in cbuf is not compressed - copy to history buf as is */
275                 memcpy(history_ptr, cbuf, len);
276                 history_ptr += len;
277                 *rlen = history_ptr - rdp->mppc->history_ptr;
278                 rdp->mppc->history_ptr = history_ptr;
279                 return true;
280         }
281
282         /* load initial data */
283         tmp = 24;
284         while (cptr < cbuf + len)
285         {
286                 i32 = *cptr++;
287                 d32  |= i32 << tmp;
288                 bits_left += 8;
289                 tmp -= 8;
290                 if (tmp < 0)
291                 {
292                         break;
293                 }
294         }
295
296         if (cptr < cbuf + len)
297         {
298                 cur_byte = *cptr++;
299                 cur_bits_left = 8;
300         }
301         else
302         {
303                 cur_bits_left = 0;
304         }
305
306         /*
307         ** start uncompressing data in cbuf
308         */
309
310         while (bits_left >= 8)
311         {
312                 /*
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
318                 */
319
320                 /*
321                    at this point, we are guaranteed that d32 has 32 bits to
322                    be processed, unless we have reached end of cbuf
323                 */
324
325                 copy_offset = 0;
326
327                 if ((d32 & 0x80000000) == 0)
328                 {
329                         /* got a literal */
330                         *history_ptr++ = d32 >> 24;
331                         d32 <<= 8;
332                         bits_left -= 8;
333                 }
334                 else if ((d32 & 0xc0000000) == 0x80000000)
335                 {
336                         /* got encoded literal */
337                         d32 <<= 2;
338                         *history_ptr++ = (d32 >> 25) | 0x80;
339                         d32 <<= 7;
340                         bits_left -= 9;
341                 }
342                 else if ((d32 & 0xf0000000) == 0xf0000000)
343                 {
344                         /* got copy offset in range 0 - 63, */
345                         /* with 6 bit copy offset */
346                         d32 <<= 4;
347                         copy_offset = d32 >> 26;
348                         d32 <<= 6;
349                         bits_left -= 10;
350                 }
351                 else if ((d32 & 0xf0000000) == 0xe0000000)
352                 {
353                         /* got copy offset in range 64 - 319, */
354                         /* with 8 bit copy offset */
355                         d32 <<= 4;
356                         copy_offset = d32 >> 24;
357                         copy_offset += 64;
358                         d32 <<= 8;
359                         bits_left -= 12;
360                 }
361                 else if ((d32 & 0xe0000000) == 0xc0000000)
362                 {
363                         /* got copy offset in range 320 - 8191, */
364                         /* with 13 bits copy offset */
365                         d32 <<= 3;
366                         copy_offset = d32 >> 19;
367                         copy_offset += 320;
368                         d32 <<= 13;
369                         bits_left -= 16;
370                 }
371
372                 /*
373                 ** get more bits before we process length of match
374                 */
375
376                 /* how may bits do we need to get? */
377                 tmp = 32 - bits_left;
378
379                 while (tmp)
380                 {
381                         if (cur_bits_left < tmp)
382                         {
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)
389                                 {
390                                         /* more compressed data available */
391                                         cur_byte = *cptr++;
392                                         cur_bits_left = 8;
393                                 }
394                                 else
395                                 {
396                                         /* no more compressed data available */
397                                         tmp = 0;
398                                         cur_bits_left = 0;
399                                 }
400                         }
401                         else if (cur_bits_left > tmp)
402                         {
403                                 /* we have more bits than we need */
404                                 d32 |= cur_byte >> (8 - tmp);
405                                 cur_byte <<= tmp;
406                                 cur_bits_left -= tmp;
407                                 bits_left = 32;
408                                 break;
409                         }
410                         else
411                         {
412                                 /* we have just the right amount of bits */
413                                 d32 |= cur_byte >> (8 - tmp);
414                                 bits_left = 32;
415                                 if (cptr < cbuf + len)
416                                 {
417                                         cur_byte = *cptr++;
418                                         cur_bits_left = 8;
419                                 }
420                                 else
421                                 {
422                                         cur_bits_left = 0;
423                                 }
424                                 break;
425                         }
426                 }
427
428                 if (!copy_offset)
429                 {
430                         continue;
431                 }
432
433                 /*
434                 ** compute Length of Match
435                 */
436
437                 /*
438                    lengh of match  Encoding (binary header + LoM bits
439                    --------------  ----------------------------------
440                    3               0
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
452                 */
453
454                 if ((d32 & 0x80000000) == 0)
455                 {
456                         /* lom is fixed to 3 */
457                         lom = 3;
458                         d32 <<= 1;
459                         bits_left -= 1;
460                 }
461                 else if ((d32 & 0xc0000000) == 0x80000000)
462                 {
463                         /* 2 lower bits of LoM */
464                         lom = ((d32 >> 28) & 0x03) + 4;
465                         d32 <<= 4;
466                         bits_left -= 4;
467                 }
468                 else if ((d32 & 0xe0000000) == 0xc0000000)
469                 {
470                         /* 3 lower bits of LoM */
471                         lom = ((d32 >> 26) & 0x07) + 8;
472                         d32 <<= 6;
473                         bits_left -= 6;
474                 }
475                 else if ((d32 & 0xf0000000) == 0xe0000000)
476                 {
477                         /* 4 lower bits of LoM */
478                         lom = ((d32 >> 24) & 0x0f) + 16;
479                         d32 <<= 8;
480                         bits_left -= 8;
481                 }
482                 else if ((d32 & 0xf8000000) == 0xf0000000)
483                 {
484                         /* 5 lower bits of LoM */
485                         lom = ((d32 >> 22) & 0x1f) + 32;
486                         d32 <<= 10;
487                         bits_left -= 10;
488                 }
489                 else if ((d32 & 0xfc000000) == 0xf8000000)
490                 {
491                         /* 6 lower bits of LoM */
492                         lom = ((d32 >> 20) & 0x3f) + 64;
493                         d32 <<= 12;
494                         bits_left -= 12;
495                 }
496                 else if ((d32 & 0xfe000000) == 0xfc000000)
497                 {
498                         /* 7 lower bits of LoM */
499                         lom = ((d32 >> 18) & 0x7f) + 128;
500                         d32 <<= 14;
501                         bits_left -= 14;
502                 }
503                 else if ((d32 & 0xff000000) == 0xfe000000)
504                 {
505                         /* 8 lower bits of LoM */
506                         lom = ((d32 >> 16) & 0xff) + 256;
507                         d32 <<= 16;
508                         bits_left -= 16;
509                 }
510                 else if ((d32 & 0xff800000) == 0xff000000)
511                 {
512                         /* 9 lower bits of LoM */
513                         lom = ((d32 >> 14) & 0x1ff) + 512;
514                         d32 <<= 18;
515                         bits_left -= 18;
516                 }
517                 else if ((d32 & 0xffc00000) == 0xff800000)
518                 {
519                         /* 10 lower bits of LoM */
520                         lom = ((d32 >> 12) & 0x3ff) + 1024;
521                         d32 <<= 20;
522                         bits_left -= 20;
523                 }
524                 else if ((d32 & 0xffe00000) == 0xffc00000)
525                 {
526                         /* 11 lower bits of LoM */
527                         lom = ((d32 >> 10) & 0x7ff) + 2048;
528                         d32 <<= 22;
529                         bits_left -= 22;
530                 }
531                 else if ((d32 & 0xfff00000) == 0xffe00000)
532                 {
533                         /* 12 lower bits of LoM */
534                         lom = ((d32 >> 8) & 0xfff) + 4096;
535                         d32 <<= 24;
536                         bits_left -= 24;
537                 }
538
539                 /* now that we have copy_offset and LoM, process them */
540
541                 src_ptr = history_ptr - copy_offset;
542                 if (src_ptr >= rdp->mppc->history_buf)
543                 {
544                         /* data does not wrap around */
545                         while (lom > 0)
546                         {
547                                 *history_ptr++ = *src_ptr++;
548                                 lom--;
549                         }
550                 }
551                 else
552                 {
553                         src_ptr = rdp->mppc->history_buf_end - (copy_offset - (history_ptr - rdp->mppc->history_buf));
554                         src_ptr++;
555                         while (lom && (src_ptr <= rdp->mppc->history_buf_end))
556                         {
557                                 *history_ptr++ = *src_ptr++;
558                                 lom--;
559                         }
560
561                         src_ptr = rdp->mppc->history_buf;
562                         while (lom > 0)
563                         {
564                                 *history_ptr++ = *src_ptr++;
565                                 lom--;
566                         }
567                 }
568
569                 /*
570                 ** get more bits before we restart the loop
571                 */
572
573                 /* how may bits do we need to get? */
574                 tmp = 32 - bits_left;
575
576                 while (tmp)
577                 {
578                         if (cur_bits_left < tmp)
579                         {
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)
586                                 {
587                                         /* more compressed data available */
588                                         cur_byte = *cptr++;
589                                         cur_bits_left = 8;
590                                 }
591                                 else
592                                 {
593                                         /* no more compressed data available */
594                                         tmp = 0;
595                                         cur_bits_left = 0;
596                                 }
597                         }
598                         else if (cur_bits_left > tmp)
599                         {
600                                 /* we have more bits than we need */
601                                 d32 |= cur_byte >> (8 - tmp);
602                                 cur_byte <<= tmp;
603                                 cur_bits_left -= tmp;
604                                 bits_left = 32;
605                                 break;
606                         }
607                         else
608                         {
609                                 /* we have just the right amount of bits */
610                                 d32 |= cur_byte >> (8 - tmp);
611                                 bits_left = 32;
612                                 if (cptr < cbuf + len)
613                                 {
614                                         cur_byte = *cptr++;
615                                         cur_bits_left = 8;
616                                 }
617                                 else
618                                 {
619                                         cur_bits_left = 0;
620                                 }
621                                 break;
622                         }
623                 }
624         } /* end while (bits_left >= 8) */
625
626         *rlen = history_ptr - rdp->mppc->history_ptr;
627
628         rdp->mppc->history_ptr = history_ptr;
629
630         return true;
631 }
632
633 /**
634  * decompress RDP 5 data
635  *
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
642  *
643  * @return        True on success, False on failure
644  */
645
646 int decompress_rdp_5(rdpRdp* rdp, uint8* cbuf, int len, int ctype, uint32* roff, uint32* rlen)
647 {
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 */
658         int       tmp;
659         uint32    i32;
660
661         if ((rdp->mppc == NULL) || (rdp->mppc->history_buf == NULL))
662         {
663                 printf("decompress_rdp_5: null\n");
664                 return false;
665         }
666
667         src_ptr = 0;
668         cptr = cbuf;
669         copy_offset = 0;
670         lom = 0;
671         bits_left = 0;
672         cur_bits_left = 0;
673         d32 = 0;
674         cur_byte = 0;
675         *rlen = 0;
676
677         /* get start of history buffer */
678         history_buf = rdp->mppc->history_buf;
679
680         /* get next free slot in history buffer */
681         history_ptr = rdp->mppc->history_ptr;
682         *roff = history_ptr - history_buf;
683
684         if (ctype & PACKET_AT_FRONT)
685         {
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;
689                 *roff = 0;
690         }
691
692         if (ctype & PACKET_FLUSHED)
693         {
694                 /* re-init history buffer */
695                 history_ptr = rdp->mppc->history_buf;
696                 memset(history_buf, 0, RDP6_HISTORY_BUF_SIZE);
697                 *roff = 0;
698         }
699
700         if ((ctype & PACKET_COMPRESSED) != PACKET_COMPRESSED)
701         {
702                 /* data in cbuf is not compressed - copy to history buf as is */
703                 memcpy(history_ptr, cbuf, len);
704                 history_ptr += len;
705                 *rlen = history_ptr - rdp->mppc->history_ptr;
706                 rdp->mppc->history_ptr = history_ptr;
707                 return true;
708         }
709
710         /* load initial data */
711         tmp = 24;
712         while (cptr < cbuf + len)
713         {
714                 i32 = *cptr++;
715                 d32  |= i32 << tmp;
716                 bits_left += 8;
717                 tmp -= 8;
718                 if (tmp < 0)
719                 {
720                         break;
721                 }
722         }
723
724         if (cptr < cbuf + len)
725         {
726                 cur_byte = *cptr++;
727                 cur_bits_left = 8;
728         }
729         else
730         {
731                 cur_bits_left = 0;
732         }
733
734         /*
735         ** start uncompressing data in cbuf
736         */
737
738         while (bits_left >= 8)
739         {
740                 /*
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+
747                 */
748
749                 /*
750                    at this point, we are guaranteed that d32 has 32 bits to
751                    be processed, unless we have reached end of cbuf
752                 */
753
754                 copy_offset = 0;
755
756                 if ((d32 & 0x80000000) == 0)
757                 {
758                         /* got a literal */
759                         *history_ptr++ = d32 >> 24;
760                         d32 <<= 8;
761                         bits_left -= 8;
762                 }
763                 else if ((d32 & 0xc0000000) == 0x80000000)
764                 {
765                         /* got encoded literal */
766                         d32 <<= 2;
767                         *history_ptr++ = (d32 >> 25) | 0x80;
768                         d32 <<= 7;
769                         bits_left -= 9;
770                 }
771                 else if ((d32 & 0xf8000000) == 0xf8000000)
772                 {
773                         /* got copy offset in range 0 - 63, */
774                         /* with 6 bit copy offset */
775                         d32 <<= 5;
776                         copy_offset = d32 >> 26;
777                         d32 <<= 6;
778                         bits_left -= 11;
779                 }
780                 else if ((d32 & 0xf8000000) == 0xf0000000)
781                 {
782                         /* got copy offset in range 64 - 319, */
783                         /* with 8 bit copy offset */
784                         d32 <<= 5;
785                         copy_offset = d32 >> 24;
786                         copy_offset += 64;
787                         d32 <<= 8;
788                         bits_left -= 13;
789                 }
790                 else if ((d32 & 0xf0000000) == 0xe0000000)
791                 {
792                         /* got copy offset in range 320 - 2367, */
793                         /* with 11 bits copy offset */
794                         d32 <<= 4;
795                         copy_offset = d32 >> 21;
796                         copy_offset += 320;
797                         d32 <<= 11;
798                         bits_left -= 15;
799                 }
800                 else if ((d32 & 0xe0000000) == 0xc0000000)
801                 {
802                         /* got copy offset in range 2368+, */
803                         /* with 16 bits copy offset */
804                         d32 <<= 3;
805                         copy_offset = d32 >> 16;
806                         copy_offset += 2368;
807                         d32 <<= 16;
808                         bits_left -= 19;
809                 }
810
811                 /*
812                 ** get more bits before we process length of match
813                 */
814
815                 /* how may bits do we need to get? */
816                 tmp = 32 - bits_left;
817
818                 while (tmp)
819                 {
820                         if (cur_bits_left < tmp)
821                         {
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)
828                                 {
829                                         /* more compressed data available */
830                                         cur_byte = *cptr++;
831                                         cur_bits_left = 8;
832                                 }
833                                 else
834                                 {
835                                         /* no more compressed data available */
836                                         tmp = 0;
837                                         cur_bits_left = 0;
838                                 }
839                         }
840                         else if (cur_bits_left > tmp)
841                         {
842                                 /* we have more bits than we need */
843                                 d32 |= cur_byte >> (8 - tmp);
844                                 cur_byte <<= tmp;
845                                 cur_bits_left -= tmp;
846                                 bits_left = 32;
847                                 break;
848                         }
849                         else
850                         {
851                                 /* we have just the right amount of bits */
852                                 d32 |= cur_byte >> (8 - tmp);
853                                 bits_left = 32;
854                                 if (cptr < cbuf + len)
855                                 {
856                                         cur_byte = *cptr++;
857                                         cur_bits_left = 8;
858                                 }
859                                 else
860                                 {
861                                         cur_bits_left = 0;
862                                 }
863                                 break;
864                         }
865                 }
866
867                 if (!copy_offset)
868                 {
869                         continue;
870                 }
871
872                 /*
873                 ** compute Length of Match
874                 */
875
876                 /*
877                    lengh of match  Encoding (binary header + LoM bits
878                    --------------  ----------------------------------
879                    3               0
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
894                 */
895
896                 if ((d32 & 0x80000000) == 0)
897                 {
898                         /* lom is fixed to 3 */
899                         lom = 3;
900                         d32 <<= 1;
901                         bits_left -= 1;
902                 }
903                 else if ((d32 & 0xc0000000) == 0x80000000)
904                 {
905                         /* 2 lower bits of LoM */
906                         lom = ((d32 >> 28) & 0x03) + 4;
907                         d32 <<= 4;
908                         bits_left -= 4;
909                 }
910                 else if ((d32 & 0xe0000000) == 0xc0000000)
911                 {
912                         /* 3 lower bits of LoM */
913                         lom = ((d32 >> 26) & 0x07) + 8;
914                         d32 <<= 6;
915                         bits_left -= 6;
916                 }
917                 else if ((d32 & 0xf0000000) == 0xe0000000)
918                 {
919                         /* 4 lower bits of LoM */
920                         lom = ((d32 >> 24) & 0x0f) + 16;
921                         d32 <<= 8;
922                         bits_left -= 8;
923                 }
924                 else if ((d32 & 0xf8000000) == 0xf0000000)
925                 {
926                         /* 5 lower bits of LoM */
927                         lom = ((d32 >> 22) & 0x1f) + 32;
928                         d32 <<= 10;
929                         bits_left -= 10;
930                 }
931                 else if ((d32 & 0xfc000000) == 0xf8000000)
932                 {
933                         /* 6 lower bits of LoM */
934                         lom = ((d32 >> 20) & 0x3f) + 64;
935                         d32 <<= 12;
936                         bits_left -= 12;
937                 }
938                 else if ((d32 & 0xfe000000) == 0xfc000000)
939                 {
940                         /* 7 lower bits of LoM */
941                         lom = ((d32 >> 18) & 0x7f) + 128;
942                         d32 <<= 14;
943                         bits_left -= 14;
944                 }
945                 else if ((d32 & 0xff000000) == 0xfe000000)
946                 {
947                         /* 8 lower bits of LoM */
948                         lom = ((d32 >> 16) & 0xff) + 256;
949                         d32 <<= 16;
950                         bits_left -= 16;
951                 }
952                 else if ((d32 & 0xff800000) == 0xff000000)
953                 {
954                         /* 9 lower bits of LoM */
955                         lom = ((d32 >> 14) & 0x1ff) + 512;
956                         d32 <<= 18;
957                         bits_left -= 18;
958                 }
959                 else if ((d32 & 0xffc00000) == 0xff800000)
960                 {
961                         /* 10 lower bits of LoM */
962                         lom = ((d32 >> 12) & 0x3ff) + 1024;
963                         d32 <<= 20;
964                         bits_left -= 20;
965                 }
966                 else if ((d32 & 0xffe00000) == 0xffc00000)
967                 {
968                         /* 11 lower bits of LoM */
969                         lom = ((d32 >> 10) & 0x7ff) + 2048;
970                         d32 <<= 22;
971                         bits_left -= 22;
972                 }
973                 else if ((d32 & 0xfff00000) == 0xffe00000)
974                 {
975                         /* 12 lower bits of LoM */
976                         lom = ((d32 >> 8) & 0xfff) + 4096;
977                         d32 <<= 24;
978                         bits_left -= 24;
979                 }
980                 else if ((d32 & 0xfff80000) == 0xfff00000)
981                 {
982                         /* 13 lower bits of LoM */
983                         lom = ((d32 >> 6) & 0x1fff) + 8192;
984                         d32 <<= 26;
985                         bits_left -= 26;
986                 }
987                 else if ((d32 & 0xfffc0000) == 0xfff80000)
988                 {
989                         /* 14 lower bits of LoM */
990                         lom = ((d32 >> 4) & 0x3fff) + 16384;
991                         d32 <<= 28;
992                         bits_left -= 28;
993                 }
994                 else if ((d32 & 0xfffe0000) == 0xfffc0000)
995                 {
996                         /* 15 lower bits of LoM */
997                         lom = ((d32 >> 2) & 0x7fff) + 32768;
998                         d32 <<= 30;
999                         bits_left -= 30;
1000                 }
1001
1002                 /* now that we have copy_offset and LoM, process them */
1003
1004                 src_ptr = history_ptr - copy_offset;
1005                 if (src_ptr >= rdp->mppc->history_buf)
1006                 {
1007                         /* data does not wrap around */
1008                         while (lom > 0)
1009                         {
1010                                 *history_ptr++ = *src_ptr++;
1011                                 lom--;
1012                         }
1013                 }
1014                 else
1015                 {
1016                         src_ptr = rdp->mppc->history_buf_end - (copy_offset - (history_ptr - rdp->mppc->history_buf));
1017                         src_ptr++;
1018                         while (lom && (src_ptr <= rdp->mppc->history_buf_end))
1019                         {
1020                                 *history_ptr++ = *src_ptr++;
1021                                 lom--;
1022                         }
1023
1024                         src_ptr = rdp->mppc->history_buf;
1025                         while (lom > 0)
1026                         {
1027                                 *history_ptr++ = *src_ptr++;
1028                                 lom--;
1029                         }
1030                 }
1031
1032                 /*
1033                 ** get more bits before we restart the loop
1034                 */
1035
1036                 /* how may bits do we need to get? */
1037                 tmp = 32 - bits_left;
1038
1039                 while (tmp)
1040                 {
1041                         if (cur_bits_left < tmp)
1042                         {
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)
1049                                 {
1050                                         /* more compressed data available */
1051                                         cur_byte = *cptr++;
1052                                         cur_bits_left = 8;
1053                                 }
1054                                 else
1055                                 {
1056                                         /* no more compressed data available */
1057                                         tmp = 0;
1058                                         cur_bits_left = 0;
1059                                 }
1060                         }
1061                         else if (cur_bits_left > tmp)
1062                         {
1063                                 /* we have more bits than we need */
1064                                 d32 |= cur_byte >> (8 - tmp);
1065                                 cur_byte <<= tmp;
1066                                 cur_bits_left -= tmp;
1067                                 bits_left = 32;
1068                                 break;
1069                         }
1070                         else
1071                         {
1072                                 /* we have just the right amount of bits */
1073                                 d32 |= cur_byte >> (8 - tmp);
1074                                 bits_left = 32;
1075                                 if (cptr < cbuf + len)
1076                                 {
1077                                         cur_byte = *cptr++;
1078                                         cur_bits_left = 8;
1079                                 }
1080                                 else
1081                                 {
1082                                         cur_bits_left = 0;
1083                                 }
1084                                 break;
1085                         }
1086                 }
1087
1088         } /* end while (cptr < cbuf + len) */
1089
1090         *rlen = history_ptr - rdp->mppc->history_ptr;
1091
1092         rdp->mppc->history_ptr = history_ptr;
1093
1094         return true;
1095 }
1096
1097 /**
1098  * decompress RDP 6 data
1099  *
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
1106  *
1107  * @return        True on success, False on failure
1108  */
1109
1110 int decompress_rdp_6(rdpRdp* rdp, uint8* cbuf, int len, int ctype, uint32* roff, uint32* rlen)
1111 {
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 */
1123         int       tmp;
1124         uint32    i32;
1125
1126         if ((rdp->mppc == NULL) || (rdp->mppc->history_buf == NULL))
1127         {
1128                 printf("decompress_rdp_6: null\n");
1129                 return false;
1130         }
1131
1132         src_ptr = 0;
1133         cptr = cbuf;
1134         copy_offset = 0;
1135         lom = 0;
1136         bits_left = 0;
1137         cur_bits_left = 0;
1138         d32 = 0;
1139         cur_byte = 0;
1140         *rlen = 0;
1141
1142         /* get start of history buffer */
1143         history_buf = rdp->mppc->history_buf;
1144
1145         /* get start of offset_cache */
1146         offset_cache = rdp->mppc->offset_cache;
1147
1148         /* get next free slot in history buffer */
1149         history_ptr = rdp->mppc->history_ptr;
1150         *roff = history_ptr - history_buf;
1151
1152         if (ctype & PACKET_AT_FRONT)
1153         {
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;
1159                 *roff = 32768;
1160         }
1161         
1162         if (ctype & PACKET_FLUSHED)
1163         {
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);
1168                 *roff = 0;
1169         }
1170
1171         if ((ctype & PACKET_COMPRESSED) != PACKET_COMPRESSED)
1172         {
1173                 /* data in cbuf is not compressed - copy to history buf as is */
1174                 memcpy(history_ptr, cbuf, len);
1175                 history_ptr += len;
1176                 *rlen = history_ptr - rdp->mppc->history_ptr;
1177                 rdp->mppc->history_ptr = history_ptr;
1178                 return true;
1179         }
1180
1181         /* load initial data */
1182         tmp = 24;
1183         while (cptr < cbuf + len)
1184         {
1185                 i32 = *cptr++;
1186                 d32  |= i32 << tmp;
1187                 bits_left += 8;
1188                 tmp -= 8;
1189                 if (tmp < 0)
1190                 {
1191                         break;
1192                 }
1193         }
1194
1195         if (cptr < cbuf + len)
1196         {
1197                 cur_byte = *cptr++;
1198                 cur_bits_left = 8;
1199         }
1200         else
1201         {
1202                 cur_bits_left = 0;
1203         }
1204
1205         /*
1206         ** start uncompressing data in cbuf
1207         */
1208
1209
1210         return true;
1211 }
1212
1213 /**
1214  * decompress RDP 6.1 data
1215  *
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
1222  *
1223  * @return        True on success, False on failure
1224  */
1225
1226 int decompress_rdp_61(rdpRdp* rdp, uint8* cbuf, int len, int ctype, uint32* roff, uint32* rlen)
1227 {
1228         return false;
1229 }
1230
1231 /**
1232  * allocate space to store history buffer
1233  *
1234  * @param rdp rdp struct that contains rdp_mppc struct
1235  * @return pointer to new struct, or NULL on failure
1236  */
1237
1238 struct rdp_mppc* mppc_new(rdpRdp* rdp)
1239 {
1240         struct rdp_mppc* ptr;
1241
1242         ptr = (struct rdp_mppc*) xmalloc(sizeof(struct rdp_mppc));
1243
1244         if (!ptr)
1245         {
1246                 printf("mppc_new(): system out of memory\n");
1247                 return NULL;
1248         }
1249
1250         ptr->history_buf = (uint8*) xmalloc(RDP6_HISTORY_BUF_SIZE);
1251         ptr->offset_cache = (uint16*) xzalloc(RDP6_OFFSET_CACHE_SIZE);
1252
1253         if (!ptr->history_buf)
1254         {
1255                 printf("mppc_new(): system out of memory\n");
1256                 xfree(ptr);
1257                 return NULL;
1258         }
1259
1260         ptr->history_ptr = ptr->history_buf;
1261         ptr->history_buf_end = ptr->history_buf + RDP6_HISTORY_BUF_SIZE - 1;
1262
1263         return ptr;
1264 }
1265
1266 /**
1267  * free history buffer
1268  *
1269  * @param rdp rdp struct that contains rdp_mppc struct
1270  */
1271
1272 void mppc_free(rdpRdp* rdp)
1273 {
1274         if (!rdp->mppc)
1275         {
1276                 return;
1277         }
1278
1279         if (rdp->mppc->history_buf)
1280         {
1281                 xfree(rdp->mppc->history_buf);
1282                 rdp->mppc->history_buf = NULL;
1283                 rdp->mppc->history_ptr = NULL;
1284         }
1285
1286         if (rdp->mppc->offset_cache)
1287         {
1288                 xfree(rdp->mppc->offset_cache);
1289         }
1290
1291         xfree(rdp->mppc);
1292 }