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

Legend:
Removed from v.24  
changed lines
  Added in v.828

  ViewVC Help
Powered by ViewVC 1.1.26