]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/boost/system/detail/system_category_win32.hpp
buildsys: switch source download to quincy
[ceph.git] / ceph / src / boost / boost / system / detail / system_category_win32.hpp
CommitLineData
92f5a8d4
TL
1// Windows implementation of system_error_category
2//
3// Copyright Beman Dawes 2002, 2006
4// Copyright (c) Microsoft Corporation 2014
5// Copyright 2018 Peter Dimov
6//
7// Distributed under the Boost Software License, Version 1.0. (See accompanying
8// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9//
10// See library home page at http://www.boost.org/libs/system
11
12#include <boost/winapi/error_codes.hpp>
13#include <boost/winapi/error_handling.hpp>
14#include <boost/winapi/character_code_conversion.hpp>
15#include <boost/winapi/local_memory.hpp>
16#include <cstdio>
17
18//
19
20namespace boost
21{
22
23namespace system
24{
25
26namespace detail
27{
28
29#if ( defined(_MSC_VER) && _MSC_VER < 1900 ) || ( defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) )
30
31inline char const * unknown_message_win32( int ev, char * buffer, std::size_t len )
32{
33# if defined( BOOST_MSVC )
34# pragma warning( push )
35# pragma warning( disable: 4996 )
36# endif
37
38 _snprintf( buffer, len - 1, "Unknown error (%d)", ev );
39
40 buffer[ len - 1 ] = 0;
41 return buffer;
42
43# if defined( BOOST_MSVC )
44# pragma warning( pop )
45# endif
46}
47
48#else
49
50inline char const * unknown_message_win32( int ev, char * buffer, std::size_t len )
51{
52 std::snprintf( buffer, len, "Unknown error (%d)", ev );
53 return buffer;
54}
55
56#endif
57
58inline boost::winapi::UINT_ message_cp_win32()
59{
60#if defined(BOOST_SYSTEM_USE_UTF8)
61
62 return boost::winapi::CP_UTF8_;
63
64#else
65
66 return boost::winapi::CP_ACP_;
67
68#endif
69}
70
71inline char const * system_category_message_win32( int ev, char * buffer, std::size_t len ) BOOST_NOEXCEPT
72{
73 if( len == 0 )
74 {
75 return buffer;
76 }
77
78 if( len == 1 )
79 {
80 buffer[0] = 0;
81 return buffer;
82 }
83
84 boost::winapi::UINT_ const code_page = message_cp_win32();
85
86 int r = 0;
87
88#if !defined(BOOST_NO_ANSI_APIS)
89
90 if( code_page == boost::winapi::CP_ACP_ )
91 {
92 using namespace boost::winapi;
93
94 DWORD_ retval = boost::winapi::FormatMessageA(
95 FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_,
96 NULL,
97 ev,
98 MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ), // Default language
99 buffer,
100 static_cast<DWORD_>( len ),
101 NULL
102 );
103
104 r = static_cast<int>( retval );
105 }
106 else
107
108#endif
109
110 {
111 using namespace boost::winapi;
112
113 wchar_t * lpMsgBuf = 0;
114
115 DWORD_ retval = boost::winapi::FormatMessageW(
116 FORMAT_MESSAGE_ALLOCATE_BUFFER_ | FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_,
117 NULL,
118 ev,
119 MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ), // Default language
120 (LPWSTR_) &lpMsgBuf,
121 0,
122 NULL
123 );
124
125 if( retval != 0 )
126 {
127 r = boost::winapi::WideCharToMultiByte( code_page, 0, lpMsgBuf, -1, buffer, static_cast<int>( len ), NULL, NULL );
128 boost::winapi::LocalFree( lpMsgBuf );
129 if ( r != 0 ) --r; // exclude null terminator
130 }
131 }
132
133 if( r == 0 )
134 {
135 return unknown_message_win32( ev, buffer, len );
136 }
137
138 while( r > 0 && ( buffer[ r-1 ] == '\n' || buffer[ r-1 ] == '\r' ) )
139 {
140 buffer[ --r ] = 0;
141 }
142
143 if( r > 0 && buffer[ r-1 ] == '.' )
144 {
145 buffer[ --r ] = 0;
146 }
147
148 return buffer;
149}
150
151struct local_free
152{
153 void * p_;
154
155 ~local_free()
156 {
157 boost::winapi::LocalFree( p_ );
158 }
159};
160
161inline std::string unknown_message_win32( int ev )
162{
163 char buffer[ 38 ];
164 return unknown_message_win32( ev, buffer, sizeof( buffer ) );
165}
166
167inline std::string system_category_message_win32( int ev )
168{
169 using namespace boost::winapi;
170
171 wchar_t * lpMsgBuf = 0;
172
173 DWORD_ retval = boost::winapi::FormatMessageW(
174 FORMAT_MESSAGE_ALLOCATE_BUFFER_ | FORMAT_MESSAGE_FROM_SYSTEM_ | FORMAT_MESSAGE_IGNORE_INSERTS_,
175 NULL,
176 ev,
177 MAKELANGID_( LANG_NEUTRAL_, SUBLANG_DEFAULT_ ), // Default language
178 (LPWSTR_) &lpMsgBuf,
179 0,
180 NULL
181 );
182
183 if( retval == 0 )
184 {
185 return unknown_message_win32( ev );
186 }
187
188 local_free lf_ = { lpMsgBuf };
189 (void)lf_;
190
191 UINT_ const code_page = message_cp_win32();
192
193 int r = boost::winapi::WideCharToMultiByte( code_page, 0, lpMsgBuf, -1, 0, 0, NULL, NULL );
194
195 if( r == 0 )
196 {
197 return unknown_message_win32( ev );
198 }
199
200 std::string buffer( r, char() );
201
202 r = boost::winapi::WideCharToMultiByte( code_page, 0, lpMsgBuf, -1, &buffer[0], r, NULL, NULL );
203
204 if( r == 0 )
205 {
206 return unknown_message_win32( ev );
207 }
208
209 --r; // exclude null terminator
210
211 while( r > 0 && ( buffer[ r-1 ] == '\n' || buffer[ r-1 ] == '\r' ) )
212 {
213 --r;
214 }
215
216 if( r > 0 && buffer[ r-1 ] == '.' )
217 {
218 --r;
219 }
220
221 buffer.resize( r );
222
223 return buffer;
224}
225
226inline error_condition system_category_default_error_condition_win32( int ev ) BOOST_NOEXCEPT
227{
228 // When using the Windows Runtime, most system errors are reported as HRESULTs.
229 // We want to map the common Win32 errors to their equivalent error condition,
230 // whether or not they are reported via an HRESULT.
231
232#define BOOST_SYSTEM_FAILED(hr) ((hr) < 0)
233#define BOOST_SYSTEM_HRESULT_FACILITY(hr) (((hr) >> 16) & 0x1fff)
234#define BOOST_SYSTEM_HRESULT_CODE(hr) ((hr) & 0xFFFF)
235#define BOOST_SYSTEM_FACILITY_WIN32 7
236
237 if( BOOST_SYSTEM_FAILED( ev ) && BOOST_SYSTEM_HRESULT_FACILITY( ev ) == BOOST_SYSTEM_FACILITY_WIN32 )
238 {
239 ev = BOOST_SYSTEM_HRESULT_CODE( ev );
240 }
241
242#undef BOOST_SYSTEM_FAILED
243#undef BOOST_SYSTEM_HRESULT_FACILITY
244#undef BOOST_SYSTEM_HRESULT_CODE
245#undef BOOST_SYSTEM_FACILITY_WIN32
246
247 using namespace boost::winapi;
248 using namespace errc;
249
250 // Windows system -> posix_errno decode table
251 // see WinError.h comments for descriptions of errors
252
253 switch ( ev )
254 {
255 case 0: return make_error_condition( success );
256
257 case ERROR_ACCESS_DENIED_: return make_error_condition( permission_denied );
258 case ERROR_ALREADY_EXISTS_: return make_error_condition( file_exists );
259 case ERROR_BAD_UNIT_: return make_error_condition( no_such_device );
260 case ERROR_BUFFER_OVERFLOW_: return make_error_condition( filename_too_long );
261 case ERROR_BUSY_: return make_error_condition( device_or_resource_busy );
262 case ERROR_BUSY_DRIVE_: return make_error_condition( device_or_resource_busy );
263 case ERROR_CANNOT_MAKE_: return make_error_condition( permission_denied );
264 case ERROR_CANTOPEN_: return make_error_condition( io_error );
265 case ERROR_CANTREAD_: return make_error_condition( io_error );
266 case ERROR_CANTWRITE_: return make_error_condition( io_error );
267 case ERROR_CONNECTION_ABORTED_: return make_error_condition( connection_aborted );
268 case ERROR_CURRENT_DIRECTORY_: return make_error_condition( permission_denied );
269 case ERROR_DEV_NOT_EXIST_: return make_error_condition( no_such_device );
270 case ERROR_DEVICE_IN_USE_: return make_error_condition( device_or_resource_busy );
271 case ERROR_DIR_NOT_EMPTY_: return make_error_condition( directory_not_empty );
272 case ERROR_DIRECTORY_: return make_error_condition( invalid_argument ); // WinError.h: "The directory name is invalid"
273 case ERROR_DISK_FULL_: return make_error_condition( no_space_on_device );
274 case ERROR_FILE_EXISTS_: return make_error_condition( file_exists );
275 case ERROR_FILE_NOT_FOUND_: return make_error_condition( no_such_file_or_directory );
276 case ERROR_HANDLE_DISK_FULL_: return make_error_condition( no_space_on_device );
277 case ERROR_INVALID_ACCESS_: return make_error_condition( permission_denied );
278 case ERROR_INVALID_DRIVE_: return make_error_condition( no_such_device );
279 case ERROR_INVALID_FUNCTION_: return make_error_condition( function_not_supported );
280 case ERROR_INVALID_HANDLE_: return make_error_condition( invalid_argument );
281 case ERROR_INVALID_NAME_: return make_error_condition( invalid_argument );
282 case ERROR_LOCK_VIOLATION_: return make_error_condition( no_lock_available );
283 case ERROR_LOCKED_: return make_error_condition( no_lock_available );
284 case ERROR_NEGATIVE_SEEK_: return make_error_condition( invalid_argument );
285 case ERROR_NOACCESS_: return make_error_condition( permission_denied );
286 case ERROR_NOT_ENOUGH_MEMORY_: return make_error_condition( not_enough_memory );
287 case ERROR_NOT_READY_: return make_error_condition( resource_unavailable_try_again );
288 case ERROR_NOT_SAME_DEVICE_: return make_error_condition( cross_device_link );
289 case ERROR_OPEN_FAILED_: return make_error_condition( io_error );
290 case ERROR_OPEN_FILES_: return make_error_condition( device_or_resource_busy );
291 case ERROR_OPERATION_ABORTED_: return make_error_condition( operation_canceled );
292 case ERROR_OUTOFMEMORY_: return make_error_condition( not_enough_memory );
293 case ERROR_PATH_NOT_FOUND_: return make_error_condition( no_such_file_or_directory );
294 case ERROR_READ_FAULT_: return make_error_condition( io_error );
295 case ERROR_RETRY_: return make_error_condition( resource_unavailable_try_again );
296 case ERROR_SEEK_: return make_error_condition( io_error );
297 case ERROR_SHARING_VIOLATION_: return make_error_condition( permission_denied );
298 case ERROR_TOO_MANY_OPEN_FILES_: return make_error_condition( too_many_files_open );
299 case ERROR_WRITE_FAULT_: return make_error_condition( io_error );
300 case ERROR_WRITE_PROTECT_: return make_error_condition( permission_denied );
301 case WSAEACCES_: return make_error_condition( permission_denied );
302 case WSAEADDRINUSE_: return make_error_condition( address_in_use );
303 case WSAEADDRNOTAVAIL_: return make_error_condition( address_not_available );
304 case WSAEAFNOSUPPORT_: return make_error_condition( address_family_not_supported );
305 case WSAEALREADY_: return make_error_condition( connection_already_in_progress );
306 case WSAEBADF_: return make_error_condition( bad_file_descriptor );
307 case WSAECONNABORTED_: return make_error_condition( connection_aborted );
308 case WSAECONNREFUSED_: return make_error_condition( connection_refused );
309 case WSAECONNRESET_: return make_error_condition( connection_reset );
310 case WSAEDESTADDRREQ_: return make_error_condition( destination_address_required );
311 case WSAEFAULT_: return make_error_condition( bad_address );
312 case WSAEHOSTUNREACH_: return make_error_condition( host_unreachable );
313 case WSAEINPROGRESS_: return make_error_condition( operation_in_progress );
314 case WSAEINTR_: return make_error_condition( interrupted );
315 case WSAEINVAL_: return make_error_condition( invalid_argument );
316 case WSAEISCONN_: return make_error_condition( already_connected );
317 case WSAEMFILE_: return make_error_condition( too_many_files_open );
318 case WSAEMSGSIZE_: return make_error_condition( message_size );
319 case WSAENAMETOOLONG_: return make_error_condition( filename_too_long );
320 case WSAENETDOWN_: return make_error_condition( network_down );
321 case WSAENETRESET_: return make_error_condition( network_reset );
322 case WSAENETUNREACH_: return make_error_condition( network_unreachable );
323 case WSAENOBUFS_: return make_error_condition( no_buffer_space );
324 case WSAENOPROTOOPT_: return make_error_condition( no_protocol_option );
325 case WSAENOTCONN_: return make_error_condition( not_connected );
326 case WSAENOTSOCK_: return make_error_condition( not_a_socket );
327 case WSAEOPNOTSUPP_: return make_error_condition( operation_not_supported );
328 case WSAEPROTONOSUPPORT_: return make_error_condition( protocol_not_supported );
329 case WSAEPROTOTYPE_: return make_error_condition( wrong_protocol_type );
330 case WSAETIMEDOUT_: return make_error_condition( timed_out );
331 case WSAEWOULDBLOCK_: return make_error_condition( operation_would_block );
332
333 default: return error_condition( ev, system_category() );
334 }
335}
336
337} // namespace detail
338
339} // namespace system
340
341} // namespace boost