/[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 717 by astrand, Thu Jun 17 09:42:58 2004 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"
23    
24  /* Establish a connection up to the RDP layer */  extern uint16 g_mcs_userid;
25  HCONN rdp_connect(char *server, int width, int height)  extern char g_username[16];
26  {  extern BOOL g_bitmap_compression;
27          HCONN conn;  extern BOOL g_orders;
28    extern BOOL g_encryption;
29          if ((conn = mcs_connect(server)) == NULL)  extern BOOL g_desktop_save;
30                  return NULL;  extern BOOL g_use_rdp5;
31    extern uint16 g_server_rdp_version;
32    extern uint32 g_rdp5_performanceflags;
33    extern int g_server_bpp;
34    extern int g_width;
35    extern int g_height;
36    extern BOOL g_bitmap_cache;
37    
38          rdp_establish_key(conn);  uint8 *g_next_packet;
39          mcs_recv(conn, False); /* Server's licensing certificate */  uint32 g_rdp_shareid;
         rdp_send_cert(conn);  
         mcs_recv(conn, False);  
         mcs_recv(conn, False);  
40    
41          return conn;  extern RDPCOMP g_mppc_dict;
42    
43  }  #if WITH_DEBUG
44    static uint32 g_packetno;
45  /* Work this out later. This is useless anyway when encryption is off. */  #endif
 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);  
 }  
46    
47  /* Initialise RDP transport packet */  /* Receive an RDP packet */
48  void rdp_init(HCONN conn)  static STREAM
49    rdp_recv(uint8 * type)
50  {  {
51          mcs_init_data(conn);          static STREAM rdp_s;
52          PUSH_LAYER(conn->out, rdp_offset, 6);          uint16 length, pdu_type;
 }  
53    
54  /* Transmit RDP transport packet */          if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end))
55  void rdp_send(HCONN conn, uint16 pdu_type)          {
56  {                  rdp_s = sec_recv();
57          RDP_HEADER hdr;                  if (rdp_s == NULL)
58          int length;                          return NULL;
59    
60          POP_LAYER(conn->out, rdp_offset);                  g_next_packet = rdp_s->p;
61          length = conn->out.end - conn->out.offset;          }
62          rdp_make_header(&hdr, length, pdu_type, conn->mcs_userid);          else
63          rdp_io_header(&conn->out, &hdr);          {
64          mcs_send_data(conn, MCS_GLOBAL_CHANNEL, True);                  rdp_s->p = g_next_packet;
65  }          }
66    
67  /* Initialise RDP transport data packet */          in_uint16_le(rdp_s, length);
68  void rdp_init_data(HCONN conn)          /* 32k packets are really 8, keepalive fix */
69  {          if (length == 0x8000)
70          mcs_init_data(conn);          {
71          PUSH_LAYER(conn->out, rdp_offset, 18);                  g_next_packet += 8;
72  }                  *type = 0;
73                    return rdp_s;
74            }
75            in_uint16_le(rdp_s, pdu_type);
76            in_uint8s(rdp_s, 2);    /* userid */
77            *type = pdu_type & 0xf;
78    
79  /* Transmit RDP transport data packet */  #if WITH_DEBUG
80  void rdp_send_data(HCONN conn, uint16 data_pdu_type)          DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type));
81  {          hexdump(g_next_packet, length);
82          RDP_HEADER hdr;  #endif /*  */
         RDP_DATA_HEADER datahdr;  
         int length = conn->out.end - conn->out.offset;  
83    
84          POP_LAYER(conn->out, rdp_offset);          g_next_packet += length;
85          length = conn->out.end - conn->out.offset;          return rdp_s;
         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);  
86  }  }
87    
88  void rdp_send_confirm_active(HCONN conn, uint32 shareid, int width, int height)  /* Initialise an RDP data packet */
89    static STREAM
90    rdp_init_data(int maxlen)
91  {  {
92          RDP_ACTIVE_PDU active;          STREAM s;
   
         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);  
 }  
93    
94  void rdp_send_synchronize(HCONN conn)          s = sec_init(g_encryption ? SEC_ENCRYPT : 0, maxlen + 18);
95  {          s_push_layer(s, rdp_hdr, 18);
         RDP_SYNCHRONISE_PDU sync;  
96    
97          rdp_init_data(conn);          return s;
         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);  
98  }  }
99    
100  void rdp_send_control(HCONN conn, uint16 action)  /* Send an RDP data packet */
101    static void
102    rdp_send_data(STREAM s, uint8 data_pdu_type)
103  {  {
104          RDP_CONTROL_PDU control;          uint16 length;
   
         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);  
 }  
105    
106  void rdp_send_fonts(HCONN conn, uint16 seqno)          s_pop_layer(s, rdp_hdr);
107  {          length = s->end - s->p;
         RDP_FONT_PDU fonts;  
108    
109          rdp_init_data(conn);          out_uint16_le(s, length);
110          rdp_make_font_pdu(&fonts, seqno);          out_uint16_le(s, (RDP_PDU_DATA | 0x10));
111          rdp_io_font_pdu(&conn->out, &fonts);          out_uint16_le(s, (g_mcs_userid + 1001));
         MARK_END(conn->out);  
         rdp_send_data(conn, RDP_DATA_PDU_FONT2);  
 }  
112    
113  void rdp_send_input(HCONN conn, uint16 message_type, uint16 device_flags,          out_uint32_le(s, g_rdp_shareid);
114                                  uint16 param1, uint16 param2)          out_uint8(s, 0);        /* pad */
115  {          out_uint8(s, 1);        /* streamid */
116          RDP_INPUT_PDU input;          out_uint16_le(s, (length - 14));
117            out_uint8(s, data_pdu_type);
118            out_uint8(s, 0);        /* compress_type */
119            out_uint16(s, 0);       /* compress_len */
120    
121          rdp_init_data(conn);          sec_send(s, g_encryption ? SEC_ENCRYPT : 0);
         rdp_make_input_pdu(&input, message_type, device_flags, param1, param2);  
         rdp_io_input_pdu(&conn->out, &input);  
         MARK_END(conn->out);  
         rdp_send_data(conn, RDP_DATA_PDU_INPUT);  
122  }  }
123    
124  BOOL rdp_recv_pdu(HCONN conn, uint8 *type)  /* Output a string in Unicode */
125    void
126    rdp_out_unistr(STREAM s, char *string, int len)
127  {  {
128          RDP_HEADER hdr;          int i = 0, j = 0;
129    
130          conn->in.offset = conn->in.rdp_offset;          len += 2;
131    
132          if (conn->in.offset >= conn->in.end)          while (i < len)
133          {          {
134                  if (!mcs_recv(conn, False))                  s->p[i++] = string[j++];
135                          return False;                  s->p[i++] = 0;
136          }          }
137    
138          if (!rdp_io_header(&conn->in, &hdr))          s->p += len;
                 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);  
 #endif  
   
         return True;  
139  }  }
140    
141  /* Disconnect from the RDP layer */  /* Input a string in Unicode
142  void rdp_disconnect(HCONN conn)   *
143     * Returns str_len of string
144     */
145    int
146    rdp_in_unistr(STREAM s, char *string, int uni_len)
147  {  {
148          mcs_disconnect(conn);          int i = 0;
 }  
   
 /* 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;  
 }  
149    
150  /* Parse an RDP header */          while (i < uni_len / 2)
151  BOOL rdp_io_header(STREAM s, RDP_HEADER *hdr)          {
152  {                  in_uint8a(s, &string[i++], 1);
153          BOOL res = True;                  in_uint8s(s, 1);
154            }
         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;  
155    
156          return res;          return i - 1;
157  }  }
158    
 /* 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;  
 }  
159    
160  /* Parse a data header */  /* Parse a logon info packet */
161  BOOL rdp_io_data_header(STREAM s, RDP_DATA_HEADER *hdr)  static void
162    rdp_send_logon_info(uint32 flags, char *domain, char *user,
163                        char *password, char *program, char *directory)
164  {  {
165          BOOL res = True;          char *ipaddr = tcp_get_address();
166            int len_domain = 2 * strlen(domain);
167          res = res ? lsb_io_uint32(s, &hdr->shareid      ) : False;          int len_user = 2 * strlen(user);
168          res = res ? prs_io_uint8 (s, &hdr->pad          ) : False;          int len_password = 2 * strlen(password);
169          res = res ? prs_io_uint8 (s, &hdr->streamid     ) : False;          int len_program = 2 * strlen(program);
170          res = res ? lsb_io_uint16(s, &hdr->length       ) : False;          int len_directory = 2 * strlen(directory);
171          res = res ? prs_io_uint8 (s, &hdr->data_pdu_type) : False;          int len_ip = 2 * strlen(ipaddr);
172          res = res ? prs_io_uint8 (s, &hdr->compress_type) : False;          int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll");
173          res = res ? lsb_io_uint16(s, &hdr->compress_len ) : False;          int packetlen = 0;
174            uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO;
175          return res;          STREAM s;
176  }          time_t t = time(NULL);
177            time_t tzone;
178    
179  BOOL rdp_io_present(STREAM s, uint32 *present, uint8 flags, int size)  #if 0
180  {          /* enable rdp compression */
181          uint8 bits;          /* some problems still exist with rdp5 */
182          int i;          flags |= RDP_COMPRESSION;
183    #endif
         if (flags & RDP_ORDER_SMALL)  
         {  
                 size--;  
         }  
184    
185          if (flags & RDP_ORDER_TINY)          if (!g_use_rdp5 || 1 == g_server_rdp_version)
186          {          {
187                  if (size < 2)                  DEBUG_RDP5(("Sending RDP4-style Logon packet\n"));
                         return False;  
188    
189                  size -= 2;                  s = sec_init(sec_flags, 18 + len_domain + len_user + len_password
190          }                               + len_program + len_directory + 10);
191    
192          *present = 0;                  out_uint32(s, 0);
193          for (i = 0; i < size; i++)                  out_uint32_le(s, flags);
194          {                  out_uint16_le(s, len_domain);
195                  prs_io_uint8(s, &bits);                  out_uint16_le(s, len_user);
196                  *present |= bits << (i * 8);                  out_uint16_le(s, len_password);
197          }                  out_uint16_le(s, len_program);
198                    out_uint16_le(s, len_directory);
199          return True;                  rdp_out_unistr(s, domain, len_domain);
200  }                  rdp_out_unistr(s, user, len_user);
201                    rdp_out_unistr(s, password, len_password);
202  BOOL rdp_io_coord(STREAM s, uint16 *coord, BOOL delta)                  rdp_out_unistr(s, program, len_program);
203  {                  rdp_out_unistr(s, directory, len_directory);
         uint8 change;  
         BOOL res;  
   
         if (delta)  
         {  
                 res = prs_io_uint8(s, &change);  
                 *coord += (char)change;  
204          }          }
205          else          else
206          {          {
                 res = lsb_io_uint16(s, coord);  
         }  
207    
208          return res;                  flags |= RDP_LOGON_BLOB;
209  }                  DEBUG_RDP5(("Sending RDP5-style Logon packet\n"));
210                    packetlen = 4 + /* Unknown uint32 */
211  BOOL rdp_io_colour(STREAM s, uint8 *colour)                          4 +     /* flags */
212  {                          2 +     /* len_domain */
213          BOOL res;                          2 +     /* len_user */
214                            (flags & RDP_LOGON_AUTO ? 2 : 0) +      /* len_password */
215          res = prs_io_uint8(s, colour);                          (flags & RDP_LOGON_BLOB ? 2 : 0) +      /* Length of BLOB */
216          s->offset += 2;                          2 +     /* len_program */
217                            2 +     /* len_directory */
218                            (0 < len_domain ? len_domain : 2) +     /* domain */
219                            len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 +    /* We have no 512 byte BLOB. Perhaps we must? */
220                            (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + /* After the BLOB is a unknown int16. If there is a BLOB, that is. */
221                            (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 +     /* Unknown (2) */
222                            2 +     /* Client ip length */
223                            len_ip +        /* Client ip */
224                            2 +     /* DLL string length */
225                            len_dll +       /* DLL string */
226                            2 +     /* Unknown */
227                            2 +     /* Unknown */
228                            64 +    /* Time zone #0 */
229                            2 +     /* Unknown */
230                            64 +    /* Time zone #1 */
231                            32;     /* Unknown */
232    
233                    s = sec_init(sec_flags, packetlen);
234                    DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen));
235    
236                    out_uint32(s, 0);       /* Unknown */
237                    out_uint32_le(s, flags);
238                    out_uint16_le(s, len_domain);
239                    out_uint16_le(s, len_user);
240                    if (flags & RDP_LOGON_AUTO)
241                    {
242                            out_uint16_le(s, len_password);
243    
244          return res;                  }
245  }                  if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
246                    {
247                            out_uint16_le(s, 0);
248                    }
249                    out_uint16_le(s, len_program);
250                    out_uint16_le(s, len_directory);
251                    if (0 < len_domain)
252                            rdp_out_unistr(s, domain, len_domain);
253                    else
254                            out_uint16_le(s, 0);
255                    rdp_out_unistr(s, user, len_user);
256                    if (flags & RDP_LOGON_AUTO)
257                    {
258                            rdp_out_unistr(s, password, len_password);
259                    }
260                    if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO))
261                    {
262                            out_uint16_le(s, 0);
263                    }
264                    if (0 < len_program)
265                    {
266                            rdp_out_unistr(s, program, len_program);
267    
268  BOOL rdp_io_colourmap(STREAM s, COLOURMAP *colours)                  }
269  {                  else
270          int datasize;                  {
271                            out_uint16_le(s, 0);
272                    }
273                    if (0 < len_directory)
274                    {
275                            rdp_out_unistr(s, directory, len_directory);
276                    }
277                    else
278                    {
279                            out_uint16_le(s, 0);
280                    }
281                    out_uint16_le(s, 2);
282                    out_uint16_le(s, len_ip + 2);   /* Length of client ip */
283                    rdp_out_unistr(s, ipaddr, len_ip);
284                    out_uint16_le(s, len_dll + 2);
285                    rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll);
286    
287          lsb_io_uint16(s, &colours->ncolours);                  tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60;
288          datasize = colours->ncolours * 3;                  out_uint32_le(s, tzone);
289    
290          if (datasize > sizeof(colours->colours))                  rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid"));
291                  return False;                  out_uint8s(s, 62 - 2 * strlen("GTB, normaltid"));
292    
293          memcpy(colours->colours, s->data + s->offset, datasize);                  out_uint32_le(s, 0x0a0000);
294          s->offset += datasize;                  out_uint32_le(s, 0x050000);
295          return True;                  out_uint32_le(s, 3);
296  }                  out_uint32_le(s, 0);
297                    out_uint32_le(s, 0);
298    
299  BOOL rdp_io_bounds(STREAM s, BOUNDS *bounds)                  rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid"));
300  {                  out_uint8s(s, 62 - 2 * strlen("GTB, sommartid"));
         uint8 present;  
301    
302          prs_io_uint8(s, &present);                  out_uint32_le(s, 0x30000);
303                    out_uint32_le(s, 0x050000);
304                    out_uint32_le(s, 2);
305                    out_uint32(s, 0);
306                    out_uint32_le(s, 0xffffffc4);
307                    out_uint32_le(s, 0xfffffffe);
308                    out_uint32_le(s, g_rdp5_performanceflags);
309                    out_uint32(s, 0);
310    
         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);  
311    
312          return True;          }
313            s_mark_end(s);
314            sec_send(s, sec_flags);
315  }  }
316    
317  BOOL rdp_io_pen(STREAM s, PEN *pen, uint32 present)  /* Send a control PDU */
318    static void
319    rdp_send_control(uint16 action)
320  {  {
321          BOOL res = True;          STREAM s;
322    
323          if (present & 1)          s = rdp_init_data(8);
                 res = res ? prs_io_uint8(s, &pen->style) : False;  
324    
325          if (present & 2)          out_uint16_le(s, action);
326                  res = res ? prs_io_uint8(s, &pen->width) : False;          out_uint16(s, 0);       /* userid */
327            out_uint32(s, 0);       /* control id */
328    
329          if (present & 4)          s_mark_end(s);
330                  res = res ? rdp_io_colour(s, &pen->colour) : False;          rdp_send_data(s, RDP_DATA_PDU_CONTROL);
   
         return res;  
331  }  }
332    
333  BOOL rdp_io_brush(STREAM s, BRUSH *brush, uint32 present)  /* Send a synchronisation PDU */
334    static void
335    rdp_send_synchronise(void)
336  {  {
337          BOOL res = True;          STREAM s;
   
         if (present & 1)  
                 res = res ? prs_io_uint8(s, &brush->xorigin) : False;  
   
         if (present & 2)  
                 res = res ? prs_io_uint8(s, &brush->yorigin) : False;  
338    
339          if (present & 4)          s = rdp_init_data(4);
                 res = res ? prs_io_uint8(s, &brush->style) : False;  
340    
341          if (present & 8)          out_uint16_le(s, 1);    /* type */
342                  res = res ? prs_io_uint8(s, &brush->pattern[0]) : False;          out_uint16_le(s, 1002);
343    
344          if (present & 16)          s_mark_end(s);
345                  res = res ? prs_io_uint8s(s, &brush->pattern[1], 7) : False;          rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE);
   
         return res;  
 }  
   
 /* Construct a confirm/demand active PDU */  
 void rdp_make_active_pdu(RDP_ACTIVE_PDU *pdu, uint32 shareid, uint16 userid,  
                                 int width, int height)  
 {  
         memset(pdu, 0, sizeof(*pdu));  
         pdu->shareid = shareid;  
         pdu->userid  = 1002;  
         pdu->source_len = sizeof(RDP_SOURCE);  
         memcpy(pdu->source, RDP_SOURCE, sizeof(RDP_SOURCE));  
   
         pdu->caps_len = RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER  
                 + RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE + RDP_CAPLEN_ACTIVATE  
                 + RDP_CAPLEN_CONTROL + RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE  
                 + RDP_CAPLEN_UNKNOWN;  
         pdu->num_caps = 0xD;  
   
         rdp_make_general_caps (&pdu->general_caps );  
         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);  
346  }  }
347    
348  /* Parse a confirm/demand active PDU */  /* Send a single input event */
349  BOOL rdp_io_active_pdu(STREAM s, RDP_ACTIVE_PDU *pdu, int pdutype)  void
350    rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2)
351  {  {
352          uint16 capset;          STREAM s;
         uint16 length;  
         BOOL res;  
         int i;  
   
         res = lsb_io_uint32(s, &pdu->shareid);  
353    
354          if (pdutype == RDP_PDU_CONFIRM_ACTIVE)          s = rdp_init_data(16);
                 res = res ? lsb_io_uint16(s, &pdu->userid    ) : False;  
355    
356          res = res ? lsb_io_uint16(s, &pdu->source_len) : False;          out_uint16_le(s, 1);    /* number of events */
357          res = res ? lsb_io_uint16(s, &pdu->caps_len  ) : False;          out_uint16(s, 0);       /* pad */
358    
359          if (pdu->source_len > 48)          out_uint32_le(s, time);
360          {          out_uint16_le(s, message_type);
361                  ERROR("RDP source descriptor too long\n");          out_uint16_le(s, device_flags);
362                  return False;          out_uint16_le(s, param1);
363          }          out_uint16_le(s, param2);
   
         res = res ? prs_io_uint8s(s,  pdu->source, pdu->source_len) : False;  
         res = res ? lsb_io_uint16(s, &pdu->num_caps  ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->pad       ) : False;  
   
         if (s->marshall)  
         {  
                 capset = RDP_CAPSET_GENERAL;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_general_caps(s, &pdu->general_caps) : False;  
   
                 capset = RDP_CAPSET_BITMAP;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_bitmap_caps (s, &pdu->bitmap_caps ) : False;  
   
                 capset = RDP_CAPSET_ORDER;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_order_caps  (s, &pdu->order_caps  ) : False;  
   
                 capset = RDP_CAPSET_BMPCACHE;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_bmpcache_caps(s, &pdu->bmpcache_caps) : False;  
   
                 capset = RDP_CAPSET_COLCACHE;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_colcache_caps(s, &pdu->colcache_caps) : False;  
   
                 capset = RDP_CAPSET_ACTIVATE;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_activate_caps(s, &pdu->activate_caps) : False;  
   
                 capset = RDP_CAPSET_CONTROL;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_control_caps(s, &pdu->control_caps) : False;  
   
                 capset = RDP_CAPSET_POINTER;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_pointer_caps(s, &pdu->pointer_caps) : False;  
   
                 capset = RDP_CAPSET_SHARE;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_share_caps  (s, &pdu->share_caps  ) : False;  
   
                 capset = RDP_CAPSET_UNKNOWN;  
                 res = res ? lsb_io_uint16(s, &capset) : False;  
                 res = res ? rdp_io_unknown_caps(s, NULL) : False;  
         }  
         else  
         {  
                 for (i = 0; i < pdu->num_caps; i++)  
                 {  
                         if (!res)  
                                 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);  
   
                                 if (!lsb_io_uint16(s, &length))  
                                         return False;  
   
                                 s->offset += (length - 4);  
                         }  
                 }  
         }  
364    
365          return res;          s_mark_end(s);
366            rdp_send_data(s, RDP_DATA_PDU_INPUT);
367  }  }
368    
369  /* Construct a control PDU */  /* Send an (empty) font information PDU */
370  void rdp_make_control_pdu(RDP_CONTROL_PDU *pdu, uint16 action)  static void
371    rdp_send_fonts(uint16 seq)
372  {  {
373          pdu->action = action;          STREAM s;
         pdu->userid = 0;  
         pdu->controlid = 0;  
 }  
374    
375  /* Parse a control PDU */          s = rdp_init_data(8);
 BOOL rdp_io_control_pdu(STREAM s, RDP_CONTROL_PDU *pdu)  
 {  
         BOOL res = True;  
376    
377          res = res ? lsb_io_uint16(s, &pdu->action   ) : False;          out_uint16(s, 0);       /* number of fonts */
378          res = res ? lsb_io_uint16(s, &pdu->userid   ) : False;          out_uint16_le(s, 0);    /* pad? */
379          res = res ? lsb_io_uint32(s, &pdu->controlid) : False;          out_uint16_le(s, seq);  /* unknown */
380            out_uint16_le(s, 0x32); /* entry size */
381    
382          return res;          s_mark_end(s);
383            rdp_send_data(s, RDP_DATA_PDU_FONT2);
384  }  }
385    
386  /* Construct a synchronisation PDU */  /* Output general capability set */
387  void rdp_make_synchronise_pdu(RDP_SYNCHRONISE_PDU *pdu, uint16 userid)  static void
388    rdp_out_general_caps(STREAM s)
389  {  {
390          pdu->type = 1;          out_uint16_le(s, RDP_CAPSET_GENERAL);
391          pdu->userid = userid;          out_uint16_le(s, RDP_CAPLEN_GENERAL);
392    
393            out_uint16_le(s, 1);    /* OS major type */
394            out_uint16_le(s, 3);    /* OS minor type */
395            out_uint16_le(s, 0x200);        /* Protocol version */
396            out_uint16(s, 0);       /* Pad */
397            out_uint16(s, 0);       /* Compression types */
398            out_uint16_le(s, g_use_rdp5 ? 0x40d : 0);
399            /* Pad, according to T.128. 0x40d seems to
400               trigger
401               the server to start sending RDP5 packets.
402               However, the value is 0x1d04 with W2KTSK and
403               NT4MS. Hmm.. Anyway, thankyou, Microsoft,
404               for sending such information in a padding
405               field.. */
406            out_uint16(s, 0);       /* Update capability */
407            out_uint16(s, 0);       /* Remote unshare capability */
408            out_uint16(s, 0);       /* Compression level */
409            out_uint16(s, 0);       /* Pad */
410  }  }
411    
412  /* Parse a synchronisation PDU */  /* Output bitmap capability set */
413  BOOL rdp_io_synchronise_pdu(STREAM s, RDP_SYNCHRONISE_PDU *pdu)  static void
414    rdp_out_bitmap_caps(STREAM s)
415  {  {
416          BOOL res = True;          out_uint16_le(s, RDP_CAPSET_BITMAP);
417            out_uint16_le(s, RDP_CAPLEN_BITMAP);
418    
419          res = res ? lsb_io_uint16(s, &pdu->type  ) : False;          out_uint16_le(s, g_server_bpp); /* Preferred BPP */
420          res = res ? lsb_io_uint16(s, &pdu->userid) : False;          out_uint16_le(s, 1);    /* Receive 1 BPP */
421            out_uint16_le(s, 1);    /* Receive 4 BPP */
422          return res;          out_uint16_le(s, 1);    /* Receive 8 BPP */
423            out_uint16_le(s, 800);  /* Desktop width */
424            out_uint16_le(s, 600);  /* Desktop height */
425            out_uint16(s, 0);       /* Pad */
426            out_uint16(s, 1);       /* Allow resize */
427            out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */
428            out_uint16(s, 0);       /* Unknown */
429            out_uint16_le(s, 1);    /* Unknown */
430            out_uint16(s, 0);       /* Pad */
431  }  }
432    
433  /* Parse a single input event */  /* Output order capability set */
434  BOOL rdp_io_input_event(STREAM s, RDP_INPUT_EVENT *evt)  static void
435    rdp_out_order_caps(STREAM s)
436  {  {
437          BOOL res = True;          uint8 order_caps[32];
438    
         res = res ? lsb_io_uint32(s, &evt->event_time)   : False;  
         res = res ? lsb_io_uint16(s, &evt->message_type) : False;  
         res = res ? lsb_io_uint16(s, &evt->device_flags) : False;  
439    
440          if (!res)          memset(order_caps, 0, 32);
441                  return False;          order_caps[0] = 1;      /* dest blt */
442            order_caps[1] = 1;      /* pat blt */
443            order_caps[2] = 1;      /* screen blt */
444            order_caps[3] = (g_bitmap_cache ? 1 : 0);       /* memblt */
445            order_caps[8] = 1;      /* line */
446            order_caps[9] = 1;      /* line */
447            order_caps[10] = 1;     /* rect */
448            order_caps[11] = (g_desktop_save == False ? 0 : 1);     /* desksave */
449            order_caps[13] = 1;     /* memblt */
450            order_caps[14] = 1;     /* triblt */
451            order_caps[22] = 1;     /* polyline */
452            order_caps[27] = 1;     /* text2 */
453            out_uint16_le(s, RDP_CAPSET_ORDER);
454            out_uint16_le(s, RDP_CAPLEN_ORDER);
455    
456          switch (evt->message_type)          out_uint8s(s, 20);      /* Terminal desc, pad */
457          {          out_uint16_le(s, 1);    /* Cache X granularity */
458          case RDP_INPUT_CODEPOINT:          out_uint16_le(s, 20);   /* Cache Y granularity */
459          case RDP_INPUT_VIRTKEY:          out_uint16(s, 0);       /* Pad */
460                  res = res ? lsb_io_uint16(s, &evt->param1) : False;          out_uint16_le(s, 1);    /* Max order level */
461                  break;          out_uint16_le(s, 0x147);        /* Number of fonts */
462          case RDP_INPUT_SYNCHRONIZE:          out_uint16_le(s, 0x2a); /* Capability flags */
463          case RDP_INPUT_SCANCODE:          out_uint8p(s, order_caps, 32);  /* Orders supported */
464          case RDP_INPUT_MOUSE:          out_uint16_le(s, 0x6a1);        /* Text capability flags */
465                  res = res ? lsb_io_uint16(s, &evt->param1) : False;          out_uint8s(s, 6);       /* Pad */
466                  res = res ? lsb_io_uint16(s, &evt->param2) : False;          out_uint32_le(s, g_desktop_save == False ? 0 : 0x38400);        /* Desktop cache size */
467                  break;          out_uint32(s, 0);       /* Unknown */
468          default:          out_uint32_le(s, 0x4e4);        /* Unknown */
                 NOTIMP("input type %d\n", evt->message_type);  
                 return False;  
         }  
   
         return res;  
469  }  }
470    
471  /* Construct an input PDU */  /* Output bitmap cache capability set */
472  void rdp_make_input_pdu(RDP_INPUT_PDU *pdu, uint16 message_type,  static void
473                          uint16 device_flags, uint16 param1, uint16 param2)  rdp_out_bmpcache_caps(STREAM s)
474  {  {
475          uint32 now = time(NULL);          int Bpp;
476            out_uint16_le(s, RDP_CAPSET_BMPCACHE);
477            out_uint16_le(s, RDP_CAPLEN_BMPCACHE);
478    
479          pdu->num_events = 1;          Bpp = (g_server_bpp + 7) / 8;
480          pdu->pad = 0;          out_uint8s(s, 24);      /* unused */
481            out_uint16_le(s, 0x258);        /* entries */
482          pdu->event[0].event_time = now;          out_uint16_le(s, 0x100 * Bpp);  /* max cell size */
483          pdu->event[0].message_type = message_type;          out_uint16_le(s, 0x12c);        /* entries */
484          pdu->event[0].device_flags = device_flags;          out_uint16_le(s, 0x400 * Bpp);  /* max cell size */
485          pdu->event[0].param1 = param1;          out_uint16_le(s, 0x106);        /* entries */
486          pdu->event[0].param2 = param2;          out_uint16_le(s, 0x1000 * Bpp); /* max cell size */
487  }  }
488    
489  /* Parse an input PDU */  /* Output control capability set */
490  BOOL rdp_io_input_pdu(STREAM s, RDP_INPUT_PDU *pdu)  static void
491    rdp_out_control_caps(STREAM s)
492  {  {
493          BOOL res = True;          out_uint16_le(s, RDP_CAPSET_CONTROL);
494          int i;          out_uint16_le(s, RDP_CAPLEN_CONTROL);
   
         res = res ? lsb_io_uint16(s, &pdu->num_events) : False;  
         res = res ? lsb_io_uint16(s, &pdu->pad       ) : False;  
495    
496          if (pdu->num_events > RDP_MAX_EVENTS)          out_uint16(s, 0);       /* Control capabilities */
497          {          out_uint16(s, 0);       /* Remote detach */
498                  ERROR("Too many events in one PDU\n");          out_uint16_le(s, 2);    /* Control interest */
499                  return False;          out_uint16_le(s, 2);    /* Detach interest */
         }  
   
         for (i = 0; i < pdu->num_events; i++)  
         {  
                 res = res ? rdp_io_input_event(s, &pdu->event[i]) : False;  
         }  
   
         return res;  
 }  
   
 /* Construct a font information PDU */  
 void rdp_make_font_pdu(RDP_FONT_PDU *pdu, uint16 seqno)  
 {  
         pdu->num_fonts = 0;  
         pdu->unknown1 = 0x3e;  
         pdu->unknown2 = seqno;  
         pdu->entry_size = RDP_FONT_INFO_SIZE;  
500  }  }
501    
502  /* Parse a font information structure */  /* Output activation capability set */
503  BOOL rdp_io_font_info(STREAM s, RDP_FONT_INFO *font)  static void
504    rdp_out_activate_caps(STREAM s)
505  {  {
506          BOOL res = True;          out_uint16_le(s, RDP_CAPSET_ACTIVATE);
507            out_uint16_le(s, RDP_CAPLEN_ACTIVATE);
         res = res ? prs_io_uint8s(s,  font->name, 32 ) : False;  
         res = res ? lsb_io_uint16(s, &font->flags    ) : False;  
         res = res ? lsb_io_uint16(s, &font->width    ) : False;  
         res = res ? lsb_io_uint16(s, &font->height   ) : False;  
         res = res ? lsb_io_uint16(s, &font->xaspect  ) : False;  
         res = res ? lsb_io_uint16(s, &font->yaspect  ) : False;  
         res = res ? lsb_io_uint32(s, &font->signature) : False;  
         res = res ? lsb_io_uint16(s, &font->codepage ) : False;  
         res = res ? lsb_io_uint16(s, &font->ascent   ) : False;  
508    
509          return res;          out_uint16(s, 0);       /* Help key */
510            out_uint16(s, 0);       /* Help index key */
511            out_uint16(s, 0);       /* Extended help key */
512            out_uint16(s, 0);       /* Window activate */
513  }  }
514    
515  /* Parse a font information PDU */  /* Output pointer capability set */
516  BOOL rdp_io_font_pdu(STREAM s, RDP_FONT_PDU *pdu)  static void
517    rdp_out_pointer_caps(STREAM s)
518  {  {
519          BOOL res = True;          out_uint16_le(s, RDP_CAPSET_POINTER);
520          int i;          out_uint16_le(s, RDP_CAPLEN_POINTER);
521    
522          res = res ? lsb_io_uint16(s, &pdu->num_fonts ) : False;          out_uint16(s, 0);       /* Colour pointer */
523          res = res ? lsb_io_uint16(s, &pdu->unknown1  ) : False;          out_uint16_le(s, 20);   /* Cache size */
         res = res ? lsb_io_uint16(s, &pdu->unknown2  ) : False;  
         res = res ? lsb_io_uint16(s, &pdu->entry_size) : False;  
   
         if (pdu->num_fonts > RDP_MAX_FONTS)  
         {  
                 ERROR("Too many fonts in one PDU\n");  
                 return False;  
         }  
   
         for (i = 0; i < pdu->num_fonts; i++)  
         {  
                 res = res ? rdp_io_font_info(s, &pdu->font[i]) : False;  
         }  
   
         return res;  
524  }  }
525    
526  /* Parse a pointer PDU */  /* Output share capability set */
527  BOOL rdp_io_pointer_pdu(STREAM s, RDP_POINTER_PDU *ptr)  static void
528    rdp_out_share_caps(STREAM s)
529  {  {
530          BOOL res = True;          out_uint16_le(s, RDP_CAPSET_SHARE);
531            out_uint16_le(s, RDP_CAPLEN_SHARE);
         res = res ? lsb_io_uint16(s, &ptr->message) : False;  
         res = res ? lsb_io_uint16(s, &ptr->pad    ) : False;  
   
         switch (ptr->message)  
         {  
                 case RDP_POINTER_MOVE:  
                         res = res ? lsb_io_uint16(s, &ptr->x      ) : False;  
                         res = res ? lsb_io_uint16(s, &ptr->y      ) : False;  
                         break;  
         }  
532    
533          return res;          out_uint16(s, 0);       /* userid */
534            out_uint16(s, 0);       /* pad */
535  }  }
536    
537  /* Parse an update PDU */  /* Output colour cache capability set */
538  BOOL rdp_io_update_pdu(STREAM s, RDP_UPDATE_PDU *pdu)  static void
539    rdp_out_colcache_caps(STREAM s)
540  {  {
541          BOOL res = True;          out_uint16_le(s, RDP_CAPSET_COLCACHE);
542            out_uint16_le(s, RDP_CAPLEN_COLCACHE);
         res = res ? lsb_io_uint16(s, &pdu->update_type) : False;  
         res = res ? lsb_io_uint16(s, &pdu->pad        ) : False;  
543    
544          return res;          out_uint16_le(s, 6);    /* cache size */
545            out_uint16(s, 0);       /* pad */
546  }  }
547    
548    static uint8 canned_caps[] = {
549            0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, 0x04,
550            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00,
551            0x00, 0x00, 0x00, 0x00, 0x00,
552            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
553            0x00, 0x00, 0x00, 0x00, 0x00,
554            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
555            0x00, 0x00, 0x00, 0x00, 0x00,
556            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
557            0x00, 0x00, 0x00, 0x00, 0x00,
558            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
559            0x0C, 0x00, 0x08, 0x00, 0x01,
560            0x00, 0x00, 0x00, 0x0E, 0x00, 0x08, 0x00, 0x01, 0x00, 0x00, 0x00,
561            0x10, 0x00, 0x34, 0x00, 0xFE,
562            0x00, 0x04, 0x00, 0xFE, 0x00, 0x04, 0x00, 0xFE, 0x00, 0x08, 0x00,
563            0xFE, 0x00, 0x08, 0x00, 0xFE,
564            0x00, 0x10, 0x00, 0xFE, 0x00, 0x20, 0x00, 0xFE, 0x00, 0x40, 0x00,
565            0xFE, 0x00, 0x80, 0x00, 0xFE,
566            0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x08, 0x00, 0x01, 0x00, 0x01,
567            0x02, 0x00, 0x00, 0x00
568    };
569    
570  /* PRIMARY ORDERS */  /* Output unknown capability sets (number 13, 12, 14 and 16) */
571    static void
572  /* Parse an destination blt order */  rdp_out_unknown_caps(STREAM s)
 BOOL rdp_io_destblt_order(STREAM s, DESTBLT_ORDER *os, uint32 present, BOOL delta)  
573  {  {
574          if (present & 0x01)          out_uint16_le(s, RDP_CAPSET_UNKNOWN);
575                  rdp_io_coord(s, &os->x, delta);          out_uint16_le(s, 0x58);
   
         if (present & 0x02)  
                 rdp_io_coord(s, &os->y, delta);  
576    
577          if (present & 0x04)          out_uint8p(s, canned_caps, RDP_CAPLEN_UNKNOWN - 4);
                 rdp_io_coord(s, &os->cx, delta);  
   
         if (present & 0x08)  
                 rdp_io_coord(s, &os->cy, delta);  
   
         if (present & 0x10)  
                 prs_io_uint8(s, &os->opcode);  
   
         return PRS_ERROR(s);  
578  }  }
579    
580  /* Parse an pattern blt order */  #define RDP5_FLAG 0x0030
581  BOOL rdp_io_patblt_order(STREAM s, PATBLT_ORDER *os, uint32 present, BOOL delta)  /* Send a confirm active PDU */
582    static void
583    rdp_send_confirm_active(void)
584  {  {
585          if (present & 0x0001)          STREAM s;
586                  rdp_io_coord(s, &os->x, delta);          uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG;
587            uint16 caplen =
588                    RDP_CAPLEN_GENERAL + RDP_CAPLEN_BITMAP + RDP_CAPLEN_ORDER +
589                    RDP_CAPLEN_BMPCACHE + RDP_CAPLEN_COLCACHE +
590                    RDP_CAPLEN_ACTIVATE + RDP_CAPLEN_CONTROL +
591                    RDP_CAPLEN_POINTER + RDP_CAPLEN_SHARE + RDP_CAPLEN_UNKNOWN + 4 /* w2k fix, why? */ ;
592    
593          if (present & 0x0002)          s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE));
                 rdp_io_coord(s, &os->y, delta);  
594    
595          if (present & 0x0004)          out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE));
596                  rdp_io_coord(s, &os->cx, delta);          out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10));      /* Version 1 */
597            out_uint16_le(s, (g_mcs_userid + 1001));
598    
599          if (present & 0x0008)          out_uint32_le(s, g_rdp_shareid);
600                  rdp_io_coord(s, &os->cy, delta);          out_uint16_le(s, 0x3ea);        /* userid */
601            out_uint16_le(s, sizeof(RDP_SOURCE));
602            out_uint16_le(s, caplen);
603    
604          if (present & 0x0010)          out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE));
605                  prs_io_uint8(s, &os->opcode);          out_uint16_le(s, 0xd);  /* num_caps */
606            out_uint8s(s, 2);       /* pad */
607    
608          if (present & 0x0020)          rdp_out_general_caps(s);
609                  rdp_io_colour(s, &os->bgcolour);          rdp_out_bitmap_caps(s);
610            rdp_out_order_caps(s);
611            rdp_out_bmpcache_caps(s);
612            rdp_out_colcache_caps(s);
613            rdp_out_activate_caps(s);
614            rdp_out_control_caps(s);
615            rdp_out_pointer_caps(s);
616            rdp_out_share_caps(s);
617            rdp_out_unknown_caps(s);
618    
619          if (present & 0x0040)          s_mark_end(s);
620                  rdp_io_colour(s, &os->fgcolour);          sec_send(s, sec_flags);
   
         rdp_io_brush(s, &os->brush, present >> 7);  
   
         return PRS_ERROR(s);  
621  }  }
622    
623  /* Parse an screen blt order */  /* Process a general capability set */
624  BOOL rdp_io_screenblt_order(STREAM s, SCREENBLT_ORDER *os, uint32 present, BOOL delta)  static void
625    rdp_process_general_caps(STREAM s)
626  {  {
627          if (present & 0x0001)          uint16 pad2octetsB;     /* rdp5 flags? */
                 rdp_io_coord(s, &os->x, delta);  
   
         if (present & 0x0002)  
                 rdp_io_coord(s, &os->y, delta);  
628    
629          if (present & 0x0004)          in_uint8s(s, 10);
630                  rdp_io_coord(s, &os->cx, delta);          in_uint16_le(s, pad2octetsB);
631    
632          if (present & 0x0008)          if (!pad2octetsB)
633                  rdp_io_coord(s, &os->cy, delta);                  g_use_rdp5 = False;
   
         if (present & 0x0010)  
                 prs_io_uint8(s, &os->opcode);  
   
         if (present & 0x0020)  
                 rdp_io_coord(s, &os->srcx, delta);  
   
         if (present & 0x0040)  
                 rdp_io_coord(s, &os->srcy, delta);  
   
         return PRS_ERROR(s);  
634  }  }
635    
636  /* Parse a line order */  /* Process a bitmap capability set */
637  BOOL rdp_io_line_order(STREAM s, LINE_ORDER *os, uint32 present, BOOL delta)  static void
638    rdp_process_bitmap_caps(STREAM s)
639  {  {
640          if (present & 0x0001)          uint16 width, height, bpp;
                 lsb_io_uint16(s, &os->mixmode);  
   
         if (present & 0x0002)  
                 rdp_io_coord(s, &os->startx, delta);  
   
         if (present & 0x0004)  
                 rdp_io_coord(s, &os->starty, delta);  
   
         if (present & 0x0008)  
                 rdp_io_coord(s, &os->endx, delta);  
641    
642          if (present & 0x0010)          in_uint16_le(s, bpp);
643                  rdp_io_coord(s, &os->endy, delta);          in_uint8s(s, 6);
644    
645          if (present & 0x0020)          in_uint16_le(s, width);
646                  rdp_io_colour(s, &os->bgcolour);          in_uint16_le(s, height);
647    
648          if (present & 0x0040)          DEBUG(("setting desktop size and bpp to: %dx%dx%d\n", width, height, bpp));
                 prs_io_uint8(s, &os->opcode);  
649    
650          rdp_io_pen(s, &os->pen, present >> 7);          /*
651             * The server may limit bpp and change the size of the desktop (for
652          return PRS_ERROR(s);           * example when shadowing another session).
653             */
654            if (g_server_bpp != bpp)
655            {
656                    warning("colour depth changed from %d to %d\n", g_server_bpp, bpp);
657                    g_server_bpp = bpp;
658            }
659            if (g_width != width || g_height != height)
660            {
661                    warning("screen size changed from %dx%d to %dx%d\n", g_width, g_height,
662                            width, height);
663                    g_width = width;
664                    g_height = height;
665                    ui_resize_window();
666            }
667  }  }
668    
669  /* Parse an opaque rectangle order */  /* Respond to a demand active PDU */
670  BOOL rdp_io_rect_order(STREAM s, RECT_ORDER *os, uint32 present, BOOL delta)  static void
671    process_demand_active(STREAM s)
672  {  {
673          if (present & 0x01)          int n;
674                  rdp_io_coord(s, &os->x, delta);          uint8 type, *next;
675            uint16 len_src_descriptor, len_combined_caps, num_capsets, capset_type, capset_length;
         if (present & 0x02)  
                 rdp_io_coord(s, &os->y, delta);  
676    
677          if (present & 0x04)          in_uint32_le(s, g_rdp_shareid);
678                  rdp_io_coord(s, &os->cx, delta);          in_uint16_le(s, len_src_descriptor);
679            in_uint16_le(s, len_combined_caps);
680            in_uint8s(s, len_src_descriptor);
681    
682          if (present & 0x08)          in_uint16_le(s, num_capsets);
683                  rdp_io_coord(s, &os->cy, delta);          in_uint8s(s, 2);        /* pad */
684    
685          if (present & 0x10)          DEBUG(("DEMAND_ACTIVE(id=0x%x,num_caps=%d)\n", g_rdp_shareid, num_capsets));
                 prs_io_uint8(s, &os->colour);  
686    
687          return PRS_ERROR(s);          for (n = 0; n < num_capsets; n++)
688  }          {
689                    in_uint16_le(s, capset_type);
690  /* Parse a desktop save order */                  in_uint16_le(s, capset_length);
 BOOL rdp_io_desksave_order(STREAM s, DESKSAVE_ORDER *os, uint32 present, BOOL delta)  
 {  
         if (present & 0x01)  
                 lsb_io_uint32(s, &os->offset);  
   
         if (present & 0x02)  
                 rdp_io_coord(s, &os->left, delta);  
691    
692          if (present & 0x04)                  next = s->p + capset_length - 4;
                 rdp_io_coord(s, &os->top, delta);  
693    
694          if (present & 0x08)                  switch (capset_type)
695                  rdp_io_coord(s, &os->right, delta);                  {
696                            case RDP_CAPSET_GENERAL:
697                                    rdp_process_general_caps(s);
698                                    break;
699    
700          if (present & 0x10)                          case RDP_CAPSET_BITMAP:
701                  rdp_io_coord(s, &os->bottom, delta);                                  rdp_process_bitmap_caps(s);
702                                    break;
703                    }
704    
705          if (present & 0x20)                  s->p = next;
706                  prs_io_uint8(s, &os->action);          }
707    
708          return PRS_ERROR(s);          rdp_send_confirm_active();
709  }          rdp_send_synchronise();
710            rdp_send_control(RDP_CTL_COOPERATE);
711            rdp_send_control(RDP_CTL_REQUEST_CONTROL);
712            rdp_recv(&type);        /* RDP_PDU_SYNCHRONIZE */
713            rdp_recv(&type);        /* RDP_CTL_COOPERATE */
714            rdp_recv(&type);        /* RDP_CTL_GRANT_CONTROL */
715            rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0);
716    
717  /* Parse a memory blt order */          if (g_use_rdp5)
 BOOL rdp_io_memblt_order(STREAM s, MEMBLT_ORDER *os, uint32 present, BOOL delta)  
 {  
         if (present & 0x0001)  
718          {          {
719                  prs_io_uint8(s, &os->cache_id);                  rdp_send_fonts(3);
                 prs_io_uint8(s, &os->colour_table);  
720          }          }
721            else
         if (present & 0x0002)  
                 rdp_io_coord(s, &os->x, delta);  
   
         if (present & 0x0004)  
                 rdp_io_coord(s, &os->y, delta);  
   
         if (present & 0x0008)  
                 rdp_io_coord(s, &os->cx, delta);  
   
         if (present & 0x0010)  
                 rdp_io_coord(s, &os->cy, delta);  
   
         if (present & 0x0020)  
                 prs_io_uint8(s, &os->opcode);  
   
         if (present & 0x0040)  
                 rdp_io_coord(s, &os->srcx, delta);  
   
         if (present & 0x0080)  
                 rdp_io_coord(s, &os->srcy, delta);  
   
         if (present & 0x0100)  
                 lsb_io_uint16(s, &os->cache_idx);  
   
         return PRS_ERROR(s);  
 }  
   
 /* Parse a 3-way blt order */  
 BOOL rdp_io_triblt_order(STREAM s, TRIBLT_ORDER *os, uint32 present, BOOL delta)  
 {  
         if (present & 0x000001)  
722          {          {
723                  prs_io_uint8(s, &os->cache_id);                  rdp_send_fonts(1);
724                  prs_io_uint8(s, &os->colour_table);                  rdp_send_fonts(2);
725          }          }
726    
727          if (present & 0x000002)          rdp_recv(&type);        /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */
728                  rdp_io_coord(s, &os->x, delta);          reset_order_state();
   
         if (present & 0x000004)  
                 rdp_io_coord(s, &os->y, delta);  
   
         if (present & 0x000008)  
                 rdp_io_coord(s, &os->cx, delta);  
   
         if (present & 0x000010)  
                 rdp_io_coord(s, &os->cy, delta);  
   
         if (present & 0x000020)  
                 prs_io_uint8(s, &os->opcode);  
   
         if (present & 0x000040)  
                 rdp_io_coord(s, &os->srcx, delta);  
   
         if (present & 0x000080)  
                 rdp_io_coord(s, &os->srcy, delta);  
   
         if (present & 0x000100)  
                 rdp_io_colour(s, &os->bgcolour);  
   
         if (present & 0x000200)  
                 rdp_io_colour(s, &os->fgcolour);  
   
         rdp_io_brush(s, &os->brush, present >> 10);  
   
         if (present & 0x008000)  
                 lsb_io_uint16(s, &os->cache_idx);  
   
         if (present & 0x010000)  
                 lsb_io_uint16(s, &os->unknown);  
   
         return PRS_ERROR(s);  
729  }  }
730    
731  /* Parse a text order */  /* Process a colour pointer PDU */
732  BOOL rdp_io_text2_order(STREAM s, TEXT2_ORDER *os, uint32 present, BOOL delta)  void
733    process_colour_pointer_pdu(STREAM s)
734  {  {
735          if (present & 0x000001)          uint16 x, y, width, height, cache_idx, masklen, datalen;
736                  prs_io_uint8(s, &os->font);          uint8 *mask, *data;
737            HCURSOR cursor;
         if (present & 0x000002)  
                 prs_io_uint8(s, &os->flags);  
   
         if (present & 0x000004)  
                 prs_io_uint8(s, &os->unknown);  
738    
739          if (present & 0x000008)          in_uint16_le(s, cache_idx);
740                  prs_io_uint8(s, &os->mixmode);          in_uint16_le(s, x);
741            in_uint16_le(s, y);
742          if (present & 0x000010)          in_uint16_le(s, width);
743                  rdp_io_colour(s, &os->fgcolour);          in_uint16_le(s, height);
744            in_uint16_le(s, masklen);
745            in_uint16_le(s, datalen);
746            in_uint8p(s, data, datalen);
747            in_uint8p(s, mask, masklen);
748            cursor = ui_create_cursor(x, y, width, height, mask, data);
749            ui_set_cursor(cursor);
750            cache_put_cursor(cache_idx, cursor);
751    }
752    
753          if (present & 0x000020)  /* Process a cached pointer PDU */
754                  rdp_io_colour(s, &os->bgcolour);  void
755    process_cached_pointer_pdu(STREAM s)
756    {
757            uint16 cache_idx;
758    
759          if (present & 0x000040)          in_uint16_le(s, cache_idx);
760                  lsb_io_uint16(s, &os->clipleft);          ui_set_cursor(cache_get_cursor(cache_idx));
761    }
762    
763          if (present & 0x000080)  /* Process a system pointer PDU */
764                  lsb_io_uint16(s, &os->cliptop);  void
765    process_system_pointer_pdu(STREAM s)
766    {
767            uint16 system_pointer_type;
768    
769          if (present & 0x000100)          in_uint16(s, system_pointer_type);
770                  lsb_io_uint16(s, &os->clipright);          switch (system_pointer_type)
771            {
772                    case RDP_NULL_POINTER:
773                            ui_set_null_cursor();
774                            break;
775    
776          if (present & 0x000200)                  default:
777                  lsb_io_uint16(s, &os->clipbottom);                          unimpl("System pointer message 0x%x\n", system_pointer_type);
778            }
779    }
780    
781          if (present & 0x000400)  /* Process a pointer PDU */
782                  lsb_io_uint16(s, &os->boxleft);  static void
783    process_pointer_pdu(STREAM s)
784    {
785            uint16 message_type;
786            uint16 x, y;
787    
788          if (present & 0x000800)          in_uint16_le(s, message_type);
789                  lsb_io_uint16(s, &os->boxtop);          in_uint8s(s, 2);        /* pad */
790    
791          if (present & 0x001000)          switch (message_type)
792                  lsb_io_uint16(s, &os->boxright);          {
793                    case RDP_POINTER_MOVE:
794                            in_uint16_le(s, x);
795                            in_uint16_le(s, y);
796                            if (s_check(s))
797                                    ui_move_pointer(x, y);
798                            break;
799    
800          if (present & 0x002000)                  case RDP_POINTER_COLOR:
801                  lsb_io_uint16(s, &os->boxbottom);                          process_colour_pointer_pdu(s);
802                            break;
803    
804          if (present & 0x080000)                  case RDP_POINTER_CACHED:
805                  lsb_io_uint16(s, &os->x);                          process_cached_pointer_pdu(s);
806                            break;
807    
808          if (present & 0x100000)                  case RDP_POINTER_SYSTEM:
809                  lsb_io_uint16(s, &os->y);                          process_system_pointer_pdu(s);
810                            break;
811    
812          if (present & 0x200000)                  default:
813          {                          unimpl("Pointer message 0x%x\n", message_type);
                 prs_io_uint8(s, &os->length);  
                 prs_io_uint8s(s, os->text, os->length);  
814          }          }
   
         return PRS_ERROR(s);  
815  }  }
816    
817    /* Process bitmap updates */
818  /* SECONDARY ORDERS */  void
819    process_bitmap_updates(STREAM s)
 BOOL rdp_io_secondary_order(STREAM s, RDP_SECONDARY_ORDER *rso)  
820  {  {
821          BOOL res = True;          uint16 num_updates;
822            uint16 left, top, right, bottom, width, height;
823          res = res ? lsb_io_uint16(s, &rso->length) : False;          uint16 cx, cy, bpp, Bpp, compress, bufsize, size;
824          res = res ? lsb_io_uint16(s, &rso->flags ) : False;          uint8 *data, *bmpdata;
825          res = res ? prs_io_uint8 (s, &rso->type  ) : False;          int i;
   
         return res;  
 }  
826    
827  BOOL rdp_io_raw_bmpcache_order(STREAM s, RDP_RAW_BMPCACHE_ORDER *rbo)          in_uint16_le(s, num_updates);
 {  
         BOOL res = True;  
828    
829          res = res ? prs_io_uint8 (s, &rbo->cache_id  ) : False;          for (i = 0; i < num_updates; i++)
830          res = res ? prs_io_uint8 (s, &rbo->pad1      ) : False;          {
831          res = res ? prs_io_uint8 (s, &rbo->width     ) : False;                  in_uint16_le(s, left);
832          res = res ? prs_io_uint8 (s, &rbo->height    ) : False;                  in_uint16_le(s, top);
833          res = res ? prs_io_uint8 (s, &rbo->bpp       ) : False;                  in_uint16_le(s, right);
834          res = res ? lsb_io_uint16(s, &rbo->bufsize   ) : False;                  in_uint16_le(s, bottom);
835          res = res ? lsb_io_uint16(s, &rbo->cache_idx ) : False;                  in_uint16_le(s, width);
836                    in_uint16_le(s, height);
837                    in_uint16_le(s, bpp);
838                    Bpp = (bpp + 7) / 8;
839                    in_uint16_le(s, compress);
840                    in_uint16_le(s, bufsize);
841    
842          rbo->data = s->data + s->offset;                  cx = right - left + 1;
843          s->offset += rbo->bufsize;                  cy = bottom - top + 1;
844    
845          return res;                  DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n",
846  }                         left, top, right, bottom, width, height, Bpp, compress));
847    
848  BOOL rdp_io_bmpcache_order(STREAM s, RDP_BMPCACHE_ORDER *rbo)                  if (!compress)
849  {                  {
850          BOOL res = True;                          int y;
851                            bmpdata = (uint8 *) xmalloc(width * height * Bpp);
852                            for (y = 0; y < height; y++)
853                            {
854                                    in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)],
855                                              width * Bpp);
856                            }
857                            ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
858                            xfree(bmpdata);
859                            continue;
860                    }
861    
         res = res ? prs_io_uint8 (s, &rbo->cache_id  ) : False;  
         res = res ? prs_io_uint8 (s, &rbo->pad1      ) : False;  
         res = res ? prs_io_uint8 (s, &rbo->width     ) : False;  
         res = res ? prs_io_uint8 (s, &rbo->height    ) : False;  
         res = res ? prs_io_uint8 (s, &rbo->bpp       ) : False;  
         res = res ? lsb_io_uint16(s, &rbo->bufsize   ) : False;  
         res = res ? lsb_io_uint16(s, &rbo->cache_idx ) : False;  
         res = res ? lsb_io_uint16(s, &rbo->pad2      ) : False;  
         res = res ? lsb_io_uint16(s, &rbo->size      ) : False;  
         res = res ? lsb_io_uint16(s, &rbo->row_size  ) : False;  
         res = res ? lsb_io_uint16(s, &rbo->final_size) : False;  
862    
863          rbo->data = s->data + s->offset;                  if (compress & 0x400)
864          s->offset += rbo->size;                  {
865                            size = bufsize;
866                    }
867                    else
868                    {
869                            in_uint8s(s, 2);        /* pad */
870                            in_uint16_le(s, size);
871                            in_uint8s(s, 4);        /* line_size, final_size */
872                    }
873                    in_uint8p(s, data, size);
874                    bmpdata = (uint8 *) xmalloc(width * height * Bpp);
875                    if (bitmap_decompress(bmpdata, width, height, data, size, Bpp))
876                    {
877                            ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata);
878                    }
879                    else
880                    {
881                            DEBUG_RDP5(("Failed to decompress data\n"));
882                    }
883    
884          return res;                  xfree(bmpdata);
885            }
886  }  }
887    
888  BOOL rdp_io_colcache_order(STREAM s, RDP_COLCACHE_ORDER *colours)  /* Process a palette update */
889    void
890    process_palette(STREAM s)
891  {  {
892          COLOURENTRY *entry;          COLOURENTRY *entry;
893            COLOURMAP map;
894            HCOLOURMAP hmap;
895          int i;          int i;
896    
897          prs_io_uint8(s, &colours->cache_id);          in_uint8s(s, 2);        /* pad */
898          lsb_io_uint16(s, &colours->map.ncolours);          in_uint16_le(s, map.ncolours);
899            in_uint8s(s, 2);        /* pad */
900    
901            map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours);
902    
903          for (i = 0; i < colours->map.ncolours; i++)          DEBUG(("PALETTE(c=%d)\n", map.ncolours));
904    
905            for (i = 0; i < map.ncolours; i++)
906          {          {
907                  entry = &colours->map.colours[i];                  entry = &map.colours[i];
908                  prs_io_uint8(s, &entry->blue);                  in_uint8(s, entry->red);
909                  prs_io_uint8(s, &entry->green);                  in_uint8(s, entry->green);
910                  prs_io_uint8(s, &entry->red);                  in_uint8(s, entry->blue);
                 s->offset++;  
911          }          }
912    
913          return True;          hmap = ui_create_colourmap(&map);
914  }          ui_set_colourmap(hmap);
915    
916  BOOL rdp_io_fontcache_order(STREAM s, RDP_FONTCACHE_ORDER *font)          xfree(map.colours);
 {  
         RDP_FONT_GLYPH *glyph;  
         BOOL res = True;  
         int i, j, datasize;  
         uint8 in, out;  
   
         res = res ? prs_io_uint8(s, &font->font   ) : False;  
         res = res ? prs_io_uint8(s, &font->nglyphs) : False;  
   
         for (i = 0; i < font->nglyphs; i++)  
         {  
                 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++)  
                 {  
                         in = glyph->data[j];  
                         out = 0;  
                         if (in & 1) out |= 128;  
                         if (in & 2) out |= 64;  
                         if (in & 4) out |= 32;  
                         if (in & 8) out |= 16;  
                         if (in & 16) out |= 8;  
                         if (in & 32) out |= 4;  
                         if (in & 64) out |= 2;  
                         if (in & 128) out |= 1;  
                         glyph->data[j] = out;  
                 }  
         }  
   
         return res;  
917  }  }
918    
919    /* Process an update PDU */
920  /* CAPABILITIES */  static void
921    process_update_pdu(STREAM s)
 /* Construct a general capability set */  
 void rdp_make_general_caps(RDP_GENERAL_CAPS *caps)  
922  {  {
923          caps->os_major_type = 1;          uint16 update_type, count;
         caps->os_minor_type = 3;  
         caps->ver_protocol = 0x200;  
 }  
924    
925  /* Parse general capability set */          in_uint16_le(s, update_type);
 BOOL rdp_io_general_caps(STREAM s, RDP_GENERAL_CAPS *caps)  
 {  
         uint16 length = RDP_CAPLEN_GENERAL;  
         uint16 pkt_length = length;  
         BOOL res;  
926    
927          res = lsb_io_uint16(s, &pkt_length);          ui_begin_update();
928          if (pkt_length != length)          switch (update_type)
929          {          {
930                  ERROR("Unrecognised capabilities size\n");                  case RDP_UPDATE_ORDERS:
931                  return False;                          in_uint8s(s, 2);        /* pad */
932          }                          in_uint16_le(s, count);
933                            in_uint8s(s, 2);        /* pad */
934                            process_orders(s, count);
935                            break;
936    
937          res = res ? lsb_io_uint16(s, &caps->os_major_type ) : False;                  case RDP_UPDATE_BITMAP:
938          res = res ? lsb_io_uint16(s, &caps->os_minor_type ) : False;                          process_bitmap_updates(s);
939          res = res ? lsb_io_uint16(s, &caps->ver_protocol  ) : False;                          break;
         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;  
940    
941          res = lsb_io_uint16(s, &pkt_length);                  case RDP_UPDATE_PALETTE:
942          if (pkt_length != length)                          process_palette(s);
943          {                          break;
                 ERROR("Unrecognised capabilities size\n");  
                 return False;  
         }  
944    
945          res = res ? lsb_io_uint16(s, &caps->preferred_bpp) : False;                  case RDP_UPDATE_SYNCHRONIZE:
946          res = res ? lsb_io_uint16(s, &caps->receive1bpp  ) : False;                          break;
         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;  
947    
948          res = lsb_io_uint16(s, &pkt_length);                  default:
949          if (pkt_length != length)                          unimpl("update %d\n", update_type);
         {  
                 ERROR("Unrecognised capabilities size\n");  
                 return False;  
950          }          }
951            ui_end_update();
         res = res ? prs_io_uint8s(s,  caps->terminal_desc, 16) : False;  
         res = res ? lsb_io_uint32(s, &caps->pad1             ) : False;  
         res = res ? lsb_io_uint16(s, &caps->xgranularity     ) : False;  
         res = res ? lsb_io_uint16(s, &caps->ygranularity     ) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad2             ) : False;  
         res = res ? lsb_io_uint16(s, &caps->max_order_level  ) : False;  
         res = res ? lsb_io_uint16(s, &caps->num_fonts        ) : False;  
         res = res ? lsb_io_uint16(s, &caps->cap_flags        ) : False;  
         res = res ? prs_io_uint8s(s,  caps->support      , 32) : False;  
         res = res ? lsb_io_uint16(s, &caps->text_cap_flags   ) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad3             ) : False;  
         res = res ? lsb_io_uint32(s, &caps->pad4             ) : False;  
         res = res ? lsb_io_uint32(s, &caps->desk_save_size   ) : False;  
         res = res ? lsb_io_uint32(s, &caps->unknown1         ) : False;  
         res = res ? lsb_io_uint32(s, &caps->unknown2         ) : False;  
   
         return res;  
 }  
   
 /* 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;  
952  }  }
953    
954  /* Parse single bitmap cache information structure */  /* Process a disconnect PDU */
955  BOOL rdp_io_bmpcache_info(STREAM s, RDP_BMPCACHE_INFO *info)  void
956    process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason)
957  {  {
958          if (!lsb_io_uint16(s, &info->entries      ))          in_uint32_le(s, *ext_disc_reason);
                 return False;  
   
         if (!lsb_io_uint16(s, &info->max_cell_size))  
                 return False;  
959    
960          return True;          DEBUG(("Received disconnect PDU\n"));
961  }  }
962    
963  /* Parse bitmap cache capability set */  /* Process data PDU */
964  BOOL rdp_io_bmpcache_caps(STREAM s, RDP_BMPCACHE_CAPS *caps)  static BOOL
965    process_data_pdu(STREAM s, uint32 * ext_disc_reason)
966  {  {
967          uint16 length = RDP_CAPLEN_BMPCACHE;          uint8 data_pdu_type;
968          uint16 pkt_length = length;          uint8 ctype;
969          BOOL res;          uint16 clen;
970          int i;          uint32 len;
971    
972          res = lsb_io_uint16(s, &pkt_length);          uint32 roff, rlen;
973          if (pkt_length != length)  
974            struct stream *ns = &(g_mppc_dict.ns);
975    
976            in_uint8s(s, 6);        /* shareid, pad, streamid */
977            in_uint16(s, len);
978            in_uint8(s, data_pdu_type);
979            in_uint8(s, ctype);
980            in_uint16(s, clen);
981            clen -= 18;
982    
983            if (ctype & RDP_MPPC_COMPRESSED)
984          {          {
                 ERROR("Unrecognised capabilities size\n");  
                 return False;  
         }  
985    
986          for (i = 0; i < 6; i++)                  if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1)
987                  res = res ? lsb_io_uint32(s, &caps->unused[i]) : False;                          error("error while decompressing packet\n");
988    
989          for (i = 0; i < 3; i++)                  //len -= 18;
                 res = res ? rdp_io_bmpcache_info(s, &caps->caches[i]) : False;  
990    
991          return res;                  /* allocate memory and copy the uncompressed data into the temporary stream */
992  }                  ns->data = (uint8 *) xrealloc(ns->data, rlen);
993    
994  /* Construct a control capability set */                  memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen);
 void rdp_make_control_caps(RDP_CONTROL_CAPS *caps)  
 {  
         caps->control_interest = 2;  
         caps->detach_interest = 2;  
 }  
995    
996  /* Parse control capability set */                  ns->size = rlen;
997  BOOL rdp_io_control_caps(STREAM s, RDP_CONTROL_CAPS *caps)                  ns->end = (ns->data + ns->size);
998  {                  ns->p = ns->data;
999          uint16 length = RDP_CAPLEN_CONTROL;                  ns->rdp_hdr = ns->p;
         uint16 pkt_length = length;  
         BOOL res;  
1000    
1001          res = lsb_io_uint16(s, &pkt_length);                  s = ns;
         if (pkt_length != length)  
         {  
                 ERROR("Unrecognised capabilities size\n");  
                 return False;  
1002          }          }
1003    
1004          res = res ? lsb_io_uint16(s, &caps->control_caps    ) : False;          switch (data_pdu_type)
1005          res = res ? lsb_io_uint16(s, &caps->remote_detach   ) : False;          {
1006          res = res ? lsb_io_uint16(s, &caps->control_interest) : False;                  case RDP_DATA_PDU_UPDATE:
1007          res = res ? lsb_io_uint16(s, &caps->detach_interest ) : False;                          process_update_pdu(s);
1008                            break;
1009    
1010          return res;                  case RDP_DATA_PDU_CONTROL:
1011  }                          DEBUG(("Received Control PDU\n"));
1012                            break;
1013    
1014  /* Construct an activation capability set */                  case RDP_DATA_PDU_SYNCHRONISE:
1015  void rdp_make_activate_caps(RDP_ACTIVATE_CAPS *caps)                          DEBUG(("Received Sync PDU\n"));
1016  {                          break;
 }  
1017    
1018  /* Parse activation capability set */                  case RDP_DATA_PDU_POINTER:
1019  BOOL rdp_io_activate_caps(STREAM s, RDP_ACTIVATE_CAPS *caps)                          process_pointer_pdu(s);
1020  {                          break;
         uint16 length = RDP_CAPLEN_ACTIVATE;  
         uint16 pkt_length = length;  
         BOOL res;  
1021    
1022          res = lsb_io_uint16(s, &pkt_length);                  case RDP_DATA_PDU_BELL:
1023          if (pkt_length != length)                          ui_bell();
1024          {                          break;
                 ERROR("Unrecognised capabilities size\n");  
                 return False;  
         }  
1025    
1026          res = res ? lsb_io_uint16(s, &caps->help_key         ) : False;                  case RDP_DATA_PDU_LOGON:
1027          res = res ? lsb_io_uint16(s, &caps->help_index_key   ) : False;                          DEBUG(("Received Logon PDU\n"));
1028          res = res ? lsb_io_uint16(s, &caps->help_extended_key) : False;                          /* User logged on */
1029          res = res ? lsb_io_uint16(s, &caps->window_activate  ) : False;                          break;
1030    
1031          return res;                  case RDP_DATA_PDU_DISCONNECT:
1032  }                          process_disconnect_pdu(s, ext_disc_reason);
1033                            return True;
1034    
1035  /* Construct a pointer capability set */                  default:
1036  void rdp_make_pointer_caps(RDP_POINTER_CAPS *caps)                          unimpl("data PDU %d\n", data_pdu_type);
1037  {          }
1038          caps->colour_pointer = 0;          return False;
         caps->cache_size = 20;  
1039  }  }
1040    
1041  /* Parse pointer capability set */  /* Process incoming packets */
1042  BOOL rdp_io_pointer_caps(STREAM s, RDP_POINTER_CAPS *caps)  void
1043    rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1044  {  {
1045          uint16 length = RDP_CAPLEN_POINTER;          uint8 type;
1046          uint16 pkt_length = length;          BOOL disc = False;      /* True when a disconnect PDU was received */
1047          BOOL res;          STREAM s;
1048    
1049          res = lsb_io_uint16(s, &pkt_length);          while ((s = rdp_recv(&type)) != NULL)
         if (pkt_length != length)  
1050          {          {
1051                  ERROR("Unrecognised capabilities size\n");                  switch (type)
1052                  return False;                  {
1053          }                          case RDP_PDU_DEMAND_ACTIVE:
1054                                    process_demand_active(s);
1055                                    *deactivated = False;
1056                                    break;
1057    
1058          res = res ? lsb_io_uint16(s, &caps->colour_pointer) : False;                          case RDP_PDU_DEACTIVATE:
1059          res = res ? lsb_io_uint16(s, &caps->cache_size    ) : False;                                  DEBUG(("RDP_PDU_DEACTIVATE\n"));
1060                                    *deactivated = True;
1061                                    break;
1062    
1063          return res;                          case RDP_PDU_DATA:
1064  }                                  disc = process_data_pdu(s, ext_disc_reason);
1065                                    break;
1066    
1067  /* Construct a share capability set */                          case 0:
1068  void rdp_make_share_caps(RDP_SHARE_CAPS *caps, uint16 userid)                                  break;
 {  
 }  
1069    
1070  /* Parse share capability set */                          default:
1071  BOOL rdp_io_share_caps(STREAM s, RDP_SHARE_CAPS *caps)                                  unimpl("PDU %d\n", type);
1072  {                  }
         uint16 length = RDP_CAPLEN_SHARE;  
         uint16 pkt_length = length;  
         BOOL res;  
1073    
1074          res = lsb_io_uint16(s, &pkt_length);                  if (disc)
1075          if (pkt_length != length)                  {
1076          {                          return;
1077                  ERROR("Unrecognised capabilities size\n");                  }
                 return False;  
1078          }          }
1079            return;
         res = res ? lsb_io_uint16(s, &caps->userid) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad   ) : False;  
   
         return res;  
1080  }  }
1081    
1082  /* Construct a colour cache capability set */  /* used in uiports, processes the rdp packets waiting */
1083  void rdp_make_colcache_caps(RDP_COLCACHE_CAPS *caps)  BOOL
1084    rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason)
1085  {  {
1086          caps->cache_size = 6;          uint8 type;
1087  }          BOOL disc = False;      /* True when a disconnect PDU was received */
1088            BOOL cont = True;
1089            STREAM s;
1090    
1091  /* Parse colour cache capability set */          while (cont)
 BOOL rdp_io_colcache_caps(STREAM s, RDP_COLCACHE_CAPS *caps)  
 {  
         uint16 length = RDP_CAPLEN_COLCACHE;  
         uint16 pkt_length = length;  
         BOOL res;  
   
         res = lsb_io_uint16(s, &pkt_length);  
         if (pkt_length != length)  
1092          {          {
1093                  ERROR("Unrecognised capabilities size\n");                  s = rdp_recv(&type);
1094                  return False;                  if (s == NULL)
1095                            return False;
1096                    switch (type)
1097                    {
1098                            case RDP_PDU_DEMAND_ACTIVE:
1099                                    process_demand_active(s);
1100                                    *deactivated = False;
1101                                    break;
1102                            case RDP_PDU_DEACTIVATE:
1103                                    DEBUG(("RDP_PDU_DEACTIVATE\n"));
1104                                    *deactivated = True;
1105                                    break;
1106                            case RDP_PDU_DATA:
1107                                    disc = process_data_pdu(s, ext_disc_reason);
1108                                    break;
1109                            case 0:
1110                                    break;
1111                            default:
1112                                    unimpl("PDU %d\n", type);
1113                    }
1114                    if (disc)
1115                            return False;
1116                    cont = g_next_packet < s->end;
1117          }          }
1118            return True;
         res = res ? lsb_io_uint16(s, &caps->cache_size) : False;  
         res = res ? lsb_io_uint16(s, &caps->pad       ) : False;  
   
         return res;  
1119  }  }
1120    
1121  uint8 canned_caps[] = {  /* Establish a connection up to the RDP layer */
1122  0x01,0x00,0x00,0x00,0x09,0x04,0x00,0x00,0x04,  BOOL
1123  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,
1124  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)  
1125  {  {
1126          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");  
1127                  return False;                  return False;
         }  
1128    
1129          res = res ? prs_io_uint8s(s, canned_caps, RDP_CAPLEN_UNKNOWN-4) : False;          rdp_send_logon_info(flags, domain, g_username, password, command, directory);
1130            return True;
1131    }
1132    
1133          return res;  /* Disconnect from the RDP layer */
1134    void
1135    rdp_disconnect(void)
1136    {
1137            sec_disconnect();
1138  }  }

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

  ViewVC Help
Powered by ViewVC 1.1.26