xref: /reactos/base/applications/mstsc/rdp5.c (revision 40462c92)
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 <matthewc.unsw.edu.au> 1999-2008
5    Copyright 2003-2008 Erik Forsberg <forsberg@cendio.se> for Cendio AB
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 3 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, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #include "precomp.h"
22 
23 extern uint8 *g_next_packet;
24 
25 extern RDPCOMP g_mppc_dict;
26 
27 void
28 rdp5_process(STREAM s)
29 {
30 	uint16 length, count, x, y;
31 	uint8 type, ctype;
32 	uint8 *next;
33 
34 	uint32 roff, rlen;
35 	struct stream *ns = &(g_mppc_dict.ns);
36 	struct stream *ts;
37 
38 #if 0
39 	printf("RDP5 data:\n");
40 	hexdump(s->p, s->end - s->p);
41 #endif
42 
43 	ui_begin_update();
44 	while (s->p < s->end)
45 	{
46 		in_uint8(s, type);
47 		if (type & RDP5_COMPRESSED)
48 		{
49 			in_uint8(s, ctype);
50 			in_uint16_le(s, length);
51 			type ^= RDP5_COMPRESSED;
52 		}
53 		else
54 		{
55 			ctype = 0;
56 			in_uint16_le(s, length);
57 		}
58 		g_next_packet = next = s->p + length;
59 
60 		if (ctype & RDP_MPPC_COMPRESSED)
61 		{
62 			if (mppc_expand(s->p, length, ctype, &roff, &rlen) == -1)
63 				error("error while decompressing packet\n");
64 
65 			/* allocate memory and copy the uncompressed data into the temporary stream */
66 			ns->data = (uint8 *) xrealloc(ns->data, rlen);
67 
68 			memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
69 
70 			ns->size = rlen;
71 			ns->end = (ns->data + ns->size);
72 			ns->p = ns->data;
73 			ns->rdp_hdr = ns->p;
74 
75 			ts = ns;
76 		}
77 		else
78 			ts = s;
79 
80 		switch (type)
81 		{
82 			case 0:	/* update orders */
83 				in_uint16_le(ts, count);
84 				process_orders(ts, count);
85 				break;
86 			case 1:	/* update bitmap */
87 				in_uint8s(ts, 2);	/* part length */
88 				process_bitmap_updates(ts);
89 				break;
90 			case 2:	/* update palette */
91 				in_uint8s(ts, 2);	/* uint16 = 2 */
92 				process_palette(ts);
93 				break;
94 			case 3:	/* update synchronize */
95 				break;
96 			case 5:	/* null pointer */
97 				ui_set_null_cursor();
98 				break;
99 			case 6:	/* default pointer */
100 				break;
101 			case 8:	/* pointer position */
102 				in_uint16_le(ts, x);
103 				in_uint16_le(ts, y);
104 				if (s_check(ts))
105 					ui_move_pointer(x, y);
106 				break;
107 			case 9:	/* color pointer */
108 				process_colour_pointer_pdu(ts);
109 				break;
110 			case 10:	/* cached pointer */
111 				process_cached_pointer_pdu(ts);
112 				break;
113 			case 11:
114 				process_new_pointer_pdu(ts);
115 				break;
116 			default:
117 				unimpl("RDP5 opcode %d\n", type);
118 		}
119 
120 		s->p = next;
121 	}
122 	ui_end_update();
123 }
124