Version", result);
-
- #ifdef __FreeBSD__
- if(result->length == 0)
- {
- FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/usr/local/share/licenses/");
- if (dirp)
- {
- struct dirent* entry;
- while((entry = readdir(dirp)) != NULL)
- {
- if(!ffStrStartsWith(entry->d_name, "xfce-") || !isdigit(entry->d_name[5]))
- continue;
- ffStrbufAppendS(result, &entry->d_name[5]);
- }
- }
- }
- #endif
+ getXfce4ByLib(result);
if(result->length == 0 && options->slowVersionDetection)
{
@@ -117,8 +110,8 @@ static void getXFCE4(FFstrbuf* result, FFDEOptions* options)
NULL
});
- ffStrbufSubstrBeforeFirstC(result, '(');
- ffStrbufSubstrAfterFirstC(result, ' ');
+ ffStrbufSubstrBeforeFirstC(result, ')');
+ ffStrbufSubstrAfterLastC(result, ' ');
ffStrbufTrim(result, ' ');
}
}
diff --git a/src/detection/disk/disk_linux.c b/src/detection/disk/disk_linux.c
index 0cef2d64b..ae94117c2 100644
--- a/src/detection/disk/disk_linux.c
+++ b/src/detection/disk/disk_linux.c
@@ -106,14 +106,6 @@ static void detectName(FFDisk* disk)
FF_STRBUF_AUTO_DESTROY basePath = ffStrbufCreate();
- //Detect USB devices. Code is put here to reuse deviceStat
- //https://stackoverflow.com/a/73302717
- ffStrbufAppendS(&basePath, "/dev/disk/by-id/");
- detectNameFromPath(disk, &deviceStat, &basePath);
- if (ffStrbufStartsWithS(&disk->name, "usb-"))
- disk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
- ffStrbufClear(&disk->name);
-
//Try label first
ffStrbufSetS(&basePath, "/dev/disk/by-label/");
detectNameFromPath(disk, &deviceStat, &basePath);
@@ -197,9 +189,6 @@ static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
static bool isRemovable(FFDisk* currentDisk)
{
- // https://stackoverflow.com/a/73302025
- // Note my USB mobile hard disk isn't detected as removable, but my USB flash disk does.
- // USB devices should be handled in detectName
FF_STRBUF_AUTO_DESTROY basePath = ffStrbufCreateS("/sys/block/");
FF_AUTO_CLOSE_DIR DIR* dir = opendir(basePath.chars);
@@ -218,11 +207,10 @@ static bool isRemovable(FFDisk* currentDisk)
if (!ffStrStartsWith(partitionName, entry->d_name)) continue;
- // /sys/block/sdx/removable
+ // /sys/block/sdx/device/delete
ffStrbufAppendS(&basePath, entry->d_name);
- ffStrbufAppendS(&basePath, "/removable");
- FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
- return ffReadFileBuffer(basePath.chars, &buffer) && ffStrbufEqualS(&buffer, "1");
+ ffStrbufAppendS(&basePath, "/device/delete");
+ return ffPathExists(basePath.chars, FF_PATHTYPE_FILE);
}
return false;
@@ -230,14 +218,12 @@ static bool isRemovable(FFDisk* currentDisk)
static void detectType(const FFlist* disks, FFDisk* currentDisk)
{
- if(currentDisk->type != FF_DISK_VOLUME_TYPE_NONE) return;
-
- if(isRemovable(currentDisk))
+ if(ffStrbufStartsWithS(¤tDisk->mountpoint, "/boot") || ffStrbufStartsWithS(¤tDisk->mountpoint, "/efi"))
+ currentDisk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
+ else if(isRemovable(currentDisk))
currentDisk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
else if(isSubvolume(disks, currentDisk))
currentDisk->type = FF_DISK_VOLUME_TYPE_SUBVOLUME_BIT;
- else if(ffStrbufStartsWithS(¤tDisk->mountpoint, "/boot") || ffStrbufStartsWithS(¤tDisk->mountpoint, "/efi"))
- currentDisk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
else
currentDisk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
}
diff --git a/src/detection/diskio/diskio.c b/src/detection/diskio/diskio.c
index cb452743e..efac624b9 100644
--- a/src/detection/diskio/diskio.c
+++ b/src/detection/diskio/diskio.c
@@ -47,8 +47,8 @@ const char* ffDetectDiskIO(FFlist* result, FFDiskIOOptions* options)
{
FFDiskIOResult* icPrev = (FFDiskIOResult*)ffListGet(&ioCounters1, i);
FFDiskIOResult* icCurr = (FFDiskIOResult*)ffListGet(result, i);
- if (!ffStrbufEqual(&icPrev->name, &icCurr->name))
- return "Network interface name changed";
+ if (!ffStrbufEqual(&icPrev->devPath, &icCurr->devPath))
+ return "Physical disk device path changed";
static_assert(sizeof(FFDiskIOResult) - offsetof(FFDiskIOResult, bytesRead) == sizeof(uint64_t) * 4, "Unexpected struct FFDiskIOResult layout");
for (size_t off = offsetof(FFDiskIOResult, bytesRead); off < sizeof(FFDiskIOResult); off += sizeof(uint64_t))
diff --git a/src/detection/diskio/diskio.h b/src/detection/diskio/diskio.h
index 0f8b39f56..0082b18b7 100644
--- a/src/detection/diskio/diskio.h
+++ b/src/detection/diskio/diskio.h
@@ -2,19 +2,9 @@
#include "fastfetch.h"
-typedef enum FFDiskIOPhysicalType
-{
- FF_DISKIO_PHYSICAL_TYPE_UNKNOWN,
- FF_DISKIO_PHYSICAL_TYPE_HDD,
- FF_DISKIO_PHYSICAL_TYPE_SSD,
-} FFDiskIOPhysicalType;
-
typedef struct FFDiskIOResult
{
FFstrbuf name;
- FFstrbuf interconnect;
- FFDiskIOPhysicalType type;
- uint64_t size;
FFstrbuf devPath;
uint64_t bytesRead;
uint64_t readCount;
diff --git a/src/detection/diskio/diskio_apple.c b/src/detection/diskio/diskio_apple.c
index b733cbfc9..bc5d57f25 100644
--- a/src/detection/diskio/diskio_apple.c
+++ b/src/detection/diskio/diskio_apple.c
@@ -48,8 +48,6 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
ffStrbufInitS(&device->name, deviceName);
ffStrbufInit(&device->devPath);
- device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
- device->size = 0;
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey), (int64_t*) &device->bytesRead);
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey), (int64_t*) &device->bytesWritten);
@@ -62,34 +60,6 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
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;
-
- ffStrbufInit(&device->interconnect);
- 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("Physical Interconnect"), &device->interconnect);
-
- FF_CFTYPE_AUTO_RELEASE CFDictionaryRef deviceCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyDeviceCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
- if (deviceCharacteristics)
- {
- CFStringRef mediumType = (CFStringRef) CFDictionaryGetValue(deviceCharacteristics, CFSTR(kIOPropertyMediumTypeKey));
- if (mediumType)
- {
- if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeSolidStateKey), 0) == 0)
- device->type = FF_DISKIO_PHYSICAL_TYPE_SSD;
- else if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeRotationalKey), 0) == 0)
- device->type = FF_DISKIO_PHYSICAL_TYPE_HDD;
- }
- }
- }
}
return NULL;
diff --git a/src/detection/diskio/diskio_bsd.c b/src/detection/diskio/diskio_bsd.c
index a4a911b93..08ecb47cf 100644
--- a/src/detection/diskio/diskio_bsd.c
+++ b/src/detection/diskio/diskio_bsd.c
@@ -32,35 +32,25 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
if (provider->lg_geom->lg_rank != 1)
continue;
- FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateS(provider->lg_name);
- FFDiskIOPhysicalType type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
+ FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
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_DISKIO_PHYSICAL_TYPE_SSD : FF_DISKIO_PHYSICAL_TYPE_HDD;
}
+ if (name.length == 0)
+ ffStrbufSetS(&name, provider->lg_name);
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
continue;
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
ffStrbufInitF(&device->devPath, "/dev/%s", provider->lg_name);
- 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->bytesRead = snapIter->bytes[DEVSTAT_READ];
device->readCount = snapIter->operations[DEVSTAT_READ];
device->bytesWritten = snapIter->bytes[DEVSTAT_WRITE];
device->writeCount = snapIter->operations[DEVSTAT_WRITE];
- device->size = (uint64_t) provider->lg_mediasize;
ffStrbufInitMove(&device->name, &name);
- device->type = type;
}
geom_stats_snapshot_free(snap);
diff --git a/src/detection/diskio/diskio_linux.c b/src/detection/diskio/diskio_linux.c
index 3737789be..e865581c2 100644
--- a/src/detection/diskio/diskio_linux.c
+++ b/src/detection/diskio/diskio_linux.c
@@ -1,5 +1,6 @@
#include "diskio.h"
#include "common/io/io.h"
+#include "common/properties.h"
#include "util/stringUtils.h"
#include
@@ -7,107 +8,75 @@
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
- FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateS("/dev/disk/by-id/");
- uint32_t baseDirLength = baseDir.length;
+ FF_AUTO_CLOSE_DIR DIR* sysBlockDirp = opendir("/sys/block/");
+ if(sysBlockDirp == NULL)
+ return "opendir(\"/sys/block/\") == NULL";
- FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir.chars);
- if(dirp == NULL)
- return "opendir(batteryDir) == NULL";
-
- struct dirent* entry;
- while ((entry = readdir(dirp)) != NULL)
+ struct dirent* sysBlockEntry;
+ while ((sysBlockEntry = readdir(sysBlockDirp)) != NULL)
{
- if (entry->d_name[0] == '.')
+ const char* const devName = sysBlockEntry->d_name;
+
+ if (devName[0] == '.')
continue;
- char* part = strstr(entry->d_name, "-part");
- if (part && isdigit(part[strlen("-part")]))
- continue;
-
- if (ffStrStartsWith(entry->d_name, "nvme-eui.")) // NVMe drive identifier
- continue;
-
- // Other exceptions?
-
- ffStrbufAppendS(&baseDir, entry->d_name);
- char pathDev[PATH_MAX];
- ssize_t pathLen = readlink(baseDir.chars, pathDev, PATH_MAX);
- ffStrbufSubstrBefore(&baseDir, baseDirLength);
-
- if (pathLen < 0) continue;
- pathDev[pathLen] = '\0'; // ../../nvme0n1
-
- char pathDev1[PATH_MAX];
- const char* devName = basename(pathDev);
- snprintf(pathDev1, PATH_MAX, "/dev/%s", devName);
-
- // Avoid duplicated disks
- bool flag = false;
- FF_LIST_FOR_EACH(FFDiskIOResult, disk, *result)
- {
- if (ffStrbufEqualS(&disk->devPath, pathDev1))
- {
- flag = true;
- break;
- }
- }
- if (flag) continue;
-
char pathSysBlock[PATH_MAX];
- snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/stat", devName);
+ snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s", devName);
- FF_AUTO_CLOSE_FILE FILE* sysBlockStat = fopen(pathSysBlock, "r");
- if (!sysBlockStat) continue;
+ char pathSysDeviceReal[PATH_MAX];
+ ssize_t pathLength = readlink(pathSysBlock, pathSysDeviceReal, sizeof(pathSysDeviceReal) - 1);
+ if (pathLength < 0)
+ continue;
+ pathSysDeviceReal[pathLength] = '\0';
- // I/Os merges sectors ticks ...
- uint64_t nRead, sectorRead, nWritten, sectorWritten;
- if (fscanf(sysBlockStat, "%lu%*u%lu%*u%lu%*u%lu%*u", &nRead, §orRead, &nWritten, §orWritten) == 0)
+ if (strstr(pathSysDeviceReal, "/virtual/")) // virtual device
+ continue;
+
+ snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device", devName);
+ if (!ffPathExists(pathSysBlock, FF_PATHTYPE_DIRECTORY))
continue;
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
- char* slash = strchr(entry->d_name, '-');
- if (slash)
- {
- char* slash2 = strchr(slash + 1, '-');
- if (slash2)
- ffStrbufInitNS(&device->name, (uint32_t) (slash2 - slash - 1), slash + 1);
- else
- ffStrbufInitS(&device->name, slash + 1);
- ffStrbufInitNS(&device->interconnect, (uint32_t) (slash - entry->d_name), entry->d_name);
- }
- else
- {
- ffStrbufInitS(&device->name, entry->d_name);
- ffStrbufInit(&device->interconnect);
- }
- ffStrbufReplaceAllC(&device->name, '_', ' ');
+ ffStrbufInit(&device->name);
- if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
{
- ffStrbufDestroy(&device->name);
- ffStrbufDestroy(&device->interconnect);
- result->length--;
- continue;
+ 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;
+ }
}
- ffStrbufInitS(&device->devPath, pathDev1);
+ // I/Os merges sectors ticks ...
+ uint64_t nRead, sectorRead, nWritten, sectorWritten;
+ {
+ char sysBlockStat[PROC_FILE_BUFFSIZ];
+ snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/stat", devName);
+ ssize_t fileSize = ffReadFileData(pathSysBlock, sizeof(sysBlockStat) - 1, sysBlockStat);
+ if (fileSize <= 0) continue;
+ sysBlockStat[fileSize] = '\0';
+ if (sscanf(sysBlockStat, "%lu%*u%lu%*u%lu%*u%lu%*u", &nRead, §orRead, &nWritten, §orWritten) <= 0)
+ continue;
+ }
+
+ ffStrbufInitF(&device->devPath, "/dev/%s", devName);
device->bytesRead = sectorRead * 512;
device->bytesWritten = sectorWritten * 512;
device->readCount = nRead;
device->writeCount = nWritten;
-
- snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/queue/rotational", devName);
- FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
- if (ffReadFileBuffer(pathSysBlock, &buffer))
- device->type = ffStrbufEqualS(&buffer, "1") ? FF_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD;
- else
- device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
-
- snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/size", devName);
- if (ffReadFileBuffer(pathSysBlock, &buffer))
- device->size = ffStrbufToUInt(&buffer, 0);
- else
- device->size = 0;
}
return NULL;
diff --git a/src/detection/diskio/diskio_windows.c b/src/detection/diskio/diskio_windows.c
index 0fe06faf7..de7ef5c1c 100644
--- a/src/detection/diskio/diskio_windows.c
+++ b/src/detection/diskio/diskio_windows.c
@@ -1,101 +1,82 @@
#include "diskio.h"
#include "common/io/io.h"
-#include "util/windows/registry.h"
#include "util/windows/unicode.h"
+#include
#include
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
{
- FF_HKEY_AUTO_DESTROY hKey = NULL;
- if (!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\disk\\Enum", &hKey, NULL))
- return "ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L\"SYSTEM\\CurrentControlSet\\Services\\disk\\Enum\") failed";
-
- uint32_t nDevices;
- if (!ffRegReadUint(hKey, L"Count", &nDevices, NULL))
- return "ffRegReadUint(hKey, L\"Count\", &nDevices) failed";
-
wchar_t szDevice[32] = L"\\\\.\\PhysicalDrive";
wchar_t* pNum = szDevice + strlen("\\\\.\\PhysicalDrive");
- for (uint32_t idev = 0; idev <= nDevices; ++idev) {
+ 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;
- DISK_PERFORMANCE diskPerformance;
- DWORD ioctrlSize = sizeof(diskPerformance);
- DWORD dwSize;
- if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0, &diskPerformance, ioctrlSize, &dwSize, NULL))
+ FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
+ STORAGE_DEVICE_DESCRIPTOR* sdd = (STORAGE_DEVICE_DESCRIPTOR*) sddBuffer;
+
+ ffStrbufInit(&device->name);
+ if (sdd->VendorIdOffset != 0)
{
- FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
- ffStrbufInit(&device->name);
- ffStrbufInit(&device->interconnect);
- if (ffRegReadStrbuf(hKey, pNum, &device->name, NULL))
- {
- // SCSI\Disk&Ven_NVMe&Prod_WDC_PC_SN810_SDC\5&19cebb7&0&000000
- uint32_t index = ffStrbufFirstIndexC(&device->name, '\\');
- if (index != device->name.length)
- {
- ffStrbufAppendNS(&device->interconnect, index, device->name.chars); // SCSI
- ffStrbufSubstrAfter(&device->name, index);
- }
- ffStrbufSubstrBeforeLastC(&device->name, '\\');
- ffStrbufSubstrAfterFirstS(&device->name, "&Ven_");
- ffStrbufRemoveS(&device->name, "&Prod");
- ffStrbufReplaceAllC(&device->name, '_', ' ');
- ffStrbufTrim(&device->name, ' ');
- }
- else
- ffStrbufSetWS(&device->name, szDevice);
+ ffStrbufSetS(&device->name, (const char*) sddBuffer + sdd->VendorIdOffset);
+ ffStrbufTrim(&device->name, ' ');
+ }
+ if (sdd->ProductIdOffset != 0)
+ {
+ if (device->name.length)
+ ffStrbufAppendC(&device->name, ' ');
- if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
- {
- ffStrbufDestroy(&device->name);
- ffStrbufDestroy(&device->interconnect);
- result->length--;
- continue;
- }
+ ffStrbufAppendS(&device->name, (const char*) sddBuffer + sdd->ProductIdOffset);
+ ffStrbufTrimRight(&device->name, ' ');
+ }
- ffStrbufInitWS(&device->devPath, szDevice);
- device->bytesRead = (uint64_t) diskPerformance.BytesRead.QuadPart;
- device->readCount = (uint64_t) diskPerformance.ReadCount;
- device->bytesWritten = (uint64_t) diskPerformance.BytesWritten.QuadPart;
- device->writeCount = (uint64_t) diskPerformance.WriteCount;
+ if (!device->name.length)
+ ffStrbufAppendF(&device->name, "PhysicalDrive%u", (unsigned) idev);
- DEVICE_SEEK_PENALTY_DESCRIPTOR dspd = {};
- DWORD retSize = 0;
- 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_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD;
- else
- device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
+ if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
+ {
+ ffStrbufDestroy(&device->name);
+ result->length--;
+ continue;
+ }
- 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;
+ ffStrbufInitWS(&device->devPath, szDevice);
+
+ DISK_PERFORMANCE dp = {};
+ if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0, &dp, sizeof(dp), &retSize, NULL))
+ {
+ device->bytesRead = (uint64_t) dp.BytesRead.QuadPart;
+ device->readCount = (uint64_t) dp.ReadCount;
+ device->bytesWritten = (uint64_t) dp.BytesWritten.QuadPart;
+ device->writeCount = (uint64_t) dp.WriteCount;
+ }
+ else
+ {
+ ffStrbufDestroy(&device->name);
+ result->length--;
+ continue;
}
}
diff --git a/src/detection/displayserver/displayserver.h b/src/detection/displayserver/displayserver.h
index 7a5ebb8f8..b5655a84f 100644
--- a/src/detection/displayserver/displayserver.h
+++ b/src/detection/displayserver/displayserver.h
@@ -11,6 +11,7 @@
#define FF_DE_PRETTY_LXDE "LXDE"
#define FF_DE_PRETTY_LXQT "LXQT"
#define FF_DE_PRETTY_BUDGIE "Budgie"
+#define FF_DE_PRETTY_CDE "CDE"
#define FF_DE_PRETTY_UNITY "Unity"
#define FF_WM_PRETTY_KWIN "KWin"
@@ -32,6 +33,7 @@
#define FF_WM_PRETTY_HERBSTLUFTWM "herbstluftwm"
#define FF_WM_PRETTY_ICEWM "IceWM"
#define FF_WM_PRETTY_SPECTRWM "spectrwm"
+#define FF_WM_PRETTY_DTWM "dtwm"
#define FF_WM_PROTOCOL_TTY "TTY"
diff --git a/src/detection/displayserver/linux/displayserver_linux.c b/src/detection/displayserver/linux/displayserver_linux.c
index d6eb3da99..e75e311b0 100644
--- a/src/detection/displayserver/linux/displayserver_linux.c
+++ b/src/detection/displayserver/linux/displayserver_linux.c
@@ -10,7 +10,7 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
ffStrbufInit(&ds->dePrettyName);
ffListInitA(&ds->displays, sizeof(FFDisplayResult), 4);
- if (!instance.config.general.dsForceDrm)
+ if (instance.config.general.dsForceDrm == FF_DS_FORCE_DRM_TYPE_FALSE)
{
//We try wayland as our preferred display server, as it supports the most features.
//This method can't detect the name of our WM / DE
diff --git a/src/detection/displayserver/linux/drm.c b/src/detection/displayserver/linux/drm.c
index baf4e4bdf..cf6bf3cde 100644
--- a/src/detection/displayserver/linux/drm.c
+++ b/src/detection/displayserver/linux/drm.c
@@ -27,10 +27,10 @@ static const char* drmParseSysfs(FFDisplayServerResult* result)
ffStrbufAppendS(&drmDir, entry->d_name);
uint32_t drmDirWithDnameLength = drmDir.length;
- ffStrbufAppendS(&drmDir, "/enabled");
- char enabled = 'd'; // disabled
- ffReadFileData(drmDir.chars, sizeof(enabled), &enabled);
- if (enabled != 'e') // enabled
+ ffStrbufAppendS(&drmDir, "/status");
+ char status = 'd'; // disconnected
+ ffReadFileData(drmDir.chars, sizeof(status), &status);
+ if (status != 'c') // connected
{
ffStrbufSubstrBefore(&drmDir, drmDirLength);
continue;
@@ -152,6 +152,49 @@ static inline const char* drmType2Name(uint32_t connector_type)
}
}
+static const char* drmGetNameByConnId(uint32_t connId, FFstrbuf* name)
+{
+ const char* drmDirPath = "/sys/class/drm/";
+
+ FF_AUTO_CLOSE_DIR DIR* dirp = opendir(drmDirPath);
+ if(dirp == NULL)
+ return "opendir(drmDirPath) failed";
+
+ FF_STRBUF_AUTO_DESTROY drmDir = ffStrbufCreateA(64);
+ ffStrbufAppendS(&drmDir, drmDirPath);
+
+ uint32_t drmDirLength = drmDir.length;
+
+ struct dirent* entry;
+ while((entry = readdir(dirp)) != NULL)
+ {
+ if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, ".."))
+ continue;
+
+ ffStrbufAppendS(&drmDir, entry->d_name);
+ uint32_t drmDirWithDnameLength = drmDir.length;
+
+ ffStrbufAppendS(&drmDir, "/connector_id");
+ ffReadFileBuffer(drmDir.chars, name);
+ if (ffStrbufToUInt(name, 0) != connId)
+ {
+ ffStrbufSubstrBefore(&drmDir, drmDirLength);
+ continue;
+ }
+
+ ffStrbufSubstrBefore(&drmDir, drmDirWithDnameLength);
+ ffStrbufClear(name);
+ ffStrbufAppendS(&drmDir, "/edid");
+ uint8_t edidData[128];
+ if(ffReadFileData(drmDir.chars, sizeof(edidData), edidData) == sizeof(edidData))
+ ffEdidGetName(edidData, name);
+ return NULL;
+ }
+
+ ffStrbufClear(name);
+ return "Failed to match connector ID";
+}
+
static const char* drmConnectLibdrm(FFDisplayServerResult* result)
{
FF_LIBRARY_LOAD(libdrm, &instance.config.library.libdrm, "dlopen(libdrm)" FF_LIBRARY_EXTENSION " failed", "libdrm" FF_LIBRARY_EXTENSION, 2)
@@ -162,6 +205,7 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetEncoder)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetProperty)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetPropertyBlob)
+ FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeResources)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeCrtc)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeEncoder)
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeConnector)
@@ -196,18 +240,56 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
if (!conn)
continue;
- if (conn->connection != DRM_MODE_CONNECTED)
- goto next_conn;
-
- drmModeEncoder* encoder = ffdrmModeGetEncoder(fd, conn->encoder_id);
- if (!encoder)
- goto next_conn;
-
- drmModeCrtc* crtc = ffdrmModeGetCrtc(fd, encoder->crtc_id);
- if (!crtc)
- goto next_encoder;
-
+ if (conn->connection == DRM_MODE_CONNECTED)
{
+ drmModeEncoder* encoder = ffdrmModeGetEncoder(fd, conn->encoder_id);
+ uint32_t width = 0, height = 0, refreshRate = 0;
+
+ if (encoder)
+ {
+ drmModeCrtc* crtc = ffdrmModeGetCrtc(fd, encoder->crtc_id);
+ if (crtc)
+ {
+ width = crtc->mode.vdisplay;
+ height = crtc->mode.hdisplay;
+ refreshRate = crtc->mode.vrefresh;
+ if (refreshRate == 0)
+ {
+ // There are weird cases that we can't get the refresh rate from the CRTC but from the modes
+ for (int iMode = 0; iMode < conn->count_modes; ++iMode)
+ {
+ drmModeModeInfo* mode = &conn->modes[iMode];
+ if (mode->clock == crtc->mode.clock && mode->htotal == crtc->mode.htotal)
+ {
+ refreshRate = mode->vrefresh;
+ break;
+ }
+ }
+ }
+ ffdrmModeFreeCrtc(crtc);
+ }
+
+ ffdrmModeFreeEncoder(encoder);
+ }
+
+ if (width == 0 || height == 0)
+ {
+ // NVIDIA DRM driver seems incomplete and conn->encoder_id == 0
+ // Assume preferred resolution is used as what we do in drmParseSys
+ for (int iMode = 0; iMode < conn->count_modes; ++iMode)
+ {
+ drmModeModeInfo* mode = &conn->modes[iMode];
+
+ if (mode->type & DRM_MODE_TYPE_PREFERRED)
+ {
+ width = mode->hdisplay;
+ height = mode->vdisplay;
+ refreshRate = mode->vrefresh;
+ break;
+ }
+ }
+ }
+
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
for (int iProp = 0; iProp < conn->count_props; ++iProp)
@@ -219,60 +301,58 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
uint32_t type = prop->flags & (DRM_MODE_PROP_LEGACY_TYPE | DRM_MODE_PROP_EXTENDED_TYPE);
if (type == DRM_MODE_PROP_BLOB && ffStrEquals(prop->name, "EDID"))
{
- // Stangely, prop->count_blobs is 0 and prop->blob_ids is NULL
- drmModePropertyBlobPtr blob = ffdrmModeGetPropertyBlob(fd, (uint32_t) conn->prop_values[iProp]);
- if (blob->length >= 128)
- ffEdidGetName(blob->data, &name);
- ffdrmModeFreePropertyBlob(blob);
+ drmModePropertyBlobPtr blob = NULL;
+
+ if (prop->count_blobs > 0 && prop->blob_ids != NULL)
+ blob = ffdrmModeGetPropertyBlob(fd, prop->blob_ids[0]);
+ else
+ blob = ffdrmModeGetPropertyBlob(fd, (uint32_t) conn->prop_values[iProp]);
+
+ if (blob)
+ {
+ if (blob->length >= 128)
+ ffEdidGetName(blob->data, &name);
+ ffdrmModeFreePropertyBlob(blob);
+ }
break;
}
ffdrmModeFreeProperty(prop);
}
+ if (name.length == 0)
+ {
+ drmGetNameByConnId(conn->connector_id, &name);
+ }
+
if (name.length == 0)
{
const char* connectorTypeName = drmType2Name(conn->connector_type);
if (connectorTypeName == NULL)
connectorTypeName = "Unknown";
- ffStrbufSetF(&name, "%s-%d", connectorTypeName, iConn);
+ ffStrbufSetF(&name, "%s-%d", connectorTypeName, iConn + 1);
}
- uint32_t refreshRate = crtc->mode.vrefresh;
- if (refreshRate == 0)
- {
- // There are weird cases that we can't get the refresh rate from the CRTC but from the modes
- for (int iMode = 0; iMode < conn->count_modes; ++iMode)
- {
- drmModeModeInfo* mode = &conn->modes[iMode];
- if (mode->clock == crtc->mode.clock && mode->htotal == crtc->mode.htotal)
- {
- refreshRate = mode->vrefresh;
- break;
- }
- }
- }
-
- ffdsAppendDisplay(
- result,
- crtc->width, crtc->height,
+ ffdsAppendDisplay(result,
+ width,
+ height,
refreshRate,
- 0, 0,
+ 0,
+ 0,
0,
&name,
- FF_DISPLAY_TYPE_UNKNOWN,
+ conn->connector_type == DRM_MODE_CONNECTOR_eDP
+ ? FF_DISPLAY_TYPE_BUILTIN
+ : conn->connector_type == DRM_MODE_CONNECTOR_HDMIA || conn->connector_type == DRM_MODE_CONNECTOR_HDMIB
+ ? FF_DISPLAY_TYPE_EXTERNAL : FF_DISPLAY_TYPE_UNKNOWN,
false,
- 0
+ conn->connector_id
);
}
- ffdrmModeFreeCrtc(crtc);
-
- next_encoder:
- ffdrmModeFreeEncoder(encoder);
-
- next_conn:
ffdrmModeFreeConnector(conn);
}
+
+ ffdrmModeFreeResources(res);
}
ffdrmFreeDevices(devices, nDevices);
@@ -285,8 +365,11 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
void ffdsConnectDrm(FFDisplayServerResult* result)
{
#ifdef FF_HAVE_DRM
- if (drmConnectLibdrm(result) == NULL)
- return;
+ if (instance.config.general.dsForceDrm != FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY)
+ {
+ if (drmConnectLibdrm(result) == NULL)
+ return;
+ }
#endif
drmParseSysfs(result);
diff --git a/src/detection/displayserver/linux/wmde.c b/src/detection/displayserver/linux/wmde.c
index 740050b46..971b14d29 100644
--- a/src/detection/displayserver/linux/wmde.c
+++ b/src/detection/displayserver/linux/wmde.c
@@ -1,14 +1,20 @@
#include "displayserver_linux.h"
-#include "common/io/io.h"
#include "common/properties.h"
-#include "common/processing.h"
#include "util/stringUtils.h"
+#include "util/mallocHelper.h"
#include
#include
#include
#include
-#include
+
+#ifdef __FreeBSD__
+ #include
+ #include
+ #include
+#else
+ #include "common/io/io.h"
+#endif
static const char* parseEnv(void)
{
@@ -46,10 +52,12 @@ static const char* parseEnv(void)
if(getenv("TDE_FULL_SESSION") != NULL)
return "Trinity";
+ #ifdef __linux__
if(
getenv("WAYLAND_DISPLAY") != NULL &&
ffPathExists("/mnt/wslg/", FF_PATHTYPE_DIRECTORY)
) return "WSLg";
+ #endif
return NULL;
}
@@ -60,52 +68,54 @@ static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* name)
return;
if(
- strcasecmp(name, "kwin_wayland") == 0 ||
- strcasecmp(name, "kwin_wayland_wrapper") == 0 ||
- strcasecmp(name, "kwin_x11") == 0 ||
- strcasecmp(name, "kwin_x11_wrapper") == 0 ||
- strcasecmp(name, "kwin") == 0
+ ffStrEqualsIgnCase(name, "kwin_wayland") ||
+ ffStrEqualsIgnCase(name, "kwin_wayland_wrapper") ||
+ ffStrEqualsIgnCase(name, "kwin_x11") ||
+ ffStrEqualsIgnCase(name, "kwin_x11_wrapper") ||
+ ffStrEqualsIgnCase(name, "kwin")
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_KWIN);
else if(
- strcasecmp(name, "gnome-shell") == 0 ||
- strcasecmp(name, "gnome shell") == 0 ||
- strcasecmp(name, "gnome-session-binary") == 0 ||
- strcasecmp(name, "Mutter") == 0
+ ffStrEqualsIgnCase(name, "gnome-shell") ||
+ ffStrEqualsIgnCase(name, "gnome shell") ||
+ ffStrEqualsIgnCase(name, "gnome-session-binary") ||
+ ffStrEqualsIgnCase(name, "Mutter")
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MUTTER);
else if(
- strcasecmp(name, "cinnamon-session") == 0 ||
- strcasecmp(name, "Muffin") == 0 ||
- strcasecmp(name, "Mutter (Muffin)") == 0
+ ffStrEqualsIgnCase(name, "cinnamon-session") ||
+ ffStrEqualsIgnCase(name, "Muffin") ||
+ ffStrEqualsIgnCase(name, "Mutter (Muffin)")
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MUFFIN);
- else if(strcasecmp(name, "sway") == 0)
+ else if(ffStrEqualsIgnCase(name, "sway"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_SWAY);
- else if(strcasecmp(name, "weston") == 0)
+ else if(ffStrEqualsIgnCase(name, "weston"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_WESTON);
- else if(strcasecmp(name, "wayfire") == 0)
+ else if(ffStrEqualsIgnCase(name, "wayfire"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_WAYFIRE);
- else if(strcasecmp(name, "openbox") == 0)
+ else if(ffStrEqualsIgnCase(name, "openbox"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_OPENBOX);
- else if(strcasecmp(name, "xfwm4") == 0)
+ else if(ffStrEqualsIgnCase(name, "xfwm4"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_XFWM4);
- else if(strcasecmp(name, "Marco") == 0 ||
- strcasecmp(name, "Metacity (Marco)") == 0)
+ else if(ffStrEqualsIgnCase(name, "Marco") ||
+ ffStrEqualsIgnCase(name, "Metacity (Marco)"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MARCO);
- else if(strcasecmp(name, "xmonad") == 0)
+ else if(ffStrEqualsIgnCase(name, "xmonad"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_XMONAD);
- else if(strcasecmp(name, "WSLg") == 0)
+ else if(ffStrEqualsIgnCase(name, "WSLg"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_WSLG);
- else if(strcasecmp(name, "dwm") == 0)
+ else if(ffStrEqualsIgnCase(name, "dwm"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_DWM);
- else if(strcasecmp(name, "bspwm") == 0)
+ else if(ffStrEqualsIgnCase(name, "bspwm"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_BSPWM);
- else if(strcasecmp(name, "tinywm") == 0)
+ else if(ffStrEqualsIgnCase(name, "tinywm"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_TINYWM);
- else if(strcasecmp(name, "qtile") == 0)
+ else if(ffStrEqualsIgnCase(name, "qtile"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_QTILE);
- else if(strcasecmp(name, "herbstluftwm") == 0)
+ else if(ffStrEqualsIgnCase(name, "herbstluftwm"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_HERBSTLUFTWM);
- else if(strcasecmp(name, "icewm") == 0)
+ else if(ffStrEqualsIgnCase(name, "icewm"))
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_ICEWM);
+ else if(ffStrEqualsIgnCase(name, "dtwm"))
+ ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_DTWM);
}
static void applyNameIfWM(FFDisplayServerResult* result, const char* processName)
@@ -136,10 +146,10 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
return;
else if(
- strcasecmp(name, "KDE") == 0 ||
- strcasecmp(name, "plasma") == 0 ||
- strcasecmp(name, "plasmashell") == 0 ||
- strcasecmp(name, "plasmawayland") == 0
+ ffStrEqualsIgnCase(name, "KDE") ||
+ ffStrEqualsIgnCase(name, "plasma") ||
+ ffStrEqualsIgnCase(name, "plasmashell") ||
+ ffStrEqualsIgnCase(name, "plasmawayland")
) {
ffStrbufSetStatic(&result->deProcessName, "plasmashell");
ffStrbufSetStatic(&result->dePrettyName, FF_DE_PRETTY_PLASMA);
@@ -147,10 +157,10 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
}
else if(
- strcasecmp(name, "Gnome") == 0 ||
- strcasecmp(name, "ubuntu:GNOME") == 0 ||
- strcasecmp(name, "ubuntu") == 0 ||
- strcasecmp(name, "gnome-shell") == 0
+ ffStrEqualsIgnCase(name, "Gnome") ||
+ ffStrEqualsIgnCase(name, "ubuntu:GNOME") ||
+ ffStrEqualsIgnCase(name, "ubuntu") ||
+ ffStrEqualsIgnCase(name, "gnome-shell")
) {
ffStrbufSetStatic(&result->deProcessName, "gnome-shell");
const char* sessionMode = getenv("GNOME_SHELL_SESSION_MODE");
@@ -161,37 +171,37 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
}
else if(
- strcasecmp(name, "X-Cinnamon") == 0 ||
- strcasecmp(name, "Cinnamon") == 0
+ ffStrEqualsIgnCase(name, "X-Cinnamon") ||
+ ffStrEqualsIgnCase(name, "Cinnamon")
) {
ffStrbufSetS(&result->deProcessName, "cinnamon");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_CINNAMON);
}
else if(
- strcasecmp(name, "XFCE") == 0 ||
- strcasecmp(name, "X-XFCE") == 0 ||
- strcasecmp(name, "XFCE4") == 0 ||
- strcasecmp(name, "X-XFCE4") == 0 ||
- strcasecmp(name, "xfce4-session") == 0
+ ffStrEqualsIgnCase(name, "XFCE") ||
+ ffStrEqualsIgnCase(name, "X-XFCE") ||
+ ffStrEqualsIgnCase(name, "XFCE4") ||
+ ffStrEqualsIgnCase(name, "X-XFCE4") ||
+ ffStrEqualsIgnCase(name, "xfce4-session")
) {
ffStrbufSetS(&result->deProcessName, "xfce4-session");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_XFCE4);
}
else if(
- strcasecmp(name, "MATE") == 0 ||
- strcasecmp(name, "X-MATE") == 0 ||
- strcasecmp(name, "mate-session") == 0
+ ffStrEqualsIgnCase(name, "MATE") ||
+ ffStrEqualsIgnCase(name, "X-MATE") ||
+ ffStrEqualsIgnCase(name, "mate-session")
) {
ffStrbufSetS(&result->deProcessName, "mate-session");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_MATE);
}
else if(
- strcasecmp(name, "LXQt") == 0 ||
- strcasecmp(name, "X-LXQT") == 0 ||
- strcasecmp(name, "lxqt-session") == 0
+ ffStrEqualsIgnCase(name, "LXQt") ||
+ ffStrEqualsIgnCase(name, "X-LXQT") ||
+ ffStrEqualsIgnCase(name, "lxqt-session")
) {
ffStrbufSetS(&result->deProcessName, "lxqt-session");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_LXQT);
@@ -201,14 +211,21 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
}
else if(
- strcasecmp(name, "Budgie") == 0 ||
- strcasecmp(name, "X-Budgie") == 0 ||
- strcasecmp(name, "budgie-desktop") == 0 ||
- strcasecmp(name, "Budgie:GNOME") == 0
+ ffStrEqualsIgnCase(name, "Budgie") ||
+ ffStrEqualsIgnCase(name, "X-Budgie") ||
+ ffStrEqualsIgnCase(name, "budgie-desktop") ||
+ ffStrEqualsIgnCase(name, "Budgie:GNOME")
) {
ffStrbufSetS(&result->deProcessName, "budgie-desktop");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_BUDGIE);
}
+
+ else if(
+ ffStrEqualsIgnCase(name, "dtsession")
+ ) {
+ ffStrbufSetS(&result->deProcessName, "dtsession");
+ ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_CDE);
+ }
}
static void getWMProtocolNameFromEnv(FFDisplayServerResult* result)
@@ -219,9 +236,9 @@ static void getWMProtocolNameFromEnv(FFDisplayServerResult* result)
const char* env = getenv("XDG_SESSION_TYPE");
if(ffStrSet(env))
{
- if(strcasecmp(env, "x11") == 0)
+ if(ffStrEqualsIgnCase(env, "x11"))
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_X11);
- else if(strcasecmp(env, "tty") == 0)
+ else if(ffStrEqualsIgnCase(env, "tty"))
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_TTY);
else
ffStrbufSetS(&result->wmProtocolName, env);
@@ -237,30 +254,56 @@ static void getWMProtocolNameFromEnv(FFDisplayServerResult* result)
}
env = getenv("TERM");
- if(ffStrSet(env) && strcasecmp(env, "linux") == 0)
+ if(ffStrSet(env) && ffStrEqualsIgnCase(env, "linux"))
{
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_TTY);
return;
}
}
-static void getFromProcDir(FFDisplayServerResult* result)
+static const char* getFromProcesses(FFDisplayServerResult* result)
{
- DIR* proc = opendir("/proc");
- if(proc == NULL)
- return;
+ uint32_t userId = getuid();
+
+#ifdef __FreeBSD__
+ int request[] = {CTL_KERN, KERN_PROC, KERN_PROC_UID, (int) userId};
+ size_t length = 0;
+
+ if(sysctl(request, sizeof(request) / sizeof(*request), NULL, &length, NULL, 0) != 0)
+ return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_UID}, NULL) failed";
+
+ FF_AUTO_FREE struct kinfo_proc* procs = (struct kinfo_proc*) malloc(length);
+ if(sysctl(request, sizeof(request) / sizeof(*request), procs, &length, NULL, 0) != 0)
+ return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_UID}, procs) failed";
+
+ length /= sizeof(*procs);
+
+ for (struct kinfo_proc* proc = procs; proc < procs + length; ++proc)
+ {
+ if(result->dePrettyName.length == 0)
+ applyPrettyNameIfDE(result, proc->ki_comm);
+
+ if(result->wmPrettyName.length == 0)
+ applyNameIfWM(result, proc->ki_comm);
+
+ if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0)
+ break;
+ }
+#else
+ FF_AUTO_CLOSE_DIR DIR* procdir = opendir("/proc");
+ if(procdir == NULL)
+ return "opendir(\"/proc\") failed";
FF_STRBUF_AUTO_DESTROY procPath = ffStrbufCreateA(64);
ffStrbufAppendS(&procPath, "/proc/");
uint32_t procPathLength = procPath.length;
- FF_STRBUF_AUTO_DESTROY userID = ffStrbufCreateF("%i", getuid());
FF_STRBUF_AUTO_DESTROY loginuid = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY processName = ffStrbufCreateA(256); //Some processes have large command lines (looking at you chrome)
struct dirent* dirent;
- while((dirent = readdir(proc)) != NULL)
+ while((dirent = readdir(procdir)) != NULL)
{
//Match only folders starting with a number (the pid folders)
if(dirent->d_type != DT_DIR || !isdigit(dirent->d_name[0]))
@@ -272,7 +315,7 @@ static void getFromProcDir(FFDisplayServerResult* result)
//Don't check for processes not owend by the current user.
ffStrbufAppendS(&procPath, "/loginuid");
ffReadFileBuffer(procPath.chars, &loginuid);
- if(ffStrbufComp(&userID, &loginuid) != 0)
+ if(ffStrbufToUInt(&loginuid, (uint64_t) -1) != userId)
{
ffStrbufSubstrBefore(&procPath, procPathLength);
continue;
@@ -297,8 +340,9 @@ static void getFromProcDir(FFDisplayServerResult* result)
if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0)
break;
}
+#endif
- closedir(proc);
+ return NULL;
}
void ffdsDetectWMDE(FFDisplayServerResult* result)
@@ -338,7 +382,7 @@ void ffdsDetectWMDE(FFDisplayServerResult* result)
return;
//Get missing WM / DE from processes.
- getFromProcDir(result);
+ getFromProcesses(result);
//Return if both wm and de are set, or if env doesn't contain anything
if(
diff --git a/src/detection/gpu/gpu_apple.c b/src/detection/gpu/gpu_apple.c
index 616a62cc9..bb734596d 100644
--- a/src/detection/gpu/gpu_apple.c
+++ b/src/detection/gpu/gpu_apple.c
@@ -9,20 +9,26 @@
static double detectGpuTemp(const FFstrbuf* gpuName)
{
double result = 0;
- const char* error;
+ const char* error = NULL;
- if(ffStrbufStartsWithS(gpuName, "Apple M1"))
- error = ffDetectCoreTemps(FF_TEMP_GPU_M1X, &result);
- else if(ffStrbufStartsWithS(gpuName, "Apple M2"))
- error = ffDetectCoreTemps(FF_TEMP_GPU_M2X, &result);
- else if(ffStrbufStartsWithS(gpuName, "Intel"))
+ if (ffStrbufStartsWithS(gpuName, "Apple M"))
+ {
+ switch (strtol(gpuName->chars + strlen("Apple M"), NULL, 10))
+ {
+ case 1: error = ffDetectCoreTemps(FF_TEMP_GPU_M1X, &result); break;
+ case 2: error = ffDetectCoreTemps(FF_TEMP_GPU_M2X, &result); break;
+ case 3: error = ffDetectCoreTemps(FF_TEMP_GPU_M3X, &result); break;
+ default: error = "Unsupported Apple Silicon GPU";
+ }
+ }
+ else if (ffStrbufStartsWithS(gpuName, "Intel"))
error = ffDetectCoreTemps(FF_TEMP_GPU_INTEL, &result);
- else if(ffStrbufStartsWithS(gpuName, "Radeon") || ffStrbufStartsWithS(gpuName, "AMD"))
+ else if (ffStrbufStartsWithS(gpuName, "Radeon") || ffStrbufStartsWithS(gpuName, "AMD"))
error = ffDetectCoreTemps(FF_TEMP_GPU_AMD, &result);
else
error = ffDetectCoreTemps(FF_TEMP_GPU_UNKNOWN, &result);
- if(error)
+ if (error)
return FF_GPU_TEMP_UNSET;
return result;
diff --git a/src/detection/memory/memory_apple.c b/src/detection/memory/memory_apple.c
index b3a50a1eb..19e67f1a4 100644
--- a/src/detection/memory/memory_apple.c
+++ b/src/detection/memory/memory_apple.c
@@ -16,7 +16,16 @@ const char* ffDetectMemory(FFMemoryResult* ram)
if(host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t) (&vmstat), &count) != KERN_SUCCESS)
return "Failed to read host_statistics64";
- ram->bytesUsed = ((uint64_t) vmstat.active_count + vmstat.wire_count) * instance.state.platform.pageSize;
+ // https://github.com/exelban/stats/blob/master/Modules/RAM/readers.swift#L56
+ ram->bytesUsed = ((uint64_t)
+ + vmstat.active_count
+ + vmstat.inactive_count
+ + vmstat.speculative_count
+ + vmstat.wire_count
+ + vmstat.compressor_page_count
+ - vmstat.purgeable_count
+ - vmstat.external_page_count
+ ) * instance.state.platform.pageSize;
return NULL;
}
diff --git a/src/detection/packages/packages_bsd.c b/src/detection/packages/packages_bsd.c
new file mode 100644
index 000000000..cb9091457
--- /dev/null
+++ b/src/detection/packages/packages_bsd.c
@@ -0,0 +1,8 @@
+#include "packages.h"
+
+#include "common/settings.h"
+
+void ffDetectPackagesImpl(FFPackagesResult* result, FF_MAYBE_UNUSED FFPackagesOptions* options)
+{
+ result->pkg = (uint32_t) ffSettingsGetSQLite3Int(FASTFETCH_TARGET_DIR_ROOT "/var/db/pkg/local.sqlite", "SELECT count(*) FROM packages");
+}
diff --git a/src/detection/packages/packages_linux.c b/src/detection/packages/packages_linux.c
index ef5d1162d..0b608497c 100644
--- a/src/detection/packages/packages_linux.c
+++ b/src/detection/packages/packages_linux.c
@@ -11,7 +11,7 @@
static uint32_t getNumElementsImpl(const char* dirname, unsigned char type)
{
- DIR* dirp = opendir(dirname);
+ FF_AUTO_CLOSE_DIR DIR* dirp = opendir(dirname);
if(dirp == NULL)
return 0;
@@ -26,8 +26,6 @@ static uint32_t getNumElementsImpl(const char* dirname, unsigned char type)
if(type == DT_DIR && num_elements >= 2)
num_elements -= 2; // accounting for . and ..
- closedir(dirp);
-
return num_elements;
}
@@ -265,9 +263,8 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts)
packageCounts->nixDefault += getNixPackages(baseDir, "/nix/var/nix/profiles/default");
packageCounts->nixSystem += getNixPackages(baseDir, "/run/current-system");
packageCounts->pacman += getNumElements(baseDir, "/var/lib/pacman/local", DT_DIR);
- packageCounts->pkg += getSQLite3Int(baseDir, "/var/db/pkg/local.sqlite", "SELECT count(id) FROM packages");
packageCounts->pkgtool += getNumElements(baseDir, "/var/log/packages", DT_REG);
- packageCounts->rpm += getSQLite3Int(baseDir, "/var/lib/rpm/rpmdb.sqlite", "SELECT count(blob) FROM Packages");
+ packageCounts->rpm += getSQLite3Int(baseDir, "/var/lib/rpm/rpmdb.sqlite", "SELECT count(*) FROM Packages");
packageCounts->snap += getSnap(baseDir);
packageCounts->xbps += getXBPS(baseDir, "/var/db/xbps");
packageCounts->brewCask += getNumElements(baseDir, "/home/linuxbrew/.linuxbrew/Caskroom", DT_DIR);
@@ -281,7 +278,7 @@ static void getPackageCountsRegular(FFstrbuf* baseDir, FFPackagesResult* package
getPackageCounts(baseDir, packageCounts);
uint32_t baseDirLength = baseDir->length;
- ffStrbufAppendS(baseDir, FASTFETCH_TARGET_DIR_ETC"/pacman-mirrors.conf");
+ ffStrbufAppendS(baseDir, FASTFETCH_TARGET_DIR_ETC "/pacman-mirrors.conf");
if(ffParsePropFile(baseDir->chars, "Branch =", &packageCounts->pacmanBranch) && packageCounts->pacmanBranch.length == 0)
ffStrbufAppendS(&packageCounts->pacmanBranch, "stable");
ffStrbufSubstrBefore(baseDir, baseDirLength);
diff --git a/src/detection/physicaldisk/physicaldisk.h b/src/detection/physicaldisk/physicaldisk.h
new file mode 100644
index 000000000..eea569d2a
--- /dev/null
+++ b/src/detection/physicaldisk/physicaldisk.h
@@ -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);
diff --git a/src/detection/physicaldisk/physicaldisk_apple.c b/src/detection/physicaldisk/physicaldisk_apple.c
new file mode 100644
index 000000000..bd186fab1
--- /dev/null
+++ b/src/detection/physicaldisk/physicaldisk_apple.c
@@ -0,0 +1,93 @@
+#include "physicaldisk.h"
+#include "util/apple/cf_helpers.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+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;
+}
diff --git a/src/detection/physicaldisk/physicaldisk_bsd.c b/src/detection/physicaldisk/physicaldisk_bsd.c
new file mode 100644
index 000000000..c23b08aea
--- /dev/null
+++ b/src/detection/physicaldisk/physicaldisk_bsd.c
@@ -0,0 +1,70 @@
+#include "physicaldisk.h"
+#include "util/stringUtils.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+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;
+}
diff --git a/src/detection/physicaldisk/physicaldisk_linux.c b/src/detection/physicaldisk/physicaldisk_linux.c
new file mode 100644
index 000000000..b94667731
--- /dev/null
+++ b/src/detection/physicaldisk/physicaldisk_linux.c
@@ -0,0 +1,117 @@
+#include "physicaldisk.h"
+#include "common/io/io.h"
+#include "common/properties.h"
+#include "util/stringUtils.h"
+
+#include
+#include
+
+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];
+ ssize_t pathLength = readlink(pathSysBlock, pathSysDeviceReal, sizeof(pathSysDeviceReal) - 1);
+ if (pathLength < 0)
+ continue;
+ pathSysDeviceReal[pathLength] = '\0';
+
+ 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;
+}
diff --git a/src/detection/physicaldisk/physicaldisk_windows.c b/src/detection/physicaldisk/physicaldisk_windows.c
new file mode 100644
index 000000000..1ad1a5779
--- /dev/null
+++ b/src/detection/physicaldisk/physicaldisk_windows.c
@@ -0,0 +1,131 @@
+#include "physicaldisk.h"
+#include "common/io/io.h"
+#include "util/windows/unicode.h"
+
+#include
+#include
+
+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;
+}
diff --git a/src/detection/temps/temps_apple.c b/src/detection/temps/temps_apple.c
index 7054a3ed3..b274c49e0 100644
--- a/src/detection/temps/temps_apple.c
+++ b/src/detection/temps/temps_apple.c
@@ -333,6 +333,25 @@ const char *ffDetectCoreTemps(enum FFTempType type, double *result)
count += detectTemp(conn, "Tp09", result); // CPU core 8
break;
+ case FF_TEMP_CPU_M3X:
+ count += detectTemp(conn, "Te05", result); // CPU efficiency core 1
+ count += detectTemp(conn, "Te0L", result); // CPU efficiency core 2
+ count += detectTemp(conn, "Te0P", result); // CPU efficiency core 3
+ count += detectTemp(conn, "Te0S", result); // CPU efficiency core 4
+ count += detectTemp(conn, "Tf04", result); // CPU performance core 1
+ count += detectTemp(conn, "Tf09", result); // CPU performance core 2
+ count += detectTemp(conn, "Tf0A", result); // CPU performance core 3
+ count += detectTemp(conn, "Tf0B", result); // CPU performance core 4
+ count += detectTemp(conn, "Tf0D", result); // CPU performance core 5
+ count += detectTemp(conn, "Tf0E", result); // CPU performance core 6
+ count += detectTemp(conn, "Tf44", result); // CPU performance core 7
+ count += detectTemp(conn, "Tf49", result); // CPU performance core 8
+ count += detectTemp(conn, "Tf4A", result); // CPU performance core 9
+ count += detectTemp(conn, "Tf4B", result); // CPU performance core 10
+ count += detectTemp(conn, "Tf4D", result); // CPU performance core 11
+ count += detectTemp(conn, "Tf4E", result); // CPU performance core 12
+ break;
+
case FF_TEMP_GPU_INTEL:
count += detectTemp(conn, "TCGC", result); // GPU Intel Graphics
goto gpu_unknown;
@@ -359,12 +378,27 @@ const char *ffDetectCoreTemps(enum FFTempType type, double *result)
count += detectTemp(conn, "Tg0j", result); // GPU 2
break;
+ case FF_TEMP_GPU_M3X:
+ count += detectTemp(conn, "Tf14", result); // GPU 1
+ count += detectTemp(conn, "Tf18", result); // GPU 2
+ count += detectTemp(conn, "Tf19", result); // GPU 3
+ count += detectTemp(conn, "Tf1A", result); // GPU 4
+ count += detectTemp(conn, "Tf24", result); // GPU 5
+ count += detectTemp(conn, "Tf28", result); // GPU 6
+ count += detectTemp(conn, "Tf29", result); // GPU 7
+ count += detectTemp(conn, "Tf2A", result); // GPU 8
+ break;
+
case FF_TEMP_BATTERY:
count += detectTemp(conn, "TB1T", result); // Battery
+ count += detectTemp(conn, "TB2T", result); // Battery
break;
case FF_TEMP_MEMORY:
- count += detectTemp(conn, "Tm02", result); // Memory
+ count += detectTemp(conn, "Tm02", result); // Memory 1
+ count += detectTemp(conn, "Tm06", result); // Memory 2
+ count += detectTemp(conn, "Tm08", result); // Memory 3
+ count += detectTemp(conn, "Tm09", result); // Memory 4
break;
}
diff --git a/src/detection/temps/temps_apple.h b/src/detection/temps/temps_apple.h
index 7d340ba22..ccf914311 100644
--- a/src/detection/temps/temps_apple.h
+++ b/src/detection/temps/temps_apple.h
@@ -15,12 +15,14 @@ enum FFTempType
FF_TEMP_CPU_X64,
FF_TEMP_CPU_M1X,
FF_TEMP_CPU_M2X,
+ FF_TEMP_CPU_M3X,
FF_TEMP_GPU_INTEL,
FF_TEMP_GPU_AMD,
FF_TEMP_GPU_UNKNOWN,
FF_TEMP_GPU_M1X,
FF_TEMP_GPU_M2X,
+ FF_TEMP_GPU_M3X,
FF_TEMP_BATTERY,
diff --git a/src/detection/terminalshell/terminalshell.c b/src/detection/terminalshell/terminalshell.c
index d54e1cc61..68b963e07 100644
--- a/src/detection/terminalshell/terminalshell.c
+++ b/src/detection/terminalshell/terminalshell.c
@@ -4,6 +4,8 @@
#include "common/properties.h"
#include "util/stringUtils.h"
+#include
+
#ifdef _WIN32
#include "util/mallocHelper.h"
@@ -162,6 +164,28 @@ static bool getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version)
NULL
}) == NULL;
}
+#else
+static bool getShellVersionGeneric(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
+{
+ FF_STRBUF_AUTO_DESTROY command = ffStrbufCreate();
+ ffStrbufAppendS(&command, "printf \"%s\" \"$");
+ ffStrbufAppendTransformS(&command, exeName, toupper);
+ ffStrbufAppendS(&command, "_VERSION\"");
+
+ if (ffProcessAppendStdOut(version, (char* const[]) {
+ "env",
+ "-i",
+ exe->chars,
+ "-c",
+ command.chars,
+ NULL
+ }) != NULL)
+ return false;
+
+ ffStrbufSubstrBeforeFirstC(version, '(');
+ ffStrbufRemoveStrings(version, 2, (const char*[]) { "-release", "release" });
+ return true;
+}
#endif
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
@@ -198,7 +222,7 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
return getFileVersion(exe->chars, version);
#else
- return false;
+ return getShellVersionGeneric(exe, exeName, version);
#endif
}
diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c
index 7fa216f16..3fde133c4 100644
--- a/src/detection/terminalshell/terminalshell_linux.c
+++ b/src/detection/terminalshell/terminalshell_linux.c
@@ -5,7 +5,6 @@
#include "common/thread.h"
#include "util/stringUtils.h"
-#include
#include
#include
#include
@@ -68,8 +67,6 @@ static void getProcessInformation(pid_t pid, FFstrbuf* processName, FFstrbuf* ex
static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid)
{
- const char* error = NULL;
-
#ifdef __linux__
char statFilePath[64];
@@ -86,20 +83,18 @@ static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid)
!ffStrSet(name) ||
*ppid == 0
)
- error = "sscanf(stat) failed";
+ return "sscanf(stat) failed";
#elif defined(__APPLE__)
struct proc_bsdshortinfo proc;
if(proc_pidinfo(pid, PROC_PIDT_SHORTBSDINFO, 0, &proc, PROC_PIDT_SHORTBSDINFO_SIZE) <= 0)
- error = "proc_pidinfo(pid) failed";
- else
- {
- *ppid = (pid_t)proc.pbsi_ppid;
- strncpy(name, proc.pbsi_comm, 16); //trancated to 16 chars
- }
+ return "proc_pidinfo(pid) failed";
- #else
+ *ppid = (pid_t)proc.pbsi_ppid;
+ strncpy(name, proc.pbsi_comm, 16); //trancated to 16 chars
+
+ #elif defined(__FreeBSD__)
struct kinfo_proc proc;
size_t size = sizeof(proc);
@@ -108,16 +103,18 @@ static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid)
&proc, &size,
NULL, 0
))
- error = "sysctl(KERN_PROC_PID) failed";
- else
- {
- *ppid = (pid_t)proc.ki_ppid;
- strncpy(name, proc.ki_comm, COMMLEN);
- }
+ return "sysctl(KERN_PROC_PID) failed";
+
+ *ppid = (pid_t)proc.ki_ppid;
+ strncpy(name, proc.ki_comm, COMMLEN);
+
+ #else
+
+ return "Unsupported platform";
#endif
- return error;
+ return NULL;
}
static void getTerminalShell(FFTerminalShellResult* result, pid_t pid)
@@ -286,34 +283,8 @@ static void getUserShellFromEnv(FFTerminalShellResult* result)
}
}
-static void getShellVersionGeneric(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
-{
- FF_STRBUF_AUTO_DESTROY command = ffStrbufCreate();
- ffStrbufAppendS(&command, "printf \"%s\" \"$");
- ffStrbufAppendTransformS(&command, exeName, toupper);
- ffStrbufAppendS(&command, "_VERSION\"");
-
- ffProcessAppendStdOut(version, (char* const[]) {
- "env",
- "-i",
- exe->chars,
- "-c",
- command.chars,
- NULL
- });
- ffStrbufSubstrBeforeFirstC(version, '(');
- ffStrbufRemoveStrings(version, 2, (const char*[]) { "-release", "release" });
-}
-
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
-static void getShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
-{
- ffStrbufClear(version);
- if(!fftsGetShellVersion(exe, exeName, version))
- getShellVersionGeneric(exe, exeName, version);
-}
-
bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* version);
const FFTerminalShellResult* ffDetectTerminalShell()
@@ -350,7 +321,8 @@ const FFTerminalShellResult* ffDetectTerminalShell()
getTerminalFromEnv(&result);
getUserShellFromEnv(&result);
- getShellVersion(&result.shellExe, result.shellExeName, &result.shellVersion);
+ ffStrbufClear(&result.shellVersion);
+ fftsGetShellVersion(&result.shellExe, result.shellExeName, &result.shellVersion);
if(ffStrbufEqualS(&result.shellProcessName, "pwsh"))
ffStrbufInitStatic(&result.shellPrettyName, "PowerShell");
diff --git a/src/detection/wifi/wifi_windows.c b/src/detection/wifi/wifi_windows.c
index 3b7ac5a1c..18638c046 100644
--- a/src/detection/wifi/wifi_windows.c
+++ b/src/detection/wifi/wifi_windows.c
@@ -18,22 +18,22 @@ static void convertIfStateToString(WLAN_INTERFACE_STATE state, FFstrbuf* result)
ffStrbufAppendS(result, "Connected");
break;
case wlan_interface_state_ad_hoc_network_formed:
- ffStrbufAppendS(result, "First node in a ad hoc network");
+ ffStrbufAppendS(result, "Ad hoc network formed");
break;
case wlan_interface_state_disconnecting:
ffStrbufAppendS(result, "Disconnecting");
break;
case wlan_interface_state_disconnected:
- ffStrbufAppendS(result, "Not connected");
+ ffStrbufAppendS(result, "Disconnected");
break;
case wlan_interface_state_associating:
- ffStrbufAppendS(result, "Attempting to associate with a network");
+ ffStrbufAppendS(result, "Associating");
break;
case wlan_interface_state_discovering:
- ffStrbufAppendS(result, "Auto configuration is discovering settings for the network");
+ ffStrbufAppendS(result, "Discovering");
break;
case wlan_interface_state_authenticating:
- ffStrbufAppendS(result, "In process of authenticating");
+ ffStrbufAppendS(result, "Authenticating");
break;
default:
ffStrbufAppendS(result, "Unknown");
@@ -133,16 +133,16 @@ const char* ffDetectWifi(FFlist* result)
case dot11_phy_type_ht:
ffStrbufAppendS(&item->conn.protocol, "802.11n (Wi-Fi 4)");
break;
- case 8 /*dot11_phy_type_vht*/:
+ case dot11_phy_type_vht:
ffStrbufAppendS(&item->conn.protocol, "802.11ac (Wi-Fi 5)");
break;
- case 9 /*dot11_phy_type_dmg*/:
+ case dot11_phy_type_dmg:
ffStrbufAppendS(&item->conn.protocol, "802.11ad (WiGig)");
break;
- case 10 /*dot11_phy_type_he*/:
+ case dot11_phy_type_he:
ffStrbufAppendS(&item->conn.protocol, "802.11ax (Wi-Fi 6)");
break;
- case 11 /*dot11_phy_type_eht*/:
+ case dot11_phy_type_eht:
ffStrbufAppendS(&item->conn.protocol, "802.11be (Wi-Fi 7)");
break;
default:
@@ -179,10 +179,10 @@ const char* ffDetectWifi(FFlist* result)
case DOT11_AUTH_ALGO_RSNA_PSK:
ffStrbufAppendS(&item->conn.security, "WPA2-PSK");
break;
- case 8 /* DOT11_AUTH_ALGO_WPA3 */:
+ case DOT11_AUTH_ALGO_WPA3:
ffStrbufAppendS(&item->conn.security, "WPA3");
break;
- case 9 /* DOT11_AUTH_ALGO_WPA3_SAE */:
+ case DOT11_AUTH_ALGO_WPA3_SAE:
ffStrbufAppendS(&item->conn.security, "WPA3-SAE");
break;
case 10 /* DOT11_AUTH_ALGO_OWE */:
diff --git a/src/logo/ascii/adelie.txt b/src/logo/ascii/adelie.txt
index df46e57a0..417b5eb04 100644
--- a/src/logo/ascii/adelie.txt
+++ b/src/logo/ascii/adelie.txt
@@ -1,16 +1,16 @@
${c3} ,-^-___
-${c3} /\\\\\\///
-${c2}refined.${c1} /\\\\\\\\//
-${c2}reliable.${c1} /\\\\\\///
-${c2}ready.${c1} /\\\\/////\\
- __///\\\\\\\\/////\\
-${c3} _//////\\\\\\\\\\\\\\////
-${c1} ///////${c3}\\\\\\\\\\\\\\\\\\\\//
- //////${c1}\\\\\\\\\\/
- /////\\\\\\\\\\/
- /////${c3}\\\\\\\\/
- /\\\\///\\\\\\/
- /\\\\\\/${c1}\\\/
- /\\\\\\\\//
+${c3} /\\\///
+${c2}refined.${c1} /\\\\//
+${c2}reliable.${c1} /\\\///
+${c2}ready.${c1} /\\/////\
+ __///\\\\/////\
+${c3} _//////\\\\\\\////
+${c1} ///////${c3}\\\\\\\\\\//
+ //////${c1}\\\\\/
+ /////\\\\\/
+ /////${c3}\\\\/
+ /\\///\\\/
+ /\\\/${c1}\\/
+ /\\\\//
//////
- /// ${c3}\\\\\\\\\\
+ /// ${c3}\\\\\
diff --git a/src/logo/ascii/eshanizedos.txt b/src/logo/ascii/eshanizedos.txt
new file mode 100644
index 000000000..26ec7422a
--- /dev/null
+++ b/src/logo/ascii/eshanizedos.txt
@@ -0,0 +1,27 @@
+ .:-==++++++++++++++++++++++-.
+ .:=+##############################+
+ .=*###################################-
+ :+######################################:
+ :+######################################*-
+ .+#############*+--:::::::::::::::::::::.
+ :*##########*=:
+ -###########=
+ :##########+.
+ *#########=
+ =*********+ .::::::::::::::::.
+ **********. -*###################+:
+:********** =#######################=
+-*********+ +************************
+:*********+ :***********************:
+.********** .=******************+-
+ +*********-
+ .**********.
+ =**********:
+ +**********=.
+ =***********=:
+ -*************+-.
+ :+****************+++++++++++++++++++++==:
+ :+**************************************+.
+ -+************************************-
+ .-+*********************************.
+ :-==+*************************=.
diff --git a/src/logo/builtin.c b/src/logo/builtin.c
index 9e80422f3..62d141fd1 100644
--- a/src/logo/builtin.c
+++ b/src/logo/builtin.c
@@ -1348,6 +1348,15 @@ static const FFlogo E[] = {
.colorKeys = FF_COLOR_FG_WHITE,
.colorTitle = FF_COLOR_FG_WHITE,
},
+ // EshanizedOS
+ {
+ .names = {"EshanizedOS"},
+ .lines = FASTFETCH_DATATEXT_LOGO_ESHANIZEDOS,
+ .colors = {
+ FF_COLOR_FG_RED,
+ FF_COLOR_FG_WHITE,
+ },
+ },
// EuroLinux
{
.names = {"EuroLinux"},
diff --git a/src/logo/image/im6.c b/src/logo/image/im6.c
index a8820f53b..9694a797b 100644
--- a/src/logo/image/im6.c
+++ b/src/logo/image/im6.c
@@ -17,10 +17,13 @@ FFLogoImageResult ffLogoPrintImageIM6(FFLogoRequestData* requestData)
FF_LIBRARY_LOAD(imageMagick, &instance.config.library.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-6.Q16HDRI" FF_LIBRARY_EXTENSION, 8, "libMagickCore-6.Q16" FF_LIBRARY_EXTENSION, 8)
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
- return ffLogoPrintImageImpl(requestData, &(FFIMData) {
+ FFLogoImageResult result = ffLogoPrintImageImpl(requestData, &(FFIMData) {
.resizeFunc = logoResize,
.library = imageMagick,
});
+
+ imageMagick = NULL; // leak imageMagick to prevent fastfetch from crashing #552
+ return result;
}
#endif
diff --git a/src/logo/image/im7.c b/src/logo/image/im7.c
index 03229aacb..b0eeed2dc 100644
--- a/src/logo/image/im7.c
+++ b/src/logo/image/im7.c
@@ -21,10 +21,13 @@ FFLogoImageResult ffLogoPrintImageIM7(FFLogoRequestData* requestData)
)
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
- return ffLogoPrintImageImpl(requestData, &(FFIMData) {
+ FFLogoImageResult result = ffLogoPrintImageImpl(requestData, &(FFIMData) {
.resizeFunc = logoResize,
.library = imageMagick,
});
+
+ imageMagick = NULL; // leak imageMagick to prevent fastfetch from crashing #552
+ return result;
}
#endif
diff --git a/src/modules/diskio/diskio.c b/src/modules/diskio/diskio.c
index ef15cef11..d92c21609 100644
--- a/src/modules/diskio/diskio.c
+++ b/src/modules/diskio/diskio.c
@@ -6,7 +6,7 @@
#include "util/stringUtils.h"
#define FF_DISKIO_DISPLAY_NAME "Disk IO"
-#define FF_DISKIO_NUM_FORMAT_ARGS 11
+#define FF_DISKIO_NUM_FORMAT_ARGS 8
static int sortDevices(const FFDiskIOResult* left, const FFDiskIOResult* right)
{
@@ -17,10 +17,7 @@ static void formatKey(const FFDiskIOOptions* options, FFDiskIOResult* dev, uint3
{
if(options->moduleArgs.key.length == 0)
{
- if(!dev->name.length)
- ffStrbufSetF(&dev->name, "unknown %u", (unsigned) index);
-
- ffStrbufSetF(key, FF_DISKIO_DISPLAY_NAME " (%s)", dev->name.chars);
+ ffStrbufSetF(key, FF_DISKIO_DISPLAY_NAME " (%s)", dev->name.length ? dev->name.chars : dev->devPath.chars);
}
else
{
@@ -74,34 +71,15 @@ void ffPrintDiskIO(FFDiskIOOptions* options)
ffParseSize(dev->bytesWritten, &buffer2);
ffStrbufAppendS(&buffer2, "/s");
- const char* physicalType;
- switch(dev->type)
- {
- case FF_DISKIO_PHYSICAL_TYPE_HDD:
- physicalType = "HDD";
- break;
- case FF_DISKIO_PHYSICAL_TYPE_SSD:
- physicalType = "SSD";
- break;
- default:
- physicalType = "Unknown";
- break;
- }
- FF_STRBUF_AUTO_DESTROY sizePretty = ffStrbufCreate();
- ffParseSize(dev->size, &sizePretty);
-
ffPrintFormatString(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_DISKIO_NUM_FORMAT_ARGS, (FFformatarg[]){
{FF_FORMAT_ARG_TYPE_STRBUF, &buffer},
{FF_FORMAT_ARG_TYPE_STRBUF, &buffer2},
{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_UINT64, &dev->bytesRead},
{FF_FORMAT_ARG_TYPE_UINT64, &dev->bytesWritten},
{FF_FORMAT_ARG_TYPE_UINT64, &dev->readCount},
{FF_FORMAT_ARG_TYPE_UINT64, &dev->writeCount},
- {FF_FORMAT_ARG_TYPE_STRBUF, &sizePretty},
});
}
++index;
@@ -110,7 +88,6 @@ void ffPrintDiskIO(FFDiskIOOptions* options)
FF_LIST_FOR_EACH(FFDiskIOResult, dev, result)
{
ffStrbufDestroy(&dev->name);
- ffStrbufDestroy(&dev->interconnect);
ffStrbufDestroy(&dev->devPath);
}
}
@@ -181,33 +158,16 @@ void ffGenerateDiskIOJsonResult(FFDiskIOOptions* options, yyjson_mut_doc* doc, y
{
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, "interconnectType", &dev->interconnect);
yyjson_mut_obj_add_strbuf(doc, obj, "devPath", &dev->devPath);
-
- switch(dev->type)
- {
- case FF_DISKIO_PHYSICAL_TYPE_HDD:
- yyjson_mut_obj_add_str(doc, obj, "physicalType", "HDD");
- break;
- case FF_DISKIO_PHYSICAL_TYPE_SSD:
- yyjson_mut_obj_add_str(doc, obj, "physicalType", "SSD");
- break;
- default:
- yyjson_mut_obj_add_null(doc, obj, "physicalType");
- break;
- }
-
yyjson_mut_obj_add_uint(doc, obj, "bytesRead", dev->bytesRead);
yyjson_mut_obj_add_uint(doc, obj, "bytesWritten", dev->bytesWritten);
yyjson_mut_obj_add_uint(doc, obj, "readCount", dev->readCount);
yyjson_mut_obj_add_uint(doc, obj, "writeCount", dev->writeCount);
- yyjson_mut_obj_add_uint(doc, obj, "size", dev->size);
}
FF_LIST_FOR_EACH(FFDiskIOResult, dev, result)
{
ffStrbufDestroy(&dev->name);
- ffStrbufDestroy(&dev->interconnect);
ffStrbufDestroy(&dev->devPath);
}
}
@@ -218,14 +178,11 @@ void ffPrintDiskIOHelpFormat(void)
"Size of data read per second (formatted)",
"Size of data written per second (formatted)",
"Device name",
- "Device interconnect type",
- "Device physical type (SSD / HDD)",
"Device raw file path",
"Size of data read per second (in bytes)",
"Size of data written per second (in bytes)",
"Number of reads",
"Number of writes",
- "Device size (formatted)",
});
}
diff --git a/src/modules/modules.h b/src/modules/modules.h
index 57632fb7d..35d6523c4 100644
--- a/src/modules/modules.h
+++ b/src/modules/modules.h
@@ -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"
diff --git a/src/modules/options.h b/src/modules/options.h
index 191767c77..aa124c24a 100644
--- a/src/modules/options.h
+++ b/src/modules/options.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"
diff --git a/src/modules/physicaldisk/option.h b/src/modules/physicaldisk/option.h
new file mode 100644
index 000000000..243a98a6a
--- /dev/null
+++ b/src/modules/physicaldisk/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;
diff --git a/src/modules/physicaldisk/physicaldisk.c b/src/modules/physicaldisk/physicaldisk.c
new file mode 100644
index 000000000..05911eb64
--- /dev/null
+++ b/src/modules/physicaldisk/physicaldisk.c
@@ -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);
+}
diff --git a/src/modules/physicaldisk/physicaldisk.h b/src/modules/physicaldisk/physicaldisk.h
new file mode 100644
index 000000000..d8216c140
--- /dev/null
+++ b/src/modules/physicaldisk/physicaldisk.h
@@ -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);
diff --git a/src/options/general.c b/src/options/general.c
index 6357e04b8..7cec888f7 100644
--- a/src/options/general.c
+++ b/src/options/general.c
@@ -30,7 +30,24 @@ const char* ffOptionsParseGeneralJsonConfig(FFOptionsGeneral* options, yyjson_va
else if (ffStrEqualsIgnCase(key, "osFile"))
ffStrbufSetS(&options->osFile, yyjson_get_str(val));
else if (ffStrEqualsIgnCase(key, "dsForceDrm"))
- options->dsForceDrm = yyjson_get_bool(val);
+ {
+ if (yyjson_is_str(val))
+ {
+ int value;
+ const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) {
+ { "sysfs-only", FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY },
+ { "false", FF_DS_FORCE_DRM_TYPE_FALSE },
+ { "true", FF_DS_FORCE_DRM_TYPE_TRUE },
+ {},
+ });
+ if (error)
+ return "Invalid enum value of `dsForceDrm`";
+ else
+ options->dsForceDrm = (FFDsForceDrmType) value;
+ }
+ else
+ options->dsForceDrm = yyjson_get_bool(val) ? FF_DS_FORCE_DRM_TYPE_TRUE : FF_DS_FORCE_DRM_TYPE_FALSE;
+ }
#elif defined(_WIN32)
else if (ffStrEqualsIgnCase(key, "wmiTimeout"))
options->wmiTimeout = (int32_t) yyjson_get_int(val);
@@ -65,7 +82,14 @@ bool ffOptionsParseGeneralCommandLine(FFOptionsGeneral* options, const char* key
else if (ffStrEqualsIgnCase(key, "--os-file"))
ffOptionParseString(key, value, &options->osFile);
else if(ffStrEqualsIgnCase(key, "--ds-force-drm"))
- options->dsForceDrm = ffOptionParseBoolean(value);
+ {
+ if (ffOptionParseBoolean(value))
+ options->dsForceDrm = FF_DS_FORCE_DRM_TYPE_TRUE;
+ else if (ffStrEqualsIgnCase(value, "sysfs-only"))
+ options->dsForceDrm = FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY;
+ else
+ options->dsForceDrm = FF_DS_FORCE_DRM_TYPE_FALSE;
+ }
#elif defined(_WIN32)
else if (ffStrEqualsIgnCase(key, "--wmi-timeout"))
options->wmiTimeout = ffOptionParseInt32(key, value);
@@ -86,7 +110,7 @@ void ffOptionsInitGeneral(FFOptionsGeneral* options)
options->escapeBedrock = true;
ffStrbufInit(&options->playerName);
ffStrbufInit(&options->osFile);
- options->dsForceDrm = false;
+ options->dsForceDrm = FF_DS_FORCE_DRM_TYPE_FALSE;
#elif defined(_WIN32)
options->wmiTimeout = 5000;
#endif
@@ -125,7 +149,20 @@ void ffOptionsGenerateGeneralJsonConfig(FFOptionsGeneral* options, yyjson_mut_do
yyjson_mut_obj_add_strbuf(doc, obj, "osFile", &options->osFile);
if (options->dsForceDrm != defaultOptions.dsForceDrm)
- yyjson_mut_obj_add_bool(doc, obj, "dsForceDrm", options->dsForceDrm);
+ {
+ switch (options->dsForceDrm)
+ {
+ case FF_DS_FORCE_DRM_TYPE_FALSE:
+ yyjson_mut_obj_add_bool(doc, obj, "dsForceDrm", false);
+ break;
+ case FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY:
+ yyjson_mut_obj_add_str(doc, obj, "dsForceDrm", "sysfs-only");
+ break;
+ case FF_DS_FORCE_DRM_TYPE_TRUE:
+ yyjson_mut_obj_add_bool(doc, obj, "dsForceDrm", true);
+ break;
+ }
+ }
#elif defined(_WIN32)
diff --git a/src/options/general.h b/src/options/general.h
index 156991028..98667c2f8 100644
--- a/src/options/general.h
+++ b/src/options/general.h
@@ -2,6 +2,13 @@
#include "util/FFstrbuf.h"
+typedef enum FFDsForceDrmType
+{
+ FF_DS_FORCE_DRM_TYPE_FALSE = 0, // Disable
+ FF_DS_FORCE_DRM_TYPE_TRUE = 1, // Try `libdrm`, then `sysfs` if libdrm failed
+ FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY, // Use `/sys/class/drm` only
+} FFDsForceDrmType;
+
typedef struct FFOptionsGeneral
{
bool multithreading;
@@ -12,7 +19,7 @@ typedef struct FFOptionsGeneral
FFstrbuf playerName;
FFstrbuf osFile;
bool escapeBedrock;
- bool dsForceDrm;
+ FFDsForceDrmType dsForceDrm;
#elif defined(_WIN32)
int32_t wmiTimeout;
#endif
diff --git a/src/options/modules.c b/src/options/modules.c
index 2047abdde..68b835d82 100644
--- a/src/options/modules.c
+++ b/src/options/modules.c
@@ -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);
diff --git a/src/options/modules.h b/src/options/modules.h
index 66b4203c6..e9836e140 100644
--- a/src/options/modules.h
+++ b/src/options/modules.h
@@ -39,6 +39,7 @@ typedef struct FFOptionsModules
FFOpenCLOptions openCL;
FFOpenGLOptions openGL;
FFPackagesOptions packages;
+ FFPhysicalDiskOptions physicalDisk;
FFPlayerOptions player;
FFPowerAdapterOptions powerAdapter;
FFProcessesOptions processes;
diff --git a/src/util/FFstrbuf.c b/src/util/FFstrbuf.c
index 574324f7a..6dfe59589 100644
--- a/src/util/FFstrbuf.c
+++ b/src/util/FFstrbuf.c
@@ -59,9 +59,9 @@ void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free)
uint32_t oldFree = ffStrbufGetFree(strbuf);
if (oldFree >= free && !(strbuf->allocated == 0 && strbuf->length > 0))
return;
-
+
uint32_t newCap = strbuf->allocated + (free - oldFree);
-
+
if(strbuf->allocated == 0)
{
newCap += strbuf->length + 1; // +1 for the NUL
@@ -74,7 +74,7 @@ void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free)
}
else
strbuf->chars = realloc(strbuf->chars, sizeof(*strbuf->chars) * newCap);
-
+
strbuf->allocated = newCap;
}
@@ -99,6 +99,8 @@ void ffStrbufAppendC(FFstrbuf* strbuf, char c)
void ffStrbufAppendNC(FFstrbuf* strbuf, uint32_t num, char c)
{
+ if (num == 0) return;
+
ffStrbufEnsureFree(strbuf, num);
memset(&strbuf->chars[strbuf->length], c, num);
strbuf->length += num;
diff --git a/src/util/platform/FFPlatform_unix.c b/src/util/platform/FFPlatform_unix.c
index 04687f0be..f224c84eb 100644
--- a/src/util/platform/FFPlatform_unix.c
+++ b/src/util/platform/FFPlatform_unix.c
@@ -20,7 +20,7 @@ static void getExePath(FFPlatform* platform)
FFstrbuf* const exePath = &platform->exePath;
ffStrbufEnsureFree(exePath, PATH_MAX);
#ifdef __linux__
- ssize_t exePathLen = readlink("/proc/self/exe", exePath->chars, exePath->allocated);
+ ssize_t exePathLen = readlink("/proc/self/exe", exePath->chars, exePath->allocated - 1);
#elif defined(__APPLE__)
int exePathLen = proc_pidpath((int) getpid(), exePath->chars, exePath->allocated);
#elif defined(__FreeBSD__)
diff --git a/src/util/smbiosHelper.c b/src/util/smbiosHelper.c
index 1033ec880..88249f6d8 100644
--- a/src/util/smbiosHelper.c
+++ b/src/util/smbiosHelper.c
@@ -18,6 +18,8 @@ bool ffIsSmbiosValueSet(FFstrbuf* value)
!ffStrbufIgnCaseEqualS(value, "Undefined") &&
!ffStrbufIgnCaseEqualS(value, "Not Specified") &&
!ffStrbufIgnCaseEqualS(value, "Not Applicable") &&
+ !ffStrbufIgnCaseEqualS(value, "Not Defined") &&
+ !ffStrbufIgnCaseEqualS(value, "Not Available") &&
!ffStrbufIgnCaseEqualS(value, "INVALID") &&
!ffStrbufIgnCaseEqualS(value, "Type1ProductConfigId") &&
!ffStrbufIgnCaseEqualS(value, "All Series") &&