/[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

Contents of /sourceforge.net/trunk/rdesktop/rdp.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 977 - (show annotations)
Mon Aug 8 19:15:57 2005 UTC (18 years, 9 months ago) by astrand
File MIME type: text/plain
File size: 33247 byte(s)
Applied patch #1247780 (slightly modified) from Brian Chapeau: Session Directory support.

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_bpp;
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_bpp); /* Preferred BPP */
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_bpp + 7) / 8;
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, bpp;
885
886 in_uint16_le(s, bpp);
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 bpp to: %dx%dx%d\n", width, height, bpp));
893
894 /*
895 * The server may limit bpp and change the size of the desktop (for
896 * example when shadowing another session).
897 */
898 if (g_server_bpp != bpp)
899 {
900 warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
901 g_server_bpp = bpp;
902 }
903 if (g_width != width || g_height != height)
904 {
905 warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
906 width, height);
907 g_width = width;
908 g_height = height;
909 ui_resize_window();
910 }
911 }
912
913 /* Process server capabilities */
914 static void
915 rdp_process_server_caps(STREAM s, uint16 length)
916 {
917 int n;
918 uint8 *next, *start;
919 uint16 ncapsets, capset_type, capset_length;
920
921 start = s->p;
922
923 in_uint16_le(s, ncapsets);
924 in_uint8s(s, 2); /* pad */
925
926 for (n = 0; n < ncapsets; n++)
927 {
928 if (s->p > start + length)
929 return;
930
931 in_uint16_le(s, capset_type);
932 in_uint16_le(s, capset_length);
933
934 next = s->p + capset_length - 4;
935
936 switch (capset_type)
937 {
938 case RDP_CAPSET_GENERAL:
939 rdp_process_general_caps(s);
940 break;
941
942 case RDP_CAPSET_BITMAP:
943 rdp_process_bitmap_caps(s);
944 break;
945 }
946
947 s->p = next;
948 }
949 }
950
951 /* Respond to a demand active PDU */
952 static void
953 process_demand_active(STREAM s)
954 {
955 uint8 type;
956 uint16 len_src_descriptor, len_combined_caps;
957
958 in_uint32_le(s, g_rdp_shareid);
959 in_uint16_le(s, len_src_descriptor);
960 in_uint16_le(s, len_combined_caps);
961 in_uint8s(s, len_src_descriptor);
962
963 DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
964 rdp_process_server_caps(s, len_combined_caps);
965
966 rdp_send_confirm_active();
967 rdp_send_synchronise();
968 rdp_send_control(RDP_CTL_COOPERATE);
969 rdp_send_control(RDP_CTL_REQUEST_CONTROL);
970 rdp_recv(&type); /* RDP_PDU_SYNCHRONIZE */
971 rdp_recv(&type); /* RDP_CTL_COOPERATE */
972 rdp_recv(&type); /* RDP_CTL_GRANT_CONTROL */
973 rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);
974
975 if (g_use_rdp5)
976 {
977 rdp_enum_bmpcache2();
978 rdp_send_fonts(3);
979 }
980 else
981 {
982 rdp_send_fonts(1);
983 rdp_send_fonts(2);
984 }
985
986 rdp_recv(&type); /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
987 reset_order_state();
988 }
989
990 /* Process a colour pointer PDU */
991 void
992 process_colour_pointer_pdu(STREAM s)
993 {
994 uint16 x, y, width, height, cache_idx, masklen, datalen;
995 uint8 *mask, *data;
996 HCURSOR cursor;
997
998 in_uint16_le(s, cache_idx);
999 in_uint16_le(s, x);
1000 in_uint16_le(s, y);
1001 in_uint16_le(s, width);
1002 in_uint16_le(s, height);
1003 in_uint16_le(s, masklen);
1004 in_uint16_le(s, datalen);
1005 in_uint8p(s, data, datalen);
1006 in_uint8p(s, mask, masklen);
1007 cursor = ui_create_cursor(x, y, width, height, mask, data);
1008 ui_set_cursor(cursor);
1009 cache_put_cursor(cache_idx, cursor);
1010 }
1011
1012 /* Process a cached pointer PDU */
1013 void
1014 process_cached_pointer_pdu(STREAM s)
1015 {
1016 uint16 cache_idx;
1017
1018 in_uint16_le(s, cache_idx);
1019 ui_set_cursor(cache_get_cursor(cache_idx));
1020 }
1021
1022 /* Process a system pointer PDU */
1023 void
1024 process_system_pointer_pdu(STREAM s)
1025 {
1026 uint16 system_pointer_type;
1027
1028 in_uint16(s, system_pointer_type);
1029 switch (system_pointer_type)
1030 {
1031 case RDP_NULL_POINTER:
1032 ui_set_null_cursor();
1033 break;
1034
1035 default:
1036 unimpl("System pointer message 0x%x\n", system_pointer_type);
1037 }
1038 }
1039
1040 /* Process a pointer PDU */
1041 static void
1042 process_pointer_pdu(STREAM s)
1043 {
1044 uint16 message_type;
1045 uint16 x, y;
1046
1047 in_uint16_le(s, message_type);
1048 in_uint8s(s, 2); /* pad */
1049
1050 switch (message_type)
1051 {
1052 case RDP_POINTER_MOVE:
1053 in_uint16_le(s, x);
1054 in_uint16_le(s, y);
1055 if (s_check(s))
1056 ui_move_pointer(x, y);
1057 break;
1058
1059 case RDP_POINTER_COLOR:
1060 process_colour_pointer_pdu(s);
1061 break;
1062
1063 case RDP_POINTER_CACHED:
1064 process_cached_pointer_pdu(s);
1065 break;
1066
1067 case RDP_POINTER_SYSTEM:
1068 process_system_pointer_pdu(s);
1069 break;
1070
1071 default:
1072 unimpl("Pointer message 0x%x\n", message_type);
1073 }
1074 }
1075
1076 /* Process bitmap updates */
1077 void
1078 process_bitmap_updates(STREAM s)
1079 {
1080 uint16 num_updates;
1081 uint16 left, top, right, bottom, width, height;
1082 uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
1083 uint8 *data, *bmpdata;
1084 int i;
1085
1086 in_uint16_le(s, num_updates);
1087
1088 for (i = 0; i < num_updates; i++)
1089 {
1090 in_uint16_le(s, left);
1091 in_uint16_le(s, top);
1092 in_uint16_le(s, right);
1093 in_uint16_le(s, bottom);
1094 in_uint16_le(s, width);
1095 in_uint16_le(s, height);
1096 in_uint16_le(s, bpp);
1097 Bpp = (bpp + 7) / 8;
1098 in_uint16_le(s, compress);
1099 in_uint16_le(s, bufsize);
1100
1101 cx = right - left + 1;
1102 cy = bottom - top + 1;
1103
1104 DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
1105 left, top, right, bottom, width, height, Bpp, compress));
1106
1107 if (!compress)
1108 {
1109 int y;
1110 bmpdata = (uint8 *) xmalloc(width * height * Bpp);
1111 for (y = 0; y < height; y++)
1112 {
1113 in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
1114 width * Bpp);
1115 }
1116 ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
1117 xfree(bmpdata);
1118 continue;
1119 }
1120
1121
1122 if (compress & 0x400)
1123 {
1124 size = bufsize;
1125 }
1126 else
1127 {
1128 in_uint8s(s, 2); /* pad */
1129 in_uint16_le(s, size);
1130 in_uint8s(s, 4); /* line_size, final_size */
1131 }
1132 in_uint8p(s, data, size);
1133 bmpdata = (uint8 *) xmalloc(width * height * Bpp);
1134 if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
1135 {
1136 ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
1137 }
1138 else
1139 {
1140 DEBUG_RDP5(("Failed to decompress data\n"));
1141 }
1142
1143 xfree(bmpdata);
1144 }
1145 }
1146
1147 /* Process a palette update */
1148 void
1149 process_palette(STREAM s)
1150 {
1151 COLOURENTRY *entry;
1152 COLOURMAP map;
1153 HCOLOURMAP hmap;
1154 int i;
1155
1156 in_uint8s(s, 2); /* pad */
1157 in_uint16_le(s, map.ncolours);
1158 in_uint8s(s, 2); /* pad */
1159
1160 map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
1161
1162 DEBUG(("PALETTE(c=%d)\n", map.ncolours));
1163
1164 for (i = 0; i < map.ncolours; i++)
1165 {
1166 entry = &map.colours[i];
1167 in_uint8(s, entry->red);
1168 in_uint8(s, entry->green);
1169 in_uint8(s, entry->blue);
1170 }
1171
1172 hmap = ui_create_colourmap(&map);
1173 ui_set_colourmap(hmap);
1174
1175 xfree(map.colours);
1176 }
1177
1178 /* Process an update PDU */
1179 static void
1180 process_update_pdu(STREAM s)
1181 {
1182 uint16 update_type, count;
1183
1184 in_uint16_le(s, update_type);
1185
1186 ui_begin_update();
1187 switch (update_type)
1188 {
1189 case RDP_UPDATE_ORDERS:
1190 in_uint8s(s, 2); /* pad */
1191 in_uint16_le(s, count);
1192 in_uint8s(s, 2); /* pad */
1193 process_orders(s, count);
1194 break;
1195
1196 case RDP_UPDATE_BITMAP:
1197 process_bitmap_updates(s);
1198 break;
1199
1200 case RDP_UPDATE_PALETTE:
1201 process_palette(s);
1202 break;
1203
1204 case RDP_UPDATE_SYNCHRONIZE:
1205 break;
1206
1207 default:
1208 unimpl("update %d\n", update_type);
1209 }
1210 ui_end_update();
1211 }
1212
1213 /* Process a disconnect PDU */
1214 void
1215 process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
1216 {
1217 in_uint32_le(s, *ext_disc_reason);
1218
1219 DEBUG(("Received disconnect PDU\n"));
1220 }
1221
1222 /* Process data PDU */
1223 static BOOL
1224 process_data_pdu(STREAM s, uint32 * ext_disc_reason)
1225 {
1226 uint8 data_pdu_type;
1227 uint8 ctype;
1228 uint16 clen;
1229 uint32 len;
1230
1231 uint32 roff, rlen;
1232
1233 struct stream *ns = &(g_mppc_dict.ns);
1234
1235 in_uint8s(s, 6); /* shareid, pad, streamid */
1236 in_uint16(s, len);
1237 in_uint8(s, data_pdu_type);
1238 in_uint8(s, ctype);
1239 in_uint16(s, clen);
1240 clen -= 18;
1241
1242 if (ctype & RDP_MPPC_COMPRESSED)
1243 {
1244 if (len > RDP_MPPC_DICT_SIZE)
1245 error("error decompressed packet size exceeds max\n");
1246 if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1247 error("error while decompressing packet\n");
1248
1249 /* len -= 18; */
1250
1251 /* allocate memory and copy the uncompressed data into the temporary stream */
1252 ns->data = (uint8 *) xrealloc(ns->data, rlen);
1253
1254 memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
1255
1256 ns->size = rlen;
1257 ns->end = (ns->data + ns->size);
1258 ns->p = ns->data;
1259 ns->rdp_hdr = ns->p;
1260
1261 s = ns;
1262 }
1263
1264 switch (data_pdu_type)
1265 {
1266 case RDP_DATA_PDU_UPDATE:
1267 process_update_pdu(s);
1268 break;
1269
1270 case RDP_DATA_PDU_CONTROL:
1271 DEBUG(("Received Control PDU\n"));
1272 break;
1273
1274 case RDP_DATA_PDU_SYNCHRONISE:
1275 DEBUG(("Received Sync PDU\n"));
1276 break;
1277
1278 case RDP_DATA_PDU_POINTER:
1279 process_pointer_pdu(s);
1280 break;
1281
1282 case RDP_DATA_PDU_BELL:
1283 ui_bell();
1284 break;
1285
1286 case RDP_DATA_PDU_LOGON:
1287 DEBUG(("Received Logon PDU\n"));
1288 /* User logged on */
1289 break;
1290
1291 case RDP_DATA_PDU_DISCONNECT:
1292 process_disconnect_pdu(s, ext_disc_reason);
1293 return True;
1294
1295 default:
1296 unimpl("data PDU %d\n", data_pdu_type);
1297 }
1298 return False;
1299 }
1300
1301 /* Process redirect PDU from Session Directory */
1302 static BOOL
1303 process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ )
1304 {
1305 uint32 len;
1306
1307 /* these 2 bytes are unknown, seem to be zeros */
1308 in_uint8s(s, 2);
1309
1310 /* read connection flags */
1311 in_uint32_le(s, g_redirect_flags);
1312
1313 /* read length of ip string */
1314 in_uint32_le(s, len);
1315
1316 /* read ip string */
1317 rdp_in_unistr(s, g_redirect_server, len);
1318
1319 /* read length of cookie string */
1320 in_uint32_le(s, len);
1321
1322 /* read cookie string (plain ASCII) */
1323 in_uint8a(s, g_redirect_cookie, len);
1324 g_redirect_cookie[len] = 0;
1325
1326 /* read length of username string */
1327 in_uint32_le(s, len);
1328
1329 /* read username string */
1330 rdp_in_unistr(s, g_redirect_username, len);
1331
1332 /* read length of domain string */
1333 in_uint32_le(s, len);
1334
1335 /* read domain string */
1336 rdp_in_unistr(s, g_redirect_domain, len);
1337
1338 /* read length of password string */
1339 in_uint32_le(s, len);
1340
1341 /* read password string */
1342 rdp_in_unistr(s, g_redirect_password, len);
1343
1344 g_redirect = True;
1345
1346 return True;
1347 }
1348
1349 /* Process incoming packets */
1350 /* nevers gets out of here till app is done */
1351 void
1352 rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1353 {
1354 while (rdp_loop(deactivated, ext_disc_reason))
1355 ;
1356 }
1357
1358 /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1359 BOOL
1360 rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1361 {
1362 uint8 type;
1363 BOOL disc = False; /* True when a disconnect PDU was received */
1364 BOOL cont = True;
1365 STREAM s;
1366
1367 while (cont)
1368 {
1369 s = rdp_recv(&type);
1370 if (s == NULL)
1371 return False;
1372 switch (type)
1373 {
1374 case RDP_PDU_DEMAND_ACTIVE:
1375 process_demand_active(s);
1376 *deactivated = False;
1377 break;
1378 case RDP_PDU_DEACTIVATE:
1379 DEBUG(("RDP_PDU_DEACTIVATE\n"));
1380 *deactivated = True;
1381 break;
1382 case RDP_PDU_REDIRECT:
1383 return process_redirect_pdu(s);
1384 break;
1385 case RDP_PDU_DATA:
1386 disc = process_data_pdu(s, ext_disc_reason);
1387 break;
1388 case 0:
1389 break;
1390 default:
1391 unimpl("PDU %d\n", type);
1392 }
1393 if (disc)
1394 return False;
1395 cont = g_next_packet < s->end;
1396 }
1397 return True;
1398 }
1399
1400 /* Establish a connection up to the RDP layer */
1401 BOOL
1402 rdp_connect(char *server, uint32 flags, char *domain, char *password,
1403 char *command, char *directory)
1404 {
1405 if (!sec_connect(server, g_username))
1406 return False;
1407
1408 rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1409 return True;
1410 }
1411
1412 /* Establish a reconnection up to the RDP layer */
1413 BOOL
1414 rdp_reconnect(char *server, uint32 flags, char *domain, char *password,
1415 char *command, char *directory, char *cookie)
1416 {
1417 if (!sec_reconnect(server))
1418 return False;
1419
1420 rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1421 return True;
1422 }
1423
1424 /* Called during redirection to reset the state to support redirection */
1425 void
1426 rdp_reset_state(void)
1427 {
1428 g_next_packet = NULL; /* reset the packet information */
1429 g_rdp_shareid = 0;
1430 sec_reset_state();
1431 }
1432
1433 /* Disconnect from the RDP layer */
1434 void
1435 rdp_disconnect(void)
1436 {
1437 sec_disconnect();
1438 }

  ViewVC Help
Powered by ViewVC 1.1.26