diff --git a/libxrdp/libxrdp.c b/libxrdp/libxrdp.c index f9009162b6..72bcf84573 100644 --- a/libxrdp/libxrdp.c +++ b/libxrdp/libxrdp.c @@ -1406,6 +1406,23 @@ libxrdp_disable_channel(struct xrdp_session *session, int channel_id, return 1; } +/*****************************************************************************/ +int +libxrdp_drdynvc_start(struct xrdp_session *session) +{ + struct xrdp_rdp *rdp; + struct xrdp_sec *sec; + struct xrdp_channel *chan; + + LOG_DEVEL(LOG_LEVEL_TRACE, "libxrdp_drdynvc_start:"); + + rdp = (struct xrdp_rdp *) (session->rdp); + sec = rdp->sec_layer; + chan = sec->chan_layer; + return xrdp_channel_drdynvc_start(chan); +} + + /*****************************************************************************/ int libxrdp_drdynvc_open(struct xrdp_session *session, const char *name, diff --git a/libxrdp/libxrdpinc.h b/libxrdp/libxrdpinc.h index 69de7801ac..e026843c31 100644 --- a/libxrdp/libxrdpinc.h +++ b/libxrdp/libxrdpinc.h @@ -241,6 +241,8 @@ int libxrdp_disable_channel(struct xrdp_session *session, int channel_id, int is_disabled); int +libxrdp_drdynvc_start(struct xrdp_session *session); +int libxrdp_drdynvc_open(struct xrdp_session *session, const char *name, int flags, struct xrdp_drdynvc_procs *procs, int *chan_id); diff --git a/libxrdp/xrdp_channel.c b/libxrdp/xrdp_channel.c index f43804d78a..c95f6ea7ae 100644 --- a/libxrdp/xrdp_channel.c +++ b/libxrdp/xrdp_channel.c @@ -752,46 +752,63 @@ xrdp_channel_drdynvc_send_capability_request(struct xrdp_channel *self) int xrdp_channel_drdynvc_start(struct xrdp_channel *self) { - int index; - int count; - struct mcs_channel_item *ci; - struct mcs_channel_item *dci; - - LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_channel_drdynvc_start: drdynvc_channel_id %d", self->drdynvc_channel_id); + int rv = 0; + LOG_DEVEL(LOG_LEVEL_INFO, + "xrdp_channel_drdynvc_start: drdynvc_channel_id %d", + self->drdynvc_channel_id); if (self->drdynvc_channel_id != -1) { - LOG_DEVEL(LOG_LEVEL_INFO, "xrdp_channel_drdynvc_start: already started"); - return 0; + LOG_DEVEL(LOG_LEVEL_INFO, + "xrdp_channel_drdynvc_start: already started"); } - dci = NULL; - count = self->mcs_layer->channel_list->count; - for (index = 0; index < count; index++) + else { - ci = (struct mcs_channel_item *) - list_get_item(self->mcs_layer->channel_list, index); - if (ci != NULL) + int index; + int count; + struct mcs_channel_item *ci; + struct mcs_channel_item *dci; + dci = NULL; + count = self->mcs_layer->channel_list->count; + for (index = 0; index < count; index++) { - if (g_strcasecmp(ci->name, "drdynvc") == 0) + ci = (struct mcs_channel_item *) + list_get_item(self->mcs_layer->channel_list, index); + if (ci != NULL) { - dci = ci; + if (g_strcasecmp(ci->name, DRDYNVC_SVC_CHANNEL_NAME) == 0) + { + dci = ci; + break; + } } } + if (dci == NULL) + { + LOG(LOG_LEVEL_WARNING, "Static channel '%s' not found.", + DRDYNVC_SVC_CHANNEL_NAME); + rv = -1; + } + else if (dci->disabled) + { + LOG(LOG_LEVEL_WARNING, "Static channel '%s' is disabled.", + DRDYNVC_SVC_CHANNEL_NAME); + rv = -1; + } + else + { + self->drdynvc_channel_id = (dci->chanid - MCS_GLOBAL_CHANNEL) - 1; + LOG_DEVEL(LOG_LEVEL_DEBUG, DRDYNVC_SVC_CHANNEL_NAME + "Initializing Dynamic Virtual Channel with channel id %d", + self->drdynvc_channel_id); + xrdp_channel_drdynvc_send_capability_request(self); + } } - if (dci != NULL) - { - self->drdynvc_channel_id = (dci->chanid - MCS_GLOBAL_CHANNEL) - 1; - LOG_DEVEL(LOG_LEVEL_DEBUG, - "Initializing Dynamic Virtual Channel with channel id %d", - self->drdynvc_channel_id); - xrdp_channel_drdynvc_send_capability_request(self); - } - else + + if (rv != 0) { - LOG(LOG_LEVEL_WARNING, - "Dynamic Virtual Channel named 'drdynvc' not found, " - "channel not initialized"); + LOG(LOG_LEVEL_WARNING, "Dynamic channels will not be available"); } - return 0; + return rv; } /*****************************************************************************/ diff --git a/libxrdp/xrdp_rdp.c b/libxrdp/xrdp_rdp.c index 6be1ff6ead..deefd7a1f1 100644 --- a/libxrdp/xrdp_rdp.c +++ b/libxrdp/xrdp_rdp.c @@ -1323,7 +1323,6 @@ xrdp_rdp_process_data_font(struct xrdp_rdp *self, struct stream *s) self->session->callback(self->session->id, 0x555a, 0, 0, 0, 0); } - xrdp_channel_drdynvc_start(self->sec_layer->chan_layer); } else { diff --git a/xrdp/xrdp_wm.c b/xrdp/xrdp_wm.c index fcf59e5550..33c360e4dc 100644 --- a/xrdp/xrdp_wm.c +++ b/xrdp/xrdp_wm.c @@ -29,6 +29,54 @@ #include "log.h" #include "string_calls.h" +/*****************************************************************************/ +static void +xrdp_wm_load_channel_config(struct xrdp_wm *self) +{ + struct list *names = list_create(); + names->auto_free = 1; + struct list *values = list_create(); + values->auto_free = 1; + + if (file_by_name_read_section(self->session->xrdp_ini, + "Channels", names, values) == 0) + { + int chan_id; + int chan_count = libxrdp_get_channel_count(self->session); + const char *disabled_str = NULL; + + for (chan_id = 0 ; chan_id < chan_count ; ++chan_id) + { + char chan_name[16]; + if (libxrdp_query_channel(self->session, chan_id, chan_name, + NULL) == 0) + { + int disabled = 1; /* Channels disabled if not found */ + int index; + + for (index = 0; index < names->count; index++) + { + const char *q = (const char *)list_get_item(names, index); + const char *r = (const char *)list_get_item(values, index); + if (g_strcasecmp(q, chan_name) == 0) + { + disabled = !g_text2bool(r); + break; + } + } + disabled_str = (disabled) ? "disabled" : "enabled"; + LOG(LOG_LEVEL_DEBUG, "xrdp_wm_load_channel_config: " + "channel %s channel id %d is %s", + chan_name, chan_id, disabled_str); + + libxrdp_disable_channel(self->session, chan_id, disabled); + } + } + } + list_delete(names); + list_delete(values); +} + /*****************************************************************************/ struct xrdp_wm * xrdp_wm_create(struct xrdp_process *owner, @@ -69,6 +117,23 @@ xrdp_wm_create(struct xrdp_process *owner, /* to store configuration from xrdp.ini */ self->xrdp_config = g_new0(struct xrdp_config, 1); + /* Load the channel config so libxrdp can check whether + drdynvc is enabled or not */ + xrdp_wm_load_channel_config(self); + + // Start drdynvc if available. + if (libxrdp_drdynvc_start(self->session) == 0) + { + // drdynvc is started. callback() will + // be notified when capabilities are received. + } + else if (self->client_info->gfx) + { + LOG(LOG_LEVEL_WARNING, "Disabling GFX as '" + DRDYNVC_SVC_CHANNEL_NAME "' isn't available"); + self->client_info->gfx = 0; + } + return self; } @@ -564,9 +629,7 @@ xrdp_wm_init(struct xrdp_wm *self) { int fd; int index; - struct list *names; - struct list *values; - char *q; + const char *q; const char *r; char param[256]; char default_section_name[256]; @@ -590,48 +653,6 @@ xrdp_wm_init(struct xrdp_wm *self) /* Scale the login screen values */ xrdp_login_wnd_scale_config_values(self); - /* global channels allow */ - names = list_create(); - names->auto_free = 1; - values = list_create(); - values->auto_free = 1; - if (file_by_name_read_section(self->session->xrdp_ini, - "Channels", names, values) == 0) - { - int chan_id; - int chan_count = libxrdp_get_channel_count(self->session); - const char *disabled_str = NULL; - - for (chan_id = 0 ; chan_id < chan_count ; ++chan_id) - { - char chan_name[16]; - if (libxrdp_query_channel(self->session, chan_id, chan_name, - NULL) == 0) - { - int disabled = 1; /* Channels disabled if not found */ - - for (index = 0; index < names->count; index++) - { - q = (char *) list_get_item(names, index); - if (g_strcasecmp(q, chan_name) == 0) - { - r = (const char *) list_get_item(values, index); - disabled = !g_text2bool(r); - break; - } - } - disabled_str = (disabled) ? "disabled" : "enabled"; - LOG(LOG_LEVEL_DEBUG, "xrdp_wm_init: " - "channel %s channel id %d is %s", - chan_name, chan_id, disabled_str); - - libxrdp_disable_channel(self->session, chan_id, disabled); - } - } - } - list_delete(names); - list_delete(values); - xrdp_wm_load_static_colors_plus(self, autorun_name); xrdp_wm_load_static_pointers(self); self->screen->bg_color = self->xrdp_config->cfg_globals.ls_top_window_bg_color; @@ -645,9 +666,9 @@ xrdp_wm_init(struct xrdp_wm *self) fd = g_file_open_ro(self->session->xrdp_ini); if (fd != -1) { - names = list_create(); + struct list *names = list_create(); names->auto_free = 1; - values = list_create(); + struct list *values = list_create(); values->auto_free = 1; /* pick up the first section name except for 'globals', 'Logging', 'channels' @@ -656,7 +677,7 @@ xrdp_wm_init(struct xrdp_wm *self) default_section_name[0] = '\0'; for (index = 0; index < names->count; index++) { - q = (char *)list_get_item(names, index); + q = (const char *)list_get_item(names, index); if ((g_strncasecmp("globals", q, 8) != 0) && (g_strncasecmp("Logging", q, 8) != 0) && (g_strncasecmp("LoggingPerLogger", q, 17) != 0) && @@ -714,8 +735,8 @@ xrdp_wm_init(struct xrdp_wm *self) { for (index = 0; index < names->count; index++) { - q = (char *)list_get_item(names, index); - r = (char *)list_get_item(values, index); + q = (const char *)list_get_item(names, index); + r = (const char *)list_get_item(values, index); if (g_strncasecmp("password", q, 255) == 0) {