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

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

  ViewVC Help
Powered by ViewVC 1.1.26