gcontini
2020-03-15 6dd7902d6f148a4ac78e5478edb3a2ca8624f74c
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
/*
 * cpu_info.cpp
 *
 *  Created on: Dec 14, 2019
 *      Author: devel
 */
 
#include <cpuid.h>
#include <string>
#include <unordered_set>
#include <memory.h>
#include "../cpu_info.hpp"
 
namespace license {
namespace os {
using namespace std;
 
struct CPUVendorID {
    unsigned int ebx;
    unsigned int edx;
    unsigned int ecx;
 
    string toString() const { return string(reinterpret_cast<const char *>(this), 12); }
};
 
static string get_cpu_vendor() {
    unsigned int level = 0, eax = 0, ebx = 0, ecx = 0, edx = 0;
    // hypervisor flag false, try to get the vendor name, see if it's a virtual cpu
    __get_cpuid(level, &eax, &ebx, &ecx, &edx);
    CPUVendorID vendorID{.ebx = ebx, .edx = edx, .ecx = ecx};
    return vendorID.toString();
}
 
// https://en.wikipedia.org/wiki/CPUID
static string get_cpu_brand() {
    string result;
    uint32_t brand[0x10];
 
    if (!__get_cpuid_max(0x80000004, NULL)) {
        result = "NA";
    } else {
        memset(brand, 0, sizeof(brand));
        __get_cpuid(0x80000002, brand + 0x0, brand + 0x1, brand + 0x2, brand + 0x3);
        __get_cpuid(0x80000003, brand + 0x4, brand + 0x5, brand + 0x6, brand + 0x7);
        __get_cpuid(0x80000004, brand + 0x8, brand + 0x9, brand + 0xa, brand + 0xb);
        result = string(reinterpret_cast<char *>(brand));
    }
    return result;
}
 
CpuInfo::CpuInfo() : m_vendor(get_cpu_vendor()), m_brand(get_cpu_brand()) {}
 
CpuInfo::~CpuInfo() {}
/**
 * Detect Virtual machine using hypervisor bit.
 * @return true if the cpu hypervisor bit is set to 1
 */
bool CpuInfo::is_hypervisor_set() const {
    unsigned int level = 1, eax = 0, ebx = 0, ecx = 0, edx = 0;
    __get_cpuid(level, &eax, &ebx, &ecx, &edx);
 
    bool is_virtual = (((ecx >> 31) & 1) == 1);  // hypervisor flag
    return is_virtual;
}
 
uint32_t CpuInfo::model() const {
    unsigned int level = 1, eax = 0, ebx = 0, ecx = 0, edx = 0;
    __get_cpuid(level, &eax, &ebx, &ecx, &edx);
    // ax bits 0-3 stepping,4-7 model,8-11 family id,12-13 processor type
    //        14-15 reserved, 16-19 extended model, 20-27 extended family, 27-31 reserved
    // bx bits 0-7 brand index
    return (eax & 0x3FFF) | (eax & 0x3FF8000) >> 2 | (ebx & 0xff) << 24;
}
 
}  // namespace os
} /* namespace license */