/[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 624 by n-ki, Thu Mar 4 08:11:40 2004 UTC revision 855 by stargo, Sun Mar 13 13:18:48 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 19  Line 19 
19  */  */
20    
21  #include <time.h>  #include <time.h>
22    #include <errno.h>
23    #include <unistd.h>
24  #include "rdesktop.h"  #include "rdesktop.h"
25    
26    #ifdef HAVE_ICONV_H
27    #include <iconv.h>
28    #endif
29    
30  extern uint16 g_mcs_userid;  extern uint16 g_mcs_userid;
31  extern char g_username[16];  extern char g_username[64];
32    extern char g_codepage[16];
33  extern BOOL g_bitmap_compression;  extern BOOL g_bitmap_compression;
34  extern BOOL g_orders;  extern BOOL g_orders;
35  extern BOOL g_encryption;  extern BOOL g_encryption;
36  extern BOOL g_desktop_save;  extern BOOL g_desktop_save;
37    extern BOOL g_polygon_ellipse_orders;
38  extern BOOL g_use_rdp5;  extern BOOL g_use_rdp5;
39  extern uint16 g_server_rdp_version;  extern uint16 g_server_rdp_version;
40    extern uint32 g_rdp5_performanceflags;
41  extern int g_server_bpp;  extern int g_server_bpp;
42    extern int g_width;
43    extern int g_height;
44    extern BOOL g_bitmap_cache;
45    extern BOOL g_bitmap_cache_persist_enable;
46    
47  uint8 *g_next_packet;  uint8 *g_next_packet;
48  uint32 g_rdp_shareid;  uint32 g_rdp_shareid;
49    
50    extern RDPCOMP g_mppc_dict;
51    
52  #if WITH_DEBUG  #if WITH_DEBUG
53  static uint32 g_packetno;  static uint32 g_packetno;
54  #endif  #endif
# Line 44  rdp_recv(uint8 * type) Line 59  rdp_recv(uint8 * type)
59  {  {
60          static STREAM rdp_s;          static STREAM rdp_s;
61          uint16 length, pdu_type;          uint16 length, pdu_type;
62            uint8 rdpver;
63    
64          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))
65          {          {
66                  rdp_s = sec_recv();                  rdp_s = sec_recv(&rdpver);
67                  if (rdp_s == NULL)                  if (rdp_s == NULL)
68                          return NULL;                          return NULL;
69                    if (rdpver == 0xff)
70                    {
71                            g_next_packet = rdp_s->end;
72                            *type = 0;
73                            return rdp_s;
74                    }
75                    else if (rdpver != 3)
76                    {
77                            /* rdp5_process should move g_next_packet ok */
78                            rdp5_process(rdp_s);
79                            *type = 0;
80                            return rdp_s;
81                    }
82    
83                  g_next_packet = rdp_s->p;                  g_next_packet = rdp_s->p;
84          }          }
# Line 119  rdp_send_data(STREAM s, uint8 data_pdu_t Line 148  rdp_send_data(STREAM s, uint8 data_pdu_t
148  void  void
149  rdp_out_unistr(STREAM s, char *string, int len)  rdp_out_unistr(STREAM s, char *string, int len)
150  {  {
151    #ifdef  HAVE_ICONV
152            size_t ibl = strlen(string), obl = len + 2;
153            static iconv_t iconv_h = (iconv_t)-1;
154            char   *pin = string, *pout;
155    #ifdef  B_ENDIAN
156            char ss[4096];  // FIXME: global MAX_BUF_SIZE macro need
157    
158            pout = ss;
159    #else
160            pout = s->p;
161    #endif
162    
163            memset(pout, 0, len + 4);
164    
165            if (iconv_h == (iconv_t)-1)
166            {
167                    size_t i = 1, o = 4;
168                    if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t)-1)
169                    {
170                            printf("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n",
171                                    g_codepage, WINDOWS_CODEPAGE, (int)iconv_h);
172                            return;
173                    }
174                    if (iconv(iconv_h, (const char**)&pin, &i, &pout, &o) == (size_t)-1)
175                    {
176                            iconv_close(iconv_h);
177                            iconv_h = (iconv_t)-1;
178                            printf("rdp_out_unistr: iconv(1) fail, errno %d\n", errno);
179                            return;
180                    }
181                    pin = string; pout = s->p;
182            }
183    
184            if (iconv(iconv_h, (const char**)&pin, &ibl, &pout, &obl) == (size_t)-1)
185            {
186                    iconv_close(iconv_h);
187                    iconv_h = (iconv_t)-1;
188                    printf("rdp_out_unistr: iconv(2) fail, errno %d\n", errno);
189                    return;
190            }
191    
192    #ifdef  B_ENDIAN
193            swab(ss, s->p, len + 4);
194    #endif
195    
196            s->p += len + 2;
197    
198    #else /*HAVE_ICONV undef*/
199          int i = 0, j = 0;          int i = 0, j = 0;
200    
201          len += 2;          len += 2;
# Line 128  rdp_out_unistr(STREAM s, char *string, i Line 205  rdp_out_unistr(STREAM s, char *string, i
205                  s->p[i++] = string[j++];                  s->p[i++] = string[j++];
206                  s->p[i++] = 0;                  s->p[i++] = 0;
207          }          }
208            
209          s->p += len;          s->p += len;
210    #endif
211  }  }
212    
213  /* Input a string in Unicode  /* Input a string in Unicode
# Line 139  rdp_out_unistr(STREAM s, char *string, i Line 217  rdp_out_unistr(STREAM s, char *string, i
217  int  int
218  rdp_in_unistr(STREAM s, char *string, int uni_len)  rdp_in_unistr(STREAM s, char *string, int uni_len)
219  {  {
220    #ifdef  HAVE_ICONV
221            size_t ibl = uni_len, obl = uni_len;
222            char *pin, *pout = string;
223            static iconv_t iconv_h = (iconv_t)-1;
224    #ifdef  B_ENDIAN
225            char ss[4096];  // FIXME: global MAX_BUF_SIZE macro need
226    
227            swab(s->p, ss, uni_len);
228            pin = ss;
229    #else
230            pin = s->p;
231    #endif
232    
233            if (iconv_h == (iconv_t)-1)
234            {
235                    if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t)-1)
236                    {
237                            printf("rdp_in_unistr: iconv_open[%s -> %s] fail %d\n",
238                                    WINDOWS_CODEPAGE, g_codepage, (int)iconv_h);
239                            return 0;
240                    }
241            }
242    
243            if (iconv(iconv_h, (const char**)&pin, &ibl, &pout, &obl) == (size_t)-1)
244            {
245                    iconv_close(iconv_h);
246                    iconv_h = (iconv_t)-1;
247                    printf("rdp_in_unistr: iconv fail, errno %d\n", errno);
248                    return 0;
249            }
250            return pout - string;
251    #else /* HAVE_ICONV undef */
252          int i = 0;          int i = 0;
253    
254          while (i < uni_len / 2)          while (i < uni_len / 2)
# Line 148  rdp_in_unistr(STREAM s, char *string, in Line 258  rdp_in_unistr(STREAM s, char *string, in
258          }          }
259    
260          return i - 1;          return i - 1;
261    #endif
262  }  }
263    
264    
# Line 171  rdp_send_logon_info(uint32 flags, char * Line 282  rdp_send_logon_info(uint32 flags, char *
282          time_t tzone;          time_t tzone;
283    
284  #if 0  #if 0
285          // enable rdp compression          /* enable rdp compression */
286            /* some problems still exist with rdp5 */
287          flags |= RDP_COMPRESSION;          flags |= RDP_COMPRESSION;
288  #endif  #endif
289    
# Line 197  rdp_send_logon_info(uint32 flags, char * Line 309  rdp_send_logon_info(uint32 flags, char *
309          }          }
310          else          else
311          {          {
312    
313                  flags |= RDP_LOGON_BLOB;                  flags |= RDP_LOGON_BLOB;
314                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
315                  packetlen = 4 + /* Unknown uint32 */                  packetlen = 4 + /* Unknown uint32 */
# Line 297  rdp_send_logon_info(uint32 flags, char * Line 410  rdp_send_logon_info(uint32 flags, char *
410                  out_uint32(s, 0);                  out_uint32(s, 0);
411                  out_uint32_le(s, 0xffffffc4);                  out_uint32_le(s, 0xffffffc4);
412                  out_uint32_le(s, 0xfffffffe);                  out_uint32_le(s, 0xfffffffe);
413                  out_uint32_le(s, 0x0f);                  out_uint32_le(s, g_rdp5_performanceflags);
414                  out_uint32(s, 0);                  out_uint32(s, 0);
415    
416    
# Line 358  rdp_send_input(uint32 time, uint16 messa Line 471  rdp_send_input(uint32 time, uint16 messa
471          rdp_send_data(s, RDP_DATA_PDU_INPUT);          rdp_send_data(s, RDP_DATA_PDU_INPUT);
472  }  }
473    
474    /* Inform the server on the contents of the persistent bitmap cache */
475    static void
476    rdp_enum_bmpcache2(void)
477    {
478            STREAM s;
479            HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS];
480            uint32 num_keys, offset, count, flags;
481    
482            offset = 0;
483            num_keys = pstcache_enumerate(2, keylist);
484    
485            while (offset < num_keys)
486            {
487                    count = MIN(num_keys - offset, 169);
488    
489                    s = rdp_init_data(24 + count * sizeof(HASH_KEY));
490    
491                    flags = 0;
492                    if (offset == 0)
493                            flags |= PDU_FLAG_FIRST;
494                    if (num_keys - offset <= 169)
495                            flags |= PDU_FLAG_LAST;
496    
497                    /* header */
498                    out_uint32_le(s, 0);
499                    out_uint16_le(s, count);
500                    out_uint16_le(s, 0);
501                    out_uint16_le(s, 0);
502                    out_uint16_le(s, 0);
503                    out_uint16_le(s, 0);
504                    out_uint16_le(s, num_keys);
505                    out_uint32_le(s, 0);
506                    out_uint32_le(s, flags);
507    
508                    /* list */
509                    out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
510    
511                    s_mark_end(s);
512                    rdp_send_data(s, 0x2b);
513    
514                    offset += 169;
515            }
516    }
517    
518  /* Send an (empty) font information PDU */  /* Send an (empty) font information PDU */
519  static void  static void
520  rdp_send_fonts(uint16 seq)  rdp_send_fonts(uint16 seq)
# Line 367  rdp_send_fonts(uint16 seq) Line 524  rdp_send_fonts(uint16 seq)
524          s = rdp_init_data(8);          s = rdp_init_data(8);
525    
526          out_uint16(s, 0);       /* number of fonts */          out_uint16(s, 0);       /* number of fonts */
527          out_uint16_le(s, 0x3e); /* unknown */          out_uint16_le(s, 0);    /* pad? */
528          out_uint16_le(s, seq);  /* unknown */          out_uint16_le(s, seq);  /* unknown */
529          out_uint16_le(s, 0x32); /* entry size */          out_uint16_le(s, 0x32); /* entry size */
530    
# Line 408  rdp_out_bitmap_caps(STREAM s) Line 565  rdp_out_bitmap_caps(STREAM s)
565          out_uint16_le(s, RDP_CAPSET_BITMAP);          out_uint16_le(s, RDP_CAPSET_BITMAP);
566          out_uint16_le(s, RDP_CAPLEN_BITMAP);          out_uint16_le(s, RDP_CAPLEN_BITMAP);
567    
568          out_uint16_le(s, 8);    /* Preferred BPP */          out_uint16_le(s, g_server_bpp); /* Preferred BPP */
569          out_uint16_le(s, 1);    /* Receive 1 BPP */          out_uint16_le(s, 1);    /* Receive 1 BPP */
570          out_uint16_le(s, 1);    /* Receive 4 BPP */          out_uint16_le(s, 1);    /* Receive 4 BPP */
571          out_uint16_le(s, 1);    /* Receive 8 BPP */          out_uint16_le(s, 1);    /* Receive 8 BPP */
572          out_uint16_le(s, 800);  /* Desktop width */          out_uint16_le(s, 800);  /* Desktop width */
573          out_uint16_le(s, 600);  /* Desktop height */          out_uint16_le(s, 600);  /* Desktop height */
574          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
575          out_uint16(s, 0);       /* Allow resize */          out_uint16(s, 1);       /* Allow resize */
576          out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */          out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
577          out_uint16(s, 0);       /* Unknown */          out_uint16(s, 0);       /* Unknown */
578          out_uint16_le(s, 1);    /* Unknown */          out_uint16_le(s, 1);    /* Unknown */
# Line 428  rdp_out_order_caps(STREAM s) Line 585  rdp_out_order_caps(STREAM s)
585  {  {
586          uint8 order_caps[32];          uint8 order_caps[32];
587    
   
588          memset(order_caps, 0, 32);          memset(order_caps, 0, 32);
589          order_caps[0] = 1;      /* dest blt */          order_caps[0] = 1;      /* dest blt */
590          order_caps[1] = 1;      /* pat blt */          order_caps[1] = 1;      /* pat blt */
591          order_caps[2] = 1;      /* screen blt */          order_caps[2] = 1;      /* screen blt */
592          order_caps[3] = 1;      /* required for memblt? */          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
593            order_caps[4] = 0;      /* triblt */
594          order_caps[8] = 1;      /* line */          order_caps[8] = 1;      /* line */
595          order_caps[9] = 1;      /* line */          order_caps[9] = 1;      /* line */
596          order_caps[10] = 1;     /* rect */          order_caps[10] = 1;     /* rect */
597          order_caps[11] = (g_desktop_save == False ? 0 : 1);     /* desksave */          order_caps[11] = (g_desktop_save ? 1 : 0);      /* desksave */
598          order_caps[13] = 1;     /* memblt */          order_caps[13] = 1;     /* memblt */
599          order_caps[14] = 1;     /* triblt */          order_caps[14] = 1;     /* triblt */
600            order_caps[20] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon */
601            order_caps[21] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon2 */
602          order_caps[22] = 1;     /* polyline */          order_caps[22] = 1;     /* polyline */
603            order_caps[25] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse */
604            order_caps[26] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse2 */
605          order_caps[27] = 1;     /* text2 */          order_caps[27] = 1;     /* text2 */
606          out_uint16_le(s, RDP_CAPSET_ORDER);          out_uint16_le(s, RDP_CAPSET_ORDER);
607          out_uint16_le(s, RDP_CAPLEN_ORDER);          out_uint16_le(s, RDP_CAPLEN_ORDER);
# Line 478  rdp_out_bmpcache_caps(STREAM s) Line 639  rdp_out_bmpcache_caps(STREAM s)
639          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
640  }  }
641    
642    /* Output bitmap cache v2 capability set */
643    static void
644    rdp_out_bmpcache2_caps(STREAM s)
645    {
646            out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
647            out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
648    
649            out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
650    
651            out_uint16_le(s, 0x0300);       /* flags? number of caches? */
652    
653            out_uint32_le(s, BMPCACHE2_C0_CELLS);
654            out_uint32_le(s, BMPCACHE2_C1_CELLS);
655            if (pstcache_init(2))
656            {
657                    out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
658            }
659            else
660            {
661                    out_uint32_le(s, BMPCACHE2_C2_CELLS);
662            }
663            out_uint8s(s, 20);      /* other bitmap caches not used */
664    }
665    
666  /* Output control capability set */  /* Output control capability set */
667  static void  static void
668  rdp_out_control_caps(STREAM s)  rdp_out_control_caps(STREAM s)
# Line 537  rdp_out_colcache_caps(STREAM s) Line 722  rdp_out_colcache_caps(STREAM s)
722          out_uint16(s, 0);       /* pad */          out_uint16(s, 0);       /* pad */
723  }  }
724    
725  static uint8 canned_caps[] = {  static uint8 caps_0x0d[] = {
726          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
727          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
728          0x00, 0x00, 0x00, 0x00, 0x00,          0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
729          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
730          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
731          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
732          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
733          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
734          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
735          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
736          0x0C, 0x00, 0x08, 0x00, 0x01,          0x00, 0x00, 0x00, 0x00
         0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,  
         0x10, 0x00, 0x34, 0x00, 0xFE,  
         0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,  
         0xFE, 0x00, 0x08, 0x00, 0xFE,  
         0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,  
         0xFE, 0x00, 0x80, 0x00, 0xFE,  
         0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,  
         0x02, 0x00, 0x00, 0x00  
737  };  };
738    
739  /* Output unknown capability sets (number 13, 12, 14 and 16) */  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
740    
741    static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
742    
743    static uint8 caps_0x10[] = {
744            0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
745            0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
746            0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
747            0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
748            0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
749            0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
750    };
751    
752    /* Output unknown capability sets */
753  static void  static void
754  rdp_out_unknown_caps(STREAM s)  rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
755  {  {
756          out_uint16_le(s, RDP_CAPSET_UNKNOWN);          out_uint16_le(s, id);
757          out_uint16_le(s, 0x58);          out_uint16_le(s, length);
758    
759          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);          out_uint8p(s, caps, length - 4);
760  }  }
761    
762  #define RDP5_FLAG 0x0030  #define RDP5_FLAG 0x0030
# Line 580  rdp_send_confirm_active(void) Line 770  rdp_send_confirm_active(void)
770                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
771                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
772                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
773                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
774                    0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
775                    4 /* w2k fix, why? */ ;
776    
777          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
778    
# Line 600  rdp_send_confirm_active(void) Line 792  rdp_send_confirm_active(void)
792          rdp_out_general_caps(s);          rdp_out_general_caps(s);
793          rdp_out_bitmap_caps(s);          rdp_out_bitmap_caps(s);
794          rdp_out_order_caps(s);          rdp_out_order_caps(s);
795          rdp_out_bmpcache_caps(s);          g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
796          rdp_out_colcache_caps(s);          rdp_out_colcache_caps(s);
797          rdp_out_activate_caps(s);          rdp_out_activate_caps(s);
798          rdp_out_control_caps(s);          rdp_out_control_caps(s);
799          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
800          rdp_out_share_caps(s);          rdp_out_share_caps(s);
801          rdp_out_unknown_caps(s);  
802            rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
803            rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
804            rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
805            rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
806    
807          s_mark_end(s);          s_mark_end(s);
808          sec_send(s, sec_flags);          sec_send(s, sec_flags);
809  }  }
810    
811    /* Process a general capability set */
812    static void
813    rdp_process_general_caps(STREAM s)
814    {
815            uint16 pad2octetsB;     /* rdp5 flags? */
816    
817            in_uint8s(s, 10);
818            in_uint16_le(s, pad2octetsB);
819    
820            if (!pad2octetsB)
821                    g_use_rdp5 = False;
822    }
823    
824    /* Process a bitmap capability set */
825    static void
826    rdp_process_bitmap_caps(STREAM s)
827    {
828            uint16 width, height, bpp;
829    
830            in_uint16_le(s, bpp);
831            in_uint8s(s, 6);
832    
833            in_uint16_le(s, width);
834            in_uint16_le(s, height);
835    
836            DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));
837    
838            /*
839             * The server may limit bpp and change the size of the desktop (for
840             * example when shadowing another session).
841             */
842            if (g_server_bpp != bpp)
843            {
844                    warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
845                    g_server_bpp = bpp;
846            }
847            if (g_width != width || g_height != height)
848            {
849                    warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
850                            width, height);
851                    g_width = width;
852                    g_height = height;
853                    ui_resize_window();
854            }
855    }
856    
857    /* Process server capabilities */
858    void
859    rdp_process_server_caps(STREAM s, uint16 length)
860    {
861            int n;
862            uint8 *next, *start;
863            uint16 ncapsets, capset_type, capset_length;
864    
865            start = s->p;
866    
867            in_uint16_le(s, ncapsets);
868            in_uint8s(s, 2);        /* pad */
869    
870            for (n = 0; n < ncapsets; n++)
871            {
872                    if (s->p > start + length)
873                            return;
874    
875                    in_uint16_le(s, capset_type);
876                    in_uint16_le(s, capset_length);
877    
878                    next = s->p + capset_length - 4;
879    
880                    switch (capset_type)
881                    {
882                            case RDP_CAPSET_GENERAL:
883                                    rdp_process_general_caps(s);
884                                    break;
885    
886                            case RDP_CAPSET_BITMAP:
887                                    rdp_process_bitmap_caps(s);
888                                    break;
889                    }
890    
891                    s->p = next;
892            }
893    }
894    
895  /* Respond to a demand active PDU */  /* Respond to a demand active PDU */
896  static void  static void
897  process_demand_active(STREAM s)  process_demand_active(STREAM s)
898  {  {
899          uint8 type;          uint8 type;
900            uint16 len_src_descriptor, len_combined_caps;
901    
902          in_uint32_le(s, g_rdp_shareid);          in_uint32_le(s, g_rdp_shareid);
903            in_uint16_le(s, len_src_descriptor);
904            in_uint16_le(s, len_combined_caps);
905            in_uint8s(s, len_src_descriptor);
906    
907          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
908            rdp_process_server_caps(s, len_combined_caps);
909    
910          rdp_send_confirm_active();          rdp_send_confirm_active();
911          rdp_send_synchronise();          rdp_send_synchronise();
# Line 630  process_demand_active(STREAM s) Line 915  process_demand_active(STREAM s)
915          rdp_recv(&type);        /* RDP_CTL_COOPERATE */          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
916          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
917          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);
918          rdp_send_fonts(1);  
919          rdp_send_fonts(2);          if (g_use_rdp5)
920          rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 */          {
921                    rdp_enum_bmpcache2();
922                    rdp_send_fonts(3);
923            }
924            else
925            {
926                    rdp_send_fonts(1);
927                    rdp_send_fonts(2);
928            }
929    
930            rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
931          reset_order_state();          reset_order_state();
932  }  }
933    
# Line 753  process_bitmap_updates(STREAM s) Line 1048  process_bitmap_updates(STREAM s)
1048                  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",
1049                         left, top, right, bottom, width, height, Bpp, compress));                         left, top, right, bottom, width, height, Bpp, compress));
1050    
                 /* 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;  
                 }  
   
1051                  if (!compress)                  if (!compress)
1052                  {                  {
1053                          int y;                          int y;
# Line 839  process_update_pdu(STREAM s) Line 1127  process_update_pdu(STREAM s)
1127    
1128          in_uint16_le(s, update_type);          in_uint16_le(s, update_type);
1129    
1130            ui_begin_update();
1131          switch (update_type)          switch (update_type)
1132          {          {
1133                  case RDP_UPDATE_ORDERS:                  case RDP_UPDATE_ORDERS:
# Line 862  process_update_pdu(STREAM s) Line 1151  process_update_pdu(STREAM s)
1151                  default:                  default:
1152                          unimpl("update %d\n", update_type);                          unimpl("update %d\n", update_type);
1153          }          }
1154            ui_end_update();
1155    }
1156    
1157    /* Process a disconnect PDU */
1158    void
1159    process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
1160    {
1161            in_uint32_le(s, *ext_disc_reason);
1162    
1163            DEBUG(("Received disconnect PDU\n"));
1164  }  }
1165    
1166  /* Process data PDU */  /* Process data PDU */
1167  static void  static BOOL
1168  process_data_pdu(STREAM s)  process_data_pdu(STREAM s, uint32 * ext_disc_reason)
1169  {  {
1170          uint8 data_pdu_type;          uint8 data_pdu_type;
1171          uint8 ctype;          uint8 ctype;
1172          uint16 clen;          uint16 clen;
1173          int roff, rlen, len, ret;          uint32 len;
1174          static struct stream ns;  
1175          static signed char *dict = 0;          uint32 roff, rlen;
1176    
1177            struct stream *ns = &(g_mppc_dict.ns);
1178    
1179          in_uint8s(s, 6);        /* shareid, pad, streamid */          in_uint8s(s, 6);        /* shareid, pad, streamid */
1180          in_uint16(s, len);          in_uint16(s, len);
# Line 883  process_data_pdu(STREAM s) Line 1183  process_data_pdu(STREAM s)
1183          in_uint16(s, clen);          in_uint16(s, clen);
1184          clen -= 18;          clen -= 18;
1185    
1186  #if 0          if (ctype & RDP_MPPC_COMPRESSED)
         if (ctype & 0x20)  
1187          {          {
1188                  if (!dict)                  if (len > RDP_MPPC_DICT_SIZE)
1189                  {                          error("error decompressed packet size exceeds max\n");
1190                          dict = (signed char *) malloc(8200 * sizeof(signed char));                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1191                          dict = (signed char *) memset(dict, 0, 8200 * sizeof(signed char));                          error("error while decompressing packet\n");
                 }  
1192    
1193                  ret = decompress(s->p, clen, ctype, (signed char *) dict, &roff, &rlen);                  //len -= 18;
1194    
1195                  len -= 18;                  /* allocate memory and copy the uncompressed data into the temporary stream */
1196                    ns->data = (uint8 *) xrealloc(ns->data, rlen);
1197    
1198                  ns.data = xrealloc(ns.data, len);                  memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
1199    
1200                  ns.data = (unsigned char *) memcpy(ns.data, (unsigned char *) (dict + roff), len);                  ns->size = rlen;
1201                    ns->end = (ns->data + ns->size);
1202                    ns->p = ns->data;
1203                    ns->rdp_hdr = ns->p;
1204    
1205                  ns.size = len;                  s = ns;
                 ns.end = ns.data + ns.size;  
                 ns.p = ns.data;  
                 ns.rdp_hdr = ns.p;  
   
                 s = &ns;  
1206          }          }
 #endif  
1207    
1208          switch (data_pdu_type)          switch (data_pdu_type)
1209          {          {
# Line 915  process_data_pdu(STREAM s) Line 1211  process_data_pdu(STREAM s)
1211                          process_update_pdu(s);                          process_update_pdu(s);
1212                          break;                          break;
1213    
1214                    case RDP_DATA_PDU_CONTROL:
1215                            DEBUG(("Received Control PDU\n"));
1216                            break;
1217    
1218                    case RDP_DATA_PDU_SYNCHRONISE:
1219                            DEBUG(("Received Sync PDU\n"));
1220                            break;
1221    
1222                  case RDP_DATA_PDU_POINTER:                  case RDP_DATA_PDU_POINTER:
1223                          process_pointer_pdu(s);                          process_pointer_pdu(s);
1224                          break;                          break;
# Line 929  process_data_pdu(STREAM s) Line 1233  process_data_pdu(STREAM s)
1233                          break;                          break;
1234    
1235                  case RDP_DATA_PDU_DISCONNECT:                  case RDP_DATA_PDU_DISCONNECT:
1236                          /* Normally received when user logs out or disconnects from a                          process_disconnect_pdu(s, ext_disc_reason);
1237                             console session on Windows XP and 2003 Server */                          return True;
                         DEBUG(("Received disconnect PDU\n"));  
                         break;  
1238    
1239                  default:                  default:
1240                          unimpl("data PDU %d\n", data_pdu_type);                          unimpl("data PDU %d\n", data_pdu_type);
1241          }          }
1242            return False;
1243  }  }
1244    
1245  /* Process incoming packets */  /* Process incoming packets */
1246    /* nevers gets out of here till app is done */
1247    void
1248    rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1249    {
1250            while (rdp_loop(deactivated, ext_disc_reason))
1251                    ;
1252    }
1253    
1254    /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1255  BOOL  BOOL
1256  rdp_main_loop(void)  rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1257  {  {
1258          uint8 type;          uint8 type;
1259            BOOL disc = False;      /* True when a disconnect PDU was received */
1260            BOOL cont = True;
1261          STREAM s;          STREAM s;
1262    
1263          while ((s = rdp_recv(&type)) != NULL)          while (cont)
1264          {          {
1265                    s = rdp_recv(&type);
1266                    if (s == NULL)
1267                            return False;
1268                  switch (type)                  switch (type)
1269                  {                  {
1270                          case RDP_PDU_DEMAND_ACTIVE:                          case RDP_PDU_DEMAND_ACTIVE:
1271                                  process_demand_active(s);                                  process_demand_active(s);
1272                                    *deactivated = False;
1273                                  break;                                  break;
   
1274                          case RDP_PDU_DEACTIVATE:                          case RDP_PDU_DEACTIVATE:
1275                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));
1276                                  /* 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; */  
1277                                  break;                                  break;
   
1278                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1279                                  process_data_pdu(s);                                  disc = process_data_pdu(s, ext_disc_reason);
1280                                  break;                                  break;
   
1281                          case 0:                          case 0:
1282                                  break;                                  break;
   
1283                          default:                          default:
1284                                  unimpl("PDU %d\n", type);                                  unimpl("PDU %d\n", type);
1285                  }                  }
1286                    if (disc)
1287                            return False;
1288                    cont = g_next_packet < s->end;
1289          }          }
1290          return True;          return True;
         /* We want to detect if we got a clean shutdown, but we  
            can't. Se above.    
            return False;  */  
1291  }  }
1292    
1293  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */

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

  ViewVC Help
Powered by ViewVC 1.1.26