Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
325
Src/external_dependencies/openmpt-trunk/include/unrar/rdwrfn.cpp
vendored
Normal file
325
Src/external_dependencies/openmpt-trunk/include/unrar/rdwrfn.cpp
vendored
Normal file
|
@ -0,0 +1,325 @@
|
|||
#include "rar.hpp"
|
||||
|
||||
ComprDataIO::ComprDataIO()
|
||||
{
|
||||
#ifndef RAR_NOCRYPT
|
||||
Crypt=new CryptData;
|
||||
Decrypt=new CryptData;
|
||||
#endif
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
|
||||
void ComprDataIO::Init()
|
||||
{
|
||||
UnpackFromMemory=false;
|
||||
UnpackToMemory=false;
|
||||
UnpPackedSize=0;
|
||||
UnpPackedLeft=0;
|
||||
ShowProgress=true;
|
||||
TestMode=false;
|
||||
SkipUnpCRC=false;
|
||||
NoFileHeader=false;
|
||||
PackVolume=false;
|
||||
UnpVolume=false;
|
||||
NextVolumeMissing=false;
|
||||
SrcFile=NULL;
|
||||
DestFile=NULL;
|
||||
UnpWrAddr=NULL;
|
||||
UnpWrSize=0;
|
||||
Command=NULL;
|
||||
Encryption=false;
|
||||
Decryption=false;
|
||||
CurPackRead=CurPackWrite=CurUnpRead=CurUnpWrite=0;
|
||||
LastPercent=-1;
|
||||
SubHead=NULL;
|
||||
SubHeadPos=NULL;
|
||||
CurrentCommand=0;
|
||||
ProcessedArcSize=0;
|
||||
LastArcSize=0;
|
||||
TotalArcSize=0;
|
||||
}
|
||||
|
||||
|
||||
ComprDataIO::~ComprDataIO()
|
||||
{
|
||||
#ifndef RAR_NOCRYPT
|
||||
delete Crypt;
|
||||
delete Decrypt;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
int ComprDataIO::UnpRead(byte *Addr,size_t Count)
|
||||
{
|
||||
#ifndef RAR_NOCRYPT
|
||||
// In case of encryption we need to align read size to encryption
|
||||
// block size. We can do it by simple masking, because unpack read code
|
||||
// always reads more than CRYPT_BLOCK_SIZE, so we do not risk to make it 0.
|
||||
if (Decryption)
|
||||
Count &= ~CRYPT_BLOCK_MASK;
|
||||
#endif
|
||||
|
||||
int ReadSize=0,TotalRead=0;
|
||||
byte *ReadAddr;
|
||||
ReadAddr=Addr;
|
||||
while (Count > 0)
|
||||
{
|
||||
Archive *SrcArc=(Archive *)SrcFile;
|
||||
|
||||
if (UnpackFromMemory)
|
||||
{
|
||||
memcpy(Addr,UnpackFromMemoryAddr,UnpackFromMemorySize);
|
||||
ReadSize=(int)UnpackFromMemorySize;
|
||||
UnpackFromMemorySize=0;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t SizeToRead=((int64)Count>UnpPackedLeft) ? (size_t)UnpPackedLeft:Count;
|
||||
if (SizeToRead > 0)
|
||||
{
|
||||
if (UnpVolume && Decryption && (int64)Count>UnpPackedLeft)
|
||||
{
|
||||
// We need aligned blocks for decryption and we want "Keep broken
|
||||
// files" to work efficiently with missing encrypted volumes.
|
||||
// So for last data block in volume we adjust the size to read to
|
||||
// next equal or smaller block producing aligned total block size.
|
||||
// So we'll ask for next volume only when processing few unaligned
|
||||
// bytes left in the end, when most of data is already extracted.
|
||||
size_t NewTotalRead = TotalRead + SizeToRead;
|
||||
size_t Adjust = NewTotalRead - (NewTotalRead & ~CRYPT_BLOCK_MASK);
|
||||
size_t NewSizeToRead = SizeToRead - Adjust;
|
||||
if ((int)NewSizeToRead > 0)
|
||||
SizeToRead = NewSizeToRead;
|
||||
}
|
||||
|
||||
if (!SrcFile->IsOpened())
|
||||
return -1;
|
||||
ReadSize=SrcFile->Read(ReadAddr,SizeToRead);
|
||||
FileHeader *hd=SubHead!=NULL ? SubHead:&SrcArc->FileHead;
|
||||
if (!NoFileHeader && hd->SplitAfter)
|
||||
PackedDataHash.Update(ReadAddr,ReadSize);
|
||||
}
|
||||
}
|
||||
CurUnpRead+=ReadSize;
|
||||
TotalRead+=ReadSize;
|
||||
#ifndef NOVOLUME
|
||||
// These variable are not used in NOVOLUME mode, so it is better
|
||||
// to exclude commands below to avoid compiler warnings.
|
||||
ReadAddr+=ReadSize;
|
||||
Count-=ReadSize;
|
||||
#endif
|
||||
UnpPackedLeft-=ReadSize;
|
||||
|
||||
// Do not ask for next volume if we read something from current volume.
|
||||
// If next volume is missing, we need to process all data from current
|
||||
// volume before aborting. It helps to recover all possible data
|
||||
// in "Keep broken files" mode. But if we process encrypted data,
|
||||
// we ask for next volume also if we have non-aligned encryption block.
|
||||
// Since we adjust data size for decryption earlier above,
|
||||
// it does not hurt "Keep broken files" mode efficiency.
|
||||
if (UnpVolume && UnpPackedLeft == 0 &&
|
||||
(ReadSize==0 || Decryption && (TotalRead & CRYPT_BLOCK_MASK) != 0) )
|
||||
{
|
||||
#ifndef NOVOLUME
|
||||
if (!MergeArchive(*SrcArc,this,true,CurrentCommand))
|
||||
#endif
|
||||
{
|
||||
NextVolumeMissing=true;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
Archive *SrcArc=(Archive *)SrcFile;
|
||||
if (SrcArc!=NULL)
|
||||
ShowUnpRead(SrcArc->NextBlockPos-UnpPackedSize+CurUnpRead,TotalArcSize);
|
||||
if (ReadSize!=-1)
|
||||
{
|
||||
ReadSize=TotalRead;
|
||||
#ifndef RAR_NOCRYPT
|
||||
if (Decryption)
|
||||
Decrypt->DecryptBlock(Addr,ReadSize);
|
||||
#endif
|
||||
}
|
||||
Wait();
|
||||
return ReadSize;
|
||||
}
|
||||
|
||||
|
||||
void ComprDataIO::UnpWrite(byte *Addr,size_t Count)
|
||||
{
|
||||
|
||||
#ifdef RARDLL
|
||||
RAROptions *Cmd=((Archive *)SrcFile)->GetRAROptions();
|
||||
if (Cmd->DllOpMode!=RAR_SKIP)
|
||||
{
|
||||
if (Cmd->Callback!=NULL &&
|
||||
Cmd->Callback(UCM_PROCESSDATA,Cmd->UserData,(LPARAM)Addr,Count)==-1)
|
||||
ErrHandler.Exit(RARX_USERBREAK);
|
||||
/* // OPENMPT ADDITION
|
||||
if (Cmd->ProcessDataProc!=NULL)
|
||||
{
|
||||
int RetCode=Cmd->ProcessDataProc(Addr,(int)Count);
|
||||
if (RetCode==0)
|
||||
ErrHandler.Exit(RARX_USERBREAK);
|
||||
}
|
||||
*/ // OPENMPT ADDITION
|
||||
}
|
||||
#endif // RARDLL
|
||||
|
||||
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)
|
||||
UnpHash.Update(Addr,Count);
|
||||
ShowUnpWrite();
|
||||
Wait();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void ComprDataIO::ShowUnpRead(int64 ArcPos,int64 ArcSize)
|
||||
{
|
||||
return; // OPENMPT ADDITION
|
||||
if (ShowProgress && SrcFile!=NULL)
|
||||
{
|
||||
// Important when processing several archives or multivolume archive.
|
||||
ArcPos+=ProcessedArcSize;
|
||||
|
||||
Archive *SrcArc=(Archive *)SrcFile;
|
||||
RAROptions *Cmd=SrcArc->GetRAROptions();
|
||||
|
||||
int CurPercent=ToPercent(ArcPos,ArcSize);
|
||||
if (!Cmd->DisablePercentage && CurPercent!=LastPercent)
|
||||
{
|
||||
uiExtractProgress(CurUnpWrite,SrcArc->FileHead.UnpSize,ArcPos,ArcSize);
|
||||
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,size_t *Size)
|
||||
{
|
||||
*Data=UnpWrAddr;
|
||||
*Size=UnpWrSize;
|
||||
}
|
||||
|
||||
|
||||
void ComprDataIO::SetEncryption(bool Encrypt,CRYPT_METHOD Method,
|
||||
SecPassword *Password,const byte *Salt,const byte *InitV,
|
||||
uint Lg2Cnt,byte *HashKey,byte *PswCheck)
|
||||
{
|
||||
#ifndef RAR_NOCRYPT
|
||||
if (Encrypt)
|
||||
Encryption=Crypt->SetCryptKeys(true,Method,Password,Salt,InitV,Lg2Cnt,HashKey,PswCheck);
|
||||
else
|
||||
Decryption=Decrypt->SetCryptKeys(false,Method,Password,Salt,InitV,Lg2Cnt,HashKey,PswCheck);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
#if !defined(SFX_MODULE) && !defined(RAR_NOCRYPT)
|
||||
void ComprDataIO::SetAV15Encryption()
|
||||
{
|
||||
Decryption=true;
|
||||
Decrypt->SetAV15Encryption();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(SFX_MODULE) && !defined(RAR_NOCRYPT)
|
||||
void ComprDataIO::SetCmt13Encryption()
|
||||
{
|
||||
Decryption=true;
|
||||
Decrypt->SetCmt13Encryption();
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
void ComprDataIO::SetUnpackToMemory(byte *Addr,uint Size)
|
||||
{
|
||||
UnpackToMemory=true;
|
||||
UnpackToMemoryAddr=Addr;
|
||||
UnpackToMemorySize=Size;
|
||||
}
|
||||
|
||||
|
||||
// Extraction progress is based on the position in archive and we adjust
|
||||
// the total archives size here, so trailing blocks do not prevent progress
|
||||
// reaching 100% at the end of extraction. Alternatively we could print "100%"
|
||||
// after completing the entire archive extraction, but then we would need
|
||||
// to take into account possible messages like the checksum error after
|
||||
// last file percent progress.
|
||||
void ComprDataIO::AdjustTotalArcSize(Archive *Arc)
|
||||
{
|
||||
// If we know a position of QO or RR blocks, use them to adjust the total
|
||||
// packed size to beginning of these blocks. Earlier we already calculated
|
||||
// the total size based on entire archive sizes. We also set LastArcSize
|
||||
// to start of first trailing block, to add it later to ProcessedArcSize.
|
||||
int64 ArcLength=Arc->IsSeekable() ? Arc->FileLength() : 0;
|
||||
if (Arc->MainHead.QOpenOffset!=0) // QO is always preceding RR record.
|
||||
LastArcSize=Arc->MainHead.QOpenOffset;
|
||||
else
|
||||
if (Arc->MainHead.RROffset!=0)
|
||||
LastArcSize=Arc->MainHead.RROffset;
|
||||
else
|
||||
{
|
||||
// If neither QO nor RR are found, exclude the approximate size of
|
||||
// end of archive block.
|
||||
// We select EndBlock to be larger than typical 8 bytes HEAD_ENDARC,
|
||||
// but to not exceed the smallest 22 bytes HEAD_FILE with 1 byte file
|
||||
// name, so we do not have two files with 100% at the end of archive.
|
||||
const uint EndBlock=23;
|
||||
|
||||
if (ArcLength>EndBlock)
|
||||
LastArcSize=ArcLength-EndBlock;
|
||||
}
|
||||
|
||||
TotalArcSize-=ArcLength-LastArcSize;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue