xref: /third_party/lzma/CPP/Windows/ErrorMsg.cpp (revision 370b324c)
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