mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
PhysicalDisk (Windows): detect CDROMs; detect read-only
This commit is contained in:
@@ -5,78 +5,99 @@
|
||||
#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,
|
||||
sizeof(sddBuffer),
|
||||
&retSize,
|
||||
NULL
|
||||
) || retSize == 0)
|
||||
return true;
|
||||
|
||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(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;
|
||||
}
|
||||
|
||||
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--;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* 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;
|
||||
|
||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||
STORAGE_DEVICE_DESCRIPTOR* sdd = (STORAGE_DEVICE_DESCRIPTOR*) sddBuffer;
|
||||
|
||||
ffStrbufInit(&device->name);
|
||||
if (sdd->VendorIdOffset != 0)
|
||||
wchar_t szPhysicalDrive[32] = L"\\\\.\\PhysicalDrive";
|
||||
wchar_t* pNum = szPhysicalDrive + strlen("\\\\.\\PhysicalDrive");
|
||||
for (uint32_t idev = 0; ; ++idev)
|
||||
{
|
||||
ffStrbufSetS(&device->name, (const char*) sddBuffer + sdd->VendorIdOffset);
|
||||
ffStrbufTrim(&device->name, ' ');
|
||||
_ultow(idev, pNum, 10);
|
||||
|
||||
if (!detectPhysicalDisk(szPhysicalDrive, result, options))
|
||||
break;
|
||||
}
|
||||
if (sdd->ProductIdOffset != 0)
|
||||
}
|
||||
|
||||
{
|
||||
wchar_t szCdrom[32] = L"\\\\.\\CDROM";
|
||||
wchar_t* pNum = szCdrom + strlen("\\\\.\\CDROM");
|
||||
for (uint32_t idev = 0; ; ++idev)
|
||||
{
|
||||
if (device->name.length)
|
||||
ffStrbufAppendC(&device->name, ' ');
|
||||
_ultow(idev, pNum, 10);
|
||||
|
||||
ffStrbufAppendS(&device->name, (const char*) sddBuffer + sdd->ProductIdOffset);
|
||||
ffStrbufTrimRight(&device->name, ' ');
|
||||
}
|
||||
|
||||
if (!device->name.length)
|
||||
ffStrbufAppendF(&device->name, "PhysicalDrive%u", (unsigned) idev);
|
||||
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
|
||||
{
|
||||
ffStrbufDestroy(&device->name);
|
||||
result->length--;
|
||||
continue;
|
||||
}
|
||||
|
||||
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;
|
||||
if (!detectPhysicalDisk(szCdrom, result, options))
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,126 +5,170 @@
|
||||
#include <windows.h>
|
||||
#include <winioctl.h>
|
||||
|
||||
static bool detectPhysicalDisk(const wchar_t* szDevice, FFlist* result, FFPhysicalDiskOptions* 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,
|
||||
sizeof(sddBuffer),
|
||||
&retSize,
|
||||
NULL
|
||||
) || retSize == 0)
|
||||
return true;
|
||||
|
||||
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 (!device->name.length)
|
||||
ffStrbufSetWS(&device->name, szDevice);
|
||||
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
|
||||
{
|
||||
ffStrbufDestroy(&device->name);
|
||||
result->length--;
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
GET_MEDIA_TYPES gmt = {};
|
||||
if(DeviceIoControl(
|
||||
hDevice,
|
||||
IOCTL_STORAGE_GET_MEDIA_TYPES_EX,
|
||||
NULL,
|
||||
0,
|
||||
&gmt,
|
||||
sizeof(gmt),
|
||||
&retSize,
|
||||
NULL) && gmt.MediaInfoCount > 0
|
||||
)
|
||||
{
|
||||
__typeof__(gmt.MediaInfo[0].DeviceSpecific.DiskInfo)* diskInfo = &gmt.MediaInfo[0].DeviceSpecific.DiskInfo;
|
||||
if (diskInfo->MediaCharacteristics & MEDIA_READ_ONLY)
|
||||
device->type |= FF_PHYSICALDISK_TYPE_READONLY;
|
||||
if (device->size == 0)
|
||||
device->size = (uint64_t) diskInfo->NumberMediaSides * diskInfo->TracksPerCylinder * diskInfo->SectorsPerTrack * diskInfo->BytesPerSector;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
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)
|
||||
wchar_t szPhysicalDrive[32] = L"\\\\.\\PhysicalDrive";
|
||||
wchar_t* pNum = szPhysicalDrive + strlen("\\\\.\\PhysicalDrive");
|
||||
for (uint32_t idev = 0; ; ++idev)
|
||||
{
|
||||
ffStrbufSetS(&device->name, (const char*) sddBuffer + sdd->VendorIdOffset);
|
||||
ffStrbufTrim(&device->name, ' ');
|
||||
_ultow(idev, pNum, 10);
|
||||
|
||||
if (!detectPhysicalDisk(szPhysicalDrive, result, options))
|
||||
break;
|
||||
}
|
||||
if (sdd->ProductIdOffset != 0)
|
||||
}
|
||||
|
||||
{
|
||||
wchar_t szCdrom[32] = L"\\\\.\\CDROM";
|
||||
wchar_t* pNum = szCdrom + strlen("\\\\.\\CDROM");
|
||||
for (uint32_t idev = 0; ; ++idev)
|
||||
{
|
||||
if (device->name.length)
|
||||
ffStrbufAppendC(&device->name, ' ');
|
||||
_ultow(idev, pNum, 10);
|
||||
|
||||
ffStrbufAppendS(&device->name, (const char*) sddBuffer + sdd->ProductIdOffset);
|
||||
ffStrbufTrimRight(&device->name, ' ');
|
||||
if (!detectPhysicalDisk(szCdrom, result, options))
|
||||
break;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user