duvc-ctl 2.0.0
USB Video Class Camera Control Library
Loading...
Searching...
No Matches
error_decoder.cpp
Go to the documentation of this file.
1
7#include <iomanip>
8#include <sstream>
9
10#ifdef _WIN32
11#include <comdef.h>
12#include <dshow.h>
13#include <windows.h>
14#endif
15
16#ifdef _WIN32
17#include <vfwmsgs.h>
18// If vfwmsgs.h not available, define manually:
19#ifndef VFW_E_DEVICE_IN_USE
20#define VFW_E_DEVICE_IN_USE 0x80040228L
21#endif
22#endif
23
24namespace duvc {
25
26std::string decode_system_error(unsigned long error_code) {
27#ifdef _WIN32
28 LPWSTR buffer = nullptr;
31
32 DWORD size = FormatMessageW(flags, nullptr, error_code,
34 reinterpret_cast<LPWSTR>(&buffer), 0, nullptr);
35
36 std::string result;
37 if (size > 0 && buffer) {
38 // Convert wide string to UTF-8
39 int utf8_size = WideCharToMultiByte(CP_UTF8, 0, buffer, size, nullptr, 0,
40 nullptr, nullptr);
41 if (utf8_size > 0) {
42 result.resize(utf8_size);
44 nullptr, nullptr);
45 }
47 }
48
49 if (result.empty()) {
50 std::ostringstream ss;
51 ss << "System error 0x" << std::hex << error_code;
52 result = ss.str();
53 }
54
55 // Remove trailing whitespace
56 while (!result.empty() && std::isspace(result.back())) {
57 result.pop_back();
58 }
59
60 return result;
61#else
62 std::ostringstream ss;
63 ss << "System error " << error_code;
64 return ss.str();
65#endif
66}
67
68#ifdef _WIN32
69
71 _com_error error(hr);
72 std::string description;
73
74 if (error.ErrorMessage()) {
75 // Convert wide string to UTF-8
76 const wchar_t *wide_msg = error.ErrorMessage();
77 int utf8_size = WideCharToMultiByte(CP_UTF8, 0, wide_msg, -1, nullptr, 0,
78 nullptr, nullptr);
79 if (utf8_size > 0) {
80 description.resize(utf8_size - 1); // -1 for null terminator
81 WideCharToMultiByte(CP_UTF8, 0, wide_msg, -1, description.data(),
82 utf8_size, nullptr, nullptr);
83 }
84 }
85
86 if (description.empty()) {
87 // Fallback to system error message
88 description = decode_system_error(static_cast<unsigned long>(hr));
89 }
90
91 return description;
92}
93
95 std::ostringstream ss;
96
97 ss << "HRESULT: 0x" << std::hex << std::uppercase << hr << std::dec;
98
99 // Extract facility and code
100 unsigned short facility = HRESULT_FACILITY(hr);
101 unsigned short code = HRESULT_CODE(hr);
102
103 ss << " (Facility: " << facility << ", Code: " << code << ")";
104
105 // Add severity
106 if (FAILED(hr)) {
107 ss << " [FAILURE]";
108 } else {
109 ss << " [SUCCESS]";
110 }
111
112 // Add description
113 std::string description = decode_hresult(hr);
114 if (!description.empty()) {
115 ss << " - " << description;
116 }
117
118 return ss.str();
119}
120
122 // Common device-related error codes
123 switch (hr) {
124 case E_ACCESSDENIED:
132 return true;
133 default:
134 return false;
135 }
136}
137
139 switch (hr) {
140 case E_ACCESSDENIED:
141 return true;
142 default:
143 return false;
144 }
145}
146
147#endif // _WIN32
148
149std::string get_diagnostic_info() {
150 std::ostringstream ss;
151
152 ss << "duvc-ctl Diagnostic Information\n";
153 ss << "==============================\n";
154
155#ifdef _WIN32
156 // Windows version
157 ss << "Platform: Windows\n";
158
160 version_info.dwOSVersionInfoSize = sizeof(version_info);
161
162#pragma warning(push)
163#pragma warning(disable : 4996) // GetVersionEx is deprecated
165 ss << "Windows Version: " << version_info.dwMajorVersion << "."
166 << version_info.dwMinorVersion << " (Build "
167 << version_info.dwBuildNumber << ")\n";
168 }
169#pragma warning(pop)
170
171 // Process architecture
174
175 const char *arch = "Unknown";
176 switch (sys_info.wProcessorArchitecture) {
178 arch = "x64";
179 break;
181 arch = "x86";
182 break;
184 arch = "ARM64";
185 break;
187 arch = "ARM";
188 break;
189 }
190 ss << "Architecture: " << arch << "\n";
191
192 // COM initialization status
194 if (SUCCEEDED(hr)) {
195 ss << "COM Status: Available\n";
197 } else if (hr == RPC_E_CHANGED_MODE) {
198 ss << "COM Status: Already initialized (different mode)\n";
199 } else {
200 ss << "COM Status: Error - " << decode_hresult(hr) << "\n";
201 }
202
203 // DirectShow availability
204 ICreateDevEnum *dev_enum = nullptr;
207 reinterpret_cast<void **>(&dev_enum));
208 if (SUCCEEDED(hr) && dev_enum) {
209 ss << "DirectShow: Available\n";
210 dev_enum->Release();
211 } else {
212 ss << "DirectShow: Error - " << decode_hresult(hr) << "\n";
213 }
214
215#else
216 ss << "Platform: Non-Windows (stub implementation)\n";
217#endif
218
219 return ss.str();
220}
221
222} // namespace duvc
Result type that can contain either a value or an error.
Definition result.h:75
EXTERN_C const CLSID CLSID_SystemDeviceEnum
Definition device.cpp:17
EXTERN_C const IID IID_ICreateDevEnum
Definition device.cpp:19
#define VFW_E_DEVICE_IN_USE
HRESULT decoder and diagnostics utilities.
Definition core.h:13
bool is_permission_error(HRESULT hr)
Check if HRESULT indicates permission/access error.
bool is_device_error(HRESULT hr)
Check if HRESULT indicates a device-related error.
std::string get_hresult_details(HRESULT hr)
Get detailed HRESULT information.
std::string get_diagnostic_info()
Get diagnostic information for troubleshooting.
std::string decode_hresult(HRESULT hr)
Decode HRESULT to human-readable string.
std::string decode_system_error(unsigned long error_code)
Decode system error code to human-readable string.