/[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 28 - (hide annotations)
Wed Jun 20 13:54:48 2001 UTC (22 years, 11 months ago) by matty
File MIME type: text/plain
File size: 16784 byte(s)
Merges from pl19-6-5.

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

  ViewVC Help
Powered by ViewVC 1.1.26