/[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 340 - (hide annotations)
Thu Mar 6 14:11:17 2003 UTC (21 years, 2 months ago) by forsberg
File MIME type: text/plain
File size: 17263 byte(s)
If WITH_DEBUG, print the number of the packet just received, which makes
it easier to follow the packet on the network.

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

  ViewVC Help
Powered by ViewVC 1.1.26