/[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 708 - (hide annotations)
Fri Jun 4 15:01:36 2004 UTC (19 years, 11 months ago) by jsorg71
File MIME type: text/plain
File size: 25378 byte(s)
warnings when screen size of depth change and backstore resizeing when screen size changes

1 forsberg 351 /* -*- c-basic-offset: 8 -*-
2 matty 3 rdesktop: A Remote Desktop Protocol client.
3     Protocol services - RDP layer
4 matthewc 207 Copyright (C) Matthew Chapman 1999-2002
5 jsorg71 433
6 matty 3 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 jsorg71 433
11 matty 3 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 jsorg71 433
16 matty 3 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 stargo 562 #include <time.h>
22 matty 10 #include "rdesktop.h"
23 matty 3
24 jsorg71 381 extern uint16 g_mcs_userid;
25 jsorg71 437 extern char g_username[16];
26     extern BOOL g_bitmap_compression;
27     extern BOOL g_orders;
28     extern BOOL g_encryption;
29 jsorg71 438 extern BOOL g_desktop_save;
30     extern BOOL g_use_rdp5;
31     extern uint16 g_server_rdp_version;
32 stargo 637 extern uint32 g_rdp5_performanceflags;
33 jsorg71 438 extern int g_server_bpp;
34 n-ki 677 extern int g_width;
35     extern int g_height;
36 jsorg71 678 extern BOOL g_bitmap_cache;
37 matty 3
38 jsorg71 438 uint8 *g_next_packet;
39     uint32 g_rdp_shareid;
40 matty 3
41 n-ki 687 extern RDPCOMP g_mppc_dict;
42 n-ki 683
43 forsberg 340 #if WITH_DEBUG
44 jsorg71 438 static uint32 g_packetno;
45 forsberg 351 #endif
46 forsberg 340
47 matty 10 /* Receive an RDP packet */
48 matty 25 static STREAM
49 astrand 64 rdp_recv(uint8 * type)
50 matty 3 {
51 matty 10 static STREAM rdp_s;
52     uint16 length, pdu_type;
53 matty 3
54 jsorg71 438 if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))
55 matty 10 {
56     rdp_s = sec_recv();
57     if (rdp_s == NULL)
58     return NULL;
59 matty 3
60 jsorg71 438 g_next_packet = rdp_s->p;
61 matty 10 }
62     else
63 matty 7 {
64 jsorg71 438 rdp_s->p = g_next_packet;
65 matty 7 }
66    
67 matty 10 in_uint16_le(rdp_s, length);
68 jsorg71 283 /* 32k packets are really 8, keepalive fix */
69     if (length == 0x8000)
70     {
71 jsorg71 438 g_next_packet += 8;
72 jsorg71 283 *type = 0;
73     return rdp_s;
74     }
75 matty 10 in_uint16_le(rdp_s, pdu_type);
76 matty 24 in_uint8s(rdp_s, 2); /* userid */
77 matty 10 *type = pdu_type & 0xf;
78 matty 7
79 matty 30 #if WITH_DEBUG
80 jsorg71 438 DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type));
81 matthewc 513 hexdump(g_next_packet, length);
82 matty 28 #endif /* */
83 matty 7
84 jsorg71 438 g_next_packet += length;
85 matty 10 return rdp_s;
86 matty 3 }
87    
88 matty 10 /* Initialise an RDP data packet */
89 matty 25 static STREAM
90     rdp_init_data(int maxlen)
91 matty 3 {
92 matty 10 STREAM s;
93 matty 3
94 jsorg71 437 s = sec_init(g_encryption ? SEC_ENCRYPT : 0, maxlen + 18);
95 matty 10 s_push_layer(s, rdp_hdr, 18);
96    
97     return s;
98 matty 3 }
99    
100 matty 10 /* Send an RDP data packet */
101 matty 25 static void
102     rdp_send_data(STREAM s, uint8 data_pdu_type)
103 matty 9 {
104 matty 10 uint16 length;
105 matty 9
106 matty 10 s_pop_layer(s, rdp_hdr);
107     length = s->end - s->p;
108 matty 9
109 matty 10 out_uint16_le(s, length);
110     out_uint16_le(s, (RDP_PDU_DATA | 0x10));
111 jsorg71 381 out_uint16_le(s, (g_mcs_userid + 1001));
112 matty 9
113 jsorg71 438 out_uint32_le(s, g_rdp_shareid);
114 matty 24 out_uint8(s, 0); /* pad */
115     out_uint8(s, 1); /* streamid */
116 n-ki 176 out_uint16_le(s, (length - 14));
117 matty 10 out_uint8(s, data_pdu_type);
118 matty 24 out_uint8(s, 0); /* compress_type */
119     out_uint16(s, 0); /* compress_len */
120 matty 3
121 jsorg71 437 sec_send(s, g_encryption ? SEC_ENCRYPT : 0);
122 matty 3 }
123    
124 matty 10 /* Output a string in Unicode */
125 matty 25 void
126     rdp_out_unistr(STREAM s, char *string, int len)
127 matty 3 {
128 matty 10 int i = 0, j = 0;
129 matty 9
130 matty 10 len += 2;
131 matty 9
132 matty 10 while (i < len)
133 matty 9 {
134 matty 10 s->p[i++] = string[j++];
135     s->p[i++] = 0;
136 matty 9 }
137    
138 matty 10 s->p += len;
139 matty 3 }
140    
141 n-ki 569 /* Input a string in Unicode
142     *
143     * Returns str_len of string
144     */
145     int
146     rdp_in_unistr(STREAM s, char *string, int uni_len)
147     {
148     int i = 0;
149    
150     while (i < uni_len / 2)
151     {
152     in_uint8a(s, &string[i++], 1);
153     in_uint8s(s, 1);
154     }
155    
156     return i - 1;
157     }
158    
159    
160 matty 10 /* Parse a logon info packet */
161 matty 25 static void
162     rdp_send_logon_info(uint32 flags, char *domain, char *user,
163     char *password, char *program, char *directory)
164 matty 3 {
165 n-ki 624 char *ipaddr = tcp_get_address();
166 matty 24 int len_domain = 2 * strlen(domain);
167     int len_user = 2 * strlen(user);
168     int len_password = 2 * strlen(password);
169     int len_program = 2 * strlen(program);
170 matty 10 int len_directory = 2 * strlen(directory);
171 n-ki 624 int len_ip = 2 * strlen(ipaddr);
172 forsberg 371 int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
173     int packetlen = 0;
174 jsorg71 437 uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
175 matty 10 STREAM s;
176 stargo 562 time_t t = time(NULL);
177     time_t tzone;
178 matty 3
179 n-ki 687 #if 0
180     /* enable rdp compression */
181     /* some problems still exist with rdp5 */
182     flags |= RDP_COMPRESSION;
183     #endif
184    
185 jsorg71 438 if (!g_use_rdp5 || 1 == g_server_rdp_version)
186 forsberg 351 {
187     DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
188 matty 3
189 forsberg 351 s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
190     + len_program + len_directory + 10);
191 matty 3
192 forsberg 351 out_uint32(s, 0);
193     out_uint32_le(s, flags);
194     out_uint16_le(s, len_domain);
195     out_uint16_le(s, len_user);
196     out_uint16_le(s, len_password);
197     out_uint16_le(s, len_program);
198     out_uint16_le(s, len_directory);
199     rdp_out_unistr(s, domain, len_domain);
200     rdp_out_unistr(s, user, len_user);
201     rdp_out_unistr(s, password, len_password);
202     rdp_out_unistr(s, program, len_program);
203     rdp_out_unistr(s, directory, len_directory);
204     }
205     else
206     {
207 n-ki 683
208 forsberg 371 flags |= RDP_LOGON_BLOB;
209 forsberg 351 DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
210 astrand 540 packetlen = 4 + /* Unknown uint32 */
211     4 + /* flags */
212     2 + /* len_domain */
213     2 + /* len_user */
214     (flags & RDP_LOGON_AUTO ? 2 : 0) + /* len_password */
215     (flags & RDP_LOGON_BLOB ? 2 : 0) + /* Length of BLOB */
216     2 + /* len_program */
217     2 + /* len_directory */
218     (0 < len_domain ? len_domain : 2) + /* domain */
219     len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 + /* We have no 512 byte BLOB. Perhaps we must? */
220     (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + /* After the BLOB is a unknown int16. If there is a BLOB, that is. */
221     (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 + /* Unknown (2) */
222     2 + /* Client ip length */
223     len_ip + /* Client ip */
224     2 + /* DLL string length */
225     len_dll + /* DLL string */
226     2 + /* Unknown */
227     2 + /* Unknown */
228     64 + /* Time zone #0 */
229     2 + /* Unknown */
230     64 + /* Time zone #1 */
231     32; /* Unknown */
232 forsberg 410
233     s = sec_init(sec_flags, packetlen);
234 forsberg 371 DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
235 forsberg 351
236 astrand 540 out_uint32(s, 0); /* Unknown */
237 forsberg 351 out_uint32_le(s, flags);
238     out_uint16_le(s, len_domain);
239     out_uint16_le(s, len_user);
240     if (flags & RDP_LOGON_AUTO)
241     {
242     out_uint16_le(s, len_password);
243 forsberg 371
244 forsberg 351 }
245 forsberg 410 if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
246     {
247 forsberg 371 out_uint16_le(s, 0);
248     }
249 forsberg 351 out_uint16_le(s, len_program);
250     out_uint16_le(s, len_directory);
251 forsberg 371 if (0 < len_domain)
252     rdp_out_unistr(s, domain, len_domain);
253 forsberg 410 else
254 forsberg 371 out_uint16_le(s, 0);
255     rdp_out_unistr(s, user, len_user);
256 forsberg 351 if (flags & RDP_LOGON_AUTO)
257     {
258     rdp_out_unistr(s, password, len_password);
259     }
260 forsberg 410 if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
261     {
262 forsberg 371 out_uint16_le(s, 0);
263     }
264 forsberg 410 if (0 < len_program)
265     {
266 forsberg 351 rdp_out_unistr(s, program, len_program);
267 forsberg 410
268     }
269     else
270     {
271 forsberg 371 out_uint16_le(s, 0);
272     }
273 forsberg 410 if (0 < len_directory)
274     {
275 forsberg 351 rdp_out_unistr(s, directory, len_directory);
276 forsberg 410 }
277     else
278     {
279 forsberg 371 out_uint16_le(s, 0);
280 jsorg71 376 }
281 forsberg 371 out_uint16_le(s, 2);
282 astrand 540 out_uint16_le(s, len_ip + 2); /* Length of client ip */
283 n-ki 624 rdp_out_unistr(s, ipaddr, len_ip);
284 forsberg 410 out_uint16_le(s, len_dll + 2);
285 forsberg 371 rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
286 stargo 562
287 stargo 604 tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
288     out_uint32_le(s, tzone);
289 stargo 559
290 forsberg 410 rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
291     out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
292 forsberg 351
293     out_uint32_le(s, 0x0a0000);
294     out_uint32_le(s, 0x050000);
295 forsberg 371 out_uint32_le(s, 3);
296     out_uint32_le(s, 0);
297     out_uint32_le(s, 0);
298 forsberg 351
299 forsberg 410 rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
300     out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
301    
302 forsberg 371 out_uint32_le(s, 0x30000);
303 forsberg 351 out_uint32_le(s, 0x050000);
304     out_uint32_le(s, 2);
305 matthewc 365 out_uint32(s, 0);
306 forsberg 351 out_uint32_le(s, 0xffffffc4);
307     out_uint32_le(s, 0xfffffffe);
308 stargo 637 out_uint32_le(s, g_rdp5_performanceflags);
309 matthewc 365 out_uint32(s, 0);
310 forsberg 351
311 forsberg 371
312 forsberg 351 }
313 matty 10 s_mark_end(s);
314     sec_send(s, sec_flags);
315 matty 3 }
316    
317 matty 10 /* Send a control PDU */
318 matty 25 static void
319     rdp_send_control(uint16 action)
320 matty 3 {
321 matty 10 STREAM s;
322 matty 9
323 matty 10 s = rdp_init_data(8);
324 matty 9
325 matty 10 out_uint16_le(s, action);
326 matty 24 out_uint16(s, 0); /* userid */
327     out_uint32(s, 0); /* control id */
328 matty 9
329 matty 10 s_mark_end(s);
330     rdp_send_data(s, RDP_DATA_PDU_CONTROL);
331 matty 3 }
332    
333 matty 10 /* Send a synchronisation PDU */
334 matty 25 static void
335 matthewc 192 rdp_send_synchronise(void)
336 matty 3 {
337 matty 10 STREAM s;
338 matty 9
339 matty 10 s = rdp_init_data(4);
340 matty 9
341 matty 24 out_uint16_le(s, 1); /* type */
342 matty 10 out_uint16_le(s, 1002);
343 matty 9
344 matty 10 s_mark_end(s);
345     rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);
346 matty 3 }
347    
348 matty 10 /* Send a single input event */
349 matty 25 void
350 astrand 82 rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
351 matty 3 {
352 matty 10 STREAM s;
353 matty 9
354 matty 10 s = rdp_init_data(16);
355 matty 9
356 matty 24 out_uint16_le(s, 1); /* number of events */
357     out_uint16(s, 0); /* pad */
358 matty 9
359 matty 10 out_uint32_le(s, time);
360     out_uint16_le(s, message_type);
361     out_uint16_le(s, device_flags);
362     out_uint16_le(s, param1);
363     out_uint16_le(s, param2);
364 matty 9
365 matty 10 s_mark_end(s);
366     rdp_send_data(s, RDP_DATA_PDU_INPUT);
367 matty 3 }
368    
369 matty 10 /* Send an (empty) font information PDU */
370 matty 25 static void
371     rdp_send_fonts(uint16 seq)
372 matty 3 {
373 matty 10 STREAM s;
374 matty 3
375 matty 10 s = rdp_init_data(8);
376 matty 9
377 matty 10 out_uint16(s, 0); /* number of fonts */
378 n-ki 677 out_uint16_le(s, 0); /* pad? */
379 matty 10 out_uint16_le(s, seq); /* unknown */
380     out_uint16_le(s, 0x32); /* entry size */
381 matty 9
382 matty 10 s_mark_end(s);
383     rdp_send_data(s, RDP_DATA_PDU_FONT2);
384 matty 3 }
385    
386 matty 10 /* Output general capability set */
387 matty 25 static void
388     rdp_out_general_caps(STREAM s)
389 matty 3 {
390 matty 10 out_uint16_le(s, RDP_CAPSET_GENERAL);
391     out_uint16_le(s, RDP_CAPLEN_GENERAL);
392 matty 3
393 matty 10 out_uint16_le(s, 1); /* OS major type */
394     out_uint16_le(s, 3); /* OS minor type */
395 matty 24 out_uint16_le(s, 0x200); /* Protocol version */
396 matty 10 out_uint16(s, 0); /* Pad */
397     out_uint16(s, 0); /* Compression types */
398 jsorg71 438 out_uint16_le(s, g_use_rdp5 ? 0x40d : 0);
399 forsberg 351 /* Pad, according to T.128. 0x40d seems to
400     trigger
401     the server to start sending RDP5 packets.
402     However, the value is 0x1d04 with W2KTSK and
403     NT4MS. Hmm.. Anyway, thankyou, Microsoft,
404     for sending such information in a padding
405     field.. */
406 matty 10 out_uint16(s, 0); /* Update capability */
407     out_uint16(s, 0); /* Remote unshare capability */
408     out_uint16(s, 0); /* Compression level */
409     out_uint16(s, 0); /* Pad */
410 matty 3 }
411    
412 matty 10 /* Output bitmap capability set */
413 matty 25 static void
414     rdp_out_bitmap_caps(STREAM s)
415 matty 9 {
416 matty 10 out_uint16_le(s, RDP_CAPSET_BITMAP);
417     out_uint16_le(s, RDP_CAPLEN_BITMAP);
418 matty 9
419 jsorg71 654 out_uint16_le(s, g_server_bpp); /* Preferred BPP */
420 n-ki 176 out_uint16_le(s, 1); /* Receive 1 BPP */
421     out_uint16_le(s, 1); /* Receive 4 BPP */
422 matty 10 out_uint16_le(s, 1); /* Receive 8 BPP */
423     out_uint16_le(s, 800); /* Desktop width */
424     out_uint16_le(s, 600); /* Desktop height */
425     out_uint16(s, 0); /* Pad */
426 n-ki 677 out_uint16(s, 1); /* Allow resize */
427 jsorg71 437 out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
428 matty 10 out_uint16(s, 0); /* Unknown */
429     out_uint16_le(s, 1); /* Unknown */
430     out_uint16(s, 0); /* Pad */
431 matty 9 }
432    
433 matty 10 /* Output order capability set */
434 matty 25 static void
435     rdp_out_order_caps(STREAM s)
436 matty 3 {
437 matty 10 uint8 order_caps[32];
438 matty 3
439 matty 9
440 matty 28 memset(order_caps, 0, 32);
441     order_caps[0] = 1; /* dest blt */
442     order_caps[1] = 1; /* pat blt */
443     order_caps[2] = 1; /* screen blt */
444 n-ki 683 order_caps[3] = (g_bitmap_cache ? 1 : 0); /* memblt */
445 matty 28 order_caps[8] = 1; /* line */
446     order_caps[9] = 1; /* line */
447     order_caps[10] = 1; /* rect */
448 jsorg71 438 order_caps[11] = (g_desktop_save == False ? 0 : 1); /* desksave */
449 matty 28 order_caps[13] = 1; /* memblt */
450     order_caps[14] = 1; /* triblt */
451     order_caps[22] = 1; /* polyline */
452     order_caps[27] = 1; /* text2 */
453 matty 10 out_uint16_le(s, RDP_CAPSET_ORDER);
454     out_uint16_le(s, RDP_CAPLEN_ORDER);
455 matty 9
456 matty 10 out_uint8s(s, 20); /* Terminal desc, pad */
457     out_uint16_le(s, 1); /* Cache X granularity */
458     out_uint16_le(s, 20); /* Cache Y granularity */
459     out_uint16(s, 0); /* Pad */
460     out_uint16_le(s, 1); /* Max order level */
461     out_uint16_le(s, 0x147); /* Number of fonts */
462 matty 24 out_uint16_le(s, 0x2a); /* Capability flags */
463 matty 10 out_uint8p(s, order_caps, 32); /* Orders supported */
464     out_uint16_le(s, 0x6a1); /* Text capability flags */
465     out_uint8s(s, 6); /* Pad */
466 jsorg71 438 out_uint32_le(s, g_desktop_save == False ? 0 : 0x38400); /* Desktop cache size */
467 matty 10 out_uint32(s, 0); /* Unknown */
468 n-ki 176 out_uint32_le(s, 0x4e4); /* Unknown */
469 matty 9 }
470    
471 matty 10 /* Output bitmap cache capability set */
472 matty 25 static void
473     rdp_out_bmpcache_caps(STREAM s)
474 matty 9 {
475 jsorg71 433 int Bpp;
476 matty 10 out_uint16_le(s, RDP_CAPSET_BMPCACHE);
477     out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
478 matty 3
479 jsorg71 438 Bpp = (g_server_bpp + 7) / 8;
480 matty 24 out_uint8s(s, 24); /* unused */
481     out_uint16_le(s, 0x258); /* entries */
482 jsorg71 433 out_uint16_le(s, 0x100 * Bpp); /* max cell size */
483 matty 24 out_uint16_le(s, 0x12c); /* entries */
484 jsorg71 433 out_uint16_le(s, 0x400 * Bpp); /* max cell size */
485 matty 24 out_uint16_le(s, 0x106); /* entries */
486 jsorg71 433 out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
487 matty 9 }
488    
489 matty 10 /* Output control capability set */
490 matty 25 static void
491     rdp_out_control_caps(STREAM s)
492 matty 9 {
493 matty 10 out_uint16_le(s, RDP_CAPSET_CONTROL);
494     out_uint16_le(s, RDP_CAPLEN_CONTROL);
495 matty 9
496 matty 10 out_uint16(s, 0); /* Control capabilities */
497     out_uint16(s, 0); /* Remote detach */
498     out_uint16_le(s, 2); /* Control interest */
499     out_uint16_le(s, 2); /* Detach interest */
500 matty 9 }
501    
502 matty 10 /* Output activation capability set */
503 matty 25 static void
504     rdp_out_activate_caps(STREAM s)
505 matty 9 {
506 matty 10 out_uint16_le(s, RDP_CAPSET_ACTIVATE);
507     out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
508 matty 9
509 matty 10 out_uint16(s, 0); /* Help key */
510     out_uint16(s, 0); /* Help index key */
511     out_uint16(s, 0); /* Extended help key */
512     out_uint16(s, 0); /* Window activate */
513 matty 9 }
514    
515 matty 10 /* Output pointer capability set */
516 matty 25 static void
517     rdp_out_pointer_caps(STREAM s)
518 matty 9 {
519 matty 10 out_uint16_le(s, RDP_CAPSET_POINTER);
520     out_uint16_le(s, RDP_CAPLEN_POINTER);
521 matty 9
522 matty 10 out_uint16(s, 0); /* Colour pointer */
523     out_uint16_le(s, 20); /* Cache size */
524 matty 9 }
525    
526 matty 10 /* Output share capability set */
527 matty 25 static void
528     rdp_out_share_caps(STREAM s)
529 matty 3 {
530 matty 10 out_uint16_le(s, RDP_CAPSET_SHARE);
531     out_uint16_le(s, RDP_CAPLEN_SHARE);
532 matty 3
533 matty 10 out_uint16(s, 0); /* userid */
534     out_uint16(s, 0); /* pad */
535 matty 9 }
536 matty 3
537 matty 10 /* Output colour cache capability set */
538 matty 25 static void
539     rdp_out_colcache_caps(STREAM s)
540 matty 9 {
541 matty 10 out_uint16_le(s, RDP_CAPSET_COLCACHE);
542     out_uint16_le(s, RDP_CAPLEN_COLCACHE);
543 matty 3
544 matty 10 out_uint16_le(s, 6); /* cache size */
545     out_uint16(s, 0); /* pad */
546 matty 3 }
547    
548 matty 10 static uint8 canned_caps[] = {
549 matty 24 0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,
550     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
551 matty 25 0x00, 0x00, 0x00, 0x00, 0x00,
552 matty 24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
553 matty 25 0x00, 0x00, 0x00, 0x00, 0x00,
554 matty 24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
555 matty 25 0x00, 0x00, 0x00, 0x00, 0x00,
556 matty 24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557 matty 25 0x00, 0x00, 0x00, 0x00, 0x00,
558 matty 24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559 matty 25 0x0C, 0x00, 0x08, 0x00, 0x01,
560 matty 24 0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
561 matty 25 0x10, 0x00, 0x34, 0x00, 0xFE,
562 matty 24 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,
563 matty 25 0xFE, 0x00, 0x08, 0x00, 0xFE,
564 matty 24 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,
565 matty 25 0xFE, 0x00, 0x80, 0x00, 0xFE,
566 matty 24 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
567 matty 25 0x02, 0x00, 0x00, 0x00
568 matty 10 };
569 matty 3
570 forsberg 351 /* Output unknown capability sets (number 13, 12, 14 and 16) */
571 matty 25 static void
572     rdp_out_unknown_caps(STREAM s)
573 matty 3 {
574 matty 10 out_uint16_le(s, RDP_CAPSET_UNKNOWN);
575     out_uint16_le(s, 0x58);
576 matty 24
577     out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);
578 matty 3 }
579    
580 forsberg 351 #define RDP5_FLAG 0x0030
581 matty 10 /* Send a confirm active PDU */
582 matty 25 static void
583 matthewc 192 rdp_send_confirm_active(void)
584 matty 7 {
585 matty 10 STREAM s;
586 jsorg71 437 uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
587 matty 24 uint16 caplen =
588     RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
589     RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
590     RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
591 astrand 82 RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;
592 matty 7
593 forsberg 351 s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
594 matty 9
595 forsberg 351 out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
596     out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10)); /* Version 1 */
597 jsorg71 381 out_uint16_le(s, (g_mcs_userid + 1001));
598 forsberg 351
599 jsorg71 438 out_uint32_le(s, g_rdp_shareid);
600 matty 24 out_uint16_le(s, 0x3ea); /* userid */
601 matty 10 out_uint16_le(s, sizeof(RDP_SOURCE));
602     out_uint16_le(s, caplen);
603 matty 9
604 matty 10 out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
605 matty 24 out_uint16_le(s, 0xd); /* num_caps */
606     out_uint8s(s, 2); /* pad */
607 matty 9
608 matty 10 rdp_out_general_caps(s);
609     rdp_out_bitmap_caps(s);
610     rdp_out_order_caps(s);
611     rdp_out_bmpcache_caps(s);
612     rdp_out_colcache_caps(s);
613     rdp_out_activate_caps(s);
614     rdp_out_control_caps(s);
615     rdp_out_pointer_caps(s);
616     rdp_out_share_caps(s);
617     rdp_out_unknown_caps(s);
618 matty 9
619 matty 10 s_mark_end(s);
620 forsberg 351 sec_send(s, sec_flags);
621 matty 9 }
622    
623 n-ki 677 /* Process a general capability set */
624     static void
625     rdp_process_general_caps(STREAM s)
626     {
627     uint16 pad2octetsB; /* rdp5 flags? */
628    
629     in_uint8s(s, 10);
630     in_uint16_le(s, pad2octetsB);
631    
632     if (!pad2octetsB)
633     g_use_rdp5 = False;
634     }
635    
636     /* Process a bitmap capability set */
637     static void
638     rdp_process_bitmap_caps(STREAM s)
639     {
640     uint16 width, height, bpp;
641    
642     in_uint16_le(s, bpp);
643     in_uint8s(s, 6);
644    
645     in_uint16_le(s, width);
646     in_uint16_le(s, height);
647    
648     DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));
649    
650     /*
651     * The server may limit bpp and change the size of the desktop (for
652     * example when shadowing another session).
653     */
654 jsorg71 708 if (g_server_bpp != bpp)
655     {
656     warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
657     g_server_bpp = bpp;
658     }
659     if (g_width != width || g_height != height)
660     {
661     warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
662     width, height);
663     g_width = width;
664     g_height = height;
665     ui_resize_window();
666     }
667 n-ki 677 }
668    
669 matty 10 /* Respond to a demand active PDU */
670 matty 25 static void
671     process_demand_active(STREAM s)
672 matty 9 {
673 n-ki 677 int n;
674     uint8 type, *next;
675     uint16 len_src_descriptor, len_combined_caps, num_capsets, capset_type, capset_length;
676 matty 9
677 jsorg71 438 in_uint32_le(s, g_rdp_shareid);
678 n-ki 677 in_uint16_le(s, len_src_descriptor);
679     in_uint16_le(s, len_combined_caps);
680     in_uint8s(s, len_src_descriptor);
681 matty 9
682 n-ki 677 in_uint16_le(s, num_capsets);
683     in_uint8s(s, 2); /* pad */
684    
685     DEBUG(("DEMAND_ACTIVE(id=0x%x,num_caps=%d)\n", g_rdp_shareid, num_capsets));
686    
687     for (n = 0; n < num_capsets; n++)
688 jsorg71 654 {
689 n-ki 677 in_uint16_le(s, capset_type);
690     in_uint16_le(s, capset_length);
691    
692     next = s->p + capset_length - 4;
693    
694     switch (capset_type)
695 jsorg71 654 {
696 n-ki 677 case RDP_CAPSET_GENERAL:
697     rdp_process_general_caps(s);
698     break;
699    
700     case RDP_CAPSET_BITMAP:
701     rdp_process_bitmap_caps(s);
702     break;
703 jsorg71 654 }
704 n-ki 677
705     s->p = next;
706 jsorg71 654 }
707    
708 matty 10 rdp_send_confirm_active();
709     rdp_send_synchronise();
710     rdp_send_control(RDP_CTL_COOPERATE);
711     rdp_send_control(RDP_CTL_REQUEST_CONTROL);
712 matty 28 rdp_recv(&type); /* RDP_PDU_SYNCHRONIZE */
713     rdp_recv(&type); /* RDP_CTL_COOPERATE */
714     rdp_recv(&type); /* RDP_CTL_GRANT_CONTROL */
715 astrand 543 rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);
716 n-ki 677
717     if (g_use_rdp5)
718     {
719     rdp_send_fonts(3);
720     }
721     else
722     {
723     rdp_send_fonts(1);
724     rdp_send_fonts(2);
725     }
726    
727     rdp_recv(&type); /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
728 matty 10 reset_order_state();
729 matty 9 }
730    
731 forsberg 351 /* Process a colour pointer PDU */
732     void
733     process_colour_pointer_pdu(STREAM s)
734     {
735     uint16 x, y, width, height, cache_idx, masklen, datalen;
736     uint8 *mask, *data;
737     HCURSOR cursor;
738    
739     in_uint16_le(s, cache_idx);
740     in_uint16_le(s, x);
741     in_uint16_le(s, y);
742     in_uint16_le(s, width);
743     in_uint16_le(s, height);
744     in_uint16_le(s, masklen);
745     in_uint16_le(s, datalen);
746     in_uint8p(s, data, datalen);
747     in_uint8p(s, mask, masklen);
748     cursor = ui_create_cursor(x, y, width, height, mask, data);
749     ui_set_cursor(cursor);
750     cache_put_cursor(cache_idx, cursor);
751     }
752    
753     /* Process a cached pointer PDU */
754     void
755     process_cached_pointer_pdu(STREAM s)
756     {
757     uint16 cache_idx;
758    
759     in_uint16_le(s, cache_idx);
760     ui_set_cursor(cache_get_cursor(cache_idx));
761     }
762    
763 astrand 508 /* Process a system pointer PDU */
764     void
765     process_system_pointer_pdu(STREAM s)
766     {
767     uint16 system_pointer_type;
768 forsberg 351
769 astrand 508 in_uint16(s, system_pointer_type);
770     switch (system_pointer_type)
771     {
772     case RDP_NULL_POINTER:
773     ui_set_null_cursor();
774     break;
775    
776     default:
777     unimpl("System pointer message 0x%x\n", system_pointer_type);
778     }
779     }
780    
781 matty 10 /* Process a pointer PDU */
782 matty 25 static void
783     process_pointer_pdu(STREAM s)
784 matty 9 {
785 matty 10 uint16 message_type;
786 forsberg 351 uint16 x, y;
787 matty 9
788 matty 10 in_uint16_le(s, message_type);
789 matty 24 in_uint8s(s, 2); /* pad */
790 matty 9
791 matty 10 switch (message_type)
792 matty 7 {
793 matty 10 case RDP_POINTER_MOVE:
794     in_uint16_le(s, x);
795     in_uint16_le(s, y);
796     if (s_check(s))
797     ui_move_pointer(x, y);
798     break;
799 matty 9
800 matty 28 case RDP_POINTER_COLOR:
801 forsberg 351 process_colour_pointer_pdu(s);
802 matty 28 break;
803    
804     case RDP_POINTER_CACHED:
805 forsberg 351 process_cached_pointer_pdu(s);
806 matty 28 break;
807    
808 astrand 508 case RDP_POINTER_SYSTEM:
809     process_system_pointer_pdu(s);
810     break;
811    
812 matty 10 default:
813 astrand 508 unimpl("Pointer message 0x%x\n", message_type);
814 matty 7 }
815 matty 9 }
816    
817 matty 10 /* Process bitmap updates */
818 forsberg 351 void
819 matty 25 process_bitmap_updates(STREAM s)
820 matty 9 {
821 matty 10 uint16 num_updates;
822     uint16 left, top, right, bottom, width, height;
823 jsorg71 314 uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
824 matty 28 uint8 *data, *bmpdata;
825 matty 9 int i;
826    
827 matty 10 in_uint16_le(s, num_updates);
828 matty 9
829 matty 10 for (i = 0; i < num_updates; i++)
830 matty 9 {
831 matty 10 in_uint16_le(s, left);
832     in_uint16_le(s, top);
833     in_uint16_le(s, right);
834     in_uint16_le(s, bottom);
835     in_uint16_le(s, width);
836     in_uint16_le(s, height);
837     in_uint16_le(s, bpp);
838 jsorg71 314 Bpp = (bpp + 7) / 8;
839 matty 10 in_uint16_le(s, compress);
840     in_uint16_le(s, bufsize);
841 matty 9
842 matty 10 cx = right - left + 1;
843     cy = bottom - top + 1;
844 matty 7
845 forsberg 351 DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
846     left, top, right, bottom, width, height, Bpp, compress));
847 matty 9
848 matty 10 if (!compress)
849     {
850 matty 28 int y;
851 forsberg 410 bmpdata = (uint8 *) xmalloc(width * height * Bpp);
852 matty 28 for (y = 0; y < height; y++)
853     {
854 astrand 318 in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
855     width * Bpp);
856 matty 28 }
857 astrand 82 ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
858 matty 28 xfree(bmpdata);
859     continue;
860 matty 10 }
861 matty 9
862 forsberg 351
863     if (compress & 0x400)
864     {
865     size = bufsize;
866     }
867     else
868     {
869     in_uint8s(s, 2); /* pad */
870     in_uint16_le(s, size);
871     in_uint8s(s, 4); /* line_size, final_size */
872     }
873 matty 10 in_uint8p(s, data, size);
874 forsberg 410 bmpdata = (uint8 *) xmalloc(width * height * Bpp);
875 jsorg71 314 if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
876 matty 9 {
877 astrand 82 ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
878 matty 9 }
879 forsberg 351 else
880     {
881     DEBUG_RDP5(("Failed to decompress data\n"));
882     }
883    
884 matty 28 xfree(bmpdata);
885 matty 10 }
886 matty 9 }
887    
888 matty 10 /* Process a palette update */
889 forsberg 351 void
890 matty 25 process_palette(STREAM s)
891 matty 9 {
892 matthewc 254 COLOURENTRY *entry;
893     COLOURMAP map;
894 matty 10 HCOLOURMAP hmap;
895 matthewc 254 int i;
896 matty 9
897 matty 24 in_uint8s(s, 2); /* pad */
898     in_uint16_le(s, map.ncolours);
899     in_uint8s(s, 2); /* pad */
900 matty 3
901 jsorg71 436 map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
902 matthewc 254
903 forsberg 351 DEBUG(("PALETTE(c=%d)\n", map.ncolours));
904    
905 matthewc 254 for (i = 0; i < map.ncolours; i++)
906     {
907     entry = &map.colours[i];
908     in_uint8(s, entry->red);
909     in_uint8(s, entry->green);
910     in_uint8(s, entry->blue);
911 astrand 260 }
912 matthewc 254
913 matty 10 hmap = ui_create_colourmap(&map);
914     ui_set_colourmap(hmap);
915 matthewc 254
916     xfree(map.colours);
917 matty 3 }
918    
919 matty 10 /* Process an update PDU */
920 matty 25 static void
921     process_update_pdu(STREAM s)
922 matty 9 {
923 forsberg 351 uint16 update_type, count;
924 matty 9
925 matty 10 in_uint16_le(s, update_type);
926 matty 3
927 matty 10 switch (update_type)
928 matty 3 {
929 matty 10 case RDP_UPDATE_ORDERS:
930 forsberg 351 in_uint8s(s, 2); /* pad */
931     in_uint16_le(s, count);
932     in_uint8s(s, 2); /* pad */
933     process_orders(s, count);
934 matty 10 break;
935 matty 3
936 matty 10 case RDP_UPDATE_BITMAP:
937     process_bitmap_updates(s);
938     break;
939 matty 3
940 matty 10 case RDP_UPDATE_PALETTE:
941     process_palette(s);
942     break;
943 matty 3
944 matty 10 case RDP_UPDATE_SYNCHRONIZE:
945     break;
946 matty 9
947 matty 10 default:
948 matty 30 unimpl("update %d\n", update_type);
949 matty 3 }
950    
951     }
952    
953 astrand 676 /* Process a disconnect PDU */
954     void
955     process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
956     {
957     in_uint32_le(s, *ext_disc_reason);
958    
959     DEBUG(("Received disconnect PDU\n"));
960     }
961    
962 matty 10 /* Process data PDU */
963 astrand 676 static BOOL
964     process_data_pdu(STREAM s, uint32 * ext_disc_reason)
965 matty 9 {
966 matty 10 uint8 data_pdu_type;
967 n-ki 624 uint8 ctype;
968     uint16 clen;
969 n-ki 683 uint32 len;
970 matty 9
971 n-ki 683 uint32 roff, rlen;
972    
973 n-ki 687 struct stream *ns = &(g_mppc_dict.ns);
974 n-ki 683
975 n-ki 624 in_uint8s(s, 6); /* shareid, pad, streamid */
976     in_uint16(s, len);
977 matty 10 in_uint8(s, data_pdu_type);
978 n-ki 624 in_uint8(s, ctype);
979     in_uint16(s, clen);
980     clen -= 18;
981 matty 3
982 n-ki 683 if (ctype & RDP_MPPC_COMPRESSED)
983 n-ki 624 {
984    
985 n-ki 683 if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
986     error("error while decompressing packet\n");
987 n-ki 624
988 n-ki 687 //len -= 18;
989 n-ki 624
990 n-ki 683 /* allocate memory and copy the uncompressed data into the temporary stream */
991 n-ki 687 ns->data = xrealloc(ns->data, rlen);
992 n-ki 624
993 n-ki 687 memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
994 n-ki 624
995 n-ki 687 ns->size = rlen;
996 n-ki 683 ns->end = (ns->data + ns->size);
997     ns->p = ns->data;
998     ns->rdp_hdr = ns->p;
999    
1000     s = ns;
1001 n-ki 624 }
1002    
1003 matty 10 switch (data_pdu_type)
1004 matty 3 {
1005 matty 10 case RDP_DATA_PDU_UPDATE:
1006     process_update_pdu(s);
1007     break;
1008 matty 3
1009 astrand 676 case RDP_DATA_PDU_CONTROL:
1010     DEBUG(("Received Control PDU\n"));
1011     break;
1012    
1013     case RDP_DATA_PDU_SYNCHRONISE:
1014     DEBUG(("Received Sync PDU\n"));
1015     break;
1016    
1017 matty 10 case RDP_DATA_PDU_POINTER:
1018     process_pointer_pdu(s);
1019     break;
1020 matty 3
1021 matty 10 case RDP_DATA_PDU_BELL:
1022     ui_bell();
1023     break;
1024 matty 3
1025 matty 10 case RDP_DATA_PDU_LOGON:
1026 forsberg 351 DEBUG(("Received Logon PDU\n"));
1027 matty 10 /* User logged on */
1028     break;
1029 matty 3
1030 matthewc 522 case RDP_DATA_PDU_DISCONNECT:
1031 astrand 676 process_disconnect_pdu(s, ext_disc_reason);
1032     return True;
1033 matthewc 522
1034 matty 10 default:
1035 matty 30 unimpl("data PDU %d\n", data_pdu_type);
1036 matty 3 }
1037 astrand 676 return False;
1038 matty 3 }
1039    
1040 matty 10 /* Process incoming packets */
1041 astrand 676 void
1042     rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1043 matty 9 {
1044 matty 10 uint8 type;
1045 astrand 676 BOOL disc = False; /* True when a disconnect PDU was received */
1046 matty 10 STREAM s;
1047 matty 9
1048 matty 10 while ((s = rdp_recv(&type)) != NULL)
1049 matty 3 {
1050 matty 10 switch (type)
1051     {
1052     case RDP_PDU_DEMAND_ACTIVE:
1053     process_demand_active(s);
1054 astrand 676 *deactivated = False;
1055 matty 10 break;
1056 matty 3
1057 matty 10 case RDP_PDU_DEACTIVATE:
1058 n-ki 677 DEBUG(("RDP_PDU_DEACTIVATE\n"));
1059 astrand 676 *deactivated = True;
1060 matty 10 break;
1061 matty 3
1062 matty 10 case RDP_PDU_DATA:
1063 astrand 676 disc = process_data_pdu(s, ext_disc_reason);
1064 matty 10 break;
1065 matty 3
1066 jsorg71 283 case 0:
1067     break;
1068    
1069 matty 10 default:
1070 matty 30 unimpl("PDU %d\n", type);
1071 matty 10 }
1072 astrand 676
1073     if (disc)
1074     {
1075     return;
1076     }
1077 matty 3 }
1078 astrand 676 return;
1079 matty 3 }
1080    
1081 matty 10 /* Establish a connection up to the RDP layer */
1082 matty 25 BOOL
1083     rdp_connect(char *server, uint32 flags, char *domain, char *password,
1084     char *command, char *directory)
1085 matty 9 {
1086 jsorg71 437 if (!sec_connect(server, g_username))
1087 matty 3 return False;
1088    
1089 jsorg71 437 rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1090 matty 10 return True;
1091 matty 3 }
1092    
1093 matty 10 /* Disconnect from the RDP layer */
1094 matty 25 void
1095 matthewc 192 rdp_disconnect(void)
1096 matty 9 {
1097 matty 10 sec_disconnect();
1098 matty 9 }

  ViewVC Help
Powered by ViewVC 1.1.26