/[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 654 by jsorg71, Thu Apr 15 22:03:24 2004 UTC revision 831 by jdmeijer, Tue Mar 8 00:43:10 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 31  extern BOOL g_use_rdp5; Line 31  extern BOOL g_use_rdp5;
31  extern uint16 g_server_rdp_version;  extern uint16 g_server_rdp_version;
32  extern uint32 g_rdp5_performanceflags;  extern uint32 g_rdp5_performanceflags;
33  extern int g_server_bpp;  extern int g_server_bpp;
34    extern int g_width;
35    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 45  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 172  rdp_send_logon_info(uint32 flags, char * Line 192  rdp_send_logon_info(uint32 flags, char *
192          time_t tzone;          time_t tzone;
193    
194  #if 0  #if 0
195          // enable rdp compression          /* enable rdp compression */
196            /* some problems still exist with rdp5 */
197          flags |= RDP_COMPRESSION;          flags |= RDP_COMPRESSION;
198  #endif  #endif
199    
# Line 198  rdp_send_logon_info(uint32 flags, char * Line 219  rdp_send_logon_info(uint32 flags, char *
219          }          }
220          else          else
221          {          {
222    
223                  flags |= RDP_LOGON_BLOB;                  flags |= RDP_LOGON_BLOB;
224                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
225                  packetlen = 4 + /* Unknown uint32 */                  packetlen = 4 + /* Unknown uint32 */
# Line 359  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            HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS];
390            uint32 num_keys, offset, count, flags;
391    
392            offset = 0;
393            num_keys = pstcache_enumerate(2, keylist);
394    
395            while (offset < num_keys)
396            {
397                    count = MIN(num_keys - offset, 169);
398    
399                    s = rdp_init_data(24 + count * sizeof(HASH_KEY));
400    
401                    flags = 0;
402                    if (offset == 0)
403                            flags |= PDU_FLAG_FIRST;
404                    if (num_keys - 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, num_keys);
415                    out_uint32_le(s, 0);
416                    out_uint32_le(s, flags);
417    
418                    /* list */
419                    out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
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 368  rdp_send_fonts(uint16 seq) Line 434  rdp_send_fonts(uint16 seq)
434          s = rdp_init_data(8);          s = rdp_init_data(8);
435    
436          out_uint16(s, 0);       /* number of fonts */          out_uint16(s, 0);       /* number of fonts */
437          out_uint16_le(s, 0x3e); /* unknown */          out_uint16_le(s, 0);    /* pad? */
438          out_uint16_le(s, seq);  /* unknown */          out_uint16_le(s, seq);  /* unknown */
439          out_uint16_le(s, 0x32); /* entry size */          out_uint16_le(s, 0x32); /* entry size */
440    
# Line 416  rdp_out_bitmap_caps(STREAM s) Line 482  rdp_out_bitmap_caps(STREAM s)
482          out_uint16_le(s, 800);  /* Desktop width */          out_uint16_le(s, 800);  /* Desktop width */
483          out_uint16_le(s, 600);  /* Desktop height */          out_uint16_le(s, 600);  /* Desktop height */
484          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
485          out_uint16(s, 0);       /* Allow resize */          out_uint16(s, 1);       /* Allow resize */
486          out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */          out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
487          out_uint16(s, 0);       /* Unknown */          out_uint16(s, 0);       /* Unknown */
488          out_uint16_le(s, 1);    /* Unknown */          out_uint16_le(s, 1);    /* Unknown */
# Line 429  rdp_out_order_caps(STREAM s) Line 495  rdp_out_order_caps(STREAM s)
495  {  {
496          uint8 order_caps[32];          uint8 order_caps[32];
497    
   
498          memset(order_caps, 0, 32);          memset(order_caps, 0, 32);
499          order_caps[0] = 1;      /* dest blt */          order_caps[0] = 1;      /* dest blt */
500          order_caps[1] = 1;      /* pat blt */          order_caps[1] = 1;      /* pat blt */
501          order_caps[2] = 1;      /* screen blt */          order_caps[2] = 1;      /* screen blt */
502          order_caps[3] = 1;      /* required for memblt? */          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
503            order_caps[4] = 0;      /* triblt */
504          order_caps[8] = 1;      /* line */          order_caps[8] = 1;      /* line */
505          order_caps[9] = 1;      /* line */          order_caps[9] = 1;      /* line */
506          order_caps[10] = 1;     /* rect */          order_caps[10] = 1;     /* rect */
507          order_caps[11] = (g_desktop_save == False ? 0 : 1);     /* desksave */          order_caps[11] = (g_desktop_save == False ? 0 : 1);     /* desksave */
508          order_caps[13] = 1;     /* memblt */          order_caps[13] = 1;     /* memblt */
509          order_caps[14] = 1;     /* triblt */          order_caps[14] = 1;     /* triblt */
510            order_caps[20] = 1;     /* polygon */
511            order_caps[21] = 1;     /* polygon2 */
512          order_caps[22] = 1;     /* polyline */          order_caps[22] = 1;     /* polyline */
513            order_caps[25] = 1;     /* ellipse */
514            order_caps[26] = 1;     /* ellipse2 */
515          order_caps[27] = 1;     /* text2 */          order_caps[27] = 1;     /* text2 */
516          out_uint16_le(s, RDP_CAPSET_ORDER);          out_uint16_le(s, RDP_CAPSET_ORDER);
517          out_uint16_le(s, RDP_CAPLEN_ORDER);          out_uint16_le(s, RDP_CAPLEN_ORDER);
# Line 479  rdp_out_bmpcache_caps(STREAM s) Line 549  rdp_out_bmpcache_caps(STREAM s)
549          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
550  }  }
551    
552    /* Output bitmap cache v2 capability set */
553    static void
554    rdp_out_bmpcache2_caps(STREAM s)
555    {
556            out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
557            out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
558    
559            out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
560    
561            out_uint16_le(s, 0x0300);       /* flags? number of caches? */
562    
563            out_uint32_le(s, BMPCACHE2_C0_CELLS);
564            out_uint32_le(s, BMPCACHE2_C1_CELLS);
565            if (pstcache_init(2))
566            {
567                    out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
568            }
569            else
570            {
571                    out_uint32_le(s, BMPCACHE2_C2_CELLS);
572            }
573            out_uint8s(s, 20);      /* other bitmap caches not used */
574    }
575    
576  /* Output control capability set */  /* Output control capability set */
577  static void  static void
578  rdp_out_control_caps(STREAM s)  rdp_out_control_caps(STREAM s)
# Line 538  rdp_out_colcache_caps(STREAM s) Line 632  rdp_out_colcache_caps(STREAM s)
632          out_uint16(s, 0);       /* pad */          out_uint16(s, 0);       /* pad */
633  }  }
634    
635  static uint8 canned_caps[] = {  static uint8 caps_0x0d[] = {
636          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
637          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638          0x00, 0x00, 0x00, 0x00, 0x00,          0x0C, 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          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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644          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, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646          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  
647  };  };
648    
649  /* Output unknown capability sets (number 13, 12, 14 and 16) */  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
650    
651    static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
652    
653    static uint8 caps_0x10[] = {
654            0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
655            0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
656            0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
657            0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
658            0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
659            0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
660    };
661    
662    /* Output unknown capability sets */
663  static void  static void
664  rdp_out_unknown_caps(STREAM s)  rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
665  {  {
666          out_uint16_le(s, RDP_CAPSET_UNKNOWN);          out_uint16_le(s, id);
667          out_uint16_le(s, 0x58);          out_uint16_le(s, length);
668    
669          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);          out_uint8p(s, caps, length - 4);
670  }  }
671    
672  #define RDP5_FLAG 0x0030  #define RDP5_FLAG 0x0030
# Line 581  rdp_send_confirm_active(void) Line 680  rdp_send_confirm_active(void)
680                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
681                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
682                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
683                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
684                    0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
685                    4 /* w2k fix, why? */ ;
686    
687          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
688    
# Line 601  rdp_send_confirm_active(void) Line 702  rdp_send_confirm_active(void)
702          rdp_out_general_caps(s);          rdp_out_general_caps(s);
703          rdp_out_bitmap_caps(s);          rdp_out_bitmap_caps(s);
704          rdp_out_order_caps(s);          rdp_out_order_caps(s);
705          rdp_out_bmpcache_caps(s);          g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
706          rdp_out_colcache_caps(s);          rdp_out_colcache_caps(s);
707          rdp_out_activate_caps(s);          rdp_out_activate_caps(s);
708          rdp_out_control_caps(s);          rdp_out_control_caps(s);
709          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
710          rdp_out_share_caps(s);          rdp_out_share_caps(s);
711          rdp_out_unknown_caps(s);  
712            rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
713            rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
714            rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
715            rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
716    
717          s_mark_end(s);          s_mark_end(s);
718          sec_send(s, sec_flags);          sec_send(s, sec_flags);
719  }  }
720    
721  /* Respond to a demand active PDU */  /* Process a general capability set */
722  static void  static void
723  process_demand_active(STREAM s)  rdp_process_general_caps(STREAM s)
724  {  {
725          uint8 type;          uint16 pad2octetsB;     /* rdp5 flags? */
         uint16 i;  
         uint16 p_bpp;  
726    
727          in_uint32_le(s, g_rdp_shareid);          in_uint8s(s, 10);
728            in_uint16_le(s, pad2octetsB);
729    
730            if (!pad2octetsB)
731                    g_use_rdp5 = False;
732    }
733    
734    /* Process a bitmap capability set */
735    static void
736    rdp_process_bitmap_caps(STREAM s)
737    {
738            uint16 width, height, bpp;
739    
740            in_uint16_le(s, bpp);
741            in_uint8s(s, 6);
742    
743            in_uint16_le(s, width);
744            in_uint16_le(s, height);
745    
746            DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));
747    
748            /*
749             * The server may limit bpp and change the size of the desktop (for
750             * example when shadowing another session).
751             */
752            if (g_server_bpp != bpp)
753            {
754                    warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
755                    g_server_bpp = bpp;
756            }
757            if (g_width != width || g_height != height)
758            {
759                    warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
760                            width, height);
761                    g_width = width;
762                    g_height = height;
763                    ui_resize_window();
764            }
765    }
766    
767    /* Process server capabilities */
768    void
769    rdp_process_server_caps(STREAM s, uint16 length)
770    {
771            int n;
772            uint8 *next, *start;
773            uint16 ncapsets, capset_type, capset_length;
774    
775            start = s->p;
776    
777          /* scan for prefered bpp */          in_uint16_le(s, ncapsets);
778          while (s_check_rem(s, 6))          in_uint8s(s, 2);        /* pad */
779    
780            for (n = 0; n < ncapsets; n++)
781          {          {
782                  in_uint16_le(s, i);                  if (s->p > start + length)
783                  if (i == RDP_CAPSET_BITMAP)                          return;
784    
785                    in_uint16_le(s, capset_type);
786                    in_uint16_le(s, capset_length);
787    
788                    next = s->p + capset_length - 4;
789    
790                    switch (capset_type)
791                  {                  {
792                          in_uint16_le(s, i);                          case RDP_CAPSET_GENERAL:
793                          if (i == RDP_CAPLEN_BITMAP)                                  rdp_process_general_caps(s);
794                          {                                  break;
795                                  in_uint16_le(s, p_bpp);  
796                                  if (p_bpp == 8 || p_bpp == 15 || p_bpp == 16 || p_bpp == 24)                          case RDP_CAPSET_BITMAP:
797                                  {                                  rdp_process_bitmap_caps(s);
798                                          if (p_bpp < g_server_bpp)                                  break;
                                         {  
                                                 warning("Server limited colour depth to %d bits\n", p_bpp);  
                                                 g_server_bpp = p_bpp;  
                                         }  
                                         break;  
                                 }  
                         }  
799                  }                  }
800    
801                    s->p = next;
802          }          }
803    }
804    
805    /* Respond to a demand active PDU */
806    static void
807    process_demand_active(STREAM s)
808    {
809            uint8 type;
810            uint16 len_src_descriptor, len_combined_caps;
811    
812            in_uint32_le(s, g_rdp_shareid);
813            in_uint16_le(s, len_src_descriptor);
814            in_uint16_le(s, len_combined_caps);
815            in_uint8s(s, len_src_descriptor);
816    
817          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
818            rdp_process_server_caps(s, len_combined_caps);
819    
820          rdp_send_confirm_active();          rdp_send_confirm_active();
821          rdp_send_synchronise();          rdp_send_synchronise();
# Line 657  process_demand_active(STREAM s) Line 825  process_demand_active(STREAM s)
825          rdp_recv(&type);        /* RDP_CTL_COOPERATE */          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
826          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
827          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);
828          rdp_send_fonts(1);  
829          rdp_send_fonts(2);          if (g_use_rdp5)
830          rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 */          {
831                    rdp_enum_bmpcache2();
832                    rdp_send_fonts(3);
833            }
834            else
835            {
836                    rdp_send_fonts(1);
837                    rdp_send_fonts(2);
838            }
839    
840            rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
841          reset_order_state();          reset_order_state();
842  }  }
843    
# Line 859  process_update_pdu(STREAM s) Line 1037  process_update_pdu(STREAM s)
1037    
1038          in_uint16_le(s, update_type);          in_uint16_le(s, update_type);
1039    
1040            ui_begin_update();
1041          switch (update_type)          switch (update_type)
1042          {          {
1043                  case RDP_UPDATE_ORDERS:                  case RDP_UPDATE_ORDERS:
# Line 882  process_update_pdu(STREAM s) Line 1061  process_update_pdu(STREAM s)
1061                  default:                  default:
1062                          unimpl("update %d\n", update_type);                          unimpl("update %d\n", update_type);
1063          }          }
1064            ui_end_update();
1065    }
1066    
1067    /* Process a disconnect PDU */
1068    void
1069    process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
1070    {
1071            in_uint32_le(s, *ext_disc_reason);
1072    
1073            DEBUG(("Received disconnect PDU\n"));
1074  }  }
1075    
1076  /* Process data PDU */  /* Process data PDU */
1077  static void  static BOOL
1078  process_data_pdu(STREAM s)  process_data_pdu(STREAM s, uint32 * ext_disc_reason)
1079  {  {
1080          uint8 data_pdu_type;          uint8 data_pdu_type;
1081          uint8 ctype;          uint8 ctype;
1082          uint16 clen;          uint16 clen;
1083          int roff, rlen, len, ret;          uint32 len;
1084          static struct stream ns;  
1085          static signed char *dict = 0;          uint32 roff, rlen;
1086    
1087            struct stream *ns = &(g_mppc_dict.ns);
1088    
1089          in_uint8s(s, 6);        /* shareid, pad, streamid */          in_uint8s(s, 6);        /* shareid, pad, streamid */
1090          in_uint16(s, len);          in_uint16(s, len);
# Line 903  process_data_pdu(STREAM s) Line 1093  process_data_pdu(STREAM s)
1093          in_uint16(s, clen);          in_uint16(s, clen);
1094          clen -= 18;          clen -= 18;
1095    
1096  #if 0          if (ctype & RDP_MPPC_COMPRESSED)
         if (ctype & 0x20)  
1097          {          {
1098                  if (!dict)                  if (len > RDP_MPPC_DICT_SIZE)
1099                  {                          error("error decompressed packet size exceeds max\n");
1100                          dict = (signed char *) malloc(8200 * sizeof(signed char));                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1101                          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);  
1102    
1103                  len -= 18;                  //len -= 18;
1104    
1105                  ns.data = xrealloc(ns.data, len);                  /* allocate memory and copy the uncompressed data into the temporary stream */
1106                    ns->data = (uint8 *) xrealloc(ns->data, rlen);
1107    
1108                  ns.data = (unsigned char *) memcpy(ns.data, (unsigned char *) (dict + roff), len);                  memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
1109    
1110                  ns.size = len;                  ns->size = rlen;
1111                  ns.end = ns.data + ns.size;                  ns->end = (ns->data + ns->size);
1112                  ns.p = ns.data;                  ns->p = ns->data;
1113                  ns.rdp_hdr = ns.p;                  ns->rdp_hdr = ns->p;
1114    
1115                  s = &ns;                  s = ns;
1116          }          }
 #endif  
1117    
1118          switch (data_pdu_type)          switch (data_pdu_type)
1119          {          {
# Line 935  process_data_pdu(STREAM s) Line 1121  process_data_pdu(STREAM s)
1121                          process_update_pdu(s);                          process_update_pdu(s);
1122                          break;                          break;
1123    
1124                    case RDP_DATA_PDU_CONTROL:
1125                            DEBUG(("Received Control PDU\n"));
1126                            break;
1127    
1128                    case RDP_DATA_PDU_SYNCHRONISE:
1129                            DEBUG(("Received Sync PDU\n"));
1130                            break;
1131    
1132                  case RDP_DATA_PDU_POINTER:                  case RDP_DATA_PDU_POINTER:
1133                          process_pointer_pdu(s);                          process_pointer_pdu(s);
1134                          break;                          break;
# Line 949  process_data_pdu(STREAM s) Line 1143  process_data_pdu(STREAM s)
1143                          break;                          break;
1144    
1145                  case RDP_DATA_PDU_DISCONNECT:                  case RDP_DATA_PDU_DISCONNECT:
1146                          /* Normally received when user logs out or disconnects from a                          process_disconnect_pdu(s, ext_disc_reason);
1147                             console session on Windows XP and 2003 Server */                          return True;
                         DEBUG(("Received disconnect PDU\n"));  
                         break;  
1148    
1149                  default:                  default:
1150                          unimpl("data PDU %d\n", data_pdu_type);                          unimpl("data PDU %d\n", data_pdu_type);
1151          }          }
1152            return False;
1153  }  }
1154    
1155  /* Process incoming packets */  /* Process incoming packets */
1156    /* nevers gets out of here till app is done */
1157    void
1158    rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1159    {
1160            while (rdp_loop(deactivated, ext_disc_reason))
1161                    ;
1162    }
1163    
1164    /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1165  BOOL  BOOL
1166  rdp_main_loop(void)  rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1167  {  {
1168          uint8 type;          uint8 type;
1169            BOOL disc = False;      /* True when a disconnect PDU was received */
1170            BOOL cont = True;
1171          STREAM s;          STREAM s;
1172    
1173          while ((s = rdp_recv(&type)) != NULL)          while (cont)
1174          {          {
1175                    s = rdp_recv(&type);
1176                    if (s == NULL)
1177                            return False;
1178                  switch (type)                  switch (type)
1179                  {                  {
1180                          case RDP_PDU_DEMAND_ACTIVE:                          case RDP_PDU_DEMAND_ACTIVE:
1181                                  process_demand_active(s);                                  process_demand_active(s);
1182                                    *deactivated = False;
1183                                  break;                                  break;
   
1184                          case RDP_PDU_DEACTIVATE:                          case RDP_PDU_DEACTIVATE:
1185                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));
1186                                  /* 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; */  
1187                                  break;                                  break;
   
1188                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1189                                  process_data_pdu(s);                                  disc = process_data_pdu(s, ext_disc_reason);
1190                                  break;                                  break;
   
1191                          case 0:                          case 0:
1192                                  break;                                  break;
   
1193                          default:                          default:
1194                                  unimpl("PDU %d\n", type);                                  unimpl("PDU %d\n", type);
1195                  }                  }
1196                    if (disc)
1197                            return False;
1198                    cont = g_next_packet < s->end;
1199          }          }
1200          return True;          return True;
         /* We want to detect if we got a clean shutdown, but we  
            can't. Se above.    
            return False;  */  
1201  }  }
1202    
1203  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */

Legend:
Removed from v.654  
changed lines
  Added in v.831

  ViewVC Help
Powered by ViewVC 1.1.26