/[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 658 by astrand, Fri Apr 16 11:36:29 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;
34  extern int g_server_bpp;  extern int g_server_bpp;
35    extern int g_width;
36    extern int g_height;
37    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;
42    
43    extern RDPCOMP g_mppc_dict;
44    
45  #if WITH_DEBUG  #if WITH_DEBUG
46  static uint32 g_packetno;  static uint32 g_packetno;
47  #endif  #endif
# Line 45  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 172  rdp_send_logon_info(uint32 flags, char * Line 193  rdp_send_logon_info(uint32 flags, char *
193          time_t tzone;          time_t tzone;
194    
195  #if 0  #if 0
196          // enable rdp compression          /* enable rdp compression */
197            /* some problems still exist with rdp5 */
198          flags |= RDP_COMPRESSION;          flags |= RDP_COMPRESSION;
199  #endif  #endif
200    
# Line 198  rdp_send_logon_info(uint32 flags, char * Line 220  rdp_send_logon_info(uint32 flags, char *
220          }          }
221          else          else
222          {          {
223    
224                  flags |= RDP_LOGON_BLOB;                  flags |= RDP_LOGON_BLOB;
225                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
226                  packetlen = 4 + /* Unknown uint32 */                  packetlen = 4 + /* Unknown uint32 */
# Line 359  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 368  rdp_send_fonts(uint16 seq) Line 435  rdp_send_fonts(uint16 seq)
435          s = rdp_init_data(8);          s = rdp_init_data(8);
436    
437          out_uint16(s, 0);       /* number of fonts */          out_uint16(s, 0);       /* number of fonts */
438          out_uint16_le(s, 0x3e); /* unknown */          out_uint16_le(s, 0);    /* pad? */
439          out_uint16_le(s, seq);  /* unknown */          out_uint16_le(s, seq);  /* unknown */
440          out_uint16_le(s, 0x32); /* entry size */          out_uint16_le(s, 0x32); /* entry size */
441    
# Line 416  rdp_out_bitmap_caps(STREAM s) Line 483  rdp_out_bitmap_caps(STREAM s)
483          out_uint16_le(s, 800);  /* Desktop width */          out_uint16_le(s, 800);  /* Desktop width */
484          out_uint16_le(s, 600);  /* Desktop height */          out_uint16_le(s, 600);  /* Desktop height */
485          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
486          out_uint16(s, 0);       /* Allow resize */          out_uint16(s, 1);       /* Allow resize */
487          out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */          out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
488          out_uint16(s, 0);       /* Unknown */          out_uint16(s, 0);       /* Unknown */
489          out_uint16_le(s, 1);    /* Unknown */          out_uint16_le(s, 1);    /* Unknown */
# Line 429  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] = 1;      /* required for 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 479  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 538  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
         0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,  
         0x10, 0x00, 0x34, 0x00, 0xFE,  
         0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,  
         0xFE, 0x00, 0x08, 0x00, 0xFE,  
         0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,  
         0xFE, 0x00, 0x80, 0x00, 0xFE,  
         0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,  
         0x02, 0x00, 0x00, 0x00  
648  };  };
649    
650  /* Output unknown capability sets (number 13, 12, 14 and 16) */  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
651    
652    static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
653    
654    static uint8 caps_0x10[] = {
655            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 */
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 581  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 601  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);
720  }  }
721    
722  /* Respond to a demand active PDU */  /* Process a general capability set */
723  static void  static void
724  process_demand_active(STREAM s)  rdp_process_general_caps(STREAM s)
725  {  {
726          uint8 type;          uint16 pad2octetsB;     /* rdp5 flags? */
         uint16 i;  
         uint16 p_bpp;  
727    
728          in_uint32_le(s, g_rdp_shareid);          in_uint8s(s, 10);
729            in_uint16_le(s, pad2octetsB);
730    
731            if (!pad2octetsB)
732                    g_use_rdp5 = False;
733    }
734    
735    /* Process a bitmap capability set */
736    static void
737    rdp_process_bitmap_caps(STREAM s)
738    {
739            uint16 width, height, bpp;
740    
741            in_uint16_le(s, bpp);
742            in_uint8s(s, 6);
743    
744            in_uint16_le(s, width);
745            in_uint16_le(s, height);
746    
747            DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));
748    
749            /*
750             * The server may limit bpp and change the size of the desktop (for
751             * example when shadowing another session).
752             */
753            if (g_server_bpp != bpp)
754            {
755                    warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
756                    g_server_bpp = bpp;
757            }
758            if (g_width != width || g_height != height)
759            {
760                    warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
761                            width, height);
762                    g_width = width;
763                    g_height = height;
764                    ui_resize_window();
765            }
766    }
767    
768    /* Process server capabilities */
769    void
770    rdp_process_server_caps(STREAM s, uint16 length)
771    {
772            int n;
773            uint8 *next, *start;
774            uint16 ncapsets, capset_type, capset_length;
775    
776            start = s->p;
777    
778          /* scan for prefered bpp */          in_uint16_le(s, ncapsets);
779          while (s_check_rem(s, 6))          in_uint8s(s, 2);        /* pad */
780    
781            for (n = 0; n < ncapsets; n++)
782          {          {
783                  in_uint16_le(s, i);                  if (s->p > start + length)
784                  if (i == RDP_CAPSET_BITMAP)                          return;
785    
786                    in_uint16_le(s, capset_type);
787                    in_uint16_le(s, capset_length);
788    
789                    next = s->p + capset_length - 4;
790    
791                    switch (capset_type)
792                  {                  {
793                          in_uint16_le(s, i);                          case RDP_CAPSET_GENERAL:
794                          if (i == RDP_CAPLEN_BITMAP)                                  rdp_process_general_caps(s);
795                          {                                  break;
796                                  in_uint16_le(s, p_bpp);  
797                                  if (p_bpp == 8 || p_bpp == 15 || p_bpp == 16 || p_bpp == 24)                          case RDP_CAPSET_BITMAP:
798                                  {                                  rdp_process_bitmap_caps(s);
799                                          if (p_bpp < g_server_bpp)                                  break;
                                         {  
                                                 warning("Server limited colour depth to %d bits\n",  
                                                         p_bpp);  
                                                 g_server_bpp = p_bpp;  
                                         }  
                                         break;  
                                 }  
                         }  
800                  }                  }
801    
802                    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));          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 658  process_demand_active(STREAM s) Line 826  process_demand_active(STREAM s)
826          rdp_recv(&type);        /* RDP_CTL_COOPERATE */          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
827          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
828          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);
829          rdp_send_fonts(1);  
830          rdp_send_fonts(2);          if (g_use_rdp5)
831          rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 */          {
832                    rdp_enum_bmpcache2();
833                    rdp_send_fonts(3);
834            }
835            else
836            {
837                    rdp_send_fonts(1);
838                    rdp_send_fonts(2);
839            }
840    
841            rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
842          reset_order_state();          reset_order_state();
843  }  }
844    
# Line 860  process_update_pdu(STREAM s) Line 1038  process_update_pdu(STREAM s)
1038    
1039          in_uint16_le(s, update_type);          in_uint16_le(s, update_type);
1040    
1041            ui_begin_update();
1042          switch (update_type)          switch (update_type)
1043          {          {
1044                  case RDP_UPDATE_ORDERS:                  case RDP_UPDATE_ORDERS:
# Line 883  process_update_pdu(STREAM s) Line 1062  process_update_pdu(STREAM s)
1062                  default:                  default:
1063                          unimpl("update %d\n", update_type);                          unimpl("update %d\n", update_type);
1064          }          }
1065            ui_end_update();
1066    }
1067    
1068    /* Process a disconnect PDU */
1069    void
1070    process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
1071    {
1072            in_uint32_le(s, *ext_disc_reason);
1073    
1074            DEBUG(("Received disconnect PDU\n"));
1075  }  }
1076    
1077  /* Process data PDU */  /* Process data PDU */
1078  static void  static BOOL
1079  process_data_pdu(STREAM s)  process_data_pdu(STREAM s, uint32 * ext_disc_reason)
1080  {  {
1081          uint8 data_pdu_type;          uint8 data_pdu_type;
1082          uint8 ctype;          uint8 ctype;
1083          uint16 clen;          uint16 clen;
1084          int roff, rlen, len, ret;          uint32 len;
1085          static struct stream ns;  
1086          static signed char *dict = 0;          uint32 roff, rlen;
1087    
1088            struct stream *ns = &(g_mppc_dict.ns);
1089    
1090          in_uint8s(s, 6);        /* shareid, pad, streamid */          in_uint8s(s, 6);        /* shareid, pad, streamid */
1091          in_uint16(s, len);          in_uint16(s, len);
# Line 904  process_data_pdu(STREAM s) Line 1094  process_data_pdu(STREAM s)
1094          in_uint16(s, clen);          in_uint16(s, clen);
1095          clen -= 18;          clen -= 18;
1096    
1097  #if 0          if (ctype & RDP_MPPC_COMPRESSED)
         if (ctype & 0x20)  
1098          {          {
1099                  if (!dict)                  if (len > RDP_MPPC_DICT_SIZE)
1100                  {                          error("error decompressed packet size exceeds max\n");
1101                          dict = (signed char *) malloc(8200 * sizeof(signed char));                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1102                          dict = (signed char *) memset(dict, 0, 8200 * sizeof(signed char));                          error("error while decompressing packet\n");
                 }  
   
                 ret = decompress(s->p, clen, ctype, (signed char *) dict, &roff, &rlen);  
1103    
1104                  len -= 18;                  //len -= 18;
1105    
1106                  ns.data = xrealloc(ns.data, len);                  /* allocate memory and copy the uncompressed data into the temporary stream */
1107                    ns->data = (uint8 *) xrealloc(ns->data, rlen);
1108    
1109                  ns.data = (unsigned char *) memcpy(ns.data, (unsigned char *) (dict + roff), len);                  memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
1110    
1111                  ns.size = len;                  ns->size = rlen;
1112                  ns.end = ns.data + ns.size;                  ns->end = (ns->data + ns->size);
1113                  ns.p = ns.data;                  ns->p = ns->data;
1114                  ns.rdp_hdr = ns.p;                  ns->rdp_hdr = ns->p;
1115    
1116                  s = &ns;                  s = ns;
1117          }          }
 #endif  
1118    
1119          switch (data_pdu_type)          switch (data_pdu_type)
1120          {          {
# Line 936  process_data_pdu(STREAM s) Line 1122  process_data_pdu(STREAM s)
1122                          process_update_pdu(s);                          process_update_pdu(s);
1123                          break;                          break;
1124    
1125                    case RDP_DATA_PDU_CONTROL:
1126                            DEBUG(("Received Control PDU\n"));
1127                            break;
1128    
1129                    case RDP_DATA_PDU_SYNCHRONISE:
1130                            DEBUG(("Received Sync PDU\n"));
1131                            break;
1132    
1133                  case RDP_DATA_PDU_POINTER:                  case RDP_DATA_PDU_POINTER:
1134                          process_pointer_pdu(s);                          process_pointer_pdu(s);
1135                          break;                          break;
# Line 950  process_data_pdu(STREAM s) Line 1144  process_data_pdu(STREAM s)
1144                          break;                          break;
1145    
1146                  case RDP_DATA_PDU_DISCONNECT:                  case RDP_DATA_PDU_DISCONNECT:
1147                          /* Normally received when user logs out or disconnects from a                          process_disconnect_pdu(s, ext_disc_reason);
1148                             console session on Windows XP and 2003 Server */                          return True;
                         DEBUG(("Received disconnect PDU\n"));  
                         break;  
1149    
1150                  default:                  default:
1151                          unimpl("data PDU %d\n", data_pdu_type);                          unimpl("data PDU %d\n", data_pdu_type);
1152          }          }
1153            return False;
1154  }  }
1155    
1156  /* Process incoming packets */  /* Process incoming packets */
1157    /* nevers gets out of here till app is done */
1158    void
1159    rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1160    {
1161            while (rdp_loop(deactivated, ext_disc_reason))
1162                    ;
1163    }
1164    
1165    /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1166  BOOL  BOOL
1167  rdp_main_loop(void)  rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1168  {  {
1169          uint8 type;          uint8 type;
1170            BOOL disc = False;      /* True when a disconnect PDU was received */
1171            BOOL cont = True;
1172          STREAM s;          STREAM s;
1173    
1174          while ((s = rdp_recv(&type)) != NULL)          while (cont)
1175          {          {
1176                    s = rdp_recv(&type);
1177                    if (s == NULL)
1178                            return False;
1179                  switch (type)                  switch (type)
1180                  {                  {
1181                          case RDP_PDU_DEMAND_ACTIVE:                          case RDP_PDU_DEMAND_ACTIVE:
1182                                  process_demand_active(s);                                  process_demand_active(s);
1183                                    *deactivated = False;
1184                                  break;                                  break;
   
1185                          case RDP_PDU_DEACTIVATE:                          case RDP_PDU_DEACTIVATE:
1186                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));
1187                                  /* We thought we could detect a clean                                  *deactivated = True;
                                    shutdown of the session by this  
                                    packet, but it seems Windows 2003  
                                    is sending us one of these when we  
                                    reconnect to a disconnected session  
                                    return True; */  
1188                                  break;                                  break;
   
1189                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1190                                  process_data_pdu(s);                                  disc = process_data_pdu(s, ext_disc_reason);
1191                                  break;                                  break;
   
1192                          case 0:                          case 0:
1193                                  break;                                  break;
   
1194                          default:                          default:
1195                                  unimpl("PDU %d\n", type);                                  unimpl("PDU %d\n", type);
1196                  }                  }
1197                    if (disc)
1198                            return False;
1199                    cont = g_next_packet < s->end;
1200          }          }
1201          return True;          return True;
         /* We want to detect if we got a clean shutdown, but we  
            can't. Se above.    
            return False;  */  
1202  }  }
1203    
1204  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */

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

  ViewVC Help
Powered by ViewVC 1.1.26