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

Legend:
Removed from v.21  
changed lines
  Added in v.730

  ViewVC Help
Powered by ViewVC 1.1.26