unrarsrc  6.1.7
About: unrar extracts, views and tests the contents of archives created with the RAR archiver.
  Fossies Dox: unrarsrc-6.1.7.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

errhnd.cpp
Go to the documentation of this file.
1#include "rar.hpp"
2
4{
5 Clean();
6}
7
8
10{
12 ErrCount=0;
13 EnableBreak=true;
14 Silent=false;
15 UserBreak=false;
16 MainExit=false;
17 DisableShutdown=false;
18 ReadErrIgnoreAll=false;
19}
20
21
23{
26}
27
28
29void ErrorHandler::OpenError(const wchar *FileName)
30{
31#ifndef SILENT
32 OpenErrorMsg(FileName);
34#endif
35}
36
37
38void ErrorHandler::CloseError(const wchar *FileName)
39{
40 if (!UserBreak)
41 {
42 uiMsg(UIERROR_FILECLOSE,FileName);
43 SysErrMsg();
44 }
45 // We must not call Exit and throw an exception here, because this function
46 // is called from File object destructor and can be invoked when stack
47 // unwinding while handling another exception. Throwing a new exception
48 // when stack unwinding is prohibited and terminates a program.
49 // If necessary, we can check std::uncaught_exception() before throw.
51}
52
53
54void ErrorHandler::ReadError(const wchar *FileName)
55{
56#ifndef SILENT
57 ReadErrorMsg(FileName);
58#endif
59#if !defined(SILENT) || defined(RARDLL)
61#endif
62}
63
64
65void ErrorHandler::AskRepeatRead(const wchar *FileName,bool &Ignore,bool &Retry,bool &Quit)
66{
68#if !defined(SILENT) && !defined(SFX_MODULE)
69 if (!Silent)
70 {
72 SysErrMsg();
74 Ignore=true;
75 else
76 {
77 bool All=false;
78 uiAskRepeatRead(FileName,Ignore,All,Retry,Quit);
79 if (All)
80 ReadErrIgnoreAll=Ignore=true;
81 if (Quit) // Disable shutdown if user select Quit in read error prompt.
82 DisableShutdown=true;
83 }
84 return;
85 }
86#endif
87 Ignore=true; // Saving the file part for -y or -inul or "Ignore all" choice.
88}
89
90
91void ErrorHandler::WriteError(const wchar *ArcName,const wchar *FileName)
92{
93#ifndef SILENT
94 WriteErrorMsg(ArcName,FileName);
95#endif
96#if !defined(SILENT) || defined(RARDLL)
98#endif
99}
100
101
102#ifdef _WIN_ALL
103void ErrorHandler::WriteErrorFAT(const wchar *FileName)
104{
105 SysErrMsg();
106 uiMsg(UIERROR_NTFSREQUIRED,FileName);
107#if !defined(SILENT) && !defined(SFX_MODULE) || defined(RARDLL)
109#endif
110}
111#endif
112
113
114bool ErrorHandler::AskRepeatWrite(const wchar *FileName,bool DiskFull)
115{
116#ifndef SILENT
117 if (!Silent)
118 {
119 // We do not display "repeat write" prompt in Android, so we do not
120 // need the matching system error message.
121 SysErrMsg();
122 bool Repeat=uiAskRepeatWrite(FileName,DiskFull);
123 if (!Repeat) // Disable shutdown if user pressed Cancel in error dialog.
124 DisableShutdown=true;
125 return Repeat;
126 }
127#endif
128 return false;
129}
130
131
132void ErrorHandler::SeekError(const wchar *FileName)
133{
134 if (!UserBreak)
135 {
136 uiMsg(UIERROR_FILESEEK,FileName);
137 SysErrMsg();
138 }
139#if !defined(SILENT) || defined(RARDLL)
141#endif
142}
143
144
146{
147 va_list arglist;
148 va_start(arglist,fmt);
149 wchar Msg[1024];
150 vswprintf(Msg,ASIZE(Msg),fmt,arglist);
152 SysErrMsg();
153 va_end(arglist);
154}
155
156
158{
161}
162
163
165{
166 OpenErrorMsg(NULL,FileName);
167}
168
169
170void ErrorHandler::OpenErrorMsg(const wchar *ArcName,const wchar *FileName)
171{
172 Wait(); // Keep GUI responsive if many files cannot be opened when archiving.
173 uiMsg(UIERROR_FILEOPEN,ArcName,FileName);
174 SysErrMsg();
176}
177
178
180{
181 CreateErrorMsg(NULL,FileName);
182}
183
184
185void ErrorHandler::CreateErrorMsg(const wchar *ArcName,const wchar *FileName)
186{
187 uiMsg(UIERROR_FILECREATE,ArcName,FileName);
188 SysErrMsg();
190}
191
192
194{
195 ReadErrorMsg(NULL,FileName);
196}
197
198
199void ErrorHandler::ReadErrorMsg(const wchar *ArcName,const wchar *FileName)
200{
201 uiMsg(UIERROR_FILEREAD,ArcName,FileName);
202 SysErrMsg();
204}
205
206
207void ErrorHandler::WriteErrorMsg(const wchar *ArcName,const wchar *FileName)
208{
209 uiMsg(UIERROR_FILEWRITE,ArcName,FileName);
210 SysErrMsg();
212}
213
214
216{
217 uiMsg(UIERROR_ARCBROKEN,ArcName);
219}
220
221
222void ErrorHandler::ChecksumFailedMsg(const wchar *ArcName,const wchar *FileName)
223{
224 uiMsg(UIERROR_CHECKSUM,ArcName,FileName);
226}
227
228
229void ErrorHandler::UnknownMethodMsg(const wchar *ArcName,const wchar *FileName)
230{
231 uiMsg(UIERROR_UNKNOWNMETHOD,ArcName,FileName);
233}
234
235
237{
240}
241
242
244{
245 switch(Code)
246 {
247 case RARX_WARNING:
248 case RARX_USERBREAK:
250 ExitCode=Code;
251 break;
252 case RARX_CRC:
254 ExitCode=Code;
255 break;
256 case RARX_FATAL:
259 break;
260 default:
261 ExitCode=Code;
262 break;
263 }
264 ErrCount++;
265}
266
267
268#ifdef _WIN_ALL
269BOOL __stdcall ProcessSignal(DWORD SigType)
270#else
271#if defined(__sun)
272extern "C"
273#endif
274void _stdfunction ProcessSignal(int SigType)
275#endif
276{
277#ifdef _WIN_ALL
278 // When a console application is run as a service, this allows the service
279 // to continue running after the user logs off.
280 if (SigType==CTRL_LOGOFF_EVENT)
281 return TRUE;
282#endif
283
286 mprintf(St(MBreak));
287
288#ifdef _WIN_ALL
289 // Let the main thread to handle 'throw' and destroy file objects.
290 for (uint I=0;!ErrHandler.MainExit && I<50;I++)
291 Sleep(100);
292#if defined(USE_RC) && !defined(SFX_MODULE) && !defined(RARDLL)
293 ExtRes.UnloadDLL();
294#endif
295 exit(RARX_USERBREAK);
296#endif
297
298#ifdef _UNIX
299 static uint BreakCount=0;
300 // User continues to press Ctrl+C, exit immediately without cleanup.
301 if (++BreakCount>1)
302 exit(RARX_USERBREAK);
303 // Otherwise return from signal handler and let Wait() function to close
304 // files and quit. We cannot use the same approach as in Windows,
305 // because Unix signal handler can block execution of our main code.
306#endif
307
308#if defined(_WIN_ALL) && !defined(_MSC_VER)
309 // Never reached, just to avoid a compiler warning
310 return TRUE;
311#endif
312}
313
314
316{
317 EnableBreak=Enable;
318#ifdef _WIN_ALL
319 SetConsoleCtrlHandler(Enable ? ProcessSignal:NULL,TRUE);
320#else
321 signal(SIGINT,Enable ? ProcessSignal:SIG_IGN);
322 signal(SIGTERM,Enable ? ProcessSignal:SIG_IGN);
323#endif
324}
325
326
328{
329 if (Code==RARX_USERBREAK && !EnableBreak)
330 return;
331#if !defined(SILENT)
332 // Do not write "aborted" when just displaying online help.
333 if (Code!=RARX_SUCCESS && Code!=RARX_USERERROR)
334 mprintf(L"\n%s\n",St(MProgAborted));
335#endif
336 SetErrorCode(Code);
337 throw Code;
338}
339
340
341bool ErrorHandler::GetSysErrMsg(wchar *Msg,size_t Size)
342{
343#ifndef SILENT
344#ifdef _WIN_ALL
345 int ErrType=GetLastError();
346 if (ErrType!=0)
347 return FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
348 NULL,ErrType,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
349 Msg,(DWORD)Size,NULL)!=0;
350#endif
351
352#if defined(_UNIX) || defined(_EMX)
353 if (errno!=0)
354 {
355 char *err=strerror(errno);
356 if (err!=NULL)
357 {
358 CharToWide(err,Msg,Size);
359 return true;
360 }
361 }
362#endif
363#endif
364 return false;
365}
366
367
369{
370#ifndef SILENT
371 wchar Msg[1024];
372 if (!GetSysErrMsg(Msg,ASIZE(Msg)))
373 return;
374#ifdef _WIN_ALL
375 wchar *CurMsg=Msg;
376 while (CurMsg!=NULL) // Print string with \r\n as several strings to multiple lines.
377 {
378 while (*CurMsg=='\r' || *CurMsg=='\n')
379 CurMsg++;
380 if (*CurMsg==0)
381 break;
382 wchar *EndMsg=wcschr(CurMsg,'\r');
383 if (EndMsg==NULL)
384 EndMsg=wcschr(CurMsg,'\n');
385 if (EndMsg!=NULL)
386 {
387 *EndMsg=0;
388 EndMsg++;
389 }
390 uiMsg(UIERROR_SYSERRMSG,CurMsg);
391 CurMsg=EndMsg;
392 }
393#endif
394
395#if defined(_UNIX) || defined(_EMX)
397#endif
398
399#endif
400}
401
402
404{
405#ifdef _WIN_ALL
406 return GetLastError();
407#else
408 return errno;
409#endif
410}
411
412
414{
415#ifdef _WIN_ALL
416 SetLastError(Code);
417#else
418 errno=Code;
419#endif
420}
ErrorHandler ErrHandler
void ReadError(const wchar *FileName)
Definition: errhnd.cpp:54
bool DisableShutdown
Definition: errhnd.hpp:30
void OpenErrorMsg(const wchar *FileName)
Definition: errhnd.cpp:164
void MemoryErrorMsg()
Definition: errhnd.cpp:157
void GeneralErrMsg(const wchar *fmt,...)
Definition: errhnd.cpp:145
void ChecksumFailedMsg(const wchar *ArcName, const wchar *FileName)
Definition: errhnd.cpp:222
bool MainExit
Definition: errhnd.hpp:71
void AskRepeatRead(const wchar *FileName, bool &Ignore, bool &Retry, bool &Quit)
Definition: errhnd.cpp:65
void SetErrorCode(RAR_EXIT Code)
Definition: errhnd.cpp:243
void SysErrMsg()
Definition: errhnd.cpp:368
void ArcBrokenMsg(const wchar *ArcName)
Definition: errhnd.cpp:215
void UnknownMethodMsg(const wchar *ArcName, const wchar *FileName)
Definition: errhnd.cpp:229
void SetSignalHandlers(bool Enable)
Definition: errhnd.cpp:315
bool GetSysErrMsg(wchar *Msg, size_t Size)
Definition: errhnd.cpp:341
ErrorHandler()
Definition: errhnd.cpp:3
bool Silent
Definition: errhnd.hpp:29
int GetSystemErrorCode()
Definition: errhnd.cpp:403
void WriteErrorMsg(const wchar *ArcName, const wchar *FileName)
Definition: errhnd.cpp:207
void OpenError(const wchar *FileName)
Definition: errhnd.cpp:29
void WriteErrorFAT(const wchar *FileName)
void CreateErrorMsg(const wchar *FileName)
Definition: errhnd.cpp:179
bool ReadErrIgnoreAll
Definition: errhnd.hpp:31
void CloseError(const wchar *FileName)
Definition: errhnd.cpp:38
bool EnableBreak
Definition: errhnd.hpp:28
void WriteError(const wchar *ArcName, const wchar *FileName)
Definition: errhnd.cpp:91
void Clean()
Definition: errhnd.cpp:9
void MemoryError()
Definition: errhnd.cpp:22
uint ErrCount
Definition: errhnd.hpp:27
bool AskRepeatWrite(const wchar *FileName, bool DiskFull)
Definition: errhnd.cpp:114
void SeekError(const wchar *FileName)
Definition: errhnd.cpp:132
void ReadErrorMsg(const wchar *FileName)
Definition: errhnd.cpp:193
RAR_EXIT ExitCode
Definition: errhnd.hpp:26
void Exit(RAR_EXIT ExitCode)
Definition: errhnd.cpp:236
void SetDisableShutdown()
Definition: errhnd.hpp:67
bool UserBreak
Definition: errhnd.hpp:70
void SetSystemErrorCode(int Code)
Definition: errhnd.cpp:413
void Throw(RAR_EXIT Code)
Definition: errhnd.cpp:327
void mprintf(const wchar *fmt,...)
Definition: consio.cpp:118
void ProcessSignal(int SigType)
Definition: errhnd.cpp:274
RAR_EXIT
Definition: errhnd.hpp:5
@ RARX_MEMORY
Definition: errhnd.hpp:14
@ RARX_USERBREAK
Definition: errhnd.hpp:19
@ RARX_OPEN
Definition: errhnd.hpp:12
@ RARX_BADPWD
Definition: errhnd.hpp:17
@ RARX_READ
Definition: errhnd.hpp:18
@ RARX_CRC
Definition: errhnd.hpp:9
@ RARX_WRITE
Definition: errhnd.hpp:11
@ RARX_FATAL
Definition: errhnd.hpp:8
@ RARX_CREATE
Definition: errhnd.hpp:15
@ RARX_SUCCESS
Definition: errhnd.hpp:6
@ RARX_USERERROR
Definition: errhnd.hpp:13
@ RARX_WARNING
Definition: errhnd.hpp:7
#define MProgAborted
Definition: loclang.hpp:162
#define MBreak
Definition: loclang.hpp:165
#define TRUE
Definition: os.hpp:5
#define ASIZE(x)
Definition: rardefs.hpp:10
wchar_t wchar
Definition: rartypes.hpp:13
unsigned int uint
Definition: rartypes.hpp:8
const wchar * St(MSGID StringId)
Definition: resource.cpp:8
void Wait()
Definition: system.cpp:80
void uiAlarm(UIALARM_TYPE Type)
Definition: uiconsole.cpp:413
void uiAskRepeatRead(const wchar *FileName, bool &Ignore, bool &All, bool &Retry, bool &Quit)
Definition: uiconsole.cpp:440
bool uiAskRepeatWrite(const wchar *FileName, bool DiskFull)
Definition: uiconsole.cpp:452
void uiMsg(UIMESSAGE_CODE Code)
Definition: ui.hpp:148
#define UINULL
Definition: ui.hpp:146
@ UIALARM_ERROR
Definition: ui.hpp:94
@ UIERROR_MEMORY
Definition: ui.hpp:12
@ UIERROR_SYSERRMSG
Definition: ui.hpp:10
@ UIERROR_FILEWRITE
Definition: ui.hpp:13
@ UIERROR_CHECKSUM
Definition: ui.hpp:11
@ UIERROR_FILESEEK
Definition: ui.hpp:13
@ UIERROR_FILEREAD
Definition: ui.hpp:13
@ UIERROR_FILECLOSE
Definition: ui.hpp:13
@ UIERROR_ARCBROKEN
Definition: ui.hpp:17
@ UIERROR_GENERALERRMSG
Definition: ui.hpp:10
@ UIERROR_UNKNOWNMETHOD
Definition: ui.hpp:20
@ UIERROR_NTFSREQUIRED
Definition: ui.hpp:34
@ UIERROR_FILECREATE
Definition: ui.hpp:12
@ UIERROR_FILEOPEN
Definition: ui.hpp:12
bool CharToWide(const char *Src, wchar *Dest, size_t DestSize)
Definition: unicode.cpp:85