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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 410 - (hide annotations)
Fri Jun 6 10:47:34 2003 UTC (20 years, 11 months ago) by forsberg
File MIME type: text/plain
File size: 21376 byte(s)
Indentation/syntax changes after running indent-all.sh

1 forsberg 351 /* -*- c-basic-offset: 8 -*-
2 matty 3 rdesktop: A Remote Desktop Protocol client.
3     Protocol services - RDP layer
4 matthewc 207 Copyright (C) Matthew Chapman 1999-2002
5 matty 3
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 matty 10 #include "rdesktop.h"
22 matty 3
23 jsorg71 381 extern uint16 g_mcs_userid;
24 matty 10 extern char username[16];
25 matty 28 extern BOOL bitmap_compression;
26 matty 10 extern BOOL orders;
27 matty 30 extern BOOL encryption;
28 matty 28 extern BOOL desktop_save;
29 forsberg 351 extern BOOL use_rdp5;
30     extern uint16 server_rdp_version;
31 matty 3
32 matty 28 uint8 *next_packet;
33 matty 10 uint32 rdp_shareid;
34 matty 3
35 forsberg 340 #if WITH_DEBUG
36     static uint32 packetno;
37 forsberg 351 #endif
38 forsberg 340
39 matty 10 /* Receive an RDP packet */
40 matty 25 static STREAM
41 astrand 64 rdp_recv(uint8 * type)
42 matty 3 {
43 matty 10 static STREAM rdp_s;
44     uint16 length, pdu_type;
45 matty 3
46 matty 10 if ((rdp_s == NULL) || (next_packet >= rdp_s->end))
47     {
48     rdp_s = sec_recv();
49     if (rdp_s == NULL)
50     return NULL;
51 matty 3
52 matty 10 next_packet = rdp_s->p;
53     }
54     else
55 matty 7 {
56 matty 10 rdp_s->p = next_packet;
57 matty 7 }
58    
59 matty 10 in_uint16_le(rdp_s, length);
60 jsorg71 283 /* 32k packets are really 8, keepalive fix */
61     if (length == 0x8000)
62     {
63     next_packet += 8;
64     *type = 0;
65     return rdp_s;
66     }
67 matty 10 in_uint16_le(rdp_s, pdu_type);
68 matty 24 in_uint8s(rdp_s, 2); /* userid */
69 matty 10 *type = pdu_type & 0xf;
70 matty 7
71 matty 30 #if WITH_DEBUG
72 forsberg 351 DEBUG(("RDP packet #%d, (type %x)\n", ++packetno, *type));
73     // hexdump(next_packet, length);
74 matty 28 #endif /* */
75 matty 7
76 matty 28 next_packet += length;
77 matty 10 return rdp_s;
78 matty 3 }
79    
80 matty 10 /* Initialise an RDP data packet */
81 matty 25 static STREAM
82     rdp_init_data(int maxlen)
83 matty 3 {
84 matty 10 STREAM s;
85 matty 3
86 matty 30 s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 18);
87 matty 10 s_push_layer(s, rdp_hdr, 18);
88    
89     return s;
90 matty 3 }
91    
92 matty 10 /* Send an RDP data packet */
93 matty 25 static void
94     rdp_send_data(STREAM s, uint8 data_pdu_type)
95 matty 9 {
96 matty 10 uint16 length;
97 matty 9
98 matty 10 s_pop_layer(s, rdp_hdr);
99     length = s->end - s->p;
100 matty 9
101 matty 10 out_uint16_le(s, length);
102     out_uint16_le(s, (RDP_PDU_DATA | 0x10));
103 jsorg71 381 out_uint16_le(s, (g_mcs_userid + 1001));
104 matty 9
105 matty 10 out_uint32_le(s, rdp_shareid);
106 matty 24 out_uint8(s, 0); /* pad */
107     out_uint8(s, 1); /* streamid */
108 n-ki 176 out_uint16_le(s, (length - 14));
109 matty 10 out_uint8(s, data_pdu_type);
110 matty 24 out_uint8(s, 0); /* compress_type */
111     out_uint16(s, 0); /* compress_len */
112 matty 3
113 matty 30 sec_send(s, encryption ? SEC_ENCRYPT : 0);
114 matty 3 }
115    
116 matty 10 /* Output a string in Unicode */
117 matty 25 void
118     rdp_out_unistr(STREAM s, char *string, int len)
119 matty 3 {
120 matty 10 int i = 0, j = 0;
121 matty 9
122 matty 10 len += 2;
123 matty 9
124 matty 10 while (i < len)
125 matty 9 {
126 matty 10 s->p[i++] = string[j++];
127     s->p[i++] = 0;
128 matty 9 }
129    
130 matty 10 s->p += len;
131 matty 3 }
132    
133 matty 10 /* Parse a logon info packet */
134 matty 25 static void
135     rdp_send_logon_info(uint32 flags, char *domain, char *user,
136     char *password, char *program, char *directory)
137 matty 3 {
138 matty 24 int len_domain = 2 * strlen(domain);
139     int len_user = 2 * strlen(user);
140     int len_password = 2 * strlen(password);
141     int len_program = 2 * strlen(program);
142 matty 10 int len_directory = 2 * strlen(directory);
143 forsberg 371 int len_ip = 2 * strlen("127.0.0.1");
144     int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
145     int packetlen = 0;
146 astrand 82 uint32 sec_flags = encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
147 matty 10 STREAM s;
148 matty 3
149 forsberg 369 if (!use_rdp5 || 1 == server_rdp_version)
150 forsberg 351 {
151     DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
152 matty 3
153 forsberg 351 s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
154     + len_program + len_directory + 10);
155 matty 3
156 forsberg 351 out_uint32(s, 0);
157     out_uint32_le(s, flags);
158     out_uint16_le(s, len_domain);
159     out_uint16_le(s, len_user);
160     out_uint16_le(s, len_password);
161     out_uint16_le(s, len_program);
162     out_uint16_le(s, len_directory);
163     rdp_out_unistr(s, domain, len_domain);
164     rdp_out_unistr(s, user, len_user);
165     rdp_out_unistr(s, password, len_password);
166     rdp_out_unistr(s, program, len_program);
167     rdp_out_unistr(s, directory, len_directory);
168     }
169     else
170     {
171 forsberg 371 flags |= RDP_LOGON_BLOB;
172 forsberg 351 DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
173 forsberg 410 packetlen = 4 + // Unknown uint32
174     4 + // flags
175     2 + // len_domain
176     2 + // len_user
177     (flags & RDP_LOGON_AUTO ? 2 : 0) + // len_password
178     (flags & RDP_LOGON_BLOB ? 2 : 0) + // Length of BLOB
179     2 + // len_program
180     2 + // len_directory
181     (0 < len_domain ? len_domain : 2) + // domain
182     len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 + // We have no 512 byte BLOB. Perhaps we must?
183     (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + // After the BLOB is a unknown int16. If there is a BLOB, that is.
184     (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 + // Unknown (2)
185     2 + // Client ip length
186     len_ip + // Client ip
187     2 + // DLL string length
188     len_dll + // DLL string
189     2 + // Unknown
190     2 + // Unknown
191     64 + // Time zone #0
192     2 + // Unknown
193     64 + // Time zone #1
194     32; // Unknown
195    
196     s = sec_init(sec_flags, packetlen);
197 forsberg 371 DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
198 forsberg 351
199 forsberg 410 out_uint32(s, 0); // Unknown
200 forsberg 351 out_uint32_le(s, flags);
201     out_uint16_le(s, len_domain);
202     out_uint16_le(s, len_user);
203     if (flags & RDP_LOGON_AUTO)
204     {
205     out_uint16_le(s, len_password);
206 forsberg 371
207 forsberg 351 }
208 forsberg 410 if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
209     {
210 forsberg 371 out_uint16_le(s, 0);
211     }
212 forsberg 351 out_uint16_le(s, len_program);
213     out_uint16_le(s, len_directory);
214 forsberg 371 if (0 < len_domain)
215     rdp_out_unistr(s, domain, len_domain);
216 forsberg 410 else
217 forsberg 371 out_uint16_le(s, 0);
218     rdp_out_unistr(s, user, len_user);
219 forsberg 351 if (flags & RDP_LOGON_AUTO)
220     {
221     rdp_out_unistr(s, password, len_password);
222     }
223 forsberg 410 if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
224     {
225 forsberg 371 out_uint16_le(s, 0);
226     }
227 forsberg 410 if (0 < len_program)
228     {
229 forsberg 351 rdp_out_unistr(s, program, len_program);
230 forsberg 410
231     }
232     else
233     {
234 forsberg 371 out_uint16_le(s, 0);
235     }
236 forsberg 410 if (0 < len_directory)
237     {
238 forsberg 351 rdp_out_unistr(s, directory, len_directory);
239 forsberg 410 }
240     else
241     {
242 forsberg 371 out_uint16_le(s, 0);
243 jsorg71 376 }
244 forsberg 371 out_uint16_le(s, 2);
245 forsberg 410 out_uint16_le(s, len_ip + 2); // Length of client ip
246 forsberg 371 rdp_out_unistr(s, "127.0.0.1", len_ip);
247 forsberg 410 out_uint16_le(s, len_dll + 2);
248 forsberg 371 rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
249     out_uint16_le(s, 0xffc4);
250     out_uint16_le(s, 0xffff);
251 forsberg 410 rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
252     out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
253 forsberg 351
254 forsberg 410
255 forsberg 351 out_uint32_le(s, 0x0a0000);
256     out_uint32_le(s, 0x050000);
257 forsberg 371 out_uint32_le(s, 3);
258     out_uint32_le(s, 0);
259     out_uint32_le(s, 0);
260 forsberg 351
261 forsberg 410 rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
262     out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
263    
264 forsberg 371 out_uint32_le(s, 0x30000);
265 forsberg 351 out_uint32_le(s, 0x050000);
266     out_uint32_le(s, 2);
267 matthewc 365 out_uint32(s, 0);
268 forsberg 351 out_uint32_le(s, 0xffffffc4);
269     out_uint32_le(s, 0xfffffffe);
270     out_uint32_le(s, 0x0f);
271 matthewc 365 out_uint32(s, 0);
272 forsberg 351
273 forsberg 371
274 forsberg 351 }
275 matty 10 s_mark_end(s);
276     sec_send(s, sec_flags);
277 matty 3 }
278    
279 matty 10 /* Send a control PDU */
280 matty 25 static void
281     rdp_send_control(uint16 action)
282 matty 3 {
283 matty 10 STREAM s;
284 matty 9
285 matty 10 s = rdp_init_data(8);
286 matty 9
287 matty 10 out_uint16_le(s, action);
288 matty 24 out_uint16(s, 0); /* userid */
289     out_uint32(s, 0); /* control id */
290 matty 9
291 matty 10 s_mark_end(s);
292     rdp_send_data(s, RDP_DATA_PDU_CONTROL);
293 matty 3 }
294    
295 matty 10 /* Send a synchronisation PDU */
296 matty 25 static void
297 matthewc 192 rdp_send_synchronise(void)
298 matty 3 {
299 matty 10 STREAM s;
300 matty 9
301 matty 10 s = rdp_init_data(4);
302 matty 9
303 matty 24 out_uint16_le(s, 1); /* type */
304 matty 10 out_uint16_le(s, 1002);
305 matty 9
306 matty 10 s_mark_end(s);
307     rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);
308 matty 3 }
309    
310 matty 10 /* Send a single input event */
311 matty 25 void
312 astrand 82 rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
313 matty 3 {
314 matty 10 STREAM s;
315 matty 9
316 matty 10 s = rdp_init_data(16);
317 matty 9
318 matty 24 out_uint16_le(s, 1); /* number of events */
319     out_uint16(s, 0); /* pad */
320 matty 9
321 matty 10 out_uint32_le(s, time);
322     out_uint16_le(s, message_type);
323     out_uint16_le(s, device_flags);
324     out_uint16_le(s, param1);
325     out_uint16_le(s, param2);
326 matty 9
327 matty 10 s_mark_end(s);
328     rdp_send_data(s, RDP_DATA_PDU_INPUT);
329 matty 3 }
330    
331 matty 10 /* Send an (empty) font information PDU */
332 matty 25 static void
333     rdp_send_fonts(uint16 seq)
334 matty 3 {
335 matty 10 STREAM s;
336 matty 3
337 matty 10 s = rdp_init_data(8);
338 matty 9
339 matty 10 out_uint16(s, 0); /* number of fonts */
340     out_uint16_le(s, 0x3e); /* unknown */
341     out_uint16_le(s, seq); /* unknown */
342     out_uint16_le(s, 0x32); /* entry size */
343 matty 9
344 matty 10 s_mark_end(s);
345     rdp_send_data(s, RDP_DATA_PDU_FONT2);
346 matty 3 }
347    
348 matty 10 /* Output general capability set */
349 matty 25 static void
350     rdp_out_general_caps(STREAM s)
351 matty 3 {
352 matty 10 out_uint16_le(s, RDP_CAPSET_GENERAL);
353     out_uint16_le(s, RDP_CAPLEN_GENERAL);
354 matty 3
355 matty 10 out_uint16_le(s, 1); /* OS major type */
356     out_uint16_le(s, 3); /* OS minor type */
357 matty 24 out_uint16_le(s, 0x200); /* Protocol version */
358 matty 10 out_uint16(s, 0); /* Pad */
359     out_uint16(s, 0); /* Compression types */
360 matthewc 365 out_uint16_le(s, use_rdp5 ? 0x40d : 0);
361 forsberg 351 /* Pad, according to T.128. 0x40d seems to
362     trigger
363     the server to start sending RDP5 packets.
364     However, the value is 0x1d04 with W2KTSK and
365     NT4MS. Hmm.. Anyway, thankyou, Microsoft,
366     for sending such information in a padding
367     field.. */
368 matty 10 out_uint16(s, 0); /* Update capability */
369     out_uint16(s, 0); /* Remote unshare capability */
370     out_uint16(s, 0); /* Compression level */
371     out_uint16(s, 0); /* Pad */
372 matty 3 }
373    
374 matty 10 /* Output bitmap capability set */
375 matty 25 static void
376     rdp_out_bitmap_caps(STREAM s)
377 matty 9 {
378 matty 10 out_uint16_le(s, RDP_CAPSET_BITMAP);
379     out_uint16_le(s, RDP_CAPLEN_BITMAP);
380 matty 9
381 matty 10 out_uint16_le(s, 8); /* Preferred BPP */
382 n-ki 176 out_uint16_le(s, 1); /* Receive 1 BPP */
383     out_uint16_le(s, 1); /* Receive 4 BPP */
384 matty 10 out_uint16_le(s, 1); /* Receive 8 BPP */
385     out_uint16_le(s, 800); /* Desktop width */
386     out_uint16_le(s, 600); /* Desktop height */
387     out_uint16(s, 0); /* Pad */
388     out_uint16(s, 0); /* Allow resize */
389 matty 28 out_uint16_le(s, bitmap_compression ? 1 : 0); /* Support compression */
390 matty 10 out_uint16(s, 0); /* Unknown */
391     out_uint16_le(s, 1); /* Unknown */
392     out_uint16(s, 0); /* Pad */
393 matty 9 }
394    
395 matty 10 /* Output order capability set */
396 matty 25 static void
397     rdp_out_order_caps(STREAM s)
398 matty 3 {
399 matty 10 uint8 order_caps[32];
400 matty 3
401 matty 9
402 matty 28 memset(order_caps, 0, 32);
403     order_caps[0] = 1; /* dest blt */
404     order_caps[1] = 1; /* pat blt */
405     order_caps[2] = 1; /* screen blt */
406 matthewc 161 order_caps[3] = 1; /* required for memblt? */
407 matty 28 order_caps[8] = 1; /* line */
408     order_caps[9] = 1; /* line */
409     order_caps[10] = 1; /* rect */
410     order_caps[11] = (desktop_save == False ? 0 : 1); /* desksave */
411     order_caps[13] = 1; /* memblt */
412     order_caps[14] = 1; /* triblt */
413     order_caps[22] = 1; /* polyline */
414     order_caps[27] = 1; /* text2 */
415 matty 10 out_uint16_le(s, RDP_CAPSET_ORDER);
416     out_uint16_le(s, RDP_CAPLEN_ORDER);
417 matty 9
418 matty 10 out_uint8s(s, 20); /* Terminal desc, pad */
419     out_uint16_le(s, 1); /* Cache X granularity */
420     out_uint16_le(s, 20); /* Cache Y granularity */
421     out_uint16(s, 0); /* Pad */
422     out_uint16_le(s, 1); /* Max order level */
423     out_uint16_le(s, 0x147); /* Number of fonts */
424 matty 24 out_uint16_le(s, 0x2a); /* Capability flags */
425 matty 10 out_uint8p(s, order_caps, 32); /* Orders supported */
426     out_uint16_le(s, 0x6a1); /* Text capability flags */
427     out_uint8s(s, 6); /* Pad */
428 n-ki 176 out_uint32_le(s, desktop_save == False ? 0 : 0x38400); /* Desktop cache size */
429 matty 10 out_uint32(s, 0); /* Unknown */
430 n-ki 176 out_uint32_le(s, 0x4e4); /* Unknown */
431 matty 9 }
432    
433 matty 10 /* Output bitmap cache capability set */
434 matty 25 static void
435     rdp_out_bmpcache_caps(STREAM s)
436 matty 9 {
437 matty 10 out_uint16_le(s, RDP_CAPSET_BMPCACHE);
438     out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
439 matty 3
440 matty 24 out_uint8s(s, 24); /* unused */
441     out_uint16_le(s, 0x258); /* entries */
442     out_uint16_le(s, 0x100); /* max cell size */
443     out_uint16_le(s, 0x12c); /* entries */
444     out_uint16_le(s, 0x400); /* max cell size */
445     out_uint16_le(s, 0x106); /* entries */
446     out_uint16_le(s, 0x1000); /* max cell size */
447 matty 9 }
448    
449 matty 10 /* Output control capability set */
450 matty 25 static void
451     rdp_out_control_caps(STREAM s)
452 matty 9 {
453 matty 10 out_uint16_le(s, RDP_CAPSET_CONTROL);
454     out_uint16_le(s, RDP_CAPLEN_CONTROL);
455 matty 9
456 matty 10 out_uint16(s, 0); /* Control capabilities */
457     out_uint16(s, 0); /* Remote detach */
458     out_uint16_le(s, 2); /* Control interest */
459     out_uint16_le(s, 2); /* Detach interest */
460 matty 9 }
461    
462 matty 10 /* Output activation capability set */
463 matty 25 static void
464     rdp_out_activate_caps(STREAM s)
465 matty 9 {
466 matty 10 out_uint16_le(s, RDP_CAPSET_ACTIVATE);
467     out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
468 matty 9
469 matty 10 out_uint16(s, 0); /* Help key */
470     out_uint16(s, 0); /* Help index key */
471     out_uint16(s, 0); /* Extended help key */
472     out_uint16(s, 0); /* Window activate */
473 matty 9 }
474    
475 matty 10 /* Output pointer capability set */
476 matty 25 static void
477     rdp_out_pointer_caps(STREAM s)
478 matty 9 {
479 matty 10 out_uint16_le(s, RDP_CAPSET_POINTER);
480     out_uint16_le(s, RDP_CAPLEN_POINTER);
481 matty 9
482 matty 10 out_uint16(s, 0); /* Colour pointer */
483     out_uint16_le(s, 20); /* Cache size */
484 matty 9 }
485    
486 matty 10 /* Output share capability set */
487 matty 25 static void
488     rdp_out_share_caps(STREAM s)
489 matty 3 {
490 matty 10 out_uint16_le(s, RDP_CAPSET_SHARE);
491     out_uint16_le(s, RDP_CAPLEN_SHARE);
492 matty 3
493 matty 10 out_uint16(s, 0); /* userid */
494     out_uint16(s, 0); /* pad */
495 matty 9 }
496 matty 3
497 matty 10 /* Output colour cache capability set */
498 matty 25 static void
499     rdp_out_colcache_caps(STREAM s)
500 matty 9 {
501 matty 10 out_uint16_le(s, RDP_CAPSET_COLCACHE);
502     out_uint16_le(s, RDP_CAPLEN_COLCACHE);
503 matty 3
504 matty 10 out_uint16_le(s, 6); /* cache size */
505     out_uint16(s, 0); /* pad */
506 matty 3 }
507    
508 matty 10 static uint8 canned_caps[] = {
509 matty 24 0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,
510     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
511 matty 25 0x00, 0x00, 0x00, 0x00, 0x00,
512 matty 24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
513 matty 25 0x00, 0x00, 0x00, 0x00, 0x00,
514 matty 24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
515 matty 25 0x00, 0x00, 0x00, 0x00, 0x00,
516 matty 24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
517 matty 25 0x00, 0x00, 0x00, 0x00, 0x00,
518 matty 24 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
519 matty 25 0x0C, 0x00, 0x08, 0x00, 0x01,
520 matty 24 0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
521 matty 25 0x10, 0x00, 0x34, 0x00, 0xFE,
522 matty 24 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,
523 matty 25 0xFE, 0x00, 0x08, 0x00, 0xFE,
524 matty 24 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,
525 matty 25 0xFE, 0x00, 0x80, 0x00, 0xFE,
526 matty 24 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
527 matty 25 0x02, 0x00, 0x00, 0x00
528 matty 10 };
529 matty 3
530 forsberg 351 /* Output unknown capability sets (number 13, 12, 14 and 16) */
531 matty 25 static void
532     rdp_out_unknown_caps(STREAM s)
533 matty 3 {
534 matty 10 out_uint16_le(s, RDP_CAPSET_UNKNOWN);
535     out_uint16_le(s, 0x58);
536 matty 24
537     out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);
538 matty 3 }
539    
540 forsberg 351 #define RDP5_FLAG 0x0030
541 matty 10 /* Send a confirm active PDU */
542 matty 25 static void
543 matthewc 192 rdp_send_confirm_active(void)
544 matty 7 {
545 matty 10 STREAM s;
546 forsberg 351 uint32 sec_flags = encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
547 matty 24 uint16 caplen =
548     RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
549     RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
550     RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
551 astrand 82 RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;
552 matty 7
553 forsberg 351 s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
554 matty 9
555 forsberg 351 out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
556     out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10)); /* Version 1 */
557 jsorg71 381 out_uint16_le(s, (g_mcs_userid + 1001));
558 forsberg 351
559 matty 10 out_uint32_le(s, rdp_shareid);
560 matty 24 out_uint16_le(s, 0x3ea); /* userid */
561 matty 10 out_uint16_le(s, sizeof(RDP_SOURCE));
562     out_uint16_le(s, caplen);
563 matty 9
564 matty 10 out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
565 matty 24 out_uint16_le(s, 0xd); /* num_caps */
566     out_uint8s(s, 2); /* pad */
567 matty 9
568 matty 10 rdp_out_general_caps(s);
569     rdp_out_bitmap_caps(s);
570     rdp_out_order_caps(s);
571     rdp_out_bmpcache_caps(s);
572     rdp_out_colcache_caps(s);
573     rdp_out_activate_caps(s);
574     rdp_out_control_caps(s);
575     rdp_out_pointer_caps(s);
576     rdp_out_share_caps(s);
577     rdp_out_unknown_caps(s);
578 matty 9
579 matty 10 s_mark_end(s);
580 forsberg 351 sec_send(s, sec_flags);
581 matty 9 }
582    
583 matty 10 /* Respond to a demand active PDU */
584 matty 25 static void
585     process_demand_active(STREAM s)
586 matty 9 {
587 matty 10 uint8 type;
588 matty 9
589 matty 10 in_uint32_le(s, rdp_shareid);
590 matty 9
591 matty 30 DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", rdp_shareid));
592 matty 9
593 matty 10 rdp_send_confirm_active();
594     rdp_send_synchronise();
595     rdp_send_control(RDP_CTL_COOPERATE);
596     rdp_send_control(RDP_CTL_REQUEST_CONTROL);
597 matty 28 rdp_recv(&type); /* RDP_PDU_SYNCHRONIZE */
598     rdp_recv(&type); /* RDP_CTL_COOPERATE */
599     rdp_recv(&type); /* RDP_CTL_GRANT_CONTROL */
600 matty 10 rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, 0, 0);
601     rdp_send_fonts(1);
602     rdp_send_fonts(2);
603 matty 28 rdp_recv(&type); /* RDP_PDU_UNKNOWN 0x28 */
604 matty 10 reset_order_state();
605 matty 9 }
606    
607 forsberg 351 /* Process a null system pointer PDU */
608     void
609     process_null_system_pointer_pdu(STREAM s)
610     {
611     // FIXME: We should probably set another cursor here,
612     // like the X window system base cursor or something.
613     ui_set_cursor(cache_get_cursor(0));
614     }
615    
616     /* Process a colour pointer PDU */
617     void
618     process_colour_pointer_pdu(STREAM s)
619     {
620     uint16 x, y, width, height, cache_idx, masklen, datalen;
621     uint8 *mask, *data;
622     HCURSOR cursor;
623    
624     in_uint16_le(s, cache_idx);
625     in_uint16_le(s, x);
626     in_uint16_le(s, y);
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);
636     }
637    
638     /* Process a cached pointer PDU */
639     void
640     process_cached_pointer_pdu(STREAM s)
641     {
642     uint16 cache_idx;
643    
644     in_uint16_le(s, cache_idx);
645     ui_set_cursor(cache_get_cursor(cache_idx));
646     }
647    
648    
649 matty 10 /* Process a pointer PDU */
650 matty 25 static void
651     process_pointer_pdu(STREAM s)
652 matty 9 {
653 matty 10 uint16 message_type;
654 forsberg 351 uint16 x, y;
655 matty 9
656 matty 10 in_uint16_le(s, message_type);
657 matty 24 in_uint8s(s, 2); /* pad */
658 matty 9
659 matty 10 switch (message_type)
660 matty 7 {
661 matty 10 case RDP_POINTER_MOVE:
662     in_uint16_le(s, x);
663     in_uint16_le(s, y);
664     if (s_check(s))
665     ui_move_pointer(x, y);
666     break;
667 matty 9
668 matty 28 case RDP_POINTER_COLOR:
669 forsberg 351 process_colour_pointer_pdu(s);
670 matty 28 break;
671    
672     case RDP_POINTER_CACHED:
673 forsberg 351 process_cached_pointer_pdu(s);
674 matty 28 break;
675    
676 matty 10 default:
677 matty 30 DEBUG(("Pointer message 0x%x\n", message_type));
678 matty 7 }
679 matty 9 }
680    
681 matty 10 /* Process bitmap updates */
682 forsberg 351 void
683 matty 25 process_bitmap_updates(STREAM s)
684 matty 9 {
685 matty 10 uint16 num_updates;
686     uint16 left, top, right, bottom, width, height;
687 jsorg71 314 uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
688 matty 28 uint8 *data, *bmpdata;
689 matty 9 int i;
690    
691 matty 10 in_uint16_le(s, num_updates);
692 matty 9
693 matty 10 for (i = 0; i < num_updates; i++)
694 matty 9 {
695 matty 10 in_uint16_le(s, left);
696     in_uint16_le(s, top);
697     in_uint16_le(s, right);
698     in_uint16_le(s, bottom);
699     in_uint16_le(s, width);
700     in_uint16_le(s, height);
701     in_uint16_le(s, bpp);
702 jsorg71 314 Bpp = (bpp + 7) / 8;
703 matty 10 in_uint16_le(s, compress);
704     in_uint16_le(s, bufsize);
705 matty 9
706 matty 10 cx = right - left + 1;
707     cy = bottom - top + 1;
708 matty 7
709 forsberg 351 DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
710     left, top, right, bottom, width, height, Bpp, compress));
711 matty 9
712 matty 10 if (!compress)
713     {
714 matty 28 int y;
715 forsberg 410 bmpdata = (uint8 *) xmalloc(width * height * Bpp);
716 matty 28 for (y = 0; y < height; y++)
717     {
718 astrand 318 in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
719     width * Bpp);
720 matty 28 }
721 astrand 82 ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
722 matty 28 xfree(bmpdata);
723     continue;
724 matty 10 }
725 matty 9
726 forsberg 351
727     if (compress & 0x400)
728     {
729     size = bufsize;
730     }
731     else
732     {
733     in_uint8s(s, 2); /* pad */
734     in_uint16_le(s, size);
735     in_uint8s(s, 4); /* line_size, final_size */
736     }
737 matty 10 in_uint8p(s, data, size);
738 forsberg 410 bmpdata = (uint8 *) xmalloc(width * height * Bpp);
739 jsorg71 314 if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
740 matty 9 {
741 astrand 82 ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
742 matty 9 }
743 forsberg 351 else
744     {
745     DEBUG_RDP5(("Failed to decompress data\n"));
746     }
747    
748 matty 28 xfree(bmpdata);
749 matty 10 }
750 matty 9 }
751    
752 matty 10 /* Process a palette update */
753 forsberg 351 void
754 matty 25 process_palette(STREAM s)
755 matty 9 {
756 matthewc 254 COLOURENTRY *entry;
757     COLOURMAP map;
758 matty 10 HCOLOURMAP hmap;
759 matthewc 254 int i;
760 matty 9
761 matty 24 in_uint8s(s, 2); /* pad */
762     in_uint16_le(s, map.ncolours);
763     in_uint8s(s, 2); /* pad */
764 matty 3
765 forsberg 410 map.colours = (COLOURENTRY *) xmalloc(3 * map.ncolours);
766 matthewc 254
767 forsberg 351 DEBUG(("PALETTE(c=%d)\n", map.ncolours));
768    
769 matthewc 254 for (i = 0; i < map.ncolours; i++)
770     {
771     entry = &map.colours[i];
772     in_uint8(s, entry->red);
773     in_uint8(s, entry->green);
774     in_uint8(s, entry->blue);
775 astrand 260 }
776 matthewc 254
777 matty 10 hmap = ui_create_colourmap(&map);
778     ui_set_colourmap(hmap);
779 matthewc 254
780     xfree(map.colours);
781 matty 3 }
782    
783 matty 10 /* Process an update PDU */
784 matty 25 static void
785     process_update_pdu(STREAM s)
786 matty 9 {
787 forsberg 351 uint16 update_type, count;
788 matty 9
789 matty 10 in_uint16_le(s, update_type);
790 matty 3
791 matty 10 switch (update_type)
792 matty 3 {
793 matty 10 case RDP_UPDATE_ORDERS:
794 forsberg 351 in_uint8s(s, 2); /* pad */
795     in_uint16_le(s, count);
796     in_uint8s(s, 2); /* pad */
797     process_orders(s, count);
798 matty 10 break;
799 matty 3
800 matty 10 case RDP_UPDATE_BITMAP:
801     process_bitmap_updates(s);
802     break;
803 matty 3
804 matty 10 case RDP_UPDATE_PALETTE:
805     process_palette(s);
806     break;
807 matty 3
808 matty 10 case RDP_UPDATE_SYNCHRONIZE:
809     break;
810 matty 9
811 matty 10 default:
812 matty 30 unimpl("update %d\n", update_type);
813 matty 3 }
814    
815     }
816    
817 matty 10 /* Process data PDU */
818 matty 25 static void
819     process_data_pdu(STREAM s)
820 matty 9 {
821 matty 10 uint8 data_pdu_type;
822 matty 9
823 matty 24 in_uint8s(s, 8); /* shareid, pad, streamid, length */
824 matty 10 in_uint8(s, data_pdu_type);
825 matty 24 in_uint8s(s, 3); /* compress_type, compress_len */
826 matty 3
827 matty 10 switch (data_pdu_type)
828 matty 3 {
829 matty 10 case RDP_DATA_PDU_UPDATE:
830     process_update_pdu(s);
831     break;
832 matty 3
833 matty 10 case RDP_DATA_PDU_POINTER:
834     process_pointer_pdu(s);
835     break;
836 matty 3
837 matty 10 case RDP_DATA_PDU_BELL:
838     ui_bell();
839     break;
840 matty 3
841 matty 10 case RDP_DATA_PDU_LOGON:
842 forsberg 351 DEBUG(("Received Logon PDU\n"));
843 matty 10 /* User logged on */
844     break;
845 matty 3
846 matty 10 default:
847 matty 30 unimpl("data PDU %d\n", data_pdu_type);
848 matty 3 }
849     }
850    
851 matty 10 /* Process incoming packets */
852 matty 25 void
853 matthewc 192 rdp_main_loop(void)
854 matty 9 {
855 matty 10 uint8 type;
856     STREAM s;
857 matty 9
858 matty 10 while ((s = rdp_recv(&type)) != NULL)
859 matty 3 {
860 matty 10 switch (type)
861     {
862     case RDP_PDU_DEMAND_ACTIVE:
863     process_demand_active(s);
864     break;
865 matty 3
866 matty 10 case RDP_PDU_DEACTIVATE:
867     break;
868 matty 3
869 matty 10 case RDP_PDU_DATA:
870     process_data_pdu(s);
871     break;
872 matty 3
873 jsorg71 283 case 0:
874     break;
875    
876 matty 10 default:
877 matty 30 unimpl("PDU %d\n", type);
878 matty 10 }
879 matty 3 }
880     }
881    
882 matty 10 /* Establish a connection up to the RDP layer */
883 matty 25 BOOL
884     rdp_connect(char *server, uint32 flags, char *domain, char *password,
885     char *command, char *directory)
886 matty 9 {
887 forsberg 410 if (use_rdp5)
888     channels_init();
889    
890 forsberg 351 if (!sec_connect(server, username))
891 matty 3 return False;
892    
893 astrand 82 rdp_send_logon_info(flags, domain, username, password, command, directory);
894 matty 10 return True;
895 matty 3 }
896    
897 matty 10 /* Disconnect from the RDP layer */
898 matty 25 void
899 matthewc 192 rdp_disconnect(void)
900 matty 9 {
901 matty 10 sec_disconnect();
902 matty 9 }

  ViewVC Help
Powered by ViewVC 1.1.26