diff options
-rw-r--r-- | common/xrdp_client_info.h | 2 | ||||
-rw-r--r-- | libxrdp/xrdp_caps.c | 844 | ||||
-rw-r--r-- | libxrdp/xrdp_fastpath.c | 9 |
3 files changed, 448 insertions, 407 deletions
diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h index c17675e4..6536db48 100644 --- a/common/xrdp_client_info.h +++ b/common/xrdp_client_info.h @@ -121,6 +121,8 @@ struct xrdp_client_info int mcs_connection_type; int mcs_early_capability_flags; + int max_fastpath_frag_bytes; + }; #endif diff --git a/libxrdp/xrdp_caps.c b/libxrdp/xrdp_caps.c index 5fd8017f..d9e39c71 100644 --- a/libxrdp/xrdp_caps.c +++ b/libxrdp/xrdp_caps.c @@ -22,404 +22,7 @@ #include "libxrdp.h" /*****************************************************************************/ -int APP_CC -xrdp_caps_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_caps_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; - if (!s_check_rem(s, 4)) - { - g_writeln("xrdp_caps_process_confirm_active: error 1"); - return 1; - } - in_uint16_le(s, type); - in_uint16_le(s, len); - if ((len < 4) || !s_check_rem(s, len - 4)) - { - g_writeln("xrdp_caps_process_confirm_active: error len %d", len, s->end - s->p); - return 1; - } - len -= 4; - switch (type) - { - case RDP_CAPSET_GENERAL: /* 1 */ - DEBUG(("RDP_CAPSET_GENERAL")); - xrdp_caps_process_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_caps_process_order(self, s, len); - break; - case RDP_CAPSET_BMPCACHE: /* 4 */ - DEBUG(("RDP_CAPSET_BMPCACHE")); - xrdp_caps_process_bmpcache(self, s, len); - break; - case RDP_CAPSET_CONTROL: /* 5 */ - DEBUG(("RDP_CAPSET_CONTROL")); - break; - case 6: - xrdp_caps_process_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_caps_process_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 */ - xrdp_caps_process_input(self, s, len); - break; - case 14: /* 14 */ - DEBUG(("--14")); - break; - case RDP_CAPSET_BRUSHCACHE: /* 15 */ - xrdp_caps_process_brushcache(self, s, len); - break; - case 16: /* 16 */ - DEBUG(("--16")); - break; - case 17: /* 17 */ - DEBUG(("CAPSET_TYPE_OFFSCREEN_CACHE")); - xrdp_caps_process_offscreen_bmpcache(self, s, len); - break; - case RDP_CAPSET_BMPCACHE2: /* 19 */ - DEBUG(("RDP_CAPSET_BMPCACHE2")); - xrdp_caps_process_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_caps_process_rail(self, s, len); - break; - case 0x0018: /* 24 CAPSETTYPE_WINDOW */ - xrdp_caps_process_window(self, s, len); - break; - case 26: /* 26 */ - DEBUG(("--26")); - break; - case RDP_CAPSET_BMPCODECS: /* 0x1d(29) */ - xrdp_caps_process_codecs(self, s, len); - break; - default: - g_writeln("unknown in xrdp_caps_process_confirm_active %d", type); - break; - } - - s->p = p + len + 4; - } - - DEBUG(("out xrdp_caps_process_confirm_active")); - return 0; -} -/*****************************************************************************/ -int APP_CC -xrdp_caps_send_demand_active(struct xrdp_rdp *self) -{ - struct stream *s; - int caps_count; - int caps_size; - int codec_caps_count; - int codec_caps_size; - int flags; - 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); - - DEBUG(("in xrdp_caps_send_demand_active")); - - 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 */ - /* NO_BITMAP_COMPRESSION_HDR 0x0400 - FASTPATH_OUTPUT_SUPPORTED 0x0001 */ - if (self->client_info.use_fast_path & 1) - { - out_uint16_le(s, 0x401); - } - else - { - out_uint16_le(s, 0x400); - } - 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); /* NEG_DSTBLT_INDEX 0x00 0 */ - out_uint8(s, 1); /* NEG_PATBLT_INDEX 0x01 1 */ - out_uint8(s, 1); /* NEG_SCRBLT_INDEX 0x02 2 */ - out_uint8(s, 1); /* NEG_MEMBLT_INDEX 0x03 3 */ - out_uint8(s, 0); /* NEG_MEM3BLT_INDEX 0x04 4 */ - out_uint8(s, 0); /* NEG_ATEXTOUT_INDEX 0x05 5 */ - out_uint8(s, 0); /* NEG_AEXTTEXTOUT_INDEX 0x06 6 */ - out_uint8(s, 0); /* NEG_DRAWNINEGRID_INDEX 0x07 7 */ - out_uint8(s, 1); /* NEG_LINETO_INDEX 0x08 8 */ - out_uint8(s, 0); /* NEG_MULTI_DRAWNINEGRID_INDEX 0x09 9 */ - out_uint8(s, 1); /* NEG_OPAQUE_RECT_INDEX 0x0A 10 */ - out_uint8(s, 0); /* NEG_SAVEBITMAP_INDEX 0x0B 11 */ - out_uint8(s, 0); /* NEG_WTEXTOUT_INDEX 0x0C 12 */ - out_uint8(s, 0); /* NEG_MEMBLT_V2_INDEX 0x0D 13 */ - out_uint8(s, 0); /* NEG_MEM3BLT_V2_INDEX 0x0E 14 */ - out_uint8(s, 0); /* NEG_MULTIDSTBLT_INDEX 0x0F 15 */ - out_uint8(s, 0); /* NEG_MULTIPATBLT_INDEX 0x10 16 */ - out_uint8(s, 0); /* NEG_MULTISCRBLT_INDEX 0x11 17 */ - out_uint8(s, 1); /* NEG_MULTIOPAQUERECT_INDEX 0x12 18 */ - out_uint8(s, 0); /* NEG_FAST_INDEX_INDEX 0x13 19 */ - out_uint8(s, 0); /* NEG_POLYGON_SC_INDEX 0x14 20 */ - out_uint8(s, 0); /* NEG_POLYGON_CB_INDEX 0x15 21 */ - out_uint8(s, 0); /* NEG_POLYLINE_INDEX 0x16 22 */ - out_uint8(s, 0); /* unused 0x17 23 */ - out_uint8(s, 0); /* NEG_FAST_GLYPH_INDEX 0x18 24 */ - out_uint8(s, 0); /* NEG_ELLIPSE_SC_INDEX 0x19 25 */ - out_uint8(s, 0); /* NEG_ELLIPSE_CB_INDEX 0x1A 26 */ - out_uint8(s, 1); /* NEG_GLYPH_INDEX_INDEX 0x1B 27 */ - out_uint8(s, 0); /* NEG_GLYPH_WEXTTEXTOUT_INDEX 0x1C 28 */ - out_uint8(s, 0); /* NEG_GLYPH_WLONGTEXTOUT_INDEX 0x1D 29 */ - out_uint8(s, 0); /* NEG_GLYPH_WLONGEXTTEXTOUT_INDEX 0x1E 30 */ - out_uint8(s, 0); /* unused 0x1F 31 */ - 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) */ - - /* INPUT_FLAG_SCANCODES 0x0001 - INPUT_FLAG_MOUSEX 0x0004 - INPUT_FLAG_FASTPATH_INPUT 0x0008 - INPUT_FLAG_FASTPATH_INPUT2 0x0020 */ - flags = 0x0001 | 0x0004; - if (self->client_info.use_fast_path & 2) - { - /* 0x0008 INPUT_FLAG_FASTPATH_INPUT */ - /* 0x0020 INPUT_FLAG_FASTPATH_INPUT2 */ - flags |= 0x0008 | 0x0020; - } - out_uint16_le(s, flags); - out_uint8s(s, 82); - - /* 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 */ - - /* 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 */ - - 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_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; - } - DEBUG(("out (1) xrdp_caps_send_demand_active")); - - /* send Monitor Layout PDU for multimon */ - if (self->client_info.monitorCount > 0 && - self->client_info.multimon == 1) - { - DEBUG(("xrdp_caps_send_demand_active: sending monitor layout pdu")); - if (xrdp_caps_send_monitorlayout(self) != 0) - { - g_writeln("xrdp_caps_send_demand_active: error sending monitor layout pdu"); - } - } - - free_stream(s); - return 0; -} -/*****************************************************************************/ -int APP_CC +static int APP_CC xrdp_caps_process_general(struct xrdp_rdp *self, struct stream *s, int len) { @@ -447,8 +50,9 @@ xrdp_caps_process_general(struct xrdp_rdp *self, struct stream *s, } return 0; } + /*****************************************************************************/ -int APP_CC +static int APP_CC xrdp_caps_process_order(struct xrdp_rdp *self, struct stream *s, int len) { @@ -513,9 +117,10 @@ xrdp_caps_process_order(struct xrdp_rdp *self, struct stream *s, in_uint8s(s, 4); /* Unknown */ return 0; } + /*****************************************************************************/ /* get the bitmap cache size */ -int APP_CC +static int APP_CC xrdp_caps_process_bmpcache(struct xrdp_rdp *self, struct stream *s, int len) { @@ -554,9 +159,10 @@ xrdp_caps_process_bmpcache(struct xrdp_rdp *self, struct stream *s, self->client_info.cache3_size)); return 0; } + /*****************************************************************************/ /* get the bitmap cache size */ -int APP_CC +static int APP_CC xrdp_caps_process_bmpcache2(struct xrdp_rdp *self, struct stream *s, int len) { @@ -597,8 +203,9 @@ xrdp_caps_process_bmpcache2(struct xrdp_rdp *self, struct stream *s, self->client_info.cache3_size)); return 0; } + /*****************************************************************************/ -int APP_CC +static int APP_CC xrdp_caps_process_cache_v3_codec_id(struct xrdp_rdp *self, struct stream *s, int len) { @@ -615,9 +222,10 @@ xrdp_caps_process_cache_v3_codec_id(struct xrdp_rdp *self, struct stream *s, self->client_info.v3_codec_id = codec_id; return 0; } + /*****************************************************************************/ /* get the number of client cursor cache */ -int APP_CC +static int APP_CC xrdp_caps_process_pointercache(struct xrdp_rdp *self, struct stream *s, int len) { @@ -657,8 +265,9 @@ xrdp_caps_process_pointercache(struct xrdp_rdp *self, struct stream *s, } return 0; } + /*****************************************************************************/ -int APP_CC +static int APP_CC xrdp_caps_process_input(struct xrdp_rdp *self, struct stream *s, int len) { @@ -674,6 +283,7 @@ xrdp_caps_process_input(struct xrdp_rdp *self, struct stream *s, } return 0; } + /*****************************************************************************/ /* get the type of client brush cache */ int APP_CC @@ -691,6 +301,7 @@ xrdp_caps_process_brushcache(struct xrdp_rdp *self, struct stream *s, self->client_info.brush_cache_code = code; return 0; } + /*****************************************************************************/ int APP_CC xrdp_caps_process_offscreen_bmpcache(struct xrdp_rdp *self, struct stream *s, @@ -716,6 +327,7 @@ xrdp_caps_process_offscreen_bmpcache(struct xrdp_rdp *self, struct stream *s, self->client_info.offscreen_cache_entries); return 0; } + /*****************************************************************************/ int APP_CC xrdp_caps_process_rail(struct xrdp_rdp *self, struct stream *s, int len) @@ -733,8 +345,9 @@ xrdp_caps_process_rail(struct xrdp_rdp *self, struct stream *s, int len) self->client_info.rail_support_level); return 0; } + /*****************************************************************************/ -int APP_CC +static int APP_CC xrdp_caps_process_window(struct xrdp_rdp *self, struct stream *s, int len) { int i32; @@ -757,8 +370,9 @@ xrdp_caps_process_window(struct xrdp_rdp *self, struct stream *s, int len) self->client_info.wnd_num_icon_cache_entries); return 0; } + /*****************************************************************************/ -int APP_CC +static int APP_CC xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len) { int codec_id; @@ -837,6 +451,424 @@ xrdp_caps_process_codecs(struct xrdp_rdp *self, struct stream *s, int len) } /*****************************************************************************/ +static int APP_CC +xrdp_caps_process_multifragmetupdate(struct xrdp_rdp *self, struct stream *s, + int len) +{ + int MaxRequestSize; + + in_uint32_le(s, MaxRequestSize); + self->client_info.max_fastpath_frag_bytes = MaxRequestSize; + return 0; +} + +/*****************************************************************************/ +int APP_CC +xrdp_caps_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_caps_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; + if (!s_check_rem(s, 4)) + { + g_writeln("xrdp_caps_process_confirm_active: error 1"); + return 1; + } + in_uint16_le(s, type); + in_uint16_le(s, len); + if ((len < 4) || !s_check_rem(s, len - 4)) + { + g_writeln("xrdp_caps_process_confirm_active: error len %d", len, s->end - s->p); + return 1; + } + len -= 4; + switch (type) + { + case RDP_CAPSET_GENERAL: /* 1 */ + DEBUG(("RDP_CAPSET_GENERAL")); + xrdp_caps_process_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_caps_process_order(self, s, len); + break; + case RDP_CAPSET_BMPCACHE: /* 4 */ + DEBUG(("RDP_CAPSET_BMPCACHE")); + xrdp_caps_process_bmpcache(self, s, len); + break; + case RDP_CAPSET_CONTROL: /* 5 */ + DEBUG(("RDP_CAPSET_CONTROL")); + break; + case 6: + xrdp_caps_process_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_caps_process_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 */ + xrdp_caps_process_input(self, s, len); + break; + case 14: /* 14 */ + DEBUG(("--14")); + break; + case RDP_CAPSET_BRUSHCACHE: /* 15 */ + xrdp_caps_process_brushcache(self, s, len); + break; + case 16: /* 16 */ + DEBUG(("--16")); + break; + case 17: /* 17 */ + DEBUG(("CAPSET_TYPE_OFFSCREEN_CACHE")); + xrdp_caps_process_offscreen_bmpcache(self, s, len); + break; + case RDP_CAPSET_BMPCACHE2: /* 19 */ + DEBUG(("RDP_CAPSET_BMPCACHE2")); + xrdp_caps_process_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_caps_process_rail(self, s, len); + break; + case 0x0018: /* 24 CAPSETTYPE_WINDOW */ + xrdp_caps_process_window(self, s, len); + break; + case 0x001A: /* 26 CAPSETTYPE_MULTIFRAGMENTUPDATE */ + xrdp_caps_process_multifragmetupdate(self, s, len); + break; + case RDP_CAPSET_BMPCODECS: /* 0x1d(29) */ + xrdp_caps_process_codecs(self, s, len); + break; + default: + g_writeln("unknown in xrdp_caps_process_confirm_active %d", type); + break; + } + + s->p = p + len + 4; + } + + DEBUG(("out xrdp_caps_process_confirm_active")); + return 0; +} +/*****************************************************************************/ +int APP_CC +xrdp_caps_send_demand_active(struct xrdp_rdp *self) +{ + struct stream *s; + int caps_count; + int caps_size; + int codec_caps_count; + int codec_caps_size; + int flags; + 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); + + DEBUG(("in xrdp_caps_send_demand_active")); + + 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 */ + /* NO_BITMAP_COMPRESSION_HDR 0x0400 + FASTPATH_OUTPUT_SUPPORTED 0x0001 */ + if (self->client_info.use_fast_path & 1) + { + out_uint16_le(s, 0x401); + } + else + { + out_uint16_le(s, 0x400); + } + 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); /* NEG_DSTBLT_INDEX 0x00 0 */ + out_uint8(s, 1); /* NEG_PATBLT_INDEX 0x01 1 */ + out_uint8(s, 1); /* NEG_SCRBLT_INDEX 0x02 2 */ + out_uint8(s, 1); /* NEG_MEMBLT_INDEX 0x03 3 */ + out_uint8(s, 0); /* NEG_MEM3BLT_INDEX 0x04 4 */ + out_uint8(s, 0); /* NEG_ATEXTOUT_INDEX 0x05 5 */ + out_uint8(s, 0); /* NEG_AEXTTEXTOUT_INDEX 0x06 6 */ + out_uint8(s, 0); /* NEG_DRAWNINEGRID_INDEX 0x07 7 */ + out_uint8(s, 1); /* NEG_LINETO_INDEX 0x08 8 */ + out_uint8(s, 0); /* NEG_MULTI_DRAWNINEGRID_INDEX 0x09 9 */ + out_uint8(s, 1); /* NEG_OPAQUE_RECT_INDEX 0x0A 10 */ + out_uint8(s, 0); /* NEG_SAVEBITMAP_INDEX 0x0B 11 */ + out_uint8(s, 0); /* NEG_WTEXTOUT_INDEX 0x0C 12 */ + out_uint8(s, 0); /* NEG_MEMBLT_V2_INDEX 0x0D 13 */ + out_uint8(s, 0); /* NEG_MEM3BLT_V2_INDEX 0x0E 14 */ + out_uint8(s, 0); /* NEG_MULTIDSTBLT_INDEX 0x0F 15 */ + out_uint8(s, 0); /* NEG_MULTIPATBLT_INDEX 0x10 16 */ + out_uint8(s, 0); /* NEG_MULTISCRBLT_INDEX 0x11 17 */ + out_uint8(s, 1); /* NEG_MULTIOPAQUERECT_INDEX 0x12 18 */ + out_uint8(s, 0); /* NEG_FAST_INDEX_INDEX 0x13 19 */ + out_uint8(s, 0); /* NEG_POLYGON_SC_INDEX 0x14 20 */ + out_uint8(s, 0); /* NEG_POLYGON_CB_INDEX 0x15 21 */ + out_uint8(s, 0); /* NEG_POLYLINE_INDEX 0x16 22 */ + out_uint8(s, 0); /* unused 0x17 23 */ + out_uint8(s, 0); /* NEG_FAST_GLYPH_INDEX 0x18 24 */ + out_uint8(s, 0); /* NEG_ELLIPSE_SC_INDEX 0x19 25 */ + out_uint8(s, 0); /* NEG_ELLIPSE_CB_INDEX 0x1A 26 */ + out_uint8(s, 1); /* NEG_GLYPH_INDEX_INDEX 0x1B 27 */ + out_uint8(s, 0); /* NEG_GLYPH_WEXTTEXTOUT_INDEX 0x1C 28 */ + out_uint8(s, 0); /* NEG_GLYPH_WLONGTEXTOUT_INDEX 0x1D 29 */ + out_uint8(s, 0); /* NEG_GLYPH_WLONGEXTTEXTOUT_INDEX 0x1E 30 */ + out_uint8(s, 0); /* unused 0x1F 31 */ + 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) */ + + /* INPUT_FLAG_SCANCODES 0x0001 + INPUT_FLAG_MOUSEX 0x0004 + INPUT_FLAG_FASTPATH_INPUT 0x0008 + INPUT_FLAG_FASTPATH_INPUT2 0x0020 */ + flags = 0x0001 | 0x0004; + if (self->client_info.use_fast_path & 2) + { + /* 0x0008 INPUT_FLAG_FASTPATH_INPUT */ + /* 0x0020 INPUT_FLAG_FASTPATH_INPUT2 */ + flags |= 0x0008 | 0x0020; + } + out_uint16_le(s, flags); + out_uint8s(s, 82); + + /* 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 */ + + /* 6 - bitmap cache v3 codecid */ + caps_count++; + out_uint16_le(s, 0x0006); + out_uint16_le(s, 5); + out_uint8(s, 0); /* client sets */ + + if (self->client_info.use_fast_path & 1) /* fastpath output on */ + { + caps_count++; + out_uint16_le(s, 0x001A); /* 26 CAPSETTYPE_MULTIFRAGMENTUPDATE */ + out_uint16_le(s, 8); + out_uint32_le(s, 3 * 1024 * 1024); /* 3MB */ + } + + out_uint8s(s, 4); /* pad */ + + 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_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; + } + DEBUG(("out (1) xrdp_caps_send_demand_active")); + + /* send Monitor Layout PDU for multimon */ + if (self->client_info.monitorCount > 0 && + self->client_info.multimon == 1) + { + DEBUG(("xrdp_caps_send_demand_active: sending monitor layout pdu")); + if (xrdp_caps_send_monitorlayout(self) != 0) + { + g_writeln("xrdp_caps_send_demand_active: error sending monitor layout pdu"); + } + } + + free_stream(s); + return 0; +} + +/*****************************************************************************/ int APP_CC xrdp_caps_send_monitorlayout(struct xrdp_rdp *self) { diff --git a/libxrdp/xrdp_fastpath.c b/libxrdp/xrdp_fastpath.c index 372e9079..8739c764 100644 --- a/libxrdp/xrdp_fastpath.c +++ b/libxrdp/xrdp_fastpath.c @@ -101,7 +101,14 @@ xrdp_fastpath_recv(struct xrdp_fastpath *self, struct stream *s) int APP_CC xrdp_fastpath_init(struct xrdp_fastpath *self, struct stream *s) { - init_stream(s, 32 * 1024); + int bytes; + + bytes = self->session->client_info->max_fastpath_frag_bytes; + if (bytes < 32 * 1024) + { + bytes = 32 * 1024; + } + init_stream(s, bytes); return 0; } |