diff --git a/Source/Core/Common/CommonFuncs.cpp b/Source/Core/Common/CommonFuncs.cpp index 7b109e81c5..a8c1abfea2 100644 --- a/Source/Core/Common/CommonFuncs.cpp +++ b/Source/Core/Common/CommonFuncs.cpp @@ -49,4 +49,27 @@ std::string GetLastErrorString() MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), error_message, BUFFER_SIZE, nullptr); return std::string(error_message); } + +// Obtains a full path to the specified module. +std::optional GetModuleName(void* hInstance) +{ + DWORD max_size = 50; // Start with space for 50 characters and grow if needed + std::wstring name(max_size, L'\0'); + + DWORD size; + while ((size = GetModuleFileNameW(static_cast(hInstance), name.data(), max_size)) == + max_size && + GetLastError() == ERROR_INSUFFICIENT_BUFFER) + { + max_size *= 2; + name.resize(max_size); + } + + if (size == 0) + { + return std::nullopt; + } + name.resize(size); + return name; +} #endif diff --git a/Source/Core/Common/CommonFuncs.h b/Source/Core/Common/CommonFuncs.h index e276bea7ae..2378aab3db 100644 --- a/Source/Core/Common/CommonFuncs.h +++ b/Source/Core/Common/CommonFuncs.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include "Common/CommonTypes.h" @@ -47,4 +48,7 @@ std::string LastStrerrorString(); // Wrapper function to get GetLastError() string. // This function might change the error code. std::string GetLastErrorString(); + +// Obtains a full path to the specified module. +std::optional GetModuleName(void* hInstance); #endif diff --git a/Source/Core/Common/CompatPatches.cpp b/Source/Core/Common/CompatPatches.cpp index 03963ccdee..e07028e9e4 100644 --- a/Source/Core/Common/CompatPatches.cpp +++ b/Source/Core/Common/CompatPatches.cpp @@ -4,12 +4,14 @@ #include #include +#include #include #include #include #include +#include "Common/CommonFuncs.h" #include "Common/CommonTypes.h" #include "Common/LdrWatcher.h" #include "Common/StringUtil.h" @@ -162,37 +164,26 @@ struct Version } }; -static bool GetModulePath(const wchar_t* name, std::wstring* path) +static std::optional GetModulePath(const wchar_t* name) { auto module = GetModuleHandleW(name); if (module == nullptr) - return false; - DWORD path_len = MAX_PATH; -retry: - path->resize(path_len); - path_len = GetModuleFileNameW(module, const_cast(path->data()), - static_cast(path->size())); - if (!path_len) - return false; - auto error = GetLastError(); - if (error == ERROR_SUCCESS) - return true; - if (error == ERROR_INSUFFICIENT_BUFFER) - goto retry; - return false; + return std::nullopt; + + return GetModuleName(module); } static bool GetModuleVersion(const wchar_t* name, Version* version) { - std::wstring path; - if (!GetModulePath(name, &path)) + auto path = GetModulePath(name); + if (!path) return false; DWORD handle; - DWORD data_len = GetFileVersionInfoSizeW(path.c_str(), &handle); + DWORD data_len = GetFileVersionInfoSizeW(path->c_str(), &handle); if (!data_len) return false; std::vector block(data_len); - if (!GetFileVersionInfoW(path.c_str(), handle, data_len, block.data())) + if (!GetFileVersionInfoW(path->c_str(), handle, data_len, block.data())) return false; void* buf; UINT buf_len; diff --git a/Source/Core/Common/FileUtil.cpp b/Source/Core/Common/FileUtil.cpp index 814d891c22..f0594cffcc 100644 --- a/Source/Core/Common/FileUtil.cpp +++ b/Source/Core/Common/FileUtil.cpp @@ -674,22 +674,26 @@ std::string GetBundleDirectory() std::string GetExePath() { - static std::string dolphin_path; - if (dolphin_path.empty()) - { + static const std::string dolphin_path = [] { + std::string result; #ifdef _WIN32 - TCHAR dolphin_exe_path[2048]; - TCHAR dolphin_exe_expanded_path[MAX_PATH]; - GetModuleFileName(nullptr, dolphin_exe_path, ARRAYSIZE(dolphin_exe_path)); - if (_tfullpath(dolphin_exe_expanded_path, dolphin_exe_path, - ARRAYSIZE(dolphin_exe_expanded_path)) != nullptr) - dolphin_path = TStrToUTF8(dolphin_exe_expanded_path); - else - dolphin_path = TStrToUTF8(dolphin_exe_path); + auto dolphin_exe_path = GetModuleName(nullptr); + if (dolphin_exe_path) + { + std::unique_ptr dolphin_exe_expanded_path{ + _tfullpath(nullptr, dolphin_exe_path->c_str(), 0), std::free}; + if (dolphin_exe_expanded_path) + { + result = TStrToUTF8(dolphin_exe_expanded_path.get()); + } + else + { + result = TStrToUTF8(*dolphin_exe_path); + } + } #elif defined(__APPLE__) - dolphin_path = GetBundleDirectory(); - dolphin_path = - dolphin_path.substr(0, dolphin_path.find_last_of("Dolphin.app/Contents/MacOS") + 1); + result = GetBundleDirectory(); + result = result.substr(0, result.find_last_of("Dolphin.app/Contents/MacOS") + 1); #else char dolphin_exe_path[PATH_MAX]; ssize_t len = ::readlink("/proc/self/exe", dolphin_exe_path, sizeof(dolphin_exe_path)); @@ -698,9 +702,10 @@ std::string GetExePath() len = 0; } dolphin_exe_path[len] = '\0'; - dolphin_path = dolphin_exe_path; + result = dolphin_exe_path; #endif - } + return result; + }(); return dolphin_path; } diff --git a/Source/Core/WinUpdater/Main.cpp b/Source/Core/WinUpdater/Main.cpp index 9196805819..2e1bd36ff8 100644 --- a/Source/Core/WinUpdater/Main.cpp +++ b/Source/Core/WinUpdater/Main.cpp @@ -10,6 +10,7 @@ #include #include +#include "Common/CommonFuncs.h" #include "Common/StringUtil.h" #include "UpdaterCommon/UI.h" @@ -33,28 +34,6 @@ std::vector CommandLineToUtf8Argv(PCWSTR command_line) LocalFree(tokenized); return argv; } - -std::optional GetModuleName(HINSTANCE hInstance) -{ - std::wstring name; - DWORD max_size = 50; // Start with space for 50 characters and grow if needed - name.resize(max_size); - - DWORD size; - while ((size = GetModuleFileNameW(hInstance, name.data(), max_size)) == max_size && - GetLastError() == ERROR_INSUFFICIENT_BUFFER) - { - max_size *= 2; - name.resize(max_size); - } - - if (size == 0) - { - return {}; - } - name.resize(size); - return name; -} }; // namespace int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow)