mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-07 20:06:59 -06:00
15.05
This commit is contained in:
committed by
Kornel Lesiński
parent
0713a3ab80
commit
54490d51d5
@@ -71,7 +71,7 @@ static const Byte kArcProps[] =
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps
|
||||
|
||||
static const char *kMethods[] =
|
||||
static const char * const kMethods[] =
|
||||
{
|
||||
"None"
|
||||
, "MSZip"
|
||||
@@ -124,17 +124,19 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AString s;
|
||||
|
||||
for (unsigned i = 0; i < kNumMethodsMax; i++)
|
||||
{
|
||||
if ((mask & (1 << i)) == 0)
|
||||
continue;
|
||||
if (!s.IsEmpty())
|
||||
s += ' ';
|
||||
s.Add_Space_if_NotEmpty();
|
||||
char temp[kMethodNameBufSize];
|
||||
SetMethodName(temp, i, params[i == NHeader::NMethod::kQuantum ? 0 : 1]);
|
||||
s += temp;
|
||||
}
|
||||
|
||||
prop = s;
|
||||
break;
|
||||
}
|
||||
@@ -466,8 +468,8 @@ STDMETHODIMP CHandler::Open(IInStream *inStream,
|
||||
return result;
|
||||
|
||||
if (!_errorMessage.IsEmpty())
|
||||
_errorMessage += L"\n";
|
||||
_errorMessage += L"Can't open volume: ";
|
||||
_errorMessage.Add_LF();
|
||||
_errorMessage.AddAscii("Can't open volume: ");
|
||||
_errorMessage += fullName;
|
||||
|
||||
if (prevChecked)
|
||||
@@ -528,7 +530,7 @@ private:
|
||||
|
||||
Byte *TempBuf;
|
||||
UInt32 TempBufSize;
|
||||
int NumIdenticalFiles;
|
||||
unsigned NumIdenticalFiles;
|
||||
bool TempBufMode;
|
||||
UInt32 m_BufStartFolderOffset;
|
||||
|
||||
@@ -619,8 +621,9 @@ HRESULT CFolderOutStream::OpenFile()
|
||||
{
|
||||
const CMvItem &mvItem = m_Database->Items[m_StartIndex + m_CurrentIndex];
|
||||
const CItem &item = m_Database->Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
||||
int numExtractItems = 0;
|
||||
unsigned numExtractItems = 0;
|
||||
unsigned curIndex;
|
||||
|
||||
for (curIndex = m_CurrentIndex; curIndex < m_ExtractStatuses->Size(); curIndex++)
|
||||
{
|
||||
const CMvItem &mvItem2 = m_Database->Items[m_StartIndex + curIndex];
|
||||
@@ -632,10 +635,12 @@ HRESULT CFolderOutStream::OpenFile()
|
||||
if (!m_TestMode && (*m_ExtractStatuses)[curIndex])
|
||||
numExtractItems++;
|
||||
}
|
||||
|
||||
NumIdenticalFiles = (curIndex - m_CurrentIndex);
|
||||
if (NumIdenticalFiles == 0)
|
||||
NumIdenticalFiles = 1;
|
||||
TempBufMode = false;
|
||||
|
||||
if (numExtractItems > 1)
|
||||
{
|
||||
if (!TempBuf || item.Size > TempBufSize)
|
||||
@@ -699,7 +704,7 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
UInt32 realProcessed = 0;
|
||||
if (processedSize != NULL)
|
||||
if (processedSize)
|
||||
*processedSize = 0;
|
||||
while (size != 0)
|
||||
{
|
||||
@@ -707,7 +712,7 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
|
||||
{
|
||||
UInt32 numBytesToWrite = MyMin(m_RemainFileSize, size);
|
||||
HRESULT res = S_OK;
|
||||
if (numBytesToWrite > 0)
|
||||
if (numBytesToWrite != 0)
|
||||
{
|
||||
if (!isOK)
|
||||
m_IsOk = false;
|
||||
@@ -721,7 +726,7 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
|
||||
memcpy(TempBuf + (m_PosInFolder - m_BufStartFolderOffset), data, numBytesToWrite);
|
||||
}
|
||||
realProcessed += numBytesToWrite;
|
||||
if (processedSize != NULL)
|
||||
if (processedSize)
|
||||
*processedSize = realProcessed;
|
||||
data = (const void *)((const Byte *)data + numBytesToWrite);
|
||||
size -= numBytesToWrite;
|
||||
@@ -773,7 +778,7 @@ HRESULT CFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processe
|
||||
{
|
||||
UInt32 numBytesToWrite = MyMin(fileOffset - (UInt32)m_PosInFolder, size);
|
||||
realProcessed += numBytesToWrite;
|
||||
if (processedSize != NULL)
|
||||
if (processedSize)
|
||||
*processedSize = realProcessed;
|
||||
data = (const void *)((const Byte *)data + numBytesToWrite);
|
||||
size -= numBytesToWrite;
|
||||
@@ -799,24 +804,24 @@ STDMETHODIMP CFolderOutStream::Write(const void *data, UInt32 size, UInt32 *proc
|
||||
|
||||
HRESULT CFolderOutStream::FlushCorrupted()
|
||||
{
|
||||
const UInt32 kBufferSize = (1 << 10);
|
||||
Byte buffer[kBufferSize];
|
||||
for (int i = 0; i < kBufferSize; i++)
|
||||
buffer[i] = 0;
|
||||
const unsigned kBufSize = (1 << 10);
|
||||
Byte buf[kBufSize];
|
||||
for (unsigned i = 0; i < kBufSize; i++)
|
||||
buf[i] = 0;
|
||||
for (;;)
|
||||
{
|
||||
UInt64 remain = GetRemain();
|
||||
if (remain == 0)
|
||||
return S_OK;
|
||||
UInt32 size = (UInt32)MyMin(remain, (UInt64)kBufferSize);
|
||||
UInt32 size = (remain < kBufSize ? (UInt32)remain : (UInt32)kBufSize);
|
||||
UInt32 processedSizeLocal = 0;
|
||||
RINOK(Write2(buffer, size, &processedSizeLocal, false));
|
||||
RINOK(Write2(buf, size, &processedSizeLocal, false));
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT CFolderOutStream::Unsupported()
|
||||
{
|
||||
while(m_CurrentIndex < m_ExtractStatuses->Size())
|
||||
while (m_CurrentIndex < m_ExtractStatuses->Size())
|
||||
{
|
||||
HRESULT result = OpenFile();
|
||||
if (result != S_FALSE && result != S_OK)
|
||||
@@ -844,9 +849,10 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
UInt32 i;
|
||||
int lastFolder = -2;
|
||||
UInt64 lastFolderSize = 0;
|
||||
for(i = 0; i < numItems; i++)
|
||||
|
||||
for (i = 0; i < numItems; i++)
|
||||
{
|
||||
int index = allFilesMode ? i : indices[i];
|
||||
unsigned index = allFilesMode ? i : indices[i];
|
||||
const CMvItem &mvItem = m_Database.Items[index];
|
||||
const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
||||
if (item.IsDir())
|
||||
@@ -857,6 +863,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
lastFolder = folderIndex;
|
||||
lastFolderSize = item.GetEndOffset();
|
||||
}
|
||||
|
||||
totalUnPacked += lastFolderSize;
|
||||
|
||||
extractCallback->SetTotal(totalUnPacked);
|
||||
@@ -887,9 +894,10 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
CRecordVector<bool> extractStatuses;
|
||||
for(i = 0; i < numItems;)
|
||||
|
||||
for (i = 0; i < numItems;)
|
||||
{
|
||||
int index = allFilesMode ? i : indices[i];
|
||||
unsigned index = allFilesMode ? i : indices[i];
|
||||
|
||||
const CMvItem &mvItem = m_Database.Items[index];
|
||||
const CDatabaseEx &db = m_Database.Volumes[mvItem.VolumeIndex];
|
||||
@@ -909,7 +917,9 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
|
||||
int folderIndex = m_Database.GetFolderIndex(&mvItem);
|
||||
|
||||
if (folderIndex < 0)
|
||||
{
|
||||
// If we need previous archive
|
||||
@@ -923,17 +933,19 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kDataError));
|
||||
continue;
|
||||
}
|
||||
int startIndex2 = m_Database.FolderStartFileIndex[folderIndex];
|
||||
int startIndex = startIndex2;
|
||||
|
||||
unsigned startIndex2 = m_Database.FolderStartFileIndex[folderIndex];
|
||||
unsigned startIndex = startIndex2;
|
||||
extractStatuses.Clear();
|
||||
for (; startIndex < index; startIndex++)
|
||||
extractStatuses.Add(false);
|
||||
extractStatuses.Add(true);
|
||||
startIndex++;
|
||||
UInt64 curUnpack = item.GetEndOffset();
|
||||
|
||||
for (; i < numItems; i++)
|
||||
{
|
||||
int indexNext = allFilesMode ? i : indices[i];
|
||||
unsigned indexNext = allFilesMode ? i : indices[i];
|
||||
const CMvItem &mvItem = m_Database.Items[indexNext];
|
||||
const CItem &item = m_Database.Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
||||
if (item.IsDir())
|
||||
@@ -963,6 +975,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
|
||||
cabBlockInStreamSpec->MsZip = false;
|
||||
HRESULT res = S_OK;
|
||||
|
||||
switch (folder.GetMethod())
|
||||
{
|
||||
case NHeader::NMethod::kNone:
|
||||
@@ -1009,7 +1022,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
int locFolderIndex = item.GetFolderIndex(db.Folders.Size());
|
||||
bool keepHistory = false;
|
||||
bool keepInputBuffer = false;
|
||||
for (UInt32 f = 0; cabFolderOutStream->GetRemain() != 0;)
|
||||
|
||||
for (UInt32 bl = 0; cabFolderOutStream->GetRemain() != 0;)
|
||||
{
|
||||
if (volIndex >= m_Database.Volumes.Size())
|
||||
{
|
||||
@@ -1019,19 +1033,32 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
|
||||
const CDatabaseEx &db = m_Database.Volumes[volIndex];
|
||||
const CFolder &folder = db.Folders[locFolderIndex];
|
||||
if (f == 0)
|
||||
|
||||
if (bl == 0)
|
||||
{
|
||||
cabBlockInStreamSpec->ReservedSize = db.ArcInfo.GetDataBlockReserveSize();
|
||||
RINOK(db.Stream->Seek(db.StartPosition + folder.DataStart, STREAM_SEEK_SET, NULL));
|
||||
}
|
||||
if (f == folder.NumDataBlocks)
|
||||
|
||||
if (bl == folder.NumDataBlocks)
|
||||
{
|
||||
volIndex++;
|
||||
locFolderIndex = 0;
|
||||
f = 0;
|
||||
continue;
|
||||
/*
|
||||
CFolder::NumDataBlocks (CFFOLDER::cCFData in CAB specification) is 16-bit.
|
||||
But there are some big CAB archives from MS that contain more
|
||||
than (0xFFFF) CFDATA blocks in folder.
|
||||
Old cab extracting software can show error (or ask next volume)
|
||||
but cab extracting library in new Windows ignores this error.
|
||||
15.00 : We also try to ignore such error, if archive is not multi-volume.
|
||||
*/
|
||||
if (m_Database.Volumes.Size() > 1)
|
||||
{
|
||||
volIndex++;
|
||||
locFolderIndex = 0;
|
||||
bl = 0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
f++;
|
||||
bl++;
|
||||
|
||||
if (!keepInputBuffer)
|
||||
cabBlockInStreamSpec->InitForNewBlock();
|
||||
@@ -1059,7 +1086,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
unpackRemain = kBlockSizeMax;
|
||||
if (unpackRemain > unpackSize)
|
||||
unpackRemain = unpackSize;
|
||||
|
||||
|
||||
switch (folder.GetMethod())
|
||||
{
|
||||
case NHeader::NMethod::kNone:
|
||||
@@ -1092,14 +1119,17 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
res = quantumDecoder->Code(cabBlockInStream, outStream, NULL, &unpackRemain, NULL);
|
||||
break;
|
||||
}
|
||||
|
||||
if (res != S_OK)
|
||||
{
|
||||
if (res != S_FALSE)
|
||||
RINOK(res);
|
||||
break;
|
||||
}
|
||||
|
||||
keepHistory = true;
|
||||
}
|
||||
|
||||
if (res == S_OK)
|
||||
{
|
||||
RINOK(cabFolderOutStream->WriteEmptyFiles());
|
||||
@@ -1111,6 +1141,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
}
|
||||
totalUnPacked += curUnpack;
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user