Add constants. More open() implementation. Handle case where no file IDs are available.

This commit is contained in:
Michael Jumper 2013-07-26 14:11:44 -07:00
parent d9cae3d361
commit 2e4a67200c
4 changed files with 124 additions and 22 deletions

View File

@ -71,18 +71,11 @@ static void guac_rdpdr_fs_process_create(guac_rdpdr_device* device,
Stream_Read_UINT32(input_stream, create_options);
Stream_Read_UINT32(input_stream, path_length);
/* Convert path to UTF-8 */
guac_rdp_utf16_to_utf8(Stream_Pointer(input_stream), path, path_length/2 - 1);
path[path_length-1] = 0;
/* Open file */
file_id = guac_rdpdr_fs_open(device);
/* FIXME: Assuming file IDs are available */
guac_client_log_info(device->rdpdr->client, "Opened file %s ... new id=%i", path, file_id);
guac_client_log_info(device->rdpdr->client,
"des=%i, attrib=%i, shared=%i, disp=%i, opt=%i",
desired_access, file_attributes, shared_access, create_disposition,
create_options);
file_id = guac_rdpdr_fs_open(device, path);
/* Write header */
Stream_Write_UINT16(output_stream, RDPDR_CTYP_CORE);
@ -91,9 +84,27 @@ static void guac_rdpdr_fs_process_create(guac_rdpdr_device* device,
/* Write content */
Stream_Write_UINT32(output_stream, device->device_id);
Stream_Write_UINT32(output_stream, completion_id);
Stream_Write_UINT32(output_stream, 0); /* Success */
Stream_Write_UINT32(output_stream, file_id); /* fileId */
Stream_Write_UINT8(output_stream, FILE_OPENED);
/* If no file IDs available, notify server */
if (file_id == -1) {
guac_client_log_error(device->rdpdr->client, "File open refused - too many open files");
Stream_Write_UINT32(output_stream, STATUS_TOO_MANY_OPENED_FILES);
Stream_Write_UINT32(output_stream, 0); /* fileId */
Stream_Write_UINT8(output_stream, 0); /* information */
}
else {
guac_client_log_info(device->rdpdr->client, "Opened file \"%s\" ... new id=%i", path, file_id);
guac_client_log_info(device->rdpdr->client,
"des=%i, attrib=%i, shared=%i, disp=%i, opt=%i",
desired_access, file_attributes, shared_access, create_disposition,
create_options);
Stream_Write_UINT32(output_stream, STATUS_SUCCESS);
Stream_Write_UINT32(output_stream, file_id); /* fileId */
Stream_Write_UINT8(output_stream, FILE_OPENED); /* information */
}
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
@ -127,7 +138,7 @@ static void guac_rdpdr_fs_process_close(guac_rdpdr_device* device,
/* Write content */
Stream_Write_UINT32(output_stream, device->device_id);
Stream_Write_UINT32(output_stream, completion_id);
Stream_Write_UINT32(output_stream, 0); /* Success */
Stream_Write_UINT32(output_stream, STATUS_SUCCESS);
Stream_Write(output_stream, "\0\0\0\0\0", 5); /* Padding */
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
@ -248,15 +259,31 @@ void guac_rdpdr_register_fs(guac_rdpdrPlugin* rdpdr) {
}
int guac_rdpdr_fs_open(guac_rdpdr_device* device) {
int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path) {
guac_rdpdr_fs_data* data = (guac_rdpdr_fs_data*) device->data;
/* If files available, allocate a new file ID */
if (data->open_files < GUAC_RDPDR_FS_MAX_FILES) {
/* Get file ID */
int file_id = guac_pool_next_int(data->file_id_pool);
guac_rdpdr_fs_file* file = &(data->files[file_id]);
data->open_files++;
/* If path is empty, it refers to the volume itself */
if (path[0] == '\0')
file->type = GUAC_RDPDR_FS_VOLUME;
/* Otherwise, parse path */
else {
file->type = GUAC_RDPDR_FS_FILE;
/* STUB */
}
return file_id;
}
@ -267,8 +294,14 @@ int guac_rdpdr_fs_open(guac_rdpdr_device* device) {
}
void guac_rdpdr_fs_close(guac_rdpdr_device* device, int file_id) {
guac_rdpdr_fs_data* data = (guac_rdpdr_fs_data*) device->data;
guac_pool_free_int(data->file_id_pool, file_id);
data->open_files--;
/* Only close if file ID is valid */
if (file_id >= 0 && file_id <= GUAC_RDPDR_FS_MAX_FILES-1) {
guac_pool_free_int(data->file_id_pool, file_id);
data->open_files--;
}
}

View File

@ -66,6 +66,43 @@
#define FILE_OPENED 0x00000001
#define FILE_OVERWRITTEN 0x00000003
/**
* Enumeration of all supported file types.
*/
typedef enum guac_rdpdr_fs_file_type {
/**
* A regular file - either a file or directory.
*/
GUAC_RDPDR_FS_FILE,
/**
* A disk device - here, this is always virtual, and always the containing
* volume (the Guacamole drive).
*/
GUAC_RDPDR_FS_VOLUME,
} guac_rdpdr_fs_file_type;
/**
* An arbitrary file on the virtual filesystem of the Guacamole drive.
*/
typedef struct guac_rdpdr_fs_file {
/**
* The type of this file - either a FILE (file or directory) or a
* VOLUME (virtual file, represents the virtual device represented by
* the Guacamole drive).
*/
guac_rdpdr_fs_file_type type;
/**
* Associated local file descriptor.
*/
int fd;
} guac_rdpdr_fs_file;
/**
* Data specific to an instance of the printer device.
*/
@ -81,6 +118,11 @@ typedef struct guac_rdpdr_fs_data {
*/
guac_pool* file_id_pool;
/**
* All available file structures.
*/
guac_rdpdr_fs_file files[GUAC_RDPDR_FS_MAX_FILES];
} guac_rdpdr_fs_data;
/**
@ -92,7 +134,7 @@ void guac_rdpdr_register_fs(guac_rdpdrPlugin* rdpdr);
/**
* Returns the next available file ID, or -1 if none available.
*/
int guac_rdpdr_fs_open(guac_rdpdr_device* device);
int guac_rdpdr_fs_open(guac_rdpdr_device* device, const char* path);
/**
* Frees the given file ID, allowing future open operations to reuse it.

View File

@ -192,6 +192,33 @@
#define IRP_MN_QUERY_DIRECTORY 0x00000001
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x00000002
/*
* Status constants.
*/
#define STATUS_SUCCESS 0x00000000
#define STATUS_DEVICE_OFF_LINE 0x80000010
#define STATUS_NO_SUCH_FILE 0xC000000F
#define STATUS_END_OF_FILE 0xC0000011
#define STATUS_FILE_INVALID 0xC0000098
#define STATUS_FILE_IS_A_DIRECTORY 0xC00000BA
#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.
*/
#define FileFsVolumeInformation 0x00000001
#define FileFsSizeInformation 0x00000003
#define FileFsDeviceInformation 0x00000004
#define FileFsAttributeInformation 0x00000005
#define FileFsFullSizeInformation 0x00000007
/*
* Message handlers.
*/

View File

@ -155,7 +155,7 @@ void guac_rdpdr_process_print_job_create(guac_rdpdr_device* device,
/* Write content */
Stream_Write_UINT32(output_stream, device->device_id);
Stream_Write_UINT32(output_stream, completion_id);
Stream_Write_UINT32(output_stream, 0); /* Success */
Stream_Write_UINT32(output_stream, STATUS_SUCCESS);
Stream_Write_UINT32(output_stream, 0); /* fileId */
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
@ -223,7 +223,7 @@ void guac_rdpdr_process_print_job_write(guac_rdpdr_device* device,
/* Start print process */
if (guac_rdpdr_create_print_process(device) != 0) {
status = 0x80000010;
status = STATUS_DEVICE_OFF_LINE;
length = 0;
}
@ -238,7 +238,7 @@ void guac_rdpdr_process_print_job_write(guac_rdpdr_device* device,
length = write(printer_data->printer_input, buffer, length);
if (length == -1) {
guac_client_log_error(device->rdpdr->client, "Error writing to printer: %s", strerror(errno));
status = 0x80000010;
status = STATUS_DEVICE_OFF_LINE;
length = 0;
}
@ -283,7 +283,7 @@ void guac_rdpdr_process_print_job_close(guac_rdpdr_device* device,
/* Write content */
Stream_Write_UINT32(output_stream, device->device_id);
Stream_Write_UINT32(output_stream, completion_id);
Stream_Write_UINT32(output_stream, 0); /* NTSTATUS - success */
Stream_Write_UINT32(output_stream, STATUS_SUCCESS);
Stream_Write_UINT32(output_stream, 0); /* padding*/
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);