/[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 687 by n-ki, Fri Apr 30 06:18:08 2004 UTC revision 773 by jsorg71, Sat Sep 11 22:57:42 2004 UTC
# Line 34  extern int g_server_bpp; Line 34  extern int g_server_bpp;
34  extern int g_width;  extern int g_width;
35  extern int g_height;  extern int g_height;
36  extern BOOL g_bitmap_cache;  extern BOOL g_bitmap_cache;
37    extern BOOL g_bitmap_cache_persist_enable;
38    
39  uint8 *g_next_packet;  uint8 *g_next_packet;
40  uint32 g_rdp_shareid;  uint32 g_rdp_shareid;
# Line 50  rdp_recv(uint8 * type) Line 51  rdp_recv(uint8 * type)
51  {  {
52          static STREAM rdp_s;          static STREAM rdp_s;
53          uint16 length, pdu_type;          uint16 length, pdu_type;
54            uint8 rdpver;
55    
56          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))
57          {          {
58                  rdp_s = sec_recv();                  rdp_s = sec_recv(&rdpver);
59                  if (rdp_s == NULL)                  if (rdp_s == NULL)
60                          return NULL;                          return NULL;
61                    if (rdpver != 3)
62                    {
63                            /* rdp5_process should move g_next_packet ok */
64                            rdp5_process(rdp_s);
65                            *type = 0;
66                            return rdp_s;
67                    }
68    
69                  g_next_packet = rdp_s->p;                  g_next_packet = rdp_s->p;
70          }          }
# Line 366  rdp_send_input(uint32 time, uint16 messa Line 375  rdp_send_input(uint32 time, uint16 messa
375          rdp_send_data(s, RDP_DATA_PDU_INPUT);          rdp_send_data(s, RDP_DATA_PDU_INPUT);
376  }  }
377    
378    /* Inform the server on the contents of the persistent bitmap cache */
379    static void
380    rdp_enum_bmpcache2(void)
381    {
382            STREAM s;
383            uint8 idlist[BMPCACHE2_NUM_PSTCELLS * sizeof(BITMAP_ID)];
384            uint32 nids, offset, count, flags;
385    
386            offset = 0;
387            nids = pstcache_enumerate(2, idlist);
388    
389            while (offset < nids)
390            {
391                    count = MIN(nids - offset, 169);
392    
393                    s = rdp_init_data(24 + count * sizeof(BITMAP_ID));
394    
395                    flags = 0;
396                    if (offset == 0)
397                            flags |= PDU_FLAG_FIRST;
398                    if (nids - offset <= 169)
399                            flags |= PDU_FLAG_LAST;
400    
401                    /* header */
402                    out_uint32_le(s, 0);
403                    out_uint16_le(s, count);
404                    out_uint16_le(s, 0);
405                    out_uint16_le(s, 0);
406                    out_uint16_le(s, 0);
407                    out_uint16_le(s, 0);
408                    out_uint16_le(s, nids);
409                    out_uint32_le(s, 0);
410                    out_uint32_le(s, flags);
411    
412                    /* list */
413                    out_uint8a(s, idlist + offset * sizeof(BITMAP_ID), count * sizeof(BITMAP_ID));
414    
415                    s_mark_end(s);
416                    rdp_send_data(s, 0x2b);
417    
418                    offset += 169;
419            }
420    }
421    
422  /* Send an (empty) font information PDU */  /* Send an (empty) font information PDU */
423  static void  static void
424  rdp_send_fonts(uint16 seq)  rdp_send_fonts(uint16 seq)
# Line 486  rdp_out_bmpcache_caps(STREAM s) Line 539  rdp_out_bmpcache_caps(STREAM s)
539          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
540  }  }
541    
542    /* Output bitmap cache v2 capability set */
543    static void
544    rdp_out_bmpcache2_caps(STREAM s)
545    {
546            out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
547            out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
548    
549            out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
550    
551            out_uint16_le(s, 0x0300);       /* flags? number of caches? */
552    
553            out_uint32_le(s, BMPCACHE2_C0_CELLS);
554            out_uint32_le(s, BMPCACHE2_C1_CELLS);
555            if (pstcache_init(2))
556            {
557                    out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
558            }
559            else
560            {
561                    out_uint32_le(s, BMPCACHE2_C2_CELLS);
562            }
563            out_uint8s(s, 20);      /* other bitmap caches not used */
564    }
565    
566  /* Output control capability set */  /* Output control capability set */
567  static void  static void
568  rdp_out_control_caps(STREAM s)  rdp_out_control_caps(STREAM s)
# Line 545  rdp_out_colcache_caps(STREAM s) Line 622  rdp_out_colcache_caps(STREAM s)
622          out_uint16(s, 0);       /* pad */          out_uint16(s, 0);       /* pad */
623  }  }
624    
625  static uint8 canned_caps[] = {  static uint8 caps_0x0d[] = {
626          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
627          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
628          0x00, 0x00, 0x00, 0x00, 0x00,          0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
631          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
632          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
633          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
634          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
635          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
636          0x0C, 0x00, 0x08, 0x00, 0x01,          0x00, 0x00, 0x00, 0x00
637          0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,  };
638          0x10, 0x00, 0x34, 0x00, 0xFE,  
639          0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
640          0xFE, 0x00, 0x08, 0x00, 0xFE,  
641          0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,  static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
642          0xFE, 0x00, 0x80, 0x00, 0xFE,  
643          0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,  static uint8 caps_0x10[] = {
644          0x02, 0x00, 0x00, 0x00          0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
645            0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
646            0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
647            0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
648            0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
649            0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
650  };  };
651    
652  /* Output unknown capability sets (number 13, 12, 14 and 16) */  /* Output unknown capability sets */
653  static void  static void
654  rdp_out_unknown_caps(STREAM s)  rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
655  {  {
656          out_uint16_le(s, RDP_CAPSET_UNKNOWN);          out_uint16_le(s, id);
657          out_uint16_le(s, 0x58);          out_uint16_le(s, length);
658    
659          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);          out_uint8p(s, caps, length - 4);
660  }  }
661    
662  #define RDP5_FLAG 0x0030  #define RDP5_FLAG 0x0030
# Line 588  rdp_send_confirm_active(void) Line 670  rdp_send_confirm_active(void)
670                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
671                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
672                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
673                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
674                    0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
675                    4 /* w2k fix, why? */ ;
676    
677          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
678    
# Line 608  rdp_send_confirm_active(void) Line 692  rdp_send_confirm_active(void)
692          rdp_out_general_caps(s);          rdp_out_general_caps(s);
693          rdp_out_bitmap_caps(s);          rdp_out_bitmap_caps(s);
694          rdp_out_order_caps(s);          rdp_out_order_caps(s);
695          rdp_out_bmpcache_caps(s);          g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
696          rdp_out_colcache_caps(s);          rdp_out_colcache_caps(s);
697          rdp_out_activate_caps(s);          rdp_out_activate_caps(s);
698          rdp_out_control_caps(s);          rdp_out_control_caps(s);
699          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
700          rdp_out_share_caps(s);          rdp_out_share_caps(s);
701          rdp_out_unknown_caps(s);  
702            rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
703            rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
704            rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
705            rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
706    
707          s_mark_end(s);          s_mark_end(s);
708          sec_send(s, sec_flags);          sec_send(s, sec_flags);
# Line 651  rdp_process_bitmap_caps(STREAM s) Line 739  rdp_process_bitmap_caps(STREAM s)
739           * The server may limit bpp and change the size of the desktop (for           * The server may limit bpp and change the size of the desktop (for
740           * example when shadowing another session).           * example when shadowing another session).
741           */           */
742          g_server_bpp = bpp;          if (g_server_bpp != bpp)
743          g_width = width;          {
744          g_height = height;                  warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
745                    g_server_bpp = bpp;
746          ui_resize_window();          }
747            if (g_width != width || g_height != height)
748            {
749                    warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
750                            width, height);
751                    g_width = width;
752                    g_height = height;
753                    ui_resize_window();
754            }
755  }  }
756    
757  /* Respond to a demand active PDU */  /* Process server capabilities */
758  static void  void
759  process_demand_active(STREAM s)  rdp_process_server_caps(STREAM s, uint16 length)
760  {  {
761          int n;          int n;
762          uint8 type, *next;          uint8 *next, *start;
763          uint16 len_src_descriptor, len_combined_caps, num_capsets, capset_type, capset_length;          uint16 ncapsets, capset_type, capset_length;
764    
765          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);  
766    
767          in_uint16_le(s, num_capsets);          in_uint16_le(s, ncapsets);
768          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
769    
770          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++)  
771          {          {
772                    if (s->p > start + length)
773                            return;
774    
775                  in_uint16_le(s, capset_type);                  in_uint16_le(s, capset_type);
776                  in_uint16_le(s, capset_length);                  in_uint16_le(s, capset_length);
777    
# Line 696  process_demand_active(STREAM s) Line 790  process_demand_active(STREAM s)
790    
791                  s->p = next;                  s->p = next;
792          }          }
793    }
794    
795    /* Respond to a demand active PDU */
796    static void
797    process_demand_active(STREAM s)
798    {
799            uint8 type;
800            uint16 len_src_descriptor, len_combined_caps;
801    
802            in_uint32_le(s, g_rdp_shareid);
803            in_uint16_le(s, len_src_descriptor);
804            in_uint16_le(s, len_combined_caps);
805            in_uint8s(s, len_src_descriptor);
806    
807            DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
808            rdp_process_server_caps(s, len_combined_caps);
809    
810          rdp_send_confirm_active();          rdp_send_confirm_active();
811          rdp_send_synchronise();          rdp_send_synchronise();
# Line 708  process_demand_active(STREAM s) Line 818  process_demand_active(STREAM s)
818    
819          if (g_use_rdp5)          if (g_use_rdp5)
820          {          {
821                    rdp_enum_bmpcache2();
822                  rdp_send_fonts(3);                  rdp_send_fonts(3);
823          }          }
824          else          else
# Line 916  process_update_pdu(STREAM s) Line 1027  process_update_pdu(STREAM s)
1027    
1028          in_uint16_le(s, update_type);          in_uint16_le(s, update_type);
1029    
1030            ui_begin_update();
1031          switch (update_type)          switch (update_type)
1032          {          {
1033                  case RDP_UPDATE_ORDERS:                  case RDP_UPDATE_ORDERS:
# Line 939  process_update_pdu(STREAM s) Line 1051  process_update_pdu(STREAM s)
1051                  default:                  default:
1052                          unimpl("update %d\n", update_type);                          unimpl("update %d\n", update_type);
1053          }          }
1054            ui_end_update();
1055  }  }
1056    
1057  /* Process a disconnect PDU */  /* Process a disconnect PDU */
# Line 959  process_data_pdu(STREAM s, uint32 * ext_ Line 1071  process_data_pdu(STREAM s, uint32 * ext_
1071          uint8 ctype;          uint8 ctype;
1072          uint16 clen;          uint16 clen;
1073          uint32 len;          uint32 len;
1074            static int max_size;
1075    
1076          uint32 roff, rlen;          uint32 roff, rlen;
1077    
# Line 973  process_data_pdu(STREAM s, uint32 * ext_ Line 1086  process_data_pdu(STREAM s, uint32 * ext_
1086    
1087          if (ctype & RDP_MPPC_COMPRESSED)          if (ctype & RDP_MPPC_COMPRESSED)
1088          {          {
1089                    if (len > RDP_MPPC_DICT_SIZE)
1090                      error("error decompressed packet size exceeds max\n");
1091                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1092                          error("error while decompressing packet\n");                          error("error while decompressing packet\n");
1093    
1094                  //len -= 18;                  //len -= 18;
1095    
1096                  /* allocate memory and copy the uncompressed data into the temporary stream */                  /* allocate memory and copy the uncompressed data into the temporary stream */
1097                  ns->data = xrealloc(ns->data, rlen);                  ns->data = (uint8 *) xrealloc(ns->data, rlen);
1098    
1099                  memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);                  memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
1100    
# Line 1030  process_data_pdu(STREAM s, uint32 * ext_ Line 1144  process_data_pdu(STREAM s, uint32 * ext_
1144  }  }
1145    
1146  /* Process incoming packets */  /* Process incoming packets */
1147    /* nevers gets out of here till app is done */
1148  void  void
1149  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1150  {  {
1151            while (rdp_loop(deactivated, ext_disc_reason))
1152                    ;
1153    }
1154    
1155    /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1156    BOOL
1157    rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1158    {
1159          uint8 type;          uint8 type;
1160          BOOL disc = False;      /* True when a disconnect PDU was received */          BOOL disc = False;      /* True when a disconnect PDU was received */
1161            BOOL cont = True;
1162          STREAM s;          STREAM s;
1163    
1164          while ((s = rdp_recv(&type)) != NULL)          while (cont)
1165          {          {
1166                    s = rdp_recv(&type);
1167                    if (s == NULL)
1168                            return False;
1169                  switch (type)                  switch (type)
1170                  {                  {
1171                          case RDP_PDU_DEMAND_ACTIVE:                          case RDP_PDU_DEMAND_ACTIVE:
1172                                  process_demand_active(s);                                  process_demand_active(s);
1173                                  *deactivated = False;                                  *deactivated = False;
1174                                  break;                                  break;
   
1175                          case RDP_PDU_DEACTIVATE:                          case RDP_PDU_DEACTIVATE:
1176                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));
1177                                  *deactivated = True;                                  *deactivated = True;
1178                                  break;                                  break;
   
1179                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1180                                  disc = process_data_pdu(s, ext_disc_reason);                                  disc = process_data_pdu(s, ext_disc_reason);
1181                                  break;                                  break;
   
1182                          case 0:                          case 0:
1183                                  break;                                  break;
   
1184                          default:                          default:
1185                                  unimpl("PDU %d\n", type);                                  unimpl("PDU %d\n", type);
1186                  }                  }
   
1187                  if (disc)                  if (disc)
1188                  {                          return False;
1189                          return;                  cont = g_next_packet < s->end;
                 }  
1190          }          }
1191          return;          return True;
1192  }  }
1193    
1194  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */

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

  ViewVC Help
Powered by ViewVC 1.1.26