/[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 828 by stargo, Sun Mar 6 21:11:18 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 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 == 0xff)
62                    {
63                            g_next_packet = rdp_s->end;
64                            *type = 0;
65                            return rdp_s;
66                    }
67                    else if (rdpver != 3)
68                    {
69                            /* rdp5_process should move g_next_packet ok */
70                            rdp5_process(rdp_s);
71                            *type = 0;
72                            return rdp_s;
73                    }
74    
75                  g_next_packet = rdp_s->p;                  g_next_packet = rdp_s->p;
76          }          }
# Line 366  rdp_send_input(uint32 time, uint16 messa Line 381  rdp_send_input(uint32 time, uint16 messa
381          rdp_send_data(s, RDP_DATA_PDU_INPUT);          rdp_send_data(s, RDP_DATA_PDU_INPUT);
382  }  }
383    
384    /* Inform the server on the contents of the persistent bitmap cache */
385    static void
386    rdp_enum_bmpcache2(void)
387    {
388            STREAM s;
389            uint8 idlist[BMPCACHE2_NUM_PSTCELLS * sizeof(BITMAP_ID)];
390            uint32 nids, offset, count, flags;
391    
392            offset = 0;
393            nids = pstcache_enumerate(2, idlist);
394    
395            while (offset < nids)
396            {
397                    count = MIN(nids - offset, 169);
398    
399                    s = rdp_init_data(24 + count * sizeof(BITMAP_ID));
400    
401                    flags = 0;
402                    if (offset == 0)
403                            flags |= PDU_FLAG_FIRST;
404                    if (nids - offset <= 169)
405                            flags |= PDU_FLAG_LAST;
406    
407                    /* header */
408                    out_uint32_le(s, 0);
409                    out_uint16_le(s, count);
410                    out_uint16_le(s, 0);
411                    out_uint16_le(s, 0);
412                    out_uint16_le(s, 0);
413                    out_uint16_le(s, 0);
414                    out_uint16_le(s, nids);
415                    out_uint32_le(s, 0);
416                    out_uint32_le(s, flags);
417    
418                    /* list */
419                    out_uint8a(s, idlist + offset * sizeof(BITMAP_ID), count * sizeof(BITMAP_ID));
420    
421                    s_mark_end(s);
422                    rdp_send_data(s, 0x2b);
423    
424                    offset += 169;
425            }
426    }
427    
428  /* Send an (empty) font information PDU */  /* Send an (empty) font information PDU */
429  static void  static void
430  rdp_send_fonts(uint16 seq)  rdp_send_fonts(uint16 seq)
# Line 486  rdp_out_bmpcache_caps(STREAM s) Line 545  rdp_out_bmpcache_caps(STREAM s)
545          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
546  }  }
547    
548    /* Output bitmap cache v2 capability set */
549    static void
550    rdp_out_bmpcache2_caps(STREAM s)
551    {
552            out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
553            out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
554    
555            out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
556    
557            out_uint16_le(s, 0x0300);       /* flags? number of caches? */
558    
559            out_uint32_le(s, BMPCACHE2_C0_CELLS);
560            out_uint32_le(s, BMPCACHE2_C1_CELLS);
561            if (pstcache_init(2))
562            {
563                    out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
564            }
565            else
566            {
567                    out_uint32_le(s, BMPCACHE2_C2_CELLS);
568            }
569            out_uint8s(s, 20);      /* other bitmap caches not used */
570    }
571    
572  /* Output control capability set */  /* Output control capability set */
573  static void  static void
574  rdp_out_control_caps(STREAM s)  rdp_out_control_caps(STREAM s)
# Line 545  rdp_out_colcache_caps(STREAM s) Line 628  rdp_out_colcache_caps(STREAM s)
628          out_uint16(s, 0);       /* pad */          out_uint16(s, 0);       /* pad */
629  }  }
630    
631  static uint8 canned_caps[] = {  static uint8 caps_0x0d[] = {
632          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
633          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
634          0x00, 0x00, 0x00, 0x00, 0x00,          0x0C, 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          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
637          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640          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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
642          0x0C, 0x00, 0x08, 0x00, 0x01,          0x00, 0x00, 0x00, 0x00
643          0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,  };
644          0x10, 0x00, 0x34, 0x00, 0xFE,  
645          0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
646          0xFE, 0x00, 0x08, 0x00, 0xFE,  
647          0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,  static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
648          0xFE, 0x00, 0x80, 0x00, 0xFE,  
649          0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,  static uint8 caps_0x10[] = {
650          0x02, 0x00, 0x00, 0x00          0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
651            0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
652            0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
653            0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
654            0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
655            0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
656  };  };
657    
658  /* Output unknown capability sets (number 13, 12, 14 and 16) */  /* Output unknown capability sets */
659  static void  static void
660  rdp_out_unknown_caps(STREAM s)  rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
661  {  {
662          out_uint16_le(s, RDP_CAPSET_UNKNOWN);          out_uint16_le(s, id);
663          out_uint16_le(s, 0x58);          out_uint16_le(s, length);
664    
665          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);          out_uint8p(s, caps, length - 4);
666  }  }
667    
668  #define RDP5_FLAG 0x0030  #define RDP5_FLAG 0x0030
# Line 588  rdp_send_confirm_active(void) Line 676  rdp_send_confirm_active(void)
676                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
677                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
678                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
679                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
680                    0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
681                    4 /* w2k fix, why? */ ;
682    
683          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
684    
# Line 608  rdp_send_confirm_active(void) Line 698  rdp_send_confirm_active(void)
698          rdp_out_general_caps(s);          rdp_out_general_caps(s);
699          rdp_out_bitmap_caps(s);          rdp_out_bitmap_caps(s);
700          rdp_out_order_caps(s);          rdp_out_order_caps(s);
701          rdp_out_bmpcache_caps(s);          g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
702          rdp_out_colcache_caps(s);          rdp_out_colcache_caps(s);
703          rdp_out_activate_caps(s);          rdp_out_activate_caps(s);
704          rdp_out_control_caps(s);          rdp_out_control_caps(s);
705          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
706          rdp_out_share_caps(s);          rdp_out_share_caps(s);
707          rdp_out_unknown_caps(s);  
708            rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
709            rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
710            rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
711            rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
712    
713          s_mark_end(s);          s_mark_end(s);
714          sec_send(s, sec_flags);          sec_send(s, sec_flags);
# Line 651  rdp_process_bitmap_caps(STREAM s) Line 745  rdp_process_bitmap_caps(STREAM s)
745           * 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
746           * example when shadowing another session).           * example when shadowing another session).
747           */           */
748          g_server_bpp = bpp;          if (g_server_bpp != bpp)
749          g_width = width;          {
750          g_height = height;                  warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
751                    g_server_bpp = bpp;
752          ui_resize_window();          }
753            if (g_width != width || g_height != height)
754            {
755                    warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
756                            width, height);
757                    g_width = width;
758                    g_height = height;
759                    ui_resize_window();
760            }
761  }  }
762    
763  /* Respond to a demand active PDU */  /* Process server capabilities */
764  static void  void
765  process_demand_active(STREAM s)  rdp_process_server_caps(STREAM s, uint16 length)
766  {  {
767          int n;          int n;
768          uint8 type, *next;          uint8 *next, *start;
769          uint16 len_src_descriptor, len_combined_caps, num_capsets, capset_type, capset_length;          uint16 ncapsets, capset_type, capset_length;
770    
771          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);  
772    
773          in_uint16_le(s, num_capsets);          in_uint16_le(s, ncapsets);
774          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
775    
776          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++)  
777          {          {
778                    if (s->p > start + length)
779                            return;
780    
781                  in_uint16_le(s, capset_type);                  in_uint16_le(s, capset_type);
782                  in_uint16_le(s, capset_length);                  in_uint16_le(s, capset_length);
783    
# Line 696  process_demand_active(STREAM s) Line 796  process_demand_active(STREAM s)
796    
797                  s->p = next;                  s->p = next;
798          }          }
799    }
800    
801    /* Respond to a demand active PDU */
802    static void
803    process_demand_active(STREAM s)
804    {
805            uint8 type;
806            uint16 len_src_descriptor, len_combined_caps;
807    
808            in_uint32_le(s, g_rdp_shareid);
809            in_uint16_le(s, len_src_descriptor);
810            in_uint16_le(s, len_combined_caps);
811            in_uint8s(s, len_src_descriptor);
812    
813            DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
814            rdp_process_server_caps(s, len_combined_caps);
815    
816          rdp_send_confirm_active();          rdp_send_confirm_active();
817          rdp_send_synchronise();          rdp_send_synchronise();
# Line 708  process_demand_active(STREAM s) Line 824  process_demand_active(STREAM s)
824    
825          if (g_use_rdp5)          if (g_use_rdp5)
826          {          {
827                    rdp_enum_bmpcache2();
828                  rdp_send_fonts(3);                  rdp_send_fonts(3);
829          }          }
830          else          else
# Line 916  process_update_pdu(STREAM s) Line 1033  process_update_pdu(STREAM s)
1033    
1034          in_uint16_le(s, update_type);          in_uint16_le(s, update_type);
1035    
1036            ui_begin_update();
1037          switch (update_type)          switch (update_type)
1038          {          {
1039                  case RDP_UPDATE_ORDERS:                  case RDP_UPDATE_ORDERS:
# Line 939  process_update_pdu(STREAM s) Line 1057  process_update_pdu(STREAM s)
1057                  default:                  default:
1058                          unimpl("update %d\n", update_type);                          unimpl("update %d\n", update_type);
1059          }          }
1060            ui_end_update();
1061  }  }
1062    
1063  /* Process a disconnect PDU */  /* Process a disconnect PDU */
# Line 973  process_data_pdu(STREAM s, uint32 * ext_ Line 1091  process_data_pdu(STREAM s, uint32 * ext_
1091    
1092          if (ctype & RDP_MPPC_COMPRESSED)          if (ctype & RDP_MPPC_COMPRESSED)
1093          {          {
1094                    if (len > RDP_MPPC_DICT_SIZE)
1095                            error("error decompressed packet size exceeds max\n");
1096                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1097                          error("error while decompressing packet\n");                          error("error while decompressing packet\n");
1098    
1099                  //len -= 18;                  //len -= 18;
1100    
1101                  /* allocate memory and copy the uncompressed data into the temporary stream */                  /* allocate memory and copy the uncompressed data into the temporary stream */
1102                  ns->data = xrealloc(ns->data, rlen);                  ns->data = (uint8 *) xrealloc(ns->data, rlen);
1103    
1104                  memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);                  memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
1105    
# Line 1030  process_data_pdu(STREAM s, uint32 * ext_ Line 1149  process_data_pdu(STREAM s, uint32 * ext_
1149  }  }
1150    
1151  /* Process incoming packets */  /* Process incoming packets */
1152    /* nevers gets out of here till app is done */
1153  void  void
1154  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1155  {  {
1156            while (rdp_loop(deactivated, ext_disc_reason))
1157                    ;
1158    }
1159    
1160    /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1161    BOOL
1162    rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1163    {
1164          uint8 type;          uint8 type;
1165          BOOL disc = False;      /* True when a disconnect PDU was received */          BOOL disc = False;      /* True when a disconnect PDU was received */
1166            BOOL cont = True;
1167          STREAM s;          STREAM s;
1168    
1169          while ((s = rdp_recv(&type)) != NULL)          while (cont)
1170          {          {
1171                    s = rdp_recv(&type);
1172                    if (s == NULL)
1173                            return False;
1174                  switch (type)                  switch (type)
1175                  {                  {
1176                          case RDP_PDU_DEMAND_ACTIVE:                          case RDP_PDU_DEMAND_ACTIVE:
1177                                  process_demand_active(s);                                  process_demand_active(s);
1178                                  *deactivated = False;                                  *deactivated = False;
1179                                  break;                                  break;
   
1180                          case RDP_PDU_DEACTIVATE:                          case RDP_PDU_DEACTIVATE:
1181                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));
1182                                  *deactivated = True;                                  *deactivated = True;
1183                                  break;                                  break;
   
1184                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1185                                  disc = process_data_pdu(s, ext_disc_reason);                                  disc = process_data_pdu(s, ext_disc_reason);
1186                                  break;                                  break;
   
1187                          case 0:                          case 0:
1188                                  break;                                  break;
   
1189                          default:                          default:
1190                                  unimpl("PDU %d\n", type);                                  unimpl("PDU %d\n", type);
1191                  }                  }
   
1192                  if (disc)                  if (disc)
1193                  {                          return False;
1194                          return;                  cont = g_next_packet < s->end;
                 }  
1195          }          }
1196          return;          return True;
1197  }  }
1198    
1199  /* 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.828

  ViewVC Help
Powered by ViewVC 1.1.26