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

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

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

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

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

  ViewVC Help
Powered by ViewVC 1.1.26