MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Как узнать основные характеристики ПЭВМ?"
Answer 753935
В языке С (без плюсов), для получения информации о железе наверное проще всего брать информацию прямо из таблицы SMBIOS, возвращаемой функцией
GetSystemFirmwareTable
.Возьмем отсюда библиотеку для разбора SMBIOS:
// SMBIOS Table Type numbers #define SMB_TABLE_BIOS 0 #define SMB_TABLE_SYSTEM 1 #define SMB_TABLE_BASEBOARD 2 #define SMB_TABLE_CHASSIS 3 #define SMB_TABLE_PROCESSOR 4 #define SMB_TABLE_MEMCTRL 5 #define SMB_TABLE_MEMMODULES 6 #define SMB_TABLE_PORTS 8 #define SMB_TABLE_SLOTS 9 #define SMB_TABLE_OEM_STRINGS 11 #define SMB_TABLE_SYS_CFG_OPTIONS 12 #define SMB_TABLE_MEM_ARRAY 16 #define SMB_TABLE_MEM_DEVICE 17 #define SMB_TABLE_END_OF_TABLE 127 // CPU registers returned by __cpuid() #define EAX 0 #define EBX 1 #define ECX 2 #define EDX 3 // Virtualization platform providers #define VIRT_PLATFORM_NONE 0 #define VIRT_PLATFORM_VMWARE 1 #define VIRT_PLATFORM_VBOX 2 #define VIRT_PLATFORM_QEMU 3 #define VIRT_PLATFORM_KVM 4 #define VIRT_PLATFORM_MSVPC 5 #define VIRT_PLATFORM_HYPERV 6 #define VIRT_PLATFORM_XEN 7 #define VIRT_PLATFORM_VTZO 8 #define VIRT_PLATFORM_PARA 9 // 64bit Word type typedef unsigned long long QWORD; /* * Structures */ typedef struct _RawSmbiosData { BYTE Used20CallingMethod; BYTE SMBIOSMajorVersion; BYTE SMBIOSMinorVersion; BYTE DmiRevision; DWORD Length; BYTE SMBIOSTableData[1]; } RAW_SMBIOS_DATA, * PRAW_SMBIOS_DATA; typedef struct _SmbiosStructHeader { BYTE Type; BYTE Length; WORD Handle; } SMBIOS_STRUCT_HEADER, *PSMBIOS_STRUCT_HEADER; // Structures typedef struct _NODE { wchar_t *Name; // Name of the node struct _NODE_ATT_LINK *Attributes; // Array of attributes linked to the node struct _NODE *Parent; // Parent node struct _NODE_LINK *Children; // Array of linked child nodes int Flags; // Node configuration flags } NODE, * PNODE; typedef struct _NODE_LINK { struct _NODE *LinkedNode; // Node attached to this node } NODE_LINK, * PNODE_LINK; typedef struct _NODE_ATT { wchar_t *Key; // Attribute name wchar_t *Value; // Attribute value string (may be null separated multistring if NAFLG_ARRAY is set) int Flags; // Attribute configuration flags } NODE_ATT, *PNODE_ATT; typedef struct _NODE_ATT_LINK { struct _NODE_ATT *LinkedAttribute; // Attribute linked to this node } NODE_ATT_LINK, *PNODE_ATT_LINK; /********************************************************************/ PRAW_SMBIOS_DATA GetSmbiosData() { DWORD bufferSize = 0; PRAW_SMBIOS_DATA smbios = NULL; // Get required buffer size bufferSize = GetSystemFirmwareTable('RSMB', 0, NULL, 0); if (bufferSize) { smbios = (PRAW_SMBIOS_DATA)LocalAlloc(LPTR, bufferSize); bufferSize = GetSystemFirmwareTable('RSMB', 0, (PVOID)smbios, bufferSize); } return smbios; } PSMBIOS_STRUCT_HEADER GetNextStructure(PRAW_SMBIOS_DATA smbios,PSMBIOS_STRUCT_HEADER previous) { PSMBIOS_STRUCT_HEADER next = NULL; PBYTE c = NULL; // Return NULL is no data found if (NULL == smbios) return NULL; // Return first table if previous was NULL if (NULL == previous) return (PSMBIOS_STRUCT_HEADER)(&smbios->SMBIOSTableData[0]); // Move to the end of the formatted structure c = ((PBYTE)previous) + previous->Length; // Search for the end of the unformatted structure (\0\0) while (true) { if ('\0' == *c && '\0' == *(c + 1)) { /* Make sure next table is not beyond end of SMBIOS data * (Thankyou Microsoft for ommitting the structure count * in GetSystemFirmwareTable */ if ((c + 2) < ((PBYTE)smbios->SMBIOSTableData + smbios->Length)) return (PSMBIOS_STRUCT_HEADER)(c + 2); else return NULL; // We reached the end } c++; } return NULL; } PSMBIOS_STRUCT_HEADER GetNextStructureOfType(PRAW_SMBIOS_DATA smbios,PSMBIOS_STRUCT_HEADER previous, DWORD type) { PSMBIOS_STRUCT_HEADER next = previous; while (NULL != (next = GetNextStructure(smbios,next))) { if (type == next->Type) return next; } return NULL; } PSMBIOS_STRUCT_HEADER GetStructureByHandle(PRAW_SMBIOS_DATA smbios,WORD handle) { PSMBIOS_STRUCT_HEADER header = NULL; while (NULL != (header = GetNextStructure(smbios,header))) if (handle == header->Handle) return header; return NULL; } LPTSTR GetSmbiosString(PSMBIOS_STRUCT_HEADER table, BYTE index) { DWORD i = 0; DWORD len = 0; LPTSTR unicode = _wcsdup(_T("")); if (0 == index) return unicode; char *c = NULL; for (i = 1, c = (char *)table + table->Length; '\0' != *c; c += strlen(c) + 1, i++) { if (i == index) { LocalFree(unicode); len = MultiByteToWideChar(CP_UTF8, 0, c, -1, NULL, 0); unicode = (LPTSTR)LocalAlloc(LPTR, sizeof(WCHAR)* len); MultiByteToWideChar(CP_UTF8, 0, c, -1, unicode, len); break; } } return unicode; }
Смастерим функции для получения значений по смещению:
//вывод значения числового параметра таблицы SMBIOS по указанному смещению void PrintBiosValue(PRAW_SMBIOS_DATA smbios,DWORD type,DWORD offset) { PSMBIOS_STRUCT_HEADER head; head=NULL; PBYTE cursor = NULL; head = GetNextStructureOfType(smbios,head, type); if (NULL == head){printf("PrintString Error!\n");return;} cursor=((PBYTE)head+offset); // value printf("%d\n",(int)*cursor); } //вывод значения строкового параметра таблицы SMBIOS по указанному смещению void PrintBiosString(PRAW_SMBIOS_DATA smbios,DWORD type,DWORD offset) { PSMBIOS_STRUCT_HEADER head; head=NULL; PBYTE cursor = NULL; LPTSTR unicode = NULL; head = GetNextStructureOfType(smbios,head, type); if (NULL == head){printf("PrintString Error!\n");return;} cursor=((PBYTE)head+offset); BYTE val=*cursor; unicode = GetSmbiosString((head), *cursor); // value wprintf(unicode);printf("\n"); LocalFree(unicode); }
Значения смещений для конкретных параметров можно найти в спецификации SMBIOS.
Для получения размера оперативной памяти, к счастью, есть готовая функцияGetPhysicallyInstalledSystemMemory
.Пример использования:
#include <stdio.h> #include <windows.h> #include <tchar.h> int _tmain(int argc, _TCHAR* argv[]) { PRAW_SMBIOS_DATA data=GetSmbiosData(); if(data==NULL){printf("Can't get data!");goto End;} printf("BIOS vendor: "); PrintBiosString(data,SMB_TABLE_BIOS,4); printf("Motherboard vendor: "); PrintBiosString(data,SMB_TABLE_SYSTEM,4); printf("CPU vendor: "); PrintBiosString(data,SMB_TABLE_PROCESSOR,7); printf("Type: "); PrintBiosValue(data,SMB_TABLE_CHASSIS,5);//Тип компьютера: 3=desktop,9=laptop,A=notebook, ... ULONGLONG memory=0; if(GetPhysicallyInstalledSystemMemory(&memory)==FALSE)printf("Can't get memory!"); else printf("Memory: %llu KB\n",memory); End:system("PAUSE"); return 0; }
Content is retrieved from StackExchange API.
Auto-generated by ruso-archive tools.