PhysicalDisk: add new module

This commit is contained in:
李通洲
2023-12-18 10:43:20 +08:00
committed by 李通洲
parent 0f497a53ad
commit 3cd81ec3ad
14 changed files with 708 additions and 0 deletions
+6
View File
@@ -340,6 +340,7 @@ set(LIBFASTFETCH_SRC
src/modules/opengl/opengl.c
src/modules/os/os.c
src/modules/packages/packages.c
src/modules/physicaldisk/physicaldisk.c
src/modules/processes/processes.c
src/modules/player/player.c
src/modules/poweradapter/poweradapter.c
@@ -394,6 +395,7 @@ if(LINUX)
src/detection/cursor/cursor_linux.c
src/detection/bluetooth/bluetooth_linux.c
src/detection/disk/disk_linux.c
src/detection/physicaldisk/physicaldisk_linux.c
src/detection/diskio/diskio_linux.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/drm.c
@@ -453,6 +455,7 @@ elseif(ANDROID)
src/detection/cursor/cursor_nosupport.c
src/detection/cpuusage/cpuusage_linux.c
src/detection/disk/disk_linux.c
src/detection/physicaldisk/physicaldisk_linux.c
src/detection/diskio/diskio_linux.c
src/detection/displayserver/displayserver_android.c
src/detection/font/font_nosupport.c
@@ -506,6 +509,7 @@ elseif(BSD)
src/detection/cpuusage/cpuusage_bsd.c
src/detection/cursor/cursor_linux.c
src/detection/disk/disk_bsd.c
src/detection/physicaldisk/physicaldisk_bsd.c
src/detection/diskio/diskio_bsd.c
src/detection/displayserver/linux/displayserver_linux.c
src/detection/displayserver/linux/drm.c
@@ -566,6 +570,7 @@ elseif(APPLE)
src/detection/cpuusage/cpuusage_apple.c
src/detection/cursor/cursor_apple.m
src/detection/disk/disk_bsd.c
src/detection/physicaldisk/physicaldisk_apple.c
src/detection/diskio/diskio_apple.c
src/detection/displayserver/displayserver_apple.c
src/detection/font/font_apple.m
@@ -619,6 +624,7 @@ elseif(WIN32)
src/detection/cpuusage/cpuusage_windows.c
src/detection/cursor/cursor_windows.c
src/detection/disk/disk_windows.c
src/detection/physicaldisk/physicaldisk_windows.c
src/detection/diskio/diskio_windows.c
src/detection/displayserver/displayserver_windows.c
src/detection/font/font_windows.c
+1
View File
@@ -96,6 +96,7 @@ static FFModuleBaseInfo* O[] = {
static FFModuleBaseInfo* P[] = {
(void*) &instance.config.modules.packages,
(void*) &instance.config.modules.physicalDisk,
(void*) &instance.config.modules.player,
(void*) &instance.config.modules.powerAdapter,
(void*) &instance.config.modules.processes,
+25
View File
@@ -0,0 +1,25 @@
#include "fastfetch.h"
typedef enum FFPhysicalDiskType
{
FF_PHYSICALDISK_TYPE_NONE = 0,
// If neither is set, it's unknown
FF_PHYSICALDISK_TYPE_HDD = 1 << 0,
FF_PHYSICALDISK_TYPE_SSD = 1 << 1,
FF_PHYSICALDISK_TYPE_FIXED = 1 << 2,
FF_PHYSICALDISK_TYPE_REMOVABLE = 1 << 3,
} FFPhysicalDiskType;
typedef struct FFPhysicalDiskResult
{
FFstrbuf name;
FFstrbuf interconnect;
FFstrbuf serial;
FFstrbuf devPath;
FFPhysicalDiskType type;
uint64_t size;
} FFPhysicalDiskResult;
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options);
@@ -0,0 +1,93 @@
#include "physicaldisk.h"
#include "util/apple/cf_helpers.h"
#include <IOKit/IOKitLib.h>
#include <IOKit/IOBSD.h>
#include <IOKit/storage/IOMedia.h>
#include <IOKit/storage/IOBlockStorageDriver.h>
#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
#include <IOKit/storage/IOStorageProtocolCharacteristics.h>
static inline void wrapIoObjectRelease(io_service_t* service)
{
assert(service);
if (*service)
IOObjectRelease(*service);
}
#define FF_IOOBJECT_AUTO_RELEASE __attribute__((__cleanup__(wrapIoObjectRelease)))
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
{
FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = 0;
if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching(kIOMediaClass), &iterator) != KERN_SUCCESS)
return "IOServiceGetMatchingServices() failed";
io_registry_entry_t registryEntry;
while((registryEntry = IOIteratorNext(iterator)) != 0)
{
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPartition = registryEntry;
io_name_t deviceName;
if (IORegistryEntryGetName(registryEntry, deviceName) != KERN_SUCCESS)
continue;
if (options->namePrefix.length && strncmp(deviceName, options->namePrefix.chars, options->namePrefix.length) != 0)
continue;
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDriver = 0;
if (IORegistryEntryGetParentEntry(entryPartition, kIOServicePlane, &entryDriver) != KERN_SUCCESS)
continue;
if (!IOObjectConformsTo(entryDriver, kIOBlockStorageDriverClass)) // physical disk only
continue;
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
ffStrbufInit(&device->serial);
ffStrbufInitS(&device->name, deviceName);
ffStrbufInit(&device->devPath);
ffStrbufInit(&device->interconnect);
device->type = FF_PHYSICALDISK_TYPE_NONE;
device->size = 0;
FF_CFTYPE_AUTO_RELEASE CFBooleanRef removable = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOMediaRemovableKey), kCFAllocatorDefault, kNilOptions);
device->type |= CFBooleanGetValue(removable) ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
FF_CFTYPE_AUTO_RELEASE CFStringRef bsdName = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOBSDNameKey), kCFAllocatorDefault, kNilOptions);
if (bsdName)
{
ffCfStrGetString(bsdName, &device->devPath);
ffStrbufPrependS(&device->devPath, "/dev/");
}
FF_CFTYPE_AUTO_RELEASE CFNumberRef mediaSize = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOMediaSizeKey), kCFAllocatorDefault, kNilOptions);
if (mediaSize)
ffCfNumGetInt64(mediaSize, (int64_t*) &device->size);
else
device->size = 0;
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPhysical = 0;
if (IORegistryEntryGetParentEntry(entryDriver, kIOServicePlane, &entryPhysical) == KERN_SUCCESS)
{
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef protocolCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyProtocolCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
if (protocolCharacteristics)
ffCfDictGetString(protocolCharacteristics, CFSTR(kIOPropertyPhysicalInterconnectTypeKey), &device->interconnect);
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef deviceCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyDeviceCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
if (deviceCharacteristics)
{
ffCfDictGetString(deviceCharacteristics, CFSTR(kIOPropertyProductSerialNumberKey), &device->serial);
CFStringRef mediumType = (CFStringRef) CFDictionaryGetValue(deviceCharacteristics, CFSTR(kIOPropertyMediumTypeKey));
if (mediumType)
{
if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeSolidStateKey), 0) == 0)
device->type |= FF_PHYSICALDISK_TYPE_SSD;
else if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeRotationalKey), 0) == 0)
device->type |= FF_PHYSICALDISK_TYPE_HDD;
}
}
}
}
return NULL;
}
@@ -0,0 +1,70 @@
#include "physicaldisk.h"
#include "util/stringUtils.h"
#include <devstat.h>
#include <memory.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/disk.h>
#include <libgeom.h>
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
{
struct gmesh geomTree;
if (geom_gettree(&geomTree) < 0)
return "geom_gettree() failed";
if (geom_stats_open() < 0)
return "geom_stats_open() failed";
void* snap = geom_stats_snapshot_get();
struct devstat* snapIter;
while ((snapIter = geom_stats_snapshot_next(snap)) != NULL)
{
if (snapIter->device_type & DEVSTAT_TYPE_PASS)
continue;
struct gident* geomId = geom_lookupid(&geomTree, snapIter->id);
if (geomId == NULL)
continue;
if (geomId->lg_what != ISPROVIDER)
continue;
struct gprovider* provider = (struct gprovider*) geomId->lg_ptr;
if (provider->lg_geom->lg_rank != 1)
continue;
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateS(provider->lg_name);
FF_STRBUF_AUTO_DESTROY identifier = ffStrbufCreate();
FFPhysicalDiskType type = FF_PHYSICALDISK_TYPE_NONE;
for (struct gconfig* ptr = provider->lg_config.lh_first; ptr; ptr = ptr->lg_config.le_next)
{
if (ffStrEquals(ptr->lg_name, "descr"))
ffStrbufSetS(&name, ptr->lg_val);
else if (ffStrEquals(ptr->lg_name, "rotationrate") && !ffStrEquals(ptr->lg_val, "unknown"))
type |= ffStrEquals(ptr->lg_val, "0") ? FF_PHYSICALDISK_TYPE_SSD : FF_PHYSICALDISK_TYPE_HDD;
else if (ffStrEquals(ptr->lg_name, "ident"))
ffStrbufSetS(&identifier, ptr->lg_val);
}
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
continue;
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
ffStrbufInitF(&device->devPath, "/dev/%s", provider->lg_name);
ffStrbufInitMove(&device->serial, &identifier);
ffStrbufInit(&device->interconnect);
switch (snapIter->device_type & DEVSTAT_TYPE_IF_MASK)
{
case DEVSTAT_TYPE_IF_SCSI: ffStrbufAppendS(&device->interconnect, "SCSI"); break;
case DEVSTAT_TYPE_IF_IDE: ffStrbufAppendS(&device->interconnect, "IDE"); break;
case DEVSTAT_TYPE_IF_OTHER: ffStrbufAppendS(&device->interconnect, "OTHER"); break;
}
device->size = (uint64_t) provider->lg_mediasize;
ffStrbufInitMove(&device->name, &name);
device->type = type;
}
geom_stats_snapshot_free(snap);
geom_stats_close();
return NULL;
}
@@ -0,0 +1,114 @@
#include "physicaldisk.h"
#include "common/io/io.h"
#include "common/properties.h"
#include "util/stringUtils.h"
#include <ctype.h>
#include <limits.h>
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
{
FF_AUTO_CLOSE_DIR DIR* sysBlockDirp = opendir("/sys/block/");
if(sysBlockDirp == NULL)
return "opendir(\"/sys/block/\") == NULL";
struct dirent* sysBlockEntry;
while ((sysBlockEntry = readdir(sysBlockDirp)) != NULL)
{
const char* const devName = sysBlockEntry->d_name;
if (devName[0] == '.')
continue;
char pathSysBlock[PATH_MAX];
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s", devName);
char pathSysDeviceReal[PATH_MAX] = "";
readlink(pathSysBlock, pathSysDeviceReal, sizeof(pathSysDeviceReal) - 1);
if (strstr(pathSysDeviceReal, "/virtual/")) // virtual device
continue;
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device", devName);
if (!ffPathExists(pathSysBlock, FF_PATHTYPE_DIRECTORY))
continue;
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
device->type = FF_PHYSICALDISK_TYPE_NONE;
ffStrbufInit(&device->name);
{
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/vendor", devName);
ffAppendFileBuffer(pathSysBlock, &device->name);
if (device->name.length > 0)
ffStrbufAppendC(&device->name, ' ');
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/model", devName);
ffAppendFileBuffer(pathSysBlock, &device->name);
ffStrbufTrim(&device->name, ' ');
if (device->name.length == 0)
ffStrbufSetS(&device->name, devName);
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
{
ffStrbufDestroy(&device->name);
result->length--;
continue;
}
}
ffStrbufInitF(&device->devPath, "/dev/%s", devName);
{
ffStrbufInit(&device->interconnect);
if (strstr(pathSysDeviceReal, "/usb") != NULL)
ffStrbufSetS(&device->interconnect, "usb");
else
{
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/transport", devName);
if (!ffAppendFileBuffer(pathSysBlock, &device->interconnect))
{
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/uevent", devName);
if (ffParsePropFile(pathSysBlock, "DEVTYPE=", &device->interconnect))
ffStrbufSubstrBeforeLastC(&device->interconnect, '_');
}
}
}
{
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/queue/rotational", devName);
char isRotationalChar = '1';
if (ffReadFileData(pathSysBlock, 1, &isRotationalChar) > 0)
device->type |= isRotationalChar == '1' ? FF_PHYSICALDISK_TYPE_HDD : FF_PHYSICALDISK_TYPE_SSD;
}
{
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/size", devName);
char blkSize[32];
ssize_t fileSize = ffReadFileData(pathSysBlock, sizeof(blkSize) - 1, blkSize);
if (fileSize > 0)
{
blkSize[fileSize] = 0;
device->size = (uint64_t) strtoul(blkSize, NULL, 10) * 512;
}
else
device->size = 0;
}
{
char removableChar = '0';
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/removable", devName);
if (ffReadFileData(pathSysBlock, 1, &removableChar) > 0)
device->type |= removableChar == '1' ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
}
{
ffStrbufInit(&device->serial);
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/serial", devName);
ffReadFileBuffer(pathSysBlock, &device->serial);
}
}
return NULL;
}
@@ -0,0 +1,131 @@
#include "physicaldisk.h"
#include "common/io/io.h"
#include "util/windows/unicode.h"
#include <windows.h>
#include <winioctl.h>
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
{
wchar_t szDevice[32] = L"\\\\.\\PhysicalDrive";
wchar_t* pNum = szDevice + strlen("\\\\.\\PhysicalDrive");
for (uint32_t idev = 0; ; ++idev)
{
_ultow(idev, pNum, 10);
FF_AUTO_CLOSE_FD HANDLE hDevice = CreateFileW(szDevice, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hDevice == INVALID_HANDLE_VALUE)
break;
DWORD retSize;
char sddBuffer[4096];
if(!DeviceIoControl(
hDevice,
IOCTL_STORAGE_QUERY_PROPERTY,
&(STORAGE_PROPERTY_QUERY) {
.PropertyId = StorageDeviceProperty,
.QueryType = PropertyStandardQuery,
},
sizeof(STORAGE_PROPERTY_QUERY),
&sddBuffer,
sizeof(sddBuffer),
&retSize,
NULL
) || retSize == 0)
continue;
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
device->type = FF_PHYSICALDISK_TYPE_NONE;
STORAGE_DEVICE_DESCRIPTOR* sdd = (STORAGE_DEVICE_DESCRIPTOR*) sddBuffer;
ffStrbufInit(&device->name);
if (sdd->VendorIdOffset != 0)
{
ffStrbufSetS(&device->name, (const char*) sddBuffer + sdd->VendorIdOffset);
ffStrbufTrim(&device->name, ' ');
}
if (sdd->ProductIdOffset != 0)
{
if (device->name.length)
ffStrbufAppendC(&device->name, ' ');
ffStrbufAppendS(&device->name, (const char*) sddBuffer + sdd->ProductIdOffset);
ffStrbufTrimRight(&device->name, ' ');
}
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
{
ffStrbufDestroy(&device->name);
result->length--;
continue;
}
ffStrbufInitWS(&device->devPath, szDevice);
ffStrbufInit(&device->serial);
if (sdd->SerialNumberOffset != 0)
{
ffStrbufSetS(&device->serial, (const char*) sddBuffer + sdd->SerialNumberOffset);
ffStrbufTrim(&device->serial, ' ');
}
device->type |= sdd->RemovableMedia ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
ffStrbufInit(&device->interconnect);
switch (sdd->BusType)
{
case BusTypeUnknown: ffStrbufSetStatic(&device->interconnect, "Unknown"); break;
case BusTypeScsi: ffStrbufSetStatic(&device->interconnect, "Scsi"); break;
case BusTypeAtapi: ffStrbufSetStatic(&device->interconnect, "Atapi"); break;
case BusTypeAta: ffStrbufSetStatic(&device->interconnect, "Ata"); break;
case BusType1394: ffStrbufSetStatic(&device->interconnect, "1394"); break;
case BusTypeSsa: ffStrbufSetStatic(&device->interconnect, "Ssa"); break;
case BusTypeFibre: ffStrbufSetStatic(&device->interconnect, "Fibra"); break;
case BusTypeUsb: ffStrbufSetStatic(&device->interconnect, "Usb"); break;
case BusTypeRAID: ffStrbufSetStatic(&device->interconnect, "RAID"); break;
case BusTypeiScsi: ffStrbufSetStatic(&device->interconnect, "iScsi"); break;
case BusTypeSas: ffStrbufSetStatic(&device->interconnect, "Sas"); break;
case BusTypeSata: ffStrbufSetStatic(&device->interconnect, "Sata"); break;
case BusTypeSd: ffStrbufSetStatic(&device->interconnect, "Sd"); break;
case BusTypeMmc: ffStrbufSetStatic(&device->interconnect, "Mmc"); break;
case BusTypeVirtual: ffStrbufSetStatic(&device->interconnect, "Virtual"); break;
case BusTypeFileBackedVirtual: ffStrbufSetStatic(&device->interconnect, "FileBackedVirtual"); break;
case BusTypeSpaces: ffStrbufSetStatic(&device->interconnect, "Spaces"); break;
case BusTypeNvme: ffStrbufSetStatic(&device->interconnect, "Nvme"); break;
case BusTypeSCM: ffStrbufSetStatic(&device->interconnect, "SCM"); break;
case BusTypeUfs: ffStrbufSetStatic(&device->interconnect, "Ufs"); break;
default: ffStrbufSetF(&device->interconnect, "Unknown (%d)", (int) sdd->BusType); break;
}
DEVICE_SEEK_PENALTY_DESCRIPTOR dspd = {};
if(DeviceIoControl(
hDevice,
IOCTL_STORAGE_QUERY_PROPERTY,
&(STORAGE_PROPERTY_QUERY) {
.PropertyId = StorageDeviceSeekPenaltyProperty,
.QueryType = PropertyStandardQuery,
},
sizeof(STORAGE_PROPERTY_QUERY),
&dspd,
sizeof(dspd),
&retSize,
NULL
) && retSize == sizeof(dspd))
device->type |= dspd.IncursSeekPenalty ? FF_PHYSICALDISK_TYPE_HDD : FF_PHYSICALDISK_TYPE_SSD;
DISK_GEOMETRY_EX dge = {};
if(DeviceIoControl(
hDevice,
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
NULL,
0,
&dge,
sizeof(dge),
&retSize,
NULL))
device->size = (uint64_t) dge.DiskSize.QuadPart;
else
device->size = 0;
}
return NULL;
}
+1
View File
@@ -37,6 +37,7 @@
#include "modules/opencl/opencl.h"
#include "modules/os/os.h"
#include "modules/packages/packages.h"
#include "modules/physicaldisk/physicaldisk.h"
#include "modules/player/player.h"
#include "modules/poweradapter/poweradapter.h"
#include "modules/processes/processes.h"
+1
View File
@@ -37,6 +37,7 @@
#include "modules/opencl/option.h"
#include "modules/os/option.h"
#include "modules/packages/option.h"
#include "modules/physicaldisk/option.h"
#include "modules/player/option.h"
#include "modules/poweradapter/option.h"
#include "modules/processes/option.h"
+13
View File
@@ -0,0 +1,13 @@
#pragma once
// This file will be included in "fastfetch.h", do NOT put unnecessary things here
#include "common/option.h"
typedef struct FFPhysicalDiskOptions
{
FFModuleBaseInfo moduleInfo;
FFModuleArgs moduleArgs;
FFstrbuf namePrefix;
} FFPhysicalDiskOptions;
+241
View File
@@ -0,0 +1,241 @@
#include "common/printing.h"
#include "common/jsonconfig.h"
#include "common/parsing.h"
#include "detection/physicaldisk/physicaldisk.h"
#include "modules/physicaldisk/physicaldisk.h"
#include "util/stringUtils.h"
#define FF_PHYSICALDISK_DISPLAY_NAME "Physical Disk"
#define FF_PHYSICALDISK_NUM_FORMAT_ARGS 7
static int sortDevices(const FFPhysicalDiskResult* left, const FFPhysicalDiskResult* right)
{
return ffStrbufComp(&left->name, &right->name);
}
static void formatKey(const FFPhysicalDiskOptions* options, FFPhysicalDiskResult* dev, uint32_t index, FFstrbuf* key)
{
if(options->moduleArgs.key.length == 0)
{
ffStrbufSetF(key, FF_PHYSICALDISK_DISPLAY_NAME " (%s)", dev->name.length ? dev->name.chars : dev->devPath.chars);
}
else
{
ffStrbufClear(key);
ffParseFormatString(key, &options->moduleArgs.key, 2, (FFformatarg[]){
{FF_FORMAT_ARG_TYPE_UINT, &index},
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->name},
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->devPath},
});
}
}
void ffPrintPhysicalDisk(FFPhysicalDiskOptions* options)
{
FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFPhysicalDiskResult));
const char* error = ffDetectPhysicalDisk(&result, options);
if(error)
{
ffPrintError(FF_PHYSICALDISK_DISPLAY_NAME, 0, &options->moduleArgs, "%s", error);
return;
}
ffListSort(&result, (const void*) sortDevices);
uint32_t index = 0;
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
FF_LIST_FOR_EACH(FFPhysicalDiskResult, dev, result)
{
formatKey(options, dev, result.length == 1 ? 0 : index + 1, &key);
ffStrbufClear(&buffer);
ffParseSize(dev->size, &buffer);
const char* physicalType = dev->type & FF_PHYSICALDISK_TYPE_HDD
? "HDD"
: dev->type & FF_PHYSICALDISK_TYPE_SSD
? "SSD"
: "";
const char* removableType = dev->type & FF_PHYSICALDISK_TYPE_REMOVABLE
? "Removable"
: dev->type & FF_PHYSICALDISK_TYPE_FIXED
? "Fixed"
: "";
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
if (physicalType[0] || removableType[0])
{
ffStrbufAppendS(&buffer, " [");
if (physicalType[0])
ffStrbufAppendS(&buffer, physicalType);
if (removableType[0])
{
if (physicalType[0])
ffStrbufAppendS(&buffer, ", ");
ffStrbufAppendS(&buffer, removableType);
}
ffStrbufAppendC(&buffer, ']');
}
ffStrbufPutTo(&buffer, stdout);
}
else
{
ffParseSize(dev->size, &buffer);
ffPrintFormatString(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_PHYSICALDISK_NUM_FORMAT_ARGS, (FFformatarg[]){
{FF_FORMAT_ARG_TYPE_STRBUF, &buffer},
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->name},
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->interconnect},
{FF_FORMAT_ARG_TYPE_STRING, physicalType},
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->devPath},
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->serial},
{FF_FORMAT_ARG_TYPE_STRING, removableType},
});
}
++index;
}
FF_LIST_FOR_EACH(FFPhysicalDiskResult, dev, result)
{
ffStrbufDestroy(&dev->name);
ffStrbufDestroy(&dev->interconnect);
ffStrbufDestroy(&dev->devPath);
ffStrbufDestroy(&dev->serial);
}
}
bool ffParsePhysicalDiskCommandOptions(FFPhysicalDiskOptions* options, const char* key, const char* value)
{
const char* subKey = ffOptionTestPrefix(key, FF_PHYSICALDISK_MODULE_NAME);
if (!subKey) return false;
if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs))
return true;
if (ffStrEqualsIgnCase(subKey, "name-prefix"))
{
ffOptionParseString(key, value, &options->namePrefix);
return true;
}
return false;
}
void ffParsePhysicalDiskJsonObject(FFPhysicalDiskOptions* options, yyjson_val* module)
{
yyjson_val *key_, *val;
size_t idx, max;
yyjson_obj_foreach(module, idx, max, key_, val)
{
const char* key = yyjson_get_str(key_);
if(ffStrEqualsIgnCase(key, "type"))
continue;
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
continue;
if (ffStrEqualsIgnCase(key, "namePrefix"))
{
ffStrbufSetS(&options->namePrefix, yyjson_get_str(val));
continue;
}
ffPrintError(FF_PHYSICALDISK_MODULE_NAME, 0, &options->moduleArgs, "Unknown JSON key %s", key);
}
}
void ffGeneratePhysicalDiskJsonConfig(FFPhysicalDiskOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
__attribute__((__cleanup__(ffDestroyPhysicalDiskOptions))) FFPhysicalDiskOptions defaultOptions;
ffInitPhysicalDiskOptions(&defaultOptions);
ffJsonConfigGenerateModuleArgsConfig(doc, module, &defaultOptions.moduleArgs, &options->moduleArgs);
if (!ffStrbufEqual(&options->namePrefix, &defaultOptions.namePrefix))
yyjson_mut_obj_add_strbuf(doc, module, "namePrefix", &options->namePrefix);
}
void ffGeneratePhysicalDiskJsonResult(FFPhysicalDiskOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFPhysicalDiskResult));
const char* error = ffDetectPhysicalDisk(&result, options);
if(error)
{
yyjson_mut_obj_add_str(doc, module, "error", error);
return;
}
yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "result");
FF_LIST_FOR_EACH(FFPhysicalDiskResult, dev, result)
{
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
yyjson_mut_obj_add_strbuf(doc, obj, "name", &dev->name);
yyjson_mut_obj_add_strbuf(doc, obj, "devPath", &dev->devPath);
yyjson_mut_obj_add_strbuf(doc, obj, "interconnect", &dev->interconnect);
if (dev->type & FF_PHYSICALDISK_TYPE_HDD)
yyjson_mut_obj_add_str(doc, obj, "kind", "HDD");
else if (dev->type & FF_PHYSICALDISK_TYPE_SSD)
yyjson_mut_obj_add_str(doc, obj, "kind", "SSD");
else
yyjson_mut_obj_add_null(doc, obj, "kind");
yyjson_mut_obj_add_uint(doc, obj, "size", dev->size);
yyjson_mut_obj_add_strbuf(doc, obj, "serial", &dev->serial);
if (dev->type & FF_PHYSICALDISK_TYPE_REMOVABLE)
yyjson_mut_obj_add_bool(doc, obj, "removable", true);
else if (dev->type & FF_PHYSICALDISK_TYPE_FIXED)
yyjson_mut_obj_add_bool(doc, obj, "removable", false);
else
yyjson_mut_obj_add_null(doc, obj, "removable");
}
FF_LIST_FOR_EACH(FFPhysicalDiskResult, dev, result)
{
ffStrbufDestroy(&dev->name);
ffStrbufDestroy(&dev->interconnect);
ffStrbufDestroy(&dev->devPath);
}
}
void ffPrintPhysicalDiskHelpFormat(void)
{
ffPrintModuleFormatHelp(FF_PHYSICALDISK_MODULE_NAME, "{1}", FF_PHYSICALDISK_NUM_FORMAT_ARGS, (const char* []) {
"Device size (formatted)",
"Device name",
"Device interconnect type",
"Device raw file path",
"Serial number",
"Device kind (SSD or HDD)",
"Device kind (Removable or Fixed)",
});
}
void ffInitPhysicalDiskOptions(FFPhysicalDiskOptions* options)
{
ffOptionInitModuleBaseInfo(
&options->moduleInfo,
FF_PHYSICALDISK_MODULE_NAME,
"Print physical disk information",
ffParsePhysicalDiskCommandOptions,
ffParsePhysicalDiskJsonObject,
ffPrintPhysicalDisk,
ffGeneratePhysicalDiskJsonResult,
ffPrintPhysicalDiskHelpFormat,
ffGeneratePhysicalDiskJsonConfig
);
ffOptionInitModuleArg(&options->moduleArgs);
ffStrbufInit(&options->namePrefix);
}
void ffDestroyPhysicalDiskOptions(FFPhysicalDiskOptions* options)
{
ffOptionDestroyModuleArg(&options->moduleArgs);
ffStrbufDestroy(&options->namePrefix);
}
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include "fastfetch.h"
#define FF_PHYSICALDISK_MODULE_NAME "PhysicalDisk"
void ffPrintPhysicalDisk(FFPhysicalDiskOptions* options);
void ffInitPhysicalDiskOptions(FFPhysicalDiskOptions* options);
void ffDestroyPhysicalDiskOptions(FFPhysicalDiskOptions* options);
+2
View File
@@ -38,6 +38,7 @@ void ffOptionsInitModules(FFOptionsModules* options)
ffInitOpenCLOptions(&options->openCL);
ffInitOpenGLOptions(&options->openGL);
ffInitPackagesOptions(&options->packages);
ffInitPhysicalDiskOptions(&options->physicalDisk);
ffInitPlayerOptions(&options->player);
ffInitPowerAdapterOptions(&options->powerAdapter);
ffInitProcessesOptions(&options->processes);
@@ -98,6 +99,7 @@ void ffOptionsDestroyModules(FFOptionsModules* options)
ffDestroyOSOptions(&options->os);
ffDestroyOpenCLOptions(&options->openCL);
ffDestroyOpenGLOptions(&options->openGL);
ffDestroyPhysicalDiskOptions(&options->physicalDisk);
ffDestroyPackagesOptions(&options->packages);
ffDestroyPlayerOptions(&options->player);
ffDestroyPowerAdapterOptions(&options->powerAdapter);
+1
View File
@@ -39,6 +39,7 @@ typedef struct FFOptionsModules
FFOpenCLOptions openCL;
FFOpenGLOptions openGL;
FFPackagesOptions packages;
FFPhysicalDiskOptions physicalDisk;
FFPlayerOptions player;
FFPowerAdapterOptions powerAdapter;
FFProcessesOptions processes;