1
0
mirror of https://github.com/hashcat/hashcat.git synced 2024-11-21 23:58:07 +00:00

Updated unrar source from 5.9.4 to 6.0.5

This commit is contained in:
Jens Steube 2021-05-15 11:31:42 +02:00
parent ce90f83b65
commit f4ca10b116
32 changed files with 400 additions and 94 deletions

View File

@ -51,7 +51,7 @@
* RAR uses CRC32 function based on Intel Slicing-by-8 algorithm.
Original Intel Slicing-by-8 code is available here:
http://sourceforge.net/projects/slicing-by-8/
https://sourceforge.net/projects/slicing-by-8/
Original Intel Slicing-by-8 code is licensed under BSD License
available at http://www.opensource.org/licenses/bsd-license.html

View File

@ -785,7 +785,7 @@ size_t Archive::ReadHeader50()
case HEAD_SERVICE:
{
FileHeader *hd=ShortBlock.HeaderType==HEAD_FILE ? &FileHead:&SubHead;
hd->Reset();
hd->Reset(); // Clear hash, time fields and other stuff like flags.
*(BaseBlock *)hd=ShortBlock;
bool FileBlock=ShortBlock.HeaderType==HEAD_FILE;

View File

@ -56,7 +56,6 @@ void CommandData::ParseCommandLine(bool Preprocess,int argc, char *argv[])
// In Windows we may prefer to implement our own command line parser
// to avoid replacing \" by " in standard parser. Such replacing corrupts
// destination paths like "dest path\" in extraction commands.
// Also our own parser is Unicode compatible.
const wchar *CmdLine=GetCommandLine();
wchar *Par;
@ -288,7 +287,10 @@ void CommandData::ProcessSwitch(const wchar *Switch)
AppendArcNameToPath=APPENDARCNAME_DESTPATH;
else
if (Switch[2]=='1')
AppendArcNameToPath=APPENDARCNAME_OWNDIR;
AppendArcNameToPath=APPENDARCNAME_OWNSUBDIR;
else
if (Switch[2]=='2')
AppendArcNameToPath=APPENDARCNAME_OWNDIR;
break;
#ifndef SFX_MODULE
case 'G':
@ -436,9 +438,9 @@ void CommandData::ProcessSwitch(const wchar *Switch)
wcsncpyz(EmailTo,Switch[4]!=0 ? Switch+4:L"@",ASIZE(EmailTo));
break;
}
if (wcsicomp(Switch+1,L"M")==0)
if (wcsicomp(Switch+1,L"M")==0) // For compatibility with pre-WinRAR 6.0 -im syntax. Replaced with -idv.
{
MoreInfo=true;
VerboseOutput=true;
break;
}
if (wcsicomp(Switch+1,L"NUL")==0)
@ -465,6 +467,12 @@ void CommandData::ProcessSwitch(const wchar *Switch)
case 'P':
DisablePercentage=true;
break;
case 'N':
DisableNames=true;
break;
case 'V':
VerboseOutput=true;
break;
}
break;
}
@ -539,7 +547,6 @@ void CommandData::ProcessSwitch(const wchar *Switch)
case 'D': Type=FILTER_DELTA; break;
case 'A': Type=FILTER_AUDIO; break;
case 'C': Type=FILTER_RGB; break;
case 'I': Type=FILTER_ITANIUM; break;
case 'R': Type=FILTER_ARM; break;
}
if (*Str=='+' || *Str=='-')

View File

@ -11,7 +11,6 @@ enum IS_PROCESS_FILE_FLAGS {IPFF_EXCLUDE_PARENT=1};
class CommandData:public RAROptions
{
private:
void ProcessSwitchesString(const wchar *Str);
void ProcessSwitch(const wchar *Switch);
void BadSwitch(const wchar *Switch);
uint GetExclAttr(const wchar *Str,bool &Dir);
@ -34,6 +33,7 @@ class CommandData:public RAROptions
void ParseEnvVar();
void ReadConfig();
void PreprocessArg(const wchar *Arg);
void ProcessSwitchesString(const wchar *Str);
void OutTitle();
void OutHelp(RAR_EXIT ExitCode);
bool IsSwitch(int Ch);

10
deps/unrar/consio.cpp vendored
View File

@ -164,7 +164,7 @@ static void GetPasswordText(wchar *Str,uint MaxLength)
SetConsoleMode(hConIn,ConInMode);
SetConsoleMode(hConOut,ConOutMode);
#else
char StrA[MAXPASSWORD];
char StrA[MAXPASSWORD*4]; // "*4" for multibyte UTF-8 characters.
#if defined(_EMX) || defined (__VMS)
fgets(StrA,ASIZE(StrA)-1,stdin);
#elif defined(__sun)
@ -248,6 +248,12 @@ bool getwstr(wchar *str,size_t n)
ErrHandler.Exit(RARX_USERBREAK);
}
StrA[ReadSize]=0;
// We expect ANSI encoding here, but "echo text|rar ..." to pipe to RAR,
// such as send passwords, we get OEM encoding by default, unless we
// use "chcp" in console. But we avoid OEM to ANSI conversion,
// because we also want to handle ANSI files redirection correctly,
// like "rar ... < ansifile.txt".
CharToWide(&StrA[0],str,n);
cleandata(&StrA[0],StrA.Size()); // We can use this function to enter passwords.
}
@ -305,7 +311,7 @@ int Ask(const wchar *AskStr)
for (int I=0;I<NumItems;I++)
{
eprintf(I==0 ? (NumItems>4 ? L"\n":L" "):L", ");
eprintf(I==0 ? (NumItems>3 ? L"\n":L" "):L", ");
int KeyPos=ItemKeyPos[I];
for (int J=0;J<KeyPos;J++)
eprintf(L"%c",Item[I][J]);

1
deps/unrar/dll.cpp vendored
View File

@ -474,6 +474,7 @@ static int RarErrorToDll(RAR_EXIT ErrCode)
switch(ErrCode)
{
case RARX_FATAL:
case RARX_READ:
return ERAR_EREAD;
case RARX_CRC:
return ERAR_BAD_DATA;

10
deps/unrar/dll.rc vendored
View File

@ -2,8 +2,8 @@
#include <commctrl.h>
VS_VERSION_INFO VERSIONINFO
FILEVERSION 5, 91, 100, 3470
PRODUCTVERSION 5, 91, 100, 3470
FILEVERSION 6, 1, 100, 3756
PRODUCTVERSION 6, 1, 100, 3756
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
{
@ -14,9 +14,9 @@ FILETYPE VFT_APP
VALUE "CompanyName", "Alexander Roshal\0"
VALUE "ProductName", "RAR decompression library\0"
VALUE "FileDescription", "RAR decompression library\0"
VALUE "FileVersion", "5.91.0\0"
VALUE "ProductVersion", "5.91.0\0"
VALUE "LegalCopyright", "Copyright © Alexander Roshal 1993-2020\0"
VALUE "FileVersion", "6.1.0\0"
VALUE "ProductVersion", "6.1.0\0"
VALUE "LegalCopyright", "Copyright © Alexander Roshal 1993-2021\0"
VALUE "OriginalFilename", "Unrar.dll\0"
}
}

27
deps/unrar/errhnd.cpp vendored
View File

@ -15,6 +15,7 @@ void ErrorHandler::Clean()
UserBreak=false;
MainExit=false;
DisableShutdown=false;
ReadErrIgnoreAll=false;
}
@ -56,24 +57,34 @@ void ErrorHandler::ReadError(const wchar *FileName)
ReadErrorMsg(FileName);
#endif
#if !defined(SILENT) || defined(RARDLL)
Exit(RARX_FATAL);
Exit(RARX_READ);
#endif
}
bool ErrorHandler::AskRepeatRead(const wchar *FileName)
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();
bool Repeat=uiAskRepeatRead(FileName);
if (!Repeat) // Disable shutdown if user pressed Cancel in error dialog.
DisableShutdown=true;
return Repeat;
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
return false;
Ignore=true; // Saving the file part for -y or -inul or "Ignore all" choice.
}
@ -189,7 +200,7 @@ void ErrorHandler::ReadErrorMsg(const wchar *ArcName,const wchar *FileName)
{
uiMsg(UIERROR_FILEREAD,ArcName,FileName);
SysErrMsg();
SetErrorCode(RARX_FATAL);
SetErrorCode(RARX_READ);
}

View File

@ -15,9 +15,11 @@ enum RAR_EXIT // RAR exit code.
RARX_CREATE = 9,
RARX_NOFILES = 10,
RARX_BADPWD = 11,
RARX_READ = 12,
RARX_USERBREAK = 255
};
class ErrorHandler
{
private:
@ -26,6 +28,7 @@ class ErrorHandler
bool EnableBreak;
bool Silent;
bool DisableShutdown; // Shutdown is not suitable after last error.
bool ReadErrIgnoreAll;
public:
ErrorHandler();
void Clean();
@ -33,7 +36,7 @@ class ErrorHandler
void OpenError(const wchar *FileName);
void CloseError(const wchar *FileName);
void ReadError(const wchar *FileName);
bool AskRepeatRead(const wchar *FileName);
void AskRepeatRead(const wchar *FileName,bool &Ignore,bool &Retry,bool &Quit);
void WriteError(const wchar *ArcName,const wchar *FileName);
void WriteErrorFAT(const wchar *FileName);
bool AskRepeatWrite(const wchar *FileName,bool DiskFull);

View File

@ -7,7 +7,7 @@ bool ExtractSymlink(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const wcha
void SetUnixOwner(Archive &Arc,const wchar *FileName);
#endif
bool ExtractHardlink(wchar *NameNew,wchar *NameExisting,size_t NameExistingSize);
bool ExtractHardlink(CommandData *Cmd,wchar *NameNew,wchar *NameExisting,size_t NameExistingSize);
void GetStreamNameNTFS(Archive &Arc,wchar *StreamName,size_t MaxSize);

199
deps/unrar/extract.cpp vendored
View File

@ -42,6 +42,7 @@ void CmdExtract::DoExtract()
Cmd->Password.Clean(); // Clean user entered password before processing next archive.
ReconstructDone=false; // Must be reset here, not in ExtractArchiveInit().
UseExactVolName=false; // Must be reset here, not in ExtractArchiveInit().
while (true)
{
EXTRACT_ARC_CODE Code=ExtractArchive();
@ -140,7 +141,7 @@ EXTRACT_ARC_CODE CmdExtract::ExtractArchive()
return EXTRACT_ARC_NEXT;
#ifndef SFX_MODULE
if (Arc.Volume && !Arc.FirstVolume)
if (Arc.Volume && !Arc.FirstVolume && !UseExactVolName)
{
wchar FirstVolName[NM];
VolNameToFirstName(ArcName,FirstVolName,ASIZE(FirstVolName),Arc.NewNumbering);
@ -158,6 +159,16 @@ EXTRACT_ARC_CODE CmdExtract::ExtractArchive()
if (Arc.Volume)
{
#ifndef SFX_MODULE
// Try to speed up extraction for independent solid volumes by starting
// extraction from non-first volume if we can.
if (!UseExactVolName && Arc.Solid && DetectStartVolume(Arc.FileName,Arc.NewNumbering))
{
UseExactVolName=true;
return EXTRACT_ARC_REPEAT;
}
#endif
// Calculate the total size of all accessible volumes.
// This size is necessary to display the correct total progress indicator.
@ -318,11 +329,11 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
Arc.ConvertAttributes();
#if !defined(SFX_MODULE) && !defined(RARDLL)
if (Arc.FileHead.SplitBefore && FirstFile)
if (Arc.FileHead.SplitBefore && FirstFile && !UseExactVolName)
{
wchar CurVolName[NM];
wcsncpyz(CurVolName,ArcName,ASIZE(CurVolName));
VolNameToFirstName(ArcName,ArcName,ASIZE(ArcName),Arc.NewNumbering);
GetFirstVolIfFullSet(ArcName,Arc.NewNumbering,ArcName,ASIZE(ArcName));
if (wcsicomp(ArcName,CurVolName)!=0 && FileExist(ArcName))
{
@ -575,7 +586,7 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
TotalFileCount++;
}
FileCount++;
if (Command!='I')
if (Command!='I' && !Cmd->DisableNames)
if (SkipSolid)
mprintf(St(MExtrSkipFile),ArcFileName);
else
@ -594,8 +605,10 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
mprintf(St(MExtrFile),DestFileName);
break;
}
if (!Cmd->DisablePercentage)
if (!Cmd->DisablePercentage && !Cmd->DisableNames)
mprintf(L" ");
if (Cmd->DisableNames)
uiEolAfterMsg(); // Avoid erasing preceding messages by percentage indicator in -idn mode.
DataIO.CurUnpRead=0;
DataIO.CurUnpWrite=0;
@ -641,7 +654,7 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
ExtrPrepareName(Arc,Arc.FileHead.RedirName,NameExisting,ASIZE(NameExisting));
if (FileCreateMode && *NameExisting!=0) // *NameExisting can be 0 in case of excessive -ap switch.
if (Type==FSREDIR_HARDLINK)
LinkSuccess=ExtractHardlink(DestFileName,NameExisting,ASIZE(NameExisting));
LinkSuccess=ExtractHardlink(Cmd,DestFileName,NameExisting,ASIZE(NameExisting));
else
LinkSuccess=ExtractFileCopy(CurFile,Arc.FileName,DestFileName,NameExisting,ASIZE(NameExisting));
}
@ -653,7 +666,7 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
}
else
{
uiMsg(UIERROR_UNKNOWNEXTRA, Arc.FileName, DestFileName);
uiMsg(UIERROR_UNKNOWNEXTRA,Arc.FileName,DestFileName);
LinkSuccess=false;
}
@ -711,7 +724,7 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
{
if (ValidCRC)
{
if (Command!='P' && Command!='I')
if (Command!='P' && Command!='I' && !Cmd->DisableNames)
mprintf(L"%s%s ",Cmd->DisablePercentage ? L" ":L"\b\b\b\b\b ",
Arc.FileHead.FileHash.Type==HASH_NONE ? L" ?":St(MOk));
}
@ -734,7 +747,13 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
}
}
else
mprintf(L"\b\b\b\b\b ");
{
// We check SkipSolid to remove percent for skipped solid files only.
// We must not apply these \b to links with ShowChecksum==false
// and their possible error messages.
if (SkipSolid)
mprintf(L"\b\b\b\b\b ");
}
// If we successfully unpacked a hard link, we wish to set its file
// attributes. Hard link shares file metadata with link target,
@ -781,7 +800,13 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
Arc.FileHead.FileAttr&=~FILE_ATTRIBUTE_ARCHIVE;
#endif
if (!Cmd->IgnoreGeneralAttr && !SetFileAttr(DestFileName,Arc.FileHead.FileAttr))
{
uiMsg(UIERROR_FILEATTR,Arc.FileName,DestFileName);
// Android cannot set file attributes and while UIERROR_FILEATTR
// above is handled by Android RAR silently, this call would cause
// "Operation not permitted" message for every unpacked file.
ErrHandler.SysErrMsg();
}
PrevProcessed=true;
}
@ -874,11 +899,21 @@ void CmdExtract::ExtrPrepareName(Archive &Arc,const wchar *ArcFileName,wchar *De
#ifndef SFX_MODULE
if (Cmd->AppendArcNameToPath!=APPENDARCNAME_NONE)
{
if (Cmd->AppendArcNameToPath==APPENDARCNAME_DESTPATH)
wcsncatz(DestName,PointToName(Arc.FirstVolumeName),DestSize);
else
wcsncpyz(DestName,Arc.FirstVolumeName,DestSize); // To archive own dir.
SetExt(DestName,NULL,DestSize);
switch(Cmd->AppendArcNameToPath)
{
case APPENDARCNAME_DESTPATH: // To subdir of destination path.
wcsncatz(DestName,PointToName(Arc.FirstVolumeName),DestSize);
SetExt(DestName,NULL,DestSize);
break;
case APPENDARCNAME_OWNSUBDIR: // To subdir of archive own dir.
wcsncpyz(DestName,Arc.FirstVolumeName,DestSize);
SetExt(DestName,NULL,DestSize);
break;
case APPENDARCNAME_OWNDIR: // To archive own dir.
wcsncpyz(DestName,Arc.FirstVolumeName,DestSize);
RemoveNameFromPath(DestName);
break;
}
AddEndSlash(DestName,DestSize);
}
#endif
@ -1048,8 +1083,11 @@ void CmdExtract::ExtrCreateDir(Archive &Arc,const wchar *ArcFileName)
{
if (Cmd->Test)
{
mprintf(St(MExtrTestFile),ArcFileName);
mprintf(L" %s",St(MOk));
if (!Cmd->DisableNames)
{
mprintf(St(MExtrTestFile),ArcFileName);
mprintf(L" %s",St(MOk));
}
return;
}
@ -1068,26 +1106,33 @@ void CmdExtract::ExtrCreateDir(Archive &Arc,const wchar *ArcFileName)
}
if (!DirExist)
{
CreatePath(DestFileName,true);
CreatePath(DestFileName,true,Cmd->DisableNames);
MDCode=MakeDir(DestFileName,!Cmd->IgnoreGeneralAttr,Arc.FileHead.FileAttr);
if (MDCode!=MKDIR_SUCCESS)
if (MDCode!=MKDIR_SUCCESS && !IsNameUsable(DestFileName))
{
uiMsg(UIMSG_CORRECTINGNAME,Arc.FileName);
wchar OrigName[ASIZE(DestFileName)];
wcsncpyz(OrigName,DestFileName,ASIZE(OrigName));
MakeNameUsable(DestFileName,true);
CreatePath(DestFileName,true);
MDCode=MakeDir(DestFileName,!Cmd->IgnoreGeneralAttr,Arc.FileHead.FileAttr);
#ifndef SFX_MODULE
if (MDCode==MKDIR_SUCCESS)
uiMsg(UIERROR_RENAMING,Arc.FileName,OrigName,DestFileName);
uiMsg(UIERROR_RENAMING,Arc.FileName,OrigName,DestFileName);
#endif
DirExist=FileExist(DestFileName) && IsDir(GetFileAttr(DestFileName));
if (!DirExist)
{
CreatePath(DestFileName,true,Cmd->DisableNames);
MDCode=MakeDir(DestFileName,!Cmd->IgnoreGeneralAttr,Arc.FileHead.FileAttr);
}
}
}
}
if (MDCode==MKDIR_SUCCESS)
{
mprintf(St(MCreatDir),DestFileName);
mprintf(L" %s",St(MOk));
if (!Cmd->DisableNames)
{
mprintf(St(MCreatDir),DestFileName);
mprintf(L" %s",St(MOk));
}
PrevProcessed=true;
}
else
@ -1141,6 +1186,9 @@ bool CmdExtract::ExtrCreateFile(Archive &Arc,File &CurFile)
if (!UserReject)
{
ErrHandler.CreateErrorMsg(Arc.FileName,DestFileName);
if (FileExist(DestFileName) && IsDir(GetFileAttr(DestFileName)))
uiMsg(UIERROR_DIRNAMEEXISTS);
#ifdef RARDLL
Cmd->DllError=ERAR_ECREATE;
#endif
@ -1153,7 +1201,7 @@ bool CmdExtract::ExtrCreateFile(Archive &Arc,File &CurFile)
MakeNameUsable(DestFileName,true);
CreatePath(DestFileName,true);
CreatePath(DestFileName,true,Cmd->DisableNames);
if (FileCreate(Cmd,&CurFile,DestFileName,ASIZE(DestFileName),&UserReject,Arc.FileHead.UnpSize,&Arc.FileHead.mtime,true))
{
#ifndef SFX_MODULE
@ -1196,3 +1244,104 @@ bool CmdExtract::CheckUnpVer(Archive &Arc,const wchar *ArcFileName)
}
return !WrongVer;
}
#ifndef SFX_MODULE
// To speed up solid volumes extraction, try to find a non-first start volume,
// which still allows to unpack all files. It is possible for independent
// solid volumes with solid statistics reset in the beginning.
bool CmdExtract::DetectStartVolume(const wchar *VolName,bool NewNumbering)
{
wchar *ArgName=Cmd->FileArgs.GetString();
Cmd->FileArgs.Rewind();
if (ArgName!=NULL && (wcscmp(ArgName,L"*")==0 || wcscmp(ArgName,L"*.*")==0))
return false; // No need to check further for * and *.* masks.
wchar StartName[NM];
*StartName=0;
// Start search from first volume if all volumes preceding current are available.
wchar NextName[NM];
GetFirstVolIfFullSet(VolName,NewNumbering,NextName,ASIZE(NextName));
bool Matched=false;
while (!Matched)
{
Archive Arc(Cmd);
if (!Arc.Open(NextName) || !Arc.IsArchive(false) || !Arc.Volume)
break;
bool OpenNext=false;
while (Arc.ReadHeader()>0)
{
Wait();
HEADER_TYPE HeaderType=Arc.GetHeaderType();
if (HeaderType==HEAD_ENDARC)
{
OpenNext|=Arc.EndArcHead.NextVolume; // Allow open next volume.
break;
}
if (HeaderType==HEAD_FILE)
{
if (!Arc.FileHead.SplitBefore)
{
if (!Arc.FileHead.Solid) // Can start extraction from here.
wcsncpyz(StartName,NextName,ASIZE(StartName));
if (Cmd->IsProcessFile(Arc.FileHead,NULL,MATCH_WILDSUBPATH,0,NULL,0)!=0)
{
Matched=true; // First matched file found, must stop further scan.
break;
}
}
if (Arc.FileHead.SplitAfter)
{
OpenNext=true; // Allow open next volume.
break;
}
}
Arc.SeekToNext();
}
Arc.Close();
if (!OpenNext)
break;
NextVolumeName(NextName,ASIZE(NextName),!Arc.NewNumbering);
}
bool NewStartFound=wcscmp(VolName,StartName)!=0;
if (NewStartFound) // Found a new volume to start extraction.
wcsncpyz(ArcName,StartName,ASIZE(ArcName));
return NewStartFound;
}
#endif
#ifndef SFX_MODULE
// Return the first volume name if all volumes preceding the specified
// are available. Otherwise return the specified volume name.
void CmdExtract::GetFirstVolIfFullSet(const wchar *SrcName,bool NewNumbering,wchar *DestName,size_t DestSize)
{
wchar FirstVolName[NM];
VolNameToFirstName(SrcName,FirstVolName,ASIZE(FirstVolName),NewNumbering);
wchar NextName[NM];
wcsncpyz(NextName,FirstVolName,ASIZE(NextName));
wchar ResultName[NM];
wcsncpyz(ResultName,SrcName,ASIZE(ResultName));
while (true)
{
if (wcscmp(SrcName,NextName)==0)
{
wcsncpyz(ResultName,FirstVolName,DestSize);
break;
}
if (!FileExist(NextName))
break;
NextVolumeName(NextName,ASIZE(NextName),!NewNumbering);
}
wcsncpyz(DestName,ResultName,DestSize);
}
#endif

View File

@ -20,8 +20,12 @@ class CmdExtract
void ExtrCreateDir(Archive &Arc,const wchar *ArcFileName);
bool ExtrCreateFile(Archive &Arc,File &CurFile);
bool CheckUnpVer(Archive &Arc,const wchar *ArcFileName);
#ifndef SFX_MODULE
bool DetectStartVolume(const wchar *VolName,bool NewNumbering);
void GetFirstVolIfFullSet(const wchar *SrcName,bool NewNumbering,wchar *DestName,size_t DestSize);
#endif
RarTime StartTime; // time when extraction started
RarTime StartTime; // Time when extraction started.
CommandData *Cmd;
@ -34,6 +38,7 @@ class CmdExtract
bool FirstFile;
bool AllMatchesExact;
bool ReconstructDone;
bool UseExactVolName;
// If any non-zero solid file was successfully unpacked before current.
// If true and if current encrypted file is broken, obviously

View File

@ -49,7 +49,7 @@ bool FileCreate(RAROptions *Cmd,File *NewFile,wchar *Name,size_t MaxNameSize,
if (NewFile!=NULL && NewFile->Create(Name,FileMode))
return true;
CreatePath(Name,true);
CreatePath(Name,true,Cmd->DisableNames);
return NewFile!=NULL ? NewFile->Create(Name,FileMode):DelFile(Name);
}

28
deps/unrar/file.cpp vendored
View File

@ -8,7 +8,6 @@ File::File()
LastWrite=false;
HandleType=FILE_HANDLENORMAL;
SkipClose=false;
IgnoreReadErrors=false;
ErrorType=FILE_SUCCESS;
OpenShared=false;
AllowDelete=true;
@ -18,6 +17,8 @@ File::File()
NoSequentialRead=false;
CreateMode=FMF_UNDEFINED;
#endif
ReadErrorMode=FREM_ASK;
TruncatedAfterReadError=false;
}
@ -37,6 +38,7 @@ void File::operator = (File &SrcFile)
NewFile=SrcFile.NewFile;
LastWrite=SrcFile.LastWrite;
HandleType=SrcFile.HandleType;
TruncatedAfterReadError=SrcFile.TruncatedAfterReadError;
wcsncpyz(FileName,SrcFile.FileName,ASIZE(FileName));
SrcFile.SkipClose=true;
}
@ -118,12 +120,12 @@ bool File::Open(const wchar *Name,uint Mode)
#ifdef _OSF_SOURCE
extern "C" int flock(int, int);
#endif
if (!OpenShared && UpdateMode && handle>=0 && flock(handle,LOCK_EX|LOCK_NB)==-1)
{
close(handle);
return false;
}
#endif
if (handle==-1)
hNewFile=FILE_BAD_HANDLE;
@ -146,6 +148,7 @@ bool File::Open(const wchar *Name,uint Mode)
{
hFile=hNewFile;
wcsncpyz(FileName,Name,ASIZE(FileName));
TruncatedAfterReadError=false;
}
return Success;
}
@ -369,9 +372,12 @@ bool File::Write(const void *Data,size_t Size)
int File::Read(void *Data,size_t Size)
{
if (TruncatedAfterReadError)
return 0;
int64 FilePos=0; // Initialized only to suppress some compilers warning.
if (IgnoreReadErrors)
if (ReadErrorMode==FREM_IGNORE)
FilePos=Tell();
int ReadSize;
while (true)
@ -381,7 +387,7 @@ int File::Read(void *Data,size_t Size)
{
ErrorType=FILE_READERROR;
if (AllowExceptions)
if (IgnoreReadErrors)
if (ReadErrorMode==FREM_IGNORE)
{
ReadSize=0;
for (size_t I=0;I<Size;I+=512)
@ -394,8 +400,18 @@ int File::Read(void *Data,size_t Size)
}
else
{
if (HandleType==FILE_HANDLENORMAL && ErrHandler.AskRepeatRead(FileName))
continue;
bool Ignore=false,Retry=false,Quit=false;
if (ReadErrorMode==FREM_ASK && HandleType==FILE_HANDLENORMAL)
{
ErrHandler.AskRepeatRead(FileName,Ignore,Retry,Quit);
if (Retry)
continue;
}
if (Ignore || ReadErrorMode==FREM_TRUNCATE)
{
TruncatedAfterReadError=true;
return 0;
}
ErrHandler.ReadError(FileName);
}
}

12
deps/unrar/file.hpp vendored
View File

@ -46,6 +46,12 @@ enum FILE_MODE_FLAGS {
FMF_UNDEFINED=256
};
enum FILE_READ_ERROR_MODE {
FREM_ASK, // Propose to use the already read part, retry or abort.
FREM_TRUNCATE, // Use the already read part without additional prompt.
FREM_IGNORE // Try to skip unreadable block and read further.
};
class File
{
@ -54,7 +60,7 @@ class File
bool LastWrite;
FILE_HANDLETYPE HandleType;
bool SkipClose;
bool IgnoreReadErrors;
FILE_READ_ERROR_MODE ReadErrorMode;
bool NewFile;
bool AllowDelete;
bool AllowExceptions;
@ -63,6 +69,7 @@ class File
uint CreateMode;
#endif
bool PreserveAtime;
bool TruncatedAfterReadError;
protected:
bool OpenShared; // Set by 'Archive' class.
public:
@ -108,7 +115,7 @@ class File
static bool RemoveCreated();
FileHandle GetHandle() {return hFile;}
void SetHandle(FileHandle Handle) {Close();hFile=Handle;}
void SetIgnoreReadErrors(bool Mode) {IgnoreReadErrors=Mode;}
void SetReadErrorMode(FILE_READ_ERROR_MODE Mode) {ReadErrorMode=Mode;}
int64 Copy(File &Dest,int64 Length=INT64NDF);
void SetAllowDelete(bool Allow) {AllowDelete=Allow;}
void SetExceptions(bool Allow) {AllowExceptions=Allow;}
@ -116,6 +123,7 @@ class File
void RemoveSequentialFlag() {NoSequentialRead=true;}
#endif
void SetPreserveAtime(bool Preserve) {PreserveAtime=Preserve;}
bool IsTruncatedAfterReadError() {return TruncatedAfterReadError;}
#ifdef _UNIX
int GetFD()
{

22
deps/unrar/filefn.cpp vendored
View File

@ -38,7 +38,7 @@ MKDIR_CODE MakeDir(const wchar *Name,bool SetAttr,uint Attr)
}
bool CreatePath(const wchar *Path,bool SkipLastName)
bool CreatePath(const wchar *Path,bool SkipLastName,bool Silent)
{
if (Path==NULL || *Path==0)
return false;
@ -73,7 +73,7 @@ bool CreatePath(const wchar *Path,bool SkipLastName)
DirName[s-Path]=0;
Success=MakeDir(DirName,true,DirAttr)==MKDIR_SUCCESS;
if (Success)
if (Success && !Silent)
{
mprintf(St(MCreatDir),DirName);
mprintf(L" %s",St(MOk));
@ -474,6 +474,24 @@ bool DelFile(const wchar *Name)
}
bool DelDir(const wchar *Name)
{
#ifdef _WIN_ALL
bool Success=RemoveDirectory(Name)!=0;
if (!Success)
{
wchar LongName[NM];
if (GetWinLongPath(Name,LongName,ASIZE(LongName)))
Success=RemoveDirectory(LongName)!=0;
}
return Success;
#else
char NameA[NM];
WideToChar(Name,NameA,ASIZE(NameA));
bool Success=rmdir(NameA)==0;
return Success;
#endif
}
#if defined(_WIN_ALL) && !defined(SFX_MODULE)

View File

@ -4,7 +4,7 @@
enum MKDIR_CODE {MKDIR_SUCCESS,MKDIR_ERROR,MKDIR_BADPATH};
MKDIR_CODE MakeDir(const wchar *Name,bool SetAttr,uint Attr);
bool CreatePath(const wchar *Path,bool SkipLastName);
bool CreatePath(const wchar *Path,bool SkipLastName,bool Silent);
void SetDirTime(const wchar *Name,RarTime *ftm,RarTime *ftc,RarTime *fta);
bool IsRemovable(const wchar *Name);

View File

@ -1,4 +1,4 @@
bool ExtractHardlink(wchar *NameNew,wchar *NameExisting,size_t NameExistingSize)
bool ExtractHardlink(CommandData *Cmd,wchar *NameNew,wchar *NameExisting,size_t NameExistingSize)
{
SlashToNative(NameExisting,NameExisting,NameExistingSize); // Not needed for RAR 5.1+ archives.
@ -9,7 +9,7 @@ bool ExtractHardlink(wchar *NameNew,wchar *NameExisting,size_t NameExistingSize)
ErrHandler.SetErrorCode(RARX_CREATE);
return false;
}
CreatePath(NameNew,true);
CreatePath(NameNew,true,Cmd->DisableNames);
#ifdef _WIN_ALL
bool Success=CreateHardLink(NameNew,NameExisting,NULL)!=0;

4
deps/unrar/list.cpp vendored
View File

@ -28,7 +28,7 @@ void ListArchive(CommandData *Cmd)
if (!Arc.WOpen(ArcName))
continue;
bool FileMatched=true;
while (1)
while (true)
{
int64 TotalPackSize=0,TotalUnpSize=0;
uint FileCount=0;
@ -69,7 +69,7 @@ void ListArchive(CommandData *Cmd)
wchar VolNumText[50];
*VolNumText=0;
while(Arc.ReadHeader()>0)
while (Arc.ReadHeader()>0)
{
Wait(); // Allow quit listing with Ctrl+C.
HEADER_TYPE HeaderType=Arc.GetHeaderType();

View File

@ -4,6 +4,7 @@
#define MYesNoAllRenQ L"_Yes_No_All_nEver_Rename_Quit"
#define MContinueQuit L"_Continue_Quit"
#define MRetryAbort L"_Retry_Abort"
#define MIgnoreAllRetryQuit L"_Ignore_iGnore all_Retry_Quit"
#define MCopyright L"\nRAR %s Copyright (c) 1993-%d Alexander Roshal %d %s %d"
#define MRegTo L"\nRegistered to %s\n"
#define MShare L"\nTrial version Type 'rar -?' for help\n"
@ -54,7 +55,7 @@
#define MCHelpSwm L"\n - Stop switches scanning"
#define MCHelpSwAT L"\n @[+] Disable [enable] file lists"
#define MCHelpSwAC L"\n ac Clear Archive attribute after compression or extraction"
#define MCHelpSwAD L"\n ad Append archive name to destination path"
#define MCHelpSwAD L"\n ad[1,2] Alternate destination path"
#define MCHelpSwAG L"\n ag[format] Generate archive name using the current date"
#define MCHelpSwAI L"\n ai Ignore file attributes"
#define MCHelpSwAO L"\n ao Add files with Archive attribute set"
@ -79,7 +80,7 @@
#define MCHelpSwF L"\n f Freshen files"
#define MCHelpSwHP L"\n hp[password] Encrypt both file data and headers"
#define MCHelpSwHT L"\n ht[b|c] Select hash type [BLAKE2,CRC32] for file checksum"
#define MCHelpSwIDP L"\n id[c,d,p,q] Disable messages"
#define MCHelpSwIDP L"\n id[c,d,n,p,q] Display or disable messages"
#define MCHelpSwIEML L"\n ieml[addr] Send archive by email"
#define MCHelpSwIERR L"\n ierr Send all messages to stderr"
#define MCHelpSwILOG L"\n ilog[name] Log errors to file"
@ -320,7 +321,7 @@
#define MStreamUnknown L"\nWARNING: Unknown format of %s stream data\n"
#define MInvalidName L"\nERROR: Invalid file name %s"
#define MProcessArc L"\n\nProcessing archive %s"
#define MCorrectingName L"\nWARNING: Attempting to correct the invalid file name"
#define MCorrectingName L"\nWARNING: Attempting to correct the invalid file or directory name"
#define MUnpCannotMerge L"\nWARNING: You need to start extraction from a previous volume to unpack %s"
#define MUnknownOption L"\nERROR: Unknown option: %s"
#define MSubHeadCorrupt L"\nERROR: Corrupt data header found, ignored"
@ -351,7 +352,7 @@
#define MRecVolLimit L"\nTotal number of usual and recovery volumes must not exceed %d"
#define MVolumeNumber L"volume %d"
#define MCannotDelete L"\nCannot delete %s"
#define MRecycleFailed L"\nCannot move some files and folders to Recycle Bin"
#define MRecycleFailed L"\nCannot move some files and directories to Recycle Bin"
#define MCalcCRC L"\nCalculating the checksum"
#define MTooLargeSFXArc L"\nToo large SFX archive. Windows cannot run the executable file exceeding 4 GB."
#define MCalcCRCAllVol L"\nCalculating checksums of all volumes."
@ -380,3 +381,7 @@
#define MDictOutMem L"\nNot enough memory for %d MB compression dictionary, changed to %d MB."
#define MUseSmalllerDict L"\nPlease use a smaller compression dictionary."
#define MOpenErrAtime L"\nYou may need to remove -tsp switch to open this file."
#define MErrReadInfo L"\nChoose 'Ignore' to continue with the already read file part only, 'Ignore all' to do it for all read errors, 'Retry' to repeat read and 'Quit' to abort."
#define MErrReadTrunc L"\n%s is archived incompletely because of read error.\n"
#define MErrReadCount L"\n%u files are archived incompletely because of read errors."
#define MDirNameExists L"\nDirectory with such name already exists"

View File

@ -61,7 +61,8 @@ enum SAVECOPY_MODE {
enum APPENDARCNAME_MODE
{
APPENDARCNAME_NONE=0,APPENDARCNAME_DESTPATH,APPENDARCNAME_OWNDIR
APPENDARCNAME_NONE=0,APPENDARCNAME_DESTPATH,APPENDARCNAME_OWNSUBDIR,
APPENDARCNAME_OWNDIR
};
enum POWER_MODE {
@ -132,6 +133,7 @@ class RAROptions
bool DisablePercentage;
bool DisableCopyright;
bool DisableDone;
bool DisableNames;
bool PrintVersion;
int Solid;
int SolidCount;
@ -146,7 +148,7 @@ class RAROptions
Array<int64> NextVolSizes;
uint CurVolNum;
bool AllYes;
bool MoreInfo; // -im, show more information, used only in "WinRAR t" now.
bool VerboseOutput; // -iv, display verbose output, used only in "WinRAR t" now.
bool DisableSortSolid;
int ArcTime;
int ConvertNames;

View File

@ -655,7 +655,7 @@ wchar* VolNameToFirstName(const wchar *VolName,wchar *FirstName,size_t MaxSize,b
}
if (!FileExist(FirstName))
{
// If the first volume, which name we just generated, is not exist,
// If the first volume, which name we just generated, does not exist,
// check if volume with same name and any other extension is available.
// It can help in case of *.exe or *.sfx first volume.
wchar Mask[NM];

View File

@ -51,7 +51,7 @@ class CryptLoader
};
// We need to call FreeLibrary when RAR is exiting.
CryptLoader GlobalCryptLoader;
static CryptLoader GlobalCryptLoader;
#endif
SecPassword::SecPassword()

9
deps/unrar/ui.hpp vendored
View File

@ -38,7 +38,8 @@ enum UIMESSAGE_CODE {
UIERROR_PATHTOOLONG, UIERROR_DIRSCAN, UIERROR_UOWNERGET,
UIERROR_UOWNERBROKEN, UIERROR_UOWNERGETOWNERID, UIERROR_UOWNERGETGROUPID,
UIERROR_UOWNERSET, UIERROR_ULINKREAD, UIERROR_ULINKEXIST,
UIERROR_OPENPRESERVEATIME,
UIERROR_OPENPRESERVEATIME, UIERROR_READERRTRUNCATED, UIERROR_READERRCOUNT,
UIERROR_DIRNAMEEXISTS,
UIMSG_FIRST,
UIMSG_STRING, UIMSG_BUILD, UIMSG_RRSEARCH, UIMSG_ANALYZEFILEDATA,
@ -92,16 +93,18 @@ bool uiIsGlobalPasswordSet();
enum UIALARM_TYPE {UIALARM_ERROR, UIALARM_INFO, UIALARM_QUESTION};
void uiAlarm(UIALARM_TYPE Type);
void uiEolAfterMsg();
bool uiAskNextVolume(wchar *VolName,size_t MaxSize);
bool uiAskRepeatRead(const wchar *FileName);
#if !defined(SILENT) && !defined(SFX_MODULE)
void uiAskRepeatRead(const wchar *FileName,bool &Ignore,bool &All,bool &Retry,bool &Quit);
#endif
bool uiAskRepeatWrite(const wchar *FileName,bool DiskFull);
#ifndef SFX_MODULE
const wchar *uiGetMonthName(int Month);
#endif
class uiMsgStore
{
private:

View File

@ -1,3 +1,5 @@
static bool AnyMessageDisplayed=false; // For console -idn switch.
// Purely user interface function. Gets and returns user input.
UIASKREP_RESULT uiAskReplace(wchar *Name,size_t MaxNameSize,int64 FileSize,RarTime *FileTime,uint Flags)
{
@ -83,6 +85,19 @@ void uiProcessProgress(const char *Command,int64 CurSize,int64 TotalSize)
void uiMsgStore::Msg()
{
// When creating volumes, AnyMessageDisplayed must be reset for UIEVENT_NEWARCHIVE,
// so it ignores this and all earlier messages like UIEVENT_PROTECTEND
// and UIEVENT_PROTECTEND, because they precede "Creating archive" message
// and do not interfere with -idn and file names. If we do not ignore them,
// uiEolAfterMsg() in uiStartFileAddit() can cause unneeded carriage return
// in archiving percent after creating a new volume with -v -idn (and -rr
// for UIEVENT_PROTECT*) switches. AnyMessageDisplayed is set for messages
// after UIEVENT_NEWARCHIVE, so archiving percent with -idn is moved to
// next line and does not delete their last characters.
// Similarly we ignore UIEVENT_RRTESTINGEND for volumes, because it is issued
// before "Testing archive" and would add an excessive \n otherwise.
AnyMessageDisplayed=(Code!=UIEVENT_NEWARCHIVE && Code!=UIEVENT_RRTESTINGEND);
switch(Code)
{
case UIERROR_SYSERRMSG:
@ -121,6 +136,7 @@ void uiMsgStore::Msg()
Log(NULL,St(MErrSeek),Str[0]);
break;
case UIERROR_FILEREAD:
mprintf(L"\n");
Log(Str[0],St(MErrRead),Str[1]);
break;
case UIERROR_FILEWRITE:
@ -304,7 +320,15 @@ void uiMsgStore::Msg()
case UIERROR_ULINKEXIST:
Log(NULL,St(MSymLinkExists),Str[0]);
break;
case UIERROR_READERRTRUNCATED:
Log(NULL,St(MErrReadTrunc),Str[0]);
break;
case UIERROR_READERRCOUNT:
Log(NULL,St(MErrReadCount),Num[0]);
break;
case UIERROR_DIRNAMEEXISTS:
Log(NULL,St(MDirNameExists));
break;
#ifndef SFX_MODULE
case UIMSG_STRING:
@ -397,11 +421,15 @@ bool uiAskNextVolume(wchar *VolName,size_t MaxSize)
}
bool uiAskRepeatRead(const wchar *FileName)
void uiAskRepeatRead(const wchar *FileName,bool &Ignore,bool &All,bool &Retry,bool &Quit)
{
mprintf(L"\n");
Log(NULL,St(MErrRead),FileName);
return Ask(St(MRetryAbort))==1;
eprintf(St(MErrReadInfo));
int Code=Ask(St(MIgnoreAllRetryQuit));
Ignore=(Code==1);
All=(Code==2);
Quit=(Code==4);
Retry=!Ignore && !All && !Quit; // Default also for invalid input, not just for 'Retry'.
}
@ -423,3 +451,15 @@ const wchar *uiGetMonthName(int Month)
return St(MonthID[Month]);
}
#endif
void uiEolAfterMsg()
{
if (AnyMessageDisplayed)
{
// Avoid deleting several last characters of any previous error message
// with percentage indicator in -idn mode.
AnyMessageDisplayed=false;
mprintf(L"\n");
}
}

View File

@ -67,3 +67,8 @@ const wchar *uiGetMonthName(int Month)
return L"";
}
#endif
void uiEolAfterMsg()
{
}

13
deps/unrar/ulinks.cpp vendored
View File

@ -1,9 +1,14 @@
static bool UnixSymlink(const char *Target,const wchar *LinkName,RarTime *ftm,RarTime *fta)
static bool UnixSymlink(CommandData *Cmd,const char *Target,const wchar *LinkName,RarTime *ftm,RarTime *fta)
{
CreatePath(LinkName,true);
CreatePath(LinkName,true,Cmd->DisableNames);
// Overwrite prompt was already issued and confirmed earlier, so we can
// remove existing symlink or regular file here. PrepareToDelete was also
// called earlier inside of uiAskReplaceEx.
DelFile(LinkName);
char LinkNameA[NM];
WideToChar(LinkName,LinkNameA,ASIZE(LinkNameA));
if (symlink(Target,LinkNameA)==-1) // Error.
@ -75,7 +80,7 @@ bool ExtractUnixLink30(CommandData *Cmd,ComprDataIO &DataIO,Archive &Arc,const w
if (!Cmd->AbsoluteLinks && (*TargetW==0 || IsFullPath(TargetW) ||
!IsRelativeSymlinkSafe(Cmd,Arc.FileHead.FileName,LinkName,TargetW)))
return false;
return UnixSymlink(Target,LinkName,&Arc.FileHead.mtime,&Arc.FileHead.atime);
return UnixSymlink(Cmd,Target,LinkName,&Arc.FileHead.mtime,&Arc.FileHead.atime);
}
return false;
}
@ -101,5 +106,5 @@ bool ExtractUnixLink50(CommandData *Cmd,const wchar *Name,FileHeader *hd)
if (!Cmd->AbsoluteLinks && (IsFullPath(Target) ||
!IsRelativeSymlinkSafe(Cmd,hd->FileName,Name,hd->RedirName)))
return false;
return UnixSymlink(Target,Name,&hd->mtime,&hd->atime);
return UnixSymlink(Cmd,Target,Name,&hd->mtime,&hd->atime);
}

View File

@ -471,6 +471,7 @@ int wcsnicomp(const wchar *s1,const wchar *s2,size_t n)
}
// Case insensitive wcsstr().
const wchar_t* wcscasestr(const wchar_t *str, const wchar_t *search)
{
for (size_t i=0;str[i]!=0;i++)

View File

@ -1,6 +1,6 @@
#define RARVER_MAJOR 5
#define RARVER_MINOR 91
#define RARVER_MAJOR 6
#define RARVER_MINOR 1
#define RARVER_BETA 0
#define RARVER_DAY 25
#define RARVER_MONTH 6
#define RARVER_YEAR 2020
#define RARVER_DAY 7
#define RARVER_MONTH 4
#define RARVER_YEAR 2021

View File

@ -136,7 +136,7 @@ bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,wchar Comma
Arc.ConvertAttributes();
Arc.Seek(Arc.NextBlockPos-Arc.FileHead.PackSize,SEEK_SET);
}
if (ShowFileName)
if (ShowFileName && !Cmd->DisableNames)
{
mprintf(St(MExtrPoints),Arc.FileHead.FileName);
if (!Cmd->DisablePercentage)

View File

@ -71,20 +71,36 @@ bool CreateReparsePoint(CommandData *Cmd,const wchar *Name,FileHeader *hd)
!IsRelativeSymlinkSafe(Cmd,hd->FileName,Name,hd->RedirName)))
return false;
CreatePath(Name,true);
CreatePath(Name,true,Cmd->DisableNames);
// Overwrite prompt was already issued and confirmed earlier, so we can
// remove existing symlink or regular file here. PrepareToDelete was also
// called earlier inside of uiAskReplaceEx.
if (FileExist(Name))
if (IsDir(GetFileAttr(Name)))
DelDir(Name);
else
DelFile(Name);
// 'DirTarget' check is important for Unix symlinks to directories.
// Unix symlinks do not have their own 'directory' attribute.
if (hd->Dir || hd->DirTarget)
{
if (!CreateDirectory(Name,NULL))
{
uiMsg(UIERROR_DIRCREATE,UINULL,Name);
ErrHandler.SetErrorCode(RARX_CREATE);
return false;
}
}
else
{
HANDLE hFile=CreateFile(Name,GENERIC_WRITE,0,NULL,CREATE_NEW,FILE_ATTRIBUTE_NORMAL,NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
ErrHandler.CreateErrorMsg(Name);
return false;
}
CloseHandle(hFile);
}
@ -138,7 +154,11 @@ bool CreateReparsePoint(CommandData *Cmd,const wchar *Name,FileHeader *hd)
OPEN_EXISTING,FILE_FLAG_OPEN_REPARSE_POINT|
FILE_FLAG_BACKUP_SEMANTICS,NULL);
if (hFile==INVALID_HANDLE_VALUE)
{
ErrHandler.CreateErrorMsg(Name);
ErrHandler.SetErrorCode(RARX_CREATE);
return false;
}
DWORD Returned;
if (!DeviceIoControl(hFile,FSCTL_SET_REPARSE_POINT,rdb,

View File

@ -4,6 +4,7 @@
## Technical
##
- Dependencies: Updated unrar source from 5.9.4 to 6.0.5
- Dependencies: Make unrar dependencies optional and disable hash-mode 23800 if dependency is disabled
* changes v6.1.1 -> v6.2.0