Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/mpc-hc.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUnderground78 <underground78@users.sourceforge.net>2015-01-25 15:47:48 +0300
committerUnderground78 <underground78@users.sourceforge.net>2015-01-25 15:47:48 +0300
commit6fcba1bead7608fb480ab943ab9689bc66f4e009 (patch)
treeef5a968e7749e8f80f310fd44a43fc5b1d394193 /src/thirdparty/unrar
parent46ce9d630e7891230c9648afb0c17088681573e6 (diff)
parent013ebae50427b2e985939439202e206373ed5aee (diff)
Merge branch 'release-1.7.8'1.7.8
Diffstat (limited to 'src/thirdparty/unrar')
-rw-r--r--src/thirdparty/unrar/arcread.cpp3
-rw-r--r--src/thirdparty/unrar/cmddata.cpp59
-rw-r--r--src/thirdparty/unrar/cmddata.hpp2
-rw-r--r--src/thirdparty/unrar/crypt.cpp9
-rw-r--r--src/thirdparty/unrar/crypt.hpp39
-rw-r--r--src/thirdparty/unrar/crypt3.cpp47
-rw-r--r--src/thirdparty/unrar/crypt5.cpp12
-rw-r--r--src/thirdparty/unrar/dll.rc8
-rw-r--r--src/thirdparty/unrar/extract.cpp72
-rw-r--r--src/thirdparty/unrar/extract.hpp4
-rw-r--r--src/thirdparty/unrar/file.cpp59
-rw-r--r--src/thirdparty/unrar/file.hpp13
-rw-r--r--src/thirdparty/unrar/filefn.cpp42
-rw-r--r--src/thirdparty/unrar/filefn.hpp3
-rw-r--r--src/thirdparty/unrar/filestr.cpp10
-rw-r--r--src/thirdparty/unrar/list.cpp7
-rw-r--r--src/thirdparty/unrar/loclang.hpp3
-rw-r--r--src/thirdparty/unrar/options.hpp3
-rw-r--r--src/thirdparty/unrar/pathfn.cpp19
-rw-r--r--src/thirdparty/unrar/pathfn.hpp5
-rw-r--r--src/thirdparty/unrar/secpassword.cpp13
-rw-r--r--src/thirdparty/unrar/secpassword.hpp6
-rw-r--r--src/thirdparty/unrar/smallfn.cpp6
-rw-r--r--src/thirdparty/unrar/strfn.cpp10
-rw-r--r--src/thirdparty/unrar/threadmisc.cpp20
-rw-r--r--src/thirdparty/unrar/timefn.hpp1
-rw-r--r--src/thirdparty/unrar/ui.hpp7
-rw-r--r--src/thirdparty/unrar/uiconsole.cpp21
-rw-r--r--src/thirdparty/unrar/unicode.cpp31
-rw-r--r--src/thirdparty/unrar/unicode.hpp4
-rw-r--r--src/thirdparty/unrar/unrar.vcxproj14
-rw-r--r--src/thirdparty/unrar/version.hpp8
32 files changed, 359 insertions, 201 deletions
diff --git a/src/thirdparty/unrar/arcread.cpp b/src/thirdparty/unrar/arcread.cpp
index 5b70988ea..e4c3f87d5 100644
--- a/src/thirdparty/unrar/arcread.cpp
+++ b/src/thirdparty/unrar/arcread.cpp
@@ -811,7 +811,7 @@ size_t Archive::ReadHeader50()
Raw.GetB((byte *)FileName,ReadNameSize);
FileName[ReadNameSize]=0;
- UtfToWide(FileName,hd->FileName,ASIZE(hd->FileName)-1);
+ UtfToWide(FileName,hd->FileName,ASIZE(hd->FileName));
// Should do it before converting names, because extra fields can
// affect name processing, like in case of NTFS streams.
@@ -893,6 +893,7 @@ void Archive::RequestArcPassword()
ErrHandler.Exit(RARX_USERBREAK);
}
#endif
+ Cmd->ManualPassword=true;
}
}
#endif
diff --git a/src/thirdparty/unrar/cmddata.cpp b/src/thirdparty/unrar/cmddata.cpp
index f2374f146..b56410ae9 100644
--- a/src/thirdparty/unrar/cmddata.cpp
+++ b/src/thirdparty/unrar/cmddata.cpp
@@ -13,7 +13,6 @@ void CommandData::Init()
*Command=0;
*ArcName=0;
FileLists=false;
- NoMoreSwitches=false;
ListMode=RCLM_AUTO;
@@ -47,6 +46,8 @@ static const wchar *AllocCmdParam(const wchar *CmdLine,wchar **Par)
#if !defined(SFX_MODULE) && !defined(_ANDROID)
void CommandData::ParseCommandLine(bool Preprocess,int argc, char *argv[])
{
+ *Command=0;
+ NoMoreSwitches=false;
#ifdef CUSTOM_CMDLINE_PARSER
// In Windows we may prefer to implement our own command line parser
// to avoid replacing \" by " in standard parser. Such replacing corrupts
@@ -58,15 +59,12 @@ void CommandData::ParseCommandLine(bool Preprocess,int argc, char *argv[])
{
if ((CmdLine=AllocCmdParam(CmdLine,&Par))==NULL)
break;
- bool Code=true;
if (!FirstParam) // First parameter is the executable name.
if (Preprocess)
- Code=PreprocessSwitch(Par);
+ PreprocessArg(Par);
else
ParseArg(Par);
free(Par);
- if (Preprocess && !Code)
- break;
}
#else
Array<wchar> Arg;
@@ -75,10 +73,7 @@ void CommandData::ParseCommandLine(bool Preprocess,int argc, char *argv[])
Arg.Alloc(strlen(argv[I])+1);
CharToWide(argv[I],&Arg[0],Arg.Size());
if (Preprocess)
- {
- if (!PreprocessSwitch(&Arg[0]))
- break;
- }
+ PreprocessArg(&Arg[0]);
else
ParseArg(&Arg[0]);
}
@@ -93,7 +88,7 @@ void CommandData::ParseCommandLine(bool Preprocess,int argc, char *argv[])
void CommandData::ParseArg(wchar *Arg)
{
if (IsSwitch(*Arg) && !NoMoreSwitches)
- if (Arg[1]=='-')
+ if (Arg[1]=='-' && Arg[2]==0)
NoMoreSwitches=true;
else
ProcessSwitch(Arg+1);
@@ -199,37 +194,37 @@ void CommandData::ParseEnvVar()
#if !defined(SFX_MODULE) && !defined(_ANDROID)
// Preprocess those parameters, which must be processed before the rest of
// command line. Return 'false' to stop further processing.
-bool CommandData::PreprocessSwitch(const wchar *Switch)
+void CommandData::PreprocessArg(const wchar *Arg)
{
- if (IsSwitch(Switch[0]))
+ if (IsSwitch(Arg[0]) && !NoMoreSwitches)
{
- Switch++;
- char SwitchA[1024];
- WideToChar(Switch,SwitchA,ASIZE(SwitchA));
- if (wcsicomp(Switch,L"-")==0) // Switch "--".
- return false;
- if (wcsicomp(Switch,L"cfg-")==0)
+ Arg++;
+ if (Arg[0]=='-' && Arg[1]==0) // Switch "--".
+ NoMoreSwitches=true;
+ if (wcsicomp(Arg,L"cfg-")==0)
ConfigDisabled=true;
#ifndef GUI
- if (wcsnicomp(Switch,L"ilog",4)==0)
+ if (wcsnicomp(Arg,L"ilog",4)==0)
{
// Ensure that correct log file name is already set
// if we need to report an error when processing the command line.
- ProcessSwitch(Switch);
+ ProcessSwitch(Arg);
InitLogOptions(LogName,ErrlogCharset);
}
#endif
- if (wcsnicomp(Switch,L"sc",2)==0)
+ if (wcsnicomp(Arg,L"sc",2)==0)
{
// Process -sc before reading any file lists.
- ProcessSwitch(Switch);
+ ProcessSwitch(Arg);
#ifndef GUI
if (*LogName!=0)
InitLogOptions(LogName,ErrlogCharset);
#endif
}
}
- return true;
+ else
+ if (*Command==0)
+ wcsncpy(Command,Arg,ASIZE(Command)); // Need for rar.ini.
}
#endif
@@ -247,6 +242,22 @@ void CommandData::ReadConfig()
Str++;
if (wcsnicomp(Str,L"switches=",9)==0)
ProcessSwitchesString(Str+9);
+ if (*Command!=0)
+ {
+ wchar Cmd[16];
+ wcsncpyz(Cmd,Command,ASIZE(Cmd));
+ wchar C0=toupperw(Cmd[0]);
+ wchar C1=toupperw(Cmd[1]);
+ if (C0=='I' || C0=='L' || C0=='M' || C0=='S' || C0=='V')
+ Cmd[1]=0;
+ if (C0=='R' && (C1=='R' || C1=='V'))
+ Cmd[2]=0;
+ wchar SwName[16+ASIZE(Cmd)];
+ swprintf(SwName,ASIZE(SwName),L"switches_%s=",Cmd);
+ size_t Length=wcslen(SwName);
+ if (wcsnicomp(Str,SwName,Length)==0)
+ ProcessSwitchesString(Str+Length);
+ }
}
}
}
@@ -1010,7 +1021,7 @@ bool CommandData::ExclCheck(const wchar *CheckName,bool Dir,bool CheckFullPath,b
return true;
if (!CheckInclList || InclArgs.ItemsCount()==0)
return false;
- if (ExclCheckArgs(&InclArgs,Dir,CheckName,false,MATCH_WILDSUBPATH))
+ if (ExclCheckArgs(&InclArgs,Dir,CheckName,CheckFullPath,MATCH_WILDSUBPATH))
return false;
return true;
}
diff --git a/src/thirdparty/unrar/cmddata.hpp b/src/thirdparty/unrar/cmddata.hpp
index b2f3b1ae1..3ed4ef1d8 100644
--- a/src/thirdparty/unrar/cmddata.hpp
+++ b/src/thirdparty/unrar/cmddata.hpp
@@ -28,7 +28,7 @@ class CommandData:public RAROptions
void ParseDone();
void ParseEnvVar();
void ReadConfig();
- bool PreprocessSwitch(const wchar *Switch);
+ void PreprocessArg(const wchar *Arg);
void OutTitle();
void OutHelp(RAR_EXIT ExitCode);
bool IsSwitch(int Ch);
diff --git a/src/thirdparty/unrar/crypt.cpp b/src/thirdparty/unrar/crypt.cpp
index ef2e68a11..1a9764008 100644
--- a/src/thirdparty/unrar/crypt.cpp
+++ b/src/thirdparty/unrar/crypt.cpp
@@ -11,15 +11,18 @@
CryptData::CryptData()
{
Method=CRYPT_NONE;
- memset(KDFCache,0,sizeof(KDFCache));
- KDFCachePos=0;
+ memset(KDF3Cache,0,sizeof(KDF3Cache));
+ memset(KDF5Cache,0,sizeof(KDF5Cache));
+ KDF3CachePos=0;
+ KDF5CachePos=0;
memset(CRCTab,0,sizeof(CRCTab));
}
CryptData::~CryptData()
{
- cleandata(KDFCache,sizeof(KDFCache));
+ cleandata(KDF3Cache,sizeof(KDF3Cache));
+ cleandata(KDF5Cache,sizeof(KDF5Cache));
}
diff --git a/src/thirdparty/unrar/crypt.hpp b/src/thirdparty/unrar/crypt.hpp
index 1dc244600..f6382ef50 100644
--- a/src/thirdparty/unrar/crypt.hpp
+++ b/src/thirdparty/unrar/crypt.hpp
@@ -20,18 +20,28 @@ enum CRYPT_METHOD {
#define CRYPT_VERSION 0 // Supported encryption version.
-struct KDFCacheItem
-{
- SecPassword Pwd;
- byte Salt[SIZE_SALT50];
- uint Lg2Count; // Log2 of PBKDF2 repetition count.
- byte Key[32];
- byte PswCheckValue[SHA256_DIGEST_SIZE];
- byte HashKeyValue[SHA256_DIGEST_SIZE];
-};
-
class CryptData
{
+ struct KDF5CacheItem
+ {
+ SecPassword Pwd;
+ byte Salt[SIZE_SALT50];
+ byte Key[32];
+ uint Lg2Count; // Log2 of PBKDF2 repetition count.
+ byte PswCheckValue[SHA256_DIGEST_SIZE];
+ byte HashKeyValue[SHA256_DIGEST_SIZE];
+ };
+
+ struct KDF3CacheItem
+ {
+ SecPassword Pwd;
+ byte Salt[SIZE_SALT30];
+ byte Key[16];
+ byte Init[16];
+ bool SaltPresent;
+ };
+
+
private:
void SetKey13(const char *Password);
void Decrypt13(byte *Data,size_t Count);
@@ -46,10 +56,13 @@ class CryptData
void DecryptBlock20(byte *Buf);
void SetKey30(bool Encrypt,SecPassword *Password,const wchar *PwdW,const byte *Salt);
-
void SetKey50(bool Encrypt,SecPassword *Password,const wchar *PwdW,const byte *Salt,const byte *InitV,uint Lg2Cnt,byte *HashKey,byte *PswCheck);
- KDFCacheItem KDFCache[4];
- uint KDFCachePos;
+
+ KDF3CacheItem KDF3Cache[4];
+ uint KDF3CachePos;
+
+ KDF5CacheItem KDF5Cache[4];
+ uint KDF5CachePos;
CRYPT_METHOD Method;
diff --git a/src/thirdparty/unrar/crypt3.cpp b/src/thirdparty/unrar/crypt3.cpp
index ffaced56d..bcc7cfa6d 100644
--- a/src/thirdparty/unrar/crypt3.cpp
+++ b/src/thirdparty/unrar/crypt3.cpp
@@ -1,38 +1,15 @@
-struct CryptKeyCacheItem
-{
- CryptKeyCacheItem()
- {
- Password.Set(L"");
- }
-
- ~CryptKeyCacheItem()
- {
- cleandata(AESKey,sizeof(AESKey));
- cleandata(AESInit,sizeof(AESInit));
- cleandata(&Password,sizeof(Password));
- }
-
- byte AESKey[16],AESInit[16];
- SecPassword Password;
- bool SaltPresent;
- byte Salt[SIZE_SALT30];
-};
-
-static CryptKeyCacheItem Cache[4];
-static int CachePos=0;
-
void CryptData::SetKey30(bool Encrypt,SecPassword *Password,const wchar *PwdW,const byte *Salt)
{
byte AESKey[16],AESInit[16];
bool Cached=false;
- for (uint I=0;I<ASIZE(Cache);I++)
- if (Cache[I].Password==*Password &&
- (Salt==NULL && !Cache[I].SaltPresent || Salt!=NULL &&
- Cache[I].SaltPresent && memcmp(Cache[I].Salt,Salt,SIZE_SALT30)==0))
+ for (uint I=0;I<ASIZE(KDF3Cache);I++)
+ if (KDF3Cache[I].Pwd==*Password &&
+ (Salt==NULL && !KDF3Cache[I].SaltPresent || Salt!=NULL &&
+ KDF3Cache[I].SaltPresent && memcmp(KDF3Cache[I].Salt,Salt,SIZE_SALT30)==0))
{
- memcpy(AESKey,Cache[I].AESKey,sizeof(AESKey));
- memcpy(AESInit,Cache[I].AESInit,sizeof(AESInit));
+ memcpy(AESKey,KDF3Cache[I].Key,sizeof(AESKey));
+ memcpy(AESInit,KDF3Cache[I].Init,sizeof(AESInit));
Cached=true;
break;
}
@@ -73,12 +50,12 @@ void CryptData::SetKey30(bool Encrypt,SecPassword *Password,const wchar *PwdW,co
for (int J=0;J<4;J++)
AESKey[I*4+J]=(byte)(digest[I]>>(J*8));
- Cache[CachePos].Password=*Password;
- if ((Cache[CachePos].SaltPresent=(Salt!=NULL))==true)
- memcpy(Cache[CachePos].Salt,Salt,SIZE_SALT30);
- memcpy(Cache[CachePos].AESKey,AESKey,sizeof(AESKey));
- memcpy(Cache[CachePos].AESInit,AESInit,sizeof(AESInit));
- CachePos=(CachePos+1)%ASIZE(Cache);
+ KDF3Cache[KDF3CachePos].Pwd=*Password;
+ if ((KDF3Cache[KDF3CachePos].SaltPresent=(Salt!=NULL))==true)
+ memcpy(KDF3Cache[KDF3CachePos].Salt,Salt,SIZE_SALT30);
+ memcpy(KDF3Cache[KDF3CachePos].Key,AESKey,sizeof(AESKey));
+ memcpy(KDF3Cache[KDF3CachePos].Init,AESInit,sizeof(AESInit));
+ KDF3CachePos=(KDF3CachePos+1)%ASIZE(KDF3Cache);
cleandata(RawPsw,sizeof(RawPsw));
}
diff --git a/src/thirdparty/unrar/crypt5.cpp b/src/thirdparty/unrar/crypt5.cpp
index fab3cc975..abc5d34a7 100644
--- a/src/thirdparty/unrar/crypt5.cpp
+++ b/src/thirdparty/unrar/crypt5.cpp
@@ -98,15 +98,15 @@ void CryptData::SetKey50(bool Encrypt,SecPassword *Password,const wchar *PwdW,
byte Key[32],PswCheckValue[SHA256_DIGEST_SIZE],HashKeyValue[SHA256_DIGEST_SIZE];
bool Found=false;
- for (uint I=0;I<ASIZE(KDFCache);I++)
+ for (uint I=0;I<ASIZE(KDF5Cache);I++)
{
- KDFCacheItem *Item=KDFCache+I;
+ KDF5CacheItem *Item=KDF5Cache+I;
if (Item->Lg2Count==Lg2Cnt && Item->Pwd==*Password &&
memcmp(Item->Salt,Salt,SIZE_SALT50)==0)
{
- SecHideData(Item->Key,sizeof(Item->Key),false);
+ SecHideData(Item->Key,sizeof(Item->Key),false,false);
memcpy(Key,Item->Key,sizeof(Key));
- SecHideData(Item->Key,sizeof(Item->Key),true);
+ SecHideData(Item->Key,sizeof(Item->Key),true,false);
memcpy(PswCheckValue,Item->PswCheckValue,sizeof(PswCheckValue));
memcpy(HashKeyValue,Item->HashKeyValue,sizeof(HashKeyValue));
@@ -123,14 +123,14 @@ void CryptData::SetKey50(bool Encrypt,SecPassword *Password,const wchar *PwdW,
pbkdf2((byte *)PwdUtf,strlen(PwdUtf),Salt,SIZE_SALT50,Key,HashKeyValue,PswCheckValue,(1<<Lg2Cnt));
cleandata(PwdUtf,sizeof(PwdUtf));
- KDFCacheItem *Item=KDFCache+(KDFCachePos++ % ASIZE(KDFCache));
+ KDF5CacheItem *Item=KDF5Cache+(KDF5CachePos++ % ASIZE(KDF5Cache));
Item->Lg2Count=Lg2Cnt;
Item->Pwd=*Password;
memcpy(Item->Salt,Salt,SIZE_SALT50);
memcpy(Item->Key,Key,sizeof(Key));
memcpy(Item->PswCheckValue,PswCheckValue,sizeof(PswCheckValue));
memcpy(Item->HashKeyValue,HashKeyValue,sizeof(HashKeyValue));
- SecHideData(Item->Key,sizeof(Key),true);
+ SecHideData(Item->Key,sizeof(Key),true,false);
}
if (HashKey!=NULL)
memcpy(HashKey,HashKeyValue,SHA256_DIGEST_SIZE);
diff --git a/src/thirdparty/unrar/dll.rc b/src/thirdparty/unrar/dll.rc
index aedb0fc5e..1481d7632 100644
--- a/src/thirdparty/unrar/dll.rc
+++ b/src/thirdparty/unrar/dll.rc
@@ -2,8 +2,8 @@
#include <commctrl.h>
VS_VERSION_INFO VERSIONINFO
-FILEVERSION 5, 11, 1, 1315
-PRODUCTVERSION 5, 11, 1, 1315
+FILEVERSION 5, 20, 100, 1433
+PRODUCTVERSION 5, 20, 100, 1433
FILEOS VOS__WINDOWS32
FILETYPE VFT_APP
{
@@ -14,8 +14,8 @@ FILETYPE VFT_APP
VALUE "CompanyName", "Alexander Roshal\0"
VALUE "ProductName", "RAR decompression library\0"
VALUE "FileDescription", "RAR decompression library\0"
- VALUE "FileVersion", "5.11.1\0"
- VALUE "ProductVersion", "5.11.1\0"
+ VALUE "FileVersion", "5.20.0\0"
+ VALUE "ProductVersion", "5.20.0\0"
VALUE "LegalCopyright", "Copyright © Alexander Roshal 1993-2014\0"
VALUE "OriginalFilename", "Unrar.dll\0"
}
diff --git a/src/thirdparty/unrar/extract.cpp b/src/thirdparty/unrar/extract.cpp
index 770cae4d7..cab669fe9 100644
--- a/src/thirdparty/unrar/extract.cpp
+++ b/src/thirdparty/unrar/extract.cpp
@@ -9,7 +9,6 @@ CmdExtract::CmdExtract(CommandData *Cmd)
*DestFileName=0;
TotalFileCount=0;
- Password.Set(L"");
Unp=new Unpack(&DataIO);
#ifdef RAR_SMP
Unp->SetThreads(Cmd->Threads);
@@ -25,6 +24,9 @@ CmdExtract::~CmdExtract()
void CmdExtract::DoExtract()
{
+#if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(SILENT)
+ Fat32=NotFat32=false;
+#endif
PasswordCancelled=false;
DataIO.SetCurrentCommand(Cmd->Command[0]);
@@ -36,17 +38,11 @@ void CmdExtract::DoExtract()
Cmd->ArcNames.Rewind();
while (Cmd->GetArcName(ArcName,ASIZE(ArcName)))
{
+ if (Cmd->ManualPassword)
+ Cmd->Password.Clean(); // Clean user entered password before processing next archive.
while (true)
{
- SecPassword PrevCmdPassword;
- PrevCmdPassword=Cmd->Password;
-
EXTRACT_ARC_CODE Code=ExtractArchive();
-
- // Restore Cmd->Password, which could be changed in IsArchive() call
- // for next header encrypted archive.
- Cmd->Password=PrevCmdPassword;
-
if (Code!=EXTRACT_ARC_REPEAT)
break;
}
@@ -54,6 +50,10 @@ void CmdExtract::DoExtract()
DataIO.ProcessedArcSize+=FD.Size;
}
+ // Clean user entered password. Not really required, just for extra safety.
+ if (Cmd->ManualPassword)
+ Cmd->Password.Clean();
+
if (TotalFileCount==0 && Cmd->Command[0]!='I' &&
ErrHandler.GetErrorCode()!=RARX_BADPWD) // Not in case of wrong archive password.
{
@@ -86,8 +86,6 @@ void CmdExtract::ExtractArchiveInit(Archive &Arc)
#endif
PasswordAll=(Cmd->Password.IsSet());
- if (PasswordAll)
- Password=Cmd->Password;
DataIO.UnpVolume=false;
@@ -262,15 +260,11 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
int MatchNumber=Cmd->IsProcessFile(Arc.FileHead,&EqualNames,MatchType);
bool ExactMatch=MatchNumber!=0;
#ifndef SFX_MODULE
- if (Cmd->ExclPath==EXCL_BASEPATH)
+ if (*Cmd->ArcPath==0 && Cmd->ExclPath==EXCL_BASEPATH && ExactMatch)
{
- *Cmd->ArcPath=0;
- if (ExactMatch)
- {
- Cmd->FileArgs.Rewind();
- if (Cmd->FileArgs.GetString(Cmd->ArcPath,ASIZE(Cmd->ArcPath),MatchNumber-1))
- *PointToName(Cmd->ArcPath)=0;
- }
+ Cmd->FileArgs.Rewind();
+ if (Cmd->FileArgs.GetString(Cmd->ArcPath,ASIZE(Cmd->ArcPath),MatchNumber-1))
+ *PointToName(Cmd->ArcPath)=0;
}
#endif
if (ExactMatch && !EqualNames)
@@ -400,7 +394,7 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
}
#endif
// Skip only the current encrypted file if empty password is entered.
- if (!Password.IsSet())
+ if (!Cmd->Password.IsSet())
{
ErrHandler.SetErrorCode(RARX_WARNING);
#ifdef RARDLL
@@ -430,7 +424,6 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
#endif
}
-
File CurFile;
bool LinkEntry=Arc.FileHead.RedirType!=FSREDIR_NONE;
@@ -510,7 +503,7 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
mprintf(L" ");
#endif
- SecPassword FilePassword=Password;
+ SecPassword FilePassword=Cmd->Password;
#if defined(_WIN_ALL) && !defined(SFX_MODULE)
ConvertDosPassword(Arc,FilePassword);
#endif
@@ -540,6 +533,18 @@ bool CmdExtract::ExtractCurrentFile(Archive &Arc,size_t HeaderSize,bool &Repeat)
DataIO.SetFiles(&Arc,&CurFile);
DataIO.SetTestMode(TestMode);
DataIO.SetSkipUnpCRC(SkipSolid);
+
+#if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(SILENT)
+ if (!TestMode && !WrongPassword && !Arc.BrokenHeader &&
+ Arc.FileHead.UnpSize>0xffffffff && (Fat32 || !NotFat32))
+ {
+ if (!Fat32) // Not detected yet.
+ NotFat32=!(Fat32=IsFAT(Cmd->ExtrPath));
+ if (Fat32)
+ uiMsg(UIMSG_FAT32SIZE); // Inform user about FAT32 size limit.
+ }
+#endif
+
if (!TestMode && !WrongPassword && !Arc.BrokenHeader &&
(Arc.FileHead.PackSize<<11)>Arc.FileHead.UnpSize &&
(Arc.FileHead.UnpSize<100000000 || Arc.FileLength()>Arc.FileHead.PackSize))
@@ -862,11 +867,11 @@ bool CmdExtract::ExtrDllGetPassword()
}
Cmd->Password.Set(PasswordW);
cleandata(PasswordW,sizeof(PasswordW));
+ Cmd->ManualPassword=true;
}
if (!Cmd->Password.IsSet())
return false;
}
- Password=Cmd->Password;
return true;
}
#endif
@@ -875,14 +880,15 @@ bool CmdExtract::ExtrDllGetPassword()
#ifndef RARDLL
bool CmdExtract::ExtrGetPassword(Archive &Arc,const wchar *ArcFileName)
{
- if (!Password.IsSet())
+ if (!Cmd->Password.IsSet())
{
- if (!uiGetPassword(UIPASSWORD_FILE,ArcFileName,&Password))
+ if (!uiGetPassword(UIPASSWORD_FILE,ArcFileName,&Cmd->Password))
{
uiMsg(UIERROR_INCERRCOUNT);
return false;
}
+ Cmd->ManualPassword=true;
}
#if !defined(GUI) && !defined(SILENT)
else
@@ -894,7 +900,7 @@ bool CmdExtract::ExtrGetPassword(Archive &Arc,const wchar *ArcFileName)
case -1:
ErrHandler.Exit(RARX_USERBREAK);
case 2:
- if (!uiGetPassword(UIPASSWORD_FILE,ArcFileName,&Password))
+ if (!uiGetPassword(UIPASSWORD_FILE,ArcFileName,&Cmd->Password))
return false;
break;
case 3:
@@ -916,7 +922,7 @@ void CmdExtract::ConvertDosPassword(Archive &Arc,SecPassword &DestPwd)
// We need the password in OEM encoding if file was encrypted by
// native RAR/DOS (not extender based). Let's make the conversion.
wchar PlainPsw[MAXPASSWORD];
- Password.Get(PlainPsw,ASIZE(PlainPsw));
+ Cmd->Password.Get(PlainPsw,ASIZE(PlainPsw));
char PswA[MAXPASSWORD];
CharToOemBuffW(PlainPsw,PswA,ASIZE(PswA));
PswA[ASIZE(PswA)-1]=0;
@@ -957,6 +963,18 @@ void CmdExtract::ExtrCreateDir(Archive &Arc,const wchar *ArcFileName)
{
CreatePath(DestFileName,true);
MDCode=MakeDir(DestFileName,!Cmd->IgnoreGeneralAttr,Arc.FileHead.FileAttr);
+ if (MDCode!=MKDIR_SUCCESS)
+ {
+ 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);
+#endif
+ }
}
}
if (MDCode==MKDIR_SUCCESS)
diff --git a/src/thirdparty/unrar/extract.hpp b/src/thirdparty/unrar/extract.hpp
index 1539ed61a..4ea317b61 100644
--- a/src/thirdparty/unrar/extract.hpp
+++ b/src/thirdparty/unrar/extract.hpp
@@ -43,11 +43,13 @@ class CmdExtract
wchar ArcName[NM];
- SecPassword Password;
bool PasswordAll;
bool PrevExtracted;
wchar DestFileName[NM];
bool PasswordCancelled;
+#if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(SILENT)
+ bool Fat32,NotFat32;
+#endif
public:
CmdExtract(CommandData *Cmd);
~CmdExtract();
diff --git a/src/thirdparty/unrar/file.cpp b/src/thirdparty/unrar/file.cpp
index 51100acd6..8fba34adb 100644
--- a/src/thirdparty/unrar/file.cpp
+++ b/src/thirdparty/unrar/file.cpp
@@ -2,7 +2,7 @@
File::File()
{
- hFile=BAD_HANDLE;
+ hFile=FILE_BAD_HANDLE;
*FileName=0;
NewFile=false;
LastWrite=false;
@@ -22,7 +22,7 @@ File::File()
File::~File()
{
- if (hFile!=BAD_HANDLE && !SkipClose)
+ if (hFile!=FILE_BAD_HANDLE && !SkipClose)
if (NewFile)
Delete();
else
@@ -52,14 +52,14 @@ bool File::Open(const wchar *Name,uint Mode)
uint Access=WriteMode ? GENERIC_WRITE:GENERIC_READ;
if (UpdateMode)
Access|=GENERIC_WRITE;
- uint ShareMode=FILE_SHARE_READ;
+ uint ShareMode=(Mode & FMF_OPENEXCLUSIVE) ? 0 : FILE_SHARE_READ;
if (OpenShared)
ShareMode|=FILE_SHARE_WRITE;
uint Flags=NoSequentialRead ? 0:FILE_FLAG_SEQUENTIAL_SCAN;
hNewFile=CreateFile(Name,Access,ShareMode,NULL,OPEN_EXISTING,Flags,NULL);
DWORD LastError;
- if (hNewFile==BAD_HANDLE)
+ if (hNewFile==FILE_BAD_HANDLE)
{
LastError=GetLastError();
@@ -85,7 +85,7 @@ bool File::Open(const wchar *Name,uint Mode)
}
}
- if (hNewFile==BAD_HANDLE && LastError==ERROR_FILE_NOT_FOUND)
+ if (hNewFile==FILE_BAD_HANDLE && LastError==ERROR_FILE_NOT_FOUND)
ErrorType=FILE_NOTFOUND;
#else
int flags=UpdateMode ? O_RDWR:(WriteMode ? O_WRONLY:O_RDONLY);
@@ -112,7 +112,7 @@ bool File::Open(const wchar *Name,uint Mode)
}
#endif
if (handle==-1)
- hNewFile=BAD_HANDLE;
+ hNewFile=FILE_BAD_HANDLE;
else
{
#ifdef FILE_USE_OPEN
@@ -121,13 +121,13 @@ bool File::Open(const wchar *Name,uint Mode)
hNewFile=fdopen(handle,UpdateMode ? UPDATEBINARY:READBINARY);
#endif
}
- if (hNewFile==BAD_HANDLE && errno==ENOENT)
+ if (hNewFile==FILE_BAD_HANDLE && errno==ENOENT)
ErrorType=FILE_NOTFOUND;
#endif
NewFile=false;
HandleType=FILE_HANDLENORMAL;
SkipClose=false;
- bool Success=hNewFile!=BAD_HANDLE;
+ bool Success=hNewFile!=FILE_BAD_HANDLE;
if (Success)
{
hFile=hNewFile;
@@ -167,9 +167,18 @@ bool File::Create(const wchar *Name,uint Mode)
CreateMode=Mode;
uint Access=WriteMode ? GENERIC_WRITE:GENERIC_READ|GENERIC_WRITE;
DWORD ShareMode=ShareRead ? FILE_SHARE_READ:0;
- hFile=CreateFile(Name,Access,ShareMode,NULL,CREATE_ALWAYS,0,NULL);
- if (hFile==BAD_HANDLE)
+ // Windows automatically removes dots and spaces in the end of file name,
+ // So we detect such names and process them with \\?\ prefix.
+ wchar *LastChar=PointToLastChar(Name);
+ bool Special=*LastChar=='.' || *LastChar==' ';
+
+ if (Special)
+ hFile=FILE_BAD_HANDLE;
+ else
+ hFile=CreateFile(Name,Access,ShareMode,NULL,CREATE_ALWAYS,0,NULL);
+
+ if (hFile==FILE_BAD_HANDLE)
{
wchar LongName[NM];
if (GetWinLongPath(Name,LongName,ASIZE(LongName)))
@@ -181,6 +190,10 @@ bool File::Create(const wchar *Name,uint Mode)
WideToChar(Name,NameA,ASIZE(NameA));
#ifdef FILE_USE_OPEN
hFile=open(NameA,(O_CREAT|O_TRUNC) | (WriteMode ? O_WRONLY : O_RDWR));
+#ifdef _ANDROID
+ if (hFile==FILE_BAD_HANDLE)
+ hFile=JniCreateFile(Name); // If external card is read-only for usual file API.
+#endif
#else
hFile=fopen(NameA,WriteMode ? WRITEBINARY:CREATEBINARY);
#endif
@@ -189,7 +202,7 @@ bool File::Create(const wchar *Name,uint Mode)
HandleType=FILE_HANDLENORMAL;
SkipClose=false;
wcsncpyz(FileName,Name,ASIZE(FileName));
- return hFile!=BAD_HANDLE;
+ return hFile!=FILE_BAD_HANDLE;
}
@@ -215,7 +228,7 @@ bool File::Close()
{
bool Success=true;
- if (hFile!=BAD_HANDLE)
+ if (hFile!=FILE_BAD_HANDLE)
{
if (!SkipClose)
{
@@ -232,7 +245,7 @@ bool File::Close()
#endif
#endif
}
- hFile=BAD_HANDLE;
+ hFile=FILE_BAD_HANDLE;
}
HandleType=FILE_HANDLENORMAL;
if (!Success && AllowExceptions)
@@ -245,7 +258,7 @@ bool File::Delete()
{
if (HandleType!=FILE_HANDLENORMAL)
return false;
- if (hFile!=BAD_HANDLE)
+ if (hFile!=FILE_BAD_HANDLE)
Close();
if (!AllowDelete)
return false;
@@ -278,7 +291,7 @@ void File::Write(const void *Data,size_t Size)
hFile=GetStdHandle(STD_OUTPUT_HANDLE);
#else
// Cannot use the standard stdout here, because it already has wide orientation.
- if (hFile==BAD_HANDLE)
+ if (hFile==FILE_BAD_HANDLE)
{
#ifdef FILE_USE_OPEN
hFile=dup(STDOUT_FILENO); // Open new stdout stream.
@@ -390,8 +403,8 @@ int File::DirectRead(void *Data,size_t Size)
if (HandleType==FILE_HANDLESTD)
{
#ifdef _WIN_ALL
- if (Size>MaxDeviceRead)
- Size=MaxDeviceRead;
+// if (Size>MaxDeviceRead)
+// Size=MaxDeviceRead;
hFile=GetStdHandle(STD_INPUT_HANDLE);
#else
#ifdef FILE_USE_OPEN
@@ -402,6 +415,8 @@ int File::DirectRead(void *Data,size_t Size)
#endif
}
#ifdef _WIN_ALL
+ // For pipes like 'type file.txt | rar -si arcname' ReadFile may return
+ // data in small ~4KB blocks. It may slightly reduce the compression ratio.
DWORD Read;
if (!ReadFile(hFile,Data,(DWORD)Size,&Read,NULL))
{
@@ -454,7 +469,7 @@ void File::Seek(int64 Offset,int Method)
bool File::RawSeek(int64 Offset,int Method)
{
- if (hFile==BAD_HANDLE)
+ if (hFile==FILE_BAD_HANDLE)
return true;
if (Offset<0 && Method!=SEEK_SET)
{
@@ -485,7 +500,7 @@ bool File::RawSeek(int64 Offset,int Method)
int64 File::Tell()
{
- if (hFile==BAD_HANDLE)
+ if (hFile==FILE_BAD_HANDLE)
if (AllowExceptions)
ErrHandler.SeekError(FileName);
else
@@ -636,7 +651,7 @@ int64 File::FileLength()
bool File::IsDevice()
{
- if (hFile==BAD_HANDLE)
+ if (hFile==FILE_BAD_HANDLE)
return false;
#ifdef _WIN_ALL
uint Type=GetFileType(hFile);
@@ -650,7 +665,7 @@ bool File::IsDevice()
#ifndef SFX_MODULE
int64 File::Copy(File &Dest,int64 Length)
{
- Array<char> Buffer(0x10000);
+ Array<char> Buffer(0x40000);
int64 CopySize=0;
bool CopyAll=(Length==INT64NDF);
@@ -667,7 +682,7 @@ int64 File::Copy(File &Dest,int64 Length)
// For FAT32 USB flash drives in Windows if first write is 4 KB or more,
// write caching is disabled and "write through" is enabled, resulting
// in bad performance, especially for many small files. It happens when
- // we create SFX archive on USB drive, because SFX module is writetn first.
+ // we create SFX archive on USB drive, because SFX module is written first.
// So we split the first write to small 1 KB followed by rest of data.
if (CopySize==0 && WriteSize>=4096)
{
diff --git a/src/thirdparty/unrar/file.hpp b/src/thirdparty/unrar/file.hpp
index 7829aaeb0..93aac89f3 100644
--- a/src/thirdparty/unrar/file.hpp
+++ b/src/thirdparty/unrar/file.hpp
@@ -7,13 +7,13 @@
#ifdef _WIN_ALL
typedef HANDLE FileHandle;
- #define BAD_HANDLE INVALID_HANDLE_VALUE
+ #define FILE_BAD_HANDLE INVALID_HANDLE_VALUE
#elif defined(FILE_USE_OPEN)
typedef off_t FileHandle;
- #define BAD_HANDLE -1
+ #define FILE_BAD_HANDLE -1
#else
typedef FILE* FileHandle;
- #define BAD_HANDLE NULL
+ #define FILE_BAD_HANDLE NULL
#endif
class RAROptions;
@@ -35,8 +35,11 @@ enum FILE_MODE_FLAGS {
// Open files which are already opened for write by other programs.
FMF_OPENSHARED=4,
+ // Open files only if no other program is opened it even in shared mode.
+ FMF_OPENEXCLUSIVE=8,
+
// Provide read access to created file for other programs.
- FMF_SHAREREAD=8,
+ FMF_SHAREREAD=16,
// Mode flags are not defined yet.
FMF_UNDEFINED=256
@@ -91,7 +94,7 @@ class File
void SetCloseFileTime(RarTime *ftm,RarTime *fta=NULL);
static void SetCloseFileTimeByName(const wchar *Name,RarTime *ftm,RarTime *fta);
void GetOpenFileTime(RarTime *ft);
- bool IsOpened() {return hFile!=BAD_HANDLE;};
+ bool IsOpened() {return hFile!=FILE_BAD_HANDLE;};
int64 FileLength();
void SetHandleType(FILE_HANDLETYPE Type) {HandleType=Type;}
FILE_HANDLETYPE GetHandleType() {return HandleType;}
diff --git a/src/thirdparty/unrar/filefn.cpp b/src/thirdparty/unrar/filefn.cpp
index 679060578..6526f4337 100644
--- a/src/thirdparty/unrar/filefn.cpp
+++ b/src/thirdparty/unrar/filefn.cpp
@@ -3,7 +3,11 @@
MKDIR_CODE MakeDir(const wchar *Name,bool SetAttr,uint Attr)
{
#ifdef _WIN_ALL
- BOOL RetCode=CreateDirectory(Name,NULL);
+ // Windows automatically removes dots and spaces in the end of directory
+ // name. So we detect such names and process them with \\?\ prefix.
+ wchar *LastChar=PointToLastChar(Name);
+ bool Special=*LastChar=='.' || *LastChar==' ';
+ BOOL RetCode=Special ? FALSE : CreateDirectory(Name,NULL);
if (RetCode==0 && !FileExist(Name))
{
wchar LongName[NM];
@@ -25,6 +29,10 @@ MKDIR_CODE MakeDir(const wchar *Name,bool SetAttr,uint Attr)
WideToChar(Name,NameA,ASIZE(NameA));
mode_t uattr=SetAttr ? (mode_t)Attr:0777;
int ErrCode=mkdir(NameA,uattr);
+#ifdef _ANDROID
+ if (ErrCode==-1 && errno!=ENOENT)
+ ErrCode=JniMkdir(Name) ? 0 : -1; // If external card is read-only for usual file API.
+#endif
if (ErrCode==-1)
return errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR;
return MKDIR_SUCCESS;
@@ -54,8 +62,9 @@ bool CreatePath(const wchar *Path,bool SkipLastName)
break;
// Process all kinds of path separators, so user can enter Unix style
- // path in Windows or Windows in Unix.
- if (IsPathDiv(*s))
+ // path in Windows or Windows in Unix. s>Path check avoids attempting
+ // creating an empty directory for paths starting from path separator.
+ if (IsPathDiv(*s) && s>Path)
{
#ifdef _WIN_ALL
// We must not attempt to create "D:" directory, because first
@@ -169,6 +178,19 @@ int64 GetFreeDisk(const wchar *Name)
#endif
+#if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(SILENT)
+// Return 'true' for FAT and FAT32, so we can adjust the maximum supported
+// file size to 4 GB for these file systems.
+bool IsFAT(const wchar *Name)
+{
+ wchar Root[NM];
+ GetPathRoot(Name,Root,ASIZE(Root));
+ wchar FileSystem[MAX_PATH+1];
+ if (GetVolumeInformation(Root,NULL,0,NULL,NULL,NULL,FileSystem,ASIZE(FileSystem)))
+ return wcscmp(FileSystem,L"FAT")==0 || wcscmp(FileSystem,L"FAT32")==0;
+ return false;
+}
+#endif
bool FileExist(const wchar *Name)
@@ -394,7 +416,12 @@ bool RenameFile(const wchar *SrcName,const wchar *DestName)
char SrcNameA[NM],DestNameA[NM];
WideToChar(SrcName,SrcNameA,ASIZE(SrcNameA));
WideToChar(DestName,DestNameA,ASIZE(DestNameA));
- return rename(SrcNameA,DestNameA)==0;
+ bool Success=rename(SrcNameA,DestNameA)==0;
+#ifdef _ANDROID
+ if (!Success)
+ Success=JniRename(SrcName,DestName); // If external card is read-only for usual file API.
+#endif
+ return Success;
#endif
}
@@ -413,7 +440,12 @@ bool DelFile(const wchar *Name)
#else
char NameA[NM];
WideToChar(Name,NameA,ASIZE(NameA));
- return remove(NameA)==0;
+ bool Success=remove(NameA)==0;
+#ifdef _ANDROID
+ if (!Success)
+ Success=JniDelete(Name);
+#endif
+ return Success;
#endif
}
diff --git a/src/thirdparty/unrar/filefn.hpp b/src/thirdparty/unrar/filefn.hpp
index d89329471..b06cc64e1 100644
--- a/src/thirdparty/unrar/filefn.hpp
+++ b/src/thirdparty/unrar/filefn.hpp
@@ -12,6 +12,9 @@ bool IsRemovable(const wchar *Name);
int64 GetFreeDisk(const wchar *Name);
#endif
+#if defined(_WIN_ALL) && !defined(SFX_MODULE) && !defined(SILENT)
+bool IsFAT(const wchar *Root);
+#endif
bool FileExist(const wchar *Name);
bool WildFileExist(const wchar *Name);
diff --git a/src/thirdparty/unrar/filestr.cpp b/src/thirdparty/unrar/filestr.cpp
index b719206c7..a87384f24 100644
--- a/src/thirdparty/unrar/filestr.cpp
+++ b/src/thirdparty/unrar/filestr.cpp
@@ -37,15 +37,17 @@ bool ReadTextFile(
SrcFile.SetHandleType(FILE_HANDLESTD);
unsigned int DataSize=0,ReadSize;
- const int ReadBlock=1024;
- Array<char> Data(ReadBlock+5);
+ const int ReadBlock=4096;
+ Array<char> Data(ReadBlock+3);
while ((ReadSize=SrcFile.Read(&Data[DataSize],ReadBlock))!=0)
{
DataSize+=ReadSize;
Data.Add(ReadSize);
}
- memset(&Data[DataSize],0,5);
+ // Add trailing Unicode zero after text data. We add 3 bytes instead of 2
+ // in case read Unicode data contains uneven number of bytes.
+ memset(&Data[DataSize],0,3);
Array<wchar> WideStr;
@@ -136,7 +138,7 @@ bool ReadTextFile(
break;
*SpacePtr=0;
}
- if (*CurStr)
+ if (*CurStr!=0)
{
if (Unquote && *CurStr=='\"')
{
diff --git a/src/thirdparty/unrar/list.cpp b/src/thirdparty/unrar/list.cpp
index 7f1e3cd95..d64e274a6 100644
--- a/src/thirdparty/unrar/list.cpp
+++ b/src/thirdparty/unrar/list.cpp
@@ -18,6 +18,9 @@ void ListArchive(CommandData *Cmd)
wchar ArcName[NM];
while (Cmd->GetArcName(ArcName,ASIZE(ArcName)))
{
+ if (Cmd->ManualPassword)
+ Cmd->Password.Clean(); // Clean user entered password before processing next archive.
+
Archive Arc(Cmd);
#ifdef _WIN_ALL
Arc.RemoveSequentialFlag();
@@ -162,6 +165,10 @@ void ListArchive(CommandData *Cmd)
}
}
+ // Clean user entered password. Not really required, just for extra safety.
+ if (Cmd->ManualPassword)
+ Cmd->Password.Clean();
+
if (ArcCount>1 && !Bare && !Technical)
{
wchar UnpSizeText[20],PackSizeText[20];
diff --git a/src/thirdparty/unrar/loclang.hpp b/src/thirdparty/unrar/loclang.hpp
index d07df1cef..fb560713a 100644
--- a/src/thirdparty/unrar/loclang.hpp
+++ b/src/thirdparty/unrar/loclang.hpp
@@ -216,7 +216,7 @@
#define MExtrNoFiles L"\nNo files to extract"
#define MExtrAllOk L"\nAll OK"
#define MExtrTotalErr L"\nTotal errors: %ld"
-#define MFileExists L"\n\n%s already exists. Overwrite it ?"
+#define MAskReplace L"\n\nWould you like to replace the existing file %s\n%6s bytes, modified on %s\nwith a new one\n%6s bytes, modified on %s\n"
#define MAskOverwrite L"\nOverwrite %s ?"
#define MAskNewName L"\nEnter new name: "
#define MHeaderBroken L"\nCorrupt header is found"
@@ -344,6 +344,7 @@
#define MCreating L"\nCreating %s"
#define MRenaming L"\nRenaming %s to %s"
#define MNTFSRequired L"\nWrite error: only NTFS file system supports files larger than 4 GB"
+#define MFAT32Size L"\nWARNING: FAT32 file system does not support 4 GB or larger files"
#define MErrChangeAttr L"\nWARNING: Cannot change attributes of %s"
#define MWrongSFXVer L"\nERROR: default SFX module does not support RAR %d.%d archives"
#define MCannotEncName L"\nCannot encrypt archive already contained encrypted files"
diff --git a/src/thirdparty/unrar/options.hpp b/src/thirdparty/unrar/options.hpp
index 7b61ba2fb..ba9c0ca82 100644
--- a/src/thirdparty/unrar/options.hpp
+++ b/src/thirdparty/unrar/options.hpp
@@ -99,6 +99,9 @@ class RAROptions
wchar ArcPath[NM];
SecPassword Password;
bool EncryptHeaders;
+
+ bool ManualPassword; // Password entered manually during operation, might need to clean for next archive.
+
wchar LogName[NM];
MESSAGE_TYPE MsgStream;
bool Sound;
diff --git a/src/thirdparty/unrar/pathfn.cpp b/src/thirdparty/unrar/pathfn.cpp
index 016a0e824..bfd3b588e 100644
--- a/src/thirdparty/unrar/pathfn.cpp
+++ b/src/thirdparty/unrar/pathfn.cpp
@@ -196,7 +196,7 @@ void RemoveNameFromPath(wchar *Path)
#if defined(_WIN_ALL) && !defined(SFX_MODULE)
-static void GetAppDataPath(wchar *Path,size_t MaxSize,bool Create)
+bool GetAppDataPath(wchar *Path,size_t MaxSize,bool Create)
{
LPMALLOC g_pMalloc;
SHGetMalloc(&g_pMalloc);
@@ -212,12 +212,8 @@ static void GetAppDataPath(wchar *Path,size_t MaxSize,bool Create)
if (!Success && Create)
Success=MakeDir(Path,false,0)==MKDIR_SUCCESS;
}
- if (!Success)
- {
- GetModuleFileName(NULL,Path,(DWORD)MaxSize);
- RemoveNameFromPath(Path);
- }
g_pMalloc->Free(ppidl);
+ return Success;
}
#endif
@@ -237,7 +233,11 @@ void GetRarDataPath(wchar *Path,size_t MaxSize,bool Create)
}
if (*Path==0 || !FileExist(Path))
- GetAppDataPath(Path,MaxSize,Create);
+ if (!GetAppDataPath(Path,MaxSize,Create))
+ {
+ GetModuleFileName(NULL,Path,(DWORD)MaxSize);
+ RemoveNameFromPath(Path);
+ }
}
#endif
@@ -436,10 +436,13 @@ void MakeNameUsable(wchar *Name,bool Extended)
#ifndef _UNIX
if (s-Name>1 && *s==':')
*s='_';
+#if 0 // We already can create such files.
// Remove ' ' and '.' before path separator, but allow .\ and ..\.
- if ((*s==' ' || *s=='.' && s>Name && !IsPathDiv(s[-1]) && s[-1]!='.') && IsPathDiv(s[1]))
+ if (IsPathDiv(s[1]) && (*s==' ' || *s=='.' && s>Name &&
+ !IsPathDiv(s[-1]) && (s[-1]!='.' || s>Name+1 && !IsPathDiv(s[-2]))))
*s='_';
#endif
+#endif
}
}
diff --git a/src/thirdparty/unrar/pathfn.hpp b/src/thirdparty/unrar/pathfn.hpp
index b34727355..fabb29340 100644
--- a/src/thirdparty/unrar/pathfn.hpp
+++ b/src/thirdparty/unrar/pathfn.hpp
@@ -17,9 +17,14 @@ void AddEndSlash(wchar *Path,size_t MaxLength);
void MakeName(const wchar *Path,const wchar *Name,wchar *Pathname,size_t MaxSize);
void GetFilePath(const wchar *FullName,wchar *Path,size_t MaxLength);
void RemoveNameFromPath(wchar *Path);
+#if defined(_WIN_ALL) && !defined(SFX_MODULE)
+bool GetAppDataPath(wchar *Path,size_t MaxSize,bool Create);
void GetRarDataPath(wchar *Path,size_t MaxSize,bool Create);
+#endif
+#ifndef SFX_MODULE
bool EnumConfigPaths(uint Number,wchar *Path,size_t MaxSize,bool Create);
void GetConfigName(const wchar *Name,wchar *FullName,size_t MaxSize,bool CheckExist,bool Create);
+#endif
wchar* GetVolNumPart(const wchar *ArcName);
void NextVolumeName(wchar *ArcName,uint MaxLength,bool OldNumbering);
bool IsNameUsable(const wchar *Name);
diff --git a/src/thirdparty/unrar/secpassword.cpp b/src/thirdparty/unrar/secpassword.cpp
index ba7152595..2ac289b72 100644
--- a/src/thirdparty/unrar/secpassword.cpp
+++ b/src/thirdparty/unrar/secpassword.cpp
@@ -7,6 +7,7 @@ typedef BOOL (WINAPI *CRYPTUNPROTECTMEMORY)(LPVOID pData,DWORD cbData,DWORD dwFl
#ifndef CRYPTPROTECTMEMORY_BLOCK_SIZE
#define CRYPTPROTECTMEMORY_BLOCK_SIZE 16
#define CRYPTPROTECTMEMORY_SAME_PROCESS 0x00
+#define CRYPTPROTECTMEMORY_CROSS_PROCESS 0x01
#endif
class CryptLoader
@@ -48,12 +49,13 @@ class CryptLoader
CRYPTUNPROTECTMEMORY pCryptUnprotectMemory;
};
-// We want to call FreeLibrary when RAR is exiting.
+// We need to call FreeLibrary when RAR is exiting.
CryptLoader GlobalCryptLoader;
#endif
SecPassword::SecPassword()
{
+ CrossProcess=false;
Set(L"");
}
@@ -99,7 +101,7 @@ void SecPassword::Process(const wchar *Src,size_t SrcSize,wchar *Dst,size_t DstS
// Source string can be shorter than destination as in case when we process
// -p<pwd> parameter, so we need to take into account both sizes.
memcpy(Dst,Src,Min(SrcSize,DstSize)*sizeof(*Dst));
- SecHideData(Dst,DstSize*sizeof(*Dst),Encode);
+ SecHideData(Dst,DstSize*sizeof(*Dst),Encode,CrossProcess);
}
@@ -156,18 +158,19 @@ bool SecPassword::operator == (SecPassword &psw)
}
-void SecHideData(void *Data,size_t DataSize,bool Encode)
+void SecHideData(void *Data,size_t DataSize,bool Encode,bool CrossProcess)
{
#ifdef _WIN_ALL
// Try to utilize the secure Crypt[Un]ProtectMemory if possible.
if (GlobalCryptLoader.pCryptProtectMemory==NULL)
GlobalCryptLoader.Load();
size_t Aligned=DataSize-DataSize%CRYPTPROTECTMEMORY_BLOCK_SIZE;
+ DWORD Flags=CrossProcess ? CRYPTPROTECTMEMORY_CROSS_PROCESS : CRYPTPROTECTMEMORY_SAME_PROCESS;
if (Encode)
{
if (GlobalCryptLoader.pCryptProtectMemory!=NULL)
{
- if (!GlobalCryptLoader.pCryptProtectMemory(Data,DWORD(Aligned),CRYPTPROTECTMEMORY_SAME_PROCESS))
+ if (!GlobalCryptLoader.pCryptProtectMemory(Data,DWORD(Aligned),Flags))
{
ErrHandler.GeneralErrMsg(L"CryptProtectMemory failed");
ErrHandler.SysErrMsg();
@@ -180,7 +183,7 @@ void SecHideData(void *Data,size_t DataSize,bool Encode)
{
if (GlobalCryptLoader.pCryptUnprotectMemory!=NULL)
{
- if (!GlobalCryptLoader.pCryptUnprotectMemory(Data,DWORD(Aligned),CRYPTPROTECTMEMORY_SAME_PROCESS))
+ if (!GlobalCryptLoader.pCryptUnprotectMemory(Data,DWORD(Aligned),Flags))
{
ErrHandler.GeneralErrMsg(L"CryptUnprotectMemory failed");
ErrHandler.SysErrMsg();
diff --git a/src/thirdparty/unrar/secpassword.hpp b/src/thirdparty/unrar/secpassword.hpp
index 7e166a23b..375d3887a 100644
--- a/src/thirdparty/unrar/secpassword.hpp
+++ b/src/thirdparty/unrar/secpassword.hpp
@@ -22,10 +22,14 @@ class SecPassword
bool IsSet() {return PasswordSet;}
size_t Length();
bool operator == (SecPassword &psw);
+
+ // Set to true if we need to pass a password to another process.
+ // We use it when transferring parameters to UAC elevated WinRAR.
+ bool CrossProcess;
};
void cleandata(void *data,size_t size);
-void SecHideData(void *Data,size_t DataSize,bool Encode);
+void SecHideData(void *Data,size_t DataSize,bool Encode,bool CrossProcess);
#endif
diff --git a/src/thirdparty/unrar/smallfn.cpp b/src/thirdparty/unrar/smallfn.cpp
index 5b5e6f66b..fe7cb1dc2 100644
--- a/src/thirdparty/unrar/smallfn.cpp
+++ b/src/thirdparty/unrar/smallfn.cpp
@@ -4,7 +4,7 @@ int ToPercent(int64 N1,int64 N2)
{
if (N2<N1)
return(100);
- return(ToPercentUnlim(N1,N2));
+ return ToPercentUnlim(N1,N2);
}
@@ -13,5 +13,7 @@ int ToPercentUnlim(int64 N1,int64 N2)
{
if (N2==0)
return(0);
- return((int)(N1*100/N2));
+ return (int)(N1*100/N2);
}
+
+
diff --git a/src/thirdparty/unrar/strfn.cpp b/src/thirdparty/unrar/strfn.cpp
index c2888a09c..f83482fb2 100644
--- a/src/thirdparty/unrar/strfn.cpp
+++ b/src/thirdparty/unrar/strfn.cpp
@@ -265,8 +265,9 @@ wchar* wcsncpyz(wchar *dest, const wchar *src, size_t maxlen)
char* strncatz(char* dest, const char* src, size_t maxlen)
{
size_t Length = strlen(dest);
- if (Length + 1 < maxlen)
- strncat(dest, src, maxlen - Length - 1);
+ int avail=int(maxlen - Length - 1);
+ if (avail > 0)
+ strncat(dest, src, avail);
return dest;
}
@@ -277,8 +278,9 @@ char* strncatz(char* dest, const char* src, size_t maxlen)
wchar* wcsncatz(wchar* dest, const wchar* src, size_t maxlen)
{
size_t Length = wcslen(dest);
- if (Length + 1 < maxlen)
- wcsncat(dest, src, maxlen - Length - 1);
+ int avail=int(maxlen - Length - 1);
+ if (avail > 0)
+ wcsncat(dest, src, avail);
return dest;
}
diff --git a/src/thirdparty/unrar/threadmisc.cpp b/src/thirdparty/unrar/threadmisc.cpp
index d56867be4..d1524e0cf 100644
--- a/src/thirdparty/unrar/threadmisc.cpp
+++ b/src/thirdparty/unrar/threadmisc.cpp
@@ -58,6 +58,20 @@ ThreadPool* CreateThreadPool()
if (GlobalPoolUseCount++ == 0)
GlobalPool=new ThreadPool(MaxPoolThreads);
+#ifdef RARDLL
+ // We use a simple thread pool, which does not allow to add tasks from
+ // different functions and threads in the same time. It is ok for RAR,
+ // but UnRAR.dll can be used in multithreaded environment. So if one of
+ // threads requests a copy of global pool and another copy is already
+ // in use, we create and return a new pool instead of existing global.
+ if (GlobalPoolUseCount > 1)
+ {
+ ThreadPool *Pool = new ThreadPool(MaxPoolThreads);
+ CriticalSectionEnd(&PoolCreateSync.CritSection);
+ return Pool;
+ }
+#endif
+
CriticalSectionEnd(&PoolCreateSync.CritSection);
return GlobalPool;
}
@@ -69,6 +83,12 @@ void DestroyThreadPool(ThreadPool *Pool)
if (Pool!=NULL && Pool==GlobalPool && GlobalPoolUseCount > 0 && --GlobalPoolUseCount == 0)
delete GlobalPool;
+#ifdef RARDLL
+ // To correctly work in multithreaded environment UnRAR.dll creates
+ // new pools if global pool is already in use. We delete such pools here.
+ if (Pool!=NULL && Pool!=GlobalPool)
+ delete Pool;
+#endif
CriticalSectionEnd(&PoolCreateSync.CritSection);
}
diff --git a/src/thirdparty/unrar/timefn.hpp b/src/thirdparty/unrar/timefn.hpp
index f8c914b87..355baaf74 100644
--- a/src/thirdparty/unrar/timefn.hpp
+++ b/src/thirdparty/unrar/timefn.hpp
@@ -32,6 +32,7 @@ class RarTime
RarTime& operator =(time_t ut);
time_t GetUnix();
bool operator == (RarTime &rt) {return itime==rt.itime;}
+ bool operator != (RarTime &rt) {return itime!=rt.itime;}
bool operator < (RarTime &rt) {return itime<rt.itime;}
bool operator <= (RarTime &rt) {return itime<rt.itime || itime==rt.itime;}
bool operator > (RarTime &rt) {return itime>rt.itime;}
diff --git a/src/thirdparty/unrar/ui.hpp b/src/thirdparty/unrar/ui.hpp
index 9803b78ab..ae1b8839a 100644
--- a/src/thirdparty/unrar/ui.hpp
+++ b/src/thirdparty/unrar/ui.hpp
@@ -45,7 +45,7 @@ enum UIMESSAGE_CODE {
UIMSG_SECTORRECOVERED, UIMSG_SECTORNOTRECOVERED, UIMSG_FOUND,
UIMSG_CORRECTINGNAME, UIMSG_BADARCHIVE, UIMSG_CREATING, UIMSG_RENAMING,
UIMSG_RECVOLCALCCHECKSUM, UIMSG_RECVOLFOUND, UIMSG_RECVOLMISSING,
- UIMSG_MISSINGVOL, UIMSG_RECONSTRUCTING, UIMSG_CHECKSUM,
+ UIMSG_MISSINGVOL, UIMSG_RECONSTRUCTING, UIMSG_CHECKSUM, UIMSG_FAT32SIZE,
UIWAIT_FIRST,
UIWAIT_DISKFULLNEXT, UIWAIT_FCREATEERROR,
@@ -55,9 +55,8 @@ enum UIMESSAGE_CODE {
UIEVENT_DELADDEDSTART, UIEVENT_DELADDEDFILE, UIEVENT_FILESFOUND,
UIEVENT_ERASEDISK, UIEVENT_FILESUMSTART, UIEVENT_FILESUMPROGRESS,
UIEVENT_FILESUMEND, UIEVENT_PROTECTSTART, UIEVENT_PROTECTEND,
- UIEVENT_TESTADDEDSTART, UIEVENT_TESTADDEDEND, UIEVENT_RRTESTING,
- UIEVENT_NEWARCHIVE, UIEVENT_NEWREVFILE
-
+ UIEVENT_TESTADDEDSTART, UIEVENT_TESTADDEDEND, UIEVENT_RRTESTINGSTART,
+ UIEVENT_RRTESTINGEND, UIEVENT_NEWARCHIVE, UIEVENT_NEWREVFILE
};
// Flags for uiAskReplace function.
diff --git a/src/thirdparty/unrar/uiconsole.cpp b/src/thirdparty/unrar/uiconsole.cpp
index 5ddaf09f4..b9129c4f7 100644
--- a/src/thirdparty/unrar/uiconsole.cpp
+++ b/src/thirdparty/unrar/uiconsole.cpp
@@ -1,8 +1,20 @@
// Purely user interface function. Gets and returns user input.
UIASKREP_RESULT uiAskReplace(wchar *Name,size_t MaxNameSize,int64 FileSize,RarTime *FileTime,uint Flags)
{
+ wchar SizeText1[20],DateStr1[50],SizeText2[20],DateStr2[50];
+
+ FindData ExistingFD;
+ memset(&ExistingFD,0,sizeof(ExistingFD)); // In case find fails.
+ FindFile::FastFind(Name,&ExistingFD);
+ itoa(ExistingFD.Size,SizeText1);
+ ExistingFD.mtime.GetText(DateStr1,ASIZE(DateStr1),true,false);
+
+ itoa(FileSize,SizeText2);
+ FileTime->GetText(DateStr2,ASIZE(DateStr2),true,false);
+
+ eprintf(St(MAskReplace),Name,SizeText1,DateStr1,SizeText2,DateStr2);
+
bool AllowRename=(Flags & UIASKREP_F_NORENAME)==0;
- eprintf(St(MFileExists),Name);
int Choice=0;
do
{
@@ -299,11 +311,14 @@ void uiMsgStore::Msg()
case UIMSG_CHECKSUM:
mprintf(St(MCRCFailed),Str[0]);
break;
+ case UIMSG_FAT32SIZE:
+ mprintf(St(MFAT32Size));
+ mprintf(L" "); // For progress percent.
+ break;
-
- case UIEVENT_RRTESTING:
+ case UIEVENT_RRTESTINGSTART:
mprintf(L"%s ",St(MTestingRR));
break;
}
diff --git a/src/thirdparty/unrar/unicode.cpp b/src/thirdparty/unrar/unicode.cpp
index cff2358d0..9c1080aa7 100644
--- a/src/thirdparty/unrar/unicode.cpp
+++ b/src/thirdparty/unrar/unicode.cpp
@@ -433,7 +433,7 @@ const wchar_t* wcscasestr(const wchar_t *str, const wchar_t *search)
{
if (search[j]==0)
return str+i;
- if (towlower(str[i+j])!=towlower(search[j]))
+ if (tolowerw(str[i+j])!=tolowerw(search[j]))
break;
}
return NULL;
@@ -472,31 +472,50 @@ wchar* wcsupper(wchar *s)
int toupperw(int ch)
{
+#ifdef _WIN_ALL
+ // CharUpper is more reliable than towupper in Windows, which seems to be
+ // C locale dependent even in Unicode version. For example, towupper failed
+ // to convert lowercase Russian characters.
+ return (int)CharUpper((wchar *)ch);
+#else
return towupper(ch);
+#endif
}
int tolowerw(int ch)
{
+#ifdef _WIN_ALL
+ // CharLower is more reliable than towlower in Windows.
+ // See comment for towupper above.
+ return (int)CharLower((wchar *)ch);
+#else
return towlower(ch);
+#endif
}
-uint atoiw(const wchar *s)
+int atoiw(const wchar *s)
{
- return (uint)atoilw(s);
+ return (int)atoilw(s);
}
-uint64 atoilw(const wchar *s)
+int64 atoilw(const wchar *s)
{
- uint64 n=0;
+ int sign=1;
+ if (*s=='-')
+ {
+ s++;
+ sign=-1;
+ }
+ int64 n=0;
while (*s>='0' && *s<='9')
{
n=n*10+(*s-'0');
s++;
}
- return n;
+ return sign*n;
}
diff --git a/src/thirdparty/unrar/unicode.hpp b/src/thirdparty/unrar/unicode.hpp
index 29eeb0edd..e2f45b0b9 100644
--- a/src/thirdparty/unrar/unicode.hpp
+++ b/src/thirdparty/unrar/unicode.hpp
@@ -22,8 +22,8 @@ wchar* wcsupper(wchar *s);
#endif
int toupperw(int ch);
int tolowerw(int ch);
-uint atoiw(const wchar *s);
-uint64 atoilw(const wchar *s);
+int atoiw(const wchar *s);
+int64 atoilw(const wchar *s);
#ifdef DBCS_SUPPORTED
class SupportDBCS
diff --git a/src/thirdparty/unrar/unrar.vcxproj b/src/thirdparty/unrar/unrar.vcxproj
index 3a0aafb89..88eede44a 100644
--- a/src/thirdparty/unrar/unrar.vcxproj
+++ b/src/thirdparty/unrar/unrar.vcxproj
@@ -47,52 +47,46 @@
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\common.props" />
+ <Import Project="..\..\common-3rd-party.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\common.props" />
+ <Import Project="..\..\common-3rd-party.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\common.props" />
+ <Import Project="..\..\common-3rd-party.props" />
</ImportGroup>
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
<Import Project="..\..\common.props" />
+ <Import Project="..\..\common-3rd-party.props" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
- <PropertyGroup>
- </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
<PreprocessorDefinitions>_LIB;RARDLL;SILENT;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <WarningLevel>TurnOffAllWarnings</WarningLevel>
- <EnablePREfast>false</EnablePREfast>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
- <WarningLevel>TurnOffAllWarnings</WarningLevel>
<PreprocessorDefinitions>_LIB;RARDLL;SILENT;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <EnablePREfast>false</EnablePREfast>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
- <WarningLevel>TurnOffAllWarnings</WarningLevel>
<PreprocessorDefinitions>_LIB;RARDLL;SILENT;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <EnablePREfast>false</EnablePREfast>
</ClCompile>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<PrecompiledHeaderFile>rar.hpp</PrecompiledHeaderFile>
- <WarningLevel>TurnOffAllWarnings</WarningLevel>
<PreprocessorDefinitions>_LIB;RARDLL;SILENT;_CRT_SECURE_CPP_OVERLOAD_STANDARD_NAMES;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <EnablePREfast>false</EnablePREfast>
</ClCompile>
</ItemDefinitionGroup>
<ItemGroup>
diff --git a/src/thirdparty/unrar/version.hpp b/src/thirdparty/unrar/version.hpp
index ef0b664db..3a36f22b3 100644
--- a/src/thirdparty/unrar/version.hpp
+++ b/src/thirdparty/unrar/version.hpp
@@ -1,6 +1,6 @@
#define RARVER_MAJOR 5
-#define RARVER_MINOR 11
-#define RARVER_BETA 1
-#define RARVER_DAY 6
-#define RARVER_MONTH 8
+#define RARVER_MINOR 20
+#define RARVER_BETA 0
+#define RARVER_DAY 2
+#define RARVER_MONTH 12
#define RARVER_YEAR 2014