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

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

  ViewVC Help
Powered by ViewVC 1.1.26