/[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 730 by jsorg71, Tue Jun 29 16:22:41 2004 UTC revision 886 by stargo, Sat Apr 16 11:42:34 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;
# Line 35  extern int g_width; Line 49  extern int g_width;
49  extern int g_height;  extern int g_height;
50  extern BOOL g_bitmap_cache;  extern BOOL g_bitmap_cache;
51  extern BOOL g_bitmap_cache_persist_enable;  extern BOOL g_bitmap_cache_persist_enable;
52    extern BOOL g_rdp_compression;
53    
54  uint8 *g_next_packet;  uint8 *g_next_packet;
55  uint32 g_rdp_shareid;  uint32 g_rdp_shareid;
# Line 45  extern RDPCOMP g_mppc_dict; Line 60  extern RDPCOMP g_mppc_dict;
60  static uint32 g_packetno;  static uint32 g_packetno;
61  #endif  #endif
62    
63    #ifdef HAVE_ICONV
64    static BOOL g_iconv_works = True;
65    #endif
66    
67  /* Receive an RDP packet */  /* Receive an RDP packet */
68  static STREAM  static STREAM
69  rdp_recv(uint8 * type)  rdp_recv(uint8 * type)
70  {  {
71          static STREAM rdp_s;          static STREAM rdp_s;
72          uint16 length, pdu_type;          uint16 length, pdu_type;
73            uint8 rdpver;
74    
75          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))
76          {          {
77                  rdp_s = sec_recv();                  rdp_s = sec_recv(&rdpver);
78                  if (rdp_s == NULL)                  if (rdp_s == NULL)
79                          return NULL;                          return NULL;
80                    if (rdpver == 0xff)
81                    {
82                            g_next_packet = rdp_s->end;
83                            *type = 0;
84                            return rdp_s;
85                    }
86                    else if (rdpver != 3)
87                    {
88                            /* rdp5_process should move g_next_packet ok */
89                            rdp5_process(rdp_s);
90                            *type = 0;
91                            return rdp_s;
92                    }
93    
94                  g_next_packet = rdp_s->p;                  g_next_packet = rdp_s->p;
95          }          }
# Line 126  rdp_send_data(STREAM s, uint8 data_pdu_t Line 159  rdp_send_data(STREAM s, uint8 data_pdu_t
159  void  void
160  rdp_out_unistr(STREAM s, char *string, int len)  rdp_out_unistr(STREAM s, char *string, int len)
161  {  {
162          int i = 0, j = 0;  #ifdef HAVE_ICONV
163            size_t ibl = strlen(string), obl = len + 2;
164            static iconv_t iconv_h = (iconv_t) - 1;
165            char *pin = string, *pout = (char *) s->p;
166    
167          len += 2;          memset(pout, 0, len + 4);
168    
169          while (i < len)          if (g_iconv_works)
170          {          {
171                  s->p[i++] = string[j++];                  if (iconv_h == (iconv_t) - 1)
172                  s->p[i++] = 0;                  {
173                            size_t i = 1, o = 4;
174                            if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1)
175                            {
176                                    warning("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n",
177                                            g_codepage, WINDOWS_CODEPAGE, (int) iconv_h);
178    
179                                    g_iconv_works = False;
180                                    rdp_out_unistr(s, string, len);
181                                    return;
182                            }
183                            if (iconv(iconv_h, (ICONV_CONST char **) &pin, &i, &pout, &o) ==
184                                (size_t) - 1)
185                            {
186                                    iconv_close(iconv_h);
187                                    iconv_h = (iconv_t) - 1;
188                                    warning("rdp_out_unistr: iconv(1) fail, errno %d\n", errno);
189    
190                                    g_iconv_works = False;
191                                    rdp_out_unistr(s, string, len);
192                                    return;
193                            }
194                            pin = string;
195                            pout = (char *) s->p;
196                    }
197    
198                    if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
199                    {
200                            iconv_close(iconv_h);
201                            iconv_h = (iconv_t) - 1;
202                            warning("rdp_out_unistr: iconv(2) fail, errno %d\n", errno);
203    
204                            g_iconv_works = False;
205                            rdp_out_unistr(s, string, len);
206                            return;
207                    }
208    
209                    s->p += len + 2;
210    
211          }          }
212            else
213    #endif
214            {
215                    int i = 0, j = 0;
216    
217                    len += 2;
218    
219                    while (i < len)
220                    {
221                            s->p[i++] = string[j++];
222                            s->p[i++] = 0;
223                    }
224    
225          s->p += len;                  s->p += len;
226            }
227  }  }
228    
229  /* Input a string in Unicode  /* Input a string in Unicode
# Line 146  rdp_out_unistr(STREAM s, char *string, i Line 233  rdp_out_unistr(STREAM s, char *string, i
233  int  int
234  rdp_in_unistr(STREAM s, char *string, int uni_len)  rdp_in_unistr(STREAM s, char *string, int uni_len)
235  {  {
236          int i = 0;  #ifdef HAVE_ICONV
237            size_t ibl = uni_len, obl = uni_len;
238            char *pin = (char *) s->p, *pout = string;
239            static iconv_t iconv_h = (iconv_t) - 1;
240    
241          while (i < uni_len / 2)          if (g_iconv_works)
242          {          {
243                  in_uint8a(s, &string[i++], 1);                  if (iconv_h == (iconv_t) - 1)
244                  in_uint8s(s, 1);                  {
245                            if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1)
246                            {
247                                    warning("rdp_in_unistr: iconv_open[%s -> %s] fail %d\n",
248                                            WINDOWS_CODEPAGE, g_codepage, (int) iconv_h);
249    
250                                    g_iconv_works = False;
251                                    return rdp_in_unistr(s, string, uni_len);
252                            }
253                    }
254    
255                    if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
256                    {
257                            iconv_close(iconv_h);
258                            iconv_h = (iconv_t) - 1;
259                            warning("rdp_in_unistr: iconv fail, errno %d\n", errno);
260    
261                            g_iconv_works = False;
262                            return rdp_in_unistr(s, string, uni_len);
263                    }
264                    return pout - string;
265          }          }
266            else
267    #endif
268            {
269                    int i = 0;
270    
271                    while (i < uni_len / 2)
272                    {
273                            in_uint8a(s, &string[i++], 1);
274                            in_uint8s(s, 1);
275                    }
276    
277          return i - 1;                  return i - 1;
278            }
279  }  }
280    
281    
# Line 372  static void Line 493  static void
493  rdp_enum_bmpcache2(void)  rdp_enum_bmpcache2(void)
494  {  {
495          STREAM s;          STREAM s;
496          uint8 idlist[BMPCACHE2_NUM_PSTCELLS * sizeof(BITMAP_ID)];          HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS];
497          uint32 nids, offset, count, flags;          uint32 num_keys, offset, count, flags;
498    
499          offset = 0;          offset = 0;
500          nids = pstcache_enumerate(2, idlist);          num_keys = pstcache_enumerate(2, keylist);
501    
502          while (offset < nids)          while (offset < num_keys)
503          {          {
504                  count = MIN(nids - offset, 169);                  count = MIN(num_keys - offset, 169);
505    
506                  s = rdp_init_data(24 + count * sizeof(BITMAP_ID));                  s = rdp_init_data(24 + count * sizeof(HASH_KEY));
507    
508                  flags = 0;                  flags = 0;
509                  if (offset == 0)                  if (offset == 0)
510                          flags |= PDU_FLAG_FIRST;                          flags |= PDU_FLAG_FIRST;
511                  if (nids - offset <= 169)                  if (num_keys - offset <= 169)
512                          flags |= PDU_FLAG_LAST;                          flags |= PDU_FLAG_LAST;
513    
514                  /* header */                  /* header */
# Line 397  rdp_enum_bmpcache2(void) Line 518  rdp_enum_bmpcache2(void)
518                  out_uint16_le(s, 0);                  out_uint16_le(s, 0);
519                  out_uint16_le(s, 0);                  out_uint16_le(s, 0);
520                  out_uint16_le(s, 0);                  out_uint16_le(s, 0);
521                  out_uint16_le(s, nids);                  out_uint16_le(s, num_keys);
522                  out_uint32_le(s, 0);                  out_uint32_le(s, 0);
523                  out_uint32_le(s, flags);                  out_uint32_le(s, flags);
524    
525                  /* list */                  /* list */
526                  out_uint8a(s, idlist + offset * sizeof(BITMAP_ID),                  out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
                                 count * sizeof(BITMAP_ID));  
527    
528                  s_mark_end(s);                  s_mark_end(s);
529                  rdp_send_data(s, 0x2b);                  rdp_send_data(s, 0x2b);
# Line 482  rdp_out_order_caps(STREAM s) Line 602  rdp_out_order_caps(STREAM s)
602  {  {
603          uint8 order_caps[32];          uint8 order_caps[32];
604    
   
605          memset(order_caps, 0, 32);          memset(order_caps, 0, 32);
606          order_caps[0] = 1;      /* dest blt */          order_caps[0] = 1;      /* dest blt */
607          order_caps[1] = 1;      /* pat blt */          order_caps[1] = 1;      /* pat blt */
608          order_caps[2] = 1;      /* screen blt */          order_caps[2] = 1;      /* screen blt */
609          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
610            order_caps[4] = 0;      /* triblt */
611          order_caps[8] = 1;      /* line */          order_caps[8] = 1;      /* line */
612          order_caps[9] = 1;      /* line */          order_caps[9] = 1;      /* line */
613          order_caps[10] = 1;     /* rect */          order_caps[10] = 1;     /* rect */
614          order_caps[11] = (g_desktop_save == False ? 0 : 1);     /* desksave */          order_caps[11] = (g_desktop_save ? 1 : 0);      /* desksave */
615          order_caps[13] = 1;     /* memblt */          order_caps[13] = 1;     /* memblt */
616          order_caps[14] = 1;     /* triblt */          order_caps[14] = 1;     /* triblt */
617            order_caps[20] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon */
618            order_caps[21] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon2 */
619          order_caps[22] = 1;     /* polyline */          order_caps[22] = 1;     /* polyline */
620            order_caps[25] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse */
621            order_caps[26] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse2 */
622          order_caps[27] = 1;     /* text2 */          order_caps[27] = 1;     /* text2 */
623          out_uint16_le(s, RDP_CAPSET_ORDER);          out_uint16_le(s, RDP_CAPSET_ORDER);
624          out_uint16_le(s, RDP_CAPLEN_ORDER);          out_uint16_le(s, RDP_CAPLEN_ORDER);
# Line 536  rdp_out_bmpcache_caps(STREAM s) Line 660  rdp_out_bmpcache_caps(STREAM s)
660  static void  static void
661  rdp_out_bmpcache2_caps(STREAM s)  rdp_out_bmpcache2_caps(STREAM s)
662  {  {
663            uint16 cellsize;
664    
665          out_uint16_le(s, RDP_CAPSET_BMPCACHE2);          out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
666          out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);          out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
667    
668          out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */          out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
669    
670          out_uint16_le(s, 0x0300);       /* flags? number of caches? */          /* Cellsize:
671               01 = 16x16, 02 = 32x32, 03 = 64x64
672               log2(cell size) - 3
673             */
674    
675            cellsize = 0x03;
676    
677            if (g_rdp_compression)
678            {
679                    switch (g_server_bpp)
680                    {
681                            case 24:
682                            case 16:
683                            case 15:
684                                    cellsize = 0x02;
685                                    break;
686                    }
687            }
688    
689            out_uint16_le(s, (0x0000 | (cellsize << 8)));   /* flags? number of caches? */
690    
691          out_uint32_le(s, BMPCACHE2_C0_CELLS);          out_uint32_le(s, BMPCACHE2_C0_CELLS);
692          out_uint32_le(s, BMPCACHE2_C1_CELLS);          out_uint32_le(s, BMPCACHE2_C1_CELLS);
# Line 553  rdp_out_bmpcache2_caps(STREAM s) Line 698  rdp_out_bmpcache2_caps(STREAM s)
698          {          {
699                  out_uint32_le(s, BMPCACHE2_C2_CELLS);                  out_uint32_le(s, BMPCACHE2_C2_CELLS);
700          }          }
701          out_uint8s(s, 20);              /* other bitmap caches not used */          out_uint8s(s, 20);      /* other bitmap caches not used */
702  }  }
703    
704  /* Output control capability set */  /* Output control capability set */
# Line 644  static uint8 caps_0x10[] = { Line 789  static uint8 caps_0x10[] = {
789    
790  /* Output unknown capability sets */  /* Output unknown capability sets */
791  static void  static void
792  rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 *caps)  rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
793  {  {
794          out_uint16_le(s, id);          out_uint16_le(s, id);
795          out_uint16_le(s, length);          out_uint16_le(s, length);
# Line 664  rdp_send_confirm_active(void) Line 809  rdp_send_confirm_active(void)
809                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
810                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
811                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
812                  0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */ +                  0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
813                  4 /* w2k fix, why? */ ;                  4 /* w2k fix, why? */ ;
814    
815          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
# Line 692  rdp_send_confirm_active(void) Line 837  rdp_send_confirm_active(void)
837          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
838          rdp_out_share_caps(s);          rdp_out_share_caps(s);
839    
840          rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */          rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
841          rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);          rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
842          rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);          rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
843          rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */          rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
844                                    
845          s_mark_end(s);          s_mark_end(s);
846          sec_send(s, sec_flags);          sec_send(s, sec_flags);
847  }  }
# Line 740  rdp_process_bitmap_caps(STREAM s) Line 885  rdp_process_bitmap_caps(STREAM s)
885          if (g_width != width || g_height != height)          if (g_width != width || g_height != height)
886          {          {
887                  warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,                  warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
888                                  width, height);                          width, height);
889                  g_width = width;                  g_width = width;
890                  g_height = height;                  g_height = height;
891                  ui_resize_window();                  ui_resize_window();
# Line 1078  process_data_pdu(STREAM s, uint32 * ext_ Line 1223  process_data_pdu(STREAM s, uint32 * ext_
1223    
1224          if (ctype & RDP_MPPC_COMPRESSED)          if (ctype & RDP_MPPC_COMPRESSED)
1225          {          {
1226                    if (len > RDP_MPPC_DICT_SIZE)
1227                            error("error decompressed packet size exceeds max\n");
1228                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1229                          error("error while decompressing packet\n");                          error("error while decompressing packet\n");
1230    
1231                  //len -= 18;                  /* len -= 18; */
1232    
1233                  /* allocate memory and copy the uncompressed data into the temporary stream */                  /* allocate memory and copy the uncompressed data into the temporary stream */
1234                  ns->data = (uint8 *) xrealloc(ns->data, rlen);                  ns->data = (uint8 *) xrealloc(ns->data, rlen);
# Line 1135  process_data_pdu(STREAM s, uint32 * ext_ Line 1281  process_data_pdu(STREAM s, uint32 * ext_
1281  }  }
1282    
1283  /* Process incoming packets */  /* Process incoming packets */
1284    /* nevers gets out of here till app is done */
1285  void  void
1286  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1287  {  {
1288          uint8 type;          while (rdp_loop(deactivated, ext_disc_reason))
1289          BOOL disc = False;      /* True when a disconnect PDU was received */                  ;
         STREAM s;  
   
         while ((s = rdp_recv(&type)) != NULL)  
         {  
                 switch (type)  
                 {  
                         case RDP_PDU_DEMAND_ACTIVE:  
                                 process_demand_active(s);  
                                 *deactivated = False;  
                                 break;  
   
                         case RDP_PDU_DEACTIVATE:  
                                 DEBUG(("RDP_PDU_DEACTIVATE\n"));  
                                 *deactivated = True;  
                                 break;  
   
                         case RDP_PDU_DATA:  
                                 disc = process_data_pdu(s, ext_disc_reason);  
                                 break;  
   
                         case 0:  
                                 break;  
   
                         default:  
                                 unimpl("PDU %d\n", type);  
                 }  
   
                 if (disc)  
                 {  
                         return;  
                 }  
         }  
         return;  
1290  }  }
1291    
1292  /* used in uiports, processes the rdp packets waiting */  /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1293  BOOL  BOOL
1294  rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)  rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1295  {  {

Legend:
Removed from v.730  
changed lines
  Added in v.886

  ViewVC Help
Powered by ViewVC 1.1.26