This commit is contained in:
Igor Pavlov
2015-06-15 00:00:00 +00:00
committed by Kornel Lesiński
parent 0713a3ab80
commit 54490d51d5
591 changed files with 34932 additions and 16390 deletions

View File

@@ -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
}