Added unrar 3.6.7 to the repository. Most changes to the original versions done
by Ioan Molnar - thanks! Looks like our mbstowcs() function is broken, BTW - it needs to be disabled when used under Haiku. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19341 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -21,7 +21,8 @@ resource(1, "BEOS:FILE_TYPES") message {
|
|||||||
"types" = "application/x-zip-compressed",
|
"types" = "application/x-zip-compressed",
|
||||||
"types" = "application/zip",
|
"types" = "application/zip",
|
||||||
"types" = "application/x-gunzip",
|
"types" = "application/x-gunzip",
|
||||||
"types" = "application/x-bzip2"
|
"types" = "application/x-bzip2",
|
||||||
|
"types" = "application/x-rar"
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
#ifdef HAIKU_TARGET_PLATFORM_HAIKU
|
||||||
@@ -428,3 +429,4 @@ resource(5, "BEOS:M:application/x-bzip2") #'MICN' array {
|
|||||||
$"FFFFFFFFFFFFFFFF0000FFFFFFFFFFFF"
|
$"FFFFFFFFFFFFFFFF0000FFFFFFFFFFFF"
|
||||||
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
$"FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,30 +1,9 @@
|
|||||||
/*****************************************************************************/
|
/*
|
||||||
// Expander
|
* Copyright 2004-2006, Jérôme Duval. All rights reserved.
|
||||||
// Written by Jérôme Duval
|
* Distributed under the terms of the MIT License.
|
||||||
//
|
*/
|
||||||
// ExpanderRules.cpp
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// Copyright (c) 2004 OpenBeOS Project
|
|
||||||
//
|
|
||||||
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
// copy of this software and associated documentation files (the "Software"),
|
|
||||||
// to deal in the Software without restriction, including without limitation
|
|
||||||
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
// and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
// Software is furnished to do so, subject to the following conditions:
|
|
||||||
//
|
|
||||||
// The above copyright notice and this permission notice shall be included
|
|
||||||
// in all copies or substantial portions of the Software.
|
|
||||||
//
|
|
||||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
||||||
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
// DEALINGS IN THE SOFTWARE.
|
|
||||||
/*****************************************************************************/
|
|
||||||
#include "ExpanderRules.h"
|
#include "ExpanderRules.h"
|
||||||
|
|
||||||
#include <FindDirectory.h>
|
#include <FindDirectory.h>
|
||||||
@@ -34,25 +13,26 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
|
|
||||||
ExpanderRule::ExpanderRule(BString mimetype, BString filenameExtension,
|
ExpanderRule::ExpanderRule(BString mimetype, BString filenameExtension,
|
||||||
BString listingCmd, BString expandCmd)
|
BString listingCmd, BString expandCmd)
|
||||||
: fMimeType(mimetype.String()),
|
:
|
||||||
|
fMimeType(mimetype.String()),
|
||||||
fFilenameExtension(filenameExtension),
|
fFilenameExtension(filenameExtension),
|
||||||
fListingCmd(listingCmd),
|
fListingCmd(listingCmd),
|
||||||
fExpandCmd(expandCmd)
|
fExpandCmd(expandCmd)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
ExpanderRule::ExpanderRule(const char* mimetype, const char* filenameExtension,
|
ExpanderRule::ExpanderRule(const char* mimetype, const char* filenameExtension,
|
||||||
const char* listingCmd, const char* expandCmd)
|
const char* listingCmd, const char* expandCmd)
|
||||||
: fMimeType(mimetype),
|
:
|
||||||
|
fMimeType(mimetype),
|
||||||
fFilenameExtension(filenameExtension),
|
fFilenameExtension(filenameExtension),
|
||||||
fListingCmd(listingCmd),
|
fListingCmd(listingCmd),
|
||||||
fExpandCmd(expandCmd)
|
fExpandCmd(expandCmd)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -67,6 +47,7 @@ ExpanderRules::ExpanderRules()
|
|||||||
fList.AddItem(new ExpanderRule("application/x-bzip2", ".bz2", "echo %s | sed 's/.bz2$//g'", "bunzip2 %s"));
|
fList.AddItem(new ExpanderRule("application/x-bzip2", ".bz2", "echo %s | sed 's/.bz2$//g'", "bunzip2 %s"));
|
||||||
fList.AddItem(new ExpanderRule("application/zip", ".zip", "unzip -l %s", "unzip -o %s"));
|
fList.AddItem(new ExpanderRule("application/zip", ".zip", "unzip -l %s", "unzip -o %s"));
|
||||||
fList.AddItem(new ExpanderRule("application/x-zip-compressed", ".zip", "unzip -l %s", "unzip -o %s"));
|
fList.AddItem(new ExpanderRule("application/x-zip-compressed", ".zip", "unzip -l %s", "unzip -o %s"));
|
||||||
|
fList.AddItem(new ExpanderRule("application/x-rar", ".rar", "unrar v %s", "unrar x -y %s"));
|
||||||
|
|
||||||
BFile file;
|
BFile file;
|
||||||
if (Open(&file) != B_OK)
|
if (Open(&file) != B_OK)
|
||||||
@@ -78,18 +59,18 @@ ExpanderRules::ExpanderRules()
|
|||||||
char buffer[1024];
|
char buffer[1024];
|
||||||
BString strings[4];
|
BString strings[4];
|
||||||
while (fgets(buffer, 1024-1, f)!=NULL) {
|
while (fgets(buffer, 1024-1, f)!=NULL) {
|
||||||
int32 i=0, j=0;
|
int32 i = 0, j = 0;
|
||||||
int32 firstQuote = -1;
|
int32 firstQuote = -1;
|
||||||
while (buffer[i]!= '#' && buffer[i]!= '\n' && j<4) {
|
while (buffer[i] != '#' && buffer[i] != '\n' && j < 4) {
|
||||||
if (((j==0)||(j>1))&&(buffer[i] == '"')) {
|
if ((j == 0 || j > 1) && buffer[i] == '"') {
|
||||||
if (firstQuote >= 0) {
|
if (firstQuote >= 0) {
|
||||||
strings[j++].SetTo(&buffer[firstQuote+1], i-firstQuote-1);
|
strings[j++].SetTo(&buffer[firstQuote+1], i-firstQuote-1);
|
||||||
firstQuote = -1;
|
firstQuote = -1;
|
||||||
} else
|
} else
|
||||||
firstQuote = i;
|
firstQuote = i;
|
||||||
} else if ((j==1)&&((buffer[i]==' ')||(buffer[i]=='\t'))){
|
} else if (j == 1 && (buffer[i] == ' ' || buffer[i] == '\t')) {
|
||||||
if (firstQuote >= 0) {
|
if (firstQuote >= 0) {
|
||||||
if (firstQuote+1!=i) {
|
if (firstQuote + 1 != i) {
|
||||||
strings[j++].SetTo(&buffer[firstQuote+1], i-firstQuote-1);
|
strings[j++].SetTo(&buffer[firstQuote+1], i-firstQuote-1);
|
||||||
firstQuote = -1;
|
firstQuote = -1;
|
||||||
} else
|
} else
|
||||||
@@ -99,7 +80,7 @@ ExpanderRules::ExpanderRules()
|
|||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
if (j==4) {
|
if (j == 4) {
|
||||||
fList.AddItem(new ExpanderRule(strings[0], strings[1], strings[2], strings[3]));
|
fList.AddItem(new ExpanderRule(strings[0], strings[1], strings[2], strings[3]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -143,8 +124,8 @@ ExpanderRules::MatchingRule(BString &fileName, const char *filetype)
|
|||||||
int32 length = fileName.Length();
|
int32 length = fileName.Length();
|
||||||
for (int32 i=0; i<count; i++) {
|
for (int32 i=0; i<count; i++) {
|
||||||
ExpanderRule *rule = (ExpanderRule *)fList.ItemAt(i);
|
ExpanderRule *rule = (ExpanderRule *)fList.ItemAt(i);
|
||||||
if ((rule->MimeType().IsValid() && (rule->MimeType()==filetype))
|
if ((rule->MimeType().IsValid() && rule->MimeType() == filetype)
|
||||||
|| (fileName.FindLast(rule->FilenameExtension())==(length-rule->FilenameExtension().Length())))
|
|| (fileName.FindLast(rule->FilenameExtension()) == (length - rule->FilenameExtension().Length())))
|
||||||
return rule;
|
return rule;
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -179,5 +160,5 @@ RuleRefFilter::Filter(const entry_ref *ref, BNode* node, struct stat *st,
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
BString fileName(ref->name);
|
BString fileName(ref->name);
|
||||||
return (fRules.MatchingRule(fileName, filetype)!=NULL);
|
return fRules.MatchingRule(fileName, filetype) != NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,6 +168,7 @@ SubInclude HAIKU_TOP src bin screen_blanker ;
|
|||||||
SubInclude HAIKU_TOP src bin sed ;
|
SubInclude HAIKU_TOP src bin sed ;
|
||||||
SubInclude HAIKU_TOP src bin sharutils ;
|
SubInclude HAIKU_TOP src bin sharutils ;
|
||||||
SubInclude HAIKU_TOP src bin strace ;
|
SubInclude HAIKU_TOP src bin strace ;
|
||||||
|
SubInclude HAIKU_TOP src bin unrar ;
|
||||||
SubInclude HAIKU_TOP src bin vim ;
|
SubInclude HAIKU_TOP src bin vim ;
|
||||||
SubInclude HAIKU_TOP src bin zic ;
|
SubInclude HAIKU_TOP src bin zic ;
|
||||||
|
|
||||||
|
|||||||
Executable
+47
@@ -0,0 +1,47 @@
|
|||||||
|
SubDir HAIKU_TOP src bin unrar ;
|
||||||
|
|
||||||
|
BinCommand unrar :
|
||||||
|
rar.cpp
|
||||||
|
strlist.cpp
|
||||||
|
strfn.cpp
|
||||||
|
pathfn.cpp
|
||||||
|
int64.cpp
|
||||||
|
savepos.cpp
|
||||||
|
global.cpp
|
||||||
|
file.cpp
|
||||||
|
filefn.cpp
|
||||||
|
filcreat.cpp
|
||||||
|
archive.cpp
|
||||||
|
arcread.cpp
|
||||||
|
unicode.cpp
|
||||||
|
system.cpp
|
||||||
|
isnt.cpp
|
||||||
|
crypt.cpp
|
||||||
|
crc.cpp
|
||||||
|
rawread.cpp
|
||||||
|
encname.cpp
|
||||||
|
resource.cpp
|
||||||
|
match.cpp
|
||||||
|
timefn.cpp
|
||||||
|
rdwrfn.cpp
|
||||||
|
consio.cpp
|
||||||
|
options.cpp
|
||||||
|
ulinks.cpp
|
||||||
|
errhnd.cpp
|
||||||
|
rarvm.cpp
|
||||||
|
rijndael.cpp
|
||||||
|
getbits.cpp
|
||||||
|
sha1.cpp
|
||||||
|
extinfo.cpp
|
||||||
|
extract.cpp
|
||||||
|
volume.cpp
|
||||||
|
list.cpp
|
||||||
|
find.cpp
|
||||||
|
unpack.cpp
|
||||||
|
cmddata.cpp
|
||||||
|
scantree.cpp
|
||||||
|
filestr.cpp
|
||||||
|
recvol.cpp
|
||||||
|
rs.cpp
|
||||||
|
: be : unrar.rdef
|
||||||
|
;
|
||||||
@@ -0,0 +1,211 @@
|
|||||||
|
bool Archive::GetComment(Array<byte> *CmtData,Array<wchar> *CmtDataW)
|
||||||
|
{
|
||||||
|
if (!MainComment)
|
||||||
|
return(false);
|
||||||
|
SaveFilePos SavePos(*this);
|
||||||
|
|
||||||
|
ushort CmtLength;
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (OldFormat)
|
||||||
|
{
|
||||||
|
Seek(SFXSize+SIZEOF_OLDMHD,SEEK_SET);
|
||||||
|
CmtLength=GetByte()+(GetByte()<<8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (NewMhd.Flags & MHD_COMMENT)
|
||||||
|
{
|
||||||
|
Seek(SFXSize+SIZEOF_MARKHEAD+SIZEOF_NEWMHD,SEEK_SET);
|
||||||
|
ReadHeader();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Seek(SFXSize+SIZEOF_MARKHEAD+NewMhd.HeadSize,SEEK_SET);
|
||||||
|
return(SearchSubBlock(SUBHEAD_TYPE_CMT)!=0 && ReadCommentData(CmtData,CmtDataW)!=0);
|
||||||
|
}
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (CommHead.HeadCRC!=HeaderCRC)
|
||||||
|
{
|
||||||
|
Log(FileName,St(MLogCommHead));
|
||||||
|
Alarm();
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
CmtLength=CommHead.HeadSize-SIZEOF_COMMHEAD;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (OldFormat && (OldMhd.Flags & MHD_PACK_COMMENT) || !OldFormat && CommHead.Method!=0x30)
|
||||||
|
{
|
||||||
|
if (!OldFormat && (CommHead.UnpVer < 15 || CommHead.UnpVer > UNP_VER || CommHead.Method > 0x35))
|
||||||
|
return(false);
|
||||||
|
ComprDataIO DataIO;
|
||||||
|
Unpack Unpack(&DataIO);
|
||||||
|
Unpack.Init();
|
||||||
|
DataIO.SetTestMode(true);
|
||||||
|
uint UnpCmtLength;
|
||||||
|
if (OldFormat)
|
||||||
|
{
|
||||||
|
UnpCmtLength=GetByte()+(GetByte()<<8);
|
||||||
|
CmtLength-=2;
|
||||||
|
DataIO.SetCmt13Encryption();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
UnpCmtLength=CommHead.UnpSize;
|
||||||
|
DataIO.SetFiles(this,NULL);
|
||||||
|
DataIO.EnableShowProgress(false);
|
||||||
|
DataIO.SetPackedSizeToRead(CmtLength);
|
||||||
|
Unpack.SetDestSize(UnpCmtLength);
|
||||||
|
Unpack.DoUnpack(CommHead.UnpVer,false);
|
||||||
|
|
||||||
|
if (!OldFormat && ((~DataIO.UnpFileCRC)&0xffff)!=CommHead.CommCRC)
|
||||||
|
{
|
||||||
|
Log(FileName,St(MLogCommBrk));
|
||||||
|
Alarm();
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned char *UnpData;
|
||||||
|
uint UnpDataSize;
|
||||||
|
DataIO.GetUnpackedData(&UnpData,&UnpDataSize);
|
||||||
|
CmtData->Alloc(UnpDataSize);
|
||||||
|
memcpy(&((*CmtData)[0]),UnpData,UnpDataSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CmtData->Alloc(CmtLength);
|
||||||
|
|
||||||
|
Read(&((*CmtData)[0]),CmtLength);
|
||||||
|
if (!OldFormat && CommHead.CommCRC!=(~CRC(0xffffffff,&((*CmtData)[0]),CmtLength)&0xffff))
|
||||||
|
{
|
||||||
|
Log(FileName,St(MLogCommBrk));
|
||||||
|
Alarm();
|
||||||
|
CmtData->Reset();
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if defined(_WIN_32) && !defined(_WIN_CE)
|
||||||
|
if (CmtData->Size()>0)
|
||||||
|
{
|
||||||
|
int CmtSize=CmtData->Size();
|
||||||
|
OemToCharBuff((char *)CmtData->Addr(),(char *)CmtData->Addr(),CmtSize);
|
||||||
|
|
||||||
|
if (CmtDataW!=NULL)
|
||||||
|
{
|
||||||
|
CmtDataW->Alloc(CmtSize+1);
|
||||||
|
CmtData->Push(0);
|
||||||
|
CharToWide((char *)CmtData->Addr(),CmtDataW->Addr(),CmtSize+1);
|
||||||
|
CmtData->Alloc(CmtSize);
|
||||||
|
CmtDataW->Alloc(strlenw(CmtDataW->Addr()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return(CmtData->Size()>0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Archive::ReadCommentData(Array<byte> *CmtData,Array<wchar> *CmtDataW)
|
||||||
|
{
|
||||||
|
bool Unicode=SubHead.SubFlags & SUBHEAD_FLAGS_CMT_UNICODE;
|
||||||
|
if (!ReadSubData(CmtData,NULL))
|
||||||
|
return(0);
|
||||||
|
int CmtSize=CmtData->Size();
|
||||||
|
if (Unicode)
|
||||||
|
{
|
||||||
|
CmtSize/=2;
|
||||||
|
Array<wchar> DataW(CmtSize+1);
|
||||||
|
RawToWide(CmtData->Addr(),DataW.Addr(),CmtSize);
|
||||||
|
DataW[CmtSize]=0;
|
||||||
|
int DestSize=CmtSize*4;
|
||||||
|
CmtData->Alloc(DestSize+1);
|
||||||
|
WideToChar(DataW.Addr(),(char *)CmtData->Addr(),DestSize);
|
||||||
|
(*CmtData)[DestSize]=0;
|
||||||
|
CmtSize=strlen((char *)CmtData->Addr());
|
||||||
|
CmtData->Alloc(CmtSize);
|
||||||
|
if (CmtDataW!=NULL)
|
||||||
|
{
|
||||||
|
*CmtDataW=DataW;
|
||||||
|
CmtDataW->Alloc(CmtSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (CmtDataW!=NULL)
|
||||||
|
{
|
||||||
|
CmtData->Push(0);
|
||||||
|
CmtDataW->Alloc(CmtSize+1);
|
||||||
|
CharToWide((char *)CmtData->Addr(),CmtDataW->Addr(),CmtSize+1);
|
||||||
|
CmtData->Alloc(CmtSize);
|
||||||
|
CmtDataW->Alloc(strlenw(CmtDataW->Addr()));
|
||||||
|
}
|
||||||
|
return(CmtSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Archive::ViewComment()
|
||||||
|
{
|
||||||
|
#ifndef GUI
|
||||||
|
if (Cmd->DisableComment)
|
||||||
|
return;
|
||||||
|
Array<byte> CmtBuf;
|
||||||
|
if (GetComment(&CmtBuf,NULL))
|
||||||
|
{
|
||||||
|
int CmtSize=CmtBuf.Size();
|
||||||
|
char *ChPtr=(char *)memchr(&CmtBuf[0],0x1A,CmtSize);
|
||||||
|
if (ChPtr!=NULL)
|
||||||
|
CmtSize=ChPtr-(char *)&CmtBuf[0];
|
||||||
|
mprintf("\n");
|
||||||
|
OutComment((char *)&CmtBuf[0],CmtSize);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
void Archive::ViewFileComment()
|
||||||
|
{
|
||||||
|
if (!(NewLhd.Flags & LHD_COMMENT) || Cmd->DisableComment || OldFormat)
|
||||||
|
return;
|
||||||
|
#ifndef GUI
|
||||||
|
mprintf(St(MFileComment));
|
||||||
|
#endif
|
||||||
|
const int MaxSize=0x8000;
|
||||||
|
Array<char> CmtBuf(MaxSize);
|
||||||
|
SaveFilePos SavePos(*this);
|
||||||
|
Seek(CurBlockPos+SIZEOF_NEWLHD+NewLhd.NameSize,SEEK_SET);
|
||||||
|
Int64 SaveCurBlockPos=CurBlockPos;
|
||||||
|
Int64 SaveNextBlockPos=NextBlockPos;
|
||||||
|
|
||||||
|
int Size=ReadHeader();
|
||||||
|
|
||||||
|
CurBlockPos=SaveCurBlockPos;
|
||||||
|
NextBlockPos=SaveNextBlockPos;
|
||||||
|
|
||||||
|
if (Size<7 || CommHead.HeadType!=COMM_HEAD)
|
||||||
|
return;
|
||||||
|
if (CommHead.HeadCRC!=HeaderCRC)
|
||||||
|
{
|
||||||
|
#ifndef GUI
|
||||||
|
Log(FileName,St(MLogCommHead));
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (CommHead.UnpVer < 15 || CommHead.UnpVer > UNP_VER ||
|
||||||
|
CommHead.Method > 0x30 || CommHead.UnpSize > MaxSize)
|
||||||
|
return;
|
||||||
|
Read(&CmtBuf[0],CommHead.UnpSize);
|
||||||
|
if (CommHead.CommCRC!=((~CRC(0xffffffff,&CmtBuf[0],CommHead.UnpSize)&0xffff)))
|
||||||
|
{
|
||||||
|
Log(FileName,St(MLogBrokFCmt));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OutComment(&CmtBuf[0],CommHead.UnpSize);
|
||||||
|
#ifndef GUI
|
||||||
|
mprintf("\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,257 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
#ifndef SHELL_EXT
|
||||||
|
#include "arccmt.cpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
Archive::Archive(RAROptions *InitCmd)
|
||||||
|
{
|
||||||
|
Cmd=InitCmd==NULL ? &DummyCmd:InitCmd;
|
||||||
|
OpenShared=Cmd->OpenShared;
|
||||||
|
OldFormat=false;
|
||||||
|
Solid=false;
|
||||||
|
Volume=false;
|
||||||
|
MainComment=false;
|
||||||
|
Locked=false;
|
||||||
|
Signed=false;
|
||||||
|
NotFirstVolume=false;
|
||||||
|
SFXSize=0;
|
||||||
|
LatestTime.Reset();
|
||||||
|
Protected=false;
|
||||||
|
Encrypted=false;
|
||||||
|
BrokenFileHeader=false;
|
||||||
|
LastReadBlock=0;
|
||||||
|
|
||||||
|
CurBlockPos=0;
|
||||||
|
NextBlockPos=0;
|
||||||
|
|
||||||
|
RecoveryPos=SIZEOF_MARKHEAD;
|
||||||
|
RecoverySectors=-1;
|
||||||
|
|
||||||
|
memset(&NewMhd,0,sizeof(NewMhd));
|
||||||
|
NewMhd.HeadType=MAIN_HEAD;
|
||||||
|
NewMhd.HeadSize=SIZEOF_NEWMHD;
|
||||||
|
HeaderCRC=0;
|
||||||
|
VolWrite=0;
|
||||||
|
AddingFilesSize=0;
|
||||||
|
AddingHeadersSize=0;
|
||||||
|
#if !defined(SHELL_EXT) && !defined(NOCRYPT)
|
||||||
|
*HeadersSalt=0;
|
||||||
|
*SubDataSalt=0;
|
||||||
|
#endif
|
||||||
|
*FirstVolumeName=0;
|
||||||
|
*FirstVolumeNameW=0;
|
||||||
|
|
||||||
|
Splitting=false;
|
||||||
|
NewArchive=false;
|
||||||
|
|
||||||
|
SilentOpen=false;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SHELL_EXT
|
||||||
|
void Archive::CheckArc(bool EnableBroken)
|
||||||
|
{
|
||||||
|
if (!IsArchive(EnableBroken))
|
||||||
|
{
|
||||||
|
Log(FileName,St(MBadArc),FileName);
|
||||||
|
ErrHandler.Exit(FATAL_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(SHELL_EXT) && !defined(SFX_MODULE)
|
||||||
|
void Archive::CheckOpen(char *Name,wchar *NameW)
|
||||||
|
{
|
||||||
|
TOpen(Name,NameW);
|
||||||
|
CheckArc(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool Archive::WCheckOpen(char *Name,wchar *NameW)
|
||||||
|
{
|
||||||
|
if (!WOpen(Name,NameW))
|
||||||
|
return(false);
|
||||||
|
if (!IsArchive(false))
|
||||||
|
{
|
||||||
|
#ifndef SHELL_EXT
|
||||||
|
Log(FileName,St(MNotRAR),FileName);
|
||||||
|
#endif
|
||||||
|
Close();
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Archive::IsSignature(byte *D)
|
||||||
|
{
|
||||||
|
bool Valid=false;
|
||||||
|
if (D[0]==0x52)
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (D[1]==0x45 && D[2]==0x7e && D[3]==0x5e)
|
||||||
|
{
|
||||||
|
OldFormat=true;
|
||||||
|
Valid=true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (D[1]==0x61 && D[2]==0x72 && D[3]==0x21 && D[4]==0x1a && D[5]==0x07 && D[6]==0x00)
|
||||||
|
{
|
||||||
|
OldFormat=false;
|
||||||
|
Valid=true;
|
||||||
|
}
|
||||||
|
return(Valid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Archive::IsArchive(bool EnableBroken)
|
||||||
|
{
|
||||||
|
Encrypted=false;
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (IsDevice())
|
||||||
|
{
|
||||||
|
#ifndef SHELL_EXT
|
||||||
|
Log(FileName,St(MInvalidName),FileName);
|
||||||
|
#endif
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (Read(MarkHead.Mark,SIZEOF_MARKHEAD)!=SIZEOF_MARKHEAD)
|
||||||
|
return(false);
|
||||||
|
SFXSize=0;
|
||||||
|
if (IsSignature(MarkHead.Mark))
|
||||||
|
{
|
||||||
|
if (OldFormat)
|
||||||
|
Seek(0,SEEK_SET);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Array<char> Buffer(MAXSFXSIZE);
|
||||||
|
long CurPos=int64to32(Tell());
|
||||||
|
int ReadSize=Read(&Buffer[0],Buffer.Size()-16);
|
||||||
|
for (int I=0;I<ReadSize;I++)
|
||||||
|
if (Buffer[I]==0x52 && IsSignature((byte *)&Buffer[I]))
|
||||||
|
{
|
||||||
|
if (OldFormat && I>0 && CurPos<28 && ReadSize>31)
|
||||||
|
{
|
||||||
|
char *D=&Buffer[28-CurPos];
|
||||||
|
if (D[0]!=0x52 || D[1]!=0x53 || D[2]!=0x46 || D[3]!=0x58)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
SFXSize=CurPos+I;
|
||||||
|
Seek(SFXSize,SEEK_SET);
|
||||||
|
if (!OldFormat)
|
||||||
|
Read(MarkHead.Mark,SIZEOF_MARKHEAD);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (SFXSize==0)
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
ReadHeader();
|
||||||
|
SeekToNext();
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (OldFormat)
|
||||||
|
{
|
||||||
|
NewMhd.Flags=OldMhd.Flags & 0x3f;
|
||||||
|
NewMhd.HeadSize=OldMhd.HeadSize;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
if (HeaderCRC!=NewMhd.HeadCRC)
|
||||||
|
{
|
||||||
|
#ifndef SHELL_EXT
|
||||||
|
Log(FileName,St(MLogMainHead));
|
||||||
|
#endif
|
||||||
|
Alarm();
|
||||||
|
if (!EnableBroken)
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Volume=(NewMhd.Flags & MHD_VOLUME);
|
||||||
|
Solid=(NewMhd.Flags & MHD_SOLID)!=0;
|
||||||
|
MainComment=(NewMhd.Flags & MHD_COMMENT)!=0;
|
||||||
|
Locked=(NewMhd.Flags & MHD_LOCK)!=0;
|
||||||
|
Signed=(NewMhd.PosAV!=0);
|
||||||
|
Protected=(NewMhd.Flags & MHD_PROTECT)!=0;
|
||||||
|
Encrypted=(NewMhd.Flags & MHD_PASSWORD)!=0;
|
||||||
|
|
||||||
|
if (NewMhd.EncryptVer>UNP_VER)
|
||||||
|
{
|
||||||
|
#ifdef RARDLL
|
||||||
|
Cmd->DllError=ERAR_UNKNOWN_FORMAT;
|
||||||
|
#else
|
||||||
|
ErrHandler.SetErrorCode(WARNING);
|
||||||
|
#if !defined(SILENT) && !defined(SFX_MODULE)
|
||||||
|
Log(FileName,St(MUnknownMeth),FileName);
|
||||||
|
Log(FileName,St(MVerRequired),NewMhd.EncryptVer/10,NewMhd.EncryptVer%10);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
#ifdef RARDLL
|
||||||
|
SilentOpen=true;
|
||||||
|
#endif
|
||||||
|
if (!SilentOpen || !Encrypted)
|
||||||
|
{
|
||||||
|
SaveFilePos SavePos(*this);
|
||||||
|
Int64 SaveCurBlockPos=CurBlockPos,SaveNextBlockPos=NextBlockPos;
|
||||||
|
|
||||||
|
NotFirstVolume=false;
|
||||||
|
while (ReadHeader())
|
||||||
|
{
|
||||||
|
int HeaderType=GetHeaderType();
|
||||||
|
if (HeaderType==NEWSUB_HEAD)
|
||||||
|
{
|
||||||
|
if (SubHead.CmpName(SUBHEAD_TYPE_CMT))
|
||||||
|
MainComment=true;
|
||||||
|
if ((SubHead.Flags & LHD_SPLIT_BEFORE) ||
|
||||||
|
Volume && (NewMhd.Flags & MHD_FIRSTVOLUME)==0)
|
||||||
|
NotFirstVolume=true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (HeaderType==FILE_HEAD && ((NewLhd.Flags & LHD_SPLIT_BEFORE)!=0 ||
|
||||||
|
Volume && NewLhd.UnpVer>=29 && (NewMhd.Flags & MHD_FIRSTVOLUME)==0))
|
||||||
|
NotFirstVolume=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
SeekToNext();
|
||||||
|
}
|
||||||
|
CurBlockPos=SaveCurBlockPos;
|
||||||
|
NextBlockPos=SaveNextBlockPos;
|
||||||
|
}
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void Archive::SeekToNext()
|
||||||
|
{
|
||||||
|
Seek(NextBlockPos,SEEK_SET);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
int Archive::GetRecoverySize(bool Required)
|
||||||
|
{
|
||||||
|
if (!Protected)
|
||||||
|
return(0);
|
||||||
|
if (RecoverySectors!=-1 || !Required)
|
||||||
|
return(RecoverySectors);
|
||||||
|
SaveFilePos SavePos(*this);
|
||||||
|
Seek(SFXSize,SEEK_SET);
|
||||||
|
SearchSubBlock(SUBHEAD_TYPE_RR);
|
||||||
|
return(RecoverySectors);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,128 @@
|
|||||||
|
#ifndef _RAR_ARCHIVE_
|
||||||
|
#define _RAR_ARCHIVE_
|
||||||
|
|
||||||
|
class Pack;
|
||||||
|
|
||||||
|
enum {EN_LOCK=1,EN_VOL=2,EN_FIRSTVOL=4};
|
||||||
|
|
||||||
|
class Archive:public File
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
bool IsSignature(byte *D);
|
||||||
|
void UpdateLatestTime(FileHeader *CurBlock);
|
||||||
|
void Protect(int RecSectors);
|
||||||
|
void ConvertNameCase(char *Name);
|
||||||
|
void ConvertNameCase(wchar *Name);
|
||||||
|
void ConvertUnknownHeader();
|
||||||
|
bool AddArcComment(char *NameToShow);
|
||||||
|
int ReadOldHeader();
|
||||||
|
void PrepareExtraTime(FileHeader *hd,EXTTIME_MODE etm,EXTTIME_MODE etc,EXTTIME_MODE eta,EXTTIME_MODE etarc,Array<byte> &TimeData);
|
||||||
|
|
||||||
|
#if !defined(SHELL_EXT) && !defined(NOCRYPT)
|
||||||
|
CryptData HeadersCrypt;
|
||||||
|
byte HeadersSalt[SALT_SIZE];
|
||||||
|
#endif
|
||||||
|
#ifndef SHELL_EXT
|
||||||
|
ComprDataIO SubDataIO;
|
||||||
|
byte SubDataSalt[SALT_SIZE];
|
||||||
|
#endif
|
||||||
|
RAROptions *Cmd,DummyCmd;
|
||||||
|
|
||||||
|
MarkHeader MarkHead;
|
||||||
|
OldMainHeader OldMhd;
|
||||||
|
|
||||||
|
int RecoverySectors;
|
||||||
|
Int64 RecoveryPos;
|
||||||
|
|
||||||
|
RarTime LatestTime;
|
||||||
|
int LastReadBlock;
|
||||||
|
int CurHeaderType;
|
||||||
|
|
||||||
|
bool SilentOpen;
|
||||||
|
public:
|
||||||
|
Archive(RAROptions *InitCmd=NULL);
|
||||||
|
bool IsArchive(bool EnableBroken);
|
||||||
|
int SearchBlock(int BlockType);
|
||||||
|
int SearchSubBlock(const char *Type);
|
||||||
|
int ReadBlock(int BlockType);
|
||||||
|
void WriteBlock(int BlockType,BaseBlock *wb=NULL);
|
||||||
|
int PrepareNamesToWrite(char *Name,wchar *NameW,char *DestName,byte *DestNameW);
|
||||||
|
void SetLhdSize();
|
||||||
|
int ReadHeader();
|
||||||
|
void CheckArc(bool EnableBroken);
|
||||||
|
void CheckOpen(char *Name,wchar *NameW=NULL);
|
||||||
|
bool WCheckOpen(char *Name,wchar *NameW=NULL);
|
||||||
|
bool TestLock(int Mode);
|
||||||
|
void MakeTemp();
|
||||||
|
void CopyMainHeader(Archive &Src,bool CopySFX=true,char *NameToDisplay=NULL);
|
||||||
|
bool ProcessToFileHead(Archive &Src,bool LastBlockAdded,
|
||||||
|
Pack *Pack=NULL,const char *SkipName=NULL);
|
||||||
|
void TmpToArc(Archive &Src);
|
||||||
|
void CloseNew(int AdjustRecovery,bool CloseVolume);
|
||||||
|
void WriteEndBlock(bool CloseVolume);
|
||||||
|
void CopyFileRecord(Archive &Src);
|
||||||
|
void CopyArchiveData(Archive &Src);
|
||||||
|
bool GetComment(Array<byte> *CmtData,Array<wchar> *CmtDataW);
|
||||||
|
void ViewComment();
|
||||||
|
void ViewFileComment();
|
||||||
|
void SetLatestTime(RarTime *NewTime);
|
||||||
|
void SeekToNext();
|
||||||
|
bool CheckAccess();
|
||||||
|
bool IsArcDir();
|
||||||
|
bool IsArcLabel();
|
||||||
|
void ConvertAttributes();
|
||||||
|
int GetRecoverySize(bool Required);
|
||||||
|
void VolSubtractHeaderSize(int SubSize);
|
||||||
|
void AddSubData(byte *SrcData,int DataSize,File *SrcFile,char *Name,bool AllowSplit);
|
||||||
|
bool ReadSubData(Array<byte> *UnpData,File *DestFile);
|
||||||
|
int GetHeaderType() {return(CurHeaderType);};
|
||||||
|
int ReadCommentData(Array<byte> *CmtData,Array<wchar> *CmtDataW);
|
||||||
|
void WriteCommentData(byte *Data,int DataSize,bool FileComment);
|
||||||
|
RAROptions* GetRAROptions() {return(Cmd);}
|
||||||
|
void SetSilentOpen(bool Mode) {SilentOpen=Mode;}
|
||||||
|
|
||||||
|
BaseBlock ShortBlock;
|
||||||
|
MainHeader NewMhd;
|
||||||
|
FileHeader NewLhd;
|
||||||
|
EndArcHeader EndArcHead;
|
||||||
|
SubBlockHeader SubBlockHead;
|
||||||
|
FileHeader SubHead;
|
||||||
|
CommentHeader CommHead;
|
||||||
|
ProtectHeader ProtectHead;
|
||||||
|
AVHeader AVHead;
|
||||||
|
SignHeader SignHead;
|
||||||
|
UnixOwnersHeader UOHead;
|
||||||
|
MacFInfoHeader MACHead;
|
||||||
|
EAHeader EAHead;
|
||||||
|
StreamHeader StreamHead;
|
||||||
|
|
||||||
|
Int64 CurBlockPos;
|
||||||
|
Int64 NextBlockPos;
|
||||||
|
|
||||||
|
bool OldFormat;
|
||||||
|
bool Solid;
|
||||||
|
bool Volume;
|
||||||
|
bool MainComment;
|
||||||
|
bool Locked;
|
||||||
|
bool Signed;
|
||||||
|
bool NotFirstVolume;
|
||||||
|
bool Protected;
|
||||||
|
bool Encrypted;
|
||||||
|
uint SFXSize;
|
||||||
|
bool BrokenFileHeader;
|
||||||
|
|
||||||
|
bool Splitting;
|
||||||
|
|
||||||
|
ushort HeaderCRC;
|
||||||
|
|
||||||
|
Int64 VolWrite;
|
||||||
|
Int64 AddingFilesSize;
|
||||||
|
uint AddingHeadersSize;
|
||||||
|
|
||||||
|
bool NewArchive;
|
||||||
|
|
||||||
|
char FirstVolumeName[NM];
|
||||||
|
wchar FirstVolumeNameW[NM];
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,654 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
int Archive::SearchBlock(int BlockType)
|
||||||
|
{
|
||||||
|
int Size,Count=0;
|
||||||
|
while ((Size=ReadHeader())!=0 &&
|
||||||
|
(BlockType==ENDARC_HEAD || GetHeaderType()!=ENDARC_HEAD))
|
||||||
|
{
|
||||||
|
if ((++Count & 127)==0)
|
||||||
|
Wait();
|
||||||
|
if (GetHeaderType()==BlockType)
|
||||||
|
return(Size);
|
||||||
|
SeekToNext();
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Archive::SearchSubBlock(const char *Type)
|
||||||
|
{
|
||||||
|
int Size;
|
||||||
|
while ((Size=ReadHeader())!=0 && GetHeaderType()!=ENDARC_HEAD)
|
||||||
|
{
|
||||||
|
if (GetHeaderType()==NEWSUB_HEAD && SubHead.CmpName(Type))
|
||||||
|
return(Size);
|
||||||
|
SeekToNext();
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int Archive::ReadHeader()
|
||||||
|
{
|
||||||
|
CurBlockPos=Tell();
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (OldFormat)
|
||||||
|
return(ReadOldHeader());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RawRead Raw(this);
|
||||||
|
|
||||||
|
bool Decrypt=Encrypted && CurBlockPos>=SFXSize+SIZEOF_MARKHEAD+SIZEOF_NEWMHD;
|
||||||
|
|
||||||
|
if (Decrypt)
|
||||||
|
{
|
||||||
|
#if defined(SHELL_EXT) || defined(NOCRYPT)
|
||||||
|
return(0);
|
||||||
|
#else
|
||||||
|
if (Read(HeadersSalt,SALT_SIZE)!=SALT_SIZE)
|
||||||
|
return(0);
|
||||||
|
if (*Cmd->Password==0)
|
||||||
|
#ifdef RARDLL
|
||||||
|
if (Cmd->Callback==NULL ||
|
||||||
|
Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LONG)Cmd->Password,sizeof(Cmd->Password))==-1)
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
ErrHandler.Exit(USER_BREAK);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
if (!GetPassword(PASSWORD_ARCHIVE,FileName,Cmd->Password,sizeof(Cmd->Password)))
|
||||||
|
{
|
||||||
|
Close();
|
||||||
|
ErrHandler.Exit(USER_BREAK);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
HeadersCrypt.SetCryptKeys(Cmd->Password,HeadersSalt,false,false,NewMhd.EncryptVer>=36);
|
||||||
|
Raw.SetCrypt(&HeadersCrypt);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
Raw.Read(SIZEOF_SHORTBLOCKHEAD);
|
||||||
|
if (Raw.Size()==0)
|
||||||
|
{
|
||||||
|
Int64 ArcSize=FileLength();
|
||||||
|
if (CurBlockPos>ArcSize || NextBlockPos>ArcSize)
|
||||||
|
{
|
||||||
|
#ifndef SHELL_EXT
|
||||||
|
Log(FileName,St(MLogUnexpEOF));
|
||||||
|
#endif
|
||||||
|
ErrHandler.SetErrorCode(WARNING);
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
Raw.Get(ShortBlock.HeadCRC);
|
||||||
|
byte HeadType;
|
||||||
|
Raw.Get(HeadType);
|
||||||
|
ShortBlock.HeadType=(HEADER_TYPE)HeadType;
|
||||||
|
Raw.Get(ShortBlock.Flags);
|
||||||
|
Raw.Get(ShortBlock.HeadSize);
|
||||||
|
if (ShortBlock.HeadSize<SIZEOF_SHORTBLOCKHEAD)
|
||||||
|
{
|
||||||
|
#ifndef SHELL_EXT
|
||||||
|
Log(FileName,St(MLogFileHead),"???");
|
||||||
|
#endif
|
||||||
|
BrokenFileHeader=true;
|
||||||
|
ErrHandler.SetErrorCode(CRC_ERROR);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ShortBlock.HeadType==COMM_HEAD)
|
||||||
|
Raw.Read(SIZEOF_COMMHEAD-SIZEOF_SHORTBLOCKHEAD);
|
||||||
|
else
|
||||||
|
if (ShortBlock.HeadType==MAIN_HEAD && (ShortBlock.Flags & MHD_COMMENT)!=0)
|
||||||
|
Raw.Read(SIZEOF_NEWMHD-SIZEOF_SHORTBLOCKHEAD);
|
||||||
|
else
|
||||||
|
Raw.Read(ShortBlock.HeadSize-SIZEOF_SHORTBLOCKHEAD);
|
||||||
|
|
||||||
|
NextBlockPos=CurBlockPos+ShortBlock.HeadSize;
|
||||||
|
|
||||||
|
switch(ShortBlock.HeadType)
|
||||||
|
{
|
||||||
|
case MAIN_HEAD:
|
||||||
|
*(BaseBlock *)&NewMhd=ShortBlock;
|
||||||
|
Raw.Get(NewMhd.HighPosAV);
|
||||||
|
Raw.Get(NewMhd.PosAV);
|
||||||
|
if (NewMhd.Flags & MHD_ENCRYPTVER)
|
||||||
|
Raw.Get(NewMhd.EncryptVer);
|
||||||
|
break;
|
||||||
|
case ENDARC_HEAD:
|
||||||
|
*(BaseBlock *)&EndArcHead=ShortBlock;
|
||||||
|
if (EndArcHead.Flags & EARC_DATACRC)
|
||||||
|
Raw.Get(EndArcHead.ArcDataCRC);
|
||||||
|
if (EndArcHead.Flags & EARC_VOLNUMBER)
|
||||||
|
Raw.Get(EndArcHead.VolNumber);
|
||||||
|
break;
|
||||||
|
case FILE_HEAD:
|
||||||
|
case NEWSUB_HEAD:
|
||||||
|
{
|
||||||
|
FileHeader *hd=ShortBlock.HeadType==FILE_HEAD ? &NewLhd:&SubHead;
|
||||||
|
*(BaseBlock *)hd=ShortBlock;
|
||||||
|
Raw.Get(hd->PackSize);
|
||||||
|
Raw.Get(hd->UnpSize);
|
||||||
|
Raw.Get(hd->HostOS);
|
||||||
|
Raw.Get(hd->FileCRC);
|
||||||
|
Raw.Get(hd->FileTime);
|
||||||
|
Raw.Get(hd->UnpVer);
|
||||||
|
Raw.Get(hd->Method);
|
||||||
|
Raw.Get(hd->NameSize);
|
||||||
|
Raw.Get(hd->FileAttr);
|
||||||
|
if (hd->Flags & LHD_LARGE)
|
||||||
|
{
|
||||||
|
Raw.Get(hd->HighPackSize);
|
||||||
|
Raw.Get(hd->HighUnpSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hd->HighPackSize=hd->HighUnpSize=0;
|
||||||
|
if (hd->UnpSize==0xffffffff)
|
||||||
|
{
|
||||||
|
hd->UnpSize=int64to32(INT64MAX);
|
||||||
|
hd->HighUnpSize=int64to32(INT64MAX>>32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hd->FullPackSize=int32to64(hd->HighPackSize,hd->PackSize);
|
||||||
|
hd->FullUnpSize=int32to64(hd->HighUnpSize,hd->UnpSize);
|
||||||
|
|
||||||
|
char FileName[NM*4];
|
||||||
|
int NameSize=Min(hd->NameSize,sizeof(FileName)-1);
|
||||||
|
Raw.Get((byte *)FileName,NameSize);
|
||||||
|
FileName[NameSize]=0;
|
||||||
|
|
||||||
|
strncpy(hd->FileName,FileName,sizeof(hd->FileName));
|
||||||
|
hd->FileName[sizeof(hd->FileName)-1]=0;
|
||||||
|
|
||||||
|
if (hd->HeadType==NEWSUB_HEAD)
|
||||||
|
{
|
||||||
|
int DataSize=hd->HeadSize-hd->NameSize-SIZEOF_NEWLHD;
|
||||||
|
if (hd->Flags & LHD_SALT)
|
||||||
|
DataSize-=SALT_SIZE;
|
||||||
|
if (DataSize>0)
|
||||||
|
{
|
||||||
|
hd->SubData.Alloc(DataSize);
|
||||||
|
Raw.Get(&hd->SubData[0],DataSize);
|
||||||
|
if (hd->CmpName(SUBHEAD_TYPE_RR))
|
||||||
|
{
|
||||||
|
byte *D=&hd->SubData[8];
|
||||||
|
RecoverySectors=D[0]+((uint)D[1]<<8)+((uint)D[2]<<16)+((uint)D[3]<<24);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (hd->HeadType==FILE_HEAD)
|
||||||
|
{
|
||||||
|
if (hd->Flags & LHD_UNICODE)
|
||||||
|
{
|
||||||
|
EncodeFileName NameCoder;
|
||||||
|
int Length=strlen(FileName);
|
||||||
|
if (Length==hd->NameSize)
|
||||||
|
{
|
||||||
|
UtfToWide(FileName,hd->FileNameW,sizeof(hd->FileNameW)/sizeof(hd->FileNameW[0])-1);
|
||||||
|
WideToChar(hd->FileNameW,hd->FileName,sizeof(hd->FileName)/sizeof(hd->FileName[0])-1);
|
||||||
|
ExtToInt(hd->FileName,hd->FileName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Length++;
|
||||||
|
NameCoder.Decode(FileName,(byte *)FileName+Length,
|
||||||
|
hd->NameSize-Length,hd->FileNameW,
|
||||||
|
sizeof(hd->FileNameW)/sizeof(hd->FileNameW[0]));
|
||||||
|
}
|
||||||
|
if (*hd->FileNameW==0)
|
||||||
|
hd->Flags &= ~LHD_UNICODE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*hd->FileNameW=0;
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
ConvertNameCase(hd->FileName);
|
||||||
|
ConvertNameCase(hd->FileNameW);
|
||||||
|
#endif
|
||||||
|
ConvertUnknownHeader();
|
||||||
|
}
|
||||||
|
if (hd->Flags & LHD_SALT)
|
||||||
|
Raw.Get(hd->Salt,SALT_SIZE);
|
||||||
|
hd->mtime.SetDos(hd->FileTime);
|
||||||
|
hd->ctime.Reset();
|
||||||
|
hd->atime.Reset();
|
||||||
|
hd->arctime.Reset();
|
||||||
|
if (hd->Flags & LHD_EXTTIME)
|
||||||
|
{
|
||||||
|
ushort Flags;
|
||||||
|
Raw.Get(Flags);
|
||||||
|
RarTime *tbl[4];
|
||||||
|
tbl[0]=&NewLhd.mtime;
|
||||||
|
tbl[1]=&NewLhd.ctime;
|
||||||
|
tbl[2]=&NewLhd.atime;
|
||||||
|
tbl[3]=&NewLhd.arctime;
|
||||||
|
for (int I=0;I<4;I++)
|
||||||
|
{
|
||||||
|
RarTime *CurTime=tbl[I];
|
||||||
|
uint rmode=Flags>>(3-I)*4;
|
||||||
|
if ((rmode & 8)==0)
|
||||||
|
continue;
|
||||||
|
if (I!=0)
|
||||||
|
{
|
||||||
|
uint DosTime;
|
||||||
|
Raw.Get(DosTime);
|
||||||
|
CurTime->SetDos(DosTime);
|
||||||
|
}
|
||||||
|
RarLocalTime rlt;
|
||||||
|
CurTime->GetLocal(&rlt);
|
||||||
|
if (rmode & 4)
|
||||||
|
rlt.Second++;
|
||||||
|
rlt.Reminder=0;
|
||||||
|
int count=rmode&3;
|
||||||
|
for (int J=0;J<count;J++)
|
||||||
|
{
|
||||||
|
byte CurByte;
|
||||||
|
Raw.Get(CurByte);
|
||||||
|
rlt.Reminder|=(((uint)CurByte)<<((J+3-count)*8));
|
||||||
|
}
|
||||||
|
CurTime->SetLocal(&rlt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NextBlockPos+=hd->FullPackSize;
|
||||||
|
bool CRCProcessedOnly=(hd->Flags & LHD_COMMENT)!=0;
|
||||||
|
HeaderCRC=~Raw.GetCRC(CRCProcessedOnly)&0xffff;
|
||||||
|
if (hd->HeadCRC!=HeaderCRC)
|
||||||
|
{
|
||||||
|
if (hd->HeadType==NEWSUB_HEAD)
|
||||||
|
strcat(hd->FileName,"- ???");
|
||||||
|
BrokenFileHeader=true;
|
||||||
|
ErrHandler.SetErrorCode(WARNING);
|
||||||
|
#ifndef SHELL_EXT
|
||||||
|
Log(Archive::FileName,St(MLogFileHead),IntNameToExt(hd->FileName));
|
||||||
|
Alarm();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
case COMM_HEAD:
|
||||||
|
*(BaseBlock *)&CommHead=ShortBlock;
|
||||||
|
Raw.Get(CommHead.UnpSize);
|
||||||
|
Raw.Get(CommHead.UnpVer);
|
||||||
|
Raw.Get(CommHead.Method);
|
||||||
|
Raw.Get(CommHead.CommCRC);
|
||||||
|
break;
|
||||||
|
case SIGN_HEAD:
|
||||||
|
*(BaseBlock *)&SignHead=ShortBlock;
|
||||||
|
Raw.Get(SignHead.CreationTime);
|
||||||
|
Raw.Get(SignHead.ArcNameSize);
|
||||||
|
Raw.Get(SignHead.UserNameSize);
|
||||||
|
break;
|
||||||
|
case AV_HEAD:
|
||||||
|
*(BaseBlock *)&AVHead=ShortBlock;
|
||||||
|
Raw.Get(AVHead.UnpVer);
|
||||||
|
Raw.Get(AVHead.Method);
|
||||||
|
Raw.Get(AVHead.AVVer);
|
||||||
|
Raw.Get(AVHead.AVInfoCRC);
|
||||||
|
break;
|
||||||
|
case PROTECT_HEAD:
|
||||||
|
*(BaseBlock *)&ProtectHead=ShortBlock;
|
||||||
|
Raw.Get(ProtectHead.DataSize);
|
||||||
|
Raw.Get(ProtectHead.Version);
|
||||||
|
Raw.Get(ProtectHead.RecSectors);
|
||||||
|
Raw.Get(ProtectHead.TotalBlocks);
|
||||||
|
Raw.Get(ProtectHead.Mark,8);
|
||||||
|
NextBlockPos+=ProtectHead.DataSize;
|
||||||
|
RecoverySectors=ProtectHead.RecSectors;
|
||||||
|
break;
|
||||||
|
case SUB_HEAD:
|
||||||
|
*(BaseBlock *)&SubBlockHead=ShortBlock;
|
||||||
|
Raw.Get(SubBlockHead.DataSize);
|
||||||
|
NextBlockPos+=SubBlockHead.DataSize;
|
||||||
|
Raw.Get(SubBlockHead.SubType);
|
||||||
|
Raw.Get(SubBlockHead.Level);
|
||||||
|
switch(SubBlockHead.SubType)
|
||||||
|
{
|
||||||
|
case UO_HEAD:
|
||||||
|
*(SubBlockHeader *)&UOHead=SubBlockHead;
|
||||||
|
Raw.Get(UOHead.OwnerNameSize);
|
||||||
|
Raw.Get(UOHead.GroupNameSize);
|
||||||
|
if (UOHead.OwnerNameSize>NM-1)
|
||||||
|
UOHead.OwnerNameSize=NM-1;
|
||||||
|
if (UOHead.GroupNameSize>NM-1)
|
||||||
|
UOHead.GroupNameSize=NM-1;
|
||||||
|
Raw.Get((byte *)UOHead.OwnerName,UOHead.OwnerNameSize);
|
||||||
|
Raw.Get((byte *)UOHead.GroupName,UOHead.GroupNameSize);
|
||||||
|
UOHead.OwnerName[UOHead.OwnerNameSize]=0;
|
||||||
|
UOHead.GroupName[UOHead.GroupNameSize]=0;
|
||||||
|
break;
|
||||||
|
case MAC_HEAD:
|
||||||
|
*(SubBlockHeader *)&MACHead=SubBlockHead;
|
||||||
|
Raw.Get(MACHead.fileType);
|
||||||
|
Raw.Get(MACHead.fileCreator);
|
||||||
|
break;
|
||||||
|
case EA_HEAD:
|
||||||
|
case BEEA_HEAD:
|
||||||
|
case NTACL_HEAD:
|
||||||
|
*(SubBlockHeader *)&EAHead=SubBlockHead;
|
||||||
|
Raw.Get(EAHead.UnpSize);
|
||||||
|
Raw.Get(EAHead.UnpVer);
|
||||||
|
Raw.Get(EAHead.Method);
|
||||||
|
Raw.Get(EAHead.EACRC);
|
||||||
|
break;
|
||||||
|
case STREAM_HEAD:
|
||||||
|
*(SubBlockHeader *)&StreamHead=SubBlockHead;
|
||||||
|
Raw.Get(StreamHead.UnpSize);
|
||||||
|
Raw.Get(StreamHead.UnpVer);
|
||||||
|
Raw.Get(StreamHead.Method);
|
||||||
|
Raw.Get(StreamHead.StreamCRC);
|
||||||
|
Raw.Get(StreamHead.StreamNameSize);
|
||||||
|
if (StreamHead.StreamNameSize>NM-1)
|
||||||
|
StreamHead.StreamNameSize=NM-1;
|
||||||
|
Raw.Get((byte *)StreamHead.StreamName,StreamHead.StreamNameSize);
|
||||||
|
StreamHead.StreamName[StreamHead.StreamNameSize]=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
if (ShortBlock.Flags & LONG_BLOCK)
|
||||||
|
{
|
||||||
|
uint DataSize;
|
||||||
|
Raw.Get(DataSize);
|
||||||
|
NextBlockPos+=DataSize;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
HeaderCRC=~Raw.GetCRC(false)&0xffff;
|
||||||
|
CurHeaderType=ShortBlock.HeadType;
|
||||||
|
if (Decrypt)
|
||||||
|
{
|
||||||
|
NextBlockPos+=Raw.PaddedSize()+SALT_SIZE;
|
||||||
|
|
||||||
|
if (ShortBlock.HeadCRC!=HeaderCRC)
|
||||||
|
{
|
||||||
|
bool Recovered=false;
|
||||||
|
if (ShortBlock.HeadType==ENDARC_HEAD && (EndArcHead.Flags & EARC_REVSPACE)!=0)
|
||||||
|
{
|
||||||
|
SaveFilePos SavePos(*this);
|
||||||
|
Int64 Length=Tell();
|
||||||
|
Seek(Length-7,SEEK_SET);
|
||||||
|
Recovered=true;
|
||||||
|
for (int J=0;J<7;J++)
|
||||||
|
if (GetByte()!=0)
|
||||||
|
Recovered=false;
|
||||||
|
}
|
||||||
|
if (!Recovered)
|
||||||
|
{
|
||||||
|
#ifndef SILENT
|
||||||
|
Log(FileName,St(MEncrBadCRC),FileName);
|
||||||
|
#endif
|
||||||
|
Close();
|
||||||
|
|
||||||
|
BrokenFileHeader=true;
|
||||||
|
ErrHandler.SetErrorCode(CRC_ERROR);
|
||||||
|
return(0);
|
||||||
|
// ErrHandler.Exit(CRC_ERROR);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NextBlockPos<=CurBlockPos)
|
||||||
|
{
|
||||||
|
#ifndef SHELL_EXT
|
||||||
|
Log(FileName,St(MLogFileHead),"???");
|
||||||
|
#endif
|
||||||
|
BrokenFileHeader=true;
|
||||||
|
ErrHandler.SetErrorCode(CRC_ERROR);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
return(Raw.Size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
int Archive::ReadOldHeader()
|
||||||
|
{
|
||||||
|
RawRead Raw(this);
|
||||||
|
if (CurBlockPos<=SFXSize)
|
||||||
|
{
|
||||||
|
Raw.Read(SIZEOF_OLDMHD);
|
||||||
|
Raw.Get(OldMhd.Mark,4);
|
||||||
|
Raw.Get(OldMhd.HeadSize);
|
||||||
|
Raw.Get(OldMhd.Flags);
|
||||||
|
NextBlockPos=CurBlockPos+OldMhd.HeadSize;
|
||||||
|
CurHeaderType=MAIN_HEAD;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
OldFileHeader OldLhd;
|
||||||
|
Raw.Read(SIZEOF_OLDLHD);
|
||||||
|
NewLhd.HeadType=FILE_HEAD;
|
||||||
|
Raw.Get(NewLhd.PackSize);
|
||||||
|
Raw.Get(NewLhd.UnpSize);
|
||||||
|
Raw.Get(OldLhd.FileCRC);
|
||||||
|
Raw.Get(NewLhd.HeadSize);
|
||||||
|
Raw.Get(NewLhd.FileTime);
|
||||||
|
Raw.Get(OldLhd.FileAttr);
|
||||||
|
Raw.Get(OldLhd.Flags);
|
||||||
|
Raw.Get(OldLhd.UnpVer);
|
||||||
|
Raw.Get(OldLhd.NameSize);
|
||||||
|
Raw.Get(OldLhd.Method);
|
||||||
|
|
||||||
|
NewLhd.Flags=OldLhd.Flags|LONG_BLOCK;
|
||||||
|
NewLhd.UnpVer=(OldLhd.UnpVer==2) ? 13 : 10;
|
||||||
|
NewLhd.Method=OldLhd.Method+0x30;
|
||||||
|
NewLhd.NameSize=OldLhd.NameSize;
|
||||||
|
NewLhd.FileAttr=OldLhd.FileAttr;
|
||||||
|
NewLhd.FileCRC=OldLhd.FileCRC;
|
||||||
|
NewLhd.FullPackSize=NewLhd.PackSize;
|
||||||
|
NewLhd.FullUnpSize=NewLhd.UnpSize;
|
||||||
|
|
||||||
|
NewLhd.mtime.SetDos(NewLhd.FileTime);
|
||||||
|
NewLhd.ctime.Reset();
|
||||||
|
NewLhd.atime.Reset();
|
||||||
|
NewLhd.arctime.Reset();
|
||||||
|
|
||||||
|
Raw.Read(OldLhd.NameSize);
|
||||||
|
Raw.Get((byte *)NewLhd.FileName,OldLhd.NameSize);
|
||||||
|
NewLhd.FileName[OldLhd.NameSize]=0;
|
||||||
|
ConvertNameCase(NewLhd.FileName);
|
||||||
|
*NewLhd.FileNameW=0;
|
||||||
|
|
||||||
|
if (Raw.Size()!=0)
|
||||||
|
NextBlockPos=CurBlockPos+NewLhd.HeadSize+NewLhd.PackSize;
|
||||||
|
CurHeaderType=FILE_HEAD;
|
||||||
|
}
|
||||||
|
return(NextBlockPos>CurBlockPos ? Raw.Size():0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void Archive::ConvertNameCase(char *Name)
|
||||||
|
{
|
||||||
|
if (Cmd->ConvertNames==NAMES_UPPERCASE)
|
||||||
|
{
|
||||||
|
IntToExt(Name,Name);
|
||||||
|
strupper(Name);
|
||||||
|
ExtToInt(Name,Name);
|
||||||
|
}
|
||||||
|
if (Cmd->ConvertNames==NAMES_LOWERCASE)
|
||||||
|
{
|
||||||
|
IntToExt(Name,Name);
|
||||||
|
strlower(Name);
|
||||||
|
ExtToInt(Name,Name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
void Archive::ConvertNameCase(wchar *Name)
|
||||||
|
{
|
||||||
|
if (Cmd->ConvertNames==NAMES_UPPERCASE)
|
||||||
|
strupperw(Name);
|
||||||
|
if (Cmd->ConvertNames==NAMES_LOWERCASE)
|
||||||
|
strlowerw(Name);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool Archive::IsArcDir()
|
||||||
|
{
|
||||||
|
return((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool Archive::IsArcLabel()
|
||||||
|
{
|
||||||
|
return(NewLhd.HostOS<=HOST_WIN32 && (NewLhd.FileAttr & 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Archive::ConvertAttributes()
|
||||||
|
{
|
||||||
|
#if defined(_WIN_32) || defined(_EMX)
|
||||||
|
switch(NewLhd.HostOS)
|
||||||
|
{
|
||||||
|
case HOST_MSDOS:
|
||||||
|
case HOST_OS2:
|
||||||
|
case HOST_WIN32:
|
||||||
|
break;
|
||||||
|
case HOST_UNIX:
|
||||||
|
case HOST_BEOS:
|
||||||
|
if ((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY)
|
||||||
|
NewLhd.FileAttr=0x10;
|
||||||
|
else
|
||||||
|
NewLhd.FileAttr=0x20;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if ((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY)
|
||||||
|
NewLhd.FileAttr=0x10;
|
||||||
|
else
|
||||||
|
NewLhd.FileAttr=0x20;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef _UNIX
|
||||||
|
static mode_t mask = (mode_t) -1;
|
||||||
|
|
||||||
|
if (mask == (mode_t) -1)
|
||||||
|
{
|
||||||
|
mask = umask(022);
|
||||||
|
umask(mask);
|
||||||
|
}
|
||||||
|
switch(NewLhd.HostOS)
|
||||||
|
{
|
||||||
|
case HOST_MSDOS:
|
||||||
|
case HOST_OS2:
|
||||||
|
case HOST_WIN32:
|
||||||
|
if (NewLhd.FileAttr & 0x10)
|
||||||
|
NewLhd.FileAttr=0x41ff & ~mask;
|
||||||
|
else
|
||||||
|
if (NewLhd.FileAttr & 1)
|
||||||
|
NewLhd.FileAttr=0x8124 & ~mask;
|
||||||
|
else
|
||||||
|
NewLhd.FileAttr=0x81b6 & ~mask;
|
||||||
|
break;
|
||||||
|
case HOST_UNIX:
|
||||||
|
case HOST_BEOS:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if ((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY)
|
||||||
|
NewLhd.FileAttr=0x41ff & ~mask;
|
||||||
|
else
|
||||||
|
NewLhd.FileAttr=0x81b6 & ~mask;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Archive::ConvertUnknownHeader()
|
||||||
|
{
|
||||||
|
if (NewLhd.UnpVer<20 && (NewLhd.FileAttr & 0x10))
|
||||||
|
NewLhd.Flags|=LHD_DIRECTORY;
|
||||||
|
if (NewLhd.HostOS>=HOST_MAX)
|
||||||
|
{
|
||||||
|
if ((NewLhd.Flags & LHD_WINDOWMASK)==LHD_DIRECTORY)
|
||||||
|
NewLhd.FileAttr=0x10;
|
||||||
|
else
|
||||||
|
NewLhd.FileAttr=0x20;
|
||||||
|
}
|
||||||
|
for (char *s=NewLhd.FileName;*s!=0;s=charnext(s))
|
||||||
|
{
|
||||||
|
if (*s=='/' || *s=='\\')
|
||||||
|
*s=CPATHDIVIDER;
|
||||||
|
#if defined(_APPLE) && !defined(UNICODE_SUPPORTED)
|
||||||
|
if ((byte)*s<32 || (byte)*s>127)
|
||||||
|
*s='_';
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
for (wchar *s=NewLhd.FileNameW;*s!=0;s++)
|
||||||
|
if (*s=='/' || *s=='\\')
|
||||||
|
*s=CPATHDIVIDER;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SHELL_EXT
|
||||||
|
bool Archive::ReadSubData(Array<byte> *UnpData,File *DestFile)
|
||||||
|
{
|
||||||
|
if (HeaderCRC!=SubHead.HeadCRC)
|
||||||
|
{
|
||||||
|
#ifndef SHELL_EXT
|
||||||
|
Log(FileName,St(MSubHeadCorrupt));
|
||||||
|
#endif
|
||||||
|
ErrHandler.SetErrorCode(CRC_ERROR);
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
if (SubHead.Method<0x30 || SubHead.Method>0x35 || SubHead.UnpVer>/*PACK_VER*/36)
|
||||||
|
{
|
||||||
|
#ifndef SHELL_EXT
|
||||||
|
Log(FileName,St(MSubHeadUnknown));
|
||||||
|
#endif
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SubHead.PackSize==0 && (SubHead.Flags & LHD_SPLIT_AFTER)==0)
|
||||||
|
return(true);
|
||||||
|
|
||||||
|
SubDataIO.Init();
|
||||||
|
Unpack Unpack(&SubDataIO);
|
||||||
|
Unpack.Init();
|
||||||
|
|
||||||
|
if (DestFile==NULL)
|
||||||
|
{
|
||||||
|
UnpData->Alloc(SubHead.UnpSize);
|
||||||
|
SubDataIO.SetUnpackToMemory(&(*UnpData)[0],SubHead.UnpSize);
|
||||||
|
}
|
||||||
|
if (SubHead.Flags & LHD_PASSWORD)
|
||||||
|
if (*Cmd->Password)
|
||||||
|
SubDataIO.SetEncryption(SubHead.UnpVer,Cmd->Password,
|
||||||
|
(SubHead.Flags & LHD_SALT) ? SubHead.Salt:NULL,false,
|
||||||
|
SubHead.UnpVer>=36);
|
||||||
|
else
|
||||||
|
return(false);
|
||||||
|
SubDataIO.SetPackedSizeToRead(SubHead.PackSize);
|
||||||
|
SubDataIO.EnableShowProgress(false);
|
||||||
|
SubDataIO.SetFiles(this,DestFile);
|
||||||
|
SubDataIO.UnpVolume=(SubHead.Flags & LHD_SPLIT_AFTER);
|
||||||
|
SubDataIO.SetSubHeader(&SubHead,NULL);
|
||||||
|
Unpack.SetDestSize(SubHead.UnpSize);
|
||||||
|
if (SubHead.Method==0x30)
|
||||||
|
CmdExtract::UnstoreFile(SubDataIO,SubHead.UnpSize);
|
||||||
|
else
|
||||||
|
Unpack.DoUnpack(SubHead.UnpVer,false);
|
||||||
|
|
||||||
|
if (SubHead.FileCRC!=~SubDataIO.UnpFileCRC)
|
||||||
|
{
|
||||||
|
#ifndef SHELL_EXT
|
||||||
|
Log(FileName,St(MSubHeadDataCRC),SubHead.FileName);
|
||||||
|
#endif
|
||||||
|
ErrHandler.SetErrorCode(CRC_ERROR);
|
||||||
|
if (UnpData!=NULL)
|
||||||
|
UnpData->Reset();
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
#ifndef _RAR_ARRAY_
|
||||||
|
#define _RAR_ARRAY_
|
||||||
|
|
||||||
|
extern ErrorHandler ErrHandler;
|
||||||
|
|
||||||
|
template <class T> class Array
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
T *Buffer;
|
||||||
|
int BufSize;
|
||||||
|
int AllocSize;
|
||||||
|
public:
|
||||||
|
Array();
|
||||||
|
Array(int Size);
|
||||||
|
~Array();
|
||||||
|
inline void CleanData();
|
||||||
|
inline T& operator [](int Item);
|
||||||
|
inline int Size();
|
||||||
|
void Add(int Items);
|
||||||
|
void Alloc(int Items);
|
||||||
|
void Reset();
|
||||||
|
void operator = (Array<T> &Src);
|
||||||
|
void Push(T Item);
|
||||||
|
T* Addr() {return(Buffer);}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T> void Array<T>::CleanData()
|
||||||
|
{
|
||||||
|
Buffer=NULL;
|
||||||
|
BufSize=0;
|
||||||
|
AllocSize=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> Array<T>::Array()
|
||||||
|
{
|
||||||
|
CleanData();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> Array<T>::Array(int Size)
|
||||||
|
{
|
||||||
|
Buffer=(T *)rarmalloc(sizeof(T)*Size);
|
||||||
|
if (Buffer==NULL && Size!=0)
|
||||||
|
ErrHandler.MemoryError();
|
||||||
|
|
||||||
|
AllocSize=BufSize=Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> Array<T>::~Array()
|
||||||
|
{
|
||||||
|
if (Buffer!=NULL)
|
||||||
|
rarfree(Buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> inline T& Array<T>::operator [](int Item)
|
||||||
|
{
|
||||||
|
return(Buffer[Item]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> inline int Array<T>::Size()
|
||||||
|
{
|
||||||
|
return(BufSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> void Array<T>::Add(int Items)
|
||||||
|
{
|
||||||
|
BufSize+=Items;
|
||||||
|
if (BufSize>AllocSize)
|
||||||
|
{
|
||||||
|
int Suggested=AllocSize+AllocSize/4+32;
|
||||||
|
int NewSize=Max(BufSize,Suggested);
|
||||||
|
|
||||||
|
Buffer=(T *)rarrealloc(Buffer,NewSize*sizeof(T));
|
||||||
|
if (Buffer==NULL)
|
||||||
|
ErrHandler.MemoryError();
|
||||||
|
AllocSize=NewSize;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> void Array<T>::Alloc(int Items)
|
||||||
|
{
|
||||||
|
if (Items>AllocSize)
|
||||||
|
Add(Items-BufSize);
|
||||||
|
else
|
||||||
|
BufSize=Items;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> void Array<T>::Reset()
|
||||||
|
{
|
||||||
|
if (Buffer!=NULL)
|
||||||
|
{
|
||||||
|
rarfree(Buffer);
|
||||||
|
Buffer=NULL;
|
||||||
|
}
|
||||||
|
BufSize=0;
|
||||||
|
AllocSize=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> void Array<T>::operator =(Array<T> &Src)
|
||||||
|
{
|
||||||
|
Reset();
|
||||||
|
Alloc(Src.BufSize);
|
||||||
|
if (Src.BufSize!=0)
|
||||||
|
memcpy((void *)Buffer,(void *)Src.Buffer,Src.BufSize*sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <class T> void Array<T>::Push(T Item)
|
||||||
|
{
|
||||||
|
Add(1);
|
||||||
|
(*this)[Size()-1]=Item;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
|
||||||
|
|
||||||
|
void ExtractBeEA(Archive &Arc,char *FileName)
|
||||||
|
{
|
||||||
|
if (Arc.HeaderCRC!=Arc.EAHead.HeadCRC)
|
||||||
|
{
|
||||||
|
Log(Arc.FileName,St(MEABroken),FileName);
|
||||||
|
ErrHandler.SetErrorCode(CRC_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (Arc.EAHead.Method<0x31 || Arc.EAHead.Method>0x35 || Arc.EAHead.UnpVer>PACK_VER)
|
||||||
|
{
|
||||||
|
Log(Arc.FileName,St(MEAUnknHeader),FileName);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ComprDataIO DataIO;
|
||||||
|
Unpack Unpack(&DataIO);
|
||||||
|
Unpack.Init();
|
||||||
|
|
||||||
|
Array<byte> UnpData(Arc.EAHead.UnpSize);
|
||||||
|
DataIO.SetUnpackToMemory(&UnpData[0],Arc.EAHead.UnpSize);
|
||||||
|
DataIO.SetPackedSizeToRead(Arc.EAHead.DataSize);
|
||||||
|
DataIO.EnableShowProgress(false);
|
||||||
|
DataIO.SetFiles(&Arc,NULL);
|
||||||
|
Unpack.SetDestSize(Arc.EAHead.UnpSize);
|
||||||
|
Unpack.DoUnpack(Arc.EAHead.UnpVer,false);
|
||||||
|
|
||||||
|
if (Arc.EAHead.EACRC!=~DataIO.UnpFileCRC)
|
||||||
|
{
|
||||||
|
Log(Arc.FileName,St(MEABroken),FileName);
|
||||||
|
ErrHandler.SetErrorCode(CRC_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int fd = open(FileName,O_WRONLY);
|
||||||
|
if (fd==-1)
|
||||||
|
{
|
||||||
|
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||||
|
ErrHandler.SetErrorCode(WARNING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AttrPos=0;
|
||||||
|
while (AttrPos<Arc.EAHead.UnpSize)
|
||||||
|
{
|
||||||
|
unsigned char *CurItem=&UnpData[AttrPos];
|
||||||
|
int NameSize=CurItem[0]+((int)CurItem[1]<<8);
|
||||||
|
int Type=CurItem[2]+((int)CurItem[3]<<8)+((int)CurItem[4]<<16)+((int)CurItem[5]<<24);
|
||||||
|
int Size=CurItem[6]+((int)CurItem[7]<<8)+((int)CurItem[8]<<16)+((int)CurItem[9]<<24);
|
||||||
|
char Name[1024];
|
||||||
|
if (NameSize>=sizeof(Name))
|
||||||
|
{
|
||||||
|
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||||
|
ErrHandler.SetErrorCode(WARNING);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
memcpy(Name,CurItem+10,NameSize);
|
||||||
|
Name[NameSize]=0;
|
||||||
|
if (fs_write_attr(fd,Name,Type,0,CurItem+10+NameSize,Size)==-1)
|
||||||
|
{
|
||||||
|
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||||
|
ErrHandler.SetErrorCode(WARNING);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
AttrPos+=10+NameSize+Size;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
mprintf(St(MShowEA));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ExtractBeEANew(Archive &Arc,char *FileName)
|
||||||
|
{
|
||||||
|
Array<byte> SubData;
|
||||||
|
if (!Arc.ReadSubData(&SubData,NULL))
|
||||||
|
return;
|
||||||
|
|
||||||
|
int fd = open(FileName,O_WRONLY);
|
||||||
|
if (fd==-1)
|
||||||
|
{
|
||||||
|
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||||
|
ErrHandler.SetErrorCode(WARNING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int AttrPos=0;
|
||||||
|
while (AttrPos<Arc.EAHead.UnpSize)
|
||||||
|
{
|
||||||
|
unsigned char *CurItem=&SubData[AttrPos];
|
||||||
|
int NameSize=CurItem[0]+((int)CurItem[1]<<8);
|
||||||
|
int Type=CurItem[2]+((int)CurItem[3]<<8)+((int)CurItem[4]<<16)+((int)CurItem[5]<<24);
|
||||||
|
int Size=CurItem[6]+((int)CurItem[7]<<8)+((int)CurItem[8]<<16)+((int)CurItem[9]<<24);
|
||||||
|
char Name[1024];
|
||||||
|
if (NameSize>=sizeof(Name))
|
||||||
|
{
|
||||||
|
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||||
|
ErrHandler.SetErrorCode(WARNING);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
memcpy(Name,CurItem+10,NameSize);
|
||||||
|
Name[NameSize]=0;
|
||||||
|
if (fs_write_attr(fd,Name,Type,0,CurItem+10+NameSize,Size)==-1)
|
||||||
|
{
|
||||||
|
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||||
|
ErrHandler.SetErrorCode(WARNING);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
AttrPos+=10+NameSize+Size;
|
||||||
|
}
|
||||||
|
close(fd);
|
||||||
|
mprintf(St(MShowEA));
|
||||||
|
}
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,57 @@
|
|||||||
|
#ifndef _RAR_CMDDATA_
|
||||||
|
#define _RAR_CMDDATA_
|
||||||
|
|
||||||
|
#define DefaultStoreList "7z;ace;arj;bz2;cab;gz;jpeg;jpg;lha;lzh;mp3;rar;taz;tgz;z;zip"
|
||||||
|
|
||||||
|
class CommandData:public RAROptions
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
void ProcessSwitchesString(char *Str);
|
||||||
|
void ProcessSwitch(char *Switch);
|
||||||
|
void BadSwitch(char *Switch);
|
||||||
|
bool ExclCheckArgs(StringList *Args,char *CheckName,bool CheckFullPath,int MatchMode);
|
||||||
|
uint GetExclAttr(char *Str);
|
||||||
|
|
||||||
|
bool FileLists;
|
||||||
|
bool NoMoreSwitches;
|
||||||
|
bool TimeConverted;
|
||||||
|
bool BareOutput;
|
||||||
|
public:
|
||||||
|
CommandData();
|
||||||
|
~CommandData();
|
||||||
|
void Init();
|
||||||
|
void Close();
|
||||||
|
void ParseArg(char *Arg,wchar *ArgW);
|
||||||
|
void ParseDone();
|
||||||
|
void ParseEnvVar();
|
||||||
|
void ReadConfig(int argc,char *argv[]);
|
||||||
|
bool IsConfigEnabled(int argc,char *argv[]);
|
||||||
|
void OutTitle();
|
||||||
|
void OutHelp();
|
||||||
|
bool IsSwitch(int Ch);
|
||||||
|
bool ExclCheck(char *CheckName,bool CheckFullPath);
|
||||||
|
bool StoreCheck(char *CheckName);
|
||||||
|
bool TimeCheck(RarTime &ft);
|
||||||
|
bool SizeCheck(Int64 Size);
|
||||||
|
int IsProcessFile(FileHeader &NewLhd,bool *ExactMatch=NULL,int MatchType=MATCH_WILDSUBPATH);
|
||||||
|
void ProcessCommand();
|
||||||
|
void AddArcName(char *Name,wchar *NameW);
|
||||||
|
bool GetArcName(char *Name,wchar *NameW,int MaxSize);
|
||||||
|
bool CheckWinSize();
|
||||||
|
|
||||||
|
int GetRecoverySize(char *Str,int DefSize);
|
||||||
|
|
||||||
|
char Command[NM+16];
|
||||||
|
wchar CommandW[NM+16];
|
||||||
|
|
||||||
|
char ArcName[NM];
|
||||||
|
wchar ArcNameW[NM];
|
||||||
|
|
||||||
|
StringList *FileArgs;
|
||||||
|
StringList *ExclArgs;
|
||||||
|
StringList *InclArgs;
|
||||||
|
StringList *ArcNames;
|
||||||
|
StringList *StoreArgs;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
|
||||||
|
|
||||||
|
inline unsigned int RangeCoder::GetChar()
|
||||||
|
{
|
||||||
|
return(UnpackRead->GetChar());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RangeCoder::InitDecoder(Unpack *UnpackRead)
|
||||||
|
{
|
||||||
|
RangeCoder::UnpackRead=UnpackRead;
|
||||||
|
|
||||||
|
low=code=0;
|
||||||
|
range=uint(-1);
|
||||||
|
for (int i=0;i < 4;i++)
|
||||||
|
code=(code << 8) | GetChar();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#define ARI_DEC_NORMALIZE(code,low,range,read) \
|
||||||
|
{ \
|
||||||
|
while ((low^(low+range))<TOP || range<BOT && ((range=-low&(BOT-1)),1)) \
|
||||||
|
{ \
|
||||||
|
code=(code << 8) | read->GetChar(); \
|
||||||
|
range <<= 8; \
|
||||||
|
low <<= 8; \
|
||||||
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int RangeCoder::GetCurrentCount()
|
||||||
|
{
|
||||||
|
return (code-low)/(range /= SubRange.scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline uint RangeCoder::GetCurrentShiftCount(uint SHIFT)
|
||||||
|
{
|
||||||
|
return (code-low)/(range >>= SHIFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void RangeCoder::Decode()
|
||||||
|
{
|
||||||
|
low += range*SubRange.LowCount;
|
||||||
|
range *= SubRange.HighCount-SubRange.LowCount;
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* Contents: 'Carryless rangecoder' by Dmitry Subbotin *
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
const uint TOP=1 << 24, BOT=1 << 15;
|
||||||
|
|
||||||
|
class RangeCoder
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
void InitDecoder(Unpack *UnpackRead);
|
||||||
|
inline int GetCurrentCount();
|
||||||
|
inline uint GetCurrentShiftCount(uint SHIFT);
|
||||||
|
inline void Decode();
|
||||||
|
inline void PutChar(unsigned int c);
|
||||||
|
inline unsigned int GetChar();
|
||||||
|
|
||||||
|
uint low, code, range;
|
||||||
|
struct SUBRANGE
|
||||||
|
{
|
||||||
|
uint LowCount, HighCount, scale;
|
||||||
|
} SubRange;
|
||||||
|
|
||||||
|
Unpack *UnpackRead;
|
||||||
|
};
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#ifndef _RAR_COMPRESS_
|
||||||
|
#define _RAR_COMPRESS_
|
||||||
|
|
||||||
|
class ComprDataIO;
|
||||||
|
class PackingFileTable;
|
||||||
|
|
||||||
|
#define CODEBUFSIZE 0x4000
|
||||||
|
#define MAXWINSIZE 0x400000
|
||||||
|
#define MAXWINMASK (MAXWINSIZE-1)
|
||||||
|
|
||||||
|
#define LOW_DIST_REP_COUNT 16
|
||||||
|
|
||||||
|
#define NC 299 /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||||
|
#define DC 60
|
||||||
|
#define LDC 17
|
||||||
|
#define RC 28
|
||||||
|
#define HUFF_TABLE_SIZE (NC+DC+RC+LDC)
|
||||||
|
#define BC 20
|
||||||
|
|
||||||
|
#define NC20 298 /* alphabet = {0, 1, 2, ..., NC - 1} */
|
||||||
|
#define DC20 48
|
||||||
|
#define RC20 28
|
||||||
|
#define BC20 19
|
||||||
|
#define MC20 257
|
||||||
|
|
||||||
|
enum {CODE_HUFFMAN,CODE_LZ,CODE_LZ2,CODE_REPEATLZ,CODE_CACHELZ,
|
||||||
|
CODE_STARTFILE,CODE_ENDFILE,CODE_VM,CODE_VMDATA};
|
||||||
|
|
||||||
|
|
||||||
|
enum FilterType {
|
||||||
|
FILTER_NONE, FILTER_PPM /*dummy*/, FILTER_E8, FILTER_E8E9,
|
||||||
|
FILTER_UPCASETOLOW, FILTER_AUDIO, FILTER_RGB, FILTER_DELTA,
|
||||||
|
FILTER_ITANIUM, FILTER_E8E9V2
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,293 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
#ifndef GUI
|
||||||
|
#include "log.cpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(GUI) && !defined(SILENT)
|
||||||
|
static void RawPrint(char *Msg,MESSAGE_TYPE MessageType);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static MESSAGE_TYPE MsgStream=MSG_STDOUT;
|
||||||
|
static bool Sound=false;
|
||||||
|
const int MaxMsgSize=2*NM+2048;
|
||||||
|
|
||||||
|
void InitConsoleOptions(MESSAGE_TYPE MsgStream,bool Sound)
|
||||||
|
{
|
||||||
|
::MsgStream=MsgStream;
|
||||||
|
::Sound=Sound;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(GUI) && !defined(SILENT)
|
||||||
|
void mprintf(const char *fmt,...)
|
||||||
|
{
|
||||||
|
if (MsgStream==MSG_NULL || MsgStream==MSG_ERRONLY)
|
||||||
|
return;
|
||||||
|
safebuf char Msg[MaxMsgSize];
|
||||||
|
va_list argptr;
|
||||||
|
va_start(argptr,fmt);
|
||||||
|
vsprintf(Msg,fmt,argptr);
|
||||||
|
RawPrint(Msg,MsgStream);
|
||||||
|
va_end(argptr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(GUI) && !defined(SILENT)
|
||||||
|
void eprintf(const char *fmt,...)
|
||||||
|
{
|
||||||
|
if (MsgStream==MSG_NULL)
|
||||||
|
return;
|
||||||
|
safebuf char Msg[MaxMsgSize];
|
||||||
|
va_list argptr;
|
||||||
|
va_start(argptr,fmt);
|
||||||
|
vsprintf(Msg,fmt,argptr);
|
||||||
|
RawPrint(Msg,MSG_STDERR);
|
||||||
|
va_end(argptr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(GUI) && !defined(SILENT)
|
||||||
|
void RawPrint(char *Msg,MESSAGE_TYPE MessageType)
|
||||||
|
{
|
||||||
|
File OutFile;
|
||||||
|
switch(MessageType)
|
||||||
|
{
|
||||||
|
case MSG_STDOUT:
|
||||||
|
OutFile.SetHandleType(FILE_HANDLESTD);
|
||||||
|
break;
|
||||||
|
case MSG_STDERR:
|
||||||
|
case MSG_ERRONLY:
|
||||||
|
OutFile.SetHandleType(FILE_HANDLEERR);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#ifdef _WIN_32
|
||||||
|
CharToOem(Msg,Msg);
|
||||||
|
|
||||||
|
char OutMsg[MaxMsgSize],*OutPos=OutMsg;
|
||||||
|
for (int I=0;Msg[I]!=0;I++)
|
||||||
|
{
|
||||||
|
if (Msg[I]=='\n' && (I==0 || Msg[I-1]!='\r'))
|
||||||
|
*(OutPos++)='\r';
|
||||||
|
*(OutPos++)=Msg[I];
|
||||||
|
}
|
||||||
|
*OutPos=0;
|
||||||
|
strcpy(Msg,OutMsg);
|
||||||
|
#endif
|
||||||
|
#if defined(_UNIX) || defined(_EMX)
|
||||||
|
char OutMsg[MaxMsgSize],*OutPos=OutMsg;
|
||||||
|
for (int I=0;Msg[I]!=0;I++)
|
||||||
|
if (Msg[I]!='\r')
|
||||||
|
*(OutPos++)=Msg[I];
|
||||||
|
*OutPos=0;
|
||||||
|
strcpy(Msg,OutMsg);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
OutFile.Write(Msg,strlen(Msg));
|
||||||
|
// OutFile.Flush();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SILENT
|
||||||
|
void Alarm()
|
||||||
|
{
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (Sound)
|
||||||
|
putchar('\007');
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SILENT
|
||||||
|
#ifndef GUI
|
||||||
|
void GetPasswordText(char *Str,int MaxLength)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
HANDLE hConIn=GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
HANDLE hConOut=GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
DWORD ConInMode,ConOutMode;
|
||||||
|
DWORD Read=0;
|
||||||
|
GetConsoleMode(hConIn,&ConInMode);
|
||||||
|
GetConsoleMode(hConOut,&ConOutMode);
|
||||||
|
SetConsoleMode(hConIn,ENABLE_LINE_INPUT);
|
||||||
|
SetConsoleMode(hConOut,ENABLE_PROCESSED_OUTPUT|ENABLE_WRAP_AT_EOL_OUTPUT);
|
||||||
|
ReadConsole(hConIn,Str,MaxLength-1,&Read,NULL);
|
||||||
|
Str[Read]=0;
|
||||||
|
OemToChar(Str,Str);
|
||||||
|
SetConsoleMode(hConIn,ConInMode);
|
||||||
|
SetConsoleMode(hConOut,ConOutMode);
|
||||||
|
#elif defined(_EMX) || defined(_BEOS) || defined(__sparc) || defined(sparc) || defined (__VMS)
|
||||||
|
fgets(Str,MaxLength-1,stdin);
|
||||||
|
#else
|
||||||
|
strncpy(Str,getpass(""),MaxLength-1);
|
||||||
|
#endif
|
||||||
|
RemoveLF(Str);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(GUI) && !defined(SILENT)
|
||||||
|
unsigned int GetKey()
|
||||||
|
{
|
||||||
|
#ifdef SILENT
|
||||||
|
return(0);
|
||||||
|
#else
|
||||||
|
char Str[80];
|
||||||
|
#ifdef __GNUC__
|
||||||
|
fgets(Str,sizeof(Str),stdin);
|
||||||
|
return(Str[0]);
|
||||||
|
#else
|
||||||
|
File SrcFile;
|
||||||
|
SrcFile.SetHandleType(FILE_HANDLESTD);
|
||||||
|
SrcFile.Read(Str,sizeof(Str));
|
||||||
|
return(Str[0]);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SILENT
|
||||||
|
bool GetPassword(PASSWORD_TYPE Type,const char *FileName,char *Password,int MaxLength)
|
||||||
|
{
|
||||||
|
Alarm();
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
char PromptStr[256];
|
||||||
|
#if defined(_EMX) || defined(_BEOS)
|
||||||
|
strcpy(PromptStr,St(MAskPswEcho));
|
||||||
|
#else
|
||||||
|
strcpy(PromptStr,St(MAskPsw));
|
||||||
|
#endif
|
||||||
|
if (Type!=PASSWORD_GLOBAL)
|
||||||
|
{
|
||||||
|
strcat(PromptStr,St(MFor));
|
||||||
|
strcat(PromptStr,PointToName(FileName));
|
||||||
|
}
|
||||||
|
eprintf("\n%s: ",PromptStr);
|
||||||
|
GetPasswordText(Password,MaxLength);
|
||||||
|
if (*Password==0 && Type==PASSWORD_GLOBAL)
|
||||||
|
return(false);
|
||||||
|
if (Type==PASSWORD_GLOBAL)
|
||||||
|
{
|
||||||
|
strcpy(PromptStr,St(MReAskPsw));
|
||||||
|
eprintf(PromptStr);
|
||||||
|
char CmpStr[256];
|
||||||
|
GetPasswordText(CmpStr,sizeof(CmpStr));
|
||||||
|
if (*CmpStr==0 || strcmp(Password,CmpStr)!=0)
|
||||||
|
{
|
||||||
|
strcpy(PromptStr,St(MNotMatchPsw));
|
||||||
|
/*
|
||||||
|
#ifdef _WIN_32
|
||||||
|
CharToOem(PromptStr,PromptStr);
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
eprintf(PromptStr);
|
||||||
|
memset(Password,0,MaxLength);
|
||||||
|
memset(CmpStr,0,sizeof(CmpStr));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
memset(CmpStr,0,sizeof(CmpStr));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(GUI) && !defined(SILENT)
|
||||||
|
int Ask(const char *AskStr)
|
||||||
|
{
|
||||||
|
const int MaxItems=10;
|
||||||
|
char Item[MaxItems][40];
|
||||||
|
int ItemKeyPos[MaxItems],NumItems=0;
|
||||||
|
|
||||||
|
for (const char *NextItem=AskStr;NextItem!=NULL;NextItem=strchr(NextItem+1,'_'))
|
||||||
|
{
|
||||||
|
char *CurItem=Item[NumItems];
|
||||||
|
strncpy(CurItem,NextItem+1,sizeof(Item[0]));
|
||||||
|
char *EndItem=strchr(CurItem,'_');
|
||||||
|
if (EndItem!=NULL)
|
||||||
|
*EndItem=0;
|
||||||
|
int KeyPos=0,CurKey;
|
||||||
|
while ((CurKey=CurItem[KeyPos])!=0)
|
||||||
|
{
|
||||||
|
bool Found=false;
|
||||||
|
for (int I=0;I<NumItems && !Found;I++)
|
||||||
|
if (loctoupper(Item[I][ItemKeyPos[I]])==loctoupper(CurKey))
|
||||||
|
Found=true;
|
||||||
|
if (!Found && CurKey!=' ')
|
||||||
|
break;
|
||||||
|
KeyPos++;
|
||||||
|
}
|
||||||
|
ItemKeyPos[NumItems]=KeyPos;
|
||||||
|
NumItems++;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int I=0;I<NumItems;I++)
|
||||||
|
{
|
||||||
|
eprintf(I==0 ? (NumItems>4 ? "\n":" "):", ");
|
||||||
|
int KeyPos=ItemKeyPos[I];
|
||||||
|
for (int J=0;J<KeyPos;J++)
|
||||||
|
eprintf("%c",Item[I][J]);
|
||||||
|
eprintf("[%c]%s",Item[I][KeyPos],&Item[I][KeyPos+1]);
|
||||||
|
}
|
||||||
|
eprintf(" ");
|
||||||
|
int Ch=GetKey();
|
||||||
|
#if defined(_WIN_32)
|
||||||
|
OemToCharBuff((LPCSTR)&Ch,(LPTSTR)&Ch,1);
|
||||||
|
#endif
|
||||||
|
Ch=loctoupper(Ch);
|
||||||
|
for (int I=0;I<NumItems;I++)
|
||||||
|
if (Ch==Item[I][ItemKeyPos[I]])
|
||||||
|
return(I+1);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int KbdAnsi(char *Addr,int Size)
|
||||||
|
{
|
||||||
|
int RetCode=0;
|
||||||
|
#ifndef GUI
|
||||||
|
for (int I=0;I<Size;I++)
|
||||||
|
if (Addr[I]==27 && Addr[I+1]=='[')
|
||||||
|
{
|
||||||
|
for (int J=I+2;J<Size;J++)
|
||||||
|
{
|
||||||
|
if (Addr[J]=='\"')
|
||||||
|
return(2);
|
||||||
|
if (!isdigit(Addr[J]) && Addr[J]!=';')
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
RetCode=1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return(RetCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void OutComment(char *Comment,int Size)
|
||||||
|
{
|
||||||
|
#ifndef GUI
|
||||||
|
if (KbdAnsi(Comment,Size)==2)
|
||||||
|
return;
|
||||||
|
const int MaxOutSize=0x400;
|
||||||
|
for (int I=0;I<Size;I+=MaxOutSize)
|
||||||
|
{
|
||||||
|
char Msg[MaxOutSize+1];
|
||||||
|
int CopySize=Min(MaxOutSize,Size-I);
|
||||||
|
strncpy(Msg,Comment+I,CopySize);
|
||||||
|
Msg[CopySize]=0;
|
||||||
|
mprintf("%s",Msg);
|
||||||
|
}
|
||||||
|
mprintf("\n");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
#ifndef _RAR_CONSIO_
|
||||||
|
#define _RAR_CONSIO_
|
||||||
|
|
||||||
|
enum {ALARM_SOUND,ERROR_SOUND,QUESTION_SOUND};
|
||||||
|
|
||||||
|
enum PASSWORD_TYPE {PASSWORD_GLOBAL,PASSWORD_FILE,PASSWORD_ARCHIVE};
|
||||||
|
|
||||||
|
void InitConsoleOptions(MESSAGE_TYPE MsgStream,bool Sound);
|
||||||
|
|
||||||
|
#ifndef SILENT
|
||||||
|
void mprintf(const char *fmt,...);
|
||||||
|
void eprintf(const char *fmt,...);
|
||||||
|
void Alarm();
|
||||||
|
void GetPasswordText(char *Str,int MaxLength);
|
||||||
|
unsigned int GetKey();
|
||||||
|
bool GetPassword(PASSWORD_TYPE Type,const char *FileName,char *Password,int MaxLength);
|
||||||
|
int Ask(const char *AskStr);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
int KbdAnsi(char *Addr,int Size);
|
||||||
|
void OutComment(char *Comment,int Size);
|
||||||
|
|
||||||
|
#ifdef SILENT
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define mprintf(args...)
|
||||||
|
#define eprintf(args...)
|
||||||
|
#else
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
inline void mprintf(const char *fmt,...) {}
|
||||||
|
#else
|
||||||
|
inline void mprintf(const char *fmt,const char *a=NULL,const char *b=NULL) {}
|
||||||
|
#endif
|
||||||
|
inline void eprintf(const char *fmt,const char *a=NULL,const char *b=NULL) {}
|
||||||
|
inline void mprintf(const char *fmt,int b) {}
|
||||||
|
inline void eprintf(const char *fmt,int b) {}
|
||||||
|
inline void mprintf(const char *fmt,const char *a,int b) {}
|
||||||
|
inline void eprintf(const char *fmt,const char *a,int b) {}
|
||||||
|
#endif
|
||||||
|
inline void Alarm() {}
|
||||||
|
inline void GetPasswordText(char *Str,int MaxLength) {}
|
||||||
|
inline unsigned int GetKey() {return(0);}
|
||||||
|
inline bool GetPassword(PASSWORD_TYPE Type,const char *FileName,char *Password,int MaxLength) {return(false);}
|
||||||
|
inline int Ask(const char *AskStr) {return(0);}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
uint CRCTab[256];
|
||||||
|
|
||||||
|
void InitCRC()
|
||||||
|
{
|
||||||
|
for (int I=0;I<256;I++)
|
||||||
|
{
|
||||||
|
uint C=I;
|
||||||
|
for (int J=0;J<8;J++)
|
||||||
|
C=(C & 1) ? (C>>1)^0xEDB88320L : (C>>1);
|
||||||
|
CRCTab[I]=C;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint CRC(uint StartCRC,const void *Addr,uint Size)
|
||||||
|
{
|
||||||
|
if (CRCTab[1]==0)
|
||||||
|
InitCRC();
|
||||||
|
byte *Data=(byte *)Addr;
|
||||||
|
#if defined(LITTLE_ENDIAN) && defined(PRESENT_INT32) && defined(ALLOW_NOT_ALIGNED_INT)
|
||||||
|
while (Size>0 && ((long)Data & 7))
|
||||||
|
{
|
||||||
|
StartCRC=CRCTab[(byte)(StartCRC^Data[0])]^(StartCRC>>8);
|
||||||
|
Size--;
|
||||||
|
Data++;
|
||||||
|
}
|
||||||
|
while (Size>=8)
|
||||||
|
{
|
||||||
|
StartCRC^=*(uint32 *)Data;
|
||||||
|
StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
|
||||||
|
StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
|
||||||
|
StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
|
||||||
|
StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
|
||||||
|
StartCRC^=*(uint32 *)(Data+4);
|
||||||
|
StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
|
||||||
|
StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
|
||||||
|
StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
|
||||||
|
StartCRC=CRCTab[(byte)StartCRC]^(StartCRC>>8);
|
||||||
|
Data+=8;
|
||||||
|
Size-=8;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
for (uint I=0;I<Size;I++)
|
||||||
|
StartCRC=CRCTab[(byte)(StartCRC^Data[I])]^(StartCRC>>8);
|
||||||
|
return(StartCRC);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
ushort OldCRC(ushort StartCRC,const void *Addr,uint Size)
|
||||||
|
{
|
||||||
|
byte *Data=(byte *)Addr;
|
||||||
|
for (uint I=0;I<Size;I++)
|
||||||
|
{
|
||||||
|
StartCRC=(StartCRC+Data[I])&0xffff;
|
||||||
|
StartCRC=((StartCRC<<1)|(StartCRC>>15))&0xffff;
|
||||||
|
}
|
||||||
|
return(StartCRC);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef _RAR_CRC_
|
||||||
|
#define _RAR_CRC_
|
||||||
|
|
||||||
|
extern uint CRCTab[256];
|
||||||
|
|
||||||
|
void InitCRC();
|
||||||
|
uint CRC(uint StartCRC,const void *Addr,uint Size);
|
||||||
|
ushort OldCRC(ushort StartCRC,const void *Addr,uint Size);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,381 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
extern uint CRCTab[256];
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define NROUNDS 32
|
||||||
|
|
||||||
|
#define rol(x,n,xsize) (((x)<<(n)) | ((x)>>(xsize-(n))))
|
||||||
|
#define ror(x,n,xsize) (((x)>>(n)) | ((x)<<(xsize-(n))))
|
||||||
|
|
||||||
|
#define substLong(t) ( (uint)SubstTable[(uint)t&255] | \
|
||||||
|
((uint)SubstTable[(int)(t>> 8)&255]<< 8) | \
|
||||||
|
((uint)SubstTable[(int)(t>>16)&255]<<16) | \
|
||||||
|
((uint)SubstTable[(int)(t>>24)&255]<<24) )
|
||||||
|
|
||||||
|
CryptKeyCacheItem CryptData::Cache[4];
|
||||||
|
int CryptData::CachePos=0;
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
static byte InitSubstTable[256]={
|
||||||
|
215, 19,149, 35, 73,197,192,205,249, 28, 16,119, 48,221, 2, 42,
|
||||||
|
232, 1,177,233, 14, 88,219, 25,223,195,244, 90, 87,239,153,137,
|
||||||
|
255,199,147, 70, 92, 66,246, 13,216, 40, 62, 29,217,230, 86, 6,
|
||||||
|
71, 24,171,196,101,113,218,123, 93, 91,163,178,202, 67, 44,235,
|
||||||
|
107,250, 75,234, 49,167,125,211, 83,114,157,144, 32,193,143, 36,
|
||||||
|
158,124,247,187, 89,214,141, 47,121,228, 61,130,213,194,174,251,
|
||||||
|
97,110, 54,229,115, 57,152, 94,105,243,212, 55,209,245, 63, 11,
|
||||||
|
164,200, 31,156, 81,176,227, 21, 76, 99,139,188,127, 17,248, 51,
|
||||||
|
207,120,189,210, 8,226, 41, 72,183,203,135,165,166, 60, 98, 7,
|
||||||
|
122, 38,155,170, 69,172,252,238, 39,134, 59,128,236, 27,240, 80,
|
||||||
|
131, 3, 85,206,145, 79,154,142,159,220,201,133, 74, 64, 20,129,
|
||||||
|
224,185,138,103,173,182, 43, 34,254, 82,198,151,231,180, 58, 10,
|
||||||
|
118, 26,102, 12, 50,132, 22,191,136,111,162,179, 45, 4,148,108,
|
||||||
|
161, 56, 78,126,242,222, 15,175,146, 23, 33,241,181,190, 77,225,
|
||||||
|
0, 46,169,186, 68, 95,237, 65, 53,208,253,168, 9, 18,100, 52,
|
||||||
|
116,184,160, 96,109, 37, 30,106,140,104,150, 5,204,117,112, 84
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void CryptData::DecryptBlock(byte *Buf,int Size)
|
||||||
|
{
|
||||||
|
rin.blockDecrypt(Buf,Size,Buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
void CryptData::EncryptBlock20(byte *Buf)
|
||||||
|
{
|
||||||
|
uint A,B,C,D,T,TA,TB;
|
||||||
|
#if defined(BIG_ENDIAN) || !defined(PRESENT_INT32) || !defined(ALLOW_NOT_ALIGNED_INT)
|
||||||
|
A=((uint)Buf[0]|((uint)Buf[1]<<8)|((uint)Buf[2]<<16)|((uint)Buf[3]<<24))^Key[0];
|
||||||
|
B=((uint)Buf[4]|((uint)Buf[5]<<8)|((uint)Buf[6]<<16)|((uint)Buf[7]<<24))^Key[1];
|
||||||
|
C=((uint)Buf[8]|((uint)Buf[9]<<8)|((uint)Buf[10]<<16)|((uint)Buf[11]<<24))^Key[2];
|
||||||
|
D=((uint)Buf[12]|((uint)Buf[13]<<8)|((uint)Buf[14]<<16)|((uint)Buf[15]<<24))^Key[3];
|
||||||
|
#else
|
||||||
|
uint32 *BufPtr=(uint32 *)Buf;
|
||||||
|
A=BufPtr[0]^Key[0];
|
||||||
|
B=BufPtr[1]^Key[1];
|
||||||
|
C=BufPtr[2]^Key[2];
|
||||||
|
D=BufPtr[3]^Key[3];
|
||||||
|
#endif
|
||||||
|
for(int I=0;I<NROUNDS;I++)
|
||||||
|
{
|
||||||
|
T=((C+rol(D,11,32))^Key[I&3]);
|
||||||
|
TA=A^substLong(T);
|
||||||
|
T=((D^rol(C,17,32))+Key[I&3]);
|
||||||
|
TB=B^substLong(T);
|
||||||
|
A=C;
|
||||||
|
B=D;
|
||||||
|
C=TA;
|
||||||
|
D=TB;
|
||||||
|
}
|
||||||
|
#if defined(BIG_ENDIAN) || !defined(PRESENT_INT32) || !defined(ALLOW_NOT_ALIGNED_INT)
|
||||||
|
C^=Key[0];
|
||||||
|
Buf[0]=(byte)C;
|
||||||
|
Buf[1]=(byte)(C>>8);
|
||||||
|
Buf[2]=(byte)(C>>16);
|
||||||
|
Buf[3]=(byte)(C>>24);
|
||||||
|
D^=Key[1];
|
||||||
|
Buf[4]=(byte)D;
|
||||||
|
Buf[5]=(byte)(D>>8);
|
||||||
|
Buf[6]=(byte)(D>>16);
|
||||||
|
Buf[7]=(byte)(D>>24);
|
||||||
|
A^=Key[2];
|
||||||
|
Buf[8]=(byte)A;
|
||||||
|
Buf[9]=(byte)(A>>8);
|
||||||
|
Buf[10]=(byte)(A>>16);
|
||||||
|
Buf[11]=(byte)(A>>24);
|
||||||
|
B^=Key[3];
|
||||||
|
Buf[12]=(byte)B;
|
||||||
|
Buf[13]=(byte)(B>>8);
|
||||||
|
Buf[14]=(byte)(B>>16);
|
||||||
|
Buf[15]=(byte)(B>>24);
|
||||||
|
#else
|
||||||
|
BufPtr[0]=C^Key[0];
|
||||||
|
BufPtr[1]=D^Key[1];
|
||||||
|
BufPtr[2]=A^Key[2];
|
||||||
|
BufPtr[3]=B^Key[3];
|
||||||
|
#endif
|
||||||
|
UpdKeys(Buf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CryptData::DecryptBlock20(byte *Buf)
|
||||||
|
{
|
||||||
|
byte InBuf[16];
|
||||||
|
uint A,B,C,D,T,TA,TB;
|
||||||
|
#if defined(BIG_ENDIAN) || !defined(PRESENT_INT32) || !defined(ALLOW_NOT_ALIGNED_INT)
|
||||||
|
A=((uint)Buf[0]|((uint)Buf[1]<<8)|((uint)Buf[2]<<16)|((uint)Buf[3]<<24))^Key[0];
|
||||||
|
B=((uint)Buf[4]|((uint)Buf[5]<<8)|((uint)Buf[6]<<16)|((uint)Buf[7]<<24))^Key[1];
|
||||||
|
C=((uint)Buf[8]|((uint)Buf[9]<<8)|((uint)Buf[10]<<16)|((uint)Buf[11]<<24))^Key[2];
|
||||||
|
D=((uint)Buf[12]|((uint)Buf[13]<<8)|((uint)Buf[14]<<16)|((uint)Buf[15]<<24))^Key[3];
|
||||||
|
#else
|
||||||
|
uint32 *BufPtr=(uint32 *)Buf;
|
||||||
|
A=BufPtr[0]^Key[0];
|
||||||
|
B=BufPtr[1]^Key[1];
|
||||||
|
C=BufPtr[2]^Key[2];
|
||||||
|
D=BufPtr[3]^Key[3];
|
||||||
|
#endif
|
||||||
|
memcpy(InBuf,Buf,sizeof(InBuf));
|
||||||
|
for(int I=NROUNDS-1;I>=0;I--)
|
||||||
|
{
|
||||||
|
T=((C+rol(D,11,32))^Key[I&3]);
|
||||||
|
TA=A^substLong(T);
|
||||||
|
T=((D^rol(C,17,32))+Key[I&3]);
|
||||||
|
TB=B^substLong(T);
|
||||||
|
A=C;
|
||||||
|
B=D;
|
||||||
|
C=TA;
|
||||||
|
D=TB;
|
||||||
|
}
|
||||||
|
#if defined(BIG_ENDIAN) || !defined(PRESENT_INT32) || !defined(ALLOW_NOT_ALIGNED_INT)
|
||||||
|
C^=Key[0];
|
||||||
|
Buf[0]=(byte)C;
|
||||||
|
Buf[1]=(byte)(C>>8);
|
||||||
|
Buf[2]=(byte)(C>>16);
|
||||||
|
Buf[3]=(byte)(C>>24);
|
||||||
|
D^=Key[1];
|
||||||
|
Buf[4]=(byte)D;
|
||||||
|
Buf[5]=(byte)(D>>8);
|
||||||
|
Buf[6]=(byte)(D>>16);
|
||||||
|
Buf[7]=(byte)(D>>24);
|
||||||
|
A^=Key[2];
|
||||||
|
Buf[8]=(byte)A;
|
||||||
|
Buf[9]=(byte)(A>>8);
|
||||||
|
Buf[10]=(byte)(A>>16);
|
||||||
|
Buf[11]=(byte)(A>>24);
|
||||||
|
B^=Key[3];
|
||||||
|
Buf[12]=(byte)B;
|
||||||
|
Buf[13]=(byte)(B>>8);
|
||||||
|
Buf[14]=(byte)(B>>16);
|
||||||
|
Buf[15]=(byte)(B>>24);
|
||||||
|
#else
|
||||||
|
BufPtr[0]=C^Key[0];
|
||||||
|
BufPtr[1]=D^Key[1];
|
||||||
|
BufPtr[2]=A^Key[2];
|
||||||
|
BufPtr[3]=B^Key[3];
|
||||||
|
#endif
|
||||||
|
UpdKeys(InBuf);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CryptData::UpdKeys(byte *Buf)
|
||||||
|
{
|
||||||
|
for (int I=0;I<16;I+=4)
|
||||||
|
{
|
||||||
|
Key[0]^=CRCTab[Buf[I]];
|
||||||
|
Key[1]^=CRCTab[Buf[I+1]];
|
||||||
|
Key[2]^=CRCTab[Buf[I+2]];
|
||||||
|
Key[3]^=CRCTab[Buf[I+3]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CryptData::Swap(byte *Ch1,byte *Ch2)
|
||||||
|
{
|
||||||
|
byte Ch=*Ch1;
|
||||||
|
*Ch1=*Ch2;
|
||||||
|
*Ch2=Ch;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void CryptData::SetCryptKeys(char *Password,byte *Salt,bool Encrypt,bool OldOnly,bool HandsOffHash)
|
||||||
|
{
|
||||||
|
if (*Password==0)
|
||||||
|
return;
|
||||||
|
if (OldOnly)
|
||||||
|
{
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (CRCTab[1]==0)
|
||||||
|
InitCRC();
|
||||||
|
byte Psw[MAXPASSWORD];
|
||||||
|
SetOldKeys(Password);
|
||||||
|
Key[0]=0xD3A3B879L;
|
||||||
|
Key[1]=0x3F6D12F7L;
|
||||||
|
Key[2]=0x7515A235L;
|
||||||
|
Key[3]=0xA4E7F123L;
|
||||||
|
memset(Psw,0,sizeof(Psw));
|
||||||
|
#if defined(_WIN_32) && !defined(GUI)
|
||||||
|
CharToOemBuff(Password,(char*)Psw,strlen(Password));
|
||||||
|
#else
|
||||||
|
strncpy((char *)Psw,Password,MAXPASSWORD-1);
|
||||||
|
#endif
|
||||||
|
int PswLength=strlen(Password);
|
||||||
|
memcpy(SubstTable,InitSubstTable,sizeof(SubstTable));
|
||||||
|
for (int J=0;J<256;J++)
|
||||||
|
for (int I=0;I<PswLength;I+=2)
|
||||||
|
{
|
||||||
|
uint N1=(byte)CRCTab[(Psw[I]-J)&0xff];
|
||||||
|
uint N2=(byte)CRCTab[(Psw[I+1]+J)&0xff];
|
||||||
|
for (int K=1;N1!=N2;N1=(N1+1)&0xff,K++)
|
||||||
|
Swap(&SubstTable[N1],&SubstTable[(N1+I+K)&0xff]);
|
||||||
|
}
|
||||||
|
for (int I=0;I<PswLength;I+=16)
|
||||||
|
EncryptBlock20(&Psw[I]);
|
||||||
|
#endif
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Cached=false;
|
||||||
|
for (uint I=0;I<sizeof(Cache)/sizeof(Cache[0]);I++)
|
||||||
|
if (strcmp(Cache[I].Password,Password)==0 &&
|
||||||
|
(Salt==NULL && !Cache[I].SaltPresent || Salt!=NULL &&
|
||||||
|
Cache[I].SaltPresent && memcmp(Cache[I].Salt,Salt,SALT_SIZE)==0) &&
|
||||||
|
Cache[I].HandsOffHash==HandsOffHash)
|
||||||
|
{
|
||||||
|
memcpy(AESKey,Cache[I].AESKey,sizeof(AESKey));
|
||||||
|
memcpy(AESInit,Cache[I].AESInit,sizeof(AESInit));
|
||||||
|
Cached=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Cached)
|
||||||
|
{
|
||||||
|
wchar PswW[MAXPASSWORD];
|
||||||
|
CharToWide(Password,PswW,MAXPASSWORD-1);
|
||||||
|
PswW[MAXPASSWORD-1]=0;
|
||||||
|
byte RawPsw[2*MAXPASSWORD+SALT_SIZE];
|
||||||
|
WideToRaw(PswW,RawPsw);
|
||||||
|
int RawLength=2*strlenw(PswW);
|
||||||
|
if (Salt!=NULL)
|
||||||
|
{
|
||||||
|
memcpy(RawPsw+RawLength,Salt,SALT_SIZE);
|
||||||
|
RawLength+=SALT_SIZE;
|
||||||
|
}
|
||||||
|
hash_context c;
|
||||||
|
hash_initial(&c);
|
||||||
|
|
||||||
|
const int HashRounds=0x40000;
|
||||||
|
for (int I=0;I<HashRounds;I++)
|
||||||
|
{
|
||||||
|
hash_process( &c, RawPsw, RawLength, HandsOffHash);
|
||||||
|
byte PswNum[3];
|
||||||
|
PswNum[0]=(byte)I;
|
||||||
|
PswNum[1]=(byte)(I>>8);
|
||||||
|
PswNum[2]=(byte)(I>>16);
|
||||||
|
hash_process( &c, PswNum, 3, HandsOffHash);
|
||||||
|
if (I%(HashRounds/16)==0)
|
||||||
|
{
|
||||||
|
hash_context tempc=c;
|
||||||
|
uint32 digest[5];
|
||||||
|
hash_final( &tempc, digest, HandsOffHash);
|
||||||
|
AESInit[I/(HashRounds/16)]=(byte)digest[4];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
uint32 digest[5];
|
||||||
|
hash_final( &c, digest, HandsOffHash);
|
||||||
|
for (int I=0;I<4;I++)
|
||||||
|
for (int J=0;J<4;J++)
|
||||||
|
AESKey[I*4+J]=(byte)(digest[I]>>(J*8));
|
||||||
|
|
||||||
|
strcpy(Cache[CachePos].Password,Password);
|
||||||
|
if ((Cache[CachePos].SaltPresent=(Salt!=NULL))==true)
|
||||||
|
memcpy(Cache[CachePos].Salt,Salt,SALT_SIZE);
|
||||||
|
Cache[CachePos].HandsOffHash=HandsOffHash;
|
||||||
|
memcpy(Cache[CachePos].AESKey,AESKey,sizeof(AESKey));
|
||||||
|
memcpy(Cache[CachePos].AESInit,AESInit,sizeof(AESInit));
|
||||||
|
CachePos=(CachePos+1)%(sizeof(Cache)/sizeof(Cache[0]));
|
||||||
|
}
|
||||||
|
rin.init(Encrypt ? Rijndael::Encrypt : Rijndael::Decrypt,AESKey,AESInit);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
void CryptData::SetOldKeys(char *Password)
|
||||||
|
{
|
||||||
|
uint PswCRC=CRC(0xffffffff,Password,strlen(Password));
|
||||||
|
OldKey[0]=PswCRC&0xffff;
|
||||||
|
OldKey[1]=(PswCRC>>16)&0xffff;
|
||||||
|
OldKey[2]=OldKey[3]=0;
|
||||||
|
PN1=PN2=PN3=0;
|
||||||
|
byte Ch;
|
||||||
|
while ((Ch=*Password)!=0)
|
||||||
|
{
|
||||||
|
PN1+=Ch;
|
||||||
|
PN2^=Ch;
|
||||||
|
PN3+=Ch;
|
||||||
|
PN3=(byte)rol(PN3,1,8);
|
||||||
|
OldKey[2]^=Ch^CRCTab[Ch];
|
||||||
|
OldKey[3]+=Ch+(CRCTab[Ch]>>16);
|
||||||
|
Password++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CryptData::SetAV15Encryption()
|
||||||
|
{
|
||||||
|
OldKey[0]=0x4765;
|
||||||
|
OldKey[1]=0x9021;
|
||||||
|
OldKey[2]=0x7382;
|
||||||
|
OldKey[3]=0x5215;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CryptData::SetCmt13Encryption()
|
||||||
|
{
|
||||||
|
PN1=0;
|
||||||
|
PN2=7;
|
||||||
|
PN3=77;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CryptData::Crypt(byte *Data,uint Count,int Method)
|
||||||
|
{
|
||||||
|
if (Method==OLD_DECODE)
|
||||||
|
Decode13(Data,Count);
|
||||||
|
else
|
||||||
|
if (Method==OLD_ENCODE)
|
||||||
|
Encode13(Data,Count);
|
||||||
|
else
|
||||||
|
Crypt15(Data,Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CryptData::Encode13(byte *Data,uint Count)
|
||||||
|
{
|
||||||
|
while (Count--)
|
||||||
|
{
|
||||||
|
PN2+=PN3;
|
||||||
|
PN1+=PN2;
|
||||||
|
*Data+=PN1;
|
||||||
|
Data++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CryptData::Decode13(byte *Data,uint Count)
|
||||||
|
{
|
||||||
|
while (Count--)
|
||||||
|
{
|
||||||
|
PN2+=PN3;
|
||||||
|
PN1+=PN2;
|
||||||
|
*Data-=PN1;
|
||||||
|
Data++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CryptData::Crypt15(byte *Data,uint Count)
|
||||||
|
{
|
||||||
|
while (Count--)
|
||||||
|
{
|
||||||
|
OldKey[0]+=0x1234;
|
||||||
|
OldKey[1]^=CRCTab[(OldKey[0] & 0x1fe)>>1];
|
||||||
|
OldKey[2]-=CRCTab[(OldKey[0] & 0x1fe)>>1]>>16;
|
||||||
|
OldKey[0]^=OldKey[2];
|
||||||
|
OldKey[3]=ror(OldKey[3]&0xffff,1,16)^OldKey[1];
|
||||||
|
OldKey[3]=ror(OldKey[3]&0xffff,1,16);
|
||||||
|
OldKey[0]^=OldKey[3];
|
||||||
|
*Data^=(byte)(OldKey[0]>>8);
|
||||||
|
Data++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
#ifndef _RAR_CRYPT_
|
||||||
|
#define _RAR_CRYPT_
|
||||||
|
|
||||||
|
enum { OLD_DECODE=0,OLD_ENCODE=1,NEW_CRYPT=2 };
|
||||||
|
|
||||||
|
|
||||||
|
struct CryptKeyCacheItem
|
||||||
|
{
|
||||||
|
#ifndef _SFX_RTL_
|
||||||
|
CryptKeyCacheItem()
|
||||||
|
{
|
||||||
|
*Password=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
~CryptKeyCacheItem()
|
||||||
|
{
|
||||||
|
memset(AESKey,0,sizeof(AESKey));
|
||||||
|
memset(AESInit,0,sizeof(AESInit));
|
||||||
|
memset(Password,0,sizeof(Password));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
byte AESKey[16],AESInit[16];
|
||||||
|
char Password[MAXPASSWORD];
|
||||||
|
bool SaltPresent;
|
||||||
|
byte Salt[SALT_SIZE];
|
||||||
|
bool HandsOffHash;
|
||||||
|
};
|
||||||
|
|
||||||
|
class CryptData
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
void Encode13(byte *Data,uint Count);
|
||||||
|
void Decode13(byte *Data,uint Count);
|
||||||
|
void Crypt15(byte *Data,uint Count);
|
||||||
|
void UpdKeys(byte *Buf);
|
||||||
|
void Swap(byte *Ch1,byte *Ch2);
|
||||||
|
void SetOldKeys(char *Password);
|
||||||
|
|
||||||
|
Rijndael rin;
|
||||||
|
|
||||||
|
byte SubstTable[256];
|
||||||
|
uint Key[4];
|
||||||
|
ushort OldKey[4];
|
||||||
|
byte PN1,PN2,PN3;
|
||||||
|
|
||||||
|
byte AESKey[16],AESInit[16];
|
||||||
|
|
||||||
|
static CryptKeyCacheItem Cache[4];
|
||||||
|
static int CachePos;
|
||||||
|
public:
|
||||||
|
void SetCryptKeys(char *Password,byte *Salt,bool Encrypt,bool OldOnly,bool HandsOffHash);
|
||||||
|
void SetAV15Encryption();
|
||||||
|
void SetCmt13Encryption();
|
||||||
|
void EncryptBlock20(byte *Buf);
|
||||||
|
void DecryptBlock20(byte *Buf);
|
||||||
|
void EncryptBlock(byte *Buf,int Size);
|
||||||
|
void DecryptBlock(byte *Buf,int Size);
|
||||||
|
void Crypt(byte *Data,uint Count,int Method);
|
||||||
|
static void SetSalt(byte *Salt,int SaltSize);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,361 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
#include "dll.hpp"
|
||||||
|
|
||||||
|
static int RarErrorToDll(int ErrCode);
|
||||||
|
|
||||||
|
struct DataSet
|
||||||
|
{
|
||||||
|
CommandData Cmd;
|
||||||
|
CmdExtract Extract;
|
||||||
|
Archive Arc;
|
||||||
|
int OpenMode;
|
||||||
|
int HeaderSize;
|
||||||
|
|
||||||
|
DataSet():Arc(&Cmd) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
HANDLE PASCAL RAROpenArchive(struct RAROpenArchiveData *r)
|
||||||
|
{
|
||||||
|
RAROpenArchiveDataEx rx;
|
||||||
|
memset(&rx,0,sizeof(rx));
|
||||||
|
rx.ArcName=r->ArcName;
|
||||||
|
rx.OpenMode=r->OpenMode;
|
||||||
|
rx.CmtBuf=r->CmtBuf;
|
||||||
|
rx.CmtBufSize=r->CmtBufSize;
|
||||||
|
HANDLE hArc=RAROpenArchiveEx(&rx);
|
||||||
|
r->OpenResult=rx.OpenResult;
|
||||||
|
r->CmtSize=rx.CmtSize;
|
||||||
|
r->CmtState=rx.CmtState;
|
||||||
|
return(hArc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
HANDLE PASCAL RAROpenArchiveEx(struct RAROpenArchiveDataEx *r)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
r->OpenResult=0;
|
||||||
|
DataSet *Data=new DataSet;
|
||||||
|
Data->Cmd.DllError=0;
|
||||||
|
Data->OpenMode=r->OpenMode;
|
||||||
|
Data->Cmd.FileArgs->AddString("*");
|
||||||
|
|
||||||
|
char an[NM];
|
||||||
|
if (r->ArcName==NULL && r->ArcNameW!=NULL)
|
||||||
|
{
|
||||||
|
WideToChar(r->ArcNameW,an,NM);
|
||||||
|
r->ArcName=an;
|
||||||
|
}
|
||||||
|
|
||||||
|
Data->Cmd.AddArcName(r->ArcName,r->ArcNameW);
|
||||||
|
Data->Cmd.Overwrite=OVERWRITE_ALL;
|
||||||
|
Data->Cmd.VersionControl=1;
|
||||||
|
if (!Data->Arc.Open(r->ArcName,r->ArcNameW))
|
||||||
|
{
|
||||||
|
r->OpenResult=ERAR_EOPEN;
|
||||||
|
delete Data;
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
if (!Data->Arc.IsArchive(false))
|
||||||
|
{
|
||||||
|
r->OpenResult=Data->Cmd.DllError!=0 ? Data->Cmd.DllError:ERAR_BAD_ARCHIVE;
|
||||||
|
delete Data;
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
r->Flags=Data->Arc.NewMhd.Flags;
|
||||||
|
Array<byte> CmtData;
|
||||||
|
if (r->CmtBufSize!=0 && Data->Arc.GetComment(&CmtData,NULL))
|
||||||
|
{
|
||||||
|
r->Flags|=2;
|
||||||
|
int Size=CmtData.Size()+1;
|
||||||
|
r->CmtState=Size>r->CmtBufSize ? ERAR_SMALL_BUF:1;
|
||||||
|
r->CmtSize=Min(Size,r->CmtBufSize);
|
||||||
|
memcpy(r->CmtBuf,&CmtData[0],r->CmtSize-1);
|
||||||
|
if (Size<=r->CmtBufSize)
|
||||||
|
r->CmtBuf[r->CmtSize-1]=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
r->CmtState=r->CmtSize=0;
|
||||||
|
if (Data->Arc.Signed)
|
||||||
|
r->Flags|=0x20;
|
||||||
|
Data->Extract.ExtractArchiveInit(&Data->Cmd,Data->Arc);
|
||||||
|
return((HANDLE)Data);
|
||||||
|
}
|
||||||
|
catch (int ErrCode)
|
||||||
|
{
|
||||||
|
r->OpenResult=RarErrorToDll(ErrCode);
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PASCAL RARCloseArchive(HANDLE hArcData)
|
||||||
|
{
|
||||||
|
DataSet *Data=(DataSet *)hArcData;
|
||||||
|
bool Success=Data==NULL ? false:Data->Arc.Close();
|
||||||
|
delete Data;
|
||||||
|
return(Success ? 0:ERAR_ECLOSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PASCAL RARReadHeader(HANDLE hArcData,struct RARHeaderData *D)
|
||||||
|
{
|
||||||
|
DataSet *Data=(DataSet *)hArcData;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ((Data->HeaderSize=Data->Arc.SearchBlock(FILE_HEAD))<=0)
|
||||||
|
{
|
||||||
|
if (Data->Arc.Volume && Data->Arc.GetHeaderType()==ENDARC_HEAD &&
|
||||||
|
(Data->Arc.EndArcHead.Flags & EARC_NEXT_VOLUME))
|
||||||
|
if (MergeArchive(Data->Arc,NULL,false,'L'))
|
||||||
|
{
|
||||||
|
Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
|
||||||
|
return(RARReadHeader(hArcData,D));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return(ERAR_EOPEN);
|
||||||
|
return(Data->Arc.BrokenFileHeader ? ERAR_BAD_DATA:ERAR_END_ARCHIVE);
|
||||||
|
}
|
||||||
|
if (Data->OpenMode==RAR_OM_LIST && (Data->Arc.NewLhd.Flags & LHD_SPLIT_BEFORE))
|
||||||
|
{
|
||||||
|
int Code=RARProcessFile(hArcData,RAR_SKIP,NULL,NULL);
|
||||||
|
if (Code==0)
|
||||||
|
return(RARReadHeader(hArcData,D));
|
||||||
|
else
|
||||||
|
return(Code);
|
||||||
|
}
|
||||||
|
strncpy(D->ArcName,Data->Arc.FileName,sizeof(D->ArcName));
|
||||||
|
strncpy(D->FileName,Data->Arc.NewLhd.FileName,sizeof(D->FileName));
|
||||||
|
D->Flags=Data->Arc.NewLhd.Flags;
|
||||||
|
D->PackSize=Data->Arc.NewLhd.PackSize;
|
||||||
|
D->UnpSize=Data->Arc.NewLhd.UnpSize;
|
||||||
|
D->HostOS=Data->Arc.NewLhd.HostOS;
|
||||||
|
D->FileCRC=Data->Arc.NewLhd.FileCRC;
|
||||||
|
D->FileTime=Data->Arc.NewLhd.FileTime;
|
||||||
|
D->UnpVer=Data->Arc.NewLhd.UnpVer;
|
||||||
|
D->Method=Data->Arc.NewLhd.Method;
|
||||||
|
D->FileAttr=Data->Arc.NewLhd.FileAttr;
|
||||||
|
D->CmtSize=0;
|
||||||
|
D->CmtState=0;
|
||||||
|
}
|
||||||
|
catch (int ErrCode)
|
||||||
|
{
|
||||||
|
return(RarErrorToDll(ErrCode));
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PASCAL RARReadHeaderEx(HANDLE hArcData,struct RARHeaderDataEx *D)
|
||||||
|
{
|
||||||
|
DataSet *Data=(DataSet *)hArcData;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if ((Data->HeaderSize=Data->Arc.SearchBlock(FILE_HEAD))<=0)
|
||||||
|
{
|
||||||
|
if (Data->Arc.Volume && Data->Arc.GetHeaderType()==ENDARC_HEAD &&
|
||||||
|
(Data->Arc.EndArcHead.Flags & EARC_NEXT_VOLUME))
|
||||||
|
if (MergeArchive(Data->Arc,NULL,false,'L'))
|
||||||
|
{
|
||||||
|
Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
|
||||||
|
return(RARReadHeaderEx(hArcData,D));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return(ERAR_EOPEN);
|
||||||
|
return(Data->Arc.BrokenFileHeader ? ERAR_BAD_DATA:ERAR_END_ARCHIVE);
|
||||||
|
}
|
||||||
|
if (Data->OpenMode==RAR_OM_LIST && (Data->Arc.NewLhd.Flags & LHD_SPLIT_BEFORE))
|
||||||
|
{
|
||||||
|
int Code=RARProcessFile(hArcData,RAR_SKIP,NULL,NULL);
|
||||||
|
if (Code==0)
|
||||||
|
return(RARReadHeaderEx(hArcData,D));
|
||||||
|
else
|
||||||
|
return(Code);
|
||||||
|
}
|
||||||
|
strncpy(D->ArcName,Data->Arc.FileName,sizeof(D->ArcName));
|
||||||
|
if (*Data->Arc.FileNameW)
|
||||||
|
strncpyw(D->ArcNameW,Data->Arc.FileNameW,sizeof(D->ArcNameW));
|
||||||
|
else
|
||||||
|
CharToWide(Data->Arc.FileName,D->ArcNameW);
|
||||||
|
strncpy(D->FileName,Data->Arc.NewLhd.FileName,sizeof(D->FileName));
|
||||||
|
if (*Data->Arc.NewLhd.FileNameW)
|
||||||
|
strncpyw(D->FileNameW,Data->Arc.NewLhd.FileNameW,sizeof(D->FileNameW));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
char AnsiName[NM];
|
||||||
|
OemToChar(Data->Arc.NewLhd.FileName,AnsiName);
|
||||||
|
CharToWide(AnsiName,D->FileNameW);
|
||||||
|
#else
|
||||||
|
CharToWide(Data->Arc.NewLhd.FileName,D->FileNameW);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
D->Flags=Data->Arc.NewLhd.Flags;
|
||||||
|
D->PackSize=Data->Arc.NewLhd.PackSize;
|
||||||
|
D->PackSizeHigh=Data->Arc.NewLhd.HighPackSize;
|
||||||
|
D->UnpSize=Data->Arc.NewLhd.UnpSize;
|
||||||
|
D->UnpSizeHigh=Data->Arc.NewLhd.HighUnpSize;
|
||||||
|
D->HostOS=Data->Arc.NewLhd.HostOS;
|
||||||
|
D->FileCRC=Data->Arc.NewLhd.FileCRC;
|
||||||
|
D->FileTime=Data->Arc.NewLhd.FileTime;
|
||||||
|
D->UnpVer=Data->Arc.NewLhd.UnpVer;
|
||||||
|
D->Method=Data->Arc.NewLhd.Method;
|
||||||
|
D->FileAttr=Data->Arc.NewLhd.FileAttr;
|
||||||
|
D->CmtSize=0;
|
||||||
|
D->CmtState=0;
|
||||||
|
}
|
||||||
|
catch (int ErrCode)
|
||||||
|
{
|
||||||
|
return(RarErrorToDll(ErrCode));
|
||||||
|
}
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PASCAL ProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName,wchar *DestPathW,wchar *DestNameW)
|
||||||
|
{
|
||||||
|
DataSet *Data=(DataSet *)hArcData;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Data->Cmd.DllError=0;
|
||||||
|
if (Data->OpenMode==RAR_OM_LIST || Operation==RAR_SKIP && !Data->Arc.Solid)
|
||||||
|
{
|
||||||
|
if (/*Data->OpenMode==RAR_OM_LIST && */Data->Arc.Volume &&
|
||||||
|
Data->Arc.GetHeaderType()==FILE_HEAD &&
|
||||||
|
(Data->Arc.NewLhd.Flags & LHD_SPLIT_AFTER)!=0)
|
||||||
|
if (MergeArchive(Data->Arc,NULL,false,'L'))
|
||||||
|
{
|
||||||
|
Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return(ERAR_EOPEN);
|
||||||
|
Data->Arc.SeekToNext();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Data->Cmd.DllOpMode=Operation;
|
||||||
|
|
||||||
|
if (DestPath!=NULL || DestName!=NULL)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
OemToChar(NullToEmpty(DestPath),Data->Cmd.ExtrPath);
|
||||||
|
#else
|
||||||
|
strcpy(Data->Cmd.ExtrPath,NullToEmpty(DestPath));
|
||||||
|
#endif
|
||||||
|
AddEndSlash(Data->Cmd.ExtrPath);
|
||||||
|
#ifdef _WIN_32
|
||||||
|
OemToChar(NullToEmpty(DestName),Data->Cmd.DllDestName);
|
||||||
|
#else
|
||||||
|
strcpy(Data->Cmd.DllDestName,NullToEmpty(DestName));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*Data->Cmd.ExtrPath=0;
|
||||||
|
*Data->Cmd.DllDestName=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (DestPathW!=NULL || DestNameW!=NULL)
|
||||||
|
{
|
||||||
|
strncpyw(Data->Cmd.ExtrPathW,NullToEmpty(DestPathW),NM-2);
|
||||||
|
AddEndSlash(Data->Cmd.ExtrPathW);
|
||||||
|
strncpyw(Data->Cmd.DllDestNameW,NullToEmpty(DestNameW),NM-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*Data->Cmd.ExtrPathW=0;
|
||||||
|
*Data->Cmd.DllDestNameW=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
strcpy(Data->Cmd.Command,Operation==RAR_EXTRACT ? "X":"T");
|
||||||
|
Data->Cmd.Test=Operation!=RAR_EXTRACT;
|
||||||
|
bool Repeat=false;
|
||||||
|
Data->Extract.ExtractCurrentFile(&Data->Cmd,Data->Arc,Data->HeaderSize,Repeat);
|
||||||
|
|
||||||
|
while (Data->Arc.ReadHeader()!=0 && Data->Arc.GetHeaderType()==NEWSUB_HEAD)
|
||||||
|
{
|
||||||
|
Data->Extract.ExtractCurrentFile(&Data->Cmd,Data->Arc,Data->HeaderSize,Repeat);
|
||||||
|
Data->Arc.SeekToNext();
|
||||||
|
}
|
||||||
|
Data->Arc.Seek(Data->Arc.CurBlockPos,SEEK_SET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (int ErrCode)
|
||||||
|
{
|
||||||
|
return(RarErrorToDll(ErrCode));
|
||||||
|
}
|
||||||
|
return(Data->Cmd.DllError);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PASCAL RARProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName)
|
||||||
|
{
|
||||||
|
return(ProcessFile(hArcData,Operation,DestPath,DestName,NULL,NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PASCAL RARProcessFileW(HANDLE hArcData,int Operation,wchar *DestPath,wchar *DestName)
|
||||||
|
{
|
||||||
|
return(ProcessFile(hArcData,Operation,NULL,NULL,DestPath,DestName));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PASCAL RARSetChangeVolProc(HANDLE hArcData,CHANGEVOLPROC ChangeVolProc)
|
||||||
|
{
|
||||||
|
DataSet *Data=(DataSet *)hArcData;
|
||||||
|
Data->Cmd.ChangeVolProc=ChangeVolProc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PASCAL RARSetCallback(HANDLE hArcData,UNRARCALLBACK Callback,LONG UserData)
|
||||||
|
{
|
||||||
|
DataSet *Data=(DataSet *)hArcData;
|
||||||
|
Data->Cmd.Callback=Callback;
|
||||||
|
Data->Cmd.UserData=UserData;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PASCAL RARSetProcessDataProc(HANDLE hArcData,PROCESSDATAPROC ProcessDataProc)
|
||||||
|
{
|
||||||
|
DataSet *Data=(DataSet *)hArcData;
|
||||||
|
Data->Cmd.ProcessDataProc=ProcessDataProc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PASCAL RARSetPassword(HANDLE hArcData,char *Password)
|
||||||
|
{
|
||||||
|
DataSet *Data=(DataSet *)hArcData;
|
||||||
|
strncpy(Data->Cmd.Password,Password,sizeof(Data->Cmd.Password));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int PASCAL RARGetDllVersion()
|
||||||
|
{
|
||||||
|
return(RAR_DLL_VERSION);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int RarErrorToDll(int ErrCode)
|
||||||
|
{
|
||||||
|
switch(ErrCode)
|
||||||
|
{
|
||||||
|
case FATAL_ERROR:
|
||||||
|
return(ERAR_EREAD);
|
||||||
|
case CRC_ERROR:
|
||||||
|
return(ERAR_BAD_DATA);
|
||||||
|
case WRITE_ERROR:
|
||||||
|
return(ERAR_EWRITE);
|
||||||
|
case OPEN_ERROR:
|
||||||
|
return(ERAR_EOPEN);
|
||||||
|
case CREATE_ERROR:
|
||||||
|
return(ERAR_ECREATE);
|
||||||
|
case MEMORY_ERROR:
|
||||||
|
return(ERAR_NO_MEMORY);
|
||||||
|
case SUCCESS:
|
||||||
|
return(0);
|
||||||
|
default:
|
||||||
|
return(ERAR_UNKNOWN);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
EXPORTS
|
||||||
|
RAROpenArchive
|
||||||
|
RAROpenArchiveEx
|
||||||
|
RARCloseArchive
|
||||||
|
RARReadHeader
|
||||||
|
RARReadHeaderEx
|
||||||
|
RARProcessFile
|
||||||
|
RARSetCallback
|
||||||
|
RARSetChangeVolProc
|
||||||
|
RARSetProcessDataProc
|
||||||
|
RARSetPassword
|
||||||
|
RARGetDllVersion
|
||||||
@@ -0,0 +1,137 @@
|
|||||||
|
#ifndef _UNRAR_DLL_
|
||||||
|
#define _UNRAR_DLL_
|
||||||
|
|
||||||
|
#define ERAR_END_ARCHIVE 10
|
||||||
|
#define ERAR_NO_MEMORY 11
|
||||||
|
#define ERAR_BAD_DATA 12
|
||||||
|
#define ERAR_BAD_ARCHIVE 13
|
||||||
|
#define ERAR_UNKNOWN_FORMAT 14
|
||||||
|
#define ERAR_EOPEN 15
|
||||||
|
#define ERAR_ECREATE 16
|
||||||
|
#define ERAR_ECLOSE 17
|
||||||
|
#define ERAR_EREAD 18
|
||||||
|
#define ERAR_EWRITE 19
|
||||||
|
#define ERAR_SMALL_BUF 20
|
||||||
|
#define ERAR_UNKNOWN 21
|
||||||
|
|
||||||
|
#define RAR_OM_LIST 0
|
||||||
|
#define RAR_OM_EXTRACT 1
|
||||||
|
|
||||||
|
#define RAR_SKIP 0
|
||||||
|
#define RAR_TEST 1
|
||||||
|
#define RAR_EXTRACT 2
|
||||||
|
|
||||||
|
#define RAR_VOL_ASK 0
|
||||||
|
#define RAR_VOL_NOTIFY 1
|
||||||
|
|
||||||
|
#define RAR_DLL_VERSION 4
|
||||||
|
|
||||||
|
#ifdef _UNIX
|
||||||
|
#define CALLBACK
|
||||||
|
#define PASCAL
|
||||||
|
#define LONG long
|
||||||
|
#define HANDLE void *
|
||||||
|
#define UINT unsigned int
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct RARHeaderData
|
||||||
|
{
|
||||||
|
char ArcName[260];
|
||||||
|
char FileName[260];
|
||||||
|
unsigned int Flags;
|
||||||
|
unsigned int PackSize;
|
||||||
|
unsigned int UnpSize;
|
||||||
|
unsigned int HostOS;
|
||||||
|
unsigned int FileCRC;
|
||||||
|
unsigned int FileTime;
|
||||||
|
unsigned int UnpVer;
|
||||||
|
unsigned int Method;
|
||||||
|
unsigned int FileAttr;
|
||||||
|
char *CmtBuf;
|
||||||
|
unsigned int CmtBufSize;
|
||||||
|
unsigned int CmtSize;
|
||||||
|
unsigned int CmtState;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct RARHeaderDataEx
|
||||||
|
{
|
||||||
|
char ArcName[1024];
|
||||||
|
wchar_t ArcNameW[1024];
|
||||||
|
char FileName[1024];
|
||||||
|
wchar_t FileNameW[1024];
|
||||||
|
unsigned int Flags;
|
||||||
|
unsigned int PackSize;
|
||||||
|
unsigned int PackSizeHigh;
|
||||||
|
unsigned int UnpSize;
|
||||||
|
unsigned int UnpSizeHigh;
|
||||||
|
unsigned int HostOS;
|
||||||
|
unsigned int FileCRC;
|
||||||
|
unsigned int FileTime;
|
||||||
|
unsigned int UnpVer;
|
||||||
|
unsigned int Method;
|
||||||
|
unsigned int FileAttr;
|
||||||
|
char *CmtBuf;
|
||||||
|
unsigned int CmtBufSize;
|
||||||
|
unsigned int CmtSize;
|
||||||
|
unsigned int CmtState;
|
||||||
|
unsigned int Reserved[1024];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct RAROpenArchiveData
|
||||||
|
{
|
||||||
|
char *ArcName;
|
||||||
|
unsigned int OpenMode;
|
||||||
|
unsigned int OpenResult;
|
||||||
|
char *CmtBuf;
|
||||||
|
unsigned int CmtBufSize;
|
||||||
|
unsigned int CmtSize;
|
||||||
|
unsigned int CmtState;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RAROpenArchiveDataEx
|
||||||
|
{
|
||||||
|
char *ArcName;
|
||||||
|
wchar_t *ArcNameW;
|
||||||
|
unsigned int OpenMode;
|
||||||
|
unsigned int OpenResult;
|
||||||
|
char *CmtBuf;
|
||||||
|
unsigned int CmtBufSize;
|
||||||
|
unsigned int CmtSize;
|
||||||
|
unsigned int CmtState;
|
||||||
|
unsigned int Flags;
|
||||||
|
unsigned int Reserved[32];
|
||||||
|
};
|
||||||
|
|
||||||
|
enum UNRARCALLBACK_MESSAGES {
|
||||||
|
UCM_CHANGEVOLUME,UCM_PROCESSDATA,UCM_NEEDPASSWORD
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef int (CALLBACK *UNRARCALLBACK)(UINT msg,LONG UserData,LONG P1,LONG P2);
|
||||||
|
|
||||||
|
typedef int (PASCAL *CHANGEVOLPROC)(char *ArcName,int Mode);
|
||||||
|
typedef int (PASCAL *PROCESSDATAPROC)(unsigned char *Addr,int Size);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HANDLE PASCAL RAROpenArchive(struct RAROpenArchiveData *ArchiveData);
|
||||||
|
HANDLE PASCAL RAROpenArchiveEx(struct RAROpenArchiveDataEx *ArchiveData);
|
||||||
|
int PASCAL RARCloseArchive(HANDLE hArcData);
|
||||||
|
int PASCAL RARReadHeader(HANDLE hArcData,struct RARHeaderData *HeaderData);
|
||||||
|
int PASCAL RARReadHeaderEx(HANDLE hArcData,struct RARHeaderDataEx *HeaderData);
|
||||||
|
int PASCAL RARProcessFile(HANDLE hArcData,int Operation,char *DestPath,char *DestName);
|
||||||
|
int PASCAL RARProcessFileW(HANDLE hArcData,int Operation,wchar_t *DestPath,wchar_t *DestName);
|
||||||
|
void PASCAL RARSetCallback(HANDLE hArcData,UNRARCALLBACK Callback,LONG UserData);
|
||||||
|
void PASCAL RARSetChangeVolProc(HANDLE hArcData,CHANGEVOLPROC ChangeVolProc);
|
||||||
|
void PASCAL RARSetProcessDataProc(HANDLE hArcData,PROCESSDATAPROC ProcessDataProc);
|
||||||
|
void PASCAL RARSetPassword(HANDLE hArcData,char *Password);
|
||||||
|
int PASCAL RARGetDllVersion();
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
EncodeFileName::EncodeFileName()
|
||||||
|
{
|
||||||
|
Flags=0;
|
||||||
|
FlagBits=0;
|
||||||
|
FlagsPos=0;
|
||||||
|
DestSize=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void EncodeFileName::Decode(char *Name,byte *EncName,int EncSize,wchar *NameW,
|
||||||
|
int MaxDecSize)
|
||||||
|
{
|
||||||
|
int EncPos=0,DecPos=0;
|
||||||
|
byte HighByte=EncName[EncPos++];
|
||||||
|
while (EncPos<EncSize && DecPos<MaxDecSize)
|
||||||
|
{
|
||||||
|
if (FlagBits==0)
|
||||||
|
{
|
||||||
|
Flags=EncName[EncPos++];
|
||||||
|
FlagBits=8;
|
||||||
|
}
|
||||||
|
switch(Flags>>6)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
NameW[DecPos++]=EncName[EncPos++];
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
NameW[DecPos++]=EncName[EncPos++]+(HighByte<<8);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
NameW[DecPos++]=EncName[EncPos]+(EncName[EncPos+1]<<8);
|
||||||
|
EncPos+=2;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
{
|
||||||
|
int Length=EncName[EncPos++];
|
||||||
|
if (Length & 0x80)
|
||||||
|
{
|
||||||
|
byte Correction=EncName[EncPos++];
|
||||||
|
for (Length=(Length&0x7f)+2;Length>0 && DecPos<MaxDecSize;Length--,DecPos++)
|
||||||
|
NameW[DecPos]=((Name[DecPos]+Correction)&0xff)+(HighByte<<8);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
for (Length+=2;Length>0 && DecPos<MaxDecSize;Length--,DecPos++)
|
||||||
|
NameW[DecPos]=Name[DecPos];
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Flags<<=2;
|
||||||
|
FlagBits-=2;
|
||||||
|
}
|
||||||
|
NameW[DecPos<MaxDecSize ? DecPos:MaxDecSize-1]=0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
#ifndef _RAR_ENCNAME_
|
||||||
|
#define _RAR_ENCNAME_
|
||||||
|
|
||||||
|
class EncodeFileName
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
void AddFlags(int Value);
|
||||||
|
|
||||||
|
byte *EncName;
|
||||||
|
byte Flags;
|
||||||
|
int FlagBits;
|
||||||
|
int FlagsPos;
|
||||||
|
int DestSize;
|
||||||
|
public:
|
||||||
|
EncodeFileName();
|
||||||
|
int Encode(char *Name,wchar *NameW,byte *EncName);
|
||||||
|
void Decode(char *Name,byte *EncName,int EncSize,wchar *NameW,int MaxDecSize);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,374 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
static bool UserBreak;
|
||||||
|
|
||||||
|
ErrorHandler::ErrorHandler()
|
||||||
|
{
|
||||||
|
Clean();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::Clean()
|
||||||
|
{
|
||||||
|
ExitCode=SUCCESS;
|
||||||
|
ErrCount=0;
|
||||||
|
EnableBreak=true;
|
||||||
|
Silent=false;
|
||||||
|
DoShutdown=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::MemoryError()
|
||||||
|
{
|
||||||
|
MemoryErrorMsg();
|
||||||
|
Throw(MEMORY_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::OpenError(const char *FileName)
|
||||||
|
{
|
||||||
|
#ifndef SILENT
|
||||||
|
OpenErrorMsg(FileName);
|
||||||
|
Throw(OPEN_ERROR);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::CloseError(const char *FileName)
|
||||||
|
{
|
||||||
|
#ifndef SILENT
|
||||||
|
if (!UserBreak)
|
||||||
|
{
|
||||||
|
ErrMsg(NULL,St(MErrFClose),FileName);
|
||||||
|
SysErrMsg();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if !defined(SILENT) || defined(RARDLL)
|
||||||
|
Throw(FATAL_ERROR);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::ReadError(const char *FileName)
|
||||||
|
{
|
||||||
|
#ifndef SILENT
|
||||||
|
ReadErrorMsg(NULL,FileName);
|
||||||
|
#endif
|
||||||
|
#if !defined(SILENT) || defined(RARDLL)
|
||||||
|
Throw(FATAL_ERROR);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ErrorHandler::AskRepeatRead(const char *FileName)
|
||||||
|
{
|
||||||
|
#if !defined(SILENT) && !defined(SFX_MODULE) && !defined(_WIN_CE)
|
||||||
|
if (!Silent)
|
||||||
|
{
|
||||||
|
mprintf("\n");
|
||||||
|
Log(NULL,St(MErrRead),FileName);
|
||||||
|
return(Ask(St(MRetryAbort))==1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::WriteError(const char *ArcName,const char *FileName)
|
||||||
|
{
|
||||||
|
#ifndef SILENT
|
||||||
|
WriteErrorMsg(ArcName,FileName);
|
||||||
|
#endif
|
||||||
|
#if !defined(SILENT) || defined(RARDLL)
|
||||||
|
Throw(WRITE_ERROR);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN_32
|
||||||
|
void ErrorHandler::WriteErrorFAT(const char *FileName)
|
||||||
|
{
|
||||||
|
#if !defined(SILENT) && !defined(SFX_MODULE)
|
||||||
|
SysErrMsg();
|
||||||
|
ErrMsg(NULL,St(MNTFSRequired),FileName);
|
||||||
|
#endif
|
||||||
|
#if !defined(SILENT) && !defined(SFX_MODULE) || defined(RARDLL)
|
||||||
|
Throw(WRITE_ERROR);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool ErrorHandler::AskRepeatWrite(const char *FileName)
|
||||||
|
{
|
||||||
|
#if !defined(SILENT) && !defined(_WIN_CE)
|
||||||
|
if (!Silent)
|
||||||
|
{
|
||||||
|
mprintf("\n");
|
||||||
|
Log(NULL,St(MErrWrite),FileName);
|
||||||
|
return(Ask(St(MRetryAbort))==1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::SeekError(const char *FileName)
|
||||||
|
{
|
||||||
|
#ifndef SILENT
|
||||||
|
if (!UserBreak)
|
||||||
|
{
|
||||||
|
ErrMsg(NULL,St(MErrSeek),FileName);
|
||||||
|
SysErrMsg();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#if !defined(SILENT) || defined(RARDLL)
|
||||||
|
Throw(FATAL_ERROR);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::GeneralErrMsg(const char *Msg)
|
||||||
|
{
|
||||||
|
#ifndef SILENT
|
||||||
|
Log(NULL,"%s",Msg);
|
||||||
|
SysErrMsg();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::MemoryErrorMsg()
|
||||||
|
{
|
||||||
|
#ifndef SILENT
|
||||||
|
ErrMsg(NULL,St(MErrOutMem));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::OpenErrorMsg(const char *FileName)
|
||||||
|
{
|
||||||
|
OpenErrorMsg(NULL,FileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::OpenErrorMsg(const char *ArcName,const char *FileName)
|
||||||
|
{
|
||||||
|
#ifndef SILENT
|
||||||
|
Log(ArcName && *ArcName ? ArcName:NULL,St(MCannotOpen),FileName);
|
||||||
|
Alarm();
|
||||||
|
SysErrMsg();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::CreateErrorMsg(const char *FileName)
|
||||||
|
{
|
||||||
|
CreateErrorMsg(NULL,FileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::CreateErrorMsg(const char *ArcName,const char *FileName)
|
||||||
|
{
|
||||||
|
#ifndef SILENT
|
||||||
|
Log(ArcName && *ArcName ? ArcName:NULL,St(MCannotCreate),FileName);
|
||||||
|
Alarm();
|
||||||
|
#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE) && defined(MAXPATH)
|
||||||
|
if (GetLastError()==ERROR_PATH_NOT_FOUND)
|
||||||
|
{
|
||||||
|
int NameLength=strlen(FileName);
|
||||||
|
if (!IsFullPath(FileName))
|
||||||
|
{
|
||||||
|
char CurDir[NM];
|
||||||
|
GetCurrentDirectory(sizeof(CurDir),CurDir);
|
||||||
|
NameLength+=strlen(CurDir)+1;
|
||||||
|
}
|
||||||
|
if (NameLength>MAXPATH)
|
||||||
|
{
|
||||||
|
Log(ArcName && *ArcName ? ArcName:NULL,St(MMaxPathLimit),MAXPATH);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
SysErrMsg();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::ReadErrorMsg(const char *ArcName,const char *FileName)
|
||||||
|
{
|
||||||
|
#ifndef SILENT
|
||||||
|
ErrMsg(ArcName,St(MErrRead),FileName);
|
||||||
|
SysErrMsg();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::WriteErrorMsg(const char *ArcName,const char *FileName)
|
||||||
|
{
|
||||||
|
#ifndef SILENT
|
||||||
|
ErrMsg(ArcName,St(MErrWrite),FileName);
|
||||||
|
SysErrMsg();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::Exit(int ExitCode)
|
||||||
|
{
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
Alarm();
|
||||||
|
#endif
|
||||||
|
Throw(ExitCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef GUI
|
||||||
|
void ErrorHandler::ErrMsg(const char *ArcName,const char *fmt,...)
|
||||||
|
{
|
||||||
|
safebuf char Msg[NM+1024];
|
||||||
|
va_list argptr;
|
||||||
|
va_start(argptr,fmt);
|
||||||
|
vsprintf(Msg,fmt,argptr);
|
||||||
|
va_end(argptr);
|
||||||
|
#ifdef _WIN_32
|
||||||
|
if (UserBreak)
|
||||||
|
Sleep(5000);
|
||||||
|
#endif
|
||||||
|
Alarm();
|
||||||
|
if (*Msg)
|
||||||
|
{
|
||||||
|
Log(ArcName,"\n%s",Msg);
|
||||||
|
mprintf("\n%s\n",St(MProgAborted));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::SetErrorCode(int Code)
|
||||||
|
{
|
||||||
|
switch(Code)
|
||||||
|
{
|
||||||
|
case WARNING:
|
||||||
|
case USER_BREAK:
|
||||||
|
if (ExitCode==SUCCESS)
|
||||||
|
ExitCode=Code;
|
||||||
|
break;
|
||||||
|
case FATAL_ERROR:
|
||||||
|
if (ExitCode==SUCCESS || ExitCode==WARNING)
|
||||||
|
ExitCode=FATAL_ERROR;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ExitCode=Code;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ErrCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(GUI) && !defined(_SFX_RTL_)
|
||||||
|
#ifdef _WIN_32
|
||||||
|
BOOL __stdcall ProcessSignal(DWORD SigType)
|
||||||
|
#else
|
||||||
|
#if defined(__sun)
|
||||||
|
extern "C"
|
||||||
|
#endif
|
||||||
|
void _stdfunction ProcessSignal(int SigType)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
if (SigType==CTRL_LOGOFF_EVENT)
|
||||||
|
return(TRUE);
|
||||||
|
#endif
|
||||||
|
UserBreak=true;
|
||||||
|
mprintf(St(MBreak));
|
||||||
|
for (int I=0;!File::RemoveCreated() && I<3;I++)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
Sleep(100);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if defined(USE_RC) && !defined(SFX_MODULE) && !defined(_WIN_CE)
|
||||||
|
ExtRes.UnloadDLL();
|
||||||
|
#endif
|
||||||
|
exit(USER_BREAK);
|
||||||
|
#ifdef _WIN_32
|
||||||
|
return(TRUE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::SetSignalHandlers(bool Enable)
|
||||||
|
{
|
||||||
|
EnableBreak=Enable;
|
||||||
|
#if !defined(GUI) && !defined(_SFX_RTL_)
|
||||||
|
#ifdef _WIN_32
|
||||||
|
SetConsoleCtrlHandler(Enable ? ProcessSignal:NULL,TRUE);
|
||||||
|
// signal(SIGBREAK,Enable ? ProcessSignal:SIG_IGN);
|
||||||
|
#else
|
||||||
|
signal(SIGINT,Enable ? ProcessSignal:SIG_IGN);
|
||||||
|
signal(SIGTERM,Enable ? ProcessSignal:SIG_IGN);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::Throw(int Code)
|
||||||
|
{
|
||||||
|
if (Code==USER_BREAK && !EnableBreak)
|
||||||
|
return;
|
||||||
|
ErrHandler.SetErrorCode(Code);
|
||||||
|
#ifdef ALLOW_EXCEPTIONS
|
||||||
|
throw Code;
|
||||||
|
#else
|
||||||
|
File::RemoveCreated();
|
||||||
|
exit(Code);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ErrorHandler::SysErrMsg()
|
||||||
|
{
|
||||||
|
#if !defined(SFX_MODULE) && !defined(SILENT)
|
||||||
|
#ifdef _WIN_32
|
||||||
|
#define STRCHR strchr
|
||||||
|
#define ERRCHAR char
|
||||||
|
ERRCHAR *lpMsgBuf=NULL;
|
||||||
|
int ErrType=GetLastError();
|
||||||
|
if (ErrType!=0 && FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
|
||||||
|
NULL,ErrType,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
|
(LPTSTR)&lpMsgBuf,0,NULL))
|
||||||
|
{
|
||||||
|
ERRCHAR *CurMsg=lpMsgBuf;
|
||||||
|
while (CurMsg!=NULL)
|
||||||
|
{
|
||||||
|
while (*CurMsg=='\r' || *CurMsg=='\n')
|
||||||
|
CurMsg++;
|
||||||
|
if (*CurMsg==0)
|
||||||
|
break;
|
||||||
|
ERRCHAR *EndMsg=STRCHR(CurMsg,'\r');
|
||||||
|
if (EndMsg==NULL)
|
||||||
|
EndMsg=STRCHR(CurMsg,'\n');
|
||||||
|
if (EndMsg!=NULL)
|
||||||
|
{
|
||||||
|
*EndMsg=0;
|
||||||
|
EndMsg++;
|
||||||
|
}
|
||||||
|
Log(NULL,"\n%s",CurMsg);
|
||||||
|
CurMsg=EndMsg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
LocalFree( lpMsgBuf );
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_UNIX) || defined(_EMX)
|
||||||
|
char *err=strerror(errno);
|
||||||
|
if (err!=NULL)
|
||||||
|
Log(NULL,"\n%s",err);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
#ifndef _RAR_ERRHANDLER_
|
||||||
|
#define _RAR_ERRHANDLER_
|
||||||
|
|
||||||
|
#if (defined(GUI) || !defined(_WIN_32)) && !defined(SFX_MODULE) && !defined(_WIN_CE) || defined(RARDLL)
|
||||||
|
#define ALLOW_EXCEPTIONS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#define rarmalloc malloc
|
||||||
|
#define rarcalloc calloc
|
||||||
|
#define rarrealloc realloc
|
||||||
|
#define rarfree free
|
||||||
|
#define rarstrdup strdup
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
enum { SUCCESS,WARNING,FATAL_ERROR,CRC_ERROR,LOCK_ERROR,WRITE_ERROR,
|
||||||
|
OPEN_ERROR,USER_ERROR,MEMORY_ERROR,CREATE_ERROR,USER_BREAK=255};
|
||||||
|
|
||||||
|
class ErrorHandler
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
void ErrMsg(const char *ArcName,const char *fmt,...);
|
||||||
|
|
||||||
|
int ExitCode;
|
||||||
|
int ErrCount;
|
||||||
|
bool EnableBreak;
|
||||||
|
bool Silent;
|
||||||
|
bool DoShutdown;
|
||||||
|
public:
|
||||||
|
ErrorHandler();
|
||||||
|
void Clean();
|
||||||
|
void MemoryError();
|
||||||
|
void OpenError(const char *FileName);
|
||||||
|
void CloseError(const char *FileName);
|
||||||
|
void ReadError(const char *FileName);
|
||||||
|
bool AskRepeatRead(const char *FileName);
|
||||||
|
void WriteError(const char *ArcName,const char *FileName);
|
||||||
|
void WriteErrorFAT(const char *FileName);
|
||||||
|
bool AskRepeatWrite(const char *FileName);
|
||||||
|
void SeekError(const char *FileName);
|
||||||
|
void GeneralErrMsg(const char *Msg);
|
||||||
|
void MemoryErrorMsg();
|
||||||
|
void OpenErrorMsg(const char *FileName);
|
||||||
|
void OpenErrorMsg(const char *ArcName,const char *FileName);
|
||||||
|
void CreateErrorMsg(const char *FileName);
|
||||||
|
void CreateErrorMsg(const char *ArcName,const char *FileName);
|
||||||
|
void ReadErrorMsg(const char *ArcName,const char *FileName);
|
||||||
|
void WriteErrorMsg(const char *ArcName,const char *FileName);
|
||||||
|
void Exit(int ExitCode);
|
||||||
|
void SetErrorCode(int Code);
|
||||||
|
int GetErrorCode() {return(ExitCode);}
|
||||||
|
int GetErrorCount() {return(ErrCount);}
|
||||||
|
void SetSignalHandlers(bool Enable);
|
||||||
|
void Throw(int Code);
|
||||||
|
void SetSilent(bool Mode) {Silent=Mode;};
|
||||||
|
void SetShutdown(bool Mode) {DoShutdown=Mode;};
|
||||||
|
void SysErrMsg();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,76 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
#ifdef _WIN_32
|
||||||
|
#include "win32acl.cpp"
|
||||||
|
#include "win32stm.cpp"
|
||||||
|
#endif
|
||||||
|
#ifdef _BEOS
|
||||||
|
#include "beosea.cpp"
|
||||||
|
#endif
|
||||||
|
#if defined(_EMX) && !defined(_DJGPP)
|
||||||
|
#include "os2ea.cpp"
|
||||||
|
#endif
|
||||||
|
#ifdef _UNIX
|
||||||
|
#include "uowners.cpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
void SetExtraInfo(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW)
|
||||||
|
{
|
||||||
|
switch(Arc.SubBlockHead.SubType)
|
||||||
|
{
|
||||||
|
#if defined(_EMX) && !defined(_DJGPP)
|
||||||
|
case EA_HEAD:
|
||||||
|
if (Cmd->ProcessEA)
|
||||||
|
ExtractOS2EA(Arc,Name);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef _UNIX
|
||||||
|
case UO_HEAD:
|
||||||
|
if (Cmd->ProcessOwners)
|
||||||
|
ExtractUnixOwner(Arc,Name);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef _BEOS
|
||||||
|
case BEEA_HEAD:
|
||||||
|
if (Cmd->ProcessEA)
|
||||||
|
ExtractBeEA(Arc,Name);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
#ifdef _WIN_32
|
||||||
|
case NTACL_HEAD:
|
||||||
|
if (Cmd->ProcessOwners)
|
||||||
|
ExtractACL(Arc,Name,NameW);
|
||||||
|
break;
|
||||||
|
case STREAM_HEAD:
|
||||||
|
ExtractStreams(Arc,Name,NameW);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void SetExtraInfoNew(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW)
|
||||||
|
{
|
||||||
|
#if defined(_EMX) && !defined(_DJGPP)
|
||||||
|
if (Cmd->ProcessEA && Arc.SubHead.CmpName(SUBHEAD_TYPE_OS2EA))
|
||||||
|
ExtractOS2EANew(Arc,Name);
|
||||||
|
#endif
|
||||||
|
#ifdef _UNIX
|
||||||
|
if (Cmd->ProcessOwners && Arc.SubHead.CmpName(SUBHEAD_TYPE_UOWNER))
|
||||||
|
ExtractUnixOwnerNew(Arc,Name);
|
||||||
|
#endif
|
||||||
|
#ifdef _BEOS
|
||||||
|
if (Cmd->ProcessEA && Arc.SubHead.CmpName(SUBHEAD_TYPE_UOWNER))
|
||||||
|
ExtractUnixOwnerNew(Arc,Name);
|
||||||
|
#endif
|
||||||
|
#ifdef _WIN_32
|
||||||
|
if (Cmd->ProcessOwners && Arc.SubHead.CmpName(SUBHEAD_TYPE_ACL))
|
||||||
|
ExtractACLNew(Arc,Name,NameW);
|
||||||
|
if (Arc.SubHead.CmpName(SUBHEAD_TYPE_STREAM))
|
||||||
|
ExtractStreamsNew(Arc,Name,NameW);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef _RAR_EXTINFO_
|
||||||
|
#define _RAR_EXTINFO_
|
||||||
|
|
||||||
|
|
||||||
|
void SetExtraInfo(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW);
|
||||||
|
void SetExtraInfoNew(CommandData *Cmd,Archive &Arc,char *Name,wchar *NameW);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,854 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
CmdExtract::CmdExtract()
|
||||||
|
{
|
||||||
|
TotalFileCount=0;
|
||||||
|
*Password=0;
|
||||||
|
Unp=new Unpack(&DataIO);
|
||||||
|
Unp->Init(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
CmdExtract::~CmdExtract()
|
||||||
|
{
|
||||||
|
delete Unp;
|
||||||
|
memset(Password,0,sizeof(Password));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CmdExtract::DoExtract(CommandData *Cmd)
|
||||||
|
{
|
||||||
|
PasswordCancelled=false;
|
||||||
|
DataIO.SetCurrentCommand(*Cmd->Command);
|
||||||
|
|
||||||
|
struct FindData FD;
|
||||||
|
while (Cmd->GetArcName(ArcName,ArcNameW,sizeof(ArcName)))
|
||||||
|
if (FindFile::FastFind(ArcName,ArcNameW,&FD))
|
||||||
|
DataIO.TotalArcSize+=FD.Size;
|
||||||
|
Cmd->ArcNames->Rewind();
|
||||||
|
while (Cmd->GetArcName(ArcName,ArcNameW,sizeof(ArcName)))
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
char PrevCmdPassword[MAXPASSWORD];
|
||||||
|
strcpy(PrevCmdPassword,Cmd->Password);
|
||||||
|
|
||||||
|
EXTRACT_ARC_CODE Code=ExtractArchive(Cmd);
|
||||||
|
|
||||||
|
/*
|
||||||
|
restore Cmd->Password which could be changed in IsArchive() call
|
||||||
|
for next header encrypted archive
|
||||||
|
*/
|
||||||
|
strcpy(Cmd->Password,PrevCmdPassword);
|
||||||
|
|
||||||
|
if (Code!=EXTRACT_ARC_REPEAT)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (FindFile::FastFind(ArcName,ArcNameW,&FD))
|
||||||
|
DataIO.ProcessedArcSize+=FD.Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TotalFileCount==0 && *Cmd->Command!='I')
|
||||||
|
{
|
||||||
|
if (!PasswordCancelled)
|
||||||
|
{
|
||||||
|
mprintf(St(MExtrNoFiles));
|
||||||
|
}
|
||||||
|
ErrHandler.SetErrorCode(WARNING);
|
||||||
|
}
|
||||||
|
#ifndef GUI
|
||||||
|
else
|
||||||
|
if (!Cmd->DisableDone)
|
||||||
|
if (*Cmd->Command=='I')
|
||||||
|
mprintf(St(MDone));
|
||||||
|
else
|
||||||
|
if (ErrHandler.GetErrorCount()==0)
|
||||||
|
mprintf(St(MExtrAllOk));
|
||||||
|
else
|
||||||
|
mprintf(St(MExtrTotalErr),ErrHandler.GetErrorCount());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CmdExtract::ExtractArchiveInit(CommandData *Cmd,Archive &Arc)
|
||||||
|
{
|
||||||
|
DataIO.UnpArcSize=Arc.FileLength();
|
||||||
|
|
||||||
|
FileCount=0;
|
||||||
|
MatchedArgs=0;
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
FirstFile=true;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (*Cmd->Password!=0)
|
||||||
|
strcpy(Password,Cmd->Password);
|
||||||
|
PasswordAll=(*Cmd->Password!=0);
|
||||||
|
|
||||||
|
DataIO.UnpVolume=false;
|
||||||
|
|
||||||
|
PrevExtracted=false;
|
||||||
|
SignatureFound=false;
|
||||||
|
AllMatchesExact=true;
|
||||||
|
ReconstructDone=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EXTRACT_ARC_CODE CmdExtract::ExtractArchive(CommandData *Cmd)
|
||||||
|
{
|
||||||
|
Archive Arc(Cmd);
|
||||||
|
if (!Arc.WOpen(ArcName,ArcNameW))
|
||||||
|
{
|
||||||
|
ErrHandler.SetErrorCode(OPEN_ERROR);
|
||||||
|
return(EXTRACT_ARC_NEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Arc.IsArchive(true))
|
||||||
|
{
|
||||||
|
#ifndef GUI
|
||||||
|
mprintf(St(MNotRAR),ArcName);
|
||||||
|
#endif
|
||||||
|
if (CmpExt(ArcName,"rar"))
|
||||||
|
ErrHandler.SetErrorCode(WARNING);
|
||||||
|
return(EXTRACT_ARC_NEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Arc.IsOpened())
|
||||||
|
return(EXTRACT_ARC_NEXT);
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (Arc.Volume && Arc.NotFirstVolume)
|
||||||
|
{
|
||||||
|
char FirstVolName[NM];
|
||||||
|
|
||||||
|
VolNameToFirstName(ArcName,FirstVolName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING));
|
||||||
|
if (stricomp(ArcName,FirstVolName)!=0 && FileExist(FirstVolName) &&
|
||||||
|
Cmd->ArcNames->Search(FirstVolName,NULL,false))
|
||||||
|
return(EXTRACT_ARC_NEXT);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
ExtractArchiveInit(Cmd,Arc);
|
||||||
|
|
||||||
|
if (*Cmd->Command=='T' || *Cmd->Command=='I')
|
||||||
|
Cmd->Test=true;
|
||||||
|
|
||||||
|
#ifndef GUI
|
||||||
|
if (*Cmd->Command=='I')
|
||||||
|
Cmd->DisablePercentage=true;
|
||||||
|
else
|
||||||
|
if (Cmd->Test)
|
||||||
|
mprintf(St(MExtrTest),ArcName);
|
||||||
|
else
|
||||||
|
mprintf(St(MExtracting),ArcName);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Arc.ViewComment();
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
int Size=Arc.ReadHeader();
|
||||||
|
bool Repeat=false;
|
||||||
|
if (!ExtractCurrentFile(Cmd,Arc,Size,Repeat))
|
||||||
|
if (Repeat)
|
||||||
|
{
|
||||||
|
return(EXTRACT_ARC_REPEAT);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(EXTRACT_ARC_NEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CmdExtract::ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize,bool &Repeat)
|
||||||
|
{
|
||||||
|
char Command=*Cmd->Command;
|
||||||
|
if (HeaderSize<=0)
|
||||||
|
if (DataIO.UnpVolume)
|
||||||
|
{
|
||||||
|
#ifdef NOVOLUME
|
||||||
|
return(false);
|
||||||
|
#else
|
||||||
|
if (!MergeArchive(Arc,NULL,false,Command))
|
||||||
|
{
|
||||||
|
ErrHandler.SetErrorCode(WARNING);
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
SignatureFound=false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return(false);
|
||||||
|
int HeadType=Arc.GetHeaderType();
|
||||||
|
if (HeadType!=FILE_HEAD)
|
||||||
|
{
|
||||||
|
if (HeadType==AV_HEAD || HeadType==SIGN_HEAD)
|
||||||
|
SignatureFound=true;
|
||||||
|
#if !defined(SFX_MODULE) && !defined(_WIN_CE)
|
||||||
|
if (HeadType==SUB_HEAD && PrevExtracted)
|
||||||
|
SetExtraInfo(Cmd,Arc,DestFileName,*DestFileNameW ? DestFileNameW:NULL);
|
||||||
|
#endif
|
||||||
|
if (HeadType==NEWSUB_HEAD)
|
||||||
|
{
|
||||||
|
if (Arc.SubHead.CmpName(SUBHEAD_TYPE_AV))
|
||||||
|
SignatureFound=true;
|
||||||
|
#if !defined(NOSUBBLOCKS) && !defined(_WIN_CE)
|
||||||
|
if (PrevExtracted)
|
||||||
|
SetExtraInfoNew(Cmd,Arc,DestFileName,*DestFileNameW ? DestFileNameW:NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (HeadType==ENDARC_HEAD)
|
||||||
|
if (Arc.EndArcHead.Flags & EARC_NEXT_VOLUME)
|
||||||
|
{
|
||||||
|
#ifndef NOVOLUME
|
||||||
|
if (!MergeArchive(Arc,NULL,false,Command))
|
||||||
|
{
|
||||||
|
ErrHandler.SetErrorCode(WARNING);
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
SignatureFound=false;
|
||||||
|
#endif
|
||||||
|
Arc.Seek(Arc.CurBlockPos,SEEK_SET);
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return(false);
|
||||||
|
Arc.SeekToNext();
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
PrevExtracted=false;
|
||||||
|
|
||||||
|
if (SignatureFound ||
|
||||||
|
!Cmd->Recurse && MatchedArgs>=Cmd->FileArgs->ItemsCount() &&
|
||||||
|
AllMatchesExact)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
char ArcFileName[NM];
|
||||||
|
IntToExt(Arc.NewLhd.FileName,Arc.NewLhd.FileName);
|
||||||
|
strcpy(ArcFileName,Arc.NewLhd.FileName);
|
||||||
|
|
||||||
|
wchar ArcFileNameW[NM];
|
||||||
|
*ArcFileNameW=0;
|
||||||
|
|
||||||
|
int MatchType=MATCH_WILDSUBPATH;
|
||||||
|
|
||||||
|
bool EqualNames=false;
|
||||||
|
int MatchNumber=Cmd->IsProcessFile(Arc.NewLhd,&EqualNames,MatchType);
|
||||||
|
bool ExactMatch=MatchNumber!=0;
|
||||||
|
#if !defined(SFX_MODULE) && !defined(_WIN_CE)
|
||||||
|
if (Cmd->ExclPath==EXCL_BASEPATH)
|
||||||
|
{
|
||||||
|
*Cmd->ArcPath=0;
|
||||||
|
if (ExactMatch)
|
||||||
|
{
|
||||||
|
Cmd->FileArgs->Rewind();
|
||||||
|
if (Cmd->FileArgs->GetString(Cmd->ArcPath,NULL,sizeof(Cmd->ArcPath),MatchNumber-1))
|
||||||
|
*PointToName(Cmd->ArcPath)=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (ExactMatch && !EqualNames)
|
||||||
|
AllMatchesExact=false;
|
||||||
|
|
||||||
|
#ifdef UNICODE_SUPPORTED
|
||||||
|
bool WideName=(Arc.NewLhd.Flags & LHD_UNICODE) && UnicodeEnabled();
|
||||||
|
#else
|
||||||
|
bool WideName=false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _APPLE
|
||||||
|
if (WideName)
|
||||||
|
{
|
||||||
|
WideToUtf(Arc.NewLhd.FileNameW,ArcFileName,sizeof(ArcFileName));
|
||||||
|
WideName=false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
wchar *DestNameW=WideName ? DestFileNameW:NULL;
|
||||||
|
|
||||||
|
#ifdef UNICODE_SUPPORTED
|
||||||
|
if (WideName)
|
||||||
|
{
|
||||||
|
ConvertPath(Arc.NewLhd.FileNameW,ArcFileNameW);
|
||||||
|
char Name[NM];
|
||||||
|
if (WideToChar(ArcFileNameW,Name) && IsNameUsable(Name))
|
||||||
|
strcpy(ArcFileName,Name);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ConvertPath(ArcFileName,ArcFileName);
|
||||||
|
|
||||||
|
if (Arc.IsArcLabel())
|
||||||
|
return(true);
|
||||||
|
|
||||||
|
if (Arc.NewLhd.Flags & LHD_VERSION)
|
||||||
|
{
|
||||||
|
if (Cmd->VersionControl!=1 && !EqualNames)
|
||||||
|
{
|
||||||
|
if (Cmd->VersionControl==0)
|
||||||
|
ExactMatch=false;
|
||||||
|
int Version=ParseVersionFileName(ArcFileName,ArcFileNameW,false);
|
||||||
|
if (Cmd->VersionControl-1==Version)
|
||||||
|
ParseVersionFileName(ArcFileName,ArcFileNameW,true);
|
||||||
|
else
|
||||||
|
ExactMatch=false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (!Arc.IsArcDir() && Cmd->VersionControl>1)
|
||||||
|
ExactMatch=false;
|
||||||
|
|
||||||
|
Arc.ConvertAttributes();
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if ((Arc.NewLhd.Flags & (LHD_SPLIT_BEFORE/*|LHD_SOLID*/)) && FirstFile)
|
||||||
|
{
|
||||||
|
char CurVolName[NM];
|
||||||
|
strcpy(CurVolName,ArcName);
|
||||||
|
|
||||||
|
VolNameToFirstName(ArcName,ArcName,(Arc.NewMhd.Flags & MHD_NEWNUMBERING));
|
||||||
|
if (stricomp(ArcName,CurVolName)!=0 && FileExist(ArcName))
|
||||||
|
{
|
||||||
|
*ArcNameW=0;
|
||||||
|
Repeat=true;
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
#if !defined(RARDLL) && !defined(_WIN_CE)
|
||||||
|
if (!ReconstructDone)
|
||||||
|
{
|
||||||
|
ReconstructDone=true;
|
||||||
|
|
||||||
|
RecVolumes RecVol;
|
||||||
|
if (RecVol.Restore(Cmd,Arc.FileName,Arc.FileNameW,true))
|
||||||
|
{
|
||||||
|
Repeat=true;
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
strcpy(ArcName,CurVolName);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
DataIO.UnpVolume=(Arc.NewLhd.Flags & LHD_SPLIT_AFTER);
|
||||||
|
DataIO.NextVolumeMissing=false;
|
||||||
|
|
||||||
|
Arc.Seek(Arc.NextBlockPos-Arc.NewLhd.FullPackSize,SEEK_SET);
|
||||||
|
|
||||||
|
bool TestMode=false;
|
||||||
|
bool ExtrFile=false;
|
||||||
|
bool SkipSolid=false;
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (FirstFile && (ExactMatch || Arc.Solid) && (Arc.NewLhd.Flags & (LHD_SPLIT_BEFORE/*|LHD_SOLID*/))!=0)
|
||||||
|
{
|
||||||
|
if (ExactMatch)
|
||||||
|
{
|
||||||
|
Log(Arc.FileName,St(MUnpCannotMerge),ArcFileName);
|
||||||
|
#ifdef RARDLL
|
||||||
|
Cmd->DllError=ERAR_BAD_DATA;
|
||||||
|
#endif
|
||||||
|
ErrHandler.SetErrorCode(WARNING);
|
||||||
|
}
|
||||||
|
ExactMatch=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
FirstFile=false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (ExactMatch || (SkipSolid=Arc.Solid)!=0)
|
||||||
|
{
|
||||||
|
if (Arc.NewLhd.Flags & LHD_PASSWORD)
|
||||||
|
#ifndef RARDLL
|
||||||
|
if (*Password==0)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#ifdef RARDLL
|
||||||
|
if (*Cmd->Password==0)
|
||||||
|
if (Cmd->Callback==NULL ||
|
||||||
|
Cmd->Callback(UCM_NEEDPASSWORD,Cmd->UserData,(LONG)Cmd->Password,sizeof(Cmd->Password))==-1)
|
||||||
|
return(false);
|
||||||
|
strcpy(Password,Cmd->Password);
|
||||||
|
|
||||||
|
#else
|
||||||
|
if (!GetPassword(PASSWORD_FILE,ArcFileName,Password,sizeof(Password)))
|
||||||
|
{
|
||||||
|
PasswordCancelled=true;
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#if !defined(GUI) && !defined(SILENT)
|
||||||
|
else
|
||||||
|
if (!PasswordAll && (!Arc.Solid || Arc.NewLhd.UnpVer>=20 && (Arc.NewLhd.Flags & LHD_SOLID)==0))
|
||||||
|
{
|
||||||
|
eprintf(St(MUseCurPsw),ArcFileName);
|
||||||
|
switch(Cmd->AllYes ? 1:Ask(St(MYesNoAll)))
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
ErrHandler.Exit(USER_BREAK);
|
||||||
|
case 2:
|
||||||
|
if (!GetPassword(PASSWORD_FILE,ArcFileName,Password,sizeof(Password)))
|
||||||
|
{
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
PasswordAll=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (*Cmd->ExtrPath==0 && *Cmd->ExtrPathW!=0)
|
||||||
|
WideToChar(Cmd->ExtrPathW,DestFileName);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
strcpy(DestFileName,Cmd->ExtrPath);
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (Cmd->AppendArcNameToPath)
|
||||||
|
{
|
||||||
|
strcat(DestFileName,PointToName(Arc.FileName));
|
||||||
|
SetExt(DestFileName,NULL);
|
||||||
|
AddEndSlash(DestFileName);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char *ExtrName=ArcFileName;
|
||||||
|
|
||||||
|
bool EmptyName=false;
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
int Length=strlen(Cmd->ArcPath);
|
||||||
|
if (Length>1 && IsPathDiv(Cmd->ArcPath[Length-1]) &&
|
||||||
|
strlen(ArcFileName)==Length-1)
|
||||||
|
Length--;
|
||||||
|
if (Length>0 && strnicomp(Cmd->ArcPath,ArcFileName,Length)==0)
|
||||||
|
{
|
||||||
|
ExtrName+=Length;
|
||||||
|
while (*ExtrName==CPATHDIVIDER)
|
||||||
|
ExtrName++;
|
||||||
|
if (*ExtrName==0)
|
||||||
|
EmptyName=true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool AbsPaths=Cmd->ExclPath==EXCL_ABSPATH && Command=='X' && IsDriveDiv(':');
|
||||||
|
if (AbsPaths)
|
||||||
|
*DestFileName=0;
|
||||||
|
|
||||||
|
if (Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH)
|
||||||
|
strcat(DestFileName,PointToName(ExtrName));
|
||||||
|
else
|
||||||
|
strcat(DestFileName,ExtrName);
|
||||||
|
|
||||||
|
char DiskLetter=toupper(DestFileName[0]);
|
||||||
|
|
||||||
|
if (AbsPaths && DestFileName[1]=='_' && IsPathDiv(DestFileName[2]) &&
|
||||||
|
DiskLetter>='A' && DiskLetter<='Z')
|
||||||
|
DestFileName[1]=':';
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (!WideName && *Cmd->ExtrPathW!=0)
|
||||||
|
{
|
||||||
|
DestNameW=DestFileNameW;
|
||||||
|
WideName=true;
|
||||||
|
CharToWide(ArcFileName,ArcFileNameW);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (WideName)
|
||||||
|
{
|
||||||
|
if (*Cmd->ExtrPathW!=0)
|
||||||
|
strcpyw(DestFileNameW,Cmd->ExtrPathW);
|
||||||
|
else
|
||||||
|
CharToWide(Cmd->ExtrPath,DestFileNameW);
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (Cmd->AppendArcNameToPath)
|
||||||
|
{
|
||||||
|
wchar FileNameW[NM];
|
||||||
|
if (*Arc.FileNameW!=0)
|
||||||
|
strcpyw(FileNameW,Arc.FileNameW);
|
||||||
|
else
|
||||||
|
CharToWide(Arc.FileName,FileNameW);
|
||||||
|
strcatw(DestFileNameW,PointToName(FileNameW));
|
||||||
|
SetExt(DestFileNameW,NULL);
|
||||||
|
AddEndSlash(DestFileNameW);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
wchar *ExtrNameW=ArcFileNameW;
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (Length>0)
|
||||||
|
{
|
||||||
|
wchar ArcPathW[NM];
|
||||||
|
CharToWide(Cmd->ArcPath,ArcPathW);
|
||||||
|
Length=strlenw(ArcPathW);
|
||||||
|
}
|
||||||
|
ExtrNameW+=Length;
|
||||||
|
while (*ExtrNameW==CPATHDIVIDER)
|
||||||
|
ExtrNameW++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (AbsPaths)
|
||||||
|
*DestFileNameW=0;
|
||||||
|
|
||||||
|
if (Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH)
|
||||||
|
strcatw(DestFileNameW,PointToName(ExtrNameW));
|
||||||
|
else
|
||||||
|
strcatw(DestFileNameW,ExtrNameW);
|
||||||
|
|
||||||
|
if (AbsPaths && DestFileNameW[1]=='_' && IsPathDiv(DestFileNameW[2]))
|
||||||
|
DestFileNameW[1]=':';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*DestFileNameW=0;
|
||||||
|
|
||||||
|
ExtrFile=!SkipSolid && !EmptyName && (Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)==0/* && *ExtrName*/;
|
||||||
|
if ((Cmd->FreshFiles || Cmd->UpdateFiles) && (Command=='E' || Command=='X'))
|
||||||
|
{
|
||||||
|
struct FindData FD;
|
||||||
|
if (FindFile::FastFind(DestFileName,DestNameW,&FD))
|
||||||
|
{
|
||||||
|
if (FD.mtime >= Arc.NewLhd.mtime)
|
||||||
|
ExtrFile=false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (Cmd->FreshFiles)
|
||||||
|
ExtrFile=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef RARDLL
|
||||||
|
if (*Cmd->DllDestName)
|
||||||
|
{
|
||||||
|
strncpy(DestFileName,Cmd->DllDestName,sizeof(DestFileName));
|
||||||
|
*DestFileNameW=0;
|
||||||
|
if (Cmd->DllOpMode!=RAR_EXTRACT)
|
||||||
|
ExtrFile=false;
|
||||||
|
}
|
||||||
|
if (*Cmd->DllDestNameW)
|
||||||
|
{
|
||||||
|
strncpyw(DestFileNameW,Cmd->DllDestNameW,sizeof(DestFileNameW)/sizeof(DestFileNameW[0]));
|
||||||
|
DestNameW=DestFileNameW;
|
||||||
|
if (Cmd->DllOpMode!=RAR_EXTRACT)
|
||||||
|
ExtrFile=false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SFX_MODULE
|
||||||
|
if ((Arc.NewLhd.UnpVer!=UNP_VER && Arc.NewLhd.UnpVer!=29) &&
|
||||||
|
Arc.NewLhd.Method!=0x30)
|
||||||
|
#else
|
||||||
|
if (Arc.NewLhd.UnpVer<13 || Arc.NewLhd.UnpVer>UNP_VER)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#ifndef SILENT
|
||||||
|
Log(Arc.FileName,St(MUnknownMeth),ArcFileName);
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
Log(Arc.FileName,St(MVerRequired),Arc.NewLhd.UnpVer/10,Arc.NewLhd.UnpVer%10);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
ExtrFile=false;
|
||||||
|
ErrHandler.SetErrorCode(WARNING);
|
||||||
|
#ifdef RARDLL
|
||||||
|
Cmd->DllError=ERAR_UNKNOWN_FORMAT;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
File CurFile;
|
||||||
|
|
||||||
|
if (!IsLink(Arc.NewLhd.FileAttr))
|
||||||
|
if (Arc.IsArcDir())
|
||||||
|
{
|
||||||
|
if (!ExtrFile || Command=='P' || Command=='E' || Cmd->ExclPath==EXCL_SKIPWHOLEPATH)
|
||||||
|
return(true);
|
||||||
|
if (SkipSolid)
|
||||||
|
{
|
||||||
|
#ifndef GUI
|
||||||
|
mprintf(St(MExtrSkipFile),ArcFileName);
|
||||||
|
#endif
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
TotalFileCount++;
|
||||||
|
if (Cmd->Test)
|
||||||
|
{
|
||||||
|
#ifndef GUI
|
||||||
|
mprintf(St(MExtrTestFile),ArcFileName);
|
||||||
|
mprintf(" %s",St(MOk));
|
||||||
|
#endif
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
MKDIR_CODE MDCode=MakeDir(DestFileName,DestNameW,Arc.NewLhd.FileAttr);
|
||||||
|
bool DirExist=false;
|
||||||
|
if (MDCode!=MKDIR_SUCCESS)
|
||||||
|
{
|
||||||
|
DirExist=FileExist(DestFileName,DestNameW);
|
||||||
|
if (DirExist && !IsDir(GetFileAttr(DestFileName,DestNameW)))
|
||||||
|
{
|
||||||
|
bool UserReject;
|
||||||
|
FileCreate(Cmd,NULL,DestFileName,DestNameW,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime);
|
||||||
|
DirExist=false;
|
||||||
|
}
|
||||||
|
CreatePath(DestFileName,DestNameW,true);
|
||||||
|
MDCode=MakeDir(DestFileName,DestNameW,Arc.NewLhd.FileAttr);
|
||||||
|
}
|
||||||
|
if (MDCode==MKDIR_SUCCESS)
|
||||||
|
{
|
||||||
|
#ifndef GUI
|
||||||
|
mprintf(St(MCreatDir),DestFileName);
|
||||||
|
mprintf(" %s",St(MOk));
|
||||||
|
#endif
|
||||||
|
PrevExtracted=true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (DirExist)
|
||||||
|
{
|
||||||
|
SetFileAttr(DestFileName,DestNameW,Arc.NewLhd.FileAttr);
|
||||||
|
PrevExtracted=true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log(Arc.FileName,St(MExtrErrMkDir),DestFileName);
|
||||||
|
ErrHandler.SysErrMsg();
|
||||||
|
#ifdef RARDLL
|
||||||
|
Cmd->DllError=ERAR_ECREATE;
|
||||||
|
#endif
|
||||||
|
ErrHandler.SetErrorCode(CREATE_ERROR);
|
||||||
|
}
|
||||||
|
if (PrevExtracted)
|
||||||
|
{
|
||||||
|
#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE)
|
||||||
|
if (Cmd->SetCompressedAttr &&
|
||||||
|
(Arc.NewLhd.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT())
|
||||||
|
SetFileCompression(DestFileName,DestFileNameW,true);
|
||||||
|
#endif
|
||||||
|
SetDirTime(DestFileName,
|
||||||
|
Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime,
|
||||||
|
Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.NewLhd.ctime,
|
||||||
|
Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime);
|
||||||
|
}
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Cmd->Test && ExtrFile)
|
||||||
|
TestMode=true;
|
||||||
|
#if !defined(GUI) && !defined(SFX_MODULE)
|
||||||
|
if (Command=='P' && ExtrFile)
|
||||||
|
CurFile.SetHandleType(FILE_HANDLESTD);
|
||||||
|
#endif
|
||||||
|
if ((Command=='E' || Command=='X') && ExtrFile && !Cmd->Test)
|
||||||
|
{
|
||||||
|
bool UserReject;
|
||||||
|
if (!FileCreate(Cmd,&CurFile,DestFileName,DestNameW,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime))
|
||||||
|
{
|
||||||
|
ExtrFile=false;
|
||||||
|
if (!UserReject)
|
||||||
|
{
|
||||||
|
ErrHandler.CreateErrorMsg(Arc.FileName,DestFileName);
|
||||||
|
ErrHandler.SetErrorCode(CREATE_ERROR);
|
||||||
|
#ifdef RARDLL
|
||||||
|
Cmd->DllError=ERAR_ECREATE;
|
||||||
|
#endif
|
||||||
|
if (!IsNameUsable(DestFileName))
|
||||||
|
{
|
||||||
|
Log(Arc.FileName,St(MCorrectingName));
|
||||||
|
char OrigName[sizeof(DestFileName)];
|
||||||
|
strncpy(OrigName,DestFileName,sizeof(OrigName)-1);
|
||||||
|
OrigName[sizeof(OrigName)-1]=0;
|
||||||
|
|
||||||
|
MakeNameUsable(DestFileName,true);
|
||||||
|
CreatePath(DestFileName,NULL,true);
|
||||||
|
if (FileCreate(Cmd,&CurFile,DestFileName,NULL,Cmd->Overwrite,&UserReject,Arc.NewLhd.FullUnpSize,Arc.NewLhd.FileTime))
|
||||||
|
{
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
Log(Arc.FileName,St(MRenaming),OrigName,DestFileName);
|
||||||
|
#endif
|
||||||
|
ExtrFile=true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ErrHandler.CreateErrorMsg(Arc.FileName,DestFileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ExtrFile && Arc.Solid)
|
||||||
|
{
|
||||||
|
SkipSolid=true;
|
||||||
|
TestMode=true;
|
||||||
|
ExtrFile=true;
|
||||||
|
}
|
||||||
|
if (ExtrFile)
|
||||||
|
{
|
||||||
|
if (!SkipSolid)
|
||||||
|
{
|
||||||
|
if (!TestMode && Command!='P' && CurFile.IsDevice())
|
||||||
|
{
|
||||||
|
Log(Arc.FileName,St(MInvalidName),DestFileName);
|
||||||
|
ErrHandler.WriteError(Arc.FileName,DestFileName);
|
||||||
|
}
|
||||||
|
TotalFileCount++;
|
||||||
|
}
|
||||||
|
FileCount++;
|
||||||
|
#ifndef GUI
|
||||||
|
if (Command!='I')
|
||||||
|
if (SkipSolid)
|
||||||
|
mprintf(St(MExtrSkipFile),ArcFileName);
|
||||||
|
else
|
||||||
|
switch(Cmd->Test ? 'T':Command)
|
||||||
|
{
|
||||||
|
case 'T':
|
||||||
|
mprintf(St(MExtrTestFile),ArcFileName);
|
||||||
|
break;
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
case 'P':
|
||||||
|
mprintf(St(MExtrPrinting),ArcFileName);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case 'X':
|
||||||
|
case 'E':
|
||||||
|
mprintf(St(MExtrFile),DestFileName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!Cmd->DisablePercentage)
|
||||||
|
mprintf(" ");
|
||||||
|
#endif
|
||||||
|
DataIO.CurUnpRead=0;
|
||||||
|
DataIO.CurUnpWrite=0;
|
||||||
|
DataIO.UnpFileCRC=Arc.OldFormat ? 0 : 0xffffffff;
|
||||||
|
DataIO.PackedCRC=0xffffffff;
|
||||||
|
DataIO.SetEncryption(
|
||||||
|
(Arc.NewLhd.Flags & LHD_PASSWORD) ? Arc.NewLhd.UnpVer:0,Password,
|
||||||
|
(Arc.NewLhd.Flags & LHD_SALT) ? Arc.NewLhd.Salt:NULL,false,
|
||||||
|
Arc.NewLhd.UnpVer>=36);
|
||||||
|
DataIO.SetPackedSizeToRead(Arc.NewLhd.FullPackSize);
|
||||||
|
DataIO.SetFiles(&Arc,&CurFile);
|
||||||
|
DataIO.SetTestMode(TestMode);
|
||||||
|
DataIO.SetSkipUnpCRC(SkipSolid);
|
||||||
|
#ifndef _WIN_CE
|
||||||
|
if (!TestMode && !Arc.BrokenFileHeader &&
|
||||||
|
(Arc.NewLhd.FullPackSize<<11)>Arc.NewLhd.FullUnpSize &&
|
||||||
|
(Arc.NewLhd.FullUnpSize<100000000 || Arc.FileLength()>Arc.NewLhd.FullPackSize))
|
||||||
|
CurFile.Prealloc(Arc.NewLhd.FullUnpSize);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
CurFile.SetAllowDelete(!Cmd->KeepBroken);
|
||||||
|
|
||||||
|
bool LinkCreateMode=!Cmd->Test && !SkipSolid;
|
||||||
|
if (ExtractLink(DataIO,Arc,DestFileName,DataIO.UnpFileCRC,LinkCreateMode))
|
||||||
|
PrevExtracted=LinkCreateMode;
|
||||||
|
else
|
||||||
|
if ((Arc.NewLhd.Flags & LHD_SPLIT_BEFORE)==0)
|
||||||
|
if (Arc.NewLhd.Method==0x30)
|
||||||
|
UnstoreFile(DataIO,Arc.NewLhd.FullUnpSize);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Unp->SetDestSize(Arc.NewLhd.FullUnpSize);
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (Arc.NewLhd.UnpVer<=15)
|
||||||
|
Unp->DoUnpack(15,FileCount>1 && Arc.Solid);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
Unp->DoUnpack(Arc.NewLhd.UnpVer,Arc.NewLhd.Flags & LHD_SOLID);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Arc.IsOpened())
|
||||||
|
Arc.SeekToNext();
|
||||||
|
|
||||||
|
bool BrokenFile=false;
|
||||||
|
if (!SkipSolid)
|
||||||
|
{
|
||||||
|
if (Arc.OldFormat && UINT32(DataIO.UnpFileCRC)==UINT32(Arc.NewLhd.FileCRC) ||
|
||||||
|
!Arc.OldFormat && UINT32(DataIO.UnpFileCRC)==UINT32(Arc.NewLhd.FileCRC^0xffffffff))
|
||||||
|
{
|
||||||
|
#ifndef GUI
|
||||||
|
if (Command!='P' && Command!='I')
|
||||||
|
mprintf("%s%s ",Cmd->DisablePercentage ? " ":"\b\b\b\b\b ",St(MOk));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *BadArcName=/*(Arc.NewLhd.Flags & LHD_SPLIT_BEFORE) ? NULL:*/Arc.FileName;
|
||||||
|
if (Arc.NewLhd.Flags & LHD_PASSWORD)
|
||||||
|
{
|
||||||
|
Log(BadArcName,St(MEncrBadCRC),ArcFileName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log(BadArcName,St(MCRCFailed),ArcFileName);
|
||||||
|
}
|
||||||
|
BrokenFile=true;
|
||||||
|
ErrHandler.SetErrorCode(CRC_ERROR);
|
||||||
|
#ifdef RARDLL
|
||||||
|
Cmd->DllError=ERAR_BAD_DATA;
|
||||||
|
#endif
|
||||||
|
Alarm();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifndef GUI
|
||||||
|
else
|
||||||
|
mprintf("\b\b\b\b\b ");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!TestMode && (Command=='X' || Command=='E') &&
|
||||||
|
!IsLink(Arc.NewLhd.FileAttr))
|
||||||
|
{
|
||||||
|
#if defined(_WIN_32) || defined(_EMX)
|
||||||
|
if (Cmd->ClearArc)
|
||||||
|
Arc.NewLhd.FileAttr&=~FA_ARCH;
|
||||||
|
#endif
|
||||||
|
if (!BrokenFile || Cmd->KeepBroken)
|
||||||
|
{
|
||||||
|
if (BrokenFile)
|
||||||
|
CurFile.Truncate();
|
||||||
|
CurFile.SetOpenFileStat(
|
||||||
|
Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime,
|
||||||
|
Cmd->xctime==EXTTIME_NONE ? NULL:&Arc.NewLhd.ctime,
|
||||||
|
Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime);
|
||||||
|
CurFile.Close();
|
||||||
|
#if defined(_WIN_32) && !defined(_WIN_CE) && !defined(SFX_MODULE)
|
||||||
|
if (Cmd->SetCompressedAttr &&
|
||||||
|
(Arc.NewLhd.FileAttr & FILE_ATTRIBUTE_COMPRESSED)!=0 && WinNT())
|
||||||
|
SetFileCompression(CurFile.FileName,CurFile.FileNameW,true);
|
||||||
|
#endif
|
||||||
|
CurFile.SetCloseFileStat(
|
||||||
|
Cmd->xmtime==EXTTIME_NONE ? NULL:&Arc.NewLhd.mtime,
|
||||||
|
Cmd->xatime==EXTTIME_NONE ? NULL:&Arc.NewLhd.atime,
|
||||||
|
Arc.NewLhd.FileAttr);
|
||||||
|
PrevExtracted=true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ExactMatch)
|
||||||
|
MatchedArgs++;
|
||||||
|
if (DataIO.NextVolumeMissing || !Arc.IsOpened())
|
||||||
|
return(false);
|
||||||
|
if (!ExtrFile)
|
||||||
|
if (!Arc.Solid)
|
||||||
|
Arc.SeekToNext();
|
||||||
|
else
|
||||||
|
if (!SkipSolid)
|
||||||
|
return(false);
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CmdExtract::UnstoreFile(ComprDataIO &DataIO,Int64 DestUnpSize)
|
||||||
|
{
|
||||||
|
Array<byte> Buffer(0x10000);
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
unsigned int Code=DataIO.UnpRead(&Buffer[0],Buffer.Size());
|
||||||
|
if (Code==0 || (int)Code==-1)
|
||||||
|
break;
|
||||||
|
Code=Code<DestUnpSize ? Code:int64to32(DestUnpSize);
|
||||||
|
DataIO.UnpWrite(&Buffer[0],Code);
|
||||||
|
if (DestUnpSize>=0)
|
||||||
|
DestUnpSize-=Code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#ifndef _RAR_EXTRACT_
|
||||||
|
#define _RAR_EXTRACT_
|
||||||
|
|
||||||
|
enum EXTRACT_ARC_CODE {EXTRACT_ARC_NEXT,EXTRACT_ARC_REPEAT};
|
||||||
|
|
||||||
|
class CmdExtract
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
EXTRACT_ARC_CODE ExtractArchive(CommandData *Cmd);
|
||||||
|
|
||||||
|
ComprDataIO DataIO;
|
||||||
|
Unpack *Unp;
|
||||||
|
long TotalFileCount;
|
||||||
|
|
||||||
|
long FileCount;
|
||||||
|
long MatchedArgs;
|
||||||
|
bool FirstFile;
|
||||||
|
bool AllMatchesExact;
|
||||||
|
bool ReconstructDone;
|
||||||
|
|
||||||
|
char ArcName[NM];
|
||||||
|
wchar ArcNameW[NM];
|
||||||
|
|
||||||
|
char Password[MAXPASSWORD];
|
||||||
|
bool PasswordAll;
|
||||||
|
bool PrevExtracted;
|
||||||
|
bool SignatureFound;
|
||||||
|
char DestFileName[NM];
|
||||||
|
wchar DestFileNameW[NM];
|
||||||
|
bool PasswordCancelled;
|
||||||
|
public:
|
||||||
|
CmdExtract();
|
||||||
|
~CmdExtract();
|
||||||
|
void DoExtract(CommandData *Cmd);
|
||||||
|
void ExtractArchiveInit(CommandData *Cmd,Archive &Arc);
|
||||||
|
bool ExtractCurrentFile(CommandData *Cmd,Archive &Arc,int HeaderSize,
|
||||||
|
bool &Repeat);
|
||||||
|
static void UnstoreFile(ComprDataIO &DataIO,Int64 DestUnpSize);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,239 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
bool FileCreate(RAROptions *Cmd,File *NewFile,char *Name,wchar *NameW,
|
||||||
|
OVERWRITE_MODE Mode,bool *UserReject,Int64 FileSize,
|
||||||
|
uint FileTime)
|
||||||
|
{
|
||||||
|
if (UserReject!=NULL)
|
||||||
|
*UserReject=false;
|
||||||
|
#if defined(_WIN_32) && !defined(_WIN_CE)
|
||||||
|
bool ShortNameChanged=false;
|
||||||
|
#endif
|
||||||
|
while (FileExist(Name,NameW))
|
||||||
|
{
|
||||||
|
#if defined(_WIN_32) && !defined(_WIN_CE)
|
||||||
|
if (!ShortNameChanged)
|
||||||
|
{
|
||||||
|
ShortNameChanged=true;
|
||||||
|
if (UpdateExistingShortName(Name,NameW))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (Mode==OVERWRITE_NONE)
|
||||||
|
{
|
||||||
|
if (UserReject!=NULL)
|
||||||
|
*UserReject=true;
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
#ifdef SILENT
|
||||||
|
Mode=OVERWRITE_ALL;
|
||||||
|
#endif
|
||||||
|
if (Cmd->AllYes || Mode==OVERWRITE_ALL)
|
||||||
|
break;
|
||||||
|
if (Mode==OVERWRITE_ASK)
|
||||||
|
{
|
||||||
|
eprintf(St(MFileExists),Name);
|
||||||
|
int Choice=Ask(St(MYesNoAllRenQ));
|
||||||
|
if (Choice==1)
|
||||||
|
break;
|
||||||
|
if (Choice==2)
|
||||||
|
{
|
||||||
|
if (UserReject!=NULL)
|
||||||
|
*UserReject=true;
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
if (Choice==3)
|
||||||
|
{
|
||||||
|
Cmd->Overwrite=OVERWRITE_ALL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (Choice==4)
|
||||||
|
{
|
||||||
|
if (UserReject!=NULL)
|
||||||
|
*UserReject=true;
|
||||||
|
Cmd->Overwrite=OVERWRITE_NONE;
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
if (Choice==5)
|
||||||
|
{
|
||||||
|
mprintf(St(MAskNewName));
|
||||||
|
|
||||||
|
char NewName[NM];
|
||||||
|
#ifdef _WIN_32
|
||||||
|
File SrcFile;
|
||||||
|
SrcFile.SetHandleType(FILE_HANDLESTD);
|
||||||
|
int Size=SrcFile.Read(NewName,sizeof(NewName)-1);
|
||||||
|
NewName[Size]=0;
|
||||||
|
OemToChar(NewName,NewName);
|
||||||
|
#else
|
||||||
|
fgets(NewName,sizeof(NewName),stdin);
|
||||||
|
#endif
|
||||||
|
RemoveLF(NewName);
|
||||||
|
if (PointToName(NewName)==NewName)
|
||||||
|
strcpy(PointToName(Name),NewName);
|
||||||
|
else
|
||||||
|
strcpy(Name,NewName);
|
||||||
|
if (NameW!=NULL)
|
||||||
|
*NameW=0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (Choice==6)
|
||||||
|
ErrHandler.Exit(USER_BREAK);
|
||||||
|
}
|
||||||
|
if (Mode==OVERWRITE_AUTORENAME)
|
||||||
|
{
|
||||||
|
if (GetAutoRenamedName(Name))
|
||||||
|
{
|
||||||
|
if (NameW!=NULL)
|
||||||
|
*NameW=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Mode=OVERWRITE_ASK;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (NewFile!=NULL && NewFile->Create(Name,NameW))
|
||||||
|
return(true);
|
||||||
|
PrepareToDelete(Name,NameW);
|
||||||
|
CreatePath(Name,NameW,true);
|
||||||
|
return(NewFile!=NULL ? NewFile->Create(Name,NameW):DelFile(Name,NameW));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool GetAutoRenamedName(char *Name)
|
||||||
|
{
|
||||||
|
char NewName[NM];
|
||||||
|
|
||||||
|
if (strlen(Name)>sizeof(NewName)-10)
|
||||||
|
return(false);
|
||||||
|
char *Ext=GetExt(Name);
|
||||||
|
if (Ext==NULL)
|
||||||
|
Ext=Name+strlen(Name);
|
||||||
|
for (int FileVer=1;;FileVer++)
|
||||||
|
{
|
||||||
|
sprintf(NewName,"%.*s(%d)%s",Ext-Name,Name,FileVer,Ext);
|
||||||
|
if (!FileExist(NewName))
|
||||||
|
{
|
||||||
|
strcpy(Name,NewName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (FileVer>=1000000)
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_WIN_32) && !defined(_WIN_CE)
|
||||||
|
bool UpdateExistingShortName(char *Name,wchar *NameW)
|
||||||
|
{
|
||||||
|
FindData fd;
|
||||||
|
if (!FindFile::FastFind(Name,NameW,&fd))
|
||||||
|
return(false);
|
||||||
|
if (*fd.Name==0 || *fd.ShortName==0)
|
||||||
|
return(false);
|
||||||
|
if (stricomp(PointToName(fd.Name),fd.ShortName)==0 ||
|
||||||
|
stricomp(PointToName(Name),fd.ShortName)!=0)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
char NewName[NM];
|
||||||
|
for (int I=0;I<10000;I+=123)
|
||||||
|
{
|
||||||
|
strncpy(NewName,Name,sizeof(NewName));
|
||||||
|
sprintf(PointToName(NewName),"rtmp%d",I);
|
||||||
|
if (!FileExist(NewName))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (FileExist(NewName))
|
||||||
|
return(false);
|
||||||
|
char FullName[NM];
|
||||||
|
strncpy(FullName,Name,sizeof(FullName));
|
||||||
|
strcpy(PointToName(FullName),PointToName(fd.Name));
|
||||||
|
if (!MoveFile(FullName,NewName))
|
||||||
|
return(false);
|
||||||
|
File KeepShortFile;
|
||||||
|
bool Created=false;
|
||||||
|
if (!FileExist(Name))
|
||||||
|
Created=KeepShortFile.Create(Name);
|
||||||
|
MoveFile(NewName,FullName);
|
||||||
|
if (Created)
|
||||||
|
{
|
||||||
|
KeepShortFile.Close();
|
||||||
|
KeepShortFile.Delete();
|
||||||
|
}
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
bool UpdateExistingShortName(char *Name,wchar *NameW)
|
||||||
|
{
|
||||||
|
if (WinNT()<5)
|
||||||
|
return(false);
|
||||||
|
FindData fd;
|
||||||
|
if (!FindFile::FastFind(Name,NameW,&fd))
|
||||||
|
return(false);
|
||||||
|
if (*fd.Name==0 || *fd.ShortName==0)
|
||||||
|
return(false);
|
||||||
|
if (stricomp(PointToName(fd.Name),fd.ShortName)==0 ||
|
||||||
|
stricomp(PointToName(Name),fd.ShortName)!=0)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI *SETFILESHORTNAME)(HANDLE,LPCSTR);
|
||||||
|
static SETFILESHORTNAME pSetFileShortName=NULL;
|
||||||
|
if (pSetFileShortName==NULL)
|
||||||
|
{
|
||||||
|
HMODULE hKernel=GetModuleHandle("kernel32.dll");
|
||||||
|
if (hKernel!=NULL)
|
||||||
|
pSetFileShortName=(SETFILESHORTNAME)GetProcAddress(hKernel,"SetFileShortNameA");
|
||||||
|
if (pSetFileShortName==NULL)
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
static bool RestoreEnabled=false;
|
||||||
|
if (!RestoreEnabled)
|
||||||
|
{
|
||||||
|
HANDLE hToken;
|
||||||
|
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
TOKEN_PRIVILEGES tp;
|
||||||
|
tp.PrivilegeCount = 1;
|
||||||
|
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||||
|
|
||||||
|
if (LookupPrivilegeValue(NULL,SE_RESTORE_NAME,&tp.Privileges[0].Luid))
|
||||||
|
AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL);
|
||||||
|
|
||||||
|
CloseHandle(hToken);
|
||||||
|
RestoreEnabled=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
wchar FileNameW[NM];
|
||||||
|
GetWideName(Name,NameW,FileNameW);
|
||||||
|
HANDLE hFile=CreateFileW(FileNameW,GENERIC_WRITE|DELETE,FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
|
NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
|
||||||
|
if (hFile==INVALID_HANDLE_VALUE)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
bool RetCode=false;
|
||||||
|
|
||||||
|
char FullName[NM];
|
||||||
|
wchar FullNameW[NM];
|
||||||
|
strcpy(FullName,Name);
|
||||||
|
strcpyw(FullNameW,NullToEmpty(NameW));
|
||||||
|
for (int I=1;I<1000000;I++)
|
||||||
|
{
|
||||||
|
char NewName[NM];
|
||||||
|
sprintf(NewName,"NAME~%d.%d",I%1000,I/1000+1);
|
||||||
|
strcpy(PointToName(FullName),NewName);
|
||||||
|
if (*FullNameW)
|
||||||
|
CharToWide(NewName,PointToName(FullNameW));
|
||||||
|
if (!FileExist(FullName,FullNameW))
|
||||||
|
{
|
||||||
|
RetCode=pSetFileShortName(hFile,NewName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CloseHandle(hFile);
|
||||||
|
return(RetCode);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
#ifndef _RAR_FILECREATE_
|
||||||
|
#define _RAR_FILECREATE_
|
||||||
|
|
||||||
|
bool FileCreate(RAROptions *Cmd,File *NewFile,char *Name,wchar *NameW,
|
||||||
|
OVERWRITE_MODE Mode,bool *UserReject,Int64 FileSize=INT64ERR,
|
||||||
|
uint FileTime=0);
|
||||||
|
bool GetAutoRenamedName(char *Name);
|
||||||
|
|
||||||
|
#if defined(_WIN_32) && !defined(_WIN_CE)
|
||||||
|
bool UpdateExistingShortName(char *Name,wchar *NameW);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,702 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
static File *CreatedFiles[256];
|
||||||
|
static int RemoveCreatedActive=0;
|
||||||
|
|
||||||
|
File::File()
|
||||||
|
{
|
||||||
|
hFile=BAD_HANDLE;
|
||||||
|
*FileName=0;
|
||||||
|
*FileNameW=0;
|
||||||
|
NewFile=false;
|
||||||
|
LastWrite=false;
|
||||||
|
HandleType=FILE_HANDLENORMAL;
|
||||||
|
SkipClose=false;
|
||||||
|
IgnoreReadErrors=false;
|
||||||
|
ErrorType=FILE_SUCCESS;
|
||||||
|
OpenShared=false;
|
||||||
|
AllowDelete=true;
|
||||||
|
CloseCount=0;
|
||||||
|
AllowExceptions=true;
|
||||||
|
#ifdef _WIN_32
|
||||||
|
NoSequentialRead=false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
File::~File()
|
||||||
|
{
|
||||||
|
if (hFile!=BAD_HANDLE && !SkipClose)
|
||||||
|
if (NewFile)
|
||||||
|
Delete();
|
||||||
|
else
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void File::operator = (File &SrcFile)
|
||||||
|
{
|
||||||
|
hFile=SrcFile.hFile;
|
||||||
|
strcpy(FileName,SrcFile.FileName);
|
||||||
|
NewFile=SrcFile.NewFile;
|
||||||
|
LastWrite=SrcFile.LastWrite;
|
||||||
|
HandleType=SrcFile.HandleType;
|
||||||
|
SrcFile.SkipClose=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool File::Open(const char *Name,const wchar *NameW,bool OpenShared,bool Update)
|
||||||
|
{
|
||||||
|
ErrorType=FILE_SUCCESS;
|
||||||
|
FileHandle hNewFile;
|
||||||
|
if (File::OpenShared)
|
||||||
|
OpenShared=true;
|
||||||
|
#ifdef _WIN_32
|
||||||
|
uint Access=GENERIC_READ;
|
||||||
|
if (Update)
|
||||||
|
Access|=GENERIC_WRITE;
|
||||||
|
uint ShareMode=FILE_SHARE_READ;
|
||||||
|
if (OpenShared)
|
||||||
|
ShareMode|=FILE_SHARE_WRITE;
|
||||||
|
uint Flags=NoSequentialRead ? 0:FILE_FLAG_SEQUENTIAL_SCAN;
|
||||||
|
if (WinNT() && NameW!=NULL && *NameW!=0)
|
||||||
|
hNewFile=CreateFileW(NameW,Access,ShareMode,NULL,OPEN_EXISTING,Flags,NULL);
|
||||||
|
else
|
||||||
|
hNewFile=CreateFile(Name,Access,ShareMode,NULL,OPEN_EXISTING,Flags,NULL);
|
||||||
|
|
||||||
|
if (hNewFile==BAD_HANDLE && GetLastError()==ERROR_FILE_NOT_FOUND)
|
||||||
|
ErrorType=FILE_NOTFOUND;
|
||||||
|
#else
|
||||||
|
int flags=Update ? O_RDWR:O_RDONLY;
|
||||||
|
#ifdef O_BINARY
|
||||||
|
flags|=O_BINARY;
|
||||||
|
#if defined(_AIX) && defined(_LARGE_FILE_API)
|
||||||
|
flags|=O_LARGEFILE;
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#if defined(_EMX) && !defined(_DJGPP)
|
||||||
|
int sflags=OpenShared ? SH_DENYNO:SH_DENYWR;
|
||||||
|
int handle=sopen(Name,flags,sflags);
|
||||||
|
#else
|
||||||
|
int handle=open(Name,flags);
|
||||||
|
#ifdef LOCK_EX
|
||||||
|
|
||||||
|
#ifdef _OSF_SOURCE
|
||||||
|
extern "C" int flock(int, int);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef __HAIKU__
|
||||||
|
if (!OpenShared && Update && handle>=0 && flock(handle,LOCK_EX|LOCK_NB)==-1)
|
||||||
|
{
|
||||||
|
close(handle);
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
struct flock lock;
|
||||||
|
lock.l_type=LOCK_EX|LOCK_NB;
|
||||||
|
lock.l_whence=SEEK_SET;
|
||||||
|
lock.l_start=0;
|
||||||
|
lock.l_len=OFF_MAX;
|
||||||
|
if (!OpenShared && Update && handle>=0 && fcntl(handle,F_SETLK,&lock)==-1)
|
||||||
|
{
|
||||||
|
close(handle);
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
hNewFile=handle==-1 ? BAD_HANDLE:fdopen(handle,Update ? UPDATEBINARY:READBINARY);
|
||||||
|
if (hNewFile==BAD_HANDLE && errno==ENOENT)
|
||||||
|
ErrorType=FILE_NOTFOUND;
|
||||||
|
#endif
|
||||||
|
NewFile=false;
|
||||||
|
HandleType=FILE_HANDLENORMAL;
|
||||||
|
SkipClose=false;
|
||||||
|
bool Success=hNewFile!=BAD_HANDLE;
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
hFile=hNewFile;
|
||||||
|
if (NameW!=NULL)
|
||||||
|
strcpyw(FileNameW,NameW);
|
||||||
|
else
|
||||||
|
*FileNameW=0;
|
||||||
|
if (Name!=NULL)
|
||||||
|
strcpy(FileName,Name);
|
||||||
|
else
|
||||||
|
WideToChar(NameW,FileName);
|
||||||
|
AddFileToList(hFile);
|
||||||
|
}
|
||||||
|
return(Success);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(SHELL_EXT) && !defined(SFX_MODULE)
|
||||||
|
void File::TOpen(const char *Name,const wchar *NameW)
|
||||||
|
{
|
||||||
|
if (!WOpen(Name,NameW))
|
||||||
|
ErrHandler.Exit(OPEN_ERROR);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool File::WOpen(const char *Name,const wchar *NameW)
|
||||||
|
{
|
||||||
|
if (Open(Name,NameW))
|
||||||
|
return(true);
|
||||||
|
ErrHandler.OpenErrorMsg(Name);
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool File::Create(const char *Name,const wchar *NameW)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
if (WinNT() && NameW!=NULL && *NameW!=0)
|
||||||
|
hFile=CreateFileW(NameW,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,
|
||||||
|
CREATE_ALWAYS,0,NULL);
|
||||||
|
else
|
||||||
|
hFile=CreateFile(Name,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,NULL,
|
||||||
|
CREATE_ALWAYS,0,NULL);
|
||||||
|
#else
|
||||||
|
hFile=fopen(Name,CREATEBINARY);
|
||||||
|
#endif
|
||||||
|
NewFile=true;
|
||||||
|
HandleType=FILE_HANDLENORMAL;
|
||||||
|
SkipClose=false;
|
||||||
|
if (NameW!=NULL)
|
||||||
|
strcpyw(FileNameW,NameW);
|
||||||
|
else
|
||||||
|
*FileNameW=0;
|
||||||
|
if (Name!=NULL)
|
||||||
|
strcpy(FileName,Name);
|
||||||
|
else
|
||||||
|
WideToChar(NameW,FileName);
|
||||||
|
AddFileToList(hFile);
|
||||||
|
return(hFile!=BAD_HANDLE);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void File::AddFileToList(FileHandle hFile)
|
||||||
|
{
|
||||||
|
if (hFile!=BAD_HANDLE)
|
||||||
|
for (int I=0;I<sizeof(CreatedFiles)/sizeof(CreatedFiles[0]);I++)
|
||||||
|
if (CreatedFiles[I]==NULL)
|
||||||
|
{
|
||||||
|
CreatedFiles[I]=this;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(SHELL_EXT) && !defined(SFX_MODULE)
|
||||||
|
void File::TCreate(const char *Name,const wchar *NameW)
|
||||||
|
{
|
||||||
|
if (!WCreate(Name,NameW))
|
||||||
|
ErrHandler.Exit(FATAL_ERROR);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool File::WCreate(const char *Name,const wchar *NameW)
|
||||||
|
{
|
||||||
|
if (Create(Name,NameW))
|
||||||
|
return(true);
|
||||||
|
ErrHandler.SetErrorCode(CREATE_ERROR);
|
||||||
|
ErrHandler.CreateErrorMsg(Name);
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool File::Close()
|
||||||
|
{
|
||||||
|
bool Success=true;
|
||||||
|
if (HandleType!=FILE_HANDLENORMAL)
|
||||||
|
HandleType=FILE_HANDLENORMAL;
|
||||||
|
else
|
||||||
|
if (hFile!=BAD_HANDLE)
|
||||||
|
{
|
||||||
|
if (!SkipClose)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
Success=CloseHandle(hFile);
|
||||||
|
#else
|
||||||
|
Success=fclose(hFile)!=EOF;
|
||||||
|
#endif
|
||||||
|
if (Success || !RemoveCreatedActive)
|
||||||
|
for (int I=0;I<sizeof(CreatedFiles)/sizeof(CreatedFiles[0]);I++)
|
||||||
|
if (CreatedFiles[I]==this)
|
||||||
|
{
|
||||||
|
CreatedFiles[I]=NULL;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hFile=BAD_HANDLE;
|
||||||
|
if (!Success && AllowExceptions)
|
||||||
|
ErrHandler.CloseError(FileName);
|
||||||
|
}
|
||||||
|
CloseCount++;
|
||||||
|
return(Success);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void File::Flush()
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
FlushFileBuffers(hFile);
|
||||||
|
#else
|
||||||
|
fflush(hFile);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool File::Delete()
|
||||||
|
{
|
||||||
|
if (HandleType!=FILE_HANDLENORMAL || !AllowDelete)
|
||||||
|
return(false);
|
||||||
|
if (hFile!=BAD_HANDLE)
|
||||||
|
Close();
|
||||||
|
return(DelFile(FileName,FileNameW));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool File::Rename(const char *NewName)
|
||||||
|
{
|
||||||
|
bool Success=strcmp(FileName,NewName)==0;
|
||||||
|
if (!Success)
|
||||||
|
Success=rename(FileName,NewName)==0;
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
strcpy(FileName,NewName);
|
||||||
|
*FileNameW=0;
|
||||||
|
}
|
||||||
|
return(Success);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void File::Write(const void *Data,int Size)
|
||||||
|
{
|
||||||
|
if (Size==0)
|
||||||
|
return;
|
||||||
|
#ifndef _WIN_CE
|
||||||
|
if (HandleType!=FILE_HANDLENORMAL)
|
||||||
|
switch(HandleType)
|
||||||
|
{
|
||||||
|
case FILE_HANDLESTD:
|
||||||
|
#ifdef _WIN_32
|
||||||
|
hFile=GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
|
#else
|
||||||
|
hFile=stdout;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case FILE_HANDLEERR:
|
||||||
|
#ifdef _WIN_32
|
||||||
|
hFile=GetStdHandle(STD_ERROR_HANDLE);
|
||||||
|
#else
|
||||||
|
hFile=stderr;
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
bool Success;
|
||||||
|
#ifdef _WIN_32
|
||||||
|
DWORD Written;
|
||||||
|
if (HandleType!=FILE_HANDLENORMAL)
|
||||||
|
{
|
||||||
|
const int MaxSize=0x4000;
|
||||||
|
for (int I=0;I<Size;I+=MaxSize)
|
||||||
|
if (!(Success=WriteFile(hFile,(byte *)Data+I,Min(Size-I,MaxSize),&Written,NULL)))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Success=WriteFile(hFile,Data,Size,&Written,NULL);
|
||||||
|
#else
|
||||||
|
int Written=fwrite(Data,1,Size,hFile);
|
||||||
|
Success=Written==Size && !ferror(hFile);
|
||||||
|
#endif
|
||||||
|
if (!Success && AllowExceptions && HandleType==FILE_HANDLENORMAL)
|
||||||
|
{
|
||||||
|
#if defined(_WIN_32) && !defined(SFX_MODULE) && !defined(RARDLL)
|
||||||
|
int ErrCode=GetLastError();
|
||||||
|
Int64 FilePos=Tell();
|
||||||
|
Int64 FreeSize=GetFreeDisk(FileName);
|
||||||
|
SetLastError(ErrCode);
|
||||||
|
if (FreeSize>Size && FilePos-Size<=0xffffffff && FilePos+Size>0xffffffff)
|
||||||
|
ErrHandler.WriteErrorFAT(FileName);
|
||||||
|
#endif
|
||||||
|
if (ErrHandler.AskRepeatWrite(FileName))
|
||||||
|
{
|
||||||
|
#ifndef _WIN_32
|
||||||
|
clearerr(hFile);
|
||||||
|
#endif
|
||||||
|
if (Written<Size && Written>0)
|
||||||
|
Seek(Tell()-Written,SEEK_SET);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
ErrHandler.WriteError(NULL,FileName);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
LastWrite=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int File::Read(void *Data,int Size)
|
||||||
|
{
|
||||||
|
Int64 FilePos;
|
||||||
|
if (IgnoreReadErrors)
|
||||||
|
FilePos=Tell();
|
||||||
|
int ReadSize;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
ReadSize=DirectRead(Data,Size);
|
||||||
|
if (ReadSize==-1)
|
||||||
|
{
|
||||||
|
ErrorType=FILE_READERROR;
|
||||||
|
if (AllowExceptions)
|
||||||
|
if (IgnoreReadErrors)
|
||||||
|
{
|
||||||
|
ReadSize=0;
|
||||||
|
for (int I=0;I<Size;I+=512)
|
||||||
|
{
|
||||||
|
Seek(FilePos+I,SEEK_SET);
|
||||||
|
int SizeToRead=Min(Size-I,512);
|
||||||
|
int ReadCode=DirectRead(Data,SizeToRead);
|
||||||
|
ReadSize+=(ReadCode==-1) ? 512:ReadCode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (HandleType==FILE_HANDLENORMAL && ErrHandler.AskRepeatRead(FileName))
|
||||||
|
continue;
|
||||||
|
ErrHandler.ReadError(FileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return(ReadSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int File::DirectRead(void *Data,int Size)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
const int MaxDeviceRead=20000;
|
||||||
|
#endif
|
||||||
|
#ifndef _WIN_CE
|
||||||
|
if (HandleType==FILE_HANDLESTD)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
if (Size>MaxDeviceRead)
|
||||||
|
Size=MaxDeviceRead;
|
||||||
|
hFile=GetStdHandle(STD_INPUT_HANDLE);
|
||||||
|
#else
|
||||||
|
hFile=stdin;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#ifdef _WIN_32
|
||||||
|
DWORD Read;
|
||||||
|
if (!ReadFile(hFile,Data,Size,&Read,NULL))
|
||||||
|
{
|
||||||
|
if (IsDevice() && Size>MaxDeviceRead)
|
||||||
|
return(DirectRead(Data,MaxDeviceRead));
|
||||||
|
if (HandleType==FILE_HANDLESTD && GetLastError()==ERROR_BROKEN_PIPE)
|
||||||
|
return(0);
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
return(Read);
|
||||||
|
#else
|
||||||
|
if (LastWrite)
|
||||||
|
{
|
||||||
|
fflush(hFile);
|
||||||
|
LastWrite=false;
|
||||||
|
}
|
||||||
|
clearerr(hFile);
|
||||||
|
int ReadSize=fread(Data,1,Size,hFile);
|
||||||
|
if (ferror(hFile))
|
||||||
|
return(-1);
|
||||||
|
return(ReadSize);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void File::Seek(Int64 Offset,int Method)
|
||||||
|
{
|
||||||
|
if (!RawSeek(Offset,Method) && AllowExceptions)
|
||||||
|
ErrHandler.SeekError(FileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool File::RawSeek(Int64 Offset,int Method)
|
||||||
|
{
|
||||||
|
if (hFile==BAD_HANDLE)
|
||||||
|
return(true);
|
||||||
|
if (!is64plus(Offset) && Method!=SEEK_SET)
|
||||||
|
{
|
||||||
|
Offset=(Method==SEEK_CUR ? Tell():FileLength())+Offset;
|
||||||
|
Method=SEEK_SET;
|
||||||
|
}
|
||||||
|
#ifdef _WIN_32
|
||||||
|
LONG HighDist=int64to32(Offset>>32);
|
||||||
|
if (SetFilePointer(hFile,int64to32(Offset),&HighDist,Method)==0xffffffff &&
|
||||||
|
GetLastError()!=NO_ERROR)
|
||||||
|
return(false);
|
||||||
|
#else
|
||||||
|
LastWrite=false;
|
||||||
|
#if defined(_LARGEFILE_SOURCE) && !defined(_OSF_SOURCE) && !defined(__VMS)
|
||||||
|
if (fseeko(hFile,Offset,Method)!=0)
|
||||||
|
#else
|
||||||
|
if (fseek(hFile,(long)int64to32(Offset),Method)!=0)
|
||||||
|
#endif
|
||||||
|
return(false);
|
||||||
|
#endif
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int64 File::Tell()
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
LONG HighDist=0;
|
||||||
|
uint LowDist=SetFilePointer(hFile,0,&HighDist,FILE_CURRENT);
|
||||||
|
if (LowDist==0xffffffff && GetLastError()!=NO_ERROR)
|
||||||
|
if (AllowExceptions)
|
||||||
|
ErrHandler.SeekError(FileName);
|
||||||
|
else
|
||||||
|
return(-1);
|
||||||
|
return(int32to64(HighDist,LowDist));
|
||||||
|
#else
|
||||||
|
#if defined(_LARGEFILE_SOURCE) && !defined(_OSF_SOURCE)
|
||||||
|
return(ftello(hFile));
|
||||||
|
#else
|
||||||
|
return(ftell(hFile));
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void File::Prealloc(Int64 Size)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
if (RawSeek(Size,SEEK_SET))
|
||||||
|
{
|
||||||
|
Truncate();
|
||||||
|
Seek(0,SEEK_SET);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
byte File::GetByte()
|
||||||
|
{
|
||||||
|
byte Byte=0;
|
||||||
|
Read(&Byte,1);
|
||||||
|
return(Byte);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void File::PutByte(byte Byte)
|
||||||
|
{
|
||||||
|
Write(&Byte,1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool File::Truncate()
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
return(SetEndOfFile(hFile));
|
||||||
|
#else
|
||||||
|
return(false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void File::SetOpenFileTime(RarTime *ftm,RarTime *ftc,RarTime *fta)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
bool sm=ftm!=NULL && ftm->IsSet();
|
||||||
|
bool sc=ftc!=NULL && ftc->IsSet();
|
||||||
|
bool sa=fta!=NULL && fta->IsSet();
|
||||||
|
FILETIME fm,fc,fa;
|
||||||
|
if (sm)
|
||||||
|
ftm->GetWin32(&fm);
|
||||||
|
if (sc)
|
||||||
|
ftc->GetWin32(&fc);
|
||||||
|
if (sa)
|
||||||
|
fta->GetWin32(&fa);
|
||||||
|
SetFileTime(hFile,sc ? &fc:NULL,sa ? &fa:NULL,sm ? &fm:NULL);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void File::SetCloseFileTime(RarTime *ftm,RarTime *fta)
|
||||||
|
{
|
||||||
|
#if defined(_UNIX) || defined(_EMX)
|
||||||
|
SetCloseFileTimeByName(FileName,ftm,fta);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void File::SetCloseFileTimeByName(const char *Name,RarTime *ftm,RarTime *fta)
|
||||||
|
{
|
||||||
|
#if defined(_UNIX) || defined(_EMX)
|
||||||
|
bool setm=ftm!=NULL && ftm->IsSet();
|
||||||
|
bool seta=fta!=NULL && fta->IsSet();
|
||||||
|
if (setm || seta)
|
||||||
|
{
|
||||||
|
struct utimbuf ut;
|
||||||
|
if (setm)
|
||||||
|
ut.modtime=ftm->GetUnix();
|
||||||
|
else
|
||||||
|
ut.modtime=fta->GetUnix();
|
||||||
|
if (seta)
|
||||||
|
ut.actime=fta->GetUnix();
|
||||||
|
else
|
||||||
|
ut.actime=ut.modtime;
|
||||||
|
utime(Name,&ut);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void File::GetOpenFileTime(RarTime *ft)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
FILETIME FileTime;
|
||||||
|
GetFileTime(hFile,NULL,NULL,&FileTime);
|
||||||
|
*ft=FileTime;
|
||||||
|
#endif
|
||||||
|
#if defined(_UNIX) || defined(_EMX)
|
||||||
|
struct stat st;
|
||||||
|
fstat(fileno(hFile),&st);
|
||||||
|
*ft=st.st_mtime;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void File::SetOpenFileStat(RarTime *ftm,RarTime *ftc,RarTime *fta)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
SetOpenFileTime(ftm,ftc,fta);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void File::SetCloseFileStat(RarTime *ftm,RarTime *fta,uint FileAttr)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
SetFileAttr(FileName,FileNameW,FileAttr);
|
||||||
|
#endif
|
||||||
|
#ifdef _EMX
|
||||||
|
SetCloseFileTime(ftm,fta);
|
||||||
|
SetFileAttr(FileName,FileNameW,FileAttr);
|
||||||
|
#endif
|
||||||
|
#ifdef _UNIX
|
||||||
|
SetCloseFileTime(ftm,fta);
|
||||||
|
chmod(FileName,(mode_t)FileAttr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int64 File::FileLength()
|
||||||
|
{
|
||||||
|
SaveFilePos SavePos(*this);
|
||||||
|
Seek(0,SEEK_END);
|
||||||
|
return(Tell());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void File::SetHandleType(FILE_HANDLETYPE Type)
|
||||||
|
{
|
||||||
|
HandleType=Type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool File::IsDevice()
|
||||||
|
{
|
||||||
|
if (hFile==BAD_HANDLE)
|
||||||
|
return(false);
|
||||||
|
#ifdef _WIN_32
|
||||||
|
uint Type=GetFileType(hFile);
|
||||||
|
return(Type==FILE_TYPE_CHAR || Type==FILE_TYPE_PIPE);
|
||||||
|
#else
|
||||||
|
return(isatty(fileno(hFile)));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
void File::fprintf(const char *fmt,...)
|
||||||
|
{
|
||||||
|
va_list argptr;
|
||||||
|
va_start(argptr,fmt);
|
||||||
|
safebuf char Msg[2*NM+1024],OutMsg[2*NM+1024];
|
||||||
|
vsprintf(Msg,fmt,argptr);
|
||||||
|
#ifdef _WIN_32
|
||||||
|
for (int Src=0,Dest=0;;Src++)
|
||||||
|
{
|
||||||
|
char CurChar=Msg[Src];
|
||||||
|
if (CurChar=='\n')
|
||||||
|
OutMsg[Dest++]='\r';
|
||||||
|
OutMsg[Dest++]=CurChar;
|
||||||
|
if (CurChar==0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
strcpy(OutMsg,Msg);
|
||||||
|
#endif
|
||||||
|
Write(OutMsg,strlen(OutMsg));
|
||||||
|
va_end(argptr);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool File::RemoveCreated()
|
||||||
|
{
|
||||||
|
RemoveCreatedActive++;
|
||||||
|
bool RetCode=true;
|
||||||
|
for (int I=0;I<sizeof(CreatedFiles)/sizeof(CreatedFiles[0]);I++)
|
||||||
|
if (CreatedFiles[I]!=NULL)
|
||||||
|
{
|
||||||
|
CreatedFiles[I]->SetExceptions(false);
|
||||||
|
bool Success;
|
||||||
|
if (CreatedFiles[I]->NewFile)
|
||||||
|
Success=CreatedFiles[I]->Delete();
|
||||||
|
else
|
||||||
|
Success=CreatedFiles[I]->Close();
|
||||||
|
if (Success)
|
||||||
|
CreatedFiles[I]=NULL;
|
||||||
|
else
|
||||||
|
RetCode=false;
|
||||||
|
}
|
||||||
|
RemoveCreatedActive--;
|
||||||
|
return(RetCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
long File::Copy(File &Dest,Int64 Length)
|
||||||
|
{
|
||||||
|
Array<char> Buffer(0x10000);
|
||||||
|
long CopySize=0;
|
||||||
|
bool CopyAll=(Length==INT64ERR);
|
||||||
|
|
||||||
|
while (CopyAll || Length>0)
|
||||||
|
{
|
||||||
|
Wait();
|
||||||
|
int SizeToRead=(!CopyAll && Length<Buffer.Size()) ? int64to32(Length):Buffer.Size();
|
||||||
|
int ReadSize=Read(&Buffer[0],SizeToRead);
|
||||||
|
if (ReadSize==0)
|
||||||
|
break;
|
||||||
|
Dest.Write(&Buffer[0],ReadSize);
|
||||||
|
CopySize+=ReadSize;
|
||||||
|
if (!CopyAll)
|
||||||
|
Length-=ReadSize;
|
||||||
|
}
|
||||||
|
return(CopySize);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
#ifndef _RAR_FILE_
|
||||||
|
#define _RAR_FILE_
|
||||||
|
|
||||||
|
#ifdef _WIN_32
|
||||||
|
typedef HANDLE FileHandle;
|
||||||
|
#define BAD_HANDLE INVALID_HANDLE_VALUE
|
||||||
|
#else
|
||||||
|
typedef FILE* FileHandle;
|
||||||
|
#define BAD_HANDLE NULL
|
||||||
|
#endif
|
||||||
|
|
||||||
|
class RAROptions;
|
||||||
|
|
||||||
|
enum FILE_HANDLETYPE {FILE_HANDLENORMAL,FILE_HANDLESTD,FILE_HANDLEERR};
|
||||||
|
|
||||||
|
enum FILE_ERRORTYPE {FILE_SUCCESS,FILE_NOTFOUND,FILE_READERROR};
|
||||||
|
|
||||||
|
struct FileStat
|
||||||
|
{
|
||||||
|
uint FileAttr;
|
||||||
|
uint FileTime;
|
||||||
|
Int64 FileSize;
|
||||||
|
bool IsDir;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class File
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
void AddFileToList(FileHandle hFile);
|
||||||
|
|
||||||
|
FileHandle hFile;
|
||||||
|
bool LastWrite;
|
||||||
|
FILE_HANDLETYPE HandleType;
|
||||||
|
bool SkipClose;
|
||||||
|
bool IgnoreReadErrors;
|
||||||
|
bool NewFile;
|
||||||
|
bool AllowDelete;
|
||||||
|
bool AllowExceptions;
|
||||||
|
#ifdef _WIN_32
|
||||||
|
bool NoSequentialRead;
|
||||||
|
#endif
|
||||||
|
protected:
|
||||||
|
bool OpenShared;
|
||||||
|
public:
|
||||||
|
char FileName[NM];
|
||||||
|
wchar FileNameW[NM];
|
||||||
|
|
||||||
|
FILE_ERRORTYPE ErrorType;
|
||||||
|
|
||||||
|
uint CloseCount;
|
||||||
|
public:
|
||||||
|
File();
|
||||||
|
virtual ~File();
|
||||||
|
void operator = (File &SrcFile);
|
||||||
|
bool Open(const char *Name,const wchar *NameW=NULL,bool OpenShared=false,bool Update=false);
|
||||||
|
void TOpen(const char *Name,const wchar *NameW=NULL);
|
||||||
|
bool WOpen(const char *Name,const wchar *NameW=NULL);
|
||||||
|
bool Create(const char *Name,const wchar *NameW=NULL);
|
||||||
|
void TCreate(const char *Name,const wchar *NameW=NULL);
|
||||||
|
bool WCreate(const char *Name,const wchar *NameW=NULL);
|
||||||
|
bool Close();
|
||||||
|
void Flush();
|
||||||
|
bool Delete();
|
||||||
|
bool Rename(const char *NewName);
|
||||||
|
void Write(const void *Data,int Size);
|
||||||
|
int Read(void *Data,int Size);
|
||||||
|
int DirectRead(void *Data,int Size);
|
||||||
|
void Seek(Int64 Offset,int Method);
|
||||||
|
bool RawSeek(Int64 Offset,int Method);
|
||||||
|
Int64 Tell();
|
||||||
|
void Prealloc(Int64 Size);
|
||||||
|
byte GetByte();
|
||||||
|
void PutByte(byte Byte);
|
||||||
|
bool Truncate();
|
||||||
|
void SetOpenFileTime(RarTime *ftm,RarTime *ftc=NULL,RarTime *fta=NULL);
|
||||||
|
void SetCloseFileTime(RarTime *ftm,RarTime *fta=NULL);
|
||||||
|
static void SetCloseFileTimeByName(const char *Name,RarTime *ftm,RarTime *fta);
|
||||||
|
void SetOpenFileStat(RarTime *ftm,RarTime *ftc,RarTime *fta);
|
||||||
|
void SetCloseFileStat(RarTime *ftm,RarTime *fta,uint FileAttr);
|
||||||
|
void GetOpenFileTime(RarTime *ft);
|
||||||
|
bool IsOpened() {return(hFile!=BAD_HANDLE);};
|
||||||
|
Int64 FileLength();
|
||||||
|
void SetHandleType(FILE_HANDLETYPE Type);
|
||||||
|
FILE_HANDLETYPE GetHandleType() {return(HandleType);};
|
||||||
|
bool IsDevice();
|
||||||
|
void fprintf(const char *fmt,...);
|
||||||
|
static bool RemoveCreated();
|
||||||
|
FileHandle GetHandle() {return(hFile);};
|
||||||
|
void SetIgnoreReadErrors(bool Mode) {IgnoreReadErrors=Mode;};
|
||||||
|
char *GetName() {return(FileName);}
|
||||||
|
long Copy(File &Dest,Int64 Length=INT64ERR);
|
||||||
|
void SetAllowDelete(bool Allow) {AllowDelete=Allow;}
|
||||||
|
void SetExceptions(bool Allow) {AllowExceptions=Allow;}
|
||||||
|
#ifdef _WIN_32
|
||||||
|
void RemoveSequentialFlag() {NoSequentialRead=true;}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,542 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
MKDIR_CODE MakeDir(const char *Name,const wchar *NameW,uint Attr)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
int Success;
|
||||||
|
if (WinNT() && NameW!=NULL && *NameW!=0)
|
||||||
|
Success=CreateDirectoryW(NameW,NULL);
|
||||||
|
else
|
||||||
|
Success=CreateDirectory(Name,NULL);
|
||||||
|
if (Success)
|
||||||
|
{
|
||||||
|
SetFileAttr(Name,NameW,Attr);
|
||||||
|
return(MKDIR_SUCCESS);
|
||||||
|
}
|
||||||
|
int ErrCode=GetLastError();
|
||||||
|
if (ErrCode==ERROR_FILE_NOT_FOUND || ErrCode==ERROR_PATH_NOT_FOUND)
|
||||||
|
return(MKDIR_BADPATH);
|
||||||
|
return(MKDIR_ERROR);
|
||||||
|
#endif
|
||||||
|
#ifdef _EMX
|
||||||
|
#ifdef _DJGPP
|
||||||
|
if (mkdir(Name,(Attr & FA_RDONLY) ? 0:S_IWUSR)==0)
|
||||||
|
#else
|
||||||
|
if (__mkdir(Name)==0)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
SetFileAttr(Name,NameW,Attr);
|
||||||
|
return(MKDIR_SUCCESS);
|
||||||
|
}
|
||||||
|
return(errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR);
|
||||||
|
#endif
|
||||||
|
#ifdef _UNIX
|
||||||
|
int prevmask=umask(0);
|
||||||
|
int ErrCode=Name==NULL ? -1:mkdir(Name,(mode_t)Attr);
|
||||||
|
umask(prevmask);
|
||||||
|
if (ErrCode==-1)
|
||||||
|
return(errno==ENOENT ? MKDIR_BADPATH:MKDIR_ERROR);
|
||||||
|
return(MKDIR_SUCCESS);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CreatePath(const char *Path,const wchar *PathW,bool SkipLastName)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
uint DirAttr=0;
|
||||||
|
#else
|
||||||
|
uint DirAttr=0777;
|
||||||
|
#endif
|
||||||
|
#ifdef UNICODE_SUPPORTED
|
||||||
|
bool Wide=PathW!=NULL && *PathW!=0 && UnicodeEnabled();
|
||||||
|
#else
|
||||||
|
bool Wide=false;
|
||||||
|
#endif
|
||||||
|
bool IgnoreAscii=false;
|
||||||
|
|
||||||
|
const char *s=Path;
|
||||||
|
for (int PosW=0;;PosW++)
|
||||||
|
{
|
||||||
|
if (s==NULL || s-Path>=NM || *s==0)
|
||||||
|
IgnoreAscii=true;
|
||||||
|
if (Wide && (PosW>=NM || PathW[PosW]==0) || !Wide && IgnoreAscii)
|
||||||
|
break;
|
||||||
|
if (Wide && PathW[PosW]==CPATHDIVIDER || !Wide && *s==CPATHDIVIDER)
|
||||||
|
{
|
||||||
|
wchar *DirPtrW=NULL,DirNameW[NM];
|
||||||
|
if (Wide)
|
||||||
|
{
|
||||||
|
strncpyw(DirNameW,PathW,PosW);
|
||||||
|
DirNameW[PosW]=0;
|
||||||
|
DirPtrW=DirNameW;
|
||||||
|
}
|
||||||
|
char DirName[NM];
|
||||||
|
if (IgnoreAscii)
|
||||||
|
WideToChar(DirPtrW,DirName);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
#ifndef DBCS_SUPPORTED
|
||||||
|
if (*s!=CPATHDIVIDER)
|
||||||
|
for (const char *n=s;*n!=0 && n-Path<NM;n++)
|
||||||
|
if (*n==CPATHDIVIDER)
|
||||||
|
{
|
||||||
|
s=n;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
strncpy(DirName,Path,s-Path);
|
||||||
|
DirName[s-Path]=0;
|
||||||
|
}
|
||||||
|
if (MakeDir(DirName,DirPtrW,DirAttr)==MKDIR_SUCCESS)
|
||||||
|
{
|
||||||
|
#ifndef GUI
|
||||||
|
mprintf(St(MCreatDir),DirName);
|
||||||
|
mprintf(" %s",St(MOk));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!IgnoreAscii)
|
||||||
|
s=charnext(s);
|
||||||
|
}
|
||||||
|
if (!SkipLastName && !IsPathDiv(*PointToLastChar(Path)))
|
||||||
|
MakeDir(Path,PathW,DirAttr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SetDirTime(const char *Name,RarTime *ftm,RarTime *ftc,RarTime *fta)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
if (!WinNT())
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool sm=ftm!=NULL && ftm->IsSet();
|
||||||
|
bool sc=ftc!=NULL && ftc->IsSet();
|
||||||
|
bool sa=fta!=NULL && fta->IsSet();
|
||||||
|
|
||||||
|
unsigned int DirAttr=GetFileAttr(Name);
|
||||||
|
bool ResetAttr=(DirAttr!=0xffffffff && (DirAttr & FA_RDONLY)!=0);
|
||||||
|
if (ResetAttr)
|
||||||
|
SetFileAttr(Name,NULL,0);
|
||||||
|
HANDLE hFile=CreateFile(Name,GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||||
|
NULL,OPEN_EXISTING,FILE_FLAG_BACKUP_SEMANTICS,NULL);
|
||||||
|
if (hFile==INVALID_HANDLE_VALUE)
|
||||||
|
return;
|
||||||
|
FILETIME fm,fc,fa;
|
||||||
|
if (sm)
|
||||||
|
ftm->GetWin32(&fm);
|
||||||
|
if (sc)
|
||||||
|
ftc->GetWin32(&fc);
|
||||||
|
if (sa)
|
||||||
|
fta->GetWin32(&fa);
|
||||||
|
SetFileTime(hFile,sc ? &fc:NULL,sa ? &fa:NULL,sm ? &fm:NULL);
|
||||||
|
CloseHandle(hFile);
|
||||||
|
if (ResetAttr)
|
||||||
|
SetFileAttr(Name,NULL,DirAttr);
|
||||||
|
#endif
|
||||||
|
#if defined(_UNIX) || defined(_EMX)
|
||||||
|
File::SetCloseFileTimeByName(Name,ftm,fta);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsRemovable(const char *Name)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
char Root[NM];
|
||||||
|
GetPathRoot(Name,Root);
|
||||||
|
int Type=GetDriveType(*Root ? Root:NULL);
|
||||||
|
return(Type==DRIVE_REMOVABLE || Type==DRIVE_CDROM);
|
||||||
|
#elif defined(_EMX)
|
||||||
|
char Drive=toupper(Name[0]);
|
||||||
|
return((Drive=='A' || Drive=='B') && Name[1]==':');
|
||||||
|
#else
|
||||||
|
return(false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
Int64 GetFreeDisk(const char *Name)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
char Root[NM];
|
||||||
|
GetPathRoot(Name,Root);
|
||||||
|
|
||||||
|
typedef BOOL (WINAPI *GETDISKFREESPACEEX)(
|
||||||
|
LPCTSTR,PULARGE_INTEGER,PULARGE_INTEGER,PULARGE_INTEGER
|
||||||
|
);
|
||||||
|
static GETDISKFREESPACEEX pGetDiskFreeSpaceEx=NULL;
|
||||||
|
|
||||||
|
if (pGetDiskFreeSpaceEx==NULL)
|
||||||
|
{
|
||||||
|
HMODULE hKernel=GetModuleHandle("kernel32.dll");
|
||||||
|
if (hKernel!=NULL)
|
||||||
|
pGetDiskFreeSpaceEx=(GETDISKFREESPACEEX)GetProcAddress(hKernel,"GetDiskFreeSpaceExA");
|
||||||
|
}
|
||||||
|
if (pGetDiskFreeSpaceEx!=NULL)
|
||||||
|
{
|
||||||
|
GetFilePath(Name,Root);
|
||||||
|
ULARGE_INTEGER uiTotalSize,uiTotalFree,uiUserFree;
|
||||||
|
uiUserFree.u.LowPart=uiUserFree.u.HighPart=0;
|
||||||
|
if (pGetDiskFreeSpaceEx(*Root ? Root:NULL,&uiUserFree,&uiTotalSize,&uiTotalFree) &&
|
||||||
|
uiUserFree.u.HighPart<=uiTotalFree.u.HighPart)
|
||||||
|
return(int32to64(uiUserFree.u.HighPart,uiUserFree.u.LowPart));
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD SectorsPerCluster,BytesPerSector,FreeClusters,TotalClusters;
|
||||||
|
if (!GetDiskFreeSpace(*Root ? Root:NULL,&SectorsPerCluster,&BytesPerSector,&FreeClusters,&TotalClusters))
|
||||||
|
return(1457664);
|
||||||
|
Int64 FreeSize=SectorsPerCluster*BytesPerSector;
|
||||||
|
FreeSize=FreeSize*FreeClusters;
|
||||||
|
return(FreeSize);
|
||||||
|
#elif defined(_BEOS)
|
||||||
|
char Root[NM];
|
||||||
|
GetFilePath(Name,Root);
|
||||||
|
dev_t Dev=dev_for_path(*Root ? Root:".");
|
||||||
|
if (Dev<0)
|
||||||
|
return(1457664);
|
||||||
|
fs_info Info;
|
||||||
|
if (fs_stat_dev(Dev,&Info)!=0)
|
||||||
|
return(1457664);
|
||||||
|
Int64 FreeSize=Info.block_size;
|
||||||
|
FreeSize=FreeSize*Info.free_blocks;
|
||||||
|
return(FreeSize);
|
||||||
|
#elif defined(_UNIX)
|
||||||
|
return(1457664);
|
||||||
|
#elif defined(_EMX)
|
||||||
|
int Drive=(!isalpha(Name[0]) || Name[1]!=':') ? 0:toupper(Name[0])-'A'+1;
|
||||||
|
if (_osmode == OS2_MODE)
|
||||||
|
{
|
||||||
|
FSALLOCATE fsa;
|
||||||
|
if (DosQueryFSInfo(Drive,1,&fsa,sizeof(fsa))!=0)
|
||||||
|
return(1457664);
|
||||||
|
Int64 FreeSize=fsa.cSectorUnit*fsa.cbSector;
|
||||||
|
FreeSize=FreeSize*fsa.cUnitAvail;
|
||||||
|
return(FreeSize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
union REGS regs,outregs;
|
||||||
|
memset(®s,0,sizeof(regs));
|
||||||
|
regs.h.ah=0x36;
|
||||||
|
regs.h.dl=Drive;
|
||||||
|
_int86 (0x21,®s,&outregs);
|
||||||
|
if (outregs.x.ax==0xffff)
|
||||||
|
return(1457664);
|
||||||
|
Int64 FreeSize=outregs.x.ax*outregs.x.cx;
|
||||||
|
FreeSize=FreeSize*outregs.x.bx;
|
||||||
|
return(FreeSize);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#define DISABLEAUTODETECT
|
||||||
|
return(1457664);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool FileExist(const char *Name,const wchar *NameW)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
if (WinNT() && NameW!=NULL && *NameW!=0)
|
||||||
|
return(GetFileAttributesW(NameW)!=0xffffffff);
|
||||||
|
else
|
||||||
|
return(GetFileAttributes(Name)!=0xffffffff);
|
||||||
|
#elif defined(ENABLE_ACCESS)
|
||||||
|
return(access(Name,0)==0);
|
||||||
|
#else
|
||||||
|
struct FindData FD;
|
||||||
|
return(FindFile::FastFind(Name,NameW,&FD));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool WildFileExist(const char *Name,const wchar *NameW)
|
||||||
|
{
|
||||||
|
if (IsWildcard(Name,NameW))
|
||||||
|
{
|
||||||
|
FindFile Find;
|
||||||
|
Find.SetMask(Name);
|
||||||
|
Find.SetMaskW(NameW);
|
||||||
|
struct FindData fd;
|
||||||
|
return(Find.Next(&fd));
|
||||||
|
}
|
||||||
|
return(FileExist(Name,NameW));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsDir(uint Attr)
|
||||||
|
{
|
||||||
|
#if defined (_WIN_32) || defined(_EMX)
|
||||||
|
return(Attr!=0xffffffff && (Attr & 0x10)!=0);
|
||||||
|
#endif
|
||||||
|
#if defined(_UNIX)
|
||||||
|
return((Attr & 0xF000)==0x4000);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsUnreadable(uint Attr)
|
||||||
|
{
|
||||||
|
#if defined(_UNIX) && defined(S_ISFIFO) && defined(S_ISSOCK) && defined(S_ISCHR)
|
||||||
|
return(S_ISFIFO(Attr) || S_ISSOCK(Attr) || S_ISCHR(Attr));
|
||||||
|
#endif
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsLabel(uint Attr)
|
||||||
|
{
|
||||||
|
#if defined (_WIN_32) || defined(_EMX)
|
||||||
|
return((Attr & 8)!=0);
|
||||||
|
#else
|
||||||
|
return(false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsLink(uint Attr)
|
||||||
|
{
|
||||||
|
#ifdef _UNIX
|
||||||
|
return((Attr & 0xF000)==0xA000);
|
||||||
|
#else
|
||||||
|
return(false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool IsDeleteAllowed(uint FileAttr)
|
||||||
|
{
|
||||||
|
#if defined(_WIN_32) || defined(_EMX)
|
||||||
|
return((FileAttr & (FA_RDONLY|FA_SYSTEM|FA_HIDDEN))==0);
|
||||||
|
#else
|
||||||
|
return((FileAttr & (S_IRUSR|S_IWUSR))==(S_IRUSR|S_IWUSR));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PrepareToDelete(const char *Name,const wchar *NameW)
|
||||||
|
{
|
||||||
|
#if defined(_WIN_32) || defined(_EMX)
|
||||||
|
SetFileAttr(Name,NameW,0);
|
||||||
|
#endif
|
||||||
|
#ifdef _UNIX
|
||||||
|
chmod(Name,S_IRUSR|S_IWUSR|S_IXUSR);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint GetFileAttr(const char *Name,const wchar *NameW)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
if (WinNT() && NameW!=NULL && *NameW!=0)
|
||||||
|
return(GetFileAttributesW(NameW));
|
||||||
|
else
|
||||||
|
return(GetFileAttributes(Name));
|
||||||
|
#elif defined(_DJGPP)
|
||||||
|
return(_chmod(Name,0));
|
||||||
|
#else
|
||||||
|
struct stat st;
|
||||||
|
if (stat(Name,&st)!=0)
|
||||||
|
return(0);
|
||||||
|
#ifdef _EMX
|
||||||
|
return(st.st_attr);
|
||||||
|
#else
|
||||||
|
return(st.st_mode);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool SetFileAttr(const char *Name,const wchar *NameW,uint Attr)
|
||||||
|
{
|
||||||
|
bool Success;
|
||||||
|
#ifdef _WIN_32
|
||||||
|
if (WinNT() && NameW!=NULL && *NameW!=0)
|
||||||
|
Success=SetFileAttributesW(NameW,Attr)!=0;
|
||||||
|
else
|
||||||
|
Success=SetFileAttributes(Name,Attr)!=0;
|
||||||
|
#elif defined(_DJGPP)
|
||||||
|
Success=_chmod(Name,1,Attr)!=-1;
|
||||||
|
#elif defined(_EMX)
|
||||||
|
Success=__chmod(Name,1,Attr)!=-1;
|
||||||
|
#elif defined(_UNIX)
|
||||||
|
Success=chmod(Name,(mode_t)Attr)==0;
|
||||||
|
#else
|
||||||
|
Success=false;
|
||||||
|
#endif
|
||||||
|
return(Success);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ConvertNameToFull(const char *Src,char *Dest)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
#ifndef _WIN_CE
|
||||||
|
char FullName[NM],*NamePtr;
|
||||||
|
if (GetFullPathName(Src,sizeof(FullName),FullName,&NamePtr))
|
||||||
|
strcpy(Dest,FullName);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (Src!=Dest)
|
||||||
|
strcpy(Dest,Src);
|
||||||
|
#else
|
||||||
|
char FullName[NM];
|
||||||
|
if (IsPathDiv(*Src) || IsDiskLetter(Src))
|
||||||
|
strcpy(FullName,Src);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
getcwd(FullName,sizeof(FullName));
|
||||||
|
AddEndSlash(FullName);
|
||||||
|
strcat(FullName,Src);
|
||||||
|
}
|
||||||
|
strcpy(Dest,FullName);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
void ConvertNameToFull(const wchar *Src,wchar *Dest)
|
||||||
|
{
|
||||||
|
if (Src==NULL || *Src==0)
|
||||||
|
{
|
||||||
|
*Dest=0;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#ifdef _WIN_32
|
||||||
|
#ifndef _WIN_CE
|
||||||
|
if (WinNT())
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
#ifndef _WIN_CE
|
||||||
|
wchar FullName[NM],*NamePtr;
|
||||||
|
if (GetFullPathNameW(Src,sizeof(FullName)/sizeof(FullName[0]),FullName,&NamePtr))
|
||||||
|
strcpyw(Dest,FullName);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (Src!=Dest)
|
||||||
|
strcpyw(Dest,Src);
|
||||||
|
}
|
||||||
|
#ifndef _WIN_CE
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char AnsiName[NM];
|
||||||
|
WideToChar(Src,AnsiName);
|
||||||
|
ConvertNameToFull(AnsiName,AnsiName);
|
||||||
|
CharToWide(AnsiName,Dest);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
char AnsiName[NM];
|
||||||
|
WideToChar(Src,AnsiName);
|
||||||
|
ConvertNameToFull(AnsiName,AnsiName);
|
||||||
|
CharToWide(AnsiName,Dest);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
char *MkTemp(char *Name)
|
||||||
|
{
|
||||||
|
int Length=strlen(Name);
|
||||||
|
if (Length<=6)
|
||||||
|
return(NULL);
|
||||||
|
int Random=clock();
|
||||||
|
for (int Attempt=0;;Attempt++)
|
||||||
|
{
|
||||||
|
sprintf(Name+Length-6,"%06u",Random+Attempt);
|
||||||
|
Name[Length-4]='.';
|
||||||
|
if (!FileExist(Name))
|
||||||
|
break;
|
||||||
|
if (Attempt==1000)
|
||||||
|
return(NULL);
|
||||||
|
}
|
||||||
|
return(Name);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
uint CalcFileCRC(File *SrcFile,Int64 Size)
|
||||||
|
{
|
||||||
|
SaveFilePos SavePos(*SrcFile);
|
||||||
|
const int BufSize=0x10000;
|
||||||
|
Array<byte> Data(BufSize);
|
||||||
|
Int64 BlockCount=0;
|
||||||
|
uint DataCRC=0xffffffff;
|
||||||
|
int ReadSize;
|
||||||
|
|
||||||
|
|
||||||
|
SrcFile->Seek(0,SEEK_SET);
|
||||||
|
while ((ReadSize=SrcFile->Read(&Data[0],int64to32(Size==INT64ERR ? Int64(BufSize):Min(Int64(BufSize),Size))))!=0)
|
||||||
|
{
|
||||||
|
++BlockCount;
|
||||||
|
if ((BlockCount & 15)==0)
|
||||||
|
{
|
||||||
|
Wait();
|
||||||
|
}
|
||||||
|
DataCRC=CRC(DataCRC,&Data[0],ReadSize);
|
||||||
|
if (Size!=INT64ERR)
|
||||||
|
Size-=ReadSize;
|
||||||
|
}
|
||||||
|
return(DataCRC^0xffffffff);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool RenameFile(const char *SrcName,const wchar *SrcNameW,const char *DestName,const wchar *DestNameW)
|
||||||
|
{
|
||||||
|
return(rename(SrcName,DestName)==0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DelFile(const char *Name)
|
||||||
|
{
|
||||||
|
return(DelFile(Name,NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DelFile(const char *Name,const wchar *NameW)
|
||||||
|
{
|
||||||
|
return(remove(Name)==0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DelDir(const char *Name)
|
||||||
|
{
|
||||||
|
return(DelDir(Name,NULL));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DelDir(const char *Name,const wchar *NameW)
|
||||||
|
{
|
||||||
|
return(rmdir(Name)==0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_WIN_32) && !defined(_WIN_CE)
|
||||||
|
bool SetFileCompression(char *Name,wchar *NameW,bool State)
|
||||||
|
{
|
||||||
|
wchar FileNameW[NM];
|
||||||
|
GetWideName(Name,NameW,FileNameW);
|
||||||
|
HANDLE hFile=CreateFileW(FileNameW,FILE_READ_DATA|FILE_WRITE_DATA,
|
||||||
|
FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,
|
||||||
|
FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_SEQUENTIAL_SCAN,NULL);
|
||||||
|
if (hFile==INVALID_HANDLE_VALUE)
|
||||||
|
return(false);
|
||||||
|
SHORT NewState=State ? COMPRESSION_FORMAT_DEFAULT:COMPRESSION_FORMAT_NONE;
|
||||||
|
DWORD Result;
|
||||||
|
int RetCode=DeviceIoControl(hFile,FSCTL_SET_COMPRESSION,&NewState,
|
||||||
|
sizeof(NewState),NULL,0,&Result,NULL);
|
||||||
|
CloseHandle(hFile);
|
||||||
|
return(RetCode!=0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
#ifndef _RAR_FILEFN_
|
||||||
|
#define _RAR_FILEFN_
|
||||||
|
|
||||||
|
enum MKDIR_CODE {MKDIR_SUCCESS,MKDIR_ERROR,MKDIR_BADPATH};
|
||||||
|
|
||||||
|
MKDIR_CODE MakeDir(const char *Name,const wchar *NameW,uint Attr);
|
||||||
|
void CreatePath(const char *Path,const wchar *PathW,bool SkipLastName);
|
||||||
|
void SetDirTime(const char *Name,RarTime *ftm,RarTime *ftc,RarTime *fta);
|
||||||
|
bool IsRemovable(const char *Name);
|
||||||
|
Int64 GetFreeDisk(const char *Name);
|
||||||
|
bool FileExist(const char *Name,const wchar *NameW=NULL);
|
||||||
|
bool WildFileExist(const char *Name,const wchar *NameW=NULL);
|
||||||
|
bool IsDir(uint Attr);
|
||||||
|
bool IsUnreadable(uint Attr);
|
||||||
|
bool IsLabel(uint Attr);
|
||||||
|
bool IsLink(uint Attr);
|
||||||
|
void SetSFXMode(const char *FileName);
|
||||||
|
void EraseDiskContents(const char *FileName);
|
||||||
|
bool IsDeleteAllowed(uint FileAttr);
|
||||||
|
void PrepareToDelete(const char *Name,const wchar *NameW=NULL);
|
||||||
|
uint GetFileAttr(const char *Name,const wchar *NameW=NULL);
|
||||||
|
bool SetFileAttr(const char *Name,const wchar *NameW,uint Attr);
|
||||||
|
void ConvertNameToFull(const char *Src,char *Dest);
|
||||||
|
void ConvertNameToFull(const wchar *Src,wchar *Dest);
|
||||||
|
char* MkTemp(char *Name);
|
||||||
|
|
||||||
|
|
||||||
|
uint CalcFileCRC(File *SrcFile,Int64 Size=INT64ERR);
|
||||||
|
bool RenameFile(const char *SrcName,const wchar *SrcNameW,const char *DestName,const wchar *DestNameW);
|
||||||
|
bool DelFile(const char *Name);
|
||||||
|
bool DelFile(const char *Name,const wchar *NameW);
|
||||||
|
bool DelDir(const char *Name);
|
||||||
|
bool DelDir(const char *Name,const wchar *NameW);
|
||||||
|
|
||||||
|
#if defined(_WIN_32) && !defined(_WIN_CE)
|
||||||
|
bool SetFileCompression(char *Name,wchar *NameW,bool State);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
static bool IsUnicode(byte *Data,int Size);
|
||||||
|
|
||||||
|
bool ReadTextFile(char *Name,StringList *List,bool Config,bool AbortOnError,
|
||||||
|
bool ConvertToAnsi,bool Unquote,bool SkipComments)
|
||||||
|
{
|
||||||
|
char FileName[NM];
|
||||||
|
if (Config)
|
||||||
|
GetConfigName(Name,FileName,true);
|
||||||
|
else
|
||||||
|
strcpy(FileName,Name);
|
||||||
|
|
||||||
|
File SrcFile;
|
||||||
|
if (*FileName)
|
||||||
|
{
|
||||||
|
bool OpenCode=AbortOnError ? SrcFile.WOpen(FileName):SrcFile.Open(FileName);
|
||||||
|
|
||||||
|
if (!OpenCode)
|
||||||
|
{
|
||||||
|
if (AbortOnError)
|
||||||
|
ErrHandler.Exit(OPEN_ERROR);
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
SrcFile.SetHandleType(FILE_HANDLESTD);
|
||||||
|
|
||||||
|
unsigned int DataSize=0,ReadSize;
|
||||||
|
const int ReadBlock=1024;
|
||||||
|
Array<char> Data(ReadBlock+5);
|
||||||
|
while ((ReadSize=SrcFile.Read(&Data[DataSize],ReadBlock))!=0)
|
||||||
|
{
|
||||||
|
DataSize+=ReadSize;
|
||||||
|
Data.Add(ReadSize);
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(&Data[DataSize],0,5);
|
||||||
|
|
||||||
|
if (IsUnicode((byte *)&Data[0],DataSize))
|
||||||
|
{
|
||||||
|
wchar *CurStr=(wchar *)&Data[2];
|
||||||
|
Array<char> AnsiName;
|
||||||
|
|
||||||
|
while (*CurStr!=0)
|
||||||
|
{
|
||||||
|
wchar *NextStr=CurStr,*CmtPtr=NULL;
|
||||||
|
while (*NextStr!='\r' && *NextStr!='\n' && *NextStr!=0)
|
||||||
|
{
|
||||||
|
if (SkipComments && NextStr[0]=='/' && NextStr[1]=='/')
|
||||||
|
{
|
||||||
|
*NextStr=0;
|
||||||
|
CmtPtr=NextStr;
|
||||||
|
}
|
||||||
|
NextStr++;
|
||||||
|
}
|
||||||
|
*NextStr=0;
|
||||||
|
for (wchar *SpacePtr=(CmtPtr ? CmtPtr:NextStr)-1;SpacePtr>=CurStr;SpacePtr--)
|
||||||
|
{
|
||||||
|
if (*SpacePtr!=' ' && *SpacePtr!='\t')
|
||||||
|
break;
|
||||||
|
*SpacePtr=0;
|
||||||
|
}
|
||||||
|
if (*CurStr)
|
||||||
|
{
|
||||||
|
int Length=strlenw(CurStr);
|
||||||
|
int AddSize=4*(Length-AnsiName.Size()+1);
|
||||||
|
if (AddSize>0)
|
||||||
|
AnsiName.Add(AddSize);
|
||||||
|
if (Unquote && *CurStr=='\"' && CurStr[Length-1]=='\"')
|
||||||
|
{
|
||||||
|
CurStr[Length-1]=0;
|
||||||
|
CurStr++;
|
||||||
|
}
|
||||||
|
WideToChar(CurStr,&AnsiName[0],AnsiName.Size());
|
||||||
|
List->AddString(&AnsiName[0],CurStr);
|
||||||
|
}
|
||||||
|
CurStr=NextStr+1;
|
||||||
|
while (*CurStr=='\r' || *CurStr=='\n')
|
||||||
|
CurStr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *CurStr=&Data[0];
|
||||||
|
while (*CurStr!=0)
|
||||||
|
{
|
||||||
|
char *NextStr=CurStr,*CmtPtr=NULL;
|
||||||
|
while (*NextStr!='\r' && *NextStr!='\n' && *NextStr!=0)
|
||||||
|
{
|
||||||
|
if (SkipComments && NextStr[0]=='/' && NextStr[1]=='/')
|
||||||
|
{
|
||||||
|
*NextStr=0;
|
||||||
|
CmtPtr=NextStr;
|
||||||
|
}
|
||||||
|
NextStr++;
|
||||||
|
}
|
||||||
|
*NextStr=0;
|
||||||
|
for (char *SpacePtr=(CmtPtr ? CmtPtr:NextStr)-1;SpacePtr>=CurStr;SpacePtr--)
|
||||||
|
{
|
||||||
|
if (*SpacePtr!=' ' && *SpacePtr!='\t')
|
||||||
|
break;
|
||||||
|
*SpacePtr=0;
|
||||||
|
}
|
||||||
|
if (*CurStr)
|
||||||
|
{
|
||||||
|
if (Unquote && *CurStr=='\"')
|
||||||
|
{
|
||||||
|
int Length=strlen(CurStr);
|
||||||
|
if (CurStr[Length-1]=='\"')
|
||||||
|
{
|
||||||
|
CurStr[Length-1]=0;
|
||||||
|
CurStr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if defined(_WIN_32)
|
||||||
|
if (ConvertToAnsi)
|
||||||
|
OemToChar(CurStr,CurStr);
|
||||||
|
#endif
|
||||||
|
List->AddString(CurStr);
|
||||||
|
}
|
||||||
|
CurStr=NextStr+1;
|
||||||
|
while (*CurStr=='\r' || *CurStr=='\n')
|
||||||
|
CurStr++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsUnicode(byte *Data,int Size)
|
||||||
|
{
|
||||||
|
if (Size<4 || Data[0]!=0xff || Data[1]!=0xfe)
|
||||||
|
return(false);
|
||||||
|
for (int I=2;I<Size;I++)
|
||||||
|
if (Data[I]<32)
|
||||||
|
return(true);
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef _RAR_FILESTR_
|
||||||
|
#define _RAR_FILESTR_
|
||||||
|
|
||||||
|
bool ReadTextFile(char *Name,StringList *List,bool Config,
|
||||||
|
bool AbortOnError=false,bool ConvertToAnsi=false,
|
||||||
|
bool Unquote=false,bool SkipComments=false);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,287 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
FindFile::FindFile()
|
||||||
|
{
|
||||||
|
*FindMask=0;
|
||||||
|
*FindMaskW=0;
|
||||||
|
FirstCall=TRUE;
|
||||||
|
#ifdef _WIN_32
|
||||||
|
hFind=INVALID_HANDLE_VALUE;
|
||||||
|
#else
|
||||||
|
dirp=NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
FindFile::~FindFile()
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
if (hFind!=INVALID_HANDLE_VALUE)
|
||||||
|
FindClose(hFind);
|
||||||
|
#else
|
||||||
|
if (dirp!=NULL)
|
||||||
|
closedir(dirp);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FindFile::SetMask(const char *FindMask)
|
||||||
|
{
|
||||||
|
strcpy(FindFile::FindMask,FindMask);
|
||||||
|
if (*FindMaskW==0)
|
||||||
|
CharToWide(FindMask,FindMaskW);
|
||||||
|
FirstCall=TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FindFile::SetMaskW(const wchar *FindMaskW)
|
||||||
|
{
|
||||||
|
if (FindMaskW==NULL)
|
||||||
|
return;
|
||||||
|
strcpyw(FindFile::FindMaskW,FindMaskW);
|
||||||
|
if (*FindMask==0)
|
||||||
|
WideToChar(FindMaskW,FindMask);
|
||||||
|
FirstCall=TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool FindFile::Next(struct FindData *fd,bool GetSymLink)
|
||||||
|
{
|
||||||
|
fd->Error=false;
|
||||||
|
if (*FindMask==0)
|
||||||
|
return(false);
|
||||||
|
#ifdef _WIN_32
|
||||||
|
if (FirstCall)
|
||||||
|
{
|
||||||
|
if ((hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,FindMaskW,fd))==INVALID_HANDLE_VALUE)
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (Win32Find(hFind,FindMask,FindMaskW,fd)==INVALID_HANDLE_VALUE)
|
||||||
|
return(false);
|
||||||
|
#else
|
||||||
|
if (FirstCall)
|
||||||
|
{
|
||||||
|
char DirName[NM];
|
||||||
|
strcpy(DirName,FindMask);
|
||||||
|
RemoveNameFromPath(DirName);
|
||||||
|
if (*DirName==0)
|
||||||
|
strcpy(DirName,".");
|
||||||
|
/*
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int Length=strlen(DirName);
|
||||||
|
if (Length>1 && DirName[Length-1]==CPATHDIVIDER && (Length!=3 || !IsDriveDiv(DirName[1])))
|
||||||
|
DirName[Length-1]=0;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
if ((dirp=opendir(DirName))==NULL)
|
||||||
|
{
|
||||||
|
fd->Error=(errno!=ENOENT);
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
struct dirent *ent=readdir(dirp);
|
||||||
|
if (ent==NULL)
|
||||||
|
return(false);
|
||||||
|
if (strcmp(ent->d_name,".")==0 || strcmp(ent->d_name,"..")==0)
|
||||||
|
continue;
|
||||||
|
if (CmpName(FindMask,ent->d_name,MATCH_NAMES))
|
||||||
|
{
|
||||||
|
char FullName[NM];
|
||||||
|
strcpy(FullName,FindMask);
|
||||||
|
strcpy(PointToName(FullName),ent->d_name);
|
||||||
|
if (!FastFind(FullName,NULL,fd,GetSymLink))
|
||||||
|
{
|
||||||
|
ErrHandler.OpenErrorMsg(FullName);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
strcpy(fd->Name,FullName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*fd->NameW=0;
|
||||||
|
#ifdef _APPLE
|
||||||
|
if (!LowAscii(fd->Name))
|
||||||
|
UtfToWide(fd->Name,fd->NameW,sizeof(fd->NameW));
|
||||||
|
#elif defined(UNICODE_SUPPORTED)
|
||||||
|
if (!LowAscii(fd->Name) && UnicodeEnabled())
|
||||||
|
CharToWide(fd->Name,fd->NameW);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
fd->IsDir=IsDir(fd->FileAttr);
|
||||||
|
FirstCall=FALSE;
|
||||||
|
char *Name=PointToName(fd->Name);
|
||||||
|
if (strcmp(Name,".")==0 || strcmp(Name,"..")==0)
|
||||||
|
return(Next(fd));
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool FindFile::FastFind(const char *FindMask,const wchar *FindMaskW,struct FindData *fd,bool GetSymLink)
|
||||||
|
{
|
||||||
|
fd->Error=false;
|
||||||
|
#ifndef _UNIX
|
||||||
|
if (IsWildcard(FindMask,FindMaskW))
|
||||||
|
return(false);
|
||||||
|
#endif
|
||||||
|
#ifdef _WIN_32
|
||||||
|
HANDLE hFind=Win32Find(INVALID_HANDLE_VALUE,FindMask,FindMaskW,fd);
|
||||||
|
if (hFind==INVALID_HANDLE_VALUE)
|
||||||
|
return(false);
|
||||||
|
FindClose(hFind);
|
||||||
|
#else
|
||||||
|
struct stat st;
|
||||||
|
if (GetSymLink)
|
||||||
|
{
|
||||||
|
#ifdef SAVE_LINKS
|
||||||
|
if (lstat(FindMask,&st)!=0)
|
||||||
|
#else
|
||||||
|
if (stat(FindMask,&st)!=0)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
fd->Error=(errno!=ENOENT);
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (stat(FindMask,&st)!=0)
|
||||||
|
{
|
||||||
|
fd->Error=(errno!=ENOENT);
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
#ifdef _DJGPP
|
||||||
|
fd->FileAttr=chmod(FindMask,0);
|
||||||
|
#elif defined(_EMX)
|
||||||
|
fd->FileAttr=st.st_attr;
|
||||||
|
#else
|
||||||
|
fd->FileAttr=st.st_mode;
|
||||||
|
#endif
|
||||||
|
fd->IsDir=IsDir(st.st_mode);
|
||||||
|
fd->Size=st.st_size;
|
||||||
|
fd->mtime=st.st_mtime;
|
||||||
|
fd->atime=st.st_atime;
|
||||||
|
fd->ctime=st.st_ctime;
|
||||||
|
fd->FileTime=fd->mtime.GetDos();
|
||||||
|
strcpy(fd->Name,FindMask);
|
||||||
|
|
||||||
|
*fd->NameW=0;
|
||||||
|
#ifdef _APPLE
|
||||||
|
if (!LowAscii(fd->Name))
|
||||||
|
UtfToWide(fd->Name,fd->NameW,sizeof(fd->NameW));
|
||||||
|
#elif defined(UNICODE_SUPPORTED)
|
||||||
|
if (!LowAscii(fd->Name) && UnicodeEnabled())
|
||||||
|
CharToWide(fd->Name,fd->NameW);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
fd->IsDir=IsDir(fd->FileAttr);
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN_32
|
||||||
|
HANDLE FindFile::Win32Find(HANDLE hFind,const char *Mask,const wchar *MaskW,struct FindData *fd)
|
||||||
|
{
|
||||||
|
#ifndef _WIN_CE
|
||||||
|
if (WinNT())
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
wchar WideMask[NM];
|
||||||
|
if (MaskW!=NULL && *MaskW!=0)
|
||||||
|
strcpyw(WideMask,MaskW);
|
||||||
|
else
|
||||||
|
CharToWide(Mask,WideMask);
|
||||||
|
|
||||||
|
WIN32_FIND_DATAW FindData;
|
||||||
|
if (hFind==INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
hFind=FindFirstFileW(WideMask,&FindData);
|
||||||
|
if (hFind==INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
int SysErr=GetLastError();
|
||||||
|
fd->Error=(SysErr!=ERROR_FILE_NOT_FOUND &&
|
||||||
|
SysErr!=ERROR_PATH_NOT_FOUND &&
|
||||||
|
SysErr!=ERROR_NO_MORE_FILES);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (!FindNextFileW(hFind,&FindData))
|
||||||
|
{
|
||||||
|
hFind=INVALID_HANDLE_VALUE;
|
||||||
|
fd->Error=GetLastError()!=ERROR_NO_MORE_FILES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hFind!=INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
strcpyw(fd->NameW,WideMask);
|
||||||
|
strcpyw(PointToName(fd->NameW),FindData.cFileName);
|
||||||
|
WideToChar(fd->NameW,fd->Name);
|
||||||
|
fd->Size=int32to64(FindData.nFileSizeHigh,FindData.nFileSizeLow);
|
||||||
|
fd->FileAttr=FindData.dwFileAttributes;
|
||||||
|
WideToChar(FindData.cAlternateFileName,fd->ShortName);
|
||||||
|
fd->ftCreationTime=FindData.ftCreationTime;
|
||||||
|
fd->ftLastAccessTime=FindData.ftLastAccessTime;
|
||||||
|
fd->ftLastWriteTime=FindData.ftLastWriteTime;
|
||||||
|
fd->mtime=FindData.ftLastWriteTime;
|
||||||
|
fd->ctime=FindData.ftCreationTime;
|
||||||
|
fd->atime=FindData.ftLastAccessTime;
|
||||||
|
fd->FileTime=fd->mtime.GetDos();
|
||||||
|
|
||||||
|
#ifndef _WIN_CE
|
||||||
|
if (LowAscii(fd->NameW))
|
||||||
|
*fd->NameW=0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifndef _WIN_CE
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char CharMask[NM];
|
||||||
|
if (Mask!=NULL && *Mask!=0)
|
||||||
|
strcpy(CharMask,Mask);
|
||||||
|
else
|
||||||
|
WideToChar(MaskW,CharMask);
|
||||||
|
|
||||||
|
WIN32_FIND_DATA FindData;
|
||||||
|
if (hFind==INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
hFind=FindFirstFile(CharMask,&FindData);
|
||||||
|
if (hFind==INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
int SysErr=GetLastError();
|
||||||
|
fd->Error=SysErr!=ERROR_FILE_NOT_FOUND && SysErr!=ERROR_PATH_NOT_FOUND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (!FindNextFile(hFind,&FindData))
|
||||||
|
{
|
||||||
|
hFind=INVALID_HANDLE_VALUE;
|
||||||
|
fd->Error=GetLastError()!=ERROR_NO_MORE_FILES;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hFind!=INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
strcpy(fd->Name,CharMask);
|
||||||
|
strcpy(PointToName(fd->Name),FindData.cFileName);
|
||||||
|
CharToWide(fd->Name,fd->NameW);
|
||||||
|
fd->Size=int32to64(FindData.nFileSizeHigh,FindData.nFileSizeLow);
|
||||||
|
fd->FileAttr=FindData.dwFileAttributes;
|
||||||
|
strcpy(fd->ShortName,FindData.cAlternateFileName);
|
||||||
|
fd->ftCreationTime=FindData.ftCreationTime;
|
||||||
|
fd->ftLastAccessTime=FindData.ftLastAccessTime;
|
||||||
|
fd->ftLastWriteTime=FindData.ftLastWriteTime;
|
||||||
|
fd->mtime=FindData.ftLastWriteTime;
|
||||||
|
fd->ctime=FindData.ftCreationTime;
|
||||||
|
fd->atime=FindData.ftLastAccessTime;
|
||||||
|
fd->FileTime=fd->mtime.GetDos();
|
||||||
|
if (LowAscii(fd->Name))
|
||||||
|
*fd->NameW=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return(hFind);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
#ifndef _RAR_FINDDATA_
|
||||||
|
#define _RAR_FINDDATA_
|
||||||
|
|
||||||
|
struct FindData
|
||||||
|
{
|
||||||
|
char Name[NM];
|
||||||
|
wchar NameW[NM];
|
||||||
|
Int64 Size;
|
||||||
|
uint FileAttr;
|
||||||
|
uint FileTime;
|
||||||
|
bool IsDir;
|
||||||
|
RarTime mtime;
|
||||||
|
RarTime ctime;
|
||||||
|
RarTime atime;
|
||||||
|
#ifdef _WIN_32
|
||||||
|
char ShortName[NM];
|
||||||
|
FILETIME ftCreationTime;
|
||||||
|
FILETIME ftLastAccessTime;
|
||||||
|
FILETIME ftLastWriteTime;
|
||||||
|
#endif
|
||||||
|
bool Error;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FindFile
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
#ifdef _WIN_32
|
||||||
|
static HANDLE Win32Find(HANDLE hFind,const char *Mask,const wchar *MaskW,struct FindData *fd);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char FindMask[NM];
|
||||||
|
wchar FindMaskW[NM];
|
||||||
|
int FirstCall;
|
||||||
|
#ifdef _WIN_32
|
||||||
|
HANDLE hFind;
|
||||||
|
#else
|
||||||
|
DIR *dirp;
|
||||||
|
#endif
|
||||||
|
public:
|
||||||
|
FindFile();
|
||||||
|
~FindFile();
|
||||||
|
void SetMask(const char *FindMask);
|
||||||
|
void SetMaskW(const wchar *FindMaskW);
|
||||||
|
bool Next(struct FindData *fd,bool GetSymLink=false);
|
||||||
|
static bool FastFind(const char *FindMask,const wchar *FindMaskW,struct FindData *fd,bool GetSymLink=false);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
BitInput::BitInput()
|
||||||
|
{
|
||||||
|
InBuf=new byte[MAX_SIZE];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
BitInput::~BitInput()
|
||||||
|
{
|
||||||
|
delete[] InBuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void BitInput::faddbits(int Bits)
|
||||||
|
{
|
||||||
|
addbits(Bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int BitInput::fgetbits()
|
||||||
|
{
|
||||||
|
return(getbits());
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef _RAR_GETBITS_
|
||||||
|
#define _RAR_GETBITS_
|
||||||
|
|
||||||
|
class BitInput
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum BufferSize {MAX_SIZE=0x8000};
|
||||||
|
protected:
|
||||||
|
int InAddr,InBit;
|
||||||
|
public:
|
||||||
|
BitInput();
|
||||||
|
~BitInput();
|
||||||
|
|
||||||
|
byte *InBuf;
|
||||||
|
|
||||||
|
void InitBitInput()
|
||||||
|
{
|
||||||
|
InAddr=InBit=0;
|
||||||
|
}
|
||||||
|
void addbits(int Bits)
|
||||||
|
{
|
||||||
|
Bits+=InBit;
|
||||||
|
InAddr+=Bits>>3;
|
||||||
|
InBit=Bits&7;
|
||||||
|
}
|
||||||
|
unsigned int getbits()
|
||||||
|
{
|
||||||
|
unsigned int BitField=(uint)InBuf[InAddr] << 16;
|
||||||
|
BitField|=(uint)InBuf[InAddr+1] << 8;
|
||||||
|
BitField|=(uint)InBuf[InAddr+2];
|
||||||
|
BitField >>= (8-InBit);
|
||||||
|
return(BitField & 0xffff);
|
||||||
|
}
|
||||||
|
void faddbits(int Bits);
|
||||||
|
unsigned int fgetbits();
|
||||||
|
};
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
#define INCLUDEGLOBAL
|
||||||
|
|
||||||
|
|
||||||
|
#include "rar.hpp"
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef _RAR_GLOBAL_
|
||||||
|
#define _RAR_GLOBAL_
|
||||||
|
|
||||||
|
#ifdef INCLUDEGLOBAL
|
||||||
|
#define EXTVAR
|
||||||
|
#else
|
||||||
|
#define EXTVAR extern
|
||||||
|
#endif
|
||||||
|
|
||||||
|
EXTVAR ErrorHandler ErrHandler;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,306 @@
|
|||||||
|
#ifndef _RAR_HEADERS_
|
||||||
|
#define _RAR_HEADERS_
|
||||||
|
|
||||||
|
#define SIZEOF_MARKHEAD 7
|
||||||
|
#define SIZEOF_OLDMHD 7
|
||||||
|
#define SIZEOF_NEWMHD 13
|
||||||
|
#define SIZEOF_OLDLHD 21
|
||||||
|
#define SIZEOF_NEWLHD 32
|
||||||
|
#define SIZEOF_SHORTBLOCKHEAD 7
|
||||||
|
#define SIZEOF_LONGBLOCKHEAD 11
|
||||||
|
#define SIZEOF_SUBBLOCKHEAD 14
|
||||||
|
#define SIZEOF_COMMHEAD 13
|
||||||
|
#define SIZEOF_PROTECTHEAD 26
|
||||||
|
#define SIZEOF_AVHEAD 14
|
||||||
|
#define SIZEOF_SIGNHEAD 15
|
||||||
|
#define SIZEOF_UOHEAD 18
|
||||||
|
#define SIZEOF_MACHEAD 22
|
||||||
|
#define SIZEOF_EAHEAD 24
|
||||||
|
#define SIZEOF_BEEAHEAD 24
|
||||||
|
#define SIZEOF_STREAMHEAD 26
|
||||||
|
|
||||||
|
#define PACK_VER 29
|
||||||
|
#define PACK_CRYPT_VER 29
|
||||||
|
#define UNP_VER 36
|
||||||
|
#define CRYPT_VER 29
|
||||||
|
#define AV_VER 20
|
||||||
|
#define PROTECT_VER 20
|
||||||
|
|
||||||
|
#define MHD_VOLUME 0x0001
|
||||||
|
#define MHD_COMMENT 0x0002
|
||||||
|
#define MHD_LOCK 0x0004
|
||||||
|
#define MHD_SOLID 0x0008
|
||||||
|
#define MHD_PACK_COMMENT 0x0010
|
||||||
|
#define MHD_NEWNUMBERING 0x0010
|
||||||
|
#define MHD_AV 0x0020
|
||||||
|
#define MHD_PROTECT 0x0040
|
||||||
|
#define MHD_PASSWORD 0x0080
|
||||||
|
#define MHD_FIRSTVOLUME 0x0100
|
||||||
|
#define MHD_ENCRYPTVER 0x0200
|
||||||
|
|
||||||
|
#define LHD_SPLIT_BEFORE 0x0001
|
||||||
|
#define LHD_SPLIT_AFTER 0x0002
|
||||||
|
#define LHD_PASSWORD 0x0004
|
||||||
|
#define LHD_COMMENT 0x0008
|
||||||
|
#define LHD_SOLID 0x0010
|
||||||
|
|
||||||
|
#define LHD_WINDOWMASK 0x00e0
|
||||||
|
#define LHD_WINDOW64 0x0000
|
||||||
|
#define LHD_WINDOW128 0x0020
|
||||||
|
#define LHD_WINDOW256 0x0040
|
||||||
|
#define LHD_WINDOW512 0x0060
|
||||||
|
#define LHD_WINDOW1024 0x0080
|
||||||
|
#define LHD_WINDOW2048 0x00a0
|
||||||
|
#define LHD_WINDOW4096 0x00c0
|
||||||
|
#define LHD_DIRECTORY 0x00e0
|
||||||
|
|
||||||
|
#define LHD_LARGE 0x0100
|
||||||
|
#define LHD_UNICODE 0x0200
|
||||||
|
#define LHD_SALT 0x0400
|
||||||
|
#define LHD_VERSION 0x0800
|
||||||
|
#define LHD_EXTTIME 0x1000
|
||||||
|
#define LHD_EXTFLAGS 0x2000
|
||||||
|
|
||||||
|
#define SKIP_IF_UNKNOWN 0x4000
|
||||||
|
#define LONG_BLOCK 0x8000
|
||||||
|
|
||||||
|
#define EARC_NEXT_VOLUME 0x0001
|
||||||
|
#define EARC_DATACRC 0x0002
|
||||||
|
#define EARC_REVSPACE 0x0004
|
||||||
|
#define EARC_VOLNUMBER 0x0008
|
||||||
|
|
||||||
|
enum HEADER_TYPE {
|
||||||
|
MARK_HEAD=0x72,MAIN_HEAD=0x73,FILE_HEAD=0x74,COMM_HEAD=0x75,AV_HEAD=0x76,
|
||||||
|
SUB_HEAD=0x77,PROTECT_HEAD=0x78,SIGN_HEAD=0x79,NEWSUB_HEAD=0x7a,
|
||||||
|
ENDARC_HEAD=0x7b
|
||||||
|
};
|
||||||
|
|
||||||
|
enum { EA_HEAD=0x100,UO_HEAD=0x101,MAC_HEAD=0x102,BEEA_HEAD=0x103,
|
||||||
|
NTACL_HEAD=0x104,STREAM_HEAD=0x105 };
|
||||||
|
|
||||||
|
enum HOST_SYSTEM {
|
||||||
|
HOST_MSDOS=0,HOST_OS2=1,HOST_WIN32=2,HOST_UNIX=3,HOST_MACOS=4,
|
||||||
|
HOST_BEOS=5,HOST_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
#define SUBHEAD_TYPE_CMT "CMT"
|
||||||
|
#define SUBHEAD_TYPE_ACL "ACL"
|
||||||
|
#define SUBHEAD_TYPE_STREAM "STM"
|
||||||
|
#define SUBHEAD_TYPE_UOWNER "UOW"
|
||||||
|
#define SUBHEAD_TYPE_AV "AV"
|
||||||
|
#define SUBHEAD_TYPE_RR "RR"
|
||||||
|
#define SUBHEAD_TYPE_OS2EA "EA2"
|
||||||
|
#define SUBHEAD_TYPE_BEOSEA "EABE"
|
||||||
|
|
||||||
|
/* new file inherits a subblock when updating a host file */
|
||||||
|
#define SUBHEAD_FLAGS_INHERITED 0x80000000
|
||||||
|
|
||||||
|
#define SUBHEAD_FLAGS_CMT_UNICODE 0x00000001
|
||||||
|
|
||||||
|
struct OldMainHeader
|
||||||
|
{
|
||||||
|
byte Mark[4];
|
||||||
|
ushort HeadSize;
|
||||||
|
byte Flags;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct OldFileHeader
|
||||||
|
{
|
||||||
|
uint PackSize;
|
||||||
|
uint UnpSize;
|
||||||
|
ushort FileCRC;
|
||||||
|
ushort HeadSize;
|
||||||
|
uint FileTime;
|
||||||
|
byte FileAttr;
|
||||||
|
byte Flags;
|
||||||
|
byte UnpVer;
|
||||||
|
byte NameSize;
|
||||||
|
byte Method;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct MarkHeader
|
||||||
|
{
|
||||||
|
byte Mark[7];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct BaseBlock
|
||||||
|
{
|
||||||
|
ushort HeadCRC;
|
||||||
|
HEADER_TYPE HeadType;//byte
|
||||||
|
ushort Flags;
|
||||||
|
ushort HeadSize;
|
||||||
|
|
||||||
|
bool IsSubBlock()
|
||||||
|
{
|
||||||
|
if (HeadType==SUB_HEAD)
|
||||||
|
return(true);
|
||||||
|
if (HeadType==NEWSUB_HEAD && (Flags & LHD_SOLID)!=0)
|
||||||
|
return(true);
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BlockHeader:BaseBlock
|
||||||
|
{
|
||||||
|
union {
|
||||||
|
uint DataSize;
|
||||||
|
uint PackSize;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct MainHeader:BaseBlock
|
||||||
|
{
|
||||||
|
ushort HighPosAV;
|
||||||
|
uint PosAV;
|
||||||
|
byte EncryptVer;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#define SALT_SIZE 8
|
||||||
|
|
||||||
|
struct FileHeader:BlockHeader
|
||||||
|
{
|
||||||
|
uint UnpSize;
|
||||||
|
byte HostOS;
|
||||||
|
uint FileCRC;
|
||||||
|
uint FileTime;
|
||||||
|
byte UnpVer;
|
||||||
|
byte Method;
|
||||||
|
ushort NameSize;
|
||||||
|
union {
|
||||||
|
uint FileAttr;
|
||||||
|
uint SubFlags;
|
||||||
|
};
|
||||||
|
/* optional */
|
||||||
|
uint HighPackSize;
|
||||||
|
uint HighUnpSize;
|
||||||
|
/* names */
|
||||||
|
char FileName[NM];
|
||||||
|
wchar FileNameW[NM];
|
||||||
|
/* optional */
|
||||||
|
Array<byte> SubData;
|
||||||
|
byte Salt[SALT_SIZE];
|
||||||
|
|
||||||
|
RarTime mtime;
|
||||||
|
RarTime ctime;
|
||||||
|
RarTime atime;
|
||||||
|
RarTime arctime;
|
||||||
|
/* dummy */
|
||||||
|
Int64 FullPackSize;
|
||||||
|
Int64 FullUnpSize;
|
||||||
|
|
||||||
|
void Clear(int SubDataSize)
|
||||||
|
{
|
||||||
|
SubData.Alloc(SubDataSize);
|
||||||
|
Flags=LONG_BLOCK;
|
||||||
|
SubFlags=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CmpName(const char *Name)
|
||||||
|
{
|
||||||
|
return(strcmp(FileName,Name)==0);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileHeader& operator = (FileHeader &hd)
|
||||||
|
{
|
||||||
|
SubData.Reset();
|
||||||
|
memcpy(this,&hd,sizeof(*this));
|
||||||
|
SubData.CleanData();
|
||||||
|
SubData=hd.SubData;
|
||||||
|
return(*this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct EndArcHeader:BaseBlock
|
||||||
|
{
|
||||||
|
uint ArcDataCRC;
|
||||||
|
ushort VolNumber;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct SubBlockHeader:BlockHeader
|
||||||
|
{
|
||||||
|
ushort SubType;
|
||||||
|
byte Level;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct CommentHeader:BaseBlock
|
||||||
|
{
|
||||||
|
ushort UnpSize;
|
||||||
|
byte UnpVer;
|
||||||
|
byte Method;
|
||||||
|
ushort CommCRC;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct ProtectHeader:BlockHeader
|
||||||
|
{
|
||||||
|
byte Version;
|
||||||
|
ushort RecSectors;
|
||||||
|
uint TotalBlocks;
|
||||||
|
byte Mark[8];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct AVHeader:BaseBlock
|
||||||
|
{
|
||||||
|
byte UnpVer;
|
||||||
|
byte Method;
|
||||||
|
byte AVVer;
|
||||||
|
uint AVInfoCRC;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct SignHeader:BaseBlock
|
||||||
|
{
|
||||||
|
uint CreationTime;
|
||||||
|
ushort ArcNameSize;
|
||||||
|
ushort UserNameSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct UnixOwnersHeader:SubBlockHeader
|
||||||
|
{
|
||||||
|
ushort OwnerNameSize;
|
||||||
|
ushort GroupNameSize;
|
||||||
|
/* dummy */
|
||||||
|
char OwnerName[NM];
|
||||||
|
char GroupName[NM];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct EAHeader:SubBlockHeader
|
||||||
|
{
|
||||||
|
uint UnpSize;
|
||||||
|
byte UnpVer;
|
||||||
|
byte Method;
|
||||||
|
uint EACRC;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct StreamHeader:SubBlockHeader
|
||||||
|
{
|
||||||
|
uint UnpSize;
|
||||||
|
byte UnpVer;
|
||||||
|
byte Method;
|
||||||
|
uint StreamCRC;
|
||||||
|
ushort StreamNameSize;
|
||||||
|
/* dummy */
|
||||||
|
byte StreamName[NM];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct MacFInfoHeader:SubBlockHeader
|
||||||
|
{
|
||||||
|
uint fileType;
|
||||||
|
uint fileCreator;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,274 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
#ifndef NATIVE_INT64
|
||||||
|
|
||||||
|
Int64::Int64()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int64::Int64(uint n)
|
||||||
|
{
|
||||||
|
HighPart=0;
|
||||||
|
LowPart=n;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int64::Int64(uint HighPart,uint LowPart)
|
||||||
|
{
|
||||||
|
Int64::HighPart=HighPart;
|
||||||
|
Int64::LowPart=LowPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
Int64 Int64::operator = (Int64 n)
|
||||||
|
{
|
||||||
|
HighPart=n.HighPart;
|
||||||
|
LowPart=n.LowPart;
|
||||||
|
return(*this);
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
Int64 Int64::operator << (int n)
|
||||||
|
{
|
||||||
|
Int64 res=*this;
|
||||||
|
while (n--)
|
||||||
|
{
|
||||||
|
res.HighPart<<=1;
|
||||||
|
if (res.LowPart & 0x80000000)
|
||||||
|
res.HighPart|=1;
|
||||||
|
res.LowPart<<=1;
|
||||||
|
}
|
||||||
|
return(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int64 Int64::operator >> (int n)
|
||||||
|
{
|
||||||
|
Int64 res=*this;
|
||||||
|
while (n--)
|
||||||
|
{
|
||||||
|
res.LowPart>>=1;
|
||||||
|
if (res.HighPart & 1)
|
||||||
|
res.LowPart|=0x80000000;
|
||||||
|
res.HighPart>>=1;
|
||||||
|
}
|
||||||
|
return(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int64 operator / (Int64 n1,Int64 n2)
|
||||||
|
{
|
||||||
|
if (n1.HighPart==0 && n2.HighPart==0)
|
||||||
|
return(Int64(0,n1.LowPart/n2.LowPart));
|
||||||
|
int ShiftCount=0;
|
||||||
|
while (n1>n2)
|
||||||
|
{
|
||||||
|
n2=n2<<1;
|
||||||
|
if (++ShiftCount>64)
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
Int64 res=0;
|
||||||
|
while (ShiftCount-- >= 0)
|
||||||
|
{
|
||||||
|
res=res<<1;
|
||||||
|
if (n1>=n2)
|
||||||
|
{
|
||||||
|
n1-=n2;
|
||||||
|
++res;
|
||||||
|
}
|
||||||
|
n2=n2>>1;
|
||||||
|
}
|
||||||
|
return(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int64 operator * (Int64 n1,Int64 n2)
|
||||||
|
{
|
||||||
|
if (n1<0x10000 && n2<0x10000)
|
||||||
|
return(Int64(0,n1.LowPart*n2.LowPart));
|
||||||
|
Int64 res=0;
|
||||||
|
for (int I=0;I<64;I++)
|
||||||
|
{
|
||||||
|
if (n2.LowPart & 1)
|
||||||
|
res+=n1;
|
||||||
|
n1=n1<<1;
|
||||||
|
n2=n2>>1;
|
||||||
|
}
|
||||||
|
return(res);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int64 operator % (Int64 n1,Int64 n2)
|
||||||
|
{
|
||||||
|
if (n1.HighPart==0 && n2.HighPart==0)
|
||||||
|
return(Int64(0,n1.LowPart%n2.LowPart));
|
||||||
|
return(n1-n1/n2*n2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int64 operator + (Int64 n1,Int64 n2)
|
||||||
|
{
|
||||||
|
n1.LowPart+=n2.LowPart;
|
||||||
|
if (n1.LowPart<n2.LowPart)
|
||||||
|
n1.HighPart++;
|
||||||
|
n1.HighPart+=n2.HighPart;
|
||||||
|
return(n1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int64 operator - (Int64 n1,Int64 n2)
|
||||||
|
{
|
||||||
|
if (n1.LowPart<n2.LowPart)
|
||||||
|
n1.HighPart--;
|
||||||
|
n1.LowPart-=n2.LowPart;
|
||||||
|
n1.HighPart-=n2.HighPart;
|
||||||
|
return(n1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int64 operator += (Int64 &n1,Int64 n2)
|
||||||
|
{
|
||||||
|
n1=n1+n2;
|
||||||
|
return(n1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int64 operator -= (Int64 &n1,Int64 n2)
|
||||||
|
{
|
||||||
|
n1=n1-n2;
|
||||||
|
return(n1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int64 operator *= (Int64 &n1,Int64 n2)
|
||||||
|
{
|
||||||
|
n1=n1*n2;
|
||||||
|
return(n1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int64 operator /= (Int64 &n1,Int64 n2)
|
||||||
|
{
|
||||||
|
n1=n1/n2;
|
||||||
|
return(n1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int64 operator | (Int64 n1,Int64 n2)
|
||||||
|
{
|
||||||
|
n1.LowPart|=n2.LowPart;
|
||||||
|
n1.HighPart|=n2.HighPart;
|
||||||
|
return(n1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int64 operator & (Int64 n1,Int64 n2)
|
||||||
|
{
|
||||||
|
n1.LowPart&=n2.LowPart;
|
||||||
|
n1.HighPart&=n2.HighPart;
|
||||||
|
return(n1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
inline void operator -= (Int64 &n1,unsigned int n2)
|
||||||
|
{
|
||||||
|
if (n1.LowPart<n2)
|
||||||
|
n1.HighPart--;
|
||||||
|
n1.LowPart-=n2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void operator ++ (Int64 &n)
|
||||||
|
{
|
||||||
|
if (++n.LowPart == 0)
|
||||||
|
++n.HighPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void operator -- (Int64 &n)
|
||||||
|
{
|
||||||
|
if (n.LowPart-- == 0)
|
||||||
|
n.HighPart--;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool operator == (Int64 n1,Int64 n2)
|
||||||
|
{
|
||||||
|
return(n1.LowPart==n2.LowPart && n1.HighPart==n2.HighPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator > (Int64 n1,Int64 n2)
|
||||||
|
{
|
||||||
|
return((int)n1.HighPart>(int)n2.HighPart || n1.HighPart==n2.HighPart && n1.LowPart>n2.LowPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator < (Int64 n1,Int64 n2)
|
||||||
|
{
|
||||||
|
return((int)n1.HighPart<(int)n2.HighPart || n1.HighPart==n2.HighPart && n1.LowPart<n2.LowPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator != (Int64 n1,Int64 n2)
|
||||||
|
{
|
||||||
|
return(n1.LowPart!=n2.LowPart || n1.HighPart!=n2.HighPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator >= (Int64 n1,Int64 n2)
|
||||||
|
{
|
||||||
|
return(n1>n2 || n1==n2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool operator <= (Int64 n1,Int64 n2)
|
||||||
|
{
|
||||||
|
return(n1<n2 || n1==n2);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Int64::Set(uint HighPart,uint LowPart)
|
||||||
|
{
|
||||||
|
Int64::HighPart=HighPart;
|
||||||
|
Int64::LowPart=LowPart;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void itoa(Int64 n,char *Str)
|
||||||
|
{
|
||||||
|
if (n<=0xffffffff)
|
||||||
|
{
|
||||||
|
sprintf(Str,"%u",int64to32(n));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char NumStr[50];
|
||||||
|
int Pos=0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
NumStr[Pos++]=int64to32(n%10)+'0';
|
||||||
|
n=n/10;
|
||||||
|
} while (n!=0);
|
||||||
|
|
||||||
|
for (int I=0;I<Pos;I++)
|
||||||
|
Str[I]=NumStr[Pos-I-1];
|
||||||
|
Str[Pos]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Int64 atoil(char *Str)
|
||||||
|
{
|
||||||
|
Int64 n=0;
|
||||||
|
while (*Str>='0' && *Str<='9')
|
||||||
|
{
|
||||||
|
n=n*10+*Str-'0';
|
||||||
|
Str++;
|
||||||
|
}
|
||||||
|
return(n);
|
||||||
|
}
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
#ifndef _RAR_INT64_
|
||||||
|
#define _RAR_INT64_
|
||||||
|
|
||||||
|
#if defined(__BORLANDC__) || defined(_MSC_VER)
|
||||||
|
#define NATIVE_INT64
|
||||||
|
typedef __int64 Int64;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNUC__) || defined(__HP_aCC) || defined(__SUNPRO_CC)
|
||||||
|
#define NATIVE_INT64
|
||||||
|
typedef long long Int64;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef NATIVE_INT64
|
||||||
|
|
||||||
|
#define int64to32(x) ((uint)(x))
|
||||||
|
#define int32to64(high,low) ((((Int64)(high))<<32)+(low))
|
||||||
|
#define is64plus(x) (x>=0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
class Int64
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Int64();
|
||||||
|
Int64(uint n);
|
||||||
|
Int64(uint HighPart,uint LowPart);
|
||||||
|
|
||||||
|
// Int64 operator = (Int64 n);
|
||||||
|
Int64 operator << (int n);
|
||||||
|
Int64 operator >> (int n);
|
||||||
|
|
||||||
|
friend Int64 operator / (Int64 n1,Int64 n2);
|
||||||
|
friend Int64 operator * (Int64 n1,Int64 n2);
|
||||||
|
friend Int64 operator % (Int64 n1,Int64 n2);
|
||||||
|
friend Int64 operator + (Int64 n1,Int64 n2);
|
||||||
|
friend Int64 operator - (Int64 n1,Int64 n2);
|
||||||
|
friend Int64 operator += (Int64 &n1,Int64 n2);
|
||||||
|
friend Int64 operator -= (Int64 &n1,Int64 n2);
|
||||||
|
friend Int64 operator *= (Int64 &n1,Int64 n2);
|
||||||
|
friend Int64 operator /= (Int64 &n1,Int64 n2);
|
||||||
|
friend Int64 operator | (Int64 n1,Int64 n2);
|
||||||
|
friend Int64 operator & (Int64 n1,Int64 n2);
|
||||||
|
inline friend void operator -= (Int64 &n1,unsigned int n2)
|
||||||
|
{
|
||||||
|
if (n1.LowPart<n2)
|
||||||
|
n1.HighPart--;
|
||||||
|
n1.LowPart-=n2;
|
||||||
|
}
|
||||||
|
inline friend void operator ++ (Int64 &n)
|
||||||
|
{
|
||||||
|
if (++n.LowPart == 0)
|
||||||
|
++n.HighPart;
|
||||||
|
}
|
||||||
|
inline friend void operator -- (Int64 &n)
|
||||||
|
{
|
||||||
|
if (n.LowPart-- == 0)
|
||||||
|
n.HighPart--;
|
||||||
|
}
|
||||||
|
friend bool operator == (Int64 n1,Int64 n2);
|
||||||
|
friend bool operator > (Int64 n1,Int64 n2);
|
||||||
|
friend bool operator < (Int64 n1,Int64 n2);
|
||||||
|
friend bool operator != (Int64 n1,Int64 n2);
|
||||||
|
friend bool operator >= (Int64 n1,Int64 n2);
|
||||||
|
friend bool operator <= (Int64 n1,Int64 n2);
|
||||||
|
|
||||||
|
void Set(uint HighPart,uint LowPart);
|
||||||
|
uint GetLowPart() {return(LowPart);}
|
||||||
|
|
||||||
|
uint LowPart;
|
||||||
|
uint HighPart;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline uint int64to32(Int64 n) {return(n.GetLowPart());}
|
||||||
|
#define int32to64(high,low) (Int64((high),(low)))
|
||||||
|
#define is64plus(x) ((int)(x).HighPart>=0)
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define INT64ERR int32to64(0x80000000,0)
|
||||||
|
#define INT64MAX int32to64(0x7fffffff,0)
|
||||||
|
|
||||||
|
void itoa(Int64 n,char *Str);
|
||||||
|
Int64 atoil(char *Str);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
#ifdef _WIN_32
|
||||||
|
int WinNT()
|
||||||
|
{
|
||||||
|
static int dwPlatformId=-1,dwMajorVersion;
|
||||||
|
if (dwPlatformId==-1)
|
||||||
|
{
|
||||||
|
OSVERSIONINFO WinVer;
|
||||||
|
WinVer.dwOSVersionInfoSize=sizeof(WinVer);
|
||||||
|
GetVersionEx(&WinVer);
|
||||||
|
dwPlatformId=WinVer.dwPlatformId;
|
||||||
|
dwMajorVersion=WinVer.dwMajorVersion;
|
||||||
|
}
|
||||||
|
return(dwPlatformId==VER_PLATFORM_WIN32_NT ? dwMajorVersion:0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _RAR_ISNT_
|
||||||
|
#define _RAR_ISNT_
|
||||||
|
|
||||||
|
int WinNT();
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
****** ***** ****** UnRAR - free utility for RAR archives
|
||||||
|
** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
****** ******* ****** License for use and distribution of
|
||||||
|
** ** ** ** ** ** ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
** ** ** ** ** ** FREE portable version
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
The source code of UnRAR utility is freeware. This means:
|
||||||
|
|
||||||
|
1. All copyrights to RAR and the utility UnRAR are exclusively
|
||||||
|
owned by the author - Alexander Roshal.
|
||||||
|
|
||||||
|
2. The UnRAR sources may be used in any software to handle RAR
|
||||||
|
archives without limitations free of charge, but cannot be used
|
||||||
|
to re-create the RAR compression algorithm, which is proprietary.
|
||||||
|
Distribution of modified UnRAR sources in separate form or as a
|
||||||
|
part of other software is permitted, provided that it is clearly
|
||||||
|
stated in the documentation and source comments that the code may
|
||||||
|
not be used to develop a RAR (WinRAR) compatible archiver.
|
||||||
|
|
||||||
|
3. The UnRAR utility may be freely distributed. It is allowed
|
||||||
|
to distribute UnRAR inside of other software packages.
|
||||||
|
|
||||||
|
4. THE RAR ARCHIVER AND THE UnRAR UTILITY ARE DISTRIBUTED "AS IS".
|
||||||
|
NO WARRANTY OF ANY KIND IS EXPRESSED OR IMPLIED. YOU USE AT
|
||||||
|
YOUR OWN RISK. THE AUTHOR WILL NOT BE LIABLE FOR DATA LOSS,
|
||||||
|
DAMAGES, LOSS OF PROFITS OR ANY OTHER KIND OF LOSS WHILE USING
|
||||||
|
OR MISUSING THIS SOFTWARE.
|
||||||
|
|
||||||
|
5. Installing and using the UnRAR utility signifies acceptance of
|
||||||
|
these terms and conditions of the license.
|
||||||
|
|
||||||
|
6. If you don't agree with terms of the license you must remove
|
||||||
|
UnRAR files from your storage devices and cease to use the
|
||||||
|
utility.
|
||||||
|
|
||||||
|
Thank you for your interest in RAR and UnRAR.
|
||||||
|
|
||||||
|
|
||||||
|
Alexander L. Roshal
|
||||||
@@ -0,0 +1,383 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
static void ListFileHeader(FileHeader &hd,bool Verbose,bool Technical,bool &TitleShown,bool Bare);
|
||||||
|
static void ListSymLink(Archive &Arc);
|
||||||
|
static void ListFileAttr(uint A,int HostOS);
|
||||||
|
static void ListOldSubHeader(Archive &Arc);
|
||||||
|
static void ListNewSubHeader(CommandData *Cmd,Archive &Arc,bool Technical);
|
||||||
|
|
||||||
|
void ListArchive(CommandData *Cmd)
|
||||||
|
{
|
||||||
|
Int64 SumPackSize=0,SumUnpSize=0;
|
||||||
|
uint ArcCount=0,SumFileCount=0;
|
||||||
|
bool Technical=(Cmd->Command[1]=='T');
|
||||||
|
bool Bare=(Cmd->Command[1]=='B');
|
||||||
|
bool Verbose=(*Cmd->Command=='V');
|
||||||
|
|
||||||
|
char ArcName[NM];
|
||||||
|
wchar ArcNameW[NM];
|
||||||
|
|
||||||
|
while (Cmd->GetArcName(ArcName,ArcNameW,sizeof(ArcName)))
|
||||||
|
{
|
||||||
|
Archive Arc(Cmd);
|
||||||
|
#ifdef _WIN_32
|
||||||
|
Arc.RemoveSequentialFlag();
|
||||||
|
#endif
|
||||||
|
if (!Arc.WOpen(ArcName,ArcNameW))
|
||||||
|
continue;
|
||||||
|
bool FileMatched=true;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
Int64 TotalPackSize=0,TotalUnpSize=0;
|
||||||
|
uint FileCount=0;
|
||||||
|
if (Arc.IsArchive(true))
|
||||||
|
{
|
||||||
|
if (!Arc.IsOpened())
|
||||||
|
break;
|
||||||
|
bool TitleShown=false;
|
||||||
|
if (!Bare)
|
||||||
|
{
|
||||||
|
Arc.ViewComment();
|
||||||
|
mprintf("\n");
|
||||||
|
if (Arc.Solid)
|
||||||
|
mprintf(St(MListSolid));
|
||||||
|
if (Arc.SFXSize>0)
|
||||||
|
mprintf(St(MListSFX));
|
||||||
|
if (Arc.Volume)
|
||||||
|
if (Arc.Solid)
|
||||||
|
mprintf(St(MListVol1));
|
||||||
|
else
|
||||||
|
mprintf(St(MListVol2));
|
||||||
|
else
|
||||||
|
if (Arc.Solid)
|
||||||
|
mprintf(St(MListArc1));
|
||||||
|
else
|
||||||
|
mprintf(St(MListArc2));
|
||||||
|
mprintf(" %s\n",Arc.FileName);
|
||||||
|
if (Technical)
|
||||||
|
{
|
||||||
|
if (Arc.Protected)
|
||||||
|
mprintf(St(MListRecRec));
|
||||||
|
if (Arc.Locked)
|
||||||
|
mprintf(St(MListLock));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(Arc.ReadHeader()>0)
|
||||||
|
{
|
||||||
|
int HeaderType=Arc.GetHeaderType();
|
||||||
|
if (HeaderType==ENDARC_HEAD)
|
||||||
|
break;
|
||||||
|
switch(HeaderType)
|
||||||
|
{
|
||||||
|
case FILE_HEAD:
|
||||||
|
IntToExt(Arc.NewLhd.FileName,Arc.NewLhd.FileName);
|
||||||
|
if ((FileMatched=Cmd->IsProcessFile(Arc.NewLhd))==true)
|
||||||
|
{
|
||||||
|
ListFileHeader(Arc.NewLhd,Verbose,Technical,TitleShown,Bare);
|
||||||
|
if (!(Arc.NewLhd.Flags & LHD_SPLIT_BEFORE))
|
||||||
|
{
|
||||||
|
TotalUnpSize+=Arc.NewLhd.FullUnpSize;
|
||||||
|
FileCount++;
|
||||||
|
}
|
||||||
|
TotalPackSize+=Arc.NewLhd.FullPackSize;
|
||||||
|
if (Technical)
|
||||||
|
ListSymLink(Arc);
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (Verbose)
|
||||||
|
Arc.ViewFileComment();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
case SUB_HEAD:
|
||||||
|
if (Technical && FileMatched && !Bare)
|
||||||
|
ListOldSubHeader(Arc);
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
case NEWSUB_HEAD:
|
||||||
|
if (FileMatched && !Bare)
|
||||||
|
{
|
||||||
|
if (Technical)
|
||||||
|
ListFileHeader(Arc.SubHead,Verbose,true,TitleShown,false);
|
||||||
|
ListNewSubHeader(Cmd,Arc,Technical);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Arc.SeekToNext();
|
||||||
|
}
|
||||||
|
if (!Bare)
|
||||||
|
if (TitleShown)
|
||||||
|
{
|
||||||
|
mprintf("\n");
|
||||||
|
for (int I=0;I<79;I++)
|
||||||
|
mprintf("-");
|
||||||
|
char UnpSizeText[20];
|
||||||
|
itoa(TotalUnpSize,UnpSizeText);
|
||||||
|
|
||||||
|
char PackSizeText[20];
|
||||||
|
itoa(TotalPackSize,PackSizeText);
|
||||||
|
|
||||||
|
mprintf("\n%5lu %16s %8s %3d%%",FileCount,UnpSizeText,
|
||||||
|
PackSizeText,ToPercent(TotalPackSize,TotalUnpSize));
|
||||||
|
SumFileCount+=FileCount;
|
||||||
|
SumUnpSize+=TotalUnpSize;
|
||||||
|
SumPackSize+=TotalPackSize;
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (Arc.EndArcHead.Flags & EARC_VOLNUMBER)
|
||||||
|
{
|
||||||
|
mprintf(" ");
|
||||||
|
mprintf(St(MVolumeNumber),Arc.EndArcHead.VolNumber+1);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
mprintf("\n");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mprintf(St(MListNoFiles));
|
||||||
|
|
||||||
|
ArcCount++;
|
||||||
|
|
||||||
|
#ifndef NOVOLUME
|
||||||
|
if (Cmd->VolSize!=0 && ((Arc.NewLhd.Flags & LHD_SPLIT_AFTER) ||
|
||||||
|
Arc.GetHeaderType()==ENDARC_HEAD &&
|
||||||
|
(Arc.EndArcHead.Flags & EARC_NEXT_VOLUME)!=0) &&
|
||||||
|
MergeArchive(Arc,NULL,false,*Cmd->Command))
|
||||||
|
{
|
||||||
|
Arc.Seek(0,SEEK_SET);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Cmd->ArcNames->ItemsCount()<2 && !Bare)
|
||||||
|
mprintf(St(MNotRAR),Arc.FileName);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ArcCount>1 && !Bare)
|
||||||
|
{
|
||||||
|
char UnpSizeText[20],PackSizeText[20];
|
||||||
|
itoa(SumUnpSize,UnpSizeText);
|
||||||
|
itoa(SumPackSize,PackSizeText);
|
||||||
|
mprintf("\n%5lu %16s %8s %3d%%\n",SumFileCount,UnpSizeText,
|
||||||
|
PackSizeText,ToPercent(SumPackSize,SumUnpSize));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ListFileHeader(FileHeader &hd,bool Verbose,bool Technical,bool &TitleShown,bool Bare)
|
||||||
|
{
|
||||||
|
if (!Bare)
|
||||||
|
{
|
||||||
|
if (!TitleShown)
|
||||||
|
{
|
||||||
|
if (Verbose)
|
||||||
|
mprintf(St(MListPathComm));
|
||||||
|
else
|
||||||
|
mprintf(St(MListName));
|
||||||
|
mprintf(St(MListTitle));
|
||||||
|
if (Technical)
|
||||||
|
mprintf(St(MListTechTitle));
|
||||||
|
for (int I=0;I<79;I++)
|
||||||
|
mprintf("-");
|
||||||
|
TitleShown=true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hd.HeadType==NEWSUB_HEAD)
|
||||||
|
mprintf(St(MSubHeadType),hd.FileName);
|
||||||
|
|
||||||
|
mprintf("\n%c",(hd.Flags & LHD_PASSWORD) ? '*' : ' ');
|
||||||
|
}
|
||||||
|
|
||||||
|
char *Name=hd.FileName;
|
||||||
|
|
||||||
|
#ifdef UNICODE_SUPPORTED
|
||||||
|
char ConvertedName[NM];
|
||||||
|
if ((hd.Flags & LHD_UNICODE)!=0 && *hd.FileNameW!=0 && UnicodeEnabled())
|
||||||
|
{
|
||||||
|
if (WideToChar(hd.FileNameW,ConvertedName) && *ConvertedName!=0)
|
||||||
|
Name=ConvertedName;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (Bare)
|
||||||
|
{
|
||||||
|
mprintf("%s\n",Verbose ? Name:PointToName(Name));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Verbose)
|
||||||
|
mprintf("%s\n%12s ",Name,"");
|
||||||
|
else
|
||||||
|
mprintf("%-12s",PointToName(Name));
|
||||||
|
|
||||||
|
char UnpSizeText[20],PackSizeText[20];
|
||||||
|
if (hd.FullUnpSize==INT64MAX)
|
||||||
|
strcpy(UnpSizeText,"?");
|
||||||
|
else
|
||||||
|
itoa(hd.FullUnpSize,UnpSizeText);
|
||||||
|
itoa(hd.FullPackSize,PackSizeText);
|
||||||
|
|
||||||
|
mprintf(" %8s %8s ",UnpSizeText,PackSizeText);
|
||||||
|
|
||||||
|
if ((hd.Flags & LHD_SPLIT_BEFORE) && (hd.Flags & LHD_SPLIT_AFTER))
|
||||||
|
mprintf(" <->");
|
||||||
|
else
|
||||||
|
if (hd.Flags & LHD_SPLIT_BEFORE)
|
||||||
|
mprintf(" <--");
|
||||||
|
else
|
||||||
|
if (hd.Flags & LHD_SPLIT_AFTER)
|
||||||
|
mprintf(" -->");
|
||||||
|
else
|
||||||
|
mprintf("%3d%%",ToPercent(hd.FullPackSize,hd.FullUnpSize));
|
||||||
|
|
||||||
|
char DateStr[50];
|
||||||
|
hd.mtime.GetText(DateStr,false);
|
||||||
|
mprintf(" %s ",DateStr);
|
||||||
|
|
||||||
|
if (hd.HeadType==NEWSUB_HEAD)
|
||||||
|
mprintf(" %c....B ",(hd.SubFlags & SUBHEAD_FLAGS_INHERITED) ? 'I' : '.');
|
||||||
|
else
|
||||||
|
ListFileAttr(hd.FileAttr,hd.HostOS);
|
||||||
|
|
||||||
|
mprintf(" %8.8X",hd.FileCRC);
|
||||||
|
mprintf(" m%d",hd.Method-0x30);
|
||||||
|
if ((hd.Flags & LHD_WINDOWMASK)<=6*32)
|
||||||
|
mprintf("%c",((hd.Flags&LHD_WINDOWMASK)>>5)+'a');
|
||||||
|
else
|
||||||
|
mprintf(" ");
|
||||||
|
mprintf(" %d.%d",hd.UnpVer/10,hd.UnpVer%10);
|
||||||
|
|
||||||
|
static const char *RarOS[]={
|
||||||
|
"DOS","OS/2","Win95/NT","Unix","MacOS","BeOS","WinCE","","",""
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Technical)
|
||||||
|
mprintf("\n%22s %8s %4s",
|
||||||
|
(hd.HostOS<sizeof(RarOS)/sizeof(RarOS[0]) ? RarOS[hd.HostOS]:""),
|
||||||
|
(hd.Flags & LHD_SOLID) ? St(MYes):St(MNo),
|
||||||
|
(hd.Flags & LHD_VERSION) ? St(MYes):St(MNo));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ListSymLink(Archive &Arc)
|
||||||
|
{
|
||||||
|
if (Arc.NewLhd.HostOS==HOST_UNIX && (Arc.NewLhd.FileAttr & 0xF000)==0xA000)
|
||||||
|
{
|
||||||
|
char FileName[NM];
|
||||||
|
int DataSize=Min(Arc.NewLhd.PackSize,sizeof(FileName)-1);
|
||||||
|
Arc.Read(FileName,DataSize);
|
||||||
|
FileName[DataSize]=0;
|
||||||
|
mprintf("\n%22s %s","-->",FileName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ListFileAttr(uint A,int HostOS)
|
||||||
|
{
|
||||||
|
switch(HostOS)
|
||||||
|
{
|
||||||
|
case HOST_MSDOS:
|
||||||
|
case HOST_OS2:
|
||||||
|
case HOST_WIN32:
|
||||||
|
case HOST_MACOS:
|
||||||
|
mprintf(" %c%c%c%c%c%c%c ",
|
||||||
|
(A & 0x08) ? 'V' : '.',
|
||||||
|
(A & 0x10) ? 'D' : '.',
|
||||||
|
(A & 0x01) ? 'R' : '.',
|
||||||
|
(A & 0x02) ? 'H' : '.',
|
||||||
|
(A & 0x04) ? 'S' : '.',
|
||||||
|
(A & 0x20) ? 'A' : '.',
|
||||||
|
(A & 0x800) ? 'C' : '.');
|
||||||
|
break;
|
||||||
|
case HOST_UNIX:
|
||||||
|
case HOST_BEOS:
|
||||||
|
switch (A & 0xF000)
|
||||||
|
{
|
||||||
|
case 0x4000:
|
||||||
|
mprintf("d");
|
||||||
|
break;
|
||||||
|
case 0xA000:
|
||||||
|
mprintf("l");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mprintf("-");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mprintf("%c%c%c%c%c%c%c%c%c",
|
||||||
|
(A & 0x0100) ? 'r' : '-',
|
||||||
|
(A & 0x0080) ? 'w' : '-',
|
||||||
|
(A & 0x0040) ? ((A & 0x0800) ? 's':'x'):((A & 0x0800) ? 'S':'-'),
|
||||||
|
(A & 0x0020) ? 'r' : '-',
|
||||||
|
(A & 0x0010) ? 'w' : '-',
|
||||||
|
(A & 0x0008) ? ((A & 0x0400) ? 's':'x'):((A & 0x0400) ? 'S':'-'),
|
||||||
|
(A & 0x0004) ? 'r' : '-',
|
||||||
|
(A & 0x0002) ? 'w' : '-',
|
||||||
|
(A & 0x0001) ? 'x' : '-');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
void ListOldSubHeader(Archive &Arc)
|
||||||
|
{
|
||||||
|
switch(Arc.SubBlockHead.SubType)
|
||||||
|
{
|
||||||
|
case EA_HEAD:
|
||||||
|
mprintf(St(MListEAHead));
|
||||||
|
break;
|
||||||
|
case UO_HEAD:
|
||||||
|
mprintf(St(MListUOHead),Arc.UOHead.OwnerName,Arc.UOHead.GroupName);
|
||||||
|
break;
|
||||||
|
case MAC_HEAD:
|
||||||
|
mprintf(St(MListMACHead1),Arc.MACHead.fileType>>24,Arc.MACHead.fileType>>16,Arc.MACHead.fileType>>8,Arc.MACHead.fileType);
|
||||||
|
mprintf(St(MListMACHead2),Arc.MACHead.fileCreator>>24,Arc.MACHead.fileCreator>>16,Arc.MACHead.fileCreator>>8,Arc.MACHead.fileCreator);
|
||||||
|
break;
|
||||||
|
case BEEA_HEAD:
|
||||||
|
mprintf(St(MListBeEAHead));
|
||||||
|
break;
|
||||||
|
case NTACL_HEAD:
|
||||||
|
mprintf(St(MListNTACLHead));
|
||||||
|
break;
|
||||||
|
case STREAM_HEAD:
|
||||||
|
mprintf(St(MListStrmHead),Arc.StreamHead.StreamName);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mprintf(St(MListUnkHead),Arc.SubBlockHead.SubType);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
void ListNewSubHeader(CommandData *Cmd,Archive &Arc,bool Technical)
|
||||||
|
{
|
||||||
|
if (Technical && Arc.SubHead.CmpName(SUBHEAD_TYPE_CMT) &&
|
||||||
|
(Arc.SubHead.Flags & LHD_SPLIT_BEFORE)==0 && !Cmd->DisableComment)
|
||||||
|
{
|
||||||
|
Array<byte> CmtData;
|
||||||
|
int ReadSize=Arc.ReadCommentData(&CmtData,NULL);
|
||||||
|
if (ReadSize!=0)
|
||||||
|
{
|
||||||
|
mprintf(St(MFileComment));
|
||||||
|
OutComment((char *)&CmtData[0],ReadSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Arc.SubHead.CmpName(SUBHEAD_TYPE_STREAM) &&
|
||||||
|
(Arc.SubHead.Flags & LHD_SPLIT_BEFORE)==0)
|
||||||
|
{
|
||||||
|
int DestSize=Arc.SubHead.SubData.Size()/2;
|
||||||
|
wchar DestNameW[NM];
|
||||||
|
char DestName[NM];
|
||||||
|
if (DestSize<sizeof(DestName))
|
||||||
|
{
|
||||||
|
RawToWide(&Arc.SubHead.SubData[0],DestNameW,DestSize);
|
||||||
|
DestNameW[DestSize]=0;
|
||||||
|
WideToChar(DestNameW,DestName);
|
||||||
|
mprintf("\n %s",DestName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#ifndef _RAR_LIST_
|
||||||
|
#define _RAR_LIST_
|
||||||
|
|
||||||
|
void ListArchive(CommandData *Cmd);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,347 @@
|
|||||||
|
#define MYesNo "_Yes_No"
|
||||||
|
#define MYesNoAll "_Yes_No_All"
|
||||||
|
#define MYesNoAllRenQ "_Yes_No_All_nEver_Rename_Quit"
|
||||||
|
#define MContinueQuit "_Continue_Quit"
|
||||||
|
#define MRetryAbort "_Retry_Abort"
|
||||||
|
#define MCopyright "\nRAR %s Copyright (c) 1993-%d Alexander Roshal %d %s %d"
|
||||||
|
#define MRegTo "\nRegistered to %s\n"
|
||||||
|
#define MShare "\nShareware version Type RAR -? for help\n"
|
||||||
|
#define MUCopyright "\nUNRAR %s freeware Copyright (c) 1993-%d Alexander Roshal\n"
|
||||||
|
#define MBeta "beta"
|
||||||
|
#define MMonthJan "Jan"
|
||||||
|
#define MMonthFeb "Feb"
|
||||||
|
#define MMonthMar "Mar"
|
||||||
|
#define MMonthApr "Apr"
|
||||||
|
#define MMonthMay "May"
|
||||||
|
#define MMonthJun "Jun"
|
||||||
|
#define MMonthJul "Jul"
|
||||||
|
#define MMonthAug "Aug"
|
||||||
|
#define MMonthSep "Sep"
|
||||||
|
#define MMonthOct "Oct"
|
||||||
|
#define MMonthNov "Nov"
|
||||||
|
#define MMonthDec "Dec"
|
||||||
|
#define MRARTitle1 "\nUsage: rar <command> -<switch 1> -<switch N> <archive> <files...>"
|
||||||
|
#define MUNRARTitle1 "\nUsage: unrar <command> -<switch 1> -<switch N> <archive> <files...>"
|
||||||
|
#define MRARTitle2 "\n <@listfiles...> <path_to_extract\\>"
|
||||||
|
#define MCHelpCmd "\n\n<Commands>"
|
||||||
|
#define MCHelpCmdA "\n a Add files to archive"
|
||||||
|
#define MCHelpCmdC "\n c Add archive comment"
|
||||||
|
#define MCHelpCmdCF "\n cf Add files comment"
|
||||||
|
#define MCHelpCmdCH "\n ch Change archive parameters"
|
||||||
|
#define MCHelpCmdCW "\n cw Write archive comment to file"
|
||||||
|
#define MCHelpCmdD "\n d Delete files from archive"
|
||||||
|
#define MCHelpCmdE "\n e Extract files to current directory"
|
||||||
|
#define MCHelpCmdF "\n f Freshen files in archive"
|
||||||
|
#define MCHelpCmdI "\n i[par]=<str> Find string in archives"
|
||||||
|
#define MCHelpCmdK "\n k Lock archive"
|
||||||
|
#define MCHelpCmdL "\n l[t,b] List archive [technical, bare]"
|
||||||
|
#define MCHelpCmdM "\n m[f] Move to archive [files only]"
|
||||||
|
#define MCHelpCmdP "\n p Print file to stdout"
|
||||||
|
#define MCHelpCmdR "\n r Repair archive"
|
||||||
|
#define MCHelpCmdRC "\n rc Reconstruct missing volumes"
|
||||||
|
#define MCHelpCmdRN "\n rn Rename archived files"
|
||||||
|
#define MCHelpCmdRR "\n rr[N] Add data recovery record"
|
||||||
|
#define MCHelpCmdRV "\n rv[N] Create recovery volumes"
|
||||||
|
#define MCHelpCmdS "\n s[name|-] Convert archive to or from SFX"
|
||||||
|
#define MCHelpCmdT "\n t Test archive files"
|
||||||
|
#define MCHelpCmdU "\n u Update files in archive"
|
||||||
|
#define MCHelpCmdV "\n v[t,b] Verbosely list archive [technical,bare]"
|
||||||
|
#define MCHelpCmdX "\n x Extract files with full path"
|
||||||
|
#define MCHelpSw "\n\n<Switches>"
|
||||||
|
#define MCHelpSwm "\n - Stop switches scanning"
|
||||||
|
#define MCHelpSwAC "\n ac Clear Archive attribute after compression or extraction"
|
||||||
|
#define MCHelpSwAD "\n ad Append archive name to destination path"
|
||||||
|
#define MCHelpSwAG "\n ag[format] Generate archive name using the current date"
|
||||||
|
#define MCHelpSwAO "\n ao Add files with Archive attribute set"
|
||||||
|
#define MCHelpSwAP "\n ap<path> Set path inside archive"
|
||||||
|
#define MCHelpSwAS "\n as Synchronize archive contents"
|
||||||
|
#define MCHelpSwAV "\n av Put authenticity verification (registered versions only)"
|
||||||
|
#define MCHelpSwAVm "\n av- Disable authenticity verification check"
|
||||||
|
#define MCHelpSwCm "\n c- Disable comments show"
|
||||||
|
#define MCHelpSwCFGm "\n cfg- Disable read configuration"
|
||||||
|
#define MCHelpSwCL "\n cl Convert names to lower case"
|
||||||
|
#define MCHelpSwCU "\n cu Convert names to upper case"
|
||||||
|
#define MCHelpSwDF "\n df Delete files after archiving"
|
||||||
|
#define MCHelpSwDH "\n dh Open shared files"
|
||||||
|
#define MCHelpSwDS "\n ds Disable name sort for solid archive"
|
||||||
|
#define MCHelpSwEa "\n e[+]<attr> Set file exclude and include attributes"
|
||||||
|
#define MCHelpSwED "\n ed Do not add empty directories"
|
||||||
|
#define MCHelpSwEE "\n ee Do not save and extract extended attributes"
|
||||||
|
#define MCHelpSwEN "\n en Do not put 'end of archive' block"
|
||||||
|
#define MCHelpSwEP "\n ep Exclude paths from names"
|
||||||
|
#define MCHelpSwEP1 "\n ep1 Exclude base directory from names"
|
||||||
|
#define MCHelpSwEP2 "\n ep2 Expand paths to full"
|
||||||
|
#define MCHelpSwEP3 "\n ep3 Expand paths to full including the drive letter"
|
||||||
|
#define MCHelpSwF "\n f Freshen files"
|
||||||
|
#define MCHelpSwFCU "\n fcu[file] Read archive comment from Unicode file"
|
||||||
|
#define MCHelpSwHP "\n hp[password] Encrypt both file data and headers"
|
||||||
|
#define MCHelpSwIDP "\n id[c,d,p,q] Disable messages"
|
||||||
|
#define MCHelpSwIEML "\n ieml[addr] Send archive by email"
|
||||||
|
#define MCHelpSwIERR "\n ierr Send all messages to stderr"
|
||||||
|
#define MCHelpSwILOG "\n ilog[name] Log errors to file (registered versions only)"
|
||||||
|
#define MCHelpSwINUL "\n inul Disable all messages"
|
||||||
|
#define MCHelpSwIOFF "\n ioff Turn PC off after completing an operation"
|
||||||
|
#define MCHelpSwISND "\n isnd Enable sound"
|
||||||
|
#define MCHelpSwK "\n k Lock archive"
|
||||||
|
#define MCHelpSwKB "\n kb Keep broken extracted files"
|
||||||
|
#define MCHelpSwMn "\n m<0..5> Set compression level (0-store...3-default...5-maximal)"
|
||||||
|
#define MCHelpSwMC "\n mc<par> Set advanced compression parameters"
|
||||||
|
#define MCHelpSwMD "\n md<size> Dictionary size in KB (64,128,256,512,1024,2048,4096 or A-G)"
|
||||||
|
#define MCHelpSwMS "\n ms[ext;ext] Specify file types to store"
|
||||||
|
#define MCHelpSwMT "\n mt<threads> Set the number of threads"
|
||||||
|
#define MCHelpSwN "\n n<file> Include only specified file"
|
||||||
|
#define MCHelpSwNa "\n n@ Read file names to include from stdin"
|
||||||
|
#define MCHelpSwNal "\n n@<list> Include files in specified list file"
|
||||||
|
#define MCHelpSwOp "\n o+ Overwrite existing files"
|
||||||
|
#define MCHelpSwOm "\n o- Do not overwrite existing files"
|
||||||
|
#define MCHelpSwOC "\n oc Set NTFS Compressed attribute"
|
||||||
|
#define MCHelpSwOL "\n ol Save symbolic links as the link instead of the file"
|
||||||
|
#define MCHelpSwOR "\n or Rename files automatically"
|
||||||
|
#define MCHelpSwOS "\n os Save NTFS streams"
|
||||||
|
#define MCHelpSwOW "\n ow Save or restore file owner and group"
|
||||||
|
#define MCHelpSwP "\n p[password] Set password"
|
||||||
|
#define MCHelpSwPm "\n p- Do not query password"
|
||||||
|
#define MCHelpSwR "\n r Recurse subdirectories"
|
||||||
|
#define MCHelpSwR0 "\n r0 Recurse subdirectories for wildcard names only"
|
||||||
|
#define MCHelpSwRI "\n ri<P>[:<S>] Set priority (0-default,1-min..15-max) and sleep time in ms"
|
||||||
|
#define MCHelpSwRR "\n rr[N] Add data recovery record"
|
||||||
|
#define MCHelpSwRV "\n rv[N] Create recovery volumes"
|
||||||
|
#define MCHelpSwS "\n s[<N>,v[-],e] Create solid archive"
|
||||||
|
#define MCHelpSwSm "\n s- Disable solid archiving"
|
||||||
|
#define MCHelpSwSFX "\n sfx[name] Create SFX archive"
|
||||||
|
#define MCHelpSwSI "\n si[name] Read data from standard input (stdin)"
|
||||||
|
#define MCHelpSwSL "\n sl<size> Process files with size less than specified"
|
||||||
|
#define MCHelpSwSM "\n sm<size> Process files with size more than specified"
|
||||||
|
#define MCHelpSwT "\n t Test files after archiving"
|
||||||
|
#define MCHelpSwTK "\n tk Keep original archive time"
|
||||||
|
#define MCHelpSwTL "\n tl Set archive time to latest file"
|
||||||
|
#define MCHelpSwTN "\n tn<time> Process files newer than <time>"
|
||||||
|
#define MCHelpSwTO "\n to<time> Process files older than <time>"
|
||||||
|
#define MCHelpSwTA "\n ta<date> Process files modified after <date> in YYYYMMDDHHMMSS format"
|
||||||
|
#define MCHelpSwTB "\n tb<date> Process files modified before <date> in YYYYMMDDHHMMSS format"
|
||||||
|
#define MCHelpSwTS "\n ts<m,c,a>[N] Save or restore file time (modification, creation, access)"
|
||||||
|
#define MCHelpSwU "\n u Update files"
|
||||||
|
#define MCHelpSwV "\n v Create volumes with size autodetection or list all volumes"
|
||||||
|
#define MCHelpSwVUnr "\n v List all volumes"
|
||||||
|
#define MCHelpSwVn "\n v<size>[k,b] Create volumes with size=<size>*1000 [*1024, *1]"
|
||||||
|
#define MCHelpSwVD "\n vd Erase disk contents before creating volume"
|
||||||
|
#define MCHelpSwVER "\n ver[n] File version control"
|
||||||
|
#define MCHelpSwVN "\n vn Use the old style volume naming scheme"
|
||||||
|
#define MCHelpSwVP "\n vp Pause before each volume"
|
||||||
|
#define MCHelpSwW "\n w<path> Assign work directory"
|
||||||
|
#define MCHelpSwX "\n x<file> Exclude specified file"
|
||||||
|
#define MCHelpSwXa "\n x@ Read file names to exclude from stdin"
|
||||||
|
#define MCHelpSwXal "\n x@<list> Exclude files in specified list file"
|
||||||
|
#define MCHelpSwY "\n y Assume Yes on all queries"
|
||||||
|
#define MCHelpSwZ "\n z[file] Read archive comment from file"
|
||||||
|
#define MBadArc "\nERROR: Bad archive %s\n"
|
||||||
|
#define MAskPsw "Enter password (will not be echoed)"
|
||||||
|
#define MAskPswEcho "Enter password"
|
||||||
|
#define MReAskPsw "\nReenter password: "
|
||||||
|
#define MFor " for "
|
||||||
|
#define MNotMatchPsw "\nERROR: Passwords do not match\n"
|
||||||
|
#define MErrWrite "Write error in the file %s"
|
||||||
|
#define MErrRead "Read error in the file %s"
|
||||||
|
#define MErrSeek "Seek error in the file %s"
|
||||||
|
#define MErrFClose "Cannot close the file %s"
|
||||||
|
#define MErrOutMem "Not enough memory"
|
||||||
|
#define MErrBrokenArc "Corrupt archive - use 'Repair' command"
|
||||||
|
#define MProgAborted "Program aborted"
|
||||||
|
#define MErrRename "\nCannot rename %s to %s"
|
||||||
|
#define MAbsNextVol "\nCannot find volume %s"
|
||||||
|
#define MBreak "\nUser break\n"
|
||||||
|
#define MAskCreatVol "\nCreate next volume ?"
|
||||||
|
#define MAskNextDisk "\nDisk full. Insert next"
|
||||||
|
#define MCreatVol "\n\nCreating %sarchive %s\n"
|
||||||
|
#define MAskNextVol "\nInsert disk with %s"
|
||||||
|
#define MTestVol "\n\nTesting archive %s\n"
|
||||||
|
#define MExtrVol "\n\nExtracting from %s\n"
|
||||||
|
#define MConverting "\nConverting %s"
|
||||||
|
#define MCvtToSFX "\nConvert archives to SFX"
|
||||||
|
#define MCvtFromSFX "\nRemoving SFX module"
|
||||||
|
#define MNotSFX "\n%s is not SFX archive"
|
||||||
|
#define MNotRAR "\n%s is not RAR archive"
|
||||||
|
#define MNotFirstVol "\n%s is not the first volume"
|
||||||
|
#define MCvtOldFormat "\n%s - cannot convert to SFX archive with old format"
|
||||||
|
#define MCannotCreate "\nCannot create %s"
|
||||||
|
#define MCannotOpen "\nCannot open %s"
|
||||||
|
#define MUnknownMeth "\nUnknown method in %s"
|
||||||
|
#define MVerRequired "\nYou need RAR %d.%d to unpack it"
|
||||||
|
#define MOk " OK"
|
||||||
|
#define MDone "\nDone"
|
||||||
|
#define MLockingArc "\nLocking archive"
|
||||||
|
#define MNotMdfOld "\n\nERROR: Cannot modify old format archive"
|
||||||
|
#define MNotMdfLock "\n\nERROR: Locked archive"
|
||||||
|
#define MNotMdfVol "\n\nERROR: Cannot modify volume"
|
||||||
|
#define MVerifyAV "\nVerifying authenticity information ... "
|
||||||
|
#define MFailedAV " Failed\n"
|
||||||
|
#define MStrAV1 "\n\nArchive %s"
|
||||||
|
#define MStrAV2 "\ncreated at %s"
|
||||||
|
#define MStrAV3 "\nby %s\n"
|
||||||
|
#define MLogFailedAV "Invalid authenticity information"
|
||||||
|
#define MAddingAV "\nAdding authenticity verification "
|
||||||
|
#define MAVOldStyle "\n\nOld style authenticity information"
|
||||||
|
#define MPackAskReg "\nEvaluation copy. Please register.\n"
|
||||||
|
#define MCreateArchive "\nCreating %sarchive %s\n"
|
||||||
|
#define MUpdateArchive "\nUpdating %sarchive %s\n"
|
||||||
|
#define MAddSolid "solid "
|
||||||
|
#define MAddFile "\nAdding %-58s "
|
||||||
|
#define MUpdFile "\nUpdating %-58s "
|
||||||
|
#define MAddPoints "\n... %-58s "
|
||||||
|
#define MCannotUpdPswSolid "\nERROR: Cannot update solid archives with password\n"
|
||||||
|
#define MMoveDelFiles "\n\nDeleting files %s..."
|
||||||
|
#define MMoveDelDirs "and directories"
|
||||||
|
#define MMoveDelFile "\nDeleting %-30s"
|
||||||
|
#define MMoveDeleted " deleted"
|
||||||
|
#define MMoveNotDeleted " NOT DELETED"
|
||||||
|
#define MClearAttrib "\n\nClearing attributes..."
|
||||||
|
#define MMoveDelDir "\nDeleting directory %-30s"
|
||||||
|
#define MWarErrFOpen "\nWARNING: Cannot open %d %s"
|
||||||
|
#define MErrOpenFiles "files"
|
||||||
|
#define MErrOpenFile "file"
|
||||||
|
#define MAddNoFiles "\nWARNING: No files"
|
||||||
|
#define MMdfEncrSol "\n%s: encrypted"
|
||||||
|
#define MCannotMdfEncrSol "\nCannot modify solid archive containing encrypted files"
|
||||||
|
#define MAddAnalyze "\nAnalyzing archived files: "
|
||||||
|
#define MRepacking "\nRepacking archived files: "
|
||||||
|
#define MCRCFailed "\n%-20s - CRC failed"
|
||||||
|
#define MExtrTest "\n\nTesting archive %s\n"
|
||||||
|
#define MExtracting "\n\nExtracting from %s\n"
|
||||||
|
#define MUseCurPsw "\n%s - use current password ?"
|
||||||
|
#define MCreatDir "\nCreating %-56s"
|
||||||
|
#define MExtrSkipFile "\nSkipping %-56s"
|
||||||
|
#define MExtrTestFile "\nTesting %-56s"
|
||||||
|
#define MExtrFile "\nExtracting %-56s"
|
||||||
|
#define MExtrPoints "\n... %-56s"
|
||||||
|
#define MExtrErrMkDir "\nCannot create directory %s"
|
||||||
|
#define MExtrPrinting "\n------ Printing %s\n\n"
|
||||||
|
#define MEncrBadCRC "\nEncrypted file: CRC failed in %s (password incorrect ?)"
|
||||||
|
#define MExtrNoFiles "\nNo files to extract"
|
||||||
|
#define MExtrAllOk "\nAll OK"
|
||||||
|
#define MExtrTotalErr "\nTotal errors: %ld"
|
||||||
|
#define MFileExists "\n\n%s already exists. Overwrite it ?"
|
||||||
|
#define MAskOverwrite "\nOverwrite %s ?"
|
||||||
|
#define MAskNewName "\nEnter new name: "
|
||||||
|
#define MLogMainHead "\nThe archive header is corrupt"
|
||||||
|
#define MLogFileHead "\n%s - the file header is corrupt"
|
||||||
|
#define MLogCommHead "\nThe comment header is corrupt\n"
|
||||||
|
#define MLogProtectHead "The data recovery header is corrupt"
|
||||||
|
#define MReadStdinCmt "\nReading comment from stdin\n"
|
||||||
|
#define MReadCommFrom "\nReading comment from %s"
|
||||||
|
#define MDelComment "\nDeleting comment from %s"
|
||||||
|
#define MAddComment "\nAdding comment to %s"
|
||||||
|
#define MFCommAdd "\nAdding file comments"
|
||||||
|
#define MAskFComm "\n\nReading comment for %s : %s from stdin\n"
|
||||||
|
#define MLogCommBrk "\nThe archive comment is corrupt"
|
||||||
|
#define MCommAskCont "\nPress 'Enter' to continue or 'Q' to quit:"
|
||||||
|
#define MLogBrokFCmt "\nThe file comment is corrupt"
|
||||||
|
#define MAbsDestName "\nDestination file name required"
|
||||||
|
#define MWriteCommTo "\nWrite comment to %s"
|
||||||
|
#define MCommNotPres "\nComment is not present"
|
||||||
|
#define MDelFrom "\nDeleting from %s"
|
||||||
|
#define MDeleting "\nDeleting %s"
|
||||||
|
#define MEraseArc "\nErasing empty archive %s"
|
||||||
|
#define MNoDelFiles "\nNo files to delete"
|
||||||
|
#define MLogTitle "\n\n-------- %2d %s %d, archive %s\n"
|
||||||
|
#define MPathTooLong "\nERROR: Path too long\n"
|
||||||
|
#define MListSolid "Solid "
|
||||||
|
#define MListSFX "SFX "
|
||||||
|
#define MListVol1 "volume"
|
||||||
|
#define MListVol2 "Volume"
|
||||||
|
#define MListArc1 "archive"
|
||||||
|
#define MListArc2 "Archive"
|
||||||
|
#define MListRecRec "\nRecovery record is present\n"
|
||||||
|
#define MListLock "\nLock is present\n"
|
||||||
|
#define MListPathComm "\nPathname/Comment\n "
|
||||||
|
#define MListName "\n Name "
|
||||||
|
#define MListTitle " Size Packed Ratio Date Time Attr CRC Meth Ver\n"
|
||||||
|
#define MListTechTitle " Host OS Solid Old\n"
|
||||||
|
#define MListEAHead "\n OS/2 extended attributes"
|
||||||
|
#define MListUOHead "\n Unix Owner/Group data: %-14s %-14s"
|
||||||
|
#define MListBeEAHead "\n BeOS extended attributes"
|
||||||
|
#define MListNTACLHead "\n NTFS security data"
|
||||||
|
#define MListStrmHead "\n NTFS stream: %s"
|
||||||
|
#define MListUnkHead "\n Unknown subheader type: 0x%04x"
|
||||||
|
#define MFileComment "\nComment: "
|
||||||
|
#define MYes "Yes"
|
||||||
|
#define MNo "No"
|
||||||
|
#define MListNoFiles " 0 files\n"
|
||||||
|
#define MRprReconstr "\nReconstructing %s"
|
||||||
|
#define MRprBuild "\nBuilding %s"
|
||||||
|
#define MRprOldFormat "\nCannot repair archive with old format"
|
||||||
|
#define MRprFind "\nFound %s"
|
||||||
|
#define MRprAskIsSol "\nThe archive header is corrupt. Mark archive as solid ?"
|
||||||
|
#define MRprNoFiles "\nNo files found"
|
||||||
|
#define MRprSuspEntry "\n\nSuspicious entry %s"
|
||||||
|
#define MRprDir "\nDirectory"
|
||||||
|
#define MRprSuspSize "\nSize %ld Packed %ld"
|
||||||
|
#define MRprSuspAdd "\nAdd it to archive ?"
|
||||||
|
#define MLogUnexpEOF "\nUnexpected end of archive"
|
||||||
|
#define MRepAskReconst "\nReconstruct archive structure ?"
|
||||||
|
#define MRecScanning "\nScanning..."
|
||||||
|
#define MRecRNotFound "\nData recovery record not found"
|
||||||
|
#define MRecRFound "\nData recovery record found"
|
||||||
|
#define MRecSecDamage "\nSector %ld (offsets %lX...%lX) damaged"
|
||||||
|
#define MRecCorrected " - data recovered"
|
||||||
|
#define MRecFailed " - cannot recover data"
|
||||||
|
#define MAddRecRec "\nAdding data recovery record"
|
||||||
|
#define MEraseForVolume "\n\nErasing contents of drive %c:\n"
|
||||||
|
#define MGetOwnersError "\nWARNING: Cannot get %s owner and group\n"
|
||||||
|
#define MErrGetOwnerID "\nWARNING: Cannot get owner %s ID\n"
|
||||||
|
#define MErrGetGroupID "\nWARNING: Cannot get group %s ID\n"
|
||||||
|
#define MOwnersBroken "\nERROR: %s group and owner data are corrupt\n"
|
||||||
|
#define MSetOwnersError "\nWARNING: Cannot set %s owner and group\n"
|
||||||
|
#define MErrLnkRead "\nWARNING: Cannot read symbolic link %s"
|
||||||
|
#define MErrCreateLnk "\nWARNING: Cannot create link %s"
|
||||||
|
#define MSymLinkExists "\nWARNING: Symbolic link %s already exists"
|
||||||
|
#define MAskRetryCreate "\nCannot create %s. Retry ?"
|
||||||
|
#define MListMACHead1 "\n MacOS file type: %c%c%c%c ; "
|
||||||
|
#define MListMACHead2 "file creator: %c%c%c%c\n"
|
||||||
|
#define MDataBadCRC "\n%-20s : packed data CRC failed in volume %s"
|
||||||
|
#define MFileRO "\n%s is read-only"
|
||||||
|
#define MACLGetError "\nWARNING: Cannot get %s security data\n"
|
||||||
|
#define MACLSetError "\nWARNING: Cannot set %s security data\n"
|
||||||
|
#define MACLBroken "\nERROR: %s security data are corrupt\n"
|
||||||
|
#define MACLUnknown "\nWARNING: Unknown format of %s security data\n"
|
||||||
|
#define MStreamBroken "\nERROR: %s stream data are corrupt\n"
|
||||||
|
#define MStreamUnknown "\nWARNING: Unknown format of %s stream data\n"
|
||||||
|
#define MInvalidName "\nERROR: Invalid file name %s"
|
||||||
|
#define MEABroken "\nERROR: %s extended attributes are corrupt\n"
|
||||||
|
#define MEAUnknHeader "\nWARNING: %s - unknown format of extended attributes\n"
|
||||||
|
#define MCannotSetEA "\nWARNING: cannot set extended attributes to %s\n"
|
||||||
|
#define MCannotGetEA "\nERROR: Cannot get extended attributes of %s\n"
|
||||||
|
#define MShowEA " (+EA)"
|
||||||
|
#define MSkipEA "\n...skipping extended attributes"
|
||||||
|
#define MProcessArc "\n\nProcessing archive %s"
|
||||||
|
#define MSyncScanError "\nFile search errors, cannot synchronize archive"
|
||||||
|
#define MCorrectingName "\nWARNING: Attempting to correct the invalid file name"
|
||||||
|
#define MUnpCannotMerge "\nWARNING: You need to start extraction from a previous volume to unpack %s"
|
||||||
|
#define MUnknownOption "\nERROR: Unknown option: %s"
|
||||||
|
#define MSubHeadCorrupt "\nERROR: Corrupt data header found, ignored"
|
||||||
|
#define MSubHeadUnknown "\nWARNING: Unknown data header format, ignored"
|
||||||
|
#define MSubHeadDataCRC "\nERROR: Corrupt %s data block"
|
||||||
|
#define MSubHeadType "\nData header type: %s"
|
||||||
|
#define MScanError "\nCannot read contents of %s"
|
||||||
|
#define MNotVolume "\n%s is not volume"
|
||||||
|
#define MRecVolDiffSets "\nERROR: %s and %s belong to different sets"
|
||||||
|
#define MRecVolMissing "\n%d volumes missing"
|
||||||
|
#define MRecVolFound "\n%d recovery volumes found"
|
||||||
|
#define MRecVolAllExist "\nNothing to reconstruct"
|
||||||
|
#define MRecVolCannotFix "\nReconstruction impossible"
|
||||||
|
#define MReconstructing "\nReconstructing..."
|
||||||
|
#define MCreating "\nCreating %s"
|
||||||
|
#define MRenaming "\nRenaming %s to %s"
|
||||||
|
#define MNTFSRequired "\nWrite error: only NTFS file system supports files larger than 4 GB"
|
||||||
|
#define MErrChangeAttr "\nWARNING: Cannot change attributes of %s"
|
||||||
|
#define MWrongSFXVer "\nERROR: default SFX module does not support RAR %d.%d archives"
|
||||||
|
#define MCannotEncName "\nCannot encrypt archive already contained encrypted files"
|
||||||
|
#define MCannotEmail "\nCannot email the file %s"
|
||||||
|
#define MCopyrightS "\nRAR SFX archive"
|
||||||
|
#define MSHelpCmd "\n\n<Commands>"
|
||||||
|
#define MSHelpCmdE "\n -x Extract from archive (default)"
|
||||||
|
#define MSHelpCmdT "\n -t Test archive files"
|
||||||
|
#define MSHelpCmdV "\n -v Verbosely list contents of archive"
|
||||||
|
#define MMaxPathLimit "\nTotal path and file name length must not exceed %d characters"
|
||||||
|
#define MRecVolLimit "\nTotal number of usual and recovery volumes must not exceed 255"
|
||||||
|
#define MVolumeNumber "volume %d"
|
||||||
|
#define MCannotDelete "\nCannot delete %s"
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
static char LogName[NM];
|
||||||
|
|
||||||
|
void InitLogOptions(char *LogName)
|
||||||
|
{
|
||||||
|
strcpy(::LogName,LogName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SILENT
|
||||||
|
void Log(const char *ArcName,const char *Format,...)
|
||||||
|
{
|
||||||
|
safebuf char Msg[2*NM+1024];
|
||||||
|
va_list ArgPtr;
|
||||||
|
va_start(ArgPtr,Format);
|
||||||
|
vsprintf(Msg,Format,ArgPtr);
|
||||||
|
va_end(ArgPtr);
|
||||||
|
eprintf("%s",Msg);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
#ifndef _RAR_LOG_
|
||||||
|
#define _RAR_LOG_
|
||||||
|
|
||||||
|
void InitLogOptions(char *LogName);
|
||||||
|
|
||||||
|
#ifndef SILENT
|
||||||
|
void Log(const char *ArcName,const char *Format,...);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef SILENT
|
||||||
|
#ifdef __GNUC__
|
||||||
|
#define Log(args...)
|
||||||
|
#else
|
||||||
|
inline void Log(const char *a,const char *b,const char *c=NULL,const char *d=NULL) {}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,262 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
static bool match(char *pattern,char *string,bool ForceCase);
|
||||||
|
static bool match(wchar *pattern,wchar *string,bool ForceCase);
|
||||||
|
|
||||||
|
static int mstricompc(const char *Str1,const char *Str2,bool ForceCase);
|
||||||
|
static int mstricompcw(const wchar *Str1,const wchar *Str2,bool ForceCase);
|
||||||
|
static int mstrnicompc(const char *Str1,const char *Str2,int N,bool ForceCase);
|
||||||
|
static int mstrnicompcw(const wchar *Str1,const wchar *Str2,int N,bool ForceCase);
|
||||||
|
|
||||||
|
inline uint toupperc(byte ch,bool ForceCase)
|
||||||
|
{
|
||||||
|
if (ForceCase)
|
||||||
|
return(ch);
|
||||||
|
#ifdef _WIN_32
|
||||||
|
return((uint)CharUpper((LPTSTR)(ch)));
|
||||||
|
#elif defined(_UNIX)
|
||||||
|
return(ch);
|
||||||
|
#else
|
||||||
|
return(toupper(ch));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline uint touppercw(uint ch,bool ForceCase)
|
||||||
|
{
|
||||||
|
if (ForceCase)
|
||||||
|
return(ch);
|
||||||
|
#if defined(_UNIX)
|
||||||
|
return(ch);
|
||||||
|
#else
|
||||||
|
return(toupperw(ch));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CmpName(char *Wildcard,char *Name,int CmpPath)
|
||||||
|
{
|
||||||
|
bool ForceCase=(CmpPath&MATCH_FORCECASESENSITIVE)!=0;
|
||||||
|
|
||||||
|
CmpPath&=MATCH_MODEMASK;
|
||||||
|
|
||||||
|
if (CmpPath!=MATCH_NAMES)
|
||||||
|
{
|
||||||
|
int WildLength=strlen(Wildcard);
|
||||||
|
if (CmpPath!=MATCH_EXACTPATH && mstrnicompc(Wildcard,Name,WildLength,ForceCase)==0)
|
||||||
|
{
|
||||||
|
char NextCh=Name[WildLength];
|
||||||
|
if (NextCh=='\\' || NextCh=='/' || NextCh==0)
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
char Path1[NM],Path2[NM];
|
||||||
|
GetFilePath(Wildcard,Path1);
|
||||||
|
GetFilePath(Name,Path2);
|
||||||
|
if (mstricompc(Wildcard,Path2,ForceCase)==0)
|
||||||
|
return(true);
|
||||||
|
if ((CmpPath==MATCH_PATH || CmpPath==MATCH_EXACTPATH) && mstricompc(Path1,Path2,ForceCase)!=0)
|
||||||
|
return(false);
|
||||||
|
if (CmpPath==MATCH_SUBPATH || CmpPath==MATCH_WILDSUBPATH)
|
||||||
|
if (IsWildcard(Path1))
|
||||||
|
return(match(Wildcard,Name,ForceCase));
|
||||||
|
else
|
||||||
|
if (CmpPath==MATCH_SUBPATH || IsWildcard(Wildcard))
|
||||||
|
{
|
||||||
|
if (*Path1 && mstrnicompc(Path1,Path2,strlen(Path1),ForceCase)!=0)
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (mstricompc(Path1,Path2,ForceCase)!=0)
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
char *Name1=PointToName(Wildcard);
|
||||||
|
char *Name2=PointToName(Name);
|
||||||
|
if (mstrnicompc("__rar_",Name2,6,false)==0)
|
||||||
|
return(false);
|
||||||
|
return(match(Name1,Name2,ForceCase));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
bool CmpName(wchar *Wildcard,wchar *Name,int CmpPath)
|
||||||
|
{
|
||||||
|
bool ForceCase=(CmpPath&MATCH_FORCECASESENSITIVE)!=0;
|
||||||
|
|
||||||
|
CmpPath&=MATCH_MODEMASK;
|
||||||
|
|
||||||
|
if (CmpPath!=MATCH_NAMES)
|
||||||
|
{
|
||||||
|
int WildLength=strlenw(Wildcard);
|
||||||
|
if (CmpPath!=MATCH_EXACTPATH && mstrnicompcw(Wildcard,Name,WildLength,ForceCase)==0)
|
||||||
|
{
|
||||||
|
wchar NextCh=Name[WildLength];
|
||||||
|
if (NextCh==L'\\' || NextCh==L'/' || NextCh==0)
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
wchar Path1[NM],Path2[NM];
|
||||||
|
GetFilePath(Wildcard,Path1);
|
||||||
|
GetFilePath(Name,Path2);
|
||||||
|
if ((CmpPath==MATCH_PATH || CmpPath==MATCH_EXACTPATH) && mstricompcw(Path1,Path2,ForceCase)!=0)
|
||||||
|
return(false);
|
||||||
|
if (CmpPath==MATCH_SUBPATH || CmpPath==MATCH_WILDSUBPATH)
|
||||||
|
if (IsWildcard(NULL,Path1))
|
||||||
|
return(match(Wildcard,Name,ForceCase));
|
||||||
|
else
|
||||||
|
if (CmpPath==MATCH_SUBPATH || IsWildcard(NULL,Wildcard))
|
||||||
|
{
|
||||||
|
if (*Path1 && mstrnicompcw(Path1,Path2,strlenw(Path1),ForceCase)!=0)
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (mstricompcw(Path1,Path2,ForceCase)!=0)
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
wchar *Name1=PointToName(Wildcard);
|
||||||
|
wchar *Name2=PointToName(Name);
|
||||||
|
if (mstrnicompcw(L"__rar_",Name2,6,false)==0)
|
||||||
|
return(false);
|
||||||
|
return(match(Name1,Name2,ForceCase));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
bool match(char *pattern,char *string,bool ForceCase)
|
||||||
|
{
|
||||||
|
for (;; ++string)
|
||||||
|
{
|
||||||
|
char stringc=toupperc(*string,ForceCase);
|
||||||
|
char patternc=toupperc(*pattern++,ForceCase);
|
||||||
|
switch (patternc)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return(stringc==0);
|
||||||
|
case '?':
|
||||||
|
if (stringc == 0)
|
||||||
|
return(false);
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
if (*pattern==0)
|
||||||
|
return(true);
|
||||||
|
if (*pattern=='.')
|
||||||
|
{
|
||||||
|
if (pattern[1]=='*' && pattern[2]==0)
|
||||||
|
return(true);
|
||||||
|
char *dot=strchr(string,'.');
|
||||||
|
if (pattern[1]==0)
|
||||||
|
return (dot==NULL || dot[1]==0);
|
||||||
|
if (dot!=NULL)
|
||||||
|
{
|
||||||
|
string=dot;
|
||||||
|
if (strpbrk(pattern,"*?")==NULL && strchr(string+1,'.')==NULL)
|
||||||
|
return(mstricompc(pattern+1,string+1,ForceCase)==0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*string)
|
||||||
|
if (match(pattern,string++,ForceCase))
|
||||||
|
return(true);
|
||||||
|
return(false);
|
||||||
|
default:
|
||||||
|
if (patternc != stringc)
|
||||||
|
if (patternc=='.' && stringc==0)
|
||||||
|
return(match(pattern,string,ForceCase));
|
||||||
|
else
|
||||||
|
return(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
bool match(wchar *pattern,wchar *string,bool ForceCase)
|
||||||
|
{
|
||||||
|
for (;; ++string)
|
||||||
|
{
|
||||||
|
wchar stringc=touppercw(*string,ForceCase);
|
||||||
|
wchar patternc=touppercw(*pattern++,ForceCase);
|
||||||
|
switch (patternc)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return(stringc==0);
|
||||||
|
case '?':
|
||||||
|
if (stringc == 0)
|
||||||
|
return(false);
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
if (*pattern==0)
|
||||||
|
return(true);
|
||||||
|
if (*pattern=='.')
|
||||||
|
{
|
||||||
|
if (pattern[1]=='*' && pattern[2]==0)
|
||||||
|
return(true);
|
||||||
|
wchar *dot=strchrw(string,'.');
|
||||||
|
if (pattern[1]==0)
|
||||||
|
return (dot==NULL || dot[1]==0);
|
||||||
|
if (dot!=NULL)
|
||||||
|
{
|
||||||
|
string=dot;
|
||||||
|
if (strpbrkw(pattern,L"*?")==NULL && strchrw(string+1,'.')==NULL)
|
||||||
|
return(mstricompcw(pattern+1,string+1,ForceCase)==0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (*string)
|
||||||
|
if (match(pattern,string++,ForceCase))
|
||||||
|
return(true);
|
||||||
|
return(false);
|
||||||
|
default:
|
||||||
|
if (patternc != stringc)
|
||||||
|
if (patternc=='.' && stringc==0)
|
||||||
|
return(match(pattern,string,ForceCase));
|
||||||
|
else
|
||||||
|
return(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int mstricompc(const char *Str1,const char *Str2,bool ForceCase)
|
||||||
|
{
|
||||||
|
if (ForceCase)
|
||||||
|
return(strcmp(Str1,Str2));
|
||||||
|
return(stricompc(Str1,Str2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
int mstricompcw(const wchar *Str1,const wchar *Str2,bool ForceCase)
|
||||||
|
{
|
||||||
|
if (ForceCase)
|
||||||
|
return(strcmpw(Str1,Str2));
|
||||||
|
return(stricompcw(Str1,Str2));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int mstrnicompc(const char *Str1,const char *Str2,int N,bool ForceCase)
|
||||||
|
{
|
||||||
|
if (ForceCase)
|
||||||
|
return(strncmp(Str1,Str2,N));
|
||||||
|
#if defined(_UNIX)
|
||||||
|
return(strncmp(Str1,Str2,N));
|
||||||
|
#else
|
||||||
|
return(strnicomp(Str1,Str2,N));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
int mstrnicompcw(const wchar *Str1,const wchar *Str2,int N,bool ForceCase)
|
||||||
|
{
|
||||||
|
if (ForceCase)
|
||||||
|
return(strncmpw(Str1,Str2,N));
|
||||||
|
#if defined(_UNIX)
|
||||||
|
return(strncmpw(Str1,Str2,N));
|
||||||
|
#else
|
||||||
|
return(strnicmpw(Str1,Str2,N));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
#ifndef _RAR_MATCH_
|
||||||
|
#define _RAR_MATCH_
|
||||||
|
|
||||||
|
enum {MATCH_NAMES,MATCH_PATH,MATCH_EXACTPATH,MATCH_SUBPATH,MATCH_WILDSUBPATH};
|
||||||
|
|
||||||
|
#define MATCH_MODEMASK 0x0000ffff
|
||||||
|
#define MATCH_FORCECASESENSITIVE 0x80000000
|
||||||
|
|
||||||
|
bool CmpName(char *Wildcard,char *Name,int CmpPath);
|
||||||
|
bool CmpName(wchar *Wildcard,wchar *Name,int CmpPath);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,600 @@
|
|||||||
|
/****************************************************************************
|
||||||
|
* This file is part of PPMd project *
|
||||||
|
* Written and distributed to public domain by Dmitry Shkarin 1997, *
|
||||||
|
* 1999-2000 *
|
||||||
|
* Contents: model description and encoding/decoding routines *
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
inline PPM_CONTEXT* PPM_CONTEXT::createChild(ModelPPM *Model,STATE* pStats,
|
||||||
|
STATE& FirstState)
|
||||||
|
{
|
||||||
|
PPM_CONTEXT* pc = (PPM_CONTEXT*) Model->SubAlloc.AllocContext();
|
||||||
|
if ( pc )
|
||||||
|
{
|
||||||
|
pc->NumStats=1;
|
||||||
|
pc->OneState=FirstState;
|
||||||
|
pc->Suffix=this;
|
||||||
|
pStats->Successor=pc;
|
||||||
|
}
|
||||||
|
return pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModelPPM::ModelPPM()
|
||||||
|
{
|
||||||
|
MinContext=NULL;
|
||||||
|
MaxContext=NULL;
|
||||||
|
MedContext=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ModelPPM::RestartModelRare()
|
||||||
|
{
|
||||||
|
int i, k, m;
|
||||||
|
memset(CharMask,0,sizeof(CharMask));
|
||||||
|
SubAlloc.InitSubAllocator();
|
||||||
|
InitRL=-(MaxOrder < 12 ? MaxOrder:12)-1;
|
||||||
|
MinContext = MaxContext = (PPM_CONTEXT*) SubAlloc.AllocContext();
|
||||||
|
MinContext->Suffix=NULL;
|
||||||
|
OrderFall=MaxOrder;
|
||||||
|
MinContext->U.SummFreq=(MinContext->NumStats=256)+1;
|
||||||
|
FoundState=MinContext->U.Stats=(STATE*)SubAlloc.AllocUnits(256/2);
|
||||||
|
for (RunLength=InitRL, PrevSuccess=i=0;i < 256;i++)
|
||||||
|
{
|
||||||
|
MinContext->U.Stats[i].Symbol=i;
|
||||||
|
MinContext->U.Stats[i].Freq=1;
|
||||||
|
MinContext->U.Stats[i].Successor=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const ushort InitBinEsc[]={
|
||||||
|
0x3CDD,0x1F3F,0x59BF,0x48F3,0x64A1,0x5ABC,0x6632,0x6051
|
||||||
|
};
|
||||||
|
|
||||||
|
for (i=0;i < 128;i++)
|
||||||
|
for (k=0;k < 8;k++)
|
||||||
|
for (m=0;m < 64;m += 8)
|
||||||
|
BinSumm[i][k+m]=BIN_SCALE-InitBinEsc[k]/(i+2);
|
||||||
|
for (i=0;i < 25;i++)
|
||||||
|
for (k=0;k < 16;k++)
|
||||||
|
SEE2Cont[i][k].init(5*i+10);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ModelPPM::StartModelRare(int MaxOrder)
|
||||||
|
{
|
||||||
|
int i, k, m ,Step;
|
||||||
|
EscCount=1;
|
||||||
|
/*
|
||||||
|
if (MaxOrder < 2)
|
||||||
|
{
|
||||||
|
memset(CharMask,0,sizeof(CharMask));
|
||||||
|
OrderFall=ModelPPM::MaxOrder;
|
||||||
|
MinContext=MaxContext;
|
||||||
|
while (MinContext->Suffix != NULL)
|
||||||
|
{
|
||||||
|
MinContext=MinContext->Suffix;
|
||||||
|
OrderFall--;
|
||||||
|
}
|
||||||
|
FoundState=MinContext->U.Stats;
|
||||||
|
MinContext=MaxContext;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
ModelPPM::MaxOrder=MaxOrder;
|
||||||
|
RestartModelRare();
|
||||||
|
NS2BSIndx[0]=2*0;
|
||||||
|
NS2BSIndx[1]=2*1;
|
||||||
|
memset(NS2BSIndx+2,2*2,9);
|
||||||
|
memset(NS2BSIndx+11,2*3,256-11);
|
||||||
|
for (i=0;i < 3;i++)
|
||||||
|
NS2Indx[i]=i;
|
||||||
|
for (m=i, k=Step=1;i < 256;i++)
|
||||||
|
{
|
||||||
|
NS2Indx[i]=m;
|
||||||
|
if ( !--k )
|
||||||
|
{
|
||||||
|
k = ++Step;
|
||||||
|
m++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memset(HB2Flag,0,0x40);
|
||||||
|
memset(HB2Flag+0x40,0x08,0x100-0x40);
|
||||||
|
DummySEE2Cont.Shift=PERIOD_BITS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void PPM_CONTEXT::rescale(ModelPPM *Model)
|
||||||
|
{
|
||||||
|
int OldNS=NumStats, i=NumStats-1, Adder, EscFreq;
|
||||||
|
STATE* p1, * p;
|
||||||
|
for (p=Model->FoundState;p != U.Stats;p--)
|
||||||
|
_PPMD_SWAP(p[0],p[-1]);
|
||||||
|
U.Stats->Freq += 4;
|
||||||
|
U.SummFreq += 4;
|
||||||
|
EscFreq=U.SummFreq-p->Freq;
|
||||||
|
Adder=(Model->OrderFall != 0);
|
||||||
|
U.SummFreq = (p->Freq=(p->Freq+Adder) >> 1);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
EscFreq -= (++p)->Freq;
|
||||||
|
U.SummFreq += (p->Freq=(p->Freq+Adder) >> 1);
|
||||||
|
if (p[0].Freq > p[-1].Freq)
|
||||||
|
{
|
||||||
|
STATE tmp=*(p1=p);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
p1[0]=p1[-1];
|
||||||
|
} while (--p1 != U.Stats && tmp.Freq > p1[-1].Freq);
|
||||||
|
*p1=tmp;
|
||||||
|
}
|
||||||
|
} while ( --i );
|
||||||
|
if (p->Freq == 0)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
} while ((--p)->Freq == 0);
|
||||||
|
EscFreq += i;
|
||||||
|
if ((NumStats -= i) == 1)
|
||||||
|
{
|
||||||
|
STATE tmp=*U.Stats;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
tmp.Freq-=(tmp.Freq >> 1);
|
||||||
|
EscFreq>>=1;
|
||||||
|
} while (EscFreq > 1);
|
||||||
|
Model->SubAlloc.FreeUnits(U.Stats,(OldNS+1) >> 1);
|
||||||
|
*(Model->FoundState=&OneState)=tmp; return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
U.SummFreq += (EscFreq -= (EscFreq >> 1));
|
||||||
|
int n0=(OldNS+1) >> 1, n1=(NumStats+1) >> 1;
|
||||||
|
if (n0 != n1)
|
||||||
|
U.Stats = (STATE*) Model->SubAlloc.ShrinkUnits(U.Stats,n0,n1);
|
||||||
|
Model->FoundState=U.Stats;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline PPM_CONTEXT* ModelPPM::CreateSuccessors(bool Skip,STATE* p1)
|
||||||
|
{
|
||||||
|
#ifdef __ICL
|
||||||
|
static
|
||||||
|
#endif
|
||||||
|
STATE UpState;
|
||||||
|
PPM_CONTEXT* pc=MinContext, * UpBranch=FoundState->Successor;
|
||||||
|
STATE * p, * ps[MAX_O], ** pps=ps;
|
||||||
|
if ( !Skip )
|
||||||
|
{
|
||||||
|
*pps++ = FoundState;
|
||||||
|
if ( !pc->Suffix )
|
||||||
|
goto NO_LOOP;
|
||||||
|
}
|
||||||
|
if ( p1 )
|
||||||
|
{
|
||||||
|
p=p1;
|
||||||
|
pc=pc->Suffix;
|
||||||
|
goto LOOP_ENTRY;
|
||||||
|
}
|
||||||
|
do
|
||||||
|
{
|
||||||
|
pc=pc->Suffix;
|
||||||
|
if (pc->NumStats != 1)
|
||||||
|
{
|
||||||
|
if ((p=pc->U.Stats)->Symbol != FoundState->Symbol)
|
||||||
|
do
|
||||||
|
{
|
||||||
|
p++;
|
||||||
|
} while (p->Symbol != FoundState->Symbol);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
p=&(pc->OneState);
|
||||||
|
LOOP_ENTRY:
|
||||||
|
if (p->Successor != UpBranch)
|
||||||
|
{
|
||||||
|
pc=p->Successor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*pps++ = p;
|
||||||
|
} while ( pc->Suffix );
|
||||||
|
NO_LOOP:
|
||||||
|
if (pps == ps)
|
||||||
|
return pc;
|
||||||
|
UpState.Symbol=*(byte*) UpBranch;
|
||||||
|
UpState.Successor=(PPM_CONTEXT*) (((byte*) UpBranch)+1);
|
||||||
|
if (pc->NumStats != 1)
|
||||||
|
{
|
||||||
|
if ((byte*) pc <= SubAlloc.pText)
|
||||||
|
return(NULL);
|
||||||
|
if ((p=pc->U.Stats)->Symbol != UpState.Symbol)
|
||||||
|
do
|
||||||
|
{
|
||||||
|
p++;
|
||||||
|
} while (p->Symbol != UpState.Symbol);
|
||||||
|
uint cf=p->Freq-1;
|
||||||
|
uint s0=pc->U.SummFreq-pc->NumStats-cf;
|
||||||
|
UpState.Freq=1+((2*cf <= s0)?(5*cf > s0):((2*cf+3*s0-1)/(2*s0)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
UpState.Freq=pc->OneState.Freq;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
pc = pc->createChild(this,*--pps,UpState);
|
||||||
|
if ( !pc )
|
||||||
|
return NULL;
|
||||||
|
} while (pps != ps);
|
||||||
|
return pc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void ModelPPM::UpdateModel()
|
||||||
|
{
|
||||||
|
STATE fs = *FoundState, *p = NULL;
|
||||||
|
PPM_CONTEXT *pc, *Successor;
|
||||||
|
uint ns1, ns, cf, sf, s0;
|
||||||
|
if (fs.Freq < MAX_FREQ/4 && (pc=MinContext->Suffix) != NULL)
|
||||||
|
{
|
||||||
|
if (pc->NumStats != 1)
|
||||||
|
{
|
||||||
|
if ((p=pc->U.Stats)->Symbol != fs.Symbol)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
p++;
|
||||||
|
} while (p->Symbol != fs.Symbol);
|
||||||
|
if (p[0].Freq >= p[-1].Freq)
|
||||||
|
{
|
||||||
|
_PPMD_SWAP(p[0],p[-1]);
|
||||||
|
p--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (p->Freq < MAX_FREQ-9)
|
||||||
|
{
|
||||||
|
p->Freq += 2;
|
||||||
|
pc->U.SummFreq += 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p=&(pc->OneState);
|
||||||
|
p->Freq += (p->Freq < 32);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !OrderFall )
|
||||||
|
{
|
||||||
|
MinContext=MaxContext=FoundState->Successor=CreateSuccessors(TRUE,p);
|
||||||
|
if ( !MinContext )
|
||||||
|
goto RESTART_MODEL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*SubAlloc.pText++ = fs.Symbol;
|
||||||
|
Successor = (PPM_CONTEXT*) SubAlloc.pText;
|
||||||
|
if (SubAlloc.pText >= SubAlloc.FakeUnitsStart)
|
||||||
|
goto RESTART_MODEL;
|
||||||
|
if ( fs.Successor )
|
||||||
|
{
|
||||||
|
if ((byte*) fs.Successor <= SubAlloc.pText &&
|
||||||
|
(fs.Successor=CreateSuccessors(FALSE,p)) == NULL)
|
||||||
|
goto RESTART_MODEL;
|
||||||
|
if ( !--OrderFall )
|
||||||
|
{
|
||||||
|
Successor=fs.Successor;
|
||||||
|
SubAlloc.pText -= (MaxContext != MinContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FoundState->Successor=Successor;
|
||||||
|
fs.Successor=MinContext;
|
||||||
|
}
|
||||||
|
s0=MinContext->U.SummFreq-(ns=MinContext->NumStats)-(fs.Freq-1);
|
||||||
|
for (pc=MaxContext;pc != MinContext;pc=pc->Suffix)
|
||||||
|
{
|
||||||
|
if ((ns1=pc->NumStats) != 1)
|
||||||
|
{
|
||||||
|
if ((ns1 & 1) == 0)
|
||||||
|
{
|
||||||
|
pc->U.Stats=(STATE*) SubAlloc.ExpandUnits(pc->U.Stats,ns1 >> 1);
|
||||||
|
if ( !pc->U.Stats )
|
||||||
|
goto RESTART_MODEL;
|
||||||
|
}
|
||||||
|
pc->U.SummFreq += (2*ns1 < ns)+2*((4*ns1 <= ns) & (pc->U.SummFreq <= 8*ns1));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
p=(STATE*) SubAlloc.AllocUnits(1);
|
||||||
|
if ( !p )
|
||||||
|
goto RESTART_MODEL;
|
||||||
|
*p=pc->OneState;
|
||||||
|
pc->U.Stats=p;
|
||||||
|
if (p->Freq < MAX_FREQ/4-1)
|
||||||
|
p->Freq += p->Freq;
|
||||||
|
else
|
||||||
|
p->Freq = MAX_FREQ-4;
|
||||||
|
pc->U.SummFreq=p->Freq+InitEsc+(ns > 3);
|
||||||
|
}
|
||||||
|
cf=2*fs.Freq*(pc->U.SummFreq+6);
|
||||||
|
sf=s0+pc->U.SummFreq;
|
||||||
|
if (cf < 6*sf)
|
||||||
|
{
|
||||||
|
cf=1+(cf > sf)+(cf >= 4*sf);
|
||||||
|
pc->U.SummFreq += 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cf=4+(cf >= 9*sf)+(cf >= 12*sf)+(cf >= 15*sf);
|
||||||
|
pc->U.SummFreq += cf;
|
||||||
|
}
|
||||||
|
p=pc->U.Stats+ns1;
|
||||||
|
p->Successor=Successor;
|
||||||
|
p->Symbol = fs.Symbol;
|
||||||
|
p->Freq = cf;
|
||||||
|
pc->NumStats=++ns1;
|
||||||
|
}
|
||||||
|
MaxContext=MinContext=fs.Successor;
|
||||||
|
return;
|
||||||
|
RESTART_MODEL:
|
||||||
|
RestartModelRare();
|
||||||
|
EscCount=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Tabulated escapes for exponential symbol distribution
|
||||||
|
static const byte ExpEscape[16]={ 25,14, 9, 7, 5, 5, 4, 4, 4, 3, 3, 3, 2, 2, 2, 2 };
|
||||||
|
#define GET_MEAN(SUMM,SHIFT,ROUND) ((SUMM+(1 << (SHIFT-ROUND))) >> (SHIFT))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline void PPM_CONTEXT::decodeBinSymbol(ModelPPM *Model)
|
||||||
|
{
|
||||||
|
STATE& rs=OneState;
|
||||||
|
Model->HiBitsFlag=Model->HB2Flag[Model->FoundState->Symbol];
|
||||||
|
ushort& bs=Model->BinSumm[rs.Freq-1][Model->PrevSuccess+
|
||||||
|
Model->NS2BSIndx[Suffix->NumStats-1]+
|
||||||
|
Model->HiBitsFlag+2*Model->HB2Flag[rs.Symbol]+
|
||||||
|
((Model->RunLength >> 26) & 0x20)];
|
||||||
|
if (Model->Coder.GetCurrentShiftCount(TOT_BITS) < bs)
|
||||||
|
{
|
||||||
|
Model->FoundState=&rs;
|
||||||
|
rs.Freq += (rs.Freq < 128);
|
||||||
|
Model->Coder.SubRange.LowCount=0;
|
||||||
|
Model->Coder.SubRange.HighCount=bs;
|
||||||
|
bs = SHORT16(bs+INTERVAL-GET_MEAN(bs,PERIOD_BITS,2));
|
||||||
|
Model->PrevSuccess=1;
|
||||||
|
Model->RunLength++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Model->Coder.SubRange.LowCount=bs;
|
||||||
|
bs = SHORT16(bs-GET_MEAN(bs,PERIOD_BITS,2));
|
||||||
|
Model->Coder.SubRange.HighCount=BIN_SCALE;
|
||||||
|
Model->InitEsc=ExpEscape[bs >> 10];
|
||||||
|
Model->NumMasked=1;
|
||||||
|
Model->CharMask[rs.Symbol]=Model->EscCount;
|
||||||
|
Model->PrevSuccess=0;
|
||||||
|
Model->FoundState=NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void PPM_CONTEXT::update1(ModelPPM *Model,STATE* p)
|
||||||
|
{
|
||||||
|
(Model->FoundState=p)->Freq += 4;
|
||||||
|
U.SummFreq += 4;
|
||||||
|
if (p[0].Freq > p[-1].Freq)
|
||||||
|
{
|
||||||
|
_PPMD_SWAP(p[0],p[-1]);
|
||||||
|
Model->FoundState=--p;
|
||||||
|
if (p->Freq > MAX_FREQ)
|
||||||
|
rescale(Model);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline bool PPM_CONTEXT::decodeSymbol1(ModelPPM *Model)
|
||||||
|
{
|
||||||
|
Model->Coder.SubRange.scale=U.SummFreq;
|
||||||
|
STATE* p=U.Stats;
|
||||||
|
int i, HiCnt;
|
||||||
|
int count=Model->Coder.GetCurrentCount();
|
||||||
|
if (count>=Model->Coder.SubRange.scale)
|
||||||
|
return(false);
|
||||||
|
if (count < (HiCnt=p->Freq))
|
||||||
|
{
|
||||||
|
Model->PrevSuccess=(2*(Model->Coder.SubRange.HighCount=HiCnt) > Model->Coder.SubRange.scale);
|
||||||
|
Model->RunLength += Model->PrevSuccess;
|
||||||
|
(Model->FoundState=p)->Freq=(HiCnt += 4);
|
||||||
|
U.SummFreq += 4;
|
||||||
|
if (HiCnt > MAX_FREQ)
|
||||||
|
rescale(Model);
|
||||||
|
Model->Coder.SubRange.LowCount=0;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (Model->FoundState==NULL)
|
||||||
|
return(false);
|
||||||
|
Model->PrevSuccess=0;
|
||||||
|
i=NumStats-1;
|
||||||
|
while ((HiCnt += (++p)->Freq) <= count)
|
||||||
|
if (--i == 0)
|
||||||
|
{
|
||||||
|
Model->HiBitsFlag=Model->HB2Flag[Model->FoundState->Symbol];
|
||||||
|
Model->Coder.SubRange.LowCount=HiCnt;
|
||||||
|
Model->CharMask[p->Symbol]=Model->EscCount;
|
||||||
|
i=(Model->NumMasked=NumStats)-1;
|
||||||
|
Model->FoundState=NULL;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Model->CharMask[(--p)->Symbol]=Model->EscCount;
|
||||||
|
} while ( --i );
|
||||||
|
Model->Coder.SubRange.HighCount=Model->Coder.SubRange.scale;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
Model->Coder.SubRange.LowCount=(Model->Coder.SubRange.HighCount=HiCnt)-p->Freq;
|
||||||
|
update1(Model,p);
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void PPM_CONTEXT::update2(ModelPPM *Model,STATE* p)
|
||||||
|
{
|
||||||
|
(Model->FoundState=p)->Freq += 4;
|
||||||
|
U.SummFreq += 4;
|
||||||
|
if (p->Freq > MAX_FREQ)
|
||||||
|
rescale(Model);
|
||||||
|
Model->EscCount++;
|
||||||
|
Model->RunLength=Model->InitRL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline SEE2_CONTEXT* PPM_CONTEXT::makeEscFreq2(ModelPPM *Model,int Diff)
|
||||||
|
{
|
||||||
|
SEE2_CONTEXT* psee2c;
|
||||||
|
if (NumStats != 256)
|
||||||
|
{
|
||||||
|
psee2c=Model->SEE2Cont[Model->NS2Indx[Diff-1]]+
|
||||||
|
(Diff < Suffix->NumStats-NumStats)+
|
||||||
|
2*(U.SummFreq < 11*NumStats)+4*(Model->NumMasked > Diff)+
|
||||||
|
Model->HiBitsFlag;
|
||||||
|
Model->Coder.SubRange.scale=psee2c->getMean();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
psee2c=&Model->DummySEE2Cont;
|
||||||
|
Model->Coder.SubRange.scale=1;
|
||||||
|
}
|
||||||
|
return psee2c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
inline bool PPM_CONTEXT::decodeSymbol2(ModelPPM *Model)
|
||||||
|
{
|
||||||
|
int count, HiCnt, i=NumStats-Model->NumMasked;
|
||||||
|
SEE2_CONTEXT* psee2c=makeEscFreq2(Model,i);
|
||||||
|
STATE* ps[256], ** pps=ps, * p=U.Stats-1;
|
||||||
|
HiCnt=0;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
p++;
|
||||||
|
} while (Model->CharMask[p->Symbol] == Model->EscCount);
|
||||||
|
HiCnt += p->Freq;
|
||||||
|
*pps++ = p;
|
||||||
|
} while ( --i );
|
||||||
|
Model->Coder.SubRange.scale += HiCnt;
|
||||||
|
count=Model->Coder.GetCurrentCount();
|
||||||
|
if (count>=Model->Coder.SubRange.scale)
|
||||||
|
return(false);
|
||||||
|
p=*(pps=ps);
|
||||||
|
if (count < HiCnt)
|
||||||
|
{
|
||||||
|
HiCnt=0;
|
||||||
|
while ((HiCnt += p->Freq) <= count)
|
||||||
|
p=*++pps;
|
||||||
|
Model->Coder.SubRange.LowCount = (Model->Coder.SubRange.HighCount=HiCnt)-p->Freq;
|
||||||
|
psee2c->update();
|
||||||
|
update2(Model,p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Model->Coder.SubRange.LowCount=HiCnt;
|
||||||
|
Model->Coder.SubRange.HighCount=Model->Coder.SubRange.scale;
|
||||||
|
i=NumStats-Model->NumMasked;
|
||||||
|
pps--;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Model->CharMask[(*++pps)->Symbol]=Model->EscCount;
|
||||||
|
} while ( --i );
|
||||||
|
psee2c->Summ += Model->Coder.SubRange.scale;
|
||||||
|
Model->NumMasked = NumStats;
|
||||||
|
}
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void ModelPPM::ClearMask()
|
||||||
|
{
|
||||||
|
EscCount=1;
|
||||||
|
memset(CharMask,0,sizeof(CharMask));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool ModelPPM::DecodeInit(Unpack *UnpackRead,int &EscChar)
|
||||||
|
{
|
||||||
|
int MaxOrder=UnpackRead->GetChar();
|
||||||
|
bool Reset=MaxOrder & 0x20;
|
||||||
|
|
||||||
|
int MaxMB;
|
||||||
|
if (Reset)
|
||||||
|
MaxMB=UnpackRead->GetChar();
|
||||||
|
else
|
||||||
|
if (SubAlloc.GetAllocatedMemory()==0)
|
||||||
|
return(false);
|
||||||
|
if (MaxOrder & 0x40)
|
||||||
|
EscChar=UnpackRead->GetChar();
|
||||||
|
Coder.InitDecoder(UnpackRead);
|
||||||
|
if (Reset)
|
||||||
|
{
|
||||||
|
MaxOrder=(MaxOrder & 0x1f)+1;
|
||||||
|
if (MaxOrder>16)
|
||||||
|
MaxOrder=16+(MaxOrder-16)*3;
|
||||||
|
if (MaxOrder==1)
|
||||||
|
{
|
||||||
|
SubAlloc.StopSubAllocator();
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
SubAlloc.StartSubAllocator(MaxMB+1);
|
||||||
|
StartModelRare(MaxOrder);
|
||||||
|
}
|
||||||
|
return(MinContext!=NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ModelPPM::DecodeChar()
|
||||||
|
{
|
||||||
|
if ((byte*)MinContext <= SubAlloc.pText || (byte*)MinContext>SubAlloc.HeapEnd)
|
||||||
|
return(-1);
|
||||||
|
if (MinContext->NumStats != 1)
|
||||||
|
{
|
||||||
|
if ((byte*)MinContext->U.Stats <= SubAlloc.pText || (byte*)MinContext->U.Stats>SubAlloc.HeapEnd)
|
||||||
|
return(-1);
|
||||||
|
if (!MinContext->decodeSymbol1(this))
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
MinContext->decodeBinSymbol(this);
|
||||||
|
Coder.Decode();
|
||||||
|
while ( !FoundState )
|
||||||
|
{
|
||||||
|
ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead);
|
||||||
|
do
|
||||||
|
{
|
||||||
|
OrderFall++;
|
||||||
|
MinContext=MinContext->Suffix;
|
||||||
|
if ((byte*)MinContext <= SubAlloc.pText || (byte*)MinContext>SubAlloc.HeapEnd)
|
||||||
|
return(-1);
|
||||||
|
} while (MinContext->NumStats == NumMasked);
|
||||||
|
if (!MinContext->decodeSymbol2(this))
|
||||||
|
return(-1);
|
||||||
|
Coder.Decode();
|
||||||
|
}
|
||||||
|
int Symbol=FoundState->Symbol;
|
||||||
|
if (!OrderFall && (byte*) FoundState->Successor > SubAlloc.pText)
|
||||||
|
MinContext=MaxContext=FoundState->Successor;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UpdateModel();
|
||||||
|
if (EscCount == 0)
|
||||||
|
ClearMask();
|
||||||
|
}
|
||||||
|
ARI_DEC_NORMALIZE(Coder.code,Coder.low,Coder.range,Coder.UnpackRead);
|
||||||
|
return(Symbol);
|
||||||
|
}
|
||||||
@@ -0,0 +1,131 @@
|
|||||||
|
#ifndef _RAR_PPMMODEL_
|
||||||
|
#define _RAR_PPMMODEL_
|
||||||
|
|
||||||
|
#include "coder.hpp"
|
||||||
|
#include "suballoc.hpp"
|
||||||
|
|
||||||
|
const int MAX_O=64; /* maximum allowed model order */
|
||||||
|
|
||||||
|
const int INT_BITS=7, PERIOD_BITS=7, TOT_BITS=INT_BITS+PERIOD_BITS,
|
||||||
|
INTERVAL=1 << INT_BITS, BIN_SCALE=1 << TOT_BITS, MAX_FREQ=124;
|
||||||
|
|
||||||
|
#ifndef STRICT_ALIGNMENT_REQUIRED
|
||||||
|
#pragma pack(1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct SEE2_CONTEXT
|
||||||
|
{ // SEE-contexts for PPM-contexts with masked symbols
|
||||||
|
ushort Summ;
|
||||||
|
byte Shift, Count;
|
||||||
|
void init(int InitVal)
|
||||||
|
{
|
||||||
|
Summ=InitVal << (Shift=PERIOD_BITS-4);
|
||||||
|
Count=4;
|
||||||
|
}
|
||||||
|
uint getMean()
|
||||||
|
{
|
||||||
|
uint RetVal=SHORT16(Summ) >> Shift;
|
||||||
|
Summ -= RetVal;
|
||||||
|
return RetVal+(RetVal == 0);
|
||||||
|
}
|
||||||
|
void update()
|
||||||
|
{
|
||||||
|
if (Shift < PERIOD_BITS && --Count == 0)
|
||||||
|
{
|
||||||
|
Summ += Summ;
|
||||||
|
Count=3 << Shift++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ModelPPM;
|
||||||
|
struct PPM_CONTEXT;
|
||||||
|
|
||||||
|
struct STATE
|
||||||
|
{
|
||||||
|
byte Symbol;
|
||||||
|
byte Freq;
|
||||||
|
PPM_CONTEXT* Successor;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FreqData
|
||||||
|
{
|
||||||
|
ushort SummFreq;
|
||||||
|
STATE _PACK_ATTR * Stats;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PPM_CONTEXT
|
||||||
|
{
|
||||||
|
ushort NumStats;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
FreqData U;
|
||||||
|
STATE OneState;
|
||||||
|
};
|
||||||
|
|
||||||
|
PPM_CONTEXT* Suffix;
|
||||||
|
inline void encodeBinSymbol(ModelPPM *Model,int symbol); // MaxOrder:
|
||||||
|
inline void encodeSymbol1(ModelPPM *Model,int symbol); // ABCD context
|
||||||
|
inline void encodeSymbol2(ModelPPM *Model,int symbol); // BCD suffix
|
||||||
|
inline void decodeBinSymbol(ModelPPM *Model); // BCDE successor
|
||||||
|
inline bool decodeSymbol1(ModelPPM *Model); // other orders:
|
||||||
|
inline bool decodeSymbol2(ModelPPM *Model); // BCD context
|
||||||
|
inline void update1(ModelPPM *Model,STATE* p); // CD suffix
|
||||||
|
inline void update2(ModelPPM *Model,STATE* p); // BCDE successor
|
||||||
|
void rescale(ModelPPM *Model);
|
||||||
|
inline PPM_CONTEXT* createChild(ModelPPM *Model,STATE* pStats,STATE& FirstState);
|
||||||
|
inline SEE2_CONTEXT* makeEscFreq2(ModelPPM *Model,int Diff);
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef STRICT_ALIGNMENT_REQUIRED
|
||||||
|
#ifdef _AIX
|
||||||
|
#pragma pack(pop)
|
||||||
|
#else
|
||||||
|
#pragma pack()
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const uint UNIT_SIZE=Max(sizeof(PPM_CONTEXT),sizeof(RAR_MEM_BLK));
|
||||||
|
const uint FIXED_UNIT_SIZE=12;
|
||||||
|
|
||||||
|
/*
|
||||||
|
inline PPM_CONTEXT::PPM_CONTEXT(STATE* pStats,PPM_CONTEXT* ShorterContext):
|
||||||
|
NumStats(1), Suffix(ShorterContext) { pStats->Successor=this; }
|
||||||
|
inline PPM_CONTEXT::PPM_CONTEXT(): NumStats(0) {}
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
inline void _PPMD_SWAP(T& t1,T& t2) { T tmp=t1; t1=t2; t2=tmp; }
|
||||||
|
|
||||||
|
|
||||||
|
class ModelPPM
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
friend struct PPM_CONTEXT;
|
||||||
|
|
||||||
|
_PACK_ATTR SEE2_CONTEXT SEE2Cont[25][16], DummySEE2Cont;
|
||||||
|
|
||||||
|
struct PPM_CONTEXT *MinContext, *MedContext, *MaxContext;
|
||||||
|
STATE* FoundState; // found next state transition
|
||||||
|
int NumMasked, InitEsc, OrderFall, MaxOrder, RunLength, InitRL;
|
||||||
|
byte CharMask[256], NS2Indx[256], NS2BSIndx[256], HB2Flag[256];
|
||||||
|
byte EscCount, PrevSuccess, HiBitsFlag;
|
||||||
|
ushort BinSumm[128][64]; // binary SEE-contexts
|
||||||
|
|
||||||
|
RangeCoder Coder;
|
||||||
|
SubAllocator SubAlloc;
|
||||||
|
|
||||||
|
void RestartModelRare();
|
||||||
|
void StartModelRare(int MaxOrder);
|
||||||
|
inline PPM_CONTEXT* CreateSuccessors(bool Skip,STATE* p1);
|
||||||
|
|
||||||
|
inline void UpdateModel();
|
||||||
|
inline void ClearMask();
|
||||||
|
public:
|
||||||
|
ModelPPM();
|
||||||
|
bool DecodeInit(Unpack *UnpackRead,int &EscChar);
|
||||||
|
int DecodeChar();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,28 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
RAROptions::RAROptions()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RAROptions::~RAROptions()
|
||||||
|
{
|
||||||
|
memset(this,0,sizeof(RAROptions));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RAROptions::Init()
|
||||||
|
{
|
||||||
|
memset(this,0,sizeof(RAROptions));
|
||||||
|
WinSize=0x400000;
|
||||||
|
Overwrite=OVERWRITE_ASK;
|
||||||
|
Method=3;
|
||||||
|
MsgStream=MSG_STDOUT;
|
||||||
|
ConvertNames=NAMES_ORIGINALCASE;
|
||||||
|
ProcessEA=true;
|
||||||
|
xmtime=EXTTIME_HIGH3;
|
||||||
|
CurVolNum=0;
|
||||||
|
FileSizeLess=INT64ERR;
|
||||||
|
FileSizeMore=INT64ERR;
|
||||||
|
}
|
||||||
@@ -0,0 +1,139 @@
|
|||||||
|
#ifndef _RAR_OPTIONS_
|
||||||
|
#define _RAR_OPTIONS_
|
||||||
|
|
||||||
|
#define DEFAULT_RECOVERY -1
|
||||||
|
|
||||||
|
#define DEFAULT_RECVOLUMES -10
|
||||||
|
|
||||||
|
enum PathExclMode {
|
||||||
|
EXCL_NONE,EXCL_BASEPATH,EXCL_SKIPWHOLEPATH,EXCL_SAVEFULLPATH,
|
||||||
|
EXCL_SKIPABSPATH,EXCL_ABSPATH
|
||||||
|
};
|
||||||
|
enum {SOLID_NONE=0,SOLID_NORMAL=1,SOLID_COUNT=2,SOLID_FILEEXT=4,
|
||||||
|
SOLID_VOLUME_DEPENDENT=8,SOLID_VOLUME_INDEPENDENT=16};
|
||||||
|
enum {ARCTIME_NONE,ARCTIME_KEEP,ARCTIME_LATEST};
|
||||||
|
enum EXTTIME_MODE {
|
||||||
|
EXTTIME_NONE,EXTTIME_1S,EXTTIME_HIGH1,EXTTIME_HIGH2,EXTTIME_HIGH3
|
||||||
|
};
|
||||||
|
enum {NAMES_ORIGINALCASE,NAMES_UPPERCASE,NAMES_LOWERCASE};
|
||||||
|
enum MESSAGE_TYPE {MSG_STDOUT,MSG_STDERR,MSG_ERRONLY,MSG_NULL};
|
||||||
|
enum OVERWRITE_MODE {
|
||||||
|
OVERWRITE_ASK,OVERWRITE_ALL,OVERWRITE_NONE,OVERWRITE_AUTORENAME
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MAX_FILTERS 16
|
||||||
|
enum FilterState {FILTER_DEFAULT=0,FILTER_AUTO,FILTER_FORCE,FILTER_DISABLE};
|
||||||
|
|
||||||
|
|
||||||
|
struct FilterMode
|
||||||
|
{
|
||||||
|
FilterState State;
|
||||||
|
int Param1;
|
||||||
|
int Param2;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class RAROptions
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
RAROptions();
|
||||||
|
~RAROptions();
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
uint ExclFileAttr;
|
||||||
|
uint InclFileAttr;
|
||||||
|
bool InclAttrSet;
|
||||||
|
uint WinSize;
|
||||||
|
char TempPath[NM];
|
||||||
|
char SFXModule[NM];
|
||||||
|
char ExtrPath[NM];
|
||||||
|
wchar ExtrPathW[NM];
|
||||||
|
char CommentFile[NM];
|
||||||
|
bool UnicodeComment;
|
||||||
|
char ArcPath[NM];
|
||||||
|
char Password[MAXPASSWORD];
|
||||||
|
bool EncryptHeaders;
|
||||||
|
char LogName[NM];
|
||||||
|
MESSAGE_TYPE MsgStream;
|
||||||
|
bool Sound;
|
||||||
|
OVERWRITE_MODE Overwrite;
|
||||||
|
int Method;
|
||||||
|
int Recovery;
|
||||||
|
int RecVolNumber;
|
||||||
|
bool DisablePercentage;
|
||||||
|
bool DisableCopyright;
|
||||||
|
bool DisableDone;
|
||||||
|
int Solid;
|
||||||
|
int SolidCount;
|
||||||
|
bool ClearArc;
|
||||||
|
bool AddArcOnly;
|
||||||
|
bool AV;
|
||||||
|
bool DisableComment;
|
||||||
|
bool FreshFiles;
|
||||||
|
bool UpdateFiles;
|
||||||
|
PathExclMode ExclPath;
|
||||||
|
int Recurse;
|
||||||
|
Int64 VolSize;
|
||||||
|
Array<Int64> NextVolSizes;
|
||||||
|
int CurVolNum;
|
||||||
|
bool AllYes;
|
||||||
|
bool DisableViewAV;
|
||||||
|
bool DisableSortSolid;
|
||||||
|
int ArcTime;
|
||||||
|
int ConvertNames;
|
||||||
|
bool ProcessOwners;
|
||||||
|
bool SaveLinks;
|
||||||
|
int Priority;
|
||||||
|
int SleepTime;
|
||||||
|
bool KeepBroken;
|
||||||
|
bool EraseDisk;
|
||||||
|
bool OpenShared;
|
||||||
|
bool ExclEmptyDir;
|
||||||
|
bool DeleteFiles;
|
||||||
|
bool SyncFiles;
|
||||||
|
bool GenerateArcName;
|
||||||
|
char GenerateMask[80];
|
||||||
|
bool ProcessEA;
|
||||||
|
bool SaveStreams;
|
||||||
|
bool SetCompressedAttr;
|
||||||
|
uint FileTimeOlder;
|
||||||
|
uint FileTimeNewer;
|
||||||
|
RarTime FileTimeBefore;
|
||||||
|
RarTime FileTimeAfter;
|
||||||
|
Int64 FileSizeLess;
|
||||||
|
Int64 FileSizeMore;
|
||||||
|
bool OldNumbering;
|
||||||
|
bool Lock;
|
||||||
|
bool Test;
|
||||||
|
bool VolumePause;
|
||||||
|
FilterMode FilterModes[MAX_FILTERS];
|
||||||
|
char EmailTo[NM];
|
||||||
|
int VersionControl;
|
||||||
|
bool NoEndBlock;
|
||||||
|
bool AppendArcNameToPath;
|
||||||
|
bool Shutdown;
|
||||||
|
EXTTIME_MODE xmtime;
|
||||||
|
EXTTIME_MODE xctime;
|
||||||
|
EXTTIME_MODE xatime;
|
||||||
|
EXTTIME_MODE xarctime;
|
||||||
|
char CompressStdin[NM];
|
||||||
|
|
||||||
|
#ifdef PACK_SMP
|
||||||
|
uint Threads;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef RARDLL
|
||||||
|
char DllDestName[NM];
|
||||||
|
wchar DllDestNameW[NM];
|
||||||
|
int DllOpMode;
|
||||||
|
int DllError;
|
||||||
|
LONG UserData;
|
||||||
|
UNRARCALLBACK Callback;
|
||||||
|
CHANGEVOLPROC ChangeVolProc;
|
||||||
|
PROCESSDATAPROC ProcessDataProc;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,245 @@
|
|||||||
|
#ifndef _RAR_OS_
|
||||||
|
#define _RAR_OS_
|
||||||
|
|
||||||
|
#define FALSE 0
|
||||||
|
#define TRUE 1
|
||||||
|
|
||||||
|
#ifdef __EMX__
|
||||||
|
#define INCL_BASE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN_32) || defined(_EMX)
|
||||||
|
#define ENABLE_BAD_ALLOC
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if defined(_WIN_32) || defined(_EMX)
|
||||||
|
|
||||||
|
#define LITTLE_ENDIAN
|
||||||
|
#define NM 1024
|
||||||
|
|
||||||
|
#ifdef _WIN_32
|
||||||
|
|
||||||
|
#define STRICT
|
||||||
|
#undef WINVER
|
||||||
|
#undef _WIN32_WINNT
|
||||||
|
#define WINVER 0x0400
|
||||||
|
#define _WIN32_WINNT 0x0300
|
||||||
|
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
#include <prsht.h>
|
||||||
|
|
||||||
|
#ifndef _WIN_CE
|
||||||
|
#include <winioctl.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WIN_CE
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(_EMX) && !defined(_MSC_VER) && !defined(_WIN_CE)
|
||||||
|
#include <dir.h>
|
||||||
|
#endif
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define for if (0) ; else for
|
||||||
|
#ifndef _WIN_CE
|
||||||
|
#include <direct.h>
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#include <dirent.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WIN_CE
|
||||||
|
#include <share.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(ENABLE_BAD_ALLOC) && !defined(_WIN_CE)
|
||||||
|
#include <new.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _EMX
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <grp.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#ifdef _DJGPP
|
||||||
|
#include <utime.h>
|
||||||
|
#else
|
||||||
|
#include <os2.h>
|
||||||
|
#include <sys/utime.h>
|
||||||
|
#include <emx/syscalls.h>
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#if defined(_MSC_VER) || defined(__MINGW32__)
|
||||||
|
#include <exception>
|
||||||
|
#else
|
||||||
|
#include <except.h>
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#ifndef _WIN_CE
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <dos.h>
|
||||||
|
#include <io.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
#ifdef _WIN_32
|
||||||
|
#pragma hdrstop
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define ENABLE_ACCESS
|
||||||
|
|
||||||
|
#define DefConfigName "rar.ini"
|
||||||
|
#define DefLogName "rar.log"
|
||||||
|
|
||||||
|
|
||||||
|
#define PATHDIVIDER "\\"
|
||||||
|
#define PATHDIVIDERW L"\\"
|
||||||
|
#define CPATHDIVIDER '\\'
|
||||||
|
#define MASKALL "*"
|
||||||
|
#define MASKALLW L"*"
|
||||||
|
|
||||||
|
#define READBINARY "rb"
|
||||||
|
#define READTEXT "rt"
|
||||||
|
#define UPDATEBINARY "r+b"
|
||||||
|
#define CREATEBINARY "w+b"
|
||||||
|
#define APPENDTEXT "at"
|
||||||
|
|
||||||
|
#if defined(_WIN_32)
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define _stdfunction __cdecl
|
||||||
|
#else
|
||||||
|
#define _stdfunction _USERENTRY
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
|
#define _stdfunction
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _UNIX
|
||||||
|
|
||||||
|
#define NM 1024
|
||||||
|
|
||||||
|
#ifdef _BEOS
|
||||||
|
#include <fs_info.h>
|
||||||
|
#include <fs_attr.h>
|
||||||
|
#ifdef __INTEL__
|
||||||
|
#define LITTLE_ENDIAN
|
||||||
|
#else
|
||||||
|
#define BIG_ENDIAN
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <File.h>
|
||||||
|
#if defined(__QNXNTO__)
|
||||||
|
#include <sys/param.h>
|
||||||
|
#endif
|
||||||
|
#if defined(__FreeBSD__) || defined (__NetBSD__) || defined (__OpenBSD__) || defined(__APPLE__)
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#else
|
||||||
|
#endif
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <grp.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <utime.h>
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
#ifdef S_IFLNK
|
||||||
|
#define SAVE_LINKS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ENABLE_ACCESS
|
||||||
|
|
||||||
|
#define DefConfigName ".rarrc"
|
||||||
|
#define DefLogName ".rarlog"
|
||||||
|
|
||||||
|
|
||||||
|
#define PATHDIVIDER "/"
|
||||||
|
#define PATHDIVIDERW L"/"
|
||||||
|
#define CPATHDIVIDER '/'
|
||||||
|
#define MASKALL "*"
|
||||||
|
#define MASKALLW L"*"
|
||||||
|
|
||||||
|
#define READBINARY "r"
|
||||||
|
#define READTEXT "r"
|
||||||
|
#define UPDATEBINARY "r+"
|
||||||
|
#define CREATEBINARY "w+"
|
||||||
|
#define APPENDTEXT "a"
|
||||||
|
|
||||||
|
#define _stdfunction
|
||||||
|
|
||||||
|
#ifdef _APPLE
|
||||||
|
#if defined(__BIG_ENDIAN__) && !defined(BIG_ENDIAN)
|
||||||
|
#define BIG_ENDIAN
|
||||||
|
#undef LITTLE_ENDIAN
|
||||||
|
#endif
|
||||||
|
#if defined(__i386__) && !defined(LITTLE_ENDIAN)
|
||||||
|
#define LITTLE_ENDIAN
|
||||||
|
#undef BIG_ENDIAN
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__sparc) || defined(sparc) || defined(__hpux)
|
||||||
|
#ifndef BIG_ENDIAN
|
||||||
|
#define BIG_ENDIAN
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef const char* MSGID;
|
||||||
|
|
||||||
|
#define safebuf static
|
||||||
|
|
||||||
|
#if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
|
||||||
|
#if defined(BYTE_ORDER) && BYTE_ORDER == BIG_ENDIAN
|
||||||
|
#undef LITTLE_ENDIAN
|
||||||
|
#elif defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN
|
||||||
|
#undef BIG_ENDIAN
|
||||||
|
#else
|
||||||
|
#error "Both LITTLE_ENDIAN and BIG_ENDIAN are defined. Undef something one"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(BIG_ENDIAN) && !defined(_WIN_CE) && defined(_WIN_32)
|
||||||
|
/* allow not aligned integer access, increases speed in some operations */
|
||||||
|
#define ALLOW_NOT_ALIGNED_INT
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__sparc) || defined(sparc) || defined(__sparcv9)
|
||||||
|
/* prohibit not aligned access to data structures in text comression
|
||||||
|
algorithm, increases memory requirements */
|
||||||
|
#define STRICT_ALIGNMENT_REQUIRED
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // _RAR_OS_
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
#include <os2.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void ExtractOS2EA(Archive &Arc,char *FileName)
|
||||||
|
{
|
||||||
|
if (_osmode != OS2_MODE)
|
||||||
|
{
|
||||||
|
mprintf(St(MSkipEA));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Arc.HeaderCRC!=Arc.EAHead.HeadCRC)
|
||||||
|
{
|
||||||
|
Log(Arc.FileName,St(MEABroken),FileName);
|
||||||
|
ErrHandler.SetErrorCode(CRC_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Arc.EAHead.Method<0x31 || Arc.EAHead.Method>0x35 || Arc.EAHead.UnpVer>PACK_VER)
|
||||||
|
{
|
||||||
|
Log(Arc.FileName,St(MEAUnknHeader),FileName);
|
||||||
|
ErrHandler.SetErrorCode(WARNING);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct StructEAOP2
|
||||||
|
{
|
||||||
|
char *GEAPtr;
|
||||||
|
char *FEAPtr;
|
||||||
|
unsigned long Error;
|
||||||
|
} EAOP2;
|
||||||
|
|
||||||
|
ComprDataIO DataIO;
|
||||||
|
Unpack Unpack(&DataIO);
|
||||||
|
Unpack.Init();
|
||||||
|
|
||||||
|
Array<unsigned char> UnpData(Arc.EAHead.UnpSize);
|
||||||
|
DataIO.SetUnpackToMemory(&UnpData[0],Arc.EAHead.UnpSize);
|
||||||
|
DataIO.SetPackedSizeToRead(Arc.EAHead.DataSize);
|
||||||
|
DataIO.EnableShowProgress(false);
|
||||||
|
DataIO.SetFiles(&Arc,NULL);
|
||||||
|
Unpack.SetDestSize(Arc.EAHead.UnpSize);
|
||||||
|
Unpack.DoUnpack(Arc.EAHead.UnpVer,false);
|
||||||
|
|
||||||
|
if (Arc.EAHead.EACRC!=~DataIO.UnpFileCRC)
|
||||||
|
{
|
||||||
|
Log(Arc.FileName,St(MEABroken),FileName);
|
||||||
|
ErrHandler.SetErrorCode(CRC_ERROR);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
EAOP2.FEAPtr=(char *)&UnpData[0];
|
||||||
|
EAOP2.GEAPtr=NULL;
|
||||||
|
if (DosSetPathInfo((unsigned char *)FileName,2,&EAOP2,sizeof(EAOP2),0x10)!=0)
|
||||||
|
{
|
||||||
|
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||||
|
ErrHandler.SetErrorCode(WARNING);
|
||||||
|
}
|
||||||
|
File::SetCloseFileTimeByName(FileName,&Arc.NewLhd.mtime,&Arc.NewLhd.atime);
|
||||||
|
mprintf(St(MShowEA));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ExtractOS2EANew(Archive &Arc,char *FileName)
|
||||||
|
{
|
||||||
|
if (_osmode != OS2_MODE)
|
||||||
|
{
|
||||||
|
mprintf(St(MSkipEA));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array<byte> SubData;
|
||||||
|
if (!Arc.ReadSubData(&SubData,NULL))
|
||||||
|
return;
|
||||||
|
|
||||||
|
struct StructEAOP2
|
||||||
|
{
|
||||||
|
char *GEAPtr;
|
||||||
|
char *FEAPtr;
|
||||||
|
unsigned long Error;
|
||||||
|
} EAOP2;
|
||||||
|
|
||||||
|
EAOP2.FEAPtr=(char *)&SubData[0];
|
||||||
|
EAOP2.GEAPtr=NULL;
|
||||||
|
if (DosSetPathInfo((unsigned char *)FileName,2,&EAOP2,sizeof(EAOP2),0x10)!=0)
|
||||||
|
{
|
||||||
|
Log(Arc.FileName,St(MCannotSetEA),FileName);
|
||||||
|
ErrHandler.SetErrorCode(WARNING);
|
||||||
|
}
|
||||||
|
File::SetCloseFileTimeByName(FileName,&Arc.NewLhd.mtime,&Arc.NewLhd.atime);
|
||||||
|
mprintf(St(MShowEA));
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,645 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
char* PointToName(const char *Path)
|
||||||
|
{
|
||||||
|
const char *Found=NULL;
|
||||||
|
for (const char *s=Path;*s!=0;s=charnext(s))
|
||||||
|
if (IsPathDiv(*s))
|
||||||
|
Found=(char*)(s+1);
|
||||||
|
if (Found!=NULL)
|
||||||
|
return((char*)Found);
|
||||||
|
return (char*)((*Path && IsDriveDiv(Path[1]) && charnext(Path)==Path+1) ? Path+2:Path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wchar* PointToName(const wchar *Path)
|
||||||
|
{
|
||||||
|
for (int I=strlenw(Path)-1;I>=0;I--)
|
||||||
|
if (IsPathDiv(Path[I]))
|
||||||
|
return (wchar*)&Path[I+1];
|
||||||
|
return (wchar*)((*Path && IsDriveDiv(Path[1])) ? Path+2:Path);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* PointToLastChar(const char *Path)
|
||||||
|
{
|
||||||
|
for (const char *s=Path,*p=Path;;p=s,s=charnext(s))
|
||||||
|
if (*s==0)
|
||||||
|
return((char *)p);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* ConvertPath(const char *SrcPath,char *DestPath)
|
||||||
|
{
|
||||||
|
const char *DestPtr=SrcPath;
|
||||||
|
|
||||||
|
/* prevents \..\ in any part of path string */
|
||||||
|
for (const char *s=DestPtr;*s!=0;s++)
|
||||||
|
if (IsPathDiv(s[0]) && s[1]=='.' && s[2]=='.' && IsPathDiv(s[3]))
|
||||||
|
DestPtr=s+4;
|
||||||
|
|
||||||
|
/* removes any sequence of . and \ in the beginning of path string */
|
||||||
|
while (*DestPtr)
|
||||||
|
{
|
||||||
|
const char *s=DestPtr;
|
||||||
|
if (s[0] && IsDriveDiv(s[1]))
|
||||||
|
s+=2;
|
||||||
|
if (s[0]=='\\' && s[1]=='\\')
|
||||||
|
{
|
||||||
|
const char *Slash=strchr(s+2,'\\');
|
||||||
|
if (Slash!=NULL && (Slash=strchr(Slash+1,'\\'))!=NULL)
|
||||||
|
s=Slash+1;
|
||||||
|
}
|
||||||
|
for (const char *t=s;*t!=0;t++)
|
||||||
|
if (IsPathDiv(*t))
|
||||||
|
s=t+1;
|
||||||
|
else
|
||||||
|
if (*t!='.')
|
||||||
|
break;
|
||||||
|
if (s==DestPtr)
|
||||||
|
break;
|
||||||
|
DestPtr=s;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* code above does not remove last "..", doing here */
|
||||||
|
if (DestPtr[0]=='.' && DestPtr[1]=='.' && DestPtr[2]==0)
|
||||||
|
DestPtr+=2;
|
||||||
|
|
||||||
|
if (DestPath!=NULL)
|
||||||
|
{
|
||||||
|
char TmpStr[NM];
|
||||||
|
strncpy(TmpStr,DestPtr,sizeof(TmpStr)-1);
|
||||||
|
strcpy(DestPath,TmpStr);
|
||||||
|
}
|
||||||
|
return((char *)DestPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wchar* ConvertPath(const wchar *SrcPath,wchar *DestPath)
|
||||||
|
{
|
||||||
|
const wchar *DestPtr=SrcPath;
|
||||||
|
for (const wchar *s=DestPtr;*s!=0;s++)
|
||||||
|
if (IsPathDiv(s[0]) && s[1]=='.' && s[2]=='.' && IsPathDiv(s[3]))
|
||||||
|
DestPtr=s+4;
|
||||||
|
while (*DestPtr)
|
||||||
|
{
|
||||||
|
const wchar *s=DestPtr;
|
||||||
|
if (s[0] && IsDriveDiv(s[1]))
|
||||||
|
s+=2;
|
||||||
|
if (s[0]=='\\' && s[1]=='\\')
|
||||||
|
{
|
||||||
|
const wchar *Slash=strchrw(s+2,'\\');
|
||||||
|
if (Slash!=NULL && (Slash=strchrw(Slash+1,'\\'))!=NULL)
|
||||||
|
s=Slash+1;
|
||||||
|
}
|
||||||
|
for (const wchar *t=s;*t!=0;t++)
|
||||||
|
if (IsPathDiv(*t))
|
||||||
|
s=t+1;
|
||||||
|
else
|
||||||
|
if (*t!='.')
|
||||||
|
break;
|
||||||
|
if (s==DestPtr)
|
||||||
|
break;
|
||||||
|
DestPtr=s;
|
||||||
|
}
|
||||||
|
if (DestPath!=NULL)
|
||||||
|
{
|
||||||
|
wchar TmpStr[NM];
|
||||||
|
strncpyw(TmpStr,DestPtr,sizeof(TmpStr)/sizeof(TmpStr[0])-1);
|
||||||
|
strcpyw(DestPath,TmpStr);
|
||||||
|
}
|
||||||
|
return((wchar *)DestPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SetExt(char *Name,const char *NewExt)
|
||||||
|
{
|
||||||
|
char *Dot=GetExt(Name);
|
||||||
|
if (NewExt==NULL)
|
||||||
|
{
|
||||||
|
if (Dot!=NULL)
|
||||||
|
*Dot=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (Dot==NULL)
|
||||||
|
{
|
||||||
|
strcat(Name,".");
|
||||||
|
strcat(Name,NewExt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strcpy(Dot+1,NewExt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
void SetExt(wchar *Name,const wchar *NewExt)
|
||||||
|
{
|
||||||
|
if (Name==NULL || *Name==0)
|
||||||
|
return;
|
||||||
|
wchar *Dot=GetExt(Name);
|
||||||
|
if (NewExt==NULL)
|
||||||
|
{
|
||||||
|
if (Dot!=NULL)
|
||||||
|
*Dot=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (Dot==NULL)
|
||||||
|
{
|
||||||
|
strcatw(Name,L".");
|
||||||
|
strcatw(Name,NewExt);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strcpyw(Dot+1,NewExt);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
void SetSFXExt(char *SFXName)
|
||||||
|
{
|
||||||
|
#ifdef _UNIX
|
||||||
|
SetExt(SFXName,"sfx");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN_32) || defined(_EMX)
|
||||||
|
SetExt(SFXName,"exe");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
void SetSFXExt(wchar *SFXName)
|
||||||
|
{
|
||||||
|
if (SFXName==NULL || *SFXName==0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef _UNIX
|
||||||
|
SetExt(SFXName,L"sfx");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_WIN_32) || defined(_EMX)
|
||||||
|
SetExt(SFXName,L"exe");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
char *GetExt(const char *Name)
|
||||||
|
{
|
||||||
|
return(strrchrd(PointToName(Name),'.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
wchar *GetExt(const wchar *Name)
|
||||||
|
{
|
||||||
|
return(Name==NULL ? (wchar *)L"":strrchrw(PointToName(Name),'.'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool CmpExt(const char *Name,const char *Ext)
|
||||||
|
{
|
||||||
|
char *NameExt=GetExt(Name);
|
||||||
|
return(NameExt!=NULL && stricomp(NameExt+1,Ext)==0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsWildcard(const char *Str,const wchar *StrW)
|
||||||
|
{
|
||||||
|
if (StrW!=NULL && *StrW!=0)
|
||||||
|
return(strpbrkw(StrW,L"*?")!=NULL);
|
||||||
|
return(Str==NULL ? false:strpbrk(Str,"*?")!=NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsPathDiv(int Ch)
|
||||||
|
{
|
||||||
|
#if defined(_WIN_32) || defined(_EMX)
|
||||||
|
return(Ch=='\\' || Ch=='/');
|
||||||
|
#else
|
||||||
|
return(Ch==CPATHDIVIDER);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsDriveDiv(int Ch)
|
||||||
|
{
|
||||||
|
#ifdef _UNIX
|
||||||
|
return(false);
|
||||||
|
#else
|
||||||
|
return(Ch==':');
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int GetPathDisk(const char *Path)
|
||||||
|
{
|
||||||
|
if (IsDiskLetter(Path))
|
||||||
|
return(toupper(*Path)-'A');
|
||||||
|
else
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AddEndSlash(char *Path)
|
||||||
|
{
|
||||||
|
char *LastChar=PointToLastChar(Path);
|
||||||
|
if (*LastChar!=0 && *LastChar!=CPATHDIVIDER)
|
||||||
|
strcat(LastChar,PATHDIVIDER);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void AddEndSlash(wchar *Path)
|
||||||
|
{
|
||||||
|
int Length=strlenw(Path);
|
||||||
|
if (Length>0 && Path[Length-1]!=CPATHDIVIDER)
|
||||||
|
strcatw(Path,PATHDIVIDERW);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GetFilePath(const char *FullName,char *Path)
|
||||||
|
{
|
||||||
|
int PathLength=PointToName(FullName)-FullName;
|
||||||
|
strncpy(Path,FullName,PathLength);
|
||||||
|
Path[PathLength]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GetFilePath(const wchar *FullName,wchar *Path)
|
||||||
|
{
|
||||||
|
const wchar *PathPtr=/*(*FullName && IsDriveDiv(FullName[1])) ? FullName+2:*/FullName;
|
||||||
|
int PathLength=PointToName(FullName)-FullName;
|
||||||
|
strncpyw(Path,PathPtr,PathLength);
|
||||||
|
Path[PathLength]=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RemoveNameFromPath(char *Path)
|
||||||
|
{
|
||||||
|
char *Name=PointToName(Path);
|
||||||
|
if (Name>=Path+2 && (!IsDriveDiv(Path[1]) || Name>=Path+4))
|
||||||
|
Name--;
|
||||||
|
*Name=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
void RemoveNameFromPath(wchar *Path)
|
||||||
|
{
|
||||||
|
wchar *Name=PointToName(Path);
|
||||||
|
if (Name>=Path+2 && (!IsDriveDiv(Path[1]) || Name>=Path+4))
|
||||||
|
Name--;
|
||||||
|
*Name=0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
bool EnumConfigPaths(char *Path,int Number)
|
||||||
|
{
|
||||||
|
#ifdef _EMX
|
||||||
|
static char RARFileName[NM];
|
||||||
|
if (Number==-1)
|
||||||
|
strcpy(RARFileName,Path);
|
||||||
|
if (Number!=0)
|
||||||
|
return(false);
|
||||||
|
if (_osmode==OS2_MODE)
|
||||||
|
{
|
||||||
|
PTIB ptib;
|
||||||
|
PPIB ppib;
|
||||||
|
DosGetInfoBlocks(&ptib, &ppib);
|
||||||
|
DosQueryModuleName(ppib->pib_hmte,NM,Path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strcpy(Path,RARFileName);
|
||||||
|
RemoveNameFromPath(Path);
|
||||||
|
return(true);
|
||||||
|
#elif defined(_UNIX)
|
||||||
|
if (Number==0)
|
||||||
|
{
|
||||||
|
char *EnvStr=getenv("HOME");
|
||||||
|
if (EnvStr==NULL)
|
||||||
|
return(false);
|
||||||
|
strncpy(Path,EnvStr,NM);
|
||||||
|
Path[NM-1]=0;
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
static const char *AltPath[]={
|
||||||
|
"/etc","/etc/rar","/usr/lib","/usr/local/lib","/usr/local/etc"
|
||||||
|
};
|
||||||
|
Number--;
|
||||||
|
if (Number<0 || Number>=sizeof(AltPath)/sizeof(AltPath[0]))
|
||||||
|
return(false);
|
||||||
|
strcpy(Path,AltPath[Number]);
|
||||||
|
return(true);
|
||||||
|
#elif defined(_WIN_32)
|
||||||
|
if (Number!=0)
|
||||||
|
return(false);
|
||||||
|
GetModuleFileName(NULL,Path,NM);
|
||||||
|
RemoveNameFromPath(Path);
|
||||||
|
return(true);
|
||||||
|
#else
|
||||||
|
return(false);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
void GetConfigName(const char *Name,char *FullName,bool CheckExist)
|
||||||
|
{
|
||||||
|
for (int I=0;EnumConfigPaths(FullName,I);I++)
|
||||||
|
{
|
||||||
|
AddEndSlash(FullName);
|
||||||
|
strcat(FullName,Name);
|
||||||
|
if (!CheckExist || WildFileExist(FullName))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
char* GetVolNumPart(char *ArcName)
|
||||||
|
{
|
||||||
|
char *ChPtr=ArcName+strlen(ArcName)-1;
|
||||||
|
while (!isdigit(*ChPtr) && ChPtr>ArcName)
|
||||||
|
ChPtr--;
|
||||||
|
char *NumPtr=ChPtr;
|
||||||
|
while (isdigit(*NumPtr) && NumPtr>ArcName)
|
||||||
|
NumPtr--;
|
||||||
|
while (NumPtr>ArcName && *NumPtr!='.')
|
||||||
|
{
|
||||||
|
if (isdigit(*NumPtr))
|
||||||
|
{
|
||||||
|
char *Dot=strchrd(PointToName(ArcName),'.');
|
||||||
|
if (Dot!=NULL && Dot<NumPtr)
|
||||||
|
ChPtr=NumPtr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
NumPtr--;
|
||||||
|
}
|
||||||
|
return(ChPtr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void NextVolumeName(char *ArcName,bool OldNumbering)
|
||||||
|
{
|
||||||
|
char *ChPtr;
|
||||||
|
if ((ChPtr=GetExt(ArcName))==NULL)
|
||||||
|
{
|
||||||
|
strcat(ArcName,".rar");
|
||||||
|
ChPtr=GetExt(ArcName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (ChPtr[1]==0 || stricomp(ChPtr+1,"exe")==0 || stricomp(ChPtr+1,"sfx")==0)
|
||||||
|
strcpy(ChPtr+1,"rar");
|
||||||
|
if (!OldNumbering)
|
||||||
|
{
|
||||||
|
ChPtr=GetVolNumPart(ArcName);
|
||||||
|
|
||||||
|
while ((++(*ChPtr))=='9'+1)
|
||||||
|
{
|
||||||
|
*ChPtr='0';
|
||||||
|
ChPtr--;
|
||||||
|
if (ChPtr<ArcName || !isdigit(*ChPtr))
|
||||||
|
{
|
||||||
|
for (char *EndPtr=ArcName+strlen(ArcName);EndPtr!=ChPtr;EndPtr--)
|
||||||
|
*(EndPtr+1)=*EndPtr;
|
||||||
|
*(ChPtr+1)='1';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (!isdigit(*(ChPtr+2)) || !isdigit(*(ChPtr+3)))
|
||||||
|
strcpy(ChPtr+2,"00");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ChPtr+=3;
|
||||||
|
while ((++(*ChPtr))=='9'+1)
|
||||||
|
if (*(ChPtr-1)=='.')
|
||||||
|
{
|
||||||
|
*ChPtr='A';
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*ChPtr='0';
|
||||||
|
ChPtr--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsNameUsable(const char *Name)
|
||||||
|
{
|
||||||
|
#ifndef _UNIX
|
||||||
|
if (Name[0] && Name[1] && strchr(Name+2,':')!=NULL)
|
||||||
|
return(false);
|
||||||
|
for (const char *s=Name;*s!=0;s=charnext(s))
|
||||||
|
if (*s<32)
|
||||||
|
return(false);
|
||||||
|
#endif
|
||||||
|
return(*Name!=0 && strpbrk(Name,"?*<>|\"")==NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void MakeNameUsable(char *Name,bool Extended)
|
||||||
|
{
|
||||||
|
for (char *s=Name;*s!=0;s=charnext(s))
|
||||||
|
{
|
||||||
|
if (strchr(Extended ? "?*<>|\"":"?*",*s)!=NULL || Extended && *s<32)
|
||||||
|
*s='_';
|
||||||
|
#ifdef _EMX
|
||||||
|
if (*s=='=')
|
||||||
|
*s='_';
|
||||||
|
#endif
|
||||||
|
#ifndef _UNIX
|
||||||
|
if (s-Name>1 && *s==':')
|
||||||
|
*s='_';
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* UnixSlashToDos(char *SrcName,char *DestName,uint MaxLength)
|
||||||
|
{
|
||||||
|
if (DestName!=NULL && DestName!=SrcName)
|
||||||
|
if (strlen(SrcName)>=MaxLength)
|
||||||
|
{
|
||||||
|
*DestName=0;
|
||||||
|
return(DestName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strcpy(DestName,SrcName);
|
||||||
|
for (char *s=SrcName;*s!=0;s=charnext(s))
|
||||||
|
{
|
||||||
|
if (*s=='/')
|
||||||
|
if (DestName==NULL)
|
||||||
|
*s='\\';
|
||||||
|
else
|
||||||
|
DestName[s-SrcName]='\\';
|
||||||
|
}
|
||||||
|
return(DestName==NULL ? SrcName:DestName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* DosSlashToUnix(char *SrcName,char *DestName,uint MaxLength)
|
||||||
|
{
|
||||||
|
if (DestName!=NULL && DestName!=SrcName)
|
||||||
|
if (strlen(SrcName)>=MaxLength)
|
||||||
|
{
|
||||||
|
*DestName=0;
|
||||||
|
return(DestName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
strcpy(DestName,SrcName);
|
||||||
|
for (char *s=SrcName;*s!=0;s=charnext(s))
|
||||||
|
{
|
||||||
|
if (*s=='\\')
|
||||||
|
if (DestName==NULL)
|
||||||
|
*s='/';
|
||||||
|
else
|
||||||
|
DestName[s-SrcName]='/';
|
||||||
|
}
|
||||||
|
return(DestName==NULL ? SrcName:DestName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsFullPath(const char *Path)
|
||||||
|
{
|
||||||
|
char PathOnly[NM];
|
||||||
|
GetFilePath(Path,PathOnly);
|
||||||
|
if (IsWildcard(PathOnly))
|
||||||
|
return(true);
|
||||||
|
#if defined(_WIN_32) || defined(_EMX)
|
||||||
|
return(Path[0]=='\\' && Path[1]=='\\' ||
|
||||||
|
IsDiskLetter(Path) && IsPathDiv(Path[2]));
|
||||||
|
#else
|
||||||
|
return(IsPathDiv(Path[0]));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool IsDiskLetter(const char *Path)
|
||||||
|
{
|
||||||
|
char Letter=toupper(Path[0]);
|
||||||
|
return(Letter>='A' && Letter<='Z' && IsDriveDiv(Path[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GetPathRoot(const char *Path,char *Root)
|
||||||
|
{
|
||||||
|
*Root=0;
|
||||||
|
if (IsDiskLetter(Path))
|
||||||
|
sprintf(Root,"%c:\\",*Path);
|
||||||
|
else
|
||||||
|
if (Path[0]=='\\' && Path[1]=='\\')
|
||||||
|
{
|
||||||
|
const char *Slash=strchr(Path+2,'\\');
|
||||||
|
if (Slash!=NULL)
|
||||||
|
{
|
||||||
|
int Length;
|
||||||
|
if ((Slash=strchr(Slash+1,'\\'))!=NULL)
|
||||||
|
Length=Slash-Path+1;
|
||||||
|
else
|
||||||
|
Length=strlen(Path);
|
||||||
|
strncpy(Root,Path,Length);
|
||||||
|
Root[Length]=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ParseVersionFileName(char *Name,wchar *NameW,bool Truncate)
|
||||||
|
{
|
||||||
|
int Version=0;
|
||||||
|
char *VerText=strrchrd(Name,';');
|
||||||
|
if (VerText!=NULL)
|
||||||
|
{
|
||||||
|
Version=atoi(VerText+1);
|
||||||
|
if (Truncate)
|
||||||
|
*VerText=0;
|
||||||
|
}
|
||||||
|
if (NameW!=NULL)
|
||||||
|
{
|
||||||
|
wchar *VerTextW=strrchrw(NameW,';');
|
||||||
|
if (VerTextW!=NULL)
|
||||||
|
{
|
||||||
|
if (Version==0)
|
||||||
|
Version=atoiw(VerTextW+1);
|
||||||
|
if (Truncate)
|
||||||
|
*VerTextW=0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(Version);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
char* VolNameToFirstName(const char *VolName,char *FirstName,bool NewNumbering)
|
||||||
|
{
|
||||||
|
if (FirstName!=VolName)
|
||||||
|
strcpy(FirstName,VolName);
|
||||||
|
char *VolNumStart=FirstName;
|
||||||
|
if (NewNumbering)
|
||||||
|
{
|
||||||
|
int N='1';
|
||||||
|
for (char *ChPtr=GetVolNumPart(FirstName);ChPtr>FirstName;ChPtr--)
|
||||||
|
if (isdigit(*ChPtr))
|
||||||
|
{
|
||||||
|
*ChPtr=N;
|
||||||
|
N='0';
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (N=='0')
|
||||||
|
{
|
||||||
|
VolNumStart=ChPtr+1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SetExt(FirstName,"rar");
|
||||||
|
VolNumStart=GetExt(FirstName);
|
||||||
|
}
|
||||||
|
if (!FileExist(FirstName))
|
||||||
|
{
|
||||||
|
char Mask[NM];
|
||||||
|
strcpy(Mask,FirstName);
|
||||||
|
SetExt(Mask,"*");
|
||||||
|
FindFile Find;
|
||||||
|
Find.SetMask(Mask);
|
||||||
|
struct FindData FD;
|
||||||
|
while (Find.Next(&FD))
|
||||||
|
{
|
||||||
|
Archive Arc;
|
||||||
|
if (Arc.Open(FD.Name,FD.NameW) && Arc.IsArchive(true) && !Arc.NotFirstVolume)
|
||||||
|
{
|
||||||
|
strcpy(FirstName,FD.Name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(VolNumStart);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
wchar* GetWideName(const char *Name,const wchar *NameW,wchar *DestW)
|
||||||
|
{
|
||||||
|
if (NameW!=NULL && *NameW!=0)
|
||||||
|
{
|
||||||
|
if (DestW!=NameW)
|
||||||
|
strcpyw(DestW,NameW);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CharToWide(Name,DestW);
|
||||||
|
return(DestW);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
#ifndef _RAR_PATHFN_
|
||||||
|
#define _RAR_PATHFN_
|
||||||
|
|
||||||
|
char* PointToName(const char *Path);
|
||||||
|
wchar* PointToName(const wchar *Path);
|
||||||
|
char* PointToLastChar(const char *Path);
|
||||||
|
char* ConvertPath(const char *SrcPath,char *DestPath);
|
||||||
|
wchar* ConvertPath(const wchar *SrcPath,wchar *DestPath);
|
||||||
|
void SetExt(char *Name,const char *NewExt);
|
||||||
|
void SetExt(wchar *Name,const wchar *NewExt);
|
||||||
|
void SetSFXExt(char *SFXName);
|
||||||
|
void SetSFXExt(wchar *SFXName);
|
||||||
|
char *GetExt(const char *Name);
|
||||||
|
wchar *GetExt(const wchar *Name);
|
||||||
|
bool CmpExt(const char *Name,const char *Ext);
|
||||||
|
bool IsWildcard(const char *Str,const wchar *StrW=NULL);
|
||||||
|
bool IsPathDiv(int Ch);
|
||||||
|
bool IsDriveDiv(int Ch);
|
||||||
|
int GetPathDisk(const char *Path);
|
||||||
|
void AddEndSlash(char *Path);
|
||||||
|
void AddEndSlash(wchar *Path);
|
||||||
|
void GetFilePath(const char *FullName,char *Path);
|
||||||
|
void GetFilePath(const wchar *FullName,wchar *Path);
|
||||||
|
void RemoveNameFromPath(char *Path);
|
||||||
|
void RemoveNameFromPath(wchar *Path);
|
||||||
|
bool EnumConfigPaths(char *Path,int Number);
|
||||||
|
void GetConfigName(const char *Name,char *FullName,bool CheckExist);
|
||||||
|
char* GetVolNumPart(char *ArcName);
|
||||||
|
void NextVolumeName(char *ArcName,bool OldNumbering);
|
||||||
|
bool IsNameUsable(const char *Name);
|
||||||
|
void MakeNameUsable(char *Name,bool Extended);
|
||||||
|
char* UnixSlashToDos(char *SrcName,char *DestName=NULL,uint MaxLength=NM);
|
||||||
|
char* DosSlashToUnix(char *SrcName,char *DestName=NULL,uint MaxLength=NM);
|
||||||
|
bool IsFullPath(const char *Path);
|
||||||
|
bool IsDiskLetter(const char *Path);
|
||||||
|
void GetPathRoot(const char *Path,char *Root);
|
||||||
|
int ParseVersionFileName(char *Name,wchar *NameW,bool Truncate);
|
||||||
|
char* VolNameToFirstName(const char *VolName,char *FirstName,bool NewNumbering);
|
||||||
|
wchar* GetWideName(const char *Name,const wchar *NameW,wchar *DestW);
|
||||||
|
|
||||||
|
|
||||||
|
inline char* GetOutputName(const char *Name) {return((char *)Name);};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
#include "smallfn.cpp"
|
||||||
|
|
||||||
|
#ifdef _DJGPP
|
||||||
|
extern "C" char **__crt0_glob_function (char *arg) { return 0; }
|
||||||
|
extern "C" void __crt0_load_environment_file (char *progname) { }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(GUI) && !defined(RARDLL)
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
#ifdef _UNIX
|
||||||
|
setlocale(LC_ALL,"");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(_EMX) && !defined(_DJGPP)
|
||||||
|
uni_init(0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(_SFX_RTL_) && !defined(_WIN_32)
|
||||||
|
setbuf(stdout,NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(SFX_MODULE) && defined(_EMX)
|
||||||
|
EnumConfigPaths(argv[0],-1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ErrHandler.SetSignalHandlers(true);
|
||||||
|
|
||||||
|
RARInitData();
|
||||||
|
|
||||||
|
#ifdef SFX_MODULE
|
||||||
|
char ModuleName[NM];
|
||||||
|
#ifdef _WIN_32
|
||||||
|
GetModuleFileName(NULL,ModuleName,sizeof(ModuleName));
|
||||||
|
#else
|
||||||
|
strcpy(ModuleName,argv[0]);
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN_32
|
||||||
|
SetErrorMode(SEM_NOALIGNMENTFAULTEXCEPT|SEM_FAILCRITICALERRORS|SEM_NOOPENFILEERRORBOX);
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ALLOW_EXCEPTIONS
|
||||||
|
try
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
|
||||||
|
CommandData Cmd;
|
||||||
|
#ifdef SFX_MODULE
|
||||||
|
strcpy(Cmd.Command,"X");
|
||||||
|
char *Switch=NULL;
|
||||||
|
#ifdef _SFX_RTL_
|
||||||
|
char *CmdLine=GetCommandLine();
|
||||||
|
if (CmdLine!=NULL && *CmdLine=='\"')
|
||||||
|
CmdLine=strchr(CmdLine+1,'\"');
|
||||||
|
if (CmdLine!=NULL && (CmdLine=strpbrk(CmdLine," /"))!=NULL)
|
||||||
|
{
|
||||||
|
while (isspace(*CmdLine))
|
||||||
|
CmdLine++;
|
||||||
|
Switch=CmdLine;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
Switch=argc>1 ? argv[1]:NULL;
|
||||||
|
#endif
|
||||||
|
if (Switch!=NULL && Cmd.IsSwitch(Switch[0]))
|
||||||
|
{
|
||||||
|
int UpperCmd=toupper(Switch[1]);
|
||||||
|
switch(UpperCmd)
|
||||||
|
{
|
||||||
|
case 'T':
|
||||||
|
case 'V':
|
||||||
|
Cmd.Command[0]=UpperCmd;
|
||||||
|
break;
|
||||||
|
case '?':
|
||||||
|
Cmd.OutHelp();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Cmd.AddArcName(ModuleName,NULL);
|
||||||
|
#else
|
||||||
|
if (Cmd.IsConfigEnabled(argc,argv))
|
||||||
|
{
|
||||||
|
Cmd.ReadConfig(argc,argv);
|
||||||
|
Cmd.ParseEnvVar();
|
||||||
|
}
|
||||||
|
for (int I=1;I<argc;I++)
|
||||||
|
Cmd.ParseArg(argv[I],NULL);
|
||||||
|
#endif
|
||||||
|
Cmd.ParseDone();
|
||||||
|
|
||||||
|
|
||||||
|
InitConsoleOptions(Cmd.MsgStream,Cmd.Sound);
|
||||||
|
InitLogOptions(Cmd.LogName);
|
||||||
|
ErrHandler.SetSilent(Cmd.AllYes || Cmd.MsgStream==MSG_NULL);
|
||||||
|
ErrHandler.SetShutdown(Cmd.Shutdown);
|
||||||
|
|
||||||
|
Cmd.OutTitle();
|
||||||
|
Cmd.ProcessCommand();
|
||||||
|
}
|
||||||
|
#ifdef ALLOW_EXCEPTIONS
|
||||||
|
catch (int ErrCode)
|
||||||
|
{
|
||||||
|
ErrHandler.SetErrorCode(ErrCode);
|
||||||
|
}
|
||||||
|
#ifdef ENABLE_BAD_ALLOC
|
||||||
|
catch (bad_alloc)
|
||||||
|
{
|
||||||
|
ErrHandler.SetErrorCode(MEMORY_ERROR);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
ErrHandler.SetErrorCode(FATAL_ERROR);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
File::RemoveCreated();
|
||||||
|
#if defined(SFX_MODULE) && defined(_DJGPP)
|
||||||
|
_chmod(ModuleName,1,0x20);
|
||||||
|
#endif
|
||||||
|
#if defined(_EMX) && !defined(_DJGPP)
|
||||||
|
uni_done();
|
||||||
|
#endif
|
||||||
|
return(ErrHandler.GetErrorCode());
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
#ifndef _RAR_RARCOMMON_
|
||||||
|
#define _RAR_RARCOMMON_
|
||||||
|
|
||||||
|
#include "raros.hpp"
|
||||||
|
#include "os.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef RARDLL
|
||||||
|
#include "dll.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef _WIN_CE
|
||||||
|
#include "version.hpp"
|
||||||
|
#endif
|
||||||
|
#include "rartypes.hpp"
|
||||||
|
#include "rardefs.hpp"
|
||||||
|
#include "rarlang.hpp"
|
||||||
|
#include "int64.hpp"
|
||||||
|
#include "unicode.hpp"
|
||||||
|
#include "errhnd.hpp"
|
||||||
|
#include "array.hpp"
|
||||||
|
#include "timefn.hpp"
|
||||||
|
#include "headers.hpp"
|
||||||
|
#include "rarfn.hpp"
|
||||||
|
#include "pathfn.hpp"
|
||||||
|
#include "strfn.hpp"
|
||||||
|
#include "strlist.hpp"
|
||||||
|
#include "file.hpp"
|
||||||
|
#include "sha1.hpp"
|
||||||
|
#include "crc.hpp"
|
||||||
|
#include "rijndael.hpp"
|
||||||
|
#include "crypt.hpp"
|
||||||
|
#include "filefn.hpp"
|
||||||
|
#include "filestr.hpp"
|
||||||
|
#include "find.hpp"
|
||||||
|
#include "scantree.hpp"
|
||||||
|
#include "savepos.hpp"
|
||||||
|
#include "getbits.hpp"
|
||||||
|
#include "rdwrfn.hpp"
|
||||||
|
#include "options.hpp"
|
||||||
|
#include "archive.hpp"
|
||||||
|
#include "match.hpp"
|
||||||
|
#include "cmddata.hpp"
|
||||||
|
#include "filcreat.hpp"
|
||||||
|
#include "consio.hpp"
|
||||||
|
#include "system.hpp"
|
||||||
|
#include "isnt.hpp"
|
||||||
|
#include "log.hpp"
|
||||||
|
#include "rawread.hpp"
|
||||||
|
#include "encname.hpp"
|
||||||
|
#include "resource.hpp"
|
||||||
|
#include "compress.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
#include "rarvm.hpp"
|
||||||
|
#include "model.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
#include "unpack.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
#include "extinfo.hpp"
|
||||||
|
#include "extract.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "list.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#include "rs.hpp"
|
||||||
|
#include "recvol.hpp"
|
||||||
|
#include "volume.hpp"
|
||||||
|
#include "smallfn.hpp"
|
||||||
|
#include "ulinks.hpp"
|
||||||
|
|
||||||
|
#include "global.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef _RAR_DEFS_
|
||||||
|
#define _RAR_DEFS_
|
||||||
|
|
||||||
|
#define Min(x,y) (((x)<(y)) ? (x):(y))
|
||||||
|
#define Max(x,y) (((x)>(y)) ? (x):(y))
|
||||||
|
|
||||||
|
#define ASIZE(x) (sizeof(x)/sizeof(x[0]))
|
||||||
|
|
||||||
|
#define MAXPASSWORD 128
|
||||||
|
#define MAXSFXSIZE 0x80000
|
||||||
|
|
||||||
|
#define DefSFXName "default.sfx"
|
||||||
|
#define DefSortListName "rarfiles.lst"
|
||||||
|
|
||||||
|
#ifndef FA_RDONLY
|
||||||
|
#define FA_RDONLY 0x01
|
||||||
|
#define FA_HIDDEN 0x02
|
||||||
|
#define FA_SYSTEM 0x04
|
||||||
|
#define FA_LABEL 0x08
|
||||||
|
#define FA_DIREC 0x10
|
||||||
|
#define FA_ARCH 0x20
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#ifndef _RAR_FN_
|
||||||
|
#define _RAR_FN_
|
||||||
|
|
||||||
|
void RARInitData();
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef _RAR_LANG_
|
||||||
|
#define _RAR_LANG_
|
||||||
|
|
||||||
|
#ifdef USE_RC
|
||||||
|
#include "rarres.hpp"
|
||||||
|
#else
|
||||||
|
#include "loclang.hpp"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
#ifndef _RAR_RAROS_
|
||||||
|
#define _RAR_RAROS_
|
||||||
|
|
||||||
|
#ifdef __EMX__
|
||||||
|
#define _EMX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __DJGPP__
|
||||||
|
#define _DJGPP
|
||||||
|
#define _EMX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__WIN32__) || defined(_WIN32)
|
||||||
|
#define _WIN_32
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32_WCE
|
||||||
|
#define _WIN_32
|
||||||
|
#define _WIN_CE
|
||||||
|
#ifdef WM_FILECHANGEINFO
|
||||||
|
#define PC2002
|
||||||
|
#else
|
||||||
|
#undef PC2002
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __BEOS__
|
||||||
|
#define _UNIX
|
||||||
|
#define _BEOS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#define _UNIX
|
||||||
|
#define _APPLE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if !defined(_EMX) && !defined(_WIN_32) && !defined(_BEOS) && !defined(_APPLE)
|
||||||
|
#define _UNIX
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
#ifndef _RAR_TYPES_
|
||||||
|
#define _RAR_TYPES_
|
||||||
|
|
||||||
|
typedef unsigned char byte; //8 bits
|
||||||
|
typedef unsigned short ushort; //preferably 16 bits, but can be more
|
||||||
|
typedef unsigned int uint; //32 bits or more
|
||||||
|
|
||||||
|
#ifndef __BEOS__
|
||||||
|
typedef unsigned int uint32; //32 bits exactly
|
||||||
|
#endif
|
||||||
|
typedef int sint32; //signed 32 bits exactly
|
||||||
|
#define PRESENT_INT32
|
||||||
|
|
||||||
|
#if defined(_WIN_32) || defined(__GNUC__) || defined(__sgi) || defined(_AIX) || defined(__sun) || defined(__hpux) || defined(_OSF_SOURCE)
|
||||||
|
typedef wchar_t wchar;
|
||||||
|
#else
|
||||||
|
typedef ushort wchar;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define SHORT16(x) (sizeof(ushort)==2 ? (ushort)(x):((x)&0xffff))
|
||||||
|
#define UINT32(x) (sizeof(uint32)==4 ? (uint32)(x):((x)&0xffffffff))
|
||||||
|
|
||||||
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,109 @@
|
|||||||
|
#ifndef _RAR_VM_
|
||||||
|
#define _RAR_VM_
|
||||||
|
|
||||||
|
#define VM_STANDARDFILTERS
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
#define VM_OPTIMIZE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#define VM_MEMSIZE 0x40000
|
||||||
|
#define VM_MEMMASK (VM_MEMSIZE-1)
|
||||||
|
#define VM_GLOBALMEMADDR 0x3C000
|
||||||
|
#define VM_GLOBALMEMSIZE 0x2000
|
||||||
|
#define VM_FIXEDGLOBALSIZE 64
|
||||||
|
|
||||||
|
enum VM_Commands
|
||||||
|
{
|
||||||
|
VM_MOV, VM_CMP, VM_ADD, VM_SUB, VM_JZ, VM_JNZ, VM_INC, VM_DEC,
|
||||||
|
VM_JMP, VM_XOR, VM_AND, VM_OR, VM_TEST, VM_JS, VM_JNS, VM_JB,
|
||||||
|
VM_JBE, VM_JA, VM_JAE, VM_PUSH, VM_POP, VM_CALL, VM_RET, VM_NOT,
|
||||||
|
VM_SHL, VM_SHR, VM_SAR, VM_NEG, VM_PUSHA,VM_POPA, VM_PUSHF,VM_POPF,
|
||||||
|
VM_MOVZX,VM_MOVSX,VM_XCHG, VM_MUL, VM_DIV, VM_ADC, VM_SBB, VM_PRINT,
|
||||||
|
|
||||||
|
#ifdef VM_OPTIMIZE
|
||||||
|
VM_MOVB, VM_MOVD, VM_CMPB, VM_CMPD,
|
||||||
|
|
||||||
|
VM_ADDB, VM_ADDD, VM_SUBB, VM_SUBD, VM_INCB, VM_INCD, VM_DECB, VM_DECD,
|
||||||
|
VM_NEGB, VM_NEGD,
|
||||||
|
#endif
|
||||||
|
|
||||||
|
VM_STANDARD
|
||||||
|
};
|
||||||
|
|
||||||
|
enum VM_StandardFilters {
|
||||||
|
VMSF_NONE, VMSF_E8, VMSF_E8E9, VMSF_ITANIUM, VMSF_RGB, VMSF_AUDIO,
|
||||||
|
VMSF_DELTA, VMSF_UPCASE
|
||||||
|
};
|
||||||
|
|
||||||
|
enum VM_Flags {VM_FC=1,VM_FZ=2,VM_FS=0x80000000};
|
||||||
|
|
||||||
|
enum VM_OpType {VM_OPREG,VM_OPINT,VM_OPREGMEM,VM_OPNONE};
|
||||||
|
|
||||||
|
struct VM_PreparedOperand
|
||||||
|
{
|
||||||
|
VM_OpType Type;
|
||||||
|
uint Data;
|
||||||
|
uint Base;
|
||||||
|
uint *Addr;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct VM_PreparedCommand
|
||||||
|
{
|
||||||
|
VM_Commands OpCode;
|
||||||
|
bool ByteMode;
|
||||||
|
VM_PreparedOperand Op1,Op2;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct VM_PreparedProgram
|
||||||
|
{
|
||||||
|
VM_PreparedProgram() {AltCmd=NULL;}
|
||||||
|
|
||||||
|
Array<VM_PreparedCommand> Cmd;
|
||||||
|
VM_PreparedCommand *AltCmd;
|
||||||
|
int CmdCount;
|
||||||
|
|
||||||
|
Array<byte> GlobalData;
|
||||||
|
Array<byte> StaticData;
|
||||||
|
uint InitR[7];
|
||||||
|
|
||||||
|
byte *FilteredData;
|
||||||
|
unsigned int FilteredDataSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
class RarVM:private BitInput
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
inline uint GetValue(bool ByteMode,uint *Addr);
|
||||||
|
inline void SetValue(bool ByteMode,uint *Addr,uint Value);
|
||||||
|
inline uint* GetOperand(VM_PreparedOperand *CmdOp);
|
||||||
|
void DecodeArg(VM_PreparedOperand &Op,bool ByteMode);
|
||||||
|
#ifdef VM_OPTIMIZE
|
||||||
|
void Optimize(VM_PreparedProgram *Prg);
|
||||||
|
#endif
|
||||||
|
bool ExecuteCode(VM_PreparedCommand *PreparedCode,int CodeSize);
|
||||||
|
#ifdef VM_STANDARDFILTERS
|
||||||
|
VM_StandardFilters IsStandardFilter(byte *Code,int CodeSize);
|
||||||
|
void ExecuteStandardFilter(VM_StandardFilters FilterType);
|
||||||
|
unsigned int FilterItanium_GetBits(byte *Data,int BitPos,int BitCount);
|
||||||
|
void FilterItanium_SetBits(byte *Data,unsigned int BitField,int BitPos,
|
||||||
|
int BitCount);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
byte *Mem;
|
||||||
|
uint R[8];
|
||||||
|
uint Flags;
|
||||||
|
public:
|
||||||
|
RarVM();
|
||||||
|
~RarVM();
|
||||||
|
void Init();
|
||||||
|
void Prepare(byte *Code,int CodeSize,VM_PreparedProgram *Prg);
|
||||||
|
void Execute(VM_PreparedProgram *Prg);
|
||||||
|
void SetValue(uint *Addr,uint Value);
|
||||||
|
void SetMemory(unsigned int Pos,byte *Data,unsigned int DataSize);
|
||||||
|
static uint ReadData(BitInput &Inp);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
#define VMCF_OP0 0
|
||||||
|
#define VMCF_OP1 1
|
||||||
|
#define VMCF_OP2 2
|
||||||
|
#define VMCF_OPMASK 3
|
||||||
|
#define VMCF_BYTEMODE 4
|
||||||
|
#define VMCF_JUMP 8
|
||||||
|
#define VMCF_PROC 16
|
||||||
|
#define VMCF_USEFLAGS 32
|
||||||
|
#define VMCF_CHFLAGS 64
|
||||||
|
|
||||||
|
static byte VM_CmdFlags[]=
|
||||||
|
{
|
||||||
|
/* VM_MOV */ VMCF_OP2 | VMCF_BYTEMODE ,
|
||||||
|
/* VM_CMP */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||||
|
/* VM_ADD */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||||
|
/* VM_SUB */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||||
|
/* VM_JZ */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||||
|
/* VM_JNZ */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||||
|
/* VM_INC */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||||
|
/* VM_DEC */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||||
|
/* VM_JMP */ VMCF_OP1 | VMCF_JUMP ,
|
||||||
|
/* VM_XOR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||||
|
/* VM_AND */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||||
|
/* VM_OR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||||
|
/* VM_TEST */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||||
|
/* VM_JS */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||||
|
/* VM_JNS */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||||
|
/* VM_JB */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||||
|
/* VM_JBE */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||||
|
/* VM_JA */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||||
|
/* VM_JAE */ VMCF_OP1 | VMCF_JUMP | VMCF_USEFLAGS ,
|
||||||
|
/* VM_PUSH */ VMCF_OP1 ,
|
||||||
|
/* VM_POP */ VMCF_OP1 ,
|
||||||
|
/* VM_CALL */ VMCF_OP1 | VMCF_PROC ,
|
||||||
|
/* VM_RET */ VMCF_OP0 | VMCF_PROC ,
|
||||||
|
/* VM_NOT */ VMCF_OP1 | VMCF_BYTEMODE ,
|
||||||
|
/* VM_SHL */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||||
|
/* VM_SHR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||||
|
/* VM_SAR */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||||
|
/* VM_NEG */ VMCF_OP1 | VMCF_BYTEMODE | VMCF_CHFLAGS ,
|
||||||
|
/* VM_PUSHA */ VMCF_OP0 ,
|
||||||
|
/* VM_POPA */ VMCF_OP0 ,
|
||||||
|
/* VM_PUSHF */ VMCF_OP0 | VMCF_USEFLAGS ,
|
||||||
|
/* VM_POPF */ VMCF_OP0 | VMCF_CHFLAGS ,
|
||||||
|
/* VM_MOVZX */ VMCF_OP2 ,
|
||||||
|
/* VM_MOVSX */ VMCF_OP2 ,
|
||||||
|
/* VM_XCHG */ VMCF_OP2 | VMCF_BYTEMODE ,
|
||||||
|
/* VM_MUL */ VMCF_OP2 | VMCF_BYTEMODE ,
|
||||||
|
/* VM_DIV */ VMCF_OP2 | VMCF_BYTEMODE ,
|
||||||
|
/* VM_ADC */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS ,
|
||||||
|
/* VM_SBB */ VMCF_OP2 | VMCF_BYTEMODE | VMCF_USEFLAGS | VMCF_CHFLAGS ,
|
||||||
|
/* VM_PRINT */ VMCF_OP0
|
||||||
|
};
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
RawRead::RawRead(File *SrcFile)
|
||||||
|
{
|
||||||
|
RawRead::SrcFile=SrcFile;
|
||||||
|
ReadPos=0;
|
||||||
|
DataSize=0;
|
||||||
|
#ifndef SHELL_EXT
|
||||||
|
Crypt=NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RawRead::Read(int Size)
|
||||||
|
{
|
||||||
|
#if !defined(SHELL_EXT) && !defined(NOCRYPT)
|
||||||
|
if (Crypt!=NULL)
|
||||||
|
{
|
||||||
|
int CurSize=Data.Size();
|
||||||
|
int SizeToRead=Size-(CurSize-DataSize);
|
||||||
|
if (SizeToRead>0)
|
||||||
|
{
|
||||||
|
int AlignedReadSize=SizeToRead+((~SizeToRead+1)&0xf);
|
||||||
|
Data.Add(AlignedReadSize);
|
||||||
|
int ReadSize=SrcFile->Read(&Data[CurSize],AlignedReadSize);
|
||||||
|
Crypt->DecryptBlock(&Data[CurSize],AlignedReadSize);
|
||||||
|
DataSize+=ReadSize==0 ? 0:Size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
DataSize+=Size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
if (Size!=0)
|
||||||
|
{
|
||||||
|
Data.Add(Size);
|
||||||
|
DataSize+=SrcFile->Read(&Data[DataSize],Size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RawRead::Read(byte *SrcData,int Size)
|
||||||
|
{
|
||||||
|
if (Size!=0)
|
||||||
|
{
|
||||||
|
Data.Add(Size);
|
||||||
|
memcpy(&Data[DataSize],SrcData,Size);
|
||||||
|
DataSize+=Size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RawRead::Get(byte &Field)
|
||||||
|
{
|
||||||
|
Field=Data[ReadPos];
|
||||||
|
ReadPos++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RawRead::Get(ushort &Field)
|
||||||
|
{
|
||||||
|
Field=Data[ReadPos]+(Data[ReadPos+1]<<8);
|
||||||
|
ReadPos+=2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RawRead::Get(uint &Field)
|
||||||
|
{
|
||||||
|
Field=Data[ReadPos]+(Data[ReadPos+1]<<8)+(Data[ReadPos+2]<<16)+
|
||||||
|
(Data[ReadPos+3]<<24);
|
||||||
|
ReadPos+=4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RawRead::Get8(Int64 &Field)
|
||||||
|
{
|
||||||
|
uint Low,High;
|
||||||
|
Get(Low);
|
||||||
|
Get(High);
|
||||||
|
Field=int32to64(High,Low);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RawRead::Get(byte *Field,int Size)
|
||||||
|
{
|
||||||
|
memcpy(Field,&Data[ReadPos],Size);
|
||||||
|
ReadPos+=Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RawRead::Get(wchar *Field,int Size)
|
||||||
|
{
|
||||||
|
RawToWide(&Data[ReadPos],Field,Size);
|
||||||
|
ReadPos+=2*Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint RawRead::GetCRC(bool ProcessedOnly)
|
||||||
|
{
|
||||||
|
return(DataSize>2 ? CRC(0xffffffff,&Data[2],(ProcessedOnly ? ReadPos:DataSize)-2):0xffffffff);
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#ifndef _RAR_RAWREAD_
|
||||||
|
#define _RAR_RAWREAD_
|
||||||
|
|
||||||
|
class RawRead
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Array<byte> Data;
|
||||||
|
File *SrcFile;
|
||||||
|
int DataSize;
|
||||||
|
int ReadPos;
|
||||||
|
#ifndef SHELL_EXT
|
||||||
|
CryptData *Crypt;
|
||||||
|
#endif
|
||||||
|
public:
|
||||||
|
RawRead(File *SrcFile);
|
||||||
|
void Read(int Size);
|
||||||
|
void Read(byte *SrcData,int Size);
|
||||||
|
void Get(byte &Field);
|
||||||
|
void Get(ushort &Field);
|
||||||
|
void Get(uint &Field);
|
||||||
|
void Get8(Int64 &Field);
|
||||||
|
void Get(byte *Field,int Size);
|
||||||
|
void Get(wchar *Field,int Size);
|
||||||
|
uint GetCRC(bool ProcessedOnly);
|
||||||
|
int Size() {return DataSize;}
|
||||||
|
int PaddedSize() {return Data.Size()-DataSize;}
|
||||||
|
#ifndef SHELL_EXT
|
||||||
|
void SetCrypt(CryptData *Crypt) {RawRead::Crypt=Crypt;}
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,260 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
ComprDataIO::ComprDataIO()
|
||||||
|
{
|
||||||
|
Init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ComprDataIO::Init()
|
||||||
|
{
|
||||||
|
UnpackFromMemory=false;
|
||||||
|
UnpackToMemory=false;
|
||||||
|
UnpPackedSize=0;
|
||||||
|
ShowProgress=true;
|
||||||
|
TestMode=false;
|
||||||
|
SkipUnpCRC=false;
|
||||||
|
PackVolume=false;
|
||||||
|
UnpVolume=false;
|
||||||
|
NextVolumeMissing=false;
|
||||||
|
SrcFile=NULL;
|
||||||
|
DestFile=NULL;
|
||||||
|
UnpWrSize=0;
|
||||||
|
Command=NULL;
|
||||||
|
Encryption=0;
|
||||||
|
Decryption=0;
|
||||||
|
TotalPackRead=0;
|
||||||
|
CurPackRead=CurPackWrite=CurUnpRead=CurUnpWrite=0;
|
||||||
|
PackFileCRC=UnpFileCRC=PackedCRC=0xffffffff;
|
||||||
|
LastPercent=-1;
|
||||||
|
SubHead=NULL;
|
||||||
|
SubHeadPos=NULL;
|
||||||
|
CurrentCommand=0;
|
||||||
|
ProcessedArcSize=TotalArcSize=0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int ComprDataIO::UnpRead(byte *Addr,uint Count)
|
||||||
|
{
|
||||||
|
int RetCode=0,TotalRead=0;
|
||||||
|
byte *ReadAddr;
|
||||||
|
ReadAddr=Addr;
|
||||||
|
while (Count > 0)
|
||||||
|
{
|
||||||
|
Archive *SrcArc=(Archive *)SrcFile;
|
||||||
|
|
||||||
|
uint ReadSize=(Count>UnpPackedSize) ? int64to32(UnpPackedSize):Count;
|
||||||
|
if (UnpackFromMemory)
|
||||||
|
{
|
||||||
|
memcpy(Addr,UnpackFromMemoryAddr,UnpackFromMemorySize);
|
||||||
|
RetCode=UnpackFromMemorySize;
|
||||||
|
UnpackFromMemorySize=0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!SrcFile->IsOpened())
|
||||||
|
return(-1);
|
||||||
|
RetCode=SrcFile->Read(ReadAddr,ReadSize);
|
||||||
|
FileHeader *hd=SubHead!=NULL ? SubHead:&SrcArc->NewLhd;
|
||||||
|
if (hd->Flags & LHD_SPLIT_AFTER)
|
||||||
|
PackedCRC=CRC(PackedCRC,ReadAddr,ReadSize);
|
||||||
|
}
|
||||||
|
CurUnpRead+=RetCode;
|
||||||
|
ReadAddr+=RetCode;
|
||||||
|
TotalRead+=RetCode;
|
||||||
|
Count-=RetCode;
|
||||||
|
UnpPackedSize-=RetCode;
|
||||||
|
if (UnpPackedSize == 0 && UnpVolume)
|
||||||
|
{
|
||||||
|
#ifndef NOVOLUME
|
||||||
|
if (!MergeArchive(*SrcArc,this,true,CurrentCommand))
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
NextVolumeMissing=true;
|
||||||
|
return(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Archive *SrcArc=(Archive *)SrcFile;
|
||||||
|
if (SrcArc!=NULL)
|
||||||
|
ShowUnpRead(SrcArc->CurBlockPos+CurUnpRead,UnpArcSize);
|
||||||
|
if (RetCode!=-1)
|
||||||
|
{
|
||||||
|
RetCode=TotalRead;
|
||||||
|
#ifndef NOCRYPT
|
||||||
|
if (Decryption)
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (Decryption<20)
|
||||||
|
Decrypt.Crypt(Addr,RetCode,(Decryption==15) ? NEW_CRYPT : OLD_DECODE);
|
||||||
|
else
|
||||||
|
if (Decryption==20)
|
||||||
|
for (int I=0;I<RetCode;I+=16)
|
||||||
|
Decrypt.DecryptBlock20(&Addr[I]);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
int CryptSize=(RetCode & 0xf)==0 ? RetCode:((RetCode & ~0xf)+16);
|
||||||
|
Decrypt.DecryptBlock(Addr,CryptSize);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
Wait();
|
||||||
|
return(RetCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ComprDataIO::UnpWrite(byte *Addr,uint Count)
|
||||||
|
{
|
||||||
|
#ifdef RARDLL
|
||||||
|
RAROptions *Cmd=((Archive *)SrcFile)->GetRAROptions();
|
||||||
|
if (Cmd->DllOpMode!=RAR_SKIP)
|
||||||
|
{
|
||||||
|
if (Cmd->Callback!=NULL &&
|
||||||
|
Cmd->Callback(UCM_PROCESSDATA,Cmd->UserData,(LONG)Addr,Count)==-1)
|
||||||
|
ErrHandler.Exit(USER_BREAK);
|
||||||
|
if (Cmd->ProcessDataProc!=NULL)
|
||||||
|
{
|
||||||
|
#if defined(_WIN_32) && !defined(_MSC_VER) && !defined(__MINGW32__)
|
||||||
|
_EBX=_ESP;
|
||||||
|
#endif
|
||||||
|
int RetCode=Cmd->ProcessDataProc(Addr,Count);
|
||||||
|
#if defined(_WIN_32) && !defined(_MSC_VER) && !defined(__MINGW32__)
|
||||||
|
_ESP=_EBX;
|
||||||
|
#endif
|
||||||
|
if (RetCode==0)
|
||||||
|
ErrHandler.Exit(USER_BREAK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
UnpWrAddr=Addr;
|
||||||
|
UnpWrSize=Count;
|
||||||
|
if (UnpackToMemory)
|
||||||
|
{
|
||||||
|
if (Count <= UnpackToMemorySize)
|
||||||
|
{
|
||||||
|
memcpy(UnpackToMemoryAddr,Addr,Count);
|
||||||
|
UnpackToMemoryAddr+=Count;
|
||||||
|
UnpackToMemorySize-=Count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (!TestMode)
|
||||||
|
DestFile->Write(Addr,Count);
|
||||||
|
CurUnpWrite+=Count;
|
||||||
|
if (!SkipUnpCRC)
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
if (((Archive *)SrcFile)->OldFormat)
|
||||||
|
UnpFileCRC=OldCRC((ushort)UnpFileCRC,Addr,Count);
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
UnpFileCRC=CRC(UnpFileCRC,Addr,Count);
|
||||||
|
ShowUnpWrite();
|
||||||
|
Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void ComprDataIO::ShowUnpRead(Int64 ArcPos,Int64 ArcSize)
|
||||||
|
{
|
||||||
|
if (ShowProgress && SrcFile!=NULL)
|
||||||
|
{
|
||||||
|
Archive *SrcArc=(Archive *)SrcFile;
|
||||||
|
RAROptions *Cmd=SrcArc->GetRAROptions();
|
||||||
|
if (TotalArcSize!=0)
|
||||||
|
ArcSize=TotalArcSize;
|
||||||
|
ArcPos+=ProcessedArcSize;
|
||||||
|
if (!SrcArc->Volume)
|
||||||
|
{
|
||||||
|
int CurPercent=ToPercent(ArcPos,ArcSize);
|
||||||
|
if (!Cmd->DisablePercentage && CurPercent!=LastPercent)
|
||||||
|
{
|
||||||
|
mprintf("\b\b\b\b%3d%%",CurPercent);
|
||||||
|
LastPercent=CurPercent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ComprDataIO::ShowUnpWrite()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void ComprDataIO::SetFiles(File *SrcFile,File *DestFile)
|
||||||
|
{
|
||||||
|
if (SrcFile!=NULL)
|
||||||
|
ComprDataIO::SrcFile=SrcFile;
|
||||||
|
if (DestFile!=NULL)
|
||||||
|
ComprDataIO::DestFile=DestFile;
|
||||||
|
LastPercent=-1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ComprDataIO::GetUnpackedData(byte **Data,uint *Size)
|
||||||
|
{
|
||||||
|
*Data=UnpWrAddr;
|
||||||
|
*Size=UnpWrSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ComprDataIO::SetEncryption(int Method,char *Password,byte *Salt,bool Encrypt,bool HandsOffHash)
|
||||||
|
{
|
||||||
|
if (Encrypt)
|
||||||
|
{
|
||||||
|
Encryption=*Password ? Method:0;
|
||||||
|
#ifndef NOCRYPT
|
||||||
|
Crypt.SetCryptKeys(Password,Salt,Encrypt,false,HandsOffHash);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Decryption=*Password ? Method:0;
|
||||||
|
#ifndef NOCRYPT
|
||||||
|
Decrypt.SetCryptKeys(Password,Salt,Encrypt,Method<29,HandsOffHash);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
void ComprDataIO::SetAV15Encryption()
|
||||||
|
{
|
||||||
|
Decryption=15;
|
||||||
|
Decrypt.SetAV15Encryption();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
void ComprDataIO::SetCmt13Encryption()
|
||||||
|
{
|
||||||
|
Decryption=13;
|
||||||
|
Decrypt.SetCmt13Encryption();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void ComprDataIO::SetUnpackToMemory(byte *Addr,uint Size)
|
||||||
|
{
|
||||||
|
UnpackToMemory=true;
|
||||||
|
UnpackToMemoryAddr=Addr;
|
||||||
|
UnpackToMemorySize=Size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
#ifndef _RAR_DATAIO_
|
||||||
|
#define _RAR_DATAIO_
|
||||||
|
|
||||||
|
class CmdAdd;
|
||||||
|
class Unpack;
|
||||||
|
|
||||||
|
|
||||||
|
class ComprDataIO
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
void ShowUnpRead(Int64 ArcPos,Int64 ArcSize);
|
||||||
|
void ShowUnpWrite();
|
||||||
|
|
||||||
|
|
||||||
|
bool UnpackFromMemory;
|
||||||
|
uint UnpackFromMemorySize;
|
||||||
|
byte *UnpackFromMemoryAddr;
|
||||||
|
|
||||||
|
bool UnpackToMemory;
|
||||||
|
uint UnpackToMemorySize;
|
||||||
|
byte *UnpackToMemoryAddr;
|
||||||
|
|
||||||
|
uint UnpWrSize;
|
||||||
|
byte *UnpWrAddr;
|
||||||
|
|
||||||
|
Int64 UnpPackedSize;
|
||||||
|
|
||||||
|
bool ShowProgress;
|
||||||
|
bool TestMode;
|
||||||
|
bool SkipUnpCRC;
|
||||||
|
|
||||||
|
File *SrcFile;
|
||||||
|
File *DestFile;
|
||||||
|
|
||||||
|
CmdAdd *Command;
|
||||||
|
|
||||||
|
FileHeader *SubHead;
|
||||||
|
Int64 *SubHeadPos;
|
||||||
|
|
||||||
|
#ifndef NOCRYPT
|
||||||
|
CryptData Crypt;
|
||||||
|
CryptData Decrypt;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int LastPercent;
|
||||||
|
|
||||||
|
char CurrentCommand;
|
||||||
|
|
||||||
|
public:
|
||||||
|
ComprDataIO();
|
||||||
|
void Init();
|
||||||
|
int UnpRead(byte *Addr,uint Count);
|
||||||
|
void UnpWrite(byte *Addr,uint Count);
|
||||||
|
void EnableShowProgress(bool Show) {ShowProgress=Show;}
|
||||||
|
void GetUnpackedData(byte **Data,uint *Size);
|
||||||
|
void SetPackedSizeToRead(Int64 Size) {UnpPackedSize=Size;}
|
||||||
|
void SetTestMode(bool Mode) {TestMode=Mode;}
|
||||||
|
void SetSkipUnpCRC(bool Skip) {SkipUnpCRC=Skip;}
|
||||||
|
void SetFiles(File *SrcFile,File *DestFile);
|
||||||
|
void SetCommand(CmdAdd *Cmd) {Command=Cmd;}
|
||||||
|
void SetSubHeader(FileHeader *hd,Int64 *Pos) {SubHead=hd;SubHeadPos=Pos;}
|
||||||
|
void SetEncryption(int Method,char *Password,byte *Salt,bool Encrypt,bool HandsOffHash);
|
||||||
|
void SetAV15Encryption();
|
||||||
|
void SetCmt13Encryption();
|
||||||
|
void SetUnpackToMemory(byte *Addr,uint Size);
|
||||||
|
void SetCurrentCommand(char Cmd) {CurrentCommand=Cmd;}
|
||||||
|
|
||||||
|
bool PackVolume;
|
||||||
|
bool UnpVolume;
|
||||||
|
bool NextVolumeMissing;
|
||||||
|
Int64 TotalPackRead;
|
||||||
|
Int64 UnpArcSize;
|
||||||
|
Int64 CurPackRead,CurPackWrite,CurUnpRead,CurUnpWrite;
|
||||||
|
Int64 ProcessedArcSize,TotalArcSize;
|
||||||
|
|
||||||
|
uint PackFileCRC,UnpFileCRC,PackedCRC;
|
||||||
|
|
||||||
|
int Encryption;
|
||||||
|
int Decryption;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
|
||||||
|
Portable UnRAR version
|
||||||
|
|
||||||
|
|
||||||
|
1. General
|
||||||
|
|
||||||
|
This package includes freeware Unrar C++ source and a few makefiles
|
||||||
|
(makefile.bcc, makefile.msc+msc.dep, makefile.unix). Unrar source
|
||||||
|
is subset of RAR and generated from RAR source automatically,
|
||||||
|
by a small program removing blocks like '#ifndef UNRAR ... #endif'.
|
||||||
|
Such method is not perfect and you may find some RAR related
|
||||||
|
stuff unnecessary in Unrar, especially in header files.
|
||||||
|
|
||||||
|
If you wish to port Unrar to a new platform, you may need to edit
|
||||||
|
'#define LITTLE_ENDIAN' in os.hpp and data type definitions
|
||||||
|
in rartypes.hpp.
|
||||||
|
|
||||||
|
if computer architecture does not allow not aligned data access,
|
||||||
|
you need to undefine ALLOW_NOT_ALIGNED_INT and define
|
||||||
|
STRICT_ALIGNMENT_REQUIRED in os.h. Note that it will increase memory
|
||||||
|
requirements.
|
||||||
|
|
||||||
|
If you use Borland C++ makefile (makefile.bcc), you need to define
|
||||||
|
BASEPATHCC environment (or makefile) variable containing
|
||||||
|
the path to Borland C++ installation.
|
||||||
|
|
||||||
|
Makefile.unix contains numerous compiler option sets.
|
||||||
|
GCC Linux is selected by default. If you need to compile Unrar
|
||||||
|
for other platforms, uncomment corresponding lines.
|
||||||
|
|
||||||
|
|
||||||
|
2. Unrar binaries
|
||||||
|
|
||||||
|
If you compiled Unrar for OS, which is not present in "Downloads"
|
||||||
|
and "RAR extras" on www.rarlab.com, we will appreciate if you send
|
||||||
|
us the compiled executable to place it to our site.
|
||||||
|
|
||||||
|
|
||||||
|
3. Acknowledgements
|
||||||
|
|
||||||
|
This source includes parts of code written by the following authors:
|
||||||
|
|
||||||
|
Dmitry Shkarin PPMII text compression
|
||||||
|
Dmitry Subbotin Carryless rangecoder
|
||||||
|
Szymon Stefanek AES encryption
|
||||||
|
Brian Gladman AES encryption
|
||||||
|
Steve Reid SHA-1 hash function
|
||||||
|
Marcus Herbert makefile.unix file
|
||||||
|
Tomasz Klim fixes for libunrar.so
|
||||||
|
|
||||||
|
|
||||||
|
4. Legal stuff
|
||||||
|
|
||||||
|
Unrar source may be used in any software to handle RAR archives
|
||||||
|
without limitations free of charge, but cannot be used to re-create
|
||||||
|
the RAR compression algorithm, which is proprietary. Distribution
|
||||||
|
of modified Unrar source in separate form or as a part of other
|
||||||
|
software is permitted, provided that it is clearly stated in
|
||||||
|
the documentation and source comments that the code may not be used
|
||||||
|
to develop a RAR (WinRAR) compatible archiver.
|
||||||
|
|
||||||
|
More detailed license text is available in license.txt.
|
||||||
@@ -0,0 +1,367 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
#define RECVOL_BUFSIZE 0x800
|
||||||
|
|
||||||
|
RecVolumes::RecVolumes()
|
||||||
|
{
|
||||||
|
Buf.Alloc(RECVOL_BUFSIZE*256);
|
||||||
|
memset(SrcFile,0,sizeof(SrcFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
RecVolumes::~RecVolumes()
|
||||||
|
{
|
||||||
|
for (uint I=0;I<sizeof(SrcFile)/sizeof(SrcFile[0]);I++)
|
||||||
|
delete SrcFile[I];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool RecVolumes::Restore(RAROptions *Cmd,const char *Name,
|
||||||
|
const wchar *NameW,bool Silent)
|
||||||
|
{
|
||||||
|
char ArcName[NM];
|
||||||
|
wchar ArcNameW[NM];
|
||||||
|
strcpy(ArcName,Name);
|
||||||
|
strcpyw(ArcNameW,NameW);
|
||||||
|
char *Ext=GetExt(ArcName);
|
||||||
|
bool NewStyle=false;
|
||||||
|
bool RevName=Ext!=NULL && stricomp(Ext,".rev")==0;
|
||||||
|
if (RevName)
|
||||||
|
{
|
||||||
|
for (int DigitGroup=0;Ext>ArcName && DigitGroup<3;Ext--)
|
||||||
|
if (!isdigit(*Ext))
|
||||||
|
if (isdigit(*(Ext-1)) && (*Ext=='_' || DigitGroup<2))
|
||||||
|
DigitGroup++;
|
||||||
|
else
|
||||||
|
if (DigitGroup<2)
|
||||||
|
{
|
||||||
|
NewStyle=true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
while (isdigit(*Ext) && Ext>ArcName+1)
|
||||||
|
Ext--;
|
||||||
|
strcpy(Ext,"*.*");
|
||||||
|
FindFile Find;
|
||||||
|
Find.SetMask(ArcName);
|
||||||
|
struct FindData FD;
|
||||||
|
while (Find.Next(&FD))
|
||||||
|
{
|
||||||
|
Archive Arc(Cmd);
|
||||||
|
if (Arc.WOpen(FD.Name,FD.NameW) && Arc.IsArchive(true))
|
||||||
|
{
|
||||||
|
strcpy(ArcName,FD.Name);
|
||||||
|
*ArcNameW=0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Archive Arc(Cmd);
|
||||||
|
if (!Arc.WCheckOpen(ArcName,ArcNameW))
|
||||||
|
return(false);
|
||||||
|
if (!Arc.Volume)
|
||||||
|
{
|
||||||
|
#ifndef SILENT
|
||||||
|
Log(ArcName,St(MNotVolume),ArcName);
|
||||||
|
#endif
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
bool NewNumbering=(Arc.NewMhd.Flags & MHD_NEWNUMBERING);
|
||||||
|
Arc.Close();
|
||||||
|
char *VolNumStart=VolNameToFirstName(ArcName,ArcName,NewNumbering);
|
||||||
|
char RecVolMask[NM];
|
||||||
|
strcpy(RecVolMask,ArcName);
|
||||||
|
int BaseNamePartLength=VolNumStart-ArcName;
|
||||||
|
strcpy(RecVolMask+BaseNamePartLength,"*.rev");
|
||||||
|
|
||||||
|
#ifndef SILENT
|
||||||
|
Int64 RecFileSize=0;
|
||||||
|
#endif
|
||||||
|
FindFile Find;
|
||||||
|
Find.SetMask(RecVolMask);
|
||||||
|
struct FindData RecData;
|
||||||
|
int FileNumber=0,RecVolNumber=0,FoundRecVolumes=0,MissingVolumes=0;
|
||||||
|
char PrevName[NM];
|
||||||
|
while (Find.Next(&RecData))
|
||||||
|
{
|
||||||
|
char *Name=RecData.Name;
|
||||||
|
int P[3];
|
||||||
|
if (!RevName && !NewStyle)
|
||||||
|
{
|
||||||
|
NewStyle=true;
|
||||||
|
char *Dot=GetExt(Name);
|
||||||
|
if (Dot!=NULL)
|
||||||
|
{
|
||||||
|
int LineCount=0;
|
||||||
|
Dot--;
|
||||||
|
while (Dot>Name && *Dot!='.')
|
||||||
|
{
|
||||||
|
if (*Dot=='_')
|
||||||
|
LineCount++;
|
||||||
|
Dot--;
|
||||||
|
}
|
||||||
|
if (LineCount==2)
|
||||||
|
NewStyle=false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (NewStyle)
|
||||||
|
{
|
||||||
|
File CurFile;
|
||||||
|
CurFile.TOpen(Name);
|
||||||
|
CurFile.Seek(0,SEEK_END);
|
||||||
|
Int64 Length=CurFile.Tell();
|
||||||
|
CurFile.Seek(Length-7,SEEK_SET);
|
||||||
|
for (int I=0;I<3;I++)
|
||||||
|
P[2-I]=CurFile.GetByte()+1;
|
||||||
|
uint FileCRC=0;
|
||||||
|
for (int I=0;I<4;I++)
|
||||||
|
FileCRC|=CurFile.GetByte()<<(I*8);
|
||||||
|
if (FileCRC!=CalcFileCRC(&CurFile,Length-4))
|
||||||
|
{
|
||||||
|
#ifndef SILENT
|
||||||
|
mprintf(St(MCRCFailed),Name);
|
||||||
|
#endif
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char *Dot=GetExt(Name);
|
||||||
|
if (Dot==NULL)
|
||||||
|
continue;
|
||||||
|
bool WrongParam=false;
|
||||||
|
for (uint I=0;I<sizeof(P)/sizeof(P[0]);I++)
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
Dot--;
|
||||||
|
} while (isdigit(*Dot) && Dot>=Name+BaseNamePartLength);
|
||||||
|
P[I]=atoi(Dot+1);
|
||||||
|
if (P[I]==0 || P[I]>255)
|
||||||
|
WrongParam=true;
|
||||||
|
}
|
||||||
|
if (WrongParam)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (P[1]+P[2]>255)
|
||||||
|
continue;
|
||||||
|
if (RecVolNumber!=0 && RecVolNumber!=P[1] || FileNumber!=0 && FileNumber!=P[2])
|
||||||
|
{
|
||||||
|
#ifndef SILENT
|
||||||
|
Log(NULL,St(MRecVolDiffSets),Name,PrevName);
|
||||||
|
#endif
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
RecVolNumber=P[1];
|
||||||
|
FileNumber=P[2];
|
||||||
|
strcpy(PrevName,Name);
|
||||||
|
File *NewFile=new File;
|
||||||
|
NewFile->TOpen(Name);
|
||||||
|
SrcFile[FileNumber+P[0]-1]=NewFile;
|
||||||
|
FoundRecVolumes++;
|
||||||
|
#ifndef SILENT
|
||||||
|
if (RecFileSize==0)
|
||||||
|
RecFileSize=NewFile->FileLength();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#ifndef SILENT
|
||||||
|
if (!Silent || FoundRecVolumes!=0)
|
||||||
|
{
|
||||||
|
mprintf(St(MRecVolFound),FoundRecVolumes);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (FoundRecVolumes==0)
|
||||||
|
return(false);
|
||||||
|
|
||||||
|
bool WriteFlags[256];
|
||||||
|
memset(WriteFlags,0,sizeof(WriteFlags));
|
||||||
|
|
||||||
|
char LastVolName[NM];
|
||||||
|
*LastVolName=0;
|
||||||
|
|
||||||
|
for (int CurArcNum=0;CurArcNum<FileNumber;CurArcNum++)
|
||||||
|
{
|
||||||
|
Archive *NewFile=new Archive;
|
||||||
|
bool ValidVolume=FileExist(ArcName);
|
||||||
|
if (ValidVolume)
|
||||||
|
{
|
||||||
|
NewFile->TOpen(ArcName);
|
||||||
|
ValidVolume=NewFile->IsArchive(false);
|
||||||
|
if (ValidVolume)
|
||||||
|
{
|
||||||
|
while (NewFile->ReadHeader()!=0)
|
||||||
|
{
|
||||||
|
if (NewFile->GetHeaderType()==ENDARC_HEAD)
|
||||||
|
{
|
||||||
|
if ((NewFile->EndArcHead.Flags&EARC_DATACRC)!=0 &&
|
||||||
|
NewFile->EndArcHead.ArcDataCRC!=CalcFileCRC(NewFile,NewFile->CurBlockPos))
|
||||||
|
{
|
||||||
|
ValidVolume=false;
|
||||||
|
#ifndef SILENT
|
||||||
|
mprintf(St(MCRCFailed),ArcName);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
NewFile->SeekToNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!ValidVolume)
|
||||||
|
{
|
||||||
|
NewFile->Close();
|
||||||
|
char NewName[NM];
|
||||||
|
strcpy(NewName,ArcName);
|
||||||
|
strcat(NewName,".bad");
|
||||||
|
#ifndef SILENT
|
||||||
|
mprintf(St(MBadArc),ArcName);
|
||||||
|
mprintf(St(MRenaming),ArcName,NewName);
|
||||||
|
#endif
|
||||||
|
rename(ArcName,NewName);
|
||||||
|
}
|
||||||
|
NewFile->Seek(0,SEEK_SET);
|
||||||
|
}
|
||||||
|
if (!ValidVolume)
|
||||||
|
{
|
||||||
|
NewFile->TCreate(ArcName);
|
||||||
|
WriteFlags[CurArcNum]=true;
|
||||||
|
MissingVolumes++;
|
||||||
|
|
||||||
|
if (CurArcNum==FileNumber-1)
|
||||||
|
strcpy(LastVolName,ArcName);
|
||||||
|
|
||||||
|
#ifndef SILENT
|
||||||
|
mprintf(St(MAbsNextVol),ArcName);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
SrcFile[CurArcNum]=(File*)NewFile;
|
||||||
|
NextVolumeName(ArcName,!NewNumbering);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef SILENT
|
||||||
|
mprintf(St(MRecVolMissing),MissingVolumes);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (MissingVolumes==0)
|
||||||
|
{
|
||||||
|
#ifndef SILENT
|
||||||
|
mprintf(St(MRecVolAllExist));
|
||||||
|
#endif
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MissingVolumes>FoundRecVolumes)
|
||||||
|
{
|
||||||
|
#ifndef SILENT
|
||||||
|
mprintf(St(MRecVolCannotFix));
|
||||||
|
#endif
|
||||||
|
return(false);
|
||||||
|
}
|
||||||
|
#ifndef SILENT
|
||||||
|
mprintf(St(MReconstructing));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
RSCoder RSC(RecVolNumber);
|
||||||
|
|
||||||
|
int TotalFiles=FileNumber+RecVolNumber;
|
||||||
|
int Erasures[256],EraSize=0;
|
||||||
|
|
||||||
|
for (int I=0;I<TotalFiles;I++)
|
||||||
|
if (WriteFlags[I] || SrcFile[I]==NULL)
|
||||||
|
Erasures[EraSize++]=I;
|
||||||
|
|
||||||
|
#ifndef SILENT
|
||||||
|
Int64 ProcessedSize=0;
|
||||||
|
#ifndef GUI
|
||||||
|
int LastPercent=-1;
|
||||||
|
mprintf(" ");
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
int RecCount=0;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if ((++RecCount & 15)==0)
|
||||||
|
Wait();
|
||||||
|
int MaxRead=0;
|
||||||
|
for (int I=0;I<TotalFiles;I++)
|
||||||
|
if (WriteFlags[I] || SrcFile[I]==NULL)
|
||||||
|
memset(&Buf[I*RECVOL_BUFSIZE],0,RECVOL_BUFSIZE);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
int ReadSize=SrcFile[I]->Read(&Buf[I*RECVOL_BUFSIZE],RECVOL_BUFSIZE);
|
||||||
|
if (ReadSize!=RECVOL_BUFSIZE)
|
||||||
|
memset(&Buf[I*RECVOL_BUFSIZE+ReadSize],0,RECVOL_BUFSIZE-ReadSize);
|
||||||
|
if (ReadSize>MaxRead)
|
||||||
|
MaxRead=ReadSize;
|
||||||
|
}
|
||||||
|
if (MaxRead==0)
|
||||||
|
break;
|
||||||
|
#ifndef SILENT
|
||||||
|
int CurPercent=ToPercent(ProcessedSize,RecFileSize);
|
||||||
|
if (!Cmd->DisablePercentage && CurPercent!=LastPercent)
|
||||||
|
{
|
||||||
|
mprintf("\b\b\b\b%3d%%",CurPercent);
|
||||||
|
LastPercent=CurPercent;
|
||||||
|
}
|
||||||
|
ProcessedSize+=MaxRead;
|
||||||
|
#endif
|
||||||
|
for (int BufPos=0;BufPos<MaxRead;BufPos++)
|
||||||
|
{
|
||||||
|
byte Data[256];
|
||||||
|
for (int I=0;I<TotalFiles;I++)
|
||||||
|
Data[I]=Buf[I*RECVOL_BUFSIZE+BufPos];
|
||||||
|
RSC.Decode(Data,TotalFiles,Erasures,EraSize);
|
||||||
|
for (int I=0;I<EraSize;I++)
|
||||||
|
Buf[Erasures[I]*RECVOL_BUFSIZE+BufPos]=Data[Erasures[I]];
|
||||||
|
/*
|
||||||
|
for (int I=0;I<FileNumber;I++)
|
||||||
|
Buf[I*RECVOL_BUFSIZE+BufPos]=Data[I];
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
for (int I=0;I<FileNumber;I++)
|
||||||
|
if (WriteFlags[I])
|
||||||
|
SrcFile[I]->Write(&Buf[I*RECVOL_BUFSIZE],MaxRead);
|
||||||
|
}
|
||||||
|
for (int I=0;I<RecVolNumber+FileNumber;I++)
|
||||||
|
if (SrcFile[I]!=NULL)
|
||||||
|
{
|
||||||
|
File *CurFile=SrcFile[I];
|
||||||
|
if (NewStyle && WriteFlags[I])
|
||||||
|
{
|
||||||
|
Int64 Length=CurFile->Tell();
|
||||||
|
CurFile->Seek(Length-7,SEEK_SET);
|
||||||
|
for (int J=0;J<7;J++)
|
||||||
|
CurFile->PutByte(0);
|
||||||
|
}
|
||||||
|
CurFile->Close();
|
||||||
|
SrcFile[I]=NULL;
|
||||||
|
}
|
||||||
|
if (*LastVolName)
|
||||||
|
{
|
||||||
|
Archive Arc(Cmd);
|
||||||
|
if (Arc.Open(LastVolName,NULL,false,true) && Arc.IsArchive(true) &&
|
||||||
|
Arc.SearchBlock(ENDARC_HEAD))
|
||||||
|
{
|
||||||
|
Arc.Seek(Arc.NextBlockPos,SEEK_SET);
|
||||||
|
char Buf[8192];
|
||||||
|
int ReadSize=Arc.Read(Buf,sizeof(Buf));
|
||||||
|
int ZeroCount=0;
|
||||||
|
while (ZeroCount<ReadSize && Buf[ZeroCount]==0)
|
||||||
|
ZeroCount++;
|
||||||
|
if (ZeroCount==ReadSize)
|
||||||
|
{
|
||||||
|
Arc.Seek(Arc.NextBlockPos,SEEK_SET);
|
||||||
|
Arc.Truncate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#if !defined(GUI) && !defined(SILENT)
|
||||||
|
if (!Cmd->DisablePercentage)
|
||||||
|
mprintf("\b\b\b\b100%%");
|
||||||
|
if (!Silent && !Cmd->DisableDone)
|
||||||
|
mprintf(St(MDone));
|
||||||
|
#endif
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
#ifndef _RAR_RECVOL_
|
||||||
|
#define _RAR_RECVOL_
|
||||||
|
|
||||||
|
class RecVolumes
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
File *SrcFile[256];
|
||||||
|
Array<byte> Buf;
|
||||||
|
public:
|
||||||
|
RecVolumes();
|
||||||
|
~RecVolumes();
|
||||||
|
void Make(RAROptions *Cmd,char *ArcName,wchar *ArcNameW);
|
||||||
|
bool Restore(RAROptions *Cmd,const char *Name,const wchar *NameW,bool Silent);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if !defined(SILENT) || !defined(RARDLL)
|
||||||
|
const char *St(MSGID StringId)
|
||||||
|
{
|
||||||
|
return(StringId);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
#ifndef _RAR_RESOURCE_
|
||||||
|
#define _RAR_RESOURCE_
|
||||||
|
|
||||||
|
#if defined(SILENT) && defined(RARDLL)
|
||||||
|
#define St(x) ("")
|
||||||
|
#else
|
||||||
|
const char *St(MSGID StringId);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
inline const char *StT(MSGID StringId) {return(St(StringId));}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,298 @@
|
|||||||
|
/**************************************************************************
|
||||||
|
* This code is based on Szymon Stefanek AES implementation: *
|
||||||
|
* http://www.esat.kuleuven.ac.be/~rijmen/rijndael/rijndael-cpplib.tar.gz *
|
||||||
|
* *
|
||||||
|
* Dynamic tables generation is based on the Brian Gladman work: *
|
||||||
|
* http://fp.gladman.plus.com/cryptography_technology/rijndael *
|
||||||
|
**************************************************************************/
|
||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
const int uKeyLenInBytes=16, m_uRounds=10;
|
||||||
|
|
||||||
|
static byte S[256],S5[256],rcon[30];
|
||||||
|
static byte T1[256][4],T2[256][4],T3[256][4],T4[256][4];
|
||||||
|
static byte T5[256][4],T6[256][4],T7[256][4],T8[256][4];
|
||||||
|
static byte U1[256][4],U2[256][4],U3[256][4],U4[256][4];
|
||||||
|
|
||||||
|
|
||||||
|
inline void Xor128(byte *dest,const byte *arg1,const byte *arg2)
|
||||||
|
{
|
||||||
|
#if defined(PRESENT_INT32) && defined(ALLOW_NOT_ALIGNED_INT)
|
||||||
|
((uint32*)dest)[0]=((uint32*)arg1)[0]^((uint32*)arg2)[0];
|
||||||
|
((uint32*)dest)[1]=((uint32*)arg1)[1]^((uint32*)arg2)[1];
|
||||||
|
((uint32*)dest)[2]=((uint32*)arg1)[2]^((uint32*)arg2)[2];
|
||||||
|
((uint32*)dest)[3]=((uint32*)arg1)[3]^((uint32*)arg2)[3];
|
||||||
|
#else
|
||||||
|
for (int I=0;I<16;I++)
|
||||||
|
dest[I]=arg1[I]^arg2[I];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Xor128(byte *dest,const byte *arg1,const byte *arg2,
|
||||||
|
const byte *arg3,const byte *arg4)
|
||||||
|
{
|
||||||
|
#if defined(PRESENT_INT32) && defined(ALLOW_NOT_ALIGNED_INT)
|
||||||
|
(*(uint32*)dest)=(*(uint32*)arg1)^(*(uint32*)arg2)^(*(uint32*)arg3)^(*(uint32*)arg4);
|
||||||
|
#else
|
||||||
|
for (int I=0;I<4;I++)
|
||||||
|
dest[I]=arg1[I]^arg2[I]^arg3[I]^arg4[I];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline void Copy128(byte *dest,const byte *src)
|
||||||
|
{
|
||||||
|
#if defined(PRESENT_INT32) && defined(ALLOW_NOT_ALIGNED_INT)
|
||||||
|
((uint32*)dest)[0]=((uint32*)src)[0];
|
||||||
|
((uint32*)dest)[1]=((uint32*)src)[1];
|
||||||
|
((uint32*)dest)[2]=((uint32*)src)[2];
|
||||||
|
((uint32*)dest)[3]=((uint32*)src)[3];
|
||||||
|
#else
|
||||||
|
for (int I=0;I<16;I++)
|
||||||
|
dest[I]=src[I];
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// API
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
Rijndael::Rijndael()
|
||||||
|
{
|
||||||
|
if (S[0]==0)
|
||||||
|
GenerateTables();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Rijndael::init(Direction dir,const byte * key,byte * initVector)
|
||||||
|
{
|
||||||
|
m_direction = dir;
|
||||||
|
|
||||||
|
byte keyMatrix[_MAX_KEY_COLUMNS][4];
|
||||||
|
|
||||||
|
for(uint i = 0;i < uKeyLenInBytes;i++)
|
||||||
|
keyMatrix[i >> 2][i & 3] = key[i];
|
||||||
|
|
||||||
|
for(int i = 0;i < MAX_IV_SIZE;i++)
|
||||||
|
m_initVector[i] = initVector[i];
|
||||||
|
|
||||||
|
keySched(keyMatrix);
|
||||||
|
|
||||||
|
if(m_direction == Decrypt)
|
||||||
|
keyEncToDec();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int Rijndael::blockDecrypt(const byte *input, int inputLen, byte *outBuffer)
|
||||||
|
{
|
||||||
|
if (input == 0 || inputLen <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
byte block[16], iv[4][4];
|
||||||
|
memcpy(iv,m_initVector,16);
|
||||||
|
|
||||||
|
int numBlocks=inputLen/16;
|
||||||
|
for (int i = numBlocks; i > 0; i--)
|
||||||
|
{
|
||||||
|
decrypt(input, block);
|
||||||
|
Xor128(block,block,(byte*)iv);
|
||||||
|
#if STRICT_ALIGN
|
||||||
|
memcpy(iv, input, 16);
|
||||||
|
memcpy(outBuf, block, 16);
|
||||||
|
#else
|
||||||
|
Copy128((byte*)iv,input);
|
||||||
|
Copy128(outBuffer,block);
|
||||||
|
#endif
|
||||||
|
input += 16;
|
||||||
|
outBuffer += 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(m_initVector,iv,16);
|
||||||
|
|
||||||
|
return 16*numBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// ALGORITHM
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
void Rijndael::keySched(byte key[_MAX_KEY_COLUMNS][4])
|
||||||
|
{
|
||||||
|
int j,rconpointer = 0;
|
||||||
|
|
||||||
|
// Calculate the necessary round keys
|
||||||
|
// The number of calculations depends on keyBits and blockBits
|
||||||
|
int uKeyColumns = m_uRounds - 6;
|
||||||
|
|
||||||
|
byte tempKey[_MAX_KEY_COLUMNS][4];
|
||||||
|
|
||||||
|
// Copy the input key to the temporary key matrix
|
||||||
|
|
||||||
|
memcpy(tempKey,key,sizeof(tempKey));
|
||||||
|
|
||||||
|
int r = 0;
|
||||||
|
int t = 0;
|
||||||
|
|
||||||
|
// copy values into round key array
|
||||||
|
for(j = 0;(j < uKeyColumns) && (r <= m_uRounds); )
|
||||||
|
{
|
||||||
|
for(;(j < uKeyColumns) && (t < 4); j++, t++)
|
||||||
|
for (int k=0;k<4;k++)
|
||||||
|
m_expandedKey[r][t][k]=tempKey[j][k];
|
||||||
|
|
||||||
|
if(t == 4)
|
||||||
|
{
|
||||||
|
r++;
|
||||||
|
t = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while(r <= m_uRounds)
|
||||||
|
{
|
||||||
|
tempKey[0][0] ^= S[tempKey[uKeyColumns-1][1]];
|
||||||
|
tempKey[0][1] ^= S[tempKey[uKeyColumns-1][2]];
|
||||||
|
tempKey[0][2] ^= S[tempKey[uKeyColumns-1][3]];
|
||||||
|
tempKey[0][3] ^= S[tempKey[uKeyColumns-1][0]];
|
||||||
|
tempKey[0][0] ^= rcon[rconpointer++];
|
||||||
|
|
||||||
|
if (uKeyColumns != 8)
|
||||||
|
for(j = 1; j < uKeyColumns; j++)
|
||||||
|
for (int k=0;k<4;k++)
|
||||||
|
tempKey[j][k] ^= tempKey[j-1][k];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for(j = 1; j < uKeyColumns/2; j++)
|
||||||
|
for (int k=0;k<4;k++)
|
||||||
|
tempKey[j][k] ^= tempKey[j-1][k];
|
||||||
|
|
||||||
|
tempKey[uKeyColumns/2][0] ^= S[tempKey[uKeyColumns/2 - 1][0]];
|
||||||
|
tempKey[uKeyColumns/2][1] ^= S[tempKey[uKeyColumns/2 - 1][1]];
|
||||||
|
tempKey[uKeyColumns/2][2] ^= S[tempKey[uKeyColumns/2 - 1][2]];
|
||||||
|
tempKey[uKeyColumns/2][3] ^= S[tempKey[uKeyColumns/2 - 1][3]];
|
||||||
|
for(j = uKeyColumns/2 + 1; j < uKeyColumns; j++)
|
||||||
|
for (int k=0;k<4;k++)
|
||||||
|
tempKey[j][k] ^= tempKey[j-1][k];
|
||||||
|
}
|
||||||
|
for(j = 0; (j < uKeyColumns) && (r <= m_uRounds); )
|
||||||
|
{
|
||||||
|
for(; (j < uKeyColumns) && (t < 4); j++, t++)
|
||||||
|
for (int k=0;k<4;k++)
|
||||||
|
m_expandedKey[r][t][k] = tempKey[j][k];
|
||||||
|
if(t == 4)
|
||||||
|
{
|
||||||
|
r++;
|
||||||
|
t = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Rijndael::keyEncToDec()
|
||||||
|
{
|
||||||
|
for(int r = 1; r < m_uRounds; r++)
|
||||||
|
{
|
||||||
|
byte n_expandedKey[4][4];
|
||||||
|
for (int i=0;i<4;i++)
|
||||||
|
for (int j=0;j<4;j++)
|
||||||
|
{
|
||||||
|
byte *w=m_expandedKey[r][j];
|
||||||
|
n_expandedKey[j][i]=U1[w[0]][i]^U2[w[1]][i]^U3[w[2]][i]^U4[w[3]][i];
|
||||||
|
}
|
||||||
|
memcpy(m_expandedKey[r],n_expandedKey,sizeof(m_expandedKey[0]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Rijndael::decrypt(const byte a[16], byte b[16])
|
||||||
|
{
|
||||||
|
int r;
|
||||||
|
byte temp[4][4];
|
||||||
|
|
||||||
|
Xor128((byte*)temp,(byte*)a,(byte*)m_expandedKey[m_uRounds]);
|
||||||
|
|
||||||
|
Xor128(b, T5[temp[0][0]],T6[temp[3][1]],T7[temp[2][2]],T8[temp[1][3]]);
|
||||||
|
Xor128(b+4, T5[temp[1][0]],T6[temp[0][1]],T7[temp[3][2]],T8[temp[2][3]]);
|
||||||
|
Xor128(b+8, T5[temp[2][0]],T6[temp[1][1]],T7[temp[0][2]],T8[temp[3][3]]);
|
||||||
|
Xor128(b+12,T5[temp[3][0]],T6[temp[2][1]],T7[temp[1][2]],T8[temp[0][3]]);
|
||||||
|
|
||||||
|
for(r = m_uRounds-1; r > 1; r--)
|
||||||
|
{
|
||||||
|
Xor128((byte*)temp,(byte*)b,(byte*)m_expandedKey[r]);
|
||||||
|
Xor128(b, T5[temp[0][0]],T6[temp[3][1]],T7[temp[2][2]],T8[temp[1][3]]);
|
||||||
|
Xor128(b+4, T5[temp[1][0]],T6[temp[0][1]],T7[temp[3][2]],T8[temp[2][3]]);
|
||||||
|
Xor128(b+8, T5[temp[2][0]],T6[temp[1][1]],T7[temp[0][2]],T8[temp[3][3]]);
|
||||||
|
Xor128(b+12,T5[temp[3][0]],T6[temp[2][1]],T7[temp[1][2]],T8[temp[0][3]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
Xor128((byte*)temp,(byte*)b,(byte*)m_expandedKey[1]);
|
||||||
|
b[ 0] = S5[temp[0][0]];
|
||||||
|
b[ 1] = S5[temp[3][1]];
|
||||||
|
b[ 2] = S5[temp[2][2]];
|
||||||
|
b[ 3] = S5[temp[1][3]];
|
||||||
|
b[ 4] = S5[temp[1][0]];
|
||||||
|
b[ 5] = S5[temp[0][1]];
|
||||||
|
b[ 6] = S5[temp[3][2]];
|
||||||
|
b[ 7] = S5[temp[2][3]];
|
||||||
|
b[ 8] = S5[temp[2][0]];
|
||||||
|
b[ 9] = S5[temp[1][1]];
|
||||||
|
b[10] = S5[temp[0][2]];
|
||||||
|
b[11] = S5[temp[3][3]];
|
||||||
|
b[12] = S5[temp[3][0]];
|
||||||
|
b[13] = S5[temp[2][1]];
|
||||||
|
b[14] = S5[temp[1][2]];
|
||||||
|
b[15] = S5[temp[0][3]];
|
||||||
|
Xor128((byte*)b,(byte*)b,(byte*)m_expandedKey[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define ff_poly 0x011b
|
||||||
|
#define ff_hi 0x80
|
||||||
|
|
||||||
|
#define FFinv(x) ((x) ? pow[255 - log[x]]: 0)
|
||||||
|
|
||||||
|
#define FFmul02(x) (x ? pow[log[x] + 0x19] : 0)
|
||||||
|
#define FFmul03(x) (x ? pow[log[x] + 0x01] : 0)
|
||||||
|
#define FFmul09(x) (x ? pow[log[x] + 0xc7] : 0)
|
||||||
|
#define FFmul0b(x) (x ? pow[log[x] + 0x68] : 0)
|
||||||
|
#define FFmul0d(x) (x ? pow[log[x] + 0xee] : 0)
|
||||||
|
#define FFmul0e(x) (x ? pow[log[x] + 0xdf] : 0)
|
||||||
|
#define fwd_affine(x) \
|
||||||
|
(w = (uint)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), (byte)(0x63^(w^(w>>8))))
|
||||||
|
|
||||||
|
#define inv_affine(x) \
|
||||||
|
(w = (uint)x, w = (w<<1)^(w<<3)^(w<<6), (byte)(0x05^(w^(w>>8))))
|
||||||
|
|
||||||
|
void Rijndael::GenerateTables()
|
||||||
|
{
|
||||||
|
unsigned char pow[512],log[256];
|
||||||
|
int i = 0, w = 1;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
pow[i] = (byte)w;
|
||||||
|
pow[i + 255] = (byte)w;
|
||||||
|
log[w] = (byte)i++;
|
||||||
|
w ^= (w << 1) ^ (w & ff_hi ? ff_poly : 0);
|
||||||
|
} while (w != 1);
|
||||||
|
|
||||||
|
for (int i = 0,w = 1; i < sizeof(rcon)/sizeof(rcon[0]); i++)
|
||||||
|
{
|
||||||
|
rcon[i] = w;
|
||||||
|
w = (w << 1) ^ (w & ff_hi ? ff_poly : 0);
|
||||||
|
}
|
||||||
|
for(int i = 0; i < 256; ++i)
|
||||||
|
{
|
||||||
|
unsigned char b=S[i]=fwd_affine(FFinv((byte)i));
|
||||||
|
T1[i][1]=T1[i][2]=T2[i][2]=T2[i][3]=T3[i][0]=T3[i][3]=T4[i][0]=T4[i][1]=b;
|
||||||
|
T1[i][0]=T2[i][1]=T3[i][2]=T4[i][3]=FFmul02(b);
|
||||||
|
T1[i][3]=T2[i][0]=T3[i][1]=T4[i][2]=FFmul03(b);
|
||||||
|
S5[i] = b = FFinv(inv_affine((byte)i));
|
||||||
|
U1[b][3]=U2[b][0]=U3[b][1]=U4[b][2]=T5[i][3]=T6[i][0]=T7[i][1]=T8[i][2]=FFmul0b(b);
|
||||||
|
U1[b][1]=U2[b][2]=U3[b][3]=U4[b][0]=T5[i][1]=T6[i][2]=T7[i][3]=T8[i][0]=FFmul09(b);
|
||||||
|
U1[b][2]=U2[b][3]=U3[b][0]=U4[b][1]=T5[i][2]=T6[i][3]=T7[i][0]=T8[i][1]=FFmul0d(b);
|
||||||
|
U1[b][0]=U2[b][1]=U3[b][2]=U4[b][3]=T5[i][0]=T6[i][1]=T7[i][2]=T8[i][3]=FFmul0e(b);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#ifndef _RIJNDAEL_H_
|
||||||
|
#define _RIJNDAEL_H_
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* This code is based on Szymon Stefanek AES implementation: *
|
||||||
|
* http://www.esat.kuleuven.ac.be/~rijmen/rijndael/rijndael-cpplib.tar.gz *
|
||||||
|
* *
|
||||||
|
* Dynamic tables generation is based on the Brian Gladman's work: *
|
||||||
|
* http://fp.gladman.plus.com/cryptography_technology/rijndael *
|
||||||
|
**************************************************************************/
|
||||||
|
|
||||||
|
#define _MAX_KEY_COLUMNS (256/32)
|
||||||
|
#define _MAX_ROUNDS 14
|
||||||
|
#define MAX_IV_SIZE 16
|
||||||
|
|
||||||
|
class Rijndael
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum Direction { Encrypt , Decrypt };
|
||||||
|
private:
|
||||||
|
void keySched(byte key[_MAX_KEY_COLUMNS][4]);
|
||||||
|
void keyEncToDec();
|
||||||
|
void encrypt(const byte a[16], byte b[16]);
|
||||||
|
void decrypt(const byte a[16], byte b[16]);
|
||||||
|
void GenerateTables();
|
||||||
|
|
||||||
|
Direction m_direction;
|
||||||
|
byte m_initVector[MAX_IV_SIZE];
|
||||||
|
byte m_expandedKey[_MAX_ROUNDS+1][4][4];
|
||||||
|
public:
|
||||||
|
Rijndael();
|
||||||
|
void init(Direction dir,const byte *key,byte *initVector);
|
||||||
|
int blockEncrypt(const byte *input, int inputLen, byte *outBuffer);
|
||||||
|
int blockDecrypt(const byte *input, int inputLen, byte *outBuffer);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // _RIJNDAEL_H_
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
#define Clean(D,S) {for (int I=0;I<(S);I++) (D)[I]=0;}
|
||||||
|
|
||||||
|
RSCoder::RSCoder(int ParSize)
|
||||||
|
{
|
||||||
|
RSCoder::ParSize=ParSize;
|
||||||
|
FirstBlockDone=false;
|
||||||
|
gfInit();
|
||||||
|
pnInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RSCoder::gfInit()
|
||||||
|
{
|
||||||
|
for (int I=0,J=1;I<MAXPAR;I++)
|
||||||
|
{
|
||||||
|
gfLog[J]=I;
|
||||||
|
gfExp[I]=J;
|
||||||
|
if ((J<<=1)&256)
|
||||||
|
J^=285;
|
||||||
|
}
|
||||||
|
for (int I=MAXPAR;I<MAXPOL;I++)
|
||||||
|
gfExp[I]=gfExp[I-MAXPAR];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
inline int RSCoder::gfMult(int a,int b)
|
||||||
|
{
|
||||||
|
return(a==0 || b == 0 ? 0:gfExp[gfLog[a]+gfLog[b]]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RSCoder::pnInit()
|
||||||
|
{
|
||||||
|
int p1[MAXPAR+1],p2[MAXPAR+1];
|
||||||
|
|
||||||
|
Clean(p2,ParSize);
|
||||||
|
p2[0]=1;
|
||||||
|
for (int I=1;I<=ParSize;I++)
|
||||||
|
{
|
||||||
|
Clean(p1,ParSize);
|
||||||
|
p1[0]=gfExp[I];
|
||||||
|
p1[1]=1;
|
||||||
|
pnMult(p1,p2,GXPol);
|
||||||
|
for (int J=0;J<ParSize;J++)
|
||||||
|
p2[J]=GXPol[J];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RSCoder::pnMult(int *p1,int *p2,int *r)
|
||||||
|
{
|
||||||
|
Clean(r,ParSize);
|
||||||
|
for (int I=0;I<ParSize;I++)
|
||||||
|
if (p1[I]!=0)
|
||||||
|
for(int J=0;J<ParSize-I;J++)
|
||||||
|
r[I+J]^=gfMult(p1[I],p2[J]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RSCoder::Encode(byte *Data,int DataSize,byte *DestData)
|
||||||
|
{
|
||||||
|
int ShiftReg[MAXPAR+1];
|
||||||
|
|
||||||
|
Clean(ShiftReg,ParSize+1);
|
||||||
|
for (int I=0;I<DataSize;I++)
|
||||||
|
{
|
||||||
|
int D=Data[I]^ShiftReg[ParSize-1];
|
||||||
|
for (int J=ParSize-1;J>0;J--)
|
||||||
|
ShiftReg[J]=ShiftReg[J-1]^gfMult(GXPol[J],D);
|
||||||
|
ShiftReg[0]=gfMult(GXPol[0],D);
|
||||||
|
}
|
||||||
|
for (int I=0;I<ParSize;I++)
|
||||||
|
DestData[I]=ShiftReg[ParSize-I-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool RSCoder::Decode(byte *Data,int DataSize,int *EraLoc,int EraSize)
|
||||||
|
{
|
||||||
|
int SynData[MAXPOL];
|
||||||
|
bool AllZeroes=true;
|
||||||
|
for (int I=0;I<ParSize;I++)
|
||||||
|
{
|
||||||
|
int Sum=Data[0],J=1,Exp=gfExp[I+1];
|
||||||
|
for (;J+8<=DataSize;J+=8)
|
||||||
|
{
|
||||||
|
Sum=Data[J]^gfMult(Exp,Sum);
|
||||||
|
Sum=Data[J+1]^gfMult(Exp,Sum);
|
||||||
|
Sum=Data[J+2]^gfMult(Exp,Sum);
|
||||||
|
Sum=Data[J+3]^gfMult(Exp,Sum);
|
||||||
|
Sum=Data[J+4]^gfMult(Exp,Sum);
|
||||||
|
Sum=Data[J+5]^gfMult(Exp,Sum);
|
||||||
|
Sum=Data[J+6]^gfMult(Exp,Sum);
|
||||||
|
Sum=Data[J+7]^gfMult(Exp,Sum);
|
||||||
|
}
|
||||||
|
for (;J<DataSize;J++)
|
||||||
|
Sum=Data[J]^gfMult(Exp,Sum);
|
||||||
|
if ((SynData[I]=Sum)!=0)
|
||||||
|
AllZeroes=false;
|
||||||
|
}
|
||||||
|
if (AllZeroes)
|
||||||
|
return(true);
|
||||||
|
|
||||||
|
if (!FirstBlockDone)
|
||||||
|
{
|
||||||
|
FirstBlockDone=true;
|
||||||
|
Clean(PolB,ParSize+1);
|
||||||
|
PolB[0]=1;
|
||||||
|
for (int EraPos=0;EraPos<EraSize;EraPos++)
|
||||||
|
for (int I=ParSize,M=gfExp[DataSize-EraLoc[EraPos]-1];I>0;I--)
|
||||||
|
PolB[I]^=gfMult(M,PolB[I-1]);
|
||||||
|
|
||||||
|
ErrCount=0;
|
||||||
|
for (int Root=MAXPAR-DataSize;Root<MAXPAR+1;Root++)
|
||||||
|
{
|
||||||
|
int Sum=0;
|
||||||
|
for (int B=0;B<ParSize+1;B++)
|
||||||
|
Sum^=gfMult(gfExp[(B*Root)%MAXPAR],PolB[B]);
|
||||||
|
if (Sum==0)
|
||||||
|
{
|
||||||
|
Dn[ErrCount]=0;
|
||||||
|
for (int I=1;I<ParSize+1;I+=2)
|
||||||
|
Dn[ErrCount]^= gfMult(PolB[I],gfExp[Root*(I-1)%MAXPAR]);
|
||||||
|
ErrorLocs[ErrCount++]=MAXPAR-Root;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int PolD[MAXPOL];
|
||||||
|
pnMult(PolB,SynData,PolD);
|
||||||
|
if ((ErrCount<=ParSize) && ErrCount>0)
|
||||||
|
for (int I=0;I<ErrCount;I++)
|
||||||
|
{
|
||||||
|
int Loc=ErrorLocs[I],DLoc=MAXPAR-Loc,N=0;
|
||||||
|
for (int J=0;J<ParSize;J++)
|
||||||
|
N^=gfMult(PolD[J],gfExp[DLoc*J%MAXPAR]);
|
||||||
|
int DataPos=DataSize-Loc-1;
|
||||||
|
if (DataPos>=0 && DataPos<DataSize)
|
||||||
|
Data[DataPos]^=gfMult(N,gfExp[MAXPAR-gfLog[Dn[I]]]);
|
||||||
|
}
|
||||||
|
return(ErrCount<=ParSize);
|
||||||
|
}
|
||||||
@@ -0,0 +1,32 @@
|
|||||||
|
#ifndef _RAR_RS_
|
||||||
|
#define _RAR_RS_
|
||||||
|
|
||||||
|
#define MAXPAR 255
|
||||||
|
#define MAXPOL 512
|
||||||
|
|
||||||
|
class RSCoder
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
void gfInit();
|
||||||
|
int gfMult(int a,int b);
|
||||||
|
void pnInit();
|
||||||
|
void pnMult(int *p1,int *p2,int *r);
|
||||||
|
|
||||||
|
int gfExp[MAXPOL];
|
||||||
|
int gfLog[MAXPAR+1];
|
||||||
|
|
||||||
|
int GXPol[MAXPOL*2];
|
||||||
|
|
||||||
|
int ErrorLocs[MAXPAR+1],ErrCount;
|
||||||
|
int Dn[MAXPAR+1];
|
||||||
|
|
||||||
|
int ParSize;
|
||||||
|
int PolB[MAXPOL];
|
||||||
|
bool FirstBlockDone;
|
||||||
|
public:
|
||||||
|
RSCoder(int ParSize);
|
||||||
|
void Encode(byte *Data,int DataSize,byte *DestData);
|
||||||
|
bool Decode(byte *Data,int DataSize,int *EraLoc,int EraSize);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
SaveFilePos::SaveFilePos(File &SaveFile)
|
||||||
|
{
|
||||||
|
SaveFilePos::SaveFile=&SaveFile;
|
||||||
|
SavePos=SaveFile.Tell();
|
||||||
|
CloseCount=SaveFile.CloseCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SaveFilePos::~SaveFilePos()
|
||||||
|
{
|
||||||
|
if (CloseCount==SaveFile->CloseCount)
|
||||||
|
SaveFile->Seek(SavePos,SEEK_SET);
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
#ifndef _RAR_SAVEPOS_
|
||||||
|
#define _RAR_SAVEPOS_
|
||||||
|
|
||||||
|
class SaveFilePos
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
File *SaveFile;
|
||||||
|
Int64 SavePos;
|
||||||
|
uint CloseCount;
|
||||||
|
public:
|
||||||
|
SaveFilePos(File &SaveFile);
|
||||||
|
~SaveFilePos();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,279 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
ScanTree::ScanTree(StringList *FileMasks,int Recurse,bool GetLinks,int GetDirs)
|
||||||
|
{
|
||||||
|
ScanTree::FileMasks=FileMasks;
|
||||||
|
ScanTree::Recurse=Recurse;
|
||||||
|
ScanTree::GetLinks=GetLinks;
|
||||||
|
ScanTree::GetDirs=GetDirs;
|
||||||
|
|
||||||
|
SetAllMaskDepth=0;
|
||||||
|
*CurMask=0;
|
||||||
|
*CurMaskW=0;
|
||||||
|
memset(FindStack,0,sizeof(FindStack));
|
||||||
|
Depth=0;
|
||||||
|
Errors=0;
|
||||||
|
FastFindFile=false;
|
||||||
|
*ErrArcName=0;
|
||||||
|
Cmd=NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ScanTree::~ScanTree()
|
||||||
|
{
|
||||||
|
for (int I=Depth;I>=0;I--)
|
||||||
|
if (FindStack[I]!=NULL)
|
||||||
|
delete FindStack[I];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ScanTree::GetNext(FindData *FindData)
|
||||||
|
{
|
||||||
|
if (Depth<0)
|
||||||
|
return(SCAN_DONE);
|
||||||
|
|
||||||
|
int FindCode;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
if ((*CurMask==0 || FastFindFile && Depth==0) && !PrepareMasks())
|
||||||
|
return(SCAN_DONE);
|
||||||
|
FindCode=FindProc(FindData);
|
||||||
|
if (FindCode==SCAN_ERROR)
|
||||||
|
{
|
||||||
|
Errors++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (FindCode==SCAN_NEXT)
|
||||||
|
continue;
|
||||||
|
if (FindCode==SCAN_SUCCESS && FindData->IsDir && GetDirs==SCAN_SKIPDIRS)
|
||||||
|
continue;
|
||||||
|
if (FindCode==SCAN_DONE && PrepareMasks())
|
||||||
|
continue;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return(FindCode);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool ScanTree::PrepareMasks()
|
||||||
|
{
|
||||||
|
if (!FileMasks->GetString(CurMask,CurMaskW,sizeof(CurMask)))
|
||||||
|
return(false);
|
||||||
|
#ifdef _WIN_32
|
||||||
|
UnixSlashToDos(CurMask);
|
||||||
|
#endif
|
||||||
|
char *Name=PointToName(CurMask);
|
||||||
|
if (*Name==0)
|
||||||
|
strcat(CurMask,MASKALL);
|
||||||
|
if (Name[0]=='.' && (Name[1]==0 || Name[1]=='.' && Name[2]==0))
|
||||||
|
{
|
||||||
|
AddEndSlash(CurMask);
|
||||||
|
strcat(CurMask,MASKALL);
|
||||||
|
}
|
||||||
|
SpecPathLength=Name-CurMask;
|
||||||
|
// if (SpecPathLength>1)
|
||||||
|
// SpecPathLength--;
|
||||||
|
|
||||||
|
bool WideName=(*CurMaskW!=0);
|
||||||
|
|
||||||
|
if (WideName)
|
||||||
|
{
|
||||||
|
wchar *NameW=PointToName(CurMaskW);
|
||||||
|
if (*NameW==0)
|
||||||
|
strcatw(CurMaskW,MASKALLW);
|
||||||
|
if (NameW[0]=='.' && (NameW[1]==0 || NameW[1]=='.' && NameW[2]==0))
|
||||||
|
{
|
||||||
|
AddEndSlash(CurMaskW);
|
||||||
|
strcatw(CurMaskW,MASKALLW);
|
||||||
|
}
|
||||||
|
SpecPathLengthW=NameW-CurMaskW;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
wchar WideMask[NM];
|
||||||
|
CharToWide(CurMask,WideMask);
|
||||||
|
SpecPathLengthW=PointToName(WideMask)-WideMask;
|
||||||
|
}
|
||||||
|
Depth=0;
|
||||||
|
|
||||||
|
strcpy(OrigCurMask,CurMask);
|
||||||
|
strcpyw(OrigCurMaskW,CurMaskW);
|
||||||
|
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ScanTree::FindProc(FindData *FindData)
|
||||||
|
{
|
||||||
|
if (*CurMask==0)
|
||||||
|
return(SCAN_NEXT);
|
||||||
|
FastFindFile=false;
|
||||||
|
if (FindStack[Depth]==NULL)
|
||||||
|
{
|
||||||
|
bool Wildcards=IsWildcard(CurMask,CurMaskW);
|
||||||
|
bool FindCode=!Wildcards && FindFile::FastFind(CurMask,CurMaskW,FindData,GetLinks);
|
||||||
|
bool IsDir=FindCode && FindData->IsDir;
|
||||||
|
bool SearchAll=!IsDir && (Depth>0 || Recurse==RECURSE_ALWAYS ||
|
||||||
|
Wildcards && Recurse==RECURSE_WILDCARDS);
|
||||||
|
if (Depth==0)
|
||||||
|
SearchAllInRoot=SearchAll;
|
||||||
|
if (SearchAll || Wildcards)
|
||||||
|
{
|
||||||
|
FindStack[Depth]=new FindFile;
|
||||||
|
char SearchMask[NM];
|
||||||
|
strcpy(SearchMask,CurMask);
|
||||||
|
if (SearchAll)
|
||||||
|
strcpy(PointToName(SearchMask),MASKALL);
|
||||||
|
FindStack[Depth]->SetMask(SearchMask);
|
||||||
|
if (*CurMaskW)
|
||||||
|
{
|
||||||
|
wchar SearchMaskW[NM];
|
||||||
|
strcpyw(SearchMaskW,CurMaskW);
|
||||||
|
if (SearchAll)
|
||||||
|
strcpyw(PointToName(SearchMaskW),MASKALLW);
|
||||||
|
FindStack[Depth]->SetMaskW(SearchMaskW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FastFindFile=true;
|
||||||
|
if (!FindCode)
|
||||||
|
{
|
||||||
|
if (Cmd!=NULL && Cmd->ExclCheck(CurMask,true))
|
||||||
|
return(SCAN_NEXT);
|
||||||
|
ErrHandler.OpenErrorMsg(ErrArcName,CurMask);
|
||||||
|
return(FindData->Error ? SCAN_ERROR:SCAN_NEXT);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!FastFindFile && !FindStack[Depth]->Next(FindData,GetLinks))
|
||||||
|
{
|
||||||
|
bool Error=FindData->Error;
|
||||||
|
|
||||||
|
#ifdef _WIN_32
|
||||||
|
if (Error && strstr(CurMask,"System Volume Information\\")!=NULL)
|
||||||
|
Error=false;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (Cmd!=NULL && Cmd->ExclCheck(CurMask,true))
|
||||||
|
Error=false;
|
||||||
|
|
||||||
|
#ifndef SILENT
|
||||||
|
if (Error)
|
||||||
|
{
|
||||||
|
Log(NULL,St(MScanError),CurMask);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
char DirName[NM];
|
||||||
|
wchar DirNameW[NM];
|
||||||
|
*DirName=0;
|
||||||
|
*DirNameW=0;
|
||||||
|
|
||||||
|
delete FindStack[Depth];
|
||||||
|
FindStack[Depth--]=NULL;
|
||||||
|
while (Depth>=0 && FindStack[Depth]==NULL)
|
||||||
|
Depth--;
|
||||||
|
if (Depth < 0)
|
||||||
|
{
|
||||||
|
if (Error)
|
||||||
|
Errors++;
|
||||||
|
return(SCAN_DONE);
|
||||||
|
}
|
||||||
|
char *Slash=strrchrd(CurMask,CPATHDIVIDER);
|
||||||
|
if (Slash!=NULL)
|
||||||
|
{
|
||||||
|
char Mask[NM];
|
||||||
|
strcpy(Mask,Slash);
|
||||||
|
if (Depth<SetAllMaskDepth)
|
||||||
|
strcpy(Mask+1,PointToName(OrigCurMask));
|
||||||
|
*Slash=0;
|
||||||
|
strcpy(DirName,CurMask);
|
||||||
|
char *PrevSlash=strrchrd(CurMask,CPATHDIVIDER);
|
||||||
|
if (PrevSlash==NULL)
|
||||||
|
strcpy(CurMask,Mask+1);
|
||||||
|
else
|
||||||
|
strcpy(PrevSlash,Mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (*CurMaskW!=0)
|
||||||
|
{
|
||||||
|
wchar *Slash=strrchrw(CurMaskW,CPATHDIVIDER);
|
||||||
|
if (Slash!=NULL)
|
||||||
|
{
|
||||||
|
wchar Mask[NM];
|
||||||
|
strcpyw(Mask,Slash);
|
||||||
|
if (Depth<SetAllMaskDepth)
|
||||||
|
strcpyw(Mask+1,PointToName(OrigCurMaskW));
|
||||||
|
*Slash=0;
|
||||||
|
strcpyw(DirNameW,CurMaskW);
|
||||||
|
wchar *PrevSlash=strrchrw(CurMaskW,CPATHDIVIDER);
|
||||||
|
if (PrevSlash==NULL)
|
||||||
|
strcpyw(CurMaskW,Mask+1);
|
||||||
|
else
|
||||||
|
strcpyw(PrevSlash,Mask);
|
||||||
|
}
|
||||||
|
#ifndef _WIN_CE
|
||||||
|
if (LowAscii(CurMaskW))
|
||||||
|
*CurMaskW=0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (GetDirs==SCAN_GETDIRSTWICE &&
|
||||||
|
FindFile::FastFind(DirName,DirNameW,FindData,GetLinks) && FindData->IsDir)
|
||||||
|
return(Error ? SCAN_ERROR:SCAN_SUCCESS);
|
||||||
|
return(Error ? SCAN_ERROR:SCAN_NEXT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (FindData->IsDir)
|
||||||
|
{
|
||||||
|
if (!FastFindFile && Depth==0 && !SearchAllInRoot)
|
||||||
|
return(GetDirs==SCAN_GETCURDIRS ? SCAN_SUCCESS:SCAN_NEXT);
|
||||||
|
|
||||||
|
// if (GetDirs==SCAN_GETCURDIRS && Depth==0 && !SearchAllInRoot)
|
||||||
|
// return(SCAN_SUCCESS);
|
||||||
|
|
||||||
|
char Mask[NM];
|
||||||
|
bool MaskAll=FastFindFile;
|
||||||
|
|
||||||
|
// bool MaskAll=CmpName(CurMask,FindData->Name,MATCH_NAMES);
|
||||||
|
|
||||||
|
strcpy(Mask,MaskAll ? MASKALL:PointToName(CurMask));
|
||||||
|
strcpy(CurMask,FindData->Name);
|
||||||
|
|
||||||
|
if (strlen(CurMask)+strlen(Mask)+1>=NM || Depth>=MAXSCANDEPTH-1)
|
||||||
|
{
|
||||||
|
#ifndef SILENT
|
||||||
|
Log(NULL,"\n%s%c%s",CurMask,CPATHDIVIDER,Mask);
|
||||||
|
Log(NULL,St(MPathTooLong));
|
||||||
|
#endif
|
||||||
|
return(SCAN_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
|
AddEndSlash(CurMask);
|
||||||
|
strcat(CurMask,Mask);
|
||||||
|
|
||||||
|
if (*CurMaskW && *FindData->NameW==0)
|
||||||
|
CharToWide(FindData->Name,FindData->NameW);
|
||||||
|
if (*FindData->NameW!=0)
|
||||||
|
{
|
||||||
|
wchar Mask[NM];
|
||||||
|
if (FastFindFile)
|
||||||
|
strcpyw(Mask,MASKALLW);
|
||||||
|
else
|
||||||
|
if (*CurMaskW)
|
||||||
|
strcpyw(Mask,PointToName(CurMaskW));
|
||||||
|
else
|
||||||
|
CharToWide(PointToName(CurMask),Mask);
|
||||||
|
strcpyw(CurMaskW,FindData->NameW);
|
||||||
|
AddEndSlash(CurMaskW);
|
||||||
|
strcatw(CurMaskW,Mask);
|
||||||
|
}
|
||||||
|
Depth++;
|
||||||
|
if (MaskAll)
|
||||||
|
SetAllMaskDepth=Depth;
|
||||||
|
}
|
||||||
|
if (!FastFindFile && !CmpName(CurMask,FindData->Name,MATCH_NAMES))
|
||||||
|
return(SCAN_NEXT);
|
||||||
|
return(SCAN_SUCCESS);
|
||||||
|
}
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
#ifndef _RAR_SCANTREE_
|
||||||
|
#define _RAR_SCANTREE_
|
||||||
|
|
||||||
|
enum { RECURSE_NONE=0,RECURSE_ALWAYS,RECURSE_WILDCARDS };
|
||||||
|
enum { SCAN_SKIPDIRS=0,SCAN_GETDIRS,SCAN_GETDIRSTWICE,SCAN_GETCURDIRS };
|
||||||
|
enum { SCAN_SUCCESS,SCAN_DONE,SCAN_ERROR,SCAN_NEXT };
|
||||||
|
|
||||||
|
#define MAXSCANDEPTH (NM/2)
|
||||||
|
|
||||||
|
class CommandData;
|
||||||
|
|
||||||
|
class ScanTree
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
bool PrepareMasks();
|
||||||
|
int FindProc(FindData *FindData);
|
||||||
|
|
||||||
|
FindFile *FindStack[MAXSCANDEPTH];
|
||||||
|
int Depth;
|
||||||
|
|
||||||
|
int SetAllMaskDepth;
|
||||||
|
|
||||||
|
StringList *FileMasks;
|
||||||
|
int Recurse;
|
||||||
|
bool GetLinks;
|
||||||
|
int GetDirs;
|
||||||
|
int Errors;
|
||||||
|
|
||||||
|
char CurMask[NM];
|
||||||
|
wchar CurMaskW[NM];
|
||||||
|
char OrigCurMask[NM];
|
||||||
|
wchar OrigCurMaskW[NM];
|
||||||
|
bool SearchAllInRoot;
|
||||||
|
bool FastFindFile;
|
||||||
|
int SpecPathLength;
|
||||||
|
int SpecPathLengthW;
|
||||||
|
|
||||||
|
char ErrArcName[NM];
|
||||||
|
|
||||||
|
CommandData *Cmd;
|
||||||
|
public:
|
||||||
|
ScanTree(StringList *FileMasks,int Recurse,bool GetLinks,int GetDirs);
|
||||||
|
~ScanTree();
|
||||||
|
int GetNext(FindData *FindData);
|
||||||
|
int GetSpecPathLength() {return(SpecPathLength);};
|
||||||
|
int GetSpecPathLengthW() {return(SpecPathLengthW);};
|
||||||
|
int GetErrors() {return(Errors);};
|
||||||
|
void SetErrArcName(const char *Name) {strcpy(ErrArcName,Name);}
|
||||||
|
void SetCommandData(CommandData *Cmd) {ScanTree::Cmd=Cmd;}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,231 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
/*
|
||||||
|
SHA-1 in C
|
||||||
|
By Steve Reid <steve@edmweb.com>
|
||||||
|
100% Public Domain
|
||||||
|
|
||||||
|
Test Vectors (from FIPS PUB 180-1)
|
||||||
|
"abc"
|
||||||
|
A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
|
||||||
|
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
|
||||||
|
84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
|
||||||
|
A million repetitions of "a"
|
||||||
|
34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if !defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
|
||||||
|
#if defined(_M_IX86) || defined(_M_I86) || defined(__alpha)
|
||||||
|
#define LITTLE_ENDIAN
|
||||||
|
#else
|
||||||
|
#error "LITTLE_ENDIAN or BIG_ENDIAN must be defined"
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* #define SHA1HANDSOFF * Copies data before messing with it. */
|
||||||
|
|
||||||
|
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
|
||||||
|
|
||||||
|
/* blk0() and blk() perform the initial expand. */
|
||||||
|
/* I got the idea of expanding during the round function from SSLeay */
|
||||||
|
#ifdef LITTLE_ENDIAN
|
||||||
|
#define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
|
||||||
|
|(rol(block->l[i],8)&0x00FF00FF))
|
||||||
|
#else
|
||||||
|
#define blk0(i) block->l[i]
|
||||||
|
#endif
|
||||||
|
#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
|
||||||
|
^block->l[(i+2)&15]^block->l[i&15],1))
|
||||||
|
|
||||||
|
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
|
||||||
|
#define R0(v,w,x,y,z,i) {z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);}
|
||||||
|
#define R1(v,w,x,y,z,i) {z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);}
|
||||||
|
#define R2(v,w,x,y,z,i) {z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);}
|
||||||
|
#define R3(v,w,x,y,z,i) {z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);}
|
||||||
|
#define R4(v,w,x,y,z,i) {z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);}
|
||||||
|
|
||||||
|
|
||||||
|
/* Hash a single 512-bit block. This is the core of the algorithm. */
|
||||||
|
|
||||||
|
void SHA1Transform(uint32 state[5], unsigned char buffer[64], bool handsoff)
|
||||||
|
{
|
||||||
|
uint32 a, b, c, d, e;
|
||||||
|
typedef union {
|
||||||
|
unsigned char c[64];
|
||||||
|
uint32 l[16];
|
||||||
|
} CHAR64LONG16;
|
||||||
|
CHAR64LONG16* block;
|
||||||
|
static unsigned char workspace[64];
|
||||||
|
if (handsoff)
|
||||||
|
{
|
||||||
|
block = (CHAR64LONG16*)workspace;
|
||||||
|
memcpy(block, buffer, 64);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
block = (CHAR64LONG16*)buffer;
|
||||||
|
#ifdef SFX_MODULE
|
||||||
|
static int pos[80][5];
|
||||||
|
static bool pinit=false;
|
||||||
|
if (!pinit)
|
||||||
|
{
|
||||||
|
for (int I=0,P=0;I<80;I++,P=(P ? P-1:4))
|
||||||
|
{
|
||||||
|
pos[I][0]=P;
|
||||||
|
pos[I][1]=(P+1)%5;
|
||||||
|
pos[I][2]=(P+2)%5;
|
||||||
|
pos[I][3]=(P+3)%5;
|
||||||
|
pos[I][4]=(P+4)%5;
|
||||||
|
}
|
||||||
|
pinit=true;
|
||||||
|
}
|
||||||
|
uint32 s[5];
|
||||||
|
for (int I=0;I<sizeof(s)/sizeof(s[0]);I++)
|
||||||
|
s[I]=state[I];
|
||||||
|
|
||||||
|
for (int I=0;I<16;I++)
|
||||||
|
R0(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
|
||||||
|
for (int I=16;I<20;I++)
|
||||||
|
R1(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
|
||||||
|
for (int I=20;I<40;I++)
|
||||||
|
R2(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
|
||||||
|
for (int I=40;I<60;I++)
|
||||||
|
R3(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
|
||||||
|
for (int I=60;I<80;I++)
|
||||||
|
R4(s[pos[I][0]],s[pos[I][1]],s[pos[I][2]],s[pos[I][3]],s[pos[I][4]],I);
|
||||||
|
|
||||||
|
for (int I=0;I<sizeof(s)/sizeof(s[0]);I++)
|
||||||
|
state[I]+=s[I];
|
||||||
|
#else
|
||||||
|
/* Copy context->state[] to working vars */
|
||||||
|
a = state[0];
|
||||||
|
b = state[1];
|
||||||
|
c = state[2];
|
||||||
|
d = state[3];
|
||||||
|
e = state[4];
|
||||||
|
/* 4 rounds of 20 operations each. Loop unrolled. */
|
||||||
|
R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
|
||||||
|
R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
|
||||||
|
R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
|
||||||
|
R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
|
||||||
|
R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
|
||||||
|
R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
|
||||||
|
R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
|
||||||
|
R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
|
||||||
|
R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
|
||||||
|
R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
|
||||||
|
R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
|
||||||
|
R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
|
||||||
|
R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
|
||||||
|
R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
|
||||||
|
R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
|
||||||
|
R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
|
||||||
|
R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
|
||||||
|
R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
|
||||||
|
R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
|
||||||
|
R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
|
||||||
|
/* Add the working vars back into context.state[] */
|
||||||
|
state[0] += a;
|
||||||
|
state[1] += b;
|
||||||
|
state[2] += c;
|
||||||
|
state[3] += d;
|
||||||
|
state[4] += e;
|
||||||
|
|
||||||
|
/* Wipe variables */
|
||||||
|
a = b = c = d = e = 0;
|
||||||
|
memset(&a,0,sizeof(a));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Initialize new context */
|
||||||
|
|
||||||
|
void hash_initial(hash_context* context)
|
||||||
|
{
|
||||||
|
/* SHA1 initialization constants */
|
||||||
|
context->state[0] = 0x67452301;
|
||||||
|
context->state[1] = 0xEFCDAB89;
|
||||||
|
context->state[2] = 0x98BADCFE;
|
||||||
|
context->state[3] = 0x10325476;
|
||||||
|
context->state[4] = 0xC3D2E1F0;
|
||||||
|
context->count[0] = context->count[1] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Run your data through this. */
|
||||||
|
void hash_process( hash_context * context, unsigned char * data, unsigned len,
|
||||||
|
bool handsoff )
|
||||||
|
{
|
||||||
|
unsigned int i, j;
|
||||||
|
uint blen = ((uint)len)<<3;
|
||||||
|
|
||||||
|
j = (context->count[0] >> 3) & 63;
|
||||||
|
if ((context->count[0] += blen) < blen ) context->count[1]++;
|
||||||
|
context->count[1] += (len >> 29);
|
||||||
|
if ((j + len) > 63) {
|
||||||
|
memcpy(&context->buffer[j], data, (i = 64-j));
|
||||||
|
SHA1Transform(context->state, context->buffer, handsoff);
|
||||||
|
for ( ; i + 63 < len; i += 64) {
|
||||||
|
#ifdef ALLOW_NOT_ALIGNED_INT
|
||||||
|
SHA1Transform(context->state, &data[i], handsoff);
|
||||||
|
#else
|
||||||
|
unsigned char buffer[64];
|
||||||
|
memcpy(buffer,data+i,sizeof(buffer));
|
||||||
|
SHA1Transform(context->state, buffer, handsoff);
|
||||||
|
memcpy(data+i,buffer,sizeof(buffer));
|
||||||
|
#endif
|
||||||
|
#ifdef BIG_ENDIAN
|
||||||
|
if (!handsoff)
|
||||||
|
{
|
||||||
|
unsigned char *d=data+i;
|
||||||
|
for (int k=0;k<64;k+=4)
|
||||||
|
{
|
||||||
|
byte b0=d[k],b1=d[k+1];
|
||||||
|
d[k]=d[k+3];
|
||||||
|
d[k+1]=d[k+2];
|
||||||
|
d[k+2]=b1;
|
||||||
|
d[k+3]=b0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
j = 0;
|
||||||
|
}
|
||||||
|
else i = 0;
|
||||||
|
if (len > i)
|
||||||
|
memcpy(&context->buffer[j], &data[i], len - i);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Add padding and return the message digest. */
|
||||||
|
|
||||||
|
void hash_final( hash_context* context, uint32 digest[5], bool handsoff)
|
||||||
|
{
|
||||||
|
uint i, j;
|
||||||
|
unsigned char finalcount[8];
|
||||||
|
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
|
||||||
|
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
|
||||||
|
}
|
||||||
|
unsigned char ch=(unsigned char)'\200';
|
||||||
|
hash_process(context, &ch, 1, handsoff);
|
||||||
|
while ((context->count[0] & 504) != 448) {
|
||||||
|
ch=0;
|
||||||
|
hash_process(context, &ch, 1, handsoff);
|
||||||
|
}
|
||||||
|
hash_process(context, finalcount, 8, handsoff); /* Should cause a SHA1Transform() */
|
||||||
|
for (i = 0; i < 5; i++) {
|
||||||
|
digest[i] = context->state[i] & 0xffffffff;
|
||||||
|
}
|
||||||
|
/* Wipe variables */
|
||||||
|
memset(&i,0,sizeof(i));
|
||||||
|
memset(&j,0,sizeof(j));
|
||||||
|
memset(context->buffer, 0, 64);
|
||||||
|
memset(context->state, 0, 20);
|
||||||
|
memset(context->count, 0, 8);
|
||||||
|
memset(&finalcount, 0, 8);
|
||||||
|
if (handsoff)
|
||||||
|
SHA1Transform(context->state, context->buffer, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#ifndef _RAR_SHA1_
|
||||||
|
#define _RAR_SHA1_
|
||||||
|
|
||||||
|
#define HW 5
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint32 state[5];
|
||||||
|
uint32 count[2];
|
||||||
|
unsigned char buffer[64];
|
||||||
|
} hash_context;
|
||||||
|
|
||||||
|
void hash_initial( hash_context * c );
|
||||||
|
void hash_process( hash_context * c, unsigned char * data, unsigned len,
|
||||||
|
bool handsoff);
|
||||||
|
void hash_final( hash_context * c, uint32[HW], bool handsoff);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
int ToPercent(Int64 N1,Int64 N2)
|
||||||
|
{
|
||||||
|
if (N2==0)
|
||||||
|
return(0);
|
||||||
|
if (N2<N1)
|
||||||
|
return(100);
|
||||||
|
return(int64to32(N1*100/N2));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void RARInitData()
|
||||||
|
{
|
||||||
|
InitCRC();
|
||||||
|
ErrHandler.Clean();
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
#ifndef _RAR_SMALLFN_
|
||||||
|
#define _RAR_SMALLFN_
|
||||||
|
|
||||||
|
int ToPercent(Int64 N1,Int64 N2);
|
||||||
|
void RARInitData();
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,165 @@
|
|||||||
|
#include "rar.hpp"
|
||||||
|
|
||||||
|
const char *NullToEmpty(const char *Str)
|
||||||
|
{
|
||||||
|
return(Str==NULL ? "":Str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const wchar *NullToEmpty(const wchar *Str)
|
||||||
|
{
|
||||||
|
return(Str==NULL ? L"":Str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char *IntNameToExt(const char *Name)
|
||||||
|
{
|
||||||
|
static char OutName[NM];
|
||||||
|
IntToExt(Name,OutName);
|
||||||
|
return(OutName);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ExtToInt(const char *Src,char *Dest)
|
||||||
|
{
|
||||||
|
#if defined(_WIN_32)
|
||||||
|
CharToOem(Src,Dest);
|
||||||
|
#else
|
||||||
|
if (Dest!=Src)
|
||||||
|
strcpy(Dest,Src);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void IntToExt(const char *Src,char *Dest)
|
||||||
|
{
|
||||||
|
#if defined(_WIN_32)
|
||||||
|
OemToChar(Src,Dest);
|
||||||
|
#else
|
||||||
|
if (Dest!=Src)
|
||||||
|
strcpy(Dest,Src);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* strlower(char *Str)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
CharLower((LPTSTR)Str);
|
||||||
|
#else
|
||||||
|
for (char *ChPtr=Str;*ChPtr;ChPtr++)
|
||||||
|
*ChPtr=(char)loctolower(*ChPtr);
|
||||||
|
#endif
|
||||||
|
return(Str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* strupper(char *Str)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
CharUpper((LPTSTR)Str);
|
||||||
|
#else
|
||||||
|
for (char *ChPtr=Str;*ChPtr;ChPtr++)
|
||||||
|
*ChPtr=(char)loctoupper(*ChPtr);
|
||||||
|
#endif
|
||||||
|
return(Str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int stricomp(const char *Str1,const char *Str2)
|
||||||
|
{
|
||||||
|
char S1[NM*2],S2[NM*2];
|
||||||
|
strncpy(S1,Str1,sizeof(S1));
|
||||||
|
strncpy(S2,Str2,sizeof(S2));
|
||||||
|
return(strcmp(strupper(S1),strupper(S2)));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int strnicomp(const char *Str1,const char *Str2,int N)
|
||||||
|
{
|
||||||
|
char S1[512],S2[512];
|
||||||
|
strncpy(S1,Str1,sizeof(S1));
|
||||||
|
strncpy(S2,Str2,sizeof(S2));
|
||||||
|
return(strncmp(strupper(S1),strupper(S2),N));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* RemoveEOL(char *Str)
|
||||||
|
{
|
||||||
|
for (int I=strlen(Str)-1;I>=0 && (Str[I]=='\r' || Str[I]=='\n' || Str[I]==' ' || Str[I]=='\t');I--)
|
||||||
|
Str[I]=0;
|
||||||
|
return(Str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
char* RemoveLF(char *Str)
|
||||||
|
{
|
||||||
|
for (int I=strlen(Str)-1;I>=0 && (Str[I]=='\r' || Str[I]=='\n');I--)
|
||||||
|
Str[I]=0;
|
||||||
|
return(Str);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int loctolower(byte ch)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
return((int)CharLower((LPTSTR)ch));
|
||||||
|
#else
|
||||||
|
return(tolower(ch));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
unsigned int loctoupper(byte ch)
|
||||||
|
{
|
||||||
|
#ifdef _WIN_32
|
||||||
|
return((int)CharUpper((LPTSTR)ch));
|
||||||
|
#else
|
||||||
|
return(toupper(ch));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool LowAscii(const char *Str)
|
||||||
|
{
|
||||||
|
for (int I=0;Str[I]!=0;I++)
|
||||||
|
if ((byte)Str[I]<32 || (byte)Str[I]>127)
|
||||||
|
return(false);
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LowAscii(const wchar *Str)
|
||||||
|
{
|
||||||
|
for (int I=0;Str[I]!=0;I++)
|
||||||
|
if (Str[I]<32 || Str[I]>127)
|
||||||
|
return(false);
|
||||||
|
return(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int stricompc(const char *Str1,const char *Str2)
|
||||||
|
{
|
||||||
|
#if defined(_UNIX)
|
||||||
|
return(strcmp(Str1,Str2));
|
||||||
|
#else
|
||||||
|
return(stricomp(Str1,Str2));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef SFX_MODULE
|
||||||
|
int stricompcw(const wchar *Str1,const wchar *Str2)
|
||||||
|
{
|
||||||
|
#if defined(_UNIX)
|
||||||
|
return(strcmpw(Str1,Str2));
|
||||||
|
#else
|
||||||
|
return(stricmpw(Str1,Str2));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
#endif
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user