Skip to content

Commit

Permalink
Saner winQueryRegistry implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
captainurist committed Nov 5, 2023
1 parent e2233e7 commit 7731d38
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 60 deletions.
36 changes: 18 additions & 18 deletions src/Application/GamePathResolver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@
#include "Library/Logger/Logger.h"
#include "Library/Platform/Interface/Platform.h"

static std::string _resolvePath(Platform *platform, const char *envVarOverride, const std::vector<const wchar_t *> &registryKeys);
static std::string _resolvePath(Platform *platform, const char *envVarOverride, const std::vector<const char *> &registryKeys);

std::string resolveMm6Path(Platform *platform) {
return _resolvePath(
platform,
mm6PathOverrideKey,
{
L"HKEY_LOCAL_MACHINE/SOFTWARE/GOG.com/Games/1207661253/PATH",
L"HKEY_LOCAL_MACHINE/SOFTWARE/GOG.com/GOGMM6/PATH",
L"HKEY_LOCAL_MACHINE/SOFTWARE/New World Computing/Might and Magic\x00AE VI/1.0/AppPath",
L"HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/GOG.com/Games/1207661253/PATH",
L"HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/GOG.com/GOGMM6/PATH",
L"HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/New World Computing/Might and Magic\x00AE VI/1.0/AppPath",
"HKEY_LOCAL_MACHINE/SOFTWARE/GOG.com/Games/1207661253/PATH",
"HKEY_LOCAL_MACHINE/SOFTWARE/GOG.com/GOGMM6/PATH",
"HKEY_LOCAL_MACHINE/SOFTWARE/New World Computing/Might and Magic\x00AE VI/1.0/AppPath",
"HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/GOG.com/Games/1207661253/PATH",
"HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/GOG.com/GOGMM6/PATH",
"HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/New World Computing/Might and Magic\x00AE VI/1.0/AppPath",
}
);
}
Expand All @@ -28,12 +28,12 @@ std::string resolveMm7Path(Platform *platform) {
platform,
mm7PathOverrideKey,
{
L"HKEY_LOCAL_MACHINE/SOFTWARE/GOG.com/Games/1207658916/Path",
L"HKEY_LOCAL_MACHINE/SOFTWARE/GOG.com/GOGMM7/PATH",
L"HKEY_LOCAL_MACHINE/SOFTWARE/New World Computing/Might and Magic VII/1.0/AppPath",
L"HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/GOG.com/Games/1207658916/Path",
L"HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/GOG.com/GOGMM7/PATH",
L"HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/New World Computing/Might and Magic VII/1.0/AppPath",
"HKEY_LOCAL_MACHINE/SOFTWARE/GOG.com/Games/1207658916/Path",
"HKEY_LOCAL_MACHINE/SOFTWARE/GOG.com/GOGMM7/PATH",
"HKEY_LOCAL_MACHINE/SOFTWARE/New World Computing/Might and Magic VII/1.0/AppPath",
"HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/GOG.com/Games/1207658916/Path",
"HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/GOG.com/GOGMM7/PATH",
"HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/New World Computing/Might and Magic VII/1.0/AppPath",
}
);
}
Expand All @@ -44,10 +44,10 @@ std::string resolveMm8Path(Platform *platform) {
platform,
mm8PathOverrideKey,
{
L"HKEY_LOCAL_MACHINE/SOFTWARE/GOG.com/GOGMM8/PATH",
L"HKEY_LOCAL_MACHINE/SOFTWARE/New World Computing/Might and Magic Day of the Destroyer/1.0/AppPath",
L"HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/GOG.com/GOGMM8/PATH",
L"HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/New World Computing/Might and Magic Day of the Destroyer/1.0/AppPath",
"HKEY_LOCAL_MACHINE/SOFTWARE/GOG.com/GOGMM8/PATH",
"HKEY_LOCAL_MACHINE/SOFTWARE/New World Computing/Might and Magic Day of the Destroyer/1.0/AppPath",
"HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/GOG.com/GOGMM8/PATH",
"HKEY_LOCAL_MACHINE/SOFTWARE/WOW6432Node/New World Computing/Might and Magic Day of the Destroyer/1.0/AppPath",
}
);
}
Expand All @@ -56,7 +56,7 @@ std::string resolveMm8Path(Platform *platform) {
static std::string _resolvePath(
Platform *platform,
const char *envVarOverride,
const std::vector<const wchar_t *> &registryKeys
const std::vector<const char *> &registryKeys
) {
#ifdef __ANDROID__
// TODO: find a better way to deal with paths and remove this android specific block.
Expand Down
2 changes: 1 addition & 1 deletion src/Library/Platform/Interface/Platform.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ class Platform {
* @param path Registry path to query.
* @return Value at the given path, or an empty string in case of an error.
*/
virtual std::string winQueryRegistry(const std::wstring &path) const = 0;
virtual std::string winQueryRegistry(const std::string &path) const = 0;

/**
* Get various application filesystem paths.
Expand Down
2 changes: 1 addition & 1 deletion src/Library/Platform/Null/NullPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ int64_t NullPlatform::tickCount() const {
return 0; // Time's not flowing in null platform.
}

std::string NullPlatform::winQueryRegistry(const std::wstring &path) const {
std::string NullPlatform::winQueryRegistry(const std::string &path) const {
return {};
}

Expand Down
2 changes: 1 addition & 1 deletion src/Library/Platform/Null/NullPlatform.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class NullPlatform : public Platform {
virtual std::vector<Recti> displayGeometries() const override;
virtual void showMessageBox(const std::string &title, const std::string &message) const override;
virtual int64_t tickCount() const override;
virtual std::string winQueryRegistry(const std::wstring &path) const override;
virtual std::string winQueryRegistry(const std::string &path) const override;
virtual std::string storagePath(const PlatformStorage type) const override;

private:
Expand Down
2 changes: 1 addition & 1 deletion src/Library/Platform/Proxy/ProxyPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ int64_t ProxyPlatform::tickCount() const {
return nonNullBase()->tickCount();
}

std::string ProxyPlatform::winQueryRegistry(const std::wstring &path) const {
std::string ProxyPlatform::winQueryRegistry(const std::string &path) const {
return nonNullBase()->winQueryRegistry(path);
}

Expand Down
2 changes: 1 addition & 1 deletion src/Library/Platform/Proxy/ProxyPlatform.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,6 @@ class ProxyPlatform : public ProxyBase<Platform> {
virtual std::vector<Recti> displayGeometries() const override;
virtual void showMessageBox(const std::string &title, const std::string &message) const override;
virtual int64_t tickCount() const override;
virtual std::string winQueryRegistry(const std::wstring &path) const override;
virtual std::string winQueryRegistry(const std::string &path) const override;
virtual std::string storagePath(const PlatformStorage type) const override;
};
2 changes: 1 addition & 1 deletion src/Library/Platform/Sdl/SdlPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ int64_t SdlPlatform::tickCount() const {
return SDL_GetTicks64();
}

std::string SdlPlatform::winQueryRegistry(const std::wstring &) const {
std::string SdlPlatform::winQueryRegistry(const std::string &) const {
return {};
}

Expand Down
2 changes: 1 addition & 1 deletion src/Library/Platform/Sdl/SdlPlatform.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class SdlPlatform: public Platform {

virtual int64_t tickCount() const override;

virtual std::string winQueryRegistry(const std::wstring &path) const override;
virtual std::string winQueryRegistry(const std::string &path) const override;

virtual std::string storagePath(const PlatformStorage type) const override;

Expand Down
74 changes: 40 additions & 34 deletions src/Library/Platform/Win/WinPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,32 @@

#include "Utility/String.h"

static bool OS_GetAppStringRecursive(HKEY parent_key, const wchar_t *path, char *out_string, int out_string_size, int flags) {
static std::string toUtf8(std::wstring_view wstr) {
std::string result;

int len = WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr.size(), nullptr, 0, nullptr, nullptr);
if (len == 0)
return result;

result.resize(len);
WideCharToMultiByte(CP_UTF8, 0, wstr.data(), wstr.size(), result.data(), len, nullptr, nullptr);
return result;
}

static std::wstring toUtf16(std::string_view str) {
std::wstring result;

int len = MultiByteToWideChar(CP_UTF8, 0, str.data(), str.size(), nullptr, 0);
if (len == 0)
return result;

result.resize(len);
MultiByteToWideChar(CP_UTF8, 0, str.data(), str.size(), result.data(), len);
return result;
}

// TODO(captainurist): revisit this code once I'm on a win machine.
static std::wstring OS_GetAppStringRecursive(HKEY parent_key, const wchar_t *path, int flags) {
wchar_t current_key[256];
wchar_t path_tail[4096];

Expand All @@ -32,7 +57,7 @@ static bool OS_GetAppStringRecursive(HKEY parent_key, const wchar_t *path, char
else if (!wcsicmp(current_key, L"HKEY_USERS"))
parent_key = HKEY_USERS;
else
return false;
return {};

delimiter = wcsstr(path_tail, L"/");
if (delimiter) {
Expand All @@ -41,62 +66,43 @@ static bool OS_GetAppStringRecursive(HKEY parent_key, const wchar_t *path, char

wcscpy(path_tail, delimiter + 1);
} else {
return false;
return {};
}
}

if (!wcscmp(current_key, L"WOW6432Node")) {
return OS_GetAppStringRecursive(parent_key, path_tail, out_string, out_string_size, KEY_WOW64_32KEY);
return OS_GetAppStringRecursive(parent_key, path_tail, KEY_WOW64_32KEY);
}

bool result = false;
HKEY key;
if (!RegOpenKeyExW(parent_key, current_key, 0, KEY_READ | flags, &key)) {
result = OS_GetAppStringRecursive(key, path_tail, out_string, out_string_size, 0);
std::wstring result = OS_GetAppStringRecursive(key, path_tail, 0);
RegCloseKey(key);
return result;
}

return result;
return {};
} else {
auto regValue = std::make_unique<wchar_t[]>(out_string_size + 1);
for (int i = 0; i < out_string_size; ++i) {
regValue.get()[i] = L'x';
out_string[i] = 'x';
}
DWORD regNumBytesRead = sizeof(wchar_t) * (out_string_size + 1);
std::array<wchar_t, 8192> buffer = {{}};
DWORD regNumBytesRead = sizeof(buffer);
LSTATUS status = RegGetValueW(
parent_key,
nullptr,
path,
RRF_RT_REG_SZ | RRF_RT_REG_EXPAND_SZ,
nullptr,
regValue.get(),
buffer.data(),
&regNumBytesRead
);
if (status == ERROR_SUCCESS) {
if (regNumBytesRead > 0) {
int numBytesConverted = WideCharToMultiByte(CP_ACP, 0, regValue.get(), -1, out_string, out_string_size, nullptr, nullptr);
if (0 == numBytesConverted) {
status = ERROR_PATH_NOT_FOUND;
}
} else {
status = ERROR_PATH_NOT_FOUND;
}
}

if (status != ERROR_SUCCESS) {
strcpy(out_string, "");
}
if (status == ERROR_SUCCESS)
return buffer.data();

return status == ERROR_SUCCESS;
return {};
}
}

std::string WinPlatform::winQueryRegistry(const std::wstring &path) const {
char buffer[8192];
if (OS_GetAppStringRecursive(nullptr, path.c_str(), buffer, sizeof(buffer), 0))
return std::string(buffer);
return {};
std::string WinPlatform::winQueryRegistry(const std::string &path) const {
return toUtf8(OS_GetAppStringRecursive(NULL, toUtf16(path).c_str(), 0));
}

std::unique_ptr<Platform> Platform::createStandardPlatform(Logger *logger) {
Expand Down
2 changes: 1 addition & 1 deletion src/Library/Platform/Win/WinPlatform.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ class WinPlatform : public SdlPlatform {
public:
using SdlPlatform::SdlPlatform;

virtual std::string winQueryRegistry(const std::wstring &path) const override;
virtual std::string winQueryRegistry(const std::string &path) const override;
};

0 comments on commit 7731d38

Please sign in to comment.