]> git.tdb.fi Git - builder.git/blob - source/sysutils.cpp
Add drivers for the MSVC toolchain
[builder.git] / source / sysutils.cpp
1 #define _WIN32_WINNT _WIN32_WINNT_VISTA
2 #define WIN32_LEAN_AND_MEAN
3 #define INITGUID
4 #ifdef _WIN32
5 #include <windows.h>
6 #include <shlobj.h>
7 #include <knownfolders.h>
8 #else
9 #include <sys/utsname.h>
10 #endif
11 #include <msp/core/systemerror.h>
12 #include <msp/stringcodec/utf16.h>
13 #include <msp/stringcodec/utf8.h>
14 #include <msp/strings/format.h>
15 #include <msp/strings/utils.h>
16 #include "sysutils.h"
17
18 #if defined(_WIN32) && !defined(PROCESSOR_ARCHITECTURE_ARM64)
19 #define PROCESSOR_ARCHITECTURE_ARM64 12
20 #endif
21
22 using namespace std;
23 using namespace Msp;
24
25 string get_system_type()
26 {
27 #ifdef _WIN32
28         SYSTEM_INFO sysinfo;
29         GetSystemInfo(&sysinfo);
30         WORD machine = sysinfo.wProcessorArchitecture;
31         if(machine==PROCESSOR_ARCHITECTURE_AMD64 || machine==PROCESSOR_ARCHITECTURE_INTEL)
32                 return "x86-windows";
33         else if(machine==PROCESSOR_ARCHITECTURE_ARM || machine==PROCESSOR_ARCHITECTURE_ARM64)
34                 return "arm-windows";
35 #else
36         utsname un;
37         if(uname(&un)==0)
38                 return tolower(format("%s-%s", un.sysname, un.machine));
39 #endif
40
41         return string();
42 }
43
44 FS::Path get_program_files_x86_dir()
45 {
46 #ifdef _WIN32
47         wchar_t *program_files_x86_ptr = 0;
48         HRESULT err = SHGetKnownFolderPath(FOLDERID_ProgramFilesX86, 0, NULL, &program_files_x86_ptr);
49         if(err!=S_OK)
50                 throw runtime_error("Can't get Program Files path");
51
52         unsigned len = wcslen(program_files_x86_ptr);
53         FS::Path program_files_x86 = StringCodec::transcode<StringCodec::Utf16Le, StringCodec::Utf8>(
54                 string(reinterpret_cast<const char *>(program_files_x86_ptr), len*sizeof(wchar_t)));
55
56         CoTaskMemFree(program_files_x86_ptr);
57
58         return program_files_x86;
59 #else
60         return "/mnt/c/Program Files (x86)";
61 #endif
62 }
63
64 template<>
65 string get_registry_value<string>(const string &path)
66 {
67 #ifdef _WIN32
68         string::size_type first_sep = path.find('\\');
69         string::size_type last_sep = path.rfind('\\');
70         string root = path.substr(0, first_sep);
71         string key_path = path.substr(first_sep+1, last_sep-first_sep-1);
72         string value_name = path.substr(last_sep+1);
73
74         HKEY root_handle;
75         if(root=="HKCR")
76                 root_handle = HKEY_CLASSES_ROOT;
77         else if(root=="HKCC")
78                 root_handle = HKEY_CURRENT_CONFIG;
79         else if(root=="HKCU")
80                 root_handle = HKEY_CURRENT_USER;
81         else if(root=="HKLM")
82                 root_handle = HKEY_LOCAL_MACHINE;
83         else if(root=="HKU")
84                 root_handle = HKEY_USERS;
85         else
86                 throw invalid_argument("get_registry_value");
87
88         HKEY key;
89         LSTATUS err = RegOpenKeyEx(root_handle, key_path.c_str(), 0, KEY_READ, &key);
90         if(err!=ERROR_SUCCESS)
91                 throw Msp::system_error("RegOpenKey", err);
92
93         DWORD value_len;
94         err = RegGetValue(key, 0, value_name.c_str(), RRF_RT_REG_SZ, 0, 0, &value_len);
95         if(err!=ERROR_SUCCESS)
96                 throw Msp::system_error("RegGetValue", err);
97
98         char *buffer = new char[value_len];
99         err = RegGetValue(key, 0, value_name.c_str(), RRF_RT_REG_SZ, 0, buffer, &value_len);
100         if(err!=ERROR_SUCCESS)
101         {
102                 delete[] buffer;
103                 throw Msp::system_error("RegGetValue", err);
104         }
105
106         string result(buffer);
107         delete[] buffer;
108         return result;
109 #else
110         (void)path;
111         return string();
112 #endif
113 }