1
/* -*- c-basic-offset: 8 -*-
2
rdesktop: A Remote Desktop Protocol client.
3
Protocol services - RDP layer
4
Copyright (C) Matthew Chapman 1999-2002
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.
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.
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.
24
extern uint16 g_mcs_userid;
25
extern char g_username[16];
26
extern BOOL g_bitmap_compression;
28
extern BOOL g_encryption;
29
extern BOOL g_desktop_save;
30
extern BOOL g_use_rdp5;
31
extern uint16 g_server_rdp_version;
32
extern int g_server_bpp;
38
static uint32 g_packetno;
41
/* Receive an RDP packet */
43
rdp_recv(uint8 * type)
46
uint16 length, pdu_type;
48
if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))
54
g_next_packet = rdp_s->p;
58
rdp_s->p = g_next_packet;
61
in_uint16_le(rdp_s, length);
62
/* 32k packets are really 8, keepalive fix */
69
in_uint16_le(rdp_s, pdu_type);
70
in_uint8s(rdp_s, 2); /* userid */
71
*type = pdu_type & 0xf;
74
DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type));
75
hexdump(g_next_packet, length);
78
g_next_packet += length;
82
/* Initialise an RDP data packet */
84
rdp_init_data(int maxlen)
88
s = sec_init(g_encryption ? SEC_ENCRYPT : 0, maxlen + 18);
89
s_push_layer(s, rdp_hdr, 18);
94
/* Send an RDP data packet */
96
rdp_send_data(STREAM s, uint8 data_pdu_type)
100
s_pop_layer(s, rdp_hdr);
101
length = s->end - s->p;
103
out_uint16_le(s, length);
104
out_uint16_le(s, (RDP_PDU_DATA | 0x10));
105
out_uint16_le(s, (g_mcs_userid + 1001));
107
out_uint32_le(s, g_rdp_shareid);
108
out_uint8(s, 0); /* pad */
109
out_uint8(s, 1); /* streamid */
110
out_uint16_le(s, (length - 14));
111
out_uint8(s, data_pdu_type);
112
out_uint8(s, 0); /* compress_type */
113
out_uint16(s, 0); /* compress_len */
115
sec_send(s, g_encryption ? SEC_ENCRYPT : 0);
118
/* Output a string in Unicode */
120
rdp_out_unistr(STREAM s, char *string, int len)
128
s->p[i++] = string[j++];
135
/* Parse a logon info packet */
137
rdp_send_logon_info(uint32 flags, char *domain, char *user,
138
char *password, char *program, char *directory)
140
int len_domain = 2 * strlen(domain);
141
int len_user = 2 * strlen(user);
142
int len_password = 2 * strlen(password);
143
int len_program = 2 * strlen(program);
144
int len_directory = 2 * strlen(directory);
145
int len_ip = 2 * strlen("127.0.0.1");
146
int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
148
uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
150
time_t t = time(NULL);
153
if (!g_use_rdp5 || 1 == g_server_rdp_version)
155
DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
157
s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
158
+ len_program + len_directory + 10);
161
out_uint32_le(s, flags);
162
out_uint16_le(s, len_domain);
163
out_uint16_le(s, len_user);
164
out_uint16_le(s, len_password);
165
out_uint16_le(s, len_program);
166
out_uint16_le(s, len_directory);
167
rdp_out_unistr(s, domain, len_domain);
168
rdp_out_unistr(s, user, len_user);
169
rdp_out_unistr(s, password, len_password);
170
rdp_out_unistr(s, program, len_program);
171
rdp_out_unistr(s, directory, len_directory);
175
flags |= RDP_LOGON_BLOB;
176
DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
177
packetlen = 4 + /* Unknown uint32 */
181
(flags & RDP_LOGON_AUTO ? 2 : 0) + /* len_password */
182
(flags & RDP_LOGON_BLOB ? 2 : 0) + /* Length of BLOB */
183
2 + /* len_program */
184
2 + /* len_directory */
185
(0 < len_domain ? len_domain : 2) + /* domain */
186
len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 + /* We have no 512 byte BLOB. Perhaps we must? */
187
(flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + /* After the BLOB is a unknown int16. If there is a BLOB, that is. */
188
(0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 + /* Unknown (2) */
189
2 + /* Client ip length */
190
len_ip + /* Client ip */
191
2 + /* DLL string length */
192
len_dll + /* DLL string */
195
64 + /* Time zone #0 */
197
64 + /* Time zone #1 */
200
s = sec_init(sec_flags, packetlen);
201
DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
203
out_uint32(s, 0); /* Unknown */
204
out_uint32_le(s, flags);
205
out_uint16_le(s, len_domain);
206
out_uint16_le(s, len_user);
207
if (flags & RDP_LOGON_AUTO)
209
out_uint16_le(s, len_password);
212
if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
216
out_uint16_le(s, len_program);
217
out_uint16_le(s, len_directory);
219
rdp_out_unistr(s, domain, len_domain);
222
rdp_out_unistr(s, user, len_user);
223
if (flags & RDP_LOGON_AUTO)
225
rdp_out_unistr(s, password, len_password);
227
if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
233
rdp_out_unistr(s, program, len_program);
240
if (0 < len_directory)
242
rdp_out_unistr(s, directory, len_directory);
249
out_uint16_le(s, len_ip + 2); /* Length of client ip */
250
rdp_out_unistr(s, "127.0.0.1", len_ip);
251
out_uint16_le(s, len_dll + 2);
252
rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
254
tzone = (mktime(localtime(&t)) - mktime(gmtime(&t))) / 60;
255
out_uint16_le(s, tzone);
256
out_uint16_le(s, 0x0000);
258
rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
259
out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
262
out_uint32_le(s, 0x0a0000);
263
out_uint32_le(s, 0x050000);
268
rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
269
out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
271
out_uint32_le(s, 0x30000);
272
out_uint32_le(s, 0x050000);
275
out_uint32_le(s, 0xffffffc4);
276
out_uint32_le(s, 0xfffffffe);
277
out_uint32_le(s, 0x0f);
283
sec_send(s, sec_flags);
286
/* Send a control PDU */
288
rdp_send_control(uint16 action)
292
s = rdp_init_data(8);
294
out_uint16_le(s, action);
295
out_uint16(s, 0); /* userid */
296
out_uint32(s, 0); /* control id */
299
rdp_send_data(s, RDP_DATA_PDU_CONTROL);
302
/* Send a synchronisation PDU */
304
rdp_send_synchronise(void)
308
s = rdp_init_data(4);
310
out_uint16_le(s, 1); /* type */
311
out_uint16_le(s, 1002);
314
rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);
317
/* Send a single input event */
319
rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
323
s = rdp_init_data(16);
325
out_uint16_le(s, 1); /* number of events */
326
out_uint16(s, 0); /* pad */
328
out_uint32_le(s, time);
329
out_uint16_le(s, message_type);
330
out_uint16_le(s, device_flags);
331
out_uint16_le(s, param1);
332
out_uint16_le(s, param2);
335
rdp_send_data(s, RDP_DATA_PDU_INPUT);
338
/* Send an (empty) font information PDU */
340
rdp_send_fonts(uint16 seq)
344
s = rdp_init_data(8);
346
out_uint16(s, 0); /* number of fonts */
347
out_uint16_le(s, 0x3e); /* unknown */
348
out_uint16_le(s, seq); /* unknown */
349
out_uint16_le(s, 0x32); /* entry size */
352
rdp_send_data(s, RDP_DATA_PDU_FONT2);
355
/* Output general capability set */
357
rdp_out_general_caps(STREAM s)
359
out_uint16_le(s, RDP_CAPSET_GENERAL);
360
out_uint16_le(s, RDP_CAPLEN_GENERAL);
362
out_uint16_le(s, 1); /* OS major type */
363
out_uint16_le(s, 3); /* OS minor type */
364
out_uint16_le(s, 0x200); /* Protocol version */
365
out_uint16(s, 0); /* Pad */
366
out_uint16(s, 0); /* Compression types */
367
out_uint16_le(s, g_use_rdp5 ? 0x40d : 0);
368
/* Pad, according to T.128. 0x40d seems to
370
the server to start sending RDP5 packets.
371
However, the value is 0x1d04 with W2KTSK and
372
NT4MS. Hmm.. Anyway, thankyou, Microsoft,
373
for sending such information in a padding
375
out_uint16(s, 0); /* Update capability */
376
out_uint16(s, 0); /* Remote unshare capability */
377
out_uint16(s, 0); /* Compression level */
378
out_uint16(s, 0); /* Pad */
381
/* Output bitmap capability set */
383
rdp_out_bitmap_caps(STREAM s)
385
out_uint16_le(s, RDP_CAPSET_BITMAP);
386
out_uint16_le(s, RDP_CAPLEN_BITMAP);
388
out_uint16_le(s, 8); /* Preferred BPP */
389
out_uint16_le(s, 1); /* Receive 1 BPP */
390
out_uint16_le(s, 1); /* Receive 4 BPP */
391
out_uint16_le(s, 1); /* Receive 8 BPP */
392
out_uint16_le(s, 800); /* Desktop width */
393
out_uint16_le(s, 600); /* Desktop height */
394
out_uint16(s, 0); /* Pad */
395
out_uint16(s, 0); /* Allow resize */
396
out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
397
out_uint16(s, 0); /* Unknown */
398
out_uint16_le(s, 1); /* Unknown */
399
out_uint16(s, 0); /* Pad */
402
/* Output order capability set */
404
rdp_out_order_caps(STREAM s)
406
uint8 order_caps[32];
409
memset(order_caps, 0, 32);
410
order_caps[0] = 1; /* dest blt */
411
order_caps[1] = 1; /* pat blt */
412
order_caps[2] = 1; /* screen blt */
413
order_caps[3] = 1; /* required for memblt? */
414
order_caps[8] = 1; /* line */
415
order_caps[9] = 1; /* line */
416
order_caps[10] = 1; /* rect */
417
order_caps[11] = (g_desktop_save == False ? 0 : 1); /* desksave */
418
order_caps[13] = 1; /* memblt */
419
order_caps[14] = 1; /* triblt */
420
order_caps[22] = 1; /* polyline */
421
order_caps[27] = 1; /* text2 */
422
out_uint16_le(s, RDP_CAPSET_ORDER);
423
out_uint16_le(s, RDP_CAPLEN_ORDER);
425
out_uint8s(s, 20); /* Terminal desc, pad */
426
out_uint16_le(s, 1); /* Cache X granularity */
427
out_uint16_le(s, 20); /* Cache Y granularity */
428
out_uint16(s, 0); /* Pad */
429
out_uint16_le(s, 1); /* Max order level */
430
out_uint16_le(s, 0x147); /* Number of fonts */
431
out_uint16_le(s, 0x2a); /* Capability flags */
432
out_uint8p(s, order_caps, 32); /* Orders supported */
433
out_uint16_le(s, 0x6a1); /* Text capability flags */
434
out_uint8s(s, 6); /* Pad */
435
out_uint32_le(s, g_desktop_save == False ? 0 : 0x38400); /* Desktop cache size */
436
out_uint32(s, 0); /* Unknown */
437
out_uint32_le(s, 0x4e4); /* Unknown */
440
/* Output bitmap cache capability set */
442
rdp_out_bmpcache_caps(STREAM s)
445
out_uint16_le(s, RDP_CAPSET_BMPCACHE);
446
out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
448
Bpp = (g_server_bpp + 7) / 8;
449
out_uint8s(s, 24); /* unused */
450
out_uint16_le(s, 0x258); /* entries */
451
out_uint16_le(s, 0x100 * Bpp); /* max cell size */
452
out_uint16_le(s, 0x12c); /* entries */
453
out_uint16_le(s, 0x400 * Bpp); /* max cell size */
454
out_uint16_le(s, 0x106); /* entries */
455
out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
458
/* Output control capability set */
460
rdp_out_control_caps(STREAM s)
462
out_uint16_le(s, RDP_CAPSET_CONTROL);
463
out_uint16_le(s, RDP_CAPLEN_CONTROL);
465
out_uint16(s, 0); /* Control capabilities */
466
out_uint16(s, 0); /* Remote detach */
467
out_uint16_le(s, 2); /* Control interest */
468
out_uint16_le(s, 2); /* Detach interest */
471
/* Output activation capability set */
473
rdp_out_activate_caps(STREAM s)
475
out_uint16_le(s, RDP_CAPSET_ACTIVATE);
476
out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
478
out_uint16(s, 0); /* Help key */
479
out_uint16(s, 0); /* Help index key */
480
out_uint16(s, 0); /* Extended help key */
481
out_uint16(s, 0); /* Window activate */
484
/* Output pointer capability set */
486
rdp_out_pointer_caps(STREAM s)
488
out_uint16_le(s, RDP_CAPSET_POINTER);
489
out_uint16_le(s, RDP_CAPLEN_POINTER);
491
out_uint16(s, 0); /* Colour pointer */
492
out_uint16_le(s, 20); /* Cache size */
495
/* Output share capability set */
497
rdp_out_share_caps(STREAM s)
499
out_uint16_le(s, RDP_CAPSET_SHARE);
500
out_uint16_le(s, RDP_CAPLEN_SHARE);
502
out_uint16(s, 0); /* userid */
503
out_uint16(s, 0); /* pad */
506
/* Output colour cache capability set */
508
rdp_out_colcache_caps(STREAM s)
510
out_uint16_le(s, RDP_CAPSET_COLCACHE);
511
out_uint16_le(s, RDP_CAPLEN_COLCACHE);
513
out_uint16_le(s, 6); /* cache size */
514
out_uint16(s, 0); /* pad */
517
static uint8 canned_caps[] = {
518
0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,
519
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
520
0x00, 0x00, 0x00, 0x00, 0x00,
521
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
522
0x00, 0x00, 0x00, 0x00, 0x00,
523
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
524
0x00, 0x00, 0x00, 0x00, 0x00,
525
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
526
0x00, 0x00, 0x00, 0x00, 0x00,
527
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
528
0x0C, 0x00, 0x08, 0x00, 0x01,
529
0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
530
0x10, 0x00, 0x34, 0x00, 0xFE,
531
0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,
532
0xFE, 0x00, 0x08, 0x00, 0xFE,
533
0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,
534
0xFE, 0x00, 0x80, 0x00, 0xFE,
535
0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
536
0x02, 0x00, 0x00, 0x00
539
/* Output unknown capability sets (number 13, 12, 14 and 16) */
541
rdp_out_unknown_caps(STREAM s)
543
out_uint16_le(s, RDP_CAPSET_UNKNOWN);
544
out_uint16_le(s, 0x58);
546
out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);
549
#define RDP5_FLAG 0x0030
550
/* Send a confirm active PDU */
552
rdp_send_confirm_active(void)
555
uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
557
RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
558
RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
559
RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
560
RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;
562
s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
564
out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
565
out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10)); /* Version 1 */
566
out_uint16_le(s, (g_mcs_userid + 1001));
568
out_uint32_le(s, g_rdp_shareid);
569
out_uint16_le(s, 0x3ea); /* userid */
570
out_uint16_le(s, sizeof(RDP_SOURCE));
571
out_uint16_le(s, caplen);
573
out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
574
out_uint16_le(s, 0xd); /* num_caps */
575
out_uint8s(s, 2); /* pad */
577
rdp_out_general_caps(s);
578
rdp_out_bitmap_caps(s);
579
rdp_out_order_caps(s);
580
rdp_out_bmpcache_caps(s);
581
rdp_out_colcache_caps(s);
582
rdp_out_activate_caps(s);
583
rdp_out_control_caps(s);
584
rdp_out_pointer_caps(s);
585
rdp_out_share_caps(s);
586
rdp_out_unknown_caps(s);
589
sec_send(s, sec_flags);
592
/* Respond to a demand active PDU */
594
process_demand_active(STREAM s)
598
in_uint32_le(s, g_rdp_shareid);
600
DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
602
rdp_send_confirm_active();
603
rdp_send_synchronise();
604
rdp_send_control(RDP_CTL_COOPERATE);
605
rdp_send_control(RDP_CTL_REQUEST_CONTROL);
606
rdp_recv(&type); /* RDP_PDU_SYNCHRONIZE */
607
rdp_recv(&type); /* RDP_CTL_COOPERATE */
608
rdp_recv(&type); /* RDP_CTL_GRANT_CONTROL */
609
rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);
612
rdp_recv(&type); /* RDP_PDU_UNKNOWN 0x28 */
616
/* Process a colour pointer PDU */
618
process_colour_pointer_pdu(STREAM s)
620
uint16 x, y, width, height, cache_idx, masklen, datalen;
624
in_uint16_le(s, cache_idx);
627
in_uint16_le(s, width);
628
in_uint16_le(s, height);
629
in_uint16_le(s, masklen);
630
in_uint16_le(s, datalen);
631
in_uint8p(s, data, datalen);
632
in_uint8p(s, mask, masklen);
633
cursor = ui_create_cursor(x, y, width, height, mask, data);
634
ui_set_cursor(cursor);
635
cache_put_cursor(cache_idx, cursor);
638
/* Process a cached pointer PDU */
640
process_cached_pointer_pdu(STREAM s)
644
in_uint16_le(s, cache_idx);
645
ui_set_cursor(cache_get_cursor(cache_idx));
648
/* Process a system pointer PDU */
650
process_system_pointer_pdu(STREAM s)
652
uint16 system_pointer_type;
654
in_uint16(s, system_pointer_type);
655
switch (system_pointer_type)
657
case RDP_NULL_POINTER:
658
ui_set_null_cursor();
662
unimpl("System pointer message 0x%x\n", system_pointer_type);
666
/* Process a pointer PDU */
668
process_pointer_pdu(STREAM s)
673
in_uint16_le(s, message_type);
674
in_uint8s(s, 2); /* pad */
676
switch (message_type)
678
case RDP_POINTER_MOVE:
682
ui_move_pointer(x, y);
685
case RDP_POINTER_COLOR:
686
process_colour_pointer_pdu(s);
689
case RDP_POINTER_CACHED:
690
process_cached_pointer_pdu(s);
693
case RDP_POINTER_SYSTEM:
694
process_system_pointer_pdu(s);
698
unimpl("Pointer message 0x%x\n", message_type);
702
/* Process bitmap updates */
704
process_bitmap_updates(STREAM s)
707
uint16 left, top, right, bottom, width, height;
708
uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
709
uint8 *data, *bmpdata;
712
in_uint16_le(s, num_updates);
714
for (i = 0; i < num_updates; i++)
716
in_uint16_le(s, left);
717
in_uint16_le(s, top);
718
in_uint16_le(s, right);
719
in_uint16_le(s, bottom);
720
in_uint16_le(s, width);
721
in_uint16_le(s, height);
722
in_uint16_le(s, bpp);
724
in_uint16_le(s, compress);
725
in_uint16_le(s, bufsize);
727
cx = right - left + 1;
728
cy = bottom - top + 1;
730
DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
731
left, top, right, bottom, width, height, Bpp, compress));
733
/* Server may limit bpp - this is how we find out */
734
if (g_server_bpp != bpp)
736
warning("Server limited colour depth to %d bits\n", bpp);
743
bmpdata = (uint8 *) xmalloc(width * height * Bpp);
744
for (y = 0; y < height; y++)
746
in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
749
ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
755
if (compress & 0x400)
761
in_uint8s(s, 2); /* pad */
762
in_uint16_le(s, size);
763
in_uint8s(s, 4); /* line_size, final_size */
765
in_uint8p(s, data, size);
766
bmpdata = (uint8 *) xmalloc(width * height * Bpp);
767
if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
769
ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
773
DEBUG_RDP5(("Failed to decompress data\n"));
780
/* Process a palette update */
782
process_palette(STREAM s)
789
in_uint8s(s, 2); /* pad */
790
in_uint16_le(s, map.ncolours);
791
in_uint8s(s, 2); /* pad */
793
map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
795
DEBUG(("PALETTE(c=%d)\n", map.ncolours));
797
for (i = 0; i < map.ncolours; i++)
799
entry = &map.colours[i];
800
in_uint8(s, entry->red);
801
in_uint8(s, entry->green);
802
in_uint8(s, entry->blue);
805
hmap = ui_create_colourmap(&map);
806
ui_set_colourmap(hmap);
811
/* Process an update PDU */
813
process_update_pdu(STREAM s)
815
uint16 update_type, count;
817
in_uint16_le(s, update_type);
821
case RDP_UPDATE_ORDERS:
822
in_uint8s(s, 2); /* pad */
823
in_uint16_le(s, count);
824
in_uint8s(s, 2); /* pad */
825
process_orders(s, count);
828
case RDP_UPDATE_BITMAP:
829
process_bitmap_updates(s);
832
case RDP_UPDATE_PALETTE:
836
case RDP_UPDATE_SYNCHRONIZE:
840
unimpl("update %d\n", update_type);
845
/* Process data PDU */
847
process_data_pdu(STREAM s)
851
in_uint8s(s, 8); /* shareid, pad, streamid, length */
852
in_uint8(s, data_pdu_type);
853
in_uint8s(s, 3); /* compress_type, compress_len */
855
switch (data_pdu_type)
857
case RDP_DATA_PDU_UPDATE:
858
process_update_pdu(s);
861
case RDP_DATA_PDU_POINTER:
862
process_pointer_pdu(s);
865
case RDP_DATA_PDU_BELL:
869
case RDP_DATA_PDU_LOGON:
870
DEBUG(("Received Logon PDU\n"));
874
case RDP_DATA_PDU_DISCONNECT:
875
/* Normally received when user logs out or disconnects from a
876
console session on Windows XP and 2003 Server */
877
DEBUG(("Received disconnect PDU\n"));
881
unimpl("data PDU %d\n", data_pdu_type);
885
/* Process incoming packets */
892
while ((s = rdp_recv(&type)) != NULL)
896
case RDP_PDU_DEMAND_ACTIVE:
897
process_demand_active(s);
900
case RDP_PDU_DEACTIVATE:
901
DEBUG(("RDP_PDU_DEACTIVATE\n"));
902
/* We thought we could detect a clean
903
shutdown of the session by this
904
packet, but it seems Windows 2003
905
is sending us one of these when we
906
reconnect to a disconnected session
918
unimpl("PDU %d\n", type);
922
/* We want to detect if we got a clean shutdown, but we
927
/* Establish a connection up to the RDP layer */
929
rdp_connect(char *server, uint32 flags, char *domain, char *password,
930
char *command, char *directory)
932
if (!sec_connect(server, g_username))
935
rdp_send_logon_info(flags, domain, g_username, password, command, directory);
939
/* Disconnect from the RDP layer */