在获取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.3UCHAR 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 0DWORD 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-getsystemfirmwaretableneedBufferSize = 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 > 0x14DWORD SysVersion=0;DWORD ECVersion=0;
}W_BIOSInfo;typedef struct _W_TYPE_1_
{PWCHAR Manufactor;PWCHAR ProductName;PWCHAR Version;PWCHAR SerialNumber;//pSystem->Header.Length > 0x08UUID SysUUID;//pSystem->Header.Length > 0x19PWCHAR 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 > 0x08PWCHAR LocationInChassis;//pBoard->Header.Length > 0x0BPWCHAR 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 > 0x15quint64 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 != 0PWCHAR Date;//pPB->SN != 0PWCHAR 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/89959755a.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
双击打开 -执行程序: