diff --git a/doc/json_schema.json b/doc/json_schema.json index 07061c18f..be2334b2e 100644 --- a/doc/json_schema.json +++ b/doc/json_schema.json @@ -889,6 +889,11 @@ "title": "Set if unknown (unable to detect sizes) volumes should be printed", "default": false }, + "useAvailable": { + "type": "boolean", + "title": "Use f_bavail (lpFreeBytesAvailableToCaller for Windows) instead of f_bfree to calculate used bytes", + "default": false + }, "key": { "$ref": "#/$defs/key" }, diff --git a/src/data/help.txt b/src/data/help.txt index 48a076e88..6c484d29f 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -130,6 +130,7 @@ Module specific options: --disk-show-hidden : Set if hidden volumes should be printed. Default is false --disk-show-subvolumes : Set if subvolumes should be printed. Default is false --disk-show-unknown : Set if unknown (unable to detect sizes) volumes should be printed. Default is false + --disk-use-available : Use f_bavail (lpFreeBytesAvailableToCaller for Windows) instead of f_bfree to calculate used bytes. Default is false --bluetooth-show-disconnected: : Set if disconnected bluetooth devices should be printed. Default is false --display-compact-type: : Set if all displays should be printed in one line. Default is none --display-detect-name: : Set if display name should be detected and printed (if supported). Default is false diff --git a/src/detection/disk/disk.c b/src/detection/disk/disk.c index 00eba85c0..3e92ca0eb 100644 --- a/src/detection/disk/disk.c +++ b/src/detection/disk/disk.c @@ -7,7 +7,7 @@ static int compareDisks(const void* disk1, const void* disk2) return ffStrbufCompAlphabetically(&((const FFDisk*) disk1)->mountpoint, &((const FFDisk*) disk2)->mountpoint); } -const char* ffDetectDisks(FFlist* disks) +const char* ffDetectDisks(FFDiskOptions* options, FFlist* disks) { const char* error = ffDetectDisksImpl(disks); @@ -23,6 +23,12 @@ const char* ffDetectDisks(FFlist* disks) { if(disk->bytesTotal == 0) disk->type |= FF_DISK_VOLUME_TYPE_UNKNOWN_BIT; + else + { + disk->bytesUsed = disk->bytesTotal - ( + options->calcType == FF_DISK_CALC_TYPE_FREE ? disk->bytesFree : disk->bytesAvailable + ); + } } return NULL; diff --git a/src/detection/disk/disk.h b/src/detection/disk/disk.h index 24c28c9cf..fced34a92 100644 --- a/src/detection/disk/disk.h +++ b/src/detection/disk/disk.h @@ -13,6 +13,8 @@ typedef struct FFDisk FFDiskVolumeType type; uint64_t bytesUsed; + uint64_t bytesFree; + uint64_t bytesAvailable; uint64_t bytesTotal; uint32_t filesUsed; @@ -23,6 +25,6 @@ typedef struct FFDisk * Returns a List of FFDisk, sorted alphabetically by mountpoint. * If error is not set, disks contains at least one disk. */ -const char* ffDetectDisks(FFlist* result /* list of FFDisk */); +const char* ffDetectDisks(FFDiskOptions* options, FFlist* result /* list of FFDisk */); #endif diff --git a/src/detection/disk/disk_bsd.c b/src/detection/disk/disk_bsd.c index 8701f60bd..89d66b4ad 100644 --- a/src/detection/disk/disk_bsd.c +++ b/src/detection/disk/disk_bsd.c @@ -45,7 +45,9 @@ const char* ffDetectDisksImpl(FFlist* disks) #endif disk->bytesTotal = fs->f_blocks * fs->f_bsize; - disk->bytesUsed = disk->bytesTotal - ((uint64_t)fs->f_bfree * fs->f_bsize); + disk->bytesFree = (uint64_t)fs->f_bfree * fs->f_bsize; + disk->bytesAvailable = (uint64_t)fs->f_bavail * fs->f_bsize; + disk->bytesUsed = 0; // To be filled in ./disk.c disk->filesTotal = (uint32_t) fs->f_files; disk->filesUsed = (uint32_t) (disk->filesTotal - (uint64_t)fs->f_ffree); diff --git a/src/detection/disk/disk_linux.c b/src/detection/disk/disk_linux.c index 69a85ac64..1f0f6acd3 100644 --- a/src/detection/disk/disk_linux.c +++ b/src/detection/disk/disk_linux.c @@ -209,7 +209,9 @@ static void detectStats(FFDisk* disk) memset(&fs, 0, sizeof(struct statvfs)); //Set all values to 0, so our values get initialized to 0 too disk->bytesTotal = fs.f_blocks * fs.f_frsize; - disk->bytesUsed = disk->bytesTotal - (fs.f_bfree * fs.f_frsize); + disk->bytesFree = fs.f_bfree * fs.f_frsize; + disk->bytesAvailable = fs.f_bavail * fs.f_frsize; + disk->bytesUsed = 0; // To be filled in ./disk.c disk->filesTotal = (uint32_t) fs.f_files; disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree); diff --git a/src/detection/disk/disk_windows.c b/src/detection/disk/disk_windows.c index ecda28889..291d59ba6 100644 --- a/src/detection/disk/disk_windows.c +++ b/src/detection/disk/disk_windows.c @@ -25,13 +25,18 @@ const char* ffDetectDisksImpl(FFlist* disks) FFDisk* disk = ffListAdd(disks); ffStrbufInitWS(&disk->mountpoint, mountpoint); - uint64_t bytesFree; - if(!GetDiskFreeSpaceExW(mountpoint, NULL, (PULARGE_INTEGER)&disk->bytesTotal, (PULARGE_INTEGER)&bytesFree)) + if(!GetDiskFreeSpaceExW( + mountpoint, + (PULARGE_INTEGER)&disk->bytesAvailable, + (PULARGE_INTEGER)&disk->bytesTotal, + (PULARGE_INTEGER)&disk->bytesFree + )) { disk->bytesTotal = 0; - bytesFree = 0; + disk->bytesFree = 0; + disk->bytesAvailable = 0; } - disk->bytesUsed = disk->bytesTotal - bytesFree; + disk->bytesUsed = 0; // To be filled in ./disk.c if(driveType == DRIVE_REMOVABLE || driveType == DRIVE_REMOTE || driveType == DRIVE_CDROM) disk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT; diff --git a/src/modules/disk/disk.c b/src/modules/disk/disk.c index 8eed33b96..724061176 100644 --- a/src/modules/disk/disk.c +++ b/src/modules/disk/disk.c @@ -166,7 +166,7 @@ static void printAutodetected(FFDiskOptions* options, const FFlist* disks) void ffPrintDisk(FFDiskOptions* options) { FF_LIST_AUTO_DESTROY disks = ffListCreate(sizeof (FFDisk)); - const char* error = ffDetectDisks(&disks); + const char* error = ffDetectDisks(options, &disks); if(error) { @@ -195,6 +195,7 @@ void ffInitDiskOptions(FFDiskOptions* options) ffStrbufInit(&options->folders); options->showTypes = FF_DISK_VOLUME_TYPE_REGULAR_BIT | FF_DISK_VOLUME_TYPE_EXTERNAL_BIT; + options->calcType = FF_DISK_CALC_TYPE_FREE; } bool ffParseDiskCommandOptions(FFDiskOptions* options, const char* key, const char* value) @@ -255,6 +256,15 @@ bool ffParseDiskCommandOptions(FFDiskOptions* options, const char* key, const ch return true; } + if (ffStrEqualsIgnCase(subKey, "use-available")) + { + if (ffOptionParseBoolean(value)) + options->calcType = FF_DISK_CALC_TYPE_AVAILABLE; + else + options->calcType = FF_DISK_CALC_TYPE_FREE; + return true; + } + return false; } @@ -318,6 +328,15 @@ void ffParseDiskJsonObject(FFDiskOptions* options, yyjson_val* module) continue; } + if (ffStrEqualsIgnCase(key, "useAvailable")) + { + if (yyjson_get_bool(val)) + options->calcType = FF_DISK_CALC_TYPE_AVAILABLE; + else + options->calcType = FF_DISK_CALC_TYPE_FREE; + continue; + } + ffPrintError(FF_DISK_MODULE_NAME, 0, &options->moduleArgs, "Unknown JSON key %s", key); } } diff --git a/src/modules/disk/option.h b/src/modules/disk/option.h index 4b0789ad0..f24090c34 100644 --- a/src/modules/disk/option.h +++ b/src/modules/disk/option.h @@ -14,6 +14,12 @@ typedef enum FFDiskVolumeType FF_DISK_VOLUME_TYPE_UNKNOWN_BIT = 1 << 4, } FFDiskVolumeType; +typedef enum FFDiskCalcType +{ + FF_DISK_CALC_TYPE_FREE, + FF_DISK_CALC_TYPE_AVAILABLE, +} FFDiskCalcType; + typedef struct FFDiskOptions { FFModuleBaseInfo moduleInfo; @@ -21,4 +27,5 @@ typedef struct FFDiskOptions FFstrbuf folders; FFDiskVolumeType showTypes; + FFDiskCalcType calcType; } FFDiskOptions;