/[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 207 by matthewc, Thu Sep 26 14:26:46 2002 UTC revision 858 by stargo, Sun Mar 13 13:58:23 2005 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Protocol services - RDP layer     Protocol services - RDP layer
4     Copyright (C) Matthew Chapman 1999-2002     Copyright (C) Matthew Chapman 1999-2005
5      
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.     GNU General Public License for more details.
15      
16     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
21    #include <time.h>
22    #include <errno.h>
23    #include <unistd.h>
24  #include "rdesktop.h"  #include "rdesktop.h"
25    
26  extern uint16 mcs_userid;  #ifdef HAVE_ICONV
27  extern char username[16];  #ifdef HAVE_ICONV_H
28  extern BOOL bitmap_compression;  #include <iconv.h>
29  extern BOOL orders;  #endif
30  extern BOOL encryption;  
31  extern BOOL desktop_save;  #ifndef ICONV_CONST
32    #define ICONV_CONST ""
33  uint8 *next_packet;  #endif
34  uint32 rdp_shareid;  #endif
35    
36  /* Initialise an RDP packet */  extern uint16 g_mcs_userid;
37  static STREAM  extern char g_username[64];
38  rdp_init(int maxlen)  extern char g_codepage[16];
39  {  extern BOOL g_bitmap_compression;
40          STREAM s;  extern BOOL g_orders;
41    extern BOOL g_encryption;
42          s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 6);  extern BOOL g_desktop_save;
43          s_push_layer(s, rdp_hdr, 6);  extern BOOL g_polygon_ellipse_orders;
44    extern BOOL g_use_rdp5;
45    extern uint16 g_server_rdp_version;
46    extern uint32 g_rdp5_performanceflags;
47    extern int g_server_bpp;
48    extern int g_width;
49    extern int g_height;
50    extern BOOL g_bitmap_cache;
51    extern BOOL g_bitmap_cache_persist_enable;
52    
53          return s;  uint8 *g_next_packet;
54  }  uint32 g_rdp_shareid;
55    
56  /* Send an RDP packet */  extern RDPCOMP g_mppc_dict;
 static void  
 rdp_send(STREAM s, uint8 pdu_type)  
 {  
         uint16 length;  
57    
58          s_pop_layer(s, rdp_hdr);  #if WITH_DEBUG
59          length = s->end - s->p;  static uint32 g_packetno;
60    #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, encryption ? SEC_ENCRYPT : 0);  
 }  
61    
62  /* Receive an RDP packet */  /* Receive an RDP packet */
63  static STREAM  static STREAM
# Line 64  rdp_recv(uint8 * type) Line 65  rdp_recv(uint8 * type)
65  {  {
66          static STREAM rdp_s;          static STREAM rdp_s;
67          uint16 length, pdu_type;          uint16 length, pdu_type;
68            uint8 rdpver;
69    
70          if ((rdp_s == NULL) || (next_packet >= rdp_s->end))          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))
71          {          {
72                  rdp_s = sec_recv();                  rdp_s = sec_recv(&rdpver);
73                  if (rdp_s == NULL)                  if (rdp_s == NULL)
74                          return NULL;                          return NULL;
75                    if (rdpver == 0xff)
76                    {
77                            g_next_packet = rdp_s->end;
78                            *type = 0;
79                            return rdp_s;
80                    }
81                    else if (rdpver != 3)
82                    {
83                            /* rdp5_process should move g_next_packet ok */
84                            rdp5_process(rdp_s);
85                            *type = 0;
86                            return rdp_s;
87                    }
88    
89                  next_packet = rdp_s->p;                  g_next_packet = rdp_s->p;
90          }          }
91          else          else
92          {          {
93                  rdp_s->p = next_packet;                  rdp_s->p = g_next_packet;
94          }          }
95    
96          in_uint16_le(rdp_s, length);          in_uint16_le(rdp_s, length);
97            /* 32k packets are really 8, keepalive fix */
98            if (length == 0x8000)
99            {
100                    g_next_packet += 8;
101                    *type = 0;
102                    return rdp_s;
103            }
104          in_uint16_le(rdp_s, pdu_type);          in_uint16_le(rdp_s, pdu_type);
105          in_uint8s(rdp_s, 2);    /* userid */          in_uint8s(rdp_s, 2);    /* userid */
106          *type = pdu_type & 0xf;          *type = pdu_type & 0xf;
107    
108  #if WITH_DEBUG  #if WITH_DEBUG
109          DEBUG(("RDP packet (type %x):\n", *type));          DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type));
110          hexdump(next_packet, length);          hexdump(g_next_packet, length);
111  #endif /*  */  #endif /*  */
112    
113          next_packet += length;          g_next_packet += length;
114          return rdp_s;          return rdp_s;
115  }  }
116    
# Line 98  rdp_init_data(int maxlen) Line 120  rdp_init_data(int maxlen)
120  {  {
121          STREAM s;          STREAM s;
122    
123          s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 18);          s = sec_init(g_encryption ? SEC_ENCRYPT : 0, maxlen + 18);
124          s_push_layer(s, rdp_hdr, 18);          s_push_layer(s, rdp_hdr, 18);
125    
126          return s;          return s;
# Line 115  rdp_send_data(STREAM s, uint8 data_pdu_t Line 137  rdp_send_data(STREAM s, uint8 data_pdu_t
137    
138          out_uint16_le(s, length);          out_uint16_le(s, length);
139          out_uint16_le(s, (RDP_PDU_DATA | 0x10));          out_uint16_le(s, (RDP_PDU_DATA | 0x10));
140          out_uint16_le(s, (mcs_userid + 1001));          out_uint16_le(s, (g_mcs_userid + 1001));
141    
142          out_uint32_le(s, rdp_shareid);          out_uint32_le(s, g_rdp_shareid);
143          out_uint8(s, 0);        /* pad */          out_uint8(s, 0);        /* pad */
144          out_uint8(s, 1);        /* streamid */          out_uint8(s, 1);        /* streamid */
145          out_uint16_le(s, (length - 14));          out_uint16_le(s, (length - 14));
# Line 125  rdp_send_data(STREAM s, uint8 data_pdu_t Line 147  rdp_send_data(STREAM s, uint8 data_pdu_t
147          out_uint8(s, 0);        /* compress_type */          out_uint8(s, 0);        /* compress_type */
148          out_uint16(s, 0);       /* compress_len */          out_uint16(s, 0);       /* compress_len */
149    
150          sec_send(s, encryption ? SEC_ENCRYPT : 0);          sec_send(s, g_encryption ? SEC_ENCRYPT : 0);
151  }  }
152    
153  /* Output a string in Unicode */  /* Output a string in Unicode */
154  void  void
155  rdp_out_unistr(STREAM s, char *string, int len)  rdp_out_unistr(STREAM s, char *string, int len)
156  {  {
157    #ifdef HAVE_ICONV
158            size_t ibl = strlen(string), obl = len + 2;
159            static iconv_t iconv_h = (iconv_t)-1;
160            char   *pin = string, *pout;
161    #ifdef B_ENDIAN
162            char ss[4096];  // FIXME: global MAX_BUF_SIZE macro need
163    
164            pout = ss;
165    #else
166            pout = s->p;
167    #endif
168    
169            memset(pout, 0, len + 4);
170    
171            if (iconv_h == (iconv_t)-1)
172            {
173                    size_t i = 1, o = 4;
174                    if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t)-1)
175                    {
176                            printf("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n",
177                                    g_codepage, WINDOWS_CODEPAGE, (int)iconv_h);
178                            return;
179                    }
180                    if (iconv(iconv_h, (ICONV_CONST char**)&pin, &i, &pout, &o) == (size_t)-1)
181                    {
182                            iconv_close(iconv_h);
183                            iconv_h = (iconv_t)-1;
184                            printf("rdp_out_unistr: iconv(1) fail, errno %d\n", errno);
185                            return;
186                    }
187                    pin = string; pout = s->p;
188            }
189    
190            if (iconv(iconv_h, (ICONV_CONST char**)&pin, &ibl, &pout, &obl) == (size_t)-1)
191            {
192                    iconv_close(iconv_h);
193                    iconv_h = (iconv_t)-1;
194                    printf("rdp_out_unistr: iconv(2) fail, errno %d\n", errno);
195                    return;
196            }
197    
198    #ifdef B_ENDIAN
199            swab(ss, s->p, len + 4);
200    #endif
201    
202            s->p += len + 2;
203    
204    #else /*HAVE_ICONV undef*/
205          int i = 0, j = 0;          int i = 0, j = 0;
206    
207          len += 2;          len += 2;
# Line 141  rdp_out_unistr(STREAM s, char *string, i Line 211  rdp_out_unistr(STREAM s, char *string, i
211                  s->p[i++] = string[j++];                  s->p[i++] = string[j++];
212                  s->p[i++] = 0;                  s->p[i++] = 0;
213          }          }
214            
215          s->p += len;          s->p += len;
216    #endif
217    }
218    
219    /* Input a string in Unicode
220     *
221     * Returns str_len of string
222     */
223    int
224    rdp_in_unistr(STREAM s, char *string, int uni_len)
225    {
226    #ifdef HAVE_ICONV
227            size_t ibl = uni_len, obl = uni_len;
228            char *pin, *pout = string;
229            static iconv_t iconv_h = (iconv_t)-1;
230    #ifdef B_ENDIAN
231            char ss[4096];  // FIXME: global MAX_BUF_SIZE macro need
232    
233            swab(s->p, ss, uni_len);
234            pin = ss;
235    #else
236            pin = s->p;
237    #endif
238    
239            if (iconv_h == (iconv_t)-1)
240            {
241                    if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t)-1)
242                    {
243                            printf("rdp_in_unistr: iconv_open[%s -> %s] fail %d\n",
244                                    WINDOWS_CODEPAGE, g_codepage, (int)iconv_h);
245                            return 0;
246                    }
247            }
248    
249            if (iconv(iconv_h, (ICONV_CONST char**)&pin, &ibl, &pout, &obl) == (size_t)-1)
250            {
251                    iconv_close(iconv_h);
252                    iconv_h = (iconv_t)-1;
253                    printf("rdp_in_unistr: iconv fail, errno %d\n", errno);
254                    return 0;
255            }
256            return pout - string;
257    #else /* HAVE_ICONV undef */
258            int i = 0;
259    
260            while (i < uni_len / 2)
261            {
262                    in_uint8a(s, &string[i++], 1);
263                    in_uint8s(s, 1);
264            }
265    
266            return i - 1;
267    #endif
268  }  }
269    
270    
271  /* Parse a logon info packet */  /* Parse a logon info packet */
272  static void  static void
273  rdp_send_logon_info(uint32 flags, char *domain, char *user,  rdp_send_logon_info(uint32 flags, char *domain, char *user,
274                      char *password, char *program, char *directory)                      char *password, char *program, char *directory)
275  {  {
276            char *ipaddr = tcp_get_address();
277          int len_domain = 2 * strlen(domain);          int len_domain = 2 * strlen(domain);
278          int len_user = 2 * strlen(user);          int len_user = 2 * strlen(user);
279          int len_password = 2 * strlen(password);          int len_password = 2 * strlen(password);
280          int len_program = 2 * strlen(program);          int len_program = 2 * strlen(program);
281          int len_directory = 2 * strlen(directory);          int len_directory = 2 * strlen(directory);
282          uint32 sec_flags = encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;          int len_ip = 2 * strlen(ipaddr);
283            int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
284            int packetlen = 0;
285            uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
286          STREAM s;          STREAM s;
287            time_t t = time(NULL);
288            time_t tzone;
289    
290    #if 0
291            /* enable rdp compression */
292            /* some problems still exist with rdp5 */
293            flags |= RDP_COMPRESSION;
294    #endif
295    
296            if (!g_use_rdp5 || 1 == g_server_rdp_version)
297            {
298                    DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
299    
300                    s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
301                                 + len_program + len_directory + 10);
302    
303          s = sec_init(sec_flags, 18 + len_domain + len_user + len_password                  out_uint32(s, 0);
304                       + len_program + len_directory + 10);                  out_uint32_le(s, flags);
305                    out_uint16_le(s, len_domain);
306                    out_uint16_le(s, len_user);
307                    out_uint16_le(s, len_password);
308                    out_uint16_le(s, len_program);
309                    out_uint16_le(s, len_directory);
310                    rdp_out_unistr(s, domain, len_domain);
311                    rdp_out_unistr(s, user, len_user);
312                    rdp_out_unistr(s, password, len_password);
313                    rdp_out_unistr(s, program, len_program);
314                    rdp_out_unistr(s, directory, len_directory);
315            }
316            else
317            {
318    
319                    flags |= RDP_LOGON_BLOB;
320                    DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
321                    packetlen = 4 + /* Unknown uint32 */
322                            4 +     /* flags */
323                            2 +     /* len_domain */
324                            2 +     /* len_user */
325                            (flags & RDP_LOGON_AUTO ? 2 : 0) +      /* len_password */
326                            (flags & RDP_LOGON_BLOB ? 2 : 0) +      /* Length of BLOB */
327                            2 +     /* len_program */
328                            2 +     /* len_directory */
329                            (0 < len_domain ? len_domain : 2) +     /* domain */
330                            len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 +    /* We have no 512 byte BLOB. Perhaps we must? */
331                            (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + /* After the BLOB is a unknown int16. If there is a BLOB, that is. */
332                            (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 +     /* Unknown (2) */
333                            2 +     /* Client ip length */
334                            len_ip +        /* Client ip */
335                            2 +     /* DLL string length */
336                            len_dll +       /* DLL string */
337                            2 +     /* Unknown */
338                            2 +     /* Unknown */
339                            64 +    /* Time zone #0 */
340                            2 +     /* Unknown */
341                            64 +    /* Time zone #1 */
342                            32;     /* Unknown */
343    
344                    s = sec_init(sec_flags, packetlen);
345                    DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
346    
347                    out_uint32(s, 0);       /* Unknown */
348                    out_uint32_le(s, flags);
349                    out_uint16_le(s, len_domain);
350                    out_uint16_le(s, len_user);
351                    if (flags & RDP_LOGON_AUTO)
352                    {
353                            out_uint16_le(s, len_password);
354    
355          out_uint32(s, 0);                  }
356          out_uint32_le(s, flags);                  if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
357          out_uint16_le(s, len_domain);                  {
358          out_uint16_le(s, len_user);                          out_uint16_le(s, 0);
359          out_uint16_le(s, len_password);                  }
360          out_uint16_le(s, len_program);                  out_uint16_le(s, len_program);
361          out_uint16_le(s, len_directory);                  out_uint16_le(s, len_directory);
362          rdp_out_unistr(s, domain, len_domain);                  if (0 < len_domain)
363          rdp_out_unistr(s, user, len_user);                          rdp_out_unistr(s, domain, len_domain);
364          rdp_out_unistr(s, password, len_password);                  else
365          rdp_out_unistr(s, program, len_program);                          out_uint16_le(s, 0);
366          rdp_out_unistr(s, directory, len_directory);                  rdp_out_unistr(s, user, len_user);
367                    if (flags & RDP_LOGON_AUTO)
368                    {
369                            rdp_out_unistr(s, password, len_password);
370                    }
371                    if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
372                    {
373                            out_uint16_le(s, 0);
374                    }
375                    if (0 < len_program)
376                    {
377                            rdp_out_unistr(s, program, len_program);
378    
379                    }
380                    else
381                    {
382                            out_uint16_le(s, 0);
383                    }
384                    if (0 < len_directory)
385                    {
386                            rdp_out_unistr(s, directory, len_directory);
387                    }
388                    else
389                    {
390                            out_uint16_le(s, 0);
391                    }
392                    out_uint16_le(s, 2);
393                    out_uint16_le(s, len_ip + 2);   /* Length of client ip */
394                    rdp_out_unistr(s, ipaddr, len_ip);
395                    out_uint16_le(s, len_dll + 2);
396                    rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
397    
398                    tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
399                    out_uint32_le(s, tzone);
400    
401                    rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
402                    out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
403    
404                    out_uint32_le(s, 0x0a0000);
405                    out_uint32_le(s, 0x050000);
406                    out_uint32_le(s, 3);
407                    out_uint32_le(s, 0);
408                    out_uint32_le(s, 0);
409    
410                    rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
411                    out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
412    
413                    out_uint32_le(s, 0x30000);
414                    out_uint32_le(s, 0x050000);
415                    out_uint32_le(s, 2);
416                    out_uint32(s, 0);
417                    out_uint32_le(s, 0xffffffc4);
418                    out_uint32_le(s, 0xfffffffe);
419                    out_uint32_le(s, g_rdp5_performanceflags);
420                    out_uint32(s, 0);
421    
422    
423            }
424          s_mark_end(s);          s_mark_end(s);
425          sec_send(s, sec_flags);          sec_send(s, sec_flags);
426  }  }
# Line 230  rdp_send_input(uint32 time, uint16 messa Line 477  rdp_send_input(uint32 time, uint16 messa
477          rdp_send_data(s, RDP_DATA_PDU_INPUT);          rdp_send_data(s, RDP_DATA_PDU_INPUT);
478  }  }
479    
480    /* Inform the server on the contents of the persistent bitmap cache */
481    static void
482    rdp_enum_bmpcache2(void)
483    {
484            STREAM s;
485            HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS];
486            uint32 num_keys, offset, count, flags;
487    
488            offset = 0;
489            num_keys = pstcache_enumerate(2, keylist);
490    
491            while (offset < num_keys)
492            {
493                    count = MIN(num_keys - offset, 169);
494    
495                    s = rdp_init_data(24 + count * sizeof(HASH_KEY));
496    
497                    flags = 0;
498                    if (offset == 0)
499                            flags |= PDU_FLAG_FIRST;
500                    if (num_keys - offset <= 169)
501                            flags |= PDU_FLAG_LAST;
502    
503                    /* header */
504                    out_uint32_le(s, 0);
505                    out_uint16_le(s, count);
506                    out_uint16_le(s, 0);
507                    out_uint16_le(s, 0);
508                    out_uint16_le(s, 0);
509                    out_uint16_le(s, 0);
510                    out_uint16_le(s, num_keys);
511                    out_uint32_le(s, 0);
512                    out_uint32_le(s, flags);
513    
514                    /* list */
515                    out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
516    
517                    s_mark_end(s);
518                    rdp_send_data(s, 0x2b);
519    
520                    offset += 169;
521            }
522    }
523    
524  /* Send an (empty) font information PDU */  /* Send an (empty) font information PDU */
525  static void  static void
526  rdp_send_fonts(uint16 seq)  rdp_send_fonts(uint16 seq)
# Line 239  rdp_send_fonts(uint16 seq) Line 530  rdp_send_fonts(uint16 seq)
530          s = rdp_init_data(8);          s = rdp_init_data(8);
531    
532          out_uint16(s, 0);       /* number of fonts */          out_uint16(s, 0);       /* number of fonts */
533          out_uint16_le(s, 0x3e); /* unknown */          out_uint16_le(s, 0);    /* pad? */
534          out_uint16_le(s, seq);  /* unknown */          out_uint16_le(s, seq);  /* unknown */
535          out_uint16_le(s, 0x32); /* entry size */          out_uint16_le(s, 0x32); /* entry size */
536    
# Line 259  rdp_out_general_caps(STREAM s) Line 550  rdp_out_general_caps(STREAM s)
550          out_uint16_le(s, 0x200);        /* Protocol version */          out_uint16_le(s, 0x200);        /* Protocol version */
551          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
552          out_uint16(s, 0);       /* Compression types */          out_uint16(s, 0);       /* Compression types */
553          out_uint16(s, 0);       /* Pad */          out_uint16_le(s, g_use_rdp5 ? 0x40d : 0);
554            /* Pad, according to T.128. 0x40d seems to
555               trigger
556               the server to start sending RDP5 packets.
557               However, the value is 0x1d04 with W2KTSK and
558               NT4MS. Hmm.. Anyway, thankyou, Microsoft,
559               for sending such information in a padding
560               field.. */
561          out_uint16(s, 0);       /* Update capability */          out_uint16(s, 0);       /* Update capability */
562          out_uint16(s, 0);       /* Remote unshare capability */          out_uint16(s, 0);       /* Remote unshare capability */
563          out_uint16(s, 0);       /* Compression level */          out_uint16(s, 0);       /* Compression level */
# Line 273  rdp_out_bitmap_caps(STREAM s) Line 571  rdp_out_bitmap_caps(STREAM s)
571          out_uint16_le(s, RDP_CAPSET_BITMAP);          out_uint16_le(s, RDP_CAPSET_BITMAP);
572          out_uint16_le(s, RDP_CAPLEN_BITMAP);          out_uint16_le(s, RDP_CAPLEN_BITMAP);
573    
574          out_uint16_le(s, 8);    /* Preferred BPP */          out_uint16_le(s, g_server_bpp); /* Preferred BPP */
575          out_uint16_le(s, 1);    /* Receive 1 BPP */          out_uint16_le(s, 1);    /* Receive 1 BPP */
576          out_uint16_le(s, 1);    /* Receive 4 BPP */          out_uint16_le(s, 1);    /* Receive 4 BPP */
577          out_uint16_le(s, 1);    /* Receive 8 BPP */          out_uint16_le(s, 1);    /* Receive 8 BPP */
578          out_uint16_le(s, 800);  /* Desktop width */          out_uint16_le(s, 800);  /* Desktop width */
579          out_uint16_le(s, 600);  /* Desktop height */          out_uint16_le(s, 600);  /* Desktop height */
580          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
581          out_uint16(s, 0);       /* Allow resize */          out_uint16(s, 1);       /* Allow resize */
582          out_uint16_le(s, bitmap_compression ? 1 : 0);   /* Support compression */          out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
583          out_uint16(s, 0);       /* Unknown */          out_uint16(s, 0);       /* Unknown */
584          out_uint16_le(s, 1);    /* Unknown */          out_uint16_le(s, 1);    /* Unknown */
585          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
# Line 293  rdp_out_order_caps(STREAM s) Line 591  rdp_out_order_caps(STREAM s)
591  {  {
592          uint8 order_caps[32];          uint8 order_caps[32];
593    
   
594          memset(order_caps, 0, 32);          memset(order_caps, 0, 32);
595          order_caps[0] = 1;      /* dest blt */          order_caps[0] = 1;      /* dest blt */
596          order_caps[1] = 1;      /* pat blt */          order_caps[1] = 1;      /* pat blt */
597          order_caps[2] = 1;      /* screen blt */          order_caps[2] = 1;      /* screen blt */
598          order_caps[3] = 1;      /* required for memblt? */          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
599            order_caps[4] = 0;      /* triblt */
600          order_caps[8] = 1;      /* line */          order_caps[8] = 1;      /* line */
601          order_caps[9] = 1;      /* line */          order_caps[9] = 1;      /* line */
602          order_caps[10] = 1;     /* rect */          order_caps[10] = 1;     /* rect */
603          order_caps[11] = (desktop_save == False ? 0 : 1);       /* desksave */          order_caps[11] = (g_desktop_save ? 1 : 0);      /* desksave */
604          order_caps[13] = 1;     /* memblt */          order_caps[13] = 1;     /* memblt */
605          order_caps[14] = 1;     /* triblt */          order_caps[14] = 1;     /* triblt */
606            order_caps[20] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon */
607            order_caps[21] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon2 */
608          order_caps[22] = 1;     /* polyline */          order_caps[22] = 1;     /* polyline */
609            order_caps[25] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse */
610            order_caps[26] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse2 */
611          order_caps[27] = 1;     /* text2 */          order_caps[27] = 1;     /* text2 */
612          out_uint16_le(s, RDP_CAPSET_ORDER);          out_uint16_le(s, RDP_CAPSET_ORDER);
613          out_uint16_le(s, RDP_CAPLEN_ORDER);          out_uint16_le(s, RDP_CAPLEN_ORDER);
# Line 320  rdp_out_order_caps(STREAM s) Line 622  rdp_out_order_caps(STREAM s)
622          out_uint8p(s, order_caps, 32);  /* Orders supported */          out_uint8p(s, order_caps, 32);  /* Orders supported */
623          out_uint16_le(s, 0x6a1);        /* Text capability flags */          out_uint16_le(s, 0x6a1);        /* Text capability flags */
624          out_uint8s(s, 6);       /* Pad */          out_uint8s(s, 6);       /* Pad */
625          out_uint32_le(s, desktop_save == False ? 0 : 0x38400);  /* Desktop cache size */          out_uint32_le(s, g_desktop_save == False ? 0 : 0x38400);        /* Desktop cache size */
626          out_uint32(s, 0);       /* Unknown */          out_uint32(s, 0);       /* Unknown */
627          out_uint32_le(s, 0x4e4);        /* Unknown */          out_uint32_le(s, 0x4e4);        /* Unknown */
628  }  }
# Line 329  rdp_out_order_caps(STREAM s) Line 631  rdp_out_order_caps(STREAM s)
631  static void  static void
632  rdp_out_bmpcache_caps(STREAM s)  rdp_out_bmpcache_caps(STREAM s)
633  {  {
634            int Bpp;
635          out_uint16_le(s, RDP_CAPSET_BMPCACHE);          out_uint16_le(s, RDP_CAPSET_BMPCACHE);
636          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
637    
638            Bpp = (g_server_bpp + 7) / 8;
639          out_uint8s(s, 24);      /* unused */          out_uint8s(s, 24);      /* unused */
640          out_uint16_le(s, 0x258);        /* entries */          out_uint16_le(s, 0x258);        /* entries */
641          out_uint16_le(s, 0x100);        /* max cell size */          out_uint16_le(s, 0x100 * Bpp);  /* max cell size */
642          out_uint16_le(s, 0x12c);        /* entries */          out_uint16_le(s, 0x12c);        /* entries */
643          out_uint16_le(s, 0x400);        /* max cell size */          out_uint16_le(s, 0x400 * Bpp);  /* max cell size */
644          out_uint16_le(s, 0x106);        /* entries */          out_uint16_le(s, 0x106);        /* entries */
645          out_uint16_le(s, 0x1000);       /* max cell size */          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
646    }
647    
648    /* Output bitmap cache v2 capability set */
649    static void
650    rdp_out_bmpcache2_caps(STREAM s)
651    {
652            out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
653            out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
654    
655            out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
656    
657            out_uint16_le(s, 0x0300);       /* flags? number of caches? */
658    
659            out_uint32_le(s, BMPCACHE2_C0_CELLS);
660            out_uint32_le(s, BMPCACHE2_C1_CELLS);
661            if (pstcache_init(2))
662            {
663                    out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
664            }
665            else
666            {
667                    out_uint32_le(s, BMPCACHE2_C2_CELLS);
668            }
669            out_uint8s(s, 20);      /* other bitmap caches not used */
670  }  }
671    
672  /* Output control capability set */  /* Output control capability set */
# Line 400  rdp_out_colcache_caps(STREAM s) Line 728  rdp_out_colcache_caps(STREAM s)
728          out_uint16(s, 0);       /* pad */          out_uint16(s, 0);       /* pad */
729  }  }
730    
731  static uint8 canned_caps[] = {  static uint8 caps_0x0d[] = {
732          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
733          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
734          0x00, 0x00, 0x00, 0x00, 0x00,          0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
735          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
736          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
737          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
738          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
739          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
740          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
741          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
742          0x0C, 0x00, 0x08, 0x00, 0x01,          0x00, 0x00, 0x00, 0x00
         0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,  
         0x10, 0x00, 0x34, 0x00, 0xFE,  
         0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,  
         0xFE, 0x00, 0x08, 0x00, 0xFE,  
         0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,  
         0xFE, 0x00, 0x80, 0x00, 0xFE,  
         0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,  
         0x02, 0x00, 0x00, 0x00  
743  };  };
744    
745  /* Output unknown capability set */  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
746    
747    static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
748    
749    static uint8 caps_0x10[] = {
750            0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
751            0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
752            0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
753            0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
754            0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
755            0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
756    };
757    
758    /* Output unknown capability sets */
759  static void  static void
760  rdp_out_unknown_caps(STREAM s)  rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
761  {  {
762          out_uint16_le(s, RDP_CAPSET_UNKNOWN);          out_uint16_le(s, id);
763          out_uint16_le(s, 0x58);          out_uint16_le(s, length);
764    
765          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);          out_uint8p(s, caps, length - 4);
766  }  }
767    
768    #define RDP5_FLAG 0x0030
769  /* Send a confirm active PDU */  /* Send a confirm active PDU */
770  static void  static void
771  rdp_send_confirm_active(void)  rdp_send_confirm_active(void)
772  {  {
773          STREAM s;          STREAM s;
774            uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
775          uint16 caplen =          uint16 caplen =
776                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
777                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
778                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
779                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
780                    0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
781                    4 /* w2k fix, why? */ ;
782    
783          s = rdp_init(14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
784    
785          out_uint32_le(s, rdp_shareid);          out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
786            out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10));      /* Version 1 */
787            out_uint16_le(s, (g_mcs_userid + 1001));
788    
789            out_uint32_le(s, g_rdp_shareid);
790          out_uint16_le(s, 0x3ea);        /* userid */          out_uint16_le(s, 0x3ea);        /* userid */
791          out_uint16_le(s, sizeof(RDP_SOURCE));          out_uint16_le(s, sizeof(RDP_SOURCE));
792          out_uint16_le(s, caplen);          out_uint16_le(s, caplen);
# Line 457  rdp_send_confirm_active(void) Line 798  rdp_send_confirm_active(void)
798          rdp_out_general_caps(s);          rdp_out_general_caps(s);
799          rdp_out_bitmap_caps(s);          rdp_out_bitmap_caps(s);
800          rdp_out_order_caps(s);          rdp_out_order_caps(s);
801          rdp_out_bmpcache_caps(s);          g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
802          rdp_out_colcache_caps(s);          rdp_out_colcache_caps(s);
803          rdp_out_activate_caps(s);          rdp_out_activate_caps(s);
804          rdp_out_control_caps(s);          rdp_out_control_caps(s);
805          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
806          rdp_out_share_caps(s);          rdp_out_share_caps(s);
807          rdp_out_unknown_caps(s);  
808            rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
809            rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
810            rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
811            rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
812    
813          s_mark_end(s);          s_mark_end(s);
814          rdp_send(s, RDP_PDU_CONFIRM_ACTIVE);          sec_send(s, sec_flags);
815    }
816    
817    /* Process a general capability set */
818    static void
819    rdp_process_general_caps(STREAM s)
820    {
821            uint16 pad2octetsB;     /* rdp5 flags? */
822    
823            in_uint8s(s, 10);
824            in_uint16_le(s, pad2octetsB);
825    
826            if (!pad2octetsB)
827                    g_use_rdp5 = False;
828    }
829    
830    /* Process a bitmap capability set */
831    static void
832    rdp_process_bitmap_caps(STREAM s)
833    {
834            uint16 width, height, bpp;
835    
836            in_uint16_le(s, bpp);
837            in_uint8s(s, 6);
838    
839            in_uint16_le(s, width);
840            in_uint16_le(s, height);
841    
842            DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));
843    
844            /*
845             * The server may limit bpp and change the size of the desktop (for
846             * example when shadowing another session).
847             */
848            if (g_server_bpp != bpp)
849            {
850                    warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
851                    g_server_bpp = bpp;
852            }
853            if (g_width != width || g_height != height)
854            {
855                    warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
856                            width, height);
857                    g_width = width;
858                    g_height = height;
859                    ui_resize_window();
860            }
861    }
862    
863    /* Process server capabilities */
864    void
865    rdp_process_server_caps(STREAM s, uint16 length)
866    {
867            int n;
868            uint8 *next, *start;
869            uint16 ncapsets, capset_type, capset_length;
870    
871            start = s->p;
872    
873            in_uint16_le(s, ncapsets);
874            in_uint8s(s, 2);        /* pad */
875    
876            for (n = 0; n < ncapsets; n++)
877            {
878                    if (s->p > start + length)
879                            return;
880    
881                    in_uint16_le(s, capset_type);
882                    in_uint16_le(s, capset_length);
883    
884                    next = s->p + capset_length - 4;
885    
886                    switch (capset_type)
887                    {
888                            case RDP_CAPSET_GENERAL:
889                                    rdp_process_general_caps(s);
890                                    break;
891    
892                            case RDP_CAPSET_BITMAP:
893                                    rdp_process_bitmap_caps(s);
894                                    break;
895                    }
896    
897                    s->p = next;
898            }
899  }  }
900    
901  /* Respond to a demand active PDU */  /* Respond to a demand active PDU */
# Line 474  static void Line 903  static void
903  process_demand_active(STREAM s)  process_demand_active(STREAM s)
904  {  {
905          uint8 type;          uint8 type;
906            uint16 len_src_descriptor, len_combined_caps;
907    
908          in_uint32_le(s, rdp_shareid);          in_uint32_le(s, g_rdp_shareid);
909            in_uint16_le(s, len_src_descriptor);
910            in_uint16_le(s, len_combined_caps);
911            in_uint8s(s, len_src_descriptor);
912    
913          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", rdp_shareid));          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
914            rdp_process_server_caps(s, len_combined_caps);
915    
916          rdp_send_confirm_active();          rdp_send_confirm_active();
917          rdp_send_synchronise();          rdp_send_synchronise();
# Line 486  process_demand_active(STREAM s) Line 920  process_demand_active(STREAM s)
920          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
921          rdp_recv(&type);        /* RDP_CTL_COOPERATE */          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
922          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
923          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);
924          rdp_send_fonts(1);  
925          rdp_send_fonts(2);          if (g_use_rdp5)
926          rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 */          {
927                    rdp_enum_bmpcache2();
928                    rdp_send_fonts(3);
929            }
930            else
931            {
932                    rdp_send_fonts(1);
933                    rdp_send_fonts(2);
934            }
935    
936            rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
937          reset_order_state();          reset_order_state();
938  }  }
939    
940    /* Process a colour pointer PDU */
941    void
942    process_colour_pointer_pdu(STREAM s)
943    {
944            uint16 x, y, width, height, cache_idx, masklen, datalen;
945            uint8 *mask, *data;
946            HCURSOR cursor;
947    
948            in_uint16_le(s, cache_idx);
949            in_uint16_le(s, x);
950            in_uint16_le(s, y);
951            in_uint16_le(s, width);
952            in_uint16_le(s, height);
953            in_uint16_le(s, masklen);
954            in_uint16_le(s, datalen);
955            in_uint8p(s, data, datalen);
956            in_uint8p(s, mask, masklen);
957            cursor = ui_create_cursor(x, y, width, height, mask, data);
958            ui_set_cursor(cursor);
959            cache_put_cursor(cache_idx, cursor);
960    }
961    
962    /* Process a cached pointer PDU */
963    void
964    process_cached_pointer_pdu(STREAM s)
965    {
966            uint16 cache_idx;
967    
968            in_uint16_le(s, cache_idx);
969            ui_set_cursor(cache_get_cursor(cache_idx));
970    }
971    
972    /* Process a system pointer PDU */
973    void
974    process_system_pointer_pdu(STREAM s)
975    {
976            uint16 system_pointer_type;
977    
978            in_uint16(s, system_pointer_type);
979            switch (system_pointer_type)
980            {
981                    case RDP_NULL_POINTER:
982                            ui_set_null_cursor();
983                            break;
984    
985                    default:
986                            unimpl("System pointer message 0x%x\n", system_pointer_type);
987            }
988    }
989    
990  /* Process a pointer PDU */  /* Process a pointer PDU */
991  static void  static void
992  process_pointer_pdu(STREAM s)  process_pointer_pdu(STREAM s)
993  {  {
994          uint16 message_type;          uint16 message_type;
995          uint16 x, y, width, height, cache_idx, masklen, datalen;          uint16 x, y;
         uint8 *mask, *data;  
         HCURSOR cursor;  
996    
997          in_uint16_le(s, message_type);          in_uint16_le(s, message_type);
998          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
# Line 515  process_pointer_pdu(STREAM s) Line 1007  process_pointer_pdu(STREAM s)
1007                          break;                          break;
1008    
1009                  case RDP_POINTER_COLOR:                  case RDP_POINTER_COLOR:
1010                          in_uint16_le(s, cache_idx);                          process_colour_pointer_pdu(s);
                         in_uint16_le(s, x);  
                         in_uint16_le(s, y);  
                         in_uint16_le(s, width);  
                         in_uint16_le(s, height);  
                         in_uint16_le(s, masklen);  
                         in_uint16_le(s, datalen);  
                         in_uint8p(s, data, datalen);  
                         in_uint8p(s, mask, masklen);  
                         cursor = ui_create_cursor(x, y, width, height, mask, data);  
                         ui_set_cursor(cursor);  
                         cache_put_cursor(cache_idx, cursor);  
1011                          break;                          break;
1012    
1013                  case RDP_POINTER_CACHED:                  case RDP_POINTER_CACHED:
1014                          in_uint16_le(s, cache_idx);                          process_cached_pointer_pdu(s);
1015                          ui_set_cursor(cache_get_cursor(cache_idx));                          break;
1016    
1017                    case RDP_POINTER_SYSTEM:
1018                            process_system_pointer_pdu(s);
1019                          break;                          break;
1020    
1021                  default:                  default:
1022                          DEBUG(("Pointer message 0x%x\n", message_type));                          unimpl("Pointer message 0x%x\n", message_type);
1023          }          }
1024  }  }
1025    
1026  /* Process bitmap updates */  /* Process bitmap updates */
1027  static void  void
1028  process_bitmap_updates(STREAM s)  process_bitmap_updates(STREAM s)
1029  {  {
1030          uint16 num_updates;          uint16 num_updates;
1031          uint16 left, top, right, bottom, width, height;          uint16 left, top, right, bottom, width, height;
1032          uint16 cx, cy, bpp, compress, bufsize, size;          uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
1033          uint8 *data, *bmpdata;          uint8 *data, *bmpdata;
1034          int i;          int i;
1035    
# Line 560  process_bitmap_updates(STREAM s) Line 1044  process_bitmap_updates(STREAM s)
1044                  in_uint16_le(s, width);                  in_uint16_le(s, width);
1045                  in_uint16_le(s, height);                  in_uint16_le(s, height);
1046                  in_uint16_le(s, bpp);                  in_uint16_le(s, bpp);
1047                    Bpp = (bpp + 7) / 8;
1048                  in_uint16_le(s, compress);                  in_uint16_le(s, compress);
1049                  in_uint16_le(s, bufsize);                  in_uint16_le(s, bufsize);
1050    
1051                  cx = right - left + 1;                  cx = right - left + 1;
1052                  cy = bottom - top + 1;                  cy = bottom - top + 1;
1053    
1054                  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",
1055                         left, top, right, bottom, width, height, compress));                         left, top, right, bottom, width, height, Bpp, compress));
1056    
1057                  if (!compress)                  if (!compress)
1058                  {                  {
1059                          int y;                          int y;
1060                          bmpdata = xmalloc(width * height);                          bmpdata = (uint8 *) xmalloc(width * height * Bpp);
1061                          for (y = 0; y < height; y++)                          for (y = 0; y < height; y++)
1062                          {                          {
1063                                  in_uint8a(s, &bmpdata[(height - y - 1) * width], width);                                  in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
1064                                              width * Bpp);
1065                          }                          }
1066                          ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);                          ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
1067                          xfree(bmpdata);                          xfree(bmpdata);
1068                          continue;                          continue;
1069                  }                  }
1070    
                 in_uint8s(s, 2);        /* pad */  
                 in_uint16_le(s, size);  
                 in_uint8s(s, 4);        /* line_size, final_size */  
                 in_uint8p(s, data, size);  
1071    
1072                  bmpdata = xmalloc(width * height);                  if (compress & 0x400)
1073                  if (bitmap_decompress(bmpdata, width, height, data, size))                  {
1074                            size = bufsize;
1075                    }
1076                    else
1077                    {
1078                            in_uint8s(s, 2);        /* pad */
1079                            in_uint16_le(s, size);
1080                            in_uint8s(s, 4);        /* line_size, final_size */
1081                    }
1082                    in_uint8p(s, data, size);
1083                    bmpdata = (uint8 *) xmalloc(width * height * Bpp);
1084                    if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
1085                  {                  {
1086                          ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);                          ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
1087                  }                  }
1088                    else
1089                    {
1090                            DEBUG_RDP5(("Failed to decompress data\n"));
1091                    }
1092    
1093                  xfree(bmpdata);                  xfree(bmpdata);
1094          }          }
1095  }  }
1096    
1097  /* Process a palette update */  /* Process a palette update */
1098  static void  void
1099  process_palette(STREAM s)  process_palette(STREAM s)
1100  {  {
1101          HCOLOURMAP hmap;          COLOURENTRY *entry;
1102          COLOURMAP map;          COLOURMAP map;
1103          uint8 *colours;          HCOLOURMAP hmap;
1104            int i;
1105    
1106          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
1107          in_uint16_le(s, map.ncolours);          in_uint16_le(s, map.ncolours);
1108          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
1109          in_uint8p(s, colours, (map.ncolours * 3));  
1110          map.colours = (COLOURENTRY *) colours;          map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
1111    
1112            DEBUG(("PALETTE(c=%d)\n", map.ncolours));
1113    
1114            for (i = 0; i < map.ncolours; i++)
1115            {
1116                    entry = &map.colours[i];
1117                    in_uint8(s, entry->red);
1118                    in_uint8(s, entry->green);
1119                    in_uint8(s, entry->blue);
1120            }
1121    
1122          hmap = ui_create_colourmap(&map);          hmap = ui_create_colourmap(&map);
1123          ui_set_colourmap(hmap);          ui_set_colourmap(hmap);
1124    
1125            xfree(map.colours);
1126  }  }
1127    
1128  /* Process an update PDU */  /* Process an update PDU */
1129  static void  static void
1130  process_update_pdu(STREAM s)  process_update_pdu(STREAM s)
1131  {  {
1132          uint16 update_type;          uint16 update_type, count;
1133    
1134          in_uint16_le(s, update_type);          in_uint16_le(s, update_type);
1135    
1136            ui_begin_update();
1137          switch (update_type)          switch (update_type)
1138          {          {
1139                  case RDP_UPDATE_ORDERS:                  case RDP_UPDATE_ORDERS:
1140                          process_orders(s);                          in_uint8s(s, 2);        /* pad */
1141                            in_uint16_le(s, count);
1142                            in_uint8s(s, 2);        /* pad */
1143                            process_orders(s, count);
1144                          break;                          break;
1145    
1146                  case RDP_UPDATE_BITMAP:                  case RDP_UPDATE_BITMAP:
# Line 643  process_update_pdu(STREAM s) Line 1157  process_update_pdu(STREAM s)
1157                  default:                  default:
1158                          unimpl("update %d\n", update_type);                          unimpl("update %d\n", update_type);
1159          }          }
1160            ui_end_update();
1161    }
1162    
1163    /* Process a disconnect PDU */
1164    void
1165    process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
1166    {
1167            in_uint32_le(s, *ext_disc_reason);
1168    
1169            DEBUG(("Received disconnect PDU\n"));
1170  }  }
1171    
1172  /* Process data PDU */  /* Process data PDU */
1173  static void  static BOOL
1174  process_data_pdu(STREAM s)  process_data_pdu(STREAM s, uint32 * ext_disc_reason)
1175  {  {
1176          uint8 data_pdu_type;          uint8 data_pdu_type;
1177            uint8 ctype;
1178            uint16 clen;
1179            uint32 len;
1180    
1181            uint32 roff, rlen;
1182    
1183            struct stream *ns = &(g_mppc_dict.ns);
1184    
1185          in_uint8s(s, 8);        /* shareid, pad, streamid, length */          in_uint8s(s, 6);        /* shareid, pad, streamid */
1186            in_uint16(s, len);
1187          in_uint8(s, data_pdu_type);          in_uint8(s, data_pdu_type);
1188          in_uint8s(s, 3);        /* compress_type, compress_len */          in_uint8(s, ctype);
1189            in_uint16(s, clen);
1190            clen -= 18;
1191    
1192            if (ctype & RDP_MPPC_COMPRESSED)
1193            {
1194                    if (len > RDP_MPPC_DICT_SIZE)
1195                            error("error decompressed packet size exceeds max\n");
1196                    if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1197                            error("error while decompressing packet\n");
1198    
1199                    //len -= 18;
1200    
1201                    /* allocate memory and copy the uncompressed data into the temporary stream */
1202                    ns->data = (uint8 *) xrealloc(ns->data, rlen);
1203    
1204                    memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
1205    
1206                    ns->size = rlen;
1207                    ns->end = (ns->data + ns->size);
1208                    ns->p = ns->data;
1209                    ns->rdp_hdr = ns->p;
1210    
1211                    s = ns;
1212            }
1213    
1214          switch (data_pdu_type)          switch (data_pdu_type)
1215          {          {
# Line 662  process_data_pdu(STREAM s) Line 1217  process_data_pdu(STREAM s)
1217                          process_update_pdu(s);                          process_update_pdu(s);
1218                          break;                          break;
1219    
1220                    case RDP_DATA_PDU_CONTROL:
1221                            DEBUG(("Received Control PDU\n"));
1222                            break;
1223    
1224                    case RDP_DATA_PDU_SYNCHRONISE:
1225                            DEBUG(("Received Sync PDU\n"));
1226                            break;
1227    
1228                  case RDP_DATA_PDU_POINTER:                  case RDP_DATA_PDU_POINTER:
1229                          process_pointer_pdu(s);                          process_pointer_pdu(s);
1230                          break;                          break;
# Line 671  process_data_pdu(STREAM s) Line 1234  process_data_pdu(STREAM s)
1234                          break;                          break;
1235    
1236                  case RDP_DATA_PDU_LOGON:                  case RDP_DATA_PDU_LOGON:
1237                            DEBUG(("Received Logon PDU\n"));
1238                          /* User logged on */                          /* User logged on */
1239                          break;                          break;
1240    
1241                    case RDP_DATA_PDU_DISCONNECT:
1242                            process_disconnect_pdu(s, ext_disc_reason);
1243                            return True;
1244    
1245                  default:                  default:
1246                          unimpl("data PDU %d\n", data_pdu_type);                          unimpl("data PDU %d\n", data_pdu_type);
1247          }          }
1248            return False;
1249  }  }
1250    
1251  /* Process incoming packets */  /* Process incoming packets */
1252    /* nevers gets out of here till app is done */
1253  void  void
1254  rdp_main_loop(void)  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1255    {
1256            while (rdp_loop(deactivated, ext_disc_reason))
1257                    ;
1258    }
1259    
1260    /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1261    BOOL
1262    rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1263  {  {
1264          uint8 type;          uint8 type;
1265            BOOL disc = False;      /* True when a disconnect PDU was received */
1266            BOOL cont = True;
1267          STREAM s;          STREAM s;
1268    
1269          while ((s = rdp_recv(&type)) != NULL)          while (cont)
1270          {          {
1271                    s = rdp_recv(&type);
1272                    if (s == NULL)
1273                            return False;
1274                  switch (type)                  switch (type)
1275                  {                  {
1276                          case RDP_PDU_DEMAND_ACTIVE:                          case RDP_PDU_DEMAND_ACTIVE:
1277                                  process_demand_active(s);                                  process_demand_active(s);
1278                                    *deactivated = False;
1279                                  break;                                  break;
   
1280                          case RDP_PDU_DEACTIVATE:                          case RDP_PDU_DEACTIVATE:
1281                                    DEBUG(("RDP_PDU_DEACTIVATE\n"));
1282                                    *deactivated = True;
1283                                  break;                                  break;
   
1284                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1285                                  process_data_pdu(s);                                  disc = process_data_pdu(s, ext_disc_reason);
1286                                    break;
1287                            case 0:
1288                                  break;                                  break;
   
1289                          default:                          default:
1290                                  unimpl("PDU %d\n", type);                                  unimpl("PDU %d\n", type);
1291                  }                  }
1292                    if (disc)
1293                            return False;
1294                    cont = g_next_packet < s->end;
1295          }          }
1296            return True;
1297  }  }
1298    
1299  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */
# Line 712  BOOL Line 1301  BOOL
1301  rdp_connect(char *server, uint32 flags, char *domain, char *password,  rdp_connect(char *server, uint32 flags, char *domain, char *password,
1302              char *command, char *directory)              char *command, char *directory)
1303  {  {
1304          if (!sec_connect(server))          if (!sec_connect(server, g_username))
1305                  return False;                  return False;
1306    
1307          rdp_send_logon_info(flags, domain, username, password, command, directory);          rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1308          return True;          return True;
1309  }  }
1310    

Legend:
Removed from v.207  
changed lines
  Added in v.858

  ViewVC Help
Powered by ViewVC 1.1.26