DiskIO (Windows): improve device name detection

This commit is contained in:
李通洲
2023-12-17 18:24:01 +08:00
parent 1dbd8474c2
commit 70f39e641c
+115 -97
View File
@@ -17,111 +17,129 @@ 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 <= nDevices; ++idev) {
for (uint32_t idev = 0; idev <= nDevices; ++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)
continue;
DISK_PERFORMANCE diskPerformance;
DWORD ioctrlSize = sizeof(diskPerformance);
DWORD dwSize;
if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0, &diskPerformance, ioctrlSize, &dwSize, NULL))
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);
ffStrbufInit(&device->name);
STORAGE_DEVICE_DESCRIPTOR* sdd = (STORAGE_DEVICE_DESCRIPTOR*) sddBuffer;
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);
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
{
ffStrbufDestroy(&device->name);
ffStrbufDestroy(&device->interconnect);
result->length--;
continue;
}
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;
DWORD retSize = 0;
ffStrbufInit(&device->serial);
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)
{
STORAGE_DEVICE_DESCRIPTOR* sdd = (STORAGE_DEVICE_DESCRIPTOR*) sddBuffer;
if (sdd->SerialNumberOffset != 0)
{
ffStrbufSetS(&device->serial, (const char*) sddBuffer + sdd->SerialNumberOffset);
ffStrbufTrim(&device->serial, ' ');
}
}
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_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD;
else
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
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;
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, ' ');
}
ffStrbufInit(&device->serial);
if (sdd->SerialNumberOffset != 0)
{
ffStrbufSetS(&device->serial, (const char*) sddBuffer + sdd->SerialNumberOffset);
ffStrbufTrim(&device->serial, ' ');
}
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
{
ffStrbufDestroy(&device->name);
result->length--;
continue;
}
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;
}
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;
}
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_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD;
else
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
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;