mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
Windows: make SMBIOS data a singleton
This commit is contained in:
@@ -29,28 +29,17 @@ typedef struct FFSmbiosSystemEnclosure
|
||||
|
||||
const char* ffDetectChassis(FFChassisResult* result)
|
||||
{
|
||||
const FFRawSmbiosData* data = ffGetSmbiosData();
|
||||
const FFSmbiosSystemEnclosure* data = (const FFSmbiosSystemEnclosure*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_SYSTEM_ENCLOSURE];
|
||||
if (!data)
|
||||
return "System enclosure is not found in SMBIOS data";
|
||||
|
||||
for (
|
||||
const FFSmbiosHeader* header = (const FFSmbiosHeader*) data->SMBIOSTableData;
|
||||
(const uint8_t*) header < data->SMBIOSTableData + data->Length && header->Type != FF_SMBIOS_TYPE_END_OF_TABLE;
|
||||
header = ffSmbiosSkipLastStr(header)
|
||||
)
|
||||
{
|
||||
if (header->Type != FF_SMBIOS_TYPE_SYSTEM_ENCLOSURE)
|
||||
continue;
|
||||
const char* strings = (const char*) data + data->Header.Length;
|
||||
|
||||
const FFSmbiosSystemEnclosure* data = (const FFSmbiosSystemEnclosure*) header;
|
||||
const char* strings = (const char*) header + header->Length;
|
||||
ffStrbufSetStatic(&result->vendor, ffSmbiosLocateString(strings, data->Manufacturer));
|
||||
ffCleanUpSmbiosValue(&result->vendor);
|
||||
ffStrbufSetStatic(&result->version, ffSmbiosLocateString(strings, data->Version));
|
||||
ffCleanUpSmbiosValue(&result->version);
|
||||
ffStrbufSetStatic(&result->type, ffChassisTypeToString(data->Type));
|
||||
|
||||
ffStrbufSetStatic(&result->vendor, ffSmbiosLocateString(strings, data->Manufacturer));
|
||||
ffCleanUpSmbiosValue(&result->vendor);
|
||||
ffStrbufSetStatic(&result->version, ffSmbiosLocateString(strings, data->Version));
|
||||
ffCleanUpSmbiosValue(&result->version);
|
||||
ffStrbufSetStatic(&result->type, ffChassisTypeToString(data->Type));
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return "System enclosure is not found in SMBIOS data";
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -52,65 +52,58 @@ typedef struct FFSmbiosProcessorInfo
|
||||
|
||||
static const char* detectBySmbios(FFCPUResult* cpu)
|
||||
{
|
||||
const FFRawSmbiosData* data = ffGetSmbiosData();
|
||||
const FFSmbiosProcessorInfo* data = (const FFSmbiosProcessorInfo*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_PROCESSOR_INFO];
|
||||
|
||||
for (
|
||||
const FFSmbiosHeader* header = (const FFSmbiosHeader*) data->SMBIOSTableData;
|
||||
(const uint8_t*) header < data->SMBIOSTableData + data->Length && header->Type != FF_SMBIOS_TYPE_END_OF_TABLE;
|
||||
header = ffSmbiosSkipLastStr(header)
|
||||
)
|
||||
if (!data)
|
||||
return "Processor information is not found in SMBIOS data";
|
||||
|
||||
while (data->ProcessorType != 0x03 /*Central Processor*/ || (data->Status & 0b00000111) != 1 /*Enabled*/)
|
||||
{
|
||||
if (header->Type != FF_SMBIOS_TYPE_PROCESSOR_INFO)
|
||||
continue;
|
||||
|
||||
const FFSmbiosProcessorInfo* data = (const FFSmbiosProcessorInfo*) header;
|
||||
|
||||
if (data->ProcessorType != 0x03 /*Central Processor*/ || (data->Status & 0b00000111) != 1 /*Enabled*/)
|
||||
continue;
|
||||
|
||||
const char* strings = (const char*) header + header->Length;
|
||||
|
||||
cpu->frequencyMax = (data->MaxSpeed > 0 ? data->MaxSpeed : data->CurrentSpeed) / 1000.0;
|
||||
cpu->frequencyMin = data->ExternalClock / 1000.0;
|
||||
ffStrbufSetStatic(&cpu->name, ffSmbiosLocateString(strings, data->ProcessorVersion));
|
||||
ffStrbufSetStatic(&cpu->vendor, ffSmbiosLocateString(strings, data->ProcessorManufacturer));
|
||||
|
||||
if (header->Length > offsetof(FFSmbiosProcessorInfo, CoreEnabled2))
|
||||
cpu->coresPhysical = data->CoreEnabled2;
|
||||
else
|
||||
cpu->coresPhysical = data->CoreEnabled;
|
||||
|
||||
if (header->Length > offsetof(FFSmbiosProcessorInfo, ThreadEnabled))
|
||||
cpu->coresLogical = cpu->coresOnline = data->ThreadEnabled;
|
||||
else
|
||||
{
|
||||
DWORD length = 0;
|
||||
GetLogicalProcessorInformationEx(RelationGroup, NULL, &length);
|
||||
if (length == 0)
|
||||
return "GetLogicalProcessorInformationEx(RelationGroup, NULL, &length) failed";
|
||||
|
||||
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* FF_AUTO_FREE
|
||||
pProcessorInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc(length);
|
||||
|
||||
if (pProcessorInfo && GetLogicalProcessorInformationEx(RelationGroup, pProcessorInfo, &length))
|
||||
{
|
||||
for(
|
||||
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* ptr = pProcessorInfo;
|
||||
(uint8_t*)ptr < ((uint8_t*)pProcessorInfo) + length;
|
||||
ptr = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(((uint8_t*)ptr) + ptr->Size)
|
||||
)
|
||||
{
|
||||
assert(ptr->Relationship == RelationGroup);
|
||||
cpu->coresOnline += ptr->Group.GroupInfo->ActiveProcessorCount;
|
||||
cpu->coresLogical += ptr->Group.GroupInfo->MaximumProcessorCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
data = (const FFSmbiosProcessorInfo*) ffSmbiosNextEntry(&data->Header);
|
||||
if (data->Header.Type != FF_SMBIOS_TYPE_PROCESSOR_INFO)
|
||||
return "No active CPU is not found in SMBIOS data";
|
||||
}
|
||||
|
||||
return "System enclosure is not found in SMBIOS data";
|
||||
const char* strings = (const char*) data + data->Header.Length;
|
||||
|
||||
cpu->frequencyMax = (data->MaxSpeed > 0 ? data->MaxSpeed : data->CurrentSpeed) / 1000.0;
|
||||
cpu->frequencyMin = data->ExternalClock / 1000.0;
|
||||
ffStrbufSetStatic(&cpu->name, ffSmbiosLocateString(strings, data->ProcessorVersion));
|
||||
ffStrbufSetStatic(&cpu->vendor, ffSmbiosLocateString(strings, data->ProcessorManufacturer));
|
||||
|
||||
if (data->Header.Length > offsetof(FFSmbiosProcessorInfo, CoreEnabled2))
|
||||
cpu->coresPhysical = data->CoreEnabled2;
|
||||
else
|
||||
cpu->coresPhysical = data->CoreEnabled;
|
||||
|
||||
if (data->Header.Length > offsetof(FFSmbiosProcessorInfo, ThreadEnabled))
|
||||
cpu->coresLogical = cpu->coresOnline = data->ThreadEnabled;
|
||||
else
|
||||
{
|
||||
DWORD length = 0;
|
||||
GetLogicalProcessorInformationEx(RelationGroup, NULL, &length);
|
||||
if (length == 0)
|
||||
return "GetLogicalProcessorInformationEx(RelationGroup, NULL, &length) failed";
|
||||
|
||||
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* FF_AUTO_FREE
|
||||
pProcessorInfo = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)malloc(length);
|
||||
|
||||
if (pProcessorInfo && GetLogicalProcessorInformationEx(RelationGroup, pProcessorInfo, &length))
|
||||
{
|
||||
for(
|
||||
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX* ptr = pProcessorInfo;
|
||||
(uint8_t*)ptr < ((uint8_t*)pProcessorInfo) + length;
|
||||
ptr = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX*)(((uint8_t*)ptr) + ptr->Size)
|
||||
)
|
||||
{
|
||||
assert(ptr->Relationship == RelationGroup);
|
||||
cpu->coresOnline += ptr->Group.GroupInfo->ActiveProcessorCount;
|
||||
cpu->coresLogical += ptr->Group.GroupInfo->MaximumProcessorCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const char* detectByOS(FFCPUResult* cpu)
|
||||
|
||||
@@ -28,49 +28,42 @@ typedef struct FFSmbiosSystemInfo
|
||||
|
||||
const char* ffDetectHost(FFHostResult* host)
|
||||
{
|
||||
const FFRawSmbiosData* fullData = ffGetSmbiosData();
|
||||
const FFSmbiosSystemInfo* data = (const FFSmbiosSystemInfo*) (*ffGetSmbiosHeaderTable())[FF_SMBIOS_TYPE_SYSTEM_INFO];
|
||||
if (!data)
|
||||
return "System information is not found in SMBIOS data";
|
||||
|
||||
for (
|
||||
const FFSmbiosHeader* header = (const FFSmbiosHeader*) fullData->SMBIOSTableData;
|
||||
(const uint8_t*) header < fullData->SMBIOSTableData + fullData->Length && header->Type != FF_SMBIOS_TYPE_END_OF_TABLE;
|
||||
header = ffSmbiosSkipLastStr(header)
|
||||
)
|
||||
const char* strings = (const char*) data + data->Header.Length;
|
||||
|
||||
ffStrbufSetStatic(&host->vendor, ffSmbiosLocateString(strings, data->Manufacturer));
|
||||
ffCleanUpSmbiosValue(&host->vendor);
|
||||
ffStrbufSetStatic(&host->name, ffSmbiosLocateString(strings, data->ProductName));
|
||||
ffCleanUpSmbiosValue(&host->name);
|
||||
ffStrbufSetStatic(&host->version, ffSmbiosLocateString(strings, data->Version));
|
||||
ffCleanUpSmbiosValue(&host->version);
|
||||
ffStrbufSetStatic(&host->serial, ffSmbiosLocateString(strings, data->SerialNumber));
|
||||
ffCleanUpSmbiosValue(&host->serial);
|
||||
|
||||
static_assert(offsetof(FFSmbiosSystemInfo, UUID) == 0x08, "FFSmbiosSystemInfo.UUID offset is wrong");
|
||||
if (data->Header.Length > offsetof(FFSmbiosSystemInfo, UUID))
|
||||
{
|
||||
if (header->Type != FF_SMBIOS_TYPE_SYSTEM_INFO)
|
||||
continue;
|
||||
|
||||
const FFSmbiosSystemInfo* data = (const FFSmbiosSystemInfo*) header;
|
||||
const char* strings = (const char*) header + header->Length;
|
||||
|
||||
ffStrbufSetStatic(&host->vendor, ffSmbiosLocateString(strings, data->Manufacturer));
|
||||
ffCleanUpSmbiosValue(&host->vendor);
|
||||
ffStrbufSetStatic(&host->name, ffSmbiosLocateString(strings, data->ProductName));
|
||||
ffCleanUpSmbiosValue(&host->name);
|
||||
ffStrbufSetStatic(&host->version, ffSmbiosLocateString(strings, data->Version));
|
||||
ffCleanUpSmbiosValue(&host->version);
|
||||
ffStrbufSetStatic(&host->serial, ffSmbiosLocateString(strings, data->SerialNumber));
|
||||
ffCleanUpSmbiosValue(&host->serial);
|
||||
|
||||
static_assert(offsetof(FFSmbiosSystemInfo, UUID) == 0x08, "FFSmbiosSystemInfo.UUID offset is wrong");
|
||||
if (header->Length > offsetof(FFSmbiosSystemInfo, UUID))
|
||||
{
|
||||
ffStrbufSetF(&host->uuid, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
|
||||
data->UUID.TimeLow, data->UUID.TimeMid, data->UUID.TimeHighAndVersion,
|
||||
data->UUID.ClockSeqHiAndReserved, data->UUID.ClockSeqLow,
|
||||
data->UUID.Node[0], data->UUID.Node[1], data->UUID.Node[2], data->UUID.Node[3], data->UUID.Node[4], data->UUID.Node[5]);
|
||||
}
|
||||
|
||||
static_assert(offsetof(FFSmbiosSystemInfo, SKUNumber) == 0x19, "FFSmbiosSystemInfo.SKUNumber offset is wrong");
|
||||
if (header->Length > offsetof(FFSmbiosSystemInfo, SKUNumber))
|
||||
{
|
||||
ffStrbufSetStatic(&host->family, ffSmbiosLocateString(strings, data->Family));
|
||||
ffCleanUpSmbiosValue(&host->family);
|
||||
ffStrbufSetStatic(&host->sku, ffSmbiosLocateString(strings, data->SKUNumber));
|
||||
ffCleanUpSmbiosValue(&host->sku);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
ffStrbufSetF(&host->uuid, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
|
||||
data->UUID.TimeLow, data->UUID.TimeMid, data->UUID.TimeHighAndVersion,
|
||||
data->UUID.ClockSeqHiAndReserved, data->UUID.ClockSeqLow,
|
||||
data->UUID.Node[0], data->UUID.Node[1], data->UUID.Node[2], data->UUID.Node[3], data->UUID.Node[4], data->UUID.Node[5]);
|
||||
}
|
||||
|
||||
return "System information is not found in SMBIOS data";
|
||||
static_assert(offsetof(FFSmbiosSystemInfo, SKUNumber) == 0x19, "FFSmbiosSystemInfo.SKUNumber offset is wrong");
|
||||
if (data->Header.Length > offsetof(FFSmbiosSystemInfo, SKUNumber))
|
||||
{
|
||||
ffStrbufSetStatic(&host->sku, ffSmbiosLocateString(strings, data->SKUNumber));
|
||||
ffCleanUpSmbiosValue(&host->sku);
|
||||
}
|
||||
|
||||
if (data->Header.Length > offsetof(FFSmbiosSystemInfo, Family))
|
||||
{
|
||||
ffStrbufSetStatic(&host->family, ffSmbiosLocateString(strings, data->Family));
|
||||
ffCleanUpSmbiosValue(&host->family);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
+38
-3
@@ -52,17 +52,52 @@ void ffGetSmbiosValue(const char* devicesPath, const char* classPath, FFstrbuf*
|
||||
|
||||
#pragma GCC diagnostic ignored "-Wmultichar"
|
||||
|
||||
const FFRawSmbiosData* ffGetSmbiosData()
|
||||
const FFSmbiosHeader* ffSmbiosNextEntry(const FFSmbiosHeader* header)
|
||||
{
|
||||
const char* p = ((const char*) header) + header->Length;
|
||||
if (*p)
|
||||
{
|
||||
do
|
||||
p += strlen(p) + 1;
|
||||
while (*p);
|
||||
}
|
||||
else // The terminator is always double 0 even if there is no string
|
||||
p ++;
|
||||
|
||||
return (const FFSmbiosHeader*) (p + 1);
|
||||
}
|
||||
|
||||
const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable()
|
||||
{
|
||||
static FFRawSmbiosData* buffer;
|
||||
static FFSmbiosHeaderTable table;
|
||||
|
||||
if (!buffer)
|
||||
{
|
||||
const DWORD signature = 'RSMB';
|
||||
uint32_t bufSize = GetSystemFirmwareTable(signature, 0, NULL, 0);
|
||||
assert(bufSize > sizeof(FFRawSmbiosData));
|
||||
buffer = (FFRawSmbiosData*) malloc(bufSize);
|
||||
GetSystemFirmwareTable(signature, 0, buffer, bufSize);
|
||||
assert(buffer);
|
||||
uint32_t resSize = GetSystemFirmwareTable(signature, 0, buffer, bufSize);
|
||||
assert(resSize == bufSize);
|
||||
|
||||
for (
|
||||
const FFSmbiosHeader* header = (const FFSmbiosHeader*) buffer->SMBIOSTableData;
|
||||
(const uint8_t*) header < buffer->SMBIOSTableData + buffer->Length;
|
||||
header = ffSmbiosNextEntry(header)
|
||||
)
|
||||
{
|
||||
if (header->Type < FF_SMBIOS_TYPE_END_OF_TABLE)
|
||||
{
|
||||
if (!table[header->Type])
|
||||
table[header->Type] = header;
|
||||
}
|
||||
else if (header->Type == FF_SMBIOS_TYPE_END_OF_TABLE)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return buffer;
|
||||
|
||||
return &table;
|
||||
}
|
||||
#endif
|
||||
|
||||
+3
-15
@@ -100,22 +100,10 @@ static inline const char* ffSmbiosLocateString(const char* start, uint8_t index
|
||||
return start;
|
||||
}
|
||||
|
||||
static inline const FFSmbiosHeader* ffSmbiosSkipLastStr(const FFSmbiosHeader* header)
|
||||
{
|
||||
const char* p = ((const char*) header) + header->Length;
|
||||
if (*p)
|
||||
{
|
||||
do
|
||||
p += strlen(p) + 1;
|
||||
while (*p);
|
||||
}
|
||||
else // The terminator is always double 0 even if there is no string
|
||||
p ++;
|
||||
typedef const FFSmbiosHeader* FFSmbiosHeaderTable[FF_SMBIOS_TYPE_END_OF_TABLE];
|
||||
|
||||
return (const FFSmbiosHeader*) (p + 1);
|
||||
}
|
||||
|
||||
const FFRawSmbiosData* ffGetSmbiosData();
|
||||
const FFSmbiosHeader* ffSmbiosNextEntry(const FFSmbiosHeader* header);
|
||||
const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user