/*****************************************************************************/ /* check if the current order will fit in packet size of 16384, if not */ /* send what we got and init a new one */ /* returns error */ int
xrdp_orders_check(struct xrdp_orders *self, int max_size)
{ int size; int max_order_size; struct xrdp_client_info *ci;
ci = &(self->rdp_layer->client_info);
max_order_size = MAX_ORDERS_SIZE(ci);
if (self->order_level < 1)
{ if (max_size > max_order_size)
{
LOG(LOG_LEVEL_ERROR, "Requested orders max_size (%d) " "is greater than the client connection max_size (%d)",
max_size, max_order_size); return1;
} else
{
xrdp_orders_init(self); return0;
}
}
size = (int)(self->out_s->p - self->order_count_ptr); if (size < 0)
{
LOG(LOG_LEVEL_ERROR, "Bug: order data length cannot be negative. " "Found length %d bytes", size); return1;
} if (size > max_order_size)
{ /* this suggests someone calls this function without passing the correctmax_sizesoweendupputtingmoreintothebuffer
than we indicate we can */
LOG(LOG_LEVEL_WARNING, "Ignoring Bug: order data length " "is larger than maximum length. Expected %d, actual %d",
max_order_size, size); /* We where getting called with size already greater than max_order_size WhichIsuspectwasbecausethesendingoftextdidnotinclude thetextlentocheckthebuffersize.Soattempttosendthedata anyway.
Lets write the data anyway, somewhere else may barf. */ /* return 1; */
}
/*****************************************************************************/ /* check if rect is the same as the last one sent */ /* returns boolean */ staticint
xrdp_orders_last_bounds(struct xrdp_orders *self, struct xrdp_rect *rect)
{ if (rect == 0)
{ return0;
}
/*****************************************************************************/ /* check if all coords are within 256 bytes */ /* returns boolean */ staticint
xrdp_orders_send_delta(struct xrdp_orders *self, int *vals, int count)
{ int i;
for (i = 0; i < count; i += 2)
{ if (g_abs(vals[i] - vals[i + 1]) >= 128)
{ return0;
}
}
/*****************************************************************************/ /* returns error */ staticint
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 shiftingit6willmakeitRDP_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; return0;
}
/*****************************************************************************/ /* returns error */ /* send a solid rect to client */ /* max size 23 */ int
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;
if (self->orders_state.last_order != RDP_ORDER_RECT)
{
order_flags |= TS_TYPE_CHANGE;
}
self->orders_state.last_order = RDP_ORDER_RECT;
if (rect != 0)
{ /* if clip is present, still check if it's needed */ if (x < rect->left || y < rect->top ||
x + cx > rect->right || y + cy > rect->bottom)
{
order_flags |= TS_BOUNDS;
if (xrdp_orders_last_bounds(self, rect))
{
order_flags |= TS_ZERO_BOUNDS_DELTAS;
}
}
}
/*****************************************************************************/ /* returns error */ /* send a screen blt order */ /* max size 25 */ int
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 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;
if (rect != 0)
{ /* if clip is present, still check if it's needed */ if (x < rect->left || y < rect->top ||
x + cx > rect->right || y + cy > rect->bottom)
{
order_flags |= TS_BOUNDS;
if (xrdp_orders_last_bounds(self, rect))
{
order_flags |= TS_ZERO_BOUNDS_DELTAS;
}
}
}
/*****************************************************************************/ /* returns error */ /* send a pat blt order */ /* max size 39 */ int
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 order_flags; int present; int vals[8]; char *present_ptr; char *order_flags_ptr; struct xrdp_brush blank_brush;
if (self->orders_state.last_order != RDP_ORDER_PATBLT)
{
order_flags |= TS_TYPE_CHANGE;
}
self->orders_state.last_order = RDP_ORDER_PATBLT;
if (rect != 0)
{ /* if clip is present, still check if it's needed */ if (x < rect->left || y < rect->top ||
x + cx > rect->right || y + cy > rect->bottom)
{
order_flags |= TS_BOUNDS;
if (xrdp_orders_last_bounds(self, rect))
{
order_flags |= TS_ZERO_BOUNDS_DELTAS;
}
}
}
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;
}
/*****************************************************************************/ /* returns error */ /* send a dest blt order */ /* max size 21 */ int
xrdp_orders_dest_blt(struct xrdp_orders *self, int x, int y, int cx, int cy, int rop, struct xrdp_rect *rect)
{ int order_flags; int vals[8]; int present; char *present_ptr; char *order_flags_ptr;
if (rect != 0)
{ /* if clip is present, still check if it's needed */ if (x < rect->left || y < rect->top ||
x + cx > rect->right || y + cy > rect->bottom)
{
order_flags |= TS_BOUNDS;
if (xrdp_orders_last_bounds(self, rect))
{
order_flags |= TS_ZERO_BOUNDS_DELTAS;
}
}
}
/*****************************************************************************/ /* returns error */ /* send a line order */ /* max size 32 */ int
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)
{ 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;
}
/*****************************************************************************/ /* returns error */ /* send a mem blt order */ /* max size 30 */ int
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 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;
if (self->orders_state.last_order != RDP_ORDER_MEMBLT)
{
order_flags |= TS_TYPE_CHANGE;
}
self->orders_state.last_order = RDP_ORDER_MEMBLT;
if (rect != 0)
{ /* if clip is present, still check if it's needed */ if (x < rect->left || y < rect->top ||
x + cx > rect->right || y + cy > rect->bottom)
{
order_flags |= TS_BOUNDS;
if (xrdp_orders_last_bounds(self, rect))
{
order_flags |= TS_ZERO_BOUNDS_DELTAS;
}
}
}
/*****************************************************************************/ /* returns error */ int
xrdp_orders_composite_blt(struct xrdp_orders *self, int srcidx, int srcformat, int srcwidth, int srcrepeat, int *srctransform, int mskflags, int mskidx, int mskformat, int mskwidth, int mskrepeat, int op, int srcx, int srcy, int mskx, int msky, int dstx, int dsty, int width, int height, int dstformat, struct xrdp_rect *rect)
{ int order_flags; int vals[20]; int present; char *present_ptr; char *order_flags_ptr;
if (xrdp_orders_check(self, 80) != 0)
{ return1;
}
self->order_count++;
order_flags = TS_STANDARD; if (self->orders_state.last_order != RDP_ORDER_COMPOSITE)
{
order_flags |= TS_TYPE_CHANGE;
}
self->orders_state.last_order = RDP_ORDER_COMPOSITE; if (rect != 0)
{ /* if clip is present, still check if it's needed */ if (dstx < rect->left || dsty < rect->top ||
dstx + width > rect->right || dsty + height > rect->bottom)
{
order_flags |= TS_BOUNDS; if (xrdp_orders_last_bounds(self, rect))
{
/*****************************************************************************/ /* returns error */ int
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 order_flags = 0; int present = 0; char *present_ptr = (char *)NULL; char *order_flags_ptr = (char *)NULL;
/*****************************************************************************/ /* returns error */ /* when a palette gets sent, send the main palette too */ int
xrdp_orders_send_palette(struct xrdp_orders *self, int *palette, int cache_id)
{ int order_flags; int len; int i;
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);
}
LOG_DEVEL(LOG_LEVEL_TRACE, "Adding order [MS-RDPEGDI] CACHE_COLOR_TABLE_ORDER " "cacheIndex %d, numberColors 256, colorTable <omitted from log>",
cache_id); return0;
}
/*****************************************************************************/ /* returns error */ /* max size width * height * Bpp + 16 */ int
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; int max_order_size; struct xrdp_client_info *ci;
if (Bpp == 4)
{ for (i = height - 1; i >= 0; i--)
{ for (j = 0; j < width; j++)
{
pixel = GETPIXEL32(data, j, i, width);
out_uint8(self->out_s, pixel);
out_uint8(self->out_s, pixel >> 8);
out_uint8(self->out_s, pixel >> 16);
out_uint8(self->out_s, pixel >> 24);
}
out_uint8s(self->out_s, Bpp * e);
}
} elseif (Bpp == 3)
{ for (i = height - 1; i >= 0; i--)
{ for (j = 0; j < width; j++)
{
pixel = GETPIXEL32(data, j, i, width);
out_uint8(self->out_s, pixel);
out_uint8(self->out_s, pixel >> 8);
out_uint8(self->out_s, pixel >> 16);
}
out_uint8s(self->out_s, Bpp * e);
}
} elseif (Bpp == 2)
{ for (i = height - 1; i >= 0; i--)
{ for (j = 0; j < width; j++)
{
pixel = GETPIXEL16(data, j, i, width);
out_uint8(self->out_s, pixel);
out_uint8(self->out_s, pixel >> 8);
}
out_uint8s(self->out_s, Bpp * e);
}
} elseif (Bpp == 1)
{ for (i = height - 1; i >= 0; i--)
{ for (j = 0; j < width; j++)
{
pixel = GETPIXEL8(data, j, i, width);
out_uint8(self->out_s, pixel);
}
out_uint8s(self->out_s, Bpp * e);
}
}
return0;
}
/*****************************************************************************/ /* returns error */ /* max size width * height * Bpp + 16 */ int
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; int max_order_size; struct xrdp_client_info *ci;
/*****************************************************************************/ /* returns error */ /* max size datasize + 18*/ /* todo, only sends one for now */ staticint
xrdp_orders_cache_glyph(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; int flags;
if (font_char->bpp == 8) /* alpha font */
{
datasize = ((font_char->width + 3) & ~3) * font_char->height;
flags = 8 | 0x4000;
} else
{
datasize = FONT_DATASIZE(font_char);
flags = 8;
} if (xrdp_orders_check(self, datasize + 18) != 0)
{ return1;
}
self->order_count++;
order_flags = TS_STANDARD | TS_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, flags);
out_uint8(self->out_s, TS_CACHE_GLYPH); /* 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); return0;
}
/*****************************************************************************/ /* returns error */ staticint write_2byte_signed(struct stream *s, int value)
{ unsignedchar byte; int negative = 0;
/*****************************************************************************/ /* returns error */ /* max size datasize + 15*/ /* todo, only sends one for now */ staticint
xrdp_orders_cache_glyph_v2(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; int extra_flags; char *len_ptr;
/*****************************************************************************/ /* returns error */ /* max size width * height * Bpp + 14 */ int
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; int max_order_size; struct xrdp_client_info *ci;
if (Bpp == 4)
{ for (i = height - 1; i >= 0; i--)
{ for (j = 0; j < width; j++)
{
pixel = GETPIXEL32(data, j, i, width);
out_uint8(self->out_s, pixel);
out_uint8(self->out_s, pixel >> 8);
out_uint8(self->out_s, pixel >> 16);
out_uint8(self->out_s, pixel >> 24);
}
out_uint8s(self->out_s, Bpp * e);
}
} elseif (Bpp == 3)
{ for (i = height - 1; i >= 0; i--)
{ for (j = 0; j < width; j++)
{
pixel = GETPIXEL32(data, j, i, width);
out_uint8(self->out_s, pixel);
out_uint8(self->out_s, pixel >> 8);
out_uint8(self->out_s, pixel >> 16);
}
out_uint8s(self->out_s, Bpp * e);
}
} elseif (Bpp == 2)
{ for (i = height - 1; i >= 0; i--)
{ for (j = 0; j < width; j++)
{
pixel = GETPIXEL16(data, j, i, width);
out_uint8(self->out_s, pixel);
out_uint8(self->out_s, pixel >> 8);
}
out_uint8s(self->out_s, Bpp * e);
}
} elseif (Bpp == 1)
{ for (i = height - 1; i >= 0; i--)
{ for (j = 0; j < width; j++)
{
pixel = GETPIXEL8(data, j, i, width);
out_uint8(self->out_s, pixel);
}
out_uint8s(self->out_s, Bpp * e);
}
}
return0;
}
/*****************************************************************************/ /* returns error */ /* max size width * height * Bpp + 14 */ int
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; int max_order_size; struct xrdp_client_info *ci;
#ifdefined(XRDP_JPEG) /*****************************************************************************/ staticint
xrdp_orders_send_as_jpeg(struct xrdp_orders *self, int width, int height, int bpp, int hints)
{ if (hints & 1)
{ return0;
}
if (bpp != 24)
{ return0;
}
if (width * height < 64)
{ return0;
}
return1;
} #endif
#ifdefined(XRDP_NEUTRINORDP) /*****************************************************************************/ /* secondary drawing order (bitmap v3) using remotefx compression */ staticint
xrdp_orders_send_as_rfx(struct xrdp_orders *self, int width, int height, int bpp, int hints)
{ if (hints & 1)
{ return0;
}
#ifdefined(XRDP_JPEG) || defined(XRDP_NEUTRINORDP) /*****************************************************************************/ staticint
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;
/*****************************************************************************/ /* returns error */ /* send a brush cache entry */ int
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;
/*****************************************************************************/ /* returns error */ /* send an off screen bitmap entry */ int
xrdp_orders_send_create_os_surface(struct xrdp_orders *self, int id, int width, int height, struct list *del_list)
{ int order_flags; int cache_id; int flags; int index; int bytes; int num_del_list;
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);
}
}
return0;
}
/*****************************************************************************/ /* returns error */ int
xrdp_orders_send_switch_os_surface(struct xrdp_orders *self, int id)
{ int order_flags; int cache_id;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.