From 296836f65d04c966bc4dd9819e9597f0361dc141 Mon Sep 17 00:00:00 2001 From: Michael Jumper Date: Tue, 5 Nov 2013 00:48:55 -0800 Subject: [PATCH] Implement file truncation. --- .../guac_rdpdr/rdpdr_fs_messages_file_info.c | 42 +++++++++++++------ src/protocols/rdp/rdp_fs.c | 20 +++++++++ src/protocols/rdp/rdp_fs.h | 8 +++- 3 files changed, 57 insertions(+), 13 deletions(-) diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c index dbb10427..fa2e057a 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_file_info.c @@ -177,15 +177,24 @@ void guac_rdpdr_fs_process_set_rename_info(guac_rdpdr_device* device, void guac_rdpdr_fs_process_set_allocation_info(guac_rdpdr_device* device, wStream* input_stream, int file_id, int completion_id, int length) { - wStream* output_stream = guac_rdpdr_new_io_completion(device, - completion_id, STATUS_SUCCESS, 4); + int result; + UINT64 size; + wStream* output_stream; + + /* Read new size */ + Stream_Read_UINT64(input_stream, size); /* AllocationSize */ + + /* Truncate file */ + result = guac_rdp_fs_truncate((guac_rdp_fs*) device->data, file_id, size); + if (result < 0) + output_stream = guac_rdpdr_new_io_completion(device, + completion_id, guac_rdp_fs_get_status(result), 4); + else + output_stream = guac_rdpdr_new_io_completion(device, + completion_id, STATUS_SUCCESS, 4); - /* Currently do nothing, just respond */ Stream_Write_UINT32(output_stream, length); - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); - GUAC_RDP_DEBUG(2, "Sent STATUS_SUCCESS for completion_id=%i", - completion_id); } @@ -214,15 +223,24 @@ void guac_rdpdr_fs_process_set_disposition_info(guac_rdpdr_device* device, void guac_rdpdr_fs_process_set_end_of_file_info(guac_rdpdr_device* device, wStream* input_stream, int file_id, int completion_id, int length) { - wStream* output_stream = guac_rdpdr_new_io_completion(device, - completion_id, STATUS_SUCCESS, 4); + int result; + UINT64 size; + wStream* output_stream; + + /* Read new size */ + Stream_Read_UINT64(input_stream, size); /* AllocationSize */ + + /* Truncate file */ + result = guac_rdp_fs_truncate((guac_rdp_fs*) device->data, file_id, size); + if (result < 0) + output_stream = guac_rdpdr_new_io_completion(device, + completion_id, guac_rdp_fs_get_status(result), 4); + else + output_stream = guac_rdpdr_new_io_completion(device, + completion_id, STATUS_SUCCESS, 4); - /* Currently do nothing, just respond */ Stream_Write_UINT32(output_stream, length); - svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); - GUAC_RDP_DEBUG(2, "Sent STATUS_SUCCESS for completion_id=%i", - completion_id); } diff --git a/src/protocols/rdp/rdp_fs.c b/src/protocols/rdp/rdp_fs.c index 9c604c8c..48e1892c 100644 --- a/src/protocols/rdp/rdp_fs.c +++ b/src/protocols/rdp/rdp_fs.c @@ -429,6 +429,26 @@ int guac_rdp_fs_delete(guac_rdp_fs* fs, int file_id) { } +int guac_rdp_fs_truncate(guac_rdp_fs* fs, int file_id, int length) { + + /* Get file */ + guac_rdp_fs_file* file = guac_rdp_fs_get_file(fs, file_id); + if (file == NULL) { + GUAC_RDP_DEBUG(1, "Delete of bad file_id: %i", file_id); + return GUAC_RDP_FS_EINVAL; + } + + /* Attempt truncate */ + if (ftruncate(file->fd, length)) { + GUAC_RDP_DEBUG(1, "ftruncate() to %i bytes failed: \"%s\"", + length, file->real_path); + return guac_rdp_fs_get_errorcode(errno); + } + + return 0; + +} + void guac_rdp_fs_close(guac_rdp_fs* fs, int file_id) { guac_rdp_fs_file* file = guac_rdp_fs_get_file(fs, file_id); diff --git a/src/protocols/rdp/rdp_fs.h b/src/protocols/rdp/rdp_fs.h index c9990b0e..96490781 100644 --- a/src/protocols/rdp/rdp_fs.h +++ b/src/protocols/rdp/rdp_fs.h @@ -342,10 +342,16 @@ int guac_rdp_fs_rename(guac_rdp_fs* fs, int file_id, const char* new_path); /** - * Deletes the gile with the given ID. + * Deletes the file with the given ID. */ int guac_rdp_fs_delete(guac_rdp_fs* fs, int file_id); +/** + * Truncates the file with the given ID to the given length (in bytes), which + * may be larger. + */ +int guac_rdp_fs_truncate(guac_rdp_fs* fs, int file_id, int length); + /** * Frees the given file ID, allowing future open operations to reuse it. */