The real, definitive, Visual C++ support branch. Accept no substitutes
[reactos.git] / base / applications / tsclient / rdesktop / 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
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22 #include "rdesktop.h"
23
24 BOOL
25 rdp5_process(RDPCLIENT * This, STREAM s)
26 {
27 uint16 length, count, x, y;
28 uint8 type, ctype;
29 uint8 *next;
30
31 uint32 roff, rlen;
32 struct stream *ns = &(This->mppc_dict.ns);
33 struct stream *ts;
34
35 #if 0
36 printf("RDP5 data:\n");
37 hexdump(s->p, s->end - s->p);
38 #endif
39
40 ui_begin_update(This);
41 while (s->p < s->end)
42 {
43 in_uint8(s, type);
44 if (type & RDP5_COMPRESSED)
45 {
46 in_uint8(s, ctype);
47 in_uint16_le(s, length);
48 type ^= RDP5_COMPRESSED;
49 }
50 else
51 {
52 ctype = 0;
53 in_uint16_le(s, length);
54 }
55 This->next_packet = next = s->p + length;
56
57 if (ctype & RDP_MPPC_COMPRESSED)
58 {
59 void * p;
60
61 if (mppc_expand(This, s->p, length, ctype, &roff, &rlen) == -1)
62 error("error while decompressing packet\n");
63
64 /* allocate memory and copy the uncompressed data into the temporary stream */
65 p = realloc(ns->data, rlen);
66
67 if(p == NULL)
68 {
69 This->disconnect_reason = 262;
70 return False;
71 }
72
73 ns->data = (uint8 *) p;
74
75 memcpy((ns->data), (unsigned char *) (This->mppc_dict.hist + roff), rlen);
76
77 ns->size = rlen;
78 ns->end = (ns->data + ns->size);
79 ns->p = ns->data;
80 ns->rdp_hdr = ns->p;
81
82 ts = ns;
83 }
84 else
85 ts = s;
86
87 switch (type)
88 {
89 case 0: /* update orders */
90 in_uint16_le(ts, count);
91 process_orders(This, ts, count);
92 break;
93 case 1: /* update bitmap */
94 in_uint8s(ts, 2); /* part length */
95 process_bitmap_updates(This, ts);
96 break;
97 case 2: /* update palette */
98 in_uint8s(ts, 2); /* uint16 = 2 */
99 process_palette(This, ts);
100 break;
101 case 3: /* update synchronize */
102 break;
103 case 5: /* null pointer */
104 ui_set_null_cursor(This);
105 break;
106 case 6: /* default pointer */
107 break;
108 case 8: /* pointer position */
109 in_uint16_le(ts, x);
110 in_uint16_le(ts, y);
111 if (s_check(ts))
112 ui_move_pointer(This, x, y);
113 break;
114 case 9: /* color pointer */
115 process_colour_pointer_pdu(This, ts);
116 break;
117 case 10: /* cached pointer */
118 process_cached_pointer_pdu(This, ts);
119 break;
120 default:
121 unimpl("RDP5 opcode %d\n", type);
122 }
123
124 s->p = next;
125 }
126 ui_end_update(This);
127 return True;
128 }