Add constants. More open() implementation. Handle case where no file IDs are available.
This commit is contained in:
parent
d9cae3d361
commit
2e4a67200c
@ -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--;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user