/[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 889 - (hide annotations)
Sun Apr 17 23:14:20 2005 UTC (19 years, 1 month ago) by jdmeijer
File MIME type: text/plain
File size: 30698 byte(s)
Add alternative mppc decompression code with 64kB history buffer from Vahur Sinijärv, and reenable rdp5 (persistent) bitmap cache 2 (64x64)

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

  ViewVC Help
Powered by ViewVC 1.1.26