-
-
Notifications
You must be signed in to change notification settings - Fork 492
/
Copy pathCOMHelper.h
185 lines (157 loc) · 3.5 KB
/
COMHelper.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
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
#pragma once
#include <string>
#include <stdio.h>
#include <Winsock2.h>
#include <wrl\client.h>
#include <wrl\wrappers\corewrappers.h>
using namespace Microsoft::WRL::Wrappers;
#if _DEBUG
#include "DebugHelper.h"
#ifndef __STRINGIFY
#define __STRINGIFY(x) #x
#define _STRINGIFY(x) __STRINGIFY(x)
#endif
#ifndef __STRINGIFY_W
#define __STRINGIFY_W(x) L##x
#define _STRINGIFY_W(x) __STRINGIFY_W(x)
#endif
#define CleanupIfFailed(result, method) \
if(FAILED(result = method)) \
{ \
OutputDebugStringFormat(_STRINGIFY_W("HRESULT 0x%08X at " __FUNCTION__ ", line " _STRINGIFY(__LINE__) ", file " _STRINGIFY(__FILE__) "\n"), result); \
goto Cleanup; \
}
#define ReturnIfFailed(result, method) \
if(FAILED(result = method)) \
{ \
OutputDebugStringFormat(_STRINGIFY_W("HRESULT 0x%08X at " __FUNCTION__ ", line " _STRINGIFY(__LINE__) ", file " _STRINGIFY(__FILE__) "\n"), result); \
return result; \
}
#define BreakIfFailed(result, method) \
if(FAILED(result = method)) \
{ \
OutputDebugStringFormat(_STRINGIFY_W("HRESULT 0x%08X at " __FUNCTION__ ", line " _STRINGIFY(__LINE__) ", file " _STRINGIFY(__FILE__) "\n"), result); \
break; \
}
#else
#define ReturnIfFailed(result, method) \
if(FAILED(result = method)) \
{ \
return result; \
}
#define CleanupIfFailed(result, method) \
if(FAILED(result = method)) \
{ \
goto Cleanup; \
}
#define BreakIfFailed(result, method) \
if(FAILED(result = method)) \
{ \
break; \
}
#endif
#define WIN32_FROM_HRESULT(result) ((result) & 0x0000FFFF)
inline HRESULT WindowsCreateString(std::wstring const& wstring, _Out_ HSTRING* hstring)
{
return WindowsCreateString(wstring.c_str(), static_cast<UINT32>(wstring.length()), hstring);
}
inline HRESULT GetLastHRESULT()
{
return HRESULT_FROM_WIN32(GetLastError());
}
inline HRESULT WSAGetLastHRESULT()
{
return HRESULT_FROM_WIN32(WSAGetLastError());
}
#ifdef __cplusplus_winrt
using ::Platform::Exception;
inline void ThrowIfFailed(HRESULT hr)
{
if (FAILED(hr))
throw Exception::CreateException(hr);
}
inline void ThrowException(HRESULT hr)
{
throw Exception::CreateException(hr);
}
#endif
class HResultException
{
HRESULT m_Hr;
protected:
explicit HResultException(HRESULT hr)
: m_Hr(hr)
{}
public:
HRESULT GetHr() const
{
return m_Hr;
}
__declspec(noreturn)
friend void ThrowHR(HRESULT);
};
//
// Throws an exception for the given HRESULT.
//
__declspec(noreturn) __declspec(noinline)
inline void ThrowHR(HRESULT hr)
{
//if (DeviceLostException::IsDeviceLostHResult(hr))
// throw DeviceLostException(hr);
//else
throw HResultException(hr);
}
//
// Converts exceptions in the callable code into HRESULTs.
//
__declspec(noinline)
inline HRESULT ThrownExceptionToHResult()
{
try
{
throw;
}
catch (HResultException const& e)
{
return e.GetHr();
}
catch (std::bad_alloc const&)
{
return E_OUTOFMEMORY;
}
catch (...)
{
return E_UNEXPECTED;
}
}
template<typename CALLABLE>
HRESULT ExceptionBoundary(CALLABLE&& fn)
{
try
{
fn();
return S_OK;
}
catch (...)
{
return ThrownExceptionToHResult();
}
}
//
// WRL's Make<>() function returns an empty ComPtr on failure rather than
// throwing an exception. This checks the result and throws bad_alloc.
//
// Note: generally we use exceptions inside constructors to report errors.
// Therefore the only way that Make() will return an error is if an allocation
// fails.
//
__declspec(noreturn) __declspec(noinline)
inline void ThrowBadAlloc()
{
throw std::bad_alloc();
}
inline void CheckMakeResult(bool result)
{
if (!result)
ThrowBadAlloc();
}