/[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 376 - (hide annotations)
Mon May 19 21:36:33 2003 UTC (21 years ago) by jsorg71
File MIME type: text/plain
File size: 21358 byte(s)
changes so it compiles with g++(mainly for ports)

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

  ViewVC Help
Powered by ViewVC 1.1.26