/[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 82 - (hide annotations)
Tue Jul 30 07:18:48 2002 UTC (21 years, 10 months ago) by astrand
File MIME type: text/plain
File size: 16761 byte(s)
Changed max line length to 100

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

  ViewVC Help
Powered by ViewVC 1.1.26