/[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 677 by n-ki, Mon Apr 26 13:48:39 2004 UTC revision 733 by jsorg71, Mon Jul 5 19:09:07 2004 UTC
# Line 33  extern uint32 g_rdp5_performanceflags; Line 33  extern uint32 g_rdp5_performanceflags;
33  extern int g_server_bpp;  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;
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;
41    
42    extern RDPCOMP g_mppc_dict;
43    
44  #if WITH_DEBUG  #if WITH_DEBUG
45  static uint32 g_packetno;  static uint32 g_packetno;
46  #endif  #endif
# Line 47  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 174  rdp_send_logon_info(uint32 flags, char * Line 186  rdp_send_logon_info(uint32 flags, char *
186          time_t tzone;          time_t tzone;
187    
188  #if 0  #if 0
189          // enable rdp compression          /* enable rdp compression */
190            /* some problems still exist with rdp5 */
191          flags |= RDP_COMPRESSION;          flags |= RDP_COMPRESSION;
192  #endif  #endif
193    
# Line 200  rdp_send_logon_info(uint32 flags, char * Line 213  rdp_send_logon_info(uint32 flags, char *
213          }          }
214          else          else
215          {          {
216    
217                  flags |= RDP_LOGON_BLOB;                  flags |= RDP_LOGON_BLOB;
218                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
219                  packetlen = 4 + /* Unknown uint32 */                  packetlen = 4 + /* Unknown uint32 */
# Line 361  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),
414                                    count * sizeof(BITMAP_ID));
415    
416                    s_mark_end(s);
417                    rdp_send_data(s, 0x2b);
418    
419                    offset += 169;
420            }
421    }
422    
423  /* Send an (empty) font information PDU */  /* Send an (empty) font information PDU */
424  static void  static void
425  rdp_send_fonts(uint16 seq)  rdp_send_fonts(uint16 seq)
# Line 436  rdp_out_order_caps(STREAM s) Line 495  rdp_out_order_caps(STREAM s)
495          order_caps[0] = 1;      /* dest blt */          order_caps[0] = 1;      /* dest blt */
496          order_caps[1] = 1;      /* pat blt */          order_caps[1] = 1;      /* pat blt */
497          order_caps[2] = 1;      /* screen blt */          order_caps[2] = 1;      /* screen blt */
498          order_caps[3] = 1;      /* required for memblt? */          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
499          order_caps[8] = 1;      /* line */          order_caps[8] = 1;      /* line */
500          order_caps[9] = 1;      /* line */          order_caps[9] = 1;      /* line */
501          order_caps[10] = 1;     /* rect */          order_caps[10] = 1;     /* rect */
# Line 481  rdp_out_bmpcache_caps(STREAM s) Line 540  rdp_out_bmpcache_caps(STREAM s)
540          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
541  }  }
542    
543    /* Output bitmap cache v2 capability set */
544    static void
545    rdp_out_bmpcache2_caps(STREAM s)
546    {
547            out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
548            out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
549    
550            out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
551    
552            out_uint16_le(s, 0x0300);       /* flags? number of caches? */
553    
554            out_uint32_le(s, BMPCACHE2_C0_CELLS);
555            out_uint32_le(s, BMPCACHE2_C1_CELLS);
556            if (pstcache_init(2))
557            {
558                    out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
559            }
560            else
561            {
562                    out_uint32_le(s, BMPCACHE2_C2_CELLS);
563            }
564            out_uint8s(s, 20);              /* other bitmap caches not used */
565    }
566    
567  /* Output control capability set */  /* Output control capability set */
568  static void  static void
569  rdp_out_control_caps(STREAM s)  rdp_out_control_caps(STREAM s)
# Line 540  rdp_out_colcache_caps(STREAM s) Line 623  rdp_out_colcache_caps(STREAM s)
623          out_uint16(s, 0);       /* pad */          out_uint16(s, 0);       /* pad */
624  }  }
625    
626  static uint8 canned_caps[] = {  static uint8 caps_0x0d[] = {
627          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
628          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629          0x00, 0x00, 0x00, 0x00, 0x00,          0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
630          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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,
632          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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,
634          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 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,
636          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637          0x0C, 0x00, 0x08, 0x00, 0x01,          0x00, 0x00, 0x00, 0x00
638          0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,  };
639          0x10, 0x00, 0x34, 0x00, 0xFE,  
640          0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
641          0xFE, 0x00, 0x08, 0x00, 0xFE,  
642          0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,  static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
643          0xFE, 0x00, 0x80, 0x00, 0xFE,  
644          0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,  static uint8 caps_0x10[] = {
645          0x02, 0x00, 0x00, 0x00          0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
646            0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
647            0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
648            0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
649            0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
650            0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
651  };  };
652    
653  /* Output unknown capability sets (number 13, 12, 14 and 16) */  /* Output unknown capability sets */
654  static void  static void
655  rdp_out_unknown_caps(STREAM s)  rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 *caps)
656  {  {
657          out_uint16_le(s, RDP_CAPSET_UNKNOWN);          out_uint16_le(s, id);
658          out_uint16_le(s, 0x58);          out_uint16_le(s, length);
659    
660          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);          out_uint8p(s, caps, length - 4);
661  }  }
662    
663  #define RDP5_FLAG 0x0030  #define RDP5_FLAG 0x0030
# Line 583  rdp_send_confirm_active(void) Line 671  rdp_send_confirm_active(void)
671                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
672                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
673                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
674                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
675                    0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */ +
676                    4 /* w2k fix, why? */ ;
677    
678          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
679    
# Line 603  rdp_send_confirm_active(void) Line 693  rdp_send_confirm_active(void)
693          rdp_out_general_caps(s);          rdp_out_general_caps(s);
694          rdp_out_bitmap_caps(s);          rdp_out_bitmap_caps(s);
695          rdp_out_order_caps(s);          rdp_out_order_caps(s);
696          rdp_out_bmpcache_caps(s);          g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
697          rdp_out_colcache_caps(s);          rdp_out_colcache_caps(s);
698          rdp_out_activate_caps(s);          rdp_out_activate_caps(s);
699          rdp_out_control_caps(s);          rdp_out_control_caps(s);
700          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
701          rdp_out_share_caps(s);          rdp_out_share_caps(s);
         rdp_out_unknown_caps(s);  
702    
703            rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
704            rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
705            rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
706            rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
707                                    
708          s_mark_end(s);          s_mark_end(s);
709          sec_send(s, sec_flags);          sec_send(s, sec_flags);
710  }  }
# Line 646  rdp_process_bitmap_caps(STREAM s) Line 740  rdp_process_bitmap_caps(STREAM s)
740           * 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
741           * example when shadowing another session).           * example when shadowing another session).
742           */           */
743          g_server_bpp = bpp;          if (g_server_bpp != bpp)
744          g_width = width;          {
745          g_height = height;                  warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
746                    g_server_bpp = bpp;
747          ui_resize_window();          }
748            if (g_width != width || g_height != height)
749            {
750                    warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
751                                    width, height);
752                    g_width = width;
753                    g_height = height;
754                    ui_resize_window();
755            }
756  }  }
757    
758  /* Respond to a demand active PDU */  /* Process server capabilities */
759  static void  void
760  process_demand_active(STREAM s)  rdp_process_server_caps(STREAM s, uint16 length)
761  {  {
762          int n;          int n;
763          uint8 type, *next;          uint8 *next, *start;
764          uint16 len_src_descriptor, len_combined_caps, num_capsets, capset_type, capset_length;          uint16 ncapsets, capset_type, capset_length;
765    
766          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);  
767    
768          in_uint16_le(s, num_capsets);          in_uint16_le(s, ncapsets);
769          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
770    
771          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++)  
772          {          {
773                    if (s->p > start + length)
774                            return;
775    
776                  in_uint16_le(s, capset_type);                  in_uint16_le(s, capset_type);
777                  in_uint16_le(s, capset_length);                  in_uint16_le(s, capset_length);
778    
# Line 691  process_demand_active(STREAM s) Line 791  process_demand_active(STREAM s)
791    
792                  s->p = next;                  s->p = next;
793          }          }
794    }
795    
796    /* Respond to a demand active PDU */
797    static void
798    process_demand_active(STREAM s)
799    {
800            uint8 type;
801            uint16 len_src_descriptor, len_combined_caps;
802    
803            in_uint32_le(s, g_rdp_shareid);
804            in_uint16_le(s, len_src_descriptor);
805            in_uint16_le(s, len_combined_caps);
806            in_uint8s(s, len_src_descriptor);
807    
808            DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
809            rdp_process_server_caps(s, len_combined_caps);
810    
811          rdp_send_confirm_active();          rdp_send_confirm_active();
812          rdp_send_synchronise();          rdp_send_synchronise();
# Line 703  process_demand_active(STREAM s) Line 819  process_demand_active(STREAM s)
819    
820          if (g_use_rdp5)          if (g_use_rdp5)
821          {          {
822                    rdp_enum_bmpcache2();
823                  rdp_send_fonts(3);                  rdp_send_fonts(3);
824          }          }
825          else          else
# Line 911  process_update_pdu(STREAM s) Line 1028  process_update_pdu(STREAM s)
1028    
1029          in_uint16_le(s, update_type);          in_uint16_le(s, update_type);
1030    
1031            ui_begin_update();
1032          switch (update_type)          switch (update_type)
1033          {          {
1034                  case RDP_UPDATE_ORDERS:                  case RDP_UPDATE_ORDERS:
# Line 934  process_update_pdu(STREAM s) Line 1052  process_update_pdu(STREAM s)
1052                  default:                  default:
1053                          unimpl("update %d\n", update_type);                          unimpl("update %d\n", update_type);
1054          }          }
1055            ui_end_update();
1056  }  }
1057    
1058  /* Process a disconnect PDU */  /* Process a disconnect PDU */
# Line 953  process_data_pdu(STREAM s, uint32 * ext_ Line 1071  process_data_pdu(STREAM s, uint32 * ext_
1071          uint8 data_pdu_type;          uint8 data_pdu_type;
1072          uint8 ctype;          uint8 ctype;
1073          uint16 clen;          uint16 clen;
1074          int len;          uint32 len;
1075  #if 0  
1076          int roff, rlen, ret;          uint32 roff, rlen;
1077          static struct stream ns;  
1078          static signed char *dict = 0;          struct stream *ns = &(g_mppc_dict.ns);
 #endif  
1079    
1080          in_uint8s(s, 6);        /* shareid, pad, streamid */          in_uint8s(s, 6);        /* shareid, pad, streamid */
1081          in_uint16(s, len);          in_uint16(s, len);
# Line 967  process_data_pdu(STREAM s, uint32 * ext_ Line 1084  process_data_pdu(STREAM s, uint32 * ext_
1084          in_uint16(s, clen);          in_uint16(s, clen);
1085          clen -= 18;          clen -= 18;
1086    
1087  #if 0          if (ctype & RDP_MPPC_COMPRESSED)
         if (ctype & 0x20)  
1088          {          {
                 if (!dict)  
                 {  
                         dict = (signed char *) malloc(8200 * sizeof(signed char));  
                         dict = (signed char *) memset(dict, 0, 8200 * sizeof(signed char));  
                 }  
1089    
1090                  ret = decompress(s->p, clen, ctype, (signed char *) dict, &roff, &rlen);                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1091                            error("error while decompressing packet\n");
1092    
1093                  len -= 18;                  //len -= 18;
1094    
1095                  ns.data = xrealloc(ns.data, len);                  /* allocate memory and copy the uncompressed data into the temporary stream */
1096                    ns->data = (uint8 *) xrealloc(ns->data, rlen);
1097    
1098                  ns.data = (unsigned char *) memcpy(ns.data, (unsigned char *) (dict + roff), len);                  memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
1099    
1100                  ns.size = len;                  ns->size = rlen;
1101                  ns.end = ns.data + ns.size;                  ns->end = (ns->data + ns->size);
1102                  ns.p = ns.data;                  ns->p = ns->data;
1103                  ns.rdp_hdr = ns.p;                  ns->rdp_hdr = ns->p;
1104    
1105                  s = &ns;                  s = ns;
1106          }          }
 #endif  
1107    
1108          switch (data_pdu_type)          switch (data_pdu_type)
1109          {          {
# Line 1031  process_data_pdu(STREAM s, uint32 * ext_ Line 1143  process_data_pdu(STREAM s, uint32 * ext_
1143  }  }
1144    
1145  /* Process incoming packets */  /* Process incoming packets */
1146    /* nevers gets out of here till app is done */
1147  void  void
1148  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1149  {  {
1150            while (rdp_loop(deactivated, ext_disc_reason))
1151                    ;
1152    }
1153    
1154    /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1155    BOOL
1156    rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1157    {
1158          uint8 type;          uint8 type;
1159          BOOL disc = False;      /* True when a disconnect PDU was received */          BOOL disc = False;      /* True when a disconnect PDU was received */
1160            BOOL cont = True;
1161          STREAM s;          STREAM s;
1162    
1163          while ((s = rdp_recv(&type)) != NULL)          while (cont)
1164          {          {
1165                    s = rdp_recv(&type);
1166                    if (s == NULL)
1167                            return False;
1168                  switch (type)                  switch (type)
1169                  {                  {
1170                          case RDP_PDU_DEMAND_ACTIVE:                          case RDP_PDU_DEMAND_ACTIVE:
1171                                  process_demand_active(s);                                  process_demand_active(s);
1172                                  *deactivated = False;                                  *deactivated = False;
1173                                  break;                                  break;
   
1174                          case RDP_PDU_DEACTIVATE:                          case RDP_PDU_DEACTIVATE:
1175                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));
1176                                  *deactivated = True;                                  *deactivated = True;
1177                                  break;                                  break;
   
1178                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1179                                  disc = process_data_pdu(s, ext_disc_reason);                                  disc = process_data_pdu(s, ext_disc_reason);
1180                                  break;                                  break;
   
1181                          case 0:                          case 0:
1182                                  break;                                  break;
   
1183                          default:                          default:
1184                                  unimpl("PDU %d\n", type);                                  unimpl("PDU %d\n", type);
1185                  }                  }
   
1186                  if (disc)                  if (disc)
1187                  {                          return False;
1188                          return;                  cont = g_next_packet < s->end;
                 }  
1189          }          }
1190          return;          return True;
1191  }  }
1192    
1193  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */

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

  ViewVC Help
Powered by ViewVC 1.1.26