From 9afdac17dcc8956fd795797bfc5b6e1c09285342 Mon Sep 17 00:00:00 2001
From: Gabriele Contini <contini.mailing@gmail.com>
Date: 周日, 08 3月 2020 21:27:16 +0800
Subject: [PATCH] Issues #14 and #6

---
 src/library/locate/ExternalDefinition.cpp             |    6 
 src/library/os/linux/execution_environment.cpp        |   34 
 src/library/os/execution_environment_common.cpp       |   53 ++
 src/library/hw_identifier/hw_identifier_facade.cpp    |    8 
 src/library/os/os.h                                   |    4 
 src/library/os/windows/isvm/BIOSReader.cpp            |  121 ++++
 src/library/os/windows/network.cpp                    |  113 ++++
 src/inspector/inspector.cpp                           |    2 
 src/library/hw_identifier/hw_identifier.hpp           |    6 
 src/library/hw_identifier/identification_strategy.hpp |    2 
 src/library/os/CMakeLists.txt                         |   19 
 src/library/hw_identifier/hw_identifier.cpp           |    6 
 src/library/base/CMakeLists.txt                       |    2 
 src/library/locate/LocatorStrategy.cpp                |    2 
 src/library/os/windows/isvm/Native.cpp                |  437 ++++++++++++++++
 src/library/os/cpu_info.hpp                           |    6 
 src/library/os/execution_environment.hpp              |   25 
 src/library/os/cpu_info_common.cpp                    |    2 
 test/functional/CMakeLists.txt                        |   10 
 test/functional/standard-license_test.cpp             |    3 
 src/library/os/windows/isvm/main.cpp                  |   51 +
 src/library/base/file_utils.hpp                       |    0 
 src/library/base/file_utils.cpp                       |    2 
 src/library/locate/ApplicationFolder.cpp              |    2 
 src/library/os/windows/isvm/BIOSReader.h              |   22 
 test/functional/date_test.cpp                         |    2 
 src/library/os/windows/cpu_info.cpp                   |   48 +
 src/library/os/windows/execution_environment.cpp      |   39 +
 src/library/os/windows/isvm/Native.h                  |   18 
 /dev/null                                             |    1 
 doc/snippets/hardware.cpp                             |  266 ++++++++++
 src/library/hw_identifier/disk_strategy.cpp           |   19 
 src/library/locate/EnvironmentVarLocation.cpp         |    2 
 src/library/os/linux/network.cpp                      |   20 
 doc/CREDITS.md                                        |    9 
 src/library/os/windows/signature_verifier.cpp         |    9 
 src/library/hw_identifier/ethernet.cpp                |    2 
 src/library/os/windows/os-win.c                       |  134 ----
 src/library/hw_identifier/default_strategy.cpp        |    8 
 test/library/Os_Linux_test.cpp                        |   21 
 src/library/os/linux/cpu_info.cpp                     |    3 
 test/functional/crack_test.cpp                        |    3 
 42 files changed, 1,312 insertions(+), 230 deletions(-)

diff --git a/build/.gitkeep b/build/.gitkeep
deleted file mode 100644
index e69de29..0000000
--- a/build/.gitkeep
+++ /dev/null
diff --git a/doc/CREDITS.md b/doc/CREDITS.md
index 918606c..74b8e5e 100644
--- a/doc/CREDITS.md
+++ b/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.
-=============================
+
 
diff --git a/doc/snippets/hardware.cpp b/doc/snippets/hardware.cpp
new file mode 100644
index 0000000..bf4e0be
--- /dev/null
+++ b/doc/snippets/hardware.cpp
@@ -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;
+}
+*/
\ No newline at end of file
diff --git a/src/inspector/inspector.cpp b/src/inspector/inspector.cpp
index ee3a483..9ae38f5 100644
--- a/src/inspector/inspector.cpp
+++ b/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;
diff --git a/src/library/base/CMakeLists.txt b/src/library/base/CMakeLists.txt
index 5bed712..f0f9588 100644
--- a/src/library/base/CMakeLists.txt
+++ b/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
 )
diff --git a/src/library/base/FileUtils.cpp b/src/library/base/file_utils.cpp
similarity index 98%
rename from src/library/base/FileUtils.cpp
rename to src/library/base/file_utils.cpp
index f8fcc20..221cd77 100644
--- a/src/library/base/FileUtils.cpp
+++ b/src/library/base/file_utils.cpp
@@ -11,7 +11,7 @@
 #include <iostream>
 #include <algorithm>
 
-#include "FileUtils.hpp"
+#include "file_utils.hpp"
 
 namespace license {
 using namespace std;
diff --git a/src/library/base/FileUtils.hpp b/src/library/base/file_utils.hpp
similarity index 100%
rename from src/library/base/FileUtils.hpp
rename to src/library/base/file_utils.hpp
diff --git a/src/library/hw_identifier/default_strategy.cpp b/src/library/hw_identifier/default_strategy.cpp
index a770512..da21f20 100644
--- a/src/library/hw_identifier/default_strategy.cpp
+++ b/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 {
diff --git a/src/library/hw_identifier/disk_strategy.cpp b/src/library/hw_identifier/disk_strategy.cpp
index cec5da8..4fe212e 100644
--- a/src/library/hw_identifier/disk_strategy.cpp
+++ b/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);
 			}
 		}
diff --git a/src/library/hw_identifier/ethernet.cpp b/src/library/hw_identifier/ethernet.cpp
index 1d923e6..ce1d6de 100644
--- a/src/library/hw_identifier/ethernet.cpp
+++ b/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);
 
diff --git a/src/library/hw_identifier/hw_identifier.cpp b/src/library/hw_identifier/hw_identifier.cpp
index b0d31f8..5c163e7 100644
--- a/src/library/hw_identifier/hw_identifier.cpp
+++ b/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;
 }
 
diff --git a/src/library/hw_identifier/hw_identifier.hpp b/src/library/hw_identifier/hw_identifier.hpp
index d7cec0e..56d3716 100644
--- a/src/library/hw_identifier/hw_identifier.hpp
+++ b/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;
diff --git a/src/library/hw_identifier/hw_identifier_facade.cpp b/src/library/hw_identifier/hw_identifier_facade.cpp
index 45abb5d..755eb75 100644
--- a/src/library/hw_identifier/hw_identifier_facade.cpp
+++ b/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());
 		}
 	}
diff --git a/src/library/hw_identifier/identification_strategy.hpp b/src/library/hw_identifier/identification_strategy.hpp
index ad3e2de..22ded81 100644
--- a/src/library/hw_identifier/identification_strategy.hpp
+++ b/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"
 
diff --git a/src/library/hw_identifier/pc-identifiers.c b/src/library/hw_identifier/pc-identifiers.c
deleted file mode 100644
index 55ec2ba..0000000
--- a/src/library/hw_identifier/pc-identifiers.c
+++ /dev/null
@@ -1,311 +0,0 @@
-/*
- * pc-identifiers.c
- *
- *  Created on: Apr 16, 2014
- *
- */
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "../os/os.h"
-#include "pc-identifiers.h"
-#include "../base/base64.h"
-#include "../base/base.h"
-#ifdef __linux__
-#include <stdbool.h>
-#include <valgrind/memcheck.h>
-#else
-#ifdef __MINGW32__
-#include <windows.h>
-#else
-#include <Windows.h>
-#endif
-#endif
-
-static FUNCTION_RETURN generate_disk_pc_id(PcIdentifier *identifiers, unsigned int *num_identifiers, bool use_label);
-
-static FUNCTION_RETURN generate_ethernet_pc_id(PcIdentifier *identifiers, unsigned int *num_identifiers, int use_mac);
-
-static FUNCTION_RETURN generate_default_pc_id(PcIdentifier *identifiers, unsigned int *num_identifiers) {
-	size_t adapter_num, disk_num;
-	FUNCTION_RETURN result_adapterInfos, result_diskinfos, function_return;
-	unsigned int caller_identifiers, i, j, k, array_index;
-	DiskInfo *diskInfoPtr;
-	OsAdapterInfo *adapterInfoPtr;
-
-	if (identifiers == NULL || *num_identifiers == 0) {
-		result_adapterInfos = getAdapterInfos(NULL, &adapter_num);
-		if ((result_adapterInfos != FUNC_RET_OK) || (adapter_num == 0)) {
-			return generate_disk_pc_id(identifiers, num_identifiers, false);
-		}
-		result_diskinfos = getDiskInfos(NULL, &disk_num);
-		if ((result_diskinfos != FUNC_RET_OK) || (disk_num == 0)) {
-			return generate_ethernet_pc_id(identifiers, num_identifiers, true);
-		}
-		*num_identifiers = disk_num * adapter_num;
-		function_return = FUNC_RET_OK;
-	} else {
-		adapterInfoPtr = (OsAdapterInfo *)malloc((*num_identifiers) * sizeof(OsAdapterInfo));
-		adapter_num = *num_identifiers;
-		result_adapterInfos = getAdapterInfos(adapterInfoPtr, &adapter_num);
-		if (result_adapterInfos != FUNC_RET_OK && result_adapterInfos != FUNC_RET_BUFFER_TOO_SMALL) {
-			free(adapterInfoPtr);
-			return generate_disk_pc_id(identifiers, num_identifiers, false);
-		}
-		diskInfoPtr = (DiskInfo *)malloc((*num_identifiers) * sizeof(DiskInfo));
-		disk_num = *num_identifiers;
-		result_diskinfos = getDiskInfos(diskInfoPtr, &disk_num);
-		if (result_diskinfos != FUNC_RET_OK && result_diskinfos != FUNC_RET_BUFFER_TOO_SMALL) {
-			free(diskInfoPtr);
-			free(adapterInfoPtr);
-			return generate_ethernet_pc_id(identifiers, num_identifiers, true);
-		}
-		function_return = FUNC_RET_OK;
-
-		caller_identifiers = *num_identifiers;
-		for (i = 0; i < disk_num; i++) {
-			for (j = 0; j < adapter_num; j++) {
-				array_index = i * adapter_num + j;
-				if (array_index >= caller_identifiers) {
-					function_return = FUNC_RET_BUFFER_TOO_SMALL;
-					goto end;
-				}
-				for (k = 0; k < 6; k++)
-					identifiers[array_index][k] = diskInfoPtr[i].disk_sn[k + 2] ^ adapterInfoPtr[j].mac_address[k + 2];
-			}
-		}
-	end:
-#ifdef _MSC_VER
-		*num_identifiers = min(*num_identifiers, adapter_num * disk_num);
-#else
-		*num_identifiers = cmin(*num_identifiers, adapter_num * disk_num);
-#endif
-		free(diskInfoPtr);
-		free(adapterInfoPtr);
-	}
-	return function_return;
-}
-
-static FUNCTION_RETURN generate_ethernet_pc_id(PcIdentifier *identifiers, unsigned int *num_identifiers, int use_mac) {
-	return FUNC_RET_NOT_AVAIL;
-}
-
-/**
- *
- * Calculates all the possible identifiers for the current machine, for the
- * given calculation strategy requested. Pc identifiers are more than one,
- * for instance a machine with more than one disk and one network interface has
- * usually multiple identifiers.
- *
- * First 4 bit of each pc identifier are reserved 3 for the type of strategy
- * used in calculation and 1 for parity checks (not implemented here)
- *
- * @param identifiers
- * @param array_size
- * @param
- * @return
- */
-
-FUNCTION_RETURN generate_pc_id(PcIdentifier *identifiers, unsigned int *array_size, LCC_IDENTIFICATION_STRATEGY strategy) {
-	FUNCTION_RETURN result;
-	unsigned int i, j;
-	const unsigned int original_array_size = *array_size;
-	unsigned char strategy_num;
-	switch (strategy) {
-		case STRATEGY_DEFAULT:
-			result = generate_default_pc_id(identifiers, array_size);
-			break;
-		case STRATEGY_ETHERNET:
-			result = generate_ethernet_pc_id(identifiers, array_size, true);
-			break;
-		case STRATEGY_IP_ADDRESS:
-			result = generate_ethernet_pc_id(identifiers, array_size, false);
-			break;
-		case STRATEGY_DISK_NUM:
-			result = generate_disk_pc_id(identifiers, array_size, false);
-			break;
-		case STRATEGY_DISK_LABEL:
-			result = generate_disk_pc_id(identifiers, array_size, true);
-			break;
-		default:
-			return FUNC_RET_ERROR;
-	}
-
-	if (result == FUNC_RET_OK && identifiers != NULL) {
-		strategy_num = strategy << 5;
-		for (i = 0; i < *array_size; i++) {
-			// encode strategy in the first three bits of the pc_identifier
-			identifiers[i][0] = (identifiers[i][0] & 15) | strategy_num;
-		}
-		// fill array if larger
-		for (i = *array_size; i < original_array_size; i++) {
-			identifiers[i][0] = STRATEGY_UNKNOWN << 5;
-			for (j = 1; j < sizeof(PcIdentifier); j++) {
-				identifiers[i][j] = 42;  // padding
-			}
-		}
-	}
-	return result;
-}
-
-char *MakeCRC(char *BitString) {
-	static char Res[3];  // CRC Result
-	char CRC[2];
-	int i;
-
-	for (i = 0; i < 2; ++i) CRC[i] = 0;  // Init before calculation
-
-	for (i = 0; i < strlen(BitString); ++i) {
-		char doInvert = ('1' == BitString[i]) ^ CRC[1];  // XOR required?
-
-		CRC[1] = CRC[0];
-		CRC[0] = doInvert;
-	}
-
-	for (i = 0; i < 2; ++i) Res[1 - i] = CRC[i] ? '1' : '0';  // Convert binary to ASCII
-	Res[2] = 0;  // Set string terminator
-
-	return (Res);
-}
-
-FUNCTION_RETURN encode_pc_id(PcIdentifier identifier1, PcIdentifier identifier2, PcSignature pc_identifier_out) {
-	// TODO base62 encoding, now uses base64
-	PcIdentifier concat_identifiers[2];
-	char *b64_data = NULL;
-	int b64_size = 0;
-	const size_t concatIdentifiersSize = sizeof(PcIdentifier) * 2;
-	// concat_identifiers = (PcIdentifier *) malloc(concatIdentifiersSize);
-	memcpy(&concat_identifiers[0], identifier1, sizeof(PcIdentifier));
-	memcpy(&concat_identifiers[1], identifier2, sizeof(PcIdentifier));
-	b64_data = base64(concat_identifiers, concatIdentifiersSize, &b64_size);
-	if (b64_size > sizeof(PcSignature)) {
-		free(b64_data);
-		return FUNC_RET_BUFFER_TOO_SMALL;
-	}
-	sprintf(pc_identifier_out, "%.4s-%.4s-%.4s-%.4s", &b64_data[0], &b64_data[4], &b64_data[8], &b64_data[12]);
-	// free(concat_identifiers);
-	free(b64_data);
-	return FUNC_RET_OK;
-}
-
-FUNCTION_RETURN parity_check_id(PcSignature pc_identifier) { return FUNC_RET_OK; }
-
-FUNCTION_RETURN generate_user_pc_signature(PcSignature identifier_out, LCC_IDENTIFICATION_STRATEGY strategy) {
-	FUNCTION_RETURN result;
-	PcIdentifier *identifiers;
-	unsigned int req_buffer_size = 0;
-	result = generate_pc_id(NULL, &req_buffer_size, strategy);
-	if (result != FUNC_RET_OK) {
-		return result;
-	}
-	if (req_buffer_size == 0) {
-		return FUNC_RET_ERROR;
-	}
-	req_buffer_size = req_buffer_size < 2 ? 2 : req_buffer_size;
-	identifiers = (PcIdentifier *)malloc(sizeof(PcIdentifier) * req_buffer_size);
-	memset(identifiers, 0, sizeof(PcIdentifier) * req_buffer_size);
-	result = generate_pc_id(identifiers, &req_buffer_size, strategy);
-	if (result != FUNC_RET_OK) {
-		free(identifiers);
-		return result;
-	}
-#ifdef __linux__
-	VALGRIND_CHECK_VALUE_IS_DEFINED(identifiers[0]);
-	VALGRIND_CHECK_VALUE_IS_DEFINED(identifiers[1]);
-#endif
-	result = encode_pc_id(identifiers[0], identifiers[1], identifier_out);
-#ifdef __linux__
-	VALGRIND_CHECK_VALUE_IS_DEFINED(identifier_out);
-#endif
-	free(identifiers);
-	return result;
-}
-
-/**
- * Extract the two pc identifiers from the user provided code.
- * @param identifier1_out
- * @param identifier2_out
- * @param str_code: the code in the string format XXXX-XXXX-XXXX-XXXX
- * @return
- */
-static FUNCTION_RETURN decode_pc_id(PcIdentifier identifier1_out, PcIdentifier identifier2_out,
-									PcSignature pc_signature_in) {
-	// TODO base62 encoding, now uses base64
-
-	unsigned char *concat_identifiers = NULL;
-	char base64ids[17];
-	int identifiers_size;
-
-	sscanf(pc_signature_in, "%4s-%4s-%4s-%4s", &base64ids[0], &base64ids[4], &base64ids[8], &base64ids[12]);
-	concat_identifiers = unbase64(base64ids, 16, &identifiers_size);
-	if (identifiers_size > sizeof(PcIdentifier) * 2) {
-		free(concat_identifiers);
-		return FUNC_RET_BUFFER_TOO_SMALL;
-	}
-	memcpy(identifier1_out, concat_identifiers, sizeof(PcIdentifier));
-	memcpy(identifier2_out, concat_identifiers + sizeof(PcIdentifier), sizeof(PcIdentifier));
-	free(concat_identifiers);
-	return FUNC_RET_OK;
-}
-
-static LCC_IDENTIFICATION_STRATEGY strategy_from_pc_id(PcIdentifier identifier) {
-	return (LCC_IDENTIFICATION_STRATEGY)identifier[0] >> 5;
-}
-
-LCC_EVENT_TYPE validate_pc_signature(PcSignature str_code) {
-	PcIdentifier user_identifiers[2];
-	FUNCTION_RETURN result;
-	LCC_IDENTIFICATION_STRATEGY previous_strategy_id, current_strategy_id;
-	PcIdentifier *calculated_identifiers = NULL;
-	unsigned int calc_identifiers_size = 0;
-	int i = 0, j = 0;
-	// bool found;
-#ifdef _DEBUG
-	printf("Comparing pc identifiers: \n");
-#endif
-	result = decode_pc_id(user_identifiers[0], user_identifiers[1], str_code);
-	if (result != FUNC_RET_OK) {
-		return result;
-	}
-	previous_strategy_id = STRATEGY_UNKNOWN;
-	// found = false;
-	for (i = 0; i < 2; i++) {
-		current_strategy_id = strategy_from_pc_id(user_identifiers[i]);
-		if (current_strategy_id == STRATEGY_UNKNOWN && previous_strategy_id == STRATEGY_UNKNOWN && i == 1) {
-			free(calculated_identifiers);
-			printf("Comparing pc identifiers: %d %d %d %s\n", current_strategy_id, previous_strategy_id, i, str_code);
-			return LICENSE_MALFORMED;
-		} else if (current_strategy_id == STRATEGY_UNKNOWN) {
-			continue;
-		}
-		if (current_strategy_id != previous_strategy_id) {
-			if (calculated_identifiers != NULL) {
-				free(calculated_identifiers);
-			}
-			previous_strategy_id = current_strategy_id;
-			generate_pc_id(NULL, &calc_identifiers_size, current_strategy_id);
-			calculated_identifiers = (PcIdentifier *)malloc(sizeof(PcIdentifier) * calc_identifiers_size);
-			memset(calculated_identifiers, 0, sizeof(PcIdentifier) * calc_identifiers_size);
-			generate_pc_id(calculated_identifiers, &calc_identifiers_size, current_strategy_id);
-		}
-		// maybe skip the byte 0
-		for (j = 0; j < calc_identifiers_size; j++) {
-#ifdef _DEBUG
-			printf(
-				"generated id: %02x%02x%02x%02x%02x%02x index %d, user_supplied id %02x%02x%02x%02x%02x%02x idx: %d\n",
-				calculated_identifiers[j][0], calculated_identifiers[j][1], calculated_identifiers[j][2],
-				calculated_identifiers[j][3], calculated_identifiers[j][4], calculated_identifiers[j][5], j,
-				user_identifiers[i][0], user_identifiers[i][1], user_identifiers[i][2], user_identifiers[i][3],
-				user_identifiers[i][4], user_identifiers[i][5], i);
-
-#endif
-			if (!memcmp(user_identifiers[i], calculated_identifiers[j], sizeof(PcIdentifier))) {
-				free(calculated_identifiers);
-				return LICENSE_OK;
-			}
-		}
-	}
-	free(calculated_identifiers);
-	return IDENTIFIERS_MISMATCH;
-}
diff --git a/src/library/hw_identifier/pc-identifiers.h b/src/library/hw_identifier/pc-identifiers.h
deleted file mode 100644
index d7d3b14..0000000
--- a/src/library/hw_identifier/pc-identifiers.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * pc-identifiers.h
- *
- *  Created on: Apr 16, 2014
- *
- */
-
-#ifndef PC_IDENTIFIERS_H_
-#define PC_IDENTIFIERS_H_
-
-#include <licensecc/datatypes.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#include "../base/base.h"
-
-typedef char PcSignature[LCC_API_PC_IDENTIFIER_SIZE + 1];
-
-FUNCTION_RETURN generate_pc_id(PcIdentifier * identifiers, unsigned int * array_size,
-		LCC_IDENTIFICATION_STRATEGY strategy);
-
-LCC_EVENT_TYPE validate_pc_signature(PcSignature str_code);
-
-/**
- * Generates an UserPcIdentifier.
- *
- * @param identifier_out
- * @param strategy
- * @return
- */
-FUNCTION_RETURN generate_user_pc_signature(PcSignature identifier_out, LCC_IDENTIFICATION_STRATEGY strategy);
-
-#ifdef __cplusplus
-}
-#endif
-#endif /* PC_IDENTIFIERS_H_ */
diff --git a/src/library/locate/ApplicationFolder.cpp b/src/library/locate/ApplicationFolder.cpp
index b13fedd..8bc7f5a 100644
--- a/src/library/locate/ApplicationFolder.cpp
+++ b/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 {
diff --git a/src/library/locate/EnvironmentVarLocation.cpp b/src/library/locate/EnvironmentVarLocation.cpp
index 070ad8d..e74228a 100644
--- a/src/library/locate/EnvironmentVarLocation.cpp
+++ b/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 {
diff --git a/src/library/locate/ExternalDefinition.cpp b/src/library/locate/ExternalDefinition.cpp
index 7add948..a5309de 100644
--- a/src/library/locate/ExternalDefinition.cpp
+++ b/src/library/locate/ExternalDefinition.cpp
@@ -9,19 +9,19 @@
 #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 {
-using namespace std;
+	using namespace std;
 
 ExternalDefinition::ExternalDefinition(const LicenseLocation *location)
 	: LocatorStrategy("ExternalDefinition"), m_location(location) {}
diff --git a/src/library/locate/LocatorStrategy.cpp b/src/library/locate/LocatorStrategy.cpp
index 5e64648..04c722d 100644
--- a/src/library/locate/LocatorStrategy.cpp
+++ b/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 {
diff --git a/src/library/os/CMakeLists.txt b/src/library/os/CMakeLists.txt
index 986550f..c22b806 100644
--- a/src/library/os/CMakeLists.txt
+++ b/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)
diff --git a/src/library/os/cpu_info.hpp b/src/library/os/cpu_info.hpp
index 04da89b..662e181 100644
--- a/src/library/os/cpu_info.hpp
+++ b/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_ */
diff --git a/src/library/os/cpu_info_common.cpp b/src/library/os/cpu_info_common.cpp
index d75ccf1..119b77e 100644
--- a/src/library/os/cpu_info_common.cpp
+++ b/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
diff --git a/src/library/os/execution_environment.hpp b/src/library/os/execution_environment.hpp
index ce3fb63..bc503fb 100644
--- a/src/library/os/execution_environment.hpp
+++ b/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_ */
diff --git a/src/library/os/execution_environment_common.cpp b/src/library/os/execution_environment_common.cpp
new file mode 100644
index 0000000..9fa2a38
--- /dev/null
+++ b/src/library/os/execution_environment_common.cpp
@@ -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
diff --git a/src/library/os/linux/cpu_info.cpp b/src/library/os/linux/cpu_info.cpp
index 4b5ff85..b052a03 100644
--- a/src/library/os/linux/cpu_info.cpp
+++ b/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 */
diff --git a/src/library/os/linux/execution_environment.cpp b/src/library/os/linux/execution_environment.cpp
index bbddd75..9aad864 100644
--- a/src/library/os/linux/execution_environment.cpp
+++ b/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
diff --git a/src/library/os/linux/network.cpp b/src/library/os/linux/network.cpp
index e456989..475463b 100644
--- a/src/library/os/linux/network.cpp
+++ b/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;
-}
 
 /**
  *
diff --git a/src/library/os/os.h b/src/library/os/os.h
index 9fda7c7..00abae2 100644
--- a/src/library/os/os.h
+++ b/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);
diff --git a/src/library/os/windows/.gitignore b/src/library/os/windows/.gitignore
deleted file mode 100644
index f3d0437..0000000
--- a/src/library/os/windows/.gitignore
+++ /dev/null
@@ -1 +0,0 @@
-/isvm/
diff --git a/src/library/os/windows/cpu_info.cpp b/src/library/os/windows/cpu_info.cpp
new file mode 100644
index 0000000..192e178
--- /dev/null
+++ b/src/library/os/windows/cpu_info.cpp
@@ -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 */
diff --git a/src/library/os/windows/execution_environment.cpp b/src/library/os/windows/execution_environment.cpp
new file mode 100644
index 0000000..86513d5
--- /dev/null
+++ b/src/library/os/windows/execution_environment.cpp
@@ -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
diff --git a/src/library/os/windows/isvm/BIOSReader.cpp b/src/library/os/windows/isvm/BIOSReader.cpp
new file mode 100644
index 0000000..5d1b146
--- /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;
+}
diff --git a/src/library/os/windows/isvm/BIOSReader.h b/src/library/os/windows/isvm/BIOSReader.h
new file mode 100644
index 0000000..4fcfb05
--- /dev/null
+++ b/src/library/os/windows/isvm/BIOSReader.h
@@ -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
diff --git a/src/library/os/windows/isvm/Native.cpp b/src/library/os/windows/isvm/Native.cpp
new file mode 100644
index 0000000..99fbf8f
--- /dev/null
+++ b/src/library/os/windows/isvm/Native.cpp
@@ -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;
+}
diff --git a/src/library/os/windows/isvm/Native.h b/src/library/os/windows/isvm/Native.h
new file mode 100644
index 0000000..5124c8d
--- /dev/null
+++ b/src/library/os/windows/isvm/Native.h
@@ -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);
+
diff --git a/src/library/os/windows/isvm/main.cpp b/src/library/os/windows/isvm/main.cpp
new file mode 100644
index 0000000..105c105
--- /dev/null
+++ b/src/library/os/windows/isvm/main.cpp
@@ -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;
+}
+
diff --git a/src/library/os/windows/network.cpp b/src/library/os/windows/network.cpp
new file mode 100644
index 0000000..fd111aa
--- /dev/null
+++ b/src/library/os/windows/network.cpp
@@ -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
diff --git a/src/library/os/windows/os-win.c b/src/library/os/windows/os-win.c
index aa6c5f3..ef56baf 100644
--- a/src/library/os/windows/os-win.c
+++ b/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;
-}
 
diff --git a/src/library/os/windows/signature_verifier.cpp b/src/library/os/windows/signature_verifier.cpp
index 6e9b62d..a47c7dd 100644
--- a/src/library/os/windows/signature_verifier.cpp
+++ b/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;
 }
 
diff --git a/test/functional/CMakeLists.txt b/test/functional/CMakeLists.txt
index c081de9..6d2397b 100644
--- a/test/functional/CMakeLists.txt
+++ b/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})
 
diff --git a/test/functional/crack_test.cpp b/test/functional/crack_test.cpp
index fcf6143..b427928 100644
--- a/test/functional/crack_test.cpp
+++ b/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 {
diff --git a/test/functional/date_test.cpp b/test/functional/date_test.cpp
index 999331c..9638f1b 100644
--- a/test/functional/date_test.cpp
+++ b/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) {
diff --git a/test/functional/standard-license_test.cpp b/test/functional/standard-license_test.cpp
index 8bb45b1..4293d11 100644
--- a/test/functional/standard-license_test.cpp
+++ b/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;
diff --git a/test/library/Os_Linux_test.cpp b/test/library/Os_Linux_test.cpp
index 21e94e0..5306bb0 100644
--- a/test/library/Os_Linux_test.cpp
+++ b/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");
 		}

--
Gitblit v1.9.1