From 4094690282b49efdc53c7990065f14c0b41dc09d Mon Sep 17 00:00:00 2001 From: Sajid Date: Tue, 28 Jan 2025 15:37:38 +0600 Subject: [PATCH] Implement reading path and unicode string from windows registry --- UnleashedRecomp/main.cpp | 2 +- UnleashedRecomp/os/win32/registry_win32.inl | 67 +++++++++++++++------ UnleashedRecomp/user/registry.h | 2 +- 3 files changed, 52 insertions(+), 19 deletions(-) diff --git a/UnleashedRecomp/main.cpp b/UnleashedRecomp/main.cpp index 3228d1b7..a88882ba 100644 --- a/UnleashedRecomp/main.cpp +++ b/UnleashedRecomp/main.cpp @@ -176,7 +176,7 @@ int main(int argc, char *argv[]) if (!Registry::RootDirectoryPath.empty()) { if (!os::process::SetWorkingDirectory(std::filesystem::path(Registry::RootDirectoryPath))) - LOGFN_ERROR("Failed to set working directory: \"{}\"", Registry::RootDirectoryPath); + LOGFN_ERROR("Failed to set working directory: \"{}\"", Registry::RootDirectoryPath.string()); } HostStartup(); diff --git a/UnleashedRecomp/os/win32/registry_win32.inl b/UnleashedRecomp/os/win32/registry_win32.inl index 3866f4db..df0284f2 100644 --- a/UnleashedRecomp/os/win32/registry_win32.inl +++ b/UnleashedRecomp/os/win32/registry_win32.inl @@ -16,44 +16,77 @@ bool os::registry::ReadValue(const std::string& name, T& data) if (RegOpenKeyExW(HKEY_CURRENT_USER, g_registryRoot, 0, KEY_READ, &hKey) != ERROR_SUCCESS) return false; - BYTE buffer[512]; - DWORD bufferSize = sizeof(buffer); + wchar_t wideName[128]; + int wideNameSize = MultiByteToWideChar(CP_UTF8, 0, name.c_str(), name.size(), wideName, sizeof(wideName)); + if (wideNameSize == 0) + { + return false; + } + + wideName[wideNameSize] = 0; + DWORD bufferSize = 0; DWORD dataType = 0; - auto result = RegQueryValueExA(hKey, name.c_str(), NULL, &dataType, buffer, &bufferSize); - - RegCloseKey(hKey); + auto result = RegQueryValueExW(hKey, wideName, NULL, &dataType, nullptr, &bufferSize); if (result != ERROR_SUCCESS) + { + RegCloseKey(hKey); return false; + } + result = ERROR_INVALID_FUNCTION; if constexpr (std::is_same_v) { - if (dataType != REG_SZ) - return false; + if (dataType == REG_SZ) + { + std::vector buffer{}; + buffer.reserve(bufferSize); + result = RegQueryValueExW(hKey, wideName, nullptr, nullptr, buffer.data(), &bufferSize); - data = std::string((char*)buffer, bufferSize - 1); + if (result == ERROR_SUCCESS) + { + int valueSize = WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)buffer.data(), (bufferSize / sizeof(wchar_t)) - 1, nullptr, 0, nullptr, nullptr); + data.resize(valueSize); + WideCharToMultiByte(CP_UTF8, 0, (wchar_t*)buffer.data(), (bufferSize / sizeof(wchar_t)) - 1, data.data(), valueSize, nullptr, nullptr); + } + } + } + else if constexpr (std::is_same_v) + { + if (dataType == REG_SZ) + { + std::vector buffer{}; + buffer.reserve(bufferSize); + result = RegQueryValueExW(hKey, wideName, nullptr, nullptr, buffer.data(), &bufferSize); + + if (result == ERROR_SUCCESS) + { + data = reinterpret_cast(buffer.data()); + } + } } else if constexpr (std::is_same_v) { - if (dataType != REG_DWORD) - return false; - - data = *(uint32_t*)buffer; + if (dataType == REG_DWORD) + { + result = RegQueryValueExW(hKey, wideName, nullptr, nullptr, (BYTE*)&data, &bufferSize); + } } else if constexpr (std::is_same_v) { - if (dataType != REG_QWORD) - return false; - - data = *(uint32_t*)buffer; + if (dataType == REG_QWORD) + { + result = RegQueryValueExW(hKey, wideName, nullptr, nullptr, (BYTE*)&data, &bufferSize); + } } else { static_assert(false, "Unsupported data type."); } - return true; + RegCloseKey(hKey); + return result == ERROR_SUCCESS; } template diff --git a/UnleashedRecomp/user/registry.h b/UnleashedRecomp/user/registry.h index b5e21b50..867d6f0b 100644 --- a/UnleashedRecomp/user/registry.h +++ b/UnleashedRecomp/user/registry.h @@ -3,7 +3,7 @@ class Registry { public: - inline static std::string RootDirectoryPath; + inline static std::filesystem::path RootDirectoryPath; static void Load(); static void Save();