mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-15 16:11:40 -06:00
Update to 7-Zip Version 22.00
See: https://sourceforge.net/p/sevenzip/discussion/45797/thread/9c2d9061ce/
This commit is contained in:
@@ -36,22 +36,34 @@ static const Byte kProps[] =
|
||||
kpidSize,
|
||||
kpidPackSize,
|
||||
kpidMTime,
|
||||
kpidCTime,
|
||||
kpidATime,
|
||||
kpidPosixAttrib,
|
||||
kpidUser,
|
||||
kpidGroup,
|
||||
kpidUserId,
|
||||
kpidGroupId,
|
||||
kpidSymLink,
|
||||
kpidHardLink,
|
||||
kpidCharacts
|
||||
// kpidLinkType
|
||||
kpidCharacts,
|
||||
kpidComment
|
||||
, kpidDeviceMajor
|
||||
, kpidDeviceMinor
|
||||
// , kpidDevice
|
||||
// , kpidHeadersSize // for debug
|
||||
// , kpidOffset // for debug
|
||||
};
|
||||
|
||||
static const Byte kArcProps[] =
|
||||
{
|
||||
kpidHeadersSize,
|
||||
kpidCodePage,
|
||||
kpidCharacts
|
||||
kpidCharacts,
|
||||
kpidComment
|
||||
};
|
||||
|
||||
static const char *k_Characts_Prefix = "PREFIX";
|
||||
|
||||
IMP_IInArchive_Props
|
||||
IMP_IInArchive_ArcProps
|
||||
|
||||
@@ -60,14 +72,14 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
NCOM::CPropVariant prop;
|
||||
switch (propID)
|
||||
{
|
||||
case kpidPhySize: if (_phySizeDefined) prop = _phySize; break;
|
||||
case kpidHeadersSize: if (_phySizeDefined) prop = _headersSize; break;
|
||||
case kpidPhySize: if (_arc._phySize_Defined) prop = _arc._phySize; break;
|
||||
case kpidHeadersSize: if (_arc._phySize_Defined) prop = _arc._headersSize; break;
|
||||
case kpidErrorFlags:
|
||||
{
|
||||
UInt32 flags = 0;
|
||||
if (!_isArc)
|
||||
flags |= kpv_ErrorFlags_IsNotArc;
|
||||
else switch (_error)
|
||||
else switch (_arc._error)
|
||||
{
|
||||
case k_ErrorType_UnexpectedEnd: flags = kpv_ErrorFlags_UnexpectedEnd; break;
|
||||
case k_ErrorType_Corrupted: flags = kpv_ErrorFlags_HeadersError; break;
|
||||
@@ -82,7 +94,7 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
|
||||
case kpidWarningFlags:
|
||||
{
|
||||
if (_warning)
|
||||
if (_arc._is_Warning)
|
||||
prop = kpv_ErrorFlags_HeadersError;
|
||||
break;
|
||||
}
|
||||
@@ -107,7 +119,34 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
|
||||
case kpidCharacts:
|
||||
{
|
||||
prop = _encodingCharacts.GetCharactsString();
|
||||
AString s;
|
||||
if (_arc._are_Gnu) s.Add_OptSpaced("GNU");
|
||||
if (_arc._are_Posix) s.Add_OptSpaced("POSIX");
|
||||
if (_arc._are_Pax_Items) s.Add_OptSpaced("PAX_ITEM");
|
||||
if (_arc._pathPrefix_WasUsed) s.Add_OptSpaced(k_Characts_Prefix);
|
||||
if (_arc._are_LongName) s.Add_OptSpaced("LongName");
|
||||
if (_arc._are_LongLink) s.Add_OptSpaced("LongLink");
|
||||
if (_arc._are_Pax) s.Add_OptSpaced("PAX");
|
||||
if (_arc._are_pax_path) s.Add_OptSpaced("path");
|
||||
if (_arc._are_pax_link) s.Add_OptSpaced("linkpath");
|
||||
if (_arc._are_mtime) s.Add_OptSpaced("mtime");
|
||||
if (_arc._are_atime) s.Add_OptSpaced("atime");
|
||||
if (_arc._are_ctime) s.Add_OptSpaced("ctime");
|
||||
if (_arc._is_PaxGlobal_Error) s.Add_OptSpaced("PAX_GLOBAL_ERROR");
|
||||
s.Add_OptSpaced(_encodingCharacts.GetCharactsString());
|
||||
prop = s;
|
||||
break;
|
||||
}
|
||||
|
||||
case kpidComment:
|
||||
{
|
||||
if (_arc.PaxGlobal_Defined)
|
||||
{
|
||||
AString s;
|
||||
_arc.PaxGlobal.Print_To_String(s);
|
||||
if (!s.IsEmpty())
|
||||
prop = s;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -115,32 +154,6 @@ STDMETHODIMP CHandler::GetArchiveProperty(PROPID propID, PROPVARIANT *value)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CHandler::ReadItem2(ISequentialInStream *stream, bool &filled, CItemEx &item)
|
||||
{
|
||||
item.HeaderPos = _phySize;
|
||||
EErrorType error;
|
||||
HRESULT res = ReadItem(stream, filled, item, error);
|
||||
if (error == k_ErrorType_Warning)
|
||||
_warning = true;
|
||||
else if (error != k_ErrorType_OK)
|
||||
_error = error;
|
||||
RINOK(res);
|
||||
if (filled)
|
||||
{
|
||||
/*
|
||||
if (item.IsSparse())
|
||||
_isSparse = true;
|
||||
*/
|
||||
if (item.IsPaxExtendedHeader())
|
||||
_thereIsPaxExtendedHeader = true;
|
||||
if (item.IsThereWarning())
|
||||
_warning = true;
|
||||
}
|
||||
_phySize += item.HeaderSize;
|
||||
_headersSize += item.HeaderSize;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
void CEncodingCharacts::Check(const AString &s)
|
||||
{
|
||||
@@ -199,16 +212,20 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
|
||||
RINOK(stream->Seek(0, STREAM_SEEK_SET, NULL));
|
||||
}
|
||||
|
||||
_phySizeDefined = true;
|
||||
_arc._phySize_Defined = true;
|
||||
|
||||
// bool utf8_OK = true;
|
||||
|
||||
_arc.SeqStream = stream;
|
||||
_arc.InStream = stream;
|
||||
_arc.OpenCallback = callback;
|
||||
|
||||
CItemEx item;
|
||||
for (;;)
|
||||
{
|
||||
CItemEx item;
|
||||
bool filled;
|
||||
RINOK(ReadItem2(stream, filled, item));
|
||||
if (!filled)
|
||||
_arc.NumFiles = _items.Size();
|
||||
RINOK(_arc.ReadItem(item));
|
||||
if (!_arc.filled)
|
||||
break;
|
||||
|
||||
_isArc = true;
|
||||
@@ -228,10 +245,10 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
|
||||
|
||||
_items.Add(item);
|
||||
|
||||
RINOK(stream->Seek((Int64)item.GetPackSizeAligned(), STREAM_SEEK_CUR, &_phySize));
|
||||
if (_phySize > endPos)
|
||||
RINOK(stream->Seek((Int64)item.Get_PackSize_Aligned(), STREAM_SEEK_CUR, &_arc._phySize));
|
||||
if (_arc._phySize > endPos)
|
||||
{
|
||||
_error = k_ErrorType_UnexpectedEnd;
|
||||
_arc._error = k_ErrorType_UnexpectedEnd;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
@@ -241,6 +258,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
|
||||
break;
|
||||
}
|
||||
*/
|
||||
/*
|
||||
if (callback)
|
||||
{
|
||||
if (_items.Size() == 1)
|
||||
@@ -249,10 +267,11 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
|
||||
}
|
||||
if ((_items.Size() & 0x3FF) == 0)
|
||||
{
|
||||
UInt64 numFiles = _items.Size();
|
||||
const UInt64 numFiles = _items.Size();
|
||||
RINOK(callback->SetCompleted(&numFiles, &_phySize));
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -266,7 +285,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
|
||||
|
||||
if (_items.Size() == 0)
|
||||
{
|
||||
if (_error != k_ErrorType_OK)
|
||||
if (_arc._error != k_ErrorType_OK)
|
||||
{
|
||||
_isArc = false;
|
||||
return S_FALSE;
|
||||
@@ -294,6 +313,7 @@ HRESULT CHandler::Open2(IInStream *stream, IArchiveOpenCallback *callback)
|
||||
STDMETHODIMP CHandler::Open(IInStream *stream, const UInt64 *, IArchiveOpenCallback *openArchiveCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
// for (int i = 0; i < 10; i++) // for debug
|
||||
{
|
||||
Close();
|
||||
RINOK(Open2(stream, openArchiveCallback));
|
||||
@@ -314,16 +334,11 @@ STDMETHODIMP CHandler::OpenSeq(ISequentialInStream *stream)
|
||||
STDMETHODIMP CHandler::Close()
|
||||
{
|
||||
_isArc = false;
|
||||
_warning = false;
|
||||
_error = k_ErrorType_OK;
|
||||
|
||||
_phySizeDefined = false;
|
||||
_phySize = 0;
|
||||
_headersSize = 0;
|
||||
_arc.Clear();
|
||||
|
||||
_curIndex = 0;
|
||||
_latestIsRead = false;
|
||||
// _isSparse = false;
|
||||
_thereIsPaxExtendedHeader = false;
|
||||
_encodingCharacts.Clear();
|
||||
_items.Clear();
|
||||
_seqStream.Release();
|
||||
@@ -351,12 +366,12 @@ HRESULT CHandler::SkipTo(UInt32 index)
|
||||
{
|
||||
if (_latestIsRead)
|
||||
{
|
||||
UInt64 packSize = _latestItem.GetPackSizeAligned();
|
||||
const UInt64 packSize = _latestItem.Get_PackSize_Aligned();
|
||||
RINOK(copyCoderSpec->Code(_seqStream, NULL, &packSize, &packSize, NULL));
|
||||
_phySize += copyCoderSpec->TotalSize;
|
||||
_arc._phySize += copyCoderSpec->TotalSize;
|
||||
if (copyCoderSpec->TotalSize != packSize)
|
||||
{
|
||||
_error = k_ErrorType_UnexpectedEnd;
|
||||
_arc._error = k_ErrorType_UnexpectedEnd;
|
||||
return S_FALSE;
|
||||
}
|
||||
_latestIsRead = false;
|
||||
@@ -364,11 +379,12 @@ HRESULT CHandler::SkipTo(UInt32 index)
|
||||
}
|
||||
else
|
||||
{
|
||||
bool filled;
|
||||
RINOK(ReadItem2(_seqStream, filled, _latestItem));
|
||||
if (!filled)
|
||||
_arc.SeqStream = _seqStream;
|
||||
_arc.InStream = NULL;
|
||||
RINOK(_arc.ReadItem(_latestItem));
|
||||
if (!_arc.filled)
|
||||
{
|
||||
_phySizeDefined = true;
|
||||
_arc._phySize_Defined = true;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
_latestIsRead = true;
|
||||
@@ -390,6 +406,69 @@ void CHandler::TarStringToUnicode(const AString &s, NWindows::NCOM::CPropVariant
|
||||
prop = dest;
|
||||
}
|
||||
|
||||
|
||||
static void PaxTimeToProp(const CPaxTime &pt, NWindows::NCOM::CPropVariant &prop)
|
||||
{
|
||||
UInt64 v;
|
||||
if (!NTime::UnixTime64_To_FileTime64(pt.Sec, v))
|
||||
return;
|
||||
if (pt.Ns != 0)
|
||||
v += pt.Ns / 100;
|
||||
FILETIME ft;
|
||||
ft.dwLowDateTime = (DWORD)v;
|
||||
ft.dwHighDateTime = (DWORD)(v >> 32);
|
||||
prop.SetAsTimeFrom_FT_Prec_Ns100(ft,
|
||||
k_PropVar_TimePrec_Base + pt.NumDigits, pt.Ns % 100);
|
||||
}
|
||||
|
||||
|
||||
#define ValToHex(t) ((char)(((t) < 10) ? ('0' + (t)) : ('a' + ((t) - 10))))
|
||||
|
||||
static void AddByteToHex2(unsigned val, AString &s)
|
||||
{
|
||||
unsigned t;
|
||||
t = val >> 4;
|
||||
s += ValToHex(t);
|
||||
t = val & 0xF;
|
||||
s += ValToHex(t);
|
||||
}
|
||||
|
||||
static void AddSpecCharToString(const char c, AString &s)
|
||||
{
|
||||
if ((Byte)c <= 0x20 || (Byte)c > 127)
|
||||
{
|
||||
s += '[';
|
||||
AddByteToHex2((Byte)(c), s);
|
||||
s += ']';
|
||||
}
|
||||
else
|
||||
s += c;
|
||||
}
|
||||
|
||||
static void AddSpecUInt64(AString &s, const char *name, UInt64 v)
|
||||
{
|
||||
if (v != 0)
|
||||
{
|
||||
s.Add_OptSpaced(name);
|
||||
if (v > 1)
|
||||
{
|
||||
s += ':';
|
||||
s.Add_UInt64(v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void AddSpecBools(AString &s, const char *name, bool b1, bool b2)
|
||||
{
|
||||
if (b1)
|
||||
{
|
||||
s.Add_OptSpaced(name);
|
||||
if (b2)
|
||||
s += '*';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *value)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
@@ -413,49 +492,189 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
|
||||
{
|
||||
case kpidPath: TarStringToUnicode(item->Name, prop, true); break;
|
||||
case kpidIsDir: prop = item->IsDir(); break;
|
||||
case kpidSize: prop = item->GetUnpackSize(); break;
|
||||
case kpidPackSize: prop = item->GetPackSizeAligned(); break;
|
||||
case kpidSize: prop = item->Get_UnpackSize(); break;
|
||||
case kpidPackSize: prop = item->Get_PackSize_Aligned(); break;
|
||||
case kpidMTime:
|
||||
if (item->MTime != 0)
|
||||
{
|
||||
FILETIME ft;
|
||||
if (NTime::UnixTime64ToFileTime(item->MTime, ft))
|
||||
prop = ft;
|
||||
}
|
||||
break;
|
||||
case kpidPosixAttrib: prop = item->Get_Combined_Mode(); break;
|
||||
case kpidUser: TarStringToUnicode(item->User, prop); break;
|
||||
case kpidGroup: TarStringToUnicode(item->Group, prop); break;
|
||||
case kpidSymLink: if (item->LinkFlag == NFileHeader::NLinkFlag::kSymLink && !item->LinkName.IsEmpty()) TarStringToUnicode(item->LinkName, prop); break;
|
||||
case kpidHardLink: if (item->LinkFlag == NFileHeader::NLinkFlag::kHardLink && !item->LinkName.IsEmpty()) TarStringToUnicode(item->LinkName, prop); break;
|
||||
// case kpidLinkType: prop = (int)item->LinkFlag; break;
|
||||
case kpidCharacts:
|
||||
{
|
||||
AString s = item->EncodingCharacts.GetCharactsString();
|
||||
if (item->IsThereWarning())
|
||||
/*
|
||||
// for debug:
|
||||
PropVariant_SetFrom_UnixTime(prop, 1 << 30);
|
||||
prop.wReserved1 = k_PropVar_TimePrec_Base + 1;
|
||||
prop.wReserved2 = 12;
|
||||
break;
|
||||
*/
|
||||
|
||||
if (item->PaxTimes.MTime.IsDefined())
|
||||
PaxTimeToProp(item->PaxTimes.MTime, prop);
|
||||
else
|
||||
// if (item->MTime != 0)
|
||||
{
|
||||
s.Add_Space_if_NotEmpty();
|
||||
s += "HEADER_ERROR";
|
||||
// we allow (item->MTime == 0)
|
||||
FILETIME ft;
|
||||
if (NTime::UnixTime64_To_FileTime(item->MTime, ft))
|
||||
{
|
||||
unsigned prec = k_PropVar_TimePrec_Unix;
|
||||
if (item->MTime_IsBin)
|
||||
{
|
||||
/* we report here that it's Int64-UnixTime
|
||||
instead of basic UInt32-UnixTime range */
|
||||
prec = k_PropVar_TimePrec_Base;
|
||||
}
|
||||
prop.SetAsTimeFrom_FT_Prec(ft, prec);
|
||||
}
|
||||
}
|
||||
prop = s;
|
||||
break;
|
||||
}
|
||||
case kpidATime:
|
||||
if (item->PaxTimes.ATime.IsDefined())
|
||||
PaxTimeToProp(item->PaxTimes.ATime, prop);
|
||||
break;
|
||||
case kpidCTime:
|
||||
if (item->PaxTimes.CTime.IsDefined())
|
||||
PaxTimeToProp(item->PaxTimes.CTime, prop);
|
||||
break;
|
||||
case kpidPosixAttrib: prop = item->Get_Combined_Mode(); break;
|
||||
|
||||
case kpidUser:
|
||||
if (!item->User.IsEmpty())
|
||||
TarStringToUnicode(item->User, prop);
|
||||
break;
|
||||
case kpidGroup:
|
||||
if (!item->Group.IsEmpty())
|
||||
TarStringToUnicode(item->Group, prop);
|
||||
break;
|
||||
|
||||
case kpidUserId:
|
||||
// if (item->UID != 0)
|
||||
prop = (UInt32)item->UID;
|
||||
break;
|
||||
case kpidGroupId:
|
||||
// if (item->GID != 0)
|
||||
prop = (UInt32)item->GID;
|
||||
break;
|
||||
|
||||
case kpidDeviceMajor:
|
||||
if (item->DeviceMajor_Defined)
|
||||
// if (item->DeviceMajor != 0)
|
||||
prop = (UInt32)item->DeviceMajor;
|
||||
break;
|
||||
|
||||
case kpidDeviceMinor:
|
||||
if (item->DeviceMinor_Defined)
|
||||
// if (item->DeviceMinor != 0)
|
||||
prop = (UInt32)item->DeviceMinor;
|
||||
break;
|
||||
/*
|
||||
case kpidDevice:
|
||||
if (item->DeviceMajor_Defined)
|
||||
if (item->DeviceMinor_Defined)
|
||||
prop = (UInt64)MY_dev_makedev(item->DeviceMajor, item->DeviceMinor);
|
||||
break;
|
||||
*/
|
||||
|
||||
case kpidSymLink:
|
||||
if (item->Is_SymLink())
|
||||
if (!item->LinkName.IsEmpty())
|
||||
TarStringToUnicode(item->LinkName, prop);
|
||||
break;
|
||||
case kpidHardLink:
|
||||
if (item->Is_HardLink())
|
||||
if (!item->LinkName.IsEmpty())
|
||||
TarStringToUnicode(item->LinkName, prop);
|
||||
break;
|
||||
|
||||
case kpidCharacts:
|
||||
{
|
||||
AString s;
|
||||
{
|
||||
s.Add_Space_if_NotEmpty();
|
||||
AddSpecCharToString(item->LinkFlag, s);
|
||||
}
|
||||
if (item->IsMagic_GNU())
|
||||
s.Add_OptSpaced("GNU");
|
||||
else if (item->IsMagic_Posix_ustar_00())
|
||||
s.Add_OptSpaced("POSIX");
|
||||
else
|
||||
{
|
||||
s.Add_Space_if_NotEmpty();
|
||||
for (unsigned i = 0; i < sizeof(item->Magic); i++)
|
||||
AddSpecCharToString(item->Magic[i], s);
|
||||
}
|
||||
|
||||
if (item->IsSignedChecksum)
|
||||
s.Add_OptSpaced("SignedChecksum");
|
||||
|
||||
if (item->Prefix_WasUsed)
|
||||
s.Add_OptSpaced(k_Characts_Prefix);
|
||||
|
||||
s.Add_OptSpaced(item->EncodingCharacts.GetCharactsString());
|
||||
|
||||
// AddSpecUInt64(s, "LongName", item->Num_LongName_Records);
|
||||
// AddSpecUInt64(s, "LongLink", item->Num_LongLink_Records);
|
||||
AddSpecBools(s, "LongName", item->LongName_WasUsed, item->LongName_WasUsed_2);
|
||||
AddSpecBools(s, "LongLink", item->LongLink_WasUsed, item->LongLink_WasUsed_2);
|
||||
|
||||
if (item->MTime_IsBin)
|
||||
s.Add_OptSpaced("bin_mtime");
|
||||
if (item->PackSize_IsBin)
|
||||
s.Add_OptSpaced("bin_psize");
|
||||
if (item->Size_IsBin)
|
||||
s.Add_OptSpaced("bin_size");
|
||||
|
||||
AddSpecUInt64(s, "PAX", item->Num_Pax_Records);
|
||||
|
||||
if (item->PaxTimes.MTime.IsDefined()) s.Add_OptSpaced("mtime");
|
||||
if (item->PaxTimes.ATime.IsDefined()) s.Add_OptSpaced("atime");
|
||||
if (item->PaxTimes.CTime.IsDefined()) s.Add_OptSpaced("ctime");
|
||||
|
||||
if (item->pax_path_WasUsed)
|
||||
s.Add_OptSpaced("pax_path");
|
||||
if (item->pax_link_WasUsed)
|
||||
s.Add_OptSpaced("pax_linkpath");
|
||||
if (item->pax_size_WasUsed)
|
||||
s.Add_OptSpaced("pax_size");
|
||||
|
||||
if (item->IsThereWarning())
|
||||
s.Add_OptSpaced("WARNING");
|
||||
if (item->HeaderError)
|
||||
s.Add_OptSpaced("ERROR");
|
||||
if (item->Pax_Error)
|
||||
s.Add_OptSpaced("PAX_error");
|
||||
if (!item->PaxExtra.RawLines.IsEmpty())
|
||||
s.Add_OptSpaced("PAX_unsupported_line");
|
||||
if (item->Pax_Overflow)
|
||||
s.Add_OptSpaced("PAX_overflow");
|
||||
if (!s.IsEmpty())
|
||||
prop = s;
|
||||
break;
|
||||
}
|
||||
case kpidComment:
|
||||
{
|
||||
AString s;
|
||||
item->PaxExtra.Print_To_String(s);
|
||||
if (!s.IsEmpty())
|
||||
prop = s;
|
||||
break;
|
||||
}
|
||||
// case kpidHeadersSize: prop = item->HeaderSize; break; // for debug
|
||||
// case kpidOffset: prop = item->HeaderPos; break; // for debug
|
||||
}
|
||||
prop.Detach(value);
|
||||
return S_OK;
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
Int32 testMode, IArchiveExtractCallback *extractCallback)
|
||||
{
|
||||
COM_TRY_BEGIN
|
||||
ISequentialInStream *stream = _seqStream;
|
||||
bool seqMode = (_stream == NULL);
|
||||
const bool seqMode = (_stream == NULL);
|
||||
if (!seqMode)
|
||||
stream = _stream;
|
||||
|
||||
bool allFilesMode = (numItems == (UInt32)(Int32)-1);
|
||||
const bool allFilesMode = (numItems == (UInt32)(Int32)-1);
|
||||
if (allFilesMode)
|
||||
numItems = _items.Size();
|
||||
if (_stream && numItems == 0)
|
||||
@@ -463,7 +682,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
UInt64 totalSize = 0;
|
||||
UInt32 i;
|
||||
for (i = 0; i < numItems; i++)
|
||||
totalSize += _items[allFilesMode ? i : indices[i]].GetUnpackSize();
|
||||
totalSize += _items[allFilesMode ? i : indices[i]].Get_UnpackSize();
|
||||
extractCallback->SetTotal(totalSize);
|
||||
|
||||
UInt64 totalPackSize;
|
||||
@@ -503,9 +722,9 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
item = &_items[index];
|
||||
|
||||
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
|
||||
UInt64 unpackSize = item->GetUnpackSize();
|
||||
const UInt64 unpackSize = item->Get_UnpackSize();
|
||||
totalSize += unpackSize;
|
||||
totalPackSize += item->GetPackSizeAligned();
|
||||
totalPackSize += item->Get_PackSize_Aligned();
|
||||
if (item->IsDir())
|
||||
{
|
||||
RINOK(extractCallback->PrepareOperation(askMode));
|
||||
@@ -539,7 +758,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
|
||||
Int32 opRes = NExtract::NOperationResult::kOK;
|
||||
CMyComPtr<ISequentialInStream> inStream2;
|
||||
if (!item->IsSparse())
|
||||
if (!item->Is_Sparse())
|
||||
inStream2 = inStream;
|
||||
else
|
||||
{
|
||||
@@ -549,7 +768,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
}
|
||||
|
||||
{
|
||||
if (item->IsSymLink())
|
||||
if (item->Is_SymLink())
|
||||
{
|
||||
RINOK(WriteStream(outStreamSpec, (const char *)item->LinkName, item->LinkName.Len()));
|
||||
}
|
||||
@@ -557,9 +776,9 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
|
||||
{
|
||||
if (!seqMode)
|
||||
{
|
||||
RINOK(_stream->Seek((Int64)item->GetDataPosition(), STREAM_SEEK_SET, NULL));
|
||||
RINOK(_stream->Seek((Int64)item->Get_DataPos(), STREAM_SEEK_SET, NULL));
|
||||
}
|
||||
streamSpec->Init(item->GetPackSizeAligned());
|
||||
streamSpec->Init(item->Get_PackSize_Aligned());
|
||||
RINOK(copyCoder->Code(inStream2, outStream, NULL, NULL, progress));
|
||||
}
|
||||
if (outStreamSpec->GetRem() != 0)
|
||||
@@ -628,7 +847,7 @@ STDMETHODIMP CSparseStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
unsigned left = 0, right = item.SparseBlocks.Size();
|
||||
for (;;)
|
||||
{
|
||||
unsigned mid = (left + right) / 2;
|
||||
const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
|
||||
if (mid == left)
|
||||
break;
|
||||
if (_virtPos < item.SparseBlocks[mid].Offset)
|
||||
@@ -648,7 +867,7 @@ STDMETHODIMP CSparseStream::Read(void *data, UInt32 size, UInt32 *processedSize)
|
||||
UInt64 phyPos = PhyOffsets[left] + relat;
|
||||
if (_needStartSeek || _phyPos != phyPos)
|
||||
{
|
||||
RINOK(Handler->_stream->Seek((Int64)(item.GetDataPosition() + phyPos), STREAM_SEEK_SET, NULL));
|
||||
RINOK(Handler->_stream->Seek((Int64)(item.Get_DataPos() + phyPos), STREAM_SEEK_SET, NULL));
|
||||
_needStartSeek = false;
|
||||
_phyPos = phyPos;
|
||||
}
|
||||
@@ -698,7 +917,7 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
||||
|
||||
const CItemEx &item = _items[index];
|
||||
|
||||
if (item.IsSparse())
|
||||
if (item.Is_Sparse())
|
||||
{
|
||||
CSparseStream *streamSpec = new CSparseStream;
|
||||
CMyComPtr<IInStream> streamTemp = streamSpec;
|
||||
@@ -718,24 +937,30 @@ STDMETHODIMP CHandler::GetStream(UInt32 index, ISequentialInStream **stream)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (item.IsSymLink())
|
||||
if (item.Is_SymLink())
|
||||
{
|
||||
Create_BufInStream_WithReference((const Byte *)(const char *)item.LinkName, item.LinkName.Len(), (IInArchive *)this, stream);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return CreateLimitedInStream(_stream, item.GetDataPosition(), item.PackSize, stream);
|
||||
return CreateLimitedInStream(_stream, item.Get_DataPos(), item.PackSize, stream);
|
||||
|
||||
COM_TRY_END
|
||||
}
|
||||
|
||||
|
||||
void CHandler::Init()
|
||||
{
|
||||
_forceCodePage = false;
|
||||
_curCodePage = _specifiedCodePage = CP_UTF8; // CP_OEMCP;
|
||||
_thereIsPaxExtendedHeader = false;
|
||||
_posixMode = false;
|
||||
_posixMode_WasForced = false;
|
||||
// TimeOptions.Clear();
|
||||
_handlerTimeOptions.Init();
|
||||
// _handlerTimeOptions.Write_MTime.Val = true; // it's default already
|
||||
}
|
||||
|
||||
|
||||
STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVARIANT *values, UInt32 numProps)
|
||||
{
|
||||
Init();
|
||||
@@ -768,8 +993,54 @@ STDMETHODIMP CHandler::SetProperties(const wchar_t * const *names, const PROPVAR
|
||||
else if (name.IsPrefixedBy_Ascii_NoCase("memuse"))
|
||||
{
|
||||
}
|
||||
else if (name.IsEqualTo("m"))
|
||||
{
|
||||
if (prop.vt != VT_BSTR)
|
||||
return E_INVALIDARG;
|
||||
const UString s = prop.bstrVal;
|
||||
if (s.IsEqualTo_Ascii_NoCase("pax") ||
|
||||
s.IsEqualTo_Ascii_NoCase("posix"))
|
||||
_posixMode = true;
|
||||
else if (s.IsEqualTo_Ascii_NoCase("gnu"))
|
||||
_posixMode = false;
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
_posixMode_WasForced = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
if (name.IsPrefixedBy_Ascii_NoCase("td"))
|
||||
{
|
||||
name.Delete(0, 3);
|
||||
if (prop.vt == VT_EMPTY)
|
||||
{
|
||||
if (name.IsEqualTo_Ascii_NoCase("n"))
|
||||
{
|
||||
// TimeOptions.UseNativeDigits = true;
|
||||
}
|
||||
else if (name.IsEqualTo_Ascii_NoCase("r"))
|
||||
{
|
||||
// TimeOptions.RemoveZeroDigits = true;
|
||||
}
|
||||
else
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
else
|
||||
{
|
||||
UInt32 numTimeDigits = 0;
|
||||
RINOK(ParsePropToUInt32(name, prop, numTimeDigits));
|
||||
TimeOptions.NumDigits_WasForced = true;
|
||||
TimeOptions.NumDigits = numTimeDigits;
|
||||
}
|
||||
}
|
||||
*/
|
||||
bool processed = false;
|
||||
RINOK(_handlerTimeOptions.Parse(name, prop, processed));
|
||||
if (processed)
|
||||
continue;
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user