summaryrefslogtreecommitdiff
path: root/noncore/net/opierdesktop/rdp.cpp
Unidiff
Diffstat (limited to 'noncore/net/opierdesktop/rdp.cpp') (more/less context) (show whitespace changes)
-rw-r--r--noncore/net/opierdesktop/rdp.cpp748
1 files changed, 748 insertions, 0 deletions
diff --git a/noncore/net/opierdesktop/rdp.cpp b/noncore/net/opierdesktop/rdp.cpp
new file mode 100644
index 0000000..bab8568
--- a/dev/null
+++ b/noncore/net/opierdesktop/rdp.cpp
@@ -0,0 +1,748 @@
1/*
2 rdesktop: A Remote Desktop Protocol client.
3 Protocol services - RDP layer
4 Copyright (C) Matthew Chapman 1999-2002
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 "rdesktop.h"
22
23extern uint16 mcs_userid;
24extern char username[16];
25extern BOOL bitmap_compression;
26extern BOOL orders;
27extern BOOL encryption;
28extern BOOL desktop_save;
29
30uint8 *next_packet;
31uint32 rdp_shareid;
32
33/* Initialise an RDP packet */
34static STREAM
35rdp_init(int maxlen)
36{
37 STREAM s;
38
39 s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 6);
40 s_push_layer(s, rdp_hdr, 6);
41
42 return s;
43}
44
45/* Send an RDP packet */
46static void
47rdp_send(STREAM s, uint8 pdu_type)
48{
49 uint16 length;
50
51 s_pop_layer(s, rdp_hdr);
52 length = s->end - s->p;
53
54 out_uint16_le(s, length);
55 out_uint16_le(s, (pdu_type | 0x10));/* Version 1 */
56 out_uint16_le(s, (mcs_userid + 1001));
57
58 sec_send(s, encryption ? SEC_ENCRYPT : 0);
59}
60
61/* Receive an RDP packet */
62STREAM
63rdp_recv(uint8 * type)
64{
65 static STREAM rdp_s;
66 uint16 length, pdu_type;
67
68 if ((rdp_s == NULL) || (next_packet >= rdp_s->end))
69 {
70 rdp_s = sec_recv();
71 if (rdp_s == NULL)
72 return NULL;
73
74 next_packet = rdp_s->p;
75 }
76 else
77 {
78 rdp_s->p = next_packet;
79 }
80
81 in_uint16_le(rdp_s, length);
82 /* 32k packets are really 8, keepalive fix */
83 if (length == 0x8000)
84 {
85 next_packet += 8;
86 *type = 0;
87 return rdp_s;
88 }
89 in_uint16_le(rdp_s, pdu_type);
90 in_uint8s(rdp_s, 2);/* userid */
91 *type = pdu_type & 0xf;
92
93#if WITH_DEBUG
94 DEBUG(("RDP packet (type %x):\n", *type));
95 hexdump(next_packet, length);
96#endif /* */
97
98 next_packet += length;
99 return rdp_s;
100}
101
102/* Initialise an RDP data packet */
103static STREAM
104rdp_init_data(int maxlen)
105{
106 STREAM s;
107
108 s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 18);
109 s_push_layer(s, rdp_hdr, 18);
110
111 return s;
112}
113
114/* Send an RDP data packet */
115static void
116rdp_send_data(STREAM s, uint8 data_pdu_type)
117{
118 uint16 length;
119
120 s_pop_layer(s, rdp_hdr);
121 length = s->end - s->p;
122
123 out_uint16_le(s, length);
124 out_uint16_le(s, (RDP_PDU_DATA | 0x10));
125 out_uint16_le(s, (mcs_userid + 1001));
126
127 out_uint32_le(s, rdp_shareid);
128 out_uint8(s, 0);/* pad */
129 out_uint8(s, 1);/* streamid */
130 out_uint16_le(s, (length - 14));
131 out_uint8(s, data_pdu_type);
132 out_uint8(s, 0);/* compress_type */
133 out_uint16(s, 0);/* compress_len */
134
135 sec_send(s, encryption ? SEC_ENCRYPT : 0);
136}
137
138/* Output a string in Unicode */
139void
140rdp_out_unistr(STREAM s, char *string, int len)
141{
142 int i = 0, j = 0;
143
144 len += 2;
145
146 while (i < len)
147 {
148 s->p[i++] = string[j++];
149 s->p[i++] = 0;
150 }
151
152 s->p += len;
153}
154
155/* Parse a logon info packet */
156static void
157rdp_send_logon_info(uint32 flags, char *domain, char *user,
158 char *password, char *program, char *directory)
159{
160 int len_domain = 2 * strlen(domain);
161 int len_user = 2 * strlen(user);
162 int len_password = 2 * strlen(password);
163 int len_program = 2 * strlen(program);
164 int len_directory = 2 * strlen(directory);
165 uint32 sec_flags = encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
166 STREAM s;
167
168 s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
169 + len_program + len_directory + 10);
170
171 out_uint32(s, 0);
172 out_uint32_le(s, flags);
173 out_uint16_le(s, len_domain);
174 out_uint16_le(s, len_user);
175 out_uint16_le(s, len_password);
176 out_uint16_le(s, len_program);
177 out_uint16_le(s, len_directory);
178 rdp_out_unistr(s, domain, len_domain);
179 rdp_out_unistr(s, user, len_user);
180 rdp_out_unistr(s, password, len_password);
181 rdp_out_unistr(s, program, len_program);
182 rdp_out_unistr(s, directory, len_directory);
183
184 s_mark_end(s);
185 sec_send(s, sec_flags);
186}
187
188/* Send a control PDU */
189static void
190rdp_send_control(uint16 action)
191{
192 STREAM s;
193
194 s = rdp_init_data(8);
195
196 out_uint16_le(s, action);
197 out_uint16(s, 0);/* userid */
198 out_uint32(s, 0);/* control id */
199
200 s_mark_end(s);
201 rdp_send_data(s, RDP_DATA_PDU_CONTROL);
202}
203
204/* Send a synchronisation PDU */
205static void
206rdp_send_synchronise(void)
207{
208 STREAM s;
209
210 s = rdp_init_data(4);
211
212 out_uint16_le(s, 1);/* type */
213 out_uint16_le(s, 1002);
214
215 s_mark_end(s);
216 rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);
217}
218
219/* Send a single input event */
220void
221rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
222{
223 STREAM s;
224
225 s = rdp_init_data(16);
226
227 out_uint16_le(s, 1);/* number of events */
228 out_uint16(s, 0);/* pad */
229
230 out_uint32_le(s, time);
231 out_uint16_le(s, message_type);
232 out_uint16_le(s, device_flags);
233 out_uint16_le(s, param1);
234 out_uint16_le(s, param2);
235
236 s_mark_end(s);
237 rdp_send_data(s, RDP_DATA_PDU_INPUT);
238}
239
240/* Send an (empty) font information PDU */
241static void
242rdp_send_fonts(uint16 seq)
243{
244 STREAM s;
245
246 s = rdp_init_data(8);
247
248 out_uint16(s, 0);/* number of fonts */
249 out_uint16_le(s, 0x3e);/* unknown */
250 out_uint16_le(s, seq);/* unknown */
251 out_uint16_le(s, 0x32);/* entry size */
252
253 s_mark_end(s);
254 rdp_send_data(s, RDP_DATA_PDU_FONT2);
255}
256
257/* Output general capability set */
258static void
259rdp_out_general_caps(STREAM s)
260{
261 out_uint16_le(s, RDP_CAPSET_GENERAL);
262 out_uint16_le(s, RDP_CAPLEN_GENERAL);
263
264 out_uint16_le(s, 1);/* OS major type */
265 out_uint16_le(s, 3);/* OS minor type */
266 out_uint16_le(s, 0x200);/* Protocol version */
267 out_uint16(s, 0);/* Pad */
268 out_uint16(s, 0);/* Compression types */
269 out_uint16(s, 0);/* Pad */
270 out_uint16(s, 0);/* Update capability */
271 out_uint16(s, 0);/* Remote unshare capability */
272 out_uint16(s, 0);/* Compression level */
273 out_uint16(s, 0);/* Pad */
274}
275
276/* Output bitmap capability set */
277static void
278rdp_out_bitmap_caps(STREAM s)
279{
280 out_uint16_le(s, RDP_CAPSET_BITMAP);
281 out_uint16_le(s, RDP_CAPLEN_BITMAP);
282
283 out_uint16_le(s, 8);/* Preferred BPP */
284 out_uint16_le(s, 1);/* Receive 1 BPP */
285 out_uint16_le(s, 1);/* Receive 4 BPP */
286 out_uint16_le(s, 1);/* Receive 8 BPP */
287 out_uint16_le(s, 800);/* Desktop width */
288 out_uint16_le(s, 600);/* Desktop height */
289 out_uint16(s, 0);/* Pad */
290 out_uint16(s, 0);/* Allow resize */
291 out_uint16_le(s, bitmap_compression ? 1 : 0);/* Support compression */
292 out_uint16(s, 0);/* Unknown */
293 out_uint16_le(s, 1);/* Unknown */
294 out_uint16(s, 0);/* Pad */
295}
296
297/* Output order capability set */
298static void
299rdp_out_order_caps(STREAM s)
300{
301 uint8 order_caps[32];
302
303
304 memset(order_caps, 0, 32);
305 order_caps[0] = 1;/* dest blt */
306 order_caps[1] = 1;/* pat blt */
307 order_caps[2] = 1;/* screen blt */
308 // order_caps[3] = 1;/* required for memblt? */
309 order_caps[8] = 1;/* line */
310 order_caps[9] = 1;/* line */
311 order_caps[10] = 1;/* rect */
312 order_caps[11] = (desktop_save == False ? 0 : 1);/* desksave */
313 order_caps[13] = 1;/* memblt */
314 order_caps[14] = 1;/* triblt */
315 order_caps[22] = 1;/* polyline */
316 order_caps[27] = 1;/* text2 */
317 out_uint16_le(s, RDP_CAPSET_ORDER);
318 out_uint16_le(s, RDP_CAPLEN_ORDER);
319
320 out_uint8s(s, 20);/* Terminal desc, pad */
321 out_uint16_le(s, 1);/* Cache X granularity */
322 out_uint16_le(s, 20);/* Cache Y granularity */
323 out_uint16(s, 0);/* Pad */
324 out_uint16_le(s, 1);/* Max order level */
325 out_uint16_le(s, 0x147);/* Number of fonts */
326 out_uint16_le(s, 0x2a);/* Capability flags */
327 out_uint8p(s, order_caps, 32);/* Orders supported */
328 out_uint16_le(s, 0x6a1);/* Text capability flags */
329 out_uint8s(s, 6);/* Pad */
330 out_uint32_le(s, desktop_save == False ? 0 : 0x38400);/* Desktop cache size */
331 //out_uint32_le(s, 0); // desktop cache set to 0
332 out_uint32(s, 0);/* Unknown */
333 out_uint32_le(s, 0x4e4);/* Unknown */
334}
335
336/* Output bitmap cache capability set */
337static void
338rdp_out_bmpcache_caps(STREAM s)
339{
340 out_uint16_le(s, RDP_CAPSET_BMPCACHE);
341 out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
342
343 out_uint8s(s, 24);/* unused */
344 out_uint16_le(s, 0x258);/* entries */
345 out_uint16_le(s, 0x100);/* max cell size */
346 out_uint16_le(s, 0x12c);/* entries */
347 out_uint16_le(s, 0x400);/* max cell size */
348 out_uint16_le(s, 0x106);/* entries */
349 out_uint16_le(s, 0x1000);/* max cell size */
350}
351
352/* Output control capability set */
353static void
354rdp_out_control_caps(STREAM s)
355{
356 out_uint16_le(s, RDP_CAPSET_CONTROL);
357 out_uint16_le(s, RDP_CAPLEN_CONTROL);
358
359 out_uint16(s, 0);/* Control capabilities */
360 out_uint16(s, 0);/* Remote detach */
361 out_uint16_le(s, 2);/* Control interest */
362 out_uint16_le(s, 2);/* Detach interest */
363}
364
365/* Output activation capability set */
366static void
367rdp_out_activate_caps(STREAM s)
368{
369 out_uint16_le(s, RDP_CAPSET_ACTIVATE);
370 out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
371
372 out_uint16(s, 0);/* Help key */
373 out_uint16(s, 0);/* Help index key */
374 out_uint16(s, 0);/* Extended help key */
375 out_uint16(s, 0);/* Window activate */
376}
377
378/* Output pointer capability set */
379static void
380rdp_out_pointer_caps(STREAM s)
381{
382 out_uint16_le(s, RDP_CAPSET_POINTER);
383 out_uint16_le(s, RDP_CAPLEN_POINTER);
384
385 out_uint16(s, 0);/* Colour pointer */
386 out_uint16_le(s, 20);/* Cache size */
387}
388
389/* Output share capability set */
390static void
391rdp_out_share_caps(STREAM s)
392{
393 out_uint16_le(s, RDP_CAPSET_SHARE);
394 out_uint16_le(s, RDP_CAPLEN_SHARE);
395
396 out_uint16(s, 0);/* userid */
397 out_uint16(s, 0);/* pad */
398}
399
400/* Output colour cache capability set */
401static void
402rdp_out_colcache_caps(STREAM s)
403{
404 out_uint16_le(s, RDP_CAPSET_COLCACHE);
405 out_uint16_le(s, RDP_CAPLEN_COLCACHE);
406
407 out_uint16_le(s, 6);/* cache size */
408 out_uint16(s, 0);/* pad */
409}
410
411static uint8 canned_caps[] = {
412 0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,
413 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
414 0x00, 0x00, 0x00, 0x00, 0x00,
415 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
416 0x00, 0x00, 0x00, 0x00, 0x00,
417 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
418 0x00, 0x00, 0x00, 0x00, 0x00,
419 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
420 0x00, 0x00, 0x00, 0x00, 0x00,
421 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
422 0x0C, 0x00, 0x08, 0x00, 0x01,
423 0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
424 0x10, 0x00, 0x34, 0x00, 0xFE,
425 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,
426 0xFE, 0x00, 0x08, 0x00, 0xFE,
427 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,
428 0xFE, 0x00, 0x80, 0x00, 0xFE,
429 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
430 0x02, 0x00, 0x00, 0x00
431};
432
433/* Output unknown capability set */
434static void
435rdp_out_unknown_caps(STREAM s)
436{
437 out_uint16_le(s, RDP_CAPSET_UNKNOWN);
438 out_uint16_le(s, 0x58);
439
440 out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);
441}
442
443/* Send a confirm active PDU */
444static void
445rdp_send_confirm_active(void)
446{
447 STREAM s;
448 uint16 caplen =
449 RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
450 RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
451 RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
452 RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;
453
454 s = rdp_init(14 + caplen + sizeof(RDP_SOURCE));
455
456 out_uint32_le(s, rdp_shareid);
457 out_uint16_le(s, 0x3ea);/* userid */
458 out_uint16_le(s, sizeof(RDP_SOURCE));
459 out_uint16_le(s, caplen);
460
461 out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
462 out_uint16_le(s, 0xd);/* num_caps */
463 out_uint8s(s, 2);/* pad */
464
465 rdp_out_general_caps(s);
466 rdp_out_bitmap_caps(s);
467 rdp_out_order_caps(s);
468 rdp_out_bmpcache_caps(s);
469 rdp_out_colcache_caps(s);
470 rdp_out_activate_caps(s);
471 rdp_out_control_caps(s);
472 rdp_out_pointer_caps(s);
473 rdp_out_share_caps(s);
474 rdp_out_unknown_caps(s);
475
476 s_mark_end(s);
477 rdp_send(s, RDP_PDU_CONFIRM_ACTIVE);
478}
479
480/* Respond to a demand active PDU */
481void
482process_demand_active(STREAM s)
483{
484 uint8 type;
485
486 in_uint32_le(s, rdp_shareid);
487
488 DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", rdp_shareid));
489
490 rdp_send_confirm_active();
491 rdp_send_synchronise();
492 rdp_send_control(RDP_CTL_COOPERATE);
493 rdp_send_control(RDP_CTL_REQUEST_CONTROL);
494 rdp_recv(&type);/* RDP_PDU_SYNCHRONIZE */
495 rdp_recv(&type);/* RDP_CTL_COOPERATE */
496 rdp_recv(&type);/* RDP_CTL_GRANT_CONTROL */
497 rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, 0, 0);
498 rdp_send_fonts(1);
499 rdp_send_fonts(2);
500 rdp_recv(&type);/* RDP_PDU_UNKNOWN 0x28 */
501 reset_order_state();
502}
503
504/* Process a pointer PDU */
505static void
506process_pointer_pdu(STREAM s)
507{
508 uint16 message_type;
509 uint16 x, y, width, height, cache_idx, masklen, datalen;
510 uint8 *mask, *data;
511 HCURSOR cursor;
512
513 in_uint16_le(s, message_type);
514 in_uint8s(s, 2);/* pad */
515
516 switch (message_type)
517 {
518 case RDP_POINTER_MOVE:
519 in_uint16_le(s, x);
520 in_uint16_le(s, y);
521 if (s_check(s))
522 ui_move_pointer(x, y);
523 break;
524
525 case RDP_POINTER_COLOR:
526 in_uint16_le(s, cache_idx);
527 in_uint16_le(s, x);
528 in_uint16_le(s, y);
529 in_uint16_le(s, width);
530 in_uint16_le(s, height);
531 in_uint16_le(s, masklen);
532 in_uint16_le(s, datalen);
533 in_uint8p(s, data, datalen);
534 in_uint8p(s, mask, masklen);
535 cursor = ui_create_cursor(x, y, width, height, mask, data);
536 ui_set_cursor(cursor);
537 cache_put_cursor(cache_idx, cursor);
538 break;
539
540 case RDP_POINTER_CACHED:
541 in_uint16_le(s, cache_idx);
542 ui_set_cursor(cache_get_cursor(cache_idx));
543 break;
544
545 default:
546 DEBUG(("Pointer message 0x%x\n", message_type));
547 }
548}
549
550/* Process bitmap updates */
551static void
552process_bitmap_updates(STREAM s)
553{
554 uint16 num_updates;
555 uint16 left, top, right, bottom, width, height;
556 uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
557 uint8 *data, *bmpdata;
558 int i;
559
560 in_uint16_le(s, num_updates);
561
562 for (i = 0; i < num_updates; i++)
563 {
564 in_uint16_le(s, left);
565 in_uint16_le(s, top);
566 in_uint16_le(s, right);
567 in_uint16_le(s, bottom);
568 in_uint16_le(s, width);
569 in_uint16_le(s, height);
570 in_uint16_le(s, bpp);
571 Bpp = (bpp + 7) / 8;
572 in_uint16_le(s, compress);
573 in_uint16_le(s, bufsize);
574
575 cx = right - left + 1;
576 cy = bottom - top + 1;
577
578 DEBUG(("UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,cmp=%d)\n",
579 left, top, right, bottom, width, height, compress));
580
581 if (!compress)
582 {
583 int y;
584 bmpdata = (uint8*)xmalloc(width * height * Bpp);
585 for (y = 0; y < height; y++)
586 {
587 in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
588 width * Bpp);
589 }
590 ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
591 xfree(bmpdata);
592 continue;
593 }
594
595 in_uint8s(s, 2);/* pad */
596 in_uint16_le(s, size);
597 in_uint8s(s, 4);/* line_size, final_size */
598 in_uint8p(s, data, size);
599 bmpdata = (uint8*)xmalloc(width * height * Bpp);
600 if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
601 {
602 ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
603 }
604 xfree(bmpdata);
605 }
606}
607
608/* Process a palette update */
609static void
610process_palette(STREAM s)
611{
612 COLOURENTRY *entry;
613 COLOURMAP map;
614 HCOLOURMAP hmap;
615 int i;
616 uint8 data[1536];
617
618 in_uint8s(s, 2);/* pad */
619 in_uint16_le(s, map.ncolours);
620 in_uint8s(s, 2);/* pad */
621
622 map.colours = (COLOURENTRY*)data;
623
624 for (i = 0; i < map.ncolours; i++)
625 {
626 entry = &map.colours[i];
627 in_uint8(s, entry->red);
628 in_uint8(s, entry->green);
629 in_uint8(s, entry->blue);
630 }
631 hmap = ui_create_colourmap(&map);
632 ui_set_colourmap(hmap);
633}
634
635/* Process an update PDU */
636static void
637process_update_pdu(STREAM s)
638{
639 uint16 update_type;
640
641 in_uint16_le(s, update_type);
642 ui_begin_update();
643 switch (update_type)
644 {
645 case RDP_UPDATE_ORDERS:
646 process_orders(s);
647 break;
648
649 case RDP_UPDATE_BITMAP:
650 process_bitmap_updates(s);
651 break;
652
653 case RDP_UPDATE_PALETTE:
654 process_palette(s);
655 break;
656
657 case RDP_UPDATE_SYNCHRONIZE:
658 break;
659
660 default:
661 unimpl("update %d\n", update_type);
662 }
663 ui_end_update();
664}
665
666/* Process data PDU */
667void
668process_data_pdu(STREAM s)
669{
670 uint8 data_pdu_type;
671
672 in_uint8s(s, 8);/* shareid, pad, streamid, length */
673 in_uint8(s, data_pdu_type);
674 in_uint8s(s, 3);/* compress_type, compress_len */
675
676 switch (data_pdu_type)
677 {
678 case RDP_DATA_PDU_UPDATE:
679 process_update_pdu(s);
680 break;
681
682 case RDP_DATA_PDU_POINTER:
683 process_pointer_pdu(s);
684 break;
685
686 case RDP_DATA_PDU_BELL:
687 ui_bell();
688 break;
689
690 case RDP_DATA_PDU_LOGON:
691 /* User logged on */
692 break;
693
694 default:
695 unimpl("data PDU %d\n", data_pdu_type);
696 }
697}
698
699/* Process incoming packets */
700BOOL
701rdp_main_loop(void)
702{
703 uint8 type;
704 STREAM s;
705 BOOL cont = True;
706 while (cont)
707 {
708 s = rdp_recv(&type);
709 if (s == NULL)
710 return False;
711 switch (type)
712 {
713 case RDP_PDU_DEMAND_ACTIVE:
714 process_demand_active(s);
715 break;
716 case RDP_PDU_DEACTIVATE:
717 break;
718 case RDP_PDU_DATA:
719 process_data_pdu(s);
720 break;
721 case 0:
722 break;
723 default:
724 unimpl("PDU %d\n", type);
725 }
726 cont = next_packet < s->end;
727 }
728 return True;
729}
730
731/* Establish a connection up to the RDP layer */
732BOOL
733rdp_connect(char *server, uint32 flags, char *domain, char *password,
734 char *command, char *directory)
735{
736 if (!sec_connect(server))
737 return False;
738
739 rdp_send_logon_info(flags, domain, username, password, command, directory);
740 return True;
741}
742
743/* Disconnect from the RDP layer */
744void
745rdp_disconnect(void)
746{
747 sec_disconnect();
748}