diff --git a/uirdesktop/mcs.c b/uirdesktop/mcs.c deleted file mode 100644 index c954d5e0..00000000 --- a/uirdesktop/mcs.c +++ /dev/null @@ -1,469 +0,0 @@ -/* -*- c-basic-offset: 8 -*- - rdesktop: A Remote Desktop Protocol client. - Protocol services - Multipoint Communications Service - Copyright (C) Matthew Chapman 1999-2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "rdesktop.h" - -uint16 g_mcs_userid; -extern VCHANNEL g_channels[]; -extern unsigned int g_num_channels; - -/* Parse an ASN.1 BER header */ -static BOOL -ber_parse_header(STREAM s, int tagval, int *length) -{ - int tag, len; - - if (tagval > 0xff) - { - in_uint16_be(s, tag); - } - else - { - in_uint8(s, tag)} - - if (tag != tagval) - { - error("expected tag %d, got %d\n", tagval, tag); - return False; - } - - in_uint8(s, len); - - if (len & 0x80) - { - len &= ~0x80; - *length = 0; - while (len--) - next_be(s, *length); - } - else - *length = len; - - return s_check(s); -} - -/* Output an ASN.1 BER header */ -static void -ber_out_header(STREAM s, int tagval, int length) -{ - if (tagval > 0xff) - { - out_uint16_be(s, tagval); - } - else - { - out_uint8(s, tagval); - } - - if (length >= 0x80) - { - out_uint8(s, 0x82); - out_uint16_be(s, length); - } - else - out_uint8(s, length); -} - -/* Output an ASN.1 BER integer */ -static void -ber_out_integer(STREAM s, int value) -{ - ber_out_header(s, BER_TAG_INTEGER, 2); - out_uint16_be(s, value); -} - -/* Output a DOMAIN_PARAMS structure (ASN.1 BER) */ -static void -mcs_out_domain_params(STREAM s, int max_channels, int max_users, int max_tokens, int max_pdusize) -{ - ber_out_header(s, MCS_TAG_DOMAIN_PARAMS, 32); - ber_out_integer(s, max_channels); - ber_out_integer(s, max_users); - ber_out_integer(s, max_tokens); - ber_out_integer(s, 1); /* num_priorities */ - ber_out_integer(s, 0); /* min_throughput */ - ber_out_integer(s, 1); /* max_height */ - ber_out_integer(s, max_pdusize); - ber_out_integer(s, 2); /* ver_protocol */ -} - -/* Parse a DOMAIN_PARAMS structure (ASN.1 BER) */ -static BOOL -mcs_parse_domain_params(STREAM s) -{ - int length; - - ber_parse_header(s, MCS_TAG_DOMAIN_PARAMS, &length); - in_uint8s(s, length); - - return s_check(s); -} - -/* Send an MCS_CONNECT_INITIAL message (ASN.1 BER) */ -static void -mcs_send_connect_initial(STREAM mcs_data) -{ - int datalen = mcs_data->end - mcs_data->data; - int length = 9 + 3 * 34 + 4 + datalen; - STREAM s; - - s = iso_init(length + 5); - - ber_out_header(s, MCS_CONNECT_INITIAL, length); - ber_out_header(s, BER_TAG_OCTET_STRING, 1); /* calling domain */ - out_uint8(s, 1); - ber_out_header(s, BER_TAG_OCTET_STRING, 1); /* called domain */ - out_uint8(s, 1); - - ber_out_header(s, BER_TAG_BOOLEAN, 1); - out_uint8(s, 0xff); /* upward flag */ - - mcs_out_domain_params(s, 34, 2, 0, 0xffff); /* target params */ - mcs_out_domain_params(s, 1, 1, 1, 0x420); /* min params */ - mcs_out_domain_params(s, 0xffff, 0xfc17, 0xffff, 0xffff); /* max params */ - - ber_out_header(s, BER_TAG_OCTET_STRING, datalen); - out_uint8p(s, mcs_data->data, datalen); - - s_mark_end(s); - iso_send(s); -} - -/* Expect a MCS_CONNECT_RESPONSE message (ASN.1 BER) */ -static BOOL -mcs_recv_connect_response(STREAM mcs_data) -{ - uint8 result; - int length; - STREAM s; - - s = iso_recv(NULL); - if (s == NULL) - return False; - - ber_parse_header(s, MCS_CONNECT_RESPONSE, &length); - - ber_parse_header(s, BER_TAG_RESULT, &length); - in_uint8(s, result); - if (result != 0) - { - error("MCS connect: %d\n", result); - return False; - } - - ber_parse_header(s, BER_TAG_INTEGER, &length); - in_uint8s(s, length); /* connect id */ - mcs_parse_domain_params(s); - - ber_parse_header(s, BER_TAG_OCTET_STRING, &length); - - sec_process_mcs_data(s); - /* - if (length > mcs_data->size) - { - error("MCS data length %d, expected %d\n", length, - mcs_data->size); - length = mcs_data->size; - } - - in_uint8a(s, mcs_data->data, length); - mcs_data->p = mcs_data->data; - mcs_data->end = mcs_data->data + length; - */ - return s_check_end(s); -} - -/* Send an EDrq message (ASN.1 PER) */ -static void -mcs_send_edrq(void) -{ - STREAM s; - - s = iso_init(5); - - out_uint8(s, (MCS_EDRQ << 2)); - out_uint16_be(s, 1); /* height */ - out_uint16_be(s, 1); /* interval */ - - s_mark_end(s); - iso_send(s); -} - -/* Send an AUrq message (ASN.1 PER) */ -static void -mcs_send_aurq(void) -{ - STREAM s; - - s = iso_init(1); - - out_uint8(s, (MCS_AURQ << 2)); - - s_mark_end(s); - iso_send(s); -} - -/* Expect a AUcf message (ASN.1 PER) */ -static BOOL -mcs_recv_aucf(uint16 * mcs_userid) -{ - uint8 opcode, result; - STREAM s; - - s = iso_recv(NULL); - if (s == NULL) - return False; - - in_uint8(s, opcode); - if ((opcode >> 2) != MCS_AUCF) - { - error("expected AUcf, got %d\n", opcode); - return False; - } - - in_uint8(s, result); - if (result != 0) - { - error("AUrq: %d\n", result); - return False; - } - - if (opcode & 2) - in_uint16_be(s, *mcs_userid); - - return s_check_end(s); -} - -/* Send a CJrq message (ASN.1 PER) */ -static void -mcs_send_cjrq(uint16 chanid) -{ - STREAM s; - - DEBUG_RDP5(("Sending CJRQ for channel #%d\n", chanid)); - - s = iso_init(5); - - out_uint8(s, (MCS_CJRQ << 2)); - out_uint16_be(s, g_mcs_userid); - out_uint16_be(s, chanid); - - s_mark_end(s); - iso_send(s); -} - -/* Expect a CJcf message (ASN.1 PER) */ -static BOOL -mcs_recv_cjcf(void) -{ - uint8 opcode, result; - STREAM s; - - s = iso_recv(NULL); - if (s == NULL) - return False; - - in_uint8(s, opcode); - if ((opcode >> 2) != MCS_CJCF) - { - error("expected CJcf, got %d\n", opcode); - return False; - } - - in_uint8(s, result); - if (result != 0) - { - error("CJrq: %d\n", result); - return False; - } - - in_uint8s(s, 4); /* mcs_userid, req_chanid */ - if (opcode & 2) - in_uint8s(s, 2); /* join_chanid */ - - return s_check_end(s); -} - -/* Initialise an MCS transport data packet */ -STREAM -mcs_init(int length) -{ - STREAM s; - - s = iso_init(length + 8); - s_push_layer(s, mcs_hdr, 8); - - return s; -} - -/* Send an MCS transport data packet to a specific channel */ -void -mcs_send_to_channel(STREAM s, uint16 channel) -{ - uint16 length; - - s_pop_layer(s, mcs_hdr); - length = s->end - s->p - 8; - length |= 0x8000; - - out_uint8(s, (MCS_SDRQ << 2)); - out_uint16_be(s, g_mcs_userid); - out_uint16_be(s, channel); - out_uint8(s, 0x70); /* flags */ - out_uint16_be(s, length); - - iso_send(s); -} - -/* Send an MCS transport data packet to the global channel */ -void -mcs_send(STREAM s) -{ - mcs_send_to_channel(s, MCS_GLOBAL_CHANNEL); -} - -/* Receive an MCS transport data packet */ -STREAM -mcs_recv(uint16 * channel, uint8 * rdpver) -{ - uint8 opcode, appid, length; - STREAM s; - - s = iso_recv(rdpver); - if (s == NULL) - return NULL; - if (rdpver != NULL) - if (*rdpver != 3) - return s; - in_uint8(s, opcode); - appid = opcode >> 2; - if (appid != MCS_SDIN) - { - if (appid != MCS_DPUM) - { - error("expected data, got %d\n", opcode); - } - return NULL; - } - in_uint8s(s, 2); /* userid */ - in_uint16_be(s, *channel); - in_uint8s(s, 1); /* flags */ - in_uint8(s, length); - if (length & 0x80) - in_uint8s(s, 1); /* second byte of length */ - return s; -} - -/* Establish a connection up to the MCS layer */ -BOOL -mcs_connect(char *server, STREAM mcs_data, char *username) -{ - unsigned int i; - - if (!iso_connect(server, username)) - return False; - - mcs_send_connect_initial(mcs_data); - if (!mcs_recv_connect_response(mcs_data)) - goto error; - - mcs_send_edrq(); - - mcs_send_aurq(); - if (!mcs_recv_aucf(&g_mcs_userid)) - goto error; - - mcs_send_cjrq((uint16) (g_mcs_userid + MCS_USERCHANNEL_BASE)); - - if (!mcs_recv_cjcf()) - goto error; - - mcs_send_cjrq(MCS_GLOBAL_CHANNEL); - if (!mcs_recv_cjcf()) - goto error; - - for (i = 0; i < g_num_channels; i++) - { - mcs_send_cjrq(g_channels[i].mcs_id); - if (!mcs_recv_cjcf()) - goto error; - } - return True; - - error: - iso_disconnect(); - return False; -} - -/* Establish a connection up to the MCS layer */ -BOOL -mcs_reconnect(char *server, STREAM mcs_data) -{ - unsigned int i; - - if (!iso_reconnect(server)) - return False; - - mcs_send_connect_initial(mcs_data); - if (!mcs_recv_connect_response(mcs_data)) - goto error; - - mcs_send_edrq(); - - mcs_send_aurq(); - if (!mcs_recv_aucf(&g_mcs_userid)) - goto error; - - mcs_send_cjrq((uint16) (g_mcs_userid + MCS_USERCHANNEL_BASE)); - - if (!mcs_recv_cjcf()) - goto error; - - mcs_send_cjrq(MCS_GLOBAL_CHANNEL); - if (!mcs_recv_cjcf()) - goto error; - - for (i = 0; i < g_num_channels; i++) - { - mcs_send_cjrq(g_channels[i].mcs_id); - if (!mcs_recv_cjcf()) - goto error; - } - return True; - - error: - iso_disconnect(); - return False; -} - -/* Disconnect from the MCS layer */ -void -mcs_disconnect(void) -{ - iso_disconnect(); -} - -/* reset the state of the mcs layer */ -void -mcs_reset_state(void) -{ - g_mcs_userid = 0; - iso_reset_state(); -} diff --git a/uirdesktop/mppc.c b/uirdesktop/mppc.c deleted file mode 100644 index cc126c15..00000000 --- a/uirdesktop/mppc.c +++ /dev/null @@ -1,380 +0,0 @@ -/* -*- c-basic-offset: 8 -*- - rdesktop: A Remote Desktop Protocol client. - Protocol services - RDP decompression - Copyright (C) Matthew Chapman 1999-2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include -#include - -#include "rdesktop.h" - -/* mppc decompression */ -/* http://www.faqs.org/rfcs/rfc2118.html */ - -/* Contacts: */ - -/* hifn contact mentioned in the faq is */ -/* Robert Friend rfriend at hifn dot com */ - -/* if you have questions regarding MPPC */ -/* our contact is */ -/* Guus Dhaeze GDhaeze at hifn dot com */ - -/* Licensing: */ - -/* decompression is alright as long as we */ -/* don't compress data */ - -/* Algorithm: */ - -/* as the rfc states the algorithm seems to */ -/* be LZ77 with a sliding buffer */ -/* that is empty at init. */ - -/* the algorithm is called LZS and is */ -/* patented for another couple of years. */ - -/* more information is available in */ -/* http://www.ietf.org/ietf/IPR/hifn-ipr-draft-friend-tls-lzs-compression.txt */ - - -RDPCOMP g_mppc_dict; - -int -mppc_expand(uint8 * data, uint32 clen, uint8 ctype, uint32 * roff, uint32 * rlen) -{ - int k, walker_len = 0, walker; - uint32 i = 0; - int next_offset, match_off; - int match_len; - int old_offset, match_bits; - BOOL big = ctype & RDP_MPPC_BIG ? True : False; - - uint8 *dict = g_mppc_dict.hist; - - if ((ctype & RDP_MPPC_COMPRESSED) == 0) - { - *roff = 0; - *rlen = clen; - return 0; - } - - if ((ctype & RDP_MPPC_RESET) != 0) - { - g_mppc_dict.roff = 0; - } - - if ((ctype & RDP_MPPC_FLUSH) != 0) - { - memset(dict, 0, RDP_MPPC_DICT_SIZE); - g_mppc_dict.roff = 0; - } - - *roff = 0; - *rlen = 0; - - walker = g_mppc_dict.roff; - - next_offset = walker; - old_offset = next_offset; - *roff = old_offset; - if (clen == 0) - return 0; - clen += i; - - do - { - if (walker_len == 0) - { - if (i >= clen) - break; - walker = data[i++] << 24; - walker_len = 8; - } - if (walker >= 0) - { - if (walker_len < 8) - { - if (i >= clen) - { - if (walker != 0) - return -1; - break; - } - walker |= (data[i++] & 0xff) << (24 - walker_len); - walker_len += 8; - } - if (next_offset >= RDP_MPPC_DICT_SIZE) - return -1; - dict[next_offset++] = (((uint32) walker) >> ((uint32) 24)); - walker <<= 8; - walker_len -= 8; - continue; - } - walker <<= 1; - /* fetch next 8-bits */ - if (--walker_len == 0) - { - if (i >= clen) - return -1; - walker = data[i++] << 24; - walker_len = 8; - } - /* literal decoding */ - if (walker >= 0) - { - if (walker_len < 8) - { - if (i >= clen) - return -1; - walker |= (data[i++] & 0xff) << (24 - walker_len); - walker_len += 8; - } - if (next_offset >= RDP_MPPC_DICT_SIZE) - return -1; - dict[next_offset++] = (uint8) (walker >> 24 | 0x80); - walker <<= 8; - walker_len -= 8; - continue; - } - - /* decode offset */ - /* length pair */ - walker <<= 1; - if (--walker_len < (big ? 3 : 2)) - { - if (i >= clen) - return -1; - walker |= (data[i++] & 0xff) << (24 - walker_len); - walker_len += 8; - } - - if (big) - { - /* offset decoding where offset len is: - -63: 11111 followed by the lower 6 bits of the value - 64-319: 11110 followed by the lower 8 bits of the value ( value - 64 ) - 320-2367: 1110 followed by lower 11 bits of the value ( value - 320 ) - 2368-65535: 110 followed by lower 16 bits of the value ( value - 2368 ) - */ - switch (((uint32) walker) >> ((uint32) 29)) - { - case 7: /* - 63 */ - for (; walker_len < 9; walker_len += 8) - { - if (i >= clen) - return -1; - walker |= (data[i++] & 0xff) << (24 - walker_len); - } - walker <<= 3; - match_off = ((uint32) walker) >> ((uint32) 26); - walker <<= 6; - walker_len -= 9; - break; - - case 6: /* 64 - 319 */ - for (; walker_len < 11; walker_len += 8) - { - if (i >= clen) - return -1; - walker |= (data[i++] & 0xff) << (24 - walker_len); - } - - walker <<= 3; - match_off = (((uint32) walker) >> ((uint32) 24)) + 64; - walker <<= 8; - walker_len -= 11; - break; - - case 5: - case 4: /* 320 - 2367 */ - for (; walker_len < 13; walker_len += 8) - { - if (i >= clen) - return -1; - walker |= (data[i++] & 0xff) << (24 - walker_len); - } - - walker <<= 2; - match_off = (((uint32) walker) >> ((uint32) 21)) + 320; - walker <<= 11; - walker_len -= 13; - break; - - default: /* 2368 - 65535 */ - for (; walker_len < 17; walker_len += 8) - { - if (i >= clen) - return -1; - walker |= (data[i++] & 0xff) << (24 - walker_len); - } - - walker <<= 1; - match_off = (((uint32) walker) >> ((uint32) 16)) + 2368; - walker <<= 16; - walker_len -= 17; - break; - } - } - else - { - /* offset decoding where offset len is: - -63: 1111 followed by the lower 6 bits of the value - 64-319: 1110 followed by the lower 8 bits of the value ( value - 64 ) - 320-8191: 110 followed by the lower 13 bits of the value ( value - 320 ) - */ - switch (((uint32) walker) >> ((uint32) 30)) - { - case 3: /* - 63 */ - if (walker_len < 8) - { - if (i >= clen) - return -1; - walker |= (data[i++] & 0xff) << (24 - walker_len); - walker_len += 8; - } - walker <<= 2; - match_off = ((uint32) walker) >> ((uint32) 26); - walker <<= 6; - walker_len -= 8; - break; - - case 2: /* 64 - 319 */ - for (; walker_len < 10; walker_len += 8) - { - if (i >= clen) - return -1; - walker |= (data[i++] & 0xff) << (24 - walker_len); - } - - walker <<= 2; - match_off = (((uint32) walker) >> ((uint32) 24)) + 64; - walker <<= 8; - walker_len -= 10; - break; - - default: /* 320 - 8191 */ - for (; walker_len < 14; walker_len += 8) - { - if (i >= clen) - return -1; - walker |= (data[i++] & 0xff) << (24 - walker_len); - } - - match_off = (walker >> 18) + 320; - walker <<= 14; - walker_len -= 14; - break; - } - } - if (walker_len == 0) - { - if (i >= clen) - return -1; - walker = data[i++] << 24; - walker_len = 8; - } - - /* decode length of match */ - match_len = 0; - if (walker >= 0) - { /* special case - length of 3 is in bit 0 */ - match_len = 3; - walker <<= 1; - walker_len--; - } - else - { - /* this is how it works len of: - 4-7: 10 followed by 2 bits of the value - 8-15: 110 followed by 3 bits of the value - 16-31: 1110 followed by 4 bits of the value - 32-63: .... and so forth - 64-127: - 128-255: - 256-511: - 512-1023: - 1024-2047: - 2048-4095: - 4096-8191: - - i.e. 4097 is encoded as: 111111111110 000000000001 - meaning 4096 + 1... - */ - match_bits = big ? 14 : 11; /* 11 or 14 bits of value at most */ - do - { - walker <<= 1; - if (--walker_len == 0) - { - if (i >= clen) - return -1; - walker = data[i++] << 24; - walker_len = 8; - } - if (walker >= 0) - break; - if (--match_bits == 0) - { - return -1; - } - } - while (1); - match_len = (big ? 16 : 13) - match_bits; - walker <<= 1; - if (--walker_len < match_len) - { - for (; walker_len < match_len; walker_len += 8) - { - if (i >= clen) - { - return -1; - } - walker |= (data[i++] & 0xff) << (24 - walker_len); - } - } - - match_bits = match_len; - match_len = - ((walker >> (32 - match_bits)) & (~(-1 << match_bits))) | (1 << - match_bits); - walker <<= match_bits; - walker_len -= match_bits; - } - if (next_offset + match_len >= RDP_MPPC_DICT_SIZE) - { - return -1; - } - /* memory areas can overlap - meaning we can't use memXXX functions */ - k = (next_offset - match_off) & (big ? 65535 : 8191); - do - { - dict[next_offset++] = dict[k++]; - } - while (--match_len != 0); - } - while (1); - - /* store history offset */ - g_mppc_dict.roff = next_offset; - - *roff = old_offset; - *rlen = next_offset - old_offset; - - return 0; -} diff --git a/uirdesktop/orders.c b/uirdesktop/orders.c deleted file mode 100644 index 78ba58a7..00000000 --- a/uirdesktop/orders.c +++ /dev/null @@ -1,1319 +0,0 @@ -/* -*- c-basic-offset: 8 -*- - rdesktop: A Remote Desktop Protocol client. - RDP order processing - Copyright (C) Matthew Chapman 1999-2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "rdesktop.h" -#include "orders.h" - -extern uint8 *g_next_packet; -static RDP_ORDER_STATE g_order_state; -extern BOOL g_use_rdp5; - -/* Read field indicating which parameters are present */ -static void -rdp_in_present(STREAM s, uint32 * present, uint8 flags, int size) -{ - uint8 bits; - int i; - - if (flags & RDP_ORDER_SMALL) - { - size--; - } - - if (flags & RDP_ORDER_TINY) - { - if (size < 2) - size = 0; - else - size -= 2; - } - - *present = 0; - for (i = 0; i < size; i++) - { - in_uint8(s, bits); - *present |= bits << (i * 8); - } -} - -/* Read a co-ordinate (16-bit, or 8-bit delta) */ -static void -rdp_in_coord(STREAM s, sint16 * coord, BOOL delta) -{ - sint8 change; - - if (delta) - { - in_uint8(s, change); - *coord += change; - } - else - { - in_uint16_le(s, *coord); - } -} - -/* Parse a delta co-ordinate in polyline/polygon order form */ -static int -parse_delta(uint8 * buffer, int *offset) -{ - int value = buffer[(*offset)++]; - int two_byte = value & 0x80; - - if (value & 0x40) /* sign bit */ - value |= ~0x3f; - else - value &= 0x3f; - - if (two_byte) - value = (value << 8) | buffer[(*offset)++]; - - return value; -} - -/* Read a colour entry */ -static void -rdp_in_colour(STREAM s, uint32 * colour) -{ - uint32 i; - in_uint8(s, i); - *colour = i; - in_uint8(s, i); - *colour |= i << 8; - in_uint8(s, i); - *colour |= i << 16; -} - -/* Parse bounds information */ -static BOOL -rdp_parse_bounds(STREAM s, BOUNDS * bounds) -{ - uint8 present; - - in_uint8(s, present); - - if (present & 1) - rdp_in_coord(s, &bounds->left, False); - else if (present & 16) - rdp_in_coord(s, &bounds->left, True); - - if (present & 2) - rdp_in_coord(s, &bounds->top, False); - else if (present & 32) - rdp_in_coord(s, &bounds->top, True); - - if (present & 4) - rdp_in_coord(s, &bounds->right, False); - else if (present & 64) - rdp_in_coord(s, &bounds->right, True); - - if (present & 8) - rdp_in_coord(s, &bounds->bottom, False); - else if (present & 128) - rdp_in_coord(s, &bounds->bottom, True); - - return s_check(s); -} - -/* Parse a pen */ -static BOOL -rdp_parse_pen(STREAM s, PEN * pen, uint32 present) -{ - if (present & 1) - in_uint8(s, pen->style); - - if (present & 2) - in_uint8(s, pen->width); - - if (present & 4) - rdp_in_colour(s, &pen->colour); - - return s_check(s); -} - -/* Parse a brush */ -static BOOL -rdp_parse_brush(STREAM s, BRUSH * brush, uint32 present) -{ - if (present & 1) - in_uint8(s, brush->xorigin); - - if (present & 2) - in_uint8(s, brush->yorigin); - - if (present & 4) - in_uint8(s, brush->style); - - if (present & 8) - in_uint8(s, brush->pattern[0]); - - if (present & 16) - in_uint8a(s, &brush->pattern[1], 7); - - return s_check(s); -} - -/* Process a destination blt order */ -static void -process_destblt(STREAM s, DESTBLT_ORDER * os, uint32 present, BOOL delta) -{ - if (present & 0x01) - rdp_in_coord(s, &os->x, delta); - - if (present & 0x02) - rdp_in_coord(s, &os->y, delta); - - if (present & 0x04) - rdp_in_coord(s, &os->cx, delta); - - if (present & 0x08) - rdp_in_coord(s, &os->cy, delta); - - if (present & 0x10) - in_uint8(s, os->opcode); - - DEBUG(("DESTBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d)\n", - os->opcode, os->x, os->y, os->cx, os->cy)); - - ui_destblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy); -} - -/* Process a pattern blt order */ -static void -process_patblt(STREAM s, PATBLT_ORDER * os, uint32 present, BOOL delta) -{ - if (present & 0x0001) - rdp_in_coord(s, &os->x, delta); - - if (present & 0x0002) - rdp_in_coord(s, &os->y, delta); - - if (present & 0x0004) - rdp_in_coord(s, &os->cx, delta); - - if (present & 0x0008) - rdp_in_coord(s, &os->cy, delta); - - if (present & 0x0010) - in_uint8(s, os->opcode); - - if (present & 0x0020) - rdp_in_colour(s, &os->bgcolour); - - if (present & 0x0040) - rdp_in_colour(s, &os->fgcolour); - - rdp_parse_brush(s, &os->brush, present >> 7); - - DEBUG(("PATBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,bs=%d,bg=0x%x,fg=0x%x)\n", os->opcode, os->x, - os->y, os->cx, os->cy, os->brush.style, os->bgcolour, os->fgcolour)); - - ui_patblt(ROP2_P(os->opcode), os->x, os->y, os->cx, os->cy, - &os->brush, os->bgcolour, os->fgcolour); -} - -/* Process a screen blt order */ -static void -process_screenblt(STREAM s, SCREENBLT_ORDER * os, uint32 present, BOOL delta) -{ - if (present & 0x0001) - rdp_in_coord(s, &os->x, delta); - - if (present & 0x0002) - rdp_in_coord(s, &os->y, delta); - - if (present & 0x0004) - rdp_in_coord(s, &os->cx, delta); - - if (present & 0x0008) - rdp_in_coord(s, &os->cy, delta); - - if (present & 0x0010) - in_uint8(s, os->opcode); - - if (present & 0x0020) - rdp_in_coord(s, &os->srcx, delta); - - if (present & 0x0040) - rdp_in_coord(s, &os->srcy, delta); - - DEBUG(("SCREENBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,srcx=%d,srcy=%d)\n", - os->opcode, os->x, os->y, os->cx, os->cy, os->srcx, os->srcy)); - - ui_screenblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy, os->srcx, os->srcy); -} - -/* Process a line order */ -static void -process_line(STREAM s, LINE_ORDER * os, uint32 present, BOOL delta) -{ - if (present & 0x0001) - in_uint16_le(s, os->mixmode); - - if (present & 0x0002) - rdp_in_coord(s, &os->startx, delta); - - if (present & 0x0004) - rdp_in_coord(s, &os->starty, delta); - - if (present & 0x0008) - rdp_in_coord(s, &os->endx, delta); - - if (present & 0x0010) - rdp_in_coord(s, &os->endy, delta); - - if (present & 0x0020) - rdp_in_colour(s, &os->bgcolour); - - if (present & 0x0040) - in_uint8(s, os->opcode); - - rdp_parse_pen(s, &os->pen, present >> 7); - - DEBUG(("LINE(op=0x%x,sx=%d,sy=%d,dx=%d,dy=%d,fg=0x%x)\n", - os->opcode, os->startx, os->starty, os->endx, os->endy, os->pen.colour)); - - if (os->opcode < 0x01 || os->opcode > 0x10) - { - error("bad ROP2 0x%x\n", os->opcode); - return; - } - - ui_line(ROP_MINUS_1(os->opcode), os->startx, os->starty, os->endx, os->endy, &os->pen); -} - -/* Process an opaque rectangle order */ -static void -process_rect(STREAM s, RECT_ORDER * os, uint32 present, BOOL delta) -{ - uint32 i; - if (present & 0x01) - rdp_in_coord(s, &os->x, delta); - - if (present & 0x02) - rdp_in_coord(s, &os->y, delta); - - if (present & 0x04) - rdp_in_coord(s, &os->cx, delta); - - if (present & 0x08) - rdp_in_coord(s, &os->cy, delta); - - if (present & 0x10) - { - in_uint8(s, i); - os->colour = (os->colour & 0xffffff00) | i; - } - - if (present & 0x20) - { - in_uint8(s, i); - os->colour = (os->colour & 0xffff00ff) | (i << 8); - } - - if (present & 0x40) - { - in_uint8(s, i); - os->colour = (os->colour & 0xff00ffff) | (i << 16); - } - - DEBUG(("RECT(x=%d,y=%d,cx=%d,cy=%d,fg=0x%x)\n", os->x, os->y, os->cx, os->cy, os->colour)); - - ui_rect(os->x, os->y, os->cx, os->cy, os->colour); -} - -/* Process a desktop save order */ -static void -process_desksave(STREAM s, DESKSAVE_ORDER * os, uint32 present, BOOL delta) -{ - int width, height; - - if (present & 0x01) - in_uint32_le(s, os->offset); - - if (present & 0x02) - rdp_in_coord(s, &os->left, delta); - - if (present & 0x04) - rdp_in_coord(s, &os->top, delta); - - if (present & 0x08) - rdp_in_coord(s, &os->right, delta); - - if (present & 0x10) - rdp_in_coord(s, &os->bottom, delta); - - if (present & 0x20) - in_uint8(s, os->action); - - DEBUG(("DESKSAVE(l=%d,t=%d,r=%d,b=%d,off=%d,op=%d)\n", - os->left, os->top, os->right, os->bottom, os->offset, os->action)); - - width = os->right - os->left + 1; - height = os->bottom - os->top + 1; - - if (os->action == 0) - ui_desktop_save(os->offset, os->left, os->top, width, height); - else - ui_desktop_restore(os->offset, os->left, os->top, width, height); -} - -/* Process a memory blt order */ -static void -process_memblt(STREAM s, MEMBLT_ORDER * os, uint32 present, BOOL delta) -{ - RD_HBITMAP bitmap; - - if (present & 0x0001) - { - in_uint8(s, os->cache_id); - in_uint8(s, os->colour_table); - } - - if (present & 0x0002) - rdp_in_coord(s, &os->x, delta); - - if (present & 0x0004) - rdp_in_coord(s, &os->y, delta); - - if (present & 0x0008) - rdp_in_coord(s, &os->cx, delta); - - if (present & 0x0010) - rdp_in_coord(s, &os->cy, delta); - - if (present & 0x0020) - in_uint8(s, os->opcode); - - if (present & 0x0040) - rdp_in_coord(s, &os->srcx, delta); - - if (present & 0x0080) - rdp_in_coord(s, &os->srcy, delta); - - if (present & 0x0100) - in_uint16_le(s, os->cache_idx); - - DEBUG(("MEMBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,id=%d,idx=%d)\n", - os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id, os->cache_idx)); - - bitmap = cache_get_bitmap(os->cache_id, os->cache_idx); - if (bitmap == NULL) - return; - - ui_memblt(ROP2_S(os->opcode), os->x, os->y, os->cx, os->cy, bitmap, os->srcx, os->srcy); -} - -/* Process a 3-way blt order */ -static void -process_triblt(STREAM s, TRIBLT_ORDER * os, uint32 present, BOOL delta) -{ - RD_HBITMAP bitmap; - - if (present & 0x000001) - { - in_uint8(s, os->cache_id); - in_uint8(s, os->colour_table); - } - - if (present & 0x000002) - rdp_in_coord(s, &os->x, delta); - - if (present & 0x000004) - rdp_in_coord(s, &os->y, delta); - - if (present & 0x000008) - rdp_in_coord(s, &os->cx, delta); - - if (present & 0x000010) - rdp_in_coord(s, &os->cy, delta); - - if (present & 0x000020) - in_uint8(s, os->opcode); - - if (present & 0x000040) - rdp_in_coord(s, &os->srcx, delta); - - if (present & 0x000080) - rdp_in_coord(s, &os->srcy, delta); - - if (present & 0x000100) - rdp_in_colour(s, &os->bgcolour); - - if (present & 0x000200) - rdp_in_colour(s, &os->fgcolour); - - rdp_parse_brush(s, &os->brush, present >> 10); - - if (present & 0x008000) - in_uint16_le(s, os->cache_idx); - - if (present & 0x010000) - in_uint16_le(s, os->unknown); - - DEBUG(("TRIBLT(op=0x%x,x=%d,y=%d,cx=%d,cy=%d,id=%d,idx=%d,bs=%d,bg=0x%x,fg=0x%x)\n", - os->opcode, os->x, os->y, os->cx, os->cy, os->cache_id, os->cache_idx, - os->brush.style, os->bgcolour, os->fgcolour)); - - bitmap = cache_get_bitmap(os->cache_id, os->cache_idx); - if (bitmap == NULL) - return; - - ui_triblt(os->opcode, os->x, os->y, os->cx, os->cy, - bitmap, os->srcx, os->srcy, &os->brush, os->bgcolour, os->fgcolour); -} - -/* Process a polygon order */ -static void -process_polygon(STREAM s, POLYGON_ORDER * os, uint32 present, BOOL delta) -{ - int index, data, next; - uint8 flags = 0; - RD_POINT *points; - - if (present & 0x01) - rdp_in_coord(s, &os->x, delta); - - if (present & 0x02) - rdp_in_coord(s, &os->y, delta); - - if (present & 0x04) - in_uint8(s, os->opcode); - - if (present & 0x08) - in_uint8(s, os->fillmode); - - if (present & 0x10) - rdp_in_colour(s, &os->fgcolour); - - if (present & 0x20) - in_uint8(s, os->npoints); - - if (present & 0x40) - { - in_uint8(s, os->datasize); - in_uint8a(s, os->data, os->datasize); - } - - DEBUG(("POLYGON(x=%d,y=%d,op=0x%x,fm=%d,fg=0x%x,n=%d,sz=%d)\n", - os->x, os->y, os->opcode, os->fillmode, os->fgcolour, os->npoints, os->datasize)); - - DEBUG(("Data: ")); - - for (index = 0; index < os->datasize; index++) - DEBUG(("%02x ", os->data[index])); - - DEBUG(("\n")); - - if (os->opcode < 0x01 || os->opcode > 0x10) - { - error("bad ROP2 0x%x\n", os->opcode); - return; - } - - points = (RD_POINT *) xmalloc((os->npoints + 1) * sizeof(RD_POINT)); - memset(points, 0, (os->npoints + 1) * sizeof(RD_POINT)); - - points[0].x = os->x; - points[0].y = os->y; - - index = 0; - data = ((os->npoints - 1) / 4) + 1; - for (next = 1; (next <= os->npoints) && (next < 256) && (data < os->datasize); next++) - { - if ((next - 1) % 4 == 0) - flags = os->data[index++]; - - if (~flags & 0x80) - points[next].x = parse_delta(os->data, &data); - - if (~flags & 0x40) - points[next].y = parse_delta(os->data, &data); - - flags <<= 2; - } - - if (next - 1 == os->npoints) - ui_polygon(ROP_MINUS_1(os->opcode), os->fillmode, points, os->npoints + 1, NULL, 0, - os->fgcolour); - else - error("polygon parse error\n"); - - xfree(points); -} - -/* Process a polygon2 order */ -static void -process_polygon2(STREAM s, POLYGON2_ORDER * os, uint32 present, BOOL delta) -{ - int index, data, next; - uint8 flags = 0; - RD_POINT *points; - - if (present & 0x0001) - rdp_in_coord(s, &os->x, delta); - - if (present & 0x0002) - rdp_in_coord(s, &os->y, delta); - - if (present & 0x0004) - in_uint8(s, os->opcode); - - if (present & 0x0008) - in_uint8(s, os->fillmode); - - if (present & 0x0010) - rdp_in_colour(s, &os->bgcolour); - - if (present & 0x0020) - rdp_in_colour(s, &os->fgcolour); - - rdp_parse_brush(s, &os->brush, present >> 6); - - if (present & 0x0800) - in_uint8(s, os->npoints); - - if (present & 0x1000) - { - in_uint8(s, os->datasize); - in_uint8a(s, os->data, os->datasize); - } - - DEBUG(("POLYGON2(x=%d,y=%d,op=0x%x,fm=%d,bs=%d,bg=0x%x,fg=0x%x,n=%d,sz=%d)\n", - os->x, os->y, os->opcode, os->fillmode, os->brush.style, os->bgcolour, os->fgcolour, - os->npoints, os->datasize)); - - DEBUG(("Data: ")); - - for (index = 0; index < os->datasize; index++) - DEBUG(("%02x ", os->data[index])); - - DEBUG(("\n")); - - if (os->opcode < 0x01 || os->opcode > 0x10) - { - error("bad ROP2 0x%x\n", os->opcode); - return; - } - - points = (RD_POINT *) xmalloc((os->npoints + 1) * sizeof(RD_POINT)); - memset(points, 0, (os->npoints + 1) * sizeof(RD_POINT)); - - points[0].x = os->x; - points[0].y = os->y; - - index = 0; - data = ((os->npoints - 1) / 4) + 1; - for (next = 1; (next <= os->npoints) && (next < 256) && (data < os->datasize); next++) - { - if ((next - 1) % 4 == 0) - flags = os->data[index++]; - - if (~flags & 0x80) - points[next].x = parse_delta(os->data, &data); - - if (~flags & 0x40) - points[next].y = parse_delta(os->data, &data); - - flags <<= 2; - } - - if (next - 1 == os->npoints) - ui_polygon(ROP_MINUS_1(os->opcode), os->fillmode, points, os->npoints + 1, - &os->brush, os->bgcolour, os->fgcolour); - else - error("polygon2 parse error\n"); - - xfree(points); -} - -/* Process a polyline order */ -static void -process_polyline(STREAM s, POLYLINE_ORDER * os, uint32 present, BOOL delta) -{ - int index, next, data; - uint8 flags = 0; - PEN pen; - RD_POINT *points; - - if (present & 0x01) - rdp_in_coord(s, &os->x, delta); - - if (present & 0x02) - rdp_in_coord(s, &os->y, delta); - - if (present & 0x04) - in_uint8(s, os->opcode); - - if (present & 0x10) - rdp_in_colour(s, &os->fgcolour); - - if (present & 0x20) - in_uint8(s, os->lines); - - if (present & 0x40) - { - in_uint8(s, os->datasize); - in_uint8a(s, os->data, os->datasize); - } - - DEBUG(("POLYLINE(x=%d,y=%d,op=0x%x,fg=0x%x,n=%d,sz=%d)\n", - os->x, os->y, os->opcode, os->fgcolour, os->lines, os->datasize)); - - DEBUG(("Data: ")); - - for (index = 0; index < os->datasize; index++) - DEBUG(("%02x ", os->data[index])); - - DEBUG(("\n")); - - if (os->opcode < 0x01 || os->opcode > 0x10) - { - error("bad ROP2 0x%x\n", os->opcode); - return; - } - - points = (RD_POINT *) xmalloc((os->lines + 1) * sizeof(RD_POINT)); - memset(points, 0, (os->lines + 1) * sizeof(RD_POINT)); - - points[0].x = os->x; - points[0].y = os->y; - pen.style = pen.width = 0; - pen.colour = os->fgcolour; - - index = 0; - data = ((os->lines - 1) / 4) + 1; - for (next = 1; (next <= os->lines) && (data < os->datasize); next++) - { - if ((next - 1) % 4 == 0) - flags = os->data[index++]; - - if (~flags & 0x80) - points[next].x = parse_delta(os->data, &data); - - if (~flags & 0x40) - points[next].y = parse_delta(os->data, &data); - - flags <<= 2; - } - - if (next - 1 == os->lines) - ui_polyline(ROP_MINUS_1(os->opcode), points, os->lines + 1, &pen); - else - error("polyline parse error\n"); - - xfree(points); -} - -/* Process an ellipse order */ -static void -process_ellipse(STREAM s, ELLIPSE_ORDER * os, uint32 present, BOOL delta) -{ - if (present & 0x01) - rdp_in_coord(s, &os->left, delta); - - if (present & 0x02) - rdp_in_coord(s, &os->top, delta); - - if (present & 0x04) - rdp_in_coord(s, &os->right, delta); - - if (present & 0x08) - rdp_in_coord(s, &os->bottom, delta); - - if (present & 0x10) - in_uint8(s, os->opcode); - - if (present & 0x20) - in_uint8(s, os->fillmode); - - if (present & 0x40) - rdp_in_colour(s, &os->fgcolour); - - DEBUG(("ELLIPSE(l=%d,t=%d,r=%d,b=%d,op=0x%x,fm=%d,fg=0x%x)\n", os->left, os->top, - os->right, os->bottom, os->opcode, os->fillmode, os->fgcolour)); - - ui_ellipse(ROP_MINUS_1(os->opcode), os->fillmode, os->left, os->top, os->right - os->left, - os->bottom - os->top, NULL, 0, os->fgcolour); -} - -/* Process an ellipse2 order */ -static void -process_ellipse2(STREAM s, ELLIPSE2_ORDER * os, uint32 present, BOOL delta) -{ - if (present & 0x0001) - rdp_in_coord(s, &os->left, delta); - - if (present & 0x0002) - rdp_in_coord(s, &os->top, delta); - - if (present & 0x0004) - rdp_in_coord(s, &os->right, delta); - - if (present & 0x0008) - rdp_in_coord(s, &os->bottom, delta); - - if (present & 0x0010) - in_uint8(s, os->opcode); - - if (present & 0x0020) - in_uint8(s, os->fillmode); - - if (present & 0x0040) - rdp_in_colour(s, &os->bgcolour); - - if (present & 0x0080) - rdp_in_colour(s, &os->fgcolour); - - rdp_parse_brush(s, &os->brush, present >> 8); - - DEBUG(("ELLIPSE2(l=%d,t=%d,r=%d,b=%d,op=0x%x,fm=%d,bs=%d,bg=0x%x,fg=0x%x)\n", - os->left, os->top, os->right, os->bottom, os->opcode, os->fillmode, os->brush.style, - os->bgcolour, os->fgcolour)); - - ui_ellipse(ROP_MINUS_1(os->opcode), os->fillmode, os->left, os->top, os->right - os->left, - os->bottom - os->top, &os->brush, os->bgcolour, os->fgcolour); -} - -/* Process a text order */ -static void -process_text2(STREAM s, TEXT2_ORDER * os, uint32 present, BOOL delta) -{ - int i; - - if (present & 0x000001) - in_uint8(s, os->font); - - if (present & 0x000002) - in_uint8(s, os->flags); - - if (present & 0x000004) - in_uint8(s, os->opcode); - - if (present & 0x000008) - in_uint8(s, os->mixmode); - - if (present & 0x000010) - rdp_in_colour(s, &os->fgcolour); - - if (present & 0x000020) - rdp_in_colour(s, &os->bgcolour); - - if (present & 0x000040) - in_uint16_le(s, os->clipleft); - - if (present & 0x000080) - in_uint16_le(s, os->cliptop); - - if (present & 0x000100) - in_uint16_le(s, os->clipright); - - if (present & 0x000200) - in_uint16_le(s, os->clipbottom); - - if (present & 0x000400) - in_uint16_le(s, os->boxleft); - - if (present & 0x000800) - in_uint16_le(s, os->boxtop); - - if (present & 0x001000) - in_uint16_le(s, os->boxright); - - if (present & 0x002000) - in_uint16_le(s, os->boxbottom); - - rdp_parse_brush(s, &os->brush, present >> 14); - - if (present & 0x080000) - in_uint16_le(s, os->x); - - if (present & 0x100000) - in_uint16_le(s, os->y); - - if (present & 0x200000) - { - in_uint8(s, os->length); - in_uint8a(s, os->text, os->length); - } - - DEBUG(("TEXT2(x=%d,y=%d,cl=%d,ct=%d,cr=%d,cb=%d,bl=%d,bt=%d,br=%d,bb=%d,bs=%d,bg=0x%x,fg=0x%x,font=%d,fl=0x%x,op=0x%x,mix=%d,n=%d)\n", os->x, os->y, os->clipleft, os->cliptop, os->clipright, os->clipbottom, os->boxleft, os->boxtop, os->boxright, os->boxbottom, os->brush.style, os->bgcolour, os->fgcolour, os->font, os->flags, os->opcode, os->mixmode, os->length)); - - DEBUG(("Text: ")); - - for (i = 0; i < os->length; i++) - DEBUG(("%02x ", os->text[i])); - - DEBUG(("\n")); - - ui_draw_text(os->font, os->flags, ROP_MINUS_1(os->opcode), os->mixmode, os->x, os->y, - os->clipleft, os->cliptop, os->clipright - os->clipleft, - os->clipbottom - os->cliptop, os->boxleft, os->boxtop, - os->boxright - os->boxleft, os->boxbottom - os->boxtop, - &os->brush, os->bgcolour, os->fgcolour, os->text, os->length); -} - -/* Process a raw bitmap cache order */ -static void -process_raw_bmpcache(STREAM s) -{ - RD_HBITMAP bitmap; - uint16 cache_idx, bufsize; - uint8 cache_id, width, height, bpp, Bpp; - uint8 *data/*, *inverted*/; - int y; - - in_uint8(s, cache_id); - in_uint8s(s, 1); /* pad */ - in_uint8(s, width); - in_uint8(s, height); - in_uint8(s, bpp); - Bpp = (bpp + 7) / 8; - in_uint16_le(s, bufsize); - in_uint16_le(s, cache_idx); - in_uint8p(s, data, bufsize); - bitmap = ui_create_bitmap_ex(width, height, data, bufsize, False); -/* - DEBUG(("RAW_BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d)\n", width, height, cache_id, cache_idx)); - inverted = (uint8 *) xmalloc(width * height * Bpp); - for (y = 0; y < height; y++) - { - memcpy(&inverted[(height - y - 1) * (width * Bpp)], &data[y * (width * Bpp)], - width * Bpp); - } - - bitmap = ui_create_bitmap(width, height, inverted); - xfree(inverted); -*/ - cache_put_bitmap(cache_id, cache_idx, bitmap); -} - -/* Process a bitmap cache order */ -static void -process_bmpcache(STREAM s) -{ - RD_HBITMAP bitmap; - uint16 cache_idx, size; - uint8 cache_id, width, height, bpp, Bpp; - uint8 *data/*, *bmpdata*/; - uint16 bufsize, pad2, row_size, final_size; - uint8 pad1; - - pad2 = row_size = final_size = 0xffff; /* Shut the compiler up */ - - in_uint8(s, cache_id); - in_uint8(s, pad1); /* pad */ - in_uint8(s, width); - in_uint8(s, height); - in_uint8(s, bpp); - Bpp = (bpp + 7) / 8; - in_uint16_le(s, bufsize); /* bufsize */ - in_uint16_le(s, cache_idx); - - if (g_use_rdp5) - { - size = bufsize; - } - else - { - - /* Begin compressedBitmapData */ - in_uint16_le(s, pad2); /* pad */ - in_uint16_le(s, size); - /* in_uint8s(s, 4); *//* row_size, final_size */ - in_uint16_le(s, row_size); - in_uint16_le(s, final_size); - - } - in_uint8p(s, data, size); - - DEBUG(("BMPCACHE(cx=%d,cy=%d,id=%d,idx=%d,bpp=%d,size=%d,pad1=%d,bufsize=%d,pad2=%d,rs=%d,fs=%d)\n", width, height, cache_id, cache_idx, bpp, size, pad1, bufsize, pad2, row_size, final_size)); - - bitmap = ui_create_bitmap_ex(width, height, data, size, True); - cache_put_bitmap(cache_id, cache_idx, bitmap); -/* - bmpdata = (uint8 *) xmalloc(width * height * Bpp); - - if (bitmap_decompress(bmpdata, width, height, data, size, Bpp)) - { - bitmap = ui_create_bitmap(width, height, bmpdata); - cache_put_bitmap(cache_id, cache_idx, bitmap); - } - else - { - DEBUG(("Failed to decompress bitmap data\n")); - } - - xfree(bmpdata); -*/ -} - -/* Process a bitmap cache v2 order */ -static void -process_bmpcache2(STREAM s, uint16 flags, BOOL compressed) -{ - RD_HBITMAP bitmap; - int y; - uint8 cache_id, cache_idx_low, width, height, Bpp; - uint16 cache_idx, bufsize; - uint8 *data, *bmpdata, *bitmap_id; - - bitmap_id = NULL; /* prevent compiler warning */ - cache_id = flags & ID_MASK; - Bpp = ((flags & MODE_MASK) >> MODE_SHIFT) - 2; - - if (flags & PERSIST) - { - in_uint8p(s, bitmap_id, 8); - } - - if (flags & SQUARE) - { - in_uint8(s, width); - height = width; - } - else - { - in_uint8(s, width); - in_uint8(s, height); - } - - in_uint16_be(s, bufsize); - bufsize &= BUFSIZE_MASK; - in_uint8(s, cache_idx); - - if (cache_idx & LONG_FORMAT) - { - in_uint8(s, cache_idx_low); - cache_idx = ((cache_idx ^ LONG_FORMAT) << 8) + cache_idx_low; - } - - in_uint8p(s, data, bufsize); - - DEBUG(("BMPCACHE2(compr=%d,flags=%x,cx=%d,cy=%d,id=%d,idx=%d,Bpp=%d,bs=%d)\n", - compressed, flags, width, height, cache_id, cache_idx, Bpp, bufsize)); - - bitmap = ui_create_bitmap_ex(width, height, data, bufsize, compressed); - cache_put_bitmap(cache_id, cache_idx, bitmap); - - /* todo, persitant bitmap not working this was */ -/* - bmpdata = (uint8 *) xmalloc(width * height * Bpp); - - if (compressed) - { - if (!bitmap_decompress(bmpdata, width, height, data, bufsize, Bpp)) - { - DEBUG(("Failed to decompress bitmap data\n")); - xfree(bmpdata); - return; - } - } - else - { - for (y = 0; y < height; y++) - memcpy(&bmpdata[(height - y - 1) * (width * Bpp)], - &data[y * (width * Bpp)], width * Bpp); - } - - bitmap = ui_create_bitmap(width, height, bmpdata); - - if (bitmap) - { - cache_put_bitmap(cache_id, cache_idx, bitmap); - if (flags & PERSIST) - pstcache_save_bitmap(cache_id, cache_idx, bitmap_id, width, height, - (uint16) (width * height * Bpp), bmpdata); - } - else - { - DEBUG(("process_bmpcache2: ui_create_bitmap failed\n")); - } - - xfree(bmpdata); -*/ -} - -/* Process a colourmap cache order */ -static void -process_colcache(STREAM s) -{ - COLOURENTRY *entry; - COLOURMAP map; - RD_HCOLOURMAP hmap; - uint8 cache_id; - int i; - - in_uint8(s, cache_id); - in_uint16_le(s, map.ncolours); - - map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours); - - for (i = 0; i < map.ncolours; i++) - { - entry = &map.colours[i]; - in_uint8(s, entry->blue); - in_uint8(s, entry->green); - in_uint8(s, entry->red); - in_uint8s(s, 1); /* pad */ - } - - DEBUG(("COLCACHE(id=%d,n=%d)\n", cache_id, map.ncolours)); - - hmap = ui_create_colourmap(&map); - - if (cache_id) - ui_set_colourmap(hmap); - - xfree(map.colours); -} - -/* Process a font cache order */ -static void -process_fontcache(STREAM s) -{ - RD_HGLYPH bitmap; - uint8 font, nglyphs; - uint16 character, offset, baseline, width, height; - int i, datasize; - uint8 *data; - - in_uint8(s, font); - in_uint8(s, nglyphs); - - DEBUG(("FONTCACHE(font=%d,n=%d)\n", font, nglyphs)); - - for (i = 0; i < nglyphs; i++) - { - in_uint16_le(s, character); - in_uint16_le(s, offset); - in_uint16_le(s, baseline); - in_uint16_le(s, width); - in_uint16_le(s, height); - - datasize = (height * ((width + 7) / 8) + 3) & ~3; - in_uint8p(s, data, datasize); - - bitmap = ui_create_glyph(width, height, data); - cache_put_font(font, character, offset, baseline, width, height, bitmap); - } -} - -/* Process a secondary order */ -static void -process_secondary_order(STREAM s) -{ - /* The length isn't calculated correctly by the server. - * For very compact orders the length becomes negative - * so a signed integer must be used. */ - uint16 length; - uint16 flags; - uint8 type; - uint8 *next_order; - - in_uint16_le(s, length); - in_uint16_le(s, flags); /* used by bmpcache2 */ - in_uint8(s, type); - - next_order = s->p + (sint16) length + 7; - - switch (type) - { - case RDP_ORDER_RAW_BMPCACHE: - process_raw_bmpcache(s); - break; - - case RDP_ORDER_COLCACHE: - process_colcache(s); - break; - - case RDP_ORDER_BMPCACHE: - process_bmpcache(s); - break; - - case RDP_ORDER_FONTCACHE: - process_fontcache(s); - break; - - case RDP_ORDER_RAW_BMPCACHE2: - process_bmpcache2(s, flags, False); /* uncompressed */ - break; - - case RDP_ORDER_BMPCACHE2: - process_bmpcache2(s, flags, True); /* compressed */ - break; - - default: - unimpl("secondary order %d\n", type); - } - - s->p = next_order; -} - -/* Process an order PDU */ -void -process_orders(STREAM s, uint16 num_orders) -{ - RDP_ORDER_STATE *os = &g_order_state; - uint32 present; - uint8 order_flags; - int size, processed = 0; - BOOL delta; - - while (processed < num_orders) - { - in_uint8(s, order_flags); - - if (!(order_flags & RDP_ORDER_STANDARD)) - { - error("order parsing failed\n"); - break; - } - - if (order_flags & RDP_ORDER_SECONDARY) - { - process_secondary_order(s); - } - else - { - if (order_flags & RDP_ORDER_CHANGE) - { - in_uint8(s, os->order_type); - } - - switch (os->order_type) - { - case RDP_ORDER_TRIBLT: - case RDP_ORDER_TEXT2: - size = 3; - break; - - case RDP_ORDER_PATBLT: - case RDP_ORDER_MEMBLT: - case RDP_ORDER_LINE: - case RDP_ORDER_POLYGON2: - case RDP_ORDER_ELLIPSE2: - size = 2; - break; - - default: - size = 1; - } - - rdp_in_present(s, &present, order_flags, size); - - if (order_flags & RDP_ORDER_BOUNDS) - { - if (!(order_flags & RDP_ORDER_LASTBOUNDS)) - rdp_parse_bounds(s, &os->bounds); - - ui_set_clip(os->bounds.left, - os->bounds.top, - os->bounds.right - - os->bounds.left + 1, - os->bounds.bottom - os->bounds.top + 1); - } - - delta = order_flags & RDP_ORDER_DELTA; - - switch (os->order_type) - { - case RDP_ORDER_DESTBLT: - process_destblt(s, &os->destblt, present, delta); - break; - - case RDP_ORDER_PATBLT: - process_patblt(s, &os->patblt, present, delta); - break; - - case RDP_ORDER_SCREENBLT: - process_screenblt(s, &os->screenblt, present, delta); - break; - - case RDP_ORDER_LINE: - process_line(s, &os->line, present, delta); - break; - - case RDP_ORDER_RECT: - process_rect(s, &os->rect, present, delta); - break; - - case RDP_ORDER_DESKSAVE: - process_desksave(s, &os->desksave, present, delta); - break; - - case RDP_ORDER_MEMBLT: - process_memblt(s, &os->memblt, present, delta); - break; - - case RDP_ORDER_TRIBLT: - process_triblt(s, &os->triblt, present, delta); - break; - - case RDP_ORDER_POLYGON: - process_polygon(s, &os->polygon, present, delta); - break; - - case RDP_ORDER_POLYGON2: - process_polygon2(s, &os->polygon2, present, delta); - break; - - case RDP_ORDER_POLYLINE: - process_polyline(s, &os->polyline, present, delta); - break; - - case RDP_ORDER_ELLIPSE: - process_ellipse(s, &os->ellipse, present, delta); - break; - - case RDP_ORDER_ELLIPSE2: - process_ellipse2(s, &os->ellipse2, present, delta); - break; - - case RDP_ORDER_TEXT2: - process_text2(s, &os->text2, present, delta); - break; - - default: - unimpl("order %d\n", os->order_type); - return; - } - - if (order_flags & RDP_ORDER_BOUNDS) - ui_reset_clip(); - } - - processed++; - } -#if 0 - /* not true when RDP_COMPRESSION is set */ - if (s->p != g_next_packet) - error("%d bytes remaining\n", (int) (g_next_packet - s->p)); -#endif - -} - -/* Reset order state */ -void -reset_order_state(void) -{ - memset(&g_order_state, 0, sizeof(g_order_state)); - g_order_state.order_type = RDP_ORDER_PATBLT; -} diff --git a/uirdesktop/pstcache.c b/uirdesktop/pstcache.c deleted file mode 100644 index 840bf77e..00000000 --- a/uirdesktop/pstcache.c +++ /dev/null @@ -1,200 +0,0 @@ -/* -*- c-basic-offset: 8 -*- - rdesktop: A Remote Desktop Protocol client. - Persistent Bitmap Cache routines - Copyright (C) Jeroen Meijer 2004-2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "rdesktop.h" - -#define MAX_CELL_SIZE 0x1000 /* pixels */ - -#define IS_PERSISTENT(id) (id < 8 && g_pstcache_fd[id] > 0) - -extern int g_server_depth; -extern BOOL g_bitmap_cache; -extern BOOL g_bitmap_cache_persist_enable; -extern BOOL g_bitmap_cache_precache; - -int g_pstcache_fd[8]; -int g_pstcache_Bpp; -BOOL g_pstcache_enumerated = False; -uint8 zero_key[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; - - -/* Update mru stamp/index for a bitmap */ -void -pstcache_touch_bitmap(uint8 cache_id, uint16 cache_idx, uint32 stamp) -{ - int fd; - - if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS) - return; - - fd = g_pstcache_fd[cache_id]; - rd_lseek_file(fd, 12 + cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER))); - rd_write_file(fd, &stamp, sizeof(stamp)); -} - -/* Load a bitmap from the persistent cache */ -BOOL -pstcache_load_bitmap(uint8 cache_id, uint16 cache_idx) -{ - uint8 *celldata; - int fd; - CELLHEADER cellhdr; - RD_HBITMAP bitmap; - - if (!g_bitmap_cache_persist_enable) - return False; - - if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS) - return False; - - fd = g_pstcache_fd[cache_id]; - rd_lseek_file(fd, cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER))); - rd_read_file(fd, &cellhdr, sizeof(CELLHEADER)); - celldata = (uint8 *) xmalloc(cellhdr.length); - rd_read_file(fd, celldata, cellhdr.length); - - bitmap = ui_create_bitmap(cellhdr.width, cellhdr.height, celldata); - DEBUG(("Load bitmap from disk: id=%d, idx=%d, bmp=0x%x)\n", cache_id, cache_idx, bitmap)); - cache_put_bitmap(cache_id, cache_idx, bitmap); - - xfree(celldata); - return True; -} - -/* Store a bitmap in the persistent cache */ -BOOL -pstcache_save_bitmap(uint8 cache_id, uint16 cache_idx, uint8 * key, - uint8 width, uint8 height, uint16 length, uint8 * data) -{ - int fd; - CELLHEADER cellhdr; - - if (!IS_PERSISTENT(cache_id) || cache_idx >= BMPCACHE2_NUM_PSTCELLS) - return False; - - memcpy(cellhdr.key, key, sizeof(HASH_KEY)); - cellhdr.width = width; - cellhdr.height = height; - cellhdr.length = length; - cellhdr.stamp = 0; - - fd = g_pstcache_fd[cache_id]; - rd_lseek_file(fd, cache_idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER))); - rd_write_file(fd, &cellhdr, sizeof(CELLHEADER)); - rd_write_file(fd, data, length); - - return True; -} - -/* List the bitmap keys from the persistent cache file */ -int -pstcache_enumerate(uint8 id, HASH_KEY * keylist) -{ - int fd, n; - uint16 idx; - sint16 mru_idx[0xa00]; - uint32 mru_stamp[0xa00]; - CELLHEADER cellhdr; - - if (!(g_bitmap_cache && g_bitmap_cache_persist_enable && IS_PERSISTENT(id))) - return 0; - - /* The server disconnects if the bitmap cache content is sent more than once */ - if (g_pstcache_enumerated) - return 0; - - DEBUG_RDP5(("Persistent bitmap cache enumeration... ")); - for (idx = 0; idx < BMPCACHE2_NUM_PSTCELLS; idx++) - { - fd = g_pstcache_fd[id]; - rd_lseek_file(fd, idx * (g_pstcache_Bpp * MAX_CELL_SIZE + sizeof(CELLHEADER))); - if (rd_read_file(fd, &cellhdr, sizeof(CELLHEADER)) <= 0) - break; - - if (memcmp(cellhdr.key, zero_key, sizeof(HASH_KEY)) != 0) - { - memcpy(keylist[idx], cellhdr.key, sizeof(HASH_KEY)); - - /* Pre-cache (not possible for 8 bit colour depth cause it needs a colourmap) */ - if (g_bitmap_cache_precache && cellhdr.stamp && g_server_depth > 8) - pstcache_load_bitmap(id, idx); - - /* Sort by stamp */ - for (n = idx; n > 0 && cellhdr.stamp < mru_stamp[n - 1]; n--) - { - mru_idx[n] = mru_idx[n - 1]; - mru_stamp[n] = mru_stamp[n - 1]; - } - - mru_idx[n] = idx; - mru_stamp[n] = cellhdr.stamp; - } - else - { - break; - } - } - - DEBUG_RDP5(("%d cached bitmaps.\n", idx)); - - cache_rebuild_bmpcache_linked_list(id, mru_idx, idx); - g_pstcache_enumerated = True; - return idx; -} - -/* initialise the persistent bitmap cache */ -BOOL -pstcache_init(uint8 cache_id) -{ - int fd; - char filename[256]; - - if (g_pstcache_enumerated) - return True; - - g_pstcache_fd[cache_id] = 0; - - if (!(g_bitmap_cache && g_bitmap_cache_persist_enable)) - return False; - - if (!rd_pstcache_mkdir()) - { - DEBUG(("failed to get/make cache directory!\n")); - return False; - } - - g_pstcache_Bpp = (g_server_depth + 7) / 8; - sprintf(filename, "cache/pstcache_%d_%d", cache_id, g_pstcache_Bpp); - DEBUG(("persistent bitmap cache file: %s\n", filename)); - - fd = rd_open_file(filename); - if (fd == -1) - return False; - - if (!rd_lock_file(fd, 0, 0)) - { - warning("Persistent bitmap caching is disabled. (The file is already in use)\n"); - rd_close_file(fd); - return False; - } - - g_pstcache_fd[cache_id] = fd; - return True; -} diff --git a/uirdesktop/rdp.c b/uirdesktop/rdp.c deleted file mode 100644 index ed2452d4..00000000 --- a/uirdesktop/rdp.c +++ /dev/null @@ -1,1470 +0,0 @@ -/* -*- c-basic-offset: 8 -*- - rdesktop: A Remote Desktop Protocol client. - Protocol services - RDP layer - Copyright (C) Matthew Chapman 1999-2005 - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -//#include -#ifndef _WIN32 -#include -#include -#endif -#include "rdesktop.h" - -#ifdef HAVE_ICONV -#ifdef HAVE_ICONV_H -#include -#endif - -#ifndef ICONV_CONST -#define ICONV_CONST "" -#endif -#endif - -extern uint16 g_mcs_userid; -extern char g_username[64]; -extern char g_codepage[16]; -extern BOOL g_bitmap_compression; -extern BOOL g_orders; -extern BOOL g_encryption; -extern BOOL g_desktop_save; -extern BOOL g_polygon_ellipse_orders; -extern BOOL g_use_rdp5; -extern uint16 g_server_rdp_version; -extern uint32 g_rdp5_performanceflags; -extern int g_server_depth; -extern int g_width; -extern int g_height; -extern BOOL g_bitmap_cache; -extern BOOL g_bitmap_cache_persist_enable; - -uint8 *g_next_packet; -uint32 g_rdp_shareid; - -extern RDPCOMP g_mppc_dict; - -/* Session Directory support */ -extern BOOL g_redirect; -extern char g_redirect_server[64]; -extern char g_redirect_domain[16]; -extern char g_redirect_password[64]; -extern char g_redirect_username[64]; -extern char g_redirect_cookie[128]; -extern uint32 g_redirect_flags; -/* END Session Directory support */ - -#ifdef WITH_DEBUG -static uint32 g_packetno; -#endif - -#ifdef HAVE_ICONV -static BOOL g_iconv_works = True; -#endif - -/* Receive an RDP packet */ -static STREAM -rdp_recv(uint8 * type) -{ - static STREAM rdp_s; - uint16 length, pdu_type; - uint8 rdpver; - - if ((rdp_s == NULL) || (g_next_packet >= rdp_s->end) || (g_next_packet == NULL)) - { - rdp_s = sec_recv(&rdpver); - if (rdp_s == NULL) - return NULL; - if (rdpver == 0xff) - { - g_next_packet = rdp_s->end; - *type = 0; - return rdp_s; - } - else if (rdpver != 3) - { - /* rdp5_process should move g_next_packet ok */ - rdp5_process(rdp_s); - *type = 0; - return rdp_s; - } - - g_next_packet = rdp_s->p; - } - else - { - rdp_s->p = g_next_packet; - } - - in_uint16_le(rdp_s, length); - /* 32k packets are really 8, keepalive fix */ - if (length == 0x8000) - { - g_next_packet += 8; - *type = 0; - return rdp_s; - } - in_uint16_le(rdp_s, pdu_type); - in_uint8s(rdp_s, 2); /* userid */ - *type = pdu_type & 0xf; - -#ifdef WITH_DEBUG - DEBUG(("RDP packet #%d, (type %x)\n", ++g_packetno, *type)); - hexdump(g_next_packet, length); -#endif /* */ - - g_next_packet += length; - return rdp_s; -} - -/* Initialise an RDP data packet */ -static STREAM -rdp_init_data(int maxlen) -{ - STREAM s; - - s = sec_init(g_encryption ? SEC_ENCRYPT : 0, maxlen + 18); - s_push_layer(s, rdp_hdr, 18); - - return s; -} - -/* Send an RDP data packet */ -static void -rdp_send_data(STREAM s, uint8 data_pdu_type) -{ - uint16 length; - - s_pop_layer(s, rdp_hdr); - length = s->end - s->p; - - out_uint16_le(s, length); - out_uint16_le(s, (RDP_PDU_DATA | 0x10)); - out_uint16_le(s, (g_mcs_userid + 1001)); - - out_uint32_le(s, g_rdp_shareid); - out_uint8(s, 0); /* pad */ - out_uint8(s, 1); /* streamid */ - out_uint16_le(s, (length - 14)); - out_uint8(s, data_pdu_type); - out_uint8(s, 0); /* compress_type */ - out_uint16(s, 0); /* compress_len */ - - sec_send(s, g_encryption ? SEC_ENCRYPT : 0); -} - -/* Output a string in Unicode */ -void -rdp_out_unistr(STREAM s, char *string, int len) -{ -#ifdef HAVE_ICONV - size_t ibl = strlen(string), obl = len + 2; - static iconv_t iconv_h = (iconv_t) - 1; - char *pin = string, *pout = (char *) s->p; - - memset(pout, 0, len + 4); - - if (g_iconv_works) - { - if (iconv_h == (iconv_t) - 1) - { - size_t i = 1, o = 4; - if ((iconv_h = iconv_open(WINDOWS_CODEPAGE, g_codepage)) == (iconv_t) - 1) - { - warning("rdp_out_unistr: iconv_open[%s -> %s] fail %d\n", - g_codepage, WINDOWS_CODEPAGE, (int) iconv_h); - - g_iconv_works = False; - rdp_out_unistr(s, string, len); - return; - } - if (iconv(iconv_h, (ICONV_CONST char **) &pin, &i, &pout, &o) == - (size_t) - 1) - { - iconv_close(iconv_h); - iconv_h = (iconv_t) - 1; - warning("rdp_out_unistr: iconv(1) fail, errno %d\n", errno); - - g_iconv_works = False; - rdp_out_unistr(s, string, len); - return; - } - pin = string; - pout = (char *) s->p; - } - - if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1) - { - iconv_close(iconv_h); - iconv_h = (iconv_t) - 1; - warning("rdp_out_unistr: iconv(2) fail, errno %d\n", errno); - - g_iconv_works = False; - rdp_out_unistr(s, string, len); - return; - } - - s->p += len + 2; - - } - else -#endif - { - int i = 0, j = 0; - - len += 2; - - while (i < len) - { - s->p[i++] = string[j++]; - s->p[i++] = 0; - } - - s->p += len; - } -} - -/* Input a string in Unicode - * - * Returns str_len of string - */ -int -rdp_in_unistr(STREAM s, char *string, int uni_len) -{ -#ifdef HAVE_ICONV - size_t ibl = uni_len, obl = uni_len; - char *pin = (char *) s->p, *pout = string; - static iconv_t iconv_h = (iconv_t) - 1; - - if (g_iconv_works) - { - if (iconv_h == (iconv_t) - 1) - { - if ((iconv_h = iconv_open(g_codepage, WINDOWS_CODEPAGE)) == (iconv_t) - 1) - { - warning("rdp_in_unistr: iconv_open[%s -> %s] fail %d\n", - WINDOWS_CODEPAGE, g_codepage, (int) iconv_h); - - g_iconv_works = False; - return rdp_in_unistr(s, string, uni_len); - } - } - - if (iconv(iconv_h, (ICONV_CONST char **) &pin, &ibl, &pout, &obl) == (size_t) - 1) - { - iconv_close(iconv_h); - iconv_h = (iconv_t) - 1; - warning("rdp_in_unistr: iconv fail, errno %d\n", errno); - - g_iconv_works = False; - return rdp_in_unistr(s, string, uni_len); - } - - /* we must update the location of the current STREAM for future reads of s->p */ - s->p += uni_len; - - return pout - string; - } - else -#endif - { - int i = 0; - - while (i < uni_len / 2) - { - in_uint8a(s, &string[i++], 1); - in_uint8s(s, 1); - } - - return i - 1; - } -} - - -/* Parse a logon info packet */ -static void -rdp_send_logon_info(uint32 flags, char *domain, char *user, - char *password, char *program, char *directory) -{ - char *ipaddr = tcp_get_address(); - int len_domain = 2 * strlen(domain); - int len_user = 2 * strlen(user); - int len_password = 2 * strlen(password); - int len_program = 2 * strlen(program); - int len_directory = 2 * strlen(directory); - int len_ip = 2 * strlen(ipaddr); - int len_dll = 2 * strlen("C:\\WINNT\\System32\\mstscax.dll"); - int packetlen = 0; - uint32 sec_flags = g_encryption ? (SEC_LOGON_INFO | SEC_ENCRYPT) : SEC_LOGON_INFO; - STREAM s; - time_t tzone; - -#ifdef _WIN32 - TIME_ZONE_INFORMATION tzi; -#else - time_t t = time(NULL); -#endif - - if (!g_use_rdp5 || 1 == g_server_rdp_version) - { - DEBUG_RDP5(("Sending RDP4-style Logon packet\n")); - - s = sec_init(sec_flags, 18 + len_domain + len_user + len_password - + len_program + len_directory + 10); - - out_uint32(s, 0); - out_uint32_le(s, flags); - out_uint16_le(s, len_domain); - out_uint16_le(s, len_user); - out_uint16_le(s, len_password); - out_uint16_le(s, len_program); - out_uint16_le(s, len_directory); - rdp_out_unistr(s, domain, len_domain); - rdp_out_unistr(s, user, len_user); - rdp_out_unistr(s, password, len_password); - rdp_out_unistr(s, program, len_program); - rdp_out_unistr(s, directory, len_directory); - } - else - { - flags |= RDP_LOGON_BLOB; - DEBUG_RDP5(("Sending RDP5-style Logon packet\n")); - packetlen = 4 + /* Unknown uint32 */ - 4 + /* flags */ - 2 + /* len_domain */ - 2 + /* len_user */ - (flags & RDP_LOGON_AUTO ? 2 : 0) + /* len_password */ - (flags & RDP_LOGON_BLOB ? 2 : 0) + /* Length of BLOB */ - 2 + /* len_program */ - 2 + /* len_directory */ - (0 < len_domain ? len_domain : 2) + /* domain */ - len_user + (flags & RDP_LOGON_AUTO ? len_password : 0) + 0 + /* We have no 512 byte BLOB. Perhaps we must? */ - (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO) ? 2 : 0) + /* After the BLOB is a unknown int16. If there is a BLOB, that is. */ - (0 < len_program ? len_program : 2) + (0 < len_directory ? len_directory : 2) + 2 + /* Unknown (2) */ - 2 + /* Client ip length */ - len_ip + /* Client ip */ - 2 + /* DLL string length */ - len_dll + /* DLL string */ - 2 + /* Unknown */ - 2 + /* Unknown */ - 64 + /* Time zone #0 */ - 2 + /* Unknown */ - 64 + /* Time zone #1 */ - 32; /* Unknown */ - - s = sec_init(sec_flags, packetlen); - DEBUG_RDP5(("Called sec_init with packetlen %d\n", packetlen)); - - out_uint32(s, 0); /* Unknown */ - out_uint32_le(s, flags); - out_uint16_le(s, len_domain); - out_uint16_le(s, len_user); - if (flags & RDP_LOGON_AUTO) - { - out_uint16_le(s, len_password); - - } - if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO)) - { - out_uint16_le(s, 0); - } - out_uint16_le(s, len_program); - out_uint16_le(s, len_directory); - if (0 < len_domain) - rdp_out_unistr(s, domain, len_domain); - else - out_uint16_le(s, 0); - rdp_out_unistr(s, user, len_user); - if (flags & RDP_LOGON_AUTO) - { - rdp_out_unistr(s, password, len_password); - } - if (flags & RDP_LOGON_BLOB && !(flags & RDP_LOGON_AUTO)) - { - out_uint16_le(s, 0); - } - if (0 < len_program) - { - rdp_out_unistr(s, program, len_program); - - } - else - { - out_uint16_le(s, 0); - } - if (0 < len_directory) - { - rdp_out_unistr(s, directory, len_directory); - } - else - { - out_uint16_le(s, 0); - } - out_uint16_le(s, 2); - out_uint16_le(s, len_ip + 2); /* Length of client ip */ - rdp_out_unistr(s, ipaddr, len_ip); - out_uint16_le(s, len_dll + 2); - rdp_out_unistr(s, "C:\\WINNT\\System32\\mstscax.dll", len_dll); - -#ifdef _WIN32 - GetTimeZoneInformation(&tzi); - tzone = tzi.Bias; -#else - tzone = (mktime(gmtime(&t)) - mktime(localtime(&t))) / 60; -#endif - out_uint32_le(s, tzone); - - rdp_out_unistr(s, "GTB, normaltid", 2 * strlen("GTB, normaltid")); - out_uint8s(s, 62 - 2 * strlen("GTB, normaltid")); - - out_uint32_le(s, 0x0a0000); - out_uint32_le(s, 0x050000); - out_uint32_le(s, 3); - out_uint32_le(s, 0); - out_uint32_le(s, 0); - - rdp_out_unistr(s, "GTB, sommartid", 2 * strlen("GTB, sommartid")); - out_uint8s(s, 62 - 2 * strlen("GTB, sommartid")); - - out_uint32_le(s, 0x30000); - out_uint32_le(s, 0x050000); - out_uint32_le(s, 2); - out_uint32(s, 0); - out_uint32_le(s, 0xffffffc4); - out_uint32_le(s, 0xfffffffe); - out_uint32_le(s, g_rdp5_performanceflags); - out_uint32(s, 0); - } - s_mark_end(s); - sec_send(s, sec_flags); -} - -/* Send a control PDU */ -static void -rdp_send_control(uint16 action) -{ - STREAM s; - - s = rdp_init_data(8); - - out_uint16_le(s, action); - out_uint16(s, 0); /* userid */ - out_uint32(s, 0); /* control id */ - - s_mark_end(s); - rdp_send_data(s, RDP_DATA_PDU_CONTROL); -} - -/* Send a synchronisation PDU */ -static void -rdp_send_synchronise(void) -{ - STREAM s; - - s = rdp_init_data(4); - - out_uint16_le(s, 1); /* type */ - out_uint16_le(s, 1002); - - s_mark_end(s); - rdp_send_data(s, RDP_DATA_PDU_SYNCHRONISE); -} - -/* Send a single input event */ -void -rdp_send_input(uint32 time, uint16 message_type, uint16 device_flags, uint16 param1, uint16 param2) -{ - STREAM s; - - s = rdp_init_data(16); - - out_uint16_le(s, 1); /* number of events */ - out_uint16(s, 0); /* pad */ - - out_uint32_le(s, time); - out_uint16_le(s, message_type); - out_uint16_le(s, device_flags); - out_uint16_le(s, param1); - out_uint16_le(s, param2); - - s_mark_end(s); - rdp_send_data(s, RDP_DATA_PDU_INPUT); -} - -/* Send a client window information PDU */ -void -rdp_send_client_window_status(int status) -{ - STREAM s; - static int current_status = 1; - - if (current_status == status) - return; - - s = rdp_init_data(12); - - out_uint32_le(s, status); - - switch (status) - { - case 0: /* shut the server up */ - break; - - case 1: /* receive data again */ - out_uint32_le(s, 0); /* unknown */ - out_uint16_le(s, g_width); - out_uint16_le(s, g_height); - break; - } - - s_mark_end(s); - rdp_send_data(s, RDP_DATA_PDU_CLIENT_WINDOW_STATUS); - current_status = status; -} - -/* Send persistent bitmap cache enumeration PDU's */ -static void -rdp_enum_bmpcache2(void) -{ - STREAM s; - HASH_KEY keylist[BMPCACHE2_NUM_PSTCELLS]; - uint32 num_keys, offset, count, flags; - - offset = 0; - num_keys = pstcache_enumerate(2, keylist); - - while (offset < num_keys) - { - count = MIN(num_keys - offset, 169); - - s = rdp_init_data(24 + count * sizeof(HASH_KEY)); - - flags = 0; - if (offset == 0) - flags |= PDU_FLAG_FIRST; - if (num_keys - offset <= 169) - flags |= PDU_FLAG_LAST; - - /* header */ - out_uint32_le(s, 0); - out_uint16_le(s, count); - out_uint16_le(s, 0); - out_uint16_le(s, 0); - out_uint16_le(s, 0); - out_uint16_le(s, 0); - out_uint16_le(s, num_keys); - out_uint32_le(s, 0); - out_uint32_le(s, flags); - - /* list */ - out_uint8a(s, keylist[offset], count * sizeof(HASH_KEY)); - - s_mark_end(s); - rdp_send_data(s, 0x2b); - - offset += 169; - } -} - -/* Send an (empty) font information PDU */ -static void -rdp_send_fonts(uint16 seq) -{ - STREAM s; - - s = rdp_init_data(8); - - out_uint16(s, 0); /* number of fonts */ - out_uint16_le(s, 0); /* pad? */ - out_uint16_le(s, seq); /* unknown */ - out_uint16_le(s, 0x32); /* entry size */ - - s_mark_end(s); - rdp_send_data(s, RDP_DATA_PDU_FONT2); -} - -/* Output general capability set */ -static void -rdp_out_general_caps(STREAM s) -{ - out_uint16_le(s, RDP_CAPSET_GENERAL); - out_uint16_le(s, RDP_CAPLEN_GENERAL); - - out_uint16_le(s, 1); /* OS major type */ - out_uint16_le(s, 3); /* OS minor type */ - out_uint16_le(s, 0x200); /* Protocol version */ - out_uint16(s, 0); /* Pad */ - out_uint16(s, 0); /* Compression types */ - out_uint16_le(s, g_use_rdp5 ? 0x40d : 0); - /* Pad, according to T.128. 0x40d seems to - trigger - the server to start sending RDP5 packets. - However, the value is 0x1d04 with W2KTSK and - NT4MS. Hmm.. Anyway, thankyou, Microsoft, - for sending such information in a padding - field.. */ - out_uint16(s, 0); /* Update capability */ - out_uint16(s, 0); /* Remote unshare capability */ - out_uint16(s, 0); /* Compression level */ - out_uint16(s, 0); /* Pad */ -} - -/* Output bitmap capability set */ -static void -rdp_out_bitmap_caps(STREAM s) -{ - out_uint16_le(s, RDP_CAPSET_BITMAP); - out_uint16_le(s, RDP_CAPLEN_BITMAP); - - out_uint16_le(s, g_server_depth); /* Preferred colour depth */ - out_uint16_le(s, 1); /* Receive 1 BPP */ - out_uint16_le(s, 1); /* Receive 4 BPP */ - out_uint16_le(s, 1); /* Receive 8 BPP */ - out_uint16_le(s, 800); /* Desktop width */ - out_uint16_le(s, 600); /* Desktop height */ - out_uint16(s, 0); /* Pad */ - out_uint16(s, 1); /* Allow resize */ - out_uint16_le(s, g_bitmap_compression ? 1 : 0); /* Support compression */ - out_uint16(s, 0); /* Unknown */ - out_uint16_le(s, 1); /* Unknown */ - out_uint16(s, 0); /* Pad */ -} - -/* Output order capability set */ -static void -rdp_out_order_caps(STREAM s) -{ - uint8 order_caps[32]; - - memset(order_caps, 0, 32); - order_caps[0] = 1; /* dest blt */ - order_caps[1] = 1; /* pat blt */ - order_caps[2] = 1; /* screen blt */ - order_caps[3] = (g_bitmap_cache ? 1 : 0); /* memblt */ - order_caps[4] = 0; /* triblt */ - order_caps[8] = 1; /* line */ - order_caps[9] = 1; /* line */ - order_caps[10] = 1; /* rect */ - order_caps[11] = (g_desktop_save ? 1 : 0); /* desksave */ - order_caps[13] = 1; /* memblt */ - order_caps[14] = 1; /* triblt */ - order_caps[20] = (g_polygon_ellipse_orders ? 1 : 0); /* polygon */ - order_caps[21] = (g_polygon_ellipse_orders ? 1 : 0); /* polygon2 */ - order_caps[22] = 1; /* polyline */ - order_caps[25] = (g_polygon_ellipse_orders ? 1 : 0); /* ellipse */ - order_caps[26] = (g_polygon_ellipse_orders ? 1 : 0); /* ellipse2 */ - order_caps[27] = 1; /* text2 */ - out_uint16_le(s, RDP_CAPSET_ORDER); - out_uint16_le(s, RDP_CAPLEN_ORDER); - - out_uint8s(s, 20); /* Terminal desc, pad */ - out_uint16_le(s, 1); /* Cache X granularity */ - out_uint16_le(s, 20); /* Cache Y granularity */ - out_uint16(s, 0); /* Pad */ - out_uint16_le(s, 1); /* Max order level */ - out_uint16_le(s, 0x147); /* Number of fonts */ - out_uint16_le(s, 0x2a); /* Capability flags */ - out_uint8p(s, order_caps, 32); /* Orders supported */ - out_uint16_le(s, 0x6a1); /* Text capability flags */ - out_uint8s(s, 6); /* Pad */ - out_uint32_le(s, g_desktop_save == False ? 0 : 0x38400); /* Desktop cache size */ - out_uint32(s, 0); /* Unknown */ - out_uint32_le(s, 0x4e4); /* Unknown */ -} - -/* Output bitmap cache capability set */ -static void -rdp_out_bmpcache_caps(STREAM s) -{ - int Bpp; - out_uint16_le(s, RDP_CAPSET_BMPCACHE); - out_uint16_le(s, RDP_CAPLEN_BMPCACHE); - - Bpp = (g_server_depth + 7) / 8; /* bytes per pixel */ - out_uint8s(s, 24); /* unused */ - out_uint16_le(s, 0x258); /* entries */ - out_uint16_le(s, 0x100 * Bpp); /* max cell size */ - out_uint16_le(s, 0x12c); /* entries */ - out_uint16_le(s, 0x400 * Bpp); /* max cell size */ - out_uint16_le(s, 0x106); /* entries */ - out_uint16_le(s, 0x1000 * Bpp); /* max cell size */ -} - -/* Output bitmap cache v2 capability set */ -static void -rdp_out_bmpcache2_caps(STREAM s) -{ - out_uint16_le(s, RDP_CAPSET_BMPCACHE2); - out_uint16_le(s, RDP_CAPLEN_BMPCACHE2); - - out_uint16_le(s, g_bitmap_cache_persist_enable ? 2 : 0); /* version */ - - out_uint16_be(s, 3); /* number of caches in this set */ - - /* max cell size for cache 0 is 16x16, 1 = 32x32, 2 = 64x64, etc */ - out_uint32_le(s, BMPCACHE2_C0_CELLS); - out_uint32_le(s, BMPCACHE2_C1_CELLS); - if (pstcache_init(2)) - { - out_uint32_le(s, BMPCACHE2_NUM_PSTCELLS | BMPCACHE2_FLAG_PERSIST); - } - else - { - out_uint32_le(s, BMPCACHE2_C2_CELLS); - } - out_uint8s(s, 20); /* other bitmap caches not used */ -} - -/* Output control capability set */ -static void -rdp_out_control_caps(STREAM s) -{ - out_uint16_le(s, RDP_CAPSET_CONTROL); - out_uint16_le(s, RDP_CAPLEN_CONTROL); - - out_uint16(s, 0); /* Control capabilities */ - out_uint16(s, 0); /* Remote detach */ - out_uint16_le(s, 2); /* Control interest */ - out_uint16_le(s, 2); /* Detach interest */ -} - -/* Output activation capability set */ -static void -rdp_out_activate_caps(STREAM s) -{ - out_uint16_le(s, RDP_CAPSET_ACTIVATE); - out_uint16_le(s, RDP_CAPLEN_ACTIVATE); - - out_uint16(s, 0); /* Help key */ - out_uint16(s, 0); /* Help index key */ - out_uint16(s, 0); /* Extended help key */ - out_uint16(s, 0); /* Window activate */ -} - -/* Output pointer capability set */ -static void -rdp_out_pointer_caps(STREAM s) -{ - out_uint16_le(s, RDP_CAPSET_POINTER); - out_uint16_le(s, RDP_CAPLEN_POINTER); - - out_uint16(s, 0); /* Colour pointer */ - out_uint16_le(s, 20); /* Cache size */ -} - -/* Output share capability set */ -static void -rdp_out_share_caps(STREAM s) -{ - out_uint16_le(s, RDP_CAPSET_SHARE); - out_uint16_le(s, RDP_CAPLEN_SHARE); - - out_uint16(s, 0); /* userid */ - out_uint16(s, 0); /* pad */ -} - -/* Output colour cache capability set */ -static void -rdp_out_colcache_caps(STREAM s) -{ - out_uint16_le(s, RDP_CAPSET_COLCACHE); - out_uint16_le(s, RDP_CAPLEN_COLCACHE); - - out_uint16_le(s, 6); /* cache size */ - out_uint16(s, 0); /* pad */ -} - -static uint8 caps_0x0d[] = { - 0x01, 0x00, 0x00, 0x00, 0x09, 0x04, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 -}; - -static uint8 caps_0x0c[] = { 0x01, 0x00, 0x00, 0x00 }; - -static uint8 caps_0x0e[] = { 0x01, 0x00, 0x00, 0x00 }; - -static uint8 caps_0x10[] = { - 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 -}; - -/* Output unknown capability sets */ -static void -rdp_out_unknown_caps(STREAM s, uint16 id, uint16 length, uint8 * caps) -{ - out_uint16_le(s, id); - out_uint16_le(s, length); - - out_uint8p(s, caps, length - 4); -} - -#define RDP5_FLAG 0x0030 -/* Send a confirm active PDU */ -static void -rdp_send_confirm_active(void) -{ - STREAM s; - uint32 sec_flags = g_encryption ? (RDP5_FLAG | SEC_ENCRYPT) : RDP5_FLAG; - uint16 caplen = - 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 + - 0x58 + 0x08 + 0x08 + 0x34 /* unknown caps */ + - 4 /* w2k fix, why? */ ; - - s = sec_init(sec_flags, 6 + 14 + caplen + sizeof(RDP_SOURCE)); - - out_uint16_le(s, 2 + 14 + caplen + sizeof(RDP_SOURCE)); - out_uint16_le(s, (RDP_PDU_CONFIRM_ACTIVE | 0x10)); /* Version 1 */ - out_uint16_le(s, (g_mcs_userid + 1001)); - - out_uint32_le(s, g_rdp_shareid); - out_uint16_le(s, 0x3ea); /* userid */ - out_uint16_le(s, sizeof(RDP_SOURCE)); - out_uint16_le(s, caplen); - - out_uint8p(s, RDP_SOURCE, sizeof(RDP_SOURCE)); - out_uint16_le(s, 0xd); /* num_caps */ - out_uint8s(s, 2); /* pad */ - - rdp_out_general_caps(s); - rdp_out_bitmap_caps(s); - rdp_out_order_caps(s); - g_use_rdp5 ? rdp_out_bmpcache2_caps(s) : rdp_out_bmpcache_caps(s); - rdp_out_colcache_caps(s); - rdp_out_activate_caps(s); - rdp_out_control_caps(s); - rdp_out_pointer_caps(s); - rdp_out_share_caps(s); - - rdp_out_unknown_caps(s, 0x0d, 0x58, caps_0x0d); /* international? */ - rdp_out_unknown_caps(s, 0x0c, 0x08, caps_0x0c); - rdp_out_unknown_caps(s, 0x0e, 0x08, caps_0x0e); - rdp_out_unknown_caps(s, 0x10, 0x34, caps_0x10); /* glyph cache? */ - - s_mark_end(s); - sec_send(s, sec_flags); -} - -/* Process a general capability set */ -static void -rdp_process_general_caps(STREAM s) -{ - uint16 pad2octetsB; /* rdp5 flags? */ - - in_uint8s(s, 10); - in_uint16_le(s, pad2octetsB); - - if (!pad2octetsB) - g_use_rdp5 = False; -} - -/* Process a bitmap capability set */ -static void -rdp_process_bitmap_caps(STREAM s) -{ - uint16 width, height, depth; - - in_uint16_le(s, depth); - in_uint8s(s, 6); - - in_uint16_le(s, width); - in_uint16_le(s, height); - - DEBUG(("setting desktop size and depth to: %dx%dx%d\n", width, height, depth)); - - /* - * The server may limit depth and change the size of the desktop (for - * example when shadowing another session). - */ - if (g_server_depth != depth) - { - warning("Remote desktop does not support colour depth %d; falling back to %d\n", - g_server_depth, depth); - g_server_depth = depth; - } - if (g_width != width || g_height != height) - { - warning("Remote desktop changed from %dx%d to %dx%d.\n", g_width, g_height, - width, height); - g_width = width; - g_height = height; - ui_resize_window(); - } -} - -/* Process server capabilities */ -static void -rdp_process_server_caps(STREAM s, uint16 length) -{ - int n; - uint8 *next, *start; - uint16 ncapsets, capset_type, capset_length; - - start = s->p; - - in_uint16_le(s, ncapsets); - in_uint8s(s, 2); /* pad */ - - for (n = 0; n < ncapsets; n++) - { - if (s->p > start + length) - return; - - in_uint16_le(s, capset_type); - in_uint16_le(s, capset_length); - - next = s->p + capset_length - 4; - - switch (capset_type) - { - case RDP_CAPSET_GENERAL: - rdp_process_general_caps(s); - break; - - case RDP_CAPSET_BITMAP: - rdp_process_bitmap_caps(s); - break; - } - - s->p = next; - } -} - -/* Respond to a demand active PDU */ -static void -process_demand_active(STREAM s) -{ - uint8 type; - uint16 len_src_descriptor, len_combined_caps; - - in_uint32_le(s, g_rdp_shareid); - in_uint16_le(s, len_src_descriptor); - in_uint16_le(s, len_combined_caps); - in_uint8s(s, len_src_descriptor); - - DEBUG(("DEMAND_ACTIVE(id=0x%x)\n", g_rdp_shareid)); - rdp_process_server_caps(s, len_combined_caps); - - rdp_send_confirm_active(); - rdp_send_synchronise(); - rdp_send_control(RDP_CTL_COOPERATE); - rdp_send_control(RDP_CTL_REQUEST_CONTROL); - rdp_recv(&type); /* RDP_PDU_SYNCHRONIZE */ - rdp_recv(&type); /* RDP_CTL_COOPERATE */ - rdp_recv(&type); /* RDP_CTL_GRANT_CONTROL */ - rdp_send_input(0, RDP_INPUT_SYNCHRONIZE, 0, ui_get_numlock_state(read_keyboard_state()), 0); - - if (g_use_rdp5) - { - rdp_enum_bmpcache2(); - rdp_send_fonts(3); - } - else - { - rdp_send_fonts(1); - rdp_send_fonts(2); - } - - rdp_recv(&type); /* RDP_PDU_UNKNOWN 0x28 (Fonts?) */ - reset_order_state(); -} - -/* Process a colour pointer PDU */ -void -process_colour_pointer_pdu(STREAM s) -{ - uint16 x, y, width, height, cache_idx, masklen, datalen; - uint8 *mask, *data; - RD_HCURSOR cursor; - - in_uint16_le(s, cache_idx); - in_uint16_le(s, x); - in_uint16_le(s, y); - in_uint16_le(s, width); - in_uint16_le(s, height); - in_uint16_le(s, masklen); - in_uint16_le(s, datalen); - in_uint8p(s, data, datalen); - in_uint8p(s, mask, masklen); - cursor = ui_create_cursor(x, y, width, height, mask, data); - ui_set_cursor(cursor); - cache_put_cursor(cache_idx, cursor); -} - -/* Process a cached pointer PDU */ -void -process_cached_pointer_pdu(STREAM s) -{ - uint16 cache_idx; - - in_uint16_le(s, cache_idx); - ui_set_cursor(cache_get_cursor(cache_idx)); -} - -/* Process a system pointer PDU */ -void -process_system_pointer_pdu(STREAM s) -{ - uint16 system_pointer_type; - - in_uint16(s, system_pointer_type); - switch (system_pointer_type) - { - case RDP_NULL_POINTER: - ui_set_null_cursor(); - break; - - default: - unimpl("System pointer message 0x%x\n", system_pointer_type); - } -} - -/* Process a pointer PDU */ -static void -process_pointer_pdu(STREAM s) -{ - uint16 message_type; - uint16 x, y; - - in_uint16_le(s, message_type); - in_uint8s(s, 2); /* pad */ - - switch (message_type) - { - case RDP_POINTER_MOVE: - in_uint16_le(s, x); - in_uint16_le(s, y); - if (s_check(s)) - ui_move_pointer(x, y); - break; - - case RDP_POINTER_COLOR: - process_colour_pointer_pdu(s); - break; - - case RDP_POINTER_CACHED: - process_cached_pointer_pdu(s); - break; - - case RDP_POINTER_SYSTEM: - process_system_pointer_pdu(s); - break; - - default: - unimpl("Pointer message 0x%x\n", message_type); - } -} - -/* Process bitmap updates */ -void -process_bitmap_updates(STREAM s) -{ - uint16 num_updates; - uint16 left, top, right, bottom, width, height; - uint16 cx, cy, bpp, Bpp, compress, bufsize, size; - uint8 *data, *bmpdata; - int i; - - in_uint16_le(s, num_updates); - - for (i = 0; i < num_updates; i++) - { - in_uint16_le(s, left); - in_uint16_le(s, top); - in_uint16_le(s, right); - in_uint16_le(s, bottom); - in_uint16_le(s, width); - in_uint16_le(s, height); - in_uint16_le(s, bpp); - Bpp = (bpp + 7) / 8; - in_uint16_le(s, compress); - in_uint16_le(s, bufsize); - - cx = right - left + 1; - cy = bottom - top + 1; - - DEBUG(("BITMAP_UPDATE(l=%d,t=%d,r=%d,b=%d,w=%d,h=%d,Bpp=%d,cmp=%d)\n", - left, top, right, bottom, width, height, Bpp, compress)); - if (!compress) - { - size = width * height * Bpp; /* same as bufsize */ - } - else if (compress & 0x400) - { - size = bufsize; - } - else - { - in_uint8s(s, 2); /* pad */ - in_uint16_le(s, size); - in_uint8s(s, 4); - } - in_uint8p(s, data, size); - ui_paint_bitmap_ex(left, top, cx, cy, width, height, data, size, compress); -#if 0 - if (!compress) - { - int y; - bmpdata = (uint8 *) xmalloc(width * height * Bpp); - for (y = 0; y < height; y++) - { - in_uint8a(s, &bmpdata[(height - y - 1) * (width * Bpp)], - width * Bpp); - } - ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata); - xfree(bmpdata); - continue; - } - - - if (compress & 0x400) - { - size = bufsize; - } - else - { - in_uint8s(s, 2); /* pad */ - in_uint16_le(s, size); - in_uint8s(s, 4); /* line_size, final_size */ - } - in_uint8p(s, data, size); - bmpdata = (uint8 *) xmalloc(width * height * Bpp); - if (bitmap_decompress(bmpdata, width, height, data, size, Bpp)) - { - ui_paint_bitmap(left, top, cx, cy, width, height, bmpdata); - } - else - { - DEBUG_RDP5(("Failed to decompress data\n")); - } - xfree(bmpdata); -#endif - } -} - -/* Process a palette update */ -void -process_palette(STREAM s) -{ - COLOURENTRY *entry; - COLOURMAP map; - RD_HCOLOURMAP hmap; - int i; - - in_uint8s(s, 2); /* pad */ - in_uint16_le(s, map.ncolours); - in_uint8s(s, 2); /* pad */ - - map.colours = (COLOURENTRY *) xmalloc(sizeof(COLOURENTRY) * map.ncolours); - - DEBUG(("PALETTE(c=%d)\n", map.ncolours)); - - for (i = 0; i < map.ncolours; i++) - { - entry = &map.colours[i]; - in_uint8(s, entry->red); - in_uint8(s, entry->green); - in_uint8(s, entry->blue); - } - - hmap = ui_create_colourmap(&map); - ui_set_colourmap(hmap); - - xfree(map.colours); -} - -/* Process an update PDU */ -static void -process_update_pdu(STREAM s) -{ - uint16 update_type, count; - - in_uint16_le(s, update_type); - - ui_begin_update(); - switch (update_type) - { - case RDP_UPDATE_ORDERS: - in_uint8s(s, 2); /* pad */ - in_uint16_le(s, count); - in_uint8s(s, 2); /* pad */ - process_orders(s, count); - break; - - case RDP_UPDATE_BITMAP: - process_bitmap_updates(s); - break; - - case RDP_UPDATE_PALETTE: - process_palette(s); - break; - - case RDP_UPDATE_SYNCHRONIZE: - break; - - default: - unimpl("update %d\n", update_type); - } - ui_end_update(); -} - -/* Process a disconnect PDU */ -void -process_disconnect_pdu(STREAM s, uint32 * ext_disc_reason) -{ - in_uint32_le(s, *ext_disc_reason); - - DEBUG(("Received disconnect PDU\n")); -} - -/* Process data PDU */ -static BOOL -process_data_pdu(STREAM s, uint32 * ext_disc_reason) -{ - uint8 data_pdu_type; - uint8 ctype; - uint16 clen; - uint32 len; - - uint32 roff, rlen; - - struct stream *ns = &(g_mppc_dict.ns); - - in_uint8s(s, 6); /* shareid, pad, streamid */ - in_uint16(s, len); - in_uint8(s, data_pdu_type); - in_uint8(s, ctype); - in_uint16(s, clen); - clen -= 18; - - if (ctype & RDP_MPPC_COMPRESSED) - { - if (len > RDP_MPPC_DICT_SIZE) - error("error decompressed packet size exceeds max\n"); - if (mppc_expand(s->p, clen, ctype, &roff, &rlen) == -1) - error("error while decompressing packet\n"); - - /* len -= 18; */ - - /* allocate memory and copy the uncompressed data into the temporary stream */ - ns->data = (uint8 *) xrealloc(ns->data, rlen); - - memcpy((ns->data), (unsigned char *) (g_mppc_dict.hist + roff), rlen); - - ns->size = rlen; - ns->end = (ns->data + ns->size); - ns->p = ns->data; - ns->rdp_hdr = ns->p; - - s = ns; - } - - switch (data_pdu_type) - { - case RDP_DATA_PDU_UPDATE: - process_update_pdu(s); - break; - - case RDP_DATA_PDU_CONTROL: - DEBUG(("Received Control PDU\n")); - break; - - case RDP_DATA_PDU_SYNCHRONISE: - DEBUG(("Received Sync PDU\n")); - break; - - case RDP_DATA_PDU_POINTER: - process_pointer_pdu(s); - break; - - case RDP_DATA_PDU_BELL: - ui_bell(); - break; - - case RDP_DATA_PDU_LOGON: - DEBUG(("Received Logon PDU\n")); - /* User logged on */ - ui_logon(); - break; - - case RDP_DATA_PDU_DISCONNECT: - process_disconnect_pdu(s, ext_disc_reason); - /* We used to return true and disconnect immediately here, but - * Windows Vista sends a disconnect PDU with reason 0 when - * reconnecting to a disconnected session, and MSTSC doesn't - * drop the connection. I think we should just save the status. - */ - break; - - default: - unimpl("data PDU %d\n", data_pdu_type); - } - return False; -} - -/* Process redirect PDU from Session Directory */ -static BOOL -process_redirect_pdu(STREAM s /*, uint32 * ext_disc_reason */ ) -{ - uint32 len; - - /* these 2 bytes are unknown, seem to be zeros */ - in_uint8s(s, 2); - - /* read connection flags */ - in_uint32_le(s, g_redirect_flags); - - /* read length of ip string */ - in_uint32_le(s, len); - - /* read ip string */ - rdp_in_unistr(s, g_redirect_server, len); - - /* read length of cookie string */ - in_uint32_le(s, len); - - /* read cookie string (plain ASCII) */ - in_uint8a(s, g_redirect_cookie, len); - g_redirect_cookie[len] = 0; - - /* read length of username string */ - in_uint32_le(s, len); - - /* read username string */ - rdp_in_unistr(s, g_redirect_username, len); - - /* read length of domain string */ - in_uint32_le(s, len); - - /* read domain string */ - rdp_in_unistr(s, g_redirect_domain, len); - - /* read length of password string */ - in_uint32_le(s, len); - - /* read password string */ - rdp_in_unistr(s, g_redirect_password, len); - - g_redirect = True; - - return True; -} - -/* Process incoming packets */ -/* nevers gets out of here till app is done */ -void -rdp_main_loop(BOOL * deactivated, uint32 * ext_disc_reason) -{ - while (rdp_loop(deactivated, ext_disc_reason)) - ; -} - -/* used in uiports and rdp_main_loop, processes the rdp packets waiting */ -BOOL -rdp_loop(BOOL * deactivated, uint32 * ext_disc_reason) -{ - uint8 type; - BOOL disc = False; /* True when a disconnect PDU was received */ - BOOL cont = True; - STREAM s; - - while (cont) - { - s = rdp_recv(&type); - if (s == NULL) - return False; - switch (type) - { - case RDP_PDU_DEMAND_ACTIVE: - process_demand_active(s); - *deactivated = False; - break; - case RDP_PDU_DEACTIVATE: - DEBUG(("RDP_PDU_DEACTIVATE\n")); - *deactivated = True; - break; - case RDP_PDU_REDIRECT: - return process_redirect_pdu(s); - break; - case RDP_PDU_DATA: - disc = process_data_pdu(s, ext_disc_reason); - break; - case 0: - break; - default: - unimpl("PDU %d\n", type); - } - if (disc) - return False; - cont = g_next_packet < s->end; - } - return True; -} - -/* Establish a connection up to the RDP layer */ -BOOL -rdp_connect(char *server, uint32 flags, char *domain, char *password, - char *command, char *directory) -{ - if (!sec_connect(server, g_username)) - return False; - - rdp_send_logon_info(flags, domain, g_username, password, command, directory); - return True; -} - -/* Establish a reconnection up to the RDP layer */ -BOOL -rdp_reconnect(char *server, uint32 flags, char *domain, char *password, - char *command, char *directory, char *cookie) -{ - if (!sec_reconnect(server)) - return False; - - rdp_send_logon_info(flags, domain, g_username, password, command, directory); - return True; -} - -/* Called during redirection to reset the state to support redirection */ -void -rdp_reset_state(void) -{ - g_next_packet = NULL; /* reset the packet information */ - g_rdp_shareid = 0; - sec_reset_state(); -} - -/* Disconnect from the RDP layer */ -void -rdp_disconnect(void) -{ - sec_disconnect(); -}