/[rdesktop]/sourceforge.net/trunk/rdesktop/rdp.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /sourceforge.net/trunk/rdesktop/rdp.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 314 - (hide annotations)
Fri Feb 7 23:43:37 2003 UTC (21 years, 3 months ago) by jsorg71
File MIME type: text/plain
File size: 17191 byte(s)
one bitmap decomp function to handle all colour depths

1 matty 3 /*
2     rdesktop: A Remote Desktop Protocol client.
3     Protocol services - RDP layer
4 matthewc 207 Copyright (C) Matthew Chapman 1999-2002
5 matty 3
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10    
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14     GNU General Public License for more details.
15    
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19     */
20    
21 matty 10 #include "rdesktop.h"
22 matty 3
23 matty 10 extern uint16 mcs_userid;
24     extern char username[16];
25 matty 28 extern BOOL bitmap_compression;
26 matty 10 extern BOOL orders;
27 matty 30 extern BOOL encryption;
28 matty 28 extern BOOL desktop_save;
29 matty 3
30 matty 28 uint8 *next_packet;
31 matty 10 uint32 rdp_shareid;
32 matty 3
33 matty 10 /* Initialise an RDP packet */
34 matty 25 static STREAM
35     rdp_init(int maxlen)
36 matty 3 {
37 matty 10 STREAM s;
38 matty 3
39 matty 30 s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 6);
40 matty 10 s_push_layer(s, rdp_hdr, 6);
41 matty 9
42 matty 10 return s;
43 matty 9 }
44    
45 matty 10 /* Send an RDP packet */
46 matty 25 static void
47     rdp_send(STREAM s, uint8 pdu_type)
48 matty 3 {
49 matty 10 uint16 length;
50 matty 3
51 matty 10 s_pop_layer(s, rdp_hdr);
52     length = s->end - s->p;
53 matty 3
54 matty 10 out_uint16_le(s, length);
55 matty 24 out_uint16_le(s, (pdu_type | 0x10)); /* Version 1 */
56 matty 10 out_uint16_le(s, (mcs_userid + 1001));
57 matty 3
58 matty 30 sec_send(s, encryption ? SEC_ENCRYPT : 0);
59 matty 3 }
60    
61 matty 10 /* Receive an RDP packet */
62 matty 25 static STREAM
63 astrand 64 rdp_recv(uint8 * type)
64 matty 3 {
65 matty 10 static STREAM rdp_s;
66     uint16 length, pdu_type;
67 matty 3
68 matty 10 if ((rdp_s == NULL) || (next_packet >= rdp_s->end))
69     {
70     rdp_s = sec_recv();
71     if (rdp_s == NULL)
72     return NULL;
73 matty 3
74 matty 10 next_packet = rdp_s->p;
75     }
76     else
77 matty 7 {
78 matty 10 rdp_s->p = next_packet;
79 matty 7 }
80    
81 matty 10 in_uint16_le(rdp_s, length);
82 jsorg71 283 /* 32k packets are really 8, keepalive fix */
83     if (length == 0x8000)
84     {
85     next_packet += 8;
86     *type = 0;
87     return rdp_s;
88     }
89 matty 10 in_uint16_le(rdp_s, pdu_type);
90 matty 24 in_uint8s(rdp_s, 2); /* userid */
91 matty 10 *type = pdu_type & 0xf;
92 matty 7
93 matty 30 #if WITH_DEBUG
94     DEBUG(("RDP packet (type %x):\n", *type));
95 matty 28 hexdump(next_packet, length);
96     #endif /* */
97 matty 7
98 matty 28 next_packet += length;
99 matty 10 return rdp_s;
100 matty 3 }
101    
102 matty 10 /* Initialise an RDP data packet */
103 matty 25 static STREAM
104     rdp_init_data(int maxlen)
105 matty 3 {
106 matty 10 STREAM s;
107 matty 3
108 matty 30 s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 18);
109 matty 10 s_push_layer(s, rdp_hdr, 18);
110    
111     return s;
112 matty 3 }
113    
114 matty 10 /* Send an RDP data packet */
115 matty 25 static void
116     rdp_send_data(STREAM s, uint8 data_pdu_type)
117 matty 9 {
118 matty 10 uint16 length;
119 matty 9
120 matty 10 s_pop_layer(s, rdp_hdr);
121     length = s->end - s->p;
122 matty 9
123 matty 10 out_uint16_le(s, length);
124     out_uint16_le(s, (RDP_PDU_DATA | 0x10));
125     out_uint16_le(s, (mcs_userid + 1001));
126 matty 9
127 matty 10 out_uint32_le(s, rdp_shareid);
128 matty 24 out_uint8(s, 0); /* pad */
129     out_uint8(s, 1); /* streamid */
130 n-ki 176 out_uint16_le(s, (length - 14));
131 matty 10 out_uint8(s, data_pdu_type);
132 matty 24 out_uint8(s, 0); /* compress_type */
133     out_uint16(s, 0); /* compress_len */
134 matty 3
135 matty 30 sec_send(s, encryption ? SEC_ENCRYPT : 0);
136 matty 3 }
137    
138 matty 10 /* Output a string in Unicode */
139 matty 25 void
140     rdp_out_unistr(STREAM s, char *string, int len)
141 matty 3 {
142 matty 10 int i = 0, j = 0;
143 matty 9
144 matty 10 len += 2;
145 matty 9
146 matty 10 while (i < len)
147 matty 9 {
148 matty 10 s->p[i++] = string[j++];
149     s->p[i++] = 0;
150 matty 9 }
151    
152 matty 10 s->p += len;
153 matty 3 }
154    
155 matty 10 /* Parse a logon info packet */
156 matty 25 static void
157     rdp_send_logon_info(uint32 flags, char *domain, char *user,
158     char *password, char *program, char *directory)
159 matty 3 {
160 matty 24 int len_domain = 2 * strlen(domain);
161     int len_user = 2 * strlen(user);
162     int len_password = 2 * strlen(password);
163     int len_program = 2 * strlen(program);
164 matty 10 int len_directory = 2 * strlen(directory);
165 astrand 82 uint32 sec_flags = encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
166 matty 10 STREAM s;
167 matty 3
168 matty 10 s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
169 matty 24 + len_program + len_directory + 10);
170 matty 3
171 matty 10 out_uint32(s, 0);
172     out_uint32_le(s, flags);
173     out_uint16_le(s, len_domain);
174     out_uint16_le(s, len_user);
175     out_uint16_le(s, len_password);
176     out_uint16_le(s, len_program);
177     out_uint16_le(s, len_directory);
178 matty 24 rdp_out_unistr(s, domain, len_domain);
179     rdp_out_unistr(s, user, len_user);
180     rdp_out_unistr(s, password, len_password);
181     rdp_out_unistr(s, program, len_program);
182 matty 10 rdp_out_unistr(s, directory, len_directory);
183 matty 3
184 matty 10 s_mark_end(s);
185     sec_send(s, sec_flags);
186 matty 3 }
187    
188 matty 10 /* Send a control PDU */
189 matty 25 static void
190     rdp_send_control(uint16 action)
191 matty 3 {
192 matty 10 STREAM s;
193 matty 9
194 matty 10 s = rdp_init_data(8);
195 matty 9
196 matty 10 out_uint16_le(s, action);
197 matty 24 out_uint16(s, 0); /* userid */
198     out_uint32(s, 0); /* control id */
199 matty 9
200 matty 10 s_mark_end(s);
201     rdp_send_data(s, RDP_DATA_PDU_CONTROL);
202 matty 3 }
203    
204 matty 10 /* Send a synchronisation PDU */
205 matty 25 static void
206 matthewc 192 rdp_send_synchronise(void)
207 matty 3 {
208 matty 10 STREAM s;
209 matty 9
210 matty 10 s = rdp_init_data(4);
211 matty 9
212 matty 24 out_uint16_le(s, 1); /* type */
213 matty 10 out_uint16_le(s, 1002);
214 matty 9
215 matty 10 s_mark_end(s);
216     rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);
217 matty 3 }
218    
219 matty 10 /* Send a single input event */
220 matty 25 void
221 astrand 82 rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
222 matty 3 {
223 matty 10 STREAM s;
224 matty 9
225 matty 10 s = rdp_init_data(16);
226 matty 9
227 matty 24 out_uint16_le(s, 1); /* number of events */
228     out_uint16(s, 0); /* pad */
229 matty 9
230 matty 10 out_uint32_le(s, time);
231     out_uint16_le(s, message_type);
232     out_uint16_le(s, device_flags);
233     out_uint16_le(s, param1);
234     out_uint16_le(s, param2);
235 matty 9
236 matty 10 s_mark_end(s);
237     rdp_send_data(s, RDP_DATA_PDU_INPUT);
238 matty 3 }
239    
240 matty 10 /* Send an (empty) font information PDU */
241 matty 25 static void
242     rdp_send_fonts(uint16 seq)
243 matty 3 {
244 matty 10 STREAM s;
245 matty 3
246 matty 10 s = rdp_init_data(8);
247 matty 9
248 matty 10 out_uint16(s, 0); /* number of fonts */
249     out_uint16_le(s, 0x3e); /* unknown */
250     out_uint16_le(s, seq); /* unknown */
251     out_uint16_le(s, 0x32); /* entry size */
252 matty 9
253 matty 10 s_mark_end(s);
254     rdp_send_data(s, RDP_DATA_PDU_FONT2);
255 matty 3 }
256    
257 matty 10 /* Output general capability set */
258 matty 25 static void
259     rdp_out_general_caps(STREAM s)
260 matty 3 {
261 matty 10 out_uint16_le(s, RDP_CAPSET_GENERAL);
262     out_uint16_le(s, RDP_CAPLEN_GENERAL);
263 matty 3
264 matty 10 out_uint16_le(s, 1); /* OS major type */
265     out_uint16_le(s, 3); /* OS minor type */
266 matty 24 out_uint16_le(s, 0x200); /* Protocol version */
267 matty 10 out_uint16(s, 0); /* Pad */
268     out_uint16(s, 0); /* Compression types */
269     out_uint16(s, 0); /* Pad */
270     out_uint16(s, 0); /* Update capability */
271     out_uint16(s, 0); /* Remote unshare capability */
272     out_uint16(s, 0); /* Compression level */
273     out_uint16(s, 0); /* Pad */
274 matty 3 }
275    
276 matty 10 /* Output bitmap capability set */
277 matty 25 static void
278     rdp_out_bitmap_caps(STREAM s)
279 matty 9 {
280 matty 10 out_uint16_le(s, RDP_CAPSET_BITMAP);
281     out_uint16_le(s, RDP_CAPLEN_BITMAP);
282 matty 9
283 matty 10 out_uint16_le(s, 8); /* Preferred BPP */
284 n-ki 176 out_uint16_le(s, 1); /* Receive 1 BPP */
285     out_uint16_le(s, 1); /* Receive 4 BPP */
286 matty 10 out_uint16_le(s, 1); /* Receive 8 BPP */
287     out_uint16_le(s, 800); /* Desktop width */
288     out_uint16_le(s, 600); /* Desktop height */
289     out_uint16(s, 0); /* Pad */
290     out_uint16(s, 0); /* Allow resize */
291 matty 28 out_uint16_le(s, bitmap_compression ? 1 : 0); /* Support compression */
292 matty 10 out_uint16(s, 0); /* Unknown */
293     out_uint16_le(s, 1); /* Unknown */
294     out_uint16(s, 0); /* Pad */
295 matty 9 }
296    
297 matty 10 /* Output order capability set */
298 matty 25 static void
299     rdp_out_order_caps(STREAM s)
300 matty 3 {
301 matty 10 uint8 order_caps[32];
302 matty 3
303 matty 9
304 matty 28 memset(order_caps, 0, 32);
305     order_caps[0] = 1; /* dest blt */
306     order_caps[1] = 1; /* pat blt */
307     order_caps[2] = 1; /* screen blt */
308 matthewc 161 order_caps[3] = 1; /* required for memblt? */
309 matty 28 order_caps[8] = 1; /* line */
310     order_caps[9] = 1; /* line */
311     order_caps[10] = 1; /* rect */
312     order_caps[11] = (desktop_save == False ? 0 : 1); /* desksave */
313     order_caps[13] = 1; /* memblt */
314     order_caps[14] = 1; /* triblt */
315     order_caps[22] = 1; /* polyline */
316     order_caps[27] = 1; /* text2 */
317 matty 10 out_uint16_le(s, RDP_CAPSET_ORDER);
318     out_uint16_le(s, RDP_CAPLEN_ORDER);
319 matty 9
320 matty 10 out_uint8s(s, 20); /* Terminal desc, pad */
321     out_uint16_le(s, 1); /* Cache X granularity */
322     out_uint16_le(s, 20); /* Cache Y granularity */
323     out_uint16(s, 0); /* Pad */
324     out_uint16_le(s, 1); /* Max order level */
325     out_uint16_le(s, 0x147); /* Number of fonts */
326 matty 24 out_uint16_le(s, 0x2a); /* Capability flags */
327 matty 10 out_uint8p(s, order_caps, 32); /* Orders supported */
328     out_uint16_le(s, 0x6a1); /* Text capability flags */
329     out_uint8s(s, 6); /* Pad */
330 n-ki 176 out_uint32_le(s, desktop_save == False ? 0 : 0x38400); /* Desktop cache size */
331 matty 10 out_uint32(s, 0); /* Unknown */
332 n-ki 176 out_uint32_le(s, 0x4e4); /* Unknown */
333 matty 9 }
334    
335 matty 10 /* Output bitmap cache capability set */
336 matty 25 static void
337     rdp_out_bmpcache_caps(STREAM s)
338 matty 9 {
339 matty 10 out_uint16_le(s, RDP_CAPSET_BMPCACHE);
340     out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
341 matty 3
342 matty 24 out_uint8s(s, 24); /* unused */
343     out_uint16_le(s, 0x258); /* entries */
344     out_uint16_le(s, 0x100); /* max cell size */
345     out_uint16_le(s, 0x12c); /* entries */
346     out_uint16_le(s, 0x400); /* max cell size */
347     out_uint16_le(s, 0x106); /* entries */
348     out_uint16_le(s, 0x1000); /* max cell size */
349 matty 9 }
350    
351 matty 10 /* Output control capability set */
352 matty 25 static void
353     rdp_out_control_caps(STREAM s)
354 matty 9 {
355 matty 10 out_uint16_le(s, RDP_CAPSET_CONTROL);
356     out_uint16_le(s, RDP_CAPLEN_CONTROL);
357 matty 9
358 matty 10 out_uint16(s, 0); /* Control capabilities */
359     out_uint16(s, 0); /* Remote detach */
360     out_uint16_le(s, 2); /* Control interest */
361     out_uint16_le(s, 2); /* Detach interest */
362 matty 9 }
363    
364 matty 10 /* Output activation capability set */
365 matty 25 static void
366     rdp_out_activate_caps(STREAM s)
367 matty 9 {
368 matty 10 out_uint16_le(s, RDP_CAPSET_ACTIVATE);
369     out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
370 matty 9
371 matty 10 out_uint16(s, 0); /* Help key */
372     out_uint16(s, 0); /* Help index key */
373     out_uint16(s, 0); /* Extended help key */
374     out_uint16(s, 0); /* Window activate */
375 matty 9 }
376    
377 matty 10 /* Output pointer capability set */
378 matty 25 static void
379     rdp_out_pointer_caps(STREAM s)
380 matty 9 {
381 matty 10 out_uint16_le(s, RDP_CAPSET_POINTER);
382     out_uint16_le(s, RDP_CAPLEN_POINTER);
383 matty 9
384 matty 10 out_uint16(s, 0); /* Colour pointer */
385     out_uint16_le(s, 20); /* Cache size */
386 matty 9 }
387    
388 matty 10 /* Output share capability set */
389 matty 25 static void
390     rdp_out_share_caps(STREAM s)
391 matty 3 {
392 matty 10 out_uint16_le(s, RDP_CAPSET_SHARE);
393     out_uint16_le(s, RDP_CAPLEN_SHARE);
394 matty 3
395 matty 10 out_uint16(s, 0); /* userid */
396     out_uint16(s, 0); /* pad */
397 matty 9 }
398 matty 3
399 matty 10 /* Output colour cache capability set */
400 matty 25 static void
401     rdp_out_colcache_caps(STREAM s)
402 matty 9 {
403 matty 10 out_uint16_le(s, RDP_CAPSET_COLCACHE);
404     out_uint16_le(s, RDP_CAPLEN_COLCACHE);
405 matty 3
406 matty 10 out_uint16_le(s, 6); /* cache size */
407     out_uint16(s, 0); /* pad */
408 matty 3 }
409    
410 matty 10 static uint8 canned_caps[] = {
411 matty 24 0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,
412     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
413 matty 25 0x00, 0x00, 0x00, 0x00, 0x00,
414 matty 24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
415 matty 25 0x00, 0x00, 0x00, 0x00, 0x00,
416 matty 24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
417 matty 25 0x00, 0x00, 0x00, 0x00, 0x00,
418 matty 24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
419 matty 25 0x00, 0x00, 0x00, 0x00, 0x00,
420 matty 24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
421 matty 25 0x0C, 0x00, 0x08, 0x00, 0x01,
422 matty 24 0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
423 matty 25 0x10, 0x00, 0x34, 0x00, 0xFE,
424 matty 24 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,
425 matty 25 0xFE, 0x00, 0x08, 0x00, 0xFE,
426 matty 24 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,
427 matty 25 0xFE, 0x00, 0x80, 0x00, 0xFE,
428 matty 24 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
429 matty 25 0x02, 0x00, 0x00, 0x00
430 matty 10 };
431 matty 3
432 matty 10 /* Output unknown capability set */
433 matty 25 static void
434     rdp_out_unknown_caps(STREAM s)
435 matty 3 {
436 matty 10 out_uint16_le(s, RDP_CAPSET_UNKNOWN);
437     out_uint16_le(s, 0x58);
438 matty 24
439     out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);
440 matty 3 }
441    
442 matty 10 /* Send a confirm active PDU */
443 matty 25 static void
444 matthewc 192 rdp_send_confirm_active(void)
445 matty 7 {
446 matty 10 STREAM s;
447 matty 24 uint16 caplen =
448     RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
449     RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
450     RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
451 astrand 82 RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;
452 matty 7
453 matty 10 s = rdp_init(14 + caplen + sizeof(RDP_SOURCE));
454 matty 9
455 matty 10 out_uint32_le(s, rdp_shareid);
456 matty 24 out_uint16_le(s, 0x3ea); /* userid */
457 matty 10 out_uint16_le(s, sizeof(RDP_SOURCE));
458     out_uint16_le(s, caplen);
459 matty 9
460 matty 10 out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
461 matty 24 out_uint16_le(s, 0xd); /* num_caps */
462     out_uint8s(s, 2); /* pad */
463 matty 9
464 matty 10 rdp_out_general_caps(s);
465     rdp_out_bitmap_caps(s);
466     rdp_out_order_caps(s);
467     rdp_out_bmpcache_caps(s);
468     rdp_out_colcache_caps(s);
469     rdp_out_activate_caps(s);
470     rdp_out_control_caps(s);
471     rdp_out_pointer_caps(s);
472     rdp_out_share_caps(s);
473     rdp_out_unknown_caps(s);
474 matty 9
475 matty 10 s_mark_end(s);
476     rdp_send(s, RDP_PDU_CONFIRM_ACTIVE);
477 matty 9 }
478    
479 matty 10 /* Respond to a demand active PDU */
480 matty 25 static void
481     process_demand_active(STREAM s)
482 matty 9 {
483 matty 10 uint8 type;
484 matty 9
485 matty 10 in_uint32_le(s, rdp_shareid);
486 matty 9
487 matty 30 DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", rdp_shareid));
488 matty 9
489 matty 10 rdp_send_confirm_active();
490     rdp_send_synchronise();
491     rdp_send_control(RDP_CTL_COOPERATE);
492     rdp_send_control(RDP_CTL_REQUEST_CONTROL);
493 matty 28 rdp_recv(&type); /* RDP_PDU_SYNCHRONIZE */
494     rdp_recv(&type); /* RDP_CTL_COOPERATE */
495     rdp_recv(&type); /* RDP_CTL_GRANT_CONTROL */
496 matty 10 rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, 0, 0);
497     rdp_send_fonts(1);
498     rdp_send_fonts(2);
499 matty 28 rdp_recv(&type); /* RDP_PDU_UNKNOWN 0x28 */
500 matty 10 reset_order_state();
501 matty 9 }
502    
503 matty 10 /* Process a pointer PDU */
504 matty 25 static void
505     process_pointer_pdu(STREAM s)
506 matty 9 {
507 matty 10 uint16 message_type;
508 matty 28 uint16 x, y, width, height, cache_idx, masklen, datalen;
509     uint8 *mask, *data;
510     HCURSOR cursor;
511 matty 9
512 matty 10 in_uint16_le(s, message_type);
513 matty 24 in_uint8s(s, 2); /* pad */
514 matty 9
515 matty 10 switch (message_type)
516 matty 7 {
517 matty 10 case RDP_POINTER_MOVE:
518     in_uint16_le(s, x);
519     in_uint16_le(s, y);
520     if (s_check(s))
521     ui_move_pointer(x, y);
522     break;
523 matty 9
524 matty 28 case RDP_POINTER_COLOR:
525     in_uint16_le(s, cache_idx);
526     in_uint16_le(s, x);
527     in_uint16_le(s, y);
528     in_uint16_le(s, width);
529     in_uint16_le(s, height);
530     in_uint16_le(s, masklen);
531     in_uint16_le(s, datalen);
532     in_uint8p(s, data, datalen);
533     in_uint8p(s, mask, masklen);
534 astrand 82 cursor = ui_create_cursor(x, y, width, height, mask, data);
535 matty 28 ui_set_cursor(cursor);
536     cache_put_cursor(cache_idx, cursor);
537     break;
538    
539     case RDP_POINTER_CACHED:
540     in_uint16_le(s, cache_idx);
541     ui_set_cursor(cache_get_cursor(cache_idx));
542     break;
543    
544 matty 10 default:
545 matty 30 DEBUG(("Pointer message 0x%x\n", message_type));
546 matty 7 }
547 matty 9 }
548    
549 matty 10 /* Process bitmap updates */
550 matty 25 static void
551     process_bitmap_updates(STREAM s)
552 matty 9 {
553 matty 10 uint16 num_updates;
554     uint16 left, top, right, bottom, width, height;
555 jsorg71 314 uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
556 matty 28 uint8 *data, *bmpdata;
557 matty 9 int i;
558    
559 matty 10 in_uint16_le(s, num_updates);
560 matty 9
561 matty 10 for (i = 0; i < num_updates; i++)
562 matty 9 {
563 matty 10 in_uint16_le(s, left);
564     in_uint16_le(s, top);
565     in_uint16_le(s, right);
566     in_uint16_le(s, bottom);
567     in_uint16_le(s, width);
568     in_uint16_le(s, height);
569     in_uint16_le(s, bpp);
570 jsorg71 314 Bpp = (bpp + 7) / 8;
571 matty 10 in_uint16_le(s, compress);
572     in_uint16_le(s, bufsize);
573 matty 9
574 matty 10 cx = right - left + 1;
575     cy = bottom - top + 1;
576 matty 7
577 matty 30 DEBUG(("UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,cmp=%d)\n",
578     left, top, right, bottom, width, height, compress));
579 matty 9
580 matty 10 if (!compress)
581     {
582 matty 28 int y;
583 jsorg71 314 bmpdata = xmalloc(width * height * Bpp);
584 matty 28 for (y = 0; y < height; y++)
585     {
586 jsorg71 314 in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)], width * Bpp);
587 matty 28 }
588 astrand 82 ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
589 matty 28 xfree(bmpdata);
590     continue;
591 matty 10 }
592 matty 9
593 matty 24 in_uint8s(s, 2); /* pad */
594 matty 10 in_uint16_le(s, size);
595 matty 24 in_uint8s(s, 4); /* line_size, final_size */
596 matty 10 in_uint8p(s, data, size);
597 jsorg71 314 bmpdata = xmalloc(width * height * Bpp);
598     if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
599 matty 9 {
600 astrand 82 ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
601 matty 9 }
602 matty 28 xfree(bmpdata);
603 matty 10 }
604 matty 9 }
605    
606 matty 10 /* Process a palette update */
607 matty 25 static void
608     process_palette(STREAM s)
609 matty 9 {
610 matthewc 254 COLOURENTRY *entry;
611     COLOURMAP map;
612 matty 10 HCOLOURMAP hmap;
613 matthewc 254 int i;
614 matty 9
615 matty 24 in_uint8s(s, 2); /* pad */
616     in_uint16_le(s, map.ncolours);
617     in_uint8s(s, 2); /* pad */
618 matty 3
619 matthewc 254 map.colours = xmalloc(3 * map.ncolours);
620    
621     for (i = 0; i < map.ncolours; i++)
622     {
623     entry = &map.colours[i];
624     in_uint8(s, entry->red);
625     in_uint8(s, entry->green);
626     in_uint8(s, entry->blue);
627 astrand 260 }
628 matthewc 254
629 matty 10 hmap = ui_create_colourmap(&map);
630     ui_set_colourmap(hmap);
631 matthewc 254
632     xfree(map.colours);
633 matty 3 }
634    
635 matty 10 /* Process an update PDU */
636 matty 25 static void
637     process_update_pdu(STREAM s)
638 matty 9 {
639 matty 10 uint16 update_type;
640 matty 9
641 matty 10 in_uint16_le(s, update_type);
642 matty 3
643 matty 10 switch (update_type)
644 matty 3 {
645 matty 10 case RDP_UPDATE_ORDERS:
646     process_orders(s);
647     break;
648 matty 3
649 matty 10 case RDP_UPDATE_BITMAP:
650     process_bitmap_updates(s);
651     break;
652 matty 3
653 matty 10 case RDP_UPDATE_PALETTE:
654     process_palette(s);
655     break;
656 matty 3
657 matty 10 case RDP_UPDATE_SYNCHRONIZE:
658     break;
659 matty 9
660 matty 10 default:
661 matty 30 unimpl("update %d\n", update_type);
662 matty 3 }
663    
664     }
665    
666 matty 10 /* Process data PDU */
667 matty 25 static void
668     process_data_pdu(STREAM s)
669 matty 9 {
670 matty 10 uint8 data_pdu_type;
671 matty 9
672 matty 24 in_uint8s(s, 8); /* shareid, pad, streamid, length */
673 matty 10 in_uint8(s, data_pdu_type);
674 matty 24 in_uint8s(s, 3); /* compress_type, compress_len */
675 matty 3
676 matty 10 switch (data_pdu_type)
677 matty 3 {
678 matty 10 case RDP_DATA_PDU_UPDATE:
679     process_update_pdu(s);
680     break;
681 matty 3
682 matty 10 case RDP_DATA_PDU_POINTER:
683     process_pointer_pdu(s);
684     break;
685 matty 3
686 matty 10 case RDP_DATA_PDU_BELL:
687     ui_bell();
688     break;
689 matty 3
690 matty 10 case RDP_DATA_PDU_LOGON:
691     /* User logged on */
692     break;
693 matty 3
694 matty 10 default:
695 matty 30 unimpl("data PDU %d\n", data_pdu_type);
696 matty 3 }
697     }
698    
699 matty 10 /* Process incoming packets */
700 matty 25 void
701 matthewc 192 rdp_main_loop(void)
702 matty 9 {
703 matty 10 uint8 type;
704     STREAM s;
705 matty 9
706 matty 10 while ((s = rdp_recv(&type)) != NULL)
707 matty 3 {
708 matty 10 switch (type)
709     {
710     case RDP_PDU_DEMAND_ACTIVE:
711     process_demand_active(s);
712     break;
713 matty 3
714 matty 10 case RDP_PDU_DEACTIVATE:
715     break;
716 matty 3
717 matty 10 case RDP_PDU_DATA:
718     process_data_pdu(s);
719     break;
720 matty 3
721 jsorg71 283 case 0:
722     break;
723    
724 matty 10 default:
725 matty 30 unimpl("PDU %d\n", type);
726 matty 10 }
727 matty 3 }
728     }
729    
730 matty 10 /* Establish a connection up to the RDP layer */
731 matty 25 BOOL
732     rdp_connect(char *server, uint32 flags, char *domain, char *password,
733     char *command, char *directory)
734 matty 9 {
735 matty 10 if (!sec_connect(server))
736 matty 3 return False;
737    
738 astrand 82 rdp_send_logon_info(flags, domain, username, password, command, directory);
739 matty 10 return True;
740 matty 3 }
741    
742 matty 10 /* Disconnect from the RDP layer */
743 matty 25 void
744 matthewc 192 rdp_disconnect(void)
745 matty 9 {
746 matty 10 sec_disconnect();
747 matty 9 }

  ViewVC Help
Powered by ViewVC 1.1.26