summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp
diff options
context:
space:
mode:
author Vas Crabb <vas@vastheman.com>2023-05-04 02:41:16 +1000
committer Vas Crabb <vas@vastheman.com>2023-05-04 02:41:16 +1000
commita504bde3a7462b54fafd5cfc2f52e58d0f3218e1 (patch)
tree8b3108d572b1a0873a6cdbb4e8af1f17179545c3 /3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp
parentbefb9bf4a8cfdb2b693a32e32535b5eac522c5d8 (diff)
3rdparty/lzma: Updated to LZMA SDK version 22.01
Diffstat (limited to '3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp')
-rw-r--r--3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp566
1 files changed, 360 insertions, 206 deletions
diff --git a/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp b/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp
index bf3b982e44e..4a91a2686eb 100644
--- a/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp
+++ b/3rdparty/lzma/CPP/7zip/UI/Common/OpenArchive.cpp
@@ -14,6 +14,7 @@
#include "../../../Common/IntToString.h"
#include "../../../Common/StringConvert.h"
#include "../../../Common/StringToInt.h"
+#include "../../../Common/UTFConvert.h"
#include "../../../Common/Wildcard.h"
#include "../../../Windows/FileDir.h"
@@ -32,11 +33,13 @@
#include "SetProperties.h"
#endif
+#ifndef _SFX
#ifdef SHOW_DEBUG_INFO
#define PRF(x) x
#else
#define PRF(x)
#endif
+#endif
// increase it, if you need to support larger SFX stubs
static const UInt64 kMaxCheckStartPosition = 1 << 23;
@@ -64,7 +67,7 @@ Open:
- open FAIL:
Try to open with all other types from offset 0 only.
If some open type is OK and physical archive size is uequal or larger
- than file size, then return that archive with warning that can not be open as [extension type].
+ than file size, then return that archive with warning that cannot be open as [extension type].
If extension was EXE, it will try to open as unknown_extension case
- file has unknown extension (like a.hhh)
It tries to open via parser code.
@@ -141,14 +144,14 @@ struct CParseItem
bool LenIsUnknown;
CParseItem():
- LenIsUnknown(false),
+ // OkSize(0),
FileTime_Defined(false),
UnpackSize_Defined(false),
- NumSubFiles_Defined(false),
NumSubDirs_Defined(false),
+ NumSubFiles_Defined(false),
IsSelfExe(false),
- IsNotArcType(false)
- // OkSize(0)
+ IsNotArcType(false),
+ LenIsUnknown(false)
{}
/*
@@ -206,23 +209,25 @@ int CHandler::FindInsertPos(const CParseItem &item) const
unsigned left = 0, right = _items.Size();
while (left != right)
{
- unsigned mid = (left + right) / 2;
- const CParseItem & midItem = _items[mid];
+ const unsigned mid = (unsigned)(((size_t)left + (size_t)right) / 2);
+ const CParseItem &midItem = _items[mid];
if (item.Offset < midItem.Offset)
right = mid;
else if (item.Offset > midItem.Offset)
left = mid + 1;
else if (item.Size < midItem.Size)
right = mid;
+ /*
else if (item.Size > midItem.Size)
left = mid + 1;
+ */
else
{
left = mid + 1;
// return -1;
}
}
- return left;
+ return (int)left;
}
void CHandler::AddUnknownItem(UInt64 next)
@@ -257,10 +262,10 @@ void CHandler::AddUnknownItem(UInt64 next)
void CHandler::AddItem(const CParseItem &item)
{
AddUnknownItem(item.Offset);
- int pos = FindInsertPos(item);
- if (pos >= 0)
+ const int pos = FindInsertPos(item);
+ if (pos != -1)
{
- _items.Insert(pos, item);
+ _items.Insert((unsigned)pos, item);
UInt64 next = item.Offset + item.Size;
if (_maxEndOffset < next)
_maxEndOffset = next;
@@ -330,17 +335,17 @@ STDMETHODIMP CHandler::GetProperty(UInt32 index, PROPID propID, PROPVARIANT *val
{
case kpidPath:
{
- wchar_t sz[32];
+ char sz[32];
ConvertUInt32ToString(index + 1, sz);
- UString s = sz;
+ UString s(sz);
if (!item.Name.IsEmpty())
{
- s += L'.';
+ s += '.';
s += item.Name;
}
if (!item.Extension.IsEmpty())
{
- s += L'.';
+ s += '.';
s += item.Extension;
}
prop = s; break;
@@ -401,7 +406,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
Int32 askMode = testMode ?
NExtract::NAskMode::kTest :
NExtract::NAskMode::kExtract;
- Int32 index = allFilesMode ? i : indices[i];
+ UInt32 index = allFilesMode ? i : indices[i];
const CParseItem &item = _items[index];
RINOK(extractCallback->GetStream(index, &realOutStream, askMode));
@@ -417,7 +422,7 @@ HRESULT CHandler::Extract(const UInt32 *indices, UInt32 numItems,
outStreamSpec->Init(skipMode ? 0 : unpackSize, true);
Int32 opRes = NExtract::NOperationResult::kOK;
- RINOK(_stream->Seek(item.Offset, STREAM_SEEK_SET, NULL));
+ RINOK(_stream->Seek((Int64)item.Offset, STREAM_SEEK_SET, NULL));
streamSpec->Init(unpackSize);
RINOK(copyCoder->Code(inStream, outStream, NULL, NULL, progress));
@@ -477,7 +482,7 @@ HRESULT Archive_IsItem_Deleted(IInArchive *arc, UInt32 index, bool &result) thro
return Archive_GetItemBoolProp(arc, index, kpidIsDeleted, result);
}
-static HRESULT Archive_GetArcBoolProp(IInArchive *arc, PROPID propid, bool &result) throw()
+static HRESULT Archive_GetArcProp_Bool(IInArchive *arc, PROPID propid, bool &result) throw()
{
NCOM::CPropVariant prop;
result = false;
@@ -496,13 +501,14 @@ static HRESULT Archive_GetArcProp_UInt(IInArchive *arc, PROPID propid, UInt64 &r
RINOK(arc->GetArchiveProperty(propid, &prop));
switch (prop.vt)
{
- case VT_UI4: result = prop.ulVal; defined = true; break;
- case VT_I4: result = (Int64)prop.lVal; defined = true; break;
- case VT_UI8: result = (UInt64)prop.uhVal.QuadPart; defined = true; break;
- case VT_I8: result = (UInt64)prop.hVal.QuadPart; defined = true; break;
- case VT_EMPTY: break;
+ case VT_UI4: result = prop.ulVal; break;
+ case VT_I4: result = (UInt64)(Int64)prop.lVal; break;
+ case VT_UI8: result = (UInt64)prop.uhVal.QuadPart; break;
+ case VT_I8: result = (UInt64)prop.hVal.QuadPart; break;
+ case VT_EMPTY: return S_OK;
default: return E_FAIL;
}
+ defined = true;
return S_OK;
}
@@ -513,19 +519,20 @@ static HRESULT Archive_GetArcProp_Int(IInArchive *arc, PROPID propid, Int64 &res
RINOK(arc->GetArchiveProperty(propid, &prop));
switch (prop.vt)
{
- case VT_UI4: result = prop.ulVal; defined = true; break;
- case VT_I4: result = prop.lVal; defined = true; break;
- case VT_UI8: result = (Int64)prop.uhVal.QuadPart; defined = true; break;
- case VT_I8: result = (Int64)prop.hVal.QuadPart; defined = true; break;
- case VT_EMPTY: break;
+ case VT_UI4: result = prop.ulVal; break;
+ case VT_I4: result = prop.lVal; break;
+ case VT_UI8: result = (Int64)prop.uhVal.QuadPart; break;
+ case VT_I8: result = (Int64)prop.hVal.QuadPart; break;
+ case VT_EMPTY: return S_OK;
default: return E_FAIL;
}
+ defined = true;
return S_OK;
}
#ifndef _SFX
-HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const
+HRESULT CArc::GetItem_PathToParent(UInt32 index, UInt32 parent, UStringVector &parts) const
{
if (!GetRawProps)
return E_FAIL;
@@ -563,6 +570,8 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa
UInt32 parentType = 0;
RINOK(GetRawProps->GetParent(curIndex, &curParent, &parentType));
+ // 18.06: fixed : we don't want to split name to parts
+ /*
if (parentType != NParentType::kAltStream)
{
for (;;)
@@ -576,6 +585,7 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa
s.DeleteFrom(pos);
}
}
+ */
parts.Insert(0, s);
@@ -583,7 +593,7 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa
{
{
UString &s2 = parts[parts.Size() - 2];
- s2 += L':';
+ s2 += ':';
s2 += parts.Back();
}
parts.DeleteBack();
@@ -604,7 +614,9 @@ HRESULT CArc::GetItemPathToParent(UInt32 index, UInt32 parent, UStringVector &pa
#endif
-HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
+
+
+HRESULT CArc::GetItem_Path(UInt32 index, UString &result) const
{
#ifdef MY_CPU_LE
if (GetRawProps)
@@ -618,19 +630,42 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
propType == NPropDataType::kUtf16z)
{
unsigned len = size / 2 - 1;
+ // (len) doesn't include null terminator
+
+ /*
+ #if WCHAR_MAX > 0xffff
+ len = (unsigned)Utf16LE__Get_Num_WCHARs(p, len);
+
+ wchar_t *s = result.GetBuf(len);
+ wchar_t *sEnd = Utf16LE__To_WCHARs_Sep(p, len, s);
+ if (s + len != sEnd) return E_FAIL;
+ *sEnd = 0;
+
+ #else
+ */
+
wchar_t *s = result.GetBuf(len);
for (unsigned i = 0; i < len; i++)
{
wchar_t c = GetUi16(p);
p = (const void *)((const Byte *)p + 2);
+
#if WCHAR_PATH_SEPARATOR != L'/'
if (c == L'/')
c = WCHAR_PATH_SEPARATOR;
+ else if (c == L'\\')
+ c = WCHAR_IN_FILE_NAME_BACKSLASH_REPLACEMENT; // WSL scheme
#endif
+
*s++ = c;
}
*s = 0;
+
+ // #endif
+
result.ReleaseBuf_SetLen(len);
+
+ Convert_UnicodeEsc16_To_UnicodeEscHigh(result);
if (len != 0)
return S_OK;
}
@@ -717,11 +752,13 @@ HRESULT CArc::GetItemPath(UInt32 index, UString &result) const
}
if (result.IsEmpty())
- return GetDefaultItemPath(index, result);
+ return GetItem_DefaultPath(index, result);
+
+ Convert_UnicodeEsc16_To_UnicodeEscHigh(result);
return S_OK;
}
-HRESULT CArc::GetDefaultItemPath(UInt32 index, UString &result) const
+HRESULT CArc::GetItem_DefaultPath(UInt32 index, UString &result) const
{
result.Empty();
bool isDir;
@@ -733,7 +770,7 @@ HRESULT CArc::GetDefaultItemPath(UInt32 index, UString &result) const
RINOK(Archive->GetProperty(index, kpidExtension, &prop));
if (prop.vt == VT_BSTR)
{
- result += L'.';
+ result += '.';
result += prop.bstrVal;
}
else if (prop.vt != VT_EMPTY)
@@ -742,9 +779,9 @@ HRESULT CArc::GetDefaultItemPath(UInt32 index, UString &result) const
return S_OK;
}
-HRESULT CArc::GetItemPath2(UInt32 index, UString &result) const
+HRESULT CArc::GetItem_Path2(UInt32 index, UString &result) const
{
- RINOK(GetItemPath(index, result));
+ RINOK(GetItem_Path(index, result));
if (Ask_Deleted)
{
bool isDeleted = false;
@@ -769,7 +806,7 @@ int FindAltStreamColon_in_Path(const wchar_t *path)
if (c == ':')
{
if (colonPos < 0)
- colonPos = i;
+ colonPos = (int)i;
continue;
}
if (c == WCHAR_PATH_SEPARATOR)
@@ -796,7 +833,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
RINOK(Archive_IsItem_Dir(Archive, index, item.IsDir));
item.MainIsDir = item.IsDir;
- RINOK(GetItemPath2(index, item.Path));
+ RINOK(GetItem_Path2(index, item.Path));
#ifndef _SFX
UInt32 mainIndex = index;
@@ -848,7 +885,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
}
else
{
- RINOK(GetItemPath2(parentIndex, item.MainPath));
+ RINOK(GetItem_Path2(parentIndex, item.MainPath));
RINOK(Archive_IsItem_Dir(Archive, parentIndex, item.MainIsDir));
}
}
@@ -857,13 +894,13 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
if (item.WriteToAltStreamIfColon || needFindAltStream)
{
- /* Good handler must support GetRawProps::GetParent for alt streams./
+ /* Good handler must support GetRawProps::GetParent for alt streams.
So the following code currently is not used */
int colon = FindAltStreamColon_in_Path(item.Path);
if (colon >= 0)
{
- item.MainPath.DeleteFrom(colon);
- item.AltStreamName = item.Path.Ptr(colon + 1);
+ item.MainPath.DeleteFrom((unsigned)colon);
+ item.AltStreamName = item.Path.Ptr((unsigned)(colon + 1));
item.MainIsDir = (colon == 0 || IsPathSepar(item.Path[(unsigned)colon - 1]));
item.IsAltStream = true;
}
@@ -874,7 +911,7 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
#ifndef _SFX
if (item._use_baseParentFolder_mode)
{
- RINOK(GetItemPathToParent(mainIndex, item._baseParentFolder, item.PathParts));
+ RINOK(GetItem_PathToParent(mainIndex, (unsigned)item._baseParentFolder, item.PathParts));
#ifdef SUPPORT_ALT_STREAMS
if ((item.WriteToAltStreamIfColon || needFindAltStream) && !item.PathParts.IsEmpty())
@@ -885,10 +922,10 @@ HRESULT CArc::GetItem(UInt32 index, CReadArcItem &item) const
colon = FindAltStreamColon_in_Path(s);
if (colon >= 0)
{
- item.AltStreamName = s.Ptr(colon + 1);
+ item.AltStreamName = s.Ptr((unsigned)(colon + 1));
item.MainIsDir = (colon == 0 || IsPathSepar(s[(unsigned)colon - 1]));
item.IsAltStream = true;
- s.DeleteFrom(colon);
+ s.DeleteFrom((unsigned)colon);
}
}
if (colon == 0)
@@ -933,7 +970,7 @@ static HRESULT Archive_GetItem_Size(IInArchive *archive, UInt32 index, UInt64 &s
#endif
-HRESULT CArc::GetItemSize(UInt32 index, UInt64 &size, bool &defined) const
+HRESULT CArc::GetItem_Size(UInt32 index, UInt64 &size, bool &defined) const
{
NCOM::CPropVariant prop;
defined = false;
@@ -952,24 +989,52 @@ HRESULT CArc::GetItemSize(UInt32 index, UInt64 &size, bool &defined) const
return S_OK;
}
-HRESULT CArc::GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const
+HRESULT CArc::GetItem_MTime(UInt32 index, CArcTime &at) const
{
+ at.Clear();
NCOM::CPropVariant prop;
- defined = false;
- ft.dwHighDateTime = ft.dwLowDateTime = 0;
RINOK(Archive->GetProperty(index, kpidMTime, &prop));
+
if (prop.vt == VT_FILETIME)
{
- ft = prop.filetime;
- defined = true;
+ /*
+ // for debug
+ if (FILETIME_IsZero(prop.at) && MTime.Def)
+ {
+ at = MTime;
+ return S_OK;
+ }
+ */
+ at.Set_From_Prop(prop);
+ if (at.Prec == 0)
+ {
+ // (at.Prec == 0) before version 22.
+ // so kpidTimeType is required for that code
+ prop.Clear();
+ RINOK(Archive->GetProperty(index, kpidTimeType, &prop));
+ if (prop.vt == VT_UI4)
+ {
+ UInt32 val = prop.ulVal;
+ if (val == NFileTimeType::kWindows)
+ val = k_PropVar_TimePrec_100ns;
+ /*
+ else if (val > k_PropVar_TimePrec_1ns)
+ {
+ val = k_PropVar_TimePrec_100ns;
+ // val = k_PropVar_TimePrec_1ns;
+ // return E_FAIL; // for debug
+ }
+ */
+ at.Prec = (UInt16)val;
+ }
+ }
+ return S_OK;
}
- else if (prop.vt != VT_EMPTY)
+
+ if (prop.vt != VT_EMPTY)
return E_FAIL;
- else if (MTimeDefined)
- {
- ft = MTime;
- defined = true;
- }
+ if (MTime.Def)
+ at = MTime;
return S_OK;
}
@@ -983,52 +1048,52 @@ static inline bool TestSignature(const Byte *p1, const Byte *p2, size_t size)
return true;
}
+
static void MakeCheckOrder(CCodecs *codecs,
CIntVector &orderIndices, unsigned numTypes, CIntVector &orderIndices2,
const Byte *data, size_t dataSize)
{
for (unsigned i = 0; i < numTypes; i++)
{
- int index = orderIndices[i];
+ const int index = orderIndices[i];
if (index < 0)
continue;
- const CArcInfoEx &ai = codecs->Formats[index];
- if (ai.SignatureOffset != 0)
- {
- orderIndices2.Add(index);
- orderIndices[i] = -1;
- continue;
- }
-
- const CObjectVector<CByteBuffer> &sigs = ai.Signatures;
- FOR_VECTOR (k, sigs)
+ const CArcInfoEx &ai = codecs->Formats[(unsigned)index];
+ if (ai.SignatureOffset == 0)
{
- const CByteBuffer &sig = sigs[k];
- if (sig.Size() == 0 && dataSize == 0 ||
- sig.Size() != 0 && sig.Size() <= dataSize &&
- TestSignature(data, sig, sig.Size()))
+ if (ai.Signatures.IsEmpty())
{
- orderIndices2.Add(index);
- orderIndices[i] = -1;
- break;
+ if (dataSize != 0) // 21.04: no Signature means Empty Signature
+ continue;
+ }
+ else
+ {
+ unsigned k;
+ const CObjectVector<CByteBuffer> &sigs = ai.Signatures;
+ for (k = 0; k < sigs.Size(); k++)
+ {
+ const CByteBuffer &sig = sigs[k];
+ if (sig.Size() <= dataSize && TestSignature(data, sig, sig.Size()))
+ break;
+ }
+ if (k == sigs.Size())
+ continue;
}
}
+ orderIndices2.Add(index);
+ orderIndices[i] = -1;
}
}
-#endif
-
#ifdef UNDER_CE
static const unsigned kNumHashBytes = 1;
- #define HASH_VAL(buf, pos) ((buf)[pos])
+ #define HASH_VAL(buf) ((buf)[0])
#else
static const unsigned kNumHashBytes = 2;
- #define HASH_VAL(buf, pos) ((buf)[pos] | ((UInt32)(buf)[pos + 1] << 8))
+ // #define HASH_VAL(buf) ((buf)[0] | ((UInt32)(buf)[1] << 8))
+ #define HASH_VAL(buf) GetUi16(buf)
#endif
-
-#ifndef _SFX
-
static bool IsExeExt(const UString &ext)
{
return ext.IsEqualTo_Ascii_NoCase("exe");
@@ -1193,7 +1258,7 @@ void CArcErrorInfo::ClearErrors()
HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openRes)
{
// OkPhySize_Defined = false;
- PhySizeDefined = false;
+ PhySize_Defined = false;
PhySize = 0;
Offset = 0;
AvailPhySize = FileSize - startPos;
@@ -1226,12 +1291,12 @@ HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openR
if (openRes == S_OK || ErrorInfo.IsArc_After_NonOpen())
{
- RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, PhySize, PhySizeDefined));
+ RINOK(Archive_GetArcProp_UInt(archive, kpidPhySize, PhySize, PhySize_Defined));
/*
RINOK(Archive_GetArcProp_UInt(archive, kpidOkPhySize, OkPhySize, OkPhySize_Defined));
if (!OkPhySize_Defined)
{
- OkPhySize_Defined = PhySizeDefined;
+ OkPhySize_Defined = PhySize_Defined;
OkPhySize = PhySize;
}
*/
@@ -1239,11 +1304,11 @@ HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openR
bool offsetDefined;
RINOK(Archive_GetArcProp_Int(archive, kpidOffset, Offset, offsetDefined));
- Int64 globalOffset = startPos + Offset;
- AvailPhySize = FileSize - globalOffset;
- if (PhySizeDefined)
+ Int64 globalOffset = (Int64)startPos + Offset;
+ AvailPhySize = (UInt64)((Int64)FileSize - globalOffset);
+ if (PhySize_Defined)
{
- UInt64 endPos = globalOffset + PhySize;
+ UInt64 endPos = (UInt64)(globalOffset + (Int64)PhySize);
if (endPos < FileSize)
{
AvailPhySize = PhySize;
@@ -1259,11 +1324,12 @@ HRESULT CArc::ReadBasicProps(IInArchive *archive, UInt64 startPos, HRESULT openR
}
/*
-static PrintNumber(const char *s, int n)
+static void PrintNumber(const char *s, int n)
{
char temp[100];
sprintf(temp, "%s %d", s, n);
- OutputDebugStringA(temp);
+ // OutputDebugStringA(temp);
+ printf(temp);
}
*/
@@ -1282,7 +1348,7 @@ HRESULT CArc::PrepareToOpen(const COpenOptions &op, unsigned formatIndex, CMyCom
{
const CArcInfoEx &ai = op.codecs->Formats[formatIndex];
if (ai.LibIndex >= 0 ?
- !op.codecs->Libs[ai.LibIndex].SetCodecs :
+ !op.codecs->Libs[(unsigned)ai.LibIndex].SetCodecs :
!op.codecs->Libs.IsEmpty())
{
CMyComPtr<ISetCompressCodecsInfo> setCompressCodecsInfo;
@@ -1341,9 +1407,9 @@ static HRESULT ReadParseItemProps(IInArchive *archive, const CArcInfoEx &ai, NAr
pi.FileTime_Defined = false;
pi.ArcType = ai.Name;
- RINOK(Archive_GetArcBoolProp(archive, kpidIsNotArcType, pi.IsNotArcType));
+ RINOK(Archive_GetArcProp_Bool(archive, kpidIsNotArcType, pi.IsNotArcType));
- // RINOK(Archive_GetArcBoolProp(archive, kpidIsSelfExe, pi.IsSelfExe));
+ // RINOK(Archive_GetArcProp_Bool(archive, kpidIsSelfExe, pi.IsSelfExe));
pi.IsSelfExe = ai.Flags_PreArc();
{
@@ -1433,7 +1499,7 @@ HRESULT CArc::CheckZerosTail(const COpenOptions &op, UInt64 offset)
{
if (!op.stream)
return S_OK;
- RINOK(op.stream->Seek(offset, STREAM_SEEK_SET, NULL));
+ RINOK(op.stream->Seek((Int64)offset, STREAM_SEEK_SET, NULL));
const UInt32 kBufSize = 1 << 11;
Byte buf[kBufSize];
@@ -1459,6 +1525,8 @@ HRESULT CArc::CheckZerosTail(const COpenOptions &op, UInt64 offset)
}
}
+
+
#ifndef _SFX
class CExtractCallback_To_OpenCallback:
@@ -1506,7 +1574,7 @@ STDMETHODIMP CExtractCallback_To_OpenCallback::SetRatioInfo(const UInt64 *inSize
STDMETHODIMP CExtractCallback_To_OpenCallback::GetStream(UInt32 /* index */, ISequentialOutStream **outStream, Int32 /* askExtractMode */)
{
- *outStream = 0;
+ *outStream = NULL;
return S_OK;
}
@@ -1520,6 +1588,7 @@ STDMETHODIMP CExtractCallback_To_OpenCallback::SetOperationResult(Int32 /* opera
return S_OK;
}
+
static HRESULT OpenArchiveSpec(IInArchive *archive, bool needPhySize,
IInStream *stream, const UInt64 *maxCheckStartPosition,
IArchiveOpenCallback *openCallback,
@@ -1543,22 +1612,32 @@ static HRESULT OpenArchiveSpec(IInArchive *archive, bool needPhySize,
if (phySize_Defined)
return S_OK;
- bool phySizeCantBeDetected = false;;
- RINOK(Archive_GetArcBoolProp(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected));
+ bool phySizeCantBeDetected = false;
+ RINOK(Archive_GetArcProp_Bool(archive, kpidPhySizeCantBeDetected, phySizeCantBeDetected));
if (!phySizeCantBeDetected)
{
- RINOK(archive->Extract(0, (UInt32)(Int32)-1, BoolToInt(true), extractCallback));
+ PRF(printf("\n-- !phySize_Defined after Open, call archive->Extract()"));
+ // It's for bzip2/gz and some xz archives, where Open operation doesn't know phySize.
+ // But the Handler will know phySize after full archive testing.
+ RINOK(archive->Extract(NULL, (UInt32)(Int32)-1, BoolToInt(true), extractCallback));
+ PRF(printf("\n-- OK"));
}
}
return S_OK;
}
+
+
static int FindFormatForArchiveType(CCodecs *codecs, CIntVector orderIndices, const char *name)
{
FOR_VECTOR (i, orderIndices)
- if (StringsAreEqualNoCase_Ascii(codecs->Formats[orderIndices[i]].Name, name))
- return i;
+ {
+ int oi = orderIndices[i];
+ if (oi >= 0)
+ if (StringsAreEqualNoCase_Ascii(codecs->Formats[(unsigned)oi].Name, name))
+ return (int)i;
+ }
return -1;
}
@@ -1586,7 +1665,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
{
int dotPos = fileName.ReverseFind_Dot();
if (dotPos >= 0)
- extension = fileName.Ptr(dotPos + 1);
+ extension = fileName.Ptr((unsigned)(dotPos + 1));
}
CIntVector orderIndices;
@@ -1611,13 +1690,18 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
bool isUnknownExt = false;
#endif
+ #ifndef _SFX
bool isForced = false;
+ #endif
+
unsigned numMainTypes = 0;
int formatIndex = op.openType.FormatIndex;
if (formatIndex >= 0)
{
+ #ifndef _SFX
isForced = true;
+ #endif
orderIndices.Add(formatIndex);
numMainTypes = 1;
isMainFormatArr[(unsigned)formatIndex] = true;
@@ -1654,10 +1738,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
isNumber = true;
}
if (isNumber)
+ {
if (c == 'z' || c == 'Z')
isZip = true;
else
isRar = true;
+ }
}
#endif
@@ -1667,9 +1753,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
const CArcInfoEx &ai = op.codecs->Formats[i];
if (IgnoreSplit || !op.openType.CanReturnArc)
- if (ai.IsSplit())
+ if (ai.Is_Split())
continue;
- if (op.excludedFormats->FindInSorted(i) >= 0)
+ if (op.excludedFormats->FindInSorted((int)i) >= 0)
continue;
#ifndef _SFX
@@ -1679,17 +1765,17 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
if (ai.FindExtension(extension) >= 0
#ifndef _SFX
- || isZip && StringsAreEqualNoCase_Ascii(ai.Name, "zip")
- || isRar && StringsAreEqualNoCase_Ascii(ai.Name, "rar")
+ || (isZip && ai.Is_Zip())
+ || (isRar && ai.Is_Rar())
#endif
)
{
// PrintNumber("orderIndices.Insert", i);
- orderIndices.Insert(numFinded++, i);
+ orderIndices.Insert(numFinded++, (int)i);
isMainFormatArr[i] = true;
}
else
- orderIndices.Add(i);
+ orderIndices.Add((int)i);
}
}
@@ -1735,8 +1821,8 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
const Byte kRarHeader[] = { 0x52 , 0x61, 0x72, 0x21, 0x1a, 0x07, 0x00 };
if (TestSignature(buf, kRarHeader, 7) && buf[9] == 0x73 && (buf[10] & 1) != 0)
{
- orderIndices2.Add(orderIndices[i]);
- orderIndices[i] = -1;
+ orderIndices2.Add(orderIndices[(unsigned)i]);
+ orderIndices[(unsigned)i] = -1;
if (i >= (int)numFinded)
numFinded++;
}
@@ -1754,11 +1840,27 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
/*
check type order:
- 1) matched extension, no signuature
- 2) matched extension, matched signuature
+ 0) matched_extension && Backward
+ 1) matched_extension && (no_signuature || SignatureOffset != 0)
+ 2) matched_extension && (matched_signature)
// 3) no signuature
// 4) matched signuature
*/
+ // we move index from orderIndices to orderIndices2 for priority handlers.
+
+ for (unsigned i = 0; i < numFinded; i++)
+ {
+ const int index = orderIndices[i];
+ if (index < 0)
+ continue;
+ const CArcInfoEx &ai = op.codecs->Formats[(unsigned)index];
+ if (ai.Flags_BackwardOpen())
+ {
+ // backward doesn't need start signatures
+ orderIndices2.Add(index);
+ orderIndices[i] = -1;
+ }
+ }
MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, NULL, 0);
MakeCheckOrder(op.codecs, orderIndices, numFinded, orderIndices2, byteBuffer, processedSize);
@@ -1781,10 +1883,10 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
int iUdf = FindFormatForArchiveType(op.codecs, orderIndices, "udf");
if (iUdf > iIso && iIso >= 0)
{
- int isoIndex = orderIndices[iIso];
- int udfIndex = orderIndices[iUdf];
- orderIndices[iUdf] = isoIndex;
- orderIndices[iIso] = udfIndex;
+ int isoIndex = orderIndices[(unsigned)iIso];
+ int udfIndex = orderIndices[(unsigned)iUdf];
+ orderIndices[(unsigned)iUdf] = isoIndex;
+ orderIndices[(unsigned)iIso] = udfIndex;
}
}
@@ -1838,15 +1940,18 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
for (unsigned i = 0; i < numCheckTypes; i++)
{
FormatIndex = orderIndices[i];
+
+ // orderIndices[] item cannot be negative here
bool exactOnly = false;
#ifndef _SFX
- const CArcInfoEx &ai = op.codecs->Formats[FormatIndex];
+ const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex];
// OutputDebugStringW(ai.Name);
if (i >= numMainTypes)
{
+ // here we allow mismatched extension only for backward handlers
if (!ai.Flags_BackwardOpen()
// && !ai.Flags_PureStartOpen()
)
@@ -1867,7 +1972,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
CMyComPtr<IInArchive> archive;
- RINOK(PrepareToOpen(op, FormatIndex, archive));
+ RINOK(PrepareToOpen(op, (unsigned)FormatIndex, archive));
if (!archive)
continue;
@@ -1944,7 +2049,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
bool thereIsTail = ErrorInfo.ThereIsTail;
if (thereIsTail && mode.ZerosTailIsAllowed)
{
- RINOK(CheckZerosTail(op, Offset + PhySize));
+ RINOK(CheckZerosTail(op, (UInt64)(Offset + (Int64)PhySize)));
if (ErrorInfo.IgnoreTail)
thereIsTail = false;
}
@@ -2012,7 +2117,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
else
{
- const CArcInfoEx &ai = op.codecs->Formats[formatIndex];
+ const CArcInfoEx &ai = op.codecs->Formats[(unsigned)formatIndex];
if (ai.FindExtension(extension) >= 0)
{
if (ai.Flags_FindSignature() && searchMarkerInHandler)
@@ -2059,16 +2164,22 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
for (i = 0; i < orderIndices.Size(); i++)
{
- unsigned form = orderIndices[i];
+ // orderIndices[] item cannot be negative here
+ unsigned form = (unsigned)orderIndices[i];
if (skipFrontalFormat[form])
continue;
+
const CArcInfoEx &ai = op.codecs->Formats[form];
- if (ai.IsSplit())
+
+ if (ai.Is_Split())
{
- splitIndex = form;
+ splitIndex = (int)form;
continue;
}
+ if (ai.Flags_ByExtOnlyOpen())
+ continue;
+
if (ai.IsArcFunc)
{
UInt32 isArcRes = ai.IsArcFunc(byteBuffer, processedSize);
@@ -2081,7 +2192,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
continue;
}
- bool isNewStyleSignature = IsNewStyleSignature(ai);
+ const bool isNewStyleSignature = IsNewStyleSignature(ai);
bool needCheck = !isNewStyleSignature
|| ai.Signatures.IsEmpty()
|| ai.Flags_PureStartOpen()
@@ -2094,13 +2205,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
for (k = 0; k < ai.Signatures.Size(); k++)
{
const CByteBuffer &sig = ai.Signatures[k];
- UInt32 signatureEnd = ai.SignatureOffset + (UInt32)sig.Size();
- if (processedSize < signatureEnd)
+ if (processedSize < ai.SignatureOffset + sig.Size())
{
if (!endOfFile)
needCheck = true;
}
- else if (memcmp(sig, byteBuffer + ai.SignatureOffset, sig.Size()) == 0)
+ else if (TestSignature(sig, byteBuffer + ai.SignatureOffset, sig.Size()))
break;
}
if (k != ai.Signatures.Size())
@@ -2114,12 +2224,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
if (splitIndex >= 0)
- sortedFormats.Insert(0, splitIndex);
+ sortedFormats.Insert(0, (unsigned)splitIndex);
for (i = 0; i < sortedFormats.Size(); i++)
{
- FormatIndex = sortedFormats[i];
- const CArcInfoEx &ai = op.codecs->Formats[FormatIndex];
+ FormatIndex = (int)sortedFormats[i];
+ const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex];
if (op.callback)
RINOK(op.callback->SetTotal(NULL, &fileSize));
@@ -2127,7 +2237,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
RINOK(op.stream->Seek(0, STREAM_SEEK_SET, NULL));
CMyComPtr<IInArchive> archive;
- RINOK(PrepareToOpen(op, FormatIndex, archive));
+ RINOK(PrepareToOpen(op, (unsigned)FormatIndex, archive));
if (!archive)
continue;
@@ -2140,7 +2250,10 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
result = archive->Open(op.stream, &searchLimit, op.callback);
else
*/
- result = OpenArchiveSpec(archive, !mode.CanReturnArc, op.stream, &searchLimit, op.callback, extractCallback_To_OpenCallback);
+ // if (!CanReturnArc), it's ParserMode, and we need phy size
+ result = OpenArchiveSpec(archive,
+ !mode.CanReturnArc, // needPhySize
+ op.stream, &searchLimit, op.callback, extractCallback_To_OpenCallback);
}
if (result == S_FALSE)
@@ -2162,12 +2275,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
NArchive::NParser::CParseItem pi;
- pi.Offset = Offset;
+ pi.Offset = (UInt64)Offset;
pi.Size = AvailPhySize;
// bool needScan = false;
- if (!PhySizeDefined)
+ if (!PhySize_Defined)
{
// it's for Z format
pi.LenIsUnknown = true;
@@ -2199,7 +2312,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
{
if (mode.ZerosTailIsAllowed)
{
- RINOK(CheckZerosTail(op, Offset + PhySize));
+ RINOK(CheckZerosTail(op, (UInt64)(Offset + (Int64)PhySize)));
if (ErrorInfo.IgnoreTail)
openCur = true;
}
@@ -2294,7 +2407,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
int index = orderIndices[i];
if (index < 0)
continue;
- const CArcInfoEx &ai = op.codecs->Formats[index];
+ const CArcInfoEx &ai = op.codecs->Formats[(unsigned)index];
+ if (ai.Flags_ByExtOnlyOpen())
+ continue;
bool isDifficult = false;
// if (ai.Version < 0x91F) // we don't use parser with old DLL (before 9.31)
if (!ai.NewInterface)
@@ -2317,7 +2432,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
continue;
}
thereAreHandlersForSearch = true;
- UInt32 v = HASH_VAL(sig, 0);
+ UInt32 v = HASH_VAL(sig);
unsigned sigIndex = arc2sig[(unsigned)index] + k;
prevs[sigIndex] = hash[v];
hash[v] = (Byte)sigIndex;
@@ -2325,8 +2440,8 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
if (isDifficult)
{
- difficultFormats.Add(index);
- difficultBools[index] = true;
+ difficultFormats.Add((unsigned)index);
+ difficultBools[(unsigned)index] = true;
}
}
@@ -2394,7 +2509,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
size_t processedSize = kBufSize - bytesInBuf;
// printf("\nRead ask = %d", (unsigned)processedSize);
UInt64 seekPos = bufPhyPos + bytesInBuf;
- RINOK(op.stream->Seek(bufPhyPos + bytesInBuf, STREAM_SEEK_SET, NULL));
+ RINOK(op.stream->Seek((Int64)(bufPhyPos + bytesInBuf), STREAM_SEEK_SET, NULL));
RINOK(ReadStream(op.stream, byteBuffer + bytesInBuf, &processedSize));
// printf(" processed = %d", (unsigned)processedSize);
if (processedSize == 0)
@@ -2440,6 +2555,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
}
+ if (bytesInBuf <= (size_t)posInBuf)
+ break;
+
bool useOffsetCallback = false;
if (openCallback_Offset)
{
@@ -2464,7 +2582,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
}
- size_t availSize = bytesInBuf - (size_t)posInBuf;
+ const size_t availSize = bytesInBuf - (size_t)posInBuf;
if (availSize < kNumHashBytes)
break;
size_t scanSize = availSize -
@@ -2489,17 +2607,19 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
scanSize++;
const Byte *buf = byteBuffer + (size_t)posInBuf;
+ const Byte *bufLimit = buf + scanSize;
size_t ppp = 0;
if (!needCheckStartOpen)
{
- for (; ppp < scanSize && hash[HASH_VAL(buf, ppp)] == 0xFF; ppp++);
+ for (; buf < bufLimit && hash[HASH_VAL(buf)] == 0xFF; buf++);
+ ppp = (size_t)(buf - (byteBuffer + (size_t)posInBuf));
pos += ppp;
- if (ppp == scanSize)
+ if (buf == bufLimit)
continue;
}
- UInt32 v = HASH_VAL(buf, ppp);
+ UInt32 v = HASH_VAL(buf);
bool nextNeedCheckStartOpen = true;
unsigned i = hash[v];
unsigned indexOfDifficult = 0;
@@ -2539,7 +2659,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
const CByteBuffer &sig = ai.Signatures[sigIndex];
if (ppp + sig.Size() > availSize
- || !TestSignature(buf + ppp, sig, sig.Size()))
+ || !TestSignature(buf, sig, sig.Size()))
continue;
// printf("\nSignature OK: %10S %8x %5d", (const wchar_t *)ai.Name, (int)pos, (int)(pos - prevPos));
// prevPos = pos;
@@ -2590,13 +2710,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
// printf("\nIsArc OK: %S", (const wchar_t *)ai.Name);
}
- /*
- if (pos == 67109888)
- pos = pos;
- */
PRF(printf("\npos = %9I64d : %S", pos, (const wchar_t *)ai.Name));
- bool isMainFormat = isMainFormatArr[index];
+ const bool isMainFormat = isMainFormatArr[index];
const COpenSpecFlags &specFlags = mode.GetSpec(isForced, isMainFormat, isUnknownExt);
CMyComPtr<IInArchive> archive;
@@ -2606,14 +2722,14 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
// OutputDebugStringW(ai.Name);
- UInt64 rem = fileSize - startArcPos;
+ const UInt64 rem = fileSize - startArcPos;
UInt64 arcStreamOffset = 0;
if (ai.Flags_UseGlobalOffset())
{
limitedStreamSpec->InitAndSeek(0, fileSize);
- limitedStream->Seek(startArcPos, STREAM_SEEK_SET, NULL);
+ limitedStream->Seek((Int64)startArcPos, STREAM_SEEK_SET, NULL);
}
else
{
@@ -2633,31 +2749,40 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
extractCallback_To_OpenCallback_Spec->Files = 0;
extractCallback_To_OpenCallback_Spec->Offset = startArcPos;
- HRESULT result = OpenArchiveSpec(archive, true, limitedStream, &maxCheckStartPosition,
+ HRESULT result = OpenArchiveSpec(archive,
+ true, // needPhySize
+ limitedStream, &maxCheckStartPosition,
useOffsetCallback ? (IArchiveOpenCallback *)openCallback_Offset : (IArchiveOpenCallback *)op.callback,
extractCallback_To_OpenCallback);
RINOK(ReadBasicProps(archive, ai.Flags_UseGlobalOffset() ? 0 : startArcPos, result));
bool isOpen = false;
+
if (result == S_FALSE)
{
if (!mode.CanReturnParser)
{
if (formatIndex < 0 && ErrorInfo.IsArc_After_NonOpen())
{
- ErrorInfo.ErrorFormatIndex = index;
+ ErrorInfo.ErrorFormatIndex = (int)index;
NonOpen_ErrorInfo = ErrorInfo;
// if archive was detected, we don't need additional open attempts
return S_FALSE;
}
continue;
}
- if (!ErrorInfo.IsArc_After_NonOpen() || !PhySizeDefined || PhySize == 0)
+ if (!ErrorInfo.IsArc_After_NonOpen() || !PhySize_Defined || PhySize == 0)
continue;
}
else
{
+ if (PhySize_Defined && PhySize == 0)
+ {
+ PRF(printf(" phySize_Defined && PhySize == 0 "));
+ // we skip that epmty archive case with unusual unexpected (PhySize == 0) from Code function.
+ continue;
+ }
isOpen = true;
RINOK(result);
PRF(printf(" OK "));
@@ -2671,13 +2796,14 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
pi.Offset = startArcPos;
if (ai.Flags_UseGlobalOffset())
- pi.Offset = Offset;
+ pi.Offset = (UInt64)Offset;
else if (Offset != 0)
return E_FAIL;
- UInt64 arcRem = FileSize - pi.Offset;
+
+ const UInt64 arcRem = FileSize - pi.Offset;
UInt64 phySize = arcRem;
- bool phySizeDefined = PhySizeDefined;
- if (phySizeDefined)
+ const bool phySize_Defined = PhySize_Defined;
+ if (phySize_Defined)
{
if (pi.Offset + PhySize > FileSize)
{
@@ -2703,9 +2829,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
bool needScan = false;
- if (isOpen && !phySizeDefined)
+ if (isOpen && !phySize_Defined)
{
- // it's for Z format
+ // it's for Z format, or bzip2,gz,xz with phySize that was not detected
pi.LenIsUnknown = true;
needScan = true;
phySize = arcRem;
@@ -2722,7 +2848,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
/*
if (needSkipFullArc)
- if (pi.Offset == 0 && phySizeDefined && pi.Size >= fileSize)
+ if (pi.Offset == 0 && phySize_Defined && pi.Size >= fileSize)
continue;
*/
if (pi.Offset == 0 && !pi.LenIsUnknown && pi.Size >= FileSize)
@@ -2750,7 +2876,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
RINOK(ReadParseItemProps(archive, ai, pi));
- if (pi.Offset < startArcPos && !mode.EachPos /* && phySizeDefined */)
+ if (pi.Offset < startArcPos && !mode.EachPos /* && phySize_Defined */)
{
/* It's for DMG format.
This code deletes all previous items that are included to current item */
@@ -2769,7 +2895,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
- if (isOpen && mode.CanReturnArc && phySizeDefined)
+ if (isOpen && mode.CanReturnArc && phySize_Defined)
{
// if (pi.Offset + pi.Size >= fileSize)
bool openCur = false;
@@ -2777,7 +2903,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
bool thereIsTail = ErrorInfo.ThereIsTail;
if (thereIsTail && mode.ZerosTailIsAllowed)
{
- RINOK(CheckZerosTail(op, arcStreamOffset + Offset + PhySize));
+ RINOK(CheckZerosTail(op, (UInt64)((Int64)arcStreamOffset + Offset + (Int64)PhySize)));
if (ErrorInfo.IgnoreTail)
thereIsTail = false;
}
@@ -2785,10 +2911,12 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
if (pi.Offset != 0)
{
if (!pi.IsNotArcType)
+ {
if (thereIsTail)
openCur = specFlags.CanReturnMid;
else
openCur = specFlags.CanReturnTail;
+ }
}
else
{
@@ -2796,11 +2924,11 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
openCur = true;
else
openCur = specFlags.CanReturnFrontal;
-
if (formatIndex >= -2)
openCur = true;
}
+
if (formatIndex < 0 && pi.IsSelfExe /* && mode.SkipSfxStub */)
openCur = false;
@@ -2827,7 +2955,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
{
InStream = op.stream;
Archive = archive;
- FormatIndex = index;
+ FormatIndex = (int)index;
ArcStreamOffset = arcStreamOffset;
return S_OK;
}
@@ -2841,7 +2969,7 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
}
*/
- pi.FormatIndex = index;
+ pi.FormatIndex = (int)index;
// printf("\nAdd offset = %d", (int)pi.Offset);
handlerSpec->AddItem(pi);
@@ -2896,6 +3024,9 @@ HRESULT CArc::OpenStream2(const COpenOptions &op)
return S_OK;
}
+
+
+
HRESULT CArc::OpenStream(const COpenOptions &op)
{
RINOK(OpenStream2(op));
@@ -2908,25 +3039,25 @@ HRESULT CArc::OpenStream(const COpenOptions &op)
Archive->QueryInterface(IID_IArchiveGetRawProps, (void **)&GetRawProps);
Archive->QueryInterface(IID_IArchiveGetRootProps, (void **)&GetRootProps);
- RINOK(Archive_GetArcBoolProp(Archive, kpidIsTree, IsTree));
- RINOK(Archive_GetArcBoolProp(Archive, kpidIsDeleted, Ask_Deleted));
- RINOK(Archive_GetArcBoolProp(Archive, kpidIsAltStream, Ask_AltStream));
- RINOK(Archive_GetArcBoolProp(Archive, kpidIsAux, Ask_Aux));
- RINOK(Archive_GetArcBoolProp(Archive, kpidINode, Ask_INode));
- RINOK(Archive_GetArcBoolProp(Archive, kpidReadOnly, IsReadOnly));
+ RINOK(Archive_GetArcProp_Bool(Archive, kpidIsTree, IsTree));
+ RINOK(Archive_GetArcProp_Bool(Archive, kpidIsDeleted, Ask_Deleted));
+ RINOK(Archive_GetArcProp_Bool(Archive, kpidIsAltStream, Ask_AltStream));
+ RINOK(Archive_GetArcProp_Bool(Archive, kpidIsAux, Ask_Aux));
+ RINOK(Archive_GetArcProp_Bool(Archive, kpidINode, Ask_INode));
+ RINOK(Archive_GetArcProp_Bool(Archive, kpidReadOnly, IsReadOnly));
const UString fileName = ExtractFileNameFromPath(Path);
UString extension;
{
int dotPos = fileName.ReverseFind_Dot();
if (dotPos >= 0)
- extension = fileName.Ptr(dotPos + 1);
+ extension = fileName.Ptr((unsigned)(dotPos + 1));
}
DefaultName.Empty();
if (FormatIndex >= 0)
{
- const CArcInfoEx &ai = op.codecs->Formats[FormatIndex];
+ const CArcInfoEx &ai = op.codecs->Formats[(unsigned)FormatIndex];
if (ai.Exts.Size() == 0)
DefaultName = GetDefaultName2(fileName, UString(), UString());
else
@@ -2934,7 +3065,7 @@ HRESULT CArc::OpenStream(const COpenOptions &op)
int subExtIndex = ai.FindExtension(extension);
if (subExtIndex < 0)
subExtIndex = 0;
- const CArcExtInfo &extInfo = ai.Exts[subExtIndex];
+ const CArcExtInfo &extInfo = ai.Exts[(unsigned)subExtIndex];
DefaultName = GetDefaultName2(fileName, extInfo.Ext, extInfo.AddExt);
}
}
@@ -2946,10 +3077,10 @@ HRESULT CArc::OpenStream(const COpenOptions &op)
#ifdef _SFX
#ifdef _WIN32
- static const char *k_ExeExt = ".exe";
+ #define k_ExeExt ".exe"
static const unsigned k_ExeExt_Len = 4;
#else
- static const char *k_ExeExt = "";
+ #define k_ExeExt ""
static const unsigned k_ExeExt_Len = 0;
#endif
@@ -2972,9 +3103,7 @@ HRESULT CArc::OpenStreamOrFile(COpenOptions &op)
fileStream = fileStreamSpec;
Path = filePath;
if (!fileStreamSpec->Open(us2fs(Path)))
- {
- return GetLastError();
- }
+ return GetLastError_noZero_HRESULT();
op.stream = fileStream;
#ifdef _SFX
IgnoreSplit = true;
@@ -3009,13 +3138,13 @@ HRESULT CArc::OpenStreamOrFile(COpenOptions &op)
FOR_VECTOR (i, op.codecs->Formats)
{
const CArcInfoEx &ai = op.codecs->Formats[i];
- if (ai.IsSplit())
+ if (ai.Is_Split())
continue;
UString path3 = path2;
- path3 += L'.';
+ path3 += '.';
path3 += ai.GetMainExt(); // "7z" for SFX.
Path = path3;
- Path.AddAscii(".001");
+ Path += ".001";
bool isOk = op.callbackSpec->SetSecondFileInfo(us2fs(Path));
if (!isOk)
{
@@ -3216,7 +3345,7 @@ HRESULT CArchiveLink::Open(COpenOptions &op)
break;
CArc arc2;
- RINOK(arc.GetItemPath(mainSubfile, arc2.Path));
+ RINOK(arc.GetItem_Path(mainSubfile, arc2.Path));
bool zerosTailIsAllowed;
RINOK(Archive_GetItemBoolProp(arc.Archive, mainSubfile, kpidZerosTailIsAllowed, zerosTailIsAllowed));
@@ -3260,7 +3389,7 @@ HRESULT CArchiveLink::Open(COpenOptions &op)
break;
}
RINOK(result);
- RINOK(arc.GetItemMTime(mainSubfile, arc2.MTime, arc2.MTimeDefined));
+ RINOK(arc.GetItem_MTime(mainSubfile, arc2.MTime));
Arcs.Add(arc2);
}
IsOpen = !Arcs.IsEmpty();
@@ -3279,7 +3408,7 @@ HRESULT CArchiveLink::Open2(COpenOptions &op, IOpenCallbackUI *callbackUI)
if (!op.stream && !op.stdInMode)
{
NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), prefix, name);
- openCallbackSpec->Init(prefix, name);
+ RINOK(openCallbackSpec->Init2(prefix, name));
}
else
{
@@ -3309,7 +3438,7 @@ HRESULT CArchiveLink::Open2(COpenOptions &op, IOpenCallbackUI *callbackUI)
return S_OK;
}
-HRESULT CArc::ReOpen(const COpenOptions &op)
+HRESULT CArc::ReOpen(const COpenOptions &op, IArchiveOpenCallback *openCallback_Additional)
{
ErrorInfo.ClearErrors();
ErrorInfo.ErrorFormatIndex = -1;
@@ -3331,7 +3460,7 @@ HRESULT CArc::ReOpen(const COpenOptions &op)
CTailInStream *tailStreamSpec = new CTailInStream;
stream2 = tailStreamSpec;
tailStreamSpec->Stream = op.stream;
- tailStreamSpec->Offset = globalOffset;
+ tailStreamSpec->Offset = (UInt64)globalOffset;
tailStreamSpec->Init();
RINOK(tailStreamSpec->SeekToStart());
}
@@ -3339,12 +3468,15 @@ HRESULT CArc::ReOpen(const COpenOptions &op)
// There are archives with embedded STUBs (like ZIP), so we must support signature scanning
// But for another archives we can use 0 here. So the code can be fixed !!!
UInt64 maxStartPosition = kMaxCheckStartPosition;
- HRESULT res = Archive->Open(stream2, &maxStartPosition, op.callback);
+ IArchiveOpenCallback *openCallback = openCallback_Additional;
+ if (!openCallback)
+ openCallback = op.callback;
+ HRESULT res = Archive->Open(stream2, &maxStartPosition, openCallback);
if (res == S_OK)
{
- RINOK(ReadBasicProps(Archive, globalOffset, res));
- ArcStreamOffset = globalOffset;
+ RINOK(ReadBasicProps(Archive, (UInt64)globalOffset, res));
+ ArcStreamOffset = (UInt64)globalOffset;
if (ArcStreamOffset != 0)
InStream = op.stream;
}
@@ -3384,18 +3516,18 @@ HRESULT CArchiveLink::ReOpen(COpenOptions &op)
{
FString dirPrefix, fileName;
NFile::NDir::GetFullPathAndSplit(us2fs(op.filePath), dirPrefix, fileName);
- openCallbackSpec->Init(dirPrefix, fileName);
+ RINOK(openCallbackSpec->Init2(dirPrefix, fileName));
}
CInFileStream *fileStreamSpec = new CInFileStream;
CMyComPtr<IInStream> stream(fileStreamSpec);
if (!fileStreamSpec->Open(us2fs(op.filePath)))
- return GetLastError();
+ return GetLastError_noZero_HRESULT();
op.stream = stream;
CArc &arc = Arcs[0];
- HRESULT res = arc.ReOpen(op);
+ HRESULT res = arc.ReOpen(op, openCallbackNew);
PasswordWasAsked = openCallbackSpec->PasswordWasAsked;
// Password = openCallbackSpec->Password;
@@ -3406,6 +3538,7 @@ HRESULT CArchiveLink::ReOpen(COpenOptions &op)
#ifndef _SFX
+bool ParseComplexSize(const wchar_t *s, UInt64 &result);
bool ParseComplexSize(const wchar_t *s, UInt64 &result)
{
result = 0;
@@ -3463,7 +3596,7 @@ static bool ParseTypeParams(const UString &s, COpenType &type)
return false;
}
-bool ParseType(CCodecs &codecs, const UString &s, COpenType &type)
+static bool ParseType(CCodecs &codecs, const UString &s, COpenType &type)
{
int pos2 = s.Find(L':');
@@ -3472,11 +3605,11 @@ bool ParseType(CCodecs &codecs, const UString &s, COpenType &type)
if (pos2 < 0)
{
name = s;
- pos2 = s.Len();
+ pos2 = (int)s.Len();
}
else
{
- name = s.Left(pos2);
+ name = s.Left((unsigned)pos2);
pos2++;
}
@@ -3497,6 +3630,12 @@ bool ParseType(CCodecs &codecs, const UString &s, COpenType &type)
type.CanReturnArc = false;
type.CanReturnParser = true;
}
+ else if (name.IsEqualTo_Ascii_NoCase("hash"))
+ {
+ // type.CanReturnArc = false;
+ // type.CanReturnParser = false;
+ type.IsHashType = true;
+ }
else
return false;
}
@@ -3505,17 +3644,17 @@ bool ParseType(CCodecs &codecs, const UString &s, COpenType &type)
}
- for (unsigned i = pos2; i < s.Len();)
+ for (unsigned i = (unsigned)pos2; i < s.Len();)
{
int next = s.Find(L':', i);
if (next < 0)
- next = s.Len();
- const UString name = s.Mid(i, next - i);
+ next = (int)s.Len();
+ const UString name = s.Mid(i, (unsigned)next - i);
if (name.IsEmpty())
return false;
if (!ParseTypeParams(name, type))
return false;
- i = next + 1;
+ i = (unsigned)next + 1;
}
return true;
@@ -3524,21 +3663,36 @@ bool ParseType(CCodecs &codecs, const UString &s, COpenType &type)
bool ParseOpenTypes(CCodecs &codecs, const UString &s, CObjectVector<COpenType> &types)
{
types.Clear();
+ bool isHashType = false;
for (unsigned pos = 0; pos < s.Len();)
{
int pos2 = s.Find(L'.', pos);
if (pos2 < 0)
- pos2 = s.Len();
- UString name = s.Mid(pos, pos2 - pos);
+ pos2 = (int)s.Len();
+ UString name = s.Mid(pos, (unsigned)pos2 - pos);
if (name.IsEmpty())
return false;
COpenType type;
if (!ParseType(codecs, name, type))
return false;
+ if (isHashType)
+ return false;
+ if (type.IsHashType)
+ isHashType = true;
types.Add(type);
- pos = pos2 + 1;
+ pos = (unsigned)pos2 + 1;
}
return true;
}
+/*
+bool IsHashType(const CObjectVector<COpenType> &types)
+{
+ if (types.Size() != 1)
+ return false;
+ return types[0].IsHashType;
+}
+*/
+
+
#endif