diff options
Diffstat (limited to 'zen/com_error.h')
-rw-r--r-- | zen/com_error.h | 206 |
1 files changed, 206 insertions, 0 deletions
diff --git a/zen/com_error.h b/zen/com_error.h new file mode 100644 index 00000000..2ba76c0f --- /dev/null +++ b/zen/com_error.h @@ -0,0 +1,206 @@ +// ************************************************************************** +// * This file is part of the FreeFileSync project. It is distributed under * +// * GNU General Public License: http://www.gnu.org/licenses/gpl.html * +// * Copyright (C) 2008-2011 ZenJu (zhnmju123 AT gmx.de) * +// ************************************************************************** + +#ifndef COM_ERROR_HEADER +#define COM_ERROR_HEADER + +#include <string> +#include <cstdio> +#include "win.h" //includes "windows.h" + +namespace zen +{ +std::wstring generateErrorMsg(const std::wstring& input, HRESULT hr); +std::wstring formatWin32Msg(DWORD dwMessageId); //return empty string on error + + + + + + + + + + + + + + + + + + + + + +//################# 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) +{ + wchar_t result[100]; + ::swprintf(result, 100, L"0x%08x", number); + return std::wstring(result); +} + + +inline +std::wstring generateErrorMsg(const std::wstring& input, HRESULT hr) +{ + std::wstring output(input); + output += L"\n"; + output += L"HRESULT: " + numberToHexString(hr) + L",\n"; + + //don't use _com_error(hr).ErrorMessage(): internally 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)); //interpret hr as a Win32 code; this is often useful... + } + return output; +} +} +#endif //COM_ERROR_HEADER |