Gabriele Contini
2020-02-24 9afdac17dcc8956fd795797bfc5b6e1c09285342
Issues #14 and #6
29个文件已修改
10个文件已添加
2 文件已重命名
4个文件已删除
1888 ■■■■■ 已修改文件
build/.gitkeep 补丁 | 查看 | 原始文档 | blame | 历史
doc/CREDITS.md 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/snippets/hardware.cpp 266 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/inspector/inspector.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/base/CMakeLists.txt 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/base/file_utils.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/base/file_utils.hpp 补丁 | 查看 | 原始文档 | blame | 历史
src/library/hw_identifier/default_strategy.cpp 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/hw_identifier/disk_strategy.cpp 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/hw_identifier/ethernet.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/hw_identifier/hw_identifier.cpp 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/hw_identifier/hw_identifier.hpp 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/hw_identifier/hw_identifier_facade.cpp 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/hw_identifier/identification_strategy.hpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/hw_identifier/pc-identifiers.c 311 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/hw_identifier/pc-identifiers.h 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/ApplicationFolder.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/EnvironmentVarLocation.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/ExternalDefinition.cpp 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/locate/LocatorStrategy.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/CMakeLists.txt 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/cpu_info.hpp 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/cpu_info_common.cpp 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/execution_environment.hpp 25 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/execution_environment_common.cpp 53 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/linux/cpu_info.cpp 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/linux/execution_environment.cpp 34 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/linux/network.cpp 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/os.h 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/windows/.gitignore 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/windows/cpu_info.cpp 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/windows/execution_environment.cpp 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/windows/isvm/BIOSReader.cpp 121 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/windows/isvm/BIOSReader.h 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/windows/isvm/Native.cpp 437 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/windows/isvm/Native.h 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/windows/isvm/main.cpp 51 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/windows/network.cpp 113 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/windows/os-win.c 134 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/library/os/windows/signature_verifier.cpp 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/CMakeLists.txt 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/crack_test.cpp 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/date_test.cpp 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/functional/standard-license_test.cpp 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
test/library/Os_Linux_test.cpp 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
build/.gitkeep
doc/CREDITS.md
@@ -1,7 +1,10 @@
The following code has been used in OpenLicenseManager. Many thanks to the authors
The following open source code has been used in OpenLicenseManager.
Thanks to every one of the authors of such projects. Without you open license manager would never have been completed.
========================================================
## isVM
Thanks for the great smbios parsing code. It saved me days.
isvm : https://github.com/0of/isvm
The MIT License (MIT)
@@ -25,5 +28,5 @@
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
=============================
doc/snippets/hardware.cpp
New file
@@ -0,0 +1,266 @@
/*********************  physical_processors.cpp   *****************************
* Author:        Agner Fog
* Date created:  2019-10-29
* Last modified: 2019-11-25
* Version:       1.02 beta
* Project:       vector class library
* Description:   Detect number of physical and logical processors on CPU chip.
*                Compile for C++11 or later
*
* (c) Copyright 2019 Agner Fog.
* Apache License version 2.0 or later.
*******************************************************************************
Some modern CPUs can run two threads in each CPU core when simultaneous
multithreading (SMT, called hyperthreading by Intel) is enabled.
The number of physical processors is the number of CPU cores.
The number of logical processors is the same number multiplied by the number of
threads that can run simultaneously in each CPU core.
Simultaneous multithreading will slow down performance when two CPU-intensive
threads running in the same physical processor (CPU core) are competing for the
same resources. Therefore, the optimal number of threads for CPU-intensive
tasks is most likely to be the number of physical processors.
Tasks that are less CPU-intensive but limited by RAM access, disk access,
network, etc. may get an advantage by running as many threads as the number of
logical processors. This will be double the number of physical processors when
simultaneous multithreading is enabled.
The physicalProcessors function detects the number of physical processors and
logical processors on an x86 computer. This is useful for determining the
optimal number of threads.
Note: There are several problems in detecting the number of physical processors:
1. The CPUID instruction on Intel CPUs will return a wrong number of logical
   processors when SMT (hyperthreading) is disabled. It may be necessary to
   compare the number of processors returned by the CPUID instruction with the
   number of processors reported by the operating system to detect if SMT is
   enabled (AMD processors do not have this problem).
2. It is necessary to rely on system functions to detect if there is more than
   one CPU chip installed. It is assumed that the status of SMT is the same on
   all CPU chips in a system.
3. The behavior of VIA processors is undocumented.
4. This function is not guaranteed to work on future CPUs. It may need updating
   when new CPUs with different configurations or different CPUID functionality
   appear.
******************************************************************************/
#include <thread>     // std::thread functions
#ifdef _MSC_VER
#include <intrin.h>   // __cpuidex intrinsic function available on microsoft compilers
#endif
// Define interface to CPUID instruction.
// input:  leaf = eax, subleaf = ecx
// output: output[0] = eax, output[1] = ebx, output[2] = ecx, output[3] = edx
static inline void cpuid(int output[4], int leaf, int subleaf = 0) {
#if defined(__GNUC__) || defined(__clang__)      // use inline assembly, Gnu/AT&T syntax
    int a, b, c, d;
    __asm("cpuid" : "=a"(a), "=b"(b), "=c"(c), "=d"(d) : "a"(leaf), "c"(subleaf) : );
    output[0] = a;
    output[1] = b;
    output[2] = c;
    output[3] = d;
#elif defined (_MSC_VER)                         // Microsoft compiler, intrin.h included
    __cpuidex(output, leaf, subleaf);            // intrinsic function for CPUID
#else                                            // unknown platform. try inline assembly with masm/intel syntax
    __asm {
        mov eax, leaf
        mov ecx, subleaf
        cpuid;
        mov esi, output
        mov[esi], eax
        mov[esi + 4], ebx
        mov[esi + 8], ecx
        mov[esi + 12], edx
    }
#endif
}
// Function prototype:
int physicalProcessors(int * logical_processors = 0);
// Find the number of physical and logical processors supported by CPU
// Parameter:
// logical_processors: an optional pointer to an integer that will receive the number of logical processors.
// Return value: number of physical processors
int physicalProcessors(int * logical_processors) {
    int vendor = 0;                              // CPU vendor: 1 = Intel, 2 = AMD, 3 = VIA, 0 = other
    int logicalProc = 1;                         // number of logical processor cores
    int physicalProc = 1;                        // number of physical processor cores
    int procPerCore = 1;                         // logical cores per physical core
    bool hyperthreadingSupported = false;        // CPU supports hyperthreading / simultaneous multithreading
    int systemProcessors = std::thread::hardware_concurrency(); // number of processors reported by operating system
    int abcd[4] = { 0,0,0,0 };                   // CPUID output
    cpuid(abcd, 0);                              // CPUID function 0
    int maxLeaf = abcd[0];                       // maximum eax input for CPUID
    if (abcd[2] == 0x6C65746E) {                 // last 4 chars of "GenuineIntel"
        vendor = 1;
    }
    else if (abcd[2] == 0x444D4163) {            // last 4 chars of "AuthenticAMD"
        vendor = 2;
    }
    else if (abcd[2] == 0x736C7561) {            // last 4 chars of "CentaurHauls"
        vendor = 3;
    }
    if (maxLeaf >= 1) {
        cpuid(abcd, 1);
        if (abcd[3] & (1 << 28)) {               // hyperthreading supported
            hyperthreadingSupported = true;
        }
    }
    if (vendor == 1) {
        //////////////////
        //    Intel     //
        //////////////////
        int hyper = 0;                           // hyperthreading status: 0 = unknown, 1 = disabled, 2 = enabled
        if (maxLeaf >= 0xB) {                    // leaf 0xB or 0x1F: Extended Topology Enumeration
            int num = 0xB;
            // if (maxLeaf >= 0x1F) num = 0x1F;
            for (int c = 0; c < 5; c++) {
                cpuid(abcd, num, c);             // enumeration level c
                int type = (abcd[2] >> 8) & 0xFF;// enumeration type at level c
                if (type == 1) {                 // SMT level
                    procPerCore = abcd[1] & 0xFFFF;
                }
                else if (type >= 2) {            // core level
                    logicalProc = abcd[1] & 0xFFFF;
                }
                else if (type == 0) break;
                // There are more types/levels to consider if we use num = 0x1F. We may need
                // to fix this in the future if CPUs with more complex configurations appear
            }
            physicalProc = logicalProc / procPerCore;
            // The number of performance monitor registers depends on hyperthreading status
            // on Intel CPUs with performance monitoring version 3 or 4
            cpuid(abcd, 0xA, 0);                 // performance monitor counters information
            int perfVersion = abcd[0] & 0xFF;    // performance monitoring version
            int perfNum = (abcd[0] >> 8) & 0xFF; // number of performance monitoring registers
            if (perfVersion == 3 || perfVersion == 4) {
                if (perfNum == 4) {
                    hyper = 2;                   // 4 performance registers when hyperthreading enabled
                }
                else if (perfNum == 8) {         // 8 performance registers when hyperthreading disabled
                    hyper = 1;
                    procPerCore = 1;
                    logicalProc = physicalProc;  // reduce the number of logical processors when hyperthreading is disabled
                }
                // hyper remains 0 in all other cases, indicating unknown status
            }
        }
        else if (maxLeaf >= 4) {                 // CPUID function 4: cache parameters and cores
            cpuid(abcd, 4);
            logicalProc = (abcd[0] >> 26) + 1;
            if (hyperthreadingSupported) {
                // number of logical processors per core is not known. Assume 2 if hyperthreading supported
                procPerCore = 2;
            }
            physicalProc = logicalProc / procPerCore;
        }
        else {
            // no information. Assume 1 processor
        }
        if (systemProcessors > logicalProc) {
            // Multiple CPU chips. Assume that chips are identical with respect to hypethreading
            physicalProc = systemProcessors * physicalProc / logicalProc;
            logicalProc = systemProcessors;
        }
        else if (logicalProc > systemProcessors && systemProcessors > 0 && hyper == 0) {
            // Hyperthreading is disabled
            logicalProc = systemProcessors;
            physicalProc = systemProcessors;
        }
    }
    else if (vendor == 2) {
        //////////////////
        //    AMD       //
        //////////////////
        cpuid(abcd, 0x80000000);                 // AMD specific CPUID functions
        int maxLeaf8 = abcd[0] & 0xFFFF;         // maximum eax 0x8000.... input for CPUID
        if (maxLeaf8 >= 8) {
            cpuid(abcd, 0x80000008);
            logicalProc = (abcd[2] & 0xFF) + 1;
            if (maxLeaf8 >= 0x1E) {
                cpuid(abcd, 0x8000001E);
                procPerCore = ((abcd[1] >> 8) & 0x03) + 1;
                // procPerCore = 2 if simultaneous multithreading is enabled, 1 if disabled
            }
            else {
                if (hyperthreadingSupported) {
                    procPerCore = 2;
                }
                else {
                    procPerCore = 1;
                }
            }
            physicalProc = logicalProc / procPerCore;
        }
        else if (hyperthreadingSupported) {
            // number of logical processors per core is not known. Assume 2 if SMT supported
            logicalProc = 2;
            physicalProc = 1;
        }
        if (systemProcessors > logicalProc) {
            // Multiple CPU chips. Assume that chips are identical with respect to SMT
            physicalProc = systemProcessors * physicalProc / logicalProc;
            logicalProc = systemProcessors;
        }
    }
    else {
        //////////////////////////////
        //    VIA or unknown CPU    //
        //////////////////////////////
        // The behavior of VIA processors is undocumented! It is not known how to detect threads on a VIA processor
        physicalProc = logicalProc = systemProcessors;
        if (hyperthreadingSupported && physicalProc > 1) {
            physicalProc /= 2;
        }
    }
    if (logical_processors) {
        // return logical_processors if pointer is not null
        *logical_processors = logicalProc;
    }
    return physicalProc;
}
/* Uncomment this for testing:
#include <stdio.h>
int main() {
    int logicalProc = 0;
    int physicalProc = physicalProcessors(&logicalProc);
    printf("\nlogical processors: %i",  logicalProc);
    printf("\nphysical processors: %i", physicalProc);
    printf("\nlogical processors per core: %i", logicalProc / physicalProc);
    int sysproc = std::thread::hardware_concurrency();
    printf("\nsystem processors: %i", sysproc);
    return 0;
}
*/
src/inspector/inspector.cpp
@@ -37,7 +37,7 @@
}
int main(int argc, char* argv[]) {
    license::CpuInfo cpu;
    license::os::CpuInfo cpu;
    cout << "CpuVendor      :" << cpu.vendor() << endl;
    cout << "Virtual machine:" << cpu.cpu_virtual() << endl;
    cout << "Cpu model      : 0x" << std::hex << ((long)cpu.model()) << std::dec << endl;
src/library/base/CMakeLists.txt
@@ -1,7 +1,7 @@
ADD_LIBRARY(base OBJECT
    EventRegistry.cpp
    StringUtils.cpp
    FileUtils.cpp
    file_utils.cpp
    base64.cpp
    logger.c
)
src/library/base/file_utils.cpp
File was renamed from src/library/base/FileUtils.cpp
@@ -11,7 +11,7 @@
#include <iostream>
#include <algorithm>
#include "FileUtils.hpp"
#include "file_utils.hpp"
namespace license {
using namespace std;
src/library/base/file_utils.hpp
src/library/hw_identifier/default_strategy.cpp
@@ -14,16 +14,16 @@
namespace hw_identifier {
static vector<LCC_API_IDENTIFICATION_STRATEGY> available_strategies() {
    ExecutionEnvironment exec;
    VIRTUALIZATION virtualization = exec.getVirtualization();
    os::ExecutionEnvironment exec;
    os::VIRTUALIZATION virtualization = exec.getVirtualization();
    vector<LCC_API_IDENTIFICATION_STRATEGY> strategy_to_try;
    if (virtualization == CONTAINER) {
    if (virtualization == os::CONTAINER) {
        if (exec.is_docker()) {
            strategy_to_try = LCC_DOCKER_STRATEGIES;
        } else {
            strategy_to_try = LCC_LXC_STRATEGIES;
        }
    } else if (virtualization == VM) {
    } else if (virtualization == os::VM) {
        if (exec.is_cloud()) {
            strategy_to_try = LCC_CLOUD_STRATEGIES;
        } else {
src/library/hw_identifier/disk_strategy.cpp
@@ -14,10 +14,10 @@
static FUNCTION_RETURN generate_disk_pc_id(vector<array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA>> &v_disk_id,
                                           bool use_id) {
    size_t disk_num, available_disk_info = 0;
    size_t disk_num = 0;
    size_t available_disk_info = 0;
    FUNCTION_RETURN result_diskinfos;
    unsigned int i;
    DiskInfo *diskInfos;
    result_diskinfos = getDiskInfos(nullptr, &disk_num);
    if (result_diskinfos != FUNC_RET_OK && result_diskinfos != FUNC_RET_BUFFER_TOO_SMALL) {
@@ -26,13 +26,14 @@
    if (disk_num == 0) {
        return FUNC_RET_NOT_AVAIL;
    }
    diskInfos = (DiskInfo *)malloc(disk_num * sizeof(DiskInfo));
    size_t mem = disk_num * sizeof(DiskInfo);
    DiskInfo *diskInfos = (DiskInfo *)malloc(mem);
    if (diskInfos == nullptr) {
        return FUNC_RET_NOT_AVAIL;
    }
    memset(diskInfos, 0, disk_num * sizeof(DiskInfo));
    memset(diskInfos, 0, mem);
    result_diskinfos = getDiskInfos(diskInfos, &disk_num);
    if (result_diskinfos != FUNC_RET_OK) {
        free(diskInfos);
        return result_diskinfos;
@@ -46,17 +47,19 @@
        return FUNC_RET_NOT_AVAIL;
    }
    v_disk_id.reserve(available_disk_info);
    //FIXME use preferred drive.
    for (i = 0; i < disk_num; i++) {
        array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA> a_disk_id;
        a_disk_id.fill(0);
        if (use_id) {
            if (diskInfos[i].disk_sn[0] != 0) {
                memcpy(&a_disk_id[0], &diskInfos[i].disk_sn[2], a_disk_id.size());
                size_t size = min(a_disk_id.size(), sizeof(&diskInfos[i].disk_sn));
                memcpy(&a_disk_id[0], diskInfos[i].disk_sn, size);
                v_disk_id.push_back(a_disk_id);
            }
        } else {
            if (diskInfos[i].label[0] != 0) {
                a_disk_id.fill(0);
                strncpy((char *)&a_disk_id[0], diskInfos[i].label, a_disk_id.size());
                strncpy((char *)&a_disk_id[0], diskInfos[i].label, a_disk_id.size()-1);
                v_disk_id.push_back(a_disk_id);
            }
        }
src/library/hw_identifier/ethernet.cpp
@@ -32,7 +32,7 @@
    }
    for (auto &it : adapters) {
        unsigned int k, data_len, data_byte;
        unsigned int k, data_len;
        array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA> identifier;
        data_len = use_ip ? sizeof(os::OsAdapterInfo::ipv4_address) : sizeof(os::OsAdapterInfo::mac_address);
src/library/hw_identifier/hw_identifier.cpp
@@ -47,16 +47,16 @@
    }
}
void HwIdentifier::set_virtual_environment(VIRTUALIZATION virt) {
void HwIdentifier::set_virtual_environment(os::VIRTUALIZATION virt) {
    // 110000 0x30
    m_data[0] = (m_data[0] & ~0x30) | virt << 4;
}
void HwIdentifier::set_virtualization(VIRTUALIZATION_DETAIL virtualization_detail) {
void HwIdentifier::set_virtualization(os::VIRTUALIZATION_DETAIL virtualization_detail) {
    m_data[0] = (m_data[0] & ~0x0F) | virtualization_detail;
}
void HwIdentifier::set_cloud_provider(CLOUD_PROVIDER cloud_provider) {
void HwIdentifier::set_cloud_provider(os::CLOUD_PROVIDER cloud_provider) {
    m_data[0] = (m_data[0] & ~0x0F) | cloud_provider | 0x08;
}
src/library/hw_identifier/hw_identifier.hpp
@@ -53,9 +53,9 @@
    void set_identification_strategy(LCC_API_IDENTIFICATION_STRATEGY strategy);
    LCC_API_IDENTIFICATION_STRATEGY get_identification_strategy() const;
    void set_use_environment_var(bool use_env_var);
    void set_virtual_environment(VIRTUALIZATION virtualization);
    void set_virtualization(VIRTUALIZATION_DETAIL virtualization_detail);
    void set_cloud_provider(CLOUD_PROVIDER cloud_provider);
    void set_virtual_environment(os::VIRTUALIZATION virtualization);
    void set_virtualization(os::VIRTUALIZATION_DETAIL virtualization_detail);
    void set_cloud_provider(os::CLOUD_PROVIDER cloud_provider);
    void set_data(const std::array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA> &data);
    bool data_match(const std::array<uint8_t, HW_IDENTIFIER_PROPRIETARY_DATA> &data) const;
    std::string print() const;
src/library/hw_identifier/hw_identifier_facade.cpp
@@ -57,16 +57,16 @@
    if (result != FUNC_RET_OK) {
        /// FIXME
    }
    ExecutionEnvironment exec;
    VIRTUALIZATION virtualization = exec.getVirtualization();
    os::ExecutionEnvironment exec;
    os::VIRTUALIZATION virtualization = exec.getVirtualization();
    pc_id.set_virtual_environment(virtualization);
    pc_id.set_use_environment_var(use_env_var);
    if (virtualization != NONE) {
    if (virtualization != os::NONE) {
        bool isCloud = exec.is_cloud();
        if (isCloud) {
            pc_id.set_cloud_provider(exec.getCloudProvider());
        } else {
            CpuInfo cpu;
            os::CpuInfo cpu;
            pc_id.set_virtualization(cpu.getVirtualizationDetail());
        }
    }
src/library/hw_identifier/identification_strategy.hpp
@@ -11,7 +11,7 @@
#include <licensecc/datatypes.h>
#include <licensecc_properties.h>
#include <vector>
#include <bits/unique_ptr.h>
#include <memory>
#include "../base/base.h"
#include "hw_identifier.hpp"
src/library/hw_identifier/pc-identifiers.c
File was deleted
src/library/hw_identifier/pc-identifiers.h
File was deleted
src/library/locate/ApplicationFolder.cpp
@@ -15,9 +15,9 @@
#include "../base/logger.h"
#include "../base/base.h"
#include "../base/EventRegistry.h"
#include "../base/FileUtils.hpp"
#include "../os/os.h"
#include "ApplicationFolder.hpp"
#include "../base/file_utils.hpp"
namespace license {
namespace locate {
src/library/locate/EnvironmentVarLocation.cpp
@@ -7,9 +7,9 @@
#include <licensecc_properties.h>
#include "../base/FileUtils.hpp"
#include "../base/StringUtils.h"
#include "EnvironmentVarLocation.hpp"
#include "../base/file_utils.hpp"
namespace license {
namespace locate {
src/library/locate/ExternalDefinition.cpp
@@ -9,15 +9,15 @@
#include <cstring>
#include <string>
#include <vector>
#include <stdexcept>
#include <licensecc/datatypes.h>
#include "../base/base64.h"
#include "../base/EventRegistry.h"
#include "../base/FileUtils.hpp"
#include "../base/StringUtils.h"
#include "ExternalDefinition.hpp"
#include "../base/file_utils.hpp"
namespace license {
namespace locate {
src/library/locate/LocatorStrategy.cpp
@@ -7,8 +7,8 @@
#include <licensecc_properties.h>
#include "../base/FileUtils.hpp"
#include "LocatorStrategy.hpp"
#include "../base/file_utils.hpp"
namespace license {
namespace locate {
src/library/os/CMakeLists.txt
@@ -2,6 +2,7 @@
    IF(UNIX)
        add_library(os OBJECT
            openssl/signature_verifier.cpp
            execution_environment_common.cpp
            linux/execution_environment.cpp
            cpu_info_common.cpp
            linux/cpu_info.cpp
@@ -9,11 +10,25 @@
            linux/os-linux.c) 
    ELSE(UNIX)
          add_library(os OBJECT 
          cpu_info_common.cpp openssl/signature_verifier.cpp windows/os-win.c)
          cpu_info_common.cpp windows/cpu_info.cpp
          openssl/signature_verifier.cpp
        execution_environment_common.cpp windows/execution_environment.cpp
          windows/isvm/Native.cpp
        windows/isvm/BIOSReader.cpp
          windows/os-win.c
          windows/network.cpp)
    ENDIF(UNIX)
ELSE(UNIX OR OPENSSL_FOUND)
#windows no openssl
    add_library(os OBJECT
        cpu_info_common.cpp windows/signature_verifier.cpp windows/os-win.c)
        cpu_info_common.cpp
        windows/cpu_info.cpp
        windows/signature_verifier.cpp
        execution_environment_common.cpp windows/execution_environment.cpp
        windows/isvm/Native.cpp
        windows/isvm/BIOSReader.cpp
        windows/os-win.c
        windows/network.cpp)
ENDIF(UNIX OR OPENSSL_FOUND)
if(CODE_COVERAGE AND UNIX)
src/library/os/cpu_info.hpp
@@ -9,7 +9,7 @@
#define SRC_LIBRARY_OS_CPU_INFO_H_
#include <string>
namespace license {
namespace os {
typedef enum { BARE_TO_METAL, VMWARE, VIRTUALBOX, V_XEN, KVM, HV, V_OTHER } VIRTUALIZATION_DETAIL;
/**
@@ -32,6 +32,6 @@
    VIRTUALIZATION_DETAIL getVirtualizationDetail() const;
};
} /* namespace license */
}  // namespace os
}  // namespace license
#endif /* SRC_LIBRARY_OS_CPU_INFO_H_ */
src/library/os/cpu_info_common.cpp
@@ -8,6 +8,7 @@
#include "cpu_info.hpp"
namespace license {
namespace os {
using namespace std;
const unordered_map<string, VIRTUALIZATION_DETAIL> virtual_cpu_names{
@@ -39,4 +40,5 @@
    }
    return result;
}
}  // namespace os
}  // namespace license
src/library/os/execution_environment.hpp
@@ -8,10 +8,15 @@
#ifndef SRC_LIBRARY_OS_VIRTUALIZATION_HPP_
#define SRC_LIBRARY_OS_VIRTUALIZATION_HPP_
#include <string>
namespace license {
namespace os {
typedef enum { NONE, CONTAINER, VM } VIRTUALIZATION;
typedef enum {
    PROV_UNKNOWN,
    ON_PREMISE,
    GOOGLE_CLOUD,
    AZURE_CLOUD,
@@ -25,17 +30,23 @@
    ALI_CLOUD
} CLOUD_PROVIDER;
class ExecutionEnvironment {
private:
    std::string sys_vendor;
    std::string bios_vendor;
    std::string bios_description;
    //detect if it's a kind of container technology (docker or lxc)
    bool is_container() const;
public:
    ExecutionEnvironment(){};
    virtual ~ExecutionEnvironment(){};
    VIRTUALIZATION getVirtualization();
    bool is_cloud();
    bool is_docker();
    CLOUD_PROVIDER getCloudProvider();
    ExecutionEnvironment();
    ~ExecutionEnvironment(){};
    VIRTUALIZATION getVirtualization() const;
    bool is_cloud() const;
    bool is_docker() const;
    CLOUD_PROVIDER getCloudProvider() const;
};
}  // namespace os
}  // namespace license
#endif /* SRC_LIBRARY_OS_VIRTUALIZATION_HPP_ */
src/library/os/execution_environment_common.cpp
New file
@@ -0,0 +1,53 @@
/*
 *
 *  Created on: Feb 23, 2020
 *      Author: GC
 */
#include <stdio.h>
#include <string.h>
#include <unordered_map>
#include <array>
#include "../base/base.h"
#include "cpu_info.hpp"
#include "execution_environment.hpp"
namespace license {
namespace os {
using namespace std;
VIRTUALIZATION ExecutionEnvironment::getVirtualization() const {
    VIRTUALIZATION result;
    CpuInfo cpuInfo;
    bool isContainer = is_container();
    if (isContainer) {
        result = CONTAINER;
    } else if (cpuInfo.cpu_virtual() || is_cloud()) {
        result = VM;
    } else {
        result = NONE;
    }
    return result;
}
bool ExecutionEnvironment::is_cloud() const { return getCloudProvider() != ON_PREMISE; }
// TODO test and azure
CLOUD_PROVIDER ExecutionEnvironment::getCloudProvider() const {
    CLOUD_PROVIDER result = PROV_UNKNOWN;
    if (bios_description.size() > 0 || bios_vendor.size() > 0 || sys_vendor.size() > 0) {
        if (bios_vendor.find("SEABIOS") != string::npos || bios_description.find("ALIBABA") != string::npos ||
            sys_vendor.find("ALIBABA") != string::npos) {
            result = ALI_CLOUD;
        } else if (sys_vendor.find("GOOGLE") != string::npos || bios_description.find("GOOGLE") != string::npos) {
            result = GOOGLE_CLOUD;
        } else if (bios_vendor.find("AWS") != string::npos || bios_description.find("AMAZON") != string::npos ||
                   sys_vendor.find("AWS") != string::npos) {
            result = AWS;
        }
    }
    return result;
}
}  // namespace os
}  // namespace license
src/library/os/linux/cpu_info.cpp
@@ -11,6 +11,7 @@
#include "../cpu_info.hpp"
namespace license {
namespace os {
using namespace std;
struct CPUVendorID {
@@ -52,5 +53,5 @@
    CPUVendorID vendorID{.ebx = ebx, .edx = edx, .ecx = ecx};
    return vendorID.toString();
}
}  // namespace os
} /* namespace license */
src/library/os/linux/execution_environment.cpp
@@ -17,8 +17,10 @@
#include "../../base/base.h"
#include "../cpu_info.hpp"
#include "../execution_environment.hpp"
#include "../../base/file_utils.hpp"
namespace license {
namespace os {
using namespace std;
// 0=NO 1=Docker/2=Lxc
@@ -80,26 +82,24 @@
    return result;
}
VIRTUALIZATION ExecutionEnvironment::getVirtualization() {
    VIRTUALIZATION result;
    CpuInfo cpuInfo;
    bool isContainer = checkContainerProc() != 0 || checkSystemdContainer() != 0;
    if (isContainer) {
        result = CONTAINER;
    } else if (cpuInfo.cpu_virtual() || is_cloud()) {
        result = VM;
    } else {
        result = NONE;
ExecutionEnvironment::ExecutionEnvironment() {
    try {
        bios_vendor = get_file_contents("/sys/class/dmi/id/sys_vendor", 256);
    } catch (...) {
    }
    return result;
    try {
        bios_description = get_file_contents("/sys/class/dmi/id/modalias", 256);
    } catch (...) {
    }
    try {
        sys_vendor = get_file_contents("/sys/class/dmi/id/sys_vendor", 256);
    } catch (...) {
    }
}
bool ExecutionEnvironment::is_cloud() { return getCloudProvider() != ON_PREMISE; }
bool ExecutionEnvironment::is_container() const { return (checkContainerProc() != 0 || checkSystemdContainer() != 0); }
bool ExecutionEnvironment::is_docker() { return (checkContainerProc() == 1 || checkSystemdContainer() == 1); }
bool ExecutionEnvironment::is_docker() const { return (checkContainerProc() == 1 || checkSystemdContainer() == 1); }
CLOUD_PROVIDER ExecutionEnvironment::getCloudProvider() {
    // TODO
}
}  // namespace os
}  // namespace license
src/library/os/linux/network.cpp
@@ -23,7 +23,6 @@
#include <ifaddrs.h>
#include <linux/if_link.h>
#include <netpacket/packet.h>
#include <string.h>
#include <stdio.h>
#include <unordered_map>
@@ -35,25 +34,6 @@
namespace os {
using namespace std;
/**
 *
 * @param ifnames
 * @param ifname
 * @param ifnames_max
 * @return
 */
static int ifname_position(char *ifnames, char *ifname, int ifnames_max) {
    int i, position;
    position = -1;
    for (i = 0; i < ifnames_max; i++) {
        if (strcmp(ifname, &ifnames[i * NI_MAXHOST]) == 0) {
            position = i;
            break;
        }
    }
    return position;
}
/**
 *
src/library/os/os.h
@@ -26,10 +26,10 @@
typedef struct {
    int id;
    char device[255];
    char device[MAX_PATH];
    unsigned char disk_sn[8];
    char label[255];
    bool preferred;
    int preferred;
} DiskInfo;
FUNCTION_RETURN getDiskInfos(DiskInfo* diskInfos, size_t* disk_info_size);
src/library/os/windows/.gitignore
File was deleted
src/library/os/windows/cpu_info.cpp
New file
@@ -0,0 +1,48 @@
/*
 * cpu_info.cpp
 *
 *  Created on: Dec 14, 2019
 *      Author: devel
 */
#include <intrin.h>
#include <string>
#include <unordered_set>
#include "../cpu_info.hpp"
namespace license {
namespace os {
using namespace std;
CpuInfo::CpuInfo() {}
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 {
    int cpui[4] = {0};
    __cpuid(cpui, 0x1);
    return ((cpui[2] >> 31) & 1);
}
uint32_t CpuInfo::model() const {
    int cpui[4] = {0};
    __cpuid(cpui, 0x1);
    // 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 (cpui[0] & 0x3FFF) | (cpui[0] & 0x3FF8000) >> 2 | (cpui[1] & 0xff) << 24;
}
string CpuInfo::vendor() const {
    // hypervisor flag false, try to get the vendor name, see if it's a virtual cpu
    int cpui[4] = {0};
    __cpuid(cpui, 0x0);
    return string(reinterpret_cast<const char *>(cpui), 12);
}
}  // namespace os
} /* namespace license */
src/library/os/windows/execution_environment.cpp
New file
@@ -0,0 +1,39 @@
/*
 * virtualization.cpp
 *
 *  Created on: Dec 15, 2019
 *      Author: GC
 */
#include <sys/stat.h>
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <string>
#include "isvm/BIOSReader.h"
#include "isvm/Native.h"
#include "../../base/base.h"
#include "../../base/StringUtils.h"
#include "../cpu_info.hpp"
#include "../execution_environment.hpp"
namespace license {
namespace os {
using namespace std;
ExecutionEnvironment::ExecutionEnvironment() {
    if (InitEntryPoints()) {
        BIOSReader reader;
        SystemInformation info = reader.readSystemInfo();
        sys_vendor = toupper_copy(info.Manufacturer);
        bios_vendor = toupper_copy(info.ProductName);
        bios_description = toupper_copy(info.SysVersion) + toupper_copy(info.family);
    }
}
//TODO
bool ExecutionEnvironment::is_docker() const { return false; }
//TODO
bool ExecutionEnvironment::is_container() const { return is_docker(); }
}  // namespace os
}  // namespace license
src/library/os/windows/isvm/BIOSReader.cpp
New file
@@ -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;
}
src/library/os/windows/isvm/BIOSReader.h
New file
@@ -0,0 +1,22 @@
#ifndef BIOSREADER_H
#define BIOSREADER_H
#include <string>
class SystemInformation
{
public:
    std::string Manufacturer;
    std::string ProductName;
    std::string SysVersion;
    std::string SerialNum;
    std::string family;
};
class BIOSReader
{
public:
    SystemInformation readSystemInfo();
};
#endif
src/library/os/windows/isvm/Native.cpp
New file
@@ -0,0 +1,437 @@
#include "Native.h"
#include <tchar.h>
typedef LARGE_INTEGER PHYSICAL_ADDRESS, *PPHYSICAL_ADDRESS; // windbgkd
typedef LONG NTSTATUS;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
typedef struct _UNICODE_STRING
{
    USHORT Length;
    USHORT MaximumLength;
#ifdef MIDL_PASS
    [size_is(MaximumLength / 2), length_is((Length) / 2)] USHORT * Buffer;
#else // MIDL_PASS
    PWSTR  Buffer;
#endif // MIDL_PASS
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef enum _SECTION_INHERIT
{
    ViewShare = 1,
    ViewUnmap = 2
} SECTION_INHERIT;
#define OBJ_INHERIT             0x00000002L
#define OBJ_PERMANENT           0x00000010L
#define OBJ_EXCLUSIVE           0x00000020L
#define OBJ_CASE_INSENSITIVE    0x00000040L
#define OBJ_OPENIF              0x00000080L
#define OBJ_OPENLINK            0x00000100L
#define OBJ_VALID_ATTRIBUTES    0x000001F2L
static bool bIsWindowsXPLater = false;
static DWORD dwPageSize = 0;
#ifdef _UNICODE
#define GetVersionExProc "GetVersionExW"
#else
#define GetVersionExProc "GetVersionExA"
#endif
typedef struct _OBJECT_ATTRIBUTES
{
    ULONG Length;
    HANDLE RootDirectory;
    PUNICODE_STRING ObjectName;
    ULONG Attributes;
    PVOID SecurityDescriptor;        // Points to type SECURITY_DESCRIPTOR
    PVOID SecurityQualityOfService;  // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES;
typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
typedef struct SMBIOSEntryPoint
{
    char EntryPointString[4];
    uint8_t Checksum;
    uint8_t Length;
    uint8_t MajorVersion;
    uint8_t MinorVersion;
    uint16_t MaxStructureSize;
    uint8_t EntryPointRevision;
    char FormattedArea[5];
    char EntryPointString2[5];
    uint8_t Checksum2;
    uint16_t TableLength;
    uint32_t TableAddress;
    uint16_t NumberOfStructures;
    uint8_t BCDRevision;
} SMBIOSEntryPoint, *PSMBIOSEntryPoint;
#define InitializeObjectAttributes( p, n, a, r, s ) { \
    (p)->Length = sizeof(OBJECT_ATTRIBUTES);          \
    (p)->RootDirectory = r;                             \
    (p)->Attributes = a;                                \
    (p)->ObjectName = n;                                \
    (p)->SecurityDescriptor = s;                        \
    (p)->SecurityQualityOfService = NULL;               \
}
NTSTATUS(WINAPI *NtUnmapViewOfSection)(
    IN HANDLE  ProcessHandle,
    IN PVOID  BaseAddress
    );
NTSTATUS(WINAPI *NtOpenSection)(
    OUT PHANDLE  SectionHandle,
    IN ACCESS_MASK  DesiredAccess,
    IN POBJECT_ATTRIBUTES  ObjectAttributes
    );
NTSTATUS(WINAPI *NtMapViewOfSection)(
    IN HANDLE  SectionHandle,
    IN HANDLE  ProcessHandle,
    IN OUT PVOID *BaseAddress,
    IN ULONG  ZeroBits,
    IN ULONG  CommitSize,
    IN OUT PLARGE_INTEGER  SectionOffset,    /* optional */
    IN OUT PULONG  ViewSize,
    IN SECTION_INHERIT  InheritDisposition,
    IN ULONG  AllocationType,
    IN ULONG  Protect
    );
VOID(WINAPI *RtlInitUnicodeString)(
    IN OUT PUNICODE_STRING  DestinationString,
    IN PCWSTR  SourceString
    );
ULONG(WINAPI *RtlNtStatusToDosError) (
    IN NTSTATUS Status
    );
UINT(WINAPI *Win32GetSystemFirmwareTable)(
    _In_ DWORD FirmwareTableProviderSignature,
    _In_ DWORD FirmwareTableID,
    _Out_writes_bytes_to_opt_(BufferSize, return) PVOID pFirmwareTableBuffer,
    _In_ DWORD BufferSize);
BOOL(WINAPI *Win32GetVersionEx)(
    _Inout_  LPOSVERSIONINFO lpVersionInfo
    );
VOID(WINAPI *Win32GetSystemInfo)(
    _Out_  LPSYSTEM_INFO lpSystemInfo
    );
BOOL(WINAPI *Win32VirtualProtect)(
    _In_   LPVOID lpAddress,
    _In_   SIZE_T dwSize,
    _In_   DWORD flNewProtect,
    _Out_  PDWORD lpflOldProtect
    );
//----------------------------------------------------------------------
//
// PrintError
//
// Formats an error message for the last error
//
// Mark Russinovich
// Systems Internals
// http://www.sysinternals.com
//----------------------------------------------------------------------
void PrintError(char *message, NTSTATUS status)
{
    char *errMsg;
    FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL, RtlNtStatusToDosError(status),
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR)&errMsg, 0, NULL);
    LocalFree(errMsg);
}
//--------------------------------------------------------
//
// UnmapPhysicalMemory
//
// Maps a view of a section.
//
// Mark Russinovich
// Systems Internals
// http://www.sysinternals.com
//--------------------------------------------------------
static VOID UnmapPhysicalMemory(PVOID Address)
{
    NTSTATUS        status;
    status = NtUnmapViewOfSection((HANDLE)-1, Address);
    if (!NT_SUCCESS(status))
    {
        PrintError("Unable to unmap view", status);
    }
}
//--------------------------------------------------------
//
// MapPhysicalMemory
//
// Maps a view of a section.
//
// Mark Russinovich
// Systems Internals
// http://www.sysinternals.com
//--------------------------------------------------------
static BOOLEAN MapPhysicalMemory(HANDLE PhysicalMemory,
    PVOID Address, PDWORD Length,
    PVOID *VirtualAddress)
{
    NTSTATUS            ntStatus;
    PHYSICAL_ADDRESS    viewBase;
    char                error[256];
    viewBase.QuadPart = (ULONGLONG)(Address);
    ntStatus = NtMapViewOfSection(PhysicalMemory,
        (HANDLE)-1,
        VirtualAddress,
        0L, *Length,
        &viewBase,
        Length,
        ViewShare,
        0,
        PAGE_READONLY);
    if (!NT_SUCCESS(ntStatus)) {
        PrintError(error, ntStatus);
        return FALSE;
    }
    return TRUE;
}
//--------------------------------------------------------
//
// OpensPhysicalMemory
//
// This function opens the physical memory device. It
// uses the native API since
//
// Mark Russinovich
// Systems Internals
// http://www.sysinternals.com
//--------------------------------------------------------
static HANDLE OpenPhysicalMemory()
{
    NTSTATUS        status;
    HANDLE            physmem;
    UNICODE_STRING    physmemString;
    OBJECT_ATTRIBUTES attributes;
    WCHAR            physmemName[] = L"\\device\\physicalmemory";
    RtlInitUnicodeString(&physmemString, physmemName);
    InitializeObjectAttributes(&attributes, &physmemString,
        OBJ_CASE_INSENSITIVE, NULL, NULL);
    status = NtOpenSection(&physmem, SECTION_MAP_READ, &attributes);
    if (!NT_SUCCESS(status))
    {
        PrintError("Could not open \\device\\physicalmemory", status);
        return NULL;
    }
    return physmem;
}
static PVOID MapPhysicalMemoryWithBase(HANDLE hPhyHandle, PVOID pBase, PDWORD pLen, PVOID *pVirtualBase)
{
    DWORD dwOffset = (ULONGLONG)pBase % dwPageSize;
    DWORD dwLen = *pLen + dwOffset;
    PVOID pVAddr = NULL;
    if (MapPhysicalMemory(hPhyHandle, pBase, &dwLen, &pVAddr))
    {
        *pVirtualBase = pVAddr;
        *pLen = dwLen;
        return (PBYTE)pVAddr + dwOffset;
    }
    else
    {
        return NULL;
    }
}
bool InitEntryPoints()
{
    Win32GetVersionEx = decltype(Win32GetVersionEx)(GetProcAddress(::GetModuleHandle(_T("kernel32.dll")), GetVersionExProc));
    if (!Win32GetVersionEx)
        return false;
    Win32GetSystemInfo = decltype(Win32GetSystemInfo)(GetProcAddress(::GetModuleHandle(_T("kernel32.dll")), "GetSystemInfo"));
    if (!Win32GetSystemInfo)
        return false;
    OSVERSIONINFO osvi;
    ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    if (!Win32GetVersionEx(&osvi))
        return false;
    bIsWindowsXPLater = ((osvi.dwMajorVersion > 5) || ((osvi.dwMajorVersion == 5) && (osvi.dwMinorVersion > 1)));
    SYSTEM_INFO sysinfo;
    ::ZeroMemory(&sysinfo, sizeof (SYSTEM_INFO));
    Win32GetSystemInfo(&sysinfo);
    dwPageSize = sysinfo.dwPageSize;
    if (bIsWindowsXPLater)
    {
        Win32GetSystemFirmwareTable = decltype(Win32GetSystemFirmwareTable)(GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "GetSystemFirmwareTable"));
        if (!Win32GetSystemFirmwareTable)
            return false;
    }
    else
    {
        Win32VirtualProtect = decltype(Win32VirtualProtect)(GetProcAddress(GetModuleHandle(_T("kernel32.dll")), "VirtualProtect"));
        if (!Win32VirtualProtect)
            return false;
        RtlInitUnicodeString = (decltype(RtlInitUnicodeString))(GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "RtlInitUnicodeString"));
        if (!RtlInitUnicodeString)
            return false;
        NtUnmapViewOfSection = (decltype(NtUnmapViewOfSection))(GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtUnmapViewOfSection"));
        if (!NtUnmapViewOfSection)
            return false;
        NtOpenSection = (decltype(NtOpenSection))(GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtOpenSection"));
        if (!NtOpenSection)
            return false;
        NtMapViewOfSection = (decltype(NtMapViewOfSection))(GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "NtMapViewOfSection"));
        if (!NtMapViewOfSection)
            return false;
        RtlNtStatusToDosError = (decltype(RtlNtStatusToDosError))(GetProcAddress(GetModuleHandle(_T("ntdll.dll")), "RtlNtStatusToDosError"));
        if (!NtMapViewOfSection)
            return false;
    }
    return true;
}
void *LocateSMBIOS(uint32_t *smbios_size)
{
    void *buf = NULL;
    if (bIsWindowsXPLater)
    {
        uint32_t size = 0;
        size = Win32GetSystemFirmwareTable('RSMB', 0, buf, size);
        if (0 == size)
        {
            return NULL;
        }
        buf = malloc(size);
        if (buf)
        {
            if (0 == Win32GetSystemFirmwareTable('RSMB', 0, buf, size))
            {
                free(buf);
                buf = NULL;
            }
            else
            {
                *smbios_size = size;
            }
        }
    }
    else
    {
        HANDLE hPhysMem = OpenPhysicalMemory();
        if (NULL == hPhysMem)
            return NULL;
        DWORD dwReadLen = 0x10000;
        DWORD dwActualLen = dwReadLen;
        PVOID pBaseVAddr = NULL;
        PVOID pVAddr = MapPhysicalMemoryWithBase(hPhysMem, (PVOID)0xF0000, &dwActualLen, &pBaseVAddr);
        if (!pVAddr)
        {
            ::CloseHandle(hPhysMem);
            return NULL;
        }
        DWORD dwReadOffset = 0;
        PBYTE pbVAddr = (PBYTE)pVAddr;
        PBYTE pbGuardVAddr = pbVAddr + dwReadLen;
        while (pbVAddr < pbGuardVAddr)
        {
            if (pbVAddr[0] == '_' && pbVAddr[1] == 'S' && pbVAddr[2] == 'M' && pbVAddr[3] == '_')
            {
                break;
            }
            pbVAddr += 16;
        }
        //!    no SMBIOS found
        if (pbVAddr >= pbGuardVAddr)
        {
            UnmapPhysicalMemory(pVAddr);
            ::CloseHandle(hPhysMem);
            return NULL;
        }
        PSMBIOSEntryPoint pEntryPoint = (PSMBIOSEntryPoint)pbVAddr;
        RawSMBIOSData *pData = (RawSMBIOSData *)::malloc(pEntryPoint->TableLength + sizeof(RawSMBIOSData));
        PVOID pTableBaseVAddr = NULL;
        if (NULL != pData)
        {
            DWORD dwTableLen = pEntryPoint->TableLength;
            PVOID pTableVAddr = MapPhysicalMemoryWithBase(hPhysMem, (PVOID)pEntryPoint->TableAddress, &dwTableLen, &pTableBaseVAddr);
            if (!pTableVAddr)
            {
                UnmapPhysicalMemory(pBaseVAddr);
                ::CloseHandle(hPhysMem);
                return NULL;
            }
            pData->Used20CallingMethod = 0;
            pData->DmiRevision = 0;
            pData->SMBIOSMajorVersion = pEntryPoint->MajorVersion;
            pData->SMBIOSMinorVersion = pEntryPoint->MinorVersion;
            pData->Length = pEntryPoint->TableLength;
            ::memcpy(pData->SMBIOSTableData, (PVOID)pTableVAddr, pEntryPoint->TableLength);
            *smbios_size = pEntryPoint->TableLength;
        }
        if (NULL != pTableBaseVAddr)
            UnmapPhysicalMemory(pTableBaseVAddr);
        if (NULL != pBaseVAddr)
            UnmapPhysicalMemory(pBaseVAddr);
        ::CloseHandle(hPhysMem);
        buf = pData;
    }
    return buf;
}
src/library/os/windows/isvm/Native.h
New file
@@ -0,0 +1,18 @@
#pragma once
#include <stdint.h>
#include <Windows.h>
struct RawSMBIOSData
{
    BYTE    Used20CallingMethod;
    BYTE    SMBIOSMajorVersion;
    BYTE    SMBIOSMinorVersion;
    BYTE    DmiRevision;
    DWORD   Length;
    BYTE    SMBIOSTableData[];
};
bool InitEntryPoints();
void *LocateSMBIOS(uint32_t *smbios_size);
src/library/os/windows/isvm/main.cpp
New file
@@ -0,0 +1,51 @@
#include "intrin.h"
#include <iostream>
#include "BIOSReader.h"
#include "Native.h"
int _tmain(int argc, _TCHAR* argv[])
{
    int cpui[4] = { 0 };
    __cpuid(cpui, 0x1);
    if ((cpui[2] >> 31) & 1)
    {
        std::cout << "Inside virual machine!";
        return 1;
    }
    if (InitEntryPoints())
    {
        BIOSReader reader;
        SystemInformation info = reader.readSystemInfo();
        const char *vmVendors[] =
        {
            "VMware", "Microsoft Corporation", "Virtual Machine", "innotek GmbH", "PowerVM", "Bochs", "KVM"
        };
        const int count = _countof(vmVendors);
        for (int i = 0; i != count; ++i)
        {
            const char *vendor = vmVendors[i];
            if (std::string::npos != info.Manufacturer.find(vendor) ||
                std::string::npos != info.ProductName.find(vendor) ||
                std::string::npos != info.SerialNum.find(vendor))
            {
                std::cout << "Inside virual machine!";
                return 1;
            }
        }
    }
    else
    {
        return -1;
    }
    std::cout << "Inside host machine!";
    return 0;
}
src/library/os/windows/network.cpp
New file
@@ -0,0 +1,113 @@
/**
 * @file network_id.c
 * @date 16 Sep 2014
 * @brief File containing network interface detection functions for Windows.
 *
 * The only public function of this module is #getAdapterInfos(OsAdapterInfo *,
 *        size_t *), other functions are either static or inline.
 *
 * Responsibility of this module is to fill OsAdapterInfo structures, in a predictable way (skip loopback/vpn interfaces)
 */
#ifdef _MSC_VER
#include <Windows.h>
#endif
#include <iphlpapi.h>
#include <unordered_map>
#include <stdio.h>
#pragma comment(lib, "IPHLPAPI.lib")
#include "../../base/StringUtils.h"
#include "../../base/logger.h"
#include "../network.hpp"
namespace license {
namespace os {
using namespace std;
static int translate(char ipStringIn[16], unsigned char ipv4[4]) {
    size_t index = 0;
    char *str2 = ipStringIn; /* save the pointer */
    while (*str2) {
        if (isdigit((unsigned char)*str2)) {
            ipv4[index] *= 10;
            ipv4[index] += *str2 - '0';
        } else {
            index++;
        }
        str2++;
    }
    return 0;
}
/**
 *
 * @param adapterInfos
 * @param adapter_info_size
 * @return
 */
FUNCTION_RETURN getAdapterInfos(vector<OsAdapterInfo> &adapterInfos) {
    unordered_map<string, OsAdapterInfo> adapterByName;
    FUNCTION_RETURN f_return = FUNC_RET_OK;
    DWORD dwStatus;
    int adapter_info_size;
    PIP_ADAPTER_INFO pAdapterInfo;
    DWORD dwBufLen = sizeof(IP_ADAPTER_INFO);
    unsigned int i = 3;
    do {
        pAdapterInfo = (PIP_ADAPTER_INFO)malloc(dwBufLen);
        dwStatus = GetAdaptersInfo(     // Call GetAdapterInfo
            pAdapterInfo,  // [out] buffer to receive data
            &dwBufLen  // [in] size of receive data buffer
        );
        if (dwStatus != NO_ERROR && pAdapterInfo != nullptr) {
            free(pAdapterInfo);
            pAdapterInfo = nullptr;
        }
    } while (dwStatus == ERROR_BUFFER_OVERFLOW && i-- > 0);
    if (dwStatus == ERROR_BUFFER_OVERFLOW) {
        return FUNC_RET_ERROR;
    }
    adapter_info_size = dwBufLen / sizeof(IP_ADAPTER_INFO);
    if (adapter_info_size == 0) {
        return FUNC_RET_NOT_AVAIL;
    }
    PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
    i = 0;
    FUNCTION_RETURN result = FUNC_RET_OK;
    while (pAdapter) {
        OsAdapterInfo ai = {};
        strncpy(ai.description, pAdapter->Description,
                min(sizeof(ai.description), MAX_ADAPTER_DESCRIPTION_LENGTH));
        memcpy(ai.mac_address, pAdapter->Address, 8);
        translate(pAdapter->IpAddressList.IpAddress.String, ai.ipv4_address);
        ai.type = IFACE_TYPE_ETHERNET;
        i++;
        pAdapter = pAdapter->Next;
        if (i == adapter_info_size) {
            result = FUNC_RET_BUFFER_TOO_SMALL;
            break;
        }
        adapterByName[string(ai.description)] = ai;
    }
    free(pAdapterInfo);
    // FIXME sort by eth , enps, wlan
    if (adapterByName.size() == 0) {
        f_return = FUNC_RET_NOT_AVAIL;
    } else {
        f_return = FUNC_RET_OK;
        adapterInfos.reserve(adapterByName.size());
        for (auto &it : adapterByName) {
            adapterInfos.push_back(it.second);
        }
    }
    return f_return;
}
}  // namespace os
}  // namespace license
src/library/os/windows/os-win.c
@@ -1,17 +1,15 @@
#ifdef _MSC_VER
/*#ifdef _MSC_VER
#include <Windows.h>
#endif
#include "../base/logger.h"
#include "os.h"
#endif*/
#include "../../base/logger.h"
#include "../os.h"
#include <licensecc/datatypes.h>
#include <iphlpapi.h>
#include <stdio.h>
#pragma comment(lib, "IPHLPAPI.lib")
unsigned char* unbase64(const char* ascii, int len, int *flen);
FUNCTION_RETURN getOsSpecificIdentifier(unsigned char identifier[6]) {
    return FUNC_RET_NOT_AVAIL;
}
FUNCTION_RETURN getMachineName(unsigned char identifier[6]) {
    FUNCTION_RETURN result = FUNC_RET_ERROR;
@@ -34,15 +32,14 @@
#define MAX_UNITS 30
//bug check return with diskinfos == null func_ret_ok
FUNCTION_RETURN getDiskInfos(DiskInfo * diskInfos, size_t * disk_info_size) {
    DWORD FileMaxLen;
    DWORD fileMaxLen;
    int ndrives = 0;
    DWORD FileFlags;
    char volName[_MAX_FNAME], FileSysName[_MAX_FNAME];
    DWORD fileFlags;
    char volName[MAX_PATH], fileSysName[MAX_PATH];
    DWORD volSerial = 0;
    const DWORD dwSize = MAX_PATH;
    char szLogicalDrives[MAX_PATH] = { 0 };
    unsigned char buf[8] = "";
    FUNCTION_RETURN return_value = FUNC_RET_NOT_AVAIL;
    const DWORD dwResult = GetLogicalDriveStrings(dwSize, szLogicalDrives);
@@ -56,22 +53,21 @@
            UINT driveType = GetDriveType(szSingleDrive);
            if (driveType == DRIVE_FIXED) {
                BOOL success = GetVolumeInformation(szSingleDrive, volName, MAX_PATH,
                                                    &volSerial, &FileMaxLen, &FileFlags, FileSysName,
                                                    &volSerial, &fileMaxLen, &fileFlags, fileSysName,
                                                    MAX_PATH);
                if (success) {
                    LOG_INFO("drive         : %s", szSingleDrive);
                    LOG_INFO("Volume Name   : %s", volName);
                    LOG_INFO("Volume Serial : 0x%x", volSerial);
                    LOG_DEBUG("Max file length : %d", FileMaxLen);
                    LOG_DEBUG("Filesystem      : %s", FileSysName);
                    LOG_DEBUG("Max file length : %d", fileMaxLen);
                    LOG_DEBUG("Filesystem      : %s", fileSysName);
                    if (diskInfos != NULL) {
                        if (ndrives < (int)*disk_info_size) {
                            diskInfos[ndrives].id = ndrives;
                            strncpy(diskInfos[ndrives].device, volName, MAX_PATH);
                            strncpy(diskInfos[ndrives].label, FileSysName, MAX_PATH);
                            memcpy(diskInfos[ndrives].disk_sn, &buf, sizeof(buf));
                            strncpy(diskInfos[ndrives].device, volName, min(MAX_PATH,sizeof(volName))-1);
                            strncpy(diskInfos[ndrives].label, fileSysName,min(sizeof(diskInfos[ndrives].label), sizeof(fileSysName)) - 1);
                            memcpy(diskInfos[ndrives].disk_sn, &volSerial, sizeof(DWORD));
                            diskInfos[ndrives].preferred = (strncmp(szSingleDrive, "C", 1) != 0);
                            diskInfos[ndrives].preferred = (szSingleDrive[0] == 'C');
                        } else {
                            return_value = FUNC_RET_BUFFER_TOO_SMALL;
                        }
@@ -100,79 +96,6 @@
    return return_value;
}
static int translate(char ipStringIn[16], unsigned char ipv4[4]) {
    size_t index = 0;
    char* str2 = ipStringIn; /* save the pointer */
    while (*str2) {
        if (isdigit((unsigned char) *str2)) {
            ipv4[index] *= 10;
            ipv4[index] += *str2 - '0';
        } else {
            index++;
        }
        str2++;
    }
    return 0;
}
//http://stackoverflow.com/questions/18046063/mac-address-using-c
//TODO: count only interfaces with type (MIB_IF_TYPE_ETHERNET IF_TYPE_IEEE80211)
FUNCTION_RETURN getAdapterInfos(OsAdapterInfo * adapterInfos,
        size_t * adapter_info_size) {
    DWORD dwStatus;
    PIP_ADAPTER_INFO pAdapterInfo;
    //IP_ADAPTER_INFO AdapterInfo[20];              // Allocate information for up to 16 NICs
    DWORD dwBufLen = sizeof(IP_ADAPTER_INFO); //10 * sizeof(IP_ADAPTER_INFO);  // Save the memory size of buffer
    unsigned int i = 3;
    do {
        pAdapterInfo = (PIP_ADAPTER_INFO) malloc(dwBufLen);
        dwStatus = GetAdaptersInfo(               // Call GetAdapterInfo
                pAdapterInfo, // [out] buffer to receive data
                &dwBufLen   // [in] size of receive data buffer
                );
        if (dwStatus != NO_ERROR) {
            free(pAdapterInfo);
            pAdapterInfo = NULL;
        }
    } while (dwStatus == ERROR_BUFFER_OVERFLOW && i-- > 0);
    if (dwStatus == ERROR_BUFFER_OVERFLOW) {
        return FUNC_RET_ERROR;
    }
    if (adapterInfos == NULL || *adapter_info_size == 0) {
        *adapter_info_size = dwBufLen / sizeof(IP_ADAPTER_INFO);
        if (pAdapterInfo != NULL){
            free(pAdapterInfo);
        }
        return FUNC_RET_OK;
    }
    *adapter_info_size = dwBufLen / sizeof(IP_ADAPTER_INFO);
    memset(adapterInfos, 0, dwBufLen);
    PIP_ADAPTER_INFO pAdapter = pAdapterInfo;
    i = 0;
    FUNCTION_RETURN result = FUNC_RET_OK;
    while (pAdapter) {
        strncpy(adapterInfos[i].description, pAdapter->Description,
                min(sizeof(adapterInfos->description),
                        MAX_ADAPTER_DESCRIPTION_LENGTH));
        memcpy(adapterInfos[i].mac_address, pAdapter->Address, 8);
        translate(pAdapter->IpAddressList.IpAddress.String,
                adapterInfos[i].ipv4_address);
        adapterInfos[i].type = IFACE_TYPE_ETHERNET;
        i++;
        pAdapter = pAdapter->Next;
        if (i == *adapter_info_size) {
            result = FUNC_RET_BUFFER_TOO_SMALL;
            break;
        }
    }
    free(pAdapterInfo);
    return result;
}
FUNCTION_RETURN getModuleName(char buffer[MAX_PATH]) {
    FUNCTION_RETURN result = FUNC_RET_OK;
@@ -183,29 +106,4 @@
    return result;
}
// TODO: remove unused
static void printHash(HCRYPTHASH* hHash) {
    DWORD dwHashLen;
    DWORD dwHashLenSize = sizeof(DWORD);
    if (CryptGetHashParam(*hHash, HP_HASHSIZE, (BYTE *) &dwHashLen,
            &dwHashLenSize, 0)) {
        BYTE* pbHash = (BYTE*)malloc(dwHashLen);
        char* hashStr = (char*)malloc(dwHashLen * 2 + 1);
        if (CryptGetHashParam(*hHash, HP_HASHVAL, pbHash, &dwHashLen, 0)) {
            for (unsigned int i = 0; i < dwHashLen; i++) {
                sprintf(&hashStr[i * 2], "%02x", pbHash[i]);
            } LOG_DEBUG("Hash to verify: %s", hashStr);
        }
        free(pbHash);
        free(hashStr);
    }
}
/**
 * Not implemented yet.
 */
VIRTUALIZATION getVirtualization() {
    return NONE;
}
src/library/os/windows/signature_verifier.cpp
@@ -136,12 +136,11 @@
    DWORD status;
    FUNCTION_RETURN result = FUNC_RET_ERROR;
    PBYTE pbSignature = nullptr;
    BYTE* sigBlob = nullptr;
    BCRYPT_ALG_HANDLE hSignAlg = nullptr;
    vector<uint8_t> signatureBlob = unbase64(signatureBuffer);
    DWORD dwSigLen = signatureBlob.size();
    sigBlob = &signatureBlob[0];
    BYTE* sigBlob = &signatureBlob[0];
    
    if (NT_SUCCESS(status = BCryptOpenAlgorithmProvider(&hSignAlg, BCRYPT_RSA_ALGORITHM, NULL, 0))) {
        if ((result = readPublicKey(hSignAlg, &phKey)) == FUNC_RET_OK) {
@@ -174,9 +173,9 @@
    if (hSignAlg != nullptr) {
        BCryptCloseAlgorithmProvider(hSignAlg, 0);
    }
    if (sigBlob) {
        free(sigBlob);
    }
    //if (sigBlob) {
    //    free(sigBlob);
    //}
    return result;
}
test/functional/CMakeLists.txt
@@ -46,11 +46,11 @@
)
add_executable(test_it_pc_identifer hw_identifier_it_test.cpp)
add_executable(test_it_hw_identifier hw_identifier_it_test.cpp)
target_link_libraries(test_it_pc_identifer
 licensecc_static
target_link_libraries(test_it_hw_identifier
 license_generator_snippet
 licensecc_static
 Boost::unit_test_framework 
 Boost::filesystem
 Boost::system
@@ -59,8 +59,8 @@
add_executable(test_crack crack_test.cpp)
target_link_libraries( test_crack
 licensecc_static
 license_generator_snippet
 licensecc_static
 Boost::unit_test_framework 
 Boost::filesystem
 Boost::system
@@ -68,7 +68,7 @@
ADD_TEST(NAME test_crack COMMAND test_crack WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
ADD_TEST(NAME test_date COMMAND test_date WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
ADD_TEST(NAME test_it_pc_identifer COMMAND test_it_pc_identifer WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
ADD_TEST(NAME test_it_hw_identifier COMMAND test_it_hw_identifier WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
ADD_TEST(NAME test_standard_license COMMAND test_standard_license WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
ADD_TEST(NAME test_signature_verifier COMMAND test_signature_verifier WORKING_DIRECTORY ${CMAKE_BINARY_DIR})
test/functional/crack_test.cpp
@@ -1,3 +1,4 @@
#define BOOST_TEST_MODULE standard_license_test
#include <boost/test/unit_test.hpp>
@@ -9,7 +10,7 @@
#include <iostream>
#include "../../src/library/ini/SimpleIni.h"
#include "generate-license.h"
#include "../../src/library/base/FileUtils.hpp"
#include "../../src/library/base/file_utils.hpp"
namespace license {
namespace test {
test/functional/date_test.cpp
@@ -31,7 +31,7 @@
    BOOST_CHECK_EQUAL(result, LICENSE_OK);
    BOOST_CHECK_EQUAL(license.has_expiry, true);
    BOOST_CHECK_EQUAL(license.linked_to_pc, false);
    BOOST_CHECK_GT(license.days_left, 0);
    BOOST_CHECK_GT(license.days_left, (unsigned int)0);
}
BOOST_AUTO_TEST_CASE(license_expired) {
test/functional/standard-license_test.cpp
@@ -1,3 +1,4 @@
#define BOOST_TEST_MODULE test_standard_license
#include <boost/test/unit_test.hpp>
@@ -9,7 +10,7 @@
#include "../../src/library/ini/SimpleIni.h"
#include "generate-license.h"
#include "../../src/library/base/FileUtils.hpp"
#include "../../src/library/base/file_utils.hpp"
using namespace std;
namespace fs = boost::filesystem;
test/library/Os_Linux_test.cpp
@@ -10,13 +10,14 @@
#include "../../src/library/os/execution_environment.hpp"
namespace license {
using namespace std;
namespace test {
using namespace std;
using namespace os;
BOOST_AUTO_TEST_CASE(read_disk_id) {
    ExecutionEnvironment exec_env;
    VIRTUALIZATION virt = exec_env.getVirtualization();
    if (virt == NONE || virt == VM) {
    os::ExecutionEnvironment exec_env;
    os::VIRTUALIZATION virt = exec_env.getVirtualization();
    if (virt == VIRTUALIZATION::NONE || virt == VIRTUALIZATION::VM) {
        DiskInfo *diskInfos = NULL;
        size_t disk_info_size = 0;
        FUNCTION_RETURN result = getDiskInfos(NULL, &disk_info_size);
@@ -29,7 +30,7 @@
        BOOST_CHECK_GT(mstrnlen_s(diskInfos[0].label, sizeof diskInfos[0].label), 0);
        BOOST_CHECK_GT(diskInfos[0].disk_sn[0], 0);
        free(diskInfos);
    } else if (virt == CONTAINER) {
    } else if (virt == VIRTUALIZATION::CONTAINER) {
        // docker or lxc diskInfo is not meaningful
        DiskInfo *diskInfos = NULL;
        size_t disk_info_size = 0;
@@ -42,16 +43,16 @@
// otherwise the test is skipped
BOOST_AUTO_TEST_CASE(test_virtualization) {
    const char *env = getenv("VIRT_ENV");
    ExecutionEnvironment exec_env;
    os::ExecutionEnvironment exec_env;
    if (env != NULL) {
        if (strcmp(env, "CONTAINER") == 0) {
            VIRTUALIZATION virt = exec_env.getVirtualization();
            BOOST_CHECK_MESSAGE(virt == CONTAINER, "container detected");
            os::VIRTUALIZATION virt = exec_env.getVirtualization();
            BOOST_CHECK_MESSAGE(virt == VIRTUALIZATION::CONTAINER, "container detected");
        } else if (strcmp(env, "VM") == 0) {
            BOOST_FAIL("check for vm not implemented");
        } else if (strcmp(env, "NONE") == 0) {
            VIRTUALIZATION virt = exec_env.getVirtualization();
            BOOST_CHECK_EQUAL(virt, NONE);
            os::VIRTUALIZATION virt = exec_env.getVirtualization();
            BOOST_CHECK_EQUAL(virt, VIRTUALIZATION::NONE);
        } else {
            BOOST_FAIL(string("value ") + env + " not supported: VM,CONTAINER,NONE");
        }