This commit is contained in:
Igor Pavlov
2015-10-18 00:00:00 +00:00
committed by Kornel Lesiński
parent 6543c28020
commit a663a6deb7
44 changed files with 1659 additions and 565 deletions

View File

@@ -83,8 +83,14 @@ class CHandler: public CHandlerCont
HRESULT ReadTables(IInStream *stream);
UInt64 BlocksToBytes(UInt32 i) const { return (UInt64)i << _blockSizeLog; }
virtual UInt64 GetItemPos(UInt32 index) const { return BlocksToBytes(_items[index].StartBlock); }
virtual UInt64 GetItemSize(UInt32 index) const { return BlocksToBytes(_items[index].NumBlocks); }
virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const
{
const CItem &item = _items[index];
pos = BlocksToBytes(item.StartBlock);
size = BlocksToBytes(item.NumBlocks);
return NExtract::NOperationResult::kOK;
}
public:
INTERFACE_IInArchive_Cont(;)
};

View File

@@ -101,6 +101,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
COM_TRY_BEGIN
NCOM::CPropVariant prop;
if (m_Database.NewFormat)
{
switch (propID)
@@ -112,12 +113,15 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
prop.Detach(value);
return S_OK;
}
int entryIndex;
unsigned entryIndex;
if (m_Database.LowLevel)
entryIndex = index;
else
entryIndex = m_Database.Indices[index];
const CItem &item = m_Database.Items[entryIndex];
switch (propID)
{
case kpidPath:
@@ -161,6 +165,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
#endif
}
prop.Detach(value);
return S_OK;
COM_TRY_END
@@ -244,9 +249,9 @@ public:
UInt64 m_PosInFolder;
UInt64 m_PosInSection;
const CRecordVector<bool> *m_ExtractStatuses;
int m_StartIndex;
int m_CurrentIndex;
int m_NumFiles;
unsigned m_StartIndex;
unsigned m_CurrentIndex;
unsigned m_NumFiles;
private:
const CFilesDatabase *m_Database;
@@ -298,7 +303,7 @@ HRESULT CChmFolderOutStream::WriteEmptyFiles()
{
if (m_FileIsOpen)
return S_OK;
for (;m_CurrentIndex < m_NumFiles; m_CurrentIndex++)
for (; m_CurrentIndex < m_NumFiles; m_CurrentIndex++)
{
UInt64 fileSize = m_Database->GetFileSize(m_StartIndex + m_CurrentIndex);
if (fileSize != 0)
@@ -368,7 +373,7 @@ HRESULT CChmFolderOutStream::Write2(const void *data, UInt32 size, UInt32 *proce
// return E_FAIL;
}
int fullIndex = m_StartIndex + m_CurrentIndex;
unsigned fullIndex = m_StartIndex + m_CurrentIndex;
m_RemainFileSize = m_Database->GetFileSize(fullIndex);
UInt64 fileOffset = m_Database->GetFileOffset(fullIndex);
if (fileOffset < m_PosInSection)
@@ -408,7 +413,7 @@ HRESULT CChmFolderOutStream::FlushCorrupted(UInt64 maxSize)
{
const UInt32 kBufferSize = (1 << 10);
Byte buffer[kBufferSize];
for (int i = 0; i < kBufferSize; i++)
for (unsigned i = 0; i < kBufferSize; i++)
buffer[i] = 0;
if (maxSize > m_FolderSize)
maxSize = m_FolderSize;
@@ -531,9 +536,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
for (i = 0; i < numItems; i++)
{
UInt32 index = allFilesMode ? i : indices[i];
int entryIndex = m_Database.Indices[index];
const CItem &item = m_Database.Items[entryIndex];
UInt64 sectionIndex = item.Section;
const CItem &item = m_Database.Items[m_Database.Indices[index]];
const UInt64 sectionIndex = item.Section;
if (item.IsDir() || item.Size == 0)
continue;
if (sectionIndex == 0)
@@ -567,14 +571,17 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
CByteBuffer packBuf;
for (i = 0; i < numItems;)
for (i = 0;;)
{
RINOK(extractCallback->SetCompleted(&currentTotalSize));
if (i >= numItems)
break;
UInt32 index = allFilesMode ? i : indices[i];
i++;
int entryIndex = m_Database.Indices[index];
const CItem &item = m_Database.Items[entryIndex];
UInt64 sectionIndex = item.Section;
const CItem &item = m_Database.Items[m_Database.Indices[index]];
const UInt64 sectionIndex = item.Section;
Int32 askMode= testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
@@ -645,7 +652,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
UInt64 folderIndex = m_Database.GetFolder(index);
UInt64 compressedPos = m_Database.ContentOffset + section.Offset;
const UInt64 compressedPos = m_Database.ContentOffset + section.Offset;
RINOK(lzxDecoderSpec->SetParams_and_Alloc(lzxInfo.GetNumDictBits()));
const CItem *lastItem = &item;
@@ -673,9 +680,8 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{
for (; i < numItems; i++)
{
UInt32 nextIndex = allFilesMode ? i : indices[i];
int entryIndex = m_Database.Indices[nextIndex];
const CItem &nextItem = m_Database.Items[entryIndex];
const UInt32 nextIndex = allFilesMode ? i : indices[i];
const CItem &nextItem = m_Database.Items[m_Database.Indices[nextIndex]];
if (nextItem.Section != sectionIndex)
break;
UInt64 nextFolderIndex = m_Database.GetFolder(nextIndex);

View File

@@ -656,7 +656,7 @@ static AString GetSectionPrefix(const AString &name)
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
static int CompareFiles(const int *p1, const int *p2, void *param)
static int CompareFiles(const unsigned *p1, const unsigned *p2, void *param)
{
const CObjectVector<CItem> &items = *(const CObjectVector<CItem> *)param;
const CItem &item1 = items[*p1];
@@ -731,7 +731,7 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
RINOK(DecompressStream(inStream, database, kNameList));
/* UInt16 length = */ ReadUInt16();
UInt16 numSections = ReadUInt16();
for (int i = 0; i < numSections; i++)
for (unsigned i = 0; i < numSections; i++)
{
CSectionInfo section;
UInt16 nameLen = ReadUInt16();
@@ -766,10 +766,10 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
RINOK(DecompressStream(inStream, database, transformPrefix + kTransformList));
if ((_chunkSize & 0xF) != 0)
return S_FALSE;
int numGuids = (int)(_chunkSize / 0x10);
unsigned numGuids = (unsigned)(_chunkSize / 0x10);
if (numGuids < 1)
return S_FALSE;
for (int i = 0; i < numGuids; i++)
for (unsigned i = 0; i < numGuids; i++)
{
CMethodInfo method;
ReadGUID(method.Guid);
@@ -803,14 +803,17 @@ HRESULT CInArchive::OpenHighLevel(IInStream *inStream, CFilesDatabase &database)
return S_FALSE;
{
int n = GetLog(ReadUInt32());
// There is bug in VC6, if we use function call as parameter for inline function
UInt32 val32 = ReadUInt32();
int n = GetLog(val32);
if (n < 0 || n > 16)
return S_FALSE;
li.ResetIntervalBits = n;
}
{
int n = GetLog(ReadUInt32());
UInt32 val32 = ReadUInt32();
int n = GetLog(val32);
if (n < 0 || n > 16)
return S_FALSE;
li.WindowSizeBits = n;

View File

@@ -177,25 +177,25 @@ class CFilesDatabase: public CDatabase
{
public:
bool LowLevel;
CRecordVector<int> Indices;
CUIntVector Indices;
CObjectVector<CSectionInfo> Sections;
UInt64 GetFileSize(int fileIndex) const { return Items[Indices[fileIndex]].Size; }
UInt64 GetFileOffset(int fileIndex) const { return Items[Indices[fileIndex]].Offset; }
UInt64 GetFileSize(unsigned fileIndex) const { return Items[Indices[fileIndex]].Size; }
UInt64 GetFileOffset(unsigned fileIndex) const { return Items[Indices[fileIndex]].Offset; }
UInt64 GetFolder(int fileIndex) const
UInt64 GetFolder(unsigned fileIndex) const
{
const CItem &item = Items[Indices[fileIndex]];
const CSectionInfo &section = Sections[(int)item.Section];
const CSectionInfo &section = Sections[(unsigned)item.Section];
if (section.IsLzx())
return section.Methods[0].LzxInfo.GetFolder(item.Offset);
return 0;
}
UInt64 GetLastFolder(int fileIndex) const
UInt64 GetLastFolder(unsigned fileIndex) const
{
const CItem &item = Items[Indices[fileIndex]];
const CSectionInfo &section = Sections[(int)item.Section];
const CSectionInfo &section = Sections[(unsigned)item.Section];
if (section.IsLzx())
return section.Methods[0].LzxInfo.GetFolder(item.Offset + item.Size - 1);
return 0;

View File

@@ -433,9 +433,9 @@ HRESULT CDatabase::Open(IInStream *inStream)
SectorSizeBits = sectorSizeBits;
MiniSectorSizeBits = miniSectorSizeBits;
if (sectorSizeBits > 28 ||
if (sectorSizeBits > 24 ||
sectorSizeBits < 7 ||
miniSectorSizeBits > 28 ||
miniSectorSizeBits > 24 ||
miniSectorSizeBits < 2 ||
miniSectorSizeBits > sectorSizeBits)
return S_FALSE;

View File

File diff suppressed because it is too large Load Diff

View File

@@ -133,15 +133,23 @@ bool CHeader::Parse(const Byte *p)
default: return false;
}
{
int s = GetLog(Get16(p + 11));
if (s < 9 || s > 12)
return false;
SectorSizeLog = (Byte)s;
s = GetLog(p[13]);
if (s < 0)
return false;
SectorsPerClusterLog = (Byte)s;
{
UInt32 val32 = Get16(p + 11);
int s = GetLog(val32);
if (s < 9 || s > 12)
return false;
SectorSizeLog = (Byte)s;
}
{
UInt32 val32 = p[13];
int s = GetLog(val32);
if (s < 0)
return false;
SectorsPerClusterLog = (Byte)s;
}
ClusterSizeLog = (Byte)(SectorSizeLog + SectorsPerClusterLog);
if (ClusterSizeLog > 24)
return false;
}
NumReservedSectors = Get16(p + 14);

View File

@@ -156,8 +156,15 @@ class CHandler: public CHandlerCont
CByteBuffer _buffer;
HRESULT Open2(IInStream *stream);
virtual UInt64 GetItemPos(UInt32 index) const { return _items[index].GetPos(); }
virtual UInt64 GetItemSize(UInt32 index) const { return _items[index].GetSize(); }
virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const
{
const CPartition &item = _items[index];
pos = item.GetPos();
size = item.GetSize();
return NExtract::NOperationResult::kOK;
}
public:
INTERFACE_IInArchive_Cont(;)
};

View File

@@ -28,7 +28,11 @@ STDMETHODIMP CHandlerCont::Extract(const UInt32 *indices, UInt32 numItems,
UInt64 totalSize = 0;
UInt32 i;
for (i = 0; i < numItems; i++)
totalSize += GetItemSize(allFilesMode ? i : indices[i]);
{
UInt64 pos, size;
GetItem_ExtractInfo(allFilesMode ? i : indices[i], pos, size);
totalSize += size;
}
extractCallback->SetTotal(totalSize);
totalSize = 0;
@@ -56,21 +60,31 @@ STDMETHODIMP CHandlerCont::Extract(const UInt32 *indices, UInt32 numItems,
Int32 index = allFilesMode ? i : indices[i];
RINOK(extractCallback->GetStream(index, &outStream, askMode));
UInt64 size = GetItemSize(index);
UInt64 pos, size;
int opRes = GetItem_ExtractInfo(index, pos, size);
totalSize += size;
if (!testMode && !outStream)
continue;
RINOK(extractCallback->PrepareOperation(askMode));
RINOK(_stream->Seek(GetItemPos(index), STREAM_SEEK_SET, NULL));
streamSpec->Init(size);
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
if (opRes == NExtract::NOperationResult::kOK)
{
RINOK(_stream->Seek(pos, STREAM_SEEK_SET, NULL));
streamSpec->Init(size);
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
opRes = NExtract::NOperationResult::kDataError;
if (copyCoderSpec->TotalSize == size)
opRes = NExtract::NOperationResult::kOK;
else if (copyCoderSpec->TotalSize < size)
opRes = NExtract::NOperationResult::kUnexpectedEnd;
}
outStream.Release();
int opRes = NExtract::NOperationResult::kDataError;
if (copyCoderSpec->TotalSize == size)
opRes = NExtract::NOperationResult::kOK;
else if (copyCoderSpec->TotalSize < size)
opRes = NExtract::NOperationResult::kUnexpectedEnd;
RINOK(extractCallback->SetOperationResult(opRes));
}
@@ -81,13 +95,22 @@ STDMETHODIMP CHandlerCont::Extract(const UInt32 *indices, UInt32 numItems,
STDMETHODIMP CHandlerCont::GetStream(UInt32 index, ISequentialInStream **stream)
{
COM_TRY_BEGIN
// const CPartition &item = _items[index];
return CreateLimitedInStream(_stream, GetItemPos(index), GetItemSize(index), stream);
*stream = NULL;
UInt64 pos, size;
if (GetItem_ExtractInfo(index, pos, size) != NExtract::NOperationResult::kOK)
return S_FALSE;
return CreateLimitedInStream(_stream, pos, size, stream);
COM_TRY_END
}
CHandlerImg::CHandlerImg():
_imgExt(NULL)
{
ClearStreamVars();
}
STDMETHODIMP CHandlerImg::Seek(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition)
{
switch (seekOrigin)
@@ -190,6 +213,8 @@ STDMETHODIMP CHandlerImg::Extract(const UInt32 *indices, UInt32 numItems,
int opRes = NExtract::NOperationResult::kDataError;
ClearStreamVars();
CMyComPtr<ISequentialInStream> inStream;
HRESULT hres = GetStream(0, &inStream);
if (hres == S_FALSE)
@@ -205,6 +230,13 @@ STDMETHODIMP CHandlerImg::Extract(const UInt32 *indices, UInt32 numItems,
{
if (copyCoderSpec->TotalSize == _size)
opRes = NExtract::NOperationResult::kOK;
if (_stream_unavailData)
opRes = NExtract::NOperationResult::kUnavailable;
else if (_stream_unsupportedMethod)
opRes = NExtract::NOperationResult::kUnsupportedMethod;
else if (_stream_dataError)
opRes = NExtract::NOperationResult::kDataError;
else if (copyCoderSpec->TotalSize < _size)
opRes = NExtract::NOperationResult::kUnexpectedEnd;
}

View File

@@ -30,8 +30,8 @@ class CHandlerCont:
protected:
CMyComPtr<IInStream> _stream;
virtual UInt64 GetItemPos(UInt32 index) const = 0;
virtual UInt64 GetItemSize(UInt32 index) const = 0;
virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const = 0;
public:
MY_UNKNOWN_IMP2(IInArchive, IInArchiveGetStream)
INTERFACE_IInArchive_Cont(PURE)
@@ -39,6 +39,9 @@ public:
STDMETHOD(Extract)(const UInt32* indices, UInt32 numItems, Int32 testMode, IArchiveExtractCallback *extractCallback) MY_NO_THROW_DECL_ONLY;
STDMETHOD(GetStream)(UInt32 index, ISequentialInStream **stream);
// destructor must be virtual for this class
virtual ~CHandlerCont() {}
};
@@ -68,6 +71,22 @@ protected:
UInt64 _size;
CMyComPtr<IInStream> Stream;
const char *_imgExt;
bool _stream_unavailData;
bool _stream_unsupportedMethod;
bool _stream_dataError;
// bool _stream_UsePackSize;
// UInt64 _stream_PackSize;
void ClearStreamVars()
{
_stream_unavailData = false;
_stream_unsupportedMethod = false;
_stream_dataError = false;
// _stream_UsePackSize = false;
// _stream_PackSize = 0;
}
virtual HRESULT Open2(IInStream *stream, IArchiveOpenCallback *openCallback) = 0;
virtual void CloseAtError();
@@ -83,6 +102,10 @@ public:
STDMETHOD(Read)(void *data, UInt32 size, UInt32 *processedSize) = 0;
STDMETHOD(Seek)(Int64 offset, UInt32 seekOrigin, UInt64 *newPosition);
CHandlerImg();
// destructor must be virtual for this class
virtual ~CHandlerImg() {}
};

View File

@@ -323,7 +323,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
{
lps->InSize = lps->OutSize = currentTotalSize + offset;
const CDir &item2 = ref.Dir->_subItems[ref.Index + e];
RINOK(_stream->Seek((UInt64)item2.ExtentLocation * _archive.BlockSize, STREAM_SEEK_SET, NULL));
RINOK(_stream->Seek((UInt64)item2.ExtentLocation * kBlockSize, STREAM_SEEK_SET, NULL));
streamSpec->Init(item2.Size);
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
if (copyCoderSpec->TotalSize != item2.Size)
@@ -336,7 +336,7 @@ STDMETHODIMP CHandler::Extract(const UInt32 *indices, UInt32 numItems,
}
else
{
RINOK(_stream->Seek(blockIndex * _archive.BlockSize, STREAM_SEEK_SET, NULL));
RINOK(_stream->Seek((UInt64)blockIndex * kBlockSize, STREAM_SEEK_SET, NULL));
streamSpec->Init(currentItemSize);
RINOK(copyCoder->Code(inStream, realOutStream, NULL, NULL, progress));
if (copyCoderSpec->TotalSize != currentItemSize)
@@ -379,7 +379,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
if (item.Size == 0)
continue;
CSeekExtent se;
se.Phy = (UInt64)item.ExtentLocation * _archive.BlockSize;
se.Phy = (UInt64)item.ExtentLocation * kBlockSize;
se.Virt = virtOffset;
extentStreamSpec->Extents.Add(se);
virtOffset += item.Size;
@@ -405,7 +405,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
blockIndex = be.LoadRBA;
}
return CreateLimitedInStream(_stream, blockIndex * _archive.BlockSize, currentItemSize, stream);
return CreateLimitedInStream(_stream, (UInt64)blockIndex * kBlockSize, currentItemSize, stream);
COM_TRY_END
}

View File

@@ -88,15 +88,15 @@ AString CBootInitialEntry::GetName() const
Byte CInArchive::ReadByte()
{
if (m_BufferPos >= BlockSize)
if (m_BufferPos >= kBlockSize)
m_BufferPos = 0;
if (m_BufferPos == 0)
{
size_t processed = BlockSize;
size_t processed = kBlockSize;
HRESULT res = ReadStream(_stream, m_Buffer, &processed);
if (res != S_OK)
throw CSystemException(res);
if (processed != BlockSize)
if (processed != kBlockSize)
throw CUnexpectedEndException();
UInt64 end = _position + processed;
if (PhySize < end)
@@ -511,7 +511,7 @@ HRESULT CInArchive::Open2()
PhySize = _position;
m_BufferPos = 0;
BlockSize = kBlockSize;
// BlockSize = kBlockSize;
for (;;)
{

View File

@@ -282,7 +282,7 @@ public:
CRecordVector<CRef> Refs;
CObjectVector<CVolumeDescriptor> VolDescs;
int MainVolDescIndex;
UInt32 BlockSize;
// UInt32 BlockSize;
CObjectVector<CBootInitialEntry> BootEntries;
bool IsArc;
@@ -297,8 +297,8 @@ public:
void UpdatePhySize(UInt32 blockIndex, UInt64 size)
{
UInt64 alignedSize = (size + BlockSize - 1) & ~((UInt64)BlockSize - 1);
UInt64 end = blockIndex * BlockSize + alignedSize;
const UInt64 alignedSize = (size + kBlockSize - 1) & ~((UInt64)kBlockSize - 1);
const UInt64 end = (UInt64)blockIndex * kBlockSize + alignedSize;
if (PhySize < end)
PhySize = end;
}
@@ -315,7 +315,7 @@ public:
size = (1440 << 10);
else if (be.BootMediaType == NBootMediaType::k2d88Floppy)
size = (2880 << 10);
UInt64 startPos = (UInt64)be.LoadRBA * BlockSize;
UInt64 startPos = (UInt64)be.LoadRBA * kBlockSize;
if (startPos < _fileSize)
{
if (_fileSize - startPos < size)

View File

@@ -158,6 +158,7 @@ static const CPartType kPartTypes[] =
{ 0x1E, kFat, "FAT16-LBA-WIN95-Hidden" },
{ 0x82, 0, "Solaris x86 / Linux swap" },
{ 0x83, 0, "Linux" },
{ 0x8E, "lvm", "Linux LVM" },
{ 0xA5, 0, "BSD slice" },
{ 0xBE, 0, "Solaris 8 boot" },
{ 0xBF, 0, "New Solaris x86" },
@@ -189,8 +190,14 @@ class CHandler: public CHandlerCont
UInt64 _totalSize;
CByteBuffer _buffer;
virtual UInt64 GetItemPos(UInt32 index) const { return _items[index].Part.GetPos(); }
virtual UInt64 GetItemSize(UInt32 index) const { return _items[index].Size; }
virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const
{
const CItem &item = _items[index];
pos = item.Part.GetPos();
size = item.Size;
return NExtract::NOperationResult::kOK;
}
HRESULT ReadTables(IInStream *stream, UInt32 baseLba, UInt32 lba, unsigned level);
public:
INTERFACE_IInArchive_Cont(;)

View File

@@ -56,8 +56,15 @@ class CHandler: public CHandlerCont
CItem _items[kNumFilesMax];
HRESULT Open2(IInStream *stream);
virtual UInt64 GetItemPos(UInt32 index) const { return _items[index].Offset; }
virtual UInt64 GetItemSize(UInt32 index) const { return _items[index].Size; }
virtual int GetItem_ExtractInfo(UInt32 index, UInt64 &pos, UInt64 &size) const
{
const CItem &item = _items[index];
pos = item.Offset;
size = item.Size;
return NExtract::NOperationResult::kOK;
}
public:
INTERFACE_IInArchive_Cont(;)
};

View File

@@ -576,20 +576,20 @@ class CInStream:
UInt64 _physPos;
UInt64 _curRem;
bool _sparseMode;
size_t _compressedPos;
UInt64 _tags[kNumCacheChunks];
unsigned _chunkSizeLog;
UInt64 _tags[kNumCacheChunks];
CByteBuffer _inBuf;
CByteBuffer _outBuf;
public:
CMyComPtr<IInStream> Stream;
UInt64 Size;
UInt64 InitializedSize;
unsigned BlockSizeLog;
unsigned CompressionUnit;
bool InUse;
CRecordVector<CExtent> Extents;
bool InUse;
CMyComPtr<IInStream> Stream;
HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); }
@@ -597,11 +597,11 @@ public:
HRESULT InitAndSeek(unsigned compressionUnit)
{
CompressionUnit = compressionUnit;
_chunkSizeLog = BlockSizeLog + CompressionUnit;
if (compressionUnit != 0)
{
UInt32 cuSize = GetCuSize();
_inBuf.Alloc(cuSize);
_chunkSizeLog = BlockSizeLog + CompressionUnit;
_outBuf.Alloc(kNumCacheChunks << _chunkSizeLog);
}
for (size_t i = 0; i < kNumCacheChunks; i++)

View File

@@ -226,8 +226,13 @@ class CHandler: public CHandlerCont
HRESULT ReadHeader(ISequentialInStream *stream, bool isMainHeader);
HRESULT Open2(ISequentialInStream *stream);
virtual UInt64 GetItemPos(UInt32) const { return _headersSize; }
virtual UInt64 GetItemSize(UInt32) const { return _size; }
virtual int GetItem_ExtractInfo(UInt32 /* index */, UInt64 &pos, UInt64 &size) const
{
pos = _headersSize;
size = _size;
return NExtract::NOperationResult::kOK;
}
public:
INTERFACE_IInArchive_Cont(;)
};

View File

@@ -564,7 +564,7 @@ HRESULT CInArchive::ReadItem(int volIndex, int fsIndex, const CLongAllocDesc &la
return S_OK;
}
HRESULT CInArchive::FillRefs(CFileSet &fs, int fileIndex, int parent, int numRecurseAllowed)
HRESULT CInArchive::FillRefs(CFileSet &fs, unsigned fileIndex, int parent, int numRecurseAllowed)
{
if ((_numRefs & 0xFFF) == 0)
{

View File

@@ -252,7 +252,7 @@ struct CItem
bool IsInline;
CByteBuffer InlineData;
CRecordVector<CMyExtent> Extents;
CRecordVector<int> SubFiles;
CUIntVector SubFiles;
void Parse(const Byte *buf);
@@ -282,7 +282,7 @@ struct CItem
struct CRef
{
int Parent;
int FileIndex;
unsigned FileIndex;
};
@@ -346,7 +346,7 @@ class CInArchive
HRESULT ReadItem(int volIndex, int fsIndex, const CLongAllocDesc &lad, int numRecurseAllowed);
HRESULT Open2();
HRESULT FillRefs(CFileSet &fs, int fileIndex, int parent, int numRecurseAllowed);
HRESULT FillRefs(CFileSet &fs, unsigned fileIndex, int parent, int numRecurseAllowed);
UInt64 _processedProgressBytes;

View File

File diff suppressed because it is too large Load Diff

View File

@@ -723,7 +723,7 @@ static HRESULT Update2(
CThreads threads;
CRecordVector<HANDLE> compressingCompletedEvents;
CRecordVector<int> threadIndices; // list threads in order of updateItems
CUIntVector threadIndices; // list threads in order of updateItems
{
RINOK(memManager.AllocateSpaceAlways((size_t)numThreads * (kMemPerThread / kBlockSize)));
@@ -759,7 +759,7 @@ static HRESULT Update2(
while (itemIndex < updateItems.Size())
{
if ((UInt32)threadIndices.Size() < numThreads && mtItemIndex < updateItems.Size())
if (threadIndices.Size() < numThreads && mtItemIndex < updateItems.Size())
{
CUpdateItem &ui = updateItems[mtItemIndex++];
if (!ui.NewData)

View File

@@ -513,10 +513,11 @@ static int main2(int numArgs, const char *args[])
if (parser[NKey::kEOS].ThereIs || stdInMode)
throw "Can not use stdin in this mode";
if (fileSize > 0xF0000000)
throw "File is too big";
size_t inSize = (size_t)fileSize;
if (inSize != fileSize)
throw "File is too big";
Byte *inBuffer = NULL;
if (inSize != 0)
@@ -535,7 +536,13 @@ static int main2(int numArgs, const char *args[])
if (encodeMode)
{
// we allocate 105% of original size for output buffer
outSize = (size_t)fileSize / 20 * 21 + (1 << 16);
UInt64 outSize64 = fileSize / 20 * 21 + (1 << 16);
outSize = (size_t)outSize64;
if (outSize != outSize64)
throw "File is too big";
if (outSize != 0)
{
outBuffer = (Byte *)MyAlloc((size_t)outSize);
@@ -561,7 +568,7 @@ static int main2(int numArgs, const char *args[])
outSize = (size_t)outSize64;
if (outSize != outSize64)
throw "too big";
throw "Unpack size is too big";
if (outSize != 0)
{
outBuffer = (Byte *)MyAlloc(outSize);

View File

@@ -366,6 +366,10 @@ SOURCE=..\..\..\..\C\7zCrcOpt.c
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\7zTypes.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Alloc.c
# SUBTRACT CPP /YX /Yc /Yu
# End Source File
@@ -464,10 +468,6 @@ SOURCE=..\..\..\..\C\Threads.c
SOURCE=..\..\..\..\C\Threads.h
# End Source File
# Begin Source File
SOURCE=..\..\..\..\C\Types.h
# End Source File
# End Group
# Begin Source File

View File

@@ -86,26 +86,34 @@ STDMETHODIMP CClusterInStream::Read(void *data, UInt32 size, UInt32 *processedSi
*processedSize = 0;
if (_virtPos >= Size)
return S_OK;
{
UInt64 rem = Size - _virtPos;
if (size > rem)
size = (UInt32)rem;
}
if (size == 0)
return S_OK;
if (_curRem == 0)
{
UInt32 blockSize = (UInt32)1 << BlockSizeLog;
UInt32 virtBlock = (UInt32)(_virtPos >> BlockSizeLog);
UInt32 offsetInBlock = (UInt32)_virtPos & (blockSize - 1);
UInt32 phyBlock = Vector[virtBlock];
const UInt32 blockSize = (UInt32)1 << BlockSizeLog;
const UInt32 virtBlock = (UInt32)(_virtPos >> BlockSizeLog);
const UInt32 offsetInBlock = (UInt32)_virtPos & (blockSize - 1);
const UInt32 phyBlock = Vector[virtBlock];
UInt64 newPos = StartOffset + ((UInt64)phyBlock << BlockSizeLog) + offsetInBlock;
if (newPos != _physPos)
{
_physPos = newPos;
RINOK(SeekToPhys());
}
_curRem = blockSize - offsetInBlock;
for (int i = 1; i < 64 && (virtBlock + i) < (UInt32)Vector.Size() && phyBlock + i == Vector[virtBlock + i]; i++)
_curRem += (UInt32)1 << BlockSizeLog;
UInt64 rem = Size - _virtPos;
if (_curRem > rem)
_curRem = (UInt32)rem;
}
if (size > _curRem)
size = _curRem;
HRESULT res = Stream->Read(data, size, &size);

View File

@@ -73,11 +73,11 @@ class CClusterInStream:
UInt64 _physPos;
UInt32 _curRem;
public:
CMyComPtr<IInStream> Stream;
UInt64 StartOffset;
UInt64 Size;
unsigned BlockSizeLog;
UInt64 Size;
CMyComPtr<IInStream> Stream;
CRecordVector<UInt32> Vector;
UInt64 StartOffset;
HRESULT SeekToPhys() { return Stream->Seek(_physPos, STREAM_SEEK_SET, NULL); }

View File

@@ -90,51 +90,65 @@ HRESULT ParseMtProp(const UString &name, const PROPVARIANT &prop, UInt32 default
return ParsePropToUInt32(name, prop, numThreads);
}
static HRESULT StringToDictSize(const UString &s, UInt32 &dicSize)
static HRESULT StringToDictSize(const UString &s, NCOM::CPropVariant &destProp)
{
const wchar_t *end;
UInt32 number = ConvertStringToUInt32(s, &end);
unsigned numDigits = (unsigned)(end - s);
if (numDigits == 0 || s.Len() > numDigits + 1)
return E_INVALIDARG;
const unsigned kLogDictSizeLimit = 32;
if (s.Len() == numDigits)
{
if (number >= kLogDictSizeLimit)
if (number >= 64)
return E_INVALIDARG;
dicSize = (UInt32)1 << (unsigned)number;
if (number < 32)
destProp = (UInt32)((UInt32)1 << (unsigned)number);
else
destProp = (UInt64)((UInt64)1 << (unsigned)number);
return S_OK;
}
unsigned numBits;
switch (MyCharLower_Ascii(s[numDigits]))
{
case 'b': dicSize = number; return S_OK;
case 'b': destProp = number; return S_OK;
case 'k': numBits = 10; break;
case 'm': numBits = 20; break;
case 'g': numBits = 30; break;
default: return E_INVALIDARG;
}
if (number >= ((UInt32)1 << (kLogDictSizeLimit - numBits)))
return E_INVALIDARG;
dicSize = number << numBits;
if (number < ((UInt32)1 << (32 - numBits)))
destProp = (UInt32)(number << numBits);
else
destProp = (UInt64)((UInt64)number << numBits);
return S_OK;
}
static HRESULT PROPVARIANT_to_DictSize(const PROPVARIANT &prop, UInt32 &resValue)
static HRESULT PROPVARIANT_to_DictSize(const PROPVARIANT &prop, NCOM::CPropVariant &destProp)
{
if (prop.vt == VT_UI4)
{
UInt32 v = prop.ulVal;
if (v >= 32)
if (v >= 64)
return E_INVALIDARG;
resValue = (UInt32)1 << v;
if (v < 32)
destProp = (UInt32)((UInt32)1 << (unsigned)v);
else
destProp = (UInt64)((UInt64)1 << (unsigned)v);
return S_OK;
}
if (prop.vt == VT_BSTR)
return StringToDictSize(prop.bstrVal, resValue);
return StringToDictSize(prop.bstrVal, destProp);
return E_INVALIDARG;
}
void CProps::AddProp32(PROPID propid, UInt32 level)
{
CProp &prop = Props.AddNew();
@@ -275,10 +289,10 @@ static void SplitParams(const UString &srcString, UStringVector &subStrings)
{
subStrings.Clear();
UString s;
int len = srcString.Len();
unsigned len = srcString.Len();
if (len == 0)
return;
for (int i = 0; i < len; i++)
for (unsigned i = 0; i < len; i++)
{
wchar_t c = srcString[i];
if (c == L':')
@@ -336,9 +350,7 @@ HRESULT CMethodProps::SetParam(const UString &name, const UString &value)
if (IsLogSizeProp(prop.Id))
{
UInt32 dicSize;
RINOK(StringToDictSize(value, dicSize));
prop.Value = dicSize;
RINOK(StringToDictSize(value, prop.Value));
}
else
{
@@ -406,9 +418,7 @@ HRESULT CMethodProps::ParseParamsFromPROPVARIANT(const UString &realName, const
if (IsLogSizeProp(prop.Id))
{
UInt32 dicSize;
RINOK(PROPVARIANT_to_DictSize(value, dicSize));
prop.Value = dicSize;
RINOK(PROPVARIANT_to_DictSize(value, prop.Value));
}
else
{

View File

@@ -38,7 +38,20 @@ HRESULT SetLzma2Prop(PROPID propID, const PROPVARIANT &prop, CLzma2EncProps &lzm
switch (propID)
{
case NCoderPropID::kBlockSize:
if (prop.vt != VT_UI4) return E_INVALIDARG; lzma2Props.blockSize = prop.ulVal; break;
{
if (prop.vt == VT_UI4)
lzma2Props.blockSize = prop.ulVal;
else if (prop.vt == VT_UI8)
{
size_t v = (size_t)prop.uhVal.QuadPart;
if (v != prop.uhVal.QuadPart)
return E_INVALIDARG;
lzma2Props.blockSize = v;
}
else
return E_INVALIDARG;
break;
}
case NCoderPropID::kNumThreads:
if (prop.vt != VT_UI4) return E_INVALIDARG; lzma2Props.numTotalThreads = (int)(prop.ulVal); break;
default:

View File

@@ -441,7 +441,7 @@ STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 operationResult)
}
}
if (_outFileStream != NULL)
if (_outFileStream)
{
if (_processedFileInfo.MTimeDefined)
_outFileStreamSpec->SetMTime(&_processedFileInfo.MTime);
@@ -499,7 +499,6 @@ public:
STDMETHOD(SetCompleted)(const UInt64 *completeValue);
// IUpdateCallback2
STDMETHOD(EnumProperties)(IEnumSTATPROPSTG **enumerator);
STDMETHOD(GetUpdateItemInfo)(UInt32 index,
Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive);
STDMETHOD(GetProperty)(UInt32 index, PROPID propID, PROPVARIANT *value);
@@ -551,20 +550,14 @@ STDMETHODIMP CArchiveUpdateCallback::SetCompleted(const UInt64 * /* completeValu
return S_OK;
}
STDMETHODIMP CArchiveUpdateCallback::EnumProperties(IEnumSTATPROPSTG ** /* enumerator */)
{
return E_NOTIMPL;
}
STDMETHODIMP CArchiveUpdateCallback::GetUpdateItemInfo(UInt32 /* index */,
Int32 *newData, Int32 *newProperties, UInt32 *indexInArchive)
{
if (newData != NULL)
if (newData)
*newData = BoolToInt(true);
if (newProperties != NULL)
if (newProperties)
*newProperties = BoolToInt(true);
if (indexInArchive != NULL)
if (indexInArchive)
*indexInArchive = (UInt32)(Int32)-1;
return S_OK;
}

View File

@@ -108,34 +108,52 @@ static const char *kHelpString =
" h : Calculate hash values for files\n"
" i : Show information about supported formats\n"
" l : List contents of archive\n"
// " l[a|t][f] : List contents of archive\n"
// " a - with Additional fields\n"
// " t - with all fields\n"
// " f - with Full pathnames\n"
" rn : Rename files in archive\n"
" t : Test integrity of archive\n"
" u : Update files to archive\n"
" x : eXtract files with full paths\n"
"\n"
"<Switches>\n"
" -- : Stop switches parsing\n"
" -ai[r[-|0]]{@listfile|!wildcard} : Include archives\n"
" -ax[r[-|0]]{@listfile|!wildcard} : eXclude archives\n"
" -bd : Disable percentage indicator\n"
" -ao{a|s|t|u} : set Overwrite mode\n"
" -an : disable archive_name field\n"
" -bb[0-3] : set output log level\n"
" -bd : disable progress indicator\n"
" -bs{o|e|p}{0|1|2} : set output stream for output/error/progress line\n"
" -bt : show execution time statistics\n"
" -i[r[-|0]]{@listfile|!wildcard} : Include filenames\n"
" -m{Parameters} : set compression Method\n"
" -mmt[N] : set number of CPU threads\n"
" -o{Directory} : set Output directory\n"
#ifndef _NO_CRYPTO
" -p{Password} : set Password\n"
#endif
" -r[-|0] : Recurse subdirectories\n"
" -sa{a|e|s} : set Archive name mode\n"
" -scc{UTF-8|WIN|DOS} : set charset for for console input/output\n"
" -scs{UTF-8|UTF-16LE|UTF-16BE|WIN|DOS|{id}} : set charset for list files\n"
" -sdel : Delete files after compression\n"
" -scrc[CRC32|CRC64|SHA1|SHA256|*] : set hash function for x, e, h commands\n"
" -sdel : delete files after compression\n"
" -seml[.] : send archive by email\n"
" -sfx[{name}] : Create SFX archive\n"
" -si[{name}] : read data from stdin\n"
" -slp : set Large Pages mode\n"
" -slt : show technical information for l (List) command\n"
" -snh : store hard links as links\n"
" -snl : store symbolic links as links\n"
" -sni : store NT security information\n"
" -sns[-] : store NTFS alternate streams\n"
" -so : write data to stdout\n"
" -spd : disable wildcard matching for file names\n"
" -spe : eliminate duplication of root folder for extract command\n"
" -spf : use fully qualified file paths\n"
" -ssc[-] : set sensitive case mode\n"
" -ssw : compress shared files\n"
" -stl : set archive timestamp from the most recently modified file\n"
" -stm{HexMask} : set CPU thread affinity mask (hexadecimal number)\n"
" -stx{Type} : exclude archive type\n"
" -t{Type} : Set type of archive\n"
" -u[-][p#][q#][r#][x#][y#][z#][!newArchiveName] : Update options\n"
" -v{Size}[b|k|m|g] : Create volumes\n"

View File

@@ -85,7 +85,7 @@ public:
CRecordVector<bool> NeedWait;
~CChildProcesses() { CloseAll(); }
void DisableWait(int index) { NeedWait[index] = false; }
void DisableWait(unsigned index) { NeedWait[index] = false; }
void CloseAll()
{
@@ -491,7 +491,19 @@ typedef BOOL (WINAPI * ShellExecuteExWP)(LPSHELLEXECUTEINFOW lpExecInfo);
static HRESULT StartApplication(const UString &dir, const UString &path, HWND window, CProcess &process)
{
UString path2 = path;
#ifdef _WIN32
{
int dot = path2.ReverseFind_Dot();
int separ = path2.ReverseFind_PathSepar();
if (dot < 0 || dot < separ)
path2 += L'.';
}
#endif
UINT32 result;
#ifndef _UNICODE
if (g_IsNT)
{
@@ -500,14 +512,14 @@ static HRESULT StartApplication(const UString &dir, const UString &path, HWND wi
execInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_DDEWAIT;
execInfo.hwnd = NULL;
execInfo.lpVerb = NULL;
execInfo.lpFile = path;
execInfo.lpFile = path2;
execInfo.lpParameters = NULL;
execInfo.lpDirectory = dir.IsEmpty() ? NULL : (LPCWSTR)dir;
execInfo.nShow = SW_SHOWNORMAL;
execInfo.hProcess = 0;
ShellExecuteExWP shellExecuteExW = (ShellExecuteExWP)
::GetProcAddress(::GetModuleHandleW(L"shell32.dll"), "ShellExecuteExW");
if (shellExecuteExW == 0)
if (!shellExecuteExW)
return 0;
shellExecuteExW(&execInfo);
result = (UINT32)(UINT_PTR)execInfo.hInstApp;
@@ -525,23 +537,24 @@ static HRESULT StartApplication(const UString &dir, const UString &path, HWND wi
;
execInfo.hwnd = NULL;
execInfo.lpVerb = NULL;
const CSysString sysPath = GetSystemString(path);
const CSysString sysPath = GetSystemString(path2);
const CSysString sysDir = GetSystemString(dir);
execInfo.lpFile = sysPath;
execInfo.lpParameters = NULL;
execInfo.lpDirectory =
#ifdef UNDER_CE
NULL
#else
sysDir.IsEmpty() ? NULL : (LPCTSTR)sysDir
#endif
;
#ifdef UNDER_CE
NULL
#else
sysDir.IsEmpty() ? NULL : (LPCTSTR)sysDir
#endif
;
execInfo.nShow = SW_SHOWNORMAL;
execInfo.hProcess = 0;
::ShellExecuteEx(&execInfo);
result = (UINT32)(UINT_PTR)execInfo.hInstApp;
process.Attach(execInfo.hProcess);
}
if (result <= 32)
{
switch (result)
@@ -553,6 +566,7 @@ static HRESULT StartApplication(const UString &dir, const UString &path, HWND wi
L"7-Zip", MB_OK | MB_ICONSTOP);
}
}
return S_OK;
}
@@ -795,7 +809,7 @@ static THREAD_FUNC_DECL MyThreadFunction(void *param)
for (;;)
{
CRecordVector<HANDLE> handles;
CRecordVector<int> indices;
CUIntVector indices;
FOR_VECTOR (i, processes.Handles)
{
@@ -992,6 +1006,17 @@ static HRESULT GetTime(IFolderFolder *folder, UInt32 index, PROPID propID, FILET
}
*/
/*
tryInternal tryExternal
false false : unused
false true : external
true false : internal
true true : smart based on file extension:
!alwaysStart(name) : both
alwaysStart(name) : external
*/
void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bool editMode, bool useEditor, const wchar_t *type)
{
const UString name = GetItemName(index);
@@ -1008,7 +1033,7 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
bool tryAsArchive = tryInternal && (!tryExternal || !DoItemAlwaysStart(name));
UString fullVirtPath = _currentFolderPrefix + relPath;
const UString fullVirtPath = _currentFolderPrefix + relPath;
CTempDir tempDirectory;
if (!tempDirectory.Create(kTempDirPrefix))
@@ -1058,6 +1083,8 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
// probably we must show some message here
// return;
}
if (!tryExternal)
return;
}
}
}
@@ -1126,6 +1153,7 @@ void CPanel::OpenItemInArchive(int index, bool tryInternal, bool tryExternal, bo
options.folder = fs2us(tempDirNorm);
options.showErrorMessages = true;
HRESULT result = CopyTo(options, indices, &messages, usePassword, password);
if (_parentFolders.Size() > 0)

View File

@@ -8,13 +8,14 @@
#include "../../../Windows/Control/Static.h"
#include "../../../Windows/ErrorMsg.h"
#include "ProgressDialog2.h"
#include "DialogSize.h"
#include "ProgressDialog2Res.h"
#include "../GUI/ExtractRes.h"
#include "LangUtils.h"
#include "DialogSize.h"
#include "ProgressDialog2.h"
#include "ProgressDialog2Res.h"
using namespace NWindows;
extern HINSTANCE g_hInstance;
@@ -42,8 +43,6 @@ static const UINT kCreateDelay =
static const DWORD kPauseSleepTime = 100;
#include "LangUtils.h"
#ifdef LANG
static const UInt32 kLangIDs[] =
@@ -705,10 +704,9 @@ void CProgressDialog::UpdateStatInfo(bool showAll)
UInt32 curTime = ::GetTickCount();
const UInt64 progressTotal = bytesProgressMode ? total : totalFiles;
const UInt64 progressCompleted = bytesProgressMode ? completed : completedFiles;
{
UInt64 progressTotal = bytesProgressMode ? total : totalFiles;
UInt64 progressCompleted = bytesProgressMode ? completed : completedFiles;
if (IS_UNDEFINED_VAL(progressTotal))
{
// SetPos(0);
@@ -757,9 +755,9 @@ void CProgressDialog::UpdateStatInfo(bool showAll)
}
}
if (completed != 0)
if (progressCompleted != 0)
{
if (IS_UNDEFINED_VAL(total))
if (IS_UNDEFINED_VAL(progressTotal))
{
if (IS_DEFINED_VAL(_prevRemainingSec))
{
@@ -770,8 +768,8 @@ void CProgressDialog::UpdateStatInfo(bool showAll)
else
{
UInt64 remainingTime = 0;
if (completed < total)
remainingTime = MyMultAndDiv(_elapsedTime, total - completed, completed);
if (progressCompleted < progressTotal)
remainingTime = MyMultAndDiv(_elapsedTime, progressTotal - progressCompleted, progressCompleted);
UInt64 remainingSec = remainingTime / 1000;
if (remainingSec != _prevRemainingSec)
{
@@ -783,7 +781,7 @@ void CProgressDialog::UpdateStatInfo(bool showAll)
}
{
UInt64 elapsedTime = (_elapsedTime == 0) ? 1 : _elapsedTime;
UInt64 v = (completed * 1000) / elapsedTime;
UInt64 v = (progressCompleted * 1000) / elapsedTime;
Byte c = 0;
unsigned moveBits = 0;
if (v >= ((UInt64)10000 << 10)) { moveBits = 20; c = 'M'; }
@@ -811,11 +809,11 @@ void CProgressDialog::UpdateStatInfo(bool showAll)
{
UInt64 percent = 0;
{
if (IS_DEFINED_VAL(total))
if (IS_DEFINED_VAL(progressTotal))
{
percent = completed * 100;
if (total != 0)
percent /= total;
percent = progressCompleted * 100;
if (progressTotal != 0)
percent /= progressTotal;
}
}
if (percent != _prevPercentValue)

View File

@@ -40,7 +40,10 @@ HRESULT PropVarEm_Set_Str(PROPVARIANT *p, const char *s) throw()
{
p->bstrVal = AllocBstrFromAscii(s);
if (p->bstrVal)
{
p->vt = VT_BSTR;
return S_OK;
}
p->vt = VT_ERROR;
p->scode = E_OUTOFMEMORY;
return E_OUTOFMEMORY;