/[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 687 by n-ki, Fri Apr 30 06:18:08 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  unsigned char *next_packet;  extern BOOL g_encryption;
29  uint32 rdp_shareid;  extern BOOL g_desktop_save;
30    extern BOOL g_use_rdp5;
31  /* Initialise an RDP packet */  extern uint16 g_server_rdp_version;
32  static STREAM rdp_init(int maxlen)  extern uint32 g_rdp5_performanceflags;
33  {  extern int g_server_bpp;
34          STREAM s;  extern int g_width;
35    extern int g_height;
36          s = sec_init(SEC_ENCRYPT, maxlen + 6);  extern BOOL g_bitmap_cache;
         s_push_layer(s, rdp_hdr, 6);  
   
         return s;  
 }  
   
 /* Send an RDP packet */  
 static void rdp_send(STREAM s, uint8 pdu_type)  
 {  
         uint16 length;  
37    
38          s_pop_layer(s, rdp_hdr);  uint8 *g_next_packet;
39          length = s->end - s->p;  uint32 g_rdp_shareid;
40    
41          out_uint16_le(s, length);  extern RDPCOMP g_mppc_dict;
         out_uint16_le(s, (pdu_type | 0x10)); /* Version 1 */  
         out_uint16_le(s, (mcs_userid + 1001));  
42    
43          sec_send(s, SEC_ENCRYPT);  #if WITH_DEBUG
44  }  static uint32 g_packetno;
45    #endif
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
190                                 + len_program + len_directory + 10);
191    
192                    out_uint32(s, 0);
193                    out_uint32_le(s, flags);
194                    out_uint16_le(s, len_domain);
195                    out_uint16_le(s, len_user);
196                    out_uint16_le(s, len_password);
197                    out_uint16_le(s, len_program);
198                    out_uint16_le(s, len_directory);
199                    rdp_out_unistr(s, domain, len_domain);
200                    rdp_out_unistr(s, user, len_user);
201                    rdp_out_unistr(s, password, len_password);
202                    rdp_out_unistr(s, program, len_program);
203                    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          s = sec_init(sec_flags, 18 + len_domain + len_user + len_password                  }
269                                          + len_program + len_directory + 10);                  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    
         out_uint32(s, 0);  
         out_uint32_le(s, flags);  
         out_uint16_le(s, len_domain);  
         out_uint16_le(s, len_user);  
         out_uint16_le(s, len_password);  
         out_uint16_le(s, len_program);  
         out_uint16_le(s, len_directory);  
         rdp_out_unistr(s, domain,    len_domain);  
         rdp_out_unistr(s, user,      len_user);  
         rdp_out_unistr(s, password,  len_password);  
         rdp_out_unistr(s, program,   len_program);  
         rdp_out_unistr(s, directory, len_directory);  
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          s = rdp_init(14 + caplen + sizeof(RDP_SOURCE));                  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          out_uint32_le(s, rdp_shareid);          out_uint32_le(s, g_rdp_shareid);
600          out_uint16_le(s, 0x3ea); /* userid */          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            g_server_bpp = bpp;
655            g_width = width;
656            g_height = height;
657    
658            ui_resize_window();
659  }  }
660    
661  /* Respond to a demand active PDU */  /* Respond to a demand active PDU */
662  static void process_demand_active(STREAM s)  static void
663    process_demand_active(STREAM s)
664  {  {
665          uint8 type;          int n;
666            uint8 type, *next;
667            uint16 len_src_descriptor, len_combined_caps, num_capsets, capset_type, capset_length;
668    
669          in_uint32_le(s, rdp_shareid);          in_uint32_le(s, g_rdp_shareid);
670            in_uint16_le(s, len_src_descriptor);
671            in_uint16_le(s, len_combined_caps);
672            in_uint8s(s, len_src_descriptor);
673    
674          DEBUG("DEMAND_ACTIVE(id=0x%x)\n", rdp_shareid);          in_uint16_le(s, num_capsets);
675            in_uint8s(s, 2);        /* pad */
676    
677            DEBUG(("DEMAND_ACTIVE(id=0x%x,num_caps=%d)\n", g_rdp_shareid, num_capsets));
678    
679            for (n = 0; n < num_capsets; n++)
680            {
681                    in_uint16_le(s, capset_type);
682                    in_uint16_le(s, capset_length);
683    
684                    next = s->p + capset_length - 4;
685    
686                    switch (capset_type)
687                    {
688                            case RDP_CAPSET_GENERAL:
689                                    rdp_process_general_caps(s);
690                                    break;
691    
692                            case RDP_CAPSET_BITMAP:
693                                    rdp_process_bitmap_caps(s);
694                                    break;
695                    }
696    
697                    s->p = next;
698            }
699    
700          rdp_send_confirm_active();          rdp_send_confirm_active();
701          rdp_send_synchronise();          rdp_send_synchronise();
702          rdp_send_control(RDP_CTL_COOPERATE);          rdp_send_control(RDP_CTL_COOPERATE);
703          rdp_send_control(RDP_CTL_REQUEST_CONTROL);          rdp_send_control(RDP_CTL_REQUEST_CONTROL);
704          rdp_recv(&type); // RDP_PDU_SYNCHRONIZE          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
705          rdp_recv(&type); // RDP_CTL_COOPERATE          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
706          rdp_recv(&type); // RDP_CTL_GRANT_CONTROL          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
707          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);
708          rdp_send_fonts(1);  
709          rdp_send_fonts(2);          if (g_use_rdp5)
710          rdp_recv(&type); // RDP_PDU_UNKNOWN 0x28          {
711                    rdp_send_fonts(3);
712            }
713            else
714            {
715                    rdp_send_fonts(1);
716                    rdp_send_fonts(2);
717            }
718    
719            rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
720          reset_order_state();          reset_order_state();
721  }  }
722    
723    /* Process a colour pointer PDU */
724    void
725    process_colour_pointer_pdu(STREAM s)
726    {
727            uint16 x, y, width, height, cache_idx, masklen, datalen;
728            uint8 *mask, *data;
729            HCURSOR cursor;
730    
731            in_uint16_le(s, cache_idx);
732            in_uint16_le(s, x);
733            in_uint16_le(s, y);
734            in_uint16_le(s, width);
735            in_uint16_le(s, height);
736            in_uint16_le(s, masklen);
737            in_uint16_le(s, datalen);
738            in_uint8p(s, data, datalen);
739            in_uint8p(s, mask, masklen);
740            cursor = ui_create_cursor(x, y, width, height, mask, data);
741            ui_set_cursor(cursor);
742            cache_put_cursor(cache_idx, cursor);
743    }
744    
745    /* Process a cached pointer PDU */
746    void
747    process_cached_pointer_pdu(STREAM s)
748    {
749            uint16 cache_idx;
750    
751            in_uint16_le(s, cache_idx);
752            ui_set_cursor(cache_get_cursor(cache_idx));
753    }
754    
755    /* Process a system pointer PDU */
756    void
757    process_system_pointer_pdu(STREAM s)
758    {
759            uint16 system_pointer_type;
760    
761            in_uint16(s, system_pointer_type);
762            switch (system_pointer_type)
763            {
764                    case RDP_NULL_POINTER:
765                            ui_set_null_cursor();
766                            break;
767    
768                    default:
769                            unimpl("System pointer message 0x%x\n", system_pointer_type);
770            }
771    }
772    
773  /* Process a pointer PDU */  /* Process a pointer PDU */
774  static void process_pointer_pdu(STREAM s)  static void
775    process_pointer_pdu(STREAM s)
776  {  {
777          uint16 message_type;          uint16 message_type;
778          uint16 x, y;          uint16 x, y;
779    
780          in_uint16_le(s, message_type);          in_uint16_le(s, message_type);
781          in_uint8s(s, 2); /* pad */          in_uint8s(s, 2);        /* pad */
782    
783          switch (message_type)          switch (message_type)
784          {          {
# Line 465  static void process_pointer_pdu(STREAM s Line 789  static void process_pointer_pdu(STREAM s
789                                  ui_move_pointer(x, y);                                  ui_move_pointer(x, y);
790                          break;                          break;
791    
792                    case RDP_POINTER_COLOR:
793                            process_colour_pointer_pdu(s);
794                            break;
795    
796                    case RDP_POINTER_CACHED:
797                            process_cached_pointer_pdu(s);
798                            break;
799    
800                    case RDP_POINTER_SYSTEM:
801                            process_system_pointer_pdu(s);
802                            break;
803    
804                  default:                  default:
805                          DEBUG("Pointer message 0x%x\n", message_type);                          unimpl("Pointer message 0x%x\n", message_type);
806          }          }
807  }  }
808    
809  /* Process bitmap updates */  /* Process bitmap updates */
810  static void process_bitmap_updates(STREAM s)  void
811    process_bitmap_updates(STREAM s)
812  {  {
813          uint16 num_updates;          uint16 num_updates;
814          uint16 left, top, right, bottom, width, height;          uint16 left, top, right, bottom, width, height;
815          uint16 cx, cy, bpp, compress, bufsize, size;          uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
816          uint8 *data, *rawdata;          uint8 *data, *bmpdata;
817          int i;          int i;
818    
819          in_uint16_le(s, num_updates);          in_uint16_le(s, num_updates);
# Line 490  static void process_bitmap_updates(STREA Line 827  static void process_bitmap_updates(STREA
827                  in_uint16_le(s, width);                  in_uint16_le(s, width);
828                  in_uint16_le(s, height);                  in_uint16_le(s, height);
829                  in_uint16_le(s, bpp);                  in_uint16_le(s, bpp);
830                    Bpp = (bpp + 7) / 8;
831                  in_uint16_le(s, compress);                  in_uint16_le(s, compress);
832                  in_uint16_le(s, bufsize);                  in_uint16_le(s, bufsize);
833    
834                  cx = right - left + 1;                  cx = right - left + 1;
835                  cy = bottom - top + 1;                  cy = bottom - top + 1;
836    
837                  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",
838                          left, top, right, bottom, width, height, compress);                         left, top, right, bottom, width, height, Bpp, compress));
839    
840                  if (!compress)                  if (!compress)
841                  {                  {
842                          in_uint8p(s, data, bufsize);                          int y;
843                          ui_paint_bitmap(left, top, cx, cy, width, height, data);                          bmpdata = (uint8 *) xmalloc(width * height * Bpp);
844                          return;                          for (y = 0; y < height; y++)
845                            {
846                                    in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
847                                              width * Bpp);
848                            }
849                            ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
850                            xfree(bmpdata);
851                            continue;
852                  }                  }
853    
                 in_uint8s(s, 2); /* pad */  
                 in_uint16_le(s, size);  
                 in_uint8s(s, 4); /* line_size, final_size */  
                 in_uint8p(s, data, size);  
854    
855                  rawdata = xmalloc(width * height);                  if (compress & 0x400)
856                  if (bitmap_decompress(rawdata, width, height, data, size))                  {
857                            size = bufsize;
858                    }
859                    else
860                  {                  {
861                          ui_paint_bitmap(left, top, cx, cy, width, height,                          in_uint8s(s, 2);        /* pad */
862                                          rawdata);                          in_uint16_le(s, size);
863                            in_uint8s(s, 4);        /* line_size, final_size */
864                    }
865                    in_uint8p(s, data, size);
866                    bmpdata = (uint8 *) xmalloc(width * height * Bpp);
867                    if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
868                    {
869                            ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
870                    }
871                    else
872                    {
873                            DEBUG_RDP5(("Failed to decompress data\n"));
874                  }                  }
875    
876                  xfree(rawdata);                  xfree(bmpdata);
877          }          }
878  }  }
879    
880  /* Process a palette update */  /* Process a palette update */
881  static void process_palette(STREAM s)  void
882    process_palette(STREAM s)
883  {  {
884          HCOLOURMAP hmap;          COLOURENTRY *entry;
885          COLOURMAP map;          COLOURMAP map;
886            HCOLOURMAP hmap;
887            int i;
888    
889            in_uint8s(s, 2);        /* pad */
890            in_uint16_le(s, map.ncolours);
891            in_uint8s(s, 2);        /* pad */
892    
893            map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
894    
895          in_uint8s(s, 2); /* pad */          DEBUG(("PALETTE(c=%d)\n", map.ncolours));
896          in_uint16_le(s, map.ncolours);  
897          in_uint8s(s, 2); /* pad */          for (i = 0; i < map.ncolours; i++)
898          in_uint8p(s, (uint8 *)map.colours, (map.ncolours * 3));          {
899                    entry = &map.colours[i];
900                    in_uint8(s, entry->red);
901                    in_uint8(s, entry->green);
902                    in_uint8(s, entry->blue);
903            }
904    
905          hmap = ui_create_colourmap(&map);          hmap = ui_create_colourmap(&map);
906          ui_set_colourmap(hmap);          ui_set_colourmap(hmap);
907    
908            xfree(map.colours);
909  }  }
910    
911  /* Process an update PDU */  /* Process an update PDU */
912  static void process_update_pdu(STREAM s)  static void
913    process_update_pdu(STREAM s)
914  {  {
915          uint16 update_type;          uint16 update_type, count;
916    
917          in_uint16_le(s, update_type);          in_uint16_le(s, update_type);
918    
919          switch (update_type)          switch (update_type)
920          {          {
921                  case RDP_UPDATE_ORDERS:                  case RDP_UPDATE_ORDERS:
922                          process_orders(s);                          in_uint8s(s, 2);        /* pad */
923                            in_uint16_le(s, count);
924                            in_uint8s(s, 2);        /* pad */
925                            process_orders(s, count);
926                          break;                          break;
927    
928                  case RDP_UPDATE_BITMAP:                  case RDP_UPDATE_BITMAP:
# Line 562  static void process_update_pdu(STREAM s) Line 937  static void process_update_pdu(STREAM s)
937                          break;                          break;
938    
939                  default:                  default:
940                          NOTIMP("update %d\n", update_type);                          unimpl("update %d\n", update_type);
941          }          }
942    
943  }  }
944    
945    /* Process a disconnect PDU */
946    void
947    process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
948    {
949            in_uint32_le(s, *ext_disc_reason);
950    
951            DEBUG(("Received disconnect PDU\n"));
952    }
953    
954  /* Process data PDU */  /* Process data PDU */
955  static void process_data_pdu(STREAM s)  static BOOL
956    process_data_pdu(STREAM s, uint32 * ext_disc_reason)
957  {  {
958          uint8 data_pdu_type;          uint8 data_pdu_type;
959            uint8 ctype;
960            uint16 clen;
961            uint32 len;
962    
963            uint32 roff, rlen;
964    
965            struct stream *ns = &(g_mppc_dict.ns);
966    
967          in_uint8s(s, 8); /* shareid, pad, streamid, length */          in_uint8s(s, 6);        /* shareid, pad, streamid */
968            in_uint16(s, len);
969          in_uint8(s, data_pdu_type);          in_uint8(s, data_pdu_type);
970          in_uint8s(s, 3); /* compress_type, compress_len */          in_uint8(s, ctype);
971            in_uint16(s, clen);
972            clen -= 18;
973    
974            if (ctype & RDP_MPPC_COMPRESSED)
975            {
976    
977                    if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
978                            error("error while decompressing packet\n");
979    
980                    //len -= 18;
981    
982                    /* allocate memory and copy the uncompressed data into the temporary stream */
983                    ns->data = xrealloc(ns->data, rlen);
984    
985                    memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
986    
987                    ns->size = rlen;
988                    ns->end = (ns->data + ns->size);
989                    ns->p = ns->data;
990                    ns->rdp_hdr = ns->p;
991    
992                    s = ns;
993            }
994    
995          switch (data_pdu_type)          switch (data_pdu_type)
996          {          {
# Line 582  static void process_data_pdu(STREAM s) Line 998  static void process_data_pdu(STREAM s)
998                          process_update_pdu(s);                          process_update_pdu(s);
999                          break;                          break;
1000    
1001                    case RDP_DATA_PDU_CONTROL:
1002                            DEBUG(("Received Control PDU\n"));
1003                            break;
1004    
1005                    case RDP_DATA_PDU_SYNCHRONISE:
1006                            DEBUG(("Received Sync PDU\n"));
1007                            break;
1008    
1009                  case RDP_DATA_PDU_POINTER:                  case RDP_DATA_PDU_POINTER:
1010                          process_pointer_pdu(s);                          process_pointer_pdu(s);
1011                          break;                          break;
# Line 591  static void process_data_pdu(STREAM s) Line 1015  static void process_data_pdu(STREAM s)
1015                          break;                          break;
1016    
1017                  case RDP_DATA_PDU_LOGON:                  case RDP_DATA_PDU_LOGON:
1018                            DEBUG(("Received Logon PDU\n"));
1019                          /* User logged on */                          /* User logged on */
1020                          break;                          break;
1021    
1022                    case RDP_DATA_PDU_DISCONNECT:
1023                            process_disconnect_pdu(s, ext_disc_reason);
1024                            return True;
1025    
1026                  default:                  default:
1027                          NOTIMP("data PDU %d\n", data_pdu_type);                          unimpl("data PDU %d\n", data_pdu_type);
1028          }          }
1029            return False;
1030  }  }
1031    
1032  /* Process incoming packets */  /* Process incoming packets */
1033  void rdp_main_loop()  void
1034    rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1035  {  {
1036          uint8 type;          uint8 type;
1037            BOOL disc = False;      /* True when a disconnect PDU was received */
1038          STREAM s;          STREAM s;
1039    
1040          while ((s = rdp_recv(&type)) != NULL)          while ((s = rdp_recv(&type)) != NULL)
# Line 611  void rdp_main_loop() Line 1043  void rdp_main_loop()
1043                  {                  {
1044                          case RDP_PDU_DEMAND_ACTIVE:                          case RDP_PDU_DEMAND_ACTIVE:
1045                                  process_demand_active(s);                                  process_demand_active(s);
1046                                    *deactivated = False;
1047                                  break;                                  break;
1048    
1049                          case RDP_PDU_DEACTIVATE:                          case RDP_PDU_DEACTIVATE:
1050                                    DEBUG(("RDP_PDU_DEACTIVATE\n"));
1051                                    *deactivated = True;
1052                                  break;                                  break;
1053    
1054                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1055                                  process_data_pdu(s);                                  disc = process_data_pdu(s, ext_disc_reason);
1056                                    break;
1057    
1058                            case 0:
1059                                  break;                                  break;
1060    
1061                          default:                          default:
1062                                  NOTIMP("PDU %d\n", type);                                  unimpl("PDU %d\n", type);
1063                    }
1064    
1065                    if (disc)
1066                    {
1067                            return;
1068                  }                  }
1069          }          }
1070            return;
1071  }  }
1072    
1073  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */
1074  BOOL rdp_connect(char *server)  BOOL
1075    rdp_connect(char *server, uint32 flags, char *domain, char *password,
1076                char *command, char *directory)
1077  {  {
1078          if (!sec_connect(server))          if (!sec_connect(server, g_username))
1079                  return False;                  return False;
1080    
1081          rdp_send_logon_info(0x33, "", username, "", "", "");          rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1082          return True;          return True;
1083  }  }
1084    
1085  /* Disconnect from the RDP layer */  /* Disconnect from the RDP layer */
1086  void rdp_disconnect()  void
1087    rdp_disconnect(void)
1088  {  {
1089          sec_disconnect();          sec_disconnect();
1090  }  }
   

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

  ViewVC Help
Powered by ViewVC 1.1.26