]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/dll/include/boost/dll/detail/windows/path_from_handle.hpp
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / boost / libs / dll / include / boost / dll / detail / windows / path_from_handle.hpp
1 // Copyright 2014 Renato Tegon Forti, Antony Polukhin.
2 // Copyright 2015 Antony Polukhin.
3 //
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)
7
8 #ifndef BOOST_DLL_DETAIL_WINDOWS_PATH_FROM_HANDLE_HPP
9 #define BOOST_DLL_DETAIL_WINDOWS_PATH_FROM_HANDLE_HPP
10
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>
16
17 #ifdef BOOST_HAS_PRAGMA_ONCE
18 # pragma once
19 #endif
20
21 namespace boost { namespace dll { namespace detail {
22
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(
26 err,
27 boost::system::system_category()
28 );
29 }
30
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);
34
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();
40 if (!ec) {
41 return boost::filesystem::path(path_hldr);
42 }
43
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();
48
49 if (!ec) {
50 p.resize(size);
51 return boost::filesystem::path(p);
52 }
53 }
54
55 // Error other than ERROR_INSUFFICIENT_BUFFER_ occurred or failed to allocate buffer big enough
56 return boost::filesystem::path();
57 }
58
59 }}} // namespace boost::dll::detail
60
61 #endif // BOOST_DLL_DETAIL_WINDOWS_PATH_FROM_HANDLE_HPP
62