/[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

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

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

  ViewVC Help
Powered by ViewVC 1.1.26