diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs.c b/src/protocols/rdp/guac_rdpdr/rdpdr_fs.c index 45f78250..31c50f1e 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs.c @@ -37,6 +37,7 @@ #include #include +#include #include #ifdef ENABLE_WINPR @@ -251,24 +252,53 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path, void guac_rdpdr_fs_close(guac_rdpdr_device* device, int file_id) { guac_rdpdr_fs_data* data = (guac_rdpdr_fs_data*) device->data; + guac_rdpdr_fs_file* file; /* Only close if file ID is valid */ - if (file_id >= 0 && file_id <= GUAC_RDPDR_FS_MAX_FILES-1) { + if (file_id < 0 || file_id >= GUAC_RDPDR_FS_MAX_FILES) + return; - guac_rdpdr_fs_file* file = &(data->files[file_id]); + file = &(data->files[file_id]); - /* Close directory, if open */ - if (file->dir != NULL) - closedir(file->dir); + /* Close directory, if open */ + if (file->dir != NULL) + closedir(file->dir); - /* Close file */ - close(file->fd); + /* Close file */ + close(file->fd); - /* Free ID back to pool */ - guac_pool_free_int(data->file_id_pool, file_id); - data->open_files--; - - } + /* Free ID back to pool */ + guac_pool_free_int(data->file_id_pool, file_id); + data->open_files--; + +} + +const char* guac_rdpdr_fs_read_dir(guac_rdpdr_device* device, int file_id) { + + guac_rdpdr_fs_data* data = (guac_rdpdr_fs_data*) device->data; + guac_rdpdr_fs_file* file; + + struct dirent* result; + + /* Only read if file ID is valid */ + if (file_id < 0 || file_id >= GUAC_RDPDR_FS_MAX_FILES) + return NULL; + + file = &(data->files[file_id]); + + /* Open directory if not yet open, stop if error */ + if (file->dir == NULL) { + file->dir = fdopendir(file->fd); + if (file->dir == NULL) + return NULL; + } + + /* Read next entry, stop if error */ + if (readdir_r(file->dir, &(file->__dirent), &result)) + return NULL; + + /* Return filename */ + return file->__dirent.d_name; } diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs.h b/src/protocols/rdp/guac_rdpdr/rdpdr_fs.h index a736f219..bee64585 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs.h +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs.h @@ -176,6 +176,12 @@ typedef struct guac_rdpdr_fs_file { */ DIR* dir; + /** + * The last read dirent structure. This is used if traversing the contents + * of a directory. + */ + struct dirent __dirent; + /** * The size of this file, in bytes. */ @@ -238,5 +244,11 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path, */ void guac_rdpdr_fs_close(guac_rdpdr_device* device, int file_id); +/** + * 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); + #endif diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c index cb7c1aae..23e79aa8 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages.c @@ -275,6 +275,9 @@ void guac_rdpdr_fs_process_notify_change_directory(guac_rdpdr_device* device, void guac_rdpdr_fs_process_query_directory(guac_rdpdr_device* device, wStream* input_stream, int file_id, int completion_id) { + /*guac_rdpdr_fs_data* data = (guac_rdpdr_fs_data*) device->data; + guac_rdpdr_fs_file* file = &(data->files[file_id]);*/ + int fs_information_class, initial_query; int path_length; @@ -285,13 +288,26 @@ void guac_rdpdr_fs_process_query_directory(guac_rdpdr_device* device, wStream* i /* If this is the first query, the path is included after padding */ if (initial_query) { - Stream_Seek(input_stream, 23); /* Padding */ - /* Path here */ - } - guac_client_log_info(device->rdpdr->client, - "Received dir query - class=0x%x, path_length=%i", - fs_information_class, path_length); + unsigned char* path; + + Stream_Seek(input_stream, 23); /* Padding */ + path = Stream_Pointer(input_stream); /* Path */ + + guac_client_log_info(device->rdpdr->client, + "Received initial dir query - class=0x%x, path_length=%i, path=%s", + fs_information_class, path_length, path); + + /* Open directory */ + /*file->dir = fdopendir(file->fd);*/ + + /* FIXME: Handle error */ + + } + else + guac_client_log_info(device->rdpdr->client, + "Received continued dir query - class=0x%x", + fs_information_class); /* Dispatch to appropriate class-specific handler */ switch (fs_information_class) {