/[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 340 by forsberg, Thu Mar 6 14:11:17 2003 UTC revision 831 by jdmeijer, Tue Mar 8 00:43:10 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-2002     Copyright (C) Matthew Chapman 1999-2005
5      
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
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_use_rdp5;
31  uint8 *next_packet;  extern uint16 g_server_rdp_version;
32  uint32 rdp_shareid;  extern uint32 g_rdp5_performanceflags;
33    extern int g_server_bpp;
34  #if WITH_DEBUG  extern int g_width;
35  static uint32 packetno;  extern int g_height;
36  #endif  extern BOOL g_bitmap_cache;
37    extern BOOL g_bitmap_cache_persist_enable;
 /* Initialise an RDP packet */  
 static STREAM  
 rdp_init(int maxlen)  
 {  
         STREAM s;  
38    
39          s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 6);  uint8 *g_next_packet;
40          s_push_layer(s, rdp_hdr, 6);  uint32 g_rdp_shareid;
41    
42          return s;  extern RDPCOMP g_mppc_dict;
 }  
43    
44  /* Send an RDP packet */  #if WITH_DEBUG
45  static void  static uint32 g_packetno;
46  rdp_send(STREAM s, uint8 pdu_type)  #endif
 {  
         uint16 length;  
   
         s_pop_layer(s, rdp_hdr);  
         length = s->end - s->p;  
   
         out_uint16_le(s, length);  
         out_uint16_le(s, (pdu_type | 0x10));    /* Version 1 */  
         out_uint16_le(s, (mcs_userid + 1001));  
   
         sec_send(s, encryption ? SEC_ENCRYPT : 0);  
 }  
47    
48  /* Receive an RDP packet */  /* Receive an RDP packet */
49  static STREAM  static STREAM
# Line 68  rdp_recv(uint8 * type) Line 51  rdp_recv(uint8 * type)
51  {  {
52          static STREAM rdp_s;          static STREAM rdp_s;
53          uint16 length, pdu_type;          uint16 length, pdu_type;
54            uint8 rdpver;
55    
56          if ((rdp_s == NULL) || (next_packet >= rdp_s->end))          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))
57          {          {
58                  rdp_s = sec_recv();                  rdp_s = sec_recv(&rdpver);
59                  if (rdp_s == NULL)                  if (rdp_s == NULL)
60                          return NULL;                          return NULL;
61                    if (rdpver == 0xff)
62                    {
63                            g_next_packet = rdp_s->end;
64                            *type = 0;
65                            return rdp_s;
66                    }
67                    else if (rdpver != 3)
68                    {
69                            /* rdp5_process should move g_next_packet ok */
70                            rdp5_process(rdp_s);
71                            *type = 0;
72                            return rdp_s;
73                    }
74    
75                  next_packet = rdp_s->p;                  g_next_packet = rdp_s->p;
76          }          }
77          else          else
78          {          {
79                  rdp_s->p = next_packet;                  rdp_s->p = g_next_packet;
80          }          }
81    
82          in_uint16_le(rdp_s, length);          in_uint16_le(rdp_s, length);
83          /* 32k packets are really 8, keepalive fix */          /* 32k packets are really 8, keepalive fix */
84          if (length == 0x8000)          if (length == 0x8000)
85          {          {
86                  next_packet += 8;                  g_next_packet += 8;
87                  *type = 0;                  *type = 0;
88                  return rdp_s;                  return rdp_s;
89          }          }
# Line 95  rdp_recv(uint8 * type) Line 92  rdp_recv(uint8 * type)
92          *type = pdu_type & 0xf;          *type = pdu_type & 0xf;
93    
94  #if WITH_DEBUG  #if WITH_DEBUG
95          DEBUG(("RDP packet #%d, (type %x):\n", ++packetno, *type));          DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type));
96          hexdump(next_packet, length);          hexdump(g_next_packet, length);
97  #endif /*  */  #endif /*  */
98    
99          next_packet += length;          g_next_packet += length;
100          return rdp_s;          return rdp_s;
101  }  }
102    
# Line 109  rdp_init_data(int maxlen) Line 106  rdp_init_data(int maxlen)
106  {  {
107          STREAM s;          STREAM s;
108    
109          s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 18);          s = sec_init(g_encryption ? SEC_ENCRYPT : 0, maxlen + 18);
110          s_push_layer(s, rdp_hdr, 18);          s_push_layer(s, rdp_hdr, 18);
111    
112          return s;          return s;
# Line 126  rdp_send_data(STREAM s, uint8 data_pdu_t Line 123  rdp_send_data(STREAM s, uint8 data_pdu_t
123    
124          out_uint16_le(s, length);          out_uint16_le(s, length);
125          out_uint16_le(s, (RDP_PDU_DATA | 0x10));          out_uint16_le(s, (RDP_PDU_DATA | 0x10));
126          out_uint16_le(s, (mcs_userid + 1001));          out_uint16_le(s, (g_mcs_userid + 1001));
127    
128          out_uint32_le(s, rdp_shareid);          out_uint32_le(s, g_rdp_shareid);
129          out_uint8(s, 0);        /* pad */          out_uint8(s, 0);        /* pad */
130          out_uint8(s, 1);        /* streamid */          out_uint8(s, 1);        /* streamid */
131          out_uint16_le(s, (length - 14));          out_uint16_le(s, (length - 14));
# Line 136  rdp_send_data(STREAM s, uint8 data_pdu_t Line 133  rdp_send_data(STREAM s, uint8 data_pdu_t
133          out_uint8(s, 0);        /* compress_type */          out_uint8(s, 0);        /* compress_type */
134          out_uint16(s, 0);       /* compress_len */          out_uint16(s, 0);       /* compress_len */
135    
136          sec_send(s, encryption ? SEC_ENCRYPT : 0);          sec_send(s, g_encryption ? SEC_ENCRYPT : 0);
137  }  }
138    
139  /* Output a string in Unicode */  /* Output a string in Unicode */
# Line 156  rdp_out_unistr(STREAM s, char *string, i Line 153  rdp_out_unistr(STREAM s, char *string, i
153          s->p += len;          s->p += len;
154  }  }
155    
156    /* Input a string in Unicode
157     *
158     * Returns str_len of string
159     */
160    int
161    rdp_in_unistr(STREAM s, char *string, int uni_len)
162    {
163            int i = 0;
164    
165            while (i < uni_len / 2)
166            {
167                    in_uint8a(s, &string[i++], 1);
168                    in_uint8s(s, 1);
169            }
170    
171            return i - 1;
172    }
173    
174    
175  /* Parse a logon info packet */  /* Parse a logon info packet */
176  static void  static void
177  rdp_send_logon_info(uint32 flags, char *domain, char *user,  rdp_send_logon_info(uint32 flags, char *domain, char *user,
178                      char *password, char *program, char *directory)                      char *password, char *program, char *directory)
179  {  {
180            char *ipaddr = tcp_get_address();
181          int len_domain = 2 * strlen(domain);          int len_domain = 2 * strlen(domain);
182          int len_user = 2 * strlen(user);          int len_user = 2 * strlen(user);
183          int len_password = 2 * strlen(password);          int len_password = 2 * strlen(password);
184          int len_program = 2 * strlen(program);          int len_program = 2 * strlen(program);
185          int len_directory = 2 * strlen(directory);          int len_directory = 2 * strlen(directory);
186          uint32 sec_flags = encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;          int len_ip = 2 * strlen(ipaddr);
187            int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
188            int packetlen = 0;
189            uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
190          STREAM s;          STREAM s;
191            time_t t = time(NULL);
192            time_t tzone;
193    
194    #if 0
195            /* enable rdp compression */
196            /* some problems still exist with rdp5 */
197            flags |= RDP_COMPRESSION;
198    #endif
199    
200            if (!g_use_rdp5 || 1 == g_server_rdp_version)
201            {
202                    DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
203    
204          s = sec_init(sec_flags, 18 + len_domain + len_user + len_password                  s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
205                       + len_program + len_directory + 10);                               + len_program + len_directory + 10);
206    
207          out_uint32(s, 0);                  out_uint32(s, 0);
208          out_uint32_le(s, flags);                  out_uint32_le(s, flags);
209          out_uint16_le(s, len_domain);                  out_uint16_le(s, len_domain);
210          out_uint16_le(s, len_user);                  out_uint16_le(s, len_user);
211          out_uint16_le(s, len_password);                  out_uint16_le(s, len_password);
212          out_uint16_le(s, len_program);                  out_uint16_le(s, len_program);
213          out_uint16_le(s, len_directory);                  out_uint16_le(s, len_directory);
214          rdp_out_unistr(s, domain, len_domain);                  rdp_out_unistr(s, domain, len_domain);
215          rdp_out_unistr(s, user, len_user);                  rdp_out_unistr(s, user, len_user);
216          rdp_out_unistr(s, password, len_password);                  rdp_out_unistr(s, password, len_password);
217          rdp_out_unistr(s, program, len_program);                  rdp_out_unistr(s, program, len_program);
218          rdp_out_unistr(s, directory, len_directory);                  rdp_out_unistr(s, directory, len_directory);
219            }
220            else
221            {
222    
223                    flags |= RDP_LOGON_BLOB;
224                    DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
225                    packetlen = 4 + /* Unknown uint32 */
226                            4 +     /* flags */
227                            2 +     /* len_domain */
228                            2 +     /* len_user */
229                            (flags & RDP_LOGON_AUTO ? 2 : 0) +      /* len_password */
230                            (flags & RDP_LOGON_BLOB ? 2 : 0) +      /* Length of BLOB */
231                            2 +     /* len_program */
232                            2 +     /* len_directory */
233                            (0 < len_domain ? len_domain : 2) +     /* domain */
234                            len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 +    /* We have no 512 byte BLOB. Perhaps we must? */
235                            (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + /* After the BLOB is a unknown int16. If there is a BLOB, that is. */
236                            (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 +     /* Unknown (2) */
237                            2 +     /* Client ip length */
238                            len_ip +        /* Client ip */
239                            2 +     /* DLL string length */
240                            len_dll +       /* DLL string */
241                            2 +     /* Unknown */
242                            2 +     /* Unknown */
243                            64 +    /* Time zone #0 */
244                            2 +     /* Unknown */
245                            64 +    /* Time zone #1 */
246                            32;     /* Unknown */
247    
248                    s = sec_init(sec_flags, packetlen);
249                    DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
250    
251                    out_uint32(s, 0);       /* Unknown */
252                    out_uint32_le(s, flags);
253                    out_uint16_le(s, len_domain);
254                    out_uint16_le(s, len_user);
255                    if (flags & RDP_LOGON_AUTO)
256                    {
257                            out_uint16_le(s, len_password);
258    
259                    }
260                    if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
261                    {
262                            out_uint16_le(s, 0);
263                    }
264                    out_uint16_le(s, len_program);
265                    out_uint16_le(s, len_directory);
266                    if (0 < len_domain)
267                            rdp_out_unistr(s, domain, len_domain);
268                    else
269                            out_uint16_le(s, 0);
270                    rdp_out_unistr(s, user, len_user);
271                    if (flags & RDP_LOGON_AUTO)
272                    {
273                            rdp_out_unistr(s, password, len_password);
274                    }
275                    if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
276                    {
277                            out_uint16_le(s, 0);
278                    }
279                    if (0 < len_program)
280                    {
281                            rdp_out_unistr(s, program, len_program);
282    
283                    }
284                    else
285                    {
286                            out_uint16_le(s, 0);
287                    }
288                    if (0 < len_directory)
289                    {
290                            rdp_out_unistr(s, directory, len_directory);
291                    }
292                    else
293                    {
294                            out_uint16_le(s, 0);
295                    }
296                    out_uint16_le(s, 2);
297                    out_uint16_le(s, len_ip + 2);   /* Length of client ip */
298                    rdp_out_unistr(s, ipaddr, len_ip);
299                    out_uint16_le(s, len_dll + 2);
300                    rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
301    
302                    tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
303                    out_uint32_le(s, tzone);
304    
305                    rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
306                    out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
307    
308                    out_uint32_le(s, 0x0a0000);
309                    out_uint32_le(s, 0x050000);
310                    out_uint32_le(s, 3);
311                    out_uint32_le(s, 0);
312                    out_uint32_le(s, 0);
313    
314                    rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
315                    out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
316    
317                    out_uint32_le(s, 0x30000);
318                    out_uint32_le(s, 0x050000);
319                    out_uint32_le(s, 2);
320                    out_uint32(s, 0);
321                    out_uint32_le(s, 0xffffffc4);
322                    out_uint32_le(s, 0xfffffffe);
323                    out_uint32_le(s, g_rdp5_performanceflags);
324                    out_uint32(s, 0);
325    
326    
327            }
328          s_mark_end(s);          s_mark_end(s);
329          sec_send(s, sec_flags);          sec_send(s, sec_flags);
330  }  }
# Line 241  rdp_send_input(uint32 time, uint16 messa Line 381  rdp_send_input(uint32 time, uint16 messa
381          rdp_send_data(s, RDP_DATA_PDU_INPUT);          rdp_send_data(s, RDP_DATA_PDU_INPUT);
382  }  }
383    
384    /* Inform the server on the contents of the persistent bitmap cache */
385    static void
386    rdp_enum_bmpcache2(void)
387    {
388            STREAM s;
389            HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS];
390            uint32 num_keys, offset, count, flags;
391    
392            offset = 0;
393            num_keys = pstcache_enumerate(2, keylist);
394    
395            while (offset < num_keys)
396            {
397                    count = MIN(num_keys - offset, 169);
398    
399                    s = rdp_init_data(24 + count * sizeof(HASH_KEY));
400    
401                    flags = 0;
402                    if (offset == 0)
403                            flags |= PDU_FLAG_FIRST;
404                    if (num_keys - offset <= 169)
405                            flags |= PDU_FLAG_LAST;
406    
407                    /* header */
408                    out_uint32_le(s, 0);
409                    out_uint16_le(s, count);
410                    out_uint16_le(s, 0);
411                    out_uint16_le(s, 0);
412                    out_uint16_le(s, 0);
413                    out_uint16_le(s, 0);
414                    out_uint16_le(s, num_keys);
415                    out_uint32_le(s, 0);
416                    out_uint32_le(s, flags);
417    
418                    /* list */
419                    out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
420    
421                    s_mark_end(s);
422                    rdp_send_data(s, 0x2b);
423    
424                    offset += 169;
425            }
426    }
427    
428  /* Send an (empty) font information PDU */  /* Send an (empty) font information PDU */
429  static void  static void
430  rdp_send_fonts(uint16 seq)  rdp_send_fonts(uint16 seq)
# Line 250  rdp_send_fonts(uint16 seq) Line 434  rdp_send_fonts(uint16 seq)
434          s = rdp_init_data(8);          s = rdp_init_data(8);
435    
436          out_uint16(s, 0);       /* number of fonts */          out_uint16(s, 0);       /* number of fonts */
437          out_uint16_le(s, 0x3e); /* unknown */          out_uint16_le(s, 0);    /* pad? */
438          out_uint16_le(s, seq);  /* unknown */          out_uint16_le(s, seq);  /* unknown */
439          out_uint16_le(s, 0x32); /* entry size */          out_uint16_le(s, 0x32); /* entry size */
440    
# Line 270  rdp_out_general_caps(STREAM s) Line 454  rdp_out_general_caps(STREAM s)
454          out_uint16_le(s, 0x200);        /* Protocol version */          out_uint16_le(s, 0x200);        /* Protocol version */
455          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
456          out_uint16(s, 0);       /* Compression types */          out_uint16(s, 0);       /* Compression types */
457          out_uint16(s, 0);       /* Pad */          out_uint16_le(s, g_use_rdp5 ? 0x40d : 0);
458            /* Pad, according to T.128. 0x40d seems to
459               trigger
460               the server to start sending RDP5 packets.
461               However, the value is 0x1d04 with W2KTSK and
462               NT4MS. Hmm.. Anyway, thankyou, Microsoft,
463               for sending such information in a padding
464               field.. */
465          out_uint16(s, 0);       /* Update capability */          out_uint16(s, 0);       /* Update capability */
466          out_uint16(s, 0);       /* Remote unshare capability */          out_uint16(s, 0);       /* Remote unshare capability */
467          out_uint16(s, 0);       /* Compression level */          out_uint16(s, 0);       /* Compression level */
# Line 284  rdp_out_bitmap_caps(STREAM s) Line 475  rdp_out_bitmap_caps(STREAM s)
475          out_uint16_le(s, RDP_CAPSET_BITMAP);          out_uint16_le(s, RDP_CAPSET_BITMAP);
476          out_uint16_le(s, RDP_CAPLEN_BITMAP);          out_uint16_le(s, RDP_CAPLEN_BITMAP);
477    
478          out_uint16_le(s, 8);    /* Preferred BPP */          out_uint16_le(s, g_server_bpp); /* Preferred BPP */
479          out_uint16_le(s, 1);    /* Receive 1 BPP */          out_uint16_le(s, 1);    /* Receive 1 BPP */
480          out_uint16_le(s, 1);    /* Receive 4 BPP */          out_uint16_le(s, 1);    /* Receive 4 BPP */
481          out_uint16_le(s, 1);    /* Receive 8 BPP */          out_uint16_le(s, 1);    /* Receive 8 BPP */
482          out_uint16_le(s, 800);  /* Desktop width */          out_uint16_le(s, 800);  /* Desktop width */
483          out_uint16_le(s, 600);  /* Desktop height */          out_uint16_le(s, 600);  /* Desktop height */
484          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
485          out_uint16(s, 0);       /* Allow resize */          out_uint16(s, 1);       /* Allow resize */
486          out_uint16_le(s, bitmap_compression ? 1 : 0);   /* Support compression */          out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
487          out_uint16(s, 0);       /* Unknown */          out_uint16(s, 0);       /* Unknown */
488          out_uint16_le(s, 1);    /* Unknown */          out_uint16_le(s, 1);    /* Unknown */
489          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
# Line 304  rdp_out_order_caps(STREAM s) Line 495  rdp_out_order_caps(STREAM s)
495  {  {
496          uint8 order_caps[32];          uint8 order_caps[32];
497    
   
498          memset(order_caps, 0, 32);          memset(order_caps, 0, 32);
499          order_caps[0] = 1;      /* dest blt */          order_caps[0] = 1;      /* dest blt */
500          order_caps[1] = 1;      /* pat blt */          order_caps[1] = 1;      /* pat blt */
501          order_caps[2] = 1;      /* screen blt */          order_caps[2] = 1;      /* screen blt */
502          order_caps[3] = 1;      /* required for memblt? */          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
503            order_caps[4] = 0;      /* triblt */
504          order_caps[8] = 1;      /* line */          order_caps[8] = 1;      /* line */
505          order_caps[9] = 1;      /* line */          order_caps[9] = 1;      /* line */
506          order_caps[10] = 1;     /* rect */          order_caps[10] = 1;     /* rect */
507          order_caps[11] = (desktop_save == False ? 0 : 1);       /* desksave */          order_caps[11] = (g_desktop_save == False ? 0 : 1);     /* desksave */
508          order_caps[13] = 1;     /* memblt */          order_caps[13] = 1;     /* memblt */
509          order_caps[14] = 1;     /* triblt */          order_caps[14] = 1;     /* triblt */
510            order_caps[20] = 1;     /* polygon */
511            order_caps[21] = 1;     /* polygon2 */
512          order_caps[22] = 1;     /* polyline */          order_caps[22] = 1;     /* polyline */
513            order_caps[25] = 1;     /* ellipse */
514            order_caps[26] = 1;     /* ellipse2 */
515          order_caps[27] = 1;     /* text2 */          order_caps[27] = 1;     /* text2 */
516          out_uint16_le(s, RDP_CAPSET_ORDER);          out_uint16_le(s, RDP_CAPSET_ORDER);
517          out_uint16_le(s, RDP_CAPLEN_ORDER);          out_uint16_le(s, RDP_CAPLEN_ORDER);
# Line 331  rdp_out_order_caps(STREAM s) Line 526  rdp_out_order_caps(STREAM s)
526          out_uint8p(s, order_caps, 32);  /* Orders supported */          out_uint8p(s, order_caps, 32);  /* Orders supported */
527          out_uint16_le(s, 0x6a1);        /* Text capability flags */          out_uint16_le(s, 0x6a1);        /* Text capability flags */
528          out_uint8s(s, 6);       /* Pad */          out_uint8s(s, 6);       /* Pad */
529          out_uint32_le(s, desktop_save == False ? 0 : 0x38400);  /* Desktop cache size */          out_uint32_le(s, g_desktop_save == False ? 0 : 0x38400);        /* Desktop cache size */
530          out_uint32(s, 0);       /* Unknown */          out_uint32(s, 0);       /* Unknown */
531          out_uint32_le(s, 0x4e4);        /* Unknown */          out_uint32_le(s, 0x4e4);        /* Unknown */
532  }  }
# Line 340  rdp_out_order_caps(STREAM s) Line 535  rdp_out_order_caps(STREAM s)
535  static void  static void
536  rdp_out_bmpcache_caps(STREAM s)  rdp_out_bmpcache_caps(STREAM s)
537  {  {
538            int Bpp;
539          out_uint16_le(s, RDP_CAPSET_BMPCACHE);          out_uint16_le(s, RDP_CAPSET_BMPCACHE);
540          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
541    
542            Bpp = (g_server_bpp + 7) / 8;
543          out_uint8s(s, 24);      /* unused */          out_uint8s(s, 24);      /* unused */
544          out_uint16_le(s, 0x258);        /* entries */          out_uint16_le(s, 0x258);        /* entries */
545          out_uint16_le(s, 0x100);        /* max cell size */          out_uint16_le(s, 0x100 * Bpp);  /* max cell size */
546          out_uint16_le(s, 0x12c);        /* entries */          out_uint16_le(s, 0x12c);        /* entries */
547          out_uint16_le(s, 0x400);        /* max cell size */          out_uint16_le(s, 0x400 * Bpp);  /* max cell size */
548          out_uint16_le(s, 0x106);        /* entries */          out_uint16_le(s, 0x106);        /* entries */
549          out_uint16_le(s, 0x1000);       /* max cell size */          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
550    }
551    
552    /* Output bitmap cache v2 capability set */
553    static void
554    rdp_out_bmpcache2_caps(STREAM s)
555    {
556            out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
557            out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
558    
559            out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
560    
561            out_uint16_le(s, 0x0300);       /* flags? number of caches? */
562    
563            out_uint32_le(s, BMPCACHE2_C0_CELLS);
564            out_uint32_le(s, BMPCACHE2_C1_CELLS);
565            if (pstcache_init(2))
566            {
567                    out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
568            }
569            else
570            {
571                    out_uint32_le(s, BMPCACHE2_C2_CELLS);
572            }
573            out_uint8s(s, 20);      /* other bitmap caches not used */
574  }  }
575    
576  /* Output control capability set */  /* Output control capability set */
# Line 411  rdp_out_colcache_caps(STREAM s) Line 632  rdp_out_colcache_caps(STREAM s)
632          out_uint16(s, 0);       /* pad */          out_uint16(s, 0);       /* pad */
633  }  }
634    
635  static uint8 canned_caps[] = {  static uint8 caps_0x0d[] = {
636          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
637          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
638          0x00, 0x00, 0x00, 0x00, 0x00,          0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
639          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
640          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
641          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
642          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
643          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
644          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
645          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
646          0x0C, 0x00, 0x08, 0x00, 0x01,          0x00, 0x00, 0x00, 0x00
647          0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,  };
648          0x10, 0x00, 0x34, 0x00, 0xFE,  
649          0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
650          0xFE, 0x00, 0x08, 0x00, 0xFE,  
651          0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,  static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
652          0xFE, 0x00, 0x80, 0x00, 0xFE,  
653          0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,  static uint8 caps_0x10[] = {
654          0x02, 0x00, 0x00, 0x00          0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
655            0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
656            0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
657            0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
658            0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
659            0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
660  };  };
661    
662  /* Output unknown capability set */  /* Output unknown capability sets */
663  static void  static void
664  rdp_out_unknown_caps(STREAM s)  rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
665  {  {
666          out_uint16_le(s, RDP_CAPSET_UNKNOWN);          out_uint16_le(s, id);
667          out_uint16_le(s, 0x58);          out_uint16_le(s, length);
668    
669          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);          out_uint8p(s, caps, length - 4);
670  }  }
671    
672    #define RDP5_FLAG 0x0030
673  /* Send a confirm active PDU */  /* Send a confirm active PDU */
674  static void  static void
675  rdp_send_confirm_active(void)  rdp_send_confirm_active(void)
676  {  {
677          STREAM s;          STREAM s;
678            uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
679          uint16 caplen =          uint16 caplen =
680                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
681                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
682                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
683                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
684                    0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
685                    4 /* w2k fix, why? */ ;
686    
687            s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
688    
689          s = rdp_init(14 + caplen + sizeof(RDP_SOURCE));          out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
690            out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10));      /* Version 1 */
691            out_uint16_le(s, (g_mcs_userid + 1001));
692    
693          out_uint32_le(s, rdp_shareid);          out_uint32_le(s, g_rdp_shareid);
694          out_uint16_le(s, 0x3ea);        /* userid */          out_uint16_le(s, 0x3ea);        /* userid */
695          out_uint16_le(s, sizeof(RDP_SOURCE));          out_uint16_le(s, sizeof(RDP_SOURCE));
696          out_uint16_le(s, caplen);          out_uint16_le(s, caplen);
# Line 468  rdp_send_confirm_active(void) Line 702  rdp_send_confirm_active(void)
702          rdp_out_general_caps(s);          rdp_out_general_caps(s);
703          rdp_out_bitmap_caps(s);          rdp_out_bitmap_caps(s);
704          rdp_out_order_caps(s);          rdp_out_order_caps(s);
705          rdp_out_bmpcache_caps(s);          g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
706          rdp_out_colcache_caps(s);          rdp_out_colcache_caps(s);
707          rdp_out_activate_caps(s);          rdp_out_activate_caps(s);
708          rdp_out_control_caps(s);          rdp_out_control_caps(s);
709          rdp_out_pointer_caps(s);          rdp_out_pointer_caps(s);
710          rdp_out_share_caps(s);          rdp_out_share_caps(s);
711          rdp_out_unknown_caps(s);  
712            rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
713            rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
714            rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
715            rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
716    
717          s_mark_end(s);          s_mark_end(s);
718          rdp_send(s, RDP_PDU_CONFIRM_ACTIVE);          sec_send(s, sec_flags);
719    }
720    
721    /* Process a general capability set */
722    static void
723    rdp_process_general_caps(STREAM s)
724    {
725            uint16 pad2octetsB;     /* rdp5 flags? */
726    
727            in_uint8s(s, 10);
728            in_uint16_le(s, pad2octetsB);
729    
730            if (!pad2octetsB)
731                    g_use_rdp5 = False;
732    }
733    
734    /* Process a bitmap capability set */
735    static void
736    rdp_process_bitmap_caps(STREAM s)
737    {
738            uint16 width, height, bpp;
739    
740            in_uint16_le(s, bpp);
741            in_uint8s(s, 6);
742    
743            in_uint16_le(s, width);
744            in_uint16_le(s, height);
745    
746            DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));
747    
748            /*
749             * The server may limit bpp and change the size of the desktop (for
750             * example when shadowing another session).
751             */
752            if (g_server_bpp != bpp)
753            {
754                    warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
755                    g_server_bpp = bpp;
756            }
757            if (g_width != width || g_height != height)
758            {
759                    warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
760                            width, height);
761                    g_width = width;
762                    g_height = height;
763                    ui_resize_window();
764            }
765    }
766    
767    /* Process server capabilities */
768    void
769    rdp_process_server_caps(STREAM s, uint16 length)
770    {
771            int n;
772            uint8 *next, *start;
773            uint16 ncapsets, capset_type, capset_length;
774    
775            start = s->p;
776    
777            in_uint16_le(s, ncapsets);
778            in_uint8s(s, 2);        /* pad */
779    
780            for (n = 0; n < ncapsets; n++)
781            {
782                    if (s->p > start + length)
783                            return;
784    
785                    in_uint16_le(s, capset_type);
786                    in_uint16_le(s, capset_length);
787    
788                    next = s->p + capset_length - 4;
789    
790                    switch (capset_type)
791                    {
792                            case RDP_CAPSET_GENERAL:
793                                    rdp_process_general_caps(s);
794                                    break;
795    
796                            case RDP_CAPSET_BITMAP:
797                                    rdp_process_bitmap_caps(s);
798                                    break;
799                    }
800    
801                    s->p = next;
802            }
803  }  }
804    
805  /* Respond to a demand active PDU */  /* Respond to a demand active PDU */
# Line 485  static void Line 807  static void
807  process_demand_active(STREAM s)  process_demand_active(STREAM s)
808  {  {
809          uint8 type;          uint8 type;
810            uint16 len_src_descriptor, len_combined_caps;
811    
812          in_uint32_le(s, rdp_shareid);          in_uint32_le(s, g_rdp_shareid);
813            in_uint16_le(s, len_src_descriptor);
814            in_uint16_le(s, len_combined_caps);
815            in_uint8s(s, len_src_descriptor);
816    
817          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", rdp_shareid));          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
818            rdp_process_server_caps(s, len_combined_caps);
819    
820          rdp_send_confirm_active();          rdp_send_confirm_active();
821          rdp_send_synchronise();          rdp_send_synchronise();
# Line 497  process_demand_active(STREAM s) Line 824  process_demand_active(STREAM s)
824          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
825          rdp_recv(&type);        /* RDP_CTL_COOPERATE */          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
826          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
827          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, 0, 0);          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);
828          rdp_send_fonts(1);  
829          rdp_send_fonts(2);          if (g_use_rdp5)
830          rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 */          {
831                    rdp_enum_bmpcache2();
832                    rdp_send_fonts(3);
833            }
834            else
835            {
836                    rdp_send_fonts(1);
837                    rdp_send_fonts(2);
838            }
839    
840            rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
841          reset_order_state();          reset_order_state();
842  }  }
843    
844    /* Process a colour pointer PDU */
845    void
846    process_colour_pointer_pdu(STREAM s)
847    {
848            uint16 x, y, width, height, cache_idx, masklen, datalen;
849            uint8 *mask, *data;
850            HCURSOR cursor;
851    
852            in_uint16_le(s, cache_idx);
853            in_uint16_le(s, x);
854            in_uint16_le(s, y);
855            in_uint16_le(s, width);
856            in_uint16_le(s, height);
857            in_uint16_le(s, masklen);
858            in_uint16_le(s, datalen);
859            in_uint8p(s, data, datalen);
860            in_uint8p(s, mask, masklen);
861            cursor = ui_create_cursor(x, y, width, height, mask, data);
862            ui_set_cursor(cursor);
863            cache_put_cursor(cache_idx, cursor);
864    }
865    
866    /* Process a cached pointer PDU */
867    void
868    process_cached_pointer_pdu(STREAM s)
869    {
870            uint16 cache_idx;
871    
872            in_uint16_le(s, cache_idx);
873            ui_set_cursor(cache_get_cursor(cache_idx));
874    }
875    
876    /* Process a system pointer PDU */
877    void
878    process_system_pointer_pdu(STREAM s)
879    {
880            uint16 system_pointer_type;
881    
882            in_uint16(s, system_pointer_type);
883            switch (system_pointer_type)
884            {
885                    case RDP_NULL_POINTER:
886                            ui_set_null_cursor();
887                            break;
888    
889                    default:
890                            unimpl("System pointer message 0x%x\n", system_pointer_type);
891            }
892    }
893    
894  /* Process a pointer PDU */  /* Process a pointer PDU */
895  static void  static void
896  process_pointer_pdu(STREAM s)  process_pointer_pdu(STREAM s)
897  {  {
898          uint16 message_type;          uint16 message_type;
899          uint16 x, y, width, height, cache_idx, masklen, datalen;          uint16 x, y;
         uint8 *mask, *data;  
         HCURSOR cursor;  
900    
901          in_uint16_le(s, message_type);          in_uint16_le(s, message_type);
902          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
# Line 526  process_pointer_pdu(STREAM s) Line 911  process_pointer_pdu(STREAM s)
911                          break;                          break;
912    
913                  case RDP_POINTER_COLOR:                  case RDP_POINTER_COLOR:
914                          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);  
915                          break;                          break;
916    
917                  case RDP_POINTER_CACHED:                  case RDP_POINTER_CACHED:
918                          in_uint16_le(s, cache_idx);                          process_cached_pointer_pdu(s);
919                          ui_set_cursor(cache_get_cursor(cache_idx));                          break;
920    
921                    case RDP_POINTER_SYSTEM:
922                            process_system_pointer_pdu(s);
923                          break;                          break;
924    
925                  default:                  default:
926                          DEBUG(("Pointer message 0x%x\n", message_type));                          unimpl("Pointer message 0x%x\n", message_type);
927          }          }
928  }  }
929    
930  /* Process bitmap updates */  /* Process bitmap updates */
931  static void  void
932  process_bitmap_updates(STREAM s)  process_bitmap_updates(STREAM s)
933  {  {
934          uint16 num_updates;          uint16 num_updates;
# Line 578  process_bitmap_updates(STREAM s) Line 955  process_bitmap_updates(STREAM s)
955                  cx = right - left + 1;                  cx = right - left + 1;
956                  cy = bottom - top + 1;                  cy = bottom - top + 1;
957    
958                  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",
959                         left, top, right, bottom, width, height, compress));                         left, top, right, bottom, width, height, Bpp, compress));
960    
961                  if (!compress)                  if (!compress)
962                  {                  {
963                          int y;                          int y;
964                          bmpdata = xmalloc(width * height * Bpp);                          bmpdata = (uint8 *) xmalloc(width * height * Bpp);
965                          for (y = 0; y < height; y++)                          for (y = 0; y < height; y++)
966                          {                          {
967                                  in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],                                  in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
# Line 595  process_bitmap_updates(STREAM s) Line 972  process_bitmap_updates(STREAM s)
972                          continue;                          continue;
973                  }                  }
974    
975                  in_uint8s(s, 2);        /* pad */  
976                  in_uint16_le(s, size);                  if (compress & 0x400)
977                  in_uint8s(s, 4);        /* line_size, final_size */                  {
978                            size = bufsize;
979                    }
980                    else
981                    {
982                            in_uint8s(s, 2);        /* pad */
983                            in_uint16_le(s, size);
984                            in_uint8s(s, 4);        /* line_size, final_size */
985                    }
986                  in_uint8p(s, data, size);                  in_uint8p(s, data, size);
987                  bmpdata = xmalloc(width * height * Bpp);                  bmpdata = (uint8 *) xmalloc(width * height * Bpp);
988                  if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))                  if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
989                  {                  {
990                          ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);                          ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
991                  }                  }
992                    else
993                    {
994                            DEBUG_RDP5(("Failed to decompress data\n"));
995                    }
996    
997                  xfree(bmpdata);                  xfree(bmpdata);
998          }          }
999  }  }
1000    
1001  /* Process a palette update */  /* Process a palette update */
1002  static void  void
1003  process_palette(STREAM s)  process_palette(STREAM s)
1004  {  {
1005          COLOURENTRY *entry;          COLOURENTRY *entry;
# Line 621  process_palette(STREAM s) Line 1011  process_palette(STREAM s)
1011          in_uint16_le(s, map.ncolours);          in_uint16_le(s, map.ncolours);
1012          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
1013    
1014          map.colours = xmalloc(3 * map.ncolours);          map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
1015    
1016            DEBUG(("PALETTE(c=%d)\n", map.ncolours));
1017    
1018          for (i = 0; i < map.ncolours; i++)          for (i = 0; i < map.ncolours; i++)
1019          {          {
# Line 641  process_palette(STREAM s) Line 1033  process_palette(STREAM s)
1033  static void  static void
1034  process_update_pdu(STREAM s)  process_update_pdu(STREAM s)
1035  {  {
1036          uint16 update_type;          uint16 update_type, count;
1037    
1038          in_uint16_le(s, update_type);          in_uint16_le(s, update_type);
1039    
1040            ui_begin_update();
1041          switch (update_type)          switch (update_type)
1042          {          {
1043                  case RDP_UPDATE_ORDERS:                  case RDP_UPDATE_ORDERS:
1044                          process_orders(s);                          in_uint8s(s, 2);        /* pad */
1045                            in_uint16_le(s, count);
1046                            in_uint8s(s, 2);        /* pad */
1047                            process_orders(s, count);
1048                          break;                          break;
1049    
1050                  case RDP_UPDATE_BITMAP:                  case RDP_UPDATE_BITMAP:
# Line 665  process_update_pdu(STREAM s) Line 1061  process_update_pdu(STREAM s)
1061                  default:                  default:
1062                          unimpl("update %d\n", update_type);                          unimpl("update %d\n", update_type);
1063          }          }
1064            ui_end_update();
1065    }
1066    
1067    /* Process a disconnect PDU */
1068    void
1069    process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
1070    {
1071            in_uint32_le(s, *ext_disc_reason);
1072    
1073            DEBUG(("Received disconnect PDU\n"));
1074  }  }
1075    
1076  /* Process data PDU */  /* Process data PDU */
1077  static void  static BOOL
1078  process_data_pdu(STREAM s)  process_data_pdu(STREAM s, uint32 * ext_disc_reason)
1079  {  {
1080          uint8 data_pdu_type;          uint8 data_pdu_type;
1081            uint8 ctype;
1082            uint16 clen;
1083            uint32 len;
1084    
1085            uint32 roff, rlen;
1086    
1087            struct stream *ns = &(g_mppc_dict.ns);
1088    
1089          in_uint8s(s, 8);        /* shareid, pad, streamid, length */          in_uint8s(s, 6);        /* shareid, pad, streamid */
1090            in_uint16(s, len);
1091          in_uint8(s, data_pdu_type);          in_uint8(s, data_pdu_type);
1092          in_uint8s(s, 3);        /* compress_type, compress_len */          in_uint8(s, ctype);
1093            in_uint16(s, clen);
1094            clen -= 18;
1095    
1096            if (ctype & RDP_MPPC_COMPRESSED)
1097            {
1098                    if (len > RDP_MPPC_DICT_SIZE)
1099                            error("error decompressed packet size exceeds max\n");
1100                    if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1101                            error("error while decompressing packet\n");
1102    
1103                    //len -= 18;
1104    
1105                    /* allocate memory and copy the uncompressed data into the temporary stream */
1106                    ns->data = (uint8 *) xrealloc(ns->data, rlen);
1107    
1108                    memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
1109    
1110                    ns->size = rlen;
1111                    ns->end = (ns->data + ns->size);
1112                    ns->p = ns->data;
1113                    ns->rdp_hdr = ns->p;
1114    
1115                    s = ns;
1116            }
1117    
1118          switch (data_pdu_type)          switch (data_pdu_type)
1119          {          {
# Line 684  process_data_pdu(STREAM s) Line 1121  process_data_pdu(STREAM s)
1121                          process_update_pdu(s);                          process_update_pdu(s);
1122                          break;                          break;
1123    
1124                    case RDP_DATA_PDU_CONTROL:
1125                            DEBUG(("Received Control PDU\n"));
1126                            break;
1127    
1128                    case RDP_DATA_PDU_SYNCHRONISE:
1129                            DEBUG(("Received Sync PDU\n"));
1130                            break;
1131    
1132                  case RDP_DATA_PDU_POINTER:                  case RDP_DATA_PDU_POINTER:
1133                          process_pointer_pdu(s);                          process_pointer_pdu(s);
1134                          break;                          break;
# Line 693  process_data_pdu(STREAM s) Line 1138  process_data_pdu(STREAM s)
1138                          break;                          break;
1139    
1140                  case RDP_DATA_PDU_LOGON:                  case RDP_DATA_PDU_LOGON:
1141                            DEBUG(("Received Logon PDU\n"));
1142                          /* User logged on */                          /* User logged on */
1143                          break;                          break;
1144    
1145                    case RDP_DATA_PDU_DISCONNECT:
1146                            process_disconnect_pdu(s, ext_disc_reason);
1147                            return True;
1148    
1149                  default:                  default:
1150                          unimpl("data PDU %d\n", data_pdu_type);                          unimpl("data PDU %d\n", data_pdu_type);
1151          }          }
1152            return False;
1153  }  }
1154    
1155  /* Process incoming packets */  /* Process incoming packets */
1156    /* nevers gets out of here till app is done */
1157  void  void
1158  rdp_main_loop(void)  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1159    {
1160            while (rdp_loop(deactivated, ext_disc_reason))
1161                    ;
1162    }
1163    
1164    /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1165    BOOL
1166    rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1167  {  {
1168          uint8 type;          uint8 type;
1169            BOOL disc = False;      /* True when a disconnect PDU was received */
1170            BOOL cont = True;
1171          STREAM s;          STREAM s;
1172    
1173          while ((s = rdp_recv(&type)) != NULL)          while (cont)
1174          {          {
1175                    s = rdp_recv(&type);
1176                    if (s == NULL)
1177                            return False;
1178                  switch (type)                  switch (type)
1179                  {                  {
1180                          case RDP_PDU_DEMAND_ACTIVE:                          case RDP_PDU_DEMAND_ACTIVE:
1181                                  process_demand_active(s);                                  process_demand_active(s);
1182                                    *deactivated = False;
1183                                  break;                                  break;
   
1184                          case RDP_PDU_DEACTIVATE:                          case RDP_PDU_DEACTIVATE:
1185                                    DEBUG(("RDP_PDU_DEACTIVATE\n"));
1186                                    *deactivated = True;
1187                                  break;                                  break;
   
1188                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1189                                  process_data_pdu(s);                                  disc = process_data_pdu(s, ext_disc_reason);
1190                                  break;                                  break;
   
1191                          case 0:                          case 0:
1192                                  break;                                  break;
   
1193                          default:                          default:
1194                                  unimpl("PDU %d\n", type);                                  unimpl("PDU %d\n", type);
1195                  }                  }
1196                    if (disc)
1197                            return False;
1198                    cont = g_next_packet < s->end;
1199          }          }
1200            return True;
1201  }  }
1202    
1203  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */
# Line 737  BOOL Line 1205  BOOL
1205  rdp_connect(char *server, uint32 flags, char *domain, char *password,  rdp_connect(char *server, uint32 flags, char *domain, char *password,
1206              char *command, char *directory)              char *command, char *directory)
1207  {  {
1208          if (!sec_connect(server))          if (!sec_connect(server, g_username))
1209                  return False;                  return False;
1210    
1211          rdp_send_logon_info(flags, domain, username, password, command, directory);          rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1212          return True;          return True;
1213  }  }
1214    

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

  ViewVC Help
Powered by ViewVC 1.1.26