/[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 905 - (hide annotations)
Fri May 20 22:09:32 2005 UTC (19 years ago) by jdmeijer
File MIME type: text/plain
File size: 31093 byte(s)
Tell the server to stop sending window updates when the rdesktop window is unmapped

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

  ViewVC Help
Powered by ViewVC 1.1.26