/[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 369 - (hide annotations)
Tue Apr 22 15:48:56 2003 UTC (21 years ago) by forsberg
File MIME type: text/plain
File size: 20294 byte(s)
Fix bug that caused auto-logon not to work.

This is however just a fix for the case when you're running RDP4. The RDP5
code is still buggy.

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

  ViewVC Help
Powered by ViewVC 1.1.26