/[rdesktop]/sourceforge.net/trunk/rdesktop/rdp.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /sourceforge.net/trunk/rdesktop/rdp.c

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

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

Legend:
Removed from v.4  
changed lines
  Added in v.855

  ViewVC Help
Powered by ViewVC 1.1.26