-
Notifications
You must be signed in to change notification settings - Fork 1
/
win32Exception.h
108 lines (89 loc) · 2.14 KB
/
win32Exception.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#ifndef WIN32_EXCEPTION_H
#define WIN32_EXCEPTION_H
#include <windows.h>
#include <stdexcept>
#include <sstream>
#include <ostream>
#include <iomanip>
namespace win32
{
class exception : public std::runtime_error
{
private:
DWORD errorCode_;
static std::string error_message(DWORD errorCode);
public:
explicit exception(DWORD errorCode);
exception(const exception& other);
void swap(exception& other);
exception& operator=(const exception& other);
DWORD errorCode() const;
};
template <typename T> T check(T result, T errorValue = T(0));
inline HANDLE check_handle(HANDLE result, HANDLE errorValue = INVALID_HANDLE_VALUE);
// implementation
inline /*static*/ std::string
exception::error_message(DWORD errorCode)
{
std::ostringstream oss;
oss << "Win32 error 0x" << std::hex << std::setw(8) << std::setfill('0') << errorCode;
LPVOID message = 0;
if (FormatMessageA(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
/*lpSource*/0,
errorCode,
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), // RATIONALE: localized error texts are ungooglable
reinterpret_cast<LPSTR>(&message),
/*nSize*/0,
/*Arguments*/0))
{
oss << ": " << reinterpret_cast<const char*>(message);
LocalFree(message);
}
return oss.str();
}
inline /*explicit*/
exception::exception(DWORD errorCode)
: std::runtime_error(error_message(errorCode)), errorCode_(errorCode)
{}
inline
exception::exception(const exception& other)
: std::runtime_error(other), errorCode_(other.errorCode_)
{}
inline void
exception::swap(exception& other)
{
using std::swap;
swap(static_cast<std::runtime_error&>(*this), static_cast<std::runtime_error&>(other));
swap(errorCode_, other.errorCode_);
}
inline exception&
exception::operator=(const exception& other)
{
exception copy(other);
copy.swap(*this);
return *this;
}
inline DWORD
exception::errorCode() const
{
return errorCode_;
}
template <typename T>
T check(T result, T errorValue)
{
if (errorValue == result)
{
throw exception(::GetLastError());
}
return result;
}
inline HANDLE
check_handle(HANDLE result, HANDLE errorValue)
{
return check<HANDLE>(result, errorValue);
}
}
#endif