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

Legend:
Removed from v.340  
changed lines
  Added in v.855

  ViewVC Help
Powered by ViewVC 1.1.26