mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-10 00:07:06 -06:00
23.01
This commit is contained in:
@@ -16,10 +16,11 @@
|
||||
namespace NArchive {
|
||||
namespace N7z {
|
||||
|
||||
class CFolderOutStream:
|
||||
public ISequentialOutStream,
|
||||
public CMyUnknownImp
|
||||
{
|
||||
Z7_CLASS_IMP_COM_1(
|
||||
CFolderOutStream
|
||||
, ISequentialOutStream
|
||||
/* , ICompressGetSubStreamSize */
|
||||
)
|
||||
CMyComPtr<ISequentialOutStream> _stream;
|
||||
public:
|
||||
bool TestMode;
|
||||
@@ -31,6 +32,7 @@ private:
|
||||
UInt64 _rem;
|
||||
|
||||
const UInt32 *_indexes;
|
||||
// unsigned _startIndex;
|
||||
unsigned _numFiles;
|
||||
unsigned _fileIndex;
|
||||
|
||||
@@ -40,8 +42,6 @@ private:
|
||||
HRESULT ProcessEmptyFiles();
|
||||
|
||||
public:
|
||||
MY_UNKNOWN_IMP1(ISequentialOutStream)
|
||||
|
||||
const CDbEx *_db;
|
||||
CMyComPtr<IArchiveExtractCallback> ExtractCallback;
|
||||
|
||||
@@ -52,8 +52,6 @@ public:
|
||||
CheckCrc(true)
|
||||
{}
|
||||
|
||||
STDMETHOD(Write)(const void *data, UInt32 size, UInt32 *processedSize);
|
||||
|
||||
HRESULT Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles);
|
||||
HRESULT FlushCorrupted(Int32 callbackOperationResult);
|
||||
|
||||
@@ -63,6 +61,7 @@ public:
|
||||
|
||||
HRESULT CFolderOutStream::Init(unsigned startIndex, const UInt32 *indexes, unsigned numFiles)
|
||||
{
|
||||
// _startIndex = startIndex;
|
||||
_fileIndex = startIndex;
|
||||
_indexes = indexes;
|
||||
_numFiles = numFiles;
|
||||
@@ -76,11 +75,10 @@ HRESULT CFolderOutStream::Init(unsigned startIndex, const UInt32 *indexes, unsig
|
||||
HRESULT CFolderOutStream::OpenFile(bool isCorrupted)
|
||||
{
|
||||
const CFileItem &fi = _db->Files[_fileIndex];
|
||||
UInt32 nextFileIndex = (_indexes ? *_indexes : _fileIndex);
|
||||
Int32 askMode = (_fileIndex == nextFileIndex) ?
|
||||
(TestMode ?
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract) :
|
||||
const UInt32 nextFileIndex = (_indexes ? *_indexes : _fileIndex);
|
||||
Int32 askMode = (_fileIndex == nextFileIndex) ? TestMode ?
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract :
|
||||
NExtract::NAskMode::kSkip;
|
||||
|
||||
if (isCorrupted
|
||||
@@ -90,7 +88,7 @@ HRESULT CFolderOutStream::OpenFile(bool isCorrupted)
|
||||
askMode = NExtract::NAskMode::kTest;
|
||||
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
RINOK(ExtractCallback->GetStream(_fileIndex, &realOutStream, askMode));
|
||||
RINOK(ExtractCallback->GetStream(_fileIndex, &realOutStream, askMode))
|
||||
|
||||
_stream = realOutStream;
|
||||
_crc = CRC_INIT_VAL;
|
||||
@@ -136,13 +134,13 @@ HRESULT CFolderOutStream::ProcessEmptyFiles()
|
||||
{
|
||||
while (_numFiles != 0 && _db->Files[_fileIndex].Size == 0)
|
||||
{
|
||||
RINOK(OpenFile());
|
||||
RINOK(CloseFile());
|
||||
RINOK(OpenFile())
|
||||
RINOK(CloseFile())
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize)
|
||||
Z7_COM7F_IMF(CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *processedSize))
|
||||
{
|
||||
if (processedSize)
|
||||
*processedSize = 0;
|
||||
@@ -170,16 +168,16 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *proc
|
||||
_rem -= cur;
|
||||
if (_rem == 0)
|
||||
{
|
||||
RINOK(CloseFile());
|
||||
RINOK(ProcessEmptyFiles());
|
||||
RINOK(CloseFile())
|
||||
RINOK(ProcessEmptyFiles())
|
||||
}
|
||||
RINOK(result);
|
||||
RINOK(result)
|
||||
if (cur == 0)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
RINOK(ProcessEmptyFiles());
|
||||
RINOK(ProcessEmptyFiles())
|
||||
if (_numFiles == 0)
|
||||
{
|
||||
// we support partial extracting
|
||||
@@ -192,7 +190,7 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *proc
|
||||
// return S_FALSE;
|
||||
return k_My_HRESULT_WritingWasCut;
|
||||
}
|
||||
RINOK(OpenFile());
|
||||
RINOK(OpenFile())
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
@@ -204,18 +202,32 @@ HRESULT CFolderOutStream::FlushCorrupted(Int32 callbackOperationResult)
|
||||
{
|
||||
if (_fileIsOpen)
|
||||
{
|
||||
RINOK(CloseFile_and_SetResult(callbackOperationResult));
|
||||
RINOK(CloseFile_and_SetResult(callbackOperationResult))
|
||||
}
|
||||
else
|
||||
{
|
||||
RINOK(OpenFile(true));
|
||||
RINOK(OpenFile(true))
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec)
|
||||
/*
|
||||
Z7_COM7F_IMF(CFolderOutStream::GetSubStreamSize(UInt64 subStream, UInt64 *value))
|
||||
{
|
||||
*value = 0;
|
||||
// const unsigned numFiles_Original = _numFiles + _fileIndex - _startIndex;
|
||||
const unsigned numFiles_Original = _numFiles;
|
||||
if (subStream >= numFiles_Original)
|
||||
return S_FALSE; // E_FAIL;
|
||||
*value = _db->Files[_startIndex + (unsigned)subStream].Size;
|
||||
return S_OK;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
Z7_COM7F_IMF(CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testModeSpec, IArchiveExtractCallback *extractCallbackSpec))
|
||||
{
|
||||
// for GCC
|
||||
// CFolderOutStream *folderOutStream = new CFolderOutStream;
|
||||
@@ -229,7 +241,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
|
||||
// numItems = (UInt32)(Int32)-1;
|
||||
|
||||
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
|
||||
const bool allFilesMode = (numItems == (UInt32)(Int32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = _db.Files.Size();
|
||||
|
||||
@@ -244,8 +256,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
|
||||
for (i = 0; i < numItems; i++)
|
||||
{
|
||||
UInt32 fileIndex = allFilesMode ? i : indices[i];
|
||||
CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex];
|
||||
const UInt32 fileIndex = allFilesMode ? i : indices[i];
|
||||
const CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex];
|
||||
if (folderIndex == kNumNoIndex)
|
||||
continue;
|
||||
if (folderIndex != prevFolder || fileIndex < nextFile)
|
||||
@@ -257,7 +269,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
}
|
||||
}
|
||||
|
||||
RINOK(extractCallback->SetTotal(importantTotalUnpacked));
|
||||
RINOK(extractCallback->SetTotal(importantTotalUnpacked))
|
||||
|
||||
CLocalProgress *lps = new CLocalProgress;
|
||||
CMyComPtr<ICompressProgressInfo> progress = lps;
|
||||
@@ -268,8 +280,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
false
|
||||
#elif !defined(USE_MIXER_ST)
|
||||
true
|
||||
#elif !defined(__7Z_SET_PROPERTIES)
|
||||
#ifdef _7ZIP_ST
|
||||
#elif !defined(Z7_7Z_SET_PROPERTIES)
|
||||
#ifdef Z7_ST
|
||||
false
|
||||
#else
|
||||
true
|
||||
@@ -281,8 +293,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
|
||||
UInt64 curPacked, curUnpacked;
|
||||
|
||||
CMyComPtr<IArchiveExtractCallbackMessage> callbackMessage;
|
||||
extractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage, &callbackMessage);
|
||||
CMyComPtr<IArchiveExtractCallbackMessage2> callbackMessage;
|
||||
extractCallback.QueryInterface(IID_IArchiveExtractCallbackMessage2, &callbackMessage);
|
||||
|
||||
CFolderOutStream *folderOutStream = new CFolderOutStream;
|
||||
CMyComPtr<ISequentialOutStream> outStream(folderOutStream);
|
||||
@@ -294,7 +306,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
|
||||
for (UInt32 i = 0;; lps->OutSize += curUnpacked, lps->InSize += curPacked)
|
||||
{
|
||||
RINOK(lps->SetCur());
|
||||
RINOK(lps->SetCur())
|
||||
|
||||
if (i >= numItems)
|
||||
break;
|
||||
@@ -303,7 +315,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
curPacked = 0;
|
||||
|
||||
UInt32 fileIndex = allFilesMode ? i : indices[i];
|
||||
CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex];
|
||||
const CNum folderIndex = _db.FileIndexToFolderIndexMap[fileIndex];
|
||||
|
||||
UInt32 numSolidFiles = 1;
|
||||
|
||||
@@ -316,7 +328,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
|
||||
for (k = i + 1; k < numItems; k++)
|
||||
{
|
||||
UInt32 fileIndex2 = allFilesMode ? k : indices[k];
|
||||
const UInt32 fileIndex2 = allFilesMode ? k : indices[k];
|
||||
if (_db.FileIndexToFolderIndexMap[fileIndex2] != folderIndex
|
||||
|| fileIndex2 < nextFile)
|
||||
break;
|
||||
@@ -330,20 +342,26 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
}
|
||||
|
||||
{
|
||||
HRESULT result = folderOutStream->Init(fileIndex,
|
||||
const HRESULT result = folderOutStream->Init(fileIndex,
|
||||
allFilesMode ? NULL : indices + i,
|
||||
numSolidFiles);
|
||||
|
||||
i += numSolidFiles;
|
||||
|
||||
RINOK(result);
|
||||
RINOK(result)
|
||||
}
|
||||
|
||||
// to test solid block with zero unpacked size we disable that code
|
||||
if (folderOutStream->WasWritingFinished())
|
||||
{
|
||||
// for debug: to test zero size stream unpacking
|
||||
// if (folderIndex == kNumNoIndex) // enable this check for debug
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifndef _NO_CRYPTO
|
||||
if (folderIndex == kNumNoIndex)
|
||||
return E_FAIL;
|
||||
|
||||
#ifndef Z7_NO_CRYPTO
|
||||
CMyComPtr<ICryptoGetTextPassword> getTextPassword;
|
||||
if (extractCallback)
|
||||
extractCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
|
||||
@@ -351,16 +369,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
|
||||
try
|
||||
{
|
||||
#ifndef _NO_CRYPTO
|
||||
#ifndef Z7_NO_CRYPTO
|
||||
bool isEncrypted = false;
|
||||
bool passwordIsDefined = false;
|
||||
UString_Wipe password;
|
||||
#endif
|
||||
|
||||
|
||||
bool dataAfterEnd_Error = false;
|
||||
|
||||
HRESULT result = decoder.Decode(
|
||||
const HRESULT result = decoder.Decode(
|
||||
EXTERNAL_CODECS_VARS
|
||||
_inStream,
|
||||
_db.ArcInfo.DataStartPosition,
|
||||
@@ -372,15 +389,15 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
NULL // *inStreamMainRes
|
||||
, dataAfterEnd_Error
|
||||
|
||||
_7Z_DECODER_CRYPRO_VARS
|
||||
#if !defined(_7ZIP_ST)
|
||||
Z7_7Z_DECODER_CRYPRO_VARS
|
||||
#if !defined(Z7_ST)
|
||||
, true, _numThreads, _memUsage_Decompress
|
||||
#endif
|
||||
);
|
||||
|
||||
if (result == S_FALSE || result == E_NOTIMPL || dataAfterEnd_Error)
|
||||
{
|
||||
bool wasFinished = folderOutStream->WasWritingFinished();
|
||||
const bool wasFinished = folderOutStream->WasWritingFinished();
|
||||
|
||||
int resOp = NExtract::NOperationResult::kDataError;
|
||||
|
||||
@@ -392,14 +409,14 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
resOp = NExtract::NOperationResult::kDataAfterEnd;
|
||||
}
|
||||
|
||||
RINOK(folderOutStream->FlushCorrupted(resOp));
|
||||
RINOK(folderOutStream->FlushCorrupted(resOp))
|
||||
|
||||
if (wasFinished)
|
||||
{
|
||||
// we don't show error, if it's after required files
|
||||
if (/* !folderOutStream->ExtraWriteWasCut && */ callbackMessage)
|
||||
{
|
||||
RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, resOp));
|
||||
RINOK(callbackMessage->ReportExtractResult(NEventIndexType::kBlockIndex, folderIndex, resOp))
|
||||
}
|
||||
}
|
||||
continue;
|
||||
@@ -408,12 +425,12 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
if (result != S_OK)
|
||||
return result;
|
||||
|
||||
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
|
||||
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError))
|
||||
continue;
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError));
|
||||
RINOK(folderOutStream->FlushCorrupted(NExtract::NOperationResult::kDataError))
|
||||
// continue;
|
||||
// return E_FAIL;
|
||||
throw;
|
||||
|
||||
Reference in New Issue
Block a user