File indexing completed on 2025-01-18 09:52:35
0001 #ifndef BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_MESSAGE_WIN32_HPP_INCLUDED
0002 #define BOOST_SYSTEM_DETAIL_SYSTEM_CATEGORY_MESSAGE_WIN32_HPP_INCLUDED
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #include <boost/system/detail/snprintf.hpp>
0014 #include <boost/winapi/error_handling.hpp>
0015 #include <boost/winapi/character_code_conversion.hpp>
0016 #include <boost/winapi/local_memory.hpp>
0017 #include <boost/config.hpp>
0018 #include <cstdio>
0019
0020
0021
0022 namespace boost
0023 {
0024
0025 namespace system
0026 {
0027
0028 namespace detail
0029 {
0030
0031 inline char const * unknown_message_win32( int ev, char * buffer, std::size_t len )
0032 {
0033 detail::snprintf( buffer, len, "Unknown error (%d)", ev );
0034 return buffer;
0035 }
0036
0037 inline boost::winapi::UINT_ message_cp_win32()
0038 {
0039 #if defined(BOOST_SYSTEM_USE_UTF8)
0040
0041 return boost::winapi::CP_UTF8_;
0042
0043 #else
0044
0045 return boost::winapi::CP_ACP_;
0046
0047 #endif
0048 }
0049
0050 inline char const * system_category_message_win32( int ev, char * buffer, std::size_t len ) BOOST_NOEXCEPT
0051 {
0052 if( len == 0 )
0053 {
0054 return buffer;
0055 }
0056
0057 if( len == 1 )
0058 {
0059 buffer[0] = 0;
0060 return buffer;
0061 }
0062
0063 boost::winapi::UINT_ const code_page = message_cp_win32();
0064
0065 int r = 0;
0066
0067 #if !defined(BOOST_NO_ANSI_APIS)
0068
0069 if( code_page == boost::winapi::CP_ACP_ )
0070 {
0071 using namespace boost::winapi;
0072
0073 DWORD_ retval = boost::winapi::FormatMessageA(
0074 FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_,
0075 NULL,
0076 ev,
0077 MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ),
0078 buffer,
0079 static_cast<DWORD_>( len ),
0080 NULL
0081 );
0082
0083 r = static_cast<int>( retval );
0084 }
0085 else
0086
0087 #endif
0088
0089 {
0090 using namespace boost::winapi;
0091
0092 wchar_t * lpMsgBuf = 0;
0093
0094 DWORD_ retval = boost::winapi::FormatMessageW(
0095 FORMAT_MESSAGE_ALLOCATE_BUFFER_ | FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_,
0096 NULL,
0097 ev,
0098 MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ),
0099 (LPWSTR_) &lpMsgBuf,
0100 0,
0101 NULL
0102 );
0103
0104 if( retval != 0 )
0105 {
0106 r = boost::winapi::WideCharToMultiByte( code_page, 0, lpMsgBuf, -1, buffer, static_cast<int>( len ), NULL, NULL );
0107 boost::winapi::LocalFree( lpMsgBuf );
0108 if ( r != 0 ) --r;
0109 }
0110 }
0111
0112 if( r == 0 )
0113 {
0114 return unknown_message_win32( ev, buffer, len );
0115 }
0116
0117 while( r > 0 && ( buffer[ r-1 ] == '\n' || buffer[ r-1 ] == '\r' ) )
0118 {
0119 buffer[ --r ] = 0;
0120 }
0121
0122 if( r > 0 && buffer[ r-1 ] == '.' )
0123 {
0124 buffer[ --r ] = 0;
0125 }
0126
0127 return buffer;
0128 }
0129
0130 struct local_free
0131 {
0132 void * p_;
0133
0134 ~local_free()
0135 {
0136 boost::winapi::LocalFree( p_ );
0137 }
0138 };
0139
0140 inline std::string unknown_message_win32( int ev )
0141 {
0142 char buffer[ 38 ];
0143 return unknown_message_win32( ev, buffer, sizeof( buffer ) );
0144 }
0145
0146 inline std::string system_category_message_win32( int ev )
0147 {
0148 using namespace boost::winapi;
0149
0150 wchar_t * lpMsgBuf = 0;
0151
0152 DWORD_ retval = boost::winapi::FormatMessageW(
0153 FORMAT_MESSAGE_ALLOCATE_BUFFER_ | FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_,
0154 NULL,
0155 ev,
0156 MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ),
0157 (LPWSTR_) &lpMsgBuf,
0158 0,
0159 NULL
0160 );
0161
0162 if( retval == 0 )
0163 {
0164 return unknown_message_win32( ev );
0165 }
0166
0167 local_free lf_ = { lpMsgBuf };
0168 (void)lf_;
0169
0170 UINT_ const code_page = message_cp_win32();
0171
0172 int r = boost::winapi::WideCharToMultiByte( code_page, 0, lpMsgBuf, -1, 0, 0, NULL, NULL );
0173
0174 if( r == 0 )
0175 {
0176 return unknown_message_win32( ev );
0177 }
0178
0179 std::string buffer( r, char() );
0180
0181 r = boost::winapi::WideCharToMultiByte( code_page, 0, lpMsgBuf, -1, &buffer[0], r, NULL, NULL );
0182
0183 if( r == 0 )
0184 {
0185 return unknown_message_win32( ev );
0186 }
0187
0188 --r;
0189
0190 while( r > 0 && ( buffer[ r-1 ] == '\n' || buffer[ r-1 ] == '\r' ) )
0191 {
0192 --r;
0193 }
0194
0195 if( r > 0 && buffer[ r-1 ] == '.' )
0196 {
0197 --r;
0198 }
0199
0200 buffer.resize( r );
0201
0202 return buffer;
0203 }
0204
0205 }
0206
0207 }
0208
0209 }
0210
0211 #endif