1 // Copyright 2014 Renato Tegon Forti, Antony Polukhin.
2 // Copyright 2015 Antony Polukhin.
4 // Distributed under the Boost Software License, Version 1.0.
5 // (See accompanying file LICENSE_1_0.txt
6 // or copy at http://www.boost.org/LICENSE_1_0.txt)
8 #ifndef BOOST_DLL_DETAIL_WINDOWS_PATH_FROM_HANDLE_HPP
9 #define BOOST_DLL_DETAIL_WINDOWS_PATH_FROM_HANDLE_HPP
11 #include <boost/config.hpp>
12 #include <boost/dll/detail/system_error.hpp>
13 #include <boost/detail/winapi/dll.hpp>
14 #include <boost/detail/winapi/get_last_error.hpp>
15 #include <boost/filesystem/path.hpp>
17 #ifdef BOOST_HAS_PRAGMA_ONCE
21 namespace boost { namespace dll { namespace detail {
23 static inline boost::system::error_code last_error_code() BOOST_NOEXCEPT {
24 boost::detail::winapi::DWORD_ err = boost::detail::winapi::GetLastError();
25 return boost::system::error_code(
27 boost::system::system_category()
31 inline boost::filesystem::path path_from_handle(boost::detail::winapi::HMODULE_ handle, boost::system::error_code &ec) {
32 BOOST_STATIC_CONSTANT(boost::detail::winapi::DWORD_, ERROR_INSUFFICIENT_BUFFER_ = 0x7A);
33 BOOST_STATIC_CONSTANT(boost::detail::winapi::DWORD_, DEFAULT_PATH_SIZE_ = 260);
35 // If `handle` parameter is NULL, GetModuleFileName retrieves the path of the
36 // executable file of the current process.
37 boost::detail::winapi::WCHAR_ path_hldr[DEFAULT_PATH_SIZE_];
38 boost::detail::winapi::GetModuleFileNameW(handle, path_hldr, DEFAULT_PATH_SIZE_);
39 ec = last_error_code();
41 return boost::filesystem::path(path_hldr);
44 for (unsigned i = 2; i < 1025 && static_cast<boost::detail::winapi::DWORD_>(ec.value()) == ERROR_INSUFFICIENT_BUFFER_; i *= 2) {
45 std::wstring p(DEFAULT_PATH_SIZE_ * i, L'\0');
46 const std::size_t size = boost::detail::winapi::GetModuleFileNameW(handle, &p[0], DEFAULT_PATH_SIZE_ * i);
47 ec = last_error_code();
51 return boost::filesystem::path(p);
55 // Error other than ERROR_INSUFFICIENT_BUFFER_ occurred or failed to allocate buffer big enough
56 return boost::filesystem::path();
59 }}} // namespace boost::dll::detail
61 #endif // BOOST_DLL_DETAIL_WINDOWS_PATH_FROM_HANDLE_HPP