/[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 522 by matthewc, Wed Oct 29 04:18:00 2003 UTC revision 725 by jsorg71, Sun Jun 27 17:51:54 2004 UTC
# Line 18  Line 18 
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
21    #include <time.h>
22  #include "rdesktop.h"  #include "rdesktop.h"
23    
24  extern uint16 g_mcs_userid;  extern uint16 g_mcs_userid;
# Line 28  extern BOOL g_encryption; Line 29  extern BOOL g_encryption;
29  extern BOOL g_desktop_save;  extern BOOL g_desktop_save;
30  extern BOOL g_use_rdp5;  extern BOOL g_use_rdp5;
31  extern uint16 g_server_rdp_version;  extern uint16 g_server_rdp_version;
32    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 131  rdp_out_unistr(STREAM s, char *string, i Line 139  rdp_out_unistr(STREAM s, char *string, i
139          s->p += len;          s->p += len;
140  }  }
141    
142    /* Input a string in Unicode
143     *
144     * Returns str_len of string
145     */
146    int
147    rdp_in_unistr(STREAM s, char *string, int uni_len)
148    {
149            int i = 0;
150    
151            while (i < uni_len / 2)
152            {
153                    in_uint8a(s, &string[i++], 1);
154                    in_uint8s(s, 1);
155            }
156    
157            return i - 1;
158    }
159    
160    
161  /* Parse a logon info packet */  /* Parse a logon info packet */
162  static void  static void
163  rdp_send_logon_info(uint32 flags, char *domain, char *user,  rdp_send_logon_info(uint32 flags, char *domain, char *user,
164                      char *password, char *program, char *directory)                      char *password, char *program, char *directory)
165  {  {
166            char *ipaddr = tcp_get_address();
167          int len_domain = 2 * strlen(domain);          int len_domain = 2 * strlen(domain);
168          int len_user = 2 * strlen(user);          int len_user = 2 * strlen(user);
169          int len_password = 2 * strlen(password);          int len_password = 2 * strlen(password);
170          int len_program = 2 * strlen(program);          int len_program = 2 * strlen(program);
171          int len_directory = 2 * strlen(directory);          int len_directory = 2 * strlen(directory);
172          int len_ip = 2 * strlen("127.0.0.1");          int len_ip = 2 * strlen(ipaddr);
173          int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");          int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
174          int packetlen = 0;          int packetlen = 0;
175          uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;          uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
176          STREAM s;          STREAM s;
177            time_t t = time(NULL);
178            time_t tzone;
179    
180    #if 0
181            /* enable rdp compression */
182            /* some problems still exist with rdp5 */
183            flags |= RDP_COMPRESSION;
184    #endif
185    
186          if (!g_use_rdp5 || 1 == g_server_rdp_version)          if (!g_use_rdp5 || 1 == g_server_rdp_version)
187          {          {
# Line 169  rdp_send_logon_info(uint32 flags, char * Line 205  rdp_send_logon_info(uint32 flags, char *
205          }          }
206          else          else
207          {          {
208    
209                  flags |= RDP_LOGON_BLOB;                  flags |= RDP_LOGON_BLOB;
210                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
211                  packetlen = 4 + // Unknown uint32                  packetlen = 4 + /* Unknown uint32 */
212                          4 +     // flags                          4 +     /* flags */
213                          2 +     // len_domain                          2 +     /* len_domain */
214                          2 +     // len_user                          2 +     /* len_user */
215                          (flags & RDP_LOGON_AUTO ? 2 : 0) +      // len_password                          (flags & RDP_LOGON_AUTO ? 2 : 0) +      /* len_password */
216                          (flags & RDP_LOGON_BLOB ? 2 : 0) +      // Length of BLOB                          (flags & RDP_LOGON_BLOB ? 2 : 0) +      /* Length of BLOB */
217                          2 +     // len_program                          2 +     /* len_program */
218                          2 +     // len_directory                          2 +     /* len_directory */
219                          (0 < len_domain ? len_domain : 2) +     // domain                          (0 < len_domain ? len_domain : 2) +     /* domain */
220                          len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 +    // We have no 512 byte BLOB. Perhaps we must?                          len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 +    /* We have no 512 byte BLOB. Perhaps we must? */
221                          (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + // After the BLOB is a unknown int16. If there is a BLOB, that is.                          (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + /* After the BLOB is a unknown int16. If there is a BLOB, that is. */
222                          (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 +     // Unknown (2)                          (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 +     /* Unknown (2) */
223                          2 +     // Client ip length                          2 +     /* Client ip length */
224                          len_ip +        // Client ip                          len_ip +        /* Client ip */
225                          2 +     // DLL string length                          2 +     /* DLL string length */
226                          len_dll +       // DLL string                          len_dll +       /* DLL string */
227                          2 +     // Unknown                          2 +     /* Unknown */
228                          2 +     // Unknown                          2 +     /* Unknown */
229                          64 +    // Time zone #0                          64 +    /* Time zone #0 */
230                          2 +     // Unknown                          2 +     /* Unknown */
231                          64 +    // Time zone #1                          64 +    /* Time zone #1 */
232                          32;     // Unknown                          32;     /* Unknown */
233    
234                  s = sec_init(sec_flags, packetlen);                  s = sec_init(sec_flags, packetlen);
235                  DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));                  DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
236    
237                  out_uint32(s, 0);       // Unknown                  out_uint32(s, 0);       /* Unknown */
238                  out_uint32_le(s, flags);                  out_uint32_le(s, flags);
239                  out_uint16_le(s, len_domain);                  out_uint16_le(s, len_domain);
240                  out_uint16_le(s, len_user);                  out_uint16_le(s, len_user);
# Line 243  rdp_send_logon_info(uint32 flags, char * Line 280  rdp_send_logon_info(uint32 flags, char *
280                          out_uint16_le(s, 0);                          out_uint16_le(s, 0);
281                  }                  }
282                  out_uint16_le(s, 2);                  out_uint16_le(s, 2);
283                  out_uint16_le(s, len_ip + 2);   // Length of client ip                  out_uint16_le(s, len_ip + 2);   /* Length of client ip */
284                  rdp_out_unistr(s, "127.0.0.1", len_ip);                  rdp_out_unistr(s, ipaddr, len_ip);
285                  out_uint16_le(s, len_dll + 2);                  out_uint16_le(s, len_dll + 2);
286                  rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);                  rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
287                  out_uint16_le(s, 0xffc4);  
288                  out_uint16_le(s, 0xffff);                  tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
289                    out_uint32_le(s, tzone);
290    
291                  rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));                  rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
292                  out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));                  out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
293    
   
294                  out_uint32_le(s, 0x0a0000);                  out_uint32_le(s, 0x0a0000);
295                  out_uint32_le(s, 0x050000);                  out_uint32_le(s, 0x050000);
296                  out_uint32_le(s, 3);                  out_uint32_le(s, 3);
# Line 268  rdp_send_logon_info(uint32 flags, char * Line 306  rdp_send_logon_info(uint32 flags, char *
306                  out_uint32(s, 0);                  out_uint32(s, 0);
307                  out_uint32_le(s, 0xffffffc4);                  out_uint32_le(s, 0xffffffc4);
308                  out_uint32_le(s, 0xfffffffe);                  out_uint32_le(s, 0xfffffffe);
309                  out_uint32_le(s, 0x0f);                  out_uint32_le(s, g_rdp5_performanceflags);
310                  out_uint32(s, 0);                  out_uint32(s, 0);
311    
312    
# Line 329  rdp_send_input(uint32 time, uint16 messa Line 367  rdp_send_input(uint32 time, uint16 messa
367          rdp_send_data(s, RDP_DATA_PDU_INPUT);          rdp_send_data(s, RDP_DATA_PDU_INPUT);
368  }  }
369    
370    /* Inform the server on the contents of the persistent bitmap cache */
371    static void
372    rdp_enum_bmpcache2(void)
373    {
374            STREAM s;
375            uint8 idlist[BMPCACHE2_NUM_PSTCELLS * sizeof(BITMAP_ID)];
376            uint32 nids, offset, count, flags;
377    
378            offset = 0;
379            nids = pstcache_enumerate(2, idlist);
380    
381            while (offset < nids)
382            {
383                    count = MIN(nids - offset, 169);
384    
385                    s = rdp_init_data(24 + count * sizeof(BITMAP_ID));
386    
387                    flags = 0;
388                    if (offset == 0)
389                            flags |= PDU_FLAG_FIRST;
390                    if (nids - offset <= 169)
391                            flags |= PDU_FLAG_LAST;
392    
393                    /* header */
394                    out_uint32_le(s, 0);
395                    out_uint16_le(s, count);
396                    out_uint16_le(s, 0);
397                    out_uint16_le(s, 0);
398                    out_uint16_le(s, 0);
399                    out_uint16_le(s, 0);
400                    out_uint16_le(s, nids);
401                    out_uint32_le(s, 0);
402                    out_uint32_le(s, flags);
403    
404                    /* list */
405                    out_uint8a(s, idlist + offset * sizeof(BITMAP_ID),
406                                    count * sizeof(BITMAP_ID));
407    
408                    s_mark_end(s);
409                    rdp_send_data(s, 0x2b);
410    
411                    offset += 169;
412            }
413    }
414    
415  /* Send an (empty) font information PDU */  /* Send an (empty) font information PDU */
416  static void  static void
417  rdp_send_fonts(uint16 seq)  rdp_send_fonts(uint16 seq)
# Line 338  rdp_send_fonts(uint16 seq) Line 421  rdp_send_fonts(uint16 seq)
421          s = rdp_init_data(8);          s = rdp_init_data(8);
422    
423          out_uint16(s, 0);       /* number of fonts */          out_uint16(s, 0);       /* number of fonts */
424          out_uint16_le(s, 0x3e); /* unknown */          out_uint16_le(s, 0);    /* pad? */
425          out_uint16_le(s, seq);  /* unknown */          out_uint16_le(s, seq);  /* unknown */
426          out_uint16_le(s, 0x32); /* entry size */          out_uint16_le(s, 0x32); /* entry size */
427    
# Line 379  rdp_out_bitmap_caps(STREAM s) Line 462  rdp_out_bitmap_caps(STREAM s)
462          out_uint16_le(s, RDP_CAPSET_BITMAP);          out_uint16_le(s, RDP_CAPSET_BITMAP);
463          out_uint16_le(s, RDP_CAPLEN_BITMAP);          out_uint16_le(s, RDP_CAPLEN_BITMAP);
464    
465          out_uint16_le(s, 8);    /* Preferred BPP */          out_uint16_le(s, g_server_bpp); /* Preferred BPP */
466          out_uint16_le(s, 1);    /* Receive 1 BPP */          out_uint16_le(s, 1);    /* Receive 1 BPP */
467          out_uint16_le(s, 1);    /* Receive 4 BPP */          out_uint16_le(s, 1);    /* Receive 4 BPP */
468          out_uint16_le(s, 1);    /* Receive 8 BPP */          out_uint16_le(s, 1);    /* Receive 8 BPP */
469          out_uint16_le(s, 800);  /* Desktop width */          out_uint16_le(s, 800);  /* Desktop width */
470          out_uint16_le(s, 600);  /* Desktop height */          out_uint16_le(s, 600);  /* Desktop height */
471          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
472          out_uint16(s, 0);       /* Allow resize */          out_uint16(s, 1);       /* Allow resize */
473          out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */          out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
474          out_uint16(s, 0);       /* Unknown */          out_uint16(s, 0);       /* Unknown */
475          out_uint16_le(s, 1);    /* Unknown */          out_uint16_le(s, 1);    /* Unknown */
# Line 404  rdp_out_order_caps(STREAM s) Line 487  rdp_out_order_caps(STREAM s)
487          order_caps[0] = 1;      /* dest blt */          order_caps[0] = 1;      /* dest blt */
488          order_caps[1] = 1;      /* pat blt */          order_caps[1] = 1;      /* pat blt */
489          order_caps[2] = 1;      /* screen blt */          order_caps[2] = 1;      /* screen blt */
490          order_caps[3] = 1;      /* required for memblt? */          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
491          order_caps[8] = 1;      /* line */          order_caps[8] = 1;      /* line */
492          order_caps[9] = 1;      /* line */          order_caps[9] = 1;      /* line */
493          order_caps[10] = 1;     /* rect */          order_caps[10] = 1;     /* rect */
# Line 449  rdp_out_bmpcache_caps(STREAM s) Line 532  rdp_out_bmpcache_caps(STREAM s)
532          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
533  }  }
534    
535    /* Output bitmap cache v2 capability set */
536    static void
537    rdp_out_bmpcache2_caps(STREAM s)
538    {
539            out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
540            out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
541    
542            out_uint16_le(s, g_bitmap_cache_persist_enable ? 1 : 0);        /* version */
543    
544            out_uint16_le(s, 0x0300);       /* flags? number of caches? */
545    
546            out_uint32_le(s, BMPCACHE2_C0_CELLS);
547            out_uint32_le(s, BMPCACHE2_C1_CELLS);
548            if (pstcache_init(2))
549            {
550                    out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
551            }
552            else
553            {
554                    out_uint32_le(s, BMPCACHE2_C2_CELLS);
555            }
556            out_uint8s(s, 20);              /* other bitmap caches not used */
557    }
558    
559  /* Output control capability set */  /* Output control capability set */
560  static void  static void
561  rdp_out_control_caps(STREAM s)  rdp_out_control_caps(STREAM s)
# Line 508  rdp_out_colcache_caps(STREAM s) Line 615  rdp_out_colcache_caps(STREAM s)
615          out_uint16(s, 0);       /* pad */          out_uint16(s, 0);       /* pad */
616  }  }
617    
618  static uint8 canned_caps[] = {  static uint8 caps_0x0d[] = {
619          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
620          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
621          0x00, 0x00, 0x00, 0x00, 0x00,          0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
622          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
623          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
624          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
625          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
626          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
627          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
628          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
629          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  
630  };  };
631    
632  /* Output unknown capability sets (number 13, 12, 14 and 16) */  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
633    
634    static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
635    
636    static uint8 caps_0x10[] = {
637            0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
638            0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
639            0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
640            0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
641            0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
642            0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
643    };
644    
645    /* Output unknown capability sets */
646  static void  static void
647  rdp_out_unknown_caps(STREAM s)  rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 *caps)
648  {  {
649          out_uint16_le(s, RDP_CAPSET_UNKNOWN);          out_uint16_le(s, id);
650          out_uint16_le(s, 0x58);          out_uint16_le(s, length);
651    
652          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);          out_uint8p(s, caps, length - 4);
653  }  }
654    
655  #define RDP5_FLAG 0x0030  #define RDP5_FLAG 0x0030
# Line 551  rdp_send_confirm_active(void) Line 663  rdp_send_confirm_active(void)
663                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
664                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
665                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
666                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
667                    0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */ +
668                    4 /* w2k fix, why? */ ;
669    
670          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
671    
# Line 571  rdp_send_confirm_active(void) Line 685  rdp_send_confirm_active(void)
685          rdp_out_general_caps(s);          rdp_out_general_caps(s);
686          rdp_out_bitmap_caps(s);          rdp_out_bitmap_caps(s);
687          rdp_out_order_caps(s);          rdp_out_order_caps(s);
688          rdp_out_bmpcache_caps(s);          g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
689          rdp_out_colcache_caps(s);          rdp_out_colcache_caps(s);
690          rdp_out_activate_caps(s);          rdp_out_activate_caps(s);
691          rdp_out_control_caps(s);          rdp_out_control_caps(s);
692          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
693          rdp_out_share_caps(s);          rdp_out_share_caps(s);
         rdp_out_unknown_caps(s);  
694    
695            rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
696            rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
697            rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
698            rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
699                                    
700          s_mark_end(s);          s_mark_end(s);
701          sec_send(s, sec_flags);          sec_send(s, sec_flags);
702  }  }
703    
704    /* Process a general capability set */
705    static void
706    rdp_process_general_caps(STREAM s)
707    {
708            uint16 pad2octetsB;     /* rdp5 flags? */
709    
710            in_uint8s(s, 10);
711            in_uint16_le(s, pad2octetsB);
712    
713            if (!pad2octetsB)
714                    g_use_rdp5 = False;
715    }
716    
717    /* Process a bitmap capability set */
718    static void
719    rdp_process_bitmap_caps(STREAM s)
720    {
721            uint16 width, height, bpp;
722    
723            in_uint16_le(s, bpp);
724            in_uint8s(s, 6);
725    
726            in_uint16_le(s, width);
727            in_uint16_le(s, height);
728    
729            DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));
730    
731            /*
732             * The server may limit bpp and change the size of the desktop (for
733             * example when shadowing another session).
734             */
735            if (g_server_bpp != bpp)
736            {
737                    warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
738                    g_server_bpp = bpp;
739            }
740            if (g_width != width || g_height != height)
741            {
742                    warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
743                                    width, height);
744                    g_width = width;
745                    g_height = height;
746                    ui_resize_window();
747            }
748    }
749    
750    /* Process server capabilities */
751    void
752    rdp_process_server_caps(STREAM s, uint16 length)
753    {
754            int n;
755            uint8 *next, *start;
756            uint16 ncapsets, capset_type, capset_length;
757    
758            start = s->p;
759    
760            in_uint16_le(s, ncapsets);
761            in_uint8s(s, 2);        /* pad */
762    
763            for (n = 0; n < ncapsets; n++)
764            {
765                    if (s->p > start + length)
766                            return;
767    
768                    in_uint16_le(s, capset_type);
769                    in_uint16_le(s, capset_length);
770    
771                    next = s->p + capset_length - 4;
772    
773                    switch (capset_type)
774                    {
775                            case RDP_CAPSET_GENERAL:
776                                    rdp_process_general_caps(s);
777                                    break;
778    
779                            case RDP_CAPSET_BITMAP:
780                                    rdp_process_bitmap_caps(s);
781                                    break;
782                    }
783    
784                    s->p = next;
785            }
786    }
787    
788  /* Respond to a demand active PDU */  /* Respond to a demand active PDU */
789  static void  static void
790  process_demand_active(STREAM s)  process_demand_active(STREAM s)
791  {  {
792          uint8 type;          uint8 type;
793            uint16 len_src_descriptor, len_combined_caps;
794    
795          in_uint32_le(s, g_rdp_shareid);          in_uint32_le(s, g_rdp_shareid);
796            in_uint16_le(s, len_src_descriptor);
797            in_uint16_le(s, len_combined_caps);
798            in_uint8s(s, len_src_descriptor);
799    
800          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
801            rdp_process_server_caps(s, len_combined_caps);
802    
803          rdp_send_confirm_active();          rdp_send_confirm_active();
804          rdp_send_synchronise();          rdp_send_synchronise();
# Line 600  process_demand_active(STREAM s) Line 807  process_demand_active(STREAM s)
807          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
808          rdp_recv(&type);        /* RDP_CTL_COOPERATE */          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
809          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
810          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, 0, 0);          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);
811          rdp_send_fonts(1);  
812          rdp_send_fonts(2);          if (g_use_rdp5)
813          rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 */          {
814                    rdp_enum_bmpcache2();
815                    rdp_send_fonts(3);
816            }
817            else
818            {
819                    rdp_send_fonts(1);
820                    rdp_send_fonts(2);
821            }
822    
823            rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
824          reset_order_state();          reset_order_state();
825  }  }
826    
# Line 724  process_bitmap_updates(STREAM s) Line 941  process_bitmap_updates(STREAM s)
941                  DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",                  DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
942                         left, top, right, bottom, width, height, Bpp, compress));                         left, top, right, bottom, width, height, Bpp, compress));
943    
                 /* Server may limit bpp - this is how we find out */  
                 if (g_server_bpp != bpp) {  
                         warning("Server limited colour depth to %d bits\n", bpp);  
                         g_server_bpp = bpp;  
                 }  
   
944                  if (!compress)                  if (!compress)
945                  {                  {
946                          int y;                          int y;
# Line 809  process_update_pdu(STREAM s) Line 1020  process_update_pdu(STREAM s)
1020    
1021          in_uint16_le(s, update_type);          in_uint16_le(s, update_type);
1022    
1023            ui_begin_update();
1024          switch (update_type)          switch (update_type)
1025          {          {
1026                  case RDP_UPDATE_ORDERS:                  case RDP_UPDATE_ORDERS:
# Line 832  process_update_pdu(STREAM s) Line 1044  process_update_pdu(STREAM s)
1044                  default:                  default:
1045                          unimpl("update %d\n", update_type);                          unimpl("update %d\n", update_type);
1046          }          }
1047            ui_end_update();
1048    }
1049    
1050    /* Process a disconnect PDU */
1051    void
1052    process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
1053    {
1054            in_uint32_le(s, *ext_disc_reason);
1055    
1056            DEBUG(("Received disconnect PDU\n"));
1057  }  }
1058    
1059  /* Process data PDU */  /* Process data PDU */
1060  static void  static BOOL
1061  process_data_pdu(STREAM s)  process_data_pdu(STREAM s, uint32 * ext_disc_reason)
1062  {  {
1063          uint8 data_pdu_type;          uint8 data_pdu_type;
1064            uint8 ctype;
1065            uint16 clen;
1066            uint32 len;
1067    
1068            uint32 roff, rlen;
1069    
1070            struct stream *ns = &(g_mppc_dict.ns);
1071    
1072          in_uint8s(s, 8);        /* shareid, pad, streamid, length */          in_uint8s(s, 6);        /* shareid, pad, streamid */
1073            in_uint16(s, len);
1074          in_uint8(s, data_pdu_type);          in_uint8(s, data_pdu_type);
1075          in_uint8s(s, 3);        /* compress_type, compress_len */          in_uint8(s, ctype);
1076            in_uint16(s, clen);
1077            clen -= 18;
1078    
1079            if (ctype & RDP_MPPC_COMPRESSED)
1080            {
1081    
1082                    if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1083                            error("error while decompressing packet\n");
1084    
1085                    //len -= 18;
1086    
1087                    /* allocate memory and copy the uncompressed data into the temporary stream */
1088                    ns->data = (uint8 *) xrealloc(ns->data, rlen);
1089    
1090                    memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
1091    
1092                    ns->size = rlen;
1093                    ns->end = (ns->data + ns->size);
1094                    ns->p = ns->data;
1095                    ns->rdp_hdr = ns->p;
1096    
1097                    s = ns;
1098            }
1099    
1100          switch (data_pdu_type)          switch (data_pdu_type)
1101          {          {
# Line 851  process_data_pdu(STREAM s) Line 1103  process_data_pdu(STREAM s)
1103                          process_update_pdu(s);                          process_update_pdu(s);
1104                          break;                          break;
1105    
1106                    case RDP_DATA_PDU_CONTROL:
1107                            DEBUG(("Received Control PDU\n"));
1108                            break;
1109    
1110                    case RDP_DATA_PDU_SYNCHRONISE:
1111                            DEBUG(("Received Sync PDU\n"));
1112                            break;
1113    
1114                  case RDP_DATA_PDU_POINTER:                  case RDP_DATA_PDU_POINTER:
1115                          process_pointer_pdu(s);                          process_pointer_pdu(s);
1116                          break;                          break;
# Line 865  process_data_pdu(STREAM s) Line 1125  process_data_pdu(STREAM s)
1125                          break;                          break;
1126    
1127                  case RDP_DATA_PDU_DISCONNECT:                  case RDP_DATA_PDU_DISCONNECT:
1128                          /* Normally received when user logs out or disconnects from a                          process_disconnect_pdu(s, ext_disc_reason);
1129                             console session on Windows XP and 2003 Server */                          return True;
                         DEBUG(("Received disconnect PDU\n"));  
                         break;  
1130    
1131                  default:                  default:
1132                          unimpl("data PDU %d\n", data_pdu_type);                          unimpl("data PDU %d\n", data_pdu_type);
1133          }          }
1134            return False;
1135  }  }
1136    
1137  /* Process incoming packets */  /* Process incoming packets */
1138  BOOL  void
1139  rdp_main_loop(void)  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1140  {  {
1141          uint8 type;          uint8 type;
1142            BOOL disc = False;      /* True when a disconnect PDU was received */
1143          STREAM s;          STREAM s;
1144    
1145          while ((s = rdp_recv(&type)) != NULL)          while ((s = rdp_recv(&type)) != NULL)
# Line 888  rdp_main_loop(void) Line 1148  rdp_main_loop(void)
1148                  {                  {
1149                          case RDP_PDU_DEMAND_ACTIVE:                          case RDP_PDU_DEMAND_ACTIVE:
1150                                  process_demand_active(s);                                  process_demand_active(s);
1151                                    *deactivated = False;
1152                                  break;                                  break;
1153    
1154                          case RDP_PDU_DEACTIVATE:                          case RDP_PDU_DEACTIVATE:
1155                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));
1156                                  /* 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; */  
1157                                  break;                                  break;
1158    
1159                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1160                                  process_data_pdu(s);                                  disc = process_data_pdu(s, ext_disc_reason);
1161                                  break;                                  break;
1162    
1163                          case 0:                          case 0:
# Line 910  rdp_main_loop(void) Line 1166  rdp_main_loop(void)
1166                          default:                          default:
1167                                  unimpl("PDU %d\n", type);                                  unimpl("PDU %d\n", type);
1168                  }                  }
1169    
1170                    if (disc)
1171                    {
1172                            return;
1173                    }
1174            }
1175            return;
1176    }
1177    
1178    /* used in uiports, processes the rdp packets waiting */
1179    BOOL
1180    rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1181    {
1182            uint8 type;
1183            BOOL disc = False;      /* True when a disconnect PDU was received */
1184            BOOL cont = True;
1185            STREAM s;
1186    
1187            while (cont)
1188            {
1189                    s = rdp_recv(&type);
1190                    if (s == NULL)
1191                            return False;
1192                    switch (type)
1193                    {
1194                            case RDP_PDU_DEMAND_ACTIVE:
1195                                    process_demand_active(s);
1196                                    *deactivated = False;
1197                                    break;
1198                            case RDP_PDU_DEACTIVATE:
1199                                    DEBUG(("RDP_PDU_DEACTIVATE\n"));
1200                                    *deactivated = True;
1201                                    break;
1202                            case RDP_PDU_DATA:
1203                                    disc = process_data_pdu(s, ext_disc_reason);
1204                                    break;
1205                            case 0:
1206                                    break;
1207                            default:
1208                                    unimpl("PDU %d\n", type);
1209                    }
1210                    if (disc)
1211                            return False;
1212                    cont = g_next_packet < s->end;
1213          }          }
1214          return True;          return True;
         /* We want to detect if we got a clean shutdown, but we  
            can't. Se above.    
            return False;  */  
1215  }  }
1216    
1217  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */

Legend:
Removed from v.522  
changed lines
  Added in v.725

  ViewVC Help
Powered by ViewVC 1.1.26