mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-10 20:07:05 -06:00
4.37 beta
This commit is contained in:
committed by
Kornel Lesiński
parent
8304895f29
commit
cb9eea7264
@@ -70,7 +70,7 @@ STDAPI GetHandlerProperty(PROPID propID, PROPVARIANT *value)
|
||||
propVariant = L"iso";
|
||||
break;
|
||||
case NArchive::kUpdate:
|
||||
propVariant = true;
|
||||
propVariant = false;
|
||||
break;
|
||||
case NArchive::kKeepName:
|
||||
propVariant = false;
|
||||
|
||||
@@ -128,7 +128,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
case kpidSize:
|
||||
case kpidPackedSize:
|
||||
{
|
||||
propVariant = (UInt64)be.GetSize();
|
||||
propVariant = (UInt64)_archive.GetBootItemSize(index);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -146,7 +146,7 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
if (_archive.IsJoliet())
|
||||
s = item.GetPathU();
|
||||
else
|
||||
s = MultiByteToUnicodeString(item.GetPath(), CP_OEMCP);
|
||||
s = MultiByteToUnicodeString(item.GetPath(_archive.IsSusp, _archive.SuspSkipSize), CP_OEMCP);
|
||||
|
||||
int pos = s.ReverseFind(L';');
|
||||
if (pos >= 0 && pos == s.Length() - 2)
|
||||
@@ -210,8 +210,7 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
}
|
||||
else
|
||||
{
|
||||
const CBootInitialEntry &be = _archive.BootEntries[index - _archive.Refs.Size()];
|
||||
totalSize += be.GetSize();
|
||||
totalSize += _archive.GetBootItemSize(index - _archive.Refs.Size());
|
||||
}
|
||||
}
|
||||
extractCallback->SetTotal(totalSize);
|
||||
@@ -248,8 +247,9 @@ STDMETHODIMP CHandler::Extract(const UInt32* indices, UInt32 numItems,
|
||||
}
|
||||
else
|
||||
{
|
||||
const CBootInitialEntry &be = _archive.BootEntries[index - _archive.Refs.Size()];
|
||||
currentItemSize = be.GetSize();
|
||||
int bootIndex = index - _archive.Refs.Size();
|
||||
const CBootInitialEntry &be = _archive.BootEntries[bootIndex];
|
||||
currentItemSize = _archive.GetBootItemSize(bootIndex);
|
||||
blockIndex = be.LoadRBA;
|
||||
}
|
||||
|
||||
|
||||
@@ -253,6 +253,7 @@ void CInArchive::ReadDir(CDir &d, int level)
|
||||
SeekToBlock(d.ExtentLocation);
|
||||
UInt64 startPos = _position;
|
||||
|
||||
bool firstItem = true;
|
||||
while(true)
|
||||
{
|
||||
UInt64 offset = _position - startPos;
|
||||
@@ -263,8 +264,13 @@ void CInArchive::ReadDir(CDir &d, int level)
|
||||
continue;
|
||||
CDir subItem;
|
||||
ReadDirRecord2(subItem, len);
|
||||
if (firstItem && level == 0)
|
||||
IsSusp = subItem.CheckSusp(SuspSkipSize);
|
||||
|
||||
if (!subItem.IsSystemItem())
|
||||
d._subItems.Add(subItem);
|
||||
|
||||
firstItem = false;
|
||||
}
|
||||
for (int i = 0; i < d._subItems.Size(); i++)
|
||||
ReadDir(d._subItems[i], level + 1);
|
||||
@@ -404,6 +410,10 @@ HRESULT CInArchive::Open2()
|
||||
HRESULT CInArchive::Open(IInStream *inStream)
|
||||
{
|
||||
_stream = inStream;
|
||||
UInt64 pos;
|
||||
RINOK(_stream->Seek(0, STREAM_SEEK_CUR, &pos));
|
||||
RINOK(_stream->Seek(0, STREAM_SEEK_END, &_archiveSize));
|
||||
RINOK(_stream->Seek(pos, STREAM_SEEK_SET, &_position));
|
||||
HRESULT res = S_FALSE;
|
||||
try { res = Open2(); }
|
||||
catch(...) { Clear(); res = S_FALSE; }
|
||||
@@ -418,6 +428,8 @@ void CInArchive::Clear()
|
||||
VolDescs.Clear();
|
||||
_bootIsDefined = false;
|
||||
BootEntries.Clear();
|
||||
SuspSkipSize = 0;
|
||||
IsSusp = false;
|
||||
}
|
||||
|
||||
}}
|
||||
|
||||
@@ -25,12 +25,12 @@ struct CDir: public CDirRecord
|
||||
_subItems.Clear();
|
||||
}
|
||||
|
||||
int GetLength() const
|
||||
int GetLength(bool checkSusp, int skipSize) const
|
||||
{
|
||||
int len = FileId.GetCapacity();
|
||||
int len = GetLengthCur(checkSusp, skipSize);
|
||||
if (Parent != 0)
|
||||
if (Parent->Parent != 0)
|
||||
len += 1 + Parent->GetLength();
|
||||
len += 1 + Parent->GetLength(checkSusp, skipSize);
|
||||
return len;
|
||||
}
|
||||
|
||||
@@ -43,19 +43,19 @@ struct CDir: public CDirRecord
|
||||
return len;
|
||||
}
|
||||
|
||||
AString GetPath() const
|
||||
AString GetPath(bool checkSusp, int skipSize) const
|
||||
{
|
||||
AString s;
|
||||
int len = GetLength();
|
||||
int len = GetLength(checkSusp, skipSize);
|
||||
char *p = s.GetBuffer(len + 1);
|
||||
p += len;
|
||||
*p = 0;
|
||||
const CDir *cur = this;
|
||||
while(true)
|
||||
{
|
||||
int curLen = cur->FileId.GetCapacity();
|
||||
int curLen = cur->GetLengthCur(checkSusp, skipSize);
|
||||
p -= curLen;
|
||||
memmove(p, (const char *)(const Byte *)cur->FileId, curLen);
|
||||
memmove(p, (const char *)(const Byte *)cur->GetNameCur(checkSusp, skipSize), curLen);
|
||||
cur = cur->Parent;
|
||||
if (cur == 0)
|
||||
break;
|
||||
@@ -262,13 +262,38 @@ public:
|
||||
HRESULT Open(IInStream *inStream);
|
||||
void Clear();
|
||||
|
||||
CObjectVector<CRef> Refs;
|
||||
UInt64 _archiveSize;
|
||||
|
||||
CRecordVector<CRef> Refs;
|
||||
CObjectVector<CVolumeDescriptor> VolDescs;
|
||||
int MainVolDescIndex;
|
||||
UInt32 BlockSize;
|
||||
CObjectVector<CBootInitialEntry> BootEntries;
|
||||
|
||||
|
||||
bool IsJoliet() const { return VolDescs[MainVolDescIndex].IsJoliet(); }
|
||||
|
||||
UInt64 GetBootItemSize(int index) const
|
||||
{
|
||||
const CBootInitialEntry &be = BootEntries[index];
|
||||
UInt64 size = be.GetSize();
|
||||
if (be.BootMediaType == NBootMediaType::k1d2Floppy)
|
||||
size = (1200 << 10);
|
||||
else if (be.BootMediaType == NBootMediaType::k1d44Floppy)
|
||||
size = (1440 << 10);
|
||||
else if (be.BootMediaType == NBootMediaType::k2d88Floppy)
|
||||
size = (2880 << 10);
|
||||
UInt64 startPos = be.LoadRBA * BlockSize;
|
||||
if (startPos < _archiveSize)
|
||||
{
|
||||
if (_archiveSize - startPos < size)
|
||||
size = _archiveSize - startPos;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
bool IsSusp;
|
||||
int SuspSkipSize;
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
@@ -64,6 +64,80 @@ struct CDirRecord
|
||||
Byte b = *(const Byte *)FileId;
|
||||
return (b == 0 || b == 1);
|
||||
}
|
||||
|
||||
const Byte* FindSuspName(int skipSize, int &lenRes) const
|
||||
{
|
||||
lenRes = 0;
|
||||
const Byte *p = (const Byte *)SystemUse + skipSize;
|
||||
int length = SystemUse.GetCapacity() - skipSize;
|
||||
while (length >= 5)
|
||||
{
|
||||
int len = p[2];
|
||||
if (p[0] == 'N' && p[1] == 'M' && p[3] == 1)
|
||||
{
|
||||
lenRes = len - 5;
|
||||
return p + 5;
|
||||
}
|
||||
p += len;
|
||||
length -= len;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int GetLengthCur(bool checkSusp, int skipSize) const
|
||||
{
|
||||
if (checkSusp)
|
||||
{
|
||||
int len;
|
||||
const Byte *res = FindSuspName(skipSize, len);
|
||||
if (res != 0)
|
||||
return len;
|
||||
}
|
||||
return FileId.GetCapacity();
|
||||
}
|
||||
|
||||
const Byte* GetNameCur(bool checkSusp, int skipSize) const
|
||||
{
|
||||
if (checkSusp)
|
||||
{
|
||||
int len;
|
||||
const Byte *res = FindSuspName(skipSize, len);
|
||||
if (res != 0)
|
||||
return res;
|
||||
}
|
||||
return (const Byte *)FileId;
|
||||
}
|
||||
|
||||
|
||||
bool CheckSusp(const Byte *p, int &startPos) const
|
||||
{
|
||||
if (p[0] == 'S' &&
|
||||
p[1] == 'P' &&
|
||||
p[2] == 0x7 &&
|
||||
p[3] == 0x1 &&
|
||||
p[4] == 0xBE &&
|
||||
p[5] == 0xEF)
|
||||
{
|
||||
startPos = p[6];
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CheckSusp(int &startPos) const
|
||||
{
|
||||
const Byte *p = (const Byte *)SystemUse;
|
||||
int length = SystemUse.GetCapacity();
|
||||
const int kMinLen = 7;
|
||||
if (length < kMinLen)
|
||||
return false;
|
||||
if (CheckSusp(p, startPos))
|
||||
return true;
|
||||
const int kOffset2 = 14;
|
||||
if (length < kOffset2 + kMinLen)
|
||||
return false;
|
||||
return CheckSusp(p + kOffset2, startPos);
|
||||
}
|
||||
};
|
||||
|
||||
}}
|
||||
|
||||
Reference in New Issue
Block a user