/[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 260 by astrand, Mon Nov 18 15:31:19 2002 UTC revision 886 by stargo, Sat Apr 16 11:42:34 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          return s;  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    extern BOOL g_rdp_compression;
53    
54  /* Send an RDP packet */  uint8 *g_next_packet;
55  static void  uint32 g_rdp_shareid;
 rdp_send(STREAM s, uint8 pdu_type)  
 {  
         uint16 length;  
56    
57          s_pop_layer(s, rdp_hdr);  extern RDPCOMP g_mppc_dict;
         length = s->end - s->p;  
58    
59          out_uint16_le(s, length);  #if WITH_DEBUG
60          out_uint16_le(s, (pdu_type | 0x10));    /* Version 1 */  static uint32 g_packetno;
61          out_uint16_le(s, (mcs_userid + 1001));  #endif
62    
63          sec_send(s, encryption ? SEC_ENCRYPT : 0);  #ifdef HAVE_ICONV
64  }  static BOOL g_iconv_works = True;
65    #endif
66    
67  /* Receive an RDP packet */  /* Receive an RDP packet */
68  static STREAM  static STREAM
# Line 64  rdp_recv(uint8 * type) Line 70  rdp_recv(uint8 * type)
70  {  {
71          static STREAM rdp_s;          static STREAM rdp_s;
72          uint16 length, pdu_type;          uint16 length, pdu_type;
73            uint8 rdpver;
74    
75          if ((rdp_s == NULL) || (next_packet >= rdp_s->end))          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))
76          {          {
77                  rdp_s = sec_recv();                  rdp_s = sec_recv(&rdpver);
78                  if (rdp_s == NULL)                  if (rdp_s == NULL)
79                          return NULL;                          return NULL;
80                    if (rdpver == 0xff)
81                    {
82                            g_next_packet = rdp_s->end;
83                            *type = 0;
84                            return rdp_s;
85                    }
86                    else if (rdpver != 3)
87                    {
88                            /* rdp5_process should move g_next_packet ok */
89                            rdp5_process(rdp_s);
90                            *type = 0;
91                            return rdp_s;
92                    }
93    
94                  next_packet = rdp_s->p;                  g_next_packet = rdp_s->p;
95          }          }
96          else          else
97          {          {
98                  rdp_s->p = next_packet;                  rdp_s->p = g_next_packet;
99          }          }
100    
101          in_uint16_le(rdp_s, length);          in_uint16_le(rdp_s, length);
102            /* 32k packets are really 8, keepalive fix */
103            if (length == 0x8000)
104            {
105                    g_next_packet += 8;
106                    *type = 0;
107                    return rdp_s;
108            }
109          in_uint16_le(rdp_s, pdu_type);          in_uint16_le(rdp_s, pdu_type);
110          in_uint8s(rdp_s, 2);    /* userid */          in_uint8s(rdp_s, 2);    /* userid */
111          *type = pdu_type & 0xf;          *type = pdu_type & 0xf;
112    
113  #if WITH_DEBUG  #if WITH_DEBUG
114          DEBUG(("RDP packet (type %x):\n", *type));          DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type));
115          hexdump(next_packet, length);          hexdump(g_next_packet, length);
116  #endif /*  */  #endif /*  */
117    
118          next_packet += length;          g_next_packet += length;
119          return rdp_s;          return rdp_s;
120  }  }
121    
# Line 98  rdp_init_data(int maxlen) Line 125  rdp_init_data(int maxlen)
125  {  {
126          STREAM s;          STREAM s;
127    
128          s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 18);          s = sec_init(g_encryption ? SEC_ENCRYPT : 0, maxlen + 18);
129          s_push_layer(s, rdp_hdr, 18);          s_push_layer(s, rdp_hdr, 18);
130    
131          return s;          return s;
# Line 115  rdp_send_data(STREAM s, uint8 data_pdu_t Line 142  rdp_send_data(STREAM s, uint8 data_pdu_t
142    
143          out_uint16_le(s, length);          out_uint16_le(s, length);
144          out_uint16_le(s, (RDP_PDU_DATA | 0x10));          out_uint16_le(s, (RDP_PDU_DATA | 0x10));
145          out_uint16_le(s, (mcs_userid + 1001));          out_uint16_le(s, (g_mcs_userid + 1001));
146    
147          out_uint32_le(s, rdp_shareid);          out_uint32_le(s, g_rdp_shareid);
148          out_uint8(s, 0);        /* pad */          out_uint8(s, 0);        /* pad */
149          out_uint8(s, 1);        /* streamid */          out_uint8(s, 1);        /* streamid */
150          out_uint16_le(s, (length - 14));          out_uint16_le(s, (length - 14));
# Line 125  rdp_send_data(STREAM s, uint8 data_pdu_t Line 152  rdp_send_data(STREAM s, uint8 data_pdu_t
152          out_uint8(s, 0);        /* compress_type */          out_uint8(s, 0);        /* compress_type */
153          out_uint16(s, 0);       /* compress_len */          out_uint16(s, 0);       /* compress_len */
154    
155          sec_send(s, encryption ? SEC_ENCRYPT : 0);          sec_send(s, g_encryption ? SEC_ENCRYPT : 0);
156  }  }
157    
158  /* Output a string in Unicode */  /* Output a string in Unicode */
159  void  void
160  rdp_out_unistr(STREAM s, char *string, int len)  rdp_out_unistr(STREAM s, char *string, int len)
161  {  {
162          int i = 0, j = 0;  #ifdef HAVE_ICONV
163            size_t ibl = strlen(string), obl = len + 2;
164            static iconv_t iconv_h = (iconv_t) - 1;
165            char *pin = string, *pout = (char *) s->p;
166    
167            memset(pout, 0, len + 4);
168    
169            if (g_iconv_works)
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                                    warning("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n",
177                                            g_codepage, WINDOWS_CODEPAGE, (int) iconv_h);
178    
179                                    g_iconv_works = False;
180                                    rdp_out_unistr(s, string, len);
181                                    return;
182                            }
183                            if (iconv(iconv_h, (ICONV_CONST char **) &pin, &i, &pout, &o) ==
184                                (size_t) - 1)
185                            {
186                                    iconv_close(iconv_h);
187                                    iconv_h = (iconv_t) - 1;
188                                    warning("rdp_out_unistr: iconv(1) fail, errno %d\n", errno);
189    
190                                    g_iconv_works = False;
191                                    rdp_out_unistr(s, string, len);
192                                    return;
193                            }
194                            pin = string;
195                            pout = (char *) s->p;
196                    }
197    
198                    if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
199                    {
200                            iconv_close(iconv_h);
201                            iconv_h = (iconv_t) - 1;
202                            warning("rdp_out_unistr: iconv(2) fail, errno %d\n", errno);
203    
204                            g_iconv_works = False;
205                            rdp_out_unistr(s, string, len);
206                            return;
207                    }
208    
209                    s->p += len + 2;
210    
211            }
212            else
213    #endif
214            {
215                    int i = 0, j = 0;
216    
217                    len += 2;
218    
219                    while (i < len)
220                    {
221                            s->p[i++] = string[j++];
222                            s->p[i++] = 0;
223                    }
224    
225          len += 2;                  s->p += len;
226            }
227    }
228    
229          while (i < len)  /* Input a string in Unicode
230     *
231     * Returns str_len of string
232     */
233    int
234    rdp_in_unistr(STREAM s, char *string, int uni_len)
235    {
236    #ifdef HAVE_ICONV
237            size_t ibl = uni_len, obl = uni_len;
238            char *pin = (char *) s->p, *pout = string;
239            static iconv_t iconv_h = (iconv_t) - 1;
240    
241            if (g_iconv_works)
242          {          {
243                  s->p[i++] = string[j++];                  if (iconv_h == (iconv_t) - 1)
244                  s->p[i++] = 0;                  {
245                            if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1)
246                            {
247                                    warning("rdp_in_unistr: iconv_open[%s -> %s] fail %d\n",
248                                            WINDOWS_CODEPAGE, g_codepage, (int) iconv_h);
249    
250                                    g_iconv_works = False;
251                                    return rdp_in_unistr(s, string, uni_len);
252                            }
253                    }
254    
255                    if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
256                    {
257                            iconv_close(iconv_h);
258                            iconv_h = (iconv_t) - 1;
259                            warning("rdp_in_unistr: iconv fail, errno %d\n", errno);
260    
261                            g_iconv_works = False;
262                            return rdp_in_unistr(s, string, uni_len);
263                    }
264                    return pout - string;
265          }          }
266            else
267    #endif
268            {
269                    int i = 0;
270    
271                    while (i < uni_len / 2)
272                    {
273                            in_uint8a(s, &string[i++], 1);
274                            in_uint8s(s, 1);
275                    }
276    
277          s->p += len;                  return i - 1;
278            }
279  }  }
280    
281    
282  /* Parse a logon info packet */  /* Parse a logon info packet */
283  static void  static void
284  rdp_send_logon_info(uint32 flags, char *domain, char *user,  rdp_send_logon_info(uint32 flags, char *domain, char *user,
285                      char *password, char *program, char *directory)                      char *password, char *program, char *directory)
286  {  {
287            char *ipaddr = tcp_get_address();
288          int len_domain = 2 * strlen(domain);          int len_domain = 2 * strlen(domain);
289          int len_user = 2 * strlen(user);          int len_user = 2 * strlen(user);
290          int len_password = 2 * strlen(password);          int len_password = 2 * strlen(password);
291          int len_program = 2 * strlen(program);          int len_program = 2 * strlen(program);
292          int len_directory = 2 * strlen(directory);          int len_directory = 2 * strlen(directory);
293          uint32 sec_flags = encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;          int len_ip = 2 * strlen(ipaddr);
294            int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
295            int packetlen = 0;
296            uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
297          STREAM s;          STREAM s;
298            time_t t = time(NULL);
299            time_t tzone;
300    
301    #if 0
302            /* enable rdp compression */
303            /* some problems still exist with rdp5 */
304            flags |= RDP_COMPRESSION;
305    #endif
306    
307            if (!g_use_rdp5 || 1 == g_server_rdp_version)
308            {
309                    DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
310    
311                    s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
312                                 + len_program + len_directory + 10);
313    
314                    out_uint32(s, 0);
315                    out_uint32_le(s, flags);
316                    out_uint16_le(s, len_domain);
317                    out_uint16_le(s, len_user);
318                    out_uint16_le(s, len_password);
319                    out_uint16_le(s, len_program);
320                    out_uint16_le(s, len_directory);
321                    rdp_out_unistr(s, domain, len_domain);
322                    rdp_out_unistr(s, user, len_user);
323                    rdp_out_unistr(s, password, len_password);
324                    rdp_out_unistr(s, program, len_program);
325                    rdp_out_unistr(s, directory, len_directory);
326            }
327            else
328            {
329    
330                    flags |= RDP_LOGON_BLOB;
331                    DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
332                    packetlen = 4 + /* Unknown uint32 */
333                            4 +     /* flags */
334                            2 +     /* len_domain */
335                            2 +     /* len_user */
336                            (flags & RDP_LOGON_AUTO ? 2 : 0) +      /* len_password */
337                            (flags & RDP_LOGON_BLOB ? 2 : 0) +      /* Length of BLOB */
338                            2 +     /* len_program */
339                            2 +     /* len_directory */
340                            (0 < len_domain ? len_domain : 2) +     /* domain */
341                            len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 +    /* We have no 512 byte BLOB. Perhaps we must? */
342                            (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + /* After the BLOB is a unknown int16. If there is a BLOB, that is. */
343                            (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 +     /* Unknown (2) */
344                            2 +     /* Client ip length */
345                            len_ip +        /* Client ip */
346                            2 +     /* DLL string length */
347                            len_dll +       /* DLL string */
348                            2 +     /* Unknown */
349                            2 +     /* Unknown */
350                            64 +    /* Time zone #0 */
351                            2 +     /* Unknown */
352                            64 +    /* Time zone #1 */
353                            32;     /* Unknown */
354    
355                    s = sec_init(sec_flags, packetlen);
356                    DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
357    
358                    out_uint32(s, 0);       /* Unknown */
359                    out_uint32_le(s, flags);
360                    out_uint16_le(s, len_domain);
361                    out_uint16_le(s, len_user);
362                    if (flags & RDP_LOGON_AUTO)
363                    {
364                            out_uint16_le(s, len_password);
365    
366                    }
367                    if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
368                    {
369                            out_uint16_le(s, 0);
370                    }
371                    out_uint16_le(s, len_program);
372                    out_uint16_le(s, len_directory);
373                    if (0 < len_domain)
374                            rdp_out_unistr(s, domain, len_domain);
375                    else
376                            out_uint16_le(s, 0);
377                    rdp_out_unistr(s, user, len_user);
378                    if (flags & RDP_LOGON_AUTO)
379                    {
380                            rdp_out_unistr(s, password, len_password);
381                    }
382                    if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
383                    {
384                            out_uint16_le(s, 0);
385                    }
386                    if (0 < len_program)
387                    {
388                            rdp_out_unistr(s, program, len_program);
389    
390          s = sec_init(sec_flags, 18 + len_domain + len_user + len_password                  }
391                       + len_program + len_directory + 10);                  else
392                    {
393                            out_uint16_le(s, 0);
394                    }
395                    if (0 < len_directory)
396                    {
397                            rdp_out_unistr(s, directory, len_directory);
398                    }
399                    else
400                    {
401                            out_uint16_le(s, 0);
402                    }
403                    out_uint16_le(s, 2);
404                    out_uint16_le(s, len_ip + 2);   /* Length of client ip */
405                    rdp_out_unistr(s, ipaddr, len_ip);
406                    out_uint16_le(s, len_dll + 2);
407                    rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
408    
409                    tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
410                    out_uint32_le(s, tzone);
411    
412                    rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
413                    out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
414    
415                    out_uint32_le(s, 0x0a0000);
416                    out_uint32_le(s, 0x050000);
417                    out_uint32_le(s, 3);
418                    out_uint32_le(s, 0);
419                    out_uint32_le(s, 0);
420    
421                    rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
422                    out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
423    
424                    out_uint32_le(s, 0x30000);
425                    out_uint32_le(s, 0x050000);
426                    out_uint32_le(s, 2);
427                    out_uint32(s, 0);
428                    out_uint32_le(s, 0xffffffc4);
429                    out_uint32_le(s, 0xfffffffe);
430                    out_uint32_le(s, g_rdp5_performanceflags);
431                    out_uint32(s, 0);
432    
         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);  
433    
434            }
435          s_mark_end(s);          s_mark_end(s);
436          sec_send(s, sec_flags);          sec_send(s, sec_flags);
437  }  }
# Line 230  rdp_send_input(uint32 time, uint16 messa Line 488  rdp_send_input(uint32 time, uint16 messa
488          rdp_send_data(s, RDP_DATA_PDU_INPUT);          rdp_send_data(s, RDP_DATA_PDU_INPUT);
489  }  }
490    
491    /* Inform the server on the contents of the persistent bitmap cache */
492    static void
493    rdp_enum_bmpcache2(void)
494    {
495            STREAM s;
496            HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS];
497            uint32 num_keys, offset, count, flags;
498    
499            offset = 0;
500            num_keys = pstcache_enumerate(2, keylist);
501    
502            while (offset < num_keys)
503            {
504                    count = MIN(num_keys - offset, 169);
505    
506                    s = rdp_init_data(24 + count * sizeof(HASH_KEY));
507    
508                    flags = 0;
509                    if (offset == 0)
510                            flags |= PDU_FLAG_FIRST;
511                    if (num_keys - offset <= 169)
512                            flags |= PDU_FLAG_LAST;
513    
514                    /* header */
515                    out_uint32_le(s, 0);
516                    out_uint16_le(s, count);
517                    out_uint16_le(s, 0);
518                    out_uint16_le(s, 0);
519                    out_uint16_le(s, 0);
520                    out_uint16_le(s, 0);
521                    out_uint16_le(s, num_keys);
522                    out_uint32_le(s, 0);
523                    out_uint32_le(s, flags);
524    
525                    /* list */
526                    out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
527    
528                    s_mark_end(s);
529                    rdp_send_data(s, 0x2b);
530    
531                    offset += 169;
532            }
533    }
534    
535  /* Send an (empty) font information PDU */  /* Send an (empty) font information PDU */
536  static void  static void
537  rdp_send_fonts(uint16 seq)  rdp_send_fonts(uint16 seq)
# Line 239  rdp_send_fonts(uint16 seq) Line 541  rdp_send_fonts(uint16 seq)
541          s = rdp_init_data(8);          s = rdp_init_data(8);
542    
543          out_uint16(s, 0);       /* number of fonts */          out_uint16(s, 0);       /* number of fonts */
544          out_uint16_le(s, 0x3e); /* unknown */          out_uint16_le(s, 0);    /* pad? */
545          out_uint16_le(s, seq);  /* unknown */          out_uint16_le(s, seq);  /* unknown */
546          out_uint16_le(s, 0x32); /* entry size */          out_uint16_le(s, 0x32); /* entry size */
547    
# Line 259  rdp_out_general_caps(STREAM s) Line 561  rdp_out_general_caps(STREAM s)
561          out_uint16_le(s, 0x200);        /* Protocol version */          out_uint16_le(s, 0x200);        /* Protocol version */
562          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
563          out_uint16(s, 0);       /* Compression types */          out_uint16(s, 0);       /* Compression types */
564          out_uint16(s, 0);       /* Pad */          out_uint16_le(s, g_use_rdp5 ? 0x40d : 0);
565            /* Pad, according to T.128. 0x40d seems to
566               trigger
567               the server to start sending RDP5 packets.
568               However, the value is 0x1d04 with W2KTSK and
569               NT4MS. Hmm.. Anyway, thankyou, Microsoft,
570               for sending such information in a padding
571               field.. */
572          out_uint16(s, 0);       /* Update capability */          out_uint16(s, 0);       /* Update capability */
573          out_uint16(s, 0);       /* Remote unshare capability */          out_uint16(s, 0);       /* Remote unshare capability */
574          out_uint16(s, 0);       /* Compression level */          out_uint16(s, 0);       /* Compression level */
# Line 273  rdp_out_bitmap_caps(STREAM s) Line 582  rdp_out_bitmap_caps(STREAM s)
582          out_uint16_le(s, RDP_CAPSET_BITMAP);          out_uint16_le(s, RDP_CAPSET_BITMAP);
583          out_uint16_le(s, RDP_CAPLEN_BITMAP);          out_uint16_le(s, RDP_CAPLEN_BITMAP);
584    
585          out_uint16_le(s, 8);    /* Preferred BPP */          out_uint16_le(s, g_server_bpp); /* Preferred BPP */
586          out_uint16_le(s, 1);    /* Receive 1 BPP */          out_uint16_le(s, 1);    /* Receive 1 BPP */
587          out_uint16_le(s, 1);    /* Receive 4 BPP */          out_uint16_le(s, 1);    /* Receive 4 BPP */
588          out_uint16_le(s, 1);    /* Receive 8 BPP */          out_uint16_le(s, 1);    /* Receive 8 BPP */
589          out_uint16_le(s, 800);  /* Desktop width */          out_uint16_le(s, 800);  /* Desktop width */
590          out_uint16_le(s, 600);  /* Desktop height */          out_uint16_le(s, 600);  /* Desktop height */
591          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
592          out_uint16(s, 0);       /* Allow resize */          out_uint16(s, 1);       /* Allow resize */
593          out_uint16_le(s, bitmap_compression ? 1 : 0);   /* Support compression */          out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
594          out_uint16(s, 0);       /* Unknown */          out_uint16(s, 0);       /* Unknown */
595          out_uint16_le(s, 1);    /* Unknown */          out_uint16_le(s, 1);    /* Unknown */
596          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
# Line 293  rdp_out_order_caps(STREAM s) Line 602  rdp_out_order_caps(STREAM s)
602  {  {
603          uint8 order_caps[32];          uint8 order_caps[32];
604    
   
605          memset(order_caps, 0, 32);          memset(order_caps, 0, 32);
606          order_caps[0] = 1;      /* dest blt */          order_caps[0] = 1;      /* dest blt */
607          order_caps[1] = 1;      /* pat blt */          order_caps[1] = 1;      /* pat blt */
608          order_caps[2] = 1;      /* screen blt */          order_caps[2] = 1;      /* screen blt */
609          order_caps[3] = 1;      /* required for memblt? */          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
610            order_caps[4] = 0;      /* triblt */
611          order_caps[8] = 1;      /* line */          order_caps[8] = 1;      /* line */
612          order_caps[9] = 1;      /* line */          order_caps[9] = 1;      /* line */
613          order_caps[10] = 1;     /* rect */          order_caps[10] = 1;     /* rect */
614          order_caps[11] = (desktop_save == False ? 0 : 1);       /* desksave */          order_caps[11] = (g_desktop_save ? 1 : 0);      /* desksave */
615          order_caps[13] = 1;     /* memblt */          order_caps[13] = 1;     /* memblt */
616          order_caps[14] = 1;     /* triblt */          order_caps[14] = 1;     /* triblt */
617            order_caps[20] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon */
618            order_caps[21] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon2 */
619          order_caps[22] = 1;     /* polyline */          order_caps[22] = 1;     /* polyline */
620            order_caps[25] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse */
621            order_caps[26] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse2 */
622          order_caps[27] = 1;     /* text2 */          order_caps[27] = 1;     /* text2 */
623          out_uint16_le(s, RDP_CAPSET_ORDER);          out_uint16_le(s, RDP_CAPSET_ORDER);
624          out_uint16_le(s, RDP_CAPLEN_ORDER);          out_uint16_le(s, RDP_CAPLEN_ORDER);
# Line 320  rdp_out_order_caps(STREAM s) Line 633  rdp_out_order_caps(STREAM s)
633          out_uint8p(s, order_caps, 32);  /* Orders supported */          out_uint8p(s, order_caps, 32);  /* Orders supported */
634          out_uint16_le(s, 0x6a1);        /* Text capability flags */          out_uint16_le(s, 0x6a1);        /* Text capability flags */
635          out_uint8s(s, 6);       /* Pad */          out_uint8s(s, 6);       /* Pad */
636          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 */
637          out_uint32(s, 0);       /* Unknown */          out_uint32(s, 0);       /* Unknown */
638          out_uint32_le(s, 0x4e4);        /* Unknown */          out_uint32_le(s, 0x4e4);        /* Unknown */
639  }  }
# Line 329  rdp_out_order_caps(STREAM s) Line 642  rdp_out_order_caps(STREAM s)
642  static void  static void
643  rdp_out_bmpcache_caps(STREAM s)  rdp_out_bmpcache_caps(STREAM s)
644  {  {
645            int Bpp;
646          out_uint16_le(s, RDP_CAPSET_BMPCACHE);          out_uint16_le(s, RDP_CAPSET_BMPCACHE);
647          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
648    
649            Bpp = (g_server_bpp + 7) / 8;
650          out_uint8s(s, 24);      /* unused */          out_uint8s(s, 24);      /* unused */
651          out_uint16_le(s, 0x258);        /* entries */          out_uint16_le(s, 0x258);        /* entries */
652          out_uint16_le(s, 0x100);        /* max cell size */          out_uint16_le(s, 0x100 * Bpp);  /* max cell size */
653          out_uint16_le(s, 0x12c);        /* entries */          out_uint16_le(s, 0x12c);        /* entries */
654          out_uint16_le(s, 0x400);        /* max cell size */          out_uint16_le(s, 0x400 * Bpp);  /* max cell size */
655          out_uint16_le(s, 0x106);        /* entries */          out_uint16_le(s, 0x106);        /* entries */
656          out_uint16_le(s, 0x1000);       /* max cell size */          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
657    }
658    
659    /* Output bitmap cache v2 capability set */
660    static void
661    rdp_out_bmpcache2_caps(STREAM s)
662    {
663            uint16 cellsize;
664    
665            out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
666            out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
667    
668            out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
669    
670            /* Cellsize:
671               01 = 16x16, 02 = 32x32, 03 = 64x64
672               log2(cell size) - 3
673             */
674    
675            cellsize = 0x03;
676    
677            if (g_rdp_compression)
678            {
679                    switch (g_server_bpp)
680                    {
681                            case 24:
682                            case 16:
683                            case 15:
684                                    cellsize = 0x02;
685                                    break;
686                    }
687            }
688    
689            out_uint16_le(s, (0x0000 | (cellsize << 8)));   /* flags? number of caches? */
690    
691            out_uint32_le(s, BMPCACHE2_C0_CELLS);
692            out_uint32_le(s, BMPCACHE2_C1_CELLS);
693            if (pstcache_init(2))
694            {
695                    out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
696            }
697            else
698            {
699                    out_uint32_le(s, BMPCACHE2_C2_CELLS);
700            }
701            out_uint8s(s, 20);      /* other bitmap caches not used */
702  }  }
703    
704  /* Output control capability set */  /* Output control capability set */
# Line 400  rdp_out_colcache_caps(STREAM s) Line 760  rdp_out_colcache_caps(STREAM s)
760          out_uint16(s, 0);       /* pad */          out_uint16(s, 0);       /* pad */
761  }  }
762    
763  static uint8 canned_caps[] = {  static uint8 caps_0x0d[] = {
764          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
765          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
766          0x00, 0x00, 0x00, 0x00, 0x00,          0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
767          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
768          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
769          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
770          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
771          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
772          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
773          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
774          0x0C, 0x00, 0x08, 0x00, 0x01,          0x00, 0x00, 0x00, 0x00
775          0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,  };
776          0x10, 0x00, 0x34, 0x00, 0xFE,  
777          0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
778          0xFE, 0x00, 0x08, 0x00, 0xFE,  
779          0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,  static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
780          0xFE, 0x00, 0x80, 0x00, 0xFE,  
781          0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,  static uint8 caps_0x10[] = {
782          0x02, 0x00, 0x00, 0x00          0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
783            0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
784            0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
785            0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
786            0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
787            0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
788  };  };
789    
790  /* Output unknown capability set */  /* Output unknown capability sets */
791  static void  static void
792  rdp_out_unknown_caps(STREAM s)  rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
793  {  {
794          out_uint16_le(s, RDP_CAPSET_UNKNOWN);          out_uint16_le(s, id);
795          out_uint16_le(s, 0x58);          out_uint16_le(s, length);
796    
797          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);          out_uint8p(s, caps, length - 4);
798  }  }
799    
800    #define RDP5_FLAG 0x0030
801  /* Send a confirm active PDU */  /* Send a confirm active PDU */
802  static void  static void
803  rdp_send_confirm_active(void)  rdp_send_confirm_active(void)
804  {  {
805          STREAM s;          STREAM s;
806            uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
807          uint16 caplen =          uint16 caplen =
808                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
809                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
810                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
811                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
812                    0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
813                    4 /* w2k fix, why? */ ;
814    
815          s = rdp_init(14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
816    
817          out_uint32_le(s, rdp_shareid);          out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
818            out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10));      /* Version 1 */
819            out_uint16_le(s, (g_mcs_userid + 1001));
820    
821            out_uint32_le(s, g_rdp_shareid);
822          out_uint16_le(s, 0x3ea);        /* userid */          out_uint16_le(s, 0x3ea);        /* userid */
823          out_uint16_le(s, sizeof(RDP_SOURCE));          out_uint16_le(s, sizeof(RDP_SOURCE));
824          out_uint16_le(s, caplen);          out_uint16_le(s, caplen);
# Line 457  rdp_send_confirm_active(void) Line 830  rdp_send_confirm_active(void)
830          rdp_out_general_caps(s);          rdp_out_general_caps(s);
831          rdp_out_bitmap_caps(s);          rdp_out_bitmap_caps(s);
832          rdp_out_order_caps(s);          rdp_out_order_caps(s);
833          rdp_out_bmpcache_caps(s);          g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
834          rdp_out_colcache_caps(s);          rdp_out_colcache_caps(s);
835          rdp_out_activate_caps(s);          rdp_out_activate_caps(s);
836          rdp_out_control_caps(s);          rdp_out_control_caps(s);
837          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
838          rdp_out_share_caps(s);          rdp_out_share_caps(s);
839          rdp_out_unknown_caps(s);  
840            rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
841            rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
842            rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
843            rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
844    
845          s_mark_end(s);          s_mark_end(s);
846          rdp_send(s, RDP_PDU_CONFIRM_ACTIVE);          sec_send(s, sec_flags);
847    }
848    
849    /* Process a general capability set */
850    static void
851    rdp_process_general_caps(STREAM s)
852    {
853            uint16 pad2octetsB;     /* rdp5 flags? */
854    
855            in_uint8s(s, 10);
856            in_uint16_le(s, pad2octetsB);
857    
858            if (!pad2octetsB)
859                    g_use_rdp5 = False;
860    }
861    
862    /* Process a bitmap capability set */
863    static void
864    rdp_process_bitmap_caps(STREAM s)
865    {
866            uint16 width, height, bpp;
867    
868            in_uint16_le(s, bpp);
869            in_uint8s(s, 6);
870    
871            in_uint16_le(s, width);
872            in_uint16_le(s, height);
873    
874            DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));
875    
876            /*
877             * The server may limit bpp and change the size of the desktop (for
878             * example when shadowing another session).
879             */
880            if (g_server_bpp != bpp)
881            {
882                    warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
883                    g_server_bpp = bpp;
884            }
885            if (g_width != width || g_height != height)
886            {
887                    warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
888                            width, height);
889                    g_width = width;
890                    g_height = height;
891                    ui_resize_window();
892            }
893    }
894    
895    /* Process server capabilities */
896    void
897    rdp_process_server_caps(STREAM s, uint16 length)
898    {
899            int n;
900            uint8 *next, *start;
901            uint16 ncapsets, capset_type, capset_length;
902    
903            start = s->p;
904    
905            in_uint16_le(s, ncapsets);
906            in_uint8s(s, 2);        /* pad */
907    
908            for (n = 0; n < ncapsets; n++)
909            {
910                    if (s->p > start + length)
911                            return;
912    
913                    in_uint16_le(s, capset_type);
914                    in_uint16_le(s, capset_length);
915    
916                    next = s->p + capset_length - 4;
917    
918                    switch (capset_type)
919                    {
920                            case RDP_CAPSET_GENERAL:
921                                    rdp_process_general_caps(s);
922                                    break;
923    
924                            case RDP_CAPSET_BITMAP:
925                                    rdp_process_bitmap_caps(s);
926                                    break;
927                    }
928    
929                    s->p = next;
930            }
931  }  }
932    
933  /* Respond to a demand active PDU */  /* Respond to a demand active PDU */
# Line 474  static void Line 935  static void
935  process_demand_active(STREAM s)  process_demand_active(STREAM s)
936  {  {
937          uint8 type;          uint8 type;
938            uint16 len_src_descriptor, len_combined_caps;
939    
940          in_uint32_le(s, rdp_shareid);          in_uint32_le(s, g_rdp_shareid);
941            in_uint16_le(s, len_src_descriptor);
942            in_uint16_le(s, len_combined_caps);
943            in_uint8s(s, len_src_descriptor);
944    
945          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", rdp_shareid));          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
946            rdp_process_server_caps(s, len_combined_caps);
947    
948          rdp_send_confirm_active();          rdp_send_confirm_active();
949          rdp_send_synchronise();          rdp_send_synchronise();
# Line 486  process_demand_active(STREAM s) Line 952  process_demand_active(STREAM s)
952          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
953          rdp_recv(&type);        /* RDP_CTL_COOPERATE */          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
954          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
955          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);
956          rdp_send_fonts(1);  
957          rdp_send_fonts(2);          if (g_use_rdp5)
958          rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 */          {
959                    rdp_enum_bmpcache2();
960                    rdp_send_fonts(3);
961            }
962            else
963            {
964                    rdp_send_fonts(1);
965                    rdp_send_fonts(2);
966            }
967    
968            rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
969          reset_order_state();          reset_order_state();
970  }  }
971    
972    /* Process a colour pointer PDU */
973    void
974    process_colour_pointer_pdu(STREAM s)
975    {
976            uint16 x, y, width, height, cache_idx, masklen, datalen;
977            uint8 *mask, *data;
978            HCURSOR cursor;
979    
980            in_uint16_le(s, cache_idx);
981            in_uint16_le(s, x);
982            in_uint16_le(s, y);
983            in_uint16_le(s, width);
984            in_uint16_le(s, height);
985            in_uint16_le(s, masklen);
986            in_uint16_le(s, datalen);
987            in_uint8p(s, data, datalen);
988            in_uint8p(s, mask, masklen);
989            cursor = ui_create_cursor(x, y, width, height, mask, data);
990            ui_set_cursor(cursor);
991            cache_put_cursor(cache_idx, cursor);
992    }
993    
994    /* Process a cached pointer PDU */
995    void
996    process_cached_pointer_pdu(STREAM s)
997    {
998            uint16 cache_idx;
999    
1000            in_uint16_le(s, cache_idx);
1001            ui_set_cursor(cache_get_cursor(cache_idx));
1002    }
1003    
1004    /* Process a system pointer PDU */
1005    void
1006    process_system_pointer_pdu(STREAM s)
1007    {
1008            uint16 system_pointer_type;
1009    
1010            in_uint16(s, system_pointer_type);
1011            switch (system_pointer_type)
1012            {
1013                    case RDP_NULL_POINTER:
1014                            ui_set_null_cursor();
1015                            break;
1016    
1017                    default:
1018                            unimpl("System pointer message 0x%x\n", system_pointer_type);
1019            }
1020    }
1021    
1022  /* Process a pointer PDU */  /* Process a pointer PDU */
1023  static void  static void
1024  process_pointer_pdu(STREAM s)  process_pointer_pdu(STREAM s)
1025  {  {
1026          uint16 message_type;          uint16 message_type;
1027          uint16 x, y, width, height, cache_idx, masklen, datalen;          uint16 x, y;
         uint8 *mask, *data;  
         HCURSOR cursor;  
1028    
1029          in_uint16_le(s, message_type);          in_uint16_le(s, message_type);
1030          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
# Line 515  process_pointer_pdu(STREAM s) Line 1039  process_pointer_pdu(STREAM s)
1039                          break;                          break;
1040    
1041                  case RDP_POINTER_COLOR:                  case RDP_POINTER_COLOR:
1042                          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);  
1043                          break;                          break;
1044    
1045                  case RDP_POINTER_CACHED:                  case RDP_POINTER_CACHED:
1046                          in_uint16_le(s, cache_idx);                          process_cached_pointer_pdu(s);
1047                          ui_set_cursor(cache_get_cursor(cache_idx));                          break;
1048    
1049                    case RDP_POINTER_SYSTEM:
1050                            process_system_pointer_pdu(s);
1051                          break;                          break;
1052    
1053                  default:                  default:
1054                          DEBUG(("Pointer message 0x%x\n", message_type));                          unimpl("Pointer message 0x%x\n", message_type);
1055          }          }
1056  }  }
1057    
1058  /* Process bitmap updates */  /* Process bitmap updates */
1059  static void  void
1060  process_bitmap_updates(STREAM s)  process_bitmap_updates(STREAM s)
1061  {  {
1062          uint16 num_updates;          uint16 num_updates;
1063          uint16 left, top, right, bottom, width, height;          uint16 left, top, right, bottom, width, height;
1064          uint16 cx, cy, bpp, compress, bufsize, size;          uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
1065          uint8 *data, *bmpdata;          uint8 *data, *bmpdata;
1066          int i;          int i;
1067    
# Line 560  process_bitmap_updates(STREAM s) Line 1076  process_bitmap_updates(STREAM s)
1076                  in_uint16_le(s, width);                  in_uint16_le(s, width);
1077                  in_uint16_le(s, height);                  in_uint16_le(s, height);
1078                  in_uint16_le(s, bpp);                  in_uint16_le(s, bpp);
1079                    Bpp = (bpp + 7) / 8;
1080                  in_uint16_le(s, compress);                  in_uint16_le(s, compress);
1081                  in_uint16_le(s, bufsize);                  in_uint16_le(s, bufsize);
1082    
1083                  cx = right - left + 1;                  cx = right - left + 1;
1084                  cy = bottom - top + 1;                  cy = bottom - top + 1;
1085    
1086                  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",
1087                         left, top, right, bottom, width, height, compress));                         left, top, right, bottom, width, height, Bpp, compress));
1088    
1089                  if (!compress)                  if (!compress)
1090                  {                  {
1091                          int y;                          int y;
1092                          bmpdata = xmalloc(width * height);                          bmpdata = (uint8 *) xmalloc(width * height * Bpp);
1093                          for (y = 0; y < height; y++)                          for (y = 0; y < height; y++)
1094                          {                          {
1095                                  in_uint8a(s, &bmpdata[(height - y - 1) * width], width);                                  in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
1096                                              width * Bpp);
1097                          }                          }
1098                          ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);                          ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
1099                          xfree(bmpdata);                          xfree(bmpdata);
1100                          continue;                          continue;
1101                  }                  }
1102    
                 in_uint8s(s, 2);        /* pad */  
                 in_uint16_le(s, size);  
                 in_uint8s(s, 4);        /* line_size, final_size */  
                 in_uint8p(s, data, size);  
1103    
1104                  bmpdata = xmalloc(width * height);                  if (compress & 0x400)
1105                  if (bitmap_decompress(bmpdata, width, height, data, size))                  {
1106                            size = bufsize;
1107                    }
1108                    else
1109                    {
1110                            in_uint8s(s, 2);        /* pad */
1111                            in_uint16_le(s, size);
1112                            in_uint8s(s, 4);        /* line_size, final_size */
1113                    }
1114                    in_uint8p(s, data, size);
1115                    bmpdata = (uint8 *) xmalloc(width * height * Bpp);
1116                    if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
1117                  {                  {
1118                          ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);                          ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
1119                  }                  }
1120                    else
1121                    {
1122                            DEBUG_RDP5(("Failed to decompress data\n"));
1123                    }
1124    
1125                  xfree(bmpdata);                  xfree(bmpdata);
1126          }          }
1127  }  }
1128    
1129  /* Process a palette update */  /* Process a palette update */
1130  static void  void
1131  process_palette(STREAM s)  process_palette(STREAM s)
1132  {  {
1133          COLOURENTRY *entry;          COLOURENTRY *entry;
# Line 610  process_palette(STREAM s) Line 1139  process_palette(STREAM s)
1139          in_uint16_le(s, map.ncolours);          in_uint16_le(s, map.ncolours);
1140          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
1141    
1142          map.colours = xmalloc(3 * map.ncolours);          map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
1143    
1144            DEBUG(("PALETTE(c=%d)\n", map.ncolours));
1145    
1146          for (i = 0; i < map.ncolours; i++)          for (i = 0; i < map.ncolours; i++)
1147          {          {
# Line 630  process_palette(STREAM s) Line 1161  process_palette(STREAM s)
1161  static void  static void
1162  process_update_pdu(STREAM s)  process_update_pdu(STREAM s)
1163  {  {
1164          uint16 update_type;          uint16 update_type, count;
1165    
1166          in_uint16_le(s, update_type);          in_uint16_le(s, update_type);
1167    
1168            ui_begin_update();
1169          switch (update_type)          switch (update_type)
1170          {          {
1171                  case RDP_UPDATE_ORDERS:                  case RDP_UPDATE_ORDERS:
1172                          process_orders(s);                          in_uint8s(s, 2);        /* pad */
1173                            in_uint16_le(s, count);
1174                            in_uint8s(s, 2);        /* pad */
1175                            process_orders(s, count);
1176                          break;                          break;
1177    
1178                  case RDP_UPDATE_BITMAP:                  case RDP_UPDATE_BITMAP:
# Line 654  process_update_pdu(STREAM s) Line 1189  process_update_pdu(STREAM s)
1189                  default:                  default:
1190                          unimpl("update %d\n", update_type);                          unimpl("update %d\n", update_type);
1191          }          }
1192            ui_end_update();
1193    }
1194    
1195    /* Process a disconnect PDU */
1196    void
1197    process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
1198    {
1199            in_uint32_le(s, *ext_disc_reason);
1200    
1201            DEBUG(("Received disconnect PDU\n"));
1202  }  }
1203    
1204  /* Process data PDU */  /* Process data PDU */
1205  static void  static BOOL
1206  process_data_pdu(STREAM s)  process_data_pdu(STREAM s, uint32 * ext_disc_reason)
1207  {  {
1208          uint8 data_pdu_type;          uint8 data_pdu_type;
1209            uint8 ctype;
1210            uint16 clen;
1211            uint32 len;
1212    
1213            uint32 roff, rlen;
1214    
1215          in_uint8s(s, 8);        /* shareid, pad, streamid, length */          struct stream *ns = &(g_mppc_dict.ns);
1216    
1217            in_uint8s(s, 6);        /* shareid, pad, streamid */
1218            in_uint16(s, len);
1219          in_uint8(s, data_pdu_type);          in_uint8(s, data_pdu_type);
1220          in_uint8s(s, 3);        /* compress_type, compress_len */          in_uint8(s, ctype);
1221            in_uint16(s, clen);
1222            clen -= 18;
1223    
1224            if (ctype & RDP_MPPC_COMPRESSED)
1225            {
1226                    if (len > RDP_MPPC_DICT_SIZE)
1227                            error("error decompressed packet size exceeds max\n");
1228                    if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1229                            error("error while decompressing packet\n");
1230    
1231                    /* len -= 18; */
1232    
1233                    /* allocate memory and copy the uncompressed data into the temporary stream */
1234                    ns->data = (uint8 *) xrealloc(ns->data, rlen);
1235    
1236                    memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
1237    
1238                    ns->size = rlen;
1239                    ns->end = (ns->data + ns->size);
1240                    ns->p = ns->data;
1241                    ns->rdp_hdr = ns->p;
1242    
1243                    s = ns;
1244            }
1245    
1246          switch (data_pdu_type)          switch (data_pdu_type)
1247          {          {
# Line 673  process_data_pdu(STREAM s) Line 1249  process_data_pdu(STREAM s)
1249                          process_update_pdu(s);                          process_update_pdu(s);
1250                          break;                          break;
1251    
1252                    case RDP_DATA_PDU_CONTROL:
1253                            DEBUG(("Received Control PDU\n"));
1254                            break;
1255    
1256                    case RDP_DATA_PDU_SYNCHRONISE:
1257                            DEBUG(("Received Sync PDU\n"));
1258                            break;
1259    
1260                  case RDP_DATA_PDU_POINTER:                  case RDP_DATA_PDU_POINTER:
1261                          process_pointer_pdu(s);                          process_pointer_pdu(s);
1262                          break;                          break;
# Line 682  process_data_pdu(STREAM s) Line 1266  process_data_pdu(STREAM s)
1266                          break;                          break;
1267    
1268                  case RDP_DATA_PDU_LOGON:                  case RDP_DATA_PDU_LOGON:
1269                            DEBUG(("Received Logon PDU\n"));
1270                          /* User logged on */                          /* User logged on */
1271                          break;                          break;
1272    
1273                    case RDP_DATA_PDU_DISCONNECT:
1274                            process_disconnect_pdu(s, ext_disc_reason);
1275                            return True;
1276    
1277                  default:                  default:
1278                          unimpl("data PDU %d\n", data_pdu_type);                          unimpl("data PDU %d\n", data_pdu_type);
1279          }          }
1280            return False;
1281  }  }
1282    
1283  /* Process incoming packets */  /* Process incoming packets */
1284    /* nevers gets out of here till app is done */
1285  void  void
1286  rdp_main_loop(void)  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1287    {
1288            while (rdp_loop(deactivated, ext_disc_reason))
1289                    ;
1290    }
1291    
1292    /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1293    BOOL
1294    rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1295  {  {
1296          uint8 type;          uint8 type;
1297            BOOL disc = False;      /* True when a disconnect PDU was received */
1298            BOOL cont = True;
1299          STREAM s;          STREAM s;
1300    
1301          while ((s = rdp_recv(&type)) != NULL)          while (cont)
1302          {          {
1303                    s = rdp_recv(&type);
1304                    if (s == NULL)
1305                            return False;
1306                  switch (type)                  switch (type)
1307                  {                  {
1308                          case RDP_PDU_DEMAND_ACTIVE:                          case RDP_PDU_DEMAND_ACTIVE:
1309                                  process_demand_active(s);                                  process_demand_active(s);
1310                                    *deactivated = False;
1311                                  break;                                  break;
   
1312                          case RDP_PDU_DEACTIVATE:                          case RDP_PDU_DEACTIVATE:
1313                                    DEBUG(("RDP_PDU_DEACTIVATE\n"));
1314                                    *deactivated = True;
1315                                  break;                                  break;
   
1316                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1317                                  process_data_pdu(s);                                  disc = process_data_pdu(s, ext_disc_reason);
1318                                    break;
1319                            case 0:
1320                                  break;                                  break;
   
1321                          default:                          default:
1322                                  unimpl("PDU %d\n", type);                                  unimpl("PDU %d\n", type);
1323                  }                  }
1324                    if (disc)
1325                            return False;
1326                    cont = g_next_packet < s->end;
1327          }          }
1328            return True;
1329  }  }
1330    
1331  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */
# Line 723  BOOL Line 1333  BOOL
1333  rdp_connect(char *server, uint32 flags, char *domain, char *password,  rdp_connect(char *server, uint32 flags, char *domain, char *password,
1334              char *command, char *directory)              char *command, char *directory)
1335  {  {
1336          if (!sec_connect(server))          if (!sec_connect(server, g_username))
1337                  return False;                  return False;
1338    
1339          rdp_send_logon_info(flags, domain, username, password, command, directory);          rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1340          return True;          return True;
1341  }  }
1342    

Legend:
Removed from v.260  
changed lines
  Added in v.886

  ViewVC Help
Powered by ViewVC 1.1.26