diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_vol_info.c b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_vol_info.c index 1ebbaec7..2f619a15 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_vol_info.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_fs_messages_vol_info.c @@ -48,6 +48,7 @@ #include "rdp_status.h" #include "rdpdr_service.h" #include "client.h" +#include "debug.h" #include "unicode.h" #include @@ -106,8 +107,21 @@ void guac_rdpdr_fs_process_query_attribute_info(guac_rdpdr_device* device, wStre void guac_rdpdr_fs_process_query_full_size_info(guac_rdpdr_device* device, wStream* input_stream, int file_id, int completion_id) { - /* STUB */ - guac_client_log_error(device->rdpdr->client, - "Unimplemented stub: guac_rdpdr_fs_query_full_size_info"); + + guac_rdp_fs_info info = {0}; + guac_rdp_fs_get_info((guac_rdp_fs*) device->data, &info); + + wStream* output_stream = guac_rdpdr_new_io_completion(device, + completion_id, STATUS_SUCCESS, 16 + GUAC_FILESYSTEM_NAME_LENGTH); + + Stream_Write_UINT64(output_stream, info.blocks_total); /* TotalAllocationUnits */ + Stream_Write_UINT64(output_stream, info.blocks_available); /* CallerAvailableAllocationUnits */ + Stream_Write_UINT64(output_stream, info.blocks_available); /* ActualAvailableAllocationUnits */ + Stream_Write_UINT64(output_stream, 1); /* SectorsPerAllocationUnit */ + Stream_Write_UINT64(output_stream, info.block_size); /* BytesPerSector */ + + GUAC_RDP_DEBUG(2, "total=%i, avail=%i, size=%i", info.blocks_total, info.blocks_available, info.block_size); + svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream); + } diff --git a/src/protocols/rdp/rdp_fs.c b/src/protocols/rdp/rdp_fs.c index 9f2737aa..e6546322 100644 --- a/src/protocols/rdp/rdp_fs.c +++ b/src/protocols/rdp/rdp_fs.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include #include @@ -640,3 +641,18 @@ int guac_rdp_fs_matches(const char* filename, const char* pattern) { return fnmatch(pattern, filename, FNM_NOESCAPE) != 0; } +int guac_rdp_fs_get_info(guac_rdp_fs* fs, guac_rdp_fs_info* info) { + + /* Read FS information */ + struct statvfs fs_stat; + if (statvfs(fs->drive_path, &fs_stat)) + return guac_rdp_fs_get_status(errno); + + /* Assign to structure */ + info->blocks_available = fs_stat.f_bfree; + info->blocks_total = fs_stat.f_blocks; + info->block_size = fs_stat.f_bsize; + return 0; + +} + diff --git a/src/protocols/rdp/rdp_fs.h b/src/protocols/rdp/rdp_fs.h index b25ad833..85999750 100644 --- a/src/protocols/rdp/rdp_fs.h +++ b/src/protocols/rdp/rdp_fs.h @@ -289,6 +289,28 @@ typedef struct guac_rdp_fs { } guac_rdp_fs; +/** + * Filesystem information structure. + */ +typedef struct guac_rdp_fs_info { + + /** + * The number of free blocks available. + */ + int blocks_available; + + /** + * The number of blocks in the filesystem. + */ + int blocks_total; + + /** + * The number of bytes per block. + */ + int block_size; + +} guac_rdp_fs_info; + /** * Allocates a new filesystem given a root path. */ @@ -389,5 +411,11 @@ guac_rdp_fs_file* guac_rdp_fs_get_file(guac_rdp_fs* fs, int file_id); */ int guac_rdp_fs_matches(const char* filename, const char* pattern); +/** + * Populates the given structure with information about the filesystem, + * particularly the amount of space available. + */ +int guac_rdp_fs_get_info(guac_rdp_fs* fs, guac_rdp_fs_info* info); + #endif