+
+FS::Path get_program_files_x86_dir()
+{
+#ifdef _WIN32
+ wchar_t *program_files_x86_ptr = 0;
+ HRESULT err = SHGetKnownFolderPath(FOLDERID_ProgramFilesX86, 0, NULL, &program_files_x86_ptr);
+ if(err!=S_OK)
+ throw runtime_error("Can't get Program Files path");
+
+ unsigned len = wcslen(program_files_x86_ptr);
+ FS::Path program_files_x86 = StringCodec::transcode<StringCodec::Utf16Le, StringCodec::Utf8>(
+ string(reinterpret_cast<const char *>(program_files_x86_ptr), len*sizeof(wchar_t)));
+
+ CoTaskMemFree(program_files_x86_ptr);
+
+ return program_files_x86;
+#else
+ return "/mnt/c/Program Files (x86)";
+#endif
+}
+
+template<>
+string get_registry_value<string>(const string &path)
+{
+#ifdef _WIN32
+ string::size_type first_sep = path.find('\\');
+ string::size_type last_sep = path.rfind('\\');
+ string root = path.substr(0, first_sep);
+ string key_path = path.substr(first_sep+1, last_sep-first_sep-1);
+ string value_name = path.substr(last_sep+1);
+
+ HKEY root_handle;
+ if(root=="HKCR")
+ root_handle = HKEY_CLASSES_ROOT;
+ else if(root=="HKCC")
+ root_handle = HKEY_CURRENT_CONFIG;
+ else if(root=="HKCU")
+ root_handle = HKEY_CURRENT_USER;
+ else if(root=="HKLM")
+ root_handle = HKEY_LOCAL_MACHINE;
+ else if(root=="HKU")
+ root_handle = HKEY_USERS;
+ else
+ throw invalid_argument("get_registry_value");
+
+ HKEY key;
+ LSTATUS err = RegOpenKeyEx(root_handle, key_path.c_str(), 0, KEY_READ, &key);
+ if(err!=ERROR_SUCCESS)
+ throw Msp::system_error("RegOpenKey", err);
+
+ DWORD value_len;
+ err = RegGetValue(key, 0, value_name.c_str(), RRF_RT_REG_SZ, 0, 0, &value_len);
+ if(err!=ERROR_SUCCESS)
+ throw Msp::system_error("RegGetValue", err);
+
+ char *buffer = new char[value_len];
+ err = RegGetValue(key, 0, value_name.c_str(), RRF_RT_REG_SZ, 0, buffer, &value_len);
+ if(err!=ERROR_SUCCESS)
+ {
+ delete[] buffer;
+ throw Msp::system_error("RegGetValue", err);
+ }
+
+ string result(buffer);
+ delete[] buffer;
+ return result;
+#else
+ (void)path;
+ return string();
+#endif
+}