/[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 864 - (hide annotations)
Mon Mar 14 18:02:24 2005 UTC (19 years, 2 months ago) by stargo
File MIME type: text/plain
File size: 30683 byte(s)
handle iconv-failure more gracefully

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

  ViewVC Help
Powered by ViewVC 1.1.26