/[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 855 - (hide annotations)
Sun Mar 13 13:18:48 2005 UTC (19 years, 2 months ago) by stargo
File MIME type: text/plain
File size: 30383 byte(s)
unicode support from Andy Igoshin <ai@vsu.ru>
Currently disabled, need HAVE_ICONV and HAVE_ICONV_H defined to be
used. This should be done with a new configure test.

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

  ViewVC Help
Powered by ViewVC 1.1.26