From cbb49f88b05e4a0eb06c27401b6263a29a000bbe Mon Sep 17 00:00:00 2001 From: Antony Polukhin Date: Thu, 1 Sep 2022 15:18:04 +0300 Subject: [PATCH] fix path_from_handle implementation on Windows Refs: https://github.com/apolukhin/Boost.DLL/issues/57 --- .../dll/detail/windows/path_from_handle.hpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/include/boost/dll/detail/windows/path_from_handle.hpp b/include/boost/dll/detail/windows/path_from_handle.hpp index 9e4d9b25..87c3417d 100644 --- a/include/boost/dll/detail/windows/path_from_handle.hpp +++ b/include/boost/dll/detail/windows/path_from_handle.hpp @@ -31,27 +31,28 @@ namespace boost { namespace dll { namespace detail { BOOST_STATIC_CONSTANT(boost::winapi::DWORD_, ERROR_INSUFFICIENT_BUFFER_ = 0x7A); BOOST_STATIC_CONSTANT(boost::winapi::DWORD_, DEFAULT_PATH_SIZE_ = 260); - // On success, GetModuleFileNameW() doesn't reset last error to ERROR_SUCCESS. Resetting it manually. - boost::winapi::GetLastError(); - // 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_]; - boost::winapi::GetModuleFileNameW(handle, path_hldr, DEFAULT_PATH_SIZE_); - ec = boost::dll::detail::last_error_code(); - if (!ec) { + const boost::winapi::DWORD_ ret = boost::winapi::GetModuleFileNameW(handle, path_hldr, DEFAULT_PATH_SIZE_); + if (ret) { + // 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); - ec = boost::dll::detail::last_error_code(); - - if (!ec) { + if (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); } + + ec = boost::dll::detail::last_error_code(); } // Error other than ERROR_INSUFFICIENT_BUFFER_ occurred or failed to allocate buffer big enough.