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

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

  ViewVC Help
Powered by ViewVC 1.1.26