/[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 10 by matty, Tue Aug 15 10:23:24 2000 UTC revision 708 by jsorg71, Fri Jun 4 15:01:36 2004 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-2000     Copyright (C) Matthew Chapman 1999-2002
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 orders;  extern BOOL g_bitmap_compression;
27    extern BOOL g_orders;
28    extern BOOL g_encryption;
29    extern BOOL g_desktop_save;
30    extern BOOL g_use_rdp5;
31    extern uint16 g_server_rdp_version;
32    extern uint32 g_rdp5_performanceflags;
33    extern int g_server_bpp;
34    extern int g_width;
35    extern int g_height;
36    extern BOOL g_bitmap_cache;
37    
38  unsigned char *next_packet;  uint8 *g_next_packet;
39  uint32 rdp_shareid;  uint32 g_rdp_shareid;
   
 /* Initialise an RDP packet */  
 static STREAM rdp_init(int maxlen)  
 {  
         STREAM s;  
40    
41          s = sec_init(SEC_ENCRYPT, maxlen + 6);  extern RDPCOMP g_mppc_dict;
         s_push_layer(s, rdp_hdr, 6);  
42    
43          return s;  #if WITH_DEBUG
44  }  static uint32 g_packetno;
45    #endif
 /* Send an RDP packet */  
 static void rdp_send(STREAM s, uint8 pdu_type)  
 {  
         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, SEC_ENCRYPT);  
 }  
46    
47  /* Receive an RDP packet */  /* Receive an RDP packet */
48  static STREAM rdp_recv(uint8 *type)  static STREAM
49    rdp_recv(uint8 * type)
50  {  {
51          static STREAM rdp_s;          static STREAM rdp_s;
52          uint16 length, pdu_type;          uint16 length, pdu_type;
53    
54          if ((rdp_s == NULL) || (next_packet >= rdp_s->end))          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))
55          {          {
56                  rdp_s = sec_recv();                  rdp_s = sec_recv();
57                  if (rdp_s == NULL)                  if (rdp_s == NULL)
58                          return NULL;                          return NULL;
59    
60                  next_packet = rdp_s->p;                  g_next_packet = rdp_s->p;
61          }          }
62          else          else
63          {          {
64                  rdp_s->p = next_packet;                  rdp_s->p = g_next_packet;
65          }          }
66    
67          in_uint16_le(rdp_s, length);          in_uint16_le(rdp_s, length);
68            /* 32k packets are really 8, keepalive fix */
69            if (length == 0x8000)
70            {
71                    g_next_packet += 8;
72                    *type = 0;
73                    return rdp_s;
74            }
75          in_uint16_le(rdp_s, pdu_type);          in_uint16_le(rdp_s, pdu_type);
76          in_uint8s(rdp_s, 2); /* userid */          in_uint8s(rdp_s, 2);    /* userid */
   
         next_packet += length;  
77          *type = pdu_type & 0xf;          *type = pdu_type & 0xf;
78    
79  #if RDP_DEBUG  #if WITH_DEBUG
80          DEBUG("RDP packet (type %x):\n", *type);          DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type));
81          hexdump(rdp_s->p, length);          hexdump(g_next_packet, length);
82  #endif  #endif /*  */
83    
84            g_next_packet += length;
85          return rdp_s;          return rdp_s;
86  }  }
87    
88  /* Initialise an RDP data packet */  /* Initialise an RDP data packet */
89  static STREAM rdp_init_data(int maxlen)  static STREAM
90    rdp_init_data(int maxlen)
91  {  {
92          STREAM s;          STREAM s;
93    
94          s = sec_init(SEC_ENCRYPT, maxlen + 18);          s = sec_init(g_encryption ? SEC_ENCRYPT : 0, maxlen + 18);
95          s_push_layer(s, rdp_hdr, 18);          s_push_layer(s, rdp_hdr, 18);
96    
97          return s;          return s;
98  }  }
99    
100  /* Send an RDP data packet */  /* Send an RDP data packet */
101  static void rdp_send_data(STREAM s, uint8 data_pdu_type)  static void
102    rdp_send_data(STREAM s, uint8 data_pdu_type)
103  {  {
104          uint16 length;          uint16 length;
105    
# Line 108  static void rdp_send_data(STREAM s, uint Line 108  static void rdp_send_data(STREAM s, uint
108    
109          out_uint16_le(s, length);          out_uint16_le(s, length);
110          out_uint16_le(s, (RDP_PDU_DATA | 0x10));          out_uint16_le(s, (RDP_PDU_DATA | 0x10));
111          out_uint16_le(s, (mcs_userid + 1001));          out_uint16_le(s, (g_mcs_userid + 1001));
112    
113          out_uint32_le(s, rdp_shareid);          out_uint32_le(s, g_rdp_shareid);
114          out_uint8(s, 0);  /* pad */          out_uint8(s, 0);        /* pad */
115          out_uint8(s, 1);  /* streamid */          out_uint8(s, 1);        /* streamid */
116          out_uint16(s, (length - 14));          out_uint16_le(s, (length - 14));
117          out_uint8(s, data_pdu_type);          out_uint8(s, data_pdu_type);
118          out_uint8(s, 0);  /* compress_type */          out_uint8(s, 0);        /* compress_type */
119          out_uint16(s, 0); /* compress_len */          out_uint16(s, 0);       /* compress_len */
120    
121          sec_send(s, SEC_ENCRYPT);          sec_send(s, g_encryption ? SEC_ENCRYPT : 0);
122  }  }
123    
124  /* Output a string in Unicode */  /* Output a string in Unicode */
125  void rdp_out_unistr(STREAM s, char *string, int len)  void
126    rdp_out_unistr(STREAM s, char *string, int len)
127  {  {
128          int i = 0, j = 0;          int i = 0, j = 0;
129    
# Line 137  void rdp_out_unistr(STREAM s, char *stri Line 138  void rdp_out_unistr(STREAM s, char *stri
138          s->p += len;          s->p += len;
139  }  }
140    
141  /* Parse a logon info packet */  /* Input a string in Unicode
142  static void rdp_send_logon_info(uint32 flags, char *domain, char *user,   *
143                                  char *password, char *program, char *directory)   * Returns str_len of string
144     */
145    int
146    rdp_in_unistr(STREAM s, char *string, int uni_len)
147  {  {
148          int len_domain    = 2 * strlen(domain);          int i = 0;
149          int len_user      = 2 * strlen(user);  
150          int len_password  = 2 * strlen(password);          while (i < uni_len / 2)
151          int len_program   = 2 * strlen(program);          {
152                    in_uint8a(s, &string[i++], 1);
153                    in_uint8s(s, 1);
154            }
155    
156            return i - 1;
157    }
158    
159    
160    /* Parse a logon info packet */
161    static void
162    rdp_send_logon_info(uint32 flags, char *domain, char *user,
163                        char *password, char *program, char *directory)
164    {
165            char *ipaddr = tcp_get_address();
166            int len_domain = 2 * strlen(domain);
167            int len_user = 2 * strlen(user);
168            int len_password = 2 * strlen(password);
169            int len_program = 2 * strlen(program);
170          int len_directory = 2 * strlen(directory);          int len_directory = 2 * strlen(directory);
171          uint32 sec_flags = SEC_LOGON_INFO | SEC_ENCRYPT;          int len_ip = 2 * strlen(ipaddr);
172            int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
173            int packetlen = 0;
174            uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
175          STREAM s;          STREAM s;
176            time_t t = time(NULL);
177            time_t tzone;
178    
179    #if 0
180            /* enable rdp compression */
181            /* some problems still exist with rdp5 */
182            flags |= RDP_COMPRESSION;
183    #endif
184    
185            if (!g_use_rdp5 || 1 == g_server_rdp_version)
186            {
187                    DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
188    
189          s = sec_init(sec_flags, 18 + len_domain + len_user + len_password                  s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
190                                          + len_program + len_directory + 10);                               + len_program + len_directory + 10);
191    
192          out_uint32(s, 0);                  out_uint32(s, 0);
193          out_uint32_le(s, flags);                  out_uint32_le(s, flags);
194          out_uint16_le(s, len_domain);                  out_uint16_le(s, len_domain);
195          out_uint16_le(s, len_user);                  out_uint16_le(s, len_user);
196          out_uint16_le(s, len_password);                  out_uint16_le(s, len_password);
197          out_uint16_le(s, len_program);                  out_uint16_le(s, len_program);
198          out_uint16_le(s, len_directory);                  out_uint16_le(s, len_directory);
199          rdp_out_unistr(s, domain,    len_domain);                  rdp_out_unistr(s, domain, len_domain);
200          rdp_out_unistr(s, user,      len_user);                  rdp_out_unistr(s, user, len_user);
201          rdp_out_unistr(s, password,  len_password);                  rdp_out_unistr(s, password, len_password);
202          rdp_out_unistr(s, program,   len_program);                  rdp_out_unistr(s, program, len_program);
203          rdp_out_unistr(s, directory, len_directory);                  rdp_out_unistr(s, directory, len_directory);
204            }
205            else
206            {
207    
208                    flags |= RDP_LOGON_BLOB;
209                    DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
210                    packetlen = 4 + /* Unknown uint32 */
211                            4 +     /* flags */
212                            2 +     /* len_domain */
213                            2 +     /* len_user */
214                            (flags & RDP_LOGON_AUTO ? 2 : 0) +      /* len_password */
215                            (flags & RDP_LOGON_BLOB ? 2 : 0) +      /* Length of BLOB */
216                            2 +     /* len_program */
217                            2 +     /* len_directory */
218                            (0 < len_domain ? len_domain : 2) +     /* domain */
219                            len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 +    /* We have no 512 byte BLOB. Perhaps we must? */
220                            (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + /* After the BLOB is a unknown int16. If there is a BLOB, that is. */
221                            (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 +     /* Unknown (2) */
222                            2 +     /* Client ip length */
223                            len_ip +        /* Client ip */
224                            2 +     /* DLL string length */
225                            len_dll +       /* DLL string */
226                            2 +     /* Unknown */
227                            2 +     /* Unknown */
228                            64 +    /* Time zone #0 */
229                            2 +     /* Unknown */
230                            64 +    /* Time zone #1 */
231                            32;     /* Unknown */
232    
233                    s = sec_init(sec_flags, packetlen);
234                    DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
235    
236                    out_uint32(s, 0);       /* Unknown */
237                    out_uint32_le(s, flags);
238                    out_uint16_le(s, len_domain);
239                    out_uint16_le(s, len_user);
240                    if (flags & RDP_LOGON_AUTO)
241                    {
242                            out_uint16_le(s, len_password);
243    
244                    }
245                    if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
246                    {
247                            out_uint16_le(s, 0);
248                    }
249                    out_uint16_le(s, len_program);
250                    out_uint16_le(s, len_directory);
251                    if (0 < len_domain)
252                            rdp_out_unistr(s, domain, len_domain);
253                    else
254                            out_uint16_le(s, 0);
255                    rdp_out_unistr(s, user, len_user);
256                    if (flags & RDP_LOGON_AUTO)
257                    {
258                            rdp_out_unistr(s, password, len_password);
259                    }
260                    if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
261                    {
262                            out_uint16_le(s, 0);
263                    }
264                    if (0 < len_program)
265                    {
266                            rdp_out_unistr(s, program, len_program);
267    
268                    }
269                    else
270                    {
271                            out_uint16_le(s, 0);
272                    }
273                    if (0 < len_directory)
274                    {
275                            rdp_out_unistr(s, directory, len_directory);
276                    }
277                    else
278                    {
279                            out_uint16_le(s, 0);
280                    }
281                    out_uint16_le(s, 2);
282                    out_uint16_le(s, len_ip + 2);   /* Length of client ip */
283                    rdp_out_unistr(s, ipaddr, len_ip);
284                    out_uint16_le(s, len_dll + 2);
285                    rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
286    
287                    tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
288                    out_uint32_le(s, tzone);
289    
290                    rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
291                    out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
292    
293                    out_uint32_le(s, 0x0a0000);
294                    out_uint32_le(s, 0x050000);
295                    out_uint32_le(s, 3);
296                    out_uint32_le(s, 0);
297                    out_uint32_le(s, 0);
298    
299                    rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
300                    out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
301    
302                    out_uint32_le(s, 0x30000);
303                    out_uint32_le(s, 0x050000);
304                    out_uint32_le(s, 2);
305                    out_uint32(s, 0);
306                    out_uint32_le(s, 0xffffffc4);
307                    out_uint32_le(s, 0xfffffffe);
308                    out_uint32_le(s, g_rdp5_performanceflags);
309                    out_uint32(s, 0);
310    
311    
312            }
313          s_mark_end(s);          s_mark_end(s);
314          sec_send(s, sec_flags);          sec_send(s, sec_flags);
315  }  }
316    
317  /* Send a control PDU */  /* Send a control PDU */
318  static void rdp_send_control(uint16 action)  static void
319    rdp_send_control(uint16 action)
320  {  {
321          STREAM s;          STREAM s;
322    
323          s = rdp_init_data(8);          s = rdp_init_data(8);
324    
325          out_uint16_le(s, action);          out_uint16_le(s, action);
326          out_uint16(s, 0); /* userid */          out_uint16(s, 0);       /* userid */
327          out_uint32(s, 0); /* control id */          out_uint32(s, 0);       /* control id */
328    
329          s_mark_end(s);          s_mark_end(s);
330          rdp_send_data(s, RDP_DATA_PDU_CONTROL);          rdp_send_data(s, RDP_DATA_PDU_CONTROL);
331  }  }
332    
333  /* Send a synchronisation PDU */  /* Send a synchronisation PDU */
334  static void rdp_send_synchronise()  static void
335    rdp_send_synchronise(void)
336  {  {
337          STREAM s;          STREAM s;
338    
339          s = rdp_init_data(4);          s = rdp_init_data(4);
340    
341          out_uint16_le(s, 1); /* type */          out_uint16_le(s, 1);    /* type */
342          out_uint16_le(s, 1002);          out_uint16_le(s, 1002);
343    
344          s_mark_end(s);          s_mark_end(s);
# Line 199  static void rdp_send_synchronise() Line 346  static void rdp_send_synchronise()
346  }  }
347    
348  /* Send a single input event */  /* Send a single input event */
349  void rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags,  void
350                      uint16 param1, uint16 param2)  rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
351  {  {
352          STREAM s;          STREAM s;
353    
354          s = rdp_init_data(16);          s = rdp_init_data(16);
355    
356          out_uint16_le(s, 1); /* number of events */          out_uint16_le(s, 1);    /* number of events */
357          out_uint16(s, 0);    /* pad */          out_uint16(s, 0);       /* pad */
358    
359          out_uint32_le(s, time);          out_uint32_le(s, time);
360          out_uint16_le(s, message_type);          out_uint16_le(s, message_type);
# Line 220  void rdp_send_input(uint32 time, uint16 Line 367  void rdp_send_input(uint32 time, uint16
367  }  }
368    
369  /* Send an (empty) font information PDU */  /* Send an (empty) font information PDU */
370  static void rdp_send_fonts(uint16 seq)  static void
371    rdp_send_fonts(uint16 seq)
372  {  {
373          STREAM s;          STREAM s;
374    
375          s = rdp_init_data(8);          s = rdp_init_data(8);
376    
377          out_uint16(s, 0);       /* number of fonts */          out_uint16(s, 0);       /* number of fonts */
378          out_uint16_le(s, 0x3e); /* unknown */          out_uint16_le(s, 0);    /* pad? */
379          out_uint16_le(s, seq);  /* unknown */          out_uint16_le(s, seq);  /* unknown */
380          out_uint16_le(s, 0x32); /* entry size */          out_uint16_le(s, 0x32); /* entry size */
381    
# Line 236  static void rdp_send_fonts(uint16 seq) Line 384  static void rdp_send_fonts(uint16 seq)
384  }  }
385    
386  /* Output general capability set */  /* Output general capability set */
387  static void rdp_out_general_caps(STREAM s)  static void
388    rdp_out_general_caps(STREAM s)
389  {  {
390          out_uint16_le(s, RDP_CAPSET_GENERAL);          out_uint16_le(s, RDP_CAPSET_GENERAL);
391          out_uint16_le(s, RDP_CAPLEN_GENERAL);          out_uint16_le(s, RDP_CAPLEN_GENERAL);
392    
393          out_uint16_le(s, 1);    /* OS major type */          out_uint16_le(s, 1);    /* OS major type */
394          out_uint16_le(s, 3);    /* OS minor type */          out_uint16_le(s, 3);    /* OS minor type */
395          out_uint16_le(s, 0x200); /* Protocol version */          out_uint16_le(s, 0x200);        /* Protocol version */
396          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
397          out_uint16(s, 0);       /* Compression types */          out_uint16(s, 0);       /* Compression types */
398          out_uint16(s, 0);       /* Pad */          out_uint16_le(s, g_use_rdp5 ? 0x40d : 0);
399            /* Pad, according to T.128. 0x40d seems to
400               trigger
401               the server to start sending RDP5 packets.
402               However, the value is 0x1d04 with W2KTSK and
403               NT4MS. Hmm.. Anyway, thankyou, Microsoft,
404               for sending such information in a padding
405               field.. */
406          out_uint16(s, 0);       /* Update capability */          out_uint16(s, 0);       /* Update capability */
407          out_uint16(s, 0);       /* Remote unshare capability */          out_uint16(s, 0);       /* Remote unshare capability */
408          out_uint16(s, 0);       /* Compression level */          out_uint16(s, 0);       /* Compression level */
# Line 254  static void rdp_out_general_caps(STREAM Line 410  static void rdp_out_general_caps(STREAM
410  }  }
411    
412  /* Output bitmap capability set */  /* Output bitmap capability set */
413  static void rdp_out_bitmap_caps(STREAM s)  static void
414    rdp_out_bitmap_caps(STREAM s)
415  {  {
416          out_uint16_le(s, RDP_CAPSET_BITMAP);          out_uint16_le(s, RDP_CAPSET_BITMAP);
417          out_uint16_le(s, RDP_CAPLEN_BITMAP);          out_uint16_le(s, RDP_CAPLEN_BITMAP);
418    
419          out_uint16_le(s, 8);    /* Preferred BPP */          out_uint16_le(s, g_server_bpp); /* Preferred BPP */
420          out_uint16(s, 1);       /* Receive 1 BPP */          out_uint16_le(s, 1);    /* Receive 1 BPP */
421          out_uint16(s, 1);       /* Receive 4 BPP */          out_uint16_le(s, 1);    /* Receive 4 BPP */
422          out_uint16_le(s, 1);    /* Receive 8 BPP */          out_uint16_le(s, 1);    /* Receive 8 BPP */
423          out_uint16_le(s, 800);  /* Desktop width */          out_uint16_le(s, 800);  /* Desktop width */
424          out_uint16_le(s, 600);  /* Desktop height */          out_uint16_le(s, 600);  /* Desktop height */
425          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
426          out_uint16(s, 0);       /* Allow resize */          out_uint16(s, 1);       /* Allow resize */
427          out_uint16_le(s, 1);    /* Support compression */          out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
428          out_uint16(s, 0);       /* Unknown */          out_uint16(s, 0);       /* Unknown */
429          out_uint16_le(s, 1);    /* Unknown */          out_uint16_le(s, 1);    /* Unknown */
430          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
431  }  }
432    
433  /* Output order capability set */  /* Output order capability set */
434  static void rdp_out_order_caps(STREAM s)  static void
435    rdp_out_order_caps(STREAM s)
436  {  {
437          uint8 order_caps[32];          uint8 order_caps[32];
438    
         memset(order_caps, orders, 32);  
439    
440            memset(order_caps, 0, 32);
441            order_caps[0] = 1;      /* dest blt */
442            order_caps[1] = 1;      /* pat blt */
443            order_caps[2] = 1;      /* screen blt */
444            order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
445            order_caps[8] = 1;      /* line */
446            order_caps[9] = 1;      /* line */
447            order_caps[10] = 1;     /* rect */
448            order_caps[11] = (g_desktop_save == False ? 0 : 1);     /* desksave */
449            order_caps[13] = 1;     /* memblt */
450            order_caps[14] = 1;     /* triblt */
451            order_caps[22] = 1;     /* polyline */
452            order_caps[27] = 1;     /* text2 */
453          out_uint16_le(s, RDP_CAPSET_ORDER);          out_uint16_le(s, RDP_CAPSET_ORDER);
454          out_uint16_le(s, RDP_CAPLEN_ORDER);          out_uint16_le(s, RDP_CAPLEN_ORDER);
455    
# Line 289  static void rdp_out_order_caps(STREAM s) Line 459  static void rdp_out_order_caps(STREAM s)
459          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
460          out_uint16_le(s, 1);    /* Max order level */          out_uint16_le(s, 1);    /* Max order level */
461          out_uint16_le(s, 0x147);        /* Number of fonts */          out_uint16_le(s, 0x147);        /* Number of fonts */
462          out_uint16_le(s, 0x2a);         /* Capability flags */          out_uint16_le(s, 0x2a); /* Capability flags */
463          out_uint8p(s, order_caps, 32);  /* Orders supported */          out_uint8p(s, order_caps, 32);  /* Orders supported */
464          out_uint16_le(s, 0x6a1);        /* Text capability flags */          out_uint16_le(s, 0x6a1);        /* Text capability flags */
465          out_uint8s(s, 6);       /* Pad */          out_uint8s(s, 6);       /* Pad */
466          out_uint32(s, 0x38400); /* Desktop cache size */          out_uint32_le(s, g_desktop_save == False ? 0 : 0x38400);        /* Desktop cache size */
467          out_uint32(s, 0);       /* Unknown */          out_uint32(s, 0);       /* Unknown */
468          out_uint32(s, 0x4e4);   /* Unknown */          out_uint32_le(s, 0x4e4);        /* Unknown */
469  }  }
470    
471  /* Output bitmap cache capability set */  /* Output bitmap cache capability set */
472  static void rdp_out_bmpcache_caps(STREAM s)  static void
473    rdp_out_bmpcache_caps(STREAM s)
474  {  {
475            int Bpp;
476          out_uint16_le(s, RDP_CAPSET_BMPCACHE);          out_uint16_le(s, RDP_CAPSET_BMPCACHE);
477          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
478    
479          out_uint8s(s, 24); /* unused */          Bpp = (g_server_bpp + 7) / 8;
480          out_uint16_le(s, 0x258); /* entries */          out_uint8s(s, 24);      /* unused */
481          out_uint16_le(s, 0x100); /* max cell size */          out_uint16_le(s, 0x258);        /* entries */
482          out_uint16_le(s, 0x12c); /* entries */          out_uint16_le(s, 0x100 * Bpp);  /* max cell size */
483          out_uint16_le(s, 0x400); /* max cell size */          out_uint16_le(s, 0x12c);        /* entries */
484          out_uint16_le(s, 0x106); /* entries */          out_uint16_le(s, 0x400 * Bpp);  /* max cell size */
485          out_uint16_le(s, 0x1000); /* max cell size */          out_uint16_le(s, 0x106);        /* entries */
486            out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
487  }  }
488    
489  /* Output control capability set */  /* Output control capability set */
490  static void rdp_out_control_caps(STREAM s)  static void
491    rdp_out_control_caps(STREAM s)
492  {  {
493          out_uint16_le(s, RDP_CAPSET_CONTROL);          out_uint16_le(s, RDP_CAPSET_CONTROL);
494          out_uint16_le(s, RDP_CAPLEN_CONTROL);          out_uint16_le(s, RDP_CAPLEN_CONTROL);
# Line 326  static void rdp_out_control_caps(STREAM Line 500  static void rdp_out_control_caps(STREAM
500  }  }
501    
502  /* Output activation capability set */  /* Output activation capability set */
503  static void rdp_out_activate_caps(STREAM s)  static void
504    rdp_out_activate_caps(STREAM s)
505  {  {
506          out_uint16_le(s, RDP_CAPSET_ACTIVATE);          out_uint16_le(s, RDP_CAPSET_ACTIVATE);
507          out_uint16_le(s, RDP_CAPLEN_ACTIVATE);          out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
# Line 338  static void rdp_out_activate_caps(STREAM Line 513  static void rdp_out_activate_caps(STREAM
513  }  }
514    
515  /* Output pointer capability set */  /* Output pointer capability set */
516  static void rdp_out_pointer_caps(STREAM s)  static void
517    rdp_out_pointer_caps(STREAM s)
518  {  {
519          out_uint16_le(s, RDP_CAPSET_POINTER);          out_uint16_le(s, RDP_CAPSET_POINTER);
520          out_uint16_le(s, RDP_CAPLEN_POINTER);          out_uint16_le(s, RDP_CAPLEN_POINTER);
# Line 348  static void rdp_out_pointer_caps(STREAM Line 524  static void rdp_out_pointer_caps(STREAM
524  }  }
525    
526  /* Output share capability set */  /* Output share capability set */
527  static void rdp_out_share_caps(STREAM s)  static void
528    rdp_out_share_caps(STREAM s)
529  {  {
530          out_uint16_le(s, RDP_CAPSET_SHARE);          out_uint16_le(s, RDP_CAPSET_SHARE);
531          out_uint16_le(s, RDP_CAPLEN_SHARE);          out_uint16_le(s, RDP_CAPLEN_SHARE);
# Line 358  static void rdp_out_share_caps(STREAM s) Line 535  static void rdp_out_share_caps(STREAM s)
535  }  }
536    
537  /* Output colour cache capability set */  /* Output colour cache capability set */
538  static void rdp_out_colcache_caps(STREAM s)  static void
539    rdp_out_colcache_caps(STREAM s)
540  {  {
541          out_uint16_le(s, RDP_CAPSET_COLCACHE);          out_uint16_le(s, RDP_CAPSET_COLCACHE);
542          out_uint16_le(s, RDP_CAPLEN_COLCACHE);          out_uint16_le(s, RDP_CAPLEN_COLCACHE);
# Line 368  static void rdp_out_colcache_caps(STREAM Line 546  static void rdp_out_colcache_caps(STREAM
546  }  }
547    
548  static uint8 canned_caps[] = {  static uint8 canned_caps[] = {
549  0x01,0x00,0x00,0x00,0x09,0x04,0x00,0x00,0x04,          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,
550  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
551  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,          0x00, 0x00, 0x00, 0x00, 0x00,
552  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
553  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,          0x00, 0x00, 0x00, 0x00, 0x00,
554  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x08,0x00,0x01,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
555  0x00,0x00,0x00,0x0E,0x00,0x08,0x00,0x01,0x00,0x00,0x00,0x10,0x00,0x34,0x00,0xFE,          0x00, 0x00, 0x00, 0x00, 0x00,
556  0x00,0x04,0x00,0xFE,0x00,0x04,0x00,0xFE,0x00,0x08,0x00,0xFE,0x00,0x08,0x00,0xFE,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557  0x00,0x10,0x00,0xFE,0x00,0x20,0x00,0xFE,0x00,0x40,0x00,0xFE,0x00,0x80,0x00,0xFE,          0x00, 0x00, 0x00, 0x00, 0x00,
558  0x00,0x00,0x01,0x40,0x00,0x00,0x08,0x00,0x01,0x00,0x01,0x02,0x00,0x00,0x00          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559            0x0C, 0x00, 0x08, 0x00, 0x01,
560            0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
561            0x10, 0x00, 0x34, 0x00, 0xFE,
562            0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,
563            0xFE, 0x00, 0x08, 0x00, 0xFE,
564            0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,
565            0xFE, 0x00, 0x80, 0x00, 0xFE,
566            0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
567            0x02, 0x00, 0x00, 0x00
568  };  };
569    
570  /* Output unknown capability set */  /* Output unknown capability sets (number 13, 12, 14 and 16) */
571  static void rdp_out_unknown_caps(STREAM s)  static void
572    rdp_out_unknown_caps(STREAM s)
573  {  {
574          out_uint16_le(s, RDP_CAPSET_UNKNOWN);          out_uint16_le(s, RDP_CAPSET_UNKNOWN);
575          out_uint16_le(s, 0x58);          out_uint16_le(s, 0x58);
576            
577          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN-4);          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);
578  }  }
579    
580    #define RDP5_FLAG 0x0030
581  /* Send a confirm active PDU */  /* Send a confirm active PDU */
582  static void rdp_send_confirm_active()  static void
583    rdp_send_confirm_active(void)
584  {  {
585          STREAM s;          STREAM s;
586          uint16 caplen = RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER          uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
587                  + RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE + RDP_CAPLEN_ACTIVATE          uint16 caplen =
588                  + RDP_CAPLEN_CONTROL + RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
589                  + RDP_CAPLEN_UNKNOWN;                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
590                    RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
591                    RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;
592    
593            s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
594    
595            out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
596            out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10));      /* Version 1 */
597            out_uint16_le(s, (g_mcs_userid + 1001));
598    
599          s = rdp_init(14 + caplen + sizeof(RDP_SOURCE));          out_uint32_le(s, g_rdp_shareid);
600            out_uint16_le(s, 0x3ea);        /* userid */
         out_uint32_le(s, rdp_shareid);  
         out_uint16_le(s, 0x3ea); /* userid */  
601          out_uint16_le(s, sizeof(RDP_SOURCE));          out_uint16_le(s, sizeof(RDP_SOURCE));
602          out_uint16_le(s, caplen);          out_uint16_le(s, caplen);
603    
604          out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));          out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
605          out_uint16_le(s, 0xd); /* num_caps */          out_uint16_le(s, 0xd);  /* num_caps */
606          out_uint8s(s, 2);     /* pad */          out_uint8s(s, 2);       /* pad */
607    
608          rdp_out_general_caps(s);          rdp_out_general_caps(s);
609          rdp_out_bitmap_caps(s);          rdp_out_bitmap_caps(s);
# Line 421  static void rdp_send_confirm_active() Line 617  static void rdp_send_confirm_active()
617          rdp_out_unknown_caps(s);          rdp_out_unknown_caps(s);
618    
619          s_mark_end(s);          s_mark_end(s);
620          rdp_send(s, RDP_PDU_CONFIRM_ACTIVE);          sec_send(s, sec_flags);
621    }
622    
623    /* Process a general capability set */
624    static void
625    rdp_process_general_caps(STREAM s)
626    {
627            uint16 pad2octetsB;     /* rdp5 flags? */
628    
629            in_uint8s(s, 10);
630            in_uint16_le(s, pad2octetsB);
631    
632            if (!pad2octetsB)
633                    g_use_rdp5 = False;
634    }
635    
636    /* Process a bitmap capability set */
637    static void
638    rdp_process_bitmap_caps(STREAM s)
639    {
640            uint16 width, height, bpp;
641    
642            in_uint16_le(s, bpp);
643            in_uint8s(s, 6);
644    
645            in_uint16_le(s, width);
646            in_uint16_le(s, height);
647    
648            DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));
649    
650            /*
651             * The server may limit bpp and change the size of the desktop (for
652             * example when shadowing another session).
653             */
654            if (g_server_bpp != bpp)
655            {
656                    warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
657                    g_server_bpp = bpp;
658            }
659            if (g_width != width || g_height != height)
660            {
661                    warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
662                                    width, height);
663                    g_width = width;
664                    g_height = height;
665                    ui_resize_window();
666            }
667  }  }
668    
669  /* Respond to a demand active PDU */  /* Respond to a demand active PDU */
670  static void process_demand_active(STREAM s)  static void
671    process_demand_active(STREAM s)
672  {  {
673          uint8 type;          int n;
674            uint8 type, *next;
675            uint16 len_src_descriptor, len_combined_caps, num_capsets, capset_type, capset_length;
676    
677            in_uint32_le(s, g_rdp_shareid);
678            in_uint16_le(s, len_src_descriptor);
679            in_uint16_le(s, len_combined_caps);
680            in_uint8s(s, len_src_descriptor);
681    
682          in_uint32_le(s, rdp_shareid);          in_uint16_le(s, num_capsets);
683            in_uint8s(s, 2);        /* pad */
684    
685            DEBUG(("DEMAND_ACTIVE(id=0x%x,num_caps=%d)\n", g_rdp_shareid, num_capsets));
686    
687            for (n = 0; n < num_capsets; n++)
688            {
689                    in_uint16_le(s, capset_type);
690                    in_uint16_le(s, capset_length);
691    
692          DEBUG("DEMAND_ACTIVE(id=0x%x)\n", rdp_shareid);                  next = s->p + capset_length - 4;
693    
694                    switch (capset_type)
695                    {
696                            case RDP_CAPSET_GENERAL:
697                                    rdp_process_general_caps(s);
698                                    break;
699    
700                            case RDP_CAPSET_BITMAP:
701                                    rdp_process_bitmap_caps(s);
702                                    break;
703                    }
704    
705                    s->p = next;
706            }
707    
708          rdp_send_confirm_active();          rdp_send_confirm_active();
709          rdp_send_synchronise();          rdp_send_synchronise();
710          rdp_send_control(RDP_CTL_COOPERATE);          rdp_send_control(RDP_CTL_COOPERATE);
711          rdp_send_control(RDP_CTL_REQUEST_CONTROL);          rdp_send_control(RDP_CTL_REQUEST_CONTROL);
712          rdp_recv(&type); // RDP_PDU_SYNCHRONIZE          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
713          rdp_recv(&type); // RDP_CTL_COOPERATE          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
714          rdp_recv(&type); // RDP_CTL_GRANT_CONTROL          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
715          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);
716          rdp_send_fonts(1);  
717          rdp_send_fonts(2);          if (g_use_rdp5)
718          rdp_recv(&type); // RDP_PDU_UNKNOWN 0x28          {
719                    rdp_send_fonts(3);
720            }
721            else
722            {
723                    rdp_send_fonts(1);
724                    rdp_send_fonts(2);
725            }
726    
727            rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
728          reset_order_state();          reset_order_state();
729  }  }
730    
731    /* Process a colour pointer PDU */
732    void
733    process_colour_pointer_pdu(STREAM s)
734    {
735            uint16 x, y, width, height, cache_idx, masklen, datalen;
736            uint8 *mask, *data;
737            HCURSOR cursor;
738    
739            in_uint16_le(s, cache_idx);
740            in_uint16_le(s, x);
741            in_uint16_le(s, y);
742            in_uint16_le(s, width);
743            in_uint16_le(s, height);
744            in_uint16_le(s, masklen);
745            in_uint16_le(s, datalen);
746            in_uint8p(s, data, datalen);
747            in_uint8p(s, mask, masklen);
748            cursor = ui_create_cursor(x, y, width, height, mask, data);
749            ui_set_cursor(cursor);
750            cache_put_cursor(cache_idx, cursor);
751    }
752    
753    /* Process a cached pointer PDU */
754    void
755    process_cached_pointer_pdu(STREAM s)
756    {
757            uint16 cache_idx;
758    
759            in_uint16_le(s, cache_idx);
760            ui_set_cursor(cache_get_cursor(cache_idx));
761    }
762    
763    /* Process a system pointer PDU */
764    void
765    process_system_pointer_pdu(STREAM s)
766    {
767            uint16 system_pointer_type;
768    
769            in_uint16(s, system_pointer_type);
770            switch (system_pointer_type)
771            {
772                    case RDP_NULL_POINTER:
773                            ui_set_null_cursor();
774                            break;
775    
776                    default:
777                            unimpl("System pointer message 0x%x\n", system_pointer_type);
778            }
779    }
780    
781  /* Process a pointer PDU */  /* Process a pointer PDU */
782  static void process_pointer_pdu(STREAM s)  static void
783    process_pointer_pdu(STREAM s)
784  {  {
785          uint16 message_type;          uint16 message_type;
786          uint16 x, y;          uint16 x, y;
787    
788          in_uint16_le(s, message_type);          in_uint16_le(s, message_type);
789          in_uint8s(s, 2); /* pad */          in_uint8s(s, 2);        /* pad */
790    
791          switch (message_type)          switch (message_type)
792          {          {
# Line 465  static void process_pointer_pdu(STREAM s Line 797  static void process_pointer_pdu(STREAM s
797                                  ui_move_pointer(x, y);                                  ui_move_pointer(x, y);
798                          break;                          break;
799    
800                    case RDP_POINTER_COLOR:
801                            process_colour_pointer_pdu(s);
802                            break;
803    
804                    case RDP_POINTER_CACHED:
805                            process_cached_pointer_pdu(s);
806                            break;
807    
808                    case RDP_POINTER_SYSTEM:
809                            process_system_pointer_pdu(s);
810                            break;
811    
812                  default:                  default:
813                          DEBUG("Pointer message 0x%x\n", message_type);                          unimpl("Pointer message 0x%x\n", message_type);
814          }          }
815  }  }
816    
817  /* Process bitmap updates */  /* Process bitmap updates */
818  static void process_bitmap_updates(STREAM s)  void
819    process_bitmap_updates(STREAM s)
820  {  {
821          uint16 num_updates;          uint16 num_updates;
822          uint16 left, top, right, bottom, width, height;          uint16 left, top, right, bottom, width, height;
823          uint16 cx, cy, bpp, compress, bufsize, size;          uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
824          uint8 *data, *rawdata;          uint8 *data, *bmpdata;
825          int i;          int i;
826    
827          in_uint16_le(s, num_updates);          in_uint16_le(s, num_updates);
# Line 490  static void process_bitmap_updates(STREA Line 835  static void process_bitmap_updates(STREA
835                  in_uint16_le(s, width);                  in_uint16_le(s, width);
836                  in_uint16_le(s, height);                  in_uint16_le(s, height);
837                  in_uint16_le(s, bpp);                  in_uint16_le(s, bpp);
838                    Bpp = (bpp + 7) / 8;
839                  in_uint16_le(s, compress);                  in_uint16_le(s, compress);
840                  in_uint16_le(s, bufsize);                  in_uint16_le(s, bufsize);
841    
842                  cx = right - left + 1;                  cx = right - left + 1;
843                  cy = bottom - top + 1;                  cy = bottom - top + 1;
844    
845                  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",
846                          left, top, right, bottom, width, height, compress);                         left, top, right, bottom, width, height, Bpp, compress));
847    
848                  if (!compress)                  if (!compress)
849                  {                  {
850                          in_uint8p(s, data, bufsize);                          int y;
851                          ui_paint_bitmap(left, top, cx, cy, width, height, data);                          bmpdata = (uint8 *) xmalloc(width * height * Bpp);
852                          return;                          for (y = 0; y < height; y++)
853                            {
854                                    in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
855                                              width * Bpp);
856                            }
857                            ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
858                            xfree(bmpdata);
859                            continue;
860                  }                  }
861    
                 in_uint8s(s, 2); /* pad */  
                 in_uint16_le(s, size);  
                 in_uint8s(s, 4); /* line_size, final_size */  
                 in_uint8p(s, data, size);  
862    
863                  rawdata = xmalloc(width * height);                  if (compress & 0x400)
                 if (bitmap_decompress(rawdata, width, height, data, size))  
864                  {                  {
865                          ui_paint_bitmap(left, top, cx, cy, width, height,                          size = bufsize;
866                                          rawdata);                  }
867                    else
868                    {
869                            in_uint8s(s, 2);        /* pad */
870                            in_uint16_le(s, size);
871                            in_uint8s(s, 4);        /* line_size, final_size */
872                    }
873                    in_uint8p(s, data, size);
874                    bmpdata = (uint8 *) xmalloc(width * height * Bpp);
875                    if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
876                    {
877                            ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
878                    }
879                    else
880                    {
881                            DEBUG_RDP5(("Failed to decompress data\n"));
882                  }                  }
883    
884                  xfree(rawdata);                  xfree(bmpdata);
885          }          }
886  }  }
887    
888  /* Process a palette update */  /* Process a palette update */
889  static void process_palette(STREAM s)  void
890    process_palette(STREAM s)
891  {  {
892          HCOLOURMAP hmap;          COLOURENTRY *entry;
893          COLOURMAP map;          COLOURMAP map;
894            HCOLOURMAP hmap;
895            int i;
896    
897            in_uint8s(s, 2);        /* pad */
898            in_uint16_le(s, map.ncolours);
899            in_uint8s(s, 2);        /* pad */
900    
901            map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
902    
903            DEBUG(("PALETTE(c=%d)\n", map.ncolours));
904    
905          in_uint8s(s, 2); /* pad */          for (i = 0; i < map.ncolours; i++)
906          in_uint16_le(s, map.ncolours);          {
907          in_uint8s(s, 2); /* pad */                  entry = &map.colours[i];
908          in_uint8p(s, (uint8 *)map.colours, (map.ncolours * 3));                  in_uint8(s, entry->red);
909                    in_uint8(s, entry->green);
910                    in_uint8(s, entry->blue);
911            }
912    
913          hmap = ui_create_colourmap(&map);          hmap = ui_create_colourmap(&map);
914          ui_set_colourmap(hmap);          ui_set_colourmap(hmap);
915    
916            xfree(map.colours);
917  }  }
918    
919  /* Process an update PDU */  /* Process an update PDU */
920  static void process_update_pdu(STREAM s)  static void
921    process_update_pdu(STREAM s)
922  {  {
923          uint16 update_type;          uint16 update_type, count;
924    
925          in_uint16_le(s, update_type);          in_uint16_le(s, update_type);
926    
927          switch (update_type)          switch (update_type)
928          {          {
929                  case RDP_UPDATE_ORDERS:                  case RDP_UPDATE_ORDERS:
930                          process_orders(s);                          in_uint8s(s, 2);        /* pad */
931                            in_uint16_le(s, count);
932                            in_uint8s(s, 2);        /* pad */
933                            process_orders(s, count);
934                          break;                          break;
935    
936                  case RDP_UPDATE_BITMAP:                  case RDP_UPDATE_BITMAP:
# Line 562  static void process_update_pdu(STREAM s) Line 945  static void process_update_pdu(STREAM s)
945                          break;                          break;
946    
947                  default:                  default:
948                          NOTIMP("update %d\n", update_type);                          unimpl("update %d\n", update_type);
949          }          }
950    
951  }  }
952    
953    /* Process a disconnect PDU */
954    void
955    process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
956    {
957            in_uint32_le(s, *ext_disc_reason);
958    
959            DEBUG(("Received disconnect PDU\n"));
960    }
961    
962  /* Process data PDU */  /* Process data PDU */
963  static void process_data_pdu(STREAM s)  static BOOL
964    process_data_pdu(STREAM s, uint32 * ext_disc_reason)
965  {  {
966          uint8 data_pdu_type;          uint8 data_pdu_type;
967            uint8 ctype;
968            uint16 clen;
969            uint32 len;
970    
971            uint32 roff, rlen;
972    
973          in_uint8s(s, 8); /* shareid, pad, streamid, length */          struct stream *ns = &(g_mppc_dict.ns);
974    
975            in_uint8s(s, 6);        /* shareid, pad, streamid */
976            in_uint16(s, len);
977          in_uint8(s, data_pdu_type);          in_uint8(s, data_pdu_type);
978          in_uint8s(s, 3); /* compress_type, compress_len */          in_uint8(s, ctype);
979            in_uint16(s, clen);
980            clen -= 18;
981    
982            if (ctype & RDP_MPPC_COMPRESSED)
983            {
984    
985                    if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
986                            error("error while decompressing packet\n");
987    
988                    //len -= 18;
989    
990                    /* allocate memory and copy the uncompressed data into the temporary stream */
991                    ns->data = xrealloc(ns->data, rlen);
992    
993                    memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
994    
995                    ns->size = rlen;
996                    ns->end = (ns->data + ns->size);
997                    ns->p = ns->data;
998                    ns->rdp_hdr = ns->p;
999    
1000                    s = ns;
1001            }
1002    
1003          switch (data_pdu_type)          switch (data_pdu_type)
1004          {          {
# Line 582  static void process_data_pdu(STREAM s) Line 1006  static void process_data_pdu(STREAM s)
1006                          process_update_pdu(s);                          process_update_pdu(s);
1007                          break;                          break;
1008    
1009                    case RDP_DATA_PDU_CONTROL:
1010                            DEBUG(("Received Control PDU\n"));
1011                            break;
1012    
1013                    case RDP_DATA_PDU_SYNCHRONISE:
1014                            DEBUG(("Received Sync PDU\n"));
1015                            break;
1016    
1017                  case RDP_DATA_PDU_POINTER:                  case RDP_DATA_PDU_POINTER:
1018                          process_pointer_pdu(s);                          process_pointer_pdu(s);
1019                          break;                          break;
# Line 591  static void process_data_pdu(STREAM s) Line 1023  static void process_data_pdu(STREAM s)
1023                          break;                          break;
1024    
1025                  case RDP_DATA_PDU_LOGON:                  case RDP_DATA_PDU_LOGON:
1026                            DEBUG(("Received Logon PDU\n"));
1027                          /* User logged on */                          /* User logged on */
1028                          break;                          break;
1029    
1030                    case RDP_DATA_PDU_DISCONNECT:
1031                            process_disconnect_pdu(s, ext_disc_reason);
1032                            return True;
1033    
1034                  default:                  default:
1035                          NOTIMP("data PDU %d\n", data_pdu_type);                          unimpl("data PDU %d\n", data_pdu_type);
1036          }          }
1037            return False;
1038  }  }
1039    
1040  /* Process incoming packets */  /* Process incoming packets */
1041  void rdp_main_loop()  void
1042    rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1043  {  {
1044          uint8 type;          uint8 type;
1045            BOOL disc = False;      /* True when a disconnect PDU was received */
1046          STREAM s;          STREAM s;
1047    
1048          while ((s = rdp_recv(&type)) != NULL)          while ((s = rdp_recv(&type)) != NULL)
# Line 611  void rdp_main_loop() Line 1051  void rdp_main_loop()
1051                  {                  {
1052                          case RDP_PDU_DEMAND_ACTIVE:                          case RDP_PDU_DEMAND_ACTIVE:
1053                                  process_demand_active(s);                                  process_demand_active(s);
1054                                    *deactivated = False;
1055                                  break;                                  break;
1056    
1057                          case RDP_PDU_DEACTIVATE:                          case RDP_PDU_DEACTIVATE:
1058                                    DEBUG(("RDP_PDU_DEACTIVATE\n"));
1059                                    *deactivated = True;
1060                                  break;                                  break;
1061    
1062                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1063                                  process_data_pdu(s);                                  disc = process_data_pdu(s, ext_disc_reason);
1064                                    break;
1065    
1066                            case 0:
1067                                  break;                                  break;
1068    
1069                          default:                          default:
1070                                  NOTIMP("PDU %d\n", type);                                  unimpl("PDU %d\n", type);
1071                    }
1072    
1073                    if (disc)
1074                    {
1075                            return;
1076                  }                  }
1077          }          }
1078            return;
1079  }  }
1080    
1081  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */
1082  BOOL rdp_connect(char *server)  BOOL
1083    rdp_connect(char *server, uint32 flags, char *domain, char *password,
1084                char *command, char *directory)
1085  {  {
1086          if (!sec_connect(server))          if (!sec_connect(server, g_username))
1087                  return False;                  return False;
1088    
1089          rdp_send_logon_info(0x33, "", username, "", "", "");          rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1090          return True;          return True;
1091  }  }
1092    
1093  /* Disconnect from the RDP layer */  /* Disconnect from the RDP layer */
1094  void rdp_disconnect()  void
1095    rdp_disconnect(void)
1096  {  {
1097          sec_disconnect();          sec_disconnect();
1098  }  }
   

Legend:
Removed from v.10  
changed lines
  Added in v.708

  ViewVC Help
Powered by ViewVC 1.1.26