From 82e2ba9dde9391dfa304dbc199027fbf0f02fbd2 Mon Sep 17 00:00:00 2001 From: Antony Polukhin Date: Sat, 21 Dec 2024 15:13:32 +0300 Subject: [PATCH 1/4] Fix buffer resizing on Windows --- .../dll/detail/windows/path_from_handle.hpp | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/include/boost/dll/detail/windows/path_from_handle.hpp b/include/boost/dll/detail/windows/path_from_handle.hpp index 24ca165b..768ddb15 100644 --- a/include/boost/dll/detail/windows/path_from_handle.hpp +++ b/include/boost/dll/detail/windows/path_from_handle.hpp @@ -29,27 +29,34 @@ namespace boost { namespace dll { namespace detail { inline boost::dll::fs::path path_from_handle(boost::winapi::HMODULE_ handle, std::error_code &ec) { constexpr boost::winapi::DWORD_ ERROR_INSUFFICIENT_BUFFER_ = 0x7A; - constexpr boost::winapi::DWORD_ DEFAULT_PATH_SIZE_ = 260; + constexpr boost::winapi::DWORD_ DEFAULT_PATH_SIZE_ = 2; + + ec.clear(); // If `handle` parameter is NULL, GetModuleFileName retrieves the path of the // executable file of the current process. boost::winapi::WCHAR_ path_hldr[DEFAULT_PATH_SIZE_]; - const boost::winapi::DWORD_ ret = boost::winapi::GetModuleFileNameW(handle, path_hldr, DEFAULT_PATH_SIZE_); - if (ret) { + const boost::winapi::DWORD_ size = boost::winapi::GetModuleFileNameW(handle, path_hldr, DEFAULT_PATH_SIZE_); + + // If the function succeeds, the return value is the length of the string that is copied to the + // buffer, in characters, not including the terminating null character. If the buffer is too + // small to hold the module name, the string is truncated to nSize characters including the + // terminating null character, the function returns nSize, and the function sets the last + // error to ERROR_INSUFFICIENT_BUFFER. + if (size != 0 && size < DEFAULT_PATH_SIZE_) { // On success, GetModuleFileNameW() doesn't reset last error to ERROR_SUCCESS. Resetting it manually. - ec.clear(); return boost::dll::fs::path(path_hldr); } ec = boost::dll::detail::last_error_code(); for (unsigned i = 2; i < 1025 && static_cast(ec.value()) == ERROR_INSUFFICIENT_BUFFER_; i *= 2) { std::wstring p(DEFAULT_PATH_SIZE_ * i, L'\0'); - const std::size_t size = boost::winapi::GetModuleFileNameW(handle, &p[0], DEFAULT_PATH_SIZE_ * i); - if (size) { + const std::size_t size = boost::winapi::GetModuleFileNameW(handle, p.data(), p.size()); + if (size != 0 && size < p.size()) { // On success, GetModuleFileNameW() doesn't reset last error to ERROR_SUCCESS. Resetting it manually. ec.clear(); p.resize(size); - return boost::dll::fs::path(p); + return boost::dll::fs::path(std::move(p)); } ec = boost::dll::detail::last_error_code(); From 8aa16d32ecf9fd311441657e03255a439d17b3cd Mon Sep 17 00:00:00 2001 From: Antony Polukhin Date: Sat, 21 Dec 2024 15:27:45 +0300 Subject: [PATCH 2/4] fix --- include/boost/dll/detail/windows/path_from_handle.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/dll/detail/windows/path_from_handle.hpp b/include/boost/dll/detail/windows/path_from_handle.hpp index 768ddb15..3b63308b 100644 --- a/include/boost/dll/detail/windows/path_from_handle.hpp +++ b/include/boost/dll/detail/windows/path_from_handle.hpp @@ -51,7 +51,7 @@ namespace boost { namespace dll { namespace detail { ec = boost::dll::detail::last_error_code(); for (unsigned i = 2; i < 1025 && static_cast(ec.value()) == ERROR_INSUFFICIENT_BUFFER_; i *= 2) { std::wstring p(DEFAULT_PATH_SIZE_ * i, L'\0'); - const std::size_t size = boost::winapi::GetModuleFileNameW(handle, p.data(), p.size()); + const std::size_t size = boost::winapi::GetModuleFileNameW(handle, &p[0], p.size()); if (size != 0 && size < p.size()) { // On success, GetModuleFileNameW() doesn't reset last error to ERROR_SUCCESS. Resetting it manually. ec.clear(); From a8932906d52c0abb7cea3f79f228f440cb9b055d Mon Sep 17 00:00:00 2001 From: Antony Polukhin Date: Sat, 21 Dec 2024 16:09:28 +0300 Subject: [PATCH 3/4] cleanup --- include/boost/dll/detail/windows/path_from_handle.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/boost/dll/detail/windows/path_from_handle.hpp b/include/boost/dll/detail/windows/path_from_handle.hpp index 3b63308b..4210df63 100644 --- a/include/boost/dll/detail/windows/path_from_handle.hpp +++ b/include/boost/dll/detail/windows/path_from_handle.hpp @@ -49,8 +49,8 @@ namespace boost { namespace dll { namespace detail { } ec = boost::dll::detail::last_error_code(); - for (unsigned i = 2; i < 1025 && static_cast(ec.value()) == ERROR_INSUFFICIENT_BUFFER_; i *= 2) { - std::wstring p(DEFAULT_PATH_SIZE_ * i, L'\0'); + for (boost::winapi::DWORD_ new_size = 1024; new_size < 1024 * 1024 && static_cast(ec.value()) == ERROR_INSUFFICIENT_BUFFER_; new_size *= 2) { + std::wstring p(new_size, L'\0'); const std::size_t size = boost::winapi::GetModuleFileNameW(handle, &p[0], p.size()); if (size != 0 && size < p.size()) { // On success, GetModuleFileNameW() doesn't reset last error to ERROR_SUCCESS. Resetting it manually. From 061f704f793df0d523868f54b429daa9f8b1e7a3 Mon Sep 17 00:00:00 2001 From: Antony Polukhin Date: Sat, 21 Dec 2024 16:33:53 +0300 Subject: [PATCH 4/4] restore --- include/boost/dll/detail/windows/path_from_handle.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/boost/dll/detail/windows/path_from_handle.hpp b/include/boost/dll/detail/windows/path_from_handle.hpp index 4210df63..d3525523 100644 --- a/include/boost/dll/detail/windows/path_from_handle.hpp +++ b/include/boost/dll/detail/windows/path_from_handle.hpp @@ -29,7 +29,7 @@ namespace boost { namespace dll { namespace detail { inline boost::dll::fs::path path_from_handle(boost::winapi::HMODULE_ handle, std::error_code &ec) { constexpr boost::winapi::DWORD_ ERROR_INSUFFICIENT_BUFFER_ = 0x7A; - constexpr boost::winapi::DWORD_ DEFAULT_PATH_SIZE_ = 2; + constexpr boost::winapi::DWORD_ DEFAULT_PATH_SIZE_ = 260; ec.clear();