-
Notifications
You must be signed in to change notification settings - Fork 3
/
Exception.cpp
143 lines (124 loc) · 5.4 KB
/
Exception.cpp
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
#include "nil.h"
#include "nilUtil.h"
namespace Nil {
struct DirectInputErrorEntry {
public:
long code;
wchar_t* description;
};
const int cErrorDescriptionCount = 32; //-V112
const DirectInputErrorEntry cErrorDescriptions[cErrorDescriptionCount] =
{
{ DIERR_ACQUIRED, L"The operation cannot be performed while the device is acquired." },
{ DIERR_ALREADYINITIALIZED, L"The object is already initialized." },
{ DIERR_BADDRIVERVER, L"The object could not be created due to an incompatible driver." },
{ DIERR_DEVICEFULL, L"The device is full." },
{ DIERR_DEVICENOTREG, L"The device or device instance is not registered with DirectInput." },
{ DIERR_EFFECTPLAYING, L"The device does not support updating an effect while it is still playing." },
{ DIERR_GENERIC, L"An undetermined error occurred inside the DirectInput subsystem." },
{ DIERR_HANDLEEXISTS, L"The device already has an event notification associated with it." },
{ DIERR_HASEFFECTS, L"The device cannot be reinitialized because effects are attached to it." },
{ DIERR_INCOMPLETEEFFECT, L"The effect could not be downloaded because essential information is missing." },
{ DIERR_INPUTLOST, L"Access to the input device has been lost. It must be reacquired." },
{ DIERR_INVALIDPARAM, L"An invalid parameter was passed to the function." },
{ DIERR_MAPFILEFAIL, L"An error occurred reading or writing the action-mapping file for the device." },
{ DIERR_MOREDATA, L"Not all the requested information fit into the buffer." },
{ DIERR_NOAGGREGATION, L"The object does not support aggregation." },
{ DIERR_NOINTERFACE, L"The object does not support the specified interface." },
{ DIERR_NOTACQUIRED, L"The operation cannot be performed unless the device is acquired." },
{ DIERR_NOTBUFFERED, L"The device is not buffered." },
{ DIERR_NOTDOWNLOADED, L"The effect was not downloaded." },
{ DIERR_NOTEXCLUSIVEACQUIRED, L"The operation cannot be performed unless the device is acquired in exclusive mode." },
{ DIERR_NOTFOUND, L"The requested object does not exist." },
{ DIERR_NOTINITIALIZED, L"The object has not been initialized." },
{ DIERR_OLDDIRECTINPUTVERSION, L"The application requires a newer version of DirectInput." },
{ DIERR_OTHERAPPHASPRIO, L"Another application has a higher priority level." },
{ DIERR_OUTOFMEMORY, L"The DirectInput subsystem is out of memory." },
{ DIERR_READONLY, L"The specified property is read-only." },
{ DIERR_REPORTFULL, L"More information was requested than can be sent to the device." },
{ DIERR_UNPLUGGED, L"The device is not plugged in." },
{ DIERR_UNSUPPORTED, L"The function called is not supported at this time." },
{ E_HANDLE, L"The HWND parameter is not a valid top-level window that belongs to the process." },
{ E_PENDING, L"Data is not yet available." },
{ E_POINTER, L"An invalid pointer was passed as a parameter." }
};
Exception::Exception()
{
// Stub
}
Exception::Exception( const utf8String& description, Type type ):
mDescription( description ), mType( type )
{
handleAdditional();
}
Exception::Exception( const utf8String& description, const utf8String& source, Type type ):
mDescription( description ), mSource( source ), mType( type )
{
handleAdditional();
}
Exception::Exception( const utf8String& description, const utf8String& source, HRESULT hr, Type type ):
mDescription( description ), mSource( source ), mType( type )
{
handleAdditional( hr );
}
void Exception::handleAdditional( HRESULT hr )
{
WinAPIError error;
if ( mType == WinAPI )
{
error.code = GetLastError();
wchar_t* message = nullptr;
FormatMessageW(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, error.code, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ),
(wchar_t*)&message, 0, NULL );
if ( message )
{
error.description = message;
LocalFree( message );
}
mAdditional = error;
}
else if ( mType == DirectInput )
{
error.code = hr;
for ( unsigned long i = 0; i < cErrorDescriptionCount; i++ )
{
if ( cErrorDescriptions[i].code == error.code )
{
error.description = cErrorDescriptions[i].description;
break;
}
}
mAdditional = error;
}
}
const utf8String& Exception::getFullDescription() const
{
if ( mFullDescription.empty() )
{
stringstream stream;
stream << mDescription;
if ( !mSource.empty() )
stream << "\r\nIn function " << mSource;
if ( mType == WinAPI )
{
const WinAPIError& error = boost::get<WinAPIError>( mAdditional );
stream << "\r\nWinAPI error code " << std::hex << error.code << ":\r\n" << Util::wideToUtf8( error.description );
}
else if ( mType == DirectInput )
{
const WinAPIError& error = boost::get<WinAPIError>( mAdditional );
stream << "\r\nDirectInput error code " << std::hex << error.code << ":\r\n" << Util::wideToUtf8( error.description );
}
mFullDescription = stream.str();
}
return mFullDescription;
}
const char* Exception::what() const
{
return mFullDescription.c_str();
}
}