/[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 654 - (hide annotations)
Thu Apr 15 22:03:24 2004 UTC (20 years, 1 month ago) by jsorg71
File MIME type: text/plain
File size: 23935 byte(s)
move color fallback from process_bitmap_updates to process_demand_active

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

  ViewVC Help
Powered by ViewVC 1.1.26