doc/index.rst | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
doc/other/CREDITS.md | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/inspector/inspector.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/library/os/CMakeLists.txt | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/library/os/dmi_info.hpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/library/os/windows/dmi_info.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
src/library/os/windows/smbios.hpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
test/library/os/dmi_info_test.cpp | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
doc/index.rst
@@ -46,7 +46,7 @@ ******************* The software is made by 4 main sub-components: * `licensecc` : the C++ library with a C api (the part you have to integrate in your software) with minimal (or no) external dependencies. This is the project you're currently looking at. * ``licensecc`` : the C++ library with a C api (the part you have to integrate in your software) with minimal (or no) external dependencies. This is the project you're currently looking at. * ``lccinspector`` : a license debugger to be sent to the final customer to diagnose licensing problems or for calculating the hardware id before issuing the license. * ``lccgen`` : a license generator (github project `lcc-license-generator`_ ) to initialize the library and generate the licenses. * ``examples`` : usage samples (github project `examples <https://github.com/open-license-manager/examples>`_ ). doc/other/CREDITS.md
@@ -1,5 +1,5 @@ # Credits The following open source code has been used in OpenLicenseManager. The following open source code has been used in licensecc. Thanks to every one of the authors of such projects. Without you open license manager would never have been released. ## [inja](https://github.com/pantor/inja) @@ -9,11 +9,10 @@ Copyright (c) 2013-2017 Niels Lohmann ## [isVM](https://github.com/0of/isvm) ## [hwid generation](https://github.com/789sdf987s/hwid_generation) Thanks for the great smbios parsing code. It saved me days. MIT License Copyright (c) 2015 Magnus ## [SimpleIni](https://github.com/brofield/simpleini) src/inspector/inspector.cpp
@@ -127,7 +127,9 @@ license::os::DmiInfo dmi_info; cout << "Bios vendor :" << dmi_info.bios_vendor() << endl; cout << "Bios description :" << dmi_info.bios_description() << endl; cout << "System vendor :" << dmi_info.sys_vendor() << endl << endl; cout << "System vendor :" << dmi_info.sys_vendor() << endl; cout << "Cpu Vendor (dmi) :" << dmi_info.cpu_manufacturer() << endl; cout << "Cpu Cores (dmi) :" << dmi_info.cpu_cores() << endl; cout << "==================" << endl; if (argc == 2) { const string fname(argv[1]); src/library/os/CMakeLists.txt
@@ -16,7 +16,6 @@ openssl/signature_verifier.cpp execution_environment_common.cpp windows/execution_environment.cpp windows/isvm/BIOSReader.cpp windows/os_win.cpp windows/network.cpp) ENDIF(UNIX) @@ -29,7 +28,6 @@ windows/signature_verifier.cpp execution_environment_common.cpp windows/execution_environment.cpp windows/isvm/BIOSReader.cpp windows/os_win.cpp windows/network.cpp) ENDIF(UNIX OR OPENSSL_FOUND) src/library/os/dmi_info.hpp
@@ -17,6 +17,8 @@ std::string m_sys_vendor; std::string m_bios_vendor; std::string m_bios_description; std::string m_cpu_manufacturer; unsigned int m_cpu_cores = 0; public: DmiInfo(); @@ -24,6 +26,9 @@ const std::string& bios_vendor() const { return m_bios_vendor; }; const std::string& sys_vendor() const { return m_sys_vendor; }; const std::string& bios_description() const { return m_bios_description; }; // Only Windows const std::string& cpu_manufacturer() const { return m_cpu_manufacturer; }; const unsigned int cpu_cores() const { return m_cpu_cores; }; }; } // namespace os src/library/os/windows/dmi_info.cpp
@@ -5,19 +5,98 @@ * Author: devel */ #include "isvm/BIOSReader.h" #include "smbios.hpp" #include "../../base/string_utils.h" #include "../dmi_info.hpp" namespace license { namespace os { using namespace smbios; //#pragma pack() struct RawSMBIOSData { BYTE Used20CallingMethod; BYTE SMBIOSMajorVersion; BYTE SMBIOSMinorVersion; BYTE DmiRevision; DWORD Length; //BYTE SMBIOSTableData[1]; }; bool readSMBIOS(std::vector<uint8_t> &buffer) { const DWORD tableSignature = ('R' << 24) | ('S' << 16) | ('M' << 8) | 'B'; bool can_read = false; uint32_t size = GetSystemFirmwareTable(tableSignature, 0, NULL, 0); if (size > 0) { buffer.resize(size); if (GetSystemFirmwareTable(tableSignature, 0, buffer.data(), size) > 0) { can_read = true; } } return can_read; } DmiInfo::DmiInfo() { BIOSReader reader; SystemInformation info = reader.readSystemInfo(); m_sys_vendor = toupper_copy(info.Manufacturer); m_bios_vendor = toupper_copy(info.ProductName); m_bios_description = toupper_copy(info.SysVersion) + toupper_copy(info.family); std::vector<uint8_t> raw_smbios_data; if (readSMBIOS(raw_smbios_data)) { smbios::parser smbios_parser; RawSMBIOSData *rawData = reinterpret_cast<RawSMBIOSData *>(raw_smbios_data.data()); size_t length = static_cast<size_t>(rawData->Length); uint8_t* buff= raw_smbios_data.data() + sizeof(RawSMBIOSData); smbios_parser.feed(buff, length); for (auto &header : smbios_parser.headers) { string_array_t strings; parser::extract_strings(header, strings); switch (header->type) { case types::baseboard_info: { auto *const x = reinterpret_cast<baseboard_info *>(header); if (x->length == 0) break; if (x->manufacturer_name > 0 && x->manufacturer_name < x->length) { m_sys_vendor = strings[x->manufacturer_name]; } } break; case types::bios_info: { auto *const x = reinterpret_cast<bios_info *>(header); if (x->length == 0) break; if (x->vendor > 0 && x->vendor < x->length) { m_bios_vendor = strings[x->vendor]; } } break; case types::processor_info: { auto *const x = reinterpret_cast<proc_info *>(header); if (x->length == 0) break; if (x->manufacturer > 0 && x->manufacturer < x->length) { m_cpu_manufacturer = strings[x->manufacturer]; } m_cpu_cores = static_cast<unsigned int>(x->cores); } break; case types::system_info: { auto *const x = reinterpret_cast<system_info *>(header); if (x->length == 0) break; if (x->manufacturer > 0 && x->manufacturer<x->length && x-> product_name > 0 && x->product_name < x->length) { m_bios_description = std::string(strings[x->manufacturer]) + std::string(strings[x->product_name]); } } break; default:; } } //smbios_parser.clear(); } else { } } } } /* namespace license */ src/library/os/windows/smbios.hpp
New file @@ -0,0 +1,397 @@ /** * Credits to: * https://github.com/789sdf987s/hwid_generation */ #ifndef SMBIOS_H #define SMBIOS_H #pragma once #include <Windows.h> #include <cstdint> #include <vector> namespace smbios { namespace types { enum { bios_info = 0, // Required system_info = 1, // Required baseboard_info = 2, module_info = 2, system_enclosure = 3, // Required system_chassis = 3, // Required processor_info = 4, // Required memory_controller_info = 5, // Obsolete memory_module_info = 6, // Obsolete cache_info = 7, // Required port_connector_info = 8, system_slots = 9, // Required onboard_device_info = 10, // Obsolete oem_strings = 11, system_config_options = 12, language_info = 13, group_associations = 14, system_event_log = 15, memory_array = 16, // Required memory_device = 17, // Required memory_error_info_32_bit = 18, memory_array_mapped_addr = 19, // Required memory_device_mapped_addr = 20, builtin_pointing_device = 21, portable_battery = 22, system_reset = 23, hardware_security = 24, system_power_controls = 25, voltage_probe = 26, cooling_device = 27, temperature_probe = 28, electrical_current_probe = 29, out_of_band_remote_access = 30, bis_entry_point = 31, // Required system_boot_info = 32, // Required memory_error_info_64_bit = 33, management_device = 34, management_device_component = 35, management_device_threshold = 36, memory_channel = 37, ipmi_device_info = 38, system_power_supply = 39, additional_info = 40, onboard_device_extinfo = 41, management_controller_host = 42, inactive = 126, end_of_table = 127, // Always last structure }; } typedef uint8_t byte_t; typedef uint16_t word_t; typedef uint32_t dword_t; #ifdef _MSC_VER typedef __int64 qword_t; #else #ifdef INT64_C typedef uint64_t qword_t; #else typedef (unsigned long long int) qwordt_t; #endif #endif typedef byte_t str_id; typedef byte_t enum_t; typedef std::vector<char*> string_array_t; struct header; #pragma pack(push, 1) struct raw_smbios_data { BYTE used20_calling_method; BYTE smbios_major_version; BYTE smbios_minor_version; BYTE dmi_revision; DWORD length; BYTE smbios_table_data[1]; }; struct header { byte_t type; byte_t length; word_t handle; }; struct string_list: header { byte_t count; }; struct baseboard_info: header { byte_t manufacturer_name; byte_t product_name; byte_t version; byte_t serial_number; byte_t product; byte_t version1; byte_t serial_number1; }; struct bios_info: header { // 2.0 str_id vendor; str_id version; word_t starting_segment; str_id release_date; byte_t rom_size; qword_t characteristics; // 2.4 byte_t ext_char1; byte_t ext_char2; byte_t sb_major; byte_t sb_minor; byte_t ec_major; byte_t ec_minor; }; struct system_info: header { // 2.0 str_id manufacturer; str_id product_name; str_id version; str_id serial_number; // 2.1 struct { dword_t time_low; word_t time_mid; word_t time_hi_and_version; byte_t clock_seq_hi_and_reserved; byte_t clock_seq_low; byte_t node[6]; } uuid; enum_t wakeup_type; // 2.4 str_id sku; str_id family; }; struct system_chassis: header { // 2.0 str_id manufacturer; byte_t type; str_id version; str_id serial_number; str_id assert_tag; // 2.1 enum_t bootup_state; enum_t power_supply_state; enum_t thermal_state; enum_t security_status; // 2.3 dword_t oem; byte_t height; byte_t cords; }; struct proc_info: header { // 2.0 str_id socket_designation; enum_t type; enum_t family; str_id manufacturer; qword_t id; str_id version; byte_t voltage; word_t clock; word_t speed_max; word_t speed_cur; byte_t status; enum_t upgrade; // 2.1 word_t l1; word_t l2; word_t l3; // 2.3 str_id serial_number; str_id assert_tag; str_id part_number; // 2.5 byte_t cores; byte_t cores_enabled; byte_t threads; word_t characteristics; enum_t family2; }; struct cache_info: header { // 2.0 str_id socket_designation; word_t config; word_t size_max; word_t size_cur; word_t sram_supported; word_t sram_cur; // 2.1 byte_t speed; enum_t error_correction_type; enum_t system_cache_type; enum_t associativity; }; struct slot: header { // 2.0 str_id slot_designation; enum_t type; enum_t data_bus_width; enum_t current_usage; enum_t length; word_t id; byte_t characteristics; // 2.1 byte_t characteristics2; // 2.6 word_t segment_group; byte_t bus; byte_t device; }; typedef string_list oem_strings; typedef string_list system_config_options; struct lang_info: header { byte_t installed_langs; byte_t flags; byte_t reserved[15]; str_id current_lang; }; struct mem_arr: header { // 2.1 enum_t location; enum_t use; enum_t error_correction; dword_t capacity; word_t error_info_handle; word_t devices_number; // 2.7 qword_t capacity_ext; }; struct mem_device: header { // 2.1 word_t mem_arr_handle; word_t mem_arr_error_info_handle; word_t total_width; word_t data_width; word_t size; enum_t form_factor; byte_t device_set; str_id device_locator; str_id bank_locator; enum_t type; word_t type_detail; // 2.3 word_t speed; str_id manufacturer; str_id serial_number; str_id assert_tag; str_id part_number; // 2.6 byte_t attributes; // 2.7 dword_t size_ext; word_t clock_speed; // 2.8 word_t voltage_min; word_t voltage_max; word_t voltage; }; #pragma pack(pop) class parser final { public: parser() = default; parser(const parser &x) { feed(x.raw_data_, x.raw_size_); } ~parser() { clear(); } std::vector<header*> headers; static byte_t* skip(byte_t*); static header* extract_strings(header*, string_array_t&); void feed(const void *raw_smbios, size_t size); void clear(); protected: byte_t *raw_data_ { }; size_t raw_size_ { }; }; inline byte_t* parser::skip(byte_t *x) { auto *ptr = x + reinterpret_cast<header*>(x)->length; size_t len; if (*ptr == 0) ptr += 2; else do { len = strlen(reinterpret_cast<const char*>(ptr)); ptr += len + 1; } while (len > 0); return ptr; } inline header* parser::extract_strings(header *x, string_array_t &a) { auto *ptr = reinterpret_cast<byte_t*>(x) + x->length; a.clear(); a.push_back(nullptr); if (*ptr == 0) ptr += 2; else for (;;) { auto *str = reinterpret_cast<char*>(ptr); const auto len = strlen(str); ptr += len + 1; if (len == 0) break; a.push_back(str); } return reinterpret_cast<header*>(ptr); } inline void parser::feed(const void *raw_smbios, const size_t size) { clear(); raw_size_ = size; raw_data_ = new byte_t[raw_size_]; memcpy(raw_data_, raw_smbios, size); auto *x = raw_data_; while (static_cast<size_t>(x - raw_data_) < raw_size_) { headers.push_back(reinterpret_cast<header*>(x)); x = skip(x); } } inline void parser::clear() { headers.clear(); delete[] raw_data_; raw_size_ = 0; } } // namespace smbios #endif test/library/os/dmi_info_test.cpp
@@ -12,13 +12,11 @@ BOOST_AUTO_TEST_CASE(dmi_info) { os::DmiInfo dmiInfo; //windows bug #ifdef __unix__ BOOST_CHECK_MESSAGE(dmiInfo.bios_vendor().size()>0, "Bios vendor OK"); BOOST_CHECK_MESSAGE(dmiInfo.bios_description().size() > 0, "Bios description OK"); BOOST_CHECK_MESSAGE(dmiInfo.sys_vendor().size() > 0, "Sys vendor OK"); #endif } } // namespace test