Patch by Ioan Molnar: update unrar from version 3.67 to 3.76 - thanks!
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@21952 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
c1b3e74df2
commit
36c5ff54b6
@ -197,6 +197,10 @@ bool Archive::IsArchive(bool EnableBroken)
|
||||
#ifdef RARDLL
|
||||
SilentOpen=true;
|
||||
#endif
|
||||
|
||||
//if not encrypted, we'll check it below
|
||||
NotFirstVolume=Encrypted && (NewMhd.Flags & MHD_FIRSTVOLUME)==0;
|
||||
|
||||
if (!SilentOpen || !Encrypted)
|
||||
{
|
||||
SaveFilePos SavePos(*this);
|
||||
@ -226,6 +230,12 @@ bool Archive::IsArchive(bool EnableBroken)
|
||||
CurBlockPos=SaveCurBlockPos;
|
||||
NextBlockPos=SaveNextBlockPos;
|
||||
}
|
||||
if (!Volume || !NotFirstVolume)
|
||||
{
|
||||
strcpy(FirstVolumeName,FileName);
|
||||
strcpyw(FirstVolumeNameW,FileNameW);
|
||||
}
|
||||
|
||||
return(true);
|
||||
}
|
||||
|
||||
|
@ -10,11 +10,9 @@ class Archive:public File
|
||||
private:
|
||||
bool IsSignature(byte *D);
|
||||
void UpdateLatestTime(FileHeader *CurBlock);
|
||||
void Protect(int RecSectors);
|
||||
void ConvertNameCase(char *Name);
|
||||
void ConvertNameCase(wchar *Name);
|
||||
void ConvertUnknownHeader();
|
||||
bool AddArcComment(char *NameToShow);
|
||||
int ReadOldHeader();
|
||||
void PrepareExtraTime(FileHeader *hd,EXTTIME_MODE etm,EXTTIME_MODE etc,EXTTIME_MODE eta,EXTTIME_MODE etarc,Array<byte> &TimeData);
|
||||
|
||||
|
@ -162,8 +162,7 @@ int Archive::ReadHeader()
|
||||
Raw.Get((byte *)FileName,NameSize);
|
||||
FileName[NameSize]=0;
|
||||
|
||||
strncpy(hd->FileName,FileName,sizeof(hd->FileName));
|
||||
hd->FileName[sizeof(hd->FileName)-1]=0;
|
||||
strncpyz(hd->FileName,FileName,ASIZE(hd->FileName));
|
||||
|
||||
if (hd->HeadType==NEWSUB_HEAD)
|
||||
{
|
||||
|
@ -55,10 +55,10 @@ void CommandData::ParseArg(char *Arg,wchar *ArgW)
|
||||
else
|
||||
if (*Command==0)
|
||||
{
|
||||
strncpy(Command,Arg,sizeof(Command));
|
||||
strncpyz(Command,Arg,ASIZE(Command));
|
||||
if (ArgW!=NULL)
|
||||
strncpyw(CommandW,ArgW,sizeof(CommandW)/sizeof(CommandW[0]));
|
||||
if (toupper(*Command)=='S')
|
||||
if (etoupper(*Command)=='S')
|
||||
{
|
||||
const char *SFXName=Command[1] ? Command+1:DefSFXName;
|
||||
if (PointToName(SFXName)!=SFXName || FileExist(SFXName))
|
||||
@ -67,7 +67,7 @@ void CommandData::ParseArg(char *Arg,wchar *ArgW)
|
||||
GetConfigName(SFXName,SFXModule,true);
|
||||
}
|
||||
#ifndef GUI
|
||||
*Command=toupper(*Command);
|
||||
*Command=etoupper(*Command);
|
||||
if (*Command!='I' && *Command!='S')
|
||||
strupper(Command);
|
||||
#endif
|
||||
@ -75,19 +75,23 @@ void CommandData::ParseArg(char *Arg,wchar *ArgW)
|
||||
else
|
||||
if (*ArcName==0)
|
||||
{
|
||||
strncpy(ArcName,Arg,sizeof(ArcName));
|
||||
strncpyz(ArcName,Arg,ASIZE(ArcName));
|
||||
if (ArgW!=NULL)
|
||||
strncpyw(ArcNameW,ArgW,sizeof(ArcNameW)/sizeof(ArcNameW[0]));
|
||||
strncpyzw(ArcNameW,ArgW,ASIZE(ArcNameW));
|
||||
}
|
||||
else
|
||||
{
|
||||
int Length=strlen(Arg);
|
||||
char EndChar=Arg[Length-1];
|
||||
char CmdChar=toupper(*Command);
|
||||
char CmdChar=etoupper(*Command);
|
||||
bool Add=strchr("AFUM",CmdChar)!=NULL;
|
||||
bool Extract=CmdChar=='X' || CmdChar=='E';
|
||||
if ((IsDriveDiv(EndChar) || IsPathDiv(EndChar)) && !Add)
|
||||
strcpy(ExtrPath,Arg);
|
||||
{
|
||||
strncpyz(ExtrPath,Arg,ASIZE(ExtrPath));
|
||||
if (ArgW!=NULL)
|
||||
strncpyzw(ExtrPathW,ArgW,ASIZE(ExtrPathW));
|
||||
}
|
||||
else
|
||||
if ((Add || CmdChar=='T') && *Arg!='@')
|
||||
FileArgs->AddString(Arg);
|
||||
@ -98,7 +102,18 @@ void CommandData::ParseArg(char *Arg,wchar *ArgW)
|
||||
if (!Found && *Arg=='@' && !IsWildcard(Arg))
|
||||
{
|
||||
FileLists=true;
|
||||
ReadTextFile(Arg+1,FileArgs,false,true,true,true,true);
|
||||
|
||||
RAR_CHARSET Charset=FilelistCharset;
|
||||
|
||||
#if defined(_WIN_32) && !defined(GUI)
|
||||
// for compatibility reasons we use OEM encoding
|
||||
// in Win32 console version by default
|
||||
|
||||
if (Charset==RCH_DEFAULT)
|
||||
Charset=RCH_OEM;
|
||||
#endif
|
||||
|
||||
ReadTextFile(Arg+1,FileArgs,false,true,Charset,true,true);
|
||||
}
|
||||
else
|
||||
if (Found && FileData.IsDir && Extract && *ExtrPath==0)
|
||||
@ -118,7 +133,7 @@ void CommandData::ParseDone()
|
||||
{
|
||||
if (FileArgs->ItemsCount()==0 && !FileLists)
|
||||
FileArgs->AddString(MASKALL);
|
||||
char CmdChar=toupper(*Command);
|
||||
char CmdChar=etoupper(*Command);
|
||||
bool Extract=CmdChar=='X' || CmdChar=='E';
|
||||
if (Test && Extract)
|
||||
Test=false;
|
||||
@ -136,7 +151,11 @@ void CommandData::ParseEnvVar()
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(GUI) && !defined(SFX_MODULE)
|
||||
|
||||
// return 'false' if -cfg- is present and preprocess switches
|
||||
// which must be processed before the rest of command line
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
bool CommandData::IsConfigEnabled(int argc,char *argv[])
|
||||
{
|
||||
bool ConfigEnabled=true;
|
||||
@ -145,11 +164,20 @@ bool CommandData::IsConfigEnabled(int argc,char *argv[])
|
||||
{
|
||||
if (stricomp(&argv[I][1],"cfg-")==0)
|
||||
ConfigEnabled=false;
|
||||
#ifndef GUI
|
||||
if (strnicomp(&argv[I][1],"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(&argv[I][1]);
|
||||
InitLogOptions(LogName);
|
||||
}
|
||||
#endif
|
||||
if (strnicomp(&argv[I][1],"sc",2)==0)
|
||||
{
|
||||
// process -cs before reading any file lists
|
||||
ProcessSwitch(&argv[I][1]);
|
||||
}
|
||||
}
|
||||
return(ConfigEnabled);
|
||||
}
|
||||
@ -201,12 +229,12 @@ void CommandData::ProcessSwitchesString(char *Str)
|
||||
void CommandData::ProcessSwitch(char *Switch)
|
||||
{
|
||||
|
||||
switch(toupper(Switch[0]))
|
||||
switch(etoupper(Switch[0]))
|
||||
{
|
||||
case 'I':
|
||||
if (strnicomp(&Switch[1],"LOG",3)==0)
|
||||
{
|
||||
strncpy(LogName,Switch[4] ? Switch+4:DefLogName,sizeof(LogName));
|
||||
strncpyz(LogName,Switch[4] ? Switch+4:DefLogName,ASIZE(LogName));
|
||||
break;
|
||||
}
|
||||
if (stricomp(&Switch[1],"SND")==0)
|
||||
@ -221,7 +249,7 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
}
|
||||
if (strnicomp(&Switch[1],"EML",3)==0)
|
||||
{
|
||||
strncpy(EmailTo,Switch[4] ? Switch+4:"@",sizeof(EmailTo));
|
||||
strncpyz(EmailTo,Switch[4] ? Switch+4:"@",ASIZE(EmailTo));
|
||||
EmailTo[sizeof(EmailTo)-1]=0;
|
||||
break;
|
||||
}
|
||||
@ -230,10 +258,10 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
MsgStream=MSG_NULL;
|
||||
break;
|
||||
}
|
||||
if (toupper(Switch[1])=='D')
|
||||
if (etoupper(Switch[1])=='D')
|
||||
{
|
||||
for (int I=2;Switch[I]!=0;I++)
|
||||
switch(toupper(Switch[I]))
|
||||
switch(etoupper(Switch[I]))
|
||||
{
|
||||
case 'Q':
|
||||
MsgStream=MSG_ERRONLY;
|
||||
@ -257,7 +285,7 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
}
|
||||
break;
|
||||
case 'T':
|
||||
switch(toupper(Switch[1]))
|
||||
switch(etoupper(Switch[1]))
|
||||
{
|
||||
case 'K':
|
||||
ArcTime=ARCTIME_KEEP;
|
||||
@ -293,7 +321,7 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
Mode=(EXTTIME_MODE)(Switch[3]-'0');
|
||||
if (Switch[3]=='-')
|
||||
Mode=EXTTIME_NONE;
|
||||
switch(toupper(Switch[2]))
|
||||
switch(etoupper(Switch[2]))
|
||||
{
|
||||
case 'M':
|
||||
xmtime=Mode;
|
||||
@ -323,7 +351,7 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
}
|
||||
break;
|
||||
case 'A':
|
||||
switch(toupper(Switch[1]))
|
||||
switch(etoupper(Switch[1]))
|
||||
{
|
||||
case 'C':
|
||||
ClearArc=true;
|
||||
@ -337,7 +365,7 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
else
|
||||
{
|
||||
GenerateArcName=true;
|
||||
strncpy(GenerateMask,Switch+2,sizeof(GenerateMask));
|
||||
strncpyz(GenerateMask,Switch+2,ASIZE(GenerateMask));
|
||||
}
|
||||
break;
|
||||
case 'N': //reserved for archive name
|
||||
@ -351,11 +379,14 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
case 'S':
|
||||
SyncFiles=true;
|
||||
break;
|
||||
default:
|
||||
BadSwitch(Switch);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'D':
|
||||
if (Switch[2]==0)
|
||||
switch(toupper(Switch[1]))
|
||||
switch(etoupper(Switch[1]))
|
||||
{
|
||||
case 'S':
|
||||
DisableSortSolid=true;
|
||||
@ -369,7 +400,7 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
}
|
||||
break;
|
||||
case 'O':
|
||||
switch(toupper(Switch[1]))
|
||||
switch(etoupper(Switch[1]))
|
||||
{
|
||||
case '+':
|
||||
Overwrite=OVERWRITE_ALL;
|
||||
@ -402,7 +433,7 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
}
|
||||
break;
|
||||
case 'R':
|
||||
switch(toupper(Switch[1]))
|
||||
switch(etoupper(Switch[1]))
|
||||
{
|
||||
case 0:
|
||||
Recurse=RECURSE_ALWAYS;
|
||||
@ -435,16 +466,28 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
case 'N':
|
||||
case 'X':
|
||||
if (Switch[1]!=0)
|
||||
{
|
||||
StringList *Args=toupper(Switch[0])=='N' ? InclArgs:ExclArgs;
|
||||
{
|
||||
StringList *Args=etoupper(Switch[0])=='N' ? InclArgs:ExclArgs;
|
||||
if (Switch[1]=='@' && !IsWildcard(Switch))
|
||||
ReadTextFile(Switch+2,Args,false,true,true,true,true);
|
||||
{
|
||||
RAR_CHARSET Charset=FilelistCharset;
|
||||
|
||||
#if defined(_WIN_32) && !defined(GUI)
|
||||
// for compatibility reasons we use OEM encoding
|
||||
// in Win32 console version by default
|
||||
|
||||
if (Charset==RCH_DEFAULT)
|
||||
Charset=RCH_OEM;
|
||||
#endif
|
||||
|
||||
ReadTextFile(Switch+2,Args,false,true,Charset,true,true);
|
||||
}
|
||||
else
|
||||
Args->AddString(Switch+1);
|
||||
}
|
||||
break;
|
||||
case 'E':
|
||||
switch(toupper(Switch[1]))
|
||||
switch(etoupper(Switch[1]))
|
||||
{
|
||||
case 'P':
|
||||
switch(Switch[2])
|
||||
@ -490,14 +533,14 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
eprintf("\n");
|
||||
}
|
||||
else
|
||||
strncpy(Password,Switch+1,sizeof(Password));
|
||||
strncpyz(Password,Switch+1,ASIZE(Password));
|
||||
break;
|
||||
case 'H':
|
||||
if (toupper(Switch[1])=='P')
|
||||
if (etoupper(Switch[1])=='P')
|
||||
{
|
||||
EncryptHeaders=true;
|
||||
if (Switch[2]!=0)
|
||||
strncpy(Password,Switch+2,sizeof(Password));
|
||||
strncpyz(Password,Switch+2,ASIZE(Password));
|
||||
else
|
||||
if (*Password==0)
|
||||
{
|
||||
@ -507,11 +550,10 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
}
|
||||
break;
|
||||
case 'Z':
|
||||
strncpy(CommentFile,Switch[1]!=0 ? Switch+1:"stdin",sizeof(CommentFile)-1);
|
||||
CommentFile[sizeof(CommentFile)-1]=0;
|
||||
strncpyz(CommentFile,Switch[1]!=0 ? Switch+1:"stdin",ASIZE(CommentFile));
|
||||
break;
|
||||
case 'M':
|
||||
switch(toupper(Switch[1]))
|
||||
switch(etoupper(Switch[1]))
|
||||
{
|
||||
case 'C':
|
||||
{
|
||||
@ -537,7 +579,7 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
while (isdigit(*Str))
|
||||
Str++;
|
||||
}
|
||||
switch(toupper(*(Str++)))
|
||||
switch(etoupper(*(Str++)))
|
||||
{
|
||||
case 'T': Type=FILTER_PPM; break;
|
||||
case 'E': Type=FILTER_E8; break;
|
||||
@ -560,7 +602,7 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
case 'D':
|
||||
{
|
||||
if ((WinSize=atoi(&Switch[2]))==0)
|
||||
WinSize=0x10000<<(toupper(Switch[2])-'A');
|
||||
WinSize=0x10000<<(etoupper(Switch[2])-'A');
|
||||
else
|
||||
WinSize*=1024;
|
||||
if (!CheckWinSize())
|
||||
@ -612,7 +654,7 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
}
|
||||
break;
|
||||
case 'V':
|
||||
switch(toupper(Switch[1]))
|
||||
switch(etoupper(Switch[1]))
|
||||
{
|
||||
#ifdef _WIN_32
|
||||
case 'D':
|
||||
@ -626,7 +668,7 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
VolumePause=true;
|
||||
break;
|
||||
case 'E':
|
||||
if (toupper(Switch[2])=='R')
|
||||
if (etoupper(Switch[2])=='R')
|
||||
VersionControl=atoi(Switch+3)+1;
|
||||
break;
|
||||
case '-':
|
||||
@ -695,30 +737,19 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
}
|
||||
break;
|
||||
case 'F':
|
||||
switch(toupper(Switch[1]))
|
||||
{
|
||||
case 0:
|
||||
FreshFiles=true;
|
||||
break;
|
||||
case 'C':
|
||||
if (toupper(Switch[2])=='U')
|
||||
{
|
||||
UnicodeComment=true;
|
||||
if (*CommentFile==0 || Switch[3]!=0)
|
||||
{
|
||||
strncpy(CommentFile,Switch[3]!=0 ? Switch+3:"stdin",sizeof(CommentFile)-1);
|
||||
CommentFile[sizeof(CommentFile)-1]=0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (Switch[1]==0)
|
||||
FreshFiles=true;
|
||||
else
|
||||
BadSwitch(Switch);
|
||||
break;
|
||||
case 'U':
|
||||
if (Switch[1]==0)
|
||||
UpdateFiles=true;
|
||||
else
|
||||
BadSwitch(Switch);
|
||||
break;
|
||||
case 'W':
|
||||
strncpy(TempPath,&Switch[1],sizeof(TempPath)-1);
|
||||
strncpyz(TempPath,&Switch[1],ASIZE(TempPath));
|
||||
AddEndSlash(TempPath);
|
||||
break;
|
||||
case 'S':
|
||||
@ -736,7 +767,7 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
SolidCount=atoi(&Switch[1]);
|
||||
}
|
||||
else
|
||||
switch(toupper(Switch[1]))
|
||||
switch(etoupper(Switch[1]))
|
||||
{
|
||||
case 0:
|
||||
Solid|=SOLID_NORMAL;
|
||||
@ -761,11 +792,48 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
if (isdigit(Switch[2]))
|
||||
FileSizeMore=atoil(Switch+2);
|
||||
break;
|
||||
case 'C':
|
||||
{
|
||||
RAR_CHARSET rch;
|
||||
switch(etoupper(Switch[2]))
|
||||
{
|
||||
case 'A':
|
||||
rch=RCH_ANSI;
|
||||
break;
|
||||
case 'O':
|
||||
rch=RCH_OEM;
|
||||
break;
|
||||
case 'U':
|
||||
rch=RCH_UNICODE;
|
||||
break;
|
||||
default :
|
||||
BadSwitch(Switch);
|
||||
break;
|
||||
};
|
||||
if (Switch[3]==0)
|
||||
CommentCharset=FilelistCharset=rch;
|
||||
else
|
||||
for (int I=3;Switch[I]!=0;I++)
|
||||
switch(etoupper(Switch[I]))
|
||||
{
|
||||
case 'C':
|
||||
CommentCharset=rch;
|
||||
break;
|
||||
case 'L':
|
||||
FilelistCharset=rch;
|
||||
break;
|
||||
default:
|
||||
BadSwitch(Switch);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
}
|
||||
break;
|
||||
case 'C':
|
||||
if (Switch[2]==0)
|
||||
switch(toupper(Switch[1]))
|
||||
switch(etoupper(Switch[1]))
|
||||
{
|
||||
case '-':
|
||||
DisableComment=true;
|
||||
@ -779,7 +847,7 @@ void CommandData::ProcessSwitch(char *Switch)
|
||||
}
|
||||
break;
|
||||
case 'K':
|
||||
switch(toupper(Switch[1]))
|
||||
switch(etoupper(Switch[1]))
|
||||
{
|
||||
case 'B':
|
||||
KeepBroken=true;
|
||||
@ -866,17 +934,17 @@ void CommandData::OutHelp()
|
||||
MCHelpSwAO,MCHelpSwAP,MCHelpSwAS,MCHelpSwAV,MCHelpSwAVm,MCHelpSwCm,
|
||||
MCHelpSwCFGm,MCHelpSwCL,MCHelpSwCU,MCHelpSwDF,MCHelpSwDH,MCHelpSwDS,
|
||||
MCHelpSwEa,MCHelpSwED,MCHelpSwEE,MCHelpSwEN,MCHelpSwEP,MCHelpSwEP1,
|
||||
MCHelpSwEP2,MCHelpSwEP3,MCHelpSwF,MCHelpSwFCU,MCHelpSwHP,MCHelpSwIDP,
|
||||
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,
|
||||
MCHelpSwP,MCHelpSwPm,MCHelpSwR,MCHelpSwR0,MCHelpSwRI,MCHelpSwRR,
|
||||
MCHelpSwRV,MCHelpSwS,MCHelpSwSm,MCHelpSwSFX,MCHelpSwSI,MCHelpSwSL,
|
||||
MCHelpSwSM,MCHelpSwT,MCHelpSwTA,MCHelpSwTB,MCHelpSwTK,MCHelpSwTL,
|
||||
MCHelpSwTN,MCHelpSwTO,MCHelpSwTS,MCHelpSwU,MCHelpSwV,MCHelpSwVn,
|
||||
MCHelpSwVD,MCHelpSwVER,MCHelpSwVN,MCHelpSwVP,MCHelpSwW,MCHelpSwX,
|
||||
MCHelpSwXa,MCHelpSwXal,MCHelpSwY,MCHelpSwZ
|
||||
MCHelpSwRV,MCHelpSwS,MCHelpSwSm,MCHelpSwSC,MCHelpSwSFX,MCHelpSwSI,
|
||||
MCHelpSwSL,MCHelpSwSM,MCHelpSwT,MCHelpSwTA,MCHelpSwTB,MCHelpSwTK,
|
||||
MCHelpSwTL,MCHelpSwTN,MCHelpSwTO,MCHelpSwTS,MCHelpSwU,MCHelpSwV,
|
||||
MCHelpSwVn,MCHelpSwVD,MCHelpSwVER,MCHelpSwVN,MCHelpSwVP,MCHelpSwW,
|
||||
MCHelpSwX,MCHelpSwXa,MCHelpSwXal,MCHelpSwY,MCHelpSwZ
|
||||
#endif
|
||||
};
|
||||
|
||||
@ -1079,7 +1147,9 @@ int CommandData::IsProcessFile(FileHeader &NewLhd,bool *ExactMatch,int MatchType
|
||||
void CommandData::ProcessCommand()
|
||||
{
|
||||
#ifndef SFX_MODULE
|
||||
if (Command[1] && strchr("FUADPXETK",*Command)!=NULL || *ArcName==0)
|
||||
|
||||
const char *SingleCharCommands="FUADPXETK";
|
||||
if (Command[1] && strchr(SingleCharCommands,*Command)!=NULL || *ArcName==0)
|
||||
OutHelp();
|
||||
|
||||
#ifdef _UNIX
|
||||
@ -1163,7 +1233,7 @@ uint CommandData::GetExclAttr(char *Str)
|
||||
{
|
||||
uint Attr;
|
||||
for (Attr=0;*Str;Str++)
|
||||
switch(toupper(*Str))
|
||||
switch(etoupper(*Str))
|
||||
{
|
||||
#ifdef _UNIX
|
||||
case 'D':
|
||||
|
@ -29,7 +29,7 @@ enum {CODE_HUFFMAN,CODE_LZ,CODE_LZ2,CODE_REPEATLZ,CODE_CACHELZ,
|
||||
|
||||
enum FilterType {
|
||||
FILTER_NONE, FILTER_PPM /*dummy*/, FILTER_E8, FILTER_E8E9,
|
||||
FILTER_UPCASETOLOW, FILTER_AUDIO, FILTER_RGB, FILTER_DELTA,
|
||||
FILTER_UPCASETOLOW, FILTER_AUDIO, FILTER_RGB, FILTER_DELTA,
|
||||
FILTER_ITANIUM, FILTER_E8E9V2
|
||||
};
|
||||
|
||||
|
@ -124,8 +124,9 @@ void GetPasswordText(char *Str,int MaxLength)
|
||||
#elif defined(_EMX) || defined(_BEOS) || defined(__sparc) || defined(sparc) || defined (__VMS)
|
||||
fgets(Str,MaxLength-1,stdin);
|
||||
#else
|
||||
strncpy(Str,getpass(""),MaxLength-1);
|
||||
strncpyz(Str,getpass(""),MaxLength);
|
||||
#endif
|
||||
Str[MaxLength-1]=0;
|
||||
RemoveLF(Str);
|
||||
}
|
||||
#endif
|
||||
@ -159,7 +160,7 @@ bool GetPassword(PASSWORD_TYPE Type,const char *FileName,char *Password,int MaxL
|
||||
Alarm();
|
||||
while (true)
|
||||
{
|
||||
char PromptStr[256];
|
||||
char PromptStr[NM+256];
|
||||
#if defined(_EMX) || defined(_BEOS)
|
||||
strcpy(PromptStr,St(MAskPswEcho));
|
||||
#else
|
||||
@ -168,7 +169,9 @@ bool GetPassword(PASSWORD_TYPE Type,const char *FileName,char *Password,int MaxL
|
||||
if (Type!=PASSWORD_GLOBAL)
|
||||
{
|
||||
strcat(PromptStr,St(MFor));
|
||||
strcat(PromptStr,PointToName(FileName));
|
||||
char *NameOnly=PointToName(FileName);
|
||||
if (strlen(PromptStr)+strlen(NameOnly)<ASIZE(PromptStr))
|
||||
strcat(PromptStr,NameOnly);
|
||||
}
|
||||
eprintf("\n%s: ",PromptStr);
|
||||
GetPasswordText(Password,MaxLength);
|
||||
@ -176,19 +179,12 @@ bool GetPassword(PASSWORD_TYPE Type,const char *FileName,char *Password,int MaxL
|
||||
return(false);
|
||||
if (Type==PASSWORD_GLOBAL)
|
||||
{
|
||||
strcpy(PromptStr,St(MReAskPsw));
|
||||
eprintf(PromptStr);
|
||||
char CmpStr[256];
|
||||
GetPasswordText(CmpStr,sizeof(CmpStr));
|
||||
eprintf(St(MReAskPsw));
|
||||
char CmpStr[MAXPASSWORD];
|
||||
GetPasswordText(CmpStr,ASIZE(CmpStr));
|
||||
if (*CmpStr==0 || strcmp(Password,CmpStr)!=0)
|
||||
{
|
||||
strcpy(PromptStr,St(MNotMatchPsw));
|
||||
/*
|
||||
#ifdef _WIN_32
|
||||
CharToOem(PromptStr,PromptStr);
|
||||
#endif
|
||||
*/
|
||||
eprintf(PromptStr);
|
||||
eprintf(St(MNotMatchPsw));
|
||||
memset(Password,0,MaxLength);
|
||||
memset(CmpStr,0,sizeof(CmpStr));
|
||||
continue;
|
||||
@ -212,7 +208,7 @@ int Ask(const char *AskStr)
|
||||
for (const char *NextItem=AskStr;NextItem!=NULL;NextItem=strchr(NextItem+1,'_'))
|
||||
{
|
||||
char *CurItem=Item[NumItems];
|
||||
strncpy(CurItem,NextItem+1,sizeof(Item[0]));
|
||||
strncpyz(CurItem,NextItem+1,ASIZE(Item[0]));
|
||||
char *EndItem=strchr(CurItem,'_');
|
||||
if (EndItem!=NULL)
|
||||
*EndItem=0;
|
||||
|
@ -42,7 +42,7 @@ uint CRC(uint StartCRC,const void *Addr,uint Size)
|
||||
Size-=8;
|
||||
}
|
||||
#endif
|
||||
for (uint I=0;I<Size;I++)
|
||||
for (int I=0;I<Size;I++)
|
||||
StartCRC=CRCTab[(byte)(StartCRC^Data[I])]^(StartCRC>>8);
|
||||
return(StartCRC);
|
||||
}
|
||||
@ -51,7 +51,7 @@ uint CRC(uint StartCRC,const void *Addr,uint Size)
|
||||
ushort OldCRC(ushort StartCRC,const void *Addr,uint Size)
|
||||
{
|
||||
byte *Data=(byte *)Addr;
|
||||
for (uint I=0;I<Size;I++)
|
||||
for (int I=0;I<Size;I++)
|
||||
{
|
||||
StartCRC=(StartCRC+Data[I])&0xffff;
|
||||
StartCRC=((StartCRC<<1)|(StartCRC>>15))&0xffff;
|
||||
|
@ -204,7 +204,7 @@ void CryptData::SetCryptKeys(char *Password,byte *Salt,bool Encrypt,bool OldOnly
|
||||
#if defined(_WIN_32) && !defined(GUI)
|
||||
CharToOemBuff(Password,(char*)Psw,strlen(Password));
|
||||
#else
|
||||
strncpy((char *)Psw,Password,MAXPASSWORD-1);
|
||||
strncpyz((char *)Psw,Password,ASIZE(Psw));
|
||||
#endif
|
||||
int PswLength=strlen(Password);
|
||||
memcpy(SubstTable,InitSubstTable,sizeof(SubstTable));
|
||||
@ -223,7 +223,7 @@ void CryptData::SetCryptKeys(char *Password,byte *Salt,bool Encrypt,bool OldOnly
|
||||
}
|
||||
|
||||
bool Cached=false;
|
||||
for (uint I=0;I<sizeof(Cache)/sizeof(Cache[0]);I++)
|
||||
for (int I=0;I<sizeof(Cache)/sizeof(Cache[0]);I++)
|
||||
if (strcmp(Cache[I].Password,Password)==0 &&
|
||||
(Salt==NULL && !Cache[I].SaltPresent || Salt!=NULL &&
|
||||
Cache[I].SaltPresent && memcmp(Cache[I].Salt,Salt,SALT_SIZE)==0) &&
|
||||
|
@ -110,6 +110,7 @@ int PASCAL RARReadHeader(HANDLE hArcData,struct RARHeaderData *D)
|
||||
(Data->Arc.EndArcHead.Flags & EARC_NEXT_VOLUME))
|
||||
if (MergeArchive(Data->Arc,NULL,false,'L'))
|
||||
{
|
||||
Data->Extract.SignatureFound=false;
|
||||
Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
|
||||
return(RARReadHeader(hArcData,D));
|
||||
}
|
||||
@ -125,8 +126,8 @@ int PASCAL RARReadHeader(HANDLE hArcData,struct RARHeaderData *D)
|
||||
else
|
||||
return(Code);
|
||||
}
|
||||
strncpy(D->ArcName,Data->Arc.FileName,sizeof(D->ArcName));
|
||||
strncpy(D->FileName,Data->Arc.NewLhd.FileName,sizeof(D->FileName));
|
||||
strncpyz(D->ArcName,Data->Arc.FileName,ASIZE(D->ArcName));
|
||||
strncpyz(D->FileName,Data->Arc.NewLhd.FileName,ASIZE(D->FileName));
|
||||
D->Flags=Data->Arc.NewLhd.Flags;
|
||||
D->PackSize=Data->Arc.NewLhd.PackSize;
|
||||
D->UnpSize=Data->Arc.NewLhd.UnpSize;
|
||||
@ -158,6 +159,7 @@ int PASCAL RARReadHeaderEx(HANDLE hArcData,struct RARHeaderDataEx *D)
|
||||
(Data->Arc.EndArcHead.Flags & EARC_NEXT_VOLUME))
|
||||
if (MergeArchive(Data->Arc,NULL,false,'L'))
|
||||
{
|
||||
Data->Extract.SignatureFound=false;
|
||||
Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
|
||||
return(RARReadHeaderEx(hArcData,D));
|
||||
}
|
||||
@ -173,12 +175,12 @@ int PASCAL RARReadHeaderEx(HANDLE hArcData,struct RARHeaderDataEx *D)
|
||||
else
|
||||
return(Code);
|
||||
}
|
||||
strncpy(D->ArcName,Data->Arc.FileName,sizeof(D->ArcName));
|
||||
strncpyz(D->ArcName,Data->Arc.FileName,ASIZE(D->ArcName));
|
||||
if (*Data->Arc.FileNameW)
|
||||
strncpyw(D->ArcNameW,Data->Arc.FileNameW,sizeof(D->ArcNameW));
|
||||
else
|
||||
CharToWide(Data->Arc.FileName,D->ArcNameW);
|
||||
strncpy(D->FileName,Data->Arc.NewLhd.FileName,sizeof(D->FileName));
|
||||
strncpyz(D->FileName,Data->Arc.NewLhd.FileName,ASIZE(D->FileName));
|
||||
if (*Data->Arc.NewLhd.FileNameW)
|
||||
strncpyw(D->FileNameW,Data->Arc.NewLhd.FileNameW,sizeof(D->FileNameW));
|
||||
else
|
||||
@ -226,6 +228,7 @@ int PASCAL ProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestNa
|
||||
(Data->Arc.NewLhd.Flags & LHD_SPLIT_AFTER)!=0)
|
||||
if (MergeArchive(Data->Arc,NULL,false,'L'))
|
||||
{
|
||||
Data->Extract.SignatureFound=false;
|
||||
Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
|
||||
return(0);
|
||||
}
|
||||
@ -327,7 +330,7 @@ void PASCAL RARSetProcessDataProc(HANDLE hArcData,PROCESSDATAPROC ProcessDataPro
|
||||
void PASCAL RARSetPassword(HANDLE hArcData,char *Password)
|
||||
{
|
||||
DataSet *Data=(DataSet *)hArcData;
|
||||
strncpy(Data->Cmd.Password,Password,sizeof(Data->Cmd.Password));
|
||||
strncpyz(Data->Cmd.Password,Password,ASIZE(Data->Cmd.Password));
|
||||
}
|
||||
|
||||
|
||||
|
@ -1,18 +1,19 @@
|
||||
#ifndef _UNRAR_DLL_
|
||||
#define _UNRAR_DLL_
|
||||
|
||||
#define ERAR_END_ARCHIVE 10
|
||||
#define ERAR_NO_MEMORY 11
|
||||
#define ERAR_BAD_DATA 12
|
||||
#define ERAR_BAD_ARCHIVE 13
|
||||
#define ERAR_UNKNOWN_FORMAT 14
|
||||
#define ERAR_EOPEN 15
|
||||
#define ERAR_ECREATE 16
|
||||
#define ERAR_ECLOSE 17
|
||||
#define ERAR_EREAD 18
|
||||
#define ERAR_EWRITE 19
|
||||
#define ERAR_SMALL_BUF 20
|
||||
#define ERAR_UNKNOWN 21
|
||||
#define ERAR_END_ARCHIVE 10
|
||||
#define ERAR_NO_MEMORY 11
|
||||
#define ERAR_BAD_DATA 12
|
||||
#define ERAR_BAD_ARCHIVE 13
|
||||
#define ERAR_UNKNOWN_FORMAT 14
|
||||
#define ERAR_EOPEN 15
|
||||
#define ERAR_ECREATE 16
|
||||
#define ERAR_ECLOSE 17
|
||||
#define ERAR_EREAD 18
|
||||
#define ERAR_EWRITE 19
|
||||
#define ERAR_SMALL_BUF 20
|
||||
#define ERAR_UNKNOWN 21
|
||||
#define ERAR_MISSING_PASSWORD 22
|
||||
|
||||
#define RAR_OM_LIST 0
|
||||
#define RAR_OM_EXTRACT 1
|
||||
|
@ -357,7 +357,7 @@ bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize
|
||||
|
||||
if (ExactMatch || (SkipSolid=Arc.Solid)!=0)
|
||||
{
|
||||
if (Arc.NewLhd.Flags & LHD_PASSWORD)
|
||||
if ((Arc.NewLhd.Flags & LHD_PASSWORD)!=0)
|
||||
#ifndef RARDLL
|
||||
if (*Password==0)
|
||||
#endif
|
||||
@ -410,7 +410,7 @@ bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize
|
||||
#ifndef SFX_MODULE
|
||||
if (Cmd->AppendArcNameToPath)
|
||||
{
|
||||
strcat(DestFileName,PointToName(Arc.FileName));
|
||||
strcat(DestFileName,PointToName(Arc.FirstVolumeName));
|
||||
SetExt(DestFileName,NULL);
|
||||
AddEndSlash(DestFileName);
|
||||
}
|
||||
@ -443,7 +443,7 @@ bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize
|
||||
else
|
||||
strcat(DestFileName,ExtrName);
|
||||
|
||||
char DiskLetter=toupper(DestFileName[0]);
|
||||
char DiskLetter=etoupper(DestFileName[0]);
|
||||
|
||||
if (AbsPaths && DestFileName[1]=='_' && IsPathDiv(DestFileName[2]) &&
|
||||
DiskLetter>='A' && DiskLetter<='Z')
|
||||
@ -469,10 +469,10 @@ bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize
|
||||
if (Cmd->AppendArcNameToPath)
|
||||
{
|
||||
wchar FileNameW[NM];
|
||||
if (*Arc.FileNameW!=0)
|
||||
strcpyw(FileNameW,Arc.FileNameW);
|
||||
if (*Arc.FirstVolumeNameW!=0)
|
||||
strcpyw(FileNameW,Arc.FirstVolumeNameW);
|
||||
else
|
||||
CharToWide(Arc.FileName,FileNameW);
|
||||
CharToWide(Arc.FirstVolumeName,FileNameW);
|
||||
strcatw(DestFileNameW,PointToName(FileNameW));
|
||||
SetExt(DestFileNameW,NULL);
|
||||
AddEndSlash(DestFileNameW);
|
||||
@ -505,7 +505,8 @@ bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize
|
||||
else
|
||||
*DestFileNameW=0;
|
||||
|
||||
ExtrFile=!SkipSolid && !EmptyName && (Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)==0/* && *ExtrName*/;
|
||||
ExtrFile=!SkipSolid && !EmptyName && (Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)==0;
|
||||
|
||||
if ((Cmd->FreshFiles || Cmd->UpdateFiles) && (Command=='E' || Command=='X'))
|
||||
{
|
||||
struct FindData FD;
|
||||
@ -519,17 +520,27 @@ bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize
|
||||
ExtrFile=false;
|
||||
}
|
||||
|
||||
// skip encrypted file if no password is specified
|
||||
if ((Arc.NewLhd.Flags & LHD_PASSWORD)!=0 && *Password==0)
|
||||
{
|
||||
ErrHandler.SetErrorCode(WARNING);
|
||||
#ifdef RARDLL
|
||||
Cmd->DllError=ERAR_MISSING_PASSWORD;
|
||||
#endif
|
||||
ExtrFile=false;
|
||||
}
|
||||
|
||||
#ifdef RARDLL
|
||||
if (*Cmd->DllDestName)
|
||||
{
|
||||
strncpy(DestFileName,Cmd->DllDestName,sizeof(DestFileName));
|
||||
strncpyz(DestFileName,Cmd->DllDestName,ASIZE(DestFileName));
|
||||
*DestFileNameW=0;
|
||||
if (Cmd->DllOpMode!=RAR_EXTRACT)
|
||||
ExtrFile=false;
|
||||
}
|
||||
if (*Cmd->DllDestNameW)
|
||||
{
|
||||
strncpyw(DestFileNameW,Cmd->DllDestNameW,sizeof(DestFileNameW)/sizeof(DestFileNameW[0]));
|
||||
strncpyzw(DestFileNameW,Cmd->DllDestNameW,ASIZE(DestFileNameW));
|
||||
DestNameW=DestFileNameW;
|
||||
if (Cmd->DllOpMode!=RAR_EXTRACT)
|
||||
ExtrFile=false;
|
||||
@ -655,8 +666,7 @@ bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize
|
||||
{
|
||||
Log(Arc.FileName,St(MCorrectingName));
|
||||
char OrigName[sizeof(DestFileName)];
|
||||
strncpy(OrigName,DestFileName,sizeof(OrigName)-1);
|
||||
OrigName[sizeof(OrigName)-1]=0;
|
||||
strncpyz(OrigName,DestFileName,ASIZE(OrigName));
|
||||
|
||||
MakeNameUsable(DestFileName,true);
|
||||
CreatePath(DestFileName,NULL,true);
|
||||
@ -799,6 +809,10 @@ bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize
|
||||
#if defined(_WIN_32) || defined(_EMX)
|
||||
if (Cmd->ClearArc)
|
||||
Arc.NewLhd.FileAttr&=~FA_ARCH;
|
||||
/*
|
||||
else
|
||||
Arc.NewLhd.FileAttr|=FA_ARCH; //set archive bit for unpacked files (file is not backed up)
|
||||
*/
|
||||
#endif
|
||||
if (!BrokenFile || Cmd->KeepBroken)
|
||||
{
|
||||
|
@ -24,7 +24,6 @@ class CmdExtract
|
||||
char Password[MAXPASSWORD];
|
||||
bool PasswordAll;
|
||||
bool PrevExtracted;
|
||||
bool SignatureFound;
|
||||
char DestFileName[NM];
|
||||
wchar DestFileNameW[NM];
|
||||
bool PasswordCancelled;
|
||||
@ -36,6 +35,8 @@ class CmdExtract
|
||||
bool ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize,
|
||||
bool &Repeat);
|
||||
static void UnstoreFile(ComprDataIO &DataIO,Int64 DestUnpSize);
|
||||
|
||||
bool SignatureFound;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -139,7 +139,7 @@ bool UpdateExistingShortName(char *Name,wchar *NameW)
|
||||
char NewName[NM];
|
||||
for (int I=0;I<10000;I+=123)
|
||||
{
|
||||
strncpy(NewName,Name,sizeof(NewName));
|
||||
strncpyz(NewName,Name,ASIZE(NewName));
|
||||
sprintf(PointToName(NewName),"rtmp%d",I);
|
||||
if (!FileExist(NewName))
|
||||
break;
|
||||
@ -147,7 +147,7 @@ bool UpdateExistingShortName(char *Name,wchar *NameW)
|
||||
if (FileExist(NewName))
|
||||
return(false);
|
||||
char FullName[NM];
|
||||
strncpy(FullName,Name,sizeof(FullName));
|
||||
strncpyz(FullName,Name,ASIZE(FullName));
|
||||
strcpy(PointToName(FullName),PointToName(fd.Name));
|
||||
if (!MoveFile(FullName,NewName))
|
||||
return(false);
|
||||
|
@ -41,7 +41,7 @@ MKDIR_CODE MakeDir(const char *Name,const wchar *NameW,uint Attr)
|
||||
}
|
||||
|
||||
|
||||
void CreatePath(const char *Path,const wchar *PathW,bool SkipLastName)
|
||||
bool CreatePath(const char *Path,const wchar *PathW,bool SkipLastName)
|
||||
{
|
||||
#ifdef _WIN_32
|
||||
uint DirAttr=0;
|
||||
@ -54,6 +54,7 @@ void CreatePath(const char *Path,const wchar *PathW,bool SkipLastName)
|
||||
bool Wide=false;
|
||||
#endif
|
||||
bool IgnoreAscii=false;
|
||||
bool Success=true;
|
||||
|
||||
const char *s=Path;
|
||||
for (int PosW=0;;PosW++)
|
||||
@ -95,12 +96,16 @@ void CreatePath(const char *Path,const wchar *PathW,bool SkipLastName)
|
||||
mprintf(" %s",St(MOk));
|
||||
#endif
|
||||
}
|
||||
else
|
||||
Success=false;
|
||||
}
|
||||
if (!IgnoreAscii)
|
||||
s=charnext(s);
|
||||
}
|
||||
if (!SkipLastName && !IsPathDiv(*PointToLastChar(Path)))
|
||||
MakeDir(Path,PathW,DirAttr);
|
||||
if (MakeDir(Path,PathW,DirAttr)!=MKDIR_SUCCESS)
|
||||
Success=false;
|
||||
return(Success);
|
||||
}
|
||||
|
||||
|
||||
@ -148,7 +153,7 @@ bool IsRemovable(const char *Name)
|
||||
int Type=GetDriveType(*Root ? Root:NULL);
|
||||
return(Type==DRIVE_REMOVABLE || Type==DRIVE_CDROM);
|
||||
#elif defined(_EMX)
|
||||
char Drive=toupper(Name[0]);
|
||||
char Drive=etoupper(Name[0]);
|
||||
return((Drive=='A' || Drive=='B') && Name[1]==':');
|
||||
#else
|
||||
return(false);
|
||||
@ -176,7 +181,7 @@ Int64 GetFreeDisk(const char *Name)
|
||||
}
|
||||
if (pGetDiskFreeSpaceEx!=NULL)
|
||||
{
|
||||
GetFilePath(Name,Root);
|
||||
GetFilePath(Name,Root,ASIZE(Root));
|
||||
ULARGE_INTEGER uiTotalSize,uiTotalFree,uiUserFree;
|
||||
uiUserFree.u.LowPart=uiUserFree.u.HighPart=0;
|
||||
if (pGetDiskFreeSpaceEx(*Root ? Root:NULL,&uiUserFree,&uiTotalSize,&uiTotalFree) &&
|
||||
@ -192,7 +197,7 @@ Int64 GetFreeDisk(const char *Name)
|
||||
return(FreeSize);
|
||||
#elif defined(_BEOS)
|
||||
char Root[NM];
|
||||
GetFilePath(Name,Root);
|
||||
GetFilePath(Name,Root,ASIZE(Root));
|
||||
dev_t Dev=dev_for_path(*Root ? Root:".");
|
||||
if (Dev<0)
|
||||
return(1457664);
|
||||
@ -205,7 +210,7 @@ Int64 GetFreeDisk(const char *Name)
|
||||
#elif defined(_UNIX)
|
||||
return(1457664);
|
||||
#elif defined(_EMX)
|
||||
int Drive=(!isalpha(Name[0]) || Name[1]!=':') ? 0:toupper(Name[0])-'A'+1;
|
||||
int Drive=(!isalpha(Name[0]) || Name[1]!=':') ? 0:etoupper(Name[0])-'A'+1;
|
||||
if (_osmode == OS2_MODE)
|
||||
{
|
||||
FSALLOCATE fsa;
|
||||
@ -465,7 +470,7 @@ char *MkTemp(char *Name)
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
uint CalcFileCRC(File *SrcFile,Int64 Size)
|
||||
uint CalcFileCRC(File *SrcFile,Int64 Size,CALCCRC_SHOWMODE ShowMode)
|
||||
{
|
||||
SaveFilePos SavePos(*SrcFile);
|
||||
const int BufSize=0x10000;
|
||||
@ -474,6 +479,15 @@ uint CalcFileCRC(File *SrcFile,Int64 Size)
|
||||
uint DataCRC=0xffffffff;
|
||||
int ReadSize;
|
||||
|
||||
#if !defined(SILENT) && !defined(_WIN_CE)
|
||||
Int64 FileLength=SrcFile->FileLength();
|
||||
if (ShowMode!=CALCCRC_SHOWNONE)
|
||||
{
|
||||
mprintf(St(MCalcCRC));
|
||||
mprintf(" ");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
SrcFile->Seek(0,SEEK_SET);
|
||||
while ((ReadSize=SrcFile->Read(&Data[0],int64to32(Size==INT64ERR ? Int64(BufSize):Min(Int64(BufSize),Size))))!=0)
|
||||
@ -481,12 +495,20 @@ uint CalcFileCRC(File *SrcFile,Int64 Size)
|
||||
++BlockCount;
|
||||
if ((BlockCount & 15)==0)
|
||||
{
|
||||
#if !defined(SILENT) && !defined(_WIN_CE)
|
||||
if (ShowMode==CALCCRC_SHOWALL)
|
||||
mprintf("\b\b\b\b%3d%%",ToPercent(BlockCount*Int64(BufSize),FileLength));
|
||||
#endif
|
||||
Wait();
|
||||
}
|
||||
DataCRC=CRC(DataCRC,&Data[0],ReadSize);
|
||||
if (Size!=INT64ERR)
|
||||
Size-=ReadSize;
|
||||
}
|
||||
#if !defined(SILENT) && !defined(_WIN_CE)
|
||||
if (ShowMode==CALCCRC_SHOWALL)
|
||||
mprintf("\b\b\b\b ");
|
||||
#endif
|
||||
return(DataCRC^0xffffffff);
|
||||
}
|
||||
#endif
|
||||
|
@ -4,7 +4,7 @@
|
||||
enum MKDIR_CODE {MKDIR_SUCCESS,MKDIR_ERROR,MKDIR_BADPATH};
|
||||
|
||||
MKDIR_CODE MakeDir(const char *Name,const wchar *NameW,uint Attr);
|
||||
void CreatePath(const char *Path,const wchar *PathW,bool SkipLastName);
|
||||
bool CreatePath(const char *Path,const wchar *PathW,bool SkipLastName);
|
||||
void SetDirTime(const char *Name,RarTime *ftm,RarTime *ftc,RarTime *fta);
|
||||
bool IsRemovable(const char *Name);
|
||||
Int64 GetFreeDisk(const char *Name);
|
||||
@ -25,7 +25,9 @@ void ConvertNameToFull(const wchar *Src,wchar *Dest);
|
||||
char* MkTemp(char *Name);
|
||||
|
||||
|
||||
uint CalcFileCRC(File *SrcFile,Int64 Size=INT64ERR);
|
||||
enum CALCCRC_SHOWMODE {CALCCRC_SHOWNONE,CALCCRC_SHOWTEXT,CALCCRC_SHOWALL};
|
||||
uint CalcFileCRC(File *SrcFile,Int64 Size=INT64ERR,CALCCRC_SHOWMODE ShowMode=CALCCRC_SHOWNONE);
|
||||
|
||||
bool RenameFile(const char *SrcName,const wchar *SrcNameW,const char *DestName,const wchar *DestNameW);
|
||||
bool DelFile(const char *Name);
|
||||
bool DelFile(const char *Name,const wchar *NameW);
|
||||
|
@ -3,7 +3,7 @@
|
||||
static bool IsUnicode(byte *Data,int Size);
|
||||
|
||||
bool ReadTextFile(char *Name,StringList *List,bool Config,bool AbortOnError,
|
||||
bool ConvertToAnsi,bool Unquote,bool SkipComments)
|
||||
RAR_CHARSET SrcCharset,bool Unquote,bool SkipComments)
|
||||
{
|
||||
char FileName[NM];
|
||||
if (Config)
|
||||
@ -37,9 +37,15 @@ bool ReadTextFile(char *Name,StringList *List,bool Config,bool AbortOnError,
|
||||
|
||||
memset(&Data[DataSize],0,5);
|
||||
|
||||
if (IsUnicode((byte *)&Data[0],DataSize))
|
||||
if (SrcCharset==RCH_UNICODE ||
|
||||
SrcCharset==RCH_DEFAULT && IsUnicode((byte *)&Data[0],DataSize))
|
||||
{
|
||||
wchar *CurStr=(wchar *)&Data[2];
|
||||
// Unicode in native system format, can be more than 2 bytes per character
|
||||
Array<wchar> DataW(Data.Size()/2+1);
|
||||
for (int I=2;I<Data.Size()-1;I+=2)
|
||||
DataW[(I-2)/2]=(wchar)Data[I]+(wchar)Data[I+1]*256;
|
||||
|
||||
wchar *CurStr=&DataW[0];
|
||||
Array<char> AnsiName;
|
||||
|
||||
while (*CurStr!=0)
|
||||
@ -114,7 +120,7 @@ bool ReadTextFile(char *Name,StringList *List,bool Config,bool AbortOnError,
|
||||
}
|
||||
}
|
||||
#if defined(_WIN_32)
|
||||
if (ConvertToAnsi)
|
||||
if (SrcCharset==RCH_OEM)
|
||||
OemToChar(CurStr,CurStr);
|
||||
#endif
|
||||
List->AddString(CurStr);
|
||||
@ -133,7 +139,7 @@ bool IsUnicode(byte *Data,int Size)
|
||||
if (Size<4 || Data[0]!=0xff || Data[1]!=0xfe)
|
||||
return(false);
|
||||
for (int I=2;I<Size;I++)
|
||||
if (Data[I]<32)
|
||||
if (Data[I]<32 && Data[I]!='\r' && Data[I]!='\n')
|
||||
return(true);
|
||||
return(false);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define _RAR_FILESTR_
|
||||
|
||||
bool ReadTextFile(char *Name,StringList *List,bool Config,
|
||||
bool AbortOnError=false,bool ConvertToAnsi=false,
|
||||
bool AbortOnError=false,RAR_CHARSET SrcCharset=RCH_DEFAULT,
|
||||
bool Unquote=false,bool SkipComments=false);
|
||||
|
||||
#endif
|
||||
|
@ -92,7 +92,16 @@ bool FindFile::Next(struct FindData *fd,bool GetSymLink)
|
||||
{
|
||||
char FullName[NM];
|
||||
strcpy(FullName,FindMask);
|
||||
strcpy(PointToName(FullName),ent->d_name);
|
||||
*PointToName(FullName)=0;
|
||||
if (strlen(FullName)+strlen(ent->d_name)>=ASIZE(FullName)-1)
|
||||
{
|
||||
#ifndef SILENT
|
||||
Log(NULL,"\n%s%s",FullName,ent->d_name);
|
||||
Log(NULL,St(MPathTooLong));
|
||||
#endif
|
||||
return(false);
|
||||
}
|
||||
strcat(FullName,ent->d_name);
|
||||
if (!FastFind(FullName,NULL,fd,GetSymLink))
|
||||
{
|
||||
ErrHandler.OpenErrorMsg(FullName);
|
||||
|
@ -33,5 +33,6 @@ class BitInput
|
||||
}
|
||||
void faddbits(int Bits);
|
||||
unsigned int fgetbits();
|
||||
bool Overflow(int IncPtr) {return(InAddr+IncPtr>=MAX_SIZE);}
|
||||
};
|
||||
#endif
|
||||
|
@ -64,7 +64,7 @@
|
||||
#define SKIP_IF_UNKNOWN 0x4000
|
||||
#define LONG_BLOCK 0x8000
|
||||
|
||||
#define EARC_NEXT_VOLUME 0x0001
|
||||
#define EARC_NEXT_VOLUME 0x0001 // not last volume
|
||||
#define EARC_DATACRC 0x0002
|
||||
#define EARC_REVSPACE 0x0004
|
||||
#define EARC_VOLNUMBER 0x0008
|
||||
|
@ -118,7 +118,7 @@ void ListArchive(CommandData *Cmd)
|
||||
itoa(TotalPackSize,PackSizeText);
|
||||
|
||||
mprintf("\n%5lu %16s %8s %3d%%",FileCount,UnpSizeText,
|
||||
PackSizeText,ToPercent(TotalPackSize,TotalUnpSize));
|
||||
PackSizeText,ToPercentUnlim(TotalPackSize,TotalUnpSize));
|
||||
SumFileCount+=FileCount;
|
||||
SumUnpSize+=TotalUnpSize;
|
||||
SumPackSize+=TotalPackSize;
|
||||
@ -162,7 +162,7 @@ void ListArchive(CommandData *Cmd)
|
||||
itoa(SumUnpSize,UnpSizeText);
|
||||
itoa(SumPackSize,PackSizeText);
|
||||
mprintf("\n%5lu %16s %8s %3d%%\n",SumFileCount,UnpSizeText,
|
||||
PackSizeText,ToPercent(SumPackSize,SumUnpSize));
|
||||
PackSizeText,ToPercentUnlim(SumPackSize,SumUnpSize));
|
||||
}
|
||||
}
|
||||
|
||||
@ -231,7 +231,7 @@ void ListFileHeader(FileHeader &hd,bool Verbose,bool Technical,bool &TitleShown,
|
||||
if (hd.Flags & LHD_SPLIT_AFTER)
|
||||
mprintf(" -->");
|
||||
else
|
||||
mprintf("%3d%%",ToPercent(hd.FullPackSize,hd.FullUnpSize));
|
||||
mprintf("%3d%%",ToPercentUnlim(hd.FullPackSize,hd.FullUnpSize));
|
||||
|
||||
char DateStr[50];
|
||||
hd.mtime.GetText(DateStr,false);
|
||||
@ -355,7 +355,7 @@ void ListOldSubHeader(Archive &Arc)
|
||||
|
||||
void ListNewSubHeader(CommandData *Cmd,Archive &Arc,bool Technical)
|
||||
{
|
||||
if (Technical && Arc.SubHead.CmpName(SUBHEAD_TYPE_CMT) &&
|
||||
if (Arc.SubHead.CmpName(SUBHEAD_TYPE_CMT) &&
|
||||
(Arc.SubHead.Flags & LHD_SPLIT_BEFORE)==0 && !Cmd->DisableComment)
|
||||
{
|
||||
Array<byte> CmtData;
|
||||
|
@ -73,7 +73,6 @@
|
||||
#define MCHelpSwEP2 "\n ep2 Expand paths to full"
|
||||
#define MCHelpSwEP3 "\n ep3 Expand paths to full including the drive letter"
|
||||
#define MCHelpSwF "\n f Freshen files"
|
||||
#define MCHelpSwFCU "\n fcu[file] Read archive comment from Unicode file"
|
||||
#define MCHelpSwHP "\n hp[password] Encrypt both file data and headers"
|
||||
#define MCHelpSwIDP "\n id[c,d,p,q] Disable messages"
|
||||
#define MCHelpSwIEML "\n ieml[addr] Send archive by email"
|
||||
@ -108,6 +107,7 @@
|
||||
#define MCHelpSwRV "\n rv[N] Create recovery volumes"
|
||||
#define MCHelpSwS "\n s[<N>,v[-],e] Create solid archive"
|
||||
#define MCHelpSwSm "\n s- Disable solid archiving"
|
||||
#define MCHelpSwSC "\n sc<chr>[obj] Specify the character set"
|
||||
#define MCHelpSwSFX "\n sfx[name] Create SFX archive"
|
||||
#define MCHelpSwSI "\n si[name] Read data from standard input (stdin)"
|
||||
#define MCHelpSwSL "\n sl<size> Process files with size less than specified"
|
||||
@ -345,3 +345,5 @@
|
||||
#define MRecVolLimit "\nTotal number of usual and recovery volumes must not exceed 255"
|
||||
#define MVolumeNumber "volume %d"
|
||||
#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."
|
||||
|
@ -50,8 +50,8 @@ bool CmpName(char *Wildcard,char *Name,int CmpPath)
|
||||
return(true);
|
||||
}
|
||||
char Path1[NM],Path2[NM];
|
||||
GetFilePath(Wildcard,Path1);
|
||||
GetFilePath(Name,Path2);
|
||||
GetFilePath(Wildcard,Path1,ASIZE(Path1));
|
||||
GetFilePath(Name,Path2,ASIZE(Path1));
|
||||
if (mstricompc(Wildcard,Path2,ForceCase)==0)
|
||||
return(true);
|
||||
if ((CmpPath==MATCH_PATH || CmpPath==MATCH_EXACTPATH) && mstricompc(Path1,Path2,ForceCase)!=0)
|
||||
@ -94,8 +94,8 @@ bool CmpName(wchar *Wildcard,wchar *Name,int CmpPath)
|
||||
return(true);
|
||||
}
|
||||
wchar Path1[NM],Path2[NM];
|
||||
GetFilePath(Wildcard,Path1);
|
||||
GetFilePath(Name,Path2);
|
||||
GetFilePath(Wildcard,Path1,ASIZE(Path1));
|
||||
GetFilePath(Name,Path2,ASIZE(Path2));
|
||||
if ((CmpPath==MATCH_PATH || CmpPath==MATCH_EXACTPATH) && mstricompcw(Path1,Path2,ForceCase)!=0)
|
||||
return(false);
|
||||
if (CmpPath==MATCH_SUBPATH || CmpPath==MATCH_WILDSUBPATH)
|
||||
|
@ -21,6 +21,8 @@ enum OVERWRITE_MODE {
|
||||
OVERWRITE_ASK,OVERWRITE_ALL,OVERWRITE_NONE,OVERWRITE_AUTORENAME
|
||||
};
|
||||
|
||||
enum RAR_CHARSET { RCH_DEFAULT=0,RCH_ANSI,RCH_OEM,RCH_UNICODE };
|
||||
|
||||
#define MAX_FILTERS 16
|
||||
enum FilterState {FILTER_DEFAULT=0,FILTER_AUTO,FILTER_FORCE,FILTER_DISABLE};
|
||||
|
||||
@ -49,7 +51,8 @@ class RAROptions
|
||||
char ExtrPath[NM];
|
||||
wchar ExtrPathW[NM];
|
||||
char CommentFile[NM];
|
||||
bool UnicodeComment;
|
||||
RAR_CHARSET CommentCharset;
|
||||
RAR_CHARSET FilelistCharset;
|
||||
char ArcPath[NM];
|
||||
char Password[MAXPASSWORD];
|
||||
bool EncryptHeaders;
|
||||
|
@ -33,6 +33,7 @@
|
||||
#include <prsht.h>
|
||||
|
||||
#ifndef _WIN_CE
|
||||
#include <shlobj.h>
|
||||
#include <winioctl.h>
|
||||
#endif
|
||||
|
||||
|
@ -44,12 +44,13 @@ char* ConvertPath(const char *SrcPath,char *DestPath)
|
||||
const char *s=DestPtr;
|
||||
if (s[0] && IsDriveDiv(s[1]))
|
||||
s+=2;
|
||||
if (s[0]=='\\' && s[1]=='\\')
|
||||
{
|
||||
const char *Slash=strchr(s+2,'\\');
|
||||
if (Slash!=NULL && (Slash=strchr(Slash+1,'\\'))!=NULL)
|
||||
s=Slash+1;
|
||||
}
|
||||
else
|
||||
if (s[0]=='\\' && s[1]=='\\')
|
||||
{
|
||||
const char *Slash=strchr(s+2,'\\');
|
||||
if (Slash!=NULL && (Slash=strchr(Slash+1,'\\'))!=NULL)
|
||||
s=Slash+1;
|
||||
}
|
||||
for (const char *t=s;*t!=0;t++)
|
||||
if (IsPathDiv(*t))
|
||||
s=t+1;
|
||||
@ -68,7 +69,7 @@ char* ConvertPath(const char *SrcPath,char *DestPath)
|
||||
if (DestPath!=NULL)
|
||||
{
|
||||
char TmpStr[NM];
|
||||
strncpy(TmpStr,DestPtr,sizeof(TmpStr)-1);
|
||||
strncpyz(TmpStr,DestPtr,ASIZE(TmpStr));
|
||||
strcpy(DestPath,TmpStr);
|
||||
}
|
||||
return((char *)DestPtr);
|
||||
@ -235,7 +236,7 @@ bool IsDriveDiv(int Ch)
|
||||
int GetPathDisk(const char *Path)
|
||||
{
|
||||
if (IsDiskLetter(Path))
|
||||
return(toupper(*Path)-'A');
|
||||
return(etoupper(*Path)-'A');
|
||||
else
|
||||
return(-1);
|
||||
}
|
||||
@ -257,23 +258,26 @@ void AddEndSlash(wchar *Path)
|
||||
}
|
||||
|
||||
|
||||
void GetFilePath(const char *FullName,char *Path)
|
||||
// returns file path including the trailing path separator symbol
|
||||
void GetFilePath(const char *FullName,char *Path,int MaxLength)
|
||||
{
|
||||
int PathLength=PointToName(FullName)-FullName;
|
||||
int PathLength=Min(MaxLength-1,PointToName(FullName)-FullName);
|
||||
strncpy(Path,FullName,PathLength);
|
||||
Path[PathLength]=0;
|
||||
}
|
||||
|
||||
|
||||
void GetFilePath(const wchar *FullName,wchar *Path)
|
||||
// returns file path including the trailing path separator symbol
|
||||
void GetFilePath(const wchar *FullName,wchar *Path,int MaxLength)
|
||||
{
|
||||
const wchar *PathPtr=/*(*FullName && IsDriveDiv(FullName[1])) ? FullName+2:*/FullName;
|
||||
int PathLength=PointToName(FullName)-FullName;
|
||||
strncpyw(Path,PathPtr,PathLength);
|
||||
int PathLength=Min(MaxLength-1,PointToName(FullName)-FullName);
|
||||
strncpyw(Path,FullName,PathLength);
|
||||
Path[PathLength]=0;
|
||||
}
|
||||
|
||||
|
||||
// removes name and returns file path without the trailing
|
||||
// path separator symbol
|
||||
void RemoveNameFromPath(char *Path)
|
||||
{
|
||||
char *Name=PointToName(Path);
|
||||
@ -284,6 +288,8 @@ void RemoveNameFromPath(char *Path)
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
// removes name and returns file path without the trailing
|
||||
// path separator symbol
|
||||
void RemoveNameFromPath(wchar *Path)
|
||||
{
|
||||
wchar *Name=PointToName(Path);
|
||||
@ -294,6 +300,31 @@ void RemoveNameFromPath(wchar *Path)
|
||||
#endif
|
||||
|
||||
|
||||
#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE)
|
||||
void GetAppDataPath(char *Path)
|
||||
{
|
||||
LPMALLOC g_pMalloc;
|
||||
SHGetMalloc(&g_pMalloc);
|
||||
LPITEMIDLIST ppidl;
|
||||
*Path=0;
|
||||
bool Success=false;
|
||||
if (SHGetSpecialFolderLocation(NULL,CSIDL_APPDATA,&ppidl)==NOERROR &&
|
||||
SHGetPathFromIDList(ppidl,Path) && *Path!=0)
|
||||
{
|
||||
AddEndSlash(Path);
|
||||
strcat(Path,"WinRAR");
|
||||
Success=FileExist(Path) || MakeDir(Path,NULL,0)==MKDIR_SUCCESS;
|
||||
}
|
||||
if (!Success)
|
||||
{
|
||||
GetModuleFileName(NULL,Path,NM);
|
||||
RemoveNameFromPath(Path);
|
||||
}
|
||||
g_pMalloc->Free(ppidl);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef SFX_MODULE
|
||||
bool EnumConfigPaths(char *Path,int Number)
|
||||
{
|
||||
@ -320,7 +351,7 @@ bool EnumConfigPaths(char *Path,int Number)
|
||||
char *EnvStr=getenv("HOME");
|
||||
if (EnvStr==NULL)
|
||||
return(false);
|
||||
strncpy(Path,EnvStr,NM);
|
||||
strncpy(Path,EnvStr,NM-1);
|
||||
Path[NM-1]=0;
|
||||
return(true);
|
||||
}
|
||||
@ -333,11 +364,18 @@ bool EnumConfigPaths(char *Path,int Number)
|
||||
strcpy(Path,AltPath[Number]);
|
||||
return(true);
|
||||
#elif defined(_WIN_32)
|
||||
if (Number!=0)
|
||||
|
||||
if (Number<0 || Number>1)
|
||||
return(false);
|
||||
GetModuleFileName(NULL,Path,NM);
|
||||
RemoveNameFromPath(Path);
|
||||
if (Number==0)
|
||||
GetAppDataPath(Path);
|
||||
else
|
||||
{
|
||||
GetModuleFileName(NULL,Path,NM);
|
||||
RemoveNameFromPath(Path);
|
||||
}
|
||||
return(true);
|
||||
|
||||
#else
|
||||
return(false);
|
||||
#endif
|
||||
@ -359,6 +397,7 @@ void GetConfigName(const char *Name,char *FullName,bool CheckExist)
|
||||
#endif
|
||||
|
||||
|
||||
// returns a pointer to rightmost digit of volume number
|
||||
char* GetVolNumPart(char *ArcName)
|
||||
{
|
||||
char *ChPtr=ArcName+strlen(ArcName)-1;
|
||||
@ -506,10 +545,32 @@ char* DosSlashToUnix(char *SrcName,char *DestName,uint MaxLength)
|
||||
}
|
||||
|
||||
|
||||
wchar* UnixSlashToDos(wchar *SrcName,wchar *DestName,uint MaxLength)
|
||||
{
|
||||
if (DestName!=NULL && DestName!=SrcName)
|
||||
if (strlenw(SrcName)>=MaxLength)
|
||||
{
|
||||
*DestName=0;
|
||||
return(DestName);
|
||||
}
|
||||
else
|
||||
strcpyw(DestName,SrcName);
|
||||
for (wchar *s=SrcName;*s!=0;s++)
|
||||
{
|
||||
if (*s=='/')
|
||||
if (DestName==NULL)
|
||||
*s='\\';
|
||||
else
|
||||
DestName[s-SrcName]='\\';
|
||||
}
|
||||
return(DestName==NULL ? SrcName:DestName);
|
||||
}
|
||||
|
||||
|
||||
bool IsFullPath(const char *Path)
|
||||
{
|
||||
char PathOnly[NM];
|
||||
GetFilePath(Path,PathOnly);
|
||||
GetFilePath(Path,PathOnly,ASIZE(PathOnly));
|
||||
if (IsWildcard(PathOnly))
|
||||
return(true);
|
||||
#if defined(_WIN_32) || defined(_EMX)
|
||||
@ -523,7 +584,7 @@ bool IsFullPath(const char *Path)
|
||||
|
||||
bool IsDiskLetter(const char *Path)
|
||||
{
|
||||
char Letter=toupper(Path[0]);
|
||||
char Letter=etoupper(Path[0]);
|
||||
return(Letter>='A' && Letter<='Z' && IsDriveDiv(Path[1]));
|
||||
}
|
||||
|
||||
|
@ -19,10 +19,11 @@ bool IsDriveDiv(int Ch);
|
||||
int GetPathDisk(const char *Path);
|
||||
void AddEndSlash(char *Path);
|
||||
void AddEndSlash(wchar *Path);
|
||||
void GetFilePath(const char *FullName,char *Path);
|
||||
void GetFilePath(const wchar *FullName,wchar *Path);
|
||||
void GetFilePath(const char *FullName,char *Path,int MaxLength);
|
||||
void GetFilePath(const wchar *FullName,wchar *Path,int MaxLength);
|
||||
void RemoveNameFromPath(char *Path);
|
||||
void RemoveNameFromPath(wchar *Path);
|
||||
void GetAppDataPath(char *Path);
|
||||
bool EnumConfigPaths(char *Path,int Number);
|
||||
void GetConfigName(const char *Name,char *FullName,bool CheckExist);
|
||||
char* GetVolNumPart(char *ArcName);
|
||||
@ -31,6 +32,7 @@ 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 IsDiskLetter(const char *Path);
|
||||
void GetPathRoot(const char *Path,char *Root);
|
||||
|
@ -46,6 +46,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(_WIN_32) && !defined(SFX_MODULE) && !defined(SHELL_EXT)
|
||||
bool ShutdownOnClose;
|
||||
#endif
|
||||
|
||||
#ifdef ALLOW_EXCEPTIONS
|
||||
try
|
||||
@ -71,7 +74,7 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
if (Switch!=NULL && Cmd.IsSwitch(Switch[0]))
|
||||
{
|
||||
int UpperCmd=toupper(Switch[1]);
|
||||
int UpperCmd=etoupper(Switch[1]);
|
||||
switch(UpperCmd)
|
||||
{
|
||||
case 'T':
|
||||
@ -95,6 +98,9 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
Cmd.ParseDone();
|
||||
|
||||
#if defined(_WIN_32) && !defined(SFX_MODULE) && !defined(SHELL_EXT)
|
||||
ShutdownOnClose=Cmd.Shutdown;
|
||||
#endif
|
||||
|
||||
InitConsoleOptions(Cmd.MsgStream,Cmd.Sound);
|
||||
InitLogOptions(Cmd.LogName);
|
||||
@ -126,6 +132,10 @@ int main(int argc, char *argv[])
|
||||
#endif
|
||||
#if defined(_EMX) && !defined(_DJGPP)
|
||||
uni_done();
|
||||
#endif
|
||||
#if defined(_WIN_32) && !defined(SFX_MODULE) && !defined(SHELL_EXT)
|
||||
if (ShutdownOnClose)
|
||||
Shutdown();
|
||||
#endif
|
||||
return(ErrHandler.GetErrorCode());
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "errhnd.hpp"
|
||||
#include "array.hpp"
|
||||
#include "timefn.hpp"
|
||||
#include "options.hpp"
|
||||
#include "headers.hpp"
|
||||
#include "rarfn.hpp"
|
||||
#include "pathfn.hpp"
|
||||
@ -37,7 +38,6 @@
|
||||
#include "savepos.hpp"
|
||||
#include "getbits.hpp"
|
||||
#include "rdwrfn.hpp"
|
||||
#include "options.hpp"
|
||||
#include "archive.hpp"
|
||||
#include "match.hpp"
|
||||
#include "cmddata.hpp"
|
||||
|
@ -20,16 +20,37 @@ void RarVM::Init()
|
||||
Mem=new byte[VM_MEMSIZE+4];
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
IS_VM_MEM macro checks if address belongs to VM memory pool (Mem).
|
||||
Only Mem data are always low endian regardless of machine architecture,
|
||||
so we need to convert them to native format when reading or writing.
|
||||
VM registers have endianness of host machine.
|
||||
**********************************************************************/
|
||||
#define IS_VM_MEM(a) (((byte*)a)>=Mem && ((byte*)a)<Mem+VM_MEMSIZE)
|
||||
|
||||
inline uint RarVM::GetValue(bool ByteMode,uint *Addr)
|
||||
{
|
||||
if (ByteMode)
|
||||
{
|
||||
#ifdef BIG_ENDIAN
|
||||
if (IS_VM_MEM(Addr))
|
||||
return(*(byte *)Addr);
|
||||
else
|
||||
return(*Addr & 0xff);
|
||||
#else
|
||||
return(*(byte *)Addr);
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(BIG_ENDIAN) || !defined(ALLOW_NOT_ALIGNED_INT)
|
||||
byte *B=(byte *)Addr;
|
||||
return UINT32((uint)B[0]|((uint)B[1]<<8)|((uint)B[2]<<16)|((uint)B[3]<<24));
|
||||
if (IS_VM_MEM(Addr))
|
||||
{
|
||||
byte *B=(byte *)Addr;
|
||||
return UINT32((uint)B[0]|((uint)B[1]<<8)|((uint)B[2]<<16)|((uint)B[3]<<24));
|
||||
}
|
||||
else
|
||||
return UINT32(*Addr);
|
||||
#else
|
||||
return UINT32(*Addr);
|
||||
#endif
|
||||
@ -46,14 +67,28 @@ inline uint RarVM::GetValue(bool ByteMode,uint *Addr)
|
||||
inline void RarVM::SetValue(bool ByteMode,uint *Addr,uint Value)
|
||||
{
|
||||
if (ByteMode)
|
||||
{
|
||||
#ifdef BIG_ENDIAN
|
||||
if (IS_VM_MEM(Addr))
|
||||
*(byte *)Addr=Value;
|
||||
else
|
||||
*Addr=(*Addr & ~0xff)|(Value & 0xff);
|
||||
#else
|
||||
*(byte *)Addr=Value;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(BIG_ENDIAN) || !defined(ALLOW_NOT_ALIGNED_INT) || !defined(PRESENT_INT32)
|
||||
((byte *)Addr)[0]=(byte)Value;
|
||||
((byte *)Addr)[1]=(byte)(Value>>8);
|
||||
((byte *)Addr)[2]=(byte)(Value>>16);
|
||||
((byte *)Addr)[3]=(byte)(Value>>24);
|
||||
if (IS_VM_MEM(Addr))
|
||||
{
|
||||
((byte *)Addr)[0]=(byte)Value;
|
||||
((byte *)Addr)[1]=(byte)(Value>>8);
|
||||
((byte *)Addr)[2]=(byte)(Value>>16);
|
||||
((byte *)Addr)[3]=(byte)(Value>>24);
|
||||
}
|
||||
else
|
||||
*(uint *)Addr=Value;
|
||||
#else
|
||||
*(uint32 *)Addr=Value;
|
||||
#endif
|
||||
@ -67,9 +102,16 @@ inline void RarVM::SetValue(bool ByteMode,uint *Addr,uint Value)
|
||||
#endif
|
||||
|
||||
|
||||
void RarVM::SetValue(uint *Addr,uint Value)
|
||||
void RarVM::SetLowEndianValue(uint *Addr,uint Value)
|
||||
{
|
||||
SetValue(false,Addr,Value);
|
||||
#if defined(BIG_ENDIAN) || !defined(ALLOW_NOT_ALIGNED_INT) || !defined(PRESENT_INT32)
|
||||
((byte *)Addr)[0]=(byte)Value;
|
||||
((byte *)Addr)[1]=(byte)(Value>>8);
|
||||
((byte *)Addr)[2]=(byte)(Value>>16);
|
||||
((byte *)Addr)[3]=(byte)(Value>>24);
|
||||
#else
|
||||
*(uint32 *)Addr=Value;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -88,7 +130,7 @@ void RarVM::Execute(VM_PreparedProgram *Prg)
|
||||
unsigned int GlobalSize=Min(Prg->GlobalData.Size(),VM_GLOBALMEMSIZE);
|
||||
if (GlobalSize)
|
||||
memcpy(Mem+VM_GLOBALMEMADDR,&Prg->GlobalData[0],GlobalSize);
|
||||
uint StaticSize=Min((uint)Prg->StaticData.Size(),VM_GLOBALMEMSIZE-GlobalSize);
|
||||
unsigned int StaticSize=Min(Prg->StaticData.Size(),VM_GLOBALMEMSIZE-GlobalSize);
|
||||
if (StaticSize)
|
||||
memcpy(Mem+VM_GLOBALMEMADDR+GlobalSize,&Prg->StaticData[0],StaticSize);
|
||||
|
||||
@ -106,7 +148,8 @@ void RarVM::Execute(VM_PreparedProgram *Prg)
|
||||
Prg->FilteredDataSize=NewBlockSize;
|
||||
|
||||
Prg->GlobalData.Reset();
|
||||
uint DataSize=Min(GET_VALUE(false,(uint*)&Mem[VM_GLOBALMEMADDR+0x30]),VM_GLOBALMEMSIZE);
|
||||
|
||||
uint DataSize=Min(GET_VALUE(false,(uint*)&Mem[VM_GLOBALMEMADDR+0x30]),VM_GLOBALMEMSIZE-VM_FIXEDGLOBALSIZE);
|
||||
if (DataSize!=0)
|
||||
{
|
||||
Prg->GlobalData.Add(DataSize+VM_FIXEDGLOBALSIZE);
|
||||
@ -115,6 +158,14 @@ void RarVM::Execute(VM_PreparedProgram *Prg)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Note:
|
||||
Due to performance considerations RAR VM may set VM_FS, VM_FC, VM_FZ
|
||||
incorrectly for byte operands. These flags are always valid only
|
||||
for 32-bit operands. Check implementation of concrete VM command
|
||||
to see if it sets flags right.
|
||||
*/
|
||||
|
||||
#define SET_IP(IP) \
|
||||
if ((IP)>=CodeSize) \
|
||||
return(true); \
|
||||
@ -171,7 +222,13 @@ bool RarVM::ExecuteCode(VM_PreparedCommand *PreparedCode,int CodeSize)
|
||||
{
|
||||
uint Value1=GET_VALUE(Cmd->ByteMode,Op1);
|
||||
uint Result=UINT32(Value1+GET_VALUE(Cmd->ByteMode,Op2));
|
||||
Flags=Result==0 ? VM_FZ:(Result<Value1)|(Result&VM_FS);
|
||||
if (Cmd->ByteMode)
|
||||
{
|
||||
Result&=0xff;
|
||||
Flags=(Result<Value1)|(Result==0 ? VM_FZ:((Result&0x80) ? VM_FS:0));
|
||||
}
|
||||
else
|
||||
Flags=(Result<Value1)|(Result==0 ? VM_FZ:(Result&VM_FS));
|
||||
SET_VALUE(Cmd->ByteMode,Op1,Result);
|
||||
}
|
||||
break;
|
||||
@ -209,13 +266,15 @@ bool RarVM::ExecuteCode(VM_PreparedCommand *PreparedCode,int CodeSize)
|
||||
case VM_JNZ:
|
||||
if ((Flags & VM_FZ)==0)
|
||||
{
|
||||
SET_IP(GET_VALUE(false,(uint)Op1));
|
||||
SET_IP(GET_VALUE(false,Op1));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case VM_INC:
|
||||
{
|
||||
uint Result=UINT32(GET_VALUE(Cmd->ByteMode,Op1)+1);
|
||||
if (Cmd->ByteMode)
|
||||
Result&=0xff;
|
||||
SET_VALUE(Cmd->ByteMode,Op1,Result);
|
||||
Flags=Result==0 ? VM_FZ:Result&VM_FS;
|
||||
}
|
||||
@ -244,7 +303,7 @@ bool RarVM::ExecuteCode(VM_PreparedCommand *PreparedCode,int CodeSize)
|
||||
break;
|
||||
#endif
|
||||
case VM_JMP:
|
||||
SET_IP(GET_VALUE((uint)false,Op1));
|
||||
SET_IP(GET_VALUE(false,Op1));
|
||||
continue;
|
||||
case VM_XOR:
|
||||
{
|
||||
@ -276,42 +335,42 @@ bool RarVM::ExecuteCode(VM_PreparedCommand *PreparedCode,int CodeSize)
|
||||
case VM_JS:
|
||||
if ((Flags & VM_FS)!=0)
|
||||
{
|
||||
SET_IP(GET_VALUE((uint)false,Op1));
|
||||
SET_IP(GET_VALUE(false,Op1));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case VM_JNS:
|
||||
if ((Flags & VM_FS)==0)
|
||||
{
|
||||
SET_IP(GET_VALUE((uint)false,Op1));
|
||||
SET_IP(GET_VALUE(false,Op1));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case VM_JB:
|
||||
if ((Flags & VM_FC)!=0)
|
||||
{
|
||||
SET_IP(GET_VALUE((uint)false,Op1));
|
||||
SET_IP(GET_VALUE(false,Op1));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case VM_JBE:
|
||||
if ((Flags & (VM_FC|VM_FZ))!=0)
|
||||
{
|
||||
SET_IP(GET_VALUE((uint)false,Op1));
|
||||
SET_IP(GET_VALUE(false,Op1));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case VM_JA:
|
||||
if ((Flags & (VM_FC|VM_FZ))==0)
|
||||
{
|
||||
SET_IP(GET_VALUE((uint)false,Op1));
|
||||
SET_IP(GET_VALUE(false,Op1));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case VM_JAE:
|
||||
if ((Flags & VM_FC)==0)
|
||||
{
|
||||
SET_IP(GET_VALUE((uint)false,Op1));
|
||||
SET_IP(GET_VALUE(false,Op1));
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
@ -430,7 +489,9 @@ bool RarVM::ExecuteCode(VM_PreparedCommand *PreparedCode,int CodeSize)
|
||||
uint Value1=GET_VALUE(Cmd->ByteMode,Op1);
|
||||
uint FC=(Flags&VM_FC);
|
||||
uint Result=UINT32(Value1+GET_VALUE(Cmd->ByteMode,Op2)+FC);
|
||||
Flags=Result==0 ? VM_FZ:(Result<Value1 || Result==Value1 && FC)|(Result&VM_FS);
|
||||
if (Cmd->ByteMode)
|
||||
Result&=0xff;
|
||||
Flags=(Result<Value1 || Result==Value1 && FC)|(Result==0 ? VM_FZ:(Result&VM_FS));
|
||||
SET_VALUE(Cmd->ByteMode,Op1,Result);
|
||||
}
|
||||
break;
|
||||
@ -439,7 +500,9 @@ bool RarVM::ExecuteCode(VM_PreparedCommand *PreparedCode,int CodeSize)
|
||||
uint Value1=GET_VALUE(Cmd->ByteMode,Op1);
|
||||
uint FC=(Flags&VM_FC);
|
||||
uint Result=UINT32(Value1-GET_VALUE(Cmd->ByteMode,Op2)-FC);
|
||||
Flags=Result==0 ? VM_FZ:(Result>Value1 || Result==Value1 && FC)|(Result&VM_FS);
|
||||
if (Cmd->ByteMode)
|
||||
Result&=0xff;
|
||||
Flags=(Result>Value1 || Result==Value1 && FC)|(Result==0 ? VM_FZ:(Result&VM_FS));
|
||||
SET_VALUE(Cmd->ByteMode,Op1,Result);
|
||||
}
|
||||
break;
|
||||
@ -496,6 +559,10 @@ void RarVM::Prepare(byte *Code,int CodeSize,VM_PreparedProgram *Prg)
|
||||
#endif
|
||||
uint DataFlag=fgetbits();
|
||||
faddbits(1);
|
||||
|
||||
/* Read static data contained in DB operators. This data cannot be changed,
|
||||
it is a part of VM code, not a filter parameter.
|
||||
*/
|
||||
if (DataFlag&0x8000)
|
||||
{
|
||||
int DataSize=ReadData(*this)+1;
|
||||
@ -506,6 +573,7 @@ void RarVM::Prepare(byte *Code,int CodeSize,VM_PreparedProgram *Prg)
|
||||
faddbits(8);
|
||||
}
|
||||
}
|
||||
|
||||
while (InAddr<CodeSize)
|
||||
{
|
||||
Prg->Cmd.Add(1);
|
||||
@ -699,8 +767,6 @@ void RarVM::Optimize(VM_PreparedProgram *Prg)
|
||||
case VM_CMP:
|
||||
Cmd->OpCode=Cmd->ByteMode ? VM_CMPB:VM_CMPD;
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if ((VM_CmdFlags[Cmd->OpCode] & VMCF_CHFLAGS)==0)
|
||||
continue;
|
||||
@ -735,8 +801,6 @@ void RarVM::Optimize(VM_PreparedProgram *Prg)
|
||||
case VM_NEG:
|
||||
Cmd->OpCode=Cmd->ByteMode ? VM_NEGB:VM_NEGD;
|
||||
continue;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -864,6 +928,10 @@ void RarVM::ExecuteStandardFilter(VM_StandardFilters FilterType)
|
||||
SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20],DataSize);
|
||||
if (DataSize>=VM_GLOBALMEMADDR/2)
|
||||
break;
|
||||
|
||||
// bytes from same channels are grouped to continual data blocks,
|
||||
// so we need to place them back to their interleaving positions
|
||||
|
||||
for (int CurChannel=0;CurChannel<Channels;CurChannel++)
|
||||
{
|
||||
byte PrevByte=0;
|
||||
@ -878,7 +946,7 @@ void RarVM::ExecuteStandardFilter(VM_StandardFilters FilterType)
|
||||
byte *SrcData=Mem,*DestData=SrcData+DataSize;
|
||||
const int Channels=3;
|
||||
SET_VALUE(false,&Mem[VM_GLOBALMEMADDR+0x20],DataSize);
|
||||
if (DataSize>=VM_GLOBALMEMADDR/2)
|
||||
if (DataSize>=VM_GLOBALMEMADDR/2 || PosR<0)
|
||||
break;
|
||||
for (int CurChannel=0;CurChannel<Channels;CurChannel++)
|
||||
{
|
||||
|
@ -66,7 +66,7 @@ struct VM_PreparedProgram
|
||||
int CmdCount;
|
||||
|
||||
Array<byte> GlobalData;
|
||||
Array<byte> StaticData;
|
||||
Array<byte> StaticData; // static data contained in DB operators
|
||||
uint InitR[7];
|
||||
|
||||
byte *FilteredData;
|
||||
@ -101,7 +101,7 @@ class RarVM:private BitInput
|
||||
void Init();
|
||||
void Prepare(byte *Code,int CodeSize,VM_PreparedProgram *Prg);
|
||||
void Execute(VM_PreparedProgram *Prg);
|
||||
void SetValue(uint *Addr,uint Value);
|
||||
void SetLowEndianValue(uint *Addr,uint Value);
|
||||
void SetMemory(unsigned int Pos,byte *Data,unsigned int DataSize);
|
||||
static uint ReadData(BitInput &Inp);
|
||||
};
|
||||
|
@ -52,23 +52,38 @@ void RawRead::Read(byte *SrcData,int Size)
|
||||
|
||||
void RawRead::Get(byte &Field)
|
||||
{
|
||||
Field=Data[ReadPos];
|
||||
ReadPos++;
|
||||
if (ReadPos<DataSize)
|
||||
{
|
||||
Field=Data[ReadPos];
|
||||
ReadPos++;
|
||||
}
|
||||
else
|
||||
Field=0;
|
||||
}
|
||||
|
||||
|
||||
void RawRead::Get(ushort &Field)
|
||||
{
|
||||
Field=Data[ReadPos]+(Data[ReadPos+1]<<8);
|
||||
ReadPos+=2;
|
||||
if (ReadPos+1<DataSize)
|
||||
{
|
||||
Field=Data[ReadPos]+(Data[ReadPos+1]<<8);
|
||||
ReadPos+=2;
|
||||
}
|
||||
else
|
||||
Field=0;
|
||||
}
|
||||
|
||||
|
||||
void RawRead::Get(uint &Field)
|
||||
{
|
||||
Field=Data[ReadPos]+(Data[ReadPos+1]<<8)+(Data[ReadPos+2]<<16)+
|
||||
(Data[ReadPos+3]<<24);
|
||||
ReadPos+=4;
|
||||
if (ReadPos+3<DataSize)
|
||||
{
|
||||
Field=Data[ReadPos]+(Data[ReadPos+1]<<8)+(Data[ReadPos+2]<<16)+
|
||||
(Data[ReadPos+3]<<24);
|
||||
ReadPos+=4;
|
||||
}
|
||||
else
|
||||
Field=0;
|
||||
}
|
||||
|
||||
|
||||
@ -83,15 +98,25 @@ void RawRead::Get8(Int64 &Field)
|
||||
|
||||
void RawRead::Get(byte *Field,int Size)
|
||||
{
|
||||
memcpy(Field,&Data[ReadPos],Size);
|
||||
ReadPos+=Size;
|
||||
if (ReadPos+Size-1<DataSize)
|
||||
{
|
||||
memcpy(Field,&Data[ReadPos],Size);
|
||||
ReadPos+=Size;
|
||||
}
|
||||
else
|
||||
memset(Field,0,Size);
|
||||
}
|
||||
|
||||
|
||||
void RawRead::Get(wchar *Field,int Size)
|
||||
{
|
||||
RawToWide(&Data[ReadPos],Field,Size);
|
||||
ReadPos+=2*Size;
|
||||
if (ReadPos+2*Size-1<DataSize)
|
||||
{
|
||||
RawToWide(&Data[ReadPos],Field,Size);
|
||||
ReadPos+=2*Size;
|
||||
}
|
||||
else
|
||||
memset(Field,0,2*Size);
|
||||
}
|
||||
|
||||
|
||||
|
@ -92,7 +92,7 @@ int ComprDataIO::UnpRead(byte *Addr,uint Count)
|
||||
Decrypt.Crypt(Addr,RetCode,(Decryption==15) ? NEW_CRYPT : OLD_DECODE);
|
||||
else
|
||||
if (Decryption==20)
|
||||
for (int I=0;I<RetCode;I+=16)
|
||||
for (uint I=0;I<RetCode;I+=16)
|
||||
Decrypt.DecryptBlock20(&Addr[I]);
|
||||
else
|
||||
#endif
|
||||
|
@ -1,62 +1,62 @@
|
||||
|
||||
Portable UnRAR version
|
||||
|
||||
|
||||
1. General
|
||||
|
||||
This package includes freeware Unrar C++ source and a few makefiles
|
||||
(makefile.bcc, makefile.msc+msc.dep, makefile.unix). Unrar source
|
||||
is subset of RAR and generated from RAR source automatically,
|
||||
by a small program removing blocks like '#ifndef UNRAR ... #endif'.
|
||||
Such method is not perfect and you may find some RAR related
|
||||
stuff unnecessary in Unrar, especially in header files.
|
||||
|
||||
If you wish to port Unrar to a new platform, you may need to edit
|
||||
'#define LITTLE_ENDIAN' in os.hpp and data type definitions
|
||||
in rartypes.hpp.
|
||||
|
||||
if computer architecture does not allow not aligned data access,
|
||||
you need to undefine ALLOW_NOT_ALIGNED_INT and define
|
||||
STRICT_ALIGNMENT_REQUIRED in os.h. Note that it will increase memory
|
||||
requirements.
|
||||
|
||||
If you use Borland C++ makefile (makefile.bcc), you need to define
|
||||
BASEPATHCC environment (or makefile) variable containing
|
||||
the path to Borland C++ installation.
|
||||
|
||||
Makefile.unix contains numerous compiler option sets.
|
||||
GCC Linux is selected by default. If you need to compile Unrar
|
||||
for other platforms, uncomment corresponding lines.
|
||||
|
||||
|
||||
2. Unrar binaries
|
||||
|
||||
If you compiled Unrar for OS, which is not present in "Downloads"
|
||||
and "RAR extras" on www.rarlab.com, we will appreciate if you send
|
||||
us the compiled executable to place it to our site.
|
||||
|
||||
|
||||
3. Acknowledgements
|
||||
|
||||
This source includes parts of code written by the following authors:
|
||||
|
||||
Dmitry Shkarin PPMII text compression
|
||||
Dmitry Subbotin Carryless rangecoder
|
||||
Szymon Stefanek AES encryption
|
||||
Brian Gladman AES encryption
|
||||
Steve Reid SHA-1 hash function
|
||||
Marcus Herbert makefile.unix file
|
||||
Tomasz Klim fixes for libunrar.so
|
||||
|
||||
|
||||
4. Legal stuff
|
||||
|
||||
Unrar source may be used in any software to handle RAR archives
|
||||
without limitations free of charge, but cannot be used to re-create
|
||||
the RAR compression algorithm, which is proprietary. Distribution
|
||||
of modified Unrar source in separate form or as a part of other
|
||||
software is permitted, provided that it is clearly stated in
|
||||
the documentation and source comments that the code may not be used
|
||||
to develop a RAR (WinRAR) compatible archiver.
|
||||
|
||||
More detailed license text is available in license.txt.
|
||||
|
||||
Portable UnRAR version
|
||||
|
||||
|
||||
1. General
|
||||
|
||||
This package includes freeware Unrar C++ source and a few makefiles
|
||||
(makefile.bcc, makefile.msc+msc.dep, makefile.unix). Unrar source
|
||||
is subset of RAR and generated from RAR source automatically,
|
||||
by a small program removing blocks like '#ifndef UNRAR ... #endif'.
|
||||
Such method is not perfect and you may find some RAR related
|
||||
stuff unnecessary in Unrar, especially in header files.
|
||||
|
||||
If you wish to port Unrar to a new platform, you may need to edit
|
||||
'#define LITTLE_ENDIAN' in os.hpp and data type definitions
|
||||
in rartypes.hpp.
|
||||
|
||||
if computer architecture does not allow not aligned data access,
|
||||
you need to undefine ALLOW_NOT_ALIGNED_INT and define
|
||||
STRICT_ALIGNMENT_REQUIRED in os.h. Note that it will increase memory
|
||||
requirements.
|
||||
|
||||
If you use Borland C++ makefile (makefile.bcc), you need to define
|
||||
BASEPATHCC environment (or makefile) variable containing
|
||||
the path to Borland C++ installation.
|
||||
|
||||
Makefile.unix contains numerous compiler option sets.
|
||||
GCC Linux is selected by default. If you need to compile Unrar
|
||||
for other platforms, uncomment corresponding lines.
|
||||
|
||||
|
||||
2. Unrar binaries
|
||||
|
||||
If you compiled Unrar for OS, which is not present in "Downloads"
|
||||
and "RAR extras" on www.rarlab.com, we will appreciate if you send
|
||||
us the compiled executable to place it to our site.
|
||||
|
||||
|
||||
3. Acknowledgements
|
||||
|
||||
This source includes parts of code written by the following authors:
|
||||
|
||||
Dmitry Shkarin PPMII v.H text compression
|
||||
Dmitry Subbotin Carryless rangecoder
|
||||
Szymon Stefanek AES encryption
|
||||
Brian Gladman AES encryption
|
||||
Steve Reid SHA-1 hash function
|
||||
Marcus Herbert makefile.unix file
|
||||
Tomasz Klim fixes for libunrar.so
|
||||
|
||||
|
||||
4. Legal stuff
|
||||
|
||||
Unrar source may be used in any software to handle RAR archives
|
||||
without limitations free of charge, but cannot be used to re-create
|
||||
the RAR compression algorithm, which is proprietary. Distribution
|
||||
of modified Unrar source in separate form or as a part of other
|
||||
software is permitted, provided that it is clearly stated in
|
||||
the documentation and source comments that the code may not be used
|
||||
to develop a RAR (WinRAR) compatible archiver.
|
||||
|
||||
More detailed license text is available in license.txt.
|
||||
|
@ -11,7 +11,7 @@ RecVolumes::RecVolumes()
|
||||
|
||||
RecVolumes::~RecVolumes()
|
||||
{
|
||||
for (uint I=0;I<sizeof(SrcFile)/sizeof(SrcFile[0]);I++)
|
||||
for (int I=0;I<sizeof(SrcFile)/sizeof(SrcFile[0]);I++)
|
||||
delete SrcFile[I];
|
||||
}
|
||||
|
||||
@ -132,7 +132,7 @@ bool RecVolumes::Restore(RAROptions *Cmd,const char *Name,
|
||||
if (Dot==NULL)
|
||||
continue;
|
||||
bool WrongParam=false;
|
||||
for (uint I=0;I<sizeof(P)/sizeof(P[0]);I++)
|
||||
for (int I=0;I<sizeof(P)/sizeof(P[0]);I++)
|
||||
{
|
||||
do
|
||||
{
|
||||
|
@ -59,6 +59,8 @@ bool ScanTree::PrepareMasks()
|
||||
{
|
||||
if (!FileMasks->GetString(CurMask,CurMaskW,sizeof(CurMask)))
|
||||
return(false);
|
||||
CurMask[ASIZE(CurMask)-1]=0;
|
||||
CurMaskW[ASIZE(CurMaskW)-1]=0;
|
||||
#ifdef _WIN_32
|
||||
UnixSlashToDos(CurMask);
|
||||
#endif
|
||||
|
@ -2,10 +2,16 @@
|
||||
|
||||
int ToPercent(Int64 N1,Int64 N2)
|
||||
{
|
||||
if (N2==0)
|
||||
return(0);
|
||||
if (N2<N1)
|
||||
return(100);
|
||||
return(ToPercentUnlim(N1,N2));
|
||||
}
|
||||
|
||||
/* allows percent larger than 100 */
|
||||
int ToPercentUnlim(Int64 N1,Int64 N2)
|
||||
{
|
||||
if (N2==0)
|
||||
return(0);
|
||||
return(int64to32(N1*100/N2));
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define _RAR_SMALLFN_
|
||||
|
||||
int ToPercent(Int64 N1,Int64 N2);
|
||||
int ToPercentUnlim(Int64 N1,Int64 N2);
|
||||
void RARInitData();
|
||||
|
||||
#endif
|
||||
|
@ -69,17 +69,17 @@ char* strupper(char *Str)
|
||||
int stricomp(const char *Str1,const char *Str2)
|
||||
{
|
||||
char S1[NM*2],S2[NM*2];
|
||||
strncpy(S1,Str1,sizeof(S1));
|
||||
strncpy(S2,Str2,sizeof(S2));
|
||||
strncpyz(S1,Str1,ASIZE(S1));
|
||||
strncpyz(S2,Str2,ASIZE(S2));
|
||||
return(strcmp(strupper(S1),strupper(S2)));
|
||||
}
|
||||
|
||||
|
||||
int strnicomp(const char *Str1,const char *Str2,int N)
|
||||
{
|
||||
char S1[512],S2[512];
|
||||
strncpy(S1,Str1,sizeof(S1));
|
||||
strncpy(S2,Str2,sizeof(S2));
|
||||
char S1[NM*2],S2[NM*2];
|
||||
strncpyz(S1,Str1,ASIZE(S1));
|
||||
strncpyz(S2,Str2,ASIZE(S2));
|
||||
return(strncmp(strupper(S1),strupper(S2),N));
|
||||
}
|
||||
|
||||
@ -120,6 +120,17 @@ unsigned int loctoupper(byte ch)
|
||||
}
|
||||
|
||||
|
||||
// toupper with English only results. Avoiding Turkish i -> I conversion
|
||||
// problem
|
||||
int etoupper(int ch)
|
||||
{
|
||||
if (ch=='i')
|
||||
return('I');
|
||||
return(toupper(ch));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@ -163,3 +174,26 @@ int stricompcw(const wchar *Str1,const wchar *Str2)
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
// safe strncpy: copies maxlen-1 max and always returns zero terminated dest
|
||||
char* strncpyz(char *dest, const char *src, size_t maxlen)
|
||||
{
|
||||
if (maxlen>0)
|
||||
{
|
||||
strncpy(dest,src,maxlen-1);
|
||||
dest[maxlen-1]=0;
|
||||
}
|
||||
return(dest);
|
||||
}
|
||||
|
||||
// safe strncpyw: copies maxlen-1 max and always returns zero terminated dest
|
||||
wchar* strncpyzw(wchar *dest, const wchar *src, size_t maxlen)
|
||||
{
|
||||
if (maxlen>0)
|
||||
{
|
||||
strncpyw(dest,src,maxlen-1);
|
||||
dest[maxlen-1]=0;
|
||||
}
|
||||
return(dest);
|
||||
}
|
||||
|
@ -15,6 +15,11 @@ char* RemoveLF(char *Str);
|
||||
unsigned int loctolower(byte ch);
|
||||
unsigned int loctoupper(byte ch);
|
||||
|
||||
char* strncpyz(char *dest, const char *src, size_t maxlen);
|
||||
wchar* strncpyzw(wchar *dest, const wchar *src, size_t maxlen);
|
||||
|
||||
int etoupper(int ch);
|
||||
|
||||
|
||||
|
||||
bool LowAscii(const char *Str);
|
||||
|
@ -96,13 +96,13 @@ char* StringList::GetString()
|
||||
|
||||
bool StringList::GetString(char **Str,wchar **StrW)
|
||||
{
|
||||
if (CurPos>=(uint)StringData.Size())
|
||||
if (CurPos>=StringData.Size())
|
||||
{
|
||||
*Str=NULL;
|
||||
return(false);
|
||||
}
|
||||
*Str=&StringData[CurPos];
|
||||
if (PosDataItem<(uint)PosDataW.Size() && (uint)PosDataW[PosDataItem]==CurPos)
|
||||
if (PosDataItem<PosDataW.Size() && PosDataW[PosDataItem]==CurPos)
|
||||
{
|
||||
PosDataItem++;
|
||||
if (StrW!=NULL)
|
||||
@ -119,7 +119,7 @@ bool StringList::GetString(char **Str,wchar **StrW)
|
||||
|
||||
char* StringList::GetString(unsigned int StringPos)
|
||||
{
|
||||
if (StringPos>=(uint)StringData.Size())
|
||||
if (StringPos>=StringData.Size())
|
||||
return(NULL);
|
||||
return(&StringData[StringPos]);
|
||||
}
|
||||
|
@ -77,3 +77,26 @@ void Wait()
|
||||
|
||||
|
||||
|
||||
#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE) && !defined(SHELL_EXT)
|
||||
|
||||
#ifndef SHTDN_REASON_MAJOR_APPLICATION
|
||||
#define SHTDN_REASON_MAJOR_APPLICATION 0x00040000
|
||||
#define SHTDN_REASON_FLAG_PLANNED 0x80000000
|
||||
#define SHTDN_REASON_MINOR_MAINTENANCE 0x00000001
|
||||
#endif
|
||||
|
||||
void Shutdown()
|
||||
{
|
||||
HANDLE hToken;
|
||||
TOKEN_PRIVILEGES tkp;
|
||||
if (OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES|TOKEN_QUERY,&hToken))
|
||||
{
|
||||
LookupPrivilegeValue(NULL,SE_SHUTDOWN_NAME,&tkp.Privileges[0].Luid);
|
||||
tkp.PrivilegeCount = 1;
|
||||
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
|
||||
AdjustTokenPrivileges(hToken,FALSE,&tkp,0,(PTOKEN_PRIVILEGES)NULL,0);
|
||||
}
|
||||
ExitWindowsEx(EWX_SHUTDOWN|EWX_FORCE|EWX_POWEROFF,SHTDN_REASON_FLAG_PLANNED);
|
||||
}
|
||||
#endif
|
||||
|
@ -223,7 +223,7 @@ void RarTime::SetAgeText(char *TimeText)
|
||||
Value=Value*10+Ch-'0';
|
||||
else
|
||||
{
|
||||
switch(toupper(Ch))
|
||||
switch(etoupper(Ch))
|
||||
{
|
||||
case 'D':
|
||||
Seconds+=Value*24*3600;
|
||||
|
@ -18,6 +18,17 @@ bool WideToChar(const wchar *Src,char *Dest,int DestSize)
|
||||
// TODO: haiku fix this!
|
||||
if (wcstombs(Dest,Src,DestSize)==(size_t)-1)
|
||||
RetCode=false;
|
||||
|
||||
if ((!RetCode || *Dest==0 && *Src!=0) && DestSize>NM && strlenw(Src)<NM)
|
||||
{
|
||||
/* Workaround for strange Linux Unicode functions bug.
|
||||
Some of wcstombs and mbstowcs implementations in some situations
|
||||
(we are yet to find out what it depends on) can return an empty
|
||||
string and success code if buffer size value is too large.
|
||||
*/
|
||||
return(WideToChar(Src,Dest,NM));
|
||||
}
|
||||
|
||||
#else
|
||||
if (UnicodeEnabled())
|
||||
{
|
||||
@ -57,6 +68,16 @@ bool CharToWide(const char *Src,wchar *Dest,int DestSize)
|
||||
// TODO: haiku fix this!
|
||||
if (mbstowcs(Dest,Src,DestSize)==(size_t)-1)
|
||||
RetCode=false;
|
||||
|
||||
if ((!RetCode || *Dest==0 && *Src!=0) && DestSize>NM && strlen(Src)<NM)
|
||||
{
|
||||
/* Workaround for strange Linux Unicode functions bug.
|
||||
Some of wcstombs and mbstowcs implementations in some situations
|
||||
(we are yet to find out what it depends on) can return an empty
|
||||
string and success code if buffer size value is too large.
|
||||
*/
|
||||
return(CharToWide(Src,Dest,NM));
|
||||
}
|
||||
#else
|
||||
if (UnicodeEnabled())
|
||||
{
|
||||
@ -300,8 +321,8 @@ inline int strnicmpw_w2c(const wchar *s1,const wchar *s2,int n)
|
||||
wchar Wide1[NM*2],Wide2[NM*2];
|
||||
strncpyw(Wide1,s1,sizeof(Wide1)/sizeof(Wide1[0])-1);
|
||||
strncpyw(Wide2,s2,sizeof(Wide2)/sizeof(Wide2[0])-1);
|
||||
Wide1[Min(sizeof(Wide1)/sizeof(Wide1[0])-1,(uint)n)]=0;
|
||||
Wide2[Min(sizeof(Wide2)/sizeof(Wide2[0])-1,(uint)n)]=0;
|
||||
Wide1[Min(sizeof(Wide1)/sizeof(Wide1[0])-1,n)]=0;
|
||||
Wide2[Min(sizeof(Wide2)/sizeof(Wide2[0])-1,n)]=0;
|
||||
char Ansi1[NM*2],Ansi2[NM*2];
|
||||
WideToChar(Wide1,Ansi1,sizeof(Ansi1));
|
||||
WideToChar(Wide2,Ansi2,sizeof(Ansi2));
|
||||
|
@ -18,10 +18,10 @@ int uni_init(int codepage);
|
||||
int uni_done();
|
||||
#endif
|
||||
|
||||
bool WideToChar(const wchar *Src,char *Dest,int DestSize=0x10000000);
|
||||
bool CharToWide(const char *Src,wchar *Dest,int DestSize=0x10000000);
|
||||
byte* WideToRaw(const wchar *Src,byte *Dest,int DestSize=0x10000000);
|
||||
wchar* RawToWide(const byte *Src,wchar *Dest,int DestSize=0x10000000);
|
||||
bool WideToChar(const wchar *Src,char *Dest,int DestSize=0x1000000);
|
||||
bool CharToWide(const char *Src,wchar *Dest,int DestSize=0x1000000);
|
||||
byte* WideToRaw(const wchar *Src,byte *Dest,int DestSize=0x1000000);
|
||||
wchar* RawToWide(const byte *Src,wchar *Dest,int DestSize=0x1000000);
|
||||
void WideToUtf(const wchar *Src,char *Dest,int DestSize);
|
||||
void UtfToWide(const char *Src,wchar *Dest,int DestSize);
|
||||
bool UnicodeEnabled();
|
||||
|
@ -492,28 +492,35 @@ bool Unpack::AddVMCode(unsigned int FirstByte,byte *Code,int CodeSize)
|
||||
FiltPos--;
|
||||
}
|
||||
else
|
||||
FiltPos=LastFilter;
|
||||
FiltPos=LastFilter; // use the same filter as last time
|
||||
|
||||
if (FiltPos>Filters.Size() || FiltPos>OldFilterLengths.Size())
|
||||
return(false);
|
||||
LastFilter=FiltPos;
|
||||
bool NewFilter=(FiltPos==Filters.Size());
|
||||
|
||||
UnpackFilter *StackFilter=new UnpackFilter; // new filter for PrgStack
|
||||
|
||||
UnpackFilter *Filter;
|
||||
if (NewFilter)
|
||||
if (NewFilter) // new filter code, never used before since VM reset
|
||||
{
|
||||
// too many different filters, corrupt archive
|
||||
if (FiltPos>1024)
|
||||
return(false);
|
||||
|
||||
Filters.Add(1);
|
||||
Filters[Filters.Size()-1]=Filter=new UnpackFilter;
|
||||
StackFilter->ParentFilter=Filters.Size()-1;
|
||||
OldFilterLengths.Add(1);
|
||||
Filter->ExecCount=0;
|
||||
}
|
||||
else
|
||||
else // filter was used in the past
|
||||
{
|
||||
Filter=Filters[FiltPos];
|
||||
StackFilter->ParentFilter=FiltPos;
|
||||
Filter->ExecCount++;
|
||||
}
|
||||
|
||||
UnpackFilter *StackFilter=new UnpackFilter;
|
||||
|
||||
int EmptyCount=0;
|
||||
for (int I=0;I<PrgStack.Size();I++)
|
||||
{
|
||||
@ -550,7 +557,8 @@ bool Unpack::AddVMCode(unsigned int FirstByte,byte *Code,int CodeSize)
|
||||
StackFilter->Prg.InitR[3]=VM_GLOBALMEMADDR;
|
||||
StackFilter->Prg.InitR[4]=StackFilter->BlockLength;
|
||||
StackFilter->Prg.InitR[5]=StackFilter->ExecCount;
|
||||
if (FirstByte & 0x10)
|
||||
|
||||
if (FirstByte & 0x10) // set registers to optional parameters if any
|
||||
{
|
||||
unsigned int InitMask=Inp.fgetbits()>>9;
|
||||
Inp.faddbits(7);
|
||||
@ -558,6 +566,7 @@ bool Unpack::AddVMCode(unsigned int FirstByte,byte *Code,int CodeSize)
|
||||
if (InitMask & (1<<I))
|
||||
StackFilter->Prg.InitR[I]=RarVM::ReadData(Inp);
|
||||
}
|
||||
|
||||
if (NewFilter)
|
||||
{
|
||||
uint VMCodeSize=RarVM::ReadData(Inp);
|
||||
@ -566,6 +575,8 @@ bool Unpack::AddVMCode(unsigned int FirstByte,byte *Code,int CodeSize)
|
||||
Array<byte> VMCode(VMCodeSize);
|
||||
for (int I=0;I<VMCodeSize;I++)
|
||||
{
|
||||
if (Inp.Overflow(3))
|
||||
return(false);
|
||||
VMCode[I]=Inp.fgetbits()>>8;
|
||||
Inp.faddbits(8);
|
||||
}
|
||||
@ -577,6 +588,7 @@ bool Unpack::AddVMCode(unsigned int FirstByte,byte *Code,int CodeSize)
|
||||
int StaticDataSize=Filter->Prg.StaticData.Size();
|
||||
if (StaticDataSize>0 && StaticDataSize<VM_GLOBALMEMSIZE)
|
||||
{
|
||||
// read statically defined data contained in DB commands
|
||||
StackFilter->Prg.StaticData.Add(StaticDataSize);
|
||||
memcpy(&StackFilter->Prg.StaticData[0],&Filter->Prg.StaticData[0],StaticDataSize);
|
||||
}
|
||||
@ -588,16 +600,18 @@ bool Unpack::AddVMCode(unsigned int FirstByte,byte *Code,int CodeSize)
|
||||
}
|
||||
byte *GlobalData=&StackFilter->Prg.GlobalData[0];
|
||||
for (int I=0;I<7;I++)
|
||||
VM.SetValue((uint *)&GlobalData[I*4],StackFilter->Prg.InitR[I]);
|
||||
VM.SetValue((uint *)&GlobalData[0x1c],StackFilter->BlockLength);
|
||||
VM.SetValue((uint *)&GlobalData[0x20],0);
|
||||
VM.SetValue((uint *)&GlobalData[0x2c],StackFilter->ExecCount);
|
||||
VM.SetLowEndianValue((uint *)&GlobalData[I*4],StackFilter->Prg.InitR[I]);
|
||||
VM.SetLowEndianValue((uint *)&GlobalData[0x1c],StackFilter->BlockLength);
|
||||
VM.SetLowEndianValue((uint *)&GlobalData[0x20],0);
|
||||
VM.SetLowEndianValue((uint *)&GlobalData[0x2c],StackFilter->ExecCount);
|
||||
memset(&GlobalData[0x30],0,16);
|
||||
|
||||
if (FirstByte & 8)
|
||||
if (FirstByte & 8) // put data block passed as parameter if any
|
||||
{
|
||||
if (Inp.Overflow(3))
|
||||
return(false);
|
||||
uint DataSize=RarVM::ReadData(Inp);
|
||||
if (DataSize>=0x10000)
|
||||
if (DataSize>VM_GLOBALMEMSIZE-VM_FIXEDGLOBALSIZE)
|
||||
return(false);
|
||||
unsigned int CurSize=StackFilter->Prg.GlobalData.Size();
|
||||
if (CurSize<DataSize+VM_FIXEDGLOBALSIZE)
|
||||
@ -605,6 +619,8 @@ bool Unpack::AddVMCode(unsigned int FirstByte,byte *Code,int CodeSize)
|
||||
byte *GlobalData=&StackFilter->Prg.GlobalData[VM_FIXEDGLOBALSIZE];
|
||||
for (int I=0;I<DataSize;I++)
|
||||
{
|
||||
if (Inp.Overflow(3))
|
||||
return(false);
|
||||
GlobalData[I]=Inp.fgetbits()>>8;
|
||||
Inp.faddbits(8);
|
||||
}
|
||||
@ -670,9 +686,29 @@ void Unpack::UnpWriteBuf()
|
||||
VM.SetMemory(0,Window+BlockStart,FirstPartLength);
|
||||
VM.SetMemory(FirstPartLength,Window,BlockEnd);
|
||||
}
|
||||
|
||||
VM_PreparedProgram *ParentPrg=&Filters[flt->ParentFilter]->Prg;
|
||||
VM_PreparedProgram *Prg=&flt->Prg;
|
||||
|
||||
if (ParentPrg->GlobalData.Size()>VM_FIXEDGLOBALSIZE)
|
||||
{
|
||||
// copy global data from previous script execution if any
|
||||
Prg->GlobalData.Alloc(ParentPrg->GlobalData.Size());
|
||||
memcpy(&Prg->GlobalData[VM_FIXEDGLOBALSIZE],&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],ParentPrg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);
|
||||
}
|
||||
|
||||
ExecuteCode(Prg);
|
||||
|
||||
if (Prg->GlobalData.Size()>VM_FIXEDGLOBALSIZE)
|
||||
{
|
||||
// save global data for next script execution
|
||||
if (ParentPrg->GlobalData.Size()<Prg->GlobalData.Size())
|
||||
ParentPrg->GlobalData.Alloc(Prg->GlobalData.Size());
|
||||
memcpy(&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],&Prg->GlobalData[VM_FIXEDGLOBALSIZE],Prg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);
|
||||
}
|
||||
else
|
||||
ParentPrg->GlobalData.Reset();
|
||||
|
||||
byte *FilteredData=Prg->FilteredData;
|
||||
unsigned int FilteredDataSize=Prg->FilteredDataSize;
|
||||
|
||||
@ -684,9 +720,33 @@ void Unpack::UnpWriteBuf()
|
||||
if (NextFilter==NULL || NextFilter->BlockStart!=BlockStart ||
|
||||
NextFilter->BlockLength!=FilteredDataSize || NextFilter->NextWindow)
|
||||
break;
|
||||
|
||||
// apply several filters to same data block
|
||||
|
||||
VM.SetMemory(0,FilteredData,FilteredDataSize);
|
||||
VM_PreparedProgram *NextPrg=&PrgStack[I+1]->Prg;
|
||||
|
||||
VM_PreparedProgram *ParentPrg=&Filters[NextFilter->ParentFilter]->Prg;
|
||||
VM_PreparedProgram *NextPrg=&NextFilter->Prg;
|
||||
|
||||
if (ParentPrg->GlobalData.Size()>VM_FIXEDGLOBALSIZE)
|
||||
{
|
||||
// copy global data from previous script execution if any
|
||||
NextPrg->GlobalData.Alloc(ParentPrg->GlobalData.Size());
|
||||
memcpy(&NextPrg->GlobalData[VM_FIXEDGLOBALSIZE],&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],ParentPrg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);
|
||||
}
|
||||
|
||||
ExecuteCode(NextPrg);
|
||||
|
||||
if (NextPrg->GlobalData.Size()>VM_FIXEDGLOBALSIZE)
|
||||
{
|
||||
// save global data for next script execution
|
||||
if (ParentPrg->GlobalData.Size()<NextPrg->GlobalData.Size())
|
||||
ParentPrg->GlobalData.Alloc(NextPrg->GlobalData.Size());
|
||||
memcpy(&ParentPrg->GlobalData[VM_FIXEDGLOBALSIZE],&NextPrg->GlobalData[VM_FIXEDGLOBALSIZE],NextPrg->GlobalData.Size()-VM_FIXEDGLOBALSIZE);
|
||||
}
|
||||
else
|
||||
ParentPrg->GlobalData.Reset();
|
||||
|
||||
FilteredData=NextPrg->FilteredData;
|
||||
FilteredDataSize=NextPrg->FilteredDataSize;
|
||||
I++;
|
||||
@ -723,8 +783,8 @@ void Unpack::ExecuteCode(VM_PreparedProgram *Prg)
|
||||
if (Prg->GlobalData.Size()>0)
|
||||
{
|
||||
Prg->InitR[6]=int64to32(WrittenFileSize);
|
||||
VM.SetValue((uint *)&Prg->GlobalData[0x24],int64to32(WrittenFileSize));
|
||||
VM.SetValue((uint *)&Prg->GlobalData[0x28],int64to32(WrittenFileSize>>32));
|
||||
VM.SetLowEndianValue((uint *)&Prg->GlobalData[0x24],int64to32(WrittenFileSize));
|
||||
VM.SetLowEndianValue((uint *)&Prg->GlobalData[0x28],int64to32(WrittenFileSize>>32));
|
||||
VM.Execute(Prg);
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +57,11 @@ struct UnpackFilter
|
||||
unsigned int BlockLength;
|
||||
unsigned int ExecCount;
|
||||
bool NextWindow;
|
||||
|
||||
// position of parent filter in Filters array used as prototype for filter
|
||||
// in PrgStack array. Not defined for filters in Filters array.
|
||||
unsigned int ParentFilter;
|
||||
|
||||
VM_PreparedProgram Prg;
|
||||
};
|
||||
|
||||
@ -111,9 +116,17 @@ class Unpack:private BitInput
|
||||
int PPMEscChar;
|
||||
|
||||
RarVM VM;
|
||||
|
||||
/* Filters code, one entry per filter */
|
||||
Array<UnpackFilter*> Filters;
|
||||
|
||||
/* Filters stack, several entrances of same filter are possible */
|
||||
Array<UnpackFilter*> PrgStack;
|
||||
|
||||
/* lengths of preceding blocks, one length per filter. Used to reduce
|
||||
size required to write block length if lengths are repeating */
|
||||
Array<int> OldFilterLengths;
|
||||
|
||||
int LastFilter;
|
||||
|
||||
bool TablesRead;
|
||||
|
@ -136,6 +136,9 @@ void Unpack::OldUnpWriteBuf()
|
||||
}
|
||||
|
||||
|
||||
#define GetShortLen1(pos) ((pos)==1 ? Buf60+3:ShortLen1[pos])
|
||||
#define GetShortLen2(pos) ((pos)==3 ? Buf60+3:ShortLen2[pos])
|
||||
|
||||
void Unpack::ShortLZ()
|
||||
{
|
||||
static unsigned int ShortLen1[]={1,3,4,4,5,6,7,8,8,4,4,5,6,6,4,0};
|
||||
@ -167,21 +170,22 @@ void Unpack::ShortLZ()
|
||||
|
||||
BitField>>=8;
|
||||
|
||||
ShortLen1[1]=ShortLen2[3]=Buf60+3;
|
||||
// not thread safe, replaced by GetShortLen1 and GetShortLen2 macro
|
||||
// ShortLen1[1]=ShortLen2[3]=Buf60+3;
|
||||
|
||||
if (AvrLn1<37)
|
||||
{
|
||||
for (Length=0;;Length++)
|
||||
if (((BitField^ShortXor1[Length]) & (~(0xff>>ShortLen1[Length])))==0)
|
||||
if (((BitField^ShortXor1[Length]) & (~(0xff>>GetShortLen1(Length))))==0)
|
||||
break;
|
||||
faddbits(ShortLen1[Length]);
|
||||
faddbits(GetShortLen1(Length));
|
||||
}
|
||||
else
|
||||
{
|
||||
for (Length=0;;Length++)
|
||||
if (((BitField^ShortXor2[Length]) & (~(0xff>>ShortLen2[Length])))==0)
|
||||
if (((BitField^ShortXor2[Length]) & (~(0xff>>GetShortLen2(Length))))==0)
|
||||
break;
|
||||
faddbits(ShortLen2[Length]);
|
||||
faddbits(GetShortLen2(Length));
|
||||
}
|
||||
|
||||
if (Length >= 9)
|
||||
|
@ -4,10 +4,10 @@ resource app_flags B_MULTIPLE_LAUNCH | B_BACKGROUND_APP;
|
||||
|
||||
resource app_version {
|
||||
major = 3,
|
||||
middle = 6,
|
||||
minor = 7,
|
||||
middle = 7,
|
||||
minor = 6,
|
||||
variety = 0,
|
||||
internal = 0,
|
||||
short_info = "3.67",
|
||||
long_info = "3.67 Alexander Roshal"
|
||||
short_info = "3.76",
|
||||
long_info = "3.76 Alexander Roshal"
|
||||
};
|
||||
|
@ -1,6 +1,6 @@
|
||||
#define RARVER_MAJOR 3
|
||||
#define RARVER_MINOR 60
|
||||
#define RARVER_BETA 7
|
||||
#define RARVER_DAY 13
|
||||
#define RARVER_MONTH 7
|
||||
#define RARVER_YEAR 2006
|
||||
#define RARVER_MINOR 70
|
||||
#define RARVER_BETA 0
|
||||
#define RARVER_DAY 22
|
||||
#define RARVER_MONTH 5
|
||||
#define RARVER_YEAR 2007
|
||||
|
@ -22,15 +22,43 @@ bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,char Comman
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(SFX_MODULE) && !defined(RARDLL)
|
||||
bool RecoveryDone=false;
|
||||
#endif
|
||||
bool FailedOpen=false,OldSchemeTested=false;
|
||||
|
||||
while (!Arc.Open(NextName))
|
||||
while (!Arc.Open(NextName,NextNameW))
|
||||
{
|
||||
if (!OldSchemeTested)
|
||||
{
|
||||
@ -41,6 +69,7 @@ bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,char Comman
|
||||
if (Arc.Open(AltNextName))
|
||||
{
|
||||
strcpy(NextName,AltNextName);
|
||||
*NextNameW=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -94,6 +123,7 @@ bool MergeArchive(Archive &Arc,ComprDataIO *DataIO,bool ShowFileName,char Comman
|
||||
FailedOpen=true;
|
||||
break;
|
||||
}
|
||||
*NextNameW=0;
|
||||
#endif
|
||||
}
|
||||
if (FailedOpen)
|
||||
|
@ -33,7 +33,8 @@ void ExtractStreams(Archive &Arc,char *FileName,wchar *FileNameW)
|
||||
}
|
||||
else
|
||||
strcpy(StreamName,FileName);
|
||||
if (strlen(StreamName)+strlen((char *)Arc.StreamHead.StreamName)>=sizeof(StreamName))
|
||||
if (strlen(StreamName)+strlen((char *)Arc.StreamHead.StreamName)>=sizeof(StreamName) ||
|
||||
Arc.StreamHead.StreamName[0]!=':')
|
||||
{
|
||||
#ifndef SILENT
|
||||
Log(Arc.FileName,St(MStreamBroken),FileName);
|
||||
@ -42,6 +43,8 @@ void ExtractStreams(Archive &Arc,char *FileName,wchar *FileNameW)
|
||||
return;
|
||||
}
|
||||
|
||||
ConvertPath((char *)Arc.StreamHead.StreamName+1,(char *)Arc.StreamHead.StreamName+1);
|
||||
|
||||
strcat(StreamName,(char *)Arc.StreamHead.StreamName);
|
||||
|
||||
FindData fd;
|
||||
@ -119,6 +122,17 @@ void ExtractStreamsNew(Archive &Arc,char *FileName,wchar *FileNameW)
|
||||
RawToWide(SrcName,DestName,DestSize);
|
||||
DestName[DestSize]=0;
|
||||
|
||||
if (*DestName!=':')
|
||||
{
|
||||
#if !defined(SILENT) && !defined(SFX_MODULE)
|
||||
Log(Arc.FileName,St(MStreamBroken),FileName);
|
||||
#endif
|
||||
ErrHandler.SetErrorCode(CRC_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
ConvertPath(DestName+1,DestName+1);
|
||||
|
||||
FindData fd;
|
||||
bool Found=FindFile::FastFind(FileName,FileNameW,&fd);
|
||||
|
||||
@ -133,6 +147,8 @@ void ExtractStreamsNew(Archive &Arc,char *FileName,wchar *FileNameW)
|
||||
if (Found && HostFile.Open(FileName,FileNameW,true,true))
|
||||
SetFileTime(HostFile.GetHandle(),&fd.ftCreationTime,&fd.ftLastAccessTime,
|
||||
&fd.ftLastWriteTime);
|
||||
if (fd.FileAttr & FILE_ATTRIBUTE_READONLY)
|
||||
SetFileAttr(FileName,FileNameW,fd.FileAttr);
|
||||
|
||||
// Restoring original file attributes. Important if file was read only
|
||||
// or did not have "Archive" attribute
|
||||
SetFileAttr(FileName,FileNameW,fd.FileAttr);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user