From aacb726b663ad3a2a5c50a6b1022c95434dba35c Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Mon, 4 Nov 2013 00:50:10 -0800 Subject: [PATCH] Separate RDP filesystem operations from RDPDR. --- src/protocols/rdp/Makefile.am | 7 +- src/protocols/rdp/client.c | 8 +- src/protocols/rdp/client.h | 6 + src/protocols/rdp/guac_handlers.c | 4 + .../rdp/guac_rdpdr/rdpdr_fs_messages.c | 41 ++-- .../guac_rdpdr/rdpdr_fs_messages_dir_info.c | 7 +- .../guac_rdpdr/rdpdr_fs_messages_file_info.c | 22 +- .../guac_rdpdr/rdpdr_fs_messages_vol_info.c | 5 +- .../rdp/guac_rdpdr/rdpdr_fs_service.c | 11 +- .../rdp/guac_rdpdr/rdpdr_fs_service.h | 63 +++++ src/protocols/rdp/guac_rdpdr/rdpdr_messages.h | 24 -- src/protocols/rdp/guac_rdpdr/rdpdr_printer.c | 1 + src/protocols/rdp/guac_rdpdr/rdpdr_service.c | 2 +- .../rdp/{guac_rdpdr/rdpdr_fs.c => rdp_fs.c} | 215 +++++++++--------- .../rdp/{guac_rdpdr/rdpdr_fs.h => rdp_fs.h} | 108 +++++---- src/protocols/rdp/rdp_status.h | 69 ++++++ 16 files changed, 357 insertions(+), 236 deletions(-) create mode 100644 src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.h rename src/protocols/rdp/{guac_rdpdr/rdpdr_fs.c => rdp_fs.c} (69%) rename src/protocols/rdp/{guac_rdpdr/rdpdr_fs.h => rdp_fs.h} (76%) create mode 100644 src/protocols/rdp/rdp_status.h diff --git a/src/protocols/rdp/Makefile.am b/src/protocols/rdp/Makefile.am index 0e0e58b9..85067f43 100644 --- a/src/protocols/rdp/Makefile.am +++ b/src/protocols/rdp/Makefile.am @@ -47,6 +47,7 @@ libguac_client_rdp_la_SOURCES = \ guac_handlers.c \ rdp_bitmap.c \ rdp_cliprdr.c \ + rdp_fs.c \ rdp_gdi.c \ rdp_glyph.c \ rdp_keymap_base.c \ @@ -64,7 +65,6 @@ guacsnd_sources = \ guac_rdpsnd/rdpsnd_service.c guacdr_sources = \ - guac_rdpdr/rdpdr_fs.c \ guac_rdpdr/rdpdr_fs_messages.c \ guac_rdpdr/rdpdr_fs_messages_dir_info.c \ guac_rdpdr/rdpdr_fs_messages_file_info.c \ @@ -73,15 +73,16 @@ guacdr_sources = \ guac_rdpdr/rdpdr_messages.c \ guac_rdpdr/rdpdr_printer.c \ guac_rdpdr/rdpdr_service.c \ + rdp_fs.c \ unicode.c noinst_HEADERS = \ compat/client-cliprdr.h \ - guac_rdpdr/rdpdr_fs.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 \ @@ -94,11 +95,13 @@ noinst_HEADERS = \ guac_handlers.h \ rdp_bitmap.h \ rdp_cliprdr.h \ + rdp_fs.h \ rdp_gdi.h \ rdp_glyph.h \ rdp_keymap.h \ rdp_pointer.h \ rdp_settings.h \ + rdp_status.h \ unicode.h # Add compatibility layer for WinPR if not available diff --git a/src/protocols/rdp/client.c b/src/protocols/rdp/client.c index f61d21a2..e8a0ef0f 100644 --- a/src/protocols/rdp/client.c +++ b/src/protocols/rdp/client.c @@ -184,6 +184,12 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) { } /* end if audio enabled */ + /* Load filesystem if drive enabled */ + if (guac_client_data->settings.drive_enabled) { + guac_client_data->filesystem = + guac_rdp_fs_alloc(guac_client_data->settings.drive_path); + } + /* If RDPDR required, load it */ if (guac_client_data->settings.printing_enabled || guac_client_data->settings.drive_enabled) { @@ -546,7 +552,6 @@ int guac_client_init(guac_client* client, int argc, char** argv) { guac_client_data->settings.drive_enabled = (strcmp(argv[IDX_ENABLE_DRIVE], "true") == 0); - /* Drive enable/disable */ guac_client_data->settings.drive_path = strdup(argv[IDX_DRIVE_PATH]); /* Store client data */ @@ -556,6 +561,7 @@ int guac_client_init(guac_client* client, int argc, char** argv) { guac_client_data->current_surface = GUAC_DEFAULT_LAYER; guac_client_data->clipboard = NULL; guac_client_data->audio = NULL; + guac_client_data->filesystem = NULL; /* Main socket needs to be threadsafe */ guac_socket_require_threadsafe(client->socket); diff --git a/src/protocols/rdp/client.h b/src/protocols/rdp/client.h index 5950b539..d28da7a1 100644 --- a/src/protocols/rdp/client.h +++ b/src/protocols/rdp/client.h @@ -48,6 +48,7 @@ #include #include +#include "rdp_fs.h" #include "rdp_keymap.h" #include "rdp_settings.h" @@ -168,6 +169,11 @@ typedef struct rdp_guac_client_data { */ guac_audio_stream* audio; + /** + * The filesystem being shared, if any. + */ + guac_rdp_fs* filesystem; + /** * Lock which is locked and unlocked for each RDP message. */ diff --git a/src/protocols/rdp/guac_handlers.c b/src/protocols/rdp/guac_handlers.c index b68f3c11..20583a7c 100644 --- a/src/protocols/rdp/guac_handlers.c +++ b/src/protocols/rdp/guac_handlers.c @@ -95,6 +95,10 @@ int rdp_guac_client_free_handler(guac_client* client) { cache_free(rdp_inst->context->cache); freerdp_free(rdp_inst); + /* Clean up filesystem, if allocated */ + if (guac_client_data->filesystem != NULL) + guac_rdp_fs_free(guac_client_data->filesystem); + /* Free client data */ cairo_surface_destroy(guac_client_data->opaque_glyph_surface); cairo_surface_destroy(guac_client_data->trans_glyph_surface); diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c index b53d2e19..f875ba8b 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c @@ -44,7 +44,8 @@ #include #include -#include "rdpdr_fs.h" +#include "rdp_fs.h" +#include "rdp_status.h" #include "rdpdr_fs_messages.h" #include "rdpdr_fs_messages_vol_info.h" #include "rdpdr_fs_messages_file_info.h" @@ -65,7 +66,7 @@ void guac_rdpdr_fs_process_create(guac_rdpdr_device* device, int desired_access, file_attributes; int create_disposition, create_options, path_length; - char path[GUAC_RDPDR_FS_MAX_PATH]; + char path[GUAC_RDP_FS_MAX_PATH]; /* Read "create" information */ Stream_Read_UINT32(input_stream, desired_access); @@ -83,7 +84,8 @@ void guac_rdpdr_fs_process_create(guac_rdpdr_device* device, path, path_length/2 - 1); /* Open file */ - file_id = guac_rdpdr_fs_open(device, path, desired_access, file_attributes, + file_id = guac_rdp_fs_open((guac_rdp_fs*) device->data, path, + desired_access, file_attributes, create_disposition, create_options); /* If an error occurred, notify server */ @@ -92,7 +94,7 @@ void guac_rdpdr_fs_process_create(guac_rdpdr_device* device, "File open refused (%i): \"%s\"", file_id, path); output_stream = guac_rdpdr_new_io_completion(device, completion_id, - guac_rdpdr_fs_get_status(file_id), 5); + guac_rdp_fs_get_status(file_id), 5); Stream_Write_UINT32(output_stream, 0); /* fileId */ Stream_Write_UINT8(output_stream, 0); /* information */ } @@ -128,13 +130,13 @@ void guac_rdpdr_fs_process_read(guac_rdpdr_device* device, length = sizeof(buffer); /* Attempt read */ - bytes_read = guac_rdpdr_fs_read(device, file_id, offset, + bytes_read = guac_rdp_fs_read((guac_rdp_fs*) device->data, file_id, offset, buffer, length); /* If error, return invalid parameter */ if (bytes_read < 0) { output_stream = guac_rdpdr_new_io_completion(device, completion_id, - guac_rdpdr_fs_get_status(bytes_read), 4); + guac_rdp_fs_get_status(bytes_read), 4); Stream_Write_UINT32(output_stream, 0); /* Length */ } @@ -165,13 +167,13 @@ void guac_rdpdr_fs_process_write(guac_rdpdr_device* device, Stream_Seek(input_stream, 20); /* Padding */ /* Attempt write */ - bytes_written = guac_rdpdr_fs_write(device, file_id, offset, - Stream_Pointer(input_stream), length); + bytes_written = guac_rdp_fs_write((guac_rdp_fs*) device->data, file_id, + offset, Stream_Pointer(input_stream), length); /* If error, return invalid parameter */ if (bytes_written < 0) { output_stream = guac_rdpdr_new_io_completion(device, completion_id, - guac_rdpdr_fs_get_status(bytes_written), 5); + guac_rdp_fs_get_status(bytes_written), 5); Stream_Write_UINT32(output_stream, 0); /* Length */ Stream_Write_UINT8(output_stream, 0); /* Padding */ } @@ -194,7 +196,7 @@ void guac_rdpdr_fs_process_close(guac_rdpdr_device* device, wStream* output_stream; /* Close file */ - guac_rdpdr_fs_close(device, file_id); + guac_rdp_fs_close((guac_rdp_fs*) device->data, file_id); output_stream = guac_rdpdr_new_io_completion(device, completion_id, STATUS_SUCCESS, 4); @@ -354,14 +356,14 @@ void guac_rdpdr_fs_process_query_directory(guac_rdpdr_device* device, wStream* i wStream* output_stream; - guac_rdpdr_fs_file* file; + guac_rdp_fs_file* file; int fs_information_class, initial_query; int path_length; const char* entry_name; /* Get file */ - file = guac_rdpdr_fs_get_file(device, file_id); + file = guac_rdp_fs_get_file((guac_rdp_fs*) device->data, file_id); if (file == NULL) return; @@ -384,22 +386,23 @@ void guac_rdpdr_fs_process_query_directory(guac_rdpdr_device* device, wStream* i } /* Find first matching entry in directory */ - while ((entry_name = guac_rdpdr_fs_read_dir(device, file_id)) != NULL) { + while ((entry_name = guac_rdp_fs_read_dir((guac_rdp_fs*) device->data, + file_id)) != NULL) { /* Convert to absolute path */ - char entry_path[GUAC_RDPDR_FS_MAX_PATH]; - if (guac_rdpdr_fs_convert_path(file->absolute_path, + char entry_path[GUAC_RDP_FS_MAX_PATH]; + if (guac_rdp_fs_convert_path(file->absolute_path, entry_name, entry_path) == 0) { int entry_file_id; /* Pattern defined and match fails, continue with next file */ - if (guac_rdpdr_fs_matches(entry_path, file->dir_pattern)) + if (guac_rdp_fs_matches(entry_path, file->dir_pattern)) continue; /* Open directory entry */ - entry_file_id = guac_rdpdr_fs_open(device, entry_path, - ACCESS_FILE_READ_DATA, 0, DISP_FILE_OPEN, 0); + entry_file_id = guac_rdp_fs_open((guac_rdp_fs*) device->data, + entry_path, ACCESS_FILE_READ_DATA, 0, DISP_FILE_OPEN, 0); if (entry_file_id >= 0) { @@ -432,7 +435,7 @@ void guac_rdpdr_fs_process_query_directory(guac_rdpdr_device* device, wStream* i fs_information_class); } - guac_rdpdr_fs_close(device, entry_file_id); + guac_rdp_fs_close((guac_rdp_fs*) device->data, entry_file_id); return; } /* end if file exists */ diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_dir_info.c b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_dir_info.c index 134d7091..55ffc872 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_dir_info.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_dir_info.c @@ -45,7 +45,8 @@ #include "rdpdr_service.h" #include "rdpdr_messages.h" -#include "rdpdr_fs.h" +#include "rdp_fs.h" +#include "rdp_status.h" #include "unicode.h" void guac_rdpdr_fs_process_query_directory_info(guac_rdpdr_device* device, @@ -63,7 +64,7 @@ void guac_rdpdr_fs_process_query_full_directory_info(guac_rdpdr_device* device, void guac_rdpdr_fs_process_query_both_directory_info(guac_rdpdr_device* device, const char* entry_name, int file_id, int completion_id) { - guac_rdpdr_fs_file* file; + guac_rdp_fs_file* file; wStream* output_stream = Stream_New(NULL, 256); int length = guac_utf8_strlen(entry_name); @@ -73,7 +74,7 @@ void guac_rdpdr_fs_process_query_both_directory_info(guac_rdpdr_device* device, guac_rdp_utf8_to_utf16((const unsigned char*) entry_name, (char*) utf16_entry_name, length); /* Get file */ - file = guac_rdpdr_fs_get_file(device, file_id); + file = guac_rdp_fs_get_file((guac_rdp_fs*) device->data, file_id); if (file == NULL) return; diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c index b6604734..4d386228 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c @@ -44,7 +44,8 @@ #include #include "rdpdr_messages.h" -#include "rdpdr_fs.h" +#include "rdp_fs.h" +#include "rdp_status.h" #include "rdpdr_service.h" #include "client.h" #include "debug.h" @@ -57,10 +58,10 @@ void guac_rdpdr_fs_process_query_basic_info(guac_rdpdr_device* device, wStream* int file_id, int completion_id) { wStream* output_stream; - guac_rdpdr_fs_file* file; + guac_rdp_fs_file* file; /* Get file */ - file = guac_rdpdr_fs_get_file(device, file_id); + file = guac_rdp_fs_get_file((guac_rdp_fs*) device->data, file_id); if (file == NULL) return; @@ -86,11 +87,11 @@ void guac_rdpdr_fs_process_query_standard_info(guac_rdpdr_device* device, wStrea int file_id, int completion_id) { wStream* output_stream; - guac_rdpdr_fs_file* file; + guac_rdp_fs_file* file; BOOL is_directory = FALSE; /* Get file */ - file = guac_rdpdr_fs_get_file(device, file_id); + file = guac_rdp_fs_get_file((guac_rdp_fs*) device->data, file_id); if (file == NULL) return; @@ -119,10 +120,10 @@ void guac_rdpdr_fs_process_query_attribute_tag_info(guac_rdpdr_device* device, wStream* input_stream, int file_id, int completion_id) { wStream* output_stream; - guac_rdpdr_fs_file* file; + guac_rdp_fs_file* file; /* Get file */ - file = guac_rdpdr_fs_get_file(device, file_id); + file = guac_rdp_fs_get_file((guac_rdp_fs*) device->data, file_id); if (file == NULL) return; @@ -147,7 +148,7 @@ void guac_rdpdr_fs_process_set_rename_info(guac_rdpdr_device* device, int result; int filename_length; wStream* output_stream; - char destination_path[GUAC_RDPDR_FS_MAX_PATH]; + char destination_path[GUAC_RDP_FS_MAX_PATH]; /* Read structure */ Stream_Seek_UINT8(input_stream); /* ReplaceIfExists */ @@ -159,10 +160,11 @@ void guac_rdpdr_fs_process_set_rename_info(guac_rdpdr_device* device, destination_path, filename_length/2); /* Perform rename */ - result = guac_rdpdr_fs_rename(device, file_id, destination_path); + result = guac_rdp_fs_rename((guac_rdp_fs*) device->data, file_id, + destination_path); if (result < 0) output_stream = guac_rdpdr_new_io_completion(device, - completion_id, guac_rdpdr_fs_get_status(result), 4); + completion_id, guac_rdp_fs_get_status(result), 4); else output_stream = guac_rdpdr_new_io_completion(device, completion_id, STATUS_SUCCESS, 4); diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_vol_info.c b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_vol_info.c index cf923456..d2c4fb76 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_vol_info.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_vol_info.c @@ -44,7 +44,8 @@ #include #include "rdpdr_messages.h" -#include "rdpdr_fs.h" +#include "rdp_fs.h" +#include "rdp_status.h" #include "rdpdr_service.h" #include "client.h" #include "unicode.h" @@ -91,7 +92,7 @@ void guac_rdpdr_fs_process_query_attribute_info(guac_rdpdr_device* device, wStre Stream_Write_UINT32(output_stream, 12 + GUAC_FILESYSTEM_NAME_LENGTH); Stream_Write_UINT32(output_stream, FILE_UNICODE_ON_DISK); /* FileSystemAttributes */ - Stream_Write_UINT32(output_stream, GUAC_RDPDR_FS_MAX_PATH ); /* MaximumComponentNameLength */ + Stream_Write_UINT32(output_stream, GUAC_RDP_FS_MAX_PATH ); /* MaximumComponentNameLength */ Stream_Write_UINT32(output_stream, GUAC_FILESYSTEM_NAME_LENGTH); Stream_Write(output_stream, GUAC_FILESYSTEM_NAME, GUAC_FILESYSTEM_NAME_LENGTH); diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.c b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.c index c5730114..88a018bf 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.c @@ -43,7 +43,7 @@ #include -#include "rdpdr_fs.h" +#include "rdp_fs.h" #include "rdpdr_fs_messages.h" #include "rdpdr_messages.h" #include "rdpdr_service.h" @@ -144,14 +144,11 @@ static void guac_rdpdr_device_fs_iorequest_handler(guac_rdpdr_device* device, } static void guac_rdpdr_device_fs_free_handler(guac_rdpdr_device* device) { - guac_rdpdr_fs_data* data = (guac_rdpdr_fs_data*) device->data; - guac_pool_free(data->file_id_pool); - free(data); } void guac_rdpdr_register_fs(guac_rdpdrPlugin* rdpdr) { - guac_rdpdr_fs_data* data; + rdp_guac_client_data* data = (rdp_guac_client_data*) rdpdr->client->data; int id = rdpdr->devices_registered++; /* Get new device */ @@ -168,9 +165,7 @@ void guac_rdpdr_register_fs(guac_rdpdrPlugin* rdpdr) { device->free_handler = guac_rdpdr_device_fs_free_handler; /* Init data */ - data = device->data = malloc(sizeof(guac_rdpdr_fs_data)); - data->file_id_pool = guac_pool_alloc(0); - data->open_files = 0; + device->data = data->filesystem; } diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.h b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.h new file mode 100644 index 00000000..9daa75ec --- /dev/null +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.h @@ -0,0 +1,63 @@ + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (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.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is libguac-client-rdp. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef __GUAC_RDPDR_FS_H +#define __GUAC_RDPDR_FS_H + +/** + * Functions and macros specific to filesystem handling and initialization + * independent of RDP. The functions here may deal with the RDPDR device + * directly, but their semantics must not deal with RDP protocol messaging. + * Functions here represent a virtual Windows-style filesystem on top of UNIX + * system calls and structures, using the guac_rdpdr_device structure as a home + * for common data. + * + * @file rdpdr_fs.h + */ + +#include + +#include "rdpdr_service.h" + +/** + * Registers a new filesystem device within the RDPDR plugin. This must be done + * before RDPDR connection finishes. + */ +void guac_rdpdr_register_fs(guac_rdpdrPlugin* rdpdr); + +#endif + diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_messages.h b/src/protocols/rdp/guac_rdpdr/rdpdr_messages.h index 113306b0..c49da5eb 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_messages.h +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_messages.h @@ -198,30 +198,6 @@ #define IRP_MN_QUERY_DIRECTORY 0x00000001 #define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x00000002 -/* - * Status constants. - */ -#define STATUS_SUCCESS 0x00000000 -#define STATUS_NO_MORE_FILES 0x80000006 -#define STATUS_DEVICE_OFF_LINE 0x80000010 -#define STATUS_NOT_IMPLEMENTED 0xC0000002 -#define STATUS_INVALID_PARAMETER 0xC000000D -#define STATUS_NO_SUCH_FILE 0xC000000F -#define STATUS_END_OF_FILE 0xC0000011 -#define STATUS_ACCESS_DENIED 0xC0000022 -#define STATUS_OBJECT_NAME_COLLISION 0xC0000035 -#define STATUS_DISK_FULL 0xC000007F -#define STATUS_FILE_INVALID 0xC0000098 -#define STATUS_FILE_IS_A_DIRECTORY 0xC00000BA -#define STATUS_NOT_SUPPORTED 0xC00000BB -#define STATUS_NOT_A_DIRECTORY 0xC0000103 -#define STATUS_TOO_MANY_OPENED_FILES 0xC000011F -#define STATUS_CANNOT_DELETE 0xC0000121 -#define STATUS_FILE_DELETED 0xC0000123 -#define STATUS_FILE_CLOSED 0xC0000128 -#define STATUS_FILE_SYSTEM_LIMITATION 0xC0000427 -#define STATUS_FILE_TOO_LARGE 0xC0000904 - /* * Volume information constants. */ diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_printer.c b/src/protocols/rdp/guac_rdpdr/rdpdr_printer.c index 62602eb6..6ce08123 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_printer.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_printer.c @@ -11,6 +11,7 @@ #include +#include "rdp_status.h" #include "rdpdr_messages.h" #include "rdpdr_printer.h" #include "rdpdr_service.h" diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_service.c b/src/protocols/rdp/guac_rdpdr/rdpdr_service.c index 74639b67..d9ac12ce 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_service.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_service.c @@ -54,7 +54,7 @@ #include "rdpdr_service.h" #include "rdpdr_messages.h" #include "rdpdr_printer.h" -#include "rdpdr_fs.h" +#include "rdpdr_fs_service.h" #include "client.h" diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs.c b/src/protocols/rdp/rdp_fs.c similarity index 69% rename from src/protocols/rdp/guac_rdpdr/rdpdr_fs.c rename to src/protocols/rdp/rdp_fs.c index 9f1172b2..ead8b355 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs.c +++ b/src/protocols/rdp/rdp_fs.c @@ -35,6 +35,8 @@ * * ***** END LICENSE BLOCK ***** */ +#include +#include #include #include #include @@ -43,43 +45,46 @@ #include #include -#ifdef ENABLE_WINPR -#include -#else -#include "compat/winpr-stream.h" -#endif - -#include -#include -#include - #include -#include "rdpdr_messages.h" -#include "rdpdr_fs.h" -#include "rdpdr_service.h" -#include "client.h" +#include "rdp_fs.h" +#include "rdp_status.h" #include "debug.h" #include "unicode.h" -#include +guac_rdp_fs* guac_rdp_fs_alloc(const char* drive_path) { + + guac_rdp_fs* fs = malloc(sizeof(guac_rdp_fs)); + + fs->drive_path = strdup(drive_path); + fs->file_id_pool = guac_pool_alloc(0); + fs->open_files = 0; + + return fs; + +} + +void guac_rdp_fs_free(guac_rdp_fs* fs) { + guac_pool_free(fs->file_id_pool); + free(fs->drive_path); + free(fs); +} /** * Translates an absolute Windows virtual_path to an absolute virtual_path * which is within the "drive virtual_path" specified in the connection * settings. */ -static void __guac_rdpdr_fs_translate_path(guac_rdpdr_device* device, +static void __guac_rdp_fs_translate_path(guac_rdp_fs* fs, const char* virtual_path, char* real_path) { /* Get drive path */ - rdp_guac_client_data* client_data = (rdp_guac_client_data*) device->rdpdr->client->data; - char* drive_path = client_data->settings.drive_path; + char* drive_path = fs->drive_path; int i; /* Start with path from settings */ - for (i=0; idata; - char real_path[GUAC_RDPDR_FS_MAX_PATH]; - char normalized_path[GUAC_RDPDR_FS_MAX_PATH]; + char real_path[GUAC_RDP_FS_MAX_PATH]; + char normalized_path[GUAC_RDP_FS_MAX_PATH]; struct stat file_stat; int fd; int file_id; - guac_rdpdr_fs_file* file; + guac_rdp_fs_file* file; int flags = 0; @@ -172,9 +176,9 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path, create_options); /* If no files available, return too many open */ - if (data->open_files >= GUAC_RDPDR_FS_MAX_FILES) { + if (fs->open_files >= GUAC_RDP_FS_MAX_FILES) { GUAC_RDP_DEBUG(1, "%s", "Failure - too many open files."); - return GUAC_RDPDR_FS_ENFILE; + return GUAC_RDP_FS_ENFILE; } /* If path empty, transform to root path */ @@ -184,7 +188,7 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path, /* If path is relative, the file does not exist */ else if (path[0] != '\\') { GUAC_RDP_DEBUG(1, "Failure - path \"%s\" is relative.", path); - return GUAC_RDPDR_FS_ENOENT; + return GUAC_RDP_FS_ENOENT; } /* Translate access into flags */ @@ -203,16 +207,16 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path, flags |= O_APPEND; /* Normalize path, return no-such-file if invalid */ - if (guac_rdpdr_fs_normalize_path(path, normalized_path)) { + if (guac_rdp_fs_normalize_path(path, normalized_path)) { GUAC_RDP_DEBUG(1, "Normalization of path \"%s\" failed.", path); - return GUAC_RDPDR_FS_ENOENT; + return GUAC_RDP_FS_ENOENT; } GUAC_RDP_DEBUG(2, "Normalized path \"%s\" to \"%s\".", path, normalized_path); /* Translate normalized path to real path */ - __guac_rdpdr_fs_translate_path(device, normalized_path, real_path); + __guac_rdp_fs_translate_path(fs, normalized_path, real_path); GUAC_RDP_DEBUG(2, "Translated path \"%s\" to \"%s\".", normalized_path, real_path); @@ -252,7 +256,7 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path, /* Unrecognised disposition */ default: - return GUAC_RDPDR_FS_ENOSYS; + return GUAC_RDP_FS_ENOSYS; } @@ -261,7 +265,7 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path, if (mkdir(real_path, S_IRWXU)) { GUAC_RDP_DEBUG(1, "mkdir() failed: %s", strerror(errno)); - return guac_rdpdr_fs_get_errorcode(errno); + return guac_rdp_fs_get_errorcode(errno); } /* Unset O_CREAT and O_EXCL as directory must exist before open() */ @@ -273,12 +277,12 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path, fd = open(real_path, flags, S_IRUSR | S_IWUSR); if (fd == -1) { GUAC_RDP_DEBUG(1, "open() failed: %s", strerror(errno)); - return guac_rdpdr_fs_get_errorcode(errno); + return guac_rdp_fs_get_errorcode(errno); } /* Get file ID, init file */ - file_id = guac_pool_next_int(data->file_id_pool); - file = &(data->files[file_id]); + file_id = guac_pool_next_int(fs->file_id_pool); + file = &(fs->files[file_id]); file->fd = fd; file->dir = NULL; file->dir_pattern[0] = '\0'; @@ -307,10 +311,6 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path, /* If information cannot be retrieved, fake it */ else { - guac_client_log_info(device->rdpdr->client, - "Unable to read information for \"%s\"", - real_path); - /* Init information to 0, lacking any alternative */ file->size = 0; file->ctime = 0; @@ -320,21 +320,21 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path, } - data->open_files++; + fs->open_files++; return file_id; } -int guac_rdpdr_fs_read(guac_rdpdr_device* device, int file_id, int offset, +int guac_rdp_fs_read(guac_rdp_fs* fs, int file_id, int offset, void* buffer, int length) { int bytes_read; - guac_rdpdr_fs_file* file = guac_rdpdr_fs_get_file(device, file_id); + guac_rdp_fs_file* file = guac_rdp_fs_get_file(fs, file_id); if (file == NULL) { GUAC_RDP_DEBUG(1, "Read from bad file_id: %i", file_id); - return GUAC_RDPDR_FS_EINVAL; + return GUAC_RDP_FS_EINVAL; } /* Attempt read */ @@ -343,21 +343,21 @@ int guac_rdpdr_fs_read(guac_rdpdr_device* device, int file_id, int offset, /* Translate errno on error */ if (bytes_read < 0) - return guac_rdpdr_fs_get_errorcode(errno); + return guac_rdp_fs_get_errorcode(errno); return bytes_read; } -int guac_rdpdr_fs_write(guac_rdpdr_device* device, int file_id, int offset, +int guac_rdp_fs_write(guac_rdp_fs* fs, int file_id, int offset, void* buffer, int length) { int bytes_written; - guac_rdpdr_fs_file* file = guac_rdpdr_fs_get_file(device, file_id); + guac_rdp_fs_file* file = guac_rdp_fs_get_file(fs, file_id); if (file == NULL) { GUAC_RDP_DEBUG(1, "Write to bad file_id: %i", file_id); - return GUAC_RDPDR_FS_EINVAL; + return GUAC_RDP_FS_EINVAL; } /* Attempt write */ @@ -366,32 +366,32 @@ int guac_rdpdr_fs_write(guac_rdpdr_device* device, int file_id, int offset, /* Translate errno on error */ if (bytes_written < 0) - return guac_rdpdr_fs_get_errorcode(errno); + return guac_rdp_fs_get_errorcode(errno); return bytes_written; } -int guac_rdpdr_fs_rename(guac_rdpdr_device* device, int file_id, +int guac_rdp_fs_rename(guac_rdp_fs* fs, int file_id, const char* new_path) { - char real_path[GUAC_RDPDR_FS_MAX_PATH]; - char normalized_path[GUAC_RDPDR_FS_MAX_PATH]; + char real_path[GUAC_RDP_FS_MAX_PATH]; + char normalized_path[GUAC_RDP_FS_MAX_PATH]; - guac_rdpdr_fs_file* file = guac_rdpdr_fs_get_file(device, file_id); + guac_rdp_fs_file* file = guac_rdp_fs_get_file(fs, file_id); if (file == NULL) { GUAC_RDP_DEBUG(1, "Rename of bad file_id: %i", file_id); - return GUAC_RDPDR_FS_EINVAL; + return GUAC_RDP_FS_EINVAL; } /* Normalize path, return no-such-file if invalid */ - if (guac_rdpdr_fs_normalize_path(new_path, normalized_path)) { + if (guac_rdp_fs_normalize_path(new_path, normalized_path)) { GUAC_RDP_DEBUG(1, "Normalization of path \"%s\" failed.", new_path); - return GUAC_RDPDR_FS_ENOENT; + return GUAC_RDP_FS_ENOENT; } /* Translate normalized path to real path */ - __guac_rdpdr_fs_translate_path(device, normalized_path, real_path); + __guac_rdp_fs_translate_path(fs, normalized_path, real_path); GUAC_RDP_DEBUG(2, "Renaming \"%s\" -> \"%s\"", file->real_path, real_path); @@ -399,25 +399,23 @@ int guac_rdpdr_fs_rename(guac_rdpdr_device* device, int file_id, if (rename(file->real_path, real_path)) { GUAC_RDP_DEBUG(1, "rename() failed: \"%s\" -> \"%s\"", file->real_path, real_path); - return guac_rdpdr_fs_get_errorcode(errno); + return guac_rdp_fs_get_errorcode(errno); } return 0; } -void guac_rdpdr_fs_close(guac_rdpdr_device* device, int file_id) { +void guac_rdp_fs_close(guac_rdp_fs* fs, int file_id) { - guac_rdpdr_fs_data* data = (guac_rdpdr_fs_data*) device->data; - - guac_rdpdr_fs_file* file = guac_rdpdr_fs_get_file(device, file_id); + guac_rdp_fs_file* file = guac_rdp_fs_get_file(fs, file_id); if (file == NULL) { GUAC_RDP_DEBUG(2, "Ignoring close for bad file_id: %i", file_id); return; } - file = &(data->files[file_id]); + file = &(fs->files[file_id]); GUAC_RDP_DEBUG(2, "Closed \"%s\" (file_id=%i)", file->absolute_path, file_id); @@ -434,23 +432,22 @@ void guac_rdpdr_fs_close(guac_rdpdr_device* device, int file_id) { free(file->real_path); /* Free ID back to pool */ - guac_pool_free_int(data->file_id_pool, file_id); - data->open_files--; + guac_pool_free_int(fs->file_id_pool, file_id); + fs->open_files--; } -const char* guac_rdpdr_fs_read_dir(guac_rdpdr_device* device, int file_id) { +const char* guac_rdp_fs_read_dir(guac_rdp_fs* fs, int file_id) { - guac_rdpdr_fs_data* data = (guac_rdpdr_fs_data*) device->data; - guac_rdpdr_fs_file* file; + guac_rdp_fs_file* file; struct dirent* result; /* Only read if file ID is valid */ - if (file_id < 0 || file_id >= GUAC_RDPDR_FS_MAX_FILES) + if (file_id < 0 || file_id >= GUAC_RDP_FS_MAX_FILES) return NULL; - file = &(data->files[file_id]); + file = &(fs->files[file_id]); /* Open directory if not yet open, stop if error */ if (file->dir == NULL) { @@ -472,11 +469,11 @@ const char* guac_rdpdr_fs_read_dir(guac_rdpdr_device* device, int file_id) { } -int guac_rdpdr_fs_normalize_path(const char* path, char* abs_path) { +int guac_rdp_fs_normalize_path(const char* path, char* abs_path) { int i; int path_depth = 0; - char path_component_data[GUAC_RDPDR_FS_MAX_PATH]; + char path_component_data[GUAC_RDP_FS_MAX_PATH]; const char* path_components[64]; const char** current_path_component = &(path_components[0]); @@ -490,10 +487,10 @@ int guac_rdpdr_fs_normalize_path(const char* path, char* abs_path) { path++; /* Copy path into component data for parsing */ - strncpy(path_component_data, path, GUAC_RDPDR_FS_MAX_PATH-1); + strncpy(path_component_data, path, GUAC_RDP_FS_MAX_PATH-1); /* Find path components within path */ - for (i=0; idata; - if (file_id < 0 || file_id >= GUAC_RDPDR_FS_MAX_FILES) + if (file_id < 0 || file_id >= GUAC_RDP_FS_MAX_FILES) return NULL; /* Return file at given ID */ - return &(data->files[file_id]); + return &(fs->files[file_id]); } -int guac_rdpdr_fs_matches(const char* filename, const char* pattern) { +int guac_rdp_fs_matches(const char* filename, const char* pattern) { return fnmatch(pattern, filename, FNM_NOESCAPE) != 0; } diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs.h b/src/protocols/rdp/rdp_fs.h similarity index 76% rename from src/protocols/rdp/guac_rdpdr/rdpdr_fs.h rename to src/protocols/rdp/rdp_fs.h index cd9d2c7f..3e697add 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs.h +++ b/src/protocols/rdp/rdp_fs.h @@ -35,101 +35,89 @@ * * ***** END LICENSE BLOCK ***** */ -#ifndef __GUAC_RDPDR_FS_H -#define __GUAC_RDPDR_FS_H +#ifndef __GUAC_RDP_FS_H +#define __GUAC_RDP_FS_H /** * Functions and macros specific to filesystem handling and initialization - * independent of RDP. The functions here may deal with the RDPDR device + * independent of RDP. The functions here may deal with the filesystem device * directly, but their semantics must not deal with RDP protocol messaging. * Functions here represent a virtual Windows-style filesystem on top of UNIX - * system calls and structures, using the guac_rdpdr_device structure as a home + * system calls and structures, using the guac_rdp_fs structure as a home * for common data. * - * @file rdpdr_fs.h + * @file rdp_fs.h */ -#ifdef ENABLE_WINPR -#include -#else -#include "compat/winpr-stream.h" -#endif - #include +#include #include #include -#include "rdpdr_service.h" - -/** - * The index of the blob to use when sending files. - */ -#define GUAC_RDPDR_FS_BLOB 1 - /** * The maximum number of file IDs to provide. */ -#define GUAC_RDPDR_FS_MAX_FILES 128 +#define GUAC_RDP_FS_MAX_FILES 128 /** * The maximum number of bytes in a path string. */ -#define GUAC_RDPDR_FS_MAX_PATH 4096 +#define GUAC_RDP_FS_MAX_PATH 4096 /** * Error code returned when no more file IDs can be allocated. */ -#define GUAC_RDPDR_FS_ENFILE -1 +#define GUAC_RDP_FS_ENFILE -1 /** * Error code returned when no such file exists. */ -#define GUAC_RDPDR_FS_ENOENT -2 +#define GUAC_RDP_FS_ENOENT -2 /** * Error code returned when the operation required a directory * but the file was not a directory. */ -#define GUAC_RDPDR_FS_ENOTDIR -3 +#define GUAC_RDP_FS_ENOTDIR -3 /** * Error code returned when insufficient space exists to complete * the operation. */ -#define GUAC_RDPDR_FS_ENOSPC -4 +#define GUAC_RDP_FS_ENOSPC -4 /** * Error code returned when the operation requires a normal file but * a directory was given. */ -#define GUAC_RDPDR_FS_EISDIR -5 +#define GUAC_RDP_FS_EISDIR -5 /** * Error code returned when permission is denied. */ -#define GUAC_RDPDR_FS_EACCES -6 +#define GUAC_RDP_FS_EACCES -6 /** * Error code returned when the operation cannot be completed because the * file already exists. */ -#define GUAC_RDPDR_FS_EEXIST -7 +#define GUAC_RDP_FS_EEXIST -7 /** * Error code returned when invalid parameters were given. */ -#define GUAC_RDPDR_FS_EINVAL -8 +#define GUAC_RDP_FS_EINVAL -8 /** * Error code returned when the operation is not implemented. */ -#define GUAC_RDPDR_FS_ENOSYS -9 +#define GUAC_RDP_FS_ENOSYS -9 /** * Error code returned when the operation is not supported. */ -#define GUAC_RDPDR_FS_ENOTSUP -10 +#define GUAC_RDP_FS_ENOTSUP -10 /* * Access constants. @@ -201,7 +189,7 @@ /** * An arbitrary file on the virtual filesystem of the Guacamole drive. */ -typedef struct guac_rdpdr_fs_file { +typedef struct guac_rdp_fs_file { /** * The absolute path, including filename, of this file. @@ -233,7 +221,7 @@ typedef struct guac_rdpdr_fs_file { /** * The pattern the check directory contents against, if any. */ - char dir_pattern[GUAC_RDPDR_FS_MAX_PATH]; + char dir_pattern[GUAC_RDP_FS_MAX_PATH]; /** * Bitwise OR of all associated Windows file attributes. @@ -260,12 +248,17 @@ typedef struct guac_rdpdr_fs_file { */ uint64_t atime; -} guac_rdpdr_fs_file; +} guac_rdp_fs_file; /** - * Data specific to an instance of the printer device. + * A virtual filesystem implementing RDP-style operations. */ -typedef struct guac_rdpdr_fs_data { +typedef struct guac_rdp_fs { + + /** + * The root of the filesystem. + */ + char* drive_path; /** * The number of currently open files. @@ -280,37 +273,41 @@ typedef struct guac_rdpdr_fs_data { /** * All available file structures. */ - guac_rdpdr_fs_file files[GUAC_RDPDR_FS_MAX_FILES]; + guac_rdp_fs_file files[GUAC_RDP_FS_MAX_FILES]; -} guac_rdpdr_fs_data; +} guac_rdp_fs; /** - * Registers a new filesystem device within the RDPDR plugin. This must be done - * before RDPDR connection finishes. + * Allocates a new filesystem given a root path. */ -void guac_rdpdr_register_fs(guac_rdpdrPlugin* rdpdr); +guac_rdp_fs* guac_rdp_fs_alloc(const char* drive_path); + +/** + * Frees the given filesystem. + */ +void guac_rdp_fs_free(guac_rdp_fs* fs); /** * Converts the given relative path to an absolute path based on the given * parent path. If the path cannot be converted, non-zero is returned. */ -int guac_rdpdr_fs_convert_path(const char* parent, const char* rel_path, char* abs_path); +int guac_rdp_fs_convert_path(const char* parent, const char* rel_path, char* abs_path); /** - * Translates the given errno error code to a GUAC_RDPDR_FS error code. + * Translates the given errno error code to a GUAC_RDP_FS error code. */ -int guac_rdpdr_fs_get_errorcode(int err); +int guac_rdp_fs_get_errorcode(int err); /** - * Teanslates the given GUAC_RDPDR_FS error code to an RDPDR status code. + * Teanslates the given GUAC_RDP_FS error code to an RDPDR status code. */ -int guac_rdpdr_fs_get_status(int err); +int guac_rdp_fs_get_status(int err); /** * Returns the next available file ID, or an error code less than zero * if an error occurs. */ -int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path, +int guac_rdp_fs_open(guac_rdp_fs* fs, const char* path, int access, int file_attributes, int create_disposition, int create_options); @@ -319,7 +316,7 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path, * file having the given ID. Returns the number of bytes read, zero on EOF, * and an error code if an error occurs. */ -int guac_rdpdr_fs_read(guac_rdpdr_device* device, int file_id, int offset, +int guac_rdp_fs_read(guac_rdp_fs* fs, int file_id, int offset, void* buffer, int length); /** @@ -327,48 +324,47 @@ int guac_rdpdr_fs_read(guac_rdpdr_device* device, int file_id, int offset, * file having the given ID. Returns the number of bytes written, and an * error code if an error occurs. */ -int guac_rdpdr_fs_write(guac_rdpdr_device* device, int file_id, int offset, +int guac_rdp_fs_write(guac_rdp_fs* fs, int file_id, int offset, void* buffer, int length); /** * Renames (moves) the file with the given ID to the new path specified. * Returns zero on success, or an error code if an error occurs. */ -int guac_rdpdr_fs_rename(guac_rdpdr_device* device, int file_id, +int guac_rdp_fs_rename(guac_rdp_fs* fs, int file_id, const char* new_path); /** * Frees the given file ID, allowing future open operations to reuse it. */ -void guac_rdpdr_fs_close(guac_rdpdr_device* device, int file_id); +void guac_rdp_fs_close(guac_rdp_fs* fs, int file_id); /** * Given an arbitrary path, which may contain ".." and ".", creates an * absolute path which does NOT contain ".." or ".". */ -int guac_rdpdr_fs_normalize_path(const char* path, char* abs_path); +int guac_rdp_fs_normalize_path(const char* path, char* abs_path); /** * Given a parent path and a relative path, produces a normalized absolute path. */ -int guac_rdpdr_fs_convert_path(const char* parent, const char* rel_path, char* abs_path); +int guac_rdp_fs_convert_path(const char* parent, const char* rel_path, char* abs_path); /** * Returns the next filename within the directory having the given file ID, * or NULL if no more files. */ -const char* guac_rdpdr_fs_read_dir(guac_rdpdr_device* device, int file_id); +const char* guac_rdp_fs_read_dir(guac_rdp_fs* fs, int file_id); /** * Returns the file having the given ID, or NULL if no such file exists. */ -guac_rdpdr_fs_file* guac_rdpdr_fs_get_file(guac_rdpdr_device* device, - int file_id); +guac_rdp_fs_file* guac_rdp_fs_get_file(guac_rdp_fs* fs, int file_id); /** * Returns whether the given filename matches the given pattern. */ -int guac_rdpdr_fs_matches(const char* filename, const char* pattern); +int guac_rdp_fs_matches(const char* filename, const char* pattern); #endif diff --git a/src/protocols/rdp/rdp_status.h b/src/protocols/rdp/rdp_status.h new file mode 100644 index 00000000..a92d386a --- /dev/null +++ b/src/protocols/rdp/rdp_status.h @@ -0,0 +1,69 @@ + +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (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.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is libguac-client-rdp. + * + * The Initial Developer of the Original Code is + * Michael Jumper. + * Portions created by the Initial Developer are Copyright (C) 2011 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#ifndef __GUAC_RDP_STATUS_H +#define __GUAC_RDP_STATUS_H + +/** + * RDP-specific status constants. + * + * @file rdp_status.h + */ + +#define STATUS_SUCCESS 0x00000000 +#define STATUS_NO_MORE_FILES 0x80000006 +#define STATUS_DEVICE_OFF_LINE 0x80000010 +#define STATUS_NOT_IMPLEMENTED 0xC0000002 +#define STATUS_INVALID_PARAMETER 0xC000000D +#define STATUS_NO_SUCH_FILE 0xC000000F +#define STATUS_END_OF_FILE 0xC0000011 +#define STATUS_ACCESS_DENIED 0xC0000022 +#define STATUS_OBJECT_NAME_COLLISION 0xC0000035 +#define STATUS_DISK_FULL 0xC000007F +#define STATUS_FILE_INVALID 0xC0000098 +#define STATUS_FILE_IS_A_DIRECTORY 0xC00000BA +#define STATUS_NOT_SUPPORTED 0xC00000BB +#define STATUS_NOT_A_DIRECTORY 0xC0000103 +#define STATUS_TOO_MANY_OPENED_FILES 0xC000011F +#define STATUS_CANNOT_DELETE 0xC0000121 +#define STATUS_FILE_DELETED 0xC0000123 +#define STATUS_FILE_CLOSED 0xC0000128 +#define STATUS_FILE_SYSTEM_LIMITATION 0xC0000427 +#define STATUS_FILE_TOO_LARGE 0xC0000904 + +#endif +