/[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 713 by jsorg71, Wed Jun 16 03:08:55 2004 UTC revision 1238 by matthewc, Wed Jun 14 08:59:03 2006 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_depth;
48  extern int g_width;  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;
52    extern BOOL g_numlock_sync;
53    
54  uint8 *g_next_packet;  uint8 *g_next_packet;
55  uint32 g_rdp_shareid;  uint32 g_rdp_shareid;
56    
57  extern RDPCOMP g_mppc_dict;  extern RDPCOMP g_mppc_dict;
58    
59    /* Session Directory support */
60    extern BOOL g_redirect;
61    extern char g_redirect_server[64];
62    extern char g_redirect_domain[16];
63    extern char g_redirect_password[64];
64    extern char g_redirect_username[64];
65    extern char g_redirect_cookie[128];
66    extern uint32 g_redirect_flags;
67    /* END Session Directory support */
68    
69  #if WITH_DEBUG  #if WITH_DEBUG
70  static uint32 g_packetno;  static uint32 g_packetno;
71  #endif  #endif
72    
73    #ifdef HAVE_ICONV
74    static BOOL g_iconv_works = True;
75    #endif
76    
77  /* Receive an RDP packet */  /* Receive an RDP packet */
78  static STREAM  static STREAM
79  rdp_recv(uint8 * type)  rdp_recv(uint8 * type)
80  {  {
81          static STREAM rdp_s;          static STREAM rdp_s;
82          uint16 length, pdu_type;          uint16 length, pdu_type;
83            uint8 rdpver;
84    
85          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end) || (g_next_packet == NULL))
86          {          {
87                  rdp_s = sec_recv();                  rdp_s = sec_recv(&rdpver);
88                  if (rdp_s == NULL)                  if (rdp_s == NULL)
89                          return NULL;                          return NULL;
90                    if (rdpver == 0xff)
91                    {
92                            g_next_packet = rdp_s->end;
93                            *type = 0;
94                            return rdp_s;
95                    }
96                    else if (rdpver != 3)
97                    {
98                            /* rdp5_process should move g_next_packet ok */
99                            rdp5_process(rdp_s);
100                            *type = 0;
101                            return rdp_s;
102                    }
103    
104                  g_next_packet = rdp_s->p;                  g_next_packet = rdp_s->p;
105          }          }
# Line 125  rdp_send_data(STREAM s, uint8 data_pdu_t Line 169  rdp_send_data(STREAM s, uint8 data_pdu_t
169  void  void
170  rdp_out_unistr(STREAM s, char *string, int len)  rdp_out_unistr(STREAM s, char *string, int len)
171  {  {
172          int i = 0, j = 0;  #ifdef HAVE_ICONV
173            size_t ibl = strlen(string), obl = len + 2;
174            static iconv_t iconv_h = (iconv_t) - 1;
175            char *pin = string, *pout = (char *) s->p;
176    
177          len += 2;          memset(pout, 0, len + 4);
178    
179          while (i < len)          if (g_iconv_works)
180          {          {
181                  s->p[i++] = string[j++];                  if (iconv_h == (iconv_t) - 1)
182                  s->p[i++] = 0;                  {
183                            size_t i = 1, o = 4;
184                            if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1)
185                            {
186                                    warning("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n",
187                                            g_codepage, WINDOWS_CODEPAGE, (int) iconv_h);
188    
189                                    g_iconv_works = False;
190                                    rdp_out_unistr(s, string, len);
191                                    return;
192                            }
193                            if (iconv(iconv_h, (ICONV_CONST char **) &pin, &i, &pout, &o) ==
194                                (size_t) - 1)
195                            {
196                                    iconv_close(iconv_h);
197                                    iconv_h = (iconv_t) - 1;
198                                    warning("rdp_out_unistr: iconv(1) fail, errno %d\n", errno);
199    
200                                    g_iconv_works = False;
201                                    rdp_out_unistr(s, string, len);
202                                    return;
203                            }
204                            pin = string;
205                            pout = (char *) s->p;
206                    }
207    
208                    if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
209                    {
210                            iconv_close(iconv_h);
211                            iconv_h = (iconv_t) - 1;
212                            warning("rdp_out_unistr: iconv(2) fail, errno %d\n", errno);
213    
214                            g_iconv_works = False;
215                            rdp_out_unistr(s, string, len);
216                            return;
217                    }
218    
219                    s->p += len + 2;
220    
221          }          }
222            else
223    #endif
224            {
225                    int i = 0, j = 0;
226    
227                    len += 2;
228    
229          s->p += len;                  while (i < len)
230                    {
231                            s->p[i++] = string[j++];
232                            s->p[i++] = 0;
233                    }
234    
235                    s->p += len;
236            }
237  }  }
238    
239  /* Input a string in Unicode  /* Input a string in Unicode
# Line 145  rdp_out_unistr(STREAM s, char *string, i Line 243  rdp_out_unistr(STREAM s, char *string, i
243  int  int
244  rdp_in_unistr(STREAM s, char *string, int uni_len)  rdp_in_unistr(STREAM s, char *string, int uni_len)
245  {  {
246          int i = 0;  #ifdef HAVE_ICONV
247            size_t ibl = uni_len, obl = uni_len;
248            char *pin = (char *) s->p, *pout = string;
249            static iconv_t iconv_h = (iconv_t) - 1;
250    
251          while (i < uni_len / 2)          if (g_iconv_works)
252          {          {
253                  in_uint8a(s, &string[i++], 1);                  if (iconv_h == (iconv_t) - 1)
254                  in_uint8s(s, 1);                  {
255                            if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1)
256                            {
257                                    warning("rdp_in_unistr: iconv_open[%s -> %s] fail %d\n",
258                                            WINDOWS_CODEPAGE, g_codepage, (int) iconv_h);
259    
260                                    g_iconv_works = False;
261                                    return rdp_in_unistr(s, string, uni_len);
262                            }
263                    }
264    
265                    if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
266                    {
267                            iconv_close(iconv_h);
268                            iconv_h = (iconv_t) - 1;
269                            warning("rdp_in_unistr: iconv fail, errno %d\n", errno);
270    
271                            g_iconv_works = False;
272                            return rdp_in_unistr(s, string, uni_len);
273                    }
274    
275                    /* we must update the location of the current STREAM for future reads of s->p */
276                    s->p += uni_len;
277    
278                    return pout - string;
279          }          }
280            else
281    #endif
282            {
283                    int i = 0;
284    
285          return i - 1;                  while (i < uni_len / 2)
286                    {
287                            in_uint8a(s, &string[i++], 1);
288                            in_uint8s(s, 1);
289                    }
290    
291                    return i - 1;
292            }
293  }  }
294    
295    
# Line 176  rdp_send_logon_info(uint32 flags, char * Line 312  rdp_send_logon_info(uint32 flags, char *
312          time_t t = time(NULL);          time_t t = time(NULL);
313          time_t tzone;          time_t tzone;
314    
 #if 0  
         /* enable rdp compression */  
         /* some problems still exist with rdp5 */  
         flags |= RDP_COMPRESSION;  
 #endif  
   
315          if (!g_use_rdp5 || 1 == g_server_rdp_version)          if (!g_use_rdp5 || 1 == g_server_rdp_version)
316          {          {
317                  DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));                  DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
# Line 366  rdp_send_input(uint32 time, uint16 messa Line 496  rdp_send_input(uint32 time, uint16 messa
496          rdp_send_data(s, RDP_DATA_PDU_INPUT);          rdp_send_data(s, RDP_DATA_PDU_INPUT);
497  }  }
498    
499    /* Send a client window information PDU */
500    void
501    rdp_send_client_window_status(int status)
502    {
503            STREAM s;
504            static int current_status = 1;
505    
506            if (current_status == status)
507                    return;
508    
509            s = rdp_init_data(12);
510    
511            out_uint32_le(s, status);
512    
513            switch (status)
514            {
515                    case 0: /* shut the server up */
516                            break;
517    
518                    case 1: /* receive data again */
519                            out_uint32_le(s, 0);    /* unknown */
520                            out_uint16_le(s, g_width);
521                            out_uint16_le(s, g_height);
522                            break;
523            }
524    
525            s_mark_end(s);
526            rdp_send_data(s, RDP_DATA_PDU_CLIENT_WINDOW_STATUS);
527            current_status = status;
528    }
529    
530    /* Send persistent bitmap cache enumeration PDU's */
531    static void
532    rdp_enum_bmpcache2(void)
533    {
534            STREAM s;
535            HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS];
536            uint32 num_keys, offset, count, flags;
537    
538            offset = 0;
539            num_keys = pstcache_enumerate(2, keylist);
540    
541            while (offset < num_keys)
542            {
543                    count = MIN(num_keys - offset, 169);
544    
545                    s = rdp_init_data(24 + count * sizeof(HASH_KEY));
546    
547                    flags = 0;
548                    if (offset == 0)
549                            flags |= PDU_FLAG_FIRST;
550                    if (num_keys - offset <= 169)
551                            flags |= PDU_FLAG_LAST;
552    
553                    /* header */
554                    out_uint32_le(s, 0);
555                    out_uint16_le(s, count);
556                    out_uint16_le(s, 0);
557                    out_uint16_le(s, 0);
558                    out_uint16_le(s, 0);
559                    out_uint16_le(s, 0);
560                    out_uint16_le(s, num_keys);
561                    out_uint32_le(s, 0);
562                    out_uint32_le(s, flags);
563    
564                    /* list */
565                    out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
566    
567                    s_mark_end(s);
568                    rdp_send_data(s, 0x2b);
569    
570                    offset += 169;
571            }
572    }
573    
574  /* Send an (empty) font information PDU */  /* Send an (empty) font information PDU */
575  static void  static void
576  rdp_send_fonts(uint16 seq)  rdp_send_fonts(uint16 seq)
# Line 416  rdp_out_bitmap_caps(STREAM s) Line 621  rdp_out_bitmap_caps(STREAM s)
621          out_uint16_le(s, RDP_CAPSET_BITMAP);          out_uint16_le(s, RDP_CAPSET_BITMAP);
622          out_uint16_le(s, RDP_CAPLEN_BITMAP);          out_uint16_le(s, RDP_CAPLEN_BITMAP);
623    
624          out_uint16_le(s, g_server_bpp); /* Preferred BPP */          out_uint16_le(s, g_server_depth);       /* Preferred colour depth */
625          out_uint16_le(s, 1);    /* Receive 1 BPP */          out_uint16_le(s, 1);    /* Receive 1 BPP */
626          out_uint16_le(s, 1);    /* Receive 4 BPP */          out_uint16_le(s, 1);    /* Receive 4 BPP */
627          out_uint16_le(s, 1);    /* Receive 8 BPP */          out_uint16_le(s, 1);    /* Receive 8 BPP */
# Line 436  rdp_out_order_caps(STREAM s) Line 641  rdp_out_order_caps(STREAM s)
641  {  {
642          uint8 order_caps[32];          uint8 order_caps[32];
643    
   
644          memset(order_caps, 0, 32);          memset(order_caps, 0, 32);
645          order_caps[0] = 1;      /* dest blt */          order_caps[0] = 1;      /* dest blt */
646          order_caps[1] = 1;      /* pat blt */          order_caps[1] = 1;      /* pat blt */
647          order_caps[2] = 1;      /* screen blt */          order_caps[2] = 1;      /* screen blt */
648          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
649            order_caps[4] = 0;      /* triblt */
650          order_caps[8] = 1;      /* line */          order_caps[8] = 1;      /* line */
651          order_caps[9] = 1;      /* line */          order_caps[9] = 1;      /* line */
652          order_caps[10] = 1;     /* rect */          order_caps[10] = 1;     /* rect */
653          order_caps[11] = (g_desktop_save == False ? 0 : 1);     /* desksave */          order_caps[11] = (g_desktop_save ? 1 : 0);      /* desksave */
654          order_caps[13] = 1;     /* memblt */          order_caps[13] = 1;     /* memblt */
655          order_caps[14] = 1;     /* triblt */          order_caps[14] = 1;     /* triblt */
656            order_caps[20] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon */
657            order_caps[21] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon2 */
658          order_caps[22] = 1;     /* polyline */          order_caps[22] = 1;     /* polyline */
659            order_caps[25] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse */
660            order_caps[26] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse2 */
661          order_caps[27] = 1;     /* text2 */          order_caps[27] = 1;     /* text2 */
662          out_uint16_le(s, RDP_CAPSET_ORDER);          out_uint16_le(s, RDP_CAPSET_ORDER);
663          out_uint16_le(s, RDP_CAPLEN_ORDER);          out_uint16_le(s, RDP_CAPLEN_ORDER);
# Line 476  rdp_out_bmpcache_caps(STREAM s) Line 685  rdp_out_bmpcache_caps(STREAM s)
685          out_uint16_le(s, RDP_CAPSET_BMPCACHE);          out_uint16_le(s, RDP_CAPSET_BMPCACHE);
686          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
687    
688          Bpp = (g_server_bpp + 7) / 8;          Bpp = (g_server_depth + 7) / 8; /* bytes per pixel */
689          out_uint8s(s, 24);      /* unused */          out_uint8s(s, 24);      /* unused */
690          out_uint16_le(s, 0x258);        /* entries */          out_uint16_le(s, 0x258);        /* entries */
691          out_uint16_le(s, 0x100 * Bpp);  /* max cell size */          out_uint16_le(s, 0x100 * Bpp);  /* max cell size */
# Line 486  rdp_out_bmpcache_caps(STREAM s) Line 695  rdp_out_bmpcache_caps(STREAM s)
695          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
696  }  }
697    
698    /* Output bitmap cache v2 capability set */
699    static void
700    rdp_out_bmpcache2_caps(STREAM s)
701    {
702            out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
703            out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
704    
705            out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
706    
707            out_uint16_be(s, 3);    /* number of caches in this set */
708    
709            /* max cell size for cache 0 is 16x16, 1 = 32x32, 2 = 64x64, etc */
710            out_uint32_le(s, BMPCACHE2_C0_CELLS);
711            out_uint32_le(s, BMPCACHE2_C1_CELLS);
712            if (pstcache_init(2))
713            {
714                    out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
715            }
716            else
717            {
718                    out_uint32_le(s, BMPCACHE2_C2_CELLS);
719            }
720            out_uint8s(s, 20);      /* other bitmap caches not used */
721    }
722    
723  /* Output control capability set */  /* Output control capability set */
724  static void  static void
725  rdp_out_control_caps(STREAM s)  rdp_out_control_caps(STREAM s)
# Line 545  rdp_out_colcache_caps(STREAM s) Line 779  rdp_out_colcache_caps(STREAM s)
779          out_uint16(s, 0);       /* pad */          out_uint16(s, 0);       /* pad */
780  }  }
781    
782  static uint8 canned_caps[] = {  static uint8 caps_0x0d[] = {
783          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
784          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
785          0x00, 0x00, 0x00, 0x00, 0x00,          0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
786          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
787          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
788          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
789          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
790          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
791          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
792          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
793          0x0C, 0x00, 0x08, 0x00, 0x01,          0x00, 0x00, 0x00, 0x00
794          0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,  };
795          0x10, 0x00, 0x34, 0x00, 0xFE,  
796          0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
797          0xFE, 0x00, 0x08, 0x00, 0xFE,  
798          0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,  static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
799          0xFE, 0x00, 0x80, 0x00, 0xFE,  
800          0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,  static uint8 caps_0x10[] = {
801          0x02, 0x00, 0x00, 0x00          0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
802            0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
803            0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
804            0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
805            0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
806            0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
807  };  };
808    
809  /* Output unknown capability sets (number 13, 12, 14 and 16) */  /* Output unknown capability sets */
810  static void  static void
811  rdp_out_unknown_caps(STREAM s)  rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
812  {  {
813          out_uint16_le(s, RDP_CAPSET_UNKNOWN);          out_uint16_le(s, id);
814          out_uint16_le(s, 0x58);          out_uint16_le(s, length);
815    
816          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);          out_uint8p(s, caps, length - 4);
817  }  }
818    
819  #define RDP5_FLAG 0x0030  #define RDP5_FLAG 0x0030
# Line 588  rdp_send_confirm_active(void) Line 827  rdp_send_confirm_active(void)
827                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
828                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
829                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
830                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
831                    0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
832                    4 /* w2k fix, why? */ ;
833    
834          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
835    
# Line 608  rdp_send_confirm_active(void) Line 849  rdp_send_confirm_active(void)
849          rdp_out_general_caps(s);          rdp_out_general_caps(s);
850          rdp_out_bitmap_caps(s);          rdp_out_bitmap_caps(s);
851          rdp_out_order_caps(s);          rdp_out_order_caps(s);
852          rdp_out_bmpcache_caps(s);          g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
853          rdp_out_colcache_caps(s);          rdp_out_colcache_caps(s);
854          rdp_out_activate_caps(s);          rdp_out_activate_caps(s);
855          rdp_out_control_caps(s);          rdp_out_control_caps(s);
856          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
857          rdp_out_share_caps(s);          rdp_out_share_caps(s);
858          rdp_out_unknown_caps(s);  
859            rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
860            rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
861            rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
862            rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
863    
864          s_mark_end(s);          s_mark_end(s);
865          sec_send(s, sec_flags);          sec_send(s, sec_flags);
# Line 637  rdp_process_general_caps(STREAM s) Line 882  rdp_process_general_caps(STREAM s)
882  static void  static void
883  rdp_process_bitmap_caps(STREAM s)  rdp_process_bitmap_caps(STREAM s)
884  {  {
885          uint16 width, height, bpp;          uint16 width, height, depth;
886    
887          in_uint16_le(s, bpp);          in_uint16_le(s, depth);
888          in_uint8s(s, 6);          in_uint8s(s, 6);
889    
890          in_uint16_le(s, width);          in_uint16_le(s, width);
891          in_uint16_le(s, height);          in_uint16_le(s, height);
892    
893          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));
894    
895          /*          /*
896           * 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
897           * example when shadowing another session).           * example when shadowing another session).
898           */           */
899          if (g_server_bpp != bpp)          if (g_server_depth != depth)
900          {          {
901                  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",
902                  g_server_bpp = bpp;                          g_server_depth, depth);
903                    g_server_depth = depth;
904          }          }
905          if (g_width != width || g_height != height)          if (g_width != width || g_height != height)
906          {          {
907                  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,
908                                  width, height);                          width, height);
909                  g_width = width;                  g_width = width;
910                  g_height = height;                  g_height = height;
911                  ui_resize_window();                  ui_resize_window();
912          }          }
913  }  }
914    
915  /* Respond to a demand active PDU */  /* Process server capabilities */
916  static void  static void
917  process_demand_active(STREAM s)  rdp_process_server_caps(STREAM s, uint16 length)
918  {  {
919          int n;          int n;
920          uint8 type, *next;          uint8 *next, *start;
921          uint16 len_src_descriptor, len_combined_caps, num_capsets, capset_type, capset_length;          uint16 ncapsets, capset_type, capset_length;
922    
923          in_uint32_le(s, g_rdp_shareid);          start = s->p;
         in_uint16_le(s, len_src_descriptor);  
         in_uint16_le(s, len_combined_caps);  
         in_uint8s(s, len_src_descriptor);  
924    
925          in_uint16_le(s, num_capsets);          in_uint16_le(s, ncapsets);
926          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
927    
928          DEBUG(("DEMAND_ACTIVE(id=0x%x,num_caps=%d)\n", g_rdp_shareid, num_capsets));          for (n = 0; n < ncapsets; n++)
   
         for (n = 0; n < num_capsets; n++)  
929          {          {
930                    if (s->p > start + length)
931                            return;
932    
933                  in_uint16_le(s, capset_type);                  in_uint16_le(s, capset_type);
934                  in_uint16_le(s, capset_length);                  in_uint16_le(s, capset_length);
935    
# Line 704  process_demand_active(STREAM s) Line 948  process_demand_active(STREAM s)
948    
949                  s->p = next;                  s->p = next;
950          }          }
951    }
952    
953    /* Respond to a demand active PDU */
954    static void
955    process_demand_active(STREAM s)
956    {
957            uint8 type;
958            uint16 len_src_descriptor, len_combined_caps;
959    
960            in_uint32_le(s, g_rdp_shareid);
961            in_uint16_le(s, len_src_descriptor);
962            in_uint16_le(s, len_combined_caps);
963            in_uint8s(s, len_src_descriptor);
964    
965            DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
966            rdp_process_server_caps(s, len_combined_caps);
967    
968          rdp_send_confirm_active();          rdp_send_confirm_active();
969          rdp_send_synchronise();          rdp_send_synchronise();
# Line 712  process_demand_active(STREAM s) Line 972  process_demand_active(STREAM s)
972          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
973          rdp_recv(&type);        /* RDP_CTL_COOPERATE */          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
974          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
975          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0,
976                           g_numlock_sync ? ui_get_numlock_state(read_keyboard_state()) : 0, 0);
977    
978          if (g_use_rdp5)          if (g_use_rdp5)
979          {          {
980                    rdp_enum_bmpcache2();
981                  rdp_send_fonts(3);                  rdp_send_fonts(3);
982          }          }
983          else          else
# Line 982  process_data_pdu(STREAM s, uint32 * ext_ Line 1244  process_data_pdu(STREAM s, uint32 * ext_
1244    
1245          if (ctype & RDP_MPPC_COMPRESSED)          if (ctype & RDP_MPPC_COMPRESSED)
1246          {          {
1247                    if (len > RDP_MPPC_DICT_SIZE)
1248                            error("error decompressed packet size exceeds max\n");
1249                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1250                          error("error while decompressing packet\n");                          error("error while decompressing packet\n");
1251    
1252                  //len -= 18;                  /* len -= 18; */
1253    
1254                  /* allocate memory and copy the uncompressed data into the temporary stream */                  /* allocate memory and copy the uncompressed data into the temporary stream */
1255                  ns->data = (uint8 *) xrealloc(ns->data, rlen);                  ns->data = (uint8 *) xrealloc(ns->data, rlen);
# Line 1030  process_data_pdu(STREAM s, uint32 * ext_ Line 1293  process_data_pdu(STREAM s, uint32 * ext_
1293    
1294                  case RDP_DATA_PDU_DISCONNECT:                  case RDP_DATA_PDU_DISCONNECT:
1295                          process_disconnect_pdu(s, ext_disc_reason);                          process_disconnect_pdu(s, ext_disc_reason);
1296                          return True;  
1297                            /* We used to return true and disconnect immediately here, but
1298                             * Windows Vista sends a disconnect PDU with reason 0 when
1299                             * reconnecting to a disconnected session, and MSTSC doesn't
1300                             * drop the connection.  I think we should just save the status.
1301                             */
1302                            break;
1303    
1304                  default:                  default:
1305                          unimpl("data PDU %d\n", data_pdu_type);                          unimpl("data PDU %d\n", data_pdu_type);
# Line 1038  process_data_pdu(STREAM s, uint32 * ext_ Line 1307  process_data_pdu(STREAM s, uint32 * ext_
1307          return False;          return False;
1308  }  }
1309    
1310  /* Process incoming packets */  /* Process redirect PDU from Session Directory */
1311  void  static BOOL
1312  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)  process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ )
1313  {  {
1314          uint8 type;          uint32 len;
         BOOL disc = False;      /* True when a disconnect PDU was received */  
         STREAM s;  
1315    
1316          while ((s = rdp_recv(&type)) != NULL)          /* these 2 bytes are unknown, seem to be zeros */
1317          {          in_uint8s(s, 2);
                 switch (type)  
                 {  
                         case RDP_PDU_DEMAND_ACTIVE:  
                                 process_demand_active(s);  
                                 *deactivated = False;  
                                 break;  
1318    
1319                          case RDP_PDU_DEACTIVATE:          /* read connection flags */
1320                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));          in_uint32_le(s, g_redirect_flags);
                                 *deactivated = True;  
                                 break;  
1321    
1322                          case RDP_PDU_DATA:          /* read length of ip string */
1323                                  disc = process_data_pdu(s, ext_disc_reason);          in_uint32_le(s, len);
                                 break;  
1324    
1325                          case 0:          /* read ip string */
1326                                  break;          rdp_in_unistr(s, g_redirect_server, len);
1327    
1328                          default:          /* read length of cookie string */
1329                                  unimpl("PDU %d\n", type);          in_uint32_le(s, len);
                 }  
1330    
1331                  if (disc)          /* read cookie string (plain ASCII) */
1332                  {          in_uint8a(s, g_redirect_cookie, len);
1333                          return;          g_redirect_cookie[len] = 0;
1334                  }  
1335          }          /* read length of username string */
1336          return;          in_uint32_le(s, len);
1337    
1338            /* read username string */
1339            rdp_in_unistr(s, g_redirect_username, len);
1340    
1341            /* read length of domain string */
1342            in_uint32_le(s, len);
1343    
1344            /* read domain string */
1345            rdp_in_unistr(s, g_redirect_domain, len);
1346    
1347            /* read length of password string */
1348            in_uint32_le(s, len);
1349    
1350            /* read password string */
1351            rdp_in_unistr(s, g_redirect_password, len);
1352    
1353            g_redirect = True;
1354    
1355            return True;
1356    }
1357    
1358    /* Process incoming packets */
1359    /* nevers gets out of here till app is done */
1360    void
1361    rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1362    {
1363            while (rdp_loop(deactivated, ext_disc_reason))
1364                    ;
1365  }  }
1366    
1367  /* used in uiports, processes the rdp packets waiting */  /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1368  BOOL  BOOL
1369  rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)  rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1370  {  {
# Line 1088  rdp_loop(BOOL * deactivated, uint32 * ex Line 1373  rdp_loop(BOOL * deactivated, uint32 * ex
1373          BOOL cont = True;          BOOL cont = True;
1374          STREAM s;          STREAM s;
1375    
1376     while (cont)          while (cont)
1377          {          {
1378                  s = rdp_recv(&type);                  s = rdp_recv(&type);
1379                  if (s == NULL)                  if (s == NULL)
# Line 1103  rdp_loop(BOOL * deactivated, uint32 * ex Line 1388  rdp_loop(BOOL * deactivated, uint32 * ex
1388                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));
1389                                  *deactivated = True;                                  *deactivated = True;
1390                                  break;                                  break;
1391                            case RDP_PDU_REDIRECT:
1392                                    return process_redirect_pdu(s);
1393                                    break;
1394                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1395                                  disc = process_data_pdu(s, ext_disc_reason);                                  disc = process_data_pdu(s, ext_disc_reason);
1396                                  break;                                  break;
# Line 1130  rdp_connect(char *server, uint32 flags, Line 1418  rdp_connect(char *server, uint32 flags,
1418          return True;          return True;
1419  }  }
1420    
1421    /* Establish a reconnection up to the RDP layer */
1422    BOOL
1423    rdp_reconnect(char *server, uint32 flags, char *domain, char *password,
1424                  char *command, char *directory, char *cookie)
1425    {
1426            if (!sec_reconnect(server))
1427                    return False;
1428    
1429            rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1430            return True;
1431    }
1432    
1433    /* Called during redirection to reset the state to support redirection */
1434    void
1435    rdp_reset_state(void)
1436    {
1437            g_next_packet = NULL;   /* reset the packet information */
1438            g_rdp_shareid = 0;
1439            sec_reset_state();
1440    }
1441    
1442  /* Disconnect from the RDP layer */  /* Disconnect from the RDP layer */
1443  void  void
1444  rdp_disconnect(void)  rdp_disconnect(void)

Legend:
Removed from v.713  
changed lines
  Added in v.1238

  ViewVC Help
Powered by ViewVC 1.1.26