/[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 254 by matthewc, Tue Nov 5 11:22:20 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          mcs_recv(conn, False); /* Demand active */          STREAM s;
   
         if (!rdp_recv_pdu(conn, &type) || (type != RDP_PDU_DEMAND_ACTIVE))  
         {  
                 fprintf(stderr, "RDP error, expected Demand Active\n");  
                 mcs_disconnect(conn);  
                 return NULL;  
         }  
38    
39          rdp_io_active_pdu(&conn->in, &active, RDP_PDU_DEMAND_ACTIVE);          s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 6);
40          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  
41    
42          return conn;          return s;
43  }  }
44    
45  void rdp_main_loop(HCONN conn)  /* Send an RDP packet */
46    static void
47    rdp_send(STREAM s, uint8 pdu_type)
48  {  {
49          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);  
50    
51                  switch (hdr.data_pdu_type)          s_pop_layer(s, rdp_hdr);
52                  {          length = s->end - s->p;
                         case RDP_DATA_PDU_UPDATE:  
                                 process_update(conn, &os);  
                                 break;  
53    
54                          case RDP_DATA_PDU_POINTER:          out_uint16_le(s, length);
55                                  process_pointer(conn);          out_uint16_le(s, (pdu_type | 0x10));    /* Version 1 */
56                                  break;          out_uint16_le(s, (mcs_userid + 1001));
57    
58                          default:          sec_send(s, encryption ? SEC_ENCRYPT : 0);
                                 fprintf(stderr, "Unknown data PDU 0x%x\n",  
                                                 hdr.data_pdu_type);  
                 }  
         }  
59  }  }
60    
61  void process_memblt(HCONN conn, RDP_ORDER_STATE *os, BOOL delta)  /* Receive an RDP packet */
62    static STREAM
63    rdp_recv(uint8 * type)
64  {  {
65          HBITMAP hbitmap;          static STREAM rdp_s;
66          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);  
   
         if (present & 16)  
                 rdp_io_coord(&conn->in, &os->memblt.cy, delta);  
67    
68          if (present & 32)          if ((rdp_s == NULL) || (next_packet >= rdp_s->end))
                 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 */  
69          {          {
70                  fprintf(stderr, "Unsupported raster operation 0x%x\n",                  rdp_s = sec_recv();
71                          os->memblt.opcode);                  if (rdp_s == NULL)
72                  return;                          return NULL;
         }  
73    
74          if ((os->memblt.cache_idx > NUM_ELEMENTS(conn->bmpcache))                  next_packet = rdp_s->p;
             || ((hbitmap = conn->bmpcache[os->memblt.cache_idx]) == NULL))  
         {  
                 fprintf(stderr, "Bitmap %d not found\n", os->memblt.cache_idx);  
                 return;  
75          }          }
76            else
         fprintf(stderr, "MEMBLT %d:%dx%d\n", os->memblt.cache_idx,  
                                         os->memblt.x, os->memblt.y);  
   
         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);  
   
         if (present & 8)  
                 rdp_io_coord(&conn->in, &os->opaque_rect.cy, delta);  
   
         if (present & 16)  
                 prs_io_uint8(&conn->in, &os->opaque_rect.colour);  
   
         fprintf(stderr, "Opaque rectangle at %d, %d\n", os->opaque_rect.x, os->opaque_rect.y);  
         ui_draw_rectangle(conn->wnd, os->opaque_rect.x, os->opaque_rect.y,  
                                 os->opaque_rect.cx, os->opaque_rect.cy);  
 }  
   
 void process_bmpcache(HCONN conn)  
 {  
         RDP_BITMAP_HEADER rbh;  
         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);  
   
         input = conn->in.data + conn->in.offset;  
         conn->in.offset += rbh.size;  
 //      dump_data(conn->in.data+conn->in.offset, conn->in.rdp_offset-conn->in.offset);  
   
         bmpdata = malloc(rbh.width * rbh.height);  
         if (!bitmap_decompress(bmpdata, rbh.width, rbh.height, input, rbh.size))  
77          {          {
78                  fprintf(stderr, "Decompression failed\n");                  rdp_s->p = next_packet;
                 free(bmpdata);  
                 return;  
79          }          }
80    
81          if (rbh.cache_idx > NUM_ELEMENTS(conn->bmpcache))          in_uint16_le(rdp_s, length);
82          {          in_uint16_le(rdp_s, pdu_type);
83                  fprintf(stderr, "Attempted store past end of cache");          in_uint8s(rdp_s, 2);    /* userid */
84                  return;          *type = pdu_type & 0xf;
         }  
85    
86          entry = &conn->bmpcache[rbh.cache_idx];  #if WITH_DEBUG
87          // if (*entry != NULL)          DEBUG(("RDP packet (type %x):\n", *type));
88          //      ui_destroy_bitmap(conn->wnd, *entry);          hexdump(next_packet, length);
89    #endif /*  */
90    
91          *entry = ui_create_bitmap(conn->wnd, rbh.width, rbh.height, bmpdata);          next_packet += length;
92          //      ui_paint_bitmap(conn->wnd, bmp, x, 0);          return rdp_s;
         //      ui_destroy_bitmap(conn->wnd, bmp);  
93  }  }
94    
95  void process_orders(HCONN conn, RDP_ORDER_STATE *os)  /* Initialise an RDP data packet */
96    static STREAM
97    rdp_init_data(int maxlen)
98  {  {
99          uint16 num_orders;          STREAM s;
         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);  
100    
101                          delta = order_flags & RDP_ORDER_DELTA;          s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 18);
102            s_push_layer(s, rdp_hdr, 18);
103    
104                          switch (os->order_type)          return s;
                         {  
                         case RDP_ORDER_OPAQUE_RECT:  
                                 process_opaque_rect(conn, os, delta);  
                                 break;  
   
                         case RDP_ORDER_MEMBLT:  
                                 process_memblt(conn, os, delta);  
                                 break;  
   
                         default:  
                                 fprintf(stderr, "Unknown order %d\n", os->order_type);  
                                 return;  
                         }  
                 }  
   
                 processed++;  
         }  
105  }  }
106    
107  void process_palette(HCONN conn)  /* Send an RDP data packet */
108    static void
109    rdp_send_data(STREAM s, uint8 data_pdu_type)
110  {  {
111          HCOLORMAP map;          uint16 length;
         COLORMAP colors;  
112    
113          rdp_io_colormap(&conn->in, &colors);          s_pop_layer(s, rdp_hdr);
114          map = ui_create_colormap(conn->wnd, &colors);          length = s->end - s->p;
         ui_set_colormap(conn->wnd, map);  
         // ui_destroy_colormap(map);  
 }  
115    
116  void process_update(HCONN conn, RDP_ORDER_STATE *os)          out_uint16_le(s, length);
117  {          out_uint16_le(s, (RDP_PDU_DATA | 0x10));
118          RDP_UPDATE_PDU update;          out_uint16_le(s, (mcs_userid + 1001));
119    
120          rdp_io_update_pdu(&conn->in, &update);          out_uint32_le(s, rdp_shareid);
121          switch (update.update_type)          out_uint8(s, 0);        /* pad */
122          {          out_uint8(s, 1);        /* streamid */
123                  case RDP_UPDATE_ORDERS:          out_uint16_le(s, (length - 14));
124                          process_orders(conn, os);          out_uint8(s, data_pdu_type);
125                          break;          out_uint8(s, 0);        /* compress_type */
126                  case RDP_UPDATE_PALETTE:          out_uint16(s, 0);       /* compress_len */
                         process_palette(conn);  
                         break;  
                 case RDP_UPDATE_SYNCHRONIZE:  
                         break;  
                 default:  
                         fprintf(stderr, "Unknown update 0x%x\n",  
                                 update.update_type);  
         }  
127    
128            sec_send(s, encryption ? SEC_ENCRYPT : 0);
129  }  }
130    
131  void process_pointer(HCONN conn)  /* Output a string in Unicode */
132    void
133    rdp_out_unistr(STREAM s, char *string, int len)
134  {  {
135          RDP_POINTER ptr;          int i = 0, j = 0;
136    
137          rdp_io_pointer(&conn->in, &ptr);          len += 2;
138    
139          switch (ptr.message)          while (i < len)
140          {          {
141                  case RDP_POINTER_MOVE:                  s->p[i++] = string[j++];
142                          ui_move_pointer(conn->wnd, ptr.x, ptr.y);                  s->p[i++] = 0;
                         break;  
                 default:  
                         fprintf(stderr, "Unknown pointer message 0x%x\n",  
                                 ptr.message);  
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 */
222          RDP_INPUT_PDU input;  
223            out_uint32_le(s, time);
224            out_uint16_le(s, message_type);
225            out_uint16_le(s, device_flags);
226            out_uint16_le(s, param1);
227            out_uint16_le(s, param2);
228    
229          rdp_init_data(conn);          s_mark_end(s);
230          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);  
231  }  }
232    
233  BOOL rdp_recv_pdu(HCONN conn, uint8 *type)  /* Send an (empty) font information PDU */
234    static void
235    rdp_send_fonts(uint16 seq)
236  {  {
237          RDP_HEADER hdr;          STREAM s;
238    
239          conn->in.offset = conn->in.rdp_offset;          s = rdp_init_data(8);
   
         if (conn->in.offset >= conn->in.end)  
         {  
                 if (!mcs_recv(conn, False))  
                         return False;  
         }  
   
         if (!rdp_io_header(&conn->in, &hdr))  
                 return False;  
240    
241          conn->in.rdp_offset += hdr.length;          out_uint16(s, 0);       /* number of fonts */
242          *type = hdr.pdu_type & 0xf;          out_uint16_le(s, 0x3e); /* unknown */
243            out_uint16_le(s, seq);  /* unknown */
244            out_uint16_le(s, 0x32); /* entry size */
245    
246  #if DEBUG          s_mark_end(s);
247          fprintf(stderr, "RDP packet (type %x):\n", *type);          rdp_send_data(s, RDP_DATA_PDU_FONT2);
         dump_data(conn->in.data+conn->in.offset, conn->in.rdp_offset-conn->in.offset);  
 #endif  
   
         return True;  
248  }  }
249    
250  /* Disconnect from the RDP layer */  /* Output general capability set */
251  void rdp_disconnect(HCONN conn)  static void
252    rdp_out_general_caps(STREAM s)
253  {  {
254          mcs_disconnect(conn);          out_uint16_le(s, RDP_CAPSET_GENERAL);
255  }          out_uint16_le(s, RDP_CAPLEN_GENERAL);
256    
257  void rdp_make_header(RDP_HEADER *hdr, uint16 length, uint16 pdu_type,          out_uint16_le(s, 1);    /* OS major type */
258                       uint16 userid)          out_uint16_le(s, 3);    /* OS minor type */
259  {          out_uint16_le(s, 0x200);        /* Protocol version */
260          hdr->length = length;          out_uint16(s, 0);       /* Pad */
261          hdr->pdu_type = pdu_type | 0x10; /* Version 1 */          out_uint16(s, 0);       /* Compression types */
262          hdr->userid = userid + 1001;          out_uint16(s, 0);       /* Pad */
263            out_uint16(s, 0);       /* Update capability */
264            out_uint16(s, 0);       /* Remote unshare capability */
265            out_uint16(s, 0);       /* Compression level */
266            out_uint16(s, 0);       /* Pad */
267  }  }
268    
269  void rdp_make_data_header(RDP_DATA_HEADER *hdr, uint32 shareid,  /* Output bitmap capability set */
270                            uint16 length, uint16 data_pdu_type)  static void
271    rdp_out_bitmap_caps(STREAM s)
272  {  {
273          hdr->shareid = shareid;          out_uint16_le(s, RDP_CAPSET_BITMAP);
274          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;  
 }  
275    
276  void rdp_make_general_caps(RDP_GENERAL_CAPS *caps)          out_uint16_le(s, 8);    /* Preferred BPP */
277  {          out_uint16_le(s, 1);    /* Receive 1 BPP */
278          caps->os_major_type = 1;          out_uint16_le(s, 1);    /* Receive 4 BPP */
279          caps->os_minor_type = 3;          out_uint16_le(s, 1);    /* Receive 8 BPP */
280          caps->ver_protocol = 0x200;          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_bitmap_caps(RDP_BITMAP_CAPS *caps)  /* Output order capability set */
291    static void
292    rdp_out_order_caps(STREAM s)
293  {  {
294          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;  
 }  
295    
 void rdp_make_order_caps(RDP_ORDER_CAPS *caps)  
 {  
         caps->xgranularity = 1;  
         caps->ygranularity = 20;  
         caps->max_order_level = 1;  
         caps->num_fonts = 0x147;  
         caps->cap_flags = 0x2A;  
296    
297  //      caps->cap_flags = ORDER_CAP_NEGOTIATE | ORDER_CAP_NOSUPPORT;          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          caps->support[0] = caps->support[1] = caps->support[2]          out_uint8s(s, 20);      /* Terminal desc, pad */
314                  = caps->support[3] = caps->support[4] = caps->support[5]          out_uint16_le(s, 1);    /* Cache X granularity */
315                  = caps->support[6] = caps->support[8] = caps->support[11]          out_uint16_le(s, 20);   /* Cache Y granularity */
316                  = caps->support[12] = caps->support[22] = caps->support[28]          out_uint16(s, 0);       /* Pad */
317                  = caps->support[29] = caps->support[30] = 1;          out_uint16_le(s, 1);    /* Max order level */
318          caps->text_cap_flags = 0x6A1;          out_uint16_le(s, 0x147);        /* Number of fonts */
319          caps->desk_save_size = 0x38400;          out_uint16_le(s, 0x2a); /* Capability flags */
320          caps->unknown2 = 0x4E4;          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_bmpcache_caps(RDP_BMPCACHE_CAPS *caps)  /* Output bitmap cache capability set */
329    static void
330    rdp_out_bmpcache_caps(STREAM s)
331  {  {
332          caps->caches[0].entries = 0x258;          out_uint16_le(s, RDP_CAPSET_BMPCACHE);
333          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;  
 }  
334    
335  void rdp_make_control_caps(RDP_CONTROL_CAPS *caps)          out_uint8s(s, 24);      /* unused */
336  {          out_uint16_le(s, 0x258);        /* entries */
337          caps->control_interest = 2;          out_uint16_le(s, 0x100);        /* max cell size */
338          caps->detach_interest = 2;          out_uint16_le(s, 0x12c);        /* entries */
339            out_uint16_le(s, 0x400);        /* max cell size */
340            out_uint16_le(s, 0x106);        /* entries */
341            out_uint16_le(s, 0x1000);       /* max cell size */
342  }  }
343    
344  void rdp_make_activate_caps(RDP_ACTIVATE_CAPS *caps)  /* Output control capability set */
345    static void
346    rdp_out_control_caps(STREAM s)
347  {  {
348  }          out_uint16_le(s, RDP_CAPSET_CONTROL);
349            out_uint16_le(s, RDP_CAPLEN_CONTROL);
350    
351  void rdp_make_pointer_caps(RDP_POINTER_CAPS *caps)          out_uint16(s, 0);       /* Control capabilities */
352  {          out_uint16(s, 0);       /* Remote detach */
353          caps->colour_pointer = 0;          out_uint16_le(s, 2);    /* Control interest */
354          caps->cache_size = 20;          out_uint16_le(s, 2);    /* Detach interest */
355  }  }
356    
357  void rdp_make_share_caps(RDP_SHARE_CAPS *caps, uint16 userid)  /* Output activation capability set */
358    static void
359    rdp_out_activate_caps(STREAM s)
360  {  {
361  }          out_uint16_le(s, RDP_CAPSET_ACTIVATE);
362            out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
363    
364  void rdp_make_colcache_caps(RDP_COLCACHE_CAPS *caps)          out_uint16(s, 0);       /* Help key */
365  {          out_uint16(s, 0);       /* Help index key */
366          caps->cache_size = 6;          out_uint16(s, 0);       /* Extended help key */
367            out_uint16(s, 0);       /* Window activate */
368  }  }
369    
370  void rdp_make_active_pdu(RDP_ACTIVE_PDU *pdu, uint32 shareid, uint16 userid)  /* Output pointer capability set */
371    static void
372    rdp_out_pointer_caps(STREAM s)
373  {  {
374          memset(pdu, 0, sizeof(*pdu));          out_uint16_le(s, RDP_CAPSET_POINTER);
375          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;  
376    
377          rdp_make_general_caps (&pdu->general_caps );          out_uint16(s, 0);       /* Colour pointer */
378          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);  
379  }  }
380    
381  void rdp_make_control_pdu(RDP_CONTROL_PDU *pdu, uint16 action)  /* Output share capability set */
382    static void
383    rdp_out_share_caps(STREAM s)
384  {  {
385          pdu->action = action;          out_uint16_le(s, RDP_CAPSET_SHARE);
386          pdu->userid = 0;          out_uint16_le(s, RDP_CAPLEN_SHARE);
         pdu->controlid = 0;  
 }  
387    
388  void rdp_make_synchronize_pdu(RDP_SYNCHRONIZE_PDU *pdu, uint16 userid)          out_uint16(s, 0);       /* userid */
389  {          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;  
390  }  }
391    
392  void rdp_make_input_pdu(RDP_INPUT_PDU *pdu)  /* Output colour cache capability set */
393    static void
394    rdp_out_colcache_caps(STREAM s)
395  {  {
396          uint32 now = time(NULL);          out_uint16_le(s, RDP_CAPSET_COLCACHE);
397            out_uint16_le(s, RDP_CAPLEN_COLCACHE);
398    
399          pdu->num_events = 3;          out_uint16_le(s, 6);    /* cache size */
400          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;  
401  }  }
402    
403  BOOL rdp_io_header(STREAM s, RDP_HEADER *hdr)  static uint8 canned_caps[] = {
404  {          0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,
405          BOOL res = True;          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
406            0x00, 0x00, 0x00, 0x00, 0x00,
407          res = res ? lsb_io_uint16(s, &hdr->length  ) : False;          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
408          res = res ? lsb_io_uint16(s, &hdr->pdu_type) : False;          0x00, 0x00, 0x00, 0x00, 0x00,
409          res = res ? lsb_io_uint16(s, &hdr->userid  ) : False;          0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
410            0x00, 0x00, 0x00, 0x00, 0x00,
411          return res;          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_data_header(STREAM s, RDP_DATA_HEADER *hdr)  /* 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          BOOL res = True;          uint8 type;
477    
478          res = res ? lsb_io_uint32(s, &hdr->shareid      ) : False;          in_uint32_le(s, rdp_shareid);
         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;  
479    
480          return res;          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", rdp_shareid));
 }  
481    
482  BOOL rdp_io_coord(STREAM s, uint16 *coord, BOOL delta)          rdp_send_confirm_active();
483  {          rdp_send_synchronise();
484          uint8 change;          rdp_send_control(RDP_CTL_COOPERATE);
485          BOOL res;          rdp_send_control(RDP_CTL_REQUEST_CONTROL);
486            rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
487          if (delta)          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
488          {          rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
489                  res = prs_io_uint8(s, &change);          rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, 0, 0);
490                  *coord += change;          rdp_send_fonts(1);
491          }          rdp_send_fonts(2);
492          else          rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 */
493          {          reset_order_state();
494                  res = lsb_io_uint16(s, coord);  }
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          return res;          in_uint16_le(s, message_type);
506  }          in_uint8s(s, 2);        /* pad */
507    
508  BOOL rdp_io_colormap(STREAM s, COLORMAP *colors)          switch (message_type)
509  {          {
510          int datasize;                  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          lsb_io_uint16(s, &colors->ncolors);                  case RDP_POINTER_COLOR:
518          datasize = colors->ncolors * 3;                          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          if (datasize > sizeof(colors->colors))                  case RDP_POINTER_CACHED:
533                  return False;                          in_uint16_le(s, cache_idx);
534                            ui_set_cursor(cache_get_cursor(cache_idx));
535                            break;
536    
537          memcpy(colors->colors, s->data + s->offset, datasize);                  default:
538          s->offset += datasize;                          DEBUG(("Pointer message 0x%x\n", message_type));
539          return True;          }
540  }  }
541    
542  BOOL rdp_io_general_caps(STREAM s, RDP_GENERAL_CAPS *caps)  /* Process bitmap updates */
543    static void
544    process_bitmap_updates(STREAM s)
545  {  {
546          uint16 length = RDP_CAPLEN_GENERAL;          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;  
         }  
551    
552          res = res ? lsb_io_uint16(s, &caps->os_major_type ) : False;          in_uint16_le(s, num_updates);
         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;  
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                    in_uint16_le(s, width);
561                    in_uint16_le(s, height);
562                    in_uint16_le(s, bpp);
563                    in_uint16_le(s, compress);
564                    in_uint16_le(s, bufsize);
565    
566          res = res ? lsb_io_uint16(s, &caps->preferred_bpp) : False;                  cx = right - left + 1;
567          res = res ? lsb_io_uint16(s, &caps->receive1bpp  ) : False;                  cy = bottom - top + 1;
         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;  
568    
569          res = lsb_io_uint16(s, &pkt_length);                  DEBUG(("UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,cmp=%d)\n",
570          if (pkt_length != length)                         left, top, right, bottom, width, height, compress));
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
   
         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;  
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  BOOL rdp_io_bmpcache_info(STREAM s, RDP_BMPCACHE_INFO *info)                  in_uint8s(s, 2);        /* pad */
586  {                  in_uint16_le(s, size);
587          if (!lsb_io_uint16(s, &info->entries      ))                  in_uint8s(s, 4);        /* line_size, final_size */
588                  return False;                  in_uint8p(s, data, size);
589    
590          if (!lsb_io_uint16(s, &info->max_cell_size))                  bmpdata = xmalloc(width * height);
591                  return False;                  if (bitmap_decompress(bmpdata, width, height, data, size))
592                    {
593                            ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
594                    }
595    
596          return True;                  xfree(bmpdata);
597            }
598  }  }
599    
600  BOOL rdp_io_bmpcache_caps(STREAM s, RDP_BMPCACHE_CAPS *caps)  /* Process a palette update */
601    static void
602    process_palette(STREAM s)
603  {  {
604          uint16 length = RDP_CAPLEN_BMPCACHE;          COLOURENTRY *entry;
605          uint16 pkt_length = length;          COLOURMAP map;
606          BOOL res;          HCOLOURMAP hmap;
607          int i;          int i;
608    
609          res = lsb_io_uint16(s, &pkt_length);          in_uint8s(s, 2);        /* pad */
610          if (pkt_length != length)          in_uint16_le(s, map.ncolours);
611          {          in_uint8s(s, 2);        /* pad */
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
   
         for (i = 0; i < 6; i++)  
                 res = res ? lsb_io_uint32(s, &caps->unused[i]) : False;  
612    
613          for (i = 0; i < 3; i++)          map.colours = xmalloc(3 * map.ncolours);
                 res = res ? rdp_io_bmpcache_info(s, &caps->caches[i]) : False;  
614    
615          return res;          for (i = 0; i < map.ncolours; 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)  
616          {          {
617                  fprintf(stderr, "Unrecognised capabilities size\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);
621            }
622    
623          res = res ? lsb_io_uint16(s, &caps->control_caps    ) : False;          hmap = ui_create_colourmap(&map);
624          res = res ? lsb_io_uint16(s, &caps->remote_detach   ) : False;          ui_set_colourmap(hmap);
         res = res ? lsb_io_uint16(s, &caps->control_interest) : False;  
         res = res ? lsb_io_uint16(s, &caps->detach_interest ) : False;  
625    
626          return res;          xfree(map.colours);
627  }  }
628    
629  BOOL rdp_io_activate_caps(STREAM s, RDP_ACTIVATE_CAPS *caps)  /* Process an update PDU */
630    static void
631    process_update_pdu(STREAM s)
632  {  {
633          uint16 length = RDP_CAPLEN_ACTIVATE;          uint16 update_type;
         uint16 pkt_length = length;  
         BOOL res;  
634    
635          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;  
         }  
   
         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;  
 }  
   
 BOOL rdp_io_pointer_caps(STREAM s, RDP_POINTER_CAPS *caps)  
 {  
         uint16 length = RDP_CAPLEN_POINTER;  
         uint16 pkt_length = length;  
         BOOL res;  
636    
637          res = lsb_io_uint16(s, &pkt_length);          switch (update_type)
         if (pkt_length != length)  
638          {          {
639                  fprintf(stderr, "Unrecognised capabilities size\n");                  case RDP_UPDATE_ORDERS:
640                  return False;                          process_orders(s);
641          }                          break;
642    
643          res = res ? lsb_io_uint16(s, &caps->colour_pointer) : False;                  case RDP_UPDATE_BITMAP:
644          res = res ? lsb_io_uint16(s, &caps->cache_size    ) : False;                          process_bitmap_updates(s);
645                            break;
646    
647          return res;                  case RDP_UPDATE_PALETTE:
648  }                          process_palette(s);
649                            break;
650    
651  BOOL rdp_io_share_caps(STREAM s, RDP_SHARE_CAPS *caps)                  case RDP_UPDATE_SYNCHRONIZE:
652  {                          break;
         uint16 length = RDP_CAPLEN_SHARE;  
         uint16 pkt_length = length;  
         BOOL res;  
653    
654          res = lsb_io_uint16(s, &pkt_length);                  default:
655          if (pkt_length != length)                          unimpl("update %d\n", update_type);
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
656          }          }
657    
         res = res ? lsb_io_uint16(s, &caps->userid) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad   ) : False;  
   
         return res;  
658  }  }
659    
660  BOOL rdp_io_colcache_caps(STREAM s, RDP_COLCACHE_CAPS *caps)  /* Process data PDU */
661    static void
662    process_data_pdu(STREAM s)
663  {  {
664          uint16 length = RDP_CAPLEN_COLCACHE;          uint8 data_pdu_type;
         uint16 pkt_length = length;  
         BOOL res;  
665    
666          res = lsb_io_uint16(s, &pkt_length);          in_uint8s(s, 8);        /* shareid, pad, streamid, length */
667          if (pkt_length != length)          in_uint8(s, data_pdu_type);
668          {          in_uint8s(s, 3);        /* compress_type, compress_len */
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
         }  
669    
670          res = res ? lsb_io_uint16(s, &caps->cache_size) : False;          switch (data_pdu_type)
671          res = res ? lsb_io_uint16(s, &caps->pad       ) : False;          {
672                    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  uint8 canned_caps[] = {                  case RDP_DATA_PDU_BELL:
681  0x01,0x00,0x00,0x00,0x09,0x04,0x00,0x00,0x04,                          ui_bell();
682  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  
 };  
683    
684  BOOL rdp_io_unknown_caps(STREAM s, void *caps)                  case RDP_DATA_PDU_LOGON:
685  {                          /* User logged on */
686          uint16 length = 0x58;                          break;
         uint16 pkt_length = length;  
         BOOL res;  
687    
688          res = lsb_io_uint16(s, &pkt_length);                  default:
689          if (pkt_length != length)                          unimpl("data PDU %d\n", data_pdu_type);
         {  
                 fprintf(stderr, "Unrecognised capabilities size\n");  
                 return False;  
690          }          }
   
         res = res ? prs_io_uint8s(s, canned_caps, RDP_CAPLEN_UNKNOWN-4) : False;  
   
         return res;  
691  }  }
692    
693  BOOL rdp_io_active_pdu(STREAM s, RDP_ACTIVE_PDU *pdu, int pdutype)  /* Process incoming packets */
694    void
695    rdp_main_loop(void)
696  {  {
697          uint16 capset;          uint8 type;
698          uint16 length;          STREAM s;
         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;  
   
         res = res ? lsb_io_uint16(s, &pdu->source_len) : False;  
         res = res ? lsb_io_uint16(s, &pdu->caps_len  ) : False;  
   
         if (pdu->source_len > 48)  
         {  
                 fprintf(stderr, "RDP source descriptor too long\n");  
                 return False;  
         }  
699    
700          res = res ? prs_io_uint8s(s,  pdu->source, pdu->source_len) : False;          while ((s = rdp_recv(&type)) != NULL)
         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  
701          {          {
702                  for (i = 0; i < pdu->num_caps; i++)                  switch (type)
703                  {                  {
704                          if (!res)                          case RDP_PDU_DEMAND_ACTIVE:
705                                  return False;                                  process_demand_active(s);
   
                         if (!lsb_io_uint16(s, &capset))  
                                 return False;  
   
                         switch (capset)  
                         {  
                         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);  
706                                  break;                                  break;
707                          case RDP_CAPSET_CONTROL:  
708                                  res = rdp_io_control_caps (s, &pdu->control_caps );                          case RDP_PDU_DEACTIVATE:
                                 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);  
709                                  break;                                  break;
                         default:  
                                 fprintf(stderr, "Warning: Unrecognised capset %x\n",  
                                         capset);  
710    
711                                  if (!lsb_io_uint16(s, &length))                          case RDP_PDU_DATA:
712                                          return False;                                  process_data_pdu(s);
713                                    break;
714    
715                                  s->offset += (length - 4);                          default:
716                          }                                  unimpl("PDU %d\n", type);
717                  }                  }
718          }          }
   
         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;  
 }  
   
 BOOL rdp_io_input_event(STREAM s, RDP_INPUT_EVENT *evt)  
 {  
         BOOL res = True;  
   
         res = res ? lsb_io_uint32(s, &evt->event_time)   : False;  
         res = res ? lsb_io_uint16(s, &evt->message_type) : False;  
   
         if (!res)  
                 return False;  
   
         switch (evt->message_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;  
         }  
   
         return res;  
719  }  }
720    
721  BOOL rdp_io_input_pdu(STREAM s, RDP_INPUT_PDU *pdu)  /* Establish a connection up to the RDP layer */
722  {  BOOL
723          BOOL res = True;  rdp_connect(char *server, uint32 flags, char *domain, char *password,
724          int i;              char *command, char *directory)
   
         res = res ? lsb_io_uint16(s, &pdu->num_events) : False;  
         res = res ? lsb_io_uint16(s, &pdu->pad       ) : False;  
   
         if (pdu->num_events > RDP_MAX_EVENTS)  
         {  
                 fprintf(stderr, "Too many events in one PDU\n");  
                 return False;  
         }  
   
         for (i = 0; i < pdu->num_events; i++)  
         {  
                 res = res ? rdp_io_input_event(s, &pdu->event[i]) : False;  
         }  
   
         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;  
 }  
   
 BOOL rdp_io_font_pdu(STREAM s, RDP_FONT_PDU *pdu)  
725  {  {
726          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");  
727                  return False;                  return False;
         }  
728    
729          for (i = 0; i < pdu->num_fonts; i++)          rdp_send_logon_info(flags, domain, username, password, command, directory);
730          {          return True;
                 res = res ? rdp_io_font_info(s, &pdu->font[i]) : False;  
         }  
   
         return res;  
 }  
   
 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;  
731  }  }
732    
733  BOOL rdp_io_pointer(STREAM s, RDP_POINTER *ptr)  /* Disconnect from the RDP layer */
734    void
735    rdp_disconnect(void)
736  {  {
737          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;  
738  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26