SmbiosHelper (Windows): prefers NtQuerySystemInformation

This commit is contained in:
李通洲
2026-03-04 10:00:06 +08:00
parent 766ed07999
commit 2ce152beaf
2 changed files with 46 additions and 15 deletions
+29 -15
View File
@@ -434,7 +434,7 @@ const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable()
return &table;
}
#elif defined(_WIN32)
#include <windows.h>
#include "common/windows/nt.h"
#pragma GCC diagnostic ignored "-Wmultichar"
@@ -450,36 +450,50 @@ typedef struct FFRawSmbiosData
const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable()
{
static FFRawSmbiosData* buffer;
static SYSTEM_FIRMWARE_TABLE_INFORMATION* buffer;
static FFSmbiosHeaderTable table;
if (!buffer)
{
FF_DEBUG("Initializing Windows SMBIOS buffer");
const DWORD signature = 'RSMB';
FF_DEBUG("Querying system firmware table size with signature 'RSMB'");
uint32_t bufSize = GetSystemFirmwareTable(signature, 0, NULL, 0);
if (bufSize <= sizeof(FFRawSmbiosData)) {
FF_DEBUG("Invalid firmware table size: %u (must be > %zu)",
bufSize, sizeof(FFRawSmbiosData));
SYSTEM_FIRMWARE_TABLE_INFORMATION sfti = {
.ProviderSignature = 'RSMB',
.Action = SystemFirmwareTableGet,
};
ULONG bufSize = 0;
NtQuerySystemInformation(SystemFirmwareTableInformation, &sfti, sizeof(sfti), &bufSize);
if (bufSize <= sizeof(FFRawSmbiosData) + sizeof(sfti)) {
FF_DEBUG("Invalid firmware table size: %lu (must be > %zu)", bufSize, sizeof(FFRawSmbiosData) + sizeof(sfti));
return NULL;
}
FF_DEBUG("Firmware table size: %u bytes", bufSize);
if (bufSize != sfti.TableBufferLength + (ULONG) sizeof(sfti)) {
FF_DEBUG("Firmware table size mismatch: NtQuerySystemInformation returned %lu but expected %lu",
bufSize, sfti.TableBufferLength + (ULONG) sizeof(sfti));
return NULL;
}
FF_DEBUG("Firmware table size: %lu bytes", bufSize);
buffer = (FFRawSmbiosData*) malloc(bufSize);
assert(buffer);
buffer = malloc(bufSize);
*buffer = sfti;
FF_DEBUG("Allocated buffer for SMBIOS data");
FF_MAYBE_UNUSED uint32_t resultSize = GetSystemFirmwareTable(signature, 0, buffer, bufSize);
assert(resultSize == bufSize);
if (!NT_SUCCESS(NtQuerySystemInformation(SystemFirmwareTableInformation, buffer, bufSize, &bufSize)))
{
FF_DEBUG("NtQuerySystemInformation(SystemFirmwareTableInformation) failed");
return NULL;
}
FFRawSmbiosData* rawData = (FFRawSmbiosData*) buffer->TableBuffer;
FF_DEBUG("Successfully retrieved SMBIOS data: version %u.%u, length %u bytes",
buffer->SMBIOSMajorVersion, buffer->SMBIOSMinorVersion, buffer->Length);
rawData->SMBIOSMajorVersion, rawData->SMBIOSMinorVersion, rawData->Length);
FF_DEBUG("Parsing SMBIOS table structures");
FF_MAYBE_UNUSED int structureCount = 0;
for (
const FFSmbiosHeader* header = (const FFSmbiosHeader*) buffer->SMBIOSTableData;
(const uint8_t*) header < buffer->SMBIOSTableData + buffer->Length;
const FFSmbiosHeader* header = (const FFSmbiosHeader*) rawData->SMBIOSTableData;
(const uint8_t*) header < rawData->SMBIOSTableData + rawData->Length;
header = ffSmbiosNextEntry(header)
)
{