/[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 9 by matty, Tue Jul 25 12:34:29 2000 UTC revision 381 by jsorg71, Fri May 30 21:59:56 2003 UTC
# Line 1  Line 1 
1  /*  /* -*- c-basic-offset: 8 -*-
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 g_mcs_userid;
24  HCONN rdp_connect(char *server, int width, int height)  extern char username[16];
25  {  extern BOOL bitmap_compression;
26          HCONN conn;  extern BOOL orders;
27    extern BOOL encryption;
28          if ((conn = mcs_connect(server)) == NULL)  extern BOOL desktop_save;
29                  return NULL;  extern BOOL use_rdp5;
30    extern uint16 server_rdp_version;
         rdp_establish_key(conn);  
         mcs_recv(conn, False); /* Server's licensing certificate */  
         rdp_send_cert(conn);  
         mcs_recv(conn, False);  
         mcs_recv(conn, False);  
   
         return conn;  
   
 }  
   
 /* 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  
 };  
   
 uint8 precanned_key_packet_e1[] = {  
 0x01,0x00,0x00,0x00,0x48,0x00,0x00,0x00,0x7c,0xbd,0x8b,0x8f,0x16,0x2b,0xa1,0x00,  
 0xc6,0xfb,0x8a,0x39,0xf5,0x33,0xed,0x36,0x14,0x55,0x17,0x8c,0x3a,0xde,0x5e,0xdf,  
 0xcb,0x41,0x4c,0xc7,0x89,0x7d,0xe3,0xe9,0x34,0x08,0xda,0xdc,0x08,0x77,0x98,0xda,  
 0x65,0xae,0x27,0x74,0xf1,0x79,0xd0,0x28,0x54,0x64,0x86,0x7f,0x02,0xe0,0x71,0x51,  
 0x56,0x4e,0xca,0x72,0x94,0x62,0x49,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00  
 };  
   
 uint8 precanned_key_packet_e2[] = {  
 0x48,0x00,0x00,0x00,0x8a,0xe4,0x9f,0x8a,0xd5,0x04,0x02,0xfd,0x09,0x1f,0xff,0x53,  
 0xe0,0xb2,0x72,0x8b,0x19,0xba,0x22,0xe4,0x2a,0x7b,0xeb,0x79,0xa8,0x83,0x31,0x6f,  
 0x5c,0xcc,0x37,0x9c,0xe8,0x73,0x64,0x64,0xd3,0xab,0xaa,0x9f,0xbe,0x49,0x27,0xfc,  
 0x95,0xf3,0x6e,0xf8,0xb1,0x01,0x7c,0xba,0xa9,0xc5,0x35,0x9c,0x8f,0x74,0x3a,0x9f,  
 0xd4,0x26,0x4d,0x39,0x90,0xbe,0xf4,0xfb,0x72,0x9e,0x54,0x18  
 };  
   
 /* 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);  
 }  
   
 /* Create an RC4 key and transfer it to the server */  
 void rdp_establish_key_e1(HCONN conn)  
 {  
         mcs_init_data(conn);  
         memcpy(conn->out.data + conn->out.offset, precanned_key_packet_e1,  
                sizeof(precanned_key_packet_e1));  
         conn->out.offset += sizeof(precanned_key_packet_e1);  
         MARK_END(conn->out);  
         mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);  
 }  
   
 /* Create an RC4 key and transfer it to the server */  
 void rdp_establish_key_e2(HCONN conn)  
 {  
         mcs_init_data(conn);  
         memcpy(conn->out.data + conn->out.offset, precanned_key_packet_e2,  
                sizeof(precanned_key_packet_e2));  
         conn->out.offset += sizeof(precanned_key_packet_e2);  
         MARK_END(conn->out);  
         mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);  
 }  
   
 /* Horrible horrible certificate stuff. Work out later. */  
 uint8 precanned_cert_packet[] = { // 4c8  
 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);  
 }  
   
 /* Initialise RDP transport data packet */  
 void rdp_init_data(HCONN conn)  
 {  
         mcs_init_data(conn);  
         PUSH_LAYER(conn->out, rdp_offset, 18);  
 }  
   
 /* Transmit RDP transport data packet */  
 void rdp_send_data(HCONN conn, uint16 data_pdu_type)  
 {  
         RDP_HEADER hdr;  
         RDP_DATA_HEADER datahdr;  
         int length = conn->out.end - conn->out.offset;  
   
         POP_LAYER(conn->out, rdp_offset);  
         length = conn->out.end - conn->out.offset;  
         rdp_make_header(&hdr, length, RDP_PDU_DATA, conn->mcs_userid);  
         rdp_io_header(&conn->out, &hdr);  
         rdp_make_data_header(&datahdr, 0x103ea, length, data_pdu_type);  
         rdp_io_data_header(&conn->out, &datahdr);  
         mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);  
 }  
   
 void rdp_send_confirm_active(HCONN conn, uint32 shareid, int width, int height)  
 {  
         RDP_ACTIVE_PDU active;  
   
         rdp_init(conn);  
         rdp_make_active_pdu(&active, shareid, conn->mcs_userid, width, height);  
         rdp_io_active_pdu(&conn->out, &active, RDP_PDU_CONFIRM_ACTIVE);  
         MARK_END(conn->out);  
         rdp_send(conn, RDP_PDU_CONFIRM_ACTIVE);  
 }  
   
 void rdp_send_synchronize(HCONN conn)  
 {  
         RDP_SYNCHRONISE_PDU sync;  
   
         rdp_init_data(conn);  
         rdp_make_synchronise_pdu(&sync, 1002);  
         rdp_io_synchronise_pdu(&conn->out, &sync);  
         MARK_END(conn->out);  
         rdp_send_data(conn, RDP_DATA_PDU_SYNCHRONIZE);  
 }  
   
 void rdp_send_control(HCONN conn, uint16 action)  
 {  
         RDP_CONTROL_PDU control;  
   
         rdp_init_data(conn);  
         rdp_make_control_pdu(&control, action);  
         rdp_io_control_pdu(&conn->out, &control);  
         MARK_END(conn->out);  
         rdp_send_data(conn, RDP_DATA_PDU_CONTROL);  
 }  
   
 void rdp_send_fonts(HCONN conn, uint16 seqno)  
 {  
         RDP_FONT_PDU fonts;  
   
         rdp_init_data(conn);  
         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);  
 }  
   
 void rdp_send_input(HCONN conn, uint16 message_type, uint16 device_flags,  
                                 uint16 param1, uint16 param2)  
 {  
         RDP_INPUT_PDU input;  
   
         rdp_init_data(conn);  
         rdp_make_input_pdu(&input, message_type, device_flags, param1, param2);  
         rdp_io_input_pdu(&conn->out, &input);  
         MARK_END(conn->out);  
         rdp_send_data(conn, RDP_DATA_PDU_INPUT);  
 }  
   
 BOOL rdp_recv_pdu(HCONN conn, uint8 *type)  
 {  
         RDP_HEADER hdr;  
   
         conn->in.offset = conn->in.rdp_offset;  
   
         if (conn->in.offset >= conn->in.end)  
         {  
                 if (!mcs_recv(conn, False))  
                         return False;  
         }  
   
         if (!rdp_io_header(&conn->in, &hdr))  
                 return False;  
31    
32          conn->in.rdp_offset += hdr.length;  uint8 *next_packet;
33          *type = hdr.pdu_type & 0xf;  uint32 rdp_shareid;
34    
35  #if DUMP  #if WITH_DEBUG
36          fprintf(stderr, "RDP packet (type %x):\n", *type);  static uint32 packetno;
         dump_data(conn->in.data+conn->in.offset, conn->in.rdp_offset-conn->in.offset);  
37  #endif  #endif
38    
39          return True;  /* Receive an RDP packet */
40  }  static STREAM
41    rdp_recv(uint8 * type)
 /* Disconnect from the RDP layer */  
 void rdp_disconnect(HCONN conn)  
 {  
         mcs_disconnect(conn);  
 }  
   
 /* Construct an RDP header */  
 void rdp_make_header(RDP_HEADER *hdr, uint16 length, uint16 pdu_type,  
                      uint16 userid)  
 {  
         hdr->length = length;  
         hdr->pdu_type = pdu_type | 0x10; /* Version 1 */  
         hdr->userid = userid + 1001;  
 }  
   
 /* Parse an RDP header */  
 BOOL rdp_io_header(STREAM s, RDP_HEADER *hdr)  
 {  
         BOOL res = True;  
   
         res = res ? lsb_io_uint16(s, &hdr->length  ) : False;  
         res = res ? lsb_io_uint16(s, &hdr->pdu_type) : False;  
         if ((hdr->pdu_type & 0xf) != RDP_PDU_DEACTIVATE)  
                 res = res ? lsb_io_uint16(s, &hdr->userid  ) : False;  
   
         return res;  
 }  
   
 /* Construct a data header */  
 void rdp_make_data_header(RDP_DATA_HEADER *hdr, uint32 shareid,  
                           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;  
 }  
   
 /* Parse a data header */  
 BOOL rdp_io_data_header(STREAM s, RDP_DATA_HEADER *hdr)  
 {  
         BOOL res = True;  
   
         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;  
   
         return res;  
 }  
   
 BOOL rdp_io_present(STREAM s, uint32 *present, uint8 flags, int size)  
42  {  {
43          uint8 bits;          static STREAM rdp_s;
44          int i;          uint16 length, pdu_type;
   
         if (flags & RDP_ORDER_SMALL)  
         {  
                 size--;  
         }  
45    
46          if (flags & RDP_ORDER_TINY)          if ((rdp_s == NULL) || (next_packet >= rdp_s->end))
47          {          {
48                  if (size < 2)                  rdp_s = sec_recv();
49                          return False;                  if (rdp_s == NULL)
50                            return NULL;
51    
52                  size -= 2;                  next_packet = rdp_s->p;
53          }          }
54            else
         *present = 0;  
         for (i = 0; i < size; i++)  
55          {          {
56                  prs_io_uint8(s, &bits);                  rdp_s->p = next_packet;
                 *present |= bits << (i * 8);  
57          }          }
58    
59          return True;          in_uint16_le(rdp_s, length);
60  }          /* 32k packets are really 8, keepalive fix */
61            if (length == 0x8000)
 BOOL rdp_io_coord(STREAM s, uint16 *coord, BOOL delta)  
 {  
         uint8 change;  
         BOOL res;  
   
         if (delta)  
62          {          {
63                  res = prs_io_uint8(s, &change);                  next_packet += 8;
64                  *coord += (char)change;                  *type = 0;
65                    return rdp_s;
66          }          }
67          else          in_uint16_le(rdp_s, pdu_type);
68          {          in_uint8s(rdp_s, 2);    /* userid */
69                  res = lsb_io_uint16(s, coord);          *type = pdu_type & 0xf;
         }  
   
         return res;  
 }  
   
 BOOL rdp_io_colour(STREAM s, uint8 *colour)  
 {  
         BOOL res;  
   
         res = prs_io_uint8(s, colour);  
         s->offset += 2;  
   
         return res;  
 }  
   
 BOOL rdp_io_colourmap(STREAM s, COLOURMAP *colours)  
 {  
         int datasize;  
   
         lsb_io_uint16(s, &colours->ncolours);  
         datasize = colours->ncolours * 3;  
70    
71          if (datasize > sizeof(colours->colours))  #if WITH_DEBUG
72                  return False;          DEBUG(("RDP packet #%d, (type %x)\n", ++packetno, *type));
73            //      hexdump(next_packet, length);
74    #endif /*  */
75    
76          memcpy(colours->colours, s->data + s->offset, datasize);          next_packet += length;
77          s->offset += datasize;          return rdp_s;
         return True;  
78  }  }
79    
80  BOOL rdp_io_bounds(STREAM s, BOUNDS *bounds)  /* Initialise an RDP data packet */
81    static STREAM
82    rdp_init_data(int maxlen)
83  {  {
84          uint8 present;          STREAM s;
85    
86          prs_io_uint8(s, &present);          s = sec_init(encryption ? SEC_ENCRYPT : 0, maxlen + 18);
87            s_push_layer(s, rdp_hdr, 18);
88    
89          if (present & 1)          return s;
                 rdp_io_coord(s, &bounds->left, False);  
         else if (present & 16)  
                 rdp_io_coord(s, &bounds->left, True);  
   
         if (present & 2)  
                 rdp_io_coord(s, &bounds->top, False);  
         else if (present & 32)  
                 rdp_io_coord(s, &bounds->top, True);  
   
         if (present & 4)  
                 rdp_io_coord(s, &bounds->right, False);  
         else if (present & 64)  
                 rdp_io_coord(s, &bounds->right, True);  
   
         if (present & 8)  
                 rdp_io_coord(s, &bounds->bottom, False);  
         else if (present & 128)  
                 rdp_io_coord(s, &bounds->bottom, True);  
   
         return True;  
90  }  }
91    
92  BOOL rdp_io_pen(STREAM s, PEN *pen, uint32 present)  /* Send an RDP data packet */
93    static void
94    rdp_send_data(STREAM s, uint8 data_pdu_type)
95  {  {
96          BOOL res = True;          uint16 length;
97    
98          if (present & 1)          s_pop_layer(s, rdp_hdr);
99                  res = res ? prs_io_uint8(s, &pen->style) : False;          length = s->end - s->p;
100    
101          if (present & 2)          out_uint16_le(s, length);
102                  res = res ? prs_io_uint8(s, &pen->width) : False;          out_uint16_le(s, (RDP_PDU_DATA | 0x10));
103            out_uint16_le(s, (g_mcs_userid + 1001));
104    
105          if (present & 4)          out_uint32_le(s, rdp_shareid);
106                  res = res ? rdp_io_colour(s, &pen->colour) : False;          out_uint8(s, 0);        /* pad */
107            out_uint8(s, 1);        /* streamid */
108            out_uint16_le(s, (length - 14));
109            out_uint8(s, data_pdu_type);
110            out_uint8(s, 0);        /* compress_type */
111            out_uint16(s, 0);       /* compress_len */
112    
113          return res;          sec_send(s, encryption ? SEC_ENCRYPT : 0);
114  }  }
115    
116  BOOL rdp_io_brush(STREAM s, BRUSH *brush, uint32 present)  /* Output a string in Unicode */
117    void
118    rdp_out_unistr(STREAM s, char *string, int len)
119  {  {
120          BOOL res = True;          int i = 0, j = 0;
   
         if (present & 1)  
                 res = res ? prs_io_uint8(s, &brush->xorigin) : False;  
   
         if (present & 2)  
                 res = res ? prs_io_uint8(s, &brush->yorigin) : False;  
121    
122          if (present & 4)          len += 2;
                 res = res ? prs_io_uint8(s, &brush->style) : False;  
123    
124          if (present & 8)          while (i < len)
125                  res = res ? prs_io_uint8(s, &brush->pattern[0]) : False;          {
126                    s->p[i++] = string[j++];
127          if (present & 16)                  s->p[i++] = 0;
128                  res = res ? prs_io_uint8s(s, &brush->pattern[1], 7) : False;          }
   
         return res;  
 }  
   
 /* Construct a confirm/demand active PDU */  
 void rdp_make_active_pdu(RDP_ACTIVE_PDU *pdu, uint32 shareid, uint16 userid,  
                                 int width, int height)  
 {  
         memset(pdu, 0, sizeof(*pdu));  
         pdu->shareid = shareid;  
         pdu->userid  = 1002;  
         pdu->source_len = sizeof(RDP_SOURCE);  
         memcpy(pdu->source, RDP_SOURCE, sizeof(RDP_SOURCE));  
   
         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;  
129    
130          rdp_make_general_caps (&pdu->general_caps );          s->p += len;
         rdp_make_bitmap_caps  (&pdu->bitmap_caps, width, height);  
         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);  
131  }  }
132    
133  /* Parse a confirm/demand active PDU */  /* Parse a logon info packet */
134  BOOL rdp_io_active_pdu(STREAM s, RDP_ACTIVE_PDU *pdu, int pdutype)  static void
135    rdp_send_logon_info(uint32 flags, char *domain, char *user,
136                        char *password, char *program, char *directory)
137  {  {
138          uint16 capset;          int len_domain = 2 * strlen(domain);
139          uint16 length;          int len_user = 2 * strlen(user);
140          BOOL res;          int len_password = 2 * strlen(password);
141          int i;          int len_program = 2 * strlen(program);
142            int len_directory = 2 * strlen(directory);
143          res = lsb_io_uint32(s, &pdu->shareid);          int len_ip = 2 * strlen("127.0.0.1");
144            int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
145            int packetlen = 0;
146            uint32 sec_flags = encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
147            STREAM s;
148    
149          if (pdutype == RDP_PDU_CONFIRM_ACTIVE)          if (!use_rdp5 || 1 == server_rdp_version)
                 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)  
150          {          {
151                  ERROR("RDP source descriptor too long\n");                  DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
152                  return False;  
153          }                  s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
154                                 + len_program + len_directory + 10);
155    
156          res = res ? prs_io_uint8s(s,  pdu->source, pdu->source_len) : False;                  out_uint32(s, 0);
157          res = res ? lsb_io_uint16(s, &pdu->num_caps  ) : False;                  out_uint32_le(s, flags);
158          res = res ? lsb_io_uint16(s, &pdu->pad       ) : False;                  out_uint16_le(s, len_domain);
159                    out_uint16_le(s, len_user);
160          if (s->marshall)                  out_uint16_le(s, len_password);
161          {                  out_uint16_le(s, len_program);
162                  capset = RDP_CAPSET_GENERAL;                  out_uint16_le(s, len_directory);
163                  res = res ? lsb_io_uint16(s, &capset) : False;                  rdp_out_unistr(s, domain, len_domain);
164                  res = res ? rdp_io_general_caps(s, &pdu->general_caps) : False;                  rdp_out_unistr(s, user, len_user);
165                    rdp_out_unistr(s, password, len_password);
166                  capset = RDP_CAPSET_BITMAP;                  rdp_out_unistr(s, program, len_program);
167                  res = res ? lsb_io_uint16(s, &capset) : False;                  rdp_out_unistr(s, directory, len_directory);
                 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;  
168          }          }
169          else          else
170          {          {
171                  for (i = 0; i < pdu->num_caps; i++)                  flags |= RDP_LOGON_BLOB;
172                    DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
173                    packetlen = 4 + // Unknown uint32
174                            4 + // flags
175                            2 + // len_domain
176                            2 + // len_user
177                            (flags & RDP_LOGON_AUTO ? 2 : 0) + // len_password
178                            (flags & RDP_LOGON_BLOB ? 2 : 0) + // Length of BLOB
179                            2 + // len_program
180                            2 + // len_directory
181                            (0 < len_domain ? len_domain : 2) + // domain
182                            len_user +
183                            (flags & RDP_LOGON_AUTO ? len_password : 0) +
184                            0 + // We have no 512 byte BLOB. Perhaps we must?
185                            (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + // After the BLOB is a unknown int16. If there is a BLOB, that is.
186                            (0 < len_program ? len_program : 2) +
187                            (0 < len_directory ? len_directory : 2) +
188                            2 + // Unknown (2)
189                            2 + // Client ip length
190                            len_ip + // Client ip
191                            2 +  // DLL string length
192                            len_dll + // DLL string
193                            2 +  // Unknown
194                            2 +  // Unknown
195                            64 +  // Time zone #0
196                            2 +  // Unknown
197                            64 +  // Time zone #1
198                            32; // Unknown
199                            
200                    s = sec_init(sec_flags, packetlen);    
201                    DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
202    
203                    out_uint32(s, 0); // Unknown
204                    out_uint32_le(s, flags);
205                    out_uint16_le(s, len_domain);
206                    out_uint16_le(s, len_user);
207                    if (flags & RDP_LOGON_AUTO)
208                  {                  {
209                          if (!res)                          out_uint16_le(s, len_password);
                                 return False;  
   
                         if (!lsb_io_uint16(s, &capset))  
                                 return False;  
   
                         switch (capset)  
                         {  
                         case RDP_CAPSET_GENERAL:  
                                 res = rdp_io_general_caps (s, &pdu->general_caps );  
                                 break;  
                         case RDP_CAPSET_BITMAP:  
                                 res = rdp_io_bitmap_caps  (s, &pdu->bitmap_caps  );  
                                 break;  
                         case RDP_CAPSET_ORDER:  
                                 res = rdp_io_order_caps   (s, &pdu->order_caps   );  
                                 break;  
                         case RDP_CAPSET_BMPCACHE:  
                                 res = rdp_io_bmpcache_caps(s, &pdu->bmpcache_caps);  
                                 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:  
                                 NOTIMP("capset 0x%x\n", capset);  
210    
                                 if (!lsb_io_uint16(s, &length))  
                                         return False;  
   
                                 s->offset += (length - 4);  
                         }  
211                  }                  }
212          }                  if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO)) {
213                            out_uint16_le(s, 0);
214          return res;                  }
215  }                  out_uint16_le(s, len_program);
216                    out_uint16_le(s, len_directory);
217  /* Construct a control PDU */                  if (0 < len_domain)
218  void rdp_make_control_pdu(RDP_CONTROL_PDU *pdu, uint16 action)                          rdp_out_unistr(s, domain, len_domain);
219  {                  else
220          pdu->action = action;                          out_uint16_le(s, 0);
221          pdu->userid = 0;                  rdp_out_unistr(s, user, len_user);
222          pdu->controlid = 0;                  if (flags & RDP_LOGON_AUTO)
223  }                  {
224                            rdp_out_unistr(s, password, len_password);
225  /* Parse a control PDU */                  }
226  BOOL rdp_io_control_pdu(STREAM s, RDP_CONTROL_PDU *pdu)                  if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))  {
227  {                          out_uint16_le(s, 0);
228          BOOL res = True;                  }
229                    if (0 < len_program) {
230          res = res ? lsb_io_uint16(s, &pdu->action   ) : False;                          rdp_out_unistr(s, program, len_program);
231          res = res ? lsb_io_uint16(s, &pdu->userid   ) : False;                          
232          res = res ? lsb_io_uint32(s, &pdu->controlid) : False;                  } else {
233                            out_uint16_le(s, 0);
234          return res;                  }
235  }                  if (0 < len_directory) {
236                            rdp_out_unistr(s, directory, len_directory);
237  /* Construct a synchronisation PDU */                  } else {
238  void rdp_make_synchronise_pdu(RDP_SYNCHRONISE_PDU *pdu, uint16 userid)                          out_uint16_le(s, 0);
239  {                  }
240          pdu->type = 1;                  out_uint16_le(s, 2);
241          pdu->userid = userid;                  out_uint16_le(s, len_ip+2); // Length of client ip
242  }                  rdp_out_unistr(s, "127.0.0.1", len_ip);
243                    out_uint16_le(s, len_dll+2);
244                    rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
245                    out_uint16_le(s, 0xffc4);
246                    out_uint16_le(s, 0xffff);
247                    rdp_out_unistr(s, "GTB, normaltid",
248                                   2*strlen("GTB, normaltid"));
249                    out_uint8s(s, 62-2*strlen("GTB, normaltid"));
250                                  
251    
252                    out_uint32_le(s, 0x0a0000);
253                    out_uint32_le(s, 0x050000);
254                    out_uint32_le(s, 3);
255                    out_uint32_le(s, 0);
256                    out_uint32_le(s, 0);
257                    
258                    rdp_out_unistr(s, "GTB, sommartid",
259                                   2*strlen("GTB, sommartid"));
260                    out_uint8s(s, 62-2*strlen("GTB, sommartid"));
261    
262                    out_uint32_le(s, 0x30000);
263                    out_uint32_le(s, 0x050000);
264                    out_uint32_le(s, 2);
265                    out_uint32(s, 0);
266                    out_uint32_le(s, 0xffffffc4);
267                    out_uint32_le(s, 0xfffffffe);
268                    out_uint32_le(s, 0x0f);
269                    out_uint32(s, 0);
270    
271    
272            }
273            s_mark_end(s);
274            sec_send(s, sec_flags);
275    }
276    
277    /* Send a control PDU */
278    static void
279    rdp_send_control(uint16 action)
280    {
281            STREAM s;
282    
283            s = rdp_init_data(8);
284    
285            out_uint16_le(s, action);
286            out_uint16(s, 0);       /* userid */
287            out_uint32(s, 0);       /* control id */
288    
289            s_mark_end(s);
290            rdp_send_data(s, RDP_DATA_PDU_CONTROL);
291    }
292    
293    /* Send a synchronisation PDU */
294    static void
295    rdp_send_synchronise(void)
296    {
297            STREAM s;
298    
299            s = rdp_init_data(4);
300    
301            out_uint16_le(s, 1);    /* type */
302            out_uint16_le(s, 1002);
303    
304            s_mark_end(s);
305            rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);
306    }
307    
308    /* Send a single input event */
309    void
310    rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
311    {
312            STREAM s;
313    
314            s = rdp_init_data(16);
315    
316            out_uint16_le(s, 1);    /* number of events */
317            out_uint16(s, 0);       /* pad */
318    
319            out_uint32_le(s, time);
320            out_uint16_le(s, message_type);
321            out_uint16_le(s, device_flags);
322            out_uint16_le(s, param1);
323            out_uint16_le(s, param2);
324    
325            s_mark_end(s);
326            rdp_send_data(s, RDP_DATA_PDU_INPUT);
327    }
328    
329    /* Send an (empty) font information PDU */
330    static void
331    rdp_send_fonts(uint16 seq)
332    {
333            STREAM s;
334    
335            s = rdp_init_data(8);
336    
337            out_uint16(s, 0);       /* number of fonts */
338            out_uint16_le(s, 0x3e); /* unknown */
339            out_uint16_le(s, seq);  /* unknown */
340            out_uint16_le(s, 0x32); /* entry size */
341    
342            s_mark_end(s);
343            rdp_send_data(s, RDP_DATA_PDU_FONT2);
344    }
345    
346    /* Output general capability set */
347    static void
348    rdp_out_general_caps(STREAM s)
349    {
350            out_uint16_le(s, RDP_CAPSET_GENERAL);
351            out_uint16_le(s, RDP_CAPLEN_GENERAL);
352    
353            out_uint16_le(s, 1);    /* OS major type */
354            out_uint16_le(s, 3);    /* OS minor type */
355            out_uint16_le(s, 0x200);        /* Protocol version */
356            out_uint16(s, 0);       /* Pad */
357            out_uint16(s, 0);       /* Compression types */
358            out_uint16_le(s, use_rdp5 ? 0x40d : 0);
359            /* Pad, according to T.128. 0x40d seems to
360               trigger
361               the server to start sending RDP5 packets.
362               However, the value is 0x1d04 with W2KTSK and
363               NT4MS. Hmm.. Anyway, thankyou, Microsoft,
364               for sending such information in a padding
365               field.. */
366            out_uint16(s, 0);       /* Update capability */
367            out_uint16(s, 0);       /* Remote unshare capability */
368            out_uint16(s, 0);       /* Compression level */
369            out_uint16(s, 0);       /* Pad */
370    }
371    
372    /* Output bitmap capability set */
373    static void
374    rdp_out_bitmap_caps(STREAM s)
375    {
376            out_uint16_le(s, RDP_CAPSET_BITMAP);
377            out_uint16_le(s, RDP_CAPLEN_BITMAP);
378    
379            out_uint16_le(s, 8);    /* Preferred BPP */
380            out_uint16_le(s, 1);    /* Receive 1 BPP */
381            out_uint16_le(s, 1);    /* Receive 4 BPP */
382            out_uint16_le(s, 1);    /* Receive 8 BPP */
383            out_uint16_le(s, 800);  /* Desktop width */
384            out_uint16_le(s, 600);  /* Desktop height */
385            out_uint16(s, 0);       /* Pad */
386            out_uint16(s, 0);       /* Allow resize */
387            out_uint16_le(s, bitmap_compression ? 1 : 0);   /* Support compression */
388            out_uint16(s, 0);       /* Unknown */
389            out_uint16_le(s, 1);    /* Unknown */
390            out_uint16(s, 0);       /* Pad */
391    }
392    
393    /* Output order capability set */
394    static void
395    rdp_out_order_caps(STREAM s)
396    {
397            uint8 order_caps[32];
398    
399    
400            memset(order_caps, 0, 32);
401            order_caps[0] = 1;      /* dest blt */
402            order_caps[1] = 1;      /* pat blt */
403            order_caps[2] = 1;      /* screen blt */
404            order_caps[3] = 1;      /* required for memblt? */
405            order_caps[8] = 1;      /* line */
406            order_caps[9] = 1;      /* line */
407            order_caps[10] = 1;     /* rect */
408            order_caps[11] = (desktop_save == False ? 0 : 1);       /* desksave */
409            order_caps[13] = 1;     /* memblt */
410            order_caps[14] = 1;     /* triblt */
411            order_caps[22] = 1;     /* polyline */
412            order_caps[27] = 1;     /* text2 */
413            out_uint16_le(s, RDP_CAPSET_ORDER);
414            out_uint16_le(s, RDP_CAPLEN_ORDER);
415    
416            out_uint8s(s, 20);      /* Terminal desc, pad */
417            out_uint16_le(s, 1);    /* Cache X granularity */
418            out_uint16_le(s, 20);   /* Cache Y granularity */
419            out_uint16(s, 0);       /* Pad */
420            out_uint16_le(s, 1);    /* Max order level */
421            out_uint16_le(s, 0x147);        /* Number of fonts */
422            out_uint16_le(s, 0x2a); /* Capability flags */
423            out_uint8p(s, order_caps, 32);  /* Orders supported */
424            out_uint16_le(s, 0x6a1);        /* Text capability flags */
425            out_uint8s(s, 6);       /* Pad */
426            out_uint32_le(s, desktop_save == False ? 0 : 0x38400);  /* Desktop cache size */
427            out_uint32(s, 0);       /* Unknown */
428            out_uint32_le(s, 0x4e4);        /* Unknown */
429    }
430    
431    /* Output bitmap cache capability set */
432    static void
433    rdp_out_bmpcache_caps(STREAM s)
434    {
435            out_uint16_le(s, RDP_CAPSET_BMPCACHE);
436            out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
437    
438            out_uint8s(s, 24);      /* unused */
439            out_uint16_le(s, 0x258);        /* entries */
440            out_uint16_le(s, 0x100);        /* max cell size */
441            out_uint16_le(s, 0x12c);        /* entries */
442            out_uint16_le(s, 0x400);        /* max cell size */
443            out_uint16_le(s, 0x106);        /* entries */
444            out_uint16_le(s, 0x1000);       /* max cell size */
445    }
446    
447    /* Output control capability set */
448    static void
449    rdp_out_control_caps(STREAM s)
450    {
451            out_uint16_le(s, RDP_CAPSET_CONTROL);
452            out_uint16_le(s, RDP_CAPLEN_CONTROL);
453    
454            out_uint16(s, 0);       /* Control capabilities */
455            out_uint16(s, 0);       /* Remote detach */
456            out_uint16_le(s, 2);    /* Control interest */
457            out_uint16_le(s, 2);    /* Detach interest */
458    }
459    
460    /* Output activation capability set */
461    static void
462    rdp_out_activate_caps(STREAM s)
463    {
464            out_uint16_le(s, RDP_CAPSET_ACTIVATE);
465            out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
466    
467            out_uint16(s, 0);       /* Help key */
468            out_uint16(s, 0);       /* Help index key */
469            out_uint16(s, 0);       /* Extended help key */
470            out_uint16(s, 0);       /* Window activate */
471    }
472    
473    /* Output pointer capability set */
474    static void
475    rdp_out_pointer_caps(STREAM s)
476    {
477            out_uint16_le(s, RDP_CAPSET_POINTER);
478            out_uint16_le(s, RDP_CAPLEN_POINTER);
479    
480            out_uint16(s, 0);       /* Colour pointer */
481            out_uint16_le(s, 20);   /* Cache size */
482    }
483    
484    /* Output share capability set */
485    static void
486    rdp_out_share_caps(STREAM s)
487    {
488            out_uint16_le(s, RDP_CAPSET_SHARE);
489            out_uint16_le(s, RDP_CAPLEN_SHARE);
490    
491            out_uint16(s, 0);       /* userid */
492            out_uint16(s, 0);       /* pad */
493    }
494    
495    /* Output colour cache capability set */
496    static void
497    rdp_out_colcache_caps(STREAM s)
498    {
499            out_uint16_le(s, RDP_CAPSET_COLCACHE);
500            out_uint16_le(s, RDP_CAPLEN_COLCACHE);
501    
502            out_uint16_le(s, 6);    /* cache size */
503            out_uint16(s, 0);       /* pad */
504    }
505    
506    static uint8 canned_caps[] = {
507            0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,
508            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
509            0x00, 0x00, 0x00, 0x00, 0x00,
510            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
511            0x00, 0x00, 0x00, 0x00, 0x00,
512            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
513            0x00, 0x00, 0x00, 0x00, 0x00,
514            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
515            0x00, 0x00, 0x00, 0x00, 0x00,
516            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
517            0x0C, 0x00, 0x08, 0x00, 0x01,
518            0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
519            0x10, 0x00, 0x34, 0x00, 0xFE,
520            0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,
521            0xFE, 0x00, 0x08, 0x00, 0xFE,
522            0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,
523            0xFE, 0x00, 0x80, 0x00, 0xFE,
524            0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
525            0x02, 0x00, 0x00, 0x00
526    };
527    
528  /* Parse a synchronisation PDU */  /* Output unknown capability sets (number 13, 12, 14 and 16) */
529  BOOL rdp_io_synchronise_pdu(STREAM s, RDP_SYNCHRONISE_PDU *pdu)  static void
530    rdp_out_unknown_caps(STREAM s)
531  {  {
532          BOOL res = True;          out_uint16_le(s, RDP_CAPSET_UNKNOWN);
533            out_uint16_le(s, 0x58);
         res = res ? lsb_io_uint16(s, &pdu->type  ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->userid) : False;  
534    
535          return res;          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);
536  }  }
537    
538  /* Parse a single input event */  #define RDP5_FLAG 0x0030
539  BOOL rdp_io_input_event(STREAM s, RDP_INPUT_EVENT *evt)  /* Send a confirm active PDU */
540    static void
541    rdp_send_confirm_active(void)
542  {  {
543          BOOL res = True;          STREAM s;
544            uint32 sec_flags = encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
545          res = res ? lsb_io_uint32(s, &evt->event_time)   : False;          uint16 caplen =
546          res = res ? lsb_io_uint16(s, &evt->message_type) : False;                  RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
547          res = res ? lsb_io_uint16(s, &evt->device_flags) : False;                  RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
548                    RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
549                    RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;
550    
551          if (!res)          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
                 return False;  
552    
553          switch (evt->message_type)          out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
554          {          out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10));      /* Version 1 */
555          case RDP_INPUT_CODEPOINT:          out_uint16_le(s, (g_mcs_userid + 1001));
         case RDP_INPUT_VIRTKEY:  
                 res = res ? lsb_io_uint16(s, &evt->param1) : False;  
                 break;  
         case RDP_INPUT_SYNCHRONIZE:  
         case RDP_INPUT_SCANCODE:  
         case RDP_INPUT_MOUSE:  
                 res = res ? lsb_io_uint16(s, &evt->param1) : False;  
                 res = res ? lsb_io_uint16(s, &evt->param2) : False;  
                 break;  
         default:  
                 NOTIMP("input type %d\n", evt->message_type);  
                 return False;  
         }  
556    
557          return res;          out_uint32_le(s, rdp_shareid);
558  }          out_uint16_le(s, 0x3ea);        /* userid */
559            out_uint16_le(s, sizeof(RDP_SOURCE));
560            out_uint16_le(s, caplen);
561    
562  /* Construct an input PDU */          out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
563  void rdp_make_input_pdu(RDP_INPUT_PDU *pdu, uint16 message_type,          out_uint16_le(s, 0xd);  /* num_caps */
564                          uint16 device_flags, uint16 param1, uint16 param2)          out_uint8s(s, 2);       /* pad */
 {  
         uint32 now = time(NULL);  
565    
566          pdu->num_events = 1;          rdp_out_general_caps(s);
567          pdu->pad = 0;          rdp_out_bitmap_caps(s);
568            rdp_out_order_caps(s);
569            rdp_out_bmpcache_caps(s);
570            rdp_out_colcache_caps(s);
571            rdp_out_activate_caps(s);
572            rdp_out_control_caps(s);
573            rdp_out_pointer_caps(s);
574            rdp_out_share_caps(s);
575            rdp_out_unknown_caps(s);
576    
577          pdu->event[0].event_time = now;          s_mark_end(s);
578          pdu->event[0].message_type = message_type;          sec_send(s, sec_flags);
         pdu->event[0].device_flags = device_flags;  
         pdu->event[0].param1 = param1;  
         pdu->event[0].param2 = param2;  
579  }  }
580    
581  /* Parse an input PDU */  /* Respond to a demand active PDU */
582  BOOL rdp_io_input_pdu(STREAM s, RDP_INPUT_PDU *pdu)  static void
583    process_demand_active(STREAM s)
584  {  {
585          BOOL res = True;          uint8 type;
         int i;  
586    
587          res = res ? lsb_io_uint16(s, &pdu->num_events) : False;          in_uint32_le(s, rdp_shareid);
         res = res ? lsb_io_uint16(s, &pdu->pad       ) : False;  
588    
589          if (pdu->num_events > RDP_MAX_EVENTS)          DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", rdp_shareid));
         {  
                 ERROR("Too many events in one PDU\n");  
                 return False;  
         }  
590    
591          for (i = 0; i < pdu->num_events; i++)          rdp_send_confirm_active();
592          {          rdp_send_synchronise();
593                  res = res ? rdp_io_input_event(s, &pdu->event[i]) : False;          rdp_send_control(RDP_CTL_COOPERATE);
594          }          rdp_send_control(RDP_CTL_REQUEST_CONTROL);
595            rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
596          return res;          rdp_recv(&type);        /* RDP_CTL_COOPERATE */
597            rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
598            rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, 0, 0);
599            rdp_send_fonts(1);
600            rdp_send_fonts(2);
601            rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 */
602            reset_order_state();
603  }  }
604    
605  /* Construct a font information PDU */  /* Process a null system pointer PDU */
606  void rdp_make_font_pdu(RDP_FONT_PDU *pdu, uint16 seqno)  void
607    process_null_system_pointer_pdu(STREAM s)
608  {  {
609          pdu->num_fonts = 0;          // FIXME: We should probably set another cursor here,
610          pdu->unknown1 = 0x3e;          // like the X window system base cursor or something.
611          pdu->unknown2 = seqno;          ui_set_cursor(cache_get_cursor(0));
         pdu->entry_size = RDP_FONT_INFO_SIZE;  
612  }  }
613    
614  /* Parse a font information structure */  /* Process a colour pointer PDU */
615  BOOL rdp_io_font_info(STREAM s, RDP_FONT_INFO *font)  void
616    process_colour_pointer_pdu(STREAM s)
617  {  {
618          BOOL res = True;          uint16 x, y, width, height, cache_idx, masklen, datalen;
619            uint8 *mask, *data;
620          res = res ? prs_io_uint8s(s,  font->name, 32 ) : False;          HCURSOR cursor;
         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;  
621    
622          return res;          in_uint16_le(s, cache_idx);
623            in_uint16_le(s, x);
624            in_uint16_le(s, y);
625            in_uint16_le(s, width);
626            in_uint16_le(s, height);
627            in_uint16_le(s, masklen);
628            in_uint16_le(s, datalen);
629            in_uint8p(s, data, datalen);
630            in_uint8p(s, mask, masklen);
631            cursor = ui_create_cursor(x, y, width, height, mask, data);
632            ui_set_cursor(cursor);
633            cache_put_cursor(cache_idx, cursor);
634  }  }
635    
636  /* Parse a font information PDU */  /* Process a cached pointer PDU */
637  BOOL rdp_io_font_pdu(STREAM s, RDP_FONT_PDU *pdu)  void
638    process_cached_pointer_pdu(STREAM s)
639  {  {
640          BOOL res = True;          uint16 cache_idx;
         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)  
         {  
                 ERROR("Too many fonts in one PDU\n");  
                 return False;  
         }  
641    
642          for (i = 0; i < pdu->num_fonts; i++)          in_uint16_le(s, cache_idx);
643          {          ui_set_cursor(cache_get_cursor(cache_idx));
                 res = res ? rdp_io_font_info(s, &pdu->font[i]) : False;  
         }  
   
         return res;  
644  }  }
645    
646  /* Parse a pointer PDU */  
647  BOOL rdp_io_pointer_pdu(STREAM s, RDP_POINTER_PDU *ptr)  /* Process a pointer PDU */
648    static void
649    process_pointer_pdu(STREAM s)
650  {  {
651          BOOL res = True;          uint16 message_type;
652            uint16 x, y;
653    
654          res = res ? lsb_io_uint16(s, &ptr->message) : False;          in_uint16_le(s, message_type);
655          res = res ? lsb_io_uint16(s, &ptr->pad    ) : False;          in_uint8s(s, 2);        /* pad */
656    
657          switch (ptr->message)          switch (message_type)
658          {          {
659                  case RDP_POINTER_MOVE:                  case RDP_POINTER_MOVE:
660                          res = res ? lsb_io_uint16(s, &ptr->x      ) : False;                          in_uint16_le(s, x);
661                          res = res ? lsb_io_uint16(s, &ptr->y      ) : False;                          in_uint16_le(s, y);
662                            if (s_check(s))
663                                    ui_move_pointer(x, y);
664                          break;                          break;
         }  
   
         return res;  
 }  
   
 /* Parse an update PDU */  
 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;  
 }  
   
   
 /* PRIMARY ORDERS */  
   
 /* Parse an destination blt order */  
 BOOL rdp_io_destblt_order(STREAM s, DESTBLT_ORDER *os, uint32 present, BOOL delta)  
 {  
         if (present & 0x01)  
                 rdp_io_coord(s, &os->x, delta);  
   
         if (present & 0x02)  
                 rdp_io_coord(s, &os->y, delta);  
   
         if (present & 0x04)  
                 rdp_io_coord(s, &os->cx, delta);  
   
         if (present & 0x08)  
                 rdp_io_coord(s, &os->cy, delta);  
   
         if (present & 0x10)  
                 prs_io_uint8(s, &os->opcode);  
   
         return PRS_ERROR(s);  
 }  
   
 /* Parse an pattern blt order */  
 BOOL rdp_io_patblt_order(STREAM s, PATBLT_ORDER *os, uint32 present, BOOL delta)  
 {  
         if (present & 0x0001)  
                 rdp_io_coord(s, &os->x, delta);  
   
         if (present & 0x0002)  
                 rdp_io_coord(s, &os->y, delta);  
   
         if (present & 0x0004)  
                 rdp_io_coord(s, &os->cx, delta);  
   
         if (present & 0x0008)  
                 rdp_io_coord(s, &os->cy, delta);  
665    
666          if (present & 0x0010)                  case RDP_POINTER_COLOR:
667                  prs_io_uint8(s, &os->opcode);                          process_colour_pointer_pdu(s);
668                            break;
         if (present & 0x0020)  
                 rdp_io_colour(s, &os->bgcolour);  
   
         if (present & 0x0040)  
                 rdp_io_colour(s, &os->fgcolour);  
   
         rdp_io_brush(s, &os->brush, present >> 7);  
   
         return PRS_ERROR(s);  
 }  
   
 /* Parse an screen blt order */  
 BOOL rdp_io_screenblt_order(STREAM s, SCREENBLT_ORDER *os, uint32 present, BOOL delta)  
 {  
         if (present & 0x0001)  
                 rdp_io_coord(s, &os->x, delta);  
   
         if (present & 0x0002)  
                 rdp_io_coord(s, &os->y, delta);  
   
         if (present & 0x0004)  
                 rdp_io_coord(s, &os->cx, delta);  
   
         if (present & 0x0008)  
                 rdp_io_coord(s, &os->cy, delta);  
   
         if (present & 0x0010)  
                 prs_io_uint8(s, &os->opcode);  
   
         if (present & 0x0020)  
                 rdp_io_coord(s, &os->srcx, delta);  
   
         if (present & 0x0040)  
                 rdp_io_coord(s, &os->srcy, delta);  
   
         return PRS_ERROR(s);  
 }  
   
 /* Parse a line order */  
 BOOL rdp_io_line_order(STREAM s, LINE_ORDER *os, uint32 present, BOOL delta)  
 {  
         if (present & 0x0001)  
                 lsb_io_uint16(s, &os->mixmode);  
   
         if (present & 0x0002)  
                 rdp_io_coord(s, &os->startx, delta);  
   
         if (present & 0x0004)  
                 rdp_io_coord(s, &os->starty, delta);  
   
         if (present & 0x0008)  
                 rdp_io_coord(s, &os->endx, delta);  
   
         if (present & 0x0010)  
                 rdp_io_coord(s, &os->endy, delta);  
   
         if (present & 0x0020)  
                 rdp_io_colour(s, &os->bgcolour);  
   
         if (present & 0x0040)  
                 prs_io_uint8(s, &os->opcode);  
   
         rdp_io_pen(s, &os->pen, present >> 7);  
   
         return PRS_ERROR(s);  
 }  
   
 /* Parse an opaque rectangle order */  
 BOOL rdp_io_rect_order(STREAM s, RECT_ORDER *os, uint32 present, BOOL delta)  
 {  
         if (present & 0x01)  
                 rdp_io_coord(s, &os->x, delta);  
   
         if (present & 0x02)  
                 rdp_io_coord(s, &os->y, delta);  
   
         if (present & 0x04)  
                 rdp_io_coord(s, &os->cx, delta);  
   
         if (present & 0x08)  
                 rdp_io_coord(s, &os->cy, delta);  
   
         if (present & 0x10)  
                 prs_io_uint8(s, &os->colour);  
   
         return PRS_ERROR(s);  
 }  
   
 /* Parse a desktop save order */  
 BOOL rdp_io_desksave_order(STREAM s, DESKSAVE_ORDER *os, uint32 present, BOOL delta)  
 {  
         if (present & 0x01)  
                 lsb_io_uint32(s, &os->offset);  
   
         if (present & 0x02)  
                 rdp_io_coord(s, &os->left, delta);  
   
         if (present & 0x04)  
                 rdp_io_coord(s, &os->top, delta);  
   
         if (present & 0x08)  
                 rdp_io_coord(s, &os->right, delta);  
   
         if (present & 0x10)  
                 rdp_io_coord(s, &os->bottom, delta);  
   
         if (present & 0x20)  
                 prs_io_uint8(s, &os->action);  
   
         return PRS_ERROR(s);  
 }  
   
 /* Parse a memory blt order */  
 BOOL rdp_io_memblt_order(STREAM s, MEMBLT_ORDER *os, uint32 present, BOOL delta)  
 {  
         if (present & 0x0001)  
         {  
                 prs_io_uint8(s, &os->cache_id);  
                 prs_io_uint8(s, &os->colour_table);  
         }  
   
         if (present & 0x0002)  
                 rdp_io_coord(s, &os->x, delta);  
   
         if (present & 0x0004)  
                 rdp_io_coord(s, &os->y, delta);  
   
         if (present & 0x0008)  
                 rdp_io_coord(s, &os->cx, delta);  
   
         if (present & 0x0010)  
                 rdp_io_coord(s, &os->cy, delta);  
   
         if (present & 0x0020)  
                 prs_io_uint8(s, &os->opcode);  
   
         if (present & 0x0040)  
                 rdp_io_coord(s, &os->srcx, delta);  
   
         if (present & 0x0080)  
                 rdp_io_coord(s, &os->srcy, delta);  
   
         if (present & 0x0100)  
                 lsb_io_uint16(s, &os->cache_idx);  
669    
670          return PRS_ERROR(s);                  case RDP_POINTER_CACHED:
671  }                          process_cached_pointer_pdu(s);
672                            break;
673    
674  /* Parse a 3-way blt order */                  default:
675  BOOL rdp_io_triblt_order(STREAM s, TRIBLT_ORDER *os, uint32 present, BOOL delta)                          DEBUG(("Pointer message 0x%x\n", message_type));
 {  
         if (present & 0x000001)  
         {  
                 prs_io_uint8(s, &os->cache_id);  
                 prs_io_uint8(s, &os->colour_table);  
676          }          }
   
         if (present & 0x000002)  
                 rdp_io_coord(s, &os->x, delta);  
   
         if (present & 0x000004)  
                 rdp_io_coord(s, &os->y, delta);  
   
         if (present & 0x000008)  
                 rdp_io_coord(s, &os->cx, delta);  
   
         if (present & 0x000010)  
                 rdp_io_coord(s, &os->cy, delta);  
   
         if (present & 0x000020)  
                 prs_io_uint8(s, &os->opcode);  
   
         if (present & 0x000040)  
                 rdp_io_coord(s, &os->srcx, delta);  
   
         if (present & 0x000080)  
                 rdp_io_coord(s, &os->srcy, delta);  
   
         if (present & 0x000100)  
                 rdp_io_colour(s, &os->bgcolour);  
   
         if (present & 0x000200)  
                 rdp_io_colour(s, &os->fgcolour);  
   
         rdp_io_brush(s, &os->brush, present >> 10);  
   
         if (present & 0x008000)  
                 lsb_io_uint16(s, &os->cache_idx);  
   
         if (present & 0x010000)  
                 lsb_io_uint16(s, &os->unknown);  
   
         return PRS_ERROR(s);  
677  }  }
678    
679  /* Parse a text order */  /* Process bitmap updates */
680  BOOL rdp_io_text2_order(STREAM s, TEXT2_ORDER *os, uint32 present, BOOL delta)  void
681    process_bitmap_updates(STREAM s)
682  {  {
683          if (present & 0x000001)          uint16 num_updates;
684                  prs_io_uint8(s, &os->font);          uint16 left, top, right, bottom, width, height;
685            uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
686          if (present & 0x000002)          uint8 *data, *bmpdata;
687                  prs_io_uint8(s, &os->flags);          int i;
   
         if (present & 0x000004)  
                 prs_io_uint8(s, &os->unknown);  
   
         if (present & 0x000008)  
                 prs_io_uint8(s, &os->mixmode);  
   
         if (present & 0x000010)  
                 rdp_io_colour(s, &os->fgcolour);  
   
         if (present & 0x000020)  
                 rdp_io_colour(s, &os->bgcolour);  
   
         if (present & 0x000040)  
                 lsb_io_uint16(s, &os->clipleft);  
   
         if (present & 0x000080)  
                 lsb_io_uint16(s, &os->cliptop);  
   
         if (present & 0x000100)  
                 lsb_io_uint16(s, &os->clipright);  
   
         if (present & 0x000200)  
                 lsb_io_uint16(s, &os->clipbottom);  
   
         if (present & 0x000400)  
                 lsb_io_uint16(s, &os->boxleft);  
   
         if (present & 0x000800)  
                 lsb_io_uint16(s, &os->boxtop);  
   
         if (present & 0x001000)  
                 lsb_io_uint16(s, &os->boxright);  
   
         if (present & 0x002000)  
                 lsb_io_uint16(s, &os->boxbottom);  
   
         if (present & 0x080000)  
                 lsb_io_uint16(s, &os->x);  
688    
689          if (present & 0x100000)          in_uint16_le(s, num_updates);
                 lsb_io_uint16(s, &os->y);  
690    
691          if (present & 0x200000)          for (i = 0; i < num_updates; i++)
692          {          {
693                  prs_io_uint8(s, &os->length);                  in_uint16_le(s, left);
694                  prs_io_uint8s(s, os->text, os->length);                  in_uint16_le(s, top);
695          }                  in_uint16_le(s, right);
696                    in_uint16_le(s, bottom);
697          return PRS_ERROR(s);                  in_uint16_le(s, width);
698  }                  in_uint16_le(s, height);
699                    in_uint16_le(s, bpp);
700                    Bpp = (bpp + 7) / 8;
701                    in_uint16_le(s, compress);
702                    in_uint16_le(s, bufsize);
703    
704                    cx = right - left + 1;
705                    cy = bottom - top + 1;
706    
707  /* SECONDARY ORDERS */                  DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
708                           left, top, right, bottom, width, height, Bpp, compress));
709    
710  BOOL rdp_io_secondary_order(STREAM s, RDP_SECONDARY_ORDER *rso)                  if (!compress)
711  {                  {
712          BOOL res = True;                          int y;
713                            bmpdata = (uint8*)xmalloc(width * height * Bpp);
714          res = res ? lsb_io_uint16(s, &rso->length) : False;                          for (y = 0; y < height; y++)
715          res = res ? lsb_io_uint16(s, &rso->flags ) : False;                          {
716          res = res ? prs_io_uint8 (s, &rso->type  ) : False;                                  in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
717                                              width * Bpp);
718          return res;                          }
719  }                          ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
720                            xfree(bmpdata);
721  BOOL rdp_io_raw_bmpcache_order(STREAM s, RDP_RAW_BMPCACHE_ORDER *rbo)                          continue;
722  {                  }
         BOOL res = True;  
   
         res = res ? prs_io_uint8 (s, &rbo->cache_id  ) : False;  
         res = res ? prs_io_uint8 (s, &rbo->pad1      ) : False;  
         res = res ? prs_io_uint8 (s, &rbo->width     ) : False;  
         res = res ? prs_io_uint8 (s, &rbo->height    ) : False;  
         res = res ? prs_io_uint8 (s, &rbo->bpp       ) : False;  
         res = res ? lsb_io_uint16(s, &rbo->bufsize   ) : False;  
         res = res ? lsb_io_uint16(s, &rbo->cache_idx ) : False;  
   
         rbo->data = s->data + s->offset;  
         s->offset += rbo->bufsize;  
   
         return res;  
 }  
   
 BOOL rdp_io_bmpcache_order(STREAM s, RDP_BMPCACHE_ORDER *rbo)  
 {  
         BOOL res = True;  
723    
         res = res ? prs_io_uint8 (s, &rbo->cache_id  ) : False;  
         res = res ? prs_io_uint8 (s, &rbo->pad1      ) : False;  
         res = res ? prs_io_uint8 (s, &rbo->width     ) : False;  
         res = res ? prs_io_uint8 (s, &rbo->height    ) : False;  
         res = res ? prs_io_uint8 (s, &rbo->bpp       ) : False;  
         res = res ? lsb_io_uint16(s, &rbo->bufsize   ) : False;  
         res = res ? lsb_io_uint16(s, &rbo->cache_idx ) : False;  
         res = res ? lsb_io_uint16(s, &rbo->pad2      ) : False;  
         res = res ? lsb_io_uint16(s, &rbo->size      ) : False;  
         res = res ? lsb_io_uint16(s, &rbo->row_size  ) : False;  
         res = res ? lsb_io_uint16(s, &rbo->final_size) : False;  
724    
725          rbo->data = s->data + s->offset;                  if (compress & 0x400)
726          s->offset += rbo->size;                  {
727                            size = bufsize;
728                    }
729                    else
730                    {
731                            in_uint8s(s, 2);        /* pad */
732                            in_uint16_le(s, size);
733                            in_uint8s(s, 4);        /* line_size, final_size */
734                    }
735                    in_uint8p(s, data, size);
736                    bmpdata = (uint8*)xmalloc(width * height * Bpp);
737                    if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
738                    {
739                            ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
740                    }
741                    else
742                    {
743                            DEBUG_RDP5(("Failed to decompress data\n"));
744                    }
745    
746          return res;                  xfree(bmpdata);
747            }
748  }  }
749    
750  BOOL rdp_io_colcache_order(STREAM s, RDP_COLCACHE_ORDER *colours)  /* Process a palette update */
751    void
752    process_palette(STREAM s)
753  {  {
754          COLOURENTRY *entry;          COLOURENTRY *entry;
755            COLOURMAP map;
756            HCOLOURMAP hmap;
757          int i;          int i;
758    
759          prs_io_uint8(s, &colours->cache_id);          in_uint8s(s, 2);        /* pad */
760          lsb_io_uint16(s, &colours->map.ncolours);          in_uint16_le(s, map.ncolours);
761            in_uint8s(s, 2);        /* pad */
762    
763          for (i = 0; i < colours->map.ncolours; i++)          map.colours = (COLOURENTRY*)xmalloc(3 * map.ncolours);
         {  
                 entry = &colours->map.colours[i];  
                 prs_io_uint8(s, &entry->blue);  
                 prs_io_uint8(s, &entry->green);  
                 prs_io_uint8(s, &entry->red);  
                 s->offset++;  
         }  
764    
765          return True;          DEBUG(("PALETTE(c=%d)\n", map.ncolours));
 }  
   
 BOOL rdp_io_fontcache_order(STREAM s, RDP_FONTCACHE_ORDER *font)  
 {  
         RDP_FONT_GLYPH *glyph;  
         BOOL res = True;  
         int i, j, datasize;  
         uint8 in, out;  
766    
767          res = res ? prs_io_uint8(s, &font->font   ) : False;          for (i = 0; i < map.ncolours; i++)
         res = res ? prs_io_uint8(s, &font->nglyphs) : False;  
   
         for (i = 0; i < font->nglyphs; i++)  
768          {          {
769                  glyph = &font->glyphs[i];                  entry = &map.colours[i];
770                  res = res ? lsb_io_uint16(s, &glyph->character) : False;                  in_uint8(s, entry->red);
771                  res = res ? lsb_io_uint16(s, &glyph->unknown  ) : False;                  in_uint8(s, entry->green);
772                  res = res ? lsb_io_uint16(s, &glyph->baseline ) : False;                  in_uint8(s, entry->blue);
773                  res = res ? lsb_io_uint16(s, &glyph->width    ) : False;          }
                 res = res ? lsb_io_uint16(s, &glyph->height   ) : False;  
   
                 datasize = (glyph->height * ((glyph->width + 7) / 8) + 3) & ~3;  
                 res = res ? prs_io_uint8s(s, glyph->data, datasize) : False;  
                 for (j = 0; j < datasize; j++)  
                 {  
                         in = glyph->data[j];  
                         out = 0;  
                         if (in & 1) out |= 128;  
                         if (in & 2) out |= 64;  
                         if (in & 4) out |= 32;  
                         if (in & 8) out |= 16;  
                         if (in & 16) out |= 8;  
                         if (in & 32) out |= 4;  
                         if (in & 64) out |= 2;  
                         if (in & 128) out |= 1;  
                         glyph->data[j] = out;  
                 }  
         }  
   
         return res;  
 }  
   
774    
775  /* CAPABILITIES */          hmap = ui_create_colourmap(&map);
776            ui_set_colourmap(hmap);
777    
778  /* Construct a general capability set */          xfree(map.colours);
 void rdp_make_general_caps(RDP_GENERAL_CAPS *caps)  
 {  
         caps->os_major_type = 1;  
         caps->os_minor_type = 3;  
         caps->ver_protocol = 0x200;  
779  }  }
780    
781  /* Parse general capability set */  /* Process an update PDU */
782  BOOL rdp_io_general_caps(STREAM s, RDP_GENERAL_CAPS *caps)  static void
783    process_update_pdu(STREAM s)
784  {  {
785          uint16 length = RDP_CAPLEN_GENERAL;          uint16 update_type, count;
         uint16 pkt_length = length;  
         BOOL res;  
   
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
         {  
                 ERROR("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;  
 }  
   
 /* Construct a bitmap capability set */  
 void rdp_make_bitmap_caps(RDP_BITMAP_CAPS *caps, int width, int height)  
 {  
         caps->preferred_bpp = 8;  
         caps->receive1bpp = 1;  
         caps->receive4bpp = 1;  
         caps->receive8bpp = 1;  
         caps->width = width;  
         caps->height = height;  
         caps->compression = 1;  
         caps->unknown2 = 1;  
 }  
   
 /* Parse bitmap capability set */  
 BOOL rdp_io_bitmap_caps(STREAM s, RDP_BITMAP_CAPS *caps)  
 {  
         uint16 length = RDP_CAPLEN_BITMAP;  
         uint16 pkt_length = length;  
         BOOL res;  
786    
787          res = lsb_io_uint16(s, &pkt_length);          in_uint16_le(s, update_type);
         if (pkt_length != length)  
         {  
                 ERROR("Unrecognised capabilities size\n");  
                 return False;  
         }  
   
         res = res ? lsb_io_uint16(s, &caps->preferred_bpp) : False;  
         res = res ? lsb_io_uint16(s, &caps->receive1bpp  ) : False;  
         res = res ? lsb_io_uint16(s, &caps->receive4bpp  ) : False;  
         res = res ? lsb_io_uint16(s, &caps->receive8bpp  ) : False;  
         res = res ? lsb_io_uint16(s, &caps->width        ) : False;  
         res = res ? lsb_io_uint16(s, &caps->height       ) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad1         ) : False;  
         res = res ? lsb_io_uint16(s, &caps->allow_resize ) : False;  
         res = res ? lsb_io_uint16(s, &caps->compression  ) : False;  
         res = res ? lsb_io_uint16(s, &caps->unknown1     ) : False;  
         res = res ? lsb_io_uint16(s, &caps->unknown2     ) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad2         ) : False;  
   
         return res;  
 }  
   
 /* Construct an order capability set */  
 void rdp_make_order_caps(RDP_ORDER_CAPS *caps)  
 {  
         caps->xgranularity = 1;  
         caps->ygranularity = 20;  
         caps->max_order_level = 1;  
         caps->num_fonts = 0x147;  
         caps->cap_flags = 0x2A;  
   
 //      caps->cap_flags = ORDER_CAP_NEGOTIATE | ORDER_CAP_NOSUPPORT;  
   
         caps->support[0] = caps->support[1] = caps->support[2]  
                 = caps->support[3] = caps->support[4] = caps->support[5]  
                 = 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;  
 }  
   
 /* Parse order capability set */  
 BOOL rdp_io_order_caps(STREAM s, RDP_ORDER_CAPS *caps)  
 {  
         uint16 length = RDP_CAPLEN_ORDER;  
         uint16 pkt_length = length;  
         BOOL res;  
788    
789          res = lsb_io_uint16(s, &pkt_length);          switch (update_type)
         if (pkt_length != length)  
790          {          {
791                  ERROR("Unrecognised capabilities size\n");                  case RDP_UPDATE_ORDERS:
792                  return False;                          in_uint8s(s, 2);        /* pad */
793          }                          in_uint16_le(s, count);
794                            in_uint8s(s, 2);        /* pad */
795          res = res ? prs_io_uint8s(s,  caps->terminal_desc, 16) : False;                          process_orders(s, count);
796          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;  
 }  
   
 /* Construct a bitmap cache capability set */  
 void rdp_make_bmpcache_caps(RDP_BMPCACHE_CAPS *caps)  
 {  
         caps->caches[0].entries = 0x258;  
         caps->caches[0].max_cell_size = 0x100;  
         caps->caches[1].entries = 0x12c;  
         caps->caches[1].max_cell_size = 0x400;  
         caps->caches[2].entries = 0x106;  
         caps->caches[2].max_cell_size = 0x1000;  
 }  
   
 /* Parse single bitmap cache information structure */  
 BOOL rdp_io_bmpcache_info(STREAM s, RDP_BMPCACHE_INFO *info)  
 {  
         if (!lsb_io_uint16(s, &info->entries      ))  
                 return False;  
797    
798          if (!lsb_io_uint16(s, &info->max_cell_size))                  case RDP_UPDATE_BITMAP:
799                  return False;                          process_bitmap_updates(s);
800                            break;
801    
802          return True;                  case RDP_UPDATE_PALETTE:
803  }                          process_palette(s);
804                            break;
805    
806  /* Parse bitmap cache capability set */                  case RDP_UPDATE_SYNCHRONIZE:
807  BOOL rdp_io_bmpcache_caps(STREAM s, RDP_BMPCACHE_CAPS *caps)                          break;
 {  
         uint16 length = RDP_CAPLEN_BMPCACHE;  
         uint16 pkt_length = length;  
         BOOL res;  
         int i;  
808    
809          res = lsb_io_uint16(s, &pkt_length);                  default:
810          if (pkt_length != length)                          unimpl("update %d\n", update_type);
         {  
                 ERROR("Unrecognised capabilities size\n");  
                 return False;  
811          }          }
812    
         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;  
813  }  }
814    
815  /* Construct a control capability set */  /* Process data PDU */
816  void rdp_make_control_caps(RDP_CONTROL_CAPS *caps)  static void
817    process_data_pdu(STREAM s)
818  {  {
819          caps->control_interest = 2;          uint8 data_pdu_type;
         caps->detach_interest = 2;  
 }  
820    
821  /* Parse control capability set */          in_uint8s(s, 8);        /* shareid, pad, streamid, length */
822  BOOL rdp_io_control_caps(STREAM s, RDP_CONTROL_CAPS *caps)          in_uint8(s, data_pdu_type);
823  {          in_uint8s(s, 3);        /* compress_type, compress_len */
         uint16 length = RDP_CAPLEN_CONTROL;  
         uint16 pkt_length = length;  
         BOOL res;  
824    
825          res = lsb_io_uint16(s, &pkt_length);          switch (data_pdu_type)
         if (pkt_length != length)  
826          {          {
827                  ERROR("Unrecognised capabilities size\n");                  case RDP_DATA_PDU_UPDATE:
828                  return False;                          process_update_pdu(s);
829          }                          break;
   
         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;  
830    
831          return res;                  case RDP_DATA_PDU_POINTER:
832  }                          process_pointer_pdu(s);
833                            break;
834    
835  /* Construct an activation capability set */                  case RDP_DATA_PDU_BELL:
836  void rdp_make_activate_caps(RDP_ACTIVATE_CAPS *caps)                          ui_bell();
837  {                          break;
 }  
838    
839  /* Parse activation capability set */                  case RDP_DATA_PDU_LOGON:
840  BOOL rdp_io_activate_caps(STREAM s, RDP_ACTIVATE_CAPS *caps)                          DEBUG(("Received Logon PDU\n"));
841  {                          /* User logged on */
842          uint16 length = RDP_CAPLEN_ACTIVATE;                          break;
         uint16 pkt_length = length;  
         BOOL res;  
843    
844          res = lsb_io_uint16(s, &pkt_length);                  default:
845          if (pkt_length != length)                          unimpl("data PDU %d\n", data_pdu_type);
         {  
                 ERROR("Unrecognised capabilities size\n");  
                 return False;  
846          }          }
   
         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;  
847  }  }
848    
849  /* Construct a pointer capability set */  /* Process incoming packets */
850  void rdp_make_pointer_caps(RDP_POINTER_CAPS *caps)  void
851    rdp_main_loop(void)
852  {  {
853          caps->colour_pointer = 0;          uint8 type;
854          caps->cache_size = 20;          STREAM s;
 }  
   
 /* Parse pointer capability set */  
 BOOL rdp_io_pointer_caps(STREAM s, RDP_POINTER_CAPS *caps)  
 {  
         uint16 length = RDP_CAPLEN_POINTER;  
         uint16 pkt_length = length;  
         BOOL res;  
855    
856          res = lsb_io_uint16(s, &pkt_length);          while ((s = rdp_recv(&type)) != NULL)
         if (pkt_length != length)  
857          {          {
858                  ERROR("Unrecognised capabilities size\n");                  switch (type)
859                  return False;                  {
860          }                          case RDP_PDU_DEMAND_ACTIVE:
861                                    process_demand_active(s);
862          res = res ? lsb_io_uint16(s, &caps->colour_pointer) : False;                                  break;
         res = res ? lsb_io_uint16(s, &caps->cache_size    ) : False;  
863    
864          return res;                          case RDP_PDU_DEACTIVATE:
865  }                                  break;
866    
867  /* Construct a share capability set */                          case RDP_PDU_DATA:
868  void rdp_make_share_caps(RDP_SHARE_CAPS *caps, uint16 userid)                                  process_data_pdu(s);
869  {                                  break;
 }  
870    
871  /* Parse share capability set */                          case 0:
872  BOOL rdp_io_share_caps(STREAM s, RDP_SHARE_CAPS *caps)                                  break;
 {  
         uint16 length = RDP_CAPLEN_SHARE;  
         uint16 pkt_length = length;  
         BOOL res;  
873    
874          res = lsb_io_uint16(s, &pkt_length);                          default:
875          if (pkt_length != length)                                  unimpl("PDU %d\n", type);
876          {                  }
                 ERROR("Unrecognised capabilities size\n");  
                 return False;  
877          }          }
   
         res = res ? lsb_io_uint16(s, &caps->userid) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad   ) : False;  
   
         return res;  
 }  
   
 /* Construct a colour cache capability set */  
 void rdp_make_colcache_caps(RDP_COLCACHE_CAPS *caps)  
 {  
         caps->cache_size = 6;  
878  }  }
879    
880  /* Parse colour cache capability set */  /* Establish a connection up to the RDP layer */
881  BOOL rdp_io_colcache_caps(STREAM s, RDP_COLCACHE_CAPS *caps)  BOOL
882    rdp_connect(char *server, uint32 flags, char *domain, char *password,
883                char *command, char *directory)
884  {  {
885          uint16 length = RDP_CAPLEN_COLCACHE;          if (!sec_connect(server, username))
         uint16 pkt_length = length;  
         BOOL res;  
   
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
         {  
                 ERROR("Unrecognised capabilities size\n");  
886                  return False;                  return False;
         }  
887    
888          res = res ? lsb_io_uint16(s, &caps->cache_size) : False;          rdp_send_logon_info(flags, domain, username, password, command, directory);
889          res = res ? lsb_io_uint16(s, &caps->pad       ) : False;          return True;
   
         return res;  
890  }  }
891    
892  uint8 canned_caps[] = {  /* Disconnect from the RDP layer */
893  0x01,0x00,0x00,0x00,0x09,0x04,0x00,0x00,0x04,  void
894  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  rdp_disconnect(void)
 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  
 };  
   
 /* Insert canned capabilities */  
 BOOL rdp_io_unknown_caps(STREAM s, void *caps)  
895  {  {
896          uint16 length = 0x58;          sec_disconnect();
         uint16 pkt_length = length;  
         BOOL res;  
   
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
         {  
                 ERROR("Unrecognised capabilities size\n");  
                 return False;  
         }  
   
         res = res ? prs_io_uint8s(s, canned_caps, RDP_CAPLEN_UNKNOWN-4) : False;  
   
         return res;  
897  }  }

Legend:
Removed from v.9  
changed lines
  Added in v.381

  ViewVC Help
Powered by ViewVC 1.1.26