diff --git a/src/protocols/rdp/Makefile.am b/src/protocols/rdp/Makefile.am index 0a832514..8657420e 100644 --- a/src/protocols/rdp/Makefile.am +++ b/src/protocols/rdp/Makefile.am @@ -36,49 +36,48 @@ SUBDIRS = . tests nodist_libguac_client_rdp_la_SOURCES = \ _generated_keymaps.c -libguac_client_rdp_la_SOURCES = \ - audio_input.c \ - channels.c \ - client.c \ - clipboard.c \ - common-svc.c \ - decompose.c \ - disp.c \ - error.c \ - input.c \ - keyboard.c \ - pipe-svc.c \ - ptr_string.c \ - rail.c \ - rdp.c \ - rdp_bitmap.c \ - rdp_color.c \ - rdp_fs.c \ - rdp_gdi.c \ - rdp_glyph.c \ - rdp_keymap.c \ - rdp_print_job.c \ - rdp_pointer.c \ - rdp_settings.c \ - rdp_stream.c \ - rdpdr.c \ - rdpsnd.c \ - rdpsnd_messages.c \ - resolution.c \ - unicode.c \ +libguac_client_rdp_la_SOURCES = \ + audio_input.c \ + channels.c \ + client.c \ + clipboard.c \ + common-svc.c \ + decompose.c \ + disp.c \ + error.c \ + input.c \ + keyboard.c \ + pipe-svc.c \ + ptr_string.c \ + rail.c \ + rdp.c \ + rdp_bitmap.c \ + rdp_color.c \ + rdp_fs.c \ + rdp_gdi.c \ + rdp_glyph.c \ + rdp_keymap.c \ + rdp_print_job.c \ + rdp_pointer.c \ + rdp_settings.c \ + rdp_stream.c \ + rdpdr.c \ + rdpdr_fs_messages.c \ + rdpdr_fs_messages_dir_info.c \ + rdpdr_fs_messages_file_info.c \ + rdpdr_fs_messages_vol_info.c \ + rdpdr_fs_service.c \ + rdpdr_messages.c \ + rdpdr_printer.c \ + rdpsnd.c \ + rdpsnd_messages.c \ + resolution.c \ + unicode.c \ user.c noinst_HEADERS = \ guac_ai/ai_messages.h \ guac_ai/ai_service.h \ - guac_rdpdr/rdpdr_fs_messages.h \ - guac_rdpdr/rdpdr_fs_messages_dir_info.h \ - guac_rdpdr/rdpdr_fs_messages_file_info.h \ - guac_rdpdr/rdpdr_fs_messages_vol_info.h \ - guac_rdpdr/rdpdr_fs_service.h \ - guac_rdpdr/rdpdr_messages.h \ - guac_rdpdr/rdpdr_printer.h \ - guac_rdpdr/rdpdr_service.h \ audio_input.h \ client.h \ clipboard.h \ @@ -105,6 +104,13 @@ noinst_HEADERS = \ rdp_status.h \ rdp_stream.h \ rdpdr.h \ + rdpdr_fs_messages.h \ + rdpdr_fs_messages_dir_info.h \ + rdpdr_fs_messages_file_info.h \ + rdpdr_fs_messages_vol_info.h \ + rdpdr_fs_service.h \ + rdpdr_messages.h \ + rdpdr_printer.h \ rdpsnd.h \ rdpsnd_messages.h \ resolution.h \ @@ -134,8 +140,7 @@ libguac_client_rdp_la_LIBADD = \ freerdp_LTLIBRARIES = \ libguac-common-svc-client.la \ - libguacai-client.la \ - libguacdr-client.la + libguacai-client.la freerdpdir = ${libdir}/freerdp2 @@ -158,40 +163,6 @@ libguac_common_svc_client_la_LDFLAGS = \ libguac_common_svc_client_la_LIBADD = \ @LIBGUAC_LTLIB@ -# -# 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@ - # # Audio Input # diff --git a/src/protocols/rdp/guac-common-svc/common-svc-main.c b/src/protocols/rdp/guac-common-svc/common-svc-main.c index 441823b7..572a1d2c 100644 --- a/src/protocols/rdp/guac-common-svc/common-svc-main.c +++ b/src/protocols/rdp/guac-common-svc/common-svc-main.c @@ -283,7 +283,7 @@ static VOID guac_rdp_common_svc_handle_init_event(LPVOID user_param, * @return * TRUE if the plugin has initialized successfully, FALSE otherwise. */ -BOOL VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS entry_points, +BOOL VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS_EX entry_points, PVOID init_handle) { CHANNEL_ENTRY_POINTS_FREERDP_EX* entry_points_ex = diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_service.c b/src/protocols/rdp/guac_rdpdr/rdpdr_service.c deleted file mode 100644 index d20f7d83..00000000 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_service.c +++ /dev/null @@ -1,500 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -#include "config.h" - -#include "rdp.h" -#include "rdp_fs.h" -#include "rdp_settings.h" -#include "rdp_stream.h" -#include "rdpdr_fs_service.h" -#include "rdpdr_messages.h" -#include "rdpdr_printer.h" -#include "rdpdr_service.h" - -#include -#include - -#include -#include -#include -#include -#include -#include - -/** - * 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. - */ -static void guac_rdpdr_process_receive(guac_rdpdr* rdpdr, - wStream* input_stream) { - - int component; - int packet_id; - - /* Read header */ - Stream_Read_UINT16(input_stream, component); - Stream_Read_UINT16(input_stream, packet_id); - - /* Core component */ - if (component == RDPDR_CTYP_CORE) { - - /* Dispatch handlers based on packet ID */ - switch (packet_id) { - - case PAKID_CORE_SERVER_ANNOUNCE: - guac_rdpdr_process_server_announce(rdpdr, input_stream); - break; - - case PAKID_CORE_CLIENTID_CONFIRM: - guac_rdpdr_process_clientid_confirm(rdpdr, input_stream); - break; - - case PAKID_CORE_DEVICE_REPLY: - guac_rdpdr_process_device_reply(rdpdr, input_stream); - break; - - case PAKID_CORE_DEVICE_IOREQUEST: - guac_rdpdr_process_device_iorequest(rdpdr, input_stream); - break; - - case PAKID_CORE_SERVER_CAPABILITY: - guac_rdpdr_process_server_capability(rdpdr, input_stream); - break; - - case PAKID_CORE_USER_LOGGEDON: - guac_rdpdr_process_user_loggedon(rdpdr, input_stream); - break; - - default: - guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Ignoring RDPDR core packet with unexpected ID: 0x%04x", packet_id); - - } - - } /* end if core */ - - /* Printer component */ - else if (component == RDPDR_CTYP_PRN) { - - /* Dispatch handlers based on packet ID */ - switch (packet_id) { - - case PAKID_PRN_CACHE_DATA: - guac_rdpdr_process_prn_cache_data(rdpdr, input_stream); - break; - - case PAKID_PRN_USING_XPS: - guac_rdpdr_process_prn_using_xps(rdpdr, input_stream); - break; - - default: - guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Ignoring RDPDR printer packet with unexpected ID: 0x%04x", packet_id); - - } - - } /* end if printer */ - - else - guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Ignoring packet for unknown RDPDR component: 0x%04x", component); - -} - -wStream* guac_rdpdr_new_io_completion(guac_rdpdr_device* device, - int completion_id, int status, int size) { - - wStream* output_stream = Stream_New(NULL, 16+size); - - /* Write header */ - Stream_Write_UINT16(output_stream, RDPDR_CTYP_CORE); - Stream_Write_UINT16(output_stream, PAKID_CORE_DEVICE_IOCOMPLETION); - - /* Write content */ - Stream_Write_UINT32(output_stream, device->device_id); - Stream_Write_UINT32(output_stream, completion_id); - Stream_Write_UINT32(output_stream, status); - - return output_stream; - -} - -/** - * Callback invoked on the current connection owner (if any) when a file - * download is being initiated using the magic "Download" folder. - * - * @param owner - * The guac_user that is the owner of the connection, or NULL if the - * connection owner has left. - * - * @param data - * The full absolute path to the file that should be downloaded. - * - * @return - * The stream allocated for the file download, or NULL if the download has - * failed to start. - */ -static void* guac_rdpdr_download_to_owner(guac_user* owner, void* data) { - - /* Do not bother attempting the download if the owner has left */ - if (owner == NULL) - return NULL; - - guac_client* client = owner->client; - guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; - guac_rdp_fs* filesystem = rdp_client->filesystem; - - /* Ignore download if filesystem has been unloaded */ - if (filesystem == NULL) - return NULL; - - /* Attempt to open requested file */ - char* path = (char*) data; - int file_id = guac_rdp_fs_open(filesystem, path, - ACCESS_FILE_READ_DATA, 0, DISP_FILE_OPEN, 0); - - /* If file opened successfully, start stream */ - if (file_id >= 0) { - - guac_rdp_stream* rdp_stream; - const char* basename; - - int i; - char c; - - /* Associate stream with transfer status */ - guac_stream* stream = guac_user_alloc_stream(owner); - stream->data = rdp_stream = malloc(sizeof(guac_rdp_stream)); - stream->ack_handler = guac_rdp_download_ack_handler; - rdp_stream->type = GUAC_RDP_DOWNLOAD_STREAM; - rdp_stream->download_status.file_id = file_id; - rdp_stream->download_status.offset = 0; - - /* Get basename from absolute path */ - i=0; - basename = path; - do { - - c = path[i]; - if (c == '/' || c == '\\') - basename = &(path[i+1]); - - i++; - - } while (c != '\0'); - - guac_user_log(owner, GUAC_LOG_DEBUG, "%s: Initiating download " - "of \"%s\"", __func__, path); - - /* Begin stream */ - guac_protocol_send_file(owner->socket, stream, - "application/octet-stream", basename); - guac_socket_flush(owner->socket); - - /* Download started successfully */ - return stream; - - } - - /* Download failed */ - guac_user_log(owner, GUAC_LOG_ERROR, "Unable to download \"%s\"", path); - return NULL; - -} - -void guac_rdpdr_start_download(guac_rdpdr_device* device, char* path) { - - guac_client* client = device->rdpdr->client; - - /* Initiate download to the owner of the connection */ - guac_client_for_owner(client, guac_rdpdr_download_to_owner, 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 deleted file mode 100644 index 1fa3b126..00000000 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_service.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance - * with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - - -#ifndef __GUAC_RDPDR_SERVICE_H -#define __GUAC_RDPDR_SERVICE_H - -#include "config.h" - -#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_rdpdr guac_rdpdr; -typedef struct guac_rdpdr_device guac_rdpdr_device; - -/** - * Handler for client device list announce. Each implementing device must write - * its announcement header and data to the given output stream. - */ -typedef void guac_rdpdr_device_announce_handler(guac_rdpdr_device* device, wStream* output_stream, - int device_id); - -/** - * Handler for device I/O requests. - */ -typedef void guac_rdpdr_device_iorequest_handler(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id, int major_func, int minor_func); - -/** - * Handler for cleaning up the dynamically-allocated portions of a device. - */ -typedef void guac_rdpdr_device_free_handler(guac_rdpdr_device* device); - -/** - * Arbitrary device forwarded over the RDPDR channel. - */ -struct guac_rdpdr_device { - - /** - * The RDPDR plugin owning this device. - */ - guac_rdpdr* rdpdr; - - /** - * The ID assigned to this device by the RDPDR plugin. - */ - int device_id; - - /** - * Device name, used for logging and for passthrough to the - * server. - */ - const char* device_name; - - /** - * The type of RDPDR device that this represents. - */ - uint32_t device_type; - - /** - * The DOS name of the device. Max 8 bytes, including terminator. - */ - const char *dos_name; - - /** - * The stream that stores the RDPDR device announcement for this device. - */ - wStream* device_announce; - - /** - * The length of the device_announce wStream. - */ - int device_announce_len; - - /** - * Handler which should be called for every I/O request received. - */ - guac_rdpdr_device_iorequest_handler* iorequest_handler; - - /** - * Handler which should be called when the device is being freed. - */ - guac_rdpdr_device_free_handler* free_handler; - - /** - * Arbitrary data, used internally by the handlers for this device. - */ - void* data; - -}; - -/** - * Structure representing the current state of the Guacamole RDPDR plugin for - * FreeRDP. - */ -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. - */ - int devices_registered; - - /** - * Array of registered devices. - */ - guac_rdpdr_device devices[8]; - -}; - -/** - * Creates a new stream which contains the common DR_DEVICE_IOCOMPLETION header - * used for virtually all responses. - */ -wStream* guac_rdpdr_new_io_completion(guac_rdpdr_device* device, - int completion_id, int status, int size); - -/** - * Begins streaming the given file to the user via a Guacamole file stream. - */ -void guac_rdpdr_start_download(guac_rdpdr_device* device, char* path); - -#endif - diff --git a/src/protocols/rdp/rdpdr.c b/src/protocols/rdp/rdpdr.c index e39d393a..aabe9399 100644 --- a/src/protocols/rdp/rdpdr.c +++ b/src/protocols/rdp/rdpdr.c @@ -20,24 +20,262 @@ #include "config.h" #include "channels.h" #include "rdp.h" +#include "rdp_fs.h" +#include "rdp_settings.h" +#include "rdp_stream.h" +#include "rdpdr.h" +#include "rdpdr_fs_service.h" +#include "rdpdr_messages.h" +#include "rdpdr_printer.h" #include #include +#include +#include +#include +#include + +#include +#include + +void guac_rdpdr_process_receive(guac_rdp_common_svc* svc, + wStream* input_stream) { + + int component; + int packet_id; + + /* Read header */ + Stream_Read_UINT16(input_stream, component); + Stream_Read_UINT16(input_stream, packet_id); + + /* Core component */ + if (component == RDPDR_CTYP_CORE) { + + /* Dispatch handlers based on packet ID */ + switch (packet_id) { + + case PAKID_CORE_SERVER_ANNOUNCE: + guac_rdpdr_process_server_announce(svc, input_stream); + break; + + case PAKID_CORE_CLIENTID_CONFIRM: + guac_rdpdr_process_clientid_confirm(svc, input_stream); + break; + + case PAKID_CORE_DEVICE_REPLY: + guac_rdpdr_process_device_reply(svc, input_stream); + break; + + case PAKID_CORE_DEVICE_IOREQUEST: + guac_rdpdr_process_device_iorequest(svc, input_stream); + break; + + case PAKID_CORE_SERVER_CAPABILITY: + guac_rdpdr_process_server_capability(svc, input_stream); + break; + + case PAKID_CORE_USER_LOGGEDON: + guac_rdpdr_process_user_loggedon(svc, input_stream); + break; + + default: + guac_client_log(svc->client, GUAC_LOG_DEBUG, "Ignoring " + "RDPDR core packet with unexpected ID: 0x%04x", + packet_id); + + } + + } /* end if core */ + + /* Printer component */ + else if (component == RDPDR_CTYP_PRN) { + + /* Dispatch handlers based on packet ID */ + switch (packet_id) { + + case PAKID_PRN_CACHE_DATA: + guac_rdpdr_process_prn_cache_data(svc, input_stream); + break; + + case PAKID_PRN_USING_XPS: + guac_rdpdr_process_prn_using_xps(svc, input_stream); + break; + + default: + guac_client_log(svc->client, GUAC_LOG_DEBUG, "Ignoring RDPDR " + "printer packet with unexpected ID: 0x%04x", + packet_id); + + } + + } /* end if printer */ + + else + guac_client_log(svc->client, GUAC_LOG_DEBUG, "Ignoring packet for " + "unknown RDPDR component: 0x%04x", component); + +} + +wStream* guac_rdpdr_new_io_completion(guac_rdpdr_device* device, + int completion_id, int status, int size) { + + wStream* output_stream = Stream_New(NULL, 16+size); + + /* Write header */ + Stream_Write_UINT16(output_stream, RDPDR_CTYP_CORE); + Stream_Write_UINT16(output_stream, PAKID_CORE_DEVICE_IOCOMPLETION); + + /* Write content */ + Stream_Write_UINT32(output_stream, device->device_id); + Stream_Write_UINT32(output_stream, completion_id); + Stream_Write_UINT32(output_stream, status); + + return output_stream; + +} + +/** + * Callback invoked on the current connection owner (if any) when a file + * download is being initiated using the magic "Download" folder. + * + * @param owner + * The guac_user that is the owner of the connection, or NULL if the + * connection owner has left. + * + * @param data + * The full absolute path to the file that should be downloaded. + * + * @return + * The stream allocated for the file download, or NULL if the download has + * failed to start. + */ +static void* guac_rdpdr_download_to_owner(guac_user* owner, void* data) { + + /* Do not bother attempting the download if the owner has left */ + if (owner == NULL) + return NULL; + + guac_client* client = owner->client; + guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; + guac_rdp_fs* filesystem = rdp_client->filesystem; + + /* Ignore download if filesystem has been unloaded */ + if (filesystem == NULL) + return NULL; + + /* Attempt to open requested file */ + char* path = (char*) data; + int file_id = guac_rdp_fs_open(filesystem, path, + ACCESS_FILE_READ_DATA, 0, DISP_FILE_OPEN, 0); + + /* If file opened successfully, start stream */ + if (file_id >= 0) { + + guac_rdp_stream* rdp_stream; + const char* basename; + + int i; + char c; + + /* Associate stream with transfer status */ + guac_stream* stream = guac_user_alloc_stream(owner); + stream->data = rdp_stream = malloc(sizeof(guac_rdp_stream)); + stream->ack_handler = guac_rdp_download_ack_handler; + rdp_stream->type = GUAC_RDP_DOWNLOAD_STREAM; + rdp_stream->download_status.file_id = file_id; + rdp_stream->download_status.offset = 0; + + /* Get basename from absolute path */ + i=0; + basename = path; + do { + + c = path[i]; + if (c == '/' || c == '\\') + basename = &(path[i+1]); + + i++; + + } while (c != '\0'); + + guac_user_log(owner, GUAC_LOG_DEBUG, "%s: Initiating download " + "of \"%s\"", __func__, path); + + /* Begin stream */ + guac_protocol_send_file(owner->socket, stream, + "application/octet-stream", basename); + guac_socket_flush(owner->socket); + + /* Download started successfully */ + return stream; + + } + + /* Download failed */ + guac_user_log(owner, GUAC_LOG_ERROR, "Unable to download \"%s\"", path); + return NULL; + +} + +void guac_rdpdr_start_download(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, char* path) { + + guac_client* client = svc->client; + + /* Initiate download to the owner of the connection */ + guac_client_for_owner(client, guac_rdpdr_download_to_owner, path); + +} + +void guac_rdpdr_process_connect(guac_rdp_common_svc* svc) { + + /* Get data from client */ + guac_client* client = svc->client; + guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; + + guac_rdpdr* rdpdr = (guac_rdpdr*) calloc(1, sizeof(guac_rdpdr)); + svc->data = rdpdr; + + /* Register printer if enabled */ + if (rdp_client->settings->printing_enabled) + guac_rdpdr_register_printer(svc, rdp_client->settings->printer_name); + + /* Register drive if enabled */ + if (rdp_client->settings->drive_enabled) + guac_rdpdr_register_fs(svc, rdp_client->settings->drive_name); + +} + +void guac_rdpdr_process_terminate(guac_rdp_common_svc* svc) { + + guac_rdpdr* rdpdr = (guac_rdpdr*) svc->data; + + int i; + + for (i=0; idevices_registered; i++) { + guac_rdpdr_device* device = &(rdpdr->devices[i]); + guac_client_log(svc->client, GUAC_LOG_DEBUG, "Unloading device %i " + "(%s)", device->device_id, device->device_name); + device->free_handler(svc, device); + } + + free(rdpdr); + +} + void guac_rdpdr_load_plugin(rdpContext* context) { guac_client* client = ((rdp_freerdp_context*) context)->client; - /* Load RDPDR plugin */ - if (guac_freerdp_channels_load_plugin(context->channels, context->settings, "guacdr", client)) { + /* Load support for RDPDR */ + if (guac_rdp_common_svc_load_plugin(context, "rdpdr", + CHANNEL_OPTION_COMPRESS_RDP, guac_rdpdr_process_connect, + guac_rdpdr_process_receive, guac_rdpdr_process_terminate)) { guac_client_log(client, GUAC_LOG_WARNING, "Support for the RDPDR " "channel (device redirection) could not be loaded. Drive " "redirection and printing will not work. Sound MAY not work."); - return; } - guac_client_log(client, GUAC_LOG_DEBUG, "Support for RDPDR (device " - "redirection) registered. Awaiting channel connection."); - } diff --git a/src/protocols/rdp/rdpdr.h b/src/protocols/rdp/rdpdr.h index 0a18a58c..b5e59f0a 100644 --- a/src/protocols/rdp/rdpdr.h +++ b/src/protocols/rdp/rdpdr.h @@ -21,6 +21,121 @@ #define GUAC_RDP_RDPDR_H #include "config.h" +#include "common-svc.h" + +#include +#include + +/** + * The maximum number of bytes to allow for a device read. + */ +#define GUAC_RDP_MAX_READ_BUFFER 4194304 + +/** + * Arbitrary device forwarded over the RDPDR channel. + */ +typedef struct guac_rdpdr_device guac_rdpdr_device; + +/** + * Handler for client device list announce. Each implementing device must write + * its announcement header and data to the given output stream. + */ +typedef void guac_rdpdr_device_announce_handler(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* output_stream, int device_id); + +/** + * Handler for device I/O requests. + */ +typedef void guac_rdpdr_device_iorequest_handler(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id, int major_func, int minor_func); + +/** + * Handler for cleaning up the dynamically-allocated portions of a device. + */ +typedef void guac_rdpdr_device_free_handler(guac_rdp_common_svc* svc, + guac_rdpdr_device* device); + +struct guac_rdpdr_device { + + /** + * The ID assigned to this device by the RDPDR plugin. + */ + int device_id; + + /** + * Device name, used for logging and for passthrough to the + * server. + */ + const char* device_name; + + /** + * The type of RDPDR device that this represents. + */ + uint32_t device_type; + + /** + * The DOS name of the device. Max 8 bytes, including terminator. + */ + const char *dos_name; + + /** + * The stream that stores the RDPDR device announcement for this device. + */ + wStream* device_announce; + + /** + * The length of the device_announce wStream. + */ + int device_announce_len; + + /** + * Handler which should be called for every I/O request received. + */ + guac_rdpdr_device_iorequest_handler* iorequest_handler; + + /** + * Handler which should be called when the device is being freed. + */ + guac_rdpdr_device_free_handler* free_handler; + + /** + * Arbitrary data, used internally by the handlers for this device. + */ + void* data; + +}; + +/** + * Structure representing the current state of the Guacamole RDPDR plugin for + * FreeRDP. + */ +typedef struct guac_rdpdr { + + /** + * The number of devices registered within the devices array. + */ + int devices_registered; + + /** + * Array of registered devices. + */ + guac_rdpdr_device devices[8]; + +} guac_rdpdr; + +/** + * Creates a new stream which contains the common DR_DEVICE_IOCOMPLETION header + * used for virtually all responses. + */ +wStream* guac_rdpdr_new_io_completion(guac_rdpdr_device* device, + int completion_id, int status, int size); + +/** + * Begins streaming the given file to the user via a Guacamole file stream. + */ +void guac_rdpdr_start_download(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, char* path); /** * Initializes device redirection support (file transfer, printing, etc.) for @@ -36,5 +151,23 @@ */ void guac_rdpdr_load_plugin(rdpContext* context); +/** + * Handler which is invoked when the RDPDR channel is connected to the RDP + * server. + */ +guac_rdp_common_svc_connect_handler guac_rdpdr_process_connect; + +/** + * Handler which is invoked when the RDPDR channel has received data from the + * RDP server. + */ +guac_rdp_common_svc_receive_handler guac_rdpdr_process_receive; + +/** + * Handler which is invoked when the RDPDR channel has disconnected and is + * about to be freed. + */ +guac_rdp_common_svc_terminate_handler guac_rdpdr_process_terminate; + #endif diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c b/src/protocols/rdp/rdpdr_fs_messages.c similarity index 69% rename from src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c rename to src/protocols/rdp/rdpdr_fs_messages.c index 1336e6f9..b23a0107 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c +++ b/src/protocols/rdp/rdpdr_fs_messages.c @@ -18,13 +18,12 @@ */ #include "config.h" - +#include "rdpdr.h" #include "rdpdr_fs_messages_dir_info.h" #include "rdpdr_fs_messages_file_info.h" #include "rdpdr_fs_messages.h" #include "rdpdr_fs_messages_vol_info.h" #include "rdpdr_messages.h" -#include "rdpdr_service.h" #include "rdp_fs.h" #include "rdp_status.h" #include "unicode.h" @@ -38,8 +37,8 @@ #include #include -void guac_rdpdr_fs_process_create(guac_rdpdr_device* device, - wStream* input_stream, int completion_id) { +void guac_rdpdr_fs_process_create(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int completion_id) { wStream* output_stream; int file_id; @@ -66,7 +65,7 @@ void guac_rdpdr_fs_process_create(guac_rdpdr_device* device, desired_access, file_attributes, create_disposition, create_options); - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i] " "desired_access=0x%x, file_attributes=0x%x, " "create_disposition=0x%x, create_options=0x%x, path=\"%s\"", @@ -76,7 +75,7 @@ void guac_rdpdr_fs_process_create(guac_rdpdr_device* device, /* If an error occurred, notify server */ if (file_id < 0) { - guac_client_log(device->rdpdr->client, GUAC_LOG_ERROR, + guac_client_log(svc->client, GUAC_LOG_ERROR, "File open refused (%i): \"%s\"", file_id, path); output_stream = guac_rdpdr_new_io_completion(device, completion_id, @@ -109,14 +108,13 @@ void guac_rdpdr_fs_process_create(guac_rdpdr_device* device, } - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_read(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id) { +void guac_rdpdr_fs_process_read(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id) { UINT32 length; UINT64 offset; @@ -129,7 +127,7 @@ void guac_rdpdr_fs_process_read(guac_rdpdr_device* device, Stream_Read_UINT32(input_stream, length); Stream_Read_UINT64(input_stream, offset); - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i] length=%i, offset=%" PRIu64, __func__, file_id, length, (uint64_t) offset); @@ -159,15 +157,14 @@ void guac_rdpdr_fs_process_read(guac_rdpdr_device* device, Stream_Write(output_stream, buffer, bytes_read); /* ReadData */ } - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); free(buffer); } -void guac_rdpdr_fs_process_write(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id) { +void guac_rdpdr_fs_process_write(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id) { UINT32 length; UINT64 offset; @@ -180,7 +177,7 @@ void guac_rdpdr_fs_process_write(guac_rdpdr_device* device, Stream_Read_UINT64(input_stream, offset); Stream_Seek(input_stream, 20); /* Padding */ - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i] length=%i, offset=%" PRIu64, __func__, file_id, length, (uint64_t) offset); @@ -204,19 +201,18 @@ void guac_rdpdr_fs_process_write(guac_rdpdr_device* device, Stream_Write_UINT8(output_stream, 0); /* Padding */ } - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_close(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id) { +void guac_rdpdr_fs_process_close(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id) { wStream* output_stream; guac_rdp_fs_file* file; - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i]", __func__, file_id); @@ -228,7 +224,7 @@ void guac_rdpdr_fs_process_close(guac_rdpdr_device* device, /* If file was written to, and it's in the \Download folder, start stream */ if (file->bytes_written > 0 && strncmp(file->absolute_path, "\\Download\\", 10) == 0) { - guac_rdpdr_start_download(device, file->absolute_path); + guac_rdpdr_start_download(svc, device, file->absolute_path); guac_rdp_fs_delete((guac_rdp_fs*) device->data, file_id); } @@ -239,14 +235,13 @@ void guac_rdpdr_fs_process_close(guac_rdpdr_device* device, STATUS_SUCCESS, 4); Stream_Write(output_stream, "\0\0\0\0", 4); /* Padding */ - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_volume_info(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id) { +void guac_rdpdr_fs_process_volume_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id) { int fs_information_class; @@ -256,39 +251,40 @@ void guac_rdpdr_fs_process_volume_info(guac_rdpdr_device* device, wStream* input switch (fs_information_class) { case FileFsVolumeInformation: - guac_rdpdr_fs_process_query_volume_info(device, input_stream, + guac_rdpdr_fs_process_query_volume_info(svc, device, input_stream, file_id, completion_id); break; case FileFsSizeInformation: - guac_rdpdr_fs_process_query_size_info(device, input_stream, + guac_rdpdr_fs_process_query_size_info(svc, device, input_stream, file_id, completion_id); break; case FileFsDeviceInformation: - guac_rdpdr_fs_process_query_device_info(device, input_stream, + guac_rdpdr_fs_process_query_device_info(svc, device, input_stream, file_id, completion_id); break; case FileFsAttributeInformation: - guac_rdpdr_fs_process_query_attribute_info(device, input_stream, - file_id, completion_id); + guac_rdpdr_fs_process_query_attribute_info(svc, device, + input_stream, file_id, completion_id); break; case FileFsFullSizeInformation: - guac_rdpdr_fs_process_query_full_size_info(device, input_stream, - file_id, completion_id); + guac_rdpdr_fs_process_query_full_size_info(svc, device, + input_stream, file_id, completion_id); break; default: - guac_client_log(device->rdpdr->client, GUAC_LOG_INFO, + guac_client_log(svc->client, GUAC_LOG_INFO, "Unknown volume information class: 0x%x", fs_information_class); } } -void guac_rdpdr_fs_process_file_info(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id) { +void guac_rdpdr_fs_process_file_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id) { int fs_information_class; @@ -298,45 +294,45 @@ void guac_rdpdr_fs_process_file_info(guac_rdpdr_device* device, wStream* input_s switch (fs_information_class) { case FileBasicInformation: - guac_rdpdr_fs_process_query_basic_info(device, input_stream, + guac_rdpdr_fs_process_query_basic_info(svc, device, input_stream, file_id, completion_id); break; case FileStandardInformation: - guac_rdpdr_fs_process_query_standard_info(device, input_stream, - file_id, completion_id); + guac_rdpdr_fs_process_query_standard_info(svc, device, + input_stream, file_id, completion_id); break; case FileAttributeTagInformation: - guac_rdpdr_fs_process_query_attribute_tag_info(device, input_stream, - file_id, completion_id); + guac_rdpdr_fs_process_query_attribute_tag_info(svc, device, + input_stream, file_id, completion_id); break; default: - guac_client_log(device->rdpdr->client, GUAC_LOG_INFO, + guac_client_log(svc->client, GUAC_LOG_INFO, "Unknown file information class: 0x%x", fs_information_class); } } -void guac_rdpdr_fs_process_set_volume_info(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id) { +void guac_rdpdr_fs_process_set_volume_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id) { wStream* output_stream = guac_rdpdr_new_io_completion(device, completion_id, STATUS_NOT_SUPPORTED, 0); - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i] Set volume info not supported", __func__, file_id); - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_set_file_info(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id) { +void guac_rdpdr_fs_process_set_file_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id) { int fs_information_class; int length; @@ -349,68 +345,69 @@ void guac_rdpdr_fs_process_set_file_info(guac_rdpdr_device* device, switch (fs_information_class) { case FileBasicInformation: - guac_rdpdr_fs_process_set_basic_info(device, input_stream, + guac_rdpdr_fs_process_set_basic_info(svc, device, input_stream, file_id, completion_id, length); break; case FileEndOfFileInformation: - guac_rdpdr_fs_process_set_end_of_file_info(device, input_stream, - file_id, completion_id, length); + guac_rdpdr_fs_process_set_end_of_file_info(svc, device, + input_stream, file_id, completion_id, length); break; case FileDispositionInformation: - guac_rdpdr_fs_process_set_disposition_info(device, input_stream, - file_id, completion_id, length); + guac_rdpdr_fs_process_set_disposition_info(svc, device, + input_stream, file_id, completion_id, length); break; case FileRenameInformation: - guac_rdpdr_fs_process_set_rename_info(device, input_stream, + guac_rdpdr_fs_process_set_rename_info(svc, device, input_stream, file_id, completion_id, length); break; case FileAllocationInformation: - guac_rdpdr_fs_process_set_allocation_info(device, input_stream, - file_id, completion_id, length); + guac_rdpdr_fs_process_set_allocation_info(svc, device, + input_stream, file_id, completion_id, length); break; default: - guac_client_log(device->rdpdr->client, GUAC_LOG_INFO, + guac_client_log(svc->client, GUAC_LOG_INFO, "Unknown file information class: 0x%x", fs_information_class); } } -void guac_rdpdr_fs_process_device_control(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id) { +void guac_rdpdr_fs_process_device_control(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id) { wStream* output_stream = guac_rdpdr_new_io_completion(device, completion_id, STATUS_INVALID_PARAMETER, 4); - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i] IGNORED", __func__, file_id); /* No content for now */ Stream_Write_UINT32(output_stream, 0); - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_notify_change_directory(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id) { +void guac_rdpdr_fs_process_notify_change_directory(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id) { - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i] Not implemented", __func__, file_id); } -void guac_rdpdr_fs_process_query_directory(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id) { +void guac_rdpdr_fs_process_query_directory(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id) { wStream* output_stream; @@ -441,7 +438,7 @@ void guac_rdpdr_fs_process_query_directory(guac_rdpdr_device* device, wStream* i } - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i] initial_query=%i, dir_pattern=\"%s\"", __func__, file_id, initial_query, file->dir_pattern); @@ -470,27 +467,29 @@ void guac_rdpdr_fs_process_query_directory(guac_rdpdr_device* device, wStream* i switch (fs_information_class) { case FileDirectoryInformation: - guac_rdpdr_fs_process_query_directory_info(device, + guac_rdpdr_fs_process_query_directory_info(svc, device, entry_name, entry_file_id, completion_id); break; case FileFullDirectoryInformation: - guac_rdpdr_fs_process_query_full_directory_info(device, - entry_name, entry_file_id, completion_id); + guac_rdpdr_fs_process_query_full_directory_info(svc, + device, entry_name, entry_file_id, + completion_id); break; case FileBothDirectoryInformation: - guac_rdpdr_fs_process_query_both_directory_info(device, - entry_name, entry_file_id, completion_id); + guac_rdpdr_fs_process_query_both_directory_info(svc, + device, entry_name, entry_file_id, + completion_id); break; case FileNamesInformation: - guac_rdpdr_fs_process_query_names_info(device, + guac_rdpdr_fs_process_query_names_info(svc, device, entry_name, entry_file_id, completion_id); break; default: - guac_client_log(device->rdpdr->client, GUAC_LOG_INFO, + guac_client_log(svc->client, GUAC_LOG_INFO, "Unknown dir information class: 0x%x", fs_information_class); } @@ -512,27 +511,24 @@ 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 */ - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_lock_control(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id) { +void guac_rdpdr_fs_process_lock_control(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id) { wStream* output_stream = guac_rdpdr_new_io_completion(device, completion_id, STATUS_NOT_SUPPORTED, 5); - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i] Lock not supported", __func__, file_id); Stream_Zero(output_stream, 5); /* Padding */ - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.h b/src/protocols/rdp/rdpdr_fs_messages.h similarity index 58% rename from src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.h rename to src/protocols/rdp/rdpdr_fs_messages.h index af0c87e1..a2018f2d 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.h +++ b/src/protocols/rdp/rdpdr_fs_messages.h @@ -18,8 +18,8 @@ */ -#ifndef __GUAC_RDPDR_FS_MESSAGES_H -#define __GUAC_RDPDR_FS_MESSAGES_H +#ifndef GUAC_RDPDR_FS_MESSAGES_H +#define GUAC_RDPDR_FS_MESSAGES_H /** * Handlers for core drive I/O requests. Requests handled here may be simple @@ -30,8 +30,7 @@ */ #include "config.h" - -#include "rdpdr_service.h" +#include "rdpdr.h" #include @@ -39,33 +38,37 @@ * Handles a Server Create Drive Request. Despite its name, this request opens * a file. */ -void guac_rdpdr_fs_process_create(guac_rdpdr_device* device, - wStream* input_stream, int completion_id); +void guac_rdpdr_fs_process_create(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int completion_id); /** * Handles a Server Close Drive Reqiest. This request closes an open file. */ -void guac_rdpdr_fs_process_close(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id); +void guac_rdpdr_fs_process_close(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id); /** * Handles a Server Drive Read Request. This request reads from a file. */ -void guac_rdpdr_fs_process_read(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id); +void guac_rdpdr_fs_process_read(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id); /** * Handles a Server Drive Write Request. This request writes to a file. */ -void guac_rdpdr_fs_process_write(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id); +void guac_rdpdr_fs_process_write(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id); /** * Handles a Server Drive Control Request. This request handles one of any * number of Windows FSCTL_* control functions. */ -void guac_rdpdr_fs_process_device_control(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id); +void guac_rdpdr_fs_process_device_control(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id); /** * Handles a Server Drive Query Volume Information Request. This request @@ -73,53 +76,60 @@ void guac_rdpdr_fs_process_device_control(guac_rdpdr_device* device, wStream* in * has several query types which have their own handlers defined in a * separate file. */ -void guac_rdpdr_fs_process_volume_info(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id); +void guac_rdpdr_fs_process_volume_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id); /** * Handles a Server Drive Set Volume Information Request. Currently, this * RDPDR implementation does not support setting of volume information. */ -void guac_rdpdr_fs_process_set_volume_info(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id); +void guac_rdpdr_fs_process_set_volume_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id); /** * Handles a Server Drive Query Information Request. This request queries * information about a specific file. This request has several query types * which have their own handlers defined in a separate file. */ -void guac_rdpdr_fs_process_file_info(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id); +void guac_rdpdr_fs_process_file_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id); /** * Handles a Server Drive Set Information Request. This request sets * information about a specific file. Currently, this RDPDR implementation does * not support setting of file information. */ -void guac_rdpdr_fs_process_set_file_info(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id); +void guac_rdpdr_fs_process_set_file_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id); /** * Handles a Server Drive Query Directory Request. This request queries * information about a specific directory. This request has several query types * which have their own handlers defined in a separate file. */ -void guac_rdpdr_fs_process_query_directory(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id); +void guac_rdpdr_fs_process_query_directory(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id); /** * Handles a Server Drive NotifyChange Directory Request. This request requests * directory change notification. */ -void guac_rdpdr_fs_process_notify_change_directory(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id); +void guac_rdpdr_fs_process_notify_change_directory(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id); /** * Handles a Server Drive Lock Control Request. This request locks or unlocks * portions of a file. */ -void guac_rdpdr_fs_process_lock_control(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id); +void guac_rdpdr_fs_process_lock_control(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id); #endif diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_dir_info.c b/src/protocols/rdp/rdpdr_fs_messages_dir_info.c similarity index 80% rename from src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_dir_info.c rename to src/protocols/rdp/rdpdr_fs_messages_dir_info.c index 303e7af7..23626941 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_dir_info.c +++ b/src/protocols/rdp/rdpdr_fs_messages_dir_info.c @@ -18,8 +18,7 @@ */ #include "config.h" - -#include "rdpdr_service.h" +#include "rdpdr.h" #include "rdp_fs.h" #include "rdp_status.h" #include "unicode.h" @@ -29,8 +28,9 @@ #include -void guac_rdpdr_fs_process_query_directory_info(guac_rdpdr_device* device, - const char* entry_name, int file_id, int completion_id) { +void guac_rdpdr_fs_process_query_directory_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, const char* entry_name, int file_id, + int completion_id) { guac_rdp_fs_file* file; @@ -47,7 +47,7 @@ void guac_rdpdr_fs_process_query_directory_info(guac_rdpdr_device* device, if (file == NULL) return; - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i (entry_name=\"%s\")]", __func__, file_id, entry_name); @@ -71,14 +71,13 @@ 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); - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_query_full_directory_info(guac_rdpdr_device* device, - const char* entry_name, int file_id, int completion_id) { +void guac_rdpdr_fs_process_query_full_directory_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, const char* entry_name, int file_id, + int completion_id) { guac_rdp_fs_file* file; @@ -95,7 +94,7 @@ void guac_rdpdr_fs_process_query_full_directory_info(guac_rdpdr_device* device, if (file == NULL) return; - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i (entry_name=\"%s\")]", __func__, file_id, entry_name); @@ -120,14 +119,13 @@ 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); - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_query_both_directory_info(guac_rdpdr_device* device, - const char* entry_name, int file_id, int completion_id) { +void guac_rdpdr_fs_process_query_both_directory_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, const char* entry_name, int file_id, + int completion_id) { guac_rdp_fs_file* file; @@ -144,7 +142,7 @@ void guac_rdpdr_fs_process_query_both_directory_info(guac_rdpdr_device* device, if (file == NULL) return; - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i (entry_name=\"%s\")]", __func__, file_id, entry_name); @@ -173,14 +171,13 @@ 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); - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_query_names_info(guac_rdpdr_device* device, - const char* entry_name, int file_id, int completion_id) { +void guac_rdpdr_fs_process_query_names_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, const char* entry_name, int file_id, + int completion_id) { guac_rdp_fs_file* file; @@ -197,7 +194,7 @@ void guac_rdpdr_fs_process_query_names_info(guac_rdpdr_device* device, if (file == NULL) return; - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i (entry_name=\"%s\")]", __func__, file_id, entry_name); @@ -213,9 +210,7 @@ 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); - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_dir_info.h b/src/protocols/rdp/rdpdr_fs_messages_dir_info.h similarity index 68% rename from src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_dir_info.h rename to src/protocols/rdp/rdpdr_fs_messages_dir_info.h index 9e0fcaf6..8d493406 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_dir_info.h +++ b/src/protocols/rdp/rdpdr_fs_messages_dir_info.h @@ -18,8 +18,8 @@ */ -#ifndef __GUAC_RDPDR_FS_MESSAGES_DIR_INFO_H -#define __GUAC_RDPDR_FS_MESSAGES_DIR_INFO_H +#ifndef GUAC_RDPDR_FS_MESSAGES_DIR_INFO_H +#define GUAC_RDPDR_FS_MESSAGES_DIR_INFO_H /** * Handlers for directory queries received over the RDPDR channel via the @@ -30,8 +30,8 @@ */ #include "config.h" - -#include "rdpdr_service.h" +#include "common-svc.h" +#include "rdpdr.h" #include @@ -40,31 +40,35 @@ * documentation this is "defined as the file's name, time stamp, and size, or its * attributes." */ -void guac_rdpdr_fs_process_query_directory_info(guac_rdpdr_device* device, - const char* entry_name, int file_id, int completion_id); +void guac_rdpdr_fs_process_query_directory_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, const char* entry_name, int file_id, + int completion_id); /** * Processes a query request for FileFullDirectoryInformation. From the * documentation, this is "defined as all the basic information, plus extended * attribute size." */ -void guac_rdpdr_fs_process_query_full_directory_info(guac_rdpdr_device* device, - const char* entry_name, int file_id, int completion_id); +void guac_rdpdr_fs_process_query_full_directory_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, const char* entry_name, int file_id, + int completion_id); /** * Processes a query request for FileBothDirectoryInformation. From the * documentation, this absurdly-named request is "basic information plus * extended attribute size and short name about a file or directory." */ -void guac_rdpdr_fs_process_query_both_directory_info(guac_rdpdr_device* device, - const char* entry_name, int file_id, int completion_id); +void guac_rdpdr_fs_process_query_both_directory_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, const char* entry_name, int file_id, + int completion_id); /** * Processes a query request for FileNamesInformation. From the documentation, * this is "detailed information on the names of files in a directory." */ -void guac_rdpdr_fs_process_query_names_info(guac_rdpdr_device* device, - const char* entry_name, int file_id, int completion_id); +void guac_rdpdr_fs_process_query_names_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, const char* entry_name, int file_id, + int completion_id); #endif diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c b/src/protocols/rdp/rdpdr_fs_messages_file_info.c similarity index 67% rename from src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c rename to src/protocols/rdp/rdpdr_fs_messages_file_info.c index c69046cb..4395a2f3 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c +++ b/src/protocols/rdp/rdpdr_fs_messages_file_info.c @@ -18,8 +18,7 @@ */ #include "config.h" - -#include "rdpdr_service.h" +#include "rdpdr.h" #include "rdp_fs.h" #include "rdp_status.h" #include "unicode.h" @@ -31,8 +30,9 @@ #include #include -void guac_rdpdr_fs_process_query_basic_info(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id) { +void guac_rdpdr_fs_process_query_basic_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id) { wStream* output_stream; guac_rdp_fs_file* file; @@ -42,7 +42,7 @@ void guac_rdpdr_fs_process_query_basic_info(guac_rdpdr_device* device, wStream* if (file == NULL) return; - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i]", __func__, file_id); @@ -58,14 +58,13 @@ void guac_rdpdr_fs_process_query_basic_info(guac_rdpdr_device* device, wStream* /* Reserved field must not be sent */ - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_query_standard_info(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id) { +void guac_rdpdr_fs_process_query_standard_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id) { wStream* output_stream; guac_rdp_fs_file* file; @@ -76,7 +75,7 @@ void guac_rdpdr_fs_process_query_standard_info(guac_rdpdr_device* device, wStrea if (file == NULL) return; - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i]", __func__, file_id); @@ -95,14 +94,13 @@ void guac_rdpdr_fs_process_query_standard_info(guac_rdpdr_device* device, wStrea /* Reserved field must not be sent */ - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_query_attribute_tag_info(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id) { +void guac_rdpdr_fs_process_query_attribute_tag_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id) { wStream* output_stream; guac_rdp_fs_file* file; @@ -112,7 +110,7 @@ void guac_rdpdr_fs_process_query_attribute_tag_info(guac_rdpdr_device* device, if (file == NULL) return; - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i]", __func__, file_id); @@ -125,14 +123,13 @@ void guac_rdpdr_fs_process_query_attribute_tag_info(guac_rdpdr_device* device, /* Reserved field must not be sent */ - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_set_rename_info(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id, int length) { +void guac_rdpdr_fs_process_set_rename_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id, int length) { int result; int filename_length; @@ -148,7 +145,7 @@ void guac_rdpdr_fs_process_set_rename_info(guac_rdpdr_device* device, guac_rdp_utf16_to_utf8(Stream_Pointer(input_stream), filename_length/2, destination_path, sizeof(destination_path)); - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i] destination_path=\"%s\"", __func__, file_id, destination_path); @@ -163,7 +160,7 @@ void guac_rdpdr_fs_process_set_rename_info(guac_rdpdr_device* device, return; /* Initiate download, pretend move succeeded */ - guac_rdpdr_start_download(device, file->absolute_path); + guac_rdpdr_start_download(svc, device, file->absolute_path); output_stream = guac_rdpdr_new_io_completion(device, completion_id, STATUS_SUCCESS, 4); @@ -184,14 +181,13 @@ void guac_rdpdr_fs_process_set_rename_info(guac_rdpdr_device* device, } Stream_Write_UINT32(output_stream, length); - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_set_allocation_info(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id, int length) { +void guac_rdpdr_fs_process_set_allocation_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id, int length) { int result; UINT64 size; @@ -200,7 +196,7 @@ void guac_rdpdr_fs_process_set_allocation_info(guac_rdpdr_device* device, /* Read new size */ Stream_Read_UINT64(input_stream, size); /* AllocationSize */ - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i] size=%" PRIu64, __func__, file_id, (uint64_t) size); @@ -214,14 +210,13 @@ void guac_rdpdr_fs_process_set_allocation_info(guac_rdpdr_device* device, completion_id, STATUS_SUCCESS, 4); Stream_Write_UINT32(output_stream, length); - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_set_disposition_info(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id, int length) { +void guac_rdpdr_fs_process_set_disposition_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id, int length) { wStream* output_stream; @@ -234,20 +229,19 @@ void guac_rdpdr_fs_process_set_disposition_info(guac_rdpdr_device* device, output_stream = guac_rdpdr_new_io_completion(device, completion_id, STATUS_SUCCESS, 4); - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i]", __func__, file_id); Stream_Write_UINT32(output_stream, length); - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_set_end_of_file_info(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id, int length) { +void guac_rdpdr_fs_process_set_end_of_file_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id, int length) { int result; UINT64 size; @@ -256,7 +250,7 @@ void guac_rdpdr_fs_process_set_end_of_file_info(guac_rdpdr_device* device, /* Read new size */ Stream_Read_UINT64(input_stream, size); /* AllocationSize */ - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i] size=%" PRIu64, __func__, file_id, (uint64_t) size); @@ -270,14 +264,13 @@ 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); - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_set_basic_info(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id, int length) { +void guac_rdpdr_fs_process_set_basic_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id, int length) { wStream* output_stream = guac_rdpdr_new_io_completion(device, completion_id, STATUS_SUCCESS, 4); @@ -285,13 +278,11 @@ void guac_rdpdr_fs_process_set_basic_info(guac_rdpdr_device* device, /* Currently do nothing, just respond */ Stream_Write_UINT32(output_stream, length); - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i] IGNORED", __func__, file_id); - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.h b/src/protocols/rdp/rdpdr_fs_messages_file_info.h similarity index 61% rename from src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.h rename to src/protocols/rdp/rdpdr_fs_messages_file_info.h index de5559ad..56941d72 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.h +++ b/src/protocols/rdp/rdpdr_fs_messages_file_info.h @@ -18,8 +18,8 @@ */ -#ifndef __GUAC_RDPDR_FS_MESSAGES_FILE_INFO_H -#define __GUAC_RDPDR_FS_MESSAGES_FILE_INFO_H +#ifndef GUAC_RDPDR_FS_MESSAGES_FILE_INFO_H +#define GUAC_RDPDR_FS_MESSAGES_FILE_INFO_H /** * Handlers for file queries received over the RDPDR channel via the @@ -29,8 +29,8 @@ */ #include "config.h" - -#include "rdpdr_service.h" +#include "common-svc.h" +#include "rdpdr.h" #include @@ -39,59 +39,67 @@ * "used to query a file for the times of creation, last access, last write, * and change, in addition to file attribute information." */ -void guac_rdpdr_fs_process_query_basic_info(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id); +void guac_rdpdr_fs_process_query_basic_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id); /** * Processes a query for FileStandardInformation. From the documentation, this * is "used to query for file information such as allocation size, end-of-file * position, and number of links." */ -void guac_rdpdr_fs_process_query_standard_info(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id); +void guac_rdpdr_fs_process_query_standard_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id); /** * Processes a query for FileAttributeTagInformation. From the documentation * this is "used to query for file attribute and reparse tag information." */ -void guac_rdpdr_fs_process_query_attribute_tag_info(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id); +void guac_rdpdr_fs_process_query_attribute_tag_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id); /** * Process a set operation for FileRenameInformation. From the documentation, * this operation is used to rename a file. */ -void guac_rdpdr_fs_process_set_rename_info(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id, int length); +void guac_rdpdr_fs_process_set_rename_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id, int length); /** * Process a set operation for FileAllocationInformation. From the * documentation, this operation is used to set a file's allocation size. */ -void guac_rdpdr_fs_process_set_allocation_info(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id, int length); +void guac_rdpdr_fs_process_set_allocation_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id, int length); /** * Process a set operation for FileDispositionInformation. From the * documentation, this operation is used to mark a file for deletion. */ -void guac_rdpdr_fs_process_set_disposition_info(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id, int length); +void guac_rdpdr_fs_process_set_disposition_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id, int length); /** * Process a set operation for FileEndOfFileInformation. From the * documentation, this operation is used "to set end-of-file information for * a file." */ -void guac_rdpdr_fs_process_set_end_of_file_info(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id, int length); +void guac_rdpdr_fs_process_set_end_of_file_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id, int length); /** * Process a set operation for FileBasicInformation. From the documentation, * this is "used to set file information such as the times of creation, last * access, last write, and change, in addition to file attributes." */ -void guac_rdpdr_fs_process_set_basic_info(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id, int length); +void guac_rdpdr_fs_process_set_basic_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id, int length); #endif diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_vol_info.c b/src/protocols/rdp/rdpdr_fs_messages_vol_info.c similarity index 66% rename from src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_vol_info.c rename to src/protocols/rdp/rdpdr_fs_messages_vol_info.c index 1cc051f0..dc3a5e10 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_vol_info.c +++ b/src/protocols/rdp/rdpdr_fs_messages_vol_info.c @@ -18,9 +18,8 @@ */ #include "config.h" - +#include "rdpdr.h" #include "rdpdr_messages.h" -#include "rdpdr_service.h" #include "rdp_fs.h" #include "rdp_status.h" @@ -28,13 +27,14 @@ #include #include -void guac_rdpdr_fs_process_query_volume_info(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id) { +void guac_rdpdr_fs_process_query_volume_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id) { wStream* output_stream = guac_rdpdr_new_io_completion(device, completion_id, STATUS_SUCCESS, 21 + GUAC_FILESYSTEM_LABEL_LENGTH); - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i]", __func__, file_id); @@ -46,14 +46,13 @@ 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); - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_query_size_info(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id) { +void guac_rdpdr_fs_process_query_size_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id) { guac_rdp_fs_info info = {0}; guac_rdp_fs_get_info((guac_rdp_fs*) device->data, &info); @@ -61,7 +60,7 @@ void guac_rdpdr_fs_process_query_size_info(guac_rdpdr_device* device, wStream* i wStream* output_stream = guac_rdpdr_new_io_completion(device, completion_id, STATUS_SUCCESS, 28); - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i]", __func__, file_id); @@ -71,19 +70,18 @@ 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 */ - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_query_device_info(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id) { +void guac_rdpdr_fs_process_query_device_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id) { wStream* output_stream = guac_rdpdr_new_io_completion(device, completion_id, STATUS_SUCCESS, 12); - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i]", __func__, file_id); @@ -91,21 +89,20 @@ 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 */ - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_query_attribute_info(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id) { +void guac_rdpdr_fs_process_query_attribute_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id) { int name_len = guac_utf8_strlen(device->device_name); wStream* output_stream = guac_rdpdr_new_io_completion(device, completion_id, STATUS_SUCCESS, 16 + name_len); - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i]", __func__, file_id); @@ -118,14 +115,13 @@ 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); - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_fs_process_query_full_size_info(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id) { +void guac_rdpdr_fs_process_query_full_size_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id) { guac_rdp_fs_info info = {0}; guac_rdp_fs_get_info((guac_rdp_fs*) device->data, &info); @@ -133,7 +129,7 @@ void guac_rdpdr_fs_process_query_full_size_info(guac_rdpdr_device* device, wStre wStream* output_stream = guac_rdpdr_new_io_completion(device, completion_id, STATUS_SUCCESS, 36); - guac_client_log(device->rdpdr->client, GUAC_LOG_DEBUG, + guac_client_log(svc->client, GUAC_LOG_DEBUG, "%s: [file_id=%i]", __func__, file_id); @@ -144,9 +140,7 @@ 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 */ - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_vol_info.h b/src/protocols/rdp/rdpdr_fs_messages_vol_info.h similarity index 61% rename from src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_vol_info.h rename to src/protocols/rdp/rdpdr_fs_messages_vol_info.h index b0e3629f..1c34127e 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_vol_info.h +++ b/src/protocols/rdp/rdpdr_fs_messages_vol_info.h @@ -18,8 +18,8 @@ */ -#ifndef __GUAC_RDPDR_FS_MESSAGES_VOL_INFO_H -#define __GUAC_RDPDR_FS_MESSAGES_VOL_INFO_H +#ifndef GUAC_RDPDR_FS_MESSAGES_VOL_INFO_H +#define GUAC_RDPDR_FS_MESSAGES_VOL_INFO_H /** * Handlers for directory queries received over the RDPDR channel via the @@ -30,8 +30,7 @@ */ #include "config.h" - -#include "rdpdr_service.h" +#include "rdpdr.h" #include @@ -40,32 +39,37 @@ * documentation, this is "used to query information for a volume on which a * file system is mounted." */ -void guac_rdpdr_fs_process_query_volume_info(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id); +void guac_rdpdr_fs_process_query_volume_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id); /** * Processes a query request for FileFsSizeInformation. */ -void guac_rdpdr_fs_process_query_size_info(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id); +void guac_rdpdr_fs_process_query_size_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id); /** * Processes a query request for FileFsAttributeInformation. */ -void guac_rdpdr_fs_process_query_attribute_info(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id); +void guac_rdpdr_fs_process_query_attribute_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id); /** * Processes a query request for FileFsFullSizeInformation. */ -void guac_rdpdr_fs_process_query_full_size_info(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id); +void guac_rdpdr_fs_process_query_full_size_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id); /** * Processes a query request for FileFsDeviceInformation. */ -void guac_rdpdr_fs_process_query_device_info(guac_rdpdr_device* device, wStream* input_stream, - int file_id, int completion_id); +void guac_rdpdr_fs_process_query_device_info(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id); #endif diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.c b/src/protocols/rdp/rdpdr_fs_service.c similarity index 65% rename from src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.c rename to src/protocols/rdp/rdpdr_fs_service.c index 187bf9c4..d0532022 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.c +++ b/src/protocols/rdp/rdpdr_fs_service.c @@ -19,11 +19,10 @@ #include "config.h" - #include "rdp.h" +#include "rdpdr.h" #include "rdpdr_fs_messages.h" #include "rdpdr_messages.h" -#include "rdpdr_service.h" #include #include @@ -31,99 +30,114 @@ #include #include -static void guac_rdpdr_device_fs_iorequest_handler(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id, int major_func, int minor_func) { +static void guac_rdpdr_device_fs_iorequest_handler(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id, int major_func, int minor_func) { switch (major_func) { /* File open */ case IRP_MJ_CREATE: - guac_rdpdr_fs_process_create(device, input_stream, completion_id); + guac_rdpdr_fs_process_create(svc, device, input_stream, + completion_id); break; /* File close */ case IRP_MJ_CLOSE: - guac_rdpdr_fs_process_close(device, input_stream, file_id, completion_id); + guac_rdpdr_fs_process_close(svc, device, input_stream, file_id, + completion_id); break; /* File read */ case IRP_MJ_READ: - guac_rdpdr_fs_process_read(device, input_stream, file_id, completion_id); + guac_rdpdr_fs_process_read(svc, device, input_stream, file_id, + completion_id); break; /* File write */ case IRP_MJ_WRITE: - guac_rdpdr_fs_process_write(device, input_stream, file_id, completion_id); + guac_rdpdr_fs_process_write(svc, device, input_stream, file_id, + completion_id); break; /* Device control request (Windows FSCTL_ control codes) */ case IRP_MJ_DEVICE_CONTROL: - guac_rdpdr_fs_process_device_control(device, input_stream, file_id, completion_id); + guac_rdpdr_fs_process_device_control(svc, device, input_stream, + file_id, completion_id); break; /* Query volume (drive) information */ case IRP_MJ_QUERY_VOLUME_INFORMATION: - guac_rdpdr_fs_process_volume_info(device, input_stream, file_id, completion_id); + guac_rdpdr_fs_process_volume_info(svc, device, input_stream, + file_id, completion_id); break; /* Set volume (drive) information */ case IRP_MJ_SET_VOLUME_INFORMATION: - guac_rdpdr_fs_process_set_volume_info(device, input_stream, file_id, completion_id); + guac_rdpdr_fs_process_set_volume_info(svc, device, input_stream, + file_id, completion_id); break; /* Query file information */ case IRP_MJ_QUERY_INFORMATION: - guac_rdpdr_fs_process_file_info(device, input_stream, file_id, completion_id); + guac_rdpdr_fs_process_file_info(svc, device, input_stream, file_id, + completion_id); break; /* Set file information */ case IRP_MJ_SET_INFORMATION: - guac_rdpdr_fs_process_set_file_info(device, input_stream, file_id, completion_id); + guac_rdpdr_fs_process_set_file_info(svc, device, input_stream, + file_id, completion_id); break; case IRP_MJ_DIRECTORY_CONTROL: /* Enumerate directory contents */ if (minor_func == IRP_MN_QUERY_DIRECTORY) - guac_rdpdr_fs_process_query_directory(device, input_stream, file_id, completion_id); + guac_rdpdr_fs_process_query_directory(svc, device, + input_stream, file_id, completion_id); /* Request notification of changes to directory */ else if (minor_func == IRP_MN_NOTIFY_CHANGE_DIRECTORY) - guac_rdpdr_fs_process_notify_change_directory(device, input_stream, + guac_rdpdr_fs_process_notify_change_directory(svc, device, + input_stream, file_id, completion_id); break; /* Lock/unlock portions of a file */ case IRP_MJ_LOCK_CONTROL: - guac_rdpdr_fs_process_lock_control(device, input_stream, file_id, completion_id); + guac_rdpdr_fs_process_lock_control(svc, device, input_stream, + file_id, completion_id); break; default: - guac_client_log(device->rdpdr->client, GUAC_LOG_ERROR, + guac_client_log(svc->client, GUAC_LOG_ERROR, "Unknown filesystem I/O request function: 0x%x/0x%x", major_func, minor_func); } } -static void guac_rdpdr_device_fs_free_handler(guac_rdpdr_device* device) { +static void guac_rdpdr_device_fs_free_handler(guac_rdp_common_svc* svc, + guac_rdpdr_device* device) { Stream_Free(device->device_announce, 1); } -void guac_rdpdr_register_fs(guac_rdpdr* rdpdr, char* drive_name) { +void guac_rdpdr_register_fs(guac_rdp_common_svc* svc, char* drive_name) { - guac_client* client = rdpdr->client; + guac_client* client = svc->client; guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; + + guac_rdpdr* rdpdr = (guac_rdpdr*) svc->data; int id = rdpdr->devices_registered++; /* Get new device */ guac_rdpdr_device* device = &(rdpdr->devices[id]); /* Init device */ - device->rdpdr = rdpdr; device->device_id = id; device->device_name = drive_name; int device_name_len = guac_utf8_strlen(device->device_name); diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.h b/src/protocols/rdp/rdpdr_fs_service.h similarity index 91% rename from src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.h rename to src/protocols/rdp/rdpdr_fs_service.h index af44ac8b..a3775f95 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.h +++ b/src/protocols/rdp/rdpdr_fs_service.h @@ -18,8 +18,8 @@ */ -#ifndef __GUAC_RDPDR_FS_H -#define __GUAC_RDPDR_FS_H +#ifndef GUAC_RDPDR_FS_H +#define GUAC_RDPDR_FS_H /** * Functions and macros specific to filesystem handling and initialization @@ -33,8 +33,7 @@ */ #include "config.h" - -#include "rdpdr_service.h" +#include "rdpdr.h" #include @@ -48,7 +47,7 @@ * @param drive_name * The name of the redirected drive to display in the RDP connection. */ -void guac_rdpdr_register_fs(guac_rdpdr* rdpdr, char* drive_name); +void guac_rdpdr_register_fs(guac_rdp_common_svc* svc, char* drive_name); #endif diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_messages.c b/src/protocols/rdp/rdpdr_messages.c similarity index 68% rename from src/protocols/rdp/guac_rdpdr/rdpdr_messages.c rename to src/protocols/rdp/rdpdr_messages.c index d300ccaf..8be7c43e 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_messages.c +++ b/src/protocols/rdp/rdpdr_messages.c @@ -18,10 +18,9 @@ */ #include "config.h" - #include "rdp.h" +#include "rdpdr.h" #include "rdpdr_messages.h" -#include "rdpdr_service.h" #include "unicode.h" #include @@ -31,7 +30,7 @@ #include #include -static void guac_rdpdr_send_client_announce_reply(guac_rdpdr* rdpdr, +static void guac_rdpdr_send_client_announce_reply(guac_rdp_common_svc* svc, unsigned int major, unsigned int minor, unsigned int client_id) { wStream* output_stream = Stream_New(NULL, 12); @@ -45,13 +44,12 @@ static void guac_rdpdr_send_client_announce_reply(guac_rdpdr* rdpdr, Stream_Write_UINT16(output_stream, minor); Stream_Write_UINT32(output_stream, client_id); - rdpdr->entry_points.pVirtualChannelWriteEx(rdpdr->init_handle, - rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -static void guac_rdpdr_send_client_name_request(guac_rdpdr* rdpdr, const char* name) { +static void guac_rdpdr_send_client_name_request(guac_rdp_common_svc* svc, + const char* name) { int name_bytes = strlen(name) + 1; wStream* output_stream = Stream_New(NULL, 16 + name_bytes); @@ -66,16 +64,14 @@ static void guac_rdpdr_send_client_name_request(guac_rdpdr* rdpdr, const char* n Stream_Write_UINT32(output_stream, name_bytes); Stream_Write(output_stream, name, name_bytes); - rdpdr->entry_points.pVirtualChannelWriteEx(rdpdr->init_handle, - rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -static void guac_rdpdr_send_client_capability(guac_rdpdr* rdpdr) { +static void guac_rdpdr_send_client_capability(guac_rdp_common_svc* svc) { wStream* output_stream = Stream_New(NULL, 256); - guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Sending capabilities..."); + guac_client_log(svc->client, GUAC_LOG_INFO, "Sending capabilities..."); /* Write header */ Stream_Write_UINT16(output_stream, RDPDR_CTYP_CORE); @@ -115,14 +111,14 @@ static void guac_rdpdr_send_client_capability(guac_rdpdr* rdpdr) { Stream_Write_UINT16(output_stream, 8); Stream_Write_UINT32(output_stream, DRIVE_CAPABILITY_VERSION_02); - 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."); + guac_rdp_common_svc_write(svc, output_stream); + guac_client_log(svc->client, GUAC_LOG_INFO, "Capabilities sent."); } -static void guac_rdpdr_send_client_device_list_announce_request(guac_rdpdr* rdpdr) { +static void guac_rdpdr_send_client_device_list_announce_request(guac_rdp_common_svc* svc) { + + guac_rdpdr* rdpdr = (guac_rdpdr*) svc->data; /* Calculate number of bytes needed for the stream */ int streamBytes = 16; @@ -144,19 +140,17 @@ static void guac_rdpdr_send_client_device_list_announce_request(guac_rdpdr* rdpd Stream_Buffer(rdpdr->devices[i].device_announce), rdpdr->devices[i].device_announce_len); - guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Registered device %i (%s)", + guac_client_log(svc->client, GUAC_LOG_INFO, "Registered device %i (%s)", rdpdr->devices[i].device_id, rdpdr->devices[i].device_name); } - 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."); + guac_rdp_common_svc_write(svc, output_stream); + guac_client_log(svc->client, GUAC_LOG_INFO, "All supported devices sent."); } -void guac_rdpdr_process_server_announce(guac_rdpdr* rdpdr, +void guac_rdpdr_process_server_announce(guac_rdp_common_svc* svc, wStream* input_stream) { unsigned int major, minor, client_id; @@ -169,21 +163,25 @@ void guac_rdpdr_process_server_announce(guac_rdpdr* rdpdr, if (minor < 12) client_id = random() & 0xFFFF; - guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Connected to RDPDR %u.%u as client 0x%04x", major, minor, client_id); + guac_client_log(svc->client, GUAC_LOG_INFO, "Connected to RDPDR %u.%u as client 0x%04x", major, minor, client_id); /* Respond to announce */ - guac_rdpdr_send_client_announce_reply(rdpdr, major, minor, client_id); + guac_rdpdr_send_client_announce_reply(svc, major, minor, client_id); /* Name request */ - guac_rdpdr_send_client_name_request(rdpdr, ((guac_rdp_client *)rdpdr->client->data)->settings->client_name); + guac_rdpdr_send_client_name_request(svc, ((guac_rdp_client*) svc->client->data)->settings->client_name); } -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_clientid_confirm(guac_rdp_common_svc* svc, + wStream* input_stream) { + guac_client_log(svc->client, GUAC_LOG_INFO, "Client ID confirmed"); } -void guac_rdpdr_process_device_reply(guac_rdpdr* rdpdr, wStream* input_stream) { +void guac_rdpdr_process_device_reply(guac_rdp_common_svc* svc, + wStream* input_stream) { + + guac_rdpdr* rdpdr = (guac_rdpdr*) svc->data; unsigned int device_id, ntstatus; int severity, c, n, facility, code; @@ -201,11 +199,11 @@ void guac_rdpdr_process_device_reply(guac_rdpdr* rdpdr, wStream* input_stream) { if (device_id < rdpdr->devices_registered) { if (severity == 0x0) - guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Device %i (%s) connected successfully", + guac_client_log(svc->client, GUAC_LOG_INFO, "Device %i (%s) connected successfully", device_id, rdpdr->devices[device_id].device_name); else - guac_client_log(rdpdr->client, GUAC_LOG_ERROR, "Problem connecting device %i (%s): " + guac_client_log(svc->client, GUAC_LOG_ERROR, "Problem connecting device %i (%s): " "severity=0x%x, c=0x%x, n=0x%x, facility=0x%x, code=0x%x", device_id, rdpdr->devices[device_id].device_name, severity, c, n, facility, code); @@ -213,11 +211,14 @@ void guac_rdpdr_process_device_reply(guac_rdpdr* rdpdr, wStream* input_stream) { } else - guac_client_log(rdpdr->client, GUAC_LOG_ERROR, "Unknown device ID: 0x%08x", device_id); + guac_client_log(svc->client, GUAC_LOG_ERROR, "Unknown device ID: 0x%08x", device_id); } -void guac_rdpdr_process_device_iorequest(guac_rdpdr* rdpdr, wStream* input_stream) { +void guac_rdpdr_process_device_iorequest(guac_rdp_common_svc* svc, + wStream* input_stream) { + + guac_rdpdr* rdpdr = (guac_rdpdr*) svc->data; int device_id, file_id, completion_id, major_func, minor_func; @@ -233,17 +234,18 @@ void guac_rdpdr_process_device_iorequest(guac_rdpdr* rdpdr, wStream* input_strea /* Call handler on device */ guac_rdpdr_device* device = &(rdpdr->devices[device_id]); - device->iorequest_handler(device, input_stream, + device->iorequest_handler(svc, device, input_stream, file_id, completion_id, major_func, minor_func); } else - guac_client_log(rdpdr->client, GUAC_LOG_ERROR, "Unknown device ID: 0x%08x", device_id); + guac_client_log(svc->client, GUAC_LOG_ERROR, "Unknown device ID: 0x%08x", device_id); } -void guac_rdpdr_process_server_capability(guac_rdpdr* rdpdr, wStream* input_stream) { +void guac_rdpdr_process_server_capability(guac_rdp_common_svc* svc, + wStream* input_stream) { int count; int i; @@ -262,27 +264,30 @@ void guac_rdpdr_process_server_capability(guac_rdpdr* rdpdr, wStream* input_stre Stream_Read_UINT16(input_stream, length); /* Ignore all for now */ - guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Ignoring server capability set type=0x%04x, length=%i", type, length); + guac_client_log(svc->client, GUAC_LOG_INFO, "Ignoring server capability set type=0x%04x, length=%i", type, length); Stream_Seek(input_stream, length - 4); } /* Send own capabilities */ - guac_rdpdr_send_client_capability(rdpdr); + guac_rdpdr_send_client_capability(svc); } -void guac_rdpdr_process_user_loggedon(guac_rdpdr* rdpdr, wStream* input_stream) { +void guac_rdpdr_process_user_loggedon(guac_rdp_common_svc* svc, + wStream* input_stream) { - guac_client_log(rdpdr->client, GUAC_LOG_INFO, "User logged on"); - guac_rdpdr_send_client_device_list_announce_request(rdpdr); + guac_client_log(svc->client, GUAC_LOG_INFO, "User logged on"); + guac_rdpdr_send_client_device_list_announce_request(svc); } -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_cache_data(guac_rdp_common_svc* svc, + wStream* input_stream) { + guac_client_log(svc->client, GUAC_LOG_INFO, "Ignoring printer cached configuration data"); } -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"); +void guac_rdpdr_process_prn_using_xps(guac_rdp_common_svc* svc, + wStream* input_stream) { + guac_client_log(svc->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/rdpdr_messages.h similarity index 87% rename from src/protocols/rdp/guac_rdpdr/rdpdr_messages.h rename to src/protocols/rdp/rdpdr_messages.h index 451554e4..19c7aaa2 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_messages.h +++ b/src/protocols/rdp/rdpdr_messages.h @@ -18,12 +18,11 @@ */ -#ifndef __GUAC_RDPDR_MESSAGES_H -#define __GUAC_RDPDR_MESSAGES_H +#ifndef GUAC_RDPDR_MESSAGES_H +#define GUAC_RDPDR_MESSAGES_H #include "config.h" - -#include "rdpdr_service.h" +#include "rdpdr.h" #include @@ -204,14 +203,14 @@ * Message handlers. */ -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); +void guac_rdpdr_process_server_announce(guac_rdp_common_svc* svc, wStream* input_stream); +void guac_rdpdr_process_clientid_confirm(guac_rdp_common_svc* svc, wStream* input_stream); +void guac_rdpdr_process_device_reply(guac_rdp_common_svc* svc, wStream* input_stream); +void guac_rdpdr_process_device_iorequest(guac_rdp_common_svc* svc, wStream* input_stream); +void guac_rdpdr_process_server_capability(guac_rdp_common_svc* svc, wStream* input_stream); +void guac_rdpdr_process_user_loggedon(guac_rdp_common_svc* svc, wStream* input_stream); +void guac_rdpdr_process_prn_cache_data(guac_rdp_common_svc* svc, wStream* input_stream); +void guac_rdpdr_process_prn_using_xps(guac_rdp_common_svc* svc, wStream* input_stream); #endif diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_printer.c b/src/protocols/rdp/rdpdr_printer.c similarity index 76% rename from src/protocols/rdp/guac_rdpdr/rdpdr_printer.c rename to src/protocols/rdp/rdpdr_printer.c index 98a3eccb..dbe16de3 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_printer.c +++ b/src/protocols/rdp/rdpdr_printer.c @@ -18,10 +18,9 @@ */ #include "config.h" - +#include "rdpdr.h" #include "rdpdr_messages.h" #include "rdpdr_printer.h" -#include "rdpdr_service.h" #include "rdp.h" #include "rdp_print_job.h" #include "rdp_status.h" @@ -42,10 +41,10 @@ #include #include -void guac_rdpdr_process_print_job_create(guac_rdpdr_device* device, - wStream* input_stream, int completion_id) { +void guac_rdpdr_process_print_job_create(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int completion_id) { - guac_client* client = device->rdpdr->client; + guac_client* client = svc->client; guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; /* Log creation of print job */ @@ -60,16 +59,14 @@ void guac_rdpdr_process_print_job_create(guac_rdpdr_device* device, completion_id, STATUS_SUCCESS, 4); Stream_Write_UINT32(output_stream, 0); /* fileId */ - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_process_print_job_write(guac_rdpdr_device* device, - wStream* input_stream, int completion_id) { +void guac_rdpdr_process_print_job_write(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int completion_id) { - guac_client* client = device->rdpdr->client; + guac_client* client = svc->client; guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; guac_rdp_print_job* job = (guac_rdp_print_job*) rdp_client->active_job; @@ -101,16 +98,14 @@ void guac_rdpdr_process_print_job_write(guac_rdpdr_device* device, Stream_Write_UINT32(output_stream, length); Stream_Write_UINT8(output_stream, 0); /* Padding */ - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); } -void guac_rdpdr_process_print_job_close(guac_rdpdr_device* device, - wStream* input_stream, int completion_id) { +void guac_rdpdr_process_print_job_close(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int completion_id) { - guac_client* client = device->rdpdr->client; + guac_client* client = svc->client; guac_rdp_client* rdp_client = (guac_rdp_client*) client->data; guac_rdp_print_job* job = (guac_rdp_print_job*) rdp_client->active_job; @@ -124,38 +119,40 @@ void guac_rdpdr_process_print_job_close(guac_rdpdr_device* device, completion_id, STATUS_SUCCESS, 4); Stream_Write_UINT32(output_stream, 0); /* Padding */ - device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle, - device->rdpdr->open_handle, Stream_Buffer(output_stream), - Stream_GetPosition(output_stream), output_stream); + guac_rdp_common_svc_write(svc, output_stream); /* Log end of print job */ guac_client_log(client, GUAC_LOG_INFO, "Print job closed"); } -static void guac_rdpdr_device_printer_iorequest_handler(guac_rdpdr_device* device, - wStream* input_stream, int file_id, int completion_id, int major_func, int minor_func) { +static void guac_rdpdr_device_printer_iorequest_handler(guac_rdp_common_svc* svc, + guac_rdpdr_device* device, wStream* input_stream, int file_id, + int completion_id, int major_func, int minor_func) { switch (major_func) { /* Print job create */ case IRP_MJ_CREATE: - guac_rdpdr_process_print_job_create(device, input_stream, completion_id); + guac_rdpdr_process_print_job_create(svc, device, input_stream, + completion_id); break; /* Printer job write */ case IRP_MJ_WRITE: - guac_rdpdr_process_print_job_write(device, input_stream, completion_id); + guac_rdpdr_process_print_job_write(svc, device, input_stream, + completion_id); break; /* Printer job close */ case IRP_MJ_CLOSE: - guac_rdpdr_process_print_job_close(device, input_stream, completion_id); + guac_rdpdr_process_print_job_close(svc, device, input_stream, + completion_id); break; /* Log unknown */ default: - guac_client_log(device->rdpdr->client, GUAC_LOG_ERROR, + guac_client_log(svc->client, GUAC_LOG_ERROR, "Unknown printer I/O request function: 0x%x/0x%x", major_func, minor_func); @@ -163,21 +160,22 @@ static void guac_rdpdr_device_printer_iorequest_handler(guac_rdpdr_device* devic } -static void guac_rdpdr_device_printer_free_handler(guac_rdpdr_device* device) { +static void guac_rdpdr_device_printer_free_handler(guac_rdp_common_svc* svc, + guac_rdpdr_device* device) { Stream_Free(device->device_announce, 1); } -void guac_rdpdr_register_printer(guac_rdpdr* rdpdr, char* printer_name) { +void guac_rdpdr_register_printer(guac_rdp_common_svc* svc, char* printer_name) { + guac_rdpdr* rdpdr = (guac_rdpdr*) svc->data; int id = rdpdr->devices_registered++; /* Get new device */ guac_rdpdr_device* device = &(rdpdr->devices[id]); /* Init device */ - device->rdpdr = rdpdr; device->device_id = id; device->device_name = printer_name; int device_name_len = guac_utf8_strlen(device->device_name); diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_printer.h b/src/protocols/rdp/rdpdr_printer.h similarity index 88% rename from src/protocols/rdp/guac_rdpdr/rdpdr_printer.h rename to src/protocols/rdp/rdpdr_printer.h index 210d512c..c9b30ddc 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_printer.h +++ b/src/protocols/rdp/rdpdr_printer.h @@ -18,12 +18,11 @@ */ -#ifndef __GUAC_RDPDR_PRINTER_H -#define __GUAC_RDPDR_PRINTER_H +#ifndef GUAC_RDPDR_PRINTER_H +#define GUAC_RDPDR_PRINTER_H #include "config.h" - -#include "rdpdr_service.h" +#include "rdpdr.h" #include @@ -38,7 +37,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_rdpdr* rdpdr, char* printer_name); +void guac_rdpdr_register_printer(guac_rdp_common_svc* svc, char* printer_name); #endif