Move GetModuleName to Common
This unifies GetModuleFileName calls between Dolphin and WinUpdater and allows to gracefully remove MAX_PATH limit from GetExePath
This commit is contained in:
parent
3b21d32865
commit
689378b435
|
@ -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<std::wstring> 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<HMODULE>(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
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#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<std::wstring> GetModuleName(void* hInstance);
|
||||
#endif
|
||||
|
|
|
@ -4,12 +4,14 @@
|
|||
|
||||
#include <Windows.h>
|
||||
#include <functional>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <winternl.h>
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#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<std::wstring> 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<wchar_t*>(path->data()),
|
||||
static_cast<DWORD>(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<u8> 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;
|
||||
|
|
|
@ -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<TCHAR[], decltype(&std::free)> 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "Common/CommonFuncs.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
||||
#include "UpdaterCommon/UI.h"
|
||||
|
@ -33,28 +34,6 @@ std::vector<std::string> CommandLineToUtf8Argv(PCWSTR command_line)
|
|||
LocalFree(tokenized);
|
||||
return argv;
|
||||
}
|
||||
|
||||
std::optional<std::wstring> 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)
|
||||
|
|
Loading…
Reference in New Issue