/[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 676 by astrand, Tue Apr 20 07:01:21 2004 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 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
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;  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 45  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 120  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 131  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  /* Input a string in Unicode
# Line 140  rdp_out_unistr(STREAM s, char *string, i Line 213  rdp_out_unistr(STREAM s, char *string, i
213  int  int
214  rdp_in_unistr(STREAM s, char *string, int uni_len)  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;          int i = 0;
241    
242          while (i < uni_len / 2)          while (i < uni_len / 2)
# Line 149  rdp_in_unistr(STREAM s, char *string, in Line 246  rdp_in_unistr(STREAM s, char *string, in
246          }          }
247    
248          return i - 1;          return i - 1;
249    #endif
250  }  }
251    
252    
# Line 172  rdp_send_logon_info(uint32 flags, char * Line 270  rdp_send_logon_info(uint32 flags, char *
270          time_t tzone;          time_t tzone;
271    
272  #if 0  #if 0
273          // enable rdp compression          /* enable rdp compression */
274            /* some problems still exist with rdp5 */
275          flags |= RDP_COMPRESSION;          flags |= RDP_COMPRESSION;
276  #endif  #endif
277    
# Line 198  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 */
# Line 359  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 368  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 416  rdp_out_bitmap_caps(STREAM s) Line 560  rdp_out_bitmap_caps(STREAM s)
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 429  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 479  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 538  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 581  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 601  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  /* Respond to a demand active PDU */  /* Process a general capability set */
800  static void  static void
801  process_demand_active(STREAM s)  rdp_process_general_caps(STREAM s)
802  {  {
803          uint8 type;          uint16 pad2octetsB;     /* rdp5 flags? */
         uint16 i;  
         uint16 p_bpp;  
804    
805          in_uint32_le(s, g_rdp_shareid);          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          /* scan for prefered bpp */          start = s->p;
854          while (s_check_rem(s, 6))  
855            in_uint16_le(s, ncapsets);
856            in_uint8s(s, 2);        /* pad */
857    
858            for (n = 0; n < ncapsets; n++)
859          {          {
860                  in_uint16_le(s, i);                  if (s->p > start + length)
861                  if (i == RDP_CAPSET_BITMAP)                          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                          in_uint16_le(s, i);                          case RDP_CAPSET_GENERAL:
871                          if (i == RDP_CAPLEN_BITMAP)                                  rdp_process_general_caps(s);
872                          {                                  break;
873                                  in_uint16_le(s, p_bpp);  
874                                  if (p_bpp == 8 || p_bpp == 15 || p_bpp == 16 || p_bpp == 24)                          case RDP_CAPSET_BITMAP:
875                                  {                                  rdp_process_bitmap_caps(s);
876                                          if (p_bpp < g_server_bpp)                                  break;
                                         {  
                                                 warning("Server limited colour depth to %d bits\n",  
                                                         p_bpp);  
                                                 g_server_bpp = p_bpp;  
                                         }  
                                         break;  
                                 }  
                         }  
877                  }                  }
878    
879                    s->p = next;
880          }          }
881    }
882    
883    /* Respond to a demand active PDU */
884    static void
885    process_demand_active(STREAM s)
886    {
887            uint8 type;
888            uint16 len_src_descriptor, len_combined_caps;
889    
890            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 658  process_demand_active(STREAM s) Line 903  process_demand_active(STREAM s)
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, ui_get_numlock_state(read_keyboard_state()), 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 860  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 883  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 */  /* Process a disconnect PDU */
# Line 902  process_data_pdu(STREAM s, uint32 * ext_ Line 1158  process_data_pdu(STREAM s, uint32 * ext_
1158          uint8 data_pdu_type;          uint8 data_pdu_type;
1159          uint8 ctype;          uint8 ctype;
1160          uint16 clen;          uint16 clen;
1161          int len;          uint32 len;
1162  #if 0  
1163          int roff, rlen, ret;          uint32 roff, rlen;
1164          static struct stream ns;  
1165          static signed char *dict = 0;          struct stream *ns = &(g_mppc_dict.ns);
 #endif  
1166    
1167          in_uint8s(s, 6);        /* shareid, pad, streamid */          in_uint8s(s, 6);        /* shareid, pad, streamid */
1168          in_uint16(s, len);          in_uint16(s, len);
# Line 916  process_data_pdu(STREAM s, uint32 * ext_ Line 1171  process_data_pdu(STREAM s, uint32 * ext_
1171          in_uint16(s, clen);          in_uint16(s, clen);
1172          clen -= 18;          clen -= 18;
1173    
1174  #if 0          if (ctype & RDP_MPPC_COMPRESSED)
         if (ctype & 0x20)  
1175          {          {
1176                  if (!dict)                  if (len > RDP_MPPC_DICT_SIZE)
1177                  {                          error("error decompressed packet size exceeds max\n");
1178                          dict = (signed char *) malloc(8200 * sizeof(signed char));                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1179                          dict = (signed char *) memset(dict, 0, 8200 * sizeof(signed char));                          error("error while decompressing packet\n");
                 }  
1180    
1181                  ret = decompress(s->p, clen, ctype, (signed char *) dict, &roff, &rlen);                  //len -= 18;
1182    
1183                  len -= 18;                  /* allocate memory and copy the uncompressed data into the temporary stream */
1184                    ns->data = (uint8 *) xrealloc(ns->data, rlen);
1185    
1186                  ns.data = xrealloc(ns.data, len);                  memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
1187    
1188                  ns.data = (unsigned char *) memcpy(ns.data, (unsigned char *) (dict + roff), len);                  ns->size = rlen;
1189                    ns->end = (ns->data + ns->size);
1190                    ns->p = ns->data;
1191                    ns->rdp_hdr = ns->p;
1192    
1193                  ns.size = len;                  s = ns;
                 ns.end = ns.data + ns.size;  
                 ns.p = ns.data;  
                 ns.rdp_hdr = ns.p;  
   
                 s = &ns;  
1194          }          }
 #endif  
1195    
1196          switch (data_pdu_type)          switch (data_pdu_type)
1197          {          {
# Line 980  process_data_pdu(STREAM s, uint32 * ext_ Line 1231  process_data_pdu(STREAM s, uint32 * ext_
1231  }  }
1232    
1233  /* Process incoming packets */  /* Process incoming packets */
1234    /* nevers gets out of here till app is done */
1235  void  void
1236  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)  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
1244    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 */          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;                                  *deactivated = False;
1261                                  break;                                  break;
   
1262                          case RDP_PDU_DEACTIVATE:                          case RDP_PDU_DEACTIVATE:
1263                                    DEBUG(("RDP_PDU_DEACTIVATE\n"));
1264                                  *deactivated = True;                                  *deactivated = True;
1265                                  break;                                  break;
   
1266                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1267                                  disc = process_data_pdu(s, ext_disc_reason);                                  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)                  if (disc)
1275                  {                          return False;
1276                          return;                  cont = g_next_packet < s->end;
                 }  
1277          }          }
1278          return;          return True;
1279  }  }
1280    
1281  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */

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

  ViewVC Help
Powered by ViewVC 1.1.26