/[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 858 - (hide annotations)
Sun Mar 13 13:58:23 2005 UTC (19 years, 2 months ago) by stargo
File MIME type: text/plain
File size: 30477 byte(s)
HAVE_ICONV configure test

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

  ViewVC Help
Powered by ViewVC 1.1.26