Separate RDP filesystem operations from RDPDR.
This commit is contained in:
parent
28c3c7d926
commit
aacb726b66
@ -47,6 +47,7 @@ libguac_client_rdp_la_SOURCES = \
|
|||||||
guac_handlers.c \
|
guac_handlers.c \
|
||||||
rdp_bitmap.c \
|
rdp_bitmap.c \
|
||||||
rdp_cliprdr.c \
|
rdp_cliprdr.c \
|
||||||
|
rdp_fs.c \
|
||||||
rdp_gdi.c \
|
rdp_gdi.c \
|
||||||
rdp_glyph.c \
|
rdp_glyph.c \
|
||||||
rdp_keymap_base.c \
|
rdp_keymap_base.c \
|
||||||
@ -64,7 +65,6 @@ guacsnd_sources = \
|
|||||||
guac_rdpsnd/rdpsnd_service.c
|
guac_rdpsnd/rdpsnd_service.c
|
||||||
|
|
||||||
guacdr_sources = \
|
guacdr_sources = \
|
||||||
guac_rdpdr/rdpdr_fs.c \
|
|
||||||
guac_rdpdr/rdpdr_fs_messages.c \
|
guac_rdpdr/rdpdr_fs_messages.c \
|
||||||
guac_rdpdr/rdpdr_fs_messages_dir_info.c \
|
guac_rdpdr/rdpdr_fs_messages_dir_info.c \
|
||||||
guac_rdpdr/rdpdr_fs_messages_file_info.c \
|
guac_rdpdr/rdpdr_fs_messages_file_info.c \
|
||||||
@ -73,15 +73,16 @@ guacdr_sources = \
|
|||||||
guac_rdpdr/rdpdr_messages.c \
|
guac_rdpdr/rdpdr_messages.c \
|
||||||
guac_rdpdr/rdpdr_printer.c \
|
guac_rdpdr/rdpdr_printer.c \
|
||||||
guac_rdpdr/rdpdr_service.c \
|
guac_rdpdr/rdpdr_service.c \
|
||||||
|
rdp_fs.c \
|
||||||
unicode.c
|
unicode.c
|
||||||
|
|
||||||
noinst_HEADERS = \
|
noinst_HEADERS = \
|
||||||
compat/client-cliprdr.h \
|
compat/client-cliprdr.h \
|
||||||
guac_rdpdr/rdpdr_fs.h \
|
|
||||||
guac_rdpdr/rdpdr_fs_messages.h \
|
guac_rdpdr/rdpdr_fs_messages.h \
|
||||||
guac_rdpdr/rdpdr_fs_messages_dir_info.h \
|
guac_rdpdr/rdpdr_fs_messages_dir_info.h \
|
||||||
guac_rdpdr/rdpdr_fs_messages_file_info.h \
|
guac_rdpdr/rdpdr_fs_messages_file_info.h \
|
||||||
guac_rdpdr/rdpdr_fs_messages_vol_info.h \
|
guac_rdpdr/rdpdr_fs_messages_vol_info.h \
|
||||||
|
guac_rdpdr/rdpdr_fs_service.h \
|
||||||
guac_rdpdr/rdpdr_messages.h \
|
guac_rdpdr/rdpdr_messages.h \
|
||||||
guac_rdpdr/rdpdr_printer.h \
|
guac_rdpdr/rdpdr_printer.h \
|
||||||
guac_rdpdr/rdpdr_service.h \
|
guac_rdpdr/rdpdr_service.h \
|
||||||
@ -94,11 +95,13 @@ noinst_HEADERS = \
|
|||||||
guac_handlers.h \
|
guac_handlers.h \
|
||||||
rdp_bitmap.h \
|
rdp_bitmap.h \
|
||||||
rdp_cliprdr.h \
|
rdp_cliprdr.h \
|
||||||
|
rdp_fs.h \
|
||||||
rdp_gdi.h \
|
rdp_gdi.h \
|
||||||
rdp_glyph.h \
|
rdp_glyph.h \
|
||||||
rdp_keymap.h \
|
rdp_keymap.h \
|
||||||
rdp_pointer.h \
|
rdp_pointer.h \
|
||||||
rdp_settings.h \
|
rdp_settings.h \
|
||||||
|
rdp_status.h \
|
||||||
unicode.h
|
unicode.h
|
||||||
|
|
||||||
# Add compatibility layer for WinPR if not available
|
# Add compatibility layer for WinPR if not available
|
||||||
|
@ -184,6 +184,12 @@ BOOL rdp_freerdp_pre_connect(freerdp* instance) {
|
|||||||
|
|
||||||
} /* end if audio enabled */
|
} /* 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 RDPDR required, load it */
|
||||||
if (guac_client_data->settings.printing_enabled
|
if (guac_client_data->settings.printing_enabled
|
||||||
|| guac_client_data->settings.drive_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 =
|
guac_client_data->settings.drive_enabled =
|
||||||
(strcmp(argv[IDX_ENABLE_DRIVE], "true") == 0);
|
(strcmp(argv[IDX_ENABLE_DRIVE], "true") == 0);
|
||||||
|
|
||||||
/* Drive enable/disable */
|
|
||||||
guac_client_data->settings.drive_path = strdup(argv[IDX_DRIVE_PATH]);
|
guac_client_data->settings.drive_path = strdup(argv[IDX_DRIVE_PATH]);
|
||||||
|
|
||||||
/* Store client data */
|
/* 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->current_surface = GUAC_DEFAULT_LAYER;
|
||||||
guac_client_data->clipboard = NULL;
|
guac_client_data->clipboard = NULL;
|
||||||
guac_client_data->audio = NULL;
|
guac_client_data->audio = NULL;
|
||||||
|
guac_client_data->filesystem = NULL;
|
||||||
|
|
||||||
/* Main socket needs to be threadsafe */
|
/* Main socket needs to be threadsafe */
|
||||||
guac_socket_require_threadsafe(client->socket);
|
guac_socket_require_threadsafe(client->socket);
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
#include <guacamole/audio.h>
|
#include <guacamole/audio.h>
|
||||||
|
|
||||||
|
#include "rdp_fs.h"
|
||||||
#include "rdp_keymap.h"
|
#include "rdp_keymap.h"
|
||||||
#include "rdp_settings.h"
|
#include "rdp_settings.h"
|
||||||
|
|
||||||
@ -168,6 +169,11 @@ typedef struct rdp_guac_client_data {
|
|||||||
*/
|
*/
|
||||||
guac_audio_stream* audio;
|
guac_audio_stream* audio;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The filesystem being shared, if any.
|
||||||
|
*/
|
||||||
|
guac_rdp_fs* filesystem;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lock which is locked and unlocked for each RDP message.
|
* Lock which is locked and unlocked for each RDP message.
|
||||||
*/
|
*/
|
||||||
|
@ -95,6 +95,10 @@ int rdp_guac_client_free_handler(guac_client* client) {
|
|||||||
cache_free(rdp_inst->context->cache);
|
cache_free(rdp_inst->context->cache);
|
||||||
freerdp_free(rdp_inst);
|
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 */
|
/* Free client data */
|
||||||
cairo_surface_destroy(guac_client_data->opaque_glyph_surface);
|
cairo_surface_destroy(guac_client_data->opaque_glyph_surface);
|
||||||
cairo_surface_destroy(guac_client_data->trans_glyph_surface);
|
cairo_surface_destroy(guac_client_data->trans_glyph_surface);
|
||||||
|
@ -44,7 +44,8 @@
|
|||||||
#include <guacamole/pool.h>
|
#include <guacamole/pool.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "rdpdr_fs.h"
|
#include "rdp_fs.h"
|
||||||
|
#include "rdp_status.h"
|
||||||
#include "rdpdr_fs_messages.h"
|
#include "rdpdr_fs_messages.h"
|
||||||
#include "rdpdr_fs_messages_vol_info.h"
|
#include "rdpdr_fs_messages_vol_info.h"
|
||||||
#include "rdpdr_fs_messages_file_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 desired_access, file_attributes;
|
||||||
int create_disposition, create_options, path_length;
|
int create_disposition, create_options, path_length;
|
||||||
char path[GUAC_RDPDR_FS_MAX_PATH];
|
char path[GUAC_RDP_FS_MAX_PATH];
|
||||||
|
|
||||||
/* Read "create" information */
|
/* Read "create" information */
|
||||||
Stream_Read_UINT32(input_stream, desired_access);
|
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);
|
path, path_length/2 - 1);
|
||||||
|
|
||||||
/* Open file */
|
/* 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);
|
create_disposition, create_options);
|
||||||
|
|
||||||
/* If an error occurred, notify server */
|
/* 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);
|
"File open refused (%i): \"%s\"", file_id, path);
|
||||||
|
|
||||||
output_stream = guac_rdpdr_new_io_completion(device, completion_id,
|
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_UINT32(output_stream, 0); /* fileId */
|
||||||
Stream_Write_UINT8(output_stream, 0); /* information */
|
Stream_Write_UINT8(output_stream, 0); /* information */
|
||||||
}
|
}
|
||||||
@ -128,13 +130,13 @@ void guac_rdpdr_fs_process_read(guac_rdpdr_device* device,
|
|||||||
length = sizeof(buffer);
|
length = sizeof(buffer);
|
||||||
|
|
||||||
/* Attempt read */
|
/* 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);
|
buffer, length);
|
||||||
|
|
||||||
/* If error, return invalid parameter */
|
/* If error, return invalid parameter */
|
||||||
if (bytes_read < 0) {
|
if (bytes_read < 0) {
|
||||||
output_stream = guac_rdpdr_new_io_completion(device, completion_id,
|
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 */
|
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 */
|
Stream_Seek(input_stream, 20); /* Padding */
|
||||||
|
|
||||||
/* Attempt write */
|
/* Attempt write */
|
||||||
bytes_written = guac_rdpdr_fs_write(device, file_id, offset,
|
bytes_written = guac_rdp_fs_write((guac_rdp_fs*) device->data, file_id,
|
||||||
Stream_Pointer(input_stream), length);
|
offset, Stream_Pointer(input_stream), length);
|
||||||
|
|
||||||
/* If error, return invalid parameter */
|
/* If error, return invalid parameter */
|
||||||
if (bytes_written < 0) {
|
if (bytes_written < 0) {
|
||||||
output_stream = guac_rdpdr_new_io_completion(device, completion_id,
|
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_UINT32(output_stream, 0); /* Length */
|
||||||
Stream_Write_UINT8(output_stream, 0); /* Padding */
|
Stream_Write_UINT8(output_stream, 0); /* Padding */
|
||||||
}
|
}
|
||||||
@ -194,7 +196,7 @@ void guac_rdpdr_fs_process_close(guac_rdpdr_device* device,
|
|||||||
wStream* output_stream;
|
wStream* output_stream;
|
||||||
|
|
||||||
/* Close file */
|
/* 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,
|
output_stream = guac_rdpdr_new_io_completion(device, completion_id,
|
||||||
STATUS_SUCCESS, 4);
|
STATUS_SUCCESS, 4);
|
||||||
@ -354,14 +356,14 @@ void guac_rdpdr_fs_process_query_directory(guac_rdpdr_device* device, wStream* i
|
|||||||
|
|
||||||
wStream* output_stream;
|
wStream* output_stream;
|
||||||
|
|
||||||
guac_rdpdr_fs_file* file;
|
guac_rdp_fs_file* file;
|
||||||
int fs_information_class, initial_query;
|
int fs_information_class, initial_query;
|
||||||
int path_length;
|
int path_length;
|
||||||
|
|
||||||
const char* entry_name;
|
const char* entry_name;
|
||||||
|
|
||||||
/* Get 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)
|
if (file == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -384,22 +386,23 @@ void guac_rdpdr_fs_process_query_directory(guac_rdpdr_device* device, wStream* i
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Find first matching entry in directory */
|
/* 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 */
|
/* Convert to absolute path */
|
||||||
char entry_path[GUAC_RDPDR_FS_MAX_PATH];
|
char entry_path[GUAC_RDP_FS_MAX_PATH];
|
||||||
if (guac_rdpdr_fs_convert_path(file->absolute_path,
|
if (guac_rdp_fs_convert_path(file->absolute_path,
|
||||||
entry_name, entry_path) == 0) {
|
entry_name, entry_path) == 0) {
|
||||||
|
|
||||||
int entry_file_id;
|
int entry_file_id;
|
||||||
|
|
||||||
/* Pattern defined and match fails, continue with next file */
|
/* 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;
|
continue;
|
||||||
|
|
||||||
/* Open directory entry */
|
/* Open directory entry */
|
||||||
entry_file_id = guac_rdpdr_fs_open(device, entry_path,
|
entry_file_id = guac_rdp_fs_open((guac_rdp_fs*) device->data,
|
||||||
ACCESS_FILE_READ_DATA, 0, DISP_FILE_OPEN, 0);
|
entry_path, ACCESS_FILE_READ_DATA, 0, DISP_FILE_OPEN, 0);
|
||||||
|
|
||||||
if (entry_file_id >= 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);
|
fs_information_class);
|
||||||
}
|
}
|
||||||
|
|
||||||
guac_rdpdr_fs_close(device, entry_file_id);
|
guac_rdp_fs_close((guac_rdp_fs*) device->data, entry_file_id);
|
||||||
return;
|
return;
|
||||||
|
|
||||||
} /* end if file exists */
|
} /* end if file exists */
|
||||||
|
@ -45,7 +45,8 @@
|
|||||||
|
|
||||||
#include "rdpdr_service.h"
|
#include "rdpdr_service.h"
|
||||||
#include "rdpdr_messages.h"
|
#include "rdpdr_messages.h"
|
||||||
#include "rdpdr_fs.h"
|
#include "rdp_fs.h"
|
||||||
|
#include "rdp_status.h"
|
||||||
#include "unicode.h"
|
#include "unicode.h"
|
||||||
|
|
||||||
void guac_rdpdr_fs_process_query_directory_info(guac_rdpdr_device* device,
|
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,
|
void guac_rdpdr_fs_process_query_both_directory_info(guac_rdpdr_device* device,
|
||||||
const char* entry_name, int file_id, int completion_id) {
|
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);
|
wStream* output_stream = Stream_New(NULL, 256);
|
||||||
int length = guac_utf8_strlen(entry_name);
|
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);
|
guac_rdp_utf8_to_utf16((const unsigned char*) entry_name, (char*) utf16_entry_name, length);
|
||||||
|
|
||||||
/* Get 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)
|
if (file == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -44,7 +44,8 @@
|
|||||||
#include <guacamole/pool.h>
|
#include <guacamole/pool.h>
|
||||||
|
|
||||||
#include "rdpdr_messages.h"
|
#include "rdpdr_messages.h"
|
||||||
#include "rdpdr_fs.h"
|
#include "rdp_fs.h"
|
||||||
|
#include "rdp_status.h"
|
||||||
#include "rdpdr_service.h"
|
#include "rdpdr_service.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "debug.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) {
|
int file_id, int completion_id) {
|
||||||
|
|
||||||
wStream* output_stream;
|
wStream* output_stream;
|
||||||
guac_rdpdr_fs_file* file;
|
guac_rdp_fs_file* file;
|
||||||
|
|
||||||
/* Get 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)
|
if (file == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -86,11 +87,11 @@ void guac_rdpdr_fs_process_query_standard_info(guac_rdpdr_device* device, wStrea
|
|||||||
int file_id, int completion_id) {
|
int file_id, int completion_id) {
|
||||||
|
|
||||||
wStream* output_stream;
|
wStream* output_stream;
|
||||||
guac_rdpdr_fs_file* file;
|
guac_rdp_fs_file* file;
|
||||||
BOOL is_directory = FALSE;
|
BOOL is_directory = FALSE;
|
||||||
|
|
||||||
/* Get 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)
|
if (file == NULL)
|
||||||
return;
|
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* input_stream, int file_id, int completion_id) {
|
||||||
|
|
||||||
wStream* output_stream;
|
wStream* output_stream;
|
||||||
guac_rdpdr_fs_file* file;
|
guac_rdp_fs_file* file;
|
||||||
|
|
||||||
/* Get 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)
|
if (file == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -147,7 +148,7 @@ void guac_rdpdr_fs_process_set_rename_info(guac_rdpdr_device* device,
|
|||||||
int result;
|
int result;
|
||||||
int filename_length;
|
int filename_length;
|
||||||
wStream* output_stream;
|
wStream* output_stream;
|
||||||
char destination_path[GUAC_RDPDR_FS_MAX_PATH];
|
char destination_path[GUAC_RDP_FS_MAX_PATH];
|
||||||
|
|
||||||
/* Read structure */
|
/* Read structure */
|
||||||
Stream_Seek_UINT8(input_stream); /* ReplaceIfExists */
|
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);
|
destination_path, filename_length/2);
|
||||||
|
|
||||||
/* Perform rename */
|
/* 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)
|
if (result < 0)
|
||||||
output_stream = guac_rdpdr_new_io_completion(device,
|
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
|
else
|
||||||
output_stream = guac_rdpdr_new_io_completion(device,
|
output_stream = guac_rdpdr_new_io_completion(device,
|
||||||
completion_id, STATUS_SUCCESS, 4);
|
completion_id, STATUS_SUCCESS, 4);
|
||||||
|
@ -44,7 +44,8 @@
|
|||||||
#include <guacamole/pool.h>
|
#include <guacamole/pool.h>
|
||||||
|
|
||||||
#include "rdpdr_messages.h"
|
#include "rdpdr_messages.h"
|
||||||
#include "rdpdr_fs.h"
|
#include "rdp_fs.h"
|
||||||
|
#include "rdp_status.h"
|
||||||
#include "rdpdr_service.h"
|
#include "rdpdr_service.h"
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "unicode.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, 12 + GUAC_FILESYSTEM_NAME_LENGTH);
|
||||||
Stream_Write_UINT32(output_stream, FILE_UNICODE_ON_DISK); /* FileSystemAttributes */
|
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_UINT32(output_stream, GUAC_FILESYSTEM_NAME_LENGTH);
|
||||||
Stream_Write(output_stream, GUAC_FILESYSTEM_NAME,
|
Stream_Write(output_stream, GUAC_FILESYSTEM_NAME,
|
||||||
GUAC_FILESYSTEM_NAME_LENGTH);
|
GUAC_FILESYSTEM_NAME_LENGTH);
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
#include <guacamole/pool.h>
|
#include <guacamole/pool.h>
|
||||||
|
|
||||||
#include "rdpdr_fs.h"
|
#include "rdp_fs.h"
|
||||||
#include "rdpdr_fs_messages.h"
|
#include "rdpdr_fs_messages.h"
|
||||||
#include "rdpdr_messages.h"
|
#include "rdpdr_messages.h"
|
||||||
#include "rdpdr_service.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) {
|
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) {
|
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++;
|
int id = rdpdr->devices_registered++;
|
||||||
|
|
||||||
/* Get new device */
|
/* Get new device */
|
||||||
@ -168,9 +165,7 @@ void guac_rdpdr_register_fs(guac_rdpdrPlugin* rdpdr) {
|
|||||||
device->free_handler = guac_rdpdr_device_fs_free_handler;
|
device->free_handler = guac_rdpdr_device_fs_free_handler;
|
||||||
|
|
||||||
/* Init data */
|
/* Init data */
|
||||||
data = device->data = malloc(sizeof(guac_rdpdr_fs_data));
|
device->data = data->filesystem;
|
||||||
data->file_id_pool = guac_pool_alloc(0);
|
|
||||||
data->open_files = 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
63
src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.h
Normal file
63
src/protocols/rdp/guac_rdpdr/rdpdr_fs_service.h
Normal file
@ -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 <guacamole/pool.h>
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
@ -198,30 +198,6 @@
|
|||||||
#define IRP_MN_QUERY_DIRECTORY 0x00000001
|
#define IRP_MN_QUERY_DIRECTORY 0x00000001
|
||||||
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x00000002
|
#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.
|
* Volume information constants.
|
||||||
*/
|
*/
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
#include <guacamole/protocol.h>
|
#include <guacamole/protocol.h>
|
||||||
|
|
||||||
|
#include "rdp_status.h"
|
||||||
#include "rdpdr_messages.h"
|
#include "rdpdr_messages.h"
|
||||||
#include "rdpdr_printer.h"
|
#include "rdpdr_printer.h"
|
||||||
#include "rdpdr_service.h"
|
#include "rdpdr_service.h"
|
||||||
|
@ -54,7 +54,7 @@
|
|||||||
#include "rdpdr_service.h"
|
#include "rdpdr_service.h"
|
||||||
#include "rdpdr_messages.h"
|
#include "rdpdr_messages.h"
|
||||||
#include "rdpdr_printer.h"
|
#include "rdpdr_printer.h"
|
||||||
#include "rdpdr_fs.h"
|
#include "rdpdr_fs_service.h"
|
||||||
|
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
|
|
||||||
|
@ -35,6 +35,8 @@
|
|||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
@ -43,43 +45,46 @@
|
|||||||
#include <fnmatch.h>
|
#include <fnmatch.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#ifdef ENABLE_WINPR
|
|
||||||
#include <winpr/stream.h>
|
|
||||||
#else
|
|
||||||
#include "compat/winpr-stream.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
|
|
||||||
#include <guacamole/pool.h>
|
#include <guacamole/pool.h>
|
||||||
|
|
||||||
#include "rdpdr_messages.h"
|
#include "rdp_fs.h"
|
||||||
#include "rdpdr_fs.h"
|
#include "rdp_status.h"
|
||||||
#include "rdpdr_service.h"
|
|
||||||
#include "client.h"
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "unicode.h"
|
#include "unicode.h"
|
||||||
|
|
||||||
#include <freerdp/utils/svc_plugin.h>
|
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
|
* Translates an absolute Windows virtual_path to an absolute virtual_path
|
||||||
* which is within the "drive virtual_path" specified in the connection
|
* which is within the "drive virtual_path" specified in the connection
|
||||||
* settings.
|
* 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) {
|
const char* virtual_path, char* real_path) {
|
||||||
|
|
||||||
/* Get drive path */
|
/* Get drive path */
|
||||||
rdp_guac_client_data* client_data = (rdp_guac_client_data*) device->rdpdr->client->data;
|
char* drive_path = fs->drive_path;
|
||||||
char* drive_path = client_data->settings.drive_path;
|
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
/* Start with path from settings */
|
/* Start with path from settings */
|
||||||
for (i=0; i<GUAC_RDPDR_FS_MAX_PATH-1; i++) {
|
for (i=0; i<GUAC_RDP_FS_MAX_PATH-1; i++) {
|
||||||
|
|
||||||
/* Break on end-of-string */
|
/* Break on end-of-string */
|
||||||
char c = *(drive_path++);
|
char c = *(drive_path++);
|
||||||
@ -92,7 +97,7 @@ static void __guac_rdpdr_fs_translate_path(guac_rdpdr_device* device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Translate path */
|
/* Translate path */
|
||||||
for (; i<GUAC_RDPDR_FS_MAX_PATH-1; i++) {
|
for (; i<GUAC_RDP_FS_MAX_PATH-1; i++) {
|
||||||
|
|
||||||
/* Stop at end of string */
|
/* Stop at end of string */
|
||||||
char c = *(virtual_path++);
|
char c = *(virtual_path++);
|
||||||
@ -113,56 +118,55 @@ static void __guac_rdpdr_fs_translate_path(guac_rdpdr_device* device,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int guac_rdpdr_fs_get_errorcode(int err) {
|
int guac_rdp_fs_get_errorcode(int err) {
|
||||||
|
|
||||||
/* Translate errno codes to GUAC_RDPDR_FS codes */
|
/* Translate errno codes to GUAC_RDP_FS codes */
|
||||||
if (err == ENFILE) return GUAC_RDPDR_FS_ENFILE;
|
if (err == ENFILE) return GUAC_RDP_FS_ENFILE;
|
||||||
if (err == ENOENT) return GUAC_RDPDR_FS_ENOENT;
|
if (err == ENOENT) return GUAC_RDP_FS_ENOENT;
|
||||||
if (err == ENOTDIR) return GUAC_RDPDR_FS_ENOTDIR;
|
if (err == ENOTDIR) return GUAC_RDP_FS_ENOTDIR;
|
||||||
if (err == ENOSPC) return GUAC_RDPDR_FS_ENOSPC;
|
if (err == ENOSPC) return GUAC_RDP_FS_ENOSPC;
|
||||||
if (err == EISDIR) return GUAC_RDPDR_FS_EISDIR;
|
if (err == EISDIR) return GUAC_RDP_FS_EISDIR;
|
||||||
if (err == EACCES) return GUAC_RDPDR_FS_EACCES;
|
if (err == EACCES) return GUAC_RDP_FS_EACCES;
|
||||||
if (err == EEXIST) return GUAC_RDPDR_FS_EEXIST;
|
if (err == EEXIST) return GUAC_RDP_FS_EEXIST;
|
||||||
if (err == EINVAL) return GUAC_RDPDR_FS_EINVAL;
|
if (err == EINVAL) return GUAC_RDP_FS_EINVAL;
|
||||||
if (err == ENOSYS) return GUAC_RDPDR_FS_ENOSYS;
|
if (err == ENOSYS) return GUAC_RDP_FS_ENOSYS;
|
||||||
if (err == ENOTSUP) return GUAC_RDPDR_FS_ENOTSUP;
|
if (err == ENOTSUP) return GUAC_RDP_FS_ENOTSUP;
|
||||||
|
|
||||||
/* Default to invalid parameter */
|
/* Default to invalid parameter */
|
||||||
return GUAC_RDPDR_FS_EINVAL;
|
return GUAC_RDP_FS_EINVAL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int guac_rdpdr_fs_get_status(int err) {
|
int guac_rdp_fs_get_status(int err) {
|
||||||
|
|
||||||
/* Translate GUAC_RDPDR_FS error code to RDPDR status code */
|
/* Translate GUAC_RDP_FS error code to RDPDR status code */
|
||||||
if (err == GUAC_RDPDR_FS_ENFILE) return STATUS_NO_MORE_FILES;
|
if (err == GUAC_RDP_FS_ENFILE) return STATUS_NO_MORE_FILES;
|
||||||
if (err == GUAC_RDPDR_FS_ENOENT) return STATUS_NO_SUCH_FILE;
|
if (err == GUAC_RDP_FS_ENOENT) return STATUS_NO_SUCH_FILE;
|
||||||
if (err == GUAC_RDPDR_FS_ENOTDIR) return STATUS_NOT_A_DIRECTORY;
|
if (err == GUAC_RDP_FS_ENOTDIR) return STATUS_NOT_A_DIRECTORY;
|
||||||
if (err == GUAC_RDPDR_FS_ENOSPC) return STATUS_DISK_FULL;
|
if (err == GUAC_RDP_FS_ENOSPC) return STATUS_DISK_FULL;
|
||||||
if (err == GUAC_RDPDR_FS_EISDIR) return STATUS_FILE_IS_A_DIRECTORY;
|
if (err == GUAC_RDP_FS_EISDIR) return STATUS_FILE_IS_A_DIRECTORY;
|
||||||
if (err == GUAC_RDPDR_FS_EACCES) return STATUS_ACCESS_DENIED;
|
if (err == GUAC_RDP_FS_EACCES) return STATUS_ACCESS_DENIED;
|
||||||
if (err == GUAC_RDPDR_FS_EEXIST) return STATUS_OBJECT_NAME_COLLISION;
|
if (err == GUAC_RDP_FS_EEXIST) return STATUS_OBJECT_NAME_COLLISION;
|
||||||
if (err == GUAC_RDPDR_FS_EINVAL) return STATUS_INVALID_PARAMETER;
|
if (err == GUAC_RDP_FS_EINVAL) return STATUS_INVALID_PARAMETER;
|
||||||
if (err == GUAC_RDPDR_FS_ENOSYS) return STATUS_NOT_IMPLEMENTED;
|
if (err == GUAC_RDP_FS_ENOSYS) return STATUS_NOT_IMPLEMENTED;
|
||||||
if (err == GUAC_RDPDR_FS_ENOTSUP) return STATUS_NOT_SUPPORTED;
|
if (err == GUAC_RDP_FS_ENOTSUP) return STATUS_NOT_SUPPORTED;
|
||||||
|
|
||||||
/* Default to invalid parameter */
|
/* Default to invalid parameter */
|
||||||
return STATUS_INVALID_PARAMETER;
|
return STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 access, int file_attributes, int create_disposition,
|
||||||
int create_options) {
|
int create_options) {
|
||||||
|
|
||||||
guac_rdpdr_fs_data* data = (guac_rdpdr_fs_data*) device->data;
|
char real_path[GUAC_RDP_FS_MAX_PATH];
|
||||||
char real_path[GUAC_RDPDR_FS_MAX_PATH];
|
char normalized_path[GUAC_RDP_FS_MAX_PATH];
|
||||||
char normalized_path[GUAC_RDPDR_FS_MAX_PATH];
|
|
||||||
|
|
||||||
struct stat file_stat;
|
struct stat file_stat;
|
||||||
int fd;
|
int fd;
|
||||||
int file_id;
|
int file_id;
|
||||||
guac_rdpdr_fs_file* file;
|
guac_rdp_fs_file* file;
|
||||||
|
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
@ -172,9 +176,9 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path,
|
|||||||
create_options);
|
create_options);
|
||||||
|
|
||||||
/* If no files available, return too many open */
|
/* 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.");
|
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 */
|
/* 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 */
|
/* If path is relative, the file does not exist */
|
||||||
else if (path[0] != '\\') {
|
else if (path[0] != '\\') {
|
||||||
GUAC_RDP_DEBUG(1, "Failure - path \"%s\" is relative.", path);
|
GUAC_RDP_DEBUG(1, "Failure - path \"%s\" is relative.", path);
|
||||||
return GUAC_RDPDR_FS_ENOENT;
|
return GUAC_RDP_FS_ENOENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Translate access into flags */
|
/* Translate access into flags */
|
||||||
@ -203,16 +207,16 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path,
|
|||||||
flags |= O_APPEND;
|
flags |= O_APPEND;
|
||||||
|
|
||||||
/* Normalize path, return no-such-file if invalid */
|
/* 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);
|
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\".",
|
GUAC_RDP_DEBUG(2, "Normalized path \"%s\" to \"%s\".",
|
||||||
path, normalized_path);
|
path, normalized_path);
|
||||||
|
|
||||||
/* Translate normalized path to real 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\".",
|
GUAC_RDP_DEBUG(2, "Translated path \"%s\" to \"%s\".",
|
||||||
normalized_path, real_path);
|
normalized_path, real_path);
|
||||||
@ -252,7 +256,7 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path,
|
|||||||
|
|
||||||
/* Unrecognised disposition */
|
/* Unrecognised disposition */
|
||||||
default:
|
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)) {
|
if (mkdir(real_path, S_IRWXU)) {
|
||||||
GUAC_RDP_DEBUG(1, "mkdir() failed: %s", strerror(errno));
|
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() */
|
/* 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);
|
fd = open(real_path, flags, S_IRUSR | S_IWUSR);
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
GUAC_RDP_DEBUG(1, "open() failed: %s", strerror(errno));
|
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 */
|
/* Get file ID, init file */
|
||||||
file_id = guac_pool_next_int(data->file_id_pool);
|
file_id = guac_pool_next_int(fs->file_id_pool);
|
||||||
file = &(data->files[file_id]);
|
file = &(fs->files[file_id]);
|
||||||
file->fd = fd;
|
file->fd = fd;
|
||||||
file->dir = NULL;
|
file->dir = NULL;
|
||||||
file->dir_pattern[0] = '\0';
|
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 */
|
/* If information cannot be retrieved, fake it */
|
||||||
else {
|
else {
|
||||||
|
|
||||||
guac_client_log_info(device->rdpdr->client,
|
|
||||||
"Unable to read information for \"%s\"",
|
|
||||||
real_path);
|
|
||||||
|
|
||||||
/* Init information to 0, lacking any alternative */
|
/* Init information to 0, lacking any alternative */
|
||||||
file->size = 0;
|
file->size = 0;
|
||||||
file->ctime = 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;
|
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) {
|
void* buffer, int length) {
|
||||||
|
|
||||||
int bytes_read;
|
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) {
|
if (file == NULL) {
|
||||||
GUAC_RDP_DEBUG(1, "Read from bad file_id: %i", file_id);
|
GUAC_RDP_DEBUG(1, "Read from bad file_id: %i", file_id);
|
||||||
return GUAC_RDPDR_FS_EINVAL;
|
return GUAC_RDP_FS_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attempt read */
|
/* Attempt read */
|
||||||
@ -343,21 +343,21 @@ int guac_rdpdr_fs_read(guac_rdpdr_device* device, int file_id, int offset,
|
|||||||
|
|
||||||
/* Translate errno on error */
|
/* Translate errno on error */
|
||||||
if (bytes_read < 0)
|
if (bytes_read < 0)
|
||||||
return guac_rdpdr_fs_get_errorcode(errno);
|
return guac_rdp_fs_get_errorcode(errno);
|
||||||
|
|
||||||
return bytes_read;
|
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) {
|
void* buffer, int length) {
|
||||||
|
|
||||||
int bytes_written;
|
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) {
|
if (file == NULL) {
|
||||||
GUAC_RDP_DEBUG(1, "Write to bad file_id: %i", file_id);
|
GUAC_RDP_DEBUG(1, "Write to bad file_id: %i", file_id);
|
||||||
return GUAC_RDPDR_FS_EINVAL;
|
return GUAC_RDP_FS_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Attempt write */
|
/* Attempt write */
|
||||||
@ -366,32 +366,32 @@ int guac_rdpdr_fs_write(guac_rdpdr_device* device, int file_id, int offset,
|
|||||||
|
|
||||||
/* Translate errno on error */
|
/* Translate errno on error */
|
||||||
if (bytes_written < 0)
|
if (bytes_written < 0)
|
||||||
return guac_rdpdr_fs_get_errorcode(errno);
|
return guac_rdp_fs_get_errorcode(errno);
|
||||||
|
|
||||||
return bytes_written;
|
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) {
|
const char* new_path) {
|
||||||
|
|
||||||
char real_path[GUAC_RDPDR_FS_MAX_PATH];
|
char real_path[GUAC_RDP_FS_MAX_PATH];
|
||||||
char normalized_path[GUAC_RDPDR_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) {
|
if (file == NULL) {
|
||||||
GUAC_RDP_DEBUG(1, "Rename of bad file_id: %i", file_id);
|
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 */
|
/* 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);
|
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 */
|
/* 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);
|
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)) {
|
if (rename(file->real_path, real_path)) {
|
||||||
GUAC_RDP_DEBUG(1, "rename() failed: \"%s\" -> \"%s\"",
|
GUAC_RDP_DEBUG(1, "rename() failed: \"%s\" -> \"%s\"",
|
||||||
file->real_path, real_path);
|
file->real_path, real_path);
|
||||||
return guac_rdpdr_fs_get_errorcode(errno);
|
return guac_rdp_fs_get_errorcode(errno);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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_rdp_fs_file* file = guac_rdp_fs_get_file(fs, file_id);
|
||||||
|
|
||||||
guac_rdpdr_fs_file* file = guac_rdpdr_fs_get_file(device, file_id);
|
|
||||||
if (file == NULL) {
|
if (file == NULL) {
|
||||||
GUAC_RDP_DEBUG(2, "Ignoring close for bad file_id: %i",
|
GUAC_RDP_DEBUG(2, "Ignoring close for bad file_id: %i",
|
||||||
file_id);
|
file_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
file = &(data->files[file_id]);
|
file = &(fs->files[file_id]);
|
||||||
|
|
||||||
GUAC_RDP_DEBUG(2, "Closed \"%s\" (file_id=%i)",
|
GUAC_RDP_DEBUG(2, "Closed \"%s\" (file_id=%i)",
|
||||||
file->absolute_path, file_id);
|
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(file->real_path);
|
||||||
|
|
||||||
/* Free ID back to pool */
|
/* Free ID back to pool */
|
||||||
guac_pool_free_int(data->file_id_pool, file_id);
|
guac_pool_free_int(fs->file_id_pool, file_id);
|
||||||
data->open_files--;
|
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_rdp_fs_file* file;
|
||||||
guac_rdpdr_fs_file* file;
|
|
||||||
|
|
||||||
struct dirent* result;
|
struct dirent* result;
|
||||||
|
|
||||||
/* Only read if file ID is valid */
|
/* 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;
|
return NULL;
|
||||||
|
|
||||||
file = &(data->files[file_id]);
|
file = &(fs->files[file_id]);
|
||||||
|
|
||||||
/* Open directory if not yet open, stop if error */
|
/* Open directory if not yet open, stop if error */
|
||||||
if (file->dir == NULL) {
|
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 i;
|
||||||
int path_depth = 0;
|
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* path_components[64];
|
||||||
|
|
||||||
const char** current_path_component = &(path_components[0]);
|
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++;
|
path++;
|
||||||
|
|
||||||
/* Copy path into component data for parsing */
|
/* 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 */
|
/* Find path components within path */
|
||||||
for (i=0; i<GUAC_RDPDR_FS_MAX_PATH; i++) {
|
for (i=0; i<GUAC_RDP_FS_MAX_PATH; i++) {
|
||||||
|
|
||||||
/* If current character is a path separator, parse as component */
|
/* If current character is a path separator, parse as component */
|
||||||
char c = path_component_data[i];
|
char c = path_component_data[i];
|
||||||
@ -553,14 +550,14 @@ int guac_rdpdr_fs_normalize_path(const char* path, char* abs_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) {
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
char combined_path[GUAC_RDPDR_FS_MAX_PATH];
|
char combined_path[GUAC_RDP_FS_MAX_PATH];
|
||||||
char* current = combined_path;
|
char* current = combined_path;
|
||||||
|
|
||||||
/* Copy parent path */
|
/* Copy parent path */
|
||||||
for (i=0; i<GUAC_RDPDR_FS_MAX_PATH; i++) {
|
for (i=0; i<GUAC_RDP_FS_MAX_PATH; i++) {
|
||||||
|
|
||||||
char c = *(parent++);
|
char c = *(parent++);
|
||||||
if (c == 0)
|
if (c == 0)
|
||||||
@ -574,27 +571,25 @@ int guac_rdpdr_fs_convert_path(const char* parent, const char* rel_path, char* a
|
|||||||
*(current++) = '\\';
|
*(current++) = '\\';
|
||||||
|
|
||||||
/* Copy remaining path */
|
/* Copy remaining path */
|
||||||
strncpy(current, rel_path, GUAC_RDPDR_FS_MAX_PATH-i-2);
|
strncpy(current, rel_path, GUAC_RDP_FS_MAX_PATH-i-2);
|
||||||
|
|
||||||
/* Normalize into provided buffer */
|
/* Normalize into provided buffer */
|
||||||
return guac_rdpdr_fs_normalize_path(combined_path, abs_path);
|
return guac_rdp_fs_normalize_path(combined_path, abs_path);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
guac_rdpdr_fs_file* guac_rdpdr_fs_get_file(guac_rdpdr_device* device,
|
guac_rdp_fs_file* guac_rdp_fs_get_file(guac_rdp_fs* fs, int file_id) {
|
||||||
int file_id) {
|
|
||||||
|
|
||||||
/* Validate ID */
|
/* Validate ID */
|
||||||
guac_rdpdr_fs_data* data = (guac_rdpdr_fs_data*) device->data;
|
if (file_id < 0 || file_id >= GUAC_RDP_FS_MAX_FILES)
|
||||||
if (file_id < 0 || file_id >= GUAC_RDPDR_FS_MAX_FILES)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Return file at given ID */
|
/* 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;
|
return fnmatch(pattern, filename, FNM_NOESCAPE) != 0;
|
||||||
}
|
}
|
||||||
|
|
@ -35,101 +35,89 @@
|
|||||||
*
|
*
|
||||||
* ***** END LICENSE BLOCK ***** */
|
* ***** END LICENSE BLOCK ***** */
|
||||||
|
|
||||||
#ifndef __GUAC_RDPDR_FS_H
|
#ifndef __GUAC_RDP_FS_H
|
||||||
#define __GUAC_RDPDR_FS_H
|
#define __GUAC_RDP_FS_H
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functions and macros specific to filesystem handling and initialization
|
* 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.
|
* directly, but their semantics must not deal with RDP protocol messaging.
|
||||||
* Functions here represent a virtual Windows-style filesystem on top of UNIX
|
* 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.
|
* for common data.
|
||||||
*
|
*
|
||||||
* @file rdpdr_fs.h
|
* @file rdp_fs.h
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef ENABLE_WINPR
|
|
||||||
#include <winpr/stream.h>
|
|
||||||
#else
|
|
||||||
#include "compat/winpr-stream.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
|
||||||
#include <guacamole/pool.h>
|
#include <guacamole/pool.h>
|
||||||
|
|
||||||
#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.
|
* 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.
|
* 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.
|
* 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.
|
* 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
|
* Error code returned when the operation required a directory
|
||||||
* but the file was not 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
|
* Error code returned when insufficient space exists to complete
|
||||||
* the operation.
|
* 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
|
* Error code returned when the operation requires a normal file but
|
||||||
* a directory was given.
|
* a directory was given.
|
||||||
*/
|
*/
|
||||||
#define GUAC_RDPDR_FS_EISDIR -5
|
#define GUAC_RDP_FS_EISDIR -5
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error code returned when permission is denied.
|
* 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
|
* Error code returned when the operation cannot be completed because the
|
||||||
* file already exists.
|
* file already exists.
|
||||||
*/
|
*/
|
||||||
#define GUAC_RDPDR_FS_EEXIST -7
|
#define GUAC_RDP_FS_EEXIST -7
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error code returned when invalid parameters were given.
|
* 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.
|
* 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.
|
* Error code returned when the operation is not supported.
|
||||||
*/
|
*/
|
||||||
#define GUAC_RDPDR_FS_ENOTSUP -10
|
#define GUAC_RDP_FS_ENOTSUP -10
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Access constants.
|
* Access constants.
|
||||||
@ -201,7 +189,7 @@
|
|||||||
/**
|
/**
|
||||||
* An arbitrary file on the virtual filesystem of the Guacamole drive.
|
* 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.
|
* 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.
|
* 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.
|
* Bitwise OR of all associated Windows file attributes.
|
||||||
@ -260,12 +248,17 @@ typedef struct guac_rdpdr_fs_file {
|
|||||||
*/
|
*/
|
||||||
uint64_t atime;
|
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.
|
* The number of currently open files.
|
||||||
@ -280,37 +273,41 @@ typedef struct guac_rdpdr_fs_data {
|
|||||||
/**
|
/**
|
||||||
* All available file structures.
|
* 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
|
* Allocates a new filesystem given a root path.
|
||||||
* before RDPDR connection finishes.
|
|
||||||
*/
|
*/
|
||||||
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
|
* 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.
|
* 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
|
* Returns the next available file ID, or an error code less than zero
|
||||||
* if an error occurs.
|
* 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 access, int file_attributes, int create_disposition,
|
||||||
int create_options);
|
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,
|
* file having the given ID. Returns the number of bytes read, zero on EOF,
|
||||||
* and an error code if an error occurs.
|
* 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);
|
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
|
* file having the given ID. Returns the number of bytes written, and an
|
||||||
* error code if an error occurs.
|
* 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);
|
void* buffer, int length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renames (moves) the file with the given ID to the new path specified.
|
* 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.
|
* 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);
|
const char* new_path);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Frees the given file ID, allowing future open operations to reuse it.
|
* 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
|
* Given an arbitrary path, which may contain ".." and ".", creates an
|
||||||
* absolute path which does NOT contain ".." or ".".
|
* 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.
|
* 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,
|
* Returns the next filename within the directory having the given file ID,
|
||||||
* or NULL if no more files.
|
* 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.
|
* 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,
|
guac_rdp_fs_file* guac_rdp_fs_get_file(guac_rdp_fs* fs, int file_id);
|
||||||
int file_id);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns whether the given filename matches the given pattern.
|
* 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
|
#endif
|
||||||
|
|
69
src/protocols/rdp/rdp_status.h
Normal file
69
src/protocols/rdp/rdp_status.h
Normal file
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user