diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index 4e7218d6..7a4342db 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -346,6 +346,8 @@ xrdp_sec_delete(struct xrdp_sec* self); int APP_CC xrdp_sec_init(struct xrdp_sec* self, struct stream* s); int APP_CC +xrdp_sec_recv_fastpath(struct xrdp_sec *self, struct stream *s); +int APP_CC xrdp_sec_recv(struct xrdp_sec* self, struct stream* s, int* chan); int APP_CC xrdp_sec_send(struct xrdp_sec* self, struct stream* s, int chan); diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index a808aaa8..26e5c453 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -757,7 +757,11 @@ xrdp_rdp_send_demand_active(struct xrdp_rdp *self) 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); @@ -810,7 +814,8 @@ static int APP_CC xrdp_process_capset_general(struct xrdp_rdp *self, struct stream *s, int len) { - int i; + int extraFlags; + int client_does_fastpath_output; if (len < 10 + 2) { @@ -818,12 +823,19 @@ xrdp_process_capset_general(struct xrdp_rdp *self, struct stream *s, return 1; } in_uint8s(s, 10); - in_uint16_le(s, i); + in_uint16_le(s, extraFlags); /* use_compact_packets is pretty much 'use rdp5' */ - self->client_info.use_compact_packets = (i != 0); + self->client_info.use_compact_packets = (extraFlags != 0); /* op2 is a boolean to use compact bitmap headers in bitmap cache */ /* set it to same as 'use rdp5' boolean */ self->client_info.op2 = self->client_info.use_compact_packets; + /* FASTPATH_OUTPUT_SUPPORTED 0x0001 */ + client_does_fastpath_output = extraFlags & FASTPATH_OUTPUT_SUPPORTED; + if ((self->client_info.use_fast_path & 1) && !client_does_fastpath_output) + { + /* server supports fast path output and client does not, turn it off */ + self->client_info.use_fast_path &= ~1; + } return 0; } @@ -1042,6 +1054,24 @@ xrdp_process_capset_pointercache(struct xrdp_rdp *self, struct stream *s, return 0; } +/*****************************************************************************/ +static int APP_CC +xrdp_process_capset_input(struct xrdp_rdp *self, struct stream *s, + int len) +{ + int inputFlags; + int client_does_fastpath_input; + + in_uint16_le(s, inputFlags); + client_does_fastpath_input = (inputFlags & INPUT_FLAG_FASTPATH_INPUT) || + (inputFlags & INPUT_FLAG_FASTPATH_INPUT2); + if ((self->client_info.use_fast_path & 2) && !client_does_fastpath_input) + { + self->client_info.use_fast_path &= ~2; + } + return 0; +} + /*****************************************************************************/ /* get the type of client brush cache */ static int APP_CC @@ -1285,7 +1315,7 @@ xrdp_rdp_process_confirm_active(struct xrdp_rdp *self, struct stream *s) DEBUG(("--12")); break; case 13: /* 13 */ - DEBUG(("--13")); + xrdp_process_capset_input(self, s, len); break; case 14: /* 14 */ DEBUG(("--14"));