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

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

  ViewVC Help
Powered by ViewVC 1.1.26