File indexing completed on 2025-01-18 09:30:43
0001
0002
0003
0004
0005
0006
0007
0008 #ifndef BOOST_DLL_SHARED_LIBRARY_IMPL_HPP
0009 #define BOOST_DLL_SHARED_LIBRARY_IMPL_HPP
0010
0011 #include <boost/dll/config.hpp>
0012 #include <boost/dll/shared_library_load_mode.hpp>
0013 #include <boost/dll/detail/aggressive_ptr_cast.hpp>
0014 #include <boost/dll/detail/system_error.hpp>
0015 #include <boost/dll/detail/windows/path_from_handle.hpp>
0016
0017 #include <boost/move/utility.hpp>
0018 #include <boost/core/invoke_swap.hpp>
0019
0020 #include <boost/winapi/dll.hpp>
0021
0022 #ifdef BOOST_HAS_PRAGMA_ONCE
0023 # pragma once
0024 #endif
0025
0026 namespace boost { namespace dll { namespace detail {
0027
0028 class shared_library_impl {
0029 BOOST_MOVABLE_BUT_NOT_COPYABLE(shared_library_impl)
0030
0031 public:
0032 typedef boost::winapi::HMODULE_ native_handle_t;
0033
0034 shared_library_impl() BOOST_NOEXCEPT
0035 : handle_(NULL)
0036 {}
0037
0038 ~shared_library_impl() BOOST_NOEXCEPT {
0039 unload();
0040 }
0041
0042 shared_library_impl(BOOST_RV_REF(shared_library_impl) sl) BOOST_NOEXCEPT
0043 : handle_(sl.handle_)
0044 {
0045 sl.handle_ = NULL;
0046 }
0047
0048 shared_library_impl & operator=(BOOST_RV_REF(shared_library_impl) sl) BOOST_NOEXCEPT {
0049 swap(sl);
0050 return *this;
0051 }
0052
0053 static boost::dll::fs::path decorate(const boost::dll::fs::path& sl) {
0054 boost::dll::fs::path actual_path = sl;
0055 actual_path += suffix();
0056 return actual_path;
0057 }
0058
0059 void load(boost::dll::fs::path sl, load_mode::type portable_mode, boost::dll::fs::error_code &ec) {
0060 typedef boost::winapi::DWORD_ native_mode_t;
0061 native_mode_t native_mode = static_cast<native_mode_t>(portable_mode);
0062 unload();
0063
0064 if (!sl.is_absolute() && !(native_mode & load_mode::search_system_folders)) {
0065 boost::dll::fs::error_code current_path_ec;
0066 boost::dll::fs::path prog_loc = boost::dll::fs::current_path(current_path_ec);
0067
0068 if (!current_path_ec) {
0069 prog_loc /= sl;
0070 sl.swap(prog_loc);
0071 }
0072 }
0073 native_mode = static_cast<unsigned>(native_mode) & ~static_cast<unsigned>(load_mode::search_system_folders);
0074
0075
0076 if (!!(native_mode & load_mode::append_decorations)) {
0077 native_mode = static_cast<unsigned>(native_mode) & ~static_cast<unsigned>(load_mode::append_decorations);
0078
0079 if (load_impl(decorate(sl), native_mode, ec)) {
0080 return;
0081 }
0082
0083
0084 const boost::dll::fs::path mingw_load_path = (
0085 sl.has_parent_path()
0086 ? sl.parent_path() / L"lib"
0087 : L"lib"
0088 ).native() + sl.filename().native() + suffix().native();
0089 if (load_impl(mingw_load_path, native_mode, ec)) {
0090 return;
0091 }
0092 }
0093
0094
0095
0096
0097
0098
0099
0100
0101 if (sl.has_extension()) {
0102 handle_ = boost::winapi::LoadLibraryExW(sl.c_str(), 0, native_mode);
0103 } else {
0104 handle_ = boost::winapi::LoadLibraryExW((sl.native() + L".").c_str(), 0, native_mode);
0105 }
0106
0107
0108
0109 if (!handle_) {
0110 ec = boost::dll::detail::last_error_code();
0111 }
0112 }
0113
0114 bool is_loaded() const BOOST_NOEXCEPT {
0115 return (handle_ != 0);
0116 }
0117
0118 void unload() BOOST_NOEXCEPT {
0119 if (handle_) {
0120 boost::winapi::FreeLibrary(handle_);
0121 handle_ = 0;
0122 }
0123 }
0124
0125 void swap(shared_library_impl& rhs) BOOST_NOEXCEPT {
0126 boost::core::invoke_swap(handle_, rhs.handle_);
0127 }
0128
0129 boost::dll::fs::path full_module_path(boost::dll::fs::error_code &ec) const {
0130 return boost::dll::detail::path_from_handle(handle_, ec);
0131 }
0132
0133 static boost::dll::fs::path suffix() {
0134 return L".dll";
0135 }
0136
0137 void* symbol_addr(const char* sb, boost::dll::fs::error_code &ec) const BOOST_NOEXCEPT {
0138 if (is_resource()) {
0139
0140
0141
0142 ec = boost::dll::fs::make_error_code(
0143 boost::dll::fs::errc::operation_not_supported
0144 );
0145
0146 return NULL;
0147 }
0148
0149
0150
0151
0152 void* const symbol = boost::dll::detail::aggressive_ptr_cast<void*>(
0153 boost::winapi::get_proc_address(handle_, sb)
0154 );
0155 if (symbol == NULL) {
0156 ec = boost::dll::detail::last_error_code();
0157 }
0158
0159 return symbol;
0160 }
0161
0162 native_handle_t native() const BOOST_NOEXCEPT {
0163 return handle_;
0164 }
0165
0166 private:
0167
0168 bool load_impl(const boost::dll::fs::path &load_path, boost::winapi::DWORD_ mode, boost::dll::fs::error_code &ec) {
0169 handle_ = boost::winapi::LoadLibraryExW(load_path.c_str(), 0, mode);
0170 if (handle_) {
0171 return true;
0172 }
0173
0174 ec = boost::dll::detail::last_error_code();
0175 if (boost::dll::fs::exists(load_path)) {
0176
0177 return true;
0178 }
0179
0180 ec.clear();
0181 return false;
0182 }
0183
0184 bool is_resource() const BOOST_NOEXCEPT {
0185 return false;
0186
0187
0188 }
0189
0190 native_handle_t handle_;
0191 };
0192
0193 }}}
0194
0195 #endif