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

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

  ViewVC Help
Powered by ViewVC 1.1.26