/[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 879 - (hide annotations)
Sun Apr 3 18:08:05 2005 UTC (19 years, 1 month ago) by astrand
File MIME type: text/plain
File size: 30713 byte(s)
Indent fixes

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

  ViewVC Help
Powered by ViewVC 1.1.26