/[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 562 by stargo, Thu Dec 11 17:20:01 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
8     the Free Software Foundation; either version 2 of the License, or     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.     (at your option) any later version.
10      
11     This program is distributed in the hope that it will be useful,     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.     GNU General Public License for more details.
15      
16     You should have received a copy of the GNU General Public License     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software     along with this program; if not, write to the Free Software
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 <time.h>
22    #include "rdesktop.h"
 /* Establish a connection up to the RDP layer */  
 HCONN rdp_connect(char *server, int width, int height)  
 {  
         HCONN conn;  
   
         if ((conn = mcs_connect(server)) == NULL)  
                 return NULL;  
   
         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);  
 }  
23    
24  void rdp_send_input(HCONN conn, uint16 message_type, uint16 device_flags,  extern uint16 g_mcs_userid;
25                                  uint16 param1, uint16 param2)  extern char g_username[16];
26  {  extern BOOL g_bitmap_compression;
27          RDP_INPUT_PDU input;  extern BOOL g_orders;
28    extern BOOL g_encryption;
29    extern BOOL g_desktop_save;
30    extern BOOL g_use_rdp5;
31    extern uint16 g_server_rdp_version;
32    extern int g_server_bpp;
33    
34          rdp_init_data(conn);  uint8 *g_next_packet;
35          rdp_make_input_pdu(&input, message_type, device_flags, param1, param2);  uint32 g_rdp_shareid;
         rdp_io_input_pdu(&conn->out, &input);  
         MARK_END(conn->out);  
         rdp_send_data(conn, RDP_DATA_PDU_INPUT);  
 }  
36    
37  BOOL rdp_recv_pdu(HCONN conn, uint8 *type)  #if WITH_DEBUG
38  {  static uint32 g_packetno;
         RDP_HEADER hdr;  
   
         conn->in.offset = conn->in.rdp_offset;  
   
         if (conn->in.offset >= conn->in.end)  
         {  
                 if (!mcs_recv(conn, False))  
                         return False;  
         }  
   
         if (!rdp_io_header(&conn->in, &hdr))  
                 return False;  
   
         conn->in.rdp_offset += hdr.length;  
         *type = hdr.pdu_type & 0xf;  
   
 #if DUMP  
         fprintf(stderr, "RDP packet (type %x):\n", *type);  
         dump_data(conn->in.data+conn->in.offset, conn->in.rdp_offset-conn->in.offset);  
39  #endif  #endif
40    
41          return True;  /* Receive an RDP packet */
42  }  static STREAM
43    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)  
44  {  {
45          BOOL res = True;          static STREAM rdp_s;
46            uint16 length, pdu_type;
         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)  
 {  
         uint8 bits;  
         int i;  
   
         if (flags & RDP_ORDER_SMALL)  
         {  
                 size--;  
         }  
47    
48          if (flags & RDP_ORDER_TINY)          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))
49          {          {
50                  if (size < 2)                  rdp_s = sec_recv();
51                          return False;                  if (rdp_s == NULL)
52                            return NULL;
53    
54                  size -= 2;                  g_next_packet = rdp_s->p;
55          }          }
56            else
         *present = 0;  
         for (i = 0; i < size; i++)  
57          {          {
58                  prs_io_uint8(s, &bits);                  rdp_s->p = g_next_packet;
                 *present |= bits << (i * 8);  
59          }          }
60    
61          return True;          in_uint16_le(rdp_s, length);
62  }          /* 32k packets are really 8, keepalive fix */
63            if (length == 0x8000)
 BOOL rdp_io_coord(STREAM s, uint16 *coord, BOOL delta)  
 {  
         uint8 change;  
         BOOL res;  
   
         if (delta)  
64          {          {
65                  res = prs_io_uint8(s, &change);                  g_next_packet += 8;
66                  *coord += (char)change;                  *type = 0;
67                    return rdp_s;
68          }          }
69          else          in_uint16_le(rdp_s, pdu_type);
70          {          in_uint8s(rdp_s, 2);    /* userid */
71                  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;  
   
         if (datasize > sizeof(colours->colours))  
                 return False;  
   
         memcpy(colours->colours, s->data + s->offset, datasize);  
         s->offset += datasize;  
         return True;  
 }  
   
 BOOL rdp_io_bounds(STREAM s, BOUNDS *bounds)  
 {  
         uint8 present;  
   
         prs_io_uint8(s, &present);  
   
         if (present & 1)  
                 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;  
 }  
   
 BOOL rdp_io_pen(STREAM s, PEN *pen, uint32 present)  
 {  
         BOOL res = True;  
   
         if (present & 1)  
                 res = res ? prs_io_uint8(s, &pen->style) : False;  
   
         if (present & 2)  
                 res = res ? prs_io_uint8(s, &pen->width) : False;  
   
         if (present & 4)  
                 res = res ? rdp_io_colour(s, &pen->colour) : False;  
   
         return res;  
 }  
72    
73  BOOL rdp_io_brush(STREAM s, BRUSH *brush, uint32 present)  #if WITH_DEBUG
74  {          DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type));
75          BOOL res = True;          hexdump(g_next_packet, length);
76    #endif /*  */
         if (present & 1)  
                 res = res ? prs_io_uint8(s, &brush->xorigin) : False;  
   
         if (present & 2)  
                 res = res ? prs_io_uint8(s, &brush->yorigin) : False;  
   
         if (present & 4)  
                 res = res ? prs_io_uint8(s, &brush->style) : False;  
77    
78          if (present & 8)          g_next_packet += length;
79                  res = res ? prs_io_uint8(s, &brush->pattern[0]) : False;          return rdp_s;
   
         if (present & 16)  
                 res = res ? prs_io_uint8s(s, &brush->pattern[1], 7) : False;  
   
         return res;  
80  }  }
81    
82  /* Construct a confirm/demand active PDU */  /* Initialise an RDP data packet */
83  void rdp_make_active_pdu(RDP_ACTIVE_PDU *pdu, uint32 shareid, uint16 userid,  static STREAM
84                                  int width, int height)  rdp_init_data(int maxlen)
85  {  {
86          memset(pdu, 0, sizeof(*pdu));          STREAM s;
         pdu->shareid = shareid;  
         pdu->userid  = 1002;  
         pdu->source_len = sizeof(RDP_SOURCE);  
         memcpy(pdu->source, RDP_SOURCE, sizeof(RDP_SOURCE));  
87    
88          pdu->caps_len = RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER          s = sec_init(g_encryption ? SEC_ENCRYPT : 0, maxlen + 18);
89                  + RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE + RDP_CAPLEN_ACTIVATE          s_push_layer(s, rdp_hdr, 18);
                 + RDP_CAPLEN_CONTROL + RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE  
                 + RDP_CAPLEN_UNKNOWN;  
         pdu->num_caps = 0xD;  
90    
91          rdp_make_general_caps (&pdu->general_caps );          return s;
         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);  
92  }  }
93    
94  /* Parse a confirm/demand active PDU */  /* Send an RDP data packet */
95  BOOL rdp_io_active_pdu(STREAM s, RDP_ACTIVE_PDU *pdu, int pdutype)  static void
96    rdp_send_data(STREAM s, uint8 data_pdu_type)
97  {  {
         uint16 capset;  
98          uint16 length;          uint16 length;
         BOOL res;  
         int i;  
99    
100          res = lsb_io_uint32(s, &pdu->shareid);          s_pop_layer(s, rdp_hdr);
101            length = s->end - s->p;
         if (pdutype == RDP_PDU_CONFIRM_ACTIVE)  
                 res = res ? lsb_io_uint16(s, &pdu->userid    ) : False;  
   
         res = res ? lsb_io_uint16(s, &pdu->source_len) : False;  
         res = res ? lsb_io_uint16(s, &pdu->caps_len  ) : False;  
   
         if (pdu->source_len > 48)  
         {  
                 ERROR("RDP source descriptor too long\n");  
                 return False;  
         }  
102    
103          res = res ? prs_io_uint8s(s,  pdu->source, pdu->source_len) : False;          out_uint16_le(s, length);
104          res = res ? lsb_io_uint16(s, &pdu->num_caps  ) : False;          out_uint16_le(s, (RDP_PDU_DATA | 0x10));
105          res = res ? lsb_io_uint16(s, &pdu->pad       ) : False;          out_uint16_le(s, (g_mcs_userid + 1001));
106    
107          if (s->marshall)          out_uint32_le(s, g_rdp_shareid);
108          {          out_uint8(s, 0);        /* pad */
109                  capset = RDP_CAPSET_GENERAL;          out_uint8(s, 1);        /* streamid */
110                  res = res ? lsb_io_uint16(s, &capset) : False;          out_uint16_le(s, (length - 14));
111                  res = res ? rdp_io_general_caps(s, &pdu->general_caps) : False;          out_uint8(s, data_pdu_type);
112            out_uint8(s, 0);        /* compress_type */
113                  capset = RDP_CAPSET_BITMAP;          out_uint16(s, 0);       /* compress_len */
114                  res = res ? lsb_io_uint16(s, &capset) : False;  
115                  res = res ? rdp_io_bitmap_caps (s, &pdu->bitmap_caps ) : False;          sec_send(s, g_encryption ? SEC_ENCRYPT : 0);
116    }
117                  capset = RDP_CAPSET_ORDER;  
118                  res = res ? lsb_io_uint16(s, &capset) : False;  /* Output a string in Unicode */
119                  res = res ? rdp_io_order_caps  (s, &pdu->order_caps  ) : False;  void
120    rdp_out_unistr(STREAM s, char *string, int len)
121                  capset = RDP_CAPSET_BMPCACHE;  {
122                  res = res ? lsb_io_uint16(s, &capset) : False;          int i = 0, j = 0;
123                  res = res ? rdp_io_bmpcache_caps(s, &pdu->bmpcache_caps) : False;  
124            len += 2;
125                  capset = RDP_CAPSET_COLCACHE;  
126                  res = res ? lsb_io_uint16(s, &capset) : False;          while (i < len)
127                  res = res ? rdp_io_colcache_caps(s, &pdu->colcache_caps) : False;          {
128                    s->p[i++] = string[j++];
129                  capset = RDP_CAPSET_ACTIVATE;                  s->p[i++] = 0;
130                  res = res ? lsb_io_uint16(s, &capset) : False;          }
131                  res = res ? rdp_io_activate_caps(s, &pdu->activate_caps) : False;  
132            s->p += len;
133                  capset = RDP_CAPSET_CONTROL;  }
134                  res = res ? lsb_io_uint16(s, &capset) : False;  
135                  res = res ? rdp_io_control_caps(s, &pdu->control_caps) : False;  /* Parse a logon info packet */
136    static void
137                  capset = RDP_CAPSET_POINTER;  rdp_send_logon_info(uint32 flags, char *domain, char *user,
138                  res = res ? lsb_io_uint16(s, &capset) : False;                      char *password, char *program, char *directory)
139                  res = res ? rdp_io_pointer_caps(s, &pdu->pointer_caps) : False;  {
140            int len_domain = 2 * strlen(domain);
141                  capset = RDP_CAPSET_SHARE;          int len_user = 2 * strlen(user);
142                  res = res ? lsb_io_uint16(s, &capset) : False;          int len_password = 2 * strlen(password);
143                  res = res ? rdp_io_share_caps  (s, &pdu->share_caps  ) : False;          int len_program = 2 * strlen(program);
144            int len_directory = 2 * strlen(directory);
145                  capset = RDP_CAPSET_UNKNOWN;          int len_ip = 2 * strlen("127.0.0.1");
146                  res = res ? lsb_io_uint16(s, &capset) : False;          int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
147                  res = res ? rdp_io_unknown_caps(s, NULL) : False;          int packetlen = 0;
148            uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
149            STREAM s;
150            time_t t = time(NULL);
151            time_t tzone;
152    
153            if (!g_use_rdp5 || 1 == g_server_rdp_version)
154            {
155                    DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
156    
157                    s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
158                                 + len_program + len_directory + 10);
159    
160                    out_uint32(s, 0);
161                    out_uint32_le(s, flags);
162                    out_uint16_le(s, len_domain);
163                    out_uint16_le(s, len_user);
164                    out_uint16_le(s, len_password);
165                    out_uint16_le(s, len_program);
166                    out_uint16_le(s, len_directory);
167                    rdp_out_unistr(s, domain, len_domain);
168                    rdp_out_unistr(s, user, len_user);
169                    rdp_out_unistr(s, password, len_password);
170                    rdp_out_unistr(s, program, len_program);
171                    rdp_out_unistr(s, directory, len_directory);
172          }          }
173          else          else
174          {          {
175                  for (i = 0; i < pdu->num_caps; i++)                  flags |= RDP_LOGON_BLOB;
176                    DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
177                    packetlen = 4 + /* Unknown uint32 */
178                            4 +     /* flags */
179                            2 +     /* len_domain */
180                            2 +     /* len_user */
181                            (flags & RDP_LOGON_AUTO ? 2 : 0) +      /* len_password */
182                            (flags & RDP_LOGON_BLOB ? 2 : 0) +      /* Length of BLOB */
183                            2 +     /* len_program */
184                            2 +     /* len_directory */
185                            (0 < len_domain ? len_domain : 2) +     /* domain */
186                            len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 +    /* We have no 512 byte BLOB. Perhaps we must? */
187                            (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + /* After the BLOB is a unknown int16. If there is a BLOB, that is. */
188                            (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 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                    {
214          return res;                          out_uint16_le(s, 0);
215  }                  }
216                    out_uint16_le(s, len_program);
217  /* Construct a control PDU */                  out_uint16_le(s, len_directory);
218  void rdp_make_control_pdu(RDP_CONTROL_PDU *pdu, uint16 action)                  if (0 < len_domain)
219  {                          rdp_out_unistr(s, domain, len_domain);
220          pdu->action = action;                  else
221          pdu->userid = 0;                          out_uint16_le(s, 0);
222          pdu->controlid = 0;                  rdp_out_unistr(s, user, len_user);
223  }                  if (flags & RDP_LOGON_AUTO)
224                    {
225  /* Parse a control PDU */                          rdp_out_unistr(s, password, len_password);
226  BOOL rdp_io_control_pdu(STREAM s, RDP_CONTROL_PDU *pdu)                  }
227  {                  if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
228          BOOL res = True;                  {
229                            out_uint16_le(s, 0);
230          res = res ? lsb_io_uint16(s, &pdu->action   ) : False;                  }
231          res = res ? lsb_io_uint16(s, &pdu->userid   ) : False;                  if (0 < len_program)
232          res = res ? lsb_io_uint32(s, &pdu->controlid) : False;                  {
233                            rdp_out_unistr(s, program, len_program);
234    
235          return res;                  }
236  }                  else
237                    {
238                            out_uint16_le(s, 0);
239                    }
240                    if (0 < len_directory)
241                    {
242                            rdp_out_unistr(s, directory, len_directory);
243                    }
244                    else
245                    {
246                            out_uint16_le(s, 0);
247                    }
248                    out_uint16_le(s, 2);
249                    out_uint16_le(s, len_ip + 2);   /* Length of client ip */
250                    rdp_out_unistr(s, "127.0.0.1", len_ip);
251                    out_uint16_le(s, len_dll + 2);
252                    rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
253    
254  /* Construct a synchronisation PDU */                  tzone = (mktime(localtime(&t)) - mktime(gmtime(&t))) / 60;
255  void rdp_make_synchronise_pdu(RDP_SYNCHRONISE_PDU *pdu, uint16 userid)                  out_uint16_le(s, tzone);
256  {                  out_uint16_le(s, 0x0000);
         pdu->type = 1;  
         pdu->userid = userid;  
 }  
257    
258  /* Parse a synchronisation PDU */                  rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
259  BOOL rdp_io_synchronise_pdu(STREAM s, RDP_SYNCHRONISE_PDU *pdu)                  out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
 {  
         BOOL res = True;  
260    
         res = res ? lsb_io_uint16(s, &pdu->type  ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->userid) : False;  
261    
262          return res;                  out_uint32_le(s, 0x0a0000);
263  }                  out_uint32_le(s, 0x050000);
264                    out_uint32_le(s, 3);
265                    out_uint32_le(s, 0);
266                    out_uint32_le(s, 0);
267    
268  /* Parse a single input event */                  rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
269  BOOL rdp_io_input_event(STREAM s, RDP_INPUT_EVENT *evt)                  out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
 {  
         BOOL res = True;  
270    
271          res = res ? lsb_io_uint32(s, &evt->event_time)   : False;                  out_uint32_le(s, 0x30000);
272          res = res ? lsb_io_uint16(s, &evt->message_type) : False;                  out_uint32_le(s, 0x050000);
273          res = res ? lsb_io_uint16(s, &evt->device_flags) : False;                  out_uint32_le(s, 2);
274                    out_uint32(s, 0);
275                    out_uint32_le(s, 0xffffffc4);
276                    out_uint32_le(s, 0xfffffffe);
277                    out_uint32_le(s, 0x0f);
278                    out_uint32(s, 0);
279    
         if (!res)  
                 return False;  
280    
         switch (evt->message_type)  
         {  
         case RDP_INPUT_CODEPOINT:  
         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;  
281          }          }
282            s_mark_end(s);
283          return res;          sec_send(s, sec_flags);
 }  
   
 /* Construct an input PDU */  
 void rdp_make_input_pdu(RDP_INPUT_PDU *pdu, uint16 message_type,  
                         uint16 device_flags, uint16 param1, uint16 param2)  
 {  
         uint32 now = time(NULL);  
   
         pdu->num_events = 1;  
         pdu->pad = 0;  
   
         pdu->event[0].event_time = now;  
         pdu->event[0].message_type = message_type;  
         pdu->event[0].device_flags = device_flags;  
         pdu->event[0].param1 = param1;  
         pdu->event[0].param2 = param2;  
284  }  }
285    
286  /* Parse an input PDU */  /* Send a control PDU */
287  BOOL rdp_io_input_pdu(STREAM s, RDP_INPUT_PDU *pdu)  static void
288    rdp_send_control(uint16 action)
289  {  {
290          BOOL res = True;          STREAM s;
         int i;  
291    
292          res = res ? lsb_io_uint16(s, &pdu->num_events) : False;          s = rdp_init_data(8);
         res = res ? lsb_io_uint16(s, &pdu->pad       ) : False;  
293    
294          if (pdu->num_events > RDP_MAX_EVENTS)          out_uint16_le(s, action);
295          {          out_uint16(s, 0);       /* userid */
296                  ERROR("Too many events in one PDU\n");          out_uint32(s, 0);       /* control id */
                 return False;  
         }  
297    
298          for (i = 0; i < pdu->num_events; i++)          s_mark_end(s);
299          {          rdp_send_data(s, RDP_DATA_PDU_CONTROL);
                 res = res ? rdp_io_input_event(s, &pdu->event[i]) : False;  
         }  
   
         return res;  
300  }  }
301    
302  /* Construct a font information PDU */  /* Send a synchronisation PDU */
303  void rdp_make_font_pdu(RDP_FONT_PDU *pdu, uint16 seqno)  static void
304    rdp_send_synchronise(void)
305  {  {
306          pdu->num_fonts = 0;          STREAM s;
         pdu->unknown1 = 0x3e;  
         pdu->unknown2 = seqno;  
         pdu->entry_size = RDP_FONT_INFO_SIZE;  
 }  
307    
308  /* Parse a font information structure */          s = rdp_init_data(4);
 BOOL rdp_io_font_info(STREAM s, RDP_FONT_INFO *font)  
 {  
         BOOL res = True;  
309    
310          res = res ? prs_io_uint8s(s,  font->name, 32 ) : False;          out_uint16_le(s, 1);    /* type */
311          res = res ? lsb_io_uint16(s, &font->flags    ) : False;          out_uint16_le(s, 1002);
         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;  
312    
313          return res;          s_mark_end(s);
314            rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);
315  }  }
316    
317  /* Parse a font information PDU */  /* Send a single input event */
318  BOOL rdp_io_font_pdu(STREAM s, RDP_FONT_PDU *pdu)  void
319    rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
320  {  {
321          BOOL res = True;          STREAM s;
         int i;  
322    
323          res = res ? lsb_io_uint16(s, &pdu->num_fonts ) : False;          s = rdp_init_data(16);
         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;  
324    
325          if (pdu->num_fonts > RDP_MAX_FONTS)          out_uint16_le(s, 1);    /* number of events */
326          {          out_uint16(s, 0);       /* pad */
                 ERROR("Too many fonts in one PDU\n");  
                 return False;  
         }  
327    
328          for (i = 0; i < pdu->num_fonts; i++)          out_uint32_le(s, time);
329          {          out_uint16_le(s, message_type);
330                  res = res ? rdp_io_font_info(s, &pdu->font[i]) : False;          out_uint16_le(s, device_flags);
331          }          out_uint16_le(s, param1);
332            out_uint16_le(s, param2);
333    
334          return res;          s_mark_end(s);
335            rdp_send_data(s, RDP_DATA_PDU_INPUT);
336  }  }
337    
338  /* Parse a pointer PDU */  /* Send an (empty) font information PDU */
339  BOOL rdp_io_pointer_pdu(STREAM s, RDP_POINTER_PDU *ptr)  static void
340    rdp_send_fonts(uint16 seq)
341  {  {
342          BOOL res = True;          STREAM s;
343    
344          res = res ? lsb_io_uint16(s, &ptr->message) : False;          s = rdp_init_data(8);
         res = res ? lsb_io_uint16(s, &ptr->pad    ) : False;  
345    
346          switch (ptr->message)          out_uint16(s, 0);       /* number of fonts */
347          {          out_uint16_le(s, 0x3e); /* unknown */
348                  case RDP_POINTER_MOVE:          out_uint16_le(s, seq);  /* unknown */
349                          res = res ? lsb_io_uint16(s, &ptr->x      ) : False;          out_uint16_le(s, 0x32); /* entry size */
                         res = res ? lsb_io_uint16(s, &ptr->y      ) : False;  
                         break;  
         }  
350    
351          return res;          s_mark_end(s);
352            rdp_send_data(s, RDP_DATA_PDU_FONT2);
353  }  }
354    
355  /* Parse an update PDU */  /* Output general capability set */
356  BOOL rdp_io_update_pdu(STREAM s, RDP_UPDATE_PDU *pdu)  static void
357  {  rdp_out_general_caps(STREAM s)
         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)  
358  {  {
359          if (present & 0x01)          out_uint16_le(s, RDP_CAPSET_GENERAL);
360                  rdp_io_coord(s, &os->x, delta);          out_uint16_le(s, RDP_CAPLEN_GENERAL);
   
         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);  
361    
362          if (present & 0x10)          out_uint16_le(s, 1);    /* OS major type */
363                  prs_io_uint8(s, &os->opcode);          out_uint16_le(s, 3);    /* OS minor type */
364            out_uint16_le(s, 0x200);        /* Protocol version */
365          return PRS_ERROR(s);          out_uint16(s, 0);       /* Pad */
366            out_uint16(s, 0);       /* Compression types */
367            out_uint16_le(s, g_use_rdp5 ? 0x40d : 0);
368            /* Pad, according to T.128. 0x40d seems to
369               trigger
370               the server to start sending RDP5 packets.
371               However, the value is 0x1d04 with W2KTSK and
372               NT4MS. Hmm.. Anyway, thankyou, Microsoft,
373               for sending such information in a padding
374               field.. */
375            out_uint16(s, 0);       /* Update capability */
376            out_uint16(s, 0);       /* Remote unshare capability */
377            out_uint16(s, 0);       /* Compression level */
378            out_uint16(s, 0);       /* Pad */
379  }  }
380    
381  /* Parse an pattern blt order */  /* Output bitmap capability set */
382  BOOL rdp_io_patblt_order(STREAM s, PATBLT_ORDER *os, uint32 present, BOOL delta)  static void
383    rdp_out_bitmap_caps(STREAM s)
384  {  {
385          if (present & 0x0001)          out_uint16_le(s, RDP_CAPSET_BITMAP);
386                  rdp_io_coord(s, &os->x, delta);          out_uint16_le(s, RDP_CAPLEN_BITMAP);
   
         if (present & 0x0002)  
                 rdp_io_coord(s, &os->y, delta);  
   
         if (present & 0x0004)  
                 rdp_io_coord(s, &os->cx, delta);  
387    
388          if (present & 0x0008)          out_uint16_le(s, 8);    /* Preferred BPP */
389                  rdp_io_coord(s, &os->cy, delta);          out_uint16_le(s, 1);    /* Receive 1 BPP */
390            out_uint16_le(s, 1);    /* Receive 4 BPP */
391          if (present & 0x0010)          out_uint16_le(s, 1);    /* Receive 8 BPP */
392                  prs_io_uint8(s, &os->opcode);          out_uint16_le(s, 800);  /* Desktop width */
393            out_uint16_le(s, 600);  /* Desktop height */
394          if (present & 0x0020)          out_uint16(s, 0);       /* Pad */
395                  rdp_io_colour(s, &os->bgcolour);          out_uint16(s, 0);       /* Allow resize */
396            out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
397          if (present & 0x0040)          out_uint16(s, 0);       /* Unknown */
398                  rdp_io_colour(s, &os->fgcolour);          out_uint16_le(s, 1);    /* Unknown */
399            out_uint16(s, 0);       /* Pad */
         rdp_io_brush(s, &os->brush, present >> 7);  
   
         return PRS_ERROR(s);  
400  }  }
401    
402  /* Parse an screen blt order */  /* Output order capability set */
403  BOOL rdp_io_screenblt_order(STREAM s, SCREENBLT_ORDER *os, uint32 present, BOOL delta)  static void
404    rdp_out_order_caps(STREAM s)
405  {  {
406          if (present & 0x0001)          uint8 order_caps[32];
                 rdp_io_coord(s, &os->x, delta);  
   
         if (present & 0x0002)  
                 rdp_io_coord(s, &os->y, delta);  
407    
         if (present & 0x0004)  
                 rdp_io_coord(s, &os->cx, delta);  
408    
409          if (present & 0x0008)          memset(order_caps, 0, 32);
410                  rdp_io_coord(s, &os->cy, delta);          order_caps[0] = 1;      /* dest blt */
411            order_caps[1] = 1;      /* pat blt */
412            order_caps[2] = 1;      /* screen blt */
413            order_caps[3] = 1;      /* required for memblt? */
414            order_caps[8] = 1;      /* line */
415            order_caps[9] = 1;      /* line */
416            order_caps[10] = 1;     /* rect */
417            order_caps[11] = (g_desktop_save == False ? 0 : 1);     /* desksave */
418            order_caps[13] = 1;     /* memblt */
419            order_caps[14] = 1;     /* triblt */
420            order_caps[22] = 1;     /* polyline */
421            order_caps[27] = 1;     /* text2 */
422            out_uint16_le(s, RDP_CAPSET_ORDER);
423            out_uint16_le(s, RDP_CAPLEN_ORDER);
424    
425          if (present & 0x0010)          out_uint8s(s, 20);      /* Terminal desc, pad */
426                  prs_io_uint8(s, &os->opcode);          out_uint16_le(s, 1);    /* Cache X granularity */
427            out_uint16_le(s, 20);   /* Cache Y granularity */
428          if (present & 0x0020)          out_uint16(s, 0);       /* Pad */
429                  rdp_io_coord(s, &os->srcx, delta);          out_uint16_le(s, 1);    /* Max order level */
430            out_uint16_le(s, 0x147);        /* Number of fonts */
431          if (present & 0x0040)          out_uint16_le(s, 0x2a); /* Capability flags */
432                  rdp_io_coord(s, &os->srcy, delta);          out_uint8p(s, order_caps, 32);  /* Orders supported */
433            out_uint16_le(s, 0x6a1);        /* Text capability flags */
434          return PRS_ERROR(s);          out_uint8s(s, 6);       /* Pad */
435            out_uint32_le(s, g_desktop_save == False ? 0 : 0x38400);        /* Desktop cache size */
436            out_uint32(s, 0);       /* Unknown */
437            out_uint32_le(s, 0x4e4);        /* Unknown */
438  }  }
439    
440  /* Parse a line order */  /* Output bitmap cache capability set */
441  BOOL rdp_io_line_order(STREAM s, LINE_ORDER *os, uint32 present, BOOL delta)  static void
442    rdp_out_bmpcache_caps(STREAM s)
443  {  {
444          if (present & 0x0001)          int Bpp;
445                  lsb_io_uint16(s, &os->mixmode);          out_uint16_le(s, RDP_CAPSET_BMPCACHE);
446            out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
         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);  
447    
448          if (present & 0x0020)          Bpp = (g_server_bpp + 7) / 8;
449                  rdp_io_colour(s, &os->bgcolour);          out_uint8s(s, 24);      /* unused */
450            out_uint16_le(s, 0x258);        /* entries */
451          if (present & 0x0040)          out_uint16_le(s, 0x100 * Bpp);  /* max cell size */
452                  prs_io_uint8(s, &os->opcode);          out_uint16_le(s, 0x12c);        /* entries */
453            out_uint16_le(s, 0x400 * Bpp);  /* max cell size */
454          rdp_io_pen(s, &os->pen, present >> 7);          out_uint16_le(s, 0x106);        /* entries */
455            out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
         return PRS_ERROR(s);  
456  }  }
457    
458  /* Parse an opaque rectangle order */  /* Output control capability set */
459  BOOL rdp_io_rect_order(STREAM s, RECT_ORDER *os, uint32 present, BOOL delta)  static void
460    rdp_out_control_caps(STREAM s)
461  {  {
462          if (present & 0x01)          out_uint16_le(s, RDP_CAPSET_CONTROL);
463                  rdp_io_coord(s, &os->x, delta);          out_uint16_le(s, RDP_CAPLEN_CONTROL);
   
         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);  
464    
465          if (present & 0x10)          out_uint16(s, 0);       /* Control capabilities */
466                  prs_io_uint8(s, &os->colour);          out_uint16(s, 0);       /* Remote detach */
467            out_uint16_le(s, 2);    /* Control interest */
468          return PRS_ERROR(s);          out_uint16_le(s, 2);    /* Detach interest */
469  }  }
470    
471  /* Parse a desktop save order */  /* Output activation capability set */
472  BOOL rdp_io_desksave_order(STREAM s, DESKSAVE_ORDER *os, uint32 present, BOOL delta)  static void
473    rdp_out_activate_caps(STREAM s)
474  {  {
475          if (present & 0x01)          out_uint16_le(s, RDP_CAPSET_ACTIVATE);
476                  lsb_io_uint32(s, &os->offset);          out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
   
         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);  
477    
478          if (present & 0x10)          out_uint16(s, 0);       /* Help key */
479                  rdp_io_coord(s, &os->bottom, delta);          out_uint16(s, 0);       /* Help index key */
480            out_uint16(s, 0);       /* Extended help key */
481          if (present & 0x20)          out_uint16(s, 0);       /* Window activate */
                 prs_io_uint8(s, &os->action);  
   
         return PRS_ERROR(s);  
482  }  }
483    
484  /* Parse a memory blt order */  /* Output pointer capability set */
485  BOOL rdp_io_memblt_order(STREAM s, MEMBLT_ORDER *os, uint32 present, BOOL delta)  static void
486    rdp_out_pointer_caps(STREAM s)
487  {  {
488          if (present & 0x0001)          out_uint16_le(s, RDP_CAPSET_POINTER);
489          {          out_uint16_le(s, RDP_CAPLEN_POINTER);
                 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);  
490    
491          if (present & 0x0040)          out_uint16(s, 0);       /* Colour pointer */
492                  rdp_io_coord(s, &os->srcx, delta);          out_uint16_le(s, 20);   /* Cache size */
   
         if (present & 0x0080)  
                 rdp_io_coord(s, &os->srcy, delta);  
   
         if (present & 0x0100)  
                 lsb_io_uint16(s, &os->cache_idx);  
   
         return PRS_ERROR(s);  
493  }  }
494    
495  /* Parse a 3-way blt order */  /* Output share capability set */
496  BOOL rdp_io_triblt_order(STREAM s, TRIBLT_ORDER *os, uint32 present, BOOL delta)  static void
497    rdp_out_share_caps(STREAM s)
498  {  {
499          if (present & 0x000001)          out_uint16_le(s, RDP_CAPSET_SHARE);
500          {          out_uint16_le(s, RDP_CAPLEN_SHARE);
                 prs_io_uint8(s, &os->cache_id);  
                 prs_io_uint8(s, &os->colour_table);  
         }  
   
         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);  
501    
502          if (present & 0x000200)          out_uint16(s, 0);       /* userid */
503                  rdp_io_colour(s, &os->fgcolour);          out_uint16(s, 0);       /* pad */
   
         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);  
504  }  }
505    
506  /* Parse a text order */  /* Output colour cache capability set */
507  BOOL rdp_io_text2_order(STREAM s, TEXT2_ORDER *os, uint32 present, BOOL delta)  static void
508    rdp_out_colcache_caps(STREAM s)
509  {  {
510          if (present & 0x000001)          out_uint16_le(s, RDP_CAPSET_COLCACHE);
511                  prs_io_uint8(s, &os->font);          out_uint16_le(s, RDP_CAPLEN_COLCACHE);
   
         if (present & 0x000002)  
                 prs_io_uint8(s, &os->flags);  
   
         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);  
512    
513          if (present & 0x000400)          out_uint16_le(s, 6);    /* cache size */
514                  lsb_io_uint16(s, &os->boxleft);          out_uint16(s, 0);       /* pad */
   
         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);  
   
         if (present & 0x100000)  
                 lsb_io_uint16(s, &os->y);  
   
         if (present & 0x200000)  
         {  
                 prs_io_uint8(s, &os->length);  
                 prs_io_uint8s(s, os->text, os->length);  
         }  
   
         return PRS_ERROR(s);  
515  }  }
516    
517    static uint8 canned_caps[] = {
518            0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,
519            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
520            0x00, 0x00, 0x00, 0x00, 0x00,
521            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
522            0x00, 0x00, 0x00, 0x00, 0x00,
523            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
524            0x00, 0x00, 0x00, 0x00, 0x00,
525            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
526            0x00, 0x00, 0x00, 0x00, 0x00,
527            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
528            0x0C, 0x00, 0x08, 0x00, 0x01,
529            0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
530            0x10, 0x00, 0x34, 0x00, 0xFE,
531            0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,
532            0xFE, 0x00, 0x08, 0x00, 0xFE,
533            0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,
534            0xFE, 0x00, 0x80, 0x00, 0xFE,
535            0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
536            0x02, 0x00, 0x00, 0x00
537    };
538    
539  /* SECONDARY ORDERS */  /* Output unknown capability sets (number 13, 12, 14 and 16) */
540    static void
541  BOOL rdp_io_secondary_order(STREAM s, RDP_SECONDARY_ORDER *rso)  rdp_out_unknown_caps(STREAM s)
542    {
543            out_uint16_le(s, RDP_CAPSET_UNKNOWN);
544            out_uint16_le(s, 0x58);
545    
546            out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);
547    }
548    
549    #define RDP5_FLAG 0x0030
550    /* Send a confirm active PDU */
551    static void
552    rdp_send_confirm_active(void)
553    {
554            STREAM s;
555            uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
556            uint16 caplen =
557                    RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
558                    RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
559                    RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
560                    RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;
561    
562            s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
563    
564            out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
565            out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10));      /* Version 1 */
566            out_uint16_le(s, (g_mcs_userid + 1001));
567    
568            out_uint32_le(s, g_rdp_shareid);
569            out_uint16_le(s, 0x3ea);        /* userid */
570            out_uint16_le(s, sizeof(RDP_SOURCE));
571            out_uint16_le(s, caplen);
572    
573            out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
574            out_uint16_le(s, 0xd);  /* num_caps */
575            out_uint8s(s, 2);       /* pad */
576    
577            rdp_out_general_caps(s);
578            rdp_out_bitmap_caps(s);
579            rdp_out_order_caps(s);
580            rdp_out_bmpcache_caps(s);
581            rdp_out_colcache_caps(s);
582            rdp_out_activate_caps(s);
583            rdp_out_control_caps(s);
584            rdp_out_pointer_caps(s);
585            rdp_out_share_caps(s);
586            rdp_out_unknown_caps(s);
587    
588            s_mark_end(s);
589            sec_send(s, sec_flags);
590    }
591    
592    /* Respond to a demand active PDU */
593    static void
594    process_demand_active(STREAM s)
595    {
596            uint8 type;
597    
598            in_uint32_le(s, g_rdp_shareid);
599    
600            DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid));
601    
602            rdp_send_confirm_active();
603            rdp_send_synchronise();
604            rdp_send_control(RDP_CTL_COOPERATE);
605            rdp_send_control(RDP_CTL_REQUEST_CONTROL);
606            rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
607            rdp_recv(&type);        /* RDP_CTL_COOPERATE */
608            rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
609            rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);
610            rdp_send_fonts(1);
611            rdp_send_fonts(2);
612            rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 */
613            reset_order_state();
614    }
615    
616    /* Process a colour pointer PDU */
617    void
618    process_colour_pointer_pdu(STREAM s)
619    {
620            uint16 x, y, width, height, cache_idx, masklen, datalen;
621            uint8 *mask, *data;
622            HCURSOR cursor;
623    
624            in_uint16_le(s, cache_idx);
625            in_uint16_le(s, x);
626            in_uint16_le(s, y);
627            in_uint16_le(s, width);
628            in_uint16_le(s, height);
629            in_uint16_le(s, masklen);
630            in_uint16_le(s, datalen);
631            in_uint8p(s, data, datalen);
632            in_uint8p(s, mask, masklen);
633            cursor = ui_create_cursor(x, y, width, height, mask, data);
634            ui_set_cursor(cursor);
635            cache_put_cursor(cache_idx, cursor);
636    }
637    
638    /* Process a cached pointer PDU */
639    void
640    process_cached_pointer_pdu(STREAM s)
641    {
642            uint16 cache_idx;
643    
644            in_uint16_le(s, cache_idx);
645            ui_set_cursor(cache_get_cursor(cache_idx));
646    }
647    
648    /* Process a system pointer PDU */
649    void
650    process_system_pointer_pdu(STREAM s)
651  {  {
652          BOOL res = True;          uint16 system_pointer_type;
653    
654          res = res ? lsb_io_uint16(s, &rso->length) : False;          in_uint16(s, system_pointer_type);
655          res = res ? lsb_io_uint16(s, &rso->flags ) : False;          switch (system_pointer_type)
656          res = res ? prs_io_uint8 (s, &rso->type  ) : False;          {
657                    case RDP_NULL_POINTER:
658                            ui_set_null_cursor();
659                            break;
660    
661          return res;                  default:
662                            unimpl("System pointer message 0x%x\n", system_pointer_type);
663            }
664  }  }
665    
666  BOOL rdp_io_raw_bmpcache_order(STREAM s, RDP_RAW_BMPCACHE_ORDER *rbo)  /* Process a pointer PDU */
667    static void
668    process_pointer_pdu(STREAM s)
669  {  {
670          BOOL res = True;          uint16 message_type;
671            uint16 x, y;
         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;  
672    
673          rbo->data = s->data + s->offset;          in_uint16_le(s, message_type);
674          s->offset += rbo->bufsize;          in_uint8s(s, 2);        /* pad */
675    
676          return res;          switch (message_type)
677  }          {
678                    case RDP_POINTER_MOVE:
679                            in_uint16_le(s, x);
680                            in_uint16_le(s, y);
681                            if (s_check(s))
682                                    ui_move_pointer(x, y);
683                            break;
684    
685  BOOL rdp_io_bmpcache_order(STREAM s, RDP_BMPCACHE_ORDER *rbo)                  case RDP_POINTER_COLOR:
686  {                          process_colour_pointer_pdu(s);
687          BOOL res = True;                          break;
688    
689          res = res ? prs_io_uint8 (s, &rbo->cache_id  ) : False;                  case RDP_POINTER_CACHED:
690          res = res ? prs_io_uint8 (s, &rbo->pad1      ) : False;                          process_cached_pointer_pdu(s);
691          res = res ? prs_io_uint8 (s, &rbo->width     ) : False;                          break;
         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;  
692    
693          rbo->data = s->data + s->offset;                  case RDP_POINTER_SYSTEM:
694          s->offset += rbo->size;                          process_system_pointer_pdu(s);
695                            break;
696    
697          return res;                  default:
698                            unimpl("Pointer message 0x%x\n", message_type);
699            }
700  }  }
701    
702  BOOL rdp_io_colcache_order(STREAM s, RDP_COLCACHE_ORDER *colours)  /* Process bitmap updates */
703    void
704    process_bitmap_updates(STREAM s)
705  {  {
706          COLOURENTRY *entry;          uint16 num_updates;
707            uint16 left, top, right, bottom, width, height;
708            uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
709            uint8 *data, *bmpdata;
710          int i;          int i;
711    
712          prs_io_uint8(s, &colours->cache_id);          in_uint16_le(s, num_updates);
         lsb_io_uint16(s, &colours->map.ncolours);  
713    
714          for (i = 0; i < colours->map.ncolours; i++)          for (i = 0; i < num_updates; i++)
715          {          {
716                  entry = &colours->map.colours[i];                  in_uint16_le(s, left);
717                  prs_io_uint8(s, &entry->blue);                  in_uint16_le(s, top);
718                  prs_io_uint8(s, &entry->green);                  in_uint16_le(s, right);
719                  prs_io_uint8(s, &entry->red);                  in_uint16_le(s, bottom);
720                  s->offset++;                  in_uint16_le(s, width);
721          }                  in_uint16_le(s, height);
722                    in_uint16_le(s, bpp);
723                    Bpp = (bpp + 7) / 8;
724                    in_uint16_le(s, compress);
725                    in_uint16_le(s, bufsize);
726    
727          return True;                  cx = right - left + 1;
728  }                  cy = bottom - top + 1;
   
 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;  
729    
730          res = res ? prs_io_uint8(s, &font->font   ) : False;                  DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
731          res = res ? prs_io_uint8(s, &font->nglyphs) : False;                         left, top, right, bottom, width, height, Bpp, compress));
732    
733          for (i = 0; i < font->nglyphs; i++)                  /* Server may limit bpp - this is how we find out */
734          {                  if (g_server_bpp != bpp)
                 glyph = &font->glyphs[i];  
                 res = res ? lsb_io_uint16(s, &glyph->character) : False;  
                 res = res ? lsb_io_uint16(s, &glyph->unknown  ) : False;  
                 res = res ? lsb_io_uint16(s, &glyph->baseline ) : False;  
                 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++)  
735                  {                  {
736                          in = glyph->data[j];                          warning("Server limited colour depth to %d bits\n", bpp);
737                          out = 0;                          g_server_bpp = bpp;
                         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;  
738                  }                  }
         }  
739    
740          return res;                  if (!compress)
741  }                  {
742                            int y;
743                            bmpdata = (uint8 *) xmalloc(width * height * Bpp);
744                            for (y = 0; y < height; y++)
745                            {
746                                    in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
747                                              width * Bpp);
748                            }
749                            ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
750                            xfree(bmpdata);
751                            continue;
752                    }
753    
754    
755  /* CAPABILITIES */                  if (compress & 0x400)
756                    {
757                            size = bufsize;
758                    }
759                    else
760                    {
761                            in_uint8s(s, 2);        /* pad */
762                            in_uint16_le(s, size);
763                            in_uint8s(s, 4);        /* line_size, final_size */
764                    }
765                    in_uint8p(s, data, size);
766                    bmpdata = (uint8 *) xmalloc(width * height * Bpp);
767                    if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
768                    {
769                            ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
770                    }
771                    else
772                    {
773                            DEBUG_RDP5(("Failed to decompress data\n"));
774                    }
775    
776  /* Construct a general capability set */                  xfree(bmpdata);
777  void rdp_make_general_caps(RDP_GENERAL_CAPS *caps)          }
 {  
         caps->os_major_type = 1;  
         caps->os_minor_type = 3;  
         caps->ver_protocol = 0x200;  
778  }  }
779    
780  /* Parse general capability set */  /* Process a palette update */
781  BOOL rdp_io_general_caps(STREAM s, RDP_GENERAL_CAPS *caps)  void
782    process_palette(STREAM s)
783  {  {
784          uint16 length = RDP_CAPLEN_GENERAL;          COLOURENTRY *entry;
785          uint16 pkt_length = length;          COLOURMAP map;
786          BOOL res;          HCOLOURMAP hmap;
787            int i;
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
         {  
                 ERROR("Unrecognised capabilities size\n");  
                 return False;  
         }  
788    
789          res = res ? lsb_io_uint16(s, &caps->os_major_type ) : False;          in_uint8s(s, 2);        /* pad */
790          res = res ? lsb_io_uint16(s, &caps->os_minor_type ) : False;          in_uint16_le(s, map.ncolours);
791          res = res ? lsb_io_uint16(s, &caps->ver_protocol  ) : False;          in_uint8s(s, 2);        /* pad */
         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;  
792    
793          res = lsb_io_uint16(s, &pkt_length);          map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
         if (pkt_length != length)  
         {  
                 ERROR("Unrecognised capabilities size\n");  
                 return False;  
         }  
794    
795          res = res ? lsb_io_uint16(s, &caps->preferred_bpp) : False;          DEBUG(("PALETTE(c=%d)\n", map.ncolours));
         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;  
796    
797          res = lsb_io_uint16(s, &pkt_length);          for (i = 0; i < map.ncolours; i++)
         if (pkt_length != length)  
798          {          {
799                  ERROR("Unrecognised capabilities size\n");                  entry = &map.colours[i];
800                  return False;                  in_uint8(s, entry->red);
801                    in_uint8(s, entry->green);
802                    in_uint8(s, entry->blue);
803          }          }
804    
805          res = res ? prs_io_uint8s(s,  caps->terminal_desc, 16) : False;          hmap = ui_create_colourmap(&map);
806          res = res ? lsb_io_uint32(s, &caps->pad1             ) : False;          ui_set_colourmap(hmap);
         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;  
 }  
807    
808  /* Parse single bitmap cache information structure */          xfree(map.colours);
 BOOL rdp_io_bmpcache_info(STREAM s, RDP_BMPCACHE_INFO *info)  
 {  
         if (!lsb_io_uint16(s, &info->entries      ))  
                 return False;  
   
         if (!lsb_io_uint16(s, &info->max_cell_size))  
                 return False;  
   
         return True;  
809  }  }
810    
811  /* Parse bitmap cache capability set */  /* Process an update PDU */
812  BOOL rdp_io_bmpcache_caps(STREAM s, RDP_BMPCACHE_CAPS *caps)  static void
813    process_update_pdu(STREAM s)
814  {  {
815          uint16 length = RDP_CAPLEN_BMPCACHE;          uint16 update_type, count;
         uint16 pkt_length = length;  
         BOOL res;  
         int i;  
   
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
         {  
                 ERROR("Unrecognised capabilities size\n");  
                 return False;  
         }  
816    
817          for (i = 0; i < 6; i++)          in_uint16_le(s, update_type);
                 res = res ? lsb_io_uint32(s, &caps->unused[i]) : False;  
818    
819          for (i = 0; i < 3; i++)          switch (update_type)
820                  res = res ? rdp_io_bmpcache_info(s, &caps->caches[i]) : False;          {
821                    case RDP_UPDATE_ORDERS:
822                            in_uint8s(s, 2);        /* pad */
823                            in_uint16_le(s, count);
824                            in_uint8s(s, 2);        /* pad */
825                            process_orders(s, count);
826                            break;
827    
828          return res;                  case RDP_UPDATE_BITMAP:
829  }                          process_bitmap_updates(s);
830                            break;
831    
832  /* Construct a control capability set */                  case RDP_UPDATE_PALETTE:
833  void rdp_make_control_caps(RDP_CONTROL_CAPS *caps)                          process_palette(s);
834  {                          break;
         caps->control_interest = 2;  
         caps->detach_interest = 2;  
 }  
835    
836  /* Parse control capability set */                  case RDP_UPDATE_SYNCHRONIZE:
837  BOOL rdp_io_control_caps(STREAM s, RDP_CONTROL_CAPS *caps)                          break;
 {  
         uint16 length = RDP_CAPLEN_CONTROL;  
         uint16 pkt_length = length;  
         BOOL res;  
838    
839          res = lsb_io_uint16(s, &pkt_length);                  default:
840          if (pkt_length != length)                          unimpl("update %d\n", update_type);
         {  
                 ERROR("Unrecognised capabilities size\n");  
                 return False;  
841          }          }
842    
         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;  
843  }  }
844    
845  /* Construct an activation capability set */  /* Process data PDU */
846  void rdp_make_activate_caps(RDP_ACTIVATE_CAPS *caps)  static void
847    process_data_pdu(STREAM s)
848  {  {
849  }          uint8 data_pdu_type;
850    
851  /* Parse activation capability set */          in_uint8s(s, 8);        /* shareid, pad, streamid, length */
852  BOOL rdp_io_activate_caps(STREAM s, RDP_ACTIVATE_CAPS *caps)          in_uint8(s, data_pdu_type);
853  {          in_uint8s(s, 3);        /* compress_type, compress_len */
         uint16 length = RDP_CAPLEN_ACTIVATE;  
         uint16 pkt_length = length;  
         BOOL res;  
854    
855          res = lsb_io_uint16(s, &pkt_length);          switch (data_pdu_type)
         if (pkt_length != length)  
856          {          {
857                  ERROR("Unrecognised capabilities size\n");                  case RDP_DATA_PDU_UPDATE:
858                  return False;                          process_update_pdu(s);
859          }                          break;
860    
861          res = res ? lsb_io_uint16(s, &caps->help_key         ) : False;                  case RDP_DATA_PDU_POINTER:
862          res = res ? lsb_io_uint16(s, &caps->help_index_key   ) : False;                          process_pointer_pdu(s);
863          res = res ? lsb_io_uint16(s, &caps->help_extended_key) : False;                          break;
         res = res ? lsb_io_uint16(s, &caps->window_activate  ) : False;  
864    
865          return res;                  case RDP_DATA_PDU_BELL:
866  }                          ui_bell();
867                            break;
868    
869  /* Construct a pointer capability set */                  case RDP_DATA_PDU_LOGON:
870  void rdp_make_pointer_caps(RDP_POINTER_CAPS *caps)                          DEBUG(("Received Logon PDU\n"));
871  {                          /* User logged on */
872          caps->colour_pointer = 0;                          break;
         caps->cache_size = 20;  
 }  
873    
874  /* Parse pointer capability set */                  case RDP_DATA_PDU_DISCONNECT:
875  BOOL rdp_io_pointer_caps(STREAM s, RDP_POINTER_CAPS *caps)                          /* Normally received when user logs out or disconnects from a
876  {                             console session on Windows XP and 2003 Server */
877          uint16 length = RDP_CAPLEN_POINTER;                          DEBUG(("Received disconnect PDU\n"));
878          uint16 pkt_length = length;                          break;
         BOOL res;  
879    
880          res = lsb_io_uint16(s, &pkt_length);                  default:
881          if (pkt_length != length)                          unimpl("data PDU %d\n", data_pdu_type);
         {  
                 ERROR("Unrecognised capabilities size\n");  
                 return False;  
882          }          }
   
         res = res ? lsb_io_uint16(s, &caps->colour_pointer) : False;  
         res = res ? lsb_io_uint16(s, &caps->cache_size    ) : False;  
   
         return res;  
883  }  }
884    
885  /* Construct a share capability set */  /* Process incoming packets */
886  void rdp_make_share_caps(RDP_SHARE_CAPS *caps, uint16 userid)  BOOL
887    rdp_main_loop(void)
888  {  {
889  }          uint8 type;
890            STREAM s;
891    
892  /* Parse share capability set */          while ((s = rdp_recv(&type)) != NULL)
 BOOL rdp_io_share_caps(STREAM s, RDP_SHARE_CAPS *caps)  
 {  
         uint16 length = RDP_CAPLEN_SHARE;  
         uint16 pkt_length = length;  
         BOOL res;  
   
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
893          {          {
894                  ERROR("Unrecognised capabilities size\n");                  switch (type)
895                  return False;                  {
896          }                          case RDP_PDU_DEMAND_ACTIVE:
897                                    process_demand_active(s);
898          res = res ? lsb_io_uint16(s, &caps->userid) : False;                                  break;
         res = res ? lsb_io_uint16(s, &caps->pad   ) : False;  
899    
900          return res;                          case RDP_PDU_DEACTIVATE:
901  }                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));
902                                    /* We thought we could detect a clean
903                                       shutdown of the session by this
904                                       packet, but it seems Windows 2003
905                                       is sending us one of these when we
906                                       reconnect to a disconnected session
907                                       return True; */
908                                    break;
909    
910  /* Construct a colour cache capability set */                          case RDP_PDU_DATA:
911  void rdp_make_colcache_caps(RDP_COLCACHE_CAPS *caps)                                  process_data_pdu(s);
912  {                                  break;
         caps->cache_size = 6;  
 }  
913    
914  /* Parse colour cache capability set */                          case 0:
915  BOOL rdp_io_colcache_caps(STREAM s, RDP_COLCACHE_CAPS *caps)                                  break;
 {  
         uint16 length = RDP_CAPLEN_COLCACHE;  
         uint16 pkt_length = length;  
         BOOL res;  
916    
917          res = lsb_io_uint16(s, &pkt_length);                          default:
918          if (pkt_length != length)                                  unimpl("PDU %d\n", type);
919          {                  }
                 ERROR("Unrecognised capabilities size\n");  
                 return False;  
920          }          }
921            return True;
922          res = res ? lsb_io_uint16(s, &caps->cache_size) : False;          /* We want to detect if we got a clean shutdown, but we
923          res = res ? lsb_io_uint16(s, &caps->pad       ) : False;             can't. Se above.  
924               return False;  */
         return res;  
925  }  }
926    
927  uint8 canned_caps[] = {  /* Establish a connection up to the RDP layer */
928  0x01,0x00,0x00,0x00,0x09,0x04,0x00,0x00,0x04,  BOOL
929  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,  rdp_connect(char *server, uint32 flags, char *domain, char *password,
930  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,              char *command, char *directory)
 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)  
931  {  {
932          uint16 length = 0x58;          if (!sec_connect(server, g_username))
         uint16 pkt_length = length;  
         BOOL res;  
   
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
         {  
                 ERROR("Unrecognised capabilities size\n");  
933                  return False;                  return False;
         }  
934    
935          res = res ? prs_io_uint8s(s, canned_caps, RDP_CAPLEN_UNKNOWN-4) : False;          rdp_send_logon_info(flags, domain, g_username, password, command, directory);
936            return True;
937    }
938    
939          return res;  /* Disconnect from the RDP layer */
940    void
941    rdp_disconnect(void)
942    {
943            sec_disconnect();
944  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26