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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 10 by matty, Tue Aug 15 10:23:24 2000 UTC revision 831 by jdmeijer, Tue Mar 8 00:43:10 2005 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Protocol services - RDP layer     Protocol services - RDP layer
4     Copyright (C) Matthew Chapman 1999-2000     Copyright (C) Matthew Chapman 1999-2005
5      
6     This program is free software; you can redistribute it and/or modify     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     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     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.     GNU General Public License for more details.
15      
16     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
21    #include <time.h>
22  #include "rdesktop.h"  #include "rdesktop.h"
23    
24  extern uint16 mcs_userid;  extern uint16 g_mcs_userid;
25  extern char username[16];  extern char g_username[16];
26  extern BOOL orders;  extern BOOL g_bitmap_compression;
27    extern BOOL g_orders;
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 uint32 g_rdp5_performanceflags;
33    extern int g_server_bpp;
34    extern int g_width;
35    extern int g_height;
36    extern BOOL g_bitmap_cache;
37    extern BOOL g_bitmap_cache_persist_enable;
38    
39  unsigned char *next_packet;  uint8 *g_next_packet;
40  uint32 rdp_shareid;  uint32 g_rdp_shareid;
41    
42  /* Initialise an RDP packet */  extern RDPCOMP g_mppc_dict;
 static STREAM rdp_init(int maxlen)  
 {  
         STREAM s;  
   
         s = sec_init(SEC_ENCRYPT, maxlen + 6);  
         s_push_layer(s, rdp_hdr, 6);  
43    
44          return s;  #if WITH_DEBUG
45  }  static uint32 g_packetno;
46    #endif
 /* Send an RDP packet */  
 static void rdp_send(STREAM s, uint8 pdu_type)  
 {  
         uint16 length;  
   
         s_pop_layer(s, rdp_hdr);  
         length = s->end - s->p;  
   
         out_uint16_le(s, length);  
         out_uint16_le(s, (pdu_type | 0x10)); /* Version 1 */  
         out_uint16_le(s, (mcs_userid + 1001));  
   
         sec_send(s, SEC_ENCRYPT);  
 }  
47    
48  /* Receive an RDP packet */  /* Receive an RDP packet */
49  static STREAM rdp_recv(uint8 *type)  static STREAM
50    rdp_recv(uint8 * type)
51  {  {
52          static STREAM rdp_s;          static STREAM rdp_s;
53          uint16 length, pdu_type;          uint16 length, pdu_type;
54            uint8 rdpver;
55    
56          if ((rdp_s == NULL) || (next_packet >= rdp_s->end))          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))
57          {          {
58                  rdp_s = sec_recv();                  rdp_s = sec_recv(&rdpver);
59                  if (rdp_s == NULL)                  if (rdp_s == NULL)
60                          return NULL;                          return NULL;
61                    if (rdpver == 0xff)
62                    {
63                            g_next_packet = rdp_s->end;
64                            *type = 0;
65                            return rdp_s;
66                    }
67                    else if (rdpver != 3)
68                    {
69                            /* rdp5_process should move g_next_packet ok */
70                            rdp5_process(rdp_s);
71                            *type = 0;
72                            return rdp_s;
73                    }
74    
75                  next_packet = rdp_s->p;                  g_next_packet = rdp_s->p;
76          }          }
77          else          else
78          {          {
79                  rdp_s->p = next_packet;                  rdp_s->p = g_next_packet;
80          }          }
81    
82          in_uint16_le(rdp_s, length);          in_uint16_le(rdp_s, length);
83            /* 32k packets are really 8, keepalive fix */
84            if (length == 0x8000)
85            {
86                    g_next_packet += 8;
87                    *type = 0;
88                    return rdp_s;
89            }
90          in_uint16_le(rdp_s, pdu_type);          in_uint16_le(rdp_s, pdu_type);
91          in_uint8s(rdp_s, 2); /* userid */          in_uint8s(rdp_s, 2);    /* userid */
   
         next_packet += length;  
92          *type = pdu_type & 0xf;          *type = pdu_type & 0xf;
93    
94  #if RDP_DEBUG  #if WITH_DEBUG
95          DEBUG("RDP packet (type %x):\n", *type);          DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type));
96          hexdump(rdp_s->p, length);          hexdump(g_next_packet, length);
97  #endif  #endif /*  */
98    
99            g_next_packet += length;
100          return rdp_s;          return rdp_s;
101  }  }
102    
103  /* Initialise an RDP data packet */  /* Initialise an RDP data packet */
104  static STREAM rdp_init_data(int maxlen)  static STREAM
105    rdp_init_data(int maxlen)
106  {  {
107          STREAM s;          STREAM s;
108    
109          s = sec_init(SEC_ENCRYPT, maxlen + 18);          s = sec_init(g_encryption ? SEC_ENCRYPT : 0, maxlen + 18);
110          s_push_layer(s, rdp_hdr, 18);          s_push_layer(s, rdp_hdr, 18);
111    
112          return s;          return s;
113  }  }
114    
115  /* Send an RDP data packet */  /* Send an RDP data packet */
116  static void rdp_send_data(STREAM s, uint8 data_pdu_type)  static void
117    rdp_send_data(STREAM s, uint8 data_pdu_type)
118  {  {
119          uint16 length;          uint16 length;
120    
# Line 108  static void rdp_send_data(STREAM s, uint Line 123  static void rdp_send_data(STREAM s, uint
123    
124          out_uint16_le(s, length);          out_uint16_le(s, length);
125          out_uint16_le(s, (RDP_PDU_DATA | 0x10));          out_uint16_le(s, (RDP_PDU_DATA | 0x10));
126          out_uint16_le(s, (mcs_userid + 1001));          out_uint16_le(s, (g_mcs_userid + 1001));
127    
128          out_uint32_le(s, rdp_shareid);          out_uint32_le(s, g_rdp_shareid);
129          out_uint8(s, 0);  /* pad */          out_uint8(s, 0);        /* pad */
130          out_uint8(s, 1);  /* streamid */          out_uint8(s, 1);        /* streamid */
131          out_uint16(s, (length - 14));          out_uint16_le(s, (length - 14));
132          out_uint8(s, data_pdu_type);          out_uint8(s, data_pdu_type);
133          out_uint8(s, 0);  /* compress_type */          out_uint8(s, 0);        /* compress_type */
134          out_uint16(s, 0); /* compress_len */          out_uint16(s, 0);       /* compress_len */
135    
136          sec_send(s, SEC_ENCRYPT);          sec_send(s, g_encryption ? SEC_ENCRYPT : 0);
137  }  }
138    
139  /* Output a string in Unicode */  /* Output a string in Unicode */
140  void rdp_out_unistr(STREAM s, char *string, int len)  void
141    rdp_out_unistr(STREAM s, char *string, int len)
142  {  {
143          int i = 0, j = 0;          int i = 0, j = 0;
144    
# Line 137  void rdp_out_unistr(STREAM s, char *stri Line 153  void rdp_out_unistr(STREAM s, char *stri
153          s->p += len;          s->p += len;
154  }  }
155    
156  /* Parse a logon info packet */  /* Input a string in Unicode
157  static void rdp_send_logon_info(uint32 flags, char *domain, char *user,   *
158                                  char *password, char *program, char *directory)   * Returns str_len of string
159     */
160    int
161    rdp_in_unistr(STREAM s, char *string, int uni_len)
162  {  {
163          int len_domain    = 2 * strlen(domain);          int i = 0;
164          int len_user      = 2 * strlen(user);  
165          int len_password  = 2 * strlen(password);          while (i < uni_len / 2)
166          int len_program   = 2 * strlen(program);          {
167                    in_uint8a(s, &string[i++], 1);
168                    in_uint8s(s, 1);
169            }
170    
171            return i - 1;
172    }
173    
174    
175    /* Parse a logon info packet */
176    static void
177    rdp_send_logon_info(uint32 flags, char *domain, char *user,
178                        char *password, char *program, char *directory)
179    {
180            char *ipaddr = tcp_get_address();
181            int len_domain = 2 * strlen(domain);
182            int len_user = 2 * strlen(user);
183            int len_password = 2 * strlen(password);
184            int len_program = 2 * strlen(program);
185          int len_directory = 2 * strlen(directory);          int len_directory = 2 * strlen(directory);
186          uint32 sec_flags = SEC_LOGON_INFO | SEC_ENCRYPT;          int len_ip = 2 * strlen(ipaddr);
187            int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
188            int packetlen = 0;
189            uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
190          STREAM s;          STREAM s;
191            time_t t = time(NULL);
192            time_t tzone;
193    
194    #if 0
195            /* enable rdp compression */
196            /* some problems still exist with rdp5 */
197            flags |= RDP_COMPRESSION;
198    #endif
199    
200            if (!g_use_rdp5 || 1 == g_server_rdp_version)
201            {
202                    DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
203    
204                    s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
205                                 + len_program + len_directory + 10);
206    
207                    out_uint32(s, 0);
208                    out_uint32_le(s, flags);
209                    out_uint16_le(s, len_domain);
210                    out_uint16_le(s, len_user);
211                    out_uint16_le(s, len_password);
212                    out_uint16_le(s, len_program);
213                    out_uint16_le(s, len_directory);
214                    rdp_out_unistr(s, domain, len_domain);
215                    rdp_out_unistr(s, user, len_user);
216                    rdp_out_unistr(s, password, len_password);
217                    rdp_out_unistr(s, program, len_program);
218                    rdp_out_unistr(s, directory, len_directory);
219            }
220            else
221            {
222    
223                    flags |= RDP_LOGON_BLOB;
224                    DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
225                    packetlen = 4 + /* Unknown uint32 */
226                            4 +     /* flags */
227                            2 +     /* len_domain */
228                            2 +     /* len_user */
229                            (flags & RDP_LOGON_AUTO ? 2 : 0) +      /* len_password */
230                            (flags & RDP_LOGON_BLOB ? 2 : 0) +      /* Length of BLOB */
231                            2 +     /* len_program */
232                            2 +     /* len_directory */
233                            (0 < len_domain ? len_domain : 2) +     /* domain */
234                            len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 +    /* We have no 512 byte BLOB. Perhaps we must? */
235                            (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + /* After the BLOB is a unknown int16. If there is a BLOB, that is. */
236                            (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 +     /* Unknown (2) */
237                            2 +     /* Client ip length */
238                            len_ip +        /* Client ip */
239                            2 +     /* DLL string length */
240                            len_dll +       /* DLL string */
241                            2 +     /* Unknown */
242                            2 +     /* Unknown */
243                            64 +    /* Time zone #0 */
244                            2 +     /* Unknown */
245                            64 +    /* Time zone #1 */
246                            32;     /* Unknown */
247    
248                    s = sec_init(sec_flags, packetlen);
249                    DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
250    
251                    out_uint32(s, 0);       /* Unknown */
252                    out_uint32_le(s, flags);
253                    out_uint16_le(s, len_domain);
254                    out_uint16_le(s, len_user);
255                    if (flags & RDP_LOGON_AUTO)
256                    {
257                            out_uint16_le(s, len_password);
258    
259                    }
260                    if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
261                    {
262                            out_uint16_le(s, 0);
263                    }
264                    out_uint16_le(s, len_program);
265                    out_uint16_le(s, len_directory);
266                    if (0 < len_domain)
267                            rdp_out_unistr(s, domain, len_domain);
268                    else
269                            out_uint16_le(s, 0);
270                    rdp_out_unistr(s, user, len_user);
271                    if (flags & RDP_LOGON_AUTO)
272                    {
273                            rdp_out_unistr(s, password, len_password);
274                    }
275                    if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
276                    {
277                            out_uint16_le(s, 0);
278                    }
279                    if (0 < len_program)
280                    {
281                            rdp_out_unistr(s, program, len_program);
282    
283          s = sec_init(sec_flags, 18 + len_domain + len_user + len_password                  }
284                                          + len_program + len_directory + 10);                  else
285                    {
286                            out_uint16_le(s, 0);
287                    }
288                    if (0 < len_directory)
289                    {
290                            rdp_out_unistr(s, directory, len_directory);
291                    }
292                    else
293                    {
294                            out_uint16_le(s, 0);
295                    }
296                    out_uint16_le(s, 2);
297                    out_uint16_le(s, len_ip + 2);   /* Length of client ip */
298                    rdp_out_unistr(s, ipaddr, len_ip);
299                    out_uint16_le(s, len_dll + 2);
300                    rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
301    
302                    tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
303                    out_uint32_le(s, tzone);
304    
305                    rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
306                    out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
307    
308                    out_uint32_le(s, 0x0a0000);
309                    out_uint32_le(s, 0x050000);
310                    out_uint32_le(s, 3);
311                    out_uint32_le(s, 0);
312                    out_uint32_le(s, 0);
313    
314                    rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
315                    out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
316    
317                    out_uint32_le(s, 0x30000);
318                    out_uint32_le(s, 0x050000);
319                    out_uint32_le(s, 2);
320                    out_uint32(s, 0);
321                    out_uint32_le(s, 0xffffffc4);
322                    out_uint32_le(s, 0xfffffffe);
323                    out_uint32_le(s, g_rdp5_performanceflags);
324                    out_uint32(s, 0);
325    
         out_uint32(s, 0);  
         out_uint32_le(s, flags);  
         out_uint16_le(s, len_domain);  
         out_uint16_le(s, len_user);  
         out_uint16_le(s, len_password);  
         out_uint16_le(s, len_program);  
         out_uint16_le(s, len_directory);  
         rdp_out_unistr(s, domain,    len_domain);  
         rdp_out_unistr(s, user,      len_user);  
         rdp_out_unistr(s, password,  len_password);  
         rdp_out_unistr(s, program,   len_program);  
         rdp_out_unistr(s, directory, len_directory);  
326    
327            }
328          s_mark_end(s);          s_mark_end(s);
329          sec_send(s, sec_flags);          sec_send(s, sec_flags);
330  }  }
331    
332  /* Send a control PDU */  /* Send a control PDU */
333  static void rdp_send_control(uint16 action)  static void
334    rdp_send_control(uint16 action)
335  {  {
336          STREAM s;          STREAM s;
337    
338          s = rdp_init_data(8);          s = rdp_init_data(8);
339    
340          out_uint16_le(s, action);          out_uint16_le(s, action);
341          out_uint16(s, 0); /* userid */          out_uint16(s, 0);       /* userid */
342          out_uint32(s, 0); /* control id */          out_uint32(s, 0);       /* control id */
343    
344          s_mark_end(s);          s_mark_end(s);
345          rdp_send_data(s, RDP_DATA_PDU_CONTROL);          rdp_send_data(s, RDP_DATA_PDU_CONTROL);
346  }  }
347    
348  /* Send a synchronisation PDU */  /* Send a synchronisation PDU */
349  static void rdp_send_synchronise()  static void
350    rdp_send_synchronise(void)
351  {  {
352          STREAM s;          STREAM s;
353    
354          s = rdp_init_data(4);          s = rdp_init_data(4);
355    
356          out_uint16_le(s, 1); /* type */          out_uint16_le(s, 1);    /* type */
357          out_uint16_le(s, 1002);          out_uint16_le(s, 1002);
358    
359          s_mark_end(s);          s_mark_end(s);
# Line 199  static void rdp_send_synchronise() Line 361  static void rdp_send_synchronise()
361  }  }
362    
363  /* Send a single input event */  /* Send a single input event */
364  void rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags,  void
365                      uint16 param1, uint16 param2)  rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
366  {  {
367          STREAM s;          STREAM s;
368    
369          s = rdp_init_data(16);          s = rdp_init_data(16);
370    
371          out_uint16_le(s, 1); /* number of events */          out_uint16_le(s, 1);    /* number of events */
372          out_uint16(s, 0);    /* pad */          out_uint16(s, 0);       /* pad */
373    
374          out_uint32_le(s, time);          out_uint32_le(s, time);
375          out_uint16_le(s, message_type);          out_uint16_le(s, message_type);
# Line 219  void rdp_send_input(uint32 time, uint16 Line 381  void rdp_send_input(uint32 time, uint16
381          rdp_send_data(s, RDP_DATA_PDU_INPUT);          rdp_send_data(s, RDP_DATA_PDU_INPUT);
382  }  }
383    
384    /* Inform the server on the contents of the persistent bitmap cache */
385    static void
386    rdp_enum_bmpcache2(void)
387    {
388            STREAM s;
389            HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS];
390            uint32 num_keys, offset, count, flags;
391    
392            offset = 0;
393            num_keys = pstcache_enumerate(2, keylist);
394    
395            while (offset < num_keys)
396            {
397                    count = MIN(num_keys - offset, 169);
398    
399                    s = rdp_init_data(24 + count * sizeof(HASH_KEY));
400    
401                    flags = 0;
402                    if (offset == 0)
403                            flags |= PDU_FLAG_FIRST;
404                    if (num_keys - offset <= 169)
405                            flags |= PDU_FLAG_LAST;
406    
407                    /* header */
408                    out_uint32_le(s, 0);
409                    out_uint16_le(s, count);
410                    out_uint16_le(s, 0);
411                    out_uint16_le(s, 0);
412                    out_uint16_le(s, 0);
413                    out_uint16_le(s, 0);
414                    out_uint16_le(s, num_keys);
415                    out_uint32_le(s, 0);
416                    out_uint32_le(s, flags);
417    
418                    /* list */
419                    out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
420    
421                    s_mark_end(s);
422                    rdp_send_data(s, 0x2b);
423    
424                    offset += 169;
425            }
426    }
427    
428  /* Send an (empty) font information PDU */  /* Send an (empty) font information PDU */
429  static void rdp_send_fonts(uint16 seq)  static void
430    rdp_send_fonts(uint16 seq)
431  {  {
432          STREAM s;          STREAM s;
433    
434          s = rdp_init_data(8);          s = rdp_init_data(8);
435    
436          out_uint16(s, 0);       /* number of fonts */          out_uint16(s, 0);       /* number of fonts */
437          out_uint16_le(s, 0x3e); /* unknown */          out_uint16_le(s, 0);    /* pad? */
438          out_uint16_le(s, seq);  /* unknown */          out_uint16_le(s, seq);  /* unknown */
439          out_uint16_le(s, 0x32); /* entry size */          out_uint16_le(s, 0x32); /* entry size */
440    
# Line 236  static void rdp_send_fonts(uint16 seq) Line 443  static void rdp_send_fonts(uint16 seq)
443  }  }
444    
445  /* Output general capability set */  /* Output general capability set */
446  static void rdp_out_general_caps(STREAM s)  static void
447    rdp_out_general_caps(STREAM s)
448  {  {
449          out_uint16_le(s, RDP_CAPSET_GENERAL);          out_uint16_le(s, RDP_CAPSET_GENERAL);
450          out_uint16_le(s, RDP_CAPLEN_GENERAL);          out_uint16_le(s, RDP_CAPLEN_GENERAL);
451    
452          out_uint16_le(s, 1);    /* OS major type */          out_uint16_le(s, 1);    /* OS major type */
453          out_uint16_le(s, 3);    /* OS minor type */          out_uint16_le(s, 3);    /* OS minor type */
454          out_uint16_le(s, 0x200); /* Protocol version */          out_uint16_le(s, 0x200);        /* Protocol version */
455          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
456          out_uint16(s, 0);       /* Compression types */          out_uint16(s, 0);       /* Compression types */
457          out_uint16(s, 0);       /* Pad */          out_uint16_le(s, g_use_rdp5 ? 0x40d : 0);
458            /* Pad, according to T.128. 0x40d seems to
459               trigger
460               the server to start sending RDP5 packets.
461               However, the value is 0x1d04 with W2KTSK and
462               NT4MS. Hmm.. Anyway, thankyou, Microsoft,
463               for sending such information in a padding
464               field.. */
465          out_uint16(s, 0);       /* Update capability */          out_uint16(s, 0);       /* Update capability */
466          out_uint16(s, 0);       /* Remote unshare capability */          out_uint16(s, 0);       /* Remote unshare capability */
467          out_uint16(s, 0);       /* Compression level */          out_uint16(s, 0);       /* Compression level */
# Line 254  static void rdp_out_general_caps(STREAM Line 469  static void rdp_out_general_caps(STREAM
469  }  }
470    
471  /* Output bitmap capability set */  /* Output bitmap capability set */
472  static void rdp_out_bitmap_caps(STREAM s)  static void
473    rdp_out_bitmap_caps(STREAM s)
474  {  {
475          out_uint16_le(s, RDP_CAPSET_BITMAP);          out_uint16_le(s, RDP_CAPSET_BITMAP);
476          out_uint16_le(s, RDP_CAPLEN_BITMAP);          out_uint16_le(s, RDP_CAPLEN_BITMAP);
477    
478          out_uint16_le(s, 8);    /* Preferred BPP */          out_uint16_le(s, g_server_bpp); /* Preferred BPP */
479          out_uint16(s, 1);       /* Receive 1 BPP */          out_uint16_le(s, 1);    /* Receive 1 BPP */
480          out_uint16(s, 1);       /* Receive 4 BPP */          out_uint16_le(s, 1);    /* Receive 4 BPP */
481          out_uint16_le(s, 1);    /* Receive 8 BPP */          out_uint16_le(s, 1);    /* Receive 8 BPP */
482          out_uint16_le(s, 800);  /* Desktop width */          out_uint16_le(s, 800);  /* Desktop width */
483          out_uint16_le(s, 600);  /* Desktop height */          out_uint16_le(s, 600);  /* Desktop height */
484          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
485          out_uint16(s, 0);       /* Allow resize */          out_uint16(s, 1);       /* Allow resize */
486          out_uint16_le(s, 1);    /* Support compression */          out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
487          out_uint16(s, 0);       /* Unknown */          out_uint16(s, 0);       /* Unknown */
488          out_uint16_le(s, 1);    /* Unknown */          out_uint16_le(s, 1);    /* Unknown */
489          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
490  }  }
491    
492  /* Output order capability set */  /* Output order capability set */
493  static void rdp_out_order_caps(STREAM s)  static void
494    rdp_out_order_caps(STREAM s)
495  {  {
496          uint8 order_caps[32];          uint8 order_caps[32];
497    
498          memset(order_caps, orders, 32);          memset(order_caps, 0, 32);
499            order_caps[0] = 1;      /* dest blt */
500            order_caps[1] = 1;      /* pat blt */
501            order_caps[2] = 1;      /* screen blt */
502            order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
503            order_caps[4] = 0;      /* triblt */
504            order_caps[8] = 1;      /* line */
505            order_caps[9] = 1;      /* line */
506            order_caps[10] = 1;     /* rect */
507            order_caps[11] = (g_desktop_save == False ? 0 : 1);     /* desksave */
508            order_caps[13] = 1;     /* memblt */
509            order_caps[14] = 1;     /* triblt */
510            order_caps[20] = 1;     /* polygon */
511            order_caps[21] = 1;     /* polygon2 */
512            order_caps[22] = 1;     /* polyline */
513            order_caps[25] = 1;     /* ellipse */
514            order_caps[26] = 1;     /* ellipse2 */
515            order_caps[27] = 1;     /* text2 */
516          out_uint16_le(s, RDP_CAPSET_ORDER);          out_uint16_le(s, RDP_CAPSET_ORDER);
517          out_uint16_le(s, RDP_CAPLEN_ORDER);          out_uint16_le(s, RDP_CAPLEN_ORDER);
518    
# Line 289  static void rdp_out_order_caps(STREAM s) Line 522  static void rdp_out_order_caps(STREAM s)
522          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
523          out_uint16_le(s, 1);    /* Max order level */          out_uint16_le(s, 1);    /* Max order level */
524          out_uint16_le(s, 0x147);        /* Number of fonts */          out_uint16_le(s, 0x147);        /* Number of fonts */
525          out_uint16_le(s, 0x2a);         /* Capability flags */          out_uint16_le(s, 0x2a); /* Capability flags */
526          out_uint8p(s, order_caps, 32);  /* Orders supported */          out_uint8p(s, order_caps, 32);  /* Orders supported */
527          out_uint16_le(s, 0x6a1);        /* Text capability flags */          out_uint16_le(s, 0x6a1);        /* Text capability flags */
528          out_uint8s(s, 6);       /* Pad */          out_uint8s(s, 6);       /* Pad */
529          out_uint32(s, 0x38400); /* Desktop cache size */          out_uint32_le(s, g_desktop_save == False ? 0 : 0x38400);        /* Desktop cache size */
530          out_uint32(s, 0);       /* Unknown */          out_uint32(s, 0);       /* Unknown */
531          out_uint32(s, 0x4e4);   /* Unknown */          out_uint32_le(s, 0x4e4);        /* Unknown */
532  }  }
533    
534  /* Output bitmap cache capability set */  /* Output bitmap cache capability set */
535  static void rdp_out_bmpcache_caps(STREAM s)  static void
536    rdp_out_bmpcache_caps(STREAM s)
537  {  {
538            int Bpp;
539          out_uint16_le(s, RDP_CAPSET_BMPCACHE);          out_uint16_le(s, RDP_CAPSET_BMPCACHE);
540          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
541    
542          out_uint8s(s, 24); /* unused */          Bpp = (g_server_bpp + 7) / 8;
543          out_uint16_le(s, 0x258); /* entries */          out_uint8s(s, 24);      /* unused */
544          out_uint16_le(s, 0x100); /* max cell size */          out_uint16_le(s, 0x258);        /* entries */
545          out_uint16_le(s, 0x12c); /* entries */          out_uint16_le(s, 0x100 * Bpp);  /* max cell size */
546          out_uint16_le(s, 0x400); /* max cell size */          out_uint16_le(s, 0x12c);        /* entries */
547          out_uint16_le(s, 0x106); /* entries */          out_uint16_le(s, 0x400 * Bpp);  /* max cell size */
548          out_uint16_le(s, 0x1000); /* max cell size */          out_uint16_le(s, 0x106);        /* entries */
549            out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
550    }
551    
552    /* Output bitmap cache v2 capability set */
553    static void
554    rdp_out_bmpcache2_caps(STREAM s)
555    {
556            out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
557            out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
558    
559            out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
560    
561            out_uint16_le(s, 0x0300);       /* flags? number of caches? */
562    
563            out_uint32_le(s, BMPCACHE2_C0_CELLS);
564            out_uint32_le(s, BMPCACHE2_C1_CELLS);
565            if (pstcache_init(2))
566            {
567                    out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
568            }
569            else
570            {
571                    out_uint32_le(s, BMPCACHE2_C2_CELLS);
572            }
573            out_uint8s(s, 20);      /* other bitmap caches not used */
574  }  }
575    
576  /* Output control capability set */  /* Output control capability set */
577  static void rdp_out_control_caps(STREAM s)  static void
578    rdp_out_control_caps(STREAM s)
579  {  {
580          out_uint16_le(s, RDP_CAPSET_CONTROL);          out_uint16_le(s, RDP_CAPSET_CONTROL);
581          out_uint16_le(s, RDP_CAPLEN_CONTROL);          out_uint16_le(s, RDP_CAPLEN_CONTROL);
# Line 326  static void rdp_out_control_caps(STREAM Line 587  static void rdp_out_control_caps(STREAM
587  }  }
588    
589  /* Output activation capability set */  /* Output activation capability set */
590  static void rdp_out_activate_caps(STREAM s)  static void
591    rdp_out_activate_caps(STREAM s)
592  {  {
593          out_uint16_le(s, RDP_CAPSET_ACTIVATE);          out_uint16_le(s, RDP_CAPSET_ACTIVATE);
594          out_uint16_le(s, RDP_CAPLEN_ACTIVATE);          out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
# Line 338  static void rdp_out_activate_caps(STREAM Line 600  static void rdp_out_activate_caps(STREAM
600  }  }
601    
602  /* Output pointer capability set */  /* Output pointer capability set */
603  static void rdp_out_pointer_caps(STREAM s)  static void
604    rdp_out_pointer_caps(STREAM s)
605  {  {
606          out_uint16_le(s, RDP_CAPSET_POINTER);          out_uint16_le(s, RDP_CAPSET_POINTER);
607          out_uint16_le(s, RDP_CAPLEN_POINTER);          out_uint16_le(s, RDP_CAPLEN_POINTER);
# Line 348  static void rdp_out_pointer_caps(STREAM Line 611  static void rdp_out_pointer_caps(STREAM
611  }  }
612    
613  /* Output share capability set */  /* Output share capability set */
614  static void rdp_out_share_caps(STREAM s)  static void
615    rdp_out_share_caps(STREAM s)
616  {  {
617          out_uint16_le(s, RDP_CAPSET_SHARE);          out_uint16_le(s, RDP_CAPSET_SHARE);
618          out_uint16_le(s, RDP_CAPLEN_SHARE);          out_uint16_le(s, RDP_CAPLEN_SHARE);
# Line 358  static void rdp_out_share_caps(STREAM s) Line 622  static void rdp_out_share_caps(STREAM s)
622  }  }
623    
624  /* Output colour cache capability set */  /* Output colour cache capability set */
625  static void rdp_out_colcache_caps(STREAM s)  static void
626    rdp_out_colcache_caps(STREAM s)
627  {  {
628          out_uint16_le(s, RDP_CAPSET_COLCACHE);          out_uint16_le(s, RDP_CAPSET_COLCACHE);
629          out_uint16_le(s, RDP_CAPLEN_COLCACHE);          out_uint16_le(s, RDP_CAPLEN_COLCACHE);
# Line 367  static void rdp_out_colcache_caps(STREAM Line 632  static void rdp_out_colcache_caps(STREAM
632          out_uint16(s, 0);       /* pad */          out_uint16(s, 0);       /* pad */
633  }  }
634    
635  static uint8 canned_caps[] = {  static uint8 caps_0x0d[] = {
636  0x01,0x00,0x00,0x00,0x09,0x04,0x00,0x00,0x04,          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
637  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,          0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x08,0x00,0x01,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
642  0x00,0x00,0x00,0x0E,0x00,0x08,0x00,0x01,0x00,0x00,0x00,0x10,0x00,0x34,0x00,0xFE,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643  0x00,0x04,0x00,0xFE,0x00,0x04,0x00,0xFE,0x00,0x08,0x00,0xFE,0x00,0x08,0x00,0xFE,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644  0x00,0x10,0x00,0xFE,0x00,0x20,0x00,0xFE,0x00,0x40,0x00,0xFE,0x00,0x80,0x00,0xFE,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645  0x00,0x00,0x01,0x40,0x00,0x00,0x08,0x00,0x01,0x00,0x01,0x02,0x00,0x00,0x00          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646            0x00, 0x00, 0x00, 0x00
647  };  };
648    
649  /* Output unknown capability set */  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
650  static void rdp_out_unknown_caps(STREAM s)  
651    static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
652    
653    static uint8 caps_0x10[] = {
654            0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
655            0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
656            0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
657            0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
658            0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
659            0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
660    };
661    
662    /* Output unknown capability sets */
663    static void
664    rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
665  {  {
666          out_uint16_le(s, RDP_CAPSET_UNKNOWN);          out_uint16_le(s, id);
667          out_uint16_le(s, 0x58);          out_uint16_le(s, length);
668            
669          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN-4);          out_uint8p(s, caps, length - 4);
670  }  }
671    
672    #define RDP5_FLAG 0x0030
673  /* Send a confirm active PDU */  /* Send a confirm active PDU */
674  static void rdp_send_confirm_active()  static void
675    rdp_send_confirm_active(void)
676  {  {
677          STREAM s;          STREAM s;
678          uint16 caplen = RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER          uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
679                  + RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE + RDP_CAPLEN_ACTIVATE          uint16 caplen =
680                  + RDP_CAPLEN_CONTROL + RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
681                  + RDP_CAPLEN_UNKNOWN;                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
682                    RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
683                    RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
684                    0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
685                    4 /* w2k fix, why? */ ;
686    
687            s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
688    
689            out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
690            out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10));      /* Version 1 */
691            out_uint16_le(s, (g_mcs_userid + 1001));
692    
693          s = rdp_init(14 + caplen + sizeof(RDP_SOURCE));          out_uint32_le(s, g_rdp_shareid);
694            out_uint16_le(s, 0x3ea);        /* userid */
         out_uint32_le(s, rdp_shareid);  
         out_uint16_le(s, 0x3ea); /* userid */  
695          out_uint16_le(s, sizeof(RDP_SOURCE));          out_uint16_le(s, sizeof(RDP_SOURCE));
696          out_uint16_le(s, caplen);          out_uint16_le(s, caplen);
697    
698          out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));          out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
699          out_uint16_le(s, 0xd); /* num_caps */          out_uint16_le(s, 0xd);  /* num_caps */
700          out_uint8s(s, 2);     /* pad */          out_uint8s(s, 2);       /* pad */
701    
702          rdp_out_general_caps(s);          rdp_out_general_caps(s);
703          rdp_out_bitmap_caps(s);          rdp_out_bitmap_caps(s);
704          rdp_out_order_caps(s);          rdp_out_order_caps(s);
705          rdp_out_bmpcache_caps(s);          g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
706          rdp_out_colcache_caps(s);          rdp_out_colcache_caps(s);
707          rdp_out_activate_caps(s);          rdp_out_activate_caps(s);
708          rdp_out_control_caps(s);          rdp_out_control_caps(s);
709          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
710          rdp_out_share_caps(s);          rdp_out_share_caps(s);
711          rdp_out_unknown_caps(s);  
712            rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
713            rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
714            rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
715            rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
716    
717          s_mark_end(s);          s_mark_end(s);
718          rdp_send(s, RDP_PDU_CONFIRM_ACTIVE);          sec_send(s, sec_flags);
719    }
720    
721    /* Process a general capability set */
722    static void
723    rdp_process_general_caps(STREAM s)
724    {
725            uint16 pad2octetsB;     /* rdp5 flags? */
726    
727            in_uint8s(s, 10);
728            in_uint16_le(s, pad2octetsB);
729    
730            if (!pad2octetsB)
731                    g_use_rdp5 = False;
732    }
733    
734    /* Process a bitmap capability set */
735    static void
736    rdp_process_bitmap_caps(STREAM s)
737    {
738            uint16 width, height, bpp;
739    
740            in_uint16_le(s, bpp);
741            in_uint8s(s, 6);
742    
743            in_uint16_le(s, width);
744            in_uint16_le(s, height);
745    
746            DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));
747    
748            /*
749             * The server may limit bpp and change the size of the desktop (for
750             * example when shadowing another session).
751             */
752            if (g_server_bpp != bpp)
753            {
754                    warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
755                    g_server_bpp = bpp;
756            }
757            if (g_width != width || g_height != height)
758            {
759                    warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
760                            width, height);
761                    g_width = width;
762                    g_height = height;
763                    ui_resize_window();
764            }
765    }
766    
767    /* Process server capabilities */
768    void
769    rdp_process_server_caps(STREAM s, uint16 length)
770    {
771            int n;
772            uint8 *next, *start;
773            uint16 ncapsets, capset_type, capset_length;
774    
775            start = s->p;
776    
777            in_uint16_le(s, ncapsets);
778            in_uint8s(s, 2);        /* pad */
779    
780            for (n = 0; n < ncapsets; n++)
781            {
782                    if (s->p > start + length)
783                            return;
784    
785                    in_uint16_le(s, capset_type);
786                    in_uint16_le(s, capset_length);
787    
788                    next = s->p + capset_length - 4;
789    
790                    switch (capset_type)
791                    {
792                            case RDP_CAPSET_GENERAL:
793                                    rdp_process_general_caps(s);
794                                    break;
795    
796                            case RDP_CAPSET_BITMAP:
797                                    rdp_process_bitmap_caps(s);
798                                    break;
799                    }
800    
801                    s->p = next;
802            }
803  }  }
804    
805  /* Respond to a demand active PDU */  /* Respond to a demand active PDU */
806  static void process_demand_active(STREAM s)  static void
807    process_demand_active(STREAM s)
808  {  {
809          uint8 type;          uint8 type;
810            uint16 len_src_descriptor, len_combined_caps;
811    
812          in_uint32_le(s, rdp_shareid);          in_uint32_le(s, g_rdp_shareid);
813            in_uint16_le(s, len_src_descriptor);
814            in_uint16_le(s, len_combined_caps);
815            in_uint8s(s, len_src_descriptor);
816    
817          DEBUG("DEMAND_ACTIVE(id=0x%x)\n", rdp_shareid);          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
818            rdp_process_server_caps(s, len_combined_caps);
819    
820          rdp_send_confirm_active();          rdp_send_confirm_active();
821          rdp_send_synchronise();          rdp_send_synchronise();
822          rdp_send_control(RDP_CTL_COOPERATE);          rdp_send_control(RDP_CTL_COOPERATE);
823          rdp_send_control(RDP_CTL_REQUEST_CONTROL);          rdp_send_control(RDP_CTL_REQUEST_CONTROL);
824          rdp_recv(&type); // RDP_PDU_SYNCHRONIZE          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
825          rdp_recv(&type); // RDP_CTL_COOPERATE          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
826          rdp_recv(&type); // RDP_CTL_GRANT_CONTROL          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
827          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, 0, 0);          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);
828          rdp_send_fonts(1);  
829          rdp_send_fonts(2);          if (g_use_rdp5)
830          rdp_recv(&type); // RDP_PDU_UNKNOWN 0x28          {
831                    rdp_enum_bmpcache2();
832                    rdp_send_fonts(3);
833            }
834            else
835            {
836                    rdp_send_fonts(1);
837                    rdp_send_fonts(2);
838            }
839    
840            rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
841          reset_order_state();          reset_order_state();
842  }  }
843    
844    /* Process a colour pointer PDU */
845    void
846    process_colour_pointer_pdu(STREAM s)
847    {
848            uint16 x, y, width, height, cache_idx, masklen, datalen;
849            uint8 *mask, *data;
850            HCURSOR cursor;
851    
852            in_uint16_le(s, cache_idx);
853            in_uint16_le(s, x);
854            in_uint16_le(s, y);
855            in_uint16_le(s, width);
856            in_uint16_le(s, height);
857            in_uint16_le(s, masklen);
858            in_uint16_le(s, datalen);
859            in_uint8p(s, data, datalen);
860            in_uint8p(s, mask, masklen);
861            cursor = ui_create_cursor(x, y, width, height, mask, data);
862            ui_set_cursor(cursor);
863            cache_put_cursor(cache_idx, cursor);
864    }
865    
866    /* Process a cached pointer PDU */
867    void
868    process_cached_pointer_pdu(STREAM s)
869    {
870            uint16 cache_idx;
871    
872            in_uint16_le(s, cache_idx);
873            ui_set_cursor(cache_get_cursor(cache_idx));
874    }
875    
876    /* Process a system pointer PDU */
877    void
878    process_system_pointer_pdu(STREAM s)
879    {
880            uint16 system_pointer_type;
881    
882            in_uint16(s, system_pointer_type);
883            switch (system_pointer_type)
884            {
885                    case RDP_NULL_POINTER:
886                            ui_set_null_cursor();
887                            break;
888    
889                    default:
890                            unimpl("System pointer message 0x%x\n", system_pointer_type);
891            }
892    }
893    
894  /* Process a pointer PDU */  /* Process a pointer PDU */
895  static void process_pointer_pdu(STREAM s)  static void
896    process_pointer_pdu(STREAM s)
897  {  {
898          uint16 message_type;          uint16 message_type;
899          uint16 x, y;          uint16 x, y;
900    
901          in_uint16_le(s, message_type);          in_uint16_le(s, message_type);
902          in_uint8s(s, 2); /* pad */          in_uint8s(s, 2);        /* pad */
903    
904          switch (message_type)          switch (message_type)
905          {          {
# Line 465  static void process_pointer_pdu(STREAM s Line 910  static void process_pointer_pdu(STREAM s
910                                  ui_move_pointer(x, y);                                  ui_move_pointer(x, y);
911                          break;                          break;
912    
913                    case RDP_POINTER_COLOR:
914                            process_colour_pointer_pdu(s);
915                            break;
916    
917                    case RDP_POINTER_CACHED:
918                            process_cached_pointer_pdu(s);
919                            break;
920    
921                    case RDP_POINTER_SYSTEM:
922                            process_system_pointer_pdu(s);
923                            break;
924    
925                  default:                  default:
926                          DEBUG("Pointer message 0x%x\n", message_type);                          unimpl("Pointer message 0x%x\n", message_type);
927          }          }
928  }  }
929    
930  /* Process bitmap updates */  /* Process bitmap updates */
931  static void process_bitmap_updates(STREAM s)  void
932    process_bitmap_updates(STREAM s)
933  {  {
934          uint16 num_updates;          uint16 num_updates;
935          uint16 left, top, right, bottom, width, height;          uint16 left, top, right, bottom, width, height;
936          uint16 cx, cy, bpp, compress, bufsize, size;          uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
937          uint8 *data, *rawdata;          uint8 *data, *bmpdata;
938          int i;          int i;
939    
940          in_uint16_le(s, num_updates);          in_uint16_le(s, num_updates);
# Line 490  static void process_bitmap_updates(STREA Line 948  static void process_bitmap_updates(STREA
948                  in_uint16_le(s, width);                  in_uint16_le(s, width);
949                  in_uint16_le(s, height);                  in_uint16_le(s, height);
950                  in_uint16_le(s, bpp);                  in_uint16_le(s, bpp);
951                    Bpp = (bpp + 7) / 8;
952                  in_uint16_le(s, compress);                  in_uint16_le(s, compress);
953                  in_uint16_le(s, bufsize);                  in_uint16_le(s, bufsize);
954    
955                  cx = right - left + 1;                  cx = right - left + 1;
956                  cy = bottom - top + 1;                  cy = bottom - top + 1;
957    
958                  DEBUG("UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,cmp=%d)\n",                  DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
959                          left, top, right, bottom, width, height, compress);                         left, top, right, bottom, width, height, Bpp, compress));
960    
961                  if (!compress)                  if (!compress)
962                  {                  {
963                          in_uint8p(s, data, bufsize);                          int y;
964                          ui_paint_bitmap(left, top, cx, cy, width, height, data);                          bmpdata = (uint8 *) xmalloc(width * height * Bpp);
965                          return;                          for (y = 0; y < height; y++)
966                            {
967                                    in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
968                                              width * Bpp);
969                            }
970                            ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
971                            xfree(bmpdata);
972                            continue;
973                  }                  }
974    
                 in_uint8s(s, 2); /* pad */  
                 in_uint16_le(s, size);  
                 in_uint8s(s, 4); /* line_size, final_size */  
                 in_uint8p(s, data, size);  
975    
976                  rawdata = xmalloc(width * height);                  if (compress & 0x400)
977                  if (bitmap_decompress(rawdata, width, height, data, size))                  {
978                            size = bufsize;
979                    }
980                    else
981                    {
982                            in_uint8s(s, 2);        /* pad */
983                            in_uint16_le(s, size);
984                            in_uint8s(s, 4);        /* line_size, final_size */
985                    }
986                    in_uint8p(s, data, size);
987                    bmpdata = (uint8 *) xmalloc(width * height * Bpp);
988                    if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
989                    {
990                            ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
991                    }
992                    else
993                  {                  {
994                          ui_paint_bitmap(left, top, cx, cy, width, height,                          DEBUG_RDP5(("Failed to decompress data\n"));
                                         rawdata);  
995                  }                  }
996    
997                  xfree(rawdata);                  xfree(bmpdata);
998          }          }
999  }  }
1000    
1001  /* Process a palette update */  /* Process a palette update */
1002  static void process_palette(STREAM s)  void
1003    process_palette(STREAM s)
1004  {  {
1005          HCOLOURMAP hmap;          COLOURENTRY *entry;
1006          COLOURMAP map;          COLOURMAP map;
1007            HCOLOURMAP hmap;
1008            int i;
1009    
1010            in_uint8s(s, 2);        /* pad */
1011            in_uint16_le(s, map.ncolours);
1012            in_uint8s(s, 2);        /* pad */
1013    
1014            map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
1015    
1016            DEBUG(("PALETTE(c=%d)\n", map.ncolours));
1017    
1018          in_uint8s(s, 2); /* pad */          for (i = 0; i < map.ncolours; i++)
1019          in_uint16_le(s, map.ncolours);          {
1020          in_uint8s(s, 2); /* pad */                  entry = &map.colours[i];
1021          in_uint8p(s, (uint8 *)map.colours, (map.ncolours * 3));                  in_uint8(s, entry->red);
1022                    in_uint8(s, entry->green);
1023                    in_uint8(s, entry->blue);
1024            }
1025    
1026          hmap = ui_create_colourmap(&map);          hmap = ui_create_colourmap(&map);
1027          ui_set_colourmap(hmap);          ui_set_colourmap(hmap);
1028    
1029            xfree(map.colours);
1030  }  }
1031    
1032  /* Process an update PDU */  /* Process an update PDU */
1033  static void process_update_pdu(STREAM s)  static void
1034    process_update_pdu(STREAM s)
1035  {  {
1036          uint16 update_type;          uint16 update_type, count;
1037    
1038          in_uint16_le(s, update_type);          in_uint16_le(s, update_type);
1039    
1040            ui_begin_update();
1041          switch (update_type)          switch (update_type)
1042          {          {
1043                  case RDP_UPDATE_ORDERS:                  case RDP_UPDATE_ORDERS:
1044                          process_orders(s);                          in_uint8s(s, 2);        /* pad */
1045                            in_uint16_le(s, count);
1046                            in_uint8s(s, 2);        /* pad */
1047                            process_orders(s, count);
1048                          break;                          break;
1049    
1050                  case RDP_UPDATE_BITMAP:                  case RDP_UPDATE_BITMAP:
# Line 562  static void process_update_pdu(STREAM s) Line 1059  static void process_update_pdu(STREAM s)
1059                          break;                          break;
1060    
1061                  default:                  default:
1062                          NOTIMP("update %d\n", update_type);                          unimpl("update %d\n", update_type);
1063          }          }
1064            ui_end_update();
1065    }
1066    
1067    /* Process a disconnect PDU */
1068    void
1069    process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
1070    {
1071            in_uint32_le(s, *ext_disc_reason);
1072    
1073            DEBUG(("Received disconnect PDU\n"));
1074  }  }
1075    
1076  /* Process data PDU */  /* Process data PDU */
1077  static void process_data_pdu(STREAM s)  static BOOL
1078    process_data_pdu(STREAM s, uint32 * ext_disc_reason)
1079  {  {
1080          uint8 data_pdu_type;          uint8 data_pdu_type;
1081            uint8 ctype;
1082            uint16 clen;
1083            uint32 len;
1084    
1085          in_uint8s(s, 8); /* shareid, pad, streamid, length */          uint32 roff, rlen;
1086    
1087            struct stream *ns = &(g_mppc_dict.ns);
1088    
1089            in_uint8s(s, 6);        /* shareid, pad, streamid */
1090            in_uint16(s, len);
1091          in_uint8(s, data_pdu_type);          in_uint8(s, data_pdu_type);
1092          in_uint8s(s, 3); /* compress_type, compress_len */          in_uint8(s, ctype);
1093            in_uint16(s, clen);
1094            clen -= 18;
1095    
1096            if (ctype & RDP_MPPC_COMPRESSED)
1097            {
1098                    if (len > RDP_MPPC_DICT_SIZE)
1099                            error("error decompressed packet size exceeds max\n");
1100                    if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1101                            error("error while decompressing packet\n");
1102    
1103                    //len -= 18;
1104    
1105                    /* allocate memory and copy the uncompressed data into the temporary stream */
1106                    ns->data = (uint8 *) xrealloc(ns->data, rlen);
1107    
1108                    memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
1109    
1110                    ns->size = rlen;
1111                    ns->end = (ns->data + ns->size);
1112                    ns->p = ns->data;
1113                    ns->rdp_hdr = ns->p;
1114    
1115                    s = ns;
1116            }
1117    
1118          switch (data_pdu_type)          switch (data_pdu_type)
1119          {          {
# Line 582  static void process_data_pdu(STREAM s) Line 1121  static void process_data_pdu(STREAM s)
1121                          process_update_pdu(s);                          process_update_pdu(s);
1122                          break;                          break;
1123    
1124                    case RDP_DATA_PDU_CONTROL:
1125                            DEBUG(("Received Control PDU\n"));
1126                            break;
1127    
1128                    case RDP_DATA_PDU_SYNCHRONISE:
1129                            DEBUG(("Received Sync PDU\n"));
1130                            break;
1131    
1132                  case RDP_DATA_PDU_POINTER:                  case RDP_DATA_PDU_POINTER:
1133                          process_pointer_pdu(s);                          process_pointer_pdu(s);
1134                          break;                          break;
# Line 591  static void process_data_pdu(STREAM s) Line 1138  static void process_data_pdu(STREAM s)
1138                          break;                          break;
1139    
1140                  case RDP_DATA_PDU_LOGON:                  case RDP_DATA_PDU_LOGON:
1141                            DEBUG(("Received Logon PDU\n"));
1142                          /* User logged on */                          /* User logged on */
1143                          break;                          break;
1144    
1145                    case RDP_DATA_PDU_DISCONNECT:
1146                            process_disconnect_pdu(s, ext_disc_reason);
1147                            return True;
1148    
1149                  default:                  default:
1150                          NOTIMP("data PDU %d\n", data_pdu_type);                          unimpl("data PDU %d\n", data_pdu_type);
1151          }          }
1152            return False;
1153  }  }
1154    
1155  /* Process incoming packets */  /* Process incoming packets */
1156  void rdp_main_loop()  /* nevers gets out of here till app is done */
1157    void
1158    rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1159    {
1160            while (rdp_loop(deactivated, ext_disc_reason))
1161                    ;
1162    }
1163    
1164    /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1165    BOOL
1166    rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1167  {  {
1168          uint8 type;          uint8 type;
1169            BOOL disc = False;      /* True when a disconnect PDU was received */
1170            BOOL cont = True;
1171          STREAM s;          STREAM s;
1172    
1173          while ((s = rdp_recv(&type)) != NULL)          while (cont)
1174          {          {
1175                    s = rdp_recv(&type);
1176                    if (s == NULL)
1177                            return False;
1178                  switch (type)                  switch (type)
1179                  {                  {
1180                          case RDP_PDU_DEMAND_ACTIVE:                          case RDP_PDU_DEMAND_ACTIVE:
1181                                  process_demand_active(s);                                  process_demand_active(s);
1182                                    *deactivated = False;
1183                                  break;                                  break;
   
1184                          case RDP_PDU_DEACTIVATE:                          case RDP_PDU_DEACTIVATE:
1185                                    DEBUG(("RDP_PDU_DEACTIVATE\n"));
1186                                    *deactivated = True;
1187                                  break;                                  break;
   
1188                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1189                                  process_data_pdu(s);                                  disc = process_data_pdu(s, ext_disc_reason);
1190                                    break;
1191                            case 0:
1192                                  break;                                  break;
   
1193                          default:                          default:
1194                                  NOTIMP("PDU %d\n", type);                                  unimpl("PDU %d\n", type);
1195                  }                  }
1196                    if (disc)
1197                            return False;
1198                    cont = g_next_packet < s->end;
1199          }          }
1200            return True;
1201  }  }
1202    
1203  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */
1204  BOOL rdp_connect(char *server)  BOOL
1205    rdp_connect(char *server, uint32 flags, char *domain, char *password,
1206                char *command, char *directory)
1207  {  {
1208          if (!sec_connect(server))          if (!sec_connect(server, g_username))
1209                  return False;                  return False;
1210    
1211          rdp_send_logon_info(0x33, "", username, "", "", "");          rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1212          return True;          return True;
1213  }  }
1214    
1215  /* Disconnect from the RDP layer */  /* Disconnect from the RDP layer */
1216  void rdp_disconnect()  void
1217    rdp_disconnect(void)
1218  {  {
1219          sec_disconnect();          sec_disconnect();
1220  }  }
   

Legend:
Removed from v.10  
changed lines
  Added in v.831

  ViewVC Help
Powered by ViewVC 1.1.26