Skip to content

Commit

Permalink
maint: Factor handling of GetModuleFileNameW
Browse files Browse the repository at this point in the history
Signed-off-by: Julien Jerphanion <[email protected]>

Co-authored-by: Klaim <[email protected]>
  • Loading branch information
jjerphan and Klaim committed Jan 30, 2025
1 parent a7062c2 commit 2ee0ab0
Showing 1 changed file with 34 additions and 40 deletions.
74 changes: 34 additions & 40 deletions libmamba/src/core/util_os.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,29 +47,45 @@ static_assert(std::is_same_v<mamba::DWORD, ::DWORD>);

namespace mamba
{
// Heavily inspired by https://github.com/gpakosz/whereami/
// check their source to add support for other OS
fs::u8path get_self_exe_path()
{

#ifdef _WIN32
fs::u8path get_hmodule_path(HMODULE hModule)
{
std::wstring buffer(MAX_PATH, '\0');
DWORD size = GetModuleFileNameW(NULL, (wchar_t*) buffer.c_str(), (DWORD) buffer.size());
if (size == 0)
{
throw std::runtime_error("Could find location of the micromamba executable!");
}
else if (size == buffer.size())
DWORD new_size = MAX_PATH;
DWORD size = 0;
// There's unfortunately no way to know how much space is needed,
// so we just keep doubling the size of the buffer until the path fits.
while (true)
{
DWORD new_size = size;
do
size = GetModuleFileNameW(hModule, buffer.data(), static_cast<DWORD>(buffer.size()));
if (size == 0)
{
new_size *= 2;
buffer.reserve(new_size);
size = GetModuleFileNameW(NULL, (wchar_t*) buffer.c_str(), (DWORD) buffer.size());
} while (new_size == size);
throw mamba::mamba_error(
"Could find the filename of the module handle. (GetModuleFileNameW failed)",
mamba_error_code::internal_failure
);
}
if (size < new_size)
{
break;
}

new_size *= 2;
buffer.resize(new_size);
}
buffer.resize(buffer.find(L'\0'));
buffer.resize(size);
return fs::absolute(buffer);
}
#endif

// Heavily inspired by https://github.com/gpakosz/whereami/
// check their source to add support for other OS
fs::u8path get_self_exe_path()
{
#ifdef _WIN32
HMODULE hModule = NULL; // references file used to create the calling process
return get_hmodule_path(hModule);
#elif defined(__APPLE__)
uint32_t size = PATH_MAX;
std::vector<char> buffer(size);
Expand Down Expand Up @@ -107,29 +123,7 @@ namespace mamba
mamba_error_code::internal_failure
);
}
std::wstring buffer(MAX_PATH, '\0');
DWORD new_size = MAX_PATH;
DWORD size = 0;
while (true)
{
size = GetModuleFileNameW(hModule, buffer.data(), static_cast<DWORD>(buffer.size()));
if (size == 0)
{
throw mamba::mamba_error(
"Could find the filename of the libmamba's module handle. (GetModuleFileNameW failed)",
mamba_error_code::internal_failure
);
}
if (size < new_size)
{
break;
}

new_size *= 2;
buffer.resize(new_size);
}
buffer.resize(size);
return fs::absolute(buffer);
return get_hmodule_path(hModule);
#else
fs::u8path libmamba_path;
Dl_info dl_info;
Expand Down

0 comments on commit 2ee0ab0

Please sign in to comment.