1.SMBIOS简介
SMBIOS是System Management BIOS的概念, SMBIOS是主板或系统制造者以标准格式显示产品管理信息所需遵循的统一规范, 显示有关系统管理BIOS主板的信息。SMBIOS 使您能够找出有关的计算机制造商的详细信息、 模型类型、 序列号和 BIOS 版本、 处理器数量、 物理内存,等等。
对一些特殊制定需求,如只能针对某一厂商机器使用,往往需要通过获取SMBIOS内容解析得到该信息,添加到代码中,实现该自定义定制需求。本章主要介绍windows API获取SMBIOS信息的方法
2.SMBIOS结构信息
从 SMBIOS 2.3 版本开始,兼容 SMBIOS 的实现必须包含以下 10 个数据表结构: BIOS 信息 (Type 0) 、系统信息 (Type 1) 、系统外围或底架(Type 3) 、处理器信息 (Type 4) 、高速缓存信息 (Type 7) 、系统插槽 (Type 9) 、物理存储阵列 (Type 16) 、存储设备 (Type 17) 、存储阵列映射地址(Type 19) 、系统引导信息 (Type 32) 。
其他还有一些根据需求实现的类型,如存储设备映射地址 (Type 20) 、内建指针设备 (Type 21) 、便携式电池 (Type 22) 等等,
每种类型都有对应的结构表,详细信息可以根据不同类型去查阅对应结构表去解析,本文主要以解析BIOS(Type 0)为例。
SMBIOS结构表(BIOS(Type 0)) 参考图1-1
参考网页:http://blog.csdn.net/zhoudaxia/article/details/5919871
图1-1
3.Windows API获取SMBIOS流程
Windows提供了直接API GetSystemFirmwareTable 来获取SMBIOS信息。该函数从firmware table provider中检索特定的firmware table信息。请参考: https://msdn.microsoft.com/zh-cn/library/ms724379%28v=VS.85%29.aspx?f=255&MSPPError=-2147217396
详细使用流程:
3.1 调用GetSystemFirmwareTable 获取信息buffer大小
DWORD iSignature = 'R';
iSignature = iSignature << 8 | 'S';
iSignature = iSignature << 8 | 'M';
iSignature = iSignature << 8 | 'B';
int iBufferSizeNeeded = GetSystemFirmwareTable( iSignature, 0, 0, 0 );
参数只有FirmwareTableProviderSignature,其余都是NULL即可。
iSignature=RSMB,代表是SMBIOS firmware table provider,将是获取该部分内容。
其中,FirmwareTableProviderSignature参数列表:
Value | Meaning |
'ACPI' | The ACPI firmware table provider. |
'FIRM' | The raw firmware table provider. |
'RSMB' | The raw SMBIOS firmware table provider. |
3.2 再次调用GetSystemFirmwareTable 获取RawSMBIOSData内容
char buff[1024*2] = {0};
GetSystemFirmwareTable( iSignature, 0, buff, iBufferSizeNeeded);
这里的buff内容就是RawSMBIOSData内容
3.3 解析RawSMBIOSData内容
首先我们要先了解该结构体才能去解析内容,在windows.h定义如下:
struct RawSMBIOSData
{
BYTE Used20CallingMethod;
BYTE SMBIOSMajorVersion;
BYTE SMBIOSMinorVersion;
BYTE DmiRevision;
DWORD Length;
BYTE SMBIOSTableData[];
};
从结构体中,我们可以获取SMBIOS的版本信息和长度以及SMBIOSTableData的信息,
RawSMBIOSData *p;
p = (RawSMBIOSData *)buff;
获取SMBIOSTableData buffer的首地址:
p->SMBIOSTableData = (BYTE *)(buff + 8);//跳过前面8个字节
SMBIOSTableData可以理解为 格式区+数据内容 两部分,而格式区有一个头,类似:
struct SMBios_Thunk
{
BYTE flag;
BYTE data_offset;
};
flag是硬件类型,data_offset是表示该格式区长度。所有type SMBIOS结构表都有这个头存在。后面我们就可以通过移动p->SMBIOSTableData 指针以及SMBIOS 某type的结构表来获取具体的硬件信息了。详细参考下面SMBIOS数据解析示例。
4.SMBIOS数据解析示例
如上面所讲,SMBIOSTableData可以理解为格式区+数据内容两部分组成,可以直接获取前两个字节分析出type类型(本例type=0)和格式区长度(本例length =18)。
另外可以通过下面通俗解释确认信息段,该段数据以00 00结尾(因为字符串以00结尾,类型块结尾也是00,所以可以理解为遇到00 00为一个类型段结束),如图4-1,棕色线部分为一个完整类型段:
图4-1
根据上述信息,获取type 0字段,分析结构区以找出需要读取内容,注意红色标记部分的查找方式,结构区字符如下图4-2
图4-2
根据SMBIOS结构表分析(举例字节见红色线,格式区长度数据见黄色线标注):
第1个字节offset 0,为0x00,代表结构的TYPE号为0;
第2个字节offset 1,0x18,代表格式区长度为18,即图中蓝色段;
第3-4(2 bytes)字节offset 2,3,0x01 0x00,本结构的句柄,
第5字节offset 4,0x01, 为厂商信息,位置在格式区后紧跟的第1个字符串
......
格式区后面紧跟的为字符串内容:根据格式区指定index查找。每个字符串以00结尾,参考下图绿线部分
图4-3
第01个字符串:..A...Dell Inc.
第02个字符串:A11
.......
依次获取SMBIOS中信息
同样,以对应SMBIOS方式分析其他类型段的内容。
5.WMIC方法
上面描述的方式需要有一定的软件编程背景和对SMBIOS有一定解析能力基础者使用,对于普通使用者并不太适用,比较幸运的是windows提供另一种简便快捷的方法,只需通过命令行方式就能获取这些BIOS信息,就是使用WMIC。
WMIC扩展WMI(Windows Management Instrumentation,Windows管理工具) ,提供了从命令行接口和批命令脚本执行系统管理的支持。它是一个非常强大的管理工具。我们单独就查询BIOS中Manufacturer信息举例说明如何使用。
1.开启命令行,运行” WMIC”进入WMIC命令行环境,如果你不知道如何操作可以输入” /? “查询。
在帮助中信息中可以看到
2.我们需要知道BIOS信息,输入” bios /? “
可以看到其完整支持命令和使用方法,因为我们只是想要获取其信息,那么很明显就是使用get命令。
3.同样的方式来确认get 的使用
因为我们需要获取的是厂商信息,即对应Manufacturer属性的使用
4.完整输入获取命令:” wmic bios get manufacturer “
你可以得到Manufacturer信息。
同样的,你可以类似方法去其他信息获取或操作,对不确定使用/?来查询辅助。
另外,
在命令行环境上,当然你也可以直接输入完整命令:wmic bios get manufacturer,获取设备厂商信息,结果和操作与上面都是一致的。