mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
PhysicalDisk (Windows): switches to CMAPI; adds floppy support
This commit is contained in:
@@ -1,12 +1,14 @@
|
||||
#include "physicaldisk.h"
|
||||
#include "common/io.h"
|
||||
#include "common/windows/unicode.h"
|
||||
#include "common/mallocHelper.h"
|
||||
|
||||
#include <stdalign.h>
|
||||
#include <windows.h>
|
||||
#include <winioctl.h>
|
||||
#include <cfgmgr32.h>
|
||||
|
||||
static bool detectPhysicalDisk(const wchar_t* szDevice, FFlist* result, FFPhysicalDiskOptions* options) {
|
||||
static bool detectPhysicalDisk(const char* physicalType, 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;
|
||||
@@ -14,7 +16,9 @@ static bool detectPhysicalDisk(const wchar_t* szDevice, FFlist* result, FFPhysic
|
||||
|
||||
DWORD retSize;
|
||||
FFPhysicalDiskType type = FF_PHYSICALDISK_TYPE_NONE;
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
|
||||
|
||||
const char* interconnect = NULL;
|
||||
uint64_t size = 0;
|
||||
{
|
||||
alignas(DISK_GEOMETRY_EX) uint8_t dgeBuffer[4096];
|
||||
@@ -29,146 +33,194 @@ static bool detectPhysicalDisk(const wchar_t* szDevice, FFlist* result, FFPhysic
|
||||
NULL)) {
|
||||
const DISK_GEOMETRY_EX* dge = (const DISK_GEOMETRY_EX*) dgeBuffer;
|
||||
size = (uint64_t) dge->DiskSize.QuadPart;
|
||||
} else if (DeviceIoControl(
|
||||
hDevice,
|
||||
IOCTL_DISK_GET_DRIVE_GEOMETRY,
|
||||
NULL,
|
||||
0,
|
||||
dgeBuffer,
|
||||
sizeof(dgeBuffer),
|
||||
&retSize,
|
||||
NULL) &&
|
||||
retSize >= sizeof(DISK_GEOMETRY)) {
|
||||
const DISK_GEOMETRY* dg = (const DISK_GEOMETRY*) dgeBuffer;
|
||||
size = (uint64_t) dg->BytesPerSector * dg->SectorsPerTrack * dg->TracksPerCylinder * (uint64_t) dg->Cylinders.QuadPart;
|
||||
switch (dg->MediaType) {
|
||||
case F3_1Pt44_512:
|
||||
case F3_2Pt88_512:
|
||||
case F3_20Pt8_512:
|
||||
case F3_720_512:
|
||||
case F3_120M_512:
|
||||
case F3_640_512:
|
||||
case F3_1Pt2_512:
|
||||
case F3_1Pt23_1024:
|
||||
case F3_128Mb_512:
|
||||
case F3_230Mb_512:
|
||||
case F3_200Mb_512:
|
||||
case F3_240M_512:
|
||||
case F3_32M_512:
|
||||
ffStrbufSetStatic(&name, "3.5-inch Floppy Disk");
|
||||
break;
|
||||
case F5_1Pt2_512:
|
||||
case F5_360_512:
|
||||
case F5_320_512:
|
||||
case F5_320_1024:
|
||||
case F5_180_512:
|
||||
case F5_160_512:
|
||||
case F5_640_512:
|
||||
case F5_720_512:
|
||||
case F5_1Pt23_1024:
|
||||
ffStrbufSetStatic(&name, "5.25-inch Floppy Disk");
|
||||
break;
|
||||
case F8_256_128:
|
||||
ffStrbufSetStatic(&name, "8-inch Floppy Disk");
|
||||
break;
|
||||
default:
|
||||
return true; // Unsupported
|
||||
}
|
||||
interconnect = "Floppy Controller";
|
||||
type |= FF_PHYSICALDISK_TYPE_HDD | FF_PHYSICALDISK_TYPE_REMOVABLE;
|
||||
}
|
||||
}
|
||||
if (size == 0) {
|
||||
type |= FF_PHYSICALDISK_TYPE_UNKNOWN;
|
||||
}
|
||||
|
||||
const STORAGE_DEVICE_DESCRIPTOR* sdd = NULL;
|
||||
alignas(STORAGE_DEVICE_DESCRIPTOR) uint8_t 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;
|
||||
}
|
||||
const STORAGE_DEVICE_DESCRIPTOR* sdd = (const STORAGE_DEVICE_DESCRIPTOR*) sddBuffer;
|
||||
if (!interconnect) {
|
||||
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) {
|
||||
sdd = (const STORAGE_DEVICE_DESCRIPTOR*) sddBuffer;
|
||||
|
||||
const char* interconnect;
|
||||
switch (sdd->BusType) {
|
||||
case BusTypeScsi:
|
||||
interconnect = "SCSI";
|
||||
break;
|
||||
case BusTypeAtapi:
|
||||
interconnect = "ATAPI";
|
||||
break;
|
||||
case BusTypeAta:
|
||||
interconnect = "ATA";
|
||||
break;
|
||||
case BusType1394:
|
||||
interconnect = "IEEE 1394";
|
||||
break;
|
||||
case BusTypeSsa:
|
||||
interconnect = "SSA";
|
||||
break;
|
||||
case BusTypeFibre:
|
||||
interconnect = "Fibre";
|
||||
break;
|
||||
case BusTypeUsb:
|
||||
interconnect = "USB";
|
||||
break;
|
||||
case BusTypeRAID:
|
||||
interconnect = "RAID";
|
||||
break;
|
||||
case BusTypeiScsi:
|
||||
interconnect = "iSCSI";
|
||||
break;
|
||||
case BusTypeSas:
|
||||
interconnect = "SAS";
|
||||
break;
|
||||
case BusTypeSata:
|
||||
interconnect = "SATA";
|
||||
break;
|
||||
case BusTypeSd:
|
||||
interconnect = "SD";
|
||||
break;
|
||||
case BusTypeMmc:
|
||||
interconnect = "MMC";
|
||||
break;
|
||||
case BusTypeVirtual:
|
||||
interconnect = "Virtual";
|
||||
type |= FF_PHYSICALDISK_TYPE_VIRTUAL;
|
||||
break;
|
||||
case BusTypeFileBackedVirtual:
|
||||
interconnect = "File Backed Virtual";
|
||||
type |= FF_PHYSICALDISK_TYPE_VIRTUAL;
|
||||
break;
|
||||
case BusTypeSpaces:
|
||||
interconnect = "Storage Spaces";
|
||||
type |= FF_PHYSICALDISK_TYPE_VIRTUAL;
|
||||
break;
|
||||
case BusTypeNvme:
|
||||
interconnect = "NVMe";
|
||||
break;
|
||||
case BusTypeSCM:
|
||||
interconnect = "SCM";
|
||||
break;
|
||||
case BusTypeUfs:
|
||||
interconnect = "UFS";
|
||||
break;
|
||||
case 0x14 /*BusTypeNvmeof*/:
|
||||
interconnect = "NVMe-oF";
|
||||
break;
|
||||
default:
|
||||
interconnect = "Unknown";
|
||||
break;
|
||||
switch (sdd->BusType) {
|
||||
case BusTypeScsi:
|
||||
interconnect = "SCSI";
|
||||
break;
|
||||
case BusTypeAtapi:
|
||||
interconnect = "ATAPI";
|
||||
break;
|
||||
case BusTypeAta:
|
||||
interconnect = "ATA";
|
||||
break;
|
||||
case BusType1394:
|
||||
interconnect = "IEEE 1394";
|
||||
break;
|
||||
case BusTypeSsa:
|
||||
interconnect = "SSA";
|
||||
break;
|
||||
case BusTypeFibre:
|
||||
interconnect = "Fibre";
|
||||
break;
|
||||
case BusTypeUsb:
|
||||
interconnect = "USB";
|
||||
break;
|
||||
case BusTypeRAID:
|
||||
interconnect = "RAID";
|
||||
break;
|
||||
case BusTypeiScsi:
|
||||
interconnect = "iSCSI";
|
||||
break;
|
||||
case BusTypeSas:
|
||||
interconnect = "SAS";
|
||||
break;
|
||||
case BusTypeSata:
|
||||
interconnect = "SATA";
|
||||
break;
|
||||
case BusTypeSd:
|
||||
interconnect = "SD";
|
||||
break;
|
||||
case BusTypeMmc:
|
||||
interconnect = "MMC";
|
||||
break;
|
||||
case BusTypeVirtual:
|
||||
interconnect = "Virtual";
|
||||
type |= FF_PHYSICALDISK_TYPE_VIRTUAL;
|
||||
break;
|
||||
case BusTypeFileBackedVirtual:
|
||||
interconnect = "File Backed Virtual";
|
||||
type |= FF_PHYSICALDISK_TYPE_VIRTUAL;
|
||||
break;
|
||||
case BusTypeSpaces:
|
||||
interconnect = "Storage Spaces";
|
||||
type |= FF_PHYSICALDISK_TYPE_VIRTUAL;
|
||||
break;
|
||||
case BusTypeNvme:
|
||||
interconnect = "NVMe";
|
||||
break;
|
||||
case BusTypeSCM:
|
||||
interconnect = "SCM";
|
||||
break;
|
||||
case BusTypeUfs:
|
||||
interconnect = "UFS";
|
||||
break;
|
||||
case 0x14 /*BusTypeNvmeof*/:
|
||||
interconnect = "NVMe-oF";
|
||||
break;
|
||||
default:
|
||||
interconnect = "Unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
if (sdd->VendorIdOffset != 0) {
|
||||
ffStrbufSetS(&name, (const char*) sdd + sdd->VendorIdOffset);
|
||||
ffStrbufTrim(&name, ' ');
|
||||
}
|
||||
if (sdd->ProductIdOffset != 0) {
|
||||
if (name.length) {
|
||||
ffStrbufAppendC(&name, ' ');
|
||||
}
|
||||
|
||||
ffStrbufAppendS(&name, (const char*) sdd + sdd->ProductIdOffset);
|
||||
ffStrbufTrimRight(&name, ' ');
|
||||
}
|
||||
}
|
||||
if (!name.length) {
|
||||
ffStrbufSetStatic(&name, physicalType);
|
||||
}
|
||||
}
|
||||
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
|
||||
ffStrbufInit(&device->serial);
|
||||
ffStrbufInit(&device->revision);
|
||||
ffStrbufInit(&device->name);
|
||||
ffStrbufInitMove(&device->name, &name);
|
||||
ffStrbufInit(&device->devPath);
|
||||
ffStrbufInitStatic(&device->interconnect, interconnect);
|
||||
device->type = type;
|
||||
device->size = size;
|
||||
device->temperature = FF_PHYSICALDISK_TEMP_UNSET;
|
||||
|
||||
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, ' ');
|
||||
ffStrbufSetWS(&device->devPath, szDevice);
|
||||
|
||||
if (sdd) {
|
||||
if (sdd->SerialNumberOffset != 0) {
|
||||
ffStrbufSetS(&device->serial, (const char*) sdd + sdd->SerialNumberOffset);
|
||||
ffStrbufTrimSpace(&device->serial);
|
||||
}
|
||||
|
||||
ffStrbufAppendS(&device->name, (const char*) sddBuffer + sdd->ProductIdOffset);
|
||||
ffStrbufTrimRight(&device->name, ' ');
|
||||
}
|
||||
if (sdd->ProductRevisionOffset != 0) {
|
||||
ffStrbufSetS(&device->revision, (const char*) sdd + sdd->ProductRevisionOffset);
|
||||
ffStrbufTrimRightSpace(&device->revision);
|
||||
}
|
||||
|
||||
if (!device->name.length) {
|
||||
ffStrbufSetWS(&device->name, szDevice);
|
||||
device->type |= sdd->RemovableMedia ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
|
||||
}
|
||||
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix)) {
|
||||
ffStrbufDestroy(&device->name);
|
||||
result->length--;
|
||||
return true;
|
||||
}
|
||||
|
||||
ffStrbufSetWS(&device->devPath, szDevice);
|
||||
if (sdd->SerialNumberOffset != 0) {
|
||||
ffStrbufSetS(&device->serial, (const char*) sddBuffer + sdd->SerialNumberOffset);
|
||||
ffStrbufTrimSpace(&device->serial);
|
||||
}
|
||||
|
||||
if (sdd->ProductRevisionOffset != 0) {
|
||||
ffStrbufSetS(&device->revision, (const char*) sddBuffer + sdd->ProductRevisionOffset);
|
||||
ffStrbufTrimRightSpace(&device->revision);
|
||||
}
|
||||
|
||||
device->type |= sdd->RemovableMedia ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
|
||||
|
||||
{
|
||||
alignas(GET_MEDIA_TYPES) uint8_t buffer[4096];
|
||||
GET_MEDIA_TYPES* gmt = (GET_MEDIA_TYPES*) buffer;
|
||||
@@ -201,7 +253,7 @@ static bool detectPhysicalDisk(const wchar_t* szDevice, FFlist* result, FFPhysic
|
||||
}
|
||||
}
|
||||
|
||||
if (!(device->type & FF_PHYSICALDISK_TYPE_VIRTUAL)) {
|
||||
if (!(device->type & FF_PHYSICALDISK_TYPE_VIRTUAL) && !(device->type & FF_PHYSICALDISK_TYPE_HDD)) {
|
||||
DEVICE_SEEK_PENALTY_DESCRIPTOR dspd = {};
|
||||
if (DeviceIoControl(
|
||||
hDevice,
|
||||
@@ -242,42 +294,41 @@ static bool detectPhysicalDisk(const wchar_t* szDevice, FFlist* result, FFPhysic
|
||||
return true;
|
||||
}
|
||||
|
||||
static void detectPhysicalDisksByInterfaceClass(const char* type, const GUID* interfaceClassGuid, FFlist* result, FFPhysicalDiskOptions* options) {
|
||||
ULONG cchDeviceInterfaces = 0;
|
||||
if (CM_Get_Device_Interface_List_SizeW(
|
||||
&cchDeviceInterfaces,
|
||||
(LPGUID) interfaceClassGuid,
|
||||
NULL,
|
||||
CM_GET_DEVICE_INTERFACE_LIST_PRESENT) != CR_SUCCESS ||
|
||||
cchDeviceInterfaces <= 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
wchar_t* FF_AUTO_FREE mszDeviceInterfaces = (wchar_t*) malloc(cchDeviceInterfaces * sizeof(wchar_t));
|
||||
if (!mszDeviceInterfaces) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (CM_Get_Device_Interface_ListW(
|
||||
(LPGUID) interfaceClassGuid,
|
||||
NULL,
|
||||
mszDeviceInterfaces,
|
||||
cchDeviceInterfaces,
|
||||
CM_GET_DEVICE_INTERFACE_LIST_PRESENT) != CR_SUCCESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
// MULTI_SZ: "str1\0str2\0...\0\0"
|
||||
for (const wchar_t* p = mszDeviceInterfaces; *p; p += wcslen(p) + 1) {
|
||||
detectPhysicalDisk(type, p, result, options);
|
||||
}
|
||||
}
|
||||
|
||||
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
wchar_t szTape[32] = L"\\\\.\\Tape";
|
||||
wchar_t* pNum = szTape + strlen("\\\\.\\Tape");
|
||||
for (uint32_t idev = 0;; ++idev) {
|
||||
_ultow(idev, pNum, 10);
|
||||
|
||||
if (!detectPhysicalDisk(szTape, result, options)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
detectPhysicalDisksByInterfaceClass("Floppy", &GUID_DEVINTERFACE_FLOPPY, result, options);
|
||||
detectPhysicalDisksByInterfaceClass("Disk", &GUID_DEVINTERFACE_DISK, result, options);
|
||||
detectPhysicalDisksByInterfaceClass("CD-ROM", &GUID_DEVINTERFACE_CDROM, result, options);
|
||||
detectPhysicalDisksByInterfaceClass("Tape", &GUID_DEVINTERFACE_TAPE, result, options);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user