mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-10-28 07:44:06 +01:00
Disk: fix Windows quota affecting free space and unify disk size calculation
- Windows: use FILE_FS_FULL_SIZE_INFORMATION_EX on Windows 10 1809+ (Build >= 17763) when calcType != AVAILABLE to get ActualTotalAllocationUnits/ActualAvailableAllocationUnits (ignoring per-user disk quotas). Fall back to legacy FILE_FS_FULL_SIZE_INFORMATION with CallerAvailableAllocationUnits when calcType is AVAILABLE or EX is unavailable. - Unix-like: respect --disk-calc-type. Use f_bfree for FREE, f_bavail for AVAILABLE (Linux/BSD/SunOS). Haiku currently always uses free_blocks. - Refactor FFDisk: remove bytesUsed and bytesAvailable; compute used = total - free in disk module. - Disk module: update custom format (remove `size-available`, add `bytes-used` and `bytes-total`); update JSON output (remove `bytes.available`, `bytes.used`). - Disk detection: stop computing used in common path; let each platform set bytesFree by chosen semantics. Fixes #2651
This commit is contained in:
@@ -9,6 +9,10 @@ Changes:
|
|||||||
* It defaults to `"both"`, so a command that logs to stderr now has that output captured instead of discarded.
|
* It defaults to `"both"`, so a command that logs to stderr now has that output captured instead of discarded.
|
||||||
* Set it to `"stdout"` or `"stderr"` to restore the old single-stream behavior. (Command)
|
* Set it to `"stdout"` or `"stderr"` to restore the old single-stream behavior. (Command)
|
||||||
* The Shell module now reports the shell from the password database (`/etc/passwd`) instead of the `$SHELL` environment variable, which may differ when the login shell was changed after the session started. (Title)
|
* The Shell module now reports the shell from the password database (`/etc/passwd`) instead of the `$SHELL` environment variable, which may differ when the login shell was changed after the session started. (Title)
|
||||||
|
* The Disk custom format no longer provides `{size-available}`. `{size-free}` now reports whichever of the two the `disk.useAvailable` option selects, and the raw byte counts are available as `{bytes-used}` and `{bytes-total}`. (Disk)
|
||||||
|
* This also means `{size-free}` now changes with `disk.useAvailable`; it used to always report the file system's free size.
|
||||||
|
* The Disk JSON output no longer includes `bytes.available` and `bytes.used`. (Disk)
|
||||||
|
* `bytes.free` and `bytes.total` are unchanged; the used size can be derived as `total - free`.
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
* Added Sound detection on Android. (Sound, Android)
|
* Added Sound detection on Android. (Sound, Android)
|
||||||
@@ -34,6 +38,8 @@ Bugfixes:
|
|||||||
* Fixed assertion failure when percentage exceeds 100. (Percent)
|
* Fixed assertion failure when percentage exceeds 100. (Percent)
|
||||||
* Fixed a non-existent command being reported as a generic child process error on Windows instead of `command not found`. (Command, Windows)
|
* Fixed a non-existent command being reported as a generic child process error on Windows instead of `command not found`. (Command, Windows)
|
||||||
* Fixed Android display detection on devices running Android 17. (Display, Android)
|
* Fixed Android display detection on devices running Android 17. (Display, Android)
|
||||||
|
* Fixed Windows volumes with a per-user quota (such as network shares) reporting a wrong total size and a wrapped-around used size, because the total size was quota-limited while the free size was not. (#2651, Disk, Windows)
|
||||||
|
* On Windows 10 1809 (build 17763) and later, the whole volume's capacity and free space are now reported by default. Set `disk.useAvailable` to `true` to keep reporting the space that is available to the current user, quota included.
|
||||||
|
|
||||||
Logos:
|
Logos:
|
||||||
* Added filled Artix logo (#2631)
|
* Added filled Artix logo (#2631)
|
||||||
|
|||||||
@@ -277,7 +277,7 @@
|
|||||||
|
|
||||||
|
|
||||||
"batteryFormat": {
|
"batteryFormat": {
|
||||||
"description": "Output format for the `Battery` module. See Wiki for formatting syntax\n 1. {manufacturer}: Battery manufacturer\n 2. {name}: Battery model name *\n 3. {technology}: Battery technology\n 4. {capacity}: Battery capacity (percentage num)\n 5. {status}: Battery status\n 6. {temperature}: Battery temperature (formatted)\n 7. {cycle-count}: Battery cycle count\n 8. {serial}: Battery serial number\n 9. {manufacture-date}: Battery manufacture date\n 10. {capacity-bar}: Battery capacity (percentage bar)\n 11. {time-days}: Battery time remaining days\n 12. {time-hours}: Battery time remaining hours\n 13. {time-minutes}: Battery time remaining minutes\n 14. {time-seconds}: Battery time remaining seconds\n 15. {time-formatted}: Battery time remaining (formatted)",
|
"description": "Output format for the `Battery` module. See Wiki for formatting syntax\n 1. {manufacturer}: Battery manufacturer\n 2. {model-name}: Battery model name *\n 3. {technology}: Battery technology\n 4. {capacity}: Battery capacity (percentage num)\n 5. {status}: Battery status\n 6. {temperature}: Battery temperature (formatted)\n 7. {cycle-count}: Battery cycle count\n 8. {serial}: Battery serial number\n 9. {manufacture-date}: Battery manufacture date\n 10. {capacity-bar}: Battery capacity (percentage bar)\n 11. {time-days}: Battery time remaining days\n 12. {time-hours}: Battery time remaining hours\n 13. {time-minutes}: Battery time remaining minutes\n 14. {time-seconds}: Battery time remaining seconds\n 15. {time-formatted}: Battery time remaining (formatted)",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"biosFormat": {
|
"biosFormat": {
|
||||||
@@ -325,7 +325,7 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"cpuFormat": {
|
"cpuFormat": {
|
||||||
"description": "Output format for the `CPU` module. See Wiki for formatting syntax\n 1. {name}: Name\n 2. {vendor}: Vendor\n 3. {cores-physical}: Physical core count\n 4. {cores-logical}: Logical core count\n 5. {cores-online}: Online core count\n 6. {freq-base}: Base frequency (formatted)\n 7. {freq-max}: Max frequency (formatted)\n 8. {temperature}: Temperature (formatted)\n 9. {core-types}: Logical core count grouped by frequency\n 10. {packages}: Processor package count\n 11. {march}: CPU microarchitecture\n 12. {numa-nodes}: NUMA node count\n 13. {code-name}: CPU code name (x86 only)\n 14. {technology}: CPU technology (x86 only)",
|
"description": "Output format for the `CPU` module. See Wiki for formatting syntax\n 1. {name}: Name\n 2. {vendor}: Vendor\n 3. {cores-physical}: Physical core count\n 4. {cores-logical}: Logical core count\n 5. {cores-online}: Online core count\n 6. {freq-base}: Base frequency (formatted)\n 7. {freq-max}: Max frequency (formatted)\n 8. {temperature}: Temperature (formatted)\n 9. {core-types}: Logical core count grouped by frequency\n 10. {packages}: Processor package count\n 11. {march}: CPU microarchitecture\n 12. {numa-nodes}: NUMA node count",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"cpucacheFormat": {
|
"cpucacheFormat": {
|
||||||
@@ -353,7 +353,7 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"diskFormat": {
|
"diskFormat": {
|
||||||
"description": "Output format for the `Disk` module. See Wiki for formatting syntax\n 1. {size-used}: Size used\n 2. {size-total}: Size total\n 3. {size-percentage}: Size percentage num\n 4. {files-used}: Files used\n 5. {files-total}: Files total\n 6. {files-percentage}: Files percentage num\n 7. {is-external}: True if external volume\n 8. {is-hidden}: True if hidden volume\n 9. {filesystem}: Filesystem *\n 10. {name}: Label / name *\n 11. {is-readonly}: True if read-only\n 12. {create-time}: Create time in local timezone\n 13. {size-percentage-bar}: Size percentage bar\n 14. {files-percentage-bar}: Files percentage bar\n 15. {days}: Days after creation\n 16. {hours}: Hours after creation\n 17. {minutes}: Minutes after creation\n 18. {seconds}: Seconds after creation\n 19. {milliseconds}: Milliseconds after creation\n 20. {mountpoint}: Mount point / drive letter *\n 21. {mount-from}: Mount from (device path) *\n 22. {years}: Years integer after creation\n 23. {days-of-year}: Days of year after creation\n 24. {years-fraction}: Years fraction after creation\n 25. {size-free}: Size free\n 26. {size-available}: Size available",
|
"description": "Output format for the `Disk` module. See Wiki for formatting syntax\n 1. {size-used}: Size used (formatted)\n 2. {size-total}: Size total (formatted)\n 3. {size-percentage}: Size percentage num\n 4. {files-used}: Files used\n 5. {files-total}: Files total\n 6. {files-percentage}: Files percentage num\n 7. {is-external}: True if external volume\n 8. {is-hidden}: True if hidden volume\n 9. {filesystem}: Filesystem *\n 10. {name}: Label / name *\n 11. {is-readonly}: True if read-only\n 12. {create-time}: Create time in local timezone\n 13. {size-percentage-bar}: Size percentage bar\n 14. {files-percentage-bar}: Files percentage bar\n 15. {days}: Days after creation\n 16. {hours}: Hours after creation\n 17. {minutes}: Minutes after creation\n 18. {seconds}: Seconds after creation\n 19. {milliseconds}: Milliseconds after creation\n 20. {mountpoint}: Mount point / drive letter *\n 21. {mount-from}: Mount from (device path) *\n 22. {years}: Years integer after creation\n 23. {days-of-year}: Days of year after creation\n 24. {years-fraction}: Years fraction after creation\n 25. {size-free}: Size free (formatted)\n 26. {bytes-used}: Size used (in bytes)\n 27. {bytes-total}: Size total (in bytes)",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"diskioFormat": {
|
"diskioFormat": {
|
||||||
@@ -465,7 +465,7 @@
|
|||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"poweradapterFormat": {
|
"poweradapterFormat": {
|
||||||
"description": "Output format for the `PowerAdapter` module. See Wiki for formatting syntax\n 1. {watts}: Power adapter watts\n 2. {name}: Power adapter name\n 3. {manufacturer}: Power adapter manufacturer\n 4. {model-name}: Power adapter model\n 5. {description}: Power adapter description\n 6. {serial}: Power adapter serial number",
|
"description": "Output format for the `PowerAdapter` module. See Wiki for formatting syntax\n 1. {watts}: Power adapter watts\n 2. {name}: Power adapter name\n 3. {manufacturer}: Power adapter manufacturer\n 4. {model-name}: Power adapter model name\n 5. {description}: Power adapter description\n 6. {serial}: Power adapter serial number",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"processesFormat": {
|
"processesFormat": {
|
||||||
@@ -2716,7 +2716,7 @@
|
|||||||
},
|
},
|
||||||
"useAvailable": {
|
"useAvailable": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Use f_bavail (lpFreeBytesAvailableToCaller for Windows) instead of f_bfree to calculate used bytes\nMay be required for macOS to display correct results",
|
"description": "Use f_bavail instead of f_bfree to calculate used bytes\nMay be required for macOS to display correct results\nOn Windows, set to true to make fastfetch honors the quota settings",
|
||||||
"default": false
|
"default": false
|
||||||
},
|
},
|
||||||
"percent": {
|
"percent": {
|
||||||
|
|||||||
@@ -719,6 +719,10 @@ static inline bool ffIsSystemBasicProcessInfoAvailable() { // Includes HandleCou
|
|||||||
return SharedUserData->NtBuildNumber >= 26200; // MSDN says it was added in 26100.4770; ntdoc says 25H2
|
return SharedUserData->NtBuildNumber >= 26200; // MSDN says it was added in 26100.4770; ntdoc says 25H2
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool ffIsFileFsFullSizeInformationExAvailable() {
|
||||||
|
return SharedUserData->NtBuildNumber >= 17763; // Windows 10 October 2018 Update (1809, REDSTONE5)
|
||||||
|
}
|
||||||
|
|
||||||
NTSYSAPI NTSTATUS NTAPI NtOpenProcessToken(
|
NTSYSAPI NTSTATUS NTAPI NtOpenProcessToken(
|
||||||
_In_ HANDLE ProcessHandle,
|
_In_ HANDLE ProcessHandle,
|
||||||
_In_ ACCESS_MASK DesiredAccess,
|
_In_ ACCESS_MASK DesiredAccess,
|
||||||
@@ -1419,3 +1423,23 @@ NTSYSAPI NTSTATUS NTAPI NtTerminateProcess(
|
|||||||
|
|
||||||
NTSYSAPI NTSTATUS NTAPI RtlAcquirePebLock(VOID);
|
NTSYSAPI NTSTATUS NTAPI RtlAcquirePebLock(VOID);
|
||||||
NTSYSAPI NTSTATUS NTAPI RtlReleasePebLock(VOID);
|
NTSYSAPI NTSTATUS NTAPI RtlReleasePebLock(VOID);
|
||||||
|
|
||||||
|
typedef struct _FILE_FS_FULL_SIZE_INFORMATION_EX {
|
||||||
|
ULONGLONG ActualTotalAllocationUnits;
|
||||||
|
ULONGLONG ActualAvailableAllocationUnits;
|
||||||
|
ULONGLONG ActualPoolUnavailableAllocationUnits;
|
||||||
|
ULONGLONG CallerTotalAllocationUnits;
|
||||||
|
ULONGLONG CallerAvailableAllocationUnits;
|
||||||
|
ULONGLONG CallerPoolUnavailableAllocationUnits;
|
||||||
|
ULONGLONG UsedAllocationUnits;
|
||||||
|
ULONGLONG TotalReservedAllocationUnits;
|
||||||
|
ULONGLONG VolumeStorageReserveAllocationUnits;
|
||||||
|
ULONGLONG AvailableCommittedAllocationUnits;
|
||||||
|
ULONGLONG PoolAvailableAllocationUnits;
|
||||||
|
ULONG SectorsPerAllocationUnit;
|
||||||
|
ULONG BytesPerSector;
|
||||||
|
} FILE_FS_FULL_SIZE_INFORMATION_EX, *PFILE_FS_FULL_SIZE_INFORMATION_EX;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
FileFsFullSizeInformationEx = 14
|
||||||
|
};
|
||||||
|
|||||||
@@ -22,8 +22,6 @@ const char* ffDetectDisks(FFDiskOptions* options, FFlist* disks) {
|
|||||||
FF_LIST_FOR_EACH (FFDisk, disk, *disks) {
|
FF_LIST_FOR_EACH (FFDisk, disk, *disks) {
|
||||||
if (disk->bytesTotal == 0) {
|
if (disk->bytesTotal == 0) {
|
||||||
disk->type |= FF_DISK_VOLUME_TYPE_UNKNOWN_BIT;
|
disk->type |= FF_DISK_VOLUME_TYPE_UNKNOWN_BIT;
|
||||||
} else {
|
|
||||||
disk->bytesUsed = disk->bytesTotal - (options->calcType == FF_DISK_CALC_TYPE_FREE ? disk->bytesFree : disk->bytesAvailable);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,9 +16,7 @@ typedef struct FFDisk {
|
|||||||
FFstrbuf name;
|
FFstrbuf name;
|
||||||
FFDiskVolumeType type;
|
FFDiskVolumeType type;
|
||||||
|
|
||||||
uint64_t bytesUsed;
|
|
||||||
uint64_t bytesFree;
|
uint64_t bytesFree;
|
||||||
uint64_t bytesAvailable;
|
|
||||||
uint64_t bytesTotal;
|
uint64_t bytesTotal;
|
||||||
|
|
||||||
uint32_t filesUsed;
|
uint32_t filesUsed;
|
||||||
|
|||||||
@@ -188,9 +188,7 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks) {
|
|||||||
FFDisk* disk = FF_LIST_ADD(FFDisk, *disks);
|
FFDisk* disk = FF_LIST_ADD(FFDisk, *disks);
|
||||||
|
|
||||||
disk->bytesTotal = (uint64_t) fs->f_blocks * (uint64_t) fs->f_bsize;
|
disk->bytesTotal = (uint64_t) fs->f_blocks * (uint64_t) fs->f_bsize;
|
||||||
disk->bytesFree = (uint64_t) fs->f_bfree * (uint64_t) fs->f_bsize;
|
disk->bytesFree = (uint64_t) (options->calcType == FF_DISK_CALC_TYPE_FREE ? fs->f_bfree : fs->f_bavail) * (uint64_t) fs->f_bsize;
|
||||||
disk->bytesAvailable = (uint64_t) fs->f_bavail * (uint64_t) fs->f_bsize;
|
|
||||||
disk->bytesUsed = 0; // To be filled in ./disk.c
|
|
||||||
|
|
||||||
disk->filesTotal = (uint32_t) fs->f_files;
|
disk->filesTotal = (uint32_t) fs->f_files;
|
||||||
disk->filesUsed = (uint32_t) fs->f_files - (uint32_t) fs->f_ffree;
|
disk->filesUsed = (uint32_t) fs->f_files - (uint32_t) fs->f_ffree;
|
||||||
|
|||||||
@@ -44,8 +44,6 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks) {
|
|||||||
|
|
||||||
disk->bytesTotal = (uint64_t) fs.total_blocks * (uint64_t) fs.block_size;
|
disk->bytesTotal = (uint64_t) fs.total_blocks * (uint64_t) fs.block_size;
|
||||||
disk->bytesFree = (uint64_t) fs.free_blocks * (uint64_t) fs.block_size;
|
disk->bytesFree = (uint64_t) fs.free_blocks * (uint64_t) fs.block_size;
|
||||||
disk->bytesAvailable = disk->bytesFree;
|
|
||||||
disk->bytesUsed = 0; // To be filled in ./disk.c
|
|
||||||
|
|
||||||
disk->filesTotal = (uint32_t) fs.total_nodes;
|
disk->filesTotal = (uint32_t) fs.total_nodes;
|
||||||
disk->filesUsed = (uint32_t) (fs.total_nodes - fs.free_nodes);
|
disk->filesUsed = (uint32_t) (fs.total_nodes - fs.free_nodes);
|
||||||
|
|||||||
@@ -249,16 +249,14 @@ static void detectType(const FFlist* disks, FFDisk* currentDisk, struct mntent*
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void detectStats(FFDisk* disk) {
|
static void detectStats(FFDiskOptions* options, FFDisk* disk) {
|
||||||
struct statvfs fs;
|
struct statvfs fs;
|
||||||
if (statvfs(disk->mountpoint.chars, &fs) != 0) {
|
if (statvfs(disk->mountpoint.chars, &fs) != 0) {
|
||||||
memset(&fs, 0, sizeof(fs)); // Set all values to 0, so our values get initialized to 0 too
|
memset(&fs, 0, sizeof(fs)); // Set all values to 0, so our values get initialized to 0 too
|
||||||
}
|
}
|
||||||
|
|
||||||
disk->bytesTotal = fs.f_blocks * (uint64_t) fs.f_frsize;
|
disk->bytesTotal = fs.f_blocks * (uint64_t) fs.f_frsize;
|
||||||
disk->bytesFree = fs.f_bfree * (uint64_t) fs.f_frsize;
|
disk->bytesFree = (options->calcType == FF_DISK_CALC_TYPE_FREE ? fs.f_bfree : fs.f_bavail) * (uint64_t) fs.f_frsize;
|
||||||
disk->bytesAvailable = fs.f_bavail * (uint64_t) fs.f_frsize;
|
|
||||||
disk->bytesUsed = 0; // To be filled in ./disk.c
|
|
||||||
|
|
||||||
if (fs.f_files >= fs.f_ffree) {
|
if (fs.f_files >= fs.f_ffree) {
|
||||||
disk->filesTotal = (uint32_t) fs.f_files;
|
disk->filesTotal = (uint32_t) fs.f_files;
|
||||||
@@ -330,7 +328,7 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks) {
|
|||||||
detectType(disks, disk, device);
|
detectType(disks, disk, device);
|
||||||
|
|
||||||
// Detects stats
|
// Detects stats
|
||||||
detectStats(disk);
|
detectStats(options, disk);
|
||||||
}
|
}
|
||||||
|
|
||||||
endmntent(mountsFile);
|
endmntent(mountsFile);
|
||||||
|
|||||||
@@ -85,16 +85,14 @@ static void detectType(const FFlist* disks, FFDisk* currentDisk, struct mnttab*
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void detectStats(FFDisk* disk) {
|
static void detectStats(FFDiskOptions* options, FFDisk* disk) {
|
||||||
struct statvfs fs;
|
struct statvfs fs;
|
||||||
if (statvfs(disk->mountpoint.chars, &fs) != 0) {
|
if (statvfs(disk->mountpoint.chars, &fs) != 0) {
|
||||||
memset(&fs, 0, sizeof(fs));
|
memset(&fs, 0, sizeof(fs));
|
||||||
}
|
}
|
||||||
|
|
||||||
disk->bytesTotal = fs.f_blocks * fs.f_frsize;
|
disk->bytesTotal = fs.f_blocks * fs.f_frsize;
|
||||||
disk->bytesFree = fs.f_bfree * fs.f_frsize;
|
disk->bytesFree = (options->calcType == FF_DISK_CALC_TYPE_FREE ? fs.f_bfree : fs.f_bavail) * 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->filesTotal = (uint32_t) fs.f_files;
|
||||||
disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree);
|
disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree);
|
||||||
@@ -138,7 +136,7 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks) {
|
|||||||
ffStrbufInitS(&disk->filesystem, device.mnt_fstype);
|
ffStrbufInitS(&disk->filesystem, device.mnt_fstype);
|
||||||
ffStrbufInit(&disk->name);
|
ffStrbufInit(&disk->name);
|
||||||
detectType(disks, disk, &device);
|
detectType(disks, disk, &device);
|
||||||
detectStats(disk);
|
detectStats(options, disk);
|
||||||
}
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|||||||
@@ -75,8 +75,6 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks) {
|
|||||||
disk->filesTotal = 0;
|
disk->filesTotal = 0;
|
||||||
disk->bytesTotal = 0;
|
disk->bytesTotal = 0;
|
||||||
disk->bytesFree = 0;
|
disk->bytesFree = 0;
|
||||||
disk->bytesUsed = 0; // To be filled in ./disk.c
|
|
||||||
disk->bytesAvailable = 0;
|
|
||||||
disk->createTime = 0;
|
disk->createTime = 0;
|
||||||
ffStrbufInit(&disk->filesystem);
|
ffStrbufInit(&disk->filesystem);
|
||||||
ffStrbufInit(&disk->name);
|
ffStrbufInit(&disk->name);
|
||||||
@@ -118,12 +116,21 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (options->calcType == FF_DISK_CALC_TYPE_AVAILABLE || !ffIsFileFsFullSizeInformationExAvailable()) {
|
||||||
FILE_FS_FULL_SIZE_INFORMATION fsFullSize;
|
FILE_FS_FULL_SIZE_INFORMATION fsFullSize;
|
||||||
if (NT_SUCCESS(NtQueryVolumeInformationFile(handle, &iosb, &fsFullSize, sizeof(fsFullSize), FileFsFullSizeInformation))) {
|
if (NT_SUCCESS(NtQueryVolumeInformationFile(handle, &iosb, &fsFullSize, sizeof(fsFullSize), FileFsFullSizeInformation))) {
|
||||||
uint64_t units = fsFullSize.BytesPerSector * fsFullSize.SectorsPerAllocationUnit;
|
uint64_t units = fsFullSize.BytesPerSector * fsFullSize.SectorsPerAllocationUnit;
|
||||||
disk->bytesTotal = (uint64_t) fsFullSize.TotalAllocationUnits.QuadPart * units;
|
disk->bytesTotal = (uint64_t) fsFullSize.TotalAllocationUnits.QuadPart * units;
|
||||||
disk->bytesFree = (uint64_t) fsFullSize.ActualAvailableAllocationUnits.QuadPart * units;
|
disk->bytesFree = (uint64_t) fsFullSize.CallerAvailableAllocationUnits.QuadPart * units;
|
||||||
disk->bytesAvailable = (uint64_t) fsFullSize.CallerAvailableAllocationUnits.QuadPart * units;
|
}
|
||||||
|
} else {
|
||||||
|
FILE_FS_FULL_SIZE_INFORMATION_EX fsFullSizeEx;
|
||||||
|
if (NT_SUCCESS(NtQueryVolumeInformationFile(handle, &iosb, &fsFullSizeEx, sizeof(fsFullSizeEx), FileFsFullSizeInformationEx))) {
|
||||||
|
// Space info without considering the quota setting
|
||||||
|
uint64_t units = fsFullSizeEx.BytesPerSector * fsFullSizeEx.SectorsPerAllocationUnit;
|
||||||
|
disk->bytesTotal = (uint64_t) fsFullSizeEx.ActualTotalAllocationUnits * units;
|
||||||
|
disk->bytesFree = (uint64_t) fsFullSizeEx.ActualAvailableAllocationUnits * units;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+11
-12
@@ -15,6 +15,8 @@
|
|||||||
static void printDisk(FFDiskOptions* options, const FFDisk* disk, uint32_t index) {
|
static void printDisk(FFDiskOptions* options, const FFDisk* disk, uint32_t index) {
|
||||||
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
|
||||||
|
|
||||||
|
uint64_t bytesUsed = disk->bytesTotal - disk->bytesFree;
|
||||||
|
|
||||||
if (options->moduleArgs.key.length == 0) {
|
if (options->moduleArgs.key.length == 0) {
|
||||||
ffStrbufSetF(&key, "%s (%s)", FF_MODULE_GET_DISPLAY_NAME(Disk), disk->mountpoint.chars);
|
ffStrbufSetF(&key, "%s (%s)", FF_MODULE_GET_DISPLAY_NAME(Disk), disk->mountpoint.chars);
|
||||||
} else {
|
} else {
|
||||||
@@ -50,12 +52,12 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk, uint32_t index
|
|||||||
}
|
}
|
||||||
|
|
||||||
FF_STRBUF_AUTO_DESTROY usedPretty = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY usedPretty = ffStrbufCreate();
|
||||||
ffSizeAppendNum(disk->bytesUsed, &usedPretty);
|
ffSizeAppendNum(bytesUsed, &usedPretty);
|
||||||
|
|
||||||
FF_STRBUF_AUTO_DESTROY totalPretty = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY totalPretty = ffStrbufCreate();
|
||||||
ffSizeAppendNum(disk->bytesTotal, &totalPretty);
|
ffSizeAppendNum(disk->bytesTotal, &totalPretty);
|
||||||
|
|
||||||
double bytesPercentage = disk->bytesTotal > 0 ? (double) disk->bytesUsed / (double) disk->bytesTotal * 100.0 : 0;
|
double bytesPercentage = disk->bytesTotal > 0 ? (double) bytesUsed / (double) disk->bytesTotal * 100.0 : 0;
|
||||||
FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type;
|
FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type;
|
||||||
|
|
||||||
if (options->moduleArgs.outputFormat.length == 0) {
|
if (options->moduleArgs.outputFormat.length == 0) {
|
||||||
@@ -136,9 +138,6 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk, uint32_t index
|
|||||||
FF_STRBUF_AUTO_DESTROY freePretty = ffStrbufCreate();
|
FF_STRBUF_AUTO_DESTROY freePretty = ffStrbufCreate();
|
||||||
ffSizeAppendNum(disk->bytesFree, &freePretty);
|
ffSizeAppendNum(disk->bytesFree, &freePretty);
|
||||||
|
|
||||||
FF_STRBUF_AUTO_DESTROY availPretty = ffStrbufCreate();
|
|
||||||
ffSizeAppendNum(disk->bytesAvailable, &availPretty);
|
|
||||||
|
|
||||||
uint64_t now = ffTimeGetNow();
|
uint64_t now = ffTimeGetNow();
|
||||||
uint64_t duration = now - disk->createTime;
|
uint64_t duration = now - disk->createTime;
|
||||||
uint32_t milliseconds = (uint32_t) (duration % 1000);
|
uint32_t milliseconds = (uint32_t) (duration % 1000);
|
||||||
@@ -178,7 +177,8 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk, uint32_t index
|
|||||||
FF_ARG(age.daysOfYear, "days-of-year"),
|
FF_ARG(age.daysOfYear, "days-of-year"),
|
||||||
FF_ARG(age.yearsFraction, "years-fraction"),
|
FF_ARG(age.yearsFraction, "years-fraction"),
|
||||||
FF_ARG(freePretty, "size-free"),
|
FF_ARG(freePretty, "size-free"),
|
||||||
FF_ARG(availPretty, "size-available"),
|
FF_ARG(bytesUsed, "bytes-used"),
|
||||||
|
FF_ARG(disk->bytesTotal, "bytes-total"),
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -374,10 +374,8 @@ bool ffGenerateDiskJsonResult(FFDiskOptions* options, yyjson_mut_doc* doc, yyjso
|
|||||||
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
|
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
|
||||||
|
|
||||||
yyjson_mut_val* bytes = yyjson_mut_obj_add_obj(doc, obj, "bytes");
|
yyjson_mut_val* bytes = yyjson_mut_obj_add_obj(doc, obj, "bytes");
|
||||||
yyjson_mut_obj_add_uint(doc, bytes, "available", item->bytesAvailable);
|
|
||||||
yyjson_mut_obj_add_uint(doc, bytes, "free", item->bytesFree);
|
yyjson_mut_obj_add_uint(doc, bytes, "free", item->bytesFree);
|
||||||
yyjson_mut_obj_add_uint(doc, bytes, "total", item->bytesTotal);
|
yyjson_mut_obj_add_uint(doc, bytes, "total", item->bytesTotal);
|
||||||
yyjson_mut_obj_add_uint(doc, bytes, "used", item->bytesUsed);
|
|
||||||
|
|
||||||
yyjson_mut_val* files = yyjson_mut_obj_add_obj(doc, obj, "files");
|
yyjson_mut_val* files = yyjson_mut_obj_add_obj(doc, obj, "files");
|
||||||
if (item->filesTotal == 0 && item->filesUsed == 0) {
|
if (item->filesTotal == 0 && item->filesUsed == 0) {
|
||||||
@@ -487,8 +485,8 @@ FFModuleBaseInfo ffDiskModuleInfo = {
|
|||||||
.generateJsonResult = (void*) ffGenerateDiskJsonResult,
|
.generateJsonResult = (void*) ffGenerateDiskJsonResult,
|
||||||
.generateJsonConfig = (void*) ffGenerateDiskJsonConfig,
|
.generateJsonConfig = (void*) ffGenerateDiskJsonConfig,
|
||||||
.formatArgs = FF_FORMAT_ARG_LIST(((FFModuleFormatArg[]) {
|
.formatArgs = FF_FORMAT_ARG_LIST(((FFModuleFormatArg[]) {
|
||||||
{ "Size used", "size-used" },
|
{ "Size used (formatted)", "size-used" },
|
||||||
{ "Size total", "size-total" },
|
{ "Size total (formatted)", "size-total" },
|
||||||
{ "Size percentage num", "size-percentage" },
|
{ "Size percentage num", "size-percentage" },
|
||||||
{ "Files used", "files-used" },
|
{ "Files used", "files-used" },
|
||||||
{ "Files total", "files-total" },
|
{ "Files total", "files-total" },
|
||||||
@@ -511,8 +509,9 @@ FFModuleBaseInfo ffDiskModuleInfo = {
|
|||||||
{ "Years integer after creation", "years" },
|
{ "Years integer after creation", "years" },
|
||||||
{ "Days of year after creation", "days-of-year" },
|
{ "Days of year after creation", "days-of-year" },
|
||||||
{ "Years fraction after creation", "years-fraction" },
|
{ "Years fraction after creation", "years-fraction" },
|
||||||
{ "Size free", "size-free" },
|
{ "Size free (formatted)", "size-free" },
|
||||||
{ "Size available", "size-available" },
|
{ "Size used (in bytes)", "bytes-used" },
|
||||||
|
{ "Size total (in bytes)", "bytes-total" },
|
||||||
})),
|
})),
|
||||||
.defaultOrder = 42,
|
.defaultOrder = 42,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user