Separate RDP filesystem operations from RDPDR.

This commit is contained in:
Michael Jumper 2013-11-04 00:50:10 -08:00
parent 28c3c7d926
commit aacb726b66
16 changed files with 357 additions and 236 deletions

View File

@ -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

View File

@ -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);

View File

@ -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.
*/

View File

@ -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);

View File

@ -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 */

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View 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

View File

@ -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.
*/

View File

@ -11,6 +11,7 @@
#include <guacamole/protocol.h>
#include "rdp_status.h"
#include "rdpdr_messages.h"
#include "rdpdr_printer.h"
#include "rdpdr_service.h"

View File

@ -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"

View File

@ -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;
}

View File

@ -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

View 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