From 520301d70aafd53287b0f4d153a2b27dc025ea76 Mon Sep 17 00:00:00 2001 From: jsorg71 Date: Fri, 14 Jan 2005 03:59:36 +0000 Subject: [PATCH] set bitmap cache and bitmap compression from the config file --- common/os_calls.c | 2 +- xrdp/xrdp.h | 3 +- xrdp/xrdp.ini | 2 + xrdp/xrdp_bitmap.c | 117 +++++++++++++++++++++++++++++++++++++------ xrdp/xrdp_cache.c | 36 +++++++++++++- xrdp/xrdp_defines.h | 2 + xrdp/xrdp_mcs.c | 42 ++++++++++++++++ xrdp/xrdp_painter.c | 46 ++++++++++++++++- xrdp/xrdp_rdp.c | 119 +++++++++++++++++++++++++++++++++++++------- xrdp/xrdp_sec.c | 32 ++++++++++-- xrdp/xrdp_types.h | 32 +++++++----- xrdp/xrdp_wm.c | 39 ++++++++------- 12 files changed, 399 insertions(+), 73 deletions(-) diff --git a/common/os_calls.c b/common/os_calls.c index 9d786f16..f13c30be 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -181,7 +181,7 @@ void g_free1(void* ptr) } /*****************************************************************************/ -void g_printf(const char* format, ...) +void g_printf(char* format, ...) { va_list ap; diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index 573c990f..3d8652a5 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -126,7 +126,8 @@ int xrdp_orders_send_font(struct xrdp_orders* self, /* xrdp_cache.c */ struct xrdp_cache* xrdp_cache_create(struct xrdp_wm* owner, - struct xrdp_orders* orders); + struct xrdp_orders* orders, + struct xrdp_client_info* client_info); void xrdp_cache_delete(struct xrdp_cache* self); int xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap); int xrdp_cache_add_palette(struct xrdp_cache* self, int* palette); diff --git a/xrdp/xrdp.ini b/xrdp/xrdp.ini index 4f0493ac..f46acb9c 100644 --- a/xrdp/xrdp.ini +++ b/xrdp/xrdp.ini @@ -1,5 +1,7 @@ [globals] +bitmap_cache=yes +bitmap_compression=yes [vnc1] name=self:2 diff --git a/xrdp/xrdp_bitmap.c b/xrdp/xrdp_bitmap.c index 2f0a5346..3b74db34 100644 --- a/xrdp/xrdp_bitmap.c +++ b/xrdp/xrdp_bitmap.c @@ -73,10 +73,10 @@ int g_crc_table[256] = 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d }; -#define CRC_START(in_crc) in_crc = g_crc_seed +#define CRC_START(in_crc) (in_crc) = g_crc_seed #define CRC_PASS(in_pixel, in_crc) \ -in_crc = g_crc_table[(in_crc ^ (in_pixel)) & 0xff] ^ (in_crc >> 8) -#define CRC_END(in_crc) in_crc = (in_crc ^ g_crc_seed) + (in_crc) = g_crc_table[((in_crc) ^ (in_pixel)) & 0xff] ^ ((in_crc) >> 8) +#define CRC_END(in_crc) (in_crc) = ((in_crc) ^ g_crc_seed) /*****************************************************************************/ struct xrdp_bitmap* xrdp_bitmap_create(int width, int height, int bpp, @@ -98,9 +98,13 @@ struct xrdp_bitmap* xrdp_bitmap_create(int width, int height, int bpp, case 16: Bpp = 2; break; } if (self->type == WND_TYPE_SCREEN || self->type == WND_TYPE_BITMAP) + { self->data = (char*)g_malloc(width * height * Bpp, 1); + } if (self->type != WND_TYPE_BITMAP) + { self->child_list = xrdp_list_create(); + } self->line_size = width * Bpp; if (self->type == WND_TYPE_COMBO) { @@ -134,41 +138,61 @@ void xrdp_bitmap_delete(struct xrdp_bitmap* self) int i; if (self == 0) + { return; + } if (self->wm != 0) { if (self->wm->focused_window != 0) { if (self->wm->focused_window->focused_control == self) + { self->wm->focused_window->focused_control = 0; + } } if (self->wm->focused_window == self) + { self->wm->focused_window = 0; + } if (self->wm->dragging_window == self) + { self->wm->dragging_window = 0; + } if (self->wm->button_down == self) + { self->wm->button_down = 0; + } if (self->wm->popup_wnd == self) + { self->wm->popup_wnd = 0; + } if (self->wm->login_window == self) + { self->wm->login_window = 0; + } } if (self->child_list != 0) { for (i = self->child_list->count - 1; i >= 0; i--) + { xrdp_bitmap_delete((struct xrdp_bitmap*)self->child_list->items[i]); + } xrdp_list_delete(self->child_list); } if (self->parent != 0) { i = xrdp_list_index_of(self->parent->child_list, (int)self); if (i >= 0) + { xrdp_list_remove_item(self->parent->child_list, i); + } } xrdp_list_delete(self->string_list); xrdp_list_delete(self->data_list); if (!self->do_not_free_data) + { g_free(self->data); + } g_free(self); } @@ -198,9 +222,13 @@ int xrdp_bitmap_set_focus(struct xrdp_bitmap* self, int focused) struct xrdp_painter* painter; if (self == 0) + { return 0; + } if (self->type != WND_TYPE_WND) /* 1 */ + { return 0; + } painter = xrdp_painter_create(self->wm); xrdp_painter_begin_update(painter); if (focused) @@ -231,7 +259,9 @@ int xrdp_bitmap_get_index(struct xrdp_bitmap* self, int* palette, int color) for (i = 0; i < 256; i++) { if (color == palette[i]) + { return i; + } } for (i = 1; i < 256; i++) { @@ -241,7 +271,7 @@ int xrdp_bitmap_get_index(struct xrdp_bitmap* self, int* palette, int color) return i; } } - g_printf("color %8.8x not found\n", color); + g_printf("color %8.8x not found\n\r", color); return 255; } @@ -320,7 +350,9 @@ int xrdp_bitmap_load(struct xrdp_bitmap* self, char* filename, int* palette) xrdp_bitmap_resize(self, header.image_width, header.image_height); data = (char*)g_malloc(header.image_width * header.image_height, 1); for (i = header.image_height - 1; i >= 0; i--) + { g_file_read(fd, data + i * header.image_width, header.image_width); + } for (i = 0; i < self->height; i++) { for (j = 0; j < self->width; j++) @@ -328,19 +360,27 @@ int xrdp_bitmap_load(struct xrdp_bitmap* self, char* filename, int* palette) k = (unsigned char)data[i * header.image_width + j]; color = palette1[k]; if (self->bpp == 8) + { color = xrdp_bitmap_get_index(self, palette, color); + } else if (self->bpp == 15) + { color = COLOR15((color & 0xff0000) >> 16, (color & 0x00ff00) >> 8, (color & 0x0000ff) >> 0); + } else if (self->bpp == 16) + { color = COLOR16((color & 0xff0000) >> 16, (color & 0x00ff00) >> 8, (color & 0x0000ff) >> 0); + } else if (self->bpp == 24) + { color = COLOR24((color & 0xff0000) >> 16, (color & 0x00ff00) >> 8, (color & 0x0000ff) >> 0); + } xrdp_bitmap_set_pixel(self, j, i, color); } } @@ -355,17 +395,27 @@ int xrdp_bitmap_load(struct xrdp_bitmap* self, char* filename, int* palette) int xrdp_bitmap_get_pixel(struct xrdp_bitmap* self, int x, int y) { if (self == 0) + { return 0; + } if (self->data == 0) + { return 0; + } if (x >= 0 && x < self->width && y >= 0 && y < self->height) { if (self->bpp == 8) + { return GETPIXEL8(self->data, x, y, self->width); + } else if (self->bpp == 15 || self->bpp == 16) + { return GETPIXEL16(self->data, x, y, self->width); + } else if (self->bpp == 24) + { return GETPIXEL32(self->data, x, y, self->width); + } } return 0; } @@ -374,17 +424,27 @@ int xrdp_bitmap_get_pixel(struct xrdp_bitmap* self, int x, int y) int xrdp_bitmap_set_pixel(struct xrdp_bitmap* self, int x, int y, int pixel) { if (self == 0) + { return 0; + } if (self->data == 0) + { return 0; + } if (x >= 0 && x < self->width && y >= 0 && y < self->height) { if (self->bpp == 8) + { SETPIXEL8(self->data, x, y, self->width, pixel); + } else if (self->bpp == 15 || self->bpp == 16) + { SETPIXEL16(self->data, x, y, self->width, pixel); + } else if (self->bpp == 24) + { SETPIXEL32(self->data, x, y, self->width, pixel); + } } return 0; } @@ -484,6 +544,13 @@ int xrdp_bitmap_copy_box_with_crc(struct xrdp_bitmap* self, int destx; int desty; int pixel; + int crc; + int incs; + int incd; + unsigned char* s8; + unsigned char* d8; + unsigned short* s16; + unsigned short* d16; if (self == 0) { @@ -515,7 +582,8 @@ int xrdp_bitmap_copy_box_with_crc(struct xrdp_bitmap* self, { return 1; } - CRC_START(dest->crc); + crc = dest->crc; + CRC_START(crc); if (self->bpp == 24) { for (i = 0; i < cy; i++) @@ -523,43 +591,60 @@ int xrdp_bitmap_copy_box_with_crc(struct xrdp_bitmap* self, for (j = 0; j < cx; j++) { pixel = GETPIXEL32(self->data, j + x, i + y, self->width); - CRC_PASS(pixel, dest->crc); - CRC_PASS(pixel >> 8, dest->crc); - CRC_PASS(pixel >> 16, dest->crc); + CRC_PASS(pixel, crc); + CRC_PASS(pixel >> 8, crc); + CRC_PASS(pixel >> 16, crc); SETPIXEL32(dest->data, j + destx, i + desty, dest->width, pixel); } } } else if (self->bpp == 15 || self->bpp == 16) { + s16 = ((unsigned short*)(self->data)) + (self->width * y + x); + d16 = ((unsigned short*)(dest->data)) + (dest->width * desty + destx); + incs = self->width - cx; + incd = dest->width - cx; for (i = 0; i < cy; i++) { for (j = 0; j < cx; j++) { - pixel = GETPIXEL16(self->data, j + x, i + y, self->width); - CRC_PASS(pixel, dest->crc); - CRC_PASS(pixel >> 8, dest->crc); - SETPIXEL16(dest->data, j + destx, i + desty, dest->width, pixel); + pixel = *s16; + CRC_PASS(pixel, crc); + CRC_PASS(pixel >> 8, crc); + *d16 = pixel; + s16++; + d16++; } + s16 += incs; + d16 += incd; } } else if (self->bpp == 8) { + s8 = ((unsigned char*)(self->data)) + (self->width * y + x); + d8 = ((unsigned char*)(dest->data)) + (dest->width * desty + destx); + incs = self->width - cx; + incd = dest->width - cx; for (i = 0; i < cy; i++) { for (j = 0; j < cx; j++) { - pixel = GETPIXEL8(self->data, j + x, i + y, self->width); - CRC_PASS(pixel, dest->crc); - SETPIXEL8(dest->data, j + destx, i + desty, dest->width, pixel); + pixel = *s8; + CRC_PASS(pixel, crc); + *d8 = pixel; + s8++; + d8++; } + s8 += incs; + d8 += incd; } } else { return 1; } - CRC_END(dest->crc); + CRC_END(crc); + dest->crc = crc; return 0; } diff --git a/xrdp/xrdp_cache.c b/xrdp/xrdp_cache.c index 55ffaf42..644b98c2 100644 --- a/xrdp/xrdp_cache.c +++ b/xrdp/xrdp_cache.c @@ -24,13 +24,21 @@ /*****************************************************************************/ struct xrdp_cache* xrdp_cache_create(struct xrdp_wm* owner, - struct xrdp_orders* orders) + struct xrdp_orders* orders, + struct xrdp_client_info* client_info) { struct xrdp_cache* self; self = (struct xrdp_cache*)g_malloc(sizeof(struct xrdp_cache), 1); self->wm = owner; self->orders = orders; + self->use_bitmap_comp = client_info->use_bitmap_comp; + self->cache1_entries = client_info->cache1_entries; + self->cache1_size = client_info->cache1_size; + self->cache2_entries = client_info->cache2_entries; + self->cache2_size = client_info->cache2_size; + self->cache3_entries = client_info->cache3_entries; + self->cache3_size = client_info->cache3_size; return self; } @@ -41,15 +49,25 @@ void xrdp_cache_delete(struct xrdp_cache* self) int j; if (self == 0) + { return; + } /* free all the cached bitmaps */ for (i = 0; i < 3; i++) + { for (j = 0; j < 600; j++) + { xrdp_bitmap_delete(self->bitmap_items[i][j].bitmap); + } + } /* free all the cached font items */ for (i = 0; i < 12; i++) + { for (j = 0; j < 256; j++) + { g_free(self->char_items[i][j].font_item.data); + } + } g_free(self); } @@ -80,7 +98,11 @@ int xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap) i = 0; for (j = 0; j < self->cache1_entries; j++) { +#ifdef USE_CRC if (xrdp_bitmap_compare_with_crc(self->bitmap_items[i][j].bitmap, bitmap)) +#else + if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap)) +#endif { self->bitmap_items[i][j].stamp = self->bitmap_stamp; DEBUG(("found bitmap at %d %d\n\r", i, j)); @@ -95,7 +117,11 @@ int xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap) i = 1; for (j = 0; j < self->cache2_entries; j++) { +#ifdef USE_CRC if (xrdp_bitmap_compare_with_crc(self->bitmap_items[i][j].bitmap, bitmap)) +#else + if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap)) +#endif { self->bitmap_items[i][j].stamp = self->bitmap_stamp; DEBUG(("found bitmap at %d %d\n\r", i, j)); @@ -110,7 +136,11 @@ int xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap) i = 2; for (j = 0; j < self->cache3_entries; j++) { +#ifdef USE_CRC if (xrdp_bitmap_compare_with_crc(self->bitmap_items[i][j].bitmap, bitmap)) +#else + if (xrdp_bitmap_compare(self->bitmap_items[i][j].bitmap, bitmap)) +#endif { self->bitmap_items[i][j].stamp = self->bitmap_stamp; DEBUG(("found bitmap at %d %d\n\r", i, j)); @@ -120,6 +150,10 @@ int xrdp_cache_add_bitmap(struct xrdp_cache* self, struct xrdp_bitmap* bitmap) } } } + else + { + g_printf("error in xrdp_cache_add_bitmap, too big\n\r"); + } /* look for oldest */ cache_id = 0; cache_idx = 0; diff --git a/xrdp/xrdp_defines.h b/xrdp/xrdp_defines.h index 9fe6d56e..dfc98919 100644 --- a/xrdp/xrdp_defines.h +++ b/xrdp/xrdp_defines.h @@ -51,3 +51,5 @@ #define COLOR24(r, g, b) ((r) | ((g) << 8) | ((b) << 16)) /* font macros */ #define FONT_DATASIZE(f) ((((f)->height * (((f)->width + 7) / 8)) + 3) & ~3); +/* use crc for bitmap cache lookups */ +#define USE_CRC diff --git a/xrdp/xrdp_mcs.c b/xrdp/xrdp_mcs.c index cbe5d6e1..035e5497 100644 --- a/xrdp/xrdp_mcs.c +++ b/xrdp/xrdp_mcs.c @@ -41,7 +41,9 @@ struct xrdp_mcs* xrdp_mcs_create(struct xrdp_sec* owner) void xrdp_mcs_delete(struct xrdp_mcs* self) { if (self == 0) + { return; + } xrdp_iso_delete(self->iso_layer); g_free(self); } @@ -86,11 +88,15 @@ int xrdp_mcs_recv(struct xrdp_mcs* self, struct stream* s, int* chan) while (1) { if (xrdp_iso_recv(self->iso_layer, s) != 0) + { return 1; + } in_uint8(s, opcode); appid = opcode >> 2; if (appid == MCS_DPUM) + { return 1; + } if (appid == MCS_CJRQ) { xrdp_mcs_send_cjcf(self, self->userid + MCS_USERCHANNEL_BASE); @@ -108,7 +114,9 @@ int xrdp_mcs_recv(struct xrdp_mcs* self, struct stream* s, int* chan) in_uint8s(s, 1); in_uint8(s, len); if (len & 0x80) + { in_uint8s(s, 1); + } DEBUG((" out xrdp_mcs_recv\n\r")); return 0; } @@ -145,11 +153,17 @@ int xrdp_mcs_ber_parse_header(struct xrdp_mcs* self, struct stream* s, } } else + { *len = l; + } if (s_check(s)) + { return 0; + } else + { return 1; + } } /*****************************************************************************/ @@ -159,12 +173,18 @@ int 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; + } } /*****************************************************************************/ @@ -479,25 +499,45 @@ int xrdp_mcs_incoming(struct xrdp_mcs* self) { DEBUG((" in xrdp_mcs_incoming\n\r")); if (xrdp_iso_incoming(self->iso_layer) != 0) + { return 1; + } if (xrdp_mcs_recv_connect_initial(self) != 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 + MCS_USERCHANNEL_BASE) != 0) + { return 1; + } if (xrdp_mcs_recv_cjrq(self) != 0) + { return 1; + } if (xrdp_mcs_send_cjcf(self, MCS_GLOBAL_CHANNEL) != 0) + { return 1; + } DEBUG((" out xrdp_mcs_incoming\n\r")); return 0; } @@ -527,7 +567,9 @@ int xrdp_mcs_send(struct xrdp_mcs* self, struct stream* s) out_uint8(s, 0x70); out_uint16_be(s, len); if (xrdp_iso_send(self->iso_layer, s) != 0) + { return 1; + } DEBUG((" out xrdp_mcs_send\n\r")); return 0; } diff --git a/xrdp/xrdp_painter.c b/xrdp/xrdp_painter.c index dff1cab5..08be1aca 100644 --- a/xrdp/xrdp_painter.c +++ b/xrdp/xrdp_painter.c @@ -40,7 +40,9 @@ struct xrdp_painter* xrdp_painter_create(struct xrdp_wm* wm) void xrdp_painter_delete(struct xrdp_painter* self) { if (self == 0) + { return; + } xrdp_font_delete(self->font); g_free(self); } @@ -68,25 +70,43 @@ int xrdp_painter_clip_adj(struct xrdp_painter* self, int* x, int* y, int dy; if (!self->use_clip) + { return 1; + } if (self->clip.left > *x) + { dx = self->clip.left - *x; + } else + { dx = 0; + } if (self->clip.top > *y) + { dy = self->clip.top - *y; + } else + { dy = 0; + } if (*x + *cx > self->clip.right) + { *cx = *cx - ((*x + *cx) - self->clip.right); + } if (*y + *cy > self->clip.bottom) + { *cy = *cy - ((*y + *cy) - self->clip.bottom); + } *cx = *cx - dx; *cy = *cy - dy; if (*cx <= 0) + { return 0; + } if (*cy <= 0) + { return 0; + } *x = *x + dx; *y = *y + dy; return 1; @@ -147,14 +167,20 @@ int xrdp_painter_fill_rect(struct xrdp_painter* self, struct xrdp_rect rect; if (!check_bounds(bitmap, &x, &y, &cx, &cy)) + { return 0; + } if (!xrdp_painter_clip_adj(self, &x, &y, &cx, &cy)) + { return 0; + } /* todo data */ if (bitmap->type == WND_TYPE_BITMAP) /* 0 */ + { return 0; + } region = xrdp_region_create(self->wm); xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region, self->clip_children); @@ -189,14 +215,20 @@ int xrdp_painter_fill_rect2(struct xrdp_painter* self, struct xrdp_rect rect; if (!check_bounds(bitmap, &x, &y, &cx, &cy)) + { return 0; + } if (!xrdp_painter_clip_adj(self, &x, &y, &cx, &cy)) + { return 0; + } /* todo data */ if (bitmap->type == WND_TYPE_BITMAP) /* 0 */ + { return 0; + } region = xrdp_region_create(self->wm); xrdp_wm_get_vis_region(self->wm, bitmap, x, y, cx, cy, region, self->clip_children); @@ -265,7 +297,7 @@ int xrdp_painter_draw_bitmap(struct xrdp_painter* self, y = y + b->top; b = b->parent; } - if (self->wm->use_bitmap_cache) + if (self->wm->client_info->use_bitmap_cache) { palette_id = xrdp_cache_add_palette(self->wm->cache, self->wm->palette); j = 0; @@ -279,7 +311,11 @@ int xrdp_painter_draw_bitmap(struct xrdp_painter* self, w = MIN(SSW, to_draw->width - i); h = MIN(SSH, to_draw->height - j); b = xrdp_bitmap_create(w, h, self->wm->screen->bpp, 0); +#ifdef USE_CRC xrdp_bitmap_copy_box_with_crc(to_draw, b, i, j, w, h); +#else + xrdp_bitmap_copy_box(to_draw, b, i, j, w, h); +#endif bitmap_id = xrdp_cache_add_bitmap(self->wm->cache, b); cache_id = HIWORD(bitmap_id); cache_idx = LOWORD(bitmap_id); @@ -297,7 +333,9 @@ int xrdp_painter_draw_bitmap(struct xrdp_painter* self, rect = self->clip; RECTOFFSET(rect, x, y); if (!rect_intersect(&rect2, &rect, &rect1)) + { ok = 0; + } } else { @@ -430,12 +468,16 @@ int xrdp_painter_draw_text(struct xrdp_painter* self, len = g_strlen(text); if (len < 1) + { return 0; + } /* todo data */ if (bitmap->type == 0) + { return 0; + } font = self->font; f = 0; k = 0; @@ -465,7 +507,9 @@ int xrdp_painter_draw_text(struct xrdp_painter* self, b = b->parent; } if (self->use_clip) + { clip_rect = self->clip; + } else { MAKERECT(clip_rect, 0, 0, bitmap->width, bitmap->height); diff --git a/xrdp/xrdp_rdp.c b/xrdp/xrdp_rdp.c index a6592a56..a9e1f7f1 100644 --- a/xrdp/xrdp_rdp.c +++ b/xrdp/xrdp_rdp.c @@ -46,6 +46,49 @@ char unknown1[172] = 0x29, 0x00, 0x01, 0x00, 0x2a, 0x00, 0x05, 0x00, 0x2b, 0x00, 0x2a, 0x00 }; +/*****************************************************************************/ +int xrdp_rdp_read_config(struct xrdp_client_info* client_info) +{ + int fd; + int index; + struct xrdp_list* items; + struct xrdp_list* values; + char* item; + char* value; + + fd = g_file_open("xrdp.ini"); + if (fd > 0) + { + items = xrdp_list_create(); + items->auto_free = 1; + values = xrdp_list_create(); + values->auto_free = 1; + xrdp_file_read_section(fd, "globals", items, values); + for (index = 0; index < items->count; index++) + { + item = (char*)xrdp_list_get_item(items, index); + value = (char*)xrdp_list_get_item(values, index); + if (g_strcmp(item, "bitmap_cache") == 0) + { + if (g_strcmp(value, "yes") == 0) + { + client_info->use_bitmap_cache = 1; + } + } + else if (g_strcmp(item, "bitmap_compression") == 0) + { + if (g_strcmp(value, "yes") == 0) + { + client_info->use_bitmap_comp = 1; + } + } + } + xrdp_list_delete(items); + xrdp_list_delete(values); + g_file_close(fd); + } + return 0; +} /*****************************************************************************/ struct xrdp_rdp* xrdp_rdp_create(struct xrdp_process* owner) @@ -56,6 +99,8 @@ struct xrdp_rdp* xrdp_rdp_create(struct xrdp_process* owner) self->pro_layer = owner; self->share_id = 66538; self->sec_layer = xrdp_sec_create(self); + /* read ini settings */ + xrdp_rdp_read_config(&self->client_info); return self; } @@ -63,7 +108,9 @@ struct xrdp_rdp* xrdp_rdp_create(struct xrdp_process* owner) void xrdp_rdp_delete(struct xrdp_rdp* self) { if (self == 0) + { return; + } xrdp_sec_delete(self->sec_layer); g_free(self); } @@ -72,7 +119,9 @@ void xrdp_rdp_delete(struct xrdp_rdp* self) int 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; } @@ -81,7 +130,9 @@ int xrdp_rdp_init(struct xrdp_rdp* self, struct stream* s) int 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; } @@ -111,11 +162,15 @@ int xrdp_rdp_recv(struct xrdp_rdp* self, struct stream* s, int* code) return 0; } if (error != 0) + { return 1; + } s->next_packet = s->p; } else + { s->p = s->next_packet; + } in_uint16_le(s, len); if (len == 0x8000) { @@ -142,7 +197,9 @@ int xrdp_rdp_send(struct xrdp_rdp* self, struct stream* s, int pdu_type) out_uint16_le(s, 0x10 | pdu_type); out_uint16_le(s, self->mcs_channel); if (xrdp_sec_send(self->sec_layer, s, 0) != 0) + { return 1; + } DEBUG(("out xrdp_rdp_send\n\r")); return 0; } @@ -167,7 +224,9 @@ int xrdp_rdp_send_data(struct xrdp_rdp* self, struct stream* s, out_uint8(s, 0); out_uint16_le(s, 0); if (xrdp_sec_send(self->sec_layer, s, 0) != 0) + { return 1; + } DEBUG(("out xrdp_rdp_send_data\n\r")); return 0; } @@ -181,10 +240,10 @@ int xrdp_rdp_parse_client_mcs_data(struct xrdp_rdp* self) p = &self->sec_layer->client_mcs_data; p->p = p->data; in_uint8s(p, 31); - in_uint16_le(p, self->width); - in_uint16_le(p, self->height); + in_uint16_le(p, self->client_info.width); + in_uint16_le(p, self->client_info.height); in_uint8s(p, 120); - self->bpp = 8; + self->client_info.bpp = 8; in_uint16_le(p, i); switch (i) { @@ -192,16 +251,18 @@ int xrdp_rdp_parse_client_mcs_data(struct xrdp_rdp* self) in_uint8s(p, 6); in_uint8(p, i); if (i > 8) - self->bpp = i; + { + self->client_info.bpp = i; + } break; case 0xca02: - self->bpp = 15; + self->client_info.bpp = 15; break; case 0xca03: - self->bpp = 16; + self->client_info.bpp = 16; break; case 0xca04: - self->bpp = 24; + self->client_info.bpp = 24; break; } p->p = p->data; @@ -215,7 +276,9 @@ int xrdp_rdp_incoming(struct xrdp_rdp* self) { DEBUG(("in xrdp_rdp_incoming\n\r")); 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); @@ -261,12 +324,12 @@ int xrdp_rdp_send_demand_active(struct xrdp_rdp* self) /* Output bitmap capability set */ out_uint16_le(s, RDP_CAPSET_BITMAP); /* 2 */ out_uint16_le(s, RDP_CAPLEN_BITMAP); /* 28(0x1c) */ - out_uint16_le(s, self->bpp); /* Preferred BPP */ + 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->width); /* width */ - out_uint16_le(s, self->height); /* height */ + 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 */ @@ -364,12 +427,12 @@ int xrdp_process_capset_bmpcache(struct xrdp_rdp* self, struct stream* s, { //g_hexdump(s->p, len); in_uint8s(s, 24); - in_uint16_le(s, self->cache1_entries); - in_uint16_le(s, self->cache1_size); - in_uint16_le(s, self->cache2_entries); - in_uint16_le(s, self->cache2_size); - in_uint16_le(s, self->cache3_entries); - in_uint16_le(s, self->cache3_size); + 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); //g_printf("%d %d %d %d %d %d\n", self->cache1_entries, self->cache1_size, // self->cache2_entries, self->cache2_size, // self->cache3_entries, self->cache3_size); @@ -425,7 +488,9 @@ int xrdp_rdp_process_input_sync(struct xrdp_rdp* self, int device_flags, { DEBUG(("sync event flags %d key %d\n\r", device_flags, key_flags)); if (!self->up_and_running) + { return 0; + } xrdp_wm_key_sync(self->pro_layer->wm, device_flags, key_flags); return 0; } @@ -437,7 +502,9 @@ int xrdp_rdp_process_input_scancode(struct xrdp_rdp* self, int device_flags, { DEBUG(("key event flags %4.4x scan_code %d\n\r", device_flags, scan_code)); if (!self->up_and_running) + { return 0; + } xrdp_wm_key(self->pro_layer->wm, device_flags, scan_code); return 0; } @@ -449,7 +516,9 @@ int xrdp_rdp_process_input_mouse(struct xrdp_rdp* self, int device_flags, { DEBUG(("mouse event flags %4.4x x %d y %d\n\r", device_flags, x, y)); if (!self->up_and_running) + { return 0; + } if (device_flags & MOUSE_FLAG_MOVE) /* 0x0800 */ { xrdp_wm_mouse_move(self->pro_layer->wm, x, y); @@ -457,23 +526,35 @@ int xrdp_rdp_process_input_mouse(struct xrdp_rdp* self, int device_flags, if (device_flags & MOUSE_FLAG_BUTTON1) /* 0x1000 */ { if (device_flags & MOUSE_FLAG_DOWN) /* 0x8000 */ + { xrdp_wm_mouse_click(self->pro_layer->wm, x, y, 1, 1); + } else + { xrdp_wm_mouse_click(self->pro_layer->wm, x, y, 1, 0); + } } if (device_flags & MOUSE_FLAG_BUTTON2) /* 0x2000 */ { if (device_flags & MOUSE_FLAG_DOWN) /* 0x8000 */ + { xrdp_wm_mouse_click(self->pro_layer->wm, x, y, 2, 1); + } else + { xrdp_wm_mouse_click(self->pro_layer->wm, x, y, 2, 0); + } } if (device_flags & MOUSE_FLAG_BUTTON3) /* 0x4000 */ { if (device_flags & MOUSE_FLAG_DOWN) /* 0x8000 */ + { xrdp_wm_mouse_click(self->pro_layer->wm, x, y, 3, 1); + } else + { xrdp_wm_mouse_click(self->pro_layer->wm, x, y, 3, 0); + } } if (device_flags == MOUSE_FLAG_BUTTON4 || /* 0x0280 */ device_flags == 0x0278) @@ -701,7 +782,11 @@ int xrdp_rdp_process_data(struct xrdp_rdp* self, struct stream* s) xrdp_rdp_process_screen_update(self, s); break; - //case 35: /* 35 ?? this comes when minimuzing a full screen mstsc.exe 2600 */ + /*case 35:*/ + /* 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 minumized apps don't take bandwidth */ case 36: /* 36 ?? disconnect? */ return 1; diff --git a/xrdp/xrdp_sec.c b/xrdp/xrdp_sec.c index 3ec40f9b..15766449 100644 --- a/xrdp/xrdp_sec.c +++ b/xrdp/xrdp_sec.c @@ -131,7 +131,9 @@ struct xrdp_sec* xrdp_sec_create(struct xrdp_rdp* owner) void xrdp_sec_delete(struct xrdp_sec* self) { if (self == 0) + { return; + } xrdp_mcs_delete(self->mcs_layer); g_rc4_info_delete(self->decrypt_rc4_info); g_rc4_info_delete(self->encrypt_rc4_info); @@ -145,7 +147,9 @@ void xrdp_sec_delete(struct xrdp_sec* self) int xrdp_sec_init(struct xrdp_sec* self, struct stream* s) { if (xrdp_mcs_init(self->mcs_layer, s) != 0) + { return 1; + } s_push_layer(s, sec_hdr, 4); return 0; } @@ -185,7 +189,9 @@ int xrdp_sec_update(char* key, char* update_key, int key_len) g_rc4_set_key(rc4_info, key, key_len); g_rc4_crypt(rc4_info, key, key_len); if (key_len == 8) + { xrdp_sec_make_40bit(key); + } g_sha1_info_delete(sha1_info); g_md5_info_delete(md5_info); g_rc4_info_delete(rc4_info); @@ -220,14 +226,18 @@ int xrdp_sec_process_logon_info(struct xrdp_sec* self, struct stream* s) in_uint8s(s, 4); in_uint32_le(s, flags); - DEBUG(("in xrdp_sec_process_logon_info flags $%x\n", flags)); + DEBUG(("in xrdp_sec_process_logon_info flags $%x\n\r", flags)); /* this is the first test that the decrypt is working */ if ((flags & RDP_LOGON_NORMAL) != RDP_LOGON_NORMAL) /* 0x33 */ - return 1; /* must be or error */ + { /* must be or error */ + return 1; + } if (flags & RDP_LOGON_AUTO) - ; + { + } if (flags & RDP_COMPRESSION) - ; + { + } in_uint16_le(s, len_domain); in_uint16_le(s, len_user); in_uint16_le(s, len_password); @@ -400,7 +410,9 @@ void xrdp_sec_establish_keys(struct xrdp_sec* self) 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); g_rc4_set_key(self->decrypt_rc4_info, self->decrypt_key, self->rc4_key_len); @@ -416,7 +428,9 @@ int xrdp_sec_recv(struct xrdp_sec* self, struct stream* s, int* chan) DEBUG((" in xrdp_sec_recv\n\r")); if (xrdp_mcs_recv(self->mcs_layer, s, chan) != 0) + { return 1; + } in_uint32_le(s, flags); DEBUG((" in xrdp_sec_recv flags $%x\n\r", flags)); if (flags & SEC_ENCRYPT) /* 0x08 */ @@ -437,16 +451,22 @@ int xrdp_sec_recv(struct xrdp_sec* self, struct stream* s, int* chan) if (flags & SEC_LOGON_INFO) /* 0x40 */ { if (xrdp_sec_process_logon_info(self, s) != 0) + { return 1; + } if (xrdp_sec_send_lic_initial(self) != 0) + { return 1; + } *chan = 1; /* just set a non existing channel and exit */ return 0; } if (flags & SEC_LICENCE_NEG) /* 0x80 */ { if (xrdp_sec_send_lic_response(self) != 0) + { return 1; + } return -1; /* special error that means send demand active */ } DEBUG((" out xrdp_sec_recv error\n\r")); @@ -462,7 +482,9 @@ int xrdp_sec_send(struct xrdp_sec* self, struct stream* s, int flags) s_pop_layer(s, sec_hdr); out_uint32_le(s, flags); if (xrdp_mcs_send(self->mcs_layer, s) != 0) + { return 1; + } DEBUG((" out xrdp_sec_send\n\r")); return 0; } @@ -541,7 +563,9 @@ int xrdp_sec_incoming(struct xrdp_sec* self) DEBUG(("in xrdp_sec_incoming\n\r")); xrdp_sec_out_mcs_data(self); if (xrdp_mcs_incoming(self->mcs_layer) != 0) + { return 1; + } #ifdef XRDP_DEBUG g_printf("client mcs data received\n\r"); g_hexdump(self->client_mcs_data.data, diff --git a/xrdp/xrdp_types.h b/xrdp/xrdp_types.h index fedbbbd6..16c0f248 100644 --- a/xrdp/xrdp_types.h +++ b/xrdp/xrdp_types.h @@ -169,23 +169,32 @@ struct xrdp_sec void* encrypt_rc4_info; }; -/* rdp */ -struct xrdp_rdp +/* client info */ +struct xrdp_client_info { - struct xrdp_process* pro_layer; /* owner */ - struct xrdp_sec* sec_layer; - int share_id; - int mcs_channel; int bpp; int width; int height; - int up_and_running; int cache1_entries; int cache1_size; int cache2_entries; int cache2_size; int cache3_entries; int cache3_size; + int use_bitmap_comp; + int use_bitmap_cache; + int op1; /* use smaller bitmap header, todo */ +}; + +/* rdp */ +struct xrdp_rdp +{ + struct xrdp_process* pro_layer; /* owner */ + struct xrdp_sec* sec_layer; + int share_id; + int mcs_channel; + int up_and_running; + struct xrdp_client_info client_info; }; /* orders */ @@ -376,11 +385,8 @@ struct xrdp_wm int (*mod_init)(); int (*mod_exit)(int); struct xrdp_mod* mod; - /* */ - int use_bitmap_comp; - int use_bitmap_cache; - /* */ - int op1; /* use smaller bitmap header, todo */ + /* client info */ + struct xrdp_client_info* client_info; }; /* rdp process */ @@ -490,7 +496,7 @@ struct xrdp_font int style; }; -/* modual */ +/* module */ struct xrdp_mod_data { char name[256]; diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index ff3b9ac3..004631f6 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -28,25 +28,17 @@ struct xrdp_wm* xrdp_wm_create(struct xrdp_process* owner) struct xrdp_wm* self; self = (struct xrdp_wm*)g_malloc(sizeof(struct xrdp_wm), 1); - self->screen = xrdp_bitmap_create(owner->rdp_layer->width, - owner->rdp_layer->height, - owner->rdp_layer->bpp, WND_TYPE_SCREEN); + self->client_info = &owner->rdp_layer->client_info; + self->screen = xrdp_bitmap_create(self->client_info->width, + self->client_info->height, + self->client_info->bpp, + WND_TYPE_SCREEN); self->screen->wm = self; self->pro_layer = owner; self->orders = owner->orders; self->painter = xrdp_painter_create(self); - self->use_bitmap_comp = 1; - self->use_bitmap_cache = 1; - self->op1 = 0; self->rdp_layer = owner->rdp_layer; - self->cache = xrdp_cache_create(self, self->orders); - self->cache->use_bitmap_comp = self->use_bitmap_comp; - self->cache->cache1_entries = owner->rdp_layer->cache1_entries; - self->cache->cache1_size = owner->rdp_layer->cache1_size; - self->cache->cache2_entries = owner->rdp_layer->cache2_entries; - self->cache->cache2_size = owner->rdp_layer->cache2_size; - self->cache->cache3_entries = owner->rdp_layer->cache3_entries; - self->cache->cache3_size = owner->rdp_layer->cache3_size; + self->cache = xrdp_cache_create(self, self->orders, self->client_info); return self; } @@ -127,11 +119,13 @@ int xrdp_wm_send_bitmap(struct xrdp_wm* self, struct xrdp_bitmap* bitmap, Bpp = (bitmap->bpp + 7) / 8; e = bitmap->width % 4; if (e != 0) + { e = 4 - e; + } line_size = bitmap->width * Bpp; make_stream(s); init_stream(s, 8192); - if (self->use_bitmap_comp) + if (self->client_info->use_bitmap_comp) { make_stream(temp_s); init_stream(temp_s, 65536); @@ -148,7 +142,7 @@ int xrdp_wm_send_bitmap(struct xrdp_wm* self, struct xrdp_bitmap* bitmap, out_uint8s(s, 2); /* num_updates set later */ do { - if (self->op1) + if (self->client_info->op1) { s_push_layer(s, channel_hdr, 18); } @@ -163,7 +157,9 @@ int xrdp_wm_send_bitmap(struct xrdp_wm* self, struct xrdp_bitmap* bitmap, 4096 - total_bufsize, i - 1, temp_s, e); if (lines_sending == 0) + { break; + } num_updates++; bufsize = s->p - p; total_bufsize += bufsize; @@ -177,7 +173,7 @@ int xrdp_wm_send_bitmap(struct xrdp_wm* self, struct xrdp_bitmap* bitmap, out_uint16_le(s, bitmap->width + e); /* width */ out_uint16_le(s, lines_sending); /* height */ out_uint16_le(s, bitmap->bpp); /* bpp */ - if (self->op1) + if (self->client_info->op1) { out_uint16_le(s, 0x401); /* compress */ out_uint16_le(s, bufsize); /* compressed size */ @@ -187,8 +183,7 @@ int xrdp_wm_send_bitmap(struct xrdp_wm* self, struct xrdp_bitmap* bitmap, else { out_uint16_le(s, 0x1); /* compress */ - j = bufsize + 8; - out_uint16_le(s, j); + out_uint16_le(s, bufsize + 8); out_uint8s(s, 2); /* pad */ out_uint16_le(s, bufsize); /* compressed size */ j = (bitmap->width + e) * Bpp; @@ -197,17 +192,23 @@ int xrdp_wm_send_bitmap(struct xrdp_wm* self, struct xrdp_bitmap* bitmap, out_uint16_le(s, j); /* final size */ } if (j > 32768) + { g_printf("error, decompressed size too big, its %d\n\r", j); + } if (bufsize > 8192) + { g_printf("error, compressed size too big, its %d\n\r", 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(self->rdp_layer, s, RDP_DATA_PDU_UPDATE); if (total_bufsize > 8192) + { g_printf("error, total compressed size too big, its %d\n\r", total_bufsize); + } } free_stream(temp_s); }