GUACAMOLE-1388: Merge ensure RDP-specific resources are cleaned up after channel disconnect.
This commit is contained in:
commit
12b8eac514
@ -546,6 +546,48 @@ static void guac_rdp_cliprdr_channel_connected(rdpContext* context,
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback which disassociates Guacamole from the CliprdrClientContext
|
||||
* instance that was originally allocated by FreeRDP and is about to be
|
||||
* deallocated.
|
||||
*
|
||||
* This function is called whenever a channel disconnects via the PubSub event
|
||||
* system within FreeRDP, but only has any effect if the disconnected channel
|
||||
* is the CLIPRDR channel. This specific callback is registered with the PubSub
|
||||
* system of the relevant rdpContext when guac_rdp_clipboard_load_plugin() is
|
||||
* called.
|
||||
*
|
||||
* @param context
|
||||
* The rdpContext associated with the active RDP session.
|
||||
*
|
||||
* @param e
|
||||
* Event-specific arguments, mainly the name of the channel, and a
|
||||
* reference to the associated plugin loaded for that channel by FreeRDP.
|
||||
*/
|
||||
static void guac_rdp_cliprdr_channel_disconnected(rdpContext* context,
|
||||
ChannelDisconnectedEventArgs* e) {
|
||||
|
||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||
guac_rdp_clipboard* clipboard = rdp_client->clipboard;
|
||||
|
||||
/* FreeRDP-specific handlers for CLIPRDR are not assigned, and thus not
|
||||
* callable, until after the relevant guac_rdp_clipboard structure is
|
||||
* allocated and associated with the guac_rdp_client */
|
||||
assert(clipboard != NULL);
|
||||
|
||||
/* Ignore disconnection event if it's not for the CLIPRDR channel */
|
||||
if (strcmp(e->name, CLIPRDR_SVC_CHANNEL_NAME) != 0)
|
||||
return;
|
||||
|
||||
/* Channel is no longer connected */
|
||||
clipboard->cliprdr = NULL;
|
||||
|
||||
guac_client_log(client, GUAC_LOG_DEBUG, "CLIPRDR (clipboard redirection) "
|
||||
"channel disconnected.");
|
||||
|
||||
}
|
||||
|
||||
guac_rdp_clipboard* guac_rdp_clipboard_alloc(guac_client* client) {
|
||||
|
||||
/* Allocate clipboard and underlying storage */
|
||||
@ -575,6 +617,10 @@ void guac_rdp_clipboard_load_plugin(guac_rdp_clipboard* clipboard,
|
||||
PubSub_SubscribeChannelConnected(context->pubSub,
|
||||
(pChannelConnectedEventHandler) guac_rdp_cliprdr_channel_connected);
|
||||
|
||||
/* Clean up any RDP-specific resources when channel is disconnected */
|
||||
PubSub_SubscribeChannelDisconnected(context->pubSub,
|
||||
(pChannelDisconnectedEventHandler) guac_rdp_cliprdr_channel_disconnected);
|
||||
|
||||
guac_client_log(clipboard->client, GUAC_LOG_DEBUG, "Support for CLIPRDR "
|
||||
"(clipboard redirection) registered. Awaiting channel "
|
||||
"connection.");
|
||||
|
@ -96,12 +96,52 @@ static void guac_rdp_disp_channel_connected(rdpContext* context,
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback which disassociates Guacamole from the DispClientContext instance
|
||||
* that was originally allocated by FreeRDP and is about to be deallocated.
|
||||
*
|
||||
* This function is called whenever a channel disconnects via the PubSub event
|
||||
* system within FreeRDP, but only has any effect if the disconnected channel
|
||||
* is the Display Update channel. This specific callback is registered with the
|
||||
* PubSub system of the relevant rdpContext when guac_rdp_disp_load_plugin() is
|
||||
* called.
|
||||
*
|
||||
* @param context
|
||||
* The rdpContext associated with the active RDP session.
|
||||
*
|
||||
* @param e
|
||||
* Event-specific arguments, mainly the name of the channel, and a
|
||||
* reference to the associated plugin loaded for that channel by FreeRDP.
|
||||
*/
|
||||
static void guac_rdp_disp_channel_disconnected(rdpContext* context,
|
||||
ChannelDisconnectedEventArgs* e) {
|
||||
|
||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||
guac_rdp_disp* guac_disp = rdp_client->disp;
|
||||
|
||||
/* Ignore disconnection event if it's not for the Display Update channel */
|
||||
if (strcmp(e->name, DISP_DVC_CHANNEL_NAME) != 0)
|
||||
return;
|
||||
|
||||
/* Channel is no longer connected */
|
||||
guac_disp->disp = NULL;
|
||||
|
||||
guac_client_log(client, GUAC_LOG_DEBUG, "Display update channel "
|
||||
"disconnected.");
|
||||
|
||||
}
|
||||
|
||||
void guac_rdp_disp_load_plugin(rdpContext* context) {
|
||||
|
||||
/* Subscribe to and handle channel connected events */
|
||||
PubSub_SubscribeChannelConnected(context->pubSub,
|
||||
(pChannelConnectedEventHandler) guac_rdp_disp_channel_connected);
|
||||
|
||||
/* Subscribe to and handle channel disconnected events */
|
||||
PubSub_SubscribeChannelDisconnected(context->pubSub,
|
||||
(pChannelDisconnectedEventHandler) guac_rdp_disp_channel_disconnected);
|
||||
|
||||
/* Add "disp" channel */
|
||||
guac_freerdp_dynamic_channel_collection_add(context->settings, "disp", NULL);
|
||||
|
||||
|
@ -94,12 +94,51 @@ static void guac_rdp_rdpei_channel_connected(rdpContext* context,
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback which disassociates Guacamole from the RdpeiClientContext instance
|
||||
* that was originally allocated by FreeRDP and is about to be deallocated.
|
||||
*
|
||||
* This function is called whenever a channel disconnects via the PubSub event
|
||||
* system within FreeRDP, but only has any effect if the disconnected channel
|
||||
* is the RDPEI channel. This specific callback is registered with the PubSub
|
||||
* system of the relevant rdpContext when guac_rdp_rdpei_load_plugin() is
|
||||
* called.
|
||||
*
|
||||
* @param context
|
||||
* The rdpContext associated with the active RDP session.
|
||||
*
|
||||
* @param e
|
||||
* Event-specific arguments, mainly the name of the channel, and a
|
||||
* reference to the associated plugin loaded for that channel by FreeRDP.
|
||||
*/
|
||||
static void guac_rdp_rdpei_channel_disconnected(rdpContext* context,
|
||||
ChannelDisconnectedEventArgs* e) {
|
||||
|
||||
guac_client* client = ((rdp_freerdp_context*) context)->client;
|
||||
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||
guac_rdp_rdpei* guac_rdpei = rdp_client->rdpei;
|
||||
|
||||
/* Ignore disconnection event if it's not for the RDPEI channel */
|
||||
if (strcmp(e->name, RDPEI_DVC_CHANNEL_NAME) != 0)
|
||||
return;
|
||||
|
||||
/* Channel is no longer connected */
|
||||
guac_rdpei->rdpei = NULL;
|
||||
|
||||
guac_client_log(client, GUAC_LOG_DEBUG, "RDPDI channel disconnected.");
|
||||
|
||||
}
|
||||
|
||||
void guac_rdp_rdpei_load_plugin(rdpContext* context) {
|
||||
|
||||
/* Subscribe to and handle channel connected events */
|
||||
PubSub_SubscribeChannelConnected(context->pubSub,
|
||||
(pChannelConnectedEventHandler) guac_rdp_rdpei_channel_connected);
|
||||
|
||||
/* Subscribe to and handle channel disconnected events */
|
||||
PubSub_SubscribeChannelDisconnected(context->pubSub,
|
||||
(pChannelDisconnectedEventHandler) guac_rdp_rdpei_channel_disconnected);
|
||||
|
||||
/* Add "rdpei" channel */
|
||||
guac_freerdp_dynamic_channel_collection_add(context->settings, "rdpei", NULL);
|
||||
|
||||
|
@ -471,18 +471,6 @@ static int guac_rdp_handle_connection(guac_client* client) {
|
||||
|
||||
pthread_rwlock_wrlock(&(rdp_client->lock));
|
||||
|
||||
/* Set up screen recording, if requested */
|
||||
if (settings->recording_path != NULL) {
|
||||
rdp_client->recording = guac_common_recording_create(client,
|
||||
settings->recording_path,
|
||||
settings->recording_name,
|
||||
settings->create_recording_path,
|
||||
!settings->recording_exclude_output,
|
||||
!settings->recording_exclude_mouse,
|
||||
!settings->recording_exclude_touch,
|
||||
settings->recording_include_keys);
|
||||
}
|
||||
|
||||
/* Create display */
|
||||
rdp_client->display = guac_common_display_alloc(client,
|
||||
rdp_client->settings->width,
|
||||
@ -816,6 +804,18 @@ void* guac_rdp_client_thread(void* data) {
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Set up screen recording, if requested */
|
||||
if (settings->recording_path != NULL) {
|
||||
rdp_client->recording = guac_common_recording_create(client,
|
||||
settings->recording_path,
|
||||
settings->recording_name,
|
||||
settings->create_recording_path,
|
||||
!settings->recording_exclude_output,
|
||||
!settings->recording_exclude_mouse,
|
||||
!settings->recording_exclude_touch,
|
||||
settings->recording_include_keys);
|
||||
}
|
||||
|
||||
/* Continue handling connections until error or client disconnect */
|
||||
while (client->state == GUAC_CLIENT_RUNNING) {
|
||||
if (guac_rdp_handle_connection(client))
|
||||
|
Loading…
Reference in New Issue
Block a user