/[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 522 by matthewc, Wed Oct 29 04:18:00 2003 UTC revision 863 by stargo, Mon Mar 14 17:47:46 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 <errno.h>
23    #include <unistd.h>
24  #include "rdesktop.h"  #include "rdesktop.h"
25    
26    #ifdef HAVE_ICONV
27    #ifdef HAVE_ICONV_H
28    #include <iconv.h>
29    #endif
30    
31    #ifndef ICONV_CONST
32    #define ICONV_CONST ""
33    #endif
34    #endif
35    
36  extern uint16 g_mcs_userid;  extern uint16 g_mcs_userid;
37  extern char g_username[16];  extern char g_username[64];
38    extern char g_codepage[16];
39  extern BOOL g_bitmap_compression;  extern BOOL g_bitmap_compression;
40  extern BOOL g_orders;  extern BOOL g_orders;
41  extern BOOL g_encryption;  extern BOOL g_encryption;
42  extern BOOL g_desktop_save;  extern BOOL g_desktop_save;
43    extern BOOL g_polygon_ellipse_orders;
44  extern BOOL g_use_rdp5;  extern BOOL g_use_rdp5;
45  extern uint16 g_server_rdp_version;  extern uint16 g_server_rdp_version;
46    extern uint32 g_rdp5_performanceflags;
47  extern int g_server_bpp;  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  uint8 *g_next_packet;  uint8 *g_next_packet;
54  uint32 g_rdp_shareid;  uint32 g_rdp_shareid;
55    
56    extern RDPCOMP g_mppc_dict;
57    
58  #if WITH_DEBUG  #if WITH_DEBUG
59  static uint32 g_packetno;  static uint32 g_packetno;
60  #endif  #endif
# Line 43  rdp_recv(uint8 * type) Line 65  rdp_recv(uint8 * type)
65  {  {
66          static STREAM rdp_s;          static STREAM rdp_s;
67          uint16 length, pdu_type;          uint16 length, pdu_type;
68            uint8 rdpver;
69    
70          if ((rdp_s == NULL) || (g_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                  g_next_packet = rdp_s->p;                  g_next_packet = rdp_s->p;
90          }          }
# Line 118  rdp_send_data(STREAM s, uint8 data_pdu_t Line 154  rdp_send_data(STREAM s, uint8 data_pdu_t
154  void  void
155  rdp_out_unistr(STREAM s, char *string, int len)  rdp_out_unistr(STREAM s, char *string, int len)
156  {  {
157    #ifdef HAVE_ICONV
158            size_t ibl = strlen(string), obl = len + 2;
159            static iconv_t iconv_h = (iconv_t) - 1;
160            char *pin = string, *pout = s->p;
161    
162            memset(pout, 0, len + 4);
163    
164            if (iconv_h == (iconv_t) - 1)
165            {
166                    size_t i = 1, o = 4;
167                    if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1)
168                    {
169                            printf("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n",
170                                   g_codepage, WINDOWS_CODEPAGE, (int) iconv_h);
171                            return;
172                    }
173                    if (iconv(iconv_h, (ICONV_CONST char **) &pin, &i, &pout, &o) == (size_t) - 1)
174                    {
175                            iconv_close(iconv_h);
176                            iconv_h = (iconv_t) - 1;
177                            printf("rdp_out_unistr: iconv(1) fail, errno %d\n", errno);
178                            return;
179                    }
180                    pin = string;
181                    pout = (char *) s->p;
182            }
183    
184            if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
185            {
186                    iconv_close(iconv_h);
187                    iconv_h = (iconv_t) - 1;
188                    printf("rdp_out_unistr: iconv(2) fail, errno %d\n", errno);
189                    return;
190            }
191    
192            s->p += len + 2;
193    
194    #else /* HAVE_ICONV undef */
195          int i = 0, j = 0;          int i = 0, j = 0;
196    
197          len += 2;          len += 2;
# Line 129  rdp_out_unistr(STREAM s, char *string, i Line 203  rdp_out_unistr(STREAM s, char *string, i
203          }          }
204    
205          s->p += len;          s->p += len;
206    #endif
207    }
208    
209    /* Input a string in Unicode
210     *
211     * Returns str_len of string
212     */
213    int
214    rdp_in_unistr(STREAM s, char *string, int uni_len)
215    {
216    #ifdef HAVE_ICONV
217            size_t ibl = uni_len, obl = uni_len;
218            char *pin = s->p, *pout = string;
219            static iconv_t iconv_h = (iconv_t) - 1;
220    
221            if (iconv_h == (iconv_t) - 1)
222            {
223                    if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1)
224                    {
225                            printf("rdp_in_unistr: iconv_open[%s -> %s] fail %d\n",
226                                   WINDOWS_CODEPAGE, g_codepage, (int) iconv_h);
227                            return 0;
228                    }
229            }
230    
231            if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
232            {
233                    iconv_close(iconv_h);
234                    iconv_h = (iconv_t) - 1;
235                    printf("rdp_in_unistr: iconv fail, errno %d\n", errno);
236                    return 0;
237            }
238            return pout - string;
239    #else /* HAVE_ICONV undef */
240            int i = 0;
241    
242            while (i < uni_len / 2)
243            {
244                    in_uint8a(s, &string[i++], 1);
245                    in_uint8s(s, 1);
246            }
247    
248            return i - 1;
249    #endif
250  }  }
251    
252    
253  /* Parse a logon info packet */  /* Parse a logon info packet */
254  static void  static void
255  rdp_send_logon_info(uint32 flags, char *domain, char *user,  rdp_send_logon_info(uint32 flags, char *domain, char *user,
256                      char *password, char *program, char *directory)                      char *password, char *program, char *directory)
257  {  {
258            char *ipaddr = tcp_get_address();
259          int len_domain = 2 * strlen(domain);          int len_domain = 2 * strlen(domain);
260          int len_user = 2 * strlen(user);          int len_user = 2 * strlen(user);
261          int len_password = 2 * strlen(password);          int len_password = 2 * strlen(password);
262          int len_program = 2 * strlen(program);          int len_program = 2 * strlen(program);
263          int len_directory = 2 * strlen(directory);          int len_directory = 2 * strlen(directory);
264          int len_ip = 2 * strlen("127.0.0.1");          int len_ip = 2 * strlen(ipaddr);
265          int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");          int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
266          int packetlen = 0;          int packetlen = 0;
267          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;
268          STREAM s;          STREAM s;
269            time_t t = time(NULL);
270            time_t tzone;
271    
272    #if 0
273            /* enable rdp compression */
274            /* some problems still exist with rdp5 */
275            flags |= RDP_COMPRESSION;
276    #endif
277    
278          if (!g_use_rdp5 || 1 == g_server_rdp_version)          if (!g_use_rdp5 || 1 == g_server_rdp_version)
279          {          {
# Line 169  rdp_send_logon_info(uint32 flags, char * Line 297  rdp_send_logon_info(uint32 flags, char *
297          }          }
298          else          else
299          {          {
300    
301                  flags |= RDP_LOGON_BLOB;                  flags |= RDP_LOGON_BLOB;
302                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
303                  packetlen = 4 + // Unknown uint32                  packetlen = 4 + /* Unknown uint32 */
304                          4 +     // flags                          4 +     /* flags */
305                          2 +     // len_domain                          2 +     /* len_domain */
306                          2 +     // len_user                          2 +     /* len_user */
307                          (flags & RDP_LOGON_AUTO ? 2 : 0) +      // len_password                          (flags & RDP_LOGON_AUTO ? 2 : 0) +      /* len_password */
308                          (flags & RDP_LOGON_BLOB ? 2 : 0) +      // Length of BLOB                          (flags & RDP_LOGON_BLOB ? 2 : 0) +      /* Length of BLOB */
309                          2 +     // len_program                          2 +     /* len_program */
310                          2 +     // len_directory                          2 +     /* len_directory */
311                          (0 < len_domain ? len_domain : 2) +     // domain                          (0 < len_domain ? len_domain : 2) +     /* domain */
312                          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? */
313                          (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. */
314                          (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) */
315                          2 +     // Client ip length                          2 +     /* Client ip length */
316                          len_ip +        // Client ip                          len_ip +        /* Client ip */
317                          2 +     // DLL string length                          2 +     /* DLL string length */
318                          len_dll +       // DLL string                          len_dll +       /* DLL string */
319                          2 +     // Unknown                          2 +     /* Unknown */
320                          2 +     // Unknown                          2 +     /* Unknown */
321                          64 +    // Time zone #0                          64 +    /* Time zone #0 */
322                          2 +     // Unknown                          2 +     /* Unknown */
323                          64 +    // Time zone #1                          64 +    /* Time zone #1 */
324                          32;     // Unknown                          32;     /* Unknown */
325    
326                  s = sec_init(sec_flags, packetlen);                  s = sec_init(sec_flags, packetlen);
327                  DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));                  DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
328    
329                  out_uint32(s, 0);       // Unknown                  out_uint32(s, 0);       /* Unknown */
330                  out_uint32_le(s, flags);                  out_uint32_le(s, flags);
331                  out_uint16_le(s, len_domain);                  out_uint16_le(s, len_domain);
332                  out_uint16_le(s, len_user);                  out_uint16_le(s, len_user);
# Line 243  rdp_send_logon_info(uint32 flags, char * Line 372  rdp_send_logon_info(uint32 flags, char *
372                          out_uint16_le(s, 0);                          out_uint16_le(s, 0);
373                  }                  }
374                  out_uint16_le(s, 2);                  out_uint16_le(s, 2);
375                  out_uint16_le(s, len_ip + 2);   // Length of client ip                  out_uint16_le(s, len_ip + 2);   /* Length of client ip */
376                  rdp_out_unistr(s, "127.0.0.1", len_ip);                  rdp_out_unistr(s, ipaddr, len_ip);
377                  out_uint16_le(s, len_dll + 2);                  out_uint16_le(s, len_dll + 2);
378                  rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);                  rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
379                  out_uint16_le(s, 0xffc4);  
380                  out_uint16_le(s, 0xffff);                  tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
381                    out_uint32_le(s, tzone);
382    
383                  rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));                  rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
384                  out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));                  out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
385    
   
386                  out_uint32_le(s, 0x0a0000);                  out_uint32_le(s, 0x0a0000);
387                  out_uint32_le(s, 0x050000);                  out_uint32_le(s, 0x050000);
388                  out_uint32_le(s, 3);                  out_uint32_le(s, 3);
# Line 268  rdp_send_logon_info(uint32 flags, char * Line 398  rdp_send_logon_info(uint32 flags, char *
398                  out_uint32(s, 0);                  out_uint32(s, 0);
399                  out_uint32_le(s, 0xffffffc4);                  out_uint32_le(s, 0xffffffc4);
400                  out_uint32_le(s, 0xfffffffe);                  out_uint32_le(s, 0xfffffffe);
401                  out_uint32_le(s, 0x0f);                  out_uint32_le(s, g_rdp5_performanceflags);
402                  out_uint32(s, 0);                  out_uint32(s, 0);
403    
404    
# Line 329  rdp_send_input(uint32 time, uint16 messa Line 459  rdp_send_input(uint32 time, uint16 messa
459          rdp_send_data(s, RDP_DATA_PDU_INPUT);          rdp_send_data(s, RDP_DATA_PDU_INPUT);
460  }  }
461    
462    /* Inform the server on the contents of the persistent bitmap cache */
463    static void
464    rdp_enum_bmpcache2(void)
465    {
466            STREAM s;
467            HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS];
468            uint32 num_keys, offset, count, flags;
469    
470            offset = 0;
471            num_keys = pstcache_enumerate(2, keylist);
472    
473            while (offset < num_keys)
474            {
475                    count = MIN(num_keys - offset, 169);
476    
477                    s = rdp_init_data(24 + count * sizeof(HASH_KEY));
478    
479                    flags = 0;
480                    if (offset == 0)
481                            flags |= PDU_FLAG_FIRST;
482                    if (num_keys - offset <= 169)
483                            flags |= PDU_FLAG_LAST;
484    
485                    /* header */
486                    out_uint32_le(s, 0);
487                    out_uint16_le(s, count);
488                    out_uint16_le(s, 0);
489                    out_uint16_le(s, 0);
490                    out_uint16_le(s, 0);
491                    out_uint16_le(s, 0);
492                    out_uint16_le(s, num_keys);
493                    out_uint32_le(s, 0);
494                    out_uint32_le(s, flags);
495    
496                    /* list */
497                    out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
498    
499                    s_mark_end(s);
500                    rdp_send_data(s, 0x2b);
501    
502                    offset += 169;
503            }
504    }
505    
506  /* Send an (empty) font information PDU */  /* Send an (empty) font information PDU */
507  static void  static void
508  rdp_send_fonts(uint16 seq)  rdp_send_fonts(uint16 seq)
# Line 338  rdp_send_fonts(uint16 seq) Line 512  rdp_send_fonts(uint16 seq)
512          s = rdp_init_data(8);          s = rdp_init_data(8);
513    
514          out_uint16(s, 0);       /* number of fonts */          out_uint16(s, 0);       /* number of fonts */
515          out_uint16_le(s, 0x3e); /* unknown */          out_uint16_le(s, 0);    /* pad? */
516          out_uint16_le(s, seq);  /* unknown */          out_uint16_le(s, seq);  /* unknown */
517          out_uint16_le(s, 0x32); /* entry size */          out_uint16_le(s, 0x32); /* entry size */
518    
# Line 379  rdp_out_bitmap_caps(STREAM s) Line 553  rdp_out_bitmap_caps(STREAM s)
553          out_uint16_le(s, RDP_CAPSET_BITMAP);          out_uint16_le(s, RDP_CAPSET_BITMAP);
554          out_uint16_le(s, RDP_CAPLEN_BITMAP);          out_uint16_le(s, RDP_CAPLEN_BITMAP);
555    
556          out_uint16_le(s, 8);    /* Preferred BPP */          out_uint16_le(s, g_server_bpp); /* Preferred BPP */
557          out_uint16_le(s, 1);    /* Receive 1 BPP */          out_uint16_le(s, 1);    /* Receive 1 BPP */
558          out_uint16_le(s, 1);    /* Receive 4 BPP */          out_uint16_le(s, 1);    /* Receive 4 BPP */
559          out_uint16_le(s, 1);    /* Receive 8 BPP */          out_uint16_le(s, 1);    /* Receive 8 BPP */
560          out_uint16_le(s, 800);  /* Desktop width */          out_uint16_le(s, 800);  /* Desktop width */
561          out_uint16_le(s, 600);  /* Desktop height */          out_uint16_le(s, 600);  /* Desktop height */
562          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
563          out_uint16(s, 0);       /* Allow resize */          out_uint16(s, 1);       /* Allow resize */
564          out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */          out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
565          out_uint16(s, 0);       /* Unknown */          out_uint16(s, 0);       /* Unknown */
566          out_uint16_le(s, 1);    /* Unknown */          out_uint16_le(s, 1);    /* Unknown */
# Line 399  rdp_out_order_caps(STREAM s) Line 573  rdp_out_order_caps(STREAM s)
573  {  {
574          uint8 order_caps[32];          uint8 order_caps[32];
575    
   
576          memset(order_caps, 0, 32);          memset(order_caps, 0, 32);
577          order_caps[0] = 1;      /* dest blt */          order_caps[0] = 1;      /* dest blt */
578          order_caps[1] = 1;      /* pat blt */          order_caps[1] = 1;      /* pat blt */
579          order_caps[2] = 1;      /* screen blt */          order_caps[2] = 1;      /* screen blt */
580          order_caps[3] = 1;      /* required for memblt? */          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
581            order_caps[4] = 0;      /* triblt */
582          order_caps[8] = 1;      /* line */          order_caps[8] = 1;      /* line */
583          order_caps[9] = 1;      /* line */          order_caps[9] = 1;      /* line */
584          order_caps[10] = 1;     /* rect */          order_caps[10] = 1;     /* rect */
585          order_caps[11] = (g_desktop_save == False ? 0 : 1);     /* desksave */          order_caps[11] = (g_desktop_save ? 1 : 0);      /* desksave */
586          order_caps[13] = 1;     /* memblt */          order_caps[13] = 1;     /* memblt */
587          order_caps[14] = 1;     /* triblt */          order_caps[14] = 1;     /* triblt */
588            order_caps[20] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon */
589            order_caps[21] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon2 */
590          order_caps[22] = 1;     /* polyline */          order_caps[22] = 1;     /* polyline */
591            order_caps[25] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse */
592            order_caps[26] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse2 */
593          order_caps[27] = 1;     /* text2 */          order_caps[27] = 1;     /* text2 */
594          out_uint16_le(s, RDP_CAPSET_ORDER);          out_uint16_le(s, RDP_CAPSET_ORDER);
595          out_uint16_le(s, RDP_CAPLEN_ORDER);          out_uint16_le(s, RDP_CAPLEN_ORDER);
# Line 449  rdp_out_bmpcache_caps(STREAM s) Line 627  rdp_out_bmpcache_caps(STREAM s)
627          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
628  }  }
629    
630    /* Output bitmap cache v2 capability set */
631    static void
632    rdp_out_bmpcache2_caps(STREAM s)
633    {
634            out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
635            out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
636    
637            out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
638    
639            out_uint16_le(s, 0x0300);       /* flags? number of caches? */
640    
641            out_uint32_le(s, BMPCACHE2_C0_CELLS);
642            out_uint32_le(s, BMPCACHE2_C1_CELLS);
643            if (pstcache_init(2))
644            {
645                    out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
646            }
647            else
648            {
649                    out_uint32_le(s, BMPCACHE2_C2_CELLS);
650            }
651            out_uint8s(s, 20);      /* other bitmap caches not used */
652    }
653    
654  /* Output control capability set */  /* Output control capability set */
655  static void  static void
656  rdp_out_control_caps(STREAM s)  rdp_out_control_caps(STREAM s)
# Line 508  rdp_out_colcache_caps(STREAM s) Line 710  rdp_out_colcache_caps(STREAM s)
710          out_uint16(s, 0);       /* pad */          out_uint16(s, 0);       /* pad */
711  }  }
712    
713  static uint8 canned_caps[] = {  static uint8 caps_0x0d[] = {
714          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
715          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
716          0x00, 0x00, 0x00, 0x00, 0x00,          0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
717          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
718          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
719          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
720          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
721          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
722          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
723          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
724          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  
725  };  };
726    
727  /* Output unknown capability sets (number 13, 12, 14 and 16) */  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
728    
729    static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
730    
731    static uint8 caps_0x10[] = {
732            0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
733            0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
734            0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
735            0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
736            0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
737            0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
738    };
739    
740    /* Output unknown capability sets */
741  static void  static void
742  rdp_out_unknown_caps(STREAM s)  rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
743  {  {
744          out_uint16_le(s, RDP_CAPSET_UNKNOWN);          out_uint16_le(s, id);
745          out_uint16_le(s, 0x58);          out_uint16_le(s, length);
746    
747          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);          out_uint8p(s, caps, length - 4);
748  }  }
749    
750  #define RDP5_FLAG 0x0030  #define RDP5_FLAG 0x0030
# Line 551  rdp_send_confirm_active(void) Line 758  rdp_send_confirm_active(void)
758                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
759                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
760                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
761                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
762                    0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
763                    4 /* w2k fix, why? */ ;
764    
765          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
766    
# Line 571  rdp_send_confirm_active(void) Line 780  rdp_send_confirm_active(void)
780          rdp_out_general_caps(s);          rdp_out_general_caps(s);
781          rdp_out_bitmap_caps(s);          rdp_out_bitmap_caps(s);
782          rdp_out_order_caps(s);          rdp_out_order_caps(s);
783          rdp_out_bmpcache_caps(s);          g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
784          rdp_out_colcache_caps(s);          rdp_out_colcache_caps(s);
785          rdp_out_activate_caps(s);          rdp_out_activate_caps(s);
786          rdp_out_control_caps(s);          rdp_out_control_caps(s);
787          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
788          rdp_out_share_caps(s);          rdp_out_share_caps(s);
789          rdp_out_unknown_caps(s);  
790            rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
791            rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
792            rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
793            rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
794    
795          s_mark_end(s);          s_mark_end(s);
796          sec_send(s, sec_flags);          sec_send(s, sec_flags);
797  }  }
798    
799    /* Process a general capability set */
800    static void
801    rdp_process_general_caps(STREAM s)
802    {
803            uint16 pad2octetsB;     /* rdp5 flags? */
804    
805            in_uint8s(s, 10);
806            in_uint16_le(s, pad2octetsB);
807    
808            if (!pad2octetsB)
809                    g_use_rdp5 = False;
810    }
811    
812    /* Process a bitmap capability set */
813    static void
814    rdp_process_bitmap_caps(STREAM s)
815    {
816            uint16 width, height, bpp;
817    
818            in_uint16_le(s, bpp);
819            in_uint8s(s, 6);
820    
821            in_uint16_le(s, width);
822            in_uint16_le(s, height);
823    
824            DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));
825    
826            /*
827             * The server may limit bpp and change the size of the desktop (for
828             * example when shadowing another session).
829             */
830            if (g_server_bpp != bpp)
831            {
832                    warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
833                    g_server_bpp = bpp;
834            }
835            if (g_width != width || g_height != height)
836            {
837                    warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
838                            width, height);
839                    g_width = width;
840                    g_height = height;
841                    ui_resize_window();
842            }
843    }
844    
845    /* Process server capabilities */
846    void
847    rdp_process_server_caps(STREAM s, uint16 length)
848    {
849            int n;
850            uint8 *next, *start;
851            uint16 ncapsets, capset_type, capset_length;
852    
853            start = s->p;
854    
855            in_uint16_le(s, ncapsets);
856            in_uint8s(s, 2);        /* pad */
857    
858            for (n = 0; n < ncapsets; n++)
859            {
860                    if (s->p > start + length)
861                            return;
862    
863                    in_uint16_le(s, capset_type);
864                    in_uint16_le(s, capset_length);
865    
866                    next = s->p + capset_length - 4;
867    
868                    switch (capset_type)
869                    {
870                            case RDP_CAPSET_GENERAL:
871                                    rdp_process_general_caps(s);
872                                    break;
873    
874                            case RDP_CAPSET_BITMAP:
875                                    rdp_process_bitmap_caps(s);
876                                    break;
877                    }
878    
879                    s->p = next;
880            }
881    }
882    
883  /* Respond to a demand active PDU */  /* Respond to a demand active PDU */
884  static void  static void
885  process_demand_active(STREAM s)  process_demand_active(STREAM s)
886  {  {
887          uint8 type;          uint8 type;
888            uint16 len_src_descriptor, len_combined_caps;
889    
890          in_uint32_le(s, g_rdp_shareid);          in_uint32_le(s, g_rdp_shareid);
891            in_uint16_le(s, len_src_descriptor);
892            in_uint16_le(s, len_combined_caps);
893            in_uint8s(s, len_src_descriptor);
894    
895          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
896            rdp_process_server_caps(s, len_combined_caps);
897    
898          rdp_send_confirm_active();          rdp_send_confirm_active();
899          rdp_send_synchronise();          rdp_send_synchronise();
# Line 600  process_demand_active(STREAM s) Line 902  process_demand_active(STREAM s)
902          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
903          rdp_recv(&type);        /* RDP_CTL_COOPERATE */          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
904          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
905          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);
906          rdp_send_fonts(1);  
907          rdp_send_fonts(2);          if (g_use_rdp5)
908          rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 */          {
909                    rdp_enum_bmpcache2();
910                    rdp_send_fonts(3);
911            }
912            else
913            {
914                    rdp_send_fonts(1);
915                    rdp_send_fonts(2);
916            }
917    
918            rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
919          reset_order_state();          reset_order_state();
920  }  }
921    
# Line 724  process_bitmap_updates(STREAM s) Line 1036  process_bitmap_updates(STREAM s)
1036                  DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",                  DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
1037                         left, top, right, bottom, width, height, Bpp, compress));                         left, top, right, bottom, width, height, Bpp, compress));
1038    
                 /* Server may limit bpp - this is how we find out */  
                 if (g_server_bpp != bpp) {  
                         warning("Server limited colour depth to %d bits\n", bpp);  
                         g_server_bpp = bpp;  
                 }  
   
1039                  if (!compress)                  if (!compress)
1040                  {                  {
1041                          int y;                          int y;
# Line 809  process_update_pdu(STREAM s) Line 1115  process_update_pdu(STREAM s)
1115    
1116          in_uint16_le(s, update_type);          in_uint16_le(s, update_type);
1117    
1118            ui_begin_update();
1119          switch (update_type)          switch (update_type)
1120          {          {
1121                  case RDP_UPDATE_ORDERS:                  case RDP_UPDATE_ORDERS:
# Line 832  process_update_pdu(STREAM s) Line 1139  process_update_pdu(STREAM s)
1139                  default:                  default:
1140                          unimpl("update %d\n", update_type);                          unimpl("update %d\n", update_type);
1141          }          }
1142            ui_end_update();
1143    }
1144    
1145    /* Process a disconnect PDU */
1146    void
1147    process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
1148    {
1149            in_uint32_le(s, *ext_disc_reason);
1150    
1151            DEBUG(("Received disconnect PDU\n"));
1152  }  }
1153    
1154  /* Process data PDU */  /* Process data PDU */
1155  static void  static BOOL
1156  process_data_pdu(STREAM s)  process_data_pdu(STREAM s, uint32 * ext_disc_reason)
1157  {  {
1158          uint8 data_pdu_type;          uint8 data_pdu_type;
1159            uint8 ctype;
1160            uint16 clen;
1161            uint32 len;
1162    
1163            uint32 roff, rlen;
1164    
1165            struct stream *ns = &(g_mppc_dict.ns);
1166    
1167          in_uint8s(s, 8);        /* shareid, pad, streamid, length */          in_uint8s(s, 6);        /* shareid, pad, streamid */
1168            in_uint16(s, len);
1169          in_uint8(s, data_pdu_type);          in_uint8(s, data_pdu_type);
1170          in_uint8s(s, 3);        /* compress_type, compress_len */          in_uint8(s, ctype);
1171            in_uint16(s, clen);
1172            clen -= 18;
1173    
1174            if (ctype & RDP_MPPC_COMPRESSED)
1175            {
1176                    if (len > RDP_MPPC_DICT_SIZE)
1177                            error("error decompressed packet size exceeds max\n");
1178                    if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1179                            error("error while decompressing packet\n");
1180    
1181                    //len -= 18;
1182    
1183                    /* allocate memory and copy the uncompressed data into the temporary stream */
1184                    ns->data = (uint8 *) xrealloc(ns->data, rlen);
1185    
1186                    memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
1187    
1188                    ns->size = rlen;
1189                    ns->end = (ns->data + ns->size);
1190                    ns->p = ns->data;
1191                    ns->rdp_hdr = ns->p;
1192    
1193                    s = ns;
1194            }
1195    
1196          switch (data_pdu_type)          switch (data_pdu_type)
1197          {          {
# Line 851  process_data_pdu(STREAM s) Line 1199  process_data_pdu(STREAM s)
1199                          process_update_pdu(s);                          process_update_pdu(s);
1200                          break;                          break;
1201    
1202                    case RDP_DATA_PDU_CONTROL:
1203                            DEBUG(("Received Control PDU\n"));
1204                            break;
1205    
1206                    case RDP_DATA_PDU_SYNCHRONISE:
1207                            DEBUG(("Received Sync PDU\n"));
1208                            break;
1209    
1210                  case RDP_DATA_PDU_POINTER:                  case RDP_DATA_PDU_POINTER:
1211                          process_pointer_pdu(s);                          process_pointer_pdu(s);
1212                          break;                          break;
# Line 865  process_data_pdu(STREAM s) Line 1221  process_data_pdu(STREAM s)
1221                          break;                          break;
1222    
1223                  case RDP_DATA_PDU_DISCONNECT:                  case RDP_DATA_PDU_DISCONNECT:
1224                          /* Normally received when user logs out or disconnects from a                          process_disconnect_pdu(s, ext_disc_reason);
1225                             console session on Windows XP and 2003 Server */                          return True;
                         DEBUG(("Received disconnect PDU\n"));  
                         break;  
1226    
1227                  default:                  default:
1228                          unimpl("data PDU %d\n", data_pdu_type);                          unimpl("data PDU %d\n", data_pdu_type);
1229          }          }
1230            return False;
1231  }  }
1232    
1233  /* Process incoming packets */  /* Process incoming packets */
1234    /* nevers gets out of here till app is done */
1235    void
1236    rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1237    {
1238            while (rdp_loop(deactivated, ext_disc_reason))
1239                    ;
1240    }
1241    
1242    /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1243  BOOL  BOOL
1244  rdp_main_loop(void)  rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1245  {  {
1246          uint8 type;          uint8 type;
1247            BOOL disc = False;      /* True when a disconnect PDU was received */
1248            BOOL cont = True;
1249          STREAM s;          STREAM s;
1250    
1251          while ((s = rdp_recv(&type)) != NULL)          while (cont)
1252          {          {
1253                    s = rdp_recv(&type);
1254                    if (s == NULL)
1255                            return False;
1256                  switch (type)                  switch (type)
1257                  {                  {
1258                          case RDP_PDU_DEMAND_ACTIVE:                          case RDP_PDU_DEMAND_ACTIVE:
1259                                  process_demand_active(s);                                  process_demand_active(s);
1260                                    *deactivated = False;
1261                                  break;                                  break;
   
1262                          case RDP_PDU_DEACTIVATE:                          case RDP_PDU_DEACTIVATE:
1263                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));
1264                                  /* 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; */  
1265                                  break;                                  break;
   
1266                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1267                                  process_data_pdu(s);                                  disc = process_data_pdu(s, ext_disc_reason);
1268                                  break;                                  break;
   
1269                          case 0:                          case 0:
1270                                  break;                                  break;
   
1271                          default:                          default:
1272                                  unimpl("PDU %d\n", type);                                  unimpl("PDU %d\n", type);
1273                  }                  }
1274                    if (disc)
1275                            return False;
1276                    cont = g_next_packet < s->end;
1277          }          }
1278          return True;          return True;
         /* We want to detect if we got a clean shutdown, but we  
            can't. Se above.    
            return False;  */  
1279  }  }
1280    
1281  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */

Legend:
Removed from v.522  
changed lines
  Added in v.863

  ViewVC Help
Powered by ViewVC 1.1.26