/[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 677 - (hide annotations)
Mon Apr 26 13:48:39 2004 UTC (20 years ago) by n-ki
File MIME type: text/plain
File size: 25079 byte(s)
new: ui_resize_window() and related, which is used when resizing while shadowing. And fallback for color when connecting to a session with fewer colors than you have set in your session. Jeroen Meijer jeroen@oldambt7.com

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

  ViewVC Help
Powered by ViewVC 1.1.26