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 \
|
||||
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
|
||||
|
@ -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);
|
||||
|
@ -48,6 +48,7 @@
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/audio.h>
|
||||
|
||||
#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.
|
||||
*/
|
||||
|
@ -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);
|
||||
|
@ -44,7 +44,8 @@
|
||||
#include <guacamole/pool.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_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 */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -44,7 +44,8 @@
|
||||
#include <guacamole/pool.h>
|
||||
|
||||
#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);
|
||||
|
@ -44,7 +44,8 @@
|
||||
#include <guacamole/pool.h>
|
||||
|
||||
#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);
|
||||
|
@ -43,7 +43,7 @@
|
||||
|
||||
#include <guacamole/pool.h>
|
||||
|
||||
#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;
|
||||
|
||||
}
|
||||
|
||||
|
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_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.
|
||||
*/
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <guacamole/protocol.h>
|
||||
|
||||
#include "rdp_status.h"
|
||||
#include "rdpdr_messages.h"
|
||||
#include "rdpdr_printer.h"
|
||||
#include "rdpdr_service.h"
|
||||
|
@ -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"
|
||||
|
||||
|
@ -35,6 +35,8 @@
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
@ -43,43 +45,46 @@
|
||||
#include <fnmatch.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 "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 <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
|
||||
* 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; i<GUAC_RDPDR_FS_MAX_PATH-1; i++) {
|
||||
for (i=0; i<GUAC_RDP_FS_MAX_PATH-1; i++) {
|
||||
|
||||
/* Break on end-of-string */
|
||||
char c = *(drive_path++);
|
||||
@ -92,7 +97,7 @@ static void __guac_rdpdr_fs_translate_path(guac_rdpdr_device* device,
|
||||
}
|
||||
|
||||
/* 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 */
|
||||
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 */
|
||||
if (err == ENFILE) return GUAC_RDPDR_FS_ENFILE;
|
||||
if (err == ENOENT) return GUAC_RDPDR_FS_ENOENT;
|
||||
if (err == ENOTDIR) return GUAC_RDPDR_FS_ENOTDIR;
|
||||
if (err == ENOSPC) return GUAC_RDPDR_FS_ENOSPC;
|
||||
if (err == EISDIR) return GUAC_RDPDR_FS_EISDIR;
|
||||
if (err == EACCES) return GUAC_RDPDR_FS_EACCES;
|
||||
if (err == EEXIST) return GUAC_RDPDR_FS_EEXIST;
|
||||
if (err == EINVAL) return GUAC_RDPDR_FS_EINVAL;
|
||||
if (err == ENOSYS) return GUAC_RDPDR_FS_ENOSYS;
|
||||
if (err == ENOTSUP) return GUAC_RDPDR_FS_ENOTSUP;
|
||||
/* Translate errno codes to GUAC_RDP_FS codes */
|
||||
if (err == ENFILE) return GUAC_RDP_FS_ENFILE;
|
||||
if (err == ENOENT) return GUAC_RDP_FS_ENOENT;
|
||||
if (err == ENOTDIR) return GUAC_RDP_FS_ENOTDIR;
|
||||
if (err == ENOSPC) return GUAC_RDP_FS_ENOSPC;
|
||||
if (err == EISDIR) return GUAC_RDP_FS_EISDIR;
|
||||
if (err == EACCES) return GUAC_RDP_FS_EACCES;
|
||||
if (err == EEXIST) return GUAC_RDP_FS_EEXIST;
|
||||
if (err == EINVAL) return GUAC_RDP_FS_EINVAL;
|
||||
if (err == ENOSYS) return GUAC_RDP_FS_ENOSYS;
|
||||
if (err == ENOTSUP) return GUAC_RDP_FS_ENOTSUP;
|
||||
|
||||
/* 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 */
|
||||
if (err == GUAC_RDPDR_FS_ENFILE) return STATUS_NO_MORE_FILES;
|
||||
if (err == GUAC_RDPDR_FS_ENOENT) return STATUS_NO_SUCH_FILE;
|
||||
if (err == GUAC_RDPDR_FS_ENOTDIR) return STATUS_NOT_A_DIRECTORY;
|
||||
if (err == GUAC_RDPDR_FS_ENOSPC) return STATUS_DISK_FULL;
|
||||
if (err == GUAC_RDPDR_FS_EISDIR) return STATUS_FILE_IS_A_DIRECTORY;
|
||||
if (err == GUAC_RDPDR_FS_EACCES) return STATUS_ACCESS_DENIED;
|
||||
if (err == GUAC_RDPDR_FS_EEXIST) return STATUS_OBJECT_NAME_COLLISION;
|
||||
if (err == GUAC_RDPDR_FS_EINVAL) return STATUS_INVALID_PARAMETER;
|
||||
if (err == GUAC_RDPDR_FS_ENOSYS) return STATUS_NOT_IMPLEMENTED;
|
||||
if (err == GUAC_RDPDR_FS_ENOTSUP) return STATUS_NOT_SUPPORTED;
|
||||
/* Translate GUAC_RDP_FS error code to RDPDR status code */
|
||||
if (err == GUAC_RDP_FS_ENFILE) return STATUS_NO_MORE_FILES;
|
||||
if (err == GUAC_RDP_FS_ENOENT) return STATUS_NO_SUCH_FILE;
|
||||
if (err == GUAC_RDP_FS_ENOTDIR) return STATUS_NOT_A_DIRECTORY;
|
||||
if (err == GUAC_RDP_FS_ENOSPC) return STATUS_DISK_FULL;
|
||||
if (err == GUAC_RDP_FS_EISDIR) return STATUS_FILE_IS_A_DIRECTORY;
|
||||
if (err == GUAC_RDP_FS_EACCES) return STATUS_ACCESS_DENIED;
|
||||
if (err == GUAC_RDP_FS_EEXIST) return STATUS_OBJECT_NAME_COLLISION;
|
||||
if (err == GUAC_RDP_FS_EINVAL) return STATUS_INVALID_PARAMETER;
|
||||
if (err == GUAC_RDP_FS_ENOSYS) return STATUS_NOT_IMPLEMENTED;
|
||||
if (err == GUAC_RDP_FS_ENOTSUP) return STATUS_NOT_SUPPORTED;
|
||||
|
||||
/* Default to 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 create_options) {
|
||||
|
||||
guac_rdpdr_fs_data* data = (guac_rdpdr_fs_data*) device->data;
|
||||
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; 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 */
|
||||
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;
|
||||
char combined_path[GUAC_RDPDR_FS_MAX_PATH];
|
||||
char combined_path[GUAC_RDP_FS_MAX_PATH];
|
||||
char* current = combined_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++);
|
||||
if (c == 0)
|
||||
@ -574,27 +571,25 @@ int guac_rdpdr_fs_convert_path(const char* parent, const char* rel_path, char* a
|
||||
*(current++) = '\\';
|
||||
|
||||
/* 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 */
|
||||
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,
|
||||
int file_id) {
|
||||
guac_rdp_fs_file* guac_rdp_fs_get_file(guac_rdp_fs* fs, int file_id) {
|
||||
|
||||
/* Validate ID */
|
||||
guac_rdpdr_fs_data* data = (guac_rdpdr_fs_data*) device->data;
|
||||
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;
|
||||
}
|
||||
|
@ -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 <winpr/stream.h>
|
||||
#else
|
||||
#include "compat/winpr-stream.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdint.h>
|
||||
#include <dirent.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.
|
||||
*/
|
||||
#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
|
||||
|
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