gcontini
2020-10-31 c8f8e0c1f0a3687539a92169735845814e18c187
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
#include <windows.h>
#include <cstdint>
#include <vector>
#include <stdint.h>
#include "BIOSReader.h"
#include "../../../base/logger.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];
}
 
struct RawSMBIOSData {
    BYTE Used20CallingMethod;
    BYTE SMBIOSMajorVersion;
    BYTE SMBIOSMinorVersion;
    BYTE DmiRevision;
    DWORD Length;
    BYTE SMBIOSTableData[];
};
 
 
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;
}
 
SystemInformation BIOSReader::readSystemInfo() {
    SystemInformation info = {};
    std::vector<uint8_t> buffer;
 
    if (readSMBIOS(buffer)) {
 
        /*RawSMBIOSData *data = (RawSMBIOSData *)(buffer.data());
 
    smbios_structure_header *header = (smbios_structure_header *)(data->SMBIOSTableData);
 
    while (nullptr != header) {
        if (1 == header->type) {
            read_smbios_type_1((int8_t *)header, &info);
            header = nullptr;  //!    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);
        }
         }*/
    } else {
        LOG_DEBUG("Can't read smbios table");
    }
    return info;
}