2013-10-04 15:13:30 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include "rar.hpp"
|
|
|
|
|
|
|
|
#include "unrar.h"
|
|
|
|
|
|
|
|
#define DataIO Arc
|
|
|
|
|
|
|
|
unrar_err_t CmdExtract::ExtractCurrentFile( bool SkipSolid, bool check_compatibility_only )
|
|
|
|
{
|
|
|
|
check( Arc.GetHeaderType() == FILE_HEAD );
|
|
|
|
|
2014-09-20 13:52:10 +00:00
|
|
|
if ( Arc.FileHead.SplitBefore || Arc.FileHead.SplitAfter )
|
2013-10-04 15:13:30 +00:00
|
|
|
return unrar_err_segmented;
|
|
|
|
|
2014-09-20 13:52:10 +00:00
|
|
|
if ( Arc.FileHead.Encrypted )
|
2013-10-04 15:13:30 +00:00
|
|
|
return unrar_err_encrypted;
|
|
|
|
|
|
|
|
if ( !check_compatibility_only )
|
|
|
|
{
|
2014-09-20 13:52:10 +00:00
|
|
|
check( Arc.NextBlockPos-Arc.FileHead.PackSize == Arc.Tell() );
|
|
|
|
Arc.Seek(Arc.NextBlockPos-Arc.FileHead.PackSize,SEEK_SET);
|
2013-10-04 15:13:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// (removed lots of command-line handling)
|
|
|
|
|
|
|
|
#ifdef SFX_MODULE
|
2014-09-20 13:52:10 +00:00
|
|
|
if ((Arc.FileHead.UnpVer!=UNP_VER && Arc.FileHead.UnpVer!=29) &&
|
|
|
|
Arc.FileHead.Method!=0x30)
|
2013-10-04 15:13:30 +00:00
|
|
|
#else
|
2014-09-20 13:52:10 +00:00
|
|
|
if (Arc.FileHead.UnpVer!=VER_UNPACK5 &&
|
|
|
|
(Arc.FileHead.UnpVer<13 || Arc.FileHead.UnpVer>VER_UNPACK))
|
2013-10-04 15:13:30 +00:00
|
|
|
#endif
|
|
|
|
{
|
2014-09-20 13:52:10 +00:00
|
|
|
if (Arc.FileHead.UnpVer>VER_UNPACK)
|
2013-10-04 15:13:30 +00:00
|
|
|
return unrar_err_new_algo;
|
|
|
|
return unrar_err_old_algo;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( check_compatibility_only )
|
|
|
|
return unrar_ok;
|
|
|
|
|
|
|
|
// (removed lots of command-line/encryption/volume handling)
|
|
|
|
|
|
|
|
update_first_file_pos();
|
|
|
|
FileCount++;
|
|
|
|
DataIO.UnpFileCRC=Arc.OldFormat ? 0 : 0xffffffff;
|
|
|
|
// (removed decryption)
|
2014-09-20 13:52:10 +00:00
|
|
|
DataIO.UnpHash.Init(Arc.FileHead.FileHash.Type,1);
|
|
|
|
DataIO.PackedDataHash.Init(Arc.FileHead.FileHash.Type,1);
|
|
|
|
DataIO.SetPackedSizeToRead(Arc.FileHead.PackSize);
|
|
|
|
DataIO.SetSkipUnpCRC(SkipSolid);
|
2013-10-04 15:13:30 +00:00
|
|
|
// (removed command-line handling)
|
|
|
|
DataIO.SetSkipUnpCRC(SkipSolid);
|
|
|
|
|
2014-09-20 13:52:10 +00:00
|
|
|
if (Arc.FileHead.Method==0)
|
|
|
|
UnstoreFile(Arc.FileHead.UnpSize);
|
2013-10-04 15:13:30 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
// Defer creation of Unpack until first extraction
|
|
|
|
if ( !Unp )
|
|
|
|
{
|
|
|
|
Unp = new Unpack( &Arc );
|
|
|
|
if ( !Unp )
|
|
|
|
return unrar_err_memory;
|
|
|
|
}
|
|
|
|
|
2014-10-03 07:36:52 +00:00
|
|
|
Unp->Init(Arc.FileHead.WinSize,Arc.FileHead.Solid);
|
2014-09-20 13:52:10 +00:00
|
|
|
Unp->SetDestSize(Arc.FileHead.UnpSize);
|
2013-10-04 15:13:30 +00:00
|
|
|
#ifndef SFX_MODULE
|
2014-10-03 07:36:52 +00:00
|
|
|
if (Arc.Format!=RARFMT50 && Arc.FileHead.UnpVer<=15)
|
2013-10-04 15:13:30 +00:00
|
|
|
Unp->DoUnpack(15,FileCount>1 && Arc.Solid);
|
|
|
|
else
|
|
|
|
#endif
|
2014-10-03 07:36:52 +00:00
|
|
|
Unp->DoUnpack(Arc.FileHead.UnpVer,Arc.FileHead.Solid);
|
2013-10-04 15:13:30 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// (no need to seek to next file)
|
|
|
|
|
|
|
|
if (!SkipSolid)
|
|
|
|
{
|
2014-09-20 13:52:10 +00:00
|
|
|
HashValue UnpHash;
|
|
|
|
DataIO.UnpHash.Result(&UnpHash);
|
|
|
|
if (UnpHash==Arc.FileHead.FileHash)
|
|
|
|
{
|
2013-10-04 15:13:30 +00:00
|
|
|
// CRC is correct
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return unrar_err_corrupt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// (removed broken file handling)
|
|
|
|
// (removed command-line handling)
|
|
|
|
|
|
|
|
return unrar_ok;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-09-20 13:52:10 +00:00
|
|
|
void CmdExtract::UnstoreFile(int64 DestUnpSize)
|
2013-10-04 15:13:30 +00:00
|
|
|
{
|
2014-09-21 05:21:08 +00:00
|
|
|
Buffer.Alloc((int)Min(DestUnpSize,0x10000));
|
2013-10-04 15:13:30 +00:00
|
|
|
while (1)
|
|
|
|
{
|
2014-09-20 13:52:10 +00:00
|
|
|
unsigned int Code=DataIO.UnpRead(&Buffer[0],(uint)Buffer.Size());
|
2013-10-04 15:13:30 +00:00
|
|
|
if (Code==0 || (int)Code==-1)
|
|
|
|
break;
|
|
|
|
Code=Code<DestUnpSize ? Code:int64to32(DestUnpSize);
|
|
|
|
DataIO.UnpWrite(&Buffer[0],Code);
|
|
|
|
if (DestUnpSize>=0)
|
|
|
|
DestUnpSize-=Code;
|
|
|
|
}
|
|
|
|
Buffer.Reset();
|
|
|
|
}
|