在获取PE系统中的CPU、主板、内存信息时,发现使用WMI部分信息无法获取,通过gitGub上的DumpSMBIOS完全解决了这个问题,并单独做成了个案例,以下示例和代码都是参考DumpSMBIOS项目
SMBIOS这个数据还是用到的比较少。但是DumpSMBIOS项目有很多方面直接学习借鉴的东西。
目录
- SMBIOS 读取
- 结构体对齐
- 读取SMBIOS数据
- GetSystemFirmwareTable
- WMI
- 自定义结构体 - 实际获取数据结构
- 结构体数据转换
- 参考示例链接
- QT CMD命令行输出
- 其他方法 隐藏控制台窗体
- 可执行程序示例 :
SMBIOS 读取
详见DumpSMBIOS源码,此处只是对修改的部分代码进行一个总结,关键代码的整理
结构体对齐
在DumpSMBIOS示例中,SMBIOS读取的数据有13种类型,每种都对应结构体,并使用
#pragma pack 对齐字节,对齐字节获取数据在Windows API中很常见。
也难怪面试总有人喜欢问数据类型占几个字节的问题,
在通信方面,结构体对齐读取数据流应该方便得多。
#pragma pack(push)
#pragma pack(1)
#define WAKEUP_TYPE_COUNT 9
#define BOARD_TYPE_COUNT 13
typedef struct _RawSMBIOSData
{
BYTE Used20CallingMethod;
BYTE MajorVersion;
BYTE MinorVersion;
BYTE DmiRevision;
DWORD Length;
PBYTE SMBIOSTableData;
} RawSMBIOSData, *PRawSMBIOSData;
typedef struct _SMBIOSHEADER_
{
BYTE Type;
BYTE Length;
WORD Handle;
} SMBIOSHEADER, *PSMBIOSHEADER;
typedef struct _TYPE_0_ {
SMBIOSHEADER Header;
UCHAR Vendor;
UCHAR Version;
UINT16 StartingAddrSeg;
UCHAR ReleaseDate;
UCHAR ROMSize;
ULONG64 Characteristics;
UCHAR Extension[2]; // spec. 2.3
UCHAR MajorRelease;
UCHAR MinorRelease;
UCHAR ECFirmwareMajor;
UCHAR ECFirmwareMinor;
} BIOSInfo, *PBIOSInfo;
typedef struct _TYPE_1_ {
SMBIOSHEADER Header;
UCHAR Manufacturer;
UCHAR ProductName;
UCHAR Version;
UCHAR SN;
UCHAR UUID[16];
UCHAR WakeUpType;
UCHAR SKUNumber;
UCHAR Family;
} SystemInfo, *PSystemInfo;
typedef struct _TYPE_2_ {
SMBIOSHEADER Header;
UCHAR Manufacturer;
UCHAR Product;
UCHAR Version;
UCHAR SN;
UCHAR AssetTag;
UCHAR FeatureFlags;
UCHAR LocationInChassis;
UINT16 ChassisHandle;
UCHAR Type;
UCHAR NumObjHandle;
UINT16 *pObjHandle;
} BoardInfo, *PBoardInfo;
typedef struct _TYPE_3_ {
SMBIOSHEADER Header;
UCHAR Manufacturer;
UCHAR Type;
UCHAR Version;
UCHAR SN;
UCHAR AssetTag;
UCHAR BootupState;
UCHAR PowerSupplyState;
UCHAR ThermalState;
UCHAR SecurityStatus;
ULONG32 OEMDefine;
UCHAR Height;
UCHAR NumPowerCord;
UCHAR ElementCount;
UCHAR ElementRecordLength;
UCHAR pElements;
} SystemEnclosure, *PSystemEnclosure;
typedef struct _TYPE_4_ {
SMBIOSHEADER Header;
UCHAR SocketDesignation;
UCHAR Type;
UCHAR Family;
UCHAR Manufacturer;
ULONG64 ID;
UCHAR Version;
UCHAR Voltage;
UINT16 ExtClock;
UINT16 MaxSpeed;
UINT16 CurrentSpeed;
UCHAR Status;
UCHAR ProcessorUpgrade;
UINT16 L1CacheHandle;
UINT16 L2CacheHandle;
UINT16 L3CacheHandle;
UCHAR SerialNumber;
UCHAR AssertTag;
UCHAR PartNumber;
UCHAR CoreCount;
UCHAR CoreEnabled;
UCHAR ThreadCount;
UINT16 ProcessorCharacteristics;
UINT16 ProcessorFamily2;
} ProcessorInfo, *PProcessorInfo;
typedef struct _TYPE_5_ {
SMBIOSHEADER Header;
// Todo, Here
} MemCtrlInfo, *PMemCtrlInfo;
typedef struct _TYPE_6_ {
SMBIOSHEADER Header;
UCHAR SocketDesignation;
UCHAR BankConnections;
UCHAR CurrentSpeed;
// Todo, Here
} MemModuleInfo, *PMemModuleInfo;
typedef struct _TYPE_7_ {
SMBIOSHEADER Header;
UCHAR SocketDesignation;
UINT16 Configuration;
UINT16 MaxSize;
UINT16 InstalledSize;
UINT16 SupportSRAMType;
UINT16 CurrentSRAMType;
UCHAR Speed;
UCHAR ErrorCorrectionType;
UCHAR SystemCacheType;
UCHAR Associativity;
} CacheInfo, *PCacheInfo;
typedef struct _TYPE_11_ {
SMBIOSHEADER Header;
UCHAR Count;
} OemString, *POemString;
typedef struct _TYPE_17_ {
SMBIOSHEADER Header;
UINT16 PhysicalArrayHandle;
UINT16 ErrorInformationHandle;
UINT16 TotalWidth;
UINT16 DataWidth;
UINT16 Size;
UCHAR FormFactor;
UCHAR DeviceSet;
UCHAR DeviceLocator;
UCHAR BankLocator;
UCHAR MemoryType;
UINT16 TypeDetail;
UINT16 Speed;
UCHAR Manufacturer;
UCHAR SN;
UCHAR AssetTag;
UCHAR PN;
UCHAR Attributes;
} MemoryDevice, *PMemoryDevice;
typedef struct _TYPE_19_ {
SMBIOSHEADER Header;
ULONG32 Starting;
ULONG32 Ending;
UINT16 Handle;
UCHAR PartitionWidth;
} MemoryArrayMappedAddress, *PMemoryArrayMappedAddress;
typedef struct _TYPE_21_ {
SMBIOSHEADER Header;
UCHAR Type;
UCHAR Interface;
UCHAR NumOfButton;
} BuiltinPointDevice, *PBuiltinPointDevice;
typedef struct _TYPE_22_ {
SMBIOSHEADER Header;
UCHAR Location;
UCHAR Manufacturer;
UCHAR Date;
UCHAR SN;
UCHAR DeviceName;
UCHAR Chemistry;
UINT16 DesignCapacity;
UINT16 DesignVoltage;
UCHAR SBDSVersionNumber;
UCHAR MaximumErrorInBatteryData;
UINT16 SBDSSerialNumber;
UINT16 SBDSManufactureDate;
UCHAR SBDSDeviceChemistry;
UCHAR DesignCapacityMultiplie;
UINT32 OEM;
} PortableBattery, *PPortableBattery;
#pragma pack(pop)
读取SMBIOS数据
DumpSMBIOS使用两种方式读取SMBIOS数据
GetSystemFirmwareTable和WMI;
GetSystemFirmwareTable
使用 GetSystemFirmwareTable 函数读取原始 SMBIOS 固件表
void Lib_Smbios::initialization()
{
// GET_SYSTEM_FIRMWARE_TABLE pGetSystemFirmwareTable = (GET_SYSTEM_FIRMWARE_TABLE)GetProcAddress(GetModuleHandle(L"kernel32"), "GetSystemFirmwareTable");
LPBYTE pBuff = NULL;
PBYTE tableStart = nullptr;
UINT nTableLength = 0;
DWORD needBufferSize = 0;
const DWORD Signature = 'RSMB';
#if 0
DWORD Signature = 'R';
Signature = (Signature << 8) + 'S';
Signature = (Signature << 8) + 'M';
Signature = (Signature << 8) + 'B';
#endif
//从固件表提供程序检索指定的固件表。
//https://learn.microsoft.com/zh-cn/windows/win32/api/sysinfoapi/nf-sysinfoapi-getsystemfirmwaretable
needBufferSize = GetSystemFirmwareTable(Signature, 0, NULL, 0);
pBuff = new BYTE[needBufferSize];
needBufferSize = GetSystemFirmwareTable(Signature, 0,pBuff,needBufferSize);
if (needBufferSize > 0) {
const PRawSMBIOSData pDMIData = (PRawSMBIOSData)pBuff;
MajorVersion = pDMIData->MajorVersion;
MinorVersion = pDMIData->MinorVersion;
DMIRevision = pDMIData->DmiRevision;
tableStart = (PBYTE) & (pDMIData->SMBIOSTableData);
nTableLength = pDMIData->Length;
}
if ((0 == needBufferSize) || (nTableLength > needBufferSize))
{
if (getWmiSmbios(&pBuff, &nTableLength))
tableStart = pBuff;
}
if (tableStart)
ParseSMBIOSStruct(tableStart, nTableLength);
if (pBuff)
delete[] pBuff;
}
WMI
使用 WMI 检索 SMBIOS 属性。 Win32 类中包含许多单独的属性。 还可以使用 MSSMBios_RawSMBiosTables 类在单个缓冲区中检索原始 SMBIOS 数据。
bool Lib_Smbios::getWmiSmbios(BYTE ** data, UINT * length)
{
IWbemServices * pSvc = NULL;
IWbemServices * pSvcSmbios = NULL;
IWbemLocator * pLoc = NULL;
HRESULT result;
IEnumWbemClassObject * pEnumerator = NULL;
std::wostringstream query;
std::wstring q;
IWbemClassObject * pInstance = NULL;
VARIANT vtProp;
ULONG uReturn = 0;
CIMTYPE pvtType;
result = CoInitialize(NULL);
if (!SUCCEEDED(result))
return false;
result = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL);
if (!SUCCEEDED(result)) {
CoUninitialize();
return false;
}
result = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&pLoc);
if (!SUCCEEDED(result)) {
CoUninitialize();
return false;
}
result = pLoc->ConnectServer(_bstr_t(L"ROOT\\CIMV2"), NULL, NULL, 0, NULL, 0, 0, &pSvc);
if (!SUCCEEDED(result)) {
pLoc->Release();
CoUninitialize();
return false;
}
result = CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
if (!SUCCEEDED(result)) {
pLoc->Release();
CoUninitialize();
return false;
}
result = pLoc->ConnectServer(_bstr_t(L"ROOT\\WMI"), NULL, NULL, 0, NULL, 0, 0, &pSvcSmbios);
if (!SUCCEEDED(result)) {
pLoc->Release();
CoUninitialize();
return false;
}
result = CoSetProxyBlanket(pSvcSmbios, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
if (!SUCCEEDED(result)) {
pSvcSmbios->Release();
pSvc->Release();
pLoc->Release();
CoUninitialize();
}
result = pSvcSmbios->CreateInstanceEnum(bstr_t(L"MSSMBios_RawSMBiosTables"), 0, NULL, &pEnumerator);
if (SUCCEEDED(result)) {
while (pEnumerator) {
result = pEnumerator->Next(WBEM_INFINITE, 1, &pInstance, &uReturn);
if (!uReturn) {
break;
}
VariantInit(&vtProp);
result = pInstance->Get(bstr_t("SMBiosData"), 0, &vtProp, &pvtType, NULL);
if (SUCCEEDED(result)) {
SAFEARRAY * array = V_ARRAY(&vtProp);
*length = array->rgsabound[0].cElements;
*data = new BYTE[*length];
memcpy(*data, (BYTE*)array->pvData, *length);
VariantClear(&vtProp);
}
}
pEnumerator->Release();
if (pInstance)
pInstance->Release();
}
if (pSvcSmbios)
pSvcSmbios->Release();
if (pSvc)
pSvc->Release();
if (pLoc)
pLoc->Release();
CoUninitialize();
return true;
}
自定义结构体 - 实际获取数据结构
将DumpSMBIOS项目中打印的字段封装成结构体,转换数据时保存,不只是输出内容
#pragma region "获取 SMBIOS 指定数据(指定结构转换)" {
typedef struct _W_TYPE_0_ {
PWCHAR Vendor;
PWCHAR Version;
PWCHAR Date;
//pBIOS->Header.Length > 0x14
DWORD SysVersion=0;
DWORD ECVersion=0;
}W_BIOSInfo;
typedef struct _W_TYPE_1_
{
PWCHAR Manufactor;
PWCHAR ProductName;
PWCHAR Version;
PWCHAR SerialNumber;
//pSystem->Header.Length > 0x08
UUID SysUUID;
//pSystem->Header.Length > 0x19
PWCHAR SysSKU;
PWCHAR SysFamily;
}W_SystemInfo;
typedef struct _W_TYPE_2_
{
PWCHAR Manufacturer;
PWCHAR Product;
PWCHAR Version;
PWCHAR SN;
PWCHAR AssetTag;
UCHAR FeatureFlags;
//pBoard->Header.Length > 0x08
PWCHAR LocationInChassis;
//pBoard->Header.Length > 0x0B
PWCHAR BoardType;
}W_BoardInfo;
typedef struct _W_TYPE_3_
{
PWCHAR Manufacturer;
PWCHAR Version;
PWCHAR SN;
PWCHAR AssetTag;
}W_SystemEnclosure;
typedef struct _W_TYPE_4_
{
PWCHAR SocketDesignation;
PWCHAR ProcessType;
PWCHAR Family;
PWCHAR Manufacturer;
PWCHAR Version;
PWCHAR Voltage;
UINT16 ExtClock;
UINT16 MaxSpeed;
UINT16 CurrentSpeed;
UCHAR Status;
}W_ProcessorInfo;
typedef struct _W_TYPE_6_
{
PWCHAR SocketDesignation;
PWCHAR BankConnections;
quint64 CurrentSpeed;
} W_MemModuleInfo;
typedef struct _W_TYPE_7_
{
PWCHAR SocketDesignation;
} W_CacheInfo;
typedef struct _W_TYPE_11_
{
QList<PWCHAR> datas;
} W_OemString;
typedef struct _W_TYPE_17_
{
quint64 TotalWidth;
quint64 DataWidth;
PWCHAR DeviceLocator;
PWCHAR BankLocator;
PWCHAR MemoryType;
//pMD->Header.Length > 0x15
quint64 Speed;
PWCHAR Manufacturer;
PWCHAR SN;
PWCHAR AssetTag;
PWCHAR PN;
quint64 Size;
} W_MemoryDevice;
typedef struct _W_TYPE_21_
{
PWCHAR BuiltinPointDeviceType;
PWCHAR BuiltinPointDeviceInterface;
quint64 NumOfButton;
} W_BuiltinPointDevice;
typedef struct _W_TYPE_22_
{
PWCHAR Location;
PWCHAR Manufacturer;
//pPB->Date != 0
PWCHAR Date;
//pPB->SN != 0
PWCHAR SN;
PWCHAR DeviceName;
//(pPB->Chemistry != 2)
PWCHAR Chemistry;
PWCHAR SBDSDeviceChemistry;
quint64 DesignCapacity;
quint64 DesignCapacityMultiplie;
quint64 DesignVoltage;
PWCHAR SBDSVersionNumber;
quint64 MaximumErrorInBatteryData;
quint64 SBDSSerialNumber;
} W_PortableBattery;
#pragma endregion }
结构体数据转换
其中需要注意的是 CP_ACP 与 CP_OEMCP 的使用,
测试时使用CP_OEMCP数据乱码,
但是 DumpSMBIOS 项目中使用 CP_OEMCP输出正常,脑壳痛。
static const char* LocateStringA(const char* str, UINT i)
{
static const char strNull[] = "";
if (0 == i || 0 == *str) return strNull;
while (--i)
{
str += strlen((char*)str) + 1;
}
return str;
}
#define GetData(_STR_,_IN_VAL_,_OUT_VAL_,val) \
{ \
const char* c_##val = LocateStringA(_STR_, _IN_VAL_); \
const int n_##val = (int) strlen(c_##val); \
_OUT_VAL_= new WCHAR[n_##val + 1]; \
if (_OUT_VAL_) \
{ \
SecureZeroMemory(_OUT_VAL_, sizeof(WCHAR) * (n_##val + 1)); \
MultiByteToWideChar(CP_ACP, NULL, c_##val, n_##val, _OUT_VAL_, n_##val + 1);\
} \
}
//将UChat转换为PWCHAR数据
bool Lib_Smbios::ProcBIOSInfo(Lib_Smbios* T, void* p)
{
PBIOSInfo pBIOS = (PBIOSInfo)p;
const char* str = toPointString(p);
//后面使用宏定义 GetData 替换此处代码
// const char* Vendor = LocateStringA(str, pBIOS->Vendor);
// const char* Version = LocateStringA(str, pBIOS->Version);
// const char* Date = LocateStringA(str, pBIOS->ReleaseDate);
// const int nVendor = (int) strlen(Vendor);
// const int nVersion = (int) strlen(Version);
// const int nDate = (int) strlen(Date);
// T->DATA_BIOSInfo.Vendor= new WCHAR[nVendor + 1];
// T->DATA_BIOSInfo.Version= new WCHAR[nVersion + 1];
// T->DATA_BIOSInfo.Date= new WCHAR[nDate + 1];
// if (T->DATA_BIOSInfo.Vendor)
// {
// SecureZeroMemory(T->DATA_BIOSInfo.Vendor, sizeof(WCHAR) * (nVendor + 1));
// MultiByteToWideChar(CP_ACP, NULL, Vendor, nVendor, T->DATA_BIOSInfo.Vendor, nVendor + 1);
// }
// if (T->DATA_BIOSInfo.Version)
// {
// SecureZeroMemory(T->DATA_BIOSInfo.Version, sizeof(WCHAR) * (nVersion + 1));
// MultiByteToWideChar(CP_ACP, NULL, Version, nVersion, T->DATA_BIOSInfo.Version, nVersion + 1);
// }
// if (T->DATA_BIOSInfo.Date)
// {
// SecureZeroMemory(T->DATA_BIOSInfo.Date, sizeof(WCHAR) * (nDate + 1));
// MultiByteToWideChar(CP_ACP, NULL, Date, nDate, T->DATA_BIOSInfo.Date, nDate + 1);
// }
GetData(str,pBIOS->Vendor,T->DATA_BIOSInfo.Vendor,Vendor);
GetData(str,pBIOS->Version,T->DATA_BIOSInfo.Version,Version);
GetData(str,pBIOS->ReleaseDate,T->DATA_BIOSInfo.Date,Date);
if (pBIOS->Header.Length > 0x14)
{
T->DATA_BIOSInfo.SysVersion = pBIOS->MajorRelease << 16 | pBIOS->MinorRelease;
T->DATA_BIOSInfo.ECVersion = pBIOS->ECFirmwareMajor << 16 | pBIOS->ECFirmwareMinor;
}
if(Isprint){
_tprintf(TEXT("%s\n"), getHeaderString(0));
_tprintf(TEXT("Vendor: %s\n"), T->DATA_BIOSInfo.Vendor);
_tprintf(TEXT("Version: %s\n"), T->DATA_BIOSInfo.Version);
_tprintf(TEXT("BIOS Starting Segment: 0x%X\n"), pBIOS->StartingAddrSeg);
_tprintf(TEXT("Release Date: %s\n"), T->DATA_BIOSInfo.Date);
_tprintf(TEXT("Image Size: %dK\n"), (pBIOS->ROMSize + 1) * 64);
if (pBIOS->Header.Length > 0x14)
{ // for spec v2.4 and later
_tprintf(TEXT("System BIOS version: %d.%d\n"), pBIOS->MajorRelease, pBIOS->MinorRelease);
_tprintf(TEXT("EC Firmware version: %d.%d\n"), pBIOS->ECFirmwareMajor, pBIOS->ECFirmwareMinor);
}
}
return true;
}
参考示例链接
【SMBIOS数据结构和信息】读取参考示例链接:
https://github.com/KunYi/DumpSMBIOS
SMBIOS获取system bios ec cpu memory等相关信息
SMBIOS 规范定义了将进入与系统相关的数据结构的数据结构和信息
SMBIOS | DMTF规范
QT CMD命令行输出
之前看到某些软件既可以CMD命令行输出数据,又可以打开界面操作的时候,我就尝试过使用QT实现类似的功能。
通过console控制台程序与可执行程序放在同级目录实现,如果argc参数个数大于1就是console打印数据,否则就打开同级目录下的可执行程序,但是这样一来启动的可执行程序的时候始终会有console控制台程序一闪而逝。这个问题始终没有解决、、、
其他方法 隐藏控制台窗体
通过在main.cpp添加这段,确实能隐藏console打开,但是需要的console输出内容就没了,这只适用于隐藏不显示console控制台。
//Qt 隐藏控制台窗体
//#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
通过ShowWindow隐藏控制台也只是加快了隐藏的速度,还是能看见console控制台程序一闪而逝。
HWND consoleWindow = GetConsoleWindow(); // 获取控制台窗口句柄
// 隐藏窗口
ShowWindow(consoleWindow, SW_HIDE);
值得注意的是如果需要打印数据后自动退出程序就需要修改main的返回值
完整示例:
//Qt 隐藏控制台窗体
//#pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
if(argc==1)
{
HWND consoleWindow = GetConsoleWindow(); // 获取控制台窗口句柄
// 隐藏窗口
ShowWindow(consoleWindow, SW_HIDE);
QProcess* process=new QProcess();
process->startDetached("Computer_INFO.exe");
process->waitForStarted(-1);
}
else
{
Lib_Command_Out out;
out.OpeaType(argc, argv);
}
//退出事件循环
//https://blog.csdn.net/qq_21078557/article/details/89959755
a.exit(0);
return 0;
// return a.exec();
}
可执行程序示例 :
CMD输入示例:
SMBIOS数据查询小工具命令行:
================================
*-V 显示命令行参数
-S [-I] [filepath] 打印出SMBIOS的所有详细信息,具体内容参考GitHub上DumpSMBIOS开源项目,
可选参数[-I] 输出INI格式文件 ,
可选参数[filepath] 设置输出路径,没有则默认exe路径中生成[SMBIOS.INI]文件
-D [-I] [filepath] 打印硬盘相关信息[同上可选]
-VS [-I] [filepath] 打印卷/盘符相关信息[同上可选]*
///C:\Users\admin\Desktop\SMBIOS_READ.exe -v 输出:
========== BIOS information ==========
Vendor: American Megatrends Inc.
Version: 1005
BIOS Starting Segment: 0xF000
Release Date: 08/07/2019
Image Size: 16384K
System BIOS version: 5.12
EC Firmware version: 255.255
========== System information ==========
Manufacturer: System manufacturer
Product Name: System Product Name
Version: System Version
Serial Number: System Serial Number
UUID: F9824375-C4FB-4D1E-E715-D45D641D7A2A
Wake-up Type: Power Switch
SKU Number: SKU
Family: To be filled by O.E.M.
========== Base Board information ==========
Length: 0xF
Manufacturer: ASUSTeK COMPUTER INC.
Product Name: PRIME H310M-K R2.0
Version: Rev X.0x
Serial Number: 191262638910697
Asset Tag Number: Default string
Feature Flag: 0x9
Location in Chassis: Default string
Board Type: Processor/Memory Module
Number of Contained Object Handles: 0
Object Handles:
========== System Enclosure information ==========
Length: 0x16
Manufacturer: Default string
Version: Default string
Serial Number: Default string
Asset Tag Number: Default string
========== OEM String ==========
Count: 8
OEM String1: Default string
OEM String2: Default string
OEM String3: OLEANDER V2
OEM String4: Default string
OEM String5: FFFFFFFFFFFFF
OEM String6: FFFFFFFFFFFFF
OEM String7: FFFFFFFFFFFFF
OEM String8: Default string
========== Memory Device ==========
Length: 0x28
Total Width: 64bits
Data Width: 64bits
Device Locator: ChannelA-DIMM1
Bank Locator: BANK 0
Memory Type: DDR4
Size: 8192M
Speed: 2666
Manufacturer: CRUCIAL
Serial Number: 22AD9C80
Asset Tag Number: 9876543210
Part Number: CT8G4DFS8266.M8FE
========== Memory Device ==========
Length: 0x28
Total Width: 64bits
Data Width: 64bits
Device Locator: ChannelB-DIMM1
Bank Locator: BANK 2
Memory Type: DDR4
Size: 8192M
Speed: 2666
Manufacturer: CRUCIAL
Serial Number: 25ACA8B3
Asset Tag Number: 9876543210
Part Number: CT8G4DFS8266.M8FD
========== Memory Array Mapped Address ==========
Length: 0x1F
Starting Address: 0x00000000
Ending Address: 0x00FFFFFF
Memory Array Handle: 0x36
Partition Width: 0x2
========== Cache information ==========
Length: 0x1B
Socket Designation: L1 Cache
========== Cache information ==========
Length: 0x1B
Socket Designation: L2 Cache
========== Cache information ==========
Length: 0x1B
Socket Designation: L3 Cache
========== Processor information ==========
Length: 0x30
Socket Designation: LGA1151
Processor Type: Math Processor
Processor Family:
Processor ID:
Processor Manufacturer: Intel(R) Corporation
Processor Voltage: es|ES|iso8859-1
Processor Version: Intel(R) Core(TM) i5-9400F CPU @ 2.90GHz
External Clock: 100MHz, 0MHz is unknown clock
Max Speed: 8300MHz
Current Speed: 2900MHz
Status: 0x41
双击打开 -执行程序: