/[rdesktop]/jpeg/rdesktop/trunk/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 /jpeg/rdesktop/trunk/rdp.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

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

Legend:
Removed from v.6  
changed lines
  Added in v.858

  ViewVC Help
Powered by ViewVC 1.1.26