/[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 717 by astrand, Thu Jun 17 09:42:58 2004 UTC
# Line 2  Line 2 
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-2002
5      
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.     GNU General Public License for more details.
15      
16     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
21    #include <time.h>
22  #include "rdesktop.h"  #include "rdesktop.h"
23    
24  extern uint16 mcs_userid;  extern uint16 g_mcs_userid;
25  extern char username[16];  extern char g_username[16];
26  extern BOOL bitmap_compression;  extern BOOL g_bitmap_compression;
27  extern BOOL orders;  extern BOOL g_orders;
28  extern BOOL encryption;  extern BOOL g_encryption;
29  extern BOOL desktop_save;  extern BOOL g_desktop_save;
30  extern BOOL use_rdp5;  extern BOOL g_use_rdp5;
31  extern uint16 server_rdp_version;  extern uint16 g_server_rdp_version;
32    extern uint32 g_rdp5_performanceflags;
33    extern int g_server_bpp;
34    extern int g_width;
35    extern int g_height;
36    extern BOOL g_bitmap_cache;
37    
38  uint8 *next_packet;  uint8 *g_next_packet;
39  uint32 rdp_shareid;  uint32 g_rdp_shareid;
40    
41    extern RDPCOMP g_mppc_dict;
42    
43  #if WITH_DEBUG  #if WITH_DEBUG
44  static uint32 packetno;  static uint32 g_packetno;
45  #endif  #endif
46    
47  /* Receive an RDP packet */  /* Receive an RDP packet */
# Line 43  rdp_recv(uint8 * type) Line 51  rdp_recv(uint8 * type)
51          static STREAM rdp_s;          static STREAM rdp_s;
52          uint16 length, pdu_type;          uint16 length, pdu_type;
53    
54          if ((rdp_s == NULL) || (next_packet >= rdp_s->end))          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))
55          {          {
56                  rdp_s = sec_recv();                  rdp_s = sec_recv();
57                  if (rdp_s == NULL)                  if (rdp_s == NULL)
58                          return NULL;                          return NULL;
59    
60                  next_packet = rdp_s->p;                  g_next_packet = rdp_s->p;
61          }          }
62          else          else
63          {          {
64                  rdp_s->p = next_packet;                  rdp_s->p = g_next_packet;
65          }          }
66    
67          in_uint16_le(rdp_s, length);          in_uint16_le(rdp_s, length);
68          /* 32k packets are really 8, keepalive fix */          /* 32k packets are really 8, keepalive fix */
69          if (length == 0x8000)          if (length == 0x8000)
70          {          {
71                  next_packet += 8;                  g_next_packet += 8;
72                  *type = 0;                  *type = 0;
73                  return rdp_s;                  return rdp_s;
74          }          }
# Line 69  rdp_recv(uint8 * type) Line 77  rdp_recv(uint8 * type)
77          *type = pdu_type & 0xf;          *type = pdu_type & 0xf;
78    
79  #if WITH_DEBUG  #if WITH_DEBUG
80          DEBUG(("RDP packet #%d, (type %x)\n", ++packetno, *type));          DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type));
81          //      hexdump(next_packet, length);          hexdump(g_next_packet, length);
82  #endif /*  */  #endif /*  */
83    
84          next_packet += length;          g_next_packet += length;
85          return rdp_s;          return rdp_s;
86  }  }
87    
# Line 83  rdp_init_data(int maxlen) Line 91  rdp_init_data(int maxlen)
91  {  {
92          STREAM s;          STREAM s;
93    
94          s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 18);          s = sec_init(g_encryption ? SEC_ENCRYPT : 0, maxlen + 18);
95          s_push_layer(s, rdp_hdr, 18);          s_push_layer(s, rdp_hdr, 18);
96    
97          return s;          return s;
# Line 100  rdp_send_data(STREAM s, uint8 data_pdu_t Line 108  rdp_send_data(STREAM s, uint8 data_pdu_t
108    
109          out_uint16_le(s, length);          out_uint16_le(s, length);
110          out_uint16_le(s, (RDP_PDU_DATA | 0x10));          out_uint16_le(s, (RDP_PDU_DATA | 0x10));
111          out_uint16_le(s, (mcs_userid + 1001));          out_uint16_le(s, (g_mcs_userid + 1001));
112    
113          out_uint32_le(s, rdp_shareid);          out_uint32_le(s, g_rdp_shareid);
114          out_uint8(s, 0);        /* pad */          out_uint8(s, 0);        /* pad */
115          out_uint8(s, 1);        /* streamid */          out_uint8(s, 1);        /* streamid */
116          out_uint16_le(s, (length - 14));          out_uint16_le(s, (length - 14));
# Line 110  rdp_send_data(STREAM s, uint8 data_pdu_t Line 118  rdp_send_data(STREAM s, uint8 data_pdu_t
118          out_uint8(s, 0);        /* compress_type */          out_uint8(s, 0);        /* compress_type */
119          out_uint16(s, 0);       /* compress_len */          out_uint16(s, 0);       /* compress_len */
120    
121          sec_send(s, encryption ? SEC_ENCRYPT : 0);          sec_send(s, g_encryption ? SEC_ENCRYPT : 0);
122  }  }
123    
124  /* Output a string in Unicode */  /* Output a string in Unicode */
# Line 130  rdp_out_unistr(STREAM s, char *string, i Line 138  rdp_out_unistr(STREAM s, char *string, i
138          s->p += len;          s->p += len;
139  }  }
140    
141    /* Input a string in Unicode
142     *
143     * Returns str_len of string
144     */
145    int
146    rdp_in_unistr(STREAM s, char *string, int uni_len)
147    {
148            int i = 0;
149    
150            while (i < uni_len / 2)
151            {
152                    in_uint8a(s, &string[i++], 1);
153                    in_uint8s(s, 1);
154            }
155    
156            return i - 1;
157    }
158    
159    
160  /* Parse a logon info packet */  /* Parse a logon info packet */
161  static void  static void
162  rdp_send_logon_info(uint32 flags, char *domain, char *user,  rdp_send_logon_info(uint32 flags, char *domain, char *user,
163                      char *password, char *program, char *directory)                      char *password, char *program, char *directory)
164  {  {
165            char *ipaddr = tcp_get_address();
166          int len_domain = 2 * strlen(domain);          int len_domain = 2 * strlen(domain);
167          int len_user = 2 * strlen(user);          int len_user = 2 * strlen(user);
168          int len_password = 2 * strlen(password);          int len_password = 2 * strlen(password);
169          int len_program = 2 * strlen(program);          int len_program = 2 * strlen(program);
170          int len_directory = 2 * strlen(directory);          int len_directory = 2 * strlen(directory);
171          uint32 sec_flags = encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;          int len_ip = 2 * strlen(ipaddr);
172            int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
173            int packetlen = 0;
174            uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
175          STREAM s;          STREAM s;
176            time_t t = time(NULL);
177            time_t tzone;
178    
179          if (1 == server_rdp_version)  #if 0
180            /* enable rdp compression */
181            /* some problems still exist with rdp5 */
182            flags |= RDP_COMPRESSION;
183    #endif
184    
185            if (!g_use_rdp5 || 1 == g_server_rdp_version)
186          {          {
187                  DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));                  DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
188    
# Line 165  rdp_send_logon_info(uint32 flags, char * Line 204  rdp_send_logon_info(uint32 flags, char *
204          }          }
205          else          else
206          {          {
207    
208                    flags |= RDP_LOGON_BLOB;
209                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
210                  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 */
211                            4 +     /* flags */
212                            2 +     /* len_domain */
213                            2 +     /* len_user */
214                            (flags & RDP_LOGON_AUTO ? 2 : 0) +      /* len_password */
215                            (flags & RDP_LOGON_BLOB ? 2 : 0) +      /* Length of BLOB */
216                            2 +     /* len_program */
217                            2 +     /* len_directory */
218                            (0 < len_domain ? len_domain : 2) +     /* domain */
219                            len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 +    /* We have no 512 byte BLOB. Perhaps we must? */
220                            (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + /* After the BLOB is a unknown int16. If there is a BLOB, that is. */
221                            (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 +     /* Unknown (2) */
222                            2 +     /* Client ip length */
223                            len_ip +        /* Client ip */
224                            2 +     /* DLL string length */
225                            len_dll +       /* DLL string */
226                            2 +     /* Unknown */
227                            2 +     /* Unknown */
228                            64 +    /* Time zone #0 */
229                            2 +     /* Unknown */
230                            64 +    /* Time zone #1 */
231                            32;     /* Unknown */
232    
233                  out_uint32(s, 0);                  s = sec_init(sec_flags, packetlen);
234                    DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
235    
236                    out_uint32(s, 0);       /* Unknown */
237                  out_uint32_le(s, flags);                  out_uint32_le(s, flags);
238                  out_uint16_le(s, len_domain);                  out_uint16_le(s, len_domain);
239                  out_uint16_le(s, len_user);                  out_uint16_le(s, len_user);
240                  if (flags & RDP_LOGON_AUTO)                  if (flags & RDP_LOGON_AUTO)
241                  {                  {
242                          out_uint16_le(s, len_password);                          out_uint16_le(s, len_password);
243    
244                    }
245                    if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
246                    {
247                            out_uint16_le(s, 0);
248                  }                  }
                 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 */  
249                  out_uint16_le(s, len_program);                  out_uint16_le(s, len_program);
250                  out_uint16_le(s, len_directory);                  out_uint16_le(s, len_directory);
251                    if (0 < len_domain)
252                            rdp_out_unistr(s, domain, len_domain);
253                    else
254                            out_uint16_le(s, 0);
255                    rdp_out_unistr(s, user, len_user);
256                  if (flags & RDP_LOGON_AUTO)                  if (flags & RDP_LOGON_AUTO)
257                  {                  {
258                          rdp_out_unistr(s, password, len_password);                          rdp_out_unistr(s, password, len_password);
259                  }                  }
260                  rdp_out_unistr(s, domain, len_domain);                  if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
261                  rdp_out_unistr(s, user, len_user);                  {
262                  out_uint16(s, 0);                          out_uint16_le(s, 0);
263                  out_uint16(s, 0);                  }
264                  if (0 < len_program)                  if (0 < len_program)
265                    {
266                          rdp_out_unistr(s, program, len_program);                          rdp_out_unistr(s, program, len_program);
267    
268                    }
269                    else
270                    {
271                            out_uint16_le(s, 0);
272                    }
273                  if (0 < len_directory)                  if (0 < len_directory)
274                    {
275                          rdp_out_unistr(s, directory, len_directory);                          rdp_out_unistr(s, directory, len_directory);
276                  out_uint8s(s, 30);      /* Some kind of client data - let's see if the server                  }
277                                             handles zeros well.. */                  else
278                  out_uint16_le(s, 60);                  {
279                  rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", 58);                          out_uint16_le(s, 0);
280                  out_uint32_be(s, 0x88ffffff);                  }
281                  rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid") - 2);                  out_uint16_le(s, 2);
282                  out_uint8s(s, 30 - 2 * strlen("GTP, normaltid"));                  out_uint16_le(s, len_ip + 2);   /* Length of client ip */
283                    rdp_out_unistr(s, ipaddr, len_ip);
284                    out_uint16_le(s, len_dll + 2);
285                    rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
286    
287                    tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
288                    out_uint32_le(s, tzone);
289    
290                    rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
291                    out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
292    
293                  out_uint32_le(s, 0x0a0000);                  out_uint32_le(s, 0x0a0000);
294                  out_uint32_le(s, 0x050000);                  out_uint32_le(s, 0x050000);
295                  out_uint32_le(s, 2);                  out_uint32_le(s, 3);
296                  out_uint32(s, 0);                  out_uint32_le(s, 0);
297                  out_uint32_le(s, 0xffffffc4);                  out_uint32_le(s, 0);
                 out_uint32_le(s, 0xfffffffe);  
                 out_uint32_le(s, 0x0f);  
                 out_uint32(s, 0);  
298    
299                  rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid") - 1);                  rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
300                  out_uint8s(s, 30 - 2 * strlen("GTP, sommartid"));                  out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
301    
302                  out_uint32_le(s, 0x030000);                  out_uint32_le(s, 0x30000);
303                  out_uint32_le(s, 0x050000);                  out_uint32_le(s, 0x050000);
304                  out_uint32_le(s, 2);                  out_uint32_le(s, 2);
305                  out_uint32(s, 0);                  out_uint32(s, 0);
306                  out_uint32_le(s, 0xffffffc4);                  out_uint32_le(s, 0xffffffc4);
307                  out_uint32_le(s, 0xfffffffe);                  out_uint32_le(s, 0xfffffffe);
308                  out_uint32_le(s, 0x0f);                  out_uint32_le(s, g_rdp5_performanceflags);
309                  out_uint32(s, 0);                  out_uint32(s, 0);
310    
311    
312          }          }
313          s_mark_end(s);          s_mark_end(s);
314          sec_send(s, sec_flags);          sec_send(s, sec_flags);
# Line 288  rdp_send_fonts(uint16 seq) Line 375  rdp_send_fonts(uint16 seq)
375          s = rdp_init_data(8);          s = rdp_init_data(8);
376    
377          out_uint16(s, 0);       /* number of fonts */          out_uint16(s, 0);       /* number of fonts */
378          out_uint16_le(s, 0x3e); /* unknown */          out_uint16_le(s, 0);    /* pad? */
379          out_uint16_le(s, seq);  /* unknown */          out_uint16_le(s, seq);  /* unknown */
380          out_uint16_le(s, 0x32); /* entry size */          out_uint16_le(s, 0x32); /* entry size */
381    
# Line 308  rdp_out_general_caps(STREAM s) Line 395  rdp_out_general_caps(STREAM s)
395          out_uint16_le(s, 0x200);        /* Protocol version */          out_uint16_le(s, 0x200);        /* Protocol version */
396          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
397          out_uint16(s, 0);       /* Compression types */          out_uint16(s, 0);       /* Compression types */
398          out_uint16_le(s, use_rdp5 ? 0x40d : 0);          out_uint16_le(s, g_use_rdp5 ? 0x40d : 0);
399          /* Pad, according to T.128. 0x40d seems to          /* Pad, according to T.128. 0x40d seems to
400             trigger             trigger
401             the server to start sending RDP5 packets.             the server to start sending RDP5 packets.
# Line 329  rdp_out_bitmap_caps(STREAM s) Line 416  rdp_out_bitmap_caps(STREAM s)
416          out_uint16_le(s, RDP_CAPSET_BITMAP);          out_uint16_le(s, RDP_CAPSET_BITMAP);
417          out_uint16_le(s, RDP_CAPLEN_BITMAP);          out_uint16_le(s, RDP_CAPLEN_BITMAP);
418    
419          out_uint16_le(s, 8);    /* Preferred BPP */          out_uint16_le(s, g_server_bpp); /* Preferred BPP */
420          out_uint16_le(s, 1);    /* Receive 1 BPP */          out_uint16_le(s, 1);    /* Receive 1 BPP */
421          out_uint16_le(s, 1);    /* Receive 4 BPP */          out_uint16_le(s, 1);    /* Receive 4 BPP */
422          out_uint16_le(s, 1);    /* Receive 8 BPP */          out_uint16_le(s, 1);    /* Receive 8 BPP */
423          out_uint16_le(s, 800);  /* Desktop width */          out_uint16_le(s, 800);  /* Desktop width */
424          out_uint16_le(s, 600);  /* Desktop height */          out_uint16_le(s, 600);  /* Desktop height */
425          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
426          out_uint16(s, 0);       /* Allow resize */          out_uint16(s, 1);       /* Allow resize */
427          out_uint16_le(s, bitmap_compression ? 1 : 0);   /* Support compression */          out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
428          out_uint16(s, 0);       /* Unknown */          out_uint16(s, 0);       /* Unknown */
429          out_uint16_le(s, 1);    /* Unknown */          out_uint16_le(s, 1);    /* Unknown */
430          out_uint16(s, 0);       /* Pad */          out_uint16(s, 0);       /* Pad */
# Line 354  rdp_out_order_caps(STREAM s) Line 441  rdp_out_order_caps(STREAM s)
441          order_caps[0] = 1;      /* dest blt */          order_caps[0] = 1;      /* dest blt */
442          order_caps[1] = 1;      /* pat blt */          order_caps[1] = 1;      /* pat blt */
443          order_caps[2] = 1;      /* screen blt */          order_caps[2] = 1;      /* screen blt */
444          order_caps[3] = 1;      /* required for memblt? */          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
445          order_caps[8] = 1;      /* line */          order_caps[8] = 1;      /* line */
446          order_caps[9] = 1;      /* line */          order_caps[9] = 1;      /* line */
447          order_caps[10] = 1;     /* rect */          order_caps[10] = 1;     /* rect */
448          order_caps[11] = (desktop_save == False ? 0 : 1);       /* desksave */          order_caps[11] = (g_desktop_save == False ? 0 : 1);     /* desksave */
449          order_caps[13] = 1;     /* memblt */          order_caps[13] = 1;     /* memblt */
450          order_caps[14] = 1;     /* triblt */          order_caps[14] = 1;     /* triblt */
451          order_caps[22] = 1;     /* polyline */          order_caps[22] = 1;     /* polyline */
# Line 376  rdp_out_order_caps(STREAM s) Line 463  rdp_out_order_caps(STREAM s)
463          out_uint8p(s, order_caps, 32);  /* Orders supported */          out_uint8p(s, order_caps, 32);  /* Orders supported */
464          out_uint16_le(s, 0x6a1);        /* Text capability flags */          out_uint16_le(s, 0x6a1);        /* Text capability flags */
465          out_uint8s(s, 6);       /* Pad */          out_uint8s(s, 6);       /* Pad */
466          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 */
467          out_uint32(s, 0);       /* Unknown */          out_uint32(s, 0);       /* Unknown */
468          out_uint32_le(s, 0x4e4);        /* Unknown */          out_uint32_le(s, 0x4e4);        /* Unknown */
469  }  }
# Line 385  rdp_out_order_caps(STREAM s) Line 472  rdp_out_order_caps(STREAM s)
472  static void  static void
473  rdp_out_bmpcache_caps(STREAM s)  rdp_out_bmpcache_caps(STREAM s)
474  {  {
475            int Bpp;
476          out_uint16_le(s, RDP_CAPSET_BMPCACHE);          out_uint16_le(s, RDP_CAPSET_BMPCACHE);
477          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
478    
479            Bpp = (g_server_bpp + 7) / 8;
480          out_uint8s(s, 24);      /* unused */          out_uint8s(s, 24);      /* unused */
481          out_uint16_le(s, 0x258);        /* entries */          out_uint16_le(s, 0x258);        /* entries */
482          out_uint16_le(s, 0x100);        /* max cell size */          out_uint16_le(s, 0x100 * Bpp);  /* max cell size */
483          out_uint16_le(s, 0x12c);        /* entries */          out_uint16_le(s, 0x12c);        /* entries */
484          out_uint16_le(s, 0x400);        /* max cell size */          out_uint16_le(s, 0x400 * Bpp);  /* max cell size */
485          out_uint16_le(s, 0x106);        /* entries */          out_uint16_le(s, 0x106);        /* entries */
486          out_uint16_le(s, 0x1000);       /* max cell size */          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
487  }  }
488    
489  /* Output control capability set */  /* Output control capability set */
# Line 494  static void Line 583  static void
583  rdp_send_confirm_active(void)  rdp_send_confirm_active(void)
584  {  {
585          STREAM s;          STREAM s;
586          uint32 sec_flags = encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;          uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
587          uint16 caplen =          uint16 caplen =
588                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
589                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
# Line 505  rdp_send_confirm_active(void) Line 594  rdp_send_confirm_active(void)
594    
595          out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));          out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
596          out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10));      /* Version 1 */          out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10));      /* Version 1 */
597          out_uint16_le(s, (mcs_userid + 1001));          out_uint16_le(s, (g_mcs_userid + 1001));
598    
599          out_uint32_le(s, rdp_shareid);          out_uint32_le(s, g_rdp_shareid);
600          out_uint16_le(s, 0x3ea);        /* userid */          out_uint16_le(s, 0x3ea);        /* userid */
601          out_uint16_le(s, sizeof(RDP_SOURCE));          out_uint16_le(s, sizeof(RDP_SOURCE));
602          out_uint16_le(s, caplen);          out_uint16_le(s, caplen);
# Line 531  rdp_send_confirm_active(void) Line 620  rdp_send_confirm_active(void)
620          sec_send(s, sec_flags);          sec_send(s, sec_flags);
621  }  }
622    
623    /* Process a general capability set */
624    static void
625    rdp_process_general_caps(STREAM s)
626    {
627            uint16 pad2octetsB;     /* rdp5 flags? */
628    
629            in_uint8s(s, 10);
630            in_uint16_le(s, pad2octetsB);
631    
632            if (!pad2octetsB)
633                    g_use_rdp5 = False;
634    }
635    
636    /* Process a bitmap capability set */
637    static void
638    rdp_process_bitmap_caps(STREAM s)
639    {
640            uint16 width, height, bpp;
641    
642            in_uint16_le(s, bpp);
643            in_uint8s(s, 6);
644    
645            in_uint16_le(s, width);
646            in_uint16_le(s, height);
647    
648            DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));
649    
650            /*
651             * The server may limit bpp and change the size of the desktop (for
652             * example when shadowing another session).
653             */
654            if (g_server_bpp != bpp)
655            {
656                    warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
657                    g_server_bpp = bpp;
658            }
659            if (g_width != width || g_height != height)
660            {
661                    warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
662                            width, height);
663                    g_width = width;
664                    g_height = height;
665                    ui_resize_window();
666            }
667    }
668    
669  /* Respond to a demand active PDU */  /* Respond to a demand active PDU */
670  static void  static void
671  process_demand_active(STREAM s)  process_demand_active(STREAM s)
672  {  {
673          uint8 type;          int n;
674            uint8 type, *next;
675            uint16 len_src_descriptor, len_combined_caps, num_capsets, capset_type, capset_length;
676    
677            in_uint32_le(s, g_rdp_shareid);
678            in_uint16_le(s, len_src_descriptor);
679            in_uint16_le(s, len_combined_caps);
680            in_uint8s(s, len_src_descriptor);
681    
682            in_uint16_le(s, num_capsets);
683            in_uint8s(s, 2);        /* pad */
684    
685            DEBUG(("DEMAND_ACTIVE(id=0x%x,num_caps=%d)\n", g_rdp_shareid, num_capsets));
686    
687            for (n = 0; n < num_capsets; n++)
688            {
689                    in_uint16_le(s, capset_type);
690                    in_uint16_le(s, capset_length);
691    
692                    next = s->p + capset_length - 4;
693    
694                    switch (capset_type)
695                    {
696                            case RDP_CAPSET_GENERAL:
697                                    rdp_process_general_caps(s);
698                                    break;
699    
700          in_uint32_le(s, rdp_shareid);                          case RDP_CAPSET_BITMAP:
701                                    rdp_process_bitmap_caps(s);
702                                    break;
703                    }
704    
705          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", rdp_shareid));                  s->p = next;
706            }
707    
708          rdp_send_confirm_active();          rdp_send_confirm_active();
709          rdp_send_synchronise();          rdp_send_synchronise();
# Line 548  process_demand_active(STREAM s) Line 712  process_demand_active(STREAM s)
712          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
713          rdp_recv(&type);        /* RDP_CTL_COOPERATE */          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
714          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
715          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();  
 }  
716    
717  /* Process a null system pointer PDU */          if (g_use_rdp5)
718  void          {
719  process_null_system_pointer_pdu(STREAM s)                  rdp_send_fonts(3);
720  {          }
721          // FIXME: We should probably set another cursor here,          else
722          // like the X window system base cursor or something.          {
723          ui_set_cursor(cache_get_cursor(0));                  rdp_send_fonts(1);
724                    rdp_send_fonts(2);
725            }
726    
727            rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
728            reset_order_state();
729  }  }
730    
731  /* Process a colour pointer PDU */  /* Process a colour pointer PDU */
# Line 596  process_cached_pointer_pdu(STREAM s) Line 760  process_cached_pointer_pdu(STREAM s)
760          ui_set_cursor(cache_get_cursor(cache_idx));          ui_set_cursor(cache_get_cursor(cache_idx));
761  }  }
762    
763    /* Process a system pointer PDU */
764    void
765    process_system_pointer_pdu(STREAM s)
766    {
767            uint16 system_pointer_type;
768    
769            in_uint16(s, system_pointer_type);
770            switch (system_pointer_type)
771            {
772                    case RDP_NULL_POINTER:
773                            ui_set_null_cursor();
774                            break;
775    
776                    default:
777                            unimpl("System pointer message 0x%x\n", system_pointer_type);
778            }
779    }
780    
781  /* Process a pointer PDU */  /* Process a pointer PDU */
782  static void  static void
# Line 624  process_pointer_pdu(STREAM s) Line 805  process_pointer_pdu(STREAM s)
805                          process_cached_pointer_pdu(s);                          process_cached_pointer_pdu(s);
806                          break;                          break;
807    
808                    case RDP_POINTER_SYSTEM:
809                            process_system_pointer_pdu(s);
810                            break;
811    
812                  default:                  default:
813                          DEBUG(("Pointer message 0x%x\n", message_type));                          unimpl("Pointer message 0x%x\n", message_type);
814          }          }
815  }  }
816    
# Line 663  process_bitmap_updates(STREAM s) Line 848  process_bitmap_updates(STREAM s)
848                  if (!compress)                  if (!compress)
849                  {                  {
850                          int y;                          int y;
851                          bmpdata = xmalloc(width * height * Bpp);                          bmpdata = (uint8 *) xmalloc(width * height * Bpp);
852                          for (y = 0; y < height; y++)                          for (y = 0; y < height; y++)
853                          {                          {
854                                  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 871  process_bitmap_updates(STREAM s)
871                          in_uint8s(s, 4);        /* line_size, final_size */                          in_uint8s(s, 4);        /* line_size, final_size */
872                  }                  }
873                  in_uint8p(s, data, size);                  in_uint8p(s, data, size);
874                  bmpdata = xmalloc(width * height * Bpp);                  bmpdata = (uint8 *) xmalloc(width * height * Bpp);
875                  if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))                  if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
876                  {                  {
877                          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 898  process_palette(STREAM s)
898          in_uint16_le(s, map.ncolours);          in_uint16_le(s, map.ncolours);
899          in_uint8s(s, 2);        /* pad */          in_uint8s(s, 2);        /* pad */
900    
901          map.colours = xmalloc(3 * map.ncolours);          map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
902    
903          DEBUG(("PALETTE(c=%d)\n", map.ncolours));          DEBUG(("PALETTE(c=%d)\n", map.ncolours));
904    
# Line 739  process_update_pdu(STREAM s) Line 924  process_update_pdu(STREAM s)
924    
925          in_uint16_le(s, update_type);          in_uint16_le(s, update_type);
926    
927            ui_begin_update();
928          switch (update_type)          switch (update_type)
929          {          {
930                  case RDP_UPDATE_ORDERS:                  case RDP_UPDATE_ORDERS:
# Line 762  process_update_pdu(STREAM s) Line 948  process_update_pdu(STREAM s)
948                  default:                  default:
949                          unimpl("update %d\n", update_type);                          unimpl("update %d\n", update_type);
950          }          }
951            ui_end_update();
952    }
953    
954    /* Process a disconnect PDU */
955    void
956    process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
957    {
958            in_uint32_le(s, *ext_disc_reason);
959    
960            DEBUG(("Received disconnect PDU\n"));
961  }  }
962    
963  /* Process data PDU */  /* Process data PDU */
964  static void  static BOOL
965  process_data_pdu(STREAM s)  process_data_pdu(STREAM s, uint32 * ext_disc_reason)
966  {  {
967          uint8 data_pdu_type;          uint8 data_pdu_type;
968            uint8 ctype;
969            uint16 clen;
970            uint32 len;
971    
972            uint32 roff, rlen;
973    
974            struct stream *ns = &(g_mppc_dict.ns);
975    
976          in_uint8s(s, 8);        /* shareid, pad, streamid, length */          in_uint8s(s, 6);        /* shareid, pad, streamid */
977            in_uint16(s, len);
978          in_uint8(s, data_pdu_type);          in_uint8(s, data_pdu_type);
979          in_uint8s(s, 3);        /* compress_type, compress_len */          in_uint8(s, ctype);
980            in_uint16(s, clen);
981            clen -= 18;
982    
983            if (ctype & RDP_MPPC_COMPRESSED)
984            {
985    
986                    if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
987                            error("error while decompressing packet\n");
988    
989                    //len -= 18;
990    
991                    /* allocate memory and copy the uncompressed data into the temporary stream */
992                    ns->data = (uint8 *) xrealloc(ns->data, rlen);
993    
994                    memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
995    
996                    ns->size = rlen;
997                    ns->end = (ns->data + ns->size);
998                    ns->p = ns->data;
999                    ns->rdp_hdr = ns->p;
1000    
1001                    s = ns;
1002            }
1003    
1004          switch (data_pdu_type)          switch (data_pdu_type)
1005          {          {
# Line 781  process_data_pdu(STREAM s) Line 1007  process_data_pdu(STREAM s)
1007                          process_update_pdu(s);                          process_update_pdu(s);
1008                          break;                          break;
1009    
1010                    case RDP_DATA_PDU_CONTROL:
1011                            DEBUG(("Received Control PDU\n"));
1012                            break;
1013    
1014                    case RDP_DATA_PDU_SYNCHRONISE:
1015                            DEBUG(("Received Sync PDU\n"));
1016                            break;
1017    
1018                  case RDP_DATA_PDU_POINTER:                  case RDP_DATA_PDU_POINTER:
1019                          process_pointer_pdu(s);                          process_pointer_pdu(s);
1020                          break;                          break;
# Line 794  process_data_pdu(STREAM s) Line 1028  process_data_pdu(STREAM s)
1028                          /* User logged on */                          /* User logged on */
1029                          break;                          break;
1030    
1031                    case RDP_DATA_PDU_DISCONNECT:
1032                            process_disconnect_pdu(s, ext_disc_reason);
1033                            return True;
1034    
1035                  default:                  default:
1036                          unimpl("data PDU %d\n", data_pdu_type);                          unimpl("data PDU %d\n", data_pdu_type);
1037          }          }
1038            return False;
1039  }  }
1040    
1041  /* Process incoming packets */  /* Process incoming packets */
1042  void  void
1043  rdp_main_loop(void)  rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1044  {  {
1045          uint8 type;          uint8 type;
1046            BOOL disc = False;      /* True when a disconnect PDU was received */
1047          STREAM s;          STREAM s;
1048    
1049          while ((s = rdp_recv(&type)) != NULL)          while ((s = rdp_recv(&type)) != NULL)
# Line 812  rdp_main_loop(void) Line 1052  rdp_main_loop(void)
1052                  {                  {
1053                          case RDP_PDU_DEMAND_ACTIVE:                          case RDP_PDU_DEMAND_ACTIVE:
1054                                  process_demand_active(s);                                  process_demand_active(s);
1055                                    *deactivated = False;
1056                                  break;                                  break;
1057    
1058                          case RDP_PDU_DEACTIVATE:                          case RDP_PDU_DEACTIVATE:
1059                                    DEBUG(("RDP_PDU_DEACTIVATE\n"));
1060                                    *deactivated = True;
1061                                  break;                                  break;
1062    
1063                          case RDP_PDU_DATA:                          case RDP_PDU_DATA:
1064                                  process_data_pdu(s);                                  disc = process_data_pdu(s, ext_disc_reason);
1065                                  break;                                  break;
1066    
1067                          case 0:                          case 0:
# Line 827  rdp_main_loop(void) Line 1070  rdp_main_loop(void)
1070                          default:                          default:
1071                                  unimpl("PDU %d\n", type);                                  unimpl("PDU %d\n", type);
1072                  }                  }
1073    
1074                    if (disc)
1075                    {
1076                            return;
1077                    }
1078          }          }
1079            return;
1080    }
1081    
1082    /* used in uiports, processes the rdp packets waiting */
1083    BOOL
1084    rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1085    {
1086            uint8 type;
1087            BOOL disc = False;      /* True when a disconnect PDU was received */
1088            BOOL cont = True;
1089            STREAM s;
1090    
1091            while (cont)
1092            {
1093                    s = rdp_recv(&type);
1094                    if (s == NULL)
1095                            return False;
1096                    switch (type)
1097                    {
1098                            case RDP_PDU_DEMAND_ACTIVE:
1099                                    process_demand_active(s);
1100                                    *deactivated = False;
1101                                    break;
1102                            case RDP_PDU_DEACTIVATE:
1103                                    DEBUG(("RDP_PDU_DEACTIVATE\n"));
1104                                    *deactivated = True;
1105                                    break;
1106                            case RDP_PDU_DATA:
1107                                    disc = process_data_pdu(s, ext_disc_reason);
1108                                    break;
1109                            case 0:
1110                                    break;
1111                            default:
1112                                    unimpl("PDU %d\n", type);
1113                    }
1114                    if (disc)
1115                            return False;
1116                    cont = g_next_packet < s->end;
1117            }
1118            return True;
1119  }  }
1120    
1121  /* Establish a connection up to the RDP layer */  /* Establish a connection up to the RDP layer */
# Line 835  BOOL Line 1123  BOOL
1123  rdp_connect(char *server, uint32 flags, char *domain, char *password,  rdp_connect(char *server, uint32 flags, char *domain, char *password,
1124              char *command, char *directory)              char *command, char *directory)
1125  {  {
1126          if (!sec_connect(server, username))          if (!sec_connect(server, g_username))
1127                  return False;                  return False;
1128    
1129          rdp_send_logon_info(flags, domain, username, password, command, directory);          rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1130          return True;          return True;
1131  }  }
1132    

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

  ViewVC Help
Powered by ViewVC 1.1.26