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

Legend:
Removed from v.21  
changed lines
  Added in v.863

  ViewVC Help
Powered by ViewVC 1.1.26