/[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 857 - (hide annotations)
Sun Mar 13 13:36:04 2005 UTC (19 years, 2 months ago) by stargo
File MIME type: text/plain
File size: 30408 byte(s)
configure test for HAVE_ICONV_H, HAVE_LOCALE_H and HAVE_LANGINFO_H
still no test for HAVE_ICONV

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

  ViewVC Help
Powered by ViewVC 1.1.26