diff --git a/src/protocols/rdp/Makefile.am b/src/protocols/rdp/Makefile.am index 97f36535..aacfda6a 100644 --- a/src/protocols/rdp/Makefile.am +++ b/src/protocols/rdp/Makefile.am @@ -132,9 +132,9 @@ libguac_client_rdp_la_LIBADD = \ freerdp_LTLIBRARIES = \ libguacai-client.la \ + libguacdr-client.la \ libguacsnd-client.la \ libguacsvc-client.la -# libguacdr-client.la freerdpdir = ${libdir}/freerdp2 @@ -142,35 +142,35 @@ freerdpdir = ${libdir}/freerdp2 # RDPDR # -#libguacdr_client_la_SOURCES = \ -# guac_rdpdr/rdpdr_fs_messages.c \ -# guac_rdpdr/rdpdr_fs_messages_dir_info.c \ -# guac_rdpdr/rdpdr_fs_messages_file_info.c \ -# guac_rdpdr/rdpdr_fs_messages_vol_info.c \ -# guac_rdpdr/rdpdr_fs_service.c \ -# guac_rdpdr/rdpdr_messages.c \ -# guac_rdpdr/rdpdr_printer.c \ -# guac_rdpdr/rdpdr_service.c \ -# rdp_fs.c \ -# rdp_print_job.c \ -# rdp_stream.c \ -# unicode.c -# -#libguacdr_client_la_CFLAGS = \ -# -Werror -Wall -Iinclude \ -# @COMMON_INCLUDE@ \ -# @COMMON_SSH_INCLUDE@ \ -# @LIBGUAC_INCLUDE@ \ -# @RDP_CFLAGS@ -# -#libguacdr_client_la_LDFLAGS = \ -# -module -avoid-version -shared \ -# @PTHREAD_LIBS@ \ -# @RDP_LIBS@ -# -#libguacdr_client_la_LIBADD = \ -# @COMMON_LTLIB@ \ -# @LIBGUAC_LTLIB@ +libguacdr_client_la_SOURCES = \ + guac_rdpdr/rdpdr_fs_messages.c \ + guac_rdpdr/rdpdr_fs_messages_dir_info.c \ + guac_rdpdr/rdpdr_fs_messages_file_info.c \ + guac_rdpdr/rdpdr_fs_messages_vol_info.c \ + guac_rdpdr/rdpdr_fs_service.c \ + guac_rdpdr/rdpdr_messages.c \ + guac_rdpdr/rdpdr_printer.c \ + guac_rdpdr/rdpdr_service.c \ + rdp_fs.c \ + rdp_print_job.c \ + rdp_stream.c \ + unicode.c + +libguacdr_client_la_CFLAGS = \ + -Werror -Wall -Iinclude \ + @COMMON_INCLUDE@ \ + @COMMON_SSH_INCLUDE@ \ + @LIBGUAC_INCLUDE@ \ + @RDP_CFLAGS@ + +libguacdr_client_la_LDFLAGS = \ + -module -avoid-version -shared \ + @PTHREAD_LIBS@ \ + @RDP_LIBS@ + +libguacdr_client_la_LIBADD = \ + @COMMON_LTLIB@ \ + @LIBGUAC_LTLIB@ # # Audio Input diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c index bad3f46e..1336e6f9 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c @@ -29,7 +29,6 @@ #include "rdp_status.h" #include "unicode.h" -#include #include #include #include @@ -110,7 +109,9 @@ void guac_rdpdr_fs_process_create(guac_rdpdr_device* device, } - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -158,7 +159,9 @@ void guac_rdpdr_fs_process_read(guac_rdpdr_device* device, Stream_Write(output_stream, buffer, bytes_read); /* ReadData */ } - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); free(buffer); } @@ -201,7 +204,9 @@ void guac_rdpdr_fs_process_write(guac_rdpdr_device* device, Stream_Write_UINT8(output_stream, 0); /* Padding */ } - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -234,7 +239,9 @@ void guac_rdpdr_fs_process_close(guac_rdpdr_device* device, STATUS_SUCCESS, 4); Stream_Write(output_stream, "\0\0\0\0", 4); /* Padding */ - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -322,7 +329,9 @@ void guac_rdpdr_fs_process_set_volume_info(guac_rdpdr_device* device, "%s: [file_id=%i] Set volume info not supported", __func__, file_id); - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -385,7 +394,9 @@ void guac_rdpdr_fs_process_device_control(guac_rdpdr_device* device, /* No content for now */ Stream_Write_UINT32(output_stream, 0); - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -501,7 +512,9 @@ void guac_rdpdr_fs_process_query_directory(guac_rdpdr_device* device, wStream* i Stream_Write_UINT32(output_stream, 0); /* Length */ Stream_Write_UINT8(output_stream, 0); /* Padding */ - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -517,7 +530,9 @@ void guac_rdpdr_fs_process_lock_control(guac_rdpdr_device* device, wStream* inpu Stream_Zero(output_stream, 5); /* Padding */ - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_dir_info.c b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_dir_info.c index 3ab31e5f..303e7af7 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_dir_info.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_dir_info.c @@ -24,7 +24,6 @@ #include "rdp_status.h" #include "unicode.h" -#include #include #include @@ -72,7 +71,9 @@ void guac_rdpdr_fs_process_query_directory_info(guac_rdpdr_device* device, Stream_Write(output_stream, utf16_entry_name, utf16_length); /* FileName */ Stream_Write(output_stream, "\0\0", 2); - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -119,7 +120,9 @@ void guac_rdpdr_fs_process_query_full_directory_info(guac_rdpdr_device* device, Stream_Write(output_stream, utf16_entry_name, utf16_length); /* FileName */ Stream_Write(output_stream, "\0\0", 2); - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -170,7 +173,9 @@ void guac_rdpdr_fs_process_query_both_directory_info(guac_rdpdr_device* device, Stream_Write(output_stream, utf16_entry_name, utf16_length); /* FileName */ Stream_Write(output_stream, "\0\0", 2); - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -208,7 +213,9 @@ void guac_rdpdr_fs_process_query_names_info(guac_rdpdr_device* device, Stream_Write(output_stream, utf16_entry_name, utf16_length); /* FileName */ Stream_Write(output_stream, "\0\0", 2); - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c index e65ef9c1..c69046cb 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c @@ -24,7 +24,6 @@ #include "rdp_status.h" #include "unicode.h" -#include #include #include @@ -59,7 +58,9 @@ void guac_rdpdr_fs_process_query_basic_info(guac_rdpdr_device* device, wStream* /* Reserved field must not be sent */ - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -94,7 +95,9 @@ void guac_rdpdr_fs_process_query_standard_info(guac_rdpdr_device* device, wStrea /* Reserved field must not be sent */ - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -122,7 +125,9 @@ void guac_rdpdr_fs_process_query_attribute_tag_info(guac_rdpdr_device* device, /* Reserved field must not be sent */ - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -179,7 +184,9 @@ void guac_rdpdr_fs_process_set_rename_info(guac_rdpdr_device* device, } Stream_Write_UINT32(output_stream, length); - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -207,7 +214,9 @@ void guac_rdpdr_fs_process_set_allocation_info(guac_rdpdr_device* device, completion_id, STATUS_SUCCESS, 4); Stream_Write_UINT32(output_stream, length); - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -231,7 +240,9 @@ void guac_rdpdr_fs_process_set_disposition_info(guac_rdpdr_device* device, Stream_Write_UINT32(output_stream, length); - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -259,7 +270,9 @@ void guac_rdpdr_fs_process_set_end_of_file_info(guac_rdpdr_device* device, completion_id, STATUS_SUCCESS, 4); Stream_Write_UINT32(output_stream, length); - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -276,7 +289,9 @@ void guac_rdpdr_fs_process_set_basic_info(guac_rdpdr_device* device, "%s: [file_id=%i] IGNORED", __func__, file_id); - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_vol_info.c b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_vol_info.c index 27defb0e..1cc051f0 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_vol_info.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_vol_info.c @@ -24,7 +24,6 @@ #include "rdp_fs.h" #include "rdp_status.h" -#include #include #include #include @@ -47,7 +46,9 @@ void guac_rdpdr_fs_process_query_volume_info(guac_rdpdr_device* device, /* Reserved field must not be sent */ Stream_Write(output_stream, GUAC_FILESYSTEM_LABEL, GUAC_FILESYSTEM_LABEL_LENGTH); - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -70,7 +71,9 @@ void guac_rdpdr_fs_process_query_size_info(guac_rdpdr_device* device, wStream* i Stream_Write_UINT32(output_stream, 1); /* SectorsPerAllocationUnit */ Stream_Write_UINT32(output_stream, info.block_size); /* BytesPerSector */ - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -88,7 +91,9 @@ void guac_rdpdr_fs_process_query_device_info(guac_rdpdr_device* device, wStream* Stream_Write_UINT32(output_stream, FILE_DEVICE_DISK); /* DeviceType */ Stream_Write_UINT32(output_stream, 0); /* Characteristics */ - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -113,7 +118,9 @@ void guac_rdpdr_fs_process_query_attribute_info(guac_rdpdr_device* device, wStre Stream_Write_UINT32(output_stream, name_len); Stream_Write(output_stream, device->device_name, name_len); - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -137,7 +144,9 @@ void guac_rdpdr_fs_process_query_full_size_info(guac_rdpdr_device* device, wStre Stream_Write_UINT32(output_stream, 1); /* SectorsPerAllocationUnit */ Stream_Write_UINT32(output_stream, info.block_size); /* BytesPerSector */ - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.c b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.c index 63425ba6..187bf9c4 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.c @@ -25,7 +25,6 @@ #include "rdpdr_messages.h" #include "rdpdr_service.h" -#include #include #include #include @@ -114,7 +113,7 @@ static void guac_rdpdr_device_fs_free_handler(guac_rdpdr_device* device) { } -void guac_rdpdr_register_fs(guac_rdpdrPlugin* rdpdr, char* drive_name) { +void guac_rdpdr_register_fs(guac_rdpdr* rdpdr, char* drive_name) { guac_client* client = rdpdr->client; guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.h b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.h index f990806b..af44ac8b 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.h +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.h @@ -48,7 +48,7 @@ * @param drive_name * The name of the redirected drive to display in the RDP connection. */ -void guac_rdpdr_register_fs(guac_rdpdrPlugin* rdpdr, char* drive_name); +void guac_rdpdr_register_fs(guac_rdpdr* rdpdr, char* drive_name); #endif diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_messages.c b/src/protocols/rdp/guac_rdpdr/rdpdr_messages.c index 507b4d7c..d300ccaf 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_messages.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_messages.c @@ -24,7 +24,6 @@ #include "rdpdr_service.h" #include "unicode.h" -#include #include #include #include @@ -32,7 +31,7 @@ #include #include -static void guac_rdpdr_send_client_announce_reply(guac_rdpdrPlugin* rdpdr, +static void guac_rdpdr_send_client_announce_reply(guac_rdpdr* rdpdr, unsigned int major, unsigned int minor, unsigned int client_id) { wStream* output_stream = Stream_New(NULL, 12); @@ -46,11 +45,13 @@ static void guac_rdpdr_send_client_announce_reply(guac_rdpdrPlugin* rdpdr, Stream_Write_UINT16(output_stream, minor); Stream_Write_UINT32(output_stream, client_id); - svc_plugin_send((rdpSvcPlugin*) rdpdr, output_stream); + rdpdr->entry_points.pVirtualChannelWriteEx(rdpdr->init_handle, + rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } -static void guac_rdpdr_send_client_name_request(guac_rdpdrPlugin* rdpdr, const char* name) { +static void guac_rdpdr_send_client_name_request(guac_rdpdr* rdpdr, const char* name) { int name_bytes = strlen(name) + 1; wStream* output_stream = Stream_New(NULL, 16 + name_bytes); @@ -65,11 +66,13 @@ static void guac_rdpdr_send_client_name_request(guac_rdpdrPlugin* rdpdr, const c Stream_Write_UINT32(output_stream, name_bytes); Stream_Write(output_stream, name, name_bytes); - svc_plugin_send((rdpSvcPlugin*) rdpdr, output_stream); + rdpdr->entry_points.pVirtualChannelWriteEx(rdpdr->init_handle, + rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } -static void guac_rdpdr_send_client_capability(guac_rdpdrPlugin* rdpdr) { +static void guac_rdpdr_send_client_capability(guac_rdpdr* rdpdr) { wStream* output_stream = Stream_New(NULL, 256); guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Sending capabilities..."); @@ -112,12 +115,14 @@ static void guac_rdpdr_send_client_capability(guac_rdpdrPlugin* rdpdr) { Stream_Write_UINT16(output_stream, 8); Stream_Write_UINT32(output_stream, DRIVE_CAPABILITY_VERSION_02); - svc_plugin_send((rdpSvcPlugin*) rdpdr, output_stream); + rdpdr->entry_points.pVirtualChannelWriteEx(rdpdr->init_handle, + rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Capabilities sent."); } -static void guac_rdpdr_send_client_device_list_announce_request(guac_rdpdrPlugin* rdpdr) { +static void guac_rdpdr_send_client_device_list_announce_request(guac_rdpdr* rdpdr) { /* Calculate number of bytes needed for the stream */ int streamBytes = 16; @@ -144,12 +149,14 @@ static void guac_rdpdr_send_client_device_list_announce_request(guac_rdpdrPlugin } - svc_plugin_send((rdpSvcPlugin*) rdpdr, output_stream); + rdpdr->entry_points.pVirtualChannelWriteEx(rdpdr->init_handle, + rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); guac_client_log(rdpdr->client, GUAC_LOG_INFO, "All supported devices sent."); } -void guac_rdpdr_process_server_announce(guac_rdpdrPlugin* rdpdr, +void guac_rdpdr_process_server_announce(guac_rdpdr* rdpdr, wStream* input_stream) { unsigned int major, minor, client_id; @@ -172,11 +179,11 @@ void guac_rdpdr_process_server_announce(guac_rdpdrPlugin* rdpdr, } -void guac_rdpdr_process_clientid_confirm(guac_rdpdrPlugin* rdpdr, wStream* input_stream) { +void guac_rdpdr_process_clientid_confirm(guac_rdpdr* rdpdr, wStream* input_stream) { guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Client ID confirmed"); } -void guac_rdpdr_process_device_reply(guac_rdpdrPlugin* rdpdr, wStream* input_stream) { +void guac_rdpdr_process_device_reply(guac_rdpdr* rdpdr, wStream* input_stream) { unsigned int device_id, ntstatus; int severity, c, n, facility, code; @@ -210,7 +217,7 @@ void guac_rdpdr_process_device_reply(guac_rdpdrPlugin* rdpdr, wStream* input_str } -void guac_rdpdr_process_device_iorequest(guac_rdpdrPlugin* rdpdr, wStream* input_stream) { +void guac_rdpdr_process_device_iorequest(guac_rdpdr* rdpdr, wStream* input_stream) { int device_id, file_id, completion_id, major_func, minor_func; @@ -236,7 +243,7 @@ void guac_rdpdr_process_device_iorequest(guac_rdpdrPlugin* rdpdr, wStream* input } -void guac_rdpdr_process_server_capability(guac_rdpdrPlugin* rdpdr, wStream* input_stream) { +void guac_rdpdr_process_server_capability(guac_rdpdr* rdpdr, wStream* input_stream) { int count; int i; @@ -265,17 +272,17 @@ void guac_rdpdr_process_server_capability(guac_rdpdrPlugin* rdpdr, wStream* inpu } -void guac_rdpdr_process_user_loggedon(guac_rdpdrPlugin* rdpdr, wStream* input_stream) { +void guac_rdpdr_process_user_loggedon(guac_rdpdr* rdpdr, wStream* input_stream) { guac_client_log(rdpdr->client, GUAC_LOG_INFO, "User logged on"); guac_rdpdr_send_client_device_list_announce_request(rdpdr); } -void guac_rdpdr_process_prn_cache_data(guac_rdpdrPlugin* rdpdr, wStream* input_stream) { +void guac_rdpdr_process_prn_cache_data(guac_rdpdr* rdpdr, wStream* input_stream) { guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Ignoring printer cached configuration data"); } -void guac_rdpdr_process_prn_using_xps(guac_rdpdrPlugin* rdpdr, wStream* input_stream) { +void guac_rdpdr_process_prn_using_xps(guac_rdpdr* rdpdr, wStream* input_stream) { guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Printer unexpectedly switched to XPS mode"); } diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_messages.h b/src/protocols/rdp/guac_rdpdr/rdpdr_messages.h index b719ab0c..451554e4 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_messages.h +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_messages.h @@ -204,14 +204,14 @@ * Message handlers. */ -void guac_rdpdr_process_server_announce(guac_rdpdrPlugin* rdpdr, wStream* input_stream); -void guac_rdpdr_process_clientid_confirm(guac_rdpdrPlugin* rdpdr, wStream* input_stream); -void guac_rdpdr_process_device_reply(guac_rdpdrPlugin* rdpdr, wStream* input_stream); -void guac_rdpdr_process_device_iorequest(guac_rdpdrPlugin* rdpdr, wStream* input_stream); -void guac_rdpdr_process_server_capability(guac_rdpdrPlugin* rdpdr, wStream* input_stream); -void guac_rdpdr_process_user_loggedon(guac_rdpdrPlugin* rdpdr, wStream* input_stream); -void guac_rdpdr_process_prn_cache_data(guac_rdpdrPlugin* rdpdr, wStream* input_stream); -void guac_rdpdr_process_prn_using_xps(guac_rdpdrPlugin* rdpdr, wStream* input_stream); +void guac_rdpdr_process_server_announce(guac_rdpdr* rdpdr, wStream* input_stream); +void guac_rdpdr_process_clientid_confirm(guac_rdpdr* rdpdr, wStream* input_stream); +void guac_rdpdr_process_device_reply(guac_rdpdr* rdpdr, wStream* input_stream); +void guac_rdpdr_process_device_iorequest(guac_rdpdr* rdpdr, wStream* input_stream); +void guac_rdpdr_process_server_capability(guac_rdpdr* rdpdr, wStream* input_stream); +void guac_rdpdr_process_user_loggedon(guac_rdpdr* rdpdr, wStream* input_stream); +void guac_rdpdr_process_prn_cache_data(guac_rdpdr* rdpdr, wStream* input_stream); +void guac_rdpdr_process_prn_using_xps(guac_rdpdr* rdpdr, wStream* input_stream); #endif diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_printer.c b/src/protocols/rdp/guac_rdpdr/rdpdr_printer.c index e8c2a5da..98a3eccb 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_printer.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_printer.c @@ -27,7 +27,6 @@ #include "rdp_status.h" #include "unicode.h" -#include #include #include #include @@ -61,7 +60,9 @@ void guac_rdpdr_process_print_job_create(guac_rdpdr_device* device, completion_id, STATUS_SUCCESS, 4); Stream_Write_UINT32(output_stream, 0); /* fileId */ - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -100,7 +101,9 @@ void guac_rdpdr_process_print_job_write(guac_rdpdr_device* device, Stream_Write_UINT32(output_stream, length); Stream_Write_UINT8(output_stream, 0); /* Padding */ - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); } @@ -121,7 +124,9 @@ void guac_rdpdr_process_print_job_close(guac_rdpdr_device* device, completion_id, STATUS_SUCCESS, 4); Stream_Write_UINT32(output_stream, 0); /* Padding */ - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, + device->rdpdr->open_handle, Stream_Buffer(output_stream), + Stream_GetPosition(output_stream), output_stream); /* Log end of print job */ guac_client_log(client, GUAC_LOG_INFO, "Print job closed"); @@ -164,7 +169,7 @@ static void guac_rdpdr_device_printer_free_handler(guac_rdpdr_device* device) { } -void guac_rdpdr_register_printer(guac_rdpdrPlugin* rdpdr, char* printer_name) { +void guac_rdpdr_register_printer(guac_rdpdr* rdpdr, char* printer_name) { int id = rdpdr->devices_registered++; diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_printer.h b/src/protocols/rdp/guac_rdpdr/rdpdr_printer.h index c6abcde5..210d512c 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_printer.h +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_printer.h @@ -38,7 +38,7 @@ * The name of the printer that will be registered with the RDP * connection and passed through to the server. */ -void guac_rdpdr_register_printer(guac_rdpdrPlugin* rdpdr, char* printer_name); +void guac_rdpdr_register_printer(guac_rdpdr* rdpdr, char* printer_name); #endif diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_service.c b/src/protocols/rdp/guac_rdpdr/rdpdr_service.c index 40a1e51e..d20f7d83 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_service.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_service.c @@ -32,7 +32,6 @@ #include #include -#include #include #include #include @@ -40,92 +39,19 @@ #include /** - * Entry point for RDPDR virtual channel. + * Processes data received along the RDPDR channel via a + * CHANNEL_EVENT_DATA_RECEIVED event, forwarding the data along an established, + * outbound pipe stream to the Guacamole client. + * + * @param rdpdr + * The guac_rdpdr structure representing the RDPDR channel. + * + * @param input_stream + * The data that was received. */ -int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) { - - /* Allocate plugin */ - guac_rdpdrPlugin* rdpdr = - (guac_rdpdrPlugin*) calloc(1, sizeof(guac_rdpdrPlugin)); - - /* Init channel def */ - strcpy(rdpdr->plugin.channel_def.name, "rdpdr"); - rdpdr->plugin.channel_def.options = - CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP | CHANNEL_OPTION_COMPRESS_RDP; - - /* Set callbacks */ - rdpdr->plugin.connect_callback = guac_rdpdr_process_connect; - rdpdr->plugin.receive_callback = guac_rdpdr_process_receive; - rdpdr->plugin.event_callback = guac_rdpdr_process_event; - rdpdr->plugin.terminate_callback = guac_rdpdr_process_terminate; - - /* Finish init */ - svc_plugin_init((rdpSvcPlugin*) rdpdr, pEntryPoints); - return 1; - -} - -/* - * Service Handlers - */ - -void guac_rdpdr_process_connect(rdpSvcPlugin* plugin) { - - /* Get RDPDR plugin */ - guac_rdpdrPlugin* rdpdr = (guac_rdpdrPlugin*) plugin; - - /* Get client from plugin parameters */ - guac_client* client = (guac_client*) - plugin->channel_entry_points.pExtendedData; - - /* NULL out pExtendedData so we don't lose our guac_client due to an - * automatic free() within libfreerdp */ - plugin->channel_entry_points.pExtendedData = NULL; - - /* Get data from client */ - guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; - - /* Init plugin */ - rdpdr->client = client; - rdpdr->devices_registered = 0; - - /* Register printer if enabled */ - if (rdp_client->settings->printing_enabled) - guac_rdpdr_register_printer(rdpdr, rdp_client->settings->printer_name); - - /* Register drive if enabled */ - if (rdp_client->settings->drive_enabled) - guac_rdpdr_register_fs(rdpdr, rdp_client->settings->drive_name); - - /* Log that printing, etc. has been loaded */ - guac_client_log(client, GUAC_LOG_INFO, "guacdr connected."); - -} - -void guac_rdpdr_process_terminate(rdpSvcPlugin* plugin) { - - guac_rdpdrPlugin* rdpdr = (guac_rdpdrPlugin*) plugin; - int i; - - for (i=0; idevices_registered; i++) { - guac_rdpdr_device* device = &(rdpdr->devices[i]); - guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Unloading device %i (%s)", - device->device_id, device->device_name); - device->free_handler(device); - } - - free(plugin); -} - -void guac_rdpdr_process_event(rdpSvcPlugin* plugin, wMessage* event) { - freerdp_event_free(event); -} - -void guac_rdpdr_process_receive(rdpSvcPlugin* plugin, +static void guac_rdpdr_process_receive(guac_rdpdr* rdpdr, wStream* input_stream) { - guac_rdpdrPlugin* rdpdr = (guac_rdpdrPlugin*) plugin; - int component; int packet_id; @@ -306,3 +232,269 @@ void guac_rdpdr_start_download(guac_rdpdr_device* device, char* path) { } +/** + * Event handler for events which deal with data transmitted over the RDPDR + * channel. This specific implementation of the event handler currently + * handles only the CHANNEL_EVENT_DATA_RECEIVED event, delegating actual + * handling of that event to guac_rdpdr_process_receive(). + * + * The FreeRDP requirements for this function follow those of the + * VirtualChannelOpenEventEx callback defined within Microsoft's RDP API: + * + * https://docs.microsoft.com/en-us/previous-versions/windows/embedded/aa514754%28v%3dmsdn.10%29 + * + * @param user_param + * The pointer to arbitrary data originally passed via the first parameter + * of the pVirtualChannelInitEx() function call when the associated channel + * was initialized. The pVirtualChannelInitEx() function is exposed within + * the channel entry points structure. + * + * @param open_handle + * The handle which identifies the channel itself, typically referred to + * within the FreeRDP source as OpenHandle. + * + * @param event + * An integer representing the event that should be handled. This will be + * either CHANNEL_EVENT_DATA_RECEIVED, CHANNEL_EVENT_WRITE_CANCELLED, or + * CHANNEL_EVENT_WRITE_COMPLETE. + * + * @param data + * The data received, for CHANNEL_EVENT_DATA_RECEIVED events, and the value + * passed as user data to pVirtualChannelWriteEx() for + * CHANNEL_EVENT_WRITE_* events (note that user data for + * pVirtualChannelWriteEx() as implemented by FreeRDP MUST either be NULL + * or a wStream containing the data written). + * + * @param data_length + * The number of bytes of event-specific data. + * + * @param total_length + * The total number of bytes written to the RDP server in a single write + * operation. + * + * NOTE: The meaning of total_length is unclear. The above description was + * written mainly through referencing the documentation in MSDN. Real-world + * use will need to be consulted, likely within the FreeRDP source, before + * this value can be reliably used. The current implementation of this + * handler ignores this parameter. + * + * @param data_flags + * The result of a bitwise OR of the CHANNEL_FLAG_* flags which apply to + * the data received. This value is relevant only to + * CHANNEL_EVENT_DATA_RECEIVED events. Valid flags are CHANNEL_FLAG_FIRST, + * CHANNEL_FLAG_LAST, and CHANNEL_FLAG_ONLY. The flag CHANNEL_FLAG_MIDDLE + * is not itself a flag, but the absence of both CHANNEL_FLAG_FIRST and + * CHANNEL_FLAG_LAST. + */ +static VOID guac_rdpdr_handle_open_event(LPVOID user_param, + DWORD open_handle, UINT event, LPVOID data, UINT32 data_length, + UINT32 total_length, UINT32 data_flags) { + + /* Ignore all events except for received data */ + if (event != CHANNEL_EVENT_DATA_RECEIVED) + return; + + guac_rdpdr* rdpdr = (guac_rdpdr*) user_param; + + /* Validate relevant handle matches that of the RDPDR channel */ + if (open_handle != rdpdr->open_handle) { + guac_client_log(rdpdr->client, GUAC_LOG_WARNING, "%i bytes of data " + "received from within the remote desktop session for the " + "RDPDR channel are being dropped because the relevant open " + "handle (0x%X) does not match the open handle of RDPDR " + "(0x%X).", data_length, rdpdr->channel_def.name, open_handle, + rdpdr->open_handle); + return; + } + + wStream* input_stream = Stream_New(data, data_length); + guac_rdpdr_process_receive(rdpdr, input_stream); + Stream_Free(input_stream, FALSE); + +} + +/** + * Processes a CHANNEL_EVENT_CONNECTED event, completing the + * connection/initialization process of the RDPDR channel. + * + * @param rdpdr + * The guac_rdpdr structure representing the RDPDR channel. + */ +static void guac_rdpdr_process_connect(guac_rdpdr* rdpdr) { + + /* Get data from client */ + guac_client* client = rdpdr->client; + guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; + + /* Open FreeRDP side of connected channel */ + UINT32 open_status = + rdpdr->entry_points.pVirtualChannelOpenEx(rdpdr->init_handle, + &rdpdr->open_handle, rdpdr->channel_def.name, + guac_rdpdr_handle_open_event); + + /* Warn if the channel cannot be opened after all */ + if (open_status != CHANNEL_RC_OK) { + guac_client_log(client, GUAC_LOG_WARNING, "RDPDR channel could not be " + "opened: %s (error %i)", WTSErrorToString(open_status), + open_status); + return; + } + + /* Register printer if enabled */ + if (rdp_client->settings->printing_enabled) + guac_rdpdr_register_printer(rdpdr, rdp_client->settings->printer_name); + + /* Register drive if enabled */ + if (rdp_client->settings->drive_enabled) + guac_rdpdr_register_fs(rdpdr, rdp_client->settings->drive_name); + + /* Log that printing, etc. has been loaded */ + guac_client_log(client, GUAC_LOG_INFO, "RDPDR channel connected."); + +} + +/** + * Processes a CHANNEL_EVENT_TERMINATED event, freeing all resources associated + * with the RDPDR channel. + * + * @param rdpdr + * The guac_rdpdr structure representing the RDPDR channel. + */ +static void guac_rdpdr_process_terminate(guac_rdpdr* rdpdr) { + + int i; + + for (i=0; idevices_registered; i++) { + guac_rdpdr_device* device = &(rdpdr->devices[i]); + guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Unloading device %i (%s)", + device->device_id, device->device_name); + device->free_handler(device); + } + + guac_client_log(rdpdr->client, GUAC_LOG_INFO, "RDPDR channel disconnected."); + free(rdpdr); + +} + +/** + * Event handler for events which deal with the overall lifecycle of the RDPDR + * channel. This specific implementation of the event handler currently + * handles only CHANNEL_EVENT_CONNECTED and CHANNEL_EVENT_TERMINATED events, + * delegating actual handling of those events to guac_rdpdr_process_connect() + * and guac_rdpdr_process_terminate() respectively. + * + * The FreeRDP requirements for this function follow those of the + * VirtualChannelInitEventEx callback defined within Microsoft's RDP API: + * + * https://docs.microsoft.com/en-us/previous-versions/windows/embedded/aa514727%28v%3dmsdn.10%29 + * + * @param user_param + * The pointer to arbitrary data originally passed via the first parameter + * of the pVirtualChannelInitEx() function call when the associated channel + * was initialized. The pVirtualChannelInitEx() function is exposed within + * the channel entry points structure. + * + * @param init_handle + * The handle which identifies the client connection, typically referred to + * within the FreeRDP source as pInitHandle. + * + * @param event + * An integer representing the event that should be handled. This will be + * either CHANNEL_EVENT_CONNECTED, CHANNEL_EVENT_DISCONNECTED, + * CHANNEL_EVENT_INITIALIZED, CHANNEL_EVENT_TERMINATED, or + * CHANNEL_EVENT_V1_CONNECTED. + * + * @param data + * NULL in all cases except the CHANNEL_EVENT_CONNECTED event, in which + * case this is a null-terminated string containing the name of the server. + * + * @param data_length + * The number of bytes of data, if any. + */ +static VOID guac_rdpdr_handle_init_event(LPVOID user_param, + LPVOID init_handle, UINT event, LPVOID data, UINT data_length) { + + guac_rdpdr* rdpdr = (guac_rdpdr*) user_param; + + /* Validate relevant handle matches that of the RDPDR channel */ + if (init_handle != rdpdr->init_handle) { + guac_client_log(rdpdr->client, GUAC_LOG_WARNING, "An init event " + "(#%i) for the RDPDR channel has been dropped because the " + "relevant init handle (0x%X) does not match the init handle " + "of the RDPDR channel (0x%X).", event, init_handle, + rdpdr->init_handle); + return; + } + + switch (event) { + + /* The RDPDR channel has been connected */ + case CHANNEL_EVENT_CONNECTED: + guac_rdpdr_process_connect(rdpdr); + break; + + /* The RDPDR channel has disconnected and now must be cleaned up */ + case CHANNEL_EVENT_TERMINATED: + guac_rdpdr_process_terminate(rdpdr); + break; + + } + +} + +/** + * Entry point for FreeRDP plugins. This function is automatically invoked when + * the plugin is loaded. + * + * @param entry_points + * Functions and data specific to the FreeRDP side of the virtual channel + * and plugin. This structure must be copied within implementation-specific + * storage such that the functions it references can be invoked when + * needed. + * + * @param init_handle + * The handle which identifies the client connection, typically referred to + * within the FreeRDP source as pInitHandle. This handle is also provided + * to the channel init event handler. The handle must eventually be used + * within the channel open event handler to obtain a handle to the channel + * itself. + * + * @return + * TRUE if the plugin has initialized successfully, FALSE otherwise. + */ +BOOL VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS entry_points, + PVOID init_handle) { + + CHANNEL_ENTRY_POINTS_FREERDP_EX* entry_points_ex = + (CHANNEL_ENTRY_POINTS_FREERDP_EX*) entry_points; + + /* Allocate plugin */ + guac_rdpdr* rdpdr = (guac_rdpdr*) calloc(1, sizeof(guac_rdpdr)); + + /* Init channel def */ + strcpy(rdpdr->channel_def.name, "rdpdr"); + rdpdr->channel_def.options = CHANNEL_OPTION_INITIALIZED + | CHANNEL_OPTION_ENCRYPT_RDP + | CHANNEL_OPTION_COMPRESS_RDP; + + /* Maintain reference to associated guac_client */ + rdpdr->client = (guac_client*) entry_points_ex->pExtendedData; + + /* No devices are connected initially */ + rdpdr->devices_registered = 0; + + /* Copy FreeRDP data into RDPSND structure for future reference */ + rdpdr->entry_points = *entry_points_ex; + rdpdr->init_handle = init_handle; + + /* Complete initialization */ + if (rdpdr->entry_points.pVirtualChannelInitEx(rdpdr, rdpdr, init_handle, + &rdpdr->channel_def, 1, VIRTUAL_CHANNEL_VERSION_WIN2000, + guac_rdpdr_handle_init_event) != CHANNEL_RC_OK) { + return FALSE; + } + + return TRUE; + +} + diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_service.h b/src/protocols/rdp/guac_rdpdr/rdpdr_service.h index 064ce32d..1fa3b126 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_service.h +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_service.h @@ -23,16 +23,17 @@ #include "config.h" -#include +#include #include #include +#include /** * The maximum number of bytes to allow for a device read. */ #define GUAC_RDP_MAX_READ_BUFFER 4194304 -typedef struct guac_rdpdrPlugin guac_rdpdrPlugin; +typedef struct guac_rdpdr guac_rdpdr; typedef struct guac_rdpdr_device guac_rdpdr_device; /** @@ -61,7 +62,7 @@ struct guac_rdpdr_device { /** * The RDPDR plugin owning this device. */ - guac_rdpdrPlugin* rdpdr; + guac_rdpdr* rdpdr; /** * The ID assigned to this device by the RDPDR plugin. @@ -115,20 +116,45 @@ struct guac_rdpdr_device { * Structure representing the current state of the Guacamole RDPDR plugin for * FreeRDP. */ -struct guac_rdpdrPlugin { - - /** - * The FreeRDP parts of this plugin. This absolutely MUST be first. - * FreeRDP depends on accessing this structure as if it were an instance - * of rdpSvcPlugin. - */ - rdpSvcPlugin plugin; +struct guac_rdpdr { /** * Reference to the client owning this instance of the RDPDR plugin. */ guac_client* client; + /** + * The definition of this virtual channel (RDPDR). + */ + CHANNEL_DEF channel_def; + + /** + * Functions and data specific to the FreeRDP side of the virtual channel + * and plugin. + */ + CHANNEL_ENTRY_POINTS_FREERDP_EX entry_points; + + /** + * Handle which identifies the client connection, typically referred to + * within the FreeRDP source as pInitHandle. This handle is provided to the + * channel entry point and the channel init event handler. The handle must + * eventually be used within the channel open event handler to obtain a + * handle to the channel itself. + */ + PVOID init_handle; + + /** + * Handle which identifies the channel itself, typically referred to within + * the FreeRDP source as OpenHandle. This handle is obtained through a call + * to entry_points.pVirtualChannelOpenEx() in response to receiving a + * CHANNEL_EVENT_CONNECTED event via the init event handler. + * + * Data is received in CHANNEL_EVENT_DATA_RECEIVED events via the open + * event handler, and data is written through calls to + * entry_points.pVirtualChannelWriteEx(). + */ + DWORD open_handle; + /** * The number of devices registered within the devices array. */ @@ -141,28 +167,6 @@ struct guac_rdpdrPlugin { }; -/** - * Handler called when this plugin is loaded by FreeRDP. - */ -void guac_rdpdr_process_connect(rdpSvcPlugin* plugin); - -/** - * Handler called when this plugin receives data along its designated channel. - */ -void guac_rdpdr_process_receive(rdpSvcPlugin* plugin, - wStream* input_stream); - -/** - * Handler called when this plugin is being unloaded. - */ -void guac_rdpdr_process_terminate(rdpSvcPlugin* plugin); - -/** - * Handler called when this plugin receives an event. For the sake of RDPDR, - * all events will be ignored and simply free'd. - */ -void guac_rdpdr_process_event(rdpSvcPlugin* plugin, wMessage* event); - /** * Creates a new stream which contains the common DR_DEVICE_IOCOMPLETION header * used for virtually all responses.