Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
420
Src/external_dependencies/openmpt-trunk/include/unrar/errhnd.cpp
vendored
Normal file
420
Src/external_dependencies/openmpt-trunk/include/unrar/errhnd.cpp
vendored
Normal file
|
@ -0,0 +1,420 @@
|
|||
#include "rar.hpp"
|
||||
|
||||
ErrorHandler::ErrorHandler()
|
||||
{
|
||||
Clean();
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::Clean()
|
||||
{
|
||||
ExitCode=RARX_SUCCESS;
|
||||
ErrCount=0;
|
||||
EnableBreak=true;
|
||||
Silent=false;
|
||||
UserBreak=false;
|
||||
MainExit=false;
|
||||
DisableShutdown=false;
|
||||
ReadErrIgnoreAll=false;
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::MemoryError()
|
||||
{
|
||||
MemoryErrorMsg();
|
||||
Exit(RARX_MEMORY);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::OpenError(const wchar *FileName)
|
||||
{
|
||||
#ifndef SILENT
|
||||
OpenErrorMsg(FileName);
|
||||
Exit(RARX_OPEN);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::CloseError(const wchar *FileName)
|
||||
{
|
||||
if (!UserBreak)
|
||||
{
|
||||
uiMsg(UIERROR_FILECLOSE,FileName);
|
||||
SysErrMsg();
|
||||
}
|
||||
// We must not call Exit and throw an exception here, because this function
|
||||
// is called from File object destructor and can be invoked when stack
|
||||
// unwinding while handling another exception. Throwing a new exception
|
||||
// when stack unwinding is prohibited and terminates a program.
|
||||
// If necessary, we can check std::uncaught_exception() before throw.
|
||||
SetErrorCode(RARX_FATAL);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::ReadError(const wchar *FileName)
|
||||
{
|
||||
#ifndef SILENT
|
||||
ReadErrorMsg(FileName);
|
||||
#endif
|
||||
#if !defined(SILENT) || defined(RARDLL)
|
||||
Exit(RARX_READ);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::AskRepeatRead(const wchar *FileName,bool &Ignore,bool &Retry,bool &Quit)
|
||||
{
|
||||
SetErrorCode(RARX_READ);
|
||||
#if !defined(SILENT) && !defined(SFX_MODULE)
|
||||
if (!Silent)
|
||||
{
|
||||
uiMsg(UIERROR_FILEREAD,UINULL,FileName);
|
||||
SysErrMsg();
|
||||
if (ReadErrIgnoreAll)
|
||||
Ignore=true;
|
||||
else
|
||||
{
|
||||
bool All=false;
|
||||
uiAskRepeatRead(FileName,Ignore,All,Retry,Quit);
|
||||
if (All)
|
||||
ReadErrIgnoreAll=Ignore=true;
|
||||
if (Quit) // Disable shutdown if user select Quit in read error prompt.
|
||||
DisableShutdown=true;
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
Ignore=true; // Saving the file part for -y or -inul or "Ignore all" choice.
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::WriteError(const wchar *ArcName,const wchar *FileName)
|
||||
{
|
||||
#ifndef SILENT
|
||||
WriteErrorMsg(ArcName,FileName);
|
||||
#endif
|
||||
#if !defined(SILENT) || defined(RARDLL)
|
||||
Exit(RARX_WRITE);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN_ALL
|
||||
void ErrorHandler::WriteErrorFAT(const wchar *FileName)
|
||||
{
|
||||
SysErrMsg();
|
||||
uiMsg(UIERROR_NTFSREQUIRED,FileName);
|
||||
#if !defined(SILENT) && !defined(SFX_MODULE) || defined(RARDLL)
|
||||
Exit(RARX_WRITE);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
bool ErrorHandler::AskRepeatWrite(const wchar *FileName,bool DiskFull)
|
||||
{
|
||||
#ifndef SILENT
|
||||
if (!Silent)
|
||||
{
|
||||
// We do not display "repeat write" prompt in Android, so we do not
|
||||
// need the matching system error message.
|
||||
SysErrMsg();
|
||||
bool Repeat=uiAskRepeatWrite(FileName,DiskFull);
|
||||
if (!Repeat) // Disable shutdown if user pressed Cancel in error dialog.
|
||||
DisableShutdown=true;
|
||||
return Repeat;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::SeekError(const wchar *FileName)
|
||||
{
|
||||
if (!UserBreak)
|
||||
{
|
||||
uiMsg(UIERROR_FILESEEK,FileName);
|
||||
SysErrMsg();
|
||||
}
|
||||
#if !defined(SILENT) || defined(RARDLL)
|
||||
Exit(RARX_FATAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::GeneralErrMsg(const wchar *fmt,...)
|
||||
{
|
||||
va_list arglist;
|
||||
va_start(arglist,fmt);
|
||||
wchar Msg[1024];
|
||||
vswprintf(Msg,ASIZE(Msg),fmt,arglist);
|
||||
uiMsg(UIERROR_GENERALERRMSG,Msg);
|
||||
SysErrMsg();
|
||||
va_end(arglist);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::MemoryErrorMsg()
|
||||
{
|
||||
uiMsg(UIERROR_MEMORY);
|
||||
SetErrorCode(RARX_MEMORY);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::OpenErrorMsg(const wchar *FileName)
|
||||
{
|
||||
OpenErrorMsg(NULL,FileName);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::OpenErrorMsg(const wchar *ArcName,const wchar *FileName)
|
||||
{
|
||||
Wait(); // Keep GUI responsive if many files cannot be opened when archiving.
|
||||
uiMsg(UIERROR_FILEOPEN,ArcName,FileName);
|
||||
SysErrMsg();
|
||||
SetErrorCode(RARX_OPEN);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::CreateErrorMsg(const wchar *FileName)
|
||||
{
|
||||
CreateErrorMsg(NULL,FileName);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::CreateErrorMsg(const wchar *ArcName,const wchar *FileName)
|
||||
{
|
||||
uiMsg(UIERROR_FILECREATE,ArcName,FileName);
|
||||
SysErrMsg();
|
||||
SetErrorCode(RARX_CREATE);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::ReadErrorMsg(const wchar *FileName)
|
||||
{
|
||||
ReadErrorMsg(NULL,FileName);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::ReadErrorMsg(const wchar *ArcName,const wchar *FileName)
|
||||
{
|
||||
uiMsg(UIERROR_FILEREAD,ArcName,FileName);
|
||||
SysErrMsg();
|
||||
SetErrorCode(RARX_READ);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::WriteErrorMsg(const wchar *ArcName,const wchar *FileName)
|
||||
{
|
||||
uiMsg(UIERROR_FILEWRITE,ArcName,FileName);
|
||||
SysErrMsg();
|
||||
SetErrorCode(RARX_WRITE);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::ArcBrokenMsg(const wchar *ArcName)
|
||||
{
|
||||
uiMsg(UIERROR_ARCBROKEN,ArcName);
|
||||
SetErrorCode(RARX_CRC);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::ChecksumFailedMsg(const wchar *ArcName,const wchar *FileName)
|
||||
{
|
||||
uiMsg(UIERROR_CHECKSUM,ArcName,FileName);
|
||||
SetErrorCode(RARX_CRC);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::UnknownMethodMsg(const wchar *ArcName,const wchar *FileName)
|
||||
{
|
||||
uiMsg(UIERROR_UNKNOWNMETHOD,ArcName,FileName);
|
||||
ErrHandler.SetErrorCode(RARX_FATAL);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::Exit(RAR_EXIT ExitCode)
|
||||
{
|
||||
uiAlarm(UIALARM_ERROR);
|
||||
Throw(ExitCode);
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::SetErrorCode(RAR_EXIT Code)
|
||||
{
|
||||
switch(Code)
|
||||
{
|
||||
case RARX_WARNING:
|
||||
case RARX_USERBREAK:
|
||||
if (ExitCode==RARX_SUCCESS)
|
||||
ExitCode=Code;
|
||||
break;
|
||||
case RARX_CRC:
|
||||
if (ExitCode!=RARX_BADPWD)
|
||||
ExitCode=Code;
|
||||
break;
|
||||
case RARX_FATAL:
|
||||
if (ExitCode==RARX_SUCCESS || ExitCode==RARX_WARNING)
|
||||
ExitCode=RARX_FATAL;
|
||||
break;
|
||||
default:
|
||||
ExitCode=Code;
|
||||
break;
|
||||
}
|
||||
ErrCount++;
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN_ALL
|
||||
BOOL __stdcall ProcessSignal(DWORD SigType)
|
||||
#else
|
||||
#if defined(__sun)
|
||||
extern "C"
|
||||
#endif
|
||||
void _stdfunction ProcessSignal(int SigType)
|
||||
#endif
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
// When a console application is run as a service, this allows the service
|
||||
// to continue running after the user logs off.
|
||||
if (SigType==CTRL_LOGOFF_EVENT)
|
||||
return TRUE;
|
||||
#endif
|
||||
|
||||
ErrHandler.UserBreak=true;
|
||||
ErrHandler.SetDisableShutdown();
|
||||
mprintf(St(MBreak));
|
||||
|
||||
#ifdef _WIN_ALL
|
||||
// Let the main thread to handle 'throw' and destroy file objects.
|
||||
for (uint I=0;!ErrHandler.MainExit && I<50;I++)
|
||||
Sleep(100);
|
||||
#if defined(USE_RC) && !defined(SFX_MODULE) && !defined(RARDLL)
|
||||
ExtRes.UnloadDLL();
|
||||
#endif
|
||||
exit(RARX_USERBREAK);
|
||||
#endif
|
||||
|
||||
#ifdef _UNIX
|
||||
static uint BreakCount=0;
|
||||
// User continues to press Ctrl+C, exit immediately without cleanup.
|
||||
if (++BreakCount>1)
|
||||
exit(RARX_USERBREAK);
|
||||
// Otherwise return from signal handler and let Wait() function to close
|
||||
// files and quit. We cannot use the same approach as in Windows,
|
||||
// because Unix signal handler can block execution of our main code.
|
||||
#endif
|
||||
|
||||
#if defined(_WIN_ALL) && !defined(_MSC_VER)
|
||||
// Never reached, just to avoid a compiler warning
|
||||
return TRUE;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::SetSignalHandlers(bool Enable)
|
||||
{
|
||||
EnableBreak=Enable;
|
||||
#ifdef _WIN_ALL
|
||||
SetConsoleCtrlHandler(Enable ? ProcessSignal:NULL,TRUE);
|
||||
#else
|
||||
signal(SIGINT,Enable ? ProcessSignal:SIG_IGN);
|
||||
signal(SIGTERM,Enable ? ProcessSignal:SIG_IGN);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::Throw(RAR_EXIT Code)
|
||||
{
|
||||
if (Code==RARX_USERBREAK && !EnableBreak)
|
||||
return;
|
||||
#if !defined(SILENT)
|
||||
// Do not write "aborted" when just displaying online help.
|
||||
if (Code!=RARX_SUCCESS && Code!=RARX_USERERROR)
|
||||
mprintf(L"\n%s\n",St(MProgAborted));
|
||||
#endif
|
||||
SetErrorCode(Code);
|
||||
throw Code;
|
||||
}
|
||||
|
||||
|
||||
bool ErrorHandler::GetSysErrMsg(wchar *Msg,size_t Size)
|
||||
{
|
||||
#ifndef SILENT
|
||||
#ifdef _WIN_ALL
|
||||
int ErrType=GetLastError();
|
||||
if (ErrType!=0)
|
||||
return FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||
NULL,ErrType,MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
|
||||
Msg,(DWORD)Size,NULL)!=0;
|
||||
#endif
|
||||
|
||||
#if defined(_UNIX) || defined(_EMX)
|
||||
if (errno!=0)
|
||||
{
|
||||
char *err=strerror(errno);
|
||||
if (err!=NULL)
|
||||
{
|
||||
CharToWide(err,Msg,Size);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::SysErrMsg()
|
||||
{
|
||||
#ifndef SILENT
|
||||
wchar Msg[1024];
|
||||
if (!GetSysErrMsg(Msg,ASIZE(Msg)))
|
||||
return;
|
||||
#ifdef _WIN_ALL
|
||||
wchar *CurMsg=Msg;
|
||||
while (CurMsg!=NULL) // Print string with \r\n as several strings to multiple lines.
|
||||
{
|
||||
while (*CurMsg=='\r' || *CurMsg=='\n')
|
||||
CurMsg++;
|
||||
if (*CurMsg==0)
|
||||
break;
|
||||
wchar *EndMsg=wcschr(CurMsg,'\r');
|
||||
if (EndMsg==NULL)
|
||||
EndMsg=wcschr(CurMsg,'\n');
|
||||
if (EndMsg!=NULL)
|
||||
{
|
||||
*EndMsg=0;
|
||||
EndMsg++;
|
||||
}
|
||||
uiMsg(UIERROR_SYSERRMSG,CurMsg);
|
||||
CurMsg=EndMsg;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(_UNIX) || defined(_EMX)
|
||||
uiMsg(UIERROR_SYSERRMSG,Msg);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int ErrorHandler::GetSystemErrorCode()
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
return GetLastError();
|
||||
#else
|
||||
return errno;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void ErrorHandler::SetSystemErrorCode(int Code)
|
||||
{
|
||||
#ifdef _WIN_ALL
|
||||
SetLastError(Code);
|
||||
#else
|
||||
errno=Code;
|
||||
#endif
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue