1// Windows/ErrorMsg.h 2 3#include "StdAfx.h" 4 5#if !defined(_UNICODE) || !defined(_WIN32) 6#include "../Common/StringConvert.h" 7#endif 8 9#include "ErrorMsg.h" 10 11#ifdef _WIN32 12#if !defined(_UNICODE) 13extern bool g_IsNT; 14#endif 15#endif 16 17namespace NWindows { 18namespace NError { 19 20static bool MyFormatMessage(DWORD errorCode, UString &message) 21{ 22 #ifndef Z7_SFX 23 if ((HRESULT)errorCode == MY_HRES_ERROR_INTERNAL_ERROR) 24 { 25 message = "Internal Error: The failure in hardware (RAM or CPU), OS or program"; 26 return true; 27 } 28 #endif 29 30 #ifdef _WIN32 31 32 LPVOID msgBuf; 33 #ifndef _UNICODE 34 if (!g_IsNT) 35 { 36 if (::FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | 37 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 38 NULL, errorCode, 0, (LPTSTR) &msgBuf, 0, NULL) == 0) 39 return false; 40 message = GetUnicodeString((LPCTSTR)msgBuf); 41 } 42 else 43 #endif 44 { 45 if (::FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | 46 FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, 47 NULL, errorCode, 0, (LPWSTR) &msgBuf, 0, NULL) == 0) 48 return false; 49 message = (LPCWSTR)msgBuf; 50 } 51 ::LocalFree(msgBuf); 52 return true; 53 54 #else // _WIN32 55 56 AString m; 57 58 const char *s = NULL; 59 60 switch ((Int32)errorCode) 61 { 62 // case ERROR_NO_MORE_FILES : s = "No more files"; break; 63 // case ERROR_DIRECTORY : s = "Error Directory"; break; 64 case E_NOTIMPL : s = "E_NOTIMPL : Not implemented"; break; 65 case E_NOINTERFACE : s = "E_NOINTERFACE : No such interface supported"; break; 66 case E_ABORT : s = "E_ABORT : Operation aborted"; break; 67 case E_FAIL : s = "E_FAIL : Unspecified error"; break; 68 69 case STG_E_INVALIDFUNCTION : s = "STG_E_INVALIDFUNCTION"; break; 70 case CLASS_E_CLASSNOTAVAILABLE : s = "CLASS_E_CLASSNOTAVAILABLE"; break; 71 72 case E_OUTOFMEMORY : s = "E_OUTOFMEMORY : Can't allocate required memory"; break; 73 case E_INVALIDARG : s = "E_INVALIDARG : One or more arguments are invalid"; break; 74 75 // case MY_E_ERROR_NEGATIVE_SEEK : s = "MY_E_ERROR_NEGATIVE_SEEK"; break; 76 default: 77 break; 78 } 79 80 /* strerror() for unknown errors still shows message "Unknown error -12345678") 81 So we must transfer error codes before strerror() */ 82 if (!s) 83 { 84 if ((errorCode & 0xFFFF0000) == (UInt32)((MY_FACILITY_WRes << 16) | 0x80000000)) 85 errorCode &= 0xFFFF; 86 else if ((errorCode & ((UInt32)1 << 31))) 87 return false; // we will show hex error later for that case 88 89 s = strerror((int)errorCode); 90 91 // if (!s) 92 { 93 m += "errno="; 94 m.Add_UInt32(errorCode); 95 if (s) 96 m += " : "; 97 } 98 } 99 100 if (s) 101 m += s; 102 103 MultiByteToUnicodeString2(message, m); 104 return true; 105 106 #endif 107} 108 109 110UString MyFormatMessage(DWORD errorCode) 111{ 112 UString m; 113 if (!MyFormatMessage(errorCode, m) || m.IsEmpty()) 114 { 115 char s[16]; 116 for (int i = 0; i < 8; i++) 117 { 118 unsigned t = errorCode & 0xF; 119 errorCode >>= 4; 120 s[7 - i] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); 121 } 122 s[8] = 0; 123 m += "Error #"; 124 m += s; 125 } 126 else if (m.Len() >= 2 127 && m[m.Len() - 1] == 0x0A 128 && m[m.Len() - 2] == 0x0D) 129 m.DeleteFrom(m.Len() - 2); 130 return m; 131} 132 133}} 134