From bd55e85c131241913f21d881dfd66870c62ceefc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Mon, 25 Jul 2011 23:51:13 -0400 Subject: [PATCH] libfreerdp-core: improve order parsing --- libfreerdp-core/orders.c | 201 +++++++++++++++++++++++++++++---------- libfreerdp-core/orders.h | 52 +++++++++- libfreerdp-core/rdp.h | 2 + 3 files changed, 205 insertions(+), 50 deletions(-) diff --git a/libfreerdp-core/orders.c b/libfreerdp-core/orders.c index ad06d3eae..6b386bc31 100644 --- a/libfreerdp-core/orders.c +++ b/libfreerdp-core/orders.c @@ -77,114 +77,141 @@ uint8 ALTSEC_DRAWING_ORDER_STRINGS[][32] = "Frame Marker" }; +uint8 PRIMARY_DRAWING_ORDER_FIELD_BYTES[] = +{ + DSTBLT_ORDER_FIELD_BYTES, + PATBLT_ORDER_FIELD_BYTES, + SCRBLT_ORDER_FIELD_BYTES, + 0, 0, 0, 0, + DRAW_NINE_GRID_ORDER_FIELD_BYTES, + MULTI_DRAW_NINE_GRID_ORDER_FIELD_BYTES, + LINE_TO_ORDER_FIELD_BYTES, + OPAQUE_RECT_ORDER_FIELD_BYTES, + SAVE_BITMAP_ORDER_FIELD_BYTES, + MEMBLT_ORDER_FIELD_BYTES, + MEM3BLT_ORDER_FIELD_BYTES, + MULTI_DSTBLT_ORDER_FIELD_BYTES, + MULTI_PATBLT_ORDER_FIELD_BYTES, + MULTI_SCRBLT_ORDER_FIELD_BYTES, + MULTI_OPAQUE_RECT_ORDER_FIELD_BYTES, + FAST_INDEX_ORDER_FIELD_BYTES, + POLYGON_SC_ORDER_FIELD_BYTES, + POLYGON_CB_ORDER_FIELD_BYTES, + POLYLINE_ORDER_FIELD_BYTES, + FAST_GLYPH_ORDER_FIELD_BYTES, + ELLIPSE_SC_ORDER_FIELD_BYTES, + ELLIPSE_CB_ORDER_FIELD_BYTES, + GLYPH_INDEX_ORDER_FIELD_BYTES +}; + /* Primary Drawing Orders */ -void rdp_recv_dstblt_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_dstblt_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_patblt_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_patblt_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_scrblt_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_scrblt_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_draw_nine_grid_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_draw_nine_grid_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_multi_draw_nine_grid_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_multi_draw_nine_grid_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_line_to_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_line_to_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_opaque_rect_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_opaque_rect_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_save_bitmap_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_save_bitmap_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_memblt_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_memblt_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_mem3blt_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_mem3blt_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_multi_dstblt_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_multi_dstblt_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_multi_patblt_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_multi_patblt_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_multi_scrblt_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_multi_scrblt_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_multi_opaque_rect_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_multi_opaque_rect_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_fast_index_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_fast_index_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_polygon_sc_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_polygon_sc_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_polygon_cb_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_polygon_cb_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_polyline_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_polyline_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_fast_glyph_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_fast_glyph_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_ellipse_sc_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_ellipse_sc_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_ellipse_cb_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_ellipse_cb_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } -void rdp_recv_glyph_index_order(rdpRdp* rdp, STREAM* s) +void rdp_recv_glyph_index_order(rdpRdp* rdp, STREAM* s, ORDER_INFO* orderInfo) { } @@ -303,102 +330,167 @@ void rdp_recv_frame_marker_order(rdpRdp* rdp, STREAM* s) } +void rdp_read_field_flags(STREAM* s, uint32* fieldFlags, uint8 flags, uint8 fieldBytes) +{ + int i; + uint8 byte; + + if (flags & ORDER_ZERO_FIELD_BYTE_BIT0) + fieldBytes--; + + if (flags & ORDER_ZERO_FIELD_BYTE_BIT1) + { + if (fieldBytes < 2) + fieldBytes = 0; + else + fieldBytes -= 2; + } + + *fieldFlags = 0; + for (i = 0; i < fieldBytes; i++) + { + stream_read_uint8(s, byte); + *fieldFlags |= byte << (i * 8); + } +} + +void rdp_read_bounds(STREAM* s, ORDER_INFO* orderInfo) +{ + uint8 flags; + + stream_read_uint8(s, flags); /* field flags */ + + if (flags & BOUND_DELTA_LEFT) + stream_read_uint8(s, orderInfo->deltaBoundLeft); + else if (flags & BOUND_LEFT) + stream_read_uint16(s, orderInfo->boundLeft); + + if (flags & BOUND_DELTA_TOP) + stream_read_uint8(s, orderInfo->deltaBoundTop); + else if (flags & BOUND_TOP) + stream_read_uint16(s, orderInfo->boundTop); + + if (flags & BOUND_DELTA_RIGHT) + stream_read_uint8(s, orderInfo->deltaBoundRight); + else if (flags & BOUND_RIGHT) + stream_read_uint16(s, orderInfo->boundRight); + + if (flags & BOUND_DELTA_BOTTOM) + stream_read_uint8(s, orderInfo->deltaBoundBottom); + else if (flags & BOUND_BOTTOM) + stream_read_uint16(s, orderInfo->boundBottom); +} + void rdp_recv_primary_order(rdpRdp* rdp, STREAM* s, uint8 flags) { - uint8 orderType; + ORDER_INFO* orderInfo = &(rdp->order_info); - stream_read_uint8(s, orderType); /* orderType (1 byte) */ + if (flags & ORDER_TYPE_CHANGE) + stream_read_uint8(s, orderInfo->orderType); /* orderType (1 byte) */ - printf("%s Primary Drawing Order\n", PRIMARY_DRAWING_ORDER_STRINGS[orderType]); + rdp_read_field_flags(s, &(orderInfo->fieldFlags), flags, + PRIMARY_DRAWING_ORDER_FIELD_BYTES[orderInfo->orderType]); - switch (orderType) + if (flags & ORDER_BOUNDS) + { + if (!(flags & ORDER_ZERO_BOUNDS_DELTAS)) + { + rdp_read_bounds(s, orderInfo); + } + } + + orderInfo->deltaCoordinates = (flags & ORDER_DELTA_COORDINATES) ? True : False; + + printf("%s Primary Drawing Order\n", PRIMARY_DRAWING_ORDER_STRINGS[orderInfo->orderType]); + + switch (orderInfo->orderType) { case ORDER_TYPE_DSTBLT: - rdp_recv_dstblt_order(rdp, s); + rdp_recv_dstblt_order(rdp, s, orderInfo); break; case ORDER_TYPE_PATBLT: - rdp_recv_patblt_order(rdp, s); + rdp_recv_patblt_order(rdp, s, orderInfo); break; case ORDER_TYPE_SCRBLT: - rdp_recv_scrblt_order(rdp, s); + rdp_recv_scrblt_order(rdp, s, orderInfo); break; case ORDER_TYPE_DRAW_NINE_GRID: - rdp_recv_draw_nine_grid_order(rdp, s); + rdp_recv_draw_nine_grid_order(rdp, s, orderInfo); break; case ORDER_TYPE_MULTI_DRAW_NINE_GRID: - rdp_recv_multi_draw_nine_grid_order(rdp, s); + rdp_recv_multi_draw_nine_grid_order(rdp, s, orderInfo); break; case ORDER_TYPE_LINE_TO: - rdp_recv_line_to_order(rdp, s); + rdp_recv_line_to_order(rdp, s, orderInfo); break; case ORDER_TYPE_OPAQUE_RECT: - rdp_recv_opaque_rect_order(rdp, s); + rdp_recv_opaque_rect_order(rdp, s, orderInfo); break; case ORDER_TYPE_SAVE_BITMAP: - rdp_recv_save_bitmap_order(rdp, s); + rdp_recv_save_bitmap_order(rdp, s, orderInfo); break; case ORDER_TYPE_MEMBLT: - rdp_recv_memblt_order(rdp, s); + rdp_recv_memblt_order(rdp, s, orderInfo); break; case ORDER_TYPE_MEM3BLT: - rdp_recv_mem3blt_order(rdp, s); + rdp_recv_mem3blt_order(rdp, s, orderInfo); break; case ORDER_TYPE_MULTI_DSTBLT: - rdp_recv_multi_dstblt_order(rdp, s); + rdp_recv_multi_dstblt_order(rdp, s, orderInfo); break; case ORDER_TYPE_MULTI_PATBLT: - rdp_recv_multi_patblt_order(rdp, s); + rdp_recv_multi_patblt_order(rdp, s, orderInfo); break; case ORDER_TYPE_MULTI_SCRBLT: - rdp_recv_multi_scrblt_order(rdp, s); + rdp_recv_multi_scrblt_order(rdp, s, orderInfo); break; case ORDER_TYPE_MULTI_OPAQUE_RECT: - rdp_recv_multi_opaque_rect_order(rdp, s); + rdp_recv_multi_opaque_rect_order(rdp, s, orderInfo); break; case ORDER_TYPE_FAST_INDEX: - rdp_recv_fast_index_order(rdp, s); + rdp_recv_fast_index_order(rdp, s, orderInfo); break; case ORDER_TYPE_POLYGON_SC: - rdp_recv_polygon_sc_order(rdp, s); + rdp_recv_polygon_sc_order(rdp, s, orderInfo); break; case ORDER_TYPE_POLYGON_CB: - rdp_recv_polygon_cb_order(rdp, s); + rdp_recv_polygon_cb_order(rdp, s, orderInfo); break; case ORDER_TYPE_POLYLINE: - rdp_recv_polyline_order(rdp, s); + rdp_recv_polyline_order(rdp, s, orderInfo); break; case ORDER_TYPE_FAST_GLYPH: - rdp_recv_fast_glyph_order(rdp, s); + rdp_recv_fast_glyph_order(rdp, s, orderInfo); break; case ORDER_TYPE_ELLIPSE_SC: - rdp_recv_ellipse_sc_order(rdp, s); + rdp_recv_ellipse_sc_order(rdp, s, orderInfo); break; case ORDER_TYPE_ELLIPSE_CB: - rdp_recv_ellipse_cb_order(rdp, s); + rdp_recv_ellipse_cb_order(rdp, s, orderInfo); break; case ORDER_TYPE_GLYPH_INDEX: - rdp_recv_glyph_index_order(rdp, s); + rdp_recv_glyph_index_order(rdp, s, orderInfo); break; default: @@ -408,10 +500,19 @@ void rdp_recv_primary_order(rdpRdp* rdp, STREAM* s, uint8 flags) void rdp_recv_secondary_order(rdpRdp* rdp, STREAM* s, uint8 flags) { + uint8* next; uint8 orderType; + uint16 extraFlags; + uint16 orderLength; + stream_get_mark(s, next); + stream_read_uint16(s, orderLength); /* orderLength (2 bytes) */ + stream_read_uint16(s, extraFlags); /* extraFlags (2 bytes) */ stream_read_uint8(s, orderType); /* orderType (1 byte) */ + orderLength += 13; /* adjust length (13 bytes less than actual length) */ + next += orderLength; + printf("%s Secondary Drawing Order\n", SECONDARY_DRAWING_ORDER_STRINGS[orderType]); switch (orderType) @@ -451,13 +552,15 @@ void rdp_recv_secondary_order(rdpRdp* rdp, STREAM* s, uint8 flags) default: break; } + + stream_set_mark(s, next); } void rdp_recv_altsec_order(rdpRdp* rdp, STREAM* s, uint8 flags) { uint8 orderType; - stream_read_uint8(s, orderType); /* orderType (1 byte) */ + orderType = flags >>= 2; /* orderType is in higher 6 bits of flags field */ printf("%s Alternate Secondary Drawing Order\n", ALTSEC_DRAWING_ORDER_STRINGS[orderType]); diff --git a/libfreerdp-core/orders.h b/libfreerdp-core/orders.h index 8f758dd79..4bba1f3e2 100644 --- a/libfreerdp-core/orders.h +++ b/libfreerdp-core/orders.h @@ -20,10 +20,26 @@ #ifndef __ORDERS_H #define __ORDERS_H -#include "rdp.h" #include #include +typedef struct +{ + uint8 orderType; + uint32 fieldFlags; + uint16 boundLeft; + uint16 boundTop; + uint16 boundRight; + uint16 boundBottom; + sint8 deltaBoundLeft; + sint8 deltaBoundTop; + sint8 deltaBoundRight; + sint8 deltaBoundBottom; + boolean deltaCoordinates; +} ORDER_INFO; + +#include "rdp.h" + /* Order Control Flags */ #define ORDER_STANDARD 0x01 #define ORDER_SECONDARY 0x02 @@ -34,6 +50,16 @@ #define ORDER_ZERO_FIELD_BYTE_BIT0 0x40 #define ORDER_ZERO_FIELD_BYTE_BIT1 0x80 +/* Bound Field Flags */ +#define BOUND_LEFT 0x01 +#define BOUND_TOP 0x02 +#define BOUND_RIGHT 0x04 +#define BOUND_BOTTOM 0x08 +#define BOUND_DELTA_LEFT 0x10 +#define BOUND_DELTA_TOP 0x20 +#define BOUND_DELTA_RIGHT 0x40 +#define BOUND_DELTA_BOTTOM 0x80 + /* Order Classes */ #define ORDER_PRIMARY_CLASS 0x01 #define ORDER_SECONDARY_CLASS 0x03 @@ -88,6 +114,30 @@ #define ELLIPSE_CB_ORDER_FIELDS 13 #define GLYPH_INDEX_ORDER_FIELDS 22 +/* Primary Drawing Orders Field Bytes */ +#define DSTBLT_ORDER_FIELD_BYTES 1 +#define PATBLT_ORDER_FIELD_BYTES 2 +#define SCRBLT_ORDER_FIELD_BYTES 1 +#define DRAW_NINE_GRID_ORDER_FIELD_BYTES 1 +#define MULTI_DRAW_NINE_GRID_ORDER_FIELD_BYTES 1 +#define LINE_TO_ORDER_FIELD_BYTES 2 +#define OPAQUE_RECT_ORDER_FIELD_BYTES 1 +#define SAVE_BITMAP_ORDER_FIELD_BYTES 1 +#define MEMBLT_ORDER_FIELD_BYTES 2 +#define MEM3BLT_ORDER_FIELD_BYTES 3 +#define MULTI_DSTBLT_ORDER_FIELD_BYTES 1 +#define MULTI_PATBLT_ORDER_FIELD_BYTES 2 +#define MULTI_SCRBLT_ORDER_FIELD_BYTES 2 +#define MULTI_OPAQUE_RECT_ORDER_FIELD_BYTES 2 +#define FAST_INDEX_ORDER_FIELD_BYTES 2 +#define POLYGON_SC_ORDER_FIELD_BYTES 1 +#define POLYGON_CB_ORDER_FIELD_BYTES 2 +#define POLYLINE_ORDER_FIELD_BYTES 1 +#define FAST_GLYPH_ORDER_FIELD_BYTES 2 +#define ELLIPSE_SC_ORDER_FIELD_BYTES 1 +#define ELLIPSE_CB_ORDER_FIELD_BYTES 2 +#define GLYPH_INDEX_ORDER_FIELD_BYTES 3 + /* Secondary Drawing Orders */ #define ORDER_TYPE_BITMAP_UNCOMPRESSED 0x00 #define ORDER_TYPE_CACHE_COLOR_TABLE 0x01 diff --git a/libfreerdp-core/rdp.h b/libfreerdp-core/rdp.h index b9448a8bc..256d5a49a 100644 --- a/libfreerdp-core/rdp.h +++ b/libfreerdp-core/rdp.h @@ -27,6 +27,7 @@ typedef struct rdp_rdp rdpRdp; #include "tpdu.h" #include "nego.h" #include "update.h" +#include "orders.h" #include "license.h" #include "security.h" #include "registry.h" @@ -204,6 +205,7 @@ struct rdp_rdp { boolean licensed; boolean activated; + ORDER_INFO order_info; struct rdp_mcs* mcs; struct rdp_nego* nego; struct rdp_license* license;