/[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 886 - (hide annotations)
Sat Apr 16 11:42:34 2005 UTC (19 years, 1 month ago) by stargo
File MIME type: text/plain
File size: 31016 byte(s)
Enable rdp-compression for all bpps.
Many thanks to Vahur Sinijärv <vahur.sinijarv@cydonia.ee> for
finding the fix.

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

  ViewVC Help
Powered by ViewVC 1.1.26