/[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 513 by matthewc, Tue Oct 28 01:44:48 2003 UTC revision 828 by stargo, Sun Mar 6 21:11:18 2005 UTC
# Line 1  Line 1 
1  /* -*- c-basic-offset: 8 -*-  /* -*- 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
# Line 18  Line 18 
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
21    #include <time.h>
22  #include "rdesktop.h"  #include "rdesktop.h"
23    
24  extern uint16 g_mcs_userid;  extern uint16 g_mcs_userid;
# Line 28  extern BOOL g_encryption; Line 29  extern BOOL g_encryption;
29  extern BOOL g_desktop_save;  extern BOOL g_desktop_save;
30  extern BOOL g_use_rdp5;  extern BOOL g_use_rdp5;
31  extern uint16 g_server_rdp_version;  extern uint16 g_server_rdp_version;
32    extern uint32 g_rdp5_performanceflags;
33  extern int g_server_bpp;  extern int g_server_bpp;
34    extern int g_width;
35    extern int g_height;
36    extern BOOL g_bitmap_cache;
37    extern BOOL g_bitmap_cache_persist_enable;
38    
39  uint8 *g_next_packet;  uint8 *g_next_packet;
40  uint32 g_rdp_shareid;  uint32 g_rdp_shareid;
41    
42    extern RDPCOMP g_mppc_dict;
43    
44  #if WITH_DEBUG  #if WITH_DEBUG
45  static uint32 g_packetno;  static uint32 g_packetno;
46  #endif  #endif
# Line 43  rdp_recv(uint8 * type) Line 51  rdp_recv(uint8 * type)
51  {  {
52          static STREAM rdp_s;          static STREAM rdp_s;
53          uint16 length, pdu_type;          uint16 length, pdu_type;
54            uint8 rdpver;
55    
56          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))
57          {          {
58                  rdp_s = sec_recv();                  rdp_s = sec_recv(&rdpver);
59                  if (rdp_s == NULL)                  if (rdp_s == NULL)
60                          return NULL;                          return NULL;
61                    if (rdpver == 0xff)
62                    {
63                            g_next_packet = rdp_s->end;
64                            *type = 0;
65                            return rdp_s;
66                    }
67                    else if (rdpver != 3)
68                    {
69                            /* rdp5_process should move g_next_packet ok */
70                            rdp5_process(rdp_s);
71                            *type = 0;
72                            return rdp_s;
73                    }
74    
75                  g_next_packet = rdp_s->p;                  g_next_packet = rdp_s->p;
76          }          }
# Line 131  rdp_out_unistr(STREAM s, char *string, i Line 153  rdp_out_unistr(STREAM s, char *string, i
153          s->p += len;          s->p += len;
154  }  }
155    
156    /* Input a string in Unicode
157     *
158     * Returns str_len of string
159     */
160    int
161    rdp_in_unistr(STREAM s, char *string, int uni_len)
162    {
163            int i = 0;
164    
165            while (i < uni_len / 2)
166            {
167                    in_uint8a(s, &string[i++], 1);
168                    in_uint8s(s, 1);
169            }
170    
171            return i - 1;
172    }
173    
174    
175  /* Parse a logon info packet */  /* Parse a logon info packet */
176  static void  static void
177  rdp_send_logon_info(uint32 flags, char *domain, char *user,  rdp_send_logon_info(uint32 flags, char *domain, char *user,
178                      char *password, char *program, char *directory)                      char *password, char *program, char *directory)
179  {  {
180            char *ipaddr = tcp_get_address();
181          int len_domain = 2 * strlen(domain);          int len_domain = 2 * strlen(domain);
182          int len_user = 2 * strlen(user);          int len_user = 2 * strlen(user);
183          int len_password = 2 * strlen(password);          int len_password = 2 * strlen(password);
184          int len_program = 2 * strlen(program);          int len_program = 2 * strlen(program);
185          int len_directory = 2 * strlen(directory);          int len_directory = 2 * strlen(directory);
186          int len_ip = 2 * strlen("127.0.0.1");          int len_ip = 2 * strlen(ipaddr);
187          int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");          int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
188          int packetlen = 0;          int packetlen = 0;
189          uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;          uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
190          STREAM s;          STREAM s;
191            time_t t = time(NULL);
192            time_t tzone;
193    
194    #if 0
195            /* enable rdp compression */
196            /* some problems still exist with rdp5 */
197            flags |= RDP_COMPRESSION;
198    #endif
199    
200          if (!g_use_rdp5 || 1 == g_server_rdp_version)          if (!g_use_rdp5 || 1 == g_server_rdp_version)
201          {          {
# Line 169  rdp_send_logon_info(uint32 flags, char * Line 219  rdp_send_logon_info(uint32 flags, char *
219          }          }
220          else          else
221          {          {
222    
223                  flags |= RDP_LOGON_BLOB;                  flags |= RDP_LOGON_BLOB;
224                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
225                  packetlen = 4 + // Unknown uint32                  packetlen = 4 + /* Unknown uint32 */
226                          4 +     // flags                          4 +     /* flags */
227                          2 +     // len_domain                          2 +     /* len_domain */
228                          2 +     // len_user                          2 +     /* len_user */
229                          (flags & RDP_LOGON_AUTO ? 2 : 0) +      // len_password                          (flags & RDP_LOGON_AUTO ? 2 : 0) +      /* len_password */
230                          (flags & RDP_LOGON_BLOB ? 2 : 0) +      // Length of BLOB                          (flags & RDP_LOGON_BLOB ? 2 : 0) +      /* Length of BLOB */
231                          2 +     // len_program                          2 +     /* len_program */
232                          2 +     // len_directory                          2 +     /* len_directory */
233                          (0 < len_domain ? len_domain : 2) +     // domain                          (0 < len_domain ? len_domain : 2) +     /* domain */
234                          len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 +    // We have no 512 byte BLOB. Perhaps we must?                          len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 +    /* We have no 512 byte BLOB. Perhaps we must? */
235                          (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + // After the BLOB is a unknown int16. If there is a BLOB, that is.                          (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + /* After the BLOB is a unknown int16. If there is a BLOB, that is. */
236                          (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 +     // Unknown (2)                          (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 +     /* Unknown (2) */
237                          2 +     // Client ip length                          2 +     /* Client ip length */
238                          len_ip +        // Client ip                          len_ip +        /* Client ip */
239                          2 +     // DLL string length                          2 +     /* DLL string length */
240                          len_dll +       // DLL string                          len_dll +       /* DLL string */
241                          2 +     // Unknown                          2 +     /* Unknown */
242                          2 +     // Unknown                          2 +     /* Unknown */
243                          64 +    // Time zone #0                          64 +    /* Time zone #0 */
244                          2 +     // Unknown                          2 +     /* Unknown */
245                          64 +    // Time zone #1                          64 +    /* Time zone #1 */
246                          32;     // Unknown                          32;     /* Unknown */
247    
248                  s = sec_init(sec_flags, packetlen);                  s = sec_init(sec_flags, packetlen);
249                  DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));                  DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
250    
251                  out_uint32(s, 0);       // Unknown                  out_uint32(s, 0);       /* Unknown */
252                  out_uint32_le(s, flags);                  out_uint32_le(s, flags);
253                  out_uint16_le(s, len_domain);                  out_uint16_le(s, len_domain);
254                  out_uint16_le(s, len_user);                  out_uint16_le(s, len_user);
# Line 243  rdp_send_logon_info(uint32 flags, char * Line 294  rdp_send_logon_info(uint32 flags, char *
294                          out_uint16_le(s, 0);                          out_uint16_le(s, 0);
295                  }                  }
296                  out_uint16_le(s, 2);                  out_uint16_le(s, 2);
297                  out_uint16_le(s, len_ip + 2);   // Length of client ip                  out_uint16_le(s, len_ip + 2);   /* Length of client ip */
298                  rdp_out_unistr(s, "127.0.0.1", len_ip);                  rdp_out_unistr(s, ipaddr, len_ip);
299                  out_uint16_le(s, len_dll + 2);                  out_uint16_le(s, len_dll + 2);
300                  rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);                  rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
301                  out_uint16_le(s, 0xffc4);  
302                  out_uint16_le(s, 0xffff);                  tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
303                    out_uint32_le(s, tzone);
304    
305                  rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));                  rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
306                  out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));                  out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
307    
   
308                  out_uint32_le(s, 0x0a0000);                  out_uint32_le(s, 0x0a0000);
309                  out_uint32_le(s, 0x050000);                  out_uint32_le(s, 0x050000);
310                  out_uint32_le(s, 3);                  out_uint32_le(s, 3);
# Line 268  rdp_send_logon_info(uint32 flags, char * Line 320  rdp_send_logon_info(uint32 flags, char *
320                  out_uint32(s, 0);                  out_uint32(s, 0);
321                  out_uint32_le(s, 0xffffffc4);                  out_uint32_le(s, 0xffffffc4);
322                  out_uint32_le(s, 0xfffffffe);                  out_uint32_le(s, 0xfffffffe);
323                  out_uint32_le(s, 0x0f);                  out_uint32_le(s, g_rdp5_performanceflags);
324                  out_uint32(s, 0);                  out_uint32(s, 0);
325    
326    
# Line 329  rdp_send_input(uint32 time, uint16 messa Line 381  rdp_send_input(uint32 time, uint16 messa
381          rdp_send_data(s, RDP_DATA_PDU_INPUT);          rdp_send_data(s, RDP_DATA_PDU_INPUT);
382  }  }
383    
384    /* Inform the server on the contents of the persistent bitmap cache */
385    static void
386    rdp_enum_bmpcache2(void)
387    {
388            STREAM s;
389            uint8 idlist[BMPCACHE2_NUM_PSTCELLS * sizeof(BITMAP_ID)];
390            uint32 nids, offset, count, flags;
391    
392            offset = 0;
393            nids = pstcache_enumerate(2, idlist);
394    
395            while (offset < nids)
396            {
397                    count = MIN(nids - offset, 169);
398    
399                    s = rdp_init_data(24 + count * sizeof(BITMAP_ID));
400    
401                    flags = 0;
402                    if (offset == 0)
403                            flags |= PDU_FLAG_FIRST;
404                    if (nids - offset <= 169)
405                            flags |= PDU_FLAG_LAST;
406    
407                    /* header */
408                    out_uint32_le(s, 0);
409                    out_uint16_le(s, count);
410                    out_uint16_le(s, 0);
411                    out_uint16_le(s, 0);
412                    out_uint16_le(s, 0);
413                    out_uint16_le(s, 0);
414                    out_uint16_le(s, nids);
415                    out_uint32_le(s, 0);
416                    out_uint32_le(s, flags);
417    
418                    /* list */
419                    out_uint8a(s, idlist + offset * sizeof(BITMAP_ID), count * sizeof(BITMAP_ID));
420    
421                    s_mark_end(s);
422                    rdp_send_data(s, 0x2b);
423    
424                    offset += 169;
425            }
426    }
427    
428  /* Send an (empty) font information PDU */  /* Send an (empty) font information PDU */
429  static void  static void
430  rdp_send_fonts(uint16 seq)  rdp_send_fonts(uint16 seq)
# Line 338  rdp_send_fonts(uint16 seq) Line 434  rdp_send_fonts(uint16 seq)
434          s = rdp_init_data(8);          s = rdp_init_data(8);
435    
436          out_uint16(s, 0);       /* number of fonts */          out_uint16(s, 0);       /* number of fonts */
437          out_uint16_le(s, 0x3e); /* unknown */          out_uint16_le(s, 0);    /* pad? */
438          out_uint16_le(s, seq);  /* unknown */          out_uint16_le(s, seq);  /* unknown */
439          out_uint16_le(s, 0x32); /* entry size */          out_uint16_le(s, 0x32); /* entry size */
440    
# Line 379  rdp_out_bitmap_caps(STREAM s) Line 475  rdp_out_bitmap_caps(STREAM s)
475          out_uint16_le(s, RDP_CAPSET_BITMAP);          out_uint16_le(s, RDP_CAPSET_BITMAP);
476          out_uint16_le(s, RDP_CAPLEN_BITMAP);          out_uint16_le(s, RDP_CAPLEN_BITMAP);
477    
478          out_uint16_le(s, 8);    /* Preferred BPP */          out_uint16_le(s, g_server_bpp); /* Preferred BPP */
479          out_uint16_le(s, 1);    /* Receive 1 BPP */          out_uint16_le(s, 1);    /* Receive 1 BPP */
480          out_uint16_le(s, 1);    /* Receive 4 BPP */          out_uint16_le(s, 1);    /* Receive 4 BPP */
481          out_uint16_le(s, 1);    /* Receive 8 BPP */          out_uint16_le(s, 1);    /* Receive 8 BPP */
482          out_uint16_le(s, 800);  /* Desktop width */          out_uint16_le(s, 800);  /* Desktop width */
483          out_uint16_le(s, 600);  /* Desktop height */          out_uint16_le(s, 600);  /* Desktop height */
484          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
485          out_uint16(s, 0);       /* Allow resize */          out_uint16(s, 1);       /* Allow resize */
486          out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */          out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
487          out_uint16(s, 0);       /* Unknown */          out_uint16(s, 0);       /* Unknown */
488          out_uint16_le(s, 1);    /* Unknown */          out_uint16_le(s, 1);    /* Unknown */
# Line 404  rdp_out_order_caps(STREAM s) Line 500  rdp_out_order_caps(STREAM s)
500          order_caps[0] = 1;      /* dest blt */          order_caps[0] = 1;      /* dest blt */
501          order_caps[1] = 1;      /* pat blt */          order_caps[1] = 1;      /* pat blt */
502          order_caps[2] = 1;      /* screen blt */          order_caps[2] = 1;      /* screen blt */
503          order_caps[3] = 1;      /* required for memblt? */          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
504          order_caps[8] = 1;      /* line */          order_caps[8] = 1;      /* line */
505          order_caps[9] = 1;      /* line */          order_caps[9] = 1;      /* line */
506          order_caps[10] = 1;     /* rect */          order_caps[10] = 1;     /* rect */
# Line 449  rdp_out_bmpcache_caps(STREAM s) Line 545  rdp_out_bmpcache_caps(STREAM s)
545          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
546  }  }
547    
548    /* Output bitmap cache v2 capability set */
549    static void
550    rdp_out_bmpcache2_caps(STREAM s)
551    {
552            out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
553            out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
554    
555            out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
556    
557            out_uint16_le(s, 0x0300);       /* flags? number of caches? */
558    
559            out_uint32_le(s, BMPCACHE2_C0_CELLS);
560            out_uint32_le(s, BMPCACHE2_C1_CELLS);
561            if (pstcache_init(2))
562            {
563                    out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
564            }
565            else
566            {
567                    out_uint32_le(s, BMPCACHE2_C2_CELLS);
568            }
569            out_uint8s(s, 20);      /* other bitmap caches not used */
570    }
571    
572  /* Output control capability set */  /* Output control capability set */
573  static void  static void
574  rdp_out_control_caps(STREAM s)  rdp_out_control_caps(STREAM s)
# Line 508  rdp_out_colcache_caps(STREAM s) Line 628  rdp_out_colcache_caps(STREAM s)
628          out_uint16(s, 0);       /* pad */          out_uint16(s, 0);       /* pad */
629  }  }
630    
631  static uint8 canned_caps[] = {  static uint8 caps_0x0d[] = {
632          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
633          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
634          0x00, 0x00, 0x00, 0x00, 0x00,          0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
642          0x0C, 0x00, 0x08, 0x00, 0x01,          0x00, 0x00, 0x00, 0x00
         0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,  
         0x10, 0x00, 0x34, 0x00, 0xFE,  
         0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,  
         0xFE, 0x00, 0x08, 0x00, 0xFE,  
         0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,  
         0xFE, 0x00, 0x80, 0x00, 0xFE,  
         0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,  
         0x02, 0x00, 0x00, 0x00  
643  };  };
644    
645  /* Output unknown capability sets (number 13, 12, 14 and 16) */  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
646    
647    static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
648    
649    static uint8 caps_0x10[] = {
650            0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
651            0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
652            0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
653            0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
654            0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
655            0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
656    };
657    
658    /* Output unknown capability sets */
659  static void  static void
660  rdp_out_unknown_caps(STREAM s)  rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
661  {  {
662          out_uint16_le(s, RDP_CAPSET_UNKNOWN);          out_uint16_le(s, id);
663          out_uint16_le(s, 0x58);          out_uint16_le(s, length);
664    
665          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);          out_uint8p(s, caps, length - 4);
666  }  }
667    
668  #define RDP5_FLAG 0x0030  #define RDP5_FLAG 0x0030
# Line 551  rdp_send_confirm_active(void) Line 676  rdp_send_confirm_active(void)
676                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
677                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
678                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
679                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
680                    0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
681                    4 /* w2k fix, why? */ ;
682    
683          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
684    
# Line 571  rdp_send_confirm_active(void) Line 698  rdp_send_confirm_active(void)
698          rdp_out_general_caps(s);          rdp_out_general_caps(s);
699          rdp_out_bitmap_caps(s);          rdp_out_bitmap_caps(s);
700          rdp_out_order_caps(s);          rdp_out_order_caps(s);
701          rdp_out_bmpcache_caps(s);          g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
702          rdp_out_colcache_caps(s);          rdp_out_colcache_caps(s);
703          rdp_out_activate_caps(s);          rdp_out_activate_caps(s);
704          rdp_out_control_caps(s);          rdp_out_control_caps(s);
705          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
706          rdp_out_share_caps(s);          rdp_out_share_caps(s);
707          rdp_out_unknown_caps(s);  
708            rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
709            rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
710            rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
711            rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
712    
713          s_mark_end(s);          s_mark_end(s);
714          sec_send(s, sec_flags);          sec_send(s, sec_flags);
715  }  }
716    
717    /* Process a general capability set */
718    static void
719    rdp_process_general_caps(STREAM s)
720    {
721            uint16 pad2octetsB;     /* rdp5 flags? */
722    
723            in_uint8s(s, 10);
724            in_uint16_le(s, pad2octetsB);
725    
726            if (!pad2octetsB)
727                    g_use_rdp5 = False;
728    }
729    
730    /* Process a bitmap capability set */
731    static void
732    rdp_process_bitmap_caps(STREAM s)
733    {
734            uint16 width, height, bpp;
735    
736            in_uint16_le(s, bpp);
737            in_uint8s(s, 6);
738    
739            in_uint16_le(s, width);
740            in_uint16_le(s, height);
741    
742            DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));
743    
744            /*
745             * The server may limit bpp and change the size of the desktop (for
746             * example when shadowing another session).
747             */
748            if (g_server_bpp != bpp)
749            {
750                    warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
751                    g_server_bpp = bpp;
752            }
753            if (g_width != width || g_height != height)
754            {
755                    warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
756                            width, height);
757                    g_width = width;
758                    g_height = height;
759                    ui_resize_window();
760            }
761    }
762    
763    /* Process server capabilities */
764    void
765    rdp_process_server_caps(STREAM s, uint16 length)
766    {
767            int n;
768            uint8 *next, *start;
769            uint16 ncapsets, capset_type, capset_length;
770    
771            start = s->p;
772    
773            in_uint16_le(s, ncapsets);
774            in_uint8s(s, 2);        /* pad */
775    
776            for (n = 0; n < ncapsets; n++)
777            {
778                    if (s->p > start + length)
779                            return;
780    
781                    in_uint16_le(s, capset_type);
782                    in_uint16_le(s, capset_length);
783    
784                    next = s->p + capset_length - 4;
785    
786                    switch (capset_type)
787                    {
788                            case RDP_CAPSET_GENERAL:
789                                    rdp_process_general_caps(s);
790                                    break;
791    
792                            case RDP_CAPSET_BITMAP:
793                                    rdp_process_bitmap_caps(s);
794                                    break;
795                    }
796    
797                    s->p = next;
798            }
799    }
800    
801  /* Respond to a demand active PDU */  /* Respond to a demand active PDU */
802  static void  static void
803  process_demand_active(STREAM s)  process_demand_active(STREAM s)
804  {  {
805          uint8 type;          uint8 type;
806            uint16 len_src_descriptor, len_combined_caps;
807    
808          in_uint32_le(s, g_rdp_shareid);          in_uint32_le(s, g_rdp_shareid);
809            in_uint16_le(s, len_src_descriptor);
810            in_uint16_le(s, len_combined_caps);
811            in_uint8s(s, len_src_descriptor);
812    
813          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
814            rdp_process_server_caps(s, len_combined_caps);
815    
816          rdp_send_confirm_active();          rdp_send_confirm_active();
817          rdp_send_synchronise();          rdp_send_synchronise();
# Line 600  process_demand_active(STREAM s) Line 820  process_demand_active(STREAM s)
820          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
821          rdp_recv(&type);        /* RDP_CTL_COOPERATE */          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
822          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
823          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);
824          rdp_send_fonts(1);  
825          rdp_send_fonts(2);          if (g_use_rdp5)
826          rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 */          {
827                    rdp_enum_bmpcache2();
828                    rdp_send_fonts(3);
829            }
830            else
831            {
832                    rdp_send_fonts(1);
833                    rdp_send_fonts(2);
834            }
835    
836            rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
837          reset_order_state();          reset_order_state();
838  }  }
839    
# Line 803  process_update_pdu(STREAM s) Line 1033  process_update_pdu(STREAM s)
1033    
1034          in_uint16_le(s, update_type);          in_uint16_le(s, update_type);
1035    
1036            ui_begin_update();
1037          switch (update_type)          switch (update_type)
1038          {          {
1039                  case RDP_UPDATE_ORDERS:                  case RDP_UPDATE_ORDERS:
# Line 826  process_update_pdu(STREAM s) Line 1057  process_update_pdu(STREAM s)
1057                  default:                  default:
1058                          unimpl("update %d\n", update_type);                          unimpl("update %d\n", update_type);
1059          }          }
1060            ui_end_update();
1061    }
1062    
1063    /* Process a disconnect PDU */
1064    void
1065    process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
1066    {
1067            in_uint32_le(s, *ext_disc_reason);
1068    
1069            DEBUG(("Received disconnect PDU\n"));
1070  }  }
1071    
1072  /* Process data PDU */  /* Process data PDU */
1073  static void  static BOOL
1074  process_data_pdu(STREAM s)  process_data_pdu(STREAM s, uint32 * ext_disc_reason)
1075  {  {
1076          uint8 data_pdu_type;          uint8 data_pdu_type;
1077            uint8 ctype;
1078            uint16 clen;
1079            uint32 len;
1080    
1081            uint32 roff, rlen;
1082    
1083          in_uint8s(s, 8);        /* shareid, pad, streamid, length */          struct stream *ns = &(g_mppc_dict.ns);
1084    
1085            in_uint8s(s, 6);        /* shareid, pad, streamid */
1086            in_uint16(s, len);
1087          in_uint8(s, data_pdu_type);          in_uint8(s, data_pdu_type);
1088          in_uint8s(s, 3);        /* compress_type, compress_len */          in_uint8(s, ctype);
1089            in_uint16(s, clen);
1090            clen -= 18;
1091    
1092            if (ctype & RDP_MPPC_COMPRESSED)
1093            {
1094                    if (len > RDP_MPPC_DICT_SIZE)
1095                            error("error decompressed packet size exceeds max\n");
1096                    if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1097                            error("error while decompressing packet\n");
1098    
1099                    //len -= 18;
1100    
1101                    /* allocate memory and copy the uncompressed data into the temporary stream */
1102                    ns->data = (uint8 *) xrealloc(ns->data, rlen);
1103    
1104                    memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
1105    
1106                    ns->size = rlen;
1107                    ns->end = (ns->data + ns->size);
1108                    ns->p = ns->data;
1109                    ns->rdp_hdr = ns->p;
1110    
1111                    s = ns;
1112            }
1113    
1114          switch (data_pdu_type)          switch (data_pdu_type)
1115          {          {
# Line 845  process_data_pdu(STREAM s) Line 1117  process_data_pdu(STREAM s)
1117                          process_update_pdu(s);                          process_update_pdu(s);
1118                          break;                          break;
1119    
1120                    case RDP_DATA_PDU_CONTROL:
1121                            DEBUG(("Received Control PDU\n"));
1122                            break;
1123    
1124                    case RDP_DATA_PDU_SYNCHRONISE:
1125                            DEBUG(("Received Sync PDU\n"));
1126                            break;
1127    
1128                  case RDP_DATA_PDU_POINTER:                  case RDP_DATA_PDU_POINTER:
1129                          process_pointer_pdu(s);                          process_pointer_pdu(s);
1130                          break;                          break;
# Line 858  process_data_pdu(STREAM s) Line 1138  process_data_pdu(STREAM s)
1138                          /* User logged on */                          /* User logged on */
1139                          break;                          break;
1140    
1141                    case RDP_DATA_PDU_DISCONNECT:
1142                            process_disconnect_pdu(s, ext_disc_reason);
1143                            return True;
1144    
1145                  default:                  default:
1146                          unimpl("data PDU %d\n", data_pdu_type);                          unimpl("data PDU %d\n", data_pdu_type);
1147          }          }
1148            return False;
1149  }  }
1150    
1151  /* Process incoming packets */  /* Process incoming packets */
1152    /* nevers gets out of here till app is done */
1153    void
1154    rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1155    {
1156            while (rdp_loop(deactivated, ext_disc_reason))
1157                    ;
1158    }
1159    
1160    /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1161  BOOL  BOOL
1162  rdp_main_loop(void)  rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1163  {  {
1164          uint8 type;          uint8 type;
1165            BOOL disc = False;      /* True when a disconnect PDU was received */
1166            BOOL cont = True;
1167          STREAM s;          STREAM s;
1168    
1169          while ((s = rdp_recv(&type)) != NULL)          while (cont)
1170          {          {
1171                    s = rdp_recv(&type);
1172                    if (s == NULL)
1173                            return False;
1174                  switch (type)                  switch (type)
1175                  {                  {
1176                          case RDP_PDU_DEMAND_ACTIVE:                          case RDP_PDU_DEMAND_ACTIVE:
1177                                  process_demand_active(s);                                  process_demand_active(s);
1178                                    *deactivated = False;
1179                                  break;                                  break;
   
1180                          case RDP_PDU_DEACTIVATE:                          case RDP_PDU_DEACTIVATE:
1181                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));
1182                                  /* We thought we could detect a clean                                  *deactivated = True;
                                    shutdown of the session by this  
                                    packet, but it seems Windows 2003  
                                    is sending us one of these when we  
                                    reconnect to a disconnected session  
                                    return True; */  
1183                                  break;                                  break;
   
1184                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1185                                  process_data_pdu(s);                                  disc = process_data_pdu(s, ext_disc_reason);
1186                                  break;                                  break;
   
1187                          case 0:                          case 0:
1188                                  break;                                  break;
   
1189                          default:                          default:
1190                                  unimpl("PDU %d\n", type);                                  unimpl("PDU %d\n", type);
1191                  }                  }
1192                    if (disc)
1193                            return False;
1194                    cont = g_next_packet < s->end;
1195          }          }
1196          return True;          return True;
         /* We want to detect if we got a clean shutdown, but we  
            can't. Se above.    
            return False;  */  
1197  }  }
1198    
1199  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */

Legend:
Removed from v.513  
changed lines
  Added in v.828

  ViewVC Help
Powered by ViewVC 1.1.26