Merge pull request #1330 from jsorg71/suppress

handle TS_SUPPRESS_OUTPUT_PDU
This commit is contained in:
jsorg71 2019-04-25 15:06:12 -07:00 committed by GitHub
commit 074cfdee4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 281 additions and 61 deletions

View File

@ -156,6 +156,7 @@ struct xrdp_client_info
int no_orders_supported; int no_orders_supported;
int use_cache_glyph_v2; int use_cache_glyph_v2;
int rail_enable; int rail_enable;
int suppress_output;
}; };
#endif #endif

View File

@ -810,7 +810,8 @@ xrdp_caps_send_demand_active(struct xrdp_rdp *self)
out_uint16_le(s, 0); /* Update capability */ out_uint16_le(s, 0); /* Update capability */
out_uint16_le(s, 0); /* Remote unshare capability */ out_uint16_le(s, 0); /* Remote unshare capability */
out_uint16_le(s, 0); /* Compression level */ out_uint16_le(s, 0); /* Compression level */
out_uint16_le(s, 0); /* Pad */ out_uint8(s, 1); /* refreshRectSupport */
out_uint8(s, 1); /* suppressOutputSupport */
/* Output bitmap capability set */ /* Output bitmap capability set */
caps_count++; caps_count++;

View File

@ -1209,21 +1209,91 @@ xrdp_rdp_process_frame_ack(struct xrdp_rdp *self, struct stream *s)
return 0; return 0;
} }
/*****************************************************************************/
static int
xrdp_rdp_process_suppress(struct xrdp_rdp *self, struct stream *s)
{
int allowDisplayUpdates;
int left;
int top;
int right;
int bottom;
if (!s_check_rem(s, 1))
{
return 1;
}
in_uint8(s, allowDisplayUpdates);
g_writeln("xrdp_rdp_process_suppress: allowDisplayUpdates %d bytes "
"left %d", allowDisplayUpdates, (int) (s->end - s->p));
switch (allowDisplayUpdates)
{
case 0: /* SUPPRESS_DISPLAY_UPDATES */
self->client_info.suppress_output = 1;
g_writeln("xrdp_rdp_process_suppress: suppress_output %d",
self->client_info.suppress_output);
if (self->session->callback != 0)
{
self->session->callback(self->session->id, 0x5559, 1,
0, 0, 0);
}
break;
case 1: /* ALLOW_DISPLAY_UPDATES */
self->client_info.suppress_output = 0;
if (!s_check_rem(s, 11))
{
return 1;
}
in_uint8s(s, 3); /* pad */
in_uint16_le(s, left);
in_uint16_le(s, top);
in_uint16_le(s, right);
in_uint16_le(s, bottom);
g_writeln("xrdp_rdp_process_suppress: suppress_output %d "
"left %d top %d right %d bottom %d",
self->client_info.suppress_output,
left, top, right, bottom);
if (self->session->callback != 0)
{
self->session->callback(self->session->id, 0x5559, 0,
MAKELONG(left, top),
MAKELONG(right, bottom), 0);
}
break;
}
return 0;
}
/*****************************************************************************/ /*****************************************************************************/
/* RDP_PDU_DATA */ /* RDP_PDU_DATA */
int int
xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s) xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
{ {
int data_type; int uncompressedLength;
int pduType2;
int compressedType;
int compressedLength;
if (!s_check_rem(s, 12))
{
return 1;
}
in_uint8s(s, 6); in_uint8s(s, 6);
in_uint8s(s, 2); /* len */ in_uint16_le(s, uncompressedLength);
in_uint8(s, data_type); in_uint8(s, pduType2);
in_uint8s(s, 1); /* ctype */ in_uint8(s, compressedType);
in_uint8s(s, 2); /* clen */ in_uint16_le(s, compressedLength);
DEBUG(("xrdp_rdp_process_data code %d", data_type)); if (compressedType != 0)
{
switch (data_type) /* don't support compression */
return 1;
}
if (compressedLength > uncompressedLength)
{
return 1;
}
DEBUG(("xrdp_rdp_process_data pduType2 %d", pduType2));
switch (pduType2)
{ {
case RDP_DATA_PDU_POINTER: /* 27(0x1b) */ case RDP_DATA_PDU_POINTER: /* 27(0x1b) */
xrdp_rdp_process_data_pointer(self, s); xrdp_rdp_process_data_pointer(self, s);
@ -1240,11 +1310,8 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
case 33: /* 33(0x21) ?? Invalidate an area I think */ case 33: /* 33(0x21) ?? Invalidate an area I think */
xrdp_rdp_process_screen_update(self, s); xrdp_rdp_process_screen_update(self, s);
break; break;
case 35: /* 35(0x23) */ case 35: /* 35(0x23) PDUTYPE2_SUPPRESS_OUTPUT */
/* 35 ?? this comes when minimizing a full screen mstsc.exe 2600 */ xrdp_rdp_process_suppress(self, s);
/* I think this is saying the client no longer wants screen */
/* updates and it will issue a 33 above to catch up */
/* so minimized apps don't take bandwidth */
break; break;
case 36: /* 36(0x24) ?? disconnect query? */ case 36: /* 36(0x24) ?? disconnect query? */
/* when this message comes, send a 37 back so the client */ /* when this message comes, send a 37 back so the client */
@ -1259,10 +1326,9 @@ xrdp_rdp_process_data(struct xrdp_rdp *self, struct stream *s)
xrdp_rdp_process_frame_ack(self, s); xrdp_rdp_process_frame_ack(self, s);
break; break;
default: default:
g_writeln("unknown in xrdp_rdp_process_data %d", data_type); g_writeln("unknown in xrdp_rdp_process_data pduType2 %d", pduType2);
break; break;
} }
return 0; return 0;
} }
/*****************************************************************************/ /*****************************************************************************/

View File

@ -27,6 +27,12 @@
#include "log.h" #include "log.h"
#include <freerdp/settings.h> #include <freerdp/settings.h>
#if defined(VERSION_STRUCT_RDP_FREERDP)
#if VERSION_STRUCT_RDP_FREERDP > 1
#define NEUTRINORDP_HAS_SUPPRESS_OUTPUT
#endif
#endif
#ifdef XRDP_DEBUG #ifdef XRDP_DEBUG
#define LOG_LEVEL 99 #define LOG_LEVEL 99
#else #else
@ -541,6 +547,24 @@ lxrdp_check_wait_objs(struct mod *mod)
return 0; return 0;
} }
/******************************************************************************/
static int
lxrdp_frame_ack(struct mod* mod, int flags, int frame_id)
{
return 0;
}
/******************************************************************************/
static int
lxrdp_suppress_output(struct mod* mod, int suppress,
int left, int top, int right, int bottom)
{
#if defined(NEUTRINORDP_HAS_SUPPRESS_OUTPUT)
mod->inst->SendSuppressOutput(mod->inst, !suppress, left, top, right, bottom);
#endif
return 0;
}
/******************************************************************************/ /******************************************************************************/
static void static void
lfreerdp_begin_paint(rdpContext *context) lfreerdp_begin_paint(rdpContext *context)
@ -2009,6 +2033,8 @@ mod_init(void)
mod->mod_session_change = lxrdp_session_change; mod->mod_session_change = lxrdp_session_change;
mod->mod_get_wait_objs = lxrdp_get_wait_objs; mod->mod_get_wait_objs = lxrdp_get_wait_objs;
mod->mod_check_wait_objs = lxrdp_check_wait_objs; mod->mod_check_wait_objs = lxrdp_check_wait_objs;
mod->mod_frame_ack = lxrdp_frame_ack;
mod->mod_suppress_output = lxrdp_suppress_output;
mod->inst = freerdp_new(); mod->inst = freerdp_new();
mod->inst->PreConnect = lfreerdp_pre_connect; mod->inst->PreConnect = lfreerdp_pre_connect;

View File

@ -58,7 +58,7 @@ struct pointer_item
int bpp; int bpp;
}; };
#define CURRENT_MOD_VER 3 #define CURRENT_MOD_VER 4
struct mod struct mod
{ {
@ -76,7 +76,10 @@ struct mod
int (*mod_get_wait_objs)(struct mod *v, tbus *read_objs, int *rcount, int (*mod_get_wait_objs)(struct mod *v, tbus *read_objs, int *rcount,
tbus *write_objs, int *wcount, int *timeout); tbus *write_objs, int *wcount, int *timeout);
int (*mod_check_wait_objs)(struct mod *v); int (*mod_check_wait_objs)(struct mod *v);
tintptr mod_dumby[100 - 9]; /* align, 100 minus the number of mod int (*mod_frame_ack)(struct mod* mod, int flags, int frame_id);
int (*mod_suppress_output)(struct mod* mod, int suppress,
int left, int top, int right, int bottom);
tintptr mod_dumby[100 - 11]; /* align, 100 minus the number of mod
functions above */ functions above */
/* server functions */ /* server functions */
int (*server_begin_update)(struct mod *v); int (*server_begin_update)(struct mod *v);

View File

@ -379,6 +379,8 @@ lib_mod_event(struct vnc *v, int msg, long param1, long param2,
error = lib_send_copy(v, s); error = lib_send_copy(v, s);
} }
else if (msg == 200) /* invalidate */ else if (msg == 200) /* invalidate */
{
if (v->suppress_output == 0)
{ {
/* FramebufferUpdateRequest */ /* FramebufferUpdateRequest */
init_stream(s, 8192); init_stream(s, 8192);
@ -395,6 +397,7 @@ lib_mod_event(struct vnc *v, int msg, long param1, long param2,
s_mark_end(s); s_mark_end(s);
error = lib_send_copy(v, s); error = lib_send_copy(v, s);
} }
}
free_stream(s); free_stream(s);
return error; return error;
@ -741,6 +744,8 @@ lib_framebuffer_update(struct vnc *v)
} }
if (error == 0) if (error == 0)
{
if (v->suppress_output == 0)
{ {
/* FramebufferUpdateRequest */ /* FramebufferUpdateRequest */
init_stream(s, 8192); init_stream(s, 8192);
@ -753,6 +758,7 @@ lib_framebuffer_update(struct vnc *v)
s_mark_end(s); s_mark_end(s);
error = lib_send_copy(v, s); error = lib_send_copy(v, s);
} }
}
free_stream(s); free_stream(s);
free_stream(pixel_s); free_stream(pixel_s);
@ -916,7 +922,7 @@ lib_mod_process_message(struct vnc *v, struct stream *s)
} }
else else
{ {
g_sprintf(text, "VNC unknown in lib_mod_signal %d", type); g_sprintf(text, "VNC unknown in lib_mod_process_message %d", type);
v->server_msg(v, text, 1); v->server_msg(v, text, 1);
} }
} }
@ -1339,6 +1345,8 @@ lib_mod_connect(struct vnc *v)
} }
if (error == 0) if (error == 0)
{
if (v->suppress_output == 0)
{ {
/* FramebufferUpdateRequest */ /* FramebufferUpdateRequest */
init_stream(s, 8192); init_stream(s, 8192);
@ -1352,6 +1360,7 @@ lib_mod_connect(struct vnc *v)
s_mark_end(s); s_mark_end(s);
error = trans_force_write_s(v->trans, s); error = trans_force_write_s(v->trans, s);
} }
}
if (error == 0) if (error == 0)
{ {
@ -1492,6 +1501,43 @@ lib_mod_check_wait_objs(struct vnc *v)
return rv; return rv;
} }
/******************************************************************************/
/* return error */
int
lib_mod_frame_ack(struct vnc* v, int flags, int frame_id)
{
return 0;
}
/******************************************************************************/
/* return error */
int
lib_mod_suppress_output(struct vnc* v, int suppress,
int left, int top, int right, int bottom)
{
int error;
struct stream *s;
error = 0;
v->suppress_output = suppress;
if (suppress == 0)
{
/* FramebufferUpdateRequest */
make_stream(s);
init_stream(s, 8192);
out_uint8(s, 3);
out_uint8(s, 0);
out_uint16_be(s, 0);
out_uint16_be(s, 0);
out_uint16_be(s, v->mod_width);
out_uint16_be(s, v->mod_height);
s_mark_end(s);
error = lib_send_copy(v, s);
free_stream(s);
}
return error;
}
/******************************************************************************/ /******************************************************************************/
tintptr EXPORT_CC tintptr EXPORT_CC
mod_init(void) mod_init(void)
@ -1511,6 +1557,8 @@ mod_init(void)
v->mod_set_param = lib_mod_set_param; v->mod_set_param = lib_mod_set_param;
v->mod_get_wait_objs = lib_mod_get_wait_objs; v->mod_get_wait_objs = lib_mod_get_wait_objs;
v->mod_check_wait_objs = lib_mod_check_wait_objs; v->mod_check_wait_objs = lib_mod_check_wait_objs;
v->mod_frame_ack = lib_mod_frame_ack;
v->mod_suppress_output = lib_mod_suppress_output;
return (tintptr) v; return (tintptr) v;
} }

View File

@ -24,7 +24,7 @@
#include "os_calls.h" #include "os_calls.h"
#include "defines.h" #include "defines.h"
#define CURRENT_MOD_VER 3 #define CURRENT_MOD_VER 4
struct vnc struct vnc
{ {
@ -42,7 +42,10 @@ struct vnc
int (*mod_get_wait_objs)(struct vnc* v, tbus* read_objs, int* rcount, int (*mod_get_wait_objs)(struct vnc* v, tbus* read_objs, int* rcount,
tbus* write_objs, int* wcount, int* timeout); tbus* write_objs, int* wcount, int* timeout);
int (*mod_check_wait_objs)(struct vnc* v); int (*mod_check_wait_objs)(struct vnc* v);
tintptr mod_dumby[100 - 9]; /* align, 100 minus the number of mod int (*mod_frame_ack)(struct vnc* v, int flags, int frame_id);
int (*mod_suppress_output)(struct vnc* v, int suppress,
int left, int top, int right, int bottom);
tintptr mod_dumby[100 - 11]; /* align, 100 minus the number of mod
functions above */ functions above */
/* server functions */ /* server functions */
int (*server_begin_update)(struct vnc* v); int (*server_begin_update)(struct vnc* v);
@ -116,4 +119,5 @@ struct vnc
struct trans *trans; struct trans *trans;
int got_guid; int got_guid;
tui8 guid[16]; tui8 guid[16];
int suppress_output;
}; };

View File

@ -371,6 +371,9 @@ xrdp_bitmap_compress(char* in_data, int width, int height,
/* xrdp_mm.c */ /* xrdp_mm.c */
int int
xrdp_mm_drdynvc_up(struct xrdp_mm* self); xrdp_mm_drdynvc_up(struct xrdp_mm* self);
int
xrdp_mm_suppress_output(struct xrdp_mm* self, int suppress,
int left, int top, int right, int bottom);
struct xrdp_mm* struct xrdp_mm*
xrdp_mm_create(struct xrdp_wm* owner); xrdp_mm_create(struct xrdp_wm* owner);
void void

View File

@ -999,6 +999,25 @@ xrdp_mm_drdynvc_up(struct xrdp_mm* self)
return 0; return 0;
} }
/******************************************************************************/
int
xrdp_mm_suppress_output(struct xrdp_mm* self, int suppress,
int left, int top, int right, int bottom)
{
LLOGLN(0, ("xrdp_mm_suppress_output: suppress %d "
"left %d top %d right %d bottom %d",
suppress, left, top, right, bottom));
if (self->mod != NULL)
{
if (self->mod->mod_suppress_output != NULL)
{
self->mod->mod_suppress_output(self->mod, suppress,
left, top, right, bottom);
}
}
return 0;
}
/*****************************************************************************/ /*****************************************************************************/
/* open response from client going to channel server */ /* open response from client going to channel server */
static int static int

View File

@ -48,7 +48,9 @@ struct xrdp_mod
tbus* write_objs, int* wcount, int* timeout); tbus* write_objs, int* wcount, int* timeout);
int (*mod_check_wait_objs)(struct xrdp_mod* v); int (*mod_check_wait_objs)(struct xrdp_mod* v);
int (*mod_frame_ack)(struct xrdp_mod* v, int flags, int frame_id); int (*mod_frame_ack)(struct xrdp_mod* v, int flags, int frame_id);
tintptr mod_dumby[100 - 10]; /* align, 100 minus the number of mod int (*mod_suppress_output)(struct xrdp_mod* v, int suppress,
int left, int top, int right, int bottom);
tintptr mod_dumby[100 - 11]; /* align, 100 minus the number of mod
functions above */ functions above */
/* server functions */ /* server functions */
int (*server_begin_update)(struct xrdp_mod* v); int (*server_begin_update)(struct xrdp_mod* v);

View File

@ -1916,6 +1916,11 @@ callback(intptr_t id, int msg, intptr_t param1, intptr_t param2,
case 0x5558: case 0x5558:
xrdp_mm_drdynvc_up(wm->mm); xrdp_mm_drdynvc_up(wm->mm);
break; break;
case 0x5559:
xrdp_mm_suppress_output(wm->mm, param1,
LOWORD(param2), HIWORD(param2),
LOWORD(param3), HIWORD(param3));
break;
} }
return rv; return rv;
} }

View File

@ -1143,6 +1143,33 @@ send_paint_rect_ex_ack(struct mod *mod, int flags, int frame_id)
return 0; return 0;
} }
/******************************************************************************/
/* return error */
static int
send_suppress_output(struct mod *mod, int suppress,
int left, int top, int right, int bottom)
{
int len;
struct stream *s;
make_stream(s);
init_stream(s, 8192);
s_push_layer(s, iso_hdr, 4);
out_uint16_le(s, 108);
out_uint32_le(s, suppress);
out_uint32_le(s, left);
out_uint32_le(s, top);
out_uint32_le(s, right);
out_uint32_le(s, bottom);
s_mark_end(s);
len = (int)(s->end - s->data);
s_pop_layer(s, iso_hdr);
out_uint32_le(s, len);
lib_send_copy(mod, s);
free_stream(s);
return 0;
}
/******************************************************************************/ /******************************************************************************/
/* return error */ /* return error */
static int static int
@ -1556,6 +1583,18 @@ lib_mod_frame_ack(struct mod *amod, int flags, int frame_id)
return 0; return 0;
} }
/******************************************************************************/
/* return error */
int
lib_mod_suppress_output(struct mod *amod, int suppress,
int left, int top, int right, int bottom)
{
LLOGLN(10, ("lib_mod_suppress_output: suppress 0x%8.8x left %d top %d "
"right %d bottom %d", suppress, left, top, right, bottom));
send_suppress_output(amod, suppress, left, top, right, bottom);
return 0;
}
/******************************************************************************/ /******************************************************************************/
tintptr EXPORT_CC tintptr EXPORT_CC
mod_init(void) mod_init(void)
@ -1575,6 +1614,7 @@ mod_init(void)
mod->mod_get_wait_objs = lib_mod_get_wait_objs; mod->mod_get_wait_objs = lib_mod_get_wait_objs;
mod->mod_check_wait_objs = lib_mod_check_wait_objs; mod->mod_check_wait_objs = lib_mod_check_wait_objs;
mod->mod_frame_ack = lib_mod_frame_ack; mod->mod_frame_ack = lib_mod_frame_ack;
mod->mod_suppress_output = lib_mod_suppress_output;
return (tintptr) mod; return (tintptr) mod;
} }

View File

@ -26,7 +26,7 @@
#include "xrdp_client_info.h" #include "xrdp_client_info.h"
#include "xrdp_rail.h" #include "xrdp_rail.h"
#define CURRENT_MOD_VER 3 #define CURRENT_MOD_VER 4
struct mod struct mod
{ {
@ -45,7 +45,9 @@ struct mod
tbus* write_objs, int* wcount, int* timeout); tbus* write_objs, int* wcount, int* timeout);
int (*mod_check_wait_objs)(struct mod* v); int (*mod_check_wait_objs)(struct mod* v);
int (*mod_frame_ack)(struct mod* v, int flags, int frame_id); int (*mod_frame_ack)(struct mod* v, int flags, int frame_id);
tintptr mod_dumby[100 - 10]; /* align, 100 minus the number of mod int (*mod_suppress_output)(struct mod* v, int suppress,
int left, int top, int right, int bottom);
tintptr mod_dumby[100 - 11]; /* align, 100 minus the number of mod
functions above */ functions above */
/* server functions */ /* server functions */
int (*server_begin_update)(struct mod* v); int (*server_begin_update)(struct mod* v);