summaryrefslogtreecommitdiff
path: root/shared/com_error.h
diff options
context:
space:
mode:
Diffstat (limited to 'shared/com_error.h')
-rw-r--r--shared/com_error.h178
1 files changed, 157 insertions, 21 deletions
diff --git a/shared/com_error.h b/shared/com_error.h
index 39f26555..e3d51d4b 100644
--- a/shared/com_error.h
+++ b/shared/com_error.h
@@ -9,31 +9,22 @@
#include <string>
#include <cstdio>
-#include <comdef.h>
+#include <windows.h>
+#undef min
+#undef max
namespace util
{
std::wstring generateErrorMsg(const std::wstring& input, HRESULT hr);
+std::wstring formatWin32Msg(DWORD dwMessageId); //return empty string on error
+
+
+
-class ComException
-{
-public:
- ComException(const std::wstring& message, HRESULT hr = NO_ERROR)
- : message_(message), hr_(hr) {}
- std::wstring show() const
- {
- return hr_ != NO_ERROR ? generateErrorMsg(message_, hr_) : message_;
- }
-private:
- ComException(const ComException&);
- ComException& operator=(const ComException&);
- const std::wstring message_;
- const HRESULT hr_;
-};
@@ -56,6 +47,144 @@ private:
//################# implementation #####################
+std::wstring formatWin32Msg(DWORD dwMessageId) //return empty string on error
+{
+ std::wstring output;
+ LPWSTR buffer = NULL;
+ if (::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_MAX_WIDTH_MASK |
+ FORMAT_MESSAGE_IGNORE_INSERTS | //important: without this flag ::FormatMessage() will fail if message contains placeholders
+ FORMAT_MESSAGE_ALLOCATE_BUFFER, NULL, dwMessageId, 0, reinterpret_cast<LPWSTR>(&buffer), 0, NULL) != 0)
+ {
+ if (buffer) //just to be sure
+ {
+ output = buffer;
+ ::LocalFree(buffer);
+ }
+ }
+ return output;
+}
+
+namespace
+{
+std::wstring formatFacility(HRESULT hr)
+{
+ switch (HRESULT_FACILITY(hr))
+ {
+ case FACILITY_XPS:
+ return L"XPS";
+ case FACILITY_WINRM:
+ return L"Windows Resource Manager";
+ case FACILITY_WINDOWSUPDATE:
+ return L"Windows Update";
+ case FACILITY_WINDOWS_DEFENDER:
+ return L"Windows Defender Component";
+ case FACILITY_WINDOWS_CE:
+ return L"Windows CE";
+ case FACILITY_WINDOWS:
+ return L"Windows Subsystem";
+ case FACILITY_USERMODE_VOLMGR:
+ return L"User Mode Volume Manager";
+ case FACILITY_USERMODE_VIRTUALIZATION:
+ return L"User Mode Virtualization Subsystem";
+ case FACILITY_USERMODE_VHD:
+ return L"User Mode Virtual Hard Disk Support";
+ case FACILITY_URT:
+ return L".NET CLR";
+ case FACILITY_UMI:
+ return L"Ubiquitous Memoryintrospection Service";
+ case FACILITY_UI:
+ return L"UI";
+ case FACILITY_TPM_SOFTWARE:
+ return L"Trusted Platform Module Applications";
+ case FACILITY_TPM_SERVICES:
+ return L"Trusted Platform Module Services";
+ case FACILITY_SXS:
+ return L"Side-by-side Servicing";
+ case FACILITY_STORAGE:
+ return L"OLE Storage";
+ case FACILITY_STATE_MANAGEMENT:
+ return L"State Management Services";
+ case FACILITY_SCARD:
+ return L"Smart-card Subsystem";
+ case FACILITY_SHELL:
+ return L"User Shell";
+ case FACILITY_SETUPAPI:
+ return L"Setup API";
+ case FACILITY_SECURITY:
+ return L"Security API Layer";
+ case FACILITY_SDIAG:
+ return L"System Diagnostics";
+ case FACILITY_RPC:
+ return L"RPC Subsystem";
+ case FACILITY_RAS:
+ return L"RAS";
+ case FACILITY_PLA:
+ return L"Performance Logs and Alerts";
+ case FACILITY_OPC:
+ return L"Open Connectivity Service";
+ case FACILITY_WIN32:
+ return L"Win32";
+ case FACILITY_CONTROL:
+ return L"Control Mechanism";
+ case FACILITY_WEBSERVICES:
+ return L"Web Services";
+ case FACILITY_NDIS:
+ return L"Network Driver Interface";
+ case FACILITY_METADIRECTORY:
+ return L"Microsoft Identity Server";
+ case FACILITY_MSMQ:
+ return L"Microsoft Message Queue";
+ case FACILITY_MEDIASERVER:
+ return L"Windows Media Server";
+ case FACILITY_MBN:
+ return L"MBN";
+ case FACILITY_INTERNET:
+ return L"Wininet";
+ case FACILITY_ITF:
+ return L"COM/OLE Interface Management";
+ case FACILITY_USERMODE_HYPERVISOR:
+ return L"Usermode Hypervisor Components";
+ case FACILITY_HTTP:
+ return L"HTTP Support";
+ case FACILITY_GRAPHICS:
+ return L"Graphics Drivers";
+ case FACILITY_FWP:
+ return L"Firewall Platform";
+ case FACILITY_FVE:
+ return L"Full volume encryption";
+ case FACILITY_USERMODE_FILTER_MANAGER:
+ return L"User Mode Filter Manager";
+ case FACILITY_DPLAY:
+ return L"Direct Play";
+ case FACILITY_DISPATCH:
+ return L"COM Dispatch";
+ case FACILITY_DIRECTORYSERVICE:
+ return L"Active Directory";
+ case FACILITY_CONFIGURATION:
+ return L"Configuration Services";
+ case FACILITY_COMPLUS:
+ return L"COM+";
+ case FACILITY_USERMODE_COMMONLOG:
+ return L"Common Logging Support";
+ case FACILITY_CMI:
+ return L"Configuration Management Infrastructure";
+ case FACILITY_CERT:
+ return L"Certificate";
+ case FACILITY_BCD:
+ return L"Boot Configuration Database";
+ case FACILITY_BACKGROUNDCOPY:
+ return L"Background Copy Control";
+ case FACILITY_ACS:
+ return L"Audit Collection Service";
+ case FACILITY_AAF:
+ return L"Microsoft Agent";
+ default:
+ return L"Unknown";
+ }
+}
+}
+
inline
std::wstring numberToHexString(long number)
{
@@ -69,11 +198,18 @@ inline
std::wstring generateErrorMsg(const std::wstring& input, HRESULT hr)
{
std::wstring output(input);
- output += L" (";
- output += numberToHexString(hr);
- output += L": ";
- output += _com_error(hr).ErrorMessage();
- output += L")";
+ output += L"\n";
+ output += L"HRESULT: " + numberToHexString(hr) + L",\n";
+
+ //don't use _com_error(hr).ErrorMessage(), this is nothing more than a call to ::FormatMessage()
+ std::wstring win32Msg = formatWin32Msg(hr);
+ if (!win32Msg.empty()) //empty string on error
+ output += win32Msg;
+ else
+ {
+ output += L"Facility: " + formatFacility(hr) + L",\n";
+ output += L"Win32 Error: " + formatWin32Msg(HRESULT_CODE(hr)); //interpet hr as a Win32 code; this is often useful
+ }
return output;
}
}
bgstack15