/[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 861 - (hide annotations)
Sun Mar 13 17:40:51 2005 UTC (19 years, 2 months ago) by stargo
File MIME type: text/plain
File size: 30550 byte(s)
indent fixes

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

  ViewVC Help
Powered by ViewVC 1.1.26