From e0fc7297f5bd0c4297e6b6b8ca2d7cd80251b1c9 Mon Sep 17 00:00:00 2001 From: Jay Sorg Date: Sun, 13 May 2012 13:56:15 -0700 Subject: [PATCH] pass the client_info(caps) on to module and xserver --- common/xrdp_client_info.h | 79 +++++++++++++++++++++++++++++++++++++++ libxrdp/libxrdp.h | 1 + libxrdp/libxrdpinc.h | 45 +--------------------- libxrdp/xrdp_rdp.c | 30 ++++++++++++++- xorg/X11R7.6/rdp/rdp.h | 3 ++ xorg/X11R7.6/rdp/rdpup.c | 22 ++++++++++- xrdp/xrdp.h | 1 + xrdp/xrdp_mm.c | 4 ++ xup/xup.c | 31 +++++++++++++-- xup/xup.h | 3 +- 10 files changed, 168 insertions(+), 51 deletions(-) create mode 100644 common/xrdp_client_info.h diff --git a/common/xrdp_client_info.h b/common/xrdp_client_info.h new file mode 100644 index 00000000..7fe93c26 --- /dev/null +++ b/common/xrdp_client_info.h @@ -0,0 +1,79 @@ +/* + Copyright (c) 2012 Jay Sorg + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. + + xrdp / xserver info / caps + +*/ + +#if !defined(XRDP_CLIENT_INFO_H) +#define XRDP_CLIENT_INFO_H + +struct xrdp_client_info +{ + int size; /* bytes for this structure */ + int bpp; + int width; + int height; + /* bitmap cache info */ + int cache1_entries; + int cache1_size; + int cache2_entries; + int cache2_size; + int cache3_entries; + int cache3_size; + int bitmap_cache_persist_enable; /* 0 or 2 */ + int bitmap_cache_version; /* 0 = original version, 2 = v2 */ + /* pointer info */ + int pointer_cache_entries; + /* other */ + int use_bitmap_comp; + int use_bitmap_cache; + int op1; /* use smaller bitmap header, non cache */ + int op2; /* use smaller bitmap header in bitmap cache */ + int desktop_cache; + int use_compact_packets; /* rdp5 smaller packets */ + char hostname[32]; + int build; + int keylayout; + char username[256]; + char password[256]; + char domain[256]; + char program[256]; + char directory[256]; + int rdp_compression; + int rdp_autologin; + int crypt_level; /* 1, 2, 3 = low, medium, high */ + int channel_code; /* 0 = no channels 1 = channels */ + int sound_code; /* 1 = leave sound at server */ + int is_mce; + int rdp5_performanceflags; + int brush_cache_code; /* 0 = no cache 1 = 8x8 standard cache + 2 = arbitrary dimensions */ + char client_ip[256]; + int max_bpp; + int jpeg; /* non standard bitmap cache v2 cap */ + int offscreen_support_level; + int offscreen_cache_size; + int offscreen_cache_entries; + int rfx; +}; + +#endif diff --git a/libxrdp/libxrdp.h b/libxrdp/libxrdp.h index d63b140a..6b105676 100644 --- a/libxrdp/libxrdp.h +++ b/libxrdp/libxrdp.h @@ -37,6 +37,7 @@ #include "file.h" #include "libxrdpinc.h" #include "file_loc.h" +#include "xrdp_client_info.h" /* tcp */ struct xrdp_tcp diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h index 7b285c3b..82ac9ad0 100644 --- a/libxrdp/libxrdpinc.h +++ b/libxrdp/libxrdpinc.h @@ -23,50 +23,7 @@ #ifndef LIBXRDPINC_H #define LIBXRDPINC_H -struct xrdp_client_info -{ - int bpp; - int width; - int height; - /* bitmap cache info */ - int cache1_entries; - int cache1_size; - int cache2_entries; - int cache2_size; - int cache3_entries; - int cache3_size; - int bitmap_cache_persist_enable; /* 0 or 2 */ - int bitmap_cache_version; /* 0 = original version, 2 = v2 */ - /* pointer info */ - int pointer_cache_entries; - /* other */ - int use_bitmap_comp; - int use_bitmap_cache; - int op1; /* use smaller bitmap header, non cache */ - int op2; /* use smaller bitmap header in bitmap cache */ - int desktop_cache; - int use_compact_packets; /* rdp5 smaller packets */ - char hostname[32]; - int build; - int keylayout; - char username[256]; - char password[256]; - char domain[256]; - char program[256]; - char directory[256]; - int rdp_compression; - int rdp_autologin; - int crypt_level; /* 1, 2, 3 = low, medium, high */ - int channel_code; /* 0 = no channels 1 = channels */ - int sound_code; /* 1 = leave sound at server */ - int is_mce; - int rdp5_performanceflags; - int brush_cache_code; /* 0 = no cache 1 = 8x8 standard cache - 2 = arbitrary dimensions */ - char client_ip[256]; - int max_bpp; - int jpeg; -}; +/* struct xrdp_client_info moved to xrdp_client_info.h */ struct xrdp_brush { diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index 08618610..bdbeed48 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -157,6 +157,7 @@ xrdp_rdp_create(struct xrdp_session* session, struct trans* trans) #if defined(XRDP_FREERDP1) self->mppc_enc = mppc_enc_new(PROTO_RDP_50); #endif + self->client_info.size = sizeof(self->client_info); DEBUG(("out xrdp_rdp_create")); return self; } @@ -795,6 +796,32 @@ xrdp_process_capset_brushcache(struct xrdp_rdp* self, struct stream* s, return 0; } +/*****************************************************************************/ +static int APP_CC +xrdp_process_offscreen_bmpcache(struct xrdp_rdp* self, struct stream* s, + int len) +{ + int i32; + + if (len - 4 < 8) + { + g_writeln("xrdp_process_offscreen_bmpcache: bad len"); + return 1; + } + in_uint32_le(s, i32); + self->client_info.offscreen_support_level = i32; + in_uint16_le(s, i32); + self->client_info.offscreen_cache_size = i32 * 1024; + in_uint16_le(s, i32); + self->client_info.offscreen_cache_entries = i32; + g_writeln("xrdp_process_offscreen_bmpcache: support level %d " + "cache size %d MB cache entries %d", + self->client_info.offscreen_support_level, + self->client_info.offscreen_cache_size, + self->client_info.offscreen_cache_entries); + return 0; +} + /*****************************************************************************/ int APP_CC xrdp_rdp_process_confirm_active(struct xrdp_rdp* self, struct stream* s) @@ -869,7 +896,8 @@ xrdp_rdp_process_confirm_active(struct xrdp_rdp* self, struct stream* s) DEBUG(("--16")); break; case 17: /* 17 */ - DEBUG(("--16")); + DEBUG(("CAPSET_TYPE_OFFSCREEN_CACHE")); + xrdp_process_offscreen_bmpcache(self, s, len); break; case RDP_CAPSET_BMPCACHE2: /* 19 */ DEBUG(("RDP_CAPSET_BMPCACHE2")); diff --git a/xorg/X11R7.6/rdp/rdp.h b/xorg/X11R7.6/rdp/rdp.h index 9548f76b..98c0c067 100644 --- a/xorg/X11R7.6/rdp/rdp.h +++ b/xorg/X11R7.6/rdp/rdp.h @@ -70,6 +70,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "exevents.h" #include "xserver-properties.h" #include "xkbsrv.h" +#include "../../../common/xrdp_client_info.h" //#include "colormapst.h" @@ -133,6 +134,8 @@ struct _rdpScreenInfoRec int rdp_bpp; int rdp_Bpp; int rdp_Bpp_mask; + + struct xrdp_client_info client_info; }; typedef struct _rdpScreenInfoRec rdpScreenInfoRec; typedef rdpScreenInfoRec* rdpScreenInfoPtr; diff --git a/xorg/X11R7.6/rdp/rdpup.c b/xorg/X11R7.6/rdp/rdpup.c index c0845a2e..338e0751 100644 --- a/xorg/X11R7.6/rdp/rdpup.c +++ b/xorg/X11R7.6/rdp/rdpup.c @@ -413,6 +413,7 @@ rdpup_process_msg(struct stream* s) int param2; int param3; int param4; + int bytes; in_uint16_le(s, msg_type); if (msg_type == 103) @@ -494,9 +495,28 @@ param4 %d\n", msg, param1, param2, param3, param4)); break; } } + else if (msg_type == 104) + { + in_uint32_le(s, bytes); + if (bytes > sizeof(g_rdpScreen.client_info)) + { + bytes = sizeof(g_rdpScreen.client_info); + } + memcpy(&(g_rdpScreen.client_info), s->p - 4, bytes); + g_rdpScreen.client_info.size = bytes; + ErrorF("rdpup_process_msg: got client info bytes %d\n", bytes); + ErrorF(" jpeg support %d\n", + g_rdpScreen.client_info.jpeg); + ErrorF(" offscreen support %d\n", + g_rdpScreen.client_info.offscreen_support_level); + ErrorF(" offscreen size %d\n", + g_rdpScreen.client_info.offscreen_cache_size); + ErrorF(" offscreen entries %d\n", + g_rdpScreen.client_info.offscreen_cache_entries); + } else { - rdpLog("unknown message type in rdpup_process_msg\n"); + rdpLog("unknown message type in rdpup_process_msg %d\n", msg_type); } return 0; } diff --git a/xrdp/xrdp.h b/xrdp/xrdp.h index 409a2ace..2bc3c8b0 100644 --- a/xrdp/xrdp.h +++ b/xrdp/xrdp.h @@ -37,6 +37,7 @@ #include "list.h" #include "file.h" #include "file_loc.h" +#include "xrdp_client_info.h" /* xrdp.c */ long APP_CC diff --git a/xrdp/xrdp_mm.c b/xrdp/xrdp_mm.c index c15c4bd5..a41208eb 100644 --- a/xrdp/xrdp_mm.c +++ b/xrdp/xrdp_mm.c @@ -430,6 +430,10 @@ xrdp_mm_setup_mod2(struct xrdp_mm* self) list_add_item(self->login_values, (long)g_strdup(text)); } /* always set these */ + + self->mod->mod_set_param(self->mod, "client_info", + (char*)(self->wm->session->client_info)); + name = self->wm->session->client_info->hostname; self->mod->mod_set_param(self->mod, "hostname", name); g_snprintf(text, 255, "%d", self->wm->session->client_info->keylayout); diff --git a/xup/xup.c b/xup/xup.c index 449ec5f7..28c1b50c 100644 --- a/xup/xup.c +++ b/xup/xup.c @@ -248,7 +248,7 @@ lib_mod_connect(struct mod* mod) out_uint32_le(s, mod->width); out_uint32_le(s, mod->height); out_uint32_le(s, mod->bpp); - out_uint32_le(s, mod->rfx); /* send rfx flag */ + out_uint32_le(s, 0); s_mark_end(s); len = (int)(s->end - s->data); s_pop_layer(s, iso_hdr); @@ -471,6 +471,29 @@ lib_mod_process_orders(struct mod* mod, int type, struct stream* s) } +/******************************************************************************/ +/* return error */ +static int APP_CC +lib_send_client_info(struct mod* mod) +{ + struct stream* s; + int len; + + make_stream(s); + init_stream(s, 8192); + s_push_layer(s, iso_hdr, 4); + out_uint16_le(s, 104); + g_memcpy(s->p, &(mod->client_info), sizeof(mod->client_info)); + s->p += sizeof(mod->client_info); + s_mark_end(s); + len = (int)(s->end - s->data); + s_pop_layer(s, iso_hdr); + out_uint32_le(s, len); + lib_send(mod, s->data, len); + free_stream(s); + return 0; +} + /******************************************************************************/ /* return error */ int DEFAULT_CC @@ -531,6 +554,7 @@ lib_mod_signal(struct mod* mod) } s->p = phold + len; } + lib_send_client_info(mod); } } else if (type == 3) /* order list with len after type */ @@ -592,10 +616,9 @@ lib_mod_set_param(struct mod* mod, char* name, char* value) { g_strncpy(mod->port, value, 255); } - else if (g_strcasecmp(name, "rfx") == 0) + else if (g_strcasecmp(name, "client_info") == 0) { - mod->rfx = g_atoi(value); - g_writeln("mod->rfx = %d", mod->rfx); + g_memcpy(&(mod->client_info), value, sizeof(mod->client_info)); } return 0; } diff --git a/xup/xup.h b/xup/xup.h index ec2957ce..26d893af 100644 --- a/xup/xup.h +++ b/xup/xup.h @@ -25,6 +25,7 @@ #include "parse.h" #include "os_calls.h" #include "defines.h" +#include "xrdp_client_info.h" #define CURRENT_MOD_VER 2 @@ -105,5 +106,5 @@ struct mod char port[256]; tbus sck_obj; int shift_state; - int rfx; + struct xrdp_client_info client_info; };