/[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 7 by matty, Fri Jul 7 09:40:03 2000 UTC revision 889 by jdmeijer, Sun Apr 17 23:14:20 2005 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
2     rdesktop: A Remote Desktop Protocol client.     rdesktop: A Remote Desktop Protocol client.
3     Protocol services - RDP layer     Protocol services - RDP layer
4     Copyright (C) Matthew Chapman 1999-2000     Copyright (C) Matthew Chapman 1999-2005
5      
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.     GNU General Public License for more details.
15      
16     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  */  */
20    
21  #include "includes.h"  #include <time.h>
22    #include <errno.h>
23    #include <unistd.h>
24    #include "rdesktop.h"
25    
26    #ifdef HAVE_ICONV
27    #ifdef HAVE_ICONV_H
28    #include <iconv.h>
29    #endif
30    
31  /* Establish a connection up to the RDP layer */  #ifndef ICONV_CONST
32  HCONN rdp_connect(char *server)  #define ICONV_CONST ""
33  {  #endif
34          HCONN conn;  #endif
         RDP_ACTIVE_PDU active;  
         uint8 type;  
35    
36          if ((conn = mcs_connect(server)) == NULL)  extern uint16 g_mcs_userid;
37                  return NULL;  extern char g_username[64];
38    extern char g_codepage[16];
39    extern BOOL g_bitmap_compression;
40    extern BOOL g_orders;
41    extern BOOL g_encryption;
42    extern BOOL g_desktop_save;
43    extern BOOL g_polygon_ellipse_orders;
44    extern BOOL g_use_rdp5;
45    extern uint16 g_server_rdp_version;
46    extern uint32 g_rdp5_performanceflags;
47    extern int g_server_bpp;
48    extern int g_width;
49    extern int g_height;
50    extern BOOL g_bitmap_cache;
51    extern BOOL g_bitmap_cache_persist_enable;
52    extern BOOL g_rdp_compression;
53    
54          rdp_establish_key(conn);  uint8 *g_next_packet;
55          mcs_recv(conn, False); /* Server's licensing certificate */  uint32 g_rdp_shareid;
         rdp_send_cert(conn);  
         mcs_recv(conn, False);  
         mcs_recv(conn, False); /* Demand active */  
   
         if (!rdp_recv_pdu(conn, &type) || (type != RDP_PDU_DEMAND_ACTIVE))  
         {  
                 fprintf(stderr, "RDP error, expected Demand Active\n");  
                 mcs_disconnect(conn);  
                 return NULL;  
         }  
   
         rdp_io_active_pdu(&conn->in, &active, RDP_PDU_DEMAND_ACTIVE);  
         rdp_send_confirm_active(conn);  
         rdp_send_synchronize(conn);  
         rdp_send_control(conn, RDP_CTL_COOPERATE);  
         rdp_send_control(conn, RDP_CTL_REQUEST_CONTROL);  
         rdp_recv_pdu(conn, &type); // RDP_PDU_SYNCHRONIZE  
         rdp_recv_pdu(conn, &type); // RDP_CTL_COOPERATE  
         rdp_recv_pdu(conn, &type); // RDP_CTL_GRANT_CONTROL  
         rdp_send_input(conn);  
         rdp_send_fonts(conn, 1);  
         rdp_send_fonts(conn, 2);  
         rdp_recv_pdu(conn, &type); // RDP_PDU_UNKNOWN 0x28  
56    
57          return conn;  extern RDPCOMP g_mppc_dict;
 }  
58    
59  void rdp_main_loop(HCONN conn)  #if WITH_DEBUG
60  {  static uint32 g_packetno;
61          RDP_DATA_HEADER hdr;  #endif
         RDP_ORDER_STATE os;  
         uint8 type;  
62    
63          memset(&os, 0, sizeof(os));  #ifdef HAVE_ICONV
64    static BOOL g_iconv_works = True;
65    #endif
66    
67          while (rdp_recv_pdu(conn, &type))  /* Receive an RDP packet */
68          {  static STREAM
69                  if (type != RDP_PDU_DATA)  rdp_recv(uint8 * type)
70    {
71            static STREAM rdp_s;
72            uint16 length, pdu_type;
73            uint8 rdpver;
74    
75            if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))
76            {
77                    rdp_s = sec_recv(&rdpver);
78                    if (rdp_s == NULL)
79                            return NULL;
80                    if (rdpver == 0xff)
81                  {                  {
82                          fprintf(stderr, "Unknown PDU 0x%x\n", type);                          g_next_packet = rdp_s->end;
83                          continue;                          *type = 0;
84                            return rdp_s;
85                  }                  }
86                    else if (rdpver != 3)
                 rdp_io_data_header(&conn->in, &hdr);  
   
                 switch (hdr.data_pdu_type)  
87                  {                  {
88                          case RDP_DATA_PDU_UPDATE:                          /* rdp5_process should move g_next_packet ok */
89                                  process_update(conn, &os);                          rdp5_process(rdp_s);
90                                  break;                          *type = 0;
91                            return rdp_s;
92                    }
93    
94                          case RDP_DATA_PDU_POINTER:                  g_next_packet = rdp_s->p;
95                                  process_pointer(conn);          }
96                                  break;          else
97            {
98                    rdp_s->p = g_next_packet;
99            }
100    
101                          default:          in_uint16_le(rdp_s, length);
102                                  fprintf(stderr, "Unknown data PDU 0x%x\n",          /* 32k packets are really 8, keepalive fix */
103                                                  hdr.data_pdu_type);          if (length == 0x8000)
104                  }          {
105                    g_next_packet += 8;
106                    *type = 0;
107                    return rdp_s;
108          }          }
109            in_uint16_le(rdp_s, pdu_type);
110            in_uint8s(rdp_s, 2);    /* userid */
111            *type = pdu_type & 0xf;
112    
113    #if WITH_DEBUG
114            DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type));
115            hexdump(g_next_packet, length);
116    #endif /*  */
117    
118            g_next_packet += length;
119            return rdp_s;
120  }  }
121    
122  void process_memblt(HCONN conn, RDP_ORDER_STATE *os, BOOL delta)  /* Initialise an RDP data packet */
123    static STREAM
124    rdp_init_data(int maxlen)
125  {  {
126          HBITMAP hbitmap;          STREAM s;
         uint16 present;  
         lsb_io_uint16(&conn->in, &present);  
127    
128          if (present & 1)          s = sec_init(g_encryption ? SEC_ENCRYPT : 0, maxlen + 18);
129                  prs_io_uint8(&conn->in, &os->memblt.cache_id);          s_push_layer(s, rdp_hdr, 18);
130    
131          if (present & 2)          return s;
132                  rdp_io_coord(&conn->in, &os->memblt.x, delta);  }
133    
134          if (present & 4)  /* Send an RDP data packet */
135                  rdp_io_coord(&conn->in, &os->memblt.y, delta);  static void
136    rdp_send_data(STREAM s, uint8 data_pdu_type)
137    {
138            uint16 length;
139    
140          if (present & 8)          s_pop_layer(s, rdp_hdr);
141                  rdp_io_coord(&conn->in, &os->memblt.cx, delta);          length = s->end - s->p;
142    
143          if (present & 16)          out_uint16_le(s, length);
144                  rdp_io_coord(&conn->in, &os->memblt.cy, delta);          out_uint16_le(s, (RDP_PDU_DATA | 0x10));
145            out_uint16_le(s, (g_mcs_userid + 1001));
146    
147          if (present & 32)          out_uint32_le(s, g_rdp_shareid);
148                  prs_io_uint8(&conn->in, &os->memblt.opcode);          out_uint8(s, 0);        /* pad */
149            out_uint8(s, 1);        /* streamid */
150            out_uint16_le(s, (length - 14));
151            out_uint8(s, data_pdu_type);
152            out_uint8(s, 0);        /* compress_type */
153            out_uint16(s, 0);       /* compress_len */
154    
155          if (present & 256)          sec_send(s, g_encryption ? SEC_ENCRYPT : 0);
156                  lsb_io_uint16(&conn->in, &os->memblt.cache_idx);  }
157    
158          if (os->memblt.opcode != 0xcc) /* SRCCOPY */  /* Output a string in Unicode */
159          {  void
160                  fprintf(stderr, "Unsupported raster operation 0x%x\n",  rdp_out_unistr(STREAM s, char *string, int len)
161                          os->memblt.opcode);  {
162                  return;  #ifdef HAVE_ICONV
163          }          size_t ibl = strlen(string), obl = len + 2;
164            static iconv_t iconv_h = (iconv_t) - 1;
165            char *pin = string, *pout = (char *) s->p;
166    
167            memset(pout, 0, len + 4);
168    
169          if ((os->memblt.cache_idx > NUM_ELEMENTS(conn->bmpcache))          if (g_iconv_works)
             || ((hbitmap = conn->bmpcache[os->memblt.cache_idx]) == NULL))  
170          {          {
171                  fprintf(stderr, "Bitmap %d not found\n", os->memblt.cache_idx);                  if (iconv_h == (iconv_t) - 1)
172                  return;                  {
173          }                          size_t i = 1, o = 4;
174                            if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1)
175                            {
176                                    warning("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n",
177                                            g_codepage, WINDOWS_CODEPAGE, (int) iconv_h);
178    
179          fprintf(stderr, "MEMBLT %d:%dx%d\n", os->memblt.cache_idx,                                  g_iconv_works = False;
180                                          os->memblt.x, os->memblt.y);                                  rdp_out_unistr(s, string, len);
181                                    return;
182                            }
183                            if (iconv(iconv_h, (ICONV_CONST char **) &pin, &i, &pout, &o) ==
184                                (size_t) - 1)
185                            {
186                                    iconv_close(iconv_h);
187                                    iconv_h = (iconv_t) - 1;
188                                    warning("rdp_out_unistr: iconv(1) fail, errno %d\n", errno);
189    
190          ui_paint_bitmap(conn->wnd, hbitmap, os->memblt.x, os->memblt.y);                                  g_iconv_works = False;
191  }                                  rdp_out_unistr(s, string, len);
192                                    return;
193                            }
194                            pin = string;
195                            pout = (char *) s->p;
196                    }
197    
198  void process_opaque_rect(HCONN conn, RDP_ORDER_STATE *os, BOOL delta)                  if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
199  {                  {
200          uint8 present;                          iconv_close(iconv_h);
201          prs_io_uint8(&conn->in, &present);                          iconv_h = (iconv_t) - 1;
202                            warning("rdp_out_unistr: iconv(2) fail, errno %d\n", errno);
203    
204          if (present & 1)                          g_iconv_works = False;
205                  rdp_io_coord(&conn->in, &os->opaque_rect.x, delta);                          rdp_out_unistr(s, string, len);
206                            return;
207                    }
208    
209          if (present & 2)                  s->p += len + 2;
                 rdp_io_coord(&conn->in, &os->opaque_rect.y, delta);  
210    
211          if (present & 4)          }
212                  rdp_io_coord(&conn->in, &os->opaque_rect.cx, delta);          else
213    #endif
214            {
215                    int i = 0, j = 0;
216    
217          if (present & 8)                  len += 2;
                 rdp_io_coord(&conn->in, &os->opaque_rect.cy, delta);  
218    
219          if (present & 16)                  while (i < len)
220                  prs_io_uint8(&conn->in, &os->opaque_rect.colour);                  {
221                            s->p[i++] = string[j++];
222                            s->p[i++] = 0;
223                    }
224    
225          fprintf(stderr, "Opaque rectangle at %d, %d\n", os->opaque_rect.x, os->opaque_rect.y);                  s->p += len;
226          ui_draw_rectangle(conn->wnd, os->opaque_rect.x, os->opaque_rect.y,          }
                                 os->opaque_rect.cx, os->opaque_rect.cy);  
227  }  }
228    
229  void process_bmpcache(HCONN conn)  /* Input a string in Unicode
230     *
231     * Returns str_len of string
232     */
233    int
234    rdp_in_unistr(STREAM s, char *string, int uni_len)
235  {  {
236          RDP_BITMAP_HEADER rbh;  #ifdef HAVE_ICONV
237          HBITMAP *entry;          size_t ibl = uni_len, obl = uni_len;
238          char *input, *bmpdata;          char *pin = (char *) s->p, *pout = string;
239            static iconv_t iconv_h = (iconv_t) - 1;
240    
241          rdp_io_bitmap_header(&conn->in, &rbh);          if (g_iconv_works)
242          fprintf(stderr, "BMPCACHE %d:%dx%d\n", rbh.cache_idx,          {
243                                  rbh.width, rbh.height);                  if (iconv_h == (iconv_t) - 1)
244                    {
245                            if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1)
246                            {
247                                    warning("rdp_in_unistr: iconv_open[%s -> %s] fail %d\n",
248                                            WINDOWS_CODEPAGE, g_codepage, (int) iconv_h);
249    
250          input = conn->in.data + conn->in.offset;                                  g_iconv_works = False;
251          conn->in.offset += rbh.size;                                  return rdp_in_unistr(s, string, uni_len);
252  //      dump_data(conn->in.data+conn->in.offset, conn->in.rdp_offset-conn->in.offset);                          }
253                    }
254    
255          bmpdata = malloc(rbh.width * rbh.height);                  if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1)
256          if (!bitmap_decompress(bmpdata, rbh.width, rbh.height, input, rbh.size))                  {
257          {                          iconv_close(iconv_h);
258                  fprintf(stderr, "Decompression failed\n");                          iconv_h = (iconv_t) - 1;
259                  free(bmpdata);                          warning("rdp_in_unistr: iconv fail, errno %d\n", errno);
                 return;  
         }  
260    
261          if (rbh.cache_idx > NUM_ELEMENTS(conn->bmpcache))                          g_iconv_works = False;
262          {                          return rdp_in_unistr(s, string, uni_len);
263                  fprintf(stderr, "Attempted store past end of cache");                  }
264                  return;                  return pout - string;
265          }          }
266            else
267    #endif
268            {
269                    int i = 0;
270    
271          entry = &conn->bmpcache[rbh.cache_idx];                  while (i < uni_len / 2)
272          // if (*entry != NULL)                  {
273          //      ui_destroy_bitmap(conn->wnd, *entry);                          in_uint8a(s, &string[i++], 1);
274                            in_uint8s(s, 1);
275                    }
276    
277          *entry = ui_create_bitmap(conn->wnd, rbh.width, rbh.height, bmpdata);                  return i - 1;
278          //      ui_paint_bitmap(conn->wnd, bmp, x, 0);          }
         //      ui_destroy_bitmap(conn->wnd, bmp);  
279  }  }
280    
 void process_orders(HCONN conn, RDP_ORDER_STATE *os)  
 {  
         uint16 num_orders;  
         int processed = 0;  
         BOOL res = True;  
         BOOL delta;  
         //      unsigned char *p;  
   
         lsb_io_uint16(&conn->in, &num_orders);  
281    
282          conn->in.offset += 2;  /* Parse a logon info packet */
283          //      p = &conn->in.data[conn->in.offset];  static void
284    rdp_send_logon_info(uint32 flags, char *domain, char *user,
285          //      fprintf(stderr, "%02X %02X %02X %02X\n", p[0], p[1], p[2], p[3]);                      char *password, char *program, char *directory)
286    {
287          while ((processed < num_orders) && res)          char *ipaddr = tcp_get_address();
288            int len_domain = 2 * strlen(domain);
289            int len_user = 2 * strlen(user);
290            int len_password = 2 * strlen(password);
291            int len_program = 2 * strlen(program);
292            int len_directory = 2 * strlen(directory);
293            int len_ip = 2 * strlen(ipaddr);
294            int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
295            int packetlen = 0;
296            uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
297            STREAM s;
298            time_t t = time(NULL);
299            time_t tzone;
300    
301            if (!g_use_rdp5 || 1 == g_server_rdp_version)
302            {
303                    DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
304    
305                    s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
306                                 + len_program + len_directory + 10);
307    
308                    out_uint32(s, 0);
309                    out_uint32_le(s, flags);
310                    out_uint16_le(s, len_domain);
311                    out_uint16_le(s, len_user);
312                    out_uint16_le(s, len_password);
313                    out_uint16_le(s, len_program);
314                    out_uint16_le(s, len_directory);
315                    rdp_out_unistr(s, domain, len_domain);
316                    rdp_out_unistr(s, user, len_user);
317                    rdp_out_unistr(s, password, len_password);
318                    rdp_out_unistr(s, program, len_program);
319                    rdp_out_unistr(s, directory, len_directory);
320            }
321            else
322          {          {
                 uint8 order_flags;  
   
                 prs_io_uint8(&conn->in, &order_flags);  
                 fprintf(stderr, "Order flags: 0x%x\n", order_flags);  
323    
324                  if (order_flags == 0x51) /* ?? */                  flags |= RDP_LOGON_BLOB;
325                          return;                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
326                    packetlen = 4 + /* Unknown uint32 */
327                  if (!(order_flags & RDP_ORDER_STANDARD))                          4 +     /* flags */
328                          return;                          2 +     /* len_domain */
329                            2 +     /* len_user */
330                            (flags & RDP_LOGON_AUTO ? 2 : 0) +      /* len_password */
331                            (flags & RDP_LOGON_BLOB ? 2 : 0) +      /* Length of BLOB */
332                            2 +     /* len_program */
333                            2 +     /* len_directory */
334                            (0 < len_domain ? len_domain : 2) +     /* domain */
335                            len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 +    /* We have no 512 byte BLOB. Perhaps we must? */
336                            (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + /* After the BLOB is a unknown int16. If there is a BLOB, that is. */
337                            (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 +     /* Unknown (2) */
338                            2 +     /* Client ip length */
339                            len_ip +        /* Client ip */
340                            2 +     /* DLL string length */
341                            len_dll +       /* DLL string */
342                            2 +     /* Unknown */
343                            2 +     /* Unknown */
344                            64 +    /* Time zone #0 */
345                            2 +     /* Unknown */
346                            64 +    /* Time zone #1 */
347                            32;     /* Unknown */
348    
349                    s = sec_init(sec_flags, packetlen);
350                    DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
351    
352                    out_uint32(s, 0);       /* Unknown */
353                    out_uint32_le(s, flags);
354                    out_uint16_le(s, len_domain);
355                    out_uint16_le(s, len_user);
356                    if (flags & RDP_LOGON_AUTO)
357                    {
358                            out_uint16_le(s, len_password);
359    
360                  if (order_flags & RDP_ORDER_SECONDARY)                  }
361                    if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
362                    {
363                            out_uint16_le(s, 0);
364                    }
365                    out_uint16_le(s, len_program);
366                    out_uint16_le(s, len_directory);
367                    if (0 < len_domain)
368                            rdp_out_unistr(s, domain, len_domain);
369                    else
370                            out_uint16_le(s, 0);
371                    rdp_out_unistr(s, user, len_user);
372                    if (flags & RDP_LOGON_AUTO)
373                    {
374                            rdp_out_unistr(s, password, len_password);
375                    }
376                    if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
377                    {
378                            out_uint16_le(s, 0);
379                    }
380                    if (0 < len_program)
381                  {                  {
382                          RDP_SECONDARY_ORDER rso;                          rdp_out_unistr(s, program, len_program);
383    
                         rdp_io_secondary_order(&conn->in, &rso);  
                         switch (rso.type)  
                         {  
                         case RDP_ORDER_BMPCACHE:  
                                 process_bmpcache(conn);  
                                 break;  
                         default:  
                                 fprintf(stderr, "Unknown secondary order %d\n",  
                                         rso.type);  
                                 return;  
                         }  
384                  }                  }
385                  else                  else
386                  {                  {
387                          if (order_flags & RDP_ORDER_CHANGE)                          out_uint16_le(s, 0);
388                                  prs_io_uint8(&conn->in, &os->order_type);                  }
389                    if (0 < len_directory)
390                    {
391                            rdp_out_unistr(s, directory, len_directory);
392                    }
393                    else
394                    {
395                            out_uint16_le(s, 0);
396                    }
397                    out_uint16_le(s, 2);
398                    out_uint16_le(s, len_ip + 2);   /* Length of client ip */
399                    rdp_out_unistr(s, ipaddr, len_ip);
400                    out_uint16_le(s, len_dll + 2);
401                    rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
402    
403                          delta = order_flags & RDP_ORDER_DELTA;                  tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
404                    out_uint32_le(s, tzone);
405    
406                          switch (os->order_type)                  rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
407                          {                  out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
                         case RDP_ORDER_OPAQUE_RECT:  
                                 process_opaque_rect(conn, os, delta);  
                                 break;  
408    
409                          case RDP_ORDER_MEMBLT:                  out_uint32_le(s, 0x0a0000);
410                                  process_memblt(conn, os, delta);                  out_uint32_le(s, 0x050000);
411                                  break;                  out_uint32_le(s, 3);
412                    out_uint32_le(s, 0);
413                    out_uint32_le(s, 0);
414    
415                    rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
416                    out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
417    
418                    out_uint32_le(s, 0x30000);
419                    out_uint32_le(s, 0x050000);
420                    out_uint32_le(s, 2);
421                    out_uint32(s, 0);
422                    out_uint32_le(s, 0xffffffc4);
423                    out_uint32_le(s, 0xfffffffe);
424                    out_uint32_le(s, g_rdp5_performanceflags);
425                    out_uint32(s, 0);
426    
                         default:  
                                 fprintf(stderr, "Unknown order %d\n", os->order_type);  
                                 return;  
                         }  
                 }  
427    
                 processed++;  
428          }          }
429            s_mark_end(s);
430            sec_send(s, sec_flags);
431  }  }
432    
433  void process_palette(HCONN conn)  /* Send a control PDU */
434    static void
435    rdp_send_control(uint16 action)
436  {  {
437          HCOLORMAP map;          STREAM s;
438          COLORMAP colors;  
439            s = rdp_init_data(8);
440    
441          rdp_io_colormap(&conn->in, &colors);          out_uint16_le(s, action);
442          map = ui_create_colormap(conn->wnd, &colors);          out_uint16(s, 0);       /* userid */
443          ui_set_colormap(conn->wnd, map);          out_uint32(s, 0);       /* control id */
444          // ui_destroy_colormap(map);  
445            s_mark_end(s);
446            rdp_send_data(s, RDP_DATA_PDU_CONTROL);
447  }  }
448    
449  void process_update(HCONN conn, RDP_ORDER_STATE *os)  /* Send a synchronisation PDU */
450    static void
451    rdp_send_synchronise(void)
452  {  {
453          RDP_UPDATE_PDU update;          STREAM s;
454    
455          rdp_io_update_pdu(&conn->in, &update);          s = rdp_init_data(4);
456          switch (update.update_type)  
457          {          out_uint16_le(s, 1);    /* type */
458                  case RDP_UPDATE_ORDERS:          out_uint16_le(s, 1002);
                         process_orders(conn, os);  
                         break;  
                 case RDP_UPDATE_PALETTE:  
                         process_palette(conn);  
                         break;  
                 case RDP_UPDATE_SYNCHRONIZE:  
                         break;  
                 default:  
                         fprintf(stderr, "Unknown update 0x%x\n",  
                                 update.update_type);  
         }  
459    
460            s_mark_end(s);
461            rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);
462  }  }
463    
464  void process_pointer(HCONN conn)  /* Send a single input event */
465    void
466    rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
467  {  {
468          RDP_POINTER ptr;          STREAM s;
469    
470          rdp_io_pointer(&conn->in, &ptr);          s = rdp_init_data(16);
471    
472          switch (ptr.message)          out_uint16_le(s, 1);    /* number of events */
473          {          out_uint16(s, 0);       /* pad */
                 case RDP_POINTER_MOVE:  
                         ui_move_pointer(conn->wnd, ptr.x, ptr.y);  
                         break;  
                 default:  
                         fprintf(stderr, "Unknown pointer message 0x%x\n",  
                                 ptr.message);  
         }  
 }  
   
 /* Work this out later. This is useless anyway when encryption is off. */  
 uint8 precanned_key_packet[] = {  
    0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x00,0x00,  
    0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6c,0x86,  
    0xf7,0x99,0xef,0x60,0xc4,0x49,0x52,0xd0,0xd8,0xea,0xb5,0x4f,0x58,0x19,  
    0x52,0x2a,0x93,0x83,0x57,0x4f,0x4e,0x04,0xde,0x96,0x51,0xab,0x13,0x20,  
    0xd8,0xe5,0x00,0x00,0x00,0x00,0x00,0x00  
 };  
474    
475  /* Create an RC4 key and transfer it to the server */          out_uint32_le(s, time);
476  void rdp_establish_key(HCONN conn)          out_uint16_le(s, message_type);
477  {          out_uint16_le(s, device_flags);
478          mcs_init_data(conn);          out_uint16_le(s, param1);
479          memcpy(conn->out.data + conn->out.offset, precanned_key_packet,          out_uint16_le(s, param2);
                sizeof(precanned_key_packet));  
         conn->out.offset += sizeof(precanned_key_packet);  
         MARK_END(conn->out);  
         mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);  
 }  
   
 /* Horrible horrible certificate stuff. Work out later. */  
 uint8 precanned_cert_packet[] = {  
 0x80,0x00,0x00,0x00,0x12,0x02,0xb4,0x04,0x01,0x00,0x00,  
 0x00,0x00,0x00,0x01,0x02,0x9d,0xa3,0x7a,0x93,0x34,0x7b,0x28,0x37,0x24,0xa0,0x1f,  
 0x61,0x26,0xfd,0x96,0x3a,0x92,0x83,0xf3,0xe9,0x6a,0x2e,0x81,0x7c,0x2c,0xe4,0x72,//  
 0x01,0x18,0xe9,0xa1,0x0f,0x00,0x00,0x48,0x00,0x84,0x23,0x90,0xe6,0xd3,0xf8,0x20,  
 0xdb,0xa8,0x1b,0xb2,0xd0,0x78,0x2c,0x35,0xde,0xe3,0x0e,0x63,0x40,0xca,0xac,0x71,  
 0xc9,0x17,0x49,0x05,0x25,0xeb,0x9b,0xd0,0xa6,0x5c,0x90,0x3e,0x9d,0x4b,0x27,0x01,  
 0x79,0x1c,0x22,0xfb,0x3c,0x2c,0xb9,0x9f,0xf5,0x21,0xf3,0xee,0xd5,0x4d,0x47,0x1c,  
 0x85,0xbe,0x83,0x93,0xe8,0xed,0x8c,0x5c,0x82,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  
 0x00,0x01,0x00,0x10,0x04,0x30,0x82,0x04,0x0c,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,  
 0x0d,0x01,0x07,0x02,0xa0,0x82,0x03,0xfd,0x30,0x82,0x03,0xf9,0x02,0x01,0x01,0x31,  
 0x00,0x30,0x0b,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x07,0x01,0xa0,0x82,  
 0x03,0xe1,0x30,0x82,0x01,0x77,0x30,0x82,0x01,0x25,0xa0,0x03,0x02,0x01,0x02,0x02,  
 0x08,0x01,0xbf,0x06,0x84,0x9d,0xdb,0x2d,0xe0,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,  
 0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x30,0x38,0x31,0x36,0x30,0x11,0x06,0x03,  
 0x55,0x04,0x03,0x1e,0x0a,0x00,0x4e,0x00,0x54,0x00,0x54,0x00,0x53,0x00,0x45,0x30,  
 0x21,0x06,0x03,0x55,0x04,0x07,0x1e,0x1a,0x00,0x4d,0x00,0x69,0x00,0x63,0x00,0x72,  
 0x00,0x6f,0x00,0x73,0x00,0x6f,0x00,0x66,0x00,0x74,0x00,0x2e,0x00,0x63,0x00,0x6f,  
 0x00,0x6d,0x30,0x1e,0x17,0x0d,0x39,0x39,0x30,0x39,0x32,0x34,0x31,0x32,0x30,0x32,  
 0x30,0x34,0x5a,0x17,0x0d,0x34,0x39,0x30,0x39,0x32,0x34,0x31,0x32,0x30,0x32,0x30,  
 0x34,0x5a,0x30,0x38,0x31,0x36,0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x1e,0x0a,0x00,  
 0x4e,0x00,0x54,0x00,0x54,0x00,0x53,0x00,0x45,0x30,0x21,0x06,0x03,0x55,0x04,0x07,  
 0x1e,0x1a,0x00,0x4d,0x00,0x69,0x00,0x63,0x00,0x72,0x00,0x6f,0x00,0x73,0x00,0x6f,  
 0x00,0x66,0x00,0x74,0x00,0x2e,0x00,0x63,0x00,0x6f,0x00,0x6d,0x30,0x5c,0x30,0x0d,  
 0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x4b,0x00,  
 0x30,0x48,0x02,0x41,0x00,0x91,0xb2,0x16,0x1c,0xae,0x4f,0x7f,0x7c,0xaf,0x57,0x2b,  
 0x23,0x4c,0x0c,0x25,0x3c,0x4f,0x66,0x9d,0x25,0xc3,0x4f,0x29,0xee,0x8b,0xda,0x4e,  
 0x95,0xe7,0x3b,0xaa,0xc0,0xa7,0xba,0xaf,0x99,0x8c,0x47,0x24,0x8b,0x09,0x77,0xbc,  
 0x2c,0xf4,0xe7,0x1a,0x07,0x58,0x7b,0x11,0x37,0x2a,0xa8,0x90,0xc3,0x50,0x92,0x80,  
 0x15,0xc5,0xda,0x51,0x8b,0x02,0x03,0x01,0x00,0x01,0xa3,0x13,0x30,0x11,0x30,0x0f,  
 0x06,0x03,0x55,0x1d,0x13,0x04,0x08,0x30,0x06,0x01,0x01,0xff,0x02,0x01,0x00,0x30,  
 0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x03,0x41,0x00,0x14,0x04,0x67,  
 0x28,0xc8,0xd3,0x1f,0x13,0x14,0x2e,0x2c,0x93,0x09,0x25,0xbb,0xbe,0x86,0x6a,0xd3,  
 0x47,0x6f,0x44,0x16,0x7b,0x94,0x8c,0xb2,0xa2,0xd5,0xf7,0x4f,0xb1,0x8f,0x7f,0xde,  
 0x0b,0x88,0x34,0x4a,0x1d,0xdc,0xa1,0xfd,0x26,0xbd,0x43,0xbb,0x38,0xf1,0x87,0x34,  
 0xbb,0xe9,0x3b,0xfa,0x7f,0x1e,0xff,0xe1,0x10,0x7e,0xee,0x6e,0xd8,0x30,0x82,0x02,  
 0x62,0x30,0x82,0x02,0x10,0xa0,0x03,0x02,0x01,0x02,0x02,0x05,0x01,0x00,0x00,0x00,  
 0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,0x30,0x38,0x31,0x36,  
 0x30,0x11,0x06,0x03,0x55,0x04,0x03,0x1e,0x0a,0x00,0x4e,0x00,0x54,0x00,0x54,0x00,  
 0x53,0x00,0x45,0x30,0x21,0x06,0x03,0x55,0x04,0x07,0x1e,0x1a,0x00,0x4d,0x00,0x69,  
 0x00,0x63,0x00,0x72,0x00,0x6f,0x00,0x73,0x00,0x6f,0x00,0x66,0x00,0x74,0x00,0x2e,  
 0x00,0x63,0x00,0x6f,0x00,0x6d,0x30,0x1e,0x17,0x0d,0x39,0x39,0x30,0x39,0x32,0x34,  
 0x30,0x30,0x30,0x30,0x30,0x30,0x5a,0x17,0x0d,0x34,0x39,0x30,0x39,0x32,0x34,0x30,  
 0x30,0x30,0x30,0x30,0x30,0x5a,0x30,0x79,0x31,0x77,0x30,0x17,0x06,0x03,0x55,0x04,  
 0x03,0x1e,0x10,0x00,0x52,0x00,0x45,0x00,0x53,0x00,0x37,0x00,0x2d,0x00,0x4e,0x00,  
 0x45,0x00,0x57,0x30,0x17,0x06,0x03,0x55,0x04,0x07,0x1e,0x10,0x00,0x7a,0x00,0x32,  
 0x00,0x32,0x00,0x33,0x00,0x32,0x00,0x32,0x00,0x30,0x00,0x33,0x30,0x43,0x06,0x03,  
 0x55,0x04,0x05,0x1e,0x3c,0x00,0x31,0x00,0x42,0x00,0x63,0x00,0x4b,0x00,0x65,0x00,  
 0x57,0x00,0x50,0x00,0x6c,0x00,0x37,0x00,0x58,0x00,0x47,0x00,0x61,0x00,0x73,0x00,  
 0x38,0x00,0x4a,0x00,0x79,0x00,0x50,0x00,0x34,0x00,0x30,0x00,0x7a,0x00,0x49,0x00,  
 0x6d,0x00,0x6e,0x00,0x6f,0x00,0x51,0x00,0x5a,0x00,0x59,0x00,0x3d,0x00,0x0d,0x00,  
 0x0a,0x30,0x5c,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,  
 0x05,0x00,0x03,0x4b,0x00,0x30,0x48,0x02,0x41,0x00,0x91,0xb2,0x16,0x1c,0xae,0x4f,  
 0x7f,0x7c,0xaf,0x57,0x2b,0x23,0x4c,0x0c,0x25,0x3c,0x4f,0x66,0x9d,0x25,0xc3,0x4f,  
 0x29,0xee,0x8b,0xda,0x4e,0x95,0xe7,0x3b,0xaa,0xc0,0xa7,0xba,0xaf,0x99,0x8c,0x47,  
 0x24,0x8b,0x09,0x77,0xbc,0x2c,0xf4,0xe7,0x1a,0x07,0x58,0x7b,0x11,0x37,0x2a,0xa8,  
 0x90,0xc3,0x50,0x92,0x80,0x15,0xc5,0xda,0x51,0x8b,0x02,0x03,0x01,0x00,0x01,0xa3,  
 0x81,0xc3,0x30,0x81,0xc0,0x30,0x14,0x06,0x09,0x2b,0x06,0x01,0x04,0x01,0x82,0x37,  
 0x12,0x04,0x01,0x01,0xff,0x04,0x04,0x01,0x00,0x01,0x00,0x30,0x3c,0x06,0x09,0x2b,  
 0x06,0x01,0x04,0x01,0x82,0x37,0x12,0x02,0x01,0x01,0xff,0x04,0x2c,0x4d,0x00,0x69,  
 0x00,0x63,0x00,0x72,0x00,0x6f,0x00,0x73,0x00,0x6f,0x00,0x66,0x00,0x74,0x00,0x20,  
 0x00,0x43,0x00,0x6f,0x00,0x72,0x00,0x70,0x00,0x6f,0x00,0x72,0x00,0x61,0x00,0x74,  
 0x00,0x69,0x00,0x6f,0x00,0x6e,0x00,0x00,0x00,0x30,0x4c,0x06,0x09,0x2b,0x06,0x01,  
 0x04,0x01,0x82,0x37,0x12,0x05,0x01,0x01,0xff,0x04,0x3c,0x00,0x10,0x00,0x00,0x01,  
 0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x09,0x04,0x00,0x00,0x18,0x00,0x18,0x00,0x30,  
 0x00,0x01,0x00,0x32,0x00,0x33,0x00,0x36,0x00,0x2d,0x00,0x34,0x00,0x2e,0x00,0x30,  
 0x00,0x30,0x00,0x2d,0x00,0x45,0x00,0x58,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,  
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x1c,0x06,0x03,0x55,0x1d,0x23,0x01,0x01,  
 0xff,0x04,0x12,0x30,0x10,0xa1,0x07,0x81,0x05,0x4e,0x54,0x54,0x53,0x45,0x82,0x05,  
 0x01,0x00,0x00,0x00,0x01,0x30,0x09,0x06,0x05,0x2b,0x0e,0x03,0x02,0x1d,0x05,0x00,  
 0x03,0x41,0x00,0x7b,0x1d,0xfd,0x24,0xea,0xf2,0xe8,0x17,0xdd,0x88,0x7e,0xfd,0xee,  
 0x28,0x61,0x7a,0x02,0xc3,0x73,0xcf,0x32,0x0f,0x7c,0x66,0x87,0x31,0xa7,0xbe,0x1b,  
 0x31,0xe2,0x20,0xa5,0x76,0x91,0x68,0x97,0x53,0x9e,0x80,0xcd,0x2b,0xd0,0x8e,0x8b,  
 0x7f,0x89,0x1b,0x62,0xa8,0xf8,0xee,0x5e,0x56,0xbd,0x9c,0x6b,0x80,0x06,0x54,0xd3,  
 0xf0,0xbf,0xb2,0x31,0x00,0x01,0x00,0x14,0x00,0xc7,0x32,0xf2,0x5b,0x98,0x0e,0x04,  
 0x49,0xa0,0x27,0x7e,0xf5,0xf6,0x0f,0xda,0x08,0x1d,0xe9,0x79,0xd1,0x31,0xc6,0x50,  
 0x90,0x4a,0xd3,0x1f,0x1d,0xf0,0x65,0x0d,0xb6,0x1f,0xaf,0xc9,0x1d  
 };  
480    
481  /* Send license certificate and related data to the server */          s_mark_end(s);
482  void rdp_send_cert(HCONN conn)          rdp_send_data(s, RDP_DATA_PDU_INPUT);
 {  
         mcs_init_data(conn);  
         prs_io_uint8s(&conn->out, precanned_cert_packet, sizeof(precanned_cert_packet));  
         MARK_END(conn->out);  
         mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);  
483  }  }
484    
485  /* Initialise RDP transport packet */  /* Inform the server on the contents of the persistent bitmap cache */
486  void rdp_init(HCONN conn)  static void
487    rdp_enum_bmpcache2(void)
488  {  {
489          mcs_init_data(conn);          STREAM s;
490          PUSH_LAYER(conn->out, rdp_offset, 6);          HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS];
491  }          uint32 num_keys, offset, count, flags;
492    
493  /* Transmit RDP transport packet */          offset = 0;
494  void rdp_send(HCONN conn, uint16 pdu_type)          num_keys = pstcache_enumerate(2, keylist);
 {  
         RDP_HEADER hdr;  
         int length;  
495    
496          POP_LAYER(conn->out, rdp_offset);          while (offset < num_keys)
497          length = conn->out.end - conn->out.offset;          {
498          rdp_make_header(&hdr, length, pdu_type, conn->mcs_userid);                  count = MIN(num_keys - offset, 169);
         rdp_io_header(&conn->out, &hdr);  
         mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);  
 }  
499    
500  /* Initialise RDP transport data packet */                  s = rdp_init_data(24 + count * sizeof(HASH_KEY));
 void rdp_init_data(HCONN conn)  
 {  
         mcs_init_data(conn);  
         PUSH_LAYER(conn->out, rdp_offset, 18);  
 }  
501    
502  /* Transmit RDP transport data packet */                  flags = 0;
503  void rdp_send_data(HCONN conn, uint16 data_pdu_type)                  if (offset == 0)
504  {                          flags |= PDU_FLAG_FIRST;
505          RDP_HEADER hdr;                  if (num_keys - offset <= 169)
506          RDP_DATA_HEADER datahdr;                          flags |= PDU_FLAG_LAST;
507          int length = conn->out.end - conn->out.offset;  
508                    /* header */
509                    out_uint32_le(s, 0);
510                    out_uint16_le(s, count);
511                    out_uint16_le(s, 0);
512                    out_uint16_le(s, 0);
513                    out_uint16_le(s, 0);
514                    out_uint16_le(s, 0);
515                    out_uint16_le(s, num_keys);
516                    out_uint32_le(s, 0);
517                    out_uint32_le(s, flags);
518    
519                    /* list */
520                    out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY));
521    
522                    s_mark_end(s);
523                    rdp_send_data(s, 0x2b);
524    
525          POP_LAYER(conn->out, rdp_offset);                  offset += 169;
526          length = conn->out.end - conn->out.offset;          }
         rdp_make_header(&hdr, length, RDP_PDU_DATA, conn->mcs_userid);  
         rdp_io_header(&conn->out, &hdr);  
         rdp_make_data_header(&datahdr, 0x103ea, length, data_pdu_type);  
         rdp_io_data_header(&conn->out, &datahdr);  
         mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);  
527  }  }
528    
529  void rdp_send_confirm_active(HCONN conn)  /* Send an (empty) font information PDU */
530    static void
531    rdp_send_fonts(uint16 seq)
532  {  {
533          RDP_ACTIVE_PDU active;          STREAM s;
534    
535            s = rdp_init_data(8);
536    
537            out_uint16(s, 0);       /* number of fonts */
538            out_uint16_le(s, 0);    /* pad? */
539            out_uint16_le(s, seq);  /* unknown */
540            out_uint16_le(s, 0x32); /* entry size */
541    
542          rdp_init(conn);          s_mark_end(s);
543          rdp_make_active_pdu(&active, 0x103ea, conn->mcs_userid);          rdp_send_data(s, RDP_DATA_PDU_FONT2);
         rdp_io_active_pdu(&conn->out, &active, RDP_PDU_CONFIRM_ACTIVE);  
         MARK_END(conn->out);  
         rdp_send(conn, RDP_PDU_CONFIRM_ACTIVE);  
544  }  }
545    
546  void rdp_send_synchronize(HCONN conn)  /* Output general capability set */
547    static void
548    rdp_out_general_caps(STREAM s)
549  {  {
550          RDP_SYNCHRONIZE_PDU sync;          out_uint16_le(s, RDP_CAPSET_GENERAL);
551            out_uint16_le(s, RDP_CAPLEN_GENERAL);
552    
553          rdp_init_data(conn);          out_uint16_le(s, 1);    /* OS major type */
554          rdp_make_synchronize_pdu(&sync, 1002);          out_uint16_le(s, 3);    /* OS minor type */
555          rdp_io_synchronize_pdu(&conn->out, &sync);          out_uint16_le(s, 0x200);        /* Protocol version */
556          MARK_END(conn->out);          out_uint16(s, 0);       /* Pad */
557          rdp_send_data(conn, RDP_DATA_PDU_SYNCHRONIZE);          out_uint16(s, 0);       /* Compression types */
558            out_uint16_le(s, g_use_rdp5 ? 0x40d : 0);
559            /* Pad, according to T.128. 0x40d seems to
560               trigger
561               the server to start sending RDP5 packets.
562               However, the value is 0x1d04 with W2KTSK and
563               NT4MS. Hmm.. Anyway, thankyou, Microsoft,
564               for sending such information in a padding
565               field.. */
566            out_uint16(s, 0);       /* Update capability */
567            out_uint16(s, 0);       /* Remote unshare capability */
568            out_uint16(s, 0);       /* Compression level */
569            out_uint16(s, 0);       /* Pad */
570  }  }
571    
572  void rdp_send_control(HCONN conn, uint16 action)  /* Output bitmap capability set */
573    static void
574    rdp_out_bitmap_caps(STREAM s)
575  {  {
576          RDP_CONTROL_PDU control;          out_uint16_le(s, RDP_CAPSET_BITMAP);
577            out_uint16_le(s, RDP_CAPLEN_BITMAP);
578    
579          rdp_init_data(conn);          out_uint16_le(s, g_server_bpp); /* Preferred BPP */
580          rdp_make_control_pdu(&control, action);          out_uint16_le(s, 1);    /* Receive 1 BPP */
581          rdp_io_control_pdu(&conn->out, &control);          out_uint16_le(s, 1);    /* Receive 4 BPP */
582          MARK_END(conn->out);          out_uint16_le(s, 1);    /* Receive 8 BPP */
583          rdp_send_data(conn, RDP_DATA_PDU_CONTROL);          out_uint16_le(s, 800);  /* Desktop width */
584            out_uint16_le(s, 600);  /* Desktop height */
585            out_uint16(s, 0);       /* Pad */
586            out_uint16(s, 1);       /* Allow resize */
587            out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
588            out_uint16(s, 0);       /* Unknown */
589            out_uint16_le(s, 1);    /* Unknown */
590            out_uint16(s, 0);       /* Pad */
591  }  }
592    
593  void rdp_send_fonts(HCONN conn, uint16 seqno)  /* Output order capability set */
594    static void
595    rdp_out_order_caps(STREAM s)
596  {  {
597          RDP_FONT_PDU fonts;          uint8 order_caps[32];
598    
599          rdp_init_data(conn);          memset(order_caps, 0, 32);
600          rdp_make_font_pdu(&fonts, seqno);          order_caps[0] = 1;      /* dest blt */
601          rdp_io_font_pdu(&conn->out, &fonts);          order_caps[1] = 1;      /* pat blt */
602          MARK_END(conn->out);          order_caps[2] = 1;      /* screen blt */
603          rdp_send_data(conn, RDP_DATA_PDU_FONT2);          order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
604            order_caps[4] = 0;      /* triblt */
605            order_caps[8] = 1;      /* line */
606            order_caps[9] = 1;      /* line */
607            order_caps[10] = 1;     /* rect */
608            order_caps[11] = (g_desktop_save ? 1 : 0);      /* desksave */
609            order_caps[13] = 1;     /* memblt */
610            order_caps[14] = 1;     /* triblt */
611            order_caps[20] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon */
612            order_caps[21] = (g_polygon_ellipse_orders ? 1 : 0);    /* polygon2 */
613            order_caps[22] = 1;     /* polyline */
614            order_caps[25] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse */
615            order_caps[26] = (g_polygon_ellipse_orders ? 1 : 0);    /* ellipse2 */
616            order_caps[27] = 1;     /* text2 */
617            out_uint16_le(s, RDP_CAPSET_ORDER);
618            out_uint16_le(s, RDP_CAPLEN_ORDER);
619    
620            out_uint8s(s, 20);      /* Terminal desc, pad */
621            out_uint16_le(s, 1);    /* Cache X granularity */
622            out_uint16_le(s, 20);   /* Cache Y granularity */
623            out_uint16(s, 0);       /* Pad */
624            out_uint16_le(s, 1);    /* Max order level */
625            out_uint16_le(s, 0x147);        /* Number of fonts */
626            out_uint16_le(s, 0x2a); /* Capability flags */
627            out_uint8p(s, order_caps, 32);  /* Orders supported */
628            out_uint16_le(s, 0x6a1);        /* Text capability flags */
629            out_uint8s(s, 6);       /* Pad */
630            out_uint32_le(s, g_desktop_save == False ? 0 : 0x38400);        /* Desktop cache size */
631            out_uint32(s, 0);       /* Unknown */
632            out_uint32_le(s, 0x4e4);        /* Unknown */
633  }  }
634    
635  void rdp_send_input(HCONN conn)  /* Output bitmap cache capability set */
636    static void
637    rdp_out_bmpcache_caps(STREAM s)
638  {  {
639          RDP_INPUT_PDU input;          int Bpp;
640            out_uint16_le(s, RDP_CAPSET_BMPCACHE);
641            out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
642    
643          rdp_init_data(conn);          Bpp = (g_server_bpp + 7) / 8;
644          rdp_make_input_pdu(&input);          out_uint8s(s, 24);      /* unused */
645          rdp_io_input_pdu(&conn->out, &input);          out_uint16_le(s, 0x258);        /* entries */
646          MARK_END(conn->out);          out_uint16_le(s, 0x100 * Bpp);  /* max cell size */
647          rdp_send_data(conn, RDP_DATA_PDU_INPUT);          out_uint16_le(s, 0x12c);        /* entries */
648            out_uint16_le(s, 0x400 * Bpp);  /* max cell size */
649            out_uint16_le(s, 0x106);        /* entries */
650            out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
651  }  }
652    
653  BOOL rdp_recv_pdu(HCONN conn, uint8 *type)  /* Output bitmap cache v2 capability set */
654    static void
655    rdp_out_bmpcache2_caps(STREAM s)
656  {  {
657          RDP_HEADER hdr;          out_uint16_le(s, RDP_CAPSET_BMPCACHE2);
658            out_uint16_le(s, RDP_CAPLEN_BMPCACHE2);
659    
660            out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0);        /* version */
661    
662          conn->in.offset = conn->in.rdp_offset;          out_uint16_be(s, 3);    /* number of caches in this set */
663    
664          if (conn->in.offset >= conn->in.end)          /* max cell size for cache 0 is 16x16, 1 = 32x32, 2 = 64x64, etc */
665            out_uint32_le(s, BMPCACHE2_C0_CELLS);
666            out_uint32_le(s, BMPCACHE2_C1_CELLS);
667            if (pstcache_init(2))
668          {          {
669                  if (!mcs_recv(conn, False))                  out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST);
                         return False;  
670          }          }
671            else
672          if (!rdp_io_header(&conn->in, &hdr))          {
673                  return False;                  out_uint32_le(s, BMPCACHE2_C2_CELLS);
674            }
675          conn->in.rdp_offset += hdr.length;          out_uint8s(s, 20);      /* other bitmap caches not used */
         *type = hdr.pdu_type & 0xf;  
   
 #if DEBUG  
         fprintf(stderr, "RDP packet (type %x):\n", *type);  
         dump_data(conn->in.data+conn->in.offset, conn->in.rdp_offset-conn->in.offset);  
 #endif  
   
         return True;  
676  }  }
677    
678  /* Disconnect from the RDP layer */  /* Output control capability set */
679  void rdp_disconnect(HCONN conn)  static void
680    rdp_out_control_caps(STREAM s)
681  {  {
682          mcs_disconnect(conn);          out_uint16_le(s, RDP_CAPSET_CONTROL);
683  }          out_uint16_le(s, RDP_CAPLEN_CONTROL);
684    
685  void rdp_make_header(RDP_HEADER *hdr, uint16 length, uint16 pdu_type,          out_uint16(s, 0);       /* Control capabilities */
686                       uint16 userid)          out_uint16(s, 0);       /* Remote detach */
687  {          out_uint16_le(s, 2);    /* Control interest */
688          hdr->length = length;          out_uint16_le(s, 2);    /* Detach interest */
         hdr->pdu_type = pdu_type | 0x10; /* Version 1 */  
         hdr->userid = userid + 1001;  
689  }  }
690    
691  void rdp_make_data_header(RDP_DATA_HEADER *hdr, uint32 shareid,  /* Output activation capability set */
692                            uint16 length, uint16 data_pdu_type)  static void
693    rdp_out_activate_caps(STREAM s)
694  {  {
695          hdr->shareid = shareid;          out_uint16_le(s, RDP_CAPSET_ACTIVATE);
696          hdr->pad = 0;          out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
         hdr->streamid = 1;  
         hdr->length = length - 14;  
         hdr->data_pdu_type = data_pdu_type;  
         hdr->compress_type = 0;  
         hdr->compress_len = 0;  
 }  
697    
698  void rdp_make_general_caps(RDP_GENERAL_CAPS *caps)          out_uint16(s, 0);       /* Help key */
699  {          out_uint16(s, 0);       /* Help index key */
700          caps->os_major_type = 1;          out_uint16(s, 0);       /* Extended help key */
701          caps->os_minor_type = 3;          out_uint16(s, 0);       /* Window activate */
         caps->ver_protocol = 0x200;  
702  }  }
703    
704  void rdp_make_bitmap_caps(RDP_BITMAP_CAPS *caps)  /* Output pointer capability set */
705    static void
706    rdp_out_pointer_caps(STREAM s)
707  {  {
708          caps->preferred_bpp = 8;          out_uint16_le(s, RDP_CAPSET_POINTER);
709          caps->receive1bpp = 1;          out_uint16_le(s, RDP_CAPLEN_POINTER);
710          caps->receive4bpp = 1;  
711          caps->receive8bpp = 1;          out_uint16(s, 0);       /* Colour pointer */
712          caps->width = 640;          out_uint16_le(s, 20);   /* Cache size */
         caps->height = 480;  
         caps->compression = 1;  
         caps->unknown2 = 1;  
713  }  }
714    
715  void rdp_make_order_caps(RDP_ORDER_CAPS *caps)  /* Output share capability set */
716    static void
717    rdp_out_share_caps(STREAM s)
718  {  {
719          caps->xgranularity = 1;          out_uint16_le(s, RDP_CAPSET_SHARE);
720          caps->ygranularity = 20;          out_uint16_le(s, RDP_CAPLEN_SHARE);
         caps->max_order_level = 1;  
         caps->num_fonts = 0x147;  
         caps->cap_flags = 0x2A;  
   
 //      caps->cap_flags = ORDER_CAP_NEGOTIATE | ORDER_CAP_NOSUPPORT;  
721    
722          caps->support[0] = caps->support[1] = caps->support[2]          out_uint16(s, 0);       /* userid */
723                  = caps->support[3] = caps->support[4] = caps->support[5]          out_uint16(s, 0);       /* pad */
                 = caps->support[6] = caps->support[8] = caps->support[11]  
                 = caps->support[12] = caps->support[22] = caps->support[28]  
                 = caps->support[29] = caps->support[30] = 1;  
         caps->text_cap_flags = 0x6A1;  
         caps->desk_save_size = 0x38400;  
         caps->unknown2 = 0x4E4;  
724  }  }
725    
726  void rdp_make_bmpcache_caps(RDP_BMPCACHE_CAPS *caps)  /* Output colour cache capability set */
727    static void
728    rdp_out_colcache_caps(STREAM s)
729  {  {
730          caps->caches[0].entries = 0x258;          out_uint16_le(s, RDP_CAPSET_COLCACHE);
731          caps->caches[0].max_cell_size = 0x100;          out_uint16_le(s, RDP_CAPLEN_COLCACHE);
         caps->caches[1].entries = 0x12c;  
         caps->caches[1].max_cell_size = 0x400;  
         caps->caches[2].entries = 0x106;  
         caps->caches[2].max_cell_size = 0x1000;  
 }  
732    
733  void rdp_make_control_caps(RDP_CONTROL_CAPS *caps)          out_uint16_le(s, 6);    /* cache size */
734  {          out_uint16(s, 0);       /* pad */
         caps->control_interest = 2;  
         caps->detach_interest = 2;  
735  }  }
736    
737  void rdp_make_activate_caps(RDP_ACTIVATE_CAPS *caps)  static uint8 caps_0x0d[] = {
738  {          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00,
739  }          0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
740            0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
741            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
742            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
743            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
744            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
745            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
746            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
747            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
748            0x00, 0x00, 0x00, 0x00
749    };
750    
751  void rdp_make_pointer_caps(RDP_POINTER_CAPS *caps)  static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 };
 {  
         caps->colour_pointer = 0;  
         caps->cache_size = 20;  
 }  
752    
753  void rdp_make_share_caps(RDP_SHARE_CAPS *caps, uint16 userid)  static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 };
 {  
 }  
754    
755  void rdp_make_colcache_caps(RDP_COLCACHE_CAPS *caps)  static uint8 caps_0x10[] = {
756  {          0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00,
757          caps->cache_size = 6;          0xFE, 0x00, 0x08, 0x00, 0xFE, 0x00, 0x08, 0x00,
758  }          0xFE, 0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00,
759            0xFE, 0x00, 0x40, 0x00, 0xFE, 0x00, 0x80, 0x00,
760            0xFE, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08,
761            0x00, 0x01, 0x00, 0x01, 0x02, 0x00, 0x00, 0x00
762    };
763    
764  void rdp_make_active_pdu(RDP_ACTIVE_PDU *pdu, uint32 shareid, uint16 userid)  /* Output unknown capability sets */
765    static void
766    rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps)
767  {  {
768          memset(pdu, 0, sizeof(*pdu));          out_uint16_le(s, id);
769          pdu->shareid = shareid;          out_uint16_le(s, length);
         pdu->userid  = 1002;  
         pdu->source_len = sizeof(RDP_SOURCE);  
         memcpy(pdu->source, RDP_SOURCE, sizeof(RDP_SOURCE));  
770    
771          pdu->caps_len = RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER          out_uint8p(s, caps, length - 4);
                 + RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE + RDP_CAPLEN_ACTIVATE  
                 + RDP_CAPLEN_CONTROL + RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE  
                 + RDP_CAPLEN_UNKNOWN;  
         pdu->num_caps = 0xD;  
   
         rdp_make_general_caps (&pdu->general_caps );  
         rdp_make_bitmap_caps  (&pdu->bitmap_caps  );  
         rdp_make_order_caps   (&pdu->order_caps   );  
         rdp_make_bmpcache_caps(&pdu->bmpcache_caps);  
         rdp_make_control_caps (&pdu->control_caps );  
         rdp_make_activate_caps(&pdu->activate_caps);  
         rdp_make_pointer_caps (&pdu->pointer_caps );  
         rdp_make_share_caps   (&pdu->share_caps, userid);  
         rdp_make_colcache_caps(&pdu->colcache_caps);  
772  }  }
773    
774  void rdp_make_control_pdu(RDP_CONTROL_PDU *pdu, uint16 action)  #define RDP5_FLAG 0x0030
775    /* Send a confirm active PDU */
776    static void
777    rdp_send_confirm_active(void)
778  {  {
779          pdu->action = action;          STREAM s;
780          pdu->userid = 0;          uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
781          pdu->controlid = 0;          uint16 caplen =
782  }                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
783                    RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
784                    RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
785                    RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE +
786                    0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */  +
787                    4 /* w2k fix, why? */ ;
788    
789  void rdp_make_synchronize_pdu(RDP_SYNCHRONIZE_PDU *pdu, uint16 userid)          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
 {  
         pdu->type = 1;  
         pdu->userid = userid;  
 }  
790    
791  void rdp_make_font_pdu(RDP_FONT_PDU *pdu, uint16 seqno)          out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
792  {          out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10));      /* Version 1 */
793          pdu->num_fonts = 0;          out_uint16_le(s, (g_mcs_userid + 1001));
         pdu->unknown1 = 0x3e;  
         pdu->unknown2 = seqno;  
         pdu->entry_size = RDP_FONT_INFO_SIZE;  
 }  
794    
795  void rdp_make_input_pdu(RDP_INPUT_PDU *pdu)          out_uint32_le(s, g_rdp_shareid);
796  {          out_uint16_le(s, 0x3ea);        /* userid */
797          uint32 now = time(NULL);          out_uint16_le(s, sizeof(RDP_SOURCE));
798            out_uint16_le(s, caplen);
799    
800          pdu->num_events = 3;          out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
801          pdu->pad = 0;          out_uint16_le(s, 0xd);  /* num_caps */
802            out_uint8s(s, 2);       /* pad */
803    
804          pdu->event[0].event_time = now;          rdp_out_general_caps(s);
805          pdu->event[0].message_type = RDP_INPUT_SYNCHRONIZE;          rdp_out_bitmap_caps(s);
806          pdu->event[0].device_flags = 0;          rdp_out_order_caps(s);
807          pdu->event[0].mouse_x = 0;          g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s);
808          pdu->event[0].mouse_y = 0;          rdp_out_colcache_caps(s);
809            rdp_out_activate_caps(s);
810            rdp_out_control_caps(s);
811            rdp_out_pointer_caps(s);
812            rdp_out_share_caps(s);
813    
814          pdu->event[1].event_time = now;          rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */
815          pdu->event[1].message_type = RDP_INPUT_UNKNOWN;          rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c);
816          pdu->event[1].device_flags = 0x8000;          rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e);
817          pdu->event[1].mouse_x = 15;          rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */
         pdu->event[1].mouse_y = 0;  
818    
819          pdu->event[2].event_time = now;          s_mark_end(s);
820          pdu->event[2].message_type = RDP_INPUT_MOUSE;          sec_send(s, sec_flags);
         pdu->event[2].device_flags = MOUSE_FLAG_MOVE;  
         pdu->event[2].mouse_x = 425;  
         pdu->event[2].mouse_y = 493;  
821  }  }
822    
823  BOOL rdp_io_header(STREAM s, RDP_HEADER *hdr)  /* Process a general capability set */
824    static void
825    rdp_process_general_caps(STREAM s)
826  {  {
827          BOOL res = True;          uint16 pad2octetsB;     /* rdp5 flags? */
828    
829          res = res ? lsb_io_uint16(s, &hdr->length  ) : False;          in_uint8s(s, 10);
830          res = res ? lsb_io_uint16(s, &hdr->pdu_type) : False;          in_uint16_le(s, pad2octetsB);
         res = res ? lsb_io_uint16(s, &hdr->userid  ) : False;  
831    
832          return res;          if (!pad2octetsB)
833                    g_use_rdp5 = False;
834  }  }
835    
836  BOOL rdp_io_data_header(STREAM s, RDP_DATA_HEADER *hdr)  /* Process a bitmap capability set */
837    static void
838    rdp_process_bitmap_caps(STREAM s)
839  {  {
840          BOOL res = True;          uint16 width, height, bpp;
841    
842          res = res ? lsb_io_uint32(s, &hdr->shareid      ) : False;          in_uint16_le(s, bpp);
843          res = res ? prs_io_uint8 (s, &hdr->pad          ) : False;          in_uint8s(s, 6);
         res = res ? prs_io_uint8 (s, &hdr->streamid     ) : False;  
         res = res ? lsb_io_uint16(s, &hdr->length       ) : False;  
         res = res ? prs_io_uint8 (s, &hdr->data_pdu_type) : False;  
         res = res ? prs_io_uint8 (s, &hdr->compress_type) : False;  
         res = res ? lsb_io_uint16(s, &hdr->compress_len ) : False;  
844    
845          return res;          in_uint16_le(s, width);
846  }          in_uint16_le(s, height);
847    
848  BOOL rdp_io_coord(STREAM s, uint16 *coord, BOOL delta)          DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));
 {  
         uint8 change;  
         BOOL res;  
849    
850          if (delta)          /*
851             * The server may limit bpp and change the size of the desktop (for
852             * example when shadowing another session).
853             */
854            if (g_server_bpp != bpp)
855          {          {
856                  res = prs_io_uint8(s, &change);                  warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
857                  *coord += change;                  g_server_bpp = bpp;
858          }          }
859          else          if (g_width != width || g_height != height)
860          {          {
861                  res = lsb_io_uint16(s, coord);                  warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
862                            width, height);
863                    g_width = width;
864                    g_height = height;
865                    ui_resize_window();
866          }          }
   
         return res;  
867  }  }
868    
869  BOOL rdp_io_colormap(STREAM s, COLORMAP *colors)  /* Process server capabilities */
870    void
871    rdp_process_server_caps(STREAM s, uint16 length)
872  {  {
873          int datasize;          int n;
874            uint8 *next, *start;
875            uint16 ncapsets, capset_type, capset_length;
876    
877          lsb_io_uint16(s, &colors->ncolors);          start = s->p;
         datasize = colors->ncolors * 3;  
878    
879          if (datasize > sizeof(colors->colors))          in_uint16_le(s, ncapsets);
880                  return False;          in_uint8s(s, 2);        /* pad */
   
         memcpy(colors->colors, s->data + s->offset, datasize);  
         s->offset += datasize;  
         return True;  
 }  
   
 BOOL rdp_io_general_caps(STREAM s, RDP_GENERAL_CAPS *caps)  
 {  
         uint16 length = RDP_CAPLEN_GENERAL;  
         uint16 pkt_length = length;  
         BOOL res;  
881    
882          res = lsb_io_uint16(s, &pkt_length);          for (n = 0; n < ncapsets; n++)
         if (pkt_length != length)  
883          {          {
884                  fprintf(stderr, "Unrecognised capabilities size\n");                  if (s->p > start + length)
885                  return False;                          return;
         }  
   
         res = res ? lsb_io_uint16(s, &caps->os_major_type ) : False;  
         res = res ? lsb_io_uint16(s, &caps->os_minor_type ) : False;  
         res = res ? lsb_io_uint16(s, &caps->ver_protocol  ) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad1          ) : False;  
         res = res ? lsb_io_uint16(s, &caps->compress_types) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad2          ) : False;  
         res = res ? lsb_io_uint16(s, &caps->cap_update    ) : False;  
         res = res ? lsb_io_uint16(s, &caps->remote_unshare) : False;  
         res = res ? lsb_io_uint16(s, &caps->compress_level) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad3          ) : False;  
   
         return res;  
 }  
   
 BOOL rdp_io_bitmap_caps(STREAM s, RDP_BITMAP_CAPS *caps)  
 {  
         uint16 length = RDP_CAPLEN_BITMAP;  
         uint16 pkt_length = length;  
         BOOL res;  
886    
887          res = lsb_io_uint16(s, &pkt_length);                  in_uint16_le(s, capset_type);
888          if (pkt_length != length)                  in_uint16_le(s, capset_length);
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
889    
890          res = res ? lsb_io_uint16(s, &caps->preferred_bpp) : False;                  next = s->p + capset_length - 4;
         res = res ? lsb_io_uint16(s, &caps->receive1bpp  ) : False;  
         res = res ? lsb_io_uint16(s, &caps->receive4bpp  ) : False;  
         res = res ? lsb_io_uint16(s, &caps->receive8bpp  ) : False;  
         res = res ? lsb_io_uint16(s, &caps->width        ) : False;  
         res = res ? lsb_io_uint16(s, &caps->height       ) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad1         ) : False;  
         res = res ? lsb_io_uint16(s, &caps->allow_resize ) : False;  
         res = res ? lsb_io_uint16(s, &caps->compression  ) : False;  
         res = res ? lsb_io_uint16(s, &caps->unknown1     ) : False;  
         res = res ? lsb_io_uint16(s, &caps->unknown2     ) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad2         ) : False;  
   
         return res;  
 }  
   
 BOOL rdp_io_order_caps(STREAM s, RDP_ORDER_CAPS *caps)  
 {  
         uint16 length = RDP_CAPLEN_ORDER;  
         uint16 pkt_length = length;  
         BOOL res;  
891    
892          res = lsb_io_uint16(s, &pkt_length);                  switch (capset_type)
893          if (pkt_length != length)                  {
894          {                          case RDP_CAPSET_GENERAL:
895                  fprintf(stderr, "Unrecognised capabilities size\n");                                  rdp_process_general_caps(s);
896                  return False;                                  break;
         }  
897    
898          res = res ? prs_io_uint8s(s,  caps->terminal_desc, 16) : False;                          case RDP_CAPSET_BITMAP:
899          res = res ? lsb_io_uint32(s, &caps->pad1             ) : False;                                  rdp_process_bitmap_caps(s);
900          res = res ? lsb_io_uint16(s, &caps->xgranularity     ) : False;                                  break;
901          res = res ? lsb_io_uint16(s, &caps->ygranularity     ) : False;                  }
         res = res ? lsb_io_uint16(s, &caps->pad2             ) : False;  
         res = res ? lsb_io_uint16(s, &caps->max_order_level  ) : False;  
         res = res ? lsb_io_uint16(s, &caps->num_fonts        ) : False;  
         res = res ? lsb_io_uint16(s, &caps->cap_flags        ) : False;  
         res = res ? prs_io_uint8s(s,  caps->support      , 32) : False;  
         res = res ? lsb_io_uint16(s, &caps->text_cap_flags   ) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad3             ) : False;  
         res = res ? lsb_io_uint32(s, &caps->pad4             ) : False;  
         res = res ? lsb_io_uint32(s, &caps->desk_save_size   ) : False;  
         res = res ? lsb_io_uint32(s, &caps->unknown1         ) : False;  
         res = res ? lsb_io_uint32(s, &caps->unknown2         ) : False;  
902    
903          return res;                  s->p = next;
904            }
905  }  }
906    
907  BOOL rdp_io_bmpcache_info(STREAM s, RDP_BMPCACHE_INFO *info)  /* Respond to a demand active PDU */
908    static void
909    process_demand_active(STREAM s)
910  {  {
911          if (!lsb_io_uint16(s, &info->entries      ))          uint8 type;
912                  return False;          uint16 len_src_descriptor, len_combined_caps;
   
         if (!lsb_io_uint16(s, &info->max_cell_size))  
                 return False;  
913    
914          return True;          in_uint32_le(s, g_rdp_shareid);
915  }          in_uint16_le(s, len_src_descriptor);
916            in_uint16_le(s, len_combined_caps);
917            in_uint8s(s, len_src_descriptor);
918    
919            DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
920            rdp_process_server_caps(s, len_combined_caps);
921    
922            rdp_send_confirm_active();
923            rdp_send_synchronise();
924            rdp_send_control(RDP_CTL_COOPERATE);
925            rdp_send_control(RDP_CTL_REQUEST_CONTROL);
926            rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
927            rdp_recv(&type);        /* RDP_CTL_COOPERATE */
928            rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
929            rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);
930    
931  BOOL rdp_io_bmpcache_caps(STREAM s, RDP_BMPCACHE_CAPS *caps)          if (g_use_rdp5)
 {  
         uint16 length = RDP_CAPLEN_BMPCACHE;  
         uint16 pkt_length = length;  
         BOOL res;  
         int i;  
   
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
932          {          {
933                  fprintf(stderr, "Unrecognised capabilities size\n");                  rdp_enum_bmpcache2();
934                  return False;                  rdp_send_fonts(3);
935            }
936            else
937            {
938                    rdp_send_fonts(1);
939                    rdp_send_fonts(2);
940          }          }
941    
942          for (i = 0; i < 6; i++)          rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
943                  res = res ? lsb_io_uint32(s, &caps->unused[i]) : False;          reset_order_state();
   
         for (i = 0; i < 3; i++)  
                 res = res ? rdp_io_bmpcache_info(s, &caps->caches[i]) : False;  
   
         return res;  
944  }  }
945    
946  BOOL rdp_io_control_caps(STREAM s, RDP_CONTROL_CAPS *caps)  /* Process a colour pointer PDU */
947    void
948    process_colour_pointer_pdu(STREAM s)
949  {  {
950          uint16 length = RDP_CAPLEN_CONTROL;          uint16 x, y, width, height, cache_idx, masklen, datalen;
951          uint16 pkt_length = length;          uint8 *mask, *data;
952          BOOL res;          HCURSOR cursor;
953    
954          res = lsb_io_uint16(s, &pkt_length);          in_uint16_le(s, cache_idx);
955          if (pkt_length != length)          in_uint16_le(s, x);
956          {          in_uint16_le(s, y);
957                  fprintf(stderr, "Unrecognised capabilities size\n");          in_uint16_le(s, width);
958                  return False;          in_uint16_le(s, height);
959          }          in_uint16_le(s, masklen);
960            in_uint16_le(s, datalen);
961            in_uint8p(s, data, datalen);
962            in_uint8p(s, mask, masklen);
963            cursor = ui_create_cursor(x, y, width, height, mask, data);
964            ui_set_cursor(cursor);
965            cache_put_cursor(cache_idx, cursor);
966    }
967    
968          res = res ? lsb_io_uint16(s, &caps->control_caps    ) : False;  /* Process a cached pointer PDU */
969          res = res ? lsb_io_uint16(s, &caps->remote_detach   ) : False;  void
970          res = res ? lsb_io_uint16(s, &caps->control_interest) : False;  process_cached_pointer_pdu(STREAM s)
971          res = res ? lsb_io_uint16(s, &caps->detach_interest ) : False;  {
972            uint16 cache_idx;
973    
974          return res;          in_uint16_le(s, cache_idx);
975            ui_set_cursor(cache_get_cursor(cache_idx));
976  }  }
977    
978  BOOL rdp_io_activate_caps(STREAM s, RDP_ACTIVATE_CAPS *caps)  /* Process a system pointer PDU */
979    void
980    process_system_pointer_pdu(STREAM s)
981  {  {
982          uint16 length = RDP_CAPLEN_ACTIVATE;          uint16 system_pointer_type;
         uint16 pkt_length = length;  
         BOOL res;  
983    
984          res = lsb_io_uint16(s, &pkt_length);          in_uint16(s, system_pointer_type);
985          if (pkt_length != length)          switch (system_pointer_type)
986          {          {
987                  fprintf(stderr, "Unrecognised capabilities size\n");                  case RDP_NULL_POINTER:
988                  return False;                          ui_set_null_cursor();
989          }                          break;
   
         res = res ? lsb_io_uint16(s, &caps->help_key         ) : False;  
         res = res ? lsb_io_uint16(s, &caps->help_index_key   ) : False;  
         res = res ? lsb_io_uint16(s, &caps->help_extended_key) : False;  
         res = res ? lsb_io_uint16(s, &caps->window_activate  ) : False;  
990    
991          return res;                  default:
992                            unimpl("System pointer message 0x%x\n", system_pointer_type);
993            }
994  }  }
995    
996  BOOL rdp_io_pointer_caps(STREAM s, RDP_POINTER_CAPS *caps)  /* Process a pointer PDU */
997    static void
998    process_pointer_pdu(STREAM s)
999  {  {
1000          uint16 length = RDP_CAPLEN_POINTER;          uint16 message_type;
1001          uint16 pkt_length = length;          uint16 x, y;
1002          BOOL res;  
1003            in_uint16_le(s, message_type);
1004            in_uint8s(s, 2);        /* pad */
1005    
1006          res = lsb_io_uint16(s, &pkt_length);          switch (message_type)
         if (pkt_length != length)  
1007          {          {
1008                  fprintf(stderr, "Unrecognised capabilities size\n");                  case RDP_POINTER_MOVE:
1009                  return False;                          in_uint16_le(s, x);
1010          }                          in_uint16_le(s, y);
1011                            if (s_check(s))
1012                                    ui_move_pointer(x, y);
1013                            break;
1014    
1015          res = res ? lsb_io_uint16(s, &caps->colour_pointer) : False;                  case RDP_POINTER_COLOR:
1016          res = res ? lsb_io_uint16(s, &caps->cache_size    ) : False;                          process_colour_pointer_pdu(s);
1017                            break;
1018    
1019          return res;                  case RDP_POINTER_CACHED:
1020  }                          process_cached_pointer_pdu(s);
1021                            break;
1022    
1023  BOOL rdp_io_share_caps(STREAM s, RDP_SHARE_CAPS *caps)                  case RDP_POINTER_SYSTEM:
1024  {                          process_system_pointer_pdu(s);
1025          uint16 length = RDP_CAPLEN_SHARE;                          break;
         uint16 pkt_length = length;  
         BOOL res;  
1026    
1027          res = lsb_io_uint16(s, &pkt_length);                  default:
1028          if (pkt_length != length)                          unimpl("Pointer message 0x%x\n", message_type);
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
1029          }          }
   
         res = res ? lsb_io_uint16(s, &caps->userid) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad   ) : False;  
   
         return res;  
1030  }  }
1031    
1032  BOOL rdp_io_colcache_caps(STREAM s, RDP_COLCACHE_CAPS *caps)  /* Process bitmap updates */
1033    void
1034    process_bitmap_updates(STREAM s)
1035  {  {
1036          uint16 length = RDP_CAPLEN_COLCACHE;          uint16 num_updates;
1037          uint16 pkt_length = length;          uint16 left, top, right, bottom, width, height;
1038          BOOL res;          uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
1039            uint8 *data, *bmpdata;
1040            int i;
1041    
1042          res = lsb_io_uint16(s, &pkt_length);          in_uint16_le(s, num_updates);
         if (pkt_length != length)  
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
1043    
1044          res = res ? lsb_io_uint16(s, &caps->cache_size) : False;          for (i = 0; i < num_updates; i++)
1045          res = res ? lsb_io_uint16(s, &caps->pad       ) : False;          {
1046                    in_uint16_le(s, left);
1047                    in_uint16_le(s, top);
1048                    in_uint16_le(s, right);
1049                    in_uint16_le(s, bottom);
1050                    in_uint16_le(s, width);
1051                    in_uint16_le(s, height);
1052                    in_uint16_le(s, bpp);
1053                    Bpp = (bpp + 7) / 8;
1054                    in_uint16_le(s, compress);
1055                    in_uint16_le(s, bufsize);
1056    
1057          return res;                  cx = right - left + 1;
1058  }                  cy = bottom - top + 1;
1059    
1060  uint8 canned_caps[] = {                  DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
1061  0x01,0x00,0x00,0x00,0x09,0x04,0x00,0x00,0x04,                         left, top, right, bottom, width, height, Bpp, compress));
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x08,0x00,0x01,  
 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  
 };  
1062    
1063  BOOL rdp_io_unknown_caps(STREAM s, void *caps)                  if (!compress)
1064  {                  {
1065          uint16 length = 0x58;                          int y;
1066          uint16 pkt_length = length;                          bmpdata = (uint8 *) xmalloc(width * height * Bpp);
1067          BOOL res;                          for (y = 0; y < height; y++)
1068                            {
1069                                    in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
1070                                              width * Bpp);
1071                            }
1072                            ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
1073                            xfree(bmpdata);
1074                            continue;
1075                    }
1076    
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
1077    
1078          res = res ? prs_io_uint8s(s, canned_caps, RDP_CAPLEN_UNKNOWN-4) : False;                  if (compress & 0x400)
1079                    {
1080                            size = bufsize;
1081                    }
1082                    else
1083                    {
1084                            in_uint8s(s, 2);        /* pad */
1085                            in_uint16_le(s, size);
1086                            in_uint8s(s, 4);        /* line_size, final_size */
1087                    }
1088                    in_uint8p(s, data, size);
1089                    bmpdata = (uint8 *) xmalloc(width * height * Bpp);
1090                    if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
1091                    {
1092                            ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
1093                    }
1094                    else
1095                    {
1096                            DEBUG_RDP5(("Failed to decompress data\n"));
1097                    }
1098    
1099          return res;                  xfree(bmpdata);
1100            }
1101  }  }
1102    
1103  BOOL rdp_io_active_pdu(STREAM s, RDP_ACTIVE_PDU *pdu, int pdutype)  /* Process a palette update */
1104    void
1105    process_palette(STREAM s)
1106  {  {
1107          uint16 capset;          COLOURENTRY *entry;
1108          uint16 length;          COLOURMAP map;
1109          BOOL res;          HCOLOURMAP hmap;
1110          int i;          int i;
1111    
1112          res = lsb_io_uint32(s, &pdu->shareid);          in_uint8s(s, 2);        /* pad */
1113            in_uint16_le(s, map.ncolours);
1114            in_uint8s(s, 2);        /* pad */
1115    
1116          if (pdutype == RDP_PDU_CONFIRM_ACTIVE)          map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
                 res = res ? lsb_io_uint16(s, &pdu->userid    ) : False;  
1117    
1118          res = res ? lsb_io_uint16(s, &pdu->source_len) : False;          DEBUG(("PALETTE(c=%d)\n", map.ncolours));
         res = res ? lsb_io_uint16(s, &pdu->caps_len  ) : False;  
1119    
1120          if (pdu->source_len > 48)          for (i = 0; i < map.ncolours; i++)
1121          {          {
1122                  fprintf(stderr, "RDP source descriptor too long\n");                  entry = &map.colours[i];
1123                  return False;                  in_uint8(s, entry->red);
1124                    in_uint8(s, entry->green);
1125                    in_uint8(s, entry->blue);
1126          }          }
1127    
1128          res = res ? prs_io_uint8s(s,  pdu->source, pdu->source_len) : False;          hmap = ui_create_colourmap(&map);
1129          res = res ? lsb_io_uint16(s, &pdu->num_caps  ) : False;          ui_set_colourmap(hmap);
         res = res ? lsb_io_uint16(s, &pdu->pad       ) : False;  
   
         if (s->marshall)  
         {  
                 capset = RDP_CAPSET_GENERAL;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_general_caps(s, &pdu->general_caps) : False;  
   
                 capset = RDP_CAPSET_BITMAP;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_bitmap_caps (s, &pdu->bitmap_caps ) : False;  
   
                 capset = RDP_CAPSET_ORDER;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_order_caps  (s, &pdu->order_caps  ) : False;  
   
                 capset = RDP_CAPSET_BMPCACHE;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_bmpcache_caps(s, &pdu->bmpcache_caps) : False;  
   
                 capset = RDP_CAPSET_COLCACHE;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_colcache_caps(s, &pdu->colcache_caps) : False;  
   
                 capset = RDP_CAPSET_ACTIVATE;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_activate_caps(s, &pdu->activate_caps) : False;  
   
                 capset = RDP_CAPSET_CONTROL;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_control_caps(s, &pdu->control_caps) : False;  
   
                 capset = RDP_CAPSET_POINTER;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_pointer_caps(s, &pdu->pointer_caps) : False;  
   
                 capset = RDP_CAPSET_SHARE;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_share_caps  (s, &pdu->share_caps  ) : False;  
   
                 capset = RDP_CAPSET_UNKNOWN;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_unknown_caps(s, NULL) : False;  
         }  
         else  
         {  
                 for (i = 0; i < pdu->num_caps; i++)  
                 {  
                         if (!res)  
                                 return False;  
1130    
1131                          if (!lsb_io_uint16(s, &capset))          xfree(map.colours);
1132                                  return False;  }
1133    
1134                          switch (capset)  /* Process an update PDU */
1135                          {  static void
1136                          case RDP_CAPSET_GENERAL:  process_update_pdu(STREAM s)
1137                                  res = rdp_io_general_caps (s, &pdu->general_caps );  {
1138                                  break;          uint16 update_type, count;
                         case RDP_CAPSET_BITMAP:  
                                 res = rdp_io_bitmap_caps  (s, &pdu->bitmap_caps  );  
                                 break;  
                         case RDP_CAPSET_ORDER:  
                                 res = rdp_io_order_caps   (s, &pdu->order_caps   );  
                                 break;  
                         case RDP_CAPSET_BMPCACHE:  
                                 res = rdp_io_bmpcache_caps(s, &pdu->bmpcache_caps);  
                                 break;  
                         case RDP_CAPSET_CONTROL:  
                                 res = rdp_io_control_caps (s, &pdu->control_caps );  
                                 break;  
                         case RDP_CAPSET_ACTIVATE:  
                                 res = rdp_io_activate_caps(s, &pdu->activate_caps);  
                                 break;  
                         case RDP_CAPSET_POINTER:  
                                 res = rdp_io_pointer_caps (s, &pdu->pointer_caps );  
                                 break;  
                         case RDP_CAPSET_SHARE:  
                                 res = rdp_io_share_caps   (s, &pdu->share_caps   );  
                                 break;  
                         case RDP_CAPSET_COLCACHE:  
                                 res = rdp_io_colcache_caps(s, &pdu->colcache_caps);  
                                 break;  
                         default:  
                                 fprintf(stderr, "Warning: Unrecognised capset %x\n",  
                                         capset);  
1139    
1140                                  if (!lsb_io_uint16(s, &length))          in_uint16_le(s, update_type);
                                         return False;  
1141    
1142                                  s->offset += (length - 4);          ui_begin_update();
1143                          }          switch (update_type)
1144                  }          {
1145          }                  case RDP_UPDATE_ORDERS:
1146                            in_uint8s(s, 2);        /* pad */
1147                            in_uint16_le(s, count);
1148                            in_uint8s(s, 2);        /* pad */
1149                            process_orders(s, count);
1150                            break;
1151    
1152          return res;                  case RDP_UPDATE_BITMAP:
1153  }                          process_bitmap_updates(s);
1154                            break;
1155    
1156  BOOL rdp_io_control_pdu(STREAM s, RDP_CONTROL_PDU *pdu)                  case RDP_UPDATE_PALETTE:
1157  {                          process_palette(s);
1158          BOOL res = True;                          break;
1159    
1160          res = res ? lsb_io_uint16(s, &pdu->action   ) : False;                  case RDP_UPDATE_SYNCHRONIZE:
1161          res = res ? lsb_io_uint16(s, &pdu->userid   ) : False;                          break;
         res = res ? lsb_io_uint32(s, &pdu->controlid) : False;  
1162    
1163          return res;                  default:
1164                            unimpl("update %d\n", update_type);
1165            }
1166            ui_end_update();
1167  }  }
1168    
1169  BOOL rdp_io_synchronize_pdu(STREAM s, RDP_SYNCHRONIZE_PDU *pdu)  /* Process a disconnect PDU */
1170    void
1171    process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
1172  {  {
1173          BOOL res = True;          in_uint32_le(s, *ext_disc_reason);
   
         res = res ? lsb_io_uint16(s, &pdu->type  ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->userid) : False;  
1174    
1175          return res;          DEBUG(("Received disconnect PDU\n"));
1176  }  }
1177    
1178  BOOL rdp_io_input_event(STREAM s, RDP_INPUT_EVENT *evt)  /* Process data PDU */
1179    static BOOL
1180    process_data_pdu(STREAM s, uint32 * ext_disc_reason)
1181  {  {
1182          BOOL res = True;          uint8 data_pdu_type;
1183            uint8 ctype;
1184            uint16 clen;
1185            uint32 len;
1186    
1187          res = res ? lsb_io_uint32(s, &evt->event_time)   : False;          uint32 roff, rlen;
         res = res ? lsb_io_uint16(s, &evt->message_type) : False;  
1188    
1189          if (!res)          struct stream *ns = &(g_mppc_dict.ns);
                 return False;  
1190    
1191          switch (evt->message_type)          in_uint8s(s, 6);        /* shareid, pad, streamid */
1192            in_uint16(s, len);
1193            in_uint8(s, data_pdu_type);
1194            in_uint8(s, ctype);
1195            in_uint16(s, clen);
1196            clen -= 18;
1197    
1198            if (ctype & RDP_MPPC_COMPRESSED)
1199          {          {
1200          case RDP_INPUT_CODEPOINT:                  if (len > RDP_MPPC_DICT_SIZE)
1201          case RDP_INPUT_VIRTKEY:                          error("error decompressed packet size exceeds max\n");
1202                  res = res ? lsb_io_uint16(s, &evt->device_flags) : False;                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
1203                  res = res ? lsb_io_uint16(s, &evt->kbd_keycode ) : False;                          error("error while decompressing packet\n");
                 break;  
         case RDP_INPUT_SYNCHRONIZE:  
         case RDP_INPUT_UNKNOWN:  
         case RDP_INPUT_MOUSE:  
                 res = res ? lsb_io_uint16(s, &evt->device_flags) : False;  
                 res = res ? lsb_io_uint16(s, &evt->mouse_x     ) : False;  
                 res = res ? lsb_io_uint16(s, &evt->mouse_y     ) : False;  
                 break;  
         default:  
                 fprintf(stderr, "Unknown input type %d\n", evt->message_type);  
                 return False;  
         }  
1204    
1205          return res;                  /* len -= 18; */
 }  
1206    
1207  BOOL rdp_io_input_pdu(STREAM s, RDP_INPUT_PDU *pdu)                  /* allocate memory and copy the uncompressed data into the temporary stream */
1208  {                  ns->data = (uint8 *) xrealloc(ns->data, rlen);
         BOOL res = True;  
         int i;  
1209    
1210          res = res ? lsb_io_uint16(s, &pdu->num_events) : False;                  memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
         res = res ? lsb_io_uint16(s, &pdu->pad       ) : False;  
1211    
1212          if (pdu->num_events > RDP_MAX_EVENTS)                  ns->size = rlen;
1213          {                  ns->end = (ns->data + ns->size);
1214                  fprintf(stderr, "Too many events in one PDU\n");                  ns->p = ns->data;
1215                  return False;                  ns->rdp_hdr = ns->p;
         }  
1216    
1217          for (i = 0; i < pdu->num_events; i++)                  s = ns;
         {  
                 res = res ? rdp_io_input_event(s, &pdu->event[i]) : False;  
1218          }          }
1219    
1220          return res;          switch (data_pdu_type)
1221  }          {
1222                    case RDP_DATA_PDU_UPDATE:
1223                            process_update_pdu(s);
1224                            break;
1225    
1226  BOOL rdp_io_font_info(STREAM s, RDP_FONT_INFO *font)                  case RDP_DATA_PDU_CONTROL:
1227  {                          DEBUG(("Received Control PDU\n"));
1228          BOOL res = True;                          break;
1229    
1230          res = res ? prs_io_uint8s(s,  font->name, 32 ) : False;                  case RDP_DATA_PDU_SYNCHRONISE:
1231          res = res ? lsb_io_uint16(s, &font->flags    ) : False;                          DEBUG(("Received Sync PDU\n"));
1232          res = res ? lsb_io_uint16(s, &font->width    ) : False;                          break;
         res = res ? lsb_io_uint16(s, &font->height   ) : False;  
         res = res ? lsb_io_uint16(s, &font->xaspect  ) : False;  
         res = res ? lsb_io_uint16(s, &font->yaspect  ) : False;  
         res = res ? lsb_io_uint32(s, &font->signature) : False;  
         res = res ? lsb_io_uint16(s, &font->codepage ) : False;  
         res = res ? lsb_io_uint16(s, &font->ascent   ) : False;  
1233    
1234          return res;                  case RDP_DATA_PDU_POINTER:
1235  }                          process_pointer_pdu(s);
1236                            break;
1237    
1238  BOOL rdp_io_font_pdu(STREAM s, RDP_FONT_PDU *pdu)                  case RDP_DATA_PDU_BELL:
1239  {                          ui_bell();
1240          BOOL res = True;                          break;
         int i;  
1241    
1242          res = res ? lsb_io_uint16(s, &pdu->num_fonts ) : False;                  case RDP_DATA_PDU_LOGON:
1243          res = res ? lsb_io_uint16(s, &pdu->unknown1  ) : False;                          DEBUG(("Received Logon PDU\n"));
1244          res = res ? lsb_io_uint16(s, &pdu->unknown2  ) : False;                          /* User logged on */
1245          res = res ? lsb_io_uint16(s, &pdu->entry_size) : False;                          break;
1246    
1247          if (pdu->num_fonts > RDP_MAX_FONTS)                  case RDP_DATA_PDU_DISCONNECT:
1248          {                          process_disconnect_pdu(s, ext_disc_reason);
1249                  fprintf(stderr, "Too many fonts in one PDU\n");                          return True;
                 return False;  
         }  
1250    
1251          for (i = 0; i < pdu->num_fonts; i++)                  default:
1252          {                          unimpl("data PDU %d\n", data_pdu_type);
                 res = res ? rdp_io_font_info(s, &pdu->font[i]) : False;  
1253          }          }
1254            return False;
         return res;  
1255  }  }
1256    
1257  BOOL rdp_io_update_pdu(STREAM s, RDP_UPDATE_PDU *pdu)  /* Process incoming packets */
1258    /* nevers gets out of here till app is done */
1259    void
1260    rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1261  {  {
1262          BOOL res = True;          while (rdp_loop(deactivated, ext_disc_reason))
1263                    ;
         res = res ? lsb_io_uint16(s, &pdu->update_type) : False;  
         res = res ? lsb_io_uint16(s, &pdu->pad        ) : False;  
   
         return res;  
1264  }  }
1265    
1266  BOOL rdp_io_secondary_order(STREAM s, RDP_SECONDARY_ORDER *rso)  /* used in uiports and rdp_main_loop, processes the rdp packets waiting */
1267    BOOL
1268    rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1269  {  {
1270          BOOL res = True;          uint8 type;
1271            BOOL disc = False;      /* True when a disconnect PDU was received */
1272          res = res ? lsb_io_uint16(s, &rso->length) : False;          BOOL cont = True;
1273          res = res ? lsb_io_uint16(s, &rso->flags ) : False;          STREAM s;
         res = res ? prs_io_uint8 (s, &rso->type  ) : False;  
1274    
1275          return res;          while (cont)
1276            {
1277                    s = rdp_recv(&type);
1278                    if (s == NULL)
1279                            return False;
1280                    switch (type)
1281                    {
1282                            case RDP_PDU_DEMAND_ACTIVE:
1283                                    process_demand_active(s);
1284                                    *deactivated = False;
1285                                    break;
1286                            case RDP_PDU_DEACTIVATE:
1287                                    DEBUG(("RDP_PDU_DEACTIVATE\n"));
1288                                    *deactivated = True;
1289                                    break;
1290                            case RDP_PDU_DATA:
1291                                    disc = process_data_pdu(s, ext_disc_reason);
1292                                    break;
1293                            case 0:
1294                                    break;
1295                            default:
1296                                    unimpl("PDU %d\n", type);
1297                    }
1298                    if (disc)
1299                            return False;
1300                    cont = g_next_packet < s->end;
1301            }
1302            return True;
1303  }  }
1304    
1305  BOOL rdp_io_bitmap_header(STREAM s, RDP_BITMAP_HEADER *rdh)  /* Establish a connection up to the RDP layer */
1306    BOOL
1307    rdp_connect(char *server, uint32 flags, char *domain, char *password,
1308                char *command, char *directory)
1309  {  {
1310          BOOL res = True;          if (!sec_connect(server, g_username))
1311                    return False;
         res = res ? prs_io_uint8 (s, &rdh->cache_id  ) : False;  
         res = res ? prs_io_uint8 (s, &rdh->pad1      ) : False;  
         res = res ? prs_io_uint8 (s, &rdh->width     ) : False;  
         res = res ? prs_io_uint8 (s, &rdh->height    ) : False;  
         res = res ? prs_io_uint8 (s, &rdh->bpp       ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->bufsize   ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->cache_idx ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->pad2      ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->size      ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->row_size  ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->final_size) : False;  
1312    
1313          return res;          rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1314            return True;
1315  }  }
1316    
1317  BOOL rdp_io_pointer(STREAM s, RDP_POINTER *ptr)  /* Disconnect from the RDP layer */
1318    void
1319    rdp_disconnect(void)
1320  {  {
1321          BOOL res = True;          sec_disconnect();
   
         res = res ? lsb_io_uint16(s, &ptr->message) : False;  
         res = res ? lsb_io_uint16(s, &ptr->pad    ) : False;  
         res = res ? lsb_io_uint16(s, &ptr->x      ) : False;  
         res = res ? lsb_io_uint16(s, &ptr->y      ) : False;  
   
         return res;  
1322  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26