diff --git a/src/protocols/rdp/guac_handlers.c b/src/protocols/rdp/guac_handlers.c index 11268150..40813fe5 100644 --- a/src/protocols/rdp/guac_handlers.c +++ b/src/protocols/rdp/guac_handlers.c @@ -643,11 +643,8 @@ int rdp_guac_client_blob_handler(guac_client* client, guac_stream* stream, } /* end if upload stream */ /* Handle received SVC data */ - else if (rdp_stream->type == GUAC_RDP_INBOUND_SVC_STREAM) { - guac_client_log_info(client, - "STUB: Received %i bytes on pipe for channel \"%s\".", - length, rdp_stream->svc->name); - } + else if (rdp_stream->type == GUAC_RDP_INBOUND_SVC_STREAM) + guac_rdp_svc_write(rdp_stream->svc, data, length); guac_protocol_send_ack(client->socket, stream, "OK (DATA RECEIVED)", GUAC_PROTOCOL_STATUS_SUCCESS); diff --git a/src/protocols/rdp/guac_svc/svc_service.c b/src/protocols/rdp/guac_svc/svc_service.c index fef6f9c5..2d7faffc 100644 --- a/src/protocols/rdp/guac_svc/svc_service.c +++ b/src/protocols/rdp/guac_svc/svc_service.c @@ -74,6 +74,9 @@ int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) { svc_plugin->plugin.event_callback = guac_svc_process_event; svc_plugin->plugin.terminate_callback = guac_svc_process_terminate; + /* Store plugin reference in SVC */ + svc->plugin = (rdpSvcPlugin*) svc_plugin; + /* Finish init */ svc_plugin_init((rdpSvcPlugin*) svc_plugin, pEntryPoints); return 1; diff --git a/src/protocols/rdp/rdp_svc.c b/src/protocols/rdp/rdp_svc.c index 53b30989..39e4375a 100644 --- a/src/protocols/rdp/rdp_svc.c +++ b/src/protocols/rdp/rdp_svc.c @@ -26,6 +26,7 @@ #include "rdp_svc.h" #include +#include #include #ifdef ENABLE_WINPR @@ -41,6 +42,7 @@ guac_rdp_svc* guac_rdp_alloc_svc(guac_client* client, char* name) { /* Init SVC */ svc->client = client; svc->name = strdup(name); + svc->plugin = NULL; svc->input_pipe = NULL; svc->output_pipe = NULL; @@ -119,3 +121,24 @@ guac_rdp_svc* guac_rdp_remove_svc(guac_client* client, const char* name) { } +void guac_rdp_svc_write(guac_rdp_svc* svc, void* data, int length) { + + wStream* output_stream; + + /* Do not write of plugin not associated */ + if (svc->plugin == NULL) { + guac_client_log_error(svc->client, + "Channel \"%s\" output dropped.", + svc->name); + return; + } + + /* Build packet */ + output_stream = Stream_New(NULL, length); + Stream_Write(output_stream, data, length); + + /* Send packet */ + svc_plugin_send(svc->plugin, output_stream); + +} + diff --git a/src/protocols/rdp/rdp_svc.h b/src/protocols/rdp/rdp_svc.h index 7f8b5fbc..f3b1f6fb 100644 --- a/src/protocols/rdp/rdp_svc.h +++ b/src/protocols/rdp/rdp_svc.h @@ -26,6 +26,7 @@ #include "config.h" #include +#include #include #ifdef ENABLE_WINPR @@ -45,6 +46,11 @@ typedef struct guac_rdp_svc { */ guac_client* client; + /** + * Reference to associated SVC plugin. + */ + rdpSvcPlugin* plugin; + /** * The name of the RDP channel in use, and the name to use for each pipe. */ @@ -89,5 +95,10 @@ guac_rdp_svc* guac_rdp_get_svc(guac_client* client, const char* name); */ guac_rdp_svc* guac_rdp_remove_svc(guac_client* client, const char* name); +/** + * Write the given blob of data to the virtual channel. + */ +void guac_rdp_svc_write(guac_rdp_svc* svc, void* data, int length); + #endif