/[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 863 - (hide annotations)
Mon Mar 14 17:47:46 2005 UTC (19 years, 2 months ago) by stargo
File MIME type: text/plain
File size: 30245 byte(s)
use UTF-16LE instead of UTF-16 => let iconv swab the bytes for us

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

  ViewVC Help
Powered by ViewVC 1.1.26