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 "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 }
129