[CRT] Massively improve performance of rand_s
[reactos.git] / 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 <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 }