/[rdesktop]/sourceforge.net/trunk/rdesktop/rdp.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/rdp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

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

  ViewVC Help
Powered by ViewVC 1.1.26