mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-10-30 00:37:23 +01:00
PhysicalDisk: add new module
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
|
||||
@@ -39,6 +39,7 @@ typedef struct FFOptionsModules
|
||||
FFOpenCLOptions openCL;
|
||||
FFOpenGLOptions openGL;
|
||||
FFPackagesOptions packages;
|
||||
FFPhysicalDiskOptions physicalDisk;
|
||||
FFPlayerOptions player;
|
||||
FFPowerAdapterOptions powerAdapter;
|
||||
FFProcessesOptions processes;
|
||||
|
||||
Reference in New Issue
Block a user