From 36ce07093b68b07513149577c209ae7a57ab356b Mon Sep 17 00:00:00 2001 From: Gabriele Contini <contini.mailing@gmail.com> Date: 周日, 15 3月 2020 16:26:21 +0800 Subject: [PATCH] Merge branch 'feature/pc_identifiers' into develop issues #2 #3 #14 #49 --- src/library/os/windows/isvm/BIOSReader.cpp | 121 ++++++++++++++++++++++++++++++++++++++++ 1 files changed, 121 insertions(+), 0 deletions(-) diff --git a/src/library/os/windows/isvm/BIOSReader.cpp b/src/library/os/windows/isvm/BIOSReader.cpp new file mode 100644 index 0000000..3300964 --- /dev/null +++ b/src/library/os/windows/isvm/BIOSReader.cpp @@ -0,0 +1,121 @@ +#include "BIOSReader.h" + +#include <cstdint> + +#include "Native.h" + +struct smbios_structure_header { + uint8_t type; + uint8_t length; + uint16_t handle; +}; + +// +// System information +// +struct smbios_type_1 { + struct smbios_structure_header header; + uint8_t manufacturer_str; + uint8_t product_name_str; + uint8_t version_str; + uint8_t serial_number_str; + uint8_t uuid[16]; + uint8_t wake_up_type; + uint8_t sku_number_str; + uint8_t family_str; +}; + +#define _TYPE_COUNT1 6 + +#define _CONCATE(x, y) x##y +#define CONCATE(x, y) _CONCATE(x, y) +#define TYPE_COUNT(t) CONCATE(_TYPE_COUNT, t) + +// +// Windows +// +#include <windows.h> +#include <tchar.h> + +int8_t *parse_smbiod_content(int8_t *addr, int8_t **indexes, int32_t *count) { + //! ignore 0 + int8_t parsed_count = 0; + int8_t *raw_addr = addr; + + //! first one + if (indexes) *indexes = raw_addr; + + bool reach_terminal = false; + + while (true) { + if (0 == *raw_addr++) { + if (reach_terminal) + break; + else { + ++parsed_count; + + if (count && parsed_count < *count) { + if (indexes) *(indexes + parsed_count) = raw_addr; + } + + reach_terminal = true; + } + } else { + reach_terminal = false; + continue; + } + } + + if (count) *count = parsed_count; + + return raw_addr; +} + +void read_smbios_type_1(int8_t *addr, SystemInformation *info) { + smbios_type_1 *t1 = (smbios_type_1 *)addr; + + int32_t offset = ((0x0F) & (t1->header.length >> 4)) * 16 + (t1->header.length & 0x0F); + + int8_t *string_addr[TYPE_COUNT(1)] = {0}; + + int32_t count = TYPE_COUNT(1); + parse_smbiod_content((int8_t *)t1 + offset, string_addr, &count); + + if (0 != t1->manufacturer_str) + info->Manufacturer = (std::string::traits_type::char_type *)string_addr[t1->manufacturer_str - 1]; + + if (0 != t1->product_name_str) + info->ProductName = (std::string::traits_type::char_type *)string_addr[t1->product_name_str - 1]; + + if (0 != t1->serial_number_str) + info->SerialNum = (std::string::traits_type::char_type *)string_addr[t1->serial_number_str - 1]; + + if (0 != t1->version_str) + info->SysVersion = (std::string::traits_type::char_type *)string_addr[t1->version_str - 1]; + + if (0 != t1->family_str) info->family = (std::string::traits_type::char_type *)string_addr[t1->family_str - 1]; +} + +SystemInformation BIOSReader::readSystemInfo() { + SystemInformation info; + + uint32_t size = 0; + RawSMBIOSData *data = (RawSMBIOSData *)(LocateSMBIOS(&size)); + + if (NULL == data || 0 == size) return info; + + smbios_structure_header *header = (smbios_structure_header *)(data->SMBIOSTableData); + + while (NULL != header) { + if (1 == header->type) { + read_smbios_type_1((int8_t *)header, &info); + header = NULL; //! stop + } else { + int32_t offset = ((0x0F) & (header->length >> 4)) * 16 + (header->length & 0x0F); + header = (smbios_structure_header *)parse_smbiod_content((int8_t *)header + offset, NULL, NULL); + } + } + + free(data); + return info; +} -- Gitblit v1.9.1