/[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 977 - (hide annotations)
Mon Aug 8 19:15:57 2005 UTC (18 years, 9 months ago) by astrand
File MIME type: text/plain
File size: 33247 byte(s)
Applied patch #1247780 (slightly modified) from Brian Chapeau: Session Directory support.

1 forsberg 351 /* -*- c-basic-offset: 8 -*-
2 matty 3 rdesktop: A Remote Desktop Protocol client.
3     Protocol services - RDP layer
4 stargo 828 Copyright (C) Matthew Chapman 1999-2005
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 stargo 855 #include <errno.h>
23     #include <unistd.h>
24 matty 10 #include "rdesktop.h"
25 matty 3
26 stargo 857 #ifdef HAVE_ICONV
27 stargo 855 #ifdef HAVE_ICONV_H
28     #include <iconv.h>
29     #endif
30 stargo 858
31     #ifndef ICONV_CONST
32     #define ICONV_CONST ""
33 stargo 857 #endif
34 stargo 858 #endif
35 stargo 855
36 jsorg71 381 extern uint16 g_mcs_userid;
37 stargo 855 extern char g_username[64];
38     extern char g_codepage[16];
39 jsorg71 437 extern BOOL g_bitmap_compression;
40     extern BOOL g_orders;
41     extern BOOL g_encryption;
42 jsorg71 438 extern BOOL g_desktop_save;
43 jsorg71 848 extern BOOL g_polygon_ellipse_orders;
44 jsorg71 438 extern BOOL g_use_rdp5;
45     extern uint16 g_server_rdp_version;
46 stargo 637 extern uint32 g_rdp5_performanceflags;
47 jsorg71 438 extern int g_server_bpp;
48 n-ki 677 extern int g_width;
49     extern int g_height;
50 jsorg71 678 extern BOOL g_bitmap_cache;
51 jsorg71 725 extern BOOL g_bitmap_cache_persist_enable;
52 matty 3
53 jsorg71 438 uint8 *g_next_packet;
54     uint32 g_rdp_shareid;
55 matty 3
56 n-ki 687 extern RDPCOMP g_mppc_dict;
57 n-ki 683
58 astrand 977 /* Session Directory support */
59     extern BOOL g_redirect;
60     extern char g_redirect_server[64];
61     extern char g_redirect_domain[16];
62     extern char g_redirect_password[64];
63     extern char g_redirect_username[64];
64     extern char g_redirect_cookie[128];
65     extern uint32 g_redirect_flags;
66     /* END Session Directory support */
67    
68 forsberg 340 #if WITH_DEBUG
69 jsorg71 438 static uint32 g_packetno;
70 forsberg 351 #endif
71 forsberg 340
72 stargo 864 #ifdef HAVE_ICONV
73     static BOOL g_iconv_works = True;
74     #endif
75    
76 matty 10 /* Receive an RDP packet */
77 matty 25 static STREAM
78 astrand 64 rdp_recv(uint8 * type)
79 matty 3 {
80 matty 10 static STREAM rdp_s;
81     uint16 length, pdu_type;
82 jsorg71 733 uint8 rdpver;
83 matty 3
84 astrand 977 if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end) || (g_next_packet == NULL))
85 matty 10 {
86 jsorg71 733 rdp_s = sec_recv(&rdpver);
87 matty 10 if (rdp_s == NULL)
88     return NULL;
89 jsorg71 779 if (rdpver == 0xff)
90 jsorg71 733 {
91 jsorg71 779 g_next_packet = rdp_s->end;
92     *type = 0;
93     return rdp_s;
94     }
95     else if (rdpver != 3)
96     {
97 jsorg71 733 /* rdp5_process should move g_next_packet ok */
98     rdp5_process(rdp_s);
99     *type = 0;
100     return rdp_s;
101     }
102 matty 3
103 jsorg71 438 g_next_packet = rdp_s->p;
104 matty 10 }
105     else
106 matty 7 {
107 jsorg71 438 rdp_s->p = g_next_packet;
108 matty 7 }
109    
110 matty 10 in_uint16_le(rdp_s, length);
111 jsorg71 283 /* 32k packets are really 8, keepalive fix */
112     if (length == 0x8000)
113     {
114 jsorg71 438 g_next_packet += 8;
115 jsorg71 283 *type = 0;
116     return rdp_s;
117     }
118 matty 10 in_uint16_le(rdp_s, pdu_type);
119 matty 24 in_uint8s(rdp_s, 2); /* userid */
120 matty 10 *type = pdu_type & 0xf;
121 matty 7
122 matty 30 #if WITH_DEBUG
123 jsorg71 438 DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type));
124 matthewc 513 hexdump(g_next_packet, length);
125 matty 28 #endif /* */
126 matty 7
127 jsorg71 438 g_next_packet += length;
128 matty 10 return rdp_s;
129 matty 3 }
130    
131 matty 10 /* Initialise an RDP data packet */
132 matty 25 static STREAM
133     rdp_init_data(int maxlen)
134 matty 3 {
135 matty 10 STREAM s;
136 matty 3
137 jsorg71 437 s = sec_init(g_encryption ? SEC_ENCRYPT : 0, maxlen + 18);
138 matty 10 s_push_layer(s, rdp_hdr, 18);
139    
140     return s;
141 matty 3 }
142    
143 matty 10 /* Send an RDP data packet */
144 matty 25 static void
145     rdp_send_data(STREAM s, uint8 data_pdu_type)
146 matty 9 {
147 matty 10 uint16 length;
148 matty 9
149 matty 10 s_pop_layer(s, rdp_hdr);
150     length = s->end - s->p;
151 matty 9
152 matty 10 out_uint16_le(s, length);
153     out_uint16_le(s, (RDP_PDU_DATA | 0x10));
154 jsorg71 381 out_uint16_le(s, (g_mcs_userid + 1001));
155 matty 9
156 jsorg71 438 out_uint32_le(s, g_rdp_shareid);
157 matty 24 out_uint8(s, 0); /* pad */
158     out_uint8(s, 1); /* streamid */
159 n-ki 176 out_uint16_le(s, (length - 14));
160 matty 10 out_uint8(s, data_pdu_type);
161 matty 24 out_uint8(s, 0); /* compress_type */
162     out_uint16(s, 0); /* compress_len */
163 matty 3
164 jsorg71 437 sec_send(s, g_encryption ? SEC_ENCRYPT : 0);
165 matty 3 }
166    
167 matty 10 /* Output a string in Unicode */
168 matty 25 void
169     rdp_out_unistr(STREAM s, char *string, int len)
170 matty 3 {
171 stargo 857 #ifdef HAVE_ICONV
172 stargo 855 size_t ibl = strlen(string), obl = len + 2;
173 stargo 861 static iconv_t iconv_h = (iconv_t) - 1;
174 astrand 879 char *pin = string, *pout = (char *) s->p;
175 stargo 855
176     memset(pout, 0, len + 4);
177    
178 stargo 864 if (g_iconv_works)
179 stargo 855 {
180 stargo 864 if (iconv_h == (iconv_t) - 1)
181 stargo 855 {
182 stargo 864 size_t i = 1, o = 4;
183     if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1)
184     {
185     warning("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n",
186     g_codepage, WINDOWS_CODEPAGE, (int) iconv_h);
187    
188     g_iconv_works = False;
189 stargo 866 rdp_out_unistr(s, string, len);
190     return;
191 stargo 864 }
192     if (iconv(iconv_h, (ICONV_CONST char **) &pin, &i, &pout, &o) ==
193     (size_t) - 1)
194     {
195     iconv_close(iconv_h);
196     iconv_h = (iconv_t) - 1;
197     warning("rdp_out_unistr: iconv(1) fail, errno %d\n", errno);
198    
199     g_iconv_works = False;
200 stargo 866 rdp_out_unistr(s, string, len);
201     return;
202 stargo 864 }
203     pin = string;
204     pout = (char *) s->p;
205 stargo 855 }
206 stargo 864
207     if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
208 stargo 855 {
209     iconv_close(iconv_h);
210 stargo 861 iconv_h = (iconv_t) - 1;
211 stargo 864 warning("rdp_out_unistr: iconv(2) fail, errno %d\n", errno);
212    
213     g_iconv_works = False;
214 stargo 866 rdp_out_unistr(s, string, len);
215     return;
216 stargo 855 }
217 stargo 864
218     s->p += len + 2;
219    
220 stargo 855 }
221 stargo 864 else
222     #endif
223 stargo 855 {
224 stargo 864 int i = 0, j = 0;
225 stargo 855
226 stargo 864 len += 2;
227 stargo 855
228 stargo 864 while (i < len)
229     {
230     s->p[i++] = string[j++];
231     s->p[i++] = 0;
232     }
233 matty 9
234 stargo 864 s->p += len;
235 matty 9 }
236 matty 3 }
237    
238 n-ki 569 /* Input a string in Unicode
239     *
240     * Returns str_len of string
241     */
242     int
243     rdp_in_unistr(STREAM s, char *string, int uni_len)
244     {
245 stargo 857 #ifdef HAVE_ICONV
246 stargo 855 size_t ibl = uni_len, obl = uni_len;
247 astrand 879 char *pin = (char *) s->p, *pout = string;
248 stargo 861 static iconv_t iconv_h = (iconv_t) - 1;
249 stargo 855
250 stargo 864 if (g_iconv_works)
251 stargo 855 {
252 stargo 864 if (iconv_h == (iconv_t) - 1)
253 stargo 855 {
254 stargo 864 if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1)
255     {
256     warning("rdp_in_unistr: iconv_open[%s -> %s] fail %d\n",
257     WINDOWS_CODEPAGE, g_codepage, (int) iconv_h);
258    
259     g_iconv_works = False;
260     return rdp_in_unistr(s, string, uni_len);
261     }
262 stargo 855 }
263 stargo 864
264     if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
265     {
266     iconv_close(iconv_h);
267     iconv_h = (iconv_t) - 1;
268     warning("rdp_in_unistr: iconv fail, errno %d\n", errno);
269    
270     g_iconv_works = False;
271     return rdp_in_unistr(s, string, uni_len);
272     }
273 astrand 977
274     /* we must update the location of the current STREAM for future reads of s->p */
275     s->p += uni_len;
276    
277 stargo 864 return pout - string;
278 stargo 855 }
279 stargo 864 else
280     #endif
281 stargo 855 {
282 stargo 864 int i = 0;
283 n-ki 569
284 stargo 864 while (i < uni_len / 2)
285     {
286     in_uint8a(s, &string[i++], 1);
287     in_uint8s(s, 1);
288     }
289    
290     return i - 1;
291 n-ki 569 }
292     }
293    
294    
295 matty 10 /* Parse a logon info packet */
296 matty 25 static void
297     rdp_send_logon_info(uint32 flags, char *domain, char *user,
298     char *password, char *program, char *directory)
299 matty 3 {
300 n-ki 624 char *ipaddr = tcp_get_address();
301 matty 24 int len_domain = 2 * strlen(domain);
302     int len_user = 2 * strlen(user);
303     int len_password = 2 * strlen(password);
304     int len_program = 2 * strlen(program);
305 matty 10 int len_directory = 2 * strlen(directory);
306 n-ki 624 int len_ip = 2 * strlen(ipaddr);
307 forsberg 371 int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
308     int packetlen = 0;
309 jsorg71 437 uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
310 matty 10 STREAM s;
311 stargo 562 time_t t = time(NULL);
312     time_t tzone;
313 matty 3
314 jsorg71 438 if (!g_use_rdp5 || 1 == g_server_rdp_version)
315 forsberg 351 {
316     DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
317 matty 3
318 forsberg 351 s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
319     + len_program + len_directory + 10);
320 matty 3
321 forsberg 351 out_uint32(s, 0);
322     out_uint32_le(s, flags);
323     out_uint16_le(s, len_domain);
324     out_uint16_le(s, len_user);
325     out_uint16_le(s, len_password);
326     out_uint16_le(s, len_program);
327     out_uint16_le(s, len_directory);
328     rdp_out_unistr(s, domain, len_domain);
329     rdp_out_unistr(s, user, len_user);
330     rdp_out_unistr(s, password, len_password);
331     rdp_out_unistr(s, program, len_program);
332     rdp_out_unistr(s, directory, len_directory);
333     }
334     else
335     {
336 n-ki 683
337 forsberg 371 flags |= RDP_LOGON_BLOB;
338 forsberg 351 DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
339 astrand 540 packetlen = 4 + /* Unknown uint32 */
340     4 + /* flags */
341     2 + /* len_domain */
342     2 + /* len_user */
343     (flags & RDP_LOGON_AUTO ? 2 : 0) + /* len_password */
344     (flags & RDP_LOGON_BLOB ? 2 : 0) + /* Length of BLOB */
345     2 + /* len_program */
346     2 + /* len_directory */
347     (0 < len_domain ? len_domain : 2) + /* domain */
348     len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 + /* We have no 512 byte BLOB. Perhaps we must? */
349     (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + /* After the BLOB is a unknown int16. If there is a BLOB, that is. */
350     (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 + /* Unknown (2) */
351     2 + /* Client ip length */
352     len_ip + /* Client ip */
353     2 + /* DLL string length */
354     len_dll + /* DLL string */
355     2 + /* Unknown */
356     2 + /* Unknown */
357     64 + /* Time zone #0 */
358     2 + /* Unknown */
359     64 + /* Time zone #1 */
360     32; /* Unknown */
361 forsberg 410
362     s = sec_init(sec_flags, packetlen);
363 forsberg 371 DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
364 forsberg 351
365 astrand 540 out_uint32(s, 0); /* Unknown */
366 forsberg 351 out_uint32_le(s, flags);
367     out_uint16_le(s, len_domain);
368     out_uint16_le(s, len_user);
369     if (flags & RDP_LOGON_AUTO)
370     {
371     out_uint16_le(s, len_password);
372 forsberg 371
373 forsberg 351 }
374 forsberg 410 if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
375     {
376 forsberg 371 out_uint16_le(s, 0);
377     }
378 forsberg 351 out_uint16_le(s, len_program);
379     out_uint16_le(s, len_directory);
380 forsberg 371 if (0 < len_domain)
381     rdp_out_unistr(s, domain, len_domain);
382 forsberg 410 else
383 forsberg 371 out_uint16_le(s, 0);
384     rdp_out_unistr(s, user, len_user);
385 forsberg 351 if (flags & RDP_LOGON_AUTO)
386     {
387     rdp_out_unistr(s, password, len_password);
388     }
389 forsberg 410 if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
390     {
391 forsberg 371 out_uint16_le(s, 0);
392     }
393 forsberg 410 if (0 < len_program)
394     {
395 forsberg 351 rdp_out_unistr(s, program, len_program);
396 forsberg 410
397     }
398     else
399     {
400 forsberg 371 out_uint16_le(s, 0);
401     }
402 forsberg 410 if (0 < len_directory)
403     {
404 forsberg 351 rdp_out_unistr(s, directory, len_directory);
405 forsberg 410 }
406     else
407     {
408 forsberg 371 out_uint16_le(s, 0);
409 jsorg71 376 }
410 forsberg 371 out_uint16_le(s, 2);
411 astrand 540 out_uint16_le(s, len_ip + 2); /* Length of client ip */
412 n-ki 624 rdp_out_unistr(s, ipaddr, len_ip);
413 forsberg 410 out_uint16_le(s, len_dll + 2);
414 forsberg 371 rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
415 stargo 562
416 stargo 604 tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
417     out_uint32_le(s, tzone);
418 stargo 559
419 forsberg 410 rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
420     out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
421 forsberg 351
422     out_uint32_le(s, 0x0a0000);
423     out_uint32_le(s, 0x050000);
424 forsberg 371 out_uint32_le(s, 3);
425     out_uint32_le(s, 0);
426     out_uint32_le(s, 0);
427 forsberg 351
428 forsberg 410 rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
429     out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
430    
431 forsberg 371 out_uint32_le(s, 0x30000);
432 forsberg 351 out_uint32_le(s, 0x050000);
433     out_uint32_le(s, 2);
434 matthewc 365 out_uint32(s, 0);
435 forsberg 351 out_uint32_le(s, 0xffffffc4);
436     out_uint32_le(s, 0xfffffffe);
437 stargo 637 out_uint32_le(s, g_rdp5_performanceflags);
438 matthewc 365 out_uint32(s, 0);
439 forsberg 351
440 forsberg 371
441 forsberg 351 }
442 matty 10 s_mark_end(s);
443     sec_send(s, sec_flags);
444 matty 3 }
445    
446 matty 10 /* Send a control PDU */
447 matty 25 static void
448     rdp_send_control(uint16 action)
449 matty 3 {
450 matty 10 STREAM s;
451 matty 9
452 matty 10 s = rdp_init_data(8);
453 matty 9
454 matty 10 out_uint16_le(s, action);
455 matty 24 out_uint16(s, 0); /* userid */
456     out_uint32(s, 0); /* control id */
457 matty 9
458 matty 10 s_mark_end(s);
459     rdp_send_data(s, RDP_DATA_PDU_CONTROL);
460 matty 3 }
461    
462 matty 10 /* Send a synchronisation PDU */
463 matty 25 static void
464 matthewc 192 rdp_send_synchronise(void)
465 matty 3 {
466 matty 10 STREAM s;
467 matty 9
468 matty 10 s = rdp_init_data(4);
469 matty 9
470 matty 24 out_uint16_le(s, 1); /* type */
471 matty 10 out_uint16_le(s, 1002);
472 matty 9
473 matty 10 s_mark_end(s);
474     rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);
475 matty 3 }
476    
477 matty 10 /* Send a single input event */
478 matty 25 void
479 astrand 82 rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
480 matty 3 {
481 matty 10 STREAM s;
482 matty 9
483 matty 10 s = rdp_init_data(16);
484 matty 9
485 matty 24 out_uint16_le(s, 1); /* number of events */
486     out_uint16(s, 0); /* pad */
487 matty 9
488 matty 10 out_uint32_le(s, time);
489     out_uint16_le(s, message_type);
490     out_uint16_le(s, device_flags);
491     out_uint16_le(s, param1);
492     out_uint16_le(s, param2);
493 matty 9
494 matty 10 s_mark_end(s);
495     rdp_send_data(s, RDP_DATA_PDU_INPUT);
496 matty 3 }
497    
498 jdmeijer 905 /* Send a client window information PDU */
499     void
500     rdp_send_client_window_status(int status)
501     {
502     STREAM s;
503 jdmeijer 907 static int current_status = 1;
504 jdmeijer 905
505 jdmeijer 907 if (current_status == status)
506     return;
507    
508 jdmeijer 905 s = rdp_init_data(12);
509    
510     out_uint32_le(s, status);
511    
512     switch (status)
513     {
514     case 0: /* shut the server up */
515     break;
516    
517     case 1: /* receive data again */
518     out_uint32_le(s, 0); /* unknown */
519     out_uint16_le(s, g_width);
520     out_uint16_le(s, g_height);
521     break;
522     }
523    
524     s_mark_end(s);
525     rdp_send_data(s, RDP_DATA_PDU_CLIENT_WINDOW_STATUS);
526 jdmeijer 907 current_status = status;
527 jdmeijer 905 }
528    
529     /* Send persistent bitmap cache enumeration PDU's */
530 jsorg71 725 static void
531     rdp_enum_bmpcache2(void)
532     {
533     STREAM s;
534 jdmeijer 830 HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS];
535     uint32 num_keys, offset, count, flags;
536 jsorg71 725
537     offset = 0;
538 jdmeijer 830 num_keys = pstcache_enumerate(2, keylist);
539 jsorg71 725
540 jdmeijer 830 while (offset < num_keys)
541 jsorg71 725 {
542 jdmeijer 830 count = MIN(num_keys - offset, 169);
543 jsorg71 725
544 jdmeijer 830 s = rdp_init_data(24 + count * sizeof(HASH_KEY));
545 jsorg71 725
546     flags = 0;
547     if (offset == 0)
548     flags |= PDU_FLAG_FIRST;
549 jdmeijer 830 if (num_keys - offset <= 169)
550 jsorg71 725 flags |= PDU_FLAG_LAST;
551    
552     /* header */
553     out_uint32_le(s, 0);
554     out_uint16_le(s, count);
555     out_uint16_le(s, 0);
556     out_uint16_le(s, 0);
557     out_uint16_le(s, 0);
558     out_uint16_le(s, 0);
559 jdmeijer 830 out_uint16_le(s, num_keys);
560 jsorg71 725 out_uint32_le(s, 0);
561     out_uint32_le(s, flags);
562    
563     /* list */
564 jdmeijer 830 out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
565 jsorg71 725
566     s_mark_end(s);
567     rdp_send_data(s, 0x2b);
568    
569     offset += 169;
570     }
571     }
572    
573 matty 10 /* Send an (empty) font information PDU */
574 matty 25 static void
575     rdp_send_fonts(uint16 seq)
576 matty 3 {
577 matty 10 STREAM s;
578 matty 3
579 matty 10 s = rdp_init_data(8);
580 matty 9
581 matty 10 out_uint16(s, 0); /* number of fonts */
582 n-ki 677 out_uint16_le(s, 0); /* pad? */
583 matty 10 out_uint16_le(s, seq); /* unknown */
584     out_uint16_le(s, 0x32); /* entry size */
585 matty 9
586 matty 10 s_mark_end(s);
587     rdp_send_data(s, RDP_DATA_PDU_FONT2);
588 matty 3 }
589    
590 matty 10 /* Output general capability set */
591 matty 25 static void
592     rdp_out_general_caps(STREAM s)
593 matty 3 {
594 matty 10 out_uint16_le(s, RDP_CAPSET_GENERAL);
595     out_uint16_le(s, RDP_CAPLEN_GENERAL);
596 matty 3
597 matty 10 out_uint16_le(s, 1); /* OS major type */
598     out_uint16_le(s, 3); /* OS minor type */
599 matty 24 out_uint16_le(s, 0x200); /* Protocol version */
600 matty 10 out_uint16(s, 0); /* Pad */
601     out_uint16(s, 0); /* Compression types */
602 jsorg71 438 out_uint16_le(s, g_use_rdp5 ? 0x40d : 0);
603 forsberg 351 /* Pad, according to T.128. 0x40d seems to
604     trigger
605     the server to start sending RDP5 packets.
606     However, the value is 0x1d04 with W2KTSK and
607     NT4MS. Hmm.. Anyway, thankyou, Microsoft,
608     for sending such information in a padding
609     field.. */
610 matty 10 out_uint16(s, 0); /* Update capability */
611     out_uint16(s, 0); /* Remote unshare capability */
612     out_uint16(s, 0); /* Compression level */
613     out_uint16(s, 0); /* Pad */
614 matty 3 }
615    
616 matty 10 /* Output bitmap capability set */
617 matty 25 static void
618     rdp_out_bitmap_caps(STREAM s)
619 matty 9 {
620 matty 10 out_uint16_le(s, RDP_CAPSET_BITMAP);
621     out_uint16_le(s, RDP_CAPLEN_BITMAP);
622 matty 9
623 jsorg71 654 out_uint16_le(s, g_server_bpp); /* Preferred BPP */
624 n-ki 176 out_uint16_le(s, 1); /* Receive 1 BPP */
625     out_uint16_le(s, 1); /* Receive 4 BPP */
626 matty 10 out_uint16_le(s, 1); /* Receive 8 BPP */
627     out_uint16_le(s, 800); /* Desktop width */
628     out_uint16_le(s, 600); /* Desktop height */
629     out_uint16(s, 0); /* Pad */
630 n-ki 677 out_uint16(s, 1); /* Allow resize */
631 jsorg71 437 out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
632 matty 10 out_uint16(s, 0); /* Unknown */
633     out_uint16_le(s, 1); /* Unknown */
634     out_uint16(s, 0); /* Pad */
635 matty 9 }
636    
637 matty 10 /* Output order capability set */
638 matty 25 static void
639     rdp_out_order_caps(STREAM s)
640 matty 3 {
641 matty 10 uint8 order_caps[32];
642 matty 3
643 matty 28 memset(order_caps, 0, 32);
644     order_caps[0] = 1; /* dest blt */
645     order_caps[1] = 1; /* pat blt */
646     order_caps[2] = 1; /* screen blt */
647 n-ki 683 order_caps[3] = (g_bitmap_cache ? 1 : 0); /* memblt */
648 jdmeijer 831 order_caps[4] = 0; /* triblt */
649 matty 28 order_caps[8] = 1; /* line */
650     order_caps[9] = 1; /* line */
651     order_caps[10] = 1; /* rect */
652 jsorg71 848 order_caps[11] = (g_desktop_save ? 1 : 0); /* desksave */
653 matty 28 order_caps[13] = 1; /* memblt */
654     order_caps[14] = 1; /* triblt */
655 jsorg71 848 order_caps[20] = (g_polygon_ellipse_orders ? 1 : 0); /* polygon */
656     order_caps[21] = (g_polygon_ellipse_orders ? 1 : 0); /* polygon2 */
657 matty 28 order_caps[22] = 1; /* polyline */
658 jsorg71 848 order_caps[25] = (g_polygon_ellipse_orders ? 1 : 0); /* ellipse */
659     order_caps[26] = (g_polygon_ellipse_orders ? 1 : 0); /* ellipse2 */
660 matty 28 order_caps[27] = 1; /* text2 */
661 matty 10 out_uint16_le(s, RDP_CAPSET_ORDER);
662     out_uint16_le(s, RDP_CAPLEN_ORDER);
663 matty 9
664 matty 10 out_uint8s(s, 20); /* Terminal desc, pad */
665     out_uint16_le(s, 1); /* Cache X granularity */
666     out_uint16_le(s, 20); /* Cache Y granularity */
667     out_uint16(s, 0); /* Pad */
668     out_uint16_le(s, 1); /* Max order level */
669     out_uint16_le(s, 0x147); /* Number of fonts */
670 matty 24 out_uint16_le(s, 0x2a); /* Capability flags */
671 matty 10 out_uint8p(s, order_caps, 32); /* Orders supported */
672     out_uint16_le(s, 0x6a1); /* Text capability flags */
673     out_uint8s(s, 6); /* Pad */
674 jsorg71 438 out_uint32_le(s, g_desktop_save == False ? 0 : 0x38400); /* Desktop cache size */
675 matty 10 out_uint32(s, 0); /* Unknown */
676 n-ki 176 out_uint32_le(s, 0x4e4); /* Unknown */
677 matty 9 }
678    
679 matty 10 /* Output bitmap cache capability set */
680 matty 25 static void
681     rdp_out_bmpcache_caps(STREAM s)
682 matty 9 {
683 jsorg71 433 int Bpp;
684 matty 10 out_uint16_le(s, RDP_CAPSET_BMPCACHE);
685     out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
686 matty 3
687 jsorg71 438 Bpp = (g_server_bpp + 7) / 8;
688 matty 24 out_uint8s(s, 24); /* unused */
689     out_uint16_le(s, 0x258); /* entries */
690 jsorg71 433 out_uint16_le(s, 0x100 * Bpp); /* max cell size */
691 matty 24 out_uint16_le(s, 0x12c); /* entries */
692 jsorg71 433 out_uint16_le(s, 0x400 * Bpp); /* max cell size */
693 matty 24 out_uint16_le(s, 0x106); /* entries */
694 jsorg71 433 out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
695 matty 9 }
696    
697 jsorg71 725 /* Output bitmap cache v2 capability set */
698     static void
699     rdp_out_bmpcache2_caps(STREAM s)
700     {
701     out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
702     out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
703    
704 jsorg71 730 out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0); /* version */
705 jsorg71 725
706 jdmeijer 889 out_uint16_be(s, 3); /* number of caches in this set */
707 jsorg71 725
708 jdmeijer 889 /* max cell size for cache 0 is 16x16, 1 = 32x32, 2 = 64x64, etc */
709 jsorg71 725 out_uint32_le(s, BMPCACHE2_C0_CELLS);
710     out_uint32_le(s, BMPCACHE2_C1_CELLS);
711     if (pstcache_init(2))
712     {
713     out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
714     }
715     else
716     {
717     out_uint32_le(s, BMPCACHE2_C2_CELLS);
718     }
719 astrand 738 out_uint8s(s, 20); /* other bitmap caches not used */
720 jsorg71 725 }
721    
722 matty 10 /* Output control capability set */
723 matty 25 static void
724     rdp_out_control_caps(STREAM s)
725 matty 9 {
726 matty 10 out_uint16_le(s, RDP_CAPSET_CONTROL);
727     out_uint16_le(s, RDP_CAPLEN_CONTROL);
728 matty 9
729 matty 10 out_uint16(s, 0); /* Control capabilities */
730     out_uint16(s, 0); /* Remote detach */
731     out_uint16_le(s, 2); /* Control interest */
732     out_uint16_le(s, 2); /* Detach interest */
733 matty 9 }
734    
735 matty 10 /* Output activation capability set */
736 matty 25 static void
737     rdp_out_activate_caps(STREAM s)
738 matty 9 {
739 matty 10 out_uint16_le(s, RDP_CAPSET_ACTIVATE);
740     out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
741 matty 9
742 matty 10 out_uint16(s, 0); /* Help key */
743     out_uint16(s, 0); /* Help index key */
744     out_uint16(s, 0); /* Extended help key */
745     out_uint16(s, 0); /* Window activate */
746 matty 9 }
747    
748 matty 10 /* Output pointer capability set */
749 matty 25 static void
750     rdp_out_pointer_caps(STREAM s)
751 matty 9 {
752 matty 10 out_uint16_le(s, RDP_CAPSET_POINTER);
753     out_uint16_le(s, RDP_CAPLEN_POINTER);
754 matty 9
755 matty 10 out_uint16(s, 0); /* Colour pointer */
756     out_uint16_le(s, 20); /* Cache size */
757 matty 9 }
758    
759 matty 10 /* Output share capability set */
760 matty 25 static void
761     rdp_out_share_caps(STREAM s)
762 matty 3 {
763 matty 10 out_uint16_le(s, RDP_CAPSET_SHARE);
764     out_uint16_le(s, RDP_CAPLEN_SHARE);
765 matty 3
766 matty 10 out_uint16(s, 0); /* userid */
767     out_uint16(s, 0); /* pad */
768 matty 9 }
769 matty 3
770 matty 10 /* Output colour cache capability set */
771 matty 25 static void
772     rdp_out_colcache_caps(STREAM s)
773 matty 9 {
774 matty 10 out_uint16_le(s, RDP_CAPSET_COLCACHE);
775     out_uint16_le(s, RDP_CAPLEN_COLCACHE);
776 matty 3
777 matty 10 out_uint16_le(s, 6); /* cache size */
778     out_uint16(s, 0); /* pad */
779 matty 3 }
780    
781 jsorg71 725 static uint8 caps_0x0d[] = {
782     0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
783     0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
784     0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
785     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
786     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
787     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
788     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
789     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
790     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
791     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
792     0x00, 0x00, 0x00, 0x00
793 matty 10 };
794 matty 3
795 jsorg71 725 static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
796    
797     static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
798    
799     static uint8 caps_0x10[] = {
800     0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
801     0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
802     0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
803     0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
804     0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
805     0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
806     };
807    
808     /* Output unknown capability sets */
809 matty 25 static void
810 astrand 738 rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
811 matty 3 {
812 jsorg71 725 out_uint16_le(s, id);
813     out_uint16_le(s, length);
814 matty 24
815 jsorg71 725 out_uint8p(s, caps, length - 4);
816 matty 3 }
817    
818 forsberg 351 #define RDP5_FLAG 0x0030
819 matty 10 /* Send a confirm active PDU */
820 matty 25 static void
821 matthewc 192 rdp_send_confirm_active(void)
822 matty 7 {
823 matty 10 STREAM s;
824 jsorg71 437 uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
825 matty 24 uint16 caplen =
826     RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
827     RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
828     RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
829 jsorg71 725 RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
830 astrand 738 0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */ +
831 jsorg71 725 4 /* w2k fix, why? */ ;
832 matty 7
833 forsberg 351 s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
834 matty 9
835 forsberg 351 out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
836     out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10)); /* Version 1 */
837 jsorg71 381 out_uint16_le(s, (g_mcs_userid + 1001));
838 forsberg 351
839 jsorg71 438 out_uint32_le(s, g_rdp_shareid);
840 matty 24 out_uint16_le(s, 0x3ea); /* userid */
841 matty 10 out_uint16_le(s, sizeof(RDP_SOURCE));
842     out_uint16_le(s, caplen);
843 matty 9
844 matty 10 out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
845 matty 24 out_uint16_le(s, 0xd); /* num_caps */
846     out_uint8s(s, 2); /* pad */
847 matty 9
848 matty 10 rdp_out_general_caps(s);
849     rdp_out_bitmap_caps(s);
850     rdp_out_order_caps(s);
851 jsorg71 725 g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
852 matty 10 rdp_out_colcache_caps(s);
853     rdp_out_activate_caps(s);
854     rdp_out_control_caps(s);
855     rdp_out_pointer_caps(s);
856     rdp_out_share_caps(s);
857 matty 9
858 astrand 738 rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
859 jsorg71 725 rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
860     rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
861 astrand 738 rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
862    
863 matty 10 s_mark_end(s);
864 forsberg 351 sec_send(s, sec_flags);
865 matty 9 }
866    
867 n-ki 677 /* Process a general capability set */
868     static void
869     rdp_process_general_caps(STREAM s)
870     {
871     uint16 pad2octetsB; /* rdp5 flags? */
872    
873     in_uint8s(s, 10);
874     in_uint16_le(s, pad2octetsB);
875    
876     if (!pad2octetsB)
877     g_use_rdp5 = False;
878     }
879    
880     /* Process a bitmap capability set */
881     static void
882     rdp_process_bitmap_caps(STREAM s)
883     {
884     uint16 width, height, bpp;
885    
886     in_uint16_le(s, bpp);
887     in_uint8s(s, 6);
888    
889     in_uint16_le(s, width);
890     in_uint16_le(s, height);
891    
892     DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));
893    
894     /*
895     * The server may limit bpp and change the size of the desktop (for
896     * example when shadowing another session).
897     */
898 jsorg71 708 if (g_server_bpp != bpp)
899     {
900     warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
901     g_server_bpp = bpp;
902     }
903     if (g_width != width || g_height != height)
904     {
905     warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
906 astrand 738 width, height);
907 jsorg71 708 g_width = width;
908     g_height = height;
909     ui_resize_window();
910     }
911 n-ki 677 }
912    
913 jsorg71 725 /* Process server capabilities */
914 astrand 945 static void
915 jsorg71 725 rdp_process_server_caps(STREAM s, uint16 length)
916 matty 9 {
917 n-ki 677 int n;
918 jsorg71 725 uint8 *next, *start;
919     uint16 ncapsets, capset_type, capset_length;
920 matty 9
921 jsorg71 725 start = s->p;
922 matty 9
923 jsorg71 725 in_uint16_le(s, ncapsets);
924 n-ki 677 in_uint8s(s, 2); /* pad */
925    
926 jsorg71 725 for (n = 0; n < ncapsets; n++)
927     {
928     if (s->p > start + length)
929     return;
930 n-ki 677
931     in_uint16_le(s, capset_type);
932     in_uint16_le(s, capset_length);
933    
934     next = s->p + capset_length - 4;
935    
936     switch (capset_type)
937 jsorg71 654 {
938 n-ki 677 case RDP_CAPSET_GENERAL:
939     rdp_process_general_caps(s);
940     break;
941    
942     case RDP_CAPSET_BITMAP:
943     rdp_process_bitmap_caps(s);
944     break;
945 jsorg71 654 }
946 n-ki 677
947     s->p = next;
948 jsorg71 654 }
949 jsorg71 725 }
950 jsorg71 654
951 jsorg71 725 /* Respond to a demand active PDU */
952     static void
953     process_demand_active(STREAM s)
954     {
955     uint8 type;
956     uint16 len_src_descriptor, len_combined_caps;
957    
958     in_uint32_le(s, g_rdp_shareid);
959     in_uint16_le(s, len_src_descriptor);
960     in_uint16_le(s, len_combined_caps);
961     in_uint8s(s, len_src_descriptor);
962    
963     DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
964     rdp_process_server_caps(s, len_combined_caps);
965    
966 matty 10 rdp_send_confirm_active();
967     rdp_send_synchronise();
968     rdp_send_control(RDP_CTL_COOPERATE);
969     rdp_send_control(RDP_CTL_REQUEST_CONTROL);
970 matty 28 rdp_recv(&type); /* RDP_PDU_SYNCHRONIZE */
971     rdp_recv(&type); /* RDP_CTL_COOPERATE */
972     rdp_recv(&type); /* RDP_CTL_GRANT_CONTROL */
973 astrand 543 rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);
974 n-ki 677
975     if (g_use_rdp5)
976     {
977 jsorg71 725 rdp_enum_bmpcache2();
978 n-ki 677 rdp_send_fonts(3);
979     }
980     else
981     {
982     rdp_send_fonts(1);
983     rdp_send_fonts(2);
984     }
985    
986     rdp_recv(&type); /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
987 matty 10 reset_order_state();
988 matty 9 }
989    
990 forsberg 351 /* Process a colour pointer PDU */
991     void
992     process_colour_pointer_pdu(STREAM s)
993     {
994     uint16 x, y, width, height, cache_idx, masklen, datalen;
995     uint8 *mask, *data;
996     HCURSOR cursor;
997    
998     in_uint16_le(s, cache_idx);
999     in_uint16_le(s, x);
1000     in_uint16_le(s, y);
1001     in_uint16_le(s, width);
1002     in_uint16_le(s, height);
1003     in_uint16_le(s, masklen);
1004     in_uint16_le(s, datalen);
1005     in_uint8p(s, data, datalen);
1006     in_uint8p(s, mask, masklen);
1007     cursor = ui_create_cursor(x, y, width, height, mask, data);
1008     ui_set_cursor(cursor);
1009     cache_put_cursor(cache_idx, cursor);
1010     }
1011    
1012     /* Process a cached pointer PDU */
1013     void
1014     process_cached_pointer_pdu(STREAM s)
1015     {
1016     uint16 cache_idx;
1017    
1018     in_uint16_le(s, cache_idx);
1019     ui_set_cursor(cache_get_cursor(cache_idx));
1020     }
1021    
1022 astrand 508 /* Process a system pointer PDU */
1023     void
1024     process_system_pointer_pdu(STREAM s)
1025     {
1026     uint16 system_pointer_type;
1027 forsberg 351
1028 astrand 508 in_uint16(s, system_pointer_type);
1029     switch (system_pointer_type)
1030     {
1031     case RDP_NULL_POINTER:
1032     ui_set_null_cursor();
1033     break;
1034    
1035     default:
1036     unimpl("System pointer message 0x%x\n", system_pointer_type);
1037     }
1038     }
1039    
1040 matty 10 /* Process a pointer PDU */
1041 matty 25 static void
1042     process_pointer_pdu(STREAM s)
1043 matty 9 {
1044 matty 10 uint16 message_type;
1045 forsberg 351 uint16 x, y;
1046 matty 9
1047 matty 10 in_uint16_le(s, message_type);
1048 matty 24 in_uint8s(s, 2); /* pad */
1049 matty 9
1050 matty 10 switch (message_type)
1051 matty 7 {
1052 matty 10 case RDP_POINTER_MOVE:
1053     in_uint16_le(s, x);
1054     in_uint16_le(s, y);
1055     if (s_check(s))
1056     ui_move_pointer(x, y);
1057     break;
1058 matty 9
1059 matty 28 case RDP_POINTER_COLOR:
1060 forsberg 351 process_colour_pointer_pdu(s);
1061 matty 28 break;
1062    
1063     case RDP_POINTER_CACHED:
1064 forsberg 351 process_cached_pointer_pdu(s);
1065 matty 28 break;
1066    
1067 astrand 508 case RDP_POINTER_SYSTEM:
1068     process_system_pointer_pdu(s);
1069     break;
1070    
1071 matty 10 default:
1072 astrand 508 unimpl("Pointer message 0x%x\n", message_type);
1073 matty 7 }
1074 matty 9 }
1075    
1076 matty 10 /* Process bitmap updates */
1077 forsberg 351 void
1078 matty 25 process_bitmap_updates(STREAM s)
1079 matty 9 {
1080 matty 10 uint16 num_updates;
1081     uint16 left, top, right, bottom, width, height;
1082 jsorg71 314 uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
1083 matty 28 uint8 *data, *bmpdata;
1084 matty 9 int i;
1085    
1086 matty 10 in_uint16_le(s, num_updates);
1087 matty 9
1088 matty 10 for (i = 0; i < num_updates; i++)
1089 matty 9 {
1090 matty 10 in_uint16_le(s, left);
1091     in_uint16_le(s, top);
1092     in_uint16_le(s, right);
1093     in_uint16_le(s, bottom);
1094     in_uint16_le(s, width);
1095     in_uint16_le(s, height);
1096     in_uint16_le(s, bpp);
1097 jsorg71 314 Bpp = (bpp + 7) / 8;
1098 matty 10 in_uint16_le(s, compress);
1099     in_uint16_le(s, bufsize);
1100 matty 9
1101 matty 10 cx = right - left + 1;
1102     cy = bottom - top + 1;
1103 matty 7
1104 forsberg 351 DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
1105     left, top, right, bottom, width, height, Bpp, compress));
1106 matty 9
1107 matty 10 if (!compress)
1108     {
1109 matty 28 int y;
1110 forsberg 410 bmpdata = (uint8 *) xmalloc(width * height * Bpp);
1111 matty 28 for (y = 0; y < height; y++)
1112     {
1113 astrand 318 in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
1114     width * Bpp);
1115 matty 28 }
1116 astrand 82 ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
1117 matty 28 xfree(bmpdata);
1118     continue;
1119 matty 10 }
1120 matty 9
1121 forsberg 351
1122     if (compress & 0x400)
1123     {
1124     size = bufsize;
1125     }
1126     else
1127     {
1128     in_uint8s(s, 2); /* pad */
1129     in_uint16_le(s, size);
1130     in_uint8s(s, 4); /* line_size, final_size */
1131     }
1132 matty 10 in_uint8p(s, data, size);
1133 forsberg 410 bmpdata = (uint8 *) xmalloc(width * height * Bpp);
1134 jsorg71 314 if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
1135 matty 9 {
1136 astrand 82 ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
1137 matty 9 }
1138 forsberg 351 else
1139     {
1140     DEBUG_RDP5(("Failed to decompress data\n"));
1141     }
1142    
1143 matty 28 xfree(bmpdata);
1144 matty 10 }
1145 matty 9 }
1146    
1147 matty 10 /* Process a palette update */
1148 forsberg 351 void
1149 matty 25 process_palette(STREAM s)
1150 matty 9 {
1151 matthewc 254 COLOURENTRY *entry;
1152     COLOURMAP map;
1153 matty 10 HCOLOURMAP hmap;
1154 matthewc 254 int i;
1155 matty 9
1156 matty 24 in_uint8s(s, 2); /* pad */
1157     in_uint16_le(s, map.ncolours);
1158     in_uint8s(s, 2); /* pad */
1159 matty 3
1160 jsorg71 436 map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
1161 matthewc 254
1162 forsberg 351 DEBUG(("PALETTE(c=%d)\n", map.ncolours));
1163    
1164 matthewc 254 for (i = 0; i < map.ncolours; i++)
1165     {
1166     entry = &map.colours[i];
1167     in_uint8(s, entry->red);
1168     in_uint8(s, entry->green);
1169     in_uint8(s, entry->blue);
1170 astrand 260 }
1171 matthewc 254
1172 matty 10 hmap = ui_create_colourmap(&map);
1173     ui_set_colourmap(hmap);
1174 matthewc 254
1175     xfree(map.colours);
1176 matty 3 }
1177    
1178 matty 10 /* Process an update PDU */
1179 matty 25 static void
1180     process_update_pdu(STREAM s)
1181 matty 9 {
1182 forsberg 351 uint16 update_type, count;
1183 matty 9
1184 matty 10 in_uint16_le(s, update_type);
1185 matty 3
1186 jsorg71 713 ui_begin_update();
1187 matty 10 switch (update_type)
1188 matty 3 {
1189 matty 10 case RDP_UPDATE_ORDERS:
1190 forsberg 351 in_uint8s(s, 2); /* pad */
1191     in_uint16_le(s, count);
1192     in_uint8s(s, 2); /* pad */
1193     process_orders(s, count);
1194 matty 10 break;
1195 matty 3
1196 matty 10 case RDP_UPDATE_BITMAP:
1197     process_bitmap_updates(s);
1198     break;
1199 matty 3
1200 matty 10 case RDP_UPDATE_PALETTE:
1201     process_palette(s);
1202     break;
1203 matty 3
1204 matty 10 case RDP_UPDATE_SYNCHRONIZE:
1205     break;
1206 matty 9
1207 matty 10 default:
1208 matty 30 unimpl("update %d\n", update_type);
1209 matty 3 }
1210 jsorg71 713 ui_end_update();
1211 matty 3 }
1212    
1213 astrand 676 /* Process a disconnect PDU */
1214     void
1215     process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
1216     {
1217     in_uint32_le(s, *ext_disc_reason);
1218    
1219     DEBUG(("Received disconnect PDU\n"));
1220     }
1221    
1222 matty 10 /* Process data PDU */
1223 astrand 676 static BOOL
1224     process_data_pdu(STREAM s, uint32 * ext_disc_reason)
1225 matty 9 {
1226 matty 10 uint8 data_pdu_type;
1227 n-ki 624 uint8 ctype;
1228     uint16 clen;
1229 n-ki 683 uint32 len;
1230 matty 9
1231 n-ki 683 uint32 roff, rlen;
1232    
1233 n-ki 687 struct stream *ns = &(g_mppc_dict.ns);
1234 n-ki 683
1235 n-ki 624 in_uint8s(s, 6); /* shareid, pad, streamid */
1236     in_uint16(s, len);
1237 matty 10 in_uint8(s, data_pdu_type);
1238 n-ki 624 in_uint8(s, ctype);
1239     in_uint16(s, clen);
1240     clen -= 18;
1241 matty 3
1242 n-ki 683 if (ctype & RDP_MPPC_COMPRESSED)
1243 n-ki 624 {
1244 jsorg71 773 if (len > RDP_MPPC_DICT_SIZE)
1245 astrand 782 error("error decompressed packet size exceeds max\n");
1246 n-ki 683 if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1247     error("error while decompressing packet\n");
1248 n-ki 624
1249 stargo 865 /* len -= 18; */
1250 n-ki 624
1251 n-ki 683 /* allocate memory and copy the uncompressed data into the temporary stream */
1252 jsorg71 711 ns->data = (uint8 *) xrealloc(ns->data, rlen);
1253 n-ki 624
1254 n-ki 687 memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
1255 n-ki 624
1256 n-ki 687 ns->size = rlen;
1257 n-ki 683 ns->end = (ns->data + ns->size);
1258     ns->p = ns->data;
1259     ns->rdp_hdr = ns->p;
1260    
1261     s = ns;
1262 n-ki 624 }
1263    
1264 matty 10 switch (data_pdu_type)
1265 matty 3 {
1266 matty 10 case RDP_DATA_PDU_UPDATE:
1267     process_update_pdu(s);
1268     break;
1269 matty 3
1270 astrand 676 case RDP_DATA_PDU_CONTROL:
1271     DEBUG(("Received Control PDU\n"));
1272     break;
1273    
1274     case RDP_DATA_PDU_SYNCHRONISE:
1275     DEBUG(("Received Sync PDU\n"));
1276     break;
1277    
1278 matty 10 case RDP_DATA_PDU_POINTER:
1279     process_pointer_pdu(s);
1280     break;
1281 matty 3
1282 matty 10 case RDP_DATA_PDU_BELL:
1283     ui_bell();
1284     break;
1285 matty 3
1286 matty 10 case RDP_DATA_PDU_LOGON:
1287 forsberg 351 DEBUG(("Received Logon PDU\n"));
1288 matty 10 /* User logged on */
1289     break;
1290 matty 3
1291 matthewc 522 case RDP_DATA_PDU_DISCONNECT:
1292 astrand 676 process_disconnect_pdu(s, ext_disc_reason);
1293     return True;
1294 matthewc 522
1295 matty 10 default:
1296 matty 30 unimpl("data PDU %d\n", data_pdu_type);
1297 matty 3 }
1298 astrand 676 return False;
1299 matty 3 }
1300    
1301 astrand 977 /* Process redirect PDU from Session Directory */
1302     static BOOL
1303     process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ )
1304     {
1305     uint32 len;
1306    
1307     /* these 2 bytes are unknown, seem to be zeros */
1308     in_uint8s(s, 2);
1309    
1310     /* read connection flags */
1311     in_uint32_le(s, g_redirect_flags);
1312    
1313     /* read length of ip string */
1314     in_uint32_le(s, len);
1315    
1316     /* read ip string */
1317     rdp_in_unistr(s, g_redirect_server, len);
1318    
1319     /* read length of cookie string */
1320     in_uint32_le(s, len);
1321    
1322     /* read cookie string (plain ASCII) */
1323     in_uint8a(s, g_redirect_cookie, len);
1324     g_redirect_cookie[len] = 0;
1325    
1326     /* read length of username string */
1327     in_uint32_le(s, len);
1328    
1329     /* read username string */
1330     rdp_in_unistr(s, g_redirect_username, len);
1331    
1332     /* read length of domain string */
1333     in_uint32_le(s, len);
1334    
1335     /* read domain string */
1336     rdp_in_unistr(s, g_redirect_domain, len);
1337    
1338     /* read length of password string */
1339     in_uint32_le(s, len);
1340    
1341     /* read password string */
1342     rdp_in_unistr(s, g_redirect_password, len);
1343    
1344     g_redirect = True;
1345    
1346     return True;
1347     }
1348    
1349 matty 10 /* Process incoming packets */
1350 jsorg71 733 /* nevers gets out of here till app is done */
1351 astrand 676 void
1352     rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1353 matty 9 {
1354 jsorg71 733 while (rdp_loop(deactivated, ext_disc_reason))
1355     ;
1356 matty 3 }
1357    
1358 jsorg71 733 /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1359 jsorg71 713 BOOL
1360     rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1361     {
1362     uint8 type;
1363     BOOL disc = False; /* True when a disconnect PDU was received */
1364     BOOL cont = True;
1365     STREAM s;
1366    
1367 astrand 717 while (cont)
1368 jsorg71 713 {
1369     s = rdp_recv(&type);
1370     if (s == NULL)
1371     return False;
1372     switch (type)
1373     {
1374     case RDP_PDU_DEMAND_ACTIVE:
1375     process_demand_active(s);
1376     *deactivated = False;
1377     break;
1378     case RDP_PDU_DEACTIVATE:
1379     DEBUG(("RDP_PDU_DEACTIVATE\n"));
1380     *deactivated = True;
1381     break;
1382 astrand 977 case RDP_PDU_REDIRECT:
1383     return process_redirect_pdu(s);
1384     break;
1385 jsorg71 713 case RDP_PDU_DATA:
1386     disc = process_data_pdu(s, ext_disc_reason);
1387     break;
1388     case 0:
1389     break;
1390     default:
1391     unimpl("PDU %d\n", type);
1392     }
1393     if (disc)
1394     return False;
1395     cont = g_next_packet < s->end;
1396     }
1397     return True;
1398     }
1399    
1400 matty 10 /* Establish a connection up to the RDP layer */
1401 matty 25 BOOL
1402     rdp_connect(char *server, uint32 flags, char *domain, char *password,
1403     char *command, char *directory)
1404 matty 9 {
1405 jsorg71 437 if (!sec_connect(server, g_username))
1406 matty 3 return False;
1407    
1408 jsorg71 437 rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1409 matty 10 return True;
1410 matty 3 }
1411    
1412 astrand 977 /* Establish a reconnection up to the RDP layer */
1413     BOOL
1414     rdp_reconnect(char *server, uint32 flags, char *domain, char *password,
1415     char *command, char *directory, char *cookie)
1416     {
1417     if (!sec_reconnect(server))
1418     return False;
1419    
1420     rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1421     return True;
1422     }
1423    
1424     /* Called during redirection to reset the state to support redirection */
1425     void
1426     rdp_reset_state(void)
1427     {
1428     g_next_packet = NULL; /* reset the packet information */
1429     g_rdp_shareid = 0;
1430     sec_reset_state();
1431     }
1432    
1433 matty 10 /* Disconnect from the RDP layer */
1434 matty 25 void
1435 matthewc 192 rdp_disconnect(void)
1436 matty 9 {
1437 matty 10 sec_disconnect();
1438 matty 9 }

  ViewVC Help
Powered by ViewVC 1.1.26