/[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 64 by astrand, Thu Jul 18 16:38:31 2002 UTC revision 848 by jsorg71, Sun Mar 13 03:29:19 2005 UTC
# Line 1  Line 1 
1  /*  /* -*- 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-2001     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
8     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.     GNU General Public License for more details.
15      
16     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
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 mcs_userid;  extern uint16 g_mcs_userid;
25  extern char username[16];  extern char g_username[16];
26  extern BOOL bitmap_compression;  extern BOOL g_bitmap_compression;
27  extern BOOL orders;  extern BOOL g_orders;
28  extern BOOL encryption;  extern BOOL g_encryption;
29  extern BOOL desktop_save;  extern BOOL g_desktop_save;
30    extern BOOL g_polygon_ellipse_orders;
31  uint8 *next_packet;  extern BOOL g_use_rdp5;
32  uint32 rdp_shareid;  extern uint16 g_server_rdp_version;
33    extern uint32 g_rdp5_performanceflags;
34  /* Initialise an RDP packet */  extern int g_server_bpp;
35  static STREAM  extern int g_width;
36  rdp_init(int maxlen)  extern int g_height;
37  {  extern BOOL g_bitmap_cache;
38          STREAM s;  extern BOOL g_bitmap_cache_persist_enable;
   
         s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 6);  
         s_push_layer(s, rdp_hdr, 6);  
   
         return s;  
 }  
   
 /* Send an RDP packet */  
 static void  
 rdp_send(STREAM s, uint8 pdu_type)  
 {  
         uint16 length;  
39    
40          s_pop_layer(s, rdp_hdr);  uint8 *g_next_packet;
41          length = s->end - s->p;  uint32 g_rdp_shareid;
42    
43          out_uint16_le(s, length);  extern RDPCOMP g_mppc_dict;
         out_uint16_le(s, (pdu_type | 0x10));    /* Version 1 */  
         out_uint16_le(s, (mcs_userid + 1001));  
44    
45          sec_send(s, encryption ? SEC_ENCRYPT : 0);  #if WITH_DEBUG
46  }  static uint32 g_packetno;
47    #endif
48    
49  /* Receive an RDP packet */  /* Receive an RDP packet */
50  static STREAM  static STREAM
# Line 64  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) || (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                  next_packet = rdp_s->p;                  g_next_packet = rdp_s->p;
77          }          }
78          else          else
79          {          {
80                  rdp_s->p = next_packet;                  rdp_s->p = g_next_packet;
81          }          }
82    
83          in_uint16_le(rdp_s, length);          in_uint16_le(rdp_s, length);
84            /* 32k packets are really 8, keepalive fix */
85            if (length == 0x8000)
86            {
87                    g_next_packet += 8;
88                    *type = 0;
89                    return rdp_s;
90            }
91          in_uint16_le(rdp_s, pdu_type);          in_uint16_le(rdp_s, pdu_type);
92          in_uint8s(rdp_s, 2);    /* userid */          in_uint8s(rdp_s, 2);    /* userid */
93          *type = pdu_type & 0xf;          *type = pdu_type & 0xf;
94    
95  #if WITH_DEBUG  #if WITH_DEBUG
96          DEBUG(("RDP packet (type %x):\n", *type));          DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type));
97          hexdump(next_packet, length);          hexdump(g_next_packet, length);
98  #endif /*  */  #endif /*  */
99    
100          next_packet += length;          g_next_packet += length;
101          return rdp_s;          return rdp_s;
102  }  }
103    
# Line 98  rdp_init_data(int maxlen) Line 107  rdp_init_data(int maxlen)
107  {  {
108          STREAM s;          STREAM s;
109    
110          s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 18);          s = sec_init(g_encryption ? SEC_ENCRYPT : 0, maxlen + 18);
111          s_push_layer(s, rdp_hdr, 18);          s_push_layer(s, rdp_hdr, 18);
112    
113          return s;          return s;
# Line 115  rdp_send_data(STREAM s, uint8 data_pdu_t Line 124  rdp_send_data(STREAM s, uint8 data_pdu_t
124    
125          out_uint16_le(s, length);          out_uint16_le(s, length);
126          out_uint16_le(s, (RDP_PDU_DATA | 0x10));          out_uint16_le(s, (RDP_PDU_DATA | 0x10));
127          out_uint16_le(s, (mcs_userid + 1001));          out_uint16_le(s, (g_mcs_userid + 1001));
128    
129          out_uint32_le(s, rdp_shareid);          out_uint32_le(s, g_rdp_shareid);
130          out_uint8(s, 0);        /* pad */          out_uint8(s, 0);        /* pad */
131          out_uint8(s, 1);        /* streamid */          out_uint8(s, 1);        /* streamid */
132          out_uint16(s, (length - 14));          out_uint16_le(s, (length - 14));
133          out_uint8(s, data_pdu_type);          out_uint8(s, data_pdu_type);
134          out_uint8(s, 0);        /* compress_type */          out_uint8(s, 0);        /* compress_type */
135          out_uint16(s, 0);       /* compress_len */          out_uint16(s, 0);       /* compress_len */
136    
137          sec_send(s, encryption ? SEC_ENCRYPT : 0);          sec_send(s, g_encryption ? SEC_ENCRYPT : 0);
138  }  }
139    
140  /* Output a string in Unicode */  /* Output a string in Unicode */
# Line 145  rdp_out_unistr(STREAM s, char *string, i Line 154  rdp_out_unistr(STREAM s, char *string, i
154          s->p += len;          s->p += len;
155  }  }
156    
157    /* Input a string in Unicode
158     *
159     * Returns str_len of string
160     */
161    int
162    rdp_in_unistr(STREAM s, char *string, int uni_len)
163    {
164            int i = 0;
165    
166            while (i < uni_len / 2)
167            {
168                    in_uint8a(s, &string[i++], 1);
169                    in_uint8s(s, 1);
170            }
171    
172            return i - 1;
173    }
174    
175    
176  /* Parse a logon info packet */  /* Parse a logon info packet */
177  static void  static void
178  rdp_send_logon_info(uint32 flags, char *domain, char *user,  rdp_send_logon_info(uint32 flags, char *domain, char *user,
179                      char *password, char *program, char *directory)                      char *password, char *program, char *directory)
180  {  {
181            char *ipaddr = tcp_get_address();
182          int len_domain = 2 * strlen(domain);          int len_domain = 2 * strlen(domain);
183          int len_user = 2 * strlen(user);          int len_user = 2 * strlen(user);
184          int len_password = 2 * strlen(password);          int len_password = 2 * strlen(password);
185          int len_program = 2 * strlen(program);          int len_program = 2 * strlen(program);
186          int len_directory = 2 * strlen(directory);          int len_directory = 2 * strlen(directory);
187          uint32 sec_flags = encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT)          int len_ip = 2 * strlen(ipaddr);
188                  : SEC_LOGON_INFO;          int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
189            int packetlen = 0;
190            uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
191          STREAM s;          STREAM s;
192            time_t t = time(NULL);
193            time_t tzone;
194    
195    #if 0
196            /* enable rdp compression */
197            /* some problems still exist with rdp5 */
198            flags |= RDP_COMPRESSION;
199    #endif
200    
201            if (!g_use_rdp5 || 1 == g_server_rdp_version)
202            {
203                    DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
204    
205                    s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
206                                 + len_program + len_directory + 10);
207    
208                    out_uint32(s, 0);
209                    out_uint32_le(s, flags);
210                    out_uint16_le(s, len_domain);
211                    out_uint16_le(s, len_user);
212                    out_uint16_le(s, len_password);
213                    out_uint16_le(s, len_program);
214                    out_uint16_le(s, len_directory);
215                    rdp_out_unistr(s, domain, len_domain);
216                    rdp_out_unistr(s, user, len_user);
217                    rdp_out_unistr(s, password, len_password);
218                    rdp_out_unistr(s, program, len_program);
219                    rdp_out_unistr(s, directory, len_directory);
220            }
221            else
222            {
223    
224          s = sec_init(sec_flags, 18 + len_domain + len_user + len_password                  flags |= RDP_LOGON_BLOB;
225                       + len_program + len_directory + 10);                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
226                    packetlen = 4 + /* Unknown uint32 */
227                            4 +     /* flags */
228                            2 +     /* len_domain */
229                            2 +     /* len_user */
230                            (flags & RDP_LOGON_AUTO ? 2 : 0) +      /* len_password */
231                            (flags & RDP_LOGON_BLOB ? 2 : 0) +      /* Length of BLOB */
232                            2 +     /* len_program */
233                            2 +     /* len_directory */
234                            (0 < len_domain ? len_domain : 2) +     /* domain */
235                            len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 +    /* We have no 512 byte BLOB. Perhaps we must? */
236                            (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + /* After the BLOB is a unknown int16. If there is a BLOB, that is. */
237                            (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 +     /* Unknown (2) */
238                            2 +     /* Client ip length */
239                            len_ip +        /* Client ip */
240                            2 +     /* DLL string length */
241                            len_dll +       /* DLL string */
242                            2 +     /* Unknown */
243                            2 +     /* Unknown */
244                            64 +    /* Time zone #0 */
245                            2 +     /* Unknown */
246                            64 +    /* Time zone #1 */
247                            32;     /* Unknown */
248    
249                    s = sec_init(sec_flags, packetlen);
250                    DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
251    
252                    out_uint32(s, 0);       /* Unknown */
253                    out_uint32_le(s, flags);
254                    out_uint16_le(s, len_domain);
255                    out_uint16_le(s, len_user);
256                    if (flags & RDP_LOGON_AUTO)
257                    {
258                            out_uint16_le(s, len_password);
259    
260          out_uint32(s, 0);                  }
261          out_uint32_le(s, flags);                  if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
262          out_uint16_le(s, len_domain);                  {
263          out_uint16_le(s, len_user);                          out_uint16_le(s, 0);
264          out_uint16_le(s, len_password);                  }
265          out_uint16_le(s, len_program);                  out_uint16_le(s, len_program);
266          out_uint16_le(s, len_directory);                  out_uint16_le(s, len_directory);
267          rdp_out_unistr(s, domain, len_domain);                  if (0 < len_domain)
268          rdp_out_unistr(s, user, len_user);                          rdp_out_unistr(s, domain, len_domain);
269          rdp_out_unistr(s, password, len_password);                  else
270          rdp_out_unistr(s, program, len_program);                          out_uint16_le(s, 0);
271          rdp_out_unistr(s, directory, len_directory);                  rdp_out_unistr(s, user, len_user);
272                    if (flags & RDP_LOGON_AUTO)
273                    {
274                            rdp_out_unistr(s, password, len_password);
275                    }
276                    if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
277                    {
278                            out_uint16_le(s, 0);
279                    }
280                    if (0 < len_program)
281                    {
282                            rdp_out_unistr(s, program, len_program);
283    
284                    }
285                    else
286                    {
287                            out_uint16_le(s, 0);
288                    }
289                    if (0 < len_directory)
290                    {
291                            rdp_out_unistr(s, directory, len_directory);
292                    }
293                    else
294                    {
295                            out_uint16_le(s, 0);
296                    }
297                    out_uint16_le(s, 2);
298                    out_uint16_le(s, len_ip + 2);   /* Length of client ip */
299                    rdp_out_unistr(s, ipaddr, len_ip);
300                    out_uint16_le(s, len_dll + 2);
301                    rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
302    
303                    tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
304                    out_uint32_le(s, tzone);
305    
306                    rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
307                    out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
308    
309                    out_uint32_le(s, 0x0a0000);
310                    out_uint32_le(s, 0x050000);
311                    out_uint32_le(s, 3);
312                    out_uint32_le(s, 0);
313                    out_uint32_le(s, 0);
314    
315                    rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
316                    out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
317    
318                    out_uint32_le(s, 0x30000);
319                    out_uint32_le(s, 0x050000);
320                    out_uint32_le(s, 2);
321                    out_uint32(s, 0);
322                    out_uint32_le(s, 0xffffffc4);
323                    out_uint32_le(s, 0xfffffffe);
324                    out_uint32_le(s, g_rdp5_performanceflags);
325                    out_uint32(s, 0);
326    
327    
328            }
329          s_mark_end(s);          s_mark_end(s);
330          sec_send(s, sec_flags);          sec_send(s, sec_flags);
331  }  }
# Line 197  rdp_send_control(uint16 action) Line 348  rdp_send_control(uint16 action)
348    
349  /* Send a synchronisation PDU */  /* Send a synchronisation PDU */
350  static void  static void
351  rdp_send_synchronise()  rdp_send_synchronise(void)
352  {  {
353          STREAM s;          STREAM s;
354    
# Line 212  rdp_send_synchronise() Line 363  rdp_send_synchronise()
363    
364  /* Send a single input event */  /* Send a single input event */
365  void  void
366  rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags,  rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
                uint16 param1, uint16 param2)  
367  {  {
368          STREAM s;          STREAM s;
369    
# Line 232  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 241  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 261  rdp_out_general_caps(STREAM s) Line 455  rdp_out_general_caps(STREAM s)
455          out_uint16_le(s, 0x200);        /* Protocol version */          out_uint16_le(s, 0x200);        /* Protocol version */
456          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
457          out_uint16(s, 0);       /* Compression types */          out_uint16(s, 0);       /* Compression types */
458          out_uint16(s, 0);       /* Pad */          out_uint16_le(s, g_use_rdp5 ? 0x40d : 0);
459            /* Pad, according to T.128. 0x40d seems to
460               trigger
461               the server to start sending RDP5 packets.
462               However, the value is 0x1d04 with W2KTSK and
463               NT4MS. Hmm.. Anyway, thankyou, Microsoft,
464               for sending such information in a padding
465               field.. */
466          out_uint16(s, 0);       /* Update capability */          out_uint16(s, 0);       /* Update capability */
467          out_uint16(s, 0);       /* Remote unshare capability */          out_uint16(s, 0);       /* Remote unshare capability */
468          out_uint16(s, 0);       /* Compression level */          out_uint16(s, 0);       /* Compression level */
# Line 275  rdp_out_bitmap_caps(STREAM s) Line 476  rdp_out_bitmap_caps(STREAM s)
476          out_uint16_le(s, RDP_CAPSET_BITMAP);          out_uint16_le(s, RDP_CAPSET_BITMAP);
477          out_uint16_le(s, RDP_CAPLEN_BITMAP);          out_uint16_le(s, RDP_CAPLEN_BITMAP);
478    
479          out_uint16_le(s, 8);    /* Preferred BPP */          out_uint16_le(s, g_server_bpp); /* Preferred BPP */
480          out_uint16(s, 1);       /* Receive 1 BPP */          out_uint16_le(s, 1);    /* Receive 1 BPP */
481          out_uint16(s, 1);       /* Receive 4 BPP */          out_uint16_le(s, 1);    /* Receive 4 BPP */
482          out_uint16_le(s, 1);    /* Receive 8 BPP */          out_uint16_le(s, 1);    /* Receive 8 BPP */
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, 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 */
490          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
# Line 295  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] = (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] = (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 321  rdp_out_order_caps(STREAM s) Line 527  rdp_out_order_caps(STREAM s)
527          out_uint8p(s, order_caps, 32);  /* Orders supported */          out_uint8p(s, order_caps, 32);  /* Orders supported */
528          out_uint16_le(s, 0x6a1);        /* Text capability flags */          out_uint16_le(s, 0x6a1);        /* Text capability flags */
529          out_uint8s(s, 6);       /* Pad */          out_uint8s(s, 6);       /* Pad */
530          out_uint32(s, desktop_save == False ? 0 : 0x38400);     /* Desktop cache size */          out_uint32_le(s, g_desktop_save == False ? 0 : 0x38400);        /* Desktop cache size */
531          out_uint32(s, 0);       /* Unknown */          out_uint32(s, 0);       /* Unknown */
532          out_uint32(s, 0x4e4);   /* Unknown */          out_uint32_le(s, 0x4e4);        /* Unknown */
533  }  }
534    
535  /* Output bitmap cache capability set */  /* Output bitmap cache capability set */
536  static void  static void
537  rdp_out_bmpcache_caps(STREAM s)  rdp_out_bmpcache_caps(STREAM s)
538  {  {
539            int Bpp;
540          out_uint16_le(s, RDP_CAPSET_BMPCACHE);          out_uint16_le(s, RDP_CAPSET_BMPCACHE);
541          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
542    
543            Bpp = (g_server_bpp + 7) / 8;
544          out_uint8s(s, 24);      /* unused */          out_uint8s(s, 24);      /* unused */
545          out_uint16_le(s, 0x258);        /* entries */          out_uint16_le(s, 0x258);        /* entries */
546          out_uint16_le(s, 0x100);        /* max cell size */          out_uint16_le(s, 0x100 * Bpp);  /* max cell size */
547          out_uint16_le(s, 0x12c);        /* entries */          out_uint16_le(s, 0x12c);        /* entries */
548          out_uint16_le(s, 0x400);        /* max cell size */          out_uint16_le(s, 0x400 * Bpp);  /* max cell size */
549          out_uint16_le(s, 0x106);        /* entries */          out_uint16_le(s, 0x106);        /* entries */
550          out_uint16_le(s, 0x1000);       /* 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 */
# Line 401  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
648          0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,  };
649          0x10, 0x00, 0x34, 0x00, 0xFE,  
650          0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
651          0xFE, 0x00, 0x08, 0x00, 0xFE,  
652          0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,  static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
653          0xFE, 0x00, 0x80, 0x00, 0xFE,  
654          0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,  static uint8 caps_0x10[] = {
655          0x02, 0x00, 0x00, 0x00          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 set */  /* 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
674  /* Send a confirm active PDU */  /* Send a confirm active PDU */
675  static void  static void
676  rdp_send_confirm_active()  rdp_send_confirm_active(void)
677  {  {
678          STREAM s;          STREAM s;
679            uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
680          uint16 caplen =          uint16 caplen =
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                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
685                  + 4 /* w2k fix, why? */ ;                  0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
686                    4 /* w2k fix, why? */ ;
687    
688          s = rdp_init(14 + caplen + sizeof(RDP_SOURCE));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
689    
690          out_uint32_le(s, rdp_shareid);          out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
691            out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10));      /* Version 1 */
692            out_uint16_le(s, (g_mcs_userid + 1001));
693    
694            out_uint32_le(s, g_rdp_shareid);
695          out_uint16_le(s, 0x3ea);        /* userid */          out_uint16_le(s, 0x3ea);        /* userid */
696          out_uint16_le(s, sizeof(RDP_SOURCE));          out_uint16_le(s, sizeof(RDP_SOURCE));
697          out_uint16_le(s, caplen);          out_uint16_le(s, caplen);
# Line 459  rdp_send_confirm_active() Line 703  rdp_send_confirm_active()
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          rdp_send(s, RDP_PDU_CONFIRM_ACTIVE);          sec_send(s, sec_flags);
720    }
721    
722    /* Process a general capability set */
723    static void
724    rdp_process_general_caps(STREAM s)
725    {
726            uint16 pad2octetsB;     /* rdp5 flags? */
727    
728            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            in_uint16_le(s, ncapsets);
779            in_uint8s(s, 2);        /* pad */
780    
781            for (n = 0; n < ncapsets; n++)
782            {
783                    if (s->p > start + length)
784                            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                            case RDP_CAPSET_GENERAL:
794                                    rdp_process_general_caps(s);
795                                    break;
796    
797                            case RDP_CAPSET_BITMAP:
798                                    rdp_process_bitmap_caps(s);
799                                    break;
800                    }
801    
802                    s->p = next;
803            }
804  }  }
805    
806  /* Respond to a demand active PDU */  /* Respond to a demand active PDU */
# Line 476  static void Line 808  static void
808  process_demand_active(STREAM s)  process_demand_active(STREAM s)
809  {  {
810          uint8 type;          uint8 type;
811            uint16 len_src_descriptor, len_combined_caps;
812    
813          in_uint32_le(s, rdp_shareid);          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", 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 488  process_demand_active(STREAM s) Line 825  process_demand_active(STREAM s)
825          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
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, 0, 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    
845    /* Process a colour pointer PDU */
846    void
847    process_colour_pointer_pdu(STREAM s)
848    {
849            uint16 x, y, width, height, cache_idx, masklen, datalen;
850            uint8 *mask, *data;
851            HCURSOR cursor;
852    
853            in_uint16_le(s, cache_idx);
854            in_uint16_le(s, x);
855            in_uint16_le(s, y);
856            in_uint16_le(s, width);
857            in_uint16_le(s, height);
858            in_uint16_le(s, masklen);
859            in_uint16_le(s, datalen);
860            in_uint8p(s, data, datalen);
861            in_uint8p(s, mask, masklen);
862            cursor = ui_create_cursor(x, y, width, height, mask, data);
863            ui_set_cursor(cursor);
864            cache_put_cursor(cache_idx, cursor);
865    }
866    
867    /* Process a cached pointer PDU */
868    void
869    process_cached_pointer_pdu(STREAM s)
870    {
871            uint16 cache_idx;
872    
873            in_uint16_le(s, cache_idx);
874            ui_set_cursor(cache_get_cursor(cache_idx));
875    }
876    
877    /* Process a system pointer PDU */
878    void
879    process_system_pointer_pdu(STREAM s)
880    {
881            uint16 system_pointer_type;
882    
883            in_uint16(s, system_pointer_type);
884            switch (system_pointer_type)
885            {
886                    case RDP_NULL_POINTER:
887                            ui_set_null_cursor();
888                            break;
889    
890                    default:
891                            unimpl("System pointer message 0x%x\n", system_pointer_type);
892            }
893    }
894    
895  /* Process a pointer PDU */  /* Process a pointer PDU */
896  static void  static void
897  process_pointer_pdu(STREAM s)  process_pointer_pdu(STREAM s)
898  {  {
899          uint16 message_type;          uint16 message_type;
900          uint16 x, y, width, height, cache_idx, masklen, datalen;          uint16 x, y;
         uint8 *mask, *data;  
         HCURSOR cursor;  
901    
902          in_uint16_le(s, message_type);          in_uint16_le(s, message_type);
903          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
# Line 517  process_pointer_pdu(STREAM s) Line 912  process_pointer_pdu(STREAM s)
912                          break;                          break;
913    
914                  case RDP_POINTER_COLOR:                  case RDP_POINTER_COLOR:
915                          in_uint16_le(s, cache_idx);                          process_colour_pointer_pdu(s);
                         in_uint16_le(s, x);  
                         in_uint16_le(s, y);  
                         in_uint16_le(s, width);  
                         in_uint16_le(s, height);  
                         in_uint16_le(s, masklen);  
                         in_uint16_le(s, datalen);  
                         in_uint8p(s, data, datalen);  
                         in_uint8p(s, mask, masklen);  
                         cursor = ui_create_cursor(x, y, width, height, mask,  
                                                   data);  
                         ui_set_cursor(cursor);  
                         cache_put_cursor(cache_idx, cursor);  
916                          break;                          break;
917    
918                  case RDP_POINTER_CACHED:                  case RDP_POINTER_CACHED:
919                          in_uint16_le(s, cache_idx);                          process_cached_pointer_pdu(s);
920                          ui_set_cursor(cache_get_cursor(cache_idx));                          break;
921    
922                    case RDP_POINTER_SYSTEM:
923                            process_system_pointer_pdu(s);
924                          break;                          break;
925    
926                  default:                  default:
927                          DEBUG(("Pointer message 0x%x\n", message_type));                          unimpl("Pointer message 0x%x\n", message_type);
928          }          }
929  }  }
930    
931  /* Process bitmap updates */  /* Process bitmap updates */
932  static void  void
933  process_bitmap_updates(STREAM s)  process_bitmap_updates(STREAM s)
934  {  {
935          uint16 num_updates;          uint16 num_updates;
936          uint16 left, top, right, bottom, width, height;          uint16 left, top, right, bottom, width, height;
937          uint16 cx, cy, bpp, compress, bufsize, size;          uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
938          uint8 *data, *bmpdata;          uint8 *data, *bmpdata;
939          int i;          int i;
940    
# Line 563  process_bitmap_updates(STREAM s) Line 949  process_bitmap_updates(STREAM s)
949                  in_uint16_le(s, width);                  in_uint16_le(s, width);
950                  in_uint16_le(s, height);                  in_uint16_le(s, height);
951                  in_uint16_le(s, bpp);                  in_uint16_le(s, bpp);
952                    Bpp = (bpp + 7) / 8;
953                  in_uint16_le(s, compress);                  in_uint16_le(s, compress);
954                  in_uint16_le(s, bufsize);                  in_uint16_le(s, bufsize);
955    
956                  cx = right - left + 1;                  cx = right - left + 1;
957                  cy = bottom - top + 1;                  cy = bottom - top + 1;
958    
959                  DEBUG(("UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,cmp=%d)\n",                  DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
960                         left, top, right, bottom, width, height, compress));                         left, top, right, bottom, width, height, Bpp, compress));
961    
962                  if (!compress)                  if (!compress)
963                  {                  {
964                          int y;                          int y;
965                          bmpdata = xmalloc(width * height);                          bmpdata = (uint8 *) xmalloc(width * height * Bpp);
966                          for (y = 0; y < height; y++)                          for (y = 0; y < height; y++)
967                          {                          {
968                                  in_uint8a(s,                                  in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
969                                            &bmpdata[(height - y - 1) * width],                                            width * Bpp);
                                           width);  
970                          }                          }
971                          ui_paint_bitmap(left, top, cx, cy, width, height,                          ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
                                         bmpdata);  
972                          xfree(bmpdata);                          xfree(bmpdata);
973                          continue;                          continue;
974                  }                  }
975    
                 in_uint8s(s, 2);        /* pad */  
                 in_uint16_le(s, size);  
                 in_uint8s(s, 4);        /* line_size, final_size */  
                 in_uint8p(s, data, size);  
976    
977                  bmpdata = xmalloc(width * height);                  if (compress & 0x400)
978                  if (bitmap_decompress(bmpdata, width, height, data, size))                  {
979                            size = bufsize;
980                    }
981                    else
982                    {
983                            in_uint8s(s, 2);        /* pad */
984                            in_uint16_le(s, size);
985                            in_uint8s(s, 4);        /* line_size, final_size */
986                    }
987                    in_uint8p(s, data, size);
988                    bmpdata = (uint8 *) xmalloc(width * height * Bpp);
989                    if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
990                    {
991                            ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
992                    }
993                    else
994                  {                  {
995                          ui_paint_bitmap(left, top, cx, cy, width, height,                          DEBUG_RDP5(("Failed to decompress data\n"));
                                         bmpdata);  
996                  }                  }
997    
998                  xfree(bmpdata);                  xfree(bmpdata);
# Line 605  process_bitmap_updates(STREAM s) Line 1000  process_bitmap_updates(STREAM s)
1000  }  }
1001    
1002  /* Process a palette update */  /* Process a palette update */
1003  static void  void
1004  process_palette(STREAM s)  process_palette(STREAM s)
1005  {  {
1006          HCOLOURMAP hmap;          COLOURENTRY *entry;
1007          COLOURMAP map;          COLOURMAP map;
1008          uint8 *colours;          HCOLOURMAP hmap;
1009            int i;
1010    
1011          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
1012          in_uint16_le(s, map.ncolours);          in_uint16_le(s, map.ncolours);
1013          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
1014          in_uint8p(s, colours, (map.ncolours * 3));  
1015          map.colours = (COLOURENTRY *) colours;          map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
1016    
1017            DEBUG(("PALETTE(c=%d)\n", map.ncolours));
1018    
1019            for (i = 0; i < map.ncolours; i++)
1020            {
1021                    entry = &map.colours[i];
1022                    in_uint8(s, entry->red);
1023                    in_uint8(s, entry->green);
1024                    in_uint8(s, entry->blue);
1025            }
1026    
1027          hmap = ui_create_colourmap(&map);          hmap = ui_create_colourmap(&map);
1028          ui_set_colourmap(hmap);          ui_set_colourmap(hmap);
1029    
1030            xfree(map.colours);
1031  }  }
1032    
1033  /* Process an update PDU */  /* Process an update PDU */
1034  static void  static void
1035  process_update_pdu(STREAM s)  process_update_pdu(STREAM s)
1036  {  {
1037          uint16 update_type;          uint16 update_type, count;
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:
1045                          process_orders(s);                          in_uint8s(s, 2);        /* pad */
1046                            in_uint16_le(s, count);
1047                            in_uint8s(s, 2);        /* pad */
1048                            process_orders(s, count);
1049                          break;                          break;
1050    
1051                  case RDP_UPDATE_BITMAP:                  case RDP_UPDATE_BITMAP:
# Line 650  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;
1083            uint16 clen;
1084            uint32 len;
1085    
1086            uint32 roff, rlen;
1087    
1088          in_uint8s(s, 8);        /* shareid, pad, streamid, length */          struct stream *ns = &(g_mppc_dict.ns);
1089    
1090            in_uint8s(s, 6);        /* shareid, pad, streamid */
1091            in_uint16(s, len);
1092          in_uint8(s, data_pdu_type);          in_uint8(s, data_pdu_type);
1093          in_uint8s(s, 3);        /* compress_type, compress_len */          in_uint8(s, ctype);
1094            in_uint16(s, clen);
1095            clen -= 18;
1096    
1097            if (ctype & RDP_MPPC_COMPRESSED)
1098            {
1099                    if (len > RDP_MPPC_DICT_SIZE)
1100                            error("error decompressed packet size exceeds max\n");
1101                    if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1102                            error("error while decompressing packet\n");
1103    
1104                    //len -= 18;
1105    
1106                    /* allocate memory and copy the uncompressed data into the temporary stream */
1107                    ns->data = (uint8 *) xrealloc(ns->data, rlen);
1108    
1109                    memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
1110    
1111                    ns->size = rlen;
1112                    ns->end = (ns->data + ns->size);
1113                    ns->p = ns->data;
1114                    ns->rdp_hdr = ns->p;
1115    
1116                    s = ns;
1117            }
1118    
1119          switch (data_pdu_type)          switch (data_pdu_type)
1120          {          {
# Line 669  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 678  process_data_pdu(STREAM s) Line 1139  process_data_pdu(STREAM s)
1139                          break;                          break;
1140    
1141                  case RDP_DATA_PDU_LOGON:                  case RDP_DATA_PDU_LOGON:
1142                            DEBUG(("Received Logon PDU\n"));
1143                          /* User logged on */                          /* User logged on */
1144                          break;                          break;
1145    
1146                    case RDP_DATA_PDU_DISCONNECT:
1147                            process_disconnect_pdu(s, ext_disc_reason);
1148                            return True;
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  void
1159  rdp_main_loop()  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
1167    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"));
1187                                    *deactivated = 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;
1192                            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;
1202  }  }
1203    
1204  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */
# Line 719  BOOL Line 1206  BOOL
1206  rdp_connect(char *server, uint32 flags, char *domain, char *password,  rdp_connect(char *server, uint32 flags, char *domain, char *password,
1207              char *command, char *directory)              char *command, char *directory)
1208  {  {
1209          if (!sec_connect(server))          if (!sec_connect(server, g_username))
1210                  return False;                  return False;
1211    
1212          rdp_send_logon_info(flags, domain, username, password,          rdp_send_logon_info(flags, domain, g_username, password, command, directory);
                             command, directory);  
1213          return True;          return True;
1214  }  }
1215    
1216  /* Disconnect from the RDP layer */  /* Disconnect from the RDP layer */
1217  void  void
1218  rdp_disconnect()  rdp_disconnect(void)
1219  {  {
1220          sec_disconnect();          sec_disconnect();
1221  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26