[NTDLL]
[reactos.git] / reactos / base / applications / mstsc / rdp5.c
1 /* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Protocol services - RDP5 short form PDU processing
4 Copyright (C) Matthew Chapman 1999-2005
5 Copyright (C) Erik Forsberg 2003
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
22 #include <precomp.h>
23
24 extern uint8 *g_next_packet;
25
26 extern RDPCOMP g_mppc_dict;
27
28 void
29 rdp5_process(STREAM s)
30 {
31 uint16 length, count, x, y;
32 uint8 type, ctype;
33 uint8 *next;
34
35 uint32 roff, rlen;
36 struct stream *ns = &(g_mppc_dict.ns);
37 struct stream *ts;
38
39 #if 0
40 printf("RDP5 data:\n");
41 hexdump(s->p, s->end - s->p);
42 #endif
43
44 ui_begin_update();
45 while (s->p < s->end)
46 {
47 in_uint8(s, type);
48 if (type & RDP5_COMPRESSED)
49 {
50 in_uint8(s, ctype);
51 in_uint16_le(s, length);
52 type ^= RDP5_COMPRESSED;
53 }
54 else
55 {
56 ctype = 0;
57 in_uint16_le(s, length);
58 }
59 g_next_packet = next = s->p + length;
60
61 if (ctype & RDP_MPPC_COMPRESSED)
62 {
63 if (mppc_expand(s->p, length, ctype, &roff, &rlen) == -1)
64 error("error while decompressing packet\n");
65
66 /* allocate memory and copy the uncompressed data into the temporary stream */
67 ns->data = (uint8 *) xrealloc(ns->data, rlen);
68
69 memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
70
71 ns->size = rlen;
72 ns->end = (ns->data + ns->size);
73 ns->p = ns->data;
74 ns->rdp_hdr = ns->p;
75
76 ts = ns;
77 }
78 else
79 ts = s;
80
81 switch (type)
82 {
83 case 0: /* update orders */
84 in_uint16_le(ts, count);
85 process_orders(ts, count);
86 break;
87 case 1: /* update bitmap */
88 in_uint8s(ts, 2); /* part length */
89 process_bitmap_updates(ts);
90 break;
91 case 2: /* update palette */
92 in_uint8s(ts, 2); /* uint16 = 2 */
93 process_palette(ts);
94 break;
95 case 3: /* update synchronize */
96 break;
97 case 5: /* null pointer */
98 ui_set_null_cursor();
99 break;
100 case 6: /* default pointer */
101 break;
102 case 8: /* pointer position */
103 in_uint16_le(ts, x);
104 in_uint16_le(ts, y);
105 if (s_check(ts))
106 ui_move_pointer(x, y);
107 break;
108 case 9: /* color pointer */
109 process_colour_pointer_pdu(ts);
110 break;
111 case 10: /* cached pointer */
112 process_cached_pointer_pdu(ts);
113 break;
114 default:
115 unimpl("RDP5 opcode %d\n", type);
116 }
117
118 s->p = next;
119 }
120 ui_end_update();
121 }