/[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 848 by jsorg71, Sun Mar 13 03:29:19 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 27  extern BOOL g_bitmap_compression; Line 27  extern BOOL g_bitmap_compression;
27  extern BOOL g_orders;  extern BOOL g_orders;
28  extern BOOL g_encryption;  extern BOOL g_encryption;
29  extern BOOL g_desktop_save;  extern BOOL g_desktop_save;
30    extern BOOL g_polygon_ellipse_orders;
31  extern BOOL g_use_rdp5;  extern BOOL g_use_rdp5;
32  extern uint16 g_server_rdp_version;  extern uint16 g_server_rdp_version;
33  extern uint32 g_rdp5_performanceflags;  extern uint32 g_rdp5_performanceflags;
# Line 34  extern int g_server_bpp; Line 35  extern int g_server_bpp;
35  extern int g_width;  extern int g_width;
36  extern int g_height;  extern int g_height;
37  extern BOOL g_bitmap_cache;  extern BOOL g_bitmap_cache;
38    extern BOOL g_bitmap_cache_persist_enable;
39    
40  uint8 *g_next_packet;  uint8 *g_next_packet;
41  uint32 g_rdp_shareid;  uint32 g_rdp_shareid;
# Line 50  rdp_recv(uint8 * type) Line 52  rdp_recv(uint8 * type)
52  {  {
53          static STREAM rdp_s;          static STREAM rdp_s;
54          uint16 length, pdu_type;          uint16 length, pdu_type;
55            uint8 rdpver;
56    
57          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))
58          {          {
59                  rdp_s = sec_recv();                  rdp_s = sec_recv(&rdpver);
60                  if (rdp_s == NULL)                  if (rdp_s == NULL)
61                          return NULL;                          return NULL;
62                    if (rdpver == 0xff)
63                    {
64                            g_next_packet = rdp_s->end;
65                            *type = 0;
66                            return rdp_s;
67                    }
68                    else if (rdpver != 3)
69                    {
70                            /* rdp5_process should move g_next_packet ok */
71                            rdp5_process(rdp_s);
72                            *type = 0;
73                            return rdp_s;
74                    }
75    
76                  g_next_packet = rdp_s->p;                  g_next_packet = rdp_s->p;
77          }          }
# Line 366  rdp_send_input(uint32 time, uint16 messa Line 382  rdp_send_input(uint32 time, uint16 messa
382          rdp_send_data(s, RDP_DATA_PDU_INPUT);          rdp_send_data(s, RDP_DATA_PDU_INPUT);
383  }  }
384    
385    /* Inform the server on the contents of the persistent bitmap cache */
386    static void
387    rdp_enum_bmpcache2(void)
388    {
389            STREAM s;
390            HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS];
391            uint32 num_keys, offset, count, flags;
392    
393            offset = 0;
394            num_keys = pstcache_enumerate(2, keylist);
395    
396            while (offset < num_keys)
397            {
398                    count = MIN(num_keys - offset, 169);
399    
400                    s = rdp_init_data(24 + count * sizeof(HASH_KEY));
401    
402                    flags = 0;
403                    if (offset == 0)
404                            flags |= PDU_FLAG_FIRST;
405                    if (num_keys - offset <= 169)
406                            flags |= PDU_FLAG_LAST;
407    
408                    /* header */
409                    out_uint32_le(s, 0);
410                    out_uint16_le(s, count);
411                    out_uint16_le(s, 0);
412                    out_uint16_le(s, 0);
413                    out_uint16_le(s, 0);
414                    out_uint16_le(s, 0);
415                    out_uint16_le(s, num_keys);
416                    out_uint32_le(s, 0);
417                    out_uint32_le(s, flags);
418    
419                    /* list */
420                    out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
421    
422                    s_mark_end(s);
423                    rdp_send_data(s, 0x2b);
424    
425                    offset += 169;
426            }
427    }
428    
429  /* Send an (empty) font information PDU */  /* Send an (empty) font information PDU */
430  static void  static void
431  rdp_send_fonts(uint16 seq)  rdp_send_fonts(uint16 seq)
# Line 436  rdp_out_order_caps(STREAM s) Line 496  rdp_out_order_caps(STREAM s)
496  {  {
497          uint8 order_caps[32];          uint8 order_caps[32];
498    
   
499          memset(order_caps, 0, 32);          memset(order_caps, 0, 32);
500          order_caps[0] = 1;      /* dest blt */          order_caps[0] = 1;      /* dest blt */
501          order_caps[1] = 1;      /* pat blt */          order_caps[1] = 1;      /* pat blt */
502          order_caps[2] = 1;      /* screen blt */          order_caps[2] = 1;      /* screen blt */
503          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
504            order_caps[4] = 0;      /* triblt */
505          order_caps[8] = 1;      /* line */          order_caps[8] = 1;      /* line */
506          order_caps[9] = 1;      /* line */          order_caps[9] = 1;      /* line */
507          order_caps[10] = 1;     /* rect */          order_caps[10] = 1;     /* rect */
508          order_caps[11] = (g_desktop_save == False ? 0 : 1);     /* desksave */          order_caps[11] = (g_desktop_save ? 1 : 0);      /* desksave */
509          order_caps[13] = 1;     /* memblt */          order_caps[13] = 1;     /* memblt */
510          order_caps[14] = 1;     /* triblt */          order_caps[14] = 1;     /* triblt */
511            order_caps[20] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon */
512            order_caps[21] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon2 */
513          order_caps[22] = 1;     /* polyline */          order_caps[22] = 1;     /* polyline */
514            order_caps[25] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse */
515            order_caps[26] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse2 */
516          order_caps[27] = 1;     /* text2 */          order_caps[27] = 1;     /* text2 */
517          out_uint16_le(s, RDP_CAPSET_ORDER);          out_uint16_le(s, RDP_CAPSET_ORDER);
518          out_uint16_le(s, RDP_CAPLEN_ORDER);          out_uint16_le(s, RDP_CAPLEN_ORDER);
# Line 486  rdp_out_bmpcache_caps(STREAM s) Line 550  rdp_out_bmpcache_caps(STREAM s)
550          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
551  }  }
552    
553    /* Output bitmap cache v2 capability set */
554    static void
555    rdp_out_bmpcache2_caps(STREAM s)
556    {
557            out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
558            out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
559    
560            out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
561    
562            out_uint16_le(s, 0x0300);       /* flags? number of caches? */
563    
564            out_uint32_le(s, BMPCACHE2_C0_CELLS);
565            out_uint32_le(s, BMPCACHE2_C1_CELLS);
566            if (pstcache_init(2))
567            {
568                    out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
569            }
570            else
571            {
572                    out_uint32_le(s, BMPCACHE2_C2_CELLS);
573            }
574            out_uint8s(s, 20);      /* other bitmap caches not used */
575    }
576    
577  /* Output control capability set */  /* Output control capability set */
578  static void  static void
579  rdp_out_control_caps(STREAM s)  rdp_out_control_caps(STREAM s)
# Line 545  rdp_out_colcache_caps(STREAM s) Line 633  rdp_out_colcache_caps(STREAM s)
633          out_uint16(s, 0);       /* pad */          out_uint16(s, 0);       /* pad */
634  }  }
635    
636  static uint8 canned_caps[] = {  static uint8 caps_0x0d[] = {
637          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
638          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639          0x00, 0x00, 0x00, 0x00, 0x00,          0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
642          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
647          0x0C, 0x00, 0x08, 0x00, 0x01,          0x00, 0x00, 0x00, 0x00
648          0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,  };
649          0x10, 0x00, 0x34, 0x00, 0xFE,  
650          0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
651          0xFE, 0x00, 0x08, 0x00, 0xFE,  
652          0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,  static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
653          0xFE, 0x00, 0x80, 0x00, 0xFE,  
654          0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,  static uint8 caps_0x10[] = {
655          0x02, 0x00, 0x00, 0x00          0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
656            0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
657            0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
658            0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
659            0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
660            0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
661  };  };
662    
663  /* Output unknown capability sets (number 13, 12, 14 and 16) */  /* Output unknown capability sets */
664  static void  static void
665  rdp_out_unknown_caps(STREAM s)  rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
666  {  {
667          out_uint16_le(s, RDP_CAPSET_UNKNOWN);          out_uint16_le(s, id);
668          out_uint16_le(s, 0x58);          out_uint16_le(s, length);
669    
670          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);          out_uint8p(s, caps, length - 4);
671  }  }
672    
673  #define RDP5_FLAG 0x0030  #define RDP5_FLAG 0x0030
# Line 588  rdp_send_confirm_active(void) Line 681  rdp_send_confirm_active(void)
681                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
682                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
683                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
684                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
685                    0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
686                    4 /* w2k fix, why? */ ;
687    
688          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
689    
# Line 608  rdp_send_confirm_active(void) Line 703  rdp_send_confirm_active(void)
703          rdp_out_general_caps(s);          rdp_out_general_caps(s);
704          rdp_out_bitmap_caps(s);          rdp_out_bitmap_caps(s);
705          rdp_out_order_caps(s);          rdp_out_order_caps(s);
706          rdp_out_bmpcache_caps(s);          g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
707          rdp_out_colcache_caps(s);          rdp_out_colcache_caps(s);
708          rdp_out_activate_caps(s);          rdp_out_activate_caps(s);
709          rdp_out_control_caps(s);          rdp_out_control_caps(s);
710          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
711          rdp_out_share_caps(s);          rdp_out_share_caps(s);
712          rdp_out_unknown_caps(s);  
713            rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
714            rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
715            rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
716            rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
717    
718          s_mark_end(s);          s_mark_end(s);
719          sec_send(s, sec_flags);          sec_send(s, sec_flags);
# Line 659  rdp_process_bitmap_caps(STREAM s) Line 758  rdp_process_bitmap_caps(STREAM s)
758          if (g_width != width || g_height != height)          if (g_width != width || g_height != height)
759          {          {
760                  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,
761                                  width, height);                          width, height);
762                  g_width = width;                  g_width = width;
763                  g_height = height;                  g_height = height;
764                  ui_resize_window();                  ui_resize_window();
765          }          }
766  }  }
767    
768  /* Respond to a demand active PDU */  /* Process server capabilities */
769  static void  void
770  process_demand_active(STREAM s)  rdp_process_server_caps(STREAM s, uint16 length)
771  {  {
772          int n;          int n;
773          uint8 type, *next;          uint8 *next, *start;
774          uint16 len_src_descriptor, len_combined_caps, num_capsets, capset_type, capset_length;          uint16 ncapsets, capset_type, capset_length;
775    
776          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);  
777    
778          in_uint16_le(s, num_capsets);          in_uint16_le(s, ncapsets);
779          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
780    
781          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++)  
782          {          {
783                    if (s->p > start + length)
784                            return;
785    
786                  in_uint16_le(s, capset_type);                  in_uint16_le(s, capset_type);
787                  in_uint16_le(s, capset_length);                  in_uint16_le(s, capset_length);
788    
# Line 704  process_demand_active(STREAM s) Line 801  process_demand_active(STREAM s)
801    
802                  s->p = next;                  s->p = next;
803          }          }
804    }
805    
806    /* Respond to a demand active PDU */
807    static void
808    process_demand_active(STREAM s)
809    {
810            uint8 type;
811            uint16 len_src_descriptor, len_combined_caps;
812    
813            in_uint32_le(s, g_rdp_shareid);
814            in_uint16_le(s, len_src_descriptor);
815            in_uint16_le(s, len_combined_caps);
816            in_uint8s(s, len_src_descriptor);
817    
818            DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
819            rdp_process_server_caps(s, len_combined_caps);
820    
821          rdp_send_confirm_active();          rdp_send_confirm_active();
822          rdp_send_synchronise();          rdp_send_synchronise();
# Line 716  process_demand_active(STREAM s) Line 829  process_demand_active(STREAM s)
829    
830          if (g_use_rdp5)          if (g_use_rdp5)
831          {          {
832                    rdp_enum_bmpcache2();
833                  rdp_send_fonts(3);                  rdp_send_fonts(3);
834          }          }
835          else          else
# Line 982  process_data_pdu(STREAM s, uint32 * ext_ Line 1096  process_data_pdu(STREAM s, uint32 * ext_
1096    
1097          if (ctype & RDP_MPPC_COMPRESSED)          if (ctype & RDP_MPPC_COMPRESSED)
1098          {          {
1099                    if (len > RDP_MPPC_DICT_SIZE)
1100                            error("error decompressed packet size exceeds max\n");
1101                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1102                          error("error while decompressing packet\n");                          error("error while decompressing packet\n");
1103    
# Line 1039  process_data_pdu(STREAM s, uint32 * ext_ Line 1154  process_data_pdu(STREAM s, uint32 * ext_
1154  }  }
1155    
1156  /* Process incoming packets */  /* Process incoming packets */
1157    /* nevers gets out of here till app is done */
1158  void  void
1159  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1160  {  {
1161          uint8 type;          while (rdp_loop(deactivated, ext_disc_reason))
1162          BOOL disc = False;      /* True when a disconnect PDU was received */                  ;
         STREAM s;  
   
         while ((s = rdp_recv(&type)) != NULL)  
         {  
                 switch (type)  
                 {  
                         case RDP_PDU_DEMAND_ACTIVE:  
                                 process_demand_active(s);  
                                 *deactivated = False;  
                                 break;  
   
                         case RDP_PDU_DEACTIVATE:  
                                 DEBUG(("RDP_PDU_DEACTIVATE\n"));  
                                 *deactivated = True;  
                                 break;  
   
                         case RDP_PDU_DATA:  
                                 disc = process_data_pdu(s, ext_disc_reason);  
                                 break;  
   
                         case 0:  
                                 break;  
   
                         default:  
                                 unimpl("PDU %d\n", type);  
                 }  
   
                 if (disc)  
                 {  
                         return;  
                 }  
         }  
         return;  
1163  }  }
1164    
1165  /* used in uiports, processes the rdp packets waiting */  /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1166  BOOL  BOOL
1167  rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)  rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1168  {  {
# Line 1088  rdp_loop(BOOL * deactivated, uint32 * ex Line 1171  rdp_loop(BOOL * deactivated, uint32 * ex
1171          BOOL cont = True;          BOOL cont = True;
1172          STREAM s;          STREAM s;
1173    
1174     while (cont)          while (cont)
1175          {          {
1176                  s = rdp_recv(&type);                  s = rdp_recv(&type);
1177                  if (s == NULL)                  if (s == NULL)

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

  ViewVC Help
Powered by ViewVC 1.1.26