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

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

  ViewVC Help
Powered by ViewVC 1.1.26