/[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 1423 - (show annotations)
Sun Dec 23 06:45:47 2007 UTC (16 years, 4 months ago) by jsorg71
File MIME type: text/plain
File size: 33751 byte(s)
rdp endian is always le

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

  ViewVC Help
Powered by ViewVC 1.1.26