/[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 365 by matthewc, Wed Apr 16 08:19:15 2003 UTC revision 863 by stargo, Mon Mar 14 17:47:46 2005 UTC
# Line 1  Line 1 
1  /* -*- c-basic-offset: 8 -*-  /* -*- 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-2002     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 bitmap_compression;  #include <iconv.h>
29  extern BOOL orders;  #endif
30  extern BOOL encryption;  
31  extern BOOL desktop_save;  #ifndef ICONV_CONST
32  extern BOOL use_rdp5;  #define ICONV_CONST ""
33  extern uint16 server_rdp_version;  #endif
34    #endif
35    
36  uint8 *next_packet;  extern uint16 g_mcs_userid;
37  uint32 rdp_shareid;  extern char g_username[64];
38    extern char g_codepage[16];
39    extern BOOL g_bitmap_compression;
40    extern BOOL g_orders;
41    extern BOOL g_encryption;
42    extern BOOL g_desktop_save;
43    extern BOOL g_polygon_ellipse_orders;
44    extern BOOL g_use_rdp5;
45    extern uint16 g_server_rdp_version;
46    extern uint32 g_rdp5_performanceflags;
47    extern int g_server_bpp;
48    extern int g_width;
49    extern int g_height;
50    extern BOOL g_bitmap_cache;
51    extern BOOL g_bitmap_cache_persist_enable;
52    
53    uint8 *g_next_packet;
54    uint32 g_rdp_shareid;
55    
56    extern RDPCOMP g_mppc_dict;
57    
58  #if WITH_DEBUG  #if WITH_DEBUG
59  static uint32 packetno;  static uint32 g_packetno;
60  #endif  #endif
61    
62  /* Receive an RDP packet */  /* Receive an RDP packet */
# Line 42  rdp_recv(uint8 * type) Line 65  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 */          /* 32k packets are really 8, keepalive fix */
98          if (length == 0x8000)          if (length == 0x8000)
99          {          {
100                  next_packet += 8;                  g_next_packet += 8;
101                  *type = 0;                  *type = 0;
102                  return rdp_s;                  return rdp_s;
103          }          }
# Line 69  rdp_recv(uint8 * type) Line 106  rdp_recv(uint8 * type)
106          *type = pdu_type & 0xf;          *type = pdu_type & 0xf;
107    
108  #if WITH_DEBUG  #if WITH_DEBUG
109          DEBUG(("RDP packet #%d, (type %x)\n", ++packetno, *type));          DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type));
110          //      hexdump(next_packet, length);          hexdump(g_next_packet, length);
111  #endif /*  */  #endif /*  */
112    
113          next_packet += length;          g_next_packet += length;
114          return rdp_s;          return rdp_s;
115  }  }
116    
# Line 83  rdp_init_data(int maxlen) Line 120  rdp_init_data(int maxlen)
120  {  {
121          STREAM s;          STREAM s;
122    
123          s = sec_init(encryption ? SEC_ENCRYPT : 0, 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;
# Line 100  rdp_send_data(STREAM s, uint8 data_pdu_t Line 137  rdp_send_data(STREAM s, uint8 data_pdu_t
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_le(s, (length - 14));          out_uint16_le(s, (length - 14));
# Line 110  rdp_send_data(STREAM s, uint8 data_pdu_t Line 147  rdp_send_data(STREAM s, uint8 data_pdu_t
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, encryption ? SEC_ENCRYPT : 0);          sec_send(s, g_encryption ? SEC_ENCRYPT : 0);
151  }  }
152    
153  /* Output a string in Unicode */  /* Output a string in Unicode */
154  void  void
155  rdp_out_unistr(STREAM s, char *string, int len)  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 128  rdp_out_unistr(STREAM s, char *string, i Line 203  rdp_out_unistr(STREAM s, char *string, i
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  static void
255  rdp_send_logon_info(uint32 flags, char *domain, char *user,  rdp_send_logon_info(uint32 flags, char *domain, char *user,
256                      char *password, char *program, char *directory)                      char *password, char *program, char *directory)
257  {  {
258            char *ipaddr = tcp_get_address();
259          int len_domain = 2 * strlen(domain);          int len_domain = 2 * strlen(domain);
260          int len_user = 2 * strlen(user);          int len_user = 2 * strlen(user);
261          int len_password = 2 * strlen(password);          int len_password = 2 * strlen(password);
262          int len_program = 2 * strlen(program);          int len_program = 2 * strlen(program);
263          int len_directory = 2 * strlen(directory);          int len_directory = 2 * strlen(directory);
264          uint32 sec_flags = encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;          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 (1 == server_rdp_version)          if (!g_use_rdp5 || 1 == g_server_rdp_version)
279          {          {
280                  DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));                  DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
281    
# Line 165  rdp_send_logon_info(uint32 flags, char * Line 297  rdp_send_logon_info(uint32 flags, char *
297          }          }
298          else          else
299          {          {
300    
301                    flags |= RDP_LOGON_BLOB;
302                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
303                  s = sec_init(sec_flags, 12 + (flags & RDP_LOGON_AUTO ? 2 : 0) + 6 + (flags & RDP_LOGON_AUTO ? len_password : 0) + len_domain + len_user + 4 + len_program + len_directory + 30 + 2 + 60 + 32 + 20 + 32 + 20);   /* Phew! */                  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                  out_uint32(s, 0);                  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);                  out_uint32_le(s, flags);
331                  out_uint16_le(s, len_domain);                  out_uint16_le(s, len_domain);
332                  out_uint16_le(s, len_user);                  out_uint16_le(s, len_user);
333                  if (flags & RDP_LOGON_AUTO)                  if (flags & RDP_LOGON_AUTO)
334                  {                  {
335                          out_uint16_le(s, len_password);                          out_uint16_le(s, len_password);
336    
337                    }
338                    if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
339                    {
340                            out_uint16_le(s, 0);
341                  }                  }
                 out_uint16(s, 0);       /* Seems to be length of a 512 byte blob with  
                                            completely unknown data, but hopefully we'll do  
                                            with a 0 length block as well */  
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                    if (0 < len_domain)
345                            rdp_out_unistr(s, domain, len_domain);
346                    else
347                            out_uint16_le(s, 0);
348                    rdp_out_unistr(s, user, len_user);
349                  if (flags & RDP_LOGON_AUTO)                  if (flags & RDP_LOGON_AUTO)
350                  {                  {
351                          rdp_out_unistr(s, password, len_password);                          rdp_out_unistr(s, password, len_password);
352                  }                  }
353                  rdp_out_unistr(s, domain, len_domain);                  if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
354                  rdp_out_unistr(s, user, len_user);                  {
355                  out_uint16(s, 0);                          out_uint16_le(s, 0);
356                  out_uint16(s, 0);                  }
357                  if (0 < len_program)                  if (0 < len_program)
358                    {
359                          rdp_out_unistr(s, program, len_program);                          rdp_out_unistr(s, program, len_program);
360    
361                    }
362                    else
363                    {
364                            out_uint16_le(s, 0);
365                    }
366                  if (0 < len_directory)                  if (0 < len_directory)
367                    {
368                          rdp_out_unistr(s, directory, len_directory);                          rdp_out_unistr(s, directory, len_directory);
369                  out_uint8s(s, 30);      /* Some kind of client data - let's see if the server                  }
370                                             handles zeros well.. */                  else
371                  out_uint16_le(s, 60);                  {
372                  rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", 58);                          out_uint16_le(s, 0);
373                  out_uint32_be(s, 0x88ffffff);                  }
374                  rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid") - 2);                  out_uint16_le(s, 2);
375                  out_uint8s(s, 30 - 2 * strlen("GTP, normaltid"));                  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);                  out_uint32_le(s, 0x0a0000);
387                  out_uint32_le(s, 0x050000);                  out_uint32_le(s, 0x050000);
388                  out_uint32_le(s, 2);                  out_uint32_le(s, 3);
389                  out_uint32(s, 0);                  out_uint32_le(s, 0);
390                  out_uint32_le(s, 0xffffffc4);                  out_uint32_le(s, 0);
                 out_uint32_le(s, 0xfffffffe);  
                 out_uint32_le(s, 0x0f);  
                 out_uint32(s, 0);  
391    
392                  rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid") - 1);                  rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
393                  out_uint8s(s, 30 - 2 * strlen("GTP, sommartid"));                  out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
394    
395                  out_uint32_le(s, 0x030000);                  out_uint32_le(s, 0x30000);
396                  out_uint32_le(s, 0x050000);                  out_uint32_le(s, 0x050000);
397                  out_uint32_le(s, 2);                  out_uint32_le(s, 2);
398                  out_uint32(s, 0);                  out_uint32(s, 0);
399                  out_uint32_le(s, 0xffffffc4);                  out_uint32_le(s, 0xffffffc4);
400                  out_uint32_le(s, 0xfffffffe);                  out_uint32_le(s, 0xfffffffe);
401                  out_uint32_le(s, 0x0f);                  out_uint32_le(s, g_rdp5_performanceflags);
402                  out_uint32(s, 0);                  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);
# Line 279  rdp_send_input(uint32 time, uint16 messa Line 459  rdp_send_input(uint32 time, uint16 messa
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  static void
508  rdp_send_fonts(uint16 seq)  rdp_send_fonts(uint16 seq)
# Line 288  rdp_send_fonts(uint16 seq) Line 512  rdp_send_fonts(uint16 seq)
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 308  rdp_out_general_caps(STREAM s) Line 532  rdp_out_general_caps(STREAM s)
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_le(s, use_rdp5 ? 0x40d : 0);          out_uint16_le(s, g_use_rdp5 ? 0x40d : 0);
536          /* Pad, according to T.128. 0x40d seems to          /* Pad, according to T.128. 0x40d seems to
537             trigger             trigger
538             the server to start sending RDP5 packets.             the server to start sending RDP5 packets.
# Line 329  rdp_out_bitmap_caps(STREAM s) Line 553  rdp_out_bitmap_caps(STREAM s)
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_le(s, 1);    /* Receive 1 BPP */          out_uint16_le(s, 1);    /* Receive 1 BPP */
558          out_uint16_le(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, bitmap_compression ? 1 : 0);   /* 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 */
# Line 349  rdp_out_order_caps(STREAM s) Line 573  rdp_out_order_caps(STREAM s)
573  {  {
574          uint8 order_caps[32];          uint8 order_caps[32];
575    
   
576          memset(order_caps, 0, 32);          memset(order_caps, 0, 32);
577          order_caps[0] = 1;      /* dest blt */          order_caps[0] = 1;      /* dest blt */
578          order_caps[1] = 1;      /* pat blt */          order_caps[1] = 1;      /* pat blt */
579          order_caps[2] = 1;      /* screen blt */          order_caps[2] = 1;      /* screen blt */
580          order_caps[3] = 1;      /* required for memblt? */          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
581            order_caps[4] = 0;      /* triblt */
582          order_caps[8] = 1;      /* line */          order_caps[8] = 1;      /* line */
583          order_caps[9] = 1;      /* line */          order_caps[9] = 1;      /* line */
584          order_caps[10] = 1;     /* rect */          order_caps[10] = 1;     /* rect */
585          order_caps[11] = (desktop_save == False ? 0 : 1);       /* desksave */          order_caps[11] = (g_desktop_save ? 1 : 0);      /* desksave */
586          order_caps[13] = 1;     /* memblt */          order_caps[13] = 1;     /* memblt */
587          order_caps[14] = 1;     /* triblt */          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 */          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 */          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);
# Line 376  rdp_out_order_caps(STREAM s) Line 604  rdp_out_order_caps(STREAM s)
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_le(s, desktop_save == False ? 0 : 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_le(s, 0x4e4);        /* Unknown */          out_uint32_le(s, 0x4e4);        /* Unknown */
610  }  }
# Line 385  rdp_out_order_caps(STREAM s) Line 613  rdp_out_order_caps(STREAM s)
613  static void  static void
614  rdp_out_bmpcache_caps(STREAM s)  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            Bpp = (g_server_bpp + 7) / 8;
621          out_uint8s(s, 24);      /* unused */          out_uint8s(s, 24);      /* unused */
622          out_uint16_le(s, 0x258);        /* entries */          out_uint16_le(s, 0x258);        /* entries */
623          out_uint16_le(s, 0x100);        /* max cell size */          out_uint16_le(s, 0x100 * Bpp);  /* max cell size */
624          out_uint16_le(s, 0x12c);        /* entries */          out_uint16_le(s, 0x12c);        /* entries */
625          out_uint16_le(s, 0x400);        /* max cell size */          out_uint16_le(s, 0x400 * Bpp);  /* max cell size */
626          out_uint16_le(s, 0x106);        /* entries */          out_uint16_le(s, 0x106);        /* entries */
627          out_uint16_le(s, 0x1000);       /* max cell size */          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 */
# Line 456  rdp_out_colcache_caps(STREAM s) Line 710  rdp_out_colcache_caps(STREAM s)
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,          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
716          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,
718          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,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
720          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
721          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
722          0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
723          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
724          0x0C, 0x00, 0x08, 0x00, 0x01,          0x00, 0x00, 0x00, 0x00
         0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,  
         0x10, 0x00, 0x34, 0x00, 0xFE,  
         0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,  
         0xFE, 0x00, 0x08, 0x00, 0xFE,  
         0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,  
         0xFE, 0x00, 0x80, 0x00, 0xFE,  
         0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,  
         0x02, 0x00, 0x00, 0x00  
725  };  };
726    
727  /* Output unknown capability sets (number 13, 12, 14 and 16) */  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
728    
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  static void
742  rdp_out_unknown_caps(STREAM s)  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  #define RDP5_FLAG 0x0030
# Line 494  static void Line 753  static void
753  rdp_send_confirm_active(void)  rdp_send_confirm_active(void)
754  {  {
755          STREAM s;          STREAM s;
756          uint32 sec_flags = encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;          uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
757          uint16 caplen =          uint16 caplen =
758                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
759                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
760                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +                  RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
761                  RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;                  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));          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
766    
767          out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));          out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
768          out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10));      /* Version 1 */          out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10));      /* Version 1 */
769          out_uint16_le(s, (mcs_userid + 1001));          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);
# Line 519  rdp_send_confirm_active(void) Line 780  rdp_send_confirm_active(void)
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          sec_send(s, sec_flags);          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  static void
885  process_demand_active(STREAM s)  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();
# Line 548  process_demand_active(STREAM s) Line 902  process_demand_active(STREAM s)
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);
         rdp_send_fonts(1);  
         rdp_send_fonts(2);  
         rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 */  
         reset_order_state();  
 }  
906    
907  /* Process a null system pointer PDU */          if (g_use_rdp5)
908  void          {
909  process_null_system_pointer_pdu(STREAM s)                  rdp_enum_bmpcache2();
910  {                  rdp_send_fonts(3);
911          // FIXME: We should probably set another cursor here,          }
912          // like the X window system base cursor or something.          else
913          ui_set_cursor(cache_get_cursor(0));          {
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();
920  }  }
921    
922  /* Process a colour pointer PDU */  /* Process a colour pointer PDU */
# Line 596  process_cached_pointer_pdu(STREAM s) Line 951  process_cached_pointer_pdu(STREAM s)
951          ui_set_cursor(cache_get_cursor(cache_idx));          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  static void
# Line 624  process_pointer_pdu(STREAM s) Line 996  process_pointer_pdu(STREAM s)
996                          process_cached_pointer_pdu(s);                          process_cached_pointer_pdu(s);
997                          break;                          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    
# Line 663  process_bitmap_updates(STREAM s) Line 1039  process_bitmap_updates(STREAM s)
1039                  if (!compress)                  if (!compress)
1040                  {                  {
1041                          int y;                          int y;
1042                          bmpdata = xmalloc(width * height * Bpp);                          bmpdata = (uint8 *) xmalloc(width * height * Bpp);
1043                          for (y = 0; y < height; y++)                          for (y = 0; y < height; y++)
1044                          {                          {
1045                                  in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],                                  in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
# Line 686  process_bitmap_updates(STREAM s) Line 1062  process_bitmap_updates(STREAM s)
1062                          in_uint8s(s, 4);        /* line_size, final_size */                          in_uint8s(s, 4);        /* line_size, final_size */
1063                  }                  }
1064                  in_uint8p(s, data, size);                  in_uint8p(s, data, size);
1065                  bmpdata = xmalloc(width * height * Bpp);                  bmpdata = (uint8 *) xmalloc(width * height * Bpp);
1066                  if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))                  if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
1067                  {                  {
1068                          ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);                          ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
# Line 713  process_palette(STREAM s) Line 1089  process_palette(STREAM s)
1089          in_uint16_le(s, map.ncolours);          in_uint16_le(s, map.ncolours);
1090          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
1091    
1092          map.colours = xmalloc(3 * map.ncolours);          map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
1093    
1094          DEBUG(("PALETTE(c=%d)\n", map.ncolours));          DEBUG(("PALETTE(c=%d)\n", map.ncolours));
1095    
# Line 739  process_update_pdu(STREAM s) Line 1115  process_update_pdu(STREAM s)
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:
# Line 762  process_update_pdu(STREAM s) Line 1139  process_update_pdu(STREAM s)
1139                  default:                  default:
1140                          unimpl("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  static BOOL
1156  process_data_pdu(STREAM s)  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 781  process_data_pdu(STREAM s) Line 1199  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 794  process_data_pdu(STREAM s) Line 1220  process_data_pdu(STREAM s)
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                          unimpl("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    /* nevers gets out of here till app is done */
1235  void  void
1236  rdp_main_loop(void)  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;                                  break;
   
1269                          case 0:                          case 0:
1270                                  break;                                  break;
   
1271                          default:                          default:
1272                                  unimpl("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 */
# Line 835  BOOL Line 1283  BOOL
1283  rdp_connect(char *server, uint32 flags, char *domain, char *password,  rdp_connect(char *server, uint32 flags, char *domain, char *password,
1284              char *command, char *directory)              char *command, char *directory)
1285  {  {
1286          if (!sec_connect(server, username))          if (!sec_connect(server, g_username))
1287                  return False;                  return False;
1288    
1289          rdp_send_logon_info(flags, domain, username, password, command, directory);          rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1290          return True;          return True;
1291  }  }
1292    

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

  ViewVC Help
Powered by ViewVC 1.1.26