mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-07 09:15:00 -06:00
9.34
This commit is contained in:
committed by
Kornel Lesiński
parent
83f8ddcc5b
commit
f08f4dcc3c
452
CPP/7zip/Archive/Cab/CabIn.cpp
Executable file → Normal file
452
CPP/7zip/Archive/Cab/CabIn.cpp
Executable file → Normal file
@@ -2,154 +2,353 @@
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "../Common/FindSignature.h"
|
||||
// #include <stdio.h>
|
||||
|
||||
#include "../../../../C/CpuArch.h"
|
||||
|
||||
#include "../../Common/LimitedStreams.h"
|
||||
#include "../../Common/StreamUtils.h"
|
||||
|
||||
#include "CabIn.h"
|
||||
|
||||
#define Get16(p) GetUi16(p)
|
||||
#define Get32(p) GetUi32(p)
|
||||
|
||||
namespace NArchive {
|
||||
namespace NCab {
|
||||
|
||||
Byte CInArchive::Read8()
|
||||
struct CUnexpectedEndException {};
|
||||
|
||||
void CInArchive::Skip(unsigned size)
|
||||
{
|
||||
Byte b;
|
||||
if (!inBuffer.ReadByte(b))
|
||||
throw CInArchiveException(CInArchiveException::kUnsupported);
|
||||
return b;
|
||||
if (_inBuffer.Skip(size) != size)
|
||||
throw CUnexpectedEndException();
|
||||
}
|
||||
|
||||
UInt16 CInArchive::Read16()
|
||||
void CInArchive::Read(Byte *data, unsigned size)
|
||||
{
|
||||
UInt16 value = 0;
|
||||
for (int i = 0; i < 2; i++)
|
||||
if (_inBuffer.ReadBytes(data, size) != size)
|
||||
throw CUnexpectedEndException();
|
||||
}
|
||||
|
||||
void CInArchive::ReadName(AString &s)
|
||||
{
|
||||
for (size_t i = 0; i < ((size_t)1 << 13); i++)
|
||||
{
|
||||
Byte b = Read8();
|
||||
value |= (UInt16(b) << (8 * i));
|
||||
Byte b;
|
||||
if (!_inBuffer.ReadByte(b))
|
||||
throw CUnexpectedEndException();
|
||||
if (b == 0)
|
||||
{
|
||||
memcpy(s.GetBuffer((unsigned)i), _tempBuf, i);
|
||||
s.ReleaseBuffer((unsigned)i);
|
||||
return;
|
||||
}
|
||||
if (_tempBuf.Size() == i)
|
||||
_tempBuf.ChangeSize_KeepData(i * 2, i);
|
||||
_tempBuf[i] = b;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
UInt32 CInArchive::Read32()
|
||||
{
|
||||
UInt32 value = 0;
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
Byte b = Read8();
|
||||
value |= (UInt32(b) << (8 * i));
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
AString CInArchive::SafeReadName()
|
||||
{
|
||||
AString name;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
Byte b = Read8();
|
||||
Byte b;
|
||||
if (!_inBuffer.ReadByte(b))
|
||||
throw CUnexpectedEndException();
|
||||
if (b == 0)
|
||||
return name;
|
||||
name += (char)b;
|
||||
break;
|
||||
}
|
||||
|
||||
ErrorInNames = true;
|
||||
s = "[ERROR-LONG-PATH]";
|
||||
}
|
||||
|
||||
void CInArchive::ReadOtherArc(COtherArc &oa)
|
||||
{
|
||||
ReadName(oa.FileName);
|
||||
ReadName(oa.DiskName);
|
||||
}
|
||||
|
||||
struct CSignatureFinder
|
||||
{
|
||||
Byte *Buf;
|
||||
UInt32 Pos;
|
||||
UInt32 End;
|
||||
const Byte *Signature;
|
||||
UInt32 SignatureSize;
|
||||
|
||||
UInt32 _HeaderSize;
|
||||
UInt32 _AlignSize;
|
||||
UInt32 _BufUseCapacity;
|
||||
|
||||
ISequentialInStream *Stream;
|
||||
UInt64 Processed; // Global offset of start of Buf
|
||||
|
||||
const UInt64 *SearchLimit;
|
||||
|
||||
UInt32 GetTotalCapacity(UInt32 basicSize, UInt32 headerSize)
|
||||
{
|
||||
_HeaderSize = headerSize;
|
||||
for (_AlignSize = (1 << 5); _AlignSize < _HeaderSize; _AlignSize <<= 1);
|
||||
_BufUseCapacity = basicSize + _AlignSize;
|
||||
return _BufUseCapacity + 16;
|
||||
}
|
||||
|
||||
/*
|
||||
returns:
|
||||
S_OK - signature found (at Pos)
|
||||
S_FALSE - signature not found
|
||||
*/
|
||||
HRESULT Find();
|
||||
};
|
||||
|
||||
HRESULT CSignatureFinder::Find()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
Buf[End] = Signature[0]; // it's for fast search;
|
||||
|
||||
while (End - Pos >= _HeaderSize)
|
||||
{
|
||||
const Byte *p = Buf + Pos;
|
||||
Byte b = Signature[0];
|
||||
for (;;)
|
||||
{
|
||||
if (*p == b) break; p++;
|
||||
if (*p == b) break; p++;
|
||||
}
|
||||
Pos = (UInt32)(p - Buf);
|
||||
if (End - Pos < _HeaderSize)
|
||||
{
|
||||
Pos = End - _HeaderSize + 1;
|
||||
break;
|
||||
}
|
||||
UInt32 i;
|
||||
for (i = 1; i < SignatureSize && p[i] == Signature[i]; i++);
|
||||
if (i == SignatureSize)
|
||||
return S_OK;
|
||||
Pos++;
|
||||
}
|
||||
|
||||
if (Pos >= _AlignSize)
|
||||
{
|
||||
UInt32 num = (Pos & ~(_AlignSize - 1));
|
||||
Processed += num;
|
||||
Pos -= num;
|
||||
End -= num;
|
||||
memmove(Buf, Buf + num, End);
|
||||
}
|
||||
UInt32 rem = _BufUseCapacity - End;
|
||||
if (SearchLimit)
|
||||
{
|
||||
if (Processed + Pos > *SearchLimit)
|
||||
return S_FALSE;
|
||||
UInt64 rem2 = *SearchLimit - (Processed + End) + _HeaderSize;
|
||||
if (rem > rem2)
|
||||
rem = (UInt32)rem2;
|
||||
}
|
||||
|
||||
UInt32 processedSize;
|
||||
if (Processed == 0 && rem == _BufUseCapacity - _HeaderSize)
|
||||
rem -= _AlignSize; // to make reads more aligned.
|
||||
RINOK(Stream->Read(Buf + End, rem, &processedSize));
|
||||
if (processedSize == 0)
|
||||
return S_FALSE;
|
||||
End += processedSize;
|
||||
}
|
||||
}
|
||||
|
||||
void CInArchive::ReadOtherArchive(COtherArchive &oa)
|
||||
bool CInArcInfo::Parse(const Byte *p)
|
||||
{
|
||||
oa.FileName = SafeReadName();
|
||||
oa.DiskName = SafeReadName();
|
||||
if (Get32(p + 0x0C) != 0 ||
|
||||
Get32(p + 0x14) != 0)
|
||||
return false;
|
||||
Size = Get32(p + 8);
|
||||
if (Size < 36)
|
||||
return false;
|
||||
Flags = Get16(p + 0x1E);
|
||||
if (Flags > 7)
|
||||
return false;
|
||||
FileHeadersOffset = Get32(p + 0x10);
|
||||
if (FileHeadersOffset != 0 && FileHeadersOffset > Size)
|
||||
return false;
|
||||
VersionMinor = p[0x18];
|
||||
VersionMajor = p[0x19];
|
||||
NumFolders = Get16(p + 0x1A);
|
||||
NumFiles = Get16(p + 0x1C);
|
||||
return true;
|
||||
}
|
||||
|
||||
void CInArchive::Skip(UInt32 size)
|
||||
|
||||
HRESULT CInArchive::Open2(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
|
||||
{
|
||||
while (size-- != 0)
|
||||
Read8();
|
||||
}
|
||||
IsArc = false;
|
||||
ErrorInNames = false;
|
||||
UnexpectedEnd = false;
|
||||
HeaderError = false;
|
||||
|
||||
HRESULT CInArchive::Open(const UInt64 *searchHeaderSizeLimit, CDatabaseEx &db)
|
||||
{
|
||||
IInStream *stream = db.Stream;
|
||||
db.Clear();
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_SET, &db.StartPosition));
|
||||
RINOK(db.Stream->Seek(0, STREAM_SEEK_CUR, &db.StartPosition));
|
||||
// UInt64 temp = db.StartPosition;
|
||||
|
||||
RINOK(FindSignatureInStream(stream, NHeader::kMarker, NHeader::kMarkerSize,
|
||||
searchHeaderSizeLimit, db.StartPosition));
|
||||
CByteBuffer buffer;
|
||||
CInArcInfo &ai = db.ArcInfo;
|
||||
UInt64 startInBuf = 0;
|
||||
|
||||
RINOK(stream->Seek(db.StartPosition + NHeader::kMarkerSize, STREAM_SEEK_SET, NULL));
|
||||
if (!inBuffer.Create(1 << 17))
|
||||
return E_OUTOFMEMORY;
|
||||
inBuffer.SetStream(stream);
|
||||
inBuffer.Init();
|
||||
CLimitedSequentialInStream *limitedStreamSpec = NULL;
|
||||
CMyComPtr<ISequentialInStream> limitedStream;
|
||||
|
||||
CInArchiveInfo &ai = db.ArchiveInfo;
|
||||
// for (int iii = 0; iii < 10000; iii++)
|
||||
{
|
||||
// db.StartPosition = temp; RINOK(db.Stream->Seek(db.StartPosition, STREAM_SEEK_SET, NULL));
|
||||
|
||||
const UInt32 kMainHeaderSize = 32;
|
||||
Byte header[kMainHeaderSize];
|
||||
const UInt32 kBufSize = 1 << 15;
|
||||
RINOK(ReadStream_FALSE(db.Stream, header, kMainHeaderSize));
|
||||
if (memcmp(header, NHeader::kMarker, NHeader::kMarkerSize) == 0 && ai.Parse(header))
|
||||
{
|
||||
limitedStreamSpec = new CLimitedSequentialInStream;
|
||||
limitedStream = limitedStreamSpec;
|
||||
limitedStreamSpec->SetStream(db.Stream);
|
||||
limitedStreamSpec->Init(ai.Size - NHeader::kMarkerSize);
|
||||
buffer.Alloc(kBufSize);
|
||||
memcpy(buffer, header, kMainHeaderSize);
|
||||
UInt32 numProcessedBytes;
|
||||
RINOK(limitedStream->Read(buffer + kMainHeaderSize, kBufSize - kMainHeaderSize, &numProcessedBytes));
|
||||
_inBuffer.SetBuf(buffer, (UInt32)kBufSize, kMainHeaderSize + numProcessedBytes, kMainHeaderSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (searchHeaderSizeLimit && *searchHeaderSizeLimit == 0)
|
||||
return S_FALSE;
|
||||
|
||||
ai.Size = Read32();
|
||||
if (Read32() != 0)
|
||||
return S_FALSE;
|
||||
ai.FileHeadersOffset = Read32();
|
||||
if (Read32() != 0)
|
||||
return S_FALSE;
|
||||
CSignatureFinder finder;
|
||||
|
||||
ai.VersionMinor = Read8();
|
||||
ai.VersionMajor = Read8();
|
||||
ai.NumFolders = Read16();
|
||||
ai.NumFiles = Read16();
|
||||
ai.Flags = Read16();
|
||||
if (ai.Flags > 7)
|
||||
return S_FALSE;
|
||||
ai.SetID = Read16();
|
||||
ai.CabinetNumber = Read16();
|
||||
finder.Stream = db.Stream;
|
||||
finder.Signature = NHeader::kMarker;
|
||||
finder.SignatureSize = NHeader::kMarkerSize;
|
||||
finder.SearchLimit = searchHeaderSizeLimit;
|
||||
|
||||
buffer.Alloc(finder.GetTotalCapacity(kBufSize, kMainHeaderSize));
|
||||
finder.Buf = buffer;
|
||||
|
||||
memcpy(buffer, header, kMainHeaderSize);
|
||||
finder.Processed = db.StartPosition;
|
||||
finder.End = kMainHeaderSize;
|
||||
finder.Pos = 1;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
RINOK(finder.Find());
|
||||
if (ai.Parse(finder.Buf + finder.Pos))
|
||||
{
|
||||
db.StartPosition = finder.Processed + finder.Pos;
|
||||
limitedStreamSpec = new CLimitedSequentialInStream;
|
||||
limitedStreamSpec->SetStream(db.Stream);
|
||||
limitedStream = limitedStreamSpec;
|
||||
UInt32 remInFinder = finder.End - finder.Pos;
|
||||
if (ai.Size <= remInFinder)
|
||||
{
|
||||
limitedStreamSpec->Init(0);
|
||||
finder.End = finder.Pos + ai.Size;
|
||||
}
|
||||
else
|
||||
limitedStreamSpec->Init(ai.Size - remInFinder);
|
||||
|
||||
startInBuf = finder.Pos;
|
||||
_inBuffer.SetBuf(buffer, (UInt32)kBufSize, finder.End, finder.Pos + kMainHeaderSize);
|
||||
break;
|
||||
}
|
||||
finder.Pos++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IsArc = true;
|
||||
|
||||
_inBuffer.SetStream(limitedStream);
|
||||
if (_tempBuf.Size() == 0)
|
||||
_tempBuf.Alloc(1 << 12);
|
||||
|
||||
Byte p[16];
|
||||
unsigned nextSize = 4 + (ai.ReserveBlockPresent() ? 4 : 0);
|
||||
Read(p, nextSize);
|
||||
ai.SetID = Get16(p);
|
||||
ai.CabinetNumber = Get16(p + 2);
|
||||
|
||||
if (ai.ReserveBlockPresent())
|
||||
{
|
||||
ai.PerCabinetAreaSize = Read16();
|
||||
ai.PerFolderAreaSize = Read8();
|
||||
ai.PerDataBlockAreaSize = Read8();
|
||||
|
||||
Skip(ai.PerCabinetAreaSize);
|
||||
ai.PerCabinet_AreaSize = Get16(p + 4);
|
||||
ai.PerFolder_AreaSize = p[6];
|
||||
ai.PerDataBlock_AreaSize = p[7];
|
||||
Skip(ai.PerCabinet_AreaSize);
|
||||
}
|
||||
|
||||
{
|
||||
if (ai.IsTherePrev())
|
||||
ReadOtherArchive(ai.PrevArc);
|
||||
if (ai.IsThereNext())
|
||||
ReadOtherArchive(ai.NextArc);
|
||||
}
|
||||
if (ai.IsTherePrev()) ReadOtherArc(ai.PrevArc);
|
||||
if (ai.IsThereNext()) ReadOtherArc(ai.NextArc);
|
||||
|
||||
int i;
|
||||
UInt32 i;
|
||||
db.Folders.ClearAndReserve(ai.NumFolders);
|
||||
for (i = 0; i < ai.NumFolders; i++)
|
||||
{
|
||||
Read(p, 8);
|
||||
CFolder folder;
|
||||
|
||||
folder.DataStart = Read32();
|
||||
folder.NumDataBlocks = Read16();
|
||||
folder.CompressionTypeMajor = Read8();
|
||||
folder.CompressionTypeMinor = Read8();
|
||||
|
||||
Skip(ai.PerFolderAreaSize);
|
||||
db.Folders.Add(folder);
|
||||
folder.DataStart = Get32(p);
|
||||
folder.NumDataBlocks = Get16(p + 4);
|
||||
folder.MethodMajor = p[6];
|
||||
folder.MethodMinor = p[7];
|
||||
Skip(ai.PerFolder_AreaSize);
|
||||
db.Folders.AddInReserved(folder);
|
||||
}
|
||||
|
||||
RINOK(stream->Seek(db.StartPosition + ai.FileHeadersOffset, STREAM_SEEK_SET, NULL));
|
||||
// for (int iii = 0; iii < 10000; iii++) {
|
||||
|
||||
inBuffer.SetStream(stream);
|
||||
inBuffer.Init();
|
||||
if (_inBuffer.GetProcessedSize() - startInBuf != ai.FileHeadersOffset)
|
||||
{
|
||||
// printf("\n!!! Seek Error !!!!\n");
|
||||
// fflush(stdout);
|
||||
RINOK(db.Stream->Seek(db.StartPosition + ai.FileHeadersOffset, STREAM_SEEK_SET, NULL));
|
||||
limitedStreamSpec->Init(ai.Size - ai.FileHeadersOffset);
|
||||
_inBuffer.Init();
|
||||
}
|
||||
|
||||
db.Items.ClearAndReserve(ai.NumFiles);
|
||||
for (i = 0; i < ai.NumFiles; i++)
|
||||
{
|
||||
CItem item;
|
||||
item.Size = Read32();
|
||||
item.Offset = Read32();
|
||||
item.FolderIndex = Read16();
|
||||
UInt16 pureDate = Read16();
|
||||
UInt16 pureTime = Read16();
|
||||
item.Time = ((UInt32(pureDate) << 16)) | pureTime;
|
||||
item.Attributes = Read16();
|
||||
item.Name = SafeReadName();
|
||||
int folderIndex = item.GetFolderIndex(db.Folders.Size());
|
||||
if (folderIndex >= db.Folders.Size())
|
||||
Read(p, 16);
|
||||
CItem &item = db.Items.AddNewInReserved();
|
||||
item.Size = Get32(p);
|
||||
item.Offset = Get32(p + 4);
|
||||
item.FolderIndex = Get16(p + 8);
|
||||
UInt16 pureDate = Get16(p + 10);
|
||||
UInt16 pureTime = Get16(p + 12);
|
||||
item.Time = (((UInt32)pureDate << 16)) | pureTime;
|
||||
item.Attributes = Get16(p + 14);
|
||||
|
||||
ReadName(item.Name);
|
||||
if (item.GetFolderIndex(db.Folders.Size()) >= (int)db.Folders.Size())
|
||||
{
|
||||
HeaderError = true;
|
||||
return S_FALSE;
|
||||
db.Items.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
// }
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CInArchive::Open(CDatabaseEx &db, const UInt64 *searchHeaderSizeLimit)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Open2(db, searchHeaderSizeLimit);
|
||||
}
|
||||
catch(const CInBufferException &e) { return e.ErrorCode; }
|
||||
catch(CUnexpectedEndException &) { UnexpectedEnd = true; return S_FALSE; }
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define RINOZ(x) { int __tt = (x); if (__tt != 0) return __tt; }
|
||||
|
||||
static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param)
|
||||
@@ -161,10 +360,8 @@ static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param)
|
||||
const CItem &item2 = db2.Items[p2->ItemIndex];;
|
||||
bool isDir1 = item1.IsDir();
|
||||
bool isDir2 = item2.IsDir();
|
||||
if (isDir1 && !isDir2)
|
||||
return -1;
|
||||
if (isDir2 && !isDir1)
|
||||
return 1;
|
||||
if (isDir1 && !isDir2) return -1;
|
||||
if (isDir2 && !isDir1) return 1;
|
||||
int f1 = mvDb.GetFolderIndex(p1);
|
||||
int f2 = mvDb.GetFolderIndex(p2);
|
||||
RINOZ(MyCompare(f1, f2));
|
||||
@@ -174,7 +371,7 @@ static int CompareMvItems(const CMvItem *p1, const CMvItem *p2, void *param)
|
||||
return MyCompare(p1->ItemIndex, p2->ItemIndex);
|
||||
}
|
||||
|
||||
bool CMvDatabaseEx::AreItemsEqual(int i1, int i2)
|
||||
bool CMvDatabaseEx::AreItemsEqual(unsigned i1, unsigned i2)
|
||||
{
|
||||
const CMvItem *p1 = &Items[i1];
|
||||
const CMvItem *p2 = &Items[i2];
|
||||
@@ -182,10 +379,10 @@ bool CMvDatabaseEx::AreItemsEqual(int i1, int i2)
|
||||
const CDatabaseEx &db2 = Volumes[p2->VolumeIndex];
|
||||
const CItem &item1 = db1.Items[p1->ItemIndex];
|
||||
const CItem &item2 = db2.Items[p2->ItemIndex];;
|
||||
return GetFolderIndex(p1) == GetFolderIndex(p2) &&
|
||||
item1.Offset == item2.Offset &&
|
||||
item1.Size == item2.Size &&
|
||||
item1.Name == item2.Name;
|
||||
return GetFolderIndex(p1) == GetFolderIndex(p2)
|
||||
&& item1.Offset == item2.Offset
|
||||
&& item1.Size == item2.Size
|
||||
&& item1.Name == item2.Name;
|
||||
}
|
||||
|
||||
void CMvDatabaseEx::FillSortAndShrink()
|
||||
@@ -194,7 +391,7 @@ void CMvDatabaseEx::FillSortAndShrink()
|
||||
StartFolderOfVol.Clear();
|
||||
FolderStartFileIndex.Clear();
|
||||
int offset = 0;
|
||||
for (int v = 0; v < Volumes.Size(); v++)
|
||||
FOR_VECTOR (v, Volumes)
|
||||
{
|
||||
const CDatabaseEx &db = Volumes[v];
|
||||
int curOffset = offset;
|
||||
@@ -205,32 +402,35 @@ void CMvDatabaseEx::FillSortAndShrink()
|
||||
|
||||
CMvItem mvItem;
|
||||
mvItem.VolumeIndex = v;
|
||||
for (int i = 0 ; i < db.Items.Size(); i++)
|
||||
FOR_VECTOR (i, db.Items)
|
||||
{
|
||||
mvItem.ItemIndex = i;
|
||||
Items.Add(mvItem);
|
||||
}
|
||||
}
|
||||
|
||||
Items.Sort(CompareMvItems, (void *)this);
|
||||
int j = 1;
|
||||
int i;
|
||||
for (i = 1; i < Items.Size(); i++)
|
||||
if (!AreItemsEqual(i, i -1))
|
||||
Items[j++] = Items[i];
|
||||
Items.DeleteFrom(j);
|
||||
if (Items.Size() > 1)
|
||||
{
|
||||
Items.Sort(CompareMvItems, (void *)this);
|
||||
unsigned j = 1;
|
||||
unsigned i = 1;
|
||||
for (; i < Items.Size(); i++)
|
||||
if (!AreItemsEqual(i, i - 1))
|
||||
Items[j++] = Items[i];
|
||||
Items.DeleteFrom(j);
|
||||
}
|
||||
|
||||
for (i = 0; i < Items.Size(); i++)
|
||||
FOR_VECTOR (i, Items)
|
||||
{
|
||||
int folderIndex = GetFolderIndex(&Items[i]);
|
||||
if (folderIndex >= FolderStartFileIndex.Size())
|
||||
if (folderIndex >= (int)FolderStartFileIndex.Size())
|
||||
FolderStartFileIndex.Add(i);
|
||||
}
|
||||
}
|
||||
|
||||
bool CMvDatabaseEx::Check()
|
||||
{
|
||||
for (int v = 1; v < Volumes.Size(); v++)
|
||||
for (unsigned v = 1; v < Volumes.Size(); v++)
|
||||
{
|
||||
const CDatabaseEx &db1 = Volumes[v];
|
||||
if (db1.IsTherePrevFolder())
|
||||
@@ -240,19 +440,19 @@ bool CMvDatabaseEx::Check()
|
||||
return false;
|
||||
const CFolder &f0 = db0.Folders.Back();
|
||||
const CFolder &f1 = db1.Folders.Front();
|
||||
if (f0.CompressionTypeMajor != f1.CompressionTypeMajor ||
|
||||
f0.CompressionTypeMinor != f1.CompressionTypeMinor)
|
||||
if (f0.MethodMajor != f1.MethodMajor ||
|
||||
f0.MethodMinor != f1.MethodMinor)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
UInt32 beginPos = 0;
|
||||
UInt64 endPos = 0;
|
||||
int prevFolder = -2;
|
||||
for (int i = 0; i < Items.Size(); i++)
|
||||
FOR_VECTOR (i, Items)
|
||||
{
|
||||
const CMvItem &mvItem = Items[i];
|
||||
int fIndex = GetFolderIndex(&mvItem);
|
||||
if (fIndex >= FolderStartFileIndex.Size())
|
||||
if (fIndex >= (int)FolderStartFileIndex.Size())
|
||||
return false;
|
||||
const CItem &item = Volumes[mvItem.VolumeIndex].Items[mvItem.ItemIndex];
|
||||
if (item.IsDir())
|
||||
|
||||
Reference in New Issue
Block a user