diff options
| author | sumuel <samuel@yakubos.org> | 2026-08-17 20:44:55 +0000 |
|---|---|---|
| committer | sumuel <samuel@yakubos.org> | 2026-08-17 20:44:55 +0000 |
| commit | 76424950e373d3b04ac3dd13019151bfba3e8423 (patch) | |
| tree | 4c3cfdbda039e592b9186be3e28f8d7cfd439e8a /src/detection/diskio | |
Add the files
Diffstat (limited to 'src/detection/diskio')
| -rw-r--r-- | src/detection/diskio/diskio.c | 88 | ||||
| -rw-r--r-- | src/detection/diskio/diskio.h | 15 | ||||
| -rw-r--r-- | src/detection/diskio/diskio_apple.c | 57 | ||||
| -rw-r--r-- | src/detection/diskio/diskio_bsd.c | 120 | ||||
| -rw-r--r-- | src/detection/diskio/diskio_linux.c | 99 | ||||
| -rw-r--r-- | src/detection/diskio/diskio_nbsd.c | 50 | ||||
| -rw-r--r-- | src/detection/diskio/diskio_nosupport.c | 5 | ||||
| -rw-r--r-- | src/detection/diskio/diskio_obsd.c | 39 | ||||
| -rw-r--r-- | src/detection/diskio/diskio_sunos.c | 42 | ||||
| -rw-r--r-- | src/detection/diskio/diskio_windows.c | 101 |
10 files changed, 616 insertions, 0 deletions
diff --git a/src/detection/diskio/diskio.c b/src/detection/diskio/diskio.c new file mode 100644 index 0000000..6ff66be --- /dev/null +++ b/src/detection/diskio/diskio.c @@ -0,0 +1,88 @@ +#include "diskio.h" + +#include "common/time.h" + +const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options); + +static FFlist ioCounters1; +static uint64_t time1; + +void ffPrepareDiskIO(FFDiskIOOptions* options) { + if (options->detectTotal) { + return; + } + + if (time1 != 0) { + return; // Already prepared + } + + ffListInit(&ioCounters1); + ffDiskIOGetIoCounters(&ioCounters1, options); + time1 = ffTimeGetNow(); +} + +const char* ffDetectDiskIO(FFlist* result, FFDiskIOOptions* options) { + const char* error = NULL; + + if (options->detectTotal) { + error = ffDiskIOGetIoCounters(result, options); + if (error) { + return error; + } + return NULL; + } + + if (time1 == 0) { + ffListInit(&ioCounters1); + error = ffDiskIOGetIoCounters(&ioCounters1, options); + if (error) { + return error; + } + time1 = ffTimeGetNow(); + } + + if (ioCounters1.length == 0) { + return "No physical disk found"; + } + + uint64_t time2 = ffTimeGetNow(); + while (time2 - time1 < options->waitTime) { + ffTimeSleep((uint32_t) (options->waitTime - (time2 - time1))); + time2 = ffTimeGetNow(); + } + + error = ffDiskIOGetIoCounters(result, options); + if (error) { + return error; + } + + if (result->length != ioCounters1.length) { + return "Different number of physical disks. Hardware change?"; + } + + for (uint32_t i = 0; i < result->length; ++i) { + FFDiskIOResult* icPrev = FF_LIST_GET(FFDiskIOResult, ioCounters1, i); + FFDiskIOResult* icCurr = FF_LIST_GET(FFDiskIOResult, *result, i); + 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)) { + uint64_t* prevValue = (uint64_t*) ((uint8_t*) icPrev + off); + uint64_t* currValue = (uint64_t*) ((uint8_t*) icCurr + off); + uint64_t temp = *currValue; + *currValue -= *prevValue; + *currValue /= (time2 - time1) / 1000 /* seconds */; + + // For next function call + *prevValue = temp; + } + } + + // For next function call + time1 = time2; + // Leak ioCounters1 here + + return NULL; +} diff --git a/src/detection/diskio/diskio.h b/src/detection/diskio/diskio.h new file mode 100644 index 0000000..39c665a --- /dev/null +++ b/src/detection/diskio/diskio.h @@ -0,0 +1,15 @@ +#pragma once + +#include "fastfetch.h" +#include "modules/diskio/option.h" + +typedef struct FFDiskIOResult { + FFstrbuf name; + FFstrbuf devPath; + uint64_t bytesRead; + uint64_t readCount; + uint64_t bytesWritten; + uint64_t writeCount; +} FFDiskIOResult; + +const char* ffDetectDiskIO(FFlist* result, FFDiskIOOptions* options); diff --git a/src/detection/diskio/diskio_apple.c b/src/detection/diskio/diskio_apple.c new file mode 100644 index 0000000..dc28907 --- /dev/null +++ b/src/detection/diskio/diskio_apple.c @@ -0,0 +1,57 @@ +#include "diskio.h" +#include "common/apple/cf_helpers.h" + +#include <IOKit/IOKitLib.h> +#include <IOKit/IOBSD.h> +#include <IOKit/storage/IOMedia.h> +#include <IOKit/storage/IOBlockStorageDriver.h> +#include <IOKit/storage/IOStorageDeviceCharacteristics.h> +#include <IOKit/storage/IOStorageProtocolCharacteristics.h> + +const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) { + FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = 0; + if (IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching(kIOBlockStorageDriverClass), &iterator) != KERN_SUCCESS) { + return "IOServiceGetMatchingServices() failed"; + } + + io_registry_entry_t registryEntry; + while ((registryEntry = IOIteratorNext(iterator)) != IO_OBJECT_NULL) { + FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDriver = registryEntry; + + FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryMedia = IO_OBJECT_NULL; + if (IORegistryEntryGetChildEntry(entryDriver, kIOServicePlane, &entryMedia) != KERN_SUCCESS) { + continue; + } + + io_name_t deviceName; + if (IORegistryEntryGetName(entryMedia, deviceName) != KERN_SUCCESS) { + continue; + } + + if (options->namePrefix.length && strncmp(deviceName, options->namePrefix.chars, options->namePrefix.length) != 0) { + continue; + } + + FF_CFTYPE_AUTO_RELEASE CFDictionaryRef statistics = IORegistryEntryCreateCFProperty(entryDriver, CFSTR(kIOBlockStorageDriverStatisticsKey), kCFAllocatorDefault, kNilOptions); + if (!statistics) { + continue; + } + + FFDiskIOResult* device = FF_LIST_ADD(FFDiskIOResult, *result); + ffStrbufInitS(&device->name, deviceName); + ffStrbufInit(&device->devPath); + + ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey), (int64_t*) &device->bytesRead); + ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey), (int64_t*) &device->bytesWritten); + ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsReadsKey), (int64_t*) &device->readCount); + ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsWritesKey), (int64_t*) &device->writeCount); + + FF_CFTYPE_AUTO_RELEASE CFStringRef bsdName = IORegistryEntryCreateCFProperty(entryMedia, CFSTR(kIOBSDNameKey), kCFAllocatorDefault, kNilOptions); + if (bsdName) { + ffCfStrGetString(bsdName, &device->devPath); + ffStrbufPrependS(&device->devPath, "/dev/"); + } + } + + return NULL; +} diff --git a/src/detection/diskio/diskio_bsd.c b/src/detection/diskio/diskio_bsd.c new file mode 100644 index 0000000..f5eb4b8 --- /dev/null +++ b/src/detection/diskio/diskio_bsd.c @@ -0,0 +1,120 @@ +#include "diskio.h" + +#if __has_include(<libgeom.h>) + + #include "common/strutil.h" + + #include <devstat.h> + #include <memory.h> + #include <fcntl.h> + #include <sys/ioctl.h> + #include <sys/disk.h> + #include <libgeom.h> + +const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) { + FF_A_CLEANUP(geom_deletetree) 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(); + if (!snap) { + return "geom_stats_snapshot_get() failed"; + } + + 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 = 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); + } + } + if (name.length == 0) { + ffStrbufSetS(&name, provider->lg_name); + } + + if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix)) { + continue; + } + + FFDiskIOResult* device = FF_LIST_ADD(FFDiskIOResult, *result); + ffStrbufInitF(&device->devPath, "/dev/%s", provider->lg_name); + device->bytesRead = snapIter->bytes[DEVSTAT_READ]; + device->readCount = snapIter->operations[DEVSTAT_READ]; + device->bytesWritten = snapIter->bytes[DEVSTAT_WRITE]; + device->writeCount = snapIter->operations[DEVSTAT_WRITE]; + ffStrbufInitMove(&device->name, &name); + } + + geom_stats_snapshot_free(snap); + geom_stats_close(); + + return NULL; +} + +#else + + #include <devstat.h> + #include <memory.h> + +const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) { + if (checkversion() < 0) { + return "checkversion() failed"; + } + + struct statinfo stats = { + .dinfo = (struct devinfo*) calloc(1, sizeof(struct devinfo)), + }; + if (getdevs(&stats) < 0) { + return "getdevs() failed"; + } + + for (int i = 0; i < stats.dinfo->numdevs; i++) { + struct devstat* current = &stats.dinfo->devices[i]; + if (current->device_type & DEVSTAT_TYPE_PASS) { + continue; + } + + char deviceName[128]; + snprintf(deviceName, sizeof(deviceName), "%s%d", current->device_name, current->unit_number); + + if (options->namePrefix.length && strncmp(deviceName, options->namePrefix.chars, options->namePrefix.length) != 0) { + continue; + } + + FFDiskIOResult* device = FF_LIST_ADD(FFDiskIOResult, *result); + ffStrbufInitS(&device->name, deviceName); + ffStrbufInitF(&device->devPath, "/dev/%s", deviceName); + device->bytesRead = current->bytes_read; + device->readCount = current->num_reads; + device->bytesWritten = current->bytes_written; + device->writeCount = current->num_writes; + } + + free(stats.dinfo->mem_ptr); + free(stats.dinfo); + + return NULL; +} + +#endif diff --git a/src/detection/diskio/diskio_linux.c b/src/detection/diskio/diskio_linux.c new file mode 100644 index 0000000..c7ddc55 --- /dev/null +++ b/src/detection/diskio/diskio_linux.c @@ -0,0 +1,99 @@ +#include "diskio.h" +#include "common/io.h" +#include "common/properties.h" +#include "common/strutil.h" + +#include <ctype.h> +#include <limits.h> +#include <inttypes.h> +#include <fcntl.h> + +static const char* parseDiskIOCounters(int dfd, const char* devName, FFlist* result, FFDiskIOOptions* options) { + FF_AUTO_CLOSE_FD int devfd = openat(dfd, "device", O_RDONLY | O_CLOEXEC | O_PATH | O_DIRECTORY); + if (devfd < 0) { + return "virtual device"; + } + + FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate(); + + { + if (ffAppendFileBufferRelative(devfd, "vendor", &name)) { + ffStrbufTrimRightSpace(&name); + if (name.length > 0) { + ffStrbufAppendC(&name, ' '); + } + } + + ffAppendFileBufferRelative(devfd, "model", &name); + ffStrbufTrimRightSpace(&name); + + if (name.length == 0) { + ffStrbufSetS(&name, devName); + } else if (ffStrStartsWith(devName, "nvme")) { + int devid, nsid; + if (sscanf(devName, "nvme%dn%d", &devid, &nsid) == 2) { + bool multiNs = nsid > 1; + if (!multiNs) { + char pathSysBlock[16]; + snprintf(pathSysBlock, ARRAY_SIZE(pathSysBlock), "nvme%dn2", devid); + multiNs = faccessat(devfd, pathSysBlock, F_OK, 0) == 0; + } + if (multiNs) { + // In Asahi Linux, there are multiple namespaces for the same NVMe drive. + ffStrbufAppendF(&name, " - %d", nsid); + } + } + } + + if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix)) { + return "ignored"; + } + } + + // I/Os merges sectors ticks ... + uint64_t nRead, sectorRead, nWritten, sectorWritten; + { + char sysBlockStat[PROC_FILE_BUFFSIZ]; + ssize_t fileSize = ffReadFileDataRelative(dfd, "stat", ARRAY_SIZE(sysBlockStat) - 1, sysBlockStat); + if (fileSize <= 0) { + return "failed to read stat file"; + } + sysBlockStat[fileSize] = '\0'; + if (sscanf(sysBlockStat, "%" PRIu64 "%*u%" PRIu64 "%*u%" PRIu64 "%*u%" PRIu64 "%*u", &nRead, §orRead, &nWritten, §orWritten) <= 0) { + return "invalid stat file format"; + } + } + + FFDiskIOResult* device = FF_LIST_ADD(FFDiskIOResult, *result); + ffStrbufInitMove(&device->name, &name); + ffStrbufInitF(&device->devPath, "/dev/%s", devName); + device->bytesRead = sectorRead * 512; + device->bytesWritten = sectorWritten * 512; + device->readCount = nRead; + device->writeCount = nWritten; + + return NULL; +} + +const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* 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; + } + + FF_AUTO_CLOSE_FD int dfd = openat(dirfd(sysBlockDirp), devName, O_RDONLY | O_CLOEXEC | O_PATH | O_DIRECTORY); + if (dfd > 0) { + parseDiskIOCounters(dfd, devName, result, options); + } + } + + return NULL; +} diff --git a/src/detection/diskio/diskio_nbsd.c b/src/detection/diskio/diskio_nbsd.c new file mode 100644 index 0000000..9ca9578 --- /dev/null +++ b/src/detection/diskio/diskio_nbsd.c @@ -0,0 +1,50 @@ +#include "diskio.h" +#include "common/io.h" +#include "common/strutil.h" +#include "common/mallocHelper.h" + +#include <sys/iostat.h> +#include <sys/sysctl.h> + +const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) { + int mib[] = { CTL_HW, HW_IOSTATS, sizeof(struct io_sysctl) }; + size_t len; + if (sysctl(mib, ARRAY_SIZE(mib), NULL, &len, NULL, 0) < 0) { + return "sysctl({HW_IOSTATS}, NULL) failed"; + } + uint32_t nDrive = (uint32_t) (len / sizeof(struct io_sysctl)); + + FF_AUTO_FREE struct io_sysctl* stats = malloc(len); + + if (sysctl(mib, ARRAY_SIZE(mib), stats, &len, NULL, 0) < 0) { + return "sysctl({HW_IOSTATS}, stats) failed"; + } + + char path[64] = "/dev/"; + + for (uint32_t i = 0; i < nDrive; ++i) { + struct io_sysctl* st = &stats[i]; + + if (options->namePrefix.length && strncmp(st->name, options->namePrefix.chars, options->namePrefix.length) != 0) { + continue; + } + + // Skip partitions + char* end = ffStrCopy(&path[5], st->name, ARRAY_SIZE(path) - 8); + *end++ = 'c'; + *end = '\0'; + if (!ffPathExists(path, FF_PATHTYPE_ANY)) { + continue; + } + + FFDiskIOResult* device = FF_LIST_ADD(FFDiskIOResult, *result); + ffStrbufInitNS(&device->devPath, (uint32_t) (end - path), path); + ffStrbufInitS(&device->name, st->name); + device->bytesRead = st->rbytes; + device->readCount = st->rxfer; + device->bytesWritten = st->wbytes; + device->writeCount = st->wxfer; + } + + return NULL; +} diff --git a/src/detection/diskio/diskio_nosupport.c b/src/detection/diskio/diskio_nosupport.c new file mode 100644 index 0000000..f5de15d --- /dev/null +++ b/src/detection/diskio/diskio_nosupport.c @@ -0,0 +1,5 @@ +#include "diskio.h" + +const char* ffDiskIOGetIoCounters(FF_A_UNUSED FFlist* result, FF_A_UNUSED FFDiskIOOptions* options) { + return "Not supported on this platform"; +} diff --git a/src/detection/diskio/diskio_obsd.c b/src/detection/diskio/diskio_obsd.c new file mode 100644 index 0000000..8dbc67e --- /dev/null +++ b/src/detection/diskio/diskio_obsd.c @@ -0,0 +1,39 @@ +#include "diskio.h" +#include "common/strutil.h" +#include "common/mallocHelper.h" + +#include <sys/disk.h> +#include <sys/sysctl.h> + +const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) { + int mib[] = { CTL_HW, HW_DISKSTATS }; + size_t len; + if (sysctl(mib, ARRAY_SIZE(mib), NULL, &len, NULL, 0) < 0) { + return "sysctl({HW_DISKSTATS}, NULL) failed"; + } + uint32_t nDrive = (uint32_t) (len / sizeof(struct diskstats)); + + FF_AUTO_FREE struct diskstats* stats = malloc(len); + + if (sysctl(mib, ARRAY_SIZE(mib), stats, &len, NULL, 0) < 0) { + return "sysctl({HW_DISKSTATS}, stats) failed"; + } + + for (uint32_t i = 0; i < nDrive; ++i) { + struct diskstats* st = &stats[i]; + + if (options->namePrefix.length && strncmp(st->ds_name, options->namePrefix.chars, options->namePrefix.length) != 0) { + continue; + } + + FFDiskIOResult* device = FF_LIST_ADD(FFDiskIOResult, *result); + ffStrbufInitF(&device->devPath, "/dev/%s", st->ds_name); + ffStrbufInitS(&device->name, st->ds_name); + device->bytesRead = st->ds_rbytes; + device->readCount = st->ds_rxfer; + device->bytesWritten = st->ds_wbytes; + device->writeCount = st->ds_wxfer; + } + + return NULL; +} diff --git a/src/detection/diskio/diskio_sunos.c b/src/detection/diskio/diskio_sunos.c new file mode 100644 index 0000000..7cda420 --- /dev/null +++ b/src/detection/diskio/diskio_sunos.c @@ -0,0 +1,42 @@ +#include "diskio.h" +#include "common/strutil.h" +#include <kstat.h> + +static inline void kstatFreeWrap(kstat_ctl_t** pkc) { + assert(pkc); + if (*pkc) { + kstat_close(*pkc); + } +} + +const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) { + FF_A_CLEANUP(kstatFreeWrap) kstat_ctl_t* kc = kstat_open(); + if (!kc) { + return "kstat_open() failed"; + } + + for (kstat_t* ks = kc->kc_chain; ks; ks = ks->ks_next) { + if (ks->ks_type != KSTAT_TYPE_IO || !ffStrEquals(ks->ks_class, "disk")) { + continue; + } + + if (options->namePrefix.length && strncmp(ks->ks_name, options->namePrefix.chars, options->namePrefix.length) != 0) { + continue; + } + + kstat_io_t kio; + if (kstat_read(kc, ks, &kio) < 0) { + continue; + } + + FFDiskIOResult* device = FF_LIST_ADD(FFDiskIOResult, *result); + ffStrbufInit(&device->devPath); // unlike other platforms, `/dev/ks_name` is not available + ffStrbufInitS(&device->name, ks->ks_name); + device->bytesRead = kio.nread; + device->readCount = kio.reads; + device->bytesWritten = kio.nwritten; + device->writeCount = kio.writes; + } + + return NULL; +} diff --git a/src/detection/diskio/diskio_windows.c b/src/detection/diskio/diskio_windows.c new file mode 100644 index 0000000..80ad94e --- /dev/null +++ b/src/detection/diskio/diskio_windows.c @@ -0,0 +1,101 @@ +#include "diskio.h" +#include "common/io.h" +#include "common/windows/unicode.h" + +#include <windows.h> +#include <winioctl.h> + +static bool detectPhysicalDisk(const wchar_t* szDevice, FFlist* result, FFDiskIOOptions* options) { + FF_AUTO_CLOSE_FD HANDLE hDevice = CreateFileW(szDevice, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + if (hDevice == INVALID_HANDLE_VALUE) { + return false; + } + + DWORD retSize; + char sddBuffer[4096]; + if (!DeviceIoControl( + hDevice, + IOCTL_STORAGE_QUERY_PROPERTY, + &(STORAGE_PROPERTY_QUERY) { + .PropertyId = StorageDeviceProperty, + .QueryType = PropertyStandardQuery, + }, + sizeof(STORAGE_PROPERTY_QUERY), + &sddBuffer, + ARRAY_SIZE(sddBuffer), + &retSize, + NULL) || + retSize == 0) { + return true; + } + + FFDiskIOResult* device = FF_LIST_ADD(FFDiskIOResult, *result); + 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 (!device->name.length) { + ffStrbufSetWS(&device->name, szDevice); + } + + if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix)) { + ffStrbufDestroy(&device->name); + result->length--; + return true; + } + + 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--; + } + + ffStrbufInitWS(&device->devPath, szDevice); + + return true; +} + +const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) { + { + wchar_t szPhysicalDrive[32] = L"\\\\.\\PhysicalDrive"; + wchar_t* pNum = szPhysicalDrive + strlen("\\\\.\\PhysicalDrive"); + for (uint32_t idev = 0;; ++idev) { + _ultow(idev, pNum, 10); + + if (!detectPhysicalDisk(szPhysicalDrive, result, options)) { + break; + } + } + } + + { + wchar_t szCdrom[32] = L"\\\\.\\CDROM"; + wchar_t* pNum = szCdrom + strlen("\\\\.\\CDROM"); + for (uint32_t idev = 0;; ++idev) { + _ultow(idev, pNum, 10); + + if (!detectPhysicalDisk(szCdrom, result, options)) { + break; + } + } + } + + return NULL; +} |