/[rdesktop]/jpeg/rdesktop/trunk/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 /jpeg/rdesktop/trunk/rdp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

sourceforge.net/trunk/rdesktop/rdp.c revision 773 by jsorg71, Sat Sep 11 22:57:42 2004 UTC jpeg/rdesktop/trunk/rdp.c revision 1507 by dpavlin, Mon Jul 20 16:45:11 2009 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-2008
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    #ifndef _WIN32
23    #include <errno.h>
24    #include <unistd.h>
25    #endif
26  #include "rdesktop.h"  #include "rdesktop.h"
27    
28    #ifdef HAVE_ICONV
29    #ifdef HAVE_ICONV_H
30    #include <iconv.h>
31    #endif
32    
33    #ifndef ICONV_CONST
34    #define ICONV_CONST ""
35    #endif
36    #endif
37    
38  extern uint16 g_mcs_userid;  extern uint16 g_mcs_userid;
39  extern char g_username[16];  extern char *g_username;
40  extern BOOL g_bitmap_compression;  extern char g_codepage[16];
41  extern BOOL g_orders;  extern RD_BOOL g_bitmap_compression;
42  extern BOOL g_encryption;  extern RD_BOOL g_orders;
43  extern BOOL g_desktop_save;  extern RD_BOOL g_encryption;
44  extern BOOL g_use_rdp5;  extern RD_BOOL g_desktop_save;
45    extern RD_BOOL g_polygon_ellipse_orders;
46    extern RD_BOOL g_use_rdp5;
47  extern uint16 g_server_rdp_version;  extern uint16 g_server_rdp_version;
48  extern uint32 g_rdp5_performanceflags;  extern uint32 g_rdp5_performanceflags;
49  extern int g_server_bpp;  extern int g_server_depth;
50  extern int g_width;  extern int g_width;
51  extern int g_height;  extern int g_height;
52  extern BOOL g_bitmap_cache;  extern RD_BOOL g_bitmap_cache;
53  extern BOOL g_bitmap_cache_persist_enable;  extern RD_BOOL g_bitmap_cache_persist_enable;
54    extern RD_BOOL g_numlock_sync;
55    
56  uint8 *g_next_packet;  uint8 *g_next_packet;
57  uint32 g_rdp_shareid;  uint32 g_rdp_shareid;
58    
59  extern RDPCOMP g_mppc_dict;  extern RDPCOMP g_mppc_dict;
60    
61    /* Session Directory support */
62    extern RD_BOOL g_redirect;
63    extern char g_redirect_server[64];
64    extern char g_redirect_domain[16];
65    extern char g_redirect_password[64];
66    extern char *g_redirect_username;
67    extern char g_redirect_cookie[128];
68    extern uint32 g_redirect_flags;
69    /* END Session Directory support */
70    
71  #if WITH_DEBUG  #if WITH_DEBUG
72  static uint32 g_packetno;  static uint32 g_packetno;
73  #endif  #endif
74    
75    #ifdef HAVE_ICONV
76    static RD_BOOL g_iconv_works = True;
77    #endif
78    
79  /* Receive an RDP packet */  /* Receive an RDP packet */
80  static STREAM  static STREAM
81  rdp_recv(uint8 * type)  rdp_recv(uint8 * type)
# Line 53  rdp_recv(uint8 * type) Line 84  rdp_recv(uint8 * type)
84          uint16 length, pdu_type;          uint16 length, pdu_type;
85          uint8 rdpver;          uint8 rdpver;
86    
87          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end) || (g_next_packet == NULL))
88          {          {
89                  rdp_s = sec_recv(&rdpver);                  rdp_s = sec_recv(&rdpver);
90                  if (rdp_s == NULL)                  if (rdp_s == NULL)
91                          return NULL;                          return NULL;
92                  if (rdpver != 3)                  if (rdpver == 0xff)
93                    {
94                            g_next_packet = rdp_s->end;
95                            *type = 0;
96                            return rdp_s;
97                    }
98                    else if (rdpver != 3)
99                  {                  {
100                          /* rdp5_process should move g_next_packet ok */                          /* rdp5_process should move g_next_packet ok */
101                          rdp5_process(rdp_s);                          rdp5_process(rdp_s);
# Line 134  rdp_send_data(STREAM s, uint8 data_pdu_t Line 171  rdp_send_data(STREAM s, uint8 data_pdu_t
171  void  void
172  rdp_out_unistr(STREAM s, char *string, int len)  rdp_out_unistr(STREAM s, char *string, int len)
173  {  {
174          int i = 0, j = 0;  #ifdef HAVE_ICONV
175            size_t ibl = strlen(string), obl = len + 2;
176            static iconv_t iconv_h = (iconv_t) - 1;
177            char *pin = string, *pout = (char *) s->p;
178    
179          len += 2;          memset(pout, 0, len + 4);
180    
181          while (i < len)          if (g_iconv_works)
182          {          {
183                  s->p[i++] = string[j++];                  if (iconv_h == (iconv_t) - 1)
184                  s->p[i++] = 0;                  {
185                            size_t i = 1, o = 4;
186                            if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1)
187                            {
188                                    warning("rdp_out_unistr: iconv_open[%s -> %s] fail %p\n",
189                                            g_codepage, WINDOWS_CODEPAGE, iconv_h);
190    
191                                    g_iconv_works = False;
192                                    rdp_out_unistr(s, string, len);
193                                    return;
194                            }
195                            if (iconv(iconv_h, (ICONV_CONST char **) &pin, &i, &pout, &o) ==
196                                (size_t) - 1)
197                            {
198                                    iconv_close(iconv_h);
199                                    iconv_h = (iconv_t) - 1;
200                                    warning("rdp_out_unistr: iconv(1) fail, errno %d\n", errno);
201    
202                                    g_iconv_works = False;
203                                    rdp_out_unistr(s, string, len);
204                                    return;
205                            }
206                            pin = string;
207                            pout = (char *) s->p;
208                    }
209    
210                    if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
211                    {
212                            iconv_close(iconv_h);
213                            iconv_h = (iconv_t) - 1;
214                            warning("rdp_out_unistr: iconv(2) fail, errno %d\n", errno);
215    
216                            g_iconv_works = False;
217                            rdp_out_unistr(s, string, len);
218                            return;
219                    }
220    
221                    s->p += len + 2;
222    
223          }          }
224            else
225    #endif
226            {
227                    int i = 0, j = 0;
228    
229          s->p += len;                  len += 2;
230    
231                    while (i < len)
232                    {
233                            s->p[i++] = string[j++];
234                            s->p[i++] = 0;
235                    }
236    
237                    s->p += len;
238            }
239  }  }
240    
241  /* Input a string in Unicode  /* Input a string in Unicode
# Line 152  rdp_out_unistr(STREAM s, char *string, i Line 243  rdp_out_unistr(STREAM s, char *string, i
243   * Returns str_len of string   * Returns str_len of string
244   */   */
245  int  int
246  rdp_in_unistr(STREAM s, char *string, int uni_len)  rdp_in_unistr(STREAM s, char *string, int str_size, int in_len)
247  {  {
248          int i = 0;  #ifdef HAVE_ICONV
249            size_t ibl = in_len, obl = str_size - 1;
250            char *pin = (char *) s->p, *pout = string;
251            static iconv_t iconv_h = (iconv_t) - 1;
252    
253          while (i < uni_len / 2)          if (g_iconv_works)
254          {          {
255                  in_uint8a(s, &string[i++], 1);                  if (iconv_h == (iconv_t) - 1)
256                  in_uint8s(s, 1);                  {
257                            if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1)
258                            {
259                                    warning("rdp_in_unistr: iconv_open[%s -> %s] fail %p\n",
260                                            WINDOWS_CODEPAGE, g_codepage, iconv_h);
261    
262                                    g_iconv_works = False;
263                                    return rdp_in_unistr(s, string, str_size, in_len);
264                            }
265                    }
266    
267                    if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
268                    {
269                            if (errno == E2BIG)
270                            {
271                                    warning("server sent an unexpectedly long string, truncating\n");
272                            }
273                            else
274                            {
275                                    iconv_close(iconv_h);
276                                    iconv_h = (iconv_t) - 1;
277                                    warning("rdp_in_unistr: iconv fail, errno %d\n", errno);
278    
279                                    g_iconv_works = False;
280                                    return rdp_in_unistr(s, string, str_size, in_len);
281                            }
282                    }
283    
284                    /* we must update the location of the current STREAM for future reads of s->p */
285                    s->p += in_len;
286    
287                    *pout = 0;
288                    return pout - string;
289          }          }
290            else
291    #endif
292            {
293                    int i = 0;
294                    int len = in_len / 2;
295                    int rem = 0;
296    
297                    if (len > str_size - 1)
298                    {
299                            warning("server sent an unexpectedly long string, truncating\n");
300                            len = str_size - 1;
301                            rem = in_len - 2 * len;
302                    }
303    
304          return i - 1;                  while (i < len)
305                    {
306                            in_uint8a(s, &string[i++], 1);
307                            in_uint8s(s, 1);
308                    }
309    
310                    in_uint8s(s, rem);
311                    string[len] = 0;
312                    return len;
313            }
314  }  }
315    
316    
# Line 185  rdp_send_logon_info(uint32 flags, char * Line 333  rdp_send_logon_info(uint32 flags, char *
333          time_t t = time(NULL);          time_t t = time(NULL);
334          time_t tzone;          time_t tzone;
335    
 #if 0  
         /* enable rdp compression */  
         /* some problems still exist with rdp5 */  
         flags |= RDP_COMPRESSION;  
 #endif  
   
336          if (!g_use_rdp5 || 1 == g_server_rdp_version)          if (!g_use_rdp5 || 1 == g_server_rdp_version)
337          {          {
338                  DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));                  DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
# Line 315  rdp_send_logon_info(uint32 flags, char * Line 457  rdp_send_logon_info(uint32 flags, char *
457                  out_uint32_le(s, 0xffffffc4);                  out_uint32_le(s, 0xffffffc4);
458                  out_uint32_le(s, 0xfffffffe);                  out_uint32_le(s, 0xfffffffe);
459                  out_uint32_le(s, g_rdp5_performanceflags);                  out_uint32_le(s, g_rdp5_performanceflags);
460                  out_uint32(s, 0);                  out_uint16(s, 0);
461    
462    
463          }          }
# Line 375  rdp_send_input(uint32 time, uint16 messa Line 517  rdp_send_input(uint32 time, uint16 messa
517          rdp_send_data(s, RDP_DATA_PDU_INPUT);          rdp_send_data(s, RDP_DATA_PDU_INPUT);
518  }  }
519    
520  /* Inform the server on the contents of the persistent bitmap cache */  /* Send a client window information PDU */
521    void
522    rdp_send_client_window_status(int status)
523    {
524            STREAM s;
525            static int current_status = 1;
526    
527            if (current_status == status)
528                    return;
529    
530            s = rdp_init_data(12);
531    
532            out_uint32_le(s, status);
533    
534            switch (status)
535            {
536                    case 0: /* shut the server up */
537                            break;
538    
539                    case 1: /* receive data again */
540                            out_uint32_le(s, 0);    /* unknown */
541                            out_uint16_le(s, g_width);
542                            out_uint16_le(s, g_height);
543                            break;
544            }
545    
546            s_mark_end(s);
547            rdp_send_data(s, RDP_DATA_PDU_CLIENT_WINDOW_STATUS);
548            current_status = status;
549    }
550    
551    /* Send persistent bitmap cache enumeration PDU's */
552  static void  static void
553  rdp_enum_bmpcache2(void)  rdp_enum_bmpcache2(void)
554  {  {
555          STREAM s;          STREAM s;
556          uint8 idlist[BMPCACHE2_NUM_PSTCELLS * sizeof(BITMAP_ID)];          HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS];
557          uint32 nids, offset, count, flags;          uint32 num_keys, offset, count, flags;
558    
559          offset = 0;          offset = 0;
560          nids = pstcache_enumerate(2, idlist);          num_keys = pstcache_enumerate(2, keylist);
561    
562          while (offset < nids)          while (offset < num_keys)
563          {          {
564                  count = MIN(nids - offset, 169);                  count = MIN(num_keys - offset, 169);
565    
566                  s = rdp_init_data(24 + count * sizeof(BITMAP_ID));                  s = rdp_init_data(24 + count * sizeof(HASH_KEY));
567    
568                  flags = 0;                  flags = 0;
569                  if (offset == 0)                  if (offset == 0)
570                          flags |= PDU_FLAG_FIRST;                          flags |= PDU_FLAG_FIRST;
571                  if (nids - offset <= 169)                  if (num_keys - offset <= 169)
572                          flags |= PDU_FLAG_LAST;                          flags |= PDU_FLAG_LAST;
573    
574                  /* header */                  /* header */
# Line 405  rdp_enum_bmpcache2(void) Line 578  rdp_enum_bmpcache2(void)
578                  out_uint16_le(s, 0);                  out_uint16_le(s, 0);
579                  out_uint16_le(s, 0);                  out_uint16_le(s, 0);
580                  out_uint16_le(s, 0);                  out_uint16_le(s, 0);
581                  out_uint16_le(s, nids);                  out_uint16_le(s, num_keys);
582                  out_uint32_le(s, 0);                  out_uint32_le(s, 0);
583                  out_uint32_le(s, flags);                  out_uint32_le(s, flags);
584    
585                  /* list */                  /* list */
586                  out_uint8a(s, idlist + offset * sizeof(BITMAP_ID), count * sizeof(BITMAP_ID));                  out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
587    
588                  s_mark_end(s);                  s_mark_end(s);
589                  rdp_send_data(s, 0x2b);                  rdp_send_data(s, 0x2b);
# Line 469  rdp_out_bitmap_caps(STREAM s) Line 642  rdp_out_bitmap_caps(STREAM s)
642          out_uint16_le(s, RDP_CAPSET_BITMAP);          out_uint16_le(s, RDP_CAPSET_BITMAP);
643          out_uint16_le(s, RDP_CAPLEN_BITMAP);          out_uint16_le(s, RDP_CAPLEN_BITMAP);
644    
645          out_uint16_le(s, g_server_bpp); /* Preferred BPP */          out_uint16_le(s, g_server_depth);       /* Preferred colour depth */
646          out_uint16_le(s, 1);    /* Receive 1 BPP */          out_uint16_le(s, 1);    /* Receive 1 BPP */
647          out_uint16_le(s, 1);    /* Receive 4 BPP */          out_uint16_le(s, 1);    /* Receive 4 BPP */
648          out_uint16_le(s, 1);    /* Receive 8 BPP */          out_uint16_le(s, 1);    /* Receive 8 BPP */
# Line 489  rdp_out_order_caps(STREAM s) Line 662  rdp_out_order_caps(STREAM s)
662  {  {
663          uint8 order_caps[32];          uint8 order_caps[32];
664    
   
665          memset(order_caps, 0, 32);          memset(order_caps, 0, 32);
666          order_caps[0] = 1;      /* dest blt */          order_caps[0] = 1;      /* dest blt */
667          order_caps[1] = 1;      /* pat blt */          order_caps[1] = 1;      /* pat blt */
668          order_caps[2] = 1;      /* screen blt */          order_caps[2] = 1;      /* screen blt */
669          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
670            order_caps[4] = 0;      /* triblt */
671          order_caps[8] = 1;      /* line */          order_caps[8] = 1;      /* line */
672          order_caps[9] = 1;      /* line */          order_caps[9] = 1;      /* line */
673          order_caps[10] = 1;     /* rect */          order_caps[10] = 1;     /* rect */
674          order_caps[11] = (g_desktop_save == False ? 0 : 1);     /* desksave */          order_caps[11] = (g_desktop_save ? 1 : 0);      /* desksave */
675          order_caps[13] = 1;     /* memblt */          order_caps[13] = 1;     /* memblt */
676          order_caps[14] = 1;     /* triblt */          order_caps[14] = 1;     /* triblt */
677            order_caps[20] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon */
678            order_caps[21] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon2 */
679          order_caps[22] = 1;     /* polyline */          order_caps[22] = 1;     /* polyline */
680            order_caps[25] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse */
681            order_caps[26] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse2 */
682          order_caps[27] = 1;     /* text2 */          order_caps[27] = 1;     /* text2 */
683          out_uint16_le(s, RDP_CAPSET_ORDER);          out_uint16_le(s, RDP_CAPSET_ORDER);
684          out_uint16_le(s, RDP_CAPLEN_ORDER);          out_uint16_le(s, RDP_CAPLEN_ORDER);
# Line 529  rdp_out_bmpcache_caps(STREAM s) Line 706  rdp_out_bmpcache_caps(STREAM s)
706          out_uint16_le(s, RDP_CAPSET_BMPCACHE);          out_uint16_le(s, RDP_CAPSET_BMPCACHE);
707          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
708    
709          Bpp = (g_server_bpp + 7) / 8;          Bpp = (g_server_depth + 7) / 8; /* bytes per pixel */
710          out_uint8s(s, 24);      /* unused */          out_uint8s(s, 24);      /* unused */
711          out_uint16_le(s, 0x258);        /* entries */          out_uint16_le(s, 0x258);        /* entries */
712          out_uint16_le(s, 0x100 * Bpp);  /* max cell size */          out_uint16_le(s, 0x100 * Bpp);  /* max cell size */
# Line 548  rdp_out_bmpcache2_caps(STREAM s) Line 725  rdp_out_bmpcache2_caps(STREAM s)
725    
726          out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */          out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
727    
728          out_uint16_le(s, 0x0300);       /* flags? number of caches? */          out_uint16_be(s, 3);    /* number of caches in this set */
729    
730            /* max cell size for cache 0 is 16x16, 1 = 32x32, 2 = 64x64, etc */
731          out_uint32_le(s, BMPCACHE2_C0_CELLS);          out_uint32_le(s, BMPCACHE2_C0_CELLS);
732          out_uint32_le(s, BMPCACHE2_C1_CELLS);          out_uint32_le(s, BMPCACHE2_C1_CELLS);
733          if (pstcache_init(2))          if (pstcache_init(2))
# Line 622  rdp_out_colcache_caps(STREAM s) Line 800  rdp_out_colcache_caps(STREAM s)
800          out_uint16(s, 0);       /* pad */          out_uint16(s, 0);       /* pad */
801  }  }
802    
803    /* Output brush cache capability set */
804    static void
805    rdp_out_brushcache_caps(STREAM s)
806    {
807            out_uint16_le(s, RDP_CAPSET_BRUSHCACHE);
808            out_uint16_le(s, RDP_CAPLEN_BRUSHCACHE);
809            out_uint32_le(s, 1);    /* cache type */
810    }
811    
812  static uint8 caps_0x0d[] = {  static uint8 caps_0x0d[] = {
813          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
814          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
# Line 671  rdp_send_confirm_active(void) Line 858  rdp_send_confirm_active(void)
858                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
859                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
860                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
861                  0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +                  RDP_CAPLEN_BRUSHCACHE + 0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
862                  4 /* w2k fix, why? */ ;                  4 /* w2k fix, why? */ ;
863    
864          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
# Line 698  rdp_send_confirm_active(void) Line 885  rdp_send_confirm_active(void)
885          rdp_out_control_caps(s);          rdp_out_control_caps(s);
886          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
887          rdp_out_share_caps(s);          rdp_out_share_caps(s);
888            rdp_out_brushcache_caps(s);
889    
890          rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */          rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
891          rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);          rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
# Line 725  rdp_process_general_caps(STREAM s) Line 913  rdp_process_general_caps(STREAM s)
913  static void  static void
914  rdp_process_bitmap_caps(STREAM s)  rdp_process_bitmap_caps(STREAM s)
915  {  {
916          uint16 width, height, bpp;          uint16 width, height, depth;
917    
918          in_uint16_le(s, bpp);          in_uint16_le(s, depth);
919          in_uint8s(s, 6);          in_uint8s(s, 6);
920    
921          in_uint16_le(s, width);          in_uint16_le(s, width);
922          in_uint16_le(s, height);          in_uint16_le(s, height);
923    
924          DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));          DEBUG(("setting desktop size and depth to: %dx%dx%d\n", width, height, depth));
925    
926          /*          /*
927           * The server may limit bpp and change the size of the desktop (for           * The server may limit depth and change the size of the desktop (for
928           * example when shadowing another session).           * example when shadowing another session).
929           */           */
930          if (g_server_bpp != bpp)          if (g_server_depth != depth)
931          {          {
932                  warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);                  warning("Remote desktop does not support colour depth %d; falling back to %d\n",
933                  g_server_bpp = bpp;                          g_server_depth, depth);
934                    g_server_depth = depth;
935          }          }
936          if (g_width != width || g_height != height)          if (g_width != width || g_height != height)
937          {          {
938                  warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,                  warning("Remote desktop changed from %dx%d to %dx%d.\n", g_width, g_height,
939                          width, height);                          width, height);
940                  g_width = width;                  g_width = width;
941                  g_height = height;                  g_height = height;
# Line 755  rdp_process_bitmap_caps(STREAM s) Line 944  rdp_process_bitmap_caps(STREAM s)
944  }  }
945    
946  /* Process server capabilities */  /* Process server capabilities */
947  void  static void
948  rdp_process_server_caps(STREAM s, uint16 length)  rdp_process_server_caps(STREAM s, uint16 length)
949  {  {
950          int n;          int n;
# Line 814  process_demand_active(STREAM s) Line 1003  process_demand_active(STREAM s)
1003          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
1004          rdp_recv(&type);        /* RDP_CTL_COOPERATE */          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
1005          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
1006          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0,
1007                           g_numlock_sync ? ui_get_numlock_state(read_keyboard_state()) : 0, 0);
1008    
1009          if (g_use_rdp5)          if (g_use_rdp5)
1010          {          {
# Line 837  process_colour_pointer_pdu(STREAM s) Line 1027  process_colour_pointer_pdu(STREAM s)
1027  {  {
1028          uint16 x, y, width, height, cache_idx, masklen, datalen;          uint16 x, y, width, height, cache_idx, masklen, datalen;
1029          uint8 *mask, *data;          uint8 *mask, *data;
1030          HCURSOR cursor;          RD_HCURSOR cursor;
1031    
1032          in_uint16_le(s, cache_idx);          in_uint16_le(s, cache_idx);
1033          in_uint16_le(s, x);          in_uint16_le(s, x);
# Line 869  process_system_pointer_pdu(STREAM s) Line 1059  process_system_pointer_pdu(STREAM s)
1059  {  {
1060          uint16 system_pointer_type;          uint16 system_pointer_type;
1061    
1062          in_uint16(s, system_pointer_type);          in_uint16_le(s, system_pointer_type);
1063          switch (system_pointer_type)          switch (system_pointer_type)
1064          {          {
1065                  case RDP_NULL_POINTER:                  case RDP_NULL_POINTER:
# Line 994  process_palette(STREAM s) Line 1184  process_palette(STREAM s)
1184  {  {
1185          COLOURENTRY *entry;          COLOURENTRY *entry;
1186          COLOURMAP map;          COLOURMAP map;
1187          HCOLOURMAP hmap;          RD_HCOLOURMAP hmap;
1188          int i;          int i;
1189    
1190          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
# Line 1064  process_disconnect_pdu(STREAM s, uint32 Line 1254  process_disconnect_pdu(STREAM s, uint32
1254  }  }
1255    
1256  /* Process data PDU */  /* Process data PDU */
1257  static BOOL  static RD_BOOL
1258  process_data_pdu(STREAM s, uint32 * ext_disc_reason)  process_data_pdu(STREAM s, uint32 * ext_disc_reason)
1259  {  {
1260          uint8 data_pdu_type;          uint8 data_pdu_type;
1261          uint8 ctype;          uint8 ctype;
1262          uint16 clen;          uint16 clen;
1263          uint32 len;          uint32 len;
         static int max_size;  
1264    
1265          uint32 roff, rlen;          uint32 roff, rlen;
1266    
1267          struct stream *ns = &(g_mppc_dict.ns);          struct stream *ns = &(g_mppc_dict.ns);
1268    
1269          in_uint8s(s, 6);        /* shareid, pad, streamid */          in_uint8s(s, 6);        /* shareid, pad, streamid */
1270          in_uint16(s, len);          in_uint16_le(s, len);
1271          in_uint8(s, data_pdu_type);          in_uint8(s, data_pdu_type);
1272          in_uint8(s, ctype);          in_uint8(s, ctype);
1273          in_uint16(s, clen);          in_uint16_le(s, clen);
1274          clen -= 18;          clen -= 18;
1275    
1276          if (ctype & RDP_MPPC_COMPRESSED)          if (ctype & RDP_MPPC_COMPRESSED)
1277          {          {
1278                  if (len > RDP_MPPC_DICT_SIZE)                  if (len > RDP_MPPC_DICT_SIZE)
1279                    error("error decompressed packet size exceeds max\n");                          error("error decompressed packet size exceeds max\n");
1280                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1281                          error("error while decompressing packet\n");                          error("error while decompressing packet\n");
1282    
1283                  //len -= 18;                  /* len -= 18; */
1284    
1285                  /* allocate memory and copy the uncompressed data into the temporary stream */                  /* allocate memory and copy the uncompressed data into the temporary stream */
1286                  ns->data = (uint8 *) xrealloc(ns->data, rlen);                  ns->data = (uint8 *) xrealloc(ns->data, rlen);
# Line 1135  process_data_pdu(STREAM s, uint32 * ext_ Line 1324  process_data_pdu(STREAM s, uint32 * ext_
1324    
1325                  case RDP_DATA_PDU_DISCONNECT:                  case RDP_DATA_PDU_DISCONNECT:
1326                          process_disconnect_pdu(s, ext_disc_reason);                          process_disconnect_pdu(s, ext_disc_reason);
1327                          return True;  
1328                            /* We used to return true and disconnect immediately here, but
1329                             * Windows Vista sends a disconnect PDU with reason 0 when
1330                             * reconnecting to a disconnected session, and MSTSC doesn't
1331                             * drop the connection.  I think we should just save the status.
1332                             */
1333                            break;
1334    
1335                  default:                  default:
1336                          unimpl("data PDU %d\n", data_pdu_type);                          unimpl("data PDU %d\n", data_pdu_type);
# Line 1143  process_data_pdu(STREAM s, uint32 * ext_ Line 1338  process_data_pdu(STREAM s, uint32 * ext_
1338          return False;          return False;
1339  }  }
1340    
1341    /* Process redirect PDU from Session Directory */
1342    static RD_BOOL
1343    process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ )
1344    {
1345            uint32 len;
1346    
1347            /* these 2 bytes are unknown, seem to be zeros */
1348            in_uint8s(s, 2);
1349    
1350            /* read connection flags */
1351            in_uint32_le(s, g_redirect_flags);
1352    
1353            /* read length of ip string */
1354            in_uint32_le(s, len);
1355    
1356            /* read ip string */
1357            rdp_in_unistr(s, g_redirect_server, sizeof(g_redirect_server), len);
1358    
1359            /* read length of cookie string */
1360            in_uint32_le(s, len);
1361    
1362            /* read cookie string (plain ASCII) */
1363            if (len > sizeof(g_redirect_cookie) - 1)
1364            {
1365                    uint32 rem = len - (sizeof(g_redirect_cookie) - 1);
1366                    len = sizeof(g_redirect_cookie) - 1;
1367    
1368                    warning("Unexpectedly large redirection cookie\n");
1369                    in_uint8a(s, g_redirect_cookie, len);
1370                    in_uint8s(s, rem);
1371            }
1372            else
1373            {
1374                    in_uint8a(s, g_redirect_cookie, len);
1375            }
1376            g_redirect_cookie[len] = 0;
1377    
1378            /* read length of username string */
1379            in_uint32_le(s, len);
1380    
1381            /* read username string */
1382            g_redirect_username = (char *) xmalloc(len + 1);
1383            rdp_in_unistr(s, g_redirect_username, strlen(g_redirect_username), len);
1384    
1385            /* read length of domain string */
1386            in_uint32_le(s, len);
1387    
1388            /* read domain string */
1389            rdp_in_unistr(s, g_redirect_domain, sizeof(g_redirect_domain), len);
1390    
1391            /* read length of password string */
1392            in_uint32_le(s, len);
1393    
1394            /* read password string */
1395            rdp_in_unistr(s, g_redirect_password, sizeof(g_redirect_password), len);
1396    
1397            g_redirect = True;
1398    
1399            return True;
1400    }
1401    
1402  /* Process incoming packets */  /* Process incoming packets */
1403  /* nevers gets out of here till app is done */  /* nevers gets out of here till app is done */
1404  void  void
1405  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)  rdp_main_loop(RD_BOOL * deactivated, uint32 * ext_disc_reason)
1406  {  {
1407          while (rdp_loop(deactivated, ext_disc_reason))          while (rdp_loop(deactivated, ext_disc_reason))
1408                  ;                  ;
1409  }  }
1410    
1411  /* used in uiports and rdp_main_loop, processes the rdp packets waiting */  /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1412  BOOL  RD_BOOL
1413  rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)  rdp_loop(RD_BOOL * deactivated, uint32 * ext_disc_reason)
1414  {  {
1415          uint8 type;          uint8 type;
1416          BOOL disc = False;      /* True when a disconnect PDU was received */          RD_BOOL disc = False;   /* True when a disconnect PDU was received */
1417          BOOL cont = True;          RD_BOOL cont = True;
1418          STREAM s;          STREAM s;
1419    
1420          while (cont)          while (cont)
# Line 1176  rdp_loop(BOOL * deactivated, uint32 * ex Line 1432  rdp_loop(BOOL * deactivated, uint32 * ex
1432                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));
1433                                  *deactivated = True;                                  *deactivated = True;
1434                                  break;                                  break;
1435                            case RDP_PDU_REDIRECT:
1436                                    return process_redirect_pdu(s);
1437                                    break;
1438                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1439                                  disc = process_data_pdu(s, ext_disc_reason);                                  disc = process_data_pdu(s, ext_disc_reason);
1440                                  break;                                  break;
# Line 1192  rdp_loop(BOOL * deactivated, uint32 * ex Line 1451  rdp_loop(BOOL * deactivated, uint32 * ex
1451  }  }
1452    
1453  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */
1454  BOOL  RD_BOOL
1455  rdp_connect(char *server, uint32 flags, char *domain, char *password,  rdp_connect(char *server, uint32 flags, char *domain, char *password,
1456              char *command, char *directory)              char *command, char *directory)
1457  {  {
# Line 1203  rdp_connect(char *server, uint32 flags, Line 1462  rdp_connect(char *server, uint32 flags,
1462          return True;          return True;
1463  }  }
1464    
1465    /* Establish a reconnection up to the RDP layer */
1466    RD_BOOL
1467    rdp_reconnect(char *server, uint32 flags, char *domain, char *password,
1468                  char *command, char *directory, char *cookie)
1469    {
1470            if (!sec_reconnect(server))
1471                    return False;
1472    
1473            rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1474            return True;
1475    }
1476    
1477    /* Called during redirection to reset the state to support redirection */
1478    void
1479    rdp_reset_state(void)
1480    {
1481            g_next_packet = NULL;   /* reset the packet information */
1482            g_rdp_shareid = 0;
1483            sec_reset_state();
1484    }
1485    
1486  /* Disconnect from the RDP layer */  /* Disconnect from the RDP layer */
1487  void  void
1488  rdp_disconnect(void)  rdp_disconnect(void)

Legend:
Removed from v.773  
changed lines
  Added in v.1507

  ViewVC Help
Powered by ViewVC 1.1.26