mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-08 12:07:03 -06:00
15.07
This commit is contained in:
committed by
Kornel Lesiński
parent
cba375916f
commit
f6444c3256
@@ -144,7 +144,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
if (item.Section == 0)
|
||||
prop = "Copy";
|
||||
else if (item.Section < m_Database.Sections.Size())
|
||||
prop = m_Database.Sections[(int)item.Section].GetMethodName();
|
||||
prop = m_Database.Sections[(unsigned)item.Section].GetMethodName();
|
||||
break;
|
||||
}
|
||||
case kpidBlock:
|
||||
@@ -315,8 +315,9 @@ HRESULT CChmFolderOutStream::WriteEmptyFiles()
|
||||
HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *processedSize, bool isOK)
|
||||
{
|
||||
UInt32 realProcessed = 0;
|
||||
if (processedSize != NULL)
|
||||
if (processedSize)
|
||||
*processedSize = 0;
|
||||
|
||||
while(size != 0)
|
||||
{
|
||||
if (m_FileIsOpen)
|
||||
@@ -335,7 +336,7 @@ HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
||||
}
|
||||
}
|
||||
realProcessed += numBytesToWrite;
|
||||
if (processedSize != NULL)
|
||||
if (processedSize)
|
||||
*processedSize = realProcessed;
|
||||
data = (const void *)((const Byte *)data + numBytesToWrite);
|
||||
size -= numBytesToWrite;
|
||||
@@ -359,23 +360,32 @@ HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
||||
else
|
||||
{
|
||||
if (m_CurrentIndex >= m_NumFiles)
|
||||
return E_FAIL;
|
||||
{
|
||||
realProcessed += size;
|
||||
if (processedSize)
|
||||
*processedSize = realProcessed;
|
||||
return S_OK;
|
||||
// return E_FAIL;
|
||||
}
|
||||
|
||||
int fullIndex = m_StartIndex + m_CurrentIndex;
|
||||
m_RemainFileSize = m_Database->GetFileSize(fullIndex);
|
||||
UInt64 fileOffset = m_Database->GetFileOffset(fullIndex);
|
||||
if (fileOffset < m_PosInSection)
|
||||
return E_FAIL;
|
||||
|
||||
if (fileOffset > m_PosInSection)
|
||||
{
|
||||
UInt32 numBytesToWrite = (UInt32)MyMin(fileOffset - m_PosInSection, UInt64(size));
|
||||
realProcessed += numBytesToWrite;
|
||||
if (processedSize != NULL)
|
||||
if (processedSize)
|
||||
*processedSize = realProcessed;
|
||||
data = (const void *)((const Byte *)data + numBytesToWrite);
|
||||
size -= numBytesToWrite;
|
||||
m_PosInSection += numBytesToWrite;
|
||||
m_PosInFolder += numBytesToWrite;
|
||||
}
|
||||
|
||||
if (fileOffset == m_PosInSection)
|
||||
{
|
||||
RINOK(OpenFile());
|
||||
@@ -385,6 +395,7 @@ HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return WriteEmptyFiles();
|
||||
}
|
||||
|
||||
@@ -430,7 +441,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
|
||||
UInt64 currentTotalSize = 0;
|
||||
|
||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder();
|
||||
NCompress::CCopyCoder *copyCoderSpec = new NCompress::CCopyCoder;
|
||||
CMyComPtr<ICompressCoder> copyCoder = copyCoderSpec;
|
||||
UInt32 i;
|
||||
|
||||
@@ -446,11 +457,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
{
|
||||
UInt64 currentItemSize = 0;
|
||||
UInt64 totalSize = 0;
|
||||
|
||||
if (m_Database.NewFormat)
|
||||
totalSize = m_Database.NewFormatString.Len();
|
||||
else
|
||||
for (i = 0; i < numItems; i++)
|
||||
totalSize += m_Database.Items[allFilesMode ? i : indices[i]].Size;
|
||||
|
||||
extractCallback->SetTotal(totalSize);
|
||||
|
||||
for (i = 0; i < numItems; i++, currentTotalSize += currentItemSize)
|
||||
@@ -481,6 +494,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
RINOK(extractCallback->SetOperationResult(NExtract::NOperationResult::kOK));
|
||||
continue;
|
||||
}
|
||||
|
||||
const CItem &item = m_Database.Items[index];
|
||||
|
||||
currentItemSize = item.Size;
|
||||
@@ -513,6 +527,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
}
|
||||
|
||||
UInt64 lastFolderIndex = ((UInt64)0 - 1);
|
||||
|
||||
for (i = 0; i < numItems; i++)
|
||||
{
|
||||
UInt32 index = allFilesMode ? i : indices[i];
|
||||
@@ -526,7 +541,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
currentTotalSize += item.Size;
|
||||
continue;
|
||||
}
|
||||
const CSectionInfo §ion = m_Database.Sections[(int)item.Section];
|
||||
const CSectionInfo §ion = m_Database.Sections[(unsigned)item.Section];
|
||||
if (section.IsLzx())
|
||||
{
|
||||
const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo;
|
||||
@@ -541,14 +556,17 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
|
||||
RINOK(extractCallback->SetTotal(currentTotalSize));
|
||||
|
||||
NCompress::NLzx::CDecoder *lzxDecoderSpec = 0;
|
||||
CMyComPtr<ICompressCoder> lzxDecoder;
|
||||
NCompress::NLzx::CDecoder *lzxDecoderSpec = NULL;
|
||||
CMyComPtr<IUnknown> lzxDecoder;
|
||||
CChmFolderOutStream *chmFolderOutStream = 0;
|
||||
CMyComPtr<ISequentialOutStream> outStream;
|
||||
|
||||
currentTotalSize = 0;
|
||||
|
||||
CRecordVector<bool> extractStatuses;
|
||||
|
||||
CByteBuffer packBuf;
|
||||
|
||||
for (i = 0; i < numItems;)
|
||||
{
|
||||
RINOK(extractCallback->SetCompleted(¤tTotalSize));
|
||||
@@ -560,6 +578,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 askMode= testMode ?
|
||||
NExtract::NAskMode::kTest :
|
||||
NExtract::NAskMode::kExtract;
|
||||
|
||||
if (item.IsDir())
|
||||
{
|
||||
CMyComPtr<ISequentialOutStream> realOutStream;
|
||||
@@ -595,7 +614,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
continue;
|
||||
}
|
||||
|
||||
const CSectionInfo §ion = m_Database.Sections[(int)sectionIndex];
|
||||
const CSectionInfo §ion = m_Database.Sections[(unsigned)sectionIndex];
|
||||
|
||||
if (!section.IsLzx())
|
||||
{
|
||||
@@ -610,7 +629,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
|
||||
const CLzxInfo &lzxInfo = section.Methods[0].LzxInfo;
|
||||
|
||||
if (chmFolderOutStream == 0)
|
||||
if (!chmFolderOutStream)
|
||||
{
|
||||
chmFolderOutStream = new CChmFolderOutStream;
|
||||
outStream = chmFolderOutStream;
|
||||
@@ -618,7 +637,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
|
||||
chmFolderOutStream->Init(&m_Database, extractCallback, testMode);
|
||||
|
||||
if (lzxDecoderSpec == NULL)
|
||||
if (!lzxDecoderSpec)
|
||||
{
|
||||
lzxDecoderSpec = new NCompress::NLzx::CDecoder;
|
||||
lzxDecoder = lzxDecoderSpec;
|
||||
@@ -627,8 +646,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
UInt64 folderIndex = m_Database.GetFolder(index);
|
||||
|
||||
UInt64 compressedPos = m_Database.ContentOffset + section.Offset;
|
||||
UInt32 numDictBits = lzxInfo.GetNumDictBits();
|
||||
RINOK(lzxDecoderSpec->SetParams(numDictBits));
|
||||
RINOK(lzxDecoderSpec->SetParams_and_Alloc(lzxInfo.GetNumDictBits()));
|
||||
|
||||
const CItem *lastItem = &item;
|
||||
extractStatuses.Clear();
|
||||
@@ -645,10 +663,12 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
lastFolderIndex = m_Database.GetLastFolder(index);
|
||||
UInt64 folderSize = lzxInfo.GetFolderSize();
|
||||
UInt64 unPackSize = folderSize;
|
||||
|
||||
if (extractStatuses.IsEmpty())
|
||||
chmFolderOutStream->m_StartIndex = index + 1;
|
||||
else
|
||||
chmFolderOutStream->m_StartIndex = index;
|
||||
|
||||
if (limitFolderIndex == folderIndex)
|
||||
{
|
||||
for (; i < numItems; i++)
|
||||
@@ -671,6 +691,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
lastFolderIndex = m_Database.GetLastFolder(index);
|
||||
}
|
||||
}
|
||||
|
||||
unPackSize = MyMin(finishPos - startPos, unPackSize);
|
||||
|
||||
chmFolderOutStream->m_FolderSize = folderSize;
|
||||
@@ -679,11 +700,13 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
chmFolderOutStream->m_ExtractStatuses = &extractStatuses;
|
||||
chmFolderOutStream->m_NumFiles = extractStatuses.Size();
|
||||
chmFolderOutStream->m_CurrentIndex = 0;
|
||||
|
||||
try
|
||||
{
|
||||
UInt64 startBlock = lzxInfo.GetBlockIndexFromFolderIndex(folderIndex);
|
||||
const CResetTable &rt = lzxInfo.ResetTable;
|
||||
UInt32 numBlocks = (UInt32)rt.GetNumBlocks(unPackSize);
|
||||
|
||||
for (UInt32 b = 0; b < numBlocks; b++)
|
||||
{
|
||||
UInt64 completedSize = currentTotalSize + chmFolderOutStream->m_PosInSection - startPos;
|
||||
@@ -691,17 +714,35 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
UInt64 bCur = startBlock + b;
|
||||
if (bCur >= rt.ResetOffsets.Size())
|
||||
return E_FAIL;
|
||||
UInt64 offset = rt.ResetOffsets[(int)bCur];
|
||||
UInt64 offset = rt.ResetOffsets[(unsigned)bCur];
|
||||
UInt64 compressedSize;
|
||||
rt.GetCompressedSizeOfBlock(bCur, compressedSize);
|
||||
UInt64 rem = finishPos - chmFolderOutStream->m_PosInSection;
|
||||
if (rem > rt.BlockSize)
|
||||
rem = rt.BlockSize;
|
||||
|
||||
// chm writes full blocks. So we don't need to use reduced size for last block
|
||||
|
||||
RINOK(m_Stream->Seek(compressedPos + offset, STREAM_SEEK_SET, NULL));
|
||||
streamSpec->SetStream(m_Stream);
|
||||
streamSpec->Init(compressedSize);
|
||||
|
||||
lzxDecoderSpec->SetKeepHistory(b > 0);
|
||||
HRESULT res = lzxDecoder->Code(inStream, outStream, NULL, &rem, NULL);
|
||||
|
||||
size_t compressedSizeT = (size_t)compressedSize;
|
||||
if (compressedSizeT != compressedSize)
|
||||
throw 2;
|
||||
packBuf.AllocAtLeast(compressedSizeT);
|
||||
|
||||
HRESULT res = ReadStream_FALSE(inStream, packBuf, compressedSizeT);
|
||||
|
||||
if (res == S_OK)
|
||||
{
|
||||
lzxDecoderSpec->KeepHistoryForNext = true;
|
||||
res = lzxDecoderSpec->Code(packBuf, compressedSizeT, kBlockSize); // rt.BlockSize;
|
||||
if (res == S_OK)
|
||||
res = WriteStream(chmFolderOutStream,
|
||||
lzxDecoderSpec->GetUnpackData(),
|
||||
lzxDecoderSpec->GetUnpackSize());
|
||||
}
|
||||
|
||||
if (res != S_OK)
|
||||
{
|
||||
if (res != S_FALSE)
|
||||
@@ -714,6 +755,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
{
|
||||
RINOK(chmFolderOutStream->FlushCorrupted(unPackSize));
|
||||
}
|
||||
|
||||
currentTotalSize += folderSize;
|
||||
if (folderIndex == lastFolderIndex)
|
||||
break;
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
|
||||
// #include <stdio.h>
|
||||
|
||||
#include "../../../../C/CpuArch.h"
|
||||
|
||||
#include "../../../Common/IntToString.h"
|
||||
#include "../../../Common/UTFConvert.h"
|
||||
|
||||
@@ -11,6 +13,10 @@
|
||||
|
||||
#include "ChmIn.h"
|
||||
|
||||
#define Get16(p) GetUi16(p)
|
||||
#define Get32(p) GetUi32(p)
|
||||
#define Get64(p) GetUi64(p)
|
||||
|
||||
namespace NArchive {
|
||||
namespace NChm {
|
||||
|
||||
@@ -168,38 +174,36 @@ Byte CInArchive::ReadByte()
|
||||
|
||||
void CInArchive::Skip(size_t size)
|
||||
{
|
||||
while (size-- != 0)
|
||||
ReadByte();
|
||||
if (_inBuffer.Skip(size) != size)
|
||||
throw CEnexpectedEndException();
|
||||
}
|
||||
|
||||
void CInArchive::ReadBytes(Byte *data, UInt32 size)
|
||||
{
|
||||
for (UInt32 i = 0; i < size; i++)
|
||||
data[i] = ReadByte();
|
||||
if (_inBuffer.ReadBytes(data, size) != size)
|
||||
throw CEnexpectedEndException();
|
||||
}
|
||||
|
||||
UInt16 CInArchive::ReadUInt16()
|
||||
{
|
||||
UInt16 val = 0;
|
||||
for (int i = 0; i < 2; i++)
|
||||
val |= ((UInt16)(ReadByte()) << (8 * i));
|
||||
return val;
|
||||
Byte b0, b1;
|
||||
if (!_inBuffer.ReadByte(b0)) throw CEnexpectedEndException();
|
||||
if (!_inBuffer.ReadByte(b1)) throw CEnexpectedEndException();
|
||||
return (UInt16)(((UInt16)b1 << 8) | b0);
|
||||
}
|
||||
|
||||
UInt32 CInArchive::ReadUInt32()
|
||||
{
|
||||
UInt32 val = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
val |= ((UInt32)(ReadByte()) << (8 * i));
|
||||
return val;
|
||||
Byte p[4];
|
||||
ReadBytes(p, 4);
|
||||
return Get32(p);
|
||||
}
|
||||
|
||||
UInt64 CInArchive::ReadUInt64()
|
||||
{
|
||||
UInt64 val = 0;
|
||||
for (int i = 0; i < 8; i++)
|
||||
val |= ((UInt64)(ReadByte()) << (8 * i));
|
||||
return val;
|
||||
Byte p[8];
|
||||
ReadBytes(p, 8);
|
||||
return Get64(p);
|
||||
}
|
||||
|
||||
UInt64 CInArchive::ReadEncInt()
|
||||
@@ -227,15 +231,10 @@ void CInArchive::ReadGUID(GUID &g)
|
||||
void CInArchive::ReadString(unsigned size, AString &s)
|
||||
{
|
||||
s.Empty();
|
||||
while (size-- != 0)
|
||||
if (size != 0)
|
||||
{
|
||||
char c = (char)ReadByte();
|
||||
if (c == 0)
|
||||
{
|
||||
Skip(size);
|
||||
return;
|
||||
}
|
||||
s += c;
|
||||
ReadBytes((Byte *)s.GetBuf(size), size);
|
||||
s.ReleaseBuf_CalcLen(size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -380,6 +379,7 @@ HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database)
|
||||
ReadUInt32(); // Chunk number of next listing chunk when reading
|
||||
// directory in sequence (-1 if this is the last listing chunk)
|
||||
unsigned numItems = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
UInt64 offset = _inBuffer.GetProcessedSize() - chunkPos;
|
||||
@@ -391,9 +391,16 @@ HRESULT CInArchive::OpenChm(IInStream *inStream, CDatabase &database)
|
||||
RINOK(ReadDirEntry(database));
|
||||
numItems++;
|
||||
}
|
||||
|
||||
Skip(quickrefLength - 2);
|
||||
if (ReadUInt16() != numItems)
|
||||
return S_FALSE;
|
||||
|
||||
unsigned rrr = ReadUInt16();
|
||||
if (rrr != numItems)
|
||||
{
|
||||
// Lazarus 9-26-2 chm contains 0 here.
|
||||
if (rrr != 0)
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
Skip(dirChunkSize - 4);
|
||||
@@ -709,6 +716,14 @@ bool CFilesDatabase::Check()
|
||||
return true;
|
||||
}
|
||||
|
||||
static int inline GetLog(UInt32 num)
|
||||
{
|
||||
for (int i = 0; i < 32; i++)
|
||||
if (((UInt32)1 << i) == num)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
||||
{
|
||||
{
|
||||
@@ -771,6 +786,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
||||
{
|
||||
// Control Data
|
||||
RINOK(DecompressStream(inStream, database, sectionPrefix + kControlData));
|
||||
|
||||
FOR_VECTOR (mi, section.Methods)
|
||||
{
|
||||
CMethodInfo &method = section.Methods[mi];
|
||||
@@ -785,27 +801,22 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
||||
li.Version = ReadUInt32();
|
||||
if (li.Version != 2 && li.Version != 3)
|
||||
return S_FALSE;
|
||||
li.ResetInterval = ReadUInt32();
|
||||
li.WindowSize = ReadUInt32();
|
||||
|
||||
{
|
||||
int n = GetLog(ReadUInt32());
|
||||
if (n < 0 || n > 16)
|
||||
return S_FALSE;
|
||||
li.ResetIntervalBits = n;
|
||||
}
|
||||
|
||||
{
|
||||
int n = GetLog(ReadUInt32());
|
||||
if (n < 0 || n > 16)
|
||||
return S_FALSE;
|
||||
li.WindowSizeBits = n;
|
||||
}
|
||||
|
||||
li.CacheSize = ReadUInt32();
|
||||
if (
|
||||
li.ResetInterval != 1 &&
|
||||
li.ResetInterval != 2 &&
|
||||
li.ResetInterval != 4 &&
|
||||
li.ResetInterval != 8 &&
|
||||
li.ResetInterval != 16 &&
|
||||
li.ResetInterval != 32 &&
|
||||
li.ResetInterval != 64)
|
||||
return S_FALSE;
|
||||
if (
|
||||
li.WindowSize != 1 &&
|
||||
li.WindowSize != 2 &&
|
||||
li.WindowSize != 4 &&
|
||||
li.WindowSize != 8 &&
|
||||
li.WindowSize != 16 &&
|
||||
li.WindowSize != 32 &&
|
||||
li.WindowSize != 64)
|
||||
return S_FALSE;
|
||||
numDWORDS -= 5;
|
||||
while (numDWORDS-- != 0)
|
||||
ReadUInt32();
|
||||
@@ -835,6 +846,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
||||
RINOK(DecompressStream(inStream, database, transformPrefix +
|
||||
method.GetGuidString() + kResetTable));
|
||||
CResetTable &rt = method.LzxInfo.ResetTable;
|
||||
|
||||
if (_chunkSize < 4)
|
||||
{
|
||||
if (_chunkSize != 0)
|
||||
@@ -844,7 +856,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
||||
return S_FALSE;
|
||||
rt.UncompressedSize = 0;
|
||||
rt.CompressedSize = 0;
|
||||
rt.BlockSize = 0;
|
||||
// rt.BlockSize = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -852,18 +864,45 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
|
||||
if (ver != 2 && ver != 3)
|
||||
return S_FALSE;
|
||||
UInt32 numEntries = ReadUInt32();
|
||||
if (ReadUInt32() != 8) // Size of table entry (bytes)
|
||||
const unsigned kEntrySize = 8;
|
||||
if (ReadUInt32() != kEntrySize)
|
||||
return S_FALSE;
|
||||
if (ReadUInt32() != 0x28) // Len of table header
|
||||
const unsigned kRtHeaderSize = 4 * 4 + 8 * 3;
|
||||
if (ReadUInt32() != kRtHeaderSize)
|
||||
return S_FALSE;
|
||||
if (kRtHeaderSize + kEntrySize * (UInt64)numEntries != _chunkSize)
|
||||
return S_FALSE;
|
||||
|
||||
rt.UncompressedSize = ReadUInt64();
|
||||
rt.CompressedSize = ReadUInt64();
|
||||
rt.BlockSize = ReadUInt64(); // 0x8000 block size for locations below
|
||||
if (rt.BlockSize != 0x8000)
|
||||
UInt64 blockSize = ReadUInt64();
|
||||
if (blockSize != kBlockSize)
|
||||
return S_FALSE;
|
||||
UInt64 numBlocks = (rt.UncompressedSize + kBlockSize + 1) / kBlockSize;
|
||||
if (numEntries != numBlocks &&
|
||||
numEntries != numBlocks + 1)
|
||||
return S_FALSE;
|
||||
|
||||
rt.ResetOffsets.ClearAndReserve(numEntries);
|
||||
|
||||
for (UInt32 i = 0; i < numEntries; i++)
|
||||
rt.ResetOffsets.AddInReserved(ReadUInt64());
|
||||
{
|
||||
UInt64 v = ReadUInt64();
|
||||
if (i != 0 && v < rt.ResetOffsets[i - 1])
|
||||
return S_FALSE;
|
||||
rt.ResetOffsets.AddInReserved(v);
|
||||
}
|
||||
|
||||
if (numEntries != 0)
|
||||
if (rt.ResetOffsets[0] != 0)
|
||||
return S_FALSE;
|
||||
|
||||
if (numEntries == numBlocks + 1)
|
||||
{
|
||||
// Lazarus 9-26-2 chm contains additional entty
|
||||
if (rt.ResetOffsets.Back() != rt.CompressedSize)
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -896,14 +935,16 @@ HRESULT CInArchive::Open2(IInStream *inStream,
|
||||
|
||||
if (_help2)
|
||||
{
|
||||
const int kSignatureSize = 8;
|
||||
UInt64 signature = ((UInt64)kSignature_ITLS << 32)| kSignature_ITOL;
|
||||
const unsigned kSignatureSize = 8;
|
||||
const UInt64 signature = ((UInt64)kSignature_ITLS << 32) | kSignature_ITOL;
|
||||
UInt64 limit = 1 << 18;
|
||||
|
||||
if (searchHeaderSizeLimit)
|
||||
if (limit > *searchHeaderSizeLimit)
|
||||
limit = *searchHeaderSizeLimit;
|
||||
|
||||
UInt64 val = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte b;
|
||||
@@ -919,6 +960,7 @@ HRESULT CInArchive::Open2(IInStream *inStream,
|
||||
return S_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
database.StartPosition += _inBuffer.GetProcessedSize() - kSignatureSize;
|
||||
RINOK(OpenHelp2(inStream, database));
|
||||
if (database.NewFormat)
|
||||
|
||||
@@ -36,12 +36,13 @@ struct CItem
|
||||
|
||||
bool IsDir() const
|
||||
{
|
||||
if (Name.Len() == 0)
|
||||
if (Name.IsEmpty())
|
||||
return false;
|
||||
return (Name.Back() == '/');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct CDatabase
|
||||
{
|
||||
UInt64 StartPosition;
|
||||
@@ -73,11 +74,14 @@ struct CDatabase
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const UInt32 kBlockSize = 1 << 15;
|
||||
|
||||
struct CResetTable
|
||||
{
|
||||
UInt64 UncompressedSize;
|
||||
UInt64 CompressedSize;
|
||||
UInt64 BlockSize;
|
||||
// unsigned BlockSizeBits;
|
||||
CRecordVector<UInt64> ResetOffsets;
|
||||
|
||||
bool GetCompressedSizeOfBlocks(UInt64 blockIndex, UInt32 numBlocks, UInt64 &size) const
|
||||
@@ -91,39 +95,41 @@ struct CResetTable
|
||||
size = ResetOffsets[(unsigned)(blockIndex + numBlocks)] - startPos;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetCompressedSizeOfBlock(UInt64 blockIndex, UInt64 &size) const
|
||||
{
|
||||
return GetCompressedSizeOfBlocks(blockIndex, 1, size);
|
||||
}
|
||||
|
||||
UInt64 GetNumBlocks(UInt64 size) const
|
||||
{
|
||||
return (size + BlockSize - 1) / BlockSize;
|
||||
return (size + kBlockSize - 1) / kBlockSize;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct CLzxInfo
|
||||
{
|
||||
UInt32 Version;
|
||||
UInt32 ResetInterval;
|
||||
UInt32 WindowSize;
|
||||
|
||||
unsigned ResetIntervalBits;
|
||||
unsigned WindowSizeBits;
|
||||
UInt32 CacheSize;
|
||||
|
||||
CResetTable ResetTable;
|
||||
|
||||
UInt32 GetNumDictBits() const
|
||||
unsigned GetNumDictBits() const
|
||||
{
|
||||
if (Version == 2 || Version == 3)
|
||||
{
|
||||
for (unsigned i = 0; i <= 31; i++)
|
||||
if (((UInt32)1 << i) >= WindowSize)
|
||||
return 15 + i;
|
||||
}
|
||||
return 15 + WindowSizeBits;
|
||||
return 0;
|
||||
}
|
||||
|
||||
UInt64 GetFolderSize() const { return ResetTable.BlockSize * ResetInterval; }
|
||||
UInt64 GetFolderSize() const { return kBlockSize << ResetIntervalBits; }
|
||||
UInt64 GetFolder(UInt64 offset) const { return offset / GetFolderSize(); }
|
||||
UInt64 GetFolderPos(UInt64 folderIndex) const { return folderIndex * GetFolderSize(); }
|
||||
UInt64 GetBlockIndexFromFolderIndex(UInt64 folderIndex) const { return folderIndex * ResetInterval; }
|
||||
UInt64 GetBlockIndexFromFolderIndex(UInt64 folderIndex) const { return folderIndex << ResetIntervalBits; }
|
||||
|
||||
bool GetOffsetOfFolder(UInt64 folderIndex, UInt64 &offset) const
|
||||
{
|
||||
UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex);
|
||||
@@ -132,24 +138,28 @@ struct CLzxInfo
|
||||
offset = ResetTable.ResetOffsets[(unsigned)blockIndex];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetCompressedSizeOfFolder(UInt64 folderIndex, UInt64 &size) const
|
||||
{
|
||||
UInt64 blockIndex = GetBlockIndexFromFolderIndex(folderIndex);
|
||||
return ResetTable.GetCompressedSizeOfBlocks(blockIndex, ResetInterval, size);
|
||||
return ResetTable.GetCompressedSizeOfBlocks(blockIndex, (UInt32)1 << ResetIntervalBits, size);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct CMethodInfo
|
||||
{
|
||||
GUID Guid;
|
||||
CByteBuffer ControlData;
|
||||
CLzxInfo LzxInfo;
|
||||
|
||||
bool IsLzx() const;
|
||||
bool IsDes() const;
|
||||
AString GetGuidString() const;
|
||||
UString GetName() const;
|
||||
};
|
||||
|
||||
|
||||
struct CSectionInfo
|
||||
{
|
||||
UInt64 Offset;
|
||||
@@ -203,19 +213,12 @@ public:
|
||||
CDatabase::Clear();
|
||||
HighLevelClear();
|
||||
}
|
||||
|
||||
void SetIndices();
|
||||
void Sort();
|
||||
bool Check();
|
||||
};
|
||||
|
||||
/*
|
||||
class CProgressVirt
|
||||
{
|
||||
public:
|
||||
STDMETHOD(SetTotal)(const UInt64 *numFiles) PURE;
|
||||
STDMETHOD(SetCompleted)(const UInt64 *numFiles) PURE;
|
||||
};
|
||||
*/
|
||||
|
||||
class CInArchive
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user