diff options
Diffstat (limited to 'libxrdp')
-rw-r--r-- | libxrdp/libxrdp.c | 1303 | ||||
-rw-r--r-- | libxrdp/libxrdp.h | 40 | ||||
-rw-r--r-- | libxrdp/libxrdpinc.h | 40 | ||||
-rw-r--r-- | libxrdp/xrdp_bitmap_compress.c | 2618 | ||||
-rw-r--r-- | libxrdp/xrdp_channel.c | 254 | ||||
-rw-r--r-- | libxrdp/xrdp_fastpath.c | 289 | ||||
-rw-r--r-- | libxrdp/xrdp_iso.c | 317 | ||||
-rw-r--r-- | libxrdp/xrdp_jpeg_compress.c | 319 | ||||
-rw-r--r-- | libxrdp/xrdp_mcs.c | 1283 | ||||
-rw-r--r-- | libxrdp/xrdp_orders.c | 3929 | ||||
-rw-r--r-- | libxrdp/xrdp_orders_rail.c | 1096 | ||||
-rw-r--r-- | libxrdp/xrdp_rdp.c | 2585 | ||||
-rw-r--r-- | libxrdp/xrdp_sec.c | 1755 | ||||
-rw-r--r-- | libxrdp/xrdp_surface.c | 211 | ||||
-rw-r--r-- | libxrdp/xrdp_tcp.c | 114 |
15 files changed, 8497 insertions, 7656 deletions
diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index 3f8307c2..a391b93b 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -1,672 +1,720 @@ -/* - 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. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - this is the interface to libxrdp - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * this is the interface to libxrdp + */ #include "libxrdp.h" /******************************************************************************/ -struct xrdp_session* EXPORT_CC -libxrdp_init(tbus id, struct trans* trans) +struct xrdp_session *EXPORT_CC +libxrdp_init(tbus id, struct trans *trans) { - struct xrdp_session* session; + struct xrdp_session *session; - session = (struct xrdp_session*)g_malloc(sizeof(struct xrdp_session), 1); - session->id = id; - session->rdp = xrdp_rdp_create(session, trans); - session->orders = xrdp_orders_create(session, (struct xrdp_rdp*)session->rdp); - session->client_info = &(((struct xrdp_rdp*)session->rdp)->client_info); - make_stream(session->s); - init_stream(session->s, 8192 * 2); - return session; + session = (struct xrdp_session *)g_malloc(sizeof(struct xrdp_session), 1); + session->id = id; + session->rdp = xrdp_rdp_create(session, trans); + session->orders = xrdp_orders_create(session, (struct xrdp_rdp *)session->rdp); + session->client_info = &(((struct xrdp_rdp *)session->rdp)->client_info); + make_stream(session->s); + init_stream(session->s, 8192 * 2); + return session; } /******************************************************************************/ int EXPORT_CC -libxrdp_exit(struct xrdp_session* session) +libxrdp_exit(struct xrdp_session *session) { - if (session == 0) - { + if (session == 0) + { + return 0; + } + + xrdp_orders_delete((struct xrdp_orders *)session->orders); + xrdp_rdp_delete((struct xrdp_rdp *)session->rdp); + free_stream(session->s); + g_free(session); return 0; - } - xrdp_orders_delete((struct xrdp_orders*)session->orders); - xrdp_rdp_delete((struct xrdp_rdp*)session->rdp); - free_stream(session->s); - g_free(session); - return 0; } /******************************************************************************/ int EXPORT_CC -libxrdp_disconnect(struct xrdp_session* session) +libxrdp_disconnect(struct xrdp_session *session) { - return xrdp_rdp_disconnect((struct xrdp_rdp*)session->rdp); + return xrdp_rdp_disconnect((struct xrdp_rdp *)session->rdp); } /******************************************************************************/ int EXPORT_CC -libxrdp_process_incomming(struct xrdp_session* session) +libxrdp_process_incomming(struct xrdp_session *session) { - return xrdp_rdp_incoming((struct xrdp_rdp*)session->rdp); + return xrdp_rdp_incoming((struct xrdp_rdp *)session->rdp); } /******************************************************************************/ int EXPORT_CC -libxrdp_process_data(struct xrdp_session* session) -{ - int cont; - int rv; - int code; - int term; - int dead_lock_counter; - - term = 0; - cont = 1; - rv = 0; - dead_lock_counter = 0; - while ((cont || !session->up_and_running) && !term) - { - if (session->is_term != 0) - { - if (session->is_term()) - { - term = 1; - } - } - code = 0; - if (xrdp_rdp_recv((struct xrdp_rdp*)(session->rdp), - session->s, &code) != 0) - { - rv = 1; - break; - } - DEBUG(("libxrdp_process_data code %d", code)); - switch (code) +libxrdp_process_data(struct xrdp_session *session) +{ + int cont; + int rv; + int code; + int term; + int dead_lock_counter; + + term = 0; + cont = 1; + rv = 0; + dead_lock_counter = 0; + + while ((cont || !session->up_and_running) && !term) { - case -1: - xrdp_rdp_send_demand_active((struct xrdp_rdp*)session->rdp); - session->up_and_running = 0; - break; - case 0: - dead_lock_counter++; - break; - case RDP_PDU_CONFIRM_ACTIVE: /* 3 */ - xrdp_rdp_process_confirm_active((struct xrdp_rdp*)session->rdp, - session->s); - break; - case RDP_PDU_DATA: /* 7 */ - if (xrdp_rdp_process_data((struct xrdp_rdp*)session->rdp, - session->s) != 0) + if (session->is_term != 0) { - DEBUG(("libxrdp_process_data returned non zero")); - cont = 0; - term = 1; + if (session->is_term()) + { + term = 1; + } + } + + code = 0; + + if (xrdp_rdp_recv((struct xrdp_rdp *)(session->rdp), + session->s, &code) != 0) + { + rv = 1; + break; + } + + DEBUG(("libxrdp_process_data code %d", code)); + + switch (code) + { + case -1: + xrdp_rdp_send_demand_active((struct xrdp_rdp *)session->rdp); + session->up_and_running = 0; + break; + case 0: + dead_lock_counter++; + break; + case RDP_PDU_CONFIRM_ACTIVE: /* 3 */ + xrdp_rdp_process_confirm_active((struct xrdp_rdp *)session->rdp, + session->s); + break; + case RDP_PDU_DATA: /* 7 */ + + if (xrdp_rdp_process_data((struct xrdp_rdp *)session->rdp, + session->s) != 0) + { + DEBUG(("libxrdp_process_data returned non zero")); + cont = 0; + term = 1; + } + + break; + default: + g_writeln("unknown in libxrdp_process_data"); + dead_lock_counter++; + break; + } + + if (dead_lock_counter > 100000) + { + /*This situation can happen and this is a workaround*/ + cont = 0; + g_writeln("Serious programming error we were locked in a deadly loop") ; + g_writeln("remaining :%d", session->s->end - session->s->next_packet); + session->s->next_packet = 0; + } + + if (cont) + { + cont = (session->s->next_packet != 0) && + (session->s->next_packet < session->s->end); } - break; - default: - g_writeln("unknown in libxrdp_process_data"); - dead_lock_counter++; - break; - } - if (dead_lock_counter > 100000) - { - /*This situation can happen and this is a workaround*/ - cont = 0; - g_writeln("Serious programming error we were locked in a deadly loop") ; - g_writeln("remaining :%d",session->s->end-session->s->next_packet); - session->s->next_packet = 0; - } - if (cont) - { - cont = (session->s->next_packet != 0) && - (session->s->next_packet < session->s->end); } - } - return rv; + + return rv; } /******************************************************************************/ int EXPORT_CC -libxrdp_send_palette(struct xrdp_session* session, int* palette) +libxrdp_send_palette(struct xrdp_session *session, int *palette) { - int i = 0; - int color = 0; - struct stream* s = (struct stream *)NULL; + int i = 0; + int color = 0; + struct stream *s = (struct stream *)NULL; + + if (session->client_info->bpp > 8) + { + return 0; + } - if (session->client_info->bpp > 8) - { + DEBUG(("libxrdp_send_palette sending palette")); + /* clear orders */ + libxrdp_orders_force_send(session); + make_stream(s); + init_stream(s, 8192); + xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s); + out_uint16_le(s, RDP_UPDATE_PALETTE); + out_uint16_le(s, 0); + out_uint16_le(s, 256); /* # of colors */ + out_uint16_le(s, 0); + + for (i = 0; i < 256; i++) + { + color = palette[i]; + out_uint8(s, color >> 16); + out_uint8(s, color >> 8); + out_uint8(s, color); + } + + s_mark_end(s); + xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, RDP_DATA_PDU_UPDATE); + free_stream(s); + /* send the orders palette too */ + libxrdp_orders_init(session); + libxrdp_orders_send_palette(session, palette, 0); + libxrdp_orders_send(session); return 0; - } - DEBUG(("libxrdp_send_palette sending palette")); - /* clear orders */ - libxrdp_orders_force_send(session); - make_stream(s); - init_stream(s, 8192); - xrdp_rdp_init_data((struct xrdp_rdp*)session->rdp, s); - out_uint16_le(s, RDP_UPDATE_PALETTE); - out_uint16_le(s, 0); - out_uint16_le(s, 256); /* # of colors */ - out_uint16_le(s, 0); - for (i = 0; i < 256; i++) - { - color = palette[i]; - out_uint8(s, color >> 16); - out_uint8(s, color >> 8); - out_uint8(s, color); - } - s_mark_end(s); - xrdp_rdp_send_data((struct xrdp_rdp*)session->rdp, s, RDP_DATA_PDU_UPDATE); - free_stream(s); - /* send the orders palette too */ - libxrdp_orders_init(session); - libxrdp_orders_send_palette(session, palette, 0); - libxrdp_orders_send(session); - return 0; } /******************************************************************************/ int EXPORT_CC -libxrdp_send_bell(struct xrdp_session* session) +libxrdp_send_bell(struct xrdp_session *session) { - struct stream* s = (struct stream *)NULL; + struct stream *s = (struct stream *)NULL; - DEBUG(("libxrdp_send_bell sending bell signal")); - /* see MS documentation: Server play sound PDU, TS_PLAY_SOUND_PDU_DATA */ + DEBUG(("libxrdp_send_bell sending bell signal")); + /* see MS documentation: Server play sound PDU, TS_PLAY_SOUND_PDU_DATA */ - make_stream(s); - init_stream(s, 8192); + make_stream(s); + init_stream(s, 8192); + + if (xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s) != 0) + { + free_stream(s); + return 1; + } + + out_uint32_le(s, 440); /* frequency */ + out_uint32_le(s, 100); /* duration (ms) */ + s_mark_end(s); + + if (xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, RDP_DATA_PDU_PLAY_SOUND) != 0) + { + free_stream(s); + return 1; + } - if (xrdp_rdp_init_data((struct xrdp_rdp*)session->rdp, s) != 0) - { - free_stream(s); - return 1; - } - out_uint32_le(s, 440); /* frequency */ - out_uint32_le(s, 100); /* duration (ms) */ - s_mark_end(s); - if (xrdp_rdp_send_data((struct xrdp_rdp*)session->rdp, s, RDP_DATA_PDU_PLAY_SOUND) != 0) - { free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ int EXPORT_CC -libxrdp_send_bitmap(struct xrdp_session* session, int width, int height, - int bpp, char* data, int x, int y, int cx, int cy) -{ - int line_size = 0; - int i = 0; - int j = 0; - int total_lines = 0; - int lines_sending = 0; - int Bpp = 0; - int e = 0; - int bufsize = 0; - int total_bufsize = 0; - int num_updates = 0; - char* p_num_updates = (char *)NULL; - char* p = (char *)NULL; - char* q = (char *)NULL; - struct stream* s = (struct stream *)NULL; - struct stream* temp_s = (struct stream *)NULL; - - DEBUG(("libxrdp_send_bitmap sending bitmap")); - Bpp = (bpp + 7) / 8; - e = width % 4; - if (e != 0) - { - e = 4 - e; - } - line_size = width * Bpp; - make_stream(s); - init_stream(s, 8192); - if (session->client_info->use_bitmap_comp) - { - make_stream(temp_s); - init_stream(temp_s, 65536); - i = 0; - if (cy <= height) +libxrdp_send_bitmap(struct xrdp_session *session, int width, int height, + int bpp, char *data, int x, int y, int cx, int cy) +{ + int line_size = 0; + int i = 0; + int j = 0; + int total_lines = 0; + int lines_sending = 0; + int Bpp = 0; + int e = 0; + int bufsize = 0; + int total_bufsize = 0; + int num_updates = 0; + char *p_num_updates = (char *)NULL; + char *p = (char *)NULL; + char *q = (char *)NULL; + struct stream *s = (struct stream *)NULL; + struct stream *temp_s = (struct stream *)NULL; + + DEBUG(("libxrdp_send_bitmap sending bitmap")); + Bpp = (bpp + 7) / 8; + e = width % 4; + + if (e != 0) { - i = cy; + e = 4 - e; } - while (i > 0) + + line_size = width * Bpp; + make_stream(s); + init_stream(s, 8192); + + if (session->client_info->use_bitmap_comp) { - total_bufsize = 0; - num_updates = 0; - xrdp_rdp_init_data((struct xrdp_rdp*)session->rdp, s); - out_uint16_le(s, RDP_UPDATE_BITMAP); - p_num_updates = s->p; - out_uint8s(s, 2); /* num_updates set later */ - do - { - if (session->client_info->op1) - { - s_push_layer(s, channel_hdr, 18); - } - else - { - s_push_layer(s, channel_hdr, 26); - } - p = s->p; - lines_sending = xrdp_bitmap_compress(data, width, height, - s, bpp, - 4096 - total_bufsize, - i - 1, temp_s, e); - if (lines_sending == 0) - { - break; - } - num_updates++; - bufsize = s->p - p; - total_bufsize += bufsize; - i = i - lines_sending; - s_mark_end(s); - s_pop_layer(s, channel_hdr); - out_uint16_le(s, x); /* left */ - out_uint16_le(s, y + i); /* top */ - out_uint16_le(s, (x + cx) - 1); /* right */ - out_uint16_le(s, (y + i + lines_sending) - 1); /* bottom */ - out_uint16_le(s, width + e); /* width */ - out_uint16_le(s, lines_sending); /* height */ - out_uint16_le(s, bpp); /* bpp */ - if (session->client_info->op1) - { - out_uint16_le(s, 0x401); /* compress */ - out_uint16_le(s, bufsize); /* compressed size */ - j = (width + e) * Bpp; - j = j * lines_sending; - } - else - { - out_uint16_le(s, 0x1); /* compress */ - out_uint16_le(s, bufsize + 8); - out_uint8s(s, 2); /* pad */ - out_uint16_le(s, bufsize); /* compressed size */ - j = (width + e) * Bpp; - out_uint16_le(s, j); /* line size */ - j = j * lines_sending; - out_uint16_le(s, j); /* final size */ - } - if (j > 32768) + make_stream(temp_s); + init_stream(temp_s, 65536); + i = 0; + + if (cy <= height) { - g_writeln("error, decompressed size too big, its %d", j); + i = cy; } - if (bufsize > 8192) + + while (i > 0) { - g_writeln("error, compressed size too big, its %d", bufsize); + total_bufsize = 0; + num_updates = 0; + xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s); + out_uint16_le(s, RDP_UPDATE_BITMAP); + p_num_updates = s->p; + out_uint8s(s, 2); /* num_updates set later */ + + do + { + if (session->client_info->op1) + { + s_push_layer(s, channel_hdr, 18); + } + else + { + s_push_layer(s, channel_hdr, 26); + } + + p = s->p; + lines_sending = xrdp_bitmap_compress(data, width, height, + s, bpp, + 4096 - total_bufsize, + i - 1, temp_s, e); + + if (lines_sending == 0) + { + break; + } + + num_updates++; + bufsize = s->p - p; + total_bufsize += bufsize; + i = i - lines_sending; + s_mark_end(s); + s_pop_layer(s, channel_hdr); + out_uint16_le(s, x); /* left */ + out_uint16_le(s, y + i); /* top */ + out_uint16_le(s, (x + cx) - 1); /* right */ + out_uint16_le(s, (y + i + lines_sending) - 1); /* bottom */ + out_uint16_le(s, width + e); /* width */ + out_uint16_le(s, lines_sending); /* height */ + out_uint16_le(s, bpp); /* bpp */ + + if (session->client_info->op1) + { + out_uint16_le(s, 0x401); /* compress */ + out_uint16_le(s, bufsize); /* compressed size */ + j = (width + e) * Bpp; + j = j * lines_sending; + } + else + { + out_uint16_le(s, 0x1); /* compress */ + out_uint16_le(s, bufsize + 8); + out_uint8s(s, 2); /* pad */ + out_uint16_le(s, bufsize); /* compressed size */ + j = (width + e) * Bpp; + out_uint16_le(s, j); /* line size */ + j = j * lines_sending; + out_uint16_le(s, j); /* final size */ + } + + if (j > 32768) + { + g_writeln("error, decompressed size too big, its %d", j); + } + + if (bufsize > 8192) + { + g_writeln("error, compressed size too big, its %d", bufsize); + } + + s->p = s->end; + } + while (total_bufsize < 4096 && i > 0); + + p_num_updates[0] = num_updates; + p_num_updates[1] = num_updates >> 8; + xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, + RDP_DATA_PDU_UPDATE); + + if (total_bufsize > 8192) + { + g_writeln("error, total compressed size too big, its %d", + total_bufsize); + } } - s->p = s->end; - } while (total_bufsize < 4096 && i > 0); - p_num_updates[0] = num_updates; - p_num_updates[1] = num_updates >> 8; - xrdp_rdp_send_data((struct xrdp_rdp*)session->rdp, s, - RDP_DATA_PDU_UPDATE); - if (total_bufsize > 8192) - { - g_writeln("error, total compressed size too big, its %d", - total_bufsize); - } + + free_stream(temp_s); } - free_stream(temp_s); - } - else - { - total_lines = height; - i = 0; - p = data; - if (line_size > 0 && total_lines > 0) + else { - while (i < total_lines) - { - lines_sending = 4096 / (line_size + e * Bpp); - if (i + lines_sending > total_lines) - { - lines_sending = total_lines - i; - } - p = p + line_size * lines_sending; - xrdp_rdp_init_data((struct xrdp_rdp*)session->rdp, s); - out_uint16_le(s, RDP_UPDATE_BITMAP); - out_uint16_le(s, 1); /* num updates */ - out_uint16_le(s, x); - out_uint16_le(s, y + i); - out_uint16_le(s, (x + cx) - 1); - out_uint16_le(s, (y + i + lines_sending) - 1); - out_uint16_le(s, width + e); - out_uint16_le(s, lines_sending); - out_uint16_le(s, bpp); /* bpp */ - out_uint16_le(s, 0); /* compress */ - out_uint16_le(s, (line_size + e * Bpp) * lines_sending); /* bufsize */ - q = p; - for (j = 0; j < lines_sending; j++) + total_lines = height; + i = 0; + p = data; + + if (line_size > 0 && total_lines > 0) { - q = q - line_size; - out_uint8a(s, q, line_size); /* B_ENDIAN doesn't work here, todo */ - out_uint8s(s, e * Bpp); + while (i < total_lines) + { + lines_sending = 4096 / (line_size + e * Bpp); + + if (i + lines_sending > total_lines) + { + lines_sending = total_lines - i; + } + + p = p + line_size * lines_sending; + xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s); + out_uint16_le(s, RDP_UPDATE_BITMAP); + out_uint16_le(s, 1); /* num updates */ + out_uint16_le(s, x); + out_uint16_le(s, y + i); + out_uint16_le(s, (x + cx) - 1); + out_uint16_le(s, (y + i + lines_sending) - 1); + out_uint16_le(s, width + e); + out_uint16_le(s, lines_sending); + out_uint16_le(s, bpp); /* bpp */ + out_uint16_le(s, 0); /* compress */ + out_uint16_le(s, (line_size + e * Bpp) * lines_sending); /* bufsize */ + q = p; + + for (j = 0; j < lines_sending; j++) + { + q = q - line_size; + out_uint8a(s, q, line_size); /* B_ENDIAN doesn't work here, todo */ + out_uint8s(s, e * Bpp); + } + + s_mark_end(s); + xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, + RDP_DATA_PDU_UPDATE); + i = i + lines_sending; + } } - s_mark_end(s); - xrdp_rdp_send_data((struct xrdp_rdp*)session->rdp, s, - RDP_DATA_PDU_UPDATE); - i = i + lines_sending; - } } - } - free_stream(s); - return 0; + + free_stream(s); + return 0; } /*****************************************************************************/ int EXPORT_CC -libxrdp_send_pointer(struct xrdp_session* session, int cache_idx, - char* data, char* mask, int x, int y) -{ - struct stream* s; - char* p; - int i; - int j; - - DEBUG(("libxrdp_send_pointer sending cursor")); - make_stream(s); - init_stream(s, 8192); - xrdp_rdp_init_data((struct xrdp_rdp*)session->rdp, s); - out_uint16_le(s, RDP_POINTER_COLOR); - out_uint16_le(s, 0); /* pad */ - out_uint16_le(s, cache_idx); /* cache_idx */ - out_uint16_le(s, x); - out_uint16_le(s, y); - out_uint16_le(s, 32); - out_uint16_le(s, 32); - out_uint16_le(s, 128); - out_uint16_le(s, 3072); - p = data; - for (i = 0; i < 32; i++) - { - for (j = 0; j < 32; j++) +libxrdp_send_pointer(struct xrdp_session *session, int cache_idx, + char *data, char *mask, int x, int y) +{ + struct stream *s; + char *p; + int i; + int j; + + DEBUG(("libxrdp_send_pointer sending cursor")); + make_stream(s); + init_stream(s, 8192); + xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s); + out_uint16_le(s, RDP_POINTER_COLOR); + out_uint16_le(s, 0); /* pad */ + out_uint16_le(s, cache_idx); /* cache_idx */ + out_uint16_le(s, x); + out_uint16_le(s, y); + out_uint16_le(s, 32); + out_uint16_le(s, 32); + out_uint16_le(s, 128); + out_uint16_le(s, 3072); + p = data; + + for (i = 0; i < 32; i++) { - out_uint8(s, *p); - p++; - out_uint8(s, *p); - p++; - out_uint8(s, *p); - p++; + for (j = 0; j < 32; j++) + { + out_uint8(s, *p); + p++; + out_uint8(s, *p); + p++; + out_uint8(s, *p); + p++; + } } - } - out_uint8a(s, mask, 128); /* mask */ - s_mark_end(s); - xrdp_rdp_send_data((struct xrdp_rdp*)session->rdp, s, RDP_DATA_PDU_POINTER); - free_stream(s); - return 0; + + out_uint8a(s, mask, 128); /* mask */ + s_mark_end(s); + xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, RDP_DATA_PDU_POINTER); + free_stream(s); + return 0; } /*****************************************************************************/ int EXPORT_CC -libxrdp_set_pointer(struct xrdp_session* session, int cache_idx) +libxrdp_set_pointer(struct xrdp_session *session, int cache_idx) { - struct stream* s; + struct stream *s; - DEBUG(("libxrdp_set_pointer sending cursor index")); - make_stream(s); - init_stream(s, 8192); - xrdp_rdp_init_data((struct xrdp_rdp*)session->rdp, s); - out_uint16_le(s, RDP_POINTER_CACHED); - out_uint16_le(s, 0); /* pad */ - out_uint16_le(s, cache_idx); /* cache_idx */ - s_mark_end(s); - xrdp_rdp_send_data((struct xrdp_rdp*)session->rdp, s, RDP_DATA_PDU_POINTER); - free_stream(s); - return 0; + DEBUG(("libxrdp_set_pointer sending cursor index")); + make_stream(s); + init_stream(s, 8192); + xrdp_rdp_init_data((struct xrdp_rdp *)session->rdp, s); + out_uint16_le(s, RDP_POINTER_CACHED); + out_uint16_le(s, 0); /* pad */ + out_uint16_le(s, cache_idx); /* cache_idx */ + s_mark_end(s); + xrdp_rdp_send_data((struct xrdp_rdp *)session->rdp, s, RDP_DATA_PDU_POINTER); + free_stream(s); + return 0; } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_init(struct xrdp_session* session) +libxrdp_orders_init(struct xrdp_session *session) { - return xrdp_orders_init((struct xrdp_orders*)session->orders); + return xrdp_orders_init((struct xrdp_orders *)session->orders); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_send(struct xrdp_session* session) +libxrdp_orders_send(struct xrdp_session *session) { - return xrdp_orders_send((struct xrdp_orders*)session->orders); + return xrdp_orders_send((struct xrdp_orders *)session->orders); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_force_send(struct xrdp_session* session) +libxrdp_orders_force_send(struct xrdp_session *session) { - return xrdp_orders_force_send((struct xrdp_orders*)session->orders); + return xrdp_orders_force_send((struct xrdp_orders *)session->orders); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_rect(struct xrdp_session* session, int x, int y, - int cx, int cy, int color, struct xrdp_rect* rect) +libxrdp_orders_rect(struct xrdp_session *session, int x, int y, + int cx, int cy, int color, struct xrdp_rect *rect) { - return xrdp_orders_rect((struct xrdp_orders*)session->orders, - x, y, cx, cy, color, rect); + return xrdp_orders_rect((struct xrdp_orders *)session->orders, + x, y, cx, cy, color, rect); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_screen_blt(struct xrdp_session* session, int x, int y, +libxrdp_orders_screen_blt(struct xrdp_session *session, int x, int y, int cx, int cy, int srcx, int srcy, - int rop, struct xrdp_rect* rect) + int rop, struct xrdp_rect *rect) { - return xrdp_orders_screen_blt((struct xrdp_orders*)session->orders, - x, y, cx, cy, srcx, srcy, rop, rect); + return xrdp_orders_screen_blt((struct xrdp_orders *)session->orders, + x, y, cx, cy, srcx, srcy, rop, rect); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_pat_blt(struct xrdp_session* session, int x, int y, +libxrdp_orders_pat_blt(struct xrdp_session *session, int x, int y, int cx, int cy, int rop, int bg_color, - int fg_color, struct xrdp_brush* brush, - struct xrdp_rect* rect) + int fg_color, struct xrdp_brush *brush, + struct xrdp_rect *rect) { - return xrdp_orders_pat_blt((struct xrdp_orders*)session->orders, - x, y, cx, cy, rop, bg_color, fg_color, - brush, rect); + return xrdp_orders_pat_blt((struct xrdp_orders *)session->orders, + x, y, cx, cy, rop, bg_color, fg_color, + brush, rect); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_dest_blt(struct xrdp_session* session, int x, int y, +libxrdp_orders_dest_blt(struct xrdp_session *session, int x, int y, int cx, int cy, int rop, - struct xrdp_rect* rect) + struct xrdp_rect *rect) { - return xrdp_orders_dest_blt((struct xrdp_orders*)session->orders, - x, y, cx, cy, rop, rect); + return xrdp_orders_dest_blt((struct xrdp_orders *)session->orders, + x, y, cx, cy, rop, rect); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_line(struct xrdp_session* session, int mix_mode, +libxrdp_orders_line(struct xrdp_session *session, int mix_mode, int startx, int starty, int endx, int endy, int rop, int bg_color, - struct xrdp_pen* pen, - struct xrdp_rect* rect) + struct xrdp_pen *pen, + struct xrdp_rect *rect) { - return xrdp_orders_line((struct xrdp_orders*)session->orders, - mix_mode, startx, starty, endx, endy, - rop, bg_color, pen, rect); + return xrdp_orders_line((struct xrdp_orders *)session->orders, + mix_mode, startx, starty, endx, endy, + rop, bg_color, pen, rect); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_mem_blt(struct xrdp_session* session, int cache_id, +libxrdp_orders_mem_blt(struct xrdp_session *session, int cache_id, int color_table, int x, int y, int cx, int cy, int rop, int srcx, int srcy, - int cache_idx, struct xrdp_rect* rect) + int cache_idx, struct xrdp_rect *rect) { - return xrdp_orders_mem_blt((struct xrdp_orders*)session->orders, - cache_id, color_table, x, y, cx, cy, rop, - srcx, srcy, cache_idx, rect); + return xrdp_orders_mem_blt((struct xrdp_orders *)session->orders, + cache_id, color_table, x, y, cx, cy, rop, + srcx, srcy, cache_idx, rect); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_text(struct xrdp_session* session, +libxrdp_orders_text(struct xrdp_session *session, int font, int flags, int mixmode, int fg_color, int bg_color, int clip_left, int clip_top, int clip_right, int clip_bottom, int box_left, int box_top, int box_right, int box_bottom, - int x, int y, char* data, int data_len, - struct xrdp_rect* rect) + int x, int y, char *data, int data_len, + struct xrdp_rect *rect) { - return xrdp_orders_text((struct xrdp_orders*)session->orders, - font, flags, mixmode, fg_color, bg_color, - clip_left, clip_top, clip_right, clip_bottom, - box_left, box_top, box_right, box_bottom, - x, y, data, data_len, rect); + return xrdp_orders_text((struct xrdp_orders *)session->orders, + font, flags, mixmode, fg_color, bg_color, + clip_left, clip_top, clip_right, clip_bottom, + box_left, box_top, box_right, box_bottom, + x, y, data, data_len, rect); } /******************************************************************************/ int EXPORT_CC -libxrdp_orders_send_palette(struct xrdp_session* session, int* palette, +libxrdp_orders_send_palette(struct xrdp_session *session, int *palette, int cache_id) { - return xrdp_orders_send_palette((struct xrdp_orders*)session->orders, - palette, cache_id); + return xrdp_orders_send_palette((struct xrdp_orders *)session->orders, + palette, cache_id); } /*****************************************************************************/ int EXPORT_CC -libxrdp_orders_send_raw_bitmap(struct xrdp_session* session, - int width, int height, int bpp, char* data, +libxrdp_orders_send_raw_bitmap(struct xrdp_session *session, + int width, int height, int bpp, char *data, int cache_id, int cache_idx) { - return xrdp_orders_send_raw_bitmap((struct xrdp_orders*)session->orders, - width, height, bpp, data, - cache_id, cache_idx); + return xrdp_orders_send_raw_bitmap((struct xrdp_orders *)session->orders, + width, height, bpp, data, + cache_id, cache_idx); } /*****************************************************************************/ int EXPORT_CC -libxrdp_orders_send_bitmap(struct xrdp_session* session, - int width, int height, int bpp, char* data, +libxrdp_orders_send_bitmap(struct xrdp_session *session, + int width, int height, int bpp, char *data, int cache_id, int cache_idx) { - return xrdp_orders_send_bitmap((struct xrdp_orders*)session->orders, - width, height, bpp, data, - cache_id, cache_idx); + return xrdp_orders_send_bitmap((struct xrdp_orders *)session->orders, + width, height, bpp, data, + cache_id, cache_idx); } /*****************************************************************************/ int EXPORT_CC -libxrdp_orders_send_font(struct xrdp_session* session, - struct xrdp_font_char* font_char, +libxrdp_orders_send_font(struct xrdp_session *session, + struct xrdp_font_char *font_char, int font_index, int char_index) { - return xrdp_orders_send_font((struct xrdp_orders*)session->orders, - font_char, font_index, char_index); + return xrdp_orders_send_font((struct xrdp_orders *)session->orders, + font_char, font_index, char_index); } /*****************************************************************************/ int EXPORT_CC -libxrdp_reset(struct xrdp_session* session, +libxrdp_reset(struct xrdp_session *session, int width, int height, int bpp) { - if (session->client_info != 0) - { - /* older client can't resize */ - if (session->client_info->build <= 419) + if (session->client_info != 0) + { + /* older client can't resize */ + if (session->client_info->build <= 419) + { + return 0; + } + + /* if same, don't need to do anything */ + if (session->client_info->width == width && + session->client_info->height == height && + session->client_info->bpp == bpp) + { + return 0; + } + + session->client_info->width = width; + session->client_info->height = height; + session->client_info->bpp = bpp; + } + else + { + return 1; + } + + /* this will send any lingering orders */ + if (xrdp_orders_reset((struct xrdp_orders *)session->orders) != 0) { - return 0; + return 1; } - /* if same, don't need to do anything */ - if (session->client_info->width == width && - session->client_info->height == height && - session->client_info->bpp == bpp) + + /* shut down the rdp client */ + if (xrdp_rdp_send_deactive((struct xrdp_rdp *)session->rdp) != 0) + { + return 1; + } + + /* this should do the resizing */ + if (xrdp_rdp_send_demand_active((struct xrdp_rdp *)session->rdp) != 0) + { + return 1; + } + + /* process till up and running */ + session->up_and_running = 0; + + if (libxrdp_process_data(session) != 0) { - return 0; + g_writeln("non handled error from libxrdp_process_data"); } - session->client_info->width = width; - session->client_info->height = height; - session->client_info->bpp = bpp; - } - else - { - return 1; - } - /* this will send any lingering orders */ - if (xrdp_orders_reset((struct xrdp_orders*)session->orders) != 0) - { - return 1; - } - /* shut down the rdp client */ - if (xrdp_rdp_send_deactive((struct xrdp_rdp*)session->rdp) != 0) - { - return 1; - } - /* this should do the resizing */ - if (xrdp_rdp_send_demand_active((struct xrdp_rdp*)session->rdp) != 0) - { - return 1; - } - /* process till up and running */ - session->up_and_running = 0; - if (libxrdp_process_data(session) != 0) - { - g_writeln("non handled error from libxrdp_process_data"); - } - return 0; + + return 0; } /*****************************************************************************/ int EXPORT_CC -libxrdp_orders_send_raw_bitmap2(struct xrdp_session* session, - int width, int height, int bpp, char* data, +libxrdp_orders_send_raw_bitmap2(struct xrdp_session *session, + int width, int height, int bpp, char *data, int cache_id, int cache_idx) { - return xrdp_orders_send_raw_bitmap2((struct xrdp_orders*)session->orders, - width, height, bpp, data, - cache_id, cache_idx); + return xrdp_orders_send_raw_bitmap2((struct xrdp_orders *)session->orders, + width, height, bpp, data, + cache_id, cache_idx); } /*****************************************************************************/ int EXPORT_CC -libxrdp_orders_send_bitmap2(struct xrdp_session* session, - int width, int height, int bpp, char* data, +libxrdp_orders_send_bitmap2(struct xrdp_session *session, + int width, int height, int bpp, char *data, int cache_id, int cache_idx, int hints) { - return xrdp_orders_send_bitmap2((struct xrdp_orders*)session->orders, - width, height, bpp, data, - cache_id, cache_idx, hints); + return xrdp_orders_send_bitmap2((struct xrdp_orders *)session->orders, + width, height, bpp, data, + cache_id, cache_idx, hints); } /*****************************************************************************/ int EXPORT_CC -libxrdp_orders_send_bitmap3(struct xrdp_session* session, - int width, int height, int bpp, char* data, +libxrdp_orders_send_bitmap3(struct xrdp_session *session, + int width, int height, int bpp, char *data, int cache_id, int cache_idx, int hints) { - return xrdp_orders_send_bitmap3((struct xrdp_orders*)session->orders, - width, height, bpp, data, - cache_id, cache_idx, hints); + return xrdp_orders_send_bitmap3((struct xrdp_orders *)session->orders, + width, height, bpp, data, + cache_id, cache_idx, hints); } /*****************************************************************************/ @@ -675,226 +723,243 @@ libxrdp_orders_send_bitmap3(struct xrdp_session* session, based. either channel_name or channel_flags can be passed in nil if they are not needed */ int EXPORT_CC -libxrdp_query_channel(struct xrdp_session* session, int index, - char* channel_name, int* channel_flags) -{ - int count = 0; - struct xrdp_rdp* rdp = (struct xrdp_rdp *)NULL; - struct xrdp_mcs* mcs = (struct xrdp_mcs *)NULL; - struct mcs_channel_item* channel_item = (struct mcs_channel_item *)NULL; - - rdp = (struct xrdp_rdp*)session->rdp; - mcs = rdp->sec_layer->mcs_layer; - if (mcs->channel_list == NULL) - { - g_writeln("libxrdp_query_channel - No channel initialized"); - return 1 ; - } - count = mcs->channel_list->count; - if (index < 0 || index >= count) - { - return 1; - } - channel_item = (struct mcs_channel_item*) - list_get_item(mcs->channel_list, index); - if (channel_item == 0) - { - /* this should not happen */ - g_writeln("libxrdp_query_channel - channel item is 0"); - return 1; - } - if (channel_name != 0) - { - g_strncpy(channel_name, channel_item->name, 8); - } - if (channel_flags != 0) - { - *channel_flags = channel_item->flags; - } - return 0; +libxrdp_query_channel(struct xrdp_session *session, int index, + char *channel_name, int *channel_flags) +{ + int count = 0; + struct xrdp_rdp *rdp = (struct xrdp_rdp *)NULL; + struct xrdp_mcs *mcs = (struct xrdp_mcs *)NULL; + struct mcs_channel_item *channel_item = (struct mcs_channel_item *)NULL; + + rdp = (struct xrdp_rdp *)session->rdp; + mcs = rdp->sec_layer->mcs_layer; + + if (mcs->channel_list == NULL) + { + g_writeln("libxrdp_query_channel - No channel initialized"); + return 1 ; + } + + count = mcs->channel_list->count; + + if (index < 0 || index >= count) + { + return 1; + } + + channel_item = (struct mcs_channel_item *) + list_get_item(mcs->channel_list, index); + + if (channel_item == 0) + { + /* this should not happen */ + g_writeln("libxrdp_query_channel - channel item is 0"); + return 1; + } + + if (channel_name != 0) + { + g_strncpy(channel_name, channel_item->name, 8); + } + + if (channel_flags != 0) + { + *channel_flags = channel_item->flags; + } + + return 0; } /*****************************************************************************/ /* returns a zero based index of the channel, -1 if error or it dosen't exist */ int EXPORT_CC -libxrdp_get_channel_id(struct xrdp_session* session, char* name) -{ - int index = 0; - int count = 0; - struct xrdp_rdp* rdp = NULL; - struct xrdp_mcs* mcs = NULL; - struct mcs_channel_item* channel_item = NULL; - - rdp = (struct xrdp_rdp*)session->rdp; - mcs = rdp->sec_layer->mcs_layer; - if (mcs->channel_list == NULL) - { - g_writeln("libxrdp_get_channel_id No channel initialized"); - return -1 ; - } - count = mcs->channel_list->count; - for (index = 0; index < count; index++) - { - channel_item = (struct mcs_channel_item*) - list_get_item(mcs->channel_list, index); - if (channel_item != 0) +libxrdp_get_channel_id(struct xrdp_session *session, char *name) +{ + int index = 0; + int count = 0; + struct xrdp_rdp *rdp = NULL; + struct xrdp_mcs *mcs = NULL; + struct mcs_channel_item *channel_item = NULL; + + rdp = (struct xrdp_rdp *)session->rdp; + mcs = rdp->sec_layer->mcs_layer; + + if (mcs->channel_list == NULL) + { + g_writeln("libxrdp_get_channel_id No channel initialized"); + return -1 ; + } + + count = mcs->channel_list->count; + + for (index = 0; index < count; index++) { - if (g_strcasecmp(name, channel_item->name) == 0) - { - return index; - } + channel_item = (struct mcs_channel_item *) + list_get_item(mcs->channel_list, index); + + if (channel_item != 0) + { + if (g_strcasecmp(name, channel_item->name) == 0) + { + return index; + } + } } - } - return -1; + + return -1; } /*****************************************************************************/ int EXPORT_CC -libxrdp_send_to_channel(struct xrdp_session* session, int channel_id, - char* data, int data_len, +libxrdp_send_to_channel(struct xrdp_session *session, int channel_id, + char *data, int data_len, int total_data_len, int flags) { - struct xrdp_rdp* rdp = NULL; - struct xrdp_sec* sec = NULL; - struct xrdp_channel* chan = NULL; - struct stream* s = NULL; - - rdp = (struct xrdp_rdp*)session->rdp; - sec = rdp->sec_layer; - chan = sec->chan_layer; - make_stream(s); - init_stream(s, data_len + 1024); /* this should be big enough */ - if (xrdp_channel_init(chan, s) != 0) - { - free_stream(s); - return 1; - } - /* here we make a copy of the data */ - out_uint8a(s, data, data_len); - s_mark_end(s); - if (xrdp_channel_send(chan, s, channel_id, total_data_len, flags) != 0) - { - g_writeln("Debug - data NOT sent to channel"); + struct xrdp_rdp *rdp = NULL; + struct xrdp_sec *sec = NULL; + struct xrdp_channel *chan = NULL; + struct stream *s = NULL; + + rdp = (struct xrdp_rdp *)session->rdp; + sec = rdp->sec_layer; + chan = sec->chan_layer; + make_stream(s); + init_stream(s, data_len + 1024); /* this should be big enough */ + + if (xrdp_channel_init(chan, s) != 0) + { + free_stream(s); + return 1; + } + + /* here we make a copy of the data */ + out_uint8a(s, data, data_len); + s_mark_end(s); + + if (xrdp_channel_send(chan, s, channel_id, total_data_len, flags) != 0) + { + g_writeln("Debug - data NOT sent to channel"); + free_stream(s); + return 1; + } + free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ int EXPORT_CC -libxrdp_orders_send_brush(struct xrdp_session* session, +libxrdp_orders_send_brush(struct xrdp_session *session, int width, int height, int bpp, int type, - int size, char* data, int cache_id) + int size, char *data, int cache_id) { - return xrdp_orders_send_brush((struct xrdp_orders*)session->orders, - width, height, bpp, type, size, data, - cache_id); + return xrdp_orders_send_brush((struct xrdp_orders *)session->orders, + width, height, bpp, type, size, data, + cache_id); } /*****************************************************************************/ int EXPORT_CC -libxrdp_orders_send_create_os_surface(struct xrdp_session* session, int id, +libxrdp_orders_send_create_os_surface(struct xrdp_session *session, int id, int width, int height, - struct list* del_list) + struct list *del_list) { - return xrdp_orders_send_create_os_surface - ((struct xrdp_orders*)(session->orders), id, - width, height, del_list); + return xrdp_orders_send_create_os_surface + ((struct xrdp_orders *)(session->orders), id, + width, height, del_list); } /*****************************************************************************/ int EXPORT_CC -libxrdp_orders_send_switch_os_surface(struct xrdp_session* session, int id) +libxrdp_orders_send_switch_os_surface(struct xrdp_session *session, int id) { - return xrdp_orders_send_switch_os_surface - ((struct xrdp_orders*)(session->orders), id); + return xrdp_orders_send_switch_os_surface + ((struct xrdp_orders *)(session->orders), id); } /*****************************************************************************/ int EXPORT_CC -libxrdp_window_new_update(struct xrdp_session* session, int window_id, - struct rail_window_state_order* window_state, +libxrdp_window_new_update(struct xrdp_session *session, int window_id, + struct rail_window_state_order *window_state, int flags) { - struct xrdp_orders* orders; + struct xrdp_orders *orders; - orders = (struct xrdp_orders*)(session->orders); - return xrdp_orders_send_window_new_update(orders, window_id, - window_state, flags); + orders = (struct xrdp_orders *)(session->orders); + return xrdp_orders_send_window_new_update(orders, window_id, + window_state, flags); } /*****************************************************************************/ int EXPORT_CC -libxrdp_window_delete(struct xrdp_session* session, int window_id) +libxrdp_window_delete(struct xrdp_session *session, int window_id) { - struct xrdp_orders* orders; + struct xrdp_orders *orders; - orders = (struct xrdp_orders*)(session->orders); - return xrdp_orders_send_window_delete(orders, window_id); + orders = (struct xrdp_orders *)(session->orders); + return xrdp_orders_send_window_delete(orders, window_id); } /*****************************************************************************/ int EXPORT_CC -libxrdp_window_icon(struct xrdp_session* session, int window_id, +libxrdp_window_icon(struct xrdp_session *session, int window_id, int cache_entry, int cache_id, - struct rail_icon_info* icon_info, int flags) + struct rail_icon_info *icon_info, int flags) { - struct xrdp_orders* orders; + struct xrdp_orders *orders; - orders = (struct xrdp_orders*)(session->orders); - return xrdp_orders_send_window_icon(orders, window_id, cache_entry, - cache_id, icon_info, flags); + orders = (struct xrdp_orders *)(session->orders); + return xrdp_orders_send_window_icon(orders, window_id, cache_entry, + cache_id, icon_info, flags); } /*****************************************************************************/ int EXPORT_CC -libxrdp_window_cached_icon(struct xrdp_session* session, int window_id, +libxrdp_window_cached_icon(struct xrdp_session *session, int window_id, int cache_entry, int cache_id, int flags) { - struct xrdp_orders* orders; + struct xrdp_orders *orders; - orders = (struct xrdp_orders*)(session->orders); - return xrdp_orders_send_window_cached_icon(orders, window_id, cache_entry, - cache_id, flags); + orders = (struct xrdp_orders *)(session->orders); + return xrdp_orders_send_window_cached_icon(orders, window_id, cache_entry, + cache_id, flags); } /*****************************************************************************/ int EXPORT_CC -libxrdp_notify_new_update(struct xrdp_session* session, +libxrdp_notify_new_update(struct xrdp_session *session, int window_id, int notify_id, - struct rail_notify_state_order* notify_state, + struct rail_notify_state_order *notify_state, int flags) { - struct xrdp_orders* orders; + struct xrdp_orders *orders; - orders = (struct xrdp_orders*)(session->orders); - return xrdp_orders_send_notify_new_update(orders, window_id, notify_id, - notify_state, flags); + orders = (struct xrdp_orders *)(session->orders); + return xrdp_orders_send_notify_new_update(orders, window_id, notify_id, + notify_state, flags); } /*****************************************************************************/ int DEFAULT_CC -libxrdp_notify_delete(struct xrdp_session* session, +libxrdp_notify_delete(struct xrdp_session *session, int window_id, int notify_id) { - struct xrdp_orders* orders; + struct xrdp_orders *orders; - orders = (struct xrdp_orders*)(session->orders); - return xrdp_orders_send_notify_delete(orders, window_id, notify_id); + orders = (struct xrdp_orders *)(session->orders); + return xrdp_orders_send_notify_delete(orders, window_id, notify_id); } /*****************************************************************************/ int DEFAULT_CC -libxrdp_monitored_desktop(struct xrdp_session* session, - struct rail_monitored_desktop_order* mdo, +libxrdp_monitored_desktop(struct xrdp_session *session, + struct rail_monitored_desktop_order *mdo, int flags) { - struct xrdp_orders* orders; + struct xrdp_orders *orders; - orders = (struct xrdp_orders*)(session->orders); - return xrdp_orders_send_monitored_desktop(orders, mdo, flags); + orders = (struct xrdp_orders *)(session->orders); + return xrdp_orders_send_monitored_desktop(orders, mdo, flags); } diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index b066db95..34924715 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -1,24 +1,22 @@ -/* - 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. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - libxrdp header - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2010 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * libxrdp header + */ #if !defined(LIBXRDP_H) #define LIBXRDP_H diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h index 4f3504e6..ebfc348c 100644 --- a/libxrdp/libxrdpinc.h +++ b/libxrdp/libxrdpinc.h @@ -1,24 +1,22 @@ -/* - 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. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - header file for use with libxrdp.so / xrdp.dll - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2010 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * header file for use with libxrdp.so / xrdp.dll + */ #ifndef LIBXRDPINC_H #define LIBXRDPINC_H diff --git a/libxrdp/xrdp_bitmap_compress.c b/libxrdp/xrdp_bitmap_compress.c index fcaab1f7..87538450 100644 --- a/libxrdp/xrdp_bitmap_compress.c +++ b/libxrdp/xrdp_bitmap_compress.c @@ -1,1474 +1,1570 @@ -/* - 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. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - bitmap compressor - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * bitmap compressor + */ #include "libxrdp.h" /*****************************************************************************/ #define IN_PIXEL8(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \ -{ \ - if (in_ptr == 0) \ - { \ - in_pixel = 0; \ - } \ - else if (in_x < in_w) \ - { \ - in_pixel = GETPIXEL8(in_ptr, in_x, in_y, in_w); \ - } \ - else \ - { \ - in_pixel = in_last_pixel; \ - } \ -} + { \ + if (in_ptr == 0) \ + { \ + in_pixel = 0; \ + } \ + else if (in_x < in_w) \ + { \ + in_pixel = GETPIXEL8(in_ptr, in_x, in_y, in_w); \ + } \ + else \ + { \ + in_pixel = in_last_pixel; \ + } \ + } /*****************************************************************************/ #define IN_PIXEL16(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \ -{ \ - if (in_ptr == 0) \ - { \ - in_pixel = 0; \ - } \ - else if (in_x < in_w) \ - { \ - in_pixel = GETPIXEL16(in_ptr, in_x, in_y, in_w); \ - } \ - else \ - { \ - in_pixel = in_last_pixel; \ - } \ -} + { \ + if (in_ptr == 0) \ + { \ + in_pixel = 0; \ + } \ + else if (in_x < in_w) \ + { \ + in_pixel = GETPIXEL16(in_ptr, in_x, in_y, in_w); \ + } \ + else \ + { \ + in_pixel = in_last_pixel; \ + } \ + } /*****************************************************************************/ #define IN_PIXEL32(in_ptr, in_x, in_y, in_w, in_last_pixel, in_pixel); \ -{ \ - if (in_ptr == 0) \ - { \ - in_pixel = 0; \ - } \ - else if (in_x < in_w) \ - { \ - in_pixel = GETPIXEL32(in_ptr, in_x, in_y, in_w); \ - } \ - else \ - { \ - in_pixel = in_last_pixel; \ - } \ -} + { \ + if (in_ptr == 0) \ + { \ + in_pixel = 0; \ + } \ + else if (in_x < in_w) \ + { \ + in_pixel = GETPIXEL32(in_ptr, in_x, in_y, in_w); \ + } \ + else \ + { \ + in_pixel = in_last_pixel; \ + } \ + } /*****************************************************************************/ /* color */ #define OUT_COLOR_COUNT1(in_count, in_s, in_data) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ - { \ - temp = (0x3 << 5) | in_count; \ - out_uint8(in_s, temp); \ - out_uint8(in_s, in_data); \ - } \ - else if (in_count < 256 + 32) \ { \ - out_uint8(in_s, 0x60); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - out_uint8(in_s, in_data); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf3); \ - out_uint16_le(in_s, in_count); \ - out_uint8(in_s, in_data); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x3 << 5) | in_count; \ + out_uint8(in_s, temp); \ + out_uint8(in_s, in_data); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x60); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + out_uint8(in_s, in_data); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf3); \ + out_uint16_le(in_s, in_count); \ + out_uint8(in_s, in_data); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* color */ #define OUT_COLOR_COUNT2(in_count, in_s, in_data) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ - { \ - temp = (0x3 << 5) | in_count; \ - out_uint8(in_s, temp); \ - out_uint16_le(in_s, in_data); \ - } \ - else if (in_count < 256 + 32) \ { \ - out_uint8(in_s, 0x60); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - out_uint16_le(in_s, in_data); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf3); \ - out_uint16_le(in_s, in_count); \ - out_uint16_le(in_s, in_data); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x3 << 5) | in_count; \ + out_uint8(in_s, temp); \ + out_uint16_le(in_s, in_data); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x60); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + out_uint16_le(in_s, in_data); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf3); \ + out_uint16_le(in_s, in_count); \ + out_uint16_le(in_s, in_data); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* color */ #define OUT_COLOR_COUNT3(in_count, in_s, in_data) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ - { \ - temp = (0x3 << 5) | in_count; \ - out_uint8(in_s, temp); \ - out_uint8(in_s, in_data & 0xff); \ - out_uint8(in_s, (in_data >> 8) & 0xff); \ - out_uint8(in_s, (in_data >> 16) & 0xff); \ - } \ - else if (in_count < 256 + 32) \ - { \ - out_uint8(in_s, 0x60); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - out_uint8(in_s, in_data & 0xff); \ - out_uint8(in_s, (in_data >> 8) & 0xff); \ - out_uint8(in_s, (in_data >> 16) & 0xff); \ - } \ - else \ { \ - out_uint8(in_s, 0xf3); \ - out_uint16_le(in_s, in_count); \ - out_uint8(in_s, in_data & 0xff); \ - out_uint8(in_s, (in_data >> 8) & 0xff); \ - out_uint8(in_s, (in_data >> 16) & 0xff); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x3 << 5) | in_count; \ + out_uint8(in_s, temp); \ + out_uint8(in_s, in_data & 0xff); \ + out_uint8(in_s, (in_data >> 8) & 0xff); \ + out_uint8(in_s, (in_data >> 16) & 0xff); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x60); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + out_uint8(in_s, in_data & 0xff); \ + out_uint8(in_s, (in_data >> 8) & 0xff); \ + out_uint8(in_s, (in_data >> 16) & 0xff); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf3); \ + out_uint16_le(in_s, in_count); \ + out_uint8(in_s, in_data & 0xff); \ + out_uint8(in_s, (in_data >> 8) & 0xff); \ + out_uint8(in_s, (in_data >> 16) & 0xff); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* copy */ #define OUT_COPY_COUNT1(in_count, in_s, in_data) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ - { \ - temp = (0x4 << 5) | in_count; \ - out_uint8(in_s, temp); \ - out_uint8a(in_s, in_data->data, in_count); \ - } \ - else if (in_count < 256 + 32) \ { \ - out_uint8(in_s, 0x80); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - out_uint8a(in_s, in_data->data, in_count); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf4); \ - out_uint16_le(in_s, in_count); \ - out_uint8a(in_s, in_data->data, in_count); \ - } \ - } \ - in_count = 0; \ - init_stream(in_data, 0); \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x4 << 5) | in_count; \ + out_uint8(in_s, temp); \ + out_uint8a(in_s, in_data->data, in_count); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x80); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + out_uint8a(in_s, in_data->data, in_count); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf4); \ + out_uint16_le(in_s, in_count); \ + out_uint8a(in_s, in_data->data, in_count); \ + } \ + } \ + in_count = 0; \ + init_stream(in_data, 0); \ + } /*****************************************************************************/ /* copy */ #define OUT_COPY_COUNT2(in_count, in_s, in_data) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ - { \ - temp = (0x4 << 5) | in_count; \ - out_uint8(in_s, temp); \ - temp = in_count * 2; \ - out_uint8a(in_s, in_data->data, temp); \ - } \ - else if (in_count < 256 + 32) \ - { \ - out_uint8(in_s, 0x80); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - temp = in_count * 2; \ - out_uint8a(in_s, in_data->data, temp); \ - } \ - else \ { \ - out_uint8(in_s, 0xf4); \ - out_uint16_le(in_s, in_count); \ - temp = in_count * 2; \ - out_uint8a(in_s, in_data->data, temp); \ - } \ - } \ - in_count = 0; \ - init_stream(in_data, 0); \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x4 << 5) | in_count; \ + out_uint8(in_s, temp); \ + temp = in_count * 2; \ + out_uint8a(in_s, in_data->data, temp); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x80); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + temp = in_count * 2; \ + out_uint8a(in_s, in_data->data, temp); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf4); \ + out_uint16_le(in_s, in_count); \ + temp = in_count * 2; \ + out_uint8a(in_s, in_data->data, temp); \ + } \ + } \ + in_count = 0; \ + init_stream(in_data, 0); \ + } /*****************************************************************************/ /* copy */ #define OUT_COPY_COUNT3(in_count, in_s, in_data) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ { \ - temp = (0x4 << 5) | in_count; \ - out_uint8(in_s, temp); \ - temp = in_count * 3; \ - out_uint8a(in_s, in_data->end, temp); \ - } \ - else if (in_count < 256 + 32) \ - { \ - out_uint8(in_s, 0x80); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - temp = in_count * 3; \ - out_uint8a(in_s, in_data->end, temp); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf4); \ - out_uint16_le(in_s, in_count); \ - temp = in_count * 3; \ - out_uint8a(in_s, in_data->end, temp); \ - } \ - } \ - in_count = 0; \ - init_stream(in_data, 0); \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x4 << 5) | in_count; \ + out_uint8(in_s, temp); \ + temp = in_count * 3; \ + out_uint8a(in_s, in_data->end, temp); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x80); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + temp = in_count * 3; \ + out_uint8a(in_s, in_data->end, temp); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf4); \ + out_uint16_le(in_s, in_count); \ + temp = in_count * 3; \ + out_uint8a(in_s, in_data->end, temp); \ + } \ + } \ + in_count = 0; \ + init_stream(in_data, 0); \ + } /*****************************************************************************/ /* bicolor */ #define OUT_BICOLOR_COUNT1(in_count, in_s, in_color1, in_color2) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count / 2 < 16) \ { \ - temp = (0xe << 4) | (in_count / 2); \ - out_uint8(in_s, temp); \ - out_uint8(in_s, in_color1); \ - out_uint8(in_s, in_color2); \ - } \ - else if (in_count / 2 < 256 + 16) \ - { \ - out_uint8(in_s, 0xe0); \ - temp = in_count / 2 - 16; \ - out_uint8(in_s, temp); \ - out_uint8(in_s, in_color1); \ - out_uint8(in_s, in_color2); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf8); \ - temp = in_count / 2; \ - out_uint16_le(in_s, temp); \ - out_uint8(in_s, in_color1); \ - out_uint8(in_s, in_color2); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count / 2 < 16) \ + { \ + temp = (0xe << 4) | (in_count / 2); \ + out_uint8(in_s, temp); \ + out_uint8(in_s, in_color1); \ + out_uint8(in_s, in_color2); \ + } \ + else if (in_count / 2 < 256 + 16) \ + { \ + out_uint8(in_s, 0xe0); \ + temp = in_count / 2 - 16; \ + out_uint8(in_s, temp); \ + out_uint8(in_s, in_color1); \ + out_uint8(in_s, in_color2); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf8); \ + temp = in_count / 2; \ + out_uint16_le(in_s, temp); \ + out_uint8(in_s, in_color1); \ + out_uint8(in_s, in_color2); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* bicolor */ #define OUT_BICOLOR_COUNT2(in_count, in_s, in_color1, in_color2) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count / 2 < 16) \ - { \ - temp = (0xe << 4) | (in_count / 2); \ - out_uint8(in_s, temp); \ - out_uint16_le(in_s, in_color1); \ - out_uint16_le(in_s, in_color2); \ - } \ - else if (in_count / 2 < 256 + 16) \ { \ - out_uint8(in_s, 0xe0); \ - temp = in_count / 2 - 16; \ - out_uint8(in_s, temp); \ - out_uint16_le(in_s, in_color1); \ - out_uint16_le(in_s, in_color2); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf8); \ - temp = in_count / 2; \ - out_uint16_le(in_s, temp); \ - out_uint16_le(in_s, in_color1); \ - out_uint16_le(in_s, in_color2); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count / 2 < 16) \ + { \ + temp = (0xe << 4) | (in_count / 2); \ + out_uint8(in_s, temp); \ + out_uint16_le(in_s, in_color1); \ + out_uint16_le(in_s, in_color2); \ + } \ + else if (in_count / 2 < 256 + 16) \ + { \ + out_uint8(in_s, 0xe0); \ + temp = in_count / 2 - 16; \ + out_uint8(in_s, temp); \ + out_uint16_le(in_s, in_color1); \ + out_uint16_le(in_s, in_color2); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf8); \ + temp = in_count / 2; \ + out_uint16_le(in_s, temp); \ + out_uint16_le(in_s, in_color1); \ + out_uint16_le(in_s, in_color2); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* bicolor */ #define OUT_BICOLOR_COUNT3(in_count, in_s, in_color1, in_color2) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count / 2 < 16) \ - { \ - temp = (0xe << 4) | (in_count / 2); \ - out_uint8(in_s, temp); \ - out_uint8(in_s, in_color1 & 0xff); \ - out_uint8(in_s, (in_color1 >> 8) & 0xff); \ - out_uint8(in_s, (in_color1 >> 16) & 0xff); \ - out_uint8(in_s, in_color2 & 0xff); \ - out_uint8(in_s, (in_color2 >> 8) & 0xff); \ - out_uint8(in_s, (in_color2 >> 16) & 0xff); \ - } \ - else if (in_count / 2 < 256 + 16) \ - { \ - out_uint8(in_s, 0xe0); \ - temp = in_count / 2 - 16; \ - out_uint8(in_s, temp); \ - out_uint8(in_s, in_color1 & 0xff); \ - out_uint8(in_s, (in_color1 >> 8) & 0xff); \ - out_uint8(in_s, (in_color1 >> 16) & 0xff); \ - out_uint8(in_s, in_color2 & 0xff); \ - out_uint8(in_s, (in_color2 >> 8) & 0xff); \ - out_uint8(in_s, (in_color2 >> 16) & 0xff); \ - } \ - else \ { \ - out_uint8(in_s, 0xf8); \ - temp = in_count / 2; \ - out_uint16_le(in_s, temp); \ - out_uint8(in_s, in_color1 & 0xff); \ - out_uint8(in_s, (in_color1 >> 8) & 0xff); \ - out_uint8(in_s, (in_color1 >> 16) & 0xff); \ - out_uint8(in_s, in_color2 & 0xff); \ - out_uint8(in_s, (in_color2 >> 8) & 0xff); \ - out_uint8(in_s, (in_color2 >> 16) & 0xff); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count / 2 < 16) \ + { \ + temp = (0xe << 4) | (in_count / 2); \ + out_uint8(in_s, temp); \ + out_uint8(in_s, in_color1 & 0xff); \ + out_uint8(in_s, (in_color1 >> 8) & 0xff); \ + out_uint8(in_s, (in_color1 >> 16) & 0xff); \ + out_uint8(in_s, in_color2 & 0xff); \ + out_uint8(in_s, (in_color2 >> 8) & 0xff); \ + out_uint8(in_s, (in_color2 >> 16) & 0xff); \ + } \ + else if (in_count / 2 < 256 + 16) \ + { \ + out_uint8(in_s, 0xe0); \ + temp = in_count / 2 - 16; \ + out_uint8(in_s, temp); \ + out_uint8(in_s, in_color1 & 0xff); \ + out_uint8(in_s, (in_color1 >> 8) & 0xff); \ + out_uint8(in_s, (in_color1 >> 16) & 0xff); \ + out_uint8(in_s, in_color2 & 0xff); \ + out_uint8(in_s, (in_color2 >> 8) & 0xff); \ + out_uint8(in_s, (in_color2 >> 16) & 0xff); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf8); \ + temp = in_count / 2; \ + out_uint16_le(in_s, temp); \ + out_uint8(in_s, in_color1 & 0xff); \ + out_uint8(in_s, (in_color1 >> 8) & 0xff); \ + out_uint8(in_s, (in_color1 >> 16) & 0xff); \ + out_uint8(in_s, in_color2 & 0xff); \ + out_uint8(in_s, (in_color2 >> 8) & 0xff); \ + out_uint8(in_s, (in_color2 >> 16) & 0xff); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* fill */ #define OUT_FILL_COUNT1(in_count, in_s) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ - { \ - out_uint8(in_s, in_count); \ - } \ - else if (in_count < 256 + 32) \ { \ - out_uint8(in_s, 0x0); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf0); \ - out_uint16_le(in_s, in_count); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + out_uint8(in_s, in_count); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x0); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf0); \ + out_uint16_le(in_s, in_count); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* fill */ #define OUT_FILL_COUNT2(in_count, in_s) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ - { \ - out_uint8(in_s, in_count); \ - } \ - else if (in_count < 256 + 32) \ { \ - out_uint8(in_s, 0x0); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf0); \ - out_uint16_le(in_s, in_count); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + out_uint8(in_s, in_count); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x0); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf0); \ + out_uint16_le(in_s, in_count); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* fill */ #define OUT_FILL_COUNT3(in_count, in_s) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ - { \ - out_uint8(in_s, in_count); \ - } \ - else if (in_count < 256 + 32) \ - { \ - out_uint8(in_s, 0x0); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - } \ - else \ { \ - out_uint8(in_s, 0xf0); \ - out_uint16_le(in_s, in_count); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + out_uint8(in_s, in_count); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x0); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf0); \ + out_uint16_le(in_s, in_count); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* mix */ #define OUT_MIX_COUNT1(in_count, in_s) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ { \ - temp = (0x1 << 5) | in_count; \ - out_uint8(in_s, temp); \ - } \ - else if (in_count < 256 + 32) \ - { \ - out_uint8(in_s, 0x20); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf1); \ - out_uint16_le(in_s, in_count); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x1 << 5) | in_count; \ + out_uint8(in_s, temp); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x20); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf1); \ + out_uint16_le(in_s, in_count); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* mix */ #define OUT_MIX_COUNT2(in_count, in_s) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ { \ - temp = (0x1 << 5) | in_count; \ - out_uint8(in_s, temp); \ - } \ - else if (in_count < 256 + 32) \ - { \ - out_uint8(in_s, 0x20); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf1); \ - out_uint16_le(in_s, in_count); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x1 << 5) | in_count; \ + out_uint8(in_s, temp); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x20); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf1); \ + out_uint16_le(in_s, in_count); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* mix */ #define OUT_MIX_COUNT3(in_count, in_s) \ -{ \ - if (in_count > 0) \ - { \ - if (in_count < 32) \ - { \ - temp = (0x1 << 5) | in_count; \ - out_uint8(in_s, temp); \ - } \ - else if (in_count < 256 + 32) \ { \ - out_uint8(in_s, 0x20); \ - temp = in_count - 32; \ - out_uint8(in_s, temp); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf1); \ - out_uint16_le(in_s, in_count); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if (in_count < 32) \ + { \ + temp = (0x1 << 5) | in_count; \ + out_uint8(in_s, temp); \ + } \ + else if (in_count < 256 + 32) \ + { \ + out_uint8(in_s, 0x20); \ + temp = in_count - 32; \ + out_uint8(in_s, temp); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf1); \ + out_uint16_le(in_s, in_count); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* fom */ #define OUT_FOM_COUNT1(in_count, in_s, in_mask, in_mask_len) \ -{ \ - if (in_count > 0) \ - { \ - if ((in_count % 8) == 0 && in_count < 249) \ - { \ - temp = (0x2 << 5) | (in_count / 8); \ - out_uint8(in_s, temp); \ - out_uint8a(in_s, in_mask, in_mask_len); \ - } \ - else if (in_count < 256) \ { \ - out_uint8(in_s, 0x40); \ - temp = in_count - 1; \ - out_uint8(in_s, temp); \ - out_uint8a(in_s, in_mask, in_mask_len); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf2); \ - out_uint16_le(in_s, in_count); \ - out_uint8a(in_s, in_mask, in_mask_len); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if ((in_count % 8) == 0 && in_count < 249) \ + { \ + temp = (0x2 << 5) | (in_count / 8); \ + out_uint8(in_s, temp); \ + out_uint8a(in_s, in_mask, in_mask_len); \ + } \ + else if (in_count < 256) \ + { \ + out_uint8(in_s, 0x40); \ + temp = in_count - 1; \ + out_uint8(in_s, temp); \ + out_uint8a(in_s, in_mask, in_mask_len); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf2); \ + out_uint16_le(in_s, in_count); \ + out_uint8a(in_s, in_mask, in_mask_len); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* fom */ #define OUT_FOM_COUNT2(in_count, in_s, in_mask, in_mask_len) \ -{ \ - if (in_count > 0) \ - { \ - if ((in_count % 8) == 0 && in_count < 249) \ - { \ - temp = (0x2 << 5) | (in_count / 8); \ - out_uint8(in_s, temp); \ - out_uint8a(in_s, in_mask, in_mask_len); \ - } \ - else if (in_count < 256) \ - { \ - out_uint8(in_s, 0x40); \ - temp = in_count - 1; \ - out_uint8(in_s, temp); \ - out_uint8a(in_s, in_mask, in_mask_len); \ - } \ - else \ { \ - out_uint8(in_s, 0xf2); \ - out_uint16_le(in_s, in_count); \ - out_uint8a(in_s, in_mask, in_mask_len); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if ((in_count % 8) == 0 && in_count < 249) \ + { \ + temp = (0x2 << 5) | (in_count / 8); \ + out_uint8(in_s, temp); \ + out_uint8a(in_s, in_mask, in_mask_len); \ + } \ + else if (in_count < 256) \ + { \ + out_uint8(in_s, 0x40); \ + temp = in_count - 1; \ + out_uint8(in_s, temp); \ + out_uint8a(in_s, in_mask, in_mask_len); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf2); \ + out_uint16_le(in_s, in_count); \ + out_uint8a(in_s, in_mask, in_mask_len); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ /* fill or mix (fom) */ #define OUT_FOM_COUNT3(in_count, in_s, in_mask, in_mask_len) \ -{ \ - if (in_count > 0) \ - { \ - if ((in_count % 8) == 0 && in_count < 249) \ - { \ - temp = (0x2 << 5) | (in_count / 8); \ - out_uint8(in_s, temp); \ - out_uint8a(in_s, in_mask, in_mask_len); \ - } \ - else if (in_count < 256) \ { \ - out_uint8(in_s, 0x40); \ - temp = in_count - 1; \ - out_uint8(in_s, temp); \ - out_uint8a(in_s, in_mask, in_mask_len); \ - } \ - else \ - { \ - out_uint8(in_s, 0xf2); \ - out_uint16_le(in_s, in_count); \ - out_uint8a(in_s, in_mask, in_mask_len); \ - } \ - } \ - in_count = 0; \ -} + if (in_count > 0) \ + { \ + if ((in_count % 8) == 0 && in_count < 249) \ + { \ + temp = (0x2 << 5) | (in_count / 8); \ + out_uint8(in_s, temp); \ + out_uint8a(in_s, in_mask, in_mask_len); \ + } \ + else if (in_count < 256) \ + { \ + out_uint8(in_s, 0x40); \ + temp = in_count - 1; \ + out_uint8(in_s, temp); \ + out_uint8a(in_s, in_mask, in_mask_len); \ + } \ + else \ + { \ + out_uint8(in_s, 0xf2); \ + out_uint16_le(in_s, in_count); \ + out_uint8a(in_s, in_mask, in_mask_len); \ + } \ + } \ + in_count = 0; \ + } /*****************************************************************************/ #define TEST_FILL \ -((last_line == 0 && pixel == 0) || \ - (last_line != 0 && pixel == ypixel)) + ((last_line == 0 && pixel == 0) || \ + (last_line != 0 && pixel == ypixel)) #define TEST_MIX \ -((last_line == 0 && pixel == mix) || \ - (last_line != 0 && pixel == (ypixel ^ mix))) + ((last_line == 0 && pixel == mix) || \ + (last_line != 0 && pixel == (ypixel ^ mix))) #define TEST_FOM (TEST_FILL || TEST_MIX) #define TEST_COLOR (pixel == last_pixel) #define TEST_BICOLOR \ -( \ - (pixel != last_pixel) && \ - ( \ - (!bicolor_spin && pixel == bicolor1 && last_pixel == bicolor2) || \ - (bicolor_spin && pixel == bicolor2 && last_pixel == bicolor1) \ - ) \ -) + ( \ + (pixel != last_pixel) && \ + ( \ + (!bicolor_spin && pixel == bicolor1 && last_pixel == bicolor2) || \ + (bicolor_spin && pixel == bicolor2 && last_pixel == bicolor1) \ + ) \ + ) #define RESET_COUNTS \ -{ \ - bicolor_count = 0; \ - fill_count = 0; \ - color_count = 0; \ - mix_count = 0; \ - fom_count = 0; \ - fom_mask_len = 0; \ - bicolor_spin = 0; \ -} + { \ + bicolor_count = 0; \ + fill_count = 0; \ + color_count = 0; \ + mix_count = 0; \ + fom_count = 0; \ + fom_mask_len = 0; \ + bicolor_spin = 0; \ + } /*****************************************************************************/ int APP_CC -xrdp_bitmap_compress(char* in_data, int width, int height, - struct stream* s, int bpp, int byte_limit, - int start_line, struct stream* temp_s, +xrdp_bitmap_compress(char *in_data, int width, int height, + struct stream *s, int bpp, int byte_limit, + int start_line, struct stream *temp_s, int e) { - char* line; - char* last_line; - char fom_mask[8192]; /* good for up to 64K bitmap */ - int lines_sent; - int pixel; - int count; - int color_count; - int last_pixel; - int bicolor_count; - int bicolor1; - int bicolor2; - int bicolor_spin; - int end; - int i; - int out_count; - int ypixel; - int last_ypixel; - int fill_count; - int mix_count; - int mix; - int fom_count; - int fom_mask_len; - int temp; /* used in macros */ - - init_stream(temp_s, 0); - fom_mask_len = 0; - last_line = 0; - lines_sent = 0; - end = width + e; - count = 0; - color_count = 0; - last_pixel = 0; - last_ypixel = 0; - bicolor_count = 0; - bicolor1 = 0; - bicolor2 = 0; - bicolor_spin = 0; - fill_count = 0; - mix_count = 0; - fom_count = 0; - if (bpp == 8) - { - mix = 0xff; - out_count = end; - line = in_data + width * start_line; - while (start_line >= 0 && out_count < 32768) + char *line; + char *last_line; + char fom_mask[8192]; /* good for up to 64K bitmap */ + int lines_sent; + int pixel; + int count; + int color_count; + int last_pixel; + int bicolor_count; + int bicolor1; + int bicolor2; + int bicolor_spin; + int end; + int i; + int out_count; + int ypixel; + int last_ypixel; + int fill_count; + int mix_count; + int mix; + int fom_count; + int fom_mask_len; + int temp; /* used in macros */ + + init_stream(temp_s, 0); + fom_mask_len = 0; + last_line = 0; + lines_sent = 0; + end = width + e; + count = 0; + color_count = 0; + last_pixel = 0; + last_ypixel = 0; + bicolor_count = 0; + bicolor1 = 0; + bicolor2 = 0; + bicolor_spin = 0; + fill_count = 0; + mix_count = 0; + fom_count = 0; + + if (bpp == 8) { - i = (s->p - s->data) + count; - if (i - color_count >= byte_limit && - i - bicolor_count >= byte_limit && - i - fill_count >= byte_limit && - i - mix_count >= byte_limit && - i - fom_count >= byte_limit) - { - break; - } - out_count += end; - for (i = 0; i < end; i++) - { - /* read next pixel */ - IN_PIXEL8(line, i, 0, width, last_pixel, pixel); - IN_PIXEL8(last_line, i, 0, width, last_ypixel, ypixel); - if (!TEST_FILL) + mix = 0xff; + out_count = end; + line = in_data + width * start_line; + + while (start_line >= 0 && out_count < 32768) + { + i = (s->p - s->data) + count; + + if (i - color_count >= byte_limit && + i - bicolor_count >= byte_limit && + i - fill_count >= byte_limit && + i - mix_count >= byte_limit && + i - fom_count >= byte_limit) + { + break; + } + + out_count += end; + + for (i = 0; i < end; i++) + { + /* read next pixel */ + IN_PIXEL8(line, i, 0, width, last_pixel, pixel); + IN_PIXEL8(last_line, i, 0, width, last_ypixel, ypixel); + + if (!TEST_FILL) + { + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_FILL_COUNT1(fill_count, s); + RESET_COUNTS; + } + + fill_count = 0; + } + + if (!TEST_MIX) + { + if (mix_count > 3 && + mix_count >= fill_count && + mix_count >= bicolor_count && + mix_count >= color_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_MIX_COUNT1(mix_count, s); + RESET_COUNTS; + } + + mix_count = 0; + } + + if (!TEST_COLOR) + { + if (color_count > 3 && + color_count >= fill_count && + color_count >= bicolor_count && + color_count >= mix_count && + color_count >= fom_count) + { + count -= color_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_COLOR_COUNT1(color_count, s, last_pixel); + RESET_COUNTS; + } + + color_count = 0; + } + + if (!TEST_BICOLOR) + { + if (bicolor_count > 3 && + bicolor_count >= fill_count && + bicolor_count >= color_count && + bicolor_count >= mix_count && + bicolor_count >= fom_count) + { + if ((bicolor_count % 2) == 0) + { + count -= bicolor_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor1, bicolor2); + } + else + { + bicolor_count--; + count -= bicolor_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor2, bicolor1); + } + + RESET_COUNTS; + } + + bicolor_count = 0; + bicolor1 = last_pixel; + bicolor2 = pixel; + bicolor_spin = 0; + } + + if (!TEST_FOM) + { + if (fom_count > 3 && + fom_count >= fill_count && + fom_count >= color_count && + fom_count >= mix_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_FOM_COUNT1(fom_count, s, fom_mask, fom_mask_len); + RESET_COUNTS; + } + + fom_count = 0; + fom_mask_len = 0; + } + + if (TEST_FILL) + { + fill_count++; + } + + if (TEST_MIX) + { + mix_count++; + } + + if (TEST_COLOR) + { + color_count++; + } + + if (TEST_BICOLOR) + { + bicolor_spin = !bicolor_spin; + bicolor_count++; + } + + if (TEST_FOM) + { + if ((fom_count % 8) == 0) + { + fom_mask[fom_mask_len] = 0; + fom_mask_len++; + } + + if (pixel == (ypixel ^ mix)) + { + fom_mask[fom_mask_len - 1] |= (1 << (fom_count % 8)); + } + + fom_count++; + } + + out_uint8(temp_s, pixel); + count++; + last_pixel = pixel; + last_ypixel = ypixel; + } + + /* can't take fix, mix, or fom past first line */ + if (last_line == 0) + { + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_FILL_COUNT1(fill_count, s); + RESET_COUNTS; + } + + fill_count = 0; + + if (mix_count > 3 && + mix_count >= fill_count && + mix_count >= bicolor_count && + mix_count >= color_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_MIX_COUNT1(mix_count, s); + RESET_COUNTS; + } + + mix_count = 0; + + if (fom_count > 3 && + fom_count >= fill_count && + fom_count >= color_count && + fom_count >= mix_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_FOM_COUNT1(fom_count, s, fom_mask, fom_mask_len); + RESET_COUNTS; + } + + fom_count = 0; + fom_mask_len = 0; + } + + last_line = line; + line = line - width; + start_line--; + lines_sent++; + } + + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) { - if (fill_count > 3 && - fill_count >= color_count && - fill_count >= bicolor_count && - fill_count >= mix_count && - fill_count >= fom_count) - { count -= fill_count; OUT_COPY_COUNT1(count, s, temp_s); OUT_FILL_COUNT1(fill_count, s); - RESET_COUNTS; - } - fill_count = 0; } - if (!TEST_MIX) + else if (mix_count > 3 && + mix_count >= color_count && + mix_count >= bicolor_count && + mix_count >= fill_count && + mix_count >= fom_count) { - if (mix_count > 3 && - mix_count >= fill_count && - mix_count >= bicolor_count && - mix_count >= color_count && - mix_count >= fom_count) - { count -= mix_count; OUT_COPY_COUNT1(count, s, temp_s); OUT_MIX_COUNT1(mix_count, s); - RESET_COUNTS; - } - mix_count = 0; } - if (!TEST_COLOR) + else if (color_count > 3 && + color_count >= mix_count && + color_count >= bicolor_count && + color_count >= fill_count && + color_count >= fom_count) { - if (color_count > 3 && - color_count >= fill_count && - color_count >= bicolor_count && - color_count >= mix_count && - color_count >= fom_count) - { count -= color_count; OUT_COPY_COUNT1(count, s, temp_s); OUT_COLOR_COUNT1(color_count, s, last_pixel); - RESET_COUNTS; - } - color_count = 0; } - if (!TEST_BICOLOR) + else if (bicolor_count > 3 && + bicolor_count >= mix_count && + bicolor_count >= color_count && + bicolor_count >= fill_count && + bicolor_count >= fom_count) { - if (bicolor_count > 3 && - bicolor_count >= fill_count && - bicolor_count >= color_count && - bicolor_count >= mix_count && - bicolor_count >= fom_count) - { if ((bicolor_count % 2) == 0) { - count -= bicolor_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor1, bicolor2); + count -= bicolor_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor1, bicolor2); } else { - bicolor_count--; - count -= bicolor_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor2, bicolor1); + bicolor_count--; + count -= bicolor_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor2, bicolor1); } - RESET_COUNTS; - } - bicolor_count = 0; - bicolor1 = last_pixel; - bicolor2 = pixel; - bicolor_spin = 0; + + count -= bicolor_count; + OUT_COPY_COUNT1(count, s, temp_s); + OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor1, bicolor2); } - if (!TEST_FOM) + else if (fom_count > 3 && + fom_count >= mix_count && + fom_count >= color_count && + fom_count >= fill_count && + fom_count >= bicolor_count) { - if (fom_count > 3 && - fom_count >= fill_count && - fom_count >= color_count && - fom_count >= mix_count && - fom_count >= bicolor_count) - { count -= fom_count; OUT_COPY_COUNT1(count, s, temp_s); OUT_FOM_COUNT1(fom_count, s, fom_mask, fom_mask_len); - RESET_COUNTS; - } - fom_count = 0; - fom_mask_len = 0; } - if (TEST_FILL) + else { - fill_count++; - } - if (TEST_MIX) - { - mix_count++; - } - if (TEST_COLOR) - { - color_count++; - } - if (TEST_BICOLOR) - { - bicolor_spin = !bicolor_spin; - bicolor_count++; + OUT_COPY_COUNT1(count, s, temp_s); } - if (TEST_FOM) + } + else if ((bpp == 15) || (bpp == 16)) + { + mix = (bpp == 15) ? 0xba1f : 0xffff; + out_count = end * 2; + line = in_data + width * start_line * 2; + + while (start_line >= 0 && out_count < 32768) { - if ((fom_count % 8) == 0) - { - fom_mask[fom_mask_len] = 0; - fom_mask_len++; - } - if (pixel == (ypixel ^ mix)) - { - fom_mask[fom_mask_len - 1] |= (1 << (fom_count % 8)); - } - fom_count++; + i = (s->p - s->data) + count * 2; + + if (i - (color_count * 2) >= byte_limit && + i - (bicolor_count * 2) >= byte_limit && + i - (fill_count * 2) >= byte_limit && + i - (mix_count * 2) >= byte_limit && + i - (fom_count * 2) >= byte_limit) + { + break; + } + + out_count += end * 2; + + for (i = 0; i < end; i++) + { + /* read next pixel */ + IN_PIXEL16(line, i, 0, width, last_pixel, pixel); + IN_PIXEL16(last_line, i, 0, width, last_ypixel, ypixel); + + if (!TEST_FILL) + { + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_FILL_COUNT2(fill_count, s); + RESET_COUNTS; + } + + fill_count = 0; + } + + if (!TEST_MIX) + { + if (mix_count > 3 && + mix_count >= fill_count && + mix_count >= bicolor_count && + mix_count >= color_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_MIX_COUNT2(mix_count, s); + RESET_COUNTS; + } + + mix_count = 0; + } + + if (!TEST_COLOR) + { + if (color_count > 3 && + color_count >= fill_count && + color_count >= bicolor_count && + color_count >= mix_count && + color_count >= fom_count) + { + count -= color_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_COLOR_COUNT2(color_count, s, last_pixel); + RESET_COUNTS; + } + + color_count = 0; + } + + if (!TEST_BICOLOR) + { + if (bicolor_count > 3 && + bicolor_count >= fill_count && + bicolor_count >= color_count && + bicolor_count >= mix_count && + bicolor_count >= fom_count) + { + if ((bicolor_count % 2) == 0) + { + count -= bicolor_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor1, bicolor2); + } + else + { + bicolor_count--; + count -= bicolor_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor2, bicolor1); + } + + RESET_COUNTS; + } + + bicolor_count = 0; + bicolor1 = last_pixel; + bicolor2 = pixel; + bicolor_spin = 0; + } + + if (!TEST_FOM) + { + if (fom_count > 3 && + fom_count >= fill_count && + fom_count >= color_count && + fom_count >= mix_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_FOM_COUNT2(fom_count, s, fom_mask, fom_mask_len); + RESET_COUNTS; + } + + fom_count = 0; + fom_mask_len = 0; + } + + if (TEST_FILL) + { + fill_count++; + } + + if (TEST_MIX) + { + mix_count++; + } + + if (TEST_COLOR) + { + color_count++; + } + + if (TEST_BICOLOR) + { + bicolor_spin = !bicolor_spin; + bicolor_count++; + } + + if (TEST_FOM) + { + if ((fom_count % 8) == 0) + { + fom_mask[fom_mask_len] = 0; + fom_mask_len++; + } + + if (pixel == (ypixel ^ mix)) + { + fom_mask[fom_mask_len - 1] |= (1 << (fom_count % 8)); + } + + fom_count++; + } + + out_uint16_le(temp_s, pixel); + count++; + last_pixel = pixel; + last_ypixel = ypixel; + } + + /* can't take fix, mix, or fom past first line */ + if (last_line == 0) + { + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_FILL_COUNT2(fill_count, s); + RESET_COUNTS; + } + + fill_count = 0; + + if (mix_count > 3 && + mix_count >= fill_count && + mix_count >= bicolor_count && + mix_count >= color_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_MIX_COUNT2(mix_count, s); + RESET_COUNTS; + } + + mix_count = 0; + + if (fom_count > 3 && + fom_count >= fill_count && + fom_count >= color_count && + fom_count >= mix_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_FOM_COUNT2(fom_count, s, fom_mask, fom_mask_len); + RESET_COUNTS; + } + + fom_count = 0; + fom_mask_len = 0; + } + + last_line = line; + line = line - width * 2; + start_line--; + lines_sent++; } - out_uint8(temp_s, pixel); - count++; - last_pixel = pixel; - last_ypixel = ypixel; - } - /* can't take fix, mix, or fom past first line */ - if (last_line == 0) - { + if (fill_count > 3 && - fill_count >= color_count && - fill_count >= bicolor_count && - fill_count >= mix_count && - fill_count >= fom_count) - { - count -= fill_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_FILL_COUNT1(fill_count, s); - RESET_COUNTS; - } - fill_count = 0; - if (mix_count > 3 && - mix_count >= fill_count && - mix_count >= bicolor_count && - mix_count >= color_count && - mix_count >= fom_count) - { - count -= mix_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_MIX_COUNT1(mix_count, s); - RESET_COUNTS; - } - mix_count = 0; - if (fom_count > 3 && - fom_count >= fill_count && - fom_count >= color_count && - fom_count >= mix_count && - fom_count >= bicolor_count) + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) { - count -= fom_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_FOM_COUNT1(fom_count, s, fom_mask, fom_mask_len); - RESET_COUNTS; - } - fom_count = 0; - fom_mask_len = 0; - } - last_line = line; - line = line - width; - start_line--; - lines_sent++; - } - if (fill_count > 3 && - fill_count >= color_count && - fill_count >= bicolor_count && - fill_count >= mix_count && - fill_count >= fom_count) - { - count -= fill_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_FILL_COUNT1(fill_count, s); - } - else if (mix_count > 3 && - mix_count >= color_count && - mix_count >= bicolor_count && - mix_count >= fill_count && - mix_count >= fom_count) - { - count -= mix_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_MIX_COUNT1(mix_count, s); - } - else if (color_count > 3 && - color_count >= mix_count && - color_count >= bicolor_count && - color_count >= fill_count && - color_count >= fom_count) - { - count -= color_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_COLOR_COUNT1(color_count, s, last_pixel); - } - else if (bicolor_count > 3 && - bicolor_count >= mix_count && - bicolor_count >= color_count && - bicolor_count >= fill_count && - bicolor_count >= fom_count) - { - if ((bicolor_count % 2) == 0) - { - count -= bicolor_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor1, bicolor2); - } - else - { - bicolor_count--; - count -= bicolor_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor2, bicolor1); - } - count -= bicolor_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_BICOLOR_COUNT1(bicolor_count, s, bicolor1, bicolor2); - } - else if (fom_count > 3 && - fom_count >= mix_count && - fom_count >= color_count && - fom_count >= fill_count && - fom_count >= bicolor_count) - { - count -= fom_count; - OUT_COPY_COUNT1(count, s, temp_s); - OUT_FOM_COUNT1(fom_count, s, fom_mask, fom_mask_len); - } - else - { - OUT_COPY_COUNT1(count, s, temp_s); - } - } - else if ((bpp == 15) || (bpp == 16)) - { - mix = (bpp == 15) ? 0xba1f : 0xffff; - out_count = end * 2; - line = in_data + width * start_line * 2; - while (start_line >= 0 && out_count < 32768) - { - i = (s->p - s->data) + count * 2; - if (i - (color_count * 2) >= byte_limit && - i - (bicolor_count * 2) >= byte_limit && - i - (fill_count * 2) >= byte_limit && - i - (mix_count * 2) >= byte_limit && - i - (fom_count * 2) >= byte_limit) - { - break; - } - out_count += end * 2; - for (i = 0; i < end; i++) - { - /* read next pixel */ - IN_PIXEL16(line, i, 0, width, last_pixel, pixel); - IN_PIXEL16(last_line, i, 0, width, last_ypixel, ypixel); - if (!TEST_FILL) - { - if (fill_count > 3 && - fill_count >= color_count && - fill_count >= bicolor_count && - fill_count >= mix_count && - fill_count >= fom_count) - { count -= fill_count; OUT_COPY_COUNT2(count, s, temp_s); OUT_FILL_COUNT2(fill_count, s); - RESET_COUNTS; - } - fill_count = 0; } - if (!TEST_MIX) + else if (mix_count > 3 && + mix_count >= color_count && + mix_count >= bicolor_count && + mix_count >= fill_count && + mix_count >= fom_count) { - if (mix_count > 3 && - mix_count >= fill_count && - mix_count >= bicolor_count && - mix_count >= color_count && - mix_count >= fom_count) - { count -= mix_count; OUT_COPY_COUNT2(count, s, temp_s); OUT_MIX_COUNT2(mix_count, s); - RESET_COUNTS; - } - mix_count = 0; } - if (!TEST_COLOR) + else if (color_count > 3 && + color_count >= mix_count && + color_count >= bicolor_count && + color_count >= fill_count && + color_count >= fom_count) { - if (color_count > 3 && - color_count >= fill_count && - color_count >= bicolor_count && - color_count >= mix_count && - color_count >= fom_count) - { count -= color_count; OUT_COPY_COUNT2(count, s, temp_s); OUT_COLOR_COUNT2(color_count, s, last_pixel); - RESET_COUNTS; - } - color_count = 0; } - if (!TEST_BICOLOR) + else if (bicolor_count > 3 && + bicolor_count >= mix_count && + bicolor_count >= color_count && + bicolor_count >= fill_count && + bicolor_count >= fom_count) { - if (bicolor_count > 3 && - bicolor_count >= fill_count && - bicolor_count >= color_count && - bicolor_count >= mix_count && - bicolor_count >= fom_count) - { if ((bicolor_count % 2) == 0) { - count -= bicolor_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor1, bicolor2); + count -= bicolor_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor1, bicolor2); } else { - bicolor_count--; - count -= bicolor_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor2, bicolor1); + bicolor_count--; + count -= bicolor_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor2, bicolor1); } - RESET_COUNTS; - } - bicolor_count = 0; - bicolor1 = last_pixel; - bicolor2 = pixel; - bicolor_spin = 0; + + count -= bicolor_count; + OUT_COPY_COUNT2(count, s, temp_s); + OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor1, bicolor2); } - if (!TEST_FOM) + else if (fom_count > 3 && + fom_count >= mix_count && + fom_count >= color_count && + fom_count >= fill_count && + fom_count >= bicolor_count) { - if (fom_count > 3 && - fom_count >= fill_count && - fom_count >= color_count && - fom_count >= mix_count && - fom_count >= bicolor_count) - { count -= fom_count; OUT_COPY_COUNT2(count, s, temp_s); OUT_FOM_COUNT2(fom_count, s, fom_mask, fom_mask_len); - RESET_COUNTS; - } - fom_count = 0; - fom_mask_len = 0; } - if (TEST_FILL) + else { - fill_count++; - } - if (TEST_MIX) - { - mix_count++; - } - if (TEST_COLOR) - { - color_count++; - } - if (TEST_BICOLOR) - { - bicolor_spin = !bicolor_spin; - bicolor_count++; + OUT_COPY_COUNT2(count, s, temp_s); } - if (TEST_FOM) + } + else if (bpp == 24) + { + mix = 0xffffff; + out_count = end * 3; + line = in_data + width * start_line * 4; + + while (start_line >= 0 && out_count < 32768) { - if ((fom_count % 8) == 0) - { - fom_mask[fom_mask_len] = 0; - fom_mask_len++; - } - if (pixel == (ypixel ^ mix)) - { - fom_mask[fom_mask_len - 1] |= (1 << (fom_count % 8)); - } - fom_count++; + i = (s->p - s->data) + count * 3; + + if (i - (color_count * 3) >= byte_limit && + i - (bicolor_count * 3) >= byte_limit && + i - (fill_count * 3) >= byte_limit && + i - (mix_count * 3) >= byte_limit && + i - (fom_count * 3) >= byte_limit) + { + break; + } + + out_count += end * 3; + + for (i = 0; i < end; i++) + { + /* read next pixel */ + IN_PIXEL32(line, i, 0, width, last_pixel, pixel); + IN_PIXEL32(last_line, i, 0, width, last_ypixel, ypixel); + + if (!TEST_FILL) + { + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_FILL_COUNT3(fill_count, s); + RESET_COUNTS; + } + + fill_count = 0; + } + + if (!TEST_MIX) + { + if (mix_count > 3 && + mix_count >= fill_count && + mix_count >= bicolor_count && + mix_count >= color_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_MIX_COUNT3(mix_count, s); + RESET_COUNTS; + } + + mix_count = 0; + } + + if (!TEST_COLOR) + { + if (color_count > 3 && + color_count >= fill_count && + color_count >= bicolor_count && + color_count >= mix_count && + color_count >= fom_count) + { + count -= color_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_COLOR_COUNT3(color_count, s, last_pixel); + RESET_COUNTS; + } + + color_count = 0; + } + + if (!TEST_BICOLOR) + { + if (bicolor_count > 3 && + bicolor_count >= fill_count && + bicolor_count >= color_count && + bicolor_count >= mix_count && + bicolor_count >= fom_count) + { + if ((bicolor_count % 2) == 0) + { + count -= bicolor_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor1, bicolor2); + } + else + { + bicolor_count--; + count -= bicolor_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor2, bicolor1); + } + + RESET_COUNTS; + } + + bicolor_count = 0; + bicolor1 = last_pixel; + bicolor2 = pixel; + bicolor_spin = 0; + } + + if (!TEST_FOM) + { + if (fom_count > 3 && + fom_count >= fill_count && + fom_count >= color_count && + fom_count >= mix_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_FOM_COUNT3(fom_count, s, fom_mask, fom_mask_len); + RESET_COUNTS; + } + + fom_count = 0; + fom_mask_len = 0; + } + + if (TEST_FILL) + { + fill_count++; + } + + if (TEST_MIX) + { + mix_count++; + } + + if (TEST_COLOR) + { + color_count++; + } + + if (TEST_BICOLOR) + { + bicolor_spin = !bicolor_spin; + bicolor_count++; + } + + if (TEST_FOM) + { + if ((fom_count % 8) == 0) + { + fom_mask[fom_mask_len] = 0; + fom_mask_len++; + } + + if (pixel == (ypixel ^ mix)) + { + fom_mask[fom_mask_len - 1] |= (1 << (fom_count % 8)); + } + + fom_count++; + } + + out_uint8(temp_s, pixel & 0xff); + out_uint8(temp_s, (pixel >> 8) & 0xff); + out_uint8(temp_s, (pixel >> 16) & 0xff); + count++; + last_pixel = pixel; + last_ypixel = ypixel; + } + + /* can't take fix, mix, or fom past first line */ + if (last_line == 0) + { + if (fill_count > 3 && + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) + { + count -= fill_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_FILL_COUNT3(fill_count, s); + RESET_COUNTS; + } + + fill_count = 0; + + if (mix_count > 3 && + mix_count >= fill_count && + mix_count >= bicolor_count && + mix_count >= color_count && + mix_count >= fom_count) + { + count -= mix_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_MIX_COUNT3(mix_count, s); + RESET_COUNTS; + } + + mix_count = 0; + + if (fom_count > 3 && + fom_count >= fill_count && + fom_count >= color_count && + fom_count >= mix_count && + fom_count >= bicolor_count) + { + count -= fom_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_FOM_COUNT3(fom_count, s, fom_mask, fom_mask_len); + RESET_COUNTS; + } + + fom_count = 0; + fom_mask_len = 0; + } + + last_line = line; + line = line - width * 4; + start_line--; + lines_sent++; } - out_uint16_le(temp_s, pixel); - count++; - last_pixel = pixel; - last_ypixel = ypixel; - } - /* can't take fix, mix, or fom past first line */ - if (last_line == 0) - { + if (fill_count > 3 && - fill_count >= color_count && - fill_count >= bicolor_count && - fill_count >= mix_count && - fill_count >= fom_count) - { - count -= fill_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_FILL_COUNT2(fill_count, s); - RESET_COUNTS; - } - fill_count = 0; - if (mix_count > 3 && - mix_count >= fill_count && - mix_count >= bicolor_count && - mix_count >= color_count && - mix_count >= fom_count) - { - count -= mix_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_MIX_COUNT2(mix_count, s); - RESET_COUNTS; - } - mix_count = 0; - if (fom_count > 3 && - fom_count >= fill_count && - fom_count >= color_count && - fom_count >= mix_count && - fom_count >= bicolor_count) - { - count -= fom_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_FOM_COUNT2(fom_count, s, fom_mask, fom_mask_len); - RESET_COUNTS; - } - fom_count = 0; - fom_mask_len = 0; - } - last_line = line; - line = line - width * 2; - start_line--; - lines_sent++; - } - if (fill_count > 3 && - fill_count >= color_count && - fill_count >= bicolor_count && - fill_count >= mix_count && - fill_count >= fom_count) - { - count -= fill_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_FILL_COUNT2(fill_count, s); - } - else if (mix_count > 3 && - mix_count >= color_count && - mix_count >= bicolor_count && - mix_count >= fill_count && - mix_count >= fom_count) - { - count -= mix_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_MIX_COUNT2(mix_count, s); - } - else if (color_count > 3 && - color_count >= mix_count && - color_count >= bicolor_count && - color_count >= fill_count && - color_count >= fom_count) - { - count -= color_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_COLOR_COUNT2(color_count, s, last_pixel); - } - else if (bicolor_count > 3 && - bicolor_count >= mix_count && - bicolor_count >= color_count && - bicolor_count >= fill_count && - bicolor_count >= fom_count) - { - if ((bicolor_count % 2) == 0) - { - count -= bicolor_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor1, bicolor2); - } - else - { - bicolor_count--; - count -= bicolor_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor2, bicolor1); - } - count -= bicolor_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_BICOLOR_COUNT2(bicolor_count, s, bicolor1, bicolor2); - } - else if (fom_count > 3 && - fom_count >= mix_count && - fom_count >= color_count && - fom_count >= fill_count && - fom_count >= bicolor_count) - { - count -= fom_count; - OUT_COPY_COUNT2(count, s, temp_s); - OUT_FOM_COUNT2(fom_count, s, fom_mask, fom_mask_len); - } - else - { - OUT_COPY_COUNT2(count, s, temp_s); - } - } - else if (bpp == 24) - { - mix = 0xffffff; - out_count = end * 3; - line = in_data + width * start_line * 4; - while (start_line >= 0 && out_count < 32768) - { - i = (s->p - s->data) + count * 3; - if (i - (color_count * 3) >= byte_limit && - i - (bicolor_count * 3) >= byte_limit && - i - (fill_count * 3) >= byte_limit && - i - (mix_count * 3) >= byte_limit && - i - (fom_count * 3) >= byte_limit) - { - break; - } - out_count += end * 3; - for (i = 0; i < end; i++) - { - /* read next pixel */ - IN_PIXEL32(line, i, 0, width, last_pixel, pixel); - IN_PIXEL32(last_line, i, 0, width, last_ypixel, ypixel); - if (!TEST_FILL) + fill_count >= color_count && + fill_count >= bicolor_count && + fill_count >= mix_count && + fill_count >= fom_count) { - if (fill_count > 3 && - fill_count >= color_count && - fill_count >= bicolor_count && - fill_count >= mix_count && - fill_count >= fom_count) - { count -= fill_count; OUT_COPY_COUNT3(count, s, temp_s); OUT_FILL_COUNT3(fill_count, s); - RESET_COUNTS; - } - fill_count = 0; } - if (!TEST_MIX) + else if (mix_count > 3 && + mix_count >= color_count && + mix_count >= bicolor_count && + mix_count >= fill_count && + mix_count >= fom_count) { - if (mix_count > 3 && - mix_count >= fill_count && - mix_count >= bicolor_count && - mix_count >= color_count && - mix_count >= fom_count) - { count -= mix_count; OUT_COPY_COUNT3(count, s, temp_s); OUT_MIX_COUNT3(mix_count, s); - RESET_COUNTS; - } - mix_count = 0; } - if (!TEST_COLOR) + else if (color_count > 3 && + color_count >= mix_count && + color_count >= bicolor_count && + color_count >= fill_count && + color_count >= fom_count) { - if (color_count > 3 && - color_count >= fill_count && - color_count >= bicolor_count && - color_count >= mix_count && - color_count >= fom_count) - { count -= color_count; OUT_COPY_COUNT3(count, s, temp_s); OUT_COLOR_COUNT3(color_count, s, last_pixel); - RESET_COUNTS; - } - color_count = 0; } - if (!TEST_BICOLOR) + else if (bicolor_count > 3 && + bicolor_count >= mix_count && + bicolor_count >= color_count && + bicolor_count >= fill_count && + bicolor_count >= fom_count) { - if (bicolor_count > 3 && - bicolor_count >= fill_count && - bicolor_count >= color_count && - bicolor_count >= mix_count && - bicolor_count >= fom_count) - { if ((bicolor_count % 2) == 0) { - count -= bicolor_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor1, bicolor2); + count -= bicolor_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor1, bicolor2); } else { - bicolor_count--; - count -= bicolor_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor2, bicolor1); + bicolor_count--; + count -= bicolor_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor2, bicolor1); } - RESET_COUNTS; - } - bicolor_count = 0; - bicolor1 = last_pixel; - bicolor2 = pixel; - bicolor_spin = 0; + + count -= bicolor_count; + OUT_COPY_COUNT3(count, s, temp_s); + OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor1, bicolor2); } - if (!TEST_FOM) + else if (fom_count > 3 && + fom_count >= mix_count && + fom_count >= color_count && + fom_count >= fill_count && + fom_count >= bicolor_count) { - if (fom_count > 3 && - fom_count >= fill_count && - fom_count >= color_count && - fom_count >= mix_count && - fom_count >= bicolor_count) - { count -= fom_count; OUT_COPY_COUNT3(count, s, temp_s); OUT_FOM_COUNT3(fom_count, s, fom_mask, fom_mask_len); - RESET_COUNTS; - } - fom_count = 0; - fom_mask_len = 0; - } - if (TEST_FILL) - { - fill_count++; } - if (TEST_MIX) - { - mix_count++; - } - if (TEST_COLOR) - { - color_count++; - } - if (TEST_BICOLOR) - { - bicolor_spin = !bicolor_spin; - bicolor_count++; - } - if (TEST_FOM) - { - if ((fom_count % 8) == 0) - { - fom_mask[fom_mask_len] = 0; - fom_mask_len++; - } - if (pixel == (ypixel ^ mix)) - { - fom_mask[fom_mask_len - 1] |= (1 << (fom_count % 8)); - } - fom_count++; - } - out_uint8(temp_s, pixel & 0xff); - out_uint8(temp_s, (pixel >> 8) & 0xff); - out_uint8(temp_s, (pixel >> 16) & 0xff); - count++; - last_pixel = pixel; - last_ypixel = ypixel; - } - /* can't take fix, mix, or fom past first line */ - if (last_line == 0) - { - if (fill_count > 3 && - fill_count >= color_count && - fill_count >= bicolor_count && - fill_count >= mix_count && - fill_count >= fom_count) + else { - count -= fill_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_FILL_COUNT3(fill_count, s); - RESET_COUNTS; - } - fill_count = 0; - if (mix_count > 3 && - mix_count >= fill_count && - mix_count >= bicolor_count && - mix_count >= color_count && - mix_count >= fom_count) - { - count -= mix_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_MIX_COUNT3(mix_count, s); - RESET_COUNTS; - } - mix_count = 0; - if (fom_count > 3 && - fom_count >= fill_count && - fom_count >= color_count && - fom_count >= mix_count && - fom_count >= bicolor_count) - { - count -= fom_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_FOM_COUNT3(fom_count, s, fom_mask, fom_mask_len); - RESET_COUNTS; + OUT_COPY_COUNT3(count, s, temp_s); } - fom_count = 0; - fom_mask_len = 0; - } - last_line = line; - line = line - width * 4; - start_line--; - lines_sent++; - } - if (fill_count > 3 && - fill_count >= color_count && - fill_count >= bicolor_count && - fill_count >= mix_count && - fill_count >= fom_count) - { - count -= fill_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_FILL_COUNT3(fill_count, s); - } - else if (mix_count > 3 && - mix_count >= color_count && - mix_count >= bicolor_count && - mix_count >= fill_count && - mix_count >= fom_count) - { - count -= mix_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_MIX_COUNT3(mix_count, s); } - else if (color_count > 3 && - color_count >= mix_count && - color_count >= bicolor_count && - color_count >= fill_count && - color_count >= fom_count) - { - count -= color_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_COLOR_COUNT3(color_count, s, last_pixel); - } - else if (bicolor_count > 3 && - bicolor_count >= mix_count && - bicolor_count >= color_count && - bicolor_count >= fill_count && - bicolor_count >= fom_count) - { - if ((bicolor_count % 2) == 0) - { - count -= bicolor_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor1, bicolor2); - } - else - { - bicolor_count--; - count -= bicolor_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor2, bicolor1); - } - count -= bicolor_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_BICOLOR_COUNT3(bicolor_count, s, bicolor1, bicolor2); - } - else if (fom_count > 3 && - fom_count >= mix_count && - fom_count >= color_count && - fom_count >= fill_count && - fom_count >= bicolor_count) - { - count -= fom_count; - OUT_COPY_COUNT3(count, s, temp_s); - OUT_FOM_COUNT3(fom_count, s, fom_mask, fom_mask_len); - } - else - { - OUT_COPY_COUNT3(count, s, temp_s); - } - } - return lines_sent; + + return lines_sent; } diff --git a/libxrdp/xrdp_channel.c b/libxrdp/xrdp_channel.c index 2b3d23a5..6f40b751 100644 --- a/libxrdp/xrdp_channel.c +++ b/libxrdp/xrdp_channel.c @@ -1,24 +1,22 @@ -/* - 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. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2006-2010 - - channel layer - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2006-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * channel layer + */ #include "libxrdp.h" @@ -31,86 +29,96 @@ /*****************************************************************************/ /* returns pointer or nil on error */ -static struct mcs_channel_item* APP_CC -xrdp_channel_get_item(struct xrdp_channel* self, int channel_id) +static struct mcs_channel_item *APP_CC +xrdp_channel_get_item(struct xrdp_channel *self, int channel_id) { - struct mcs_channel_item* channel; - if(self->mcs_layer->channel_list==NULL) - { - g_writeln("xrdp_channel_get_item - No channel initialized"); - return NULL ; - } - channel = (struct mcs_channel_item*) - list_get_item(self->mcs_layer->channel_list, channel_id); - return channel; + struct mcs_channel_item *channel; + + if (self->mcs_layer->channel_list == NULL) + { + g_writeln("xrdp_channel_get_item - No channel initialized"); + return NULL ; + } + + channel = (struct mcs_channel_item *) + list_get_item(self->mcs_layer->channel_list, channel_id); + return channel; } /*****************************************************************************/ -struct xrdp_channel* APP_CC -xrdp_channel_create(struct xrdp_sec* owner, struct xrdp_mcs* mcs_layer) +struct xrdp_channel *APP_CC +xrdp_channel_create(struct xrdp_sec *owner, struct xrdp_mcs *mcs_layer) { - struct xrdp_channel* self; + struct xrdp_channel *self; - self = (struct xrdp_channel*)g_malloc(sizeof(struct xrdp_channel), 1); - self->sec_layer = owner; - self->mcs_layer = mcs_layer; - return self; + self = (struct xrdp_channel *)g_malloc(sizeof(struct xrdp_channel), 1); + self->sec_layer = owner; + self->mcs_layer = mcs_layer; + return self; } /*****************************************************************************/ /* returns error */ void APP_CC -xrdp_channel_delete(struct xrdp_channel* self) +xrdp_channel_delete(struct xrdp_channel *self) { - if (self == 0) - { - return; - } - g_memset(self,0,sizeof(struct xrdp_channel)); - g_free(self); + if (self == 0) + { + return; + } + + g_memset(self, 0, sizeof(struct xrdp_channel)); + g_free(self); } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_channel_init(struct xrdp_channel* self, struct stream* s) +xrdp_channel_init(struct xrdp_channel *self, struct stream *s) { - if (xrdp_sec_init(self->sec_layer, s) != 0) - { - return 1; - } - s_push_layer(s, channel_hdr, 8); - return 0; + if (xrdp_sec_init(self->sec_layer, s) != 0) + { + return 1; + } + + s_push_layer(s, channel_hdr, 8); + return 0; } /*****************************************************************************/ /* returns error */ /* This sends data out to the secure layer. */ int APP_CC -xrdp_channel_send(struct xrdp_channel* self, struct stream* s, int channel_id, +xrdp_channel_send(struct xrdp_channel *self, struct stream *s, int channel_id, int total_data_len, int flags) { - struct mcs_channel_item* channel; - - channel = xrdp_channel_get_item(self, channel_id); - if (channel == NULL) - { - g_writeln("xrdp_channel_send - no such channel"); - return 1; - } - s_pop_layer(s, channel_hdr); - out_uint32_le(s, total_data_len); - if (channel->flags & XR_CHANNEL_OPTION_SHOW_PROTOCOL) - { - flags |= CHANNEL_FLAG_SHOW_PROTOCOL; - } - out_uint32_le(s, flags); - if (xrdp_sec_send(self->sec_layer, s, channel->chanid) != 0) - { - g_writeln("xrdp_channel_send - failure sending data"); - return 1; - } - return 0; + struct mcs_channel_item *channel; + + channel = xrdp_channel_get_item(self, channel_id); + + if (channel == NULL) + { + g_writeln("xrdp_channel_send - no such channel"); + return 1; + } + + s_pop_layer(s, channel_hdr); + out_uint32_le(s, total_data_len); + + if (channel->flags & XR_CHANNEL_OPTION_SHOW_PROTOCOL) + { + flags |= CHANNEL_FLAG_SHOW_PROTOCOL; + } + + out_uint32_le(s, flags); + + if (xrdp_sec_send(self->sec_layer, s, channel->chanid) != 0) + { + g_writeln("xrdp_channel_send - failure sending data"); + return 1; + } + + return 0; } /*****************************************************************************/ @@ -118,36 +126,38 @@ xrdp_channel_send(struct xrdp_channel* self, struct stream* s, int channel_id, /* this will inform the callback, whatever it is that some channel data is ready. the default for this is a call to xrdp_wm.c. */ static int APP_CC -xrdp_channel_call_callback(struct xrdp_channel* self, struct stream* s, +xrdp_channel_call_callback(struct xrdp_channel *self, struct stream *s, int channel_id, int total_data_len, int flags) { - struct xrdp_session* session; - int rv; - int size; - - rv = 0; - session = self->sec_layer->rdp_layer->session; - if (session != 0) - { - if (session->callback != 0) + struct xrdp_session *session; + int rv; + int size; + + rv = 0; + session = self->sec_layer->rdp_layer->session; + + if (session != 0) { - size = (int)(s->end - s->p); - /* in xrdp_wm.c */ - rv = session->callback(session->id, 0x5555, - MAKELONG(channel_id, flags), - size, (tbus)(s->p), total_data_len); + if (session->callback != 0) + { + size = (int)(s->end - s->p); + /* in xrdp_wm.c */ + rv = session->callback(session->id, 0x5555, + MAKELONG(channel_id, flags), + size, (tbus)(s->p), total_data_len); + } + else + { + g_writeln("in xrdp_channel_call_callback, session->callback is nil"); + } } else { - g_writeln("in xrdp_channel_call_callback, session->callback is nil"); + g_writeln("in xrdp_channel_call_callback, session is nil"); } - } - else - { - g_writeln("in xrdp_channel_call_callback, session is nil"); - } - return rv; + + return rv; } /*****************************************************************************/ @@ -157,30 +167,32 @@ xrdp_channel_call_callback(struct xrdp_channel* self, struct stream* s, 'chanid' passed in here is the mcs channel id so it MCS_GLOBAL_CHANNEL plus something. */ int APP_CC -xrdp_channel_process(struct xrdp_channel* self, struct stream* s, +xrdp_channel_process(struct xrdp_channel *self, struct stream *s, int chanid) { - int length; - int flags; - int rv; - int channel_id; - struct mcs_channel_item* channel; - - - /* this assumes that the channels are in order of chanid(mcs channel id) - but they should be, see xrdp_sec_process_mcs_data_channels - the first channel should be MCS_GLOBAL_CHANNEL + 1, second - one should be MCS_GLOBAL_CHANNEL + 2, and so on */ - channel_id = (chanid - MCS_GLOBAL_CHANNEL) - 1; - channel = xrdp_channel_get_item(self, channel_id); - if (channel == NULL) - { - g_writeln("xrdp_channel_process, channel not found"); - return 1; - } - rv = 0; - in_uint32_le(s, length); - in_uint32_le(s, flags); - rv = xrdp_channel_call_callback(self, s, channel_id, length, flags); - return rv; + int length; + int flags; + int rv; + int channel_id; + struct mcs_channel_item *channel; + + + /* this assumes that the channels are in order of chanid(mcs channel id) + but they should be, see xrdp_sec_process_mcs_data_channels + the first channel should be MCS_GLOBAL_CHANNEL + 1, second + one should be MCS_GLOBAL_CHANNEL + 2, and so on */ + channel_id = (chanid - MCS_GLOBAL_CHANNEL) - 1; + channel = xrdp_channel_get_item(self, channel_id); + + if (channel == NULL) + { + g_writeln("xrdp_channel_process, channel not found"); + return 1; + } + + rv = 0; + in_uint32_le(s, length); + in_uint32_le(s, flags); + rv = xrdp_channel_call_callback(self, s, channel_id, length, flags); + return rv; } diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c index 9a147b1b..35d90407 100644 --- a/libxrdp/xrdp_fastpath.c +++ b/libxrdp/xrdp_fastpath.c @@ -20,177 +20,190 @@ #include "libxrdp.h" /*****************************************************************************/ -struct xrdp_fastpath* APP_CC -xrdp_fastpath_create(struct xrdp_session* session) +struct xrdp_fastpath *APP_CC +xrdp_fastpath_create(struct xrdp_session *session) { - struct xrdp_fastpath* self; - - self = (struct xrdp_fastpath*)g_malloc(sizeof(struct xrdp_fastpath), 1); - self->tcp_layer = - ((struct xrdp_rdp*)session->rdp)->sec_layer-> - mcs_layer->iso_layer->tcp_layer; - make_stream(self->out_s); - init_stream(self->out_s, FASTPATH_MAX_PACKET_SIZE); - return self; + struct xrdp_fastpath *self; + + self = (struct xrdp_fastpath *)g_malloc(sizeof(struct xrdp_fastpath), 1); + self->tcp_layer = + ((struct xrdp_rdp *)session->rdp)->sec_layer-> + mcs_layer->iso_layer->tcp_layer; + make_stream(self->out_s); + init_stream(self->out_s, FASTPATH_MAX_PACKET_SIZE); + return self; } /*****************************************************************************/ void APP_CC -xrdp_fastpath_delete(struct xrdp_fastpath* self) +xrdp_fastpath_delete(struct xrdp_fastpath *self) { - if (self == 0) - { - return; - } - free_stream(self->out_s); - g_free(self); + if (self == 0) + { + return; + } + + free_stream(self->out_s); + g_free(self); } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_fastpath_reset(struct xrdp_fastpath* self) +xrdp_fastpath_reset(struct xrdp_fastpath *self) { - return 0; + return 0; } int APP_CC -xrdp_fastpath_init(struct xrdp_fastpath* self) +xrdp_fastpath_init(struct xrdp_fastpath *self) { - return 0; + return 0; } /*****************************************************************************/ int APP_CC -xrdp_fastpath_send_update_pdu(struct xrdp_fastpath* self, tui8 updateCode, - struct stream* s) +xrdp_fastpath_send_update_pdu(struct xrdp_fastpath *self, tui8 updateCode, + struct stream *s) { - tui16 len; - tui16 maxLen; - tui32 payloadLeft; - tui8 fragment; - struct stream* s_send; - int compression; - int i; - int i32; - - compression = 0; - s_send = self->out_s; - maxLen = FASTPATH_MAX_PACKET_SIZE - 6; /* 6 bytes for header */ - payloadLeft = (s->end - s->data); - for (i = 0; payloadLeft > 0; i++) - { - if (payloadLeft > maxLen) - { - len = maxLen; - } - else - { - len = payloadLeft; - } - payloadLeft -= len; - if (payloadLeft == 0) - { - fragment = i ? FASTPATH_FRAGMENT_LAST : FASTPATH_FRAGMENT_SINGLE; - } - else - { - fragment = i ? FASTPATH_FRAGMENT_NEXT : FASTPATH_FRAGMENT_FIRST; - } - init_stream(s_send, 0); - out_uint8(s_send, 0); /* fOutputHeader */ - i32 = ((len + 6) >> 8) | 0x80; - out_uint8(s_send, i32); /* use 2 bytes for length even length < 128 ??? */ - i32 = (len + 6) & 0xff; - out_uint8(s_send, i32); - i32 = (updateCode & 0x0f) | ((fragment & 0x03) << 4) | - ((compression & 0x03) << 6); - out_uint8(s_send, i32); - out_uint16_le(s_send, len); - s_copy(s_send, s, len); - s_mark_end(s_send); - if (xrdp_tcp_send(self->tcp_layer, s_send) != 0) + tui16 len; + tui16 maxLen; + tui32 payloadLeft; + tui8 fragment; + struct stream *s_send; + int compression; + int i; + int i32; + + compression = 0; + s_send = self->out_s; + maxLen = FASTPATH_MAX_PACKET_SIZE - 6; /* 6 bytes for header */ + payloadLeft = (s->end - s->data); + + for (i = 0; payloadLeft > 0; i++) { - return 1; + if (payloadLeft > maxLen) + { + len = maxLen; + } + else + { + len = payloadLeft; + } + + payloadLeft -= len; + + if (payloadLeft == 0) + { + fragment = i ? FASTPATH_FRAGMENT_LAST : FASTPATH_FRAGMENT_SINGLE; + } + else + { + fragment = i ? FASTPATH_FRAGMENT_NEXT : FASTPATH_FRAGMENT_FIRST; + } + + init_stream(s_send, 0); + out_uint8(s_send, 0); /* fOutputHeader */ + i32 = ((len + 6) >> 8) | 0x80; + out_uint8(s_send, i32); /* use 2 bytes for length even length < 128 ??? */ + i32 = (len + 6) & 0xff; + out_uint8(s_send, i32); + i32 = (updateCode & 0x0f) | ((fragment & 0x03) << 4) | + ((compression & 0x03) << 6); + out_uint8(s_send, i32); + out_uint16_le(s_send, len); + s_copy(s_send, s, len); + s_mark_end(s_send); + + if (xrdp_tcp_send(self->tcp_layer, s_send) != 0) + { + return 1; + } } - } - return 0; + + return 0; } /*****************************************************************************/ int -xrdp_fastpath_process_update(struct xrdp_fastpath* self, tui8 updateCode, - tui32 size, struct stream* s) +xrdp_fastpath_process_update(struct xrdp_fastpath *self, tui8 updateCode, + tui32 size, struct stream *s) { - switch (updateCode) - { - case FASTPATH_UPDATETYPE_ORDERS: - case FASTPATH_UPDATETYPE_BITMAP: - case FASTPATH_UPDATETYPE_PALETTE: - case FASTPATH_UPDATETYPE_SYNCHRONIZE: - case FASTPATH_UPDATETYPE_SURFCMDS: - case FASTPATH_UPDATETYPE_PTR_NULL: - case FASTPATH_UPDATETYPE_PTR_DEFAULT: - case FASTPATH_UPDATETYPE_PTR_POSITION: - case FASTPATH_UPDATETYPE_COLOR: - case FASTPATH_UPDATETYPE_CACHED: - case FASTPATH_UPDATETYPE_POINTER: - break; - default: - g_writeln("xrdp_fastpath_process_update: unknown updateCode 0x%X", - updateCode); - break; - } - - return 0; + switch (updateCode) + { + case FASTPATH_UPDATETYPE_ORDERS: + case FASTPATH_UPDATETYPE_BITMAP: + case FASTPATH_UPDATETYPE_PALETTE: + case FASTPATH_UPDATETYPE_SYNCHRONIZE: + case FASTPATH_UPDATETYPE_SURFCMDS: + case FASTPATH_UPDATETYPE_PTR_NULL: + case FASTPATH_UPDATETYPE_PTR_DEFAULT: + case FASTPATH_UPDATETYPE_PTR_POSITION: + case FASTPATH_UPDATETYPE_COLOR: + case FASTPATH_UPDATETYPE_CACHED: + case FASTPATH_UPDATETYPE_POINTER: + break; + default: + g_writeln("xrdp_fastpath_process_update: unknown updateCode 0x%X", + updateCode); + break; + } + + return 0; } /*****************************************************************************/ int APP_CC -xrdp_fastpath_process_data(struct xrdp_fastpath* self, struct stream* s, +xrdp_fastpath_process_data(struct xrdp_fastpath *self, struct stream *s, tui8 header) { - tui8 encryptionFlags; - tui8 numberEvents; - tui8 length2; - tui8 updateHeader; - tui8 updateCode; - tui8 updateFrag; - tui8 updateComp; - tui16 length; - tui32 size; - - encryptionFlags = (header & 0xc0) >> 6; - numberEvents = (header & 0x3c) >> 2; - xrdp_tcp_recv(self->tcp_layer, s, 1); - in_uint8(s, length); - if (length & 0x80) - { + tui8 encryptionFlags; + tui8 numberEvents; + tui8 length2; + tui8 updateHeader; + tui8 updateCode; + tui8 updateFrag; + tui8 updateComp; + tui16 length; + tui32 size; + + encryptionFlags = (header & 0xc0) >> 6; + numberEvents = (header & 0x3c) >> 2; xrdp_tcp_recv(self->tcp_layer, s, 1); - in_uint8(s, length2); - length = (length & 0x7f) << 8 + length2 - 3; - } - else - { - length -= 2; - } - xrdp_tcp_recv(self->tcp_layer, s, length); - if (encryptionFlags != 0) - { - /* TODO decryption ...*/ - } - /* parse updateHeader */ - in_uint8(s, updateHeader); - updateCode = (updateHeader & 0x0f); - updateFrag = (updateHeader & 0x30) >> 4; - updateComp = (updateHeader & 0xc0) >> 6; - if (updateFrag && updateComp) - { - /* TODO */ - g_writeln("xrdp_fastpath_process_data: updateFrag=%d, updateComp=%d", - updateFrag,updateComp); - return 1; - } - in_uint16_le(s, size); - return xrdp_fastpath_process_update(self, updateCode, size, s); + in_uint8(s, length); + + if (length & 0x80) + { + xrdp_tcp_recv(self->tcp_layer, s, 1); + in_uint8(s, length2); + length = (length & 0x7f) << 8 + length2 - 3; + } + else + { + length -= 2; + } + + xrdp_tcp_recv(self->tcp_layer, s, length); + + if (encryptionFlags != 0) + { + /* TODO decryption ...*/ + } + + /* parse updateHeader */ + in_uint8(s, updateHeader); + updateCode = (updateHeader & 0x0f); + updateFrag = (updateHeader & 0x30) >> 4; + updateComp = (updateHeader & 0xc0) >> 6; + + if (updateFrag && updateComp) + { + /* TODO */ + g_writeln("xrdp_fastpath_process_data: updateFrag=%d, updateComp=%d", + updateFrag, updateComp); + return 1; + } + + in_uint16_le(s, size); + return xrdp_fastpath_process_update(self, updateCode, size, s); } diff --git a/libxrdp/xrdp_iso.c b/libxrdp/xrdp_iso.c index 7fee92e6..8dedc131 100644 --- a/libxrdp/xrdp_iso.c +++ b/libxrdp/xrdp_iso.c @@ -1,197 +1,216 @@ -/* - 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. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - iso layer - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * iso layer + */ #include "libxrdp.h" /*****************************************************************************/ -struct xrdp_iso* APP_CC -xrdp_iso_create(struct xrdp_mcs* owner, struct trans* trans) +struct xrdp_iso *APP_CC +xrdp_iso_create(struct xrdp_mcs *owner, struct trans *trans) { - struct xrdp_iso* self; - - DEBUG((" in xrdp_iso_create")); - self = (struct xrdp_iso*)g_malloc(sizeof(struct xrdp_iso), 1); - self->mcs_layer = owner; - self->tcp_layer = xrdp_tcp_create(self, trans); - DEBUG((" out xrdp_iso_create")); - return self; + struct xrdp_iso *self; + + DEBUG((" in xrdp_iso_create")); + self = (struct xrdp_iso *)g_malloc(sizeof(struct xrdp_iso), 1); + self->mcs_layer = owner; + self->tcp_layer = xrdp_tcp_create(self, trans); + DEBUG((" out xrdp_iso_create")); + return self; } /*****************************************************************************/ void APP_CC -xrdp_iso_delete(struct xrdp_iso* self) +xrdp_iso_delete(struct xrdp_iso *self) { - if (self == 0) - { - return; - } - xrdp_tcp_delete(self->tcp_layer); - g_free(self); + if (self == 0) + { + return; + } + + xrdp_tcp_delete(self->tcp_layer); + g_free(self); } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_iso_recv_msg(struct xrdp_iso* self, struct stream* s, int* code) +xrdp_iso_recv_msg(struct xrdp_iso *self, struct stream *s, int *code) { - int ver; - int len; - - *code = 0; - if (xrdp_tcp_recv(self->tcp_layer, s, 4) != 0) - { - return 1; - } - in_uint8(s, ver); - if (ver != 3) - { - return 1; - } - in_uint8s(s, 1); - in_uint16_be(s, len); - if (xrdp_tcp_recv(self->tcp_layer, s, len - 4) != 0) - { - return 1; - } - in_uint8s(s, 1); - in_uint8(s, *code); - if (*code == ISO_PDU_DT) - { + int ver; + int len; + + *code = 0; + + if (xrdp_tcp_recv(self->tcp_layer, s, 4) != 0) + { + return 1; + } + + in_uint8(s, ver); + + if (ver != 3) + { + return 1; + } + in_uint8s(s, 1); - } - else - { - in_uint8s(s, 5); - } - return 0; + in_uint16_be(s, len); + + if (xrdp_tcp_recv(self->tcp_layer, s, len - 4) != 0) + { + return 1; + } + + in_uint8s(s, 1); + in_uint8(s, *code); + + if (*code == ISO_PDU_DT) + { + in_uint8s(s, 1); + } + else + { + in_uint8s(s, 5); + } + + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_iso_recv(struct xrdp_iso* self, struct stream* s) +xrdp_iso_recv(struct xrdp_iso *self, struct stream *s) { - int code; - - DEBUG((" in xrdp_iso_recv")); - if (xrdp_iso_recv_msg(self, s, &code) != 0) - { - DEBUG((" out xrdp_iso_recv xrdp_iso_recv_msg return non zero")); - return 1; - } - if (code != ISO_PDU_DT) - { - DEBUG((" out xrdp_iso_recv code != ISO_PDU_DT")); - return 1; - } - DEBUG((" out xrdp_iso_recv")); - return 0; + int code; + + DEBUG((" in xrdp_iso_recv")); + + if (xrdp_iso_recv_msg(self, s, &code) != 0) + { + DEBUG((" out xrdp_iso_recv xrdp_iso_recv_msg return non zero")); + return 1; + } + + if (code != ISO_PDU_DT) + { + DEBUG((" out xrdp_iso_recv code != ISO_PDU_DT")); + return 1; + } + + DEBUG((" out xrdp_iso_recv")); + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_iso_send_msg(struct xrdp_iso* self, struct stream* s, int code) +xrdp_iso_send_msg(struct xrdp_iso *self, struct stream *s, int code) { - if (xrdp_tcp_init(self->tcp_layer, s) != 0) - { - return 1; - } - out_uint8(s, 3); - out_uint8(s, 0); - out_uint16_be(s, 11); /* length */ - out_uint8(s, 6); - out_uint8(s, code); - out_uint16_le(s, 0); - out_uint16_le(s, 0); - out_uint8(s, 0); - s_mark_end(s); - if (xrdp_tcp_send(self->tcp_layer, s) != 0) - { - return 1; - } - return 0; + if (xrdp_tcp_init(self->tcp_layer, s) != 0) + { + return 1; + } + + out_uint8(s, 3); + out_uint8(s, 0); + out_uint16_be(s, 11); /* length */ + out_uint8(s, 6); + out_uint8(s, code); + out_uint16_le(s, 0); + out_uint16_le(s, 0); + out_uint8(s, 0); + s_mark_end(s); + + if (xrdp_tcp_send(self->tcp_layer, s) != 0) + { + return 1; + } + + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_iso_incoming(struct xrdp_iso* self) +xrdp_iso_incoming(struct xrdp_iso *self) { - int code; - struct stream* s; - - make_stream(s); - init_stream(s, 8192); - DEBUG((" in xrdp_iso_incoming")); - if (xrdp_iso_recv_msg(self, s, &code) != 0) - { - free_stream(s); - return 1; - } - if (code != ISO_PDU_CR) - { - free_stream(s); - return 1; - } - if (xrdp_iso_send_msg(self, s, ISO_PDU_CC) != 0) - { + int code; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + DEBUG((" in xrdp_iso_incoming")); + + if (xrdp_iso_recv_msg(self, s, &code) != 0) + { + free_stream(s); + return 1; + } + + if (code != ISO_PDU_CR) + { + free_stream(s); + return 1; + } + + if (xrdp_iso_send_msg(self, s, ISO_PDU_CC) != 0) + { + free_stream(s); + return 1; + } + + DEBUG((" out xrdp_iso_incoming")); free_stream(s); - return 1; - } - DEBUG((" out xrdp_iso_incoming")); - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_iso_init(struct xrdp_iso* self, struct stream* s) +xrdp_iso_init(struct xrdp_iso *self, struct stream *s) { - xrdp_tcp_init(self->tcp_layer, s); - s_push_layer(s, iso_hdr, 7); - return 0; + xrdp_tcp_init(self->tcp_layer, s); + s_push_layer(s, iso_hdr, 7); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_iso_send(struct xrdp_iso* self, struct stream* s) +xrdp_iso_send(struct xrdp_iso *self, struct stream *s) { - int len; - - DEBUG((" in xrdp_iso_send")); - s_pop_layer(s, iso_hdr); - len = s->end - s->p; - out_uint8(s, 3); - out_uint8(s, 0); - out_uint16_be(s, len); - out_uint8(s, 2); - out_uint8(s, ISO_PDU_DT); - out_uint8(s, 0x80); - if (xrdp_tcp_send(self->tcp_layer, s) != 0) - { - return 1; - } - DEBUG((" out xrdp_iso_send")); - return 0; + int len; + + DEBUG((" in xrdp_iso_send")); + s_pop_layer(s, iso_hdr); + len = s->end - s->p; + out_uint8(s, 3); + out_uint8(s, 0); + out_uint16_be(s, len); + out_uint8(s, 2); + out_uint8(s, ISO_PDU_DT); + out_uint8(s, 0x80); + + if (xrdp_tcp_send(self->tcp_layer, s) != 0) + { + return 1; + } + + DEBUG((" out xrdp_iso_send")); + return 0; } diff --git a/libxrdp/xrdp_jpeg_compress.c b/libxrdp/xrdp_jpeg_compress.c index 8561982f..f8681e2b 100644 --- a/libxrdp/xrdp_jpeg_compress.c +++ b/libxrdp/xrdp_jpeg_compress.c @@ -1,24 +1,22 @@ -/* - 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. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2012 - - jpeg compressor - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * jpeg compressor + */ #include "libxrdp.h" @@ -33,10 +31,10 @@ struct mydata_comp { - char* cb; - int cb_bytes; - int total_done; - int overwrite; + char *cb; + int cb_bytes; + int total_done; + int overwrite; }; /*****************************************************************************/ @@ -44,13 +42,13 @@ struct mydata_comp static void DEFAULT_CC my_init_destination(j_compress_ptr cinfo) { - struct mydata_comp* md; + struct mydata_comp *md; - md = (struct mydata_comp*)(cinfo->client_data); - md->total_done = 0; - md->overwrite = 0; - cinfo->dest->next_output_byte = md->cb; - cinfo->dest->free_in_buffer = md->cb_bytes; + md = (struct mydata_comp *)(cinfo->client_data); + md->total_done = 0; + md->overwrite = 0; + cinfo->dest->next_output_byte = md->cb; + cinfo->dest->free_in_buffer = md->cb_bytes; } /*****************************************************************************/ @@ -58,16 +56,16 @@ my_init_destination(j_compress_ptr cinfo) static int DEFAULT_CC my_empty_output_buffer(j_compress_ptr cinfo) { - struct mydata_comp* md; - int chunk_bytes; - - md = (struct mydata_comp*)(cinfo->client_data); - chunk_bytes = md->cb_bytes; - md->total_done += chunk_bytes; - cinfo->dest->next_output_byte = md->cb; - cinfo->dest->free_in_buffer = md->cb_bytes; - md->overwrite = 1; - return 1; + struct mydata_comp *md; + int chunk_bytes; + + md = (struct mydata_comp *)(cinfo->client_data); + chunk_bytes = md->cb_bytes; + md->total_done += chunk_bytes; + cinfo->dest->next_output_byte = md->cb; + cinfo->dest->free_in_buffer = md->cb_bytes; + md->overwrite = 1; + return 1; } /*****************************************************************************/ @@ -75,149 +73,158 @@ my_empty_output_buffer(j_compress_ptr cinfo) static void DEFAULT_CC my_term_destination(j_compress_ptr cinfo) { - struct mydata_comp* md; - int chunk_bytes; + struct mydata_comp *md; + int chunk_bytes; - md = (struct mydata_comp*)(cinfo->client_data); - chunk_bytes = md->cb_bytes - cinfo->dest->free_in_buffer; - md->total_done += chunk_bytes; + md = (struct mydata_comp *)(cinfo->client_data); + chunk_bytes = md->cb_bytes - cinfo->dest->free_in_buffer; + md->total_done += chunk_bytes; } /*****************************************************************************/ static int APP_CC -jp_do_compress(char* data, int width, int height, int bpp, int quality, - char* comp_data, int* comp_data_bytes) +jp_do_compress(char *data, int width, int height, int bpp, int quality, + char *comp_data, int *comp_data_bytes) { - struct jpeg_compress_struct cinfo; - struct jpeg_error_mgr jerr; - struct jpeg_destination_mgr dst_mgr; - struct mydata_comp md; - JSAMPROW row_pointer[4]; - int Bpp; - - Bpp = (bpp + 7) / 8; - memset(&cinfo, 0, sizeof(cinfo)); - cinfo.err = jpeg_std_error(&jerr); - jpeg_create_compress(&cinfo); - memset(&md, 0, sizeof(md)); - md.cb = comp_data, - md.cb_bytes = *comp_data_bytes; - cinfo.client_data = &md; - memset(&dst_mgr, 0, sizeof(dst_mgr)); - dst_mgr.init_destination = my_init_destination; - dst_mgr.empty_output_buffer = my_empty_output_buffer; - dst_mgr.term_destination = my_term_destination; - cinfo.dest = &dst_mgr; - cinfo.image_width = width; - cinfo.image_height = height; - cinfo.input_components = Bpp; - cinfo.in_color_space = JCS_RGB; - jpeg_set_defaults(&cinfo); - cinfo.num_components = 3; - cinfo.dct_method = JDCT_FLOAT; - jpeg_set_quality(&cinfo, quality, 1); - jpeg_start_compress(&cinfo, 1); - while (cinfo.next_scanline + 3 < cinfo.image_height) - { - row_pointer[0] = data; - data += width * Bpp; - row_pointer[1] = data; - data += width * Bpp; - row_pointer[2] = data; - data += width * Bpp; - row_pointer[3] = data; - data += width * Bpp; - jpeg_write_scanlines(&cinfo, row_pointer, 4); - } - while (cinfo.next_scanline < cinfo.image_height) - { - row_pointer[0] = data; - data += width * Bpp; - jpeg_write_scanlines(&cinfo, row_pointer, 1); - } - jpeg_finish_compress(&cinfo); - *comp_data_bytes = md.total_done; - jpeg_destroy_compress(&cinfo); - if (md.overwrite) - { - return 1; - } - return 0; + struct jpeg_compress_struct cinfo; + struct jpeg_error_mgr jerr; + struct jpeg_destination_mgr dst_mgr; + struct mydata_comp md; + JSAMPROW row_pointer[4]; + int Bpp; + + Bpp = (bpp + 7) / 8; + memset(&cinfo, 0, sizeof(cinfo)); + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_compress(&cinfo); + memset(&md, 0, sizeof(md)); + md.cb = comp_data, + md.cb_bytes = *comp_data_bytes; + cinfo.client_data = &md; + memset(&dst_mgr, 0, sizeof(dst_mgr)); + dst_mgr.init_destination = my_init_destination; + dst_mgr.empty_output_buffer = my_empty_output_buffer; + dst_mgr.term_destination = my_term_destination; + cinfo.dest = &dst_mgr; + cinfo.image_width = width; + cinfo.image_height = height; + cinfo.input_components = Bpp; + cinfo.in_color_space = JCS_RGB; + jpeg_set_defaults(&cinfo); + cinfo.num_components = 3; + cinfo.dct_method = JDCT_FLOAT; + jpeg_set_quality(&cinfo, quality, 1); + jpeg_start_compress(&cinfo, 1); + + while (cinfo.next_scanline + 3 < cinfo.image_height) + { + row_pointer[0] = data; + data += width * Bpp; + row_pointer[1] = data; + data += width * Bpp; + row_pointer[2] = data; + data += width * Bpp; + row_pointer[3] = data; + data += width * Bpp; + jpeg_write_scanlines(&cinfo, row_pointer, 4); + } + + while (cinfo.next_scanline < cinfo.image_height) + { + row_pointer[0] = data; + data += width * Bpp; + jpeg_write_scanlines(&cinfo, row_pointer, 1); + } + + jpeg_finish_compress(&cinfo); + *comp_data_bytes = md.total_done; + jpeg_destroy_compress(&cinfo); + + if (md.overwrite) + { + return 1; + } + + return 0; } /*****************************************************************************/ static int APP_CC -jpeg_compress(char* in_data, int width, int height, - struct stream* s, struct stream* temp_s, int bpp, +jpeg_compress(char *in_data, int width, int height, + struct stream *s, struct stream *temp_s, int bpp, int byte_limit, int e, int quality) { - char* data; - tui32* src32; - tui16* src16; - tui8* dst8; - tui32 pixel; - int red; - int blue; - int green; - int j; - int i; - int cdata_bytes; - - data = temp_s->data; - dst8 = data; - if (bpp == 24) - { - src32 = (tui32*)in_data; - for (j = 0; j < height; j++) + char *data; + tui32 *src32; + tui16 *src16; + tui8 *dst8; + tui32 pixel; + int red; + int blue; + int green; + int j; + int i; + int cdata_bytes; + + data = temp_s->data; + dst8 = data; + + if (bpp == 24) { - for (i = 0; i < width; i++) - { - pixel = src32[i + j * width]; - SPLITCOLOR32(red, green, blue, pixel); - *(dst8++)= blue; - *(dst8++)= green; - *(dst8++)= red; - } - for (i = 0; i < e; i++) - { - *(dst8++) = blue; - *(dst8++) = green; - *(dst8++) = red; - } + src32 = (tui32 *)in_data; + + for (j = 0; j < height; j++) + { + for (i = 0; i < width; i++) + { + pixel = src32[i + j * width]; + SPLITCOLOR32(red, green, blue, pixel); + *(dst8++) = blue; + *(dst8++) = green; + *(dst8++) = red; + } + + for (i = 0; i < e; i++) + { + *(dst8++) = blue; + *(dst8++) = green; + *(dst8++) = red; + } + } } - } - else - { - g_writeln("bpp wrong %d", bpp); - } - cdata_bytes = byte_limit; - jp_do_compress(data, width + e, height, 24, quality, s->p, &cdata_bytes); - s->p += cdata_bytes; - return cdata_bytes; + else + { + g_writeln("bpp wrong %d", bpp); + } + + cdata_bytes = byte_limit; + jp_do_compress(data, width + e, height, 24, quality, s->p, &cdata_bytes); + s->p += cdata_bytes; + return cdata_bytes; } /*****************************************************************************/ int APP_CC -xrdp_jpeg_compress(char* in_data, int width, int height, - struct stream* s, int bpp, int byte_limit, - int start_line, struct stream* temp_s, +xrdp_jpeg_compress(char *in_data, int width, int height, + struct stream *s, int bpp, int byte_limit, + int start_line, struct stream *temp_s, int e, int quality) { - jpeg_compress(in_data, width, height, s, temp_s, bpp, byte_limit, - e, quality); - return height; + jpeg_compress(in_data, width, height, s, temp_s, bpp, byte_limit, + e, quality); + return height; } #else /*****************************************************************************/ int APP_CC -xrdp_jpeg_compress(char* in_data, int width, int height, - struct stream* s, int bpp, int byte_limit, - int start_line, struct stream* temp_s, +xrdp_jpeg_compress(char *in_data, int width, int height, + struct stream *s, int bpp, int byte_limit, + int start_line, struct stream *temp_s, int e, int quality) { - return height; + return height; } #endif diff --git a/libxrdp/xrdp_mcs.c b/libxrdp/xrdp_mcs.c index 618a3433..a2793960 100644 --- a/libxrdp/xrdp_mcs.c +++ b/libxrdp/xrdp_mcs.c @@ -1,642 +1,721 @@ -/* - 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. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - mcs layer - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * mcs layer + */ #include "libxrdp.h" /*****************************************************************************/ -struct xrdp_mcs* APP_CC -xrdp_mcs_create(struct xrdp_sec* owner, struct trans* trans, - struct stream* client_mcs_data, - struct stream* server_mcs_data) +struct xrdp_mcs *APP_CC +xrdp_mcs_create(struct xrdp_sec *owner, struct trans *trans, + struct stream *client_mcs_data, + struct stream *server_mcs_data) { - struct xrdp_mcs* self; - - DEBUG((" in xrdp_mcs_create")); - self = (struct xrdp_mcs*)g_malloc(sizeof(struct xrdp_mcs), 1); - self->sec_layer = owner; - self->userid = 1; - self->chanid = 1001; - self->client_mcs_data = client_mcs_data; - self->server_mcs_data = server_mcs_data; - self->iso_layer = xrdp_iso_create(self, trans); - self->channel_list = list_create(); - DEBUG((" out xrdp_mcs_create")); - return self; + struct xrdp_mcs *self; + + DEBUG((" in xrdp_mcs_create")); + self = (struct xrdp_mcs *)g_malloc(sizeof(struct xrdp_mcs), 1); + self->sec_layer = owner; + self->userid = 1; + self->chanid = 1001; + self->client_mcs_data = client_mcs_data; + self->server_mcs_data = server_mcs_data; + self->iso_layer = xrdp_iso_create(self, trans); + self->channel_list = list_create(); + DEBUG((" out xrdp_mcs_create")); + return self; } /*****************************************************************************/ void APP_CC -xrdp_mcs_delete(struct xrdp_mcs* self) +xrdp_mcs_delete(struct xrdp_mcs *self) { - struct mcs_channel_item* channel_item; - int index; - int count; - - if (self == 0) - { - return; - } - /* here we have to free the channel items and anything in them */ - count = self->channel_list->count; - for (index = count - 1; index >= 0; index--) - { - channel_item = (struct mcs_channel_item*) - list_get_item(self->channel_list, index); - g_free(channel_item); - } - list_delete(self->channel_list); - xrdp_iso_delete(self->iso_layer); - /* make sure we get null pointer exception if struct is used again. */ - DEBUG(("xrdp_mcs_delete processed")) - g_memset(self,0,sizeof(struct xrdp_mcs)) ; - g_free(self); + struct mcs_channel_item *channel_item; + int index; + int count; + + if (self == 0) + { + return; + } + + /* here we have to free the channel items and anything in them */ + count = self->channel_list->count; + + for (index = count - 1; index >= 0; index--) + { + channel_item = (struct mcs_channel_item *) + list_get_item(self->channel_list, index); + g_free(channel_item); + } + + list_delete(self->channel_list); + xrdp_iso_delete(self->iso_layer); + /* make sure we get null pointer exception if struct is used again. */ + DEBUG(("xrdp_mcs_delete processed")) + g_memset(self, 0, sizeof(struct xrdp_mcs)) ; + g_free(self); } /*****************************************************************************/ /* This function sends channel join confirm*/ /* returns error = 1 ok = 0*/ static int APP_CC -xrdp_mcs_send_cjcf(struct xrdp_mcs* self, int userid, int chanid) +xrdp_mcs_send_cjcf(struct xrdp_mcs *self, int userid, int chanid) { - struct stream* s; + struct stream *s; + + DEBUG((" in xrdp_mcs_send_cjcf")); + make_stream(s); + init_stream(s, 8192); + + if (xrdp_iso_init(self->iso_layer, s) != 0) + { + free_stream(s); + DEBUG((" out xrdp_mcs_send_cjcf error")); + return 1; + } + + out_uint8(s, (MCS_CJCF << 2) | 2); + out_uint8(s, 0); + out_uint16_be(s, userid); + out_uint16_be(s, chanid); /* TODO Explain why we send this two times */ + out_uint16_be(s, chanid); + s_mark_end(s); + + if (xrdp_iso_send(self->iso_layer, s) != 0) + { + free_stream(s); + DEBUG((" out xrdp_mcs_send_cjcf error")); + return 1; + } - DEBUG((" in xrdp_mcs_send_cjcf")); - make_stream(s); - init_stream(s, 8192); - if (xrdp_iso_init(self->iso_layer, s) != 0) - { - free_stream(s); - DEBUG((" out xrdp_mcs_send_cjcf error")); - return 1; - } - out_uint8(s, (MCS_CJCF << 2) | 2); - out_uint8(s, 0); - out_uint16_be(s, userid); - out_uint16_be(s, chanid); /* TODO Explain why we send this two times */ - out_uint16_be(s, chanid); - s_mark_end(s); - if (xrdp_iso_send(self->iso_layer, s) != 0) - { free_stream(s); - DEBUG((" out xrdp_mcs_send_cjcf error")); - return 1; - } - free_stream(s); - DEBUG((" out xrdp_mcs_send_cjcf")); - return 0; + DEBUG((" out xrdp_mcs_send_cjcf")); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_mcs_recv(struct xrdp_mcs* self, struct stream* s, int* chan) +xrdp_mcs_recv(struct xrdp_mcs *self, struct stream *s, int *chan) { - int appid; - int opcode; - int len; - int userid; - int chanid; - - DEBUG((" in xrdp_mcs_recv")); - while (1) - { - if (xrdp_iso_recv(self->iso_layer, s) != 0) - { - DEBUG((" out xrdp_mcs_recv xrdp_iso_recv returned non zero")); - return 1; - } - in_uint8(s, opcode); - appid = opcode >> 2; - if (appid == MCS_DPUM) /* Disconnect Provider Ultimatum */ + int appid; + int opcode; + int len; + int userid; + int chanid; + + DEBUG((" in xrdp_mcs_recv")); + + while (1) { - g_writeln("received Disconnect Provider Ultimatum"); - DEBUG((" out xrdp_mcs_recv appid != MCS_DPUM")); - return 1; + if (xrdp_iso_recv(self->iso_layer, s) != 0) + { + DEBUG((" out xrdp_mcs_recv xrdp_iso_recv returned non zero")); + return 1; + } + + in_uint8(s, opcode); + appid = opcode >> 2; + + if (appid == MCS_DPUM) /* Disconnect Provider Ultimatum */ + { + g_writeln("received Disconnect Provider Ultimatum"); + DEBUG((" out xrdp_mcs_recv appid != MCS_DPUM")); + return 1; + } + + /* this is channels getting added from the client */ + if (appid == MCS_CJRQ) + { + g_writeln("channel join request received"); + in_uint16_be(s, userid); + in_uint16_be(s, chanid); + DEBUG(("xrdp_mcs_recv adding channel %4.4x", chanid)); + + if (xrdp_mcs_send_cjcf(self, userid, chanid) != 0) + { + g_writeln("Non handled error from xrdp_mcs_send_cjcf") ; + } + + continue; + } + + if (appid == MCS_SDRQ || appid == MCS_SDIN) + { + break ; + } + else + { + g_writeln("Recieved an unhandled appid:%d", appid); + } + + break; } - /* this is channels getting added from the client */ - if (appid == MCS_CJRQ) + + if (appid != MCS_SDRQ) { - g_writeln("channel join request received"); - in_uint16_be(s, userid); - in_uint16_be(s, chanid); - DEBUG(("xrdp_mcs_recv adding channel %4.4x", chanid)); - if(xrdp_mcs_send_cjcf(self, userid, chanid)!=0) - { - g_writeln("Non handled error from xrdp_mcs_send_cjcf") ; - } - continue; + DEBUG((" out xrdp_mcs_recv err got 0x%x need MCS_SDRQ", appid)); + return 1; } - if(appid==MCS_SDRQ || appid==MCS_SDIN) + + in_uint8s(s, 2); + in_uint16_be(s, *chan); + in_uint8s(s, 1); + in_uint8(s, len); + + if (len & 0x80) { - break ; + in_uint8s(s, 1); } - else - { - g_writeln("Recieved an unhandled appid:%d",appid); - } - break; - } - if (appid != MCS_SDRQ) - { - DEBUG((" out xrdp_mcs_recv err got 0x%x need MCS_SDRQ", appid)); - return 1; - } - in_uint8s(s, 2); - in_uint16_be(s, *chan); - in_uint8s(s, 1); - in_uint8(s, len); - if (len & 0x80) - { - in_uint8s(s, 1); - } - DEBUG((" out xrdp_mcs_recv")); - return 0; + + DEBUG((" out xrdp_mcs_recv")); + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_ber_parse_header(struct xrdp_mcs* self, struct stream* s, - int tag_val, int* len) +xrdp_mcs_ber_parse_header(struct xrdp_mcs *self, struct stream *s, + int tag_val, int *len) { - int tag; - int l; - int i; - - if (tag_val > 0xff) - { - in_uint16_be(s, tag); - } - else - { - in_uint8(s, tag); - } - if (tag != tag_val) - { - return 1; - } - in_uint8(s, l); - if (l & 0x80) - { - l = l & ~0x80; - *len = 0; - while (l > 0) - { - in_uint8(s, i); - *len = (*len << 8) | i; - l--; - } - } - else - { - *len = l; - } - if (s_check(s)) - { - return 0; - } - else - { - return 1; - } + int tag; + int l; + int i; + + if (tag_val > 0xff) + { + in_uint16_be(s, tag); + } + else + { + in_uint8(s, tag); + } + + if (tag != tag_val) + { + return 1; + } + + in_uint8(s, l); + + if (l & 0x80) + { + l = l & ~0x80; + *len = 0; + + while (l > 0) + { + in_uint8(s, i); + *len = (*len << 8) | i; + l--; + } + } + else + { + *len = l; + } + + if (s_check(s)) + { + return 0; + } + else + { + return 1; + } } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_parse_domain_params(struct xrdp_mcs* self, struct stream* s) +xrdp_mcs_parse_domain_params(struct xrdp_mcs *self, struct stream *s) { - int len; - - if (xrdp_mcs_ber_parse_header(self, s, MCS_TAG_DOMAIN_PARAMS, &len) != 0) - { - return 1; - } - in_uint8s(s, len); - if (s_check(s)) - { - return 0; - } - else - { - return 1; - } + int len; + + if (xrdp_mcs_ber_parse_header(self, s, MCS_TAG_DOMAIN_PARAMS, &len) != 0) + { + return 1; + } + + in_uint8s(s, len); + + if (s_check(s)) + { + return 0; + } + else + { + return 1; + } } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_recv_connect_initial(struct xrdp_mcs* self) +xrdp_mcs_recv_connect_initial(struct xrdp_mcs *self) { - int len; - struct stream* s; + int len; + struct stream *s; - make_stream(s); - init_stream(s, 8192); - if (xrdp_iso_recv(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - if (xrdp_mcs_ber_parse_header(self, s, MCS_CONNECT_INITIAL, &len) != 0) - { - free_stream(s); - return 1; - } - if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0) - { - free_stream(s); - return 1; - } - in_uint8s(s, len); - if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0) - { - free_stream(s); - return 1; - } - in_uint8s(s, len); - if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_BOOLEAN, &len) != 0) - { - free_stream(s); - return 1; - } - in_uint8s(s, len); - if (xrdp_mcs_parse_domain_params(self, s) != 0) - { - free_stream(s); - return 1; - } - if (xrdp_mcs_parse_domain_params(self, s) != 0) - { - free_stream(s); - return 1; - } - if (xrdp_mcs_parse_domain_params(self, s) != 0) - { - free_stream(s); - return 1; - } - if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0) - { - free_stream(s); - return 1; - } - /* make a copy of client mcs data */ - init_stream(self->client_mcs_data, len); - out_uint8a(self->client_mcs_data, s->p, len); - in_uint8s(s, len); - s_mark_end(self->client_mcs_data); - if (s_check_end(s)) - { - free_stream(s); - return 0; - } - else - { - free_stream(s); - return 1; - } + make_stream(s); + init_stream(s, 8192); + + if (xrdp_iso_recv(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + + if (xrdp_mcs_ber_parse_header(self, s, MCS_CONNECT_INITIAL, &len) != 0) + { + free_stream(s); + return 1; + } + + if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0) + { + free_stream(s); + return 1; + } + + in_uint8s(s, len); + + if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0) + { + free_stream(s); + return 1; + } + + in_uint8s(s, len); + + if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_BOOLEAN, &len) != 0) + { + free_stream(s); + return 1; + } + + in_uint8s(s, len); + + if (xrdp_mcs_parse_domain_params(self, s) != 0) + { + free_stream(s); + return 1; + } + + if (xrdp_mcs_parse_domain_params(self, s) != 0) + { + free_stream(s); + return 1; + } + + if (xrdp_mcs_parse_domain_params(self, s) != 0) + { + free_stream(s); + return 1; + } + + if (xrdp_mcs_ber_parse_header(self, s, BER_TAG_OCTET_STRING, &len) != 0) + { + free_stream(s); + return 1; + } + + /* make a copy of client mcs data */ + init_stream(self->client_mcs_data, len); + out_uint8a(self->client_mcs_data, s->p, len); + in_uint8s(s, len); + s_mark_end(self->client_mcs_data); + + if (s_check_end(s)) + { + free_stream(s); + return 0; + } + else + { + free_stream(s); + return 1; + } } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_recv_edrq(struct xrdp_mcs* self) +xrdp_mcs_recv_edrq(struct xrdp_mcs *self) { - int opcode; - struct stream* s; + int opcode; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_iso_recv(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + + in_uint8(s, opcode); + + if ((opcode >> 2) != MCS_EDRQ) + { + free_stream(s); + return 1; + } + + in_uint8s(s, 2); + in_uint8s(s, 2); + + if (opcode & 2) + { + in_uint16_be(s, self->userid); + } + + if (!(s_check_end(s))) + { + free_stream(s); + return 1; + } - make_stream(s); - init_stream(s, 8192); - if (xrdp_iso_recv(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - in_uint8(s, opcode); - if ((opcode >> 2) != MCS_EDRQ) - { - free_stream(s); - return 1; - } - in_uint8s(s, 2); - in_uint8s(s, 2); - if (opcode & 2) - { - in_uint16_be(s, self->userid); - } - if (!(s_check_end(s))) - { free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_recv_aurq(struct xrdp_mcs* self) +xrdp_mcs_recv_aurq(struct xrdp_mcs *self) { - int opcode; - struct stream* s; + int opcode; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_iso_recv(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + + in_uint8(s, opcode); + + if ((opcode >> 2) != MCS_AURQ) + { + free_stream(s); + return 1; + } + + if (opcode & 2) + { + in_uint16_be(s, self->userid); + } + + if (!(s_check_end(s))) + { + free_stream(s); + return 1; + } - make_stream(s); - init_stream(s, 8192); - if (xrdp_iso_recv(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - in_uint8(s, opcode); - if ((opcode >> 2) != MCS_AURQ) - { - free_stream(s); - return 1; - } - if (opcode & 2) - { - in_uint16_be(s, self->userid); - } - if (!(s_check_end(s))) - { free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_send_aucf(struct xrdp_mcs* self) +xrdp_mcs_send_aucf(struct xrdp_mcs *self) { - struct stream* s; + struct stream *s; + + DEBUG((" in xrdp_mcs_send_aucf")); + make_stream(s); + init_stream(s, 8192); + + if (xrdp_iso_init(self->iso_layer, s) != 0) + { + free_stream(s); + DEBUG((" out xrdp_mcs_send_aucf error")); + return 1; + } + + out_uint8(s, ((MCS_AUCF << 2) | 2)); + out_uint8s(s, 1); + out_uint16_be(s, self->userid); + s_mark_end(s); + + if (xrdp_iso_send(self->iso_layer, s) != 0) + { + free_stream(s); + DEBUG((" out xrdp_mcs_send_aucf error")); + return 1; + } - DEBUG((" in xrdp_mcs_send_aucf")); - make_stream(s); - init_stream(s, 8192); - if (xrdp_iso_init(self->iso_layer, s) != 0) - { - free_stream(s); - DEBUG((" out xrdp_mcs_send_aucf error")); - return 1; - } - out_uint8(s, ((MCS_AUCF << 2) | 2)); - out_uint8s(s, 1); - out_uint16_be(s, self->userid); - s_mark_end(s); - if (xrdp_iso_send(self->iso_layer, s) != 0) - { free_stream(s); - DEBUG((" out xrdp_mcs_send_aucf error")); - return 1; - } - free_stream(s); - DEBUG((" out xrdp_mcs_send_aucf")); - return 0; + DEBUG((" out xrdp_mcs_send_aucf")); + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_recv_cjrq(struct xrdp_mcs* self) +xrdp_mcs_recv_cjrq(struct xrdp_mcs *self) { - int opcode; - struct stream* s; + int opcode; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_iso_recv(self->iso_layer, s) != 0) + { + free_stream(s); + return 1; + } + + in_uint8(s, opcode); + + if ((opcode >> 2) != MCS_CJRQ) + { + free_stream(s); + return 1; + } + + in_uint8s(s, 4); + + if (opcode & 2) + { + in_uint8s(s, 2); + } + + if (!(s_check_end(s))) + { + free_stream(s); + return 1; + } - make_stream(s); - init_stream(s, 8192); - if (xrdp_iso_recv(self->iso_layer, s) != 0) - { - free_stream(s); - return 1; - } - in_uint8(s, opcode); - if ((opcode >> 2) != MCS_CJRQ) - { - free_stream(s); - return 1; - } - in_uint8s(s, 4); - if (opcode & 2) - { - in_uint8s(s, 2); - } - if (!(s_check_end(s))) - { free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_ber_out_header(struct xrdp_mcs* self, struct stream* s, +xrdp_mcs_ber_out_header(struct xrdp_mcs *self, struct stream *s, int tag_val, int len) { - if (tag_val > 0xff) - { - out_uint16_be(s, tag_val); - } - else - { - out_uint8(s, tag_val); - } - if (len >= 0x80) - { - out_uint8(s, 0x82); - out_uint16_be(s, len); - } - else - { - out_uint8(s, len); - } - return 0; + if (tag_val > 0xff) + { + out_uint16_be(s, tag_val); + } + else + { + out_uint8(s, tag_val); + } + + if (len >= 0x80) + { + out_uint8(s, 0x82); + out_uint16_be(s, len); + } + else + { + out_uint8(s, len); + } + + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_ber_out_int8(struct xrdp_mcs* self, struct stream* s, int value) +xrdp_mcs_ber_out_int8(struct xrdp_mcs *self, struct stream *s, int value) { - xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 1); - out_uint8(s, value); - return 0; + xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 1); + out_uint8(s, value); + return 0; } #if 0 /* not used */ /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_ber_out_int16(struct xrdp_mcs* self, struct stream* s, int value) +xrdp_mcs_ber_out_int16(struct xrdp_mcs *self, struct stream *s, int value) { - xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 2); - out_uint8(s, (value >> 8)); - out_uint8(s, value); - return 0; + xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 2); + out_uint8(s, (value >> 8)); + out_uint8(s, value); + return 0; } #endif /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_ber_out_int24(struct xrdp_mcs* self, struct stream* s, int value) +xrdp_mcs_ber_out_int24(struct xrdp_mcs *self, struct stream *s, int value) { - xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 3); - out_uint8(s, (value >> 16)); - out_uint8(s, (value >> 8)); - out_uint8(s, value); - return 0; + xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 3); + out_uint8(s, (value >> 16)); + out_uint8(s, (value >> 8)); + out_uint8(s, value); + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_out_domain_params(struct xrdp_mcs* self, struct stream* s, +xrdp_mcs_out_domain_params(struct xrdp_mcs *self, struct stream *s, int max_channels, int max_users, int max_tokens, int max_pdu_size) { - xrdp_mcs_ber_out_header(self, s, MCS_TAG_DOMAIN_PARAMS, 26); - xrdp_mcs_ber_out_int8(self, s, max_channels); - xrdp_mcs_ber_out_int8(self, s, max_users); - xrdp_mcs_ber_out_int8(self, s, max_tokens); - xrdp_mcs_ber_out_int8(self, s, 1); - xrdp_mcs_ber_out_int8(self, s, 0); - xrdp_mcs_ber_out_int8(self, s, 1); - xrdp_mcs_ber_out_int24(self, s, max_pdu_size); - xrdp_mcs_ber_out_int8(self, s, 2); - return 0; + xrdp_mcs_ber_out_header(self, s, MCS_TAG_DOMAIN_PARAMS, 26); + xrdp_mcs_ber_out_int8(self, s, max_channels); + xrdp_mcs_ber_out_int8(self, s, max_users); + xrdp_mcs_ber_out_int8(self, s, max_tokens); + xrdp_mcs_ber_out_int8(self, s, 1); + xrdp_mcs_ber_out_int8(self, s, 0); + xrdp_mcs_ber_out_int8(self, s, 1); + xrdp_mcs_ber_out_int24(self, s, max_pdu_size); + xrdp_mcs_ber_out_int8(self, s, 2); + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_mcs_send_connect_response(struct xrdp_mcs* self) +xrdp_mcs_send_connect_response(struct xrdp_mcs *self) { - int data_len; - struct stream* s; - - DEBUG((" in xrdp_mcs_send_connect_response")); - make_stream(s); - init_stream(s, 8192); - data_len = self->server_mcs_data->end - self->server_mcs_data->data; - xrdp_iso_init(self->iso_layer, s); - xrdp_mcs_ber_out_header(self, s, MCS_CONNECT_RESPONSE, data_len + 38); - xrdp_mcs_ber_out_header(self, s, BER_TAG_RESULT, 1); - out_uint8(s, 0); - xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 1); - out_uint8(s, 0); - xrdp_mcs_out_domain_params(self, s, 22, 3, 0, 0xfff8); - xrdp_mcs_ber_out_header(self, s, BER_TAG_OCTET_STRING, data_len); - /* mcs data */ - out_uint8a(s, self->server_mcs_data->data, data_len); - s_mark_end(s); - if (xrdp_iso_send(self->iso_layer, s) != 0) - { + int data_len; + struct stream *s; + + DEBUG((" in xrdp_mcs_send_connect_response")); + make_stream(s); + init_stream(s, 8192); + data_len = self->server_mcs_data->end - self->server_mcs_data->data; + xrdp_iso_init(self->iso_layer, s); + xrdp_mcs_ber_out_header(self, s, MCS_CONNECT_RESPONSE, data_len + 38); + xrdp_mcs_ber_out_header(self, s, BER_TAG_RESULT, 1); + out_uint8(s, 0); + xrdp_mcs_ber_out_header(self, s, BER_TAG_INTEGER, 1); + out_uint8(s, 0); + xrdp_mcs_out_domain_params(self, s, 22, 3, 0, 0xfff8); + xrdp_mcs_ber_out_header(self, s, BER_TAG_OCTET_STRING, data_len); + /* mcs data */ + out_uint8a(s, self->server_mcs_data->data, data_len); + s_mark_end(s); + + if (xrdp_iso_send(self->iso_layer, s) != 0) + { + free_stream(s); + DEBUG((" out xrdp_mcs_send_connect_response error")); + return 1; + } + free_stream(s); - DEBUG((" out xrdp_mcs_send_connect_response error")); - return 1; - } - free_stream(s); - DEBUG((" out xrdp_mcs_send_connect_response")); - return 0; + DEBUG((" out xrdp_mcs_send_connect_response")); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_mcs_incoming(struct xrdp_mcs* self) +xrdp_mcs_incoming(struct xrdp_mcs *self) { - DEBUG((" in xrdp_mcs_incoming")); - if (xrdp_iso_incoming(self->iso_layer) != 0) - { - return 1; - } - if (xrdp_mcs_recv_connect_initial(self) != 0) - { - return 1; - } - /* in xrdp_sec.c */ - if (xrdp_sec_process_mcs_data(self->sec_layer) != 0) - { - return 1; - } - /* in xrdp_sec.c */ - if (xrdp_sec_out_mcs_data(self->sec_layer) != 0) - { - return 1; - } - if (xrdp_mcs_send_connect_response(self) != 0) - { - return 1; - } - if (xrdp_mcs_recv_edrq(self) != 0) - { - return 1; - } - if (xrdp_mcs_recv_aurq(self) != 0) - { - return 1; - } - if (xrdp_mcs_send_aucf(self) != 0) - { - return 1; - } - if (xrdp_mcs_recv_cjrq(self) != 0) - { - return 1; - } - if (xrdp_mcs_send_cjcf(self, self->userid, - self->userid + MCS_USERCHANNEL_BASE) != 0) - { - return 1; - } - if (xrdp_mcs_recv_cjrq(self) != 0) - { - return 1; - } - if (xrdp_mcs_send_cjcf(self, self->userid, MCS_GLOBAL_CHANNEL) != 0) - { - return 1; - } - DEBUG((" out xrdp_mcs_incoming")); - return 0; + DEBUG((" in xrdp_mcs_incoming")); + + if (xrdp_iso_incoming(self->iso_layer) != 0) + { + return 1; + } + + if (xrdp_mcs_recv_connect_initial(self) != 0) + { + return 1; + } + + /* in xrdp_sec.c */ + if (xrdp_sec_process_mcs_data(self->sec_layer) != 0) + { + return 1; + } + + /* in xrdp_sec.c */ + if (xrdp_sec_out_mcs_data(self->sec_layer) != 0) + { + return 1; + } + + if (xrdp_mcs_send_connect_response(self) != 0) + { + return 1; + } + + if (xrdp_mcs_recv_edrq(self) != 0) + { + return 1; + } + + if (xrdp_mcs_recv_aurq(self) != 0) + { + return 1; + } + + if (xrdp_mcs_send_aucf(self) != 0) + { + return 1; + } + + if (xrdp_mcs_recv_cjrq(self) != 0) + { + return 1; + } + + if (xrdp_mcs_send_cjcf(self, self->userid, + self->userid + MCS_USERCHANNEL_BASE) != 0) + { + return 1; + } + + if (xrdp_mcs_recv_cjrq(self) != 0) + { + return 1; + } + + if (xrdp_mcs_send_cjcf(self, self->userid, MCS_GLOBAL_CHANNEL) != 0) + { + return 1; + } + + DEBUG((" out xrdp_mcs_incoming")); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_mcs_init(struct xrdp_mcs* self, struct stream* s) +xrdp_mcs_init(struct xrdp_mcs *self, struct stream *s) { - xrdp_iso_init(self->iso_layer, s); - s_push_layer(s, mcs_hdr, 8); - return 0; + xrdp_iso_init(self->iso_layer, s); + s_push_layer(s, mcs_hdr, 8); + return 0; } /*****************************************************************************/ @@ -644,118 +723,132 @@ xrdp_mcs_init(struct xrdp_mcs* self, struct stream* s) /* Inform the callback that an mcs packet has been sent. This is needed so the module can send any high priority mcs packets like audio. */ static int APP_CC -xrdp_mcs_call_callback(struct xrdp_mcs* self) +xrdp_mcs_call_callback(struct xrdp_mcs *self) { - int rv; - struct xrdp_session* session; + int rv; + struct xrdp_session *session; - rv = 0; - /* if there is a callback, call it here */ - session = self->sec_layer->rdp_layer->session; - if (session != 0) - { - if (session->callback != 0) + rv = 0; + /* if there is a callback, call it here */ + session = self->sec_layer->rdp_layer->session; + + if (session != 0) { - /* in xrdp_wm.c */ - rv = session->callback(session->id, 0x5556, 0, 0, 0, 0); + if (session->callback != 0) + { + /* in xrdp_wm.c */ + rv = session->callback(session->id, 0x5556, 0, 0, 0, 0); + } + else + { + g_writeln("in xrdp_mcs_send, session->callback is nil"); + } } else { - g_writeln("in xrdp_mcs_send, session->callback is nil"); + g_writeln("in xrdp_mcs_send, session is nil"); } - } - else - { - g_writeln("in xrdp_mcs_send, session is nil"); - } - return rv; + + return rv; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_mcs_send(struct xrdp_mcs* self, struct stream* s, int chan) +xrdp_mcs_send(struct xrdp_mcs *self, struct stream *s, int chan) { - int len; - char* lp; - //static int max_len = 0; - - DEBUG((" in xrdp_mcs_send")); - s_pop_layer(s, mcs_hdr); - len = (s->end - s->p) - 8; - if (len > 8192 * 2) - { - g_writeln("error in xrdp_mcs_send, size too bog, its %d", len); - } - //if (len > max_len) - //{ - // max_len = len; - // g_printf("mcs max length is %d\r\n", max_len); - //} - //g_printf("mcs length %d max length is %d\r\n", len, max_len); - //g_printf("mcs length %d\r\n", len); - out_uint8(s, MCS_SDIN << 2); - out_uint16_be(s, self->userid); - out_uint16_be(s, chan); - out_uint8(s, 0x70); - if (len >= 128) - { - len = len | 0x8000; - out_uint16_be(s, len); - } - else - { - out_uint8(s, len); - /* move everything up one byte */ - lp = s->p; - while (lp < s->end) - { - lp[0] = lp[1]; - lp++; - } - s->end--; - } - if (xrdp_iso_send(self->iso_layer, s) != 0) - { - DEBUG((" out xrdp_mcs_send error")); - return 1; - } - /* todo, do we need to call this for every mcs packet, - maybe every 5 or so */ - if (chan == MCS_GLOBAL_CHANNEL) - { - xrdp_mcs_call_callback(self); - } - DEBUG((" out xrdp_mcs_send")); - return 0; + int len; + char *lp; + //static int max_len = 0; + + DEBUG((" in xrdp_mcs_send")); + s_pop_layer(s, mcs_hdr); + len = (s->end - s->p) - 8; + + if (len > 8192 * 2) + { + g_writeln("error in xrdp_mcs_send, size too bog, its %d", len); + } + + //if (len > max_len) + //{ + // max_len = len; + // g_printf("mcs max length is %d\r\n", max_len); + //} + //g_printf("mcs length %d max length is %d\r\n", len, max_len); + //g_printf("mcs length %d\r\n", len); + out_uint8(s, MCS_SDIN << 2); + out_uint16_be(s, self->userid); + out_uint16_be(s, chan); + out_uint8(s, 0x70); + + if (len >= 128) + { + len = len | 0x8000; + out_uint16_be(s, len); + } + else + { + out_uint8(s, len); + /* move everything up one byte */ + lp = s->p; + + while (lp < s->end) + { + lp[0] = lp[1]; + lp++; + } + + s->end--; + } + + if (xrdp_iso_send(self->iso_layer, s) != 0) + { + DEBUG((" out xrdp_mcs_send error")); + return 1; + } + + /* todo, do we need to call this for every mcs packet, + maybe every 5 or so */ + if (chan == MCS_GLOBAL_CHANNEL) + { + xrdp_mcs_call_callback(self); + } + + DEBUG((" out xrdp_mcs_send")); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_mcs_disconnect(struct xrdp_mcs* self) +xrdp_mcs_disconnect(struct xrdp_mcs *self) { - struct stream* s; + struct stream *s; + + DEBUG((" in xrdp_mcs_disconnect")); + make_stream(s); + init_stream(s, 8192); + + if (xrdp_iso_init(self->iso_layer, s) != 0) + { + free_stream(s); + DEBUG((" out xrdp_mcs_disconnect error")); + return 1; + } + + out_uint8(s, (MCS_DPUM << 2) | 1); + out_uint8(s, 0x80); + s_mark_end(s); + + if (xrdp_iso_send(self->iso_layer, s) != 0) + { + free_stream(s); + DEBUG((" out xrdp_mcs_disconnect error")); + return 1; + } - DEBUG((" in xrdp_mcs_disconnect")); - make_stream(s); - init_stream(s, 8192); - if (xrdp_iso_init(self->iso_layer, s) != 0) - { - free_stream(s); - DEBUG((" out xrdp_mcs_disconnect error")); - return 1; - } - out_uint8(s, (MCS_DPUM << 2) | 1); - out_uint8(s, 0x80); - s_mark_end(s); - if (xrdp_iso_send(self->iso_layer, s) != 0) - { free_stream(s); - DEBUG((" out xrdp_mcs_disconnect error")); - return 1; - } - free_stream(s); - DEBUG((" out xrdp_mcs_disconnect")); - return 0; + DEBUG((" out xrdp_mcs_disconnect")); + return 0; } diff --git a/libxrdp/xrdp_orders.c b/libxrdp/xrdp_orders.c index e7739e3e..438151da 100644 --- a/libxrdp/xrdp_orders.c +++ b/libxrdp/xrdp_orders.c @@ -1,24 +1,22 @@ -/* - 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. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - orders - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * orders + */ #include "libxrdp.h" @@ -28,138 +26,151 @@ #define LLOG_LEVEL 2 #define LLOGLN(_log_level, _params) \ -{ \ - if (_log_level < LLOG_LEVEL) \ - { \ - g_write("xrdp_orders.c [%10.10u]: ", g_time3()); \ - g_writeln _params ; \ - } \ -} + { \ + if (_log_level < LLOG_LEVEL) \ + { \ + g_write("xrdp_orders.c [%10.10u]: ", g_time3()); \ + g_writeln _params ; \ + } \ + } /*****************************************************************************/ -struct xrdp_orders* APP_CC -xrdp_orders_create(struct xrdp_session* session, struct xrdp_rdp* rdp_layer) +struct xrdp_orders *APP_CC +xrdp_orders_create(struct xrdp_session *session, struct xrdp_rdp *rdp_layer) { - struct xrdp_orders* self; - - self = (struct xrdp_orders*)g_malloc(sizeof(struct xrdp_orders), 1); - self->session = session; - self->rdp_layer = rdp_layer; - make_stream(self->out_s); - init_stream(self->out_s, 16384); - self->orders_state.clip_right = 1; /* silly rdp right clip */ - self->orders_state.clip_bottom = 1; /* silly rdp bottom clip */ - return self; + struct xrdp_orders *self; + + self = (struct xrdp_orders *)g_malloc(sizeof(struct xrdp_orders), 1); + self->session = session; + self->rdp_layer = rdp_layer; + make_stream(self->out_s); + init_stream(self->out_s, 16384); + self->orders_state.clip_right = 1; /* silly rdp right clip */ + self->orders_state.clip_bottom = 1; /* silly rdp bottom clip */ + return self; } /*****************************************************************************/ void APP_CC -xrdp_orders_delete(struct xrdp_orders* self) +xrdp_orders_delete(struct xrdp_orders *self) { - if (self == 0) - { - return; - } - free_stream(self->out_s); - g_free(self->orders_state.text_data); - g_free(self); + if (self == 0) + { + return; + } + + free_stream(self->out_s); + g_free(self->orders_state.text_data); + g_free(self); } /*****************************************************************************/ /* set all values to zero */ /* returns error */ int APP_CC -xrdp_orders_reset(struct xrdp_orders* self) +xrdp_orders_reset(struct xrdp_orders *self) { - if (xrdp_orders_force_send(self) != 0) - { - return 1; - } - g_free(self->orders_state.text_data); - g_memset(&(self->orders_state), 0, sizeof(self->orders_state)); - self->order_count_ptr = 0; - self->order_count = 0; - self->order_level = 0; - self->orders_state.clip_right = 1; /* silly rdp right clip */ - self->orders_state.clip_bottom = 1; /* silly rdp bottom clip */ - return 0; + if (xrdp_orders_force_send(self) != 0) + { + return 1; + } + + g_free(self->orders_state.text_data); + g_memset(&(self->orders_state), 0, sizeof(self->orders_state)); + self->order_count_ptr = 0; + self->order_count = 0; + self->order_level = 0; + self->orders_state.clip_right = 1; /* silly rdp right clip */ + self->orders_state.clip_bottom = 1; /* silly rdp bottom clip */ + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_orders_init(struct xrdp_orders* self) +xrdp_orders_init(struct xrdp_orders *self) { - self->order_level++; - if (self->order_level == 1) - { - self->order_count = 0; - /* is this big enough */ - if (xrdp_rdp_init_data(self->rdp_layer, self->out_s) != 0) - { - return 1; - } - out_uint16_le(self->out_s, RDP_UPDATE_ORDERS); - out_uint8s(self->out_s, 2); /* pad */ - self->order_count_ptr = self->out_s->p; - out_uint8s(self->out_s, 2); /* number of orders, set later */ - out_uint8s(self->out_s, 2); /* pad */ - } - return 0; + self->order_level++; + + if (self->order_level == 1) + { + self->order_count = 0; + + /* is this big enough */ + if (xrdp_rdp_init_data(self->rdp_layer, self->out_s) != 0) + { + return 1; + } + + out_uint16_le(self->out_s, RDP_UPDATE_ORDERS); + out_uint8s(self->out_s, 2); /* pad */ + self->order_count_ptr = self->out_s->p; + out_uint8s(self->out_s, 2); /* number of orders, set later */ + out_uint8s(self->out_s, 2); /* pad */ + } + + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_orders_send(struct xrdp_orders* self) +xrdp_orders_send(struct xrdp_orders *self) { - int rv; - - rv = 0; - if (self->order_level > 0) - { - self->order_level--; - if ((self->order_level == 0) && (self->order_count > 0)) - { - s_mark_end(self->out_s); - DEBUG(("xrdp_orders_send sending %d orders", self->order_count)); - self->order_count_ptr[0] = self->order_count; - self->order_count_ptr[1] = self->order_count >> 8; - self->order_count = 0; - if (xrdp_rdp_send_data(self->rdp_layer, self->out_s, - RDP_DATA_PDU_UPDATE) != 0) - { - rv = 1; - } - } - } - return rv; + int rv; + + rv = 0; + + if (self->order_level > 0) + { + self->order_level--; + + if ((self->order_level == 0) && (self->order_count > 0)) + { + s_mark_end(self->out_s); + DEBUG(("xrdp_orders_send sending %d orders", self->order_count)); + self->order_count_ptr[0] = self->order_count; + self->order_count_ptr[1] = self->order_count >> 8; + self->order_count = 0; + + if (xrdp_rdp_send_data(self->rdp_layer, self->out_s, + RDP_DATA_PDU_UPDATE) != 0) + { + rv = 1; + } + } + } + + return rv; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_orders_force_send(struct xrdp_orders* self) +xrdp_orders_force_send(struct xrdp_orders *self) { - if (self == 0) - { - return 1; - } - if ((self->order_level > 0) && (self->order_count > 0)) - { - s_mark_end(self->out_s); - DEBUG(("xrdp_orders_force_send sending %d orders", self->order_count)); - self->order_count_ptr[0] = self->order_count; - self->order_count_ptr[1] = self->order_count >> 8; - if (xrdp_rdp_send_data(self->rdp_layer, self->out_s, - RDP_DATA_PDU_UPDATE) != 0) - { - return 1; - } - } - self->order_count = 0; - self->order_level = 0; - return 0; + if (self == 0) + { + return 1; + } + + if ((self->order_level > 0) && (self->order_count > 0)) + { + s_mark_end(self->out_s); + DEBUG(("xrdp_orders_force_send sending %d orders", self->order_count)); + self->order_count_ptr[0] = self->order_count; + self->order_count_ptr[1] = self->order_count >> 8; + + if (xrdp_rdp_send_data(self->rdp_layer, self->out_s, + RDP_DATA_PDU_UPDATE) != 0) + { + return 1; + } + } + + self->order_count = 0; + self->order_level = 0; + return 0; } /*****************************************************************************/ @@ -167,232 +178,258 @@ xrdp_orders_force_send(struct xrdp_orders* self) /* send what we got and init a new one */ /* returns error */ int APP_CC -xrdp_orders_check(struct xrdp_orders* self, int max_size) +xrdp_orders_check(struct xrdp_orders *self, int max_size) { - int size; - int max_packet_size; - - if (self->rdp_layer->client_info.bpp == 8) - { - max_packet_size = 8000; - } - else - { - max_packet_size = 16000; - } - if (self->order_level < 1) - { - if (max_size > max_packet_size) - { - return 1; + int size; + int max_packet_size; + + if (self->rdp_layer->client_info.bpp == 8) + { + max_packet_size = 8000; } else { - return 0; + max_packet_size = 16000; } - } - size = (int)(self->out_s->p - self->order_count_ptr); - if ((size < 0) || (size > max_packet_size)) - { - return 1; - } - if ((size + max_size + 100) > max_packet_size) - { - xrdp_orders_force_send(self); - xrdp_orders_init(self); - } - return 0; + + if (self->order_level < 1) + { + if (max_size > max_packet_size) + { + return 1; + } + else + { + return 0; + } + } + + size = (int)(self->out_s->p - self->order_count_ptr); + + if ((size < 0) || (size > max_packet_size)) + { + return 1; + } + + if ((size + max_size + 100) > max_packet_size) + { + xrdp_orders_force_send(self); + xrdp_orders_init(self); + } + + return 0; } /*****************************************************************************/ /* check if rect is the same as the last one sent */ /* returns boolean */ static int APP_CC -xrdp_orders_last_bounds(struct xrdp_orders* self, struct xrdp_rect* rect) +xrdp_orders_last_bounds(struct xrdp_orders *self, struct xrdp_rect *rect) { - if (rect == 0) - { + if (rect == 0) + { + return 0; + } + + if ((rect->left == self->orders_state.clip_left) && + (rect->top == self->orders_state.clip_top) && + (rect->right == self->orders_state.clip_right) && + (rect->bottom == self->orders_state.clip_bottom)) + { + return 1; + } + return 0; - } - if ((rect->left == self->orders_state.clip_left) && - (rect->top == self->orders_state.clip_top) && - (rect->right == self->orders_state.clip_right) && - (rect->bottom == self->orders_state.clip_bottom)) - { - return 1; - } - return 0; } /*****************************************************************************/ /* check if all coords are withing 256 bytes */ /* returns boolean */ static int APP_CC -xrdp_orders_send_delta(struct xrdp_orders* self, int* vals, int count) +xrdp_orders_send_delta(struct xrdp_orders *self, int *vals, int count) { - int i; + int i; - for (i = 0; i < count; i += 2) - { - if (g_abs(vals[i] - vals[i + 1]) >= 128) + for (i = 0; i < count; i += 2) { - return 0; + if (g_abs(vals[i] - vals[i + 1]) >= 128) + { + return 0; + } } - } - return 1; + + return 1; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_orders_out_bounds(struct xrdp_orders* self, struct xrdp_rect* rect) +xrdp_orders_out_bounds(struct xrdp_orders *self, struct xrdp_rect *rect) { - char* bounds_flags_ptr; - int bounds_flags; - - bounds_flags = 0; - bounds_flags_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - /* left */ - if (rect->left == self->orders_state.clip_left) - { - } - else if (g_abs(rect->left - self->orders_state.clip_left) < 128) - { - bounds_flags |= 0x10; - } - else - { - bounds_flags |= 0x01; - } - /* top */ - if (rect->top == self->orders_state.clip_top) - { - } - else if (g_abs(rect->top - self->orders_state.clip_top) < 128) - { - bounds_flags |= 0x20; - } - else - { - bounds_flags |= 0x02; - } - /* right */ - if (rect->right == self->orders_state.clip_right) - { - } - else if (g_abs(rect->right - self->orders_state.clip_right) < 128) - { - bounds_flags |= 0x40; - } - else - { - bounds_flags |= 0x04; - } - /* bottom */ - if (rect->bottom == self->orders_state.clip_bottom) - { - } - else if (g_abs(rect->bottom - self->orders_state.clip_bottom) < 128) - { - bounds_flags |= 0x80; - } - else - { - bounds_flags |= 0x08; - } - /* left */ - if (bounds_flags & 0x01) - { - out_uint16_le(self->out_s, rect->left); - } - else if (bounds_flags & 0x10) - { - out_uint8(self->out_s, rect->left - self->orders_state.clip_left); - } - self->orders_state.clip_left = rect->left; - /* top */ - if (bounds_flags & 0x02) - { - out_uint16_le(self->out_s, rect->top); - } - else if (bounds_flags & 0x20) - { - out_uint8(self->out_s, rect->top - self->orders_state.clip_top); - } - self->orders_state.clip_top = rect->top; - /* right */ - if (bounds_flags & 0x04) - { - out_uint16_le(self->out_s, rect->right - 1); /* silly rdp right clip */ - } - else if (bounds_flags & 0x40) - { - out_uint8(self->out_s, rect->right - self->orders_state.clip_right); - } - self->orders_state.clip_right = rect->right; - /* bottom */ - if (bounds_flags & 0x08) - { - out_uint16_le(self->out_s, rect->bottom - 1); /* silly rdp bottom clip */ - } - else if (bounds_flags & 0x80) - { - out_uint8(self->out_s, rect->bottom - self->orders_state.clip_bottom); - } - self->orders_state.clip_bottom = rect->bottom; - /* set flags */ - *bounds_flags_ptr = bounds_flags; - return 0; + char *bounds_flags_ptr; + int bounds_flags; + + bounds_flags = 0; + bounds_flags_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + /* left */ + if (rect->left == self->orders_state.clip_left) + { + } + else if (g_abs(rect->left - self->orders_state.clip_left) < 128) + { + bounds_flags |= 0x10; + } + else + { + bounds_flags |= 0x01; + } + + /* top */ + if (rect->top == self->orders_state.clip_top) + { + } + else if (g_abs(rect->top - self->orders_state.clip_top) < 128) + { + bounds_flags |= 0x20; + } + else + { + bounds_flags |= 0x02; + } + + /* right */ + if (rect->right == self->orders_state.clip_right) + { + } + else if (g_abs(rect->right - self->orders_state.clip_right) < 128) + { + bounds_flags |= 0x40; + } + else + { + bounds_flags |= 0x04; + } + + /* bottom */ + if (rect->bottom == self->orders_state.clip_bottom) + { + } + else if (g_abs(rect->bottom - self->orders_state.clip_bottom) < 128) + { + bounds_flags |= 0x80; + } + else + { + bounds_flags |= 0x08; + } + + /* left */ + if (bounds_flags & 0x01) + { + out_uint16_le(self->out_s, rect->left); + } + else if (bounds_flags & 0x10) + { + out_uint8(self->out_s, rect->left - self->orders_state.clip_left); + } + + self->orders_state.clip_left = rect->left; + + /* top */ + if (bounds_flags & 0x02) + { + out_uint16_le(self->out_s, rect->top); + } + else if (bounds_flags & 0x20) + { + out_uint8(self->out_s, rect->top - self->orders_state.clip_top); + } + + self->orders_state.clip_top = rect->top; + + /* right */ + if (bounds_flags & 0x04) + { + out_uint16_le(self->out_s, rect->right - 1); /* silly rdp right clip */ + } + else if (bounds_flags & 0x40) + { + out_uint8(self->out_s, rect->right - self->orders_state.clip_right); + } + + self->orders_state.clip_right = rect->right; + + /* bottom */ + if (bounds_flags & 0x08) + { + out_uint16_le(self->out_s, rect->bottom - 1); /* silly rdp bottom clip */ + } + else if (bounds_flags & 0x80) + { + out_uint8(self->out_s, rect->bottom - self->orders_state.clip_bottom); + } + + self->orders_state.clip_bottom = rect->bottom; + /* set flags */ + *bounds_flags_ptr = bounds_flags; + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_order_pack_small_or_tiny(struct xrdp_orders* self, - char* order_flags_ptr, int orders_flags, - char* present_ptr, int present, +xrdp_order_pack_small_or_tiny(struct xrdp_orders *self, + char *order_flags_ptr, int orders_flags, + char *present_ptr, int present, int present_size) { - int move_up_count = 0; - int index = 0; - int size = 0; - int keep_looking = 1; - - move_up_count = 0; - keep_looking = 1; - for (index = present_size - 1; index >= 0; index--) - { - if (keep_looking) - { - if (((present >> (index * 8)) & 0xff) == 0) - { - move_up_count++; - } - else - { - keep_looking = 0; - } - } - present_ptr[index] = present >> (index * 8); - } - if (move_up_count > 0) - { - /* move_up_count should be 0, 1, 2, or 3 - shifting it 6 will make it RDP_ORDER_TINY(0x80) or - RDP_ORDER_SMALL(0x40) or both */ - orders_flags |= move_up_count << 6; - size = (int)(self->out_s->p - present_ptr); - size -= present_size; - for (index = 0; index < size; index++) - { - present_ptr[index + (present_size - move_up_count)] = - present_ptr[index + present_size]; - } - self->out_s->p -= move_up_count; - } - order_flags_ptr[0] = orders_flags; - return 0; + int move_up_count = 0; + int index = 0; + int size = 0; + int keep_looking = 1; + + move_up_count = 0; + keep_looking = 1; + + for (index = present_size - 1; index >= 0; index--) + { + if (keep_looking) + { + if (((present >> (index * 8)) & 0xff) == 0) + { + move_up_count++; + } + else + { + keep_looking = 0; + } + } + + present_ptr[index] = present >> (index * 8); + } + + if (move_up_count > 0) + { + /* move_up_count should be 0, 1, 2, or 3 + shifting it 6 will make it RDP_ORDER_TINY(0x80) or + RDP_ORDER_SMALL(0x40) or both */ + orders_flags |= move_up_count << 6; + size = (int)(self->out_s->p - present_ptr); + size -= present_size; + + for (index = 0; index < size; index++) + { + present_ptr[index + (present_size - move_up_count)] = + present_ptr[index + present_size]; + } + + self->out_s->p -= move_up_count; + } + + order_flags_ptr[0] = orders_flags; + return 0; } /*****************************************************************************/ @@ -400,140 +437,166 @@ xrdp_order_pack_small_or_tiny(struct xrdp_orders* self, /* send a solid rect to client */ /* max size 23 */ int APP_CC -xrdp_orders_rect(struct xrdp_orders* self, int x, int y, int cx, int cy, - int color, struct xrdp_rect* rect) +xrdp_orders_rect(struct xrdp_orders *self, int x, int y, int cx, int cy, + int color, struct xrdp_rect *rect) { - int order_flags; - int vals[8]; - int present; - char* present_ptr; - char* order_flags_ptr; - - xrdp_orders_check(self, 23); - self->order_count++; - order_flags = RDP_ORDER_STANDARD; - if (self->orders_state.last_order != RDP_ORDER_RECT) - { - order_flags |= RDP_ORDER_CHANGE; - } - self->orders_state.last_order = RDP_ORDER_RECT; - if (rect != 0) - { - /* if clip is present, still check if its needed */ - if (x < rect->left || y < rect->top || - x + cx > rect->right || y + cy > rect->bottom) - { - order_flags |= RDP_ORDER_BOUNDS; - if (xrdp_orders_last_bounds(self, rect)) - { - order_flags |= RDP_ORDER_LASTBOUNDS; - } - } - } - vals[0] = x; - vals[1] = self->orders_state.rect_x; - vals[2] = y; - vals[3] = self->orders_state.rect_y; - vals[4] = cx; - vals[5] = self->orders_state.rect_cx; - vals[6] = cy; - vals[7] = self->orders_state.rect_cy; - if (xrdp_orders_send_delta(self, vals, 8)) - { - order_flags |= RDP_ORDER_DELTA; - } - /* order_flags, set later, 1 byte */ - order_flags_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if (order_flags & RDP_ORDER_CHANGE) - { - out_uint8(self->out_s, self->orders_state.last_order); - } - present = 0; - /* present, set later, 1 byte */ - present_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if ((order_flags & RDP_ORDER_BOUNDS) && - !(order_flags & RDP_ORDER_LASTBOUNDS)) - { - xrdp_orders_out_bounds(self, rect); - } - if (x != self->orders_state.rect_x) - { - present |= 0x01; - if (order_flags & RDP_ORDER_DELTA) - { - out_uint8(self->out_s, x - self->orders_state.rect_x); + int order_flags; + int vals[8]; + int present; + char *present_ptr; + char *order_flags_ptr; + + xrdp_orders_check(self, 23); + self->order_count++; + order_flags = RDP_ORDER_STANDARD; + + if (self->orders_state.last_order != RDP_ORDER_RECT) + { + order_flags |= RDP_ORDER_CHANGE; } - else + + self->orders_state.last_order = RDP_ORDER_RECT; + + if (rect != 0) { - out_uint16_le(self->out_s, x); + /* if clip is present, still check if its needed */ + if (x < rect->left || y < rect->top || + x + cx > rect->right || y + cy > rect->bottom) + { + order_flags |= RDP_ORDER_BOUNDS; + + if (xrdp_orders_last_bounds(self, rect)) + { + order_flags |= RDP_ORDER_LASTBOUNDS; + } + } } - self->orders_state.rect_x = x; - } - if (y != self->orders_state.rect_y) - { - present |= 0x02; - if (order_flags & RDP_ORDER_DELTA) + + vals[0] = x; + vals[1] = self->orders_state.rect_x; + vals[2] = y; + vals[3] = self->orders_state.rect_y; + vals[4] = cx; + vals[5] = self->orders_state.rect_cx; + vals[6] = cy; + vals[7] = self->orders_state.rect_cy; + + if (xrdp_orders_send_delta(self, vals, 8)) { - out_uint8(self->out_s, y - self->orders_state.rect_y); + order_flags |= RDP_ORDER_DELTA; } - else + + /* order_flags, set later, 1 byte */ + order_flags_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if (order_flags & RDP_ORDER_CHANGE) { - out_uint16_le(self->out_s, y); + out_uint8(self->out_s, self->orders_state.last_order); } - self->orders_state.rect_y = y; - } - if (cx != self->orders_state.rect_cx) - { - present |= 0x04; - if (order_flags & RDP_ORDER_DELTA) + + present = 0; + /* present, set later, 1 byte */ + present_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if ((order_flags & RDP_ORDER_BOUNDS) && + !(order_flags & RDP_ORDER_LASTBOUNDS)) { - out_uint8(self->out_s, cx - self->orders_state.rect_cx); + xrdp_orders_out_bounds(self, rect); } - else + + if (x != self->orders_state.rect_x) { - out_uint16_le(self->out_s, cx); + present |= 0x01; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, x - self->orders_state.rect_x); + } + else + { + out_uint16_le(self->out_s, x); + } + + self->orders_state.rect_x = x; } - self->orders_state.rect_cx = cx; - } - if (cy != self->orders_state.rect_cy) - { - present |= 0x08; - if (order_flags & RDP_ORDER_DELTA) + + if (y != self->orders_state.rect_y) { - out_uint8(self->out_s, cy - self->orders_state.rect_cy); + present |= 0x02; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, y - self->orders_state.rect_y); + } + else + { + out_uint16_le(self->out_s, y); + } + + self->orders_state.rect_y = y; } - else + + if (cx != self->orders_state.rect_cx) + { + present |= 0x04; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cx - self->orders_state.rect_cx); + } + else + { + out_uint16_le(self->out_s, cx); + } + + self->orders_state.rect_cx = cx; + } + + if (cy != self->orders_state.rect_cy) + { + present |= 0x08; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cy - self->orders_state.rect_cy); + } + else + { + out_uint16_le(self->out_s, cy); + } + + self->orders_state.rect_cy = cy; + } + + if ((color & 0xff) != (self->orders_state.rect_color & 0xff)) + { + present |= 0x10; + self->orders_state.rect_color = + (self->orders_state.rect_color & 0xffff00) | (color & 0xff); + out_uint8(self->out_s, color); + } + + if ((color & 0xff00) != (self->orders_state.rect_color & 0xff00)) { - out_uint16_le(self->out_s, cy); - } - self->orders_state.rect_cy = cy; - } - if ((color & 0xff) != (self->orders_state.rect_color & 0xff)) - { - present |= 0x10; - self->orders_state.rect_color = - (self->orders_state.rect_color & 0xffff00) | (color & 0xff); - out_uint8(self->out_s, color); - } - if ((color & 0xff00) != (self->orders_state.rect_color & 0xff00)) - { - present |= 0x20; - self->orders_state.rect_color = - (self->orders_state.rect_color & 0xff00ff) | (color & 0xff00); - out_uint8(self->out_s, color >> 8); - } - if ((color & 0xff0000) != (self->orders_state.rect_color & 0xff0000)) - { - present |= 0x40; - self->orders_state.rect_color = - (self->orders_state.rect_color & 0x00ffff) | (color & 0xff0000); - out_uint8(self->out_s, color >> 16); - } - xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, - present_ptr, present, 1); - return 0; + present |= 0x20; + self->orders_state.rect_color = + (self->orders_state.rect_color & 0xff00ff) | (color & 0xff00); + out_uint8(self->out_s, color >> 8); + } + + if ((color & 0xff0000) != (self->orders_state.rect_color & 0xff0000)) + { + present |= 0x40; + self->orders_state.rect_color = + (self->orders_state.rect_color & 0x00ffff) | (color & 0xff0000); + out_uint8(self->out_s, color >> 16); + } + + xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, + present_ptr, present, 1); + return 0; } /*****************************************************************************/ @@ -541,156 +604,186 @@ xrdp_orders_rect(struct xrdp_orders* self, int x, int y, int cx, int cy, /* send a screen blt order */ /* max size 25 */ int APP_CC -xrdp_orders_screen_blt(struct xrdp_orders* self, int x, int y, +xrdp_orders_screen_blt(struct xrdp_orders *self, int x, int y, int cx, int cy, int srcx, int srcy, - int rop, struct xrdp_rect* rect) + int rop, struct xrdp_rect *rect) { - int order_flags = 0; - int vals[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int present = 0; - char* present_ptr = (char *)NULL; - char* order_flags_ptr = (char *)NULL; - - xrdp_orders_check(self, 25); - self->order_count++; - order_flags = RDP_ORDER_STANDARD; - if (self->orders_state.last_order != RDP_ORDER_SCREENBLT) - { - order_flags |= RDP_ORDER_CHANGE; - } - self->orders_state.last_order = RDP_ORDER_SCREENBLT; - if (rect != 0) - { - /* if clip is present, still check if its needed */ - if (x < rect->left || y < rect->top || - x + cx > rect->right || y + cy > rect->bottom) - { - order_flags |= RDP_ORDER_BOUNDS; - if (xrdp_orders_last_bounds(self, rect)) - { - order_flags |= RDP_ORDER_LASTBOUNDS; - } - } - } - vals[0] = x; - vals[1] = self->orders_state.scr_blt_x; - vals[2] = y; - vals[3] = self->orders_state.scr_blt_y; - vals[4] = cx; - vals[5] = self->orders_state.scr_blt_cx; - vals[6] = cy; - vals[7] = self->orders_state.scr_blt_cy; - vals[8] = srcx; - vals[9] = self->orders_state.scr_blt_srcx; - vals[10] = srcy; - vals[11] = self->orders_state.scr_blt_srcy; - if (xrdp_orders_send_delta(self, vals, 12)) - { - order_flags |= RDP_ORDER_DELTA; - } - /* order_flags, set later, 1 byte */ - order_flags_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if (order_flags & RDP_ORDER_CHANGE) - { - out_uint8(self->out_s, self->orders_state.last_order); - } - present = 0; - /* present, set later, 1 byte */ - present_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if ((order_flags & RDP_ORDER_BOUNDS) && - !(order_flags & RDP_ORDER_LASTBOUNDS)) - { - xrdp_orders_out_bounds(self, rect); - } - if (x != self->orders_state.scr_blt_x) - { - present |= 0x01; - if (order_flags & RDP_ORDER_DELTA) - { - out_uint8(self->out_s, x - self->orders_state.scr_blt_x); + int order_flags = 0; + int vals[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int present = 0; + char *present_ptr = (char *)NULL; + char *order_flags_ptr = (char *)NULL; + + xrdp_orders_check(self, 25); + self->order_count++; + order_flags = RDP_ORDER_STANDARD; + + if (self->orders_state.last_order != RDP_ORDER_SCREENBLT) + { + order_flags |= RDP_ORDER_CHANGE; } - else + + self->orders_state.last_order = RDP_ORDER_SCREENBLT; + + if (rect != 0) { - out_uint16_le(self->out_s, x); + /* if clip is present, still check if its needed */ + if (x < rect->left || y < rect->top || + x + cx > rect->right || y + cy > rect->bottom) + { + order_flags |= RDP_ORDER_BOUNDS; + + if (xrdp_orders_last_bounds(self, rect)) + { + order_flags |= RDP_ORDER_LASTBOUNDS; + } + } } - self->orders_state.scr_blt_x = x; - } - if (y != self->orders_state.scr_blt_y) - { - present |= 0x02; - if (order_flags & RDP_ORDER_DELTA) + + vals[0] = x; + vals[1] = self->orders_state.scr_blt_x; + vals[2] = y; + vals[3] = self->orders_state.scr_blt_y; + vals[4] = cx; + vals[5] = self->orders_state.scr_blt_cx; + vals[6] = cy; + vals[7] = self->orders_state.scr_blt_cy; + vals[8] = srcx; + vals[9] = self->orders_state.scr_blt_srcx; + vals[10] = srcy; + vals[11] = self->orders_state.scr_blt_srcy; + + if (xrdp_orders_send_delta(self, vals, 12)) { - out_uint8(self->out_s, y - self->orders_state.scr_blt_y); + order_flags |= RDP_ORDER_DELTA; } - else + + /* order_flags, set later, 1 byte */ + order_flags_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if (order_flags & RDP_ORDER_CHANGE) { - out_uint16_le(self->out_s, y); + out_uint8(self->out_s, self->orders_state.last_order); } - self->orders_state.scr_blt_y = y; - } - if (cx != self->orders_state.scr_blt_cx) - { - present |= 0x04; - if (order_flags & RDP_ORDER_DELTA) + + present = 0; + /* present, set later, 1 byte */ + present_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if ((order_flags & RDP_ORDER_BOUNDS) && + !(order_flags & RDP_ORDER_LASTBOUNDS)) { - out_uint8(self->out_s, cx - self->orders_state.scr_blt_cx); + xrdp_orders_out_bounds(self, rect); } - else + + if (x != self->orders_state.scr_blt_x) { - out_uint16_le(self->out_s, cx); + present |= 0x01; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, x - self->orders_state.scr_blt_x); + } + else + { + out_uint16_le(self->out_s, x); + } + + self->orders_state.scr_blt_x = x; } - self->orders_state.scr_blt_cx = cx; - } - if (cy != self->orders_state.scr_blt_cy) - { - present |= 0x08; - if (order_flags & RDP_ORDER_DELTA) + + if (y != self->orders_state.scr_blt_y) { - out_uint8(self->out_s, cy - self->orders_state.scr_blt_cy); + present |= 0x02; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, y - self->orders_state.scr_blt_y); + } + else + { + out_uint16_le(self->out_s, y); + } + + self->orders_state.scr_blt_y = y; } - else + + if (cx != self->orders_state.scr_blt_cx) { - out_uint16_le(self->out_s, cy); + present |= 0x04; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cx - self->orders_state.scr_blt_cx); + } + else + { + out_uint16_le(self->out_s, cx); + } + + self->orders_state.scr_blt_cx = cx; } - self->orders_state.scr_blt_cy = cy; - } - if (rop != self->orders_state.scr_blt_rop) - { - present |= 0x10; - out_uint8(self->out_s, rop); - self->orders_state.scr_blt_rop = rop; - } - if (srcx != self->orders_state.scr_blt_srcx) - { - present |= 0x20; - if (order_flags & RDP_ORDER_DELTA) + + if (cy != self->orders_state.scr_blt_cy) { - out_uint8(self->out_s, srcx - self->orders_state.scr_blt_srcx); + present |= 0x08; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cy - self->orders_state.scr_blt_cy); + } + else + { + out_uint16_le(self->out_s, cy); + } + + self->orders_state.scr_blt_cy = cy; } - else + + if (rop != self->orders_state.scr_blt_rop) { - out_uint16_le(self->out_s, srcx); + present |= 0x10; + out_uint8(self->out_s, rop); + self->orders_state.scr_blt_rop = rop; } - self->orders_state.scr_blt_srcx = srcx; - } - if (srcy != self->orders_state.scr_blt_srcy) - { - present |= 0x40; - if (order_flags & RDP_ORDER_DELTA) + + if (srcx != self->orders_state.scr_blt_srcx) { - out_uint8(self->out_s, srcy - self->orders_state.scr_blt_srcy); + present |= 0x20; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, srcx - self->orders_state.scr_blt_srcx); + } + else + { + out_uint16_le(self->out_s, srcx); + } + + self->orders_state.scr_blt_srcx = srcx; } - else + + if (srcy != self->orders_state.scr_blt_srcy) { - out_uint16_le(self->out_s, srcy); + present |= 0x40; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, srcy - self->orders_state.scr_blt_srcy); + } + else + { + out_uint16_le(self->out_s, srcy); + } + + self->orders_state.scr_blt_srcy = srcy; } - self->orders_state.scr_blt_srcy = srcy; - } - xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, - present_ptr, present, 1); - return 0; + + xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, + present_ptr, present, 1); + return 0; } /*****************************************************************************/ @@ -698,182 +791,215 @@ xrdp_orders_screen_blt(struct xrdp_orders* self, int x, int y, /* send a pat blt order */ /* max size 39 */ int APP_CC -xrdp_orders_pat_blt(struct xrdp_orders* self, int x, int y, +xrdp_orders_pat_blt(struct xrdp_orders *self, int x, int y, int cx, int cy, int rop, int bg_color, - int fg_color, struct xrdp_brush* brush, - struct xrdp_rect* rect) + int fg_color, struct xrdp_brush *brush, + struct xrdp_rect *rect) { - int order_flags; - int present; - int vals[8]; - char* present_ptr; - char* order_flags_ptr; - struct xrdp_brush blank_brush; - - xrdp_orders_check(self, 39); - self->order_count++; - order_flags = RDP_ORDER_STANDARD; - if (self->orders_state.last_order != RDP_ORDER_PATBLT) - { - order_flags |= RDP_ORDER_CHANGE; - } - self->orders_state.last_order = RDP_ORDER_PATBLT; - if (rect != 0) - { - /* if clip is present, still check if its needed */ - if (x < rect->left || y < rect->top || - x + cx > rect->right || y + cy > rect->bottom) - { - order_flags |= RDP_ORDER_BOUNDS; - if (xrdp_orders_last_bounds(self, rect)) - { - order_flags |= RDP_ORDER_LASTBOUNDS; - } - } - } - vals[0] = x; - vals[1] = self->orders_state.pat_blt_x; - vals[2] = y; - vals[3] = self->orders_state.pat_blt_y; - vals[4] = cx; - vals[5] = self->orders_state.pat_blt_cx; - vals[6] = cy; - vals[7] = self->orders_state.pat_blt_cy; - if (xrdp_orders_send_delta(self, vals, 8)) - { - order_flags |= RDP_ORDER_DELTA; - } - /* order_flags, set later, 1 byte */ - order_flags_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if (order_flags & RDP_ORDER_CHANGE) - { - out_uint8(self->out_s, self->orders_state.last_order); - } - present = 0; - /* present, set later, 2 bytes */ - present_ptr = self->out_s->p; - out_uint8s(self->out_s, 2); - if ((order_flags & RDP_ORDER_BOUNDS) && - !(order_flags & RDP_ORDER_LASTBOUNDS)) - { - xrdp_orders_out_bounds(self, rect); - } - if (x != self->orders_state.pat_blt_x) - { - present |= 0x0001; - if (order_flags & RDP_ORDER_DELTA) - { - out_uint8(self->out_s, x - self->orders_state.pat_blt_x); + int order_flags; + int present; + int vals[8]; + char *present_ptr; + char *order_flags_ptr; + struct xrdp_brush blank_brush; + + xrdp_orders_check(self, 39); + self->order_count++; + order_flags = RDP_ORDER_STANDARD; + + if (self->orders_state.last_order != RDP_ORDER_PATBLT) + { + order_flags |= RDP_ORDER_CHANGE; } - else + + self->orders_state.last_order = RDP_ORDER_PATBLT; + + if (rect != 0) { - out_uint16_le(self->out_s, x); + /* if clip is present, still check if its needed */ + if (x < rect->left || y < rect->top || + x + cx > rect->right || y + cy > rect->bottom) + { + order_flags |= RDP_ORDER_BOUNDS; + + if (xrdp_orders_last_bounds(self, rect)) + { + order_flags |= RDP_ORDER_LASTBOUNDS; + } + } } - self->orders_state.pat_blt_x = x; - } - if (y != self->orders_state.pat_blt_y) - { - present |= 0x0002; - if (order_flags & RDP_ORDER_DELTA) + + vals[0] = x; + vals[1] = self->orders_state.pat_blt_x; + vals[2] = y; + vals[3] = self->orders_state.pat_blt_y; + vals[4] = cx; + vals[5] = self->orders_state.pat_blt_cx; + vals[6] = cy; + vals[7] = self->orders_state.pat_blt_cy; + + if (xrdp_orders_send_delta(self, vals, 8)) { - out_uint8(self->out_s, y - self->orders_state.pat_blt_y); + order_flags |= RDP_ORDER_DELTA; } - else + + /* order_flags, set later, 1 byte */ + order_flags_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if (order_flags & RDP_ORDER_CHANGE) { - out_uint16_le(self->out_s, y); + out_uint8(self->out_s, self->orders_state.last_order); } - self->orders_state.pat_blt_y = y; - } - if (cx != self->orders_state.pat_blt_cx) - { - present |= 0x0004; - if (order_flags & RDP_ORDER_DELTA) + + present = 0; + /* present, set later, 2 bytes */ + present_ptr = self->out_s->p; + out_uint8s(self->out_s, 2); + + if ((order_flags & RDP_ORDER_BOUNDS) && + !(order_flags & RDP_ORDER_LASTBOUNDS)) { - out_uint8(self->out_s, cx - self->orders_state.pat_blt_cx); + xrdp_orders_out_bounds(self, rect); } - else + + if (x != self->orders_state.pat_blt_x) { - out_uint16_le(self->out_s, cx); + present |= 0x0001; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, x - self->orders_state.pat_blt_x); + } + else + { + out_uint16_le(self->out_s, x); + } + + self->orders_state.pat_blt_x = x; } - self->orders_state.pat_blt_cx = cx; - } - if (cy != self->orders_state.pat_blt_cy) - { - present |= 0x0008; - if (order_flags & RDP_ORDER_DELTA) + + if (y != self->orders_state.pat_blt_y) { - out_uint8(self->out_s, cy - self->orders_state.pat_blt_cy); + present |= 0x0002; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, y - self->orders_state.pat_blt_y); + } + else + { + out_uint16_le(self->out_s, y); + } + + self->orders_state.pat_blt_y = y; } - else + + if (cx != self->orders_state.pat_blt_cx) { - out_uint16_le(self->out_s, cy); - } - self->orders_state.pat_blt_cy = cy; - } - if (rop != self->orders_state.pat_blt_rop) - { - present |= 0x0010; - /* PATCOPY PATPAINT PATINVERT DSTINVERT BLACKNESS WHITENESS */ - out_uint8(self->out_s, rop); - self->orders_state.pat_blt_rop = rop; - } - if (bg_color != self->orders_state.pat_blt_bg_color) - { - present |= 0x0020; - out_uint8(self->out_s, bg_color); - out_uint8(self->out_s, bg_color >> 8); - out_uint8(self->out_s, bg_color >> 16); - self->orders_state.pat_blt_bg_color = bg_color; - } - if (fg_color != self->orders_state.pat_blt_fg_color) - { - present |= 0x0040; - out_uint8(self->out_s, fg_color); - out_uint8(self->out_s, fg_color >> 8); - out_uint8(self->out_s, fg_color >> 16); - self->orders_state.pat_blt_fg_color = fg_color; - } - if (brush == 0) /* if nil use blank one */ - { /* todo can we just set style to zero */ - g_memset(&blank_brush, 0, sizeof(struct xrdp_brush)); - brush = &blank_brush; - } - if (brush->x_orgin != self->orders_state.pat_blt_brush.x_orgin) - { - present |= 0x0080; - out_uint8(self->out_s, brush->x_orgin); - self->orders_state.pat_blt_brush.x_orgin = brush->x_orgin; - } - if (brush->y_orgin != self->orders_state.pat_blt_brush.y_orgin) - { - present |= 0x0100; - out_uint8(self->out_s, brush->y_orgin); - self->orders_state.pat_blt_brush.y_orgin = brush->y_orgin; - } - if (brush->style != self->orders_state.pat_blt_brush.style) - { - present |= 0x0200; - out_uint8(self->out_s, brush->style); - self->orders_state.pat_blt_brush.style = brush->style; - } - if (brush->pattern[0] != self->orders_state.pat_blt_brush.pattern[0]) - { - present |= 0x0400; - out_uint8(self->out_s, brush->pattern[0]); - self->orders_state.pat_blt_brush.pattern[0] = brush->pattern[0]; - } - if (g_memcmp(brush->pattern + 1, - self->orders_state.pat_blt_brush.pattern + 1, 7) != 0) - { - present |= 0x0800; - out_uint8a(self->out_s, brush->pattern + 1, 7); - g_memcpy(self->orders_state.pat_blt_brush.pattern + 1, - brush->pattern + 1, 7); - } - xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, - present_ptr, present, 2); - return 0; + present |= 0x0004; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cx - self->orders_state.pat_blt_cx); + } + else + { + out_uint16_le(self->out_s, cx); + } + + self->orders_state.pat_blt_cx = cx; + } + + if (cy != self->orders_state.pat_blt_cy) + { + present |= 0x0008; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cy - self->orders_state.pat_blt_cy); + } + else + { + out_uint16_le(self->out_s, cy); + } + + self->orders_state.pat_blt_cy = cy; + } + + if (rop != self->orders_state.pat_blt_rop) + { + present |= 0x0010; + /* PATCOPY PATPAINT PATINVERT DSTINVERT BLACKNESS WHITENESS */ + out_uint8(self->out_s, rop); + self->orders_state.pat_blt_rop = rop; + } + + if (bg_color != self->orders_state.pat_blt_bg_color) + { + present |= 0x0020; + out_uint8(self->out_s, bg_color); + out_uint8(self->out_s, bg_color >> 8); + out_uint8(self->out_s, bg_color >> 16); + self->orders_state.pat_blt_bg_color = bg_color; + } + + if (fg_color != self->orders_state.pat_blt_fg_color) + { + present |= 0x0040; + out_uint8(self->out_s, fg_color); + out_uint8(self->out_s, fg_color >> 8); + out_uint8(self->out_s, fg_color >> 16); + self->orders_state.pat_blt_fg_color = fg_color; + } + + if (brush == 0) /* if nil use blank one */ + { + /* todo can we just set style to zero */ + g_memset(&blank_brush, 0, sizeof(struct xrdp_brush)); + brush = &blank_brush; + } + + if (brush->x_orgin != self->orders_state.pat_blt_brush.x_orgin) + { + present |= 0x0080; + out_uint8(self->out_s, brush->x_orgin); + self->orders_state.pat_blt_brush.x_orgin = brush->x_orgin; + } + + if (brush->y_orgin != self->orders_state.pat_blt_brush.y_orgin) + { + present |= 0x0100; + out_uint8(self->out_s, brush->y_orgin); + self->orders_state.pat_blt_brush.y_orgin = brush->y_orgin; + } + + if (brush->style != self->orders_state.pat_blt_brush.style) + { + present |= 0x0200; + out_uint8(self->out_s, brush->style); + self->orders_state.pat_blt_brush.style = brush->style; + } + + if (brush->pattern[0] != self->orders_state.pat_blt_brush.pattern[0]) + { + present |= 0x0400; + out_uint8(self->out_s, brush->pattern[0]); + self->orders_state.pat_blt_brush.pattern[0] = brush->pattern[0]; + } + + if (g_memcmp(brush->pattern + 1, + self->orders_state.pat_blt_brush.pattern + 1, 7) != 0) + { + present |= 0x0800; + out_uint8a(self->out_s, brush->pattern + 1, 7); + g_memcpy(self->orders_state.pat_blt_brush.pattern + 1, + brush->pattern + 1, 7); + } + + xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, + present_ptr, present, 2); + return 0; } /*****************************************************************************/ @@ -881,126 +1007,150 @@ xrdp_orders_pat_blt(struct xrdp_orders* self, int x, int y, /* send a dest blt order */ /* max size 21 */ int APP_CC -xrdp_orders_dest_blt(struct xrdp_orders* self, int x, int y, +xrdp_orders_dest_blt(struct xrdp_orders *self, int x, int y, int cx, int cy, int rop, - struct xrdp_rect* rect) + struct xrdp_rect *rect) { - int order_flags; - int vals[8]; - int present; - char* present_ptr; - char* order_flags_ptr; - - xrdp_orders_check(self, 21); - self->order_count++; - order_flags = RDP_ORDER_STANDARD; - if (self->orders_state.last_order != RDP_ORDER_DESTBLT) - { - order_flags |= RDP_ORDER_CHANGE; - } - self->orders_state.last_order = RDP_ORDER_DESTBLT; - if (rect != 0) - { - /* if clip is present, still check if its needed */ - if (x < rect->left || y < rect->top || - x + cx > rect->right || y + cy > rect->bottom) - { - order_flags |= RDP_ORDER_BOUNDS; - if (xrdp_orders_last_bounds(self, rect)) - { - order_flags |= RDP_ORDER_LASTBOUNDS; - } - } - } - vals[0] = x; - vals[1] = self->orders_state.dest_blt_x; - vals[2] = y; - vals[3] = self->orders_state.dest_blt_y; - vals[4] = cx; - vals[5] = self->orders_state.dest_blt_cx; - vals[6] = cy; - vals[7] = self->orders_state.dest_blt_cy; - if (xrdp_orders_send_delta(self, vals, 8)) - { - order_flags |= RDP_ORDER_DELTA; - } - /* order_flags, set later, 1 byte */ - order_flags_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if (order_flags & RDP_ORDER_CHANGE) - { - out_uint8(self->out_s, self->orders_state.last_order); - } - present = 0; - /* present, set later, 1 byte */ - present_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if ((order_flags & RDP_ORDER_BOUNDS) && - !(order_flags & RDP_ORDER_LASTBOUNDS)) - { - xrdp_orders_out_bounds(self, rect); - } - if (x != self->orders_state.dest_blt_x) - { - present |= 0x01; - if (order_flags & RDP_ORDER_DELTA) - { - out_uint8(self->out_s, x - self->orders_state.dest_blt_x); + int order_flags; + int vals[8]; + int present; + char *present_ptr; + char *order_flags_ptr; + + xrdp_orders_check(self, 21); + self->order_count++; + order_flags = RDP_ORDER_STANDARD; + + if (self->orders_state.last_order != RDP_ORDER_DESTBLT) + { + order_flags |= RDP_ORDER_CHANGE; } - else + + self->orders_state.last_order = RDP_ORDER_DESTBLT; + + if (rect != 0) { - out_uint16_le(self->out_s, x); + /* if clip is present, still check if its needed */ + if (x < rect->left || y < rect->top || + x + cx > rect->right || y + cy > rect->bottom) + { + order_flags |= RDP_ORDER_BOUNDS; + + if (xrdp_orders_last_bounds(self, rect)) + { + order_flags |= RDP_ORDER_LASTBOUNDS; + } + } } - self->orders_state.dest_blt_x = x; - } - if (y != self->orders_state.dest_blt_y) - { - present |= 0x02; - if (order_flags & RDP_ORDER_DELTA) + + vals[0] = x; + vals[1] = self->orders_state.dest_blt_x; + vals[2] = y; + vals[3] = self->orders_state.dest_blt_y; + vals[4] = cx; + vals[5] = self->orders_state.dest_blt_cx; + vals[6] = cy; + vals[7] = self->orders_state.dest_blt_cy; + + if (xrdp_orders_send_delta(self, vals, 8)) { - out_uint8(self->out_s, y - self->orders_state.dest_blt_y); + order_flags |= RDP_ORDER_DELTA; } - else + + /* order_flags, set later, 1 byte */ + order_flags_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if (order_flags & RDP_ORDER_CHANGE) { - out_uint16_le(self->out_s, y); + out_uint8(self->out_s, self->orders_state.last_order); } - self->orders_state.dest_blt_y = y; - } - if (cx != self->orders_state.dest_blt_cx) - { - present |= 0x04; - if (order_flags & RDP_ORDER_DELTA) + + present = 0; + /* present, set later, 1 byte */ + present_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if ((order_flags & RDP_ORDER_BOUNDS) && + !(order_flags & RDP_ORDER_LASTBOUNDS)) { - out_uint8(self->out_s, cx - self->orders_state.dest_blt_cx); + xrdp_orders_out_bounds(self, rect); } - else + + if (x != self->orders_state.dest_blt_x) { - out_uint16_le(self->out_s, cx); + present |= 0x01; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, x - self->orders_state.dest_blt_x); + } + else + { + out_uint16_le(self->out_s, x); + } + + self->orders_state.dest_blt_x = x; } - self->orders_state.dest_blt_cx = cx; - } - if (cy != self->orders_state.dest_blt_cy) - { - present |= 0x08; - if (order_flags & RDP_ORDER_DELTA) + + if (y != self->orders_state.dest_blt_y) { - out_uint8(self->out_s, cy - self->orders_state.dest_blt_cy); + present |= 0x02; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, y - self->orders_state.dest_blt_y); + } + else + { + out_uint16_le(self->out_s, y); + } + + self->orders_state.dest_blt_y = y; } - else + + if (cx != self->orders_state.dest_blt_cx) { - out_uint16_le(self->out_s, cy); - } - self->orders_state.dest_blt_cy = cy; - } - if (rop != self->orders_state.dest_blt_rop) - { - present |= 0x10; - out_uint8(self->out_s, rop); - self->orders_state.dest_blt_rop = rop; - } - xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, - present_ptr, present, 1); - return 0; + present |= 0x04; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cx - self->orders_state.dest_blt_cx); + } + else + { + out_uint16_le(self->out_s, cx); + } + + self->orders_state.dest_blt_cx = cx; + } + + if (cy != self->orders_state.dest_blt_cy) + { + present |= 0x08; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cy - self->orders_state.dest_blt_cy); + } + else + { + out_uint16_le(self->out_s, cy); + } + + self->orders_state.dest_blt_cy = cy; + } + + if (rop != self->orders_state.dest_blt_rop) + { + present |= 0x10; + out_uint8(self->out_s, rop); + self->orders_state.dest_blt_rop = rop; + } + + xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, + present_ptr, present, 1); + return 0; } /*****************************************************************************/ @@ -1008,182 +1158,214 @@ xrdp_orders_dest_blt(struct xrdp_orders* self, int x, int y, /* send a line order */ /* max size 32 */ int APP_CC -xrdp_orders_line(struct xrdp_orders* self, int mix_mode, +xrdp_orders_line(struct xrdp_orders *self, int mix_mode, int startx, int starty, int endx, int endy, int rop, int bg_color, - struct xrdp_pen* pen, - struct xrdp_rect* rect) + struct xrdp_pen *pen, + struct xrdp_rect *rect) { - int order_flags = 0; - int vals[8] = {0, 0, 0, 0, 0, 0, 0, 0}; - int present = 0; - char* present_ptr = (char *)NULL; - char* order_flags_ptr = (char *)NULL; - struct xrdp_pen blank_pen; - - g_memset(&blank_pen,0,sizeof(struct xrdp_pen)); - - /* if mix mode or rop are out of range, mstsc build 6000+ will parse the orders - wrong */ - if ((mix_mode < 1) || (mix_mode > 2)) /* TRANSPARENT(1) or OPAQUE(2) */ - { - mix_mode = 1; - } - if ((rop < 1) || (rop > 0x10)) - { - rop = 0x0d; /* R2_COPYPEN */ - } - xrdp_orders_check(self, 32); - self->order_count++; - order_flags = RDP_ORDER_STANDARD; - if (self->orders_state.last_order != RDP_ORDER_LINE) - { - order_flags |= RDP_ORDER_CHANGE; - } - self->orders_state.last_order = RDP_ORDER_LINE; - if (rect != 0) - { - /* if clip is present, still check if its needed */ - if (MIN(endx, startx) < rect->left || - MIN(endy, starty) < rect->top || - MAX(endx, startx) >= rect->right || - MAX(endy, starty) >= rect->bottom) - { - order_flags |= RDP_ORDER_BOUNDS; - if (xrdp_orders_last_bounds(self, rect)) - { - order_flags |= RDP_ORDER_LASTBOUNDS; - } - } - } - vals[0] = startx; - vals[1] = self->orders_state.line_startx; - vals[2] = starty; - vals[3] = self->orders_state.line_starty; - vals[4] = endx; - vals[5] = self->orders_state.line_endx; - vals[6] = endy; - vals[7] = self->orders_state.line_endy; - if (xrdp_orders_send_delta(self, vals, 8)) - { - order_flags |= RDP_ORDER_DELTA; - } - /* order_flags, set later, 1 byte */ - order_flags_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if (order_flags & RDP_ORDER_CHANGE) - { - out_uint8(self->out_s, self->orders_state.last_order); - } - present = 0; - /* present, set later, 2 bytes */ - present_ptr = self->out_s->p; - out_uint8s(self->out_s, 2); - if ((order_flags & RDP_ORDER_BOUNDS) && - !(order_flags & RDP_ORDER_LASTBOUNDS)) - { - xrdp_orders_out_bounds(self, rect); - } - if (mix_mode != self->orders_state.line_mix_mode) - { - present |= 0x0001; - out_uint16_le(self->out_s, mix_mode); - self->orders_state.line_mix_mode = mix_mode; - } - if (startx != self->orders_state.line_startx) - { - present |= 0x0002; - if (order_flags & RDP_ORDER_DELTA) - { - out_uint8(self->out_s, startx - self->orders_state.line_startx); + int order_flags = 0; + int vals[8] = {0, 0, 0, 0, 0, 0, 0, 0}; + int present = 0; + char *present_ptr = (char *)NULL; + char *order_flags_ptr = (char *)NULL; + struct xrdp_pen blank_pen; + + g_memset(&blank_pen, 0, sizeof(struct xrdp_pen)); + + /* if mix mode or rop are out of range, mstsc build 6000+ will parse the orders + wrong */ + if ((mix_mode < 1) || (mix_mode > 2)) /* TRANSPARENT(1) or OPAQUE(2) */ + { + mix_mode = 1; } - else + + if ((rop < 1) || (rop > 0x10)) { - out_uint16_le(self->out_s, startx); + rop = 0x0d; /* R2_COPYPEN */ } - self->orders_state.line_startx = startx; - } - if (starty != self->orders_state.line_starty) - { - present |= 0x0004; - if (order_flags & RDP_ORDER_DELTA) + + xrdp_orders_check(self, 32); + self->order_count++; + order_flags = RDP_ORDER_STANDARD; + + if (self->orders_state.last_order != RDP_ORDER_LINE) { - out_uint8(self->out_s, starty - self->orders_state.line_starty); + order_flags |= RDP_ORDER_CHANGE; } - else + + self->orders_state.last_order = RDP_ORDER_LINE; + + if (rect != 0) { - out_uint16_le(self->out_s, starty); + /* if clip is present, still check if its needed */ + if (MIN(endx, startx) < rect->left || + MIN(endy, starty) < rect->top || + MAX(endx, startx) >= rect->right || + MAX(endy, starty) >= rect->bottom) + { + order_flags |= RDP_ORDER_BOUNDS; + + if (xrdp_orders_last_bounds(self, rect)) + { + order_flags |= RDP_ORDER_LASTBOUNDS; + } + } } - self->orders_state.line_starty = starty; - } - if (endx != self->orders_state.line_endx) - { - present |= 0x0008; - if (order_flags & RDP_ORDER_DELTA) + + vals[0] = startx; + vals[1] = self->orders_state.line_startx; + vals[2] = starty; + vals[3] = self->orders_state.line_starty; + vals[4] = endx; + vals[5] = self->orders_state.line_endx; + vals[6] = endy; + vals[7] = self->orders_state.line_endy; + + if (xrdp_orders_send_delta(self, vals, 8)) { - out_uint8(self->out_s, endx - self->orders_state.line_endx); + order_flags |= RDP_ORDER_DELTA; } - else + + /* order_flags, set later, 1 byte */ + order_flags_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if (order_flags & RDP_ORDER_CHANGE) { - out_uint16_le(self->out_s, endx); + out_uint8(self->out_s, self->orders_state.last_order); } - self->orders_state.line_endx = endx; - } - if (endy != self->orders_state.line_endy) - { - present |= 0x0010; - if (order_flags & RDP_ORDER_DELTA) + + present = 0; + /* present, set later, 2 bytes */ + present_ptr = self->out_s->p; + out_uint8s(self->out_s, 2); + + if ((order_flags & RDP_ORDER_BOUNDS) && + !(order_flags & RDP_ORDER_LASTBOUNDS)) { - out_uint8(self->out_s, endy - self->orders_state.line_endy); + xrdp_orders_out_bounds(self, rect); } - else + + if (mix_mode != self->orders_state.line_mix_mode) { - out_uint16_le(self->out_s, endy); - } - self->orders_state.line_endy = endy; - } - if (bg_color != self->orders_state.line_bg_color) - { - present |= 0x0020; - out_uint8(self->out_s, bg_color); - out_uint8(self->out_s, bg_color >> 8); - out_uint8(self->out_s, bg_color >> 16); - self->orders_state.line_bg_color = bg_color; - } - if (rop != self->orders_state.line_rop) - { - present |= 0x0040; - out_uint8(self->out_s, rop); - self->orders_state.line_rop = rop; - } - if (pen == 0) - { - g_memset(&blank_pen, 0, sizeof(struct xrdp_pen)); - pen = &blank_pen; - } - if (pen->style != self->orders_state.line_pen.style) - { - present |= 0x0080; - out_uint8(self->out_s, pen->style); - self->orders_state.line_pen.style = pen->style; - } - if (pen->width != self->orders_state.line_pen.width) - { - present |= 0x0100; - out_uint8(self->out_s, pen->width); - self->orders_state.line_pen.width = pen->width; - } - if (pen->color != self->orders_state.line_pen.color) - { - present |= 0x0200; - out_uint8(self->out_s, pen->color); - out_uint8(self->out_s, pen->color >> 8); - out_uint8(self->out_s, pen->color >> 16); - self->orders_state.line_pen.color = pen->color; - } - xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, - present_ptr, present, 2); - return 0; + present |= 0x0001; + out_uint16_le(self->out_s, mix_mode); + self->orders_state.line_mix_mode = mix_mode; + } + + if (startx != self->orders_state.line_startx) + { + present |= 0x0002; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, startx - self->orders_state.line_startx); + } + else + { + out_uint16_le(self->out_s, startx); + } + + self->orders_state.line_startx = startx; + } + + if (starty != self->orders_state.line_starty) + { + present |= 0x0004; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, starty - self->orders_state.line_starty); + } + else + { + out_uint16_le(self->out_s, starty); + } + + self->orders_state.line_starty = starty; + } + + if (endx != self->orders_state.line_endx) + { + present |= 0x0008; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, endx - self->orders_state.line_endx); + } + else + { + out_uint16_le(self->out_s, endx); + } + + self->orders_state.line_endx = endx; + } + + if (endy != self->orders_state.line_endy) + { + present |= 0x0010; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, endy - self->orders_state.line_endy); + } + else + { + out_uint16_le(self->out_s, endy); + } + + self->orders_state.line_endy = endy; + } + + if (bg_color != self->orders_state.line_bg_color) + { + present |= 0x0020; + out_uint8(self->out_s, bg_color); + out_uint8(self->out_s, bg_color >> 8); + out_uint8(self->out_s, bg_color >> 16); + self->orders_state.line_bg_color = bg_color; + } + + if (rop != self->orders_state.line_rop) + { + present |= 0x0040; + out_uint8(self->out_s, rop); + self->orders_state.line_rop = rop; + } + + if (pen == 0) + { + g_memset(&blank_pen, 0, sizeof(struct xrdp_pen)); + pen = &blank_pen; + } + + if (pen->style != self->orders_state.line_pen.style) + { + present |= 0x0080; + out_uint8(self->out_s, pen->style); + self->orders_state.line_pen.style = pen->style; + } + + if (pen->width != self->orders_state.line_pen.width) + { + present |= 0x0100; + out_uint8(self->out_s, pen->width); + self->orders_state.line_pen.width = pen->width; + } + + if (pen->color != self->orders_state.line_pen.color) + { + present |= 0x0200; + out_uint8(self->out_s, pen->color); + out_uint8(self->out_s, pen->color >> 8); + out_uint8(self->out_s, pen->color >> 16); + self->orders_state.line_pen.color = pen->color; + } + + xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, + present_ptr, present, 2); + return 0; } /*****************************************************************************/ @@ -1191,541 +1373,617 @@ xrdp_orders_line(struct xrdp_orders* self, int mix_mode, /* send a mem blt order */ /* max size 30 */ int APP_CC -xrdp_orders_mem_blt(struct xrdp_orders* self, int cache_id, +xrdp_orders_mem_blt(struct xrdp_orders *self, int cache_id, int color_table, int x, int y, int cx, int cy, int rop, int srcx, int srcy, - int cache_idx, struct xrdp_rect* rect) + int cache_idx, struct xrdp_rect *rect) { - int order_flags = 0; - int vals[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - int present = 0; - char* present_ptr = (char *)NULL; - char* order_flags_ptr = (char *)NULL; - - xrdp_orders_check(self, 30); - self->order_count++; - order_flags = RDP_ORDER_STANDARD; - if (self->orders_state.last_order != RDP_ORDER_MEMBLT) - { - order_flags |= RDP_ORDER_CHANGE; - } - self->orders_state.last_order = RDP_ORDER_MEMBLT; - if (rect != 0) - { - /* if clip is present, still check if its needed */ - if (x < rect->left || y < rect->top || - x + cx > rect->right || y + cy > rect->bottom) - { - order_flags |= RDP_ORDER_BOUNDS; - if (xrdp_orders_last_bounds(self, rect)) - { - order_flags |= RDP_ORDER_LASTBOUNDS; - } - } - } - vals[0] = x; - vals[1] = self->orders_state.mem_blt_x; - vals[2] = y; - vals[3] = self->orders_state.mem_blt_y; - vals[4] = cx; - vals[5] = self->orders_state.mem_blt_cx; - vals[6] = cy; - vals[7] = self->orders_state.mem_blt_cy; - vals[8] = srcx; - vals[9] = self->orders_state.mem_blt_srcx; - vals[10] = srcy; - vals[11] = self->orders_state.mem_blt_srcy; - if (xrdp_orders_send_delta(self, vals, 12)) - { - order_flags |= RDP_ORDER_DELTA; - } - /* order_flags, set later, 1 byte */ - order_flags_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if (order_flags & RDP_ORDER_CHANGE) - { - out_uint8(self->out_s, self->orders_state.last_order); - } - present = 0; - /* present, set later, 2 bytes */ - present_ptr = self->out_s->p; - out_uint8s(self->out_s, 2); - if ((order_flags & RDP_ORDER_BOUNDS) && - !(order_flags & RDP_ORDER_LASTBOUNDS)) - { - xrdp_orders_out_bounds(self, rect); - } - if (cache_id != self->orders_state.mem_blt_cache_id || - color_table != self->orders_state.mem_blt_color_table) - { - present |= 0x0001; - out_uint8(self->out_s, cache_id); - out_uint8(self->out_s, color_table); - self->orders_state.mem_blt_cache_id = cache_id; - self->orders_state.mem_blt_color_table = color_table; - } - if (x != self->orders_state.mem_blt_x) - { - present |= 0x0002; - if (order_flags & RDP_ORDER_DELTA) + int order_flags = 0; + int vals[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + int present = 0; + char *present_ptr = (char *)NULL; + char *order_flags_ptr = (char *)NULL; + + xrdp_orders_check(self, 30); + self->order_count++; + order_flags = RDP_ORDER_STANDARD; + + if (self->orders_state.last_order != RDP_ORDER_MEMBLT) { - out_uint8(self->out_s, x - self->orders_state.mem_blt_x); + order_flags |= RDP_ORDER_CHANGE; } - else + + self->orders_state.last_order = RDP_ORDER_MEMBLT; + + if (rect != 0) { - out_uint16_le(self->out_s, x); + /* if clip is present, still check if its needed */ + if (x < rect->left || y < rect->top || + x + cx > rect->right || y + cy > rect->bottom) + { + order_flags |= RDP_ORDER_BOUNDS; + + if (xrdp_orders_last_bounds(self, rect)) + { + order_flags |= RDP_ORDER_LASTBOUNDS; + } + } } - self->orders_state.mem_blt_x = x; - } - if (y != self->orders_state.mem_blt_y) - { - present |= 0x0004; - if (order_flags & RDP_ORDER_DELTA) + + vals[0] = x; + vals[1] = self->orders_state.mem_blt_x; + vals[2] = y; + vals[3] = self->orders_state.mem_blt_y; + vals[4] = cx; + vals[5] = self->orders_state.mem_blt_cx; + vals[6] = cy; + vals[7] = self->orders_state.mem_blt_cy; + vals[8] = srcx; + vals[9] = self->orders_state.mem_blt_srcx; + vals[10] = srcy; + vals[11] = self->orders_state.mem_blt_srcy; + + if (xrdp_orders_send_delta(self, vals, 12)) { - out_uint8(self->out_s, y - self->orders_state.mem_blt_y); + order_flags |= RDP_ORDER_DELTA; } - else + + /* order_flags, set later, 1 byte */ + order_flags_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if (order_flags & RDP_ORDER_CHANGE) { - out_uint16_le(self->out_s, y); + out_uint8(self->out_s, self->orders_state.last_order); } - self->orders_state.mem_blt_y = y; - } - if (cx != self->orders_state.mem_blt_cx) - { - present |= 0x0008; - if (order_flags & RDP_ORDER_DELTA) + + present = 0; + /* present, set later, 2 bytes */ + present_ptr = self->out_s->p; + out_uint8s(self->out_s, 2); + + if ((order_flags & RDP_ORDER_BOUNDS) && + !(order_flags & RDP_ORDER_LASTBOUNDS)) { - out_uint8(self->out_s, cx - self->orders_state.mem_blt_cx); + xrdp_orders_out_bounds(self, rect); } - else + + if (cache_id != self->orders_state.mem_blt_cache_id || + color_table != self->orders_state.mem_blt_color_table) { - out_uint16_le(self->out_s, cx); + present |= 0x0001; + out_uint8(self->out_s, cache_id); + out_uint8(self->out_s, color_table); + self->orders_state.mem_blt_cache_id = cache_id; + self->orders_state.mem_blt_color_table = color_table; } - self->orders_state.mem_blt_cx = cx; - } - if (cy != self->orders_state.mem_blt_cy) - { - present |= 0x0010; - if (order_flags & RDP_ORDER_DELTA) + + if (x != self->orders_state.mem_blt_x) { - out_uint8(self->out_s, cy - self->orders_state.mem_blt_cy); + present |= 0x0002; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, x - self->orders_state.mem_blt_x); + } + else + { + out_uint16_le(self->out_s, x); + } + + self->orders_state.mem_blt_x = x; } - else + + if (y != self->orders_state.mem_blt_y) { - out_uint16_le(self->out_s, cy); + present |= 0x0004; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, y - self->orders_state.mem_blt_y); + } + else + { + out_uint16_le(self->out_s, y); + } + + self->orders_state.mem_blt_y = y; } - self->orders_state.mem_blt_cy = cy; - } - if (rop != self->orders_state.mem_blt_rop) - { - present |= 0x0020; - out_uint8(self->out_s, rop); - self->orders_state.mem_blt_rop = rop; - } - if (srcx != self->orders_state.mem_blt_srcx) - { - present |= 0x0040; - if (order_flags & RDP_ORDER_DELTA) + + if (cx != self->orders_state.mem_blt_cx) { - out_uint8(self->out_s, srcx - self->orders_state.mem_blt_srcx); + present |= 0x0008; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cx - self->orders_state.mem_blt_cx); + } + else + { + out_uint16_le(self->out_s, cx); + } + + self->orders_state.mem_blt_cx = cx; } - else + + if (cy != self->orders_state.mem_blt_cy) { - out_uint16_le(self->out_s, srcx); + present |= 0x0010; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, cy - self->orders_state.mem_blt_cy); + } + else + { + out_uint16_le(self->out_s, cy); + } + + self->orders_state.mem_blt_cy = cy; } - self->orders_state.mem_blt_srcx = srcx; - } - if (srcy != self->orders_state.mem_blt_srcy) - { - present |= 0x0080; - if (order_flags & RDP_ORDER_DELTA) + + if (rop != self->orders_state.mem_blt_rop) { - out_uint8(self->out_s, srcy - self->orders_state.mem_blt_srcy); + present |= 0x0020; + out_uint8(self->out_s, rop); + self->orders_state.mem_blt_rop = rop; } - else + + if (srcx != self->orders_state.mem_blt_srcx) { - out_uint16_le(self->out_s, srcy); + present |= 0x0040; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, srcx - self->orders_state.mem_blt_srcx); + } + else + { + out_uint16_le(self->out_s, srcx); + } + + self->orders_state.mem_blt_srcx = srcx; } - self->orders_state.mem_blt_srcy = srcy; - } - if (cache_idx != self->orders_state.mem_blt_cache_idx) - { - present |= 0x0100; - out_uint16_le(self->out_s, cache_idx); - self->orders_state.mem_blt_cache_idx = cache_idx; - } - xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, - present_ptr, present, 2); - return 0; + + if (srcy != self->orders_state.mem_blt_srcy) + { + present |= 0x0080; + + if (order_flags & RDP_ORDER_DELTA) + { + out_uint8(self->out_s, srcy - self->orders_state.mem_blt_srcy); + } + else + { + out_uint16_le(self->out_s, srcy); + } + + self->orders_state.mem_blt_srcy = srcy; + } + + if (cache_idx != self->orders_state.mem_blt_cache_idx) + { + present |= 0x0100; + out_uint16_le(self->out_s, cache_idx); + self->orders_state.mem_blt_cache_idx = cache_idx; + } + + xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, + present_ptr, present, 2); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_orders_text(struct xrdp_orders* self, +xrdp_orders_text(struct xrdp_orders *self, int font, int flags, int mixmode, int fg_color, int bg_color, int clip_left, int clip_top, int clip_right, int clip_bottom, int box_left, int box_top, int box_right, int box_bottom, - int x, int y, char* data, int data_len, - struct xrdp_rect* rect) + int x, int y, char *data, int data_len, + struct xrdp_rect *rect) { - int order_flags = 0; - int present = 0; - char* present_ptr = (char *)NULL; - char* order_flags_ptr = (char *)NULL; - - xrdp_orders_check(self, 100); - self->order_count++; - order_flags = RDP_ORDER_STANDARD; - if (self->orders_state.last_order != RDP_ORDER_TEXT2) - { - order_flags |= RDP_ORDER_CHANGE; - } - self->orders_state.last_order = RDP_ORDER_TEXT2; - if (rect != 0) - { - /* if clip is present, still check if its needed */ - if ((box_right - box_left > 1 && - (box_left < rect->left || - box_top < rect->top || - box_right > rect->right || - box_bottom > rect->bottom)) || - (clip_left < rect->left || - clip_top < rect->top || - clip_right > rect->right || - clip_bottom > rect->bottom)) - { - order_flags |= RDP_ORDER_BOUNDS; - if (xrdp_orders_last_bounds(self, rect)) - { - order_flags |= RDP_ORDER_LASTBOUNDS; - } - } - } - /* order_flags, set later, 1 byte */ - order_flags_ptr = self->out_s->p; - out_uint8s(self->out_s, 1); - if (order_flags & RDP_ORDER_CHANGE) - { - out_uint8(self->out_s, self->orders_state.last_order); - } - present = 0; - /* present, set later, 3 bytes */ - present_ptr = self->out_s->p; - out_uint8s(self->out_s, 3); - if ((order_flags & RDP_ORDER_BOUNDS) && - !(order_flags & RDP_ORDER_LASTBOUNDS)) - { - xrdp_orders_out_bounds(self, rect); - } - if (font != self->orders_state.text_font) - { - present |= 0x000001; - out_uint8(self->out_s, font); - self->orders_state.text_font = font; - } - if (flags != self->orders_state.text_flags) - { - present |= 0x000002; - out_uint8(self->out_s, flags); - self->orders_state.text_flags = flags; - } - /* unknown */ - if (mixmode != self->orders_state.text_mixmode) - { - present |= 0x000008; - out_uint8(self->out_s, mixmode); - self->orders_state.text_mixmode = mixmode; - } - if (fg_color != self->orders_state.text_fg_color) - { - present |= 0x000010; - out_uint8(self->out_s, fg_color); - out_uint8(self->out_s, fg_color >> 8); - out_uint8(self->out_s, fg_color >> 16); - self->orders_state.text_fg_color = fg_color; - } - if (bg_color != self->orders_state.text_bg_color) - { - present |= 0x000020; - out_uint8(self->out_s, bg_color); - out_uint8(self->out_s, bg_color >> 8); - out_uint8(self->out_s, bg_color >> 16); - self->orders_state.text_bg_color = bg_color; - } - if (clip_left != self->orders_state.text_clip_left) - { - present |= 0x000040; - out_uint16_le(self->out_s, clip_left); - self->orders_state.text_clip_left = clip_left; - } - if (clip_top != self->orders_state.text_clip_top) - { - present |= 0x000080; - out_uint16_le(self->out_s, clip_top); - self->orders_state.text_clip_top = clip_top; - } - if (clip_right != self->orders_state.text_clip_right) - { - present |= 0x000100; - out_uint16_le(self->out_s, clip_right); - self->orders_state.text_clip_right = clip_right; - } - if (clip_bottom != self->orders_state.text_clip_bottom) - { - present |= 0x000200; - out_uint16_le(self->out_s, clip_bottom); - self->orders_state.text_clip_bottom = clip_bottom; - } - if (box_left != self->orders_state.text_box_left) - { - present |= 0x000400; - out_uint16_le(self->out_s, box_left); - self->orders_state.text_box_left = box_left; - } - if (box_top != self->orders_state.text_box_top) - { - present |= 0x000800; - out_uint16_le(self->out_s, box_top); - self->orders_state.text_box_top = box_top; - } - if (box_right != self->orders_state.text_box_right) - { - present |= 0x001000; - out_uint16_le(self->out_s, box_right); - self->orders_state.text_box_right = box_right; - } - if (box_bottom != self->orders_state.text_box_bottom) - { - present |= 0x002000; - out_uint16_le(self->out_s, box_bottom); - self->orders_state.text_box_bottom = box_bottom; - } - if (x != self->orders_state.text_x) - { - present |= 0x080000; - out_uint16_le(self->out_s, x); - self->orders_state.text_x = x; - } - if (y != self->orders_state.text_y) - { - present |= 0x100000; - out_uint16_le(self->out_s, y); - self->orders_state.text_y = y; - } - { - /* always send text */ - present |= 0x200000; - out_uint8(self->out_s, data_len); - out_uint8a(self->out_s, data, data_len); - } - xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, - present_ptr, present, 3); - return 0; + int order_flags = 0; + int present = 0; + char *present_ptr = (char *)NULL; + char *order_flags_ptr = (char *)NULL; + + xrdp_orders_check(self, 100); + self->order_count++; + order_flags = RDP_ORDER_STANDARD; + + if (self->orders_state.last_order != RDP_ORDER_TEXT2) + { + order_flags |= RDP_ORDER_CHANGE; + } + + self->orders_state.last_order = RDP_ORDER_TEXT2; + + if (rect != 0) + { + /* if clip is present, still check if its needed */ + if ((box_right - box_left > 1 && + (box_left < rect->left || + box_top < rect->top || + box_right > rect->right || + box_bottom > rect->bottom)) || + (clip_left < rect->left || + clip_top < rect->top || + clip_right > rect->right || + clip_bottom > rect->bottom)) + { + order_flags |= RDP_ORDER_BOUNDS; + + if (xrdp_orders_last_bounds(self, rect)) + { + order_flags |= RDP_ORDER_LASTBOUNDS; + } + } + } + + /* order_flags, set later, 1 byte */ + order_flags_ptr = self->out_s->p; + out_uint8s(self->out_s, 1); + + if (order_flags & RDP_ORDER_CHANGE) + { + out_uint8(self->out_s, self->orders_state.last_order); + } + + present = 0; + /* present, set later, 3 bytes */ + present_ptr = self->out_s->p; + out_uint8s(self->out_s, 3); + + if ((order_flags & RDP_ORDER_BOUNDS) && + !(order_flags & RDP_ORDER_LASTBOUNDS)) + { + xrdp_orders_out_bounds(self, rect); + } + + if (font != self->orders_state.text_font) + { + present |= 0x000001; + out_uint8(self->out_s, font); + self->orders_state.text_font = font; + } + + if (flags != self->orders_state.text_flags) + { + present |= 0x000002; + out_uint8(self->out_s, flags); + self->orders_state.text_flags = flags; + } + + /* unknown */ + if (mixmode != self->orders_state.text_mixmode) + { + present |= 0x000008; + out_uint8(self->out_s, mixmode); + self->orders_state.text_mixmode = mixmode; + } + + if (fg_color != self->orders_state.text_fg_color) + { + present |= 0x000010; + out_uint8(self->out_s, fg_color); + out_uint8(self->out_s, fg_color >> 8); + out_uint8(self->out_s, fg_color >> 16); + self->orders_state.text_fg_color = fg_color; + } + + if (bg_color != self->orders_state.text_bg_color) + { + present |= 0x000020; + out_uint8(self->out_s, bg_color); + out_uint8(self->out_s, bg_color >> 8); + out_uint8(self->out_s, bg_color >> 16); + self->orders_state.text_bg_color = bg_color; + } + + if (clip_left != self->orders_state.text_clip_left) + { + present |= 0x000040; + out_uint16_le(self->out_s, clip_left); + self->orders_state.text_clip_left = clip_left; + } + + if (clip_top != self->orders_state.text_clip_top) + { + present |= 0x000080; + out_uint16_le(self->out_s, clip_top); + self->orders_state.text_clip_top = clip_top; + } + + if (clip_right != self->orders_state.text_clip_right) + { + present |= 0x000100; + out_uint16_le(self->out_s, clip_right); + self->orders_state.text_clip_right = clip_right; + } + + if (clip_bottom != self->orders_state.text_clip_bottom) + { + present |= 0x000200; + out_uint16_le(self->out_s, clip_bottom); + self->orders_state.text_clip_bottom = clip_bottom; + } + + if (box_left != self->orders_state.text_box_left) + { + present |= 0x000400; + out_uint16_le(self->out_s, box_left); + self->orders_state.text_box_left = box_left; + } + + if (box_top != self->orders_state.text_box_top) + { + present |= 0x000800; + out_uint16_le(self->out_s, box_top); + self->orders_state.text_box_top = box_top; + } + + if (box_right != self->orders_state.text_box_right) + { + present |= 0x001000; + out_uint16_le(self->out_s, box_right); + self->orders_state.text_box_right = box_right; + } + + if (box_bottom != self->orders_state.text_box_bottom) + { + present |= 0x002000; + out_uint16_le(self->out_s, box_bottom); + self->orders_state.text_box_bottom = box_bottom; + } + + if (x != self->orders_state.text_x) + { + present |= 0x080000; + out_uint16_le(self->out_s, x); + self->orders_state.text_x = x; + } + + if (y != self->orders_state.text_y) + { + present |= 0x100000; + out_uint16_le(self->out_s, y); + self->orders_state.text_y = y; + } + + { + /* always send text */ + present |= 0x200000; + out_uint8(self->out_s, data_len); + out_uint8a(self->out_s, data, data_len); + } + + xrdp_order_pack_small_or_tiny(self, order_flags_ptr, order_flags, + present_ptr, present, 3); + return 0; } /*****************************************************************************/ /* returns error */ /* when a palette gets sent, send the main palette too */ int APP_CC -xrdp_orders_send_palette(struct xrdp_orders* self, int* palette, +xrdp_orders_send_palette(struct xrdp_orders *self, int *palette, int cache_id) { - int order_flags; - int len; - int i; - - xrdp_orders_check(self, 2000); - self->order_count++; - order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; - out_uint8(self->out_s, order_flags); - len = 1027 - 7; /* length after type minus 7 */ - out_uint16_le(self->out_s, len); - out_uint16_le(self->out_s, 0); /* flags */ - out_uint8(self->out_s, RDP_ORDER_COLCACHE); /* type */ - out_uint8(self->out_s, cache_id); - out_uint16_le(self->out_s, 256); /* num colors */ - for (i = 0; i < 256; i++) - { - out_uint8(self->out_s, palette[i]); - out_uint8(self->out_s, palette[i] >> 8); - out_uint8(self->out_s, palette[i] >> 16); - out_uint8(self->out_s, 0); - } - return 0; + int order_flags; + int len; + int i; + + xrdp_orders_check(self, 2000); + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + len = 1027 - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + out_uint16_le(self->out_s, 0); /* flags */ + out_uint8(self->out_s, RDP_ORDER_COLCACHE); /* type */ + out_uint8(self->out_s, cache_id); + out_uint16_le(self->out_s, 256); /* num colors */ + + for (i = 0; i < 256; i++) + { + out_uint8(self->out_s, palette[i]); + out_uint8(self->out_s, palette[i] >> 8); + out_uint8(self->out_s, palette[i] >> 16); + out_uint8(self->out_s, 0); + } + + return 0; } /*****************************************************************************/ /* returns error */ /* max size width * height * Bpp + 16 */ int APP_CC -xrdp_orders_send_raw_bitmap(struct xrdp_orders* self, - int width, int height, int bpp, char* data, +xrdp_orders_send_raw_bitmap(struct xrdp_orders *self, + int width, int height, int bpp, char *data, int cache_id, int cache_idx) { - int order_flags = 0; - int len = 0; - int bufsize = 0; - int Bpp = 0; - int i = 0; - int j = 0; - int pixel = 0; - int e = 0; - - if (width > 64) - { - g_writeln("error, width > 64"); - return 1; - } - if (height > 64) - { - g_writeln("error, height > 64"); - return 1; - } - e = width % 4; - if (e != 0) - { - e = 4 - e; - } - Bpp = (bpp + 7) / 8; - bufsize = (width + e) * height * Bpp; - xrdp_orders_check(self, bufsize + 16); - self->order_count++; - order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; - out_uint8(self->out_s, order_flags); - len = (bufsize + 9) - 7; /* length after type minus 7 */ - out_uint16_le(self->out_s, len); - out_uint16_le(self->out_s, 8); /* flags */ - out_uint8(self->out_s, RDP_ORDER_RAW_BMPCACHE); /* type */ - out_uint8(self->out_s, cache_id); - out_uint8s(self->out_s, 1); /* pad */ - out_uint8(self->out_s, width + e); - out_uint8(self->out_s, height); - out_uint8(self->out_s, bpp); - out_uint16_le(self->out_s, bufsize); - out_uint16_le(self->out_s, cache_idx); - for (i = height - 1; i >= 0; i--) - { - for (j = 0; j < width; j++) - { - if (Bpp == 3) - { - pixel = GETPIXEL32(data, j, i, width); - out_uint8(self->out_s, pixel >> 16); - out_uint8(self->out_s, pixel >> 8); - out_uint8(self->out_s, pixel); - } - else if (Bpp == 2) - { - pixel = GETPIXEL16(data, j, i, width); - out_uint8(self->out_s, pixel); - out_uint8(self->out_s, pixel >> 8); - } - else if (Bpp == 1) - { - pixel = GETPIXEL8(data, j, i, width); - out_uint8(self->out_s, pixel); - } - } - for (j = 0; j < e; j++) - { - out_uint8s(self->out_s, Bpp); - } - } - return 0; + int order_flags = 0; + int len = 0; + int bufsize = 0; + int Bpp = 0; + int i = 0; + int j = 0; + int pixel = 0; + int e = 0; + + if (width > 64) + { + g_writeln("error, width > 64"); + return 1; + } + + if (height > 64) + { + g_writeln("error, height > 64"); + return 1; + } + + e = width % 4; + + if (e != 0) + { + e = 4 - e; + } + + Bpp = (bpp + 7) / 8; + bufsize = (width + e) * height * Bpp; + xrdp_orders_check(self, bufsize + 16); + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + len = (bufsize + 9) - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + out_uint16_le(self->out_s, 8); /* flags */ + out_uint8(self->out_s, RDP_ORDER_RAW_BMPCACHE); /* type */ + out_uint8(self->out_s, cache_id); + out_uint8s(self->out_s, 1); /* pad */ + out_uint8(self->out_s, width + e); + out_uint8(self->out_s, height); + out_uint8(self->out_s, bpp); + out_uint16_le(self->out_s, bufsize); + out_uint16_le(self->out_s, cache_idx); + + for (i = height - 1; i >= 0; i--) + { + for (j = 0; j < width; j++) + { + if (Bpp == 3) + { + pixel = GETPIXEL32(data, j, i, width); + out_uint8(self->out_s, pixel >> 16); + out_uint8(self->out_s, pixel >> 8); + out_uint8(self->out_s, pixel); + } + else if (Bpp == 2) + { + pixel = GETPIXEL16(data, j, i, width); + out_uint8(self->out_s, pixel); + out_uint8(self->out_s, pixel >> 8); + } + else if (Bpp == 1) + { + pixel = GETPIXEL8(data, j, i, width); + out_uint8(self->out_s, pixel); + } + } + + for (j = 0; j < e; j++) + { + out_uint8s(self->out_s, Bpp); + } + } + + return 0; } /*****************************************************************************/ /* returns error */ /* max size width * height * Bpp + 16 */ int APP_CC -xrdp_orders_send_bitmap(struct xrdp_orders* self, - int width, int height, int bpp, char* data, +xrdp_orders_send_bitmap(struct xrdp_orders *self, + int width, int height, int bpp, char *data, int cache_id, int cache_idx) { - int order_flags = 0; - int len = 0; - int bufsize = 0; - int Bpp = 0; - int i = 0; - int lines_sending = 0; - int e = 0; - struct stream* s = NULL; - struct stream* temp_s = NULL; - char* p = NULL; - - if (width > 64) - { - g_writeln("error, width > 64"); - return 1; - } - if (height > 64) - { - g_writeln("error, height > 64"); - return 1; - } - e = width % 4; - if (e != 0) - { - e = 4 - e; - } - make_stream(s); - init_stream(s, 16384); - make_stream(temp_s); - init_stream(temp_s, 16384); - p = s->p; - i = height; - lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384, - i - 1, temp_s, e); - if (lines_sending != height) - { + int order_flags = 0; + int len = 0; + int bufsize = 0; + int Bpp = 0; + int i = 0; + int lines_sending = 0; + int e = 0; + struct stream *s = NULL; + struct stream *temp_s = NULL; + char *p = NULL; + + if (width > 64) + { + g_writeln("error, width > 64"); + return 1; + } + + if (height > 64) + { + g_writeln("error, height > 64"); + return 1; + } + + e = width % 4; + + if (e != 0) + { + e = 4 - e; + } + + make_stream(s); + init_stream(s, 16384); + make_stream(temp_s); + init_stream(temp_s, 16384); + p = s->p; + i = height; + lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384, + i - 1, temp_s, e); + + if (lines_sending != height) + { + free_stream(s); + free_stream(temp_s); + g_writeln("error in xrdp_orders_send_bitmap, lines_sending(%d) != \ +height(%d)", lines_sending, height); + return 1; + } + + bufsize = (int)(s->p - p); + Bpp = (bpp + 7) / 8; + xrdp_orders_check(self, bufsize + 16); + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + + if (self->rdp_layer->client_info.op2) + { + len = (bufsize + 9) - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + out_uint16_le(self->out_s, 1024); /* flags */ + } + else + { + len = (bufsize + 9 + 8) - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + out_uint16_le(self->out_s, 8); /* flags */ + } + + out_uint8(self->out_s, RDP_ORDER_BMPCACHE); /* type */ + out_uint8(self->out_s, cache_id); + out_uint8s(self->out_s, 1); /* pad */ + out_uint8(self->out_s, width + e); + out_uint8(self->out_s, height); + out_uint8(self->out_s, bpp); + out_uint16_le(self->out_s, bufsize/* + 8*/); + out_uint16_le(self->out_s, cache_idx); + + if (!self->rdp_layer->client_info.op2) + { + out_uint8s(self->out_s, 2); /* pad */ + out_uint16_le(self->out_s, bufsize); + out_uint16_le(self->out_s, (width + e) * Bpp); /* line size */ + out_uint16_le(self->out_s, (width + e) * + Bpp * height); /* final size */ + } + + out_uint8a(self->out_s, s->data, bufsize); free_stream(s); free_stream(temp_s); - g_writeln("error in xrdp_orders_send_bitmap, lines_sending(%d) != \ -height(%d)", lines_sending, height); - return 1; - } - bufsize = (int)(s->p - p); - Bpp = (bpp + 7) / 8; - xrdp_orders_check(self, bufsize + 16); - self->order_count++; - order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; - out_uint8(self->out_s, order_flags); - if (self->rdp_layer->client_info.op2) - { - len = (bufsize + 9) - 7; /* length after type minus 7 */ - out_uint16_le(self->out_s, len); - out_uint16_le(self->out_s, 1024); /* flags */ - } - else - { - len = (bufsize + 9 + 8) - 7; /* length after type minus 7 */ - out_uint16_le(self->out_s, len); - out_uint16_le(self->out_s, 8); /* flags */ - } - out_uint8(self->out_s, RDP_ORDER_BMPCACHE); /* type */ - out_uint8(self->out_s, cache_id); - out_uint8s(self->out_s, 1); /* pad */ - out_uint8(self->out_s, width + e); - out_uint8(self->out_s, height); - out_uint8(self->out_s, bpp); - out_uint16_le(self->out_s, bufsize/* + 8*/); - out_uint16_le(self->out_s, cache_idx); - if (!self->rdp_layer->client_info.op2) - { - out_uint8s(self->out_s, 2); /* pad */ - out_uint16_le(self->out_s, bufsize); - out_uint16_le(self->out_s, (width + e) * Bpp); /* line size */ - out_uint16_le(self->out_s, (width + e) * - Bpp * height); /* final size */ - } - out_uint8a(self->out_s, s->data, bufsize); - free_stream(s); - free_stream(temp_s); - return 0; + return 0; } /*****************************************************************************/ @@ -1733,457 +1991,492 @@ height(%d)", lines_sending, height); /* max size datasize + 18*/ /* todo, only sends one for now */ int APP_CC -xrdp_orders_send_font(struct xrdp_orders* self, - struct xrdp_font_char* font_char, +xrdp_orders_send_font(struct xrdp_orders *self, + struct xrdp_font_char *font_char, int font_index, int char_index) { - int order_flags = 0; - int datasize = 0; - int len = 0; - - datasize = FONT_DATASIZE(font_char); - xrdp_orders_check(self, datasize + 18); - self->order_count++; - order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; - out_uint8(self->out_s, order_flags); - len = (datasize + 12) - 7; /* length after type minus 7 */ - out_uint16_le(self->out_s, len); - out_uint16_le(self->out_s, 8); /* flags */ - out_uint8(self->out_s, RDP_ORDER_FONTCACHE); /* type */ - out_uint8(self->out_s, font_index); - out_uint8(self->out_s, 1); /* num of chars */ - out_uint16_le(self->out_s, char_index); - out_uint16_le(self->out_s, font_char->offset); - out_uint16_le(self->out_s, font_char->baseline); - out_uint16_le(self->out_s, font_char->width); - out_uint16_le(self->out_s, font_char->height); - out_uint8a(self->out_s, font_char->data, datasize); - return 0; + int order_flags = 0; + int datasize = 0; + int len = 0; + + datasize = FONT_DATASIZE(font_char); + xrdp_orders_check(self, datasize + 18); + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + len = (datasize + 12) - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + out_uint16_le(self->out_s, 8); /* flags */ + out_uint8(self->out_s, RDP_ORDER_FONTCACHE); /* type */ + out_uint8(self->out_s, font_index); + out_uint8(self->out_s, 1); /* num of chars */ + out_uint16_le(self->out_s, char_index); + out_uint16_le(self->out_s, font_char->offset); + out_uint16_le(self->out_s, font_char->baseline); + out_uint16_le(self->out_s, font_char->width); + out_uint16_le(self->out_s, font_char->height); + out_uint8a(self->out_s, font_char->data, datasize); + return 0; } /*****************************************************************************/ /* returns error */ /* max size width * height * Bpp + 14 */ int APP_CC -xrdp_orders_send_raw_bitmap2(struct xrdp_orders* self, - int width, int height, int bpp, char* data, +xrdp_orders_send_raw_bitmap2(struct xrdp_orders *self, + int width, int height, int bpp, char *data, int cache_id, int cache_idx) { - int order_flags = 0; - int len = 0; - int bufsize = 0; - int Bpp = 0; - int i = 0; - int j = 0; - int pixel = 0; - int e = 0; - - if (width > 64) - { - g_writeln("error, width > 64"); - return 1; - } - if (height > 64) - { - g_writeln("error, height > 64"); - return 1; - } - e = width % 4; - if (e != 0) - { - e = 4 - e; - } - Bpp = (bpp + 7) / 8; - bufsize = (width + e) * height * Bpp; - xrdp_orders_check(self, bufsize + 14); - self->order_count++; - order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; - out_uint8(self->out_s, order_flags); - len = (bufsize + 6) - 7; /* length after type minus 7 */ - out_uint16_le(self->out_s, len); - i = (((Bpp + 2) << 3) & 0x38) | (cache_id & 7); - out_uint16_le(self->out_s, i); /* flags */ - out_uint8(self->out_s, RDP_ORDER_RAW_BMPCACHE2); /* type */ - out_uint8(self->out_s, width + e); - out_uint8(self->out_s, height); - out_uint16_be(self->out_s, bufsize | 0x4000); - i = ((cache_idx >> 8) & 0xff) | 0x80; - out_uint8(self->out_s, i); - i = cache_idx & 0xff; - out_uint8(self->out_s, i); - for (i = height - 1; i >= 0; i--) - { - for (j = 0; j < width; j++) - { - if (Bpp == 3) - { - pixel = GETPIXEL32(data, j, i, width); - out_uint8(self->out_s, pixel >> 16); - out_uint8(self->out_s, pixel >> 8); - out_uint8(self->out_s, pixel); - } - else if (Bpp == 2) - { - pixel = GETPIXEL16(data, j, i, width); - out_uint8(self->out_s, pixel); - out_uint8(self->out_s, pixel >> 8); - } - else if (Bpp == 1) - { - pixel = GETPIXEL8(data, j, i, width); - out_uint8(self->out_s, pixel); - } - } - for (j = 0; j < e; j++) - { - out_uint8s(self->out_s, Bpp); - } - } - return 0; + int order_flags = 0; + int len = 0; + int bufsize = 0; + int Bpp = 0; + int i = 0; + int j = 0; + int pixel = 0; + int e = 0; + + if (width > 64) + { + g_writeln("error, width > 64"); + return 1; + } + + if (height > 64) + { + g_writeln("error, height > 64"); + return 1; + } + + e = width % 4; + + if (e != 0) + { + e = 4 - e; + } + + Bpp = (bpp + 7) / 8; + bufsize = (width + e) * height * Bpp; + xrdp_orders_check(self, bufsize + 14); + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + len = (bufsize + 6) - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + i = (((Bpp + 2) << 3) & 0x38) | (cache_id & 7); + out_uint16_le(self->out_s, i); /* flags */ + out_uint8(self->out_s, RDP_ORDER_RAW_BMPCACHE2); /* type */ + out_uint8(self->out_s, width + e); + out_uint8(self->out_s, height); + out_uint16_be(self->out_s, bufsize | 0x4000); + i = ((cache_idx >> 8) & 0xff) | 0x80; + out_uint8(self->out_s, i); + i = cache_idx & 0xff; + out_uint8(self->out_s, i); + + for (i = height - 1; i >= 0; i--) + { + for (j = 0; j < width; j++) + { + if (Bpp == 3) + { + pixel = GETPIXEL32(data, j, i, width); + out_uint8(self->out_s, pixel >> 16); + out_uint8(self->out_s, pixel >> 8); + out_uint8(self->out_s, pixel); + } + else if (Bpp == 2) + { + pixel = GETPIXEL16(data, j, i, width); + out_uint8(self->out_s, pixel); + out_uint8(self->out_s, pixel >> 8); + } + else if (Bpp == 1) + { + pixel = GETPIXEL8(data, j, i, width); + out_uint8(self->out_s, pixel); + } + } + + for (j = 0; j < e; j++) + { + out_uint8s(self->out_s, Bpp); + } + } + + return 0; } /*****************************************************************************/ /* returns error */ /* max size width * height * Bpp + 14 */ int APP_CC -xrdp_orders_send_bitmap2(struct xrdp_orders* self, - int width, int height, int bpp, char* data, +xrdp_orders_send_bitmap2(struct xrdp_orders *self, + int width, int height, int bpp, char *data, int cache_id, int cache_idx, int hints) { - int order_flags = 0; - int len = 0; - int bufsize = 0; - int Bpp = 0; - int i = 0; - int lines_sending = 0; - int e = 0; - struct stream* s = NULL; - struct stream* temp_s = NULL; - char* p = NULL; - - if (width > 64) - { - g_writeln("error, width > 64"); - return 1; - } - if (height > 64) - { - g_writeln("error, height > 64"); - return 1; - } - e = width % 4; - if (e != 0) - { - e = 4 - e; - } - make_stream(s); - init_stream(s, 16384); - make_stream(temp_s); - init_stream(temp_s, 16384); - p = s->p; - i = height; - lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384, + int order_flags = 0; + int len = 0; + int bufsize = 0; + int Bpp = 0; + int i = 0; + int lines_sending = 0; + int e = 0; + struct stream *s = NULL; + struct stream *temp_s = NULL; + char *p = NULL; + + if (width > 64) + { + g_writeln("error, width > 64"); + return 1; + } + + if (height > 64) + { + g_writeln("error, height > 64"); + return 1; + } + + e = width % 4; + + if (e != 0) + { + e = 4 - e; + } + + make_stream(s); + init_stream(s, 16384); + make_stream(temp_s); + init_stream(temp_s, 16384); + p = s->p; + i = height; + lines_sending = xrdp_bitmap_compress(data, width, height, s, bpp, 16384, i - 1, temp_s, e); - if (lines_sending != height) - { + + if (lines_sending != height) + { + free_stream(s); + free_stream(temp_s); + g_writeln("error in xrdp_orders_send_bitmap2, lines_sending(%d) != \ +height(%d)", lines_sending, height); + return 1; + } + + bufsize = (int)(s->p - p); + Bpp = (bpp + 7) / 8; + xrdp_orders_check(self, bufsize + 14); + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + len = (bufsize + 6) - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + i = (((Bpp + 2) << 3) & 0x38) | (cache_id & 7); + i = i | (0x08 << 7); /* CBR2_NO_BITMAP_COMPRESSION_HDR */ + out_uint16_le(self->out_s, i); /* flags */ + out_uint8(self->out_s, RDP_ORDER_BMPCACHE2); /* type */ + out_uint8(self->out_s, width + e); + out_uint8(self->out_s, height); + out_uint16_be(self->out_s, bufsize | 0x4000); + i = ((cache_idx >> 8) & 0xff) | 0x80; + out_uint8(self->out_s, i); + i = cache_idx & 0xff; + out_uint8(self->out_s, i); + out_uint8a(self->out_s, s->data, bufsize); free_stream(s); free_stream(temp_s); - g_writeln("error in xrdp_orders_send_bitmap2, lines_sending(%d) != \ -height(%d)", lines_sending, height); - return 1; - } - bufsize = (int)(s->p - p); - Bpp = (bpp + 7) / 8; - xrdp_orders_check(self, bufsize + 14); - self->order_count++; - order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; - out_uint8(self->out_s, order_flags); - len = (bufsize + 6) - 7; /* length after type minus 7 */ - out_uint16_le(self->out_s, len); - i = (((Bpp + 2) << 3) & 0x38) | (cache_id & 7); - i = i | (0x08 << 7); /* CBR2_NO_BITMAP_COMPRESSION_HDR */ - out_uint16_le(self->out_s, i); /* flags */ - out_uint8(self->out_s, RDP_ORDER_BMPCACHE2); /* type */ - out_uint8(self->out_s, width + e); - out_uint8(self->out_s, height); - out_uint16_be(self->out_s, bufsize | 0x4000); - i = ((cache_idx >> 8) & 0xff) | 0x80; - out_uint8(self->out_s, i); - i = cache_idx & 0xff; - out_uint8(self->out_s, i); - out_uint8a(self->out_s, s->data, bufsize); - free_stream(s); - free_stream(temp_s); - return 0; + return 0; } /*****************************************************************************/ static int -xrdp_orders_send_as_jpeg(struct xrdp_orders* self, +xrdp_orders_send_as_jpeg(struct xrdp_orders *self, int width, int height, int bpp, int hints) { - if (hints & 1) - { - return 0; - } - if (bpp != 24) - { - return 0; - } - if (width * height < 64) - { - return 0; - } - return 1; + if (hints & 1) + { + return 0; + } + + if (bpp != 24) + { + return 0; + } + + if (width * height < 64) + { + return 0; + } + + return 1; } #if defined(XRDP_FREERDP1) /*****************************************************************************/ /* secondary drawing order (bitmap v3) using remotefx compression */ static int APP_CC -xrdp_orders_send_as_rfx(struct xrdp_orders* self, +xrdp_orders_send_as_rfx(struct xrdp_orders *self, int width, int height, int bpp, int hints) { - if (hints & 1) - { - return 0; - } - if (bpp != 24) - { - return 0; - } - if (width * height < 64) - { - return 0; - } - return 1; + if (hints & 1) + { + return 0; + } + + if (bpp != 24) + { + return 0; + } + + if (width * height < 64) + { + return 0; + } + + return 1; } #endif /*****************************************************************************/ static int APP_CC -xrdp_orders_out_v3(struct xrdp_orders* self, int cache_id, int cache_idx, - char* buf, int bufsize, int width, int height, int bpp, +xrdp_orders_out_v3(struct xrdp_orders *self, int cache_id, int cache_idx, + char *buf, int bufsize, int width, int height, int bpp, int codec_id) { - int Bpp; - int order_flags; - int len; - int i; - - Bpp = (bpp + 7) / 8; - xrdp_orders_check(self, bufsize + 30); - self->order_count++; - order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; - out_uint8(self->out_s, order_flags); - len = (bufsize + 22) - 7; /* length after type minus 7 */ - out_uint16_le(self->out_s, len); - i = (((Bpp + 2) << 3) & 0x38) | (cache_id & 7); - out_uint16_le(self->out_s, i); /* flags */ - out_uint8(self->out_s, RDP_ORDER_BMPCACHE3); /* type */ - /* cache index */ - out_uint16_le(self->out_s, cache_idx); - /* persistant cache key 1/2 */ - out_uint32_le(self->out_s, 0); - out_uint32_le(self->out_s, 0); - /* bitmap data */ - out_uint8(self->out_s, bpp); - out_uint8(self->out_s, 0); /* reserved */ - out_uint8(self->out_s, 0); /* reserved */ - out_uint8(self->out_s, codec_id); - out_uint16_le(self->out_s, width); - out_uint16_le(self->out_s, height); - out_uint32_le(self->out_s, bufsize); - out_uint8a(self->out_s, buf, bufsize); - return 0; + int Bpp; + int order_flags; + int len; + int i; + + Bpp = (bpp + 7) / 8; + xrdp_orders_check(self, bufsize + 30); + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + len = (bufsize + 22) - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + i = (((Bpp + 2) << 3) & 0x38) | (cache_id & 7); + out_uint16_le(self->out_s, i); /* flags */ + out_uint8(self->out_s, RDP_ORDER_BMPCACHE3); /* type */ + /* cache index */ + out_uint16_le(self->out_s, cache_idx); + /* persistant cache key 1/2 */ + out_uint32_le(self->out_s, 0); + out_uint32_le(self->out_s, 0); + /* bitmap data */ + out_uint8(self->out_s, bpp); + out_uint8(self->out_s, 0); /* reserved */ + out_uint8(self->out_s, 0); /* reserved */ + out_uint8(self->out_s, codec_id); + out_uint16_le(self->out_s, width); + out_uint16_le(self->out_s, height); + out_uint32_le(self->out_s, bufsize); + out_uint8a(self->out_s, buf, bufsize); + return 0; } /*****************************************************************************/ /* secondary drawing order (bitmap v3) using remotefx compression */ int APP_CC -xrdp_orders_send_bitmap3(struct xrdp_orders* self, - int width, int height, int bpp, char* data, +xrdp_orders_send_bitmap3(struct xrdp_orders *self, + int width, int height, int bpp, char *data, int cache_id, int cache_idx, int hints) { - int e; - int bufsize; - int quality; - struct stream* xr_s; /* xrdp stream */ - struct stream* temp_s; /* xrdp stream */ - struct xrdp_client_info* ci; + int e; + int bufsize; + int quality; + struct stream *xr_s; /* xrdp stream */ + struct stream *temp_s; /* xrdp stream */ + struct xrdp_client_info *ci; #if defined(XRDP_FREERDP1) - STREAM* fr_s; /* FreeRDP stream */ - RFX_CONTEXT* context; - RFX_RECT rect; + STREAM *fr_s; /* FreeRDP stream */ + RFX_CONTEXT *context; + RFX_RECT rect; #endif - ci = &(self->rdp_layer->client_info); - if (ci->v3_codec_id == 0) - { - return 2; - } - if (ci->v3_codec_id == ci->rfx_codec_id) - { + ci = &(self->rdp_layer->client_info); + + if (ci->v3_codec_id == 0) + { + return 2; + } + + if (ci->v3_codec_id == ci->rfx_codec_id) + { #if defined(XRDP_FREERDP1) - if (!xrdp_orders_send_as_rfx(self, width, height, bpp, hints)) - { - return 2; - } - LLOGLN(10, ("xrdp_orders_send_bitmap3: rfx")); - context = (RFX_CONTEXT*)(self->rdp_layer->rfx_enc); - make_stream(xr_s); - init_stream(xr_s, 16384); - fr_s = stream_new(0); - stream_attach(fr_s, (tui8*)(xr_s->data), 16384); - rect.x = 0; - rect.y = 0; - rect.width = width; - rect.height = height; - rfx_compose_message(context, fr_s, &rect, 1, (tui8*)data, width, - height, width * 4); - bufsize = stream_get_length(fr_s); - xrdp_orders_out_v3(self, cache_id, cache_idx, (char*)(fr_s->data), bufsize, - width, height, bpp,ci->v3_codec_id); - stream_detach(fr_s); - stream_free(fr_s); - free_stream(xr_s); - return 0; + + if (!xrdp_orders_send_as_rfx(self, width, height, bpp, hints)) + { + return 2; + } + + LLOGLN(10, ("xrdp_orders_send_bitmap3: rfx")); + context = (RFX_CONTEXT *)(self->rdp_layer->rfx_enc); + make_stream(xr_s); + init_stream(xr_s, 16384); + fr_s = stream_new(0); + stream_attach(fr_s, (tui8 *)(xr_s->data), 16384); + rect.x = 0; + rect.y = 0; + rect.width = width; + rect.height = height; + rfx_compose_message(context, fr_s, &rect, 1, (tui8 *)data, width, + height, width * 4); + bufsize = stream_get_length(fr_s); + xrdp_orders_out_v3(self, cache_id, cache_idx, (char *)(fr_s->data), bufsize, + width, height, bpp, ci->v3_codec_id); + stream_detach(fr_s); + stream_free(fr_s); + free_stream(xr_s); + return 0; #else - return 2; + return 2; #endif - } - else if (ci->v3_codec_id == ci->jpeg_codec_id) - { -#if defined(XRDP_JPEG) - if (!xrdp_orders_send_as_jpeg(self, width, height, bpp, hints)) + } + else if (ci->v3_codec_id == ci->jpeg_codec_id) { - LLOGLN(10, ("xrdp_orders_send_bitmap3: jpeg skipped")); - return 2; +#if defined(XRDP_JPEG) + + if (!xrdp_orders_send_as_jpeg(self, width, height, bpp, hints)) + { + LLOGLN(10, ("xrdp_orders_send_bitmap3: jpeg skipped")); + return 2; + } + + LLOGLN(10, ("xrdp_orders_send_bitmap3: jpeg")); + e = width % 4; + + if (e != 0) + { + e = 4 - e; + } + + make_stream(xr_s); + init_stream(xr_s, 16384); + make_stream(temp_s); + init_stream(temp_s, 16384); + quality = ci->jpeg_prop[0]; + xrdp_jpeg_compress(data, width, height, xr_s, bpp, 16384, + height - 1, temp_s, e, quality); + s_mark_end(xr_s); + bufsize = (int)(xr_s->end - xr_s->data); + xrdp_orders_out_v3(self, cache_id, cache_idx, (char *)(xr_s->data), bufsize, + width + e, height, bpp, ci->v3_codec_id); + free_stream(xr_s); + free_stream(temp_s); + return 0; +#else + return 2; +#endif } - LLOGLN(10, ("xrdp_orders_send_bitmap3: jpeg")); - e = width % 4; - if (e != 0) + else { - e = 4 - e; + g_writeln("xrdp_orders_send_bitmap3: todo unknown codec"); + return 1; } - make_stream(xr_s); - init_stream(xr_s, 16384); - make_stream(temp_s); - init_stream(temp_s, 16384); - quality = ci->jpeg_prop[0]; - xrdp_jpeg_compress(data, width, height, xr_s, bpp, 16384, - height - 1, temp_s, e, quality); - s_mark_end(xr_s); - bufsize = (int)(xr_s->end - xr_s->data); - xrdp_orders_out_v3(self, cache_id, cache_idx, (char*)(xr_s->data), bufsize, - width + e, height, bpp,ci->v3_codec_id); - free_stream(xr_s); - free_stream(temp_s); + return 0; -#else - return 2; -#endif - } - else - { - g_writeln("xrdp_orders_send_bitmap3: todo unknown codec"); - return 1; - } - return 0; } /*****************************************************************************/ /* returns error */ /* send a brush cache entry */ int APP_CC -xrdp_orders_send_brush(struct xrdp_orders* self, int width, int height, - int bpp, int type, int size, char* data, int cache_id) +xrdp_orders_send_brush(struct xrdp_orders *self, int width, int height, + int bpp, int type, int size, char *data, int cache_id) { - int order_flags = 0; - int len = 0; - - xrdp_orders_check(self, size + 12); - self->order_count++; - order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; - out_uint8(self->out_s, order_flags); - len = (size + 6) - 7; /* length after type minus 7 */ - out_uint16_le(self->out_s, len); - out_uint16_le(self->out_s, 0); /* flags */ - out_uint8(self->out_s, RDP_ORDER_BRUSHCACHE); /* type */ - out_uint8(self->out_s, cache_id); - out_uint8(self->out_s, bpp); - out_uint8(self->out_s, width); - out_uint8(self->out_s, height); - out_uint8(self->out_s, type); - out_uint8(self->out_s, size); - out_uint8a(self->out_s, data, size); - return 0; + int order_flags = 0; + int len = 0; + + xrdp_orders_check(self, size + 12); + self->order_count++; + order_flags = RDP_ORDER_STANDARD | RDP_ORDER_SECONDARY; + out_uint8(self->out_s, order_flags); + len = (size + 6) - 7; /* length after type minus 7 */ + out_uint16_le(self->out_s, len); + out_uint16_le(self->out_s, 0); /* flags */ + out_uint8(self->out_s, RDP_ORDER_BRUSHCACHE); /* type */ + out_uint8(self->out_s, cache_id); + out_uint8(self->out_s, bpp); + out_uint8(self->out_s, width); + out_uint8(self->out_s, height); + out_uint8(self->out_s, type); + out_uint8(self->out_s, size); + out_uint8a(self->out_s, data, size); + return 0; } /*****************************************************************************/ /* returns error */ /* send an off screen bitmap entry */ int APP_CC -xrdp_orders_send_create_os_surface(struct xrdp_orders* self, int id, +xrdp_orders_send_create_os_surface(struct xrdp_orders *self, int id, int width, int height, - struct list* del_list) + struct list *del_list) { - int order_flags; - int cache_id; - int flags; - int index; - int bytes; - int num_del_list; - - bytes = 7; - num_del_list = del_list->count; - if (num_del_list > 0) - { - bytes += 2; - bytes += num_del_list * 2; - } - xrdp_orders_check(self, bytes); - self->order_count++; - order_flags = RDP_ORDER_SECONDARY; - order_flags |= 1 << 2; /* type RDP_ORDER_ALTSEC_CREATE_OFFSCR_BITMAP */ - out_uint8(self->out_s, order_flags); - cache_id = id & 0x7fff; - flags = cache_id; - if (num_del_list > 0) - { - flags |= 0x8000; - } - out_uint16_le(self->out_s, flags); - out_uint16_le(self->out_s, width); - out_uint16_le(self->out_s, height); - if (num_del_list > 0) - { - /* delete list */ - out_uint16_le(self->out_s, num_del_list); - for (index = 0; index < num_del_list; index++) - { - cache_id = list_get_item(del_list, index) & 0x7fff; - out_uint16_le(self->out_s, cache_id); - } - } - return 0; + int order_flags; + int cache_id; + int flags; + int index; + int bytes; + int num_del_list; + + bytes = 7; + num_del_list = del_list->count; + + if (num_del_list > 0) + { + bytes += 2; + bytes += num_del_list * 2; + } + + xrdp_orders_check(self, bytes); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 1 << 2; /* type RDP_ORDER_ALTSEC_CREATE_OFFSCR_BITMAP */ + out_uint8(self->out_s, order_flags); + cache_id = id & 0x7fff; + flags = cache_id; + + if (num_del_list > 0) + { + flags |= 0x8000; + } + + out_uint16_le(self->out_s, flags); + out_uint16_le(self->out_s, width); + out_uint16_le(self->out_s, height); + + if (num_del_list > 0) + { + /* delete list */ + out_uint16_le(self->out_s, num_del_list); + + for (index = 0; index < num_del_list; index++) + { + cache_id = list_get_item(del_list, index) & 0x7fff; + out_uint16_le(self->out_s, cache_id); + } + } + + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_orders_send_switch_os_surface(struct xrdp_orders* self, int id) +xrdp_orders_send_switch_os_surface(struct xrdp_orders *self, int id) { - int order_flags; - int cache_id; - - xrdp_orders_check(self, 3); - self->order_count++; - order_flags = RDP_ORDER_SECONDARY; - order_flags |= 0 << 2; /* type RDP_ORDER_ALTSEC_SWITCH_SURFACE */ - out_uint8(self->out_s, order_flags); - cache_id = id & 0xffff; - out_uint16_le(self->out_s, cache_id); - return 0; + int order_flags; + int cache_id; + + xrdp_orders_check(self, 3); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0 << 2; /* type RDP_ORDER_ALTSEC_SWITCH_SURFACE */ + out_uint8(self->out_s, order_flags); + cache_id = id & 0xffff; + out_uint16_le(self->out_s, cache_id); + return 0; } diff --git a/libxrdp/xrdp_orders_rail.c b/libxrdp/xrdp_orders_rail.c index 62f9b8ea..3ac0fd2a 100644 --- a/libxrdp/xrdp_orders_rail.c +++ b/libxrdp/xrdp_orders_rail.c @@ -27,26 +27,26 @@ /* RAIL */ /* returns error */ int APP_CC -xrdp_orders_send_window_delete(struct xrdp_orders* self, int window_id) +xrdp_orders_send_window_delete(struct xrdp_orders *self, int window_id) { - int order_size; - int order_flags; - int field_present_flags; - - order_size = 11; - xrdp_orders_check(self, order_size); - self->order_count++; - order_flags = RDP_ORDER_SECONDARY; - order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ - out_uint8(self->out_s, order_flags); - /* orderSize (2 bytes) */ - out_uint16_le(self->out_s, order_size); - /* FieldsPresentFlags (4 bytes) */ - field_present_flags = WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_STATE_DELETED; - out_uint32_le(self->out_s, field_present_flags); - /* windowId (4 bytes) */ - out_uint32_le(self->out_s, window_id); - return 0; + int order_size; + int order_flags; + int field_present_flags; + + order_size = 11; + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + field_present_flags = WINDOW_ORDER_TYPE_WINDOW | WINDOW_ORDER_STATE_DELETED; + out_uint32_le(self->out_s, field_present_flags); + /* windowId (4 bytes) */ + out_uint32_le(self->out_s, window_id); + return 0; } /*****************************************************************************/ @@ -55,69 +55,74 @@ xrdp_orders_send_window_delete(struct xrdp_orders* self, int window_id) /* flags can contain WINDOW_ORDER_STATE_NEW and/or WINDOW_ORDER_FIELD_ICON_BIG */ int APP_CC -xrdp_orders_send_window_cached_icon(struct xrdp_orders* self, +xrdp_orders_send_window_cached_icon(struct xrdp_orders *self, int window_id, int cache_entry, int cache_id, int flags) { - int order_size; - int order_flags; - int field_present_flags; - - order_size = 14; - xrdp_orders_check(self, order_size); - self->order_count++; - order_flags = RDP_ORDER_SECONDARY; - order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ - out_uint8(self->out_s, order_flags); - /* orderSize (2 bytes) */ - out_uint16_le(self->out_s, order_size); - /* FieldsPresentFlags (4 bytes) */ - field_present_flags = flags | WINDOW_ORDER_TYPE_WINDOW | - WINDOW_ORDER_CACHED_ICON; - out_uint32_le(self->out_s, field_present_flags); - /* windowId (4 bytes) */ - out_uint32_le(self->out_s, window_id); - /* CacheEntry (2 bytes) */ - out_uint16_le(self->out_s, cache_entry); - /* CacheId (1 byte) */ - out_uint8(self->out_s, cache_id); - return 0; + int order_size; + int order_flags; + int field_present_flags; + + order_size = 14; + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + field_present_flags = flags | WINDOW_ORDER_TYPE_WINDOW | + WINDOW_ORDER_CACHED_ICON; + out_uint32_le(self->out_s, field_present_flags); + /* windowId (4 bytes) */ + out_uint32_le(self->out_s, window_id); + /* CacheEntry (2 bytes) */ + out_uint16_le(self->out_s, cache_entry); + /* CacheId (1 byte) */ + out_uint8(self->out_s, cache_id); + return 0; } /*****************************************************************************/ /* RAIL */ /* returns error */ static int APP_CC -xrdp_orders_send_ts_icon(struct stream* s, int cache_entry, int cache_id, - struct rail_icon_info* icon_info) +xrdp_orders_send_ts_icon(struct stream *s, int cache_entry, int cache_id, + struct rail_icon_info *icon_info) { - int use_cmap; - - use_cmap = 0; - if ((icon_info->bpp == 1) || (icon_info->bpp == 2) || (icon_info->bpp == 4)) - { - use_cmap = 1; - } - - /* TS_ICON_INFO */ - out_uint16_le(s, cache_entry); - out_uint8(s, cache_id); - out_uint8(s, icon_info->bpp); - out_uint16_le(s, icon_info->width); - out_uint16_le(s, icon_info->height); - if (use_cmap) - { - out_uint16_le(s, icon_info->cmap_bytes); - } - out_uint16_le(s, icon_info->mask_bytes); - out_uint16_le(s, icon_info->data_bytes); - out_uint8p(s, icon_info->mask, icon_info->mask_bytes); - if (use_cmap) - { - out_uint8p(s, icon_info->cmap, icon_info->cmap_bytes); - } - out_uint8p(s, icon_info->data, icon_info->data_bytes); - return 0; + int use_cmap; + + use_cmap = 0; + + if ((icon_info->bpp == 1) || (icon_info->bpp == 2) || (icon_info->bpp == 4)) + { + use_cmap = 1; + } + + /* TS_ICON_INFO */ + out_uint16_le(s, cache_entry); + out_uint8(s, cache_id); + out_uint8(s, icon_info->bpp); + out_uint16_le(s, icon_info->width); + out_uint16_le(s, icon_info->height); + + if (use_cmap) + { + out_uint16_le(s, icon_info->cmap_bytes); + } + + out_uint16_le(s, icon_info->mask_bytes); + out_uint16_le(s, icon_info->data_bytes); + out_uint8p(s, icon_info->mask, icon_info->mask_bytes); + + if (use_cmap) + { + out_uint8p(s, icon_info->cmap, icon_info->cmap_bytes); + } + + out_uint8p(s, icon_info->data, icon_info->data_bytes); + return 0; } /*****************************************************************************/ @@ -126,71 +131,78 @@ xrdp_orders_send_ts_icon(struct stream* s, int cache_entry, int cache_id, /* flags can contain WINDOW_ORDER_STATE_NEW and/or WINDOW_ORDER_FIELD_ICON_BIG */ int APP_CC -xrdp_orders_send_window_icon(struct xrdp_orders* self, +xrdp_orders_send_window_icon(struct xrdp_orders *self, int window_id, int cache_entry, int cache_id, - struct rail_icon_info* icon_info, + struct rail_icon_info *icon_info, int flags) { - int order_size; - int order_flags; - int field_present_flags; - int use_cmap; - - use_cmap = 0; - if ((icon_info->bpp == 1) || (icon_info->bpp == 2) || (icon_info->bpp == 4)) - { - use_cmap = 1; - } - order_size = 23 + icon_info->mask_bytes + icon_info->data_bytes; - if (use_cmap) - { - order_size += icon_info->cmap_bytes + 2; - } - xrdp_orders_check(self, order_size); - self->order_count++; - order_flags = RDP_ORDER_SECONDARY; - order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ - out_uint8(self->out_s, order_flags); - /* orderSize (2 bytes) */ - out_uint16_le(self->out_s, order_size); - /* FieldsPresentFlags (4 bytes) */ - field_present_flags = flags | WINDOW_ORDER_TYPE_WINDOW | - WINDOW_ORDER_ICON; - out_uint32_le(self->out_s, field_present_flags); - /* windowId (4 bytes) */ - out_uint32_le(self->out_s, window_id); - - xrdp_orders_send_ts_icon(self->out_s, cache_entry, cache_id, icon_info); - - return 0; + int order_size; + int order_flags; + int field_present_flags; + int use_cmap; + + use_cmap = 0; + + if ((icon_info->bpp == 1) || (icon_info->bpp == 2) || (icon_info->bpp == 4)) + { + use_cmap = 1; + } + + order_size = 23 + icon_info->mask_bytes + icon_info->data_bytes; + + if (use_cmap) + { + order_size += icon_info->cmap_bytes + 2; + } + + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + field_present_flags = flags | WINDOW_ORDER_TYPE_WINDOW | + WINDOW_ORDER_ICON; + out_uint32_le(self->out_s, field_present_flags); + /* windowId (4 bytes) */ + out_uint32_le(self->out_s, window_id); + + xrdp_orders_send_ts_icon(self->out_s, cache_entry, cache_id, icon_info); + + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_orders_send_as_unicode(struct stream* s, const char* text) +xrdp_orders_send_as_unicode(struct stream *s, const char *text) { - int str_chars; - int index; - int i32; - twchar wdst[256]; - - str_chars = g_mbstowcs(wdst, text, 255); - if (str_chars > 0) - { - i32 = str_chars * 2; - out_uint16_le(s, i32); - for (index = 0; index < str_chars; index++) - { - i32 = wdst[index]; - out_uint16_le(s, i32); - } - } - else - { - out_uint16_le(s, 0); - } - return 0; + int str_chars; + int index; + int i32; + twchar wdst[256]; + + str_chars = g_mbstowcs(wdst, text, 255); + + if (str_chars > 0) + { + i32 = str_chars * 2; + out_uint16_le(s, i32); + + for (index = 0; index < str_chars; index++) + { + i32 = wdst[index]; + out_uint16_le(s, i32); + } + } + else + { + out_uint16_le(s, 0); + } + + return 0; } /*****************************************************************************/ @@ -198,247 +210,276 @@ xrdp_orders_send_as_unicode(struct stream* s, const char* text) /* returns error */ /* flags can contain WINDOW_ORDER_STATE_NEW */ int APP_CC -xrdp_orders_send_window_new_update(struct xrdp_orders* self, int window_id, - struct rail_window_state_order* window_state, +xrdp_orders_send_window_new_update(struct xrdp_orders *self, int window_id, + struct rail_window_state_order *window_state, int flags) { - int order_size; - int order_flags; - int field_present_flags; - int num_chars; - int index; - - order_size = 11; - field_present_flags = flags | WINDOW_ORDER_TYPE_WINDOW; - if (field_present_flags & WINDOW_ORDER_FIELD_OWNER) - { - /* ownerWindowId (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_STYLE) - { - /* style (4 bytes) */ - order_size += 4; - /* extendedStyle (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_SHOW) - { - /* showState (1 byte) */ - order_size += 1; - } - if (field_present_flags & WINDOW_ORDER_FIELD_TITLE) - { - /* titleInfo */ - num_chars = g_mbstowcs(0, window_state->title_info, 0); - order_size += 2 * num_chars + 2; - } - if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) - { - /* clientOffsetX (4 bytes) */ - order_size += 4; - /* clientOffsetY (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) - { - /* clientAreaWidth (4 bytes) */ - order_size += 4; - /* clientAreaHeight (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_RP_CONTENT) - { - /* RPContent (1 byte) */ - order_size += 1; - } - if (field_present_flags & WINDOW_ORDER_FIELD_ROOT_PARENT) - { - /* rootParentHandle (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_WND_OFFSET) - { - /* windowOffsetX (4 bytes) */ - order_size += 4; - /* windowOffsetY (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) - { - /* windowClientDeltaX (4 bytes) */ - order_size += 4; - /* windowClientDeltaY (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_WND_SIZE) - { - /* windowWidth (4 bytes) */ - order_size += 4; - /* windowHeight (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_WND_RECTS) - { - /* numWindowRects (2 bytes) */ - order_size += 2; - order_size += 8 * window_state->num_window_rects; - } - if (field_present_flags & WINDOW_ORDER_FIELD_VIS_OFFSET) - { - /* visibleOffsetX (4 bytes) */ - order_size += 4; - /* visibleOffsetY (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_VISIBILITY) - { - /* numVisibilityRects (2 bytes) */ - order_size += 2; - order_size += 8 * window_state->num_visibility_rects; - } - - xrdp_orders_check(self, order_size); - self->order_count++; - order_flags = RDP_ORDER_SECONDARY; - order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ - out_uint8(self->out_s, order_flags); - /* orderSize (2 bytes) */ - out_uint16_le(self->out_s, order_size); - /* FieldsPresentFlags (4 bytes) */ - out_uint32_le(self->out_s, field_present_flags); - /* windowId (4 bytes) */ - out_uint32_le(self->out_s, window_id); - - if (field_present_flags & WINDOW_ORDER_FIELD_OWNER) - { - /* ownerWindowId (4 bytes) */ - out_uint32_le(self->out_s, window_state->owner_window_id); - } - if (field_present_flags & WINDOW_ORDER_FIELD_STYLE) - { - /* style (4 bytes) */ - out_uint32_le(self->out_s, window_state->style); - /* extendedStyle (4 bytes) */ - out_uint32_le(self->out_s, window_state->extended_style); - } - if (field_present_flags & WINDOW_ORDER_FIELD_SHOW) - { - /* showState (1 byte) */ - out_uint8(self->out_s, window_state->show_state); - } - if (field_present_flags & WINDOW_ORDER_FIELD_TITLE) - { - /* titleInfo */ - xrdp_orders_send_as_unicode(self->out_s, window_state->title_info); - } - if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) - { - /* clientOffsetX (4 bytes) */ - out_uint32_le(self->out_s, window_state->client_offset_x); - /* clientOffsetY (4 bytes) */ - out_uint32_le(self->out_s, window_state->client_offset_y); - } - if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) - { - /* clientAreaWidth (4 bytes) */ - out_uint32_le(self->out_s, window_state->client_area_width); - /* clientAreaHeight (4 bytes) */ - out_uint32_le(self->out_s, window_state->client_area_height); - } - if (field_present_flags & WINDOW_ORDER_FIELD_RP_CONTENT) - { - /* RPContent (1 byte) */ - out_uint8(self->out_s, window_state->rp_content); - } - if (field_present_flags & WINDOW_ORDER_FIELD_ROOT_PARENT) - { - /* rootParentHandle (4 bytes) */ - out_uint32_le(self->out_s, window_state->root_parent_handle); - } - if (field_present_flags & WINDOW_ORDER_FIELD_WND_OFFSET) - { - /* windowOffsetX (4 bytes) */ - out_uint32_le(self->out_s, window_state->window_offset_x); - /* windowOffsetY (4 bytes) */ - out_uint32_le(self->out_s, window_state->window_offset_y); - } - if (field_present_flags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) - { - /* windowClientDeltaX (4 bytes) */ - out_uint32_le(self->out_s, window_state->window_client_delta_x); - /* windowClientDeltaY (4 bytes) */ - out_uint32_le(self->out_s, window_state->window_client_delta_y); - } - if (field_present_flags & WINDOW_ORDER_FIELD_WND_SIZE) - { - /* windowWidth (4 bytes) */ - out_uint32_le(self->out_s, window_state->window_width); - /* windowHeight (4 bytes) */ - out_uint32_le(self->out_s, window_state->window_height); - } - if (field_present_flags & WINDOW_ORDER_FIELD_WND_RECTS) - { - /* numWindowRects (2 bytes) */ - out_uint16_le(self->out_s, window_state->num_window_rects); - for (index = 0; index < window_state->num_window_rects; index++) - { - out_uint16_le(self->out_s, window_state->window_rects[index].left); - out_uint16_le(self->out_s, window_state->window_rects[index].top); - out_uint16_le(self->out_s, window_state->window_rects[index].right); - out_uint16_le(self->out_s, window_state->window_rects[index].bottom); - } - } - if (field_present_flags & WINDOW_ORDER_FIELD_VIS_OFFSET) - { - /* visibleOffsetX (4 bytes) */ - out_uint32_le(self->out_s, window_state->visible_offset_x); - /* visibleOffsetY (4 bytes) */ - out_uint32_le(self->out_s, window_state->visible_offset_y); - } - if (field_present_flags & WINDOW_ORDER_FIELD_VISIBILITY) - { - /* numVisibilityRects (2 bytes) */ - out_uint16_le(self->out_s, window_state->num_visibility_rects); - for (index = 0; index < window_state->num_visibility_rects; index++) - { - out_uint16_le(self->out_s, window_state->visibility_rects[index].left); - out_uint16_le(self->out_s, window_state->visibility_rects[index].top); - out_uint16_le(self->out_s, window_state->visibility_rects[index].right); - out_uint16_le(self->out_s, window_state->visibility_rects[index].bottom); - } - } - - return 0; + int order_size; + int order_flags; + int field_present_flags; + int num_chars; + int index; + + order_size = 11; + field_present_flags = flags | WINDOW_ORDER_TYPE_WINDOW; + + if (field_present_flags & WINDOW_ORDER_FIELD_OWNER) + { + /* ownerWindowId (4 bytes) */ + order_size += 4; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_STYLE) + { + /* style (4 bytes) */ + order_size += 4; + /* extendedStyle (4 bytes) */ + order_size += 4; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_SHOW) + { + /* showState (1 byte) */ + order_size += 1; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_TITLE) + { + /* titleInfo */ + num_chars = g_mbstowcs(0, window_state->title_info, 0); + order_size += 2 * num_chars + 2; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) + { + /* clientOffsetX (4 bytes) */ + order_size += 4; + /* clientOffsetY (4 bytes) */ + order_size += 4; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) + { + /* clientAreaWidth (4 bytes) */ + order_size += 4; + /* clientAreaHeight (4 bytes) */ + order_size += 4; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_RP_CONTENT) + { + /* RPContent (1 byte) */ + order_size += 1; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_ROOT_PARENT) + { + /* rootParentHandle (4 bytes) */ + order_size += 4; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_WND_OFFSET) + { + /* windowOffsetX (4 bytes) */ + order_size += 4; + /* windowOffsetY (4 bytes) */ + order_size += 4; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) + { + /* windowClientDeltaX (4 bytes) */ + order_size += 4; + /* windowClientDeltaY (4 bytes) */ + order_size += 4; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_WND_SIZE) + { + /* windowWidth (4 bytes) */ + order_size += 4; + /* windowHeight (4 bytes) */ + order_size += 4; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_WND_RECTS) + { + /* numWindowRects (2 bytes) */ + order_size += 2; + order_size += 8 * window_state->num_window_rects; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_VIS_OFFSET) + { + /* visibleOffsetX (4 bytes) */ + order_size += 4; + /* visibleOffsetY (4 bytes) */ + order_size += 4; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_VISIBILITY) + { + /* numVisibilityRects (2 bytes) */ + order_size += 2; + order_size += 8 * window_state->num_visibility_rects; + } + + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + out_uint32_le(self->out_s, field_present_flags); + /* windowId (4 bytes) */ + out_uint32_le(self->out_s, window_id); + + if (field_present_flags & WINDOW_ORDER_FIELD_OWNER) + { + /* ownerWindowId (4 bytes) */ + out_uint32_le(self->out_s, window_state->owner_window_id); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_STYLE) + { + /* style (4 bytes) */ + out_uint32_le(self->out_s, window_state->style); + /* extendedStyle (4 bytes) */ + out_uint32_le(self->out_s, window_state->extended_style); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_SHOW) + { + /* showState (1 byte) */ + out_uint8(self->out_s, window_state->show_state); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_TITLE) + { + /* titleInfo */ + xrdp_orders_send_as_unicode(self->out_s, window_state->title_info); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_OFFSET) + { + /* clientOffsetX (4 bytes) */ + out_uint32_le(self->out_s, window_state->client_offset_x); + /* clientOffsetY (4 bytes) */ + out_uint32_le(self->out_s, window_state->client_offset_y); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_CLIENT_AREA_SIZE) + { + /* clientAreaWidth (4 bytes) */ + out_uint32_le(self->out_s, window_state->client_area_width); + /* clientAreaHeight (4 bytes) */ + out_uint32_le(self->out_s, window_state->client_area_height); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_RP_CONTENT) + { + /* RPContent (1 byte) */ + out_uint8(self->out_s, window_state->rp_content); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_ROOT_PARENT) + { + /* rootParentHandle (4 bytes) */ + out_uint32_le(self->out_s, window_state->root_parent_handle); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_WND_OFFSET) + { + /* windowOffsetX (4 bytes) */ + out_uint32_le(self->out_s, window_state->window_offset_x); + /* windowOffsetY (4 bytes) */ + out_uint32_le(self->out_s, window_state->window_offset_y); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_WND_CLIENT_DELTA) + { + /* windowClientDeltaX (4 bytes) */ + out_uint32_le(self->out_s, window_state->window_client_delta_x); + /* windowClientDeltaY (4 bytes) */ + out_uint32_le(self->out_s, window_state->window_client_delta_y); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_WND_SIZE) + { + /* windowWidth (4 bytes) */ + out_uint32_le(self->out_s, window_state->window_width); + /* windowHeight (4 bytes) */ + out_uint32_le(self->out_s, window_state->window_height); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_WND_RECTS) + { + /* numWindowRects (2 bytes) */ + out_uint16_le(self->out_s, window_state->num_window_rects); + + for (index = 0; index < window_state->num_window_rects; index++) + { + out_uint16_le(self->out_s, window_state->window_rects[index].left); + out_uint16_le(self->out_s, window_state->window_rects[index].top); + out_uint16_le(self->out_s, window_state->window_rects[index].right); + out_uint16_le(self->out_s, window_state->window_rects[index].bottom); + } + } + + if (field_present_flags & WINDOW_ORDER_FIELD_VIS_OFFSET) + { + /* visibleOffsetX (4 bytes) */ + out_uint32_le(self->out_s, window_state->visible_offset_x); + /* visibleOffsetY (4 bytes) */ + out_uint32_le(self->out_s, window_state->visible_offset_y); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_VISIBILITY) + { + /* numVisibilityRects (2 bytes) */ + out_uint16_le(self->out_s, window_state->num_visibility_rects); + + for (index = 0; index < window_state->num_visibility_rects; index++) + { + out_uint16_le(self->out_s, window_state->visibility_rects[index].left); + out_uint16_le(self->out_s, window_state->visibility_rects[index].top); + out_uint16_le(self->out_s, window_state->visibility_rects[index].right); + out_uint16_le(self->out_s, window_state->visibility_rects[index].bottom); + } + } + + return 0; } /*****************************************************************************/ /* RAIL */ /* returns error */ int APP_CC -xrdp_orders_send_notify_delete(struct xrdp_orders* self, int window_id, +xrdp_orders_send_notify_delete(struct xrdp_orders *self, int window_id, int notify_id) { - int order_size; - int order_flags; - int field_present_flags; - - order_size = 15; - xrdp_orders_check(self, order_size); - self->order_count++; - order_flags = RDP_ORDER_SECONDARY; - order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ - out_uint8(self->out_s, order_flags); - /* orderSize (2 bytes) */ - out_uint16_le(self->out_s, order_size); - /* FieldsPresentFlags (4 bytes) */ - field_present_flags = WINDOW_ORDER_TYPE_NOTIFY | WINDOW_ORDER_STATE_DELETED; - out_uint32_le(self->out_s, field_present_flags); - /* windowId (4 bytes) */ - out_uint32_le(self->out_s, window_id); - /* notifyIconId (4 bytes) */ - out_uint32_le(self->out_s, notify_id); - return 0; + int order_size; + int order_flags; + int field_present_flags; + + order_size = 15; + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + field_present_flags = WINDOW_ORDER_TYPE_NOTIFY | WINDOW_ORDER_STATE_DELETED; + out_uint32_le(self->out_s, field_present_flags); + /* windowId (4 bytes) */ + out_uint32_le(self->out_s, window_id); + /* notifyIconId (4 bytes) */ + out_uint32_le(self->out_s, notify_id); + return 0; } /*****************************************************************************/ @@ -446,123 +487,137 @@ xrdp_orders_send_notify_delete(struct xrdp_orders* self, int window_id, /* returns error */ /* flags can contain WINDOW_ORDER_STATE_NEW */ int APP_CC -xrdp_orders_send_notify_new_update(struct xrdp_orders* self, +xrdp_orders_send_notify_new_update(struct xrdp_orders *self, int window_id, int notify_id, - struct rail_notify_state_order* notify_state, + struct rail_notify_state_order *notify_state, int flags) { - int order_size; - int order_flags; - int field_present_flags; - int num_chars; - int use_cmap; - - order_size = 15; - field_present_flags = flags | WINDOW_ORDER_TYPE_NOTIFY; - if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_VERSION) - { - /* Version (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_TIP) - { - /* ToolTip (variable) UNICODE_STRING */ - num_chars = g_mbstowcs(0, notify_state->tool_tip, 0); - order_size += 2 * num_chars + 2; - } - if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) - { - /* InfoTip (variable) TS_NOTIFY_ICON_INFOTIP */ - /* UNICODE_STRING */ - num_chars = g_mbstowcs(0, notify_state->infotip.title, 0); - order_size += 2 * num_chars + 2; - /* UNICODE_STRING */ - num_chars = g_mbstowcs(0, notify_state->infotip.text, 0); - order_size += 2 * num_chars + 2; - /* Timeout (4 bytes) */ - /* InfoFlags (4 bytes) */ - order_size += 8; - } - if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_STATE) - { - /* State (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_ICON) - { - /* Icon (variable) */ - use_cmap = 0; - if ((notify_state->icon_info.bpp == 1) || (notify_state->icon_info.bpp == 2) || - (notify_state->icon_info.bpp == 4)) + int order_size; + int order_flags; + int field_present_flags; + int num_chars; + int use_cmap; + + order_size = 15; + field_present_flags = flags | WINDOW_ORDER_TYPE_NOTIFY; + + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_VERSION) { - use_cmap = 1; + /* Version (4 bytes) */ + order_size += 4; } - order_size += 12 + notify_state->icon_info.mask_bytes + - notify_state->icon_info.data_bytes; - if (use_cmap) + + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_TIP) { - order_size += notify_state->icon_info.cmap_bytes + 2; - } - } - if (field_present_flags & WINDOW_ORDER_CACHED_ICON) - { - /* CachedIcon (3 bytes) */ - order_size += 3; - } - - xrdp_orders_check(self, order_size); - self->order_count++; - order_flags = RDP_ORDER_SECONDARY; - order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ - out_uint8(self->out_s, order_flags); - /* orderSize (2 bytes) */ - out_uint16_le(self->out_s, order_size); - /* FieldsPresentFlags (4 bytes) */ - out_uint32_le(self->out_s, field_present_flags); - /* windowId (4 bytes) */ - out_uint32_le(self->out_s, window_id); - /* notifyIconId (4 bytes) */ - out_uint32_le(self->out_s, notify_id); - - if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_VERSION) - { - /* Version (4 bytes) */ - out_uint32_le(self->out_s, notify_state->version); - } - if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_TIP) - { - /* ToolTip (variable) UNICODE_STRING */ - xrdp_orders_send_as_unicode(self->out_s, notify_state->tool_tip); - } - if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) - { - /* InfoTip (variable) TS_NOTIFY_ICON_INFOTIP */ - out_uint32_le(self->out_s, notify_state->infotip.timeout); - out_uint32_le(self->out_s, notify_state->infotip.flags); - xrdp_orders_send_as_unicode(self->out_s, notify_state->infotip.text); - xrdp_orders_send_as_unicode(self->out_s, notify_state->infotip.title); - } - if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_STATE) - { - /* State (4 bytes) */ - out_uint32_le(self->out_s, notify_state->state); - } - if (field_present_flags & WINDOW_ORDER_ICON) - { - /* Icon (variable) */ - xrdp_orders_send_ts_icon(self->out_s, notify_state->icon_cache_entry, - notify_state->icon_cache_id, - ¬ify_state->icon_info); - } - if (field_present_flags & WINDOW_ORDER_CACHED_ICON) - { - /* CacheEntry (2 bytes) */ - out_uint16_le(self->out_s, notify_state->icon_cache_entry); - /* CacheId (1 byte) */ - out_uint8(self->out_s, notify_state->icon_cache_id); - } + /* ToolTip (variable) UNICODE_STRING */ + num_chars = g_mbstowcs(0, notify_state->tool_tip, 0); + order_size += 2 * num_chars + 2; + } - return 0; + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) + { + /* InfoTip (variable) TS_NOTIFY_ICON_INFOTIP */ + /* UNICODE_STRING */ + num_chars = g_mbstowcs(0, notify_state->infotip.title, 0); + order_size += 2 * num_chars + 2; + /* UNICODE_STRING */ + num_chars = g_mbstowcs(0, notify_state->infotip.text, 0); + order_size += 2 * num_chars + 2; + /* Timeout (4 bytes) */ + /* InfoFlags (4 bytes) */ + order_size += 8; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_STATE) + { + /* State (4 bytes) */ + order_size += 4; + } + + if (field_present_flags & WINDOW_ORDER_ICON) + { + /* Icon (variable) */ + use_cmap = 0; + + if ((notify_state->icon_info.bpp == 1) || (notify_state->icon_info.bpp == 2) || + (notify_state->icon_info.bpp == 4)) + { + use_cmap = 1; + } + + order_size += 12 + notify_state->icon_info.mask_bytes + + notify_state->icon_info.data_bytes; + + if (use_cmap) + { + order_size += notify_state->icon_info.cmap_bytes + 2; + } + } + + if (field_present_flags & WINDOW_ORDER_CACHED_ICON) + { + /* CachedIcon (3 bytes) */ + order_size += 3; + } + + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + out_uint32_le(self->out_s, field_present_flags); + /* windowId (4 bytes) */ + out_uint32_le(self->out_s, window_id); + /* notifyIconId (4 bytes) */ + out_uint32_le(self->out_s, notify_id); + + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_VERSION) + { + /* Version (4 bytes) */ + out_uint32_le(self->out_s, notify_state->version); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_TIP) + { + /* ToolTip (variable) UNICODE_STRING */ + xrdp_orders_send_as_unicode(self->out_s, notify_state->tool_tip); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_INFO_TIP) + { + /* InfoTip (variable) TS_NOTIFY_ICON_INFOTIP */ + out_uint32_le(self->out_s, notify_state->infotip.timeout); + out_uint32_le(self->out_s, notify_state->infotip.flags); + xrdp_orders_send_as_unicode(self->out_s, notify_state->infotip.text); + xrdp_orders_send_as_unicode(self->out_s, notify_state->infotip.title); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_NOTIFY_STATE) + { + /* State (4 bytes) */ + out_uint32_le(self->out_s, notify_state->state); + } + + if (field_present_flags & WINDOW_ORDER_ICON) + { + /* Icon (variable) */ + xrdp_orders_send_ts_icon(self->out_s, notify_state->icon_cache_entry, + notify_state->icon_cache_id, + ¬ify_state->icon_info); + } + + if (field_present_flags & WINDOW_ORDER_CACHED_ICON) + { + /* CacheEntry (2 bytes) */ + out_uint16_le(self->out_s, notify_state->icon_cache_entry); + /* CacheId (1 byte) */ + out_uint8(self->out_s, notify_state->icon_cache_id); + } + + return 0; } /*****************************************************************************/ @@ -570,56 +625,59 @@ xrdp_orders_send_notify_new_update(struct xrdp_orders* self, /* returns error */ /* used for both Non-Monitored Desktop and Actively Monitored Desktop */ int APP_CC -xrdp_orders_send_monitored_desktop(struct xrdp_orders* self, - struct rail_monitored_desktop_order* mdo, +xrdp_orders_send_monitored_desktop(struct xrdp_orders *self, + struct rail_monitored_desktop_order *mdo, int flags) { - int order_size; - int order_flags; - int field_present_flags; - int index; - - order_size = 7; - field_present_flags = flags | WINDOW_ORDER_TYPE_DESKTOP; - - if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND) - { - /* ActiveWindowId (4 bytes) */ - order_size += 4; - } - if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER) - { - /* NumWindowIds (1 byte) */ - order_size += 1; - /* WindowIds (variable) */ - order_size += mdo->num_window_ids * 4; - } - - xrdp_orders_check(self, order_size); - self->order_count++; - order_flags = RDP_ORDER_SECONDARY; - order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ - out_uint8(self->out_s, order_flags); - /* orderSize (2 bytes) */ - out_uint16_le(self->out_s, order_size); - /* FieldsPresentFlags (4 bytes) */ - out_uint32_le(self->out_s, field_present_flags); - - if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND) - { - /* ActiveWindowId (4 bytes) */ - out_uint32_le(self->out_s, mdo->active_window_id); - } - if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER) - { - /* NumWindowIds (1 byte) */ - out_uint8(self->out_s, mdo->num_window_ids); - /* WindowIds (variable) */ - for (index = 0; index < mdo->num_window_ids; index++) - { - out_uint32_le(self->out_s, mdo->window_ids[index]); - } - } - - return 0; + int order_size; + int order_flags; + int field_present_flags; + int index; + + order_size = 7; + field_present_flags = flags | WINDOW_ORDER_TYPE_DESKTOP; + + if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND) + { + /* ActiveWindowId (4 bytes) */ + order_size += 4; + } + + if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER) + { + /* NumWindowIds (1 byte) */ + order_size += 1; + /* WindowIds (variable) */ + order_size += mdo->num_window_ids * 4; + } + + xrdp_orders_check(self, order_size); + self->order_count++; + order_flags = RDP_ORDER_SECONDARY; + order_flags |= 0xb << 2; /* type TS_ALTSEC_WINDOW */ + out_uint8(self->out_s, order_flags); + /* orderSize (2 bytes) */ + out_uint16_le(self->out_s, order_size); + /* FieldsPresentFlags (4 bytes) */ + out_uint32_le(self->out_s, field_present_flags); + + if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ACTIVE_WND) + { + /* ActiveWindowId (4 bytes) */ + out_uint32_le(self->out_s, mdo->active_window_id); + } + + if (field_present_flags & WINDOW_ORDER_FIELD_DESKTOP_ZORDER) + { + /* NumWindowIds (1 byte) */ + out_uint8(self->out_s, mdo->num_window_ids); + + /* WindowIds (variable) */ + for (index = 0; index < mdo->num_window_ids; index++) + { + out_uint32_le(self->out_s, mdo->window_ids[index]); + } + } + + return 0; } diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index 53e3ddc2..bf0f8f4e 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -1,24 +1,22 @@ -/* - 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. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - rdp layer - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * rdp layer + */ #include "libxrdp.h" @@ -29,28 +27,30 @@ /* some compilers need unsigned char to avoid warnings */ static tui8 g_unknown1[172] = -{ 0xff, 0x02, 0xb6, 0x00, 0x28, 0x00, 0x00, 0x00, - 0x27, 0x00, 0x27, 0x00, 0x03, 0x00, 0x04, 0x00, - 0x00, 0x00, 0x26, 0x00, 0x01, 0x00, 0x1e, 0x00, - 0x02, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x1d, 0x00, - 0x04, 0x00, 0x27, 0x00, 0x05, 0x00, 0x0b, 0x00, - 0x06, 0x00, 0x28, 0x00, 0x08, 0x00, 0x21, 0x00, - 0x09, 0x00, 0x20, 0x00, 0x0a, 0x00, 0x22, 0x00, - 0x0b, 0x00, 0x25, 0x00, 0x0c, 0x00, 0x24, 0x00, - 0x0d, 0x00, 0x23, 0x00, 0x0e, 0x00, 0x19, 0x00, - 0x0f, 0x00, 0x16, 0x00, 0x10, 0x00, 0x15, 0x00, - 0x11, 0x00, 0x1c, 0x00, 0x12, 0x00, 0x1b, 0x00, - 0x13, 0x00, 0x1a, 0x00, 0x14, 0x00, 0x17, 0x00, - 0x15, 0x00, 0x18, 0x00, 0x16, 0x00, 0x0e, 0x00, - 0x18, 0x00, 0x0c, 0x00, 0x19, 0x00, 0x0d, 0x00, - 0x1a, 0x00, 0x12, 0x00, 0x1b, 0x00, 0x14, 0x00, - 0x1f, 0x00, 0x13, 0x00, 0x20, 0x00, 0x00, 0x00, - 0x21, 0x00, 0x0a, 0x00, 0x22, 0x00, 0x06, 0x00, - 0x23, 0x00, 0x07, 0x00, 0x24, 0x00, 0x08, 0x00, - 0x25, 0x00, 0x09, 0x00, 0x26, 0x00, 0x04, 0x00, - 0x27, 0x00, 0x03, 0x00, 0x28, 0x00, 0x02, 0x00, - 0x29, 0x00, 0x01, 0x00, 0x2a, 0x00, 0x05, 0x00, - 0x2b, 0x00, 0x2a, 0x00 }; +{ + 0xff, 0x02, 0xb6, 0x00, 0x28, 0x00, 0x00, 0x00, + 0x27, 0x00, 0x27, 0x00, 0x03, 0x00, 0x04, 0x00, + 0x00, 0x00, 0x26, 0x00, 0x01, 0x00, 0x1e, 0x00, + 0x02, 0x00, 0x1f, 0x00, 0x03, 0x00, 0x1d, 0x00, + 0x04, 0x00, 0x27, 0x00, 0x05, 0x00, 0x0b, 0x00, + 0x06, 0x00, 0x28, 0x00, 0x08, 0x00, 0x21, 0x00, + 0x09, 0x00, 0x20, 0x00, 0x0a, 0x00, 0x22, 0x00, + 0x0b, 0x00, 0x25, 0x00, 0x0c, 0x00, 0x24, 0x00, + 0x0d, 0x00, 0x23, 0x00, 0x0e, 0x00, 0x19, 0x00, + 0x0f, 0x00, 0x16, 0x00, 0x10, 0x00, 0x15, 0x00, + 0x11, 0x00, 0x1c, 0x00, 0x12, 0x00, 0x1b, 0x00, + 0x13, 0x00, 0x1a, 0x00, 0x14, 0x00, 0x17, 0x00, + 0x15, 0x00, 0x18, 0x00, 0x16, 0x00, 0x0e, 0x00, + 0x18, 0x00, 0x0c, 0x00, 0x19, 0x00, 0x0d, 0x00, + 0x1a, 0x00, 0x12, 0x00, 0x1b, 0x00, 0x14, 0x00, + 0x1f, 0x00, 0x13, 0x00, 0x20, 0x00, 0x00, 0x00, + 0x21, 0x00, 0x0a, 0x00, 0x22, 0x00, 0x06, 0x00, + 0x23, 0x00, 0x07, 0x00, 0x24, 0x00, 0x08, 0x00, + 0x25, 0x00, 0x09, 0x00, 0x26, 0x00, 0x04, 0x00, + 0x27, 0x00, 0x03, 0x00, 0x28, 0x00, 0x02, 0x00, + 0x29, 0x00, 0x01, 0x00, 0x2a, 0x00, 0x05, 0x00, + 0x2b, 0x00, 0x2a, 0x00 +}; /* some compilers need unsigned char to avoid warnings */ /* @@ -60,113 +60,116 @@ static tui8 g_unknown2[8] = /*****************************************************************************/ static int APP_CC -xrdp_rdp_read_config(struct xrdp_client_info* client_info) +xrdp_rdp_read_config(struct xrdp_client_info *client_info) { - int index = 0; - struct list* items = (struct list *)NULL; - struct list* values = (struct list *)NULL; - char* item = (char *)NULL; - char* value = (char *)NULL; - char cfg_file[256]; - - /* initialize (zero out) local variables: */ - g_memset(cfg_file,0,sizeof(char) * 256); - - items = list_create(); - items->auto_free = 1; - values = list_create(); - values->auto_free = 1; - g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); - file_by_name_read_section(cfg_file, "globals", items, values); - for (index = 0; index < items->count; index++) - { - item = (char*)list_get_item(items, index); - value = (char*)list_get_item(values, index); - if (g_strcasecmp(item, "bitmap_cache") == 0) + int index = 0; + struct list *items = (struct list *)NULL; + struct list *values = (struct list *)NULL; + char *item = (char *)NULL; + char *value = (char *)NULL; + char cfg_file[256]; + + /* initialize (zero out) local variables: */ + g_memset(cfg_file, 0, sizeof(char) * 256); + + items = list_create(); + items->auto_free = 1; + values = list_create(); + values->auto_free = 1; + g_snprintf(cfg_file, 255, "%s/xrdp.ini", XRDP_CFG_PATH); + file_by_name_read_section(cfg_file, "globals", items, values); + + for (index = 0; index < items->count; index++) { - if ((g_strcasecmp(value, "yes") == 0) || - (g_strcasecmp(value, "true") == 0) || - (g_strcasecmp(value, "1") == 0)) - { - client_info->use_bitmap_cache = 1; - } - } - else if (g_strcasecmp(item, "bitmap_compression") == 0) - { - if (g_strcasecmp(value, "yes") == 0 || - g_strcasecmp(value, "true") == 0 || - g_strcasecmp(value, "1") == 0) - { - client_info->use_bitmap_comp = 1; - } - } - else if (g_strcasecmp(item, "crypt_level") == 0) - { - if (g_strcasecmp(value, "low") == 0) - { - client_info->crypt_level = 1; - } - else if (g_strcasecmp(value, "medium") == 0) - { - client_info->crypt_level = 2; - } - else if (g_strcasecmp(value, "high") == 0) - { - client_info->crypt_level = 3; - } - else - { - g_writeln("Warning: Your configured crypt level is" - "undefined 'high' will be used"); - client_info->crypt_level = 3; - } - } - else if (g_strcasecmp(item, "channel_code") == 0) - { - if ((g_strcasecmp(value, "yes") == 0) || - (g_strcasecmp(value, "1") == 0) || - (g_strcasecmp(value, "true") == 0)) - { - client_info->channel_code = 1; - } - else - { - g_writeln("Info: All channels are disabled"); - } - } - else if (g_strcasecmp(item, "max_bpp") == 0) - { - client_info->max_bpp = g_atoi(value); + item = (char *)list_get_item(items, index); + value = (char *)list_get_item(values, index); + + if (g_strcasecmp(item, "bitmap_cache") == 0) + { + if ((g_strcasecmp(value, "yes") == 0) || + (g_strcasecmp(value, "true") == 0) || + (g_strcasecmp(value, "1") == 0)) + { + client_info->use_bitmap_cache = 1; + } + } + else if (g_strcasecmp(item, "bitmap_compression") == 0) + { + if (g_strcasecmp(value, "yes") == 0 || + g_strcasecmp(value, "true") == 0 || + g_strcasecmp(value, "1") == 0) + { + client_info->use_bitmap_comp = 1; + } + } + else if (g_strcasecmp(item, "crypt_level") == 0) + { + if (g_strcasecmp(value, "low") == 0) + { + client_info->crypt_level = 1; + } + else if (g_strcasecmp(value, "medium") == 0) + { + client_info->crypt_level = 2; + } + else if (g_strcasecmp(value, "high") == 0) + { + client_info->crypt_level = 3; + } + else + { + g_writeln("Warning: Your configured crypt level is" + "undefined 'high' will be used"); + client_info->crypt_level = 3; + } + } + else if (g_strcasecmp(item, "channel_code") == 0) + { + if ((g_strcasecmp(value, "yes") == 0) || + (g_strcasecmp(value, "1") == 0) || + (g_strcasecmp(value, "true") == 0)) + { + client_info->channel_code = 1; + } + else + { + g_writeln("Info: All channels are disabled"); + } + } + else if (g_strcasecmp(item, "max_bpp") == 0) + { + client_info->max_bpp = g_atoi(value); + } } - } - list_delete(items); - list_delete(values); - return 0; + + list_delete(items); + list_delete(values); + return 0; } #if defined(XRDP_FREERDP1) /*****************************************************************************/ static void -cpuid(tui32 info, tui32* eax, tui32* ebx, tui32* ecx, tui32* edx) +cpuid(tui32 info, tui32 *eax, tui32 *ebx, tui32 *ecx, tui32 *edx) { #ifdef __GNUC__ #if defined(__i386__) || defined(__x86_64__) - __asm volatile - ( - /* The EBX (or RBX register on x86_64) is used for the PIC base address - and must not be corrupted by our inline assembly. */ + __asm volatile + ( + /* The EBX (or RBX register on x86_64) is used for the PIC base address + and must not be corrupted by our inline assembly. */ #if defined(__i386__) - "mov %%ebx, %%esi;" - "cpuid;" - "xchg %%ebx, %%esi;" + "mov %%ebx, %%esi;" + "cpuid;" + "xchg %%ebx, %%esi;" #else - "mov %%rbx, %%rsi;" - "cpuid;" - "xchg %%rbx, %%rsi;" + "mov %%rbx, %%rsi;" + "cpuid;" + "xchg %%rbx, %%rsi;" #endif - : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx) - : "0" (info) - ); + : "=a" (*eax), "=S" (*ebx), "=c" (*ecx), "=d" (*edx) + : "0" (info) + ); #endif #endif } @@ -175,1379 +178,1457 @@ cpuid(tui32 info, tui32* eax, tui32* ebx, tui32* ecx, tui32* edx) static tui32 xrdp_rdp_detect_cpu(void) { - tui32 eax; - tui32 ebx; - tui32 ecx; - tui32 edx; - tui32 cpu_opt; - - eax = 0; - ebx = 0; - ecx = 0; - edx = 0; - cpu_opt = 0; - cpuid(1, &eax, &ebx, &ecx, &edx); - - if (edx & (1 << 26)) - { - DEBUG("SSE2 detected"); - cpu_opt |= CPU_SSE2; - } - - return cpu_opt; + tui32 eax; + tui32 ebx; + tui32 ecx; + tui32 edx; + tui32 cpu_opt; + + eax = 0; + ebx = 0; + ecx = 0; + edx = 0; + cpu_opt = 0; + cpuid(1, &eax, &ebx, &ecx, &edx); + + if (edx & (1 << 26)) + { + DEBUG("SSE2 detected"); + cpu_opt |= CPU_SSE2; + } + + return cpu_opt; } #endif /*****************************************************************************/ -struct xrdp_rdp* APP_CC -xrdp_rdp_create(struct xrdp_session* session, struct trans* trans) +struct xrdp_rdp *APP_CC +xrdp_rdp_create(struct xrdp_session *session, struct trans *trans) { - struct xrdp_rdp* self = (struct xrdp_rdp *)NULL; - int bytes; - - DEBUG(("in xrdp_rdp_create")); - self = (struct xrdp_rdp*)g_malloc(sizeof(struct xrdp_rdp), 1); - self->session = session; - self->share_id = 66538; - /* read ini settings */ - xrdp_rdp_read_config(&self->client_info); - /* create sec layer */ - self->sec_layer = xrdp_sec_create(self, trans, self->client_info.crypt_level, - self->client_info.channel_code); - /* default 8 bit v1 color bitmap cache entries and size */ - self->client_info.cache1_entries = 600; - self->client_info.cache1_size = 256; - self->client_info.cache2_entries = 300; - self->client_info.cache2_size = 1024; - self->client_info.cache3_entries = 262; - self->client_info.cache3_size = 4096; - /* load client ip info */ - bytes = sizeof(self->client_info.client_ip) - 1; - g_write_ip_address(trans->sck, self->client_info.client_ip, bytes); + struct xrdp_rdp *self = (struct xrdp_rdp *)NULL; + int bytes; + + DEBUG(("in xrdp_rdp_create")); + self = (struct xrdp_rdp *)g_malloc(sizeof(struct xrdp_rdp), 1); + self->session = session; + self->share_id = 66538; + /* read ini settings */ + xrdp_rdp_read_config(&self->client_info); + /* create sec layer */ + self->sec_layer = xrdp_sec_create(self, trans, self->client_info.crypt_level, + self->client_info.channel_code); + /* default 8 bit v1 color bitmap cache entries and size */ + self->client_info.cache1_entries = 600; + self->client_info.cache1_size = 256; + self->client_info.cache2_entries = 300; + self->client_info.cache2_size = 1024; + self->client_info.cache3_entries = 262; + self->client_info.cache3_size = 4096; + /* load client ip info */ + bytes = sizeof(self->client_info.client_ip) - 1; + g_write_ip_address(trans->sck, self->client_info.client_ip, bytes); #if defined(XRDP_FREERDP1) - self->mppc_enc = mppc_enc_new(PROTO_RDP_50); - self->rfx_enc = rfx_context_new(); - rfx_context_set_cpu_opt(self->rfx_enc, xrdp_rdp_detect_cpu()); + self->mppc_enc = mppc_enc_new(PROTO_RDP_50); + self->rfx_enc = rfx_context_new(); + rfx_context_set_cpu_opt(self->rfx_enc, xrdp_rdp_detect_cpu()); #endif - self->client_info.size = sizeof(self->client_info); - DEBUG(("out xrdp_rdp_create")); - return self; + self->client_info.size = sizeof(self->client_info); + DEBUG(("out xrdp_rdp_create")); + return self; } /*****************************************************************************/ void APP_CC -xrdp_rdp_delete(struct xrdp_rdp* self) +xrdp_rdp_delete(struct xrdp_rdp *self) { - if (self == 0) - { - return; - } - xrdp_sec_delete(self->sec_layer); + if (self == 0) + { + return; + } + + xrdp_sec_delete(self->sec_layer); #if defined(XRDP_FREERDP1) - mppc_enc_free((struct rdp_mppc_enc*)(self->mppc_enc)); - rfx_context_free((RFX_CONTEXT*)(self->rfx_enc)); + mppc_enc_free((struct rdp_mppc_enc *)(self->mppc_enc)); + rfx_context_free((RFX_CONTEXT *)(self->rfx_enc)); #endif - g_free(self); + g_free(self); } /*****************************************************************************/ int APP_CC -xrdp_rdp_init(struct xrdp_rdp* self, struct stream* s) +xrdp_rdp_init(struct xrdp_rdp *self, struct stream *s) { - if (xrdp_sec_init(self->sec_layer, s) != 0) - { - return 1; - } - s_push_layer(s, rdp_hdr, 6); - return 0; + if (xrdp_sec_init(self->sec_layer, s) != 0) + { + return 1; + } + + s_push_layer(s, rdp_hdr, 6); + return 0; } /*****************************************************************************/ int APP_CC -xrdp_rdp_init_data(struct xrdp_rdp* self, struct stream* s) +xrdp_rdp_init_data(struct xrdp_rdp *self, struct stream *s) { - if (xrdp_sec_init(self->sec_layer, s) != 0) - { - return 1; - } - s_push_layer(s, rdp_hdr, 18); - return 0; + if (xrdp_sec_init(self->sec_layer, s) != 0) + { + return 1; + } + + s_push_layer(s, rdp_hdr, 18); + return 0; } /*****************************************************************************/ /* returns erros */ int APP_CC -xrdp_rdp_recv(struct xrdp_rdp* self, struct stream* s, int* code) +xrdp_rdp_recv(struct xrdp_rdp *self, struct stream *s, int *code) { - int error = 0; - int len = 0; - int pdu_code = 0; - int chan = 0; - - DEBUG(("in xrdp_rdp_recv")); - if (s->next_packet == 0 || s->next_packet >= s->end) - { - chan = 0; - error = xrdp_sec_recv(self->sec_layer, s, &chan); - if (error == -1) /* special code for send demand active */ + int error = 0; + int len = 0; + int pdu_code = 0; + int chan = 0; + + DEBUG(("in xrdp_rdp_recv")); + + if (s->next_packet == 0 || s->next_packet >= s->end) + { + chan = 0; + error = xrdp_sec_recv(self->sec_layer, s, &chan); + + if (error == -1) /* special code for send demand active */ + { + s->next_packet = 0; + *code = -1; + DEBUG(("out (1) xrdp_rdp_recv")); + return 0; + } + + if (error != 0) + { + DEBUG(("out xrdp_rdp_recv error")); + return 1; + } + + if ((chan != MCS_GLOBAL_CHANNEL) && (chan > 0)) + { + if (chan > MCS_GLOBAL_CHANNEL) + { + if (xrdp_channel_process(self->sec_layer->chan_layer, s, chan) != 0) + { + g_writeln("xrdp_channel_process returned unhandled error") ; + } + } + else + { + g_writeln("Wrong channel Id to be handled by xrdp_channel_process %d", chan); + } + + s->next_packet = 0; + *code = 0; + DEBUG(("out (2) xrdp_rdp_recv")); + return 0; + } + + s->next_packet = s->p; + } + else { - s->next_packet = 0; - *code = -1; - DEBUG(("out (1) xrdp_rdp_recv")); - return 0; + DEBUG(("xrdp_rdp_recv stream not touched")) + s->p = s->next_packet; } - if (error != 0) + + if (!s_check_rem(s, 6)) { - DEBUG(("out xrdp_rdp_recv error")); - return 1; + s->next_packet = 0; + *code = 0; + DEBUG(("out (3) xrdp_rdp_recv")); + len = (int)(s->end - s->p); + g_writeln("xrdp_rdp_recv: bad RDP packet, length [%d]", len); + return 0; } - if ((chan != MCS_GLOBAL_CHANNEL) && (chan > 0)) + else { - if (chan > MCS_GLOBAL_CHANNEL) - { - if(xrdp_channel_process(self->sec_layer->chan_layer, s, chan)!=0) - { - g_writeln("xrdp_channel_process returned unhandled error") ; - } - } - else - { - g_writeln("Wrong channel Id to be handled by xrdp_channel_process %d",chan); - } - s->next_packet = 0; - *code = 0; - DEBUG(("out (2) xrdp_rdp_recv")); - return 0; + in_uint16_le(s, len); + /*g_writeln("New len received : %d next packet: %d s_end: %d",len,s->next_packet,s->end); */ + in_uint16_le(s, pdu_code); + *code = pdu_code & 0xf; + in_uint8s(s, 2); /* mcs user id */ + s->next_packet += len; + DEBUG(("out (4) xrdp_rdp_recv")); + return 0; } - s->next_packet = s->p; - } - else - { - DEBUG(("xrdp_rdp_recv stream not touched")) - s->p = s->next_packet; - } - if (!s_check_rem(s, 6)) - { - s->next_packet = 0; - *code = 0; - DEBUG(("out (3) xrdp_rdp_recv")); - len = (int)(s->end - s->p); - g_writeln("xrdp_rdp_recv: bad RDP packet, length [%d]", len); - return 0; - } - else - { - in_uint16_le(s, len); - /*g_writeln("New len received : %d next packet: %d s_end: %d",len,s->next_packet,s->end); */ - in_uint16_le(s, pdu_code); - *code = pdu_code & 0xf; - in_uint8s(s, 2); /* mcs user id */ - s->next_packet += len; - DEBUG(("out (4) xrdp_rdp_recv")); - return 0; - } } /*****************************************************************************/ int APP_CC -xrdp_rdp_send(struct xrdp_rdp* self, struct stream* s, int pdu_type) +xrdp_rdp_send(struct xrdp_rdp *self, struct stream *s, int pdu_type) { - int len = 0; - - DEBUG(("in xrdp_rdp_send")); - s_pop_layer(s, rdp_hdr); - len = s->end - s->p; - out_uint16_le(s, len); - out_uint16_le(s, 0x10 | pdu_type); - out_uint16_le(s, self->mcs_channel); - if (xrdp_sec_send(self->sec_layer, s, MCS_GLOBAL_CHANNEL) != 0) - { - DEBUG(("out xrdp_rdp_send error")); - return 1; - } - DEBUG(("out xrdp_rdp_send")); - return 0; + int len = 0; + + DEBUG(("in xrdp_rdp_send")); + s_pop_layer(s, rdp_hdr); + len = s->end - s->p; + out_uint16_le(s, len); + out_uint16_le(s, 0x10 | pdu_type); + out_uint16_le(s, self->mcs_channel); + + if (xrdp_sec_send(self->sec_layer, s, MCS_GLOBAL_CHANNEL) != 0) + { + DEBUG(("out xrdp_rdp_send error")); + return 1; + } + + DEBUG(("out xrdp_rdp_send")); + return 0; } /*****************************************************************************/ int APP_CC -xrdp_rdp_send_data(struct xrdp_rdp* self, struct stream* s, +xrdp_rdp_send_data(struct xrdp_rdp *self, struct stream *s, int data_pdu_type) { - int len; - int ctype; - int clen; - int dlen; - int pdulen; - int pdutype; - int tocomplen; - int iso_offset; - int mcs_offset; - int sec_offset; - int rdp_offset; - struct stream ls; + int len; + int ctype; + int clen; + int dlen; + int pdulen; + int pdutype; + int tocomplen; + int iso_offset; + int mcs_offset; + int sec_offset; + int rdp_offset; + struct stream ls; #if defined(XRDP_FREERDP1) - struct rdp_mppc_enc* mppc_enc; + struct rdp_mppc_enc *mppc_enc; #endif - DEBUG(("in xrdp_rdp_send_data")); - s_pop_layer(s, rdp_hdr); - len = (int)(s->end - s->p); - pdutype = 0x10 | RDP_PDU_DATA; - pdulen = len; - dlen = len; - ctype = 0; - clen = len; - tocomplen = pdulen - 18; + DEBUG(("in xrdp_rdp_send_data")); + s_pop_layer(s, rdp_hdr); + len = (int)(s->end - s->p); + pdutype = 0x10 | RDP_PDU_DATA; + pdulen = len; + dlen = len; + ctype = 0; + clen = len; + tocomplen = pdulen - 18; #if defined(XRDP_FREERDP1) - if (self->client_info.rdp_compression && self->session->up_and_running) - { - mppc_enc = (struct rdp_mppc_enc*)(self->mppc_enc); - if (compress_rdp(mppc_enc, (tui8*)(s->p + 18), tocomplen)) + + if (self->client_info.rdp_compression && self->session->up_and_running) { - DEBUG(("mppc_encode ok flags 0x%x bytes_in_opb %d historyOffset %d " - "tocomplen %d", mppc_enc->flags, mppc_enc->bytes_in_opb, - mppc_enc->historyOffset, tocomplen)); - if (mppc_enc->flags & RDP_MPPC_COMPRESSED) - { - clen = mppc_enc->bytes_in_opb + 18; - pdulen = clen; - ctype = mppc_enc->flags; - iso_offset = (int)(s->iso_hdr - s->data); - mcs_offset = (int)(s->mcs_hdr - s->data); - sec_offset = (int)(s->sec_hdr - s->data); - rdp_offset = (int)(s->rdp_hdr - s->data); - - /* outputBuffer has 64 bytes preceding it */ - ls.data = mppc_enc->outputBuffer - (rdp_offset + 18); - ls.p = ls.data + rdp_offset; - ls.end = ls.p + clen; - ls.size = clen; - ls.iso_hdr = ls.data + iso_offset; - ls.mcs_hdr = ls.data + mcs_offset; - ls.sec_hdr = ls.data + sec_offset; - ls.rdp_hdr = ls.data + rdp_offset; - ls.channel_hdr = 0; - ls.next_packet = 0; - s = &ls; - } + mppc_enc = (struct rdp_mppc_enc *)(self->mppc_enc); + + if (compress_rdp(mppc_enc, (tui8 *)(s->p + 18), tocomplen)) + { + DEBUG(("mppc_encode ok flags 0x%x bytes_in_opb %d historyOffset %d " + "tocomplen %d", mppc_enc->flags, mppc_enc->bytes_in_opb, + mppc_enc->historyOffset, tocomplen)); + + if (mppc_enc->flags & RDP_MPPC_COMPRESSED) + { + clen = mppc_enc->bytes_in_opb + 18; + pdulen = clen; + ctype = mppc_enc->flags; + iso_offset = (int)(s->iso_hdr - s->data); + mcs_offset = (int)(s->mcs_hdr - s->data); + sec_offset = (int)(s->sec_hdr - s->data); + rdp_offset = (int)(s->rdp_hdr - s->data); + + /* outputBuffer has 64 bytes preceding it */ + ls.data = mppc_enc->outputBuffer - (rdp_offset + 18); + ls.p = ls.data + rdp_offset; + ls.end = ls.p + clen; + ls.size = clen; + ls.iso_hdr = ls.data + iso_offset; + ls.mcs_hdr = ls.data + mcs_offset; + ls.sec_hdr = ls.data + sec_offset; + ls.rdp_hdr = ls.data + rdp_offset; + ls.channel_hdr = 0; + ls.next_packet = 0; + s = &ls; + } + } + else + { + g_writeln("mppc_encode not ok"); + } } - else + +#endif + out_uint16_le(s, pdulen); + out_uint16_le(s, pdutype); + out_uint16_le(s, self->mcs_channel); + out_uint32_le(s, self->share_id); + out_uint8(s, 0); + out_uint8(s, 1); + out_uint16_le(s, dlen); + out_uint8(s, data_pdu_type); + out_uint8(s, ctype); + out_uint16_le(s, clen); + + if (xrdp_sec_send(self->sec_layer, s, MCS_GLOBAL_CHANNEL) != 0) { - g_writeln("mppc_encode not ok"); + DEBUG(("out xrdp_rdp_send_data error")); + return 1; } - } -#endif - out_uint16_le(s, pdulen); - out_uint16_le(s, pdutype); - out_uint16_le(s, self->mcs_channel); - out_uint32_le(s, self->share_id); - out_uint8(s, 0); - out_uint8(s, 1); - out_uint16_le(s, dlen); - out_uint8(s, data_pdu_type); - out_uint8(s, ctype); - out_uint16_le(s, clen); - - if (xrdp_sec_send(self->sec_layer, s, MCS_GLOBAL_CHANNEL) != 0) - { - DEBUG(("out xrdp_rdp_send_data error")); - return 1; - } - DEBUG(("out xrdp_rdp_send_data")); - return 0; + + DEBUG(("out xrdp_rdp_send_data")); + return 0; } /*****************************************************************************/ int APP_CC -xrdp_rdp_send_data_update_sync(struct xrdp_rdp* self) +xrdp_rdp_send_data_update_sync(struct xrdp_rdp *self) { - struct stream * s = (struct stream *)NULL; - - make_stream(s); - init_stream(s, 8192); - DEBUG(("in xrdp_rdp_send_data_update_sync")); - if (xrdp_rdp_init_data(self, s) != 0) - { - DEBUG(("out xrdp_rdp_send_data_update_sync error")); - free_stream(s); - return 1; - } - out_uint16_le(s, RDP_UPDATE_SYNCHRONIZE); - out_uint8s(s, 2); - s_mark_end(s); - if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_UPDATE) != 0) - { - DEBUG(("out xrdp_rdp_send_data_update_sync error")); + struct stream *s = (struct stream *)NULL; + + make_stream(s); + init_stream(s, 8192); + DEBUG(("in xrdp_rdp_send_data_update_sync")); + + if (xrdp_rdp_init_data(self, s) != 0) + { + DEBUG(("out xrdp_rdp_send_data_update_sync error")); + free_stream(s); + return 1; + } + + out_uint16_le(s, RDP_UPDATE_SYNCHRONIZE); + out_uint8s(s, 2); + s_mark_end(s); + + if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_UPDATE) != 0) + { + DEBUG(("out xrdp_rdp_send_data_update_sync error")); + free_stream(s); + return 1; + } + + DEBUG(("out xrdp_rdp_send_data_update_sync")); free_stream(s); - return 1; - } - DEBUG(("out xrdp_rdp_send_data_update_sync")); - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_rdp_parse_client_mcs_data(struct xrdp_rdp* self) +xrdp_rdp_parse_client_mcs_data(struct xrdp_rdp *self) { - struct stream* p = (struct stream *)NULL; - int i = 0; - - p = &(self->sec_layer->client_mcs_data); - p->p = p->data; - in_uint8s(p, 31); - in_uint16_le(p, self->client_info.width); - in_uint16_le(p, self->client_info.height); - in_uint8s(p, 120); - self->client_info.bpp = 8; - in_uint16_le(p, i); - switch (i) - { - case 0xca01: - in_uint8s(p, 6); - in_uint8(p, i); - if (i > 8) - { - self->client_info.bpp = i; - } - break; - case 0xca02: - self->client_info.bpp = 15; - break; - case 0xca03: - self->client_info.bpp = 16; - break; - case 0xca04: - self->client_info.bpp = 24; - break; - } - if (self->client_info.max_bpp > 0) - { - if (self->client_info.bpp > self->client_info.max_bpp) + struct stream *p = (struct stream *)NULL; + int i = 0; + + p = &(self->sec_layer->client_mcs_data); + p->p = p->data; + in_uint8s(p, 31); + in_uint16_le(p, self->client_info.width); + in_uint16_le(p, self->client_info.height); + in_uint8s(p, 120); + self->client_info.bpp = 8; + in_uint16_le(p, i); + + switch (i) + { + case 0xca01: + in_uint8s(p, 6); + in_uint8(p, i); + + if (i > 8) + { + self->client_info.bpp = i; + } + + break; + case 0xca02: + self->client_info.bpp = 15; + break; + case 0xca03: + self->client_info.bpp = 16; + break; + case 0xca04: + self->client_info.bpp = 24; + break; + } + + if (self->client_info.max_bpp > 0) { - self->client_info.bpp = self->client_info.max_bpp; + if (self->client_info.bpp > self->client_info.max_bpp) + { + self->client_info.bpp = self->client_info.max_bpp; + } } - } - p->p = p->data; - DEBUG(("client width %d, client height %d bpp %d", - self->client_info.width, self->client_info.height, - self->client_info.bpp)); - return 0; + + p->p = p->data; + DEBUG(("client width %d, client height %d bpp %d", + self->client_info.width, self->client_info.height, + self->client_info.bpp)); + return 0; } /*****************************************************************************/ int APP_CC -xrdp_rdp_incoming(struct xrdp_rdp* self) +xrdp_rdp_incoming(struct xrdp_rdp *self) { - DEBUG(("in xrdp_rdp_incoming")); - if (xrdp_sec_incoming(self->sec_layer) != 0) - { - return 1; - } - self->mcs_channel = self->sec_layer->mcs_layer->userid + - MCS_USERCHANNEL_BASE; - xrdp_rdp_parse_client_mcs_data(self); - DEBUG(("out xrdp_rdp_incoming mcs channel %d", self->mcs_channel)); - return 0; + DEBUG(("in xrdp_rdp_incoming")); + + if (xrdp_sec_incoming(self->sec_layer) != 0) + { + return 1; + } + + self->mcs_channel = self->sec_layer->mcs_layer->userid + + MCS_USERCHANNEL_BASE; + xrdp_rdp_parse_client_mcs_data(self); + DEBUG(("out xrdp_rdp_incoming mcs channel %d", self->mcs_channel)); + return 0; } /*****************************************************************************/ int APP_CC -xrdp_rdp_send_demand_active(struct xrdp_rdp* self) +xrdp_rdp_send_demand_active(struct xrdp_rdp *self) { - struct stream* s; - int caps_count; - int caps_size; - int codec_caps_count; - int codec_caps_size; - char* caps_count_ptr; - char* caps_size_ptr; - char* caps_ptr; - char* codec_caps_count_ptr; - char* codec_caps_size_ptr; - - make_stream(s); - init_stream(s, 8192); - if (xrdp_rdp_init(self, s) != 0) - { - free_stream(s); - return 1; - } - - caps_count = 0; - out_uint32_le(s, self->share_id); - out_uint16_le(s, 4); /* 4 chars for RDP\0 */ - /* 2 bytes size after num caps, set later */ - caps_size_ptr = s->p; - out_uint8s(s, 2); - out_uint8a(s, "RDP", 4); - /* 4 byte num caps, set later */ - caps_count_ptr = s->p; - out_uint8s(s, 4); - caps_ptr = s->p; - - /* Output share capability set */ - caps_count++; - out_uint16_le(s, RDP_CAPSET_SHARE); - out_uint16_le(s, RDP_CAPLEN_SHARE); - out_uint16_le(s, self->mcs_channel); - out_uint16_be(s, 0xb5e2); /* 0x73e1 */ - - /* Output general capability set */ - caps_count++; - out_uint16_le(s, RDP_CAPSET_GENERAL); /* 1 */ - out_uint16_le(s, RDP_CAPLEN_GENERAL); /* 24(0x18) */ - 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_le(s, 0); /* pad */ - out_uint16_le(s, 0); /* Compression types */ - //out_uint16_le(s, 0); /* pad use 0x40d for rdp packets, 0 for not */ - out_uint16_le(s, 0x40d); /* pad use 0x40d for rdp packets, 0 for not */ - out_uint16_le(s, 0); /* Update capability */ - out_uint16_le(s, 0); /* Remote unshare capability */ - out_uint16_le(s, 0); /* Compression level */ - out_uint16_le(s, 0); /* Pad */ - - /* Output bitmap capability set */ - caps_count++; - out_uint16_le(s, RDP_CAPSET_BITMAP); /* 2 */ - out_uint16_le(s, RDP_CAPLEN_BITMAP); /* 28(0x1c) */ - out_uint16_le(s, self->client_info.bpp); /* Preferred BPP */ - 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, self->client_info.width); /* width */ - out_uint16_le(s, self->client_info.height); /* height */ - out_uint16_le(s, 0); /* Pad */ - out_uint16_le(s, 1); /* Allow resize */ - out_uint16_le(s, 1); /* bitmap compression */ - out_uint16_le(s, 0); /* unknown */ - out_uint16_le(s, 0); /* unknown */ - out_uint16_le(s, 0); /* pad */ - - /* Output font capability set */ - caps_count++; - out_uint16_le(s, RDP_CAPSET_FONT); /* 14 */ - out_uint16_le(s, RDP_CAPLEN_FONT); /* 4 */ - - /* Output order capability set */ - caps_count++; - out_uint16_le(s, RDP_CAPSET_ORDER); /* 3 */ - out_uint16_le(s, RDP_CAPLEN_ORDER); /* 88(0x58) */ - out_uint8s(s, 16); - out_uint32_be(s, 0x40420f00); - out_uint16_le(s, 1); /* Cache X granularity */ - out_uint16_le(s, 20); /* Cache Y granularity */ - out_uint16_le(s, 0); /* Pad */ - out_uint16_le(s, 1); /* Max order level */ - out_uint16_le(s, 0x2f); /* Number of fonts */ - out_uint16_le(s, 0x22); /* Capability flags */ - /* caps */ - out_uint8(s, 1); /* dest blt */ - out_uint8(s, 1); /* pat blt */ - out_uint8(s, 1); /* screen blt */ - out_uint8(s, 1); /* mem blt */ - out_uint8(s, 0); /* tri blt */ - out_uint8(s, 0); /* unused */ - out_uint8(s, 0); /* unused */ - out_uint8(s, 0); /* nine grid */ - out_uint8(s, 1); /* line to */ - out_uint8(s, 0); /* multi nine grid */ - out_uint8(s, 1); /* rect */ - out_uint8(s, 0); /* desk save */ - out_uint8(s, 0); /* unused */ - out_uint8(s, 0); /* unused */ - out_uint8(s, 0); /* unused */ - out_uint8(s, 0); /* multi dest blt */ - out_uint8(s, 0); /* multi pat blt */ - out_uint8(s, 0); /* multi screen blt */ - out_uint8(s, 1); /* multi rect */ - out_uint8(s, 0); /* fast index */ - out_uint8(s, 0); /* polygonSC ([MS-RDPEGDI], 2.2.2.2.1.1.2.16) */ - out_uint8(s, 0); /* polygonCB ([MS-RDPEGDI], 2.2.2.2.1.1.2.17) */ - out_uint8(s, 0); /* polyline */ - out_uint8(s, 0); /* unused */ - out_uint8(s, 0); /* fast glyph */ - out_uint8(s, 0); /* ellipse */ - out_uint8(s, 0); /* ellipse */ - out_uint8(s, 0); /* ? */ - out_uint8(s, 0); /* unused */ - out_uint8(s, 0); /* unused */ - out_uint8(s, 0); /* unused */ - out_uint8(s, 0); /* unused */ - out_uint16_le(s, 0x6a1); - /* declare support of bitmap cache rev3 */ - out_uint16_le(s, XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT); - out_uint32_le(s, 0x0f4240); /* desk save */ - out_uint32_le(s, 0x0f4240); /* desk save */ - out_uint32_le(s, 1); /* ? */ - out_uint32_le(s, 0); /* ? */ - - /* Output bmpcodecs capability set */ - caps_count++; - out_uint16_le(s, RDP_CAPSET_BMPCODECS); - codec_caps_size_ptr = s->p; - out_uint8s(s, 2); /* cap len set later */ - codec_caps_count = 0; - codec_caps_count_ptr = s->p; - out_uint8s(s, 1); /* bitmapCodecCount set later */ - /* nscodec */ - codec_caps_count++; - out_uint8a(s, XR_CODEC_GUID_NSCODEC, 16); - out_uint8(s, 1); /* codec id, must be 1 */ - out_uint16_le(s, 3); - out_uint8(s, 0x01); /* fAllowDynamicFidelity */ - out_uint8(s, 0x01); /* fAllowSubsampling */ - out_uint8(s, 0x03); /* colorLossLevel */ - /* remotefx */ - codec_caps_count++; - out_uint8a(s, XR_CODEC_GUID_REMOTEFX, 16); - out_uint8(s, 0); /* codec id, client sets */ - out_uint16_le(s, 256); - out_uint8s(s, 256); - /* jpeg */ - codec_caps_count++; - out_uint8a(s, XR_CODEC_GUID_JPEG, 16); - out_uint8(s, 0); /* codec id, client sets */ - out_uint16_le(s, 1); /* ext length */ - out_uint8(s, 75); - /* calculate and set size and count */ - codec_caps_size = (int)(s->p - codec_caps_size_ptr); - codec_caps_size += 2; /* 2 bytes for RDP_CAPSET_BMPCODECS above */ - codec_caps_size_ptr[0] = codec_caps_size; - codec_caps_size_ptr[1] = codec_caps_size >> 8; - codec_caps_count_ptr[0] = codec_caps_count; - - /* Output color cache capability set */ - caps_count++; - out_uint16_le(s, RDP_CAPSET_COLCACHE); - out_uint16_le(s, RDP_CAPLEN_COLCACHE); - out_uint16_le(s, 6); /* cache size */ - out_uint16_le(s, 0); /* pad */ - - /* Output pointer capability set */ - caps_count++; - out_uint16_le(s, RDP_CAPSET_POINTER); - out_uint16_le(s, RDP_CAPLEN_POINTER); - out_uint16_le(s, 1); /* Colour pointer */ - out_uint16_le(s, 0x19); /* Cache size */ - out_uint16_le(s, 0x19); /* Cache size */ - - /* Output input capability set */ - caps_count++; - out_uint16_le(s, RDP_CAPSET_INPUT); /* 13(0xd) */ - out_uint16_le(s, RDP_CAPLEN_INPUT); /* 88(0x58) */ - out_uint8(s, 1); - out_uint8s(s, 83); - - /* Remote Programs Capability Set */ - caps_count++; - out_uint16_le(s, 0x0017); /* CAPSETTYPE_RAIL */ - out_uint16_le(s, 8); - out_uint32_le(s, 3); /* TS_RAIL_LEVEL_SUPPORTED + struct stream *s; + int caps_count; + int caps_size; + int codec_caps_count; + int codec_caps_size; + char *caps_count_ptr; + char *caps_size_ptr; + char *caps_ptr; + char *codec_caps_count_ptr; + char *codec_caps_size_ptr; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_rdp_init(self, s) != 0) + { + free_stream(s); + return 1; + } + + caps_count = 0; + out_uint32_le(s, self->share_id); + out_uint16_le(s, 4); /* 4 chars for RDP\0 */ + /* 2 bytes size after num caps, set later */ + caps_size_ptr = s->p; + out_uint8s(s, 2); + out_uint8a(s, "RDP", 4); + /* 4 byte num caps, set later */ + caps_count_ptr = s->p; + out_uint8s(s, 4); + caps_ptr = s->p; + + /* Output share capability set */ + caps_count++; + out_uint16_le(s, RDP_CAPSET_SHARE); + out_uint16_le(s, RDP_CAPLEN_SHARE); + out_uint16_le(s, self->mcs_channel); + out_uint16_be(s, 0xb5e2); /* 0x73e1 */ + + /* Output general capability set */ + caps_count++; + out_uint16_le(s, RDP_CAPSET_GENERAL); /* 1 */ + out_uint16_le(s, RDP_CAPLEN_GENERAL); /* 24(0x18) */ + 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_le(s, 0); /* pad */ + out_uint16_le(s, 0); /* Compression types */ + //out_uint16_le(s, 0); /* pad use 0x40d for rdp packets, 0 for not */ + out_uint16_le(s, 0x40d); /* pad use 0x40d for rdp packets, 0 for not */ + out_uint16_le(s, 0); /* Update capability */ + out_uint16_le(s, 0); /* Remote unshare capability */ + out_uint16_le(s, 0); /* Compression level */ + out_uint16_le(s, 0); /* Pad */ + + /* Output bitmap capability set */ + caps_count++; + out_uint16_le(s, RDP_CAPSET_BITMAP); /* 2 */ + out_uint16_le(s, RDP_CAPLEN_BITMAP); /* 28(0x1c) */ + out_uint16_le(s, self->client_info.bpp); /* Preferred BPP */ + 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, self->client_info.width); /* width */ + out_uint16_le(s, self->client_info.height); /* height */ + out_uint16_le(s, 0); /* Pad */ + out_uint16_le(s, 1); /* Allow resize */ + out_uint16_le(s, 1); /* bitmap compression */ + out_uint16_le(s, 0); /* unknown */ + out_uint16_le(s, 0); /* unknown */ + out_uint16_le(s, 0); /* pad */ + + /* Output font capability set */ + caps_count++; + out_uint16_le(s, RDP_CAPSET_FONT); /* 14 */ + out_uint16_le(s, RDP_CAPLEN_FONT); /* 4 */ + + /* Output order capability set */ + caps_count++; + out_uint16_le(s, RDP_CAPSET_ORDER); /* 3 */ + out_uint16_le(s, RDP_CAPLEN_ORDER); /* 88(0x58) */ + out_uint8s(s, 16); + out_uint32_be(s, 0x40420f00); + out_uint16_le(s, 1); /* Cache X granularity */ + out_uint16_le(s, 20); /* Cache Y granularity */ + out_uint16_le(s, 0); /* Pad */ + out_uint16_le(s, 1); /* Max order level */ + out_uint16_le(s, 0x2f); /* Number of fonts */ + out_uint16_le(s, 0x22); /* Capability flags */ + /* caps */ + out_uint8(s, 1); /* dest blt */ + out_uint8(s, 1); /* pat blt */ + out_uint8(s, 1); /* screen blt */ + out_uint8(s, 1); /* mem blt */ + out_uint8(s, 0); /* tri blt */ + out_uint8(s, 0); /* unused */ + out_uint8(s, 0); /* unused */ + out_uint8(s, 0); /* nine grid */ + out_uint8(s, 1); /* line to */ + out_uint8(s, 0); /* multi nine grid */ + out_uint8(s, 1); /* rect */ + out_uint8(s, 0); /* desk save */ + out_uint8(s, 0); /* unused */ + out_uint8(s, 0); /* unused */ + out_uint8(s, 0); /* unused */ + out_uint8(s, 0); /* multi dest blt */ + out_uint8(s, 0); /* multi pat blt */ + out_uint8(s, 0); /* multi screen blt */ + out_uint8(s, 1); /* multi rect */ + out_uint8(s, 0); /* fast index */ + out_uint8(s, 0); /* polygonSC ([MS-RDPEGDI], 2.2.2.2.1.1.2.16) */ + out_uint8(s, 0); /* polygonCB ([MS-RDPEGDI], 2.2.2.2.1.1.2.17) */ + out_uint8(s, 0); /* polyline */ + out_uint8(s, 0); /* unused */ + out_uint8(s, 0); /* fast glyph */ + out_uint8(s, 0); /* ellipse */ + out_uint8(s, 0); /* ellipse */ + out_uint8(s, 0); /* ? */ + out_uint8(s, 0); /* unused */ + out_uint8(s, 0); /* unused */ + out_uint8(s, 0); /* unused */ + out_uint8(s, 0); /* unused */ + out_uint16_le(s, 0x6a1); + /* declare support of bitmap cache rev3 */ + out_uint16_le(s, XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT); + out_uint32_le(s, 0x0f4240); /* desk save */ + out_uint32_le(s, 0x0f4240); /* desk save */ + out_uint32_le(s, 1); /* ? */ + out_uint32_le(s, 0); /* ? */ + + /* Output bmpcodecs capability set */ + caps_count++; + out_uint16_le(s, RDP_CAPSET_BMPCODECS); + codec_caps_size_ptr = s->p; + out_uint8s(s, 2); /* cap len set later */ + codec_caps_count = 0; + codec_caps_count_ptr = s->p; + out_uint8s(s, 1); /* bitmapCodecCount set later */ + /* nscodec */ + codec_caps_count++; + out_uint8a(s, XR_CODEC_GUID_NSCODEC, 16); + out_uint8(s, 1); /* codec id, must be 1 */ + out_uint16_le(s, 3); + out_uint8(s, 0x01); /* fAllowDynamicFidelity */ + out_uint8(s, 0x01); /* fAllowSubsampling */ + out_uint8(s, 0x03); /* colorLossLevel */ + /* remotefx */ + codec_caps_count++; + out_uint8a(s, XR_CODEC_GUID_REMOTEFX, 16); + out_uint8(s, 0); /* codec id, client sets */ + out_uint16_le(s, 256); + out_uint8s(s, 256); + /* jpeg */ + codec_caps_count++; + out_uint8a(s, XR_CODEC_GUID_JPEG, 16); + out_uint8(s, 0); /* codec id, client sets */ + out_uint16_le(s, 1); /* ext length */ + out_uint8(s, 75); + /* calculate and set size and count */ + codec_caps_size = (int)(s->p - codec_caps_size_ptr); + codec_caps_size += 2; /* 2 bytes for RDP_CAPSET_BMPCODECS above */ + codec_caps_size_ptr[0] = codec_caps_size; + codec_caps_size_ptr[1] = codec_caps_size >> 8; + codec_caps_count_ptr[0] = codec_caps_count; + + /* Output color cache capability set */ + caps_count++; + out_uint16_le(s, RDP_CAPSET_COLCACHE); + out_uint16_le(s, RDP_CAPLEN_COLCACHE); + out_uint16_le(s, 6); /* cache size */ + out_uint16_le(s, 0); /* pad */ + + /* Output pointer capability set */ + caps_count++; + out_uint16_le(s, RDP_CAPSET_POINTER); + out_uint16_le(s, RDP_CAPLEN_POINTER); + out_uint16_le(s, 1); /* Colour pointer */ + out_uint16_le(s, 0x19); /* Cache size */ + out_uint16_le(s, 0x19); /* Cache size */ + + /* Output input capability set */ + caps_count++; + out_uint16_le(s, RDP_CAPSET_INPUT); /* 13(0xd) */ + out_uint16_le(s, RDP_CAPLEN_INPUT); /* 88(0x58) */ + out_uint8(s, 1); + out_uint8s(s, 83); + + /* Remote Programs Capability Set */ + caps_count++; + out_uint16_le(s, 0x0017); /* CAPSETTYPE_RAIL */ + out_uint16_le(s, 8); + out_uint32_le(s, 3); /* TS_RAIL_LEVEL_SUPPORTED TS_RAIL_LEVEL_DOCKED_LANGBAR_SUPPORTED */ - /* Window List Capability Set */ - caps_count++; - out_uint16_le(s, 0x0018); /* CAPSETTYPE_WINDOW */ - out_uint16_le(s, 11); - out_uint32_le(s, 2); /* TS_WINDOW_LEVEL_SUPPORTED_EX */ - out_uint8(s, 3); /* NumIconCaches */ - out_uint16_le(s, 12); /* NumIconCacheEntries */ + /* Window List Capability Set */ + caps_count++; + out_uint16_le(s, 0x0018); /* CAPSETTYPE_WINDOW */ + out_uint16_le(s, 11); + out_uint32_le(s, 2); /* TS_WINDOW_LEVEL_SUPPORTED_EX */ + out_uint8(s, 3); /* NumIconCaches */ + out_uint16_le(s, 12); /* NumIconCacheEntries */ - /* 6 - bitmap cache v3 codecid */ - caps_count++; - out_uint16_le(s, 0x0006); - out_uint16_le(s, 5); - out_uint8(s, 0); /* client sets */ + /* 6 - bitmap cache v3 codecid */ + caps_count++; + out_uint16_le(s, 0x0006); + out_uint16_le(s, 5); + out_uint8(s, 0); /* client sets */ - out_uint8s(s, 4); /* pad */ + out_uint8s(s, 4); /* pad */ - s_mark_end(s); + s_mark_end(s); - caps_size = (int)(s->end - caps_ptr); - caps_size_ptr[0] = caps_size; - caps_size_ptr[1] = caps_size >> 8; + caps_size = (int)(s->end - caps_ptr); + caps_size_ptr[0] = caps_size; + caps_size_ptr[1] = caps_size >> 8; - caps_count_ptr[0] = caps_count; - caps_count_ptr[1] = caps_count >> 8; - caps_count_ptr[2] = caps_count >> 16; - caps_count_ptr[3] = caps_count >> 24; + caps_count_ptr[0] = caps_count; + caps_count_ptr[1] = caps_count >> 8; + caps_count_ptr[2] = caps_count >> 16; + caps_count_ptr[3] = caps_count >> 24; - if (xrdp_rdp_send(self, s, RDP_PDU_DEMAND_ACTIVE) != 0) - { - free_stream(s); - return 1; - } + if (xrdp_rdp_send(self, s, RDP_PDU_DEMAND_ACTIVE) != 0) + { + free_stream(s); + return 1; + } - free_stream(s); - return 0; + free_stream(s); + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_process_capset_general(struct xrdp_rdp* self, struct stream* s, +xrdp_process_capset_general(struct xrdp_rdp *self, struct stream *s, int len) { - int i; - - in_uint8s(s, 10); - in_uint16_le(s, i); - /* use_compact_packets is pretty much 'use rdp5' */ - self->client_info.use_compact_packets = (i != 0); - /* op2 is a boolean to use compact bitmap headers in bitmap cache */ - /* set it to same as 'use rdp5' boolean */ - self->client_info.op2 = self->client_info.use_compact_packets; - return 0; + int i; + + in_uint8s(s, 10); + in_uint16_le(s, i); + /* use_compact_packets is pretty much 'use rdp5' */ + self->client_info.use_compact_packets = (i != 0); + /* op2 is a boolean to use compact bitmap headers in bitmap cache */ + /* set it to same as 'use rdp5' boolean */ + self->client_info.op2 = self->client_info.use_compact_packets; + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_process_capset_order(struct xrdp_rdp* self, struct stream* s, +xrdp_process_capset_order(struct xrdp_rdp *self, struct stream *s, int len) { - int i; - char order_caps[32]; - int ex_flags; - - DEBUG(("order capabilities")); - in_uint8s(s, 20); /* Terminal desc, pad */ - in_uint8s(s, 2); /* Cache X granularity */ - in_uint8s(s, 2); /* Cache Y granularity */ - in_uint8s(s, 2); /* Pad */ - in_uint8s(s, 2); /* Max order level */ - in_uint8s(s, 2); /* Number of fonts */ - in_uint8s(s, 2); /* Capability flags */ - in_uint8a(s, order_caps, 32); /* Orders supported */ - DEBUG(("dest blt-0 %d", order_caps[0])); - DEBUG(("pat blt-1 %d", order_caps[1])); - DEBUG(("screen blt-2 %d", order_caps[2])); - DEBUG(("memblt-3-13 %d %d", order_caps[3], order_caps[13])); - DEBUG(("triblt-4-14 %d %d", order_caps[4], order_caps[14])); - DEBUG(("line-8 %d", order_caps[8])); - DEBUG(("line-9 %d", order_caps[9])); - DEBUG(("rect-10 %d", order_caps[10])); - DEBUG(("desksave-11 %d", order_caps[11])); - DEBUG(("polygon-20 %d", order_caps[20])); - DEBUG(("polygon2-21 %d", order_caps[21])); - DEBUG(("polyline-22 %d", order_caps[22])); - DEBUG(("ellipse-25 %d", order_caps[25])); - DEBUG(("ellipse2-26 %d", order_caps[26])); - DEBUG(("text2-27 %d", order_caps[27])); - DEBUG(("order_caps dump")); + int i; + char order_caps[32]; + int ex_flags; + + DEBUG(("order capabilities")); + in_uint8s(s, 20); /* Terminal desc, pad */ + in_uint8s(s, 2); /* Cache X granularity */ + in_uint8s(s, 2); /* Cache Y granularity */ + in_uint8s(s, 2); /* Pad */ + in_uint8s(s, 2); /* Max order level */ + in_uint8s(s, 2); /* Number of fonts */ + in_uint8s(s, 2); /* Capability flags */ + in_uint8a(s, order_caps, 32); /* Orders supported */ + DEBUG(("dest blt-0 %d", order_caps[0])); + DEBUG(("pat blt-1 %d", order_caps[1])); + DEBUG(("screen blt-2 %d", order_caps[2])); + DEBUG(("memblt-3-13 %d %d", order_caps[3], order_caps[13])); + DEBUG(("triblt-4-14 %d %d", order_caps[4], order_caps[14])); + DEBUG(("line-8 %d", order_caps[8])); + DEBUG(("line-9 %d", order_caps[9])); + DEBUG(("rect-10 %d", order_caps[10])); + DEBUG(("desksave-11 %d", order_caps[11])); + DEBUG(("polygon-20 %d", order_caps[20])); + DEBUG(("polygon2-21 %d", order_caps[21])); + DEBUG(("polyline-22 %d", order_caps[22])); + DEBUG(("ellipse-25 %d", order_caps[25])); + DEBUG(("ellipse2-26 %d", order_caps[26])); + DEBUG(("text2-27 %d", order_caps[27])); + DEBUG(("order_caps dump")); #if defined(XRDP_DEBUG) - g_hexdump(order_caps, 32); + g_hexdump(order_caps, 32); #endif - in_uint8s(s, 2); /* Text capability flags */ - /* read extended order support flags */ - in_uint16_le(s, ex_flags); /* Ex flags */ - if (ex_flags & XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT) - { - g_writeln("xrdp_process_capset_order: bitmap cache v3 supported"); - self->client_info.bitmap_cache_version |= 4; - } - in_uint8s(s, 4); /* Pad */ - - in_uint32_le(s, i); /* desktop cache size, usually 0x38400 */ - self->client_info.desktop_cache = i; - DEBUG(("desktop cache size %d", i)); - in_uint8s(s, 4); /* Unknown */ - in_uint8s(s, 4); /* Unknown */ - return 0; + in_uint8s(s, 2); /* Text capability flags */ + /* read extended order support flags */ + in_uint16_le(s, ex_flags); /* Ex flags */ + + if (ex_flags & XR_ORDERFLAGS_EX_CACHE_BITMAP_REV3_SUPPORT) + { + g_writeln("xrdp_process_capset_order: bitmap cache v3 supported"); + self->client_info.bitmap_cache_version |= 4; + } + + in_uint8s(s, 4); /* Pad */ + + in_uint32_le(s, i); /* desktop cache size, usually 0x38400 */ + self->client_info.desktop_cache = i; + DEBUG(("desktop cache size %d", i)); + in_uint8s(s, 4); /* Unknown */ + in_uint8s(s, 4); /* Unknown */ + return 0; } /*****************************************************************************/ /* get the bitmap cache size */ static int APP_CC -xrdp_process_capset_bmpcache(struct xrdp_rdp* self, struct stream* s, +xrdp_process_capset_bmpcache(struct xrdp_rdp *self, struct stream *s, int len) { - self->client_info.bitmap_cache_version |= 1; - in_uint8s(s, 24); - in_uint16_le(s, self->client_info.cache1_entries); - in_uint16_le(s, self->client_info.cache1_size); - in_uint16_le(s, self->client_info.cache2_entries); - in_uint16_le(s, self->client_info.cache2_size); - in_uint16_le(s, self->client_info.cache3_entries); - in_uint16_le(s, self->client_info.cache3_size); - DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries, - self->client_info.cache1_size)); - DEBUG(("cache2 entries %d size %d", self->client_info.cache2_entries, - self->client_info.cache2_size)); - DEBUG(("cache3 entries %d size %d", self->client_info.cache3_entries, - self->client_info.cache3_size)); - return 0; + self->client_info.bitmap_cache_version |= 1; + in_uint8s(s, 24); + in_uint16_le(s, self->client_info.cache1_entries); + in_uint16_le(s, self->client_info.cache1_size); + in_uint16_le(s, self->client_info.cache2_entries); + in_uint16_le(s, self->client_info.cache2_size); + in_uint16_le(s, self->client_info.cache3_entries); + in_uint16_le(s, self->client_info.cache3_size); + DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries, + self->client_info.cache1_size)); + DEBUG(("cache2 entries %d size %d", self->client_info.cache2_entries, + self->client_info.cache2_size)); + DEBUG(("cache3 entries %d size %d", self->client_info.cache3_entries, + self->client_info.cache3_size)); + return 0; } /*****************************************************************************/ /* get the bitmap cache size */ static int APP_CC -xrdp_process_capset_bmpcache2(struct xrdp_rdp* self, struct stream* s, +xrdp_process_capset_bmpcache2(struct xrdp_rdp *self, struct stream *s, int len) { - int Bpp = 0; - int i = 0; - - self->client_info.bitmap_cache_version |= 2; - Bpp = (self->client_info.bpp + 7) / 8; - in_uint16_le(s, i); /* cache flags */ - self->client_info.bitmap_cache_persist_enable = i; - in_uint8s(s, 2); /* number of caches in set, 3 */ - in_uint32_le(s, i); - i = MIN(i, 2000); - self->client_info.cache1_entries = i; - self->client_info.cache1_size = 256 * Bpp; - in_uint32_le(s, i); - i = MIN(i, 2000); - self->client_info.cache2_entries = i; - self->client_info.cache2_size = 1024 * Bpp; - in_uint32_le(s, i); - i = i & 0x7fffffff; - i = MIN(i, 2000); - self->client_info.cache3_entries = i; - self->client_info.cache3_size = 4096 * Bpp; - DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries, - self->client_info.cache1_size)); - DEBUG(("cache2 entries %d size %d", self->client_info.cache2_entries, - self->client_info.cache2_size)); - DEBUG(("cache3 entries %d size %d", self->client_info.cache3_entries, - self->client_info.cache3_size)); - return 0; + int Bpp = 0; + int i = 0; + + self->client_info.bitmap_cache_version |= 2; + Bpp = (self->client_info.bpp + 7) / 8; + in_uint16_le(s, i); /* cache flags */ + self->client_info.bitmap_cache_persist_enable = i; + in_uint8s(s, 2); /* number of caches in set, 3 */ + in_uint32_le(s, i); + i = MIN(i, 2000); + self->client_info.cache1_entries = i; + self->client_info.cache1_size = 256 * Bpp; + in_uint32_le(s, i); + i = MIN(i, 2000); + self->client_info.cache2_entries = i; + self->client_info.cache2_size = 1024 * Bpp; + in_uint32_le(s, i); + i = i & 0x7fffffff; + i = MIN(i, 2000); + self->client_info.cache3_entries = i; + self->client_info.cache3_size = 4096 * Bpp; + DEBUG(("cache1 entries %d size %d", self->client_info.cache1_entries, + self->client_info.cache1_size)); + DEBUG(("cache2 entries %d size %d", self->client_info.cache2_entries, + self->client_info.cache2_size)); + DEBUG(("cache3 entries %d size %d", self->client_info.cache3_entries, + self->client_info.cache3_size)); + return 0; } /*****************************************************************************/ static int -xrdp_process_capset_cache_v3_codec_id(struct xrdp_rdp* self, struct stream* s, +xrdp_process_capset_cache_v3_codec_id(struct xrdp_rdp *self, struct stream *s, int len) { - int codec_id; + int codec_id; - in_uint8(s, codec_id); - g_writeln("xrdp_process_capset_cache_v3_codec_id: cache_v3_codec_id %d", - codec_id); - self->client_info.v3_codec_id = codec_id; - return 0; + in_uint8(s, codec_id); + g_writeln("xrdp_process_capset_cache_v3_codec_id: cache_v3_codec_id %d", + codec_id); + self->client_info.v3_codec_id = codec_id; + return 0; } /*****************************************************************************/ /* get the number of client cursor cache */ static int APP_CC -xrdp_process_capset_pointercache(struct xrdp_rdp* self, struct stream* s, +xrdp_process_capset_pointercache(struct xrdp_rdp *self, struct stream *s, int len) { - int i; + int i; - in_uint8s(s, 2); /* color pointer */ - in_uint16_le(s, i); - i = MIN(i, 32); - self->client_info.pointer_cache_entries = i; - return 0; + in_uint8s(s, 2); /* color pointer */ + in_uint16_le(s, i); + i = MIN(i, 32); + self->client_info.pointer_cache_entries = i; + return 0; } /*****************************************************************************/ /* get the type of client brush cache */ static int APP_CC -xrdp_process_capset_brushcache(struct xrdp_rdp* self, struct stream* s, +xrdp_process_capset_brushcache(struct xrdp_rdp *self, struct stream *s, int len) { - int code; + int code; - in_uint32_le(s, code); - self->client_info.brush_cache_code = code; - return 0; + in_uint32_le(s, code); + self->client_info.brush_cache_code = code; + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_process_offscreen_bmpcache(struct xrdp_rdp* self, struct stream* s, +xrdp_process_offscreen_bmpcache(struct xrdp_rdp *self, struct stream *s, int len) { - int i32; - - if (len - 4 < 8) - { - g_writeln("xrdp_process_offscreen_bmpcache: bad len"); - return 1; - } - in_uint32_le(s, i32); - self->client_info.offscreen_support_level = i32; - in_uint16_le(s, i32); - self->client_info.offscreen_cache_size = i32 * 1024; - in_uint16_le(s, i32); - self->client_info.offscreen_cache_entries = i32; - g_writeln("xrdp_process_offscreen_bmpcache: support level %d " - "cache size %d MB cache entries %d", - self->client_info.offscreen_support_level, - self->client_info.offscreen_cache_size, - self->client_info.offscreen_cache_entries); - return 0; + int i32; + + if (len - 4 < 8) + { + g_writeln("xrdp_process_offscreen_bmpcache: bad len"); + return 1; + } + + in_uint32_le(s, i32); + self->client_info.offscreen_support_level = i32; + in_uint16_le(s, i32); + self->client_info.offscreen_cache_size = i32 * 1024; + in_uint16_le(s, i32); + self->client_info.offscreen_cache_entries = i32; + g_writeln("xrdp_process_offscreen_bmpcache: support level %d " + "cache size %d MB cache entries %d", + self->client_info.offscreen_support_level, + self->client_info.offscreen_cache_size, + self->client_info.offscreen_cache_entries); + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_process_capset_rail(struct xrdp_rdp* self, struct stream* s, int len) +xrdp_process_capset_rail(struct xrdp_rdp *self, struct stream *s, int len) { - int i32; - - if (len - 4 < 4) - { - g_writeln("xrdp_process_capset_rail: bad len"); - return 1; - } - in_uint32_le(s, i32); - self->client_info.rail_support_level = i32; - g_writeln("xrdp_process_capset_rail: rail_support_level %d", - self->client_info.rail_support_level); - return 0; + int i32; + + if (len - 4 < 4) + { + g_writeln("xrdp_process_capset_rail: bad len"); + return 1; + } + + in_uint32_le(s, i32); + self->client_info.rail_support_level = i32; + g_writeln("xrdp_process_capset_rail: rail_support_level %d", + self->client_info.rail_support_level); + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_process_capset_window(struct xrdp_rdp* self, struct stream* s, int len) +xrdp_process_capset_window(struct xrdp_rdp *self, struct stream *s, int len) { - int i32; - - if (len - 4 < 7) - { - g_writeln("xrdp_process_capset_window: bad len"); - return 1; - } - in_uint32_le(s, i32); - self->client_info.wnd_support_level = i32; - in_uint8(s, i32); - self->client_info.wnd_num_icon_caches = i32; - in_uint16_le(s, i32); - self->client_info.wnd_num_icon_cache_entries = i32; - g_writeln("xrdp_process_capset_window wnd_support_level %d " - "wnd_num_icon_caches %d wnd_num_icon_cache_entries %d", - self->client_info.wnd_support_level, - self->client_info.wnd_num_icon_caches, - self->client_info.wnd_num_icon_cache_entries); - return 0; + int i32; + + if (len - 4 < 7) + { + g_writeln("xrdp_process_capset_window: bad len"); + return 1; + } + + in_uint32_le(s, i32); + self->client_info.wnd_support_level = i32; + in_uint8(s, i32); + self->client_info.wnd_num_icon_caches = i32; + in_uint16_le(s, i32); + self->client_info.wnd_num_icon_cache_entries = i32; + g_writeln("xrdp_process_capset_window wnd_support_level %d " + "wnd_num_icon_caches %d wnd_num_icon_cache_entries %d", + self->client_info.wnd_support_level, + self->client_info.wnd_num_icon_caches, + self->client_info.wnd_num_icon_cache_entries); + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_process_capset_codecs(struct xrdp_rdp* self, struct stream* s, int len) +xrdp_process_capset_codecs(struct xrdp_rdp *self, struct stream *s, int len) { - int codec_id; - int codec_count; - int index; - int codec_properties_length; - int i1; - char* codec_guid; - char* next_guid; - - in_uint8(s, codec_count); - for (index = 0; index < codec_count; index++) - { - codec_guid = s->p; - in_uint8s(s, 16); - in_uint8(s, codec_id); - in_uint16_le(s, codec_properties_length); - next_guid = s->p + codec_properties_length; - if (g_memcmp(codec_guid, XR_CODEC_GUID_NSCODEC, 16) == 0) - { - g_writeln("xrdp_process_capset_codecs: nscodec codec id %d prop len %d", - codec_id, codec_properties_length); - self->client_info.ns_codec_id = codec_id; - i1 = MIN(64, codec_properties_length); - g_memcpy(self->client_info.ns_prop, s->p, i1); - self->client_info.ns_prop_len = i1; - } - else if (g_memcmp(codec_guid, XR_CODEC_GUID_REMOTEFX, 16) == 0) - { - g_writeln("xrdp_process_capset_codecs: rfx codec id %d prop len %d", - codec_id, codec_properties_length); - self->client_info.rfx_codec_id = codec_id; - i1 = MIN(64, codec_properties_length); - g_memcpy(self->client_info.rfx_prop, s->p, i1); - self->client_info.rfx_prop_len = i1; - } - else if (g_memcmp(codec_guid, XR_CODEC_GUID_JPEG, 16) == 0) - { - g_writeln("xrdp_process_capset_codecs: jpeg codec id %d prop len %d", - codec_id, codec_properties_length); - self->client_info.jpeg_codec_id = codec_id; - i1 = MIN(64, codec_properties_length); - g_memcpy(self->client_info.jpeg_prop, s->p, i1); - self->client_info.jpeg_prop_len = i1; - g_writeln(" jpeg quality %d", self->client_info.jpeg_prop[0]); - } - else + int codec_id; + int codec_count; + int index; + int codec_properties_length; + int i1; + char *codec_guid; + char *next_guid; + + in_uint8(s, codec_count); + + for (index = 0; index < codec_count; index++) { - g_writeln("xrdp_process_capset_codecs: unknown codec id %d", codec_id); + codec_guid = s->p; + in_uint8s(s, 16); + in_uint8(s, codec_id); + in_uint16_le(s, codec_properties_length); + next_guid = s->p + codec_properties_length; + + if (g_memcmp(codec_guid, XR_CODEC_GUID_NSCODEC, 16) == 0) + { + g_writeln("xrdp_process_capset_codecs: nscodec codec id %d prop len %d", + codec_id, codec_properties_length); + self->client_info.ns_codec_id = codec_id; + i1 = MIN(64, codec_properties_length); + g_memcpy(self->client_info.ns_prop, s->p, i1); + self->client_info.ns_prop_len = i1; + } + else if (g_memcmp(codec_guid, XR_CODEC_GUID_REMOTEFX, 16) == 0) + { + g_writeln("xrdp_process_capset_codecs: rfx codec id %d prop len %d", + codec_id, codec_properties_length); + self->client_info.rfx_codec_id = codec_id; + i1 = MIN(64, codec_properties_length); + g_memcpy(self->client_info.rfx_prop, s->p, i1); + self->client_info.rfx_prop_len = i1; + } + else if (g_memcmp(codec_guid, XR_CODEC_GUID_JPEG, 16) == 0) + { + g_writeln("xrdp_process_capset_codecs: jpeg codec id %d prop len %d", + codec_id, codec_properties_length); + self->client_info.jpeg_codec_id = codec_id; + i1 = MIN(64, codec_properties_length); + g_memcpy(self->client_info.jpeg_prop, s->p, i1); + self->client_info.jpeg_prop_len = i1; + g_writeln(" jpeg quality %d", self->client_info.jpeg_prop[0]); + } + else + { + g_writeln("xrdp_process_capset_codecs: unknown codec id %d", codec_id); + } + + s->p = next_guid; } - s->p = next_guid; - } - return 0; + + return 0; } /*****************************************************************************/ int APP_CC -xrdp_rdp_process_confirm_active(struct xrdp_rdp* self, struct stream* s) +xrdp_rdp_process_confirm_active(struct xrdp_rdp *self, struct stream *s) { - int cap_len; - int source_len; - int num_caps; - int index; - int type; - int len; - char* p; - - DEBUG(("in xrdp_rdp_process_confirm_active")); - in_uint8s(s, 4); /* rdp_shareid */ - in_uint8s(s, 2); /* userid */ - in_uint16_le(s, source_len); /* sizeof RDP_SOURCE */ - in_uint16_le(s, cap_len); - in_uint8s(s, source_len); - in_uint16_le(s, num_caps); - in_uint8s(s, 2); /* pad */ - for (index = 0; index < num_caps; index++) - { - p = s->p; - in_uint16_le(s, type); - in_uint16_le(s, len); - switch (type) + int cap_len; + int source_len; + int num_caps; + int index; + int type; + int len; + char *p; + + DEBUG(("in xrdp_rdp_process_confirm_active")); + in_uint8s(s, 4); /* rdp_shareid */ + in_uint8s(s, 2); /* userid */ + in_uint16_le(s, source_len); /* sizeof RDP_SOURCE */ + in_uint16_le(s, cap_len); + in_uint8s(s, source_len); + in_uint16_le(s, num_caps); + in_uint8s(s, 2); /* pad */ + + for (index = 0; index < num_caps; index++) { - case RDP_CAPSET_GENERAL: /* 1 */ - DEBUG(("RDP_CAPSET_GENERAL")); - xrdp_process_capset_general(self, s, len); - break; - case RDP_CAPSET_BITMAP: /* 2 */ - DEBUG(("RDP_CAPSET_BITMAP")); - break; - case RDP_CAPSET_ORDER: /* 3 */ - DEBUG(("RDP_CAPSET_ORDER")); - xrdp_process_capset_order(self, s, len); - break; - case RDP_CAPSET_BMPCACHE: /* 4 */ - DEBUG(("RDP_CAPSET_BMPCACHE")); - xrdp_process_capset_bmpcache(self, s, len); - break; - case RDP_CAPSET_CONTROL: /* 5 */ - DEBUG(("RDP_CAPSET_CONTROL")); - break; - case 6: - xrdp_process_capset_cache_v3_codec_id(self, s, len); - break; - case RDP_CAPSET_ACTIVATE: /* 7 */ - DEBUG(("RDP_CAPSET_ACTIVATE")); - break; - case RDP_CAPSET_POINTER: /* 8 */ - DEBUG(("RDP_CAPSET_POINTER")); - xrdp_process_capset_pointercache(self, s, len); - break; - case RDP_CAPSET_SHARE: /* 9 */ - DEBUG(("RDP_CAPSET_SHARE")); - break; - case RDP_CAPSET_COLCACHE: /* 10 */ - DEBUG(("RDP_CAPSET_COLCACHE")); - break; - case 12: /* 12 */ - DEBUG(("--12")); - break; - case 13: /* 13 */ - DEBUG(("--13")); - break; - case 14: /* 14 */ - DEBUG(("--14")); - break; - case RDP_CAPSET_BRUSHCACHE: /* 15 */ - xrdp_process_capset_brushcache(self, s, len); - break; - case 16: /* 16 */ - DEBUG(("--16")); - break; - case 17: /* 17 */ - DEBUG(("CAPSET_TYPE_OFFSCREEN_CACHE")); - xrdp_process_offscreen_bmpcache(self, s, len); - break; - case RDP_CAPSET_BMPCACHE2: /* 19 */ - DEBUG(("RDP_CAPSET_BMPCACHE2")); - xrdp_process_capset_bmpcache2(self, s, len); - break; - case 20: /* 20 */ - DEBUG(("--20")); - break; - case 21: /* 21 */ - DEBUG(("--21")); - break; - case 22: /* 22 */ - DEBUG(("--22")); - break; - case 0x0017: /* 23 CAPSETTYPE_RAIL */ - xrdp_process_capset_rail(self, s, len); - break; - case 0x0018: /* 24 CAPSETTYPE_WINDOW */ - xrdp_process_capset_window(self, s, len); - break; - case 26: /* 26 */ - DEBUG(("--26")); - break; - case RDP_CAPSET_BMPCODECS: /* 0x1d(29) */ - xrdp_process_capset_codecs(self, s, len); - break; - default: - g_writeln("unknown in xrdp_rdp_process_confirm_active %d", type); - break; + p = s->p; + in_uint16_le(s, type); + in_uint16_le(s, len); + + switch (type) + { + case RDP_CAPSET_GENERAL: /* 1 */ + DEBUG(("RDP_CAPSET_GENERAL")); + xrdp_process_capset_general(self, s, len); + break; + case RDP_CAPSET_BITMAP: /* 2 */ + DEBUG(("RDP_CAPSET_BITMAP")); + break; + case RDP_CAPSET_ORDER: /* 3 */ + DEBUG(("RDP_CAPSET_ORDER")); + xrdp_process_capset_order(self, s, len); + break; + case RDP_CAPSET_BMPCACHE: /* 4 */ + DEBUG(("RDP_CAPSET_BMPCACHE")); + xrdp_process_capset_bmpcache(self, s, len); + break; + case RDP_CAPSET_CONTROL: /* 5 */ + DEBUG(("RDP_CAPSET_CONTROL")); + break; + case 6: + xrdp_process_capset_cache_v3_codec_id(self, s, len); + break; + case RDP_CAPSET_ACTIVATE: /* 7 */ + DEBUG(("RDP_CAPSET_ACTIVATE")); + break; + case RDP_CAPSET_POINTER: /* 8 */ + DEBUG(("RDP_CAPSET_POINTER")); + xrdp_process_capset_pointercache(self, s, len); + break; + case RDP_CAPSET_SHARE: /* 9 */ + DEBUG(("RDP_CAPSET_SHARE")); + break; + case RDP_CAPSET_COLCACHE: /* 10 */ + DEBUG(("RDP_CAPSET_COLCACHE")); + break; + case 12: /* 12 */ + DEBUG(("--12")); + break; + case 13: /* 13 */ + DEBUG(("--13")); + break; + case 14: /* 14 */ + DEBUG(("--14")); + break; + case RDP_CAPSET_BRUSHCACHE: /* 15 */ + xrdp_process_capset_brushcache(self, s, len); + break; + case 16: /* 16 */ + DEBUG(("--16")); + break; + case 17: /* 17 */ + DEBUG(("CAPSET_TYPE_OFFSCREEN_CACHE")); + xrdp_process_offscreen_bmpcache(self, s, len); + break; + case RDP_CAPSET_BMPCACHE2: /* 19 */ + DEBUG(("RDP_CAPSET_BMPCACHE2")); + xrdp_process_capset_bmpcache2(self, s, len); + break; + case 20: /* 20 */ + DEBUG(("--20")); + break; + case 21: /* 21 */ + DEBUG(("--21")); + break; + case 22: /* 22 */ + DEBUG(("--22")); + break; + case 0x0017: /* 23 CAPSETTYPE_RAIL */ + xrdp_process_capset_rail(self, s, len); + break; + case 0x0018: /* 24 CAPSETTYPE_WINDOW */ + xrdp_process_capset_window(self, s, len); + break; + case 26: /* 26 */ + DEBUG(("--26")); + break; + case RDP_CAPSET_BMPCODECS: /* 0x1d(29) */ + xrdp_process_capset_codecs(self, s, len); + break; + default: + g_writeln("unknown in xrdp_rdp_process_confirm_active %d", type); + break; + } + + s->p = p + len; } - s->p = p + len; - } - DEBUG(("out xrdp_rdp_process_confirm_active")); - return 0; + + DEBUG(("out xrdp_rdp_process_confirm_active")); + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_rdp_process_data_pointer(struct xrdp_rdp* self, struct stream* s) +xrdp_rdp_process_data_pointer(struct xrdp_rdp *self, struct stream *s) { - return 0; + return 0; } /*****************************************************************************/ /* RDP_DATA_PDU_INPUT */ static int APP_CC -xrdp_rdp_process_data_input(struct xrdp_rdp* self, struct stream* s) +xrdp_rdp_process_data_input(struct xrdp_rdp *self, struct stream *s) { - int num_events; - int index; - int msg_type; - int device_flags; - int param1; - int param2; - int time; - - in_uint16_le(s, num_events); - in_uint8s(s, 2); /* pad */ - DEBUG(("in xrdp_rdp_process_data_input %d events", num_events)); - for (index = 0; index < num_events; index++) - { - in_uint32_le(s, time); - in_uint16_le(s, msg_type); - in_uint16_le(s, device_flags); - in_sint16_le(s, param1); - in_sint16_le(s, param2); - DEBUG(("xrdp_rdp_process_data_input event %4.4x flags %4.4x param1 %d \ -param2 %d time %d", msg_type, device_flags, param1, param2, time)); - if (self->session->callback != 0) + int num_events; + int index; + int msg_type; + int device_flags; + int param1; + int param2; + int time; + + in_uint16_le(s, num_events); + in_uint8s(s, 2); /* pad */ + DEBUG(("in xrdp_rdp_process_data_input %d events", num_events)); + + for (index = 0; index < num_events; index++) { - /* msg_type can be - RDP_INPUT_SYNCHRONIZE - 0 - RDP_INPUT_SCANCODE - 4 - RDP_INPUT_MOUSE - 0x8001 */ - /* call to xrdp_wm.c : callback */ - self->session->callback(self->session->id, msg_type, param1, param2, - device_flags, time); + in_uint32_le(s, time); + in_uint16_le(s, msg_type); + in_uint16_le(s, device_flags); + in_sint16_le(s, param1); + in_sint16_le(s, param2); + DEBUG(("xrdp_rdp_process_data_input event %4.4x flags %4.4x param1 %d \ +param2 %d time %d", msg_type, device_flags, param1, param2, time)); + + if (self->session->callback != 0) + { + /* msg_type can be + RDP_INPUT_SYNCHRONIZE - 0 + RDP_INPUT_SCANCODE - 4 + RDP_INPUT_MOUSE - 0x8001 */ + /* call to xrdp_wm.c : callback */ + self->session->callback(self->session->id, msg_type, param1, param2, + device_flags, time); + } } - } - DEBUG(("out xrdp_rdp_process_data_input")); - return 0; + + DEBUG(("out xrdp_rdp_process_data_input")); + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_rdp_send_synchronise(struct xrdp_rdp* self) +xrdp_rdp_send_synchronise(struct xrdp_rdp *self) { - struct stream* s; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_rdp_init_data(self, s) != 0) + { + free_stream(s); + return 1; + } + + out_uint16_le(s, 1); + out_uint16_le(s, 1002); + s_mark_end(s); + + if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_SYNCHRONISE) != 0) + { + free_stream(s); + return 1; + } - make_stream(s); - init_stream(s, 8192); - if (xrdp_rdp_init_data(self, s) != 0) - { - free_stream(s); - return 1; - } - out_uint16_le(s, 1); - out_uint16_le(s, 1002); - s_mark_end(s); - if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_SYNCHRONISE) != 0) - { free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_rdp_send_control(struct xrdp_rdp* self, int action) +xrdp_rdp_send_control(struct xrdp_rdp *self, int action) { - struct stream* s; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_rdp_init_data(self, s) != 0) + { + free_stream(s); + return 1; + } + + out_uint16_le(s, action); + out_uint16_le(s, 0); /* userid */ + out_uint32_le(s, 1002); /* control id */ + s_mark_end(s); + + if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_CONTROL) != 0) + { + free_stream(s); + return 1; + } - make_stream(s); - init_stream(s, 8192); - if (xrdp_rdp_init_data(self, s) != 0) - { - free_stream(s); - return 1; - } - out_uint16_le(s, action); - out_uint16_le(s, 0); /* userid */ - out_uint32_le(s, 1002); /* control id */ - s_mark_end(s); - if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_CONTROL) != 0) - { free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_rdp_process_data_control(struct xrdp_rdp* self, struct stream* s) +xrdp_rdp_process_data_control(struct xrdp_rdp *self, struct stream *s) { - int action; - - DEBUG(("xrdp_rdp_process_data_control")); - in_uint16_le(s, action); - in_uint8s(s, 2); /* user id */ - in_uint8s(s, 4); /* control id */ - if (action == RDP_CTL_REQUEST_CONTROL) - { - DEBUG(("xrdp_rdp_process_data_control got RDP_CTL_REQUEST_CONTROL")); - DEBUG(("xrdp_rdp_process_data_control calling xrdp_rdp_send_synchronise")); - xrdp_rdp_send_synchronise(self); - DEBUG(("xrdp_rdp_process_data_control sending RDP_CTL_COOPERATE")); - xrdp_rdp_send_control(self, RDP_CTL_COOPERATE); - DEBUG(("xrdp_rdp_process_data_control sending RDP_CTL_GRANT_CONTROL")); - xrdp_rdp_send_control(self, RDP_CTL_GRANT_CONTROL); - } - else - { - DEBUG(("xrdp_rdp_process_data_control unknown action")); - } - return 0; + int action; + + DEBUG(("xrdp_rdp_process_data_control")); + in_uint16_le(s, action); + in_uint8s(s, 2); /* user id */ + in_uint8s(s, 4); /* control id */ + + if (action == RDP_CTL_REQUEST_CONTROL) + { + DEBUG(("xrdp_rdp_process_data_control got RDP_CTL_REQUEST_CONTROL")); + DEBUG(("xrdp_rdp_process_data_control calling xrdp_rdp_send_synchronise")); + xrdp_rdp_send_synchronise(self); + DEBUG(("xrdp_rdp_process_data_control sending RDP_CTL_COOPERATE")); + xrdp_rdp_send_control(self, RDP_CTL_COOPERATE); + DEBUG(("xrdp_rdp_process_data_control sending RDP_CTL_GRANT_CONTROL")); + xrdp_rdp_send_control(self, RDP_CTL_GRANT_CONTROL); + } + else + { + DEBUG(("xrdp_rdp_process_data_control unknown action")); + } + + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_rdp_process_data_sync(struct xrdp_rdp* self) +xrdp_rdp_process_data_sync(struct xrdp_rdp *self) { - DEBUG(("xrdp_rdp_process_data_sync")); - return 0; + DEBUG(("xrdp_rdp_process_data_sync")); + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_rdp_process_screen_update(struct xrdp_rdp* self, struct stream* s) +xrdp_rdp_process_screen_update(struct xrdp_rdp *self, struct stream *s) { - int op; - int left; - int top; - int right; - int bottom; - int cx; - int cy; - - in_uint32_le(s, op); - in_uint16_le(s, left); - in_uint16_le(s, top); - in_uint16_le(s, right); - in_uint16_le(s, bottom); - cx = (right - left) + 1; - cy = (bottom - top) + 1; - if (self->session->callback != 0) - { - self->session->callback(self->session->id, 0x4444, left, top, cx, cy); - } - return 0; + int op; + int left; + int top; + int right; + int bottom; + int cx; + int cy; + + in_uint32_le(s, op); + in_uint16_le(s, left); + in_uint16_le(s, top); + in_uint16_le(s, right); + in_uint16_le(s, bottom); + cx = (right - left) + 1; + cy = (bottom - top) + 1; + + if (self->session->callback != 0) + { + self->session->callback(self->session->id, 0x4444, left, top, cx, cy); + } + + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_rdp_send_unknown1(struct xrdp_rdp* self) +xrdp_rdp_send_unknown1(struct xrdp_rdp *self) { - struct stream* s; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_rdp_init_data(self, s) != 0) + { + free_stream(s); + return 1; + } + + out_uint8a(s, g_unknown1, 172); + s_mark_end(s); + + if (xrdp_rdp_send_data(self, s, 0x28) != 0) + { + free_stream(s); + return 1; + } - make_stream(s); - init_stream(s, 8192); - if (xrdp_rdp_init_data(self, s) != 0) - { - free_stream(s); - return 1; - } - out_uint8a(s, g_unknown1, 172); - s_mark_end(s); - if (xrdp_rdp_send_data(self, s, 0x28) != 0) - { free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ static int APP_CC -xrdp_rdp_process_data_font(struct xrdp_rdp* self, struct stream* s) +xrdp_rdp_process_data_font(struct xrdp_rdp *self, struct stream *s) { - int seq; - - DEBUG(("in xrdp_rdp_process_data_font")); - in_uint8s(s, 2); /* num of fonts */ - in_uint8s(s, 2); /* unknown */ - in_uint16_le(s, seq); - /* 419 client sends Seq 1, then 2 */ - /* 2600 clients sends only Seq 3 */ - if (seq == 2 || seq == 3) /* after second font message, we are up and */ - { /* running */ - DEBUG(("sending unknown1")); - xrdp_rdp_send_unknown1(self); - self->session->up_and_running = 1; - DEBUG(("up_and_running set")); - xrdp_rdp_send_data_update_sync(self); - } - DEBUG(("out xrdp_rdp_process_data_font")); - return 0; + int seq; + + DEBUG(("in xrdp_rdp_process_data_font")); + in_uint8s(s, 2); /* num of fonts */ + in_uint8s(s, 2); /* unknown */ + in_uint16_le(s, seq); + + /* 419 client sends Seq 1, then 2 */ + /* 2600 clients sends only Seq 3 */ + if (seq == 2 || seq == 3) /* after second font message, we are up and */ + { + /* running */ + DEBUG(("sending unknown1")); + xrdp_rdp_send_unknown1(self); + self->session->up_and_running = 1; + DEBUG(("up_and_running set")); + xrdp_rdp_send_data_update_sync(self); + } + + DEBUG(("out xrdp_rdp_process_data_font")); + return 0; } /*****************************************************************************/ /* sent 37 pdu */ static int APP_CC -xrdp_rdp_send_disconnect_query_response(struct xrdp_rdp* self) +xrdp_rdp_send_disconnect_query_response(struct xrdp_rdp *self) { - struct stream* s; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_rdp_init_data(self, s) != 0) + { + free_stream(s); + return 1; + } + + s_mark_end(s); + + if (xrdp_rdp_send_data(self, s, 37) != 0) + { + free_stream(s); + return 1; + } - make_stream(s); - init_stream(s, 8192); - if (xrdp_rdp_init_data(self, s) != 0) - { - free_stream(s); - return 1; - } - s_mark_end(s); - if (xrdp_rdp_send_data(self, s, 37) != 0) - { free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } #if 0 /* not used */ /*****************************************************************************/ /* sent RDP_DATA_PDU_DISCONNECT 47 pdu */ static int APP_CC -xrdp_rdp_send_disconnect_reason(struct xrdp_rdp* self, int reason) +xrdp_rdp_send_disconnect_reason(struct xrdp_rdp *self, int reason) { - struct stream* s; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_rdp_init_data(self, s) != 0) + { + free_stream(s); + return 1; + } + + out_uint32_le(s, reason); + s_mark_end(s); + + if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_DISCONNECT) != 0) + { + free_stream(s); + return 1; + } - make_stream(s); - init_stream(s, 8192); - if (xrdp_rdp_init_data(self, s) != 0) - { - free_stream(s); - return 1; - } - out_uint32_le(s, reason); - s_mark_end(s); - if (xrdp_rdp_send_data(self, s, RDP_DATA_PDU_DISCONNECT) != 0) - { free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } #endif /*****************************************************************************/ /* RDP_PDU_DATA */ int APP_CC -xrdp_rdp_process_data(struct xrdp_rdp* self, struct stream* s) +xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s) { - int len; - int data_type; - int ctype; - int clen; - - in_uint8s(s, 6); - in_uint16_le(s, len); - in_uint8(s, data_type); - in_uint8(s, ctype); - in_uint16_le(s, clen); - DEBUG(("xrdp_rdp_process_data code %d", data_type)); - switch (data_type) - { - case RDP_DATA_PDU_POINTER: /* 27(0x1b) */ - xrdp_rdp_process_data_pointer(self, s); - break; - case RDP_DATA_PDU_INPUT: /* 28(0x1c) */ - xrdp_rdp_process_data_input(self, s); - break; - case RDP_DATA_PDU_CONTROL: /* 20(0x14) */ - xrdp_rdp_process_data_control(self, s); - break; - case RDP_DATA_PDU_SYNCHRONISE: /* 31(0x1f) */ - xrdp_rdp_process_data_sync(self); - break; - case 33: /* 33(0x21) ?? Invalidate an area I think */ - xrdp_rdp_process_screen_update(self, s); - break; - case 35: /* 35(0x23) */ - /* 35 ?? this comes when minimuzing a full screen mstsc.exe 2600 */ - /* I think this is saying the client no longer wants screen */ - /* updates and it will issue a 33 above to catch up */ - /* so minimized apps don't take bandwidth */ - break; - case 36: /* 36(0x24) ?? disconnect query? */ - /* when this message comes, send a 37 back so the client */ - /* is sure the connection is alive and it can ask if user */ - /* really wants to disconnect */ - xrdp_rdp_send_disconnect_query_response(self); /* send a 37 back */ - break; - case RDP_DATA_PDU_FONT2: /* 39(0x27) */ - xrdp_rdp_process_data_font(self, s); - break; - default: - g_writeln("unknown in xrdp_rdp_process_data %d", data_type); - break; - } - return 0; + int len; + int data_type; + int ctype; + int clen; + + in_uint8s(s, 6); + in_uint16_le(s, len); + in_uint8(s, data_type); + in_uint8(s, ctype); + in_uint16_le(s, clen); + DEBUG(("xrdp_rdp_process_data code %d", data_type)); + + switch (data_type) + { + case RDP_DATA_PDU_POINTER: /* 27(0x1b) */ + xrdp_rdp_process_data_pointer(self, s); + break; + case RDP_DATA_PDU_INPUT: /* 28(0x1c) */ + xrdp_rdp_process_data_input(self, s); + break; + case RDP_DATA_PDU_CONTROL: /* 20(0x14) */ + xrdp_rdp_process_data_control(self, s); + break; + case RDP_DATA_PDU_SYNCHRONISE: /* 31(0x1f) */ + xrdp_rdp_process_data_sync(self); + break; + case 33: /* 33(0x21) ?? Invalidate an area I think */ + xrdp_rdp_process_screen_update(self, s); + break; + case 35: /* 35(0x23) */ + /* 35 ?? this comes when minimuzing a full screen mstsc.exe 2600 */ + /* I think this is saying the client no longer wants screen */ + /* updates and it will issue a 33 above to catch up */ + /* so minimized apps don't take bandwidth */ + break; + case 36: /* 36(0x24) ?? disconnect query? */ + /* when this message comes, send a 37 back so the client */ + /* is sure the connection is alive and it can ask if user */ + /* really wants to disconnect */ + xrdp_rdp_send_disconnect_query_response(self); /* send a 37 back */ + break; + case RDP_DATA_PDU_FONT2: /* 39(0x27) */ + xrdp_rdp_process_data_font(self, s); + break; + default: + g_writeln("unknown in xrdp_rdp_process_data %d", data_type); + break; + } + + return 0; } /*****************************************************************************/ int APP_CC -xrdp_rdp_disconnect(struct xrdp_rdp* self) +xrdp_rdp_disconnect(struct xrdp_rdp *self) { - int rv; + int rv; - DEBUG(("in xrdp_rdp_disconnect")); - rv = xrdp_sec_disconnect(self->sec_layer); - DEBUG(("out xrdp_rdp_disconnect")); - return rv; + DEBUG(("in xrdp_rdp_disconnect")); + rv = xrdp_sec_disconnect(self->sec_layer); + DEBUG(("out xrdp_rdp_disconnect")); + return rv; } /*****************************************************************************/ int APP_CC -xrdp_rdp_send_deactive(struct xrdp_rdp* self) +xrdp_rdp_send_deactive(struct xrdp_rdp *self) { - struct stream* s; + struct stream *s; + + DEBUG(("in xrdp_rdp_send_deactive")); + make_stream(s); + init_stream(s, 8192); + + if (xrdp_rdp_init(self, s) != 0) + { + free_stream(s); + DEBUG(("out xrdp_rdp_send_deactive error")); + return 1; + } + + s_mark_end(s); + + if (xrdp_rdp_send(self, s, RDP_PDU_DEACTIVATE) != 0) + { + free_stream(s); + DEBUG(("out xrdp_rdp_send_deactive error")); + return 1; + } - DEBUG(("in xrdp_rdp_send_deactive")); - make_stream(s); - init_stream(s, 8192); - if (xrdp_rdp_init(self, s) != 0) - { - free_stream(s); - DEBUG(("out xrdp_rdp_send_deactive error")); - return 1; - } - s_mark_end(s); - if (xrdp_rdp_send(self, s, RDP_PDU_DEACTIVATE) != 0) - { free_stream(s); - DEBUG(("out xrdp_rdp_send_deactive error")); - return 1; - } - free_stream(s); - DEBUG(("out xrdp_rdp_send_deactive")); - return 0; + DEBUG(("out xrdp_rdp_send_deactive")); + return 0; } diff --git a/libxrdp/xrdp_sec.c b/libxrdp/xrdp_sec.c index 381e8435..66b66264 100644 --- a/libxrdp/xrdp_sec.c +++ b/libxrdp/xrdp_sec.c @@ -1,1008 +1,1111 @@ -/* - 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. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - secure layer - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004-2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * secure layer + */ #include "libxrdp.h" /* some compilers need unsigned char to avoid warnings */ static tui8 g_pad_54[40] = -{ 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, - 54, 54, 54, 54, 54, 54, 54, 54 }; +{ + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, 54, + 54, 54, 54, 54, 54, 54, 54, 54 +}; /* some compilers need unsigned char to avoid warnings */ static tui8 g_pad_92[48] = -{ 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, - 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92 }; +{ + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, + 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92, 92 +}; /* some compilers need unsigned char to avoid warnings */ static tui8 g_lic1[322] = -{ 0x80, 0x00, 0x3e, 0x01, 0x01, 0x02, 0x3e, 0x01, - 0x7b, 0x3c, 0x31, 0xa6, 0xae, 0xe8, 0x74, 0xf6, - 0xb4, 0xa5, 0x03, 0x90, 0xe7, 0xc2, 0xc7, 0x39, - 0xba, 0x53, 0x1c, 0x30, 0x54, 0x6e, 0x90, 0x05, - 0xd0, 0x05, 0xce, 0x44, 0x18, 0x91, 0x83, 0x81, - 0x00, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00, - 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72, 0x00, - 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x66, 0x00, - 0x74, 0x00, 0x20, 0x00, 0x43, 0x00, 0x6f, 0x00, - 0x72, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72, 0x00, - 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, - 0x6e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, - 0x32, 0x00, 0x33, 0x00, 0x36, 0x00, 0x00, 0x00, - 0x0d, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x03, 0x00, 0xb8, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x06, 0x00, 0x5c, 0x00, 0x52, 0x53, 0x41, 0x31, - 0x48, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, - 0x3f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, - 0x01, 0xc7, 0xc9, 0xf7, 0x8e, 0x5a, 0x38, 0xe4, - 0x29, 0xc3, 0x00, 0x95, 0x2d, 0xdd, 0x4c, 0x3e, - 0x50, 0x45, 0x0b, 0x0d, 0x9e, 0x2a, 0x5d, 0x18, - 0x63, 0x64, 0xc4, 0x2c, 0xf7, 0x8f, 0x29, 0xd5, - 0x3f, 0xc5, 0x35, 0x22, 0x34, 0xff, 0xad, 0x3a, - 0xe6, 0xe3, 0x95, 0x06, 0xae, 0x55, 0x82, 0xe3, - 0xc8, 0xc7, 0xb4, 0xa8, 0x47, 0xc8, 0x50, 0x71, - 0x74, 0x29, 0x53, 0x89, 0x6d, 0x9c, 0xed, 0x70, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x08, 0x00, 0x48, 0x00, 0xa8, 0xf4, 0x31, 0xb9, - 0xab, 0x4b, 0xe6, 0xb4, 0xf4, 0x39, 0x89, 0xd6, - 0xb1, 0xda, 0xf6, 0x1e, 0xec, 0xb1, 0xf0, 0x54, - 0x3b, 0x5e, 0x3e, 0x6a, 0x71, 0xb4, 0xf7, 0x75, - 0xc8, 0x16, 0x2f, 0x24, 0x00, 0xde, 0xe9, 0x82, - 0x99, 0x5f, 0x33, 0x0b, 0xa9, 0xa6, 0x94, 0xaf, - 0xcb, 0x11, 0xc3, 0xf2, 0xdb, 0x09, 0x42, 0x68, - 0x29, 0x56, 0x58, 0x01, 0x56, 0xdb, 0x59, 0x03, - 0x69, 0xdb, 0x7d, 0x37, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, - 0x0e, 0x00, 0x0e, 0x00, 0x6d, 0x69, 0x63, 0x72, - 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, - 0x6d, 0x00 }; +{ + 0x80, 0x00, 0x3e, 0x01, 0x01, 0x02, 0x3e, 0x01, + 0x7b, 0x3c, 0x31, 0xa6, 0xae, 0xe8, 0x74, 0xf6, + 0xb4, 0xa5, 0x03, 0x90, 0xe7, 0xc2, 0xc7, 0x39, + 0xba, 0x53, 0x1c, 0x30, 0x54, 0x6e, 0x90, 0x05, + 0xd0, 0x05, 0xce, 0x44, 0x18, 0x91, 0x83, 0x81, + 0x00, 0x00, 0x04, 0x00, 0x2c, 0x00, 0x00, 0x00, + 0x4d, 0x00, 0x69, 0x00, 0x63, 0x00, 0x72, 0x00, + 0x6f, 0x00, 0x73, 0x00, 0x6f, 0x00, 0x66, 0x00, + 0x74, 0x00, 0x20, 0x00, 0x43, 0x00, 0x6f, 0x00, + 0x72, 0x00, 0x70, 0x00, 0x6f, 0x00, 0x72, 0x00, + 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, + 0x6e, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0x32, 0x00, 0x33, 0x00, 0x36, 0x00, 0x00, 0x00, + 0x0d, 0x00, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x03, 0x00, 0xb8, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x06, 0x00, 0x5c, 0x00, 0x52, 0x53, 0x41, 0x31, + 0x48, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, + 0x3f, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, + 0x01, 0xc7, 0xc9, 0xf7, 0x8e, 0x5a, 0x38, 0xe4, + 0x29, 0xc3, 0x00, 0x95, 0x2d, 0xdd, 0x4c, 0x3e, + 0x50, 0x45, 0x0b, 0x0d, 0x9e, 0x2a, 0x5d, 0x18, + 0x63, 0x64, 0xc4, 0x2c, 0xf7, 0x8f, 0x29, 0xd5, + 0x3f, 0xc5, 0x35, 0x22, 0x34, 0xff, 0xad, 0x3a, + 0xe6, 0xe3, 0x95, 0x06, 0xae, 0x55, 0x82, 0xe3, + 0xc8, 0xc7, 0xb4, 0xa8, 0x47, 0xc8, 0x50, 0x71, + 0x74, 0x29, 0x53, 0x89, 0x6d, 0x9c, 0xed, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x48, 0x00, 0xa8, 0xf4, 0x31, 0xb9, + 0xab, 0x4b, 0xe6, 0xb4, 0xf4, 0x39, 0x89, 0xd6, + 0xb1, 0xda, 0xf6, 0x1e, 0xec, 0xb1, 0xf0, 0x54, + 0x3b, 0x5e, 0x3e, 0x6a, 0x71, 0xb4, 0xf7, 0x75, + 0xc8, 0x16, 0x2f, 0x24, 0x00, 0xde, 0xe9, 0x82, + 0x99, 0x5f, 0x33, 0x0b, 0xa9, 0xa6, 0x94, 0xaf, + 0xcb, 0x11, 0xc3, 0xf2, 0xdb, 0x09, 0x42, 0x68, + 0x29, 0x56, 0x58, 0x01, 0x56, 0xdb, 0x59, 0x03, + 0x69, 0xdb, 0x7d, 0x37, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, + 0x0e, 0x00, 0x0e, 0x00, 0x6d, 0x69, 0x63, 0x72, + 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x2e, 0x63, 0x6f, + 0x6d, 0x00 +}; /* some compilers need unsigned char to avoid warnings */ static tui8 g_lic2[20] = -{ 0x80, 0x00, 0x10, 0x00, 0xff, 0x02, 0x10, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0x28, 0x14, 0x00, 0x00 }; +{ + 0x80, 0x00, 0x10, 0x00, 0xff, 0x02, 0x10, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0x28, 0x14, 0x00, 0x00 +}; /* mce */ /* some compilers need unsigned char to avoid warnings */ static tui8 g_lic3[20] = -{ 0x80, 0x02, 0x10, 0x00, 0xff, 0x03, 0x10, 0x00, - 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, - 0xf3, 0x99, 0x00, 0x00 }; +{ + 0x80, 0x02, 0x10, 0x00, 0xff, 0x03, 0x10, 0x00, + 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, + 0xf3, 0x99, 0x00, 0x00 +}; /*****************************************************************************/ static void APP_CC -hex_str_to_bin(char* in, char* out, int out_len) -{ - int in_index; - int in_len; - int out_index; - int val; - char hex[16]; - - in_len = g_strlen(in); - out_index = 0; - in_index = 0; - while (in_index <= (in_len - 4)) - { - if ((in[in_index] == '0') && (in[in_index + 1] == 'x')) - { - hex[0] = in[in_index + 2]; - hex[1] = in[in_index + 3]; - hex[2] = 0; - if (out_index < out_len) - { - val = g_htoi(hex); - out[out_index] = val; - } - out_index++; - } - in_index++; - } +hex_str_to_bin(char *in, char *out, int out_len) +{ + int in_index; + int in_len; + int out_index; + int val; + char hex[16]; + + in_len = g_strlen(in); + out_index = 0; + in_index = 0; + + while (in_index <= (in_len - 4)) + { + if ((in[in_index] == '0') && (in[in_index + 1] == 'x')) + { + hex[0] = in[in_index + 2]; + hex[1] = in[in_index + 3]; + hex[2] = 0; + + if (out_index < out_len) + { + val = g_htoi(hex); + out[out_index] = val; + } + + out_index++; + } + + in_index++; + } } /*****************************************************************************/ -struct xrdp_sec* APP_CC -xrdp_sec_create(struct xrdp_rdp* owner, struct trans* trans, int crypt_level, +struct xrdp_sec *APP_CC +xrdp_sec_create(struct xrdp_rdp *owner, struct trans *trans, int crypt_level, int channel_code) { - struct xrdp_sec* self; - - DEBUG((" in xrdp_sec_create")); - self = (struct xrdp_sec*)g_malloc(sizeof(struct xrdp_sec), 1); - self->rdp_layer = owner; - self->rc4_key_size = 1; /* 1 = 40 bit, 2 = 128 bit */ - self->crypt_level = 1; /* 1, 2, 3 = low, medium, high */ - switch (crypt_level) - { - case 1: - self->rc4_key_size = 1; - self->crypt_level = 1; - break; - case 2: - self->rc4_key_size = 1; - self->crypt_level = 2; - break; - case 3: - self->rc4_key_size = 2; - self->crypt_level = 3; - break; - default: - g_writeln("Fatal : Illegal crypt_level"); - break ; - } - self->channel_code = channel_code; - if(self->decrypt_rc4_info!=NULL) - { - g_writeln("xrdp_sec_create - decrypt_rc4_info already created !!!"); - } - self->decrypt_rc4_info = ssl_rc4_info_create(); - if(self->encrypt_rc4_info!=NULL) - { - g_writeln("xrdp_sec_create - encrypt_rc4_info already created !!!"); - } - self->encrypt_rc4_info = ssl_rc4_info_create(); - self->mcs_layer = xrdp_mcs_create(self, trans, &self->client_mcs_data, - &self->server_mcs_data); - self->chan_layer = xrdp_channel_create(self, self->mcs_layer); - DEBUG((" out xrdp_sec_create")); - return self; + struct xrdp_sec *self; + + DEBUG((" in xrdp_sec_create")); + self = (struct xrdp_sec *)g_malloc(sizeof(struct xrdp_sec), 1); + self->rdp_layer = owner; + self->rc4_key_size = 1; /* 1 = 40 bit, 2 = 128 bit */ + self->crypt_level = 1; /* 1, 2, 3 = low, medium, high */ + + switch (crypt_level) + { + case 1: + self->rc4_key_size = 1; + self->crypt_level = 1; + break; + case 2: + self->rc4_key_size = 1; + self->crypt_level = 2; + break; + case 3: + self->rc4_key_size = 2; + self->crypt_level = 3; + break; + default: + g_writeln("Fatal : Illegal crypt_level"); + break ; + } + + self->channel_code = channel_code; + + if (self->decrypt_rc4_info != NULL) + { + g_writeln("xrdp_sec_create - decrypt_rc4_info already created !!!"); + } + + self->decrypt_rc4_info = ssl_rc4_info_create(); + + if (self->encrypt_rc4_info != NULL) + { + g_writeln("xrdp_sec_create - encrypt_rc4_info already created !!!"); + } + + self->encrypt_rc4_info = ssl_rc4_info_create(); + self->mcs_layer = xrdp_mcs_create(self, trans, &self->client_mcs_data, + &self->server_mcs_data); + self->chan_layer = xrdp_channel_create(self, self->mcs_layer); + DEBUG((" out xrdp_sec_create")); + return self; } /*****************************************************************************/ void APP_CC -xrdp_sec_delete(struct xrdp_sec* self) -{ - if (self == 0) - { - g_writeln("xrdp_sec_delete: indata is null"); - return; - } - xrdp_channel_delete(self->chan_layer); - xrdp_mcs_delete(self->mcs_layer); - ssl_rc4_info_delete(self->decrypt_rc4_info); /* TODO clear all data */ - ssl_rc4_info_delete(self->encrypt_rc4_info); /* TODO clear all data */ - g_free(self->client_mcs_data.data); - g_free(self->server_mcs_data.data); - /* Crypto information must always be cleared */ - g_memset(self,0,sizeof(struct xrdp_sec)); - g_free(self); +xrdp_sec_delete(struct xrdp_sec *self) +{ + if (self == 0) + { + g_writeln("xrdp_sec_delete: indata is null"); + return; + } + + xrdp_channel_delete(self->chan_layer); + xrdp_mcs_delete(self->mcs_layer); + ssl_rc4_info_delete(self->decrypt_rc4_info); /* TODO clear all data */ + ssl_rc4_info_delete(self->encrypt_rc4_info); /* TODO clear all data */ + g_free(self->client_mcs_data.data); + g_free(self->server_mcs_data.data); + /* Crypto information must always be cleared */ + g_memset(self, 0, sizeof(struct xrdp_sec)); + g_free(self); } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_sec_init(struct xrdp_sec* self, struct stream* s) -{ - if (xrdp_mcs_init(self->mcs_layer, s) != 0) - { - return 1; - } - if (self->crypt_level > 1) - { - s_push_layer(s, sec_hdr, 4 + 8); - } - else - { - s_push_layer(s, sec_hdr, 4); - } - return 0; +xrdp_sec_init(struct xrdp_sec *self, struct stream *s) +{ + if (xrdp_mcs_init(self->mcs_layer, s) != 0) + { + return 1; + } + + if (self->crypt_level > 1) + { + s_push_layer(s, sec_hdr, 4 + 8); + } + else + { + s_push_layer(s, sec_hdr, 4); + } + + return 0; } /*****************************************************************************/ /* Reduce key entropy from 64 to 40 bits */ static void APP_CC -xrdp_sec_make_40bit(char* key) +xrdp_sec_make_40bit(char *key) { - key[0] = 0xd1; - key[1] = 0x26; - key[2] = 0x9e; + key[0] = 0xd1; + key[1] = 0x26; + key[2] = 0x9e; } /*****************************************************************************/ /* returns error */ /* update an encryption key */ static int APP_CC -xrdp_sec_update(char* key, char* update_key, int key_len) -{ - char shasig[20]; - void* sha1_info; - void* md5_info; - void* rc4_info; - - sha1_info = ssl_sha1_info_create(); - md5_info = ssl_md5_info_create(); - rc4_info = ssl_rc4_info_create(); - ssl_sha1_clear(sha1_info); - ssl_sha1_transform(sha1_info, update_key, key_len); - ssl_sha1_transform(sha1_info, (char*)g_pad_54, 40); - ssl_sha1_transform(sha1_info, key, key_len); - ssl_sha1_complete(sha1_info, shasig); - ssl_md5_clear(md5_info); - ssl_md5_transform(md5_info, update_key, key_len); - ssl_md5_transform(md5_info, (char*)g_pad_92, 48); - ssl_md5_transform(md5_info, shasig, 20); - ssl_md5_complete(md5_info, key); - ssl_rc4_set_key(rc4_info, key, key_len); - ssl_rc4_crypt(rc4_info, key, key_len); - if (key_len == 8) - { - xrdp_sec_make_40bit(key); - } - ssl_sha1_info_delete(sha1_info); - ssl_md5_info_delete(md5_info); - ssl_rc4_info_delete(rc4_info); - return 0; +xrdp_sec_update(char *key, char *update_key, int key_len) +{ + char shasig[20]; + void *sha1_info; + void *md5_info; + void *rc4_info; + + sha1_info = ssl_sha1_info_create(); + md5_info = ssl_md5_info_create(); + rc4_info = ssl_rc4_info_create(); + ssl_sha1_clear(sha1_info); + ssl_sha1_transform(sha1_info, update_key, key_len); + ssl_sha1_transform(sha1_info, (char *)g_pad_54, 40); + ssl_sha1_transform(sha1_info, key, key_len); + ssl_sha1_complete(sha1_info, shasig); + ssl_md5_clear(md5_info); + ssl_md5_transform(md5_info, update_key, key_len); + ssl_md5_transform(md5_info, (char *)g_pad_92, 48); + ssl_md5_transform(md5_info, shasig, 20); + ssl_md5_complete(md5_info, key); + ssl_rc4_set_key(rc4_info, key, key_len); + ssl_rc4_crypt(rc4_info, key, key_len); + + if (key_len == 8) + { + xrdp_sec_make_40bit(key); + } + + ssl_sha1_info_delete(sha1_info); + ssl_md5_info_delete(md5_info); + ssl_rc4_info_delete(rc4_info); + return 0; } /*****************************************************************************/ static void APP_CC -xrdp_sec_decrypt(struct xrdp_sec* self, char* data, int len) -{ - if (self->decrypt_use_count == 4096) - { - xrdp_sec_update(self->decrypt_key, self->decrypt_update_key, - self->rc4_key_len); - ssl_rc4_set_key(self->decrypt_rc4_info, self->decrypt_key, - self->rc4_key_len); - self->decrypt_use_count = 0; - } - ssl_rc4_crypt(self->decrypt_rc4_info, data, len); - self->decrypt_use_count++; +xrdp_sec_decrypt(struct xrdp_sec *self, char *data, int len) +{ + if (self->decrypt_use_count == 4096) + { + xrdp_sec_update(self->decrypt_key, self->decrypt_update_key, + self->rc4_key_len); + ssl_rc4_set_key(self->decrypt_rc4_info, self->decrypt_key, + self->rc4_key_len); + self->decrypt_use_count = 0; + } + + ssl_rc4_crypt(self->decrypt_rc4_info, data, len); + self->decrypt_use_count++; } /*****************************************************************************/ static void APP_CC -xrdp_sec_encrypt(struct xrdp_sec* self, char* data, int len) -{ - if (self->encrypt_use_count == 4096) - { - xrdp_sec_update(self->encrypt_key, self->encrypt_update_key, - self->rc4_key_len); - ssl_rc4_set_key(self->encrypt_rc4_info, self->encrypt_key, - self->rc4_key_len); - self->encrypt_use_count = 0; - } - ssl_rc4_crypt(self->encrypt_rc4_info, data, len); - self->encrypt_use_count++; +xrdp_sec_encrypt(struct xrdp_sec *self, char *data, int len) +{ + if (self->encrypt_use_count == 4096) + { + xrdp_sec_update(self->encrypt_key, self->encrypt_update_key, + self->rc4_key_len); + ssl_rc4_set_key(self->encrypt_rc4_info, self->encrypt_key, + self->rc4_key_len); + self->encrypt_use_count = 0; + } + + ssl_rc4_crypt(self->encrypt_rc4_info, data, len); + self->encrypt_use_count++; } /*****************************************************************************/ static int APP_CC -unicode_in(struct stream* s, int uni_len, char* dst, int dst_len) -{ - int dst_index; - int src_index; - - dst_index = 0; - src_index = 0; - while (src_index < uni_len) - { - if (dst_index >= dst_len || src_index > 512) - { - break; - } - in_uint8(s, dst[dst_index]); - in_uint8s(s, 1); - dst_index++; - src_index += 2; - } - in_uint8s(s, 2); - return 0; +unicode_in(struct stream *s, int uni_len, char *dst, int dst_len) +{ + int dst_index; + int src_index; + + dst_index = 0; + src_index = 0; + + while (src_index < uni_len) + { + if (dst_index >= dst_len || src_index > 512) + { + break; + } + + in_uint8(s, dst[dst_index]); + in_uint8s(s, 1); + dst_index++; + src_index += 2; + } + + in_uint8s(s, 2); + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_sec_process_logon_info(struct xrdp_sec* self, struct stream* s) -{ - int flags = 0; - int len_domain = 0; - int len_user = 0; - int len_password = 0; - int len_program = 0; - int len_directory = 0; - int len_ip = 0; - int len_dll = 0; - int tzone = 0; - char tmpdata[256]; - - /* initialize (zero out) local variables */ - g_memset(tmpdata,0,sizeof(char)*256); - in_uint8s(s, 4); - in_uint32_le(s, flags); - DEBUG(("in xrdp_sec_process_logon_info flags $%x", flags)); - /* this is the first test that the decrypt is working */ - if ((flags & RDP_LOGON_NORMAL) != RDP_LOGON_NORMAL) /* 0x33 */ - { /* must be or error */ - DEBUG(("xrdp_sec_process_logon_info: flags wrong, major error")); - return 1; - } - if (flags & RDP_LOGON_LEAVE_AUDIO) - { - self->rdp_layer->client_info.sound_code = 1; - DEBUG(("flag RDP_LOGON_LEAVE_AUDIO found")); - } - if ((flags & RDP_LOGON_AUTO) && (!self->rdp_layer->client_info.is_mce)) - /* todo, for now not allowing autologon and mce both */ - { - self->rdp_layer->client_info.rdp_autologin = 1; - DEBUG(("flag RDP_LOGON_AUTO found")); - } - if (flags & RDP_COMPRESSION) - { - self->rdp_layer->client_info.rdp_compression = 1; - DEBUG(("flag RDP_COMPRESSION found")); - } - in_uint16_le(s, len_domain); - if (len_domain > 511) { - DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_domain > 511")); - return 1; - } - in_uint16_le(s, len_user); - if (len_user > 511) { - DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_user > 511")); - return 1; - } - in_uint16_le(s, len_password); - if (len_password > 511) { - DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_password > 511")); - return 1; - } - in_uint16_le(s, len_program); - if (len_program > 511) { - DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_program > 511")); - return 1; - } - in_uint16_le(s, len_directory); - if (len_directory > 511) { - DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_directory > 511")); - return 1; - } - unicode_in(s, len_domain, self->rdp_layer->client_info.domain, 255); - DEBUG(("domain %s", self->rdp_layer->client_info.domain)); - unicode_in(s, len_user, self->rdp_layer->client_info.username, 255); - DEBUG(("username %s", self->rdp_layer->client_info.username)); - if (flags & RDP_LOGON_AUTO) - { - unicode_in(s, len_password, self->rdp_layer->client_info.password, 255); - DEBUG(("flag RDP_LOGON_AUTO found")); - } - else - { - in_uint8s(s, len_password + 2); - } - unicode_in(s, len_program, self->rdp_layer->client_info.program, 255); - DEBUG(("program %s", self->rdp_layer->client_info.program)); - unicode_in(s, len_directory, self->rdp_layer->client_info.directory, 255); - DEBUG(("directory %s", self->rdp_layer->client_info.directory)); - if (flags & RDP_LOGON_BLOB) - { - in_uint8s(s, 2); /* unknown */ - in_uint16_le(s, len_ip); - unicode_in(s, len_ip - 2, tmpdata, 255); - in_uint16_le(s, len_dll); - unicode_in(s, len_dll - 2, tmpdata, 255); - in_uint32_le(s, tzone); /* len of timetone */ - in_uint8s(s, 62); /* skip */ - in_uint8s(s, 22); /* skip misc. */ - in_uint8s(s, 62); /* skip */ - in_uint8s(s, 26); /* skip stuff */ - in_uint32_le(s, self->rdp_layer->client_info.rdp5_performanceflags); - } - DEBUG(("out xrdp_sec_process_logon_info")); - return 0; +xrdp_sec_process_logon_info(struct xrdp_sec *self, struct stream *s) +{ + int flags = 0; + int len_domain = 0; + int len_user = 0; + int len_password = 0; + int len_program = 0; + int len_directory = 0; + int len_ip = 0; + int len_dll = 0; + int tzone = 0; + char tmpdata[256]; + + /* initialize (zero out) local variables */ + g_memset(tmpdata, 0, sizeof(char) * 256); + in_uint8s(s, 4); + in_uint32_le(s, flags); + DEBUG(("in xrdp_sec_process_logon_info flags $%x", flags)); + + /* this is the first test that the decrypt is working */ + if ((flags & RDP_LOGON_NORMAL) != RDP_LOGON_NORMAL) /* 0x33 */ + { + /* must be or error */ + DEBUG(("xrdp_sec_process_logon_info: flags wrong, major error")); + return 1; + } + + if (flags & RDP_LOGON_LEAVE_AUDIO) + { + self->rdp_layer->client_info.sound_code = 1; + DEBUG(("flag RDP_LOGON_LEAVE_AUDIO found")); + } + + if ((flags & RDP_LOGON_AUTO) && (!self->rdp_layer->client_info.is_mce)) + /* todo, for now not allowing autologon and mce both */ + { + self->rdp_layer->client_info.rdp_autologin = 1; + DEBUG(("flag RDP_LOGON_AUTO found")); + } + + if (flags & RDP_COMPRESSION) + { + self->rdp_layer->client_info.rdp_compression = 1; + DEBUG(("flag RDP_COMPRESSION found")); + } + + in_uint16_le(s, len_domain); + + if (len_domain > 511) + { + DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_domain > 511")); + return 1; + } + + in_uint16_le(s, len_user); + + if (len_user > 511) + { + DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_user > 511")); + return 1; + } + + in_uint16_le(s, len_password); + + if (len_password > 511) + { + DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_password > 511")); + return 1; + } + + in_uint16_le(s, len_program); + + if (len_program > 511) + { + DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_program > 511")); + return 1; + } + + in_uint16_le(s, len_directory); + + if (len_directory > 511) + { + DEBUG(("ERROR [xrdp_sec_process_logon_info()]: len_directory > 511")); + return 1; + } + + unicode_in(s, len_domain, self->rdp_layer->client_info.domain, 255); + DEBUG(("domain %s", self->rdp_layer->client_info.domain)); + unicode_in(s, len_user, self->rdp_layer->client_info.username, 255); + DEBUG(("username %s", self->rdp_layer->client_info.username)); + + if (flags & RDP_LOGON_AUTO) + { + unicode_in(s, len_password, self->rdp_layer->client_info.password, 255); + DEBUG(("flag RDP_LOGON_AUTO found")); + } + else + { + in_uint8s(s, len_password + 2); + } + + unicode_in(s, len_program, self->rdp_layer->client_info.program, 255); + DEBUG(("program %s", self->rdp_layer->client_info.program)); + unicode_in(s, len_directory, self->rdp_layer->client_info.directory, 255); + DEBUG(("directory %s", self->rdp_layer->client_info.directory)); + + if (flags & RDP_LOGON_BLOB) + { + in_uint8s(s, 2); /* unknown */ + in_uint16_le(s, len_ip); + unicode_in(s, len_ip - 2, tmpdata, 255); + in_uint16_le(s, len_dll); + unicode_in(s, len_dll - 2, tmpdata, 255); + in_uint32_le(s, tzone); /* len of timetone */ + in_uint8s(s, 62); /* skip */ + in_uint8s(s, 22); /* skip misc. */ + in_uint8s(s, 62); /* skip */ + in_uint8s(s, 26); /* skip stuff */ + in_uint32_le(s, self->rdp_layer->client_info.rdp5_performanceflags); + } + + DEBUG(("out xrdp_sec_process_logon_info")); + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_sec_send_lic_initial(struct xrdp_sec* self) +xrdp_sec_send_lic_initial(struct xrdp_sec *self) { - struct stream* s = (struct stream *)NULL; + struct stream *s = (struct stream *)NULL; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_mcs_init(self->mcs_layer, s) != 0) + { + free_stream(s); + return 1; + } + + out_uint8a(s, g_lic1, 322); + s_mark_end(s); + + if (xrdp_mcs_send(self->mcs_layer, s, MCS_GLOBAL_CHANNEL) != 0) + { + free_stream(s); + return 1; + } - make_stream(s); - init_stream(s, 8192); - if (xrdp_mcs_init(self->mcs_layer, s) != 0) - { - free_stream(s); - return 1; - } - out_uint8a(s, g_lic1, 322); - s_mark_end(s); - if (xrdp_mcs_send(self->mcs_layer, s, MCS_GLOBAL_CHANNEL) != 0) - { free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_sec_send_lic_response(struct xrdp_sec* self) +xrdp_sec_send_lic_response(struct xrdp_sec *self) { - struct stream* s; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_mcs_init(self->mcs_layer, s) != 0) + { + free_stream(s); + return 1; + } + + out_uint8a(s, g_lic2, 20); + s_mark_end(s); + + if (xrdp_mcs_send(self->mcs_layer, s, MCS_GLOBAL_CHANNEL) != 0) + { + free_stream(s); + return 1; + } - make_stream(s); - init_stream(s, 8192); - if (xrdp_mcs_init(self->mcs_layer, s) != 0) - { - free_stream(s); - return 1; - } - out_uint8a(s, g_lic2, 20); - s_mark_end(s); - if (xrdp_mcs_send(self->mcs_layer, s, MCS_GLOBAL_CHANNEL) != 0) - { free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ /* returns error */ static int APP_CC -xrdp_sec_send_media_lic_response(struct xrdp_sec* self) +xrdp_sec_send_media_lic_response(struct xrdp_sec *self) { - struct stream* s; + struct stream *s; + + make_stream(s); + init_stream(s, 8192); + + if (xrdp_mcs_init(self->mcs_layer, s) != 0) + { + free_stream(s); + return 1; + } + + out_uint8a(s, g_lic3, sizeof(g_lic3)); + s_mark_end(s); + + if (xrdp_mcs_send(self->mcs_layer, s, MCS_GLOBAL_CHANNEL) != 0) + { + free_stream(s); + return 1; + } - make_stream(s); - init_stream(s, 8192); - if (xrdp_mcs_init(self->mcs_layer, s) != 0) - { - free_stream(s); - return 1; - } - out_uint8a(s, g_lic3, sizeof(g_lic3)); - s_mark_end(s); - if (xrdp_mcs_send(self->mcs_layer, s, MCS_GLOBAL_CHANNEL) != 0) - { free_stream(s); - return 1; - } - free_stream(s); - return 0; + return 0; } /*****************************************************************************/ static void APP_CC -xrdp_sec_rsa_op(char* out, char* in, char* mod, char* exp) +xrdp_sec_rsa_op(char *out, char *in, char *mod, char *exp) { - ssl_mod_exp(out, 64, in, 64, mod, 64, exp, 64); + ssl_mod_exp(out, 64, in, 64, mod, 64, exp, 64); } /*****************************************************************************/ static void APP_CC -xrdp_sec_hash_48(char* out, char* in, char* salt1, char* salt2, int salt) -{ - int i; - void* sha1_info; - void* md5_info; - char pad[4]; - char sha1_sig[20]; - char md5_sig[16]; - - sha1_info = ssl_sha1_info_create(); - md5_info = ssl_md5_info_create(); - for (i = 0; i < 3; i++) - { - g_memset(pad, salt + i, 4); - ssl_sha1_clear(sha1_info); - ssl_sha1_transform(sha1_info, pad, i + 1); - ssl_sha1_transform(sha1_info, in, 48); - ssl_sha1_transform(sha1_info, salt1, 32); - ssl_sha1_transform(sha1_info, salt2, 32); - ssl_sha1_complete(sha1_info, sha1_sig); - ssl_md5_clear(md5_info); - ssl_md5_transform(md5_info, in, 48); - ssl_md5_transform(md5_info, sha1_sig, 20); - ssl_md5_complete(md5_info, md5_sig); - g_memcpy(out + i * 16, md5_sig, 16); - } - ssl_sha1_info_delete(sha1_info); - ssl_md5_info_delete(md5_info); +xrdp_sec_hash_48(char *out, char *in, char *salt1, char *salt2, int salt) +{ + int i; + void *sha1_info; + void *md5_info; + char pad[4]; + char sha1_sig[20]; + char md5_sig[16]; + + sha1_info = ssl_sha1_info_create(); + md5_info = ssl_md5_info_create(); + + for (i = 0; i < 3; i++) + { + g_memset(pad, salt + i, 4); + ssl_sha1_clear(sha1_info); + ssl_sha1_transform(sha1_info, pad, i + 1); + ssl_sha1_transform(sha1_info, in, 48); + ssl_sha1_transform(sha1_info, salt1, 32); + ssl_sha1_transform(sha1_info, salt2, 32); + ssl_sha1_complete(sha1_info, sha1_sig); + ssl_md5_clear(md5_info); + ssl_md5_transform(md5_info, in, 48); + ssl_md5_transform(md5_info, sha1_sig, 20); + ssl_md5_complete(md5_info, md5_sig); + g_memcpy(out + i * 16, md5_sig, 16); + } + + ssl_sha1_info_delete(sha1_info); + ssl_md5_info_delete(md5_info); } /*****************************************************************************/ static void APP_CC -xrdp_sec_hash_16(char* out, char* in, char* salt1, char* salt2) +xrdp_sec_hash_16(char *out, char *in, char *salt1, char *salt2) { - void* md5_info; + void *md5_info; - md5_info = ssl_md5_info_create(); - ssl_md5_clear(md5_info); - ssl_md5_transform(md5_info, in, 16); - ssl_md5_transform(md5_info, salt1, 32); - ssl_md5_transform(md5_info, salt2, 32); - ssl_md5_complete(md5_info, out); - ssl_md5_info_delete(md5_info); + md5_info = ssl_md5_info_create(); + ssl_md5_clear(md5_info); + ssl_md5_transform(md5_info, in, 16); + ssl_md5_transform(md5_info, salt1, 32); + ssl_md5_transform(md5_info, salt2, 32); + ssl_md5_complete(md5_info, out); + ssl_md5_info_delete(md5_info); } /*****************************************************************************/ static void APP_CC -xrdp_sec_establish_keys(struct xrdp_sec* self) -{ - char session_key[48]; - char temp_hash[48]; - char input[48]; - - g_memcpy(input, self->client_random, 24); - g_memcpy(input + 24, self->server_random, 24); - xrdp_sec_hash_48(temp_hash, input, self->client_random, - self->server_random, 65); - xrdp_sec_hash_48(session_key, temp_hash, self->client_random, - self->server_random, 88); - g_memcpy(self->sign_key, session_key, 16); - xrdp_sec_hash_16(self->encrypt_key, session_key + 16, self->client_random, - self->server_random); - xrdp_sec_hash_16(self->decrypt_key, session_key + 32, self->client_random, - self->server_random); - if (self->rc4_key_size == 1) - { - xrdp_sec_make_40bit(self->sign_key); - xrdp_sec_make_40bit(self->encrypt_key); - xrdp_sec_make_40bit(self->decrypt_key); - self->rc4_key_len = 8; - } - else - { - self->rc4_key_len = 16; - } - g_memcpy(self->decrypt_update_key, self->decrypt_key, 16); - g_memcpy(self->encrypt_update_key, self->encrypt_key, 16); - ssl_rc4_set_key(self->decrypt_rc4_info, self->decrypt_key, self->rc4_key_len); - ssl_rc4_set_key(self->encrypt_rc4_info, self->encrypt_key, self->rc4_key_len); +xrdp_sec_establish_keys(struct xrdp_sec *self) +{ + char session_key[48]; + char temp_hash[48]; + char input[48]; + + g_memcpy(input, self->client_random, 24); + g_memcpy(input + 24, self->server_random, 24); + xrdp_sec_hash_48(temp_hash, input, self->client_random, + self->server_random, 65); + xrdp_sec_hash_48(session_key, temp_hash, self->client_random, + self->server_random, 88); + g_memcpy(self->sign_key, session_key, 16); + xrdp_sec_hash_16(self->encrypt_key, session_key + 16, self->client_random, + self->server_random); + xrdp_sec_hash_16(self->decrypt_key, session_key + 32, self->client_random, + self->server_random); + + if (self->rc4_key_size == 1) + { + xrdp_sec_make_40bit(self->sign_key); + xrdp_sec_make_40bit(self->encrypt_key); + xrdp_sec_make_40bit(self->decrypt_key); + self->rc4_key_len = 8; + } + else + { + self->rc4_key_len = 16; + } + + g_memcpy(self->decrypt_update_key, self->decrypt_key, 16); + g_memcpy(self->encrypt_update_key, self->encrypt_key, 16); + ssl_rc4_set_key(self->decrypt_rc4_info, self->decrypt_key, self->rc4_key_len); + ssl_rc4_set_key(self->encrypt_rc4_info, self->encrypt_key, self->rc4_key_len); } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_sec_recv(struct xrdp_sec* self, struct stream* s, int* chan) -{ - int flags; - int len; - - DEBUG((" in xrdp_sec_recv")); - if (xrdp_mcs_recv(self->mcs_layer, s, chan) != 0) - { - DEBUG((" out xrdp_sec_recv error")); - return 1; - } - in_uint32_le(s, flags); - DEBUG((" in xrdp_sec_recv flags $%x", flags)); - if (flags & SEC_ENCRYPT) /* 0x08 */ - { - in_uint8s(s, 8); /* signature */ - xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p)); - } - if (flags & SEC_CLIENT_RANDOM) /* 0x01 */ - { - in_uint32_le(s, len); - in_uint8a(s, self->client_crypt_random, 64); - xrdp_sec_rsa_op(self->client_random, self->client_crypt_random, - self->pub_mod, self->pri_exp); - xrdp_sec_establish_keys(self); - *chan = 1; /* just set a non existing channel and exit */ - DEBUG((" out xrdp_sec_recv")); - return 0; - } - if (flags & SEC_LOGON_INFO) /* 0x40 */ - { - if (xrdp_sec_process_logon_info(self, s) != 0) - { - DEBUG((" out xrdp_sec_recv error")); - return 1; - } - if (self->rdp_layer->client_info.is_mce) +xrdp_sec_recv(struct xrdp_sec *self, struct stream *s, int *chan) +{ + int flags; + int len; + + DEBUG((" in xrdp_sec_recv")); + + if (xrdp_mcs_recv(self->mcs_layer, s, chan) != 0) { - if (xrdp_sec_send_media_lic_response(self) != 0) - { DEBUG((" out xrdp_sec_recv error")); return 1; - } - DEBUG((" out xrdp_sec_recv")); - return -1; /* special error that means send demand active */ } - if (xrdp_sec_send_lic_initial(self) != 0) + + in_uint32_le(s, flags); + DEBUG((" in xrdp_sec_recv flags $%x", flags)); + + if (flags & SEC_ENCRYPT) /* 0x08 */ + { + in_uint8s(s, 8); /* signature */ + xrdp_sec_decrypt(self, s->p, (int)(s->end - s->p)); + } + + if (flags & SEC_CLIENT_RANDOM) /* 0x01 */ { - DEBUG((" out xrdp_sec_recv error")); - return 1; + in_uint32_le(s, len); + in_uint8a(s, self->client_crypt_random, 64); + xrdp_sec_rsa_op(self->client_random, self->client_crypt_random, + self->pub_mod, self->pri_exp); + xrdp_sec_establish_keys(self); + *chan = 1; /* just set a non existing channel and exit */ + DEBUG((" out xrdp_sec_recv")); + return 0; } - *chan = 1; /* just set a non existing channel and exit */ - DEBUG((" out xrdp_sec_recv")); - return 0; - } - if (flags & SEC_LICENCE_NEG) /* 0x80 */ - { - if (xrdp_sec_send_lic_response(self) != 0) + + if (flags & SEC_LOGON_INFO) /* 0x40 */ { - DEBUG((" out xrdp_sec_recv error")); - return 1; + if (xrdp_sec_process_logon_info(self, s) != 0) + { + DEBUG((" out xrdp_sec_recv error")); + return 1; + } + + if (self->rdp_layer->client_info.is_mce) + { + if (xrdp_sec_send_media_lic_response(self) != 0) + { + DEBUG((" out xrdp_sec_recv error")); + return 1; + } + + DEBUG((" out xrdp_sec_recv")); + return -1; /* special error that means send demand active */ + } + + if (xrdp_sec_send_lic_initial(self) != 0) + { + DEBUG((" out xrdp_sec_recv error")); + return 1; + } + + *chan = 1; /* just set a non existing channel and exit */ + DEBUG((" out xrdp_sec_recv")); + return 0; + } + + if (flags & SEC_LICENCE_NEG) /* 0x80 */ + { + if (xrdp_sec_send_lic_response(self) != 0) + { + DEBUG((" out xrdp_sec_recv error")); + return 1; + } + + DEBUG((" out xrdp_sec_recv")); + return -1; /* special error that means send demand active */ } + DEBUG((" out xrdp_sec_recv")); - return -1; /* special error that means send demand active */ - } - DEBUG((" out xrdp_sec_recv")); - return 0; + return 0; } /*****************************************************************************/ /* Output a uint32 into a buffer (little-endian) */ static void -buf_out_uint32(char* buffer, int value) +buf_out_uint32(char *buffer, int value) { - buffer[0] = (value) & 0xff; - buffer[1] = (value >> 8) & 0xff; - buffer[2] = (value >> 16) & 0xff; - buffer[3] = (value >> 24) & 0xff; + buffer[0] = (value) & 0xff; + buffer[1] = (value >> 8) & 0xff; + buffer[2] = (value >> 16) & 0xff; + buffer[3] = (value >> 24) & 0xff; } /*****************************************************************************/ /* Generate a MAC hash (5.2.3.1), using a combination of SHA1 and MD5 */ static void APP_CC -xrdp_sec_sign(struct xrdp_sec* self, char* out, int out_len, - char* data, int data_len) -{ - char shasig[20]; - char md5sig[16]; - char lenhdr[4]; - void* sha1_info; - void* md5_info; - - buf_out_uint32(lenhdr, data_len); - sha1_info = ssl_sha1_info_create(); - md5_info = ssl_md5_info_create(); - ssl_sha1_clear(sha1_info); - ssl_sha1_transform(sha1_info, self->sign_key, self->rc4_key_len); - ssl_sha1_transform(sha1_info, (char*)g_pad_54, 40); - ssl_sha1_transform(sha1_info, lenhdr, 4); - ssl_sha1_transform(sha1_info, data, data_len); - ssl_sha1_complete(sha1_info, shasig); - ssl_md5_clear(md5_info); - ssl_md5_transform(md5_info, self->sign_key, self->rc4_key_len); - ssl_md5_transform(md5_info, (char*)g_pad_92, 48); - ssl_md5_transform(md5_info, shasig, 20); - ssl_md5_complete(md5_info, md5sig); - g_memcpy(out, md5sig, out_len); - ssl_sha1_info_delete(sha1_info); - ssl_md5_info_delete(md5_info); +xrdp_sec_sign(struct xrdp_sec *self, char *out, int out_len, + char *data, int data_len) +{ + char shasig[20]; + char md5sig[16]; + char lenhdr[4]; + void *sha1_info; + void *md5_info; + + buf_out_uint32(lenhdr, data_len); + sha1_info = ssl_sha1_info_create(); + md5_info = ssl_md5_info_create(); + ssl_sha1_clear(sha1_info); + ssl_sha1_transform(sha1_info, self->sign_key, self->rc4_key_len); + ssl_sha1_transform(sha1_info, (char *)g_pad_54, 40); + ssl_sha1_transform(sha1_info, lenhdr, 4); + ssl_sha1_transform(sha1_info, data, data_len); + ssl_sha1_complete(sha1_info, shasig); + ssl_md5_clear(md5_info); + ssl_md5_transform(md5_info, self->sign_key, self->rc4_key_len); + ssl_md5_transform(md5_info, (char *)g_pad_92, 48); + ssl_md5_transform(md5_info, shasig, 20); + ssl_md5_complete(md5_info, md5sig); + g_memcpy(out, md5sig, out_len); + ssl_sha1_info_delete(sha1_info); + ssl_md5_info_delete(md5_info); } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_sec_send(struct xrdp_sec* self, struct stream* s, int chan) -{ - int datalen; - - DEBUG((" in xrdp_sec_send")); - s_pop_layer(s, sec_hdr); - if (self->crypt_level > 1) - { - out_uint32_le(s, SEC_ENCRYPT); - datalen = (int)((s->end - s->p) - 8); - xrdp_sec_sign(self, s->p, 8, s->p + 8, datalen); - xrdp_sec_encrypt(self, s->p + 8, datalen); - } - else - { - out_uint32_le(s, 0); - } - if (xrdp_mcs_send(self->mcs_layer, s, chan) != 0) - { - return 1; - } - DEBUG((" out xrdp_sec_send")); - return 0; +xrdp_sec_send(struct xrdp_sec *self, struct stream *s, int chan) +{ + int datalen; + + DEBUG((" in xrdp_sec_send")); + s_pop_layer(s, sec_hdr); + + if (self->crypt_level > 1) + { + out_uint32_le(s, SEC_ENCRYPT); + datalen = (int)((s->end - s->p) - 8); + xrdp_sec_sign(self, s->p, 8, s->p + 8, datalen); + xrdp_sec_encrypt(self, s->p + 8, datalen); + } + else + { + out_uint32_le(s, 0); + } + + if (xrdp_mcs_send(self->mcs_layer, s, chan) != 0) + { + return 1; + } + + DEBUG((" out xrdp_sec_send")); + return 0; } /*****************************************************************************/ /* this adds the mcs channels in the list of channels to be used when creating the server mcs data */ static int APP_CC -xrdp_sec_process_mcs_data_channels(struct xrdp_sec* self, struct stream* s) +xrdp_sec_process_mcs_data_channels(struct xrdp_sec *self, struct stream *s) { - int num_channels; - int index; - struct mcs_channel_item* channel_item; + int num_channels; + int index; + struct mcs_channel_item *channel_item; + + DEBUG(("processing channels, channel_code is %d", self->channel_code)); + + /* this is an option set in xrdp.ini */ + if (self->channel_code != 1) /* are channels on? */ + { + g_writeln("Processing channel data from client - The channel is off"); + return 0; + } + + in_uint32_le(s, num_channels); + + for (index = 0; index < num_channels; index++) + { + channel_item = (struct mcs_channel_item *) + g_malloc(sizeof(struct mcs_channel_item), 1); + in_uint8a(s, channel_item->name, 8); + in_uint32_le(s, channel_item->flags); + channel_item->chanid = MCS_GLOBAL_CHANNEL + (index + 1); + list_add_item(self->mcs_layer->channel_list, (long)channel_item); + DEBUG(("got channel flags %8.8x name %s", channel_item->flags, + channel_item->name)); + } - DEBUG(("processing channels, channel_code is %d", self->channel_code)); - /* this is an option set in xrdp.ini */ - if (self->channel_code != 1) /* are channels on? */ - { - g_writeln("Processing channel data from client - The channel is off"); return 0; - } - in_uint32_le(s, num_channels); - for (index = 0; index < num_channels; index++) - { - channel_item = (struct mcs_channel_item*) - g_malloc(sizeof(struct mcs_channel_item), 1); - in_uint8a(s, channel_item->name, 8); - in_uint32_le(s, channel_item->flags); - channel_item->chanid = MCS_GLOBAL_CHANNEL + (index + 1); - list_add_item(self->mcs_layer->channel_list, (long)channel_item); - DEBUG(("got channel flags %8.8x name %s", channel_item->flags, - channel_item->name)); - } - return 0; } /*****************************************************************************/ /* process client mcs data, we need some things in here to create the server mcs data */ int APP_CC -xrdp_sec_process_mcs_data(struct xrdp_sec* self) -{ - struct stream* s = (struct stream *)NULL; - char* hold_p = (char *)NULL; - int tag = 0; - int size = 0; - - s = &self->client_mcs_data; - /* set p to beginning */ - s->p = s->data; - /* skip header */ - in_uint8s(s, 23); - while (s_check_rem(s, 4)) - { - hold_p = s->p; - in_uint16_le(s, tag); - in_uint16_le(s, size); - if (size < 4 || !s_check_rem(s, size - 4)) - { - g_writeln("error in xrdp_sec_process_mcs_data tag %d size %d", - tag, size); - break; - } - switch (tag) - { - case SEC_TAG_CLI_INFO: - break; - case SEC_TAG_CLI_CRYPT: - break; - case SEC_TAG_CLI_CHANNELS: - xrdp_sec_process_mcs_data_channels(self, s); - break; - case SEC_TAG_CLI_4: - break; - default: - g_writeln("error unknown xrdp_sec_process_mcs_data tag %d size %d", - tag, size); - break; - } - s->p = hold_p + size; - } - /* set p to beginning */ - s->p = s->data; - return 0; +xrdp_sec_process_mcs_data(struct xrdp_sec *self) +{ + struct stream *s = (struct stream *)NULL; + char *hold_p = (char *)NULL; + int tag = 0; + int size = 0; + + s = &self->client_mcs_data; + /* set p to beginning */ + s->p = s->data; + /* skip header */ + in_uint8s(s, 23); + + while (s_check_rem(s, 4)) + { + hold_p = s->p; + in_uint16_le(s, tag); + in_uint16_le(s, size); + + if (size < 4 || !s_check_rem(s, size - 4)) + { + g_writeln("error in xrdp_sec_process_mcs_data tag %d size %d", + tag, size); + break; + } + + switch (tag) + { + case SEC_TAG_CLI_INFO: + break; + case SEC_TAG_CLI_CRYPT: + break; + case SEC_TAG_CLI_CHANNELS: + xrdp_sec_process_mcs_data_channels(self, s); + break; + case SEC_TAG_CLI_4: + break; + default: + g_writeln("error unknown xrdp_sec_process_mcs_data tag %d size %d", + tag, size); + break; + } + + s->p = hold_p + size; + } + + /* set p to beginning */ + s->p = s->data; + return 0; } /*****************************************************************************/ /* prepare server mcs data to send in mcs layer */ int APP_CC -xrdp_sec_out_mcs_data(struct xrdp_sec* self) -{ - struct stream* s; - int num_channels_even; - int num_channels; - int index; - int channel; - - num_channels = self->mcs_layer->channel_list->count; - num_channels_even = num_channels + (num_channels & 1); - s = &self->server_mcs_data; - init_stream(s, 512); - out_uint16_be(s, 5); - out_uint16_be(s, 0x14); - out_uint8(s, 0x7c); - out_uint16_be(s, 1); - out_uint8(s, 0x2a); - out_uint8(s, 0x14); - out_uint8(s, 0x76); - out_uint8(s, 0x0a); - out_uint8(s, 1); - out_uint8(s, 1); - out_uint8(s, 0); - out_uint16_le(s, 0xc001); - out_uint8(s, 0); - out_uint8(s, 0x4d); /* M */ - out_uint8(s, 0x63); /* c */ - out_uint8(s, 0x44); /* D */ - out_uint8(s, 0x6e); /* n */ - out_uint16_be(s, 0x80fc + (num_channels_even * 2)); - out_uint16_le(s, SEC_TAG_SRV_INFO); - out_uint16_le(s, 8); /* len */ - out_uint8(s, 4); /* 4 = rdp5 1 = rdp4 */ - out_uint8(s, 0); - out_uint8(s, 8); - out_uint8(s, 0); - out_uint16_le(s, SEC_TAG_SRV_CHANNELS); - out_uint16_le(s, 8 + (num_channels_even * 2)); /* len */ - out_uint16_le(s, MCS_GLOBAL_CHANNEL); /* 1003, 0x03eb main channel */ - out_uint16_le(s, num_channels); /* number of other channels */ - for (index = 0; index < num_channels_even; index++) - { - if (index < num_channels) - { - channel = MCS_GLOBAL_CHANNEL + (index + 1); - out_uint16_le(s, channel); - } - else +xrdp_sec_out_mcs_data(struct xrdp_sec *self) +{ + struct stream *s; + int num_channels_even; + int num_channels; + int index; + int channel; + + num_channels = self->mcs_layer->channel_list->count; + num_channels_even = num_channels + (num_channels & 1); + s = &self->server_mcs_data; + init_stream(s, 512); + out_uint16_be(s, 5); + out_uint16_be(s, 0x14); + out_uint8(s, 0x7c); + out_uint16_be(s, 1); + out_uint8(s, 0x2a); + out_uint8(s, 0x14); + out_uint8(s, 0x76); + out_uint8(s, 0x0a); + out_uint8(s, 1); + out_uint8(s, 1); + out_uint8(s, 0); + out_uint16_le(s, 0xc001); + out_uint8(s, 0); + out_uint8(s, 0x4d); /* M */ + out_uint8(s, 0x63); /* c */ + out_uint8(s, 0x44); /* D */ + out_uint8(s, 0x6e); /* n */ + out_uint16_be(s, 0x80fc + (num_channels_even * 2)); + out_uint16_le(s, SEC_TAG_SRV_INFO); + out_uint16_le(s, 8); /* len */ + out_uint8(s, 4); /* 4 = rdp5 1 = rdp4 */ + out_uint8(s, 0); + out_uint8(s, 8); + out_uint8(s, 0); + out_uint16_le(s, SEC_TAG_SRV_CHANNELS); + out_uint16_le(s, 8 + (num_channels_even * 2)); /* len */ + out_uint16_le(s, MCS_GLOBAL_CHANNEL); /* 1003, 0x03eb main channel */ + out_uint16_le(s, num_channels); /* number of other channels */ + + for (index = 0; index < num_channels_even; index++) { - out_uint16_le(s, 0); - } - } - out_uint16_le(s, SEC_TAG_SRV_CRYPT); - out_uint16_le(s, 0x00ec); /* len is 236 */ - out_uint32_le(s, self->rc4_key_size); /* key len 1 = 40 bit 2 = 128 bit */ - out_uint32_le(s, self->crypt_level); /* crypt level 1 = low 2 = medium */ - /* 3 = high */ - out_uint32_le(s, 32); /* 32 bytes random len */ - out_uint32_le(s, 0xb8); /* 184 bytes rsa info(certificate) len */ - out_uint8a(s, self->server_random, 32); - /* here to end is certificate */ - /* HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ */ - /* TermService\Parameters\Certificate */ - out_uint32_le(s, 1); - out_uint32_le(s, 1); - out_uint32_le(s, 1); - out_uint16_le(s, SEC_TAG_PUBKEY); - out_uint16_le(s, 0x005c); /* 92 bytes length of SEC_TAG_PUBKEY */ - out_uint32_le(s, SEC_RSA_MAGIC); - out_uint32_le(s, 0x48); /* 72 bytes modulus len */ - out_uint32_be(s, 0x00020000); - out_uint32_be(s, 0x3f000000); - out_uint8a(s, self->pub_exp, 4); /* pub exp */ - out_uint8a(s, self->pub_mod, 64); /* pub mod */ - out_uint8s(s, 8); /* pad */ - out_uint16_le(s, SEC_TAG_KEYSIG); - out_uint16_le(s, 72); /* len */ - out_uint8a(s, self->pub_sig, 64); /* pub sig */ - out_uint8s(s, 8); /* pad */ - /* end certificate */ - s_mark_end(s); - return 0; + if (index < num_channels) + { + channel = MCS_GLOBAL_CHANNEL + (index + 1); + out_uint16_le(s, channel); + } + else + { + out_uint16_le(s, 0); + } + } + + out_uint16_le(s, SEC_TAG_SRV_CRYPT); + out_uint16_le(s, 0x00ec); /* len is 236 */ + out_uint32_le(s, self->rc4_key_size); /* key len 1 = 40 bit 2 = 128 bit */ + out_uint32_le(s, self->crypt_level); /* crypt level 1 = low 2 = medium */ + /* 3 = high */ + out_uint32_le(s, 32); /* 32 bytes random len */ + out_uint32_le(s, 0xb8); /* 184 bytes rsa info(certificate) len */ + out_uint8a(s, self->server_random, 32); + /* here to end is certificate */ + /* HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\ */ + /* TermService\Parameters\Certificate */ + out_uint32_le(s, 1); + out_uint32_le(s, 1); + out_uint32_le(s, 1); + out_uint16_le(s, SEC_TAG_PUBKEY); + out_uint16_le(s, 0x005c); /* 92 bytes length of SEC_TAG_PUBKEY */ + out_uint32_le(s, SEC_RSA_MAGIC); + out_uint32_le(s, 0x48); /* 72 bytes modulus len */ + out_uint32_be(s, 0x00020000); + out_uint32_be(s, 0x3f000000); + out_uint8a(s, self->pub_exp, 4); /* pub exp */ + out_uint8a(s, self->pub_mod, 64); /* pub mod */ + out_uint8s(s, 8); /* pad */ + out_uint16_le(s, SEC_TAG_KEYSIG); + out_uint16_le(s, 72); /* len */ + out_uint8a(s, self->pub_sig, 64); /* pub sig */ + out_uint8s(s, 8); /* pad */ + /* end certificate */ + s_mark_end(s); + return 0; } /*****************************************************************************/ /* process the mcs client data we received from the mcs layer */ static void APP_CC -xrdp_sec_in_mcs_data(struct xrdp_sec* self) -{ - struct stream* s = (struct stream *)NULL; - struct xrdp_client_info* client_info = (struct xrdp_client_info *)NULL; - int index = 0; - char c = 0; - - client_info = &(self->rdp_layer->client_info); - s = &(self->client_mcs_data); - /* get hostname, its unicode */ - s->p = s->data; - in_uint8s(s, 47); - g_memset(client_info->hostname, 0, 32); - c = 1; - index = 0; - while (index < 16 && c != 0) - { - in_uint8(s, c); - in_uint8s(s, 1); - client_info->hostname[index] = c; - index++; - } - /* get build */ - s->p = s->data; - in_uint8s(s, 43); - in_uint32_le(s, client_info->build); - /* get keylayout */ - s->p = s->data; - in_uint8s(s, 39); - in_uint32_le(s, client_info->keylayout); - s->p = s->data; +xrdp_sec_in_mcs_data(struct xrdp_sec *self) +{ + struct stream *s = (struct stream *)NULL; + struct xrdp_client_info *client_info = (struct xrdp_client_info *)NULL; + int index = 0; + char c = 0; + + client_info = &(self->rdp_layer->client_info); + s = &(self->client_mcs_data); + /* get hostname, its unicode */ + s->p = s->data; + in_uint8s(s, 47); + g_memset(client_info->hostname, 0, 32); + c = 1; + index = 0; + + while (index < 16 && c != 0) + { + in_uint8(s, c); + in_uint8s(s, 1); + client_info->hostname[index] = c; + index++; + } + + /* get build */ + s->p = s->data; + in_uint8s(s, 43); + in_uint32_le(s, client_info->build); + /* get keylayout */ + s->p = s->data; + in_uint8s(s, 39); + in_uint32_le(s, client_info->keylayout); + s->p = s->data; } /*****************************************************************************/ int APP_CC -xrdp_sec_incoming(struct xrdp_sec* self) -{ - struct list* items = NULL; - struct list* values = NULL; - int index = 0; - char* item = NULL; - char* value = NULL; - char key_file[256]; - - g_memset(key_file,0,sizeof(char)*256); - - DEBUG((" in xrdp_sec_incoming")); - g_random(self->server_random, 32); - items = list_create(); - items->auto_free = 1; - values = list_create(); - values->auto_free = 1; - g_snprintf(key_file, 255, "%s/rsakeys.ini", XRDP_CFG_PATH); - if (file_by_name_read_section(key_file, "keys", items, values) != 0) - { - /* this is a show stopper */ - g_writeln("xrdp_sec_incoming: error reading %s file", key_file); - list_delete(items); - list_delete(values); - return 1; - } - for (index = 0; index < items->count; index++) - { - item = (char*)list_get_item(items, index); - value = (char*)list_get_item(values, index); - if (g_strcasecmp(item, "pub_exp") == 0) - { - hex_str_to_bin(value, self->pub_exp, 4); - } - else if (g_strcasecmp(item, "pub_mod") == 0) +xrdp_sec_incoming(struct xrdp_sec *self) +{ + struct list *items = NULL; + struct list *values = NULL; + int index = 0; + char *item = NULL; + char *value = NULL; + char key_file[256]; + + g_memset(key_file, 0, sizeof(char) * 256); + + DEBUG((" in xrdp_sec_incoming")); + g_random(self->server_random, 32); + items = list_create(); + items->auto_free = 1; + values = list_create(); + values->auto_free = 1; + g_snprintf(key_file, 255, "%s/rsakeys.ini", XRDP_CFG_PATH); + + if (file_by_name_read_section(key_file, "keys", items, values) != 0) { - hex_str_to_bin(value, self->pub_mod, 64); + /* this is a show stopper */ + g_writeln("xrdp_sec_incoming: error reading %s file", key_file); + list_delete(items); + list_delete(values); + return 1; } - else if (g_strcasecmp(item, "pub_sig") == 0) + + for (index = 0; index < items->count; index++) { - hex_str_to_bin(value, self->pub_sig, 64); + item = (char *)list_get_item(items, index); + value = (char *)list_get_item(values, index); + + if (g_strcasecmp(item, "pub_exp") == 0) + { + hex_str_to_bin(value, self->pub_exp, 4); + } + else if (g_strcasecmp(item, "pub_mod") == 0) + { + hex_str_to_bin(value, self->pub_mod, 64); + } + else if (g_strcasecmp(item, "pub_sig") == 0) + { + hex_str_to_bin(value, self->pub_sig, 64); + } + else if (g_strcasecmp(item, "pri_exp") == 0) + { + hex_str_to_bin(value, self->pri_exp, 64); + } } - else if (g_strcasecmp(item, "pri_exp") == 0) + + list_delete(items); + list_delete(values); + + if (xrdp_mcs_incoming(self->mcs_layer) != 0) { - hex_str_to_bin(value, self->pri_exp, 64); + return 1; } - } - list_delete(items); - list_delete(values); - if (xrdp_mcs_incoming(self->mcs_layer) != 0) - { - return 1; - } + #ifdef XRDP_DEBUG - g_writeln("client mcs data received"); - g_hexdump(self->client_mcs_data.data, - (int)(self->client_mcs_data.end - self->client_mcs_data.data)); - g_writeln("server mcs data sent"); - g_hexdump(self->server_mcs_data.data, - (int)(self->server_mcs_data.end - self->server_mcs_data.data)); + g_writeln("client mcs data received"); + g_hexdump(self->client_mcs_data.data, + (int)(self->client_mcs_data.end - self->client_mcs_data.data)); + g_writeln("server mcs data sent"); + g_hexdump(self->server_mcs_data.data, + (int)(self->server_mcs_data.end - self->server_mcs_data.data)); #endif - DEBUG((" out xrdp_sec_incoming")); - xrdp_sec_in_mcs_data(self); - return 0; + DEBUG((" out xrdp_sec_incoming")); + xrdp_sec_in_mcs_data(self); + return 0; } /*****************************************************************************/ int APP_CC -xrdp_sec_disconnect(struct xrdp_sec* self) +xrdp_sec_disconnect(struct xrdp_sec *self) { - int rv; + int rv; - DEBUG((" in xrdp_sec_disconnect")); - rv = xrdp_mcs_disconnect(self->mcs_layer); - DEBUG((" out xrdp_sec_disconnect")); - return rv; + DEBUG((" in xrdp_sec_disconnect")); + rv = xrdp_mcs_disconnect(self->mcs_layer); + DEBUG((" out xrdp_sec_disconnect")); + return rv; } diff --git a/libxrdp/xrdp_surface.c b/libxrdp/xrdp_surface.c index efc640ee..34ab9f48 100644 --- a/libxrdp/xrdp_surface.c +++ b/libxrdp/xrdp_surface.c @@ -21,141 +21,144 @@ #include "freerdp/codec/rfx.h" /*****************************************************************************/ -struct xrdp_surface* APP_CC -xrdp_surface_create(struct xrdp_session* session, struct xrdp_fastpath* fastpath) +struct xrdp_surface *APP_CC +xrdp_surface_create(struct xrdp_session *session, struct xrdp_fastpath *fastpath) { - struct xrdp_surface* self; - - self = (struct xrdp_surface*)g_malloc(sizeof(struct xrdp_surface), 1); - self->session = session; - self->fastpath = fastpath; - self->rfx_context = rfx_context_new(); - self->s = stream_new(16384); - return self; + struct xrdp_surface *self; + + self = (struct xrdp_surface *)g_malloc(sizeof(struct xrdp_surface), 1); + self->session = session; + self->fastpath = fastpath; + self->rfx_context = rfx_context_new(); + self->s = stream_new(16384); + return self; } /*****************************************************************************/ void APP_CC -xrdp_surface_delete(struct xrdp_surface* self) +xrdp_surface_delete(struct xrdp_surface *self) { - STREAM* s; - RFX_CONTEXT* rfx_context; - - if (self == 0) - { - return; - } - s = (STREAM*)(self->s); - rfx_context = (RFX_CONTEXT*)(self->rfx_context); - free_stream(self->out_s); - stream_free(s); - rfx_context_free(rfx_context); - g_free(self); + STREAM *s; + RFX_CONTEXT *rfx_context; + + if (self == 0) + { + return; + } + + s = (STREAM *)(self->s); + rfx_context = (RFX_CONTEXT *)(self->rfx_context); + free_stream(self->out_s); + stream_free(s); + rfx_context_free(rfx_context); + g_free(self); } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_surface_reset(struct xrdp_surface* self) +xrdp_surface_reset(struct xrdp_surface *self) { - return 0; + return 0; } /*****************************************************************************/ int APP_CC -xrdp_surface_init(struct xrdp_surface* self) +xrdp_surface_init(struct xrdp_surface *self) { - int width; - int height; - RFX_CONTEXT* rfx_context; + int width; + int height; + RFX_CONTEXT *rfx_context; - rfx_context = (RFX_CONTEXT*)(self->rfx_context); - width = self->session->client_info->width; - height= self->session->client_info->height; + rfx_context = (RFX_CONTEXT *)(self->rfx_context); + width = self->session->client_info->width; + height = self->session->client_info->height; - rfx_context->mode = self->session->client_info->rfx_entropy; - rfx_context->width = width; - rfx_context->height= height; + rfx_context->mode = self->session->client_info->rfx_entropy; + rfx_context->width = width; + rfx_context->height = height; - make_stream(self->out_s); - init_stream(self->out_s, 2 * 3 * width * height + 22); + make_stream(self->out_s); + init_stream(self->out_s, 2 * 3 * width * height + 22); - return 0; + return 0; } /*****************************************************************************/ int APP_CC -xrdp_surface_send_surface_bits(struct xrdp_surface* self,int bpp, char* data, +xrdp_surface_send_surface_bits(struct xrdp_surface *self, int bpp, char *data, int x, int y, int cx, int cy) { - RFX_RECT rect; - char* buf; - int Bpp; - int i; - int j; - int codecId; - uint32 bitmapDataLength; - STREAM* s; - RFX_CONTEXT* rfx_context; - - s = (STREAM*)(self->s); - rfx_context = (RFX_CONTEXT*)(self->rfx_context); - if ((bpp == 24) || (bpp == 32)) - { - } - else - { - g_writeln("bpp = %d is not supported\n", bpp); - return 1; - } - Bpp = 4; - - rect.x = 0; - rect.y = 0; - rect.width = cx; - rect.height = cy; - - init_stream(self->out_s, 0); - - stream_set_pos(s, 0); - rfx_compose_message(rfx_context, s, &rect, 1, data, cx, cy, Bpp * cx); - - codecId = self->session->client_info->rfx_codecId; - /* surface_bits_command */ - out_uint16_le(self->out_s, CMDTYPE_STREAM_SURFACE_BITS); /* cmdType */ - out_uint16_le(self->out_s, x); /* destLeft */ - out_uint16_le(self->out_s, y); /* destTop */ - out_uint16_le(self->out_s, x + cx); /* destRight */ - out_uint16_le(self->out_s, y + cy); /* destBottom */ - out_uint8(self->out_s, 32); /* bpp */ - out_uint8(self->out_s, 0); /* reserved1 */ - out_uint8(self->out_s, 0); /* reserved2 */ - out_uint8(self->out_s, codecId); /* codecId */ - out_uint16_le(self->out_s, cx); /* width */ - out_uint16_le(self->out_s, cy); /* height */ - bitmapDataLength = stream_get_length(s); - out_uint32_le(self->out_s, bitmapDataLength); /* bitmapDataLength */ - - /* rfx bit stream */ - out_uint8p(self->out_s, s->data, bitmapDataLength); - - s_mark_end(self->out_s); - return xrdp_fastpath_send_update_pdu(self->fastpath, - FASTPATH_UPDATETYPE_SURFCMDS, - self->out_s); + RFX_RECT rect; + char *buf; + int Bpp; + int i; + int j; + int codecId; + uint32 bitmapDataLength; + STREAM *s; + RFX_CONTEXT *rfx_context; + + s = (STREAM *)(self->s); + rfx_context = (RFX_CONTEXT *)(self->rfx_context); + + if ((bpp == 24) || (bpp == 32)) + { + } + else + { + g_writeln("bpp = %d is not supported\n", bpp); + return 1; + } + + Bpp = 4; + + rect.x = 0; + rect.y = 0; + rect.width = cx; + rect.height = cy; + + init_stream(self->out_s, 0); + + stream_set_pos(s, 0); + rfx_compose_message(rfx_context, s, &rect, 1, data, cx, cy, Bpp * cx); + + codecId = self->session->client_info->rfx_codecId; + /* surface_bits_command */ + out_uint16_le(self->out_s, CMDTYPE_STREAM_SURFACE_BITS); /* cmdType */ + out_uint16_le(self->out_s, x); /* destLeft */ + out_uint16_le(self->out_s, y); /* destTop */ + out_uint16_le(self->out_s, x + cx); /* destRight */ + out_uint16_le(self->out_s, y + cy); /* destBottom */ + out_uint8(self->out_s, 32); /* bpp */ + out_uint8(self->out_s, 0); /* reserved1 */ + out_uint8(self->out_s, 0); /* reserved2 */ + out_uint8(self->out_s, codecId); /* codecId */ + out_uint16_le(self->out_s, cx); /* width */ + out_uint16_le(self->out_s, cy); /* height */ + bitmapDataLength = stream_get_length(s); + out_uint32_le(self->out_s, bitmapDataLength); /* bitmapDataLength */ + + /* rfx bit stream */ + out_uint8p(self->out_s, s->data, bitmapDataLength); + + s_mark_end(self->out_s); + return xrdp_fastpath_send_update_pdu(self->fastpath, + FASTPATH_UPDATETYPE_SURFCMDS, + self->out_s); } /*****************************************************************************/ int APP_CC -xrdp_surface_send_frame_marker(struct xrdp_surface* self, +xrdp_surface_send_frame_marker(struct xrdp_surface *self, uint16 frameAction, uint32 frameId) { - init_stream(self->out_s, 0); - out_uint16_le(self->out_s, CMDTYPE_FRAME_MARKER); - out_uint16_le(self->out_s, frameAction); - out_uint32_le(self->out_s, frameId); - s_mark_end(self->out_s); - return xrdp_fastpath_send_update_pdu(self->fastpath, - FASTPATH_UPDATETYPE_SURFCMDS, - self->out_s); + init_stream(self->out_s, 0); + out_uint16_le(self->out_s, CMDTYPE_FRAME_MARKER); + out_uint16_le(self->out_s, frameAction); + out_uint32_le(self->out_s, frameId); + s_mark_end(self->out_s); + return xrdp_fastpath_send_update_pdu(self->fastpath, + FASTPATH_UPDATETYPE_SURFCMDS, + self->out_s); } diff --git a/libxrdp/xrdp_tcp.c b/libxrdp/xrdp_tcp.c index e4755ad6..807797a1 100644 --- a/libxrdp/xrdp_tcp.c +++ b/libxrdp/xrdp_tcp.c @@ -1,87 +1,89 @@ -/* - 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. - - xrdp: A Remote Desktop Protocol server. - Copyright (C) Jay Sorg 2004-2010 - - tcp layer - -*/ +/** + * xrdp: A Remote Desktop Protocol server. + * + * Copyright (C) Jay Sorg 2004 - 2012 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * tcp layer + */ #include "libxrdp.h" /*****************************************************************************/ -struct xrdp_tcp* APP_CC -xrdp_tcp_create(struct xrdp_iso* owner, struct trans* trans) +struct xrdp_tcp *APP_CC +xrdp_tcp_create(struct xrdp_iso *owner, struct trans *trans) { - struct xrdp_tcp* self; + struct xrdp_tcp *self; - DEBUG((" in xrdp_tcp_create")); - self = (struct xrdp_tcp*)g_malloc(sizeof(struct xrdp_tcp), 1); - self->iso_layer = owner; - self->trans = trans; - DEBUG((" out xrdp_tcp_create")); - return self; + DEBUG((" in xrdp_tcp_create")); + self = (struct xrdp_tcp *)g_malloc(sizeof(struct xrdp_tcp), 1); + self->iso_layer = owner; + self->trans = trans; + DEBUG((" out xrdp_tcp_create")); + return self; } /*****************************************************************************/ void APP_CC -xrdp_tcp_delete(struct xrdp_tcp* self) +xrdp_tcp_delete(struct xrdp_tcp *self) { - g_free(self); + g_free(self); } /*****************************************************************************/ /* get out stream ready for data */ /* returns error */ int APP_CC -xrdp_tcp_init(struct xrdp_tcp* self, struct stream* s) +xrdp_tcp_init(struct xrdp_tcp *self, struct stream *s) { - init_stream(s, 8192); - return 0; + init_stream(s, 8192); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_tcp_recv(struct xrdp_tcp* self, struct stream* s, int len) +xrdp_tcp_recv(struct xrdp_tcp *self, struct stream *s, int len) { - DEBUG((" in xrdp_tcp_recv, gota get %d bytes", len)); - init_stream(s, len); - if (trans_force_read_s(self->trans, s, len) != 0) - { - DEBUG((" error in trans_force_read_s")); - return 1; - } - DEBUG((" out xrdp_tcp_recv")); - return 0; + DEBUG((" in xrdp_tcp_recv, gota get %d bytes", len)); + init_stream(s, len); + + if (trans_force_read_s(self->trans, s, len) != 0) + { + DEBUG((" error in trans_force_read_s")); + return 1; + } + + DEBUG((" out xrdp_tcp_recv")); + return 0; } /*****************************************************************************/ /* returns error */ int APP_CC -xrdp_tcp_send(struct xrdp_tcp* self, struct stream* s) +xrdp_tcp_send(struct xrdp_tcp *self, struct stream *s) { - int len; - len = s->end - s->data; - DEBUG((" in xrdp_tcp_send, gota send %d bytes", len)); - if (trans_force_write_s(self->trans, s) != 0) - { - DEBUG((" error in trans_force_write_s")); - return 1; - } - DEBUG((" out xrdp_tcp_send, sent %d bytes ok", len)); - return 0; + int len; + len = s->end - s->data; + DEBUG((" in xrdp_tcp_send, gota send %d bytes", len)); + + if (trans_force_write_s(self->trans, s) != 0) + { + DEBUG((" error in trans_force_write_s")); + return 1; + } + + DEBUG((" out xrdp_tcp_send, sent %d bytes ok", len)); + return 0; } |