/[rdesktop]/sourceforge.net/branches/seamlessrdp-branch/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

Contents of /sourceforge.net/branches/seamlessrdp-branch/rdesktop/rdp.c

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26