/[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 6 by matty, Wed Jul 5 07:44:21 2000 UTC revision 260 by astrand, Mon Nov 18 15:31:19 2002 UTC
# Line 1  Line 1 
1  /*  /*
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-2002
5        
6     This program is free software; you can redistribute it and/or modify     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by     it under the terms of the GNU General Public License as published by
# Line 18  Line 18 
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 "rdesktop.h"
22    
23  /* Establish a connection up to the RDP layer */  extern uint16 mcs_userid;
24  HCONN rdp_connect(char *server)  extern char username[16];
25  {  extern BOOL bitmap_compression;
26          HCONN conn;  extern BOOL orders;
27          RDP_ACTIVE_PDU active;  extern BOOL encryption;
28          uint8 type;  extern BOOL desktop_save;
29    
30          if ((conn = mcs_connect(server)) == NULL)  uint8 *next_packet;
31                  return NULL;  uint32 rdp_shareid;
32    
33          rdp_establish_key(conn);  /* Initialise an RDP packet */
34          mcs_recv(conn, False); /* Server's licensing certificate */  static STREAM
35          rdp_send_cert(conn);  rdp_init(int maxlen)
36          mcs_recv(conn, False);  {
37            STREAM s;
38    
39          if (!rdp_recv_pdu(conn, &type) || (type != RDP_PDU_DEMAND_ACTIVE))          s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 6);
40          {          s_push_layer(s, rdp_hdr, 6);
                 fprintf(stderr, "RDP error, expected Demand Active\n");  
                 mcs_disconnect(conn);  
                 return NULL;  
         }  
41    
42          rdp_io_active_pdu(&conn->in, &active, RDP_PDU_DEMAND_ACTIVE);          return s;
43          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  
   
         return conn;  
 }  
   
 void rdp_main_loop(HCONN conn)  
 {  
         RDP_DATA_HEADER hdr;  
         RDP_UPDATE_PDU update;  
         RDP_ORDER_STATE os;  
         uint8 type;  
44    
45          memset(&os, 0, sizeof(os));  /* Send an RDP packet */
46    static void
47    rdp_send(STREAM s, uint8 pdu_type)
48    {
49            uint16 length;
50    
51          while (rdp_recv_pdu(conn, &type))          s_pop_layer(s, rdp_hdr);
52          {          length = s->end - s->p;
                 if (type != RDP_PDU_DATA)  
                         continue;  
53    
54                  rdp_io_data_header(&conn->in, &hdr);          out_uint16_le(s, length);
55            out_uint16_le(s, (pdu_type | 0x10));    /* Version 1 */
56            out_uint16_le(s, (mcs_userid + 1001));
57    
58                  switch (hdr.data_pdu_type)          sec_send(s, encryption ? SEC_ENCRYPT : 0);
                 {  
                 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;  
                 }  
         }  
59  }  }
60    
61  void prs_io_coord(STREAM s, uint16 *coord, BOOL delta)  /* Receive an RDP packet */
62    static STREAM
63    rdp_recv(uint8 * type)
64  {  {
65          uint8 change;          static STREAM rdp_s;
66            uint16 length, pdu_type;
67    
68          if (delta)          if ((rdp_s == NULL) || (next_packet >= rdp_s->end))
69          {          {
70                  prs_io_uint8(s, &change);                  rdp_s = sec_recv();
71                  *coord += change;                  if (rdp_s == NULL)
72                            return NULL;
73    
74                    next_packet = rdp_s->p;
75          }          }
76          else          else
77          {          {
78                  lsb_io_uint16(s, coord);                  rdp_s->p = next_packet;
79          }          }
 }  
80    
81  void process_opaque_rect(HCONN conn, RDP_ORDER_STATE *os, BOOL delta)          in_uint16_le(rdp_s, length);
82  {          in_uint16_le(rdp_s, pdu_type);
83          uint8 present;          in_uint8s(rdp_s, 2);    /* userid */
84          prs_io_uint8(&conn->in, &present);          *type = pdu_type & 0xf;
   
         if (present & 1)  
                 prs_io_coord(&conn->in, &os->opaque_rect.x, delta);  
85    
86          if (present & 2)  #if WITH_DEBUG
87                  prs_io_coord(&conn->in, &os->opaque_rect.y, delta);          DEBUG(("RDP packet (type %x):\n", *type));
88            hexdump(next_packet, length);
89    #endif /*  */
90    
91          if (present & 4)          next_packet += length;
92                  prs_io_coord(&conn->in, &os->opaque_rect.cx, delta);          return rdp_s;
93    }
94    
95          if (present & 8)  /* Initialise an RDP data packet */
96                  prs_io_coord(&conn->in, &os->opaque_rect.cy, delta);  static STREAM
97    rdp_init_data(int maxlen)
98    {
99            STREAM s;
100    
101          if (present & 16)          s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 18);
102                  prs_io_uint8(&conn->in, &os->opaque_rect.colour);          s_push_layer(s, rdp_hdr, 18);
103    
104          fprintf(stderr, "Opaque rectangle at %d, %d\n", os->opaque_rect.x, os->opaque_rect.y);          return s;
105  }  }
106    
107  void process_bmpcache(HCONN conn)  /* Send an RDP data packet */
108    static void
109    rdp_send_data(STREAM s, uint8 data_pdu_type)
110  {  {
111            uint16 length;
112    
113          RDP_BITMAP_HEADER rbh;          s_pop_layer(s, rdp_hdr);
114          char *bmpdata;          length = s->end - s->p;
         HBITMAP bmp;  
         static int x = 0;  
   
         rdp_io_bitmap_header(&conn->in, &rbh);  
         fprintf(stderr, "Decompressing bitmap %d x %d, final size %d\n", rbh.width, rbh.height, rbh.final_size);  
115    
116          bmpdata = malloc(rbh.width * rbh.height);          out_uint16_le(s, length);
117          bitmap_decompress(conn->in.data          out_uint16_le(s, (RDP_PDU_DATA | 0x10));
118                            + conn->in.offset, rbh.size,          out_uint16_le(s, (mcs_userid + 1001));
                           bmpdata, rbh.width);  
         conn->in.offset += rbh.size;  
119    
120          bmp = ui_create_bitmap(conn->wnd, rbh.width, rbh.height, bmpdata);          out_uint32_le(s, rdp_shareid);
121          ui_paint_bitmap(conn->wnd, bmp, x, 0);          out_uint8(s, 0);        /* pad */
122          ui_destroy_bitmap(bmp);          out_uint8(s, 1);        /* streamid */
123            out_uint16_le(s, (length - 14));
124            out_uint8(s, data_pdu_type);
125            out_uint8(s, 0);        /* compress_type */
126            out_uint16(s, 0);       /* compress_len */
127    
128          x += rbh.width;          sec_send(s, encryption ? SEC_ENCRYPT : 0);
129  }  }
130    
131  void process_orders(HCONN conn, RDP_ORDER_STATE *os)  /* Output a string in Unicode */
132    void
133    rdp_out_unistr(STREAM s, char *string, int len)
134  {  {
135          uint16 num_orders;          int i = 0, j = 0;
         int processed = 0;  
         BOOL res = True;  
         //      unsigned char *p;  
   
         lsb_io_uint16(&conn->in, &num_orders);  
   
         conn->in.offset += 2;  
         //      p = &conn->in.data[conn->in.offset];  
136    
137          //      fprintf(stderr, "%02X %02X %02X %02X\n", p[0], p[1], p[2], p[3]);          len += 2;
138    
139          while ((processed < num_orders) && res)          while (i < len)
140          {          {
141                  uint8 order_flags;                  s->p[i++] = string[j++];
142                    s->p[i++] = 0;
                 prs_io_uint8(&conn->in, &order_flags);  
   
                 if (!(order_flags & RDP_ORDER_STANDARD))  
                         return;  
   
                 if (order_flags & RDP_ORDER_SECONDARY)  
                 {  
                         RDP_SECONDARY_ORDER rso;  
   
                         rdp_io_secondary_order(&conn->in, &rso);  
                         switch (rso.type)  
                         {  
                         case RDP_ORDER_BMPCACHE:  
                                 process_bmpcache(conn);  
                                 break;  
                         default:  
                                 fprintf(stderr, "Unknown secondary order %d\n",  
                                         rso.type);  
                                 return;  
                         }  
   
   
                 }  
   
                 if (order_flags & RDP_ORDER_CHANGE)  
                         prs_io_uint8(&conn->in, &os->order_type);  
   
                 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;  
                 }  
   
                 processed++;  
143          }          }
 }  
144    
145  /* Work this out later. This is useless anyway when encryption is off. */          s->p += len;
 uint8 precanned_key_packet[] = {  
    0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x00,0x00,0x00,0x00,0x00,  
    0x00,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6c,0x86,  
    0xf7,0x99,0xef,0x60,0xc4,0x49,0x52,0xd0,0xd8,0xea,0xb5,0x4f,0x58,0x19,  
    0x52,0x2a,0x93,0x83,0x57,0x4f,0x4e,0x04,0xde,0x96,0x51,0xab,0x13,0x20,  
    0xd8,0xe5,0x00,0x00,0x00,0x00,0x00,0x00  
 };  
   
 /* Create an RC4 key and transfer it to the server */  
 void rdp_establish_key(HCONN conn)  
 {  
         mcs_init_data(conn);  
         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  
 };  
   
 /* Send license certificate and related data to the server */  
 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);  
146  }  }
147    
148  /* Initialise RDP transport packet */  /* Parse a logon info packet */
149  void rdp_init(HCONN conn)  static void
150    rdp_send_logon_info(uint32 flags, char *domain, char *user,
151                        char *password, char *program, char *directory)
152  {  {
153          mcs_init_data(conn);          int len_domain = 2 * strlen(domain);
154          PUSH_LAYER(conn->out, rdp_offset, 6);          int len_user = 2 * strlen(user);
155  }          int len_password = 2 * strlen(password);
156            int len_program = 2 * strlen(program);
157            int len_directory = 2 * strlen(directory);
158            uint32 sec_flags = encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
159            STREAM s;
160    
161  /* Transmit RDP transport packet */          s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
162  void rdp_send(HCONN conn, uint16 pdu_type)                       + len_program + len_directory + 10);
 {  
         RDP_HEADER hdr;  
         int length;  
163    
164          POP_LAYER(conn->out, rdp_offset);          out_uint32(s, 0);
165          length = conn->out.end - conn->out.offset;          out_uint32_le(s, flags);
166          rdp_make_header(&hdr, length, pdu_type, conn->mcs_userid);          out_uint16_le(s, len_domain);
167          rdp_io_header(&conn->out, &hdr);          out_uint16_le(s, len_user);
168          mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);          out_uint16_le(s, len_password);
169  }          out_uint16_le(s, len_program);
170            out_uint16_le(s, len_directory);
171            rdp_out_unistr(s, domain, len_domain);
172            rdp_out_unistr(s, user, len_user);
173            rdp_out_unistr(s, password, len_password);
174            rdp_out_unistr(s, program, len_program);
175            rdp_out_unistr(s, directory, len_directory);
176    
177  /* Initialise RDP transport data packet */          s_mark_end(s);
178  void rdp_init_data(HCONN conn)          sec_send(s, sec_flags);
 {  
         mcs_init_data(conn);  
         PUSH_LAYER(conn->out, rdp_offset, 18);  
179  }  }
180    
181  /* Transmit RDP transport data packet */  /* Send a control PDU */
182  void rdp_send_data(HCONN conn, uint16 data_pdu_type)  static void
183    rdp_send_control(uint16 action)
184  {  {
185          RDP_HEADER hdr;          STREAM s;
         RDP_DATA_HEADER datahdr;  
         int length = conn->out.end - conn->out.offset;  
186    
187          POP_LAYER(conn->out, rdp_offset);          s = rdp_init_data(8);
         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);  
 }  
188    
189  void rdp_send_confirm_active(HCONN conn)          out_uint16_le(s, action);
190  {          out_uint16(s, 0);       /* userid */
191          RDP_ACTIVE_PDU active;          out_uint32(s, 0);       /* control id */
192    
193          rdp_init(conn);          s_mark_end(s);
194          rdp_make_active_pdu(&active, 0x103ea, conn->mcs_userid);          rdp_send_data(s, RDP_DATA_PDU_CONTROL);
         rdp_io_active_pdu(&conn->out, &active, RDP_PDU_CONFIRM_ACTIVE);  
         MARK_END(conn->out);  
         rdp_send(conn, RDP_PDU_CONFIRM_ACTIVE);  
195  }  }
196    
197  void rdp_send_synchronize(HCONN conn)  /* Send a synchronisation PDU */
198    static void
199    rdp_send_synchronise(void)
200  {  {
201          RDP_SYNCHRONIZE_PDU sync;          STREAM s;
202    
203          rdp_init_data(conn);          s = rdp_init_data(4);
         rdp_make_synchronize_pdu(&sync, 1002);  
         rdp_io_synchronize_pdu(&conn->out, &sync);  
         MARK_END(conn->out);  
         rdp_send_data(conn, RDP_DATA_PDU_SYNCHRONIZE);  
 }  
204    
205  void rdp_send_control(HCONN conn, uint16 action)          out_uint16_le(s, 1);    /* type */
206  {          out_uint16_le(s, 1002);
         RDP_CONTROL_PDU control;  
207    
208          rdp_init_data(conn);          s_mark_end(s);
209          rdp_make_control_pdu(&control, action);          rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);
         rdp_io_control_pdu(&conn->out, &control);  
         MARK_END(conn->out);  
         rdp_send_data(conn, RDP_DATA_PDU_CONTROL);  
210  }  }
211    
212  void rdp_send_fonts(HCONN conn, uint16 seqno)  /* Send a single input event */
213    void
214    rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
215  {  {
216          RDP_FONT_PDU fonts;          STREAM s;
217    
218          rdp_init_data(conn);          s = rdp_init_data(16);
         rdp_make_font_pdu(&fonts, seqno);  
         rdp_io_font_pdu(&conn->out, &fonts);  
         MARK_END(conn->out);  
         rdp_send_data(conn, RDP_DATA_PDU_FONT2);  
 }  
219    
220  void rdp_send_input(HCONN conn)          out_uint16_le(s, 1);    /* number of events */
221  {          out_uint16(s, 0);       /* pad */
         RDP_INPUT_PDU input;  
222    
223          rdp_init_data(conn);          out_uint32_le(s, time);
224          rdp_make_input_pdu(&input);          out_uint16_le(s, message_type);
225          rdp_io_input_pdu(&conn->out, &input);          out_uint16_le(s, device_flags);
226          MARK_END(conn->out);          out_uint16_le(s, param1);
227          rdp_send_data(conn, RDP_DATA_PDU_INPUT);          out_uint16_le(s, param2);
 }  
228    
229  BOOL rdp_recv_pdu(HCONN conn, uint8 *type)          s_mark_end(s);
230  {          rdp_send_data(s, RDP_DATA_PDU_INPUT);
         RDP_HEADER hdr;  
   
         if (!mcs_recv(conn, False) || !rdp_io_header(&conn->in, &hdr))  
                 return False;  
   
         *type = hdr.pdu_type & 0xf;  
         return True;  
231  }  }
232    
233  /* Disconnect from the RDP layer */  /* Send an (empty) font information PDU */
234  void rdp_disconnect(HCONN conn)  static void
235    rdp_send_fonts(uint16 seq)
236  {  {
237          mcs_disconnect(conn);          STREAM s;
 }  
238    
239  void rdp_make_header(RDP_HEADER *hdr, uint16 length, uint16 pdu_type,          s = rdp_init_data(8);
                      uint16 userid)  
 {  
         hdr->length = length;  
         hdr->pdu_type = pdu_type | 0x10; /* Version 1 */  
         hdr->userid = userid + 1001;  
 }  
240    
241  void rdp_make_data_header(RDP_DATA_HEADER *hdr, uint32 shareid,          out_uint16(s, 0);       /* number of fonts */
242                            uint16 length, uint16 data_pdu_type)          out_uint16_le(s, 0x3e); /* unknown */
243  {          out_uint16_le(s, seq);  /* unknown */
244          hdr->shareid = shareid;          out_uint16_le(s, 0x32); /* entry size */
         hdr->pad = 0;  
         hdr->streamid = 1;  
         hdr->length = length - 14;  
         hdr->data_pdu_type = data_pdu_type;  
         hdr->compress_type = 0;  
         hdr->compress_len = 0;  
 }  
   
 void rdp_make_general_caps(RDP_GENERAL_CAPS *caps)  
 {  
         caps->os_major_type = 1;  
         caps->os_minor_type = 3;  
         caps->ver_protocol = 0x200;  
 }  
245    
246  void rdp_make_bitmap_caps(RDP_BITMAP_CAPS *caps)          s_mark_end(s);
247  {          rdp_send_data(s, RDP_DATA_PDU_FONT2);
         caps->preferred_bpp = 8;  
         caps->receive1bpp = 1;  
         caps->receive4bpp = 1;  
         caps->receive8bpp = 1;  
         caps->width = 640;  
         caps->height = 480;  
         caps->compression = 1;  
         caps->unknown2 = 1;  
248  }  }
249    
250  void rdp_make_order_caps(RDP_ORDER_CAPS *caps)  /* Output general capability set */
251    static void
252    rdp_out_general_caps(STREAM s)
253  {  {
254          caps->xgranularity = 1;          out_uint16_le(s, RDP_CAPSET_GENERAL);
255          caps->ygranularity = 20;          out_uint16_le(s, RDP_CAPLEN_GENERAL);
         caps->max_order_level = 1;  
         caps->num_fonts = 0x147;  
         caps->cap_flags = 0x2A;  
256    
257  //      caps->cap_flags = ORDER_CAP_NEGOTIATE | ORDER_CAP_NOSUPPORT;          out_uint16_le(s, 1);    /* OS major type */
258            out_uint16_le(s, 3);    /* OS minor type */
259          caps->support[0] = caps->support[1] = caps->support[2]          out_uint16_le(s, 0x200);        /* Protocol version */
260                  = caps->support[3] = caps->support[4] = caps->support[5]          out_uint16(s, 0);       /* Pad */
261                  = caps->support[6] = caps->support[8] = caps->support[11]          out_uint16(s, 0);       /* Compression types */
262                  = caps->support[12] = caps->support[22] = caps->support[28]          out_uint16(s, 0);       /* Pad */
263                  = caps->support[29] = caps->support[30] = 1;          out_uint16(s, 0);       /* Update capability */
264          caps->text_cap_flags = 0x6A1;          out_uint16(s, 0);       /* Remote unshare capability */
265          caps->desk_save_size = 0x38400;          out_uint16(s, 0);       /* Compression level */
266          caps->unknown2 = 0x4E4;          out_uint16(s, 0);       /* Pad */
267  }  }
268    
269  void rdp_make_bmpcache_caps(RDP_BMPCACHE_CAPS *caps)  /* Output bitmap capability set */
270    static void
271    rdp_out_bitmap_caps(STREAM s)
272  {  {
273          caps->caches[0].entries = 0x258;          out_uint16_le(s, RDP_CAPSET_BITMAP);
274          caps->caches[0].max_cell_size = 0x100;          out_uint16_le(s, RDP_CAPLEN_BITMAP);
         caps->caches[1].entries = 0x12c;  
         caps->caches[1].max_cell_size = 0x400;  
         caps->caches[2].entries = 0x106;  
         caps->caches[2].max_cell_size = 0x1000;  
 }  
275    
276  void rdp_make_control_caps(RDP_CONTROL_CAPS *caps)          out_uint16_le(s, 8);    /* Preferred BPP */
277  {          out_uint16_le(s, 1);    /* Receive 1 BPP */
278          caps->control_interest = 2;          out_uint16_le(s, 1);    /* Receive 4 BPP */
279          caps->detach_interest = 2;          out_uint16_le(s, 1);    /* Receive 8 BPP */
280            out_uint16_le(s, 800);  /* Desktop width */
281            out_uint16_le(s, 600);  /* Desktop height */
282            out_uint16(s, 0);       /* Pad */
283            out_uint16(s, 0);       /* Allow resize */
284            out_uint16_le(s, bitmap_compression ? 1 : 0);   /* Support compression */
285            out_uint16(s, 0);       /* Unknown */
286            out_uint16_le(s, 1);    /* Unknown */
287            out_uint16(s, 0);       /* Pad */
288  }  }
289    
290  void rdp_make_activate_caps(RDP_ACTIVATE_CAPS *caps)  /* Output order capability set */
291    static void
292    rdp_out_order_caps(STREAM s)
293  {  {
294  }          uint8 order_caps[32];
295    
 void rdp_make_pointer_caps(RDP_POINTER_CAPS *caps)  
 {  
         caps->colour_pointer = 0;  
         caps->cache_size = 20;  
 }  
296    
297  void rdp_make_share_caps(RDP_SHARE_CAPS *caps, uint16 userid)          memset(order_caps, 0, 32);
298  {          order_caps[0] = 1;      /* dest blt */
299  }          order_caps[1] = 1;      /* pat blt */
300            order_caps[2] = 1;      /* screen blt */
301            order_caps[3] = 1;      /* required for memblt? */
302            order_caps[8] = 1;      /* line */
303            order_caps[9] = 1;      /* line */
304            order_caps[10] = 1;     /* rect */
305            order_caps[11] = (desktop_save == False ? 0 : 1);       /* desksave */
306            order_caps[13] = 1;     /* memblt */
307            order_caps[14] = 1;     /* triblt */
308            order_caps[22] = 1;     /* polyline */
309            order_caps[27] = 1;     /* text2 */
310            out_uint16_le(s, RDP_CAPSET_ORDER);
311            out_uint16_le(s, RDP_CAPLEN_ORDER);
312    
313  void rdp_make_colcache_caps(RDP_COLCACHE_CAPS *caps)          out_uint8s(s, 20);      /* Terminal desc, pad */
314  {          out_uint16_le(s, 1);    /* Cache X granularity */
315          caps->cache_size = 6;          out_uint16_le(s, 20);   /* Cache Y granularity */
316            out_uint16(s, 0);       /* Pad */
317            out_uint16_le(s, 1);    /* Max order level */
318            out_uint16_le(s, 0x147);        /* Number of fonts */
319            out_uint16_le(s, 0x2a); /* Capability flags */
320            out_uint8p(s, order_caps, 32);  /* Orders supported */
321            out_uint16_le(s, 0x6a1);        /* Text capability flags */
322            out_uint8s(s, 6);       /* Pad */
323            out_uint32_le(s, desktop_save == False ? 0 : 0x38400);  /* Desktop cache size */
324            out_uint32(s, 0);       /* Unknown */
325            out_uint32_le(s, 0x4e4);        /* Unknown */
326  }  }
327    
328  void rdp_make_active_pdu(RDP_ACTIVE_PDU *pdu, uint32 shareid, uint16 userid)  /* Output bitmap cache capability set */
329    static void
330    rdp_out_bmpcache_caps(STREAM s)
331  {  {
332          memset(pdu, 0, sizeof(*pdu));          out_uint16_le(s, RDP_CAPSET_BMPCACHE);
333          pdu->shareid = shareid;          out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
         pdu->userid  = 1002;  
         pdu->source_len = sizeof(RDP_SOURCE);  
         memcpy(pdu->source, RDP_SOURCE, sizeof(RDP_SOURCE));  
   
         pdu->caps_len = RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER  
                 + 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;  
334    
335          rdp_make_general_caps (&pdu->general_caps );          out_uint8s(s, 24);      /* unused */
336          rdp_make_bitmap_caps  (&pdu->bitmap_caps  );          out_uint16_le(s, 0x258);        /* entries */
337          rdp_make_order_caps   (&pdu->order_caps   );          out_uint16_le(s, 0x100);        /* max cell size */
338          rdp_make_bmpcache_caps(&pdu->bmpcache_caps);          out_uint16_le(s, 0x12c);        /* entries */
339          rdp_make_control_caps (&pdu->control_caps );          out_uint16_le(s, 0x400);        /* max cell size */
340          rdp_make_activate_caps(&pdu->activate_caps);          out_uint16_le(s, 0x106);        /* entries */
341          rdp_make_pointer_caps (&pdu->pointer_caps );          out_uint16_le(s, 0x1000);       /* max cell size */
         rdp_make_share_caps   (&pdu->share_caps, userid);  
         rdp_make_colcache_caps(&pdu->colcache_caps);  
342  }  }
343    
344  void rdp_make_control_pdu(RDP_CONTROL_PDU *pdu, uint16 action)  /* Output control capability set */
345    static void
346    rdp_out_control_caps(STREAM s)
347  {  {
348          pdu->action = action;          out_uint16_le(s, RDP_CAPSET_CONTROL);
349          pdu->userid = 0;          out_uint16_le(s, RDP_CAPLEN_CONTROL);
         pdu->controlid = 0;  
 }  
   
 void rdp_make_synchronize_pdu(RDP_SYNCHRONIZE_PDU *pdu, uint16 userid)  
 {  
         pdu->type = 1;  
         pdu->userid = userid;  
 }  
350    
351  void rdp_make_font_pdu(RDP_FONT_PDU *pdu, uint16 seqno)          out_uint16(s, 0);       /* Control capabilities */
352  {          out_uint16(s, 0);       /* Remote detach */
353          pdu->num_fonts = 0;          out_uint16_le(s, 2);    /* Control interest */
354          pdu->unknown1 = 0x3e;          out_uint16_le(s, 2);    /* Detach interest */
         pdu->unknown2 = seqno;  
         pdu->entry_size = RDP_FONT_INFO_SIZE;  
355  }  }
356    
357  void rdp_make_input_pdu(RDP_INPUT_PDU *pdu)  /* Output activation capability set */
358    static void
359    rdp_out_activate_caps(STREAM s)
360  {  {
361          uint32 now = time(NULL);          out_uint16_le(s, RDP_CAPSET_ACTIVATE);
362            out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
         pdu->num_events = 3;  
         pdu->pad = 0;  
   
         pdu->event[0].event_time = now;  
         pdu->event[0].message_type = RDP_INPUT_SYNCHRONIZE;  
         pdu->event[0].device_flags = 0;  
         pdu->event[0].mouse_x = 0;  
         pdu->event[0].mouse_y = 0;  
   
         pdu->event[1].event_time = now;  
         pdu->event[1].message_type = RDP_INPUT_UNKNOWN;  
         pdu->event[1].device_flags = 0x8000;  
         pdu->event[1].mouse_x = 15;  
         pdu->event[1].mouse_y = 0;  
363    
364          pdu->event[2].event_time = now;          out_uint16(s, 0);       /* Help key */
365          pdu->event[2].message_type = RDP_INPUT_MOUSE;          out_uint16(s, 0);       /* Help index key */
366          pdu->event[2].device_flags = MOUSE_FLAG_MOVE;          out_uint16(s, 0);       /* Extended help key */
367          pdu->event[2].mouse_x = 425;          out_uint16(s, 0);       /* Window activate */
         pdu->event[2].mouse_y = 493;  
368  }  }
369    
370  BOOL rdp_io_header(STREAM s, RDP_HEADER *hdr)  /* Output pointer capability set */
371    static void
372    rdp_out_pointer_caps(STREAM s)
373  {  {
374          BOOL res = True;          out_uint16_le(s, RDP_CAPSET_POINTER);
375            out_uint16_le(s, RDP_CAPLEN_POINTER);
376    
377          res = res ? lsb_io_uint16(s, &hdr->length  ) : False;          out_uint16(s, 0);       /* Colour pointer */
378          res = res ? lsb_io_uint16(s, &hdr->pdu_type) : False;          out_uint16_le(s, 20);   /* Cache size */
         res = res ? lsb_io_uint16(s, &hdr->userid  ) : False;  
   
         return res;  
379  }  }
380    
381  BOOL rdp_io_data_header(STREAM s, RDP_DATA_HEADER *hdr)  /* Output share capability set */
382    static void
383    rdp_out_share_caps(STREAM s)
384  {  {
385          BOOL res = True;          out_uint16_le(s, RDP_CAPSET_SHARE);
386            out_uint16_le(s, RDP_CAPLEN_SHARE);
         res = res ? lsb_io_uint32(s, &hdr->shareid      ) : False;  
         res = res ? prs_io_uint8 (s, &hdr->pad          ) : False;  
         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;  
387    
388          return res;          out_uint16(s, 0);       /* userid */
389            out_uint16(s, 0);       /* pad */
390  }  }
391    
392  BOOL rdp_io_general_caps(STREAM s, RDP_GENERAL_CAPS *caps)  /* Output colour cache capability set */
393    static void
394    rdp_out_colcache_caps(STREAM s)
395  {  {
396          uint16 length = RDP_CAPLEN_GENERAL;          out_uint16_le(s, RDP_CAPSET_COLCACHE);
397          uint16 pkt_length = length;          out_uint16_le(s, RDP_CAPLEN_COLCACHE);
         BOOL res;  
   
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
   
         res = res ? lsb_io_uint16(s, &caps->os_major_type ) : False;  
         res = res ? lsb_io_uint16(s, &caps->os_minor_type ) : False;  
         res = res ? lsb_io_uint16(s, &caps->ver_protocol  ) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad1          ) : False;  
         res = res ? lsb_io_uint16(s, &caps->compress_types) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad2          ) : False;  
         res = res ? lsb_io_uint16(s, &caps->cap_update    ) : False;  
         res = res ? lsb_io_uint16(s, &caps->remote_unshare) : False;  
         res = res ? lsb_io_uint16(s, &caps->compress_level) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad3          ) : False;  
   
         return res;  
 }  
   
 BOOL rdp_io_bitmap_caps(STREAM s, RDP_BITMAP_CAPS *caps)  
 {  
         uint16 length = RDP_CAPLEN_BITMAP;  
         uint16 pkt_length = length;  
         BOOL res;  
   
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
   
         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)  
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
398    
399          res = res ? prs_io_uint8s(s,  caps->terminal_desc, 16) : False;          out_uint16_le(s, 6);    /* cache size */
400          res = res ? lsb_io_uint32(s, &caps->pad1             ) : False;          out_uint16(s, 0);       /* pad */
         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;  
401  }  }
402    
403  BOOL rdp_io_bmpcache_info(STREAM s, RDP_BMPCACHE_INFO *info)  static uint8 canned_caps[] = {
404  {          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,
405          if (!lsb_io_uint16(s, &info->entries      ))          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
406                  return False;          0x00, 0x00, 0x00, 0x00, 0x00,
407            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
408          if (!lsb_io_uint16(s, &info->max_cell_size))          0x00, 0x00, 0x00, 0x00, 0x00,
409                  return False;          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410            0x00, 0x00, 0x00, 0x00, 0x00,
411          return True;          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
412  }          0x00, 0x00, 0x00, 0x00, 0x00,
413            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
414            0x0C, 0x00, 0x08, 0x00, 0x01,
415            0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
416            0x10, 0x00, 0x34, 0x00, 0xFE,
417            0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,
418            0xFE, 0x00, 0x08, 0x00, 0xFE,
419            0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,
420            0xFE, 0x00, 0x80, 0x00, 0xFE,
421            0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
422            0x02, 0x00, 0x00, 0x00
423    };
424    
425  BOOL rdp_io_bmpcache_caps(STREAM s, RDP_BMPCACHE_CAPS *caps)  /* Output unknown capability set */
426    static void
427    rdp_out_unknown_caps(STREAM s)
428    {
429            out_uint16_le(s, RDP_CAPSET_UNKNOWN);
430            out_uint16_le(s, 0x58);
431    
432            out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);
433    }
434    
435    /* Send a confirm active PDU */
436    static void
437    rdp_send_confirm_active(void)
438    {
439            STREAM s;
440            uint16 caplen =
441                    RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
442                    RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
443                    RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
444                    RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;
445    
446            s = rdp_init(14 + caplen + sizeof(RDP_SOURCE));
447    
448            out_uint32_le(s, rdp_shareid);
449            out_uint16_le(s, 0x3ea);        /* userid */
450            out_uint16_le(s, sizeof(RDP_SOURCE));
451            out_uint16_le(s, caplen);
452    
453            out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
454            out_uint16_le(s, 0xd);  /* num_caps */
455            out_uint8s(s, 2);       /* pad */
456    
457            rdp_out_general_caps(s);
458            rdp_out_bitmap_caps(s);
459            rdp_out_order_caps(s);
460            rdp_out_bmpcache_caps(s);
461            rdp_out_colcache_caps(s);
462            rdp_out_activate_caps(s);
463            rdp_out_control_caps(s);
464            rdp_out_pointer_caps(s);
465            rdp_out_share_caps(s);
466            rdp_out_unknown_caps(s);
467    
468            s_mark_end(s);
469            rdp_send(s, RDP_PDU_CONFIRM_ACTIVE);
470    }
471    
472    /* Respond to a demand active PDU */
473    static void
474    process_demand_active(STREAM s)
475  {  {
476          uint16 length = RDP_CAPLEN_BMPCACHE;          uint8 type;
         uint16 pkt_length = length;  
         BOOL res;  
         int i;  
   
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
   
         for (i = 0; i < 6; i++)  
                 res = res ? lsb_io_uint32(s, &caps->unused[i]) : False;  
   
         for (i = 0; i < 3; i++)  
                 res = res ? rdp_io_bmpcache_info(s, &caps->caches[i]) : False;  
477    
478          return res;          in_uint32_le(s, rdp_shareid);
 }  
479    
480  BOOL rdp_io_control_caps(STREAM s, RDP_CONTROL_CAPS *caps)          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", rdp_shareid));
 {  
         uint16 length = RDP_CAPLEN_CONTROL;  
         uint16 pkt_length = length;  
         BOOL res;  
481    
482          res = lsb_io_uint16(s, &pkt_length);          rdp_send_confirm_active();
483          if (pkt_length != length)          rdp_send_synchronise();
484          {          rdp_send_control(RDP_CTL_COOPERATE);
485                  fprintf(stderr, "Unrecognised capabilities size\n");          rdp_send_control(RDP_CTL_REQUEST_CONTROL);
486                  return False;          rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
487          }          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
488            rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
489          res = res ? lsb_io_uint16(s, &caps->control_caps    ) : False;          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, 0, 0);
490          res = res ? lsb_io_uint16(s, &caps->remote_detach   ) : False;          rdp_send_fonts(1);
491          res = res ? lsb_io_uint16(s, &caps->control_interest) : False;          rdp_send_fonts(2);
492          res = res ? lsb_io_uint16(s, &caps->detach_interest ) : False;          rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 */
493            reset_order_state();
494    }
495    
496    /* Process a pointer PDU */
497    static void
498    process_pointer_pdu(STREAM s)
499    {
500            uint16 message_type;
501            uint16 x, y, width, height, cache_idx, masklen, datalen;
502            uint8 *mask, *data;
503            HCURSOR cursor;
504    
505            in_uint16_le(s, message_type);
506            in_uint8s(s, 2);        /* pad */
507    
508            switch (message_type)
509            {
510                    case RDP_POINTER_MOVE:
511                            in_uint16_le(s, x);
512                            in_uint16_le(s, y);
513                            if (s_check(s))
514                                    ui_move_pointer(x, y);
515                            break;
516    
517          return res;                  case RDP_POINTER_COLOR:
518  }                          in_uint16_le(s, cache_idx);
519                            in_uint16_le(s, x);
520                            in_uint16_le(s, y);
521                            in_uint16_le(s, width);
522                            in_uint16_le(s, height);
523                            in_uint16_le(s, masklen);
524                            in_uint16_le(s, datalen);
525                            in_uint8p(s, data, datalen);
526                            in_uint8p(s, mask, masklen);
527                            cursor = ui_create_cursor(x, y, width, height, mask, data);
528                            ui_set_cursor(cursor);
529                            cache_put_cursor(cache_idx, cursor);
530                            break;
531    
532  BOOL rdp_io_activate_caps(STREAM s, RDP_ACTIVATE_CAPS *caps)                  case RDP_POINTER_CACHED:
533  {                          in_uint16_le(s, cache_idx);
534          uint16 length = RDP_CAPLEN_ACTIVATE;                          ui_set_cursor(cache_get_cursor(cache_idx));
535          uint16 pkt_length = length;                          break;
         BOOL res;  
536    
537          res = lsb_io_uint16(s, &pkt_length);                  default:
538          if (pkt_length != length)                          DEBUG(("Pointer message 0x%x\n", message_type));
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
539          }          }
   
         res = res ? lsb_io_uint16(s, &caps->help_key         ) : False;  
         res = res ? lsb_io_uint16(s, &caps->help_index_key   ) : False;  
         res = res ? lsb_io_uint16(s, &caps->help_extended_key) : False;  
         res = res ? lsb_io_uint16(s, &caps->window_activate  ) : False;  
   
         return res;  
540  }  }
541    
542  BOOL rdp_io_pointer_caps(STREAM s, RDP_POINTER_CAPS *caps)  /* Process bitmap updates */
543    static void
544    process_bitmap_updates(STREAM s)
545  {  {
546          uint16 length = RDP_CAPLEN_POINTER;          uint16 num_updates;
547          uint16 pkt_length = length;          uint16 left, top, right, bottom, width, height;
548          BOOL res;          uint16 cx, cy, bpp, compress, bufsize, size;
549            uint8 *data, *bmpdata;
550          res = lsb_io_uint16(s, &pkt_length);          int i;
         if (pkt_length != length)  
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
   
         res = res ? lsb_io_uint16(s, &caps->colour_pointer) : False;  
         res = res ? lsb_io_uint16(s, &caps->cache_size    ) : False;  
   
         return res;  
 }  
551    
552  BOOL rdp_io_share_caps(STREAM s, RDP_SHARE_CAPS *caps)          in_uint16_le(s, num_updates);
 {  
         uint16 length = RDP_CAPLEN_SHARE;  
         uint16 pkt_length = length;  
         BOOL res;  
553    
554          res = lsb_io_uint16(s, &pkt_length);          for (i = 0; i < num_updates; i++)
         if (pkt_length != length)  
555          {          {
556                  fprintf(stderr, "Unrecognised capabilities size\n");                  in_uint16_le(s, left);
557                  return False;                  in_uint16_le(s, top);
558          }                  in_uint16_le(s, right);
559                    in_uint16_le(s, bottom);
560          res = res ? lsb_io_uint16(s, &caps->userid) : False;                  in_uint16_le(s, width);
561          res = res ? lsb_io_uint16(s, &caps->pad   ) : False;                  in_uint16_le(s, height);
562                    in_uint16_le(s, bpp);
563          return res;                  in_uint16_le(s, compress);
564  }                  in_uint16_le(s, bufsize);
   
 BOOL rdp_io_colcache_caps(STREAM s, RDP_COLCACHE_CAPS *caps)  
 {  
         uint16 length = RDP_CAPLEN_COLCACHE;  
         uint16 pkt_length = length;  
         BOOL res;  
565    
566          res = lsb_io_uint16(s, &pkt_length);                  cx = right - left + 1;
567          if (pkt_length != length)                  cy = bottom - top + 1;
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
568    
569          res = res ? lsb_io_uint16(s, &caps->cache_size) : False;                  DEBUG(("UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,cmp=%d)\n",
570          res = res ? lsb_io_uint16(s, &caps->pad       ) : False;                         left, top, right, bottom, width, height, compress));
571    
572          return res;                  if (!compress)
573  }                  {
574                            int y;
575                            bmpdata = xmalloc(width * height);
576                            for (y = 0; y < height; y++)
577                            {
578                                    in_uint8a(s, &bmpdata[(height - y - 1) * width], width);
579                            }
580                            ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
581                            xfree(bmpdata);
582                            continue;
583                    }
584    
585  uint8 canned_caps[] = {                  in_uint8s(s, 2);        /* pad */
586  0x01,0x00,0x00,0x00,0x09,0x04,0x00,0x00,0x04,                  in_uint16_le(s, size);
587  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,                  in_uint8s(s, 4);        /* line_size, final_size */
588  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,                  in_uint8p(s, data, size);
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  
 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x08,0x00,0x01,  
 0x00,0x00,0x00,0x0E,0x00,0x08,0x00,0x01,0x00,0x00,0x00,0x10,0x00,0x34,0x00,0xFE,  
 0x00,0x04,0x00,0xFE,0x00,0x04,0x00,0xFE,0x00,0x08,0x00,0xFE,0x00,0x08,0x00,0xFE,  
 0x00,0x10,0x00,0xFE,0x00,0x20,0x00,0xFE,0x00,0x40,0x00,0xFE,0x00,0x80,0x00,0xFE,  
 0x00,0x00,0x01,0x40,0x00,0x00,0x08,0x00,0x01,0x00,0x01,0x02,0x00,0x00,0x00  
 };  
589    
590  BOOL rdp_io_unknown_caps(STREAM s, void *caps)                  bmpdata = xmalloc(width * height);
591  {                  if (bitmap_decompress(bmpdata, width, height, data, size))
592          uint16 length = 0x58;                  {
593          uint16 pkt_length = length;                          ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
594          BOOL res;                  }
595    
596          res = lsb_io_uint16(s, &pkt_length);                  xfree(bmpdata);
         if (pkt_length != length)  
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
597          }          }
   
         res = res ? prs_io_uint8s(s, canned_caps, RDP_CAPLEN_UNKNOWN-4) : False;  
   
         return res;  
598  }  }
599    
600  BOOL rdp_io_active_pdu(STREAM s, RDP_ACTIVE_PDU *pdu, int pdutype)  /* Process a palette update */
601    static void
602    process_palette(STREAM s)
603  {  {
604          uint16 capset;          COLOURENTRY *entry;
605          uint16 length;          COLOURMAP map;
606          BOOL res;          HCOLOURMAP hmap;
607          int i;          int i;
608    
609          res = lsb_io_uint32(s, &pdu->shareid);          in_uint8s(s, 2);        /* pad */
610            in_uint16_le(s, map.ncolours);
611          if (pdutype == RDP_PDU_CONFIRM_ACTIVE)          in_uint8s(s, 2);        /* pad */
                 res = res ? lsb_io_uint16(s, &pdu->userid    ) : False;  
612    
613          res = res ? lsb_io_uint16(s, &pdu->source_len) : False;          map.colours = xmalloc(3 * map.ncolours);
         res = res ? lsb_io_uint16(s, &pdu->caps_len  ) : False;  
614    
615          if (pdu->source_len > 48)          for (i = 0; i < map.ncolours; i++)
616          {          {
617                  fprintf(stderr, "RDP source descriptor too long\n");                  entry = &map.colours[i];
618                  return False;                  in_uint8(s, entry->red);
619          }                  in_uint8(s, entry->green);
620                    in_uint8(s, entry->blue);
         res = res ? prs_io_uint8s(s,  pdu->source, pdu->source_len) : False;  
         res = res ? lsb_io_uint16(s, &pdu->num_caps  ) : False;  
         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;  
621          }          }
         else  
         {  
                 for (i = 0; i < pdu->num_caps; i++)  
                 {  
                         if (!res)  
                                 return False;  
622    
623                          if (!lsb_io_uint16(s, &capset))          hmap = ui_create_colourmap(&map);
624                                  return False;          ui_set_colourmap(hmap);
625    
626                          switch (capset)          xfree(map.colours);
                         {  
                         case RDP_CAPSET_GENERAL:  
                                 res = rdp_io_general_caps (s, &pdu->general_caps );  
                                 break;  
                         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);  
   
                                 if (!lsb_io_uint16(s, &length))  
                                         return False;  
   
                                 s->offset += (length - 4);  
                         }  
                 }  
         }  
   
         return res;  
627  }  }
628    
629  BOOL rdp_io_control_pdu(STREAM s, RDP_CONTROL_PDU *pdu)  /* Process an update PDU */
630    static void
631    process_update_pdu(STREAM s)
632  {  {
633          BOOL res = True;          uint16 update_type;
634    
635          res = res ? lsb_io_uint16(s, &pdu->action   ) : False;          in_uint16_le(s, update_type);
         res = res ? lsb_io_uint16(s, &pdu->userid   ) : False;  
         res = res ? lsb_io_uint32(s, &pdu->controlid) : False;  
636    
637          return res;          switch (update_type)
638  }          {
639                    case RDP_UPDATE_ORDERS:
640  BOOL rdp_io_synchronize_pdu(STREAM s, RDP_SYNCHRONIZE_PDU *pdu)                          process_orders(s);
641  {                          break;
         BOOL res = True;  
   
         res = res ? lsb_io_uint16(s, &pdu->type  ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->userid) : False;  
   
         return res;  
 }  
642    
643  BOOL rdp_io_input_event(STREAM s, RDP_INPUT_EVENT *evt)                  case RDP_UPDATE_BITMAP:
644  {                          process_bitmap_updates(s);
645          BOOL res = True;                          break;
646    
647          res = res ? lsb_io_uint32(s, &evt->event_time)   : False;                  case RDP_UPDATE_PALETTE:
648          res = res ? lsb_io_uint16(s, &evt->message_type) : False;                          process_palette(s);
649                            break;
650    
651          if (!res)                  case RDP_UPDATE_SYNCHRONIZE:
652                  return False;                          break;
653    
654          switch (evt->message_type)                  default:
655          {                          unimpl("update %d\n", update_type);
         case RDP_INPUT_CODEPOINT:  
         case RDP_INPUT_VIRTKEY:  
                 res = res ? lsb_io_uint16(s, &evt->device_flags) : False;  
                 res = res ? lsb_io_uint16(s, &evt->kbd_keycode ) : False;  
                 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;  
656          }          }
657    
         return res;  
658  }  }
659    
660  BOOL rdp_io_input_pdu(STREAM s, RDP_INPUT_PDU *pdu)  /* Process data PDU */
661    static void
662    process_data_pdu(STREAM s)
663  {  {
664          BOOL res = True;          uint8 data_pdu_type;
         int i;  
   
         res = res ? lsb_io_uint16(s, &pdu->num_events) : False;  
         res = res ? lsb_io_uint16(s, &pdu->pad       ) : False;  
665    
666          if (pdu->num_events > RDP_MAX_EVENTS)          in_uint8s(s, 8);        /* shareid, pad, streamid, length */
667          {          in_uint8(s, data_pdu_type);
668                  fprintf(stderr, "Too many events in one PDU\n");          in_uint8s(s, 3);        /* compress_type, compress_len */
                 return False;  
         }  
669    
670          for (i = 0; i < pdu->num_events; i++)          switch (data_pdu_type)
671          {          {
672                  res = res ? rdp_io_input_event(s, &pdu->event[i]) : False;                  case RDP_DATA_PDU_UPDATE:
673          }                          process_update_pdu(s);
674                            break;
675    
676          return res;                  case RDP_DATA_PDU_POINTER:
677  }                          process_pointer_pdu(s);
678                            break;
679    
680  BOOL rdp_io_font_info(STREAM s, RDP_FONT_INFO *font)                  case RDP_DATA_PDU_BELL:
681  {                          ui_bell();
682          BOOL res = True;                          break;
683    
684          res = res ? prs_io_uint8s(s,  font->name, 32 ) : False;                  case RDP_DATA_PDU_LOGON:
685          res = res ? lsb_io_uint16(s, &font->flags    ) : False;                          /* User logged on */
686          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;  
687    
688          return res;                  default:
689                            unimpl("data PDU %d\n", data_pdu_type);
690            }
691  }  }
692    
693  BOOL rdp_io_font_pdu(STREAM s, RDP_FONT_PDU *pdu)  /* Process incoming packets */
694    void
695    rdp_main_loop(void)
696  {  {
697          BOOL res = True;          uint8 type;
698          int i;          STREAM s;
   
         res = res ? lsb_io_uint16(s, &pdu->num_fonts ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->unknown1  ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->unknown2  ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->entry_size) : False;  
   
         if (pdu->num_fonts > RDP_MAX_FONTS)  
         {  
                 fprintf(stderr, "Too many fonts in one PDU\n");  
                 return False;  
         }  
699    
700          for (i = 0; i < pdu->num_fonts; i++)          while ((s = rdp_recv(&type)) != NULL)
701          {          {
702                  res = res ? rdp_io_font_info(s, &pdu->font[i]) : False;                  switch (type)
703          }                  {
704                            case RDP_PDU_DEMAND_ACTIVE:
705          return res;                                  process_demand_active(s);
706  }                                  break;
707    
708  BOOL rdp_io_update_pdu(STREAM s, RDP_UPDATE_PDU *pdu)                          case RDP_PDU_DEACTIVATE:
709  {                                  break;
         BOOL res = True;  
710    
711          res = res ? lsb_io_uint16(s, &pdu->update_type) : False;                          case RDP_PDU_DATA:
712          res = res ? lsb_io_uint16(s, &pdu->pad        ) : False;                                  process_data_pdu(s);
713                                    break;
714    
715          return res;                          default:
716                                    unimpl("PDU %d\n", type);
717                    }
718            }
719  }  }
720    
721  BOOL rdp_io_secondary_order(STREAM s, RDP_SECONDARY_ORDER *rso)  /* Establish a connection up to the RDP layer */
722    BOOL
723    rdp_connect(char *server, uint32 flags, char *domain, char *password,
724                char *command, char *directory)
725  {  {
726          BOOL res = True;          if (!sec_connect(server))
727                    return False;
         res = res ? lsb_io_uint16(s, &rso->length) : False;  
         res = res ? lsb_io_uint16(s, &rso->flags ) : False;  
         res = res ? prs_io_uint8 (s, &rso->type  ) : False;  
728    
729          return res;          rdp_send_logon_info(flags, domain, username, password, command, directory);
730            return True;
731  }  }
732    
733  BOOL rdp_io_bitmap_header(STREAM s, RDP_BITMAP_HEADER *rdh)  /* Disconnect from the RDP layer */
734    void
735    rdp_disconnect(void)
736  {  {
737          BOOL res = True;          sec_disconnect();
   
         res = res ? prs_io_uint8 (s, &rdh->cache_id  ) : False;  
         res = res ? prs_io_uint8 (s, &rdh->pad1      ) : False;  
         res = res ? prs_io_uint8 (s, &rdh->width     ) : False;  
         res = res ? prs_io_uint8 (s, &rdh->height    ) : False;  
         res = res ? prs_io_uint8 (s, &rdh->bpp       ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->bufsize   ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->cache_idx ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->pad2      ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->size      ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->row_size  ) : False;  
         res = res ? lsb_io_uint16(s, &rdh->final_size) : False;  
   
         return res;  
738  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26