diff options
-rw-r--r-- | rdp/rdp.h | 5 | ||||
-rw-r--r-- | rdp/rdp_orders.c | 139 | ||||
-rw-r--r-- | rdp/rdp_rdp.c | 60 | ||||
-rw-r--r-- | rdp/rdp_sec.c | 2 |
4 files changed, 181 insertions, 25 deletions
@@ -426,6 +426,11 @@ rdp_orders_reset_state(struct rdp_orders* self); int APP_CC rdp_orders_process_orders(struct rdp_orders* self, struct stream* s, int num_orders); +char* APP_CC +rdp_orders_convert_bitmap(int in_bpp, int out_bpp, char* bmpdata, + int width, int height, int* palette); +int APP_CC +rdp_orders_convert_color(int in_bpp, int out_bpp, int in_color, int* palette); /* rdp_lic.c */ struct rdp_lic* APP_CC diff --git a/rdp/rdp_orders.c b/rdp/rdp_orders.c index a22faa27..5a68b5ef 100644 --- a/rdp/rdp_orders.c +++ b/rdp/rdp_orders.c @@ -40,10 +40,16 @@ rdp_orders_delete(struct rdp_orders* self) int i; int j; + if (self == 0) + { + return; + } + /* free the colormap cache */ for (i = 0; i < 6; i++) { g_free(self->cache_colormap[i]); } + /* free the bitmap cache */ for (i = 0; i < 3; i++) { for (j = 0; j < 600; j++) @@ -427,6 +433,9 @@ static void APP_CC rdp_orders_process_text2(struct rdp_orders* self, struct stream* s, int present, int delta) { + int fgcolor; + int bgcolor; + if (present & 0x000001) { in_uint8(s, self->state.text_font); @@ -499,10 +508,16 @@ rdp_orders_process_text2(struct rdp_orders* self, struct stream* s, } self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, self->state.text_opcode); - self->rdp_layer->mod->server_set_fgcolor(self->rdp_layer->mod, - self->state.text_fgcolor); - self->rdp_layer->mod->server_set_bgcolor(self->rdp_layer->mod, - self->state.text_bgcolor); + fgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, + self->rdp_layer->mod->xrdp_bpp, + self->state.text_fgcolor, + self->rdp_layer->colormap.colors); + self->rdp_layer->mod->server_set_fgcolor(self->rdp_layer->mod, fgcolor); + bgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, + self->rdp_layer->mod->xrdp_bpp, + self->state.text_bgcolor, + self->rdp_layer->colormap.colors); + self->rdp_layer->mod->server_set_bgcolor(self->rdp_layer->mod, bgcolor); self->rdp_layer->mod->server_draw_text(self->rdp_layer->mod, self->state.text_font, self->state.text_flags, @@ -564,6 +579,9 @@ static void APP_CC rdp_orders_process_patblt(struct rdp_orders* self, struct stream* s, int present, int delta) { + int fgcolor; + int bgcolor; + if (present & 0x0001) { rdp_orders_in_coord(s, &self->state.pat_x, delta); @@ -596,10 +614,16 @@ rdp_orders_process_patblt(struct rdp_orders* self, struct stream* s, self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, self->state.pat_opcode); self->rdp_layer->mod->server_set_mixmode(self->rdp_layer->mod, 1); - self->rdp_layer->mod->server_set_fgcolor(self->rdp_layer->mod, - self->state.pat_fgcolor); - self->rdp_layer->mod->server_set_bgcolor(self->rdp_layer->mod, - self->state.pat_bgcolor); + fgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, + self->rdp_layer->mod->xrdp_bpp, + self->state.pat_fgcolor, + self->rdp_layer->colormap.colors); + self->rdp_layer->mod->server_set_fgcolor(self->rdp_layer->mod, fgcolor); + bgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, + self->rdp_layer->mod->xrdp_bpp, + self->state.pat_bgcolor, + self->rdp_layer->colormap.colors); + self->rdp_layer->mod->server_set_bgcolor(self->rdp_layer->mod, bgcolor); self->rdp_layer->mod->server_set_brush(self->rdp_layer->mod, self->state.pat_brush.xorigin, self->state.pat_brush.yorigin, @@ -666,6 +690,8 @@ static void APP_CC rdp_orders_process_line(struct rdp_orders* self, struct stream* s, int present, int delta) { + int fgcolor; + if (present & 0x0001) { in_uint16_le(s, self->state.line_mixmode); @@ -697,8 +723,11 @@ rdp_orders_process_line(struct rdp_orders* self, struct stream* s, rdp_orders_parse_pen(s, &self->state.line_pen, present >> 7); self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, self->state.line_opcode); - self->rdp_layer->mod->server_set_fgcolor(self->rdp_layer->mod, - self->state.line_pen.color); + fgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, + self->rdp_layer->mod->xrdp_bpp, + self->state.line_pen.color, + self->rdp_layer->colormap.colors); + self->rdp_layer->mod->server_set_fgcolor(self->rdp_layer->mod, fgcolor); self->rdp_layer->mod->server_set_pen(self->rdp_layer->mod, self->state.line_pen.style, self->state.line_pen.width); @@ -717,6 +746,7 @@ rdp_orders_process_rect(struct rdp_orders* self, struct stream* s, int present, int delta) { int i; + int fgcolor; if (present & 0x01) { @@ -749,8 +779,11 @@ rdp_orders_process_rect(struct rdp_orders* self, struct stream* s, in_uint8(s, i); self->state.rect_color = (self->state.rect_color & 0xff00ffff) | (i << 16); } - self->rdp_layer->mod->server_set_fgcolor(self->rdp_layer->mod, - self->state.rect_color); + fgcolor = rdp_orders_convert_color(self->rdp_layer->mod->rdp_bpp, + self->rdp_layer->mod->xrdp_bpp, + self->state.rect_color, + self->rdp_layer->colormap.colors); + self->rdp_layer->mod->server_set_fgcolor(self->rdp_layer->mod, fgcolor); self->rdp_layer->mod->server_fill_rect(self->rdp_layer->mod, self->state.rect_x, self->state.rect_y, @@ -810,6 +843,7 @@ rdp_orders_process_memblt(struct rdp_orders* self, struct stream* s, int present, int delta) { struct rdp_bitmap* bitmap; + char* bmpdata; if (present & 0x0001) { @@ -854,17 +888,27 @@ rdp_orders_process_memblt(struct rdp_orders* self, struct stream* s, { self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, self->state.memblt_opcode); + bmpdata = rdp_orders_convert_bitmap(self->rdp_layer->mod->xrdp_bpp, + self->rdp_layer->mod->rdp_bpp, + bitmap->data, bitmap->width, + bitmap->height, + self->cache_colormap + [self->state.memblt_color_table]->colors); self->rdp_layer->mod->server_paint_rect(self->rdp_layer->mod, self->state.memblt_x, self->state.memblt_y, self->state.memblt_cx, self->state.memblt_cy, - bitmap->data, + bmpdata, bitmap->width, bitmap->height, self->state.memblt_srcx, self->state.memblt_srcy); self->rdp_layer->mod->server_set_opcode(self->rdp_layer->mod, 0xcc); + if (bmpdata != bitmap->data) + { + g_free(bmpdata); + } } } @@ -1015,3 +1059,72 @@ rdp_orders_process_orders(struct rdp_orders* self, struct stream* s, } return 0; } + +/*****************************************************************************/ +/* returns pointer, it might return bmpdata if the data dosen't need to + be converted, else it mallocs it. The calling function must free + it if needed */ +char* APP_CC +rdp_orders_convert_bitmap(int in_bpp, int out_bpp, char* bmpdata, + int width, int height, int* palette) +{ + char* out; + char* src; + char* dst; + int i; + int j; + int red; + int green; + int blue; + int pixel; + + if (in_bpp == out_bpp && in_bpp == 16) + { + return bmpdata; + } + if (in_bpp == 8 && out_bpp == 8) + { + out = g_malloc(width * height, 0); + src = bmpdata; + dst = out; + for (i = 0; i < height; i++) + { + for (j = 0; j < width; j++) + { + pixel = *((unsigned char*)src); + pixel = palette[pixel]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR8(red, green, blue); + *dst = pixel; + src++; + dst++; + } + } + return out; + } + return 0; +} + +/*****************************************************************************/ +/* returns color or 0 */ +int APP_CC +rdp_orders_convert_color(int in_bpp, int out_bpp, int in_color, int* palette) +{ + int pixel; + int red; + int green; + int blue; + + if (in_bpp == out_bpp && in_bpp == 16) + { + return in_color; + } + if (in_bpp == 8 && out_bpp == 8) + { + pixel = palette[in_color]; + SPLITCOLOR32(red, green, blue, pixel); + pixel = COLOR8(red, green, blue); + return pixel; + } + return 0; +} diff --git a/rdp/rdp_rdp.c b/rdp/rdp_rdp.c index 972db54e..a65a5467 100644 --- a/rdp/rdp_rdp.c +++ b/rdp/rdp_rdp.c @@ -153,7 +153,7 @@ rdp_rdp_out_bitmap_caps(struct rdp_rdp* self, struct stream* s) { out_uint16_le(s, RDP_CAPSET_BITMAP); out_uint16_le(s, RDP_CAPLEN_BITMAP); - out_uint16_le(s, self->mod->rdp_bpp); /* Preferred BPP */ + out_uint16_le(s, self->mod->xrdp_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 */ @@ -220,7 +220,7 @@ rdp_rdp_out_bmpcache_caps(struct rdp_rdp* self, struct stream* s) out_uint16_le(s, RDP_CAPSET_BMPCACHE); out_uint16_le(s, RDP_CAPLEN_BMPCACHE); - Bpp = (self->mod->rdp_bpp + 7) / 8; + Bpp = (self->mod->xrdp_bpp + 7) / 8; out_uint8s(s, 24); /* unused */ out_uint16_le(s, 0x258); /* entries */ out_uint16_le(s, 0x100 * Bpp); /* max cell size */ @@ -501,7 +501,8 @@ rdp_rdp_process_bitmap_updates(struct rdp_rdp* self, struct stream* s) int i; int y; char* data; - char* bmpdata; + char* bmpdata0; + char* bmpdata1; in_uint16_le(s, num_updates); for (i = 0; i < num_updates; i++) @@ -518,7 +519,7 @@ rdp_rdp_process_bitmap_updates(struct rdp_rdp* self, struct stream* s) in_uint16_le(s, bufsize); cx = (right - left) + 1; cy = (bottom - top) + 1; - bmpdata = (char*)g_malloc(width * height * Bpp, 0); + bmpdata0 = (char*)g_malloc(width * height * Bpp, 0); if (compress) { if (compress & 0x400) @@ -532,21 +533,31 @@ rdp_rdp_process_bitmap_updates(struct rdp_rdp* self, struct stream* s) in_uint8s(s, 4); /* line_size, final_size */ } in_uint8p(s, data, size); - rdp_bitmap_decompress(bmpdata, width, height, data, size, Bpp); - self->mod->server_paint_rect(self->mod, left, top, cx, cy, bmpdata, + rdp_bitmap_decompress(bmpdata0, width, height, data, size, Bpp); + bmpdata1 = rdp_orders_convert_bitmap(bpp, self->mod->rdp_bpp, + bmpdata0, width, height, + self->colormap.colors); + self->mod->server_paint_rect(self->mod, left, top, cx, cy, bmpdata1, width, height, 0, 0); } else { for (y = 0; y < height; y++) { - data = bmpdata + ((height - y) - 1) * (width * Bpp); + data = bmpdata0 + ((height - y) - 1) * (width * Bpp); in_uint8a(s, data, width * Bpp); } - self->mod->server_paint_rect(self->mod, left, top, cx, cy, bmpdata, + bmpdata1 = rdp_orders_convert_bitmap(bpp, self->mod->rdp_bpp, + bmpdata0, width, height, + self->colormap.colors); + self->mod->server_paint_rect(self->mod, left, top, cx, cy, bmpdata1, width, height, 0, 0); } - g_free(bmpdata); + if (bmpdata0 != bmpdata1) + { + g_free(bmpdata1); + } + g_free(bmpdata0); } } @@ -845,7 +856,32 @@ rdp_rdp_process_data_pdu(struct rdp_rdp* self, struct stream* s) } /******************************************************************************/ +/* Process a bitmap capability set */ +static void APP_CC +rdp_rdp_process_general_caps(struct rdp_rdp* self, struct stream* s) +{ +} + +/******************************************************************************/ +/* Process a bitmap capability set */ +static void APP_CC +rdp_rdp_process_bitmap_caps(struct rdp_rdp* self, struct stream* s) +{ + int width; + int height; + int bpp; + + in_uint16_le(s, bpp); + in_uint8s(s, 6); + in_uint16_le(s, width); + in_uint16_le(s, height); + self->mod->rdp_bpp = bpp; + /* todo, call reset if needed and use width and height */ +} + +/******************************************************************************/ /* Process server capabilities */ +/* returns error */ static int APP_CC rdp_rdp_process_server_caps(struct rdp_rdp* self, struct stream* s, int len) { @@ -871,10 +907,12 @@ rdp_rdp_process_server_caps(struct rdp_rdp* self, struct stream* s, int len) switch (capset_type) { case RDP_CAPSET_GENERAL: - //rdp_process_general_caps(s); + rdp_rdp_process_general_caps(self, s); break; case RDP_CAPSET_BITMAP: - //rdp_process_bitmap_caps(s); + rdp_rdp_process_bitmap_caps(self, s); + break; + default: break; } s->p = next; diff --git a/rdp/rdp_sec.c b/rdp/rdp_sec.c index 0bd727ee..38ee73b3 100644 --- a/rdp/rdp_sec.c +++ b/rdp/rdp_sec.c @@ -209,7 +209,7 @@ rdp_sec_out_mcs_data(struct rdp_sec* self) out_uint16_le(s, 0xca01); /* color depth? */ out_uint16_le(s, 1); out_uint32_le(s, 0); - out_uint8(s, self->rdp_layer->mod->rdp_bpp); + out_uint8(s, self->rdp_layer->mod->xrdp_bpp); out_uint16_le(s, 0x0700); out_uint8(s, 0); out_uint32_le(s, 1); |