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