1 #ifndef BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_MESSAGE_WIN32_HPP_INCLUDED
2 #define BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_MESSAGE_WIN32_HPP_INCLUDED
4 // Copyright Beman Dawes 2002, 2006
5 // Copyright (c) Microsoft Corporation 2014
6 // Copyright 2018, 2020 Peter Dimov
8 // Distributed under the Boost Software License, Version 1.0. (See accompanying
9 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
11 // See library home page at http://www.boost.org/libs/system
13 #include <boost/winapi/error_handling.hpp>
14 #include <boost/winapi/character_code_conversion.hpp>
15 #include <boost/winapi/local_memory.hpp>
16 #include <boost/config.hpp>
30 #if ( defined(_MSC_VER) && _MSC_VER < 1900 ) || ( defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) )
32 inline char const * unknown_message_win32( int ev, char * buffer, std::size_t len )
34 # if defined( BOOST_MSVC )
35 # pragma warning( push )
36 # pragma warning( disable: 4996 )
39 _snprintf( buffer, len - 1, "Unknown error (%d)", ev );
41 buffer[ len - 1 ] = 0;
44 # if defined( BOOST_MSVC )
45 # pragma warning( pop )
51 inline char const * unknown_message_win32( int ev, char * buffer, std::size_t len )
53 std::snprintf( buffer, len, "Unknown error (%d)", ev );
59 inline boost::winapi::UINT_ message_cp_win32()
61 #if defined(BOOST_SYSTEM_USE_UTF8)
63 return boost::winapi::CP_UTF8_;
67 return boost::winapi::CP_ACP_;
72 inline char const * system_category_message_win32( int ev, char * buffer, std::size_t len ) BOOST_NOEXCEPT
85 boost::winapi::UINT_ const code_page = message_cp_win32();
89 #if !defined(BOOST_NO_ANSI_APIS)
91 if( code_page == boost::winapi::CP_ACP_ )
93 using namespace boost::winapi;
95 DWORD_ retval = boost::winapi::FormatMessageA(
96 FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_,
99 MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ), // Default language
101 static_cast<DWORD_>( len ),
105 r = static_cast<int>( retval );
112 using namespace boost::winapi;
114 wchar_t * lpMsgBuf = 0;
116 DWORD_ retval = boost::winapi::FormatMessageW(
117 FORMAT_MESSAGE_ALLOCATE_BUFFER_ | FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_,
120 MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ), // Default language
128 r = boost::winapi::WideCharToMultiByte( code_page, 0, lpMsgBuf, -1, buffer, static_cast<int>( len ), NULL, NULL );
129 boost::winapi::LocalFree( lpMsgBuf );
130 if ( r != 0 ) --r; // exclude null terminator
136 return unknown_message_win32( ev, buffer, len );
139 while( r > 0 && ( buffer[ r-1 ] == '\n' || buffer[ r-1 ] == '\r' ) )
144 if( r > 0 && buffer[ r-1 ] == '.' )
158 boost::winapi::LocalFree( p_ );
162 inline std::string unknown_message_win32( int ev )
165 return unknown_message_win32( ev, buffer, sizeof( buffer ) );
168 inline std::string system_category_message_win32( int ev )
170 using namespace boost::winapi;
172 wchar_t * lpMsgBuf = 0;
174 DWORD_ retval = boost::winapi::FormatMessageW(
175 FORMAT_MESSAGE_ALLOCATE_BUFFER_ | FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_,
178 MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ), // Default language
186 return unknown_message_win32( ev );
189 local_free lf_ = { lpMsgBuf };
192 UINT_ const code_page = message_cp_win32();
194 int r = boost::winapi::WideCharToMultiByte( code_page, 0, lpMsgBuf, -1, 0, 0, NULL, NULL );
198 return unknown_message_win32( ev );
201 std::string buffer( r, char() );
203 r = boost::winapi::WideCharToMultiByte( code_page, 0, lpMsgBuf, -1, &buffer[0], r, NULL, NULL );
207 return unknown_message_win32( ev );
210 --r; // exclude null terminator
212 while( r > 0 && ( buffer[ r-1 ] == '\n' || buffer[ r-1 ] == '\r' ) )
217 if( r > 0 && buffer[ r-1 ] == '.' )
227 } // namespace detail
229 } // namespace system
233 #endif // #ifndef BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_MESSAGE_WIN32_HPP_INCLUDED