diff --git a/build/Jamfile.v2 b/build/Jamfile.v2 index 6982bb4..dacc15b 100644 --- a/build/Jamfile.v2 +++ b/build/Jamfile.v2 @@ -27,6 +27,7 @@ project.pop-current ; # Windows libs lib psapi ; lib advapi32 ; +lib secur32 ; lib ws2_32 ; lib mswsock ; @@ -194,6 +195,7 @@ project boost/log windows:NOMINMAX windows:WIN32_LEAN_AND_MEAN + windows:SECURITY_WIN32 windows:BOOST_USE_WINDOWS_H windows:ws2_32 windows:mswsock @@ -201,6 +203,7 @@ project boost/log cygwin:NOMINMAX cygwin:WIN32_LEAN_AND_MEAN + cygwin:SECURITY_WIN32 cygwin:__USE_W32_SOCKETS cygwin:BOOST_USE_WINDOWS_H cygwin:ws2_32 @@ -434,6 +437,7 @@ rule select-platform-specific-sources ( properties * ) result += windows/mapped_shared_memory.cpp ; result += windows/ipc_sync_wrappers.cpp ; result += windows/ipc_reliable_message_queue.cpp ; + result += secur32 ; } if ! [ has-config-flag BOOST_LOG_WITHOUT_DEBUG_OUTPUT : $(properties) ] diff --git a/include/boost/log/sinks/text_ipc_message_queue_backend.hpp b/include/boost/log/sinks/text_ipc_message_queue_backend.hpp index 5387412..b7096f7 100644 --- a/include/boost/log/sinks/text_ipc_message_queue_backend.hpp +++ b/include/boost/log/sinks/text_ipc_message_queue_backend.hpp @@ -19,6 +19,7 @@ #define BOOST_LOG_SINKS_TEXT_IPC_MESSAGE_QUEUE_BACKEND_HPP_INCLUDED_ #include +#include #include #include #include @@ -144,7 +145,7 @@ public: void consume(record_view const&, string_type const& formatted_message) { if (m_queue.is_open()) - m_queue.send(formatted_message.data(), formatted_message.size()); + m_queue.send(formatted_message.data(), static_cast< uint32_t >(formatted_message.size())); } }; diff --git a/src/code_conversion.cpp b/src/code_conversion.cpp index 03f5d72..cf07d05 100644 --- a/src/code_conversion.cpp +++ b/src/code_conversion.cpp @@ -24,6 +24,7 @@ #if defined(BOOST_WINDOWS) #include #include +#include #include #endif #include @@ -228,7 +229,8 @@ std::wstring utf8_to_utf16(const char* str) } } - BOOST_LOG_THROW_DESCR(conversion_error, "Failed to convert UTF-8 to UTF-16"); + const boost::detail::winapi::DWORD_ err = boost::detail::winapi::GetLastError(); + BOOST_LOG_THROW_DESCR_PARAMS(system_error, "Failed to convert UTF-8 to UTF-16", (err)); BOOST_LOG_UNREACHABLE_RETURN(std::wstring()); } @@ -241,20 +243,27 @@ std::string utf16_to_utf8(const wchar_t* wstr) else if (BOOST_UNLIKELY(utf16_len > static_cast< std::size_t >((std::numeric_limits< int >::max)()))) BOOST_LOG_THROW_DESCR(bad_alloc, "UTF-16 string too long"); - int len = boost::detail::winapi::WideCharToMultiByte(boost::detail::winapi::CP_UTF8_, boost::detail::winapi::MB_ERR_INVALID_CHARS_, wstr, static_cast< int >(utf16_len), NULL, 0, NULL, NULL); + const boost::detail::winapi::DWORD_ flags = +#if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6 + boost::detail::winapi::WC_ERR_INVALID_CHARS_; +#else + 0u; +#endif + int len = boost::detail::winapi::WideCharToMultiByte(boost::detail::winapi::CP_UTF8_, flags, wstr, static_cast< int >(utf16_len), NULL, 0, NULL, NULL); if (BOOST_LIKELY(len > 0)) { std::string str; str.resize(len); - len = boost::detail::winapi::WideCharToMultiByte(boost::detail::winapi::CP_UTF8_, boost::detail::winapi::MB_ERR_INVALID_CHARS_, wstr, static_cast< int >(utf16_len), &str[0], len, NULL, NULL); + len = boost::detail::winapi::WideCharToMultiByte(boost::detail::winapi::CP_UTF8_, flags, wstr, static_cast< int >(utf16_len), &str[0], len, NULL, NULL); if (BOOST_LIKELY(len > 0)) { return str; } } - BOOST_LOG_THROW_DESCR(conversion_error, "Failed to convert UTF-16 to UTF-8"); + const boost::detail::winapi::DWORD_ err = boost::detail::winapi::GetLastError(); + BOOST_LOG_THROW_DESCR_PARAMS(system_error, "Failed to convert UTF-16 to UTF-8", (err)); BOOST_LOG_UNREACHABLE_RETURN(std::string()); } diff --git a/src/windows/auto_handle.hpp b/src/windows/auto_handle.hpp index 158f9bd..c965ee4 100644 --- a/src/windows/auto_handle.hpp +++ b/src/windows/auto_handle.hpp @@ -53,7 +53,7 @@ public: } boost::detail::winapi::HANDLE_ get() const BOOST_NOEXCEPT { return m_handle; } - boost::detail::winapi::HANDLE_* get_ptr() const BOOST_NOEXCEPT { return &m_handle; } + boost::detail::winapi::HANDLE_* get_ptr() BOOST_NOEXCEPT { return &m_handle; } void swap(auto_handle& that) BOOST_NOEXCEPT { diff --git a/src/windows/ipc_reliable_message_queue.cpp b/src/windows/ipc_reliable_message_queue.cpp index 9d83a9c..7ccf91e 100644 --- a/src/windows/ipc_reliable_message_queue.cpp +++ b/src/windows/ipc_reliable_message_queue.cpp @@ -704,7 +704,7 @@ BOOST_LOG_API void reliable_message_queue::stop_local() BOOST_ASSERT(m_impl != NULL); try { - m_impl->stop(); + m_impl->stop_local(); } catch (boost::exception& e) { @@ -718,7 +718,7 @@ BOOST_LOG_API void reliable_message_queue::reset_local() BOOST_ASSERT(m_impl != NULL); try { - m_impl->reset(); + m_impl->reset_local(); } catch (boost::exception& e) { diff --git a/src/windows/object_name.cpp b/src/windows/object_name.cpp index 2664549..78fc217 100644 --- a/src/windows/object_name.cpp +++ b/src/windows/object_name.cpp @@ -15,7 +15,9 @@ #include #include +#include #include +#include #include #include #include @@ -25,7 +27,9 @@ #include #include #include +#include #include "windows/auto_handle.hpp" +#include "windows/utf_code_conversion.hpp" #include namespace boost { @@ -36,7 +40,7 @@ namespace ipc { BOOST_LOG_ANONYMOUS_NAMESPACE { -#if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_VISTA +#if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6 class auto_boundary_descriptor { @@ -61,7 +65,7 @@ public: } HANDLE get() const BOOST_NOEXCEPT { return m_handle; } - HANDLE* get_ptr() const BOOST_NOEXCEPT { return &m_handle; } + HANDLE* get_ptr() BOOST_NOEXCEPT { return &m_handle; } void swap(auto_boundary_descriptor& that) BOOST_NOEXCEPT { @@ -77,6 +81,17 @@ public: //! Handle for the private namespace for \c user scope static boost::atomic< HANDLE > g_user_private_namespace; +//! Closes the private namespace on process exit +void close_user_namespace() +{ + HANDLE h = g_user_private_namespace.load(boost::memory_order_acquire); + if (h) + { + ClosePrivateNamespace(h, 0); + g_user_private_namespace.store((HANDLE)NULL, boost::memory_order_release); + } +} + //! Attempts to create or open the private namespace bool init_user_namespace() { @@ -84,13 +99,20 @@ bool init_user_namespace() if (BOOST_UNLIKELY(!h)) { // Obtain the current user SID - auto_handle h_process_token; + boost::log::ipc::aux::auto_handle h_process_token; if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, h_process_token.get_ptr())) return false; - TOKEN_USER token_user = {}; DWORD token_user_size = 0; - if (!GetTokenInformation(h_process_token.get(), TokenUser, &token_user, sizeof(token_user), &token_user_size) || !token_user.User.Sid) + GetTokenInformation(h_process_token.get(), TokenUser, NULL, 0u, &token_user_size); + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER || token_user_size < sizeof(TOKEN_USER)) + return false; + std::vector< unsigned char > token_user_storage(static_cast< std::size_t >(token_user_size), static_cast< unsigned char >(0u)); + if (!GetTokenInformation(h_process_token.get(), TokenUser, &token_user_storage[0], token_user_size, &token_user_size)) + return false; + + TOKEN_USER const& token_user = *reinterpret_cast< const TOKEN_USER* >(&token_user_storage[0]); + if (!token_user.User.Sid) return false; // Create a boindary descriptor with the user's SID @@ -104,7 +126,7 @@ bool init_user_namespace() // Create or open a namespace for kernel objects h = CreatePrivateNamespaceW(NULL, h_boundary.get(), L"User"); if (!h) - h = OpenPrivateNamespace(h_boundary.get(), L"User"); + h = OpenPrivateNamespaceW(h_boundary.get(), L"User"); if (h) { @@ -114,13 +136,17 @@ bool init_user_namespace() ClosePrivateNamespace(h, 0); h = expected; } + else + { + std::atexit(&close_user_namespace); + } } } return !!h; } -#endif // BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_VISTA +#endif // BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6 //! Returns a prefix string for a shared resource according to the scope std::string get_scope_prefix(object_name::scope ns) @@ -144,17 +170,17 @@ std::string get_scope_prefix(object_name::scope ns) case object_name::user: { -#if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_VISTA +#if BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6 if (init_user_namespace()) { prefix = "User\\boost.log.user"; } else -#endif // BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_VISTA +#endif // BOOST_USE_WINAPI_VERSION >= BOOST_WINAPI_VERSION_WIN6 { wchar_t buf[UNLEN + 1u]; ULONG len = sizeof(buf) / sizeof(*buf); - if (BOOST_UNLIKELY(!GetUserNameEx(NameSamCompatible, buf, &len))) + if (BOOST_UNLIKELY(!GetUserNameExW(NameSamCompatible, buf, &len))) { const boost::detail::winapi::DWORD_ err = boost::detail::winapi::GetLastError(); BOOST_LOG_THROW_DESCR_PARAMS(boost::log::system_error, "Failed to obtain the current user name", (err)); @@ -162,7 +188,7 @@ std::string get_scope_prefix(object_name::scope ns) std::replace(buf, buf + len, L'\\', L'.'); - prefix = "Local\\boost.log.user." + utf16_to_utf8(buf); + prefix = "Local\\boost.log.user." + boost::log::aux::utf16_to_utf8(buf); } } break;