Windows: make SMBIOS data a singleton

This commit is contained in:
李通洲
2024-01-06 14:46:54 +08:00
parent fe0b43d92d
commit 1d35811253
5 changed files with 133 additions and 135 deletions
+10 -21
View File
@@ -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;
}
+48 -55
View File
@@ -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)
+34 -41
View File
@@ -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
View File
@@ -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
View File
@@ -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