summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--uirdesktop/mcs.c469
-rw-r--r--uirdesktop/mppc.c380
-rw-r--r--uirdesktop/orders.c1319
-rw-r--r--uirdesktop/pstcache.c200
-rw-r--r--uirdesktop/rdp.c1470
5 files changed, 0 insertions, 3838 deletions
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 <stdio.h>
-#include <string.h>
-
-#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 <time.h>
-#ifndef _WIN32
-#include <errno.h>
-#include <unistd.h>
-#endif
-#include "rdesktop.h"
-
-#ifdef HAVE_ICONV
-#ifdef HAVE_ICONV_H
-#include <iconv.h>
-#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();
-}