机器的SMBios数据保存在注册表中,据说从XP开始微软就已经这么干,附件是从注册表导出的数据供参考。
现在需要从SMBios中拆分出机器的BIOS信息、机器硬件信息等等,只是这是二进制数据,不知道如何处理,求大神援助!
另:红毛搞过用API直接读取SMBios数据的示例,我为什么不用上呢?因为该API不兼容XP,最重要的是我没研究明白。
这里有些资料介绍貌似比较详细:BIOS入知识枝桠——SMBIOS_smbios是什么意思
去把红毛撺掇过来吧,他搞这个在行。
红毛提不起兴趣
顶一下,希望得到解答。
示例文件夹·有红毛写的例子
ENVI^ ENVIMODE=1 ENVI$ &NL=0d 0a //转换RSMB为DWORD----开始 CODE *,RSMB,*-ANSI,&FirmwareTableProviderSignatureHex SED -ex &FirmwareTableProviderSignature=0, 0x,,&FirmwareTableProviderSignatureHex //转换RSMB为DWORD----结束 //第四个参数传入0,则返回获取RSMB结构长度 CALL $--qd --ret:&GetSystemFirmwareTableRet Kernel32.dll,GetSystemFirmwareTable,#%&FirmwareTableProviderSignature%,#0,#0,#0 //判断API是否成功 IFEX #%&GetSystemFirmwareTableRet%=0,EXIT //设置RSMB长度 ENVI &BufferSize=%&GetSystemFirmwareTableRet% //申请%&BufferSize%长度的&pFirmwareTableBuffer变量内存空间 SET$# pFirmwareTableBuffer=*%&BufferSize% 0 //获取&pFirmwareTableBuffer数据 CALL $--qd --ret:&GetSystemFirmwareTableRet Kernel32.DLL,GetSystemFirmwareTable,#%&FirmwareTableProviderSignature%,#0,*&pFirmwareTableBuffer,#%&BufferSize% //MESS. %&GetSystemFirmwareTableRet% //SET?数据类型 源PE变量名或地址=变量名:偏移字节数 //取PE对象中指定类型2进制数据。 SET?char pFirmwareTableBuffer=&&Used20CallingMethod:0 CALC &Used20CallingMethod=%&Used20CallingMethod% //16进制转10进制 SET?char pFirmwareTableBuffer=&&SMBIOSMajorVersion:1 CALC &SMBIOSMajorVersion=%&SMBIOSMajorVersion% SET?char pFirmwareTableBuffer=&&SMBIOSMinorVersion:2 CALC &SMBIOSMinorVersion=%&SMBIOSMinorVersion% SET?char pFirmwareTableBuffer=&&DmiRevision:3 CALC &DmiRevision=%&DmiRevision% SET?int pFirmwareTableBuffer=&&SMBIOSTableDataLength:4 ENVI &&SMBIOS_Version=%&SMBIOSMajorVersion%.%&SMBIOSMinorVersion% //SET-make PE变量名=[地址|&PE变量名[@[$]偏移]][;[*][[$]字节数]] //创建PE变量。*为char串 SET-make &SMBIOSTableData=&pFirmwareTableBuffer@(1 + 1 + 1 + 1 + 4);*%&SMBIOSTableDataLength% //获取实际的SMBIOSTableData数据 //把数据写入到一个文件中,方便用Winhex查看对比。 //IFEX %&CurDir%\SMBIOSTableData.Bin,FILE %&CurDir%\SMBIOSTableData.Bin //GETF -bin &pFirmwareTableBuffer,(1 + 1 + 1 + 1 + 4)#%&SMBIOSTableDataLength%,&SMBIOSTableDataTemp //PUTF %&CurDir%\SMBIOSTableData.Bin,0#,%&SMBIOSTableDataTemp% SET$# &type=*1 0 //申请1个字节的内存空间,定义一个变量,作为类型变量 SET$# &data_offset=*1 0 //申请1个字节的内存空间,定义一个变量,作为类型(格式区)长度 ENVI &&Type_Start=0 //定义一个变量,作为当前类型的起始位置值的标记 CODE *ANSI,0x00 0x00,**ANSI,&&TypeKeyWords CODE *ANSI,0x00,**ANSI,&&CharKeyWords LOOP #%&Type_Start%>=0, {* //SET-zero PE变量名=[[$]数值][@[$]偏移]][;[$]数量] //清除变量的内存,默认0 $:加宽,可多次 SET-zero type= SET-zero data_offset= SET?char SMBIOSTableData=&type:%&&Type_Start% ENVI &&Type_Start_Last=%&Type_Start% //上一个类型的结束位置 SET?char SMBIOSTableData=&data_offset:(%&Type_Start% + 1) CALC &data_offset=%&data_offset% //MESS &data_offset=%&data_offset% CALC &pdata_offset=%&data_offset%-1 //格式区结束地址,0x00为首地址 GETF -find &SMBIOSTableData,(%&data_offset% + %&Type_Start%)###0#1#0,&&Type_End,*&&TypeKeyWords //MESS %&Type_End% IFEX $%&Type_End%=-1,EXIT LOOP CALC &&Type_Start=%&Type_End% + 2 //尾部加上两个字节的0x00 0x00 //MESS aaa IFEX [ #%&type%=17 & $%&SMBIOS_Version%>=2.0 ], {* CALC &BIOS_INFO_Len=%&Type_Start% - %&data_offset% - %&Type_Start_Last% //字符串区的长度 GETF -find &SMBIOSTableData,(%&Type_Start_Last% + %&data_offset% )#%&BIOS_INFO_Len%##0#1#0,*&&BIOS_INFO_CharKeyWords,*&&CharKeyWords CALL Memory_Manufacturer &&Memory_vendor CALL Memory_Size &&Size CALL Memory_SerialNumber &&SerialNumber CALL Memory_PartNumber &&PartNumber CALL Memory_MemoryType &&MemoryType CALL Memory_Speed &&Speed MESS. \%&NL%品牌:%&Memory_vendor% \%&NL%大小:%&&Size% \%&NL%序列号:%&&SerialNumber% \%&NL%零件号:%&&PartNumber% \%&NL%内存类型:%&&MemoryType% \%&NL%速度:%&&Speed% } } _SUB Memory_Speed * //MESS %&Type_Start_Last% SET?wchar &SMBIOSTableData=&Speed:( %&Type_Start_Last% + 0x15 ) CALC &Speed=%&Speed% ENVI-ret %1=%&Speed% _END _SUB Memory_MemoryType * SET?char &SMBIOSTableData=&MemoryType:( %&Type_Start_Last% + 0x12 ) IFEX $%&MemoryType%=0x1A,ENVI &MemoryType=DDR4 IFEX $%&MemoryType%=0x18,ENVI &MemoryType=DDR3 IFEX $%&MemoryType%=0x13,ENVI &MemoryType=DDR2 IFEX $%&MemoryType%=0x12,ENVI &MemoryType=DDR IFEX $%&MemoryType%=0x1B,ENVI &MemoryType=LPDDR IFEX $%&MemoryType%=0x1C,ENVI &MemoryType=LPDDR2 IFEX $%&MemoryType%=0x1D,ENVI &MemoryType=LPDDR3 IFEX $%&MemoryType%=0x1E,ENVI &MemoryType=LPDDR4 IFEX $%&MemoryType%=0x23,ENVI &MemoryType=LPDDR5 ENVI-ret %1=%&MemoryType% _END _SUB Memory_PartNumber * GETF &SMBIOSTableData,( %&Type_Start_Last% + 0x1A )#1,&&PartNumber_CharNum CALL Get_Split_Dmi_Info "%&PartNumber_CharNum%" "%&BIOS_INFO_CharKeyWords%" &&PartNumber ENVI-ret %1=%&&PartNumber% _END _SUB Memory_SerialNumber * GETF &SMBIOSTableData,( %&Type_Start_Last% + 0x18 )#1,&&SerialNumber_CharNum CALL Get_Split_Dmi_Info "%&SerialNumber_CharNum%" "%&BIOS_INFO_CharKeyWords%" &&SerialNumber ENVI-ret %1=%&&SerialNumber% _END _SUB Memory_Size * //MESS %&Type_Start_Last% SET?wchar &SMBIOSTableData=&Size:( %&Type_Start_Last% + 0x0C ) CALC &Size=%&Size% ENVI-ret %1=%&Size% _END _SUB Memory_Manufacturer * GETF &SMBIOSTableData,( %&Type_Start_Last% + 0x17 )#1,&&BIOS_vendor_CharNum CALL Get_Split_Dmi_Info "%&BIOS_vendor_CharNum%" "%&BIOS_INFO_CharKeyWords%" &&Memory_vendor ENVI-ret %1=%&&Memory_vendor% _END _SUB Get_Split_Dmi_Info ^ENVI &&CharNum=%~1 //字符串区域的第几个字符串>=1 //MESS aaa IFEX $%&&CharNum%=0, {* EXIT } ^ENVI &&This_CharKeyWords=%&pdata_offset% %~2 //MESS %&&This_CharKeyWords% CALC &&NextCharNum=%&&CharNum% + 1 MSTR &&Start,&&End=<%&&CharNum%><%&&NextCharNum%>%&&This_CharKeyWords% GETF &SMBIOSTableData,( %&&Start% + 1 )#( %&&End% - %&&Start%),&&This_Info CODE ***ANSI,&&This_Info,**UNI,&&This_Info MSTR * -trim &This_Info=&This_Info //MESS %&&This_Info% ENVI-ret %3=%&This_Info% _END EXIT FILE 结构体 struct RawSMBIOSData { BYTE Used20CallingMethod; //1b BYTE SMBIOSMajorVersion; //1b BYTE SMBIOSMinorVersion; //1b BYTE DmiRevision; //1b DWORD Length; //4b BYTE SMBIOSTableData[]; //Length b };
这是内存信息,根据我自己的习惯把红毛代码稍微改了改,其他信息查阅文档计算偏移量就行
从注册表读取(信息可能会有一些缺失):
ENVI^ ENVIMODE=1 ENVI$ &NL=0d 0a REGI .HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\mssmbios\Data\\SMBiosData,&&smbios SET$# &SMBIOSTableData=%&&smbios% SET$# &type=*1 0 //申请1个字节的内存空间,定义一个变量,作为类型变量 SET$# &data_offset=*1 0 //申请1个字节的内存空间,定义一个变量,作为类型(格式区)长度 ENVI &&Type_Start=0 //定义一个变量,作为当前类型的起始位置值的标记 CODE *ANSI,0x00 0x00,**ANSI,&&TypeKeyWords CODE *ANSI,0x00,**ANSI,&&CharKeyWords LOOP #%&Type_Start%>=0, {* //SET-zero PE变量名=[[$]数值][@[$]偏移]][;[$]数量] //清除变量的内存,默认0 $:加宽,可多次 SET-zero type= SET-zero data_offset= SET?char SMBIOSTableData=&type:%&&Type_Start% ENVI &&Type_Start_Last=%&Type_Start% //上一个类型的结束位置 SET?char SMBIOSTableData=&data_offset:(%&Type_Start% + 1) CALC &data_offset=%&data_offset% //MESS &data_offset=%&data_offset% CALC &pdata_offset=%&data_offset%-1 //格式区结束地址,0x00为首地址 GETF -find &SMBIOSTableData,(%&data_offset% + %&Type_Start%)###0#1#0,&&Type_End,*&&TypeKeyWords //MESS %&Type_End% IFEX $%&Type_End%=-1,EXIT LOOP CALC &&Type_Start=%&Type_End% + 2 //尾部加上两个字节的0x00 0x00 //MESS aaa IFEX #%&type%=17, {* CALC &BIOS_INFO_Len=%&Type_Start% - %&data_offset% - %&Type_Start_Last% //字符串区的长度 GETF -find &SMBIOSTableData,(%&Type_Start_Last% + %&data_offset% )#%&BIOS_INFO_Len%##0#1#0,*&&BIOS_INFO_CharKeyWords,*&&CharKeyWords CALL Memory_Manufacturer &&Memory_vendor CALL Memory_Size &&Size CALL Memory_SerialNumber &&SerialNumber CALL Memory_PartNumber &&PartNumber CALL Memory_MemoryType &&MemoryType CALL Memory_Speed &&Speed MESS. \%&NL%品牌:%&Memory_vendor% \%&NL%大小:%&&Size% \%&NL%序列号:%&&SerialNumber% \%&NL%零件号:%&&PartNumber% \%&NL%内存类型:%&&MemoryType% \%&NL%速度:%&&Speed% } } _SUB Memory_Speed * //MESS %&Type_Start_Last% SET?wchar &SMBIOSTableData=&Speed:( %&Type_Start_Last% + 0x15 ) CALC &Speed=%&Speed% ENVI-ret %1=%&Speed% _END _SUB Memory_MemoryType * SET?char &SMBIOSTableData=&MemoryType:( %&Type_Start_Last% + 0x12 ) IFEX $%&MemoryType%=0x1A,ENVI &MemoryType=DDR4 IFEX $%&MemoryType%=0x18,ENVI &MemoryType=DDR3 IFEX $%&MemoryType%=0x13,ENVI &MemoryType=DDR2 IFEX $%&MemoryType%=0x12,ENVI &MemoryType=DDR IFEX $%&MemoryType%=0x1B,ENVI &MemoryType=LPDDR IFEX $%&MemoryType%=0x1C,ENVI &MemoryType=LPDDR2 IFEX $%&MemoryType%=0x1D,ENVI &MemoryType=LPDDR3 IFEX $%&MemoryType%=0x1E,ENVI &MemoryType=LPDDR4 IFEX $%&MemoryType%=0x23,ENVI &MemoryType=LPDDR5 ENVI-ret %1=%&MemoryType% _END _SUB Memory_PartNumber * GETF &SMBIOSTableData,( %&Type_Start_Last% + 0x1A )#1,&&PartNumber_CharNum CALL Get_Split_Dmi_Info "%&PartNumber_CharNum%" "%&BIOS_INFO_CharKeyWords%" &&PartNumber ENVI-ret %1=%&&PartNumber% _END _SUB Memory_SerialNumber * GETF &SMBIOSTableData,( %&Type_Start_Last% + 0x18 )#1,&&SerialNumber_CharNum CALL Get_Split_Dmi_Info "%&SerialNumber_CharNum%" "%&BIOS_INFO_CharKeyWords%" &&SerialNumber ENVI-ret %1=%&&SerialNumber% _END _SUB Memory_Size * //MESS %&Type_Start_Last% SET?wchar &SMBIOSTableData=&Size:( %&Type_Start_Last% + 0x0C ) CALC &Size=%&Size% ENVI-ret %1=%&Size% _END _SUB Memory_Manufacturer * GETF &SMBIOSTableData,( %&Type_Start_Last% + 0x17 )#1,&&BIOS_vendor_CharNum CALL Get_Split_Dmi_Info "%&BIOS_vendor_CharNum%" "%&BIOS_INFO_CharKeyWords%" &&Memory_vendor ENVI-ret %1=%&&Memory_vendor% _END _SUB Get_Split_Dmi_Info ^ENVI &&CharNum=%~1 //字符串区域的第几个字符串>=1 //MESS aaa IFEX $%&&CharNum%=0, {* EXIT } ^ENVI &&This_CharKeyWords=%&pdata_offset% %~2 //MESS %&&This_CharKeyWords% CALC &&NextCharNum=%&&CharNum% + 1 MSTR &&Start,&&End=<%&&CharNum%><%&&NextCharNum%>%&&This_CharKeyWords% GETF &SMBIOSTableData,( %&&Start% + 1 )#( %&&End% - %&&Start%),&&This_Info CODE ***ANSI,&&This_Info,**UNI,&&This_Info MSTR * -trim &This_Info=&This_Info //MESS %&&This_Info% ENVI-ret %3=%&This_Info% _END
123 为什么粘贴代码直接就乱了 ENVI^ ENVIMODE=1 ENVI$ &NL=0d 0a //转换RSMB为DWORD----开始 CODE *,RSMB,*-ANSI,&F ...
粘贴代码可以用“插入/编辑代码示例”功能
caocaofff 粘贴代码可以用“插入/编辑代码示例”功能
原来是点这个,我用错了,点的第一个
123 从注册表读取(信息可能会有一些缺失): ENVI^ ENVIMODE=1ENVI$ &NL=0d 0aREGI .HKEY_LOCAL_MACHINE\SYSTEM\CurrentC ...
从注册表读取的这段,没获取到序列号,为啥呢?
anson4 从注册表读取的这段,没获取到序列号,为啥呢?
具体我也没看,反正从注册表和api读取的原始结构都不一样,api读取的开头就是bios信息,注册表读取的直接就没有bios信息,其他的我也没细看
123 具体我也没看,反正从注册表和api读取的原始结构都不一样,api读取的开头就是bios信息,注册表读取的直接就没有bios信息,其他的我也没细看
好的,谢谢!
API有个缺点,就是在XP下用不了。
支持64位的
123 支持64位的
32 位的 XP 偶尔还能遇到使用的,64 位的没遇到过。
123 从注册表读取(信息可能会有一些缺失): ENVI^ ENVIMODE=1 ENVI$ &NL=0d 0a REGI .HKEY_LOCAL_MACHINE\SYSTEM\Curr ...
我建议你到源码分享区开个帖子,方便别人搜索。
527104427 我建议你到源码分享区开个帖子,方便别人搜索。
好的