/[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 733 by jsorg71, Mon Jul 5 19:09:07 2004 UTC revision 905 by jdmeijer, Fri May 20 22:09:32 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 45  extern RDPCOMP g_mppc_dict; Line 59  extern RDPCOMP g_mppc_dict;
59  static uint32 g_packetno;  static uint32 g_packetno;
60  #endif  #endif
61    
62    #ifdef HAVE_ICONV
63    static BOOL g_iconv_works = True;
64    #endif
65    
66  /* Receive an RDP packet */  /* Receive an RDP packet */
67  static STREAM  static STREAM
68  rdp_recv(uint8 * type)  rdp_recv(uint8 * type)
# Line 58  rdp_recv(uint8 * type) Line 76  rdp_recv(uint8 * type)
76                  rdp_s = sec_recv(&rdpver);                  rdp_s = sec_recv(&rdpver);
77                  if (rdp_s == NULL)                  if (rdp_s == NULL)
78                          return NULL;                          return NULL;
79                  if (rdpver != 3)                  if (rdpver == 0xff)
80                    {
81                            g_next_packet = rdp_s->end;
82                            *type = 0;
83                            return rdp_s;
84                    }
85                    else if (rdpver != 3)
86                  {                  {
87                          /* rdp5_process should move g_next_packet ok */                          /* rdp5_process should move g_next_packet ok */
88                          rdp5_process(rdp_s);                          rdp5_process(rdp_s);
# Line 134  rdp_send_data(STREAM s, uint8 data_pdu_t Line 158  rdp_send_data(STREAM s, uint8 data_pdu_t
158  void  void
159  rdp_out_unistr(STREAM s, char *string, int len)  rdp_out_unistr(STREAM s, char *string, int len)
160  {  {
161          int i = 0, j = 0;  #ifdef HAVE_ICONV
162            size_t ibl = strlen(string), obl = len + 2;
163            static iconv_t iconv_h = (iconv_t) - 1;
164            char *pin = string, *pout = (char *) s->p;
165    
166          len += 2;          memset(pout, 0, len + 4);
167    
168          while (i < len)          if (g_iconv_works)
169          {          {
170                  s->p[i++] = string[j++];                  if (iconv_h == (iconv_t) - 1)
171                  s->p[i++] = 0;                  {
172                            size_t i = 1, o = 4;
173                            if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1)
174                            {
175                                    warning("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n",
176                                            g_codepage, WINDOWS_CODEPAGE, (int) iconv_h);
177    
178                                    g_iconv_works = False;
179                                    rdp_out_unistr(s, string, len);
180                                    return;
181                            }
182                            if (iconv(iconv_h, (ICONV_CONST char **) &pin, &i, &pout, &o) ==
183                                (size_t) - 1)
184                            {
185                                    iconv_close(iconv_h);
186                                    iconv_h = (iconv_t) - 1;
187                                    warning("rdp_out_unistr: iconv(1) fail, errno %d\n", errno);
188    
189                                    g_iconv_works = False;
190                                    rdp_out_unistr(s, string, len);
191                                    return;
192                            }
193                            pin = string;
194                            pout = (char *) s->p;
195                    }
196    
197                    if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
198                    {
199                            iconv_close(iconv_h);
200                            iconv_h = (iconv_t) - 1;
201                            warning("rdp_out_unistr: iconv(2) fail, errno %d\n", errno);
202    
203                            g_iconv_works = False;
204                            rdp_out_unistr(s, string, len);
205                            return;
206                    }
207    
208                    s->p += len + 2;
209    
210          }          }
211            else
212    #endif
213            {
214                    int i = 0, j = 0;
215    
216                    len += 2;
217    
218                    while (i < len)
219                    {
220                            s->p[i++] = string[j++];
221                            s->p[i++] = 0;
222                    }
223    
224          s->p += len;                  s->p += len;
225            }
226  }  }
227    
228  /* Input a string in Unicode  /* Input a string in Unicode
# Line 154  rdp_out_unistr(STREAM s, char *string, i Line 232  rdp_out_unistr(STREAM s, char *string, i
232  int  int
233  rdp_in_unistr(STREAM s, char *string, int uni_len)  rdp_in_unistr(STREAM s, char *string, int uni_len)
234  {  {
235          int i = 0;  #ifdef HAVE_ICONV
236            size_t ibl = uni_len, obl = uni_len;
237            char *pin = (char *) s->p, *pout = string;
238            static iconv_t iconv_h = (iconv_t) - 1;
239    
240          while (i < uni_len / 2)          if (g_iconv_works)
241          {          {
242                  in_uint8a(s, &string[i++], 1);                  if (iconv_h == (iconv_t) - 1)
243                  in_uint8s(s, 1);                  {
244                            if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1)
245                            {
246                                    warning("rdp_in_unistr: iconv_open[%s -> %s] fail %d\n",
247                                            WINDOWS_CODEPAGE, g_codepage, (int) iconv_h);
248    
249                                    g_iconv_works = False;
250                                    return rdp_in_unistr(s, string, uni_len);
251                            }
252                    }
253    
254                    if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
255                    {
256                            iconv_close(iconv_h);
257                            iconv_h = (iconv_t) - 1;
258                            warning("rdp_in_unistr: iconv fail, errno %d\n", errno);
259    
260                            g_iconv_works = False;
261                            return rdp_in_unistr(s, string, uni_len);
262                    }
263                    return pout - string;
264          }          }
265            else
266    #endif
267            {
268                    int i = 0;
269    
270                    while (i < uni_len / 2)
271                    {
272                            in_uint8a(s, &string[i++], 1);
273                            in_uint8s(s, 1);
274                    }
275    
276          return i - 1;                  return i - 1;
277            }
278  }  }
279    
280    
# Line 185  rdp_send_logon_info(uint32 flags, char * Line 297  rdp_send_logon_info(uint32 flags, char *
297          time_t t = time(NULL);          time_t t = time(NULL);
298          time_t tzone;          time_t tzone;
299    
 #if 0  
         /* enable rdp compression */  
         /* some problems still exist with rdp5 */  
         flags |= RDP_COMPRESSION;  
 #endif  
   
300          if (!g_use_rdp5 || 1 == g_server_rdp_version)          if (!g_use_rdp5 || 1 == g_server_rdp_version)
301          {          {
302                  DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));                  DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
# Line 375  rdp_send_input(uint32 time, uint16 messa Line 481  rdp_send_input(uint32 time, uint16 messa
481          rdp_send_data(s, RDP_DATA_PDU_INPUT);          rdp_send_data(s, RDP_DATA_PDU_INPUT);
482  }  }
483    
484  /* Inform the server on the contents of the persistent bitmap cache */  /* Send a client window information PDU */
485    void
486    rdp_send_client_window_status(int status)
487    {
488            STREAM s;
489    
490            s = rdp_init_data(12);
491    
492            out_uint32_le(s, status);
493    
494            switch (status)
495            {
496                    case 0: /* shut the server up */
497                            break;
498    
499                    case 1: /* receive data again */
500                            out_uint32_le(s, 0);    /* unknown */
501                            out_uint16_le(s, g_width);
502                            out_uint16_le(s, g_height);
503                            break;
504            }
505    
506            s_mark_end(s);
507            rdp_send_data(s, RDP_DATA_PDU_CLIENT_WINDOW_STATUS);
508    }
509    
510    /* Send persistent bitmap cache enumeration PDU's */
511  static void  static void
512  rdp_enum_bmpcache2(void)  rdp_enum_bmpcache2(void)
513  {  {
514          STREAM s;          STREAM s;
515          uint8 idlist[BMPCACHE2_NUM_PSTCELLS * sizeof(BITMAP_ID)];          HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS];
516          uint32 nids, offset, count, flags;          uint32 num_keys, offset, count, flags;
517    
518          offset = 0;          offset = 0;
519          nids = pstcache_enumerate(2, idlist);          num_keys = pstcache_enumerate(2, keylist);
520    
521          while (offset < nids)          while (offset < num_keys)
522          {          {
523                  count = MIN(nids - offset, 169);                  count = MIN(num_keys - offset, 169);
524    
525                  s = rdp_init_data(24 + count * sizeof(BITMAP_ID));                  s = rdp_init_data(24 + count * sizeof(HASH_KEY));
526    
527                  flags = 0;                  flags = 0;
528                  if (offset == 0)                  if (offset == 0)
529                          flags |= PDU_FLAG_FIRST;                          flags |= PDU_FLAG_FIRST;
530                  if (nids - offset <= 169)                  if (num_keys - offset <= 169)
531                          flags |= PDU_FLAG_LAST;                          flags |= PDU_FLAG_LAST;
532    
533                  /* header */                  /* header */
# Line 405  rdp_enum_bmpcache2(void) Line 537  rdp_enum_bmpcache2(void)
537                  out_uint16_le(s, 0);                  out_uint16_le(s, 0);
538                  out_uint16_le(s, 0);                  out_uint16_le(s, 0);
539                  out_uint16_le(s, 0);                  out_uint16_le(s, 0);
540                  out_uint16_le(s, nids);                  out_uint16_le(s, num_keys);
541                  out_uint32_le(s, 0);                  out_uint32_le(s, 0);
542                  out_uint32_le(s, flags);                  out_uint32_le(s, flags);
543    
544                  /* list */                  /* list */
545                  out_uint8a(s, idlist + offset * sizeof(BITMAP_ID),                  out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
                                 count * sizeof(BITMAP_ID));  
546    
547                  s_mark_end(s);                  s_mark_end(s);
548                  rdp_send_data(s, 0x2b);                  rdp_send_data(s, 0x2b);
# Line 490  rdp_out_order_caps(STREAM s) Line 621  rdp_out_order_caps(STREAM s)
621  {  {
622          uint8 order_caps[32];          uint8 order_caps[32];
623    
   
624          memset(order_caps, 0, 32);          memset(order_caps, 0, 32);
625          order_caps[0] = 1;      /* dest blt */          order_caps[0] = 1;      /* dest blt */
626          order_caps[1] = 1;      /* pat blt */          order_caps[1] = 1;      /* pat blt */
627          order_caps[2] = 1;      /* screen blt */          order_caps[2] = 1;      /* screen blt */
628          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
629            order_caps[4] = 0;      /* triblt */
630          order_caps[8] = 1;      /* line */          order_caps[8] = 1;      /* line */
631          order_caps[9] = 1;      /* line */          order_caps[9] = 1;      /* line */
632          order_caps[10] = 1;     /* rect */          order_caps[10] = 1;     /* rect */
633          order_caps[11] = (g_desktop_save == False ? 0 : 1);     /* desksave */          order_caps[11] = (g_desktop_save ? 1 : 0);      /* desksave */
634          order_caps[13] = 1;     /* memblt */          order_caps[13] = 1;     /* memblt */
635          order_caps[14] = 1;     /* triblt */          order_caps[14] = 1;     /* triblt */
636            order_caps[20] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon */
637            order_caps[21] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon2 */
638          order_caps[22] = 1;     /* polyline */          order_caps[22] = 1;     /* polyline */
639            order_caps[25] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse */
640            order_caps[26] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse2 */
641          order_caps[27] = 1;     /* text2 */          order_caps[27] = 1;     /* text2 */
642          out_uint16_le(s, RDP_CAPSET_ORDER);          out_uint16_le(s, RDP_CAPSET_ORDER);
643          out_uint16_le(s, RDP_CAPLEN_ORDER);          out_uint16_le(s, RDP_CAPLEN_ORDER);
# Line 549  rdp_out_bmpcache2_caps(STREAM s) Line 684  rdp_out_bmpcache2_caps(STREAM s)
684    
685          out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */          out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
686    
687          out_uint16_le(s, 0x0300);       /* flags? number of caches? */          out_uint16_be(s, 3);    /* number of caches in this set */
688    
689            /* max cell size for cache 0 is 16x16, 1 = 32x32, 2 = 64x64, etc */
690          out_uint32_le(s, BMPCACHE2_C0_CELLS);          out_uint32_le(s, BMPCACHE2_C0_CELLS);
691          out_uint32_le(s, BMPCACHE2_C1_CELLS);          out_uint32_le(s, BMPCACHE2_C1_CELLS);
692          if (pstcache_init(2))          if (pstcache_init(2))
# Line 561  rdp_out_bmpcache2_caps(STREAM s) Line 697  rdp_out_bmpcache2_caps(STREAM s)
697          {          {
698                  out_uint32_le(s, BMPCACHE2_C2_CELLS);                  out_uint32_le(s, BMPCACHE2_C2_CELLS);
699          }          }
700          out_uint8s(s, 20);              /* other bitmap caches not used */          out_uint8s(s, 20);      /* other bitmap caches not used */
701  }  }
702    
703  /* Output control capability set */  /* Output control capability set */
# Line 652  static uint8 caps_0x10[] = { Line 788  static uint8 caps_0x10[] = {
788    
789  /* Output unknown capability sets */  /* Output unknown capability sets */
790  static void  static void
791  rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 *caps)  rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
792  {  {
793          out_uint16_le(s, id);          out_uint16_le(s, id);
794          out_uint16_le(s, length);          out_uint16_le(s, length);
# Line 672  rdp_send_confirm_active(void) Line 808  rdp_send_confirm_active(void)
808                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
809                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
810                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
811                  0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */ +                  0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
812                  4 /* w2k fix, why? */ ;                  4 /* w2k fix, why? */ ;
813    
814          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
# Line 700  rdp_send_confirm_active(void) Line 836  rdp_send_confirm_active(void)
836          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
837          rdp_out_share_caps(s);          rdp_out_share_caps(s);
838    
839          rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */          rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
840          rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);          rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
841          rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);          rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
842          rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */          rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
843                                    
844          s_mark_end(s);          s_mark_end(s);
845          sec_send(s, sec_flags);          sec_send(s, sec_flags);
846  }  }
# Line 748  rdp_process_bitmap_caps(STREAM s) Line 884  rdp_process_bitmap_caps(STREAM s)
884          if (g_width != width || g_height != height)          if (g_width != width || g_height != height)
885          {          {
886                  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,
887                                  width, height);                          width, height);
888                  g_width = width;                  g_width = width;
889                  g_height = height;                  g_height = height;
890                  ui_resize_window();                  ui_resize_window();
# Line 1086  process_data_pdu(STREAM s, uint32 * ext_ Line 1222  process_data_pdu(STREAM s, uint32 * ext_
1222    
1223          if (ctype & RDP_MPPC_COMPRESSED)          if (ctype & RDP_MPPC_COMPRESSED)
1224          {          {
1225                    if (len > RDP_MPPC_DICT_SIZE)
1226                            error("error decompressed packet size exceeds max\n");
1227                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1228                          error("error while decompressing packet\n");                          error("error while decompressing packet\n");
1229    
1230                  //len -= 18;                  /* len -= 18; */
1231    
1232                  /* allocate memory and copy the uncompressed data into the temporary stream */                  /* allocate memory and copy the uncompressed data into the temporary stream */
1233                  ns->data = (uint8 *) xrealloc(ns->data, rlen);                  ns->data = (uint8 *) xrealloc(ns->data, rlen);

Legend:
Removed from v.733  
changed lines
  Added in v.905

  ViewVC Help
Powered by ViewVC 1.1.26