diff --git a/src/error_code.cpp b/src/error_code.cpp index dfd4a0e..bd87403 100644 --- a/src/error_code.cpp +++ b/src/error_code.cpp @@ -29,8 +29,9 @@ using namespace boost::system::errc; # if defined( BOOST_WINDOWS_API ) # include +# include "local_free_on_destruction.hpp" # ifndef ERROR_INCORRECT_SIZE -# define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS +# define ERROR_INCORRECT_SIZE ERROR_BAD_ARGUMENTS # endif # endif @@ -340,25 +341,11 @@ namespace return generic_category().message( ev ); } # else -// TODO: - -//Some quick notes on the implementation (sorry for the noise if -//someone has already mentioned them): -// -//- The ::LocalFree() usage isn't exception safe. -// -//See: -// -// -// -//in the implementation of what() for an example. -// -//Cheers, -//Chris + std::string system_error_category::message( int ev ) const { # ifndef BOOST_NO_ANSI_APIS - LPVOID lpMsgBuf; + LPVOID lpMsgBuf = 0; DWORD retval = ::FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | @@ -370,13 +357,13 @@ namespace 0, NULL ); + detail::local_free_on_destruction lfod(lpMsgBuf); if (retval == 0) return std::string("Unknown error"); std::string str( static_cast(lpMsgBuf) ); - ::LocalFree( lpMsgBuf ); // free the buffer # else // WinCE workaround - LPVOID lpMsgBuf; + LPVOID lpMsgBuf = 0; DWORD retval = ::FormatMessageW( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | @@ -388,6 +375,7 @@ namespace 0, NULL ); + detail::local_free_on_destruction lfod(lpMsgBuf); if (retval == 0) return std::string("Unknown error"); @@ -397,7 +385,6 @@ namespace return std::string("Unknown error"); std::string str( narrow_buffer ); - ::LocalFree( lpMsgBuf ); // free the buffer # endif while ( str.size() && (str[str.size()-1] == '\n' || str[str.size()-1] == '\r') ) diff --git a/src/local_free_on_destruction.hpp b/src/local_free_on_destruction.hpp new file mode 100644 index 0000000..110024f --- /dev/null +++ b/src/local_free_on_destruction.hpp @@ -0,0 +1,40 @@ +// local_free_on_exit.hpp ------------------------------------------------------------// + +// Copyright (c) 2003-2010 Christopher M. Kohlhoff (chris at kohlhoff dot com) +// Copyright (c) 2010 Beman Dawes + +// Distributed under the Boost Software License, Version 1.0. +// See http://www.boost.org/LICENSE_1_0.txt + +// This is derived from boost/asio/detail/local_free_on_block_exit.hpp to avoid +// a dependency on asio. Thanks to Chris Kohlhoff for pointing it out. + +#ifndef BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP +#define BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP + +namespace boost { +namespace system { +namespace detail { + +class local_free_on_destruction +{ +public: + explicit local_free_on_destruction(void* p) + : p_(p) {} + + ~local_free_on_destruction() + { + ::LocalFree(p_); + } + +private: + void* p_; + local_free_on_destruction(const local_free_on_destruction&); // = deleted + local_free_on_destruction& operator=(const local_free_on_destruction&); // = deleted +}; + +} // namespace detail +} // namespace system +} // namespace boost + +#endif // BOOST_SYSTEM_LOCAL_FREE_ON_EXIT_HPP