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)
13 extern bool g_IsNT;
14 #endif
15 #endif
16
17 namespace NWindows {
18 namespace NError {
19
MyFormatMessage(DWORD errorCode,UString & message)20 static bool MyFormatMessage(DWORD errorCode, UString &message)
21 {
22 #ifndef _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
MyFormatMessage(DWORD errorCode)110 UString 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