summaryrefslogtreecommitdiff
path: root/unrar
diff options
context:
space:
mode:
Diffstat (limited to 'unrar')
-rw-r--r--unrar/unrar.c8
-rw-r--r--unrar/unrar/archive.hpp1
-rw-r--r--unrar/unrar/arcread.cpp26
-rw-r--r--unrar/unrar/cmddata.cpp72
-rw-r--r--unrar/unrar/cmddata.hpp2
-rw-r--r--unrar/unrar/consio.cpp47
-rw-r--r--unrar/unrar/consio.hpp2
-rw-r--r--unrar/unrar/crc.cpp14
-rw-r--r--unrar/unrar/crc.hpp4
-rw-r--r--unrar/unrar/dll.cpp10
-rw-r--r--unrar/unrar/dll.hpp12
-rw-r--r--unrar/unrar/errhnd.cpp3
-rw-r--r--unrar/unrar/errhnd.hpp1
-rw-r--r--unrar/unrar/extract.cpp66
-rw-r--r--unrar/unrar/extract.hpp1
-rw-r--r--unrar/unrar/filcreat.cpp4
-rw-r--r--unrar/unrar/file.cpp35
-rw-r--r--unrar/unrar/file.hpp8
-rw-r--r--unrar/unrar/filefn.cpp21
-rw-r--r--unrar/unrar/filefn.hpp5
-rw-r--r--unrar/unrar/filestr.cpp45
-rw-r--r--unrar/unrar/filestr.hpp3
-rw-r--r--unrar/unrar/find.cpp11
-rw-r--r--unrar/unrar/find.hpp7
-rw-r--r--unrar/unrar/headers.hpp12
-rw-r--r--unrar/unrar/list.cpp21
-rw-r--r--unrar/unrar/loclang.hpp7
-rw-r--r--unrar/unrar/makefile.unix28
-rw-r--r--unrar/unrar/match.cpp22
-rw-r--r--unrar/unrar/match.hpp17
-rw-r--r--unrar/unrar/options.cpp2
-rw-r--r--unrar/unrar/options.hpp10
-rw-r--r--unrar/unrar/os.hpp3
-rw-r--r--unrar/unrar/pathfn.cpp86
-rw-r--r--unrar/unrar/pathfn.hpp5
-rw-r--r--unrar/unrar/rdwrfn.cpp24
-rw-r--r--unrar/unrar/rdwrfn.hpp7
-rw-r--r--unrar/unrar/recvol.cpp11
-rw-r--r--unrar/unrar/scantree.cpp14
-rw-r--r--unrar/unrar/scantree.hpp3
-rw-r--r--unrar/unrar/strfn.cpp10
-rw-r--r--unrar/unrar/strlist.cpp2
-rw-r--r--unrar/unrar/timefn.cpp2
-rw-r--r--unrar/unrar/unicode.cpp40
-rw-r--r--unrar/unrar/unicode.hpp9
-rw-r--r--unrar/unrar/unpack.cpp5
-rw-r--r--unrar/unrar/uowners.cpp4
-rw-r--r--unrar/unrar/version.hpp10
-rw-r--r--unrar/unrar/volume.cpp63
49 files changed, 589 insertions, 236 deletions
diff --git a/unrar/unrar.c b/unrar/unrar.c
index 6435aeb..8a725f6 100644
--- a/unrar/unrar.c
+++ b/unrar/unrar.c
@@ -1,5 +1,5 @@
/* UNRAR plugin for Tux Commander
- * version 0.2.2, designed for unrar v3.7.1 beta1
+ * version 0.2.3, designed for unrar v3.8.2
* Copyright (C) 2008 Tomas Bzatek <tbzatek@users.sourceforge.net>
* Check for updates on tuxcmd.sourceforge.net
*
@@ -55,8 +55,8 @@ enum HOST_SYSTEM {
};
-#define VERSION "0.2.2"
-#define BUILD_DATE "2008-05-11"
+#define VERSION "0.2.3"
+#define BUILD_DATE "2008-08-21"
#define DEFAULT_BLOCK_SIZE 65536
@@ -139,7 +139,7 @@ struct TVFSInfo VFSGetInfo()
module_info.About = strdup(s);
free(s);
s = (char*)malloc(255);
- snprintf(s, 255, "Plugin Copyright (C) 2008 Tomáš Bžatek\nUNRAR sources Copyright (C) 2002-2007 Alexander Roshal");
+ snprintf(s, 255, "Plugin Copyright (C) 2008 Tomáš Bžatek\nUNRAR sources Copyright (C) 2002-2008 Alexander Roshal");
module_info.Copyright = strdup(s);
return module_info;
}
diff --git a/unrar/unrar/archive.hpp b/unrar/unrar/archive.hpp
index 1e0675e..a278aff 100644
--- a/unrar/unrar/archive.hpp
+++ b/unrar/unrar/archive.hpp
@@ -14,7 +14,6 @@ class Archive:public File
void ConvertNameCase(wchar *Name);
void ConvertUnknownHeader();
int ReadOldHeader();
- void PrepareExtraTime(FileHeader *hd,EXTTIME_MODE etm,EXTTIME_MODE etc,EXTTIME_MODE eta,EXTTIME_MODE etarc,Array<byte> &TimeData);
#if !defined(SHELL_EXT) && !defined(NOCRYPT)
CryptData HeadersCrypt;
diff --git a/unrar/unrar/arcread.cpp b/unrar/unrar/arcread.cpp
index 43a23db..8dd03fa 100644
--- a/unrar/unrar/arcread.cpp
+++ b/unrar/unrar/arcread.cpp
@@ -52,7 +52,7 @@ int Archive::ReadHeader()
if (*Cmd->Password==0)
#ifdef RARDLL
if (Cmd->Callback==NULL ||
- Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LONG)Cmd->Password,sizeof(Cmd->Password))==-1)
+ Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LPARAM)Cmd->Password,sizeof(Cmd->Password))==-1)
{
Close();
ErrHandler.Exit(USER_BREAK);
@@ -370,6 +370,8 @@ int Archive::ReadHeader()
bool Recovered=false;
if (ShortBlock.HeadType==ENDARC_HEAD && (EndArcHead.Flags & EARC_REVSPACE)!=0)
{
+ // Last 7 bytes of recovered volume can contain zeroes, because
+ // REV files store its own information (volume number, etc.) here.
SaveFilePos SavePos(*this);
Int64 Length=Tell();
Seek(Length-7,SEEK_SET);
@@ -582,10 +584,32 @@ void Archive::ConvertUnknownHeader()
if ((byte)*s<32 || (byte)*s>127)
*s='_';
#endif
+
+#if defined(_WIN_32) || defined(_EMX)
+ // ':' in file names is allowed in Unix, but not in Windows.
+ // Even worse, file data will be written to NTFS stream on NTFS,
+ // so automatic name correction on file create error in extraction
+ // routine does not work. Let's better replace ':' now.
+ if (NewLhd.HostOS==HOST_UNIX && *s==':')
+ *s='_';
+#endif
+
}
+
for (wchar *s=NewLhd.FileNameW;*s!=0;s++)
+ {
if (*s=='/' || *s=='\\')
*s=CPATHDIVIDER;
+
+#if defined(_WIN_32) || defined(_EMX)
+ // ':' in file names is allowed in Unix, but not in Windows.
+ // Even worse, file data will be written to NTFS stream on NTFS,
+ // so automatic name correction on file create error in extraction
+ // routine does not work. Let's better replace ':' now.
+ if (NewLhd.HostOS==HOST_UNIX && *s==':')
+ *s='_';
+#endif
+ }
}
diff --git a/unrar/unrar/cmddata.cpp b/unrar/unrar/cmddata.cpp
index 41f3dd7..1f17cce 100644
--- a/unrar/unrar/cmddata.cpp
+++ b/unrar/unrar/cmddata.cpp
@@ -51,7 +51,7 @@ void CommandData::ParseArg(char *Arg,wchar *ArgW)
if (Arg[1]=='-')
NoMoreSwitches=true;
else
- ProcessSwitch(&Arg[1]);
+ ProcessSwitch(&Arg[1],(ArgW!=NULL && *ArgW!=0 ? &ArgW[1]:NULL));
else
if (*Command==0)
{
@@ -81,8 +81,8 @@ void CommandData::ParseArg(char *Arg,wchar *ArgW)
}
else
{
- int Length=strlen(Arg);
- char EndChar=Arg[Length-1];
+ size_t Length=strlen(Arg);
+ char EndChar=Length==0 ? 0:Arg[Length-1];
char CmdChar=etoupper(*Command);
bool Add=strchr("AFUM",CmdChar)!=NULL;
bool Extract=CmdChar=='X' || CmdChar=='E';
@@ -113,7 +113,7 @@ void CommandData::ParseArg(char *Arg,wchar *ArgW)
Charset=RCH_OEM;
#endif
- ReadTextFile(Arg+1,FileArgs,false,true,Charset,true,true);
+ ReadTextFile(Arg+1,FileArgs,false,true,Charset,true,true,true);
}
else
if (Found && FileData.IsDir && Extract && *ExtrPath==0)
@@ -226,7 +226,7 @@ void CommandData::ProcessSwitchesString(char *Str)
#if !defined(SFX_MODULE)
-void CommandData::ProcessSwitch(char *Switch)
+void CommandData::ProcessSwitch(char *Switch,wchar *SwitchW)
{
switch(etoupper(Switch[0]))
@@ -375,6 +375,8 @@ void CommandData::ProcessSwitch(char *Switch)
break;
case 'P':
strcpy(ArcPath,Switch+2);
+ if (SwitchW!=NULL && *SwitchW!=0)
+ strcpyw(ArcPathW,SwitchW+2);
break;
case 'S':
SyncFiles=true;
@@ -408,6 +410,9 @@ void CommandData::ProcessSwitch(char *Switch)
case '-':
Overwrite=OVERWRITE_NONE;
break;
+ case 0:
+ Overwrite=OVERWRITE_FORCE_ASK;
+ break;
case 'R':
Overwrite=OVERWRITE_AUTORENAME;
break;
@@ -480,7 +485,7 @@ void CommandData::ProcessSwitch(char *Switch)
Charset=RCH_OEM;
#endif
- ReadTextFile(Switch+2,Args,false,true,Charset,true,true);
+ ReadTextFile(Switch+2,Args,false,true,Charset,true,true,true);
}
else
Args->AddString(Switch+1);
@@ -794,7 +799,7 @@ void CommandData::ProcessSwitch(char *Switch)
break;
case 'C':
{
- RAR_CHARSET rch;
+ RAR_CHARSET rch=RCH_DEFAULT;
switch(etoupper(Switch[2]))
{
case 'A':
@@ -908,6 +913,18 @@ void CommandData::OutTitle()
#endif
+inline bool CmpMSGID(MSGID i1,MSGID i2)
+{
+#ifdef MSGID_INT
+ return(i1==i2);
+#else
+ // If MSGID is const char*, we cannot compare pointers only.
+ // Pointers to different instances of same strings can differ,
+ // so we need to compare complete strings.
+ return(strcmp(i1,i2)==0);
+#endif
+}
+
void CommandData::OutHelp()
{
#if !defined(GUI) && !defined(SILENT)
@@ -916,12 +933,13 @@ void CommandData::OutHelp()
#ifdef SFX_MODULE
MCHelpCmd,MSHelpCmdE,MSHelpCmdT,MSHelpCmdV
#elif defined(UNRAR)
- MUNRARTitle1,MRARTitle2,MCHelpCmd,MCHelpCmdE,MCHelpCmdL,MCHelpCmdP,
- MCHelpCmdT,MCHelpCmdV,MCHelpCmdX,MCHelpSw,MCHelpSwm,MCHelpSwAC,MCHelpSwAD,
- MCHelpSwAP,MCHelpSwAVm,MCHelpSwCm,MCHelpSwCFGm,MCHelpSwCL,MCHelpSwCU,
+ MUNRARTitle1,MRARTitle2,MCHelpCmd,MCHelpCmdE,MCHelpCmdL,
+ MCHelpCmdP,MCHelpCmdT,MCHelpCmdV,MCHelpCmdX,MCHelpSw,
+ MCHelpSwm,MCHelpSwAC,MCHelpSwAD,MCHelpSwAP,
+ MCHelpSwCm,MCHelpSwCFGm,MCHelpSwCL,MCHelpSwCU,
MCHelpSwDH,MCHelpSwEP,MCHelpSwEP3,MCHelpSwF,MCHelpSwIDP,MCHelpSwIERR,
MCHelpSwINUL,MCHelpSwIOFF,MCHelpSwKB,MCHelpSwN,MCHelpSwNa,MCHelpSwNal,
- MCHelpSwOp,MCHelpSwOm,MCHelpSwOC,MCHelpSwOR,MCHelpSwOW,MCHelpSwP,
+ MCHelpSwO,MCHelpSwOC,MCHelpSwOR,MCHelpSwOW,MCHelpSwP,
MCHelpSwPm,MCHelpSwR,MCHelpSwRI,MCHelpSwSL,MCHelpSwSM,MCHelpSwTA,
MCHelpSwTB,MCHelpSwTN,MCHelpSwTO,MCHelpSwTS,MCHelpSwU,MCHelpSwVUnr,
MCHelpSwVER,MCHelpSwVP,MCHelpSwX,MCHelpSwXa,MCHelpSwXal,MCHelpSwY
@@ -932,13 +950,13 @@ void CommandData::OutHelp()
MCHelpCmdRN,MCHelpCmdRR,MCHelpCmdRV,MCHelpCmdS,MCHelpCmdT,MCHelpCmdU,
MCHelpCmdV,MCHelpCmdX,MCHelpSw,MCHelpSwm,MCHelpSwAC,MCHelpSwAD,MCHelpSwAG,
MCHelpSwAO,MCHelpSwAP,MCHelpSwAS,MCHelpSwAV,MCHelpSwAVm,MCHelpSwCm,
- MCHelpSwCFGm,MCHelpSwCL,MCHelpSwCU,MCHelpSwDF,MCHelpSwDH,MCHelpSwDS,
- MCHelpSwEa,MCHelpSwED,MCHelpSwEE,MCHelpSwEN,MCHelpSwEP,MCHelpSwEP1,
- MCHelpSwEP2,MCHelpSwEP3,MCHelpSwF,MCHelpSwHP,MCHelpSwIDP,
- MCHelpSwIEML,MCHelpSwIERR,MCHelpSwILOG,MCHelpSwINUL,MCHelpSwIOFF,
- MCHelpSwISND,MCHelpSwK,MCHelpSwKB,MCHelpSwMn,MCHelpSwMC,MCHelpSwMD,
- MCHelpSwMS,MCHelpSwMT,MCHelpSwN,MCHelpSwNa,MCHelpSwNal,MCHelpSwOp,
- MCHelpSwOm,MCHelpSwOC,MCHelpSwOL,MCHelpSwOR,MCHelpSwOS,MCHelpSwOW,
+ MCHelpSwCFGm,MCHelpSwCL,MCHelpSwCU,MCHelpSwDF,MCHelpSwDH,MCHelpSwDR,
+ MCHelpSwDS,MCHelpSwDW,MCHelpSwEa,MCHelpSwED,MCHelpSwEE,MCHelpSwEN,
+ MCHelpSwEP,MCHelpSwEP1,MCHelpSwEP2,MCHelpSwEP3,MCHelpSwF,MCHelpSwHP,
+ MCHelpSwIDP,MCHelpSwIEML,MCHelpSwIERR,MCHelpSwILOG,MCHelpSwINUL,
+ MCHelpSwIOFF,MCHelpSwISND,MCHelpSwK,MCHelpSwKB,MCHelpSwMn,MCHelpSwMC,
+ MCHelpSwMD,MCHelpSwMS,MCHelpSwMT,MCHelpSwN,MCHelpSwNa,MCHelpSwNal,
+ MCHelpSwO,MCHelpSwOC,MCHelpSwOL,MCHelpSwOR,MCHelpSwOS,MCHelpSwOW,
MCHelpSwP,MCHelpSwPm,MCHelpSwR,MCHelpSwR0,MCHelpSwRI,MCHelpSwRR,
MCHelpSwRV,MCHelpSwS,MCHelpSwSm,MCHelpSwSC,MCHelpSwSFX,MCHelpSwSI,
MCHelpSwSL,MCHelpSwSM,MCHelpSwT,MCHelpSwTA,MCHelpSwTB,MCHelpSwTK,
@@ -958,11 +976,11 @@ void CommandData::OutHelp()
#ifndef _WIN_32
static MSGID Win32Only[]={
MCHelpSwIEML,MCHelpSwVD,MCHelpSwAO,MCHelpSwOS,MCHelpSwIOFF,
- MCHelpSwEP2,MCHelpSwOC
+ MCHelpSwEP2,MCHelpSwOC,MCHelpSwDR,MCHelpSwRI
};
bool Found=false;
for (int J=0;J<sizeof(Win32Only)/sizeof(Win32Only[0]);J++)
- if (Help[I]==Win32Only[J])
+ if (CmpMSGID(Help[I],Win32Only[J]))
{
Found=true;
break;
@@ -971,27 +989,23 @@ void CommandData::OutHelp()
continue;
#endif
#if !defined(_UNIX) && !defined(_WIN_32)
- if (Help[I]==MCHelpSwOW)
+ if (CmpMSGID(Help[I],MCHelpSwOW))
continue;
#endif
#if !defined(_WIN_32) && !defined(_EMX)
- if (Help[I]==MCHelpSwAC)
+ if (CmpMSGID(Help[I],MCHelpSwAC))
continue;
#endif
#ifndef SAVE_LINKS
- if (Help[I]==MCHelpSwOL)
- continue;
-#endif
-#ifndef _WIN_32
- if (Help[I]==MCHelpSwRI)
+ if (CmpMSGID(Help[I],MCHelpSwOL))
continue;
#endif
#ifndef PACK_SMP
- if (Help[I]==MCHelpSwMT)
+ if (CmpMSGID(Help[I],MCHelpSwMT))
continue;
#endif
#ifndef _BEOS
- if (Help[I]==MCHelpSwEE)
+ if (CmpMSGID(Help[I],MCHelpSwEE))
{
#if defined(_EMX) && !defined(_DJGPP)
if (_osmode != OS2_MODE)
diff --git a/unrar/unrar/cmddata.hpp b/unrar/unrar/cmddata.hpp
index 5dfe2dc..64a336d 100644
--- a/unrar/unrar/cmddata.hpp
+++ b/unrar/unrar/cmddata.hpp
@@ -7,7 +7,7 @@ class CommandData:public RAROptions
{
private:
void ProcessSwitchesString(char *Str);
- void ProcessSwitch(char *Switch);
+ void ProcessSwitch(char *Switch,wchar *SwitchW=NULL);
void BadSwitch(char *Switch);
bool ExclCheckArgs(StringList *Args,char *CheckName,bool CheckFullPath,int MatchMode);
uint GetExclAttr(char *Str);
diff --git a/unrar/unrar/consio.cpp b/unrar/unrar/consio.cpp
index f1f4ba0..6644dce 100644
--- a/unrar/unrar/consio.cpp
+++ b/unrar/unrar/consio.cpp
@@ -4,8 +4,11 @@
#include "log.cpp"
#endif
+static int KbdAnsi(char *Addr,int Size);
+
#if !defined(GUI) && !defined(SILENT)
static void RawPrint(char *Msg,MESSAGE_TYPE MessageType);
+static uint GetKey();
#endif
static MESSAGE_TYPE MsgStream=MSG_STDOUT;
@@ -133,27 +136,6 @@ void GetPasswordText(char *Str,int MaxLength)
#endif
-#if !defined(GUI) && !defined(SILENT)
-unsigned int GetKey()
-{
-#ifdef SILENT
- return(0);
-#else
- char Str[80];
-#ifdef __GNUC__
- fgets(Str,sizeof(Str),stdin);
- return(Str[0]);
-#else
- File SrcFile;
- SrcFile.SetHandleType(FILE_HANDLESTD);
- SrcFile.Read(Str,sizeof(Str));
- return(Str[0]);
-#endif
-#endif
-}
-#endif
-
-
#ifndef SILENT
bool GetPassword(PASSWORD_TYPE Type,const char *FileName,char *Password,int MaxLength)
{
@@ -199,6 +181,29 @@ bool GetPassword(PASSWORD_TYPE Type,const char *FileName,char *Password,int MaxL
#if !defined(GUI) && !defined(SILENT)
+uint GetKey()
+{
+ char Str[80];
+ bool EndOfFile;
+#if defined(__GNUC__) || defined(sun)
+ EndOfFile=(fgets(Str,sizeof(Str),stdin)==NULL);
+#else
+ File SrcFile;
+ SrcFile.SetHandleType(FILE_HANDLESTD);
+ EndOfFile=(SrcFile.Read(Str,sizeof(Str))==0);
+#endif
+ if (EndOfFile)
+ {
+ // Looks like stdin is a null device. We can enter to infinite loop
+ // calling Ask(), so let's better exit.
+ ErrHandler.Exit(USER_BREAK);
+ }
+ return(Str[0]);
+}
+#endif
+
+
+#if !defined(GUI) && !defined(SILENT)
int Ask(const char *AskStr)
{
const int MaxItems=10;
diff --git a/unrar/unrar/consio.hpp b/unrar/unrar/consio.hpp
index 003a011..b077cea 100644
--- a/unrar/unrar/consio.hpp
+++ b/unrar/unrar/consio.hpp
@@ -12,12 +12,10 @@ void mprintf(const char *fmt,...);
void eprintf(const char *fmt,...);
void Alarm();
void GetPasswordText(char *Str,int MaxLength);
-unsigned int GetKey();
bool GetPassword(PASSWORD_TYPE Type,const char *FileName,char *Password,int MaxLength);
int Ask(const char *AskStr);
#endif
-int KbdAnsi(char *Addr,int Size);
void OutComment(char *Comment,int Size);
#ifdef SILENT
diff --git a/unrar/unrar/crc.cpp b/unrar/unrar/crc.cpp
index 1d91e45..9758241 100644
--- a/unrar/unrar/crc.cpp
+++ b/unrar/unrar/crc.cpp
@@ -14,12 +14,18 @@ void InitCRC()
}
-uint CRC(uint StartCRC,const void *Addr,uint Size)
+uint CRC(uint StartCRC,const void *Addr,size_t Size)
{
if (CRCTab[1]==0)
InitCRC();
byte *Data=(byte *)Addr;
#if defined(LITTLE_ENDIAN) && defined(PRESENT_INT32) && defined(ALLOW_NOT_ALIGNED_INT)
+
+#ifdef _MSC_VER
+ // avoid a warning about 'Data' pointer truncation in 64 bit mode
+ #pragma warning( disable : 4311 )
+#endif
+
while (Size>0 && ((long)Data & 7))
{
StartCRC=CRCTab[(byte)(StartCRC^Data[0])]^(StartCRC>>8);
@@ -42,16 +48,16 @@ uint CRC(uint StartCRC,const void *Addr,uint Size)
Size-=8;
}
#endif
- for (int I=0;I<Size;I++)
+ for (size_t I=0;I<Size;I++)
StartCRC=CRCTab[(byte)(StartCRC^Data[I])]^(StartCRC>>8);
return(StartCRC);
}
#ifndef SFX_MODULE
-ushort OldCRC(ushort StartCRC,const void *Addr,uint Size)
+ushort OldCRC(ushort StartCRC,const void *Addr,size_t Size)
{
byte *Data=(byte *)Addr;
- for (int I=0;I<Size;I++)
+ for (size_t I=0;I<Size;I++)
{
StartCRC=(StartCRC+Data[I])&0xffff;
StartCRC=((StartCRC<<1)|(StartCRC>>15))&0xffff;
diff --git a/unrar/unrar/crc.hpp b/unrar/unrar/crc.hpp
index 47ee7e2..a632a54 100644
--- a/unrar/unrar/crc.hpp
+++ b/unrar/unrar/crc.hpp
@@ -4,7 +4,7 @@
extern uint CRCTab[256];
void InitCRC();
-uint CRC(uint StartCRC,const void *Addr,uint Size);
-ushort OldCRC(ushort StartCRC,const void *Addr,uint Size);
+uint CRC(uint StartCRC,const void *Addr,size_t Size);
+ushort OldCRC(ushort StartCRC,const void *Addr,size_t Size);
#endif
diff --git a/unrar/unrar/dll.cpp b/unrar/unrar/dll.cpp
index f1a2cc9..18e62bd 100644
--- a/unrar/unrar/dll.cpp
+++ b/unrar/unrar/dll.cpp
@@ -221,9 +221,10 @@ int PASCAL ProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestNa
try
{
Data->Cmd.DllError=0;
- if (Data->OpenMode==RAR_OM_LIST || Operation==RAR_SKIP && !Data->Arc.Solid)
+ if (Data->OpenMode==RAR_OM_LIST || Data->OpenMode==RAR_OM_LIST_INCSPLIT ||
+ Operation==RAR_SKIP && !Data->Arc.Solid)
{
- if (/*Data->OpenMode==RAR_OM_LIST && */Data->Arc.Volume &&
+ if (Data->Arc.Volume &&
Data->Arc.GetHeaderType()==FILE_HEAD &&
(Data->Arc.NewLhd.Flags & LHD_SPLIT_AFTER)!=0)
if (MergeArchive(Data->Arc,NULL,false,'L'))
@@ -265,6 +266,9 @@ int PASCAL ProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestNa
strncpyw(Data->Cmd.ExtrPathW,NullToEmpty(DestPathW),NM-2);
AddEndSlash(Data->Cmd.ExtrPathW);
strncpyw(Data->Cmd.DllDestNameW,NullToEmpty(DestNameW),NM-1);
+
+ if (*Data->Cmd.DllDestNameW!=0 && *Data->Cmd.DllDestName==0)
+ WideToChar(Data->Cmd.DllDestNameW,Data->Cmd.DllDestName);
}
else
{
@@ -312,7 +316,7 @@ void PASCAL RARSetChangeVolProc(HANDLE hArcData,CHANGEVOLPROC ChangeVolProc)
}
-void PASCAL RARSetCallback(HANDLE hArcData,UNRARCALLBACK Callback,LONG UserData)
+void PASCAL RARSetCallback(HANDLE hArcData,UNRARCALLBACK Callback,LPARAM UserData)
{
DataSet *Data=(DataSet *)hArcData;
Data->Cmd.Callback=Callback;
diff --git a/unrar/unrar/dll.hpp b/unrar/unrar/dll.hpp
index 4b67744..c7cf622 100644
--- a/unrar/unrar/dll.hpp
+++ b/unrar/unrar/dll.hpp
@@ -1,6 +1,9 @@
#ifndef _UNRAR_DLL_
#define _UNRAR_DLL_
+/* Added by Tomas Bzatek - GCC 4.3 compatibility */
+#define LPARAM LONG
+
#define ERAR_END_ARCHIVE 10
#define ERAR_NO_MEMORY 11
#define ERAR_BAD_DATA 12
@@ -15,8 +18,9 @@
#define ERAR_UNKNOWN 21
#define ERAR_MISSING_PASSWORD 22
-#define RAR_OM_LIST 0
-#define RAR_OM_EXTRACT 1
+#define RAR_OM_LIST 0
+#define RAR_OM_EXTRACT 1
+#define RAR_OM_LIST_INCSPLIT 2
#define RAR_SKIP 0
#define RAR_TEST 1
@@ -109,7 +113,7 @@ enum UNRARCALLBACK_MESSAGES {
UCM_CHANGEVOLUME,UCM_PROCESSDATA,UCM_NEEDPASSWORD
};
-typedef int (CALLBACK *UNRARCALLBACK)(UINT msg,LONG UserData,LONG P1,LONG P2);
+typedef int (CALLBACK *UNRARCALLBACK)(UINT msg,LPARAM UserData,LPARAM P1,LPARAM P2);
typedef int (PASCAL *CHANGEVOLPROC)(char *ArcName,int Mode);
typedef int (PASCAL *PROCESSDATAPROC)(unsigned char *Addr,int Size);
@@ -125,7 +129,7 @@ int PASCAL RARReadHeader(HANDLE hArcData,struct RARHeaderData *HeaderData);
int PASCAL RARReadHeaderEx(HANDLE hArcData,struct RARHeaderDataEx *HeaderData);
int PASCAL RARProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName);
int PASCAL RARProcessFileW(HANDLE hArcData,int Operation,wchar_t *DestPath,wchar_t *DestName);
-void PASCAL RARSetCallback(HANDLE hArcData,UNRARCALLBACK Callback,LONG UserData);
+void PASCAL RARSetCallback(HANDLE hArcData,UNRARCALLBACK Callback,LPARAM UserData);
void PASCAL RARSetChangeVolProc(HANDLE hArcData,CHANGEVOLPROC ChangeVolProc);
void PASCAL RARSetProcessDataProc(HANDLE hArcData,PROCESSDATAPROC ProcessDataProc);
void PASCAL RARSetPassword(HANDLE hArcData,char *Password);
diff --git a/unrar/unrar/errhnd.cpp b/unrar/unrar/errhnd.cpp
index 035eae9..2797f63 100644
--- a/unrar/unrar/errhnd.cpp
+++ b/unrar/unrar/errhnd.cpp
@@ -290,7 +290,8 @@ void _stdfunction ProcessSignal(int SigType)
ExtRes.UnloadDLL();
#endif
exit(USER_BREAK);
-#ifdef _WIN_32
+#if defined(_WIN_32) && !defined(_MSC_VER)
+ // never reached, just to avoid a compiler warning
return(TRUE);
#endif
}
diff --git a/unrar/unrar/errhnd.hpp b/unrar/unrar/errhnd.hpp
index 732243c..950a62c 100644
--- a/unrar/unrar/errhnd.hpp
+++ b/unrar/unrar/errhnd.hpp
@@ -12,6 +12,7 @@
#define rarrealloc realloc
#define rarfree free
#define rarstrdup strdup
+#define rarstrdupw strdupw
diff --git a/unrar/unrar/extract.cpp b/unrar/unrar/extract.cpp
index e9d7517..712dc90 100644
--- a/unrar/unrar/extract.cpp
+++ b/unrar/unrar/extract.cpp
@@ -25,6 +25,7 @@ void CmdExtract::DoExtract(CommandData *Cmd)
while (Cmd->GetArcName(ArcName,ArcNameW,sizeof(ArcName)))
if (FindFile::FastFind(ArcName,ArcNameW,&FD))
DataIO.TotalArcSize+=FD.Size;
+
Cmd->ArcNames->Rewind();
while (Cmd->GetArcName(ArcName,ArcNameW,sizeof(ArcName)))
{
@@ -35,10 +36,8 @@ void CmdExtract::DoExtract(CommandData *Cmd)
EXTRACT_ARC_CODE Code=ExtractArchive(Cmd);
-/*
- restore Cmd->Password which could be changed in IsArchive() call
- for next header encrypted archive
-*/
+ // restore Cmd->Password which could be changed in IsArchive() call
+ // for next header encrypted archive
strcpy(Cmd->Password,PrevCmdPassword);
if (Code!=EXTRACT_ARC_REPEAT)
@@ -90,6 +89,8 @@ void CmdExtract::ExtractArchiveInit(CommandData *Cmd,Archive &Arc)
SignatureFound=false;
AllMatchesExact=true;
ReconstructDone=false;
+
+ StartTime.SetCurrentTime();
}
@@ -112,6 +113,7 @@ EXTRACT_ARC_CODE CmdExtract::ExtractArchive(CommandData *Cmd)
return(EXTRACT_ARC_NEXT);
}
+ // archive with corrupt encrypted header can be closed in IsArchive() call
if (!Arc.IsOpened())
return(EXTRACT_ARC_NEXT);
@@ -119,13 +121,42 @@ EXTRACT_ARC_CODE CmdExtract::ExtractArchive(CommandData *Cmd)
if (Arc.Volume && Arc.NotFirstVolume)
{
char FirstVolName[NM];
-
VolNameToFirstName(ArcName,FirstVolName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING));
+
+ // If several volume names from same volume set are specified
+ // and current volume is not first in set and first volume is present
+ // and specified too, let's skip the current volume.
if (stricomp(ArcName,FirstVolName)!=0 && FileExist(FirstVolName) &&
Cmd->ArcNames->Search(FirstVolName,NULL,false))
return(EXTRACT_ARC_NEXT);
}
#endif
+
+ if (Arc.Volume)
+ {
+ // Calculate the total size of all accessible volumes.
+ // This size is necessary to display the correct total progress indicator.
+
+ char NextName[NM];
+ wchar NextNameW[NM];
+
+ strcpy(NextName,Arc.FileName);
+ strcpyw(NextNameW,Arc.FileNameW);
+
+ while (true)
+ {
+ // First volume is already added to DataIO.TotalArcSize
+ // in initial TotalArcSize calculation in DoExtract.
+ // So we skip it and start from second volume.
+ NextVolumeName(NextName,NextNameW,ASIZE(NextName),(Arc.NewMhd.Flags & MHD_NEWNUMBERING)==0 || Arc.OldFormat);
+ struct FindData FD;
+ if (FindFile::FastFind(NextName,NextNameW,&FD))
+ DataIO.TotalArcSize+=FD.Size;
+ else
+ break;
+ }
+ }
+
ExtractArchiveInit(Cmd,Arc);
if (*Cmd->Command=='T' || *Cmd->Command=='I')
@@ -174,7 +205,7 @@ bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize
#ifdef NOVOLUME
return(false);
#else
- if (!MergeArchive(Arc,NULL,false,Command))
+ if (!MergeArchive(Arc,&DataIO,false,Command))
{
ErrHandler.SetErrorCode(WARNING);
return(false);
@@ -206,7 +237,7 @@ bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize
if (Arc.EndArcHead.Flags & EARC_NEXT_VOLUME)
{
#ifndef NOVOLUME
- if (!MergeArchive(Arc,NULL,false,Command))
+ if (!MergeArchive(Arc,&DataIO,false,Command))
{
ErrHandler.SetErrorCode(WARNING);
return(false);
@@ -352,7 +383,7 @@ bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize
#ifdef RARDLL
Cmd->DllError=ERAR_BAD_DATA;
#endif
- ErrHandler.SetErrorCode(WARNING);
+ ErrHandler.SetErrorCode(OPEN_ERROR);
}
ExactMatch=false;
}
@@ -370,7 +401,7 @@ bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize
#ifdef RARDLL
if (*Cmd->Password==0)
if (Cmd->Callback==NULL ||
- Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LONG)Cmd->Password,sizeof(Cmd->Password))==-1)
+ Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LPARAM)Cmd->Password,sizeof(Cmd->Password))==-1)
return(false);
strcpy(Password,Cmd->Password);
@@ -488,7 +519,7 @@ bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize
if (Length>0)
{
wchar ArcPathW[NM];
- CharToWide(Cmd->ArcPath,ArcPathW);
+ GetWideName(Cmd->ArcPath,Cmd->ArcPathW,ArcPathW);
Length=strlenw(ArcPathW);
}
ExtrNameW+=Length;
@@ -518,7 +549,16 @@ bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize
if (FindFile::FastFind(DestFileName,DestNameW,&FD))
{
if (FD.mtime >= Arc.NewLhd.mtime)
- ExtrFile=false;
+ {
+ // If directory already exists and its modification time is newer
+ // than start of extraction, it is likely it was created
+ // when creating a path to one of already extracted items.
+ // In such case we'll better update its time even if archived
+ // directory is older.
+
+ if (!FD.IsDir || FD.mtime<StartTime)
+ ExtrFile=false;
+ }
}
else
if (Cmd->FreshFiles)
@@ -637,9 +677,9 @@ bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize
#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE)
if (Cmd->SetCompressedAttr &&
(Arc.NewLhd.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT())
- SetFileCompression(DestFileName,DestFileNameW,true);
+ SetFileCompression(DestFileName,DestNameW,true);
#endif
- SetDirTime(DestFileName,
+ SetDirTime(DestFileName,DestNameW,
Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime,
Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.NewLhd.ctime,
Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime);
diff --git a/unrar/unrar/extract.hpp b/unrar/unrar/extract.hpp
index 09dfc94..dcf4534 100644
--- a/unrar/unrar/extract.hpp
+++ b/unrar/unrar/extract.hpp
@@ -7,6 +7,7 @@ class CmdExtract
{
private:
EXTRACT_ARC_CODE ExtractArchive(CommandData *Cmd);
+ RarTime StartTime; // time when extraction started
ComprDataIO DataIO;
Unpack *Unp;
diff --git a/unrar/unrar/filcreat.cpp b/unrar/unrar/filcreat.cpp
index 175736a..c377dd6 100644
--- a/unrar/unrar/filcreat.cpp
+++ b/unrar/unrar/filcreat.cpp
@@ -30,7 +30,7 @@ bool FileCreate(RAROptions *Cmd,File *NewFile,char *Name,wchar *NameW,
#endif
if (Cmd->AllYes || Mode==OVERWRITE_ALL)
break;
- if (Mode==OVERWRITE_ASK)
+ if (Mode==OVERWRITE_DEFAULT || Mode==OVERWRITE_FORCE_ASK)
{
eprintf(St(MFileExists),Name);
int Choice=Ask(St(MYesNoAllRenQ));
@@ -88,7 +88,7 @@ bool FileCreate(RAROptions *Cmd,File *NewFile,char *Name,wchar *NameW,
*NameW=0;
}
else
- Mode=OVERWRITE_ASK;
+ Mode=OVERWRITE_DEFAULT;
continue;
}
}
diff --git a/unrar/unrar/file.cpp b/unrar/unrar/file.cpp
index a2c43b8..8fe71ec 100644
--- a/unrar/unrar/file.cpp
+++ b/unrar/unrar/file.cpp
@@ -135,14 +135,15 @@ bool File::WOpen(const char *Name,const wchar *NameW)
}
-bool File::Create(const char *Name,const wchar *NameW)
+bool File::Create(const char *Name,const wchar *NameW,bool ShareRead)
{
#ifdef _WIN_32
+ DWORD ShareMode=(ShareRead || File::OpenShared) ? FILE_SHARE_READ:0;
if (WinNT() && NameW!=NULL && *NameW!=0)
- hFile=CreateFileW(NameW,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,
+ hFile=CreateFileW(NameW,GENERIC_READ|GENERIC_WRITE,ShareMode,NULL,
CREATE_ALWAYS,0,NULL);
else
- hFile=CreateFile(Name,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,
+ hFile=CreateFile(Name,GENERIC_READ|GENERIC_WRITE,ShareMode,NULL,
CREATE_ALWAYS,0,NULL);
#else
hFile=fopen(Name,CREATEBINARY);
@@ -176,17 +177,17 @@ void File::AddFileToList(FileHandle hFile)
#if !defined(SHELL_EXT) && !defined(SFX_MODULE)
-void File::TCreate(const char *Name,const wchar *NameW)
+void File::TCreate(const char *Name,const wchar *NameW,bool ShareRead)
{
- if (!WCreate(Name,NameW))
+ if (!WCreate(Name,NameW,ShareRead))
ErrHandler.Exit(FATAL_ERROR);
}
#endif
-bool File::WCreate(const char *Name,const wchar *NameW)
+bool File::WCreate(const char *Name,const wchar *NameW,bool ShareRead)
{
- if (Create(Name,NameW))
+ if (Create(Name,NameW,ShareRead))
return(true);
ErrHandler.SetErrorCode(CREATE_ERROR);
ErrHandler.CreateErrorMsg(Name);
@@ -248,15 +249,21 @@ bool File::Delete()
}
-bool File::Rename(const char *NewName)
+bool File::Rename(const char *NewName,const wchar *NewNameW)
{
+ // we do not need to rename if names are already same
bool Success=strcmp(FileName,NewName)==0;
+ if (Success && *FileNameW!=0 && *NullToEmpty(NewNameW)!=0)
+ Success=strcmpw(FileNameW,NewNameW)==0;
+
if (!Success)
- Success=rename(FileName,NewName)==0;
+ Success=RenameFile(FileName,FileNameW,NewName,NewNameW);
+
if (Success)
{
+ // renamed successfully, storing the new name
strcpy(FileName,NewName);
- *FileNameW=0;
+ strcpyw(FileNameW,NullToEmpty(NewNameW));
}
return(Success);
}
@@ -288,11 +295,12 @@ void File::Write(const void *Data,int Size)
#endif
while (1)
{
- bool Success;
+ bool Success=false;
#ifdef _WIN_32
- DWORD Written;
+ DWORD Written=0;
if (HandleType!=FILE_HANDLENORMAL)
{
+ // writing to stdout can fail in old Windows if data block is too large
const int MaxSize=0x4000;
for (int I=0;I<Size;I+=MaxSize)
if (!(Success=WriteFile(hFile,(byte *)Data+I,Min(Size-I,MaxSize),&Written,NULL)))
@@ -333,7 +341,8 @@ void File::Write(const void *Data,int Size)
int File::Read(void *Data,int Size)
{
- Int64 FilePos;
+ Int64 FilePos=0; //initialized only to suppress some compilers warning
+
if (IgnoreReadErrors)
FilePos=Tell();
int ReadSize;
diff --git a/unrar/unrar/file.hpp b/unrar/unrar/file.hpp
index afa9529..e5f768c 100644
--- a/unrar/unrar/file.hpp
+++ b/unrar/unrar/file.hpp
@@ -56,13 +56,13 @@ class File
bool Open(const char *Name,const wchar *NameW=NULL,bool OpenShared=false,bool Update=false);
void TOpen(const char *Name,const wchar *NameW=NULL);
bool WOpen(const char *Name,const wchar *NameW=NULL);
- bool Create(const char *Name,const wchar *NameW=NULL);
- void TCreate(const char *Name,const wchar *NameW=NULL);
- bool WCreate(const char *Name,const wchar *NameW=NULL);
+ bool Create(const char *Name,const wchar *NameW=NULL,bool ShareRead=true);
+ void TCreate(const char *Name,const wchar *NameW=NULL,bool ShareRead=true);
+ bool WCreate(const char *Name,const wchar *NameW=NULL,bool ShareRead=true);
bool Close();
void Flush();
bool Delete();
- bool Rename(const char *NewName);
+ bool Rename(const char *NewName,const wchar *NewNameW=NULL);
void Write(const void *Data,int Size);
int Read(void *Data,int Size);
int DirectRead(void *Data,int Size);
diff --git a/unrar/unrar/filefn.cpp b/unrar/unrar/filefn.cpp
index 1c43eae..54b0b99 100644
--- a/unrar/unrar/filefn.cpp
+++ b/unrar/unrar/filefn.cpp
@@ -109,7 +109,7 @@ bool CreatePath(const char *Path,const wchar *PathW,bool SkipLastName)
}
-void SetDirTime(const char *Name,RarTime *ftm,RarTime *ftc,RarTime *fta)
+void SetDirTime(const char *Name,const wchar *NameW,RarTime *ftm,RarTime *ftc,RarTime *fta)
{
#ifdef _WIN_32
if (!WinNT())
@@ -119,11 +119,14 @@ void SetDirTime(const char *Name,RarTime *ftm,RarTime *ftc,RarTime *fta)
bool sc=ftc!=NULL && ftc->IsSet();
bool sa=fta!=NULL && fta->IsSet();
- unsigned int DirAttr=GetFileAttr(Name);
+ unsigned int DirAttr=GetFileAttr(Name,NameW);
bool ResetAttr=(DirAttr!=0xffffffff && (DirAttr & FA_RDONLY)!=0);
if (ResetAttr)
- SetFileAttr(Name,NULL,0);
- HANDLE hFile=CreateFile(Name,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
+ SetFileAttr(Name,NameW,0);
+
+ wchar DirNameW[NM];
+ GetWideName(Name,NameW,DirNameW);
+ HANDLE hFile=CreateFileW(DirNameW,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
if (hFile==INVALID_HANDLE_VALUE)
return;
@@ -137,7 +140,7 @@ void SetDirTime(const char *Name,RarTime *ftm,RarTime *ftc,RarTime *fta)
SetFileTime(hFile,sc ? &fc:NULL,sa ? &fa:NULL,sm ? &fm:NULL);
CloseHandle(hFile);
if (ResetAttr)
- SetFileAttr(Name,NULL,DirAttr);
+ SetFileAttr(Name,NameW,DirAttr);
#endif
#if defined(_UNIX) || defined(_EMX)
File::SetCloseFileTimeByName(Name,ftm,fta);
@@ -455,7 +458,7 @@ void ConvertNameToFull(const wchar *Src,wchar *Dest)
#ifndef SFX_MODULE
char *MkTemp(char *Name)
{
- int Length=strlen(Name);
+ size_t Length=strlen(Name);
if (Length<=6)
return(NULL);
int Random=clock();
@@ -568,3 +571,9 @@ bool SetFileCompression(char *Name,wchar *NameW,bool State)
return(RetCode!=0);
}
#endif
+
+
+
+
+
+
diff --git a/unrar/unrar/filefn.hpp b/unrar/unrar/filefn.hpp
index ec6cba5..cd8e3fc 100644
--- a/unrar/unrar/filefn.hpp
+++ b/unrar/unrar/filefn.hpp
@@ -5,7 +5,7 @@ enum MKDIR_CODE {MKDIR_SUCCESS,MKDIR_ERROR,MKDIR_BADPATH};
MKDIR_CODE MakeDir(const char *Name,const wchar *NameW,uint Attr);
bool CreatePath(const char *Path,const wchar *PathW,bool SkipLastName);
-void SetDirTime(const char *Name,RarTime *ftm,RarTime *ftc,RarTime *fta);
+void SetDirTime(const char *Name,const wchar *NameW,RarTime *ftm,RarTime *ftc,RarTime *fta);
bool IsRemovable(const char *Name);
Int64 GetFreeDisk(const char *Name);
bool FileExist(const char *Name,const wchar *NameW=NULL);
@@ -38,4 +38,7 @@ bool DelDir(const char *Name,const wchar *NameW);
bool SetFileCompression(char *Name,wchar *NameW,bool State);
#endif
+
+
+
#endif
diff --git a/unrar/unrar/filestr.cpp b/unrar/unrar/filestr.cpp
index 55e79a1..c7217af 100644
--- a/unrar/unrar/filestr.cpp
+++ b/unrar/unrar/filestr.cpp
@@ -3,7 +3,8 @@
static bool IsUnicode(byte *Data,int Size);
bool ReadTextFile(char *Name,StringList *List,bool Config,bool AbortOnError,
- RAR_CHARSET SrcCharset,bool Unquote,bool SkipComments)
+ RAR_CHARSET SrcCharset,bool Unquote,bool SkipComments,
+ bool ExpandEnvStr)
{
char FileName[NM];
if (Config)
@@ -79,7 +80,28 @@ bool ReadTextFile(char *Name,StringList *List,bool Config,bool AbortOnError,
CurStr++;
}
WideToChar(CurStr,&AnsiName[0],AnsiName.Size());
- List->AddString(&AnsiName[0],CurStr);
+
+ bool Expanded=false;
+#if defined(_WIN_32) && !defined(_WIN_CE)
+ if (ExpandEnvStr && *CurStr=='%')
+ {
+ // expanding environment variables in Windows version
+
+ char ExpName[NM];
+ wchar ExpNameW[NM];
+ *ExpNameW=0;
+ int ret,retw=1;
+ ret=ExpandEnvironmentStrings(&AnsiName[0],ExpName,ASIZE(ExpName));
+ if (ret!=0 && WinNT())
+ retw=ExpandEnvironmentStringsW(CurStr,ExpNameW,ASIZE(ExpNameW));
+ Expanded=ret!=0 && ret<ASIZE(ExpName) &&
+ retw!=0 && retw<ASIZE(ExpNameW);
+ if (Expanded)
+ List->AddString(ExpName,ExpNameW);
+ }
+#endif
+ if (!Expanded)
+ List->AddString(&AnsiName[0],CurStr);
}
CurStr=NextStr+1;
while (*CurStr=='\r' || *CurStr=='\n')
@@ -112,7 +134,7 @@ bool ReadTextFile(char *Name,StringList *List,bool Config,bool AbortOnError,
{
if (Unquote && *CurStr=='\"')
{
- int Length=strlen(CurStr);
+ size_t Length=strlen(CurStr);
if (CurStr[Length-1]=='\"')
{
CurStr[Length-1]=0;
@@ -123,7 +145,22 @@ bool ReadTextFile(char *Name,StringList *List,bool Config,bool AbortOnError,
if (SrcCharset==RCH_OEM)
OemToChar(CurStr,CurStr);
#endif
- List->AddString(CurStr);
+
+ bool Expanded=false;
+#if defined(_WIN_32) && !defined(_WIN_CE)
+ if (ExpandEnvStr && *CurStr=='%')
+ {
+ // expanding environment variables in Windows version
+
+ char ExpName[NM];
+ int ret=ExpandEnvironmentStrings(CurStr,ExpName,ASIZE(ExpName));
+ Expanded=ret!=0 && ret<ASIZE(ExpName);
+ if (Expanded)
+ List->AddString(ExpName);
+ }
+#endif
+ if (!Expanded)
+ List->AddString(CurStr);
}
CurStr=NextStr+1;
while (*CurStr=='\r' || *CurStr=='\n')
diff --git a/unrar/unrar/filestr.hpp b/unrar/unrar/filestr.hpp
index 43ce417..927711b 100644
--- a/unrar/unrar/filestr.hpp
+++ b/unrar/unrar/filestr.hpp
@@ -3,6 +3,7 @@
bool ReadTextFile(char *Name,StringList *List,bool Config,
bool AbortOnError=false,RAR_CHARSET SrcCharset=RCH_DEFAULT,
- bool Unquote=false,bool SkipComments=false);
+ bool Unquote=false,bool SkipComments=false,
+ bool ExpandEnvStr=false);
#endif
diff --git a/unrar/unrar/find.cpp b/unrar/unrar/find.cpp
index 9885ee6..50a0af6 100644
--- a/unrar/unrar/find.cpp
+++ b/unrar/unrar/find.cpp
@@ -4,7 +4,7 @@ FindFile::FindFile()
{
*FindMask=0;
*FindMaskW=0;
- FirstCall=TRUE;
+ FirstCall=true;
#ifdef _WIN_32
hFind=INVALID_HANDLE_VALUE;
#else
@@ -30,7 +30,7 @@ void FindFile::SetMask(const char *FindMask)
strcpy(FindFile::FindMask,FindMask);
if (*FindMaskW==0)
CharToWide(FindMask,FindMaskW);
- FirstCall=TRUE;
+ FirstCall=true;
}
@@ -41,7 +41,7 @@ void FindFile::SetMaskW(const wchar *FindMaskW)
strcpyw(FindFile::FindMaskW,FindMaskW);
if (*FindMask==0)
WideToChar(FindMaskW,FindMask);
- FirstCall=TRUE;
+ FirstCall=true;
}
@@ -120,8 +120,9 @@ bool FindFile::Next(struct FindData *fd,bool GetSymLink)
CharToWide(fd->Name,fd->NameW);
#endif
#endif
+ fd->Flags=0;
fd->IsDir=IsDir(fd->FileAttr);
- FirstCall=FALSE;
+ FirstCall=false;
char *Name=PointToName(fd->Name);
if (strcmp(Name,".")==0 || strcmp(Name,"..")==0)
return(Next(fd));
@@ -185,6 +186,7 @@ bool FindFile::FastFind(const char *FindMask,const wchar *FindMaskW,struct FindD
CharToWide(fd->Name,fd->NameW);
#endif
#endif
+ fd->Flags=0;
fd->IsDir=IsDir(fd->FileAttr);
return(true);
}
@@ -290,6 +292,7 @@ HANDLE FindFile::Win32Find(HANDLE hFind,const char *Mask,const wchar *MaskW,stru
}
}
#endif
+ fd->Flags=0;
return(hFind);
}
#endif
diff --git a/unrar/unrar/find.hpp b/unrar/unrar/find.hpp
index 8154819..3320d50 100644
--- a/unrar/unrar/find.hpp
+++ b/unrar/unrar/find.hpp
@@ -1,6 +1,10 @@
#ifndef _RAR_FINDDATA_
#define _RAR_FINDDATA_
+enum FINDDATA_FLAGS {
+ FDDF_SECONDDIR=1 // second entry of directory in SCAN_GETDIRSTWICE ScanTree mode
+};
+
struct FindData
{
char Name[NM];
@@ -18,6 +22,7 @@ struct FindData
FILETIME ftLastAccessTime;
FILETIME ftLastWriteTime;
#endif
+ uint Flags;
bool Error;
};
@@ -30,7 +35,7 @@ class FindFile
char FindMask[NM];
wchar FindMaskW[NM];
- int FirstCall;
+ bool FirstCall;
#ifdef _WIN_32
HANDLE hFind;
#else
diff --git a/unrar/unrar/headers.hpp b/unrar/unrar/headers.hpp
index acf597d..94e8aa0 100644
--- a/unrar/unrar/headers.hpp
+++ b/unrar/unrar/headers.hpp
@@ -65,9 +65,9 @@
#define LONG_BLOCK 0x8000
#define EARC_NEXT_VOLUME 0x0001 // not last volume
-#define EARC_DATACRC 0x0002
-#define EARC_REVSPACE 0x0004
-#define EARC_VOLNUMBER 0x0008
+#define EARC_DATACRC 0x0002 // store CRC32 of RAR archive (now used only in volumes)
+#define EARC_REVSPACE 0x0004 // reserve space for end of REV file 7 byte record
+#define EARC_VOLNUMBER 0x0008 // store a number of current volume
enum HEADER_TYPE {
MARK_HEAD=0x72,MAIN_HEAD=0x73,FILE_HEAD=0x74,COMM_HEAD=0x75,AV_HEAD=0x76,
@@ -218,11 +218,13 @@ struct FileHeader:BlockHeader
struct EndArcHeader:BaseBlock
{
- uint ArcDataCRC;
- ushort VolNumber;
+ uint ArcDataCRC; // optional archive CRC32
+ ushort VolNumber; // optional current volume number
};
+// SubBlockHeader and its successors were used in RAR 2.x format.
+// RAR 3.x uses FileHeader with NEWSUB_HEAD HeadType for subblocks.
struct SubBlockHeader:BlockHeader
{
ushort SubType;
diff --git a/unrar/unrar/list.cpp b/unrar/unrar/list.cpp
index d569006..99d730f 100644
--- a/unrar/unrar/list.cpp
+++ b/unrar/unrar/list.cpp
@@ -270,13 +270,20 @@ void ListFileHeader(FileHeader &hd,bool Verbose,bool Technical,bool &TitleShown,
void ListSymLink(Archive &Arc)
{
if (Arc.NewLhd.HostOS==HOST_UNIX && (Arc.NewLhd.FileAttr & 0xF000)==0xA000)
- {
- char FileName[NM];
- int DataSize=Min(Arc.NewLhd.PackSize,sizeof(FileName)-1);
- Arc.Read(FileName,DataSize);
- FileName[DataSize]=0;
- mprintf("\n%22s %s","-->",FileName);
- }
+ if ((Arc.NewLhd.Flags & LHD_PASSWORD)==0)
+ {
+ char FileName[NM];
+ int DataSize=Min(Arc.NewLhd.PackSize,sizeof(FileName)-1);
+ Arc.Read(FileName,DataSize);
+ FileName[DataSize]=0;
+ mprintf("\n%22s %s","-->",FileName);
+ }
+ else
+ {
+ // Link data are encrypted. We would need to ask for password
+ // and initialize decryption routine to display the link target.
+ mprintf("\n%22s %s","-->","*<-?->");
+ }
}
diff --git a/unrar/unrar/loclang.hpp b/unrar/unrar/loclang.hpp
index c425bb3..37da3a0 100644
--- a/unrar/unrar/loclang.hpp
+++ b/unrar/unrar/loclang.hpp
@@ -1,5 +1,6 @@
#define MYesNo "_Yes_No"
#define MYesNoAll "_Yes_No_All"
+#define MYesNoAllQ "_Yes_No_All_nEver_Quit"
#define MYesNoAllRenQ "_Yes_No_All_nEver_Rename_Quit"
#define MContinueQuit "_Continue_Quit"
#define MRetryAbort "_Retry_Abort"
@@ -63,7 +64,9 @@
#define MCHelpSwCU "\n cu Convert names to upper case"
#define MCHelpSwDF "\n df Delete files after archiving"
#define MCHelpSwDH "\n dh Open shared files"
+#define MCHelpSwDR "\n dr Delete files to Recycle Bin"
#define MCHelpSwDS "\n ds Disable name sort for solid archive"
+#define MCHelpSwDW "\n dw Wipe files after archiving"
#define MCHelpSwEa "\n e[+]<attr> Set file exclude and include attributes"
#define MCHelpSwED "\n ed Do not add empty directories"
#define MCHelpSwEE "\n ee Do not save and extract extended attributes"
@@ -91,8 +94,7 @@
#define MCHelpSwN "\n n<file> Include only specified file"
#define MCHelpSwNa "\n n@ Read file names to include from stdin"
#define MCHelpSwNal "\n n@<list> Include files in specified list file"
-#define MCHelpSwOp "\n o+ Overwrite existing files"
-#define MCHelpSwOm "\n o- Do not overwrite existing files"
+#define MCHelpSwO "\n o[+|-] Set the overwrite mode"
#define MCHelpSwOC "\n oc Set NTFS Compressed attribute"
#define MCHelpSwOL "\n ol Save symbolic links as the link instead of the file"
#define MCHelpSwOR "\n or Rename files automatically"
@@ -347,3 +349,4 @@
#define MCannotDelete "\nCannot delete %s"
#define MCalcCRC "\nCalculating the control sum"
#define MTooLargeSFXArc "\nWARNING: Too large SFX archive. Windows cannot run the executable file exceeding 4 GB."
+#define MCalcCRCAllVol "\nCalculating control sums of all volumes."
diff --git a/unrar/unrar/makefile.unix b/unrar/unrar/makefile.unix
index f2a7dcf..d22ed58 100644
--- a/unrar/unrar/makefile.unix
+++ b/unrar/unrar/makefile.unix
@@ -10,30 +10,35 @@ CXX=g++
CXXFLAGS=-O2
DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
STRIP=strip
+DESTDIR=/usr
# Linux using LCC
#CXX=lcc
#CXXFLAGS=-O2
#DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
#STRIP=strip
+#DESTDIR=/usr
# HP UX using aCC
#CXX=aCC
#CXXFLAGS=-AA +O2 +Onolimit
#DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
#STRIP=strip
+#DESTDIR=/usr
# IRIX using GCC
#CXX=g++
#CXXFLAGS=-O2
#DEFINES=-DBIG_ENDIAN -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_BSD_COMPAT -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED=1
#STRIP=strip
+#DESTDIR=/usr
# IRIX using MIPSPro (experimental)
#CXX=CC
#CXXFLAGS=-O2 -mips3 -woff 1234,1156,3284 -LANG:std
#DEFINES=-DBIG_ENDIAN -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_BSD_COMPAT -DNATIVE_INT64 -DInt64=int64_t
#STRIP=strip
+#DESTDIR=/usr
# AIX using xlC (IBM VisualAge C++ 5.0)
#CXX=xlC
@@ -41,36 +46,42 @@ STRIP=strip
#DEFINES=-D_LARGE_FILES -D_LARGE_FILE_API
#LIBS=-lbsd
#STRIP=strip
+#DESTDIR=/usr
# Solaris using CC (SUN Forte Developer 7 C++)
#CXX=CC
#CXXFLAGS=-xO2 -xbuiltin=%all -xinline=%auto
#DEFINES=-DBIG_ENDIAN -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
#STRIP=strip
+#DESTDIR=/usr
# Solaris using GCC (optimized for UltraSPARC 1 CPU)
#CXX=g++
#CXXFLAGS=-O3 -mcpu=v9 -mtune=ultrasparc -m32
#DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
#STRIP=/usr/ccs/bin/strip
+#DESTDIR=/usr
# Tru64 5.1B using GCC3
#CXX=g++
#CXXFLAGS=-O2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_XOPEN_SOURCE=500
#STRIP=strip
#LDFLAGS=-rpath /usr/local/gcc/lib
+#DESTDIR=/usr
# Tru64 5.1B using DEC C++
#CXX=cxx
#CXXFLAGS=-O4 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -DNATIVE_INT64 -DInt64=long
#STRIP=strip
#LDFLAGS=
+#DESTDIR=/usr
# QNX 6.x using GCC
#CXX=g++
#CXXFLAGS=-O2 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -fexceptions
#STRIP=strip
#LDFLAGS=-fexceptions
+#DESTDIR=/usr
# Cross-compile
# Linux using arm-linux-g++
@@ -79,6 +90,7 @@ STRIP=strip
#DEFINES=-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE
#STRIP=arm-linux-strip
#LDFLAGS=-static
+#DESTDIR=/usr
##########################
@@ -98,6 +110,10 @@ OBJECTS=rar.o strlist.o strfn.o pathfn.o int64.o savepos.o global.o file.o filef
all: unrar
+install: install-unrar
+
+uninstall: uninstall-unrar
+
clean:
@rm -f *.o *.bak *~
@@ -117,3 +133,15 @@ lib: WHAT=RARDLL
lib: $(OBJECTS) $(LIB_OBJ)
@rm -f libunrar.so
$(LINK) -shared -o libunrar.so $(LDFLAGS) $(OBJECTS) $(LIB_OBJ)
+
+install-unrar:
+ install unrar $(DESTDIR)/bin
+
+uninstall-unrar:
+ rm -f $(DESTDIR)/bin/unrar
+
+install-lib:
+ install libunrar.so $(DESTDIR)/lib
+
+uninstall-lib:
+ rm -f $(DESTDIR)/lib/libunrar.so
diff --git a/unrar/unrar/match.cpp b/unrar/unrar/match.cpp
index de03fb4..bd1c02f 100644
--- a/unrar/unrar/match.cpp
+++ b/unrar/unrar/match.cpp
@@ -5,15 +5,15 @@ static bool match(wchar *pattern,wchar *string,bool ForceCase);
static int mstricompc(const char *Str1,const char *Str2,bool ForceCase);
static int mstricompcw(const wchar *Str1,const wchar *Str2,bool ForceCase);
-static int mstrnicompc(const char *Str1,const char *Str2,int N,bool ForceCase);
-static int mstrnicompcw(const wchar *Str1,const wchar *Str2,int N,bool ForceCase);
+static int mstrnicompc(const char *Str1,const char *Str2,size_t N,bool ForceCase);
+static int mstrnicompcw(const wchar *Str1,const wchar *Str2,size_t N,bool ForceCase);
inline uint toupperc(byte ch,bool ForceCase)
{
if (ForceCase)
return(ch);
#ifdef _WIN_32
- return((uint)CharUpper((LPTSTR)(ch)));
+ return((uint)(LPARAM)CharUpper((LPTSTR)(ch)));
#elif defined(_UNIX)
return(ch);
#else
@@ -42,7 +42,7 @@ bool CmpName(char *Wildcard,char *Name,int CmpPath)
if (CmpPath!=MATCH_NAMES)
{
- int WildLength=strlen(Wildcard);
+ size_t WildLength=strlen(Wildcard);
if (CmpPath!=MATCH_EXACTPATH && mstrnicompc(Wildcard,Name,WildLength,ForceCase)==0)
{
char NextCh=Name[WildLength];
@@ -71,8 +71,12 @@ bool CmpName(char *Wildcard,char *Name,int CmpPath)
}
char *Name1=PointToName(Wildcard);
char *Name2=PointToName(Name);
+
+ // always return false for RAR temporary files to exclude them
+ // from archiving operations
if (mstrnicompc("__rar_",Name2,6,false)==0)
return(false);
+
return(match(Name1,Name2,ForceCase));
}
@@ -86,7 +90,7 @@ bool CmpName(wchar *Wildcard,wchar *Name,int CmpPath)
if (CmpPath!=MATCH_NAMES)
{
- int WildLength=strlenw(Wildcard);
+ size_t WildLength=strlenw(Wildcard);
if (CmpPath!=MATCH_EXACTPATH && mstrnicompcw(Wildcard,Name,WildLength,ForceCase)==0)
{
wchar NextCh=Name[WildLength];
@@ -113,8 +117,12 @@ bool CmpName(wchar *Wildcard,wchar *Name,int CmpPath)
}
wchar *Name1=PointToName(Wildcard);
wchar *Name2=PointToName(Name);
+
+ // always return false for RAR temporary files to exclude them
+ // from archiving operations
if (mstrnicompcw(L"__rar_",Name2,6,false)==0)
return(false);
+
return(match(Name1,Name2,ForceCase));
}
#endif
@@ -236,7 +244,7 @@ int mstricompcw(const wchar *Str1,const wchar *Str2,bool ForceCase)
#endif
-int mstrnicompc(const char *Str1,const char *Str2,int N,bool ForceCase)
+int mstrnicompc(const char *Str1,const char *Str2,size_t N,bool ForceCase)
{
if (ForceCase)
return(strncmp(Str1,Str2,N));
@@ -249,7 +257,7 @@ int mstrnicompc(const char *Str1,const char *Str2,int N,bool ForceCase)
#ifndef SFX_MODULE
-int mstrnicompcw(const wchar *Str1,const wchar *Str2,int N,bool ForceCase)
+int mstrnicompcw(const wchar *Str1,const wchar *Str2,size_t N,bool ForceCase)
{
if (ForceCase)
return(strncmpw(Str1,Str2,N));
diff --git a/unrar/unrar/match.hpp b/unrar/unrar/match.hpp
index 5ea6115..0e43514 100644
--- a/unrar/unrar/match.hpp
+++ b/unrar/unrar/match.hpp
@@ -1,7 +1,22 @@
#ifndef _RAR_MATCH_
#define _RAR_MATCH_
-enum {MATCH_NAMES,MATCH_PATH,MATCH_EXACTPATH,MATCH_SUBPATH,MATCH_WILDSUBPATH};
+enum {
+ MATCH_NAMES, // Compare names only.
+
+ MATCH_PATH, // Compares names and paths. Both must match exactly.
+ // Unlike MATCH_EXACTPATH, also matches names if
+ // mask contains path only and this path is a part
+ // of name path.
+
+ MATCH_EXACTPATH, // Compares names and paths. Both must match exactly.
+
+ MATCH_SUBPATH, // Names must be the same, but path in mask is allowed
+ // to be only a part of name path.
+
+ MATCH_WILDSUBPATH // Works as MATCH_SUBPATH if mask contains wildcards
+ // and as MATCH_PATH otherwise.
+};
#define MATCH_MODEMASK 0x0000ffff
#define MATCH_FORCECASESENSITIVE 0x80000000
diff --git a/unrar/unrar/options.cpp b/unrar/unrar/options.cpp
index e6efb42..57ca92f 100644
--- a/unrar/unrar/options.cpp
+++ b/unrar/unrar/options.cpp
@@ -16,7 +16,7 @@ void RAROptions::Init()
{
memset(this,0,sizeof(RAROptions));
WinSize=0x400000;
- Overwrite=OVERWRITE_ASK;
+ Overwrite=OVERWRITE_DEFAULT;
Method=3;
MsgStream=MSG_STDOUT;
ConvertNames=NAMES_ORIGINALCASE;
diff --git a/unrar/unrar/options.hpp b/unrar/unrar/options.hpp
index cc2db48..8af0e8b 100644
--- a/unrar/unrar/options.hpp
+++ b/unrar/unrar/options.hpp
@@ -17,8 +17,13 @@ enum EXTTIME_MODE {
};
enum {NAMES_ORIGINALCASE,NAMES_UPPERCASE,NAMES_LOWERCASE};
enum MESSAGE_TYPE {MSG_STDOUT,MSG_STDERR,MSG_ERRONLY,MSG_NULL};
+
enum OVERWRITE_MODE {
- OVERWRITE_ASK,OVERWRITE_ALL,OVERWRITE_NONE,OVERWRITE_AUTORENAME
+ OVERWRITE_DEFAULT, // ask for extraction, silently overwrite for archiving
+ OVERWRITE_ALL,
+ OVERWRITE_NONE,
+ OVERWRITE_AUTORENAME,
+ OVERWRITE_FORCE_ASK
};
enum RAR_CHARSET { RCH_DEFAULT=0,RCH_ANSI,RCH_OEM,RCH_UNICODE };
@@ -54,6 +59,7 @@ class RAROptions
RAR_CHARSET CommentCharset;
RAR_CHARSET FilelistCharset;
char ArcPath[NM];
+ wchar ArcPathW[NM];
char Password[MAXPASSWORD];
bool EncryptHeaders;
char LogName[NM];
@@ -133,7 +139,7 @@ class RAROptions
wchar DllDestNameW[NM];
int DllOpMode;
int DllError;
- LONG UserData;
+ LPARAM UserData;
UNRARCALLBACK Callback;
CHANGEVOLPROC ChangeVolProc;
PROCESSDATAPROC ProcessDataProc;
diff --git a/unrar/unrar/os.hpp b/unrar/unrar/os.hpp
index 453b9b0..fbcf3a0 100644
--- a/unrar/unrar/os.hpp
+++ b/unrar/unrar/os.hpp
@@ -33,6 +33,7 @@
#include <prsht.h>
#ifndef _WIN_CE
+ #include <shellapi.h>
#include <shlobj.h>
#include <winioctl.h>
#endif
@@ -213,7 +214,7 @@
#endif
-typedef const char* MSGID;
+ typedef const char* MSGID;
#define safebuf static
diff --git a/unrar/unrar/pathfn.cpp b/unrar/unrar/pathfn.cpp
index e635d16..3621916 100644
--- a/unrar/unrar/pathfn.cpp
+++ b/unrar/unrar/pathfn.cpp
@@ -29,6 +29,8 @@ char* PointToLastChar(const char *Path)
}
+
+
char* ConvertPath(const char *SrcPath,char *DestPath)
{
const char *DestPtr=SrcPath;
@@ -325,6 +327,26 @@ void GetAppDataPath(char *Path)
#endif
+#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE)
+void GetRarDataPath(char *Path)
+{
+ *Path=0;
+
+ HKEY hKey;
+ if (RegOpenKeyEx(HKEY_CURRENT_USER,"Software\\WinRAR\\Paths",0,
+ KEY_QUERY_VALUE,&hKey)==ERROR_SUCCESS)
+ {
+ DWORD DataSize=NM,Type;
+ RegQueryValueEx(hKey,"AppData",0,&Type,(BYTE *)Path,&DataSize);
+ RegCloseKey(hKey);
+ }
+
+ if (*Path==0 || !FileExist(Path))
+ GetAppDataPath(Path);
+}
+#endif
+
+
#ifndef SFX_MODULE
bool EnumConfigPaths(char *Path,int Number)
{
@@ -348,18 +370,16 @@ bool EnumConfigPaths(char *Path,int Number)
RemoveNameFromPath(Path);
return(true);
#elif defined(_UNIX)
+ static const char *AltPath[]={
+ "/etc","/etc/rar","/usr/lib","/usr/local/lib","/usr/local/etc"
+ };
if (Number==0)
{
char *EnvStr=getenv("HOME");
- if (EnvStr==NULL)
- return(false);
- strncpy(Path,EnvStr,NM-1);
+ strncpy(Path, (EnvStr==NULL) ? AltPath[0] : EnvStr, NM-1);
Path[NM-1]=0;
return(true);
}
- static const char *AltPath[]={
- "/etc","/etc/rar","/usr/lib","/usr/local/lib","/usr/local/etc"
- };
Number--;
if (Number<0 || Number>=sizeof(AltPath)/sizeof(AltPath[0]))
return(false);
@@ -370,7 +390,7 @@ bool EnumConfigPaths(char *Path,int Number)
if (Number<0 || Number>1)
return(false);
if (Number==0)
- GetAppDataPath(Path);
+ GetRarDataPath(Path);
else
{
GetModuleFileName(NULL,Path,NM);
@@ -388,6 +408,7 @@ bool EnumConfigPaths(char *Path,int Number)
#ifndef SFX_MODULE
void GetConfigName(const char *Name,char *FullName,bool CheckExist)
{
+ *FullName=0;
for (int I=0;EnumConfigPaths(FullName,I);I++)
{
AddEndSlash(FullName);
@@ -423,7 +444,7 @@ char* GetVolNumPart(char *ArcName)
}
-void NextVolumeName(char *ArcName,bool OldNumbering)
+void NextVolumeName(char *ArcName,wchar *ArcNameW,uint MaxLength,bool OldNumbering)
{
char *ChPtr;
if ((ChPtr=GetExt(ArcName))==NULL)
@@ -469,6 +490,29 @@ void NextVolumeName(char *ArcName,bool OldNumbering)
ChPtr--;
}
}
+ if (ArcNameW!=NULL && *ArcNameW!=0)
+ {
+ // Copy incremented trailing low ASCII volume name part to Unicode name.
+ // It is simpler than implementing Unicode version of entire function.
+ char *NumPtr=GetVolNumPart(ArcName);
+
+ // moving to first digit in volume number
+ while (NumPtr>ArcName && isdigit(*NumPtr) && isdigit(*(NumPtr-1)))
+ NumPtr--;
+
+ // also copy the first character before volume number,
+ // because it can be changed when going from .r99 to .s00
+ if (NumPtr>ArcName)
+ NumPtr--;
+
+ int CharsToCopy=strlen(ArcName)-(NumPtr-ArcName);
+ int DestPos=strlenw(ArcNameW)-CharsToCopy;
+ if (DestPos>0)
+ {
+ CharToWide(NumPtr,ArcNameW+DestPos,MaxLength-DestPos-1);
+ ArcNameW[MaxLength-1]=0;
+ }
+ }
}
@@ -579,7 +623,22 @@ bool IsFullPath(const char *Path)
{
char PathOnly[NM];
GetFilePath(Path,PathOnly,ASIZE(PathOnly));
- if (IsWildcard(PathOnly))
+ if (IsWildcard(PathOnly,NULL))
+ return(true);
+#if defined(_WIN_32) || defined(_EMX)
+ return(Path[0]=='\\' && Path[1]=='\\' ||
+ IsDiskLetter(Path) && IsPathDiv(Path[2]));
+#else
+ return(IsPathDiv(Path[0]));
+#endif
+}
+
+
+bool IsFullPath(const wchar *Path)
+{
+ wchar PathOnly[NM];
+ GetFilePath(Path,PathOnly,ASIZE(PathOnly));
+ if (IsWildcard(NULL,PathOnly))
return(true);
#if defined(_WIN_32) || defined(_EMX)
return(Path[0]=='\\' && Path[1]=='\\' ||
@@ -597,6 +656,13 @@ bool IsDiskLetter(const char *Path)
}
+bool IsDiskLetter(const wchar *Path)
+{
+ int Letter=etoupper(Path[0]);
+ return(Letter>='A' && Letter<='Z' && IsDriveDiv(Path[1]));
+}
+
+
void GetPathRoot(const char *Path,char *Root)
{
*Root=0;
@@ -608,7 +674,7 @@ void GetPathRoot(const char *Path,char *Root)
const char *Slash=strchr(Path+2,'\\');
if (Slash!=NULL)
{
- int Length;
+ size_t Length;
if ((Slash=strchr(Slash+1,'\\'))!=NULL)
Length=Slash-Path+1;
else
diff --git a/unrar/unrar/pathfn.hpp b/unrar/unrar/pathfn.hpp
index 6975993..6b0ac31 100644
--- a/unrar/unrar/pathfn.hpp
+++ b/unrar/unrar/pathfn.hpp
@@ -24,17 +24,20 @@ void GetFilePath(const wchar *FullName,wchar *Path,int MaxLength);
void RemoveNameFromPath(char *Path);
void RemoveNameFromPath(wchar *Path);
void GetAppDataPath(char *Path);
+void GetRarDataPath(char *Path);
bool EnumConfigPaths(char *Path,int Number);
void GetConfigName(const char *Name,char *FullName,bool CheckExist);
char* GetVolNumPart(char *ArcName);
-void NextVolumeName(char *ArcName,bool OldNumbering);
+void NextVolumeName(char *ArcName,wchar *ArcNameW,uint MaxLength,bool OldNumbering);
bool IsNameUsable(const char *Name);
void MakeNameUsable(char *Name,bool Extended);
char* UnixSlashToDos(char *SrcName,char *DestName=NULL,uint MaxLength=NM);
char* DosSlashToUnix(char *SrcName,char *DestName=NULL,uint MaxLength=NM);
wchar* UnixSlashToDos(wchar *SrcName,wchar *DestName=NULL,uint MaxLength=NM);
bool IsFullPath(const char *Path);
+bool IsFullPath(const wchar *Path);
bool IsDiskLetter(const char *Path);
+bool IsDiskLetter(const wchar *Path);
void GetPathRoot(const char *Path,char *Root);
int ParseVersionFileName(char *Name,wchar *NameW,bool Truncate);
char* VolNameToFirstName(const char *VolName,char *FirstName,bool NewNumbering);
diff --git a/unrar/unrar/rdwrfn.cpp b/unrar/unrar/rdwrfn.cpp
index 2454377..2662bdb 100644
--- a/unrar/unrar/rdwrfn.cpp
+++ b/unrar/unrar/rdwrfn.cpp
@@ -118,7 +118,7 @@ void ComprDataIO::UnpWrite(byte *Addr,uint Count)
if (Cmd->DllOpMode!=RAR_SKIP)
{
if (Cmd->Callback!=NULL &&
- Cmd->Callback(UCM_PROCESSDATA,Cmd->UserData,(LONG)Addr,Count)==-1)
+ Cmd->Callback(UCM_PROCESSDATA,Cmd->UserData,(LPARAM)Addr,Count)==-1)
ErrHandler.Exit(USER_BREAK);
if (Cmd->ProcessDataProc!=NULL)
{
@@ -169,19 +169,21 @@ void ComprDataIO::ShowUnpRead(Int64 ArcPos,Int64 ArcSize)
{
if (ShowProgress && SrcFile!=NULL)
{
- Archive *SrcArc=(Archive *)SrcFile;
- RAROptions *Cmd=SrcArc->GetRAROptions();
if (TotalArcSize!=0)
+ {
+ // important when processing several archives or multivolume archive
ArcSize=TotalArcSize;
- ArcPos+=ProcessedArcSize;
- if (!SrcArc->Volume)
+ ArcPos+=ProcessedArcSize;
+ }
+
+ Archive *SrcArc=(Archive *)SrcFile;
+ RAROptions *Cmd=SrcArc->GetRAROptions();
+
+ int CurPercent=ToPercent(ArcPos,ArcSize);
+ if (!Cmd->DisablePercentage && CurPercent!=LastPercent)
{
- int CurPercent=ToPercent(ArcPos,ArcSize);
- if (!Cmd->DisablePercentage && CurPercent!=LastPercent)
- {
- mprintf("\b\b\b\b%3d%%",CurPercent);
- LastPercent=CurPercent;
- }
+ mprintf("\b\b\b\b%3d%%",CurPercent);
+ LastPercent=CurPercent;
}
}
}
diff --git a/unrar/unrar/rdwrfn.hpp b/unrar/unrar/rdwrfn.hpp
index 8313627..b80ae28 100644
--- a/unrar/unrar/rdwrfn.hpp
+++ b/unrar/unrar/rdwrfn.hpp
@@ -72,7 +72,12 @@ class ComprDataIO
Int64 TotalPackRead;
Int64 UnpArcSize;
Int64 CurPackRead,CurPackWrite,CurUnpRead,CurUnpWrite;
- Int64 ProcessedArcSize,TotalArcSize;
+
+ // Size of already processed archives.
+ // Used to calculate the total operation progress.
+ Int64 ProcessedArcSize;
+
+ Int64 TotalArcSize;
uint PackFileCRC,UnpFileCRC,PackedCRC;
diff --git a/unrar/unrar/recvol.cpp b/unrar/unrar/recvol.cpp
index 0296b02..6d6f6af 100644
--- a/unrar/unrar/recvol.cpp
+++ b/unrar/unrar/recvol.cpp
@@ -79,6 +79,11 @@ bool RecVolumes::Restore(RAROptions *Cmd,const char *Name,
#ifndef SILENT
Int64 RecFileSize=0;
#endif
+
+#ifndef SILENT
+ mprintf(St(MCalcCRCAllVol));
+#endif
+
FindFile Find;
Find.SetMask(RecVolMask);
struct FindData RecData;
@@ -236,7 +241,7 @@ bool RecVolumes::Restore(RAROptions *Cmd,const char *Name,
#endif
}
SrcFile[CurArcNum]=(File*)NewFile;
- NextVolumeName(ArcName,!NewNumbering);
+ NextVolumeName(ArcName,ArcNameW,ASIZE(ArcName),!NewNumbering);
}
#ifndef SILENT
@@ -273,8 +278,10 @@ bool RecVolumes::Restore(RAROptions *Cmd,const char *Name,
#ifndef SILENT
Int64 ProcessedSize=0;
-#ifndef GUI
+
+/* Modified by Tomas Bzatek - bug in defines */
int LastPercent=-1;
+#ifndef GUI
mprintf(" ");
#endif
#endif
diff --git a/unrar/unrar/scantree.cpp b/unrar/unrar/scantree.cpp
index 416de6d..cfd2ef7 100644
--- a/unrar/unrar/scantree.cpp
+++ b/unrar/unrar/scantree.cpp
@@ -7,6 +7,8 @@ ScanTree::ScanTree(StringList *FileMasks,int Recurse,bool GetLinks,int GetDirs)
ScanTree::GetLinks=GetLinks;
ScanTree::GetDirs=GetDirs;
+ ScanEntireDisk=false;
+
SetAllMaskDepth=0;
*CurMask=0;
*CurMaskW=0;
@@ -57,6 +59,7 @@ int ScanTree::GetNext(FindData *FindData)
bool ScanTree::PrepareMasks()
{
+ ScanEntireDisk=false;
if (!FileMasks->GetString(CurMask,CurMaskW,sizeof(CurMask)))
return(false);
CurMask[ASIZE(CurMask)-1]=0;
@@ -64,6 +67,12 @@ bool ScanTree::PrepareMasks()
#ifdef _WIN_32
UnixSlashToDos(CurMask);
#endif
+
+ // We wish to scan entire disk if mask like c:\ is specified
+ // regardless of recursion mode. Use c:\*.* mask when need to scan only
+ // the root directory.
+ ScanEntireDisk=IsDiskLetter(CurMask) && IsPathDiv(CurMask[2]) && CurMask[3]==0;
+
char *Name=PointToName(CurMask);
if (*Name==0)
strcat(CurMask,MASKALL);
@@ -116,7 +125,7 @@ int ScanTree::FindProc(FindData *FindData)
bool FindCode=!Wildcards && FindFile::FastFind(CurMask,CurMaskW,FindData,GetLinks);
bool IsDir=FindCode && FindData->IsDir;
bool SearchAll=!IsDir && (Depth>0 || Recurse==RECURSE_ALWAYS ||
- Wildcards && Recurse==RECURSE_WILDCARDS);
+ Wildcards && Recurse==RECURSE_WILDCARDS || ScanEntireDisk);
if (Depth==0)
SearchAllInRoot=SearchAll;
if (SearchAll || Wildcards)
@@ -234,7 +243,10 @@ int ScanTree::FindProc(FindData *FindData)
}
if (GetDirs==SCAN_GETDIRSTWICE &&
FindFile::FastFind(DirName,DirNameW,FindData,GetLinks) && FindData->IsDir)
+ {
+ FindData->Flags|=FDDF_SECONDDIR;
return(Error ? SCAN_ERROR:SCAN_SUCCESS);
+ }
return(Error ? SCAN_ERROR:SCAN_NEXT);
}
diff --git a/unrar/unrar/scantree.hpp b/unrar/unrar/scantree.hpp
index 2f206ba..34d52fe 100644
--- a/unrar/unrar/scantree.hpp
+++ b/unrar/unrar/scantree.hpp
@@ -26,6 +26,9 @@ class ScanTree
int GetDirs;
int Errors;
+ // set when processing paths like c:\ (root directory without wildcards)
+ bool ScanEntireDisk;
+
char CurMask[NM];
wchar CurMaskW[NM];
char OrigCurMask[NM];
diff --git a/unrar/unrar/strfn.cpp b/unrar/unrar/strfn.cpp
index 4c22799..52b7a5f 100644
--- a/unrar/unrar/strfn.cpp
+++ b/unrar/unrar/strfn.cpp
@@ -86,7 +86,7 @@ int strnicomp(const char *Str1,const char *Str2,int N)
char* RemoveEOL(char *Str)
{
- for (int I=strlen(Str)-1;I>=0 && (Str[I]=='\r' || Str[I]=='\n' || Str[I]==' ' || Str[I]=='\t');I--)
+ for (int I=(int)strlen(Str)-1;I>=0 && (Str[I]=='\r' || Str[I]=='\n' || Str[I]==' ' || Str[I]=='\t');I--)
Str[I]=0;
return(Str);
}
@@ -94,7 +94,7 @@ char* RemoveEOL(char *Str)
char* RemoveLF(char *Str)
{
- for (int I=strlen(Str)-1;I>=0 && (Str[I]=='\r' || Str[I]=='\n');I--)
+ for (int I=(int)strlen(Str)-1;I>=0 && (Str[I]=='\r' || Str[I]=='\n');I--)
Str[I]=0;
return(Str);
}
@@ -103,7 +103,8 @@ char* RemoveLF(char *Str)
unsigned int loctolower(byte ch)
{
#ifdef _WIN_32
- return((int)CharLower((LPTSTR)ch));
+ // convert to LPARAM first to avoid a warning in 64 bit mode
+ return((int)(LPARAM)CharLower((LPTSTR)ch));
#else
return(tolower(ch));
#endif
@@ -113,7 +114,8 @@ unsigned int loctolower(byte ch)
unsigned int loctoupper(byte ch)
{
#ifdef _WIN_32
- return((int)CharUpper((LPTSTR)ch));
+ // convert to LPARAM first to avoid a warning in 64 bit mode
+ return((int)(LPARAM)CharUpper((LPTSTR)ch));
#else
return(toupper(ch));
#endif
diff --git a/unrar/unrar/strlist.cpp b/unrar/unrar/strlist.cpp
index 86cace5..7e7e50c 100644
--- a/unrar/unrar/strlist.cpp
+++ b/unrar/unrar/strlist.cpp
@@ -31,7 +31,7 @@ unsigned int StringList::AddString(const char *Str)
unsigned int StringList::AddString(const char *Str,const wchar *StrW)
{
int PrevSize=StringData.Size();
- StringData.Add(strlen(Str)+1);
+ StringData.Add((int)(strlen(Str)+1));
strcpy(&StringData[PrevSize],Str);
if (StrW!=NULL && *StrW!=0)
{
diff --git a/unrar/unrar/timefn.cpp b/unrar/unrar/timefn.cpp
index d11c663..3a7b834 100644
--- a/unrar/unrar/timefn.cpp
+++ b/unrar/unrar/timefn.cpp
@@ -248,7 +248,6 @@ void RarTime::SetAgeText(char *TimeText)
#endif
-#ifndef SFX_MODULE
void RarTime::SetCurrentTime()
{
#ifdef _WIN_32
@@ -263,7 +262,6 @@ void RarTime::SetCurrentTime()
*this=st;
#endif
}
-#endif
#if !defined(SFX_MODULE) && !defined(_WIN_CE)
diff --git a/unrar/unrar/unicode.cpp b/unrar/unrar/unicode.cpp
index 83d1187..affc905 100644
--- a/unrar/unrar/unicode.cpp
+++ b/unrar/unrar/unicode.cpp
@@ -16,7 +16,10 @@ bool WideToChar(const wchar *Src,char *Dest,int DestSize)
#else
#ifdef MBFUNCTIONS
- if (wcstombs(Dest,Src,DestSize)==(size_t)-1)
+ size_t ResultingSize=wcstombs(Dest,Src,DestSize);
+ if (ResultingSize==(size_t)-1)
+ RetCode=false;
+ if (ResultingSize==0 && *Src!=0)
RetCode=false;
if ((!RetCode || *Dest==0 && *Src!=0) && DestSize>NM && strlenw(Src)<NM)
@@ -66,7 +69,10 @@ bool CharToWide(const char *Src,wchar *Dest,int DestSize)
#else
#ifdef MBFUNCTIONS
- if (mbstowcs(Dest,Src,DestSize)==(size_t)-1)
+ size_t ResultingSize=mbstowcs(Dest,Src,DestSize);
+ if (ResultingSize==(size_t)-1)
+ RetCode=false;
+ if (ResultingSize==0 && *Src!=0)
RetCode=false;
if ((!RetCode || *Dest==0 && *Src!=0) && DestSize>NM && strlen(Src)<NM)
@@ -241,11 +247,11 @@ wchar* strcpyw(wchar *dest,const wchar *src)
}
-wchar* strncpyw(wchar *dest,const wchar *src,int n)
+wchar* strncpyw(wchar *dest,const wchar *src,size_t n)
{
do {
*(dest++)=*src;
- } while (*(src++)!=0 && --n > 0);
+ } while (*(src++)!=0 && (int)(--n) > 0);
return(dest);
}
@@ -257,11 +263,11 @@ wchar* strcatw(wchar *dest,const wchar *src)
#ifndef SFX_MODULE
-wchar* strncatw(wchar *dest,const wchar *src,int n)
+wchar* strncatw(wchar *dest,const wchar *src,size_t n)
{
dest+=strlenw(dest);
while (true)
- if (--n<0)
+ if ((int)(--n)<0)
{
*dest=0;
break;
@@ -287,9 +293,9 @@ int strcmpw(const wchar *s1,const wchar *s2)
}
-int strncmpw(const wchar *s1,const wchar *s2,int n)
+int strncmpw(const wchar *s1,const wchar *s2,size_t n)
{
- while (n-->0)
+ while ((int)(n--)>0)
{
if (*s1<*s2)
return(-1);
@@ -316,7 +322,7 @@ int stricmpw(const wchar *s1,const wchar *s2)
#if !defined(SFX_MODULE) && !defined(_WIN_CE)
-inline int strnicmpw_w2c(const wchar *s1,const wchar *s2,int n)
+inline int strnicmpw_w2c(const wchar *s1,const wchar *s2,size_t n)
{
wchar Wide1[NM*2],Wide2[NM*2];
strncpyw(Wide1,s1,sizeof(Wide1)/sizeof(Wide1[0])-1);
@@ -332,7 +338,7 @@ inline int strnicmpw_w2c(const wchar *s1,const wchar *s2,int n)
#ifndef SFX_MODULE
-int strnicmpw(const wchar *s1,const wchar *s2,int n)
+int strnicmpw(const wchar *s1,const wchar *s2,size_t n)
{
return(strnicmpw_w2c(s1,s2,n));
}
@@ -395,6 +401,20 @@ wchar* strupperw(wchar *Str)
#ifndef SFX_MODULE
+wchar* strdupw(const wchar *Str)
+{
+ if (Str==NULL)
+ return(NULL);
+ wchar *n=(wchar *)malloc((strlenw(Str)+1)*sizeof(wchar));
+ if (n==NULL)
+ return(NULL);
+ strcpyw(n,Str);
+ return(n);
+}
+#endif
+
+
+#ifndef SFX_MODULE
int toupperw(int ch)
{
return((ch<128) ? loctoupper(ch):ch);
diff --git a/unrar/unrar/unicode.hpp b/unrar/unrar/unicode.hpp
index 8175c00..3b4e2c3 100644
--- a/unrar/unrar/unicode.hpp
+++ b/unrar/unrar/unicode.hpp
@@ -28,18 +28,19 @@ bool UnicodeEnabled();
int strlenw(const wchar *str);
wchar* strcpyw(wchar *dest,const wchar *src);
-wchar* strncpyw(wchar *dest,const wchar *src,int n);
+wchar* strncpyw(wchar *dest,const wchar *src,size_t n);
wchar* strcatw(wchar *dest,const wchar *src);
-wchar* strncatw(wchar *dest,const wchar *src,int n);
+wchar* strncatw(wchar *dest,const wchar *src,size_t n);
int strcmpw(const wchar *s1,const wchar *s2);
-int strncmpw(const wchar *s1,const wchar *s2,int n);
+int strncmpw(const wchar *s1,const wchar *s2,size_t n);
int stricmpw(const wchar *s1,const wchar *s2);
-int strnicmpw(const wchar *s1,const wchar *s2,int n);
+int strnicmpw(const wchar *s1,const wchar *s2,size_t n);
wchar *strchrw(const wchar *s,int c);
wchar* strrchrw(const wchar *s,int c);
wchar* strpbrkw(const wchar *s1,const wchar *s2);
wchar* strlowerw(wchar *Str);
wchar* strupperw(wchar *Str);
+wchar* strdupw(const wchar *Str);
int toupperw(int ch);
int atoiw(const wchar *s);
diff --git a/unrar/unrar/unpack.cpp b/unrar/unrar/unpack.cpp
index 1b239ca..3e26153 100644
--- a/unrar/unrar/unpack.cpp
+++ b/unrar/unrar/unpack.cpp
@@ -262,6 +262,11 @@ void Unpack::Unpack29(bool Solid)
}
if (Failed)
break;
+
+#ifdef _MSC_VER
+ // avoid a warning about uninitialized 'Length' variable
+ #pragma warning( disable : 4701 )
+#endif
CopyString(Length+32,Distance+2);
continue;
}
diff --git a/unrar/unrar/uowners.cpp b/unrar/unrar/uowners.cpp
index c906059..38471e0 100644
--- a/unrar/unrar/uowners.cpp
+++ b/unrar/unrar/uowners.cpp
@@ -34,7 +34,7 @@ void ExtractUnixOwner(Archive &Arc,char *FileName)
#endif
{
Log(Arc.FileName,St(MSetOwnersError),FileName);
- ErrHandler.SetErrorCode(CRC_ERROR);
+ ErrHandler.SetErrorCode(CREATE_ERROR);
}
SetFileAttr(FileName,NULL,Attr);
}
@@ -74,7 +74,7 @@ void ExtractUnixOwnerNew(Archive &Arc,char *FileName)
#endif
{
Log(Arc.FileName,St(MSetOwnersError),FileName);
- ErrHandler.SetErrorCode(CRC_ERROR);
+ ErrHandler.SetErrorCode(CREATE_ERROR);
}
SetFileAttr(FileName,NULL,Attr);
}
diff --git a/unrar/unrar/version.hpp b/unrar/unrar/version.hpp
index d29ecec..616d34d 100644
--- a/unrar/unrar/version.hpp
+++ b/unrar/unrar/version.hpp
@@ -1,6 +1,6 @@
#define RARVER_MAJOR 3
-#define RARVER_MINOR 71
-#define RARVER_BETA 1
-#define RARVER_DAY 10
-#define RARVER_MONTH 9
-#define RARVER_YEAR 2007
+#define RARVER_MINOR 80
+#define RARVER_BETA 2
+#define RARVER_DAY 15
+#define RARVER_MONTH 6
+#define RARVER_YEAR 2008
diff --git a/unrar/unrar/volume.cpp b/unrar/unrar/volume.cpp
index 9a79662..4c138db 100644
--- a/unrar/unrar/volume.cpp
+++ b/unrar/unrar/volume.cpp
@@ -19,39 +19,17 @@ bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,char Comman
}
Int64 PosBeforeClose=Arc.Tell();
+
+ if (DataIO!=NULL)
+ DataIO->ProcessedArcSize+=Arc.FileLength();
+
Arc.Close();
char NextName[NM];
wchar NextNameW[NM];
- *NextNameW=0;
strcpy(NextName,Arc.FileName);
- NextVolumeName(NextName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING)==0 || Arc.OldFormat);
-
- if (*Arc.FileNameW!=0)
- {
- // Copy incremented trailing low ASCII volume name part to Unicode name.
- // It is simpler than also implementing Unicode version of NextVolumeName.
-
- strcpyw(NextNameW,Arc.FileNameW);
- char *NumPtr=GetVolNumPart(NextName);
-
- // moving to first digit in volume number
- while (NumPtr>NextName && isdigit(*NumPtr) && isdigit(*(NumPtr-1)))
- NumPtr--;
-
- // also copy the first character before volume number,
- // because it can be changed when going from .r99 to .s00
- if (NumPtr>NextName)
- NumPtr--;
-
- int CharsToCopy=strlen(NextName)-(NumPtr-NextName);
- int DestPos=strlenw(NextNameW)-CharsToCopy;
- if (DestPos>0)
- {
- CharToWide(NumPtr,NextNameW+DestPos,ASIZE(NextNameW)-DestPos-1);
- NextNameW[ASIZE(NextNameW)-1]=0;
- }
- }
+ strcpyw(NextNameW,Arc.FileNameW);
+ NextVolumeName(NextName,NextNameW,ASIZE(NextName),(Arc.NewMhd.Flags & MHD_NEWNUMBERING)==0 || Arc.OldFormat);
#if !defined(SFX_MODULE) && !defined(RARDLL)
bool RecoveryDone=false;
@@ -60,22 +38,33 @@ bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,char Comman
while (!Arc.Open(NextName,NextNameW))
{
+ // We need to open a new volume which size was not calculated
+ // in total size before, so we cannot calculate the total progress
+ // anymore. Let's reset the total size to zero and stop
+ // the total progress.
+ if (DataIO!=NULL)
+ DataIO->TotalArcSize=0;
+
if (!OldSchemeTested)
{
+ // Checking for new style volumes renamed by user to old style
+ // name format. Some users did it for unknown reason.
char AltNextName[NM];
+ wchar AltNextNameW[NM];
strcpy(AltNextName,Arc.FileName);
- NextVolumeName(AltNextName,true);
+ strcpyw(AltNextNameW,Arc.FileNameW);
+ NextVolumeName(AltNextName,AltNextNameW,ASIZE(AltNextName),true);
OldSchemeTested=true;
- if (Arc.Open(AltNextName))
+ if (Arc.Open(AltNextName,AltNextNameW))
{
strcpy(NextName,AltNextName);
- *NextNameW=0;
+ strcpyw(NextNameW,AltNextNameW);
break;
}
}
#ifdef RARDLL
if (Cmd->Callback==NULL && Cmd->ChangeVolProc==NULL ||
- Cmd->Callback!=NULL && Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LONG)NextName,RAR_VOL_ASK)==-1)
+ Cmd->Callback!=NULL && Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LPARAM)NextName,RAR_VOL_ASK)==-1)
{
Cmd->DllError=ERAR_EOPEN;
FailedOpen=true;
@@ -123,6 +112,7 @@ bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,char Comman
FailedOpen=true;
break;
}
+
#endif // RARDLL
*NextNameW=0;
}
@@ -138,7 +128,7 @@ bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,char Comman
Arc.CheckArc(true);
#ifdef RARDLL
if (Cmd->Callback!=NULL &&
- Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LONG)NextName,RAR_VOL_NOTIFY)==-1)
+ Cmd->Callback(UCM_CHANGEVOLUME,Cmd->UserData,(LPARAM)NextName,RAR_VOL_NOTIFY)==-1)
return(false);
if (Cmd->ChangeVolProc!=NULL)
{
@@ -197,8 +187,13 @@ bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,char Comman
}
#ifdef SFX_MODULE
DataIO->UnpArcSize=Arc.FileLength();
- DataIO->CurUnpRead=0;
#endif
+
+ // Reset the size of packed data read from current volume. It is used
+ // to display the total progress and preceding volumes are already
+ // compensated with ProcessedArcSize, so we need to reset this variable.
+ DataIO->CurUnpRead=0;
+
DataIO->PackedCRC=0xffffffff;
// DataIO->SetFiles(&Arc,NULL);
}