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

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

  ViewVC Help
Powered by ViewVC 1.1.26